mirror of
https://bitbucket.org/smil3y/kde-extraapps.git
synced 2025-02-27 04:13:05 +00:00
315 lines
10 KiB
C++
315 lines
10 KiB
C++
|
|
/*
|
|
Copyright (c) 2003-2007 Clarence Dang <dang@kde.org>
|
|
All rights reserved.
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
modification, are permitted provided that the following conditions
|
|
are met:
|
|
|
|
1. Redistributions of source code must retain the above copyright
|
|
notice, this list of conditions and the following disclaimer.
|
|
2. Redistributions in binary form must reproduce the above copyright
|
|
notice, this list of conditions and the following disclaimer in the
|
|
documentation and/or other materials provided with the distribution.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#define DEBUG_KP_TOOL_ROTATE 0
|
|
|
|
|
|
#include <kpTransformRotateDialog.h>
|
|
|
|
#include <qapplication.h>
|
|
#include <qbuttongroup.h>
|
|
#include <qgroupbox.h>
|
|
#include <qlabel.h>
|
|
#include <qlayout.h>
|
|
#include <QImage>
|
|
#include <qpolygon.h>
|
|
#include <qpushbutton.h>
|
|
#include <qradiobutton.h>
|
|
#include <qmatrix.h>
|
|
|
|
#include <kdebug.h>
|
|
#include <kiconloader.h>
|
|
#include <knuminput.h>
|
|
#include <klocale.h>
|
|
|
|
#include <kpDefs.h>
|
|
#include <kpDocument.h>
|
|
#include <kpPixmapFX.h>
|
|
#include <kpTool.h>
|
|
#include <kpTransformDialogEnvironment.h>
|
|
#include <kpViewManager.h>
|
|
|
|
|
|
// private static
|
|
int kpTransformRotateDialog::s_lastWidth = -1,
|
|
kpTransformRotateDialog::s_lastHeight = -1;
|
|
|
|
// private static
|
|
bool kpTransformRotateDialog::s_lastIsClockwise = true;
|
|
int kpTransformRotateDialog::s_lastAngleCustom = 0;
|
|
|
|
|
|
kpTransformRotateDialog::kpTransformRotateDialog (bool actOnSelection,
|
|
kpTransformDialogEnvironment *_env, QWidget *parent)
|
|
: kpTransformPreviewDialog (kpTransformPreviewDialog::AllFeatures,
|
|
false/*don't reserve top row*/,
|
|
actOnSelection ? i18nc ("@title:window", "Rotate Selection") : i18nc ("@title:window", "Rotate Image"),
|
|
i18n ("After rotate:"),
|
|
actOnSelection,
|
|
_env, parent)
|
|
{
|
|
s_lastAngleCustom = 0;
|
|
|
|
|
|
createDirectionGroupBox ();
|
|
createAngleGroupBox ();
|
|
|
|
|
|
if (s_lastWidth > 0 && s_lastHeight > 0)
|
|
resize (s_lastWidth, s_lastHeight);
|
|
|
|
|
|
slotAngleCustomRadioButtonToggled (m_angleCustomRadioButton->isChecked ());
|
|
slotUpdate ();
|
|
}
|
|
|
|
kpTransformRotateDialog::~kpTransformRotateDialog ()
|
|
{
|
|
s_lastWidth = width (), s_lastHeight = height ();
|
|
}
|
|
|
|
|
|
// private
|
|
void kpTransformRotateDialog::createDirectionGroupBox ()
|
|
{
|
|
QGroupBox *directionGroupBox = new QGroupBox (i18n ("Direction"), mainWidget ());
|
|
addCustomWidget (directionGroupBox);
|
|
|
|
|
|
QLabel *antiClockwisePixmapLabel = new QLabel (directionGroupBox);
|
|
antiClockwisePixmapLabel->setPixmap (UserIcon ("image_rotate_anticlockwise"));
|
|
|
|
QLabel *clockwisePixmapLabel = new QLabel (directionGroupBox);
|
|
clockwisePixmapLabel->setPixmap (UserIcon ("image_rotate_clockwise"));
|
|
|
|
|
|
m_antiClockwiseRadioButton = new QRadioButton (i18n ("Cou&nterclockwise"), directionGroupBox);
|
|
m_clockwiseRadioButton = new QRadioButton (i18n ("C&lockwise"), directionGroupBox);
|
|
|
|
|
|
m_antiClockwiseRadioButton->setChecked (!s_lastIsClockwise);
|
|
m_clockwiseRadioButton->setChecked (s_lastIsClockwise);
|
|
|
|
|
|
QGridLayout *directionLayout = new QGridLayout (directionGroupBox );
|
|
directionLayout->setSpacing( spacingHint() );
|
|
directionLayout->setMargin( marginHint () * 2 );
|
|
directionLayout->addWidget (antiClockwisePixmapLabel, 0, 0, Qt::AlignCenter);
|
|
directionLayout->addWidget (clockwisePixmapLabel, 0, 1, Qt::AlignCenter);
|
|
directionLayout->addWidget (m_antiClockwiseRadioButton, 1, 0, Qt::AlignCenter);
|
|
directionLayout->addWidget (m_clockwiseRadioButton, 1, 1, Qt::AlignCenter);
|
|
|
|
|
|
connect (m_antiClockwiseRadioButton, SIGNAL (toggled (bool)),
|
|
this, SLOT (slotUpdate ()));
|
|
connect (m_clockwiseRadioButton, SIGNAL (toggled (bool)),
|
|
this, SLOT (slotUpdate ()));
|
|
}
|
|
|
|
// private
|
|
void kpTransformRotateDialog::createAngleGroupBox ()
|
|
{
|
|
QGroupBox *angleGroupBox = new QGroupBox (i18n ("Angle"), mainWidget ());
|
|
addCustomWidget (angleGroupBox);
|
|
|
|
|
|
m_angle90RadioButton = new QRadioButton (i18n ("90 °rees"), angleGroupBox);
|
|
m_angle180RadioButton = new QRadioButton (i18n ("180 d&egrees"), angleGroupBox);
|
|
m_angle270RadioButton = new QRadioButton (i18n ("270 de&grees"), angleGroupBox);
|
|
|
|
m_angleCustomRadioButton = new QRadioButton (i18n ("C&ustom:"), angleGroupBox);
|
|
m_angleCustomInput = new KIntNumInput (s_lastAngleCustom, angleGroupBox);
|
|
m_angleCustomInput->setMinimum (-359);
|
|
m_angleCustomInput->setMaximum (+359);
|
|
QLabel *degreesLabel = new QLabel (i18n ("degrees"), angleGroupBox);
|
|
|
|
|
|
m_angleCustomRadioButton->setChecked (true);
|
|
|
|
|
|
QGridLayout *angleLayout = new QGridLayout (angleGroupBox );
|
|
angleLayout->setMargin( marginHint () * 2 );
|
|
angleLayout->setSpacing( spacingHint ());
|
|
|
|
angleLayout->addWidget (m_angle90RadioButton, 0, 0, 1, 3);
|
|
angleLayout->addWidget (m_angle180RadioButton, 1, 0, 1, 3);
|
|
angleLayout->addWidget (m_angle270RadioButton, 2, 0, 1, 3);
|
|
|
|
angleLayout->addWidget (m_angleCustomRadioButton, 3, 0);
|
|
angleLayout->addWidget (m_angleCustomInput, 3, 1);
|
|
angleLayout->addWidget (degreesLabel, 3, 2);
|
|
|
|
angleLayout->setColumnStretch (1, 2); // Stretch Custom Angle Input
|
|
|
|
|
|
connect (m_angle90RadioButton, SIGNAL (toggled (bool)),
|
|
this, SLOT (slotUpdate ()));
|
|
connect (m_angle180RadioButton, SIGNAL (toggled (bool)),
|
|
this, SLOT (slotUpdate ()));
|
|
connect (m_angle270RadioButton, SIGNAL (toggled (bool)),
|
|
this, SLOT (slotUpdate ()));
|
|
|
|
connect (m_angleCustomRadioButton, SIGNAL (toggled (bool)),
|
|
this, SLOT (slotAngleCustomRadioButtonToggled (bool)));
|
|
connect (m_angleCustomRadioButton, SIGNAL (toggled (bool)),
|
|
this, SLOT (slotUpdate ()));
|
|
|
|
connect (m_angleCustomInput, SIGNAL (valueChanged (int)),
|
|
this, SLOT (slotUpdate ()));
|
|
}
|
|
|
|
|
|
// public virtual [base kpTransformPreviewDialog]
|
|
bool kpTransformRotateDialog::isNoOp () const
|
|
{
|
|
return (angle () == 0);
|
|
}
|
|
|
|
// public
|
|
int kpTransformRotateDialog::angle () const
|
|
{
|
|
int retAngle;
|
|
|
|
|
|
if (m_angle90RadioButton->isChecked ())
|
|
retAngle = 90;
|
|
else if (m_angle180RadioButton->isChecked ())
|
|
retAngle = 180;
|
|
else if (m_angle270RadioButton->isChecked ())
|
|
retAngle = 270;
|
|
else // if (m_angleCustomRadioButton->isChecked ())
|
|
retAngle = m_angleCustomInput->value ();
|
|
|
|
|
|
if (m_antiClockwiseRadioButton->isChecked ())
|
|
retAngle *= -1;
|
|
|
|
|
|
if (retAngle < 0)
|
|
retAngle += ((0 - retAngle) / 360 + 1) * 360;
|
|
|
|
if (retAngle >= 360)
|
|
retAngle -= ((retAngle - 360) / 360 + 1) * 360;
|
|
|
|
|
|
return retAngle;
|
|
}
|
|
|
|
|
|
// private virtual [base kpTransformPreviewDialog]
|
|
QSize kpTransformRotateDialog::newDimensions () const
|
|
{
|
|
QMatrix matrix = kpPixmapFX::rotateMatrix (m_oldWidth, m_oldHeight, angle ());
|
|
QRect rect = matrix.mapRect (QRect (0, 0, m_oldWidth, m_oldHeight));
|
|
return rect.size ();
|
|
}
|
|
|
|
// private virtual [base kpTransformPreviewDialog]
|
|
QImage kpTransformRotateDialog::transformPixmap (const QImage &image,
|
|
int targetWidth, int targetHeight) const
|
|
{
|
|
return kpPixmapFX::rotate (image, angle (),
|
|
m_environ->backgroundColor (m_actOnSelection),
|
|
targetWidth, targetHeight);
|
|
}
|
|
|
|
|
|
// private slot
|
|
void kpTransformRotateDialog::slotAngleCustomRadioButtonToggled (bool isChecked)
|
|
{
|
|
m_angleCustomInput->setEnabled (isChecked);
|
|
|
|
if (isChecked)
|
|
m_angleCustomInput->setEditFocus ();
|
|
}
|
|
|
|
// private slot virtual [base kpTransformPreviewDialog]
|
|
void kpTransformRotateDialog::slotUpdate ()
|
|
{
|
|
s_lastIsClockwise = m_clockwiseRadioButton->isChecked ();
|
|
s_lastAngleCustom = m_angleCustomInput->value ();
|
|
|
|
kpTransformPreviewDialog::slotUpdate ();
|
|
}
|
|
|
|
|
|
// private slot virtual [base QDialog]
|
|
void kpTransformRotateDialog::accept ()
|
|
{
|
|
KLocalizedString message;
|
|
QString caption, continueButtonText;
|
|
|
|
if (document ()->selection ())
|
|
{
|
|
if (!document ()->textSelection ())
|
|
{
|
|
message =
|
|
ki18n ("<qt><p>Rotating the selection to %1x%2"
|
|
" may take a substantial amount of memory."
|
|
" This can reduce system"
|
|
" responsiveness and cause other application resource"
|
|
" problems.</p>"
|
|
|
|
"<p>Are you sure want to rotate the selection?</p></qt>");
|
|
|
|
caption = i18nc ("@title:window", "Rotate Selection?");
|
|
continueButtonText = i18n ("Rotat&e Selection");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
message =
|
|
ki18n ("<qt><p>Rotating the image to %1x%2"
|
|
" may take a substantial amount of memory."
|
|
" This can reduce system"
|
|
" responsiveness and cause other application resource"
|
|
" problems.</p>"
|
|
|
|
"<p>Are you sure want to rotate the image?</p></qt>");
|
|
|
|
caption = i18nc ("@title:window", "Rotate Image?");
|
|
continueButtonText = i18n ("Rotat&e Image");
|
|
}
|
|
|
|
|
|
const int newWidth = newDimensions ().width ();
|
|
const int newHeight = newDimensions ().height ();
|
|
|
|
if (kpTool::warnIfBigImageSize (m_oldWidth,
|
|
m_oldHeight,
|
|
newWidth, newHeight,
|
|
message.subs (newWidth).subs (newHeight).toString (),
|
|
caption,
|
|
continueButtonText,
|
|
this))
|
|
{
|
|
KDialog::accept ();
|
|
}
|
|
}
|
|
|
|
|
|
#include "moc_kpTransformRotateDialog.cpp"
|