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/batchprocessimages/batchprocessimagesdialog.cpp

1093 lines
36 KiB

/* ============================================================
*
* This file is a part of kipi-plugins project
* http://www.kipi-plugins.org
*
* Date : 2004-10-01
* Description : a kipi plugin to batch process images
*
* Copyright (C) 2004-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 <unistd.h>
}
// Include files for TQt
#include <tqvbox.h>
#include <tqlayout.h>
#include <tqdir.h>
#include <tqwidget.h>
#include <tqlabel.h>
#include <tqgroupbox.h>
#include <tqwhatsthis.h>
#include <tqcombobox.h>
#include <tqcheckbox.h>
#include <tqprocess.h>
#include <tqcolor.h>
#include <tqpainter.h>
#include <tqpalette.h>
#include <tqimage.h>
#include <tqevent.h>
#include <tqdragobject.h>
#include <tqfileinfo.h>
#include <tqhgroupbox.h>
#include <tqvgroupbox.h>
#include <tqframe.h>
#include <tqwmatrix.h>
// Include files for KDE
#include <kstandarddirs.h>
#include <kcolorbutton.h>
#include <tdelocale.h>
#include <kprogress.h>
#include <tdefiledialog.h>
#include <kiconloader.h>
#include <tdemessagebox.h>
#include <knuminput.h>
#include <kinstance.h>
#include <tdeconfig.h>
#include <tdeapplication.h>
#include <kdebug.h>
#include <kdialogbase.h>
#include <tdelistview.h>
#include <kimageio.h>
#include <kprocess.h>
#include <klineeditdlg.h>
#include <tdeio/jobclasses.h>
#include <tdeio/netaccess.h>
#include <tdeio/global.h>
#include <tdeio/previewjob.h>
#include <kbuttonbox.h>
#include <tdediroperator.h>
#include <tdeversion.h>
#include <kurlrequester.h>
#include <klineedit.h>
// KIPI includes
#include <libkipi/uploadwidget.h>
#include <libkipi/imagedialog.h>
// Local includes
#include "pluginsversion.h"
#include "outputdialog.h"
#include "imagepreview.h"
#include "batchprocessimagesdialog.h"
#include "batchprocessimagesdialog.moc"
namespace KIPIBatchProcessImagesPlugin
{
BatchProcessImagesDialog::BatchProcessImagesDialog( KURL::List urlList, KIPI::Interface* interface,
TQString caption, TQWidget *parent )
: KDialogBase( KDialogBase::Plain, caption, Help|User1|Cancel,
Cancel, parent, "BatchProcessImagesDialog", false, false, i18n("&Start")),
m_selectedImageFiles( urlList), m_interface( interface )
{
// Init. Tmp folder
TDEStandardDirs dir;
m_tmpFolder = dir.saveLocation("tmp", "kipi-batchprocessimagesplugin-" +
TQString::number(getpid()) );
m_convertStatus = NO_PROCESS;
m_progressStatus = 0;
m_ProcessusProc = 0;
m_PreviewProc = 0;
KImageIO::registerFormats();
TQWidget* box = plainPage();
TQVBoxLayout *dvlay = new TQVBoxLayout(box, 0, KDialog::spacingHint());
//---------------------------------------------
TQHBoxLayout *hlay = new TQHBoxLayout( dvlay );
groupBox1 = new TQGroupBox( 0, TQt::Vertical, box );
groupBox1->layout()->setSpacing(KDialog::spacingHint());
groupBox1->layout()->setMargin(KDialog::marginHint());
TQGridLayout* grid = new TQGridLayout( groupBox1->layout(), 2, 3);
m_labelType = new TQLabel( groupBox1 );
grid->addMultiCellWidget(m_labelType, 0, 0, 0, 0);
m_Type = new TQComboBox(false, groupBox1);
grid->addMultiCellWidget(m_Type, 0, 0, 1, 1);
m_optionsButton = new TQPushButton (groupBox1, "OptionButton");
m_optionsButton->setText(i18n("Options"));
TQWhatsThis::add( m_optionsButton, i18n("<p>You can choose here the options to use "
"for the current process."));
grid->addMultiCellWidget(m_optionsButton, 0, 0, 2, 2);
m_smallPreview = new TQCheckBox(i18n("Small preview"), groupBox1);
TQWhatsThis::add( m_smallPreview, i18n("<p>If you enable this option, "
"all preview effects will be calculated on a small zone "
"of the image (300x300 pixels in the top left corner). "
"Enable this option if you have a slow computer.") );
m_smallPreview->setChecked( true );
grid->addMultiCellWidget(m_smallPreview, 1, 1, 0, 1);
m_previewButton = new TQPushButton (groupBox1, "PreviewButton");
m_previewButton->setText(i18n("&Preview"));
TQWhatsThis::add( m_previewButton, i18n("<p>This button builds a process "
"preview for the currently selected image on the list."));
grid->addMultiCellWidget(m_previewButton, 1, 1, 2, 2);
hlay->addWidget( groupBox1 );
//---------------------------------------------
groupBox2 = new TQGroupBox( 2, TQt::Horizontal, i18n("File Operations"), box );
m_labelOverWrite = new TQLabel (i18n("Overwrite mode:"), groupBox2);
m_overWriteMode = new TQComboBox( false, groupBox2 );
m_overWriteMode->insertItem(i18n("Ask"));
m_overWriteMode->insertItem(i18n("Always Overwrite"));
m_overWriteMode->insertItem(i18n("Rename"));
m_overWriteMode->insertItem(i18n("Skip"));
m_overWriteMode->setCurrentText (i18n("Rename"));
TQWhatsThis::add( m_overWriteMode, i18n("<p>Select here the overwrite mode used if your target's image "
"files already exist.") );
m_removeOriginal = new TQCheckBox(i18n("Remove original"), groupBox2);
TQWhatsThis::add( m_removeOriginal, i18n("<p>If you enable this option, "
"all original image files will be removed after processing.") );
m_removeOriginal->setChecked( false );
hlay->addWidget( groupBox2 );
//---------------------------------------------
groupBox3 = new TQHGroupBox( i18n("Target Folder"), box );
m_destinationURL = new KURLRequester(groupBox3);
m_destinationURL->setMode(KFile::Directory | KFile::LocalOnly);
KIPI::ImageCollection album = interface->currentAlbum();
if (album.isValid())
{
TQString url;
if (album.isDirectory())
{
url = album.uploadPath().path();
}
else
{
url = TQDir::homeDirPath();
}
m_destinationURL->lineEdit()->setText(url);
}
TQWhatsThis::add( m_destinationURL, i18n("<p>Here you can select the target folder which "
"will used by the process."));
dvlay->addWidget( groupBox3 );
//---------------------------------------------
groupBox4 = new TQHGroupBox( box );
TQWidget* box41 = new TQWidget( groupBox4 );
TQHBoxLayout* lay2 = new TQHBoxLayout( box41, 0, spacingHint() );
m_listFiles = new BatchProcessImagesList( box41 );
lay2->addWidget( m_listFiles );
m_listFiles->setSizePolicy(TQSizePolicy::Expanding, TQSizePolicy::MinimumExpanding);
TQVBoxLayout* lay3 = new TQVBoxLayout( lay2 );
m_addImagesButton = new TQPushButton ( i18n( "&Add..." ), box41 );
lay3->addWidget( m_addImagesButton );
TQWhatsThis::add( m_addImagesButton, i18n("<p>Add images to the list.") );
m_remImagesButton = new TQPushButton ( i18n( "&Remove" ), box41 );
lay3->addWidget( m_remImagesButton );
TQWhatsThis::add( m_remImagesButton, i18n("<p>Remove selected image from the list.") );
m_imageLabel = new TQLabel( box41 );
m_imageLabel->setFixedHeight( 80 );
m_imageLabel->setAlignment( TQt::AlignHCenter | TQt::AlignVCenter );
m_imageLabel->setSizePolicy( TQSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Preferred ) );
lay3->addWidget( m_imageLabel );
TQWhatsThis::add( m_imageLabel, i18n( "<p>The preview of the selected image on the list." ) );
lay3->addStretch( 1 );
dvlay->addWidget( groupBox4 );
//---------------------------------------------
m_progress = new KProgress( box, "Progress" );
m_progress->setTotalSteps(100);
m_progress->setValue(0);
TQWhatsThis::add( m_progress, i18n("<p>This is the current percentage of the task completed.") );
dvlay->addWidget( m_progress );
//---------------------------------------------
connect(m_listFiles, TQT_SIGNAL(doubleClicked(TQListViewItem *)),
this, TQT_SLOT(slotListDoubleClicked(TQListViewItem *)));
connect(this, TQT_SIGNAL(user1Clicked()),
this, TQT_SLOT(slotProcessStart()));
connect(m_optionsButton, TQT_SIGNAL(clicked()),
this, TQT_SLOT(slotOptionsClicked()));
connect(m_previewButton, TQT_SIGNAL(clicked()),
this, TQT_SLOT(slotPreview()));
connect(m_Type, TQT_SIGNAL(activated(int)),
this, TQT_SLOT(slotTypeChanged(int)));
connect(m_listFiles, TQT_SIGNAL( addedDropItems(TQStringList) ),
this, TQT_SLOT( slotAddDropItems(TQStringList)));
connect(m_listFiles, TQT_SIGNAL( currentChanged( TQListViewItem * ) ),
this, TQT_SLOT( slotImageSelected( TQListViewItem * )));
connect(m_addImagesButton, TQT_SIGNAL(clicked()),
this, TQT_SLOT(slotImagesFilesButtonAdd()));
connect(m_remImagesButton, TQT_SIGNAL(clicked()),
this, TQT_SLOT(slotImagesFilesButtonRem()));
// Get the image files filters from the hosts app.
m_ImagesFilesSort = m_interface->fileExtensions();
dvlay->activate();
}
BatchProcessImagesDialog::~BatchProcessImagesDialog()
{
}
void BatchProcessImagesDialog::slotImagesFilesButtonAdd( void )
{
TQStringList ImageFilesList;
KURL::List urls = KIPI::ImageDialog::getImageURLs( this, m_interface );
for ( KURL::List::Iterator it = urls.begin() ; it != urls.end() ; ++it )
ImageFilesList << (*it).path(); // PENDING(blackie) handle remote URLS
if ( urls.isEmpty() ) return;
slotAddDropItems(ImageFilesList);
}
void BatchProcessImagesDialog::slotImagesFilesButtonRem( void )
{
BatchProcessImagesItem *pitem = static_cast<BatchProcessImagesItem*>( m_listFiles->currentItem() );
if ( pitem )
{
m_listFiles->takeItem(pitem);
m_listFiles->setSelected( m_listFiles->currentItem(), true );
m_selectedImageFiles.remove(m_selectedImageFiles.find(pitem->pathSrc()));
delete pitem;
m_nbItem = m_selectedImageFiles.count();
if (m_nbItem == 0)
groupBox4->setTitle(i18n("Image Files List"));
else
groupBox4->setTitle(i18n("Image File List (1 item)", "Image File List (%n items)", m_nbItem));
}
}
void BatchProcessImagesDialog::slotImageSelected( TQListViewItem * item )
{
if ( !item || m_listFiles->childCount() == 0 )
{
m_imageLabel->clear();
return;
}
BatchProcessImagesItem *pitem = static_cast<BatchProcessImagesItem*>( item );
if ( !pitem ) return;
m_imageLabel->clear();
TQString IdemIndexed = "file:" + pitem->pathSrc();
KURL url(IdemIndexed);
TDEIO::PreviewJob* m_thumbJob = TDEIO::filePreview( url, m_imageLabel->height() );
connect(m_thumbJob, TQT_SIGNAL(gotPreview(const KFileItem*, const TQPixmap&)),
this, TQT_SLOT(slotGotPreview(const KFileItem*, const TQPixmap&)));
}
void BatchProcessImagesDialog::slotGotPreview(const KFileItem* url, const TQPixmap &pixmap)
{
TQPixmap pix( pixmap );
// Rotate the thumbnail compared to the angle the host application dictate
KIPI::ImageInfo info = m_interface->info( url->url() );
if ( info.angle() != 0 )
{
TQImage img = pix.convertToImage();
TQWMatrix matrix;
matrix.rotate( info.angle() );
img = img.xForm( matrix );
pix.convertFromImage( img );
}
m_imageLabel->setPixmap(pix);
}
void BatchProcessImagesDialog::slotAddDropItems(TQStringList filesPath)
{
if (filesPath.isEmpty()) return;
for ( TQStringList::Iterator it = filesPath.begin() ; it != filesPath.end() ; ++it )
{
TQString currentDropFile = *it;
// Check if the new item already exist in the list.
bool findItem = false;
for ( KURL::List::Iterator it2 = m_selectedImageFiles.begin() ; it2 != m_selectedImageFiles.end() ; ++it2 )
{
TQString currentFile = (*it2).path(); // PENDING(blackie) Handle URL's
if ( currentFile == currentDropFile )
findItem = true;
}
if (findItem == false)
m_selectedImageFiles.append(currentDropFile);
}
listImageFiles();
}
void BatchProcessImagesDialog::closeEvent ( TQCloseEvent *e )
{
if (!e) return;
if ( m_PreviewProc != 0 )
if ( m_PreviewProc->isRunning() ) m_PreviewProc->kill(SIGTERM);
if ( m_ProcessusProc != 0 )
if ( m_ProcessusProc->isRunning() ) m_ProcessusProc->kill(SIGTERM);
e->accept();
}
void BatchProcessImagesDialog::slotProcessStart( void )
{
if ( m_selectedImageFiles.isEmpty() == true )
return;
if ( m_removeOriginal->isChecked() == true )
{
if ( KMessageBox::warningContinueCancel(this,
i18n("All original image files will be removed from the source Album.\nDo you want to continue?"),
i18n("Delete Original Image Files"), KStdGuiItem::cont(),
"KIPIplugin-BatchProcessImages-AlwaysRemomveOriginalFiles") != KMessageBox::Continue )
return;
}
m_convertStatus = UNDER_PROCESS;
disconnect( this, TQT_SIGNAL(user1Clicked()), this, TQT_SLOT(slotProcessStart()));
showButtonCancel( false );
setButtonText( User1, i18n("&Stop") );
connect(this, TQT_SIGNAL(user1Clicked()), this, TQT_SLOT(slotProcessStop()));
m_labelType->setEnabled(false);
m_Type->setEnabled(false);
m_optionsButton->setEnabled(false);
m_previewButton->setEnabled(false);
m_smallPreview->setEnabled(false);
m_labelOverWrite->setEnabled(false);
m_overWriteMode->setEnabled(false);
m_removeOriginal->setEnabled(false);
m_destinationURL->setEnabled(false);
m_addImagesButton->setEnabled(false);
m_remImagesButton->setEnabled(false);
m_listFile2Process_iterator = new TQListViewItemIterator( m_listFiles );
startProcess();
}
bool BatchProcessImagesDialog::startProcess(void)
{
if ( m_convertStatus == STOP_PROCESS )
{
endProcess();
return true;
}
TQString targetAlbum = m_destinationURL->url();
//TODO check if it is valid also for remote URL's
// this is a workarond for bug 117397
TQFileInfo dirInfo(targetAlbum + "/");
if (!dirInfo.isDir () || !dirInfo.isWritable())
{
KMessageBox::error(this, i18n("You must specify a writable path for your output file."));
endProcess();
return true;
}
BatchProcessImagesItem *item = static_cast<BatchProcessImagesItem*>( m_listFile2Process_iterator->current() );
m_listFiles->setCurrentItem(item);
if ( prepareStartProcess(item, targetAlbum) == false ) // If there is a problem during the
{ // preparation -> pass to the next item!
++*m_listFile2Process_iterator;
++m_progressStatus;
m_progress->setValue((int)((float)m_progressStatus *(float)100 / (float)m_nbItem));
item = static_cast<BatchProcessImagesItem*>( m_listFile2Process_iterator->current() );
m_listFiles->setCurrentItem(item);
if ( m_listFile2Process_iterator->current() )
{
startProcess();
return true;
}
else
{
endProcess();
return true;
}
}
KURL desturl(targetAlbum + "/" + item->nameDest());
#if TDE_VERSION >= 0x30200
if ( TDEIO::NetAccess::exists( desturl, false, TQT_TQWIDGET(kapp->activeWindow()) ) == true )
#else
if ( TDEIO::NetAccess::exists( desturl ) == true )
#endif
{
switch (overwriteMode())
{
case OVERWRITE_ASK:
{
int ValRet = KMessageBox::warningYesNoCancel(this,
i18n("The destination file \"%1\" already exists;\n"
"do you want overwrite it?").arg(item->nameDest()),
i18n("Overwrite Destination Image File"), KStdGuiItem::cont());
if ( ValRet == KMessageBox::No )
{
item->changeResult(i18n("Skipped."));
item->changeError(i18n("destination image file already exists (skipped by user)."));
++*m_listFile2Process_iterator;
++m_progressStatus;
m_progress->setValue((int)((float)m_progressStatus *(float)100 / (float)m_nbItem));
if ( m_listFile2Process_iterator->current() )
{
startProcess();
return true;
}
else
{
endProcess();
return true;
}
}
else if ( ValRet == KMessageBox::Cancel )
{
processAborted(false);
return false;
}
else
{
item->setDidOverWrite( true );
}
break;
}
case OVERWRITE_RENAME:
{
TQFileInfo *Target = new TQFileInfo(targetAlbum + "/" + item->nameDest());
TQString newFileName = RenameTargetImageFile(Target);
if ( newFileName.isNull() )
{
item->changeResult(i18n("Failed."));
item->changeError(i18n("destination image file already exists and cannot be renamed."));
++*m_listFile2Process_iterator;
++m_progressStatus;
m_progress->setValue((int)((float)m_progressStatus *(float)100 / (float)m_nbItem));
if ( m_listFile2Process_iterator->current() )
{
startProcess();
return true;
}
else
{
endProcess();
return true;
}
}
else
{
TQFileInfo *newTarget = new TQFileInfo(newFileName);
item->changeNameDest(newTarget->fileName());
}
break;
}
case OVERWRITE_SKIP:
{
item->changeResult(i18n("Skipped."));
item->changeError(i18n("destination image file already exists (skipped automatically)."));
++*m_listFile2Process_iterator;
++m_progressStatus;
m_progress->setValue((int)((float)m_progressStatus *(float)100 / (float)m_nbItem));
if ( m_listFile2Process_iterator->current() )
{
startProcess();
return true;
}
else
{
endProcess();
return true;
}
break;
}
case OVERWRITE_OVER: // In this case do nothing : 'convert' default mode...
item->setDidOverWrite( true );
break;
default:
{
endProcess();
return true;
break;
}
}
}
m_commandLine = TQString();
m_ProcessusProc = new TDEProcess;
m_commandLine.append(makeProcess(m_ProcessusProc, item, targetAlbum));
item->changeOutputMess(m_commandLine + "\n\n");
connect(m_ProcessusProc, TQT_SIGNAL(processExited(TDEProcess *)),
this, TQT_SLOT(slotProcessDone(TDEProcess*)));
connect(m_ProcessusProc, TQT_SIGNAL(receivedStdout(TDEProcess *, char*, int)),
this, TQT_SLOT(slotReadStd(TDEProcess*, char*, int)));
connect(m_ProcessusProc, TQT_SIGNAL(receivedStderr(TDEProcess *, char*, int)),
this, TQT_SLOT(slotReadStd(TDEProcess*, char*, int)));
bool result = m_ProcessusProc->start(TDEProcess::NotifyOnExit, TDEProcess::All);
if(!result)
{
KMessageBox::error(this, i18n("Cannot start 'convert' program from 'ImageMagick' package;\n"
"please check your installation."));
return false;
}
return true;
}
void BatchProcessImagesDialog::slotReadStd(TDEProcess* /*proc*/, char *buffer, int buflen)
{
BatchProcessImagesItem *item = static_cast<BatchProcessImagesItem*>( m_listFile2Process_iterator->current() );
item->changeOutputMess( TQString::fromLocal8Bit(buffer, buflen) );
}
void BatchProcessImagesDialog::slotProcessDone(TDEProcess* proc)
{
if ( m_convertStatus == PROCESS_DONE )
{
// processAborted() has already been called. No need to show the warning.
return;
}
BatchProcessImagesItem *item = dynamic_cast<BatchProcessImagesItem*>( m_listFile2Process_iterator->current() );
m_listFiles->ensureItemVisible(m_listFiles->currentItem());
if ( !m_ProcessusProc->normalExit() )
{
int code = KMessageBox::warningContinueCancel( this,
i18n("The 'convert' program from 'ImageMagick' package has been stopped abnormally"),
i18n("Error running 'convert'") );
if ( code == KMessageBox::Cancel )
{
processAborted(true);
}
else
{
item->changeResult(i18n("Failed."));
item->changeError(i18n("'convert' program from 'ImageMagick' package has been stopped abnormally."));
++*m_listFile2Process_iterator;
++m_progressStatus;
m_progress->setValue((int)((float)m_progressStatus *(float)100 / (float)m_nbItem));
if ( m_listFile2Process_iterator->current() )
startProcess();
else
endProcess();
}
return;
}
int ValRet = proc->exitStatus();
kdWarning() << "Convert exit (" << ValRet << ")" << endl;
switch (ValRet)
{
case 0: // Process finished successfully !
{
item->changeResult(i18n("OK"));
item->changeError(i18n("no processing error"));
processDone();
// Save the comments for the converted image
KURL src;
src.setPath( item->pathSrc() );
KURL dest = m_destinationURL->url();
dest.addPath( item->nameDest() );
TQString errmsg;
KURL::List urlList;
urlList.append(src);
urlList.append(dest);
m_interface->refreshImages( urlList );
if ( !item->overWrote() )
{
// Do not add an entry if there was an image at the location already.
bool ok = m_interface->addImage( dest, errmsg );
if ( !ok )
{
int code = KMessageBox::warningContinueCancel( this,
i18n("<qt>Error adding image to application; error message was: "
"<b>%1</b></qt>").arg( errmsg ),
i18n("Error Adding Image to Application") );
if ( code == KMessageBox::Cancel )
{
slotProcessStop();
break;
}
else
item->changeResult(i18n("Failed."));
}
}
if ( src != dest )
{
KIPI::ImageInfo srcInfo = m_interface->info( src );
KIPI::ImageInfo destInfo = m_interface->info( dest );
destInfo.cloneData( srcInfo );
}
if ( m_removeOriginal->isChecked() && src != dest )
{
KURL deleteImage(item->pathSrc());
#if TDE_VERSION >= 0x30200
if ( TDEIO::NetAccess::del( deleteImage, TQT_TQWIDGET(kapp->activeWindow()) ) == false )
#else
if ( TDEIO::NetAccess::del( deleteImage ) == false )
#endif
{
item->changeResult(i18n("Warning:"));
item->changeError(i18n("cannot remove original image file."));
}
else
m_interface->delImage( item->pathSrc() );
}
break;
}
case 15: // process aborted !
{
processAborted(true);
break;
}
default : // Processing error !
{
item->changeResult(i18n("Failed."));
item->changeError(i18n("cannot process original image file."));
break;
}
}
++*m_listFile2Process_iterator;
++m_progressStatus;
m_progress->setValue((int)((float)m_progressStatus *(float)100 / (float)m_nbItem));
if ( m_listFile2Process_iterator->current() )
startProcess();
else
endProcess();
}
void BatchProcessImagesDialog::slotListDoubleClicked(TQListViewItem *itemClicked)
{
BatchProcessImagesItem *item = static_cast<BatchProcessImagesItem*>( itemClicked );
if (m_convertStatus == PROCESS_DONE)
{
OutputDialog *infoDialog = new OutputDialog(this,
i18n("Image processing error"),
item->outputMess(),
i18n("Image \"%1\": %2\n\nThe output messages are:\n")
.arg(item->nameSrc()).arg(item->error())
);
infoDialog->exec();
}
}
void BatchProcessImagesDialog::slotPreview(void)
{
kdWarning() << "BatchProcessImagesDialog::slotPreview" << endl;
if ( m_listFiles->currentItem() == 0 )
{
KMessageBox::error(this, i18n("You must select an item from the list to calculate the preview."));
return;
}
BatchProcessImagesItem *item = static_cast<BatchProcessImagesItem*>( m_listFiles->currentItem() );
m_listFiles->setEnabled(false);
m_labelType->setEnabled(false);
m_Type->setEnabled(false);
m_optionsButton->setEnabled(false);
m_previewButton->setEnabled(false);
m_labelOverWrite->setEnabled(false);
m_overWriteMode->setEnabled(false);
m_removeOriginal->setEnabled(false);
m_smallPreview->setEnabled(false);
m_destinationURL->setEnabled(false);
m_addImagesButton->setEnabled(false);
m_remImagesButton->setEnabled(false);
disconnect( this, TQT_SIGNAL(user1Clicked()),
this, TQT_SLOT(slotProcessStart()));
showButtonCancel( false );
setButtonText( User1, i18n("&Stop") );
connect(this, TQT_SIGNAL(user1Clicked()),
this, TQT_SLOT(slotPreviewStop()));
m_previewOutput = "";
m_PreviewProc = new TDEProcess;
m_previewOutput.append(makeProcess(m_PreviewProc, item, TQString(), true));
*m_PreviewProc << m_tmpFolder + "/" + TQString::number(getpid()) + "preview.PNG";
m_previewOutput.append( " " + m_tmpFolder + "/" + TQString::number(getpid()) + "preview.PNG\n\n");
connect(m_PreviewProc, TQT_SIGNAL(processExited(TDEProcess *)),
this, TQT_SLOT(slotPreviewProcessDone(TDEProcess*)));
connect(m_PreviewProc, TQT_SIGNAL(receivedStdout(TDEProcess *, char*, int)),
this, TQT_SLOT(slotPreviewReadStd(TDEProcess*, char*, int)));
connect(m_PreviewProc, TQT_SIGNAL(receivedStderr(TDEProcess *, char*, int)),
this, TQT_SLOT(slotPreviewReadStd(TDEProcess*, char*, int)));
bool result = m_PreviewProc->start(TDEProcess::NotifyOnExit, TDEProcess::All);
if(!result)
{
KMessageBox::error(this, i18n("Cannot start 'convert' program from 'ImageMagick' package;\n"
"please check your installation."));
m_previewButton->setEnabled(true);
return;
}
}
void BatchProcessImagesDialog::slotPreviewReadStd(TDEProcess* /*proc*/, char *buffer, int buflen)
{
m_previewOutput.append( TQString::fromLocal8Bit(buffer, buflen) );
}
void BatchProcessImagesDialog::slotPreviewProcessDone(TDEProcess* proc)
{
if (!m_PreviewProc->normalExit())
{
KMessageBox::error(this, i18n("Cannot run properly 'convert' program from 'ImageMagick' package."));
m_previewButton->setEnabled(true);
return;
}
BatchProcessImagesItem *item = static_cast<BatchProcessImagesItem*>( m_listFiles->currentItem() );
int ValRet = proc->exitStatus();
kdWarning() << "Convert exit (" << ValRet << ")" << endl;
if ( ValRet == 0 )
{
TQString cropTitle = "";
if ( m_smallPreview->isChecked() )
cropTitle = i18n(" - small preview");
ImagePreview *previewDialog = new ImagePreview(
item->pathSrc(),
m_tmpFolder + "/" + TQString::number(getpid()) + "preview.PNG",
m_tmpFolder,
m_smallPreview->isChecked(),
false,
m_Type->currentText() + cropTitle,
item->nameSrc(),
this);
previewDialog->exec();
KURL deletePreviewImage(m_tmpFolder + "/" + TQString::number(getpid()) + "preview.PNG");
#if TDE_VERSION >= 0x30200
TDEIO::NetAccess::del( deletePreviewImage, TQT_TQWIDGET(kapp->activeWindow()) );
#else
TDEIO::NetAccess::del( deletePreviewImage );
#endif
}
else
{
OutputDialog *infoDialog = new OutputDialog(this,
i18n("Preview processing error"),
m_previewOutput,
i18n("Cannot process preview for image \"%1\"."
"\nThe output messages are:\n")
.arg(item->nameSrc())
);
infoDialog->exec();
}
endPreview();
}
void BatchProcessImagesDialog::slotPreviewStop( void )
{
// Try to kill the current preview process !
if ( m_PreviewProc->isRunning() == true ) m_PreviewProc->kill(SIGTERM);
endPreview();
}
void BatchProcessImagesDialog::slotProcessStop( void )
{
// Try to kill the current process !
if ( m_ProcessusProc->isRunning() == true ) m_ProcessusProc->kill(SIGTERM);
// If kill operation failed, Stop the process at the next image !
if ( m_convertStatus == UNDER_PROCESS ) m_convertStatus = STOP_PROCESS;
processAborted(true);
}
void BatchProcessImagesDialog::slotOk()
{
close();
saveSettings();
delete this;
}
void BatchProcessImagesDialog::listImageFiles(void)
{
m_nbItem = m_selectedImageFiles.count();
if (m_nbItem == 0) groupBox4->setTitle(i18n("Image File List"));
else
groupBox4->setTitle(i18n("Image File List (1 item)", "Image File List (%n items)", m_nbItem));
if (m_selectedImageFiles.isEmpty()) return;
for ( KURL::List::Iterator it = m_selectedImageFiles.begin() ; it != m_selectedImageFiles.end() ; ++it )
{
TQString currentFile = (*it).path(); // PENDING(blackie) Handle URLS
TQFileInfo *fi = new TQFileInfo(currentFile);
// Check if the new item already exist in the list.
bool findItem = false;
TQListViewItemIterator it2( m_listFiles );
while ( it2.current() )
{
BatchProcessImagesItem *pitem = static_cast<BatchProcessImagesItem*>(it2.current());
if ( pitem->pathSrc() == currentFile.section('/', 0, -1) )
findItem = true;
++it2;
}
if (findItem == false)
{
TQString oldFileName = fi->fileName();
TQString newFileName = oldFileName2NewFileName(oldFileName);
new BatchProcessImagesItem(m_listFiles,
currentFile.section('/', 0, -1),
oldFileName,
newFileName,
""
);
}
delete fi;
}
m_listFiles->setCurrentItem( m_listFiles->firstChild());
m_listFiles->setSelected( m_listFiles->currentItem(), true );
slotImageSelected(m_listFiles->currentItem());
m_listFiles->ensureItemVisible(m_listFiles->currentItem());
}
void BatchProcessImagesDialog::endPreview(void)
{
m_listFiles->setEnabled(true);
m_labelType->setEnabled(true);
m_Type->setEnabled(true);
m_previewButton->setEnabled(true);
m_labelOverWrite->setEnabled(true);
m_overWriteMode->setEnabled(true);
m_destinationURL->setEnabled(true);
m_addImagesButton->setEnabled(true);
m_remImagesButton->setEnabled(true);
m_smallPreview->setEnabled(true);
m_removeOriginal->setEnabled(true);
showButtonCancel( true );
m_optionsButton->setEnabled(true); // Default status if 'slotTypeChanged' isn't re-implemented.
slotTypeChanged(m_Type->currentItem());
setButtonText( User1, i18n("&Start") );
disconnect(this, TQT_SIGNAL(user1Clicked()),
this, TQT_SLOT(slotPreviewStop()));
connect(this, TQT_SIGNAL(user1Clicked()),
this, TQT_SLOT(slotProcessStart()));
}
int BatchProcessImagesDialog::overwriteMode(void)
{
TQString OverWrite = m_overWriteMode->currentText();
if (OverWrite == i18n("Ask"))
return OVERWRITE_ASK;
if (OverWrite == i18n("Rename"))
return OVERWRITE_RENAME;
if (OverWrite == i18n("Skip"))
return OVERWRITE_SKIP;
if (OverWrite == i18n("Always Overwrite"))
return OVERWRITE_OVER;
return OVERWRITE_ASK;
}
void BatchProcessImagesDialog::processAborted(bool removeFlag)
{
kdWarning() << "BatchProcessImagesDialog::processAborted" << endl;
BatchProcessImagesItem *item = static_cast<BatchProcessImagesItem*>( m_listFile2Process_iterator->current() );
m_listFiles->ensureItemVisible(m_listFiles->currentItem());
item->changeResult(i18n("Aborted."));
item->changeError(i18n("process aborted by user"));
if (removeFlag == true) // Try to delete de destination !
{
KURL deleteImage = m_destinationURL->url();
deleteImage.addPath(item->nameDest());
#if TDE_VERSION >= 0x30200
if ( TDEIO::NetAccess::exists( deleteImage, false, TQT_TQWIDGET(kapp->activeWindow()) ) == true )
TDEIO::NetAccess::del( deleteImage, TQT_TQWIDGET(kapp->activeWindow()) );
#else
if ( TDEIO::NetAccess::exists( deleteImage ) == true )
TDEIO::NetAccess::del( deleteImage );
#endif
}
endProcess();
}
void BatchProcessImagesDialog::endProcess(void)
{
m_convertStatus = PROCESS_DONE;
setButtonText( User1, i18n("&Close") );
disconnect(this, TQT_SIGNAL(user1Clicked()),
this, TQT_SLOT(slotProcessStop()));
connect(this, TQT_SIGNAL(user1Clicked()),
this, TQT_SLOT(slotOk()));
}
TQString BatchProcessImagesDialog::RenameTargetImageFile(TQFileInfo *fi)
{
TQString Temp;
int Enumerator = 0;
KURL NewDestUrl;
do
{
++Enumerator;
Temp = Temp.setNum( Enumerator );
NewDestUrl = fi->filePath().left( fi->filePath().findRev('.', -1)) + "_" + Temp
+ "." + fi->filePath().section('.', -1 );
}
while ( Enumerator < 100 &&
#if TDE_VERSION >= 0x30200
TDEIO::NetAccess::exists( NewDestUrl, true, TQT_TQWIDGET(kapp->activeWindow()) )
#else
TDEIO::NetAccess::exists( NewDestUrl )
#endif
== true );
if (Enumerator == 100) return TQString();
return (NewDestUrl.path());
}
TQString BatchProcessImagesDialog::extractArguments(TDEProcess *proc)
{
TQString retArguments;
TQValueList<TQCString> argumentsList = proc->args();
for ( TQValueList<TQCString>::iterator it = argumentsList.begin() ; it != argumentsList.end() ; ++it )
retArguments.append(*it + " ");
return (retArguments);
}
} // NameSpace KIPIBatchProcessImagesPlugin