From 73007f7d632bdd5565b8394043bb2de07bebb336 Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Wed, 28 Oct 2009 07:18:00 +0000 Subject: After some discussions at http://reviewboard.kde.org/r/1938 it turned out that moving KMetaDataWidget and KMetaDataConfigurationDialog to kdelibs should be postponed to KDE 4.5. The main reason is that adding application specific properties is not possible with the current API in a generic way. Also the topic how to hide properties application specific is an open point... So now all adjustments from the review have been adapted to the Dolphin code. After KDE 4.4 has been released some refactoring will be done so that the open topics above are handled in a nice way. svn path=/trunk/KDE/kdebase/apps/; revision=1041547 --- src/CMakeLists.txt | 10 +- src/dolphinmainwindow.cpp | 1 - src/panels/information/commentwidget.cpp | 98 --- src/panels/information/commentwidget_p.h | 51 -- src/panels/information/edittagsdialog.cpp | 180 ------ src/panels/information/edittagsdialog_p.h | 67 -- src/panels/information/informationpanelcontent.cpp | 18 +- src/panels/information/informationpanelcontent.h | 10 +- src/panels/information/kcommentwidget.cpp | 97 +++ src/panels/information/kcommentwidget_p.h | 53 ++ src/panels/information/kedittagsdialog.cpp | 179 ++++++ src/panels/information/kedittagsdialog_p.h | 67 ++ .../information/kmetadataconfigurationdialog.cpp | 283 ++++++++ .../information/kmetadataconfigurationdialog.h | 63 ++ src/panels/information/kmetadatawidget.cpp | 672 +++++++++++++++++++ src/panels/information/kmetadatawidget.h | 129 ++++ src/panels/information/ktaggingwidget.cpp | 109 ++++ src/panels/information/ktaggingwidget_p.h | 54 ++ .../information/metadataconfigurationdialog.cpp | 278 -------- .../information/metadataconfigurationdialog.h | 62 -- src/panels/information/metadatawidget.cpp | 709 --------------------- src/panels/information/metadatawidget.h | 202 ------ src/panels/information/taggingwidget.cpp | 110 ---- src/panels/information/taggingwidget_p.h | 52 -- 24 files changed, 1720 insertions(+), 1834 deletions(-) delete mode 100644 src/panels/information/commentwidget.cpp delete mode 100644 src/panels/information/commentwidget_p.h delete mode 100644 src/panels/information/edittagsdialog.cpp delete mode 100644 src/panels/information/edittagsdialog_p.h create mode 100644 src/panels/information/kcommentwidget.cpp create mode 100644 src/panels/information/kcommentwidget_p.h create mode 100644 src/panels/information/kedittagsdialog.cpp create mode 100644 src/panels/information/kedittagsdialog_p.h create mode 100644 src/panels/information/kmetadataconfigurationdialog.cpp create mode 100644 src/panels/information/kmetadataconfigurationdialog.h create mode 100644 src/panels/information/kmetadatawidget.cpp create mode 100644 src/panels/information/kmetadatawidget.h create mode 100644 src/panels/information/ktaggingwidget.cpp create mode 100644 src/panels/information/ktaggingwidget_p.h delete mode 100644 src/panels/information/metadataconfigurationdialog.cpp delete mode 100644 src/panels/information/metadataconfigurationdialog.h delete mode 100644 src/panels/information/metadatawidget.cpp delete mode 100644 src/panels/information/metadatawidget.h delete mode 100644 src/panels/information/taggingwidget.cpp delete mode 100644 src/panels/information/taggingwidget_p.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ea6bda63a..f34367854 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -112,8 +112,8 @@ set(dolphin_SRCS pixmapviewer.cpp panels/information/informationpanel.cpp panels/information/informationpanelcontent.cpp - panels/information/metadatawidget.cpp - panels/information/metadataconfigurationdialog.cpp + panels/information/kmetadatawidget.cpp + panels/information/kmetadataconfigurationdialog.cpp panels/information/phononwidget.cpp panels/folders/ktreeview.cpp panels/places/placespanel.cpp @@ -157,10 +157,10 @@ kde4_add_kcfg_files(dolphin_SRCS if(Nepomuk_FOUND) set(dolphin_SRCS ${dolphin_SRCS} - panels/information/commentwidget.cpp - panels/information/edittagsdialog.cpp + panels/information/kcommentwidget.cpp + panels/information/kedittagsdialog.cpp panels/information/nepomukmassupdatejob.cpp - panels/information/taggingwidget.cpp + panels/information/ktaggingwidget.cpp ) endif(Nepomuk_FOUND) diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp index e82b42483..000e9ce6e 100644 --- a/src/dolphinmainwindow.cpp +++ b/src/dolphinmainwindow.cpp @@ -35,7 +35,6 @@ #include "panels/folders/folderspanel.h" #include "panels/places/placespanel.h" #include "panels/information/informationpanel.h" -#include "panels/information/metadatawidget.h" #include "mainwindowadaptor.h" #include "statusbar/dolphinstatusbar.h" #include "viewproperties.h" diff --git a/src/panels/information/commentwidget.cpp b/src/panels/information/commentwidget.cpp deleted file mode 100644 index 06a4c33be..000000000 --- a/src/panels/information/commentwidget.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sebastian Trueg * - * Copyright (C) 2009 by Peter Penz * - * * - * 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 "commentwidget_p.h" - -#include -#include -#include - -#include -#include -#include - -CommentWidget::CommentWidget(QWidget* parent) : - QWidget(parent), - m_label(0), - m_comment() -{ - m_label = new QLabel(this); - m_label->setFont(KGlobalSettings::smallestReadableFont()); - m_label->setWordWrap(true); - m_label->setAlignment(Qt::AlignTop); - connect(m_label, SIGNAL(linkActivated(const QString&)), this, SLOT(slotLinkActivated(const QString&))); - - QVBoxLayout* layout = new QVBoxLayout(this); - layout->setMargin(0); - 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(this, 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(KGlobal::config(), "Nepomuk 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); -} - -#include "commentwidget_p.moc" diff --git a/src/panels/information/commentwidget_p.h b/src/panels/information/commentwidget_p.h deleted file mode 100644 index 3985487d5..000000000 --- a/src/panels/information/commentwidget_p.h +++ /dev/null @@ -1,51 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sebastian Trueg * - * Copyright (C) 2009 by Peter Penz * - * * - * 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 COMMENT_WIDGET -#define COMMENT_WIDGET - -#include -#include - -class QLabel; - -class CommentWidget : public QWidget -{ - Q_OBJECT - -public: - CommentWidget(QWidget* parent); - virtual ~CommentWidget(); - - void setText(const QString& comment); - QString text() const; - -signals: - void commentChanged(const QString& comment); - -private slots: - void slotLinkActivated(const QString& link); - -private: - QLabel* m_label; - QString m_comment; -}; - -#endif diff --git a/src/panels/information/edittagsdialog.cpp b/src/panels/information/edittagsdialog.cpp deleted file mode 100644 index c3b3efcad..000000000 --- a/src/panels/information/edittagsdialog.cpp +++ /dev/null @@ -1,180 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Peter Penz * - * * - * 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 -#include - -#include -#include -#include -#include -#include - -EditTagsDialog::EditTagsDialog(const QList& tags, - QWidget* parent, - Qt::WFlags flags) : - KDialog(parent, flags), - m_tags(tags), - m_tagsList(0), - m_newTagItem(0), - m_newTagEdit(0) -{ - - 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); - - QWidget* mainWidget = new QWidget(this); - QVBoxLayout* topLayout = new QVBoxLayout(mainWidget); - - QLabel* label = new QLabel(i18nc("@label:textbox", - "Configure which tags should " - "be applied."), this); - - m_tagsList = new QListWidget(this); - m_tagsList->setSortingEnabled(true); - m_tagsList->setSelectionMode(QAbstractItemView::NoSelection); - - QLabel* newTagLabel = new QLabel(i18nc("@label", "Create new tag:")); - m_newTagEdit = new KLineEdit(this); - m_newTagEdit->setClearButtonShown(true); - connect(m_newTagEdit, SIGNAL(textEdited(const QString&)), - this, SLOT(slotTextEdited(const QString&))); - - QHBoxLayout* newTagLayout = new QHBoxLayout(); - newTagLayout->addWidget(newTagLabel); - newTagLayout->addWidget(m_newTagEdit, 1); - - topLayout->addWidget(label); - topLayout->addWidget(m_tagsList); - topLayout->addLayout(newTagLayout); - - setMainWidget(mainWidget); - - loadTags(); -} - -EditTagsDialog::~EditTagsDialog() -{ -} - -QList EditTagsDialog::tags() const -{ - return m_tags; -} - -void EditTagsDialog::slotButtonClicked(int button) -{ - if (button == KDialog::Ok) { - // update m_tags with the checked values, so - // that the caller of the EditTagsDialog can - // receive the tags by EditTagsDialog::tags() - m_tags.clear(); - - const int count = m_tagsList->count(); - for (int i = 0; i < count; ++i) { - QListWidgetItem* item = m_tagsList->item(i); - if (item->checkState() == Qt::Checked) { - const QString label = item->data(Qt::UserRole).toString(); - Nepomuk::Tag tag(label); - tag.setLabel(label); - m_tags.append(tag); - } - } - - accept(); - } else { - KDialog::slotButtonClicked(button); - } -} - -void EditTagsDialog::slotTextEdited(const QString& text) -{ - // Remove unnecessary spaces from a new tag is - // mandatory, as the user cannot see the difference - // between a tag "Test" and "Test ". - const QString tagText = text.simplified(); - if (tagText.isEmpty()) { - removeNewTagItem(); - return; - } - - // Check whether the new tag already exists. If this - // is the case, remove the new tag item. - const int count = m_tagsList->count(); - for (int i = 0; i < count; ++i) { - const QListWidgetItem* item = m_tagsList->item(i); - const bool remove = (item->text() == tagText) && - ((m_newTagItem == 0) || (m_newTagItem != item)); - if (remove) { - m_tagsList->scrollToItem(item); - removeNewTagItem(); - return; - } - } - - // There is no tag in the list with the the passed text. - if (m_newTagItem == 0) { - m_newTagItem = new QListWidgetItem(tagText, m_tagsList); - } else { - m_newTagItem->setText(tagText); - } - m_newTagItem->setData(Qt::UserRole, tagText); - m_newTagItem->setCheckState(Qt::Checked); - m_tagsList->scrollToItem(m_newTagItem); -} - -void EditTagsDialog::loadTags() -{ - // load all available tags and mark those tags as checked - // that have been passed to the EditTagsDialog - QList tags = Nepomuk::Tag::allTags(); - foreach (const Nepomuk::Tag& tag, tags) { - const QString label = tag.label(); - - QListWidgetItem* item = new QListWidgetItem(label, m_tagsList); - item->setData(Qt::UserRole, label); - - bool check = false; - foreach (const Nepomuk::Tag& selectedTag, m_tags) { - if (selectedTag.label() == label) { - check = true; - break; - } - } - item->setCheckState(check ? Qt::Checked : Qt::Unchecked); - } -} - -void EditTagsDialog::removeNewTagItem() -{ - if (m_newTagItem != 0) { - const int row = m_tagsList->row(m_newTagItem); - m_tagsList->takeItem(row); - delete m_newTagItem; - m_newTagItem = 0; - } -} - -#include "edittagsdialog_p.moc" diff --git a/src/panels/information/edittagsdialog_p.h b/src/panels/information/edittagsdialog_p.h deleted file mode 100644 index f72d5d84d..000000000 --- a/src/panels/information/edittagsdialog_p.h +++ /dev/null @@ -1,67 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Peter Penz * - * * - * 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 - -#include - -class KLineEdit; -class QListWidget; -class QListWidgetItem; - -/** - * @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& tags, - QWidget* parent = 0, - Qt::WFlags flags = 0); - - virtual ~EditTagsDialog(); - - QList tags() const; - -protected slots: - virtual void slotButtonClicked(int button); - -private slots: - void slotTextEdited(const QString& text); - -private: - void loadTags(); - void removeNewTagItem(); - -private: - QList m_tags; - QListWidget* m_tagsList; - QListWidgetItem* m_newTagItem; - KLineEdit* m_newTagEdit; -}; - -#endif diff --git a/src/panels/information/informationpanelcontent.cpp b/src/panels/information/informationpanelcontent.cpp index 854af58ef..831a6e78b 100644 --- a/src/panels/information/informationpanelcontent.cpp +++ b/src/panels/information/informationpanelcontent.cpp @@ -47,21 +47,11 @@ #include "dolphin_informationpanelsettings.h" #include "settings/dolphinsettings.h" -#include "metadatawidget.h" -#include "metadataconfigurationdialog.h" +#include "kmetadatawidget.h" +#include "kmetadataconfigurationdialog.h" #include "phononwidget.h" #include "pixmapviewer.h" -/** - * Helper function for sorting items with qSort() in - * InformationPanelContent::contextMenu(). - */ -bool lessThan(const QAction* action1, const QAction* action2) -{ - return action1->text() < action2->text(); -} - - InformationPanelContent::InformationPanelContent(QWidget* parent) : Panel(parent), m_item(), @@ -117,7 +107,7 @@ InformationPanelContent::InformationPanelContent(QWidget* parent) : m_preview->setVisible(showPreview); m_previewSeparator->setVisible(showPreview); - m_metaDataWidget = new MetaDataWidget(parent); + m_metaDataWidget = new KMetaDataWidget(parent); m_metaDataWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); // Encapsulate the MetaDataWidget inside a container that has a dummy widget @@ -302,7 +292,7 @@ void InformationPanelContent::configureSettings() m_previewSeparator->setVisible(isChecked); InformationPanelSettings::setShowPreview(isChecked); } else if (action == configureAction) { - MetaDataConfigurationDialog dialog(m_metaDataWidget, this, Qt::Dialog); + KMetaDataConfigurationDialog dialog(m_metaDataWidget, this, Qt::Dialog); dialog.exec(); } diff --git a/src/panels/information/informationpanelcontent.h b/src/panels/information/informationpanelcontent.h index 63948fd4f..9c17b9397 100644 --- a/src/panels/information/informationpanelcontent.h +++ b/src/panels/information/informationpanelcontent.h @@ -26,14 +26,14 @@ #include #include +class KFileItem; +class KMetaDataWidget; +class KSeparator; +class MetaTextLabel; class PhononWidget; class PixmapViewer; -class MetaDataWidget; -class MetaTextLabel; class QPixmap; class QString; -class KFileItem; -class KSeparator; class QLabel; class QScrollArea; @@ -120,7 +120,7 @@ private: PixmapViewer* m_preview; KSeparator* m_previewSeparator; PhononWidget* m_phononWidget; - MetaDataWidget* m_metaDataWidget; + KMetaDataWidget* m_metaDataWidget; QScrollArea* m_metaDataArea; }; diff --git a/src/panels/information/kcommentwidget.cpp b/src/panels/information/kcommentwidget.cpp new file mode 100644 index 000000000..770b6c10c --- /dev/null +++ b/src/panels/information/kcommentwidget.cpp @@ -0,0 +1,97 @@ +/***************************************************************************** + * Copyright (C) 2008 by Sebastian Trueg * + * Copyright (C) 2009 by Peter Penz * + * * + * 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 "kcommentwidget_p.h" + +#include +#include +#include + +#include +#include +#include + +KCommentWidget::KCommentWidget(QWidget* parent) : + QWidget(parent), + m_label(0), + m_comment() +{ + m_label = new QLabel(this); + m_label->setFont(KGlobalSettings::smallestReadableFont()); + m_label->setWordWrap(true); + m_label->setAlignment(Qt::AlignTop); + connect(m_label, SIGNAL(linkActivated(const QString&)), this, SLOT(slotLinkActivated(const QString&))); + + QVBoxLayout* layout = new QVBoxLayout(this); + layout->setMargin(0); + layout->addWidget(m_label); + + setText(m_comment); +} + +KCommentWidget::~KCommentWidget() +{ +} + +void KCommentWidget::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 KCommentWidget::text() const +{ + return m_comment; +} + +void KCommentWidget::slotLinkActivated(const QString& link) +{ + KDialog dialog(this, 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(KGlobal::config(), "Nepomuk KEditCommentDialog"); + 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); +} + +#include "kcommentwidget_p.moc" diff --git a/src/panels/information/kcommentwidget_p.h b/src/panels/information/kcommentwidget_p.h new file mode 100644 index 000000000..977531372 --- /dev/null +++ b/src/panels/information/kcommentwidget_p.h @@ -0,0 +1,53 @@ +/***************************************************************************** + * Copyright (C) 2008 by Sebastian Trueg * + * Copyright (C) 2009 by Peter Penz * + * * + * 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 KCOMMENT_WIDGET +#define KCOMMENT_WIDGET + +#include +#include + +class QLabel; + +/** + * @brief Allows to edit and show a comment as part of KMetaDataWidget. + */ +class KCommentWidget : public QWidget +{ + Q_OBJECT + +public: + KCommentWidget(QWidget* parent); + virtual ~KCommentWidget(); + + void setText(const QString& comment); + QString text() const; + +signals: + void commentChanged(const QString& comment); + +private slots: + void slotLinkActivated(const QString& link); + +private: + QLabel* m_label; + QString m_comment; +}; + +#endif diff --git a/src/panels/information/kedittagsdialog.cpp b/src/panels/information/kedittagsdialog.cpp new file mode 100644 index 000000000..4dfe0275d --- /dev/null +++ b/src/panels/information/kedittagsdialog.cpp @@ -0,0 +1,179 @@ +/***************************************************************************** + * Copyright (C) 2009 by Peter Penz * + * * + * 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 "kedittagsdialog_p.h" + +#include +#include + +#include +#include +#include +#include +#include + +KEditTagsDialog::KEditTagsDialog(const QList& tags, + QWidget* parent, + Qt::WFlags flags) : + KDialog(parent, flags), + m_tags(tags), + m_tagsList(0), + m_newTagItem(0), + m_newTagEdit(0) +{ + + 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); + + QWidget* mainWidget = new QWidget(this); + QVBoxLayout* topLayout = new QVBoxLayout(mainWidget); + + QLabel* label = new QLabel(i18nc("@label:textbox", + "Configure which tags should " + "be applied."), this); + + m_tagsList = new QListWidget(this); + m_tagsList->setSortingEnabled(true); + m_tagsList->setSelectionMode(QAbstractItemView::NoSelection); + + QLabel* newTagLabel = new QLabel(i18nc("@label", "Create new tag:")); + m_newTagEdit = new KLineEdit(this); + m_newTagEdit->setClearButtonShown(true); + connect(m_newTagEdit, SIGNAL(textEdited(const QString&)), + this, SLOT(slotTextEdited(const QString&))); + + QHBoxLayout* newTagLayout = new QHBoxLayout(); + newTagLayout->addWidget(newTagLabel); + newTagLayout->addWidget(m_newTagEdit, 1); + + topLayout->addWidget(label); + topLayout->addWidget(m_tagsList); + topLayout->addLayout(newTagLayout); + + setMainWidget(mainWidget); + + loadTags(); +} + +KEditTagsDialog::~KEditTagsDialog() +{ +} + +QList KEditTagsDialog::tags() const +{ + return m_tags; +} + +void KEditTagsDialog::slotButtonClicked(int button) +{ + if (button == KDialog::Ok) { + // update m_tags with the checked values, so + // that the caller of the KEditTagsDialog can + // receive the tags by KEditTagsDialog::tags() + m_tags.clear(); + + const int count = m_tagsList->count(); + for (int i = 0; i < count; ++i) { + QListWidgetItem* item = m_tagsList->item(i); + if (item->checkState() == Qt::Checked) { + const QString label = item->data(Qt::UserRole).toString(); + Nepomuk::Tag tag(label); + tag.setLabel(label); + m_tags.append(tag); + } + } + + accept(); + } else { + KDialog::slotButtonClicked(button); + } +} + +void KEditTagsDialog::slotTextEdited(const QString& text) +{ + // Remove unnecessary spaces from a new tag is + // mandatory, as the user cannot see the difference + // between a tag "Test" and "Test ". + const QString tagText = text.simplified(); + if (tagText.isEmpty()) { + removeNewTagItem(); + return; + } + + // Check whether the new tag already exists. If this + // is the case, remove the new tag item. + const int count = m_tagsList->count(); + for (int i = 0; i < count; ++i) { + const QListWidgetItem* item = m_tagsList->item(i); + const bool remove = (item->text() == tagText) && + ((m_newTagItem == 0) || (m_newTagItem != item)); + if (remove) { + m_tagsList->scrollToItem(item); + removeNewTagItem(); + return; + } + } + + // There is no tag in the list with the the passed text. + if (m_newTagItem == 0) { + m_newTagItem = new QListWidgetItem(tagText, m_tagsList); + } else { + m_newTagItem->setText(tagText); + } + m_newTagItem->setData(Qt::UserRole, tagText); + m_newTagItem->setCheckState(Qt::Checked); + m_tagsList->scrollToItem(m_newTagItem); +} + +void KEditTagsDialog::loadTags() +{ + // load all available tags and mark those tags as checked + // that have been passed to the KEditTagsDialog + QList tags = Nepomuk::Tag::allTags(); + foreach (const Nepomuk::Tag& tag, tags) { + const QString label = tag.label(); + + QListWidgetItem* item = new QListWidgetItem(label, m_tagsList); + item->setData(Qt::UserRole, label); + + bool check = false; + foreach (const Nepomuk::Tag& selectedTag, m_tags) { + if (selectedTag.label() == label) { + check = true; + break; + } + } + item->setCheckState(check ? Qt::Checked : Qt::Unchecked); + } +} + +void KEditTagsDialog::removeNewTagItem() +{ + if (m_newTagItem != 0) { + const int row = m_tagsList->row(m_newTagItem); + m_tagsList->takeItem(row); + delete m_newTagItem; + m_newTagItem = 0; + } +} + +#include "kedittagsdialog_p.moc" diff --git a/src/panels/information/kedittagsdialog_p.h b/src/panels/information/kedittagsdialog_p.h new file mode 100644 index 000000000..d85bcf9da --- /dev/null +++ b/src/panels/information/kedittagsdialog_p.h @@ -0,0 +1,67 @@ +/***************************************************************************** + * Copyright (C) 2009 by Peter Penz * + * * + * 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 KEDIT_TAGS_DIALOG_H +#define KEDIT_TAGS_DIALOG_H + +#include +#include + +class KLineEdit; +class QListWidget; +class QListWidgetItem; + +/** + * @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. + * + * @see KMetaDataConfigurationDialog + */ +class KEditTagsDialog : public KDialog +{ + Q_OBJECT + +public: + KEditTagsDialog(const QList& tags, + QWidget* parent = 0, + Qt::WFlags flags = 0); + + virtual ~KEditTagsDialog(); + + QList tags() const; + +protected slots: + virtual void slotButtonClicked(int button); + +private slots: + void slotTextEdited(const QString& text); + +private: + void loadTags(); + void removeNewTagItem(); + +private: + QList m_tags; + QListWidget* m_tagsList; + QListWidgetItem* m_newTagItem; + KLineEdit* m_newTagEdit; +}; + +#endif diff --git a/src/panels/information/kmetadataconfigurationdialog.cpp b/src/panels/information/kmetadataconfigurationdialog.cpp new file mode 100644 index 000000000..bbe437139 --- /dev/null +++ b/src/panels/information/kmetadataconfigurationdialog.cpp @@ -0,0 +1,283 @@ +/***************************************************************************** + * Copyright (C) 2009 by Peter Penz * + * * + * 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 "kmetadataconfigurationdialog.h" +#include "kmetadatawidget.h" +#include + +#include +#ifdef HAVE_NEPOMUK + #define DISABLE_NEPOMUK_LEGACY + #include + #include + #include + #include +#endif + +#include +#include +#include + +class KMetaDataConfigurationDialog::Private +{ +public: + Private(KMetaDataConfigurationDialog* parent, KMetaDataWidget* metaDataWidget); + ~Private(); + + void init(); + void loadMetaData(); + QString tunedLabel(const QString& label) const; + + int m_visibleDataTypes; + KMetaDataWidget* m_metaDataWidget; + QListWidget* m_metaDataList; + +private: + KMetaDataConfigurationDialog* const q; +}; + +KMetaDataConfigurationDialog::Private::Private(KMetaDataConfigurationDialog* parent, + KMetaDataWidget* metaDataWidget) : + q(parent) +{ + m_visibleDataTypes = 0; + m_metaDataWidget = metaDataWidget; + + q->setCaption(i18nc("@title:window", "Configure Shown Data")); + q->setButtons(KDialog::Ok | KDialog::Cancel); + q->setDefaultButton(KDialog::Ok); + + QWidget* mainWidget = new QWidget(q); + QVBoxLayout* topLayout = new QVBoxLayout(mainWidget); + + QLabel* label = new QLabel(i18nc("@label:textbox", + "Configure which data should " + "be shown."), q); + + m_metaDataList = new QListWidget(q); + m_metaDataList->setSelectionMode(QAbstractItemView::NoSelection); + + topLayout->addWidget(label); + topLayout->addWidget(m_metaDataList); + + q->setMainWidget(mainWidget); + + loadMetaData(); + + const KConfigGroup dialogConfig(KGlobal::config(), "Nepomuk KMetaDataConfigurationDialog"); + q->restoreDialogSize(dialogConfig); +} + +KMetaDataConfigurationDialog::Private::~Private() +{ + KConfigGroup dialogConfig(KGlobal::config(), "Nepomuk KMetaDataConfigurationDialog"); + q->saveDialogSize(dialogConfig, KConfigBase::Persistent); +} + +void KMetaDataConfigurationDialog::Private::loadMetaData() +{ + KConfig config("kmetainformationrc", KConfig::NoGlobals); + KConfigGroup settings = config.group("Show"); + + // Add fixed meta data items where the visibility does not + // depend on the currently used URL. + KMetaDataWidget::MetaDataTypes visibleDataTypes = KMetaDataWidget::TypeData | + KMetaDataWidget::SizeData | + KMetaDataWidget::ModifiedData | + KMetaDataWidget::OwnerData | + KMetaDataWidget::PermissionsData | + KMetaDataWidget::RatingData | + KMetaDataWidget::TagsData | + KMetaDataWidget::CommentData; + if (m_metaDataWidget != 0) { + visibleDataTypes = m_metaDataWidget->visibleDataTypes(); + } + + typedef QPair FixedItem; + QList fixedItems; + if (visibleDataTypes & KMetaDataWidget::TypeData) { + fixedItems.append(FixedItem("type", i18nc("@item::inlistbox", "Type"))); + } + if (visibleDataTypes & KMetaDataWidget::SizeData) { + fixedItems.append(FixedItem("size", i18nc("@item::inlistbox", "Size"))); + } + if (visibleDataTypes & KMetaDataWidget::ModifiedData) { + fixedItems.append(FixedItem("modified", i18nc("@item::inlistbox", "Modified"))); + } + if (visibleDataTypes & KMetaDataWidget::OwnerData) { + fixedItems.append(FixedItem("owner", i18nc("@item::inlistbox", "Owner"))); + } + if (visibleDataTypes & KMetaDataWidget::PermissionsData) { + fixedItems.append(FixedItem("permissions", i18nc("@item::inlistbox", "Permissions"))); + } +#ifdef HAVE_NEPOMUK + if (Nepomuk::ResourceManager::instance()->init() == 0) { + if (visibleDataTypes & KMetaDataWidget::RatingData) { + fixedItems.append(FixedItem("rating", i18nc("@item::inlistbox", "Rating"))); + } + if (visibleDataTypes & KMetaDataWidget::TagsData) { + fixedItems.append(FixedItem("tags", i18nc("@item::inlistbox", "Tags"))); + } + if (visibleDataTypes & KMetaDataWidget::CommentData) { + fixedItems.append(FixedItem("comment", i18nc("@item::inlistbox", "Comment"))); + } + } +#endif + + foreach (const FixedItem& fixedItem, fixedItems) { + const QString key = fixedItem.first; + const QString label = fixedItem.second; + QListWidgetItem* item = new QListWidgetItem(label, m_metaDataList); + item->setData(Qt::UserRole, key); + const bool show = settings.readEntry(key, true); + item->setCheckState(show ? Qt::Checked : Qt::Unchecked); + } + +#ifdef HAVE_NEPOMUK + if (Nepomuk::ResourceManager::instance()->init() != 0) { + return; + } + + // Get all meta information labels that are available for + // the currently shown file item and add them to the list. + if (m_metaDataWidget == 0) { + // TODO: in this case all available meta data from the system + // should be added. + return; + } + + const KFileItemList items = m_metaDataWidget->items(); + if (items.count() != 1) { + // TODO: handle als usecases for more than one item: + return; + } + Nepomuk::Resource res(items.first().nepomukUri()); + + QHash properties = res.properties(); + QHash::const_iterator it = properties.constBegin(); + while (it != properties.constEnd()) { + Nepomuk::Types::Property prop(it.key()); + const QString key = prop.name(); + + // Meta information provided by Nepomuk that is already + // available from KFileItem as "fixed item" (see above) + // should not be shown as second entry. + static const char* hiddenProperties[] = { + "contentSize", // = fixed item "size" + "description", // = fixed item "comment" + "fileExtension", // ~ fixed item "type" + "hasTag", // = fixed item "tags" + "name", // not shown as part of the meta data widget + "lastModified", // = fixed item "modified" + "size", // = fixed item "size" + "mimeType", // = fixed item "type" + "numericRating", // = fixed item "rating" + 0 // mandatory last entry + }; + bool skip = false; + int i = 0; + while (hiddenProperties[i] != 0) { + if (key == hiddenProperties[i]) { + skip = true; + break; + } + ++i; + } + + if (!skip) { + // TODO #1: use Nepomuk::formatValue(res, prop) if available + // instead of it.value().toString() + // TODO #2: using tunedLabel() is a workaround for KDE 4.3 (4.4?) until + // we get translated labels + const QString label = tunedLabel(prop.label()); + QListWidgetItem* item = new QListWidgetItem(label, m_metaDataList); + item->setData(Qt::UserRole, key); + const bool show = settings.readEntry(key, true); + item->setCheckState(show ? Qt::Checked : Qt::Unchecked); + } + + ++it; + } +#endif +} + +QString KMetaDataConfigurationDialog::Private::tunedLabel(const QString& label) const +{ + QString tunedLabel; + const int labelLength = label.length(); + if (labelLength > 0) { + tunedLabel.reserve(labelLength); + tunedLabel = label[0].toUpper(); + for (int i = 1; i < labelLength; ++i) { + if (label[i].isUpper() && !label[i - 1].isSpace() && !label[i - 1].isUpper()) { + tunedLabel += ' '; + tunedLabel += label[i].toLower(); + } else { + tunedLabel += label[i]; + } + } + } + return tunedLabel; +} + +KMetaDataConfigurationDialog::KMetaDataConfigurationDialog(QWidget* parent, + Qt::WFlags flags) : + KDialog(parent, flags), + d(new Private(this, 0)) +{ +} + +KMetaDataConfigurationDialog::KMetaDataConfigurationDialog(KMetaDataWidget* metaDataWidget, + QWidget* parent, + Qt::WFlags flags) : + KDialog(parent, flags), + d(new Private(this, metaDataWidget)) +{ +} + +KMetaDataConfigurationDialog::~KMetaDataConfigurationDialog() +{ +} + +void KMetaDataConfigurationDialog::slotButtonClicked(int button) +{ + if (button == KDialog::Ok) { + KConfig config("kmetainformationrc", KConfig::NoGlobals); + KConfigGroup showGroup = config.group("Show"); + + const int count = d->m_metaDataList->count(); + for (int i = 0; i < count; ++i) { + QListWidgetItem* item = d->m_metaDataList->item(i); + const bool show = (item->checkState() == Qt::Checked); + const QString key = item->data(Qt::UserRole).toString(); + showGroup.writeEntry(key, show); + } + + showGroup.sync(); + + if (d->m_metaDataWidget != 0) { + // trigger an update + d->m_metaDataWidget->setVisibleDataTypes(d->m_metaDataWidget->visibleDataTypes()); + } + accept(); + } else { + KDialog::slotButtonClicked(button); + } +} + +#include "kmetadataconfigurationdialog.moc" diff --git a/src/panels/information/kmetadataconfigurationdialog.h b/src/panels/information/kmetadataconfigurationdialog.h new file mode 100644 index 000000000..98579d751 --- /dev/null +++ b/src/panels/information/kmetadataconfigurationdialog.h @@ -0,0 +1,63 @@ +/***************************************************************************** + * Copyright (C) 2009 by Peter Penz * + * * + * 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 KMETA_DATA_CONFIGURATION_DIALOG_H +#define KMETA_DATA_CONFIGURATION_DIALOG_H + +#include +#include + +class KMetaDataWidget; + +/** + * @brief Dialog which allows to configure which meta data should be shown. + * @see KMetaDataWidget + */ +class KFILE_EXPORT KMetaDataConfigurationDialog : public KDialog +{ + Q_OBJECT + +public: + /** + * Allows to configure the visibility of all available meta + * data. + */ + KMetaDataConfigurationDialog(QWidget* parent = 0, + Qt::WFlags flags = 0); + + /** + * Allows to configure the visibility of the meta data + * shown by the meta data widget. The number of offered + * meta data is optimized for the set of file items + * that are applied to the meta data widget. + */ + KMetaDataConfigurationDialog(KMetaDataWidget* metaDataWidget, + QWidget* parent = 0, + Qt::WFlags flags = 0); + + virtual ~KMetaDataConfigurationDialog(); + +protected slots: + virtual void slotButtonClicked(int button); + +private: + class Private; + Private* d; +}; + +#endif diff --git a/src/panels/information/kmetadatawidget.cpp b/src/panels/information/kmetadatawidget.cpp new file mode 100644 index 000000000..fd2f237dd --- /dev/null +++ b/src/panels/information/kmetadatawidget.cpp @@ -0,0 +1,672 @@ +/***************************************************************************** + * Copyright (C) 2008 by Sebastian Trueg * + * Copyright (C) 2009 by Peter Penz * + * * + * 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 "kmetadatawidget.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#ifdef HAVE_NEPOMUK + #define DISABLE_NEPOMUK_LEGACY + + #include "kcommentwidget_p.h" + #include "ktaggingwidget_p.h" + + #include + #include + #include + #include + #include + #include "nepomukmassupdatejob_p.h" + + #include + #include + #include +#endif + +class KMetaDataWidget::Private +{ +public: + struct Row + { + QLabel* label; + QWidget* infoWidget; + }; + + Private(KMetaDataWidget* parent); + ~Private(); + + void addRow(QLabel* label, QWidget* infoWidget); + void removeMetaInfoRows(); + void setRowVisible(QWidget* infoWidget, bool visible); + + /** + * Initializes the configuration file "kmetainformationrc" + * with proper default settings for the first start in + * an uninitialized environment. + */ + void initMetaInfoSettings(); + + /** + * Parses the configuration file "kmetainformationrc" and + * updates the visibility of all rows. + */ + void updateRowsVisibility(); + + void slotLoadingFinished(); + void slotRatingChanged(unsigned int rating); + void slotTagsChanged(const QList& 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); + + bool m_isSizeVisible; + MetaDataTypes m_visibleDataTypes; + QList m_fileItems; + QList m_rows; + + QGridLayout* m_gridLayout; + + QLabel* m_typeInfo; + QLabel* m_sizeLabel; + QLabel* m_sizeInfo; + QLabel* m_modifiedInfo; + QLabel* m_ownerInfo; + QLabel* m_permissionsInfo; + +#ifdef HAVE_NEPOMUK + KRatingWidget* m_ratingWidget; + KTaggingWidget* m_taggingWidget; + KCommentWidget* m_commentWidget; + + // shared data between the GUI-thread and + // the loader-thread (see LoadFilesThread): + QMutex m_mutex; + struct SharedData + { + int rating; + QString comment; + QList tags; + QList metaInfoLabels; + QList metaInfoValues; + QMap files; + } m_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* m_sharedData, QMutex* m_mutex); + virtual ~LoadFilesThread(); + void loadFiles(const KUrl::List& urls); + virtual void run(); + + private: + /** + * Assures that the settings for the meta information + * are initialized with proper default values. + */ + void initMetaInfoSettings(KConfigGroup& group); + + /** + * Temporary helper method for KDE 4.3 as we currently don't get + * translated labels for Nepmok literals: Replaces camelcase labels + * like "fileLocation" by "File Location:". + */ + QString tunedLabel(const QString& label) const; + + private: + SharedData* m_sharedData; + QMutex* m_mutex; + KUrl::List m_urls; + bool m_canceled; + }; + + LoadFilesThread* m_loadFilesThread; +#endif + +private: + KMetaDataWidget* const q; +}; + +KMetaDataWidget::Private::Private(KMetaDataWidget* parent) : + m_isSizeVisible(true), + m_visibleDataTypes(TypeData | SizeData | ModifiedData | OwnerData | + PermissionsData | RatingData | TagsData | CommentData), + m_fileItems(), + m_rows(), + m_gridLayout(0), + m_typeInfo(0), + m_sizeLabel(0), + m_sizeInfo(0), + m_modifiedInfo(0), + m_ownerInfo(0), + m_permissionsInfo(0), +#ifdef HAVE_NEPOMUK + m_ratingWidget(0), + m_taggingWidget(0), + m_commentWidget(0), + m_loadFilesThread(0), +#endif + q(parent) +{ + m_gridLayout = new QGridLayout(parent); + m_gridLayout->setMargin(0); + + 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); + + 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); + +#ifdef HAVE_NEPOMUK + if (Nepomuk::ResourceManager::instance()->init() == 0) { + 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 KTaggingWidget(parent); + connect(m_taggingWidget, SIGNAL(tagsChanged(const QList&)), + q, SLOT(slotTagsChanged(const QList&))); + + m_commentWidget = new KCommentWidget(parent); + connect(m_commentWidget, SIGNAL(commentChanged(const QString&)), + q, SLOT(slotCommentChanged(const QString&))); + + 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); + + m_loadFilesThread = new LoadFilesThread(&m_sharedData, &m_mutex); + connect(m_loadFilesThread, SIGNAL(finished()), q, SLOT(slotLoadingFinished())); + } + + m_sharedData.rating = 0; +#endif + + initMetaInfoSettings(); + updateRowsVisibility(); +} + +KMetaDataWidget::Private::~Private() +{ +#ifdef HAVE_NEPOMUK + delete m_loadFilesThread; +#endif +} + +void KMetaDataWidget::Private::addRow(QLabel* label, QWidget* infoWidget) +{ + Row row; + row.label = label; + row.infoWidget = infoWidget; + m_rows.append(row); + + const QFont smallFont = KGlobalSettings::smallestReadableFont(); + // use a brighter color for the label and a small font size + QPalette palette = label->palette(); + QColor textColor = palette.color(QPalette::Text); + textColor.setAlpha(128); + palette.setColor(QPalette::WindowText, textColor); + label->setPalette(palette); + label->setFont(smallFont); + label->setWordWrap(true); + label->setAlignment(Qt::AlignTop | Qt::AlignRight); + + QLabel* infoLabel = qobject_cast(infoWidget); + if (infoLabel != 0) { + infoLabel->setFont(smallFont); + infoLabel->setWordWrap(true); + infoLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft); + } + + // add the row to grid layout + const int rowIndex = m_rows.count(); + m_gridLayout->addWidget(label, rowIndex, 0, Qt::AlignRight); + const int spacerWidth = QFontMetrics(smallFont).size(Qt::TextSingleLine, " ").width(); + m_gridLayout->addItem(new QSpacerItem(spacerWidth, 1), rowIndex, 1); + m_gridLayout->addWidget(infoWidget, rowIndex, 2, Qt::AlignLeft); +} + +void KMetaDataWidget::Private::setRowVisible(QWidget* infoWidget, bool visible) +{ + foreach (const Row& row, m_rows) { + if (row.infoWidget == infoWidget) { + row.label->setVisible(visible); + row.infoWidget->setVisible(visible); + return; + } + } +} + + +void KMetaDataWidget::Private::initMetaInfoSettings() +{ + KConfig config("kmetainformationrc", KConfig::NoGlobals); + KConfigGroup settings = config.group("Show"); + if (!settings.readEntry("initialized", false)) { + // The resource file is read the first time. Assure + // that some meta information is disabled per default. + + static const char* disabledProperties[] = { + "asText", "contentSize", "created", "depth", "description", "fileExtension", + "fileName", "fileSize", "hasTag", "isPartOf", "lastModified", "mimeType", "name", + "numericRating", "parentUrl", "permissions", "plainTextContent", "owner", + "sourceModified", "url", + 0 // mandatory last entry + }; + + int i = 0; + while (disabledProperties[i] != 0) { + settings.writeEntry(disabledProperties[i], false); + ++i; + } + + // mark the group as initialized + settings.writeEntry("initialized", true); + } +} + +void KMetaDataWidget::Private::updateRowsVisibility() +{ + KConfig config("kmetainformationrc", KConfig::NoGlobals); + KConfigGroup settings = config.group("Show"); + + setRowVisible(m_typeInfo, + (m_visibleDataTypes & KMetaDataWidget::TypeData) && + settings.readEntry("type", true)); + + // Cache in m_isSizeVisible whether the size should be shown. This + // is necessary as the size is temporary hidden when the target + // file item is a directory. + m_isSizeVisible = (m_visibleDataTypes & KMetaDataWidget::SizeData) && + settings.readEntry("size", true); + setRowVisible(m_sizeInfo, m_isSizeVisible); + + setRowVisible(m_modifiedInfo, + (m_visibleDataTypes & KMetaDataWidget::ModifiedData) && + settings.readEntry("modified", true)); + + setRowVisible(m_ownerInfo, + (m_visibleDataTypes & KMetaDataWidget::OwnerData) && + settings.readEntry("owner", true)); + + setRowVisible(m_permissionsInfo, + (m_visibleDataTypes & KMetaDataWidget::PermissionsData) && + settings.readEntry("permissions", true)); + +#ifdef HAVE_NEPOMUK + if (Nepomuk::ResourceManager::instance()->init() == 0) { + setRowVisible(m_ratingWidget, + (m_visibleDataTypes & KMetaDataWidget::RatingData) && + settings.readEntry("rating", true)); + + setRowVisible(m_taggingWidget, + (m_visibleDataTypes & KMetaDataWidget::TagsData) && + settings.readEntry("tags", true)); + + setRowVisible(m_commentWidget, + (m_visibleDataTypes & KMetaDataWidget::CommentData) && + settings.readEntry("comment", true)); + } +#endif +} + +void KMetaDataWidget::Private::slotLoadingFinished() +{ +#ifdef HAVE_NEPOMUK + QMutexLocker locker(&m_mutex); + m_ratingWidget->setRating(m_sharedData.rating); + m_commentWidget->setText(m_sharedData.comment); + m_taggingWidget->setTags(m_sharedData.tags); + + // Show the remaining meta information as text. The number + // of required rows may very. Existing rows are reused to + // prevent flickering. + int index = 8; // TODO: don't hardcode this value here + const int rowCount = m_rows.count(); + Q_ASSERT(rowCount >= index); + + Q_ASSERT(m_sharedData.metaInfoLabels.count() == m_sharedData.metaInfoValues.count()); + const int metaInfoCount = m_sharedData.metaInfoLabels.count(); + for (int i = 0; i < metaInfoCount; ++i) { + if (index < rowCount) { + // adjust texts of the current row + m_rows[index].label->setText(m_sharedData.metaInfoLabels[i]); + QLabel* infoValueLabel = qobject_cast(m_rows[index].infoWidget); + Q_ASSERT(infoValueLabel != 0); + infoValueLabel->setText(m_sharedData.metaInfoValues[i]); + } else { + // create new row + QLabel* infoLabel = new QLabel(m_sharedData.metaInfoLabels[i], q); + QLabel* infoValue = new QLabel(m_sharedData.metaInfoValues[i], q); + addRow(infoLabel, infoValue); + } + ++index; + } + if (metaInfoCount > 0) { + --index; + } + + // remove rows that are not needed anymore + for (int i = rowCount - 1; i > index; --i) { + delete m_rows[i].label; + delete m_rows[i].infoWidget; + m_rows.pop_back(); + } +#endif +} + +void KMetaDataWidget::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); +#endif +} + +void KMetaDataWidget::Private::slotTagsChanged(const QList& tags) +{ +#ifdef HAVE_NEPOMUK + m_taggingWidget->setTags(tags); + + QMutexLocker locker(&m_mutex); + Nepomuk::MassUpdateJob* job = + Nepomuk::MassUpdateJob::tagResources(m_sharedData.files.values(), tags); + locker.unlock(); + startChangeDataJob(job); +#endif +} + +void KMetaDataWidget::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); +#endif +} + +void KMetaDataWidget::Private::slotMetaDataUpdateDone() +{ + q->setEnabled(true); +} + +void KMetaDataWidget::Private::startChangeDataJob(KJob* job) +{ + connect(job, SIGNAL(result(KJob*)), + q, SLOT(slotMetaDataUpdateDone())); + q->setEnabled(false); // no updates during execution + job->start(); +} + +#ifdef HAVE_NEPOMUK +KMetaDataWidget::Private::LoadFilesThread::LoadFilesThread( + KMetaDataWidget::Private::SharedData* m_sharedData, + QMutex* m_mutex) : + m_sharedData(m_sharedData), + m_mutex(m_mutex), + m_urls(), + m_canceled(false) +{ +} + +KMetaDataWidget::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 KMetaDataWidget::Private::LoadFilesThread::loadFiles(const KUrl::List& urls) +{ + QMutexLocker locker(m_mutex); + m_urls = urls; + m_canceled = false; + start(); +} + +void KMetaDataWidget::Private::LoadFilesThread::run() +{ + QMutexLocker locker(m_mutex); + const KUrl::List urls = m_urls; + locker.unlock(); + + KConfig config("kmetainformationrc", KConfig::NoGlobals); + KConfigGroup settings = config.group("Show"); + + bool first = true; + unsigned int rating = 0; + QString comment; + QList tags; + QList metaInfoLabels; + QList metaInfoValues; + QMap files; + foreach (const KUrl& url, urls) { + if (m_canceled) { + return; + } + + Nepomuk::Resource file(url); + files.insert(url, 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(); + } + + if (first && (urls.count() == 1)) { + // TODO: show shared meta information instead + // of not showing anything on multiple selections + QHash properties = file.properties(); + QHash::const_iterator it = properties.constBegin(); + while (it != properties.constEnd()) { + Nepomuk::Types::Property prop(it.key()); + if (settings.readEntry(prop.name(), true)) { + // TODO #1: use Nepomuk::formatValue(res, prop) if available + // instead of it.value().toString() + // TODO #2: using tunedLabel() is a workaround for KDE 4.3 (4.4?) until + // we get translated labels + metaInfoLabels.append(tunedLabel(prop.label())); + metaInfoValues.append(it.value().toString()); + } + ++it; + } + } + + first = false; + } + + locker.relock(); + m_sharedData->rating = rating; + m_sharedData->comment = comment; + m_sharedData->tags = tags; + m_sharedData->metaInfoLabels = metaInfoLabels; + m_sharedData->metaInfoValues = metaInfoValues; + m_sharedData->files = files; +} + +QString KMetaDataWidget::Private::LoadFilesThread::tunedLabel(const QString& label) const +{ + QString tunedLabel; + const int labelLength = label.length(); + if (labelLength > 0) { + tunedLabel.reserve(labelLength); + tunedLabel = label[0].toUpper(); + for (int i = 1; i < labelLength; ++i) { + if (label[i].isUpper() && !label[i - 1].isSpace() && !label[i - 1].isUpper()) { + tunedLabel += ' '; + tunedLabel += label[i].toLower(); + } else { + tunedLabel += label[i]; + } + } + } + return tunedLabel + ':'; +} + +#endif // HAVE_NEPOMUK + +KMetaDataWidget::KMetaDataWidget(QWidget* parent) : + QWidget(parent), + d(new Private(this)) +{ +} + +KMetaDataWidget::~KMetaDataWidget() +{ + delete d; +} + +void KMetaDataWidget::setItem(const KFileItem& item) +{ + // update values for "type", "size", "modified", + // "owner" and "permissions" synchronously + d->m_sizeLabel->setText(i18nc("@label", "Size:")); + if (item.isDir()) { + d->m_typeInfo->setText(i18nc("@label", "Folder")); + d->setRowVisible(d->m_sizeInfo, false); + } else { + d->m_typeInfo->setText(item.mimeComment()); + d->m_sizeInfo->setText(KIO::convertSize(item.size())); + d->setRowVisible(d->m_sizeInfo, d->m_isSizeVisible); + } + d->m_modifiedInfo->setText(item.timeString()); + d->m_ownerInfo->setText(item.user()); + d->m_permissionsInfo->setText(item.permissionsString()); + + setItems(KFileItemList() << item); +} + +void KMetaDataWidget::setItems(const KFileItemList& items) +{ + d->m_fileItems = 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, d->m_isSizeVisible); + + quint64 totalSize = 0; + foreach (const KFileItem& item, items) { + if (!item.isDir() && !item.isLink()) { + totalSize += item.size(); + } + } + d->m_sizeInfo->setText(KIO::convertSize(totalSize)); + } + +#ifdef HAVE_NEPOMUK + if (Nepomuk::ResourceManager::instance()->init() == 0) { + QList urls; + foreach (const KFileItem& item, items) { + const KUrl url = item.nepomukUri(); + if (url.isValid()) { + urls.append(url); + } + } + d->m_loadFilesThread->loadFiles(urls); + } +#endif +} + +void KMetaDataWidget::setItem(const KUrl& url) +{ + KFileItem item(KFileItem::Unknown, KFileItem::Unknown, url); + item.refresh(); + setItem(item); +} + +void KMetaDataWidget::setItems(const QList& urls) +{ + KFileItemList items; + foreach (const KUrl& url, urls) { + KFileItem item(KFileItem::Unknown, KFileItem::Unknown, url); + item.refresh(); + items.append(item); + } + setItems(items); +} + +KFileItemList KMetaDataWidget::items() const +{ + return d->m_fileItems; +} + +void KMetaDataWidget::setVisibleDataTypes(MetaDataTypes data) +{ + d->m_visibleDataTypes = data; + d->updateRowsVisibility(); +} + +KMetaDataWidget::MetaDataTypes KMetaDataWidget::visibleDataTypes() const +{ + return d->m_visibleDataTypes; +} + +#include "kmetadatawidget.moc" diff --git a/src/panels/information/kmetadatawidget.h b/src/panels/information/kmetadatawidget.h new file mode 100644 index 000000000..fbcf79f40 --- /dev/null +++ b/src/panels/information/kmetadatawidget.h @@ -0,0 +1,129 @@ +/***************************************************************************** + * Copyright (C) 2008 by Sebastian Trueg * + * Copyright (C) 2009 by Peter Penz * + * * + * 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 KMETADATAWIDGET_H +#define KMETADATAWIDGET_H + +#include +#include + +#include +#include + +class KUrl; + +/** + * @brief Shows the meta data of one or more file items. + * + * Meta data like name, size, rating, comment, ... are + * shown as several rows containing a description and + * the meta data value. It is possible for the user + * to change specific meta data like rating, tags and + * comment. The changes are stored automatically by the + * meta data widget. + */ +class KFILE_EXPORT KMetaDataWidget : public QWidget +{ + Q_OBJECT + +public: + /** + * Allows to specify which general data types should be shown + * by the meta data widget. + * @see KMetaDataWidget::setVisibleDataTypes() + * @see KMetaDataWidget::visibleDataTypes() + */ + enum MetaDataType + { + None = 0, + TypeData = 1, + SizeData = 2, + ModifiedData = 4, + OwnerData = 8, + PermissionsData = 16, + RatingData = 32, + TagsData = 64, + CommentData = 128 + }; + Q_DECLARE_FLAGS(MetaDataTypes, MetaDataType) + + explicit KMetaDataWidget(QWidget* parent = 0); + virtual ~KMetaDataWidget(); + + /** + * Triggers the asynchronous loading of the meta data + * for the file item \p item. Connect to the signal + * loadingFinished() to be able to read the meta + * data. + */ + void setItem(const KFileItem& item); + + /** + * Triggers the asynchronous loading of the meta data + * for the file items \p items. Connect to the signal + * loadingFinished() to be able to read the meta + * data. + */ + void setItems(const KFileItemList& items); + + /** + * Convenience method for KMetaDataWidget::setItem(const KFileItem&), + * if the application has only an URL and no file item. + * For performance reason it is recommended to use this convenience + * method only if the application does not have a file item already. + */ + void setItem(const KUrl& url); + + /** + * Convenience method for KMetaDataWidget::setItems(const KFileItemList&), + * if the application has only URLs and no file items. + * For performance reason it is recommended to use this convenience + * method only if the application does not have a file items already. + */ + void setItems(const QList& urls); + + KFileItemList items() const; + + /** + * Specifies which kind of data types should be shown (@see KMetaDataWidget::Data). + * Example: metaDataWidget->setVisibleDataTypes(KMetaDataWidget::TypeData | KMetaDataWidget::ModifiedData); + * Per default all data types are shown. + */ + void setVisibleDataTypes(MetaDataTypes data); + + /** + * Returns which kind of data is shown (@see KMetaDataWidget::Data). + * Example: if (metaDataWidget->shownData() & KMetaDataWidget::TypeData) ... + */ + MetaDataTypes visibleDataTypes() const; + +private: + class Private; + 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& tags)) + Q_PRIVATE_SLOT(d, void slotCommentChanged(const QString& comment)) + Q_PRIVATE_SLOT(d, void slotMetaDataUpdateDone()) +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(KMetaDataWidget::MetaDataTypes) + +#endif diff --git a/src/panels/information/ktaggingwidget.cpp b/src/panels/information/ktaggingwidget.cpp new file mode 100644 index 000000000..3fc3b0026 --- /dev/null +++ b/src/panels/information/ktaggingwidget.cpp @@ -0,0 +1,109 @@ +/***************************************************************************** + * Copyright (C) 2009 by Peter Penz * + * * + * 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 "ktaggingwidget_p.h" + +#include "kedittagsdialog_p.h" + +#include +#include + +#include +#include + +KTaggingWidget::KTaggingWidget(QWidget* parent) : + QWidget(parent), + m_label(0), + m_tags(), + m_tagsText() +{ + m_label = new QLabel(this); + m_label->setFont(KGlobalSettings::smallestReadableFont()); + m_label->setWordWrap(true); + m_label->setAlignment(Qt::AlignTop); + connect(m_label, SIGNAL(linkActivated(const QString&)), this, SLOT(slotLinkActivated(const QString&))); + + QVBoxLayout* layout = new QVBoxLayout(this); + layout->setMargin(0); + layout->addWidget(m_label); + + setTags(QList()); +} + +KTaggingWidget::~KTaggingWidget() +{ +} + +void KTaggingWidget::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 KTaggingWidget::tags() const +{ + return m_tags; +} + +void KTaggingWidget::slotLinkActivated(const QString& link) +{ + Q_UNUSED(link); + + KEditTagsDialog dialog(m_tags, this, Qt::Dialog); + KConfigGroup dialogConfig(KGlobal::config(), "Nepomuk KEditTagsDialog"); + dialog.restoreDialogSize(dialogConfig); + + if (dialog.exec() == QDialog::Accepted) { + const QList 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 "ktaggingwidget_p.moc" diff --git a/src/panels/information/ktaggingwidget_p.h b/src/panels/information/ktaggingwidget_p.h new file mode 100644 index 000000000..b26bdca49 --- /dev/null +++ b/src/panels/information/ktaggingwidget_p.h @@ -0,0 +1,54 @@ +/***************************************************************************** + * Copyright (C) 2009 by Peter Penz * + * * + * 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 TAGGING_WIDGET_H +#define TAGGING_WIDGET_H + +#include +#include +#include + +class QLabel; + +/** + * @brief Allows to edit and show tags as part of KMetaDataWidget. + */ +class KTaggingWidget : public QWidget +{ + Q_OBJECT + +public: + KTaggingWidget(QWidget* parent); + virtual ~KTaggingWidget(); + + void setTags(const QList& tags); + QList tags() const; + +signals: + void tagsChanged(const QList& tags); + +private slots: + void slotLinkActivated(const QString& link); + +private: + QLabel* m_label; + QList m_tags; + QString m_tagsText; +}; + +#endif diff --git a/src/panels/information/metadataconfigurationdialog.cpp b/src/panels/information/metadataconfigurationdialog.cpp deleted file mode 100644 index a53eaa339..000000000 --- a/src/panels/information/metadataconfigurationdialog.cpp +++ /dev/null @@ -1,278 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Peter Penz * - * * - * 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 "metadataconfigurationdialog.h" - -#include "metadatawidget.h" - -#include - -#include -#ifdef HAVE_NEPOMUK - #define DISABLE_NEPOMUK_LEGACY - #include - #include - #include - #include -#endif - -#include -#include -#include - -class MetaDataConfigurationDialog::Private -{ -public: - Private(MetaDataConfigurationDialog* parent, MetaDataWidget* metaDataWidget); - ~Private(); - - void init(); - void loadMetaData(); - QString tunedLabel(const QString& label) const; - - int m_hiddenData; - MetaDataWidget* m_metaDataWidget; - QListWidget* m_metaDataList; - -private: - MetaDataConfigurationDialog* const q; -}; - -MetaDataConfigurationDialog::Private::Private(MetaDataConfigurationDialog* parent, - MetaDataWidget* metaDataWidget) : - q(parent) -{ - m_hiddenData = 0; - m_metaDataWidget = metaDataWidget; - - q->setCaption(i18nc("@title:window", "Configure Shown Data")); - q->setButtons(KDialog::Ok | KDialog::Cancel); - q->setDefaultButton(KDialog::Ok); - - QWidget* mainWidget = new QWidget(q); - QVBoxLayout* topLayout = new QVBoxLayout(mainWidget); - - QLabel* label = new QLabel(i18nc("@label:textbox", - "Configure which data should " - "be shown."), q); - - m_metaDataList = new QListWidget(q); - m_metaDataList->setSelectionMode(QAbstractItemView::NoSelection); - - topLayout->addWidget(label); - topLayout->addWidget(m_metaDataList); - - q->setMainWidget(mainWidget); - - loadMetaData(); - - const KConfigGroup dialogConfig(KGlobal::config(), "Nepomuk MetaDataConfigurationDialog"); - q->restoreDialogSize(dialogConfig); -} - -MetaDataConfigurationDialog::Private::~Private() -{ - KConfigGroup dialogConfig(KGlobal::config(), "Nepomuk MetaDataConfigurationDialog"); - q->saveDialogSize(dialogConfig, KConfigBase::Persistent); -} - -void MetaDataConfigurationDialog::Private::loadMetaData() -{ - KConfig config("kmetainformationrc", KConfig::NoGlobals); - KConfigGroup settings = config.group("Show"); - - // Add fixed meta data items where the visibility does not - // depend on the currently used URL. - int hiddenData = 0; - if (m_metaDataWidget != 0) { - hiddenData = m_metaDataWidget->hiddenData(); - } - - typedef QPair FixedItem; - QList fixedItems; - if (!(hiddenData & MetaDataWidget::TypeData)) { - fixedItems.append(FixedItem("type", i18nc("@item::inlistbox", "Type"))); - } - if (!(hiddenData & MetaDataWidget::SizeData)) { - fixedItems.append(FixedItem("size", i18nc("@item::inlistbox", "Size"))); - } - if (!(hiddenData & MetaDataWidget::ModifiedData)) { - fixedItems.append(FixedItem("modified", i18nc("@item::inlistbox", "Modified"))); - } - if (!(hiddenData & MetaDataWidget::OwnerData)) { - fixedItems.append(FixedItem("owner", i18nc("@item::inlistbox", "Owner"))); - } - if (!(hiddenData & MetaDataWidget::PermissionsData)) { - fixedItems.append(FixedItem("permissions", i18nc("@item::inlistbox", "Permissions"))); - } -#ifdef HAVE_NEPOMUK - if (Nepomuk::ResourceManager::instance()->init() == 0) { - if (!(hiddenData & MetaDataWidget::RatingData)) { - fixedItems.append(FixedItem("rating", i18nc("@item::inlistbox", "Rating"))); - } - if (!(hiddenData & MetaDataWidget::TagsData)) { - fixedItems.append(FixedItem("tags", i18nc("@item::inlistbox", "Tags"))); - } - if (!(hiddenData & MetaDataWidget::CommentData)) { - fixedItems.append(FixedItem("comment", i18nc("@item::inlistbox", "Comment"))); - } - } -#endif - - foreach (const FixedItem& fixedItem, fixedItems) { - const QString key = fixedItem.first; - const QString label = fixedItem.second; - QListWidgetItem* item = new QListWidgetItem(label, m_metaDataList); - item->setData(Qt::UserRole, key); - const bool show = settings.readEntry(key, true); - item->setCheckState(show ? Qt::Checked : Qt::Unchecked); - } - -#ifdef HAVE_NEPOMUK - if (Nepomuk::ResourceManager::instance()->init() != 0) { - return; - } - - // Get all meta information labels that are available for - // the currently shown file item and add them to the list. - if (m_metaDataWidget == 0) { - // TODO: in this case all available meta data from the system - // should be added. - return; - } - - const KFileItemList items = m_metaDataWidget->items(); - if (items.count() != 1) { - // TODO: handle als usecases for more than one item: - return; - } - Nepomuk::Resource res(items.first().nepomukUri()); - - QHash properties = res.properties(); - QHash::const_iterator it = properties.constBegin(); - while (it != properties.constEnd()) { - Nepomuk::Types::Property prop(it.key()); - const QString key = prop.name(); - - // Meta information provided by Nepomuk that is already - // available from KFileItem as "fixed item" (see above) - // should not be shown as second entry. - static const char* hiddenProperties[] = { - "contentSize", // = fixed item "size" - "fileExtension", // ~ fixed item "type" - "hasTag", // = fixed item "tags" - "name", // not shown as part of the meta data widget - "lastModified", // = fixed item "modified" - "size", // = fixed item "size" - "mimeType", // = fixed item "type" - "numericRating", // = fixed item "rating" - 0 // mandatory last entry - }; - bool skip = false; - int i = 0; - while (hiddenProperties[i] != 0) { - if (key == hiddenProperties[i]) { - skip = true; - break; - } - ++i; - } - - if (!skip) { - // TODO #1: use Nepomuk::formatValue(res, prop) if available - // instead of it.value().toString() - // TODO #2: using tunedLabel() is a workaround for KDE 4.3 (4.4?) until - // we get translated labels - const QString label = tunedLabel(prop.label()); - QListWidgetItem* item = new QListWidgetItem(label, m_metaDataList); - item->setData(Qt::UserRole, key); - const bool show = settings.readEntry(key, true); - item->setCheckState(show ? Qt::Checked : Qt::Unchecked); - } - - ++it; - } -#endif -} - -QString MetaDataConfigurationDialog::Private::tunedLabel(const QString& label) const -{ - QString tunedLabel; - const int labelLength = label.length(); - if (labelLength > 0) { - tunedLabel.reserve(labelLength); - tunedLabel = label[0].toUpper(); - for (int i = 1; i < labelLength; ++i) { - if (label[i].isUpper() && !label[i - 1].isSpace() && !label[i - 1].isUpper()) { - tunedLabel += ' '; - tunedLabel += label[i].toLower(); - } else { - tunedLabel += label[i]; - } - } - } - return tunedLabel; -} - -MetaDataConfigurationDialog::MetaDataConfigurationDialog(QWidget* parent, - Qt::WFlags flags) : - KDialog(parent, flags), - d(new Private(this, 0)) -{ -} - -MetaDataConfigurationDialog::MetaDataConfigurationDialog(MetaDataWidget* metaDataWidget, - QWidget* parent, - Qt::WFlags flags) : - KDialog(parent, flags), - d(new Private(this, metaDataWidget)) -{ -} - -MetaDataConfigurationDialog::~MetaDataConfigurationDialog() -{ -} - -void MetaDataConfigurationDialog::slotButtonClicked(int button) -{ - if (button == KDialog::Ok) { - KConfig config("kmetainformationrc", KConfig::NoGlobals); - KConfigGroup showGroup = config.group("Show"); - - const int count = d->m_metaDataList->count(); - for (int i = 0; i < count; ++i) { - QListWidgetItem* item = d->m_metaDataList->item(i); - const bool show = (item->checkState() == Qt::Checked); - const QString key = item->data(Qt::UserRole).toString(); - showGroup.writeEntry(key, show); - } - - showGroup.sync(); - - if (d->m_metaDataWidget != 0) { - // trigger an update - d->m_metaDataWidget->setHiddenData(d->m_metaDataWidget->hiddenData()); - } - accept(); - } else { - KDialog::slotButtonClicked(button); - } -} - -#include "metadataconfigurationdialog.moc" diff --git a/src/panels/information/metadataconfigurationdialog.h b/src/panels/information/metadataconfigurationdialog.h deleted file mode 100644 index 82dc06ddf..000000000 --- a/src/panels/information/metadataconfigurationdialog.h +++ /dev/null @@ -1,62 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Peter Penz * - * * - * 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 META_DATA_CONFIGURATION_DIALOG_H -#define META_DATA_CONFIGURATION_DIALOG_H - -#include - -class MetaDataWidget; - -/** - * @brief Dialog which allows to configure which meta data should be shown. - */ -class MetaDataConfigurationDialog : public KDialog -{ - Q_OBJECT - -public: - /** - * Allows to configure the visibility of all available meta - * data. - */ - MetaDataConfigurationDialog(QWidget* parent = 0, - Qt::WFlags flags = 0); - - /** - * Allows to configure the visibility of the meta data - * shown by the meta data widget. The number of offered - * meta data is optimized for the set of file items - * that are applied to the meta data widget. - */ - MetaDataConfigurationDialog(MetaDataWidget* metaDataWidget, - QWidget* parent = 0, - Qt::WFlags flags = 0); - - virtual ~MetaDataConfigurationDialog(); - -protected slots: - virtual void slotButtonClicked(int button); - -private: - class Private; - Private* d; -}; - -#endif diff --git a/src/panels/information/metadatawidget.cpp b/src/panels/information/metadatawidget.cpp deleted file mode 100644 index 67e3d1e44..000000000 --- a/src/panels/information/metadatawidget.cpp +++ /dev/null @@ -1,709 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sebastian Trueg * - * Copyright (C) 2009 by Peter Penz * - * * - * 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 "metadatawidget.h" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#ifdef HAVE_NEPOMUK - #define DISABLE_NEPOMUK_LEGACY - - #include "commentwidget_p.h" - #include "nepomukmassupdatejob_p.h" - #include "taggingwidget_p.h" - - #include - #include - #include - #include - #include - - #include - #include - #include -#endif - -#include - -class MetaDataWidget::Private -{ -public: - struct Row - { - QLabel* label; - QWidget* infoWidget; - }; - - Private(MetaDataWidget* parent); - ~Private(); - - void addRow(QLabel* label, QWidget* infoWidget); - void removeMetaInfoRows(); - void setRowVisible(QWidget* infoWidget, bool visible); - - /** - * Initializes the configuration file "kmetainformationrc" - * with proper default settings for the first start in - * an uninitialized environment. - */ - void initMetaInfoSettings(); - - /** - * Parses the configuration file "kmetainformationrc" and - * updates the visibility of all rows. - */ - void updateRowsVisibility(); - - void slotLoadingFinished(); - void slotRatingChanged(unsigned int rating); - void slotTagsChanged(const QList& 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); - - bool m_isSizeVisible; - MetaDataTypes m_hiddenData; - QList m_fileItems; - QList m_rows; - - QGridLayout* m_gridLayout; - - 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; - - // shared data between the GUI-thread and - // the loader-thread (see LoadFilesThread): - QMutex m_mutex; - struct SharedData - { - int rating; - QString comment; - QList tags; - QList metaInfoLabels; - QList metaInfoValues; - QMap files; - } m_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* m_sharedData, QMutex* m_mutex); - virtual ~LoadFilesThread(); - void loadFiles(const KUrl::List& urls); - virtual void run(); - - private: - /** - * Assures that the settings for the meta information - * are initialized with proper default values. - */ - void initMetaInfoSettings(KConfigGroup& group); - - /** - * Temporary helper method for KDE 4.3 as we currently don't get - * translated labels for Nepmok literals: Replaces camelcase labels - * like "fileLocation" by "File Location:". - */ - QString tunedLabel(const QString& label) const; - - private: - SharedData* m_sharedData; - QMutex* m_mutex; - KUrl::List m_urls; - bool m_canceled; - }; - - LoadFilesThread* m_loadFilesThread; -#endif - -private: - MetaDataWidget* const q; -}; - -MetaDataWidget::Private::Private(MetaDataWidget* parent) : - m_isSizeVisible(true), - m_hiddenData(None), - m_fileItems(), - m_rows(), - m_gridLayout(0), - m_typeInfo(0), - m_sizeLabel(0), - m_sizeInfo(0), - m_modifiedInfo(0), - m_ownerInfo(0), - m_permissionsInfo(0), -#ifdef HAVE_NEPOMUK - m_ratingWidget(0), - m_taggingWidget(0), - m_commentWidget(0), - m_loadFilesThread(0), -#endif - q(parent) -{ - m_gridLayout = new QGridLayout(parent); - m_gridLayout->setMargin(0); - - 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); - - 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); - -#ifdef HAVE_NEPOMUK - if (Nepomuk::ResourceManager::instance()->init() == 0) { - 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&)), - q, SLOT(slotTagsChanged(const QList&))); - - m_commentWidget = new CommentWidget(parent); - connect(m_commentWidget, SIGNAL(commentChanged(const QString&)), - q, SLOT(slotCommentChanged(const QString&))); - - 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); - - m_loadFilesThread = new LoadFilesThread(&m_sharedData, &m_mutex); - connect(m_loadFilesThread, SIGNAL(finished()), q, SLOT(slotLoadingFinished())); - } - - m_sharedData.rating = 0; -#endif - - initMetaInfoSettings(); - updateRowsVisibility(); -} - -MetaDataWidget::Private::~Private() -{ -#ifdef HAVE_NEPOMUK - delete m_loadFilesThread; -#endif -} - -void MetaDataWidget::Private::addRow(QLabel* label, QWidget* infoWidget) -{ - Row row; - row.label = label; - row.infoWidget = infoWidget; - m_rows.append(row); - - const QFont smallFont = KGlobalSettings::smallestReadableFont(); - // use a brighter color for the label and a small font size - QPalette palette = label->palette(); - QColor textColor = palette.color(QPalette::Text); - textColor.setAlpha(128); - palette.setColor(QPalette::WindowText, textColor); - label->setPalette(palette); - label->setFont(smallFont); - label->setWordWrap(true); - label->setAlignment(Qt::AlignTop | Qt::AlignRight); - - QLabel* infoLabel = qobject_cast(infoWidget); - if (infoLabel != 0) { - infoLabel->setFont(smallFont); - infoLabel->setWordWrap(true); - infoLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft); - } - - // add the row to grid layout - const int rowIndex = m_rows.count(); - m_gridLayout->addWidget(label, rowIndex, 0, Qt::AlignRight); - const int spacerWidth = QFontMetrics(smallFont).size(Qt::TextSingleLine, " ").width(); - m_gridLayout->addItem(new QSpacerItem(spacerWidth, 1), rowIndex, 1); - m_gridLayout->addWidget(infoWidget, rowIndex, 2, Qt::AlignLeft); -} - -void MetaDataWidget::Private::setRowVisible(QWidget* infoWidget, bool visible) -{ - foreach (const Row& row, m_rows) { - if (row.infoWidget == infoWidget) { - row.label->setVisible(visible); - row.infoWidget->setVisible(visible); - return; - } - } -} - - -void MetaDataWidget::Private::initMetaInfoSettings() -{ - KConfig config("kmetainformationrc", KConfig::NoGlobals); - KConfigGroup settings = config.group("Show"); - if (!settings.readEntry("initialized", false)) { - // The resource file is read the first time. Assure - // that some meta information is disabled per default. - - static const char* disabledProperties[] = { - "asText", "contentSize", "created", "depth", "description", "fileExtension", - "fileName", "fileSize", "hasTag", "isPartOf", "lastModified", "mimeType", "name", - "numericRating", "parentUrl", "permissions", "plainTextContent", "owner", - "sourceModified", "url", - 0 // mandatory last entry - }; - - int i = 0; - while (disabledProperties[i] != 0) { - settings.writeEntry(disabledProperties[i], false); - ++i; - } - - // mark the group as initialized - settings.writeEntry("initialized", true); - } -} - -void MetaDataWidget::Private::updateRowsVisibility() -{ - KConfig config("kmetainformationrc", KConfig::NoGlobals); - KConfigGroup settings = config.group("Show"); - - setRowVisible(m_typeInfo, - !(m_hiddenData & MetaDataWidget::TypeData) && - settings.readEntry("type", true)); - - // Cache in m_isSizeVisible whether the size should be shown. This - // is necessary as the size is temporary hidden when the target - // file item is a directory. - m_isSizeVisible = !(m_hiddenData & MetaDataWidget::SizeData) && - settings.readEntry("size", true); - setRowVisible(m_sizeInfo, m_isSizeVisible); - - setRowVisible(m_modifiedInfo, - !(m_hiddenData & MetaDataWidget::ModifiedData) && - settings.readEntry("modified", true)); - - setRowVisible(m_ownerInfo, - !(m_hiddenData & MetaDataWidget::OwnerData) && - settings.readEntry("owner", true)); - - setRowVisible(m_permissionsInfo, - !(m_hiddenData & MetaDataWidget::PermissionsData) && - settings.readEntry("permissions", true)); - -#ifdef HAVE_NEPOMUK - if (Nepomuk::ResourceManager::instance()->init() == 0) { - setRowVisible(m_ratingWidget, - !(m_hiddenData & MetaDataWidget::RatingData) && - settings.readEntry("rating", true)); - - setRowVisible(m_taggingWidget, - !(m_hiddenData & MetaDataWidget::TagsData) && - settings.readEntry("tags", true)); - - setRowVisible(m_commentWidget, - !(m_hiddenData & MetaDataWidget::CommentData) && - settings.readEntry("comment", true)); - } -#endif -} - -void MetaDataWidget::Private::slotLoadingFinished() -{ -#ifdef HAVE_NEPOMUK - QMutexLocker locker(&m_mutex); - m_ratingWidget->setRating(m_sharedData.rating); - m_commentWidget->setText(m_sharedData.comment); - m_taggingWidget->setTags(m_sharedData.tags); - - // Show the remaining meta information as text. The number - // of required rows may very. Existing rows are reused to - // prevent flickering. - int index = 8; // TODO: don't hardcode this value here - const int rowCount = m_rows.count(); - Q_ASSERT(rowCount >= index); - - Q_ASSERT(m_sharedData.metaInfoLabels.count() == m_sharedData.metaInfoValues.count()); - const int metaInfoCount = m_sharedData.metaInfoLabels.count(); - for (int i = 0; i < metaInfoCount; ++i) { - if (index < rowCount) { - // adjust texts of the current row - m_rows[index].label->setText(m_sharedData.metaInfoLabels[i]); - QLabel* infoValueLabel = qobject_cast(m_rows[index].infoWidget); - Q_ASSERT(infoValueLabel != 0); - infoValueLabel->setText(m_sharedData.metaInfoValues[i]); - } else { - // create new row - QLabel* infoLabel = new QLabel(m_sharedData.metaInfoLabels[i], q); - QLabel* infoValue = new QLabel(m_sharedData.metaInfoValues[i], q); - addRow(infoLabel, infoValue); - } - ++index; - } - if (metaInfoCount > 0) { - --index; - } - - // remove rows that are not needed anymore - for (int i = rowCount - 1; i > index; --i) { - delete m_rows[i].label; - delete m_rows[i].infoWidget; - m_rows.pop_back(); - } - - emit q->loadingFinished(); -#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); -#endif - emit q->ratingChanged(rating); -} - -void MetaDataWidget::Private::slotTagsChanged(const QList& tags) -{ -#ifdef HAVE_NEPOMUK - m_taggingWidget->setTags(tags); - - QMutexLocker locker(&m_mutex); - Nepomuk::MassUpdateJob* job = - Nepomuk::MassUpdateJob::tagResources(m_sharedData.files.values(), tags); - locker.unlock(); - startChangeDataJob(job); -#endif - emit q->tagsChanged(tags); -} - -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); -#endif - emit q->commentChanged(comment); -} - -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_sharedData(m_sharedData), - m_mutex(m_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(); - - KConfig config("kmetainformationrc", KConfig::NoGlobals); - KConfigGroup settings = config.group("Show"); - - bool first = true; - unsigned int rating = 0; - QString comment; - QList tags; - QList metaInfoLabels; - QList metaInfoValues; - QMap files; - foreach (const KUrl& url, urls) { - if (m_canceled) { - return; - } - - Nepomuk::Resource file(url); - files.insert(url, 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(); - } - - if (first && (urls.count() == 1)) { - // TODO: show shared meta information instead - // of not showing anything on multiple selections - QHash properties = file.properties(); - QHash::const_iterator it = properties.constBegin(); - while (it != properties.constEnd()) { - Nepomuk::Types::Property prop(it.key()); - if (settings.readEntry(prop.name(), true)) { - // TODO #1: use Nepomuk::formatValue(res, prop) if available - // instead of it.value().toString() - // TODO #2: using tunedLabel() is a workaround for KDE 4.3 (4.4?) until - // we get translated labels - metaInfoLabels.append(tunedLabel(prop.label())); - metaInfoValues.append(it.value().toString()); - } - ++it; - } - } - - first = false; - } - - locker.relock(); - m_sharedData->rating = rating; - m_sharedData->comment = comment; - m_sharedData->tags = tags; - m_sharedData->metaInfoLabels = metaInfoLabels; - m_sharedData->metaInfoValues = metaInfoValues; - m_sharedData->files = files; -} - -QString MetaDataWidget::Private::LoadFilesThread::tunedLabel(const QString& label) const -{ - QString tunedLabel; - const int labelLength = label.length(); - if (labelLength > 0) { - tunedLabel.reserve(labelLength); - tunedLabel = label[0].toUpper(); - for (int i = 1; i < labelLength; ++i) { - if (label[i].isUpper() && !label[i - 1].isSpace() && !label[i - 1].isUpper()) { - tunedLabel += ' '; - tunedLabel += label[i].toLower(); - } else { - tunedLabel += label[i]; - } - } - } - return tunedLabel + ':'; -} - -#endif // HAVE_NEPOMUK - -MetaDataWidget::MetaDataWidget(QWidget* parent) : - QWidget(parent), - d(new Private(this)) -{ -} - -MetaDataWidget::~MetaDataWidget() -{ - delete d; -} - -void MetaDataWidget::setItem(const KFileItem& item) -{ - // update values for "type", "size", "modified", - // "owner" and "permissions" synchronously - d->m_sizeLabel->setText(i18nc("@label", "Size:")); - if (item.isDir()) { - d->m_typeInfo->setText(i18nc("@label", "Folder")); - d->setRowVisible(d->m_sizeInfo, false); - } else { - d->m_typeInfo->setText(item.mimeComment()); - d->m_sizeInfo->setText(KIO::convertSize(item.size())); - d->setRowVisible(d->m_sizeInfo, d->m_isSizeVisible); - } - d->m_modifiedInfo->setText(item.timeString()); - d->m_ownerInfo->setText(item.user()); - d->m_permissionsInfo->setText(item.permissionsString()); - - setItems(KFileItemList() << item); -} - -void MetaDataWidget::setItems(const KFileItemList& items) -{ - d->m_fileItems = 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, d->m_isSizeVisible); - - quint64 totalSize = 0; - foreach (const KFileItem& item, items) { - if (!item.isDir() && !item.isLink()) { - totalSize += item.size(); - } - } - d->m_sizeInfo->setText(KIO::convertSize(totalSize)); - } - -#ifdef HAVE_NEPOMUK - if (Nepomuk::ResourceManager::instance()->init() == 0) { - QList urls; - foreach (const KFileItem& item, items) { - const KUrl url = item.nepomukUri(); - if (url.isValid()) { - urls.append(url); - } - } - d->m_loadFilesThread->loadFiles(urls); - } -#endif -} - -void MetaDataWidget::setItem(const KUrl& url) -{ - KFileItem item(KFileItem::Unknown, KFileItem::Unknown, url); - item.refresh(); - setItem(item); -} - -void MetaDataWidget::setItems(const QList& urls) -{ - KFileItemList items; - foreach (const KUrl& url, urls) { - KFileItem item(KFileItem::Unknown, KFileItem::Unknown, url); - item.refresh(); - items.append(item); - } - setItems(items); -} - -KFileItemList MetaDataWidget::items() const -{ - return d->m_fileItems; -} - -void MetaDataWidget::setHiddenData(MetaDataTypes data) -{ - d->m_hiddenData = data; - d->updateRowsVisibility(); -} - -MetaDataWidget::MetaDataTypes MetaDataWidget::hiddenData() const -{ - return d->m_hiddenData; -} - -unsigned int MetaDataWidget::rating() const -{ -#ifdef HAVE_NEPOMUK - QMutexLocker locker(&d->m_mutex); - return d->m_sharedData.rating; -#else - return 0; -#endif -} - -QList MetaDataWidget::tags() const -{ -#ifdef HAVE_NEPOMUK - QMutexLocker locker(&d->m_mutex); - return d->m_sharedData.tags; -#else - return QList(); -#endif -} - -QString MetaDataWidget::comment() const -{ -#ifdef HAVE_NEPOMUK - QMutexLocker locker(&d->m_mutex); - return d->m_sharedData.comment; -#else - return QString(); -#endif -} - -#include "metadatawidget.moc" diff --git a/src/panels/information/metadatawidget.h b/src/panels/information/metadatawidget.h deleted file mode 100644 index b03469014..000000000 --- a/src/panels/information/metadatawidget.h +++ /dev/null @@ -1,202 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sebastian Trueg * - * Copyright (C) 2009 by Peter Penz * - * * - * 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 METADATAWIDGET_H -#define METADATAWIDGET_H - -#include -#ifdef HAVE_NEPOMUK - #include -#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 - -#include -#include - -class KUrl; - -/** - * @brief Shows the meta data of one or more file items. - * - * Meta data like name, size, rating, comment, ... are - * shown as several rows containing a description and - * the meta data value. It is possible for the user - * to change specific meta data like rating, tags and - * comment. The changes are stored automatically by the - * meta data widget. - */ -class MetaDataWidget : public QWidget -{ - Q_OBJECT - -public: - /** - * Allows to specify which general data should be hidden - * by the meta data widget. - * @see MetaDataWidget::setHiddenData() - * @see MetaDataWidget::hiddenData() - */ - enum MetaDataType - { - None = 0, - TypeData = 1, - SizeData= 2, - ModifiedData = 4, - OwnerData = 8, - PermissionsData = 16, - RatingData = 32, - TagsData = 64, - CommentData = 128 - }; - Q_DECLARE_FLAGS( MetaDataTypes, MetaDataType ) - - explicit MetaDataWidget(QWidget* parent = 0); - virtual ~MetaDataWidget(); - - /** - * Triggers the asynchronous loading of the meta data - * for the file item \p item. Connect to the signal - * loadingFinished() to be able to read the meta - * data. - */ - void setItem(const KFileItem& item); - - /** - * Triggers the asynchronous loading of the meta data - * for the file items \p items. Connect to the signal - * loadingFinished() to be able to read the meta - * data. - */ - void setItems(const KFileItemList& items); - - /** - * Convenience method for MetaDataWidget::setItem(const KFileItem&), - * if the application has only an URL and no file item. - * For performance reason it is recommended to use this convenience - * method only if the application does not have a file item already. - */ - void setItem(const KUrl& url); - - /** - * Convenience method for MetaDataWidget::setItems(const KFileItemList&), - * if the application has only URLs and no file items. - * For performance reason it is recommended to use this convenience - * method only if the application does not have a file items already. - */ - void setItems(const QList& urls); - - KFileItemList items() const; - - /** - * Specifies which kind of data should be hidden (@see MetaDataWidget::Data). - * Example: metaDataWidget->setHiddenData(MetaDataWidget::TypeData | ModifiedData); - * Per default no data is hidden. - */ - void setHiddenData(MetaDataTypes data); - - /** - * Returns which kind of data is hidden (@see MetaDataWidget::Data). - * Example: if (metaDataWidget->hiddenData() & MetaDataWidget::TypeData) ... - */ - MetaDataTypes hiddenData() const; - - /** - * Returns the rating for the currently set item(s). It is required - * to wait for the signal loadingFinished() or ratingChanged() - * to get a valid result. - */ - unsigned int rating() const; - - /** - * Returns the tags for the currently set item(s). It is required - * to wait for the signal loadingFinished() or tagsChanged() - * to get a valid result. - */ - QList tags() const; - - /** - * Returns the comment for the currently set item(s). It is required - * to wait for the signal loadingFinished() or commentChanged() - * to get a valid result. - */ - QString comment() const; - -signals: - /** - * Is emitted if the loading of the meta data has been finished - * after invoking MetaDataWidget::setItem() or MetaDataWidget::setItems(). - */ - void loadingFinished(); - - /** - * Is emitted after the user has changed the rating. - * The changed rating is automatically stored already by - * the meta data widget. - * Note that the signal is not emitted if the rating has - * indirectly been changed by MetaDataWidget::setItem() or - * MetaDataWidget::setItems(). In this case connect to - * the signal loadingFinished() instead. - */ - void ratingChanged(const int rating); - - /** - * Is emitted after the user has changed the tags. - * The changed tags are automatically stored already by - * the meta data widget. - * Note that the signal is not emitted if the tags have - * indirectly been changed by MetaDataWidget::setItem() or - * MetaDataWidget::setItems(). In this case connect to - * the signal loadingFinished() instead. - */ - void tagsChanged(const QList& tags); - - /** - * Is emitted after the user has changed the comment. - * The changed comment is automatically stored already by - * the meta data widget. - * Note that the signal is not emitted if the comment has - * indirectly been changed by MetaDataWidget::setItem() or - * MetaDataWidget::setItems(). In this case connect to - * the signal loadingFinished() instead. - */ - void commentChanged(const QString& comment); - -private: - class Private; - 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& tags)) - Q_PRIVATE_SLOT(d, void slotCommentChanged(const QString& comment)) - Q_PRIVATE_SLOT(d, void slotMetaDataUpdateDone()) -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(MetaDataWidget::MetaDataTypes) - -#endif diff --git a/src/panels/information/taggingwidget.cpp b/src/panels/information/taggingwidget.cpp deleted file mode 100644 index 1c081f07c..000000000 --- a/src/panels/information/taggingwidget.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Peter Penz * - * * - * 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 "taggingwidget_p.h" - -#include "edittagsdialog_p.h" - -#include -#include - -#include -#include - -TaggingWidget::TaggingWidget(QWidget* parent) : - QWidget(parent), - m_label(0), - m_tags(), - m_tagsText() -{ - m_label = new QLabel(this); - m_label->setFont(KGlobalSettings::smallestReadableFont()); - m_label->setWordWrap(true); - m_label->setAlignment(Qt::AlignTop); - connect(m_label, SIGNAL(linkActivated(const QString&)), this, SLOT(slotLinkActivated(const QString&))); - - QVBoxLayout* layout = new QVBoxLayout(this); - layout->setMargin(0); - 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); - - EditTagsDialog dialog(m_tags, this, Qt::Dialog); - KConfigGroup dialogConfig(KGlobal::config(), "Nepomuk EditTagsDialog"); - dialog.restoreDialogSize(dialogConfig); - - if (dialog.exec() == QDialog::Accepted) { - const QList 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" diff --git a/src/panels/information/taggingwidget_p.h b/src/panels/information/taggingwidget_p.h deleted file mode 100644 index 64f8bffd5..000000000 --- a/src/panels/information/taggingwidget_p.h +++ /dev/null @@ -1,52 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Peter Penz * - * * - * 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 TAGGING_WIDGET_H -#define TAGGING_WIDGET_H - -#include -#include -#include - -class QLabel; - -class TaggingWidget : public QWidget -{ - Q_OBJECT - -public: - TaggingWidget(QWidget* parent); - virtual ~TaggingWidget(); - - void setTags(const QList& tags); - QList tags() const; - -signals: - void tagsChanged(const QList& tags); - -private slots: - void slotLinkActivated(const QString& link); - -private: - QLabel* m_label; - QList m_tags; - QString m_tagsText; -}; - -#endif -- cgit v1.3