/* ============================================================ * * This file is a part of kipi-plugins project * http://www.kipi-plugins.org * * Date : 2003-10-24 * Description : Raw converter batch dialog * * Copyright (C) 2003-2005 by Renchi Raju * Copyright (C) 2006-2008 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. * * ============================================================ */ // C Ansi includes. extern "C" { #include #include #include } // C++ includes. #include // TQt includes. #include #include #include #include #include #include #include #include #include #include // KDE includes. #include #include #include #include #include #include #include #include #include #include #include #include #include #include // LibKDcraw includes. #include #include // Local includes. #include "kpaboutdata.h" #include "pluginsversion.h" #include "rawdecodingiface.h" #include "savesettingswidget.h" #include "actionthread.h" #include "clistviewitem.h" #include "batchdialog.h" #include "batchdialog.moc" namespace KIPIRawConverterPlugin { BatchDialog::BatchDialog(TQWidget* /*parent*/) : KDialogBase(0, 0, false, i18n("Raw Images Batch Converter"), Help|Default|User1|User2|Close, Close, true, i18n("Con&vert"), i18n("&Abort")) { m_currentConvertItem = 0; m_thread = 0; m_page = new TQWidget( this ); setMainWidget( m_page ); TQGridLayout *mainLayout = new TQGridLayout(m_page, 2, 1, 0, spacingHint()); //--------------------------------------------- m_listView = new TDEListView(m_page); m_listView->addColumn( i18n("Thumbnail") ); m_listView->addColumn( i18n("Raw File") ); m_listView->addColumn( i18n("Target File") ); m_listView->addColumn( i18n("Camera") ); m_listView->setResizeMode(TQListView::AllColumns); m_listView->setAllColumnsShowFocus(true); m_listView->setSorting(-1); m_listView->setSizePolicy(TQSizePolicy::Expanding, TQSizePolicy::Expanding); m_listView->setSelectionMode(TQListView::Single); m_listView->setMinimumWidth(450); // --------------------------------------------------------------- m_decodingSettingsBox = new KDcrawIface::DcrawSettingsWidget(m_page, false, true, true); m_saveSettingsBox = new SaveSettingsWidget(m_page); #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 m_progressBar = new KProgress(m_page); m_progressBar->setMaximumHeight( fontMetrics().height()+2 ); m_progressBar->hide(); mainLayout->addMultiCellWidget(m_listView, 0, 2, 0, 0); mainLayout->addMultiCellWidget(m_decodingSettingsBox, 0, 0, 1, 1); mainLayout->addMultiCellWidget(m_progressBar, 1, 1, 1, 1); mainLayout->setColStretch(0, 10); mainLayout->setRowStretch(2, 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 batch convert Raw images"), "(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("

Start converting the Raw images from current settings")); setButtonTip( User2, i18n("

Abort the current Raw files conversion")); setButtonTip( Close, i18n("

