Subversion Repositories Scribus

Rev

Rev 22982 | Rev 23054 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

/***************************************************************************
        copyright            : (C) 2015 by Craig Bradney
        email                : mrb@scribus.info
***************************************************************************/


/***************************************************************************
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
*                                                                         *
***************************************************************************/


#include <QCursor>
#include <QDebug>
#include <QFile>
#include <QIcon>
#include <QTextCodec>
#include <QTextStream>
#include <QDomDocument>

#include "iconmanager.h"
#include "prefsmanager.h"
#include "scpaths.h"

IconManager* IconManager::m_instance = nullptr;

IconManager::IconManager(QObject *parent)
 : QObject(parent)
{
}

IconManager::~IconManager()
{
}

IconManager* IconManager::instance()
{
        if (m_instance == nullptr)
                m_instance = new IconManager();

        return m_instance;
}

void IconManager::deleteInstance()
{
        delete m_instance;
        m_instance = nullptr;
}

bool IconManager::setup()
{
        if (!initIcons())
        {
                qDebug()<<"No icons found :(";
                return false;
        }
        return true;
}


bool IconManager::initIcons()
{
        readIconConfigFiles();
        return !(m_iconSets.isEmpty() || m_activeSetBasename.isEmpty());
}

void IconManager::readIconConfigFiles()
{
        QString baseIconDir(ScPaths::instance().iconDir());
        QStringList locations;
        locations<<baseIconDir;
        QStringList configNames;
        for (QStringList::Iterator it = locations.begin(); it != locations.end(); ++it)
        {
                QFileInfo iconDir(*it);
                if (!iconDir.exists())
                        continue;
                QDir id(*it, "*.xml", QDir::Name, QDir::Dirs | QDir::NoDotAndDotDot | QDir::Files | QDir::NoSymLinks);
                if (!id.exists() || (id.count() == 0))
                        continue;
                for (uint i = 0; i < id.count(); ++i)
                {
                        QFileInfo file(*it + id[i]);
                        //qDebug()<<file.absoluteFilePath();
                        QFile dataFile(file.absoluteFilePath());
                        if (!dataFile.exists())
                                continue;
                        if (!dataFile.open(QIODevice::ReadOnly))
                                continue;
                        QTextStream ts(&dataFile);
                        ts.setCodec(QTextCodec::codecForName("UTF-8"));
                        QString errorMsg;
                        int eline;
                        int ecol;
                        QDomDocument xmlData( QString(file.baseName()));
                        QString data(ts.readAll());
                        dataFile.close();
                        if (!xmlData.setContent( data, &errorMsg, &eline, &ecol))
                        {
                                qDebug()<<data<<errorMsg<<eline<<ecol;
                                if (data.contains("404 not found", Qt::CaseInsensitive))
                                        qDebug()<<"File not found on server";
                                else
                                        qDebug()<<"Could not open file"<<dataFile.fileName();
                                continue;
                        }
                        QDomElement docElem = xmlData.documentElement();
                        ScIconSetData isd;
                        for (QDomNode n = docElem.firstChild(); !n.isNull(); n = n.nextSibling())
                        {
                                QDomElement e = n.toElement();
                                if (e.isNull())
                                        continue;
                                //qDebug()<<e.tagName()<<e.text();
                                if (e.tagName() == "path")
                                {
                                        isd.path = e.text();
                                }
                                else if (e.tagName() == "author")
                                {
                                        isd.author = e.text();
                                }
                                else if (e.tagName() == "license")
                                {
                                        isd.license = e.text();
                                }
                                else if (e.tagName() == "activeversion")
                                {
                                        isd.activeversion = e.text();
                                }
                                else if (e.tagName() == "variant")
                                {
                                        isd.variant = e.text();
                                }
                                else if (e.tagName() == "nametext")
                                {
                                        if (e.hasAttribute("lang"))
                                        {
                                                isd.nameTranslations.insert(e.attribute("lang"),e.text());
                                                if (e.attribute("lang") == "en_US")
                                                        isd.baseName = e.text();
                                        }
                                }
                        }

                        //just in case there's no en_US basename
                        if (isd.baseName.isEmpty())
                                continue;

                        m_iconSets.insert(isd.baseName, isd);
                        if (isd.activeversion.isEmpty())
                                continue;

                        int av_major, av_minor, av_patch, curr_major, curr_minor, curr_patch, ver_major, ver_minor, ver_patch;
                        int av_fullver, curr_fullver, ver_fullver;
                        av_major = isd.activeversion.section(".", 0, 0).toInt();
                        av_minor = isd.activeversion.section(".", 1, 1).toInt();
                        av_patch = isd.activeversion.section(".", 2, 2).toInt();
                        av_fullver = av_major * 10000 + av_minor * 100 + av_patch;
                        curr_major = m_activeSetVersion.section(".", 0, 0).toInt();
                        curr_minor = m_activeSetVersion.section(".", 1, 1).toInt();
                        curr_patch = m_activeSetVersion.section(".", 2, 2).toInt();
                        curr_fullver = curr_major * 10000 + curr_minor * 100 + curr_patch;
                        ver_major = QString(VERSION).section(".", 0, 0).toInt();
                        ver_minor = QString(VERSION).section(".", 1, 1).toInt();
                        ver_patch = QString(VERSION).section(".", 2, 2).toInt();
                        ver_fullver = ver_major * 10000 + ver_minor * 100 + ver_patch;
                        //If iconset version <= app version, and iconset version >= current active iconset version
                        if ((av_fullver <= ver_fullver) && (av_fullver >= curr_fullver))
                        {
                                // Do not use variant of an iconset such as "dark" ones by default
                                if ((av_fullver == curr_fullver) && !isd.variant.isEmpty())
                                        continue;
                                m_backupSetBasename = m_activeSetBasename;
                                m_backupSetVersion = m_backupSetVersion;
                                m_activeSetBasename = isd.baseName;
                                m_activeSetVersion = isd.activeversion;
                                //qDebug()<<"backupSetBasename"<<m_backupSetBasename<<"activeSetBasename"<<m_activeSetBasename;
                        }
                }
        }
}

