From: Peter Penz Date: Sat, 10 Oct 2009 14:13:50 +0000 (+0000) Subject: Start of refactoring so that the metadata widget can be moved outside of Dolphin... X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/commitdiff_plain/eaeee9f7d68d120b1982f24e73d8183db3418261?ds=inline Start of refactoring so that the metadata widget can be moved outside of Dolphin for other applications. The temporary removed code will be integrated again within the next 10 days (-> currently no meta data is shown and cannot be updated). svn path=/trunk/KDE/kdebase/apps/; revision=1033585 --- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 01cd27ee5..8cba1d906 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -111,11 +111,9 @@ set(dolphin_SRCS filterbar.cpp main.cpp pixmapviewer.cpp - panels/information/commentwidget.cpp panels/information/informationpanel.cpp panels/information/informationpanelcontent.cpp panels/information/metadatawidget.cpp - panels/information/metatextlabel.cpp panels/information/phononwidget.cpp panels/folders/ktreeview.cpp panels/places/placespanel.cpp @@ -154,13 +152,10 @@ kde4_add_kcfg_files(dolphin_SRCS if(Nepomuk_FOUND) set(dolphin_SRCS ${dolphin_SRCS} + panels/information/commentwidget.cpp panels/information/nepomukmassupdatejob.cpp - panels/information/tagcloud.cpp - panels/information/resourcetaggingwidget.cpp - panels/information/taggingpopup.cpp - panels/information/newtagdialog.cpp + panels/information/taggingwidget.cpp ) -kde4_add_ui_files(dolphin_SRCS panels/information/newtagdialog.ui) endif(Nepomuk_FOUND) diff --git a/src/dolphinmodel.cpp b/src/dolphinmodel.cpp index 503c1086d..3467c8a38 100644 --- a/src/dolphinmodel.cpp +++ b/src/dolphinmodel.cpp @@ -24,14 +24,6 @@ #include "kcategorizedview.h" -#include -#ifdef HAVE_NEPOMUK -#include -#include -#include -#include -#endif - #include #include #include diff --git a/src/dolphinsortfilterproxymodel.cpp b/src/dolphinsortfilterproxymodel.cpp index d119a416f..900f2fae6 100644 --- a/src/dolphinsortfilterproxymodel.cpp +++ b/src/dolphinsortfilterproxymodel.cpp @@ -40,10 +40,6 @@ static DolphinView::Sorting sortingTypeTable[] = DolphinView::SortByOwner, // DolphinModel::Owner DolphinView::SortByGroup, // DolphinModel::Group DolphinView::SortByType // DolphinModel::Type -#ifdef HAVE_NEPOMUK - , DolphinView::SortByRating - , DolphinView::SortByTags -#endif }; DolphinSortFilterProxyModel::DolphinSortFilterProxyModel(QObject* parent) : diff --git a/src/dolphinviewactionhandler.cpp b/src/dolphinviewactionhandler.cpp index 0885cceb9..3c010f80f 100644 --- a/src/dolphinviewactionhandler.cpp +++ b/src/dolphinviewactionhandler.cpp @@ -262,31 +262,6 @@ QActionGroup* DolphinViewActionHandler::createSortByActionGroup() sortByType->setData(QVariant::fromValue(DolphinView::SortByType)); sortByActionGroup->addAction(sortByType); - // TODO: Hid "sort by rating" and "sort by tags" as without caching the performance - // is too slow currently (Nepomuk will support caching in future releases). - // - // KToggleAction* sortByRating = m_actionCollection->add("sort_by_rating"); - // sortByRating->setData(QVariant::fromValue(DolphinView::SortByRating)); - // sortByRating->setText(i18nc("@action:inmenu Sort By", "Rating")); - // sortByActionGroup->addAction(sortByRating); - // - // KToggleAction* sortByTags = m_actionCollection->add("sort_by_tags"); - // sortByTags->setData(QVariant::fromValue(DolphinView::SortByTags)); - // sortByTags->setText(i18nc("@action:inmenu Sort By", "Tags")); - // sortByActionGroup->addAction(sortByTags); - // -#ifdef HAVE_NEPOMUK - // if (!MetaDataWidget::metaDataAvailable()) { - // sortByRating->setEnabled(false); - // sortByTags->setEnabled(false); - // } -#else - // sortByRating->setEnabled(false); - // sortByTags->setEnabled(false); -#endif - - - return sortByActionGroup; } @@ -500,14 +475,6 @@ void DolphinViewActionHandler::slotSortingChanged(DolphinView::Sorting sorting) case DolphinView::SortByType: action = m_actionCollection->action("sort_by_type"); break; -#ifdef HAVE_NEPOMUK - case DolphinView::SortByRating: - action = m_actionCollection->action("sort_by_rating"); - break; - case DolphinView::SortByTags: - action = m_actionCollection->action("sort_by_tags"); - break; -#endif default: break; } diff --git a/src/panels/information/commentwidget.cpp b/src/panels/information/commentwidget.cpp index 23f79dfb1..63d8a1dc3 100644 --- a/src/panels/information/commentwidget.cpp +++ b/src/panels/information/commentwidget.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2008 by Sebastian Trueg * + * Copyright (C) 2009 by Peter Penz * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -17,111 +17,15 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * ***************************************************************************/ -#include "commentwidget.h" +#include "commentwidget_p.h" -#include -#include -#include -#include -#include - -#include - - -class CommentWidget::Private -{ -public: - Private( CommentWidget* parent ) - : q( parent ) { - } - - void update(); - void _k_slotEnableEditing(); - - QTextEdit* textEdit; - QLabel* addComment; - - QString comment; - -private: - CommentWidget* q; -}; - - -void CommentWidget::Private::update() +CommentWidget::CommentWidget(QWidget* parent) : + QWidget(parent) { - textEdit->setText( comment ); - const bool hasComment = !comment.isEmpty(); - textEdit->setVisible(hasComment); - addComment->setVisible(!hasComment); } - -void CommentWidget::Private::_k_slotEnableEditing() -{ - textEdit->show(); - textEdit->setFocus(); - addComment->hide(); -} - - - -CommentWidget::CommentWidget( QWidget* parent ) - : QWidget( parent ), - d( new Private( this ) ) -{ - d->textEdit = new QTextEdit( this ); - d->textEdit->installEventFilter( this ); - d->textEdit->setMinimumHeight( 100 ); - d->textEdit->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Ignored); - - d->addComment = new QLabel( this ); - d->addComment->setText( "

" + i18nc( "@label", "Add Comment..." ) + "" ); - - QVBoxLayout* layout = new QVBoxLayout( this ); - layout->setMargin( 0 ); - layout->addWidget( d->textEdit ); - layout->addWidget( d->addComment ); - d->update(); - connect( d->addComment, SIGNAL( linkActivated( const QString& ) ), this, SLOT( _k_slotEnableEditing() ) ); -} - - CommentWidget::~CommentWidget() { - delete d; -} - - -void CommentWidget::setComment( const QString& comment ) -{ - d->comment = comment; - d->update(); -} - - -QString CommentWidget::comment() const -{ - return d->comment; -} - - -QString CommentWidget::editorText() const -{ - return d->textEdit->toPlainText(); -} - -bool CommentWidget::eventFilter( QObject* watched, QEvent* event ) -{ - if ( watched == d->textEdit && event->type() == QEvent::FocusOut ) { - const QString currentComment = editorText(); - if ( currentComment != d->comment ) { - d->comment = currentComment; - emit commentChanged( currentComment ); - } - d->update(); - } - return QWidget::eventFilter( watched, event ); } -#include "commentwidget.moc" +#include "commentwidget_p.moc" diff --git a/src/panels/information/commentwidget.h b/src/panels/information/commentwidget_p.h similarity index 72% rename from src/panels/information/commentwidget.h rename to src/panels/information/commentwidget_p.h index 93460d703..b3768b131 100644 --- a/src/panels/information/commentwidget.h +++ b/src/panels/information/commentwidget_p.h @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2008 by Sebastian Trueg * + * Copyright (C) 2009 by Peter Penz * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -17,34 +17,18 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * ***************************************************************************/ -#ifndef _NEPOMUK_COMMENT_WIDGET_H_ -#define _NEPOMUK_COMMENT_WIDGET_H_ +#ifndef COMMENT_WIDGET +#define COMMENT_WIDGET -#include +#include class CommentWidget : public QWidget { Q_OBJECT public: - CommentWidget( QWidget* parent = 0 ); + CommentWidget(QWidget* parent); virtual ~CommentWidget(); - - void setComment( const QString& comment ); - QString comment() const; - - QString editorText() const; - - virtual bool eventFilter( QObject* watched, QEvent* event ); - -Q_SIGNALS: - void commentChanged( const QString& ); - -private: - class Private; - Private* const d; - - Q_PRIVATE_SLOT( d, void _k_slotEnableEditing() ) }; #endif diff --git a/src/panels/information/informationpanelcontent.cpp b/src/panels/information/informationpanelcontent.cpp index 231fa98da..1d95c0013 100644 --- a/src/panels/information/informationpanelcontent.cpp +++ b/src/panels/information/informationpanelcontent.cpp @@ -48,7 +48,6 @@ #include "dolphin_informationpanelsettings.h" #include "settings/dolphinsettings.h" #include "metadatawidget.h" -#include "metatextlabel.h" #include "phononwidget.h" #include "pixmapviewer.h" @@ -79,9 +78,7 @@ InformationPanelContent::InformationPanelContent(QWidget* parent) : m_previewSeparator(0), m_phononWidget(0), m_metaDataWidget(0), - m_metaDataSeparator(0), - m_metaTextArea(0), - m_metaTextLabel(0) + m_metaDataArea(0) { parent->installEventFilter(this); @@ -126,34 +123,14 @@ InformationPanelContent::InformationPanelContent(QWidget* parent) : m_preview->setVisible(showPreview); m_previewSeparator->setVisible(showPreview); - if (MetaDataWidget::metaDataAvailable()) { - // rating, comment and tags - m_metaDataWidget = new MetaDataWidget(parent); - m_metaDataWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); - m_metaDataWidget->setMaximumWidth(KIconLoader::SizeEnormous); + m_metaDataWidget = new MetaDataWidget(parent); - const bool showRating = InformationPanelSettings::showRating(); - const bool showComment = InformationPanelSettings::showComment(); - const bool showTags = InformationPanelSettings::showTags(); + m_metaDataArea = new QScrollArea(parent); + //m_metaDataArea->setWidget(m_metaDataArea); + m_metaDataArea->setWidgetResizable(true); + m_metaDataArea->setFrameShape(QFrame::NoFrame); - m_metaDataWidget->setRatingVisible(showRating); - m_metaDataWidget->setCommentVisible(showComment); - m_metaDataWidget->setTagsVisible(showTags); - - m_metaDataSeparator = new KSeparator(this); - m_metaDataSeparator->setVisible(showRating || showComment || showTags); - } - - // general meta text information - m_metaTextLabel = new MetaTextLabel(parent); - m_metaTextLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); - - m_metaTextArea = new QScrollArea(parent); - m_metaTextArea->setWidget(m_metaTextLabel); - m_metaTextArea->setWidgetResizable(true); - m_metaTextArea->setFrameShape(QFrame::NoFrame); - - QWidget* viewport = m_metaTextArea->viewport(); + QWidget* viewport = m_metaDataArea->viewport(); viewport->installEventFilter(this); QPalette palette = viewport->palette(); @@ -167,9 +144,8 @@ InformationPanelContent::InformationPanelContent(QWidget* parent) : layout->addWidget(m_previewSeparator); if (m_metaDataWidget != 0) { layout->addWidget(m_metaDataWidget); - layout->addWidget(m_metaDataSeparator); } - layout->addWidget(m_metaTextArea); + layout->addWidget(m_metaDataArea); parent->setLayout(layout); } @@ -212,49 +188,32 @@ void InformationPanelContent::showItem(const KFileItem& item) setNameLabelText(itemUrl.fileName()); } - m_metaTextLabel->clear(); - if (item.isDir()) { - m_metaTextLabel->add(i18nc("@label", "Type:"), i18nc("@label", "Folder")); - m_metaTextLabel->add(i18nc("@label", "Modified:"), item.timeString()); - } else { - m_metaTextLabel->add(i18nc("@label", "Type:"), item.mimeComment()); - - m_metaTextLabel->add(i18nc("@label", "Size:"), KIO::convertSize(item.size())); - m_metaTextLabel->add(i18nc("@label", "Modified:"), item.timeString()); - -#ifdef HAVE_NEPOMUK - if ( item.nepomukUri().isValid() ) { - KConfig config("kmetainformationrc", KConfig::NoGlobals); - KConfigGroup settings = config.group("Show"); - initMetaInfoSettings(settings); - - Nepomuk::Resource res(item.url()); - - QHash properties = res.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 until - // we get translated labels - m_metaTextLabel->add(tunedLabel(prop.label()) + ':', it.value().toString()); - } - ++it; +/* TODO: move to MetaDataWidget + if (!item.isDir() && item.nepomukUri().isValid()) { + KConfig config("kmetainformationrc", KConfig::NoGlobals); + KConfigGroup settings = config.group("Show"); + initMetaInfoSettings(settings); + + Nepomuk::Resource res(item.url()); + + QHash properties = res.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 until + // we get translated labels + m_metaTextLabel->add(tunedLabel(prop.label()) + ':', it.value().toString()); } + ++it; } -#endif } +*/ if (m_metaDataWidget != 0) { - if ( item.nepomukUri().isValid() ) { - m_metaDataWidget->setFile(item.nepomukUri()); - m_metaDataWidget->show(); - } - else { - m_metaDataWidget->hide(); - } + m_metaDataWidget->setItem(item); } if (InformationPanelSettings::showPreview()) { @@ -295,26 +254,9 @@ void InformationPanelContent::showItems(const KFileItemList& items) setNameLabelText(i18ncp("@info", "%1 item selected", "%1 items selected", items.count())); if (m_metaDataWidget != 0) { - KUrl::List urls; - foreach (const KFileItem& item, items) { - if ( item.nepomukUri().isValid() ) - urls.append(item.nepomukUri()); - } - m_metaDataWidget->setFiles(urls); - m_metaDataWidget->setVisible(!urls.isEmpty()); + m_metaDataWidget->setItems(items); } - quint64 totalSize = 0; - foreach (const KFileItem& item, items) { - // Only count the size of files, not dirs to match what - // DolphinViewContainer::selectionStatusBarText() does. - if (!item.isDir() && !item.isLink()) { - totalSize += item.size(); - } - } - m_metaTextLabel->clear(); - m_metaTextLabel->add(i18nc("@label", "Total size:"), KIO::convertSize(totalSize)); - m_phononWidget->hide(); m_item = KFileItem(); @@ -324,10 +266,10 @@ bool InformationPanelContent::eventFilter(QObject* obj, QEvent* event) { if (event->type() == QEvent::Resize) { QResizeEvent* resizeEvent = static_cast(event); - if (obj == m_metaTextArea->viewport()) { + if (obj == m_metaDataArea->viewport()) { // The size of the meta text area has changed. Adjust the fixed // width in a way that no horizontal scrollbar needs to be shown. - m_metaTextLabel->setFixedWidth(resizeEvent->size().width()); + //m_metaDataWidget->setFixedWidth(resizeEvent->size().width()); } else if (obj == parent()) { // If the text inside the name label or the info label cannot // get wrapped, then the maximum width of the label is increased @@ -340,7 +282,7 @@ bool InformationPanelContent::eventFilter(QObject* obj, QEvent* event) // The metadata widget also contains a text widget which may return // a large preferred width. if (m_metaDataWidget != 0) { - m_metaDataWidget->setMaximumWidth(maxWidth); + //m_metaDataWidget->setMaximumWidth(maxWidth); } // try to increase the preview as large as possible @@ -370,7 +312,7 @@ void InformationPanelContent::configureSettings() previewAction->setCheckable(true); previewAction->setChecked(InformationPanelSettings::showPreview()); - const bool metaDataAvailable = MetaDataWidget::metaDataAvailable(); + const bool metaDataAvailable = true; // MetaDataWidget::metaDataAvailable(); TODO QAction* ratingAction = popup.addAction(i18nc("@action:inmenu", "Rating")); ratingAction->setIcon(KIcon("rating")); @@ -458,25 +400,25 @@ void InformationPanelContent::configureSettings() m_previewSeparator->setVisible(isChecked); InformationPanelSettings::setShowPreview(isChecked); } else if (action == ratingAction) { - m_metaDataWidget->setRatingVisible(isChecked); + //m_metaDataWidget->setRatingVisible(isChecked); InformationPanelSettings::setShowRating(isChecked); } else if (action == commentAction) { - m_metaDataWidget->setCommentVisible(isChecked); + //m_metaDataWidget->setCommentVisible(isChecked); InformationPanelSettings::setShowComment(isChecked); } else if (action == tagsAction) { - m_metaDataWidget->setTagsVisible(isChecked); + //m_metaDataWidget->setTagsVisible(isChecked); InformationPanelSettings::setShowTags(isChecked); } else { settings.writeEntry(action->data().toString(), action->isChecked()); settings.sync(); } - if (m_metaDataWidget != 0) { + /*if (m_metaDataWidget != 0) { const bool visible = m_metaDataWidget->isRatingVisible() || m_metaDataWidget->isCommentVisible() || m_metaDataWidget->areTagsVisible(); m_metaDataSeparator->setVisible(visible); - } + }*/ showItem(m_item); #endif diff --git a/src/panels/information/informationpanelcontent.h b/src/panels/information/informationpanelcontent.h index 11010572c..3b9fc6dc3 100644 --- a/src/panels/information/informationpanelcontent.h +++ b/src/panels/information/informationpanelcontent.h @@ -136,10 +136,7 @@ private: KSeparator* m_previewSeparator; PhononWidget* m_phononWidget; MetaDataWidget* m_metaDataWidget; - KSeparator* m_metaDataSeparator; - - QScrollArea* m_metaTextArea; - MetaTextLabel* m_metaTextLabel; + QScrollArea* m_metaDataArea; }; #endif // INFORMATIONPANELCONTENT_H diff --git a/src/panels/information/metadatawidget.cpp b/src/panels/information/metadatawidget.cpp index ea550ed52..5c97d5257 100644 --- a/src/panels/information/metadatawidget.cpp +++ b/src/panels/information/metadatawidget.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2007 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 * @@ -19,341 +19,181 @@ #include "metadatawidget.h" -#include "commentwidget.h" - -#include - +#include #include -#include - -#include -#include -#include -#include -#include -#include -#include +#include #ifdef HAVE_NEPOMUK -#include "nepomukmassupdatejob.h" -#include -#include -#include -#include -#include -#include -#include "resourcetaggingwidget.h" +#include "commentwidget_p.h" +#include "nepomukmassupdatejob_p.h" +#include "taggingwidget_p.h" #endif +#include -bool MetaDataWidget::metaDataAvailable() -{ -#ifdef HAVE_NEPOMUK - return !Nepomuk::ResourceManager::instance()->init(); -#else - return false; -#endif -} - +#include +#include +#include +#include class MetaDataWidget::Private { public: -#ifdef HAVE_NEPOMUK - CommentWidget* commentWidget; - KRatingWidget* ratingWidget; - Nepomuk::ResourceTaggingWidget* tagWidget; - - // shared data between the GUI-thread and - // the loader-thread (see LoadFilesThread): - QMutex mutex; - struct SharedData - { - int rating; - QString comment; - QList fileRes; - QMap files; - } 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 + struct Row { - public: - LoadFilesThread(SharedData* sharedData, QMutex* mutex); - ~LoadFilesThread(); - void loadFiles(const KUrl::List& urls); - virtual void run(); - - private: - SharedData* m_sharedData; - QMutex* m_mutex; - KUrl::List m_urls; - bool m_canceled; + QLabel* label; + QWidget* infoWidget; }; - LoadFilesThread* loadFilesThread; -#endif -}; - -#ifdef HAVE_NEPOMUK - -MetaDataWidget::Private::LoadFilesThread::LoadFilesThread( - MetaDataWidget::Private::SharedData* sharedData, - QMutex* mutex) : - m_sharedData(sharedData), - m_mutex(mutex), - m_urls(), - m_canceled(false) -{ -} - -MetaDataWidget::Private::LoadFilesThread::~LoadFilesThread() -{ - // this thread may very well be deleted during execution. We need - // to protect it from crashes here - m_canceled = true; - wait(); -} - -void MetaDataWidget::Private::LoadFilesThread::loadFiles(const KUrl::List& urls) -{ - QMutexLocker locker( m_mutex ); - m_urls = urls; - m_canceled = false; - start(); -} + Private(MetaDataWidget* parent); + ~Private(); -void MetaDataWidget::Private::LoadFilesThread::run() -{ - QMutexLocker locker( m_mutex ); - const KUrl::List urls = m_urls; - locker.unlock(); - - bool first = true; - QList fileRes; - QMap files; - unsigned int rating = 0; - QString comment; - Q_FOREACH( const KUrl &url, urls ) { - if ( m_canceled ) - return; - Nepomuk::Resource file( url, Soprano::Vocabulary::Xesam::File() ); - files.insert( url, file ); - fileRes.append( file ); + void addRow(QLabel* label, QWidget* infoWidget); + void setRowVisible(QWidget* infoWidget, bool visible); - if ( !first && rating != file.rating() ) { - rating = 0; // reset rating - } - else if ( first ) { - rating = file.rating(); - } - - if ( !first && comment != file.description() ) { - comment.clear(); - } - else if ( first ) { - comment = file.description(); - } - first = false; - } + QList m_rows; - locker.relock(); - m_sharedData->rating = rating; - m_sharedData->comment = comment; - m_sharedData->fileRes = fileRes; - m_sharedData->files = files; -} -#endif + QGridLayout* m_gridLayout; -MetaDataWidget::MetaDataWidget(QWidget* parent) : - QWidget(parent) -{ + QLabel* m_typeInfo; + QLabel* m_sizeLabel; + QLabel* m_sizeInfo; + QLabel* m_modifiedInfo; + QLabel* m_ownerInfo; + QLabel* m_permissionsInfo; #ifdef HAVE_NEPOMUK - d = new Private; - d->commentWidget = new CommentWidget(this); - d->commentWidget->setFocusPolicy(Qt::ClickFocus); - d->ratingWidget = new KRatingWidget(this); - d->ratingWidget->setAlignment( Qt::AlignCenter ); - d->tagWidget = new Nepomuk::ResourceTaggingWidget(this); - connect(d->ratingWidget, SIGNAL(ratingChanged(unsigned int)), this, SLOT(slotRatingChanged(unsigned int))); - connect(d->commentWidget, SIGNAL(commentChanged(const QString&)), this, SLOT(slotCommentChanged(const QString&))); - connect(d->tagWidget, SIGNAL(tagClicked(const Nepomuk::Tag&)), this, SLOT(slotTagClicked( const Nepomuk::Tag&))); - - d->sharedData.rating = 0; - d->loadFilesThread = new Private::LoadFilesThread(&d->sharedData, &d->mutex); - connect(d->loadFilesThread, SIGNAL(finished()), this, SLOT(slotLoadingFinished())); - - QVBoxLayout* lay = new QVBoxLayout(this); - lay->setMargin(0); - lay->addWidget(d->ratingWidget); - lay->addWidget(d->commentWidget); - lay->addWidget( d->tagWidget ); -#else - d = 0; + KRatingWidget* m_ratingWidget; + TaggingWidget* m_taggingWidget; + CommentWidget* m_commentWidget; #endif -} +private: + MetaDataWidget* const q; +}; -MetaDataWidget::~MetaDataWidget() -{ -#ifdef HAVE_NEPOMUK - delete d->loadFilesThread; -#endif - delete d; -} - -void MetaDataWidget::setRatingVisible(bool visible) -{ +MetaDataWidget::Private::Private(MetaDataWidget* parent) : + m_rows(), + m_gridLayout(0), + m_typeInfo(0), + m_sizeLabel(0), + m_sizeInfo(0), + m_modifiedInfo(0), + m_ownerInfo(0), + m_permissionsInfo(0), #ifdef HAVE_NEPOMUK - d->ratingWidget->setVisible(visible); -#else - Q_UNUSED(visible); + m_ratingWidget(0), + m_taggingWidget(0), + m_commentWidget(0), #endif -} - - -bool MetaDataWidget::isRatingVisible() const + q(parent) { -#ifdef HAVE_NEPOMUK - return d->ratingWidget->isVisible(); -#else - return false; -#endif -} - + m_gridLayout = new QGridLayout(parent); -void MetaDataWidget::setCommentVisible(bool visible) -{ + 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); #ifdef HAVE_NEPOMUK - d->commentWidget->setVisible(visible); -#else - Q_UNUSED(visible); + m_ratingWidget = new KRatingWidget(parent); + m_taggingWidget = new TaggingWidget(parent); + m_commentWidget = new CommentWidget(parent); #endif -} - -bool MetaDataWidget::isCommentVisible() const -{ + 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 - return d->commentWidget->isVisible(); -#else - return false; + 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); #endif } - -void MetaDataWidget::setTagsVisible(bool visible) +MetaDataWidget::Private::~Private() { -#ifdef HAVE_NEPOMUK - d->tagWidget->setVisible(visible); -#else - Q_UNUSED(visible); -#endif } - -bool MetaDataWidget::areTagsVisible() const +void MetaDataWidget::Private::addRow(QLabel* label, QWidget* infoWidget) { -#ifdef HAVE_NEPOMUK - return d->tagWidget->isVisible(); -#else - return false; -#endif -} + Row row; + row.label = label; + row.infoWidget = infoWidget; + m_rows.append(row); + QPalette palette = label->palette(); + QColor textColor = palette.color(QPalette::Text); + textColor.setAlpha(128); + palette.setColor(QPalette::WindowText, textColor); + label->setPalette(palette); -void MetaDataWidget::setFile(const KUrl& url) -{ - KUrl::List urls; - urls.append( url ); - setFiles( urls ); + const int rowIndex = m_rows.count(); + m_gridLayout->addWidget(label, rowIndex, 0, Qt::AlignLeft); + m_gridLayout->addWidget(infoWidget, rowIndex, 1, Qt::AlignRight); } -void MetaDataWidget::setFiles(const KUrl::List& urls) +void MetaDataWidget::Private::setRowVisible(QWidget* infoWidget, bool visible) { -#ifdef HAVE_NEPOMUK - // Assure that the currently edited text is stored before - // loading the meta data for new files. - const QString currentComment = d->commentWidget->editorText(); - if ( currentComment != d->commentWidget->comment() ) { - slotCommentChanged( currentComment ); + foreach (const Row& row, m_rows) { + if (row.infoWidget == infoWidget) { + row.label->setVisible(visible); + row.infoWidget->setVisible(visible); + return; + } } - - d->loadFilesThread->loadFiles( urls ); -#else - Q_UNUSED( urls ); -#endif } -void MetaDataWidget::slotCommentChanged( const QString& s ) +MetaDataWidget::MetaDataWidget(QWidget* parent) : + QWidget(parent), + d(new Private(this)) { -#ifdef HAVE_NEPOMUK - disconnect(d->commentWidget, SIGNAL(commentChanged(const QString&)), this, SLOT(slotCommentChanged(const QString&))); - - QMutexLocker locker( &d->mutex ); - Nepomuk::MassUpdateJob* job = Nepomuk::MassUpdateJob::commentResources( d->sharedData.files.values(), s ); - locker.unlock(); - connect( job, SIGNAL( result( KJob* ) ), - this, SLOT( metadataUpdateDone() ) ); - setEnabled( false ); // no updates during execution - job->start(); - - connect(d->commentWidget, SIGNAL(commentChanged(const QString&)), this, SLOT(slotCommentChanged(const QString&))); -#else - Q_UNUSED( s ); -#endif } - -void MetaDataWidget::slotRatingChanged(unsigned int rating) +MetaDataWidget::~MetaDataWidget() { -#ifdef HAVE_NEPOMUK - QMutexLocker locker( &d->mutex ); - Nepomuk::MassUpdateJob* job = Nepomuk::MassUpdateJob::rateResources( d->sharedData.files.values(), rating ); - locker.unlock(); - connect( job, SIGNAL( result( KJob* ) ), - this, SLOT( metadataUpdateDone() ) ); - setEnabled( false ); // no updates during execution - job->start(); -#else - Q_UNUSED( rating ); -#endif + delete d; } - -void MetaDataWidget::metadataUpdateDone() +void MetaDataWidget::setItem(const KFileItem& item) { - setEnabled( true ); -} - + // 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, true); + } + d->m_modifiedInfo->setText(item.timeString()); + d->m_ownerInfo->setText(item.user()); + d->m_permissionsInfo->setText(item.permissionsString()); -bool MetaDataWidget::eventFilter(QObject* obj, QEvent* event) -{ - return QWidget::eventFilter(obj, event); + setItems(KFileItemList() << item); } - -void MetaDataWidget::slotTagClicked( const Nepomuk::Tag& tag ) +void MetaDataWidget::setItems(const KFileItemList& items) { - Q_UNUSED( tag ); -#ifdef HAVE_NEPOMUK - d->tagWidget->showTagPopup( QCursor::pos() ); -#endif -} + if (items.count() > 1) { + // calculate the size of all items and show this + // information to the user + d->m_sizeLabel->setText(i18nc("@label", "Total Size:")); + d->setRowVisible(d->m_sizeInfo, true); -void MetaDataWidget::slotLoadingFinished() -{ -#ifdef HAVE_NEPOMUK - QMutexLocker locker( &d->mutex ); - d->ratingWidget->setRating( d->sharedData.rating ); - d->commentWidget->setComment( d->sharedData.comment ); - d->tagWidget->setResources( d->sharedData.fileRes ); -#endif + quint64 totalSize = 0; + foreach (const KFileItem& item, items) { + if (!item.isDir() && !item.isLink()) { + totalSize += item.size(); + } + } + d->m_sizeInfo->setText(KIO::convertSize(totalSize)); + } } #include "metadatawidget.moc" diff --git a/src/panels/information/metadatawidget.h b/src/panels/information/metadatawidget.h index b1e774492..1a84dab0d 100644 --- a/src/panels/information/metadatawidget.h +++ b/src/panels/information/metadatawidget.h @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2007 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 * @@ -17,61 +17,27 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * ***************************************************************************/ -#ifndef METADATA_WIDGET_H -#define METADATA_WIDGET_H +#ifndef METADATAWIDGET_H +#define METADATAWIDGET_H -#include +#include -#include - -namespace Nepomuk { - class Tag; -} +class KFileItem; +class KFileItemList; +/** + * @brief + */ class MetaDataWidget : public QWidget { Q_OBJECT public: - MetaDataWidget(QWidget* parent = 0); + explicit MetaDataWidget(QWidget* parent = 0); virtual ~MetaDataWidget(); - /** - * \return true if the KMetaData system could be found and initialized. - * false if KMetaData was not available at compile time or if it has not - * been initialized properly. - */ - static bool metaDataAvailable(); - - void setRatingVisible(bool visible); - bool isRatingVisible() const; - - void setCommentVisible(bool visible); - bool isCommentVisible() const; - - void setTagsVisible(bool visible); - bool areTagsVisible() const; - -public Q_SLOTS: - void setFile(const KUrl& url); - void setFiles(const KUrl::List& urls); - -signals: - /** - * This signal gets emitted if the metadata for the set file was changed on the - * outside. NOT IMPLEMENTED YET. - */ - void metaDataChanged(); - -private Q_SLOTS: - void slotCommentChanged(const QString&); - void slotRatingChanged(unsigned int rating); - void metadataUpdateDone(); - void slotTagClicked( const Nepomuk::Tag& ); - void slotLoadingFinished(); - -protected: - bool eventFilter(QObject* obj, QEvent* event); + void setItem(const KFileItem& item); + void setItems(const KFileItemList& items); private: class Private; diff --git a/src/panels/information/metatextlabel.cpp b/src/panels/information/metatextlabel.cpp deleted file mode 100644 index 793f72669..000000000 --- a/src/panels/information/metatextlabel.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 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 "metatextlabel.h" - -#include -#include - -#include -#include -#include -#include - -MetaTextLabel::MetaTextLabel(QWidget* parent) : - QWidget(parent), - m_metaInfos() -{ - setFont(KGlobalSettings::smallestReadableFont()); - setMinimumHeight(0); -} - -MetaTextLabel::~MetaTextLabel() -{ -} - -void MetaTextLabel::clear() -{ - setMinimumHeight(0); - m_metaInfos.clear(); - update(); -} - -void MetaTextLabel::add(const QString& labelText, const QString& infoText) -{ - MetaInfo metaInfo; - metaInfo.label = labelText; - metaInfo.info = infoText; - - // add the meta information alphabetically sorted - bool inserted = false; - const int count = m_metaInfos.size(); - for (int i = 0; i < count; ++i) { - if (m_metaInfos[i].label > labelText) { - m_metaInfos.insert(i, metaInfo); - inserted = true; - break; - } - } - if (!inserted) { - m_metaInfos.append(metaInfo); - } - - setMinimumHeight(minimumHeight() + requiredHeight(metaInfo)); - update(); -} - -void MetaTextLabel::paintEvent(QPaintEvent* event) -{ - QWidget::paintEvent(event); - - QPainter painter(this); - - const QColor infoColor = palette().color(QPalette::Foreground); - QColor labelColor = infoColor; - labelColor.setAlpha(128); - - int y = 0; - const int infoWidth = infoTextWidth(); - const int labelWidth = labelTextWidth(); - const int infoX = infoWidth; - const int maxHeight = maxHeightPerLine(); - - foreach (const MetaInfo& metaInfo, m_metaInfos) { - // draw label (e. g. "Date:") - painter.setPen(labelColor); - painter.drawText(0, y, labelWidth, maxHeight, - Qt::AlignTop | Qt::AlignRight | Qt::TextWordWrap, - metaInfo.label); - - // draw information (e. g. "2008-11-09 20:12") - painter.setPen(infoColor); - painter.drawText(infoX, y, infoWidth, maxHeight, - Qt::AlignTop | Qt::AlignLeft | Qt::TextWordWrap, - metaInfo.info); - - y += requiredHeight(metaInfo); - } -} - -void MetaTextLabel::resizeEvent(QResizeEvent* event) -{ - QWidget::resizeEvent(event); - - int minimumHeight = 0; - foreach (const MetaInfo& metaInfo, m_metaInfos) { - minimumHeight += requiredHeight(metaInfo); - } - setMinimumHeight(minimumHeight); -} - -int MetaTextLabel::requiredHeight(const MetaInfo& info) const -{ - const int labelTextHeight = requiredHeight(info.label, labelTextWidth()); - const int infoTextHeight = requiredHeight(info.info, infoTextWidth()); - return qMax(labelTextHeight, infoTextHeight); -} - -int MetaTextLabel::requiredHeight(const QString& text, int width) const -{ - QTextOption textOption; - textOption.setWrapMode(QTextOption::WordWrap); - - qreal height = 0; - const int leading = fontMetrics().leading(); - - QTextLayout textLayout(text); - textLayout.setFont(font()); - textLayout.setTextOption(textOption); - - textLayout.beginLayout(); - QTextLine line = textLayout.createLine(); - while (line.isValid()) { - line.setLineWidth(width); - height += leading; - height += line.height(); - line = textLayout.createLine(); - } - textLayout.endLayout(); - - int adjustedHeight = static_cast(height); - if (adjustedHeight > maxHeightPerLine()) { - adjustedHeight = maxHeightPerLine(); - } - - return adjustedHeight + Spacing; -} - -int MetaTextLabel::maxHeightPerLine() const -{ - return fontMetrics().height() * 100; -} - -#include "metatextlabel.moc" diff --git a/src/panels/information/metatextlabel.h b/src/panels/information/metatextlabel.h deleted file mode 100644 index 500cbca69..000000000 --- a/src/panels/information/metatextlabel.h +++ /dev/null @@ -1,85 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 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 METATEXTLABEL_H -#define METATEXTLABEL_H - -#include - -/** - * @brief Displays general meta in several lines. - * - * Each line contains a label and the meta information. - */ -class MetaTextLabel : public QWidget -{ - Q_OBJECT - -public: - explicit MetaTextLabel(QWidget* parent = 0); - virtual ~MetaTextLabel(); - - void clear(); - void add(const QString& labelText, const QString& infoText); - -protected: - virtual void paintEvent(QPaintEvent* event); - virtual void resizeEvent(QResizeEvent* event); - -private: - enum { Spacing = 2 }; - - struct MetaInfo - { - QString label; - QString info; - }; - - QList m_metaInfos; - - /** - * Returns the required height in pixels for the - * label text and information text provided by \a info. - */ - int requiredHeight(const MetaInfo& info) const; - - /** Helper method for requiredHeight(const MetaInfo& info). */ - int requiredHeight(const QString& text, int width) const; - int labelTextWidth() const; - int infoTextWidth() const; - - /** - * Returns the maximum height in pixels for the text of - * one added line. The returned value does not contain - * any additional spacing between texts. - */ - int maxHeightPerLine() const; -}; - -inline int MetaTextLabel::labelTextWidth() const -{ - return width() / 2 - 2 * Spacing; -} - -inline int MetaTextLabel::infoTextWidth() const -{ - return width() / 2; -} - -#endif diff --git a/src/panels/information/nepomukmassupdatejob.cpp b/src/panels/information/nepomukmassupdatejob.cpp index 5c883fd4b..bd3aada6a 100644 --- a/src/panels/information/nepomukmassupdatejob.cpp +++ b/src/panels/information/nepomukmassupdatejob.cpp @@ -17,7 +17,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * ***************************************************************************/ -#include "nepomukmassupdatejob.h" +#include "nepomukmassupdatejob_p.h" #include #include @@ -160,4 +160,4 @@ Nepomuk::MassUpdateJob* Nepomuk::MassUpdateJob::commentResources( const QList - - 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, 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 "newtagdialog.h" - -#include - -#include -#include -#include - - -NewTagDialog::NewTagDialog( QWidget* parent ) - : KDialog( parent ) -{ - setCaption( i18nc( "@title:window", "Create New Tag" ) ); - setButtons( Ok|Cancel ); - enableButtonOk( false ); - - setupUi( mainWidget() ); - - connect( m_editTagLabel, SIGNAL( textChanged(const QString&) ), - this, SLOT( slotLabelChanged(const QString&) ) ); - - // TODO: use KGlobal::config() if NewTagDialog will be moved to kdelibs (KDE 4.2?) - KConfigGroup group(KSharedConfig::openConfig("dolphinrc"), "NewTagDialog"); - restoreDialogSize(group); -} - - -NewTagDialog::~NewTagDialog() -{ - // TODO: use KGlobal::config() if NewTagDialog will be moved to kdelibs (KDE 4.2?) - KConfigGroup group(KSharedConfig::openConfig("dolphinrc"), "NewTagDialog"); - saveDialogSize(group, KConfigBase::Persistent); -} - - -QSize NewTagDialog::sizeHint() const -{ - return QSize(400, 256); -} - -void NewTagDialog::slotLabelChanged( const QString& text ) -{ - enableButtonOk( !text.isEmpty() ); -} - - -Nepomuk::Tag NewTagDialog::createTag( QWidget* parent ) -{ - QPointer dlg = new NewTagDialog( parent ); - dlg->m_labelTitle->setText( i18nc( "@title:window", "Create New Tag" ) ); - dlg->m_labelTitle->setComment( i18nc( "@title:window subtitle to previous message", "with optional icon and description" ) ); - dlg->m_labelTitle->setPixmap( KIcon( "nepomuk" ).pixmap( 32, 32 ) ); - - dlg->m_editTagLabel->setFocus(); - - if ( dlg->exec() ) { - QString name = dlg->m_editTagLabel->text(); - QString comment = dlg->m_editTagComment->text(); - QString icon = dlg->m_buttonTagIcon->icon(); - delete dlg; - - Nepomuk::Tag newTag( name ); - newTag.setLabel( name ); - newTag.addIdentifier( name ); - if ( !comment.isEmpty() ) { - newTag.setDescription( comment ); - } - if ( !icon.isEmpty() ) { - newTag.addSymbol( icon ); - } - return newTag; - } - else { - delete dlg; - return Nepomuk::Tag(); - } -} - -#include "newtagdialog.moc" diff --git a/src/panels/information/newtagdialog.h b/src/panels/information/newtagdialog.h deleted file mode 100644 index b11cd1611..000000000 --- a/src/panels/information/newtagdialog.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - Copyright (C) 2008 by Sebastian Trueg - - 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, 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 _NEW_TAG_DIALOG_H_ -#define _NEW_TAG_DIALOG_H_ - -#include -#include "ui_newtagdialog.h" - -namespace Nepomuk { - class Tag; -} - -class NewTagDialog : public KDialog, public Ui_NewTagDialog -{ - Q_OBJECT - -public: - ~NewTagDialog(); - - virtual QSize sizeHint() const; - - static Nepomuk::Tag createTag( QWidget* parent = 0 ); - -private Q_SLOTS: - void slotLabelChanged( const QString& text ); - -private: - NewTagDialog( QWidget* parent = 0 ); -}; - -#endif diff --git a/src/panels/information/newtagdialog.ui b/src/panels/information/newtagdialog.ui deleted file mode 100644 index 1d3c3fc61..000000000 --- a/src/panels/information/newtagdialog.ui +++ /dev/null @@ -1,107 +0,0 @@ - - NewTagDialog - - - - 0 - 0 - 390 - 149 - - - - - - - - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 5 - - - - - - - - Name: - - - - - - - - - - - - - 0 - 0 - - - - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 10 - - - - - - - - Detailed description (optional): - - - - - - - - - - - KIconButton - QPushButton -

kicondialog.h
- - - KLineEdit - QLineEdit -
klineedit.h
-
- - KTitleWidget - QWidget -
ktitlewidget.h
-
- - - - diff --git a/src/panels/information/resourcetaggingwidget.cpp b/src/panels/information/resourcetaggingwidget.cpp deleted file mode 100644 index ac14e45a0..000000000 --- a/src/panels/information/resourcetaggingwidget.cpp +++ /dev/null @@ -1,206 +0,0 @@ -/* - This file is part of the Nepomuk KDE project. - Copyright (C) 2007 Sebastian Trueg - - 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 "resourcetaggingwidget.h" -#include "tagcloud.h" -#include "taggingpopup.h" -#include "nepomukmassupdatejob.h" - -#include -#include -#include -#include -#include - -#include - -namespace Nepomuk { - inline uint qHash( const Tag& res ) - { - return qHash( res.resourceUri().toString() ); - } -} - - -class Nepomuk::ResourceTaggingWidget::Private -{ -public: - QList resources; - - TagCloud* resourceTagCloud; - TaggingPopup* popup; - - QList resourceTags; - - bool tagsChanged; - - void showTaggingPopup( const QPoint& ); - void updateResources(); - void _k_slotShowTaggingPopup(); - void _k_metadataUpdateDone(); - static QList intersectTags( const QList& ); - - ResourceTaggingWidget* q; -}; - - -void Nepomuk::ResourceTaggingWidget::Private::showTaggingPopup( const QPoint& pos ) -{ - popup->showAllTags(); - resourceTags = intersectTags( resources ); - Q_FOREACH( const Tag &tag, resourceTags ) { - popup->setTagSelected( tag, true ); - } - - tagsChanged = false; - popup->exec( pos ); - - if( tagsChanged ) { - updateResources(); - } - - resourceTagCloud->showTags( resourceTags ); -} - - -void Nepomuk::ResourceTaggingWidget::Private::updateResources() -{ - MassUpdateJob* job = MassUpdateJob::tagResources( resources, resourceTags ); - connect( job, SIGNAL( result( KJob* ) ), - q, SLOT( _k_metadataUpdateDone() ) ); - q->setEnabled( false ); // no updates during execution - job->start(); -} - - -void Nepomuk::ResourceTaggingWidget::Private::_k_slotShowTaggingPopup() -{ - showTaggingPopup( QCursor::pos() ); -} - - -void Nepomuk::ResourceTaggingWidget::Private::_k_metadataUpdateDone() -{ - q->setEnabled( true ); -} - - -QList Nepomuk::ResourceTaggingWidget::Private::intersectTags( const QList& res ) -{ - if ( res.count() == 1 ) { - return res.first().tags(); - } - else if ( !res.isEmpty() ) { - // determine the tags used for all resources - QSet tags = QSet::fromList( res.first().tags() ); - QList::const_iterator it = res.begin(); - for ( ++it; it != res.end(); ++it ) { - tags.intersect( QSet::fromList( (*it).tags() ) ); - } - return tags.values(); - } - else { - return QList(); - } -} - - -Nepomuk::ResourceTaggingWidget::ResourceTaggingWidget( QWidget* parent ) - : QWidget( parent ), - d( new Private() ) -{ - d->q = this; - - QVBoxLayout* layout = new QVBoxLayout( this ); - layout->setMargin( 0 ); - d->resourceTagCloud = new TagCloud( this ); - layout->addWidget( d->resourceTagCloud ); - QLabel* changeTagsLabel = new QLabel( "

" + i18nc( "@label", "Change Tags..." ) + "", this ); - connect( changeTagsLabel, SIGNAL( linkActivated( const QString ) ), - this, SLOT( _k_slotShowTaggingPopup() ) ); - layout->addWidget( changeTagsLabel ); - - // the popup tag cloud - d->popup = new TaggingPopup; - d->popup->setSelectionEnabled( true ); - d->popup->setNewTagButtonEnabled( true ); - - connect( d->popup, SIGNAL( tagToggled( const Nepomuk::Tag&, bool ) ), - this, SLOT( slotTagToggled( const Nepomuk::Tag&, bool ) ) ); - connect( d->popup, SIGNAL( tagAdded( const Nepomuk::Tag& ) ), - this, SLOT( slotTagAdded( const Nepomuk::Tag& ) ) ); - - connect( d->resourceTagCloud, SIGNAL( tagClicked( const Nepomuk::Tag& ) ), - this, SIGNAL( tagClicked( const Nepomuk::Tag& ) ) ); -} - - -Nepomuk::ResourceTaggingWidget::~ResourceTaggingWidget() -{ - delete d->popup; - delete d; -} - - -void Nepomuk::ResourceTaggingWidget::setResource( const Nepomuk::Resource& res ) -{ - setResources( QList() << res ); -} - - -void Nepomuk::ResourceTaggingWidget::setResources( const QList& resList ) -{ - d->resources = resList; - d->resourceTagCloud->showTags( d->intersectTags( resList ) ); -} - - -void Nepomuk::ResourceTaggingWidget::slotTagToggled( const Nepomuk::Tag& tag, bool enabled ) -{ - if ( enabled ) { - d->resourceTags.append( tag ); - } - else { - d->resourceTags.removeAll( tag ); - } - d->tagsChanged = true; - d->popup->hide(); -} - - -void Nepomuk::ResourceTaggingWidget::slotTagAdded( const Nepomuk::Tag& tag ) -{ - // assign it right away - d->resourceTags.append( tag ); - d->updateResources(); -} - - -void Nepomuk::ResourceTaggingWidget::contextMenuEvent( QContextMenuEvent* e ) -{ - d->showTaggingPopup( e->globalPos() ); -} - - -void Nepomuk::ResourceTaggingWidget::showTagPopup( const QPoint& pos ) -{ - d->showTaggingPopup( pos ); -} - -#include "resourcetaggingwidget.moc" diff --git a/src/panels/information/resourcetaggingwidget.h b/src/panels/information/resourcetaggingwidget.h deleted file mode 100644 index 9976b6523..000000000 --- a/src/panels/information/resourcetaggingwidget.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - This file is part of the Nepomuk KDE project. - Copyright (C) 2007 Sebastian Trueg - - 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 _NEPOMUK_RESOURCE_TAGGING_WIDGET_H_ -#define _NEPOMUK_RESOURCE_TAGGING_WIDGET_H_ - -#include - -#include - -class QContextMenuEvent; - -namespace Nepomuk { - class ResourceTaggingWidget : public QWidget - { - Q_OBJECT - - public: - ResourceTaggingWidget( QWidget* parent = 0 ); - ~ResourceTaggingWidget(); - - Q_SIGNALS: - void tagClicked( const Nepomuk::Tag& tag ); - - public Q_SLOTS: - void setResource( const Nepomuk::Resource& ); - void setResources( const QList& ); - void showTagPopup( const QPoint& pos ); - - private Q_SLOTS: - void slotTagToggled( const Nepomuk::Tag& tag, bool enabled ); - void slotTagAdded( const Nepomuk::Tag& tag ); - - protected: - void contextMenuEvent( QContextMenuEvent* e ); - - private: - class Private; - Private* const d; - - Q_PRIVATE_SLOT( d, void _k_slotShowTaggingPopup() ) - Q_PRIVATE_SLOT( d, void _k_metadataUpdateDone() ) - }; -} - -#endif diff --git a/src/panels/information/tagcloud.cpp b/src/panels/information/tagcloud.cpp deleted file mode 100644 index ca3a51af1..000000000 --- a/src/panels/information/tagcloud.cpp +++ /dev/null @@ -1,1032 +0,0 @@ -/* - This file is part of the Nepomuk KDE project. - Copyright (C) 2007 Sebastian Trueg - - 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 "tagcloud.h" -#include "newtagdialog.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include - - -namespace { - const int s_hSpacing = 10; - const int s_vSpacing = 5; - - class TagNode { - public: - TagNode() - : weight( 0 ), - selected( false ) { - } - - bool operator==( const TagNode& other ) const { - return tag == other.tag; - } - - // fixed info - Nepomuk::Tag tag; - int weight; - - // misc - bool selected; - - // info generated by rebuildCloud - QFont font; - QRect rect; - QRect zoomedRect; - QString text; - }; - - bool tagNodeNameLessThan( const TagNode& n1, const TagNode& n2 ) { - return n1.text < n2.text; - } - - bool tagNodeWeightLessThan( const TagNode& n1, const TagNode& n2 ) { - return n1.weight < n2.weight; - } - - int rowLength( const QList& row ) { - int rowLen = 0; - for ( int j = 0; j < row.count(); ++j ) { - rowLen += row[j]->rect.width(); - if ( j < row.count()-1 ) { - rowLen += s_hSpacing; - } - } - return rowLen; - } - - int rowHeight( const QList& row ) { - int h = 0; - for ( int j = 0; j < row.count(); ++j ) { - h = qMax( row[j]->rect.height(), h ); - } - return h; - } - - QSize cloudSize( const QList >& rows ) { - int w = 0; - int h = 0; - for ( int i = 0; i < rows.count(); ++i ) { - w = qMax( w, rowLength( rows[i] ) ); - h += rowHeight( rows[i] ); - if ( i < rows.count()-1 ) { - h += s_vSpacing; - } - } - return QSize( w, h ); - } -} - - -class Nepomuk::TagCloud::Private -{ -public: - Private( TagCloud* parent ) - : maxFontSize( 0 ), - minFontSize( 0 ), - maxNumberDisplayedTags( 0 ), - selectionEnabled( false ), - newTagButtonEnabled( false ), - alignment( Qt::AlignCenter ), - sorting( SortAlpabetically ), - zoomEnabled( true ), - contextMenuEnabled( true ), - showAllTags( false ), - customNewTagAction( 0 ), - hoverTag( 0 ), - cachedHfwWidth( -1 ), - m_parent( parent ) { - newTagNode.text = i18nc( "@label", "New Tag..." ); - } - - int maxFontSize; - int minFontSize; - int maxNumberDisplayedTags; - bool selectionEnabled; - bool newTagButtonEnabled; - Qt::Alignment alignment; - Sorting sorting; - bool zoomEnabled; - bool contextMenuEnabled; - - // The resource whose tags we are showing - // invalid if we show all tags or a selection - KUrl resource; - bool showAllTags; - - // the actual nodes - QList nodes; - - // just a helper structure for speeding up things - QList > rows; - - TagNode newTagNode; - QAction* customNewTagAction; - - TagNode* hoverTag; - - QMatrix zoomMatrix; - - QSize cachedSizeHint; - int cachedHfwWidth; - int cachedHfwHeight; - - void invalidateCachedValues() { - cachedSizeHint = QSize(); - cachedHfwWidth = -1; - } - - int getMinFontSize() const; - int getMaxFontSize() const; - void updateNodeWeights(); - void updateNodeFonts(); - void sortNodes(); - void rebuildCloud(); - TagNode* tagAt( const QPoint& pos ); - TagNode* findTagInRow( const QList& row, const QPoint& pos ); - TagNode* nodeForTag( const Tag& tag ); - int calculateWeight( const Nepomuk::Tag& tag ); - -private: - TagCloud* m_parent; -}; - - -int Nepomuk::TagCloud::Private::getMinFontSize() const -{ - return minFontSize > 0 ? minFontSize : ( 8 * m_parent->font().pointSize() / 10 ); -} - - -int Nepomuk::TagCloud::Private::getMaxFontSize() const -{ - return maxFontSize > 0 ? maxFontSize : ( 22 * m_parent->font().pointSize() / 10 ); -} - - -int Nepomuk::TagCloud::Private::calculateWeight( const Nepomuk::Tag& tag ) -{ - // stupid SPARQL has no functions such as count! - Soprano::QueryResultIterator it - = ResourceManager::instance()->mainModel()->executeQuery( QString( "select ?r where { ?r <%1> <%2> . }" ) - .arg( Soprano::Vocabulary::NAO::hasTag().toString() ) - .arg( QString::fromAscii( tag.resourceUri().toEncoded() ) ), - Soprano::Query::QueryLanguageSparql ); - int w = 0; - while ( it.next() ) { - ++w; - } - return w; -} - - -void Nepomuk::TagCloud::Private::updateNodeWeights() -{ - bool changedWeights = false; - for ( QList::iterator it = nodes.begin(); - it != nodes.end(); ++it ) { - TagNode& node = *it; - int w = calculateWeight( node.tag ); - if ( w != node.weight ) { - node.weight = w; - changedWeights = true; - } - } - if ( changedWeights ) { - updateNodeFonts(); - } -} - - -void Nepomuk::TagCloud::Private::updateNodeFonts() -{ - int maxWeight = 0; - int minWeight = 0; - for ( QList::iterator it = nodes.begin(); - it != nodes.end(); ++it ) { - TagNode& node = *it; - minWeight = qMin( minWeight, node.weight ); - maxWeight = qMax( maxWeight, node.weight ); - } - - // calculate font sizes - // ---------------------------------------------- - int usedMinFontSize = getMinFontSize(); - int usedMaxFontSize = getMaxFontSize(); - for ( QList::iterator it = nodes.begin(); - it != nodes.end(); ++it ) { - TagNode& node = *it; - double normalizedWeight = (double)(node.weight - minWeight) / (double)qMax(maxWeight - minWeight, 1); - node.font = m_parent->font(); - node.font.setPointSize( usedMinFontSize + (int)((double)(usedMaxFontSize-usedMinFontSize) * normalizedWeight) ); - if( normalizedWeight > 0.8 ) - node.font.setBold( true ); - } - - if ( newTagButtonEnabled ) { - newTagNode.font = m_parent->font(); - newTagNode.font.setPointSize( usedMinFontSize ); - newTagNode.font.setUnderline( true ); - } -} - - -void Nepomuk::TagCloud::Private::sortNodes() -{ - if ( sorting == SortAlpabetically ) { - qSort( nodes.begin(), nodes.end(), tagNodeNameLessThan ); - } - else if ( sorting == SortByWeight ) { - qSort( nodes.begin(), nodes.end(), tagNodeWeightLessThan ); - } - else if ( sorting == SortRandom ) { - KRandomSequence().randomize( nodes ); - } -} - - -void Nepomuk::TagCloud::Private::rebuildCloud() -{ - // - Always try to be quadratic - // - Always prefer to expand horizontally - // - If we cannot fit everything into m_parent->contentsRect(), zoom - // - If alignment & Qt::AlignJustify insert spaces between tags - - sortNodes(); - - QRect contentsRect = m_parent->contentsRect(); - - // initialize the nodes' sizes - // ---------------------------------------------- - for ( QList::iterator it = nodes.begin(); - it != nodes.end(); ++it ) { - TagNode& node = *it; - node.rect = QFontMetrics( node.font ).boundingRect( node.text ); - } - if ( newTagButtonEnabled ) { - newTagNode.rect = QFontMetrics( newTagNode.font ).boundingRect( customNewTagAction ? customNewTagAction->text() : newTagNode.text ); - } - - - // and position the nodes - // ---------------------------------------------- - rows.clear(); - if ( !nodes.isEmpty() || newTagButtonEnabled ) { - if ( 0 ) { // FIXME: make it configurable - QRect lineRect; - QRect totalRect; - QList row; - for ( QList::iterator it = nodes.begin(); - it != nodes.end(); /* We do increment it below */ ) { - TagNode& node = *it; - - int usedSpacing = row.isEmpty() ? 0 : s_hSpacing; - if ( lineRect.width() + usedSpacing + node.rect.width() <= contentsRect.width() ) { - node.rect.moveBottomLeft( QPoint( lineRect.right() + usedSpacing, lineRect.bottom() ) ); - QRect newLineRect = lineRect.united( node.rect ); - newLineRect.moveTopLeft( lineRect.topLeft() ); - lineRect = newLineRect; - row.append( &node ); - - // update all other nodes in this line - Q_FOREACH( TagNode* n, row ) { - n->rect.moveBottom( lineRect.bottom() - ( lineRect.height() - n->rect.height() )/2 ); - } - - ++it; - } - else { - rows.append( row ); - row.clear(); - int newLineTop = lineRect.bottom() + s_vSpacing; - lineRect = QRect(); - lineRect.moveTop( newLineTop ); - } - } - rows.append( row ); - } - else { - // initialize first row - rows.append( QList() ); - for ( QList::iterator it = nodes.begin(); - it != nodes.end(); ++it ) { - TagNode& node = *it; - rows.first().append( &node ); - } - if ( newTagButtonEnabled ) { - rows.first().append( &newTagNode ); - } - - // calculate the rows - QList > bestRows( rows ); - QSize size( rowLength( rows.first() ), rowHeight( rows.first() ) ); - QSize bestSize( size ); - while ( ( size.height() < size.width() || - size.width() > contentsRect.width() ) && - size.height() <= contentsRect.height() ) { - // find the longest row - int maxRow = 0; - int maxLen = 0; - for ( int i = 0; i < rows.count(); ++i ) { - int rowLen = rowLength( rows[i] ); - if ( rowLen > maxLen ) { - maxLen = rowLen; - maxRow = i; - } - } - - // move the last item from the longest row to the next row - TagNode* node = rows[maxRow].takeLast(); - if ( rows.count() <= maxRow+1 ) { - rows.append( QList() ); - } - rows[maxRow+1].prepend( node ); - - // update the size - size = cloudSize( rows ); - - if ( size.width() < bestSize.width() && - ( size.width() > size.height() || - bestSize.width() > contentsRect.width() ) && - size.height() <= contentsRect.height() ) { - bestSize = size; - bestRows = rows; - } - } - rows = bestRows; - - // position the tags - int y = 0; - for ( QList >::iterator rowIt = rows.begin(); rowIt != rows.end(); ++rowIt ) { - QList& row = *rowIt; - int h = rowHeight( row ); - int x = 0; - Q_FOREACH( TagNode* node, row ) { - node->rect.moveTop( y + ( h - node->rect.height() )/2 ); - node->rect.moveLeft( x ); - x += s_hSpacing + node->rect.width(); - } - y += h + s_vSpacing; - } - } - - - // let's see if we have to zoom - // ---------------------------------------------- - zoomMatrix = QMatrix(); - int w = contentsRect.width(); - if ( zoomEnabled ) { - for ( QList >::iterator rowIt = rows.begin(); rowIt != rows.end(); ++rowIt ) { - QList& row = *rowIt; - w = qMax( w, row.last()->rect.right() ); - } - if ( w > contentsRect.width() ) { - double zoomFactor = ( double )contentsRect.width() / ( double )w; - zoomMatrix.scale( zoomFactor, zoomFactor ); - } - } - - // force horizontal alignment - // ---------------------------------------------- - for ( QList >::iterator rowIt = rows.begin(); rowIt != rows.end(); ++rowIt ) { - QList& row = *rowIt; - int space = /*contentsRect.right()*/w - row.last()->rect.right(); - if ( alignment & ( Qt::AlignRight|Qt::AlignHCenter ) ) { - Q_FOREACH( TagNode* node, row ) { - node->rect.moveLeft( node->rect.left() + ( alignment & Qt::AlignRight ? space : space/2 ) ); - } - } - else if ( alignment & Qt::AlignJustify && row.count() > 1 ) { - space /= ( row.count()-1 ); - int i = 0; - Q_FOREACH( TagNode* node, row ) { - node->rect.moveLeft( node->rect.left() + ( space * i++ ) ); - } - } - } - - // force vertical alignment - // ---------------------------------------------- - int verticalSpace = contentsRect.bottom() - rows.last().first()->rect.bottom(); - if ( alignment & ( Qt::AlignBottom|Qt::AlignVCenter ) ) { - for ( QList >::iterator rowIt = rows.begin(); rowIt != rows.end(); ++rowIt ) { - Q_FOREACH( TagNode* node, *rowIt ) { - node->rect.moveTop( node->rect.top() + ( alignment & Qt::AlignBottom ? verticalSpace : verticalSpace/2 ) ); - } - } - } - - for( QList::iterator it = nodes.begin(); it != nodes.end(); ++it ) { - it->zoomedRect = zoomMatrix.mapRect( it->rect ); - } - newTagNode.zoomedRect = zoomMatrix.mapRect( newTagNode.rect ); - } - - m_parent->updateGeometry(); - m_parent->update(); -} - - -// binary search in row -TagNode* Nepomuk::TagCloud::Private::findTagInRow( const QList& row, const QPoint& pos ) -{ - int x = m_parent->width() ? row.count() * pos.x() / m_parent->width() : 0; - - int i = 0; - while ( 1 ) { - if ( x-i >= 0 && x-i < row.count() && row[x-i]->zoomedRect.contains( pos ) ) { - return row[x-i]; - } - else if ( x+i >= 0 && x+i < row.count() && row[x+i]->zoomedRect.contains( pos ) ) { - return row[x+i]; - } - if ( x-i < 0 && x+i >= row.count() ) { - return 0; - } - ++i; - } - return 0; -} - - -// binary search in cloud -TagNode* Nepomuk::TagCloud::Private::tagAt( const QPoint& pos ) -{ - int y = m_parent->height() ? rows.count() * pos.y() / m_parent->height() : 0; - - int i = 0; - while ( 1 ) { - if ( y-i >= 0 && y-i < rows.count() ) { - if ( TagNode* node = findTagInRow( rows[y-i], pos ) ) { - return node; - } - } - if ( y+i >= 0 && y+i < rows.count() ) { - if ( TagNode* node = findTagInRow( rows[y+i], pos ) ) { - return node; - } - } - if ( y-i < 0 && y+i >= rows.count() ) { - return 0; - } - ++i; - } - return 0; -} - - -TagNode* Nepomuk::TagCloud::Private::nodeForTag( const Tag& tag ) -{ - for ( QList::iterator it = nodes.begin(); - it != nodes.end(); ++it ) { - TagNode& node = *it; - if ( tag == node.tag ) { - return &node; - } - } - return 0; -} - - - -Nepomuk::TagCloud::TagCloud( QWidget* parent ) - : QFrame( parent ), - d( new Private(this) ) -{ - QSizePolicy policy( QSizePolicy::Preferred, - QSizePolicy::Preferred ); - policy.setHeightForWidth( true ); - setSizePolicy( policy ); - setMouseTracking( true ); - - // Since signals are delivered in no particular order - // our slot might be called before the resources are updated - // Then, we would use invalid cached data. - // By using queued connections this problem should be solved. - connect( ResourceManager::instance()->mainModel(), - SIGNAL( statementAdded( const Soprano::Statement& ) ), - this, - SLOT( slotStatementAdded( const Soprano::Statement& ) ), - Qt::QueuedConnection ); - connect( ResourceManager::instance()->mainModel(), - SIGNAL( statementRemoved( const Soprano::Statement& ) ), - this, - SLOT( slotStatementRemoved( const Soprano::Statement& ) ), - Qt::QueuedConnection ); -} - - -Nepomuk::TagCloud::~TagCloud() -{ - delete d; -} - - -void Nepomuk::TagCloud::setMaxFontSize( int size ) -{ - d->invalidateCachedValues(); - d->maxFontSize = size; - d->updateNodeFonts(); - d->rebuildCloud(); -} - - -void Nepomuk::TagCloud::setMinFontSize( int size ) -{ - d->invalidateCachedValues(); - d->minFontSize = size; - d->updateNodeFonts(); - d->rebuildCloud(); -} - - -void Nepomuk::TagCloud::setMaxNumberDisplayedTags( int n ) -{ - d->maxNumberDisplayedTags = n; - d->rebuildCloud(); -} - - -void Nepomuk::TagCloud::setSelectionEnabled( bool enabled ) -{ - d->selectionEnabled = enabled; - update(); -} - - -void Nepomuk::TagCloud::setNewTagButtonEnabled( bool enabled ) -{ - d->newTagButtonEnabled = enabled; - d->rebuildCloud(); -} - - -bool Nepomuk::TagCloud::zoomEnabled() const -{ - return d->zoomEnabled; -} - - -void Nepomuk::TagCloud::setZoomEnabled( bool zoom ) -{ - if ( d->zoomEnabled != zoom ) { - d->zoomEnabled = zoom; - d->rebuildCloud(); - } -} - - -void Nepomuk::TagCloud::setContextMenuEnabled( bool enabled ) -{ - d->contextMenuEnabled = enabled; -} - - -void Nepomuk::TagCloud::setAlignment( Qt::Alignment alignment ) -{ - d->alignment = alignment; - d->rebuildCloud(); -} - - -void Nepomuk::TagCloud::setSorting( Sorting s ) -{ - d->invalidateCachedValues(); - d->sorting = s; - d->rebuildCloud(); -} - - -void Nepomuk::TagCloud::showAllTags() -{ - showTags( Nepomuk::Tag::allTags() ); - d->showAllTags = true; -} - - -void Nepomuk::TagCloud::showResourceTags( const Resource& resource ) -{ - showTags( resource.tags() ); - d->resource = resource.resourceUri(); -} - - -void Nepomuk::TagCloud::showTags( const QList& tags ) -{ - d->resource = KUrl(); - d->showAllTags = false; - d->invalidateCachedValues(); - d->nodes.clear(); - Q_FOREACH( const Tag &tag, tags ) { - TagNode node; - node.tag = tag; - node.weight = d->calculateWeight( tag ); - node.text = node.tag.genericLabel(); - - d->nodes.append( node ); - } - d->updateNodeFonts(); - d->rebuildCloud(); -} - - -void Nepomuk::TagCloud::setTagSelected( const Tag& tag, bool selected ) -{ - if ( TagNode* node = d->nodeForTag( tag ) ) { - node->selected = selected; - if ( d->selectionEnabled ) { - update( node->zoomedRect ); - } - } -} - - -QSize Nepomuk::TagCloud::sizeHint() const -{ - // If we have tags d->rebuildCloud() has been called at least once, - // thus, we have proper rects (i.e. needed sizes) - - if ( !d->cachedSizeHint.isValid() ) { - QList > rows; - rows.append( QList() ); - for ( QList::iterator it = d->nodes.begin(); - it != d->nodes.end(); ++it ) { - TagNode& node = *it; - rows.first().append( &node ); - } - if ( d->newTagButtonEnabled ) { - rows.first().append( &d->newTagNode ); - } - - QSize size( rowLength( rows.first() ), rowHeight( rows.first() ) ); - QSize bestSize( size ); - while ( size.height() < size.width() ) { - // find the longest row - int maxRow = 0; - int maxLen = 0; - for ( int i = 0; i < rows.count(); ++i ) { - int rowLen = rowLength( rows[i] ); - if ( rowLen > maxLen ) { - maxLen = rowLen; - maxRow = i; - } - } - - // move the last item from the longest row to the next row - TagNode* node = rows[maxRow].takeLast(); - if ( rows.count() <= maxRow+1 ) { - rows.append( QList() ); - } - rows[maxRow+1].prepend( node ); - - // update the size - size = cloudSize( rows ); - - if ( size.width() < bestSize.width() && - size.width() > size.height() ) { - bestSize = size; - } - } - - d->cachedSizeHint = QSize( bestSize.width() + frameWidth()*2, - bestSize.height() + frameWidth()*2 ); - } - - return d->cachedSizeHint; -} - - -QSize Nepomuk::TagCloud::minimumSizeHint() const -{ - return QFrame::minimumSizeHint(); - // If we have tags d->rebuildCloud() has been called at least once, - // thus, we have proper rects (i.e. needed sizes) - if ( d->nodes.isEmpty() && !d->newTagButtonEnabled ) { - return QSize( fontMetrics().width( i18nc( "@label Indicator when no tags defined", "No Tags" ) ), fontMetrics().height() ); - } - else { - QSize size; - for ( QList::iterator it = d->nodes.begin(); - it != d->nodes.end(); ++it ) { - size.setWidth( qMax( size.width(), ( *it ).rect.width() ) ); - size.setHeight( qMax( size.height(), ( *it ).rect.height() ) ); - } - if ( d->newTagButtonEnabled ) { - size.setWidth( qMax( size.width(), d->newTagNode.rect.width() ) ); - size.setHeight( qMax( size.height(), d->newTagNode.rect.height() ) ); - } - size.setWidth( size.width() + frameWidth()*2 ); - size.setHeight( size.height() + frameWidth()*2 ); - return size; - } -} - - -int Nepomuk::TagCloud::heightForWidth( int contentsWidth ) const -{ - // If we have tags d->rebuildCloud() has been called at least once, - // thus, we have proper rects (i.e. needed sizes) - - if ( d->cachedHfwWidth != contentsWidth ) { - // have to keep in mind the frame - contentsWidth -= frameWidth()*2; - - QList allNodes; - for ( QList::iterator it = d->nodes.begin(); - it != d->nodes.end(); ++it ) { - TagNode& node = *it; - allNodes.append( &node ); - } - if ( d->newTagButtonEnabled ) { - allNodes.append( &d->newTagNode ); - } - - int h = 0; - bool newRow = true; - int rowW = 0; - int rowH = 0; - int maxW = 0; - for ( int i = 0; i < allNodes.count(); ++i ) { - int w = rowW; - if ( !newRow ) { - w += s_hSpacing; - } - newRow = false; - w += allNodes[i]->rect.width(); - if ( w <= contentsWidth ) { - rowH = qMax( rowH, allNodes[i]->rect.height() ); - rowW = w; - } - else { - if ( h > 0 ) { - h += s_vSpacing; - } - h += rowH; - rowH = allNodes[i]->rect.height(); - rowW = allNodes[i]->rect.width(); - } - maxW = qMax( maxW, rowW ); - } - if ( rowH > 0 ) { - h += s_vSpacing + rowH; - } - - d->cachedHfwWidth = contentsWidth; - d->cachedHfwHeight = h; - - // zooming - if ( maxW > contentsWidth ) { - d->cachedHfwHeight = d->cachedHfwHeight * contentsWidth / maxW; - } - } - - return d->cachedHfwHeight + frameWidth()*2; -} - - -void Nepomuk::TagCloud::resizeEvent( QResizeEvent* e ) -{ - QFrame::resizeEvent( e ); - d->rebuildCloud(); - update(); -} - - -void Nepomuk::TagCloud::paintEvent( QPaintEvent* e ) -{ - QFrame::paintEvent( e ); - - KStatefulBrush normalTextBrush( KColorScheme::View, KColorScheme::NormalText ); - KStatefulBrush activeTextBrush( KColorScheme::View, KColorScheme::VisitedText ); - KStatefulBrush hoverTextBrush( KColorScheme::View, KColorScheme::ActiveText ); - - QPainter p( this ); - QRegion paintRegion = e->region(); - - p.save(); - p.setMatrix( d->zoomMatrix ); - - for ( QList::iterator it = d->nodes.begin(); - it != d->nodes.end(); ++it ) { - TagNode& node = *it; - - if ( paintRegion.contains( node.zoomedRect ) ) { - p.setFont( node.font ); - - if ( &node == d->hoverTag ) { - p.setPen( hoverTextBrush.brush( this ).color() ); - } - else if ( d->selectionEnabled && node.selected ) { - p.setPen( activeTextBrush.brush( this ).color() ); - } - else { - p.setPen( normalTextBrush.brush( this ).color() ); - } - p.drawText( node.rect, Qt::AlignCenter, node.text ); - } - } - - if ( d->newTagButtonEnabled ) { - p.setFont( d->newTagNode.font ); - if ( &d->newTagNode == d->hoverTag ) { - p.setPen( hoverTextBrush.brush( this ).color() ); - } - else { - p.setPen( normalTextBrush.brush( this ).color() ); - } - p.drawText( d->newTagNode.rect, Qt::AlignCenter, d->customNewTagAction ? d->customNewTagAction->text() : d->newTagNode.text ); - } - - p.restore(); -} - - -void Nepomuk::TagCloud::mousePressEvent( QMouseEvent* e ) -{ - if ( e->button() == Qt::LeftButton ) { - if ( TagNode* node = d->tagAt( e->pos() ) ) { - kDebug() << "clicked" << node->text; - if ( node == &d->newTagNode ) { - if ( d->customNewTagAction ) { - d->customNewTagAction->trigger(); - } - else { - // FIXME: nicer gui - Tag newTag = NewTagDialog::createTag( this ); - if ( newTag.isValid() ) { - emit tagAdded( newTag ); - } - } - } - else { - emit tagClicked( node->tag ); - if ( d->selectionEnabled ) { - kDebug() << "Toggleing tag" << node->text; - node->selected = !node->selected; - emit tagToggled( node->tag, node->selected ); - update( node->zoomedRect ); - } - } - } - } - else if ( d->contextMenuEnabled && - e->button() == Qt::RightButton ) { - if ( TagNode* node = d->tagAt( e->pos() ) ) { - KMenu menu; - QAction* a = menu.addAction( KIcon( "edit-delete" ), i18nc( "@action:menu", "Delete tag '%1'", node->text ) ); - if ( menu.exec( e->globalPos() ) == a && - KMessageBox::questionYesNo( this, i18n( "Do you really want to delete tag '%1'?", node->text ) ) == KMessageBox::Yes ) { - if ( d->selectionEnabled && - node->selected ) { - node->selected = false; - emit tagToggled( node->tag, false ); - } - node->tag.remove(); - d->nodes.removeAll( *node ); - d->rebuildCloud(); - } - } - } -} - - -void Nepomuk::TagCloud::mouseMoveEvent( QMouseEvent* e ) -{ - if ( e->buttons() == Qt::NoButton ) { - - TagNode* oldHoverTag = d->hoverTag; - - if ( ( d->hoverTag = d->tagAt( e->pos() ) ) && - !d->selectionEnabled ) { - setCursor( Qt::PointingHandCursor ); - } - else if ( d->newTagButtonEnabled && - d->newTagNode.zoomedRect.contains( e->pos() ) ) { - d->hoverTag = &d->newTagNode; - setCursor( Qt::PointingHandCursor ); - } - else { - unsetCursor(); - } - - if ( oldHoverTag || d->hoverTag ) { - QRect updateRect; - if ( d->hoverTag ) - updateRect = updateRect.united( d->hoverTag->zoomedRect ); - if ( oldHoverTag ) - updateRect = updateRect.united( oldHoverTag->zoomedRect ); - - update( updateRect ); - } - } -} - - -void Nepomuk::TagCloud::leaveEvent( QEvent* ) -{ - unsetCursor(); - if ( d->hoverTag ) { - QRect updateRect = d->hoverTag->zoomedRect; - d->hoverTag = 0; - update( updateRect ); - } -} - - -void Nepomuk::TagCloud::slotStatementAdded( const Soprano::Statement& s ) -{ - if ( s.predicate().uri() == Soprano::Vocabulary::RDF::type() && - s.object().uri() == Nepomuk::Tag::resourceTypeUri() ) { - // new tag created - if ( d->showAllTags ) { - showAllTags(); - } - } - else if ( s.predicate().uri() == Nepomuk::Resource::tagUri() ) { - if ( s.subject().uri() == d->resource ) { - showResourceTags( d->resource ); - } - else { - // weights might have changed - d->updateNodeWeights(); - d->rebuildCloud(); - } - } -} - - -void Nepomuk::TagCloud::slotStatementRemoved( const Soprano::Statement& s ) -{ - // FIXME: In theory might contain empty nodes as wildcards - - if ( s.predicate().uri() == Nepomuk::Resource::tagUri() ) { - if ( d->resource.isValid() && - d->resource == s.subject().uri() ) { - showResourceTags( d->resource ); - } - else { - // weights might have changed - d->updateNodeWeights(); - d->rebuildCloud(); - } - } - else if ( s.predicate().uri() == Soprano::Vocabulary::RDF::type() && - s.object().uri() == Nepomuk::Tag::resourceTypeUri() ) { - // tag deleted - if ( d->showAllTags ) { - showAllTags(); - } - } -} - - -void Nepomuk::TagCloud::setCustomNewTagAction( QAction* action ) -{ - d->customNewTagAction = action; - setNewTagButtonEnabled( action != 0 ); -} - -#include "tagcloud.moc" diff --git a/src/panels/information/tagcloud.h b/src/panels/information/tagcloud.h deleted file mode 100644 index 9710ca9b7..000000000 --- a/src/panels/information/tagcloud.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - This file is part of the Nepomuk KDE project. - Copyright (C) 2007 Sebastian Trueg - - 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 _NEPOMUK_TAG_CLOUD_H_ -#define _NEPOMUK_TAG_CLOUD_H_ - -#include -#include - -#include - -#include - -class QResizeEvent; -class QPaintEvent; -class QMouseEvent; -class QEvent; - -namespace Nepomuk { - class TagCloud : public QFrame - { - Q_OBJECT - - public: - TagCloud( QWidget* parent = 0 ); - ~TagCloud(); - - enum Sorting { - SortAlpabetically, - SortByWeight, - SortRandom - }; - - int heightForWidth( int w ) const; - QSize sizeHint() const; - QSize minimumSizeHint() const; - - bool zoomEnabled() const; - - public Q_SLOTS: - /** - * Set the maximum used font size. The default is 0 - * which means to calculate proper values from the KDE - * defaults. - */ - void setMaxFontSize( int size ); - - /** - * Set the minimum used font size. The default is 0 - * which means to calculate proper values from the KDE - * defaults. - */ - void setMinFontSize( int size ); - - /** - * Set the maximum number of displayed tags. The default is 0 - * which means to display all tags. - * - * NOT IMPLEMENTED YET - */ - void setMaxNumberDisplayedTags( int n ); - - /** - * Allow selection of tags, i.e. enabling and disabling of tags. - */ - void setSelectionEnabled( bool enabled ); - - void setNewTagButtonEnabled( bool enabled ); - void setContextMenuEnabled( bool enabled ); - void setAlignment( Qt::Alignment alignment ); - - void setZoomEnabled( bool zoom ); - - /** - * Default: SortAlpabetically - */ - void setSorting( Sorting ); - - /** - * Will reset tags set via showTags() - */ - void showAllTags(); - - /** - * Set the tags to be shown in the tag cloud. - * If the new tag button is enabled (setEnableNewTagButton()) - * new tags will automatically be added to the list of shown tags. - */ - void showTags( const QList& tags ); - - void showResourceTags( const Resource& resource ); - - /** - * Select or deselect a tag. This does only make sense - * if selection is enabled and \p tag is actually - * displayed. - * - * \sa setSelectionEnabled - */ - void setTagSelected( const Tag& tag, bool selected ); - - void setCustomNewTagAction( QAction* action ); - - Q_SIGNALS: - void tagClicked( const Nepomuk::Tag& tag ); - void tagAdded( const Nepomuk::Tag& tag ); - void tagToggled( const Nepomuk::Tag& tag, bool enabled ); - - protected: - void resizeEvent( QResizeEvent* e ); - void paintEvent( QPaintEvent* e ); - void mousePressEvent( QMouseEvent* ); - void mouseMoveEvent( QMouseEvent* ); - void leaveEvent( QEvent* ); - - private Q_SLOTS: - void slotStatementAdded( const Soprano::Statement& s ); - void slotStatementRemoved( const Soprano::Statement& s ); - - private: - class Private; - Private* const d; - }; -} - -#endif diff --git a/src/panels/information/taggingpopup.cpp b/src/panels/information/taggingpopup.cpp deleted file mode 100644 index 76db05970..000000000 --- a/src/panels/information/taggingpopup.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/* - This file is part of the Nepomuk KDE project. - Copyright (C) 2007 Sebastian Trueg - - 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 "taggingpopup.h" - -#include -#include -#include -#include -#include - -#include -#include - - -class Nepomuk::TaggingPopup::Private -{ -public: - Private( TaggingPopup* parent ) - : eventLoop( 0 ), - m_parent( parent ) { - } - - QEventLoop* eventLoop; - QPoint popupPos; - - QRect geometryForPopupPos( const QPoint& p ) { - QSize size = m_parent->sizeHint(); - - // we want a little margin - const int margin = KDialog::marginHint(); - size.setHeight( size.height() + margin*2 ); - size.setWidth( size.width() + margin*2 ); - - QRect screen = QApplication::desktop()->screenGeometry( QApplication::desktop()->screenNumber( p ) ); - - // calculate popup position - QPoint pos( p.x() - size.width()/2, p.y() - size.height()/2 ); - - // ensure we do not leave the desktop - if ( pos.x() + size.width() > screen.right() ) { - pos.setX( screen.right() - size.width() ); - } - else if ( pos.x() < screen.left() ) { - pos.setX( screen.left() ); - } - - if ( pos.y() + size.height() > screen.bottom() ) { - pos.setY( screen.bottom() - size.height() ); - } - else if ( pos.y() < screen.top() ) { - pos.setY( screen.top() ); - } - - return QRect( pos, size ); - } - -private: - TaggingPopup* m_parent; -}; - - -Nepomuk::TaggingPopup::TaggingPopup( QWidget* parent ) - : TagCloud( parent ), - d( new Private( this ) ) -{ - setFrameStyle( QFrame::StyledPanel ); - setWindowFlags( Qt::Popup ); -} - - -Nepomuk::TaggingPopup::~TaggingPopup() -{ - delete d; -} - - -void Nepomuk::TaggingPopup::popup( const QPoint& p ) -{ - setGeometry( d->geometryForPopupPos( p ) ); - d->popupPos = p; - - show(); -} - - -void Nepomuk::TaggingPopup::exec( const QPoint& pos ) -{ - QEventLoop eventLoop; - d->eventLoop = &eventLoop; - popup( pos ); - - QPointer guard = this; - (void) eventLoop.exec(); - if ( !guard.isNull() ) - d->eventLoop = 0; -} - - -void Nepomuk::TaggingPopup::mousePressEvent( QMouseEvent* e ) -{ - if ( !rect().contains( e->pos() ) ) { - hide(); - } - else { - TagCloud::mousePressEvent( e ); - } -} - - -void Nepomuk::TaggingPopup::hideEvent( QHideEvent* e ) -{ - Q_UNUSED( e ); - if ( d->eventLoop ) { - d->eventLoop->exit(); - } -} - - -bool Nepomuk::TaggingPopup::event( QEvent* e ) -{ - if ( e->type() == QEvent::LayoutRequest ) { - if ( isVisible() ) { - setGeometry( d->geometryForPopupPos( d->popupPos ) ); - return true; - } - } - - return TagCloud::event( e ); -} - diff --git a/src/panels/information/taggingpopup.h b/src/panels/information/taggingpopup.h deleted file mode 100644 index db9472b23..000000000 --- a/src/panels/information/taggingpopup.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - This file is part of the Nepomuk KDE project. - Copyright (C) 2007 Sebastian Trueg - - 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 _NEPOMUK_TAGGING_POPUP_H_ -#define _NEPOMUK_TAGGING_POPUP_H_ - -#include "tagcloud.h" - -class QMouseEvent; -class QHideEvent; - -namespace Nepomuk { - class TaggingPopup : public TagCloud - { - public: - TaggingPopup( QWidget* parent = 0 ); - ~TaggingPopup(); - - void popup( const QPoint& pos ); - void exec( const QPoint& pos ); - - bool event( QEvent* e ); - - protected: - void mousePressEvent( QMouseEvent* e ); - void hideEvent( QHideEvent* e ); - - private: - class Private; - Private* const d; - }; -} - -#endif diff --git a/src/panels/information/taggingwidget.cpp b/src/panels/information/taggingwidget.cpp new file mode 100644 index 000000000..96690f28e --- /dev/null +++ b/src/panels/information/taggingwidget.cpp @@ -0,0 +1,31 @@ +/*************************************************************************** + * 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" + +TaggingWidget::TaggingWidget(QWidget* parent) : + QWidget(parent) +{ +} + +TaggingWidget::~TaggingWidget() +{ +} + +#include "taggingwidget_p.moc" diff --git a/src/panels/information/taggingwidget_p.h b/src/panels/information/taggingwidget_p.h new file mode 100644 index 000000000..036caff9a --- /dev/null +++ b/src/panels/information/taggingwidget_p.h @@ -0,0 +1,34 @@ +/*************************************************************************** + * 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 +#define TAGGING_WIDGET + +#include + +class TaggingWidget : public QWidget +{ + Q_OBJECT + +public: + TaggingWidget(QWidget* parent); + virtual ~TaggingWidget(); +}; + +#endif diff --git a/src/viewproperties.cpp b/src/viewproperties.cpp index 3fc102d6c..c22b0adc1 100644 --- a/src/viewproperties.cpp +++ b/src/viewproperties.cpp @@ -29,10 +29,6 @@ #include #include -#ifdef HAVE_NEPOMUK - #include -#endif - #include #include #include @@ -46,14 +42,6 @@ ViewProperties::ViewProperties(const KUrl& url) : m_autoSave(true), m_node(0) { -#ifdef HAVE_NEPOMUK - static bool checkedNepomukSupport = false; - if (!checkedNepomukSupport) { - m_nepomukSupport = !Nepomuk::ResourceManager::instance()->init(); - checkedNepomukSupport = true; - } -#endif - KUrl cleanUrl(url); cleanUrl.cleanPath(); m_filepath = cleanUrl.toLocalFile();