/* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2005-05-07 * Description : A threaded filter control panel dialog for * image editor plugins using DImg * * Copyright (C) 2005-2007 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ // TQt includes. #include #include #include #include #include #include #include #include // KDE includes. #include #include #include #include #include #include #include #include #include // Local includes. #include "ddebug.h" #include "dimgthreadedfilter.h" #include "dimginterface.h" #include "ctrlpaneldlg.h" #include "ctrlpaneldlg.moc" namespace Digikam { class CtrlPanelDlgPriv { public: enum RunningMode { NoneRendering=0, PreviewRendering, FinalRendering }; CtrlPanelDlgPriv() { parent = 0; timer = 0; aboutData = 0; progressBar = true; tryAction = false; currentRenderingMode = NoneRendering; } bool tryAction; bool progressBar; int currentRenderingMode; TQWidget *parent; TQTimer *timer; TQString name; TDEAboutData *aboutData; }; CtrlPanelDlg::CtrlPanelDlg(TQWidget* parent, TQString title, TQString name, bool loadFileSettings, bool tryAction, bool progressBar, int separateViewMode, TQFrame* bannerFrame) : KDialogBase(Plain, 0, Help|Default|User1|User2|User3|Try|Ok|Cancel, Ok, parent, 0, true, true, i18n("&Abort"), i18n("&Save As..."), i18n("&Load...")) { kapp->setOverrideCursor( KCursor::waitCursor() ); setCaption(DImgInterface::defaultInterface()->getImageFileName() + TQString(" - ") + title); d = new CtrlPanelDlgPriv; d->parent = parent; d->name = name; d->tryAction = tryAction; d->progressBar = progressBar; m_threadedFilter = 0; TQString whatsThis; setButtonWhatsThis ( Default, i18n("

Reset all filter parameters to their default values.") ); setButtonWhatsThis ( User1, i18n("

Abort the current image rendering.") ); setButtonWhatsThis ( User3, i18n("

Load all filter parameters from settings text file.") ); setButtonWhatsThis ( User2, i18n("

Save all filter parameters to settings text file.") ); showButton(User2, loadFileSettings); showButton(User3, loadFileSettings); showButton(Try, tryAction); // disable Abort button on startup enableButton(User1, false); resize(configDialogSize(name + TQString(" Tool Dialog"))); TQVBoxLayout *topLayout = new TQVBoxLayout( plainPage(), 0, spacingHint()); // ------------------------------------------------------------- if (bannerFrame) { bannerFrame->reparent( plainPage(), TQPoint(0, 0) ); topLayout->addWidget(bannerFrame); } // ------------------------------------------------------------- m_imagePreviewWidget = new ImagePannelWidget(470, 350, name + TQString(" Tool Dialog"), plainPage(), separateViewMode); topLayout->addWidget(m_imagePreviewWidget); // ------------------------------------------------------------- TQTimer::singleShot(0, this, TQ_SLOT(slotInit())); kapp->restoreOverrideCursor(); } CtrlPanelDlg::~CtrlPanelDlg() { if (d->aboutData) delete d->aboutData; if (d->timer) delete d->timer; if (m_threadedFilter) delete m_threadedFilter; delete d; } void CtrlPanelDlg::slotInit() { // Reset values to defaults. TQTimer::singleShot(0, this, TQ_SLOT(readUserSettings())); if (!d->tryAction) { connect(m_imagePreviewWidget, TQ_SIGNAL(signalOriginalClipFocusChanged()), this, TQ_SLOT(slotFocusChanged())); } else { connect(m_imagePreviewWidget, TQ_SIGNAL(signalResized()), this, TQ_SLOT(slotFocusChanged())); } } void CtrlPanelDlg::setAboutData(TDEAboutData *about) { d->aboutData = about; TQPushButton *helpButton = actionButton( Help ); KHelpMenu* helpMenu = new KHelpMenu(this, d->aboutData, false); helpMenu->menu()->removeItemAt(0); helpMenu->menu()->insertItem(i18n("digiKam Handbook"), this, TQ_SLOT(slotHelp()), 0, -1, 0); helpButton->setPopup( helpMenu->menu() ); } void CtrlPanelDlg::abortPreview() { d->currentRenderingMode = CtrlPanelDlgPriv::NoneRendering; m_imagePreviewWidget->setProgress(0); m_imagePreviewWidget->setPreviewImageWaitCursor(false); m_imagePreviewWidget->setEnable(true); m_imagePreviewWidget->setProgressVisible(false); enableButton(Ok, true); enableButton(User1, false); enableButton(User2, true); enableButton(User3, true); enableButton(Try, true); enableButton(Default, true); renderingFinished(); } void CtrlPanelDlg::slotTry() { slotEffect(); } void CtrlPanelDlg::slotUser1() { if (d->currentRenderingMode != CtrlPanelDlgPriv::NoneRendering) if (m_threadedFilter) m_threadedFilter->stopComputation(); } void CtrlPanelDlg::slotDefault() { resetValues(); slotEffect(); } void CtrlPanelDlg::slotCancel() { if (d->currentRenderingMode != CtrlPanelDlgPriv::NoneRendering) { if (m_threadedFilter) m_threadedFilter->stopComputation(); kapp->restoreOverrideCursor(); } saveDialogSize(d->name + TQString(" Tool Dialog")); done(Cancel); } void CtrlPanelDlg::closeEvent(TQCloseEvent *e) { if (d->currentRenderingMode != CtrlPanelDlgPriv::NoneRendering) { if (m_threadedFilter) m_threadedFilter->stopComputation(); kapp->restoreOverrideCursor(); } saveDialogSize(d->name + TQString(" Tool Dialog")); e->accept(); } void CtrlPanelDlg::slotFocusChanged(void) { if (d->currentRenderingMode == CtrlPanelDlgPriv::FinalRendering) { m_imagePreviewWidget->update(); return; } else if (d->currentRenderingMode == CtrlPanelDlgPriv::PreviewRendering) { if (m_threadedFilter) m_threadedFilter->stopComputation(); } TQTimer::singleShot(0, this, TQ_SLOT(slotEffect())); } void CtrlPanelDlg::slotHelp() { // If setAboutData() is called by plugin, well DigikamImagePlugins help is lauched, // else digiKam help. In this case, setHelp() method must be used to set anchor and handbook name. if (d->aboutData) TDEApplication::kApplication()->invokeHelp(d->name, "digikam"); else KDialogBase::slotHelp(); } void CtrlPanelDlg::slotTimer() { if (d->timer) { d->timer->stop(); delete d->timer; } d->timer = new TQTimer( this ); connect( d->timer, TQ_SIGNAL(timeout()), this, TQ_SLOT(slotEffect()) ); d->timer->start(500, true); } void CtrlPanelDlg::slotEffect() { // Computation already in process. if (d->currentRenderingMode != CtrlPanelDlgPriv::NoneRendering) return; d->currentRenderingMode = CtrlPanelDlgPriv::PreviewRendering; DDebug() << "Preview " << d->name << " started..." << endl; m_imagePreviewWidget->setEnable(false); m_imagePreviewWidget->setProgressVisible(true); enableButton(Ok, false); enableButton(User1, true); enableButton(User2, false); enableButton(User3, false); enableButton(Try, false); enableButton(Default, false); m_imagePreviewWidget->setPreviewImageWaitCursor(true); m_imagePreviewWidget->setProgress(0); if (m_threadedFilter) { delete m_threadedFilter; m_threadedFilter = 0; } prepareEffect(); } void CtrlPanelDlg::slotOk() { d->currentRenderingMode = CtrlPanelDlgPriv::FinalRendering; DDebug() << "Final " << d->name << " started..." << endl; saveDialogSize(d->name + TQString(" Tool Dialog")); writeUserSettings(); m_imagePreviewWidget->setEnable(false); m_imagePreviewWidget->setProgressVisible(true); enableButton(Ok, false); enableButton(User1, false); enableButton(User2, false); enableButton(User3, false); enableButton(Try, false); enableButton(Default, false); kapp->setOverrideCursor( KCursor::waitCursor() ); m_imagePreviewWidget->setProgress(0); if (m_threadedFilter) { delete m_threadedFilter; m_threadedFilter = 0; } prepareFinal(); } void CtrlPanelDlg::customEvent(TQCustomEvent *event) { if (!event) return; DImgThreadedFilter::EventData *ed = (DImgThreadedFilter::EventData*) event->data(); if (!ed) return; if (ed->starting) // Computation in progress ! { m_imagePreviewWidget->setProgress(ed->progress); } else { if (ed->success) // Computation Completed ! { switch (d->currentRenderingMode) { case CtrlPanelDlgPriv::PreviewRendering: { DDebug() << "Preview " << d->name << " completed..." << endl; putPreviewData(); abortPreview(); break; } case CtrlPanelDlgPriv::FinalRendering: { DDebug() << "Final" << d->name << " completed..." << endl; putFinalData(); kapp->restoreOverrideCursor(); accept(); break; } } } else // Computation Failed ! { switch (d->currentRenderingMode) { case CtrlPanelDlgPriv::PreviewRendering: { DDebug() << "Preview " << d->name << " failed..." << endl; // abortPreview() must be call here for set progress bar to 0 properly. abortPreview(); break; } case CtrlPanelDlgPriv::FinalRendering: break; } } } delete ed; } // Backport KDialog::keyPressEvent() implementation from KDELibs to ignore Enter/Return Key events // to prevent any conflicts between dialog keys events and SpinBox keys events. void CtrlPanelDlg::keyPressEvent(TQKeyEvent *e) { if ( e->state() == 0 ) { switch ( e->key() ) { case Key_Escape: e->accept(); reject(); break; case Key_Enter: case Key_Return: e->ignore(); break; default: e->ignore(); return; } } else { // accept the dialog when Ctrl-Return is pressed if ( e->state() == ControlButton && (e->key() == Key_Return || e->key() == Key_Enter) ) { e->accept(); accept(); } else { e->ignore(); } } } } // NameSpace Digikam