diff options
-rw-r--r-- | examples/qtquick/quickwindow.qml | 5 | ||||
-rw-r--r-- | lib/qquickwebcontentsview.cpp | 48 | ||||
-rw-r--r-- | lib/qquickwebcontentsview.h | 13 | ||||
-rw-r--r-- | lib/qwebcontentsview.cpp | 2 | ||||
-rw-r--r-- | lib/web_contents_delegate_qt.cpp | 56 | ||||
-rw-r--r-- | lib/web_contents_delegate_qt.h | 23 |
6 files changed, 118 insertions, 29 deletions
diff --git a/examples/qtquick/quickwindow.qml b/examples/qtquick/quickwindow.qml index bd6504d6b..688014b6f 100644 --- a/examples/qtquick/quickwindow.qml +++ b/examples/qtquick/quickwindow.qml @@ -8,6 +8,7 @@ ApplicationWindow { height: 600 width: 800 visible: true + title: webContentsView.title toolBar: ToolBar { id: navigationBar @@ -28,8 +29,8 @@ ApplicationWindow { } ToolButton { id: reloadButton - iconName: "view-refresh" - iconSource: ":/icons/view-refresh.png" + iconName: webContentsView.loading ? "process-stop" : "view-refresh" + iconSource: webContentsView.loading ? ":/icons/process-stop.png" : ":/icons/view-refresh.png" onClicked: webContentsView.reload() } TextField { diff --git a/lib/qquickwebcontentsview.cpp b/lib/qquickwebcontentsview.cpp index dec521183..0b56aa543 100644 --- a/lib/qquickwebcontentsview.cpp +++ b/lib/qquickwebcontentsview.cpp @@ -44,6 +44,7 @@ // Needed to get access to content::GetContentClient() #define CONTENT_IMPLEMENTATION +#include "content/public/browser/navigation_entry.h" #include "content/public/browser/web_contents.h" #include "browser_context_qt.h" @@ -60,9 +61,8 @@ void QQuickWebContentsView::registerType() qmlRegisterType<QQuickWebContentsView>("QtWebEngine", 1, 0, "WebContentsView"); } -class QQuickWebContentsViewPrivate +struct QQuickWebContentsViewPrivate { -public: scoped_refptr<WebEngineContext> context; scoped_ptr<WebContentsDelegateQt> webContentsDelegate; }; @@ -70,11 +70,18 @@ public: QQuickWebContentsView::QQuickWebContentsView() { d.reset(new QQuickWebContentsViewPrivate); + // This has to be the first thing we do. d->context = WebEngineContext::current(); content::BrowserContext* browser_context = static_cast<ContentBrowserClientQt*>(content::GetContentClient()->browser())->browser_context(); - d->webContentsDelegate.reset(WebContentsDelegateQt::CreateNewWindow(browser_context, NULL, MSG_ROUTING_NONE, gfx::Size())); + d->webContentsDelegate.reset(new WebContentsDelegateQt(this, browser_context, NULL, MSG_ROUTING_NONE, gfx::Size())); + + WebContentsDelegateQt* delegate = d->webContentsDelegate.get(); + connect(delegate, SIGNAL(titleChanged(QString)), this, SIGNAL(titleChanged(QString))); + connect(delegate, SIGNAL(urlChanged()), this, SIGNAL(urlChanged())); + connect(delegate, SIGNAL(loadingStateChanged()), this, SIGNAL(loadingStateChanged())); + WebContentsViewQt* content_view = static_cast<WebContentsViewQt*>(d->webContentsDelegate->web_contents()->GetView()); QQuickItem* windowContainer = content_view->windowContainer()->qQuickItem(); windowContainer->setParentItem(this); @@ -117,3 +124,38 @@ void QQuickWebContentsView::reload() d->webContentsDelegate->web_contents()->GetController().Reload(false); d->webContentsDelegate->web_contents()->GetView()->Focus(); } + +void QQuickWebContentsView::stop() +{ + content::NavigationController& controller = d->webContentsDelegate->web_contents()->GetController(); + + int index = controller.GetPendingEntryIndex(); + if (index != -1) + controller.RemoveEntryAtIndex(index); + + d->webContentsDelegate->web_contents()->GetView()->Focus(); +} + +bool QQuickWebContentsView::isLoading() const +{ + return d->webContentsDelegate->web_contents()->IsLoading(); +} + +QString QQuickWebContentsView::title() const +{ + content::NavigationEntry* entry = d->webContentsDelegate->web_contents()->GetController().GetVisibleEntry(); + if (!entry) + return QString(); + return QString::fromUtf16(entry->GetTitle().data()); +} + +bool QQuickWebContentsView::canGoBack() const +{ + return d->webContentsDelegate->web_contents()->GetController().CanGoBack(); +} + +bool QQuickWebContentsView::canGoForward() const +{ + return d->webContentsDelegate->web_contents()->GetController().CanGoForward(); +} + diff --git a/lib/qquickwebcontentsview.h b/lib/qquickwebcontentsview.h index 9e9979b0a..c94d5e488 100644 --- a/lib/qquickwebcontentsview.h +++ b/lib/qquickwebcontentsview.h @@ -50,6 +50,11 @@ class QQuickWebContentsViewPrivate; class Q_DECL_EXPORT QQuickWebContentsView : public QQuickItem { Q_OBJECT Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged) + Q_PROPERTY(bool loading READ isLoading NOTIFY loadingStateChanged) + Q_PROPERTY(QString title READ title NOTIFY titleChanged) + Q_PROPERTY(bool canGoBack READ canGoBack NOTIFY loadingStateChanged) + Q_PROPERTY(bool canGoForward READ canGoForward NOTIFY loadingStateChanged) + public: static void registerType(); @@ -58,15 +63,21 @@ public: QUrl url() const; void setUrl(const QUrl&); + bool isLoading() const; + QString title() const; + bool canGoBack() const; + bool canGoForward() const; public Q_SLOTS: void goBack(); void goForward(); void reload(); + void stop(); Q_SIGNALS: - void titleChanged(); + void titleChanged(QString); void urlChanged(); + void loadingStateChanged(); private: QScopedPointer<QQuickWebContentsViewPrivate> d; diff --git a/lib/qwebcontentsview.cpp b/lib/qwebcontentsview.cpp index 3da4c727e..061d518cd 100644 --- a/lib/qwebcontentsview.cpp +++ b/lib/qwebcontentsview.cpp @@ -69,7 +69,7 @@ QWebContentsView::QWebContentsView() d->context = WebEngineContext::current(); content::BrowserContext* browser_context = static_cast<ContentBrowserClientQt*>(content::GetContentClient()->browser())->browser_context(); - d->webContentsDelegate.reset(WebContentsDelegateQt::CreateNewWindow(browser_context, NULL, MSG_ROUTING_NONE, gfx::Size())); + d->webContentsDelegate.reset(new WebContentsDelegateQt(this, browser_context, NULL, MSG_ROUTING_NONE, gfx::Size())); QVBoxLayout *layout = new QVBoxLayout; layout->setContentsMargins(0, 0, 0, 0); setLayout(layout); diff --git a/lib/web_contents_delegate_qt.cpp b/lib/web_contents_delegate_qt.cpp index 71f3e6d9c..d4aad13a0 100644 --- a/lib/web_contents_delegate_qt.cpp +++ b/lib/web_contents_delegate_qt.cpp @@ -41,8 +41,14 @@ #include "web_contents_delegate_qt.h" +#include "content/public/browser/navigation_controller.h" +#include "content/public/browser/navigation_entry.h" +#include "content/public/browser/notification_source.h" +#include "content/public/browser/notification_details.h" +#include "content/public/browser/notification_types.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" +#include "content/public/browser/invalidate_type.h" #include "content/public/common/renderer_preferences.h" #include <QGuiApplication> @@ -51,13 +57,8 @@ static const int kTestWindowWidth = 800; static const int kTestWindowHeight = 600; -WebContentsDelegateQt::WebContentsDelegateQt(content::WebContents* web_contents) - : m_webContents(web_contents) -{ - m_webContents->SetDelegate(this); -} - -WebContentsDelegateQt* WebContentsDelegateQt::CreateNewWindow(content::BrowserContext* browser_context, content::SiteInstance* site_instance, int routing_id, const gfx::Size& initial_size) +WebContentsDelegateQt::WebContentsDelegateQt(QObject* webContentsView, content::BrowserContext* browser_context, content::SiteInstance* site_instance, int routing_id, const gfx::Size& initial_size) + : m_webContentsView(webContentsView) { content::WebContents::CreateParams create_params(browser_context, site_instance); create_params.routing_id = routing_id; @@ -65,26 +66,47 @@ WebContentsDelegateQt* WebContentsDelegateQt::CreateNewWindow(content::BrowserCo create_params.initial_size = initial_size; else create_params.initial_size = gfx::Size(kTestWindowWidth, kTestWindowHeight); - content::WebContents::Create(create_params); - content::WebContents* web_contents = content::WebContents::Create(create_params); - WebContentsDelegateQt* delegate = new WebContentsDelegateQt(web_contents); - content::RendererPreferences* rendererPrefs = delegate->m_webContents->GetMutableRendererPrefs(); + m_webContents.reset(content::WebContents::Create(create_params)); + + content::RendererPreferences* rendererPrefs = m_webContents->GetMutableRendererPrefs(); rendererPrefs->use_custom_colors = true; // Qt returns a flash time (the whole cycle) in ms, chromium expects just the interval in seconds const int qtCursorFlashTime = QGuiApplication::styleHints()->cursorFlashTime(); rendererPrefs->caret_blink_interval = 0.5 * static_cast<double>(qtCursorFlashTime) / 1000; - delegate->m_webContents->GetRenderViewHost()->SyncRendererPrefs(); + m_webContents->GetRenderViewHost()->SyncRendererPrefs(); - return delegate; + m_webContents->SetDelegate(this); + m_registrar.Add(this, content::NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED, content::Source<content::WebContents>(m_webContents.get())); } -content::WebContents* WebContentsDelegateQt::web_contents() +void WebContentsDelegateQt::Observe(int type, const content::NotificationSource& source, const content::NotificationDetails& details) { - return m_webContents.get(); + if (type == content::NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED) { + std::pair<content::NavigationEntry*, bool>* title = content::Details<std::pair<content::NavigationEntry*, bool> >(details).ptr(); + + if (title->first) { + string16 text = title->first->GetTitle(); + QString title = QString::fromUtf16(text.data()); + Q_EMIT titleChanged(title); + } + } } -void WebContentsDelegateQt::Observe(int, const content::NotificationSource&, const content::NotificationDetails&) +void WebContentsDelegateQt::NavigationStateChanged(const content::WebContents* source, unsigned changed_flags) { - // IMPLEMENT THIS!!!! + if (changed_flags & content::INVALIDATE_TYPE_URL) + Q_EMIT urlChanged(); } + +void WebContentsDelegateQt::LoadingStateChanged(content::WebContents* source) +{ + Q_EMIT loadingStateChanged(); +} + +content::WebContents* WebContentsDelegateQt::web_contents() +{ + return m_webContents.get(); +} + + diff --git a/lib/web_contents_delegate_qt.h b/lib/web_contents_delegate_qt.h index 6e4a16ff4..80776a2d4 100644 --- a/lib/web_contents_delegate_qt.h +++ b/lib/web_contents_delegate_qt.h @@ -43,7 +43,11 @@ #define WEB_CONTENTS_DELEGATE_QT #include "content/public/browser/notification_observer.h" +#include "content/public/browser/notification_registrar.h" #include "content/public/browser/web_contents_delegate.h" +#include "content/public/browser/web_contents.h" + +#include <QObject> namespace content { @@ -51,19 +55,28 @@ namespace content { class SiteInstance; } -class WebContentsDelegateQt : public content::WebContentsDelegate +class WebContentsDelegateQt : public QObject + , public content::WebContentsDelegate , public content::NotificationObserver { + Q_OBJECT public: - static WebContentsDelegateQt* CreateNewWindow(content::BrowserContext*, content::SiteInstance*, int routing_id, const gfx::Size& initial_size); + WebContentsDelegateQt(QObject* webContentsView, content::BrowserContext*, content::SiteInstance*, int routing_id, const gfx::Size& initial_size); content::WebContents* web_contents(); - virtual void Observe(int, const content::NotificationSource&, const content::NotificationDetails&); + virtual void Observe(int type, const content::NotificationSource&, const content::NotificationDetails&); + virtual void NavigationStateChanged(const content::WebContents* source, unsigned changed_flags); + virtual void LoadingStateChanged(content::WebContents* source); -private: - WebContentsDelegateQt(content::WebContents*); +Q_SIGNALS: + void titleChanged(QString title); + void urlChanged(); + void loadingStateChanged(); +private: scoped_ptr<content::WebContents> m_webContents; + content::NotificationRegistrar m_registrar; + QObject* m_webContentsView; }; #endif |