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/metadataedit/plugin_metadataedit.cpp

589 lines
19 KiB

/* ============================================================
*
* 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 <tdeconfig.h>
#include <kdebug.h>
#include <kpopupmenu.h>
#include <kmessagebox.h>
#include <tdefiledialog.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(TQObject *parent, const char*, const TQStringList&)
: KIPI::Plugin( Factory::instance(), parent, "MetadataEdit")
{
kdDebug( 51001 ) << "Plugin_MetadataEdit plugin loaded" << endl;
}
void Plugin_MetadataEdit::setup( TQWidget* 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,
TQT_SLOT(slotEditExif()),
actionCollection(),
"editexif"));
m_actionMetadataEdit->insert(new KAction (i18n("Remove EXIF..."),
0,
0,
this,
TQT_SLOT(slotRemoveExif()),
actionCollection(),
"removeexif"));
m_actionMetadataEdit->insert(new KAction (i18n("Import EXIF..."),
0,
0,
this,
TQT_SLOT(slotImportExif()),
actionCollection(),
"importexif"));
m_actionMetadataEdit->popupMenu()->insertSeparator();
m_actionMetadataEdit->insert(new KAction (i18n("Edit IPTC..."),
0,
0,
this,
TQT_SLOT(slotEditIptc()),
actionCollection(),
"editiptc"));
m_actionMetadataEdit->insert(new KAction (i18n("Remove IPTC..."),
0,
0,
this,
TQT_SLOT(slotRemoveIptc()),
actionCollection(),
"removeiptc"));
m_actionMetadataEdit->insert(new KAction (i18n("Import IPTC..."),
0,
0,
this,
TQT_SLOT(slotImportIptc()),
actionCollection(),
"importiptc"));
m_actionMetadataEdit->popupMenu()->insertSeparator();
m_actionMetadataEdit->insert(new KAction (i18n("Edit Captions..."),
0,
0,
this,
TQT_SLOT(slotEditComments()),
actionCollection(),
"editcomments"));
m_actionMetadataEdit->insert(new KAction (i18n("Remove Captions..."),
0,
0,
this,
TQT_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, TQT_SIGNAL(selectionChanged(bool)),
m_actionMetadataEdit, TQT_SLOT(setEnabled(bool)));
}
void Plugin_MetadataEdit::slotEditExif()
{
KIPI::ImageCollection images = m_interface->currentSelection();
if ( !images.isValid() || images.images().isEmpty() )
return;
KIPIMetadataEditPlugin::EXIFEditDialog dialog(TQT_TQWIDGET(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(
TQT_TQWIDGET(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;
TQStringList 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(
TQT_TQWIDGET(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(TDEGlobalSettings::documentPath(),
TQString(), TQT_TQWIDGET(kapp->activeWindow()),
i18n("Select File to Import EXIF metadata") );
if( importEXIFFile.isEmpty() )
return;
KExiv2Iface::KExiv2 exiv2Iface;
if (!exiv2Iface.load(importEXIFFile.path()))
{
KMessageBox::error(TQT_TQWIDGET(kapp->activeWindow()),
i18n("Cannot load metadata from \"%1\"").arg(importEXIFFile.fileName()),
i18n("Import EXIF Metadata"));
return;
}
TQByteArray exifData = exiv2Iface.getExif();
if (exifData.isEmpty())
{
KMessageBox::error(TQT_TQWIDGET(kapp->activeWindow()),
i18n("\"%1\" do not have EXIF metadata").arg(importEXIFFile.fileName()),
i18n("Import EXIF Metadata"));
return;
}
if (KMessageBox::warningYesNo(
TQT_TQWIDGET(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;
TQStringList 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(
TQT_TQWIDGET(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(TQT_TQWIDGET(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(
TQT_TQWIDGET(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;
TQStringList 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(
TQT_TQWIDGET(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(TDEGlobalSettings::documentPath(),
TQString(), TQT_TQWIDGET(kapp->activeWindow()),
i18n("Select File to Import IPTC metadata") );
if( importIPTCFile.isEmpty() )
return;
KExiv2Iface::KExiv2 exiv2Iface;
if (!exiv2Iface.load(importIPTCFile.path()))
{
KMessageBox::error(TQT_TQWIDGET(kapp->activeWindow()),
i18n("Cannot load metadata from \"%1\"").arg(importIPTCFile.fileName()),
i18n("Import IPTC Metadata"));
return;
}
TQByteArray iptcData = exiv2Iface.getIptc();
if (iptcData.isEmpty())
{
KMessageBox::error(TQT_TQWIDGET(kapp->activeWindow()),
i18n("\"%1\" do not have IPTC metadata").arg(importIPTCFile.fileName()),
i18n("Import IPTC Metadata"));
return;
}
if (KMessageBox::warningYesNo(
TQT_TQWIDGET(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;
TQStringList 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(
TQT_TQWIDGET(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(TQT_TQWIDGET(kapp->activeWindow()));
if (dlg.exec() != KMessageBox::Ok)
return;
KURL::List imageURLs = images.images();
KURL::List updatedURLs;
TQStringList 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(
TQT_TQWIDGET(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(TQT_TQWIDGET(kapp->activeWindow()));
if (dlg.exec() != KMessageBox::Ok)
return;
KURL::List imageURLs = images.images();
KURL::List updatedURLs;
TQStringList 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(TQString());
}
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(TQByteArray());
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(
TQT_TQWIDGET(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
}