diff --git a/metadataedit/common/exifeditwidget.cpp b/metadataedit/common/exifeditwidget.cpp
new file mode 100644
index 0000000..d1089f9
--- /dev/null
+++ b/metadataedit/common/exifeditwidget.cpp
@@ -0,0 +1,383 @@
+/* ============================================================
+ *
+ * This file is a part of kipi-plugins project
+ * http://www.kipi-plugins.org
+ *
+ * Date        : 2011-03-14
+ * Description : a KPageWidget to edit EXIF metadata
+ *
+ * Copyright (C) 2006-2010 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.
+ *
+ * ============================================================ */
+
+#include "exifeditwidget.moc"
+
+// Qt includes
+
+#include <QCloseEvent>
+#include <QKeyEvent>
+
+// KDE includes
+
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kdebug.h>
+#include <kguiitem.h>
+#include <khelpmenu.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kmenu.h>
+#include <kmessagebox.h>
+#include <kpushbutton.h>
+#include <ktoolinvocation.h>
+#include <KConfigGroup>
+
+// LibKIPI includes
+
+#include <libkipi/imagecollection.h>
+#include <libkipi/imageinfo.h>
+#include <libkipi/interface.h>
+#include <libkipi/plugin.h>
+
+// LibKExiv2 includes
+
+#include <libkexiv2/version.h>
+#include <libkexiv2/kexiv2.h>
+
+// Local includes
+
+#include "exifadjust.h"
+#include "exifcaption.h"
+#include "exifdatetime.h"
+#include "exifdevice.h"
+#include "exiflens.h"
+#include "exiflight.h"
+#include "kpaboutdata.h"
+#include "pluginsversion.h"
+
+using namespace KExiv2Iface;
+using namespace KIPIPlugins;
+
+namespace KIPIMetadataEditPlugin
+{
+
+class allEXIFEditWidgetPrivate
+{
+
+public:
+
+    allEXIFEditWidgetPrivate()
+    {
+        modified      = false;
+        isReadOnly    = false;
+        interface     = 0;
+
+        about         = 0;
+
+        page_caption  = 0;
+        page_datetime = 0;
+        page_lens     = 0;
+        page_device   = 0;
+        page_light    = 0;
+        page_adjust   = 0;
+
+        captionPage   = 0;
+        datetimePage  = 0;
+        lensPage      = 0;
+        devicePage    = 0;
+        lightPage     = 0;
+        adjustPage    = 0;
+    }
+
+    bool                      modified;
+    bool                      isReadOnly;
+
+    QByteArray                exifData;
+    QByteArray                iptcData;
+    QByteArray                xmpData;
+
+    KPageWidgetItem          *page_caption;
+    KPageWidgetItem          *page_datetime;
+    KPageWidgetItem          *page_lens;
+    KPageWidgetItem          *page_device;
+    KPageWidgetItem          *page_light;
+    KPageWidgetItem          *page_adjust;
+
+    KUrl::List                urls;
+
+    KUrl::List::iterator      currItem;
+
+    EXIFCaption              *captionPage;
+    EXIFDateTime             *datetimePage;
+    EXIFLens                 *lensPage;
+    EXIFDevice               *devicePage;
+    EXIFLight                *lightPage;
+    EXIFAdjust               *adjustPage;
+
+    Interface                *interface;
+
+    KPAboutData              *about;
+};
+
+allEXIFEditWidget::allEXIFEditWidget(QWidget* parent, KUrl::List urls, Interface *iface)
+              : KPageWidget(parent), d(new allEXIFEditWidgetPrivate)
+{
+    d->urls      = urls;
+    d->interface = iface;
+    d->currItem  = d->urls.begin();
+
+    // ---------------------------------------------------------------
+
+    d->captionPage   = new EXIFCaption(this);
+    d->page_caption  = addPage(d->captionPage, i18nc("image caption", "Caption"));
+    d->page_caption->setHeader(i18n("Caption Information"));
+    d->page_caption->setIcon(KIcon("edit-rename"));
+
+    d->datetimePage  = new EXIFDateTime(this);
+    d->page_datetime = addPage(d->datetimePage, i18n("Date & Time"));
+    d->page_datetime->setHeader(i18n("Date and Time Information"));
+    d->page_datetime->setIcon(KIcon("view-calendar-day"));
+
+    d->lensPage      = new EXIFLens(this);
+    d->page_lens     = addPage(d->lensPage, i18n("Lens"));
+    d->page_lens->setHeader(i18n("Lens Settings"));
+    d->page_lens->setIcon(KIcon("camera-photo"));
+
+    d->devicePage    = new EXIFDevice(this);
+    d->page_device   = addPage(d->devicePage, i18n("Device"));
+    d->page_device->setHeader(i18n("Capture Device Settings"));
+    d->page_device->setIcon(KIcon("scanner"));
+
+    d->lightPage     = new EXIFLight(this);
+    d->page_light    = addPage(d->lightPage, i18n("Light"));
+    d->page_light->setHeader(i18n("Light Source Information"));
+    d->page_light->setIcon(KIcon("image-x-generic"));
+
+    d->adjustPage    = new EXIFAdjust(this);
+    d->page_adjust   = addPage(d->adjustPage, i18nc("Picture adjustments", "Adjustments"));
+    d->page_adjust->setHeader(i18n("Pictures Adjustments"));
+    d->page_adjust->setIcon(KIcon("fill-color"));
+
+    // ------------------------------------------------------------
+
+    connect(d->captionPage, SIGNAL(signalModified()),
+            this, SLOT(slotModified()));
+
+    connect(d->datetimePage, SIGNAL(signalModified()),
+            this, SLOT(slotModified()));
+
+    connect(d->lensPage, SIGNAL(signalModified()),
+            this, SLOT(slotModified()));
+
+    connect(d->devicePage, SIGNAL(signalModified()),
+            this, SLOT(slotModified()));
+
+    connect(d->lightPage, SIGNAL(signalModified()),
+            this, SLOT(slotModified()));
+
+    connect(d->adjustPage, SIGNAL(signalModified()),
+            this, SLOT(slotModified()));
+
+    // ------------------------------------------------------------
+
+    readSettings();
+    slotItemChanged();
+}
+
+allEXIFEditWidget::~allEXIFEditWidget()
+{
+    delete d->about;
+    delete d;
+}
+
+void allEXIFEditWidget::slotClose()
+{
+    saveSettings();
+}
+
+void allEXIFEditWidget::readSettings()
+{
+    KConfig config("kipirc");
+    KConfigGroup group = config.group("All Metadata Edit Settings");
+    showPage(group.readEntry("All EXIF Edit Page", 0));
+    d->captionPage->setCheckedSyncJFIFComment(group.readEntry("All Sync JFIF Comment", true));
+    d->captionPage->setCheckedSyncHOSTComment(group.readEntry("All Sync Host Comment", true));
+    d->captionPage->setCheckedSyncXMPCaption(group.readEntry("All Sync XMP Caption", true));
+    d->captionPage->setCheckedSyncIPTCCaption(group.readEntry("All Sync IPTC Caption", true));
+    d->datetimePage->setCheckedSyncHOSTDate(group.readEntry("All Sync Host Date", true));
+    d->datetimePage->setCheckedSyncXMPDate(group.readEntry("All Sync XMP Date", true));
+    d->datetimePage->setCheckedSyncIPTCDate(group.readEntry("All Sync IPTC Date", true));
+}
+
+void allEXIFEditWidget::saveSettings()
+{
+    KConfig config("kipirc");
+    KConfigGroup group = config.group("All Metadata Edit Settings");
+    group.writeEntry("All EXIF Edit Page", activePageIndex());
+    group.writeEntry("All Sync JFIF Comment", d->captionPage->syncJFIFCommentIsChecked());
+    group.writeEntry("All Sync Host Comment", d->captionPage->syncHOSTCommentIsChecked());
+    group.writeEntry("All Sync XMP Caption", d->captionPage->syncXMPCaptionIsChecked());
+    group.writeEntry("All Sync IPTC Caption", d->captionPage->syncIPTCCaptionIsChecked());
+    group.writeEntry("All Sync Host Date", d->datetimePage->syncHOSTDateIsChecked());
+    group.writeEntry("All Sync XMP Date", d->datetimePage->syncXMPDateIsChecked());
+    group.writeEntry("All Sync IPTC Date", d->datetimePage->syncIPTCDateIsChecked());
+    config.sync();
+}
+
+void allEXIFEditWidget::slotItemChanged()
+{
+    KExiv2 exiv2Iface;
+    exiv2Iface.load((*d->currItem).path());
+
+#if KEXIV2_VERSION >= 0x010000
+    d->exifData = exiv2Iface.getExifEncoded();
+#else
+    d->exifData = exiv2Iface.getExif();
+#endif
+
+    d->iptcData = exiv2Iface.getIptc();
+    d->xmpData  = exiv2Iface.getXmp();
+    d->captionPage->readMetadata(d->exifData);
+    d->datetimePage->readMetadata(d->exifData);
+    d->lensPage->readMetadata(d->exifData);
+    d->devicePage->readMetadata(d->exifData);
+    d->lightPage->readMetadata(d->exifData);
+    d->adjustPage->readMetadata(d->exifData);
+
+    d->isReadOnly = !KExiv2::canWriteExif((*d->currItem).path());
+    emit signalSetReadOnly(d->isReadOnly);
+    d->page_caption->setEnabled(!d->isReadOnly);
+    d->page_datetime->setEnabled(!d->isReadOnly);
+    d->page_lens->setEnabled(!d->isReadOnly);
+    d->page_device->setEnabled(!d->isReadOnly);
+    d->page_light->setEnabled(!d->isReadOnly);
+    d->page_adjust->setEnabled(!d->isReadOnly);
+}
+
+void allEXIFEditWidget::slotApply()
+{
+    if (d->modified && !d->isReadOnly)
+    {
+        ImageInfo info = d->interface->info(*d->currItem);
+
+        if (d->captionPage->syncHOSTCommentIsChecked())
+        {
+            info.setDescription(d->captionPage->getEXIFUserComments());
+        }
+        d->captionPage->applyMetadata(d->exifData, d->iptcData, d->xmpData);
+
+        if (d->datetimePage->syncHOSTDateIsChecked())
+        {
+            info.setTime(d->datetimePage->getEXIFCreationDate());
+        }
+        d->datetimePage->applyMetadata(d->exifData, d->iptcData, d->xmpData);
+
+        d->lensPage->applyMetadata(d->exifData);
+        d->devicePage->applyMetadata(d->exifData);
+        d->lightPage->applyMetadata(d->exifData);
+        d->adjustPage->applyMetadata(d->exifData);
+
+        KExiv2 exiv2Iface;
+        exiv2Iface.setWriteRawFiles(d->interface->hostSetting("WriteMetadataToRAW").toBool());
+
+#if KEXIV2_VERSION >= 0x000600
+        exiv2Iface.setUpdateFileTimeStamp(d->interface->hostSetting("WriteMetadataUpdateFiletimeStamp").toBool());
+#endif
+
+        exiv2Iface.load((*d->currItem).path());
+        exiv2Iface.setExif(d->exifData);
+        exiv2Iface.setIptc(d->iptcData);
+        exiv2Iface.setXmp(d->xmpData);
+        exiv2Iface.save((*d->currItem).path());
+
+        d->modified = false;
+    }
+}
+
+void allEXIFEditWidget::slotUser1()
+{
+    slotApply();
+    d->currItem++;
+    slotItemChanged();
+}
+
+void allEXIFEditWidget::slotUser2()
+{
+    slotApply();
+    d->currItem--;
+    slotItemChanged();
+}
+
+void allEXIFEditWidget::slotModified()
+{
+    if (!d->isReadOnly)
+    {
+        d->modified = true;
+        emit signalModified();
+    }
+}
+
+void allEXIFEditWidget::slotOk()
+{
+    slotApply();
+    saveSettings();
+}
+
+void allEXIFEditWidget::showPage(int page)
+{
+    switch(page)
+    {
+        case 0:
+            setCurrentPage(d->page_caption);
+            break;
+        case 1:
+            setCurrentPage(d->page_datetime);
+            break;
+        case 2:
+            setCurrentPage(d->page_lens);
+            break;
+        case 3:
+            setCurrentPage(d->page_device);
+            break;
+        case 4:
+            setCurrentPage(d->page_light);
+            break;
+        case 5:
+            setCurrentPage(d->page_adjust);
+            break;
+        default:
+            setCurrentPage(d->page_caption);
+            break;
+    }
+}
+
+int allEXIFEditWidget::activePageIndex()
+{
+    KPageWidgetItem *cur = currentPage();
+
+    if (cur == d->page_caption)  return 0;
+    if (cur == d->page_datetime) return 1;
+    if (cur == d->page_lens)     return 2;
+    if (cur == d->page_device)   return 3;
+    if (cur == d->page_light)    return 4;
+    if (cur == d->page_adjust)   return 5;
+
+    return 0;
+}
+
+bool allEXIFEditWidget::isModified()
+{
+    return d->modified;
+}
+
+}  // namespace KIPIMetadataEditPlugin
diff --git a/metadataedit/common/exifeditwidget.h b/metadataedit/common/exifeditwidget.h
new file mode 100644
index 0000000..c0e2123
--- /dev/null
+++ b/metadataedit/common/exifeditwidget.h
@@ -0,0 +1,91 @@
+/* ============================================================
+ *
+ * This file is a part of kipi-plugins project
+ * http://www.kipi-plugins.org
+ *
+ * Date        : 2011-03-14
+ * Description : a KPageWidget to edit EXIF metadata
+ *
+ * Copyright (C) 2006-2010 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.
+ *
+ * ============================================================ */
+
+#ifndef EXIFEDITWIDGET_H
+#define EXIFEDITWIDGET_H
+
+// KDE includes
+
+ #include <kpagewidget.h>
+#include <kurl.h>
+
+class QCloseEvent;
+class QEvent;
+class QObject;
+
+namespace KIPI
+{
+    class Interface;
+}
+
+using namespace KIPI;
+
+namespace KIPIMetadataEditPlugin
+{
+
+class allEXIFEditWidgetPrivate;
+
+class allEXIFEditWidget : public KPageWidget
+{
+    Q_OBJECT
+
+public:
+
+    allEXIFEditWidget(QWidget* parent, KUrl::List urls, Interface* iface);
+    ~allEXIFEditWidget();
+    
+    bool isModified();
+
+Q_SIGNALS:
+    void signalSetReadOnly( bool );
+    void signalModified();
+
+public Q_SLOTS:
+
+    void slotModified();
+
+protected Q_SLOTS:
+
+    void slotOk();
+
+private Q_SLOTS:
+    void slotClose();
+    void slotItemChanged();
+    void slotApply();
+    void slotUser1();
+    void slotUser2();
+
+private:
+    void readSettings();
+    void saveSettings();
+
+    int  activePageIndex();
+    void showPage(int page);
+
+private:
+
+    allEXIFEditWidgetPrivate* const d;
+};
+
+}  // namespace KIPIMetadataEditPlugin
+
+#endif /* EXIFEDITDIALOG_H */
diff --git a/metadataedit/common/iptceditwidget.cpp b/metadataedit/common/iptceditwidget.cpp
new file mode 100644
index 0000000..4a5ec86
--- /dev/null
+++ b/metadataedit/common/iptceditwidget.cpp
@@ -0,0 +1,440 @@
+/* ============================================================
+ *
+ * This file is a part of kipi-plugins project
+ * http://www.kipi-plugins.org
+ *
+ * Date        : 2011-03-14
+ * Description : a KPageWidget to edit IPTC metadata
+ *
+ * Copyright (C) 2006-2010 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.
+ *
+ * ============================================================ */
+
+#include "iptceditwidget.moc"
+
+// Qt includes
+
+#include <QCloseEvent>
+#include <QKeyEvent>
+
+// KDE includes
+
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kdebug.h>
+#include <kguiitem.h>
+#include <khelpmenu.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kmenu.h>
+#include <kmessagebox.h>
+#include <kpushbutton.h>
+#include <ktoolinvocation.h>
+
+// LibKIPI includes
+
+#include <libkipi/imagecollection.h>
+#include <libkipi/imageinfo.h>
+#include <libkipi/interface.h>
+#include <libkipi/plugin.h>
+
+// LibKExiv2 includes
+
+#include <libkexiv2/version.h>
+#include <libkexiv2/kexiv2.h>
+
+// Local includes
+
+#include "iptccategories.h"
+#include "iptccontent.h"
+#include "iptccredits.h"
+#include "iptcenvelope.h"
+#include "iptckeywords.h"
+#include "iptcorigin.h"
+#include "iptcproperties.h"
+#include "iptcstatus.h"
+#include "iptcsubjects.h"
+#include "kpaboutdata.h"
+#include "pluginsversion.h"
+
+using namespace KExiv2Iface;
+using namespace KIPIPlugins;
+
+namespace KIPIMetadataEditPlugin
+{
+
+class allIPTCEditWidgetPrivate
+{
+
+public:
+
+    allIPTCEditWidgetPrivate()
+    {
+        modified        = false;
+        isReadOnly      = false;
+        page_content    = 0;
+        page_properties = 0;
+        page_subjects   = 0;
+        page_keywords   = 0;
+        page_categories = 0;
+        page_credits    = 0;
+        page_status     = 0;
+        page_origin     = 0;
+        page_envelope   = 0;
+        about           = 0;
+        contentPage     = 0;
+        propertiesPage  = 0;
+        subjectsPage    = 0;
+        keywordsPage    = 0;
+        categoriesPage  = 0;
+        creditsPage     = 0;
+        statusPage      = 0;
+        originPage      = 0;
+        envelopePage    = 0;
+    }
+
+    bool                  modified;
+    bool                  isReadOnly;
+
+    QByteArray            exifData;
+    QByteArray            iptcData;
+
+    KPageWidgetItem      *page_content;
+    KPageWidgetItem      *page_properties;
+    KPageWidgetItem      *page_subjects;
+    KPageWidgetItem      *page_keywords;
+    KPageWidgetItem      *page_categories;
+    KPageWidgetItem      *page_credits;
+    KPageWidgetItem      *page_status;
+    KPageWidgetItem      *page_origin;
+    KPageWidgetItem      *page_envelope;
+
+    KUrl::List            urls;
+
+    KUrl::List::iterator  currItem;
+
+    IPTCContent          *contentPage;
+    IPTCProperties       *propertiesPage;
+    IPTCSubjects         *subjectsPage;
+    IPTCKeywords         *keywordsPage;
+    IPTCCategories       *categoriesPage;
+    IPTCCredits          *creditsPage;
+    IPTCStatus           *statusPage;
+    IPTCOrigin           *originPage;
+    IPTCEnvelope         *envelopePage;
+
+    Interface            *interface;
+
+    KPAboutData          *about;
+};
+
+allIPTCEditWidget::allIPTCEditWidget(QWidget* parent, KUrl::List urls, Interface* iface)
+              : KPageWidget(parent), d(new allIPTCEditWidgetPrivate)
+{
+    d->urls      = urls;
+    d->interface = iface;
+    d->currItem  = d->urls.begin();
+ 
+    // ---------------------------------------------------------------
+
+    d->contentPage   = new IPTCContent(this);
+    d->page_content  = addPage(d->contentPage, i18n("Content"));
+    d->page_content->setHeader(i18n("<qt>Content Information<br/>"
+                     "<i>Use this panel to describe the visual content of the image</i></qt>"));
+    d->page_content->setIcon(KIcon("help-contents"));
+
+    d->originPage  = new IPTCOrigin(this);
+    d->page_origin = addPage(d->originPage, i18n("Origin"));
+    d->page_origin->setHeader(i18n("<qt>Origin Information<br/>"
+                    "<i>Use this panel for formal descriptive information about the image</i></qt>"));
+    d->page_origin->setIcon(KIcon("applications-internet"));
+
+    d->creditsPage  = new IPTCCredits(this);
+    d->page_credits = addPage(d->creditsPage, i18n("Credits"));
+    d->page_credits->setHeader(i18n("<qt>Credit Information<br/>"
+                     "<i>Use this panel to record copyright information about the image</i></qt>"));
+    d->page_credits->setIcon(KIcon("view-pim-contacts"));
+
+    d->subjectsPage  = new IPTCSubjects(this);
+    d->page_subjects = addPage(d->subjectsPage, i18n("Subjects"));
+    d->page_subjects->setHeader(i18n("<qt>Subject Information<br/>"
+                      "<i>Use this panel to record subject information about the image</i></qt>"));
+    d->page_subjects->setIcon(KIcon("feed-subscribe"));
+
+    d->keywordsPage  = new IPTCKeywords(this);
+    d->page_keywords = addPage(d->keywordsPage, i18n("Keywords"));
+    d->page_keywords->setHeader(i18n("<qt>Keyword Information<br/>"
+                      "<i>Use this panel to record keywords relevant to the image</i></qt>"));
+    d->page_keywords->setIcon(KIcon("bookmarks"));
+
+    d->categoriesPage  = new IPTCCategories(this);
+    d->page_categories = addPage(d->categoriesPage, i18n("Categories"));
+    d->page_categories->setHeader(i18n("<qt>Category Information<br/>"
+                        "<i>Use this panel to record categories relevant to the image</i></qt>"));
+    d->page_categories->setIcon(KIcon("folder-image"));
+
+    d->statusPage  = new IPTCStatus(this);
+    d->page_status = addPage(d->statusPage, i18n("Status"));
+    d->page_status->setHeader(i18n("<qt>Status Information<br/>"
+                    "<i>Use this panel to record workflow information</i></qt>"));
+    d->page_status->setIcon(KIcon("view-pim-tasks"));
+
+    d->propertiesPage  = new IPTCProperties(this);
+    d->page_properties = addPage(d->propertiesPage, i18n("Properties"));
+    d->page_properties->setHeader(i18n("<qt>Status Properties<br/>"
+                      "<i>Use this panel to record workflow properties</i></qt>"));
+    d->page_properties->setIcon(KIcon("draw-freehand"));
+
+    d->envelopePage  = new IPTCEnvelope(this);
+    d->page_envelope = addPage(d->envelopePage, i18n("Envelope"));
+    d->page_envelope->setHeader(i18n("<qt>Envelope Information<br/>"
+                      "<i>Use this panel to record editorial details</i></qt>"));
+    d->page_envelope->setIcon(KIcon("view-pim-mail"));
+
+    // ---------------------------------------------------------------
+
+    connect(d->contentPage, SIGNAL(signalModified()),
+            this, SLOT(slotModified()));
+
+    connect(d->propertiesPage, SIGNAL(signalModified()),
+            this, SLOT(slotModified()));
+
+    connect(d->subjectsPage, SIGNAL(signalModified()),
+            this, SLOT(slotModified()));
+
+    connect(d->keywordsPage, SIGNAL(signalModified()),
+            this, SLOT(slotModified()));
+
+    connect(d->categoriesPage, SIGNAL(signalModified()),
+            this, SLOT(slotModified()));
+
+    connect(d->creditsPage, SIGNAL(signalModified()),
+            this, SLOT(slotModified()));
+
+    connect(d->statusPage, SIGNAL(signalModified()),
+            this, SLOT(slotModified()));
+
+    connect(d->originPage, SIGNAL(signalModified()),
+            this, SLOT(slotModified()));
+
+    connect(d->envelopePage, SIGNAL(signalModified()),
+            this, SLOT(slotModified()));
+
+    // ------------------------------------------------------------
+
+    readSettings();
+    slotItemChanged();
+}
+
+allIPTCEditWidget::~allIPTCEditWidget()
+{
+    delete d->about;
+    delete d;
+}
+
+void allIPTCEditWidget::slotClose()
+{
+    saveSettings();
+}
+
+void allIPTCEditWidget::readSettings()
+{
+    KConfig config("kipirc");
+    KConfigGroup group = config.group("All Metadata Edit Settings");
+    showPage(group.readEntry("All IPTC Edit Page", 0));
+    d->contentPage->setCheckedSyncJFIFComment(group.readEntry("All Sync JFIF Comment", true));
+    d->contentPage->setCheckedSyncHOSTComment(group.readEntry("All Sync Host Comment", true));
+    d->contentPage->setCheckedSyncEXIFComment(group.readEntry("All Sync EXIF Comment", true));
+    d->originPage->setCheckedSyncHOSTDate(group.readEntry("All Sync Host Date", true));
+    d->originPage->setCheckedSyncEXIFDate(group.readEntry("All Sync EXIF Date", true));
+}
+
+void allIPTCEditWidget::saveSettings()
+{
+    KConfig config("kipirc");
+    KConfigGroup group = config.group("All Metadata Edit Settings");
+    group.writeEntry("All IPTC Edit Page", activePageIndex());
+    group.writeEntry("All Sync JFIF Comment", d->contentPage->syncJFIFCommentIsChecked());
+    group.writeEntry("All Sync Host Comment", d->contentPage->syncHOSTCommentIsChecked());
+    group.writeEntry("All Sync EXIF Comment", d->contentPage->syncEXIFCommentIsChecked());
+    group.writeEntry("All Sync Host Date", d->originPage->syncHOSTDateIsChecked());
+    group.writeEntry("All Sync EXIF Date", d->originPage->syncEXIFDateIsChecked());
+    config.sync();
+}
+
+void allIPTCEditWidget::slotItemChanged()
+{
+    KExiv2 exiv2Iface;
+    exiv2Iface.load((*d->currItem).path());
+
+#if KEXIV2_VERSION >= 0x010000
+    d->exifData = exiv2Iface.getExifEncoded();
+#else
+    d->exifData = exiv2Iface.getExif();
+#endif
+
+    d->iptcData = exiv2Iface.getIptc();
+    d->contentPage->readMetadata(d->iptcData);
+    d->originPage->readMetadata(d->iptcData);
+    d->creditsPage->readMetadata(d->iptcData);
+    d->subjectsPage->readMetadata(d->iptcData);
+    d->keywordsPage->readMetadata(d->iptcData);
+    d->categoriesPage->readMetadata(d->iptcData);
+    d->statusPage->readMetadata(d->iptcData);
+    d->propertiesPage->readMetadata(d->iptcData);
+    d->envelopePage->readMetadata(d->iptcData);
+
+    d->isReadOnly = !KExiv2::canWriteIptc((*d->currItem).path());
+    emit signalSetReadOnly(d->isReadOnly);
+    
+    d->page_content->setEnabled(!d->isReadOnly);
+    d->page_origin->setEnabled(!d->isReadOnly);
+    d->page_credits->setEnabled(!d->isReadOnly);
+    d->page_subjects->setEnabled(!d->isReadOnly);
+    d->page_keywords->setEnabled(!d->isReadOnly);
+    d->page_categories->setEnabled(!d->isReadOnly);
+    d->page_status->setEnabled(!d->isReadOnly);
+    d->page_properties->setEnabled(!d->isReadOnly);
+    d->page_envelope->setEnabled(!d->isReadOnly);
+}
+
+void allIPTCEditWidget::slotApply()
+{
+    if (d->modified && !d->isReadOnly)
+    {
+        ImageInfo info = d->interface->info(*d->currItem);
+
+        if (d->contentPage->syncHOSTCommentIsChecked())
+        {
+            info.setDescription(d->contentPage->getIPTCCaption());
+        }
+        d->contentPage->applyMetadata(d->exifData, d->iptcData);
+
+        if (d->originPage->syncHOSTDateIsChecked())
+        {
+            info.setTime(d->originPage->getIPTCCreationDate());
+        }
+        d->originPage->applyMetadata(d->exifData, d->iptcData);
+
+        d->creditsPage->applyMetadata(d->iptcData);
+        d->subjectsPage->applyMetadata(d->iptcData);
+        d->keywordsPage->applyMetadata(d->iptcData);
+        d->categoriesPage->applyMetadata(d->iptcData);
+        d->statusPage->applyMetadata(d->iptcData);
+        d->propertiesPage->applyMetadata(d->iptcData);
+        d->envelopePage->applyMetadata(d->iptcData);
+
+        KExiv2 exiv2Iface;
+        exiv2Iface.setWriteRawFiles(d->interface->hostSetting("WriteMetadataToRAW").toBool());
+
+#if KEXIV2_VERSION >= 0x000600
+        exiv2Iface.setUpdateFileTimeStamp(d->interface->hostSetting("WriteMetadataUpdateFiletimeStamp").toBool());
+#endif
+
+        exiv2Iface.load((*d->currItem).path());
+        exiv2Iface.setExif(d->exifData);
+        exiv2Iface.setIptc(d->iptcData);
+        exiv2Iface.save((*d->currItem).path());
+        d->modified = false;
+    }
+}
+
+void allIPTCEditWidget::slotUser1()
+{
+    slotApply();
+    d->currItem++;
+    slotItemChanged();
+}
+
+void allIPTCEditWidget::slotUser2()
+{
+    slotApply();
+    d->currItem--;
+    slotItemChanged();
+}
+
+void allIPTCEditWidget::slotModified()
+{
+    if (!d->isReadOnly)
+    {
+        d->modified = true;
+        emit signalModified();
+    }
+}
+
+void allIPTCEditWidget::slotOk()
+{
+    slotApply();
+    saveSettings();
+}
+
+void allIPTCEditWidget::showPage(int page)
+{
+    switch(page)
+    {
+        case 0:
+            setCurrentPage(d->page_content);
+            break;
+        case 1:
+            setCurrentPage(d->page_origin);
+            break;
+        case 2:
+            setCurrentPage(d->page_credits);
+            break;
+        case 3:
+            setCurrentPage(d->page_subjects);
+            break;
+        case 4:
+            setCurrentPage(d->page_keywords);
+            break;
+        case 5:
+            setCurrentPage(d->page_categories);
+            break;
+        case 6:
+            setCurrentPage(d->page_status);
+            break;
+        case 7:
+            setCurrentPage(d->page_properties);
+            break;
+        case 8:
+            setCurrentPage(d->page_envelope);
+            break;
+        default:
+            setCurrentPage(d->page_content);
+            break;
+    }
+}
+
+int allIPTCEditWidget::activePageIndex()
+{
+    KPageWidgetItem *cur = currentPage();
+
+    if (cur == d->page_content)    return 0;
+    if (cur == d->page_origin)     return 1;
+    if (cur == d->page_credits)    return 2;
+    if (cur == d->page_subjects)   return 3;
+    if (cur == d->page_keywords)   return 4;
+    if (cur == d->page_categories) return 5;
+    if (cur == d->page_status)     return 6;
+    if (cur == d->page_properties) return 7;
+    if (cur == d->page_envelope)   return 8;
+
+    return 0;
+}
+
+bool allIPTCEditWidget::isModified()
+{
+    return d->modified;
+}
+
+}  // namespace KIPIMetadataEditPlugin
diff --git a/metadataedit/common/iptceditwidget.h b/metadataedit/common/iptceditwidget.h
new file mode 100644
index 0000000..7c493d2
--- /dev/null
+++ b/metadataedit/common/iptceditwidget.h
@@ -0,0 +1,91 @@
+/* ============================================================
+ *
+ * This file is a part of kipi-plugins project
+ * http://www.kipi-plugins.org
+ *
+ * Date        : 2011-03-14
+ * Description : a KPageWidget to edit IPTC metadata
+ *
+ * Copyright (C) 2006-2010 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.
+ *
+ * ============================================================ */
+
+#ifndef IPTCEDITWIDGET_H
+#define IPTCEDITWIDGET_H
+
+// KDE includes
+
+#include <kpagedialog.h>
+#include <kurl.h>
+
+class QCloseEvent;
+class QEvent;
+class QObject;
+
+namespace KIPI
+{
+    class Interface;
+}
+
+using namespace KIPI;
+
+namespace KIPIMetadataEditPlugin
+{
+
+class allIPTCEditWidgetPrivate;
+
+class allIPTCEditWidget : public KPageWidget
+{
+    Q_OBJECT
+
+public:
+
+    allIPTCEditWidget(QWidget* parent, KUrl::List urls, Interface* iface);
+    ~allIPTCEditWidget();
+    
+    bool isModified();
+
+Q_SIGNALS:
+    void signalModified();
+    void signalSetReadOnly( bool );
+
+public Q_SLOTS:
+
+    void slotModified();
+
+protected Q_SLOTS:
+
+    void slotOk();
+    void slotClose();
+
+private Q_SLOTS:
+    void slotItemChanged();
+    void slotApply();
+    void slotUser1();
+    void slotUser2();
+
+private:
+    void readSettings();
+    void saveSettings();
+
+    int  activePageIndex();
+    void showPage(int page);
+
+private:
+
+    allIPTCEditWidgetPrivate* const d;
+};
+
+}  // namespace KIPIMetadataEditPlugin
+
+#endif /* IPTCEDITWIDGET_H */
diff --git a/metadataedit/common/metadataedit.cpp b/metadataedit/common/metadataedit.cpp
new file mode 100644
index 0000000..3bd2aa2
--- /dev/null
+++ b/metadataedit/common/metadataedit.cpp
@@ -0,0 +1,403 @@
+/* ============================================================
+ *
+ * This file is a part of kipi-plugins project
+ * http://www.kipi-plugins.org
+ *
+ * Date        : 2011-03-14
+ * Description : a dialog to edit EXIF,IPTC and XMP metadata
+ *
+ * Copyright (C) 2011 by Dodon Victor <dodonvictor 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.
+ *
+ * ============================================================ */
+
+#include "metadataedit.moc"
+
+// Qt includes
+
+#include <QCloseEvent>
+#include <QKeyEvent>
+#include <QPointer>
+#include <QObject>
+
+// KDE includes
+
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kdebug.h>
+#include <kguiitem.h>
+#include <khelpmenu.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kmenu.h>
+#include <kmessagebox.h>
+#include <kpushbutton.h>
+#include <ktoolinvocation.h>
+#include <ktabwidget.h>
+
+// LibKIPI includes
+
+#include <libkipi/imagecollection.h>
+#include <libkipi/imageinfo.h>
+#include <libkipi/interface.h>
+#include <libkipi/plugin.h>
+
+// LibKExiv2 includes
+
+#include <libkexiv2/version.h>
+#include <libkexiv2/kexiv2.h>
+
+// Local includes
+
+#include "kpaboutdata.h"
+#include "pluginsversion.h"
+#include "exifeditwidget.h"
+#include "iptceditwidget.h"
+#include "xmpeditwidget.h"
+
+using namespace KExiv2Iface;
+using namespace KIPIPlugins;
+
+namespace KIPIMetadataEditPlugin
+{
+
+class MetadataEditDialogPrivate
+{
+public:
+    MetadataEditDialogPrivate()
+    {
+        isReadOnly = false;
+        about = 0;
+        tabWidget = 0;
+        tabExif = 0;
+        tabIptc = 0;
+        tabXmp = 0;
+    }
+    
+    bool isReadOnly;
+    
+    KUrl::List                            urls;
+    KUrl::List::iterator                  currItem;
+    
+    Interface                             *interface;
+    
+    KTabWidget                            *tabWidget;
+    allEXIFEditWidget                     *tabExif;
+    allIPTCEditWidget                     *tabIptc;
+    allXMPEditWidget                      *tabXmp;
+    KPAboutData                           *about;
+    QString                               tabName;
+};
+
+MetadataEditDialog::MetadataEditDialog(QWidget *parent,KUrl::List urls,
+        Interface *iface): KDialog(parent),d(new MetadataEditDialogPrivate)
+{
+    d->urls      = urls;
+    d->interface = iface;
+    d->currItem  = d->urls.begin();
+    
+    this-> setCaption(tr("Metadata edit dialog"));
+    d->tabWidget = new KTabWidget(this);
+    d->tabExif = new allEXIFEditWidget(this, urls, iface);
+    d->tabIptc = new allIPTCEditWidget(this, urls, iface);
+    d->tabXmp = new allXMPEditWidget(this, urls, iface);
+    d->tabWidget->addTab(d->tabExif,QObject::tr("Edit EXIF"));
+    d->tabWidget->addTab(d->tabIptc,QObject::tr("Edit IPTC"));
+    d->tabWidget->addTab(d->tabXmp,QObject::tr("Edit XMP"));
+    
+    setMainWidget(d->tabWidget);
+    setButtons(urls.count() > 1 ? Help|User1|User2|Ok|Apply|Close
+                                   : Help|Ok|Apply|Close);
+    setDefaultButton(Ok);
+    setButtonIcon(User1, KIcon("go-next"));
+    setButtonIcon(User2, KIcon("go-previous"));
+    setButtonText(User1, i18n("Next"));
+    setButtonText(User2, i18n("Previous"));
+    setModal(true);
+    
+    //----------------------------------------------------------
+    
+    connect(d->tabExif,SIGNAL(signalModified()),
+        this,SLOT(slotModified()));
+    
+    connect(d->tabIptc,SIGNAL(signalModified()),
+        this,SLOT(slotModified()));
+    
+    connect(d->tabXmp,SIGNAL(signalModified()),
+        this,SLOT(slotModified()));    
+        
+    connect(this,SIGNAL(applyClicked()),
+        this,SLOT(slotApply()));
+        
+    connect(this,SIGNAL(signalApply()),
+        d->tabExif,SLOT(slotApply()));
+        
+    connect(this,SIGNAL(signalApply()),
+        d->tabIptc,SLOT(slotApply()));
+        
+    connect(this,SIGNAL(signalApply()),
+        d->tabXmp,SLOT(slotApply()));
+        
+    connect(this,SIGNAL(closeClicked()),
+        this,SLOT(slotClose()));
+        
+    connect(this,SIGNAL(signalClose()),
+        d->tabExif,SLOT(slotClose()));
+        
+    connect(this,SIGNAL(signalClose()),
+        d->tabIptc,SLOT(slotClose()));
+    
+    connect(this,SIGNAL(signalClose()),
+        d->tabXmp,SLOT(slotClose()));
+        
+    connect(this,SIGNAL(user1Clicked()),
+        this,SLOT(slotUser1()));
+        
+    connect(this,SIGNAL(signalUser1()),
+        d->tabExif,SLOT(slotUser1()));
+        
+    connect(this,SIGNAL(signalUser1()),
+        d->tabIptc,SLOT(slotUser1()));
+    
+    connect(this,SIGNAL(signalUser1()),
+        d->tabXmp,SLOT(slotUser1()));
+        
+    connect(this,SIGNAL(user2Clicked()),
+        this,SLOT(slotUser2()));
+        
+    connect(this,SIGNAL(signalUser2()),
+        d->tabExif,SLOT(slotUser2()));
+        
+    connect(this,SIGNAL(signalUser2()),
+        d->tabIptc,SLOT(slotUser2()));
+    
+    connect(this,SIGNAL(signalUser2()),
+        d->tabXmp,SLOT(slotUser2()));
+        
+    connect(this,SIGNAL(okClicked()),
+        this,SLOT(slotOk()));
+        
+    connect(this,SIGNAL(signalOk()),
+        d->tabExif,SLOT(slotOk()));
+        
+    connect(this,SIGNAL(signalOk()),
+        d->tabIptc,SLOT(slotOk()));
+    
+    connect(this,SIGNAL(signalOk()),
+        d->tabXmp,SLOT(slotOk()));
+        
+    connect(d->tabExif,SIGNAL(signalSetReadOnly(bool)),
+        this,SLOT(slotSetReadOnly(bool)));
+        
+    connect(d->tabIptc,SIGNAL(signalSetReadOnly(bool)),
+        this,SLOT(slotSetReadOnly(bool)));
+        
+    connect(d->tabXmp,SIGNAL(signalSetReadOnly(bool)),
+        this,SLOT(slotSetReadOnly(bool)));
+        
+    connect(d->tabWidget,SIGNAL(currentChanged(int)),
+        this,SLOT(setWindowTitle(int)));
+    
+    //----------------------------------------------------------
+    
+    enableButton(Apply,false);
+    
+    d->about = new KPAboutData(ki18n("Edit Metadata"),
+                               0,
+                               KAboutData::License_GPL,
+                               ki18n("A Plugin to edit pictures' metadata."),
+                               ki18n("(c) 2006-2010, Gilles Caulier"));
+
+    d->about->addAuthor(ki18n("Gilles Caulier"), ki18n("Author and Maintainer"),
+                        "caulier dot gilles at gmail dot com");
+
+    disconnect(this, SIGNAL(helpClicked()),
+               this, SLOT(slotHelp()));
+
+    KHelpMenu* helpMenu = new KHelpMenu(this, d->about, false);
+    helpMenu->menu()->removeAction(helpMenu->menu()->actions().first());
+    QAction *handbook   = new QAction(i18n("Handbook"), this);
+    connect(handbook, SIGNAL(triggered(bool)),
+            this, SLOT(slotHelp()));
+    helpMenu->menu()->insertAction(helpMenu->menu()->actions().first(), handbook);
+    button(Help)->setMenu(helpMenu->menu());
+    
+    readSettings();
+    slotItemChanged();
+
+}
+
+MetadataEditDialog::~MetadataEditDialog()
+{
+    delete d->about;
+    delete d;
+};
+
+void MetadataEditDialog::slotHelp()
+{
+    KToolInvocation::invokeHelp("metadataeditor", "kipi-plugins");
+}
+
+void MetadataEditDialog::slotClose()
+{
+    emit signalClose();
+    saveSettings();
+    close();
+}
+
+void MetadataEditDialog::slotModified()
+{
+    bool modified=false;
+    
+    switch (d->tabWidget->currentIndex()) {
+    
+        case 0:
+            modified = d->tabExif->isModified();
+            break;
+    
+        case 1:
+            modified = d->tabIptc->isModified();
+            break;
+    
+        case 2:
+            modified = d->tabXmp->isModified();
+            break;
+        }
+    
+    enableButton(Apply,modified);    
+}
+
+void MetadataEditDialog::slotApply()
+{
+    emit signalApply();
+    slotItemChanged();
+}
+
+void MetadataEditDialog::readSettings()
+{
+    KConfig config("kipirc");
+    KConfigGroup group = config.group(QString("Metadata Edit Dialog"));
+    restoreDialogSize(group);
+}
+
+void MetadataEditDialog::saveSettings()
+{
+    KConfig config("kipirc");
+    KConfigGroup group = config.group(QString("Metadata Edit Dialog"));
+    saveDialogSize(group);
+}
+
+void MetadataEditDialog::slotUser1()
+{
+    slotApply();
+    d->currItem++;
+    emit signalUser1();
+    slotItemChanged();
+}
+
+void MetadataEditDialog::slotUser2()
+{
+    slotApply();
+    d->currItem--;
+    emit signalUser2();
+    slotItemChanged();
+}
+
+void MetadataEditDialog::slotItemChanged()
+{
+    enableButton(Apply, !d->isReadOnly);
+    setWindowTitle(d->tabWidget->currentIndex());
+    enableButton(User1, *(d->currItem) != d->urls.last());
+    enableButton(User2, *(d->currItem) != d->urls.first());
+    enableButton(Apply, false);
+}
+
+void MetadataEditDialog::slotOk()
+{
+    slotApply();
+    saveSettings();
+    emit signalOk();
+    accept();
+}
+
+bool MetadataEditDialog::eventFilter(QObject *, QEvent *e)
+{
+    if ( e->type() == QEvent::KeyPress )
+    {
+        QKeyEvent *k = (QKeyEvent *)e;
+
+        if (k->modifiers() == Qt::ControlModifier &&
+            (k->key() == Qt::Key_Enter || k->key() == Qt::Key_Return))
+        {
+            slotApply();
+
+            if (isButtonEnabled(User1))
+                slotUser1();
+
+            return true;
+        }
+        else if (k->modifiers() == Qt::ShiftModifier &&
+                 (k->key() == Qt::Key_Enter || k->key() == Qt::Key_Return))
+        {
+            slotApply();
+
+            if (isButtonEnabled(User2))
+                slotUser2();
+
+            return true;
+        }
+
+        return false;
+    }
+
+    return false;
+}
+
+void MetadataEditDialog::closeEvent(QCloseEvent *e)
+{
+    if (!e) return;
+    saveSettings();
+    e->accept();
+}
+
+void MetadataEditDialog::slotSetReadOnly(bool state)
+{
+    d->isReadOnly = state;
+}
+
+void MetadataEditDialog::setWindowTitle(int tabIndex)
+{
+    switch (tabIndex) { 
+       
+        case 0:
+            d->tabName = "EXIF";
+            break;
+        
+        case 1:
+            d->tabName = "IPTC";
+            break;
+        
+        case 2:
+            d->tabName = "XMP";
+            break;
+    }
+    
+    setCaption(QString("%1 (%2/%3) - %4 %5 %6 ")
+        .arg((*d->currItem).fileName())
+        .arg(d->urls.indexOf(*(d->currItem))+1)
+        .arg(d->urls.count())
+        .arg(i18n("Edit"))
+        .arg(d->tabName)
+        .arg(i18n("Metadata")));
+}
+
+}
diff --git a/metadataedit/common/metadataedit.h b/metadataedit/common/metadataedit.h
new file mode 100644
index 0000000..6704bab
--- /dev/null
+++ b/metadataedit/common/metadataedit.h
@@ -0,0 +1,95 @@
+/* ============================================================
+ *
+ * This file is a part of kipi-plugins project
+ * http://www.kipi-plugins.org
+ *
+ * Date        : 2011-03-14
+ * Description : a dialog to edit EXIF,IPTC and XMP metadata
+ *
+ * Copyright (C) 2011 by Dodon Victor <dodonvictor 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.
+ *
+ * ============================================================ */
+
+#ifndef EDITALLMETADATA_H
+#define EDITALLMETADATA_H
+
+#include <kpagedialog.h>
+#include <kurl.h>
+#include <QObject>
+
+class QObject;
+class QCloseEvent;
+class Event;
+
+namespace KIPI
+{
+    class Interface;
+}
+
+using namespace KIPI;
+
+namespace KIPIMetadataEditPlugin
+{
+
+class MetadataEditDialogPrivate;
+
+class MetadataEditDialog : public KDialog
+{
+    Q_OBJECT
+        
+public:
+    MetadataEditDialog(QWidget *parent,KUrl::List urls,Interface *iface);
+    ~MetadataEditDialog();
+        
+public Q_SLOTS:
+
+    void slotModified();
+
+private Q_SLOTS:
+
+    void slotHelp();
+    void slotOk();
+    void slotClose();
+    void slotItemChanged();
+    void slotApply();
+    void slotUser1();
+    void slotUser2();
+    void slotSetReadOnly(bool);
+    void setWindowTitle(int);
+    
+Q_SIGNALS:
+
+    void signalApply();
+    void signalClose();
+    void signalUser1();
+    void signalUser2();    
+    void signalOk();
+    
+protected:
+
+    void closeEvent(QCloseEvent*);
+    bool eventFilter(QObject*, QEvent*);
+        
+private:
+
+    void saveSettings();
+    void readSettings();
+
+private:
+
+    MetadataEditDialogPrivate* const d;
+};
+
+}  // namespace KIPIMetadataEditPlugin
+
+#endif  /* EDITALLMETADATA_H */
diff --git a/metadataedit/common/xmpeditwidget.cpp b/metadataedit/common/xmpeditwidget.cpp
new file mode 100644
index 0000000..5eae06b
--- /dev/null
+++ b/metadataedit/common/xmpeditwidget.cpp
@@ -0,0 +1,429 @@
+/* ============================================================
+ *
+ * This file is a part of kipi-plugins project
+ * http://www.kipi-plugins.org
+ *
+ * Date        : 2011-10-11
+ * Description : a KPageWidget to edit XMP metadata
+ *
+ * Copyright (C) 2007-2010 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.
+ *
+ * ============================================================ */
+
+#include "xmpeditwidget.moc"
+
+// Qt includes
+
+#include <QCloseEvent>
+#include <QKeyEvent>
+
+// KDE includes
+
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kdebug.h>
+#include <kguiitem.h>
+#include <khelpmenu.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kmenu.h>
+#include <kmessagebox.h>
+#include <kpushbutton.h>
+#include <ktoolinvocation.h>
+
+// LibKIPI includes
+
+#include <libkipi/imagecollection.h>
+#include <libkipi/imageinfo.h>
+#include <libkipi/interface.h>
+#include <libkipi/plugin.h>
+
+// LibKExiv2 includes
+
+#include <libkexiv2/version.h>
+#include <libkexiv2/kexiv2.h>
+
+// Local includes
+
+#include "kpaboutdata.h"
+#include "pluginsversion.h"
+#include "xmpcategories.h"
+#include "xmpcontent.h"
+#include "xmpcredits.h"
+#include "xmpkeywords.h"
+#include "xmporigin.h"
+#include "xmpproperties.h"
+#include "xmpstatus.h"
+#include "xmpsubjects.h"
+
+using namespace KExiv2Iface;
+using namespace KIPIPlugins;
+
+namespace KIPIMetadataEditPlugin
+{
+
+class allXMPEditWidgetPrivate
+{
+
+public:
+
+    allXMPEditWidgetPrivate()
+    {
+        modified        = false;
+        isReadOnly      = false;
+        page_content    = 0;
+        page_properties = 0;
+        page_subjects   = 0;
+        page_keywords   = 0;
+        page_categories = 0;
+        page_credits    = 0;
+        page_status     = 0;
+        page_origin     = 0;
+        about           = 0;
+        keywordsPage    = 0;
+        categoriesPage  = 0;
+        contentPage     = 0;
+        subjectsPage    = 0;
+        originPage      = 0;
+        creditsPage     = 0;
+        statusPage      = 0;
+        propertiesPage  = 0;
+    }
+
+    bool                  modified;
+    bool                  isReadOnly;
+
+    QByteArray            exifData;
+    QByteArray            iptcData;
+    QByteArray            xmpData;
+
+    KPageWidgetItem      *page_content;
+    KPageWidgetItem      *page_origin;
+    KPageWidgetItem      *page_subjects;
+    KPageWidgetItem      *page_keywords;
+    KPageWidgetItem      *page_categories;
+    KPageWidgetItem      *page_credits;
+    KPageWidgetItem      *page_status;
+    KPageWidgetItem      *page_properties;
+
+    KUrl::List            urls;
+
+    KUrl::List::iterator  currItem;
+
+    XMPContent           *contentPage;
+    XMPKeywords          *keywordsPage;
+    XMPCategories        *categoriesPage;
+    XMPSubjects          *subjectsPage;
+    XMPOrigin            *originPage;
+    XMPCredits           *creditsPage;
+    XMPStatus            *statusPage;
+    XMPProperties        *propertiesPage;
+
+    Interface            *interface;
+
+    KPAboutData          *about;
+};
+
+allXMPEditWidget::allXMPEditWidget(QWidget* parent, KUrl::List urls, Interface *iface)
+             : KPageWidget(parent), d(new allXMPEditWidgetPrivate)
+{
+    d->urls      = urls;
+    d->interface = iface;
+    d->currItem  = d->urls.begin();
+
+    // ---------------------------------------------------------------
+
+    d->contentPage   = new XMPContent(this);
+    d->page_content  = addPage(d->contentPage, i18n("Content"));
+    d->page_content->setHeader(i18n("<qt>Content Information<br/>"
+                     "<i>Use this panel to describe the visual content of the image</i></qt>"));
+    d->page_content->setIcon(KIcon("draw-text"));
+
+    d->originPage  = new XMPOrigin(this);
+    d->page_origin = addPage(d->originPage, i18n("Origin"));
+    d->page_origin->setHeader(i18n("<qt>Origin Information<br/>"
+                    "<i>Use this panel for formal descriptive information about the image</i></qt>"));
+    d->page_origin->setIcon(KIcon("document-properties"));
+
+    d->creditsPage  = new XMPCredits(this);
+    d->page_credits = addPage(d->creditsPage, i18n("Credits"));
+    d->page_credits->setHeader(i18n("<qt>Credit Information<br/>"
+                     "<i>Use this panel to record copyright information about the image</i></qt>"));
+    d->page_credits->setIcon(KIcon("view-pim-contacts"));
+
+    d->subjectsPage  = new XMPSubjects(this);
+    d->page_subjects = addPage(d->subjectsPage, i18n("Subjects"));
+    d->page_subjects->setHeader(i18n("<qt>Subject Information<br/>"
+                      "<i>Use this panel to record subject information about the image</i></qt>"));
+    d->page_subjects->setIcon(KIcon("feed-subscribe"));
+
+    d->keywordsPage  = new XMPKeywords(this);
+    d->page_keywords = addPage(d->keywordsPage, i18n("Keywords"));
+    d->page_keywords->setHeader(i18n("<qt>Keyword Information<br/>"
+                      "<i>Use this panel to record keywords relevant to the image</i></qt>"));
+    d->page_keywords->setIcon(KIcon("bookmarks"));
+
+    d->categoriesPage  = new XMPCategories(this);
+    d->page_categories = addPage(d->categoriesPage, i18n("Categories"));
+    d->page_categories->setHeader(i18n("<qt>Category Information<br/>"
+                        "<i>Use this panel to record categories relevant to the image</i></qt>"));
+    d->page_categories->setIcon(KIcon("folder"));
+
+    d->statusPage  = new XMPStatus(this);
+    d->page_status = addPage(d->statusPage, i18n("Status"));
+    d->page_status->setHeader(i18n("<qt>Status Information<br/>"
+                    "<i>Use this panel to record workflow information</i></qt>"));
+    d->page_status->setIcon(KIcon("view-pim-tasks"));
+
+    d->propertiesPage  = new XMPProperties(this);
+    d->page_properties = addPage(d->propertiesPage, i18n("Properties"));
+    d->page_properties->setHeader(i18n("<qt>Status Properties<br/>"
+                      "<i>Use this panel to record workflow properties</i></qt>"));
+    d->page_properties->setIcon(KIcon("draw-freehand"));
+
+    // ------------------------------------------------------------
+
+    connect(d->contentPage, SIGNAL(signalModified()),
+            this, SLOT(slotModified()));
+
+    connect(d->propertiesPage, SIGNAL(signalModified()),
+            this, SLOT(slotModified()));
+
+    connect(d->originPage, SIGNAL(signalModified()),
+            this, SLOT(slotModified()));
+
+    connect(d->subjectsPage, SIGNAL(signalModified()),
+            this, SLOT(slotModified()));
+
+    connect(d->keywordsPage, SIGNAL(signalModified()),
+            this, SLOT(slotModified()));
+
+    connect(d->categoriesPage, SIGNAL(signalModified()),
+            this, SLOT(slotModified()));
+
+    connect(d->creditsPage, SIGNAL(signalModified()),
+            this, SLOT(slotModified()));
+
+    connect(d->statusPage, SIGNAL(signalModified()),
+            this, SLOT(slotModified()));
+
+    // ------------------------------------------------------------
+
+    readSettings();
+    slotItemChanged();
+}
+
+allXMPEditWidget::~allXMPEditWidget()
+{
+    delete d->about;
+    delete d;
+}
+
+void allXMPEditWidget::slotClose()
+{
+    saveSettings();
+}
+
+void allXMPEditWidget::readSettings()
+{
+    KConfig config("kipirc");
+    KConfigGroup group = config.group("All Metadata Edit Settings");
+
+    showPage(group.readEntry("All XMP Edit Page", 0));
+    d->contentPage->setCheckedSyncJFIFComment(group.readEntry("All Sync JFIF Comment", true));
+    d->contentPage->setCheckedSyncHOSTComment(group.readEntry("All Sync Host Comment", true));
+    d->contentPage->setCheckedSyncEXIFComment(group.readEntry("All Sync EXIF Comment", true));
+    d->originPage->setCheckedSyncHOSTDate(group.readEntry("All Sync Host Date", true));
+    d->originPage->setCheckedSyncEXIFDate(group.readEntry("All Sync EXIF Date", true));
+
+    KConfigGroup group2 = config.group(QString("All XMP Edit Dialog"));
+}
+
+void allXMPEditWidget::saveSettings()
+{
+    KConfig config("kipirc");
+    KConfigGroup group = config.group("All Metadata Edit Settings");
+
+    group.writeEntry("All XMP Edit Page", activePageIndex());
+    group.writeEntry("All Sync JFIF Comment", d->contentPage->syncJFIFCommentIsChecked());
+    group.writeEntry("All Sync Host Comment", d->contentPage->syncHOSTCommentIsChecked());
+    group.writeEntry("All Sync EXIF Comment", d->contentPage->syncEXIFCommentIsChecked());
+    group.writeEntry("All Sync Host Date", d->originPage->syncHOSTDateIsChecked());
+    group.writeEntry("All Sync EXIF Date", d->originPage->syncEXIFDateIsChecked());
+
+    KConfigGroup group2 = config.group(QString("All XMP Edit Dialog"));
+    config.sync();
+}
+
+void allXMPEditWidget::slotItemChanged()
+{
+    KExiv2 exiv2Iface;
+    exiv2Iface.load((*d->currItem).path());
+
+#if KEXIV2_VERSION >= 0x010000
+    d->exifData = exiv2Iface.getExifEncoded();
+#else
+    d->exifData = exiv2Iface.getExif();
+#endif
+
+    d->iptcData = exiv2Iface.getIptc();
+    d->xmpData  = exiv2Iface.getXmp();
+
+    d->contentPage->readMetadata(d->xmpData);
+    d->originPage->readMetadata(d->xmpData);
+    d->subjectsPage->readMetadata(d->xmpData);
+    d->keywordsPage->readMetadata(d->xmpData);
+    d->categoriesPage->readMetadata(d->xmpData);
+    d->creditsPage->readMetadata(d->xmpData);
+    d->statusPage->readMetadata(d->xmpData);
+    d->propertiesPage->readMetadata(d->xmpData);
+    d->isReadOnly = !KExiv2::canWriteXmp((*d->currItem).path());
+    emit signalSetReadOnly(d->isReadOnly);
+
+    d->page_content->setEnabled(!d->isReadOnly);
+    d->page_origin->setEnabled(!d->isReadOnly);
+    d->page_subjects->setEnabled(!d->isReadOnly);
+    d->page_keywords->setEnabled(!d->isReadOnly);
+    d->page_categories->setEnabled(!d->isReadOnly);
+    d->page_credits->setEnabled(!d->isReadOnly);
+    d->page_status->setEnabled(!d->isReadOnly);
+    d->page_properties->setEnabled(!d->isReadOnly);
+
+}
+
+void allXMPEditWidget::slotApply()
+{
+    if (d->modified && !d->isReadOnly)
+    {
+        ImageInfo info = d->interface->info(*d->currItem);
+
+        if (d->contentPage->syncHOSTCommentIsChecked())
+        {
+            info.setDescription(d->contentPage->getXMPCaption());
+        }
+        d->contentPage->applyMetadata(d->exifData, d->xmpData);
+
+        if (d->originPage->syncHOSTDateIsChecked())
+        {
+            info.setTime(d->originPage->getXMPCreationDate());
+        }
+        d->originPage->applyMetadata(d->exifData, d->xmpData);
+
+        d->subjectsPage->applyMetadata(d->xmpData);
+        d->keywordsPage->applyMetadata(d->xmpData);
+        d->categoriesPage->applyMetadata(d->xmpData);
+        d->creditsPage->applyMetadata(d->xmpData);
+        d->statusPage->applyMetadata(d->xmpData);
+        d->propertiesPage->applyMetadata(d->xmpData);
+
+        KExiv2 exiv2Iface;
+        exiv2Iface.setWriteRawFiles(d->interface->hostSetting("WriteMetadataToRAW").toBool());
+
+#if KEXIV2_VERSION >= 0x000600
+        exiv2Iface.setUpdateFileTimeStamp(d->interface->hostSetting("WriteMetadataUpdateFiletimeStamp").toBool());
+#endif
+
+        exiv2Iface.load((*d->currItem).path());
+        exiv2Iface.setExif(d->exifData);
+        exiv2Iface.setIptc(d->iptcData);
+        exiv2Iface.setXmp(d->xmpData);
+        exiv2Iface.save((*d->currItem).path());
+        d->modified = false;
+    }
+}
+
+void allXMPEditWidget::slotUser1()
+{
+    slotApply();
+    d->currItem++;
+    slotItemChanged();
+}
+
+void allXMPEditWidget::slotUser2()
+{
+    slotApply();
+    d->currItem--;
+    slotItemChanged();
+}
+
+void allXMPEditWidget::slotModified()
+{
+    if (!d->isReadOnly)
+    {
+        d->modified = true;
+        emit signalModified();
+    }
+}
+
+void allXMPEditWidget::slotOk()
+{
+    slotApply();
+    saveSettings();
+}
+
+void allXMPEditWidget::showPage(int page)
+{
+    switch(page)
+    {
+        case 0:
+            setCurrentPage(d->page_content);
+            break;
+        case 1:
+            setCurrentPage(d->page_origin);
+            break;
+        case 2:
+            setCurrentPage(d->page_credits);
+            break;
+        case 3:
+            setCurrentPage(d->page_subjects);
+            break;
+        case 4:
+            setCurrentPage(d->page_keywords);
+            break;
+        case 5:
+            setCurrentPage(d->page_categories);
+            break;
+        case 6:
+            setCurrentPage(d->page_status);
+            break;
+        case 7:
+            setCurrentPage(d->page_properties);
+            break;
+        default:
+            setCurrentPage(d->page_content);
+            break;
+    }
+}
+
+int allXMPEditWidget::activePageIndex()
+{
+    KPageWidgetItem *cur = currentPage();
+
+    if (cur == d->page_content)    return 0;
+    if (cur == d->page_origin)     return 1;
+    if (cur == d->page_credits)    return 2;
+    if (cur == d->page_subjects)   return 3;
+    if (cur == d->page_keywords)   return 4;
+    if (cur == d->page_categories) return 5;
+    if (cur == d->page_status)     return 6;
+    if (cur == d->page_properties) return 7;
+
+    return 0;
+}
+
+bool allXMPEditWidget::isModified()
+{
+    return d->modified;
+}
+
+}  // namespace KIPIMetadataEditPlugin
diff --git a/metadataedit/common/xmpeditwidget.h b/metadataedit/common/xmpeditwidget.h
new file mode 100644
index 0000000..d260823
--- /dev/null
+++ b/metadataedit/common/xmpeditwidget.h
@@ -0,0 +1,92 @@
+/* ============================================================
+ *
+ * This file is a part of kipi-plugins project
+ * http://www.kipi-plugins.org
+ *
+ * Date        : 2011-03-14
+ * Description : a KPageWidget to edit XMP metadata
+ *
+ * Copyright (C) 2007-2010 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.
+ *
+ * ============================================================ */
+
+#ifndef ALLXMPEDITWIDGET_H
+#define ALLXMPEDITWIDGET_H
+
+// KDE includes
+
+#include <kpagedialog.h>
+#include <kurl.h>
+
+class QCloseEvent;
+class QEvent;
+class QObject;
+
+namespace KIPI
+{
+    class Interface;
+}
+
+using namespace KIPI;
+
+namespace KIPIMetadataEditPlugin
+{
+
+class allXMPEditWidgetPrivate;
+
+class allXMPEditWidget : public KPageWidget
+{
+    Q_OBJECT
+
+public:
+
+    allXMPEditWidget(QWidget* parent, KUrl::List urls, Interface *iface);
+    ~allXMPEditWidget();
+    
+    bool isModified();
+
+Q_SIGNALS:
+    void signalModified();
+    void signalSetReadOnly( bool );
+
+public Q_SLOTS:
+
+    void slotModified();
+
+protected Q_SLOTS:
+
+    void slotOk();
+    void slotClose();
+
+private Q_SLOTS:
+
+    void slotItemChanged();
+    void slotApply();
+    void slotUser1();
+    void slotUser2();
+
+private:
+    void readSettings();
+    void saveSettings();
+
+    int  activePageIndex();
+    void showPage(int page);
+
+private:
+
+    allXMPEditWidgetPrivate* const d;
+};
+
+}  // namespace KIPIMetadataEditPlugin
+
+#endif /* ALLXMPEDITWIDGET_H */
diff --git a/metadataedit/common_backup/altlangstringedit.cpp b/metadataedit/common_backup/altlangstringedit.cpp
new file mode 100644
index 0000000..c6eac7d
--- /dev/null
+++ b/metadataedit/common_backup/altlangstringedit.cpp
@@ -0,0 +1,596 @@
+/* ============================================================
+ *
+ * This file is a part of kipi-plugins project
+ * http://www.kipi-plugins.org
+ *
+ * Date        : 2007-10-18
+ * Description : a widget to edit a tag with multiple alternative
+ *               language string entries.
+ *
+ * Copyright (C) 2007-2010 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.
+ *
+ * ============================================================ */
+
+#include "altlangstringedit.moc"
+
+// Qt includes
+
+#include <QCheckBox>
+#include <QLabel>
+#include <QMap>
+#include <QPushButton>
+#include <QGridLayout>
+
+// KDE includes
+
+#include <kdialog.h>
+#include <kglobal.h>
+#include <kiconloader.h>
+#include <klistwidget.h>
+#include <klocale.h>
+#include <ktextedit.h>
+
+// LibKDcraw includes
+
+#include <libkdcraw/squeezedcombobox.h>
+
+// Local includes
+
+#include "metadatacheckbox.h"
+
+using namespace KDcrawIface;
+
+namespace KIPIMetadataEditPlugin
+{
+
+class AltLangStringsEditPriv
+{
+public:
+
+    AltLangStringsEditPriv()
+    {
+        addValueButton = 0;
+        delValueButton = 0;
+        repValueButton = 0;
+        valueBox       = 0;
+        valueCheck     = 0;
+        languageCB     = 0;
+
+        // We cannot use KLocale::allLanguagesList() here because KDE only
+        // support 2 characters country codes. XMP require 2+2 characters language+country
+        // following ISO 3066 (http://babelwiki.babelzilla.org/index.php?title=Language_codes)
+
+        // The first one from the list is the Default Language code specified by XMP paper
+        languageCodeMap.insert( "x-default", i18n("Default Language") );
+
+        // Standard ISO 3066 country codes.
+
+        languageCodeMap.insert( "af-ZA", i18n("Afrikaans (South Africa)") );
+        languageCodeMap.insert( "am-ET", i18n("Amharic (Ethiopia)") );
+        languageCodeMap.insert( "ar-AE", i18n("Arabic (UAE)") );
+        languageCodeMap.insert( "ar-BH", i18n("Arabic (Bahrain)") );
+        languageCodeMap.insert( "ar-DZ", i18n("Arabic (Algeria)") );
+        languageCodeMap.insert( "ar-EG", i18n("Arabic (Egypt)") );
+        languageCodeMap.insert( "ar-IQ", i18n("Arabic (Iraq)") );
+        languageCodeMap.insert( "ar-JO", i18n("Arabic (Jordan)") );
+        languageCodeMap.insert( "ar-KW", i18n("Arabic (Kuwait)") );
+        languageCodeMap.insert( "ar-LB", i18n("Arabic (Lebanon)") );
+        languageCodeMap.insert( "ar-LY", i18n("Arabic (Libya)") );
+        languageCodeMap.insert( "ar-MA", i18n("Arabic (Morocco)") );
+        languageCodeMap.insert( "ar-OM", i18n("Arabic (Oman)") );
+        languageCodeMap.insert( "ar-QA", i18n("Arabic (Qatar)") );
+        languageCodeMap.insert( "ar-SA", i18n("Arabic (Saudi Arabia)") );
+        languageCodeMap.insert( "ar-SY", i18n("Arabic (Syria)") );
+        languageCodeMap.insert( "ar-TN", i18n("Arabic (Tunisia)") );
+        languageCodeMap.insert( "ar-YE", i18n("Arabic (Yemen)") );
+        languageCodeMap.insert( "as-IN", i18n("Assamese (India)") );
+        languageCodeMap.insert( "ba-RU", i18n("Bashkir (Russia)") );
+        languageCodeMap.insert( "be-BY", i18n("Belarusian (Belarus)") );
+        languageCodeMap.insert( "bg-BG", i18n("Bulgarian (Bulgaria)") );
+        languageCodeMap.insert( "bn-IN", i18n("Bengali (India)") );
+        languageCodeMap.insert( "bo-BT", i18n("Tibetan (Bhutan)") );
+        languageCodeMap.insert( "bo-CN", i18n("Tibetan (PRC)") );
+        languageCodeMap.insert( "br-FR", i18n("Breton (France)") );
+        languageCodeMap.insert( "ca-AD", i18n("Catalan (Andorra)") );
+        languageCodeMap.insert( "ca-ES", i18n("Catalan (Spain)") );
+        languageCodeMap.insert( "ca-FR", i18n("Catalan (France)") );
+        languageCodeMap.insert( "co-FR", i18n("Corsican (France)") );
+        languageCodeMap.insert( "cs-CZ", i18n("Czech (Czech Republic)") );
+        languageCodeMap.insert( "cy-GB", i18n("Welsh (United Kingdom)") );
+        languageCodeMap.insert( "da-DK", i18n("Danish (Denmark)") );
+        languageCodeMap.insert( "de-AT", i18n("German (Austria)") );
+        languageCodeMap.insert( "de-CH", i18n("German (Switzerland)") );
+        languageCodeMap.insert( "de-DE", i18n("German (Germany)") );
+        languageCodeMap.insert( "de-LI", i18n("German (Liechtenstein)") );
+        languageCodeMap.insert( "de-LU", i18n("German (Luxembourg)") );
+        languageCodeMap.insert( "el-GR", i18n("Greek (Greece)") );
+        languageCodeMap.insert( "en-AU", i18n("English (Australia)") );
+        languageCodeMap.insert( "en-BZ", i18n("English (Belize)") );
+        languageCodeMap.insert( "en-CA", i18n("English (Canada)") );
+        languageCodeMap.insert( "en-CB", i18n("English (Caribbean)") );
+        languageCodeMap.insert( "en-GB", i18n("English (United Kingdom)") );
+        languageCodeMap.insert( "en-IE", i18n("English (Ireland)") );
+        languageCodeMap.insert( "en-IN", i18n("English (India)") );
+        languageCodeMap.insert( "en-JA", i18n("English (Jamaica)") );
+        languageCodeMap.insert( "en-MY", i18n("English (Malaysia)") );
+        languageCodeMap.insert( "en-NZ", i18n("English (New Zealand)") );
+        languageCodeMap.insert( "en-PH", i18n("English (Philippines)") );
+        languageCodeMap.insert( "en-SG", i18n("English (Singapore)") );
+        languageCodeMap.insert( "en-TT", i18n("English (Trinidad)") );
+        languageCodeMap.insert( "en-US", i18n("English (United States)") );
+        languageCodeMap.insert( "en-ZA", i18n("English (South Africa)") );
+        languageCodeMap.insert( "en-ZW", i18n("English (Zimbabwe)") );
+        languageCodeMap.insert( "es-AR", i18n("Spanish (Argentina)") );
+        languageCodeMap.insert( "es-BO", i18n("Spanish (Bolivia)") );
+        languageCodeMap.insert( "es-CL", i18n("Spanish (Chile)") );
+        languageCodeMap.insert( "es-CO", i18n("Spanish (Colombia)") );
+        languageCodeMap.insert( "es-CR", i18n("Spanish (Costa Rica)") );
+        languageCodeMap.insert( "es-DO", i18n("Spanish (Dominican Republic)") );
+        languageCodeMap.insert( "es-EC", i18n("Spanish (Ecuador)") );
+        languageCodeMap.insert( "es-ES", i18n("Spanish (Spain)") );
+        languageCodeMap.insert( "es-GT", i18n("Spanish (Guatemala)") );
+        languageCodeMap.insert( "es-HN", i18n("Spanish (Honduras)") );
+        languageCodeMap.insert( "es-MX", i18n("Spanish (Mexico)") );
+        languageCodeMap.insert( "es-NI", i18n("Spanish (Nicaragua)") );
+        languageCodeMap.insert( "es-PA", i18n("Spanish (Panama)") );
+        languageCodeMap.insert( "es-PE", i18n("Spanish (Peru)") );
+        languageCodeMap.insert( "es-PR", i18n("Spanish (Puerto Rico)") );
+        languageCodeMap.insert( "es-PY", i18n("Spanish (Paraguay)") );
+        languageCodeMap.insert( "es-SV", i18n("Spanish (El Salvador)") );
+        languageCodeMap.insert( "es-UR", i18n("Spanish (Uruguay)") );
+        languageCodeMap.insert( "es-US", i18n("Spanish (United States)") );
+        languageCodeMap.insert( "es-VE", i18n("Spanish (Venezuela)") );
+        languageCodeMap.insert( "et-EE", i18n("Estonian (Estonia)") );
+        languageCodeMap.insert( "eu-ES", i18n("Basque (Basque Country)") );
+        languageCodeMap.insert( "fa-IR", i18n("Persian (Iran)") );
+        languageCodeMap.insert( "fi-FI", i18n("Finnish (Finland)") );
+        languageCodeMap.insert( "fo-FO", i18n("Faeroese (Faero Islands)") );
+        languageCodeMap.insert( "fr-BE", i18n("French (Belgium)") );
+        languageCodeMap.insert( "fr-CA", i18n("French (Canada)") );
+        languageCodeMap.insert( "fr-CH", i18n("French (Switzerland)") );
+        languageCodeMap.insert( "fr-FR", i18n("French (France)") );
+        languageCodeMap.insert( "fr-LU", i18n("French (Luxembourg)") );
+        languageCodeMap.insert( "fr-MC", i18n("French (Monaco)") );
+        languageCodeMap.insert( "fy-NL", i18n("Frisian (Netherlands)") );
+        languageCodeMap.insert( "ga-IE", i18n("Irish (Ireland)") );
+        languageCodeMap.insert( "gl-ES", i18n("Galician (Galicia)") );
+        languageCodeMap.insert( "gu-IN", i18n("Gujarati (India)") );
+        languageCodeMap.insert( "he-IL", i18n("Hebrew (Israel)") );
+        languageCodeMap.insert( "hi-IN", i18n("Hindi (India)") );
+        languageCodeMap.insert( "hr-BA", i18n("Croatian (Bosnia and Herzegovina, Latin)") );
+        languageCodeMap.insert( "hr-HR", i18n("Croatian (Croatia)") );
+        languageCodeMap.insert( "hu-HU", i18n("Hungarian (Hungary)") );
+        languageCodeMap.insert( "hy-AM", i18n("Armenian (Armenia)") );
+        languageCodeMap.insert( "id-ID", i18n("(Indonesian)") );
+        languageCodeMap.insert( "ii-CN", i18n("Yi (PRC)") );
+        languageCodeMap.insert( "is-IS", i18n("Icelandic (Iceland)") );
+        languageCodeMap.insert( "it-CH", i18n("Italian (Switzerland)") );
+        languageCodeMap.insert( "it-IT", i18n("Italian (Italy)") );
+        languageCodeMap.insert( "ja-JP", i18n("Japanese (Japan)") );
+        languageCodeMap.insert( "ka-GE", i18n("Georgian (Georgia)") );
+        languageCodeMap.insert( "kk-KZ", i18n("Kazakh (Kazakhstan)") );
+        languageCodeMap.insert( "kl-GL", i18n("Greenlandic (Greenland)") );
+        languageCodeMap.insert( "km-KH", i18n("Khmer (Cambodia)") );
+        languageCodeMap.insert( "kn-IN", i18n("Kannada (India)") );
+        languageCodeMap.insert( "ko-KR", i18n("Korean (South Korea)") );
+        languageCodeMap.insert( "ky-KG", i18n("Kyrgyz (Kyrgyzstan)") );
+        languageCodeMap.insert( "lb-LU", i18n("Luxembourgish (Luxembourg)") );
+        languageCodeMap.insert( "lo-LA", i18n("Lao (Lao PDR)") );
+        languageCodeMap.insert( "lt-LT", i18n("Lithuanian (Lithuania)") );
+        languageCodeMap.insert( "lv-LV", i18n("Latvian (Latvia)") );
+        languageCodeMap.insert( "mi-NZ", i18n("Maori (New Zealand)") );
+        languageCodeMap.insert( "mk-MK", i18n("Macedonian (Macedonia)") );
+        languageCodeMap.insert( "ml-IN", i18n("Malayalam (India)") );
+        languageCodeMap.insert( "mn-CN", i18n("Mongolian (PRC)") );
+        languageCodeMap.insert( "mn-MN", i18n("Mongolian (Mongolia)") );
+        languageCodeMap.insert( "mr-IN", i18n("Marathi (India)") );
+        languageCodeMap.insert( "ms-BN", i18n("Malay (Brunei Darussalam)") );
+        languageCodeMap.insert( "ms-MY", i18n("Malay (Malaysia)") );
+        languageCodeMap.insert( "mt-MT", i18n("Maltese (Malta)") );
+        languageCodeMap.insert( "nb-NO", i18n("Norwegian Bokmål (Norway)") );
+        languageCodeMap.insert( "ne-NP", i18n("Nepali (Nepal)") );
+        languageCodeMap.insert( "nl-BE", i18n("Dutch (Belgium)") );
+        languageCodeMap.insert( "nl-NL", i18n("Dutch (Netherlands)") );
+        languageCodeMap.insert( "nn-NO", i18n("Norwegian Nynorsk (Norway)") );
+        languageCodeMap.insert( "ns-ZA", i18n("Sesotho sa Leboa (South Africa)") );
+        languageCodeMap.insert( "oc-FR", i18n("Occitan (France)") );
+        languageCodeMap.insert( "or-IN", i18n("Oriya (India)") );
+        languageCodeMap.insert( "pa-IN", i18n("Punjabi (India)") );
+        languageCodeMap.insert( "pl-PL", i18n("Polish (Poland)") );
+        languageCodeMap.insert( "ps-AF", i18n("Pashto (Afghanistan)") );
+        languageCodeMap.insert( "pt-BR", i18n("Portuguese (Brazil)") );
+        languageCodeMap.insert( "pt-PT", i18n("Portuguese (Portugal)") );
+        languageCodeMap.insert( "rm-CH", i18n("Romansh (Switzerland)") );
+        languageCodeMap.insert( "ro-RO", i18n("Romanian (Romania)") );
+        languageCodeMap.insert( "ru-RU", i18n("Russian (Russia)") );
+        languageCodeMap.insert( "rw-RW", i18n("Kinyarwanda (Rwanda)") );
+        languageCodeMap.insert( "sa-IN", i18n("Sanskrit (India)") );
+        languageCodeMap.insert( "se-FI", i18n("Sami (Northern, Finland)") );
+        languageCodeMap.insert( "se-NO", i18n("Sami (Northern, Norway)") );
+        languageCodeMap.insert( "se-SE", i18n("Sami (Northern, Sweden)") );
+        languageCodeMap.insert( "si-LK", i18n("Sinhala (Sri Lanka)") );
+        languageCodeMap.insert( "sk-SK", i18n("Slovak (Slovakia)") );
+        languageCodeMap.insert( "sl-SI", i18n("Slovenian (Slovenia)") );
+        languageCodeMap.insert( "sq-AL", i18n("Albanian (Albania)") );
+        languageCodeMap.insert( "sv-FI", i18n("Swedish (Finland)") );
+        languageCodeMap.insert( "sv-SE", i18n("Swedish (Sweden)") );
+        languageCodeMap.insert( "sw-KE", i18n("Swahili (Kenya)") );
+        languageCodeMap.insert( "ta-IN", i18n("Tamil (India)") );
+        languageCodeMap.insert( "te-IN", i18n("Telugu (India)") );
+        languageCodeMap.insert( "th-TH", i18n("Thai (Thailand)") );
+        languageCodeMap.insert( "tk-TM", i18n("Turkmen (Turkmenistan)") );
+        languageCodeMap.insert( "tn-ZA", i18n("Setswana Tswana (South Africa)") );
+        languageCodeMap.insert( "tr-IN", i18n("Urdu (India)") );
+        languageCodeMap.insert( "tr-TR", i18n("Turkish (Turkey)") );
+        languageCodeMap.insert( "tt-RU", i18n("Tatar (Russia)") );
+        languageCodeMap.insert( "ug-CN", i18n("Uighur (PRC)") );
+        languageCodeMap.insert( "uk-UA", i18n("Ukrainian (Ukraine)") );
+        languageCodeMap.insert( "ur-PK", i18n("Urdu (Pakistan)") );
+        languageCodeMap.insert( "vi-VN", i18n("Vietnamese (Vietnam)") );
+        languageCodeMap.insert( "wo-SN", i18n("Wolof (Senegal)") );
+        languageCodeMap.insert( "xh-ZA", i18n("isiXhosa Xhosa (South Africa)") );
+        languageCodeMap.insert( "yo-NG", i18n("Yoruba (Nigeria)") );
+        languageCodeMap.insert( "zh-CN", i18n("Chinese (PRC)") );
+        languageCodeMap.insert( "zh-HK", i18n("Chinese (Hong Kong SAR, PRC)") );
+        languageCodeMap.insert( "zh-MO", i18n("Chinese (Macao SAR)") );
+        languageCodeMap.insert( "zh-SG", i18n("Chinese (Singapore)") );
+        languageCodeMap.insert( "zh-TW", i18n("Chinese (Taiwan)") );
+        languageCodeMap.insert( "zu-ZA", i18n("isiZulu Zulu (South Africa)") );
+    }
+
+    typedef QMap<QString, QString>   LanguageCodeMap;
+
+    LanguageCodeMap                  languageCodeMap;
+
+    KExiv2::AltLangMap               oldValues;
+
+    QPushButton                     *addValueButton;
+    QPushButton                     *delValueButton;
+    QPushButton                     *repValueButton;
+
+    KListWidget                     *valueBox;
+
+    KTextEdit                       *valueEdit;
+
+    SqueezedComboBox                *languageCB;
+
+    MetadataCheckBox                *valueCheck;
+};
+
+AltLangStringsEdit::AltLangStringsEdit(QWidget* parent, const QString& title, const QString& desc)
+                  : QWidget(parent), d(new AltLangStringsEditPriv)
+{
+    QGridLayout *grid = new QGridLayout(this);
+
+    // --------------------------------------------------------
+
+    d->valueCheck     = new MetadataCheckBox(title, this);
+
+    d->addValueButton = new QPushButton(this);
+    d->delValueButton = new QPushButton(this);
+    d->repValueButton = new QPushButton(this);
+    d->addValueButton->setIcon(SmallIcon("list-add"));
+    d->delValueButton->setIcon(SmallIcon("list-remove"));
+    d->repValueButton->setIcon(SmallIcon("view-refresh"));
+    d->addValueButton->setWhatsThis(i18n("Add a new value to the list"));
+    d->delValueButton->setWhatsThis(i18n("Remove the current selected value from the list"));
+    d->repValueButton->setWhatsThis(i18n("Replace the current selected value from the list"));
+    d->delValueButton->setEnabled(false);
+    d->repValueButton->setEnabled(false);
+
+    d->valueBox  = new KListWidget(this);
+    d->valueBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+    d->valueBox->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+    d->valueBox->setSelectionMode(QAbstractItemView::SingleSelection);
+    d->valueBox->setSortingEnabled(true);
+
+    d->languageCB = new SqueezedComboBox(this);
+    d->languageCB->setWhatsThis(i18n("Select here language code."));
+
+    d->valueEdit = new KTextEdit(this);
+    d->valueEdit->setWhatsThis(desc);
+    d->valueEdit->setMaximumHeight( fontMetrics().height()*3 ); // 3 lines used to edit text.
+
+    // --------------------------------------------------------
+
+    grid->setAlignment( Qt::AlignTop );
+    grid->addWidget(d->valueCheck,                 0, 0, 1, 1);
+    grid->addWidget(d->addValueButton,             0, 2, 1, 1);
+    grid->addWidget(d->delValueButton,             0, 3, 1, 1);
+    grid->addWidget(d->repValueButton,             0, 4, 1, 1);
+    grid->addWidget(d->valueBox,                   0, 5, 3, 1);
+    grid->addWidget(new QLabel(i18n("Language:")), 1, 0, 1, 1);
+    grid->addWidget(d->languageCB,                 1, 1, 1, 4);
+    grid->addWidget(d->valueEdit,                  2, 0, 1, 5);
+    grid->setColumnStretch(1, 5);
+    grid->setColumnStretch(5, 10);
+    grid->setMargin(0);
+    grid->setSpacing(KDialog::spacingHint());
+
+    // --------------------------------------------------------
+
+    connect(d->valueBox, SIGNAL(itemSelectionChanged()),
+            this, SLOT(slotSelectionChanged()));
+
+    connect(d->addValueButton, SIGNAL(clicked()),
+            this, SLOT(slotAddValue()));
+
+    connect(d->delValueButton, SIGNAL(clicked()),
+            this, SLOT(slotDeleteValue()));
+
+    connect(d->repValueButton, SIGNAL(clicked()),
+            this, SLOT(slotReplaceValue()));
+
+    // --------------------------------------------------------
+
+    connect(d->valueCheck, SIGNAL(toggled(bool)),
+            this, SIGNAL(signalToggled(bool)));
+
+    connect(d->valueCheck, SIGNAL(toggled(bool)),
+            d->valueEdit, SLOT(setEnabled(bool)));
+
+    connect(d->valueCheck, SIGNAL(toggled(bool)),
+            d->addValueButton, SLOT(setEnabled(bool)));
+
+    connect(d->valueCheck, SIGNAL(toggled(bool)),
+            d->delValueButton, SLOT(setEnabled(bool)));
+
+    connect(d->valueCheck, SIGNAL(toggled(bool)),
+            d->repValueButton, SLOT(setEnabled(bool)));
+
+    connect(d->valueCheck, SIGNAL(toggled(bool)),
+            d->valueBox, SLOT(setEnabled(bool)));
+
+    // --------------------------------------------------------
+
+    connect(d->valueCheck, SIGNAL(toggled(bool)),
+            this, SIGNAL(signalModified()));
+
+    connect(d->addValueButton, SIGNAL(clicked()),
+            this, SIGNAL(signalModified()));
+
+    connect(d->delValueButton, SIGNAL(clicked()),
+            this, SIGNAL(signalModified()));
+
+    connect(d->repValueButton, SIGNAL(clicked()),
+            this, SIGNAL(signalModified()));
+}
+
+AltLangStringsEdit::~AltLangStringsEdit()
+{
+    delete d;
+}
+
+void AltLangStringsEdit::setValid(bool v)
+{
+    d->valueCheck->setValid(v);
+}
+
+bool AltLangStringsEdit::isValid() const
+{
+    return d->valueCheck->isValid();
+}
+
+void AltLangStringsEdit::slotDeleteValue()
+{
+    QListWidgetItem *item = d->valueBox->currentItem();
+    if (!item) return;
+    d->valueBox->takeItem(d->valueBox->row(item));
+    delete item;
+    loadLangAltListEntries();
+}
+
+void AltLangStringsEdit::slotSelectionChanged()
+{
+    if (!d->valueBox->selectedItems().isEmpty())
+    {
+        QString current = d->valueBox->currentItem()->text();
+        QString lang    = current.left(current.indexOf("] ")+1);
+        QString text    = current.remove(0, lang.size()+1);
+        d->valueEdit->setText(text);
+
+        for (int i = 0; i < d->languageCB->count(); i++)
+        {
+            QString langCode = d->languageCB->item(i);
+            QString code     = langCode.left(langCode.indexOf("] ")+1);
+
+            if (code == lang)
+            {
+                d->languageCB->setCurrentIndex(i);
+                break;
+            }
+        }
+
+        d->delValueButton->setEnabled(true);
+        d->repValueButton->setEnabled(true);
+    }
+    else
+    {
+        d->delValueButton->setEnabled(false);
+        d->repValueButton->setEnabled(false);
+    }
+}
+
+void AltLangStringsEdit::slotAddValue()
+{
+    QString langCode = d->languageCB->itemHighlighted();
+    QString text     = d->valueEdit->toPlainText();
+    if (text.isEmpty()) return;
+
+    QString lang     = langCode.left(langCode.indexOf("] ")+1);
+    QString newValue = QString("%1 %2").arg(lang).arg(text);
+
+    bool found            = false;
+    QListWidgetItem *item = 0;
+
+    for (int row = 0 ; row < d->valueBox->count(); row++)
+    {
+        item             = d->valueBox->item(row);
+        QString language = item->text().left(item->text().indexOf("] "));
+        language.remove(0, 1);
+
+        if (lang.contains(language))
+        {
+            found = true;
+            break;
+        }
+    }
+
+    if (found)
+    {
+        d->valueBox->takeItem(d->valueBox->row(item));
+        delete item;
+    }
+
+    d->valueBox->insertItem(d->valueBox->count(), newValue);
+    d->valueEdit->clear();
+    loadLangAltListEntries();
+}
+
+void AltLangStringsEdit::slotReplaceValue()
+{
+    QString langCode = d->languageCB->itemHighlighted();
+    QString text     = d->valueEdit->toPlainText();
+    if (text.isEmpty()) return;
+
+    QString lang     = langCode.left(langCode.indexOf("] ")+1);
+    QString newValue = QString("%1 %2").arg(lang).arg(text);
+
+    bool found            = false;
+    QListWidgetItem *item = 0;
+
+    for (int row = 0 ; row < d->valueBox->count(); row++)
+    {
+        item             = d->valueBox->item(row);
+        QString language = item->text().left(item->text().indexOf("] "));
+        language.remove(0, 1);
+
+        if (lang.contains(language))
+        {
+            found = true;
+            break;
+        }
+    }
+
+    if (found)
+    {
+        slotAddValue();
+        return;
+    }
+
+    if (!d->valueBox->selectedItems().isEmpty())
+    {
+        d->valueBox->currentItem()->setText(newValue);
+        d->valueEdit->clear();
+        loadLangAltListEntries();
+    }
+}
+
+void AltLangStringsEdit::setValues(const KExiv2::AltLangMap& values)
+{
+    blockSignals(true);
+    d->oldValues = values;
+
+    d->valueBox->clear();
+    d->valueCheck->setChecked(false);
+    if (!d->oldValues.isEmpty())
+    {
+        for (KExiv2::AltLangMap::Iterator it = d->oldValues.begin();
+             it != d->oldValues.end(); ++it)
+        {
+            QString newValue = QString("[%1] %2").arg(it.key()).arg(it.value());
+            d->valueBox->insertItem(0, newValue);
+        }
+
+        d->valueCheck->setChecked(true);
+    }
+    d->valueEdit->setEnabled(d->valueCheck->isChecked());
+    d->valueBox->setEnabled(d->valueCheck->isChecked());
+    d->addValueButton->setEnabled(d->valueCheck->isChecked());
+    d->delValueButton->setEnabled(d->valueCheck->isChecked());
+
+    blockSignals(false);
+
+    loadLangAltListEntries();
+}
+
+bool AltLangStringsEdit::getValues(KExiv2::AltLangMap& oldValues,
+                                   KExiv2::AltLangMap& newValues)
+{
+    oldValues = d->oldValues;
+
+    newValues.clear();
+    for (int i = 0 ; i < d->valueBox->count(); i++)
+    {
+        QListWidgetItem *item = d->valueBox->item(i);
+        QString lang          = item->text().left(item->text().indexOf("] "));
+        lang.remove(0, 1);
+        QString text          = item->text().remove(0, lang.size()+3);
+        newValues.insert(lang, text);
+    }
+
+    return d->valueCheck->isChecked();
+}
+
+void AltLangStringsEdit::loadLangAltListEntries()
+{
+
+    QStringList list;
+    for (int i = 0 ; i < d->valueBox->count(); i++)
+    {
+        QListWidgetItem *item = d->valueBox->item(i);
+        QString lang          = item->text().left(item->text().indexOf("] "));
+        lang.remove(0, 1);
+        list.append(lang);
+    }
+
+    d->languageCB->clear();
+    for (AltLangStringsEditPriv::LanguageCodeMap::Iterator it = d->languageCodeMap.begin();
+         it != d->languageCodeMap.end(); ++it)
+    {
+        d->languageCB->addSqueezedItem(QString("[%1] %2").arg(it.key()).arg(it.value()));
+        if (list.contains(it.key()))
+            d->languageCB->setItemIcon(d->languageCB->count()-1, SmallIcon("dialog-ok"));
+    }
+
+    emit signalDefaultLanguageEnabled(list.contains(QString("x-default")));
+}
+
+QString AltLangStringsEdit::defaultAltLang() const
+{
+    for (int i = 0 ; i < d->valueBox->count(); i++)
+    {
+        QListWidgetItem *item = d->valueBox->item(i);
+        QString lang          = item->text().left(item->text().indexOf("] "));
+        lang.remove(0, 1);
+        QString text          = item->text().remove(0, lang.size()+3);
+        if (lang == QString("x-default"))
+            return text;
+    }
+    return QString();
+}
+
+bool AltLangStringsEdit::asDefaultAltLang() const
+{
+    for (int i = 0 ; i < d->valueBox->count(); i++)
+    {
+        QListWidgetItem *item = d->valueBox->item(i);
+        QString lang          = item->text().left(item->text().indexOf("] "));
+        lang.remove(0, 1);
+        if (lang == QString("x-default"))
+            return true;
+    }
+    return false;
+}
+
+}  // namespace KIPIMetadataEditPlugin
diff --git a/metadataedit/common_backup/altlangstringedit.h b/metadataedit/common_backup/altlangstringedit.h
new file mode 100644
index 0000000..350c58f
--- /dev/null
+++ b/metadataedit/common_backup/altlangstringedit.h
@@ -0,0 +1,84 @@
+/* ============================================================
+ *
+ * This file is a part of kipi-plugins project
+ * http://www.kipi-plugins.org
+ *
+ * Date        : 2007-10-18
+ * Description : a widget to edit a tag with multiple alternative
+ *               language string entries.
+ *
+ * Copyright (C) 2007-2010 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.
+ *
+ * ============================================================ */
+
+#ifndef ALTLANGSTRINGEDIT_H
+#define ALTLANGSTRINGEDIT_H
+
+// Qt includes
+
+#include <QWidget>
+
+// LibKExiv2 includes
+
+#include <libkexiv2/kexiv2.h>
+
+using namespace KExiv2Iface;
+
+namespace KIPIMetadataEditPlugin
+{
+
+class AltLangStringsEditPriv;
+
+class AltLangStringsEdit : public QWidget
+{
+    Q_OBJECT
+
+public:
+
+    AltLangStringsEdit(QWidget* parent, const QString& title, const QString& desc);
+    ~AltLangStringsEdit();
+
+    void setValues(const KExiv2::AltLangMap& values);
+    bool getValues(KExiv2::AltLangMap& oldValues, KExiv2::AltLangMap& newValues);
+
+    void setValid(bool v);
+    bool isValid() const;
+
+    QString defaultAltLang() const;
+    bool    asDefaultAltLang() const;
+
+Q_SIGNALS:
+
+    void signalToggled(bool);
+    void signalModified();
+    void signalDefaultLanguageEnabled(bool);
+
+private Q_SLOTS:
+
+    void slotSelectionChanged();
+    void slotAddValue();
+    void slotDeleteValue();
+    void slotReplaceValue();
+
+private:
+
+    void loadLangAltListEntries();
+
+private:
+
+    AltLangStringsEditPriv* const d;
+};
+
+}  // namespace KIPIMetadataEditPlugin
+
+#endif // ALTLANGSTRINGEDIT_H
diff --git a/metadataedit/common_backup/metadatacheckbox.cpp b/metadataedit/common_backup/metadatacheckbox.cpp
new file mode 100644
index 0000000..f775a52
--- /dev/null
+++ b/metadataedit/common_backup/metadatacheckbox.cpp
@@ -0,0 +1,59 @@
+/* ============================================================
+ *
+ * This file is a part of kipi-plugins project
+ * http://www.kipi-plugins.org
+ *
+ * Date        : 2006-10-18
+ * Description : a checkbox with a boolean valid parameter.
+ *               The boolean statement is used to check if
+ *               a metadata value from a picture have a know
+ *               value registered by EXIF/IPTC spec.
+ *
+ * Copyright (C) 2006-2010 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.
+ *
+ * ============================================================ */
+
+#include "metadatacheckbox.moc"
+
+namespace KIPIMetadataEditPlugin
+{
+
+MetadataCheckBox::MetadataCheckBox(const QString& text, QWidget* parent)
+                : QCheckBox(text, parent)
+{
+    m_valid = true;
+
+    connect(this, SIGNAL(toggled(bool)),
+            this, SLOT(slotValid()));
+}
+
+MetadataCheckBox::~MetadataCheckBox()
+{
+}
+
+void MetadataCheckBox::setValid(bool v)
+{
+    m_valid = v;
+}
+
+bool MetadataCheckBox::isValid() const
+{
+    return m_valid;
+}
+
+void MetadataCheckBox::slotValid()
+{
+    setValid(true);
+}
+
+}  // namespace KIPIMetadataEditPlugin
diff --git a/metadataedit/common_backup/metadatacheckbox.h b/metadataedit/common_backup/metadatacheckbox.h
new file mode 100644
index 0000000..60f5bbb
--- /dev/null
+++ b/metadataedit/common_backup/metadatacheckbox.h
@@ -0,0 +1,59 @@
+/* ============================================================
+ *
+ * This file is a part of kipi-plugins project
+ * http://www.kipi-plugins.org
+ *
+ * Date        : 2006-10-18
+ * Description : a checkbox with a boolean valid parameter.
+ *               The boolean statement is used to check if
+ *               a metadata value from a picture have a know
+ *               value registered by EXIF/IPTC spec.
+ *
+ * Copyright (C) 2006-2010 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.
+ *
+ * ============================================================ */
+
+#ifndef METADATA_CHECKBOX_H
+#define METADATA_CHECKBOX_H
+
+// Qt includes
+
+#include <QCheckBox>
+
+namespace KIPIMetadataEditPlugin
+{
+
+class MetadataCheckBox : public QCheckBox
+{
+    Q_OBJECT
+
+public:
+
+    MetadataCheckBox(const QString& text, QWidget* parent);
+    ~MetadataCheckBox();
+
+    void setValid(bool v);
+    bool isValid() const;
+
+private Q_SLOTS:
+
+    void slotValid();
+
+private:
+
+    bool m_valid;
+};
+
+}  // namespace KIPIMetadataEditPlugin
+
+#endif // METADATA_CHECKBOX_H 
diff --git a/metadataedit/common_backup/multistringsedit.cpp b/metadataedit/common_backup/multistringsedit.cpp
new file mode 100644
index 0000000..09be7a9
--- /dev/null
+++ b/metadataedit/common_backup/multistringsedit.cpp
@@ -0,0 +1,281 @@
+/* ============================================================
+ *
+ * This file is a part of kipi-plugins project
+ * http://www.kipi-plugins.org
+ *
+ * Date        : 2007-10-08
+ * Description : a widget to edit a tag with multiple string entries.
+ *
+ * Copyright (C) 2007-2010 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.
+ *
+ * ============================================================ */
+
+#include "multistringsedit.moc"
+
+// Qt includes
+
+#include <QCheckBox>
+#include <QPushButton>
+#include <QValidator>
+#include <QGridLayout>
+
+// KDE includes
+
+#include <kdialog.h>
+#include <kiconloader.h>
+#include <klineedit.h>
+#include <klistwidget.h>
+#include <klocale.h>
+
+namespace KIPIMetadataEditPlugin
+{
+
+class MultiStringsEditPriv
+{
+public:
+
+    MultiStringsEditPriv()
+    {
+        addValueButton = 0;
+        delValueButton = 0;
+        repValueButton = 0;
+        valueBox       = 0;
+        valueCheck     = 0;
+        valueEdit      = 0;
+    }
+
+    QStringList  oldValues;
+
+    QPushButton *addValueButton;
+    QPushButton *delValueButton;
+    QPushButton *repValueButton;
+
+    QCheckBox   *valueCheck;
+
+    KLineEdit   *valueEdit;
+
+    KListWidget *valueBox;
+};
+
+MultiStringsEdit::MultiStringsEdit(QWidget* parent, const QString& title,
+                                   const QString& desc, bool ascii, int size)
+                : QWidget(parent), d(new MultiStringsEditPriv)
+{
+    QGridLayout *grid = new QGridLayout(this);
+
+    // IPTC only accept printable Ascii char.
+    QRegExp asciiRx("[\x20-\x7F]+$");
+    QValidator *asciiValidator = new QRegExpValidator(asciiRx, this);
+
+    // --------------------------------------------------------
+
+    d->valueCheck = new QCheckBox(title, this);
+
+    d->addValueButton = new QPushButton(this);
+    d->delValueButton = new QPushButton(this);
+    d->repValueButton = new QPushButton(this);
+    d->addValueButton->setIcon(SmallIcon("list-add"));
+    d->delValueButton->setIcon(SmallIcon("edit-delete"));
+    d->repValueButton->setIcon(SmallIcon("view-refresh"));
+    d->addValueButton->setWhatsThis(i18n("Add a new value to the list"));
+    d->delValueButton->setWhatsThis(i18n("Remove the current selected value from the list"));
+    d->repValueButton->setWhatsThis(i18n("Replace the current selected value from the list"));
+    d->delValueButton->setEnabled(false);
+    d->repValueButton->setEnabled(false);
+
+    d->valueBox  = new KListWidget(this);
+    d->valueBox->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Ignored);
+    d->valueBox->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+
+    d->valueEdit = new KLineEdit(this);
+    d->valueEdit->setClearButtonShown(true);
+    QString whatsThis = desc;
+
+    if (ascii || size != -1)
+    {
+        whatsThis.append(i18n(" This field is limited to:"));
+    }
+
+    if (ascii)
+    {
+        d->valueEdit->setValidator(asciiValidator);
+        whatsThis.append(i18n("<p>Printable ASCII characters.</p>"));
+    }
+
+    if (size != -1)
+    {
+        d->valueEdit->setMaxLength(size);
+        whatsThis.append(i18np("<p>1 character.</p>","<p>%1 characters.</p>", size));
+    }
+
+    d->valueEdit->setWhatsThis(whatsThis);
+
+    // --------------------------------------------------------
+
+    grid->setAlignment( Qt::AlignTop );
+    grid->addWidget(d->valueCheck,      0, 0, 1, 1);
+    grid->addWidget(d->addValueButton,  0, 1, 1, 1);
+    grid->addWidget(d->delValueButton,  0, 2, 1, 1);
+    grid->addWidget(d->repValueButton,  0, 3, 1, 1);
+    grid->addWidget(d->valueBox,        0, 4, 3, 1);
+    grid->addWidget(d->valueEdit,       2, 0, 1, 4);
+    grid->setRowStretch(1, 10);
+    grid->setColumnStretch(0, 10);
+    grid->setColumnStretch(4, 100);
+    grid->setMargin(0);
+    grid->setSpacing(KDialog::spacingHint());
+
+    // --------------------------------------------------------
+
+    connect(d->valueBox, SIGNAL(itemSelectionChanged()),
+            this, SLOT(slotSelectionChanged()));
+
+    connect(d->addValueButton, SIGNAL(clicked()),
+            this, SLOT(slotAddValue()));
+
+    connect(d->delValueButton, SIGNAL(clicked()),
+            this, SLOT(slotDeleteValue()));
+
+    connect(d->repValueButton, SIGNAL(clicked()),
+            this, SLOT(slotReplaceValue()));
+
+    // --------------------------------------------------------
+
+    connect(d->valueCheck, SIGNAL(toggled(bool)),
+            d->valueEdit, SLOT(setEnabled(bool)));
+
+    connect(d->valueCheck, SIGNAL(toggled(bool)),
+            d->addValueButton, SLOT(setEnabled(bool)));
+
+    connect(d->valueCheck, SIGNAL(toggled(bool)),
+            d->delValueButton, SLOT(setEnabled(bool)));
+
+    connect(d->valueCheck, SIGNAL(toggled(bool)),
+            d->repValueButton, SLOT(setEnabled(bool)));
+
+    connect(d->valueCheck, SIGNAL(toggled(bool)),
+            d->valueBox, SLOT(setEnabled(bool)));
+
+    // --------------------------------------------------------
+
+    connect(d->valueCheck, SIGNAL(toggled(bool)),
+            this, SIGNAL(signalModified()));
+
+    connect(d->addValueButton, SIGNAL(clicked()),
+            this, SIGNAL(signalModified()));
+
+    connect(d->delValueButton, SIGNAL(clicked()),
+            this, SIGNAL(signalModified()));
+
+    connect(d->repValueButton, SIGNAL(clicked()),
+            this, SIGNAL(signalModified()));
+}
+
+MultiStringsEdit::~MultiStringsEdit()
+{
+    delete d;
+}
+
+void MultiStringsEdit::slotDeleteValue()
+{
+    QListWidgetItem *item = d->valueBox->currentItem();
+    if (!item) return;
+    d->valueBox->takeItem(d->valueBox->row(item));
+    delete item;
+}
+
+void MultiStringsEdit::slotReplaceValue()
+{
+    QString newValue = d->valueEdit->text();
+    if (newValue.isEmpty()) return;
+
+    if (!d->valueBox->selectedItems().isEmpty())
+    {
+        d->valueBox->selectedItems()[0]->setText(newValue);
+        d->valueEdit->clear();
+    }
+}
+
+void MultiStringsEdit::slotSelectionChanged()
+{
+    if (!d->valueBox->selectedItems().isEmpty())
+    {
+        d->valueEdit->setText(d->valueBox->selectedItems()[0]->text());
+        d->delValueButton->setEnabled(true);
+        d->repValueButton->setEnabled(true);
+    }
+    else
+    {
+        d->delValueButton->setEnabled(false);
+        d->repValueButton->setEnabled(false);
+    }
+}
+
+void MultiStringsEdit::slotAddValue()
+{
+    QString newValue = d->valueEdit->text();
+    if (newValue.isEmpty()) return;
+
+    bool found = false;
+    for (int i = 0 ; i < d->valueBox->count(); i++)
+    {
+        QListWidgetItem *item = d->valueBox->item(i);
+        if (newValue == item->text())
+        {
+            found = true;
+            break;
+        }
+    }
+
+    if (!found)
+    {
+        d->valueBox->insertItem(d->valueBox->count(), newValue);
+        d->valueEdit->clear();
+    }
+}
+
+void MultiStringsEdit::setValues(const QStringList& values)
+{
+    blockSignals(true);
+    d->oldValues = values;
+
+    d->valueBox->clear();
+    d->valueCheck->setChecked(false);
+    if (!d->oldValues.isEmpty())
+    {
+        d->valueBox->insertItems(0, d->oldValues);
+        d->valueCheck->setChecked(true);
+    }
+    d->valueEdit->setEnabled(d->valueCheck->isChecked());
+    d->valueBox->setEnabled(d->valueCheck->isChecked());
+    d->addValueButton->setEnabled(d->valueCheck->isChecked());
+    d->delValueButton->setEnabled(d->valueCheck->isChecked());
+
+    blockSignals(false);
+}
+
+bool MultiStringsEdit::getValues(QStringList& oldValues, QStringList& newValues)
+{
+    oldValues = d->oldValues;
+
+    newValues.clear();
+    for (int i = 0 ; i < d->valueBox->count(); i++)
+    {
+        QListWidgetItem *item = d->valueBox->item(i);
+        newValues.append(item->text());
+    }
+
+    return d->valueCheck->isChecked();
+}
+
+}  // namespace KIPIMetadataEditPlugin
diff --git a/metadataedit/common_backup/multistringsedit.h b/metadataedit/common_backup/multistringsedit.h
new file mode 100644
index 0000000..cee4e81
--- /dev/null
+++ b/metadataedit/common_backup/multistringsedit.h
@@ -0,0 +1,66 @@
+/* ============================================================
+ *
+ * This file is a part of kipi-plugins project
+ * http://www.kipi-plugins.org
+ *
+ * Date        : 2007-10-08
+ * Description : a widget to edit a tag with multiple string entries.
+ *
+ * Copyright (C) 2007-2010 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.
+ *
+ * ============================================================ */
+
+#ifndef MULTI_STRINGS_EDIT_H
+#define MULTI_STRINGS_EDIT_H
+
+// Qt includes
+
+#include <QWidget>
+
+namespace KIPIMetadataEditPlugin
+{
+
+class MultiStringsEditPriv;
+
+class MultiStringsEdit : public QWidget
+{
+    Q_OBJECT
+
+public:
+
+    MultiStringsEdit(QWidget* parent, const QString& title, 
+                     const QString& desc, bool ascii=true, int size=-1);
+    ~MultiStringsEdit();
+
+    void setValues(const QStringList& values);
+    bool getValues(QStringList& oldValues, QStringList& newValues);
+
+Q_SIGNALS:
+
+    void signalModified();
+
+private Q_SLOTS:
+
+    void slotSelectionChanged();
+    void slotAddValue();
+    void slotDeleteValue();
+    void slotReplaceValue();
+
+private:
+
+    MultiStringsEditPriv* const d;
+};
+
+}  // namespace KIPIMetadataEditPlugin
+
+#endif // MULTI_STRINGS_EDIT_H
diff --git a/metadataedit/common_backup/multivaluesedit.cpp b/metadataedit/common_backup/multivaluesedit.cpp
new file mode 100644
index 0000000..15b9e17
--- /dev/null
+++ b/metadataedit/common_backup/multivaluesedit.cpp
@@ -0,0 +1,287 @@
+/* ============================================================
+ *
+ * This file is a part of kipi-plugins project
+ * http://www.kipi-plugins.org
+ *
+ * Date        : 2007-10-08
+ * Description : a widget to edit a tag with multiple fixed values.
+ *
+ * Copyright (C) 2007-2010 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.
+ *
+ * ============================================================ */
+
+#include "multivaluesedit.moc"
+
+// Qt includes
+
+#include <QCheckBox>
+#include <QPushButton>
+#include <QGridLayout>
+
+// KDE includes
+
+#include <kcombobox.h>
+#include <kdialog.h>
+#include <kiconloader.h>
+#include <klistwidget.h>
+#include <klocale.h>
+
+// LibKDcraw includes
+
+#include <libkdcraw/squeezedcombobox.h>
+
+// Local includes
+
+#include "metadatacheckbox.h"
+
+using namespace KDcrawIface;
+
+namespace KIPIMetadataEditPlugin
+{
+
+class MultiValuesEditPriv
+{
+public:
+
+    MultiValuesEditPriv()
+    {
+        addValueButton = 0;
+        delValueButton = 0;
+        repValueButton = 0;
+        valueBox       = 0;
+        valueCheck     = 0;
+        dataList       = 0;
+    }
+
+    QStringList                    oldValues;
+
+    QPushButton                   *addValueButton;
+    QPushButton                   *delValueButton;
+    QPushButton                   *repValueButton;
+
+    KListWidget                   *valueBox;
+
+    MetadataCheckBox              *valueCheck;
+
+    SqueezedComboBox              *dataList;
+};
+
+MultiValuesEdit::MultiValuesEdit(QWidget* parent, const QString& title, const QString& desc)
+               : QWidget(parent), d(new MultiValuesEditPriv)
+{
+    QGridLayout *grid = new QGridLayout(this);
+
+    // --------------------------------------------------------
+
+    d->valueCheck = new MetadataCheckBox(title, this);
+
+    d->addValueButton = new QPushButton(this);
+    d->delValueButton = new QPushButton(this);
+    d->repValueButton = new QPushButton(this);
+    d->addValueButton->setIcon(SmallIcon("list-add"));
+    d->delValueButton->setIcon(SmallIcon("edit-delete"));
+    d->repValueButton->setIcon(SmallIcon("view-refresh"));
+    d->addValueButton->setWhatsThis(i18n("Add a new value to the list"));
+    d->delValueButton->setWhatsThis(i18n("Remove the current selected value from the list"));
+    d->repValueButton->setWhatsThis(i18n("Replace the current selected value from the list"));
+    d->delValueButton->setEnabled(false);
+    d->repValueButton->setEnabled(false);
+
+    d->valueBox = new KListWidget(this);
+    d->valueBox->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Ignored);
+    d->valueBox->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+
+    d->dataList = new SqueezedComboBox(this);
+    d->dataList->model()->sort(0);
+    d->dataList->setWhatsThis(desc);
+
+    // --------------------------------------------------------
+
+    grid->setAlignment( Qt::AlignTop );
+    grid->addWidget(d->valueCheck,      0, 0, 1, 1);
+    grid->addWidget(d->addValueButton,  0, 1, 1, 1);
+    grid->addWidget(d->delValueButton,  0, 2, 1, 1);
+    grid->addWidget(d->repValueButton,  0, 3, 1, 1);
+    grid->addWidget(d->valueBox,        0, 4, 3, 1);
+    grid->addWidget(d->dataList,        2, 0, 1, 4);
+    grid->setRowStretch(1, 10);
+    grid->setColumnStretch(0, 10);
+    grid->setColumnStretch(4, 100);
+    grid->setMargin(0);
+    grid->setSpacing(KDialog::spacingHint());
+
+    // --------------------------------------------------------
+
+    connect(d->valueBox, SIGNAL(itemSelectionChanged()),
+            this, SLOT(slotSelectionChanged()));
+
+    connect(d->addValueButton, SIGNAL(clicked()),
+            this, SLOT(slotAddValue()));
+
+    connect(d->delValueButton, SIGNAL(clicked()),
+            this, SLOT(slotDeleteValue()));
+
+    connect(d->repValueButton, SIGNAL(clicked()),
+            this, SLOT(slotReplaceValue()));
+
+    // --------------------------------------------------------
+
+    connect(d->valueCheck, SIGNAL(toggled(bool)),
+            d->dataList, SLOT(setEnabled(bool)));
+
+    connect(d->valueCheck, SIGNAL(toggled(bool)),
+            d->addValueButton, SLOT(setEnabled(bool)));
+
+    connect(d->valueCheck, SIGNAL(toggled(bool)),
+            d->delValueButton, SLOT(setEnabled(bool)));
+
+    connect(d->valueCheck, SIGNAL(toggled(bool)),
+            d->repValueButton, SLOT(setEnabled(bool)));
+
+    connect(d->valueCheck, SIGNAL(toggled(bool)),
+            d->valueBox, SLOT(setEnabled(bool)));
+
+    // --------------------------------------------------------
+
+    connect(d->valueCheck, SIGNAL(toggled(bool)),
+            this, SIGNAL(signalModified()));
+
+    connect(d->addValueButton, SIGNAL(clicked()),
+            this, SIGNAL(signalModified()));
+
+    connect(d->delValueButton, SIGNAL(clicked()),
+            this, SIGNAL(signalModified()));
+
+    connect(d->repValueButton, SIGNAL(clicked()),
+            this, SIGNAL(signalModified()));
+}
+
+MultiValuesEdit::~MultiValuesEdit()
+{
+    delete d;
+}
+
+void MultiValuesEdit::slotDeleteValue()
+{
+    QListWidgetItem *item = d->valueBox->currentItem();
+    if (!item) return;
+    d->valueBox->takeItem(d->valueBox->row(item));
+    delete item;
+}
+
+void MultiValuesEdit::slotReplaceValue()
+{
+    QString newValue = d->dataList->itemHighlighted();
+    if (newValue.isEmpty()) return;
+
+    if (!d->valueBox->selectedItems().isEmpty())
+        d->valueBox->selectedItems()[0]->setText(newValue);
+}
+
+void MultiValuesEdit::slotSelectionChanged()
+{
+    if (!d->valueBox->selectedItems().isEmpty())
+    {
+        d->dataList->findText(d->valueBox->selectedItems()[0]->text());
+        d->delValueButton->setEnabled(true);
+        d->repValueButton->setEnabled(true);
+    }
+    else
+    {
+        d->delValueButton->setEnabled(false);
+        d->repValueButton->setEnabled(false);
+    }
+}
+
+void MultiValuesEdit::slotAddValue()
+{
+    QString newValue = d->dataList->itemHighlighted();
+    if (newValue.isEmpty()) return;
+
+    bool found = false;
+    for (int i = 0 ; i < d->valueBox->count(); i++)
+    {
+        QListWidgetItem *item = d->valueBox->item(i);
+        if (newValue == item->text())
+        {
+            found = true;
+            break;
+        }
+    }
+
+    if (!found)
+        d->valueBox->insertItem(d->valueBox->count(), newValue);
+}
+
+void MultiValuesEdit::setData(const QStringList& data)
+{
+    d->dataList->clear();
+    for (QStringList::const_iterator it = data.constBegin(); it != data.constEnd(); ++it )
+        d->dataList->addSqueezedItem(*it);
+}
+
+QStringList MultiValuesEdit::getData() const
+{
+    QStringList data;
+    for (int i = 0 ; i < d->dataList->count(); i++)
+    {
+        data.append(d->dataList->item(i));
+    }
+    return data;
+}
+
+void MultiValuesEdit::setValues(const QStringList& values)
+{
+    blockSignals(true);
+    d->oldValues = values;
+
+    d->valueBox->clear();
+    d->valueCheck->setChecked(false);
+    if (!d->oldValues.isEmpty())
+    {
+        d->valueBox->insertItems(0, d->oldValues);
+        d->valueCheck->setChecked(true);
+    }
+    d->dataList->setEnabled(d->valueCheck->isChecked());
+    d->valueBox->setEnabled(d->valueCheck->isChecked());
+    d->addValueButton->setEnabled(d->valueCheck->isChecked());
+    d->delValueButton->setEnabled(d->valueCheck->isChecked());
+
+    blockSignals(false);
+}
+
+bool MultiValuesEdit::getValues(QStringList& oldValues, QStringList& newValues)
+{
+    oldValues = d->oldValues;
+
+    newValues.clear();
+    for (int i = 0 ; i < d->valueBox->count(); i++)
+    {
+        QListWidgetItem *item = d->valueBox->item(i);
+        newValues.append(item->text());
+    }
+
+    return d->valueCheck->isChecked();
+}
+
+void MultiValuesEdit::setValid(bool v)
+{
+    d->valueCheck->setValid(v);
+}
+
+bool MultiValuesEdit::isValid() const
+{
+    return d->valueCheck->isValid();
+}
+
+}  // namespace KIPIMetadataEditPlugin
diff --git a/metadataedit/common_backup/multivaluesedit.h b/metadataedit/common_backup/multivaluesedit.h
new file mode 100644
index 0000000..2a22107
--- /dev/null
+++ b/metadataedit/common_backup/multivaluesedit.h
@@ -0,0 +1,71 @@
+/* ============================================================
+ *
+ * This file is a part of kipi-plugins project
+ * http://www.kipi-plugins.org
+ *
+ * Date        : 2007-10-08
+ * Description : a widget to edit a tag with multiple fixed values.
+ *
+ * Copyright (C) 2007-2010 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.
+ *
+ * ============================================================ */
+
+#ifndef MULTI_VALUES_EDIT_H
+#define MULTI_VALUES_EDIT_H
+
+// Qt includes
+
+#include <QWidget>
+
+namespace KIPIMetadataEditPlugin
+{
+
+class MultiValuesEditPriv;
+
+class MultiValuesEdit : public QWidget
+{
+    Q_OBJECT
+
+public:
+
+    MultiValuesEdit(QWidget* parent, const QString& title, const QString& desc);
+    ~MultiValuesEdit();
+
+    void setValid(bool v);
+    bool isValid() const;
+
+    void setData(const QStringList& data);
+    QStringList getData() const;
+
+    void setValues(const QStringList& values);
+    bool getValues(QStringList& oldValues, QStringList& newValues);
+
+Q_SIGNALS:
+
+    void signalModified();
+
+private Q_SLOTS:
+
+    void slotSelectionChanged();
+    void slotAddValue();
+    void slotDeleteValue();
+    void slotReplaceValue();
+
+private:
+
+    MultiValuesEditPriv* const d;
+};
+
+}  // namespace KIPIMetadataEditPlugin
+
+#endif // MULTI_VALUES_EDIT_H
diff --git a/metadataedit/common_backup/objectattributesedit.cpp b/metadataedit/common_backup/objectattributesedit.cpp
new file mode 100644
index 0000000..547757a
--- /dev/null
+++ b/metadataedit/common_backup/objectattributesedit.cpp
@@ -0,0 +1,339 @@
+/* ============================================================
+ *
+ * This file is a part of kipi-plugins project
+ * http://www.kipi-plugins.org
+ *
+ * Date        : 2007-10-08
+ * Description : a widget to edit Application2 ObjectAttribute
+ *               Iptc tag.
+ *
+ * Copyright (C) 2007-2010 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.
+ *
+ * ============================================================ */
+
+#include "objectattributesedit.moc"
+
+// Qt includes
+
+#include <QCheckBox>
+#include <QPushButton>
+#include <QValidator>
+#include <QGridLayout>
+
+// KDE includes
+
+#include <kcombobox.h>
+#include <kdialog.h>
+#include <kiconloader.h>
+#include <klineedit.h>
+#include <klistwidget.h>
+#include <klocale.h>
+
+// LibKDcraw includes
+
+#include <libkdcraw/squeezedcombobox.h>
+
+// Local includes
+
+#include "metadatacheckbox.h"
+
+using namespace KDcrawIface;
+
+namespace KIPIMetadataEditPlugin
+{
+
+class ObjectAttributesEditPriv
+{
+public:
+
+    ObjectAttributesEditPriv()
+    {
+        addValueButton = 0;
+        delValueButton = 0;
+        repValueButton = 0;
+        valueBox       = 0;
+        valueCheck     = 0;
+        valueEdit      = 0;
+        dataList       = 0;
+    }
+
+    QStringList                    oldValues;
+
+    QPushButton                   *addValueButton;
+    QPushButton                   *delValueButton;
+    QPushButton                   *repValueButton;
+
+    KLineEdit                     *valueEdit;
+
+    KListWidget                   *valueBox;
+
+    MetadataCheckBox              *valueCheck;
+
+    SqueezedComboBox              *dataList;
+};
+
+ObjectAttributesEdit::ObjectAttributesEdit(QWidget* parent, bool ascii, int size)
+                    : QWidget(parent), d(new ObjectAttributesEditPriv)
+{
+    QGridLayout *grid = new QGridLayout(this);
+
+    // IPTC only accept printable Ascii char.
+    QRegExp asciiRx("[\x20-\x7F]+$");
+    QValidator *asciiValidator = new QRegExpValidator(asciiRx, this);
+
+    // --------------------------------------------------------
+
+    d->valueCheck = new MetadataCheckBox(i18n("Attribute:"), this);
+
+    d->addValueButton = new QPushButton(this);
+    d->delValueButton = new QPushButton(this);
+    d->repValueButton = new QPushButton(this);
+    d->addValueButton->setIcon(SmallIcon("list-add"));
+    d->delValueButton->setIcon(SmallIcon("edit-delete"));
+    d->repValueButton->setIcon(SmallIcon("view-refresh"));
+    d->addValueButton->setWhatsThis(i18n("Add a new value to the list"));
+    d->delValueButton->setWhatsThis(i18n("Remove the current selected value from the list"));
+    d->repValueButton->setWhatsThis(i18n("Replace the current selected value from the list"));
+    d->delValueButton->setEnabled(false);
+    d->repValueButton->setEnabled(false);
+
+    d->valueBox = new KListWidget(this);
+    d->valueBox->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Ignored);
+    d->valueBox->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+
+    // --------------------------------------------------------
+
+    d->dataList = new SqueezedComboBox(this);
+    d->dataList->model()->sort(0);
+    d->dataList->setWhatsThis(i18n("Select here the editorial attribute of content."));
+    d->dataList->addSqueezedItem(QString("001 - ") + i18nc("Content type", "Current"));
+    d->dataList->addSqueezedItem(QString("002 - ") + i18nc("Content type", "Analysis"));
+    d->dataList->addSqueezedItem(QString("003 - ") + i18nc("Content type", "Archive material"));
+    d->dataList->addSqueezedItem(QString("004 - ") + i18nc("Content type", "Background"));
+    d->dataList->addSqueezedItem(QString("005 - ") + i18nc("Content type", "Feature"));
+    d->dataList->addSqueezedItem(QString("006 - ") + i18nc("Content type", "Forecast"));
+    d->dataList->addSqueezedItem(QString("007 - ") + i18nc("Content type", "History"));
+    d->dataList->addSqueezedItem(QString("008 - ") + i18nc("Content type", "Obituary"));
+    d->dataList->addSqueezedItem(QString("009 - ") + i18nc("Content type", "Opinion"));
+    d->dataList->addSqueezedItem(QString("010 - ") + i18nc("Content type", "Polls & Surveys"));
+    d->dataList->addSqueezedItem(QString("011 - ") + i18nc("Content type", "Profile"));
+    d->dataList->addSqueezedItem(QString("012 - ") + i18nc("Content type", "Results Listings & Table"));
+    d->dataList->addSqueezedItem(QString("013 - ") + i18nc("Content type", "Side bar & Supporting information"));
+    d->dataList->addSqueezedItem(QString("014 - ") + i18nc("Content type", "Summary"));
+    d->dataList->addSqueezedItem(QString("015 - ") + i18nc("Content type", "Transcript & Verbatim"));
+    d->dataList->addSqueezedItem(QString("016 - ") + i18nc("Content type", "Interview"));
+    d->dataList->addSqueezedItem(QString("017 - ") + i18nc("Content type", "From the Scene"));
+    d->dataList->addSqueezedItem(QString("018 - ") + i18nc("Content type", "Retrospective"));
+    d->dataList->addSqueezedItem(QString("019 - ") + i18nc("Content type", "Statistics"));
+    d->dataList->addSqueezedItem(QString("020 - ") + i18nc("Content type", "Update"));
+    d->dataList->addSqueezedItem(QString("021 - ") + i18nc("Content type", "Wrap-up"));
+    d->dataList->addSqueezedItem(QString("022 - ") + i18nc("Content type", "Press Release"));
+
+    // --------------------------------------------------------
+
+    d->valueEdit = new KLineEdit(this);
+    d->valueEdit->setClearButtonShown(true);
+    QString whatsThis = i18n("Set here the editorial attribute description of "
+                             "content. This field is limited to 64 ASCII characters.");
+
+    if (ascii || size != -1)
+    {
+        whatsThis.append(i18n(" This field is limited to:"));
+    }
+
+    if (ascii)
+    {
+        d->valueEdit->setValidator(asciiValidator);
+        whatsThis.append(i18n("<p>Printable ASCII characters.</p>"));
+    }
+
+    if (size != -1)
+    {
+        d->valueEdit->setMaxLength(size);
+        whatsThis.append(i18np("<p>1 character.</p>","<p>%1 characters.</p>", size));
+    }
+
+    d->valueEdit->setWhatsThis(whatsThis);
+
+    // --------------------------------------------------------
+
+    grid->setAlignment( Qt::AlignTop );
+    grid->addWidget(d->valueCheck,      0, 0, 1, 1);
+    grid->addWidget(d->addValueButton,  0, 1, 1, 1);
+    grid->addWidget(d->delValueButton,  0, 2, 1, 1);
+    grid->addWidget(d->repValueButton,  0, 3, 1, 1);
+    grid->addWidget(d->valueBox,        0, 4, 4, 1);
+    grid->addWidget(d->dataList,        1, 0, 1, 4);
+    grid->addWidget(d->valueEdit,       2, 0, 1, 4);
+    grid->setRowStretch(3, 10);
+    grid->setColumnStretch(0, 10);
+    grid->setColumnStretch(4, 100);
+    grid->setMargin(0);
+    grid->setSpacing(KDialog::spacingHint());
+
+    // --------------------------------------------------------
+
+    connect(d->valueBox, SIGNAL(itemSelectionChanged()),
+            this, SLOT(slotSelectionChanged()));
+
+    connect(d->addValueButton, SIGNAL(clicked()),
+            this, SLOT(slotAddValue()));
+
+    connect(d->delValueButton, SIGNAL(clicked()),
+            this, SLOT(slotDeleteValue()));
+
+    connect(d->repValueButton, SIGNAL(clicked()),
+            this, SLOT(slotReplaceValue()));
+
+    // --------------------------------------------------------
+
+    connect(d->valueCheck, SIGNAL(toggled(bool)),
+            d->valueEdit, SLOT(setEnabled(bool)));
+
+    connect(d->valueCheck, SIGNAL(toggled(bool)),
+            d->dataList, SLOT(setEnabled(bool)));
+
+    connect(d->valueCheck, SIGNAL(toggled(bool)),
+            d->addValueButton, SLOT(setEnabled(bool)));
+
+    connect(d->valueCheck, SIGNAL(toggled(bool)),
+            d->delValueButton, SLOT(setEnabled(bool)));
+
+    connect(d->valueCheck, SIGNAL(toggled(bool)),
+            d->repValueButton, SLOT(setEnabled(bool)));
+
+    connect(d->valueCheck, SIGNAL(toggled(bool)),
+            d->valueBox, SLOT(setEnabled(bool)));
+
+    // --------------------------------------------------------
+
+    connect(d->valueCheck, SIGNAL(toggled(bool)),
+            this, SIGNAL(signalModified()));
+
+    connect(d->addValueButton, SIGNAL(clicked()),
+            this, SIGNAL(signalModified()));
+
+    connect(d->delValueButton, SIGNAL(clicked()),
+            this, SIGNAL(signalModified()));
+
+    connect(d->repValueButton, SIGNAL(clicked()),
+            this, SIGNAL(signalModified()));
+}
+
+ObjectAttributesEdit::~ObjectAttributesEdit()
+{
+    delete d;
+}
+
+void ObjectAttributesEdit::slotDeleteValue()
+{
+    QListWidgetItem *item = d->valueBox->currentItem();
+    if (!item) return;
+    d->valueBox->takeItem(d->valueBox->row(item));
+    delete item;
+}
+
+void ObjectAttributesEdit::slotReplaceValue()
+{
+    QString newValue = d->dataList->itemHighlighted().left(3);
+    newValue.append(QString(":%1").arg(d->valueEdit->text()));
+
+    if (!d->valueBox->selectedItems().isEmpty())
+        d->valueBox->selectedItems()[0]->setText(newValue);
+}
+
+void ObjectAttributesEdit::slotSelectionChanged()
+{
+    if (!d->valueBox->selectedItems().isEmpty())
+    {
+        bool ok   = false;
+        int index = d->valueBox->selectedItems()[0]->text().section(':', 0, 0).toInt(&ok);
+        if (ok)
+        {
+            d->dataList->setCurrentIndex(index-1);
+            d->valueEdit->setText(d->valueBox->selectedItems()[0]->text().section(':', -1));
+            d->delValueButton->setEnabled(true);
+            d->repValueButton->setEnabled(true);
+            return;
+        }
+    }
+
+    d->delValueButton->setEnabled(false);
+    d->repValueButton->setEnabled(false);
+}
+
+void ObjectAttributesEdit::slotAddValue()
+{
+    QString newValue = d->dataList->itemHighlighted().left(3);
+    newValue.append(QString(":%1").arg(d->valueEdit->text()));
+
+    bool found = false;
+    for (int i = 0 ; i < d->valueBox->count(); i++)
+    {
+        QListWidgetItem *item = d->valueBox->item(i);
+        if (newValue == item->text())
+        {
+            found = true;
+            break;
+        }
+    }
+
+    if (!found)
+        d->valueBox->insertItem(d->valueBox->count(), newValue);
+}
+
+void ObjectAttributesEdit::setValues(const QStringList& values)
+{
+    blockSignals(true);
+    d->oldValues = values;
+
+    d->valueBox->clear();
+    d->valueCheck->setChecked(false);
+    if (!d->oldValues.isEmpty())
+    {
+        d->valueBox->insertItems(0, d->oldValues);
+        d->valueCheck->setChecked(true);
+    }
+    d->dataList->setEnabled(d->valueCheck->isChecked());
+    d->valueBox->setEnabled(d->valueCheck->isChecked());
+    d->addValueButton->setEnabled(d->valueCheck->isChecked());
+    d->delValueButton->setEnabled(d->valueCheck->isChecked());
+
+    blockSignals(false);
+}
+
+bool ObjectAttributesEdit::getValues(QStringList& oldValues, QStringList& newValues)
+{
+    oldValues = d->oldValues;
+
+    newValues.clear();
+    for (int i = 0 ; i < d->valueBox->count(); i++)
+    {
+        QListWidgetItem *item = d->valueBox->item(i);
+        newValues.append(item->text());
+    }
+
+    return d->valueCheck->isChecked();
+}
+
+void ObjectAttributesEdit::setValid(bool v)
+{
+    d->valueCheck->setValid(v);
+}
+
+bool ObjectAttributesEdit::isValid() const
+{
+    return d->valueCheck->isValid();
+}
+
+}  // namespace KIPIMetadataEditPlugin
diff --git a/metadataedit/common_backup/objectattributesedit.h b/metadataedit/common_backup/objectattributesedit.h
new file mode 100644
index 0000000..b06da37
--- /dev/null
+++ b/metadataedit/common_backup/objectattributesedit.h
@@ -0,0 +1,69 @@
+/* ============================================================
+ *
+ * This file is a part of kipi-plugins project
+ * http://www.kipi-plugins.org
+ *
+ * Date        : 2007-10-08
+ * Description : a widget to edit Application2 ObjectAttribute 
+ *               Iptc tag.
+ *
+ * Copyright (C) 2007-2010 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.
+ *
+ * ============================================================ */
+
+#ifndef OBJECT_ATTRIBUTES_EDIT_H
+#define OBJECT_ATTRIBUTES_EDIT_H
+
+// Qt includes
+
+#include <QWidget>
+
+namespace KIPIMetadataEditPlugin
+{
+
+class ObjectAttributesEditPriv;
+
+class ObjectAttributesEdit : public QWidget
+{
+    Q_OBJECT
+
+public:
+
+    explicit ObjectAttributesEdit(QWidget* parent, bool ascii=true, int size=-1);
+    ~ObjectAttributesEdit();
+
+    void setValid(bool v);
+    bool isValid() const;
+
+    void setValues(const QStringList& values);
+    bool getValues(QStringList& oldValues, QStringList& newValues);
+
+Q_SIGNALS:
+
+    void signalModified();
+
+private Q_SLOTS:
+
+    void slotSelectionChanged();
+    void slotAddValue();
+    void slotDeleteValue();
+    void slotReplaceValue();
+
+private:
+
+    ObjectAttributesEditPriv* const d;
+};
+
+}  // namespace KIPIMetadataEditPlugin
+
+#endif // OBJECT_ATTRIBUTES_EDIT_H
