2011-04-22 Yi Shen <yi.4.shen@nokia.com>
[WebKit-https.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 #include <QtGui>
24 #include <QtPlugin>
25 #include <akndiscreetpopup.h>
26
27 class ItemListDelegate : public QStyledItemDelegate {
28 public:
29     ItemListDelegate(QObject* parent = 0)
30         : QStyledItemDelegate(parent)
31     {
32     }
33
34     void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
35     {
36         Q_ASSERT(index.isValid());
37
38         QStyleOptionViewItemV4 opt = option;
39         opt.state = opt.state & (~QStyle::State_HasFocus);
40         opt.text = index.data().toString();
41         initStyleOption(&opt, index);
42
43         const QWidget* widget = 0;
44         Popup* selectPopup = qobject_cast<Popup*>(parent());
45         if (selectPopup)
46             widget = selectPopup->listWidget();
47
48         QStyle* style = widget ? widget->style() : QApplication::style();
49         style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, widget);
50     }
51 };
52
53 Popup::Popup(const QWebSelectData& data)
54     : m_data(data)
55 {
56     setModal(true);
57     m_list = new QListWidget(this);
58     int width = QApplication::desktop()->size().width();
59     QVBoxLayout* vLayout = new QVBoxLayout(this);
60     vLayout->setContentsMargins(width / 20, 5, 5, 5);
61     if (data.multiple())
62         m_list->setSelectionMode(QAbstractItemView::MultiSelection);
63     populateList();
64     vLayout->addWidget(m_list);
65    
66     ItemListDelegate* itemDelegate = new ItemListDelegate(this);
67     m_list->setItemDelegate(itemDelegate);
68 }
69
70 void Popup::resizeEvent(QResizeEvent* e)
71 {
72     QDialog::resizeEvent(e);
73     m_list->setGeometry(m_list->geometry().x(), m_list->geometry().y(), m_list->width(), m_list->height());
74 }
75
76 void Popup::populateList()
77 {
78     QListWidgetItem* listItem;
79     m_preSelectedIndices.clear();
80     for (int i = 0; i < m_data.itemCount(); ++i) {
81         if (m_data.itemType(i) == QWebSelectData::Option) {
82             listItem = new QListWidgetItem(m_data.itemText(i));
83             m_list->addItem(listItem);
84             listItem->setSelected(m_data.itemIsSelected(i));
85             if (m_data.itemIsSelected(i)) {
86                 m_preSelectedIndices.append(i);
87                 m_list->setCurrentItem(listItem);
88             }
89         } else if (m_data.itemType(i) == QWebSelectData::Group) {
90             listItem = new QListWidgetItem(m_data.itemText(i));
91             m_list->addItem(listItem);
92             listItem->setSelected(false);
93             listItem->setFlags(Qt::NoItemFlags);
94         }
95     }
96     connect(m_list, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(onItemSelected(QListWidgetItem*)));
97 }
98
99 void Popup::onItemSelected(QListWidgetItem* item)
100 {
101     if (item->flags() != Qt::NoItemFlags) {
102         if (!m_data.multiple())
103             updateAndClose();
104     }
105 }
106
107 void Popup::updateSelectionsBeforeDialogClosing()
108 {
109     QList<QListWidgetItem*> selected = m_list->selectedItems();
110     if (m_data.multiple()) {
111         QList<int> selectedIndices;
112         Q_FOREACH(QListWidgetItem* item, selected)
113             selectedIndices.append(m_list->row(item));
114
115         for (int i = 0; i < m_data.itemCount(); ++i) {
116             if ((m_preSelectedIndices.contains(i) && !selectedIndices.contains(i)) || (!m_preSelectedIndices.contains(i) && selectedIndices.contains(i)))
117                 emit itemClicked(i);
118         }
119     } else {
120         Q_FOREACH(QListWidgetItem* item, selected)
121             emit itemClicked(m_list->row(item));
122     }
123 }
124
125 void Popup::updateAndClose()
126 {
127     updateSelectionsBeforeDialogClosing();
128     accept();
129 }
130
131 WebPopup::WebPopup()
132     : m_popup(0)
133 {
134 }
135
136 WebPopup::~WebPopup()
137 {
138     if (m_popup)
139         m_popup->deleteLater();
140 }
141
142 Popup* WebPopup::createSingleSelectionPopup(const QWebSelectData& data)
143 {
144     return new SingleSelectionPopup(data);
145 }
146
147 Popup* WebPopup::createMultipleSelectionPopup(const QWebSelectData& data)
148 {
149     return new MultipleSelectionPopup(data);
150 }
151
152 Popup* WebPopup::createPopup(const QWebSelectData& data)
153 {
154     Popup* result = data.multiple() ? createMultipleSelectionPopup(data) : createSingleSelectionPopup(data);
155     connect(result, SIGNAL(finished(int)), this, SLOT(popupClosed()));
156     connect(result, SIGNAL(itemClicked(int)), this, SLOT(itemClicked(int)));
157     return result;
158 }
159
160 void WebPopup::show(const QWebSelectData& data)
161 {
162     if (m_popup)
163         return;
164
165     m_popup = createPopup(data);
166     m_popup->showMaximized();
167 }
168
169 void WebPopup::hide()
170 {
171     if (!m_popup)
172         return;
173
174     m_popup->accept();
175 }
176
177 void WebPopup::popupClosed()
178 {
179     if (!m_popup)
180         return;
181
182     m_popup->deleteLater();
183     m_popup = 0;
184     emit didHide();
185 }
186
187 void WebPopup::itemClicked(int idx)
188 {
189     emit selectItem(idx, true, false);
190 }
191
192 SingleSelectionPopup::SingleSelectionPopup(const QWebSelectData& data)
193     : Popup(data)
194 {
195     setWindowTitle("Select item");
196
197     QAction* cancelAction = new QAction("Cancel", this);
198     cancelAction->setSoftKeyRole(QAction::NegativeSoftKey);
199     addAction(cancelAction);
200     connect(cancelAction, SIGNAL(triggered(bool)), this, SLOT(reject()));
201 }
202
203 MultipleSelectionPopup::MultipleSelectionPopup(const QWebSelectData& data)
204     : Popup(data)
205 {
206     setWindowTitle("Select items");
207
208     QAction* cancelAction = new QAction("Cancel", this);
209     cancelAction->setSoftKeyRole(QAction::NegativeSoftKey);
210     addAction(cancelAction);
211     connect(cancelAction, SIGNAL(triggered(bool)), this, SLOT(reject()));
212
213     QAction* okAction = new QAction("Ok", this);
214     okAction->setSoftKeyRole(QAction::PositiveSoftKey);
215     addAction(okAction);
216     connect(okAction, SIGNAL(triggered(bool)), this, SLOT(updateAndClose()));
217 }
218
219 void WebNotificationPresenter::showNotification(const QWebNotificationData* data)
220 {
221     HBufC* title = HBufC::New(data->title().size());
222     *title = TPtrC(data->title().utf16(), data->title().size());
223     HBufC* message = HBufC::New(data->message().size());
224     *message = TPtrC(data->message().utf16(), data->message().size());
225     TRAP_IGNORE(CAknDiscreetPopup::ShowGlobalPopupL(*title, *message, KAknsIIDNone, KNullDesC));
226     emit notificationClosed();
227     deleteLater();
228     delete title;
229     delete message;
230 }
231
232 bool WebPlugin::supportsExtension(Extension extension) const
233 {
234     if (extension == MultipleSelections)
235         return true;
236     if (extension == Notifications)
237         return true;
238     if (extension == FullScreenVideoPlayer)
239         return true;        
240     return false;
241 }
242
243 QObject* WebPlugin::createExtension(Extension extension) const
244 {
245     switch (extension) {
246     case MultipleSelections:
247         return new WebPopup();
248     case Notifications:
249         return new WebNotificationPresenter();
250     default:
251         return 0;
252     }
253 }
254
255 Q_EXPORT_PLUGIN2(qwebselectim, WebPlugin)