mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-01-23 13:04:23 +00:00
Use alternative method for plugin favicon validity. Drop unnecessary code.
This commit is contained in:
parent
34c29b78f9
commit
c2a2d306da
@ -45,7 +45,6 @@ fspathedit.h
|
|||||||
fspathedit_p.h
|
fspathedit_p.h
|
||||||
guiiconprovider.h
|
guiiconprovider.h
|
||||||
hidabletabwidget.h
|
hidabletabwidget.h
|
||||||
ico.h
|
|
||||||
loglistwidget.h
|
loglistwidget.h
|
||||||
mainwindow.h
|
mainwindow.h
|
||||||
messageboxraised.h
|
messageboxraised.h
|
||||||
@ -87,7 +86,6 @@ executionlog.cpp
|
|||||||
fspathedit.cpp
|
fspathedit.cpp
|
||||||
fspathedit_p.cpp
|
fspathedit_p.cpp
|
||||||
guiiconprovider.cpp
|
guiiconprovider.cpp
|
||||||
ico.cpp
|
|
||||||
loglistwidget.cpp
|
loglistwidget.cpp
|
||||||
mainwindow.cpp
|
mainwindow.cpp
|
||||||
messageboxraised.cpp
|
messageboxraised.cpp
|
||||||
|
@ -19,7 +19,6 @@ HEADERS += \
|
|||||||
$$PWD/torrentcontenttreeview.h \
|
$$PWD/torrentcontenttreeview.h \
|
||||||
$$PWD/deletionconfirmationdlg.h \
|
$$PWD/deletionconfirmationdlg.h \
|
||||||
$$PWD/statusbar.h \
|
$$PWD/statusbar.h \
|
||||||
$$PWD/ico.h \
|
|
||||||
$$PWD/speedlimitdlg.h \
|
$$PWD/speedlimitdlg.h \
|
||||||
$$PWD/about_imp.h \
|
$$PWD/about_imp.h \
|
||||||
$$PWD/previewselect.h \
|
$$PWD/previewselect.h \
|
||||||
@ -63,7 +62,6 @@ HEADERS += \
|
|||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
$$PWD/mainwindow.cpp \
|
$$PWD/mainwindow.cpp \
|
||||||
$$PWD/ico.cpp \
|
|
||||||
$$PWD/transferlistwidget.cpp \
|
$$PWD/transferlistwidget.cpp \
|
||||||
$$PWD/transferlistsortmodel.cpp \
|
$$PWD/transferlistsortmodel.cpp \
|
||||||
$$PWD/transferlistdelegate.cpp \
|
$$PWD/transferlistdelegate.cpp \
|
||||||
|
460
src/gui/ico.cpp
460
src/gui/ico.cpp
@ -1,460 +0,0 @@
|
|||||||
/*
|
|
||||||
* kimgio import filter for MS Windows .ico files
|
|
||||||
*
|
|
||||||
* Distributed under the terms of the LGPL
|
|
||||||
* Copyright (c) 2000 Malte Starostik <malte@kde.org>
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "ico.h"
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <QImage>
|
|
||||||
#include <QBitmap>
|
|
||||||
#include <QApplication>
|
|
||||||
#include <QVector>
|
|
||||||
#include <QDesktopWidget>
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
// Global header (see http://www.daubnet.com/formats/ICO.html)
|
|
||||||
struct IcoHeader
|
|
||||||
{
|
|
||||||
enum Type { Icon = 1, Cursor };
|
|
||||||
quint16 reserved;
|
|
||||||
quint16 type;
|
|
||||||
quint16 count;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline QDataStream& operator >>( QDataStream& s, IcoHeader& h )
|
|
||||||
{
|
|
||||||
return s >> h.reserved >> h.type >> h.count;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Based on qt_read_dib et al. from qimage.cpp
|
|
||||||
// (c) 1992-2002 Trolltech AS.
|
|
||||||
struct BMP_INFOHDR
|
|
||||||
{
|
|
||||||
static const quint32 Size = 40;
|
|
||||||
quint32 biSize; // size of this struct
|
|
||||||
quint32 biWidth; // pixmap width
|
|
||||||
quint32 biHeight; // pixmap height
|
|
||||||
quint16 biPlanes; // should be 1
|
|
||||||
quint16 biBitCount; // number of bits per pixel
|
|
||||||
enum Compression { RGB = 0 };
|
|
||||||
quint32 biCompression; // compression method
|
|
||||||
quint32 biSizeImage; // size of image
|
|
||||||
quint32 biXPelsPerMeter; // horizontal resolution
|
|
||||||
quint32 biYPelsPerMeter; // vertical resolution
|
|
||||||
quint32 biClrUsed; // number of colors used
|
|
||||||
quint32 biClrImportant; // number of important colors
|
|
||||||
};
|
|
||||||
const quint32 BMP_INFOHDR::Size;
|
|
||||||
|
|
||||||
QDataStream& operator >>( QDataStream &s, BMP_INFOHDR &bi )
|
|
||||||
{
|
|
||||||
s >> bi.biSize;
|
|
||||||
if ( bi.biSize == BMP_INFOHDR::Size )
|
|
||||||
{
|
|
||||||
s >> bi.biWidth >> bi.biHeight >> bi.biPlanes >> bi.biBitCount;
|
|
||||||
s >> bi.biCompression >> bi.biSizeImage;
|
|
||||||
s >> bi.biXPelsPerMeter >> bi.biYPelsPerMeter;
|
|
||||||
s >> bi.biClrUsed >> bi.biClrImportant;
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
QDataStream &operator<<( QDataStream &s, const BMP_INFOHDR &bi )
|
|
||||||
{
|
|
||||||
s << bi.biSize;
|
|
||||||
s << bi.biWidth << bi.biHeight;
|
|
||||||
s << bi.biPlanes;
|
|
||||||
s << bi.biBitCount;
|
|
||||||
s << bi.biCompression;
|
|
||||||
s << bi.biSizeImage;
|
|
||||||
s << bi.biXPelsPerMeter << bi.biYPelsPerMeter;
|
|
||||||
s << bi.biClrUsed << bi.biClrImportant;
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Header for every icon in the file
|
|
||||||
struct IconRec
|
|
||||||
{
|
|
||||||
unsigned char width;
|
|
||||||
unsigned char height;
|
|
||||||
quint16 colors;
|
|
||||||
quint16 hotspotX;
|
|
||||||
quint16 hotspotY;
|
|
||||||
quint32 size;
|
|
||||||
quint32 offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline QDataStream& operator >>( QDataStream& s, IconRec& r )
|
|
||||||
{
|
|
||||||
return s >> r.width >> r.height >> r.colors
|
|
||||||
>> r.hotspotX >> r.hotspotY >> r.size >> r.offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct LessDifference
|
|
||||||
{
|
|
||||||
LessDifference( unsigned s, unsigned c )
|
|
||||||
: size( s ), colors( c ) {}
|
|
||||||
|
|
||||||
bool operator ()( const IconRec& lhs, const IconRec& rhs ) const
|
|
||||||
{
|
|
||||||
// closest size match precedes everything else
|
|
||||||
if ( std::abs( int( lhs.width - size ) ) <
|
|
||||||
std::abs( int( rhs.width - size ) ) ) return true;
|
|
||||||
else if ( std::abs( int( lhs.width - size ) ) >
|
|
||||||
std::abs( int( rhs.width - size ) ) ) return false;
|
|
||||||
else if ( colors == 0 )
|
|
||||||
{
|
|
||||||
// high/true color requested
|
|
||||||
if ( lhs.colors == 0 ) return true;
|
|
||||||
else if ( rhs.colors == 0 ) return false;
|
|
||||||
else return lhs.colors > rhs.colors;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// indexed icon requested
|
|
||||||
if ( lhs.colors == 0 && rhs.colors == 0 ) return false;
|
|
||||||
else if ( lhs.colors == 0 ) return false;
|
|
||||||
else return std::abs( int( lhs.colors - colors ) ) <
|
|
||||||
std::abs( int( rhs.colors - colors ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unsigned size;
|
|
||||||
unsigned colors;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool loadFromDIB( QDataStream& stream, const IconRec& rec, QImage& icon )
|
|
||||||
{
|
|
||||||
BMP_INFOHDR header;
|
|
||||||
stream >> header;
|
|
||||||
if ( stream.atEnd() || header.biSize != BMP_INFOHDR::Size ||
|
|
||||||
header.biSize > rec.size ||
|
|
||||||
header.biCompression != BMP_INFOHDR::RGB ||
|
|
||||||
( header.biBitCount != 1 && header.biBitCount != 4 &&
|
|
||||||
header.biBitCount != 8 && header.biBitCount != 24 &&
|
|
||||||
header.biBitCount != 32 ) ) return false;
|
|
||||||
|
|
||||||
unsigned paletteSize, paletteEntries;
|
|
||||||
|
|
||||||
if (header.biBitCount > 8)
|
|
||||||
{
|
|
||||||
paletteEntries = 0;
|
|
||||||
paletteSize = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
paletteSize = (1 << header.biBitCount);
|
|
||||||
paletteEntries = paletteSize;
|
|
||||||
if (header.biClrUsed && header.biClrUsed < paletteSize)
|
|
||||||
paletteEntries = header.biClrUsed;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Always create a 32-bit image to get the mask right
|
|
||||||
// Note: this is safe as rec.width, rec.height are bytes
|
|
||||||
icon = QImage( rec.width, rec.height, QImage::Format_ARGB32 );
|
|
||||||
if ( icon.isNull() ) return false;
|
|
||||||
|
|
||||||
QVector< QRgb > colorTable( paletteSize );
|
|
||||||
|
|
||||||
colorTable.fill( QRgb( 0 ) );
|
|
||||||
for ( unsigned i = 0; i < paletteEntries; ++i )
|
|
||||||
{
|
|
||||||
unsigned char rgb[ 4 ];
|
|
||||||
stream.readRawData( reinterpret_cast< char* >( &rgb ),
|
|
||||||
sizeof( rgb ) );
|
|
||||||
colorTable[ i ] = qRgb( rgb[ 2 ], rgb[ 1 ], rgb[ 0 ] );
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned bpl = ( rec.width * header.biBitCount + 31 ) / 32 * 4;
|
|
||||||
|
|
||||||
unsigned char* buf = new unsigned char[ bpl ];
|
|
||||||
for ( unsigned y = rec.height; !stream.atEnd() && y--; )
|
|
||||||
{
|
|
||||||
stream.readRawData( reinterpret_cast< char* >( buf ), bpl );
|
|
||||||
unsigned char* pixel = buf;
|
|
||||||
QRgb* p = reinterpret_cast< QRgb* >( icon.scanLine(y));
|
|
||||||
switch ( header.biBitCount )
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
for ( unsigned x = 0; x < rec.width; ++x )
|
|
||||||
*p++ = colorTable[
|
|
||||||
( pixel[ x / 8 ] >> ( 7 - ( x & 0x07 ) ) ) & 1 ];
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
for ( unsigned x = 0; x < rec.width; ++x )
|
|
||||||
if ( x & 1 ) *p++ = colorTable[ pixel[ x / 2 ] & 0x0f ];
|
|
||||||
else *p++ = colorTable[ pixel[ x / 2 ] >> 4 ];
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
for ( unsigned x = 0; x < rec.width; ++x )
|
|
||||||
*p++ = colorTable[ pixel[ x ] ];
|
|
||||||
break;
|
|
||||||
case 24:
|
|
||||||
for ( unsigned x = 0; x < rec.width; ++x )
|
|
||||||
*p++ = qRgb( pixel[ 3 * x + 2 ],
|
|
||||||
pixel[ 3 * x + 1 ],
|
|
||||||
pixel[ 3 * x ] );
|
|
||||||
break;
|
|
||||||
case 32:
|
|
||||||
for ( unsigned x = 0; x < rec.width; ++x )
|
|
||||||
*p++ = qRgba( pixel[ 4 * x + 2 ],
|
|
||||||
pixel[ 4 * x + 1 ],
|
|
||||||
pixel[ 4 * x ],
|
|
||||||
pixel[ 4 * x + 3] );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete[] buf;
|
|
||||||
|
|
||||||
if ( header.biBitCount < 32 )
|
|
||||||
{
|
|
||||||
// Traditional 1-bit mask
|
|
||||||
bpl = ( rec.width + 31 ) / 32 * 4;
|
|
||||||
buf = new unsigned char[ bpl ];
|
|
||||||
for ( unsigned y = rec.height; y--; )
|
|
||||||
{
|
|
||||||
stream.readRawData( reinterpret_cast< char* >( buf ), bpl );
|
|
||||||
QRgb* p = reinterpret_cast< QRgb* >(icon.scanLine(y));
|
|
||||||
for ( unsigned x = 0; x < rec.width; ++x, ++p )
|
|
||||||
if ( ( ( buf[ x / 8 ] >> ( 7 - ( x & 0x07 ) ) ) & 1 ) )
|
|
||||||
*p &= RGB_MASK;
|
|
||||||
}
|
|
||||||
delete[] buf;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ICOHandler::ICOHandler()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ICOHandler::canRead() const
|
|
||||||
{
|
|
||||||
if (canRead(device())) {
|
|
||||||
setFormat("ico");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ICOHandler::read(QImage *outImage)
|
|
||||||
{
|
|
||||||
|
|
||||||
qint64 offset = device()->pos();
|
|
||||||
|
|
||||||
QDataStream stream( device() );
|
|
||||||
stream.setByteOrder( QDataStream::LittleEndian );
|
|
||||||
IcoHeader header;
|
|
||||||
stream >> header;
|
|
||||||
if ( stream.atEnd() || !header.count ||
|
|
||||||
( header.type != IcoHeader::Icon && header.type != IcoHeader::Cursor) )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
unsigned requestedSize = 32;
|
|
||||||
unsigned requestedColors = QApplication::desktop()->depth() > 8 ? 0 : QApplication::desktop()->depth();
|
|
||||||
int requestedIndex = -1;
|
|
||||||
#if 0
|
|
||||||
if ( io->parameters() )
|
|
||||||
{
|
|
||||||
QStringList params = QString(io->parameters()).split( ';', QString::SkipEmptyParts );
|
|
||||||
QMap< QString, QString > options;
|
|
||||||
for ( QStringList::ConstIterator it = params.begin();
|
|
||||||
it != params.end(); ++it )
|
|
||||||
{
|
|
||||||
QStringList tmp = (*it).split( '=', QString::SkipEmptyParts );
|
|
||||||
if ( tmp.count() == 2 ) options[ tmp[ 0 ] ] = tmp[ 1 ];
|
|
||||||
}
|
|
||||||
if ( options[ "index" ].toUInt() )
|
|
||||||
requestedIndex = options[ "index" ].toUInt();
|
|
||||||
if ( options[ "size" ].toUInt() )
|
|
||||||
requestedSize = options[ "size" ].toUInt();
|
|
||||||
if ( options[ "colors" ].toUInt() )
|
|
||||||
requestedColors = options[ "colors" ].toUInt();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef std::vector< IconRec > IconList;
|
|
||||||
IconList icons;
|
|
||||||
for ( unsigned i = 0; i < header.count; ++i )
|
|
||||||
{
|
|
||||||
if ( stream.atEnd() )
|
|
||||||
return false;
|
|
||||||
IconRec rec;
|
|
||||||
stream >> rec;
|
|
||||||
icons.push_back( rec );
|
|
||||||
}
|
|
||||||
IconList::const_iterator selected;
|
|
||||||
if (requestedIndex >= 0) {
|
|
||||||
selected = std::min( icons.begin() + requestedIndex, icons.end() );
|
|
||||||
} else {
|
|
||||||
selected = std::min_element( icons.begin(), icons.end(),
|
|
||||||
LessDifference( requestedSize, requestedColors ) );
|
|
||||||
}
|
|
||||||
if ( stream.atEnd() || selected == icons.end() ||
|
|
||||||
offset + selected->offset > device()->size() )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
device()->seek( offset + selected->offset );
|
|
||||||
QImage icon;
|
|
||||||
if ( loadFromDIB( stream, *selected, icon ) )
|
|
||||||
{
|
|
||||||
icon.setText( "X-Index", QString::number( selected - icons.begin() ) );
|
|
||||||
if ( header.type == IcoHeader::Cursor )
|
|
||||||
{
|
|
||||||
icon.setText( "X-HotspotX", QString::number( selected->hotspotX ) );
|
|
||||||
icon.setText( "X-HotspotY", QString::number( selected->hotspotY ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
*outImage = icon;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ICOHandler::write(const QImage &/*image*/)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
if (image.isNull())
|
|
||||||
return;
|
|
||||||
|
|
||||||
QByteArray dibData;
|
|
||||||
QDataStream dib(dibData, QIODevice::ReadWrite);
|
|
||||||
dib.setByteOrder(QDataStream::LittleEndian);
|
|
||||||
|
|
||||||
QImage pixels = image;
|
|
||||||
QImage mask;
|
|
||||||
if (io->image().hasAlphaBuffer())
|
|
||||||
mask = image.createAlphaMask();
|
|
||||||
else
|
|
||||||
mask = image.createHeuristicMask();
|
|
||||||
mask.invertPixels();
|
|
||||||
for ( int y = 0; y < pixels.height(); ++y )
|
|
||||||
for ( int x = 0; x < pixels.width(); ++x )
|
|
||||||
if ( mask.pixel( x, y ) == 0 ) pixels.setPixel( x, y, 0 );
|
|
||||||
|
|
||||||
if (!qt_write_dib(dib, pixels))
|
|
||||||
return;
|
|
||||||
|
|
||||||
uint hdrPos = dib.device()->at();
|
|
||||||
if (!qt_write_dib(dib, mask))
|
|
||||||
return;
|
|
||||||
memmove(dibData.data() + hdrPos, dibData.data() + hdrPos + BMP_WIN + 8, dibData.size() - hdrPos - BMP_WIN - 8);
|
|
||||||
dibData.resize(dibData.size() - BMP_WIN - 8);
|
|
||||||
|
|
||||||
QDataStream ico(device());
|
|
||||||
ico.setByteOrder(QDataStream::LittleEndian);
|
|
||||||
IcoHeader hdr;
|
|
||||||
hdr.reserved = 0;
|
|
||||||
hdr.type = Icon;
|
|
||||||
hdr.count = 1;
|
|
||||||
ico << hdr.reserved << hdr.type << hdr.count;
|
|
||||||
IconRec rec;
|
|
||||||
rec.width = image.width();
|
|
||||||
rec.height = image.height();
|
|
||||||
if (image.numColors() <= 16)
|
|
||||||
rec.colors = 16;
|
|
||||||
else if (image.depth() <= 8)
|
|
||||||
rec.colors = 256;
|
|
||||||
else
|
|
||||||
rec.colors = 0;
|
|
||||||
rec.hotspotX = 0;
|
|
||||||
rec.hotspotY = 0;
|
|
||||||
rec.dibSize = dibData.size();
|
|
||||||
ico << rec.width << rec.height << rec.colors
|
|
||||||
<< rec.hotspotX << rec.hotspotY << rec.dibSize;
|
|
||||||
rec.dibOffset = ico.device()->at() + sizeof(rec.dibOffset);
|
|
||||||
ico << rec.dibOffset;
|
|
||||||
|
|
||||||
BMP_INFOHDR dibHeader;
|
|
||||||
dib.device()->at(0);
|
|
||||||
dib >> dibHeader;
|
|
||||||
dibHeader.biHeight = image.height() << 1;
|
|
||||||
dib.device()->at(0);
|
|
||||||
dib << dibHeader;
|
|
||||||
|
|
||||||
ico.writeRawBytes(dibData.data(), dibData.size());
|
|
||||||
return true;
|
|
||||||
#endif
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray ICOHandler::name() const
|
|
||||||
{
|
|
||||||
return "ico";
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ICOHandler::canRead(QIODevice *device)
|
|
||||||
{
|
|
||||||
if (!device) {
|
|
||||||
qWarning("ICOHandler::canRead() called with no device");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const qint64 oldPos = device->pos();
|
|
||||||
|
|
||||||
char head[8];
|
|
||||||
qint64 readBytes = device->read(head, sizeof(head));
|
|
||||||
const bool readOk = readBytes == sizeof(head);
|
|
||||||
|
|
||||||
if (device->isSequential()) {
|
|
||||||
while (readBytes > 0)
|
|
||||||
device->ungetChar(head[readBytes-- - 1]);
|
|
||||||
} else {
|
|
||||||
device->seek(oldPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !readOk )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return head[2] == '\001' && head[3] == '\000' && // type should be 1
|
|
||||||
( head[6] == 16 || head[6] == 32 || head[6] == 64 ) && // width can only be one of those
|
|
||||||
( head[7] == 16 || head[7] == 32 || head[7] == 64 ); // same for height
|
|
||||||
}
|
|
||||||
|
|
||||||
class ICOPlugin : public QImageIOPlugin
|
|
||||||
{
|
|
||||||
Q_PLUGIN_METADATA(IID "org.qbittorrent.ICOPlugin")
|
|
||||||
public:
|
|
||||||
QStringList keys() const;
|
|
||||||
Capabilities capabilities(QIODevice *device, const QByteArray &format) const;
|
|
||||||
QImageIOHandler *create(QIODevice *device, const QByteArray &format = QByteArray()) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
QStringList ICOPlugin::keys() const
|
|
||||||
{
|
|
||||||
return QStringList() << "ico" << "ICO";
|
|
||||||
}
|
|
||||||
|
|
||||||
QImageIOPlugin::Capabilities ICOPlugin::capabilities(QIODevice *device, const QByteArray &format) const
|
|
||||||
{
|
|
||||||
if (format == "ico" || format == "ICO")
|
|
||||||
return Capabilities(CanRead);
|
|
||||||
if (!format.isEmpty())
|
|
||||||
return 0;
|
|
||||||
if (!device->isOpen())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
Capabilities cap;
|
|
||||||
if (device->isReadable() && ICOHandler::canRead(device))
|
|
||||||
cap |= CanRead;
|
|
||||||
return cap;
|
|
||||||
}
|
|
||||||
|
|
||||||
QImageIOHandler *ICOPlugin::create(QIODevice *device, const QByteArray &format) const
|
|
||||||
{
|
|
||||||
QImageIOHandler *handler = new ICOHandler;
|
|
||||||
handler->setDevice(device);
|
|
||||||
handler->setFormat(format);
|
|
||||||
return handler;
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
/*
|
|
||||||
* ico.h - kimgio import filter for MS Windows .ico files
|
|
||||||
*
|
|
||||||
* Distributed under the terms of the LGPL
|
|
||||||
* Copyright (c) 2000 Malte Starostik <malte@kde.org>
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
// You can use QImageIO::setParameters() to request a specific
|
|
||||||
// Icon out of an .ico file:
|
|
||||||
//
|
|
||||||
// Options consist of a name=value pair and are separated by a semicolon.
|
|
||||||
// Available options are:
|
|
||||||
// size=<size> select the icon that most closely matches <size> (pixels)
|
|
||||||
// default: 32
|
|
||||||
// colors=<num> select the icon that has <num> colors (or comes closest)
|
|
||||||
// default: 1 << display depth or 0 (RGB) if display depth > 8
|
|
||||||
// index=<index> select the indexth icon from the file. If this option
|
|
||||||
// is present, the size and colors options will be ignored.
|
|
||||||
// default: none
|
|
||||||
// If both size and colors are given, size takes precedence.
|
|
||||||
//
|
|
||||||
// The old format is still supported:
|
|
||||||
// the parameters consist of a single string in the form
|
|
||||||
// "<size>[:<colors>]" which correspond to the options above
|
|
||||||
//
|
|
||||||
// If an icon was returned (i.e. the file is valid and the index option
|
|
||||||
// if present was not out of range), the icon's index within the .ico
|
|
||||||
// file is returned in the text tag "X-Index" of the image.
|
|
||||||
// If the icon is in fact a cursor, its hotspot coordinates are returned
|
|
||||||
// in the text tags "X-HotspotX" and "X-HotspotY".
|
|
||||||
|
|
||||||
#ifndef _ICO_H_
|
|
||||||
#define _ICO_H_
|
|
||||||
|
|
||||||
#include <QtGui/QImageIOPlugin>
|
|
||||||
|
|
||||||
class ICOHandler : public QImageIOHandler
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ICOHandler();
|
|
||||||
|
|
||||||
bool canRead() const;
|
|
||||||
bool read(QImage *outImage);
|
|
||||||
bool write(const QImage &image);
|
|
||||||
|
|
||||||
QByteArray name() const;
|
|
||||||
|
|
||||||
static bool canRead(QIODevice *device);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -39,12 +39,12 @@
|
|||||||
#include <QMimeData>
|
#include <QMimeData>
|
||||||
#include <QClipboard>
|
#include <QClipboard>
|
||||||
#include <QTableView>
|
#include <QTableView>
|
||||||
|
#include <QImageReader>
|
||||||
|
|
||||||
#include "base/utils/fs.h"
|
#include "base/utils/fs.h"
|
||||||
#include "base/utils/misc.h"
|
#include "base/utils/misc.h"
|
||||||
#include "base/net/downloadmanager.h"
|
#include "base/net/downloadmanager.h"
|
||||||
#include "base/net/downloadhandler.h"
|
#include "base/net/downloadhandler.h"
|
||||||
#include "ico.h"
|
|
||||||
#include "searchwidget.h"
|
#include "searchwidget.h"
|
||||||
#include "pluginsourcedlg.h"
|
#include "pluginsourcedlg.h"
|
||||||
#include "guiiconprovider.h"
|
#include "guiiconprovider.h"
|
||||||
@ -364,18 +364,33 @@ void PluginSelectDlg::iconDownloaded(const QString &url, QString filePath)
|
|||||||
filePath = Utils::Fs::fromNativePath(filePath);
|
filePath = Utils::Fs::fromNativePath(filePath);
|
||||||
|
|
||||||
// Icon downloaded
|
// Icon downloaded
|
||||||
QImage fileIcon;
|
QIcon icon(filePath);
|
||||||
if (fileIcon.load(filePath)) {
|
// Detect a non-decodable icon
|
||||||
|
QList<QSize> sizes = icon.availableSizes();
|
||||||
|
bool invalid = (sizes.isEmpty() || icon.pixmap(sizes.first()).isNull());
|
||||||
|
if (!invalid) {
|
||||||
foreach (QTreeWidgetItem *item, findItemsWithUrl(url)) {
|
foreach (QTreeWidgetItem *item, findItemsWithUrl(url)) {
|
||||||
QString id = item->text(PLUGIN_ID);
|
QString id = item->text(PLUGIN_ID);
|
||||||
PluginInfo *plugin = m_pluginManager->pluginInfo(id);
|
PluginInfo *plugin = m_pluginManager->pluginInfo(id);
|
||||||
if (!plugin) continue;
|
if (!plugin) continue;
|
||||||
|
|
||||||
QFile icon(filePath);
|
QString iconPath = QString("%1/%2.%3")
|
||||||
icon.open(QIODevice::ReadOnly);
|
.arg(SearchEngine::pluginsLocation())
|
||||||
QString iconPath = QString("%1/%2.%3").arg(SearchEngine::pluginsLocation()).arg(id).arg(ICOHandler::canRead(&icon) ? "ico" : "png");
|
.arg(id)
|
||||||
|
.arg(url.endsWith(".ico", Qt::CaseInsensitive) ? "ico" : "png");
|
||||||
if (QFile::copy(filePath, iconPath)) {
|
if (QFile::copy(filePath, iconPath)) {
|
||||||
item->setData(PLUGIN_NAME, Qt::DecorationRole, QVariant(QIcon(iconPath)));
|
// This 2nd check is necessary. Some favicons (eg from piratebay)
|
||||||
|
// decode fine without an ext, but fail to do so when appending the ext
|
||||||
|
// from the url. Probably a Qt bug.
|
||||||
|
QIcon iconWithExt(iconPath);
|
||||||
|
QList<QSize> sizesExt = iconWithExt.availableSizes();
|
||||||
|
bool invalidExt = (sizesExt.isEmpty() || iconWithExt.pixmap(sizesExt.first()).isNull());
|
||||||
|
if (invalidExt) {
|
||||||
|
Utils::Fs::forceRemove(iconPath);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
item->setData(PLUGIN_NAME, Qt::DecorationRole, iconWithExt);
|
||||||
m_pluginManager->updateIconPath(plugin);
|
m_pluginManager->updateIconPath(plugin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user