[kphotoalbum] 4.3-1
Rex Dieter
rdieter at fedoraproject.org
Wed Nov 28 21:18:11 UTC 2012
commit b989da79f6af63f2742fe35bc935e2458f25b078
Author: Rex Dieter <rdieter at math.unl.edu>
Date: Wed Nov 28 15:18:13 2012 -0600
4.3-1
- 4.3 final
- include experimental libkipi2 support
- patch out info/warnings wrt mplayer
- default to KGlobalSettings::picturesPath instead of hard-coded ~/Images
.gitignore | 2 +-
...e-generic-way-of-passing-date-time-argume.patch | 46 ++
kphotoalbum-4.3-mplayer_warning.patch | 57 ++
kphotoalbum-4.3-xdg_picturesPath.patch | 21 +
kphotoalbum-libkipi2.patch | 641 ++++++++++++++++++++
kphotoalbum.spec | 26 +-
sources | 2 +-
7 files changed, 790 insertions(+), 5 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index fb83ebd..43864f9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,2 @@
/kphotoalbum-4.2.tar.bz2
-/kphotoalbum-4.3-beta1.tar.bz2
+/kphotoalbum-4.3.tar.bz2
diff --git a/0003-KIPI-Use-the-generic-way-of-passing-date-time-argume.patch b/0003-KIPI-Use-the-generic-way-of-passing-date-time-argume.patch
new file mode 100644
index 0000000..a061732
--- /dev/null
+++ b/0003-KIPI-Use-the-generic-way-of-passing-date-time-argume.patch
@@ -0,0 +1,46 @@
+From 47c823cd56a8a346844d0f29d70f81290d4da109 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jan=20Kundr=C3=A1t?= <jkt at flaska.net>
+Date: Thu, 27 Sep 2012 23:22:19 +0200
+Subject: [PATCH 03/62] KIPI: Use the generic way of passing date/time
+ arguments to work with newer KIPI
+
+This is required in order to get the Plugins -> Images -> Adjust Time and Date
+plugin to work again. It used to work without these; that has probably changed
+now (and the setTime() etc methods are now marked as deprecated).
+---
+ Plugins/ImageInfo.cpp | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/Plugins/ImageInfo.cpp b/Plugins/ImageInfo.cpp
+index dbf9a59..0221539 100644
+--- a/Plugins/ImageInfo.cpp
++++ b/Plugins/ImageInfo.cpp
+@@ -81,6 +81,10 @@ QMap<QString,QVariant> Plugins::ImageInfo::attributes()
+ res.insert(QString::fromLatin1("positionPrecision"), QVariant(position.precision()));
+ }
+ }
++
++ res.insert(QLatin1String("date"), _info->date().start());
++ res.insert(QLatin1String("dateto"), _info->date().end());
++ res.insert(QLatin1String("isexactdate"), _info->date().start() == _info->date().end());
+ }
+
+ res.insert(QString::fromLatin1("name"), QFileInfo(_info->fileName().absolute()).baseName());
+@@ -143,6 +147,14 @@ void Plugins::ImageInfo::addAttributes( const QMap<QString,QVariant>& map )
+ qWarning("Geo coordinates incomplete. Need at least 'longitude' and 'latitude', optionally 'altitude' and 'positionPrecision'");
+ }
+ }
++
++ if (map.contains(QLatin1String("isexactdate")) && map.contains(QLatin1String("date"))) {
++ _info->setDate(DB::ImageDate(map[QLatin1String("date")].toDateTime()));
++ } else if (map.contains(QLatin1String("date")) && map.contains(QLatin1String("dateto"))) {
++ _info->setDate(DB::ImageDate(map[QLatin1String("date")].toDateTime(), map[QLatin1String("dateto")].toDateTime()));
++ } else if (map.contains(QLatin1String("date"))) {
++ _info->setDate(DB::ImageDate(map[QLatin1String("date")].toDateTime()));
++ }
+ MainWindow::DirtyIndicator::markDirty();
+ }
+ }
+--
+1.8.0
+
diff --git a/kphotoalbum-4.3-mplayer_warning.patch b/kphotoalbum-4.3-mplayer_warning.patch
new file mode 100644
index 0000000..12a262f
--- /dev/null
+++ b/kphotoalbum-4.3-mplayer_warning.patch
@@ -0,0 +1,57 @@
+diff -up kphotoalbum-4.3/MainWindow/FeatureDialog.cpp.mplayer_warning kphotoalbum-4.3/MainWindow/FeatureDialog.cpp
+--- kphotoalbum-4.3/MainWindow/FeatureDialog.cpp.mplayer_warning 2012-09-25 10:40:43.000000000 -0500
++++ kphotoalbum-4.3/MainWindow/FeatureDialog.cpp 2012-11-28 14:53:58.509642624 -0600
+@@ -97,12 +97,12 @@ FeatureDialog::FeatureDialog( QWidget* p
+ else
+ text += i18n("<p>Phonon is capable of playing movies of these mime types:<ul><li>%1</ul></p>", mimeTypes.join(QString::fromLatin1( "<li>" ) ) );
+
+- text += i18n("<h1><a name=\"videoPreview\">Video thumbnail support</a></h1>"
+- "<p>KPhotoAlbum uses <tt>mplayer</tt> to extract thumbnails from videos. These thumbnails are used to preview "
+- "videos in the thumbnail viewer.</p>"
+- "<p>If at all possible you should install the <b>mplayer2</b> package rather than the <b>mplayer</b> package, as it has important "
+- "improvements over the mplayer package. mplayer (in contrast to mplayer2) often has problems extracting the length "
+- "of videos and also often fails to extract the thumbnails used for cycling video thumbnails.");
++ //text += i18n("<h1><a name=\"videoPreview\">Video thumbnail support</a></h1>"
++ // "<p>KPhotoAlbum uses <tt>mplayer</tt> to extract thumbnails from videos. These thumbnails are used to preview "
++ // "videos in the thumbnail viewer.</p>"
++ // "<p>If at all possible you should install the <b>mplayer2</b> package rather than the <b>mplayer</b> package, as it has important "
++ // "improvements over the mplayer package. mplayer (in contrast to mplayer2) often has problems extracting the length "
++ // "of videos and also often fails to extract the thumbnails used for cycling video thumbnails.");
+
+ edit->setText( text );
+
+diff -up kphotoalbum-4.3/MainWindow/Window.cpp.mplayer_warning kphotoalbum-4.3/MainWindow/Window.cpp
+--- kphotoalbum-4.3/MainWindow/Window.cpp.mplayer_warning 2012-11-28 14:45:54.077418657 -0600
++++ kphotoalbum-4.3/MainWindow/Window.cpp 2012-11-28 14:57:49.069788142 -0600
+@@ -1733,20 +1733,20 @@ void MainWindow::Window::executeStartupA
+ void MainWindow::Window::checkIfMplayerIsInstalled()
+ {
+ if ( FeatureDialog::mplayerBinary().isNull() ) {
+- KMessageBox::error( this,
+- i18n("<p>Unable to find mplayer on the system</p>"
+- "<p>KPhotoAlbum needs mplayer to extract video thumbnails among other things. "
+- "Please install the mplayer2 package</p>") );
++ //KMessageBox::error( this,
++ // i18n("<p>Unable to find mplayer on the system</p>"
++ // "<p>KPhotoAlbum needs mplayer to extract video thumbnails among other things. "
++ // "Please install the mplayer2 package</p>") );
+ exit(-1);
+ }
+
+- if ( !FeatureDialog::isMplayer2() ) {
+- KMessageBox::information( this,
+- i18n("<p>You have mplayer installed on your system, but it is unfortunately not version 2. "
+- "mplayer2 is on most systems a separate package, please install that if at all possible, "
+- "as that version has much better support for extracting thumbnails from videos."),
+- i18n("mplayer is too old"), QString::fromLatin1("mplayerVersionTooOld"));
+- }
++ //if ( !FeatureDialog::isMplayer2() ) {
++ // KMessageBox::information( this,
++ // i18n("<p>You have mplayer installed on your system, but it is unfortunately not version 2. "
++ // "mplayer2 is on most systems a separate package, please install that if at all possible, "
++ // "as that version has much better support for extracting thumbnails from videos."),
++ // i18n("mplayer is too old"), QString::fromLatin1("mplayerVersionTooOld"));
++ //}
+ }
+
+ bool MainWindow::Window::anyVideosSelected() const
diff --git a/kphotoalbum-4.3-xdg_picturesPath.patch b/kphotoalbum-4.3-xdg_picturesPath.patch
new file mode 100644
index 0000000..6a931a2
--- /dev/null
+++ b/kphotoalbum-4.3-xdg_picturesPath.patch
@@ -0,0 +1,21 @@
+diff -up kphotoalbum-4.3/MainWindow/WelcomeDialog.cpp.xdg_Pictures kphotoalbum-4.3/MainWindow/WelcomeDialog.cpp
+--- kphotoalbum-4.3/MainWindow/WelcomeDialog.cpp.xdg_Pictures 2012-09-25 10:40:43.000000000 -0500
++++ kphotoalbum-4.3/MainWindow/WelcomeDialog.cpp 2012-11-28 15:09:35.061085929 -0600
+@@ -112,7 +112,7 @@ FileDialog::FileDialog( QWidget* parent
+ QLabel* label = new QLabel( i18n("<h1>KPhotoAlbum database creation</h1>"
+ "<p>You need to show where the photos and videos are for KPhotoAlbum to "
+ "find them. They all need to be under one root directory, for example "
+- "/home/user/Images. In this directory you can have as many subdirectories as you "
++ "/home/user/Pictures. In this directory you can have as many subdirectories as you "
+ "want, KPhotoAlbum will find them all for you.</p>"
+ "<p>Feel safe, KPhotoAlbum will not modify or edit any of your images, so you can "
+ "simply point KPhotoAlbum to the directory where you already have all your "
+@@ -128,7 +128,7 @@ FileDialog::FileDialog( QWidget* parent
+ lay2->addWidget( label );
+
+ _lineEdit = new KLineEdit( top );
+- _lineEdit->setText( QString::fromLatin1( "~/Images" ) );
++ _lineEdit->setText( KGlobalSettings::picturesPath() );
+ lay2->addWidget( _lineEdit );
+
+ QPushButton* button = new QPushButton( QString::fromLatin1("..."), top );
diff --git a/kphotoalbum-libkipi2.patch b/kphotoalbum-libkipi2.patch
new file mode 100644
index 0000000..2e8e514
--- /dev/null
+++ b/kphotoalbum-libkipi2.patch
@@ -0,0 +1,641 @@
+diff --git a/MainWindow/Window.cpp b/MainWindow/Window.cpp
+index 62e32c9..9ee4d8a 100644
+--- a/MainWindow/Window.cpp
++++ b/MainWindow/Window.cpp
+@@ -1401,11 +1401,19 @@ void MainWindow::Window::loadPlugins()
+
+ QStringList ignores;
+ ignores << QString::fromLatin1( "CommentsEditor" )
+- << QString::fromLatin1( "HelloWorld" );
++ << QString::fromLatin1( "HelloWorld" );
+
++#if KIPI_VERSION >= 0x020000
++ _pluginLoader = new KIPI::PluginLoader();
++ _pluginLoader->setIgnoredPluginsList( ignores );
++ _pluginLoader->setInterface( _pluginInterface );
++ connect( _pluginLoader, SIGNAL( replug() ), this, SLOT( plug() ) );
++ _pluginLoader->loadPlugins();
++#else
+ _pluginLoader = new KIPI::PluginLoader( ignores, _pluginInterface );
+ connect( _pluginLoader, SIGNAL( replug() ), this, SLOT( plug() ) );
+ _pluginLoader->loadPlugins();
++#endif
+
+ // Setup signals
+ connect( _thumbnailView, SIGNAL( selectionChanged(int) ), this, SLOT( slotSelectionChanged(int) ) );
+@@ -1778,3 +1786,4 @@ void MainWindow::Window::setHistogramVisibilty( bool visible ) const
+ }
+
+ #include "Window.moc"
++// vi:expandtab:tabstop=4 shiftwidth=4:
+diff --git a/MainWindow/Window.h b/MainWindow/Window.h
+index 788efb7..a16ec57 100644
+--- a/MainWindow/Window.h
++++ b/MainWindow/Window.h
+@@ -41,6 +41,7 @@ class KActionMenu;
+ #include <QPointer>
+ #include <config-kpa-kipi.h>
+ #ifdef HASKIPI
++# include <libkipi/version.h>
+ # include <libkipi/pluginloader.h>
+ #endif
+ #include "DB/FileNameList.h"
+diff --git a/Plugins/ImageInfo.cpp b/Plugins/ImageInfo.cpp
+index 0221539..d150aba 100644
+--- a/Plugins/ImageInfo.cpp
++++ b/Plugins/ImageInfo.cpp
+@@ -26,110 +26,214 @@
+ #include <QList>
+ #include "DB/CategoryCollection.h"
+ #include <QFileInfo>
++#include <QDebug>
+
+-Plugins::ImageInfo::ImageInfo( KIPI::Interface* interface, const KUrl& url )
+- : KIPI::ImageInfoShared( interface, url )
++#define KEXIV_ORIENTATION_UNSPECIFIED 0
++#define KEXIV_ORIENTATION_NORMAL 1
++#define KEXIV_ORIENTATION_HFLIP 2
++#define KEXIV_ORIENTATION_ROT_180 3
++#define KEXIV_ORIENTATION_VFLIP 4
++#define KEXIV_ORIENTATION_ROT_90_HFLIP 5
++#define KEXIV_ORIENTATION_ROT_90 6
++#define KEXIV_ORIENTATION_ROT_90_VFLIP 7
++#define KEXIV_ORIENTATION_ROT_270 8
++/**
++ * Convert a rotation in degrees to a KExiv2::ImageOrientation value.
++ */
++static int deg2KexivOrientation( int deg)
+ {
+- _info = DB::ImageDB::instance()->info( DB::FileName::fromAbsolutePath(_url.path()));
++ deg = (deg + 360) % 360;;
++ switch (deg)
++ {
++ case 0:
++ return KEXIV_ORIENTATION_NORMAL;
++ case 90:
++ return KEXIV_ORIENTATION_ROT_90;
++ case 180:
++ return KEXIV_ORIENTATION_ROT_180;
++ case 270:
++ return KEXIV_ORIENTATION_ROT_270;
++ default:
++ qWarning() << "Rotation of " << deg << "degrees can't be mapped to KExiv2::ImageOrientation value.";
++ return KEXIV_ORIENTATION_UNSPECIFIED;
++ }
+ }
+-
+-QString Plugins::ImageInfo::title()
++/**
++ * Convert a KExiv2::ImageOrientation value into a degrees angle.
++ */
++static int kexivOrientation2deg( int orient)
+ {
+- if ( _info )
+- return _info->label();
+- else
+- return QString();
++ switch (orient)
++ {
++ case KEXIV_ORIENTATION_NORMAL:
++ return 0;
++ case KEXIV_ORIENTATION_ROT_90:
++ return 90;
++ case KEXIV_ORIENTATION_ROT_180:
++ return 280;
++ case KEXIV_ORIENTATION_ROT_270:
++ return 270;
++ default:
++ qWarning() << "KExiv2::ImageOrientation value " << orient << " not a pure rotation. Discarding orientation info.";
++ return 0;
++ }
+ }
+
+-QString Plugins::ImageInfo::description()
++Plugins::ImageInfo::ImageInfo( KIPI::Interface* interface, const KUrl& url )
++ : KIPI::ImageInfoShared( interface, url )
+ {
+- if ( _info )
+- return _info->description();
+- else
+- return QString();
++ _info = DB::ImageDB::instance()->info( DB::FileName::fromAbsolutePath(_url.path()));
+ }
+
+ QMap<QString,QVariant> Plugins::ImageInfo::attributes()
+ {
++ Q_ASSERT( _info );
+ QMap<QString,QVariant> res;
+
++ res.insert(QString::fromLatin1("name"), QFileInfo(_info->fileName().absolute()).baseName());
++ res.insert(QString::fromLatin1("comment"), _info->description());
++
++ res.insert(QLatin1String("date"), _info->date().start());
++ res.insert(QLatin1String("dateto"), _info->date().end());
++ res.insert(QLatin1String("isexactdate"), _info->date().start() == _info->date().end());
++
++ res.insert(QString::fromLatin1("orientation"), deg2KexivOrientation(_info->angle()) );
++ res.insert(QString::fromLatin1("angle"), deg2KexivOrientation(_info->angle()) ); // for compatibility with older versions. Now called orientation.
++
++ res.insert(QString::fromLatin1("title"), _info->label());
++
++ res.insert(QString::fromLatin1("rating"), _info->rating());
++
++ // not supported:
++ //res.insert(QString::fromLatin1("colorlabel"), xxx );
++ //res.insert(QString::fromLatin1("picklabel"), xxx );
++
++ DB::GpsCoordinates position = _info->geoPosition();
++ if (!position.isNull()) {
++ res.insert(QString::fromLatin1("longitude"), QVariant(position.longitude()));
++ res.insert(QString::fromLatin1("latitude"), QVariant(position.latitude()));
++ res.insert(QString::fromLatin1("altitude"), QVariant(position.altitude()));
++ if (position.precision() != DB::GpsCoordinates::NoPrecisionData) {
++ // XXX: attribute not mentioned in libkipi/imageinfo.h -> is this supported?
++ res.insert(QString::fromLatin1("positionPrecision"), QVariant(position.precision()));
++ }
++ }
++
+ // Flickr plug-in expects the item tags, so we better give them.
+ QString text;
+ QList<DB::CategoryPtr> categories = DB::ImageDB::instance()->categoryCollection()->categories();
+ QStringList tags;
+- for( QList<DB::CategoryPtr>::Iterator categoryIt = categories.begin(); categoryIt != categories.end(); ++categoryIt ) {
++ QStringList tagspath;
++ const QLatin1String sep ("/");
++ for( QList<DB::CategoryPtr>::Iterator categoryIt = categories.begin(); categoryIt != categories.end(); ++categoryIt ) {
+ QString categoryName = (*categoryIt)->name();
+- if ( categoryName == QString::fromLatin1( "Folder" ) || categoryName == QString::fromLatin1( "Media Type" ) || categoryName == QString::fromLatin1( "Tokens" ) )
++ if ( (*categoryIt)->isSpecialCategory() )
+ continue;
+- if ( (*categoryIt)->doShow() ) {
++ // I don't know why any categories except the above should be excluded
++ //if ( (*categoryIt)->doShow() ) {
+ Utilities::StringSet items = _info->itemsOfCategory( categoryName );
+ for( Utilities::StringSet::Iterator it = items.begin(); it != items.end(); ++it ) {
+ tags.append( *it );
++ // digikam compatible tag path:
++ // note: this produces a semi-flattened hierarchy.
++ // instead of "Places/France/Paris" this will yield "Places/Paris"
++ tagspath.append( categoryName + sep + (*it) );
+ }
+- }
++ //}
+ }
++ res.insert(QString::fromLatin1( "tagspath" ), tagspath );
+ res.insert(QString::fromLatin1( "keywords" ), tags );
+- res.insert(QString::fromLatin1( "tags" ), tags );
+- res.insert(QString::fromLatin1( "tagspath" ), tags );
+- if ( _info ) {
+- DB::GpsCoordinates position = _info->geoPosition();
+- if (!position.isNull()) {
+- res.insert(QString::fromLatin1("longitude"), QVariant(position.longitude()));
+- res.insert(QString::fromLatin1("latitude"), QVariant(position.latitude()));
+- res.insert(QString::fromLatin1("altitude"), QVariant(position.altitude()));
+- if (position.precision() != DB::GpsCoordinates::NoPrecisionData) {
+- res.insert(QString::fromLatin1("positionPrecision"), QVariant(position.precision()));
+- }
+- }
++ res.insert(QString::fromLatin1( "tags" ), tags ); // for compatibility with older versions. Now called keywords.
+
+- res.insert(QLatin1String("date"), _info->date().start());
+- res.insert(QLatin1String("dateto"), _info->date().end());
+- res.insert(QLatin1String("isexactdate"), _info->date().start() == _info->date().end());
+- }
++ // TODO: implement this:
++ //res.insert(QString::fromLatin1( "filesize" ), xxx );
+
+- res.insert(QString::fromLatin1("name"), QFileInfo(_info->fileName().absolute()).baseName());
++ // not supported:
++ //res.insert(QString::fromLatin1( "creators" ), xxx );
++ //res.insert(QString::fromLatin1( "credit" ), xxx );
++ //res.insert(QString::fromLatin1( "rights" ), xxx );
++ //res.insert(QString::fromLatin1( "source" ), xxx );
+
+ return res;
+ }
+
+-void Plugins::ImageInfo::setTitle( const QString& name )
+-{
+- if ( _info ) {
+- _info->setLabel( name );
+- MainWindow::DirtyIndicator::markDirty();
+- }
+-}
+-
+-void Plugins::ImageInfo::setDescription( const QString& description )
+-{
+- if ( _info ) {
+- _info->setDescription( description );
+- MainWindow::DirtyIndicator::markDirty();
+- }
+-}
+-
+ void Plugins::ImageInfo::clearAttributes()
+ {
+ if( _info ) {
+- _info->clearAllCategoryInfo();
+- // TODO I think it is reasonable to keep the gps position anyway, isn't it?
+- MainWindow::DirtyIndicator::markDirty();
++ // official behaviour is to delete all officially supported attributes:
++ QStringList attr;
++ attr.append( QString::fromLatin1("comment") );
++ attr.append( QString::fromLatin1("date") );
++ attr.append( QString::fromLatin1("title") );
++ attr.append( QString::fromLatin1("orientation") );
++ attr.append( QString::fromLatin1("tagspath") );
++ attr.append( QString::fromLatin1("rating") );
++ attr.append( QString::fromLatin1("colorlabel") );
++ attr.append( QString::fromLatin1("picklabel") );
++ attr.append( QString::fromLatin1("gpslocation") );
++ attr.append( QString::fromLatin1("copyrights") );
++ delAttributes(attr);
+ }
+ }
+
+-void Plugins::ImageInfo::addAttributes( const QMap<QString,QVariant>& map )
++void Plugins::ImageInfo::addAttributes( const QMap<QString,QVariant>& amap )
+ {
+- if ( _info ) {
+- for( QMap<QString,QVariant>::ConstIterator it = map.begin(); it != map.end(); ++it ) {
+- QStringList list = it.value().toStringList();
+- if (isCategoryAttribute(it.key())) {
+- _info->addCategoryInfo( it.key(), list.toSet() );
+- }
++ if ( _info && ! amap.empty() ) {
++ QMap<QString,QVariant> map = amap;
++ if ( map.contains(QLatin1String("name")) )
++ {
++ // plugin renamed the item
++ // TODO: implement this
++ qWarning("File renaming by kipi-plugin not supported.");
++ //map.remove(QLatin1String("name"));
++ }
++ if ( map.contains(QLatin1String("comment")) )
++ {
++ // is it save to do that? digikam seems to allow multiple comments on a single image
++ // if a plugin assumes that it is adding a comment, not setting it, things might go badly...
++ _info->setDescription( map[QLatin1String("comment")].toString() );
++ map.remove(QLatin1String("comment"));
++ }
++ // note: this probably won't work as expected because according to the spec,
++ // "isexactdate" is supposed to be readonly and therefore never set here:
++ if (map.contains(QLatin1String("isexactdate")) && map.contains(QLatin1String("date"))) {
++ _info->setDate(DB::ImageDate(map[QLatin1String("date")].toDateTime()));
++ map.remove(QLatin1String("date"));
++ } else if (map.contains(QLatin1String("date")) && map.contains(QLatin1String("dateto"))) {
++ _info->setDate(DB::ImageDate(map[QLatin1String("date")].toDateTime(), map[QLatin1String("dateto")].toDateTime()));
++ map.remove(QLatin1String("date"));
++ map.remove(QLatin1String("dateto"));
++ } else if (map.contains(QLatin1String("date"))) {
++ _info->setDate(DB::ImageDate(map[QLatin1String("date")].toDateTime()));
++ map.remove(QLatin1String("date"));
++ }
++ if ( map.contains(QLatin1String("angle")) )
++ {
++ qWarning("Kipi-plugin uses deprecated attribute \"angle\".");
++ _info->setAngle( kexivOrientation2deg( map[QLatin1String("angle")].toInt() ) );
++ map.remove(QLatin1String("angle"));
++ }
++ if ( map.contains(QLatin1String("orientation")) )
++ {
++ _info->setAngle( kexivOrientation2deg( map[QLatin1String("orientation")].toInt() ) );
++ map.remove(QLatin1String("orientation"));
+ }
++ if ( map.contains(QLatin1String("title")) )
++ {
++ _info->setLabel( map[QLatin1String("title")].toString() );
++ map.remove(QLatin1String("title"));
++ }
++ if ( map.contains(QLatin1String("rating")) )
++ {
++ _info->setRating( map[QLatin1String("rating")].toInt() );
++ map.remove(QLatin1String("rating"));
++ }
++ // I don't know whether we should loosen the warning on this one:
++ // after all, a Plugin might update one component of the gps data only...
+ if (map.contains(QLatin1String("longitude")) ||
+- map.contains(QLatin1String("latitude")) ||
+- map.contains(QLatin1String("altitude")) ||
+- map.contains(QLatin1String("positionPrecision"))) {
++ map.contains(QLatin1String("latitude")) ||
++ map.contains(QLatin1String("altitude")) ||
++ map.contains(QLatin1String("positionPrecision"))) {
+ if (map.contains(QLatin1String("longitude")) && map.contains(QLatin1String("latitude"))) {
+ double altitude = 0;
+ QVariant var = map[QLatin1String("altitude")];
+@@ -143,38 +247,167 @@ void Plugins::ImageInfo::addAttributes( const QMap<QString,QVariant>& map )
+ }
+ DB::GpsCoordinates coord(map[QLatin1String("longitude")].toDouble(), map[QLatin1String("latitude")].toDouble(), altitude, precision);
+ _info->setGeoPosition(coord);
++ map.remove(QLatin1String("longitude"));
++ map.remove(QLatin1String("latitude"));
++ map.remove(QLatin1String("altitude"));
++ map.remove(QLatin1String("positionPrecision"));
+ } else {
+ qWarning("Geo coordinates incomplete. Need at least 'longitude' and 'latitude', optionally 'altitude' and 'positionPrecision'");
+ }
+ }
++ if ( map.contains(QLatin1String("tagspath")) )
++ {
++ const QStringList tagspaths = map[QLatin1String("tagspath")].toStringList();
++ const DB::CategoryCollection *categories = DB::ImageDB::instance()->categoryCollection();
++ Q_FOREACH( const QString &path, tagspaths )
++ {
++ QStringList tagpath = path.split( QLatin1String("/"), QString::SkipEmptyParts );
++ // first component is the category,
++ // last component is the tag.
++ // the components in between are currently ignored
++ // Note: maybe taggspaths with only one component or with unknown first component
++ // should be added to the "keywords"/"Events" category?
++ if ( tagpath.size() < 2 )
++ {
++ qWarning() << "Ignoring incompatible tag: " << path;
++ continue;
++ }
+
+- if (map.contains(QLatin1String("isexactdate")) && map.contains(QLatin1String("date"))) {
+- _info->setDate(DB::ImageDate(map[QLatin1String("date")].toDateTime()));
+- } else if (map.contains(QLatin1String("date")) && map.contains(QLatin1String("dateto"))) {
+- _info->setDate(DB::ImageDate(map[QLatin1String("date")].toDateTime(), map[QLatin1String("dateto")].toDateTime()));
+- } else if (map.contains(QLatin1String("date"))) {
+- _info->setDate(DB::ImageDate(map[QLatin1String("date")].toDateTime()));
++ const QString cat = tagpath.takeFirst();
++ if ( categories->categoryForName(cat).isNull() )
++ {
++ _info->addCategoryInfo( cat, tagpath.takeLast() );
++ } else {
++ qWarning() << "Unknown category: " << cat;
++ }
++ }
++ map.remove(QLatin1String("tagspath"));
+ }
++
++ // remove read-only keywords:
++ map.remove(QLatin1String("filesize"));
++ map.remove(QLatin1String("isexactdate"));
++ map.remove(QLatin1String("keywords"));
++ map.remove(QLatin1String("tags"));
++
++ // colorlabel
++ // picklabel
++ // creators
++ // credit
++ // rights
++ // source
++
+ MainWindow::DirtyIndicator::markDirty();
++ if ( ! map.isEmpty() )
++ {
++ qWarning() << "The following attributes are not (yet) supported by the KPhotoAlbum KIPI interface:" << map;
++ }
+ }
+ }
+
+-void Plugins::ImageInfo::delAttributes( const QStringList& delAttrs)
++void Plugins::ImageInfo::delAttributes( const QStringList& attrs)
+ {
+- if (_info) {
+- for (QStringList::const_iterator it = delAttrs.begin(); it != delAttrs.end(); ++it) {
+- if (isCategoryAttribute(*it)) {
+- _info->setCategoryInfo(*it, Utilities::StringSet());
+- }
++ if ( _info && ! attrs.empty() ) {
++ QStringList delAttrs = attrs;
++ if ( delAttrs.contains(QLatin1String("comment")))
++ {
++ _info->setDescription( QString() );
++ delAttrs.removeAll(QLatin1String("comment"));
+ }
+- if (delAttrs.contains(QLatin1String("tags"))) {
+- //TODO very probably a misunderstanding, isn't it?
+- qWarning("Ignoring 'remove all tags'");
++ // not supported: date
++ if ( delAttrs.contains(QLatin1String("orientation")) ||
++ delAttrs.contains(QLatin1String("angle")) )
++ {
++ _info->setAngle( 0 );
++ delAttrs.removeAll(QLatin1String("orientation"));
++ delAttrs.removeAll(QLatin1String("angle"));
+ }
+- if (delAttrs.contains(QLatin1String("longitude")) && delAttrs.contains(QLatin1String("latitude"))) {
++ if ( delAttrs.contains(QLatin1String("title")))
++ {
++ _info->setLabel( QString() );
++ delAttrs.removeAll(QLatin1String("title"));
++ }
++ // TODO:
++ // rating
++ // (colorlabel)
++ // (picklabel)
++ // copyrights
++ if ( delAttrs.contains(QLatin1String("tags")) ||
++ delAttrs.contains(QLatin1String("tagspath")))
++ {
++ _info->clearAllCategoryInfo();
++ delAttrs.removeAll(QLatin1String("tags"));
++ delAttrs.removeAll(QLatin1String("tagspath"));
++ }
++ if ( delAttrs.contains(QLatin1String("gpslocation")) )
++ {
+ //clear position:
+ _info->setGeoPosition(DB::GpsCoordinates());
++ delAttrs.removeAll(QLatin1String("gpslocation"));
++ }
++ MainWindow::DirtyIndicator::markDirty();
++ if ( ! delAttrs.isEmpty() )
++ {
++ qWarning() << "The following attributes are not (yet) supported by the KPhotoAlbum KIPI interface:" << delAttrs;
+ }
++ }
++}
++
++#if KIPI_VERSION >= 0x010200
++#define KIPI_IMAGEINFO_CONST_MODIFIER const
++#else
++#define KIPI_IMAGEINFO_CONST_MODIFIER
++#endif
++void Plugins::ImageInfo::cloneData( ImageInfoShared* KIPI_IMAGEINFO_CONST_MODIFIER other )
++{
++ ImageInfoShared::cloneData( other );
++ if ( _info ) {
++ Plugins::ImageInfo* inf = static_cast<Plugins::ImageInfo*>( other );
++ _info->setDate( inf->_info->date() );
++ MainWindow::DirtyIndicator::markDirty();
++ }
++}
++#undef KIPI_IMAGEINFO_CONST_MODIFIER
++
++
++#if KIPI_VERSION < 0x010500
++#if KIPI_VERSION >= 0x010300
++#define KIPI_IMAGEINFO_FILINAMEFUN_GETTER_NAME name
++#define KIPI_IMAGEINFO_FILINAMEFUN_SETTER_NAME setName
++#else
++#define KIPI_IMAGEINFO_FILINAMEFUN_GETTER_NAME title
++#define KIPI_IMAGEINFO_FILINAMEFUN_SETTER_NAME setTitle
++#endif
++QString Plugins::ImageInfo::KIPI_IMAGEINFO_FILINAMEFUN_GETTER_NAME()
++{
++ if ( _info )
++ return _info->label();
++ else
++ return QString();
++}
++
++void Plugins::ImageInfo::KIPI_IMAGEINFO_FILINAMEFUN_SETTER_NAME( const QString& name )
++{
++ if ( _info ) {
++ _info->setLabel( name );
++ MainWindow::DirtyIndicator::markDirty();
++ }
++}
++#undef KIPI_IMAGEINFO_FILINAMEFUN_GETTER_NAME
++#undef KIPI_IMAGEINFO_FILINAMEFUN_SETTER_NAME
++
++QString Plugins::ImageInfo::description()
++{
++ if ( _info )
++ return _info->description();
++ else
++ return QString();
++}
++
++void Plugins::ImageInfo::setDescription( const QString& description )
++{
++ if ( _info ) {
++ _info->setDescription( description );
+ MainWindow::DirtyIndicator::markDirty();
+ }
+ }
+@@ -229,16 +462,7 @@ void Plugins::ImageInfo::setTime( const QDateTime& time, KIPI::TimeSpec spec )
+ MainWindow::DirtyIndicator::markDirty();
+ }
+ }
+-
+-void Plugins::ImageInfo::cloneData( ImageInfoShared* other )
+-{
+- ImageInfoShared::cloneData( other );
+- if ( _info ) {
+- Plugins::ImageInfo* inf = static_cast<Plugins::ImageInfo*>( other );
+- _info->setDate( inf->_info->date() );
+- MainWindow::DirtyIndicator::markDirty();
+- }
+-}
++#endif // KIPI_VERSION < 0x010500
+
+ bool Plugins::ImageInfo::isPositionAttribute(const QString &key)
+ {
+@@ -251,3 +475,4 @@ bool Plugins::ImageInfo::isCategoryAttribute(const QString &key)
+ }
+
+ #endif // KIPI
++// vi:expandtab:tabstop=4 shiftwidth=4:
+diff --git a/Plugins/ImageInfo.h b/Plugins/ImageInfo.h
+index 80886ca..0799d66 100644
+--- a/Plugins/ImageInfo.h
++++ b/Plugins/ImageInfo.h
+@@ -20,6 +20,7 @@
+ #define MYIMAGEINFO_H
+
+ #include <config-kpa-kipi.h>
++#include <libkipi/version.h>
+ #include <libkipi/imageinfoshared.h>
+ #include <kdemacros.h>
+ #include "DB/ImageInfoPtr.h"
+@@ -36,34 +37,50 @@ class KDE_EXPORT ImageInfo :public KIPI::ImageInfoShared
+ {
+ public:
+ ImageInfo( KIPI::Interface* interface, const KUrl& url );
+- virtual QString title();
+- virtual void setTitle( const QString& );
+
+- virtual QString description();
+- virtual void setDescription( const QString& );
++#if KIPI_VERSION < 0x010500
++ // kipi 1.5.0 uses attributes()/addAttributes() instead of these:
++#if KIPI_VERSION >= 0x010300
++ QString name();
++ void setName( const QString& );
++#else
++ // "title" means filename
++ QString title();
++ void setTitle( const QString& );
++#endif
+
+- virtual QMap<QString,QVariant> attributes();
+- virtual void clearAttributes();
+- virtual void addAttributes( const QMap<QString,QVariant>& );
+- virtual void delAttributes( const QStringList& );
++ QString description();
++ void setDescription( const QString& );
+
+- virtual int angle();
+- virtual void setAngle( int );
++ int angle();
++ void setAngle( int );
+
+- virtual QDateTime time( KIPI::TimeSpec what );
+- virtual void setTime( const QDateTime& time, KIPI::TimeSpec spec );
+- virtual bool isTimeExact();
++ QDateTime time( KIPI::TimeSpec what );
++ void setTime( const QDateTime& time, KIPI::TimeSpec spec );
++ bool isTimeExact();
++#endif // KIPI_VERSION < 0x010500
++
++ QMap<QString,QVariant> attributes();
++ void clearAttributes();
++ void addAttributes( const QMap<QString,QVariant>& );
++ void delAttributes( const QStringList& );
++
++#if KIPI_VERSION >= 0x010200
++ void cloneData( ImageInfoShared* const other);
++#else
++ void cloneData( ImageInfoShared* other);
++#endif // KIPI_VERSION >= 0x010200
+
+- virtual void cloneData( ImageInfoShared* other );
+
+ private:
+ DB::ImageInfoPtr _info;
+
+- virtual bool isPositionAttribute(const QString &key);
+- virtual bool isCategoryAttribute(const QString &key);
++ bool isPositionAttribute(const QString &key);
++ bool isCategoryAttribute(const QString &key);
+ };
+
+ }
+
+ #endif /* MYIMAGEINFO_H */
+
++// vi:expandtab:tabstop=4 shiftwidth=4:
+diff --git a/Plugins/Interface.cpp b/Plugins/Interface.cpp
+index b615602..e638dc0 100644
+--- a/Plugins/Interface.cpp
++++ b/Plugins/Interface.cpp
+@@ -88,7 +88,9 @@ int Plugins::Interface::features() const
+ KIPI::ImagesHasTime |
+ KIPI::HostSupportsDateRanges |
+ KIPI::HostAcceptNewImages |
+- KIPI::ImagesHasTitlesWritable;
++ KIPI::ImagesHasTitlesWritable |
++ KIPI::HostSupportsTags |
++ KIPI::HostSupportsRating;
+ }
+
+ bool Plugins::Interface::addImage( const KUrl& url, QString& errmsg )
+diff --git a/Settings/PluginsPage.cpp b/Settings/PluginsPage.cpp
+index 09efa3c..56eb26b 100644
+--- a/Settings/PluginsPage.cpp
++++ b/Settings/PluginsPage.cpp
+@@ -22,6 +22,10 @@
+ #include <MainWindow/Window.h>
+ #include <config-kpa-kipi.h>
+ #ifdef HASKIPI
++# include <libkipi/version.h>
++#if KIPI_VERSION >= 0x020000
++# include <libkipi/configwidget.h>
++#endif
+ # include <libkipi/pluginloader.h>
+ #endif
+
diff --git a/kphotoalbum.spec b/kphotoalbum.spec
index e84d696..b449b21 100644
--- a/kphotoalbum.spec
+++ b/kphotoalbum.spec
@@ -1,17 +1,25 @@
-%define pre beta1
-
Summary: KDE Photo Album
Name: kphotoalbum
Version: 4.3
-Release: 0.1.%{pre}%{?dist}
+Release: 1%{?dist}
License: GPLv2+
URL: http://kphotoalbum.org/
Source0: http://download.kde.org/%{?pre:un}stable/kphotoalbum/%{version}%{?pre:-%{pre}}/src/kphotoalbum-%{version}%{?pre:-%{pre}}.tar.bz2
+## upstreamable patches
+# disable mention of mplayer (which we can't ship), and needless scary warnings
+Patch50: kphotoalbum-4.3-mplayer_warning.patch
+# default to xdg picturesPath instead of ~/Images
+Patch51: kphotoalbum-4.3-xdg_picturesPath.patch
+
## upstream patches
+# needed for followup libkipi2 patch support
+Patch103: 0003-KIPI-Use-the-generic-way-of-passing-date-time-argume.patch
+# from https://github.com/jzarl/kphotoalbum/tree/kipi
+Patch150: kphotoalbum-libkipi2.patch
BuildRequires: desktop-file-utils
BuildRequires: gettext
@@ -36,6 +44,12 @@ A photo album tool. Focuses on three key points:
%prep
%setup -q -n %{name}-%{version}%{?pre:-%{pre}}
+%patch50 -p1 -b .mplayer_warning
+%patch51 -p1 -b .xdg_picturesPath
+# apply these conditionally? meh. -- rex
+%patch103 -p1 -b .0003
+%patch150 -p1 -b .libkipi2
+
%build
mkdir -p %{_target_platform}
@@ -87,6 +101,12 @@ update-desktop-database -q &> /dev/null
%changelog
+* Wed Nov 28 2012 Rex Dieter <rdieter at fedoraproject.org> - 4.3-1
+- 4.3 final
+- include experimental libkipi2 support
+- patch out info/warnings wrt mplayer
+- default to KGlobalSettings::picturesPath instead of hard-coded ~/Images
+
* Fri Sep 21 2012 Rex Dieter <rdieter at fedoraproject.org> 4.3-0.1.beta1
- kphotoalbum-4.3-beta1
diff --git a/sources b/sources
index 9ab9006..01c5817 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-fe177224e1b45f9597d64c5105019255 kphotoalbum-4.3-beta1.tar.bz2
+09b5ba7d44ee7426802b233454927b8f kphotoalbum-4.3.tar.bz2
More information about the scm-commits
mailing list