File indexing completed on 2024-05-12 15:59:51
0001 /* 0002 * SPDX-License-Identifier: GPL-3.0-or-later 0003 */ 0004 0005 #include "KisResourceQueryMapper.h" 0006 0007 #include "kis_assert.h" 0008 #include <QString> 0009 #include <QVariant> 0010 #include <QImage> 0011 #include <QByteArray> 0012 #include <QBuffer> 0013 #include <QDebug> 0014 #include <QSqlError> 0015 0016 #include "KisResourceModel.h" 0017 #include "KisResourceLocator.h" 0018 #include "KisResourceModelProvider.h" 0019 #include "KisTag.h" 0020 0021 0022 0023 QImage KisResourceQueryMapper::getThumbnailFromQuery(const QSqlQuery &query, bool useResourcePrefix) 0024 { 0025 QString storageLocation = query.value("location").toString(); 0026 QString resourceType = query.value("resource_type").toString(); 0027 QString filename = query.value(useResourcePrefix ? "resource_filename" : "filename").toString(); 0028 0029 QImage img = KisResourceLocator::instance()->thumbnailCached(storageLocation, resourceType, filename); 0030 if (!img.isNull()) { 0031 return img; 0032 } else { 0033 const int resourceId = query.value(useResourcePrefix ? "resource_id" : "id").toInt(); 0034 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(resourceId >= 0, img); 0035 0036 bool result = false; 0037 QSqlQuery thumbQuery; 0038 result = thumbQuery.prepare("SELECT thumbnail FROM resources WHERE resources.id = :resource_id"); 0039 if (!result) { 0040 qWarning() << "Failed to prepare query for thumbnail of" << resourceId << thumbQuery.lastError(); 0041 return img; 0042 } 0043 0044 thumbQuery.bindValue(":resource_id", resourceId); 0045 0046 result = thumbQuery.exec(); 0047 0048 if (!result) { 0049 qWarning() << "Failed to execute query for thumbnail of" << resourceId << thumbQuery.lastError(); 0050 return img; 0051 } 0052 0053 if (!thumbQuery.next()) { 0054 qWarning() << "Failed to find thumbnail of" << resourceId; 0055 return img; 0056 } 0057 0058 QByteArray ba = thumbQuery.value("thumbnail").toByteArray(); 0059 QBuffer buf(&ba); 0060 buf.open(QBuffer::ReadOnly); 0061 img.load(&buf, "PNG"); 0062 KisResourceLocator::instance()->cacheThumbnail(storageLocation, resourceType, filename, img); 0063 return img; 0064 } 0065 } 0066 0067 QVariant KisResourceQueryMapper::variantFromResourceQuery(const QSqlQuery &query, int column, int role, bool useResourcePrefix) 0068 { 0069 const QString resourceType = query.value("resource_type").toString(); 0070 0071 switch(role) { 0072 case Qt::DisplayRole: 0073 { 0074 switch(column) { 0075 case KisAbstractResourceModel::Id: 0076 return query.value(useResourcePrefix ? "resource_id" : "id"); 0077 case KisAbstractResourceModel::StorageId: 0078 return query.value("storage_id"); 0079 case KisAbstractResourceModel::Name: 0080 return query.value(useResourcePrefix ? "resource_name" : "name"); 0081 case KisAbstractResourceModel::Filename: 0082 return query.value(useResourcePrefix ? "resource_filename" : "filename"); 0083 case KisAbstractResourceModel::Tooltip: 0084 return query.value(useResourcePrefix ? "resource_tooltip" : "tooltip"); 0085 case KisAbstractResourceModel::Thumbnail: 0086 { 0087 return QVariant::fromValue<QImage>(getThumbnailFromQuery(query, useResourcePrefix)); 0088 } 0089 case KisAbstractResourceModel::Status: 0090 return query.value(useResourcePrefix ? "resource_status" : "status"); 0091 case KisAbstractResourceModel::Location: 0092 return query.value("location"); 0093 case KisAbstractResourceModel::ResourceType: 0094 return query.value("resource_type"); 0095 case KisAbstractResourceModel::Dirty: 0096 { 0097 QString storageLocation = query.value("location").toString(); 0098 QString filename = query.value(useResourcePrefix ? "resource_filename" : "filename").toString(); 0099 0100 // An uncached resource has not been loaded, so it cannot be dirty 0101 if (!KisResourceLocator::instance()->resourceCached(storageLocation, resourceType, filename)) { 0102 return false; 0103 } 0104 else { 0105 // Now we have to check the resource, but that's cheap since it's been loaded in any case 0106 KoResourceSP resource = KisResourceLocator::instance()->resourceForId(query.value(useResourcePrefix ? "resource_id" : "id").toInt()); 0107 return resource->isDirty(); 0108 } 0109 } 0110 case KisAbstractResourceModel::ResourceActive: 0111 return query.value("resource_active"); 0112 case KisAbstractResourceModel::StorageActive: 0113 return query.value(useResourcePrefix ? "resource_storage_active" : "storage_active"); 0114 default: 0115 ; 0116 }; 0117 Q_FALLTHROUGH(); 0118 } 0119 case Qt::DecorationRole: 0120 { 0121 if (column == KisAbstractResourceModel::Thumbnail) { 0122 return QVariant::fromValue<QImage>(getThumbnailFromQuery(query, useResourcePrefix)); 0123 } 0124 return QVariant(); 0125 } 0126 case Qt::StatusTipRole: 0127 return QVariant(); 0128 case Qt::ToolTipRole: 0129 Q_FALLTHROUGH(); 0130 case Qt::WhatsThisRole: 0131 return query.value("tooltip"); 0132 case Qt::UserRole + KisAbstractResourceModel::Id: 0133 return query.value(useResourcePrefix ? "resource_id" : "id"); 0134 case Qt::UserRole + KisAbstractResourceModel::StorageId: 0135 return query.value("storage_id"); 0136 case Qt::UserRole + KisAbstractResourceModel::Name: 0137 return query.value(useResourcePrefix ? "resource_name" : "name"); 0138 case Qt::UserRole + KisAbstractResourceModel::Filename: 0139 return query.value(useResourcePrefix ? "resource_filename" : "filename"); 0140 case Qt::UserRole + KisAbstractResourceModel::Tooltip: 0141 return query.value(useResourcePrefix ? "resource_tooltip" : "tooltip"); 0142 case Qt::UserRole + KisAbstractResourceModel::MD5: 0143 return query.value(useResourcePrefix ? "resource_md5sum" : "md5sum"); 0144 case Qt::UserRole + KisAbstractResourceModel::Thumbnail: 0145 { 0146 return QVariant::fromValue<QImage>(getThumbnailFromQuery(query, useResourcePrefix)); 0147 } 0148 case Qt::UserRole + KisAbstractResourceModel::Status: 0149 return query.value(useResourcePrefix ? "resource_status" : "status"); 0150 case Qt::UserRole + KisAbstractResourceModel::Location: 0151 return query.value("location"); 0152 case Qt::UserRole + KisAbstractResourceModel::ResourceType: 0153 return query.value("resource_type"); 0154 case Qt::UserRole + KisAbstractResourceModel::Tags: 0155 { 0156 KisAllResourcesModel *resourceModel = KisResourceModelProvider::resourceModel(resourceType); 0157 QStringList tagNames; 0158 Q_FOREACH(const KisTagSP tag, resourceModel->tagsForResource(query.value(useResourcePrefix ? "resource_id" : "id").toInt())) { 0159 tagNames << tag->name(); 0160 } 0161 return tagNames; 0162 } 0163 case Qt::UserRole + KisAbstractResourceModel::Dirty: 0164 { 0165 QString storageLocation = query.value("location").toString(); 0166 QString filename = query.value(useResourcePrefix ? "resource_filename" : "filename").toString(); 0167 0168 // An uncached resource has not been loaded, so it cannot be dirty 0169 if (!KisResourceLocator::instance()->resourceCached(storageLocation, resourceType, filename)) { 0170 return false; 0171 } 0172 else { 0173 // Now we have to check the resource, but that's cheap since it's been loaded in any case 0174 KoResourceSP resource = KisResourceLocator::instance()->resourceForId(query.value(useResourcePrefix ? "resource_id" : "id").toInt()); 0175 return resource->isDirty(); 0176 } 0177 } 0178 case Qt::UserRole + KisAbstractResourceModel::MetaData: 0179 { 0180 QMap<QString, QVariant> r = KisResourceLocator::instance()->metaDataForResource(query.value(useResourcePrefix ? "resource_id" : "id").toInt()); 0181 return r; 0182 } 0183 case Qt::UserRole + KisAbstractResourceModel::ResourceActive: 0184 { 0185 return query.value("resource_active"); 0186 } 0187 case Qt::UserRole + KisAbstractResourceModel::StorageActive: 0188 { 0189 return query.value(useResourcePrefix ? "resource_storage_active" : "storage_active"); 0190 } 0191 default: 0192 ; 0193 } 0194 0195 return QVariant(); 0196 } 0197