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.
589 lines
19 KiB
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
|
|
}
|