]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Provide a KMetaDataModel for KMetaDataWidget.
authorPeter Penz <peter.penz19@gmail.com>
Sat, 13 Mar 2010 13:38:40 +0000 (13:38 +0000)
committerPeter Penz <peter.penz19@gmail.com>
Sat, 13 Mar 2010 13:38:40 +0000 (13:38 +0000)
This allows to extend the model with custom meta data (might e. g. be useful for Gwenview).

svn path=/trunk/KDE/kdebase/apps/; revision=1102749

src/CMakeLists.txt
src/panels/information/informationpanelcontent.cpp
src/panels/information/kloadmetadatathread.cpp
src/panels/information/kloadmetadatathread_p.h
src/panels/information/kmetadatamodel.cpp [new file with mode: 0644]
src/panels/information/kmetadatamodel.h [new file with mode: 0644]
src/panels/information/kmetadatawidget.cpp
src/panels/information/kmetadatawidget.h
src/panels/information/knfotranslator.cpp
src/panels/information/knfotranslator_p.h
src/tooltips/tooltipmanager.cpp

index f8dd2349fbe3b8f205ce608c0ddaf5f712e38ee5..a8e9c89c0e0c7c77e0dec71bb86e5849407264a4 100644 (file)
@@ -43,6 +43,7 @@ set(dolphinprivate_LIB_SRCS
     settings/viewpropertiesdialog.cpp
     settings/viewpropsprogressinfo.cpp
     panels/information/kmetadataconfigurationdialog.cpp
     settings/viewpropertiesdialog.cpp
     settings/viewpropsprogressinfo.cpp
     panels/information/kmetadataconfigurationdialog.cpp
+    panels/information/kmetadatamodel.cpp
     panels/information/kmetadatawidget.cpp
     panels/information/knfotranslator.cpp
     tooltips/ktooltip.cpp
     panels/information/kmetadatawidget.cpp
     panels/information/knfotranslator.cpp
     tooltips/ktooltip.cpp
@@ -126,6 +127,7 @@ set(dolphin_SRCS
     panels/information/informationpanel.cpp
     panels/information/informationpanelcontent.cpp
     panels/information/kmetadataconfigurationdialog.cpp
     panels/information/informationpanel.cpp
     panels/information/informationpanelcontent.cpp
     panels/information/kmetadataconfigurationdialog.cpp
+    panels/information/kmetadatamodel.cpp
     panels/information/kmetadatawidget.cpp
     panels/information/knfotranslator.cpp
     panels/information/phononwidget.cpp
     panels/information/kmetadatawidget.cpp
     panels/information/knfotranslator.cpp
     panels/information/phononwidget.cpp
@@ -249,6 +251,7 @@ set(kcm_dolphinservices_PART_SRCS
 set(kcm_dolphingeneral_PART_SRCS
     kcm/kcmdolphingeneral.cpp
     panels/information/kmetadataconfigurationdialog.cpp
 set(kcm_dolphingeneral_PART_SRCS
     kcm/kcmdolphingeneral.cpp
     panels/information/kmetadataconfigurationdialog.cpp
+    panels/information/kmetadatamodel.cpp
     panels/information/kmetadatawidget.cpp
     panels/information/knfotranslator.cpp
     settings/behaviorsettingspage.cpp
     panels/information/kmetadatawidget.cpp
     panels/information/knfotranslator.cpp
     settings/behaviorsettingspage.cpp
index 1164a5591c001a4dcb08edcb13f57f59d7111f7a..87294bfc1e86f88b5f3f5be6a2811310ad599930 100644 (file)
@@ -46,6 +46,7 @@
 
 #include "dolphin_informationpanelsettings.h"
 #include "settings/dolphinsettings.h"
 
 #include "dolphin_informationpanelsettings.h"
 #include "settings/dolphinsettings.h"
+#include "kmetadatamodel.h"
 #include "kmetadatawidget.h"
 #include "kmetadataconfigurationdialog.h"
 #include "phononwidget.h"
 #include "kmetadatawidget.h"
 #include "kmetadataconfigurationdialog.h"
 #include "phononwidget.h"
@@ -102,6 +103,7 @@ InformationPanelContent::InformationPanelContent(QWidget* parent) :
     m_preview->setVisible(showPreview);
 
     m_metaDataWidget = new KMetaDataWidget(parent);
     m_preview->setVisible(showPreview);
 
     m_metaDataWidget = new KMetaDataWidget(parent);
+    m_metaDataWidget->setModel(new KMetaDataModel(this));
     m_metaDataWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum);
     connect(m_metaDataWidget, SIGNAL(urlActivated(KUrl)), this, SIGNAL(urlActivated(KUrl)));
 
     m_metaDataWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum);
     connect(m_metaDataWidget, SIGNAL(urlActivated(KUrl)), this, SIGNAL(urlActivated(KUrl)));
 
index edd3995e20897ca1ffe9856a801e6ad766aebec8..ba4ebeda55ee4f121bc6341282c2aca4a6be9bdb 100644 (file)
@@ -1,5 +1,5 @@
 /*****************************************************************************
 /*****************************************************************************
- * Copyright (C) 2009 by Peter Penz <peter.penz@gmx.at>                      *
+ * Copyright (C) 2009-2010 by Peter Penz <peter.penz@gmx.at>                 *
  * Copyright (C) 2009 by Sebastian Trueg <trueg@kde.org>                     *
  *                                                                           *
  * This library is free software; you can redistribute it and/or             *
  * Copyright (C) 2009 by Sebastian Trueg <trueg@kde.org>                     *
  *                                                                           *
  * This library is free software; you can redistribute it and/or             *
 #include <kfilemetainfoitem.h>
 #include <kglobal.h>
 #include <klocale.h>
 #include <kfilemetainfoitem.h>
 #include <kglobal.h>
 #include <klocale.h>
-#include "knfotranslator_p.h"
+#include "kmetadatamodel.h"
 #include <kprotocolinfo.h>
 
 #include <nepomuk/resource.h>
 #include <kprotocolinfo.h>
 
 #include <nepomuk/resource.h>
+#include <nepomuk/resourcemanager.h>
 
 
-KLoadMetaDataThread::KLoadMetaDataThread() :
-    m_rating(0),
-    m_comment(),
-    m_tags(),
-    m_items(),
-    m_files(),
+KLoadMetaDataThread::KLoadMetaDataThread(KMetaDataModel* model) :
+    m_model(model),
+    m_data(),
     m_urls(),
     m_canceled(false)
 {
     m_urls(),
     m_canceled(false)
 {
+    Q_ASSERT(model != 0);
 }
 
 KLoadMetaDataThread::~KLoadMetaDataThread()
 }
 
 KLoadMetaDataThread::~KLoadMetaDataThread()
@@ -52,6 +51,11 @@ void KLoadMetaDataThread::load(const KUrl::List& urls)
     start();
 }
 
     start();
 }
 
+QMap<KUrl, Nepomuk::Variant> KLoadMetaDataThread::data() const
+{
+    return m_data;
+}
+
 void KLoadMetaDataThread::cancel()
 {
     // Setting m_canceled to true will cancel KLoadMetaDataThread::run()
 void KLoadMetaDataThread::cancel()
 {
     // Setting m_canceled to true will cancel KLoadMetaDataThread::run()
@@ -79,6 +83,10 @@ void KLoadMetaDataThread::run()
     KConfig config("kmetainformationrc", KConfig::NoGlobals);
     KConfigGroup settings = config.group("Show");
 
     KConfig config("kmetainformationrc", KConfig::NoGlobals);
     KConfigGroup settings = config.group("Show");
 
+    unsigned int rating = 0;
+    QString comment;
+    QList<Nepomuk::Tag> tags;
+
     bool first = true;
     foreach (const KUrl& url, m_urls) {
         if (m_canceled) {
     bool first = true;
     foreach (const KUrl& url, m_urls) {
         if (m_canceled) {
@@ -90,27 +98,24 @@ void KLoadMetaDataThread::run()
             continue;
         }
 
             continue;
         }
 
-        m_files.insert(url, file);
-
-        if (!first && (m_rating != file.rating())) {
-            m_rating = 0; // reset rating
+        if (!first && (rating != file.rating())) {
+            rating = 0; // reset rating
         } else if (first) {
         } else if (first) {
-            m_rating = file.rating();
+            rating = file.rating();
         }
 
         }
 
-        if (!first && (m_comment != file.description())) {
-            m_comment.clear(); // reset comment
+        if (!first && (comment != file.description())) {
+            comment.clear(); // reset comment
         } else if (first) {
         } else if (first) {
-            m_comment = file.description();
+            comment = file.description();
         }
 
         }
 
-        if (!first && (m_tags != file.tags())) {
-            m_tags.clear(); // reset tags
+        if (!first && (tags != file.tags())) {
+            tags.clear(); // reset tags
         } else if (first) {
         } else if (first) {
-            m_tags = file.tags();
+            tags = file.tags();
         }
 
         }
 
-        const KNfoTranslator& nfo = KNfoTranslator::instance();
         if (first && (m_urls.count() == 1)) {
             // get cached meta data by checking the indexed files
             QHash<QUrl, Nepomuk::Variant> variants = file.properties();
         if (first && (m_urls.count() == 1)) {
             // get cached meta data by checking the indexed files
             QHash<QUrl, Nepomuk::Variant> variants = file.properties();
@@ -119,11 +124,7 @@ void KLoadMetaDataThread::run()
                 Nepomuk::Types::Property prop(it.key());
                 const QString uriString = prop.uri().toString();
                 if (settings.readEntry(uriString, true)) {
                 Nepomuk::Types::Property prop(it.key());
                 const QString uriString = prop.uri().toString();
                 if (settings.readEntry(uriString, true)) {
-                    Item item;
-                    item.name = uriString;
-                    item.label = nfo.translation(prop.uri());
-                    item.value = formatValue(it.value());
-                    m_items.append(item);
+                    m_data.insert(uriString, formatValue(it.value()));
                 }
                 ++it;
             }
                 }
                 ++it;
             }
@@ -136,11 +137,8 @@ void KLoadMetaDataThread::run()
                 foreach (const KFileMetaInfoItem& metaInfoItem, metaInfoItems) {
                     const QString uriString = metaInfoItem.name();
                     if (settings.readEntry(uriString, true)) {
                 foreach (const KFileMetaInfoItem& metaInfoItem, metaInfoItems) {
                     const QString uriString = metaInfoItem.name();
                     if (settings.readEntry(uriString, true)) {
-                        Item item;
-                        item.name = uriString;
-                        item.label = nfo.translation(metaInfoItem.name());
-                        item.value = metaInfoItem.value().toString();
-                        m_items.append(item);
+                        const Nepomuk::Variant value(metaInfoItem.value());
+                        m_data.insert(uriString, formatValue(value));
                     }
                 }
             }
                     }
                 }
             }
@@ -148,31 +146,20 @@ void KLoadMetaDataThread::run()
 
         first = false;
     }
 
         first = false;
     }
-}
 
 
-int KLoadMetaDataThread::rating() const
-{
-    return m_rating;
-}
+    const bool isNepomukActivated = (Nepomuk::ResourceManager::instance()->init() == 0);
+    if (isNepomukActivated) {
+        m_data.insert(KUrl("kfileitem#rating"), rating);
+        m_data.insert(KUrl("kfileitem#comment"), comment);
 
 
-QString KLoadMetaDataThread::comment() const
-{
-    return m_comment;
-}
-
-QList<Nepomuk::Tag> KLoadMetaDataThread::tags() const
-{
-    return m_tags;
-}
-
-QList<KLoadMetaDataThread::Item> KLoadMetaDataThread::items() const
-{
-    return m_items;
-}
+        QList<Nepomuk::Variant> tagVariants;
+        foreach (const Nepomuk::Tag& tag, tags) {
+            tagVariants.append(Nepomuk::Variant(tag));
+        }
+        m_data.insert(KUrl("kfileitem#tags"), tagVariants);
+    }
 
 
-QMap<KUrl, Nepomuk::Resource> KLoadMetaDataThread::files() const
-{
-    return m_files;
+    m_data.unite(m_model->loadData());
 }
 
 void KLoadMetaDataThread::slotFinished()
 }
 
 void KLoadMetaDataThread::slotFinished()
index 6aba52ad31dee9f74aba5fba30942a9f7243a019..be03d262f30be69ba9455e9c447021d36431fae5 100644 (file)
@@ -1,5 +1,5 @@
 /*****************************************************************************
 /*****************************************************************************
- * Copyright (C) 2009 by Peter Penz <peter.penz@gmx.at>                      *
+ * Copyright (C) 2009-2010 by Peter Penz <peter.penz@gmx.at>                 *
  *                                                                           *
  * This library is free software; you can redistribute it and/or             *
  * modify it under the terms of the GNU Library General Public               *
  *                                                                           *
  * This library is free software; you can redistribute it and/or             *
  * modify it under the terms of the GNU Library General Public               *
@@ -28,6 +28,8 @@
 #include <QList>
 #include <QThread>
 
 #include <QList>
 #include <QThread>
 
+class KMetaDataModel;
+
 /**
  * Loads the meta data of files that are
  * required by the widget KMetaDataWidget.
 /**
  * Loads the meta data of files that are
  * required by the widget KMetaDataWidget.
@@ -37,30 +39,30 @@ class KLoadMetaDataThread : public QThread
     Q_OBJECT
 
 public:
     Q_OBJECT
 
 public:
-    struct Item
-    {
-        QString name;
-        QString label;
-        QString value;
-    };
-
-    KLoadMetaDataThread();
+    KLoadMetaDataThread(KMetaDataModel* model);
     virtual ~KLoadMetaDataThread();
 
     /**
      * Starts the thread and loads the meta data for
      * the files given by \p urls. After receiving
     virtual ~KLoadMetaDataThread();
 
     /**
      * Starts the thread and loads the meta data for
      * the files given by \p urls. After receiving
-     * the signal finished(), the methods
-     * rating(), comment(), tags(), metaInfoLabels(),
-     * metaInfoValues() and files() return valid data.
+     * the signal finished(), the method KLoadMetaDataThread::data()
+     * provides the loaded meta data.
      */
     void load(const KUrl::List& urls);
 
      */
     void load(const KUrl::List& urls);
 
+    /**
+     * Returns the meta data for the URLs given
+     * by KLoadMetaDataThread::load(). The method only provides
+     * valid results after the signal finished() has been
+     * emitted.
+     */
+    QMap<KUrl, Nepomuk::Variant> data() const;
+
     /**
      * Tells the thread that it should cancel as soon
      * as possible. It is undefined when the thread
      * gets cancelled. The signal finished() will emitted
     /**
      * Tells the thread that it should cancel as soon
      * as possible. It is undefined when the thread
      * gets cancelled. The signal finished() will emitted
-     * after the cancelling has been done.
+     * after the cancelling has been done.mergedIt
      */
     void cancel();
 
      */
     void cancel();
 
@@ -75,12 +77,6 @@ public:
     /** @see QThread::run() */
     virtual void run();
 
     /** @see QThread::run() */
     virtual void run();
 
-    int rating() const;
-    QString comment() const;
-    QList<Nepomuk::Tag> tags() const;
-    QList<Item> items() const;
-    QMap<KUrl, Nepomuk::Resource> files() const;
-
 private slots:
     void slotFinished();
 
 private slots:
     void slotFinished();
 
@@ -93,12 +89,8 @@ private:
     QString formatValue(const Nepomuk::Variant& value);
 
 private:
     QString formatValue(const Nepomuk::Variant& value);
 
 private:
-    unsigned int m_rating;
-    QString m_comment;
-    QList<Nepomuk::Tag> m_tags;
-    QList<Item> m_items;
-    QMap<KUrl, Nepomuk::Resource> m_files;
-
+    KMetaDataModel* m_model;
+    QMap<KUrl, Nepomuk::Variant> m_data;
     KUrl::List m_urls;
     bool m_canceled;
 };
     KUrl::List m_urls;
     bool m_canceled;
 };
diff --git a/src/panels/information/kmetadatamodel.cpp b/src/panels/information/kmetadatamodel.cpp
new file mode 100644 (file)
index 0000000..4521568
--- /dev/null
@@ -0,0 +1,142 @@
+/*****************************************************************************
+ * Copyright (C) 2010 by Peter Penz <peter.penz@gmx.at>                      *
+ *                                                                           *
+ * This library is free software; you can redistribute it and/or             *
+ * modify it under the terms of the GNU Library General Public               *
+ * License version 2 as published by the Free Software Foundation.           *
+ *                                                                           *
+ * This library 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         *
+ * Library General Public License for more details.                          *
+ *                                                                           *
+ * You should have received a copy of the GNU Library General Public License *
+ * along with this library; see the file COPYING.LIB.  If not, write to      *
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,      *
+ * Boston, MA 02110-1301, USA.                                               *
+ *****************************************************************************/
+
+#include "kmetadatamodel.h"
+
+#include <kfileitem.h>
+#include "kloadmetadatathread_p.h"
+#include <kurl.h>
+
+class KMetaDataModel::Private
+{
+
+public:
+    Private(KMetaDataModel* parent);
+    ~Private();
+
+    void slotLoadingFinished();
+
+    QList<KFileItem> m_fileItems;
+#ifdef HAVE_NEPOMUK
+    QMap<KUrl, Nepomuk::Variant> m_data;
+
+    QList<KLoadMetaDataThread*> m_metaDataThreads;
+    KLoadMetaDataThread* m_latestMetaDataThread;
+#endif
+
+private:
+    KMetaDataModel* const q;
+};
+
+KMetaDataModel::Private::Private(KMetaDataModel* parent) :
+    m_fileItems(),
+#ifdef HAVE_NEPOMUK
+    m_data(),
+    m_metaDataThreads(),
+    m_latestMetaDataThread(0),
+#endif
+    q(parent)
+{
+}
+
+KMetaDataModel::Private::~Private()
+{
+}
+
+KMetaDataModel::KMetaDataModel(QObject* parent) :
+    QObject(parent),
+    d(new Private(this))
+{
+}
+
+KMetaDataModel::~KMetaDataModel()
+{
+    delete d;
+}
+
+void KMetaDataModel::Private::slotLoadingFinished()
+{
+#ifdef HAVE_NEPOMUK
+    // The thread that has emitted the finished() signal
+    // will get deleted and removed from m_metaDataThreads.
+    const int threadsCount = m_metaDataThreads.count();
+    for (int i = 0; i < threadsCount; ++i) {
+        KLoadMetaDataThread* thread = m_metaDataThreads[i];
+        if (thread == q->sender()) {
+            m_metaDataThreads.removeAt(i);
+            if (thread != m_latestMetaDataThread) {
+                // Ignore data of older threads, as the data got
+                // obsolete by m_latestMetaDataThread.
+                thread->deleteLater();
+                return;
+            }
+        }
+    }
+
+    m_data = m_latestMetaDataThread->data();
+    m_latestMetaDataThread->deleteLater();
+#endif
+
+    emit q->loadingFinished();
+}
+
+void KMetaDataModel::setItems(const KFileItemList& items)
+{
+    d->m_fileItems = items;
+
+#ifdef HAVE_NEPOMUK
+    QList<KUrl> urls;
+    foreach (const KFileItem& item, items) {
+        const KUrl url = item.nepomukUri();
+        if (url.isValid()) {
+            urls.append(url);
+        }
+    }
+
+    // Cancel all threads that have not emitted a finished() signal.
+    // The deleting of those threads is done in slotLoadingFinished().
+    foreach (KLoadMetaDataThread* thread, d->m_metaDataThreads) {
+        thread->cancel();
+    }
+
+    // create a new thread that will provide the meeta data for the items
+    d->m_latestMetaDataThread = new KLoadMetaDataThread(this);
+    connect(d->m_latestMetaDataThread, SIGNAL(finished()), this, SLOT(slotLoadingFinished()));
+    d->m_latestMetaDataThread->load(urls);
+    d->m_metaDataThreads.append(d->m_latestMetaDataThread);
+#endif
+}
+
+KFileItemList KMetaDataModel::items() const
+{
+    return d->m_fileItems;
+}
+
+#ifdef HAVE_NEPOMUK
+QMap<KUrl, Nepomuk::Variant> KMetaDataModel::data() const
+{
+    return d->m_data;
+}
+
+QMap<KUrl, Nepomuk::Variant> KMetaDataModel::loadData() const
+{
+    return QMap<KUrl, Nepomuk::Variant>();
+}
+#endif
+
+#include "kmetadatamodel.moc"
diff --git a/src/panels/information/kmetadatamodel.h b/src/panels/information/kmetadatamodel.h
new file mode 100644 (file)
index 0000000..4b12563
--- /dev/null
@@ -0,0 +1,105 @@
+/*****************************************************************************
+ * Copyright (C) 2010 by Peter Penz <peter.penz@gmx.at>                      *
+ *                                                                           *
+ * This library is free software; you can redistribute it and/or             *
+ * modify it under the terms of the GNU Library General Public               *
+ * License version 2 as published by the Free Software Foundation.           *
+ *                                                                           *
+ * This library 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         *
+ * Library General Public License for more details.                          *
+ *                                                                           *
+ * You should have received a copy of the GNU Library General Public License *
+ * along with this library; see the file COPYING.LIB.  If not, write to      *
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,      *
+ * Boston, MA 02110-1301, USA.                                               *
+ *****************************************************************************/
+
+#ifndef KMETADATAMODEL_H
+#define KMETADATAMODEL_H
+
+#include <kurl.h>
+
+#include <QObject>
+#include <QMap>
+#include <QString>
+
+
+#include <config-nepomuk.h>
+#ifdef HAVE_NEPOMUK
+    #define DISABLE_NEPOMUK_LEGACY
+    #include <nepomuk/variant.h>
+#endif
+
+class KFileItemList;
+class KUrl;
+
+/**
+ * @brief Provides the data for the KMetaDataWidget.
+ *
+ * The default implementation provides all meta data
+ * that are available due to Strigi and Nepomuk. If custom
+ * meta data should be added, the method KMetaDataModel::loadData()
+ * must be overwritten.
+ *
+ * @see KMetaDataWidget
+ */
+class KMetaDataModel : public QObject
+{
+    Q_OBJECT
+
+public:
+    explicit KMetaDataModel(QObject* parent = 0);
+    virtual ~KMetaDataModel();
+
+    /**
+     * Sets the items, where the meta data should be
+     * requested. The loading of the meta data is done
+     * asynchronously. The signal loadingFinished() is
+     * emitted, as soon as the loading has been finished.
+     * The meta data can be retrieved by
+     * KMetaDataModel::data() afterwards.
+     */
+    void setItems(const KFileItemList& items);
+    KFileItemList items() const;
+
+#ifdef HAVE_NEPOMUK
+    /**
+     * @return Meta data for the items that have been set by
+     *         KMetaDataModel::setItems(). The method should
+     *         be invoked after the signal loadingFinished() has
+     *         been received (otherwise no data will be returned).
+     */
+    QMap<KUrl, Nepomuk::Variant> data() const;
+
+protected:
+    /**
+     * Implement this method if custom meta data should be retrieved
+     * and added to the list returned by KMetaDataModel::data().
+     * Use KMetaDataModel::items() to get the list of items, where
+     * the meta data should be requested. The method is invoked in
+     * a custom thread context, so that the user interface won't get
+     * blocked if the operation takes longer. The default implementation
+     * returns an empty list.
+     */
+    virtual QMap<KUrl, Nepomuk::Variant> loadData() const;
+#endif
+
+signals:
+    /**
+     * Is emitted after the loading triggered by KMetaDataModel::setItems()
+     * has been finished.
+     */
+    void loadingFinished();
+
+private:
+    class Private;
+    Private* d;
+
+    Q_PRIVATE_SLOT(d, void slotLoadingFinished())
+
+    friend class KLoadMetaDataThread; // invokes KMetaDataObject::loadData()
+};
+
+#endif
index b10e04f336c563c2f2264fb776f0d743545bc032..996238509c6b257e5cbe4a747b1c5418bff26524 100644 (file)
@@ -1,6 +1,6 @@
 /*****************************************************************************
  * Copyright (C) 2008 by Sebastian Trueg <trueg@kde.org>                     *
 /*****************************************************************************
  * Copyright (C) 2008 by Sebastian Trueg <trueg@kde.org>                     *
- * Copyright (C) 2009 by Peter Penz <peter.penz@gmx.at>                      *
+ * Copyright (C) 2009-2010 by Peter Penz <peter.penz@gmx.at>                 *
  *                                                                           *
  * This library is free software; you can redistribute it and/or             *
  * modify it under the terms of the GNU Library General Public               *
  *                                                                           *
  * This library is free software; you can redistribute it and/or             *
  * modify it under the terms of the GNU Library General Public               *
@@ -25,6 +25,8 @@
 #include <kglobalsettings.h>
 #include <kglobal.h>
 #include <klocale.h>
 #include <kglobalsettings.h>
 #include <kglobal.h>
 #include <klocale.h>
+#include "kmetadatamodel.h"
+#include "knfotranslator_p.h"
 
 #include <QEvent>
 #include <QFontMetrics>
 
 #include <QEvent>
 #include <QFontMetrics>
@@ -38,7 +40,6 @@
     #define DISABLE_NEPOMUK_LEGACY
 
     #include "kcommentwidget_p.h"
     #define DISABLE_NEPOMUK_LEGACY
 
     #include "kcommentwidget_p.h"
-    #include "kloadmetadatathread_p.h"
     #include "ktaggingwidget_p.h"
 
     #include <nepomuk/kratingwidget.h>
     #include "ktaggingwidget_p.h"
 
     #include <nepomuk/kratingwidget.h>
@@ -107,10 +108,7 @@ public:
      */
     void startChangeDataJob(KJob* job);
 
      */
     void startChangeDataJob(KJob* job);
 
-    /**
-     * Merges items like 'width' and 'height' as one item.
-     */
-    QList<KLoadMetaDataThread::Item> mergedItems(const QList<KLoadMetaDataThread::Item>& items);
+    QList<Nepomuk::Resource> resourceList() const;
 #endif
 
     bool m_sizeVisible;
 #endif
 
     bool m_sizeVisible;
@@ -121,6 +119,8 @@ public:
     QList<KFileItem> m_fileItems;
     QList<Row> m_rows;
 
     QList<KFileItem> m_fileItems;
     QList<Row> m_rows;
 
+    KMetaDataModel* m_model;
+
     QGridLayout* m_gridLayout;
 
     QLabel* m_typeInfo;
     QGridLayout* m_gridLayout;
 
     QLabel* m_typeInfo;
@@ -134,11 +134,6 @@ public:
     KRatingWidget* m_ratingWidget;
     KTaggingWidget* m_taggingWidget;
     KCommentWidget* m_commentWidget;
     KRatingWidget* m_ratingWidget;
     KTaggingWidget* m_taggingWidget;
     KCommentWidget* m_commentWidget;
-
-    QMap<KUrl, Nepomuk::Resource> m_files;
-
-    QList<KLoadMetaDataThread*> m_metaDataThreads;
-    KLoadMetaDataThread* m_latestMetaDataThread;
 #endif
 
 private:
 #endif
 
 private:
@@ -154,6 +149,7 @@ KMetaDataWidget::Private::Private(KMetaDataWidget* parent) :
                 PermissionsData | RatingData | TagsData | CommentData),
     m_fileItems(),
     m_rows(),
                 PermissionsData | RatingData | TagsData | CommentData),
     m_fileItems(),
     m_rows(),
