mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-01-25 14:04:23 +00:00
Merge pull request #6156 from evsh/file-icons
Use system file type specific icons in contents tab
This commit is contained in:
commit
8e6df572a8
@ -14,6 +14,9 @@ find_package(LibtorrentRasterbar REQUIRED)
|
|||||||
list(APPEND QBT_QT_COMPONENTS Core Network Xml)
|
list(APPEND QBT_QT_COMPONENTS Core Network Xml)
|
||||||
if (GUI)
|
if (GUI)
|
||||||
list (APPEND QBT_QT_COMPONENTS Concurrent Gui Widgets)
|
list (APPEND QBT_QT_COMPONENTS Concurrent Gui Widgets)
|
||||||
|
if (WIN32)
|
||||||
|
list (APPEND QBT_QT_COMPONENTS WinExtras)
|
||||||
|
endif(WIN32)
|
||||||
endif (GUI)
|
endif (GUI)
|
||||||
if (DBUS)
|
if (DBUS)
|
||||||
list (APPEND QBT_QT_COMPONENTS DBus)
|
list (APPEND QBT_QT_COMPONENTS DBus)
|
||||||
|
@ -150,3 +150,6 @@ target_link_libraries(qbt_gui qbt_lineedit qbt_powermanagement qbt_rss qbt_prope
|
|||||||
${QBT_GUI_OPTIONAL_LINK_LIBRARIES} qbt_base
|
${QBT_GUI_OPTIONAL_LINK_LIBRARIES} qbt_base
|
||||||
QtSingleApplication::QtSingleApplication
|
QtSingleApplication::QtSingleApplication
|
||||||
)
|
)
|
||||||
|
if(WIN32)
|
||||||
|
target_link_libraries(qbt_gui Qt5::WinExtras)
|
||||||
|
endif(WIN32)
|
||||||
|
@ -29,8 +29,19 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
#include <QFileIconProvider>
|
||||||
|
#include <QFileInfo>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <Shellapi.h>
|
||||||
|
#include <QtWin>
|
||||||
|
#else
|
||||||
|
#include <QMimeDatabase>
|
||||||
|
#include <QMimeType>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "guiiconprovider.h"
|
#include "guiiconprovider.h"
|
||||||
#include "base/utils/misc.h"
|
#include "base/utils/misc.h"
|
||||||
#include "base/utils/fs.h"
|
#include "base/utils/fs.h"
|
||||||
@ -47,21 +58,97 @@ namespace
|
|||||||
return cached;
|
return cached;
|
||||||
}
|
}
|
||||||
|
|
||||||
QIcon getFileIcon()
|
class UnifiedFileIconProvider: public QFileIconProvider
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
using QFileIconProvider::icon;
|
||||||
|
QIcon icon(const QFileInfo &info) const override
|
||||||
|
{
|
||||||
|
Q_UNUSED(info);
|
||||||
static QIcon cached = GuiIconProvider::instance()->getIcon("text-plain");
|
static QIcon cached = GuiIconProvider::instance()->getIcon("text-plain");
|
||||||
return cached;
|
return cached;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
// See QTBUG-25319 for explanation why this is required
|
||||||
|
class WinShellFileIconProvider: public UnifiedFileIconProvider
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using QFileIconProvider::icon;
|
||||||
|
QIcon icon(const QFileInfo &info) const override
|
||||||
|
{
|
||||||
|
SHFILEINFO sfi = { 0 };
|
||||||
|
HRESULT hr = ::SHGetFileInfoW(info.absoluteFilePath().toStdWString().c_str(),
|
||||||
|
FILE_ATTRIBUTE_NORMAL, &sfi, sizeof(sfi), SHGFI_ICON | SHGFI_USEFILEATTRIBUTES);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return UnifiedFileIconProvider::icon(info);
|
||||||
|
|
||||||
|
QPixmap iconPixmap = QtWin::fromHICON(sfi.hIcon);
|
||||||
|
::DestroyIcon(sfi.hIcon);
|
||||||
|
return QIcon(iconPixmap);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
/**
|
||||||
|
* @brief Tests whether QFileIconProvider actually works
|
||||||
|
*
|
||||||
|
* Some QPA plugins do not implement QPlatformTheme::fileIcon(), and
|
||||||
|
* QFileIconProvider::icon() returns empty icons as the result. Here we ask it for
|
||||||
|
* two icons for probably absent files and when both icons are null, we assume that
|
||||||
|
* the current QPA plugin does not implement QPlatformTheme::fileIcon().
|
||||||
|
*/
|
||||||
|
bool doesQFileIconProviderWork()
|
||||||
|
{
|
||||||
|
QFileIconProvider provider;
|
||||||
|
const char PSEUDO_UNIQUE_FILE_NAME[] = "/tmp/qBittorrent-test-QFileIconProvider-845eb448-7ad5-4cdb-b764-b3f322a266a9";
|
||||||
|
QIcon testIcon1 = provider.icon(QFileInfo(
|
||||||
|
QLatin1String(PSEUDO_UNIQUE_FILE_NAME) + QLatin1String(".pdf")));
|
||||||
|
QIcon testIcon2 = provider.icon(QFileInfo(
|
||||||
|
QLatin1String(PSEUDO_UNIQUE_FILE_NAME) + QLatin1String(".png")));
|
||||||
|
|
||||||
|
return (!testIcon1.isNull() || !testIcon2.isNull());
|
||||||
|
}
|
||||||
|
|
||||||
|
class MimeFileIconProvider: public UnifiedFileIconProvider
|
||||||
|
{
|
||||||
|
using QFileIconProvider::icon;
|
||||||
|
QIcon icon(const QFileInfo &info) const override
|
||||||
|
{
|
||||||
|
const QMimeType mimeType = m_db.mimeTypeForFile(info, QMimeDatabase::MatchExtension);
|
||||||
|
QIcon res = QIcon::fromTheme(mimeType.iconName());
|
||||||
|
if (!res.isNull()) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = QIcon::fromTheme(mimeType.genericIconName());
|
||||||
|
if (!res.isNull()) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
return UnifiedFileIconProvider::icon(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QMimeDatabase m_db;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TorrentContentModel::TorrentContentModel(QObject *parent)
|
TorrentContentModel::TorrentContentModel(QObject *parent)
|
||||||
: QAbstractItemModel(parent)
|
: QAbstractItemModel(parent)
|
||||||
, m_rootItem(new TorrentContentModelFolder(QList<QVariant>({ tr("Name"), tr("Size"), tr("Progress"), tr("Download Priority"), tr("Remaining"), tr("Availability") })))
|
, m_rootItem(new TorrentContentModelFolder(QList<QVariant>({ tr("Name"), tr("Size"), tr("Progress"), tr("Download Priority"), tr("Remaining"), tr("Availability") })))
|
||||||
{
|
{
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
m_fileIconProvider = new WinShellFileIconProvider();
|
||||||
|
#else
|
||||||
|
static bool doesBuiltInProviderWork = doesQFileIconProviderWork();
|
||||||
|
m_fileIconProvider = doesBuiltInProviderWork ? new QFileIconProvider() : new MimeFileIconProvider();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TorrentContentModel::~TorrentContentModel()
|
TorrentContentModel::~TorrentContentModel()
|
||||||
{
|
{
|
||||||
|
delete m_fileIconProvider;
|
||||||
delete m_rootItem;
|
delete m_rootItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,7 +289,7 @@ QVariant TorrentContentModel::data(const QModelIndex& index, int role) const
|
|||||||
if (item->itemType() == TorrentContentModelItem::FolderType)
|
if (item->itemType() == TorrentContentModelItem::FolderType)
|
||||||
return getDirectoryIcon();
|
return getDirectoryIcon();
|
||||||
else
|
else
|
||||||
return getFileIcon();
|
return m_fileIconProvider->icon(QFileInfo(item->name()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((index.column() == TorrentContentModelItem::COL_NAME) && (role == Qt::CheckStateRole)) {
|
if ((index.column() == TorrentContentModelItem::COL_NAME) && (role == Qt::CheckStateRole)) {
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
#include "base/bittorrent/torrentinfo.h"
|
#include "base/bittorrent/torrentinfo.h"
|
||||||
#include "torrentcontentmodelitem.h"
|
#include "torrentcontentmodelitem.h"
|
||||||
|
|
||||||
|
class QFileIconProvider;
|
||||||
class TorrentContentModelFile;
|
class TorrentContentModelFile;
|
||||||
|
|
||||||
class TorrentContentModel: public QAbstractItemModel
|
class TorrentContentModel: public QAbstractItemModel
|
||||||
@ -54,16 +55,16 @@ public:
|
|||||||
void updateFilesAvailability(const QVector<qreal> &fa);
|
void updateFilesAvailability(const QVector<qreal> &fa);
|
||||||
QVector<int> getFilePriorities() const;
|
QVector<int> getFilePriorities() const;
|
||||||
bool allFiltered() const;
|
bool allFiltered() const;
|
||||||
virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole);
|
bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override;
|
||||||
TorrentContentModelItem::ItemType itemType(const QModelIndex& index) const;
|
TorrentContentModelItem::ItemType itemType(const QModelIndex& index) const;
|
||||||
int getFileIndex(const QModelIndex& index);
|
int getFileIndex(const QModelIndex& index);
|
||||||
virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
|
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||||
virtual Qt::ItemFlags flags(const QModelIndex& index) const;
|
Qt::ItemFlags flags(const QModelIndex& index) const override;
|
||||||
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||||
virtual QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const;
|
QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override;
|
||||||
virtual QModelIndex parent(const QModelIndex& index) const;
|
QModelIndex parent(const QModelIndex& index) const override;
|
||||||
virtual int rowCount(const QModelIndex& parent = QModelIndex()) const;
|
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||||
void clear();
|
void clear();
|
||||||
void setupModelData(const BitTorrent::TorrentInfo &info);
|
void setupModelData(const BitTorrent::TorrentInfo &info);
|
||||||
|
|
||||||
@ -77,6 +78,7 @@ public slots:
|
|||||||
private:
|
private:
|
||||||
TorrentContentModelFolder *m_rootItem;
|
TorrentContentModelFolder *m_rootItem;
|
||||||
QVector<TorrentContentModelFile *> m_filesIndex;
|
QVector<TorrentContentModelFile *> m_filesIndex;
|
||||||
|
QFileIconProvider *m_fileIconProvider;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TORRENTCONTENTMODEL_H
|
#endif // TORRENTCONTENTMODEL_H
|
||||||
|
@ -28,6 +28,9 @@ nogui {
|
|||||||
DEFINES += QBT_STATIC_QT
|
DEFINES += QBT_STATIC_QT
|
||||||
QTPLUGIN += qico
|
QTPLUGIN += qico
|
||||||
}
|
}
|
||||||
|
win32 {
|
||||||
|
QT += winextras
|
||||||
|
}
|
||||||
TARGET = qbittorrent
|
TARGET = qbittorrent
|
||||||
}
|
}
|
||||||
nowebui: DEFINES += DISABLE_WEBUI
|
nowebui: DEFINES += DISABLE_WEBUI
|
||||||
|
Loading…
x
Reference in New Issue
Block a user