Skip to content
This repository has been archived by the owner on May 10, 2018. It is now read-only.

Commit

Permalink
Rewritten icon fetching in bookmarks importing, closes #24
Browse files Browse the repository at this point in the history
Instead of using QWebPage and then loading the whole page in order to
get icon, it is now using own IconFetcher class.
It simply download page, looks for <link rel=shortcut and downloads icon
from here. If no <link rel=shortcut is present, the downloading standard
favicon.ico from base directory.
  • Loading branch information
nowrep committed Oct 28, 2011
1 parent f951e6b commit 2f44e27
Show file tree
Hide file tree
Showing 13 changed files with 247 additions and 45 deletions.
Binary file modified bin/locale/sk_SK.qm
Binary file not shown.
5 changes: 5 additions & 0 deletions bin/themes/chrome/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,11 @@
background: transparent;
}

#sidebar-splitter::handle
{
background-color:transparent;
}

/*WebSearchBar*/
#websearchbar
{
Expand Down
5 changes: 5 additions & 0 deletions bin/themes/default/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,11 @@
background: transparent;
}

#sidebar-splitter::handle
{
background-color:transparent;
}

/*SourceViewer*/
#sourceviewer-textedit
{
Expand Down
5 changes: 5 additions & 0 deletions bin/themes/mac/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,11 @@
background: transparent;
}

#sidebar-splitter::handle
{
background-color:transparent;
}

/*WebSearchBar*/
#websearchbar
{
Expand Down
5 changes: 5 additions & 0 deletions bin/themes/windows/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,11 @@
background: transparent;
}

#sidebar-splitter::handle
{
background-color:transparent;
}

/*WebSearchBar*/
#websearchbar
{
Expand Down
8 changes: 6 additions & 2 deletions src/QupZilla.pro
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,8 @@ SOURCES += main.cpp\
bookmarksimport/firefoximporter.cpp \
bookmarksimport/chromeimporter.cpp \
bookmarksimport/operaimporter.cpp \
bookmarksimport/bookmarksimportdialog.cpp
bookmarksimport/bookmarksimportdialog.cpp \
tools/iconfetcher.cpp

HEADERS += \
3rdparty/qtwin.h \
Expand Down Expand Up @@ -275,7 +276,8 @@ HEADERS += \
bookmarksimport/firefoximporter.h \
bookmarksimport/chromeimporter.h \
bookmarksimport/operaimporter.h \
bookmarksimport/bookmarksimportdialog.h
bookmarksimport/bookmarksimportdialog.h \
tools/iconfetcher.h

FORMS += \
preferences/autofillmanager.ui \
Expand Down Expand Up @@ -404,6 +406,8 @@ message($$DEFINES)








1 change: 1 addition & 0 deletions src/app/qupzilla.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ void QupZilla::setupUi()
m_mainLayout->setContentsMargins(0,0,0,0);
m_mainLayout->setSpacing(0);
m_mainSplitter = new QSplitter(this);
m_mainSplitter->setObjectName("sidebar-splitter");
m_mainSplitter->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
m_tabWidget = new TabWidget(this);
m_superMenu = new QMenu(this);
Expand Down
2 changes: 1 addition & 1 deletion src/bookmarks/bookmarksmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ bool BookmarksModel::createFolder(const QString &name)
if (query.next())
return false;

query.prepare("INSERT INTO folders (name) VALUES (?)");
query.prepare("INSERT INTO folders (name, subfolder) VALUES (?, 'no')");
query.bindValue(0, name);
if (!query.exec())
return false;
Expand Down
62 changes: 34 additions & 28 deletions src/bookmarksimport/bookmarksimportdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include "chromeimporter.h"
#include "operaimporter.h"
#include "mainapplication.h"
#include "iconfetcher.h"
#include "networkmanager.h"

BookmarksImportDialog::BookmarksImportDialog(QWidget* parent)
: QDialog(parent)
Expand Down Expand Up @@ -80,42 +82,46 @@ void BookmarksImportDialog::startFetchingIcons()
ui->treeWidget->addTopLevelItem(item);
i++;

QWebPage* page = new QWebPage();
QWebFrame* frame = page->mainFrame();
frame->load(b.url);
connect(frame, SIGNAL(loadFinished(bool)), this, SLOT(loadFinished()));
connect(frame, SIGNAL(iconChanged()), this, SLOT(iconChanged()));
QPair<QWebFrame*, QUrl> pair;
pair.first = frame;
IconFetcher* fetcher = new IconFetcher(this);
fetcher->setNetworkAccessManager(mApp->networkManager());
connect(fetcher, SIGNAL(finished()), this, SLOT(loadFinished()));
connect(fetcher, SIGNAL(iconFetched(QIcon)), this, SLOT(iconFetched(QIcon)));
fetcher->fetchIcon(b.url);

QPair<IconFetcher*, QUrl> pair;
pair.first = fetcher;
pair.second = b.url;
m_webViews.append(pair);
m_fetchers.append(pair);
}
}

