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

0001 /*
0002  * SPDX-FileCopyrightText: 2004 Michael Thaler <michael.thaler@physik.tu-muenchen.de>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "rotateimage.h"
0008 
0009 #include <math.h>
0010 
0011 #include <klocalizedstring.h>
0012 #include <kis_debug.h>
0013 #include <kpluginfactory.h>
0014 #include <kis_icon.h>
0015 #include <kundo2magicstring.h>
0016 #include <kis_image.h>
0017 #include <kis_types.h>
0018 #include <KisViewManager.h>
0019 #include <kis_image_manager.h>
0020 #include <kis_node_manager.h>
0021 #include <kis_canvas_resource_provider.h>
0022 #include <kis_group_layer.h>
0023 #include <kis_action.h>
0024 #include <kis_selection.h>
0025 
0026 #include "dlg_rotateimage.h"
0027 
0028 K_PLUGIN_FACTORY_WITH_JSON(RotateImageFactory, "kritarotateimage.json", registerPlugin<RotateImage>();)
0029 
0030 RotateImage::RotateImage(QObject *parent, const QVariantList &)
0031         : KisActionPlugin(parent)
0032 {
0033 
0034     KisAction *action  = createAction("rotateimage");
0035     connect(action, SIGNAL(triggered()), this, SLOT(slotRotateImage()));
0036 
0037     action  = createAction("rotateImageCW90");
0038     connect(action, SIGNAL(triggered()), this, SLOT(slotRotateImage90()));
0039 
0040     action  = createAction("rotateImage180");
0041     connect(action, SIGNAL(triggered()), this, SLOT(slotRotateImage180()));
0042 
0043     action  = createAction("rotateImageCCW90");
0044     connect(action, SIGNAL(triggered()), this, SLOT(slotRotateImage270()));
0045 
0046     action  = createAction("mirrorImageHorizontal");
0047     connect(action, SIGNAL(triggered()), this, SLOT(slotMirrorImageHorizontal()));
0048 
0049     action  = createAction("mirrorImageVertical");
0050     connect(action, SIGNAL(triggered()), this, SLOT(slotMirrorImageVertical()));
0051 
0052     action  = createAction("rotatelayer");
0053     connect(action, SIGNAL(triggered()), this, SLOT(slotRotateLayer()));
0054 
0055     action  = createAction("rotateLayer180");
0056     connect(action, SIGNAL(triggered()), this, SLOT(slotRotateLayer180()));
0057 
0058     action  = createAction("rotateLayerCW90");
0059     connect(action, SIGNAL(triggered()), this, SLOT(slotRotateLayerCW90()));
0060 
0061     action  = createAction("rotateLayerCCW90");
0062     connect(action, SIGNAL(triggered()), this, SLOT(slotRotateLayerCCW90()));
0063 
0064     action  = createAction("rotateAllLayers");
0065     connect(action, SIGNAL(triggered()), this, SLOT(slotRotateAllLayers()));
0066 
0067     action  = createAction("rotateAllLayersCW90");
0068     connect(action, SIGNAL(triggered()), this, SLOT(slotRotateAllLayersCW90()));
0069 
0070     action  = createAction("rotateAllLayersCCW90");
0071     connect(action, SIGNAL(triggered()), this, SLOT(slotRotateAllLayersCCW90()));
0072 
0073     action  = createAction("rotateAllLayers180");
0074     connect(action, SIGNAL(triggered()), this, SLOT(slotRotateAllLayers180()));
0075 }
0076 
0077 RotateImage::~RotateImage()
0078 {
0079 }
0080 
0081 void RotateImage::slotRotateImage()
0082 {
0083     KisImageWSP image = viewManager()->image();
0084     if (!image) return;
0085 
0086     if (!viewManager()->blockUntilOperationsFinished(image)) return;
0087 
0088     DlgRotateImage * dlgRotateImage = new DlgRotateImage(viewManager()->mainWindowAsQWidget(), "RotateImage");
0089     Q_CHECK_PTR(dlgRotateImage);
0090 
0091     dlgRotateImage->setCaption(i18n("Rotate Image"));
0092 
0093     if (dlgRotateImage->exec() == QDialog::Accepted) {
0094         double angle = dlgRotateImage->angle() * M_PI / 180;
0095         viewManager()->imageManager()->rotateCurrentImage(angle);
0096     }
0097     delete dlgRotateImage;
0098 }
0099 
0100 void RotateImage::slotRotateImage90()
0101 {
0102     viewManager()->imageManager()->rotateCurrentImage(M_PI / 2);
0103 }
0104 
0105 void RotateImage::slotRotateImage180()
0106 {
0107     viewManager()->imageManager()->rotateCurrentImage(M_PI);
0108 }
0109 
0110 void RotateImage::slotRotateImage270()
0111 {
0112     viewManager()->imageManager()->rotateCurrentImage(- M_PI / 2 + M_PI*2);
0113 }
0114 
0115 void RotateImage::slotMirrorImageVertical()
0116 {
0117     KisImageWSP image = viewManager()->image();
0118     if (!image) return;
0119     viewManager()->nodeManager()->mirrorNode(image->rootLayer(),
0120                                              kundo2_i18n("Mirror Image Vertically"),
0121                                              Qt::Vertical, 0);
0122 }
0123 
0124 void RotateImage::slotMirrorImageHorizontal()
0125 {
0126     KisImageWSP image = viewManager()->image();
0127     if (!image) return;
0128     viewManager()->nodeManager()->mirrorNode(image->rootLayer(),
0129                                              kundo2_i18n("Mirror Image Horizontally"),
0130                                              Qt::Horizontal, 0);
0131 }
0132 
0133 
0134 void RotateImage::rotateLayerCustomImpl(KisNodeSP rootNode)
0135 {
0136     rotateLayersCustomImpl(KisNodeList{rootNode});
0137 }
0138 void RotateImage::rotateLayersCustomImpl(KisNodeList nodes)
0139 {
0140     KisImageWSP image = viewManager()->image();
0141     if (!image) return;
0142 
0143     if (!viewManager()->blockUntilOperationsFinished(image)) return;
0144 
0145     DlgRotateImage * dlgRotateImage = new DlgRotateImage(viewManager()->mainWindowAsQWidget(), "RotateLayer");
0146     Q_CHECK_PTR(dlgRotateImage);
0147 
0148     dlgRotateImage->setCaption(i18np("Rotate Layer", "Rotate %1 Layers", nodes.size()));
0149 
0150     if (dlgRotateImage->exec() == QDialog::Accepted) {
0151         double angle = dlgRotateImage->angle() * M_PI / 180;
0152         image->rotateNodes(nodes, angle, viewManager()->selection());
0153     }
0154     delete dlgRotateImage;
0155 }
0156 
0157 void RotateImage::rotateLayerImpl(KisNodeSP rootNode, qreal radians)
0158 {
0159     rotateLayersImpl(KisNodeList{rootNode}, radians);
0160 }
0161 void RotateImage::rotateLayersImpl(KisNodeList nodes, qreal radians)
0162 {
0163     KisImageWSP image = viewManager()->image();
0164     if (!image) return;
0165 
0166     if (!viewManager()->blockUntilOperationsFinished(image)) return;
0167 
0168     image->rotateNodes(nodes, radians, viewManager()->selection());
0169 }
0170 
0171 void RotateImage::slotRotateLayer()
0172 {
0173     rotateLayersCustomImpl(viewManager()->nodeManager()->selectedNodes());
0174 }
0175 
0176 void RotateImage::slotRotateAllLayers()
0177 {
0178     KisImageWSP image = viewManager()->image();
0179     if (!image) return;
0180 
0181     rotateLayerCustomImpl(image->root());
0182 }
0183 
0184 void RotateImage::slotRotateLayerCW90()
0185 {
0186     rotateLayersImpl(viewManager()->nodeManager()->selectedNodes(), M_PI / 2);
0187 }
0188 
0189 void RotateImage::slotRotateLayerCCW90()
0190 {
0191     rotateLayersImpl(viewManager()->nodeManager()->selectedNodes(), -M_PI / 2);
0192 }
0193 
0194 void RotateImage::slotRotateLayer180()
0195 {
0196     rotateLayersImpl(viewManager()->nodeManager()->selectedNodes(), M_PI);
0197 }
0198 
0199 void RotateImage::slotRotateAllLayersCW90()
0200 {
0201     KisImageWSP image = viewManager()->image();
0202     if (!image) return;
0203 
0204     rotateLayerImpl(image->root(), M_PI / 2);
0205 }
0206 
0207 void RotateImage::slotRotateAllLayersCCW90()
0208 {
0209     KisImageWSP image = viewManager()->image();
0210     if (!image) return;
0211 
0212     rotateLayerImpl(image->root(), -M_PI / 2);
0213 }
0214 
0215 void RotateImage::slotRotateAllLayers180()
0216 {
0217     KisImageWSP image = viewManager()->image();
0218     if (!image) return;
0219 
0220     rotateLayerImpl(image->root(), M_PI);
0221 }
0222 
0223 #include "rotateimage.moc"