You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
digikam/digikam/libs/dialogs/ctrlpaneldlg.cpp

446 lines
12 KiB

/* ============================================================
*
* 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 <caulier dot gilles at gmail dot com>
*
* 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 <tqvgroupbox.h>
#include <tqlabel.h>
#include <tqpushbutton.h>
#include <tqwhatsthis.h>
#include <tqtooltip.h>
#include <tqlayout.h>
#include <tqframe.h>
#include <tqtimer.h>
// KDE includes.
#include <kcursor.h>
#include <tdelocale.h>
#include <tdeaboutdata.h>
#include <khelpmenu.h>
#include <kiconloader.h>
#include <tdeapplication.h>
#include <tdepopupmenu.h>
#include <kstandarddirs.h>
#include <tdeglobalsettings.h>
// 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("<p>Reset all filter parameters to their default values.") );
setButtonWhatsThis ( User1, i18n("<p>Abort the current image rendering.") );
setButtonWhatsThis ( User3, i18n("<p>Load all filter parameters from settings text file.") );
setButtonWhatsThis ( User2, i18n("<p>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