Improved KMetaData integration. The Dolphin info sidebar now uses KMetaData to allow file rating, commenting, and tagging.

This commit is indended to show what can be done with KMetaData in an easy way. The GUI is not perfect yet.

svn path=/trunk/KDE/kdebase/apps/; revision=644510
This commit is contained in:
Sebastian Trueg 2007-03-20 09:01:22 +00:00
parent 397b9bd450
commit 4af3a2dcb4
9 changed files with 232 additions and 224 deletions

View file

@ -33,7 +33,7 @@ set(dolphin_SRCS
iconsviewsettingspage.cpp
infosidebarpage.cpp
main.cpp
metadataloader.cpp
metadatawidget.cpp
protocolcombo.cpp
pixmapviewer.cpp
renamedialog.cpp
@ -68,13 +68,14 @@ qt4_add_dbus_adaptor(dolphin_SRCS
kde4_add_executable(dolphin ${dolphin_SRCS})
# find Nepomuk's libkmetadata
find_path(KMETADATA_INCLUDE_DIR NAMES kmetadata/kmetadata.h PATHS ${KDE4_INCLUDE_DIR})
find_library(KMETADATA_LIBRARY NAMES kmetadata PATHS ${KDE4_LIB_DIR})
if(KMETADATA_INCLUDE_DIR AND KMETADATA_LIBRARY)
set(KDE4_KMETADATA kmetadata)
find_library(KMETADATA_LIBRARY NAMES kmetadata kmetadatatools PATHS ${KDE4_LIB_DIR})
find_library(KMETADATA_TOOLS_LIBRARY NAMES kmetadatatools PATHS ${KDE4_LIB_DIR})
if(KMETADATA_INCLUDE_DIR AND KMETADATA_LIBRARY AND KMETADATA_TOOLS_LIBRARY)
set(KDE4_KMETADATA kmetadata kmetadatatools)
set(HAVE_KMETADATA 1)
else(KMETADATA_INCLUDE_DIR AND KMETADATA_LIBRARY)
set(KDE4_KMETADATA "")
endif(KMETADATA_INCLUDE_DIR AND KMETADATA_LIBRARY)
endif(KMETADATA_INCLUDE_DIR AND KMETADATA_LIBRARY AND KMETADATA_TOOLS_LIBRARY)
configure_file(config-kmetadata.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-kmetadata.h )
target_link_libraries(dolphin ${KDE4_KDECORE_LIBS} ${KDE4_KDEPRINT_LIBS} ${KDE4_KMETADATA} konq)

View file

@ -20,7 +20,6 @@
#include "dolphinapplication.h"
#include "dolphinmainwindow.h"
#include "metadataloader.h"
#include <applicationadaptor.h>
#include <kurl.h>
@ -56,12 +55,6 @@ DolphinMainWindow* DolphinApplication::createMainWindow()
return mainWindow;
}
MetadataLoader* DolphinApplication::metadataLoader()
{
static MetadataLoader loader;
return &loader;
}
int DolphinApplication::openWindow(const QString& url)
{
DolphinMainWindow* win = createMainWindow();

View file

@ -25,7 +25,6 @@
#include <kuniqueapplication.h>
class DolphinMainWindow;
class MetadataLoader;
/**
* @brief Holds the application data which can be accessed.
@ -52,11 +51,6 @@ public:
DolphinMainWindow* createMainWindow();
void refreshMainWindows();
/**
* Returns the metadata loader.
*/
MetadataLoader* metadataLoader();
public slots:
int openWindow(const QString& url);

View file

@ -29,7 +29,7 @@
#include "dolphinsettingsdialog.h"
#include "dolphinstatusbar.h"
#include "infosidebarpage.h"
#include "metadataloader.h"
#include "metadatawidget.h"
#include "mainwindowadaptor.h"
#include "treeviewsidebarpage.h"
#include "urlnavigator.h"
@ -1058,7 +1058,7 @@ void DolphinMainWindow::init()
resize(640, 480);
}
#ifdef HAVE_KMETADATA
if (!DolphinApplication::app()->metadataLoader()->storageUp())
if ( !MetaDataWidget::metaDataAvailable() )
activeView()->statusBar()->setMessage(i18n("Failed to contact Nepomuk service, annotation and tagging are disabled."), DolphinStatusBar::Error);
#endif
}

View file

