30 #define DISABLE_NEPOMUK_LEGACY
31 #include "nepomukmassupdatejob.h"
32 #include "tagwidget.h"
36 #include "resourcemanager.h"
58 static QString plainText(
const QString& richText)
61 plainText.reserve(richText.length());
64 for (
int i = 0; i < richText.length(); ++i) {
65 const QChar c = richText.at(i);
66 if (c == QLatin1Char(
'<')) {
68 }
else if (c == QLatin1Char(
'>')) {
85class ValueWidget :
public QLabel
88 explicit ValueWidget(QWidget* parent = 0);
89 virtual QSize sizeHint()
const;
92ValueWidget::ValueWidget(
QWidget* parent) :
97QSize ValueWidget::sizeHint()
const
99 QFontMetrics metrics(font());
104 return metrics.size(Qt::TextSingleLine, plainText(text()));
109class KFileMetaDataProvider::Private
116 void slotLoadingFinished();
118 void slotRatingChanged(
unsigned int rating);
119 void slotTagsChanged(
const QList<Nepomuk::Tag>& tags);
120 void slotCommentChanged(
const QString& comment);
122 void slotMetaDataUpdateDone();
123 void slotTagClicked(
const Nepomuk::Tag& tag);
124 void slotLinkActivated(
const QString& link);
131 void startChangeDataJob(KJob* job);
133#ifndef KIO_NO_NEPOMUK
134 QList<Nepomuk::Resource> resourceList()
const;
135 QWidget* createRatingWidget(
int rating, QWidget* parent);
136 QWidget* createTagWidget(
const QList<Nepomuk::Tag>& tags, QWidget* parent);
137 QWidget* createCommentWidget(
const QString& comment, QWidget* parent);
139 QWidget* createValueWidget(
const QString& value, QWidget* parent);
144 static int subDirectoriesCount(
const QString &path);
147 bool m_nepomukActivated;
148 QList<KFileItem> m_fileItems;
150#ifndef KIO_NO_NEPOMUK
151 QHash<KUrl, Nepomuk::Variant> m_data;
153 QList<KFileMetaDataReader*> m_metaDataReaders;
154 KFileMetaDataReader* m_latestMetaDataReader;
156 QWeakPointer<KRatingWidget> m_ratingWidget;
157 QWeakPointer<Nepomuk::TagWidget> m_tagWidget;
158 QWeakPointer<KCommentWidget> m_commentWidget;
167 m_nepomukActivated(false),
169#ifndef KIO_NO_NEPOMUK
172 m_latestMetaDataReader(0),
179#ifndef KIO_NO_NEPOMUK
180 m_nepomukActivated = Nepomuk::ResourceManager::instance()->initialized();
184KFileMetaDataProvider::Private::~Private()
186#ifndef KIO_NO_NEPOMUK
187 qDeleteAll(m_metaDataReaders);
191void KFileMetaDataProvider::Private::slotLoadingFinished()
193#ifndef KIO_NO_NEPOMUK
194 KFileMetaDataReader* finishedMetaDataReader = qobject_cast<KFileMetaDataReader*>(q->sender());
197 for (
int i = 0; i < m_metaDataReaders.count(); ++i) {
198 KFileMetaDataReader* metaDataReader = m_metaDataReaders[i];
199 if (metaDataReader == finishedMetaDataReader) {
200 m_metaDataReaders.removeAt(i);
201 if (metaDataReader != m_latestMetaDataReader) {
204 metaDataReader->deleteLater();
210 m_data = m_latestMetaDataReader->metaData();
211 m_latestMetaDataReader->deleteLater();
213 if (m_fileItems.count() == 1) {
216 const KFileItem& item = m_fileItems.first();
219 const int count = subDirectoriesCount(item.
url().
pathOrUrl());
221 m_data.insert(KUrl(
"kfileitem#size"), QString(
"Unknown"));
223 const QString itemCountString =
i18ncp(
"@item:intable",
"%1 item",
"%1 items", count);
224 m_data.insert(KUrl(
"kfileitem#size"), itemCountString);
229 m_data.insert(KUrl(
"kfileitem#type"), item.
mimeComment());
231 m_data.insert(KUrl(
"kfileitem#owner"), item.
user());
233 }
else if (m_fileItems.count() > 1) {
235 quint64 totalSize = 0;
236 foreach (
const KFileItem& item, m_fileItems) {
238 totalSize += item.
size();
245 emit q->loadingFinished();
248void KFileMetaDataProvider::Private::slotRatingChanged(
unsigned int rating)
250#ifndef KIO_NO_NEPOMUK
251 Nepomuk::MassUpdateJob* job = Nepomuk::MassUpdateJob::rateResources(resourceList(), rating);
252 startChangeDataJob(job);
258void KFileMetaDataProvider::Private::slotTagsChanged(
const QList<Nepomuk::Tag>& tags)
260#ifndef KIO_NO_NEPOMUK
261 if (!m_tagWidget.isNull()) {
262 m_tagWidget.data()->setSelectedTags(tags);
264 Nepomuk::MassUpdateJob* job = Nepomuk::MassUpdateJob::tagResources(resourceList(), tags);
265 startChangeDataJob(job);
272void KFileMetaDataProvider::Private::slotCommentChanged(
const QString& comment)
274#ifndef KIO_NO_NEPOMUK
275 Nepomuk::MassUpdateJob* job = Nepomuk::MassUpdateJob::commentResources(resourceList(), comment);
276 startChangeDataJob(job);
282void KFileMetaDataProvider::Private::slotTagClicked(
const Nepomuk::Tag& tag)
284#ifndef KIO_NO_NEPOMUK
285 emit q->urlActivated(tag.resourceUri());
291void KFileMetaDataProvider::Private::slotLinkActivated(
const QString& link)
293 emit q->urlActivated(KUrl(link));
296void KFileMetaDataProvider::Private::startChangeDataJob(KJob* job)
298 connect(job, SIGNAL(result(KJob*)),
300 emit q->dataChangeStarted();
304#ifndef KIO_NO_NEPOMUK
305QList<Nepomuk::Resource> KFileMetaDataProvider::Private::resourceList()
const
307 QList<Nepomuk::Resource>
list;
308 foreach (
const KFileItem& item, m_fileItems) {
311 list.append(Nepomuk::Resource(url));
316QWidget* KFileMetaDataProvider::Private::createRatingWidget(
int rating, QWidget* parent)
318 KRatingWidget* ratingWidget =
new KRatingWidget(parent);
319 const Qt::Alignment align = (ratingWidget->
layoutDirection() == Qt::LeftToRight) ?
320 Qt::AlignLeft : Qt::AlignRight;
323 const QFontMetrics metrics(parent->font());
326 connect(ratingWidget, SIGNAL(ratingChanged(uint)),
327 q, SLOT(slotRatingChanged(uint)));
329 m_ratingWidget = ratingWidget;
334QWidget* KFileMetaDataProvider::Private::createTagWidget(
const QList<Nepomuk::Tag>& tags, QWidget* parent)
336 Nepomuk::TagWidget* tagWidget =
new Nepomuk::TagWidget(parent);
337 tagWidget->setModeFlags(m_readOnly
338 ? Nepomuk::TagWidget::MiniMode | Nepomuk::TagWidget::ReadOnly
339 : Nepomuk::TagWidget::MiniMode);
340 tagWidget->setSelectedTags(tags);
342 connect(tagWidget, SIGNAL(selectionChanged(QList<Nepomuk::Tag>)),
343 q, SLOT(slotTagsChanged(QList<Nepomuk::Tag>)));
344 connect(tagWidget, SIGNAL(tagClicked(Nepomuk::Tag)),
345 q, SLOT(slotTagClicked(Nepomuk::Tag)));
347 m_tagWidget = tagWidget;
352QWidget* KFileMetaDataProvider::Private::createCommentWidget(
const QString& comment, QWidget* parent)
354 KCommentWidget* commentWidget =
new KCommentWidget(parent);
355 commentWidget->
setText(comment);
358 connect(commentWidget, SIGNAL(commentChanged(QString)),
359 q, SLOT(slotCommentChanged(QString)));
361 m_commentWidget = commentWidget;
363 return commentWidget;
367QWidget* KFileMetaDataProvider::Private::createValueWidget(
const QString& value, QWidget* parent)
369 ValueWidget* valueWidget =
new ValueWidget(parent);
370 valueWidget->setWordWrap(
true);
371 valueWidget->setAlignment(Qt::AlignTop | Qt::AlignLeft);
372 valueWidget->setText(m_readOnly ? plainText(value) : value);
373 connect(valueWidget, SIGNAL(linkActivated(QString)), q, SLOT(slotLinkActivated(QString)));
390 d->m_fileItems =
items;
392#ifndef KIO_NO_NEPOMUK
393 if (
items.isEmpty()) {
396 Q_PRIVATE_SLOT(d,
void slotDataChangeStarted())
397 Q_PRIVATE_SLOT(d,
void slotDataChangeFinished())
407 d->m_latestMetaDataReader->setReadContextData(d->m_nepomukActivated);
408 connect(d->m_latestMetaDataReader, SIGNAL(finished()),
this, SLOT(slotLoadingFinished()));
409 d->m_metaDataReaders.append(d->m_latestMetaDataReader);
410 d->m_latestMetaDataReader->start();
416 struct TranslationItem {
417 const char*
const key;
418 const char*
const context;
419 const char*
const value;
422 static const TranslationItem translations[] = {
436 if (hash.isEmpty()) {
437 const TranslationItem* item = &translations[0];
438 while (item->key != 0) {
439 hash.insert(item->key,
i18nc(item->context, item->value));
444 QString value = hash.value(metaDataUri.
url());
445 if (value.isEmpty()) {
456 const QString uri = metaDataUri.
url();
457 if (uri == QLatin1String(
"kfileitem#type")) {
458 group = QLatin1String(
"0FileItemA");
459 }
else if (uri == QLatin1String(
"kfileitem#size")) {
460 group = QLatin1String(
"0FileItemB");
461 }
else if (uri == QLatin1String(
"http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#width")) {
462 group = QLatin1String(
"0SizeA");
463 }
else if (uri == QLatin1String(
"http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#height")) {
464 group = QLatin1String(
"0SizeB");
472 return d->m_fileItems;
477 d->m_readOnly = readOnly;
482 return d->m_readOnly;
485#ifndef KIO_NO_NEPOMUK
492 const Nepomuk::Variant& value,
495 Q_ASSERT(parent != 0);
498 if (d->m_nepomukActivated) {
499 const QString uri = metaDataUri.
url();
500 if (uri == QLatin1String(
"kfileitem#rating")) {
501 widget = d->createRatingWidget(value.toInt(), parent);
502 }
else if (uri == QLatin1String(
"kfileitem#tags")) {
503 const QStringList tagNames = value.toStringList();
505 foreach (
const QString& tagName, tagNames) {
506 tags.append(Nepomuk::Tag(tagName));
509 widget = d->createTagWidget(tags, parent);
510 }
else if (uri == QLatin1String(
"kfileitem#comment")) {
511 widget = d->createCommentWidget(value.toString(), parent);
516 widget = d->createValueWidget(value.toString(), parent);
519 widget->setForegroundRole(parent->foregroundRole());
520 widget->setFont(parent->font());
526int KFileMetaDataProvider::Private::subDirectoriesCount(
const QString& path)
530 return dir.entryList(QDir::AllEntries|QDir::NoDotAndDotDot|QDir::System).count();
536 DIR* dir = ::opendir(QFile::encodeName(path));
539 struct dirent *dirEntry = 0;
540 while ((dirEntry = ::readdir(dir))) {
541 if (dirEntry->d_name[0] ==
'.') {
542 if (dirEntry->d_name[1] ==
'\0') {
546 if (dirEntry->d_name[1] ==
'.' && dirEntry->d_name[2] ==
'\0') {
559#include "kfilemetadataprovider_p.moc"
List of KFileItems, which adds a few helper methods to QList<KFileItem>.
A KFileItem is a generic class to handle a file, local or remote.
KDateTime time(FileTimes which) const
Requests the modification, access or creation time, depending on which.
QString user() const
Returns the owner of the file.
KIO::filesize_t size() const
Returns the size of the file, if known.
bool isLink() const
Returns true if this item represents a link in the UNIX sense of a link.
KUrl nepomukUri() const
Returns the resource URI to be used for Nepomuk annotations.
bool isDir() const
Returns true if this item represents a directory.
KUrl url() const
Returns the url of the file.
QString permissionsString() const
Returns the access permissions for the file as a string.
QString mimeComment() const
Returns the user-readable string representing the type of this file, like "OpenDocument Text File".
static KNfoTranslator & instance()
QString translation(const KUrl &uri) const
QString pathOrUrl() const
QString url(AdjustPathOption trailing=LeaveTrailingSlash) const
#define I18N_NOOP2_NOSTRIP(ctxt, text)
QString i18nc(const char *ctxt, const char *text)
QString i18ncp(const char *ctxt, const char *sing, const char *plur, const A1 &a1)
QString convertSize(KIO::filesize_t size)
Converts size from bytes to the string representation.
QStringList list(const QString &fileClass)
Returns a list of directories associated with this file-class.