mirror of
https://github.com/c0re100/qBittorrent-Enhanced-Edition.git
synced 2025-01-09 04:18:39 +08: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)
|
||||
if (GUI)
|
||||
list (APPEND QBT_QT_COMPONENTS Concurrent Gui Widgets)
|
||||
if (WIN32)
|
||||
list (APPEND QBT_QT_COMPONENTS WinExtras)
|
||||
endif(WIN32)
|
||||
endif (GUI)
|
||||
if (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
|
||||
QtSingleApplication::QtSingleApplication
|
||||
)
|
||||
if(WIN32)
|
||||
target_link_libraries(qbt_gui Qt5::WinExtras)
|
||||
endif(WIN32)
|
||||
|
@ -29,8 +29,19 @@
|
||||
*/
|
||||
|
||||
#include <QDir>
|
||||
#include <QFileIconProvider>
|
||||
#include <QFileInfo>
|
||||
#include <QIcon>
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include <Windows.h>
|
||||
#include <Shellapi.h>
|
||||
#include <QtWin>
|
||||
#else
|
||||
#include <QMimeDatabase>
|
||||
#include <QMimeType>
|
||||
#endif
|
||||
|
||||
#include "guiiconprovider.h"
|
||||
#include "base/utils/misc.h"
|
||||
#include "base/utils/fs.h"
|
||||
@ -47,21 +58,97 @@ namespace
|
||||
return cached;
|
||||
}
|
||||
|
||||
QIcon getFileIcon()
|
||||
class UnifiedFileIconProvider: public QFileIconProvider
|
||||
{
|
||||
static QIcon cached = GuiIconProvider::instance()->getIcon("text-plain");
|
||||
return cached;
|
||||
public:
|
||||
using QFileIconProvider::icon;
|
||||
QIcon icon(const QFileInfo &info) const override
|
||||
{
|
||||
Q_UNUSED(info);
|
||||
static QIcon cached = GuiIconProvider::instance()->getIcon("text-plain");
|
||||
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)
|
||||
: QAbstractItemModel(parent)
|
||||
, 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()
|
||||
{
|
||||
delete m_fileIconProvider;
|
||||
delete m_rootItem;
|
||||
}
|
||||
|
||||
@ -202,7 +289,7 @@ QVariant TorrentContentModel::data(const QModelIndex& index, int role) const
|
||||
if (item->itemType() == TorrentContentModelItem::FolderType)
|
||||
return getDirectoryIcon();
|
||||
else
|
||||
return getFileIcon();
|
||||
return m_fileIconProvider->icon(QFileInfo(item->name()));
|
||||
}
|
||||
|
||||
if ((index.column() == TorrentContentModelItem::COL_NAME) && (role == Qt::CheckStateRole)) {
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "base/bittorrent/torrentinfo.h"
|
||||
#include "torrentcontentmodelitem.h"
|
||||
|
||||
class QFileIconProvider;
|
||||
class TorrentContentModelFile;
|
||||
|
||||
class TorrentContentModel: public QAbstractItemModel
|
||||
@ -54,16 +55,16 @@ public:
|
||||
void updateFilesAvailability(const QVector<qreal> &fa);
|
||||
QVector<int> getFilePriorities() const;
|
||||
bool allFiltered() const;
|
||||
virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole);
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override;
|
||||
TorrentContentModelItem::ItemType itemType(const QModelIndex& index) const;
|
||||
int getFileIndex(const QModelIndex& index);
|
||||
virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
|
||||
virtual Qt::ItemFlags flags(const QModelIndex& index) const;
|
||||
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
||||
virtual QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const;
|
||||
virtual QModelIndex parent(const QModelIndex& index) const;
|
||||
virtual int rowCount(const QModelIndex& parent = QModelIndex()) const;
|
||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||
Qt::ItemFlags flags(const QModelIndex& index) const override;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||
QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override;
|
||||
QModelIndex parent(const QModelIndex& index) const override;
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
void clear();
|
||||
void setupModelData(const BitTorrent::TorrentInfo &info);
|
||||
|
||||
@ -77,6 +78,7 @@ public slots:
|
||||
private:
|
||||
TorrentContentModelFolder *m_rootItem;
|
||||
QVector<TorrentContentModelFile *> m_filesIndex;
|
||||
QFileIconProvider *m_fileIconProvider;
|
||||
};
|
||||
|
||||
#endif // TORRENTCONTENTMODEL_H
|
||||
|
@ -28,6 +28,9 @@ nogui {
|
||||
DEFINES += QBT_STATIC_QT
|
||||
QTPLUGIN += qico
|
||||
}
|
||||
win32 {
|
||||
QT += winextras
|
||||
}
|
||||
TARGET = qbittorrent
|
||||
}
|
||||
nowebui: DEFINES += DISABLE_WEBUI
|
||||
|
Loading…
Reference in New Issue
Block a user