QCursor IconManager::loadCursor(const QString& nam, int hotX, int hotY, bool forceUseColor)
{
        return QCursor(loadPixmap(nam, forceUseColor), hotX, hotY);
}

QIcon IconManager::loadIcon(const QString& nam, bool forceUseColor)
{
        return QIcon(loadPixmap(nam, forceUseColor));
}

QPixmap IconManager::loadPixmap(const QString& nam, bool forceUseColor, bool rtlFlip)
{
        if (m_pxCache.contains(nam))
                return *m_pxCache[nam];

        QString iconFilePath(pathForIcon(nam));
        QPixmap *pm = new QPixmap();
        pm->load(iconFilePath);
        if (pm->isNull())
                qWarning("Unable to load icon %s: Got null pixmap", iconFilePath.toLatin1().constData());
//      else
//              qDebug()<<"Successful icon load from"<<iconFilePath;
        if (PrefsManager::instance()->appPrefs.uiPrefs.grayscaleIcons && !forceUseColor)
                iconToGrayscale(pm);
        if (rtlFlip)
        {
                QTransform t;
                t.rotate(180);
                *pm = pm->transformed(t);
        }
        m_pxCache.insert(nam, pm);
        return *pm;
}

void IconManager::iconToGrayscale(QPixmap* pm)
{
        QImage qi(pm->toImage());
        int h = qi.height();
        int w = qi.width();
        QRgb c_rgb;
        for (int i = 0; i < w; ++i)
        {
                for (int j = 0; j < h; ++j)
                {
                        c_rgb = qi.pixel(i, j);
                        int k = qMin(qRound(0.3 * qRed(c_rgb) + 0.59 * qGreen(c_rgb) + 0.11 * qBlue(c_rgb)), 255);
                        qi.setPixel(i, j, qRgba(k, k, k, qAlpha(c_rgb)));
                }
        }
        *pm = QPixmap::fromImage(qi);
}

bool IconManager::setActiveFromPrefs(const QString& prefsSet)
{
        //qDebug()<<"setting active from prefs to"<<prefsSet;
        if (!m_iconSets.contains(prefsSet))
                return false;
        m_activeSetBasename = m_iconSets[prefsSet].baseName;
        m_activeSetVersion = m_iconSets[prefsSet].activeversion;
        return true;
}

QString IconManager::baseNameForTranslation(const QString& transName) const
{
        QString name;
        for (const ScIconSetData& value : m_iconSets)
        {
                QMapIterator<QString, QString> nameValue(value.nameTranslations);
                while (nameValue.hasNext())
                {
                        nameValue.next();
                        if (nameValue.value()==transName)
                                return value.nameTranslations["en_US"];
                }
        }
        return name;
}

QString IconManager::pathForIcon(const QString& nam)
{
        //QString iconset(PrefsManager::instance()->appPrefs.uiPrefs.iconSet);
        QString iconSubdir(m_iconSets[m_activeSetBasename].path+"/");
        QString primaryIconSubdir(m_iconSets[m_backupSetBasename].path+"/");

        QString iconFilePath(QString("%1%2%3").arg(ScPaths::instance().iconDir(), iconSubdir, nam));
        if (QFile::exists(iconFilePath))
                return iconFilePath;

        qWarning("pathForIcon: Unable to load icon %s: File not found", iconFilePath.toLatin1().constData());
        iconFilePath=QString("%1%2%3").arg(ScPaths::instance().iconDir(), primaryIconSubdir, nam);

        if (QFile::exists(iconFilePath))
        {
                //qDebug()<<iconFilePath;
                return iconFilePath;
        }
#ifdef WANT_DEBUG
        qWarning("pathForIcon: Unable to load icon %s: File not found", iconFilePath.toLatin1().constData());
#endif
        return "";
}

QStringList IconManager::pathList() const
{
        QStringList paths;
        for (const ScIconSetData& value :  m_iconSets)
                paths << value.path;
        return paths;
}

QStringList IconManager::nameList(const QString& language) const
{
        QStringList names;
        for (const ScIconSetData& value : m_iconSets)
        {
                if (value.nameTranslations.contains(language))
                        names << value.nameTranslations.value(language);
                else if (value.nameTranslations.contains("en_US"))
                        names << value.nameTranslations.value("en_US");
                else if (value.nameTranslations.contains("en"))
                        names << value.nameTranslations.value("en");
                else
                        names << value.path;
        }
        return names;
}

void IconManager::languageChange()
{

}