set(dolphin_SRCS
${dolphin_SRCS}
panels/information/commentwidget.cpp
+ panels/information/edittagsdialog.cpp
panels/information/nepomukmassupdatejob.cpp
panels/information/taggingwidget.cpp
)
void CommentWidget::slotLinkActivated(const QString& link)
{
- KDialog dialog(0, Qt::Dialog);
+ KDialog dialog(this, Qt::Dialog);
QTextEdit* editor = new QTextEdit(&dialog);
editor->setText(m_comment);
dialog.setDefaultButton(KDialog::Ok);
KConfigGroup dialogConfig(KSharedConfig::openConfig("dolphinrc"),
- "EditCommitDialog");
+ "EditCommentDialog");
dialog.restoreDialogSize(dialogConfig);
if (dialog.exec() == QDialog::Accepted) {
+ const QString oldText = m_comment;
setText(editor->toPlainText());
+ if (oldText != m_comment) {
+ emit commentChanged(m_comment);
+ }
}
dialog.saveDialogSize(dialogConfig, KConfigBase::Persistent);
void setText(const QString& comment);
QString text() const;
+signals:
+ void commentChanged(const QString& comment);
+
private slots:
void slotLinkActivated(const QString& link);
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2009 by Peter Penz <peter.penz@gmx.at> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "edittagsdialog_p.h"
+
+#include <klocale.h>
+
+EditTagsDialog::EditTagsDialog(const QList<Nepomuk::Tag>& tags,
+ QWidget* parent,
+ Qt::WFlags flags) :
+ KDialog(parent, flags),
+ m_tags(tags)
+{
+
+ const QString caption = (tags.count() > 0) ?
+ i18nc("@title:window", "Change Tags") :
+ i18nc("@title:window", "Add Tags");
+ setCaption(caption);
+ setButtons(KDialog::Ok | KDialog::Cancel);
+ setDefaultButton(KDialog::Ok);
+}
+
+EditTagsDialog::~EditTagsDialog()
+{
+}
+
+QList<Nepomuk::Tag> EditTagsDialog::tags() const
+{
+ return m_tags;
+}
+
+#include "edittagsdialog_p.moc"
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2009 by Peter Penz <peter.penz@gmx.at> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef EDIT_TAGS_DIALOG_H
+#define EDIT_TAGS_DIALOG_H
+
+#include <kdialog.h>
+
+#include <Nepomuk/Tag>
+
+/**
+ * @brief Dialog to edit a list of Nepomuk tags.
+ *
+ * It is possible for the user to add existing tags,
+ * create new tags or to remove tags.
+ */
+class EditTagsDialog : public KDialog
+{
+ Q_OBJECT
+
+public:
+ EditTagsDialog(const QList<Nepomuk::Tag>& tags,
+ QWidget* parent = 0,
+ Qt::WFlags flags = 0);
+
+ virtual ~EditTagsDialog();
+
+ QList<Nepomuk::Tag> tags() const;
+
+private:
+ QList<Nepomuk::Tag> m_tags;
+};
+
+#endif
#include <Nepomuk/KRatingWidget>
#include <Nepomuk/Resource>
- #include <Nepomuk/Tag>
#include <Nepomuk/Types/Property>
#include <Nepomuk/Variant>
void setRowVisible(QWidget* infoWidget, bool visible);
void slotLoadingFinished();
+ void slotRatingChanged(unsigned int rating);
+ void slotTagsChanged(const QList<Nepomuk::Tag>& tags);
+ void slotCommentChanged(const QString& comment);
+ void slotMetaDataUpdateDone();
+
+ /**
+ * Disables the metadata widget and starts the job that
+ * changes the meta data asynchronously. After the job
+ * has been finished, the metadata widget gets enabled again.
+ */
+ void startChangeDataJob(KJob* job);
QList<Row> m_rows;
QList<Nepomuk::Tag> tags;
QList<QString> metaInfoLabels;
QList<QString> metaInfoValues;
+ QMap<KUrl, Nepomuk::Resource> files;
} m_sharedData;
/**
QString tunedLabel(const QString& label) const;
private:
- SharedData* m_m_sharedData;
- QMutex* m_m_mutex;
+ SharedData* m_sharedData;
+ QMutex* m_mutex;
KUrl::List m_urls;
bool m_canceled;
};
const QFontMetrics fontMetrics(KGlobalSettings::smallestReadableFont());
m_ratingWidget = new KRatingWidget(parent);
m_ratingWidget->setFixedHeight(fontMetrics.height());
+ connect(m_ratingWidget, SIGNAL(ratingChanged(unsigned int)),
+ q, SLOT(slotRatingChanged(unsigned int)));
m_taggingWidget = new TaggingWidget(parent);
+ connect(m_taggingWidget, SIGNAL(tagsChanged(const QList<Nepomuk::Tag>&)),
+ q, SLOT(slotTagsChanged(const QList<Nepomuk::Tag>&)));
m_commentWidget = new CommentWidget(parent);
+ connect(m_commentWidget, SIGNAL(commentChanged(const QString&)),
+ q, SLOT(slotCommentChanged(const QString&)));
#endif
addRow(new QLabel(i18nc("@label", "Type:"), parent), m_typeInfo);
#endif
}
+void MetaDataWidget::Private::slotRatingChanged(unsigned int rating)
+{
+#ifdef HAVE_NEPOMUK
+ QMutexLocker locker(&m_mutex);
+ Nepomuk::MassUpdateJob* job =
+ Nepomuk::MassUpdateJob::rateResources(m_sharedData.files.values(), rating);
+ locker.unlock();
+ startChangeDataJob(job);
+#else
+ Q_UNUSED(rating);
+#endif
+}
+
+void MetaDataWidget::Private::slotTagsChanged(const QList<Nepomuk::Tag>& tags)
+{
+#ifdef HAVE_NEPOMUK
+ QMutexLocker locker(&m_mutex);
+ Nepomuk::MassUpdateJob* job =
+ Nepomuk::MassUpdateJob::tagResources(m_sharedData.files.values(), tags);
+ locker.unlock();
+ startChangeDataJob(job);
+#else
+ Q_UNUSED(tags);
+#endif
+}
+
+void MetaDataWidget::Private::slotCommentChanged(const QString& comment)
+{
+#ifdef HAVE_NEPOMUK
+ QMutexLocker locker(&m_mutex);
+ Nepomuk::MassUpdateJob* job =
+ Nepomuk::MassUpdateJob::commentResources(m_sharedData.files.values(), comment);
+ locker.unlock();
+ startChangeDataJob(job);
+#else
+ Q_UNUSED(comment);
+#endif
+}
+
+void MetaDataWidget::Private::slotMetaDataUpdateDone()
+{
+ q->setEnabled(true);
+}
+
+void MetaDataWidget::Private::startChangeDataJob(KJob* job)
+{
+ connect(job, SIGNAL(result(KJob*)),
+ q, SLOT(slotMetaDataUpdateDone()));
+ q->setEnabled(false); // no updates during execution
+ job->start();
+}
+
#ifdef HAVE_NEPOMUK
MetaDataWidget::Private::LoadFilesThread::LoadFilesThread(
MetaDataWidget::Private::SharedData* m_sharedData,
QMutex* m_mutex) :
- m_m_sharedData(m_sharedData),
- m_m_mutex(m_mutex),
+ m_sharedData(m_sharedData),
+ m_mutex(m_mutex),
m_urls(),
m_canceled(false)
{
void MetaDataWidget::Private::LoadFilesThread::loadFiles(const KUrl::List& urls)
{
- QMutexLocker locker(m_m_mutex);
+ QMutexLocker locker(m_mutex);
m_urls = urls;
m_canceled = false;
start();
void MetaDataWidget::Private::LoadFilesThread::run()
{
- QMutexLocker locker(m_m_mutex);
+ QMutexLocker locker(m_mutex);
const KUrl::List urls = m_urls;
locker.unlock();
QList<Nepomuk::Tag> tags;
QList<QString> metaInfoLabels;
QList<QString> metaInfoValues;
+ QMap<KUrl, Nepomuk::Resource> files;
foreach (const KUrl& url, urls) {
if (m_canceled) {
return;
}
Nepomuk::Resource file(url, Soprano::Vocabulary::Xesam::File());
+ files.insert(url, file);
if (!first && (rating != file.rating())) {
rating = 0; // reset rating
}
locker.relock();
- m_m_sharedData->rating = rating;
- m_m_sharedData->comment = comment;
- m_m_sharedData->tags = tags;
- m_m_sharedData->metaInfoLabels = metaInfoLabels;
- m_m_sharedData->metaInfoValues = metaInfoValues;
+ m_sharedData->rating = rating;
+ m_sharedData->comment = comment;
+ m_sharedData->tags = tags;
+ m_sharedData->metaInfoLabels = metaInfoLabels;
+ m_sharedData->metaInfoValues = metaInfoValues;
+ m_sharedData->files = files;
}
void MetaDataWidget::Private::LoadFilesThread::initMetaInfoSettings(KConfigGroup& group)
return tunedLabel + ':';
}
-#endif
+#endif // HAVE_NEPOMUK
MetaDataWidget::MetaDataWidget(QWidget* parent) :
QWidget(parent),
#ifndef METADATAWIDGET_H
#define METADATAWIDGET_H
+#include <config-nepomuk.h>
+#ifdef HAVE_NEPOMUK
+ #include <Nepomuk/Tag>
+#else
+ // The HAVE_NEPOMUK macro cannot be used in combination with
+ // Q_PRIVATE_SLOT, hence a workaround is used for environments
+ // where Nepomuk is not available:
+ namespace Nepomuk {
+ typedef int Tag;
+ }
+#endif
+
+#include <QList>
#include <QWidget>
class KFileItem;
Private* d;
Q_PRIVATE_SLOT(d, void slotLoadingFinished())
+ Q_PRIVATE_SLOT(d, void slotRatingChanged(unsigned int rating))
+ Q_PRIVATE_SLOT(d, void slotTagsChanged(const QList<Nepomuk::Tag>& tags))
+ Q_PRIVATE_SLOT(d, void slotCommentChanged(const QString& comment))
+ Q_PRIVATE_SLOT(d, void slotMetaDataUpdateDone())
};
#endif
#include "nepomukmassupdatejob_p.h"
#include <klocale.h>
-#include <kdebug.h>
#include <nepomuk/tag.h>
#include <nepomuk/tools.h>
-Nepomuk::MassUpdateJob::MassUpdateJob( QObject* parent )
- : KJob( parent ),
- m_index( -1 )
+Nepomuk::MassUpdateJob::MassUpdateJob(QObject* parent)
+ : KJob(parent),
+ m_index(-1)
{
- kDebug();
- setCapabilities( Killable|Suspendable );
- connect( &m_processTimer, SIGNAL( timeout() ),
- this, SLOT( slotNext() ) );
+ setCapabilities(Killable|Suspendable);
+ connect(&m_processTimer, SIGNAL(timeout()),
+ this, SLOT(slotNext()));
}
-
Nepomuk::MassUpdateJob::~MassUpdateJob()
{
- kDebug();
}
-
-void Nepomuk::MassUpdateJob::setFiles( const KUrl::List& urls )
+void Nepomuk::MassUpdateJob::setFiles(const KUrl::List& urls)
{
m_resources.clear();
- foreach( const KUrl &url, urls ) {
- m_resources.append( Resource( url ) );
+ foreach(const KUrl &url, urls){
+ m_resources.append(Resource(url));
}
- setTotalAmount( KJob::Files, m_resources.count() );
+ setTotalAmount(KJob::Files, m_resources.count());
}
-
-void Nepomuk::MassUpdateJob::setResources( const QList<Nepomuk::Resource>& rl )
+void Nepomuk::MassUpdateJob::setResources(const QList<Nepomuk::Resource>& rl)
{
m_resources = rl;
- setTotalAmount( KJob::Files, m_resources.count() );
+ setTotalAmount(KJob::Files, m_resources.count());
}
-
-void Nepomuk::MassUpdateJob::setProperties( const QList<QPair<QUrl,Nepomuk::Variant> >& props )
+void Nepomuk::MassUpdateJob::setProperties(const QList<QPair<QUrl,Nepomuk::Variant> >& props)
{
m_properties = props;
}
-
void Nepomuk::MassUpdateJob::start()
{
- if ( m_index < 0 ) {
- kDebug();
- emit description( this,
- i18nc("@info:progress", "Changing annotations") );
+ if (m_index < 0){
+ emit description(this, i18nc("@info:progress", "Changing annotations"));
m_index = 0;
m_processTimer.start();
}
- else {
- kDebug() << "Job has already been started";
- }
}
bool Nepomuk::MassUpdateJob::doKill()
{
- if ( m_index > 0 ) {
+ if (m_index > 0){
m_processTimer.stop();
m_index = -1;
return true;
- }
- else {
+ } else {
return false;
}
}
-
bool Nepomuk::MassUpdateJob::doSuspend()
{
m_processTimer.stop();
return true;
}
-
bool Nepomuk::MassUpdateJob::doResume()
{
- if ( m_index > 0 ) {
+ if (m_index > 0){
m_processTimer.start();
return true;
- }
- else {
+ } else {
return false;
}
}
-
void Nepomuk::MassUpdateJob::slotNext()
{
- if ( !isSuspended() ) {
- if ( m_index < m_resources.count() ) {
+ if (!isSuspended()) {
+ if (m_index < m_resources.count()){
Nepomuk::Resource& res = m_resources[m_index];
- for ( int i = 0; i < m_properties.count(); ++i ) {
- res.setProperty( m_properties[i].first, m_properties[i].second );
+ for (int i = 0; i < m_properties.count(); ++i){
+ res.setProperty(m_properties[i].first, m_properties[i].second);
}
++m_index;
- setProcessedAmount( KJob::Files, m_index );
- }
- else if ( m_index >= m_resources.count() ) {
- kDebug() << "done";
+ setProcessedAmount(KJob::Files, m_index);
+ } else if (m_index >= m_resources.count()) {
m_index = -1;
m_processTimer.stop();
emitResult();
}
}
-
-Nepomuk::MassUpdateJob* Nepomuk::MassUpdateJob::tagResources( const QList<Nepomuk::Resource>& rl, const QList<Nepomuk::Tag>& tags )
+Nepomuk::MassUpdateJob* Nepomuk::MassUpdateJob::tagResources(const QList<Nepomuk::Resource>& rl,
+ const QList<Nepomuk::Tag>& tags)
{
Nepomuk::MassUpdateJob* job = new Nepomuk::MassUpdateJob();
- job->setResources( rl );
- job->setProperties( QList<QPair<QUrl,Nepomuk::Variant> >() << qMakePair( QUrl( Nepomuk::Resource::tagUri() ), Nepomuk::Variant( convertResourceList<Tag>( tags ) ) ) );
+ job->setResources(rl);
+ job->setProperties(QList<QPair<QUrl,Nepomuk::Variant> >() <<
+ qMakePair(QUrl(Nepomuk::Resource::tagUri()),
+ Nepomuk::Variant(convertResourceList<Tag>(tags))));
return job;
}
-
-Nepomuk::MassUpdateJob* Nepomuk::MassUpdateJob::rateResources( const QList<Nepomuk::Resource>& rl, int rating )
+Nepomuk::MassUpdateJob* Nepomuk::MassUpdateJob::rateResources(const QList<Nepomuk::Resource>& rl,
+ unsigned int rating)
{
Nepomuk::MassUpdateJob* job = new Nepomuk::MassUpdateJob();
- job->setResources( rl );
- job->setProperties( QList<QPair<QUrl,Nepomuk::Variant> >() << qMakePair( QUrl( Nepomuk::Resource::ratingUri() ), Nepomuk::Variant( rating ) ) );
+ job->setResources(rl);
+ job->setProperties(QList<QPair<QUrl,Nepomuk::Variant> >() <<
+ qMakePair(QUrl(Nepomuk::Resource::ratingUri()),
+ Nepomuk::Variant(rating)));
return job;
}
-
-Nepomuk::MassUpdateJob* Nepomuk::MassUpdateJob::commentResources( const QList<Nepomuk::Resource>& rl, const QString& comment )
+Nepomuk::MassUpdateJob* Nepomuk::MassUpdateJob::commentResources(const QList<Nepomuk::Resource>& rl,
+ const QString& comment)
{
Nepomuk::MassUpdateJob* job = new Nepomuk::MassUpdateJob();
- job->setResources( rl );
- job->setProperties( QList<QPair<QUrl,Nepomuk::Variant> >() << qMakePair( QUrl( Nepomuk::Resource::descriptionUri() ), Nepomuk::Variant( comment ) ) );
+ job->setResources(rl);
+ job->setProperties(QList<QPair<QUrl,Nepomuk::Variant> >() <<
+ qMakePair(QUrl(Nepomuk::Resource::descriptionUri()),
+ Nepomuk::Variant(comment)));
return job;
}
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
-#ifndef _NEPOMUK_MASS_UPDATE_JOB_H_
-#define _NEPOMUK_MASS_UPDATE_JOB_H_
+#ifndef NEPOMUK_MASS_UPDATE_JOB_H
+#define NEPOMUK_MASS_UPDATE_JOB_H
#include <kjob.h>
#include <kurl.h>
Q_OBJECT
public:
- MassUpdateJob( QObject* parent = 0 );
- ~MassUpdateJob();
+ MassUpdateJob(QObject* parent = 0);
+ virtual ~MassUpdateJob();
/**
* Set a list of files to change
* This has the same effect as using setResources
* with a list of manually created resources.
*/
- void setFiles( const KUrl::List& urls );
+ void setFiles(const KUrl::List& urls);
/**
* Set a list of resources to change.
*/
- void setResources( const QList<Nepomuk::Resource>& );
+ void setResources(const QList<Nepomuk::Resource>&);
/**
* Set the properties to change in the mass update.
*/
- void setProperties( const QList<QPair<QUrl,Nepomuk::Variant> >& props );
+ void setProperties(const QList<QPair<QUrl,Nepomuk::Variant> >& props);
/**
* Actually start the job.
*/
void start();
- static MassUpdateJob* tagResources( const QList<Nepomuk::Resource>&, const QList<Nepomuk::Tag>& tags );
- static MassUpdateJob* commentResources( const QList<Nepomuk::Resource>&, const QString& comment );
- static MassUpdateJob* rateResources( const QList<Nepomuk::Resource>&, int rating );
+ static MassUpdateJob* tagResources(const QList<Nepomuk::Resource>&, const QList<Nepomuk::Tag>& tags);
+ static MassUpdateJob* commentResources(const QList<Nepomuk::Resource>&, const QString& comment);
+ static MassUpdateJob* rateResources(const QList<Nepomuk::Resource>&, unsigned int rating);
protected:
bool doKill();
#include "taggingwidget_p.h"
+#include "edittagsdialog_p.h"
+
#include <kglobalsettings.h>
#include <klocale.h>
void TaggingWidget::slotLinkActivated(const QString& link)
{
Q_UNUSED(link);
- // TODO
+
+ EditTagsDialog dialog(m_tags, this, Qt::Dialog);
+ KConfigGroup dialogConfig(KSharedConfig::openConfig("dolphinrc"),
+ "EditTagsDialog");
+ dialog.restoreDialogSize(dialogConfig);
+
+ if (dialog.exec() == QDialog::Accepted) {
+ const QList<Nepomuk::Tag> oldTags = m_tags;
+ m_tags = dialog.tags();
+
+ if (oldTags.count() != m_tags.count()) {
+ emit tagsChanged(m_tags);
+ } else {
+ // The number of tags is equal. Check whether the
+ // content of the tags are also equal:
+ const int tagsCount = m_tags.count();
+ for (int i = 0; i < tagsCount; ++i) {
+ if (oldTags[i].genericLabel() != m_tags[i].genericLabel()) {
+ // at least one tag has been changed
+ emit tagsChanged(m_tags);
+ break;
+ }
+ }
+ }
+ }
+
+ dialog.saveDialogSize(dialogConfig, KConfigBase::Persistent);
}
#include "taggingwidget_p.moc"
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
-#ifndef TAGGING_WIDGET
-#define TAGGING_WIDGET
+#ifndef TAGGING_WIDGET_H
+#define TAGGING_WIDGET_H
#include <nepomuk/tag.h>
#include <QString>
void setTags(const QList<Nepomuk::Tag>& tags);
QList<Nepomuk::Tag> tags() const;
+signals:
+ void tagsChanged(const QList<Nepomuk::Tag>& tags);
+
private slots:
void slotLinkActivated(const QString& link);