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.
554 lines
15 KiB
554 lines
15 KiB
/* ============================================================
|
|
*
|
|
* This file is a part of kipi-plugins project
|
|
* http://www.kipi-plugins.org
|
|
*
|
|
* Date : 2003-10-01
|
|
* Description : a kipi plugin to batch process images
|
|
*
|
|
* Copyright (C) 2003-2007 by Gilles Caulier <caulier dot gilles at gmail dot com>
|
|
* Copyright (C) 2005 by Owen Hirst <n8rider@sbcglobal.net>
|
|
*
|
|
* 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>
|
|
#include <ctime>
|
|
|
|
// TQt includes.
|
|
|
|
#include <tqlistview.h>
|
|
#include <tqlineedit.h>
|
|
#include <tqcheckbox.h>
|
|
#include <tqspinbox.h>
|
|
#include <tqfile.h>
|
|
#include <tqfileinfo.h>
|
|
#include <tqpushbutton.h>
|
|
#include <tqlabel.h>
|
|
#include <tqcombobox.h>
|
|
#include <tqtimer.h>
|
|
#include <tqprogressdialog.h>
|
|
#include <tqgroupbox.h>
|
|
#include <tqpopupmenu.h>
|
|
|
|
// KDE includes.
|
|
|
|
#include <tdelocale.h>
|
|
#include <tdeconfig.h>
|
|
#include <tdeio/previewjob.h>
|
|
#include <tdeio/renamedlg.h>
|
|
#include <kdebug.h>
|
|
#include <tdeversion.h>
|
|
|
|
// Libkipi includes.
|
|
|
|
#include <libkipi/interface.h>
|
|
#include <libkipi/imageinfo.h>
|
|
#include <libkipi/imagedialog.h>
|
|
|
|
// Local includes.
|
|
|
|
#include "batchprocessimagesitem.h"
|
|
#include "renameimageswidget.h"
|
|
#include "renameimageswidget.moc"
|
|
|
|
namespace KIPIBatchProcessImagesPlugin
|
|
{
|
|
|
|
RenameImagesWidget::RenameImagesWidget(TQWidget *parent,
|
|
KIPI::Interface* interface,
|
|
const KURL::List& urlList)
|
|
: RenameImagesBase(parent),
|
|
m_interface(interface),
|
|
m_urlList(urlList)
|
|
{
|
|
m_listView->setSorting(-1);
|
|
#if KDE_IS_VERSION(3,4,0)
|
|
// next can be done directly into designer but it seems not to compile
|
|
// under kde < 3.4.0
|
|
m_listView->setShadeSortColumn( FALSE );
|
|
#endif
|
|
|
|
readSettings();
|
|
|
|
TQPopupMenu* sortMenu = new TQPopupMenu(this);
|
|
sortMenu->insertItem(i18n("Sort by Name"), BYNAME);
|
|
sortMenu->insertItem(i18n("Sort by Size"), BYSIZE);
|
|
sortMenu->insertItem(i18n("Sort by Date"), BYDATE);
|
|
m_sortButton->setPopup(sortMenu);
|
|
|
|
connect(m_listView, TQT_SIGNAL(doubleClicked(TQListViewItem*)),
|
|
TQT_SLOT(slotListViewDoubleClicked(TQListViewItem*)));
|
|
connect(m_listView, TQT_SIGNAL(selectionChanged(TQListViewItem*)),
|
|
TQT_SLOT(slotImageSelected(TQListViewItem*)));
|
|
|
|
connect(m_prefixEdit, TQT_SIGNAL(textChanged(const TQString&)),
|
|
TQT_SLOT(slotOptionsChanged()));
|
|
connect(m_seqSpin, TQT_SIGNAL(valueChanged(int)),
|
|
TQT_SLOT(slotOptionsChanged()));
|
|
connect(m_addFileNameCheck, TQT_SIGNAL(toggled(bool)),
|
|
TQT_SLOT(slotOptionsChanged()));
|
|
connect(m_addFileDateCheck, TQT_SIGNAL(toggled(bool)),
|
|
TQT_SLOT(slotOptionsChanged()));
|
|
connect(m_formatDateCheck, TQT_SIGNAL(toggled(bool)),
|
|
TQT_SLOT(slotOptionsChanged()));
|
|
connect(m_formatDateEdit, TQT_SIGNAL(textChanged(const TQString&)),
|
|
TQT_SLOT(slotOptionsChanged()));
|
|
|
|
connect(m_addButton, TQT_SIGNAL(clicked()),
|
|
TQT_SLOT(slotAddImages()));
|
|
connect(m_removeButton, TQT_SIGNAL(clicked()),
|
|
TQT_SLOT(slotRemoveImage()));
|
|
|
|
connect(sortMenu, TQT_SIGNAL(activated(int)),
|
|
TQT_SLOT(sortList(int)) );
|
|
|
|
connect(m_reverseList, TQT_SIGNAL(clicked()),
|
|
TQT_SLOT(reverseList()) );
|
|
|
|
connect(m_moveUp, TQT_SIGNAL(clicked()),
|
|
TQT_SLOT(moveCurrentItemUp()) );
|
|
|
|
connect(m_moveDown, TQT_SIGNAL(clicked()),
|
|
TQT_SLOT(moveCurrentItemDown()) );
|
|
|
|
m_timer = new TQTimer(this);
|
|
m_progress = new TQProgressDialog(this, 0, true);
|
|
connect(m_timer, TQT_SIGNAL(timeout()),
|
|
TQT_SLOT(slotNext()));
|
|
connect(m_progress, TQT_SIGNAL(canceled()),
|
|
TQT_SLOT(slotAbort()));
|
|
|
|
for (KURL::List::iterator it = m_urlList.begin();
|
|
it != m_urlList.end(); ++it)
|
|
{
|
|
new BatchProcessImagesItem(m_listView,
|
|
(*it).path().section('/', 0, -1),
|
|
(*it).filename(),
|
|
TQString(),
|
|
TQString());
|
|
}
|
|
|
|
updateListing();
|
|
}
|
|
|
|
RenameImagesWidget::~RenameImagesWidget()
|
|
{
|
|
delete m_timer;
|
|
delete m_progress;
|
|
|
|
saveSettings();
|
|
}
|
|
|
|
void RenameImagesWidget::readSettings()
|
|
{
|
|
TDEConfig config("kipirc");
|
|
config.setGroup("RenameImages Settings");
|
|
|
|
m_prefixEdit->setText(config.readEntry("PrefixString", ""));
|
|
m_seqSpin->setValue(config.readNumEntry("FirstRenameValue", 1));
|
|
|
|
m_addFileNameCheck->setChecked(config.readBoolEntry("AddOriginalFileName", false));
|
|
m_addFileDateCheck->setChecked(config.readBoolEntry("AddImageFileDate", false));
|
|
m_formatDateCheck->setChecked(config.readBoolEntry("FormatDate", false));
|
|
m_formatDateEdit->setText(config.readEntry("FormatDateString", "%Y-%m-%d"));
|
|
|
|
slotOptionsChanged();
|
|
}
|
|
|
|
void RenameImagesWidget::saveSettings()
|
|
{
|
|
TDEConfig config("kipirc");
|
|
config.setGroup("RenameImages Settings");
|
|
|
|
config.writeEntry("PrefixString", m_prefixEdit->text());
|
|
config.writeEntry("FirstRenameValue", m_seqSpin->value());
|
|
|
|
config.writeEntry("AddOriginalFileName", m_addFileNameCheck->isChecked());
|
|
config.writeEntry("AddImageFileDate", m_addFileDateCheck->isChecked());
|
|
config.writeEntry("FormatDate", m_formatDateCheck->isChecked());
|
|
config.writeEntry("FormatDateString", m_formatDateEdit->text());
|
|
|
|
config.sync();
|
|
}
|
|
|
|
void RenameImagesWidget::slotOptionsChanged()
|
|
{
|
|
m_formatDateCheck->setEnabled(m_addFileDateCheck->isChecked());
|
|
m_formatDateEdit->setEnabled(m_formatDateCheck->isEnabled() &&
|
|
m_formatDateCheck->isChecked());
|
|
|
|
updateListing();
|
|
}
|
|
|
|
void RenameImagesWidget::slotListViewDoubleClicked(TQListViewItem*)
|
|
{
|
|
// TODO: Implement
|
|
}
|
|
|
|
void RenameImagesWidget::slotImageSelected(TQListViewItem* item)
|
|
{
|
|
if (!item)
|
|
{
|
|
m_removeButton->setEnabled(false);
|
|
return;
|
|
}
|
|
|
|
m_removeButton->setEnabled(true);
|
|
m_pixLabel->clear();
|
|
|
|
BatchProcessImagesItem* it = static_cast<BatchProcessImagesItem*>(item);
|
|
TDEIO::PreviewJob* thumbJob = TDEIO::filePreview(KURL(it->pathSrc()),
|
|
m_pixLabel->height() );
|
|
|
|
connect(thumbJob, TQT_SIGNAL(gotPreview(const KFileItem*, const TQPixmap&)),
|
|
TQT_SLOT(slotGotPreview(const KFileItem*, const TQPixmap&)));
|
|
}
|
|
|
|
|
|
void RenameImagesWidget::sortList(int intSortOrder)
|
|
{
|
|
SortOrder sortOrder = static_cast<SortOrder>(intSortOrder);
|
|
|
|
for (TQListViewItem* it = m_listView->firstChild(); it;
|
|
it = it->nextSibling())
|
|
{
|
|
BatchProcessImagesItem* item = static_cast<BatchProcessImagesItem*>(it);
|
|
|
|
switch (sortOrder)
|
|
{
|
|
case(BYNAME):
|
|
{
|
|
item->setKey(item->text(1), false);
|
|
break;
|
|
}
|
|
case(BYSIZE):
|
|
{
|
|
TQFileInfo fi(item->pathSrc());
|
|
item->setKey(TQString::number(fi.size()), false);
|
|
break;
|
|
}
|
|
case(BYDATE):
|
|
{
|
|
KURL url(item->pathSrc());
|
|
KIPI::ImageInfo info = m_interface->info(url);
|
|
item->setKey(info.time().toString(Qt::ISODate), false);
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
|
|
// Update list order. We need to set the sorting column temporarily
|
|
// otherwise sort() won't do anything
|
|
m_listView->setSorting(1);
|
|
m_listView->sort();
|
|
m_listView->setSorting(-1);
|
|
|
|
updateListing();
|
|
}
|
|
|
|
|
|
void RenameImagesWidget::reverseList()
|
|
{
|
|
if (m_listView->childCount() < 2) return;
|
|
|
|
TQListViewItem* lastItem = m_listView->lastItem();
|
|
|
|
while (m_listView->firstChild() != lastItem) {
|
|
m_listView->firstChild()->moveItem(lastItem);
|
|
}
|
|
|
|
updateListing();
|
|
}
|
|
|
|
|
|
void RenameImagesWidget::moveCurrentItemUp() {
|
|
TQListViewItem* currentItem = m_listView->currentItem();
|
|
if (!currentItem) return;
|
|
|
|
for (TQListViewItem* previousItem = m_listView->firstChild(); previousItem;
|
|
previousItem = previousItem->nextSibling())
|
|
{
|
|
if (previousItem->nextSibling() == currentItem) {
|
|
previousItem->moveItem(currentItem);
|
|
break;
|
|
}
|
|
}
|
|
|
|
updateListing();
|
|
}
|
|
|
|
|
|
void RenameImagesWidget::moveCurrentItemDown() {
|
|
TQListViewItem* currentItem = m_listView->currentItem();
|
|
if (!currentItem) return;
|
|
|
|
TQListViewItem* nextItem = currentItem->nextSibling();
|
|
if (nextItem) {
|
|
currentItem->moveItem(nextItem);
|
|
}
|
|
|
|
updateListing();
|
|
}
|
|
|
|
|
|
void RenameImagesWidget::updateListing()
|
|
{
|
|
int pos = 0;
|
|
for (TQListViewItem* it = m_listView->firstChild(); it;
|
|
it = it->nextSibling())
|
|
{
|
|
BatchProcessImagesItem* item = static_cast<BatchProcessImagesItem*>(it);
|
|
item->changeNameDest(oldToNewName(item, pos));
|
|
item->changeResult(TQString());
|
|
item->changeError(TQString());
|
|
item->changeOutputMess(TQString());
|
|
pos++;
|
|
}
|
|
}
|
|
|
|
TQString RenameImagesWidget::oldToNewName(BatchProcessImagesItem* item,
|
|
int itemPosition)
|
|
{
|
|
KURL url;
|
|
url.setPath(item->pathSrc());
|
|
|
|
TQFileInfo fi(item->pathSrc());
|
|
|
|
KIPI::ImageInfo info = m_interface->info(url);
|
|
|
|
TQString newName = m_prefixEdit->text();
|
|
|
|
if (m_addFileNameCheck->isChecked())
|
|
{
|
|
newName += fi.baseName();
|
|
newName += "_";
|
|
}
|
|
|
|
if (m_addFileDateCheck->isChecked())
|
|
{
|
|
TQString format = m_formatDateEdit->text();
|
|
format = format.simplifyWhiteSpace();
|
|
format.replace("%%","%");
|
|
format.replace("%s","");
|
|
format.replace("/", "");
|
|
|
|
time_t time = info.time().toTime_t();
|
|
struct tm* time_tm = ::localtime(&time);
|
|
char s[100];
|
|
::strftime(s, 100, TQFile::encodeName(format), time_tm);
|
|
|
|
newName += TQString::fromLatin1(s);
|
|
newName += "_";
|
|
}
|
|
|
|
int count = m_listView->childCount();
|
|
int numDigits = 1;
|
|
while (count > 0)
|
|
{
|
|
numDigits++;
|
|
count = count / 10;
|
|
}
|
|
|
|
TQString format;
|
|
format.sprintf("0%dd", numDigits);
|
|
format = "%" + format;
|
|
|
|
TQString seq;
|
|
seq.sprintf(format.latin1(), itemPosition + m_seqSpin->value());
|
|
newName += seq;
|
|
|
|
newName += TQString::fromLatin1(".") + fi.extension();
|
|
|
|
return newName;
|
|
}
|
|
|
|
void RenameImagesWidget::slotGotPreview(const KFileItem*, const TQPixmap& pix)
|
|
{
|
|
m_pixLabel->setPixmap(pix);
|
|
}
|
|
|
|
void RenameImagesWidget::slotStart()
|
|
{
|
|
m_timer->start(0, true);
|
|
|
|
m_listView->setSelected(m_listView->firstChild(), true);
|
|
m_listView->ensureItemVisible(m_listView->firstChild());
|
|
|
|
m_progress->setTotalSteps(m_listView->childCount());
|
|
m_progress->setProgress(0);
|
|
m_progress->show();
|
|
|
|
m_overwriteAll = false;
|
|
m_autoSkip = false;
|
|
}
|
|
|
|
void RenameImagesWidget::slotAbort()
|
|
{
|
|
m_timer->stop();
|
|
m_progress->reset();
|
|
m_progress->hide();
|
|
}
|
|
|
|
void RenameImagesWidget::slotNext()
|
|
{
|
|
TQListViewItem* it = m_listView->selectedItem();
|
|
if (!it)
|
|
{
|
|
slotAbort();
|
|
return;
|
|
}
|
|
|
|
BatchProcessImagesItem* item = static_cast<BatchProcessImagesItem*>(it);
|
|
KURL src;
|
|
src.setPath(item->pathSrc());
|
|
KURL dst = src.upURL();
|
|
dst.addPath(item->text(2));
|
|
|
|
bool skip = false;
|
|
bool overwrite = false;
|
|
|
|
if (!m_overwriteAll)
|
|
{
|
|
struct stat info;
|
|
while (::stat(TQFile::encodeName(dst.path()), &info) == 0)
|
|
{
|
|
if (m_autoSkip)
|
|
{
|
|
skip = true;
|
|
break;
|
|
}
|
|
|
|
TDEIO::RenameDlg dlg(this, i18n("Rename File"), src.path(), dst.path(),
|
|
TDEIO::RenameDlg_Mode(TDEIO::M_MULTI |
|
|
TDEIO::M_OVERWRITE |
|
|
TDEIO::M_SKIP));
|
|
int result = dlg.exec();
|
|
dst = dlg.newDestURL();
|
|
|
|
switch (result)
|
|
{
|
|
case TDEIO::R_CANCEL:
|
|
{
|
|
slotAbort();
|
|
return;
|
|
}
|
|
case TDEIO::R_SKIP:
|
|
{
|
|
skip = true;
|
|
break;
|
|
}
|
|
case TDEIO::R_AUTO_SKIP:
|
|
{
|
|
m_autoSkip = true;
|
|
skip = true;
|
|
break;
|
|
}
|
|
case TDEIO::R_OVERWRITE:
|
|
{
|
|
overwrite = true;
|
|
break;
|
|
}
|
|
case TDEIO::R_OVERWRITE_ALL:
|
|
{
|
|
m_overwriteAll = true;
|
|
overwrite = true;
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (skip || overwrite)
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (skip)
|
|
{
|
|
item->changeResult(i18n("Skipped"));
|
|
}
|
|
else
|
|
{
|
|
// Get the src info
|
|
KIPI::ImageInfo srcInfo = m_interface->info(src);
|
|
|
|
if (::rename(TQFile::encodeName(src.path()),
|
|
TQFile::encodeName(dst.path())) == 0)
|
|
{
|
|
srcInfo.setTitle(dst.filename());
|
|
|
|
item->changeResult(i18n("OK"));
|
|
}
|
|
else
|
|
{
|
|
item->changeResult(i18n("Failed"));
|
|
}
|
|
}
|
|
|
|
m_progress->setProgress(m_progress->progress() + 1);
|
|
|
|
if (it->nextSibling())
|
|
{
|
|
m_listView->setSelected(it->nextSibling(), true);
|
|
m_listView->ensureItemVisible(it->nextSibling());
|
|
m_timer->start(0, true);
|
|
}
|
|
}
|
|
|
|
void RenameImagesWidget::slotAddImages()
|
|
{
|
|
KURL::List urls = KIPI::ImageDialog::getImageURLs(this, m_interface);
|
|
|
|
for (KURL::List::iterator it = urls.begin(); it != urls.end(); ++it)
|
|
{
|
|
if (m_urlList.contains(*it))
|
|
continue;
|
|
|
|
new BatchProcessImagesItem(m_listView,
|
|
(*it).path().section('/', 0, -1),
|
|
(*it).filename(),
|
|
TQString(),
|
|
TQString());
|
|
m_urlList.append(*it);
|
|
}
|
|
|
|
updateListing();
|
|
}
|
|
|
|
void RenameImagesWidget::slotRemoveImage()
|
|
{
|
|
if (!m_listView->selectedItem())
|
|
return;
|
|
|
|
BatchProcessImagesItem* item =
|
|
static_cast<BatchProcessImagesItem*>(m_listView->selectedItem());
|
|
delete item;
|
|
|
|
m_pixLabel->clear();
|
|
|
|
updateListing();
|
|
}
|
|
|
|
} // namespace KIPIBatchProcessImagesPlugin
|