blob: 3255f22be64c15df4d0de0c9a5532380448c27a7 [file] [log] [blame]
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qquickwebenginefaviconprovider_p_p.h"
#include "favicon_manager.h"
#include "qquickwebengineview_p.h"
#include "qquickwebengineview_p_p.h"
#include "web_contents_adapter.h"
#include <QtGui/QIcon>
#include <QtGui/QPixmap>
QT_BEGIN_NAMESPACE
using QtWebEngineCore::FaviconInfo;
using QtWebEngineCore::FaviconManager;
static inline unsigned area(const QSize &size)
{
return size.width() * size.height();
}
QString QQuickWebEngineFaviconProvider::identifier()
{
return QStringLiteral("favicon");
}
QUrl QQuickWebEngineFaviconProvider::faviconProviderUrl(const QUrl &url)
{
if (url.isEmpty())
return url;
QUrl providerUrl;
providerUrl.setScheme(QStringLiteral("image"));
providerUrl.setHost(identifier());
providerUrl.setPath(QStringLiteral("/%1").arg(url.toString(QUrl::RemoveQuery | QUrl::RemoveFragment)));
if (url.hasQuery())
providerUrl.setQuery(url.query(QUrl::FullyDecoded));
if (url.hasFragment())
providerUrl.setFragment(url.fragment(QUrl::FullyDecoded));
return providerUrl;
}
QQuickWebEngineFaviconProvider::QQuickWebEngineFaviconProvider()
: QQuickImageProvider(QQuickImageProvider::Pixmap)
, m_latestView(0)
{
}
QQuickWebEngineFaviconProvider::~QQuickWebEngineFaviconProvider()
{
qDeleteAll(m_iconUrlMap);
}
QUrl QQuickWebEngineFaviconProvider::attach(QQuickWebEngineView *view, const QUrl &iconUrl)
{
if (iconUrl.isEmpty())
return QUrl();
m_latestView = view;
if (!m_iconUrlMap.contains(view))
m_iconUrlMap.insert(view, new QList<QUrl>());
QList<QUrl> *iconUrls = m_iconUrlMap[view];
if (!iconUrls->contains(iconUrl))
iconUrls->append(iconUrl);
return faviconProviderUrl(iconUrl);
}
void QQuickWebEngineFaviconProvider::detach(QQuickWebEngineView *view)
{
QList<QUrl> *iconUrls = m_iconUrlMap.take(view);
delete iconUrls;
}
QPixmap QQuickWebEngineFaviconProvider::requestPixmap(const QString &id, QSize *size, const QSize &requestedSize)
{
Q_UNUSED(size);
Q_UNUSED(requestedSize);
QUrl iconUrl(id);
QQuickWebEngineView *view = viewForIconUrl(iconUrl);
if (!view || iconUrl.isEmpty())
return QPixmap();
FaviconManager *faviconManager = view->d_ptr->adapter->faviconManager();
Q_ASSERT(faviconManager);
const FaviconInfo &faviconInfo = faviconManager->getFaviconInfo(iconUrl);
const QIcon &icon = faviconManager->getIcon(faviconInfo.candidate ? QUrl() : iconUrl);
Q_ASSERT(!icon.isNull());
const QSize &bestSize = faviconInfo.size;
// If source size is not specified, use the best quality
if (!requestedSize.isValid()) {
if (size)
*size = bestSize;
return icon.pixmap(bestSize).copy();
}
const QSize &fitSize = findFitSize(icon.availableSizes(), requestedSize, bestSize);
const QPixmap &iconPixmap = icon.pixmap(fitSize);
if (size)
*size = iconPixmap.size();
return iconPixmap.scaled(requestedSize, Qt::KeepAspectRatio, Qt::SmoothTransformation).copy();
}
QQuickWebEngineView *QQuickWebEngineFaviconProvider::viewForIconUrl(const QUrl &iconUrl) const
{
// The most common use case is that the requested iconUrl belongs to the
// latest WebEngineView which was raised an iconChanged signal.
if (m_latestView) {
QList<QUrl> *iconUrls = m_iconUrlMap[m_latestView];
if (iconUrls && iconUrls->contains(iconUrl))
return m_latestView;
}
for (auto it = m_iconUrlMap.cbegin(), end = m_iconUrlMap.cend(); it != end; ++it) {
if (it.value()->contains(iconUrl))
return it.key();
}
return 0;
}
QSize QQuickWebEngineFaviconProvider::findFitSize(const QList<QSize> &availableSizes,
const QSize &requestedSize,
const QSize &bestSize) const
{
Q_ASSERT(availableSizes.count());
if (availableSizes.count() == 1 || area(requestedSize) >= area(bestSize))
return bestSize;
QSize fitSize = bestSize;
for (const QSize &size : availableSizes) {
if (area(size) == area(requestedSize))
return size;
if (area(requestedSize) < area(size) && area(size) < area(fitSize))
fitSize = size;
}
return fitSize;
}
QT_END_NAMESPACE