@ -17,6 +17,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#include <config-kmetadata.h>
#include "infosidebarpage.h"
#include <assert.h>
@ -42,13 +44,14 @@
#include <kglobalsettings.h>
#include <kfilemetainfo.h>
#include <kvbox.h>
#include <kratingwidget.h>
#include <kseparator.h>
#include "dolphinmainwindow.h"
#include "dolphinapplication.h"
#include "pixmapviewer.h"
#include "dolphinsettings.h"
#include "metadataloader.h"
#include "metadatawidget.h"
InfoSidebarPage::InfoSidebarPage(DolphinMainWindow* mainWindow, QWidget* parent) :
SidebarPage(mainWindow, parent),
@ -57,8 +60,7 @@ InfoSidebarPage::InfoSidebarPage(DolphinMainWindow* mainWindow, QWidget* parent)
m_timer(0),
m_preview(0),
m_name(0),
m_infos(0),
m_metadata(DolphinApplication::app()->metadataLoader())
m_infos(0)
{
const int spacing = KDialog::spacingHint();
@ -91,18 +93,10 @@ InfoSidebarPage::InfoSidebarPage(DolphinMainWindow* mainWindow, QWidget* parent)
KSeparator* sep2 = new KSeparator(this);
// annotation
KSeparator* sep3 = 0;
if (m_metadata->storageUp()) {
m_annotationLabel = new QLabel(this);
m_annotationLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
m_annotationLabel->setTextFormat(Qt::RichText);
m_annotationLabel->setWordWrap(true);
m_annotationButton = new QPushButton("", this);
m_annotationButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
connect(m_annotationButton, SIGNAL(released()), this, SLOT(changeAnnotation()));
sep3 = new KSeparator(this);
}
if ( MetaDataWidget::metaDataAvailable() )
m_metadataWidget = new MetaDataWidget( this );
else
m_metadataWidget = 0;
// actions
m_actionBox = new KVBox(this);
@ -118,10 +112,9 @@ InfoSidebarPage::InfoSidebarPage(DolphinMainWindow* mainWindow, QWidget* parent)
layout->addWidget(sep1);
layout->addWidget(m_infos);
layout->addWidget(sep2);
if (m_metadata->storageUp()) {
layout->addWidget(m_annotationLabel);
layout->addWidget(m_annotationButton);
layout->addWidget(sep3);
if ( m_metadataWidget ) {
layout->addWidget( m_metadataWidget );
layout->addWidget( new KSeparator( this ) );
}
layout->addWidget(m_actionBox);
layout->addWidget(dummy);
@ -309,7 +302,8 @@ void InfoSidebarPage::createMetaInfo()
if (fileItem.isDir()) {
addInfoLine(i18n("Type:"), i18n("Directory"));
}
showAnnotation(m_shownUrl);
if ( MetaDataWidget::metaDataAvailable() )
m_metadataWidget->setFile( fileItem.url() );
}
else if (view->selectedItems().count() == 1) {
KFileItem* fileItem = view->selectedItems()[0];
@ -329,10 +323,11 @@ void InfoSidebarPage::createMetaInfo()
}
}
}
showAnnotation(fileItem->url());
if ( MetaDataWidget::metaDataAvailable() )
m_metadataWidget->setFile( fileItem->url() );
}
else {
showAnnotations(view->selectedItems().urlList());
m_metadataWidget->setFiles( view->selectedItems().urlList() );
unsigned long int totSize = 0;
foreach(KFileItem* item, view->selectedItems()) {
totSize += item->size(); //FIXME what to do with directories ? (same with the one-item-selected-code), item->size() does not return the size of the content : not very instinctive for users
@ -516,73 +511,7 @@ void InfoSidebarPage::insertActions()
}
}
void InfoSidebarPage::showAnnotation(const KUrl& file)
{
if(m_metadata->storageUp()) {
QString text = m_metadata->annotation(file);
if (!text.isEmpty()) {
m_annotationLabel->show();
m_annotationLabel->setText(QString("<b>%1</b> :<br/>%2").arg(i18n("Annotation")).arg(text));
m_annotationButton->setText(i18n("Change annotation"));
} else {
m_annotationLabel->hide();
m_annotationButton->setText(i18n("Annotate file"));
}
}
}
void InfoSidebarPage::showAnnotations(const KUrl::List& files)
{
if (m_metadata->storageUp()) {
bool hasAnnotation = false;
unsigned int annotateNum = 0;
QString firsts = QString("<b>%1 :</b><br/>").arg(i18n("Annotations"));
foreach (KUrl file, files) {
QString annotation = m_metadata->annotation(file);
if (!annotation.isEmpty()) {
hasAnnotation = true;
if (annotateNum < 3) {
// don't show more than 3 annotations
firsts += m_annotationLabel->fontMetrics().elidedText(QString("<b>%1</b> : %2<br/>").arg(file.fileName()).arg(annotation), Qt::ElideRight, width());//FIXME not really the good method, does not handle resizing ...
annotateNum++;
}
}
}
if (hasAnnotation) {
m_annotationLabel->show();
m_annotationLabel->setText(firsts);
}
else {
m_annotationLabel->hide();
}
m_annotationButton->setText(hasAnnotation ? i18n("Change annotations") : i18n("Annotate files"));
}
}
void InfoSidebarPage::changeAnnotation()
{
bool ok = false;
KUrl::List files(mainWindow()->activeView()->selectedItems().urlList());
QString name, old;
if (files.isEmpty()) {
files << m_shownUrl;
}
else if (files.count() == 1) {
name = files[0].url();
old = m_metadata->annotation(files[0]);
}
else {
name = QString("%1 files").arg(files.count());
old = QString();
}
QString text = QInputDialog::getText(this, "Annotate", QString("Set annotation for %1").arg(name), QLineEdit::Normal, old, &ok);//FIXME temporary, must move to a real dialog
if(ok) {
foreach(KUrl file, files) {
m_metadata->setAnnotation(file, text);
}
showAnnotation(files[0]);
}
}
ServiceButton::ServiceButton(const QIcon& icon,
const QString& text,

View file

@ -48,7 +48,7 @@ class QLabel;
class KVBox;
class Q3Grid;
class PixmapViewer;
class MetadataLoader;
class MetaDataWidget;
/**
* @brief Prototype for a information sidebar.
@ -114,12 +114,6 @@ private slots:
*/
void startService(int index);
/**
* Opens a dialog to change the annotation of the currently selected
* file(s).
*/
void changeAnnotation();
private:
/**
* Connects to signals from the currently active Dolphin view to get
@ -157,16 +151,6 @@ private:
*/
void insertActions();
/**
* Show the annotation of a file in the sidebar.
*/
void showAnnotation(const KUrl& file);
/**
* Show the annotations of multiple files in the sidebar.
*/
void showAnnotations(const KUrl::List& files);
bool m_multipleSelection;
bool m_pendingPreview;
QTimer* m_timer;
@ -183,9 +167,7 @@ private:
Q3PtrList<QWidget> m_actionWidgets; // TODO: use children() from QObject instead
Q3ValueVector<KDEDesktopMimeType::Service> m_actionsVector;
QLabel* m_annotationLabel;
QPushButton* m_annotationButton;//Move to sthing sexy visually
MetadataLoader* m_metadata;
MetaDataWidget* m_metadataWidget;
};
// TODO #1: move to SidebarPage?

