File indexing completed on 2024-05-12 04:19:47
0001 // vim: set tabstop=4 shiftwidth=4 expandtab: 0002 /* 0003 Gwenview: an image viewer 0004 Copyright 2007 Aurélien Gâteau <agateau@kde.org> 0005 0006 This program is free software; you can redistribute it and/or 0007 modify it under the terms of the GNU General Public License 0008 as published by the Free Software Foundation; either version 2 0009 of the License, or (at your option) any later version. 0010 0011 This program is distributed in the hope that it will be useful, 0012 but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0014 GNU General Public License for more details. 0015 0016 You should have received a copy of the GNU General Public License 0017 along with this program; if not, write to the Free Software 0018 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 0019 0020 */ 0021 // Self 0022 #include "redeyereductiontool.h" 0023 0024 // Qt 0025 #include <QDialogButtonBox> 0026 #include <QGraphicsSceneMouseEvent> 0027 #include <QPainter> 0028 #include <QPushButton> 0029 #include <QRect> 0030 0031 // KF 0032 0033 // Local 0034 #include "gwenview_lib_debug.h" 0035 #include "gwenviewconfig.h" 0036 #include "redeyereductionimageoperation.h" 0037 #include "ui_redeyereductionwidget.h" 0038 #include <lib/documentview/rasterimageview.h> 0039 0040 namespace Gwenview 0041 { 0042 struct RedEyeReductionWidget : public QWidget, public Ui_RedEyeReductionWidget { 0043 RedEyeReductionWidget() 0044 { 0045 setupUi(this); 0046 QPushButton *okButton = mainDialogButtonBox->button(QDialogButtonBox::Ok); 0047 okButton->setIcon(QIcon::fromTheme(QStringLiteral("redeyes"))); 0048 okButton->setText(i18n("Reduce Red Eye")); 0049 } 0050 0051 void showNotSetPage() 0052 { 0053 // Prevent Close button from turning blue upon accepting 0054 helpTextLabel->setFocus(); 0055 0056 stackedWidget->setCurrentWidget(notSetPage); 0057 } 0058 0059 void showMainPage() 0060 { 0061 stackedWidget->setCurrentWidget(mainPage); 0062 } 0063 }; 0064 0065 struct RedEyeReductionToolPrivate { 0066 RedEyeReductionTool *q = nullptr; 0067 RedEyeReductionTool::Status mStatus; 0068 QPointF mCenter; 0069 int mDiameter; 0070 RedEyeReductionWidget *mToolWidget = nullptr; 0071 0072 void setupToolWidget() 0073 { 0074 mToolWidget = new RedEyeReductionWidget; 0075 mToolWidget->showNotSetPage(); 0076 QObject::connect(mToolWidget->diameterSpinBox, SIGNAL(valueChanged(int)), q, SLOT(setDiameter(int))); 0077 QObject::connect(mToolWidget->mainDialogButtonBox, &QDialogButtonBox::accepted, q, &RedEyeReductionTool::slotApplyClicked); 0078 QObject::connect(mToolWidget->mainDialogButtonBox, &QDialogButtonBox::rejected, q, &RedEyeReductionTool::done); 0079 QObject::connect(mToolWidget->helpDialogButtonBox, &QDialogButtonBox::rejected, q, &RedEyeReductionTool::done); 0080 } 0081 0082 QRectF rectF() const 0083 { 0084 if (mStatus == RedEyeReductionTool::NotSet) { 0085 return QRectF(); 0086 } 0087 return QRectF(mCenter.x() - mDiameter / 2, mCenter.y() - mDiameter / 2, mDiameter, mDiameter); 0088 } 0089 }; 0090 0091 RedEyeReductionTool::RedEyeReductionTool(RasterImageView *view) 0092 : AbstractRasterImageViewTool(view) 0093 , d(new RedEyeReductionToolPrivate) 0094 { 0095 d->q = this; 0096 d->mDiameter = GwenviewConfig::redEyeReductionDiameter(); 0097 d->mStatus = NotSet; 0098 d->setupToolWidget(); 0099 0100 view->document()->startLoadingFullImage(); 0101 } 0102 0103 RedEyeReductionTool::~RedEyeReductionTool() 0104 { 0105 GwenviewConfig::setRedEyeReductionDiameter(d->mDiameter); 0106 delete d->mToolWidget; 0107 delete d; 0108 } 0109 0110 void RedEyeReductionTool::paint(QPainter *painter) 0111 { 0112 if (d->mStatus == NotSet) { 0113 return; 0114 } 0115 const QRectF docRectF = d->rectF(); 0116 imageView()->document()->waitUntilLoaded(); 0117 0118 const QRect docRect = docRectF.toAlignedRect(); 0119 QImage img = imageView()->document()->image().copy(docRect); 0120 const QRectF imgRectF(docRectF.left() - docRect.left(), docRectF.top() - docRect.top(), docRectF.width(), docRectF.height()); 0121 RedEyeReductionImageOperation::apply(&img, imgRectF); 0122 0123 const QRectF viewRectF = imageView()->mapToView(docRectF); 0124 painter->drawImage(viewRectF, img, imgRectF); 0125 } 0126 0127 void RedEyeReductionTool::mousePressEvent(QGraphicsSceneMouseEvent *event) 0128 { 0129 if (event->buttons() != Qt::LeftButton || event->modifiers() & Qt::ControlModifier) { 0130 event->ignore(); 0131 return; 0132 } 0133 event->accept(); 0134 if (d->mStatus == NotSet) { 0135 d->mToolWidget->diameterSpinBox->setValue(d->mDiameter); 0136 d->mToolWidget->showMainPage(); 0137 d->mStatus = Adjusting; 0138 } 0139 d->mCenter = imageView()->mapToImage(event->pos()); 0140 imageView()->update(); 0141 } 0142 0143 void RedEyeReductionTool::mouseMoveEvent(QGraphicsSceneMouseEvent *event) 0144 { 0145 event->accept(); 0146 if (event->buttons() == Qt::NoButton) { 0147 return; 0148 } 0149 d->mCenter = imageView()->mapToImage(event->pos()); 0150 imageView()->update(); 0151 } 0152 0153 void RedEyeReductionTool::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) 0154 { 0155 // Just prevent the event from reaching the image view 0156 event->accept(); 0157 } 0158 0159 void RedEyeReductionTool::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) 0160 { 0161 if (event->buttons() != Qt::LeftButton) { 0162 event->ignore(); 0163 return; 0164 } 0165 event->accept(); 0166 Q_EMIT d->mToolWidget->mainDialogButtonBox->accepted(); 0167 } 0168 0169 void RedEyeReductionTool::keyPressEvent(QKeyEvent *event) 0170 { 0171 QDialogButtonBox *buttons; 0172 if (d->mStatus == Adjusting) { 0173 buttons = d->mToolWidget->mainDialogButtonBox; 0174 } else { 0175 buttons = d->mToolWidget->helpDialogButtonBox; 0176 } 0177 0178 switch (event->key()) { 0179 case Qt::Key_Escape: 0180 event->accept(); 0181 Q_EMIT buttons->rejected(); 0182 break; 0183 case Qt::Key_Return: 0184 case Qt::Key_Enter: { 0185 event->accept(); 0186 auto focusButton = static_cast<QPushButton *>(buttons->focusWidget()); 0187 if (focusButton && buttons->buttonRole(focusButton) == QDialogButtonBox::RejectRole) { 0188 Q_EMIT buttons->rejected(); 0189 } else { 0190 Q_EMIT buttons->accepted(); 0191 } 0192 break; 0193 } 0194 default: 0195 break; 0196 } 0197 } 0198 0199 void RedEyeReductionTool::toolActivated() 0200 { 0201 imageView()->setCursor(Qt::CrossCursor); 0202 } 0203 0204 void RedEyeReductionTool::slotApplyClicked() 0205 { 0206 QRectF docRectF = d->rectF(); 0207 if (!docRectF.isValid()) { 0208 qCWarning(GWENVIEW_LIB_LOG) << "invalid rect"; 0209 return; 0210 } 0211 auto op = new RedEyeReductionImageOperation(docRectF); 0212 Q_EMIT imageOperationRequested(op); 0213 0214 d->mStatus = NotSet; 0215 d->mToolWidget->showNotSetPage(); 0216 } 0217 0218 void RedEyeReductionTool::setDiameter(int value) 0219 { 0220 d->mDiameter = value; 0221 imageView()->update(); 0222 } 0223 0224 QWidget *RedEyeReductionTool::widget() const 0225 { 0226 return d->mToolWidget; 0227 } 0228 0229 } // namespace 0230 0231 #include "moc_redeyereductiontool.cpp"