Browse Source

Merge pull request #6156 from evsh/file-icons

Use system file type specific icons in contents tab
adaptive-webui-19844
sledgehammer999 7 years ago committed by GitHub
parent
commit
8e6df572a8
  1. 3
      src/CMakeLists.txt
  2. 3
      src/gui/CMakeLists.txt
  3. 95
      src/gui/torrentcontentmodel.cpp
  4. 18
      src/gui/torrentcontentmodel.h
  5. 3
      src/src.pro

3
src/CMakeLists.txt

@ -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)

3
src/gui/CMakeLists.txt

@ -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)

95
src/gui/torrentcontentmodel.cpp

@ -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
{ {
static QIcon cached = GuiIconProvider::instance()->getIcon("text-plain"); public:
return cached; 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) 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)) {

18
src/gui/torrentcontentmodel.h

@ -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

3
src/src.pro

@ -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…
Cancel
Save