source: trunk/qt/favicon.cc @ 14163

Last change on this file since 14163 was 14163, checked in by jordan, 9 years ago

(trunk, qt) #5465: restore Qt 4.6 support, patch by mike.did

  • Property svn:keywords set to Date Rev Author Id
File size: 3.6 KB
Line 
1/*
2 * This file Copyright (C) Mnemosyne LLC
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2
6 * as published by the Free Software Foundation.
7 *
8 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
9 *
10 * $Id: favicon.cc 14163 2013-08-17 16:22:56Z jordan $
11 */
12
13#include <QDir>
14#include <QNetworkAccessManager>
15#include <QNetworkReply>
16#include <QNetworkRequest>
17
18#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
19 #include <QDesktopServices>
20#else
21 #include <QStandardPaths>
22#endif
23
24#include "favicon.h"
25
26/***
27****
28***/
29
30Favicons :: Favicons( )
31{
32    myNAM = new QNetworkAccessManager( );
33    connect( myNAM, SIGNAL(finished(QNetworkReply*)), this, SLOT(onRequestFinished(QNetworkReply*)) );
34}
35
36Favicons :: ~Favicons( )
37{
38    delete myNAM;
39}
40
41/***
42****
43***/
44
45QString
46Favicons :: getCacheDir( )
47{
48    const QString base =
49#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
50        QDesktopServices::storageLocation( QDesktopServices::CacheLocation );
51#else
52        QStandardPaths::writableLocation( QStandardPaths::CacheLocation );
53#endif
54
55    return QDir( base ).absoluteFilePath( "favicons" );
56}
57
58void
59Favicons :: ensureCacheDirHasBeenScanned( )
60{
61    static bool hasBeenScanned = false;
62
63    if( !hasBeenScanned )
64    {
65        hasBeenScanned = true;
66
67        QDir cacheDir( getCacheDir( ) );
68        cacheDir.mkpath( cacheDir.absolutePath( ) );
69
70        QStringList files = cacheDir.entryList( QDir::Files|QDir::Readable );
71        foreach( QString file, files ) {
72            QPixmap pixmap;
73            pixmap.load( cacheDir.absoluteFilePath( file ) );
74            if( !pixmap.isNull( ) )
75                myPixmaps.insert( file, pixmap );
76        }
77    }
78}
79
80QString
81Favicons :: getHost( const QUrl& url )
82{
83    QString host = url.host( );
84    const int first_dot = host.indexOf( '.' );
85    const int last_dot = host.lastIndexOf( '.' );
86
87    if( ( first_dot != -1 ) && ( last_dot != -1 ) && ( first_dot != last_dot ) )
88        host.remove( 0, first_dot + 1 );
89
90    return host;
91}
92
93QPixmap
94Favicons :: find( const QUrl& url )
95{
96    return findFromHost( getHost( url ) );
97}
98
99namespace
100{
101    const QSize rightSize( 16, 16 );
102};
103
104QPixmap
105Favicons :: findFromHost( const QString& host )
106{
107    ensureCacheDirHasBeenScanned( );
108
109    const QPixmap pixmap = myPixmaps[ host ];
110    return pixmap.size()==rightSize ? pixmap : pixmap.scaled(rightSize);
111}
112
113void
114Favicons :: add( const QUrl& url )
115{
116    ensureCacheDirHasBeenScanned( );
117
118    const QString host = getHost( url );
119
120    if( !myPixmaps.contains( host ) )
121    {
122        // add a placholder s.t. we only ping the server once per session
123        QPixmap tmp( rightSize );
124        tmp.fill( Qt::transparent );
125        myPixmaps.insert( host, tmp );
126
127        // try to download the favicon
128        const QString path = "http://" + host + "/favicon.";
129        QStringList suffixes;
130        suffixes << "ico" << "png" << "gif" << "jpg";
131        foreach( QString suffix, suffixes )
132            myNAM->get( QNetworkRequest( path + suffix ) );
133    }
134}
135
136void
137Favicons :: onRequestFinished( QNetworkReply * reply )
138{
139    const QString host = reply->url().host();
140
141    QPixmap pixmap;
142
143    const QByteArray content = reply->readAll( );
144    if( !reply->error( ) )
145        pixmap.loadFromData( content );
146
147    if( !pixmap.isNull( ) )
148    {
149        // save it in memory...
150        myPixmaps.insert( host, pixmap );
151
152        // save it on disk...
153        QDir cacheDir( getCacheDir( ) );
154        cacheDir.mkpath( cacheDir.absolutePath( ) );
155        QFile file( cacheDir.absoluteFilePath( host ) );
156        file.open( QIODevice::WriteOnly );
157        file.write( content );
158        file.close( );
159
160        // notify listeners
161        emit pixmapReady( host );
162    }
163}
Note: See TracBrowser for help on using the repository browser.