+    m_model(0),
     m_gridLayout(0),
     m_typeInfo(0),
     m_sizeLabel(0),
     m_gridLayout(0),
     m_typeInfo(0),
     m_sizeLabel(0),
@@ -165,9 +161,6 @@ KMetaDataWidget::Private::Private(KMetaDataWidget* parent) :
     m_ratingWidget(0),
     m_taggingWidget(0),
     m_commentWidget(0),
     m_ratingWidget(0),
     m_taggingWidget(0),
     m_commentWidget(0),
-    m_files(),
-    m_metaDataThreads(),
-    m_latestMetaDataThread(0),
 #endif
     q(parent)
 {
 #endif
     q(parent)
 {
@@ -212,17 +205,6 @@ KMetaDataWidget::Private::Private(KMetaDataWidget* parent) :
 
 KMetaDataWidget::Private::~Private()
 {
 
 KMetaDataWidget::Private::~Private()
 {
-#ifdef HAVE_NEPOMUK
-    // If there are still threads that receive meta data, tell them
-    // that they should cancel as soon as possible. No waiting is done
-    // here, the threads delete themselves after finishing.
-    foreach (KLoadMetaDataThread* thread, m_metaDataThreads) {
-        disconnect(thread, SIGNAL(finished()), q, SLOT(slotLoadingFinished()));
-        thread->cancelAndDelete();
-    }
-    m_metaDataThreads.clear();
-    m_latestMetaDataThread = 0;
-#endif
 }
 
 void KMetaDataWidget::Private::addRow(QLabel* label, QWidget* infoWidget)
 }
 
 void KMetaDataWidget::Private::addRow(QLabel* label, QWidget* infoWidget)
@@ -311,6 +293,10 @@ void KMetaDataWidget::Private::initMetaInfoSettings()
             "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#model",
             "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#orientation",
             "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#whiteBalance",
             "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#model",
             "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#orientation",
             "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#whiteBalance",
+            "http://www.semanticdesktop.org/ontologies/2007/08/15/nao#description",
+            "http://www.semanticdesktop.org/ontologies/2007/08/15/nao#hasTag",
+            "http://www.semanticdesktop.org/ontologies/2007/08/15/nao#lastModified",
+            "http://www.semanticdesktop.org/ontologies/2007/08/15/nao#numericRating",
             "http://www.w3.org/1999/02/22-rdf-syntax-ns#type",
             "kfileitem#owner",
             "kfileitem#permissions",
             "http://www.w3.org/1999/02/22-rdf-syntax-ns#type",
             "kfileitem#owner",
             "kfileitem#permissions",
@@ -380,67 +366,65 @@ void KMetaDataWidget::Private::updateRowsVisibility()
 void KMetaDataWidget::Private::slotLoadingFinished()
 {
 #ifdef HAVE_NEPOMUK
 void KMetaDataWidget::Private::slotLoadingFinished()
 {
 #ifdef HAVE_NEPOMUK
-    // The thread that has emitted the finished() signal
-    // will get deleted and removed from m_metaDataThreads.
-    const int threadsCount = m_metaDataThreads.count();
-    for (int i = 0; i < threadsCount; ++i) {
-        KLoadMetaDataThread* thread = m_metaDataThreads[i];
-        if (thread == q->sender()) {
-            m_metaDataThreads.removeAt(i);
-            if (thread != m_latestMetaDataThread) {
-                // Ignore data of older threads, as the data got
-                // obsolete by m_latestMetaDataThread.
-                thread->deleteLater();
-                return;
-            }
-        }
-    }
-
-    if (m_nepomukActivated) {
-        Q_ASSERT(m_ratingWidget != 0);
-        Q_ASSERT(m_commentWidget != 0);
-        Q_ASSERT(m_taggingWidget != 0);
-        m_ratingWidget->setRating(m_latestMetaDataThread->rating());
-        m_commentWidget->setText(m_latestMetaDataThread->comment());
-        m_taggingWidget->setTags(m_latestMetaDataThread->tags());
-    }
-
     // Show the remaining meta information as text. The number
     // of required rows may very. Existing rows are reused to
     // prevent flickering.
     // Show the remaining meta information as text. The number
     // of required rows may very. Existing rows are reused to
     // prevent flickering.
+
+    const KNfoTranslator& nfo = KNfoTranslator::instance();
     int rowIndex = m_fixedRowCount;
     int rowIndex = m_fixedRowCount;
-    const QList<KLoadMetaDataThread::Item> items = mergedItems(m_latestMetaDataThread->items());
-    foreach (const KLoadMetaDataThread::Item& item, items) {
-        const QString itemLabel = item.label;
-        QString itemValue = item.value;
-        if (item.value.startsWith("<a href=")) {
-           // use the text color for the value-links, to create a visual difference
-           // to the semantically different links like "Change..."
-           const QColor linkColor = q->palette().text().color();
-           QString decoration;
-           if (m_readOnly) {
-               decoration = QString::fromLatin1("text-decoration:none;");
-           }
-           const QString styleText = QString::fromLatin1("style=\"color:%1;%2\" ")
-                                                         .arg(linkColor.name())
-                                                         .arg(decoration);
-           itemValue.insert(3 /* after "<a "*/, styleText);
+
+    QMap<KUrl, Nepomuk::Variant> data = m_model->data();
+    QMap<KUrl, Nepomuk::Variant>::const_iterator it = data.constBegin();
+    while (it != data.constEnd()) {
+        const KUrl key = it.key();
+        const Nepomuk::Variant value = it.value();
+        const QString itemLabel = nfo.translation(it.key());
+
+        bool appliedData = false;
+        if (m_nepomukActivated) {
+            const QString key = it.key().url();
+            if (key == QLatin1String("kfileitem#rating")) {
+                m_ratingWidget->setRating(value.toInt());
+                appliedData = true;
+            } else if (key == QLatin1String("kfileitem#comment")) {
+                m_commentWidget->setText(value.toString());
+                appliedData = true;
+            } else if (key == QLatin1String("kfileitem#tags")) {
+                QList<Nepomuk::Variant> variants = value.toVariantList();
+                QList<Nepomuk::Tag> tags;
+                foreach (const Nepomuk::Variant& variant, variants) {
+                    const Nepomuk::Resource resource = variant.toResource();
+                    tags.append(static_cast<Nepomuk::Tag>(resource));
+                }
+                m_taggingWidget->setTags(tags);
+                appliedData = true;
+            }
         }
         }
-        if (rowIndex < m_rows.count()) {
-            // adjust texts of the current row
-            m_rows[rowIndex].label->setText(itemLabel);
-            QLabel* infoValueLabel = qobject_cast<QLabel*>(m_rows[rowIndex].infoWidget);
-            Q_ASSERT(infoValueLabel != 0);
-            infoValueLabel->setText(itemValue);
-        } else {
-            // create new row
-            QLabel* infoLabel = new QLabel(itemLabel, q);
-            QLabel* infoValue = new QLabel(itemValue, q);
-            connect(infoValue, SIGNAL(linkActivated(QString)),
-                    q, SLOT(slotLinkActivated(QString)));
-            addRow(infoLabel, infoValue);
+
+        if (!appliedData) {
+            QString itemValue;
+            if (value.isString()) {
+                itemValue = value.toString();
+            }
+
+            if (rowIndex < m_rows.count()) {
+                // adjust texts of the current row
+                m_rows[rowIndex].label->setText(itemLabel);
+                QLabel* infoValueLabel = qobject_cast<QLabel*>(m_rows[rowIndex].infoWidget);
+                Q_ASSERT(infoValueLabel != 0);
+                infoValueLabel->setText(itemValue);
+            } else {
+                // create new row
+                QLabel* infoLabel = new QLabel(itemLabel, q);
+                QLabel* infoValue = new QLabel(itemValue, q);
+                connect(infoValue, SIGNAL(linkActivated(QString)),
+                        q, SLOT(slotLinkActivated(QString)));
+                addRow(infoLabel, infoValue);
+            }
+            ++rowIndex;
         }
         }
-        ++rowIndex;
+
+        ++it;
     }
 
     // remove rows that are not needed anymore
     }
 
     // remove rows that are not needed anymore
@@ -449,9 +433,6 @@ void KMetaDataWidget::Private::slotLoadingFinished()
         delete m_rows[i].infoWidget;
         m_rows.pop_back();
     }
         delete m_rows[i].infoWidget;
         m_rows.pop_back();
     }
-
-    m_files = m_latestMetaDataThread->files();
-    m_latestMetaDataThread->deleteLater();
 #endif
 
     q->updateGeometry();
 #endif
 
     q->updateGeometry();
@@ -461,7 +442,7 @@ void KMetaDataWidget::Private::slotRatingChanged(unsigned int rating)
 {
 #ifdef HAVE_NEPOMUK
     Nepomuk::MassUpdateJob* job =
 {
 #ifdef HAVE_NEPOMUK
     Nepomuk::MassUpdateJob* job =
-        Nepomuk::MassUpdateJob::rateResources(m_files.values(), rating);
+        Nepomuk::MassUpdateJob::rateResources(resourceList(), rating);
     startChangeDataJob(job);
 #else
     Q_UNUSED(rating);
     startChangeDataJob(job);
 #else
     Q_UNUSED(rating);
@@ -474,7 +455,7 @@ void KMetaDataWidget::Private::slotTagsChanged(const QList<Nepomuk::Tag>& tags)
     m_taggingWidget->setTags(tags);
 
     Nepomuk::MassUpdateJob* job =
     m_taggingWidget->setTags(tags);
 
     Nepomuk::MassUpdateJob* job =
-        Nepomuk::MassUpdateJob::tagResources(m_files.values(), tags);
+        Nepomuk::MassUpdateJob::tagResources(resourceList(), tags);
     startChangeDataJob(job);
 #else
     Q_UNUSED(tags);
     startChangeDataJob(job);
 #else
     Q_UNUSED(tags);
@@ -485,7 +466,7 @@ void KMetaDataWidget::Private::slotCommentChanged(const QString& comment)
 {
 #ifdef HAVE_NEPOMUK
     Nepomuk::MassUpdateJob* job =
 {
 #ifdef HAVE_NEPOMUK
     Nepomuk::MassUpdateJob* job =
-        Nepomuk::MassUpdateJob::commentResources(m_files.values(), comment);
+        Nepomuk::MassUpdateJob::commentResources(resourceList(), comment);
     startChangeDataJob(job);
 #else
     Q_UNUSED(comment);
     startChangeDataJob(job);
 #else
     Q_UNUSED(comment);
@@ -522,46 +503,14 @@ void KMetaDataWidget::Private::startChangeDataJob(KJob* job)
     job->start();
 }
 
     job->start();
 }
 
-QList<KLoadMetaDataThread::Item>
-    KMetaDataWidget::Private::mergedItems(const QList<KLoadMetaDataThread::Item>& items)
+QList<Nepomuk::Resource> KMetaDataWidget::Private::resourceList() const
 {
 {
-    // TODO: Currently only "width" and "height" are merged as "width x height". If
-    // other kind of merges should be done too, a more general approach is required.
-    QList<KLoadMetaDataThread::Item> mergedItems;
-
-    KLoadMetaDataThread::Item width;
-    KLoadMetaDataThread::Item height;
-
-    foreach (const KLoadMetaDataThread::Item& item, items) {
-        if (item.name == QLatin1String("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#width")) {
-            width = item;
-        } else if (item.name == QLatin1String("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#height")) {
-            height = item;
-        } else {
-            // insert the item sorted by the label
-            int pos = 0;
-            while ((mergedItems.count() > pos) &&
-                   (mergedItems[pos].label < item.label)) {
-                ++pos;
-            }
-            mergedItems.insert(pos, item);
-        }
+    QList<Nepomuk::Resource> list;
+    foreach (const KFileItem& item, m_fileItems) {
+        const KUrl url = item.url();
+        list.append(Nepomuk::Resource(url));
     }
     }
-
-    const bool foundWidth = !width.name.isEmpty();
-    const bool foundHeight = !height.name.isEmpty();
-    if (foundWidth && !foundHeight) {
-        mergedItems.insert(0, width);
-    } else if (foundHeight && !foundWidth) {
-        mergedItems.insert(0, height);
-    } else if (foundWidth && foundHeight) {
-        KLoadMetaDataThread::Item size;
-        size.label = i18nc("@label image width and height", "Width x Height");
-        size.value = width.value + " x " + height.value;
-        mergedItems.insert(0, size);
-    }
-
-    return mergedItems;
+    return list;
 }
 #endif
 
 }
 #endif
 
@@ -599,6 +548,9 @@ void KMetaDataWidget::setItem(const KFileItem& item)
 void KMetaDataWidget::setItems(const KFileItemList& items)
 {
     d->m_fileItems = items;
 void KMetaDataWidget::setItems(const KFileItemList& items)
 {
     d->m_fileItems = items;
+    if (d->m_model != 0) {
+        d->m_model->setItems(items);
+    }
 
     if (items.count() > 1) {
         // calculate the size of all items and show this
 
     if (items.count() > 1) {
         // calculate the size of all items and show this
@@ -614,28 +566,6 @@ void KMetaDataWidget::setItems(const KFileItemList& items)
         }
         d->m_sizeInfo->setText(KIO::convertSize(totalSize));
     }
         }
         d->m_sizeInfo->setText(KIO::convertSize(totalSize));
     }
-
-#ifdef HAVE_NEPOMUK
-    QList<KUrl> urls;
-    foreach (const KFileItem& item, items) {
-        const KUrl url = item.nepomukUri();
-        if (url.isValid()) {
-            urls.append(url);
-        }
-    }
-
-    // Cancel all threads that have not emitted a finished() signal.
-    // The deleting of those threads is done in slotLoadingFinished().
-    foreach (KLoadMetaDataThread* thread, d->m_metaDataThreads) {
-        thread->cancel();
-    }
-
-    // create a new thread that will provide the meeta data for the items
-    d->m_latestMetaDataThread = new KLoadMetaDataThread();
-    connect(d->m_latestMetaDataThread, SIGNAL(finished()), this, SLOT(slotLoadingFinished()));
-    d->m_latestMetaDataThread->load(urls);
-    d->m_metaDataThreads.append(d->m_latestMetaDataThread);
-#endif
 }
 
 void KMetaDataWidget::setItem(const KUrl& url)
 }
 
 void KMetaDataWidget::setItem(const KUrl& url)
@@ -661,6 +591,20 @@ KFileItemList KMetaDataWidget::items() const
     return d->m_fileItems;
 }
 
     return d->m_fileItems;
 }
 
