File indexing completed on 2024-05-12 05:09:51

0001 /***************************************************************************
0002     Copyright (C) 2017 Robby Stephenson <robby@periapsis.org>
0003  ***************************************************************************/
0004 
0005 /***************************************************************************
0006  *                                                                         *
0007  *   This program is free software; you can redistribute it and/or         *
0008  *   modify it under the terms of the GNU General Public License as        *
0009  *   published by the Free Software Foundation; either version 2 of        *
0010  *   the License or (at your option) version 3 or any later version        *
0011  *   accepted by the membership of KDE e.V. (or its successor approved     *
0012  *   by the membership of KDE e.V.), which shall act as a proxy            *
0013  *   defined in Section 14 of version 3 of the license.                    *
0014  *                                                                         *
0015  *   This program is distributed in the hope that it will be useful,       *
0016  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0017  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0018  *   GNU General Public License for more details.                          *
0019  *                                                                         *
0020  *   You should have received a copy of the GNU General Public License     *
0021  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
0022  *                                                                         *
0023  ***************************************************************************/
0024 
0025 #include "entryiconmodel.h"
0026 #include "models.h"
0027 #include "../collectionfactory.h"
0028 #include "../config/tellico_config.h"
0029 #include "../tellico_debug.h"
0030 
0031 #include <QIcon>
0032 #include <QPixmap>
0033 
0034 using namespace Tellico;
0035 using Tellico::EntryIconModel;
0036 
0037 EntryIconModel::EntryIconModel(QObject* parent_) : QIdentityProxyModel(parent_) {
0038   m_iconCache.setMaxCost(Config::iconCacheSize());
0039 }
0040 
0041 EntryIconModel::~EntryIconModel() {
0042   qDeleteAll(m_defaultIcons);
0043 }
0044 
0045 void EntryIconModel::setSourceModel(QAbstractItemModel* newSourceModel_) {
0046   QIdentityProxyModel::setSourceModel(newSourceModel_);
0047   if(newSourceModel_) {
0048     connect(newSourceModel_, &QAbstractItemModel::modelReset, this, &EntryIconModel::clearCache);
0049   }
0050 }
0051 
0052 QVariant EntryIconModel::data(const QModelIndex& index_, int role_) const {
0053   switch(role_) {
0054     // this IdentityModel serves to return the entry's primary image as the DecorationRole
0055     // no matter what the index column may be
0056     case Qt::DecorationRole:
0057     {
0058       Data::EntryPtr entry = index_.data(EntryPtrRole).value<Data::EntryPtr>();
0059       if(!entry) {
0060         return QVariant();
0061       }
0062 
0063       // return entry primary image in this case
0064       Data::FieldPtr field = entry->collection()->primaryImageField();
0065       if(!field) {
0066         return defaultIcon(entry->collection());
0067       }
0068       const QString id = entry->field(field);
0069       if(m_iconCache.contains(id)) {
0070         return QIcon(*m_iconCache.object(id));
0071       }
0072 
0073       QVariant v = QIdentityProxyModel::data(index_, PrimaryImageRole);
0074       if(v.isNull() || !v.canConvert<QPixmap>()) {
0075         return defaultIcon(entry->collection());
0076       }
0077 
0078       const QPixmap p = v.value<QPixmap>();
0079       QIcon* icon = new QIcon(p);
0080       if(!m_iconCache.insert(id, icon)) {
0081         // failing to insert invalidates the icon pointer
0082         myDebug() << "failed to insert into icon cache";
0083         return QIcon(p);
0084       }
0085       return QIcon(*icon);
0086     }
0087   }
0088 
0089   return QIdentityProxyModel::data(index_, role_);
0090 }
0091 
0092 void EntryIconModel::clearCache() {
0093   m_iconCache.clear();
0094 }
0095 
0096 const QIcon& EntryIconModel::defaultIcon(Data::CollPtr coll_) const {
0097   QIcon* icon = m_defaultIcons.value(coll_->type());
0098   if(icon) {
0099     return *icon;
0100   }
0101   QIcon tmpIcon = QIcon(QLatin1String(":/icons/nocover_") + CollectionFactory::typeName(coll_->type()));
0102   // apparently, for a resource icon that doesn't exist, it may not be null, but just have no available sizes
0103   if(tmpIcon.isNull() || tmpIcon.availableSizes().isEmpty()) {
0104 //    myLog() << "null nocover image, loading tellico.png";
0105     tmpIcon = QIcon::fromTheme(QStringLiteral("tellico"), QIcon(QLatin1String(":/icons/tellico")));
0106   }
0107 
0108   icon = new QIcon(tmpIcon);
0109   m_defaultIcons.insert(coll_->type(), icon);
0110   return *icon;
0111 }