summaryrefslogtreecommitdiffstats
path: root/digikam/libs/imageproperties
diff options
context:
space:
mode:
Diffstat (limited to 'digikam/libs/imageproperties')
-rw-r--r--digikam/libs/imageproperties/Makefile.am51
-rw-r--r--digikam/libs/imageproperties/cameraitempropertiestab.cpp555
-rw-r--r--digikam/libs/imageproperties/cameraitempropertiestab.h68
-rw-r--r--digikam/libs/imageproperties/imagedescedittab.cpp1763
-rw-r--r--digikam/libs/imageproperties/imagedescedittab.h144
-rw-r--r--digikam/libs/imageproperties/imagepropertiescolorstab.cpp799
-rw-r--r--digikam/libs/imageproperties/imagepropertiescolorstab.h113
-rw-r--r--digikam/libs/imageproperties/imagepropertiesmetadatatab.cpp201
-rw-r--r--digikam/libs/imageproperties/imagepropertiesmetadatatab.h67
-rw-r--r--digikam/libs/imageproperties/imagepropertiessidebar.cpp150
-rw-r--r--digikam/libs/imageproperties/imagepropertiessidebar.h92
-rw-r--r--digikam/libs/imageproperties/imagepropertiessidebarcamgui.cpp209
-rw-r--r--digikam/libs/imageproperties/imagepropertiessidebarcamgui.h86
-rw-r--r--digikam/libs/imageproperties/imagepropertiessidebardb.cpp368
-rw-r--r--digikam/libs/imageproperties/imagepropertiessidebardb.h116
-rw-r--r--digikam/libs/imageproperties/imagepropertiestab.cpp601
-rw-r--r--digikam/libs/imageproperties/imagepropertiestab.h65
-rw-r--r--digikam/libs/imageproperties/navigatebartab.cpp146
-rw-r--r--digikam/libs/imageproperties/navigatebartab.h84
-rw-r--r--digikam/libs/imageproperties/navigatebarwidget.cpp112
-rw-r--r--digikam/libs/imageproperties/navigatebarwidget.h69
-rw-r--r--digikam/libs/imageproperties/talbumlistview.cpp528
-rw-r--r--digikam/libs/imageproperties/talbumlistview.h108
23 files changed, 6495 insertions, 0 deletions
diff --git a/digikam/libs/imageproperties/Makefile.am b/digikam/libs/imageproperties/Makefile.am
new file mode 100644
index 0000000..a766aef
--- /dev/null
+++ b/digikam/libs/imageproperties/Makefile.am
@@ -0,0 +1,51 @@
+METASOURCES = AUTO
+
+noinst_LTLIBRARIES = libimagepropertiesshowfoto.la libimagepropertiesdigikam.la \
+ libimagepropertiescamgui.la
+
+# Image Properties SideBar for Camera GUI.
+
+libimagepropertiescamgui_la_SOURCES = imagepropertiessidebarcamgui.cpp cameraitempropertiestab.cpp
+
+libimagepropertiescamgui_la_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+
+# Image Properties SideBar for Showfoto (without digiKam database support).
+
+libimagepropertiesshowfoto_la_SOURCES = imagepropertiessidebar.cpp navigatebarwidget.cpp \
+ imagepropertiesmetadatatab.cpp imagepropertiescolorstab.cpp \
+ imagepropertiestab.cpp navigatebartab.cpp
+
+libimagepropertiesshowfoto_la_LIBADD = $(top_builddir)/digikam/libs/widgets/libwidgets.la \
+ $(top_builddir)/digikam/libs/dmetadata/libdmetadata.la \
+ $(top_builddir)/digikam/libs/dimg/libdimg.la \
+ $(top_builddir)/digikam/libs/threadimageio/libthreadimageio.la \
+ $(top_builddir)/digikam/libs/histogram/libhistogram.la
+
+libimagepropertiesshowfoto_la_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+
+# Image Properties SideBar for digiKam Main interface and Image Editor (digiKam database support).
+
+libimagepropertiesdigikam_la_SOURCES = imagedescedittab.cpp imagepropertiessidebar.cpp \
+ imagepropertiessidebardb.cpp \
+ talbumlistview.cpp imagepropertiesmetadatatab.cpp \
+ imagepropertiescolorstab.cpp \
+ navigatebarwidget.cpp imagepropertiestab.cpp navigatebartab.cpp
+
+libimagepropertiesdigikam_la_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+
+INCLUDES = -I$(top_srcdir)/digikam/libs/histogram \
+ -I$(top_srcdir)/digikam/libs/themeengine \
+ -I$(top_srcdir)/digikam/libs/dmetadata \
+ -I$(top_srcdir)/digikam/libs/widgets/common \
+ -I$(top_srcdir)/digikam/libs/widgets/iccprofiles \
+ -I$(top_srcdir)/digikam/libs/widgets/metadata \
+ -I$(top_srcdir)/digikam/libs/dialogs \
+ -I$(top_srcdir)/digikam/libs/dimg \
+ -I$(top_srcdir)/digikam/libs/threadimageio \
+ -I$(top_srcdir)/digikam/utilities/cameragui \
+ -I$(top_srcdir)/digikam/utilities/batch \
+ -I$(top_srcdir)/digikam/digikam \
+ $(LIBKEXIV2_CFLAGS) \
+ $(LIBKDCRAW_CFLAGS) \
+ $(all_includes)
+
diff --git a/digikam/libs/imageproperties/cameraitempropertiestab.cpp b/digikam/libs/imageproperties/cameraitempropertiestab.cpp
new file mode 100644
index 0000000..9eea429
--- /dev/null
+++ b/digikam/libs/imageproperties/cameraitempropertiestab.cpp
@@ -0,0 +1,555 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2006-02-08
+ * Description : A tab to display camera item information
+ *
+ * Copyright (C) 2006-2008 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.
+ *
+ * ============================================================ */
+
+// Qt includes.
+
+#include <qlayout.h>
+#include <qstyle.h>
+#include <qfile.h>
+#include <qlabel.h>
+#include <qpixmap.h>
+#include <qcombobox.h>
+#include <qwhatsthis.h>
+#include <qframe.h>
+#include <qscrollview.h>
+
+// KDE includes.
+
+#include <klocale.h>
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kdialogbase.h>
+#include <kfileitem.h>
+#include <kmimetype.h>
+#include <kseparator.h>
+#include <ksqueezedtextlabel.h>
+
+// Local includes.
+
+#include "ddebug.h"
+#include "dmetadata.h"
+#include "gpiteminfo.h"
+#include "navigatebarwidget.h"
+#include "cameraitempropertiestab.h"
+#include "cameraitempropertiestab.moc"
+
+namespace Digikam
+{
+
+class CameraItemPropertiesTabPriv
+{
+public:
+
+ CameraItemPropertiesTabPriv()
+ {
+ title = 0;
+ file = 0;
+ folder = 0;
+ date = 0;
+ size = 0;
+ isReadable = 0;
+ isWritable = 0;
+ mime = 0;
+ dimensions = 0;
+ newFileName = 0;
+ downloaded = 0;
+ settingsArea = 0;
+ title2 = 0;
+ make = 0;
+ model = 0;
+ photoDate = 0;
+ aperture = 0;
+ focalLength = 0;
+ exposureTime = 0;
+ sensitivity = 0;
+ exposureMode = 0;
+ flash = 0;
+ whiteBalance = 0;
+ labelFile = 0;
+ labelFolder = 0;
+ labelFileIsReadable = 0;
+ labelFileIsWritable = 0;
+ labelFileDate = 0;
+ labelFileSize = 0;
+ labelImageMime = 0;
+ labelImageDimensions = 0;
+ labelNewFileName = 0;
+ labelAlreadyDownloaded = 0;
+ labelPhotoMake = 0;
+ labelPhotoModel = 0;
+ labelPhotoDateTime = 0;
+ labelPhotoAperture = 0;
+ labelPhotoFocalLenght = 0;
+ labelPhotoExposureTime = 0;
+ labelPhotoSensitivity = 0;
+ labelPhotoExposureMode = 0;
+ labelPhotoFlash = 0;
+ labelPhotoWhiteBalance = 0;
+ }
+
+ QLabel *title;
+ QLabel *file;
+ QLabel *folder;
+ QLabel *date;
+ QLabel *size;
+ QLabel *isReadable;
+ QLabel *isWritable;
+ QLabel *mime;
+ QLabel *dimensions;
+ QLabel *newFileName;
+ QLabel *downloaded;
+
+ QLabel *title2;
+ QLabel *make;
+ QLabel *model;
+ QLabel *photoDate;
+ QLabel *aperture;
+ QLabel *focalLength;
+ QLabel *exposureTime;
+ QLabel *sensitivity;
+ QLabel *exposureMode;
+ QLabel *flash;
+ QLabel *whiteBalance;
+
+ QFrame *settingsArea;
+
+ KSqueezedTextLabel *labelFile;
+ KSqueezedTextLabel *labelFolder;
+ KSqueezedTextLabel *labelFileIsReadable;
+ KSqueezedTextLabel *labelFileIsWritable;
+ KSqueezedTextLabel *labelFileDate;
+ KSqueezedTextLabel *labelFileSize;
+ KSqueezedTextLabel *labelImageMime;
+ KSqueezedTextLabel *labelImageDimensions;
+ KSqueezedTextLabel *labelNewFileName;
+ KSqueezedTextLabel *labelAlreadyDownloaded;
+
+ KSqueezedTextLabel *labelPhotoMake;
+ KSqueezedTextLabel *labelPhotoModel;
+ KSqueezedTextLabel *labelPhotoDateTime;
+ KSqueezedTextLabel *labelPhotoAperture;
+ KSqueezedTextLabel *labelPhotoFocalLenght;
+ KSqueezedTextLabel *labelPhotoExposureTime;
+ KSqueezedTextLabel *labelPhotoSensitivity;
+ KSqueezedTextLabel *labelPhotoExposureMode;
+ KSqueezedTextLabel *labelPhotoFlash;
+ KSqueezedTextLabel *labelPhotoWhiteBalance;
+};
+
+CameraItemPropertiesTab::CameraItemPropertiesTab(QWidget* parent, bool navBar)
+ : NavigateBarTab(parent)
+{
+ d = new CameraItemPropertiesTabPriv;
+
+ setupNavigateBar(navBar);
+
+ QScrollView *sv = new QScrollView(this);
+ sv->viewport()->setBackgroundMode(Qt::PaletteBackground);
+ sv->setResizePolicy(QScrollView::AutoOneFit);
+ sv->setFrameStyle(QFrame::NoFrame);
+
+ d->settingsArea = new QFrame(sv->viewport());
+ d->settingsArea->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken );
+ d->settingsArea->setLineWidth( style().pixelMetric(QStyle::PM_DefaultFrameWidth, this) );
+
+ sv->addChild(d->settingsArea);
+ m_navigateBarLayout->addWidget(sv);
+
+ // --------------------------------------------------
+
+ QGridLayout *settingsLayout = new QGridLayout(d->settingsArea, 27, 1, KDialog::spacingHint(), 0);
+
+ d->title = new QLabel(i18n("<big><b>Camera File Properties</b></big>"), d->settingsArea);
+ d->file = new QLabel(i18n("<b>File</b>:"), d->settingsArea);
+ d->folder = new QLabel(i18n("<b>Folder</b>:"), d->settingsArea);
+ d->date = new QLabel(i18n("<b>Date</b>:"), d->settingsArea);
+ d->size = new QLabel(i18n("<b>Size</b>:"), d->settingsArea);
+ d->isReadable = new QLabel(i18n("<b>Readable</b>:"), d->settingsArea);
+ d->isWritable = new QLabel(i18n("<b>Writable</b>:"), d->settingsArea);
+ d->mime = new QLabel(i18n("<b>Type</b>:"), d->settingsArea);
+ d->dimensions = new QLabel(i18n("<b>Dimensions</b>:"), d->settingsArea);
+ d->newFileName = new QLabel(i18n("<nobr><b>New Name</b></nobr>:"), d->settingsArea);
+ d->downloaded = new QLabel(i18n("<b>Downloaded</b>:"), d->settingsArea);
+
+ KSeparator *line = new KSeparator (Horizontal, d->settingsArea);
+ d->title2 = new QLabel(i18n("<big><b>Photograph Properties</b></big>"), d->settingsArea);
+ d->make = new QLabel(i18n("<b>Make</b>:"), d->settingsArea);
+ d->model = new QLabel(i18n("<b>Model</b>:"), d->settingsArea);
+ d->photoDate = new QLabel(i18n("<b>Created</b>:"), d->settingsArea);
+ d->aperture = new QLabel(i18n("<b>Aperture</b>:"), d->settingsArea);
+ d->focalLength = new QLabel(i18n("<b>Focal</b>:"), d->settingsArea);
+ d->exposureTime = new QLabel(i18n("<b>Exposure</b>:"), d->settingsArea);
+ d->sensitivity = new QLabel(i18n("<b>Sensitivity</b>:"), d->settingsArea);
+ d->exposureMode = new QLabel(i18n("<nobr><b>Mode/Program</b></nobr>:"), d->settingsArea);
+ d->flash = new QLabel(i18n("<b>Flash</b>:"), d->settingsArea);
+ d->whiteBalance = new QLabel(i18n("<nobr><b>White balance</b></nobr>:"), d->settingsArea);
+
+ d->labelFile = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelFolder = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelFileDate = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelFileSize = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelFileIsReadable = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelFileIsWritable = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelImageMime = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelImageDimensions = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelNewFileName = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelAlreadyDownloaded = new KSqueezedTextLabel(0, d->settingsArea);
+
+ d->labelPhotoMake = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelPhotoModel = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelPhotoDateTime = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelPhotoAperture = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelPhotoFocalLenght = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelPhotoExposureTime = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelPhotoSensitivity = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelPhotoExposureMode = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelPhotoFlash = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelPhotoWhiteBalance = new KSqueezedTextLabel(0, d->settingsArea);
+
+ int hgt = fontMetrics().height()-2;
+ d->title->setAlignment(Qt::AlignCenter);
+ d->file->setMaximumHeight(hgt);
+ d->folder->setMaximumHeight(hgt);
+ d->date->setMaximumHeight(hgt);
+ d->size->setMaximumHeight(hgt);
+ d->isReadable->setMaximumHeight(hgt);
+ d->isWritable->setMaximumHeight(hgt);
+ d->mime->setMaximumHeight(hgt);
+ d->dimensions->setMaximumHeight(hgt);
+ d->newFileName->setMaximumHeight(hgt);
+ d->downloaded->setMaximumHeight(hgt);
+ d->labelFile->setMaximumHeight(hgt);
+ d->labelFolder->setMaximumHeight(hgt);
+ d->labelFileDate->setMaximumHeight(hgt);
+ d->labelFileSize->setMaximumHeight(hgt);
+ d->labelFileIsReadable->setMaximumHeight(hgt);
+ d->labelFileIsWritable->setMaximumHeight(hgt);
+ d->labelImageMime->setMaximumHeight(hgt);
+ d->labelImageDimensions->setMaximumHeight(hgt);
+ d->labelNewFileName->setMaximumHeight(hgt);
+ d->labelAlreadyDownloaded->setMaximumHeight(hgt);
+
+ d->title2->setAlignment(Qt::AlignCenter);
+ d->make->setMaximumHeight(hgt);
+ d->model->setMaximumHeight(hgt);
+ d->photoDate->setMaximumHeight(hgt);
+ d->aperture->setMaximumHeight(hgt);
+ d->focalLength->setMaximumHeight(hgt);
+ d->exposureTime->setMaximumHeight(hgt);
+ d->sensitivity->setMaximumHeight(hgt);
+ d->exposureMode->setMaximumHeight(hgt);
+ d->flash->setMaximumHeight(hgt);
+ d->whiteBalance->setMaximumHeight(hgt);
+ d->labelPhotoMake->setMaximumHeight(hgt);
+ d->labelPhotoModel->setMaximumHeight(hgt);
+ d->labelPhotoDateTime->setMaximumHeight(hgt);
+ d->labelPhotoAperture->setMaximumHeight(hgt);
+ d->labelPhotoFocalLenght->setMaximumHeight(hgt);
+ d->labelPhotoExposureTime->setMaximumHeight(hgt);
+ d->labelPhotoSensitivity->setMaximumHeight(hgt);
+ d->labelPhotoExposureMode->setMaximumHeight(hgt);
+ d->labelPhotoFlash->setMaximumHeight(hgt);
+ d->labelPhotoWhiteBalance->setMaximumHeight(hgt);
+
+ // --------------------------------------------------
+
+ settingsLayout->addMultiCellWidget(d->title, 0, 0, 0, 1);
+ settingsLayout->addMultiCell(new QSpacerItem(KDialog::spacingHint(), KDialog::spacingHint(),
+ QSizePolicy::Minimum, QSizePolicy::MinimumExpanding), 1, 1, 0, 1);
+ settingsLayout->addMultiCellWidget(d->file, 2, 2, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelFile, 2, 2, 1, 1);
+ settingsLayout->addMultiCellWidget(d->folder, 3, 3, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelFolder, 3, 3, 1, 1);
+ settingsLayout->addMultiCellWidget(d->date, 4, 4, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelFileDate, 4, 4, 1, 1);
+ settingsLayout->addMultiCellWidget(d->size, 5, 5, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelFileSize, 5, 5, 1, 1);
+ settingsLayout->addMultiCellWidget(d->isReadable, 6, 6, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelFileIsReadable, 6, 6, 1, 1);
+ settingsLayout->addMultiCellWidget(d->isWritable, 7, 7, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelFileIsWritable, 7, 7, 1, 1);
+ settingsLayout->addMultiCellWidget(d->mime, 8, 8, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelImageMime, 8, 8, 1, 1);
+ settingsLayout->addMultiCellWidget(d->dimensions, 9, 9, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelImageDimensions, 9, 9, 1, 1);
+ settingsLayout->addMultiCellWidget(d->newFileName, 10, 10, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelNewFileName, 10, 10, 1, 1);
+ settingsLayout->addMultiCellWidget(d->downloaded, 11, 11, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelAlreadyDownloaded, 11, 11, 1, 1);
+
+ settingsLayout->addMultiCell(new QSpacerItem(KDialog::spacingHint(), KDialog::spacingHint(),
+ QSizePolicy::Minimum, QSizePolicy::MinimumExpanding), 12, 12, 0, 1);
+ settingsLayout->addMultiCellWidget(line, 13, 13, 0, 1);
+ settingsLayout->addMultiCell(new QSpacerItem(KDialog::spacingHint(), KDialog::spacingHint(),
+ QSizePolicy::Minimum, QSizePolicy::MinimumExpanding), 14, 14, 0, 1);
+
+ settingsLayout->addMultiCellWidget(d->title2, 15, 15, 0, 1);
+ settingsLayout->addMultiCell(new QSpacerItem(KDialog::spacingHint(), KDialog::spacingHint(),
+ QSizePolicy::Minimum, QSizePolicy::MinimumExpanding), 16, 16, 0, 1);
+ settingsLayout->addMultiCellWidget(d->make, 17, 17, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelPhotoMake, 17, 17, 1, 1);
+ settingsLayout->addMultiCellWidget(d->model, 18, 18, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelPhotoModel, 18, 18, 1, 1);
+ settingsLayout->addMultiCellWidget(d->photoDate, 19, 19, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelPhotoDateTime, 19, 19, 1, 1);
+ settingsLayout->addMultiCellWidget(d->aperture, 20, 20, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelPhotoAperture, 20, 20, 1, 1);
+ settingsLayout->addMultiCellWidget(d->focalLength, 21, 21, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelPhotoFocalLenght, 21, 21, 1, 1);
+ settingsLayout->addMultiCellWidget(d->exposureTime, 22, 22, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelPhotoExposureTime, 22, 22, 1, 1);
+ settingsLayout->addMultiCellWidget(d->sensitivity, 23, 23, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelPhotoSensitivity, 23, 23, 1, 1);
+ settingsLayout->addMultiCellWidget(d->exposureMode, 24, 24, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelPhotoExposureMode, 24, 24, 1, 1);
+ settingsLayout->addMultiCellWidget(d->flash, 25, 25, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelPhotoFlash, 25, 25, 1, 1);
+ settingsLayout->addMultiCellWidget(d->whiteBalance, 26, 26, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelPhotoWhiteBalance, 26, 26, 1, 1);
+ settingsLayout->setRowStretch(27, 10);
+ settingsLayout->setColStretch(1, 10);
+}
+
+CameraItemPropertiesTab::~CameraItemPropertiesTab()
+{
+ delete d;
+}
+
+void CameraItemPropertiesTab::setCurrentItem(const GPItemInfo* itemInfo,
+ const QString &newFileName, const QByteArray& exifData,
+ const KURL &currentURL)
+{
+ if (!itemInfo)
+ {
+ d->labelFile->setText(QString());
+ d->labelFolder->setText(QString());
+ d->labelFileIsReadable->setText(QString());
+ d->labelFileIsWritable->setText(QString());
+ d->labelFileDate->setText(QString());
+ d->labelFileSize->setText(QString());
+ d->labelImageMime->setText(QString());
+ d->labelImageDimensions->setText(QString());
+ d->labelNewFileName->setText(QString());
+ d->labelAlreadyDownloaded->setText(QString());
+
+ d->labelPhotoMake->setText(QString());
+ d->labelPhotoModel->setText(QString());
+ d->labelPhotoDateTime->setText(QString());
+ d->labelPhotoAperture->setText(QString());
+ d->labelPhotoFocalLenght->setText(QString());
+ d->labelPhotoExposureTime->setText(QString());
+ d->labelPhotoSensitivity->setText(QString());
+ d->labelPhotoExposureMode->setText(QString());
+ d->labelPhotoFlash->setText(QString());
+ d->labelPhotoWhiteBalance->setText(QString());
+
+ setEnabled(false);
+ return;
+ }
+
+ setEnabled(true);
+
+ QString str;
+ QString unknown(i18n("<i>unknown</i>"));
+
+ // -- Camera file system information ------------------------------------------
+
+ d->labelFile->setText(itemInfo->name);
+ d->labelFolder->setText(itemInfo->folder);
+
+ if (itemInfo->readPermissions < 0)
+ str = unknown;
+ else if (itemInfo->readPermissions == 0)
+ str = i18n("No");
+ else
+ str = i18n("Yes");
+
+ d->labelFileIsReadable->setText(str);
+
+ if (itemInfo->writePermissions < 0)
+ str = unknown;
+ else if (itemInfo->writePermissions == 0)
+ str = i18n("No");
+ else
+ str = i18n("Yes");
+
+ d->labelFileIsWritable->setText(str);
+
+ QDateTime date;
+ date.setTime_t(itemInfo->mtime);
+ d->labelFileDate->setText(KGlobal::locale()->formatDateTime(date, true, true));
+
+ str = i18n("%1 (%2)").arg(KIO::convertSize(itemInfo->size))
+ .arg(KGlobal::locale()->formatNumber(itemInfo->size, 0));
+ d->labelFileSize->setText(str);
+
+ // -- Image Properties --------------------------------------------------
+
+ d->labelImageMime->setText( (itemInfo->mime == QString("image/x-raw")) ?
+ i18n("RAW Image") : KMimeType::mimeType(itemInfo->mime)->comment() );
+
+ QString mpixels;
+ QSize dims;
+ if (itemInfo->width == -1 && itemInfo->height == -1 && !currentURL.isEmpty())
+ {
+ // delayed loading to list faster from UMSCamera
+ if (itemInfo->mime == QString("image/x-raw"))
+ {
+ DMetadata metaData(currentURL.path());
+ dims = metaData.getImageDimensions();
+ }
+ else
+ {
+ KFileMetaInfo meta(currentURL.path());
+ if (meta.isValid())
+ {
+ if (meta.containsGroup("Jpeg EXIF Data"))
+ dims = meta.group("Jpeg EXIF Data").item("Dimensions").value().toSize();
+ else if (meta.containsGroup("General"))
+ dims = meta.group("General").item("Dimensions").value().toSize();
+ else if (meta.containsGroup("Technical"))
+ dims = meta.group("Technical").item("Dimensions").value().toSize();
+ }
+ }
+ }
+ else
+ {
+ // if available (GPCamera), take dimensions directly from itemInfo
+ dims = QSize(itemInfo->width, itemInfo->height);
+ }
+ mpixels.setNum(dims.width()*dims.height()/1000000.0, 'f', 2);
+ str = (!dims.isValid()) ? unknown : i18n("%1x%2 (%3Mpx)")
+ .arg(dims.width()).arg(dims.height()).arg(mpixels);
+ d->labelImageDimensions->setText(str);
+
+ // -- Download information ------------------------------------------
+
+ d->labelNewFileName->setText(newFileName.isEmpty() ? i18n("<i>unchanged</i>") : newFileName);
+
+ if (itemInfo->downloaded == GPItemInfo::DownloadUnknow)
+ str = unknown;
+ else if (itemInfo->downloaded == GPItemInfo::DownloadedYes)
+ str = i18n("Yes");
+ else
+ str = i18n("No");
+
+ d->labelAlreadyDownloaded->setText(str);
+
+ // -- Photograph information ------------------------------------------
+ // NOTA: If something is changed here, please updated albumfiletip section too.
+
+ QString unavailable(i18n("<i>unavailable</i>"));
+ DMetadata metaData;
+ metaData.setExif(exifData);
+ PhotoInfoContainer photoInfo = metaData.getPhotographInformations();
+
+ if (photoInfo.isEmpty())
+ {
+ d->title2->hide();
+ d->make->hide();
+ d->model->hide();
+ d->photoDate->hide();
+ d->aperture->hide();
+ d->focalLength->hide();
+ d->exposureTime->hide();
+ d->sensitivity->hide();
+ d->exposureMode->hide();
+ d->flash->hide();
+ d->whiteBalance->hide();
+ d->labelPhotoMake->hide();
+ d->labelPhotoModel->hide();
+ d->labelPhotoDateTime->hide();
+ d->labelPhotoAperture->hide();
+ d->labelPhotoFocalLenght->hide();
+ d->labelPhotoExposureTime->hide();
+ d->labelPhotoSensitivity->hide();
+ d->labelPhotoExposureMode->hide();
+ d->labelPhotoFlash->hide();
+ d->labelPhotoWhiteBalance->hide();
+ }
+ else
+ {
+ d->title2->show();
+ d->make->show();
+ d->model->show();
+ d->photoDate->show();
+ d->aperture->show();
+ d->focalLength->show();
+ d->exposureTime->show();
+ d->sensitivity->show();
+ d->exposureMode->show();
+ d->flash->show();
+ d->whiteBalance->show();
+ d->labelPhotoMake->show();
+ d->labelPhotoModel->show();
+ d->labelPhotoDateTime->show();
+ d->labelPhotoAperture->show();
+ d->labelPhotoFocalLenght->show();
+ d->labelPhotoExposureTime->show();
+ d->labelPhotoSensitivity->show();
+ d->labelPhotoExposureMode->show();
+ d->labelPhotoFlash->show();
+ d->labelPhotoWhiteBalance->show();
+ }
+
+ d->labelPhotoMake->setText(photoInfo.make.isEmpty() ? unavailable : photoInfo.make);
+ d->labelPhotoModel->setText(photoInfo.model.isEmpty() ? unavailable : photoInfo.model);
+
+ if (photoInfo.dateTime.isValid())
+ {
+ str = KGlobal::locale()->formatDateTime(photoInfo.dateTime, true, true);
+ d->labelPhotoDateTime->setText(str);
+ }
+ else
+ d->labelPhotoDateTime->setText(unavailable);
+
+ d->labelPhotoAperture->setText(photoInfo.aperture.isEmpty() ? unavailable : photoInfo.aperture);
+
+ if (photoInfo.focalLength35mm.isEmpty())
+ d->labelPhotoFocalLenght->setText(photoInfo.focalLength.isEmpty() ? unavailable : photoInfo.focalLength);
+ else
+ {
+ str = i18n("%1 (35mm: %2)").arg(photoInfo.focalLength).arg(photoInfo.focalLength35mm);
+ d->labelPhotoFocalLenght->setText(str);
+ }
+
+ d->labelPhotoExposureTime->setText(photoInfo.exposureTime.isEmpty() ? unavailable : photoInfo.exposureTime);
+ d->labelPhotoSensitivity->setText(photoInfo.sensitivity.isEmpty() ? unavailable : i18n("%1 ISO").arg(photoInfo.sensitivity));
+
+ if (photoInfo.exposureMode.isEmpty() && photoInfo.exposureProgram.isEmpty())
+ d->labelPhotoExposureMode->setText(unavailable);
+ else if (!photoInfo.exposureMode.isEmpty() && photoInfo.exposureProgram.isEmpty())
+ d->labelPhotoExposureMode->setText(photoInfo.exposureMode);
+ else if (photoInfo.exposureMode.isEmpty() && !photoInfo.exposureProgram.isEmpty())
+ d->labelPhotoExposureMode->setText(photoInfo.exposureProgram);
+ else
+ {
+ str = QString("%1 / %2").arg(photoInfo.exposureMode).arg(photoInfo.exposureProgram);
+ d->labelPhotoExposureMode->setText(str);
+ }
+
+ d->labelPhotoFlash->setText(photoInfo.flash.isEmpty() ? unavailable : photoInfo.flash);
+ d->labelPhotoWhiteBalance->setText(photoInfo.whiteBalance.isEmpty() ? unavailable : photoInfo.whiteBalance);
+}
+
+} // NameSpace Digikam
diff --git a/digikam/libs/imageproperties/cameraitempropertiestab.h b/digikam/libs/imageproperties/cameraitempropertiestab.h
new file mode 100644
index 0000000..13f3a16
--- /dev/null
+++ b/digikam/libs/imageproperties/cameraitempropertiestab.h
@@ -0,0 +1,68 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2006-02-08
+ * Description : A tab to display camera item information
+ *
+ * Copyright (C) 2006-2008 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 CAMERAITEMPROPERTIESTAB_H
+#define CAMERAITEMPROPERTIESTAB_H
+
+// Qt includes.
+
+#include <qwidget.h>
+#include <qstring.h>
+
+// KDE includes.
+
+#include <kurl.h>
+
+// Local includes.
+
+#include "digikam_export.h"
+#include "navigatebartab.h"
+
+namespace Digikam
+{
+
+class GPItemInfo;
+class CameraItemPropertiesTabPriv;
+
+class DIGIKAM_EXPORT CameraItemPropertiesTab : public NavigateBarTab
+{
+ Q_OBJECT
+
+public:
+
+ CameraItemPropertiesTab(QWidget* parent, bool navBar=true);
+ ~CameraItemPropertiesTab();
+
+ void setCurrentItem(const GPItemInfo* itemInfo=0,
+ const QString &newFileName=QString(),
+ const QByteArray& exifData=QByteArray(),
+ const KURL &currentURL = KURL());
+
+private:
+
+ CameraItemPropertiesTabPriv* d;
+};
+
+} // NameSpace Digikam
+
+#endif /* CAMERAITEMPROPERTIESTAB_H */
diff --git a/digikam/libs/imageproperties/imagedescedittab.cpp b/digikam/libs/imageproperties/imagedescedittab.cpp
new file mode 100644
index 0000000..bb9b815
--- /dev/null
+++ b/digikam/libs/imageproperties/imagedescedittab.cpp
@@ -0,0 +1,1763 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2003-03-09
+ * Description : Captions, Tags, and Rating properties editor
+ *
+ * Copyright (C) 2003-2005 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
+ * Copyright (C) 2003-2009 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ * Copyright (C) 2006-2009 by Marcel Wiesweg <marcel.wiesweg@gmx.de>
+ * Copyright (C) 2009 by Andi Clemens <andi dot clemens at gmx dot net>
+ *
+ * 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.
+ *
+ * ============================================================ */
+
+// Qt includes.
+
+#include <qhbox.h>
+#include <qvbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qtoolbutton.h>
+#include <qpushbutton.h>
+#include <qiconset.h>
+#include <qwhatsthis.h>
+#include <qtooltip.h>
+#include <qscrollview.h>
+
+// KDE includes.
+
+#include <kabc/stdaddressbook.h>
+#include <kpopupmenu.h>
+#include <klocale.h>
+#include <kurl.h>
+#include <kcursor.h>
+#include <kapplication.h>
+#include <kiconloader.h>
+#include <kmessagebox.h>
+#include <ktextedit.h>
+#include <kconfig.h>
+#include <klineedit.h>
+#include <kdialogbase.h>
+
+// Local includes.
+
+#include "ddebug.h"
+#include "dmetadata.h"
+#include "kdatetimeedit.h"
+#include "albumiconitem.h"
+#include "albumdb.h"
+#include "album.h"
+#include "albumsettings.h"
+#include "albumlister.h"
+#include "albumthumbnailloader.h"
+#include "tageditdlg.h"
+#include "navigatebarwidget.h"
+#include "ratingwidget.h"
+#include "talbumlistview.h"
+#include "tagfilterview.h"
+#include "imageinfo.h"
+#include "imageattributeswatch.h"
+#include "metadatahub.h"
+#include "statusprogressbar.h"
+#include "searchtextbar.h"
+#include "imagedescedittab.h"
+#include "imagedescedittab.moc"
+
+namespace Digikam
+{
+
+class ImageDescEditTabPriv
+{
+
+public:
+
+ ImageDescEditTabPriv()
+ {
+ modified = false;
+ ignoreImageAttributesWatch = false;
+ recentTagsBtn = 0;
+ commentsEdit = 0;
+ tagsSearchBar = 0;
+ dateTimeEdit = 0;
+ tagsView = 0;
+ ratingWidget = 0;
+ ABCMenu = 0;
+ assignedTagsBtn = 0;
+ applyBtn = 0;
+ revertBtn = 0;
+ newTagEdit = 0;
+ toggleAutoTags = TagFilterView::NoToggleAuto;
+ }
+
+ bool modified;
+ bool ignoreImageAttributesWatch;
+
+ QToolButton *recentTagsBtn;
+ QToolButton *assignedTagsBtn;
+ QToolButton *revertBtn;
+
+ QPopupMenu *ABCMenu;
+
+ QPushButton *applyBtn;
+
+ QPushButton *moreButton;
+ QPopupMenu *moreMenu;
+
+ KTextEdit *commentsEdit;
+
+ KDateTimeEdit *dateTimeEdit;
+
+ SearchTextBar *tagsSearchBar;
+ SearchTextBar *newTagEdit;
+
+ QPtrList<ImageInfo> currInfos;
+
+ TAlbumListView *tagsView;
+
+ RatingWidget *ratingWidget;
+
+ TagFilterView::ToggleAutoTags toggleAutoTags;
+
+ MetadataHub hub;
+};
+
+ImageDescEditTab::ImageDescEditTab(QWidget *parent, bool navBar)
+ : NavigateBarTab(parent)
+{
+ d = new ImageDescEditTabPriv;
+
+ setupNavigateBar(navBar);
+
+ QScrollView *sv = new QScrollView(this);
+ sv->viewport()->setBackgroundMode(Qt::PaletteBackground);
+ sv->setResizePolicy(QScrollView::AutoOneFit);
+ sv->setFrameStyle(QFrame::NoFrame);
+
+ QWidget *settingsArea = new QWidget(sv->viewport());
+ sv->addChild(settingsArea);
+ m_navigateBarLayout->addWidget(sv);
+
+ QGridLayout *settingsLayout = new QGridLayout(settingsArea, 6, 1,
+ KDialog::spacingHint(), KDialog::spacingHint());
+
+ // Captions/Date/Rating view -----------------------------------
+
+ QVBox *commentsBox = new QVBox(settingsArea);
+ new QLabel(i18n("Caption:"), commentsBox);
+ d->commentsEdit = new KTextEdit(commentsBox);
+ d->commentsEdit->setTextFormat(QTextEdit::PlainText);
+ d->commentsEdit->setCheckSpellingEnabled(true);
+ d->commentsEdit->setFixedHeight(100);
+
+ QHBox *dateBox = new QHBox(settingsArea);
+ new QLabel(i18n("Date:"), dateBox);
+ d->dateTimeEdit = new KDateTimeEdit(dateBox, "datepicker");
+
+ QHBox *ratingBox = new QHBox(settingsArea);
+ new QLabel(i18n("Rating:"), ratingBox);
+ d->ratingWidget = new RatingWidget(ratingBox);
+
+ // Tags view ---------------------------------------------------
+
+ d->newTagEdit = new SearchTextBar(settingsArea, "ImageDescEditTabNewTagEdit", i18n("Enter new tag here..."));
+ QWhatsThis::add(d->newTagEdit, i18n("Enter here the text used to create new tags. "
+ "'/' can be used here to create a hierarchy of tags. "
+ "',' can be used here to create more than one hierarchy at the same time."));
+
+ d->tagsView = new TAlbumListView(settingsArea);
+
+ QHBox *tagsSearch = new QHBox(settingsArea);
+ tagsSearch->setSpacing(KDialog::spacingHint());
+
+ d->tagsSearchBar = new SearchTextBar(tagsSearch, "ImageDescEditTabTagsSearchBar");
+
+ d->assignedTagsBtn = new QToolButton(tagsSearch);
+ QToolTip::add(d->assignedTagsBtn, i18n("Tags already assigned"));
+ d->assignedTagsBtn->setIconSet(kapp->iconLoader()->loadIcon("tag-assigned",
+ KIcon::NoGroup, KIcon::SizeSmall,
+ KIcon::DefaultState, 0, true));
+ d->assignedTagsBtn->setToggleButton(true);
+
+ d->recentTagsBtn = new QToolButton(tagsSearch);
+ QPopupMenu *popupMenu = new QPopupMenu(d->recentTagsBtn);
+ QToolTip::add(d->recentTagsBtn, i18n("Recent Tags"));
+ d->recentTagsBtn->setIconSet(kapp->iconLoader()->loadIcon("tag-recents",
+ KIcon::NoGroup, KIcon::SizeSmall,
+ KIcon::DefaultState, 0, true));
+ d->recentTagsBtn->setUsesBigPixmap(false);
+ d->recentTagsBtn->setPopup(popupMenu);
+ d->recentTagsBtn->setPopupDelay(1);
+
+ // Buttons -----------------------------------------
+
+ QHBox *buttonsBox = new QHBox(settingsArea);
+ buttonsBox->setSpacing(KDialog::spacingHint());
+
+ d->revertBtn = new QToolButton(buttonsBox);
+ d->revertBtn->setIconSet(SmallIcon("reload_page"));
+ QToolTip::add(d->revertBtn, i18n("Revert all changes"));
+ d->revertBtn->setEnabled(false);
+
+ d->applyBtn = new QPushButton(i18n("Apply"), buttonsBox);
+ d->applyBtn->setIconSet(SmallIcon("button_ok"));
+ d->applyBtn->setEnabled(false);
+ QToolTip::add(d->applyBtn, i18n("Apply all changes to images"));
+ buttonsBox->setStretchFactor(d->applyBtn, 10);
+
+ d->moreButton = new QPushButton(i18n("More"), buttonsBox);
+ d->moreMenu = new QPopupMenu(this);
+ d->moreButton->setPopup(d->moreMenu);
+
+ // --------------------------------------------------
+
+ settingsLayout->addMultiCellWidget(commentsBox, 0, 0, 0, 1);
+ settingsLayout->addMultiCellWidget(dateBox, 1, 1, 0, 1);
+ settingsLayout->addMultiCellWidget(ratingBox, 2, 2, 0, 1);
+ settingsLayout->addMultiCellWidget(d->newTagEdit, 3, 3, 0, 1);
+ settingsLayout->addMultiCellWidget(d->tagsView, 4, 4, 0, 1);
+ settingsLayout->addMultiCellWidget(tagsSearch, 5, 5, 0, 1);
+ settingsLayout->addMultiCellWidget(buttonsBox, 6, 6, 0, 1);
+ settingsLayout->setRowStretch(4, 10);
+
+ // --------------------------------------------------
+
+ connect(d->tagsView, SIGNAL(signalProgressBarMode(int, const QString&)),
+ this, SIGNAL(signalProgressBarMode(int, const QString&)));
+
+ connect(d->tagsView, SIGNAL(signalProgressValue(int)),
+ this, SIGNAL(signalProgressValue(int)));
+
+ connect(popupMenu, SIGNAL(activated(int)),
+ this, SLOT(slotRecentTagsMenuActivated(int)));
+
+ connect(d->tagsView, SIGNAL(signalItemStateChanged(TAlbumCheckListItem *)),
+ this, SLOT(slotItemStateChanged(TAlbumCheckListItem *)));
+
+ connect(d->commentsEdit, SIGNAL(textChanged()),
+ this, SLOT(slotCommentChanged()));
+
+ connect(d->dateTimeEdit, SIGNAL(dateTimeChanged(const QDateTime& )),
+ this, SLOT(slotDateTimeChanged(const QDateTime&)));
+
+ connect(d->ratingWidget, SIGNAL(signalRatingChanged(int)),
+ this, SLOT(slotRatingChanged(int)));
+
+ connect(d->tagsView, SIGNAL(rightButtonClicked(QListViewItem*, const QPoint &, int)),
+ this, SLOT(slotRightButtonClicked(QListViewItem*, const QPoint&, int)));
+
+ connect(d->tagsSearchBar, SIGNAL(signalTextChanged(const QString&)),
+ this, SLOT(slotTagsSearchChanged(const QString&)));
+
+ connect(this, SIGNAL(signalTagFilterMatch(bool)),
+ d->tagsSearchBar, SLOT(slotSearchResult(bool)));
+
+ connect(d->assignedTagsBtn, SIGNAL(toggled(bool)),
+ this, SLOT(slotAssignedTagsToggled(bool)));
+
+ connect(d->newTagEdit->lineEdit(), SIGNAL(returnPressed(const QString&)),
+ this, SLOT(slotCreateNewTag()));
+
+ connect(d->applyBtn, SIGNAL(clicked()),
+ this, SLOT(slotApplyAllChanges()));
+
+ connect(d->revertBtn, SIGNAL(clicked()),
+ this, SLOT(slotRevertAllChanges()));
+
+ connect(d->moreMenu, SIGNAL(aboutToShow()),
+ this, SLOT(slotMoreMenu()));
+
+ // Initialize ---------------------------------------------
+
+ d->commentsEdit->installEventFilter(this);
+ d->dateTimeEdit->installEventFilter(this);
+ d->ratingWidget->installEventFilter(this);
+ d->tagsView->installEventFilter(this);
+ updateRecentTags();
+
+ // Connect to album manager -----------------------------
+
+ AlbumManager* man = AlbumManager::instance();
+
+ connect(man, SIGNAL(signalAlbumAdded(Album*)),
+ this, SLOT(slotAlbumAdded(Album*)));
+
+ connect(man, SIGNAL(signalAlbumDeleted(Album*)),
+ this, SLOT(slotAlbumDeleted(Album*)));
+
+ connect(man, SIGNAL(signalAlbumRenamed(Album*)),
+ this, SLOT(slotAlbumRenamed(Album*)));
+
+ connect(man, SIGNAL(signalAlbumsCleared()),
+ this, SLOT(slotAlbumsCleared()));
+
+ connect(man, SIGNAL(signalAlbumIconChanged(Album*)),
+ this, SLOT(slotAlbumIconChanged(Album*)));
+
+ connect(man, SIGNAL(signalTAlbumMoved(TAlbum*, TAlbum*)),
+ this, SLOT(slotAlbumMoved(TAlbum*, TAlbum*)));
+
+ // Connect to thumbnail loader -----------------------------
+
+ AlbumThumbnailLoader *loader = AlbumThumbnailLoader::instance();
+
+ connect(loader, SIGNAL(signalThumbnail(Album *, const QPixmap&)),
+ this, SLOT(slotGotThumbnailFromIcon(Album *, const QPixmap&)));
+
+ connect(loader, SIGNAL(signalFailed(Album *)),
+ this, SLOT(slotThumbnailLost(Album *)));
+
+ connect(loader, SIGNAL(signalReloadThumbnails()),
+ this, SLOT(slotReloadThumbnails()));
+
+ // Connect to attribute watch ------------------------------
+
+ ImageAttributesWatch *watch = ImageAttributesWatch::instance();
+
+ connect(watch, SIGNAL(signalImageTagsChanged(Q_LLONG)),
+ this, SLOT(slotImageTagsChanged(Q_LLONG)));
+
+ connect(watch, SIGNAL(signalImagesChanged(int)),
+ this, SLOT(slotImagesChanged(int)));
+
+ connect(watch, SIGNAL(signalImageRatingChanged(Q_LLONG)),
+ this, SLOT(slotImageRatingChanged(Q_LLONG)));
+
+ connect(watch, SIGNAL(signalImageDateChanged(Q_LLONG)),
+ this, SLOT(slotImageDateChanged(Q_LLONG)));
+
+ connect(watch, SIGNAL(signalImageCaptionChanged(Q_LLONG)),
+ this, SLOT(slotImageCaptionChanged(Q_LLONG)));
+
+ // -- read config ---------------------------------------------------------
+
+ KConfig* config = kapp->config();
+ config->setGroup("Tag List View");
+ d->toggleAutoTags = (TagFilterView::ToggleAutoTags)(config->readNumEntry("Toggle Auto Tags",
+ TagFilterView::NoToggleAuto));
+}
+
+ImageDescEditTab::~ImageDescEditTab()
+{
+ slotChangingItems();
+
+ /*
+ AlbumList tList = AlbumManager::instance()->allTAlbums();
+ for (AlbumList::iterator it = tList.begin(); it != tList.end(); ++it)
+ {
+ (*it)->removeExtraData(this);
+ }
+ */
+
+ KConfig* config = kapp->config();
+ config->setGroup("Tag List View");
+ config->writeEntry("Toggle Auto Tags", (int)(d->toggleAutoTags));
+ config->sync();
+
+ delete d;
+}
+
+bool ImageDescEditTab::singleSelection() const
+{
+ return (d->currInfos.count() == 1);
+}
+
+void ImageDescEditTab::slotChangingItems()
+{
+ if (!d->modified)
+ return;
+
+ if (d->currInfos.isEmpty())
+ return;
+
+ if (!AlbumSettings::instance()->getApplySidebarChangesDirectly())
+ {
+ KDialogBase *dialog = new KDialogBase(i18n("Apply changes?"),
+ KDialogBase::Yes | KDialogBase::No,
+ KDialogBase::Yes, KDialogBase::No,
+ this, "applyChanges",
+ true, true,
+ KStdGuiItem::yes(), KStdGuiItem::discard());
+
+ int changedFields = 0;
+ if (d->hub.commentChanged())
+ changedFields++;
+ if (d->hub.dateTimeChanged())
+ changedFields++;
+ if (d->hub.ratingChanged())
+ changedFields++;
+ if (d->hub.tagsChanged())
+ changedFields++;
+
+ QString text;
+ if (changedFields == 1)
+ {
+ if (d->hub.commentChanged())
+ text = i18n("<qt><p>You have edited the comment of the image. ",
+ "<qt><p>You have edited the comment of %n images. ",
+ d->currInfos.count());
+ else if (d->hub.dateTimeChanged())
+ text = i18n("<qt><p>You have edited the date of the image. ",
+ "<qt><p>You have edited the date of %n images. ",
+ d->currInfos.count());
+ else if (d->hub.ratingChanged())
+ text = i18n("<qt><p>You have edited the rating of the image. ",
+ "<qt><p>You have edited the rating of %n images. ",
+ d->currInfos.count());
+ else if (d->hub.tagsChanged())
+ text = i18n("<qt><p>You have edited the tags of the image. ",
+ "<qt><p>You have edited the tags of %n images. ",
+ d->currInfos.count());
+
+ text += i18n("Do you want to apply your changes?</p></qt>");
+ }
+ else
+ {
+ text = i18n("<qt><p>You have edited the metadata of the image: </p><ul>",
+ "<qt><p>You have edited the metadata of %n images: </p><ul>",
+ d->currInfos.count());
+
+ if (d->hub.commentChanged())
+ text += i18n("<li>comment</li>");
+ if (d->hub.dateTimeChanged())
+ text += i18n("<li>date</li>");
+ if (d->hub.ratingChanged())
+ text += i18n("<li>rating</li>");
+ if (d->hub.tagsChanged())
+ text += i18n("<li>tags</li>");
+
+ text += "</ul><p>";
+
+ text += i18n("Do you want to apply your changes?</p></qt>");
+ }
+
+ bool alwaysApply = false;
+ int returnCode = KMessageBox::createKMessageBox
+ (dialog, QMessageBox::Information,
+ text, QStringList(),
+ i18n("Always apply changes without confirmation"),
+ &alwaysApply, KMessageBox::Notify);
+
+ if (alwaysApply)
+ AlbumSettings::instance()->setApplySidebarChangesDirectly(true);
+
+ if (returnCode == KDialogBase::User1)
+ return;
+ // otherwise apply
+ }
+
+ slotApplyAllChanges();
+}
+
+void ImageDescEditTab::slotApplyAllChanges()
+{
+ if (!d->modified)
+ return;
+
+ if (d->currInfos.isEmpty())
+ return;
+
+ bool progressInfo = (d->currInfos.count() > 1);
+ emit signalProgressBarMode(StatusProgressBar::ProgressBarMode,
+ i18n("Applying changes to images. Please wait..."));
+ MetadataWriteSettings writeSettings = MetadataHub::defaultWriteSettings();
+
+ // debugging - use this to indicate reentry from event loop (kapp->processEvents)
+ // remove before final release
+ if (d->ignoreImageAttributesWatch)
+ {
+ DWarning() << "ImageDescEditTab::slotApplyAllChanges(): re-entering from event loop!" << endl;
+ }
+
+ // we are now changing attributes ourselves
+ d->ignoreImageAttributesWatch = true;
+ AlbumLister::instance()->blockSignals(true);
+ AlbumManager::instance()->albumDB()->beginTransaction();
+ int i=0;
+ for (ImageInfo *info = d->currInfos.first(); info; info = d->currInfos.next())
+ {
+ // apply to database
+ d->hub.write(info);
+ // apply to file metadata
+ d->hub.write(info->filePath(), MetadataHub::FullWrite, writeSettings);
+
+ emit signalProgressValue((int)((i++/(float)d->currInfos.count())*100.0));
+ if (progressInfo)
+ kapp->processEvents();
+ }
+ AlbumLister::instance()->blockSignals(false);
+ AlbumManager::instance()->albumDB()->commitTransaction();
+
+ d->ignoreImageAttributesWatch = false;
+
+ emit signalProgressBarMode(StatusProgressBar::TextMode, QString());
+
+ d->modified = false;
+ d->hub.resetChanged();
+ d->applyBtn->setEnabled(false);
+ d->revertBtn->setEnabled(false);
+
+ updateRecentTags();
+ updateTagsView();
+}
+
+void ImageDescEditTab::slotRevertAllChanges()
+{
+ if (!d->modified)
+ return;
+
+ if (d->currInfos.isEmpty())
+ return;
+
+ setInfos(d->currInfos);
+}
+
+void ImageDescEditTab::setItem(ImageInfo *info)
+{
+ slotChangingItems();
+ QPtrList<ImageInfo> list;
+ if (info)
+ list.append(info);
+ setInfos(list);
+}
+
+void ImageDescEditTab::setItems(QPtrList<ImageInfo> infos)
+{
+ slotChangingItems();
+ setInfos(infos);
+}
+
+void ImageDescEditTab::setInfos(QPtrList<ImageInfo> infos)
+{
+ if (infos.isEmpty())
+ {
+ d->hub = MetadataHub();
+ d->commentsEdit->blockSignals(true);
+ d->commentsEdit->clear();
+ d->commentsEdit->blockSignals(false);
+ d->currInfos.clear();
+ setEnabled(false);
+ return;
+ }
+
+ setEnabled(true);
+ d->currInfos = infos;
+ d->modified = false;
+ d->hub = MetadataHub();
+ d->applyBtn->setEnabled(false);
+ d->revertBtn->setEnabled(false);
+
+ for (ImageInfo *info = d->currInfos.first(); info; info = d->currInfos.next())
+ {
+ d->hub.load(info);
+ }
+
+ updateComments();
+ updateRating();
+ updateDate();
+ updateTagsView();
+}
+
+void ImageDescEditTab::slotReadFromFileMetadataToDatabase()
+{
+ emit signalProgressBarMode(StatusProgressBar::ProgressBarMode,
+ i18n("Reading metadata from files. Please wait..."));
+
+ d->ignoreImageAttributesWatch = true;
+ AlbumManager::instance()->albumDB()->beginTransaction();
+ int i=0;
+ for (ImageInfo *info = d->currInfos.first(); info; info = d->currInfos.next())
+ {
+ // A batch operation: a hub for each single file, not the common hub
+ MetadataHub fileHub(MetadataHub::NewTagsImport);
+ // read in from DMetadata
+ fileHub.load(info->filePath());
+ // write out to database
+ fileHub.write(info);
+
+ emit signalProgressValue((int)((i++/(float)d->currInfos.count())*100.0));
+ kapp->processEvents();
+ }
+ AlbumManager::instance()->albumDB()->commitTransaction();
+ d->ignoreImageAttributesWatch = false;
+
+ emit signalProgressBarMode(StatusProgressBar::TextMode, QString());
+
+ // reload everything
+ setInfos(d->currInfos);
+}
+
+void ImageDescEditTab::slotWriteToFileMetadataFromDatabase()
+{
+ emit signalProgressBarMode(StatusProgressBar::ProgressBarMode,
+ i18n("Writing metadata to files. Please wait..."));
+ MetadataWriteSettings writeSettings = MetadataHub::defaultWriteSettings();
+
+ int i=0;
+ for (ImageInfo *info = d->currInfos.first(); info; info = d->currInfos.next())
+ {
+ MetadataHub fileHub;
+ // read in from database
+ fileHub.load(info);
+ // write out to file DMetadata
+ fileHub.write(info->filePath());
+
+ emit signalProgressValue((int)((i++/(float)d->currInfos.count())*100.0));
+ kapp->processEvents();
+ }
+
+ emit signalProgressBarMode(StatusProgressBar::TextMode, QString());
+}
+
+bool ImageDescEditTab::eventFilter(QObject *, QEvent *e)
+{
+ if ( e->type() == QEvent::KeyPress )
+ {
+ QKeyEvent *k = (QKeyEvent *)e;
+ if (k->state() == Qt::ControlButton &&
+ (k->key() == Qt::Key_Enter || k->key() == Qt::Key_Return))
+ {
+ emit signalNextItem();
+ return true;
+ }
+ else if (k->state() == Qt::ShiftButton &&
+ (k->key() == Qt::Key_Enter || k->key() == Qt::Key_Return))
+ {
+ emit signalPrevItem();
+ return true;
+ }
+
+ return false;
+ }
+
+ return false;
+}
+
+void ImageDescEditTab::populateTags()
+{
+ d->tagsView->clear();
+
+ AlbumList tList = AlbumManager::instance()->allTAlbums();
+ for (AlbumList::iterator it = tList.begin(); it != tList.end(); ++it)
+ {
+ TAlbum *tag = (TAlbum*)(*it);
+ slotAlbumAdded(tag);
+ }
+
+ d->tagsView->loadViewState();
+}
+
+void ImageDescEditTab::slotItemStateChanged(TAlbumCheckListItem *item)
+{
+ TagFilterView::ToggleAutoTags oldAutoTags = d->toggleAutoTags;
+
+ switch(d->toggleAutoTags)
+ {
+ case TagFilterView::Children:
+ d->toggleAutoTags = TagFilterView::NoToggleAuto;
+ toggleChildTags(item->album(), item->isOn());
+ d->toggleAutoTags = oldAutoTags;
+ break;
+ case TagFilterView::Parents:
+ d->toggleAutoTags = TagFilterView::NoToggleAuto;
+ toggleParentTags(item->album(), item->isOn());
+ d->toggleAutoTags = oldAutoTags;
+ break;
+ case TagFilterView::ChildrenAndParents:
+ d->toggleAutoTags = TagFilterView::NoToggleAuto;
+ toggleChildTags(item->album(), item->isOn());
+ toggleParentTags(item->album(), item->isOn());
+ d->toggleAutoTags = oldAutoTags;
+ break;
+ default:
+ break;
+ }
+
+ d->hub.setTag(item->album(), item->isOn());
+
+ d->tagsView->blockSignals(true);
+ item->setStatus(d->hub.tagStatus(item->album()));
+ d->tagsView->blockSignals(false);
+
+ slotModified();
+}
+
+void ImageDescEditTab::slotCommentChanged()
+{
+ // we cannot trust that the text actually changed
+ // (there are bogus signals caused by spell checking, see bug 141663)
+ // so we have to check before marking the metadata as modified
+ if (d->hub.comment() == d->commentsEdit->text())
+ return;
+
+ d->hub.setComment(d->commentsEdit->text());
+ setMetadataWidgetStatus(d->hub.commentStatus(), d->commentsEdit);
+ slotModified();
+}
+
+void ImageDescEditTab::slotDateTimeChanged(const QDateTime& dateTime)
+{
+ d->hub.setDateTime(dateTime);
+ setMetadataWidgetStatus(d->hub.dateTimeStatus(), d->dateTimeEdit);
+ slotModified();
+}
+
+void ImageDescEditTab::slotRatingChanged(int rating)
+{
+ d->hub.setRating(rating);
+ // no handling for MetadataDisjoint needed for rating,
+ // we set it to 0 when disjoint, see below
+ slotModified();
+}
+
+void ImageDescEditTab::slotModified()
+{
+ d->modified = true;
+ d->applyBtn->setEnabled(true);
+ d->revertBtn->setEnabled(true);
+}
+
+void ImageDescEditTab::assignRating(int rating)
+{
+ d->ratingWidget->setRating(rating);
+}
+
+void ImageDescEditTab::updateTagsView()
+{
+ d->tagsView->blockSignals(true);
+
+ QListViewItemIterator it( d->tagsView);
+ while (it.current())
+ {
+ TAlbumCheckListItem* tItem = dynamic_cast<TAlbumCheckListItem*>(it.current());
+ if (tItem)
+ tItem->setStatus(d->hub.tagStatus(tItem->album()));
+ ++it;
+ }
+
+ // The condition is a temporary fix not to destroy name filtering on image change.
+ // See comments in these methods.
+ if (d->assignedTagsBtn->isOn())
+ slotAssignedTagsToggled(d->assignedTagsBtn->isOn());
+
+ d->tagsView->blockSignals(false);
+}
+
+void ImageDescEditTab::updateComments()
+{
+ d->commentsEdit->blockSignals(true);
+ d->commentsEdit->setText(d->hub.comment());
+ setMetadataWidgetStatus(d->hub.commentStatus(), d->commentsEdit);
+ d->commentsEdit->blockSignals(false);
+}
+
+void ImageDescEditTab::updateRating()
+{
+ d->ratingWidget->blockSignals(true);
+ if (d->hub.ratingStatus() == MetadataHub::MetadataDisjoint)
+ d->ratingWidget->setRating(0);
+ else
+ d->ratingWidget->setRating(d->hub.rating());
+ d->ratingWidget->blockSignals(false);
+}
+
+void ImageDescEditTab::updateDate()
+{
+ d->dateTimeEdit->blockSignals(true);
+ d->dateTimeEdit->setDateTime(d->hub.dateTime());
+ setMetadataWidgetStatus(d->hub.dateTimeStatus(), d->dateTimeEdit);
+ d->dateTimeEdit->blockSignals(false);
+}
+
+void ImageDescEditTab::setMetadataWidgetStatus(int status, QWidget *widget)
+{
+ if (status == MetadataHub::MetadataDisjoint)
+ {
+ // For text widgets: Set text color to color of disabled text
+ QPalette palette = widget->palette();
+ palette.setColor(QColorGroup::Text, palette.color(QPalette::Disabled, QColorGroup::Text));
+ widget->setPalette(palette);
+ }
+ else
+ {
+ widget->unsetPalette();
+ }
+}
+
+void ImageDescEditTab::slotRightButtonClicked(QListViewItem *item, const QPoint &, int )
+{
+ TAlbum *album;
+
+ if (!item)
+ {
+ album = AlbumManager::instance()->findTAlbum(0);
+ }
+ else
+ {
+ TAlbumCheckListItem* viewItem = dynamic_cast<TAlbumCheckListItem*>(item);
+
+ if(!viewItem)
+ album = AlbumManager::instance()->findTAlbum(0);
+ else
+ album = viewItem->album();
+ }
+
+ if(!album)
+ return;
+
+ d->ABCMenu = new QPopupMenu;
+
+ connect(d->ABCMenu, SIGNAL( aboutToShow() ),
+ this, SLOT( slotABCContextMenu() ));
+
+ KPopupMenu popmenu(this);
+ popmenu.insertTitle(SmallIcon("digikam"), i18n("Tags"));
+ popmenu.insertItem(SmallIcon("tag-new"), i18n("New Tag..."), 10);
+ popmenu.insertItem(SmallIcon("tag-addressbook"), i18n("Create Tag From AddressBook"), d->ABCMenu);
+
+ if (!album->isRoot())
+ {
+ popmenu.insertItem(SmallIcon("tag-properties"), i18n("Edit Tag Properties..."), 11);
+ popmenu.insertItem(SmallIcon("tag-reset"), i18n("Reset Tag Icon"), 13);
+ popmenu.insertSeparator(-1);
+ popmenu.insertItem(SmallIcon("tag-delete"), i18n("Delete Tag"), 12);
+ }
+
+ popmenu.insertSeparator(-1);
+
+ QPopupMenu selectTagsMenu;
+ selectTagsMenu.insertItem(i18n("All Tags"), 14);
+ if (!album->isRoot())
+ {
+ selectTagsMenu.insertSeparator(-1);
+ selectTagsMenu.insertItem(i18n("Children"), 17);
+ selectTagsMenu.insertItem(i18n("Parents"), 19);
+ }
+ popmenu.insertItem(i18n("Select"), &selectTagsMenu);
+
+ QPopupMenu deselectTagsMenu;
+ deselectTagsMenu.insertItem(i18n("All Tags"), 15);
+ if (!album->isRoot())
+ {
+ deselectTagsMenu.insertSeparator(-1);
+ deselectTagsMenu.insertItem(i18n("Children"), 18);
+ deselectTagsMenu.insertItem(i18n("Parents"), 20);
+ }
+ popmenu.insertItem(i18n("Deselect"), &deselectTagsMenu);
+
+ popmenu.insertItem(i18n("Invert Selection"), 16);
+ popmenu.insertSeparator(-1);
+
+ QPopupMenu toggleAutoMenu;
+ toggleAutoMenu.setCheckable(true);
+ toggleAutoMenu.insertItem(i18n("None"), 21);
+ toggleAutoMenu.insertSeparator(-1);
+ toggleAutoMenu.insertItem(i18n("Children"), 22);
+ toggleAutoMenu.insertItem(i18n("Parents"), 23);
+ toggleAutoMenu.insertItem(i18n("Both"), 24);
+ toggleAutoMenu.setItemChecked(21 + d->toggleAutoTags, true);
+ popmenu.insertItem(i18n("Toggle Auto"), &toggleAutoMenu);
+
+ TagFilterView::ToggleAutoTags oldAutoTags = d->toggleAutoTags;
+
+ int choice = popmenu.exec((QCursor::pos()));
+ switch( choice )
+ {
+ case 10: // New Tag.
+ {
+ tagNew(album);
+ break;
+ }
+ case 11: // Edit Tag Properties.
+ {
+ if (!album->isRoot())
+ tagEdit(album);
+ break;
+ }
+ case 12: // Delete Tag.
+ {
+ if (!album->isRoot())
+ tagDelete(album);
+ break;
+ }
+ case 13: // Reset Tag Icon.
+ {
+ QString errMsg;
+ AlbumManager::instance()->updateTAlbumIcon(album, QString("tag"), 0, errMsg);
+ break;
+ }
+ case 14: // Select All Tags.
+ {
+ d->toggleAutoTags = TagFilterView::NoToggleAuto;
+ QListViewItemIterator it(d->tagsView, QListViewItemIterator::NotChecked);
+ while (it.current())
+ {
+ TAlbumCheckListItem* item = dynamic_cast<TAlbumCheckListItem*>(it.current());
+ if (item->isVisible())
+ item->setOn(true);
+ ++it;
+ }
+ d->toggleAutoTags = oldAutoTags;
+ break;
+ }
+ case 15: // Deselect All Tags.
+ {
+ d->toggleAutoTags = TagFilterView::NoToggleAuto;
+ QListViewItemIterator it(d->tagsView, QListViewItemIterator::Checked);
+ while (it.current())
+ {
+ TAlbumCheckListItem* item = dynamic_cast<TAlbumCheckListItem*>(it.current());
+ if (item->isVisible())
+ item->setOn(false);
+ ++it;
+ }
+ d->toggleAutoTags = oldAutoTags;
+ break;
+ }
+ case 16: // Invert All Tags Selection.
+ {
+ d->toggleAutoTags = TagFilterView::NoToggleAuto;
+ QListViewItemIterator it(d->tagsView);
+ while (it.current())
+ {
+ TAlbumCheckListItem* item = dynamic_cast<TAlbumCheckListItem*>(it.current());
+ if (item->isVisible())
+ item->setOn(!item->isOn());
+ ++it;
+ }
+ d->toggleAutoTags = oldAutoTags;
+ break;
+ }
+ case 17: // Select Child Tags.
+ {
+ d->toggleAutoTags = TagFilterView::NoToggleAuto;
+ toggleChildTags(album, true);
+ TAlbumCheckListItem *item = (TAlbumCheckListItem*)album->extraData(d->tagsView);
+ item->setOn(true);
+ d->toggleAutoTags = oldAutoTags;
+ break;
+ }
+ case 18: // Deselect Child Tags.
+ {
+ d->toggleAutoTags = TagFilterView::NoToggleAuto;
+ toggleChildTags(album, false);
+ TAlbumCheckListItem *item = (TAlbumCheckListItem*)album->extraData(d->tagsView);
+ item->setOn(false);
+ d->toggleAutoTags = oldAutoTags;
+ break;
+ }
+ case 19: // Select Parent Tags.
+ {
+ d->toggleAutoTags = TagFilterView::NoToggleAuto;
+ toggleParentTags(album, true);
+ TAlbumCheckListItem *item = (TAlbumCheckListItem*)album->extraData(d->tagsView);
+ item->setOn(true);
+ d->toggleAutoTags = oldAutoTags;
+ break;
+ }
+ case 20: // Deselect Parent Tags.
+ {
+ d->toggleAutoTags = TagFilterView::NoToggleAuto;
+ toggleParentTags(album, false);
+ TAlbumCheckListItem *item = (TAlbumCheckListItem*)album->extraData(d->tagsView);
+ item->setOn(false);
+ d->toggleAutoTags = oldAutoTags;
+ break;
+ }
+ case 21: // No toggle auto tags.
+ {
+ d->toggleAutoTags = TagFilterView::NoToggleAuto;
+ break;
+ }
+ case 22: // Toggle auto Children tags.
+ {
+ d->toggleAutoTags = TagFilterView::Children;
+ break;
+ }
+ case 23: // Toggle auto Parents tags.
+ {
+ d->toggleAutoTags = TagFilterView::Parents;
+ break;
+ }
+ case 24: // Toggle auto Children and Parents tags.
+ {
+ d->toggleAutoTags = TagFilterView::ChildrenAndParents;
+ break;
+ }
+ default:
+ break;
+ }
+
+ if ( choice > 100 )
+ {
+ tagNew(album, d->ABCMenu->text( choice ), "tag-people" );
+ }
+
+ delete d->ABCMenu;
+ d->ABCMenu = 0;
+}
+
+void ImageDescEditTab::slotABCContextMenu()
+{
+ d->ABCMenu->clear();
+
+ int counter = 100;
+ KABC::AddressBook* ab = KABC::StdAddressBook::self();
+ QStringList names;
+ for ( KABC::AddressBook::Iterator it = ab->begin(); it != ab->end(); ++it )
+ {
+ names.push_back(it->formattedName());
+ }
+
+ qHeapSort(names);
+
+ for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it )
+ {
+ QString name = *it;
+ if ( !name.isNull() )
+ d->ABCMenu->insertItem( name, ++counter );
+ }
+
+ if (counter == 100)
+ {
+ d->ABCMenu->insertItem( i18n("No AddressBook Entries Found"), ++counter );
+ d->ABCMenu->setItemEnabled( counter, false );
+ }
+}
+
+void ImageDescEditTab::slotMoreMenu()
+{
+ d->moreMenu->clear();
+
+ if (singleSelection())
+ {
+ d->moreMenu->insertItem(i18n("Read metadata from file to database"), this, SLOT(slotReadFromFileMetadataToDatabase()));
+ int writeActionId = d->moreMenu->insertItem(i18n("Write metadata to each file"), this, SLOT(slotWriteToFileMetadataFromDatabase()));
+ // we do not need a "Write to file" action here because the apply button will do just that
+ // if selection is a single file.
+ // Adding the option will confuse users: Does the apply button not write to file?
+ // Removing the option will confuse users: There is not option to write to file! (not visible in single selection)
+ // Disabling will confuse users: Why is it disabled?
+ d->moreMenu->setItemEnabled(writeActionId, false);
+ }
+ else
+ {
+ // We need to make clear that this action is different from the Apply button,
+ // which saves the same changes to all files. These batch operations operate on each single file.
+ d->moreMenu->insertItem(i18n("Read metadata from each file to database"), this, SLOT(slotReadFromFileMetadataToDatabase()));
+ d->moreMenu->insertItem(i18n("Write metadata to each file"), this, SLOT(slotWriteToFileMetadataFromDatabase()));
+ }
+}
+
+void ImageDescEditTab::tagNew(TAlbum* parAlbum, const QString& _title, const QString& _icon) const
+{
+ if (!parAlbum)
+ return;
+
+ QString title = _title;
+ QString icon = _icon;
+
+ if (title.isNull())
+ {
+ if (!TagEditDlg::tagCreate(kapp->activeWindow(), parAlbum, title, icon))
+ return;
+ }
+
+ QMap<QString, QString> errMap;
+ AlbumList tList = TagEditDlg::createTAlbum(parAlbum, title, icon, errMap);
+ TagEditDlg::showtagsListCreationError(kapp->activeWindow(), errMap);
+
+ for (AlbumList::iterator it = tList.begin(); it != tList.end(); ++it)
+ {
+ TAlbumCheckListItem* item = (TAlbumCheckListItem*)(*it)->extraData(d->tagsView);
+ if (item)
+ {
+ item->setOn(true);
+ d->tagsView->setSelected(item, true);
+ d->tagsView->ensureItemVisible(item);
+ }
+ }
+}
+
+void ImageDescEditTab::tagDelete(TAlbum *album)
+{
+ if (!album || album->isRoot())
+ return;
+
+ AlbumManager *albumMan = AlbumManager::instance();
+
+ if (album == albumMan->currentAlbum() ||
+ album->isAncestorOf(albumMan->currentAlbum()))
+ {
+ KMessageBox::error(this, i18n("You are currently viewing items in the "
+ "tag '%1' that you are about to delete. "
+ "You will need to apply change first "
+ "if you want to delete the tag." )
+ .arg(album->title()));
+ return;
+ }
+
+ // find number of subtags
+ int children = 0;
+ AlbumIterator iter(album);
+ while(iter.current())
+ {
+ children++;
+ ++iter;
+ }
+
+ if(children)
+ {
+ int result = KMessageBox::warningContinueCancel(this,
+ i18n("Tag '%1' has one subtag. "
+ "Deleting this will also delete "
+ "the subtag. "
+ "Do you want to continue?",
+ "Tag '%1' has %n subtags. "
+ "Deleting this will also delete "
+ "the subtags. "
+ "Do you want to continue?",
+ children).arg(album->title()));
+
+ if(result != KMessageBox::Continue)
+ return;
+ }
+
+ QString message;
+ LLongList assignedItems = albumMan->albumDB()->getItemIDsInTag(album->id());
+ if (!assignedItems.isEmpty())
+ {
+ message = i18n("Tag '%1' is assigned to one item. "
+ "Do you want to continue?",
+ "Tag '%1' is assigned to %n items. "
+ "Do you want to continue?",
+ assignedItems.count()).arg(album->title());
+ }
+ else
+ {
+ message = i18n("Delete '%1' tag?").arg(album->title());
+ }
+
+ int result = KMessageBox::warningContinueCancel(this, message,
+ i18n("Delete Tag"),
+ KGuiItem(i18n("Delete"),
+ "editdelete"));
+
+ if (result == KMessageBox::Continue)
+ {
+ QString errMsg;
+ if (!albumMan->deleteTAlbum(album, errMsg))
+ KMessageBox::error(this, errMsg);
+ }
+}
+
+void ImageDescEditTab::tagEdit(TAlbum* album)
+{
+ if (!album || album->isRoot())
+ return;
+
+ QString title;
+ QString icon;
+
+ if (!TagEditDlg::tagEdit(kapp->activeWindow(), album, title, icon))
+ return;
+
+ AlbumManager *albumMan = AlbumManager::instance();
+ if (album->title() != title)
+ {
+ QString errMsg;
+ if (!albumMan->renameTAlbum(album, title, errMsg))
+ {
+ KMessageBox::error(this, errMsg);
+ return;
+ }
+ }
+
+ if (album->icon() != icon)
+ {
+ QString errMsg;
+ if (!albumMan->updateTAlbumIcon(album, icon, 0, errMsg))
+ {
+ KMessageBox::error(this, errMsg);
+ }
+ }
+}
+
+void ImageDescEditTab::slotAlbumAdded(Album* a)
+{
+ if (!a || a->type() != Album::TAG)
+ return;
+
+ TAlbumCheckListItem* viewItem = 0;
+
+ TAlbum* tag = dynamic_cast<TAlbum*>(a);
+ if (!tag)
+ return;
+
+ if (tag->isRoot())
+ {
+ viewItem = new TAlbumCheckListItem(d->tagsView, tag);
+ }
+ else
+ {
+ TAlbumCheckListItem* parent = (TAlbumCheckListItem*)(tag->parent()->extraData(d->tagsView));
+ if (!parent)
+ {
+ DWarning() << k_funcinfo << "Failed to find parent for Tag " << tag->title()
+ << endl;
+ return;
+ }
+
+ viewItem = new TAlbumCheckListItem(parent, tag);
+ d->tagsSearchBar->lineEdit()->completionObject()->addItem(tag->title());
+ d->newTagEdit->lineEdit()->completionObject()->addItem(tag->tagPath());
+ d->newTagEdit->lineEdit()->completionObject()->addItem(tag->tagPath().remove(0, 1)); // without root "/"
+ }
+
+ if (viewItem)
+ {
+ // commenting this out due to the issues described in bug 148166.
+ // viewItem->setOpen(true);
+ setTagThumbnail(tag);
+ }
+}
+
+void ImageDescEditTab::slotAlbumDeleted(Album* a)
+{
+ if (!a || a->isRoot() || a->type() != Album::TAG)
+ return;
+
+ TAlbum* album = (TAlbum*)a;
+
+ d->tagsSearchBar->lineEdit()->completionObject()->removeItem(album->title());
+ d->newTagEdit->lineEdit()->completionObject()->removeItem(album->tagPath());
+ d->newTagEdit->lineEdit()->completionObject()->removeItem(album->tagPath().remove(0, 1)); // without root "/"
+ TAlbumCheckListItem* viewItem = (TAlbumCheckListItem*)album->extraData(d->tagsView);
+ delete viewItem;
+ album->removeExtraData(this);
+ d->hub.setTag(album, false, MetadataHub::MetadataDisjoint);
+}
+
+void ImageDescEditTab::slotAlbumsCleared()
+{
+ d->tagsView->clear();
+ d->tagsSearchBar->lineEdit()->completionObject()->clear();
+ d->newTagEdit->lineEdit()->completionObject()->clear();
+}
+
+void ImageDescEditTab::slotAlbumIconChanged(Album* a)
+{
+ if (!a || a->isRoot() || a->type() != Album::TAG)
+ return;
+
+ setTagThumbnail((TAlbum *)a);
+}
+
+void ImageDescEditTab::slotAlbumMoved(TAlbum* tag, TAlbum* newParent)
+{
+ if (!tag || !newParent)
+ return;
+
+ TAlbumCheckListItem* item = (TAlbumCheckListItem*)tag->extraData(d->tagsView);
+ if (!item)
+ return;
+
+ if (item->parent())
+ {
+ QListViewItem* oldPItem = item->parent();
+ oldPItem->takeItem(item);
+ }
+ else
+ {
+ d->tagsView->takeItem(item);
+ }
+
+ TAlbumCheckListItem* newPItem = (TAlbumCheckListItem*)newParent->extraData(d->tagsView);
+ if (newPItem)
+ newPItem->insertItem(item);
+ else
+ d->tagsView->insertItem(item);
+}
+
+void ImageDescEditTab::slotAlbumRenamed(Album* album)
+{
+ if (!album || album->isRoot() || album->type() != Album::TAG)
+ return;
+
+ TAlbum* tag = (TAlbum*)album;
+ d->tagsSearchBar->lineEdit()->completionObject()->addItem(tag->title());
+ d->newTagEdit->lineEdit()->completionObject()->addItem(tag->tagPath());
+ d->newTagEdit->lineEdit()->completionObject()->addItem(tag->tagPath().remove(0, 1)); // without root "/"
+ slotTagsSearchChanged(d->tagsSearchBar->lineEdit()->text());
+ TAlbumCheckListItem* item = (TAlbumCheckListItem*)(tag->extraData(d->tagsView));
+ if (item)
+ item->refresh();
+}
+
+void ImageDescEditTab::toggleChildTags(TAlbum *album, bool b)
+{
+ if (!album)
+ return;
+
+ AlbumIterator it(album);
+ while ( it.current() )
+ {
+ TAlbum *ta = (TAlbum*)it.current();
+ TAlbumCheckListItem *item = (TAlbumCheckListItem*)(ta->extraData(d->tagsView));
+ if (item)
+ if (item->isVisible())
+ item->setOn(b);
+ ++it;
+ }
+}
+
+void ImageDescEditTab::toggleParentTags(TAlbum *album, bool b)
+{
+ if (!album)
+ return;
+
+ QListViewItemIterator it(d->tagsView);
+ while (it.current())
+ {
+ TAlbumCheckListItem* item = dynamic_cast<TAlbumCheckListItem*>(it.current());
+ if (item->isVisible())
+ {
+ if (!item->album())
+ continue;
+ if (item->album() == album->parent())
+ {
+ item->setOn(b);
+ toggleParentTags(item->album() , b);
+ }
+ }
+ ++it;
+ }
+}
+
+void ImageDescEditTab::setTagThumbnail(TAlbum *album)
+{
+ if(!album)
+ return;
+
+ TAlbumCheckListItem* item = (TAlbumCheckListItem*)album->extraData(d->tagsView);
+
+ if(!item)
+ return;
+
+ AlbumThumbnailLoader *loader = AlbumThumbnailLoader::instance();
+ QPixmap icon;
+ if (!loader->getTagThumbnail(album, icon))
+ {
+ if (icon.isNull())
+ {
+ item->setPixmap(0, loader->getStandardTagIcon(album));
+ }
+ else
+ {
+ QPixmap blendedIcon = loader->blendIcons(loader->getStandardTagIcon(), icon);
+ item->setPixmap(0, blendedIcon);
+ }
+ }
+}
+
+void ImageDescEditTab::slotGotThumbnailFromIcon(Album *album, const QPixmap& thumbnail)
+{
+ if(!album || album->type() != Album::TAG)
+ return;
+
+ // update item in tags tree
+ TAlbumCheckListItem* item = (TAlbumCheckListItem*)album->extraData(d->tagsView);
+ if(!item)
+ return;
+
+ AlbumThumbnailLoader *loader = AlbumThumbnailLoader::instance();
+ QPixmap blendedIcon = loader->blendIcons(loader->getStandardTagIcon(), thumbnail);
+ item->setPixmap(0, blendedIcon);
+
+ // update item in recent tags popup menu, if found there in
+ QPopupMenu *menu = d->recentTagsBtn->popup();
+ if (menu->indexOf(album->id()) != -1)
+ {
+ menu->changeItem(album->id(), thumbnail, menu->text(album->id()));
+ }
+}
+
+void ImageDescEditTab::slotThumbnailLost(Album *)
+{
+ // we already set the standard icon before loading
+}
+
+void ImageDescEditTab::slotReloadThumbnails()
+{
+ AlbumList tList = AlbumManager::instance()->allTAlbums();
+ for (AlbumList::iterator it = tList.begin(); it != tList.end(); ++it)
+ {
+ TAlbum* tag = (TAlbum*)(*it);
+ setTagThumbnail(tag);
+ }
+}
+
+void ImageDescEditTab::slotImageTagsChanged(Q_LLONG imageId)
+{
+ // don't lose modifications
+ if (d->ignoreImageAttributesWatch || d->modified)
+ return;
+
+ reloadForMetadataChange(imageId);
+}
+
+void ImageDescEditTab::slotImagesChanged(int albumId)
+{
+ if (d->ignoreImageAttributesWatch || d->modified)
+ return;
+
+ Album *a = AlbumManager::instance()->findAlbum(albumId);
+ if (d->currInfos.isEmpty() || !a || a->isRoot() || a->type() != Album::TAG)
+ return;
+
+ setInfos(d->currInfos);
+}
+
+void ImageDescEditTab::slotImageRatingChanged(Q_LLONG imageId)
+{
+ if (d->ignoreImageAttributesWatch || d->modified)
+ return;
+
+ reloadForMetadataChange(imageId);
+}
+
+void ImageDescEditTab::slotImageCaptionChanged(Q_LLONG imageId)
+{
+ if (d->ignoreImageAttributesWatch || d->modified)
+ return;
+
+ reloadForMetadataChange(imageId);
+}
+
+void ImageDescEditTab::slotImageDateChanged(Q_LLONG imageId)
+{
+ if (d->ignoreImageAttributesWatch || d->modified)
+ return;
+
+ reloadForMetadataChange(imageId);
+}
+
+// private common code for above methods
+void ImageDescEditTab::reloadForMetadataChange(Q_LLONG imageId)
+{
+ if (d->currInfos.isEmpty())
+ return;
+
+ if (singleSelection())
+ {
+ if (d->currInfos.first()->id() == imageId)
+ setInfos(d->currInfos);
+ }
+ else
+ {
+ // if image id is in our list, update
+ for (ImageInfo *info = d->currInfos.first(); info; info = d->currInfos.next())
+ {
+ if (info->id() == imageId)
+ {
+ setInfos(d->currInfos);
+ return;
+ }
+ }
+ }
+}
+
+void ImageDescEditTab::updateRecentTags()
+{
+ QPopupMenu *menu = d->recentTagsBtn->popup();
+ menu->clear();
+
+ AlbumManager* albumMan = AlbumManager::instance();
+ IntList recentTags = albumMan->albumDB()->getRecentlyAssignedTags();
+
+ if (recentTags.isEmpty())
+ {
+ menu->insertItem(i18n("No Recently Assigned Tags"), 0);
+ menu->setItemEnabled(0, false);
+ }
+ else
+ {
+ for (IntList::const_iterator it = recentTags.begin();
+ it != recentTags.end(); ++it)
+ {
+ TAlbum* album = albumMan->findTAlbum(*it);
+ if (album)
+ {
+ AlbumThumbnailLoader *loader = AlbumThumbnailLoader::instance();
+ QPixmap icon;
+ if (!loader->getTagThumbnail(album, icon))
+ {
+ if (icon.isNull())
+ {
+ icon = loader->getStandardTagIcon(album, AlbumThumbnailLoader::SmallerSize);
+ }
+ }
+ QString text = album->title() + " (" + ((TAlbum*)album->parent())->prettyURL() + ')';
+ menu->insertItem(icon, text, album->id());
+ }
+ }
+ }
+}
+
+void ImageDescEditTab::slotRecentTagsMenuActivated(int id)
+{
+ AlbumManager* albumMan = AlbumManager::instance();
+
+ if (id > 0)
+ {
+ TAlbum* album = albumMan->findTAlbum(id);
+ if (album)
+ {
+ TAlbumCheckListItem* viewItem = (TAlbumCheckListItem*)album->extraData(d->tagsView);
+ if (viewItem)
+ {
+ viewItem->setOn(true);
+ d->tagsView->setSelected(viewItem, true);
+ d->tagsView->ensureItemVisible(viewItem);
+ }
+ }
+ }
+}
+
+void ImageDescEditTab::slotTagsSearchChanged(const QString& filter)
+{
+ if (filter.isEmpty())
+ {
+ d->tagsView->collapseView(FolderView::OmitRoot);
+ return;
+ }
+
+ //TODO: this will destroy assigned-tags filtering. Unify in one method.
+ QString search = filter.lower();
+
+ bool atleastOneMatch = false;
+
+ AlbumList tList = AlbumManager::instance()->allTAlbums();
+ for (AlbumList::iterator it = tList.begin(); it != tList.end(); ++it)
+ {
+ TAlbum* tag = (TAlbum*)(*it);
+
+ // don't touch the root Tag
+ if (tag->isRoot())
+ continue;
+
+ bool match = tag->title().lower().contains(search);
+ bool doesExpand = false;
+ if (!match)
+ {
+ // check if any of the parents match the search
+ Album* parent = tag->parent();
+ while (parent && !parent->isRoot())
+ {
+ if (parent->title().lower().contains(search))
+ {
+ match = true;
+ break;
+ }
+
+ parent = parent->parent();
+ }
+ }
+
+ if (!match)
+ {
+ // check if any of the children match the search
+ AlbumIterator it(tag);
+ while (it.current())
+ {
+ if ((*it)->title().lower().contains(search))
+ {
+ match = true;
+ doesExpand = true;
+ break;
+ }
+ ++it;
+ }
+ }
+
+ TAlbumCheckListItem* viewItem = (TAlbumCheckListItem*)(tag->extraData(d->tagsView));
+
+ if (match)
+ {
+ atleastOneMatch = true;
+
+ if (viewItem)
+ {
+ viewItem->setVisible(true);
+ viewItem->setOpen(doesExpand);
+ }
+ }
+ else
+ {
+ if (viewItem)
+ {
+ viewItem->setVisible(false);
+ viewItem->setOpen(false);
+ }
+ }
+ }
+
+ if (search.isEmpty())
+ {
+ TAlbum* root = AlbumManager::instance()->findTAlbum(0);
+ TAlbumCheckListItem* rootItem = (TAlbumCheckListItem*)(root->extraData(d->tagsView));
+ if (rootItem)
+ rootItem->setText(0, root->title());
+ }
+ else
+ {
+ TAlbum* root = AlbumManager::instance()->findTAlbum(0);
+ TAlbumCheckListItem* rootItem = (TAlbumCheckListItem*)(root->extraData(d->tagsView));
+ if (rootItem)
+ rootItem->setText(0, i18n("Found Tags"));
+ }
+
+ emit signalTagFilterMatch(atleastOneMatch);
+}
+
+void ImageDescEditTab::slotAssignedTagsToggled(bool t)
+{
+ //TODO: this will destroy name filtering. Unify in one method.
+ QListViewItemIterator it(d->tagsView);
+ while (it.current())
+ {
+ TAlbumCheckListItem* item = dynamic_cast<TAlbumCheckListItem*>(it.current());
+ TAlbum *tag = item->album();
+ if (tag)
+ {
+ if (!tag->isRoot())
+ {
+ if (t)
+ {
+ MetadataHub::TagStatus status = d->hub.tagStatus(item->album());
+ bool tagAssigned = (status == MetadataHub::MetadataAvailable && status.hasTag)
+ || status == MetadataHub::MetadataDisjoint;
+ item->setVisible(tagAssigned);
+
+ if (tagAssigned)
+ {
+ Album* parent = tag->parent();
+ while (parent && !parent->isRoot())
+ {
+ TAlbumCheckListItem *pitem = (TAlbumCheckListItem*)parent->extraData(d->tagsView);
+ pitem->setVisible(true);
+ parent = parent->parent();
+ }
+ }
+ }
+ else
+ {
+ item->setVisible(true);
+ }
+ }
+ }
+ ++it;
+ }
+
+ // correct visibilities afterwards:
+ // As QListViewItem::setVisible works recursively on all it's children
+ // we have to correct this
+ if (t)
+ {
+ it = d->tagsView;
+ while (it.current())
+ {
+ TAlbumCheckListItem* item = dynamic_cast<TAlbumCheckListItem*>(it.current());
+ TAlbum *tag = item->album();
+ if (tag)
+ {
+ if (!tag->isRoot())
+ {
+ // only if the current item is not marked as tagged, check all children
+ MetadataHub::TagStatus status = d->hub.tagStatus(item->album());
+ bool tagAssigned = (status == MetadataHub::MetadataAvailable && status.hasTag)
+ || status == MetadataHub::MetadataDisjoint;
+ if (!tagAssigned)
+ {
+ bool somethingIsSet = false;
+ QListViewItem* nextSibling = (*it)->nextSibling();
+ QListViewItemIterator tmpIt = it;
+ ++tmpIt;
+ while (*tmpIt != nextSibling )
+ {
+ TAlbumCheckListItem* tmpItem = dynamic_cast<TAlbumCheckListItem*>(tmpIt.current());
+ MetadataHub::TagStatus tmpStatus = d->hub.tagStatus(tmpItem->album());
+ bool tmpTagAssigned = (tmpStatus == MetadataHub::MetadataAvailable && tmpStatus.hasTag)
+ || tmpStatus == MetadataHub::MetadataDisjoint;
+ if(tmpTagAssigned)
+ {
+ somethingIsSet = true;
+ }
+ ++tmpIt;
+ }
+ if (!somethingIsSet)
+ {
+ item->setVisible(false);
+ }
+ }
+ }
+ }
+ ++it;
+ }
+ }
+
+ TAlbum *root = AlbumManager::instance()->findTAlbum(0);
+ TAlbumCheckListItem *rootItem = (TAlbumCheckListItem*)(root->extraData(d->tagsView));
+ if (rootItem)
+ {
+ if (t)
+ rootItem->setText(0, i18n("Assigned Tags"));
+ else
+ rootItem->setText(0, root->title());
+ }
+}
+
+void ImageDescEditTab::refreshTagsView()
+{
+ d->tagsView->refresh();
+}
+
+void ImageDescEditTab::slotCreateNewTag()
+{
+ QString tagStr = d->newTagEdit->text();
+ if (tagStr.isEmpty()) return;
+
+ TAlbum *mainRootAlbum = 0;
+ TAlbumCheckListItem* item = dynamic_cast<TAlbumCheckListItem*>(d->tagsView->selectedItem());
+ if (item)
+ mainRootAlbum = item->album();
+
+ QMap<QString, QString> errMap;
+ AlbumList tList = TagEditDlg::createTAlbum(mainRootAlbum, tagStr, QString("tag"), errMap);
+
+ for (AlbumList::iterator it = tList.begin(); it != tList.end(); ++it)
+ {
+ TAlbumCheckListItem* item = (TAlbumCheckListItem*)(*it)->extraData(d->tagsView);
+ if (item)
+ {
+ item->setOn(true);
+ d->tagsView->ensureItemVisible(item);
+ }
+ }
+
+ d->newTagEdit->lineEdit()->clear();
+}
+
+} // NameSpace Digikam
diff --git a/digikam/libs/imageproperties/imagedescedittab.h b/digikam/libs/imageproperties/imagedescedittab.h
new file mode 100644
index 0000000..7a25738
--- /dev/null
+++ b/digikam/libs/imageproperties/imagedescedittab.h
@@ -0,0 +1,144 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2003-03-09
+ * Description : Captions, Tags, and Rating properties editor
+ *
+ * Copyright (C) 2003-2005 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
+ * Copyright (C) 2003-2009 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ * Copyright (C) 2006-2009 by Marcel Wiesweg <marcel.wiesweg@gmx.de>
+ * Copyright (C) 2009 by Andi Clemens <andi dot clemens at gmx dot net>
+ *
+ * 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 IMAGEDESCEDITTAB_H
+#define IMAGEDESCEDITTAB_H
+
+// Qt includes.
+
+#include <qwidget.h>
+#include <qpixmap.h>
+#include <qptrlist.h>
+
+// Local includes.
+
+#include "digikam_export.h"
+#include "navigatebartab.h"
+#include "albummanager.h"
+
+class QListViewItem;
+
+namespace Digikam
+{
+class TAlbumCheckListItem;
+class ImageInfo;
+class ImageDescEditTabPriv;
+
+class DIGIKAM_EXPORT ImageDescEditTab : public NavigateBarTab
+{
+ Q_OBJECT
+
+public:
+
+ ImageDescEditTab(QWidget *parent, bool navBar=true);
+ ~ImageDescEditTab();
+
+ void assignRating(int rating);
+ void setItem(ImageInfo *info=0);
+ void setItems(QPtrList<ImageInfo> infos);
+ void populateTags();
+ void refreshTagsView();
+
+signals:
+
+ void signalProgressBarMode(int, const QString&);
+ void signalProgressValue(int);
+ void signalTagFilterMatch(bool);
+
+protected:
+
+ bool eventFilter(QObject *o, QEvent *e);
+
+private:
+
+ void setInfos(QPtrList<ImageInfo> infos);
+
+ void updateTagsView();
+ void updateComments();
+ void updateRating();
+ void updateDate();
+ void updateRecentTags();
+
+ void tagNew(TAlbum* parAlbum, const QString& _title=QString(), const QString& _icon=QString()) const;
+ void tagEdit(TAlbum* album);
+ void tagDelete(TAlbum *album);
+
+ void toggleChildTags(TAlbum *album, bool b);
+ void toggleParentTags(TAlbum *album, bool b);
+
+ void setTagThumbnail(TAlbum *album);
+
+ bool singleSelection() const;
+ void setMetadataWidgetStatus(int status, QWidget *widget);
+ void reloadForMetadataChange(Q_LLONG imageId);
+
+private slots:
+
+ void slotApplyAllChanges();
+ void slotCreateNewTag();
+ void slotRevertAllChanges();
+ void slotChangingItems();
+ void slotItemStateChanged(TAlbumCheckListItem *);
+ void slotCommentChanged();
+ void slotDateTimeChanged(const QDateTime& dateTime);
+ void slotRatingChanged(int rating);
+ void slotModified();
+ void slotRightButtonClicked(QListViewItem *, const QPoint &, int);
+ void slotTagsSearchChanged(const QString&);
+
+ void slotAlbumAdded(Album* a);
+ void slotAlbumDeleted(Album* a);
+ void slotAlbumIconChanged(Album* a);
+ void slotAlbumRenamed(Album* a);
+ void slotAlbumsCleared();
+ void slotAlbumMoved(TAlbum* tag, TAlbum* newParent);
+
+ void slotABCContextMenu();
+ void slotGotThumbnailFromIcon(Album *album, const QPixmap& thumbnail);
+ void slotThumbnailLost(Album *album);
+ void slotReloadThumbnails();
+
+ void slotImageTagsChanged(Q_LLONG imageId);
+ void slotImagesChanged(int albumId);
+ void slotImageRatingChanged(Q_LLONG imageId);
+ void slotImageDateChanged(Q_LLONG imageId);
+ void slotImageCaptionChanged(Q_LLONG imageId);
+
+ void slotRecentTagsMenuActivated(int);
+ void slotAssignedTagsToggled(bool);
+
+ void slotMoreMenu();
+ void slotReadFromFileMetadataToDatabase();
+ void slotWriteToFileMetadataFromDatabase();
+
+private:
+
+ ImageDescEditTabPriv* d;
+};
+
+} // NameSpace Digikam
+
+#endif // IMAGEDESCEDITTAB_H
diff --git a/digikam/libs/imageproperties/imagepropertiescolorstab.cpp b/digikam/libs/imageproperties/imagepropertiescolorstab.cpp
new file mode 100644
index 0000000..5201c55
--- /dev/null
+++ b/digikam/libs/imageproperties/imagepropertiescolorstab.cpp
@@ -0,0 +1,799 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-11-17
+ * Description : a tab to display colors information of images
+ *
+ * Copyright (C) 2004-2008 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.
+ *
+ * ============================================================ */
+
+// C++ includes.
+
+#include <cmath>
+
+// Qt includes.
+
+#include <qlayout.h>
+#include <qspinbox.h>
+#include <qcombobox.h>
+#include <qlabel.h>
+#include <qwhatsthis.h>
+#include <qgroupbox.h>
+#include <qhbuttongroup.h>
+#include <qpushbutton.h>
+#include <qtooltip.h>
+#include <qvbox.h>
+#include <qscrollview.h>
+
+// KDE includes.
+
+#include <klocale.h>
+#include <ksqueezedtextlabel.h>
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kdialogbase.h>
+#include <kstandarddirs.h>
+#include <ktabwidget.h>
+
+// Local includes.
+
+#include "ddebug.h"
+#include "dimg.h"
+#include "imagehistogram.h"
+#include "histogramwidget.h"
+#include "colorgradientwidget.h"
+#include "navigatebarwidget.h"
+#include "sharedloadsavethread.h"
+#include "iccprofilewidget.h"
+#include "cietonguewidget.h"
+#include "imagepropertiescolorstab.h"
+#include "imagepropertiescolorstab.moc"
+
+namespace Digikam
+{
+
+class ImagePropertiesColorsTabPriv
+{
+public:
+
+ enum MetadataTab
+ {
+ HISTOGRAM=0,
+ ICCPROFILE
+ };
+
+ ImagePropertiesColorsTabPriv()
+ {
+ imageLoaderThread = 0;
+ tab = 0;
+ channelCB = 0;
+ colorsCB = 0;
+ renderingCB = 0;
+ scaleBG = 0;
+ regionBG = 0;
+ minInterv = 0;
+ maxInterv = 0;
+ labelMeanValue = 0;
+ labelPixelsValue = 0;
+ labelStdDevValue = 0;
+ labelCountValue = 0;
+ labelMedianValue = 0;
+ labelPercentileValue = 0;
+ labelColorDepth = 0;
+ labelAlphaChannel = 0;
+
+ iccProfileWidget = 0;
+ hGradient = 0;
+ histogramWidget = 0;
+ imageLoaderThread = 0;
+
+ inLoadingProcess = false;
+ }
+
+ bool inLoadingProcess;
+
+ QComboBox *channelCB;
+ QComboBox *colorsCB;
+ QComboBox *renderingCB;
+
+ QHButtonGroup *scaleBG;
+ QHButtonGroup *regionBG;
+
+ QSpinBox *minInterv;
+ QSpinBox *maxInterv;
+
+ QLabel *labelMeanValue;
+ QLabel *labelPixelsValue;
+ QLabel *labelStdDevValue;
+ QLabel *labelCountValue;
+ QLabel *labelMedianValue;
+ QLabel *labelPercentileValue;
+ QLabel *labelColorDepth;
+ QLabel *labelAlphaChannel;
+
+ QString currentFilePath;
+ LoadingDescription currentLoadingDescription;
+
+ QRect selectionArea;
+
+ QByteArray embedded_profile;
+
+ KTabWidget *tab;
+
+ DImg image;
+ DImg imageSelection;
+
+ ICCProfileWidget *iccProfileWidget;
+ ColorGradientWidget *hGradient;
+ HistogramWidget *histogramWidget;
+ SharedLoadSaveThread *imageLoaderThread;
+};
+
+ImagePropertiesColorsTab::ImagePropertiesColorsTab(QWidget* parent, bool navBar)
+ : NavigateBarTab(parent)
+{
+ d = new ImagePropertiesColorsTabPriv;
+
+ setupNavigateBar(navBar);
+ d->tab = new KTabWidget(this);
+ m_navigateBarLayout->addWidget(d->tab);
+
+ // Histogram tab area -----------------------------------------------------
+
+ QScrollView *sv = new QScrollView(d->tab);
+ sv->viewport()->setBackgroundMode(Qt::PaletteBackground);
+ sv->setResizePolicy(QScrollView::AutoOneFit);
+ sv->setFrameStyle(QFrame::NoFrame);
+
+ QWidget* histogramPage = new QWidget(sv->viewport());
+ QGridLayout *topLayout = new QGridLayout(histogramPage, 8, 3,
+ KDialog::spacingHint(), KDialog::spacingHint());
+ sv->addChild(histogramPage);
+
+ QLabel *label1 = new QLabel(i18n("Channel:"), histogramPage);
+ label1->setAlignment ( Qt::AlignRight | Qt::AlignVCenter );
+ d->channelCB = new QComboBox( false, histogramPage );
+ d->channelCB->insertItem( i18n("Luminosity") );
+ d->channelCB->insertItem( i18n("Red") );
+ d->channelCB->insertItem( i18n("Green") );
+ d->channelCB->insertItem( i18n("Blue") );
+ d->channelCB->insertItem( i18n("Alpha") );
+ d->channelCB->insertItem( i18n("Colors") );
+ QWhatsThis::add( d->channelCB, i18n("<p>Select the histogram channel to display here:<p>"
+ "<b>Luminosity</b>: Display luminosity (perceived brightness) values.<p>"
+ "<b>Red</b>: Display the red image channel.<p>"
+ "<b>Green</b>: Display the green image channel.<p>"
+ "<b>Blue</b>: Display the blue image channel.<p>"
+ "<b>Alpha</b>: Display the alpha image channel. "
+ "This channel corresponds to the transparency value and "
+ "is supported by some image formats such as PNG or TIFF.<p>"
+ "<b>Colors</b>: Display all color channel values at the same time."));
+
+ d->scaleBG = new QHButtonGroup(histogramPage);
+ d->scaleBG->setExclusive(true);
+ d->scaleBG->setFrameShape(QFrame::NoFrame);
+ d->scaleBG->setInsideMargin( 0 );
+ QWhatsThis::add( d->scaleBG, i18n("<p>Select the histogram scale here.<p>"
+ "If the image's maximal values are small, you can use the linear scale.<p>"
+ "Logarithmic scale can be used when the maximal values are big; "
+ "if it is used, all values (small and large) will be visible on the "
+ "graph."));
+
+ QPushButton *linHistoButton = new QPushButton( d->scaleBG );
+ QToolTip::add( linHistoButton, i18n( "<p>Linear" ) );
+ d->scaleBG->insert(linHistoButton, HistogramWidget::LinScaleHistogram);
+ KGlobal::dirs()->addResourceType("histogram-lin", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ QString directory = KGlobal::dirs()->findResourceDir("histogram-lin", "histogram-lin.png");
+ linHistoButton->setPixmap( QPixmap( directory + "histogram-lin.png" ) );
+ linHistoButton->setToggleButton(true);
+
+ QPushButton *logHistoButton = new QPushButton( d->scaleBG );
+ QToolTip::add( logHistoButton, i18n( "<p>Logarithmic" ) );
+ d->scaleBG->insert(logHistoButton, HistogramWidget::LogScaleHistogram);
+ KGlobal::dirs()->addResourceType("histogram-log", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ directory = KGlobal::dirs()->findResourceDir("histogram-log", "histogram-log.png");
+ logHistoButton->setPixmap( QPixmap( directory + "histogram-log.png" ) );
+ logHistoButton->setToggleButton(true);
+
+ QLabel *label10 = new QLabel(i18n("Colors:"), histogramPage);
+ label10->setAlignment ( Qt::AlignRight | Qt::AlignVCenter );
+ d->colorsCB = new QComboBox( false, histogramPage );
+ d->colorsCB->insertItem( i18n("Red") );
+ d->colorsCB->insertItem( i18n("Green") );
+ d->colorsCB->insertItem( i18n("Blue") );
+ d->colorsCB->setEnabled( false );
+ QWhatsThis::add( d->colorsCB, i18n("<p>Select the main color displayed with Colors Channel mode here:<p>"
+ "<b>Red</b>: Draw the red image channel in the foreground.<p>"
+ "<b>Green</b>: Draw the green image channel in the foreground.<p>"
+ "<b>Blue</b>: Draw the blue image channel in the foreground.<p>"));
+
+ d->regionBG = new QHButtonGroup(histogramPage);
+ d->regionBG->setExclusive(true);
+ d->regionBG->setFrameShape(QFrame::NoFrame);
+ d->regionBG->setInsideMargin( 0 );
+ d->regionBG->hide();
+ QWhatsThis::add( d->regionBG, i18n("<p>Select from which region the histogram will be computed here:<p>"
+ "<b>Full Image</b>: Compute histogram using the full image.<p>"
+ "<b>Selection</b>: Compute histogram using the current image "
+ "selection."));
+
+ QPushButton *fullImageButton = new QPushButton( d->regionBG );
+ QToolTip::add( fullImageButton, i18n( "<p>Full Image" ) );
+ d->regionBG->insert(fullImageButton, HistogramWidget::FullImageHistogram);
+ KGlobal::dirs()->addResourceType("image-full", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ directory = KGlobal::dirs()->findResourceDir("image-full", "image-full.png");
+ fullImageButton->setPixmap( QPixmap( directory + "image-full.png" ) );
+ fullImageButton->setToggleButton(true);
+
+ QPushButton *SelectionImageButton = new QPushButton( d->regionBG );
+ QToolTip::add( SelectionImageButton, i18n( "<p>Selection" ) );
+ d->regionBG->insert(SelectionImageButton, HistogramWidget::ImageSelectionHistogram);
+ KGlobal::dirs()->addResourceType("image-selection", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ directory = KGlobal::dirs()->findResourceDir("image-selection", "image-selection.png");
+ SelectionImageButton->setPixmap( QPixmap( directory + "image-selection.png" ) );
+ SelectionImageButton->setToggleButton(true);
+
+ // -------------------------------------------------------------
+
+ QVBox *histoBox = new QVBox(histogramPage);
+ d->histogramWidget = new HistogramWidget(256, 140, histoBox);
+ QWhatsThis::add( d->histogramWidget, i18n("<p>This is the histogram drawing of the "
+ "selected image channel"));
+ QLabel *space = new QLabel(histoBox);
+ space->setFixedHeight(1);
+ d->hGradient = new ColorGradientWidget(ColorGradientWidget::Horizontal, 10, histoBox);
+ d->hGradient->setColors(QColor("black"), QColor("white"));
+
+ // -------------------------------------------------------------
+
+ QHBoxLayout *hlay2 = new QHBoxLayout(KDialog::spacingHint());
+ QLabel *label3 = new QLabel(i18n("Range:"), histogramPage);
+ label3->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
+ d->minInterv = new QSpinBox(0, 255, 1, histogramPage);
+ d->minInterv->setValue(0);
+ QWhatsThis::add(d->minInterv, i18n("<p>Select the minimal intensity "
+ "value of the histogram selection here."));
+ d->maxInterv = new QSpinBox(0, 255, 1, histogramPage);
+ d->maxInterv->setValue(255);
+ QWhatsThis::add(d->minInterv, i18n("<p>Select the maximal intensity value "
+ "of the histogram selection here."));
+ hlay2->addWidget(label3);
+ hlay2->addWidget(d->minInterv);
+ hlay2->addWidget(d->maxInterv);
+
+ // -------------------------------------------------------------
+
+ QGroupBox *gbox = new QGroupBox(2, Qt::Horizontal, i18n("Statistics"), histogramPage);
+ QWhatsThis::add( gbox, i18n("<p>Here you can see the statistical results calculated from the "
+ "selected histogram part. These values are available for all "
+ "channels."));
+
+ QLabel *label5 = new QLabel(i18n("Pixels:"), gbox);
+ label5->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
+ d->labelPixelsValue = new QLabel(gbox);
+ d->labelPixelsValue->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+
+ QLabel *label7 = new QLabel(i18n("Count:"), gbox);
+ label7->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
+ d->labelCountValue = new QLabel(gbox);
+ d->labelCountValue->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+
+ QLabel *label4 = new QLabel(i18n("Mean:"), gbox);
+ label4->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
+ d->labelMeanValue = new QLabel(gbox);
+ d->labelMeanValue->setAlignment (Qt::AlignRight | Qt::AlignVCenter);
+
+ QLabel *label6 = new QLabel(i18n("Std. deviation:"), gbox);
+ label6->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
+ d->labelStdDevValue = new QLabel(gbox);
+ d->labelStdDevValue->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+
+ QLabel *label8 = new QLabel(i18n("Median:"), gbox);
+ label8->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
+ d->labelMedianValue = new QLabel(gbox);
+ d->labelMedianValue->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+
+ QLabel *label9 = new QLabel(i18n("Percentile:"), gbox);
+ label9->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
+ d->labelPercentileValue = new QLabel(gbox);
+ d->labelPercentileValue->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+
+ QLabel *label11 = new QLabel(i18n("Color depth:"), gbox);
+ label11->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
+ d->labelColorDepth = new QLabel(gbox);
+ d->labelColorDepth->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+
+ QLabel *label12 = new QLabel(i18n("Alpha Channel:"), gbox);
+ label12->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
+ d->labelAlphaChannel = new QLabel(gbox);
+ d->labelAlphaChannel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+
+ topLayout->addMultiCellWidget(label1, 1, 1, 0, 0);
+ topLayout->addMultiCellWidget(d->channelCB, 1, 1, 1, 1);
+ topLayout->addMultiCellWidget(d->scaleBG, 1, 1, 3, 3);
+ topLayout->addMultiCellWidget(label10, 2, 2, 0, 0);
+ topLayout->addMultiCellWidget(d->colorsCB, 2, 2, 1, 1);
+ topLayout->addMultiCellWidget(d->regionBG, 2, 2, 3, 3);
+ topLayout->addMultiCellWidget(histoBox, 3, 4, 0, 3);
+ topLayout->addMultiCellLayout(hlay2, 5, 5, 0, 3);
+ topLayout->addMultiCellWidget(gbox, 6, 6, 0, 3);
+ topLayout->setColStretch(2, 10);
+ topLayout->setRowStretch(7, 10);
+
+ d->tab->insertTab(sv, i18n("Histogram"), ImagePropertiesColorsTabPriv::HISTOGRAM );
+
+ // ICC Profiles tab area ---------------------------------------
+
+ QScrollView *sv2 = new QScrollView(d->tab);
+ sv2->viewport()->setBackgroundMode(Qt::PaletteBackground);
+ sv2->setResizePolicy(QScrollView::AutoOneFit);
+ sv2->setFrameStyle(QFrame::NoFrame);
+
+ d->iccProfileWidget = new ICCProfileWidget(sv2->viewport());
+ sv2->addChild(d->iccProfileWidget);
+ d->tab->insertTab(sv2, i18n("ICC profile"), ImagePropertiesColorsTabPriv::ICCPROFILE);
+
+ // -------------------------------------------------------------
+
+ connect(d->channelCB, SIGNAL(activated(int)),
+ this, SLOT(slotChannelChanged(int)));
+
+ connect(d->scaleBG, SIGNAL(released(int)),
+ this, SLOT(slotScaleChanged(int)));
+
+ connect(d->colorsCB, SIGNAL(activated(int)),
+ this, SLOT(slotColorsChanged(int)));
+
+ connect(d->regionBG, SIGNAL(released(int)),
+ this, SLOT(slotRenderingChanged(int)));
+
+ connect(d->histogramWidget, SIGNAL(signalIntervalChanged( int, int )),
+ this, SLOT(slotUpdateInterval(int, int)));
+
+ connect(d->histogramWidget, SIGNAL(signalMaximumValueChanged( int )),
+ this, SLOT(slotUpdateIntervRange(int)));
+
+ connect(d->histogramWidget, SIGNAL(signalHistogramComputationDone(bool)),
+ this, SLOT(slotRefreshOptions(bool)));
+
+ connect(d->histogramWidget, SIGNAL(signalHistogramComputationFailed(void)),
+ this, SLOT(slotHistogramComputationFailed(void)));
+
+ connect(d->minInterv, SIGNAL(valueChanged (int)),
+ this, SLOT(slotMinValueChanged(int)));
+
+ connect(d->maxInterv, SIGNAL(valueChanged (int)),
+ this, SLOT(slotMaxValueChanged(int)));
+
+ // -- read config ---------------------------------------------------------
+
+ KConfig* config = kapp->config();
+ config->setGroup("Image Properties SideBar");
+ d->tab->setCurrentPage(config->readNumEntry("ImagePropertiesColors Tab",
+ ImagePropertiesColorsTabPriv::HISTOGRAM));
+ d->iccProfileWidget->setMode(config->readNumEntry("ICC Level", ICCProfileWidget::SIMPLE));
+ d->iccProfileWidget->setCurrentItemByKey(config->readEntry("Current ICC Item", QString()));
+
+ d->channelCB->setCurrentItem(config->readNumEntry("Histogram Channel", 0)); // Luminosity.
+ d->scaleBG->setButton(config->readNumEntry("Histogram Scale", HistogramWidget::LogScaleHistogram));
+ d->colorsCB->setCurrentItem(config->readNumEntry("Histogram Color", 0)); // Red.
+ d->regionBG->setButton(config->readNumEntry("Histogram Rendering", HistogramWidget::FullImageHistogram));
+}
+
+ImagePropertiesColorsTab::~ImagePropertiesColorsTab()
+{
+ // If there is a currently histogram computation when dialog is closed,
+ // stop it before the d->image data are deleted automatically!
+ d->histogramWidget->stopHistogramComputation();
+
+ KConfig* config = kapp->config();
+ config->setGroup("Image Properties SideBar");
+ config->writeEntry("ImagePropertiesColors Tab", d->tab->currentPageIndex());
+ config->writeEntry("Histogram Channel", d->channelCB->currentItem());
+ config->writeEntry("Histogram Scale", d->scaleBG->selectedId());
+ config->writeEntry("Histogram Color", d->colorsCB->currentItem());
+ config->writeEntry("Histogram Rendering", d->regionBG->selectedId());
+ config->writeEntry("ICC Level", d->iccProfileWidget->getMode());
+ config->writeEntry("Current ICC Item", d->iccProfileWidget->getCurrentItemKey());
+ config->sync();
+
+ if (d->imageLoaderThread)
+ delete d->imageLoaderThread;
+
+ if (d->histogramWidget)
+ delete d->histogramWidget;
+
+ if (d->hGradient)
+ delete d->hGradient;
+
+ delete d;
+}
+
+void ImagePropertiesColorsTab::setData(const KURL& url, const QRect &selectionArea,
+ DImg *img)
+{
+ // We might be getting duplicate events from AlbumIconView,
+ // which will cause all sorts of duplicate work.
+ // More importantly, while the loading thread can handle this pretty well,
+ // this will completely mess up the timing of progress info in the histogram widget.
+ // So filter here, before the stopHistogramComputation!
+ if (!img && url.path() == d->currentFilePath && d->inLoadingProcess)
+ return;
+
+ // This is necessary to stop computation because d->image.bits() is currently used by
+ // threaded histogram algorithm.
+ d->histogramWidget->stopHistogramComputation();
+
+ d->currentFilePath = QString();
+ d->currentLoadingDescription = LoadingDescription();
+ d->iccProfileWidget->loadFromURL(KURL());
+
+ // Clear information.
+ d->labelMeanValue->clear();
+ d->labelPixelsValue->clear();
+ d->labelStdDevValue->clear();
+ d->labelCountValue->clear();
+ d->labelMedianValue->clear();
+ d->labelPercentileValue->clear();
+ d->labelColorDepth->clear();
+ d->labelAlphaChannel->clear();
+
+ if (url.isEmpty())
+ {
+ setEnabled(false);
+ return;
+ }
+
+ d->selectionArea = selectionArea;
+ d->image.reset();
+ setEnabled(true);
+
+ if (!img)
+ {
+ loadImageFromUrl(url);
+ }
+ else
+ {
+ d->image = img->copy();
+
+ if ( !d->image.isNull() )
+ {
+ getICCData();
+
+ // If a selection area is done in Image Editor and if the current image is the same
+ // in Image Editor, then compute too the histogram for this selection.
+ if (d->selectionArea.isValid())
+ {
+ d->imageSelection = d->image.copy(d->selectionArea);
+ d->histogramWidget->updateData(d->image.bits(), d->image.width(), d->image.height(),
+ d->image.sixteenBit(), d->imageSelection.bits(),
+ d->imageSelection.width(), d->imageSelection.height());
+ d->regionBG->show();
+ updateInformations();
+ }
+ else
+ {
+ d->histogramWidget->updateData(d->image.bits(), d->image.width(),
+ d->image.height(), d->image.sixteenBit());
+ d->regionBG->hide();
+ updateInformations();
+ }
+ }
+ else
+ {
+ d->histogramWidget->setLoadingFailed();
+ d->iccProfileWidget->setLoadingFailed();
+ slotHistogramComputationFailed();
+ }
+ }
+}
+
+void ImagePropertiesColorsTab::loadImageFromUrl(const KURL& url)
+{
+ // create thread on demand
+ if (!d->imageLoaderThread)
+ {
+ d->imageLoaderThread = new SharedLoadSaveThread();
+
+ connect(d->imageLoaderThread, SIGNAL(signalImageLoaded(const LoadingDescription &, const DImg&)),
+ this, SLOT(slotLoadImageFromUrlComplete(const LoadingDescription &, const DImg&)));
+
+ connect(d->imageLoaderThread, SIGNAL(signalMoreCompleteLoadingAvailable(const LoadingDescription &, const LoadingDescription &)),
+ this, SLOT(slotMoreCompleteLoadingAvailable(const LoadingDescription &, const LoadingDescription &)));
+ }
+
+ LoadingDescription desc = LoadingDescription(url.path());
+
+ if (DImg::fileFormat(desc.filePath) == DImg::RAW)
+ {
+ // use raw settings optimized for speed
+
+ DRawDecoding rawDecodingSettings = DRawDecoding();
+ rawDecodingSettings.optimizeTimeLoading();
+ desc = LoadingDescription(desc.filePath, rawDecodingSettings);
+ }
+
+ if (d->currentLoadingDescription.equalsOrBetterThan(desc))
+ return;
+
+ d->currentFilePath = desc.filePath;
+ d->currentLoadingDescription = desc;
+ d->inLoadingProcess = true;
+
+ d->imageLoaderThread->load(d->currentLoadingDescription,
+ SharedLoadSaveThread::AccessModeRead,
+ SharedLoadSaveThread::LoadingPolicyFirstRemovePrevious);
+
+ d->histogramWidget->setDataLoading();
+ d->iccProfileWidget->setDataLoading();
+}
+
+void ImagePropertiesColorsTab::slotLoadImageFromUrlComplete(const LoadingDescription &loadingDescription, const DImg& img)
+{
+ // Discard any leftover messages from previous, possibly aborted loads
+ if ( !loadingDescription.equalsOrBetterThan(d->currentLoadingDescription) )
+ return;
+
+ if ( !img.isNull() )
+ {
+ d->histogramWidget->updateData(img.bits(), img.width(), img.height(), img.sixteenBit());
+
+ // As a safety precaution, this must be changed only after updateData is called,
+ // which stops computation because d->image.bits() is currently used by threaded histogram algorithm.
+ d->image = img;
+ d->regionBG->hide();
+ updateInformations();
+ getICCData();
+ }
+ else
+ {
+ d->histogramWidget->setLoadingFailed();
+ d->iccProfileWidget->setLoadingFailed();
+ slotHistogramComputationFailed();
+ }
+ d->inLoadingProcess = false;
+}
+
+void ImagePropertiesColorsTab::slotMoreCompleteLoadingAvailable(const LoadingDescription &oldLoadingDescription,
+ const LoadingDescription &newLoadingDescription)
+{
+ if (oldLoadingDescription == d->currentLoadingDescription &&
+ newLoadingDescription.equalsOrBetterThan(d->currentLoadingDescription))
+ {
+ // Yes, we do want to stop our old time-optimized loading and chain to the current, more complete loading.
+ // Even the time-optimized raw loading takes significant time, and we must avoid two dcraw instances running
+ // at a time.
+ d->currentLoadingDescription = newLoadingDescription;
+ d->inLoadingProcess = true;
+ d->imageLoaderThread->load(newLoadingDescription,
+ SharedLoadSaveThread::AccessModeRead,
+ SharedLoadSaveThread::LoadingPolicyFirstRemovePrevious);
+ }
+}
+
+void ImagePropertiesColorsTab::setSelection(const QRect &selectionArea)
+{
+ // This is necessary to stop computation because d->image.bits() is currently used by
+ // threaded histogram algorithm.
+
+ d->histogramWidget->stopHistogramComputation();
+ d->selectionArea = selectionArea;
+
+ if (d->selectionArea.isValid())
+ {
+ d->imageSelection = d->image.copy(d->selectionArea);
+ d->histogramWidget->updateSelectionData(d->imageSelection.bits(), d->imageSelection.width(),
+ d->imageSelection.height(), d->imageSelection.sixteenBit());
+ d->regionBG->show();
+ }
+ else
+ {
+ d->regionBG->hide();
+ slotRenderingChanged(HistogramWidget::FullImageHistogram);
+ }
+}
+
+void ImagePropertiesColorsTab::slotRefreshOptions(bool /*sixteenBit*/)
+{
+ slotChannelChanged(d->channelCB->currentItem());
+ slotScaleChanged(d->scaleBG->selectedId());
+ slotColorsChanged(d->colorsCB->currentItem());
+
+ if (d->selectionArea.isValid())
+ slotRenderingChanged(d->regionBG->selectedId());
+}
+
+void ImagePropertiesColorsTab::slotHistogramComputationFailed()
+{
+ d->imageSelection.reset();
+ d->image.reset();
+}
+
+void ImagePropertiesColorsTab::slotChannelChanged(int channel)
+{
+ switch(channel)
+ {
+ case RedChannel:
+ d->histogramWidget->m_channelType = HistogramWidget::RedChannelHistogram;
+ d->hGradient->setColors( QColor( "black" ), QColor( "red" ) );
+ d->colorsCB->setEnabled(false);
+ break;
+
+ case GreenChannel:
+ d->histogramWidget->m_channelType = HistogramWidget::GreenChannelHistogram;
+ d->hGradient->setColors( QColor( "black" ), QColor( "green" ) );
+ d->colorsCB->setEnabled(false);
+ break;
+
+ case BlueChannel:
+ d->histogramWidget->m_channelType = HistogramWidget::BlueChannelHistogram;
+ d->hGradient->setColors( QColor( "black" ), QColor( "blue" ) );
+ d->colorsCB->setEnabled(false);
+ break;
+
+ case AlphaChannel:
+ d->histogramWidget->m_channelType = HistogramWidget::AlphaChannelHistogram;
+ d->hGradient->setColors( QColor( "black" ), QColor( "white" ) );
+ d->colorsCB->setEnabled(false);
+ break;
+
+ case ColorChannels:
+ d->histogramWidget->m_channelType = HistogramWidget::ColorChannelsHistogram;
+ d->hGradient->setColors( QColor( "black" ), QColor( "white" ) );
+ d->colorsCB->setEnabled(true);
+ break;
+
+ default: // Luminosity.
+ d->histogramWidget->m_channelType = HistogramWidget::ValueHistogram;
+ d->hGradient->setColors( QColor( "black" ), QColor( "white" ) );
+ d->colorsCB->setEnabled(false);
+ break;
+ }
+
+ d->histogramWidget->repaint(false);
+ updateStatistiques();
+}
+
+void ImagePropertiesColorsTab::slotScaleChanged(int scale)
+{
+ d->histogramWidget->m_scaleType = scale;
+ d->histogramWidget->repaint(false);
+}
+
+void ImagePropertiesColorsTab::slotColorsChanged(int color)
+{
+ switch(color)
+ {
+ case AllColorsGreen:
+ d->histogramWidget->m_colorType = HistogramWidget::GreenColor;
+ break;
+
+ case AllColorsBlue:
+ d->histogramWidget->m_colorType = HistogramWidget::BlueColor;
+ break;
+
+ default: // Red.
+ d->histogramWidget->m_colorType = HistogramWidget::RedColor;
+ break;
+ }
+
+ d->histogramWidget->repaint(false);
+ updateStatistiques();
+}
+
+void ImagePropertiesColorsTab::slotRenderingChanged(int rendering)
+{
+ d->histogramWidget->m_renderingType = rendering;
+ d->histogramWidget->repaint(false);
+ updateStatistiques();
+}
+
+void ImagePropertiesColorsTab::slotMinValueChanged(int min)
+{
+ // Called when user changes values of spin box.
+ // Communicate the change to histogram widget.
+
+ // make the one control "push" the other
+ if (min == d->maxInterv->value()+1)
+ d->maxInterv->setValue(min);
+ d->maxInterv->setMinValue(min-1);
+ d->histogramWidget->slotMinValueChanged(min);
+ updateStatistiques();
+}
+
+void ImagePropertiesColorsTab::slotMaxValueChanged(int max)
+{
+ if (max == d->minInterv->value()-1)
+ d->minInterv->setValue(max);
+ d->minInterv->setMaxValue(max+1);
+ d->histogramWidget->slotMaxValueChanged(max);
+ updateStatistiques();
+}
+
+void ImagePropertiesColorsTab::slotUpdateInterval(int min, int max)
+{
+ // Called when value is set from within histogram widget.
+ // Block signals to prevent slotMinValueChanged and
+ // slotMaxValueChanged being called.
+ d->minInterv->blockSignals(true);
+ d->minInterv->setMaxValue(max+1);
+ d->minInterv->setValue(min);
+ d->minInterv->blockSignals(false);
+
+ d->maxInterv->blockSignals(true);
+ d->maxInterv->setMinValue(min-1);
+ d->maxInterv->setValue(max);
+ d->maxInterv->blockSignals(false);
+
+ updateStatistiques();
+}
+
+void ImagePropertiesColorsTab::slotUpdateIntervRange(int range)
+{
+ d->maxInterv->setMaxValue( range );
+}
+
+void ImagePropertiesColorsTab::updateInformations()
+{
+ d->labelColorDepth->setText(d->image.sixteenBit() ? i18n("16 bits") : i18n("8 bits"));
+ d->labelAlphaChannel->setText(d->image.hasAlpha() ? i18n("Yes") : i18n("No"));
+}
+
+void ImagePropertiesColorsTab::updateStatistiques()
+{
+ QString value;
+ int min = d->minInterv->value();
+ int max = d->maxInterv->value();
+ int channel = d->channelCB->currentItem();
+
+ if ( channel == HistogramWidget::ColorChannelsHistogram )
+ channel = d->colorsCB->currentItem()+1;
+
+ double mean = d->histogramWidget->m_imageHistogram->getMean(channel, min, max);
+ d->labelMeanValue->setText(value.setNum(mean, 'f', 1));
+
+ double pixels = d->histogramWidget->m_imageHistogram->getPixels();
+ d->labelPixelsValue->setText(value.setNum((float)pixels, 'f', 0));
+
+ double stddev = d->histogramWidget->m_imageHistogram->getStdDev(channel, min, max);
+ d->labelStdDevValue->setText(value.setNum(stddev, 'f', 1));
+
+ double counts = d->histogramWidget->m_imageHistogram->getCount(channel, min, max);
+ d->labelCountValue->setText(value.setNum((float)counts, 'f', 0));
+
+ double median = d->histogramWidget->m_imageHistogram->getMedian(channel, min, max);
+ d->labelMedianValue->setText(value.setNum(median, 'f', 1));
+
+ double percentile = (pixels > 0 ? (100.0 * counts / pixels) : 0.0);
+ d->labelPercentileValue->setText(value.setNum(percentile, 'f', 1));
+}
+
+void ImagePropertiesColorsTab::getICCData()
+{
+ if (d->image.getICCProfil().isNull())
+ {
+ d->iccProfileWidget->setLoadingFailed();
+ }
+ else
+ {
+ d->embedded_profile = d->image.getICCProfil();
+ d->iccProfileWidget->loadFromData(d->currentFilePath, d->embedded_profile);
+ }
+}
+
+} // NameSpace Digikam
+
diff --git a/digikam/libs/imageproperties/imagepropertiescolorstab.h b/digikam/libs/imageproperties/imagepropertiescolorstab.h
new file mode 100644
index 0000000..314c925
--- /dev/null
+++ b/digikam/libs/imageproperties/imagepropertiescolorstab.h
@@ -0,0 +1,113 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-11-17
+ * Description : a tab to display colors information of images
+ *
+ * Copyright (C) 2004-2008 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 IMAGEPROPERTIESCOLORSTAB_H
+#define IMAGEPROPERTIESCOLORSTAB_H
+
+// Qt includes.
+
+#include <qwidget.h>
+#include <qcstring.h>
+
+// KDE includes.
+
+#include <kurl.h>
+
+// Local includes.
+
+#include "dimg.h"
+#include "digikam_export.h"
+#include "navigatebartab.h"
+
+class QRect;
+
+namespace Digikam
+{
+
+class DImg;
+class LoadingDescription;
+class ImagePropertiesColorsTabPriv;
+
+class DIGIKAM_EXPORT ImagePropertiesColorsTab : public NavigateBarTab
+{
+ Q_OBJECT
+
+public:
+
+ ImagePropertiesColorsTab(QWidget* parent, bool navBar=true);
+ ~ImagePropertiesColorsTab();
+
+ void setData(const KURL& url=KURL(), const QRect &selectionArea = QRect(),
+ DImg *img=0);
+
+ void setSelection(const QRect &selectionArea);
+
+private:
+
+ void loadImageFromUrl(const KURL& url);
+ void updateInformations();
+ void updateStatistiques();
+ void getICCData();
+
+private slots:
+
+ void slotRefreshOptions(bool sixteenBit);
+ void slotHistogramComputationFailed(void);
+ void slotChannelChanged(int channel);
+ void slotScaleChanged(int scale);
+ void slotColorsChanged(int color);
+ void slotRenderingChanged(int rendering);
+ void slotMinValueChanged(int);
+ void slotMaxValueChanged(int);
+
+ void slotUpdateInterval(int min, int max);
+ void slotUpdateIntervRange(int range);
+
+ void slotLoadImageFromUrlComplete(const LoadingDescription &loadingDescription, const DImg& img);
+ void slotMoreCompleteLoadingAvailable(const LoadingDescription &oldLoadingDescription,
+ const LoadingDescription &newLoadingDescription);
+
+private:
+
+ enum ColorChannel
+ {
+ LuminosityChannel=0,
+ RedChannel,
+ GreenChannel,
+ BlueChannel,
+ AlphaChannel,
+ ColorChannels
+ };
+
+ enum AllColorsColorType
+ {
+ AllColorsRed=0,
+ AllColorsGreen,
+ AllColorsBlue
+ };
+
+ ImagePropertiesColorsTabPriv* d;
+};
+
+} // NameSpace Digikam
+
+#endif /* IMAGEPROPERTIESCOLORSTAB_H */
diff --git a/digikam/libs/imageproperties/imagepropertiesmetadatatab.cpp b/digikam/libs/imageproperties/imagepropertiesmetadatatab.cpp
new file mode 100644
index 0000000..f7fe828
--- /dev/null
+++ b/digikam/libs/imageproperties/imagepropertiesmetadatatab.cpp
@@ -0,0 +1,201 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-11-17
+ * Description : a tab to display metadata information of images
+ *
+ * Copyright (C) 2004-2007 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ *
+ * This program is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation;
+ * either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * ============================================================ */
+
+// Qt includes.
+
+#include <qlayout.h>
+#include <qfile.h>
+#include <qlabel.h>
+#include <qpixmap.h>
+#include <qfileinfo.h>
+#include <qwhatsthis.h>
+
+// KDE includes.
+
+#include <klocale.h>
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kdialogbase.h>
+#include <kfileitem.h>
+#include <ktabwidget.h>
+
+// Local includes.
+
+#include "ddebug.h"
+#include "dmetadata.h"
+#include "exifwidget.h"
+#include "makernotewidget.h"
+#include "iptcwidget.h"
+#include "gpswidget.h"
+#include "navigatebarwidget.h"
+#include "imagepropertiesmetadatatab.h"
+#include "imagepropertiesmetadatatab.moc"
+
+namespace Digikam
+{
+
+class ImagePropertiesMetadataTabPriv
+{
+public:
+
+ enum MetadataTab
+ {
+ EXIF=0,
+ MAKERNOTE,
+ IPTC,
+ GPS
+ };
+
+ ImagePropertiesMetadataTabPriv()
+ {
+ exifWidget = 0;
+ makernoteWidget = 0;
+ iptcWidget = 0;
+ gpsWidget = 0;
+ tab = 0;
+ }
+
+ KTabWidget *tab;
+
+ ExifWidget *exifWidget;
+
+ MakerNoteWidget *makernoteWidget;
+
+ IptcWidget *iptcWidget;
+
+ GPSWidget *gpsWidget;
+};
+
+ImagePropertiesMetaDataTab::ImagePropertiesMetaDataTab(QWidget* parent, bool navBar)
+ : NavigateBarTab(parent)
+{
+ d = new ImagePropertiesMetadataTabPriv;
+
+ setupNavigateBar(navBar);
+ d->tab = new KTabWidget(this);
+ m_navigateBarLayout->addWidget(d->tab);
+
+ // Exif tab area -----------------------------------------------------
+
+ d->exifWidget = new ExifWidget(d->tab);
+ d->tab->insertTab(d->exifWidget, i18n("EXIF"), ImagePropertiesMetadataTabPriv::EXIF);
+
+ // Makernote tab area -----------------------------------------------------
+
+ d->makernoteWidget = new MakerNoteWidget(d->tab);
+ d->tab->insertTab(d->makernoteWidget, i18n("Makernote"), ImagePropertiesMetadataTabPriv::MAKERNOTE);
+
+ // IPTC tab area ---------------------------------------
+
+ d->iptcWidget = new IptcWidget(d->tab);
+ d->tab->insertTab(d->iptcWidget, i18n("IPTC"), ImagePropertiesMetadataTabPriv::IPTC);
+
+ // GPS tab area ---------------------------------------
+
+ d->gpsWidget = new GPSWidget(d->tab);
+ d->tab->insertTab(d->gpsWidget, i18n("GPS"), ImagePropertiesMetadataTabPriv::GPS);
+
+ // -- read config ---------------------------------------------------------
+
+ KConfig* config = kapp->config();
+ config->setGroup("Image Properties SideBar");
+ d->tab->setCurrentPage(config->readNumEntry("ImagePropertiesMetaData Tab",
+ ImagePropertiesMetadataTabPriv::EXIF));
+ d->exifWidget->setMode(config->readNumEntry("EXIF Level", ExifWidget::SIMPLE));
+ d->makernoteWidget->setMode(config->readNumEntry("MAKERNOTE Level", MakerNoteWidget::SIMPLE));
+ d->iptcWidget->setMode(config->readNumEntry("IPTC Level", IptcWidget::SIMPLE));
+ d->gpsWidget->setMode(config->readNumEntry("GPS Level", GPSWidget::SIMPLE));
+ d->exifWidget->setCurrentItemByKey(config->readEntry("Current EXIF Item", QString()));
+ d->makernoteWidget->setCurrentItemByKey(config->readEntry("Current MAKERNOTE Item", QString()));
+ d->iptcWidget->setCurrentItemByKey(config->readEntry("Current IPTC Item", QString()));
+ d->gpsWidget->setCurrentItemByKey(config->readEntry("Current GPS Item", QString()));
+ d->gpsWidget->setWebGPSLocator(config->readNumEntry("Current Web GPS Locator", GPSWidget::MapQuest));
+}
+
+ImagePropertiesMetaDataTab::~ImagePropertiesMetaDataTab()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("Image Properties SideBar");
+ config->writeEntry("ImagePropertiesMetaData Tab", d->tab->currentPageIndex());
+ config->writeEntry("EXIF Level", d->exifWidget->getMode());
+ config->writeEntry("MAKERNOTE Level", d->makernoteWidget->getMode());
+ config->writeEntry("IPTC Level", d->iptcWidget->getMode());
+ config->writeEntry("GPS Level", d->gpsWidget->getMode());
+ config->writeEntry("Current EXIF Item", d->exifWidget->getCurrentItemKey());
+ config->writeEntry("Current MAKERNOTE Item", d->makernoteWidget->getCurrentItemKey());
+ config->writeEntry("Current IPTC Item", d->iptcWidget->getCurrentItemKey());
+ config->writeEntry("Current GPS Item", d->gpsWidget->getCurrentItemKey());
+ config->writeEntry("Current Web GPS Locator", d->gpsWidget->getWebGPSLocator());
+ config->sync();
+
+ delete d;
+}
+
+void ImagePropertiesMetaDataTab::setCurrentURL(const KURL& url)
+{
+ if (url.isEmpty())
+ {
+ d->exifWidget->loadFromURL(url);
+ d->makernoteWidget->loadFromURL(url);
+ d->iptcWidget->loadFromURL(url);
+ d->gpsWidget->loadFromURL(url);
+ setEnabled(false);
+ return;
+ }
+
+ setEnabled(true);
+ DMetadata metadata(url.path());
+
+ QByteArray exifData = metadata.getExif();
+ QByteArray iptcData = metadata.getIptc();
+
+ d->exifWidget->loadFromData(url.filename(), exifData);
+ d->makernoteWidget->loadFromData(url.filename(), exifData);
+ d->iptcWidget->loadFromData(url.filename(), iptcData);
+ d->gpsWidget->loadFromData(url.filename(), exifData);
+}
+
+void ImagePropertiesMetaDataTab::setCurrentData(const QByteArray& exifData,
+ const QByteArray& iptcData,
+ const QString& filename)
+{
+ if (exifData.isEmpty() && iptcData.isEmpty())
+ {
+ d->exifWidget->loadFromData(filename, exifData);
+ d->makernoteWidget->loadFromData(filename, exifData);
+ d->iptcWidget->loadFromData(filename, iptcData);
+ d->gpsWidget->loadFromData(filename, exifData);
+ setEnabled(false);
+ return;
+ }
+
+ setEnabled(true);
+
+ d->exifWidget->loadFromData(filename, exifData);
+ d->makernoteWidget->loadFromData(filename, exifData);
+ d->iptcWidget->loadFromData(filename, iptcData);
+ d->gpsWidget->loadFromData(filename, exifData);
+}
+
+} // NameSpace Digikam
+
diff --git a/digikam/libs/imageproperties/imagepropertiesmetadatatab.h b/digikam/libs/imageproperties/imagepropertiesmetadatatab.h
new file mode 100644
index 0000000..709e9c0
--- /dev/null
+++ b/digikam/libs/imageproperties/imagepropertiesmetadatatab.h
@@ -0,0 +1,67 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-11-17
+ * Description : a tab to display metadata information of images
+ *
+ * Copyright (C) 2004-2007 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ *
+ * This program is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation;
+ * either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * ============================================================ */
+
+#ifndef IMAGEPROPERTIESMETADATATAB_H
+#define IMAGEPROPERTIESMETADATATAB_H
+
+// Qt includes.
+
+#include <qwidget.h>
+#include <qcstring.h>
+
+// KDE includes.
+
+#include <kurl.h>
+
+// Local includes.
+
+#include "digikam_export.h"
+#include "navigatebartab.h"
+
+namespace Digikam
+{
+
+class ImagePropertiesMetadataTabPriv;
+
+class DIGIKAM_EXPORT ImagePropertiesMetaDataTab : public NavigateBarTab
+{
+ Q_OBJECT
+
+public:
+
+ ImagePropertiesMetaDataTab(QWidget* parent, bool navBar=true);
+ ~ImagePropertiesMetaDataTab();
+
+ void setCurrentURL(const KURL& url=KURL());
+ void setCurrentData(const QByteArray& exifData=QByteArray(),
+ const QByteArray& iptcData=QByteArray(),
+ const QString& filename=QString());
+
+private:
+
+ ImagePropertiesMetadataTabPriv* d;
+};
+
+} // NameSpace Digikam
+
+#endif /* IMAGEPROPERTIESMETADATATAB_H */
diff --git a/digikam/libs/imageproperties/imagepropertiessidebar.cpp b/digikam/libs/imageproperties/imagepropertiessidebar.cpp
new file mode 100644
index 0000000..e42df5c
--- /dev/null
+++ b/digikam/libs/imageproperties/imagepropertiessidebar.cpp
@@ -0,0 +1,150 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-11-17
+ * Description : simple image properties side bar (without support
+ * of digiKam database).
+ *
+ * Copyright (C) 2004-2008 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.
+ *
+ * ============================================================ */
+
+// Qt includes.
+
+#include <qrect.h>
+#include <qsplitter.h>
+
+// KDE includes.
+
+#include <klocale.h>
+#include <kconfig.h>
+#include <kapplication.h>
+#include <kcursor.h>
+#include <kglobal.h>
+#include <kiconloader.h>
+
+// Local includes.
+
+#include "ddebug.h"
+#include "dimg.h"
+#include "imagepropertiestab.h"
+#include "imagepropertiesmetadatatab.h"
+#include "imagepropertiescolorstab.h"
+#include "imagepropertiessidebar.h"
+#include "imagepropertiessidebar.moc"
+
+namespace Digikam
+{
+
+ImagePropertiesSideBar::ImagePropertiesSideBar(QWidget *parent, const char *name,
+ QSplitter *splitter, Side side,
+ bool mimimizedDefault, bool navBar)
+ : Sidebar(parent, name, side, mimimizedDefault)
+{
+ m_image = 0;
+ m_currentRect = QRect();
+ m_dirtyPropertiesTab = false;
+ m_dirtyMetadataTab = false;
+ m_dirtyColorTab = false;
+
+ m_propertiesTab = new ImagePropertiesTab(parent, navBar);
+ m_metadataTab = new ImagePropertiesMetaDataTab(parent, navBar);
+ m_colorTab = new ImagePropertiesColorsTab(parent, navBar);
+
+ setSplitter(splitter);
+
+ appendTab(m_propertiesTab, SmallIcon("info"), i18n("Properties"));
+ appendTab(m_metadataTab, SmallIcon("exifinfo"), i18n("Metadata"));
+ appendTab(m_colorTab, SmallIcon("blend"), i18n("Colors"));
+
+ connect(this, SIGNAL(signalChangedTab(QWidget*)),
+ this, SLOT(slotChangedTab(QWidget*)));
+}
+
+ImagePropertiesSideBar::~ImagePropertiesSideBar()
+{
+}
+
+void ImagePropertiesSideBar::itemChanged(const KURL& url, const QRect &rect, DImg *img)
+{
+ if (!url.isValid())
+ return;
+
+ m_currentURL = url;
+ m_currentRect = rect;
+ m_image = img;
+ m_dirtyPropertiesTab = false;
+ m_dirtyMetadataTab = false;
+ m_dirtyColorTab = false;
+
+ slotChangedTab( getActiveTab() );
+}
+
+void ImagePropertiesSideBar::slotNoCurrentItem(void)
+{
+ m_currentURL = KURL();
+
+ m_propertiesTab->setCurrentURL();
+ m_propertiesTab->setNavigateBarFileName();
+
+ m_metadataTab->setCurrentURL();
+ m_metadataTab->setNavigateBarFileName();
+
+ m_colorTab->setData();
+ m_colorTab->setNavigateBarFileName();
+
+ m_dirtyPropertiesTab = false;
+ m_dirtyMetadataTab = false;
+ m_dirtyColorTab = false;
+}
+
+void ImagePropertiesSideBar::slotImageSelectionChanged(const QRect &rect)
+{
+ m_currentRect = rect;
+
+ if (m_dirtyColorTab)
+ m_colorTab->setSelection(rect);
+ else
+ slotChangedTab(m_colorTab);
+}
+
+void ImagePropertiesSideBar::slotChangedTab(QWidget* tab)
+{
+ if (!m_currentURL.isValid())
+ return;
+
+ setCursor(KCursor::waitCursor());
+
+ if (tab == m_propertiesTab && !m_dirtyPropertiesTab)
+ {
+ m_propertiesTab->setCurrentURL(m_currentURL);
+ m_dirtyPropertiesTab = true;
+ }
+ else if (tab == m_metadataTab && !m_dirtyMetadataTab)
+ {
+ m_metadataTab->setCurrentURL(m_currentURL);
+ m_dirtyMetadataTab = true;
+ }
+ else if (tab == m_colorTab && !m_dirtyColorTab)
+ {
+ m_colorTab->setData(m_currentURL, m_currentRect, m_image);
+ m_dirtyColorTab = true;
+ }
+
+ unsetCursor();
+}
+
+} // NameSpace Digikam
diff --git a/digikam/libs/imageproperties/imagepropertiessidebar.h b/digikam/libs/imageproperties/imagepropertiessidebar.h
new file mode 100644
index 0000000..02643c5
--- /dev/null
+++ b/digikam/libs/imageproperties/imagepropertiessidebar.h
@@ -0,0 +1,92 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-11-17
+ * Description : simple image properties side bar (without support
+ * of digiKam database).
+ *
+ * Copyright (C) 2004-2008 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 IMAGEPROPERTIESSIDEBAR_H
+#define IMAGEPROPERTIESSIDEBAR_H
+
+// KDE includes.
+
+#include <kurl.h>
+
+// Local includes.
+
+#include "sidebar.h"
+#include "digikam_export.h"
+
+class QSplitter;
+class QWidget;
+class QRect;
+
+namespace Digikam
+{
+
+class DImg;
+class ImagePropertiesTab;
+class ImagePropertiesMetaDataTab;
+class ImagePropertiesColorsTab;
+
+class DIGIKAM_EXPORT ImagePropertiesSideBar : public Sidebar
+{
+ Q_OBJECT
+
+public:
+
+ ImagePropertiesSideBar(QWidget* parent, const char *name, QSplitter *splitter,
+ Side side=Left, bool mimimizedDefault=false, bool navBar=false);
+
+ ~ImagePropertiesSideBar();
+
+ virtual void itemChanged(const KURL& url, const QRect &rect = QRect(), DImg *img = 0);
+
+public slots:
+
+ void slotImageSelectionChanged(const QRect &rect);
+ virtual void slotNoCurrentItem(void);
+
+
+protected slots:
+
+ virtual void slotChangedTab(QWidget* tab);
+
+protected:
+
+ bool m_dirtyPropertiesTab;
+ bool m_dirtyMetadataTab;
+ bool m_dirtyColorTab;
+
+ QRect m_currentRect;
+
+ KURL m_currentURL;
+
+ DImg *m_image;
+
+ ImagePropertiesTab *m_propertiesTab;
+ ImagePropertiesMetaDataTab *m_metadataTab;
+ ImagePropertiesColorsTab *m_colorTab;
+
+};
+
+} // NameSpace Digikam
+
+#endif // IMAGEPROPERTIESSIDEBAR_H
diff --git a/digikam/libs/imageproperties/imagepropertiessidebarcamgui.cpp b/digikam/libs/imageproperties/imagepropertiessidebarcamgui.cpp
new file mode 100644
index 0000000..e388f1d
--- /dev/null
+++ b/digikam/libs/imageproperties/imagepropertiessidebarcamgui.cpp
@@ -0,0 +1,209 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2006-02-08
+ * Description : simple image properties side bar used by
+ * camera gui.
+ *
+ * Copyright (C) 2006-2008 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.
+ *
+ * ============================================================ */
+
+// Qt includes.
+
+#include <qsplitter.h>
+
+// KDE includes.
+
+#include <klocale.h>
+#include <kconfig.h>
+#include <kapplication.h>
+#include <kcursor.h>
+#include <kglobal.h>
+#include <kiconloader.h>
+
+// Local includes.
+
+#include "ddebug.h"
+#include "dmetadata.h"
+#include "gpiteminfo.h"
+#include "cameraiconview.h"
+#include "cameraiconitem.h"
+#include "cameraitempropertiestab.h"
+#include "imagepropertiesmetadatatab.h"
+#include "statusnavigatebar.h"
+#include "navigatebarwidget.h"
+#include "imagepropertiessidebarcamgui.h"
+#include "imagepropertiessidebarcamgui.moc"
+
+namespace Digikam
+{
+
+class ImagePropertiesSideBarCamGuiPriv
+{
+public:
+
+ ImagePropertiesSideBarCamGuiPriv()
+ {
+ dirtyMetadataTab = false;
+ dirtyCameraItemTab = false;
+ metadataTab = 0;
+ cameraItemTab = 0;
+ itemInfo = 0;
+ cameraView = 0;
+ cameraItem = 0;
+ exifData = QByteArray();
+ currentURL = KURL();
+ }
+
+ bool dirtyMetadataTab;
+ bool dirtyCameraItemTab;
+
+ QByteArray exifData;
+
+ KURL currentURL;
+
+ GPItemInfo *itemInfo;
+
+ ImagePropertiesMetaDataTab *metadataTab;
+
+ CameraIconView *cameraView;
+
+ CameraIconViewItem *cameraItem;
+
+ CameraItemPropertiesTab *cameraItemTab;
+};
+
+ImagePropertiesSideBarCamGui::ImagePropertiesSideBarCamGui(QWidget *parent, const char *name,
+ QSplitter *splitter, Side side,
+ bool mimimizedDefault)
+ : Sidebar(parent, name, side, mimimizedDefault)
+{
+ d = new ImagePropertiesSideBarCamGuiPriv;
+ d->cameraItemTab = new CameraItemPropertiesTab(parent, true);
+ d->metadataTab = new ImagePropertiesMetaDataTab(parent, true);
+
+ setSplitter(splitter);
+
+ appendTab(d->cameraItemTab, SmallIcon("info"), i18n("Properties"));
+ appendTab(d->metadataTab, SmallIcon("exifinfo"), i18n("Metadata"));
+
+ // ----------------------------------------------------------
+
+ connectNavigateSignals(d->cameraItemTab);
+ connectNavigateSignals(d->metadataTab);
+
+ connect(this, SIGNAL(signalChangedTab(QWidget*)),
+ this, SLOT(slotChangedTab(QWidget*)));
+}
+
+ImagePropertiesSideBarCamGui::~ImagePropertiesSideBarCamGui()
+{
+ delete d;
+}
+
+void ImagePropertiesSideBarCamGui::connectNavigateSignals(NavigateBarTab *tab)
+{
+ connect(tab, SIGNAL(signalFirstItem()),
+ this, SIGNAL(signalFirstItem()));
+
+ connect(tab, SIGNAL(signalPrevItem()),
+ this, SIGNAL(signalPrevItem()));
+
+ connect(tab, SIGNAL(signalNextItem()),
+ this, SIGNAL(signalNextItem()));
+
+ connect(tab, SIGNAL(signalLastItem()),
+ this, SIGNAL(signalLastItem()));
+}
+
+void ImagePropertiesSideBarCamGui::itemChanged(GPItemInfo* itemInfo, const KURL& url,
+ const QByteArray& exifData,
+ CameraIconView* view, CameraIconViewItem* item)
+{
+ if (!itemInfo)
+ return;
+
+ d->exifData = exifData;
+ d->itemInfo = itemInfo;
+ d->currentURL = url;
+ d->dirtyMetadataTab = false;
+ d->dirtyCameraItemTab = false;
+ d->cameraView = view;
+ d->cameraItem = item;
+
+ if (d->exifData.isEmpty())
+ {
+ DMetadata metaData(d->currentURL.path());
+ d->exifData = metaData.getExif();
+ }
+
+ slotChangedTab( getActiveTab() );
+}
+
+void ImagePropertiesSideBarCamGui::slotNoCurrentItem(void)
+{
+ d->itemInfo = 0;
+ d->cameraItem = 0;
+ d->exifData = QByteArray();
+ d->currentURL = KURL();
+ d->dirtyMetadataTab = false;
+ d->dirtyCameraItemTab = false;
+
+ d->cameraItemTab->setCurrentItem();
+ d->metadataTab->setCurrentURL();
+}
+
+void ImagePropertiesSideBarCamGui::slotChangedTab(QWidget* tab)
+{
+ if (!d->itemInfo)
+ return;
+
+ setCursor(KCursor::waitCursor());
+
+ if (tab == d->cameraItemTab && !d->dirtyCameraItemTab)
+ {
+ d->cameraItemTab->setCurrentItem(d->itemInfo,
+ d->cameraItem->getDownloadName(), d->exifData,
+ d->currentURL);
+
+ d->dirtyCameraItemTab = true;
+ }
+ else if (tab == d->metadataTab && !d->dirtyMetadataTab)
+ {
+ d->metadataTab->setCurrentData(d->exifData, QByteArray(),
+ d->itemInfo->name);
+
+ d->dirtyMetadataTab = true;
+ }
+
+ // setting of NavigateBar, common for all tabs
+ NavigateBarTab *navtab = dynamic_cast<NavigateBarTab *>(tab);
+ if (navtab)
+ {
+ int currentItemType = StatusNavigateBar::ItemCurrent;
+ if (d->cameraView->firstItem() == d->cameraItem)
+ currentItemType = StatusNavigateBar::ItemFirst;
+ else if (d->cameraView->lastItem() == d->cameraItem)
+ currentItemType = StatusNavigateBar::ItemLast;
+
+ navtab->setNavigateBarState(currentItemType);
+ navtab->setNavigateBarFileName();
+ }
+ unsetCursor();
+}
+
+} // NameSpace Digikam
diff --git a/digikam/libs/imageproperties/imagepropertiessidebarcamgui.h b/digikam/libs/imageproperties/imagepropertiessidebarcamgui.h
new file mode 100644
index 0000000..f9042b9
--- /dev/null
+++ b/digikam/libs/imageproperties/imagepropertiessidebarcamgui.h
@@ -0,0 +1,86 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2006-02-08
+ * Description : simple image properties side bar used by
+ * camera gui.
+ *
+ * Copyright (C) 2006-2008 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 IMAGEPROPERTIESSIDEBARCAMGUI_H
+#define IMAGEPROPERTIESSIDEBARCAMGUI_H
+
+// KDE includes.
+
+#include <kurl.h>
+
+// Local includes.
+
+#include "sidebar.h"
+#include "digikam_export.h"
+
+class QSplitter;
+class QWidget;
+
+namespace Digikam
+{
+
+class GPItemInfo;
+class CameraIconView;
+class CameraIconViewItem;
+class NavigateBarTab;
+class ImagePropertiesSideBarCamGuiPriv;
+
+class DIGIKAM_EXPORT ImagePropertiesSideBarCamGui : public Sidebar
+{
+ Q_OBJECT
+
+public:
+
+ ImagePropertiesSideBarCamGui(QWidget* parent, const char *name, QSplitter *splitter,
+ Side side=Left, bool mimimizedDefault=false);
+
+ ~ImagePropertiesSideBarCamGui();
+
+ void itemChanged(GPItemInfo* itemInfo, const KURL& url, const QByteArray& exifData=QByteArray(),
+ CameraIconView* view=0, CameraIconViewItem* item=0);
+
+public slots:
+
+ virtual void slotNoCurrentItem(void);
+
+signals:
+
+ void signalFirstItem(void);
+ void signalPrevItem(void);
+ void signalNextItem(void);
+ void signalLastItem(void);
+
+private slots:
+
+ virtual void slotChangedTab(QWidget* tab);
+
+private:
+
+ ImagePropertiesSideBarCamGuiPriv* d;
+ void connectNavigateSignals(NavigateBarTab *tab);
+};
+
+} // NameSpace Digikam
+
+#endif // IMAGEPROPERTIESSIDEBARCAMGUI_H
diff --git a/digikam/libs/imageproperties/imagepropertiessidebardb.cpp b/digikam/libs/imageproperties/imagepropertiessidebardb.cpp
new file mode 100644
index 0000000..94d627e
--- /dev/null
+++ b/digikam/libs/imageproperties/imagepropertiessidebardb.cpp
@@ -0,0 +1,368 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-11-17
+ * Description : image properties side bar using data from
+ * digiKam database.
+ *
+ * Copyright (C) 2004-2008 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ * Copyright (C) 2007 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
+ *
+ * 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.
+ *
+ * ============================================================ */
+
+// Qt includes.
+
+#include <qrect.h>
+#include <qcolor.h>
+#include <qsplitter.h>
+
+// KDE includes.
+
+#include <klocale.h>
+#include <kconfig.h>
+#include <kapplication.h>
+#include <kcursor.h>
+#include <kglobal.h>
+#include <kiconloader.h>
+
+// Local includes.
+
+#include "ddebug.h"
+#include "dimg.h"
+#include "imageinfo.h"
+#include "imagedescedittab.h"
+#include "imageattributeswatch.h"
+#include "imagepropertiestab.h"
+#include "imagepropertiesmetadatatab.h"
+#include "imagepropertiescolorstab.h"
+#include "imagepropertiessidebardb.h"
+#include "imagepropertiessidebardb.moc"
+
+namespace Digikam
+{
+
+class ImagePropertiesSideBarDBPriv
+{
+public:
+
+ ImagePropertiesSideBarDBPriv()
+ {
+ desceditTab = 0;
+ dirtyDesceditTab = false;
+ hasPrevious = false;
+ hasNext = false;
+ hasImageInfoOwnership = false;
+ }
+
+ bool dirtyDesceditTab;
+
+ QPtrList<ImageInfo> currentInfos;
+
+ ImageDescEditTab *desceditTab;
+
+ bool hasPrevious;
+ bool hasNext;
+
+ bool hasImageInfoOwnership;
+};
+
+ImagePropertiesSideBarDB::ImagePropertiesSideBarDB(QWidget *parent, const char *name, QSplitter *splitter,
+ Side side, bool mimimizedDefault)
+ : ImagePropertiesSideBar(parent, name, splitter, side, mimimizedDefault, false)
+{
+ // Navigate bar is disabled by passing false to parent class constructor, and tab constructors
+
+ d = new ImagePropertiesSideBarDBPriv;
+ d->desceditTab = new ImageDescEditTab(parent, false);
+
+ appendTab(d->desceditTab, SmallIcon("imagecomment"), i18n("Captions/Tags"));
+
+ // ----------------------------------------------------------
+
+ connect(this, SIGNAL(signalChangedTab(QWidget*)),
+ this, SLOT(slotChangedTab(QWidget*)));
+
+ connect(d->desceditTab, SIGNAL(signalProgressBarMode(int, const QString&)),
+ this, SIGNAL(signalProgressBarMode(int, const QString&)));
+
+ connect(d->desceditTab, SIGNAL(signalProgressValue(int)),
+ this, SIGNAL(signalProgressValue(int)));
+
+ ImageAttributesWatch *watch = ImageAttributesWatch::instance();
+
+ connect(watch, SIGNAL(signalFileMetadataChanged(const KURL &)),
+ this, SLOT(slotFileMetadataChanged(const KURL &)));
+}
+
+ImagePropertiesSideBarDB::~ImagePropertiesSideBarDB()
+{
+ delete d;
+}
+
+void ImagePropertiesSideBarDB::itemChanged(ImageInfo *info,
+ const QRect &rect, DImg *img)
+{
+ itemChanged(info->kurl(), info, rect, img);
+}
+
+void ImagePropertiesSideBarDB::itemChanged(const KURL& url, const QRect &rect, DImg *img)
+{
+ itemChanged(url, 0, rect, img);
+}
+
+void ImagePropertiesSideBarDB::itemChanged(const KURL& url, ImageInfo *info,
+ const QRect &rect, DImg *img)
+{
+ if ( !url.isValid() )
+ return;
+
+ m_currentURL = url;
+
+ QPtrList<ImageInfo> list;
+ if (info)
+ list.append(info);
+
+ itemChanged(list, rect, img);
+}
+
+void ImagePropertiesSideBarDB::itemChanged(QPtrList<ImageInfo> infos)
+{
+ if (infos.isEmpty())
+ return;
+
+ m_currentURL = infos.first()->kurl();
+
+ itemChanged(infos, QRect(), 0);
+}
+
+void ImagePropertiesSideBarDB::itemChanged(QPtrList<ImageInfo> infos,
+ const QRect &rect, DImg *img)
+{
+ m_currentRect = rect;
+ m_image = img;
+
+ // The list _may_ have autoDelete set to true.
+ // Keep old ImageInfo objects from being deleted
+ // until the tab has had the chance to save changes and clear lists.
+ QPtrList<ImageInfo> temporaryList;
+ if (d->hasImageInfoOwnership)
+ {
+ temporaryList = d->currentInfos;
+ d->hasImageInfoOwnership = false;
+ }
+
+ d->currentInfos = infos;
+
+ m_dirtyPropertiesTab = false;
+ m_dirtyMetadataTab = false;
+ m_dirtyColorTab = false;
+ d->dirtyDesceditTab = false;
+
+ // All tabs that store the ImageInfo list and access it after selection change
+ // must release the image info here. slotChangedTab only handles the active tab!
+ d->desceditTab->setItem();
+
+ slotChangedTab( getActiveTab() );
+
+ // now delete old objects, after slotChangedTab
+ for (ImageInfo *info = temporaryList.first(); info; info = temporaryList.next())
+ {
+ delete info;
+ }
+}
+
+void ImagePropertiesSideBarDB::takeImageInfoOwnership(bool takeOwnership)
+{
+ d->hasImageInfoOwnership = takeOwnership;
+}
+
+
+void ImagePropertiesSideBarDB::slotNoCurrentItem(void)
+{
+ ImagePropertiesSideBar::slotNoCurrentItem();
+
+ // All tabs that store the ImageInfo list and access it after selection change
+ // must release the image info here. slotChangedTab only handles the active tab!
+ d->desceditTab->setItem();
+
+ if (d->hasImageInfoOwnership)
+ {
+ for (ImageInfo *info = d->currentInfos.first(); info; info = d->currentInfos.next())
+ {
+ delete info;
+ }
+ d->hasImageInfoOwnership = false;
+ }
+ d->currentInfos.clear();
+
+ d->desceditTab->setItem();
+ d->dirtyDesceditTab = false;
+}
+
+void ImagePropertiesSideBarDB::populateTags(void)
+{
+ d->desceditTab->populateTags();
+}
+
+void ImagePropertiesSideBarDB::slotChangedTab(QWidget* tab)
+{
+ setCursor(KCursor::waitCursor());
+
+ // No database data available, for example in the case of image editor is
+ // started from camera GUI.
+ if (d->currentInfos.isEmpty())
+ {
+ if (tab == m_propertiesTab && !m_dirtyPropertiesTab)
+ {
+ m_propertiesTab->setCurrentURL(m_currentURL);
+ m_dirtyPropertiesTab = true;
+ }
+ else if (tab == m_metadataTab && !m_dirtyMetadataTab)
+ {
+ if (m_image)
+ m_metadataTab->setCurrentData(m_image->getExif(), m_image->getIptc(),
+ m_currentURL.fileName());
+ else
+ m_metadataTab->setCurrentURL(m_currentURL);
+
+ m_dirtyMetadataTab = true;
+ }
+ else if (tab == m_colorTab && !m_dirtyColorTab)
+ {
+ m_colorTab->setData(m_currentURL, m_currentRect, m_image);
+ m_dirtyColorTab = true;
+ }
+ else if (tab == d->desceditTab && !d->dirtyDesceditTab)
+ {
+ // Do nothing here. We cannot get data from database !
+ d->desceditTab->setItem();
+ d->dirtyDesceditTab = true;
+ }
+ }
+ else if (d->currentInfos.count() == 1) // Data from database available...
+ {
+ if (tab == m_propertiesTab && !m_dirtyPropertiesTab)
+ {
+ m_propertiesTab->setCurrentURL(m_currentURL);
+ m_dirtyPropertiesTab = true;
+ }
+ else if (tab == m_metadataTab && !m_dirtyMetadataTab)
+ {
+ if (m_image)
+ m_metadataTab->setCurrentData(m_image->getExif(), m_image->getIptc(),
+ m_currentURL.fileName());
+ else
+ m_metadataTab->setCurrentURL(m_currentURL);
+
+ m_dirtyMetadataTab = true;
+ }
+ else if (tab == m_colorTab && !m_dirtyColorTab)
+ {
+ m_colorTab->setData(m_currentURL, m_currentRect, m_image);
+ m_dirtyColorTab = true;
+ }
+ else if (tab == d->desceditTab && !d->dirtyDesceditTab)
+ {
+ d->desceditTab->setItem(d->currentInfos.first());
+ d->dirtyDesceditTab = true;
+ }
+ }
+ else // Data from database available, multiple selection
+ {
+ if (tab == m_propertiesTab && !m_dirtyPropertiesTab)
+ {
+ //TODO
+ m_propertiesTab->setCurrentURL(m_currentURL);
+ m_dirtyPropertiesTab = true;
+ }
+ else if (tab == m_metadataTab && !m_dirtyMetadataTab)
+ {
+ // any ideas?
+ m_metadataTab->setCurrentURL();
+ m_dirtyMetadataTab = true;
+ }
+ else if (tab == m_colorTab && !m_dirtyColorTab)
+ {
+ // any ideas?
+ m_colorTab->setData();
+ m_dirtyColorTab = true;
+ }
+ else if (tab == d->desceditTab && !d->dirtyDesceditTab)
+ {
+ d->desceditTab->setItems(d->currentInfos);
+ d->dirtyDesceditTab = true;
+ }
+ }
+
+ unsetCursor();
+}
+
+void ImagePropertiesSideBarDB::slotFileMetadataChanged(const KURL &url)
+{
+ if (url == m_currentURL)
+ {
+ // trigger an update
+ m_dirtyMetadataTab = false;
+
+ if (getActiveTab() == m_metadataTab)
+ {
+ // update now - reuse code form slotChangedTab
+ slotChangedTab( getActiveTab() );
+ }
+ }
+}
+
+void ImagePropertiesSideBarDB::slotAssignRating(int rating)
+{
+ d->desceditTab->assignRating(rating);
+}
+
+void ImagePropertiesSideBarDB::slotAssignRatingNoStar()
+{
+ d->desceditTab->assignRating(0);
+}
+
+void ImagePropertiesSideBarDB::slotAssignRatingOneStar()
+{
+ d->desceditTab->assignRating(1);
+}
+
+void ImagePropertiesSideBarDB::slotAssignRatingTwoStar()
+{
+ d->desceditTab->assignRating(2);
+}
+
+void ImagePropertiesSideBarDB::slotAssignRatingThreeStar()
+{
+ d->desceditTab->assignRating(3);
+}
+
+void ImagePropertiesSideBarDB::slotAssignRatingFourStar()
+{
+ d->desceditTab->assignRating(4);
+}
+
+void ImagePropertiesSideBarDB::slotAssignRatingFiveStar()
+{
+ d->desceditTab->assignRating(5);
+}
+
+void ImagePropertiesSideBarDB::refreshTagsView()
+{
+ d->desceditTab->refreshTagsView();
+}
+
+} // NameSpace Digikam
diff --git a/digikam/libs/imageproperties/imagepropertiessidebardb.h b/digikam/libs/imageproperties/imagepropertiessidebardb.h
new file mode 100644
index 0000000..7f2d7c2
--- /dev/null
+++ b/digikam/libs/imageproperties/imagepropertiessidebardb.h
@@ -0,0 +1,116 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-11-17
+ * Description : image properties side bar using data from
+ * digiKam database.
+ *
+ * Copyright (C) 2004-2008 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ * Copyright (C) 2007 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
+ *
+ * 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 IMAGEPROPERTIESSIDEBARDB_H
+#define IMAGEPROPERTIESSIDEBARDB_H
+
+// Qt includes.
+
+#include <qptrlist.h>
+
+// KDE includes.
+
+#include <kurl.h>
+
+// Local includes.
+
+#include "imagepropertiessidebar.h"
+#include "digikam_export.h"
+
+class QSplitter;
+class QWidget;
+class QRect;
+
+namespace Digikam
+{
+
+class DImg;
+class AlbumIconView;
+class AlbumIconItem;
+class ImageInfo;
+class NavigateBarTab;
+class ImagePropertiesSideBarDBPriv;
+
+class DIGIKAM_EXPORT ImagePropertiesSideBarDB : public ImagePropertiesSideBar
+{
+ Q_OBJECT
+
+public:
+
+ ImagePropertiesSideBarDB(QWidget* parent, const char *name, QSplitter *splitter, Side side=Left,
+ bool mimimizedDefault=false);
+
+ ~ImagePropertiesSideBarDB();
+
+ virtual void itemChanged(const KURL& url, const QRect &rect = QRect(), DImg *img = 0);
+
+ virtual void itemChanged(ImageInfo *info, const QRect &rect = QRect(), DImg *img = 0);
+ virtual void itemChanged(QPtrList<ImageInfo> infos);
+
+ void takeImageInfoOwnership(bool takeOwnership);
+
+ void populateTags(void);
+ void refreshTagsView();
+
+signals:
+
+ void signalFirstItem(void);
+ void signalPrevItem(void);
+ void signalNextItem(void);
+ void signalLastItem(void);
+ void signalProgressBarMode(int, const QString&);
+ void signalProgressValue(int);
+
+public slots:
+
+ void slotAssignRating(int rating);
+ void slotAssignRatingNoStar();
+ void slotAssignRatingOneStar();
+ void slotAssignRatingTwoStar();
+ void slotAssignRatingThreeStar();
+ void slotAssignRatingFourStar();
+ void slotAssignRatingFiveStar();
+
+ virtual void slotNoCurrentItem(void);
+
+private slots:
+
+ void slotChangedTab(QWidget* tab);
+ void slotFileMetadataChanged(const KURL &url);
+
+private:
+
+ void itemChanged(const KURL& url, ImageInfo *info,
+ const QRect &rect, DImg *img);
+ void itemChanged(QPtrList<ImageInfo> infos, const QRect &rect, DImg *img);
+
+private:
+
+ ImagePropertiesSideBarDBPriv* d;
+};
+
+} // NameSpace Digikam
+
+#endif // IMAGEPROPERTIESSIDEBARDB_H
diff --git a/digikam/libs/imageproperties/imagepropertiestab.cpp b/digikam/libs/imageproperties/imagepropertiestab.cpp
new file mode 100644
index 0000000..3abf3d2
--- /dev/null
+++ b/digikam/libs/imageproperties/imagepropertiestab.cpp
@@ -0,0 +1,601 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2006-04-19
+ * Description : A tab to display general image information
+ *
+ * Copyright (C) 2006-2008 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.
+ *
+ * ============================================================ */
+
+// Qt includes.
+
+#include <qlayout.h>
+#include <qstyle.h>
+#include <qfile.h>
+#include <qlabel.h>
+#include <qpixmap.h>
+#include <qfileinfo.h>
+#include <qwhatsthis.h>
+#include <qframe.h>
+#include <qscrollview.h>
+
+// KDE includes.
+
+#include <klocale.h>
+#include <kdialogbase.h>
+#include <kfileitem.h>
+#include <ksqueezedtextlabel.h>
+#include <kseparator.h>
+
+// LibKDcraw includes.
+
+#include <libkdcraw/version.h>
+#include <libkdcraw/kdcraw.h>
+
+#if KDCRAW_VERSION < 0x000106
+#include <libkdcraw/dcrawbinary.h>
+#endif
+
+// Local includes.
+
+#include "ddebug.h"
+#include "dmetadata.h"
+#include "navigatebarwidget.h"
+#include "imagepropertiestab.h"
+#include "imagepropertiestab.moc"
+
+namespace Digikam
+{
+
+class ImagePropertiesTabPriv
+{
+public:
+
+ ImagePropertiesTabPriv()
+ {
+ settingsArea = 0;
+ title = 0;
+ file = 0;
+ folder = 0;
+ modifiedDate = 0;
+ size = 0;
+ owner = 0;
+ permissions = 0;
+ title2 = 0;
+ mime = 0;
+ dimensions = 0;
+ compression = 0;
+ bitDepth = 0;
+ colorMode = 0;
+ title3 = 0;
+ make = 0;
+ model = 0;
+ photoDate = 0;
+ aperture = 0;
+ focalLength = 0;
+ exposureTime = 0;
+ sensitivity = 0;
+ exposureMode = 0;
+ flash = 0;
+ whiteBalance = 0;
+ labelFile = 0;
+ labelFolder = 0;
+ labelFileModifiedDate = 0;
+ labelFileSize = 0;
+ labelFileOwner = 0;
+ labelFilePermissions = 0;
+ labelImageMime = 0;
+ labelImageDimensions = 0;
+ labelImageCompression = 0;
+ labelImageBitDepth = 0;
+ labelImageColorMode = 0;
+ labelPhotoMake = 0;
+ labelPhotoModel = 0;
+ labelPhotoDateTime = 0;
+ labelPhotoAperture = 0;
+ labelPhotoFocalLenght = 0;
+ labelPhotoExposureTime = 0;
+ labelPhotoSensitivity = 0;
+ labelPhotoExposureMode = 0;
+ labelPhotoFlash = 0;
+ labelPhotoWhiteBalance = 0;
+ }
+
+ QLabel *title;
+ QLabel *file;
+ QLabel *folder;
+ QLabel *modifiedDate;
+ QLabel *size;
+ QLabel *owner;
+ QLabel *permissions;
+
+ QLabel *title2;
+ QLabel *mime;
+ QLabel *dimensions;
+ QLabel *compression;
+ QLabel *bitDepth;
+ QLabel *colorMode;
+
+ QLabel *title3;
+ QLabel *make;
+ QLabel *model;
+ QLabel *photoDate;
+ QLabel *aperture;
+ QLabel *focalLength;
+ QLabel *exposureTime;
+ QLabel *sensitivity;
+ QLabel *exposureMode;
+ QLabel *flash;
+ QLabel *whiteBalance;
+
+ QFrame *settingsArea;
+
+ KSqueezedTextLabel *labelFile;
+ KSqueezedTextLabel *labelFolder;
+ KSqueezedTextLabel *labelFileModifiedDate;
+ KSqueezedTextLabel *labelFileSize;
+ KSqueezedTextLabel *labelFileOwner;
+ KSqueezedTextLabel *labelFilePermissions;
+
+ KSqueezedTextLabel *labelImageMime;
+ KSqueezedTextLabel *labelImageDimensions;
+ KSqueezedTextLabel *labelImageCompression;
+ KSqueezedTextLabel *labelImageBitDepth;
+ KSqueezedTextLabel *labelImageColorMode;
+
+ KSqueezedTextLabel *labelPhotoMake;
+ KSqueezedTextLabel *labelPhotoModel;
+ KSqueezedTextLabel *labelPhotoDateTime;
+ KSqueezedTextLabel *labelPhotoAperture;
+ KSqueezedTextLabel *labelPhotoFocalLenght;
+ KSqueezedTextLabel *labelPhotoExposureTime;
+ KSqueezedTextLabel *labelPhotoSensitivity;
+ KSqueezedTextLabel *labelPhotoExposureMode;
+ KSqueezedTextLabel *labelPhotoFlash;
+ KSqueezedTextLabel *labelPhotoWhiteBalance;
+};
+
+ImagePropertiesTab::ImagePropertiesTab(QWidget* parent, bool navBar)
+ : NavigateBarTab(parent)
+{
+ d = new ImagePropertiesTabPriv;
+
+ setupNavigateBar(navBar);
+
+ QScrollView *sv = new QScrollView(this);
+ sv->viewport()->setBackgroundMode(Qt::PaletteBackground);
+ sv->setResizePolicy(QScrollView::AutoOneFit);
+ sv->setFrameStyle(QFrame::NoFrame);
+
+ d->settingsArea = new QFrame(sv->viewport());
+ d->settingsArea->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken );
+ d->settingsArea->setLineWidth( style().pixelMetric(QStyle::PM_DefaultFrameWidth, this) );
+
+ sv->addChild(d->settingsArea);
+ m_navigateBarLayout->addWidget(sv);
+
+ // --------------------------------------------------
+
+ QGridLayout *settingsLayout = new QGridLayout(d->settingsArea, 33, 1, KDialog::spacingHint(), 0);
+
+ // --------------------------------------------------
+
+ d->title = new QLabel(i18n("<big><b>File Properties</b></big>"), d->settingsArea);
+ d->file = new QLabel(i18n("<b>File</b>:"), d->settingsArea);
+ d->folder = new QLabel(i18n("<b>Folder</b>:"), d->settingsArea);
+ d->modifiedDate = new QLabel(i18n("<b>Modified</b>:"), d->settingsArea);
+ d->size = new QLabel(i18n("<b>Size</b>:"), d->settingsArea);
+ d->owner = new QLabel(i18n("<b>Owner</b>:"), d->settingsArea);
+ d->permissions = new QLabel(i18n("<b>Permissions</b>:"), d->settingsArea);
+
+ KSeparator *line = new KSeparator (Horizontal, d->settingsArea);
+ d->title2 = new QLabel(i18n("<big><b>Image Properties</b></big>"), d->settingsArea);
+ d->mime = new QLabel(i18n("<b>Type</b>:"), d->settingsArea);
+ d->dimensions = new QLabel(i18n("<b>Dimensions</b>:"), d->settingsArea);
+ d->compression = new QLabel(i18n("<b>Compression</b>:"), d->settingsArea);
+ d->bitDepth = new QLabel(i18n("<nobr><b>Bit depth</b></nobr>:"), d->settingsArea);
+ d->colorMode = new QLabel(i18n("<nobr><b>Color mode</b></nobr>:"), d->settingsArea);
+
+ KSeparator *line2 = new KSeparator (Horizontal, d->settingsArea);
+ d->title3 = new QLabel(i18n("<big><b>Photograph Properties</b></big>"), d->settingsArea);
+ d->make = new QLabel(i18n("<b>Make</b>:"), d->settingsArea);
+ d->model = new QLabel(i18n("<b>Model</b>:"), d->settingsArea);
+ d->photoDate = new QLabel(i18n("<b>Created</b>:"), d->settingsArea);
+ d->aperture = new QLabel(i18n("<b>Aperture</b>:"), d->settingsArea);
+ d->focalLength = new QLabel(i18n("<b>Focal</b>:"), d->settingsArea);
+ d->exposureTime = new QLabel(i18n("<b>Exposure</b>:"), d->settingsArea);
+ d->sensitivity = new QLabel(i18n("<b>Sensitivity</b>:"), d->settingsArea);
+ d->exposureMode = new QLabel(i18n("<nobr><b>Mode/Program</b></nobr>:"), d->settingsArea);
+ d->flash = new QLabel(i18n("<b>Flash</b>:"), d->settingsArea);
+ d->whiteBalance = new QLabel(i18n("<nobr><b>White balance</b></nobr>:"), d->settingsArea);
+
+ d->labelFile = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelFolder = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelFileModifiedDate = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelFileSize = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelFileOwner = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelFilePermissions = new KSqueezedTextLabel(0, d->settingsArea);
+
+ d->labelImageMime = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelImageDimensions = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelImageCompression = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelImageBitDepth = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelImageColorMode = new KSqueezedTextLabel(0, d->settingsArea);
+
+ d->labelPhotoMake = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelPhotoModel = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelPhotoDateTime = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelPhotoAperture = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelPhotoFocalLenght = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelPhotoExposureTime = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelPhotoSensitivity = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelPhotoExposureMode = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelPhotoFlash = new KSqueezedTextLabel(0, d->settingsArea);
+ d->labelPhotoWhiteBalance = new KSqueezedTextLabel(0, d->settingsArea);
+
+ int hgt = fontMetrics().height()-2;
+ d->title->setAlignment(Qt::AlignCenter);
+ d->file->setMaximumHeight(hgt);
+ d->folder->setMaximumHeight(hgt);
+ d->modifiedDate->setMaximumHeight(hgt);
+ d->size->setMaximumHeight(hgt);
+ d->owner->setMaximumHeight(hgt);
+ d->permissions->setMaximumHeight(hgt);
+ d->labelFile->setMaximumHeight(hgt);
+ d->labelFolder->setMaximumHeight(hgt);
+ d->labelFileModifiedDate->setMaximumHeight(hgt);
+ d->labelFileSize->setMaximumHeight(hgt);
+ d->labelFileOwner->setMaximumHeight(hgt);
+ d->labelFilePermissions->setMaximumHeight(hgt);
+
+ d->title2->setAlignment(Qt::AlignCenter);
+ d->mime->setMaximumHeight(hgt);
+ d->dimensions->setMaximumHeight(hgt);
+ d->compression->setMaximumHeight(hgt);
+ d->bitDepth->setMaximumHeight(hgt);
+ d->colorMode->setMaximumHeight(hgt);
+ d->labelImageMime->setMaximumHeight(hgt);
+ d->labelImageDimensions->setMaximumHeight(hgt);
+ d->labelImageCompression->setMaximumHeight(hgt);
+ d->labelImageBitDepth->setMaximumHeight(hgt);
+ d->labelImageColorMode->setMaximumHeight(hgt);
+
+ d->title3->setAlignment(Qt::AlignCenter);
+ d->make->setMaximumHeight(hgt);
+ d->model->setMaximumHeight(hgt);
+ d->photoDate->setMaximumHeight(hgt);
+ d->aperture->setMaximumHeight(hgt);
+ d->focalLength->setMaximumHeight(hgt);
+ d->exposureTime->setMaximumHeight(hgt);
+ d->sensitivity->setMaximumHeight(hgt);
+ d->exposureMode->setMaximumHeight(hgt);
+ d->flash->setMaximumHeight(hgt);
+ d->whiteBalance->setMaximumHeight(hgt);
+ d->labelPhotoMake->setMaximumHeight(hgt);
+ d->labelPhotoModel->setMaximumHeight(hgt);
+ d->labelPhotoDateTime->setMaximumHeight(hgt);
+ d->labelPhotoAperture->setMaximumHeight(hgt);
+ d->labelPhotoFocalLenght->setMaximumHeight(hgt);
+ d->labelPhotoExposureTime->setMaximumHeight(hgt);
+ d->labelPhotoSensitivity->setMaximumHeight(hgt);
+ d->labelPhotoExposureMode->setMaximumHeight(hgt);
+ d->labelPhotoFlash->setMaximumHeight(hgt);
+ d->labelPhotoWhiteBalance->setMaximumHeight(hgt);
+
+ // --------------------------------------------------
+
+ settingsLayout->addMultiCellWidget(d->title, 0, 0, 0, 1);
+ settingsLayout->addMultiCell(new QSpacerItem(KDialog::spacingHint(), KDialog::spacingHint(),
+ QSizePolicy::Minimum, QSizePolicy::MinimumExpanding), 1, 1, 0, 1);
+ settingsLayout->addMultiCellWidget(d->file, 2, 2, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelFile, 2, 2, 1, 1);
+ settingsLayout->addMultiCellWidget(d->folder, 3, 3, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelFolder, 3, 3, 1, 1);
+ settingsLayout->addMultiCellWidget(d->modifiedDate, 4, 4, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelFileModifiedDate, 4, 4, 1, 1);
+ settingsLayout->addMultiCellWidget(d->size, 5, 5, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelFileSize, 5, 5, 1, 1);
+ settingsLayout->addMultiCellWidget(d->owner, 6, 6, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelFileOwner, 6, 6, 1, 1);
+ settingsLayout->addMultiCellWidget(d->permissions, 7, 7, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelFilePermissions, 7, 7, 1, 1);
+
+ settingsLayout->addMultiCell(new QSpacerItem(KDialog::spacingHint(), KDialog::spacingHint(),
+ QSizePolicy::Minimum, QSizePolicy::MinimumExpanding), 8, 8, 0, 1);
+ settingsLayout->addMultiCellWidget(line, 9, 9, 0, 1);
+ settingsLayout->addMultiCell(new QSpacerItem(KDialog::spacingHint(), KDialog::spacingHint(),
+ QSizePolicy::Minimum, QSizePolicy::MinimumExpanding), 10, 10, 0, 1);
+
+ settingsLayout->addMultiCellWidget(d->title2, 11, 11, 0, 1);
+ settingsLayout->addMultiCell(new QSpacerItem(KDialog::spacingHint(), KDialog::spacingHint(),
+ QSizePolicy::Minimum, QSizePolicy::MinimumExpanding), 12, 12, 0, 1);
+ settingsLayout->addMultiCellWidget(d->mime, 13, 13, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelImageMime, 13, 13, 1, 1);
+ settingsLayout->addMultiCellWidget(d->dimensions, 14, 14, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelImageDimensions, 14, 14, 1, 1);
+ settingsLayout->addMultiCellWidget(d->compression, 15, 15, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelImageCompression, 15, 15, 1, 1);
+ settingsLayout->addMultiCellWidget(d->bitDepth, 16, 16, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelImageBitDepth, 16, 16, 1, 1);
+ settingsLayout->addMultiCellWidget(d->colorMode, 17, 17, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelImageColorMode, 17, 17, 1, 1);
+
+ settingsLayout->addMultiCell(new QSpacerItem(KDialog::spacingHint(), KDialog::spacingHint(),
+ QSizePolicy::Minimum, QSizePolicy::MinimumExpanding), 18, 18, 0, 1);
+ settingsLayout->addMultiCellWidget(line2, 19, 19, 0, 1);
+ settingsLayout->addMultiCell(new QSpacerItem(KDialog::spacingHint(), KDialog::spacingHint(),
+ QSizePolicy::Minimum, QSizePolicy::MinimumExpanding), 20, 20, 0, 1);
+
+ settingsLayout->addMultiCellWidget(d->title3, 21, 21, 0, 1);
+ settingsLayout->addMultiCell(new QSpacerItem(KDialog::spacingHint(), KDialog::spacingHint(),
+ QSizePolicy::Minimum, QSizePolicy::MinimumExpanding), 22, 22, 0, 1);
+ settingsLayout->addMultiCellWidget(d->make, 23, 23, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelPhotoMake, 23, 23, 1, 1);
+ settingsLayout->addMultiCellWidget(d->model, 24, 24, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelPhotoModel, 24, 24, 1, 1);
+ settingsLayout->addMultiCellWidget(d->photoDate, 25, 25, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelPhotoDateTime, 25, 25, 1, 1);
+ settingsLayout->addMultiCellWidget(d->aperture, 26, 26, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelPhotoAperture, 26, 26, 1, 1);
+ settingsLayout->addMultiCellWidget(d->focalLength, 27, 27, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelPhotoFocalLenght, 27, 27, 1, 1);
+ settingsLayout->addMultiCellWidget(d->exposureTime, 28, 28, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelPhotoExposureTime, 28, 28, 1, 1);
+ settingsLayout->addMultiCellWidget(d->sensitivity, 29, 29, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelPhotoSensitivity, 29, 29, 1, 1);
+ settingsLayout->addMultiCellWidget(d->exposureMode, 30, 30, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelPhotoExposureMode, 30, 30, 1, 1);
+ settingsLayout->addMultiCellWidget(d->flash, 31, 31, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelPhotoFlash, 31, 31, 1, 1);
+ settingsLayout->addMultiCellWidget(d->whiteBalance, 32, 32, 0, 0);
+ settingsLayout->addMultiCellWidget(d->labelPhotoWhiteBalance, 32, 32, 1, 1);
+
+ settingsLayout->setRowStretch(33, 10);
+ settingsLayout->setColStretch(1, 10);
+}
+
+ImagePropertiesTab::~ImagePropertiesTab()
+{
+ delete d;
+}
+
+void ImagePropertiesTab::setCurrentURL(const KURL& url)
+{
+ if (url.isEmpty())
+ {
+ setNavigateBarFileName();
+
+ d->labelFile->setText(QString());
+ d->labelFolder->setText(QString());
+ d->labelFileModifiedDate->setText(QString());
+ d->labelFileSize->setText(QString());
+ d->labelFileOwner->setText(QString());
+ d->labelFilePermissions->setText(QString());
+
+ d->labelImageMime->setText(QString());
+ d->labelImageDimensions->setText(QString());
+ d->labelImageCompression->setText(QString());
+ d->labelImageBitDepth->setText(QString());
+ d->labelImageColorMode->setText(QString());
+
+ d->labelPhotoMake->setText(QString());
+ d->labelPhotoModel->setText(QString());
+ d->labelPhotoDateTime->setText(QString());
+ d->labelPhotoAperture->setText(QString());
+ d->labelPhotoFocalLenght->setText(QString());
+ d->labelPhotoExposureTime->setText(QString());
+ d->labelPhotoSensitivity->setText(QString());
+ d->labelPhotoExposureMode->setText(QString());
+ d->labelPhotoFlash->setText(QString());
+ d->labelPhotoWhiteBalance->setText(QString());
+
+ setEnabled(false);
+ return;
+ }
+
+ setEnabled(true);
+
+ QString str;
+ QString unavailable(i18n("<i>unavailable</i>"));
+
+ KFileItem fi(KFileItem::Unknown, KFileItem::Unknown, url);
+ QFileInfo fileInfo(url.path());
+ DMetadata metaData(url.path());
+
+ // -- File system information ------------------------------------------
+
+ d->labelFile->setText(url.fileName());
+ d->labelFolder->setText(url.directory());
+
+ QDateTime modifiedDate = fileInfo.lastModified();
+ str = KGlobal::locale()->formatDateTime(modifiedDate, true, true);
+ d->labelFileModifiedDate->setText(str);
+
+ str = QString("%1 (%2)").arg(KIO::convertSize(fi.size()))
+ .arg(KGlobal::locale()->formatNumber(fi.size(), 0));
+ d->labelFileSize->setText(str);
+
+ d->labelFileOwner->setText( QString("%1 - %2").arg(fi.user()).arg(fi.group()) );
+ d->labelFilePermissions->setText( fi.permissionsString() );
+
+ // -- Image Properties --------------------------------------------------
+
+ QSize dims;
+ QString compression, bitDepth, colorMode;
+#if KDCRAW_VERSION < 0x000106
+ QString rawFilesExt(KDcrawIface::DcrawBinary::instance()->rawFiles());
+#else
+ QString rawFilesExt(KDcrawIface::KDcraw::rawFiles());
+#endif
+ QString ext = fileInfo.extension(false).upper();
+
+ if (!ext.isEmpty() && rawFilesExt.upper().contains(ext))
+ {
+ d->labelImageMime->setText(i18n("RAW Image"));
+ compression = i18n("None");
+ bitDepth = "48";
+ dims = metaData.getImageDimensions();
+ colorMode = i18n("Uncalibrated");
+ }
+ else
+ {
+ d->labelImageMime->setText(fi.mimeComment());
+
+ KFileMetaInfo meta = fi.metaInfo();
+ if (meta.isValid())
+ {
+ if (meta.containsGroup("Jpeg EXIF Data")) // JPEG image ?
+ {
+ dims = meta.group("Jpeg EXIF Data").item("Dimensions").value().toSize();
+
+ QString quality = meta.group("Jpeg EXIF Data").item("JPEG quality").value().toString();
+ quality.isEmpty() ? compression = unavailable :
+ compression = i18n("JPEG quality %1").arg(quality);
+ bitDepth = meta.group("Jpeg EXIF Data").item("BitDepth").value().toString();
+ colorMode = meta.group("Jpeg EXIF Data").item("ColorMode").value().toString();
+ }
+
+ if (meta.containsGroup("General"))
+ {
+ if (dims.isEmpty() )
+ dims = meta.group("General").item("Dimensions").value().toSize();
+ if (compression.isEmpty())
+ compression = meta.group("General").item("Compression").value().toString();
+ if (bitDepth.isEmpty())
+ bitDepth = meta.group("General").item("BitDepth").value().toString();
+ if (colorMode.isEmpty())
+ colorMode = meta.group("General").item("ColorMode").value().toString();
+ }
+
+ if (meta.containsGroup("Technical"))
+ {
+ if (dims.isEmpty())
+ dims = meta.group("Technical").item("Dimensions").value().toSize();
+ if (compression.isEmpty())
+ compression = meta.group("Technical").item("Compression").value().toString();
+ if (bitDepth.isEmpty())
+ bitDepth = meta.group("Technical").item("BitDepth").value().toString();
+ if (colorMode.isEmpty())
+ colorMode = meta.group("Technical").item("ColorMode").value().toString();
+ }
+ }
+ }
+
+ QString mpixels;
+ mpixels.setNum(dims.width()*dims.height()/1000000.0, 'f', 2);
+ str = (!dims.isValid()) ? i18n("Unknown") : i18n("%1x%2 (%3Mpx)")
+ .arg(dims.width()).arg(dims.height()).arg(mpixels);
+ d->labelImageDimensions->setText(str);
+ d->labelImageCompression->setText(compression.isEmpty() ? unavailable : compression);
+ d->labelImageBitDepth->setText(bitDepth.isEmpty() ? unavailable : i18n("%1 bpp").arg(bitDepth));
+ d->labelImageColorMode->setText(colorMode.isEmpty() ? unavailable : colorMode);
+
+ // -- Photograph information ------------------------------------------
+ // NOTA: If something is changed here, please updated albumfiletip section too.
+
+ PhotoInfoContainer photoInfo = metaData.getPhotographInformations();
+
+ if (photoInfo.isEmpty())
+ {
+ d->title3->hide();
+ d->make->hide();
+ d->model->hide();
+ d->photoDate->hide();
+ d->aperture->hide();
+ d->focalLength->hide();
+ d->exposureTime->hide();
+ d->sensitivity->hide();
+ d->exposureMode->hide();
+ d->flash->hide();
+ d->whiteBalance->hide();
+ d->labelPhotoMake->hide();
+ d->labelPhotoModel->hide();
+ d->labelPhotoDateTime->hide();
+ d->labelPhotoAperture->hide();
+ d->labelPhotoFocalLenght->hide();
+ d->labelPhotoExposureTime->hide();
+ d->labelPhotoSensitivity->hide();
+ d->labelPhotoExposureMode->hide();
+ d->labelPhotoFlash->hide();
+ d->labelPhotoWhiteBalance->hide();
+ }
+ else
+ {
+ d->title3->show();
+ d->make->show();
+ d->model->show();
+ d->photoDate->show();
+ d->aperture->show();
+ d->focalLength->show();
+ d->exposureTime->show();
+ d->sensitivity->show();
+ d->exposureMode->show();
+ d->flash->show();
+ d->whiteBalance->show();
+ d->labelPhotoMake->show();
+ d->labelPhotoModel->show();
+ d->labelPhotoDateTime->show();
+ d->labelPhotoAperture->show();
+ d->labelPhotoFocalLenght->show();
+ d->labelPhotoExposureTime->show();
+ d->labelPhotoSensitivity->show();
+ d->labelPhotoExposureMode->show();
+ d->labelPhotoFlash->show();
+ d->labelPhotoWhiteBalance->show();
+ }
+
+ d->labelPhotoMake->setText(photoInfo.make.isEmpty() ? unavailable : photoInfo.make);
+ d->labelPhotoModel->setText(photoInfo.model.isEmpty() ? unavailable : photoInfo.model);
+
+ if (photoInfo.dateTime.isValid())
+ {
+ str = KGlobal::locale()->formatDateTime(photoInfo.dateTime, true, true);
+ d->labelPhotoDateTime->setText(str);
+ }
+ else
+ d->labelPhotoDateTime->setText(unavailable);
+
+ d->labelPhotoAperture->setText(photoInfo.aperture.isEmpty() ? unavailable : photoInfo.aperture);
+
+ if (photoInfo.focalLength35mm.isEmpty())
+ d->labelPhotoFocalLenght->setText(photoInfo.focalLength.isEmpty() ? unavailable : photoInfo.focalLength);
+ else
+ {
+ str = i18n("%1 (35mm: %2)").arg(photoInfo.focalLength).arg(photoInfo.focalLength35mm);
+ d->labelPhotoFocalLenght->setText(str);
+ }
+
+ d->labelPhotoExposureTime->setText(photoInfo.exposureTime.isEmpty() ? unavailable : photoInfo.exposureTime);
+ d->labelPhotoSensitivity->setText(photoInfo.sensitivity.isEmpty() ? unavailable : i18n("%1 ISO").arg(photoInfo.sensitivity));
+
+ if (photoInfo.exposureMode.isEmpty() && photoInfo.exposureProgram.isEmpty())
+ d->labelPhotoExposureMode->setText(unavailable);
+ else if (!photoInfo.exposureMode.isEmpty() && photoInfo.exposureProgram.isEmpty())
+ d->labelPhotoExposureMode->setText(photoInfo.exposureMode);
+ else if (photoInfo.exposureMode.isEmpty() && !photoInfo.exposureProgram.isEmpty())
+ d->labelPhotoExposureMode->setText(photoInfo.exposureProgram);
+ else
+ {
+ str = QString("%1 / %2").arg(photoInfo.exposureMode).arg(photoInfo.exposureProgram);
+ d->labelPhotoExposureMode->setText(str);
+ }
+
+ d->labelPhotoFlash->setText(photoInfo.flash.isEmpty() ? unavailable : photoInfo.flash);
+ d->labelPhotoWhiteBalance->setText(photoInfo.whiteBalance.isEmpty() ? unavailable : photoInfo.whiteBalance);
+}
+
+} // NameSpace Digikam
diff --git a/digikam/libs/imageproperties/imagepropertiestab.h b/digikam/libs/imageproperties/imagepropertiestab.h
new file mode 100644
index 0000000..be54f93
--- /dev/null
+++ b/digikam/libs/imageproperties/imagepropertiestab.h
@@ -0,0 +1,65 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2006-04-19
+ * Description : A tab to display general image information
+ *
+ * Copyright (C) 2006-2008 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 IMAGEPROPERTIESTAB_H
+#define IMAGEPROPERTIESTAB_H
+
+// Qt includes.
+
+#include <qwidget.h>
+#include <qstring.h>
+#include <qcolor.h>
+
+// KDE includes.
+
+#include <kurl.h>
+
+// Local includes.
+
+#include "digikam_export.h"
+#include "navigatebartab.h"
+
+namespace Digikam
+{
+
+class ImagePropertiesTabPriv;
+
+class DIGIKAM_EXPORT ImagePropertiesTab : public NavigateBarTab
+{
+ Q_OBJECT
+
+public:
+
+ ImagePropertiesTab(QWidget* parent, bool navBar=true);
+ ~ImagePropertiesTab();
+
+ void setCurrentURL(const KURL& url=KURL());
+
+private:
+
+ ImagePropertiesTabPriv* d;
+};
+
+} // NameSpace Digikam
+
+#endif /* IMAGEPROPERTIESTAB_H */
diff --git a/digikam/libs/imageproperties/navigatebartab.cpp b/digikam/libs/imageproperties/navigatebartab.cpp
new file mode 100644
index 0000000..dd3ae3f
--- /dev/null
+++ b/digikam/libs/imageproperties/navigatebartab.cpp
@@ -0,0 +1,146 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2007-01-04
+ * Description : A parent tab class with a navigation bar
+ *
+ * Copyright (C) 2006-2007 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ * Copyright (C) 2007 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
+ *
+ * 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.
+ *
+ * ============================================================ */
+
+// Qt includes.
+
+#include <qlayout.h>
+#include <qwidgetstack.h>
+#include <qlabel.h>
+
+// Local includes.
+
+#include "statusnavigatebar.h"
+#include "navigatebarwidget.h"
+#include "navigatebartab.h"
+#include "navigatebartab.moc"
+
+namespace Digikam
+{
+
+class NavigateBarTabPriv
+{
+public:
+
+ NavigateBarTabPriv()
+ {
+ stack = 0;
+ navigateBar = 0;
+ label = 0;
+ }
+
+ QWidgetStack *stack;
+
+ QLabel *label;
+
+ NavigateBarWidget *navigateBar;
+};
+
+NavigateBarTab::NavigateBarTab(QWidget* parent)
+ : QWidget(parent, 0, Qt::WDestructiveClose)
+{
+ d = new NavigateBarTabPriv;
+ m_navigateBarLayout = 0;
+}
+
+NavigateBarTab::~NavigateBarTab()
+{
+ delete d;
+}
+
+void NavigateBarTab::setupNavigateBar(bool withBar)
+{
+ m_navigateBarLayout = new QVBoxLayout(this);
+
+ if (withBar)
+ {
+ d->stack = new QWidgetStack(this);
+ m_navigateBarLayout->addWidget(d->stack);
+
+ d->navigateBar = new NavigateBarWidget(d->stack, withBar);
+ d->stack->addWidget(d->navigateBar);
+
+ connect(d->navigateBar, SIGNAL(signalFirstItem()),
+ this, SIGNAL(signalFirstItem()));
+
+ connect(d->navigateBar, SIGNAL(signalPrevItem()),
+ this, SIGNAL(signalPrevItem()));
+
+ connect(d->navigateBar, SIGNAL(signalNextItem()),
+ this, SIGNAL(signalNextItem()));
+
+ connect(d->navigateBar, SIGNAL(signalLastItem()),
+ this, SIGNAL(signalLastItem()));
+
+ d->label = new QLabel(d->stack);
+ d->label->setAlignment(Qt::AlignCenter);
+ d->stack->addWidget(d->label);
+ }
+}
+
+void NavigateBarTab::setNavigateBarState(bool hasPrevious, bool hasNext)
+{
+ if (!d->navigateBar)
+ return;
+
+ d->stack->raiseWidget(d->navigateBar);
+
+ if (hasPrevious && hasNext)
+ d->navigateBar->setButtonsState(StatusNavigateBar::ItemCurrent);
+ else if (!hasPrevious && hasNext)
+ d->navigateBar->setButtonsState(StatusNavigateBar::ItemFirst);
+ else if (hasPrevious && !hasNext)
+ d->navigateBar->setButtonsState(StatusNavigateBar::ItemLast);
+ else
+ d->navigateBar->setButtonsState(StatusNavigateBar::NoNavigation);
+}
+
+void NavigateBarTab::setNavigateBarState(int itemType)
+{
+ if (!d->navigateBar)
+ return;
+
+ d->stack->raiseWidget(d->navigateBar);
+ d->navigateBar->setButtonsState(itemType);
+}
+
+void NavigateBarTab::setNavigateBarFileName(const QString &name)
+{
+ if (!d->navigateBar)
+ return;
+
+ d->stack->raiseWidget(d->navigateBar);
+ d->navigateBar->setFileName(name);
+}
+
+void NavigateBarTab::setLabelText(const QString &text)
+{
+ if (!d->label)
+ return;
+
+ d->stack->raiseWidget(d->label);
+ d->label->setText(text);
+}
+
+} // NameSpace Digikam
+
diff --git a/digikam/libs/imageproperties/navigatebartab.h b/digikam/libs/imageproperties/navigatebartab.h
new file mode 100644
index 0000000..27a34c9
--- /dev/null
+++ b/digikam/libs/imageproperties/navigatebartab.h
@@ -0,0 +1,84 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2007-01-04
+ * Description : A parent tab class with a navigation bar
+ *
+ * Copyright (C) 2006-2007 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ * Copyright (C) 2007 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
+ *
+ * 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 NAVIGATEBARTAB_H
+#define NAVIGATEBARTAB_H
+
+// Qt includes.
+
+#include <qwidget.h>
+#include <qstring.h>
+
+// KDE includes.
+
+#include <kurl.h>
+
+// Local includes.
+
+#include "digikam_export.h"
+#include "imagepropertiessidebar.h"
+
+class QVBoxLayout;
+
+namespace Digikam
+{
+
+class NavigateBarWidget;
+class NavigateBarTabPriv;
+
+class DIGIKAM_EXPORT NavigateBarTab : public QWidget
+{
+ Q_OBJECT
+
+public:
+
+ NavigateBarTab(QWidget* parent);
+ ~NavigateBarTab();
+
+ void setNavigateBarState(bool hasPrevious, bool hasNext);
+ void setNavigateBarState(int itemType);
+ void setNavigateBarFileName(const QString &name = QString());
+ void setLabelText(const QString &text);
+
+signals:
+
+ void signalFirstItem(void);
+ void signalPrevItem(void);
+ void signalNextItem(void);
+ void signalLastItem(void);
+
+protected:
+
+ void setupNavigateBar(bool withBar);
+
+protected:
+
+ QVBoxLayout *m_navigateBarLayout;
+ NavigateBarTabPriv *d;
+
+};
+
+} // NameSpace Digikam
+
+#endif /* NAVIGATEBARTAB_H */
diff --git a/digikam/libs/imageproperties/navigatebarwidget.cpp b/digikam/libs/imageproperties/navigatebarwidget.cpp
new file mode 100644
index 0000000..79745bc
--- /dev/null
+++ b/digikam/libs/imageproperties/navigatebarwidget.cpp
@@ -0,0 +1,112 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2005-07-07
+ * Description : a navigate bar with text
+ *
+ * Copyright (C) 2005-2007 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ *
+ * This program is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation;
+ * either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * ============================================================ */
+
+// Qt includes.
+
+#include <qlayout.h>
+
+// KDE includes.
+
+#include <ksqueezedtextlabel.h>
+#include <kdialogbase.h>
+#include <klocale.h>
+
+// Local includes.
+
+#include "statusnavigatebar.h"
+#include "navigatebarwidget.h"
+#include "navigatebarwidget.moc"
+
+namespace Digikam
+{
+
+class NavigateBarWidgetPriv
+{
+public:
+
+ NavigateBarWidgetPriv()
+ {
+ filename = 0;
+ navBar = 0;
+ }
+
+ KSqueezedTextLabel *filename;
+
+ StatusNavigateBar *navBar;
+};
+
+NavigateBarWidget::NavigateBarWidget(QWidget *parent, bool show)
+ : QWidget(parent, 0, Qt::WDestructiveClose)
+{
+ d = new NavigateBarWidgetPriv;
+
+ QHBoxLayout *lay = new QHBoxLayout(this);
+ d->navBar = new StatusNavigateBar(this);
+ d->filename = new KSqueezedTextLabel(this);
+
+ lay->addWidget(d->navBar);
+ lay->addSpacing( KDialog::spacingHint() );
+ lay->addWidget(d->filename);
+
+ if (!show) hide();
+
+ connect(d->navBar, SIGNAL(signalFirstItem()),
+ this, SIGNAL(signalFirstItem()));
+
+ connect(d->navBar, SIGNAL(signalPrevItem()),
+ this, SIGNAL(signalPrevItem()));
+
+ connect(d->navBar, SIGNAL(signalNextItem()),
+ this, SIGNAL(signalNextItem()));
+
+ connect(d->navBar, SIGNAL(signalLastItem()),
+ this, SIGNAL(signalLastItem()));
+}
+
+NavigateBarWidget::~NavigateBarWidget()
+{
+ delete d;
+}
+
+void NavigateBarWidget::setFileName(QString filename)
+{
+ d->filename->setText(filename);
+}
+
+QString NavigateBarWidget::getFileName()
+{
+ return (d->filename->text());
+}
+
+void NavigateBarWidget::setButtonsState(int itemType)
+{
+ d->navBar->setButtonsState(itemType);
+}
+
+int NavigateBarWidget::getButtonsState()
+{
+ return (d->navBar->getButtonsState());
+}
+
+} // namespace Digikam
+
diff --git a/digikam/libs/imageproperties/navigatebarwidget.h b/digikam/libs/imageproperties/navigatebarwidget.h
new file mode 100644
index 0000000..ba3f87c
--- /dev/null
+++ b/digikam/libs/imageproperties/navigatebarwidget.h
@@ -0,0 +1,69 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2005-07-07
+ * Description : a navigate bar with text
+ *
+ * Copyright (C) 2005-2007 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ *
+ * This program is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation;
+ * either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * ============================================================ */
+
+#ifndef NAVIGATEBARWIDGET_H
+#define NAVIGATEBARWIDGET_H
+
+// Qt includes.
+
+#include <qwidget.h>
+#include <qstring.h>
+
+// Local includes.
+
+#include "digikam_export.h"
+
+namespace Digikam
+{
+
+class NavigateBarWidgetPriv;
+
+class DIGIKAM_EXPORT NavigateBarWidget : public QWidget
+{
+Q_OBJECT
+
+public:
+
+ NavigateBarWidget(QWidget *parent=0, bool show=true);
+ ~NavigateBarWidget();
+
+ void setFileName(QString filename=QString());
+ QString getFileName();
+ void setButtonsState(int itemType);
+ int getButtonsState();
+
+signals:
+
+ void signalFirstItem(void);
+ void signalPrevItem(void);
+ void signalNextItem(void);
+ void signalLastItem(void);
+
+private :
+
+ NavigateBarWidgetPriv* d;
+};
+
+} // namespace Digikam
+
+#endif /* NAVIGATEBARWIDGET_H */
diff --git a/digikam/libs/imageproperties/talbumlistview.cpp b/digikam/libs/imageproperties/talbumlistview.cpp
new file mode 100644
index 0000000..4c85aad
--- /dev/null
+++ b/digikam/libs/imageproperties/talbumlistview.cpp
@@ -0,0 +1,528 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2006-18-12
+ * Description : A list view to display digiKam Tags.
+ *
+ * Copyright (C) 2006-2009 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ * Copyright (C) 2009 by Andi Clemens <andi dot clemens at gmx dot net>
+ *
+ * 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.
+ *
+ * ============================================================ */
+
+// Qt includes.
+
+#include <qheader.h>
+
+// KDE includes.
+
+#include <kpopupmenu.h>
+#include <klocale.h>
+#include <kurl.h>
+#include <kcursor.h>
+#include <kapplication.h>
+#include <kiconloader.h>
+#include <kmessagebox.h>
+#include <kconfig.h>
+#include <kglobalsettings.h>
+#include <kdialogbase.h>
+
+// Local includes.
+
+#include "ddebug.h"
+#include "albumiconitem.h"
+#include "albumlister.h"
+#include "albummanager.h"
+#include "albumdb.h"
+#include "album.h"
+#include "albumsettings.h"
+#include "imageinfo.h"
+#include "navigatebarwidget.h"
+#include "dragobjects.h"
+#include "imageattributeswatch.h"
+#include "albumthumbnailloader.h"
+#include "statusprogressbar.h"
+#include "talbumlistview.h"
+#include "talbumlistview.moc"
+
+// X11 includes.
+
+extern "C"
+{
+#include <X11/Xlib.h>
+}
+
+namespace Digikam
+{
+
+TAlbumCheckListItem::TAlbumCheckListItem(QListView* parent, TAlbum* album)
+ : FolderCheckListItem(parent, album->title(), QCheckListItem::RadioButtonController)
+{
+ setDragEnabled(true);
+ m_album = album;
+ m_count = 0;
+
+ if (m_album)
+ m_album->setExtraData(listView(), this);
+}
+
+TAlbumCheckListItem::TAlbumCheckListItem(QCheckListItem* parent, TAlbum* album)
+ : FolderCheckListItem(parent, album->title(), QCheckListItem::CheckBox)
+{
+ setDragEnabled(true);
+ m_album = album;
+ m_count = 0;
+
+ if (m_album)
+ m_album->setExtraData(listView(), this);
+}
+
+void TAlbumCheckListItem::refresh()
+{
+ if (!m_album) return;
+
+ if (AlbumSettings::instance()->getShowFolderTreeViewItemsCount() &&
+ dynamic_cast<TAlbumCheckListItem*>(parent()))
+ {
+ if (isOpen())
+ setText(0, QString("%1 (%2)").arg(m_album->title()).arg(m_count));
+ else
+ {
+ int countRecursive = m_count;
+ AlbumIterator it(m_album);
+ while ( it.current() )
+ {
+ TAlbumCheckListItem *item = (TAlbumCheckListItem*)it.current()->extraData(listView());
+ if (item)
+ countRecursive += item->count();
+ ++it;
+ }
+ setText(0, QString("%1 (%2)").arg(m_album->title()).arg(countRecursive));
+ }
+ }
+ else
+ {
+ setText(0, m_album->title());
+ }
+}
+
+void TAlbumCheckListItem::stateChange(bool val)
+{
+ QCheckListItem::stateChange(val);
+ ((TAlbumListView*)listView())->stateChanged(this);
+}
+
+void TAlbumCheckListItem::setOpen(bool o)
+{
+ QListViewItem::setOpen(o);
+ refresh();
+}
+
+TAlbum* TAlbumCheckListItem::album() const
+{
+ return m_album;
+}
+
+int TAlbumCheckListItem::id() const
+{
+ return m_album ? m_album->id() : 0;
+}
+
+void TAlbumCheckListItem::setCount(int count)
+{
+ m_count = count;
+ refresh();
+}
+
+int TAlbumCheckListItem::count()
+{
+ return m_count;
+}
+
+void TAlbumCheckListItem::setStatus(MetadataHub::TagStatus status)
+{
+ if (status == MetadataHub::MetadataDisjoint)
+ {
+ if (type() != QCheckListItem::RadioButtonController) setTristate(true);
+ setState(QCheckListItem::NoChange);
+ }
+ else
+ {
+ if (type() != QCheckListItem::RadioButtonController) setTristate(false);
+ setOn(status.hasTag);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+TAlbumListView::TAlbumListView(QWidget* parent)
+ : FolderView(parent, "TAlbumListView")
+{
+ addColumn(i18n("Tags"));
+ header()->hide();
+ setResizeMode(QListView::LastColumn);
+ setRootIsDecorated(true);
+
+ setAcceptDrops(true);
+ viewport()->setAcceptDrops(true);
+
+ connect(AlbumManager::instance(), SIGNAL(signalTAlbumsDirty(const QMap<int, int>&)),
+ this, SLOT(slotRefresh(const QMap<int, int>&)));
+}
+
+TAlbumListView::~TAlbumListView()
+{
+ saveViewState();
+}
+
+void TAlbumListView::stateChanged(TAlbumCheckListItem *item)
+{
+ emit signalItemStateChanged(item);
+}
+
+QDragObject* TAlbumListView::dragObject()
+{
+ TAlbumCheckListItem *item = dynamic_cast<TAlbumCheckListItem*>(dragItem());
+ if(!item)
+ return 0;
+
+ if(!item->parent())
+ return 0;
+
+ TagDrag *t = new TagDrag(item->id(), this);
+ t->setPixmap(*item->pixmap(0));
+
+ return t;
+}
+
+bool TAlbumListView::acceptDrop(const QDropEvent *e) const
+{
+ QPoint vp = contentsToViewport(e->pos());
+ TAlbumCheckListItem *itemDrop = dynamic_cast<TAlbumCheckListItem*>(itemAt(vp));
+ TAlbumCheckListItem *itemDrag = dynamic_cast<TAlbumCheckListItem*>(dragItem());
+
+ if(TagDrag::canDecode(e) || TagListDrag::canDecode(e))
+ {
+ // Allow dragging at the root, to move the tag to the root
+ if(!itemDrop)
+ return true;
+
+ // Dragging an item on itself makes no sense
+ if(itemDrag == itemDrop)
+ return false;
+
+ // Dragging a parent on its child makes no sense
+ if(itemDrag && itemDrag->album()->isAncestorOf(itemDrop->album()))
+ return false;
+
+ return true;
+ }
+
+ if (ItemDrag::canDecode(e) && itemDrop && itemDrop->album()->parent())
+ {
+ // Only other possibility is image items being dropped
+ // And allow this only if there is a Tag to be dropped
+ // on and also the Tag is not root.
+ return true;
+ }
+
+ return false;
+}
+
+void TAlbumListView::contentsDropEvent(QDropEvent *e)
+{
+ QListView::contentsDropEvent(e);
+
+ if(!acceptDrop(e))
+ return;
+
+ QPoint vp = contentsToViewport(e->pos());
+ TAlbumCheckListItem *itemDrop = dynamic_cast<TAlbumCheckListItem*>(itemAt(vp));
+
+ if(TagDrag::canDecode(e))
+ {
+ QByteArray ba = e->encodedData("digikam/tag-id");
+ QDataStream ds(ba, IO_ReadOnly);
+ int tagID;
+ ds >> tagID;
+
+ AlbumManager* man = AlbumManager::instance();
+ TAlbum* talbum = man->findTAlbum(tagID);
+
+ if(!talbum)
+ return;
+
+ if (talbum == itemDrop->album())
+ return;
+
+ KPopupMenu popMenu(this);
+ popMenu.insertTitle(SmallIcon("digikam"), i18n("Tags"));
+ popMenu.insertItem(SmallIcon("goto"), i18n("&Move Here"), 10);
+ popMenu.insertSeparator(-1);
+ popMenu.insertItem(SmallIcon("cancel"), i18n("C&ancel"), 20);
+ popMenu.setMouseTracking(true);
+ int id = popMenu.exec(QCursor::pos());
+
+ if(id == 10)
+ {
+ TAlbum *newParentTag = 0;
+
+ if (!itemDrop)
+ {
+ // move dragItem to the root
+ newParentTag = AlbumManager::instance()->findTAlbum(0);
+ }
+ else
+ {
+ // move dragItem as child of dropItem
+ newParentTag = itemDrop->album();
+ }
+
+ QString errMsg;
+ if (!AlbumManager::instance()->moveTAlbum(talbum, newParentTag, errMsg))
+ {
+ KMessageBox::error(this, errMsg);
+ }
+
+ if(itemDrop && !itemDrop->isOpen())
+ itemDrop->setOpen(true);
+ }
+
+ return;
+ }
+
+ if (ItemDrag::canDecode(e))
+ {
+ TAlbum *destAlbum = itemDrop->album();
+ TAlbum *srcAlbum;
+
+ KURL::List urls;
+ KURL::List kioURLs;
+ QValueList<int> albumIDs;
+ QValueList<int> imageIDs;
+
+ if (!ItemDrag::decode(e, urls, kioURLs, albumIDs, imageIDs))
+ return;
+
+ if (urls.isEmpty() || kioURLs.isEmpty() || albumIDs.isEmpty() || imageIDs.isEmpty())
+ return;
+
+ // all the albumids will be the same
+ int albumID = albumIDs.first();
+ srcAlbum = AlbumManager::instance()->findTAlbum(albumID);
+ if (!srcAlbum)
+ {
+ DWarning() << "Could not find source album of drag"
+ << endl;
+ return;
+ }
+
+ int id = 0;
+ char keys_return[32];
+ XQueryKeymap(x11Display(), keys_return);
+ int key_1 = XKeysymToKeycode(x11Display(), 0xFFE3);
+ int key_2 = XKeysymToKeycode(x11Display(), 0xFFE4);
+
+ if(srcAlbum == destAlbum)
+ {
+ // Setting the dropped image as the album thumbnail
+ // If the ctrl key is pressed, when dropping the image, the
+ // thumbnail is set without a popup menu
+ if (((keys_return[key_1 / 8]) && (1 << (key_1 % 8))) ||
+ ((keys_return[key_2 / 8]) && (1 << (key_2 % 8))))
+ {
+ id = 12;
+ }
+ else
+ {
+ KPopupMenu popMenu(this);
+ popMenu.insertTitle(SmallIcon("digikam"), i18n("Tags"));
+ popMenu.insertItem(i18n("Set as Tag Thumbnail"), 12);
+ popMenu.insertSeparator(-1);
+ popMenu.insertItem( SmallIcon("cancel"), i18n("C&ancel") );
+
+ popMenu.setMouseTracking(true);
+ id = popMenu.exec(QCursor::pos());
+ }
+
+ if(id == 12)
+ {
+ QString errMsg;
+ AlbumManager::instance()->updateTAlbumIcon(destAlbum, QString(),
+ imageIDs.first(), errMsg);
+ }
+ return;
+ }
+
+ // If a ctrl key is pressed while dropping the drag object,
+ // the tag is assigned to the images without showing a
+ // popup menu.
+ if (((keys_return[key_1 / 8]) && (1 << (key_1 % 8))) ||
+ ((keys_return[key_2 / 8]) && (1 << (key_2 % 8))))
+ {
+ id = 10;
+ }
+ else
+ {
+ KPopupMenu popMenu(this);
+ popMenu.insertTitle(SmallIcon("digikam"), i18n("Tags"));
+ popMenu.insertItem( SmallIcon("tag"), i18n("Assign Tag '%1' to Items")
+ .arg(destAlbum->prettyURL()), 10) ;
+ popMenu.insertSeparator(-1);
+ popMenu.insertItem( SmallIcon("cancel"), i18n("C&ancel") );
+
+ popMenu.setMouseTracking(true);
+ id = popMenu.exec(QCursor::pos());
+ }
+
+ if (id == 10)
+ {
+ emit signalProgressBarMode(StatusProgressBar::ProgressBarMode,
+ i18n("Assign tag to images. Please wait..."));
+
+ AlbumLister::instance()->blockSignals(true);
+ AlbumManager::instance()->albumDB()->beginTransaction();
+ int i=0;
+ for (QValueList<int>::const_iterator it = imageIDs.begin();
+ it != imageIDs.end(); ++it)
+ {
+ // create temporary ImageInfo object
+ ImageInfo info(*it);
+
+ MetadataHub hub;
+ hub.load(&info);
+ hub.setTag(destAlbum, true);
+ hub.write(&info, MetadataHub::PartialWrite);
+ hub.write(info.filePath(), MetadataHub::FullWriteIfChanged);
+
+ emit signalProgressValue((int)((i++/(float)imageIDs.count())*100.0));
+ kapp->processEvents();
+ }
+ AlbumLister::instance()->blockSignals(false);
+ AlbumManager::instance()->albumDB()->commitTransaction();
+
+ ImageAttributesWatch::instance()->imagesChanged(destAlbum->id());
+
+ emit signalProgressBarMode(StatusProgressBar::TextMode, QString());
+ }
+ }
+}
+
+void TAlbumListView::refresh()
+{
+ QListViewItemIterator it(this);
+
+ while (it.current())
+ {
+ TAlbumCheckListItem* item = dynamic_cast<TAlbumCheckListItem*>(*it);
+ if (item)
+ item->refresh();
+ ++it;
+ }
+}
+
+void TAlbumListView::slotRefresh(const QMap<int, int>& tagsStatMap)
+{
+ QListViewItemIterator it(this);
+
+ while (it.current())
+ {
+ TAlbumCheckListItem* item = dynamic_cast<TAlbumCheckListItem*>(*it);
+ if (item)
+ {
+ if (item->album())
+ {
+ int id = item->id();
+ QMap<int, int>::const_iterator it2 = tagsStatMap.find(id);
+ if ( it2 != tagsStatMap.end() )
+ item->setCount(it2.data());
+ }
+ }
+ ++it;
+ }
+
+ refresh();
+}
+
+void TAlbumListView::loadViewState()
+{
+ KConfig *config = kapp->config();
+ config->setGroup(name());
+
+ int selectedItem = config->readNumEntry("LastSelectedItem", 0);
+
+ QValueList<int> openFolders;
+ if(config->hasKey("OpenFolders"))
+ {
+ openFolders = config->readIntListEntry("OpenFolders");
+ }
+
+ TAlbumCheckListItem *item = 0;
+ TAlbumCheckListItem *foundItem = 0;
+ QListViewItemIterator it(this->lastItem());
+
+ for( ; it.current(); --it)
+ {
+ item = dynamic_cast<TAlbumCheckListItem*>(it.current());
+ if(!item)
+ continue;
+
+ // Start the album root always open
+ if(openFolders.contains(item->id()) || item->id() == 0)
+ setOpen(item, true);
+ else
+ setOpen(item, false);
+
+ if(item->id() == selectedItem)
+ {
+ // Save the found selected item so that it can be made visible.
+ foundItem = item;
+ }
+ }
+
+ // Important note: this cannot be done inside the previous loop
+ // because opening folders prevents the visibility.
+ // Fixes bug #144815.
+ // (Looks a bit like a bug in Qt to me ...)
+ if (foundItem)
+ {
+ setSelected(foundItem, true);
+ ensureItemVisible(foundItem);
+ }
+}
+
+void TAlbumListView::saveViewState()
+{
+ KConfig *config = kapp->config();
+ config->setGroup(name());
+
+ TAlbumCheckListItem *item = dynamic_cast<TAlbumCheckListItem*>(selectedItem());
+ if(item)
+ config->writeEntry("LastSelectedItem", item->id());
+ else
+ config->writeEntry("LastSelectedItem", 0);
+
+ QValueList<int> openFolders;
+ QListViewItemIterator it(this);
+ for( ; it.current(); ++it)
+ {
+ item = dynamic_cast<TAlbumCheckListItem*>(it.current());
+ if(item && isOpen(item))
+ openFolders.push_back(item->id());
+ }
+ config->writeEntry("OpenFolders", openFolders);
+}
+
+} // NameSpace Digikam
diff --git a/digikam/libs/imageproperties/talbumlistview.h b/digikam/libs/imageproperties/talbumlistview.h
new file mode 100644
index 0000000..c5eac53
--- /dev/null
+++ b/digikam/libs/imageproperties/talbumlistview.h
@@ -0,0 +1,108 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2006-18-12
+ * Description : A list view to display digiKam Tags.
+ *
+ * Copyright (C) 2006-2009 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ * Copyright (C) 2009 by Andi Clemens <andi dot clemens at gmx dot net>
+ *
+ * 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 TALBUMLISTVIEW_H
+#define TALBUMLISTVIEW_H
+
+// Local includes.
+
+#include "digikam_export.h"
+#include "metadatahub.h"
+#include "folderitem.h"
+#include "folderview.h"
+
+class QDropEvent;
+class QMouseEvent;
+
+namespace Digikam
+{
+class TAlbum;
+
+class DIGIKAM_EXPORT TAlbumCheckListItem : public FolderCheckListItem
+{
+public:
+
+ TAlbumCheckListItem(QListView* parent, TAlbum* album);
+
+ TAlbumCheckListItem(QCheckListItem* parent, TAlbum* album);
+
+ void setStatus(MetadataHub::TagStatus status);
+ void refresh();
+ void setOpen(bool o);
+ TAlbum* album() const;
+ int id() const;
+ void setCount(int count);
+ int count();
+
+private :
+
+ void stateChange(bool val);
+
+private :
+
+ int m_count;
+
+ TAlbum *m_album;
+};
+
+// ------------------------------------------------------------------------
+
+class DIGIKAM_EXPORT TAlbumListView : public FolderView
+{
+ Q_OBJECT
+
+public:
+
+ TAlbumListView(QWidget* parent);
+ ~TAlbumListView();
+
+ void stateChanged(TAlbumCheckListItem *item);
+ void refresh();
+ void loadViewState();
+
+signals:
+
+ void signalProgressBarMode(int, const QString&);
+ void signalProgressValue(int);
+ void signalItemStateChanged(TAlbumCheckListItem *item);
+
+protected:
+
+ bool acceptDrop(const QDropEvent *e) const;
+ void contentsDropEvent(QDropEvent *e);
+
+ QDragObject* dragObject();
+
+private slots:
+
+ void slotRefresh(const QMap<int, int>&);
+
+private:
+
+ void saveViewState();
+};
+
+} // NameSpace Digikam
+
+#endif // TALBUMLISTVIEW_H