File indexing completed on 2024-05-26 04:24:44

0001 /*
0002    Copyright (c) 2003-2007 Clarence Dang <dang@kde.org>
0003    All rights reserved.
0004 
0005    Redistribution and use in source and binary forms, with or without
0006    modification, are permitted provided that the following conditions
0007    are met:
0008 
0009    1. Redistributions of source code must retain the above copyright
0010       notice, this list of conditions and the following disclaimer.
0011    2. Redistributions in binary form must reproduce the above copyright
0012       notice, this list of conditions and the following disclaimer in the
0013       documentation and/or other materials provided with the distribution.
0014 
0015    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
0016    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0017    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
0018    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
0019    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
0020    NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0021    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0022    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0023    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
0024    THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0025 */
0026 
0027 
0028 #define DEBUG_KP_TOOL_SKEW 0
0029 #define DEBUG_KP_TOOL_SKEW_DIALOG 0
0030 
0031 
0032 #include "dialogs/imagelib/transforms/kpTransformSkewDialog.h"
0033 
0034 #include <QGridLayout>
0035 #include <QGroupBox>
0036 #include <QLabel>
0037 #include <QPushButton>
0038 #include <QImage>
0039 #include <QSpinBox>
0040 
0041 #include "kpLogCategories.h"
0042 #include <KLocalizedString>
0043 
0044 #include "kpDefs.h"
0045 #include "document/kpDocument.h"
0046 #include "pixmapfx/kpPixmapFX.h"
0047 #include "tools/kpTool.h"
0048 #include "environments/dialogs/imagelib/transforms/kpTransformDialogEnvironment.h"
0049 
0050 
0051 // private static
0052 int kpTransformSkewDialog::s_lastWidth = -1,
0053     kpTransformSkewDialog::s_lastHeight = -1;
0054 
0055 // private static
0056 int kpTransformSkewDialog::s_lastHorizontalAngle = 0,
0057     kpTransformSkewDialog::s_lastVerticalAngle = 0;
0058 
0059 
0060 kpTransformSkewDialog::kpTransformSkewDialog (bool actOnSelection,
0061         kpTransformDialogEnvironment *_env, QWidget *parent)
0062     : kpTransformPreviewDialog (kpTransformPreviewDialog::AllFeatures,
0063         false/*don't reserve top row*/,
0064         actOnSelection ? i18nc ("@title:window", "Skew Selection") : i18nc ("@title:window", "Skew Image"),
0065         i18n ("After skew:"),
0066         actOnSelection,
0067         _env, parent)
0068 {
0069     // Too confusing - disable for now
0070     s_lastHorizontalAngle = s_lastVerticalAngle = 0;
0071 
0072 
0073     createAngleGroupBox ();
0074 
0075 
0076     if (s_lastWidth > 0 && s_lastHeight > 0) {
0077         resize (s_lastWidth, s_lastHeight);
0078     }
0079 
0080 
0081     slotUpdate ();
0082     
0083 
0084     m_horizontalSkewInput->setFocus ();
0085 }
0086 
0087 kpTransformSkewDialog::~kpTransformSkewDialog ()
0088 {
0089     s_lastWidth = width ();
0090     s_lastHeight = height ();
0091 }
0092 
0093 
0094 // private
0095 void kpTransformSkewDialog::createAngleGroupBox ()
0096 {
0097     auto *angleGroupBox = new QGroupBox (i18n ("Angle"), mainWidget ());
0098     addCustomWidget (angleGroupBox);
0099 
0100 
0101     auto *horizontalSkewPixmapLabel = new QLabel (angleGroupBox);
0102     horizontalSkewPixmapLabel->setPixmap (QStringLiteral(":/icons/image_skew_horizontal"));
0103 
0104     auto *horizontalSkewLabel = new QLabel (i18n ("&Horizontal:"), angleGroupBox);
0105     m_horizontalSkewInput = new QSpinBox;
0106     m_horizontalSkewInput->setValue(s_lastHorizontalAngle);
0107     m_horizontalSkewInput->setMinimum(-89);
0108     m_horizontalSkewInput->setMaximum(+89);
0109 
0110     auto *horizontalSkewDegreesLabel = new QLabel (i18n ("degrees"), angleGroupBox);
0111 
0112 
0113     auto *verticalSkewPixmapLabel = new QLabel (angleGroupBox);
0114     verticalSkewPixmapLabel->setPixmap (QStringLiteral(":/icons/image_skew_vertical"));
0115 
0116     auto *verticalSkewLabel = new QLabel (i18n ("&Vertical:"), angleGroupBox);
0117     m_verticalSkewInput = new QSpinBox;
0118     m_verticalSkewInput->setValue(s_lastVerticalAngle);
0119     m_verticalSkewInput->setMinimum(-89);
0120     m_verticalSkewInput->setMaximum(+89);
0121 
0122     auto *verticalSkewDegreesLabel = new QLabel (i18n ("degrees"), angleGroupBox);
0123 
0124 
0125     horizontalSkewLabel->setBuddy (m_horizontalSkewInput);
0126     verticalSkewLabel->setBuddy (m_verticalSkewInput);
0127 
0128 
0129     auto *angleLayout = new QGridLayout (angleGroupBox);
0130 
0131     angleLayout->addWidget (horizontalSkewPixmapLabel, 0, 0);
0132     angleLayout->addWidget (horizontalSkewLabel, 0, 1);
0133     angleLayout->addWidget (m_horizontalSkewInput, 0, 2, Qt::AlignVCenter);
0134     angleLayout->addWidget (horizontalSkewDegreesLabel, 0, 3);
0135 
0136     angleLayout->addWidget (verticalSkewPixmapLabel, 1, 0);
0137     angleLayout->addWidget (verticalSkewLabel, 1, 1);
0138     angleLayout->addWidget (m_verticalSkewInput, 1, 2, Qt::AlignVCenter);
0139     angleLayout->addWidget (verticalSkewDegreesLabel, 1, 3);
0140 
0141 
0142     connect (m_horizontalSkewInput,
0143              static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
0144              this, &kpTransformSkewDialog::slotUpdate);
0145 
0146     connect (m_verticalSkewInput,
0147              static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
0148              this, &kpTransformSkewDialog::slotUpdate);
0149 }
0150 
0151 
0152 // private virtual [base kpTransformPreviewDialog]
0153 QSize kpTransformSkewDialog::newDimensions () const
0154 {
0155     kpDocument *doc = document ();
0156     Q_ASSERT (doc);
0157 
0158     auto skewMatrix = kpPixmapFX::skewMatrix (doc->image (),
0159                                                   horizontalAngleForPixmapFX (),
0160                                                   verticalAngleForPixmapFX ());
0161     auto skewRect = skewMatrix.mapRect (doc->rect (m_actOnSelection));
0162 
0163     return  {skewRect.width (), skewRect.height ()};
0164 }
0165 
0166 // private virtual [base kpTransformPreviewDialog]
0167 QImage kpTransformSkewDialog::transformPixmap (const QImage &image,
0168                                            int targetWidth, int targetHeight) const
0169 {
0170     return kpPixmapFX::skew (image,
0171                              horizontalAngleForPixmapFX (),
0172                              verticalAngleForPixmapFX (),
0173                              m_environ->backgroundColor (m_actOnSelection),
0174                              targetWidth,
0175                              targetHeight);
0176 }
0177 
0178 
0179 // private
0180 void kpTransformSkewDialog::updateLastAngles ()
0181 {
0182     s_lastHorizontalAngle = horizontalAngle ();
0183     s_lastVerticalAngle = verticalAngle ();
0184 }
0185 
0186 // private slot virtual [base kpTransformPreviewDialog]
0187 void kpTransformSkewDialog::slotUpdate ()
0188 {
0189     updateLastAngles ();
0190     kpTransformPreviewDialog::slotUpdate ();
0191 }
0192 
0193 
0194 // public
0195 int kpTransformSkewDialog::horizontalAngle () const
0196 {
0197     return m_horizontalSkewInput->value ();
0198 }
0199 
0200 // public
0201 int kpTransformSkewDialog::verticalAngle () const
0202 {
0203     return m_verticalSkewInput->value ();
0204 }
0205 
0206 
0207 // public static
0208 int kpTransformSkewDialog::horizontalAngleForPixmapFX (int hangle)
0209 {
0210     return -hangle;
0211 }
0212 
0213 // public static
0214 int kpTransformSkewDialog::verticalAngleForPixmapFX (int vangle)
0215 {
0216     return -vangle;
0217 }
0218 
0219 
0220 // public
0221 int kpTransformSkewDialog::horizontalAngleForPixmapFX () const
0222 {
0223     return kpTransformSkewDialog::horizontalAngleForPixmapFX (horizontalAngle ());
0224 }
0225 
0226 // public
0227 int kpTransformSkewDialog::verticalAngleForPixmapFX () const
0228 {
0229     return kpTransformSkewDialog::verticalAngleForPixmapFX (verticalAngle ());
0230 }
0231 
0232 
0233 // public virtual [base kpTransformPreviewDialog]
0234 bool kpTransformSkewDialog::isNoOp () const
0235 {
0236     return (horizontalAngle () == 0) && (verticalAngle () == 0);
0237 }
0238 
0239 
0240 // private slot virtual [base QDialog]
0241 void kpTransformSkewDialog::accept ()
0242 {
0243     KLocalizedString message;
0244     QString caption, continueButtonText;
0245 
0246     if (document ()->selection ())
0247     {
0248         if (!document ()->textSelection ())
0249         {
0250             message =
0251                 ki18n ("<qt><p>Skewing the selection to %1x%2"
0252                       " may take a substantial amount of memory."
0253                       " This can reduce system"
0254                       " responsiveness and cause other application resource"
0255                       " problems.</p>"
0256 
0257                       "<p>Are you sure you want to skew the selection?</p></qt>");
0258 
0259             caption = i18nc ("@title:window", "Skew Selection?");
0260             continueButtonText = i18n ("Sk&ew Selection");
0261         }
0262     }
0263     else
0264     {
0265         message =
0266             ki18n ("<qt><p>Skewing the image to %1x%2"
0267                   " may take a substantial amount of memory."
0268                   " This can reduce system"
0269                   " responsiveness and cause other application resource"
0270                   " problems.</p>"
0271 
0272                   "<p>Are you sure you want to skew the image?</p></qt>");
0273 
0274         caption = i18nc ("@title:window", "Skew Image?");
0275         continueButtonText = i18n ("Sk&ew Image");
0276     }
0277 
0278 
0279     const int newWidth = newDimensions ().width ();
0280     const int newHeight = newDimensions ().height ();
0281 
0282     if (kpTool::warnIfBigImageSize (m_oldWidth,
0283             m_oldHeight,
0284             newWidth, newHeight,
0285             message.subs (newWidth).subs (newHeight).toString (),
0286             caption,
0287             continueButtonText,
0288             this))
0289     {
0290         QDialog::accept ();
0291     }
0292 }
0293 
0294 #include "moc_kpTransformSkewDialog.cpp"