diff options
author | Kirill Burtsev <kirill.burtsev@qt.io> | 2020-12-18 20:02:02 +0100 |
---|---|---|
committer | Kirill Burtsev <kirill.burtsev@qt.io> | 2021-06-04 18:41:46 +0200 |
commit | 742b9db0e34c8fc08e9f50c3053aed5f501f08d2 (patch) | |
tree | 81265ca9b3bee9f78389b8855c7cf565769e15ce /src/core/api | |
parent | 881339e9d9054c46f2621119246de7a13c83761a (diff) |
Merge WebEngineHistory's quick implementation into QWebEngineHistory
[ChangeLog][QWebEngineCore][QWebEngineHistory] New methods to access
navigation history as a model through new class QWebEngineHistoryModel.
[ChangeLog][QWebEngineQuick] QQuickWebEngineHistory is merged into QWebEngineHistory.
Task-number: QTBUG-74585
Change-Id: I9f9a73bbaf3954282dfc220cfc2c4cb08a37fb73
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'src/core/api')
-rw-r--r-- | src/core/api/qwebenginehistory.cpp | 256 | ||||
-rw-r--r-- | src/core/api/qwebenginehistory.h | 56 | ||||
-rw-r--r-- | src/core/api/qwebenginehistory_p.h | 60 | ||||
-rw-r--r-- | src/core/api/qwebenginepage.cpp | 6 |
4 files changed, 323 insertions, 55 deletions
diff --git a/src/core/api/qwebenginehistory.cpp b/src/core/api/qwebenginehistory.cpp index 08119d78c..bf2813bfb 100644 --- a/src/core/api/qwebenginehistory.cpp +++ b/src/core/api/qwebenginehistory.cpp @@ -50,50 +50,45 @@ QT_BEGIN_NAMESPACE */ QWebEngineHistoryItemPrivate::QWebEngineHistoryItemPrivate( - QtWebEngineCore::WebContentsAdapterClient *adapter, int index) - : m_adapter(adapter), index(index) + QtWebEngineCore::WebContentsAdapterClient *client, int index) + : client(client), index(index) { } -QWebEngineHistoryItem::QWebEngineHistoryItem(QWebEngineHistoryItemPrivate *d) : d(d) { } - -QWebEngineHistoryItem::QWebEngineHistoryItem(const QWebEngineHistoryItem &other) : d(other.d) { } - -QWebEngineHistoryItem &QWebEngineHistoryItem::operator=(const QWebEngineHistoryItem &other) +QtWebEngineCore::WebContentsAdapter *QWebEngineHistoryItemPrivate::adapter() const { - d = other.d; - return *this; + return client ? client->webContentsAdapter() : nullptr; } -QWebEngineHistoryItem::~QWebEngineHistoryItem() { } +QWebEngineHistoryItem::QWebEngineHistoryItem(QWebEngineHistoryItemPrivate *d) : d(d) { } +QWebEngineHistoryItem::QWebEngineHistoryItem(const QWebEngineHistoryItem &other) = default; +QWebEngineHistoryItem::QWebEngineHistoryItem(QWebEngineHistoryItem &&other) = default; +QWebEngineHistoryItem &QWebEngineHistoryItem::operator=(const QWebEngineHistoryItem &other) = default; +QWebEngineHistoryItem &QWebEngineHistoryItem::operator=(QWebEngineHistoryItem &&other) = default; +QWebEngineHistoryItem::~QWebEngineHistoryItem() = default; QUrl QWebEngineHistoryItem::originalUrl() const { Q_D(const QWebEngineHistoryItem); - return d->m_adapter - ? d->m_adapter->webContentsAdapter()->getNavigationEntryOriginalUrl(d->index) - : QUrl(); + return d->adapter() ? d->adapter()->getNavigationEntryOriginalUrl(d->index) : QUrl(); } QUrl QWebEngineHistoryItem::url() const { Q_D(const QWebEngineHistoryItem); - return d->m_adapter ? d->m_adapter->webContentsAdapter()->getNavigationEntryUrl(d->index) - : QUrl(); + return d->adapter() ? d->adapter()->getNavigationEntryUrl(d->index) : QUrl(); } QString QWebEngineHistoryItem::title() const { Q_D(const QWebEngineHistoryItem); - return d->m_adapter ? d->m_adapter->webContentsAdapter()->getNavigationEntryTitle(d->index) - : QString(); + return d->adapter() ? d->adapter()->getNavigationEntryTitle(d->index) : QString(); } QDateTime QWebEngineHistoryItem::lastVisited() const { Q_D(const QWebEngineHistoryItem); - return d->m_adapter ? d->m_adapter->webContentsAdapter()->getNavigationEntryTimestamp(d->index) - : QDateTime(); + return d->adapter() ? d->adapter()->getNavigationEntryTimestamp(d->index) : QDateTime(); } /*! @@ -104,22 +99,22 @@ QDateTime QWebEngineHistoryItem::lastVisited() const QUrl QWebEngineHistoryItem::iconUrl() const { Q_D(const QWebEngineHistoryItem); - return d->m_adapter ? d->m_adapter->webContentsAdapter()->getNavigationEntryIconUrl(d->index) - : QUrl(); + return d->adapter() ? d->adapter()->getNavigationEntryIconUrl(d->index) : QUrl(); } bool QWebEngineHistoryItem::isValid() const { Q_D(const QWebEngineHistoryItem); - if (!d->m_adapter) + if (!d->client) return false; - return d->index >= 0 && d->index < d->m_adapter->webContentsAdapter()->navigationEntryCount(); + return d->index >= 0 && d->index < d->adapter()->navigationEntryCount(); } -QWebEngineHistoryPrivate::QWebEngineHistoryPrivate( - QtWebEngineCore::WebContentsAdapterClient *adapter) - : m_adapter(adapter) +QWebEngineHistoryPrivate::QWebEngineHistoryPrivate(QtWebEngineCore::WebContentsAdapterClient *client, + const ImageProviderUrl &imageProviderUrl) + : client(client), imageProviderUrl(imageProviderUrl) { + Q_ASSERT(client); } QWebEngineHistoryPrivate::~QWebEngineHistoryPrivate() @@ -127,33 +122,175 @@ QWebEngineHistoryPrivate::~QWebEngineHistoryPrivate() // Invalidate shared item references possibly still out there. QList<QWebEngineHistoryItem>::iterator it, end; for (it = items.begin(), end = items.end(); it != end; ++it) - it->d->m_adapter = nullptr; + it->d->client = nullptr; } void QWebEngineHistoryPrivate::updateItems() const { // Keep track of items we return to be able to invalidate them - // and avoid dangling references to our m_adapter. - int entryCount = m_adapter->webContentsAdapter()->navigationEntryCount(); + // and avoid dangling references to our client. + int entryCount = adapter()->navigationEntryCount(); while (items.size() > entryCount) { - items.last().d->m_adapter = nullptr; + items.last().d->client = nullptr; items.removeLast(); } while (items.size() < entryCount) { int nextIndex = items.size(); - items.append(QWebEngineHistoryItem(new QWebEngineHistoryItemPrivate(m_adapter, nextIndex))); + items.append(QWebEngineHistoryItem(new QWebEngineHistoryItemPrivate(client, nextIndex))); + } +} + +QtWebEngineCore::WebContentsAdapter *QWebEngineHistoryPrivate::adapter() const +{ + Q_ASSERT(client->webContentsAdapter()); + return client->webContentsAdapter(); +} + +QWebEngineHistoryModelPrivate::QWebEngineHistoryModelPrivate(const QWebEngineHistoryPrivate *history) + : history(history) +{ + Q_ASSERT(history); +} + +QWebEngineHistoryModelPrivate::~QWebEngineHistoryModelPrivate() +{ +} + +QtWebEngineCore::WebContentsAdapter *QWebEngineHistoryModelPrivate::adapter() const +{ + Q_ASSERT(history->adapter()); + return history->adapter(); +} + +int QWebEngineHistoryModelPrivate::count() const +{ + return adapter()->navigationEntryCount(); +} + +int QWebEngineHistoryModelPrivate::index(int index) const +{ + return index; +} + +int QWebEngineHistoryModelPrivate::offsetForIndex(int index) const +{ + return index - adapter()->currentNavigationEntryIndex(); +} + +int QWebEngineBackHistoryModelPrivate::count() const +{ + return adapter()->currentNavigationEntryIndex(); +} + +int QWebEngineBackHistoryModelPrivate::index(int i) const +{ + Q_ASSERT(i >= 0 && i < count()); + return count() - 1 - i; +} + +int QWebEngineBackHistoryModelPrivate::offsetForIndex(int index) const +{ + return - index - 1; +} + +int QWebEngineForwardHistoryModelPrivate::count() const +{ + if (!adapter()->isInitialized()) + return 0; + return adapter()->navigationEntryCount() - adapter()->currentNavigationEntryIndex() - 1; +} + +int QWebEngineForwardHistoryModelPrivate::index(int i) const +{ + return adapter()->currentNavigationEntryIndex() + i + 1; +} + +int QWebEngineForwardHistoryModelPrivate::offsetForIndex(int index) const +{ + return index + 1; +} + +QWebEngineHistoryModel::QWebEngineHistoryModel(QWebEngineHistoryModelPrivate *d) + : d_ptr(d) +{ +} + +QWebEngineHistoryModel::~QWebEngineHistoryModel() +{ +} + +QHash<int, QByteArray> QWebEngineHistoryModel::roleNames() const +{ + QHash<int, QByteArray> roles; + roles[Qt::DisplayRole] = "display"; + roles[Qt::ToolTipRole] = "toolTip"; + roles[UrlRole] = "url"; + roles[TitleRole] = "title"; + roles[OffsetRole] = "offset"; + roles[IconUrlRole] = "icon"; + return roles; +} + +int QWebEngineHistoryModel::rowCount(const QModelIndex &index) const +{ + Q_UNUSED(index); + Q_D(const QWebEngineHistoryModel); + return d->count(); +} + +QVariant QWebEngineHistoryModel::data(const QModelIndex &index, int role) const +{ + Q_D(const QWebEngineHistoryModel); + + if (!index.isValid()) + return QVariant(); + + switch (role) { + case Qt::DisplayRole: + case TitleRole: + return d->adapter()->getNavigationEntryTitle(d->index(index.row())); + + case Qt::ToolTipRole: + case UrlRole: + return d->adapter()->getNavigationEntryUrl(d->index(index.row())); + + case OffsetRole: + return d->offsetForIndex(index.row()); + + case IconUrlRole: { + QUrl url = QUrl(d->adapter()->getNavigationEntryIconUrl(d->index(index.row()))); + return d->history->urlOrImageProviderUrl(url); + } + default: + break; } + + return QVariant(); +} + +void QWebEngineHistoryModel::reset() +{ + beginResetModel(); + endResetModel(); } QWebEngineHistory::QWebEngineHistory(QWebEngineHistoryPrivate *d) : d_ptr(d) { } QWebEngineHistory::~QWebEngineHistory() { } +/*! + \qmlmethod void WebEngineHistory::clear() + \since QtWebEngine 1.11 + + Clears the history. +*/ + void QWebEngineHistory::clear() { Q_D(const QWebEngineHistory); - d->m_adapter->webContentsAdapter()->clearNavigationHistory(); - d->m_adapter->updateNavigationActions(); + d->adapter()->clearNavigationHistory(); + d->client->updateNavigationActions(); + reset(); } QList<QWebEngineHistoryItem> QWebEngineHistory::items() const @@ -184,32 +321,32 @@ QList<QWebEngineHistoryItem> QWebEngineHistory::forwardItems(int maxItems) const bool QWebEngineHistory::canGoBack() const { Q_D(const QWebEngineHistory); - return d->m_adapter->webContentsAdapter()->canGoToOffset(-1); + return d->adapter()->canGoToOffset(-1); } bool QWebEngineHistory::canGoForward() const { Q_D(const QWebEngineHistory); - return d->m_adapter->webContentsAdapter()->canGoToOffset(1); + return d->adapter()->canGoToOffset(1); } void QWebEngineHistory::back() { Q_D(const QWebEngineHistory); - d->m_adapter->webContentsAdapter()->navigateToOffset(-1); + d->adapter()->navigateToOffset(-1); } void QWebEngineHistory::forward() { Q_D(const QWebEngineHistory); - d->m_adapter->webContentsAdapter()->navigateToOffset(1); + d->adapter()->navigateToOffset(1); } void QWebEngineHistory::goToItem(const QWebEngineHistoryItem &item) { Q_D(const QWebEngineHistory); - Q_ASSERT(item.d->m_adapter == d->m_adapter); - d->m_adapter->webContentsAdapter()->navigateToIndex(item.d->index); + Q_ASSERT(item.d->client == d->client); + d->adapter()->navigateToIndex(item.d->index); } QWebEngineHistoryItem QWebEngineHistory::backItem() const @@ -244,15 +381,50 @@ QWebEngineHistoryItem QWebEngineHistory::itemAt(int i) const int QWebEngineHistory::currentItemIndex() const { Q_D(const QWebEngineHistory); - return d->m_adapter->webContentsAdapter()->currentNavigationEntryIndex(); + return d->adapter()->currentNavigationEntryIndex(); } int QWebEngineHistory::count() const { Q_D(const QWebEngineHistory); - if (!d->m_adapter->webContentsAdapter()->isInitialized()) + if (!d->adapter()->isInitialized()) return 0; - return d->m_adapter->webContentsAdapter()->navigationEntryCount(); + return d->adapter()->navigationEntryCount(); +} + +QWebEngineHistoryModel *QWebEngineHistory::itemsModel() const +{ + Q_D(const QWebEngineHistory); + if (!d->navigationModel) + d->navigationModel.reset(new QWebEngineHistoryModel(new QWebEngineHistoryModelPrivate(d))); + return d->navigationModel.data(); +} + +QWebEngineHistoryModel *QWebEngineHistory::backItemsModel() const +{ + Q_D(const QWebEngineHistory); + if (!d->backNavigationModel) + d->backNavigationModel.reset(new QWebEngineHistoryModel(new QWebEngineBackHistoryModelPrivate(d))); + return d->backNavigationModel.data(); +} + +QWebEngineHistoryModel *QWebEngineHistory::forwardItemsModel() const +{ + Q_D(const QWebEngineHistory); + if (!d->forwardNavigationModel) + d->forwardNavigationModel.reset(new QWebEngineHistoryModel(new QWebEngineForwardHistoryModelPrivate(d))); + return d->forwardNavigationModel.data(); +} + +void QWebEngineHistory::reset() +{ + Q_D(QWebEngineHistory); + if (d->navigationModel) + d->navigationModel->reset(); + if (d->backNavigationModel) + d->backNavigationModel->reset(); + if (d->forwardNavigationModel) + d->forwardNavigationModel->reset(); } QT_END_NAMESPACE diff --git a/src/core/api/qwebenginehistory.h b/src/core/api/qwebenginehistory.h index f7e591e38..f572ba011 100644 --- a/src/core/api/qwebenginehistory.h +++ b/src/core/api/qwebenginehistory.h @@ -41,6 +41,7 @@ #define QWEBENGINEHISTORY_H #include <QtWebEngineCore/qtwebenginecoreglobal.h> +#include <QtCore/QAbstractListModel> #include <QtCore/qurl.h> #include <QtCore/qstring.h> #include <QtCore/qdatetime.h> @@ -50,15 +51,20 @@ QT_BEGIN_NAMESPACE class QWebEngineHistory; +class QWebEngineHistoryPrivate; class QWebEngineHistoryItemPrivate; +class QWebEngineHistoryModelPrivate; class QWebEnginePage; class QWebEnginePagePrivate; +class QQuickWebEngineViewPrivate; class Q_WEBENGINECORE_EXPORT QWebEngineHistoryItem { public: QWebEngineHistoryItem(const QWebEngineHistoryItem &other); + QWebEngineHistoryItem(QWebEngineHistoryItem &&other); QWebEngineHistoryItem &operator=(const QWebEngineHistoryItem &other); + QWebEngineHistoryItem &operator=(QWebEngineHistoryItem &&other); ~QWebEngineHistoryItem(); QUrl originalUrl() const; @@ -80,13 +86,47 @@ private: friend class QWebEngineHistoryPrivate; }; -Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QWebEngineHistoryItem) +Q_DECLARE_SHARED(QWebEngineHistoryItem) -class QWebEngineHistoryPrivate; -class Q_WEBENGINECORE_EXPORT QWebEngineHistory +class Q_WEBENGINECORE_EXPORT QWebEngineHistoryModel : public QAbstractListModel +{ + Q_OBJECT + +public: + enum Roles { + UrlRole = Qt::UserRole, + TitleRole, + OffsetRole, + IconUrlRole, + }; + + int rowCount(const QModelIndex& parent = QModelIndex()) const override; + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; + QHash<int, QByteArray> roleNames() const override; + void reset(); + +private: + QWebEngineHistoryModel(QWebEngineHistoryModelPrivate *); + virtual ~QWebEngineHistoryModel(); + + Q_DISABLE_COPY(QWebEngineHistoryModel) + Q_DECLARE_PRIVATE(QWebEngineHistoryModel) + QScopedPointer<QWebEngineHistoryModelPrivate> d_ptr; + + friend class QWebEngineHistory; + friend class QWebEngineHistoryPrivate; + friend void QScopedPointerDeleter<QWebEngineHistoryModel>::cleanup(QWebEngineHistoryModel *) noexcept; +}; + +class Q_WEBENGINECORE_EXPORT QWebEngineHistory : public QObject { + Q_OBJECT + Q_PROPERTY(QWebEngineHistoryModel *items READ itemsModel CONSTANT FINAL) + Q_PROPERTY(QWebEngineHistoryModel *backItems READ backItemsModel CONSTANT FINAL) + Q_PROPERTY(QWebEngineHistoryModel *forwardItems READ forwardItemsModel CONSTANT FINAL) + public: - void clear(); + Q_REVISION(1) Q_INVOKABLE void clear(); QList<QWebEngineHistoryItem> items() const; QList<QWebEngineHistoryItem> backItems(int maxItems) const; @@ -108,6 +148,10 @@ public: int count() const; + QWebEngineHistoryModel *itemsModel() const; + QWebEngineHistoryModel *backItemsModel() const; + QWebEngineHistoryModel *forwardItemsModel() const; + private: QWebEngineHistory(QWebEngineHistoryPrivate *d); ~QWebEngineHistory(); @@ -116,10 +160,14 @@ private: Q_DECLARE_PRIVATE(QWebEngineHistory) QScopedPointer<QWebEngineHistoryPrivate> d_ptr; + void reset(); + friend Q_WEBENGINECORE_EXPORT QDataStream &operator>>(QDataStream &, QWebEngineHistory &); friend Q_WEBENGINECORE_EXPORT QDataStream &operator<<(QDataStream &, const QWebEngineHistory &); friend class QWebEnginePage; friend class QWebEnginePagePrivate; + friend class QQuickWebEngineViewPrivate; + friend void QScopedPointerDeleter<QWebEngineHistory>::cleanup(QWebEngineHistory *) noexcept; }; QT_END_NAMESPACE diff --git a/src/core/api/qwebenginehistory_p.h b/src/core/api/qwebenginehistory_p.h index 2ca944e5b..fb52f799c 100644 --- a/src/core/api/qwebenginehistory_p.h +++ b/src/core/api/qwebenginehistory_p.h @@ -51,33 +51,83 @@ // We mean it. // #include "qtwebenginecoreglobal_p.h" +#include "qwebenginehistory.h" #include <QtCore/qshareddata.h> namespace QtWebEngineCore { +class WebContentsAdapter; class WebContentsAdapterClient; } QT_BEGIN_NAMESPACE + class QWebEnginePagePrivate; class QWebEngineHistoryItemPrivate : public QSharedData { public: - QWebEngineHistoryItemPrivate(QtWebEngineCore::WebContentsAdapterClient *adapter = nullptr, - int index = 0); - QtWebEngineCore::WebContentsAdapterClient *m_adapter; + QWebEngineHistoryItemPrivate(QtWebEngineCore::WebContentsAdapterClient *client = nullptr, int index = 0); + QtWebEngineCore::WebContentsAdapter *adapter() const; + QtWebEngineCore::WebContentsAdapterClient *client; int index; }; +class QWebEngineHistoryModelPrivate +{ +public: + QWebEngineHistoryModelPrivate(const QWebEngineHistoryPrivate *history); + virtual ~QWebEngineHistoryModelPrivate(); + + virtual int count() const; + virtual int index(int) const; + virtual int offsetForIndex(int) const; + + QtWebEngineCore::WebContentsAdapter *adapter() const; + const QWebEngineHistoryPrivate *history; +}; + +class QWebEngineBackHistoryModelPrivate : public QWebEngineHistoryModelPrivate +{ +public: + QWebEngineBackHistoryModelPrivate(const QWebEngineHistoryPrivate *history) + : QWebEngineHistoryModelPrivate(history) { } + + int count() const override; + int index(int) const override; + int offsetForIndex(int) const override; +}; + +class QWebEngineForwardHistoryModelPrivate : public QWebEngineHistoryModelPrivate +{ +public: + QWebEngineForwardHistoryModelPrivate(const QWebEngineHistoryPrivate *history) + : QWebEngineHistoryModelPrivate(history) { } + + int count() const override; + int index(int) const override; + int offsetForIndex(int) const override; +}; + class Q_WEBENGINECORE_PRIVATE_EXPORT QWebEngineHistoryPrivate { public: - QWebEngineHistoryPrivate(QtWebEngineCore::WebContentsAdapterClient *adapter); + typedef std::function<QUrl (const QUrl &)> ImageProviderUrl; + QWebEngineHistoryPrivate(QtWebEngineCore::WebContentsAdapterClient *client, + const ImageProviderUrl &imageProviderUrl = ImageProviderUrl()); ~QWebEngineHistoryPrivate(); + void updateItems() const; + QtWebEngineCore::WebContentsAdapter *adapter() const; + + QtWebEngineCore::WebContentsAdapterClient *client; + + ImageProviderUrl imageProviderUrl; + QUrl urlOrImageProviderUrl(const QUrl &url) const { return imageProviderUrl ? imageProviderUrl(url) : url; } - QtWebEngineCore::WebContentsAdapterClient *m_adapter; mutable QList<QWebEngineHistoryItem> items; + mutable QScopedPointer<QWebEngineHistoryModel> navigationModel; + mutable QScopedPointer<QWebEngineHistoryModel> backNavigationModel; + mutable QScopedPointer<QWebEngineHistoryModel> forwardNavigationModel; }; QT_END_NAMESPACE diff --git a/src/core/api/qwebenginepage.cpp b/src/core/api/qwebenginepage.cpp index 64b4f4d99..460b5a351 100644 --- a/src/core/api/qwebenginepage.cpp +++ b/src/core/api/qwebenginepage.cpp @@ -2389,8 +2389,7 @@ QWebEnginePage* QWebEnginePage::fromDownloadRequest(QWebEngineDownloadRequest *r QDataStream &operator<<(QDataStream &stream, const QWebEngineHistory &history) { - QtWebEngineCore::WebContentsAdapter *adapter = - history.d_func()->m_adapter->webContentsAdapter(); + auto adapter = history.d_func()->adapter(); if (!adapter->isInitialized()) adapter->loadDefault(); adapter->serializeNavigationHistory(stream); @@ -2399,8 +2398,7 @@ QDataStream &operator<<(QDataStream &stream, const QWebEngineHistory &history) QDataStream &operator>>(QDataStream &stream, QWebEngineHistory &history) { - static_cast<QWebEnginePagePrivate *>(history.d_func()->m_adapter) - ->recreateFromSerializedHistory(stream); + static_cast<QWebEnginePagePrivate *>(history.d_func()->client)->recreateFromSerializedHistory(stream); return stream; } |