File indexing completed on 2024-12-22 04:15:12

0001 /*
0002  *  SPDX-FileCopyrightText: 2023 Srirupa Datta <srirupa.sps@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "ui_wdgresourcepreview.h"
0008 #include "wdg_resource_preview.h"
0009 
0010 #include <QAction>
0011 #include <QDebug>
0012 #include <QItemSelection>
0013 #include <QMenu>
0014 #include <QMenuBar>
0015 #include <QPainter>
0016 #include <QLabel>
0017 #include <QCompleter>
0018 #include <QToolButton>
0019 #include <QLineEdit>
0020 
0021 #include <kis_action.h>
0022 #include <kis_action_manager.h>
0023 #include <kis_icon.h>
0024 #include <KisResourceTypeModel.h>
0025 #include <KisStorageModel.h>
0026 #include <KisTagModel.h>
0027 #include <KisResourceItemListView.h>
0028 #include <KisResourceLocator.h>
0029 #include <KisResourceModel.h>
0030 #include <KisTagFilterResourceProxyModel.h>
0031 #include <kis_assert.h>
0032 #include <KisResourceItemDelegate.h>
0033 #include <wdgtagselection.h>
0034 #include <kis_paintop_factory.h>
0035 #include <kis_paintop_registry.h>
0036 #include <dlg_create_bundle.h>
0037 #include <ResourceImporter.h>
0038 #include <KoIcon.h>
0039 #include "ResourceListViewModes.h"
0040 #include <kis_config.h>
0041 #include "KisResourceItemViewer.h"
0042 
0043 
0044 WdgResourcePreview::WdgResourcePreview(WidgetType type, QWidget *parent) :
0045     QWidget(parent),
0046     m_ui(new Ui::WdgResourcePreview),
0047     m_type(type)
0048 
0049 {
0050     m_ui->setupUi(this);
0051 
0052     m_ui->resourceItemView->setFixedToolTipThumbnailSize(QSize(128, 128));
0053 
0054     if (m_type == WidgetType::ResourceManager) {
0055         m_resourceTypeModel = new KisResourceTypeModel(this);
0056         m_ui->cmbResourceType->setModel(m_resourceTypeModel);
0057         m_ui->cmbResourceType->setModelColumn(KisResourceTypeModel::Name);
0058         for (int i = 0; i < m_resourceTypeModel->rowCount(); i++) {
0059             QModelIndex idx = m_resourceTypeModel->index(i, 0);
0060             QString resourceType = m_resourceTypeModel->data(idx, Qt::UserRole + KisResourceTypeModel::ResourceType).toString();
0061             if (resourceType == "paintoppresets") {
0062                 m_ui->cmbResourceType->setCurrentIndex(i);
0063                 break;
0064             }
0065         }
0066     } else {
0067         QStringList resourceTypes = QStringList() << ResourceType::Brushes << ResourceType::PaintOpPresets << ResourceType::Gradients << ResourceType::GamutMasks;
0068         #if defined HAVE_SEEXPR
0069         resourceTypes << ResourceType::SeExprScripts;
0070         #endif
0071         resourceTypes << ResourceType::Patterns << ResourceType::Palettes << ResourceType::Workspaces;
0072 
0073         for (int i = 0; i < resourceTypes.size(); i++) {
0074             m_ui->cmbResourceType->addItem(ResourceName::resourceTypeToName(resourceTypes[i]), resourceTypes[i]);
0075         }
0076     }
0077 
0078     connect(m_ui->cmbResourceType, SIGNAL(activated(int)), SLOT(slotResourceTypeSelected(int)));
0079     connect(m_ui->cmbResourceType, SIGNAL(activated(int)), SIGNAL(resourceTypeSelected(int)));
0080 
0081     QString selectedResourceType = getCurrentResourceType();
0082 
0083 
0084     KisTagModel* tagModel = new KisTagModel(selectedResourceType);
0085     tagModel->sort(KisAllTagsModel::Name);
0086     m_tagModelsForResourceType.insert(selectedResourceType, tagModel);
0087 
0088     m_ui->cmbTag->setModel(tagModel);
0089     m_ui->cmbTag->setModelColumn(KisAllTagsModel::Name);
0090 
0091     connect(m_ui->cmbTag, SIGNAL(activated(int)), SLOT(slotTagSelected(int)));
0092 
0093     if (m_type == WidgetType::BundleCreator) {
0094         m_ui->cmbStorage->setVisible(false);
0095     } else {
0096         m_storageModel = new KisStorageModel(this);
0097 
0098         m_ui->cmbStorage->setModel(m_storageModel);
0099         m_ui->cmbStorage->setModelColumn(KisStorageModel::DisplayName);
0100         connect(m_ui->cmbStorage, SIGNAL(activated(int)), SLOT(slotStorageSelected(int)));
0101     }
0102 
0103     // the model will be owned by `proxyModel`
0104     KisResourceModel* resourceModel;
0105 
0106     if (m_type == WidgetType::ResourceManager) {
0107         resourceModel = new KisResourceModel(selectedResourceType);
0108         resourceModel->setStorageFilter(KisResourceModel::ShowAllStorages);
0109         resourceModel->setResourceFilter(m_ui->chkShowDeleted->isChecked() ? KisResourceModel::ShowAllResources : KisResourceModel::ShowActiveResources);
0110 
0111     } else {
0112 
0113         QString standarizedResourceType = (selectedResourceType == "presets" ? ResourceType::PaintOpPresets : selectedResourceType);
0114         resourceModel = new KisResourceModel(standarizedResourceType);
0115     }
0116 
0117     KisTagFilterResourceProxyModel* proxyModel = new KisTagFilterResourceProxyModel(selectedResourceType);
0118     proxyModel->setResourceModel(resourceModel);
0119     proxyModel->setTagFilter(0);
0120     if (m_type == WidgetType::ResourceManager) {
0121         proxyModel->setStorageFilter(true, getCurrentStorageId());
0122     }
0123     proxyModel->sort(KisAbstractResourceModel::Name);
0124     m_resourceProxyModelsForResourceType.insert(selectedResourceType, proxyModel);
0125 
0126     m_ui->resourceItemView->setModel(proxyModel);
0127     m_kisResourceItemDelegate = new KisResourceItemDelegate(this);
0128     m_ui->resourceItemView->setItemDelegate(m_kisResourceItemDelegate);
0129     m_ui->resourceItemView->setSelectionMode(QAbstractItemView::ExtendedSelection);
0130 
0131     if (m_type == WidgetType::BundleCreator) {
0132         m_ui->chkShowDeleted->setVisible(false);
0133     } else {
0134         connect(m_ui->chkShowDeleted, SIGNAL(stateChanged(int)), SLOT(slotShowDeletedChanged(int)));
0135     }
0136 
0137     connect(m_ui->lneFilterText, SIGNAL(textChanged(const QString&)), SLOT(slotFilterTextChanged(const QString&)));
0138 
0139     connect(m_ui->resourceItemView, SIGNAL(currentResourceChanged(QModelIndex)), SIGNAL(signalResourcesSelectionChanged(QModelIndex)));
0140 
0141     KisResourceItemViewer *viewModeButton;
0142 
0143     if (m_type == WidgetType::BundleCreator) {
0144         viewModeButton = new KisResourceItemViewer(Viewer::TableAvailable, this);
0145     } else {
0146         viewModeButton = new KisResourceItemViewer(Viewer::ResourceManager, this);
0147     }
0148 
0149     KisConfig cfg(true);
0150 
0151     if (m_type == WidgetType::BundleCreator) {
0152         m_mode = (cfg.readEntry<quint32>("ResourceItemsBCSearch.viewMode", 1) == 1)? ListViewMode::IconGrid : ListViewMode::Detail;
0153     } else {
0154         m_mode = (cfg.readEntry<quint32>("ResourceItemsRM.viewMode", 1) == 1)? ListViewMode::IconGrid : ListViewMode::Detail;
0155     }
0156 
0157     connect(viewModeButton, SIGNAL(onViewThumbnail()), this, SLOT(slotViewThumbnail()));
0158     connect(viewModeButton, SIGNAL(onViewDetails()), this, SLOT(slotViewDetails()));
0159 
0160     if (m_type == WidgetType::BundleCreator) {
0161         QLabel *label = new QLabel("Search");
0162         m_ui->horizontalLayout_2->addWidget(label);
0163     } else {
0164         m_ui->horizontalLayout_2->setAlignment(Qt::AlignRight);
0165     }
0166     m_ui->horizontalLayout_2->addWidget(viewModeButton);
0167 
0168     if (m_mode == ListViewMode::IconGrid) {
0169         slotViewThumbnail();
0170     } else {
0171         slotViewDetails();
0172     }
0173 
0174 }
0175 
0176 WdgResourcePreview::~WdgResourcePreview()
0177 {
0178     qDeleteAll(m_tagModelsForResourceType);
0179     qDeleteAll(m_resourceProxyModelsForResourceType);
0180     delete m_storageModel;
0181     delete m_resourceTypeModel;
0182 }
0183 
0184 void WdgResourcePreview::slotViewThumbnail()
0185 {
0186     m_kisResourceItemDelegate->setShowText(false);
0187     m_ui->resourceItemView->setItemDelegate(m_kisResourceItemDelegate);
0188     m_ui->resourceItemView->setListViewMode(ListViewMode::IconGrid);
0189 }
0190 
0191 void WdgResourcePreview::slotViewDetails()
0192 {
0193     m_kisResourceItemDelegate->setShowText(true);
0194     m_ui->resourceItemView->setItemDelegate(m_kisResourceItemDelegate);
0195     m_ui->resourceItemView->setListViewMode(ListViewMode::Detail);
0196 }
0197 
0198 void WdgResourcePreview::slotResourceTypeSelected(int)
0199 {
0200 
0201     QString selectedResourceType = getCurrentResourceType();
0202     if (!m_tagModelsForResourceType.contains(selectedResourceType)) {
0203         m_tagModelsForResourceType.insert(selectedResourceType, new KisTagModel(selectedResourceType));
0204         m_tagModelsForResourceType[selectedResourceType]->sort(KisAllTagsModel::Name);
0205     }
0206 
0207     m_ui->cmbTag->setModel(m_tagModelsForResourceType[selectedResourceType]);
0208 
0209     if (!m_resourceProxyModelsForResourceType.contains(selectedResourceType)) {
0210         // the model will be owned by `proxyModel`
0211         KisResourceModel* resourceModel;
0212         if (m_type == WidgetType::ResourceManager) {
0213             resourceModel = new KisResourceModel(selectedResourceType);
0214             KIS_SAFE_ASSERT_RECOVER_RETURN(resourceModel);
0215             resourceModel->setStorageFilter(KisResourceModel::ShowAllStorages);
0216             resourceModel->setResourceFilter(m_ui->chkShowDeleted->isChecked() ? KisResourceModel::ShowAllResources : KisResourceModel::ShowActiveResources);
0217         } else {
0218             QString standarizedResourceType = (selectedResourceType == "presets" ? ResourceType::PaintOpPresets : selectedResourceType);
0219             resourceModel = new KisResourceModel(standarizedResourceType);
0220             KIS_SAFE_ASSERT_RECOVER_RETURN(resourceModel);
0221         }
0222 
0223         KisTagFilterResourceProxyModel* proxyModel = new KisTagFilterResourceProxyModel(selectedResourceType);
0224         KIS_SAFE_ASSERT_RECOVER_RETURN(proxyModel);
0225         proxyModel->setResourceModel(resourceModel);
0226         proxyModel->sort(KisAbstractResourceModel::Name);
0227         m_resourceProxyModelsForResourceType.insert(selectedResourceType, proxyModel);
0228     }
0229 
0230     if (m_type == WidgetType::ResourceManager) {
0231         m_resourceProxyModelsForResourceType[selectedResourceType]->setStorageFilter(true, getCurrentStorageId());
0232     }
0233     m_resourceProxyModelsForResourceType[selectedResourceType]->setTagFilter(getCurrentTag());
0234 
0235     m_ui->resourceItemView->setModel(m_resourceProxyModelsForResourceType[selectedResourceType]);
0236 
0237     if (selectedResourceType == ResourceType::Gradients) {
0238         m_ui->resourceItemView->setFixedToolTipThumbnailSize(QSize(256, 64));
0239         m_ui->resourceItemView->setToolTipShouldRenderCheckers(true);
0240     }
0241     else if (selectedResourceType == ResourceType::PaintOpPresets) {
0242         m_ui->resourceItemView->setFixedToolTipThumbnailSize(QSize(128, 128));
0243     } else if (selectedResourceType == ResourceType::Patterns || selectedResourceType == ResourceType::Palettes) {
0244         m_ui->resourceItemView->setFixedToolTipThumbnailSize(QSize(256, 256));
0245         m_ui->resourceItemView->setToolTipShouldRenderCheckers(false);
0246     }
0247 }
0248 void WdgResourcePreview::slotTagSelected(int)
0249 {
0250     if (!m_resourceProxyModelsForResourceType.contains(getCurrentResourceType())) {
0251         return;
0252     }
0253     m_resourceProxyModelsForResourceType[getCurrentResourceType()]->setTagFilter(getCurrentTag());
0254 }
0255 void WdgResourcePreview::slotStorageSelected(int)
0256 {
0257     if (!m_resourceProxyModelsForResourceType.contains(getCurrentResourceType())) {
0258         return;
0259     }
0260     m_resourceProxyModelsForResourceType[getCurrentResourceType()]->setStorageFilter(true, getCurrentStorageId());
0261 }
0262 
0263 void WdgResourcePreview::slotFilterTextChanged(const QString& filterText)
0264 {
0265     if (m_resourceProxyModelsForResourceType.contains(getCurrentResourceType())) {
0266         m_resourceProxyModelsForResourceType[getCurrentResourceType()]->setSearchText(filterText);
0267     }
0268 }
0269 void WdgResourcePreview::slotShowDeletedChanged(int newState)
0270 {
0271     Q_UNUSED(newState);
0272 
0273     if (m_resourceProxyModelsForResourceType.contains(getCurrentResourceType())) {
0274         m_resourceProxyModelsForResourceType[getCurrentResourceType()]->setResourceFilter(
0275                     m_ui->chkShowDeleted->isChecked() ? KisTagFilterResourceProxyModel::ShowAllResources : KisTagFilterResourceProxyModel::ShowActiveResources);
0276     }
0277 }
0278 
0279 QString WdgResourcePreview::getCurrentResourceType()
0280 {
0281     if (m_type == WidgetType::ResourceManager) {
0282         return m_ui->cmbResourceType->currentData(Qt::UserRole + KisResourceTypeModel::ResourceType).toString();
0283     } else {
0284         QString s = m_ui->cmbResourceType->currentText();
0285         if (s == "Brush Presets") return "paintoppresets";
0286         if (s == "Brush Tips") return "brushes";
0287         if (s == "Gradients") return "gradients";
0288         if (s == "Gamut Masks") return "gamutmasks";
0289         if (s == "SeExpr Scripts") return "seexpr_scripts";
0290         if (s == "Palettes") return "palettes";
0291         if (s == "Patterns") return "patterns";
0292         if (s == "Workspaces") return "workspaces";
0293     }
0294     return "";
0295 }
0296 
0297 QSharedPointer<KisTag> WdgResourcePreview::getCurrentTag()
0298 {
0299     return m_ui->cmbTag->currentData(Qt::UserRole + KisAllTagsModel::KisTagRole).value<KisTagSP>();
0300 }
0301 
0302 QModelIndexList WdgResourcePreview::geResourceItemsSelected()
0303 {
0304     QModelIndexList list = m_ui->resourceItemView->selectionModel()->selection().indexes();
0305     return list;
0306 }
0307 
0308 QMap<QString, KisTagFilterResourceProxyModel*> WdgResourcePreview::getResourceProxyModelsForResourceType()
0309 {
0310     return m_resourceProxyModelsForResourceType;
0311 }
0312 
0313 int WdgResourcePreview::getCurrentStorageId()
0314 {
0315     return m_ui->cmbStorage->currentData(Qt::UserRole + KisStorageModel::Id).toInt();
0316 }
0317 
0318 QAbstractItemModel* WdgResourcePreview::getModel()
0319 {
0320     return m_ui->resourceItemView->model();
0321 }