Exit Raw Converter")); m_blinkConvertTimer = new TQTimer(this); m_thread = new ActionThread(this); // --------------------------------------------------------------- connect(m_blinkConvertTimer, TQ_SIGNAL(timeout()), this, TQ_SLOT(slotConvertBlinkTimerDone())); connect(m_saveSettingsBox, TQ_SIGNAL(signalSaveFormatChanged()), this, TQ_SLOT(slotSaveFormatChanged())); // --------------------------------------------------------------- m_itemDict.setAutoDelete(true); busy(false); readSettings(); } BatchDialog::~BatchDialog() { delete m_about; delete m_thread; } void BatchDialog::closeEvent(TQCloseEvent *e) { if (!e) return; m_blinkConvertTimer->stop(); m_thread->cancel(); saveSettings(); e->accept(); } void BatchDialog::slotClose() { m_blinkConvertTimer->stop(); m_thread->cancel(); saveSettings(); KDialogBase::slotClose(); } void BatchDialog::slotDefault() { m_decodingSettingsBox->setDefaultSettings(); m_saveSettingsBox->setDefaultSettings(); } void BatchDialog::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("Batch Raw Converter Dialog"))); } void BatchDialog::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("Batch Raw Converter Dialog")); config.sync(); } void BatchDialog::slotHelp() { TDEApplication::kApplication()->invokeHelp("rawconverter", "kipi-plugins"); } void BatchDialog::slotUser1() { m_fileList.clear(); TQListViewItemIterator it( m_listView ); while ( it.current() ) { CListViewItem *item = (CListViewItem*) it.current(); if (item->isEnabled()) { item->setPixmap(1, 0); m_fileList.append(item->rawItem->directory + TQString("/") + item->rawItem->src); } ++it; } if (m_fileList.empty()) { KMessageBox::error(this, i18n("There is no Raw file to process in the list!")); busy(false); slotAborted(); return; } m_progressBar->setTotalSteps(m_fileList.count()); m_progressBar->setProgress(0); m_progressBar->show(); 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()); processOne(); } void BatchDialog::slotUser2() { m_blinkConvertTimer->stop(); m_fileList.clear(); m_thread->cancel(); busy(false); if (m_currentConvertItem) m_currentConvertItem->viewItem->setPixmap(1, SmallIcon("cancel")); TQTimer::singleShot(500, this, TQ_SLOT(slotAborted())); } void BatchDialog::slotAborted() { m_progressBar->setProgress(0); m_progressBar->hide(); } void BatchDialog::addItems(const TQStringList& itemList) { 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; } KURL::List urlList; TQPixmap pix(SmallIcon( "file_broken", TDEIcon::SizeLarge, TDEIcon::DisabledState )); for (TQStringList::const_iterator it = itemList.begin(); it != itemList.end(); ++it) { TQFileInfo fi(*it); if (fi.exists() && !m_itemDict.find(fi.fileName())) { RawItem *item = new RawItem; item->directory = fi.dirPath(); item->src = fi.fileName(); item->dest = fi.baseName() + TQString(".") + ext; new CListViewItem(m_listView, pix, item, m_listView->lastItem()); m_itemDict.insert(item->src, item); urlList.append(fi.absFilePath()); } } if (!urlList.empty()) { m_thread->identifyRawFiles(urlList); if (!m_thread->running()) m_thread->start(); } } void BatchDialog::slotSaveFormatChanged() { 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; } TQListViewItemIterator it( m_listView ); while ( it.current() ) { CListViewItem *item = (CListViewItem*) it.current(); if (item->isEnabled()) { RawItem *rawItem = item->rawItem; TQFileInfo fi(rawItem->directory + TQString("/") + rawItem->src); rawItem->dest = fi.baseName() + TQString(".") + ext; item->setText(2, rawItem->dest); } ++it; } } void BatchDialog::processOne() { if (m_fileList.empty()) { busy(false); slotAborted(); return; } TQString file(m_fileList.first()); m_fileList.pop_front(); m_thread->processRawFile(KURL(file)); if (!m_thread->running()) m_thread->start(); } void BatchDialog::busy(bool busy) { enableButton(User1, !busy); enableButton(User2, busy); enableButton(Close, !busy); m_decodingSettingsBox->setEnabled(!busy); m_saveSettingsBox->setEnabled(!busy); m_listView->setEnabled(!busy); busy ? m_page->setCursor(KCursor::waitCursor()) : m_page->unsetCursor(); } void BatchDialog::slotConvertBlinkTimerDone() { if(m_convertBlink) { if (m_currentConvertItem) m_currentConvertItem->viewItem->setPixmap(1, SmallIcon("1rightarrow")); } else { if (m_currentConvertItem) m_currentConvertItem->viewItem->setPixmap(1, SmallIcon("2rightarrow")); } m_convertBlink = !m_convertBlink; m_blinkConvertTimer->start(500); } void BatchDialog::processing(const TQString& file) { TQString filename = TQFileInfo(file).fileName(); m_currentConvertItem = m_itemDict.find(filename); if (m_currentConvertItem) { m_listView->setSelected(m_currentConvertItem->viewItem, true); m_listView->ensureItemVisible(m_currentConvertItem->viewItem); } m_convertBlink = false; m_blinkConvertTimer->start(500); } void BatchDialog::processed(const TQString& file, const TQString& tmpFile) { m_blinkConvertTimer->stop(); TQString filename = TQFileInfo(file).fileName(); TQString destFile(m_currentConvertItem->directory + TQString("/") + m_currentConvertItem->dest); 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(m_currentConvertItem->src), 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(); m_currentConvertItem->viewItem->setPixmap(1, SmallIcon("cancel")); 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 )); m_currentConvertItem->viewItem->setPixmap(1, SmallIcon("cancel")); } else { m_currentConvertItem->dest = TQFileInfo(destFile).fileName(); m_currentConvertItem->viewItem->setText(2, m_currentConvertItem->dest); m_currentConvertItem->viewItem->setPixmap(1, SmallIcon("ok")); } } m_progressBar->advance(1); m_currentConvertItem = 0; } void BatchDialog::processingFailed(const TQString& file) { TQString filename = TQFileInfo(file).fileName(); m_currentConvertItem->viewItem->setPixmap(1, SmallIcon("no")); m_progressBar->advance(1); m_currentConvertItem = 0; } void BatchDialog::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): 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): break; case(PROCESS): { processingFailed(d->filePath); processOne(); break; } default: { kdWarning( 51000 ) << "KIPIRawConverterPlugin: Unknown event" << endl; break; } } } else // Something is done... { switch (d->action) { case(IDENTIFY): { TQFileInfo fi(d->filePath); RawItem *rawItem = m_itemDict.find(fi.fileName()); if (rawItem) { if (!d->image.isNull()) { TQPixmap pix = TQPixmap(d->image.scale(64, 64, TQImage::ScaleMin)); rawItem->viewItem->setThumbnail(pix); } rawItem->viewItem->setText(3, d->message); rawItem->identity = d->message; } break; } case(PROCESS): { processed(d->filePath, d->destPath); processOne(); break; } default: { kdWarning( 51000 ) << "KIPIRawConverterPlugin: Unknown event" << endl; break; } } } } delete d; } } // NameSpace KIPIRawConverterPlugin