+void KMetaDataWidget::setModel(KMetaDataModel* model)
+{
+    if (d->m_model != 0) {
+        disconnect(d->m_model, SIGNAL(loadingFinished()));
+    }
+    d->m_model = model;
+    connect(d->m_model, SIGNAL(loadingFinished()), this, SLOT(slotLoadingFinished()));
+}
+
+KMetaDataModel* KMetaDataWidget::model() const
+{
+    return d->m_model;
+}
+
 void KMetaDataWidget::setReadOnly(bool readOnly)
 {
     d->m_readOnly = readOnly;
 void KMetaDataWidget::setReadOnly(bool readOnly)
 {
     d->m_readOnly = readOnly;
index 715defbc321eb859fd33dbb0a7e185b074568c99..858f1998a35ff12c725ad85ff268ddcb8ef1a182 100644 (file)
@@ -1,6 +1,6 @@
 /*****************************************************************************
  * Copyright (C) 2008 by Sebastian Trueg <trueg@kde.org>                     *
 /*****************************************************************************
  * Copyright (C) 2008 by Sebastian Trueg <trueg@kde.org>                     *
- * Copyright (C) 2009 by Peter Penz <peter.penz@gmx.at>                      *
+ * Copyright (C) 2009-2010 by Peter Penz <peter.penz@gmx.at>                 *
  *                                                                           *
  * This library is free software; you can redistribute it and/or             *
  * modify it under the terms of the GNU Library General Public               *
  *                                                                           *
  * This library is free software; you can redistribute it and/or             *
  * modify it under the terms of the GNU Library General Public               *
@@ -27,6 +27,7 @@
 
 #include <config-nepomuk.h>
 
 
 #include <config-nepomuk.h>
 
+class KMetaDataModel;
 class KUrl;
 
 /**
 class KUrl;
 
 /**
@@ -38,6 +39,10 @@ class KUrl;
  * to change specific meta data like rating, tags and
  * comment. The changes are stored automatically by the
  * meta data widget.
  * to change specific meta data like rating, tags and
  * comment. The changes are stored automatically by the
  * meta data widget.
+ *
+ * To show more than basic meta data, the meta data widget
+ * must be provided with a meta data model
+ * (see KMetaDataWidget::setModel()).
  */
 class KMetaDataWidget : public QWidget
 {
  */
 class KMetaDataWidget : public QWidget
 {
@@ -101,6 +106,13 @@ public:
 
     KFileItemList items() const;
 
 
     KFileItemList items() const;
 
+    /**
+     * Sets the used model which provides the data for the widget.
+     * One model can be shared by several meta data widgets.
+     */
+    void setModel(KMetaDataModel* model);
+    KMetaDataModel* model() const;
+
     /**
      * If set to true, data like comment, tag or rating cannot be changed by the user.
      * Per default read-only is disabled.
     /**
      * If set to true, data like comment, tag or rating cannot be changed by the user.
      * Per default read-only is disabled.
index 7da8181b792fca97e812ed35245f2958361764df..2c09329304d9c7a3efcb2d37dba3b2d9061c82b7 100644 (file)
@@ -20,7 +20,7 @@
 #include <klocale.h>
 #include <kstandarddirs.h>
 
 #include <klocale.h>
 #include <kstandarddirs.h>
 
-#include <QUrl>
+#include <kurl.h>
 
 struct TranslationTuple {
     const char* const key;
 
 struct TranslationTuple {
     const char* const key;
@@ -84,9 +84,9 @@ KNfoTranslator& KNfoTranslator::instance()
     return s_nfoTranslator->instance;
 }
 
     return s_nfoTranslator->instance;
 }
 
-QString KNfoTranslator::translation(const QUrl& uri) const
+QString KNfoTranslator::translation(const KUrl& uri) const
 {
 {
-    const QString key = uri.toString();
+    const QString key = uri.url();
     if (m_hash.contains(key)) {
         return m_hash.value(key);
     }
     if (m_hash.contains(key)) {
         return m_hash.value(key);
     }
index 293eda4c6687deaf410e4085190b43d4224d5f28..def13f7c47ec1347dadb1a312a51d3e2cfb180e1 100644 (file)
@@ -22,7 +22,7 @@
 #include <QHash>
 #include <QString>
 
 #include <QHash>
 #include <QString>
 
-class QUrl;
+class KUrl;
 
 /**
  * @brief Returns translations for Nepomuk File Ontology URIs.
 
 /**
  * @brief Returns translations for Nepomuk File Ontology URIs.
@@ -33,7 +33,7 @@ class KNfoTranslator
 {
 public:
     static KNfoTranslator& instance();
 {
 public:
     static KNfoTranslator& instance();
-    QString translation(const QUrl& uri) const;
+    QString translation(const KUrl& uri) const;
 
 protected:
     KNfoTranslator();
 
 protected:
     KNfoTranslator();
index d8a9e190cd3a29c60f95d9dffc45cd43ba112058..bcb3d60cdfbb79e6f06cab657afdee8e74c00b02 100644 (file)
@@ -26,6 +26,7 @@
 #include <kio/previewjob.h>
 #include <kseparator.h>
 
 #include <kio/previewjob.h>
 #include <kseparator.h>
 
+#include "panels/information/kmetadatamodel.h"
 #include "panels/information/kmetadatawidget.h"
 #include "tooltips/ktooltip.h"
 
 #include "panels/information/kmetadatawidget.h"
 #include "tooltips/ktooltip.h"
 
@@ -262,6 +263,7 @@ QWidget* ToolTipManager::createTipContent(const QPixmap& pixmap) const
 
     // add meta data
     KMetaDataWidget* metaDataWidget = new KMetaDataWidget(tipContent);
 
     // add meta data
     KMetaDataWidget* metaDataWidget = new KMetaDataWidget(tipContent);
+    metaDataWidget->setModel(new KMetaDataModel(tipContent));
     metaDataWidget->setForegroundRole(QPalette::ToolTipText);
     metaDataWidget->setItem(m_item);
     metaDataWidget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
     metaDataWidget->setForegroundRole(QPalette::ToolTipText);
     metaDataWidget->setItem(m_item);
     metaDataWidget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);