File indexing completed on 2024-05-26 04:24:43
0001 0002 /* 0003 Copyright (c) 2003-2007 Clarence Dang <dang@kde.org> 0004 All rights reserved. 0005 0006 Redistribution and use in source and binary forms, with or without 0007 modification, are permitted provided that the following conditions 0008 are met: 0009 0010 1. Redistributions of source code must retain the above copyright 0011 notice, this list of conditions and the following disclaimer. 0012 2. Redistributions in binary form must reproduce the above copyright 0013 notice, this list of conditions and the following disclaimer in the 0014 documentation and/or other materials provided with the distribution. 0015 0016 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 0017 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 0018 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 0019 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 0020 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 0021 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 0022 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 0023 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 0024 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 0025 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0026 */ 0027 0028 0029 #define DEBUG_KP_EFFECTS_DIALOG 0 0030 0031 0032 #include "kpEffectsDialog.h" 0033 0034 #include "kpDefs.h" 0035 #include "document/kpDocument.h" 0036 #include "widgets/imagelib/effects/kpEffectBalanceWidget.h" 0037 #include "widgets/imagelib/effects/kpEffectBlurSharpenWidget.h" 0038 #include "widgets/imagelib/effects/kpEffectEmbossWidget.h" 0039 #include "widgets/imagelib/effects/kpEffectFlattenWidget.h" 0040 #include "widgets/imagelib/effects/kpEffectHSVWidget.h" 0041 #include "widgets/imagelib/effects/kpEffectInvertWidget.h" 0042 #include "widgets/imagelib/effects/kpEffectReduceColorsWidget.h" 0043 #include "widgets/imagelib/effects/kpEffectToneEnhanceWidget.h" 0044 #include "pixmapfx/kpPixmapFX.h" 0045 #include "environments/dialogs/imagelib/transforms/kpTransformDialogEnvironment.h" 0046 0047 #include <KConfig> 0048 #include "kpLogCategories.h" 0049 #include <KLocalizedString> 0050 0051 #include <QComboBox> 0052 #include <QGroupBox> 0053 #include <QLabel> 0054 #include <QLayout> 0055 #include <QTimer> 0056 #include <QImage> 0057 0058 0059 // protected static 0060 int kpEffectsDialog::s_lastWidth = 640; 0061 int kpEffectsDialog::s_lastHeight = 620; 0062 0063 0064 kpEffectsDialog::kpEffectsDialog (bool actOnSelection, 0065 kpTransformDialogEnvironment *_env, 0066 QWidget *parent, 0067 int defaultSelectedEffect) 0068 : kpTransformPreviewDialog (kpTransformPreviewDialog::Preview, 0069 true/*reserve top row*/, 0070 QString()/*caption*/, 0071 QString()/*afterActionText (no Dimensions Group Box)*/, 0072 actOnSelection, 0073 _env, 0074 parent), 0075 m_delayedUpdateTimer (new QTimer (this)), 0076 m_effectsComboBox (nullptr), 0077 m_settingsGroupBox (nullptr), 0078 m_settingsLayout (nullptr), 0079 m_effectWidget (nullptr) 0080 { 0081 #if DEBUG_KP_EFFECTS_DIALOG 0082 qCDebug(kpLogDialogs) << "kpEffectsDialog::kpEffectsDialog()"; 0083 #endif 0084 const bool e = updatesEnabled (); 0085 setUpdatesEnabled (false); 0086 0087 0088 if (actOnSelection) { 0089 setWindowTitle (i18nc ("@title:window", "More Image Effects (Selection)")); 0090 } 0091 else { 0092 setWindowTitle (i18nc ("@title:window", "More Image Effects")); 0093 } 0094 0095 0096 m_delayedUpdateTimer->setSingleShot (true); 0097 connect (m_delayedUpdateTimer, &QTimer::timeout, 0098 this, &kpEffectsDialog::slotUpdateWithWaitCursor); 0099 0100 0101 QWidget *effectContainer = new QWidget (mainWidget ()); 0102 0103 auto *containerLayout = new QHBoxLayout (effectContainer); 0104 containerLayout->setContentsMargins(0, 0, 0, 0); 0105 0106 QLabel *label = new QLabel (i18n ("&Effect:"), effectContainer); 0107 0108 m_effectsComboBox = new QComboBox (effectContainer); 0109 // Keep in alphabetical order. 0110 // TODO: What about translations? 0111 // sync: order in selectEffect(). 0112 m_effectsComboBox->addItem (i18n ("Balance")); 0113 m_effectsComboBox->addItem (i18n ("Emboss")); 0114 m_effectsComboBox->addItem (i18n ("Flatten")); 0115 m_effectsComboBox->addItem (i18n ("Histogram Equalizer")); 0116 m_effectsComboBox->addItem (i18n ("Hue, Saturation, Value")); 0117 m_effectsComboBox->addItem (i18n ("Invert")); 0118 m_effectsComboBox->addItem (i18n ("Reduce Colors")); 0119 m_effectsComboBox->addItem (i18n ("Soften & Sharpen")); 0120 0121 containerLayout->addWidget (label); 0122 containerLayout->addWidget (m_effectsComboBox, 1); 0123 0124 label->setBuddy (m_effectsComboBox); 0125 0126 addCustomWidgetToFront (effectContainer); 0127 0128 0129 m_settingsGroupBox = new QGroupBox (mainWidget ()); 0130 m_settingsLayout = new QVBoxLayout ( m_settingsGroupBox ); 0131 addCustomWidgetToBack (m_settingsGroupBox); 0132 0133 0134 connect (m_effectsComboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated), 0135 this, &kpEffectsDialog::selectEffect); 0136 0137 0138 selectEffect (defaultSelectedEffect); 0139 0140 0141 resize (s_lastWidth, s_lastHeight); 0142 0143 0144 #if DEBUG_KP_EFFECTS_DIALOG 0145 qCDebug(kpLogDialogs) << "about to setUpdatesEnabled()"; 0146 #endif 0147 // OPT: The preview pixmap gets recalculated here and then possibly 0148 // again when QResizeEvent fires, when the dialog is shown. 0149 setUpdatesEnabled (e); 0150 #if DEBUG_KP_EFFECTS_DIALOG 0151 qCDebug(kpLogDialogs) << endl 0152 << endl 0153 << endl; 0154 #endif 0155 } 0156 0157 kpEffectsDialog::~kpEffectsDialog () 0158 { 0159 s_lastWidth = width (); 0160 s_lastHeight = height (); 0161 } 0162 0163 0164 // public virtual [base kpTransformPreviewDialog] 0165 bool kpEffectsDialog::isNoOp () const 0166 { 0167 if (!m_effectWidget) { 0168 return true; 0169 } 0170 0171 return m_effectWidget->isNoOp (); 0172 } 0173 0174 // public 0175 kpEffectCommandBase *kpEffectsDialog::createCommand () const 0176 { 0177 if (!m_effectWidget) { 0178 return nullptr; 0179 } 0180 0181 return m_effectWidget->createCommand (m_environ->commandEnvironment ()); 0182 } 0183 0184 0185 // protected virtual [base kpTransformPreviewDialog] 0186 QSize kpEffectsDialog::newDimensions () const 0187 { 0188 kpDocument *doc = document (); 0189 if (!doc) { 0190 return {}; 0191 } 0192 0193 return {doc->width (m_actOnSelection), doc->height (m_actOnSelection)}; 0194 } 0195 0196 // protected virtual [base kpTransformPreviewDialog] 0197 QImage kpEffectsDialog::transformPixmap (const QImage &pixmap, 0198 int targetWidth, int targetHeight) const 0199 { 0200 QImage pixmapWithEffect; 0201 0202 if (m_effectWidget && !m_effectWidget->isNoOp ()) { 0203 pixmapWithEffect = m_effectWidget->applyEffect (pixmap); 0204 } 0205 else { 0206 pixmapWithEffect = pixmap; 0207 } 0208 0209 return kpPixmapFX::scale (pixmapWithEffect, targetWidth, targetHeight); 0210 } 0211 0212 0213 // public 0214 int kpEffectsDialog::selectedEffect () const 0215 { 0216 return m_effectsComboBox->currentIndex (); 0217 } 0218 0219 // public slot 0220 void kpEffectsDialog::selectEffect (int which) 0221 { 0222 #if DEBUG_KP_EFFECTS_DIALOG 0223 qCDebug(kpLogDialogs) << "kpEffectsDialog::selectEffect(" << which << ")"; 0224 #endif 0225 0226 if (which < 0 || 0227 which >= m_effectsComboBox->count ()) 0228 { 0229 return; 0230 } 0231 0232 if (which != m_effectsComboBox->currentIndex ()) { 0233 m_effectsComboBox->setCurrentIndex (which); 0234 } 0235 0236 0237 delete m_effectWidget; 0238 m_effectWidget = nullptr; 0239 0240 0241 m_settingsGroupBox->setWindowTitle(QString()); 0242 0243 #define CREATE_EFFECT_WIDGET(name) \ 0244 m_effectWidget = new name (m_actOnSelection, m_settingsGroupBox) 0245 // sync: order in constructor. 0246 switch (which) 0247 { 0248 case 0: 0249 CREATE_EFFECT_WIDGET (kpEffectBalanceWidget); 0250 break; 0251 0252 case 1: 0253 CREATE_EFFECT_WIDGET (kpEffectEmbossWidget); 0254 break; 0255 0256 case 2: 0257 CREATE_EFFECT_WIDGET (kpEffectFlattenWidget); 0258 break; 0259 0260 case 3: 0261 CREATE_EFFECT_WIDGET (kpEffectToneEnhanceWidget); 0262 break; 0263 0264 case 4: 0265 CREATE_EFFECT_WIDGET (kpEffectHSVWidget); 0266 break; 0267 0268 case 5: 0269 CREATE_EFFECT_WIDGET (kpEffectInvertWidget); 0270 break; 0271 0272 case 6: 0273 CREATE_EFFECT_WIDGET (kpEffectReduceColorsWidget); 0274 break; 0275 0276 case 7: 0277 CREATE_EFFECT_WIDGET (kpEffectBlurSharpenWidget); 0278 break; 0279 } 0280 #undef CREATE_EFFECT_WIDGET 0281 0282 0283 if (m_effectWidget) 0284 { 0285 const bool e = updatesEnabled (); 0286 setUpdatesEnabled (false); 0287 0288 #if DEBUG_KP_EFFECTS_DIALOG 0289 qCDebug(kpLogDialogs) << "widget exists for effect #"; 0290 #endif 0291 m_settingsGroupBox->setTitle (m_effectWidget->caption ()); 0292 0293 // Show widget. 0294 // 0295 // Don't resize the whole dialog when doing this. 0296 // This seems to work magically without any extra code with Qt4. 0297 #if DEBUG_KP_EFFECTS_DIALOG 0298 qCDebug(kpLogDialogs) << "addWidget"; 0299 #endif 0300 m_settingsLayout->addWidget (m_effectWidget); 0301 #if DEBUG_KP_EFFECTS_DIALOG 0302 qCDebug(kpLogDialogs) << "show widget"; 0303 #endif 0304 m_effectWidget->show (); 0305 0306 connect (m_effectWidget, &kpEffectWidgetBase::settingsChangedNoWaitCursor, 0307 this, &kpEffectsDialog::slotUpdate); 0308 connect (m_effectWidget, &kpEffectWidgetBase::settingsChanged, 0309 this, &kpEffectsDialog::slotUpdateWithWaitCursor); 0310 connect (m_effectWidget, &kpEffectWidgetBase::settingsChangedDelayed, 0311 this, &kpEffectsDialog::slotDelayedUpdate); 0312 0313 #if DEBUG_KP_EFFECTS_DIALOG 0314 qCDebug(kpLogDialogs) << "about to setUpdatesEnabled()"; 0315 #endif 0316 setUpdatesEnabled (e); 0317 } 0318 0319 0320 #if DEBUG_KP_EFFECTS_DIALOG 0321 qCDebug(kpLogDialogs) << "done" 0322 << endl 0323 << endl 0324 << endl; 0325 #endif 0326 } 0327 0328 0329 // protected slot virtual [base kpTransformPreviewDialog] 0330 void kpEffectsDialog::slotUpdate () 0331 { 0332 #if DEBUG_KP_EFFECTS_DIALOG 0333 qCDebug(kpLogDialogs) << "kpEffectsDialog::slotUpdate()" 0334 << " timerActive=" << m_delayedUpdateTimer->isActive () 0335 << endl; 0336 #endif 0337 0338 m_delayedUpdateTimer->stop (); 0339 0340 kpTransformPreviewDialog::slotUpdate (); 0341 } 0342 0343 // protected slot virtual [base kpTransformPreviewDialog] 0344 void kpEffectsDialog::slotUpdateWithWaitCursor () 0345 { 0346 #if DEBUG_KP_EFFECTS_DIALOG 0347 qCDebug(kpLogDialogs) << "kpEffectsDialog::slotUpdateWithWaitCursor()" 0348 << " timerActive=" << m_delayedUpdateTimer->isActive () 0349 << endl; 0350 #endif 0351 0352 m_delayedUpdateTimer->stop (); 0353 0354 kpTransformPreviewDialog::slotUpdateWithWaitCursor (); 0355 } 0356 0357 0358 // protected slot 0359 void kpEffectsDialog::slotDelayedUpdate () 0360 { 0361 #if DEBUG_KP_EFFECTS_DIALOG 0362 qCDebug(kpLogDialogs) << "kpEffectsDialog::slotDelayedUpdate()" 0363 << " timerActive=" << m_delayedUpdateTimer->isActive () 0364 << endl; 0365 #endif 0366 m_delayedUpdateTimer->stop (); 0367 0368 // (single shot) 0369 m_delayedUpdateTimer->start (400/*ms*/); 0370 } 0371 0372 #include "moc_kpEffectsDialog.cpp"