#include "eiconengin.h"
#include <QPainter>
#include <QDebug>
#include <QDir>
#include <QDirIterator>
#include <QSettings>
#include <QtGui/QIconEnginePlugin>
#include <QtGui/QPixmapCache>
#include <QtGui/QIconEngine>
#include <QtGui/QStyleOption>
#include <QtCore/QList>
#include <QtCore/QHash>
#include <QtCore/QDir>
#include <QtCore/QSettings>
#include <QtGui/QPainter>
#include <QtGui/QApplication>
#include <QtCore/QLatin1Literal>
QT_BEGIN_NAMESPACE
QString themBackPath(const QString &path)
{
foreach (QString p, QIcon::themeSearchPaths())
{
QDir dirS(p);
if(dirS.exists(p+"/"+path))
{
// qDebug()<<"reurned"<<p+"/"+path;
return p+"/"+path;
}
}
return path;
}
QStringList parents(const QString &path)
{
QFile themeIndex(themBackPath(path) + QLatin1String("/index.theme"));
QStringList m_parents;
#ifndef QT_NO_SETTINGS
if (themeIndex.exists()) {
const QSettings indexReader(themeIndex.fileName(), QSettings::IniFormat);
// Parent themes provide fallbacks for missing icons
m_parents = indexReader.value(
QLatin1String("Icon Theme/Inherits")).toStringList();
}
#endif //QT_NO_SETTINGS
// Ensure that all themes fall back to hicolor
if (!m_parents.contains(QLatin1String("hicolor")))
m_parents.append(QLatin1String("hicolor"));
// if (!m_parents.contains(QLatin1String("/usr/share/pixmaps")))
// m_parents.append(QLatin1String("/usr/share/pixmaps"));
return m_parents;
}
EIconEngin::EIconEngin(const QString &iconName,const QString& themName):
m_iconName(iconName),isfallback(true)
{
if(QIcon::hasThemeIcon(iconName)){
m_icon=QIcon::fromTheme(m_iconName);
// m_availableSizes=m_icon.availableSizes();
m_themName=QIcon::themeName();
qDebug()<<"EIconEngin(qicon) themName:"<<m_themName;
}else{
if(!themName.isEmpty()){
m_themName=themName;
// qDebug()<<"EIconEngin(themName) themName:"<<m_themName;
m_availableSizes.clear();
iconFromTheme((m_themName));
}
}
}
void EIconEngin::paint(QPainter *painter, const QRect &rect,
QIcon::Mode mode, QIcon::State state)
{
QSize size=m_icon.actualSize(rect.size());
painter->drawPixmap(rect, pixmap(size,mode,state));
}
QPixmap EIconEngin::pixmap(const QSize &size, QIcon::Mode mode,
QIcon::State state)
{
ensureLoaded();
QPixmap pix= m_icon.pixmap(size,mode,state);
//qDebug()<<size<<m_icon.availableSizes()<<m_availableSizes;
//TODO: fix this icon
if(pix.isNull())
pix=QIcon::fromTheme("unknown",QIcon::fromTheme("folder")).pixmap(size,mode,state);
if(size!=pix.size())
pix=pix.scaled(size);
return pix;
}
void EIconEngin::ensureLoaded()
{
/*****************************************************
*اذا كانت السمة موجودة سيتم استخدام السمة
**اما اذا لم تكن هناك سمة سيتم لستخدام الاحتياطية
*اذا تغيرت السمة سينظر اذا وجدت سيتم انشاء احتياطية
*واستخدام الحالية وهكذا
****************************************************/
if(!QIcon::hasThemeIcon(m_iconName))
{
if(!isfallback)
{
qDebug()<<"!isfallback"<<m_themName;
m_availableSizes.clear();
m_icon=QIcon();
iconFromTheme((m_themName));
if(m_availableSizes.isEmpty()){
foreach (QString s, parents(m_themName)) {
iconFromTheme(s);
if(!m_availableSizes.isEmpty())
break;
}
}
qDebug()<<"!isfallback"<< m_icon.availableSizes();;
isfallback=true;
}
}else
{
if(isfallback)
{
qDebug()<<"hasThemeIcon"<<m_themName;
if(QIcon::hasThemeIcon(m_iconName))
{
qDebug()<<"hasThemeIcon"<<m_themName;
m_icon=QIcon::fromTheme(m_iconName);
m_availableSizes=m_icon.availableSizes();
m_themName=QIcon::themeName();
isfallback=false;
}
}
}
}
void EIconEngin::iconFromTheme(const QString &theme)
{
QString mpath= themBackPath(theme);
addIconFile(mpath);
QDirIterator it( mpath,QDir::AllDirs |
QDir::NoDotAndDotDot , QDirIterator::Subdirectories);
while(it.hasNext())
{
it.next();
QString curPath=it.filePath();
addIconFile(curPath);
}
}
void EIconEngin::addIconFile(const QString &curPath)
{
QStringList listStr;
listStr<<m_iconName+".png" <<m_iconName+".xpm"
<<m_iconName+".svg"<<m_iconName+".svgz";
QStringList files = QDir(curPath).entryList(QStringList(listStr),
QDir::Files | QDir::NoDotAndDotDot);
foreach (QString s, files) {
QString f= QDir(curPath).absoluteFilePath(s);
QSize size=QPixmap(f).size();
if(!size.isNull()){
qDebug()<<f<<QPixmap(f).size();
m_icon.addFile(f,size);
// m_icon.addPixmap(QPixmap(f));
m_availableSizes.append(size);
}
}
}
//-------------------------------------------------------------------
//--------------------------------------------------
/*
void EIconEngin::virtual_hook(int id, void *data)
{
ensureLoaded();
qDebug()<<"hook"<<m_availableSizes;
switch (id) {
case QIconEngineV2::AvailableSizesHook:
{
QIconEngineV2::AvailableSizesArgument &arg
= *reinterpret_cast<QIconEngineV2::AvailableSizesArgument*>(data);
// const QList<QIconDirInfo> directoryKey = iconLoaderInstance()->theme().keyList();
arg.sizes.clear();
// Gets all sizes from the DirectoryInfo entries
arg.sizes=m_availableSizes;//m_icon.availableSizes();
}
break;
#if QT_VERSION >= 0x040700
case QIconEngineV2::IconNameHook:
{
QString &name = *reinterpret_cast<QString*>(data);
name = m_iconName;
}
break;
#else
#warning QIconEngineV2::IconNameHook is ignored due Qt version. Upgrade to 4.7.x
#endif
default:
QIconEngineV2::virtual_hook(id, data);
}
}
*/
void EIconEngin::virtual_hook(int id, void *data)
{
ensureLoaded();
qDebug()<<"virtual_hook"<<m_iconName<<m_availableSizes;
switch (id) {
case QIconEngineV2::AvailableSizesHook:
{
QIconEngineV2::AvailableSizesArgument &arg
= *reinterpret_cast<QIconEngineV2::AvailableSizesArgument*>(data);
//const QList<QIconDirInfo> directoryKey = iconLoaderInstance()->theme().keyList();
arg.sizes.clear();
// Gets all sizes from the DirectoryInfo entries
arg.sizes=m_icon.availableSizes();
}
break;
#if QT_VERSION >= 0x040700
case QIconEngineV2::IconNameHook:
{
QString &name = *reinterpret_cast<QString*>(data);
name = m_iconName;
}
break;
#else
#warning QIconEngineV2::IconNameHook is ignored due Qt version. Upgrade to 4.7.x
#endif
default:
QIconEngineV2::virtual_hook(id, data);
}
}