diff options
Diffstat (limited to 'kipi-plugins/metadataedit/plugin_metadataedit.cpp')
-rw-r--r-- | kipi-plugins/metadataedit/plugin_metadataedit.cpp | 588 |
1 files changed, 588 insertions, 0 deletions
diff --git a/kipi-plugins/metadataedit/plugin_metadataedit.cpp b/kipi-plugins/metadataedit/plugin_metadataedit.cpp new file mode 100644 index 0000000..64f8a39 --- /dev/null +++ b/kipi-plugins/metadataedit/plugin_metadataedit.cpp @@ -0,0 +1,588 @@ +/* ============================================================ + * + * This file is a part of kipi-plugins project + * http://www.kipi-plugins.org + * + * Date : 2006-10-11 + * Description : a plugin to edit pictures metadata + * + * Copyright (C) 2006-2007 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. + * + * ============================================================ */ + +// KDE includes. + +#include <klocale.h> +#include <kaction.h> +#include <kapplication.h> +#include <kgenericfactory.h> +#include <klibloader.h> +#include <kconfig.h> +#include <kdebug.h> +#include <kpopupmenu.h> +#include <kmessagebox.h> +#include <kfiledialog.h> +#include <kglobalsettings.h> + +// LibKIPI includes. + +#include <libkipi/imagecollection.h> + +// LibKExiv2 includes. + +#include <libkexiv2/kexiv2.h> + +// Local includes. + +#include "exifeditdialog.h" +#include "iptceditdialog.h" +#include "commenteditdialog.h" +#include "commentremovedialog.h" +#include "plugin_metadataedit.h" +#include "plugin_metadataedit.moc" + +typedef KGenericFactory<Plugin_MetadataEdit> Factory; + +K_EXPORT_COMPONENT_FACTORY( kipiplugin_metadataedit, Factory("kipiplugin_metadataedit")) + +Plugin_MetadataEdit::Plugin_MetadataEdit(QObject *parent, const char*, const QStringList&) + : KIPI::Plugin( Factory::instance(), parent, "MetadataEdit") +{ + kdDebug( 51001 ) << "Plugin_MetadataEdit plugin loaded" << endl; +} + +void Plugin_MetadataEdit::setup( QWidget* widget ) +{ + KIPI::Plugin::setup( widget ); + + m_actionMetadataEdit = new KActionMenu(i18n("Metadata"), + 0, + actionCollection(), + "metadataedit"); + + m_actionMetadataEdit->insert(new KAction (i18n("Edit EXIF..."), + 0, + 0, + this, + SLOT(slotEditExif()), + actionCollection(), + "editexif")); + + m_actionMetadataEdit->insert(new KAction (i18n("Remove EXIF..."), + 0, + 0, + this, + SLOT(slotRemoveExif()), + actionCollection(), + "removeexif")); + + m_actionMetadataEdit->insert(new KAction (i18n("Import EXIF..."), + 0, + 0, + this, + SLOT(slotImportExif()), + actionCollection(), + "importexif")); + + m_actionMetadataEdit->popupMenu()->insertSeparator(); + + m_actionMetadataEdit->insert(new KAction (i18n("Edit IPTC..."), + 0, + 0, + this, + SLOT(slotEditIptc()), + actionCollection(), + "editiptc")); + + m_actionMetadataEdit->insert(new KAction (i18n("Remove IPTC..."), + 0, + 0, + this, + SLOT(slotRemoveIptc()), + actionCollection(), + "removeiptc")); + + m_actionMetadataEdit->insert(new KAction (i18n("Import IPTC..."), + 0, + 0, + this, + SLOT(slotImportIptc()), + actionCollection(), + "importiptc")); + + m_actionMetadataEdit->popupMenu()->insertSeparator(); + + m_actionMetadataEdit->insert(new KAction (i18n("Edit Captions..."), + 0, + 0, + this, + SLOT(slotEditComments()), + actionCollection(), + "editcomments")); + + m_actionMetadataEdit->insert(new KAction (i18n("Remove Captions..."), + 0, + 0, + this, + SLOT(slotRemoveComments()), + actionCollection(), + "removecomments")); + + addAction( m_actionMetadataEdit ); + + m_interface = dynamic_cast< KIPI::Interface* >( parent() ); + + if ( !m_interface ) + { + kdError( 51000 ) << "Kipi interface is null!" << endl; + return; + } + + KIPI::ImageCollection selection = m_interface->currentSelection(); + m_actionMetadataEdit->setEnabled( selection.isValid() && !selection.images().isEmpty() ); + + connect( m_interface, SIGNAL(selectionChanged(bool)), + m_actionMetadataEdit, SLOT(setEnabled(bool))); +} + +void Plugin_MetadataEdit::slotEditExif() +{ + KIPI::ImageCollection images = m_interface->currentSelection(); + + if ( !images.isValid() || images.images().isEmpty() ) + return; + + KIPIMetadataEditPlugin::EXIFEditDialog dialog(kapp->activeWindow(), images.images(), m_interface); + dialog.exec(); + m_interface->refreshImages(images.images()); +} + +void Plugin_MetadataEdit::slotRemoveExif() +{ + KIPI::ImageCollection images = m_interface->currentSelection(); + + if ( !images.isValid() || images.images().isEmpty() ) + return; + + if (KMessageBox::warningYesNo( + kapp->activeWindow(), + i18n("EXIF metadata will be permanently removed from all current selected pictures.\n" + "Do you want to continue ?"), + i18n("Remove EXIF Metadata")) != KMessageBox::Yes) + return; + + KURL::List imageURLs = images.images(); + KURL::List updatedURLs; + QStringList errorFiles; + + for( KURL::List::iterator it = imageURLs.begin() ; + it != imageURLs.end(); ++it) + { + KURL url = *it; + bool ret = false; + + if (!KExiv2Iface::KExiv2::isReadOnly(url.path())) + { + ret = true; + KExiv2Iface::KExiv2 exiv2Iface; + ret &= exiv2Iface.load(url.path()); + ret &= exiv2Iface.clearExif(); + ret &= exiv2Iface.save(url.path()); + } + + if (!ret) + errorFiles.append(url.fileName()); + else + updatedURLs.append(url); + } + + // We use kipi interface refreshImages() method to tell to host than + // metadata from pictures have changed and need to be re-read. + + m_interface->refreshImages(updatedURLs); + + if (!errorFiles.isEmpty()) + { + KMessageBox::errorList( + kapp->activeWindow(), + i18n("Unable to remove EXIF metadata from:"), + errorFiles, + i18n("Remove EXIF Metadata")); + } +} + +void Plugin_MetadataEdit::slotImportExif() +{ + KIPI::ImageCollection images = m_interface->currentSelection(); + + if ( !images.isValid() || images.images().isEmpty() ) + return; + + KURL importEXIFFile = KFileDialog::getOpenURL(KGlobalSettings::documentPath(), + QString::null, kapp->activeWindow(), + i18n("Select File to Import EXIF metadata") ); + if( importEXIFFile.isEmpty() ) + return; + + KExiv2Iface::KExiv2 exiv2Iface; + if (!exiv2Iface.load(importEXIFFile.path())) + { + KMessageBox::error(kapp->activeWindow(), + i18n("Cannot load metadata from \"%1\"").arg(importEXIFFile.fileName()), + i18n("Import EXIF Metadata")); + return; + } + + QByteArray exifData = exiv2Iface.getExif(); + if (exifData.isEmpty()) + { + KMessageBox::error(kapp->activeWindow(), + i18n("\"%1\" do not have EXIF metadata").arg(importEXIFFile.fileName()), + i18n("Import EXIF Metadata")); + return; + } + + if (KMessageBox::warningYesNo( + kapp->activeWindow(), + i18n("EXIF metadata from current selected pictures will be permanently " + "replaced by the EXIF content of \"%1\".\n" + "Do you want to continue ?").arg(importEXIFFile.fileName()), + i18n("Import EXIF Metadata")) != KMessageBox::Yes) + return; + + + KURL::List imageURLs = images.images(); + KURL::List updatedURLs; + QStringList errorFiles; + + for( KURL::List::iterator it = imageURLs.begin() ; + it != imageURLs.end(); ++it) + { + KURL url = *it; + bool ret = false; + + if (!KExiv2Iface::KExiv2::isReadOnly(url.path())) + { + ret = true; + KExiv2Iface::KExiv2 exiv2Iface; + ret &= exiv2Iface.load(url.path()); + ret &= exiv2Iface.setExif(exifData); + ret &= exiv2Iface.save(url.path()); + } + + if (!ret) + errorFiles.append(url.fileName()); + else + updatedURLs.append(url); + } + + // We use kipi interface refreshImages() method to tell to host than + // metadata from pictures have changed and need to be re-read. + + m_interface->refreshImages(updatedURLs); + + if (!errorFiles.isEmpty()) + { + KMessageBox::errorList( + kapp->activeWindow(), + i18n("Unable to set EXIF metadata from:"), + errorFiles, + i18n("Import EXIF Metadata")); + } +} + +void Plugin_MetadataEdit::slotEditIptc() +{ + KIPI::ImageCollection images = m_interface->currentSelection(); + + if ( !images.isValid() || images.images().isEmpty() ) + return; + + KIPIMetadataEditPlugin::IPTCEditDialog dialog(kapp->activeWindow(), images.images(), m_interface); + dialog.exec(); + m_interface->refreshImages(images.images()); +} + +void Plugin_MetadataEdit::slotRemoveIptc() +{ + KIPI::ImageCollection images = m_interface->currentSelection(); + + if ( !images.isValid() || images.images().isEmpty() ) + return; + + if (KMessageBox::warningYesNo( + kapp->activeWindow(), + i18n("IPTC metadata will be permanently removed from all current selected pictures.\n" + "Do you want to continue ?"), + i18n("Remove IPTC Metadata")) != KMessageBox::Yes) + return; + + KURL::List imageURLs = images.images(); + KURL::List updatedURLs; + QStringList errorFiles; + + for( KURL::List::iterator it = imageURLs.begin() ; + it != imageURLs.end(); ++it) + { + KURL url = *it; + bool ret = false; + + if (!KExiv2Iface::KExiv2::isReadOnly(url.path())) + { + ret = true; + KExiv2Iface::KExiv2 exiv2Iface; + ret &= exiv2Iface.load(url.path()); + ret &= exiv2Iface.clearIptc(); + ret &= exiv2Iface.save(url.path()); + } + + if (!ret) + errorFiles.append(url.fileName()); + else + updatedURLs.append(url); + } + + // We use kipi interface refreshImages() method to tell to host than + // metadata from pictures have changed and need to be re-read. + + m_interface->refreshImages(updatedURLs); + + if (!errorFiles.isEmpty()) + { + KMessageBox::errorList( + kapp->activeWindow(), + i18n("Unable to remove IPTC metadata from:"), + errorFiles, + i18n("Remove IPTC Metadata")); + } +} + +void Plugin_MetadataEdit::slotImportIptc() +{ + KIPI::ImageCollection images = m_interface->currentSelection(); + + if ( !images.isValid() || images.images().isEmpty() ) + return; + + KURL importIPTCFile = KFileDialog::getOpenURL(KGlobalSettings::documentPath(), + QString::null, kapp->activeWindow(), + i18n("Select File to Import IPTC metadata") ); + if( importIPTCFile.isEmpty() ) + return; + + KExiv2Iface::KExiv2 exiv2Iface; + if (!exiv2Iface.load(importIPTCFile.path())) + { + KMessageBox::error(kapp->activeWindow(), + i18n("Cannot load metadata from \"%1\"").arg(importIPTCFile.fileName()), + i18n("Import IPTC Metadata")); + return; + } + + QByteArray iptcData = exiv2Iface.getIptc(); + if (iptcData.isEmpty()) + { + KMessageBox::error(kapp->activeWindow(), + i18n("\"%1\" do not have IPTC metadata").arg(importIPTCFile.fileName()), + i18n("Import IPTC Metadata")); + return; + } + + if (KMessageBox::warningYesNo( + kapp->activeWindow(), + i18n("IPTC metadata from current selected pictures will be permanently " + "replaced by the IPTC content of \"%1\".\n" + "Do you want to continue ?").arg(importIPTCFile.fileName()), + i18n("Import IPTC Metadata")) != KMessageBox::Yes) + return; + + + KURL::List imageURLs = images.images(); + KURL::List updatedURLs; + QStringList errorFiles; + + for( KURL::List::iterator it = imageURLs.begin() ; + it != imageURLs.end(); ++it) + { + KURL url = *it; + bool ret = false; + + if (!KExiv2Iface::KExiv2::isReadOnly(url.path())) + { + ret = true; + KExiv2Iface::KExiv2 exiv2Iface; + ret &= exiv2Iface.load(url.path()); + ret &= exiv2Iface.setIptc(iptcData); + ret &= exiv2Iface.save(url.path()); + } + + if (!ret) + errorFiles.append(url.fileName()); + else + updatedURLs.append(url); + } + + // We use kipi interface refreshImages() method to tell to host than + // metadata from pictures have changed and need to be re-read. + + m_interface->refreshImages(updatedURLs); + + if (!errorFiles.isEmpty()) + { + KMessageBox::errorList( + kapp->activeWindow(), + i18n("Unable to set IPTC metadata from:"), + errorFiles, + i18n("Import IPTC Metadata")); + } +} + +void Plugin_MetadataEdit::slotEditComments() +{ + KIPI::ImageCollection images = m_interface->currentSelection(); + + if ( !images.isValid() || images.images().isEmpty() ) + return; + + KIPIMetadataEditPlugin::CommentEditDialog dlg(kapp->activeWindow()); + + if (dlg.exec() != KMessageBox::Ok) + return; + + KURL::List imageURLs = images.images(); + KURL::List updatedURLs; + QStringList errorFiles; + + for( KURL::List::iterator it = imageURLs.begin() ; + it != imageURLs.end(); ++it) + { + KURL url = *it; + bool ret = false; + + KIPI::ImageInfo info = m_interface->info(url); + info.setDescription(dlg.getComments()); + + if (!KExiv2Iface::KExiv2::isReadOnly(url.path())) + { + ret = true; + KExiv2Iface::KExiv2 exiv2Iface; + ret &= exiv2Iface.load(url.path()); + + if (dlg.syncEXIFCommentIsChecked()) + ret &= exiv2Iface.setExifComment(dlg.getComments()); + + if (dlg.syncJFIFCommentIsChecked()) + ret &= exiv2Iface.setComments(dlg.getComments().utf8()); + + if (dlg.syncIPTCCaptionIsChecked()) + ret &= exiv2Iface.setIptcTagString("Iptc.Application2.Caption", dlg.getComments()); + + ret &= exiv2Iface.save(url.path()); + } + + if (!ret) + errorFiles.append(url.fileName()); + else + updatedURLs.append(url); + } + + // We use kipi interface refreshImages() method to tell to host than + // metadata from pictures have changed and need to be re-read. + + m_interface->refreshImages(updatedURLs); + + if (!errorFiles.isEmpty()) + { + KMessageBox::informationList( + kapp->activeWindow(), + i18n("Unable to set captions as image metadata from:"), + errorFiles, + i18n("Edit Image Caption")); + } +} + +void Plugin_MetadataEdit::slotRemoveComments() +{ + KIPI::ImageCollection images = m_interface->currentSelection(); + + if ( !images.isValid() || images.images().isEmpty() ) + return; + + KIPIMetadataEditPlugin::CommentRemoveDialog dlg(kapp->activeWindow()); + + if (dlg.exec() != KMessageBox::Ok) + return; + + KURL::List imageURLs = images.images(); + KURL::List updatedURLs; + QStringList errorFiles; + + for( KURL::List::iterator it = imageURLs.begin() ; + it != imageURLs.end(); ++it) + { + KURL url = *it; + bool ret = false; + + if (dlg.removeHOSTCommentIsChecked()) + { + KIPI::ImageInfo info = m_interface->info(url); + info.setDescription(QString::null); + } + + if (!KExiv2Iface::KExiv2::isReadOnly(url.path())) + { + ret = true; + KExiv2Iface::KExiv2 exiv2Iface; + ret &= exiv2Iface.load(url.path()); + + if (dlg.removeEXIFCommentIsChecked()) + ret &= exiv2Iface.removeExifTag("Exif.Photo.UserComment"); + + if (dlg.removeJFIFCommentIsChecked()) + ret &= exiv2Iface.setComments(QByteArray()); + + if (dlg.removeIPTCCaptionIsChecked()) + ret &= exiv2Iface.removeIptcTag("Iptc.Application2.Caption"); + + ret &= exiv2Iface.save(url.path()); + } + + if (!ret) + errorFiles.append(url.fileName()); + else + updatedURLs.append(url); + } + + // We use kipi interface refreshImages() method to tell to host than + // metadata from pictures have changed and need to be re-read. + + m_interface->refreshImages(updatedURLs); + + if (!errorFiles.isEmpty()) + { + KMessageBox::informationList( + kapp->activeWindow(), + i18n("Unable to remove caption as image metadata from:"), + errorFiles, + i18n("Remove Image Caption")); + } +} + +KIPI::Category Plugin_MetadataEdit::category( KAction* action ) const +{ + if ( action == m_actionMetadataEdit ) + return KIPI::IMAGESPLUGIN; + + kdWarning( 51000 ) << "Unrecognized action for plugin category identification" << endl; + return KIPI::IMAGESPLUGIN; // no warning from compiler, please +} |