From: Peter Penz Date: Sat, 10 Oct 2009 20:12:58 +0000 (+0000) Subject: Reactivate reading of the meta data for the rating, comments and tags. All expensive... X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/commitdiff_plain/a56d2e78ce3265b66b1443a7707cf54114da7f69 Reactivate reading of the meta data for the rating, comments and tags. All expensive operations are done in a separate thread to assure that the Dolphin UI never gets blocked. svn path=/trunk/KDE/kdebase/apps/; revision=1033696 --- diff --git a/src/panels/information/commentwidget.cpp b/src/panels/information/commentwidget.cpp index 63d8a1dc3..6397bc39a 100644 --- a/src/panels/information/commentwidget.cpp +++ b/src/panels/information/commentwidget.cpp @@ -1,4 +1,5 @@ /*************************************************************************** + * Copyright (C) 2008 by Sebastian Trueg * * Copyright (C) 2009 by Peter Penz * * * * This program is free software; you can redistribute it and/or modify * @@ -19,13 +20,71 @@ #include "commentwidget_p.h" +#include +#include + +#include +#include +#include + CommentWidget::CommentWidget(QWidget* parent) : - QWidget(parent) + QWidget(parent), + m_label(0), + m_comment() { + m_label = new QLabel(this); + connect(m_label, SIGNAL(linkActivated(const QString&)), this, SLOT(slotLinkActivated(const QString&))); + + QVBoxLayout* layout = new QVBoxLayout(this); + layout->addWidget(m_label); + + setText(m_comment); } CommentWidget::~CommentWidget() { } +void CommentWidget::setText(const QString& comment) +{ + if (comment.isEmpty()) { + m_label->setText("" + i18nc("@label", "Add Comment...") + ""); + } else { + m_label->setText("

" + comment + " " + i18nc("@label", "Change...") + "

"); + } + m_comment = comment; +} + +QString CommentWidget::text() const +{ + return m_comment; +} + +void CommentWidget::slotLinkActivated(const QString& link) +{ + KDialog dialog(0, Qt::Dialog); + + QTextEdit* editor = new QTextEdit(&dialog); + editor->setText(m_comment); + + dialog.setMainWidget(editor); + + const QString caption = (link == "changeComment") ? + i18nc("@title:window", "Change Comment") : + i18nc("@title:window", "Add Comment"); + dialog.setCaption(caption); + dialog.setButtons(KDialog::Ok | KDialog::Cancel); + dialog.setDefaultButton(KDialog::Ok); + + KConfigGroup dialogConfig(KSharedConfig::openConfig("dolphinrc"), + "EditCommitDialog"); + dialog.restoreDialogSize(dialogConfig); + + if (dialog.exec() == QDialog::Accepted) { + setText(editor->toPlainText()); + } + + dialog.saveDialogSize(dialogConfig, KConfigBase::Persistent); +} + #include "commentwidget_p.moc" diff --git a/src/panels/information/commentwidget_p.h b/src/panels/information/commentwidget_p.h index b3768b131..67bced044 100644 --- a/src/panels/information/commentwidget_p.h +++ b/src/panels/information/commentwidget_p.h @@ -1,4 +1,5 @@ /*************************************************************************** + * Copyright (C) 2008 by Sebastian Trueg * * Copyright (C) 2009 by Peter Penz * * * * This program is free software; you can redistribute it and/or modify * @@ -20,8 +21,11 @@ #ifndef COMMENT_WIDGET #define COMMENT_WIDGET +#include #include +class QLabel; + class CommentWidget : public QWidget { Q_OBJECT @@ -29,6 +33,16 @@ class CommentWidget : public QWidget public: CommentWidget(QWidget* parent); virtual ~CommentWidget(); + + void setText(const QString& comment); + QString text() const; + +private slots: + void slotLinkActivated(const QString& link); + +private: + QLabel* m_label; + QString m_comment; }; #endif diff --git a/src/panels/information/metadatawidget.cpp b/src/panels/information/metadatawidget.cpp index 5c97d5257..76a6769b1 100644 --- a/src/panels/information/metadatawidget.cpp +++ b/src/panels/information/metadatawidget.cpp @@ -1,4 +1,5 @@ /*************************************************************************** + * Copyright (C) 2008 by Sebastian Trueg * * Copyright (C) 2009 by Peter Penz * * * * This program is free software; you can redistribute it and/or modify * @@ -22,20 +23,25 @@ #include #include -#include -#ifdef HAVE_NEPOMUK -#include "commentwidget_p.h" -#include "nepomukmassupdatejob_p.h" -#include "taggingwidget_p.h" -#endif - -#include - #include #include #include #include +#include +#ifdef HAVE_NEPOMUK + #include "commentwidget_p.h" + #include "nepomukmassupdatejob_p.h" + #include "taggingwidget_p.h" + + #include + #include + #include + #include + #include + #include +#endif + class MetaDataWidget::Private { public: @@ -51,20 +57,55 @@ public: void addRow(QLabel* label, QWidget* infoWidget); void setRowVisible(QWidget* infoWidget, bool visible); - QList m_rows; + void slotLoadingFinished(); + + QList rows; + + QGridLayout* gridLayout; - QGridLayout* m_gridLayout; + QLabel* typeInfo; + QLabel* sizeLabel; + QLabel* sizeInfo; + QLabel* modifiedInfo; + QLabel* ownerInfo; + QLabel* permissionsInfo; - QLabel* m_typeInfo; - QLabel* m_sizeLabel; - QLabel* m_sizeInfo; - QLabel* m_modifiedInfo; - QLabel* m_ownerInfo; - QLabel* m_permissionsInfo; #ifdef HAVE_NEPOMUK - KRatingWidget* m_ratingWidget; - TaggingWidget* m_taggingWidget; - CommentWidget* m_commentWidget; + KRatingWidget* ratingWidget; + TaggingWidget* taggingWidget; + CommentWidget* commentWidget; + + // shared data between the GUI-thread and + // the loader-thread (see LoadFilesThread): + QMutex mutex; + struct SharedData + { + int rating; + QString comment; + QList tags; + } sharedData; + + /** + * Loads the meta data of files and writes + * the result into a shared data pool that + * can be used by the widgets in the GUI thread. + */ + class LoadFilesThread : public QThread + { + public: + LoadFilesThread(SharedData* sharedData, QMutex* mutex); + virtual ~LoadFilesThread(); + void loadFiles(const KUrl::List& urls); + virtual void run(); + + private: + SharedData* m_sharedData; + QMutex* m_mutex; + KUrl::List m_urls; + bool m_canceled; + }; + + LoadFilesThread* loadFilesThread; #endif private: @@ -72,49 +113,57 @@ private: }; MetaDataWidget::Private::Private(MetaDataWidget* parent) : - m_rows(), - m_gridLayout(0), - m_typeInfo(0), - m_sizeLabel(0), - m_sizeInfo(0), - m_modifiedInfo(0), - m_ownerInfo(0), - m_permissionsInfo(0), + rows(), + gridLayout(0), + typeInfo(0), + sizeLabel(0), + sizeInfo(0), + modifiedInfo(0), + ownerInfo(0), + permissionsInfo(0), #ifdef HAVE_NEPOMUK - m_ratingWidget(0), - m_taggingWidget(0), - m_commentWidget(0), + ratingWidget(0), + taggingWidget(0), + commentWidget(0), + loadFilesThread(0), #endif q(parent) { - m_gridLayout = new QGridLayout(parent); - - m_typeInfo = new QLabel(parent); - m_sizeLabel = new QLabel(parent); - m_sizeInfo = new QLabel(parent); - m_modifiedInfo = new QLabel(parent); - m_ownerInfo = new QLabel(parent); - m_permissionsInfo = new QLabel(parent); + gridLayout = new QGridLayout(parent); + + typeInfo = new QLabel(parent); + sizeLabel = new QLabel(parent); + sizeInfo = new QLabel(parent); + modifiedInfo = new QLabel(parent); + ownerInfo = new QLabel(parent); + permissionsInfo = new QLabel(parent); #ifdef HAVE_NEPOMUK - m_ratingWidget = new KRatingWidget(parent); - m_taggingWidget = new TaggingWidget(parent); - m_commentWidget = new CommentWidget(parent); + ratingWidget = new KRatingWidget(parent); + taggingWidget = new TaggingWidget(parent); + commentWidget = new CommentWidget(parent); #endif - addRow(new QLabel(i18nc("@label", "Type:"), parent), m_typeInfo); - addRow(m_sizeLabel, m_sizeInfo); - addRow(new QLabel(i18nc("@label", "Modified:"), parent), m_modifiedInfo); - addRow(new QLabel(i18nc("@label", "Owner:"), parent), m_ownerInfo); - addRow(new QLabel(i18nc("@label", "Permissions:"), parent), m_permissionsInfo); + addRow(new QLabel(i18nc("@label", "Type:"), parent), typeInfo); + addRow(sizeLabel, sizeInfo); + addRow(new QLabel(i18nc("@label", "Modified:"), parent), modifiedInfo); + addRow(new QLabel(i18nc("@label", "Owner:"), parent), ownerInfo); + addRow(new QLabel(i18nc("@label", "Permissions:"), parent), permissionsInfo); #ifdef HAVE_NEPOMUK - addRow(new QLabel(i18nc("@label", "Rating:"), parent), m_ratingWidget); - addRow(new QLabel(i18nc("@label", "Tags:"), parent), m_taggingWidget); - addRow(new QLabel(i18nc("@label", "Comment:"), parent), m_commentWidget); + addRow(new QLabel(i18nc("@label", "Rating:"), parent), ratingWidget); + addRow(new QLabel(i18nc("@label", "Tags:"), parent), taggingWidget); + addRow(new QLabel(i18nc("@label", "Comment:"), parent), commentWidget); + + sharedData.rating = 0; + loadFilesThread = new LoadFilesThread(&sharedData, &mutex); + connect(loadFilesThread, SIGNAL(finished()), q, SLOT(slotLoadingFinished())); #endif } MetaDataWidget::Private::~Private() { +#ifdef HAVE_NEPOMUK + delete loadFilesThread; +#endif } void MetaDataWidget::Private::addRow(QLabel* label, QWidget* infoWidget) @@ -122,22 +171,24 @@ void MetaDataWidget::Private::addRow(QLabel* label, QWidget* infoWidget) Row row; row.label = label; row.infoWidget = infoWidget; - m_rows.append(row); + rows.append(row); + // use a brighter color for the label QPalette palette = label->palette(); QColor textColor = palette.color(QPalette::Text); textColor.setAlpha(128); palette.setColor(QPalette::WindowText, textColor); label->setPalette(palette); - const int rowIndex = m_rows.count(); - m_gridLayout->addWidget(label, rowIndex, 0, Qt::AlignLeft); - m_gridLayout->addWidget(infoWidget, rowIndex, 1, Qt::AlignRight); + // add the row to grid layout + const int rowIndex = rows.count(); + gridLayout->addWidget(label, rowIndex, 0, Qt::AlignLeft); + gridLayout->addWidget(infoWidget, rowIndex, 1, Qt::AlignRight); } void MetaDataWidget::Private::setRowVisible(QWidget* infoWidget, bool visible) { - foreach (const Row& row, m_rows) { + foreach (const Row& row, rows) { if (row.infoWidget == infoWidget) { row.label->setVisible(visible); row.infoWidget->setVisible(visible); @@ -146,6 +197,87 @@ void MetaDataWidget::Private::setRowVisible(QWidget* infoWidget, bool visible) } } +void MetaDataWidget::Private::slotLoadingFinished() +{ +#ifdef HAVE_NEPOMUK + QMutexLocker locker(&mutex); + ratingWidget->setRating(sharedData.rating); + commentWidget->setText(sharedData.comment); + taggingWidget->setTags(sharedData.tags); +#endif +} + +#ifdef HAVE_NEPOMUK +MetaDataWidget::Private::LoadFilesThread::LoadFilesThread( + MetaDataWidget::Private::SharedData* sharedData, + QMutex* mutex) : + m_sharedData(sharedData), + m_mutex(mutex), + m_urls(), + m_canceled(false) +{ +} + +MetaDataWidget::Private::LoadFilesThread::~LoadFilesThread() +{ + // This thread may very well be deleted during execution. We need + // to protect it from crashes here. + m_canceled = true; + wait(); +} + +void MetaDataWidget::Private::LoadFilesThread::loadFiles(const KUrl::List& urls) +{ + QMutexLocker locker(m_mutex); + m_urls = urls; + m_canceled = false; + start(); +} + +void MetaDataWidget::Private::LoadFilesThread::run() +{ + QMutexLocker locker(m_mutex); + const KUrl::List urls = m_urls; + locker.unlock(); + + bool first = true; + unsigned int rating = 0; + QString comment; + QList tags; + foreach (const KUrl& url, urls) { + if (m_canceled) { + return; + } + + Nepomuk::Resource file(url, Soprano::Vocabulary::Xesam::File()); + + if (!first && (rating != file.rating())) { + rating = 0; // reset rating + } else if (first) { + rating = file.rating(); + } + + if (!first && (comment != file.description())) { + comment.clear(); // reset comment + } else if (first) { + comment = file.description(); + } + + if (!first && (tags != file.tags())) { + tags.clear(); // reset tags + } else if (first) { + tags = file.tags(); + } + + first = false; + } + + locker.relock(); + m_sharedData->rating = rating; + m_sharedData->comment = comment; + m_sharedData->tags = tags; +} +#endif MetaDataWidget::MetaDataWidget(QWidget* parent) : QWidget(parent), @@ -162,18 +294,18 @@ void MetaDataWidget::setItem(const KFileItem& item) { // update values for "type", "size", "modified", // "owner" and "permissions" synchronously - d->m_sizeLabel->setText(i18nc("@label", "Size:")); + d->sizeLabel->setText(i18nc("@label", "Size:")); if (item.isDir()) { - d->m_typeInfo->setText(i18nc("@label", "Folder")); - d->setRowVisible(d->m_sizeInfo, false); + d->typeInfo->setText(i18nc("@label", "Folder")); + d->setRowVisible(d->sizeInfo, false); } else { - d->m_typeInfo->setText(item.mimeComment()); - d->m_sizeInfo->setText(KIO::convertSize(item.size())); - d->setRowVisible(d->m_sizeInfo, true); + d->typeInfo->setText(item.mimeComment()); + d->sizeInfo->setText(KIO::convertSize(item.size())); + d->setRowVisible(d->sizeInfo, true); } - d->m_modifiedInfo->setText(item.timeString()); - d->m_ownerInfo->setText(item.user()); - d->m_permissionsInfo->setText(item.permissionsString()); + d->modifiedInfo->setText(item.timeString()); + d->ownerInfo->setText(item.user()); + d->permissionsInfo->setText(item.permissionsString()); setItems(KFileItemList() << item); } @@ -183,8 +315,8 @@ void MetaDataWidget::setItems(const KFileItemList& items) if (items.count() > 1) { // calculate the size of all items and show this // information to the user - d->m_sizeLabel->setText(i18nc("@label", "Total Size:")); - d->setRowVisible(d->m_sizeInfo, true); + d->sizeLabel->setText(i18nc("@label", "Total Size:")); + d->setRowVisible(d->sizeInfo, true); quint64 totalSize = 0; foreach (const KFileItem& item, items) { @@ -192,8 +324,19 @@ void MetaDataWidget::setItems(const KFileItemList& items) totalSize += item.size(); } } - d->m_sizeInfo->setText(KIO::convertSize(totalSize)); + d->sizeInfo->setText(KIO::convertSize(totalSize)); } + +#ifdef HAVE_NEPOMUK + QList urls; + foreach (const KFileItem& item, items) { + const KUrl url = item.nepomukUri(); + if (url.isValid()) { + urls.append(url); + } + } + d->loadFilesThread->loadFiles(urls); +#endif } #include "metadatawidget.moc" diff --git a/src/panels/information/metadatawidget.h b/src/panels/information/metadatawidget.h index 1a84dab0d..1b390b275 100644 --- a/src/panels/information/metadatawidget.h +++ b/src/panels/information/metadatawidget.h @@ -1,4 +1,5 @@ /*************************************************************************** + * Copyright (C) 2008 by Sebastian Trueg * * Copyright (C) 2009 by Peter Penz * * * * This program is free software; you can redistribute it and/or modify * @@ -42,6 +43,8 @@ public: private: class Private; Private* d; + + Q_PRIVATE_SLOT(d, void slotLoadingFinished()) }; #endif diff --git a/src/panels/information/taggingwidget.cpp b/src/panels/information/taggingwidget.cpp index 96690f28e..7c9616d95 100644 --- a/src/panels/information/taggingwidget.cpp +++ b/src/panels/information/taggingwidget.cpp @@ -19,13 +19,61 @@ #include "taggingwidget_p.h" +#include + +#include +#include + TaggingWidget::TaggingWidget(QWidget* parent) : - QWidget(parent) + QWidget(parent), + m_label(0), + m_tags(), + m_tagsText() { + m_label = new QLabel(this); + connect(m_label, SIGNAL(linkActivated(const QString&)), this, SLOT(slotLinkActivated(const QString&))); + + QVBoxLayout* layout = new QVBoxLayout(this); + layout->addWidget(m_label); + + setTags(QList()); } TaggingWidget::~TaggingWidget() { } +void TaggingWidget::setTags(const QList& tags) +{ + m_tags = tags; + + m_tagsText.clear(); + bool first = true; + foreach (const Nepomuk::Tag& tag, m_tags) { + if (!first) { + m_tagsText += ", "; + } + m_tagsText += tag.genericLabel(); + first = false; + } + + if (m_tagsText.isEmpty()) { + m_label->setText("" + i18nc("@label", "Add Tags...") + ""); + } else { + m_label->setText("

" + m_tagsText + " " + i18nc("@label", "Change...") + "

"); + } + +} + +QList TaggingWidget::tags() const +{ + return m_tags; +} + +void TaggingWidget::slotLinkActivated(const QString& link) +{ + Q_UNUSED(link); + // TODO +} + #include "taggingwidget_p.moc" diff --git a/src/panels/information/taggingwidget_p.h b/src/panels/information/taggingwidget_p.h index 036caff9a..50f15ffe5 100644 --- a/src/panels/information/taggingwidget_p.h +++ b/src/panels/information/taggingwidget_p.h @@ -20,8 +20,12 @@ #ifndef TAGGING_WIDGET #define TAGGING_WIDGET +#include +#include #include +class QLabel; + class TaggingWidget : public QWidget { Q_OBJECT @@ -29,6 +33,17 @@ class TaggingWidget : public QWidget public: TaggingWidget(QWidget* parent); virtual ~TaggingWidget(); + + void setTags(const QList& tags); + QList tags() const; + +private slots: + void slotLinkActivated(const QString& link); + +private: + QLabel* m_label; + QList m_tags; + QString m_tagsText; }; #endif