File indexing completed on 2024-06-02 04:32:28
0001 /* 0002 * SPDX-FileCopyrightText: 2021 Mathias Wein <lynx.mw+kde@gmail.com> 0003 * SPDX-FileCopyrightText: 2023 Srirupa Datta <srirupa.sps@gmail.com> 0004 * 0005 * SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "DlgResourceManager.h" 0009 0010 #include "ui_WdgDlgResourceManager.h" 0011 0012 #include <QItemSelection> 0013 #include <QPainter> 0014 0015 #include <kis_action.h> 0016 #include <kis_action_manager.h> 0017 #include <KisResourceTypeModel.h> 0018 #include <KisStorageModel.h> 0019 #include <KisTagModel.h> 0020 #include <KisResourceModel.h> 0021 #include <KisTagFilterResourceProxyModel.h> 0022 #include <kis_assert.h> 0023 #include <KisResourceItemDelegate.h> 0024 #include <wdgtagselection.h> 0025 #include <kis_paintop_factory.h> 0026 #include <kis_paintop_registry.h> 0027 #include <dlg_create_bundle.h> 0028 #include <ResourceImporter.h> 0029 #include <KisResourceLocator.h> 0030 0031 DlgResourceManager::DlgResourceManager(KisActionManager *actionMgr, QWidget *parent) 0032 : KoDialog(parent) 0033 , m_ui(new Ui::WdgDlgResourceManager) 0034 , m_actionManager(actionMgr) 0035 , m_tagsController(0) 0036 { 0037 setCaption(i18n("Manage Resources")); 0038 m_page = new QWidget(this); 0039 m_ui->setupUi(m_page); 0040 resize(m_page->size()); 0041 setMainWidget(m_page); 0042 setButtons(Close); 0043 setDefaultButton(Close); 0044 0045 m_wdgResourcePreview = new WdgResourcePreview(WidgetType::ResourceManager, this); 0046 m_ui->formLayout->addWidget(m_wdgResourcePreview); 0047 0048 connect(m_wdgResourcePreview, SIGNAL(signalResourcesSelectionChanged(QModelIndex)), this, SLOT(slotResourcesSelectionChanged(QModelIndex))); 0049 0050 connect(m_ui->btnDeleteResource, SIGNAL(clicked(bool)), SLOT(slotDeleteResources())); 0051 connect(m_ui->btnCreateBundle, SIGNAL(clicked(bool)), SLOT(slotCreateBundle())); 0052 connect(m_ui->btnOpenResourceFolder, SIGNAL(clicked(bool)), SLOT(slotOpenResourceFolder())); 0053 connect(m_ui->btnImportResources, SIGNAL(clicked(bool)), SLOT(slotImportResources())); 0054 connect(m_ui->btnExtractTagsToResourceFolder, SIGNAL(clicked(bool)), SLOT(slotSaveTags())); 0055 0056 0057 m_tagsController.reset(new KisWdgTagSelectionControllerOneResource(m_ui->wdgResourcesTags, true)); 0058 0059 #ifdef Q_OS_ANDROID 0060 // TODO(sh_zam): Opening a directory can cause a crash. A ContentProvider is needed for this. 0061 m_ui->btnOpenResourceFolder->setEnabled(false); 0062 m_ui->btnOpenResourceFolder->setVisible(false); 0063 #endif 0064 0065 // make sure the panel is properly cleared. -Amy 0066 slotResourcesSelectionChanged({}); 0067 } 0068 0069 DlgResourceManager::~DlgResourceManager() 0070 { 0071 } 0072 0073 void DlgResourceManager::slotResourcesSelectionChanged(QModelIndex index) 0074 { 0075 Q_UNUSED(index); 0076 QModelIndexList list = m_wdgResourcePreview->geResourceItemsSelected(); 0077 KisTagFilterResourceProxyModel* model = m_wdgResourcePreview->getResourceProxyModelsForResourceType()[m_wdgResourcePreview->getCurrentResourceType()]; 0078 if (list.size() == 1) { 0079 const QModelIndex idx = list[0]; 0080 m_ui->lblFilename->setText(model->data(idx, Qt::UserRole + KisAllResourcesModel::Filename).toString()); 0081 m_ui->lneName->setText(model->data(idx, Qt::UserRole + KisAllResourcesModel::Name).toString()); 0082 m_ui->lblLocation->setText(model->data(idx, Qt::UserRole + KisAllResourcesModel::Location).toString()); 0083 m_ui->lblId->setText(model->data(idx, Qt::UserRole + KisAllResourcesModel::Id).toString()); 0084 0085 const QSize thumbSize = m_ui->lblThumbnail->size(); 0086 0087 QImage thumbLabel = m_thumbnailPainter.getReadyThumbnail(idx, thumbSize*devicePixelRatioF(), palette()); 0088 thumbLabel.setDevicePixelRatio(devicePixelRatioF()); 0089 0090 const QPixmap pix = QPixmap::fromImage(thumbLabel); 0091 m_ui->lblThumbnail->setScaledContents(true); 0092 m_ui->lblThumbnail->setPixmap(pix); 0093 0094 const QMap<QString, QVariant> metadata = 0095 model->data(idx, Qt::UserRole + KisAllResourcesModel::MetaData).toMap(); 0096 0097 m_ui->lblMetadata->setDisabled(false); 0098 m_ui->lblFilename->setDisabled(false); 0099 m_ui->lblLocation->setDisabled(false); 0100 m_ui->lblThumbnail->setDisabled(false); 0101 m_ui->lneName->setDisabled(false); 0102 m_ui->lblId->setDisabled(false); 0103 m_ui->lblMetadata->setText(constructMetadata(metadata, m_wdgResourcePreview->getCurrentResourceType())); 0104 } else if (list.size() > 1) { 0105 0106 QString commonLocation = model->data(list.first(), Qt::UserRole + KisAllResourcesModel::Location).toString(); 0107 bool commonLocationFound = true; 0108 Q_FOREACH(QModelIndex idx, list) { 0109 QString location = model->data(idx, Qt::UserRole + KisAllResourcesModel::Location).toString(); 0110 if (location != commonLocation) { 0111 commonLocationFound = false; 0112 } 0113 } 0114 0115 QString multipleSelectedText = i18nc("In Resource manager, this is text shown instead of filename, name or location, " 0116 "when multiple resources are shown so there is no one specific filename", "(Multiple selected)"); 0117 0118 m_ui->lblId->setText(multipleSelectedText); 0119 m_ui->lblMetadata->setText(""); 0120 m_ui->lblFilename->setText(multipleSelectedText); 0121 m_ui->lblLocation->setText(commonLocationFound ? commonLocation : multipleSelectedText); 0122 m_ui->lneName->setText(multipleSelectedText); 0123 m_ui->lblThumbnail->setText(multipleSelectedText); 0124 QPixmap pix; 0125 m_ui->lblThumbnail->setPixmap(pix); 0126 0127 m_ui->lblMetadata->setDisabled(true); 0128 m_ui->lblFilename->setDisabled(true); 0129 m_ui->lblLocation->setDisabled(!commonLocationFound); 0130 m_ui->lblThumbnail->setDisabled(true); 0131 m_ui->lneName->setDisabled(true); 0132 m_ui->lblId->setDisabled(true); 0133 } else { 0134 QString noneSelectedText = i18nc("In Resource manager, this is text shown instead of filename, name or location, " 0135 "when no resource is shown so there is no specific filename", "(None selected)"); 0136 0137 m_ui->lblId->setText(noneSelectedText); 0138 m_ui->lblMetadata->setText(noneSelectedText); 0139 m_ui->lblFilename->setText(noneSelectedText); 0140 m_ui->lblLocation->setText(noneSelectedText); 0141 m_ui->lneName->setText(noneSelectedText); 0142 m_ui->lblThumbnail->setText(noneSelectedText); 0143 m_ui->lblThumbnail->setPixmap({}); 0144 0145 m_ui->lblMetadata->setDisabled(true); 0146 m_ui->lblFilename->setDisabled(true); 0147 m_ui->lblLocation->setDisabled(true); 0148 m_ui->lblThumbnail->setDisabled(true); 0149 m_ui->lneName->setDisabled(true); 0150 m_ui->lblId->setDisabled(true); 0151 } 0152 0153 QList<int> resourceIds; 0154 Q_FOREACH(QModelIndex idx, list) { 0155 int resourceId = model->data(idx, Qt::UserRole + KisAllResourcesModel::Id).toInt(); 0156 resourceIds << resourceId; 0157 } 0158 updateDeleteButtonState(list); 0159 m_tagsController->setResourceIds(m_wdgResourcePreview->getCurrentResourceType(), resourceIds); 0160 } 0161 0162 void DlgResourceManager::slotDeleteResources() 0163 { 0164 QModelIndexList list = m_wdgResourcePreview->geResourceItemsSelected(); 0165 QMap<QString, KisTagFilterResourceProxyModel*> resourceProxyModelsForResourceType = m_wdgResourcePreview->getResourceProxyModelsForResourceType(); 0166 0167 if (!resourceProxyModelsForResourceType.contains(m_wdgResourcePreview->getCurrentResourceType()) || list.empty()) { 0168 return; 0169 } 0170 KisTagFilterResourceProxyModel *model = resourceProxyModelsForResourceType[m_wdgResourcePreview->getCurrentResourceType()]; 0171 KisAllResourcesModel *allModel = KisResourceModelProvider::resourceModel(m_wdgResourcePreview->getCurrentResourceType()); 0172 0173 if (static_cast<QAbstractItemModel*>(model) != m_wdgResourcePreview->getModel()) { 0174 qCritical() << "wrong item model!"; 0175 return; 0176 } 0177 0178 // deleting a resource with "Show deleted resources" disabled will update the proxy model 0179 // and next index in selection now points at wrong item. 0180 QList<int> resourceIds; 0181 Q_FOREACH (QModelIndex index, list) { 0182 int resourceId = model->data(index, Qt::UserRole + KisResourceModel::Id).toInt(); 0183 resourceIds.append(resourceId); 0184 } 0185 0186 Q_FOREACH (int resourceId, resourceIds) { 0187 0188 QModelIndex index = allModel->indexForResourceId(resourceId); 0189 allModel->setResourceActive(index, m_undeleteMode); 0190 } 0191 0192 updateDeleteButtonState(list); 0193 } 0194 0195 void DlgResourceManager::slotImportResources() 0196 { 0197 ResourceImporter importer(this); 0198 importer.importResources(); 0199 0200 } 0201 0202 void DlgResourceManager::slotOpenResourceFolder() 0203 { 0204 if (m_actionManager) { 0205 KisAction *action = m_actionManager->actionByName("open_resources_directory"); 0206 action->trigger(); 0207 } 0208 } 0209 0210 void DlgResourceManager::slotCreateBundle() 0211 { 0212 DlgCreateBundle* dlg = new DlgCreateBundle(0, this); 0213 dlg->exec(); 0214 } 0215 0216 0217 void DlgResourceManager::slotSaveTags() 0218 { 0219 KisResourceLocator::instance()->saveTags(); 0220 } 0221 0222 void DlgResourceManager::updateDeleteButtonState(const QModelIndexList &list) 0223 { 0224 bool allActive = true; 0225 bool allInactive = true; 0226 0227 for(QModelIndex index: list) { 0228 bool active = index.data(Qt::UserRole + KisAllResourcesModel::ResourceActive).toBool(); 0229 allActive = allActive && active; 0230 allInactive = allInactive && !active; 0231 } 0232 0233 // if nothing selected or selected are mixed active/inactive state 0234 if (allActive == allInactive) { 0235 m_ui->btnDeleteResource->setEnabled(false); 0236 } 0237 // either all are active or all are inactive 0238 else { 0239 m_undeleteMode = allInactive; 0240 m_ui->btnDeleteResource->setEnabled(true); 0241 if (m_undeleteMode) { 0242 m_ui->btnDeleteResource->setText(i18n("Undelete Resources")); 0243 } else { 0244 m_ui->btnDeleteResource->setText(i18n("Delete Resources")); 0245 } 0246 } 0247 } 0248 0249 QString DlgResourceManager::constructMetadata(const QMap<QString, QVariant> &metadata, const QString &resourceType) 0250 { 0251 QString response; 0252 if (resourceType == ResourceType::PaintOpPresets) { 0253 QString paintopKey = "paintopid"; 0254 QString paintopId = metadata.contains(paintopKey) ? metadata[paintopKey].toString() : ""; 0255 if (!paintopId.isEmpty()) { 0256 0257 KisPaintOpFactory* factory = KisPaintOpRegistry::instance()->get(paintopId); 0258 if (factory) { 0259 QString name = factory->name(); 0260 response.append(name); 0261 } else { 0262 response.append(i18nc("Brush engine type, in resource manager", "Engine: ")); 0263 response.append(paintopId); 0264 } 0265 } 0266 0267 0268 } else if (resourceType == ResourceType::GamutMasks) { 0269 QString descriptionKey = "description"; 0270 QString description = metadata.contains(descriptionKey) ? metadata[descriptionKey].toString() : ""; 0271 response.append(description); 0272 } else { 0273 Q_FOREACH(QString key, metadata.keys()) { 0274 response.append(key).append(": ").append(metadata[key].toString()).append("\n"); 0275 } 0276 } 0277 return response; 0278 0279 }