View file

@ -1,73 +0,0 @@
/***************************************************************************
* Copyright (C) 2006 by Oscar Blumberg *
* o.blumberg@robertlan.eu.org *
* *
* 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 <config-kmetadata.h>
#include "metadataloader.h"
#ifdef HAVE_KMETADATA
#include <kmetadata/kmetadata.h>
#endif
#include <kurl.h>
#include <QString>
MetadataLoader::MetadataLoader()
{
#ifdef HAVE_KMETADATA
if (Nepomuk::KMetaData::ResourceManager::instance()->init()) {
m_up = false;
Nepomuk::KMetaData::ResourceManager::instance()->setAutoSync(false);
}
else {
m_up = true;
}
#else
m_up = false;
#endif
}
MetadataLoader::~MetadataLoader()
{
}
bool MetadataLoader::storageUp() {
return m_up;
}
QString MetadataLoader::annotation(const KUrl& file)
{
#ifdef HAVE_KMETADATA
if(m_up)
return Nepomuk::KMetaData::File(file.url()).getComment();
else
#endif
return QString();
}
void MetadataLoader::setAnnotation(const KUrl& file, const QString& annotation)
{
#ifdef HAVE_KMETADATA
if (m_up) {
Nepomuk::KMetaData::File(file.url()).setComment(annotation);
}
#endif
}

165
src/metadatawidget.cpp Normal file
View file

@ -0,0 +1,165 @@
/***************************************************************************
* Copyright (C) 2007 by Sebastian Trueg <trueg@kde.org> *
* *
* 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 <config-kmetadata.h>
#include "metadatawidget.h"
#include <klocale.h>
#include <QLabel>
#include <QGridLayout>
#include <QTextEdit>
#ifdef HAVE_KMETADATA
#include <kmetadatatagwidget.h>
#include <kmetadata/resourcemanager.h>
#include <kmetadata/file.h>
#include <kratingwidget.h>
#include <kmetadatatagwidget.h>
#endif
bool MetaDataWidget::metaDataAvailable()
{
#ifdef HAVE_KMETADATA
return !Nepomuk::KMetaData::ResourceManager::instance()->init();
#else
return false;
#endif
}
class MetaDataWidget::Private
{
public:
void loadComment( const QString& comment ) {
editComment->blockSignals( true );
if ( comment.isEmpty() ) {
editComment->setFontItalic( true );
editComment->setText( i18n( "Click to add comment..." ) );
}
else {
editComment->setFontItalic( false );
editComment->setText( comment );
}
editComment->blockSignals( false );
}
KUrl fileUrl;
#ifdef HAVE_KMETADATA
Nepomuk::KMetaData::File file;
QTextEdit* editComment;
KRatingWidget* ratingWidget;
Nepomuk::KMetaData::TagWidget* tagWidget;
#endif
};
MetaDataWidget::MetaDataWidget( QWidget* parent )
: QWidget( parent )
{
d = new Private;
#ifdef HAVE_KMETADATA
d->editComment = new QTextEdit( this );
d->tagWidget = new Nepomuk::KMetaData::TagWidget( this );
d->ratingWidget = new KRatingWidget( this );
connect( d->ratingWidget, SIGNAL(ratingChanged(int)), this, SLOT(slotRatingChanged(int)) );
connect( d->editComment, SIGNAL( textChanged() ), this, SLOT( slotCommentChanged() ) );
QVBoxLayout* lay = new QVBoxLayout( this );
lay->setMargin( 0 );
QHBoxLayout* hbox = new QHBoxLayout;
hbox->addWidget( new QLabel( i18n( "Rating:" ), this ) );
hbox->addStretch( 1 );
hbox->addWidget( d->ratingWidget );
lay->addLayout( hbox );
lay->addWidget( d->editComment );
hbox = new QHBoxLayout;
hbox->addWidget( new QLabel( i18n( "Tags:" ), this ) );
hbox->addWidget( d->tagWidget, 1 );
lay->addLayout( hbox );
d->editComment->installEventFilter( this );
d->editComment->viewport()->installEventFilter( this );
#endif
}
MetaDataWidget::~MetaDataWidget()
{
delete d;
}
void MetaDataWidget::setFile( const KUrl& url )
{
#ifdef HAVE_KMETADATA
d->fileUrl = url;
d->file = Nepomuk::KMetaData::File( url.url() );
d->file.setLocation( url.url() );
d->ratingWidget->setRating( d->file.getRating() );
d->tagWidget->setTaggedResource( d->file );
d->loadComment( d->file.getComment() );
#endif
}
void MetaDataWidget::setFiles( const KUrl::List urls )
{
// FIXME: support multiple files
setFile( urls.first() );
}
void MetaDataWidget::slotCommentChanged()
{
d->file.setComment( d->editComment->toPlainText() );
}
void MetaDataWidget::slotRatingChanged( int r )
{
d->file.setRating( r );
}
bool MetaDataWidget::eventFilter( QObject* obj, QEvent* event )
{
if ( obj == d->editComment->viewport()
|| obj == d->editComment ) {
if ( event->type() == QEvent::FocusOut ) {
// make sure the info text is displayed again
d->loadComment( d->editComment->toPlainText() );
}
else if ( event->type() == QEvent::FocusIn ) {
qDebug() << "JKGHLKGLKHÖLKJHLÖ" << endl;
d->editComment->setFontItalic( false );
if ( d->file.getComment().isEmpty() )
d->editComment->setText( QString() );
}
}
return QWidget::eventFilter( obj, event );
}
#include "metadatawidget.moc"

View file

@ -1,6 +1,5 @@
/***************************************************************************
* Copyright (C) 2006 by Oscar Blumberg *
* o.blumberg@robertlan.eu.org *
* Copyright (C) 2007 by Sebastian Trueg <trueg@kde.org> *
* *
* 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 *
@ -15,35 +14,53 @@
* 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 *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#ifndef METADATALOADER_H
#define METADATALOADER_H
#ifndef METADATA_WIDGET_H
#define METADATA_WIDGET_H
class KUrl;
class QString;
#include <QWidget>
/**
* @brief Load metadata for specific files.
* This class uses the KMetaData API to load metadata from the NEPOMUK storage.
*
* @author Oscar Blumberg <o.blumberg@robertlan.eu.org>
*/
class MetadataLoader
#include <kurl.h>
class MetaDataWidget : public QWidget
{
friend class DolphinApplication;
public:
~MetadataLoader();
bool storageUp();
Q_OBJECT
QString annotation(const KUrl& file);
void setAnnotation(const KUrl& file, const QString& annotation);
public:
MetaDataWidget( QWidget* parent = 0 );
~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();
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();
void slotRatingChanged( int r );
protected:
bool eventFilter( QObject* obj, QEvent* event );
private:
MetadataLoader();
bool m_up;
class Private;
Private* d;
};
#endif