File indexing completed on 2024-06-16 04:16:50

0001 /*
0002  * This file is part of Krita
0003  *
0004  * SPDX-FileCopyrightText: 2020 L. E. Segovia <amy@amyspark.me>
0005  *
0006  *  SPDX-License-Identifier: GPL-2.0-or-later
0007  */
0008 
0009 #include <KStandardGuiItem>
0010 #include <QDate>
0011 #include <QMessageBox>
0012 #include <QTime>
0013 
0014 #include <KisImportExportManager.h>
0015 #include <KisResourceUserOperations.h>
0016 #include <KoColorSpaceRegistry.h>
0017 #include <KoFileDialog.h>
0018 #include <KoResourceServerProvider.h>
0019 
0020 #include <kis_fill_painter.h>
0021 #include <kis_paint_device.h>
0022 #include <kis_default_bounds.h>
0023 
0024 #include "KisResourceTypes.h"
0025 #include "kis_wdg_seexpr_presets_save.h"
0026 #include "resources/KisSeExprScript.h"
0027 
0028 KisWdgSeExprPresetsSave::KisWdgSeExprPresetsSave(QWidget *parent)
0029     : KisWdgSeExprSavePreset(parent)
0030     , m_currentPreset(nullptr)
0031 {
0032     // we will default to reusing the previous preset thumbnail
0033     // have that checked by default, hide the other elements, and load the last preset image
0034     connect(loadExistingThumbnailButton, SIGNAL(clicked(bool)), this, SLOT(loadExistingThumbnail()));
0035     connect(loadImageIntoThumbnailButton, SIGNAL(clicked(bool)), this, SLOT(loadImageFromFile()));
0036     connect(loadRenderFromScriptButton, SIGNAL(clicked(bool)), this, SLOT(renderScriptToThumbnail()));
0037     connect(clearPresetThumbnailButton, SIGNAL(clicked(bool)), presetThumbnailWidget, SLOT(clear()));
0038 
0039     KGuiItem::assign(buttons->button(QDialogButtonBox::Save), KStandardGuiItem::save());
0040     KGuiItem::assign(buttons->button(QDialogButtonBox::Cancel), KStandardGuiItem::cancel());
0041 
0042     connect(buttons, SIGNAL(accepted()), this, SLOT(savePreset()));
0043     connect(buttons, SIGNAL(rejected()), this, SLOT(close()));
0044 }
0045 
0046 KisWdgSeExprPresetsSave::~KisWdgSeExprPresetsSave()
0047 {
0048 }
0049 
0050 void KisWdgSeExprPresetsSave::setCurrentPreset(KisSeExprScriptSP resource)
0051 {
0052     m_currentPreset = resource;
0053 }
0054 
0055 void KisWdgSeExprPresetsSave::setCurrentRenderConfiguration(KisFilterConfigurationSP config)
0056 {
0057     m_currentConfiguration = config;
0058 }
0059 
0060 void KisWdgSeExprPresetsSave::showDialog()
0061 {
0062     setModal(true);
0063 
0064     // set the name of the current preset area.
0065     KisSeExprScriptSP preset = m_currentPreset;
0066 
0067     // UI will look a bit different if we are saving a new preset
0068     if (m_useNewPresetDialog) {
0069         setWindowTitle(i18n("Save New SeExpr Preset"));
0070 
0071         if (preset) {
0072             // If the id is -1, this is a new preset that has never been saved, so it cannot be a copy
0073             QString name = preset->name().replace("_", " ");
0074             if (preset->resourceId() > -1) {
0075                 name = QString("%1 %2").arg(name, i18n("Copy"));
0076             }
0077             newPresetNameTextField->setText(name);
0078             newPresetNameTextField->setReadOnly(false);
0079             newPresetNameTextField->setEnabled(true);
0080         }
0081     } else {
0082         setWindowTitle(i18n("Save SeExpr Preset"));
0083 
0084         if (preset) {
0085             const QString name(preset->name().replace("_", " "));
0086             newPresetNameTextField->setText(name);
0087             newPresetNameTextField->setReadOnly(true);
0088             newPresetNameTextField->setEnabled(false);
0089         }
0090     }
0091 
0092     if (preset) {
0093         presetThumbnailWidget->setPixmap(QPixmap::fromImage(preset->image()));
0094     }
0095 
0096     open();
0097 }
0098 
0099 void KisWdgSeExprPresetsSave::loadImageFromFile()
0100 {
0101     // create a dialog to retrieve an image file.
0102     KoFileDialog dialog(0, KoFileDialog::OpenFile, "OpenDocument");
0103     dialog.setMimeTypeFilters(KisImportExportManager::supportedMimeTypes(KisImportExportManager::Import));
0104     dialog.setDefaultDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
0105     QString filename = dialog.filename(); // the filename() returns the entire path & file name, not just the file name
0106 
0107     if (!filename.isEmpty()) { // empty if "cancel" is pressed
0108         // take that file and load it into the thumbnail are
0109         const QImage imageToLoad(filename);
0110 
0111         presetThumbnailWidget->clear(); // clear the background in case our new image has transparency
0112         presetThumbnailWidget->setPixmap(QPixmap::fromImage(imageToLoad));
0113     }
0114 }
0115 
0116 void KisWdgSeExprPresetsSave::loadExistingThumbnail()
0117 {
0118     presetThumbnailWidget->setPixmap(QPixmap::fromImage(m_currentPreset->image()));
0119 }
0120 
0121 void KisWdgSeExprPresetsSave::renderScriptToThumbnail()
0122 {
0123     if (m_currentConfiguration) {
0124         // TODO add some sort of progress marker?
0125         KisDefaultBoundsBaseSP bounds(new KisWrapAroundBoundsWrapper(new KisDefaultBounds(), QRect(0, 0, 256, 256)));
0126         KisPaintDeviceSP src = new KisPaintDevice(KoColorSpaceRegistry::instance()->rgb8());
0127         src->setDefaultBounds(bounds);
0128         src->setSupportsWraparoundMode(true);
0129         KisFillPainter fillPainter(src);
0130         fillPainter.fillRect(0, 0, 256, 256, m_currentConfiguration);
0131 
0132         QImage thumbnail = src->convertToQImage(nullptr, 0, 0, 256, 256);
0133         presetThumbnailWidget->setPixmap(QPixmap::fromImage(thumbnail));
0134     }
0135 }
0136 
0137 void KisWdgSeExprPresetsSave::savePreset()
0138 {
0139     KIS_ASSERT_RECOVER_RETURN(m_currentPreset);
0140 
0141     KisResourceModel model(ResourceType::SeExprScripts);
0142     QModelIndex idx = model.indexForResourceId(m_currentPreset->resourceId());
0143     bool r = true;
0144 
0145     if (idx.isValid() && !m_useNewPresetDialog) {
0146         // saving a preset that is replacing an existing one
0147         const QString presetFileName = m_currentPreset->name().split(" ").join("_");
0148         if (presetThumbnailWidget->pixmap()) {
0149             m_currentPreset->setImage(presetThumbnailWidget->pixmap()->toImage());
0150         }
0151         m_currentPreset->setScript(m_currentConfiguration->getString("script"));
0152         m_currentPreset->setFilename(presetFileName + m_currentPreset->defaultFileExtension());
0153         m_currentPreset->setValid(true);
0154         r = KisResourceUserOperations::updateResourceWithUserInput(this, m_currentPreset);
0155         if (r) {
0156             emit resourceSelected(m_currentPreset);
0157         }
0158     } else {
0159         // Saving a completely new preset
0160         // Clone the preset, otherwise the modifications will impact the existing resource
0161         KisSeExprScriptSP newPreset = m_currentPreset->clone().dynamicCast<KisSeExprScript>();
0162 
0163         if (newPreset) {
0164             const QString presetFileName = newPresetNameTextField->text().split(" ").join("_");
0165             newPreset->setName(newPresetNameTextField->text());
0166             newPreset->setFilename(presetFileName + newPreset->defaultFileExtension());
0167             if (presetThumbnailWidget->pixmap()) {
0168                 newPreset->setImage(presetThumbnailWidget->pixmap()->toImage());
0169             }
0170             newPreset->setScript(m_currentConfiguration->getString("script"));
0171             newPreset->setValid(true);
0172 
0173             r = KisResourceUserOperations::addResourceWithUserInput(this, newPreset);
0174 
0175             // trying to get brush preset to load after it is created
0176             if (r) {
0177                 m_currentPreset = newPreset;
0178                 emit resourceSelected(m_currentPreset);
0179             }
0180         }
0181     }
0182 
0183     close(); // we are done... so close the save brush dialog
0184 }
0185 
0186 void KisWdgSeExprPresetsSave::useNewPresetDialog(bool show)
0187 {
0188     m_useNewPresetDialog = show;
0189 }
0190 
0191 #include "moc_kis_wdg_seexpr_presets_save.cpp"