* Switched to experimental * Bumped Standards to 4.1.1 * Fixed Symbols * Added build dependency libexif-dev * Added dependencies libexif-dev and libmenu-cache-dev to libfm-qt-dev * Added override for dh_missing * Bumped years in copyright
139 lines
4.1 KiB
C++
139 lines
4.1 KiB
C++
#include "iconinfo.h"
|
|
#include "iconinfo_p.h"
|
|
|
|
namespace Fm {
|
|
|
|
std::unordered_map<GIcon*, std::shared_ptr<IconInfo>, IconInfo::GIconHash, IconInfo::GIconEqual> IconInfo::cache_;
|
|
std::mutex IconInfo::mutex_;
|
|
QIcon IconInfo::fallbackQicon_;
|
|
|
|
static const char* fallbackIconNames[] = {
|
|
"unknown",
|
|
"application-octet-stream",
|
|
"application-x-generic",
|
|
"text-x-generic",
|
|
nullptr
|
|
};
|
|
|
|
IconInfo::IconInfo(const char* name):
|
|
gicon_{g_themed_icon_new(name), false} {
|
|
}
|
|
|
|
IconInfo::IconInfo(const GIconPtr gicon):
|
|
gicon_{std::move(gicon)} {
|
|
}
|
|
|
|
IconInfo::~IconInfo() {
|
|
}
|
|
|
|
// static
|
|
std::shared_ptr<const IconInfo> IconInfo::fromName(const char* name) {
|
|
GObjectPtr<GIcon> gicon{g_themed_icon_new(name), false};
|
|
return fromGIcon(gicon);
|
|
}
|
|
|
|
// static
|
|
std::shared_ptr<const IconInfo> IconInfo::fromGIcon(GIconPtr gicon) {
|
|
if(Q_LIKELY(gicon)) {
|
|
std::lock_guard<std::mutex> lock{mutex_};
|
|
auto it = cache_.find(gicon.get());
|
|
if(it != cache_.end()) {
|
|
return it->second;
|
|
}
|
|
// not found in the cache, create a new entry for it.
|
|
auto icon = std::make_shared<IconInfo>(std::move(gicon));
|
|
cache_.insert(std::make_pair(icon->gicon_.get(), icon));
|
|
return icon;
|
|
}
|
|
return std::shared_ptr<const IconInfo>{};
|
|
}
|
|
|
|
void IconInfo::updateQIcons() {
|
|
std::lock_guard<std::mutex> lock{mutex_};
|
|
fallbackQicon_ = QIcon();
|
|
for(auto& elem: cache_) {
|
|
auto& info = elem.second;
|
|
info->internalQicon_ = QIcon();
|
|
}
|
|
}
|
|
|
|
QIcon IconInfo::qicon(const bool& transparent) const {
|
|
if(Q_LIKELY(!transparent)) {
|
|
if(Q_UNLIKELY(qicon_.isNull() && gicon_)) {
|
|
if(!G_IS_FILE_ICON(gicon_.get())) {
|
|
qicon_ = QIcon(new IconEngine{shared_from_this()});
|
|
}
|
|
else {
|
|
qicon_ = internalQicon_;
|
|
}
|
|
}
|
|
}
|
|
else { // transparent == true
|
|
if(Q_UNLIKELY(qiconTransparent_.isNull() && gicon_)) {
|
|
if(!G_IS_FILE_ICON(gicon_.get())) {
|
|
qiconTransparent_ = QIcon(new IconEngine{shared_from_this(), transparent});
|
|
}
|
|
else {
|
|
qiconTransparent_ = internalQicon_;
|
|
}
|
|
}
|
|
}
|
|
return !transparent ? qicon_ : qiconTransparent_;
|
|
}
|
|
|
|
QIcon IconInfo::qiconFromNames(const char* const* names) {
|
|
const gchar* const* name;
|
|
// qDebug("names: %p", names);
|
|
for(name = names; *name; ++name) {
|
|
// qDebug("icon name=%s", *name);
|
|
QIcon qicon = QIcon::fromTheme(*name);
|
|
if(!qicon.isNull()) {
|
|
return qicon;
|
|
}
|
|
}
|
|
return QIcon();
|
|
}
|
|
|
|
std::forward_list<std::shared_ptr<const IconInfo>> IconInfo::emblems() const {
|
|
std::forward_list<std::shared_ptr<const IconInfo>> result;
|
|
if(hasEmblems()) {
|
|
const GList* emblems_glist = g_emblemed_icon_get_emblems(G_EMBLEMED_ICON(gicon_.get()));
|
|
for(auto l = emblems_glist; l; l = l->next) {
|
|
auto gemblem = G_EMBLEM(l->data);
|
|
GIconPtr gemblem_icon{g_emblem_get_icon(gemblem), true};
|
|
result.emplace_front(fromGIcon(gemblem_icon));
|
|
}
|
|
result.reverse();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
QIcon IconInfo::internalQicon() const {
|
|
if(Q_UNLIKELY(internalQicon_.isNull())) {
|
|
GIcon* gicon = gicon_.get();
|
|
if(G_IS_EMBLEMED_ICON(gicon_.get())) {
|
|
gicon = g_emblemed_icon_get_icon(G_EMBLEMED_ICON(gicon));
|
|
}
|
|
if(G_IS_THEMED_ICON(gicon)) {
|
|
const gchar* const* names = g_themed_icon_get_names(G_THEMED_ICON(gicon));
|
|
internalQicon_ = qiconFromNames(names);
|
|
}
|
|
else if(G_IS_FILE_ICON(gicon)) {
|
|
GFile* file = g_file_icon_get_file(G_FILE_ICON(gicon));
|
|
CStrPtr fpath{g_file_get_path(file)};
|
|
internalQicon_ = QIcon(fpath.get());
|
|
}
|
|
|
|
// fallback to default icon
|
|
if(Q_UNLIKELY(internalQicon_.isNull())) {
|
|
if(Q_UNLIKELY(fallbackQicon_.isNull())) {
|
|
fallbackQicon_ = qiconFromNames(fallbackIconNames);
|
|
}
|
|
internalQicon_ = fallbackQicon_;
|
|
}
|
|
}
|
|
return internalQicon_;
|
|
}
|
|
|
|
} // namespace Fm
|