File indexing completed on 2024-05-12 16:01:32

0001 /* This file is part of the KDE project
0002  * SPDX-FileCopyrightText: 2006 Boudewijn Rempt <boud@valdyas.org>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "kis_image_manager.h"
0008 
0009 #include <QString>
0010 #include <QStandardPaths>
0011 
0012 #include <QAction>
0013 #include <QUrl>
0014 #include <QColorDialog>
0015 
0016 #include <klocalizedstring.h>
0017 
0018 #include <KoColor.h>
0019 #include <KoFileDialog.h>
0020 
0021 #include <kis_types.h>
0022 #include <kis_image.h>
0023 #include <kis_icon.h>
0024 #include <KisImportExportManager.h>
0025 #include "kis_import_catcher.h"
0026 #include "KisViewManager.h"
0027 #include "KisDocument.h"
0028 #include "dialogs/kis_dlg_image_properties.h"
0029 #include "commands/kis_image_commands.h"
0030 #include "kis_action.h"
0031 #include "kis_action_manager.h"
0032 #include "kis_layer_utils.h"
0033 
0034 #include "kis_signal_compressor_with_param.h"
0035 
0036 
0037 KisImageManager::KisImageManager(KisViewManager * view)
0038         : m_view(view)
0039 {
0040 }
0041 
0042 void KisImageManager::setView(QPointer<KisView>imageView)
0043 {
0044     Q_UNUSED(imageView);
0045 }
0046 
0047 void KisImageManager::setup(KisActionManager *actionManager)
0048 {
0049 
0050     KisAction *action  = actionManager->createAction("import_layer_from_file");
0051     connect(action, SIGNAL(triggered()), this, SLOT(slotImportLayerFromFile()));
0052 
0053     action  = actionManager->createAction("image_properties");
0054     connect(action, SIGNAL(triggered()), this, SLOT(slotImageProperties()));
0055 
0056     action  = actionManager->createAction("import_layer_as_paint_layer");
0057     connect(action, SIGNAL(triggered()), this, SLOT(slotImportLayerFromFile()));
0058 
0059     action  = actionManager->createAction("import_layer_as_transparency_mask");
0060     connect(action, SIGNAL(triggered()), this, SLOT(slotImportLayerAsTransparencyMask()));
0061 
0062     action  = actionManager->createAction("import_layer_as_filter_mask");
0063     connect(action, SIGNAL(triggered()), this, SLOT(slotImportLayerAsFilterMask()));
0064 
0065     action  = actionManager->createAction("import_layer_as_selection_mask");
0066     connect(action, SIGNAL(triggered()), this, SLOT(slotImportLayerAsSelectionMask()));
0067 
0068     action = actionManager->createAction("image_color");
0069     connect(action, SIGNAL(triggered()), this, SLOT(slotImageColor()));
0070 }
0071 
0072 void KisImageManager::slotImportLayerFromFile()
0073 {
0074     importImage(QUrl(), "KisPaintLayer");
0075 }
0076 
0077 void KisImageManager::slotImportLayerAsTransparencyMask()
0078 {
0079     importImage(QUrl(), "KisTransparencyMask");
0080 }
0081 
0082 void KisImageManager::slotImportLayerAsFilterMask()
0083 {
0084     importImage(QUrl(), "KisFilterMask");
0085 }
0086 
0087 void KisImageManager::slotImportLayerAsSelectionMask()
0088 {
0089     importImage(QUrl(), "KisSelectionMask");
0090 }
0091 
0092 
0093 qint32 KisImageManager::importImage(const QUrl &urlArg, const QString &layerType)
0094 {
0095     KisImageWSP currentImage = m_view->image();
0096 
0097     if (!currentImage) {
0098         return 0;
0099     }
0100 
0101     QList<QString> paths;
0102     qint32 rc = 0;
0103 
0104     if (urlArg.isEmpty()) {
0105         KoFileDialog dialog(m_view->mainWindowAsQWidget(), KoFileDialog::OpenFiles, "OpenDocument");
0106         dialog.setCaption(i18n("Import Image"));
0107         dialog.setDefaultDir(QStandardPaths::writableLocation(QStandardPaths::PicturesLocation));
0108         dialog.setMimeTypeFilters(KisImportExportManager::supportedMimeTypes(KisImportExportManager::Import));
0109         QStringList fileNames = dialog.filenames();
0110         Q_FOREACH (const QString &fileName, fileNames) {
0111             paths << fileName;
0112         }
0113 
0114     } else {
0115         paths.push_back(urlArg.toLocalFile());
0116     }
0117 
0118     if (paths.empty()) {
0119         return 0;
0120     }
0121 
0122     Q_FOREACH(const QString &path, paths) {
0123         if (path.endsWith("svg")) {
0124             new KisImportCatcher(path, m_view, "KisShapeLayer");
0125         }
0126         else {
0127             new KisImportCatcher(path, m_view, layerType);
0128         }
0129     }
0130 
0131     m_view->canvas()->update();
0132 
0133     return rc;
0134 }
0135 
0136 void KisImageManager::resizeCurrentImage(qint32 w, qint32 h, qint32 xOffset, qint32 yOffset)
0137 {
0138     if (!m_view->image()) return;
0139 
0140     m_view->image()->resizeImage(QRect(-xOffset, -yOffset, w, h));
0141 }
0142 
0143 void KisImageManager::scaleCurrentImage(const QSize &size, qreal xres, qreal yres, KisFilterStrategy *filterStrategy)
0144 {
0145     if (!m_view->image()) return;
0146     m_view->image()->scaleImage(size, xres, yres, filterStrategy);
0147 }
0148 
0149 void KisImageManager::rotateCurrentImage(double radians)
0150 {
0151     if (!m_view->image()) return;
0152     m_view->image()->rotateImage(radians);
0153 }
0154 
0155 void KisImageManager::shearCurrentImage(double angleX, double angleY)
0156 {
0157     if (!m_view->image()) return;
0158     m_view->image()->shear(angleX, angleY);
0159 }
0160 
0161 
0162 void KisImageManager::slotImageProperties()
0163 {
0164     KisImageWSP image = m_view->image();
0165     if (!image) return;
0166 
0167     QPointer<KisDlgImageProperties> dlg = new KisDlgImageProperties(image, m_view->mainWindowAsQWidget());
0168     if (dlg->exec() == QDialog::Accepted) {
0169         if (dlg->convertLayerPixels()) {
0170             image->convertImageColorSpace(dlg->colorSpace(),
0171                                           KoColorConversionTransformation::internalRenderingIntent(),
0172                                           KoColorConversionTransformation::internalConversionFlags());
0173 
0174         } else {
0175             image->convertImageProjectionColorSpace(dlg->colorSpace());
0176         }
0177     }
0178     delete dlg;
0179 }
0180 
0181 void updateImageBackgroundColor(KisImageSP image, const QColorDialog *dlg)
0182 {
0183     QColor newColor = dlg->currentColor();
0184     KoColor bg = image->defaultProjectionColor();
0185     bg.fromQColor(newColor);
0186 
0187     KisLayerUtils::changeImageDefaultProjectionColor(image, bg);
0188 }
0189 
0190 void KisImageManager::slotImageColor()
0191 {
0192     KisImageWSP image = m_view->image();
0193     if (!image) return;
0194 
0195     QColorDialog dlg;
0196     dlg.setOption(QColorDialog::ShowAlphaChannel, true);
0197     dlg.setWindowTitle(i18n("Select a Color"));
0198     KoColor oldBgColor = image->defaultProjectionColor();
0199     dlg.setCurrentColor(oldBgColor.toQColor());
0200 
0201     KisSignalCompressor compressor(200, KisSignalCompressor::FIRST_INACTIVE);
0202 
0203     std::function<void ()> updateCall(std::bind(updateImageBackgroundColor, image, &dlg));
0204     SignalToFunctionProxy proxy(updateCall);
0205 
0206     connect(&dlg, SIGNAL(currentColorChanged(QColor)), &compressor, SLOT(start()));
0207     connect(&compressor, SIGNAL(timeout()), &proxy, SLOT(start()));
0208 
0209     if (dlg.exec() == QDialog::Accepted) {
0210         if (compressor.isActive()) {
0211             compressor.stop();
0212             updateCall();
0213         }
0214     } else {
0215         KisLayerUtils::changeImageDefaultProjectionColor(image, oldBgColor);
0216     }
0217 }
0218 
0219