summaryrefslogtreecommitdiffstats
path: root/kipi-plugins/metadataedit/plugin_metadataedit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kipi-plugins/metadataedit/plugin_metadataedit.cpp')
-rw-r--r--kipi-plugins/metadataedit/plugin_metadataedit.cpp588
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
+}