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.
kipi-plugins/kipi-plugins/rawconverter/singledialog.cpp

598 lines
22 KiB

/* ============================================================
*
* This file is a part of kipi-plugins project
* http://www.kipi-plugins.org
*
* Date : 2003-10-22
* Description : Raw converter single dialog
*
* Copyright (C) 2003-2005 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
* Copyright (C) 2006-2008 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.
*
* ============================================================ */
// C Ansi includes.
extern "C"
{
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
}
// C++ includes.
#include <cstdio>
// TQt includes.
#include <tqtimer.h>
#include <tqframe.h>
#include <tqlabel.h>
#include <tqlayout.h>
#include <tqtooltip.h>
#include <tqfileinfo.h>
#include <tqevent.h>
#include <tqpushbutton.h>
#include <tqfile.h>
// KDE includes.
#include <kcursor.h>
#include <tdelocale.h>
#include <tdemessagebox.h>
#include <tdeconfig.h>
#include <tdeio/renamedlg.h>
#include <tdeapplication.h>
#include <khelpmenu.h>
#include <kiconloader.h>
#include <tdepopupmenu.h>
#include <kstandarddirs.h>
#include <kdebug.h>
// LibKDcraw includes.
#include <libkdcraw/version.h>
#include <libkdcraw/dcrawsettingswidget.h>
// Local includes.
#include "kpaboutdata.h"
#include "pluginsversion.h"
#include "previewwidget.h"
#include "rawdecodingiface.h"
#include "savesettingswidget.h"
#include "actionthread.h"
#include "singledialog.h"
#include "singledialog.moc"
namespace KIPIRawConverterPlugin
{
SingleDialog::SingleDialog(const TQString& file, TQWidget */*parent*/)
: KDialogBase(0, 0, false, i18n("Raw Image Converter"),
Help|Default|User1|User2|User3|Close, Close, true,
i18n("&Preview"), i18n("Con&vert"), i18n("&Abort"))
{
m_inputFile = file;
m_inputFileName = TQFileInfo(file).fileName();
TQWidget *page = new TQWidget( this );
setMainWidget( page );
TQGridLayout *mainLayout = new TQGridLayout(page, 1, 1, 0, spacingHint());
m_previewWidget = new PreviewWidget(page);
// ---------------------------------------------------------------
m_decodingSettingsBox = new KDcrawIface::DcrawSettingsWidget(page, false, true, true);
m_saveSettingsBox = new SaveSettingsWidget(m_decodingSettingsBox);
#if KDCRAW_VERSION >= 0x000105
m_decodingSettingsBox->addItem(m_saveSettingsBox, i18n("Save settings"));
m_decodingSettingsBox->updateMinimumWidth();
#else
m_decodingSettingsBox->insertTab(m_saveSettingsBox, i18n("Save settings"));
#endif
mainLayout->addMultiCellWidget(m_previewWidget, 0, 1, 0, 0);
mainLayout->addMultiCellWidget(m_decodingSettingsBox, 0, 0, 1, 1);
mainLayout->setColStretch(0, 10);
mainLayout->setRowStretch(1, 10);
// ---------------------------------------------------------------
// About data and help button.
m_about = new KIPIPlugins::KPAboutData(I18N_NOOP("RAW Image Converter"),
0,
TDEAboutData::License_GPL,
I18N_NOOP("A Kipi plugin to convert a Raw image"),
"(c) 2003-2005, Renchi Raju\n"
"(c) 2006-2008, Gilles Caulier");
m_about->addAuthor("Renchi Raju", I18N_NOOP("Original author"),
"renchi at pooh dot tam dot uiuc dot edu");
m_about->addAuthor("Gilles Caulier", I18N_NOOP("Maintainer"),
"caulier dot gilles at gmail dot com");
KHelpMenu* helpMenu = new KHelpMenu(this, m_about, false);
helpMenu->menu()->removeItemAt(0);
helpMenu->menu()->insertItem(i18n("Plugin Handbook"), this, TQ_SLOT(slotHelp()), 0, -1, 0);
actionButton(Help)->setPopup( helpMenu->menu() );
// ---------------------------------------------------------------
setButtonTip( User1, i18n("<p>Generate a Preview from current settings. "
"Uses a simple bilinear interpolation for "
"quick results."));
setButtonTip( User2, i18n("<p>Convert the Raw Image from current settings. "
"This uses a high-quality adaptive algorithm."));
setButtonTip( User3, i18n("<p>Abort the current Raw file conversion"));
setButtonTip( Close, i18n("<p>Exit Raw Converter"));
m_blinkPreviewTimer = new TQTimer(this);
m_blinkConvertTimer = new TQTimer(this);
m_thread = new ActionThread(this);
// ---------------------------------------------------------------
connect(m_blinkPreviewTimer, TQ_SIGNAL(timeout()),
this, TQ_SLOT(slotPreviewBlinkTimerDone()));
connect(m_blinkConvertTimer, TQ_SIGNAL(timeout()),
this, TQ_SLOT(slotConvertBlinkTimerDone()));
// ---------------------------------------------------------------
busy(false);
readSettings();
TQTimer::singleShot(0, this, TQ_SLOT( slotIdentify() ) );
}
SingleDialog::~SingleDialog()
{
delete m_about;
delete m_thread;
}
void SingleDialog::closeEvent(TQCloseEvent *e)
{
if (!e) return;
m_blinkPreviewTimer->stop();
m_blinkConvertTimer->stop();
m_thread->cancel();
saveSettings();
e->accept();
}
void SingleDialog::slotClose()
{
m_blinkPreviewTimer->stop();
m_blinkConvertTimer->stop();
m_thread->cancel();
saveSettings();
KDialogBase::slotClose();
}
void SingleDialog::slotDefault()
{
m_decodingSettingsBox->setDefaultSettings();
m_saveSettingsBox->setDefaultSettings();
}
void SingleDialog::readSettings()
{
TDEConfig config("kipirc");
config.setGroup("RawConverter Settings");
m_decodingSettingsBox->setWhiteBalance((KDcrawIface::RawDecodingSettings::WhiteBalance)
config.readNumEntry("White Balance",
KDcrawIface::RawDecodingSettings::CAMERA));
m_decodingSettingsBox->setCustomWhiteBalance(config.readNumEntry("Custom White Balance", 6500));
m_decodingSettingsBox->setCustomWhiteBalanceGreen(config.readDoubleNumEntry("Custom White Balance Green", 1.0));
m_decodingSettingsBox->setFourColor(config.readBoolEntry("Four Color RGB", false));
m_decodingSettingsBox->setUnclipColor(config.readNumEntry("Unclip Color", 0));
m_decodingSettingsBox->setDontStretchPixels(config.readBoolEntry("Dont Stretch Pixels", false));
m_decodingSettingsBox->setNoiseReduction(config.readBoolEntry("Use Noise Reduction", false));
m_decodingSettingsBox->setBrightness(config.readDoubleNumEntry("Brightness Multiplier", 1.0));
m_decodingSettingsBox->setUseBlackPoint(config.readBoolEntry("Use Black Point", false));
m_decodingSettingsBox->setBlackPoint(config.readNumEntry("Black Point", 0));
#if KDCRAW_VERSION >= 0x000105
m_decodingSettingsBox->setUseWhitePoint(config.readBoolEntry("Use White Point", false));
m_decodingSettingsBox->setWhitePoint(config.readNumEntry("White Point", 0));
m_decodingSettingsBox->setMedianFilterPasses(config.readNumEntry("Median Filter Passes", 0));
#endif
m_decodingSettingsBox->setNRThreshold(config.readNumEntry("NR Threshold", 100));
m_decodingSettingsBox->setUseCACorrection(config.readBoolEntry("EnableCACorrection", false));
m_decodingSettingsBox->setcaRedMultiplier(config.readDoubleNumEntry("caRedMultiplier", 1.0));
m_decodingSettingsBox->setcaBlueMultiplier(config.readDoubleNumEntry("caBlueMultiplier", 1.0));
m_decodingSettingsBox->setQuality(
(KDcrawIface::RawDecodingSettings::DecodingQuality)config.readNumEntry("Decoding Quality",
(int)(KDcrawIface::RawDecodingSettings::BILINEAR)));
m_decodingSettingsBox->setOutputColorSpace(
(KDcrawIface::RawDecodingSettings::OutputColorSpace)config.readNumEntry("Output Color Space",
(int)(KDcrawIface::RawDecodingSettings::SRGB)));
m_saveSettingsBox->setFileFormat(
(SaveSettingsWidget::OutputFormat)config.readNumEntry("Output Format",
(int)(SaveSettingsWidget::OUTPUT_PNG)));
m_saveSettingsBox->setConflictRule(
(SaveSettingsWidget::ConflictRule)config.readNumEntry("Conflict",
(int)(SaveSettingsWidget::OVERWRITE)));
resize(configDialogSize(config, TQString("Single Raw Converter Dialog")));
}
void SingleDialog::saveSettings()
{
TDEConfig config("kipirc");
config.setGroup("RawConverter Settings");
config.writeEntry("White Balance", m_decodingSettingsBox->whiteBalance());
config.writeEntry("Custom White Balance", m_decodingSettingsBox->customWhiteBalance());
config.writeEntry("Custom White Balance Green", m_decodingSettingsBox->customWhiteBalanceGreen());
config.writeEntry("Four Color RGB", m_decodingSettingsBox->useFourColor());
config.writeEntry("Unclip Color", m_decodingSettingsBox->unclipColor());
config.writeEntry("Dont Stretch Pixels", m_decodingSettingsBox->useDontStretchPixels());
config.writeEntry("Use Noise Reduction", m_decodingSettingsBox->useNoiseReduction());
config.writeEntry("Brightness Multiplier", m_decodingSettingsBox->brightness());
config.writeEntry("Use Black Point", m_decodingSettingsBox->useBlackPoint());
config.writeEntry("Black Point", m_decodingSettingsBox->blackPoint());
#if KDCRAW_VERSION >= 0x000105
config.writeEntry("Use White Point", m_decodingSettingsBox->useWhitePoint());
config.writeEntry("White Point", m_decodingSettingsBox->whitePoint());
config.writeEntry("Median Filter Passes", m_decodingSettingsBox->medianFilterPasses());
#endif
config.writeEntry("NR Threshold", m_decodingSettingsBox->NRThreshold());
config.writeEntry("EnableCACorrection", m_decodingSettingsBox->useCACorrection());
config.writeEntry("caRedMultiplier", m_decodingSettingsBox->caRedMultiplier());
config.writeEntry("caBlueMultiplier", m_decodingSettingsBox->caBlueMultiplier());
config.writeEntry("Decoding Quality", (int)m_decodingSettingsBox->quality());
config.writeEntry("Output Color Space", (int)m_decodingSettingsBox->outputColorSpace());
config.writeEntry("Output Format", (int)m_saveSettingsBox->fileFormat());
config.writeEntry("Conflict", (int)m_saveSettingsBox->conflictRule());
saveDialogSize(config, TQString("Single Raw Converter Dialog"));
config.sync();
}
void SingleDialog::slotHelp()
{
TDEApplication::kApplication()->invokeHelp("rawconverter", "kipi-plugins");
}
// 'Preview' dialog button.
void SingleDialog::slotUser1()
{
KDcrawIface::RawDecodingSettings rawDecodingSettings;
rawDecodingSettings.whiteBalance = m_decodingSettingsBox->whiteBalance();
rawDecodingSettings.customWhiteBalance = m_decodingSettingsBox->customWhiteBalance();
rawDecodingSettings.customWhiteBalanceGreen = m_decodingSettingsBox->customWhiteBalanceGreen();
rawDecodingSettings.RGBInterpolate4Colors = m_decodingSettingsBox->useFourColor();
rawDecodingSettings.unclipColors = m_decodingSettingsBox->unclipColor();
rawDecodingSettings.DontStretchPixels = m_decodingSettingsBox->useDontStretchPixels();
rawDecodingSettings.enableNoiseReduction = m_decodingSettingsBox->useNoiseReduction();
rawDecodingSettings.brightness = m_decodingSettingsBox->brightness();
rawDecodingSettings.enableBlackPoint = m_decodingSettingsBox->useBlackPoint();
rawDecodingSettings.blackPoint = m_decodingSettingsBox->blackPoint();
#if KDCRAW_VERSION >= 0x000105
rawDecodingSettings.enableWhitePoint = m_decodingSettingsBox->useWhitePoint();
rawDecodingSettings.whitePoint = m_decodingSettingsBox->whitePoint();
rawDecodingSettings.medianFilterPasses = m_decodingSettingsBox->medianFilterPasses();
#endif
rawDecodingSettings.NRThreshold = m_decodingSettingsBox->NRThreshold();
rawDecodingSettings.enableCACorrection = m_decodingSettingsBox->useCACorrection();
rawDecodingSettings.caMultiplier[0] = m_decodingSettingsBox->caRedMultiplier();
rawDecodingSettings.caMultiplier[1] = m_decodingSettingsBox->caBlueMultiplier();
rawDecodingSettings.RAWQuality = m_decodingSettingsBox->quality();
rawDecodingSettings.outputColorSpace = m_decodingSettingsBox->outputColorSpace();
m_thread->setRawDecodingSettings(rawDecodingSettings, SaveSettingsWidget::OUTPUT_PPM);
m_thread->processHalfRawFile(KURL(m_inputFile));
if (!m_thread->running())
m_thread->start();
}
// 'Convert' dialog button.
void SingleDialog::slotUser2()
{
KDcrawIface::RawDecodingSettings rawDecodingSettings;
rawDecodingSettings.whiteBalance = m_decodingSettingsBox->whiteBalance();
rawDecodingSettings.customWhiteBalance = m_decodingSettingsBox->customWhiteBalance();
rawDecodingSettings.customWhiteBalanceGreen = m_decodingSettingsBox->customWhiteBalanceGreen();
rawDecodingSettings.RGBInterpolate4Colors = m_decodingSettingsBox->useFourColor();
rawDecodingSettings.unclipColors = m_decodingSettingsBox->unclipColor();
rawDecodingSettings.DontStretchPixels = m_decodingSettingsBox->useDontStretchPixels();
rawDecodingSettings.enableNoiseReduction = m_decodingSettingsBox->useNoiseReduction();
rawDecodingSettings.brightness = m_decodingSettingsBox->brightness();
rawDecodingSettings.enableBlackPoint = m_decodingSettingsBox->useBlackPoint();
rawDecodingSettings.blackPoint = m_decodingSettingsBox->blackPoint();
#if KDCRAW_VERSION >= 0x000105
rawDecodingSettings.enableWhitePoint = m_decodingSettingsBox->useWhitePoint();
rawDecodingSettings.whitePoint = m_decodingSettingsBox->whitePoint();
rawDecodingSettings.medianFilterPasses = m_decodingSettingsBox->medianFilterPasses();
#endif
rawDecodingSettings.NRThreshold = m_decodingSettingsBox->NRThreshold();
rawDecodingSettings.enableCACorrection = m_decodingSettingsBox->useCACorrection();
rawDecodingSettings.caMultiplier[0] = m_decodingSettingsBox->caRedMultiplier();
rawDecodingSettings.caMultiplier[1] = m_decodingSettingsBox->caBlueMultiplier();
rawDecodingSettings.RAWQuality = m_decodingSettingsBox->quality();
rawDecodingSettings.outputColorSpace = m_decodingSettingsBox->outputColorSpace();
m_thread->setRawDecodingSettings(rawDecodingSettings, m_saveSettingsBox->fileFormat());
m_thread->processRawFile(KURL(m_inputFile));
if (!m_thread->running())
m_thread->start();
}
// 'Abort' dialog button.
void SingleDialog::slotUser3()
{
m_thread->cancel();
}
void SingleDialog::slotIdentify()
{
m_thread->identifyRawFile(KURL(m_inputFile), true);
if (!m_thread->running())
m_thread->start();
}
void SingleDialog::busy(bool val)
{
m_decodingSettingsBox->setEnabled(!val);
m_saveSettingsBox->setEnabled(!val);
enableButton (User1, !val);
enableButton (User2, !val);
enableButton (User3, val);
enableButton (Close, !val);
}
void SingleDialog::identified(const TQString&, const TQString& identity, const TQPixmap& preview)
{
m_previewWidget->setInfo(m_inputFileName + TQString(" :\n") + identity, TQt::white, preview);
}
void SingleDialog::previewing(const TQString&)
{
m_previewBlink = false;
m_previewWidget->setCursor( KCursor::waitCursor() );
m_blinkPreviewTimer->start(200);
}
void SingleDialog::previewed(const TQString&, const TQString& tmpFile)
{
m_previewWidget->unsetCursor();
m_blinkPreviewTimer->stop();
m_previewWidget->load(tmpFile);
::remove(TQFile::encodeName(tmpFile));
}
void SingleDialog::previewFailed(const TQString&)
{
m_previewWidget->unsetCursor();
m_blinkPreviewTimer->stop();
m_previewWidget->setInfo(i18n("Failed to generate preview"), TQt::red);
}
void SingleDialog::processing(const TQString&)
{
m_convertBlink = false;
m_previewWidget->setCursor( KCursor::waitCursor() );
m_blinkConvertTimer->start(200);
}
void SingleDialog::processed(const TQString&, const TQString& tmpFile)
{
m_previewWidget->unsetCursor();
m_blinkConvertTimer->stop();
m_previewWidget->load(tmpFile);
TQString filter("*.");
TQString ext;
switch(m_saveSettingsBox->fileFormat())
{
case SaveSettingsWidget::OUTPUT_JPEG:
ext = "jpg";
break;
case SaveSettingsWidget::OUTPUT_TIFF:
ext = "tif";
break;
case SaveSettingsWidget::OUTPUT_PPM:
ext = "ppm";
break;
case SaveSettingsWidget::OUTPUT_PNG:
ext = "png";
break;
}
filter += ext;
TQFileInfo fi(m_inputFile);
TQString destFile = fi.dirPath(true) + TQString("/") + fi.baseName() + TQString(".") + ext;
if (m_saveSettingsBox->conflictRule() != SaveSettingsWidget::OVERWRITE)
{
struct stat statBuf;
if (::stat(TQFile::encodeName(destFile), &statBuf) == 0)
{
TDEIO::RenameDlg dlg(this, i18n("Save Raw Image converted from '%1' as").arg(fi.fileName()),
tmpFile, destFile,
TDEIO::RenameDlg_Mode(TDEIO::M_SINGLE | TDEIO::M_OVERWRITE | TDEIO::M_SKIP));
switch (dlg.exec())
{
case TDEIO::R_CANCEL:
case TDEIO::R_SKIP:
{
destFile = TQString();
break;
}
case TDEIO::R_RENAME:
{
destFile = dlg.newDestURL().path();
break;
}
default: // Overwrite.
break;
}
}
}
if (!destFile.isEmpty())
{
if (::rename(TQFile::encodeName(tmpFile), TQFile::encodeName(destFile)) != 0)
{
KMessageBox::error(this, i18n("Failed to save image %1").arg( destFile ));
}
}
}
void SingleDialog::processingFailed(const TQString&)
{
m_previewWidget->unsetCursor();
m_blinkConvertTimer->stop();
m_previewWidget->setInfo(i18n("Failed to convert Raw image"), TQt::red);
}
void SingleDialog::slotPreviewBlinkTimerDone()
{
TQString preview = i18n("Generating Preview...");
if (m_previewBlink)
m_previewWidget->setInfo(preview, TQt::green);
else
m_previewWidget->setInfo(preview, TQt::darkGreen);
m_previewBlink = !m_previewBlink;
m_blinkPreviewTimer->start(200);
}
void SingleDialog::slotConvertBlinkTimerDone()
{
TQString convert = i18n("Converting Raw Image...");
if (m_convertBlink)
m_previewWidget->setInfo(convert, TQt::green);
else
m_previewWidget->setInfo(convert, TQt::darkGreen);
m_convertBlink = !m_convertBlink;
m_blinkConvertTimer->start(200);
}
void SingleDialog::customEvent(TQCustomEvent *event)
{
if (!event) return;
EventData *d = (EventData*) event->data();
if (!d) return;
TQString text;
if (d->starting) // Something have been started...
{
switch (d->action)
{
case(IDENTIFY_FULL):
break;
case(PREVIEW):
{
busy(true);
previewing(d->filePath);
break;
}
case(PROCESS):
{
busy(true);
processing(d->filePath);
break;
}
default:
{
kdWarning( 51000 ) << "KIPIRawConverterPlugin: Unknown event" << endl;
break;
}
}
}
else
{
if (!d->success) // Something is failed...
{
switch (d->action)
{
case(IDENTIFY_FULL):
break;
case(PREVIEW):
{
previewFailed(d->filePath);
busy(false);
break;
}
case(PROCESS):
{
processingFailed(d->filePath);
busy(false);
break;
}
default:
{
kdWarning( 51000 ) << "KIPIRawConverterPlugin: Unknown event" << endl;
break;
}
}
}
else // Something is done...
{
switch (d->action)
{
case(IDENTIFY_FULL):
{
TQPixmap pix = TQPixmap(d->image.scale(256, 256, TQImage::ScaleMin));
identified(d->filePath, d->message, pix);
busy(false);
break;
}
case(PREVIEW):
{
previewed(d->filePath, d->destPath);
busy(false);
break;
}
case(PROCESS):
{
processed(d->filePath, d->destPath);
busy(false);
break;
}
default:
{
kdWarning( 51000 ) << "KIPIRawConverterPlugin: Unknown event" << endl;
break;
}
}
}
}
delete d;
}
} // NameSpace KIPIRawConverterPlugin