void BookmarksImportDialog::stopDownloading()
{
ui->nextButton->setEnabled(true);
ui->stopButton->hide();
ui->progressBar->setValue(ui->progressBar->maximum());
}

void BookmarksImportDialog::loadFinished()
{
ui->progressBar->setValue(ui->progressBar->value() + 1);

if (ui->progressBar->value() == ui->progressBar->maximum())
if (ui->progressBar->value() == ui->progressBar->maximum()) {
ui->stopButton->hide();
ui->nextButton->setEnabled(true);
}
}

void BookmarksImportDialog::iconChanged()
void BookmarksImportDialog::iconFetched(const QIcon &icon)
{
QWebFrame* view = qobject_cast<QWebFrame*>(sender());
if (!view)
IconFetcher* fetcher = qobject_cast<IconFetcher*>(sender());
if (!fetcher)
return;

QUrl url;
for (int i = 0; i < m_webViews.count(); i++) {
QPair<QWebFrame*, QUrl> pair = m_webViews.at(i);
if (pair.first == view) {
for (int i = 0; i < m_fetchers.count(); i++) {
QPair<IconFetcher*, QUrl> pair = m_fetchers.at(i);
if (pair.first == fetcher) {
url = pair.second;
break;
}
Expand All @@ -128,16 +134,16 @@ void BookmarksImportDialog::iconChanged()
if (items.count() == 0)
return;

QTreeWidgetItem* item = items.at(0);

item->setIcon(0, view->icon());
foreach (QTreeWidgetItem* item, items) {
item->setIcon(0, icon);

foreach (BookmarksModel::Bookmark b, m_exportedBookmarks) {
if (b.url == url) {
m_exportedBookmarks.removeOne(b);
b.icon = view->icon();
m_exportedBookmarks.append(b);
break;
foreach (BookmarksModel::Bookmark b, m_exportedBookmarks) {
if (b.url == url) {
m_exportedBookmarks.removeOne(b);
b.icon = icon;
m_exportedBookmarks.append(b);
break;
}
}
}
}
Expand Down Expand Up @@ -280,10 +286,10 @@ void BookmarksImportDialog::setupBrowser(Browser browser)

BookmarksImportDialog::~BookmarksImportDialog()
{
if (m_webViews.count() > 0) {
for (int i = 0; i < m_webViews.count(); i++) {tr("");
QWebFrame* frame= m_webViews.at(i).first;
delete frame->page();
if (m_fetchers.count() > 0) {
for (int i = 0; i < m_fetchers.count(); i++) {tr("");
IconFetcher* fetcher = m_fetchers.at(i).first;
delete fetcher;
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/bookmarksimport/bookmarksimportdialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ namespace Ui {
class BookmarksImportDialog;
}

class IconFetcher;
class BookmarksImportDialog : public QDialog
{
Q_OBJECT
Expand All @@ -27,9 +28,8 @@ private slots:
void nextPage();
void setFile();


void stopDownloading();
void iconChanged();
void iconFetched(const QIcon &icon);
void loadFinished();

private:
Expand All @@ -54,7 +54,7 @@ private slots:

QList<BookmarksModel::Bookmark> m_exportedBookmarks;

QList<QPair<QWebFrame*, QUrl> > m_webViews;
QList<QPair<IconFetcher*, QUrl> > m_fetchers;
};

#endif // BOOKMARKSIMPORTDIALOG_H
116 changes: 116 additions & 0 deletions src/tools/iconfetcher.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#include "iconfetcher.h"

#include <QDebug>

FollowRedirectReply::FollowRedirectReply(const QUrl &url, QNetworkAccessManager* manager)
: QObject()
, m_manager(manager)
, m_redirectCount(0)
{
m_reply = m_manager->get(QNetworkRequest(url));
connect(m_reply, SIGNAL(finished()), this, SLOT(replyFinished()));
}

void FollowRedirectReply::replyFinished()
{
int replyStatus = m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();

if ( (replyStatus != 301 && replyStatus != 302) || m_redirectCount == 5) {
emit finished();
return;
}
m_redirectCount++;

QUrl redirectUrl = m_reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
m_reply->close();
m_reply->deleteLater();

m_reply = m_manager->get(QNetworkRequest(redirectUrl));
connect(m_reply, SIGNAL(finished()), this, SLOT(replyFinished()));
}

FollowRedirectReply::~FollowRedirectReply()
{
m_reply->close();
m_reply->deleteLater();
}

IconFetcher::IconFetcher(QObject* parent)
: QObject(parent)
, m_manager(0)
{
}

void IconFetcher::fetchIcon(const QUrl &url)
{
if (!m_manager)
return;

FollowRedirectReply* reply = new FollowRedirectReply(url, m_manager);
connect(reply, SIGNAL(finished()), this, SLOT(pageDownloaded()));
}

void IconFetcher::pageDownloaded()
{
FollowRedirectReply* reply = qobject_cast<FollowRedirectReply*> (sender());
if (!reply)
return;

QString html = reply->reply()->readAll();
QUrl replyUrl = reply->reply()->url();
delete reply;

QRegExp rx("<link(.*)>", Qt::CaseInsensitive);
rx.setMinimal(true);

QString shortcutIconTag;
int pos = 0;
while ((pos = rx.indexIn(html, pos)) != -1) {
QString linkTag = rx.cap(0);
pos += rx.matchedLength();

if (linkTag.contains("rel=\"shortcut icon\"", Qt::CaseInsensitive)) {
shortcutIconTag = linkTag;
break;
}
}

FollowRedirectReply* newReply;
if (shortcutIconTag.isEmpty()) {
// QUrl faviconUrl = replyUrl.resolved(QUrl("favicon.ico"));
// Rather getting favicon.ico from base directory than from subfolders
QUrl faviconUrl = QUrl(replyUrl.toString(QUrl::RemovePath | QUrl::RemoveQuery) + "/favicon.ico");
newReply = new FollowRedirectReply(faviconUrl, m_manager);
}
else {
QRegExp rx("href=\"(.*)\"", Qt::CaseInsensitive);
rx.setMinimal(true);
rx.indexIn(shortcutIconTag);
QUrl url = QUrl(rx.cap(1));

QUrl iconUrl = QUrl(replyUrl).resolved(url);
newReply = new FollowRedirectReply(iconUrl, m_manager);
}

connect(newReply, SIGNAL(finished()), this, SLOT(iconDownloaded()));
}

void IconFetcher::iconDownloaded()
{
FollowRedirectReply* reply = qobject_cast<FollowRedirectReply*> (sender());
if (!reply)
return;

QByteArray response = reply->reply()->readAll();
delete reply;

if (!response.isEmpty()) {
QImage image;
image.loadFromData(response);
QIcon icon = QIcon(QPixmap::fromImage(image));
if (!icon.isNull())
emit iconFetched(icon);
}

emit finished();
}
Loading

0 comments on commit 2f44e27

Please sign in to comment.