/* ============================================================ * * 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 * Copyright (C) 2005 by Owen Hirst * * 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 #include // TQt includes. #include #include #include #include #include #include #include #include #include #include #include #include #include // KDE includes. #include #include #include #include #include #include // Libkipi includes. #include #include #include // 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(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(intSortOrder); for (TQListViewItem* it = m_listView->firstChild(); it; it = it->nextSibling()) { BatchProcessImagesItem* item = static_cast(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(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(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(m_listView->selectedItem()); delete item; m_pixLabel->clear(); updateListing(); } } // namespace KIPIBatchProcessImagesPlugin