Changeset 102573 in webkit
- Timestamp:
- Dec 12, 2011 5:53:13 AM (12 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 2 deleted
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit2/ChangeLog
r102554 r102573 1 2011-12-12 Caio Marcelo de Oliveira Filho <caio.oliveira@openbossa.org> 2 3 [Qt] [WK2] Support customizing popup menus with QML 4 https://bugs.webkit.org/show_bug.cgi?id=73560 5 6 Reviewed by Tor Arne Vestbø. 7 8 Add a new property 'itemSelector' to WebView (experimental for now) that contains 9 the QML component used when it needs to spawn a popup menu. For example, <select> 10 HTML tag may trigger a popup menu. 11 12 When loaded the component will have the 'model' available in its context with two 13 properties: 'elementRect', describing the position of the element which spawned 14 the item selector, and 'items', which is a model ready to be used by ListView. The 15 'model' also have methods to accept/reject the selection. 16 17 Option groups are available as a property for each row in the 'items' model. This 18 can be used together with ListView to create sections, as demonstrated in the 19 MiniBrowser. QML tests were added as well. 20 21 The existing Desktop version is removed since after the Qt5 refactoring isn't 22 working correctly. Once Qt have its own QML components for popup, we hope to use 23 it as a default if no other popupMenu is specified. 24 25 * Target.pri: 26 * UIProcess/API/qt/qquickwebview.cpp: 27 (QQuickWebViewPrivate::QQuickWebViewPrivate): 28 (QQuickWebViewExperimental::itemSelector): 29 (QQuickWebViewExperimental::setItemSelector): 30 * UIProcess/API/qt/qquickwebview_p.h: 31 * UIProcess/API/qt/qquickwebview_p_p.h: 32 (QQuickWebViewPrivate::get): 33 * UIProcess/API/qt/tests/qmltests/WebView/tst_itemSelector.qml: Added. 34 * UIProcess/API/qt/tests/qmltests/common/select.html: Added. 35 * UIProcess/API/qt/tests/qmltests/qmltests.pro: 36 * UIProcess/qt/QtPageClient.cpp: 37 * UIProcess/qt/QtWebPageProxy.cpp: 38 (QtWebPageProxy::createPopupMenuProxy): 39 * UIProcess/qt/WebPopupMenuProxyQt.cpp: 40 (WebKit::PopupMenuItemModel::rowCount): 41 (WebKit::PopupMenuItemModel::Item::Item): 42 (WebKit::ItemSelectorContextObject::elementRect): 43 (WebKit::ItemSelectorContextObject::items): 44 (WebKit::ItemSelectorContextObject::reject): 45 (WebKit::ItemSelectorContextObject::ItemSelectorContextObject): 46 (WebKit::ItemSelectorContextObject::accept): 47 (WebKit::createRoleNamesHash): 48 (WebKit::PopupMenuItemModel::PopupMenuItemModel): 49 (WebKit::PopupMenuItemModel::data): 50 (WebKit::PopupMenuItemModel::select): 51 (WebKit::PopupMenuItemModel::selectedOriginalIndex): 52 (WebKit::PopupMenuItemModel::buildItems): 53 (WebKit::WebPopupMenuProxyQt::WebPopupMenuProxyQt): 54 (WebKit::WebPopupMenuProxyQt::showPopupMenu): 55 (WebKit::WebPopupMenuProxyQt::hidePopupMenu): 56 (WebKit::WebPopupMenuProxyQt::selectIndex): 57 (WebKit::WebPopupMenuProxyQt::createItem): 58 (WebKit::WebPopupMenuProxyQt::createContext): 59 (WebKit::WebPopupMenuProxyQt::notifyValueChanged): 60 * UIProcess/qt/WebPopupMenuProxyQt.h: 61 (WebKit::WebPopupMenuProxyQt::create): 62 * UIProcess/qt/WebPopupMenuProxyQtDesktop.cpp: Removed. 63 * UIProcess/qt/WebPopupMenuProxyQtDesktop.h: Removed. 64 1 65 2011-12-11 Gopal Raghavan <gopal.1.raghavan@nokia.com> 2 66 -
trunk/Source/WebKit2/Target.pri
r102520 r102573 274 274 UIProcess/qt/WebGeolocationProviderQt.h \ 275 275 UIProcess/qt/WebPopupMenuProxyQt.h \ 276 UIProcess/qt/WebPopupMenuProxyQtDesktop.h \277 276 WebProcess/ApplicationCache/WebApplicationCacheManager.h \ 278 277 WebProcess/Authentication/AuthenticationManager.h \ … … 601 600 UIProcess/qt/WebPageProxyQt.cpp \ 602 601 UIProcess/qt/WebPopupMenuProxyQt.cpp \ 603 UIProcess/qt/WebPopupMenuProxyQtDesktop.cpp \604 602 UIProcess/qt/WebPreferencesQt.cpp \ 605 603 WebProcess/ApplicationCache/WebApplicationCacheManager.cpp \ -
trunk/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp
r102445 r102573 43 43 , confirmDialog(0) 44 44 , promptDialog(0) 45 , itemSelector(0) 45 46 , postTransitionState(adoptPtr(new PostTransitionState(this))) 46 47 , isTransitioningToNewPage(false) … … 495 496 } 496 497 498 QDeclarativeComponent* QQuickWebViewExperimental::itemSelector() const 499 { 500 Q_D(const QQuickWebView); 501 return d->itemSelector; 502 } 503 504 void QQuickWebViewExperimental::setItemSelector(QDeclarativeComponent* itemSelector) 505 { 506 Q_D(QQuickWebView); 507 if (d->itemSelector == itemSelector) 508 return; 509 d->itemSelector = itemSelector; 510 emit itemSelectorChanged(); 511 } 512 497 513 bool QQuickWebViewExperimental::useTraditionalDesktopBehaviour() const 498 514 { -
trunk/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h
r102502 r102573 173 173 Q_PROPERTY(QDeclarativeComponent* confirmDialog READ confirmDialog WRITE setConfirmDialog NOTIFY confirmDialogChanged) 174 174 Q_PROPERTY(QDeclarativeComponent* promptDialog READ promptDialog WRITE setPromptDialog NOTIFY promptDialogChanged) 175 Q_PROPERTY(QDeclarativeComponent* itemSelector READ itemSelector WRITE setItemSelector NOTIFY itemSelectorChanged) 175 176 Q_PROPERTY(bool useTraditionalDesktopBehaviour READ useTraditionalDesktopBehaviour WRITE setUseTraditionalDesktopBehaviour) 176 177 … … 185 186 QDeclarativeComponent* promptDialog() const; 186 187 void setPromptDialog(QDeclarativeComponent*); 188 QDeclarativeComponent* itemSelector() const; 189 void setItemSelector(QDeclarativeComponent*); 187 190 188 191 bool useTraditionalDesktopBehaviour() const; … … 195 198 void confirmDialogChanged(); 196 199 void promptDialogChanged(); 200 void itemSelectorChanged(); 197 201 void downloadRequested(QWebDownloadItem* downloadItem); 198 202 void permissionRequested(QWebPermissionRequest* permission); -
trunk/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h
r102142 r102573 49 49 50 50 public: 51 static QQuickWebViewPrivate* get(QQuickWebView* q) { return q->d_ptr.data(); } 52 51 53 QQuickWebViewPrivate(QQuickWebView* viewport, WKContextRef contextRef = 0, WKPageGroupRef pageGroupRef = 0); 52 54 virtual ~QQuickWebViewPrivate(); … … 82 84 83 85 void setUseTraditionalDesktopBehaviour(bool enable); 86 void setViewInAttachedProperties(QObject*); 84 87 85 88 private: … … 110 113 }; 111 114 112 void setViewInAttachedProperties(QObject*);113 114 115 QScopedPointer<QtPageClient> pageClient; 115 116 QScopedPointer<QtWebPageEventHandler> eventHandler; … … 128 129 QDeclarativeComponent* confirmDialog; 129 130 QDeclarativeComponent* promptDialog; 131 QDeclarativeComponent* itemSelector; 130 132 131 133 WebCore::ViewportArguments viewportArguments; -
trunk/Source/WebKit2/UIProcess/API/qt/tests/qmltests/qmltests.pro
r102554 r102573 24 24 WebView/tst_download.qml \ 25 25 WebView/tst_geopermission.qml \ 26 WebView/tst_itemSelector.qml \ 26 27 WebView/tst_javaScriptDialogs.qml \ 27 28 WebView/tst_loadFail.qml \ -
trunk/Source/WebKit2/UIProcess/qt/QtPageClient.cpp
r102136 r102573 27 27 #include "WebContextMenuProxyQt.h" 28 28 #include "WebEditCommandProxy.h" 29 #include "WebPopupMenuProxyQtDesktop.h"30 29 #include <QGuiApplication> 31 30 #include <QUndoStack> -
trunk/Source/WebKit2/UIProcess/qt/QtWebPageProxy.cpp
r102445 r102573 45 45 #include "WebContextMenuProxyQt.h" 46 46 #include "WebEditCommandProxy.h" 47 #include "WebPopupMenuProxyQt Desktop.h"47 #include "WebPopupMenuProxyQt.h" 48 48 #include "WKStringQt.h" 49 49 #include "WKURLQt.h" … … 185 185 PassRefPtr<WebPopupMenuProxy> QtWebPageProxy::createPopupMenuProxy(WebPageProxy*) 186 186 { 187 return WebPopupMenuProxyQt Desktop::create(m_webPageProxy.get(), m_qmlWebView);187 return WebPopupMenuProxyQt::create(m_webPageProxy.get(), m_qmlWebView); 188 188 } 189 189 -
trunk/Source/WebKit2/UIProcess/qt/WebPopupMenuProxyQt.cpp
r95901 r102573 1 1 /* 2 2 * Copyright (C) 2010 Apple Inc. All rights reserved. 3 * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies) 3 4 * 4 5 * Redistribution and use in source and binary forms, with or without … … 29 30 #include "PlatformPopupMenuData.h" 30 31 #include "WebPopupItem.h" 32 #include "qquickwebview_p.h" 33 #include "qquickwebview_p_p.h" 34 #include <QtCore/QAbstractListModel> 35 #include <QtDeclarative/QDeclarativeContext> 36 #include <QtDeclarative/QDeclarativeEngine> 31 37 32 38 using namespace WebCore; … … 34 40 namespace WebKit { 35 41 36 WebPopupMenuProxyQt::WebPopupMenuProxyQt() 37 : WebPopupMenuProxy(0) 42 static QHash<int, QByteArray> createRoleNamesHash(); 43 44 class PopupMenuItemModel : public QAbstractListModel { 45 Q_OBJECT 46 47 public: 48 enum Roles { 49 GroupRole = Qt::UserRole, 50 EnabledRole = Qt::UserRole + 1, 51 SelectedRole = Qt::UserRole + 2, 52 IsSeparatorRole = Qt::UserRole + 3 53 }; 54 55 PopupMenuItemModel(const Vector<WebPopupItem>&, int selectedOriginalIndex); 56 virtual int rowCount(const QModelIndex& parent = QModelIndex()) const { return m_items.size(); } 57 virtual QVariant data(const QModelIndex&, int role = Qt::DisplayRole) const; 58 59 Q_INVOKABLE void select(int); 60 61 int selectedOriginalIndex() const; 62 63 private: 64 struct Item { 65 Item(const WebPopupItem& webPopupItem, const QString& group, int originalIndex, bool selected) 66 : text(webPopupItem.m_text) 67 , toolTip(webPopupItem.m_toolTip) 68 , group(group) 69 , originalIndex(originalIndex) 70 , enabled(webPopupItem.m_isEnabled) 71 , selected(selected) 72 , isSeparator(webPopupItem.m_type == WebPopupItem::Separator) 73 { } 74 75 QString text; 76 QString toolTip; 77 QString group; 78 // Keep track of originalIndex because we don't add the label (group) items to our vector. 79 int originalIndex; 80 bool enabled; 81 bool selected; 82 bool isSeparator; 83 }; 84 85 void buildItems(const Vector<WebPopupItem>& webPopupItems, int selectedOriginalIndex); 86 87 Vector<Item> m_items; 88 int m_selectedModelIndex; 89 }; 90 91 class ItemSelectorContextObject : public QObject { 92 Q_OBJECT 93 Q_PROPERTY(QRect elementRect READ elementRect CONSTANT FINAL) 94 Q_PROPERTY(QObject* items READ items CONSTANT FINAL) 95 96 public: 97 ItemSelectorContextObject(const IntRect& elementRect, const Vector<WebPopupItem>&, int selectedIndex); 98 99 QRect elementRect() const { return m_elementRect; } 100 PopupMenuItemModel* items() { return &m_items; } 101 102 Q_INVOKABLE void accept(int index = -1); 103 Q_INVOKABLE void reject() { emit rejected(); } 104 105 Q_SIGNALS: 106 void acceptedWithOriginalIndex(int); 107 void rejected(); 108 109 private: 110 QRect m_elementRect; 111 PopupMenuItemModel m_items; 112 }; 113 114 ItemSelectorContextObject::ItemSelectorContextObject(const IntRect& elementRect, const Vector<WebPopupItem>& webPopupItems, int selectedIndex) 115 : m_elementRect(elementRect) 116 , m_items(webPopupItems, selectedIndex) 117 { 118 } 119 120 void ItemSelectorContextObject::accept(int index) 121 { 122 if (index != -1) 123 m_items.select(index); 124 int originalIndex = m_items.selectedOriginalIndex(); 125 emit acceptedWithOriginalIndex(originalIndex); 126 } 127 128 static QHash<int, QByteArray> createRoleNamesHash() 129 { 130 QHash<int, QByteArray> roles; 131 roles[Qt::DisplayRole] = "text"; 132 roles[Qt::ToolTipRole] = "tooltip"; 133 roles[PopupMenuItemModel::GroupRole] = "group"; 134 roles[PopupMenuItemModel::EnabledRole] = "enabled"; 135 roles[PopupMenuItemModel::SelectedRole] = "selected"; 136 roles[PopupMenuItemModel::IsSeparatorRole] = "isSeparator"; 137 return roles; 138 } 139 140 PopupMenuItemModel::PopupMenuItemModel(const Vector<WebPopupItem>& webPopupItems, int selectedOriginalIndex) 141 : m_selectedModelIndex(-1) 142 { 143 static QHash<int, QByteArray> roles = createRoleNamesHash(); 144 setRoleNames(roles); 145 buildItems(webPopupItems, selectedOriginalIndex); 146 } 147 148 QVariant PopupMenuItemModel::data(const QModelIndex& index, int role) const 149 { 150 if (!index.isValid() || index.row() < 0 || index.row() >= m_items.size()) 151 return QVariant(); 152 153 const Item& item = m_items[index.row()]; 154 if (item.isSeparator) { 155 if (role == IsSeparatorRole) 156 return true; 157 return QVariant(); 158 } 159 160 switch (role) { 161 case Qt::DisplayRole: 162 return item.text; 163 case Qt::ToolTipRole: 164 return item.toolTip; 165 case GroupRole: 166 return item.group; 167 case EnabledRole: 168 return item.enabled; 169 case SelectedRole: 170 return item.selected; 171 case IsSeparatorRole: 172 return false; 173 } 174 175 return QVariant(); 176 } 177 178 void PopupMenuItemModel::select(int index) 179 { 180 int oldIndex = m_selectedModelIndex; 181 if (index == oldIndex) 182 return; 183 if (index < 0 || index >= m_items.size()) 184 return; 185 Item& item = m_items[index]; 186 if (!item.enabled) 187 return; 188 189 Item& oldItem = m_items[oldIndex]; 190 oldItem.selected = false; 191 item.selected = true; 192 m_selectedModelIndex = index; 193 194 emit dataChanged(this->index(oldIndex), this->index(oldIndex)); 195 emit dataChanged(this->index(index), this->index(index)); 196 } 197 198 int PopupMenuItemModel::selectedOriginalIndex() const 199 { 200 if (m_selectedModelIndex == -1) 201 return -1; 202 return m_items[m_selectedModelIndex].originalIndex; 203 } 204 205 void PopupMenuItemModel::buildItems(const Vector<WebPopupItem>& webPopupItems, int selectedOriginalIndex) 206 { 207 QString currentGroup; 208 m_items.reserveInitialCapacity(webPopupItems.size()); 209 for (int i = 0; i < webPopupItems.size(); i++) { 210 const WebPopupItem& webPopupItem = webPopupItems[i]; 211 if (webPopupItem.m_isLabel) { 212 currentGroup = webPopupItem.m_text; 213 continue; 214 } 215 const bool selected = i == selectedOriginalIndex; 216 if (selected) 217 m_selectedModelIndex = m_items.size(); 218 m_items.append(Item(webPopupItem, currentGroup, i, selected)); 219 } 220 } 221 222 WebPopupMenuProxyQt::WebPopupMenuProxyQt(WebPopupMenuProxy::Client* client, QQuickWebView* webView) 223 : WebPopupMenuProxy(client) 224 , m_webView(webView) 38 225 { 39 226 } … … 45 232 void WebPopupMenuProxyQt::showPopupMenu(const IntRect& rect, WebCore::TextDirection, double, const Vector<WebPopupItem>& items, const PlatformPopupMenuData&, int32_t selectedIndex) 46 233 { 234 m_selectedIndex = selectedIndex; 235 236 ItemSelectorContextObject* contextObject = new ItemSelectorContextObject(rect, items, m_selectedIndex); 237 createItem(contextObject); 238 if (!m_itemSelector) { 239 notifyValueChanged(); 240 return; 241 } 47 242 } 48 243 49 244 void WebPopupMenuProxyQt::hidePopupMenu() 50 245 { 246 m_itemSelector.clear(); 247 m_context.clear(); 248 notifyValueChanged(); 249 } 250 251 void WebPopupMenuProxyQt::selectIndex(int index) 252 { 253 m_selectedIndex = index; 254 } 255 256 void WebPopupMenuProxyQt::createItem(QObject* contextObject) 257 { 258 QDeclarativeComponent* component = m_webView->experimental()->itemSelector(); 259 if (!component) { 260 delete contextObject; 261 return; 262 } 263 264 createContext(component, contextObject); 265 QObject* object = component->beginCreate(m_context.get()); 266 if (!object) { 267 m_context.clear(); 268 return; 269 } 270 271 m_itemSelector = adoptPtr(qobject_cast<QQuickItem*>(object)); 272 if (!m_itemSelector) { 273 m_context.clear(); 274 m_itemSelector.clear(); 275 return; 276 } 277 278 connect(contextObject, SIGNAL(acceptedWithOriginalIndex(int)), SLOT(selectIndex(int))); 279 280 // We enqueue these because they are triggered by m_itemSelector and will lead to its destruction. 281 connect(contextObject, SIGNAL(acceptedWithOriginalIndex(int)), SLOT(hidePopupMenu()), Qt::QueuedConnection); 282 connect(contextObject, SIGNAL(rejected()), SLOT(hidePopupMenu()), Qt::QueuedConnection); 283 284 QQuickWebViewPrivate::get(m_webView)->setViewInAttachedProperties(m_itemSelector.get()); 285 component->completeCreate(); 286 287 m_itemSelector->setParentItem(m_webView); 288 } 289 290 void WebPopupMenuProxyQt::createContext(QDeclarativeComponent* component, QObject* contextObject) 291 { 292 QDeclarativeContext* baseContext = component->creationContext(); 293 if (!baseContext) 294 baseContext = QDeclarativeEngine::contextForObject(m_webView); 295 m_context = adoptPtr(new QDeclarativeContext(baseContext)); 296 297 contextObject->setParent(m_context.get()); 298 m_context->setContextProperty(QLatin1String("model"), contextObject); 299 m_context->setContextObject(contextObject); 300 } 301 302 void WebPopupMenuProxyQt::notifyValueChanged() 303 { 304 if (m_client) { 305 m_client->valueChangedForPopupMenu(this, m_selectedIndex); 306 invalidate(); 307 } 51 308 } 52 309 53 310 } // namespace WebKit 311 312 // Since we define QObjects in WebPopupMenuProxyQt.cpp, this will trigger moc to run on .cpp. 313 #include "WebPopupMenuProxyQt.moc" 314 315 // And we can't compile the moc for WebPopupMenuProxyQt.h by itself, since it doesn't include "config.h" 316 #include "moc_WebPopupMenuProxyQt.cpp" -
trunk/Source/WebKit2/UIProcess/qt/WebPopupMenuProxyQt.h
r95901 r102573 1 1 /* 2 2 * Copyright (C) 2010 Apple Inc. All rights reserved. 3 * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies) 3 4 * 4 5 * Redistribution and use in source and binary forms, with or without … … 29 30 #include "WebPopupMenuProxy.h" 30 31 32 #include <QtCore/QObject> 33 #include <wtf/OwnPtr.h> 34 35 class QDeclarativeComponent; 36 class QDeclarativeContext; 37 class QQuickWebView; 38 class QQuickItem; 39 31 40 namespace WebKit { 32 41 33 class WebPopupMenuProxyQt : public WebPopupMenuProxy { 42 class WebPopupMenuProxyQt : public QObject, public WebPopupMenuProxy { 43 Q_OBJECT 44 34 45 public: 35 static PassRefPtr<WebPopupMenuProxyQt> create( )46 static PassRefPtr<WebPopupMenuProxyQt> create(WebPopupMenuProxy::Client* client, QQuickWebView* webView) 36 47 { 37 return adoptRef(new WebPopupMenuProxyQt( ));48 return adoptRef(new WebPopupMenuProxyQt(client, webView)); 38 49 } 39 50 ~WebPopupMenuProxyQt(); 40 51 41 52 virtual void showPopupMenu(const WebCore::IntRect&, WebCore::TextDirection, double pageScaleFactor, const Vector<WebPopupItem>&, const PlatformPopupMenuData&, int32_t selectedIndex); 53 54 public Q_SLOTS: 42 55 virtual void hidePopupMenu(); 43 56 57 private Q_SLOTS: 58 void selectIndex(int); 59 44 60 private: 45 WebPopupMenuProxyQt(); 61 WebPopupMenuProxyQt(WebPopupMenuProxy::Client*, QQuickWebView*); 62 void createItem(QObject*); 63 void createContext(QDeclarativeComponent*, QObject*); 64 65 void notifyValueChanged(); 66 67 OwnPtr<QDeclarativeContext> m_context; 68 OwnPtr<QQuickItem> m_itemSelector; 69 70 QQuickWebView* m_webView; 71 int32_t m_selectedIndex; 46 72 }; 47 73 -
trunk/Tools/ChangeLog
r102568 r102573 1 2011-12-12 Caio Marcelo de Oliveira Filho <caio.oliveira@openbossa.org> 2 3 [Qt] [WK2] Support customizing popup menus with QML 4 https://bugs.webkit.org/show_bug.cgi?id=73560 5 6 Reviewed by Tor Arne Vestbø. 7 8 Add an Item Selector to our WebView using the experimental API. 9 10 * MiniBrowser/qt/MiniBrowser.pro: 11 * MiniBrowser/qt/MiniBrowser.qrc: 12 * MiniBrowser/qt/qml/BrowserWindow.qml: 13 * MiniBrowser/qt/qml/ItemSelector.qml: Added. 14 1 15 2011-12-12 Alexander Færøy <alexander.faeroy@nokia.com> 2 16 -
trunk/Tools/MiniBrowser/qt/MiniBrowser.pro
r101384 r102573 31 31 32 32 OTHER_FILES += \ 33 qml/BrowserWindow.qml 33 qml/BrowserWindow.qml \ 34 qml/ItemSelector.qml -
trunk/Tools/MiniBrowser/qt/MiniBrowser.qrc
r102348 r102573 7 7 <file>icons/touchpoint.png</file> 8 8 <file>qml/BrowserWindow.qml</file> 9 <file>qml/ItemSelector.qml</file> 9 10 <file>qml/MockTouchPoint.qml</file> 10 11 <file>useragentlist.txt</file> -
trunk/Tools/MiniBrowser/qt/qml/BrowserWindow.qml
r102035 r102573 29 29 import QtQuick 2.0 30 30 import QtWebKit 3.0 31 import QtWebKit.experimental 3.0 31 32 32 33 Rectangle { … … 231 232 forceActiveFocus(); 232 233 } 234 235 experimental.itemSelector: ItemSelector { } 233 236 } 234 237
Note: See TracChangeset
for help on using the changeset viewer.