From 6e3e08e33ce46101542d2dadf2b363d0b823a647 Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Sun, 21 Jun 2009 08:16:03 +0000 Subject: [PATCH] Simplify how Nepomuk comments can be edited by the user: - don't provide any mode for editing, just let the user directly manipulate the comment inside the text widget - automatically save changes, no explicit confirmation required svn path=/trunk/KDE/kdebase/apps/; revision=984592 --- src/CMakeLists.txt | 1 - src/panels/information/commenteditwidget.cpp | 241 ------------------- src/panels/information/commenteditwidget.h | 62 ----- src/panels/information/commentwidget.cpp | 64 +++-- src/panels/information/commentwidget.h | 8 +- src/panels/information/informationpanel.cpp | 4 +- src/panels/information/metadatawidget.cpp | 37 +-- 7 files changed, 58 insertions(+), 359 deletions(-) delete mode 100644 src/panels/information/commenteditwidget.cpp delete mode 100644 src/panels/information/commenteditwidget.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b705909e9d..083b31e21f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -102,7 +102,6 @@ set(dolphin_SRCS main.cpp pixmapviewer.cpp panels/information/commentwidget.cpp - panels/information/commenteditwidget.cpp panels/information/informationpanel.cpp panels/information/metadatawidget.cpp panels/information/metatextlabel.cpp diff --git a/src/panels/information/commenteditwidget.cpp b/src/panels/information/commenteditwidget.cpp deleted file mode 100644 index 9efff6adac..0000000000 --- a/src/panels/information/commenteditwidget.cpp +++ /dev/null @@ -1,241 +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 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 "commenteditwidget.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - - -class CommentEditWidget::Private -{ -public: - Private( CommentEditWidget* parent ) - : eventLoop( 0 ), - q( parent ) { - } - - QEventLoop* eventLoop; - bool success; - KTextEdit* textEdit; - QToolButton* buttonSave; - QToolButton* buttonCancel; - - QString comment; - - QRect geometryForPopupPos( const QPoint& p ) { - QSize size = q->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 ); - } - - void _k_saveClicked(); - void _k_cancelClicked(); - -private: - CommentEditWidget* q; -}; - - -void CommentEditWidget::Private::_k_saveClicked() -{ - comment = textEdit->toPlainText(); - success = true; - q->hide(); -} - - -void CommentEditWidget::Private::_k_cancelClicked() -{ - success = false; - q->hide(); -} - - -CommentEditWidget::CommentEditWidget( QWidget* parent ) - : QFrame( parent ), - d( new Private( this ) ) -{ - setFrameStyle( QFrame::StyledPanel ); - setWindowFlags( Qt::Popup ); - - d->textEdit = new KTextEdit( this ); - d->textEdit->installEventFilter( this ); - QVBoxLayout* layout = new QVBoxLayout( this ); - layout->setMargin( 0 ); - layout->addWidget( d->textEdit ); - - d->buttonSave = new QToolButton( d->textEdit ); - d->buttonCancel = new QToolButton( d->textEdit ); - d->buttonSave->setToolButtonStyle( Qt::ToolButtonTextBesideIcon ); - d->buttonCancel->setToolButtonStyle( Qt::ToolButtonTextBesideIcon ); - d->buttonSave->setAutoRaise( true ); - d->buttonCancel->setAutoRaise( true ); - d->buttonSave->setIcon( KIcon( "document-save" ) ); - d->buttonCancel->setIcon( KIcon( "edit-delete" ) ); - d->buttonSave->setText( i18nc( "@action:button", "Save" ) ); - d->buttonCancel->setText( i18nc( "@action:button", "Cancel" ) ); - - QFont fnt( font() ); - fnt.setPointSize( fnt.pointSize()-2 ); - d->buttonSave->setFont( fnt ); - d->buttonCancel->setFont( fnt ); - - connect( d->buttonSave, SIGNAL(clicked()), - this, SLOT( _k_saveClicked() ) ); - connect( d->buttonCancel, SIGNAL(clicked()), - this, SLOT( _k_cancelClicked() ) ); -} - - -CommentEditWidget::~CommentEditWidget() -{ - delete d; -} - - -void CommentEditWidget::setComment( const QString& s ) -{ - d->comment = s; -} - - -QString CommentEditWidget::comment() -{ - return d->comment; -} - - -bool CommentEditWidget::exec( const QPoint& pos ) -{ - d->success = false; - d->textEdit->setPlainText( d->comment ); - d->textEdit->setFocus(); - d->textEdit->moveCursor( QTextCursor::End ); - QEventLoop eventLoop; - d->eventLoop = &eventLoop; - setGeometry( d->geometryForPopupPos( pos ) ); - show(); - - QPointer guard = this; - (void) eventLoop.exec(); - if ( !guard.isNull() ) - d->eventLoop = 0; - return d->success; -} - - -void CommentEditWidget::mousePressEvent( QMouseEvent* e ) -{ - // clicking outside of the widget means cancel - if ( !rect().contains( e->pos() ) ) { - d->success = false; - hide(); - } - else { - QWidget::mousePressEvent( e ); - } -} - - -void CommentEditWidget::hideEvent( QHideEvent* e ) -{ - Q_UNUSED( e ); - if ( d->eventLoop ) { - d->eventLoop->exit(); - } -} - - -void CommentEditWidget::updateButtons() -{ - QSize sbs = d->buttonSave->sizeHint(); - QSize cbs = d->buttonCancel->sizeHint(); - - // FIXME: button order - d->buttonCancel->setGeometry( QRect( QPoint( d->textEdit->width() - cbs.width() - frameWidth(), - d->textEdit->height() - cbs.height() - frameWidth() ), - cbs ) ); - d->buttonSave->setGeometry( QRect( QPoint( d->textEdit->width() - cbs.width() - sbs.width() - frameWidth(), - d->textEdit->height() - sbs.height() - frameWidth() ), - sbs ) ); -} - - -void CommentEditWidget::resizeEvent( QResizeEvent* e ) -{ - QWidget::resizeEvent( e ); - updateButtons(); -} - - -bool CommentEditWidget::eventFilter( QObject* watched, QEvent* event ) -{ - if ( watched == d->textEdit && event->type() == QEvent::KeyPress ) { - QKeyEvent* ke = static_cast( event ); - kDebug() << "keypress:" << ke->key() << ke->modifiers(); - if ( ( ke->key() == Qt::Key_Enter || - ke->key() == Qt::Key_Return ) && - ke->modifiers() & Qt::ControlModifier ) { - d->_k_saveClicked(); - return true; - } - } - - return QFrame::eventFilter( watched, event ); -} - -#include "commenteditwidget.moc" diff --git a/src/panels/information/commenteditwidget.h b/src/panels/information/commenteditwidget.h deleted file mode 100644 index 18ab8d7b2d..0000000000 --- a/src/panels/information/commenteditwidget.h +++ /dev/null @@ -1,62 +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 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***************************************************************************/ - -#ifndef _COMMENT_EDIT_WIDGET_H_ -#define _COMMENT_EDIT_WIDGET_H_ - -#include - -class QResizeEvent; -class QMouseEvent; -class QHideEvent; - -class CommentEditWidget : public QFrame -{ - Q_OBJECT - -public: - CommentEditWidget( QWidget* parent = 0 ); - ~CommentEditWidget(); - - void setComment( const QString& s ); - QString comment(); - - /** - * Show the comment widget at position pos. - * \return true if the user chose to save the comment, - * false otherwise. - */ - bool exec( const QPoint& pos ); - - bool eventFilter( QObject* watched, QEvent* event ); - -private: - void updateButtons(); - void resizeEvent( QResizeEvent* ); - void mousePressEvent( QMouseEvent* e ); - void hideEvent( QHideEvent* e ); - - class Private; - Private* const d; - - Q_PRIVATE_SLOT( d, void _k_saveClicked() ) - Q_PRIVATE_SLOT( d, void _k_cancelClicked() ) -}; - -#endif diff --git a/src/panels/information/commentwidget.cpp b/src/panels/information/commentwidget.cpp index 93bbad84f9..23f79dfb1d 100644 --- a/src/panels/information/commentwidget.cpp +++ b/src/panels/information/commentwidget.cpp @@ -18,13 +18,11 @@ ***************************************************************************/ #include "commentwidget.h" -#include "commenteditwidget.h" #include #include #include #include -#include #include #include @@ -40,10 +38,8 @@ public: void update(); void _k_slotEnableEditing(); - QLabel* commentLabel; - QScrollArea* scrollArea; - QLabel* commentLink; - CommentEditWidget* edit; + QTextEdit* textEdit; + QLabel* addComment; QString comment; @@ -54,27 +50,18 @@ private: void CommentWidget::Private::update() { - commentLabel->setText( comment ); - if ( comment.isEmpty() ) { - scrollArea->hide(); - commentLink->setText( "

" + i18nc( "@label", "Add Comment..." ) + "" ); - } - else { - scrollArea->show(); - commentLink->setText( "

" + i18nc( "@label", "Change Comment..." ) + "" ); - } + textEdit->setText( comment ); + const bool hasComment = !comment.isEmpty(); + textEdit->setVisible(hasComment); + addComment->setVisible(!hasComment); } void CommentWidget::Private::_k_slotEnableEditing() { - CommentEditWidget w; - w.setComment( comment ); - if ( w.exec( QCursor::pos() ) ) { - comment = w.comment(); - update(); - emit q->commentChanged( comment ); - } + textEdit->show(); + textEdit->setFocus(); + addComment->hide(); } @@ -83,22 +70,20 @@ CommentWidget::CommentWidget( QWidget* parent ) : QWidget( parent ), d( new Private( this ) ) { - d->commentLabel = new QLabel( this ); - d->commentLabel->setWordWrap( true ); + d->textEdit = new QTextEdit( this ); + d->textEdit->installEventFilter( this ); + d->textEdit->setMinimumHeight( 100 ); + d->textEdit->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Ignored); - d->scrollArea = new QScrollArea( this ); - d->scrollArea->setWidget( d->commentLabel ); - d->scrollArea->setWidgetResizable( true ); - d->scrollArea->setFrameShape( QFrame::StyledPanel ); - - d->commentLink = new QLabel( this ); + d->addComment = new QLabel( this ); + d->addComment->setText( "

" + i18nc( "@label", "Add Comment..." ) + "" ); QVBoxLayout* layout = new QVBoxLayout( this ); layout->setMargin( 0 ); - layout->addWidget( d->scrollArea ); - layout->addWidget( d->commentLink ); + layout->addWidget( d->textEdit ); + layout->addWidget( d->addComment ); d->update(); - connect( d->commentLink, SIGNAL( linkActivated( const QString& ) ), this, SLOT( _k_slotEnableEditing() ) ); + connect( d->addComment, SIGNAL( linkActivated( const QString& ) ), this, SLOT( _k_slotEnableEditing() ) ); } @@ -121,8 +106,21 @@ QString CommentWidget::comment() const } +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 ); } diff --git a/src/panels/information/commentwidget.h b/src/panels/information/commentwidget.h index 8c588518ce..93460d703d 100644 --- a/src/panels/information/commentwidget.h +++ b/src/panels/information/commentwidget.h @@ -28,17 +28,19 @@ class CommentWidget : public QWidget public: CommentWidget( QWidget* parent = 0 ); - ~CommentWidget(); + 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: - bool eventFilter( QObject* watched, QEvent* event ); - class Private; Private* const d; diff --git a/src/panels/information/informationpanel.cpp b/src/panels/information/informationpanel.cpp index a49d851697..2150c64659 100644 --- a/src/panels/information/informationpanel.cpp +++ b/src/panels/information/informationpanel.cpp @@ -302,7 +302,7 @@ void InformationPanel::contextMenuEvent(QContextMenuEvent* event) } if (!skip) { - const QString label = key; // TODO + const QString label = tunedLabel(key); // TODO QAction* action = new QAction(label, &popup); action->setCheckable(true); action->setChecked(settings.readEntry(key, true)); @@ -587,7 +587,7 @@ void InformationPanel::showMetaInfo() // 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(label), it.value().toString()); + m_metaTextLabel->add(tunedLabel(label) + ':', it.value().toString()); } ++it; } diff --git a/src/panels/information/metadatawidget.cpp b/src/panels/information/metadatawidget.cpp index b2689b9b30..6a2f6073a4 100644 --- a/src/panels/information/metadatawidget.cpp +++ b/src/panels/information/metadatawidget.cpp @@ -24,7 +24,6 @@ #include #include -#include #include #include @@ -61,9 +60,7 @@ class MetaDataWidget::Private { public: #ifdef HAVE_NEPOMUK - void loadComment(const QString& comment); - - CommentWidget* editComment; + CommentWidget* commentWidget; KRatingWidget* ratingWidget; Nepomuk::ResourceTaggingWidget* tagWidget; @@ -103,10 +100,6 @@ public: }; #ifdef HAVE_NEPOMUK -void MetaDataWidget::Private::loadComment(const QString& comment) -{ - editComment->setComment( comment ); -} MetaDataWidget::Private::LoadFilesThread::LoadFilesThread( MetaDataWidget::Private::SharedData* sharedData, @@ -181,14 +174,14 @@ MetaDataWidget::MetaDataWidget(QWidget* parent) : { #ifdef HAVE_NEPOMUK d = new Private; - d->editComment = new CommentWidget(this); - d->editComment->setFocusPolicy(Qt::ClickFocus); + 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->editComment, SIGNAL(commentChanged(const QString&)), this, SLOT(slotCommentChanged(const QString&))); - connect( d->tagWidget, SIGNAL( tagClicked( const Nepomuk::Tag& ) ), this, SLOT( slotTagClicked( const Nepomuk::Tag& ) ) ); + 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); @@ -197,7 +190,7 @@ MetaDataWidget::MetaDataWidget(QWidget* parent) : QVBoxLayout* lay = new QVBoxLayout(this); lay->setMargin(0); lay->addWidget(d->ratingWidget); - lay->addWidget(d->editComment); + lay->addWidget(d->commentWidget); lay->addWidget( d->tagWidget ); #else d = 0; @@ -236,7 +229,7 @@ bool MetaDataWidget::isRatingVisible() const void MetaDataWidget::setCommentVisible(bool visible) { #ifdef HAVE_NEPOMUK - d->editComment->setVisible(visible); + d->commentWidget->setVisible(visible); #else Q_UNUSED(visible); #endif @@ -246,7 +239,7 @@ void MetaDataWidget::setCommentVisible(bool visible) bool MetaDataWidget::isCommentVisible() const { #ifdef HAVE_NEPOMUK - return d->editComment->isVisible(); + return d->commentWidget->isVisible(); #else return false; #endif @@ -275,7 +268,6 @@ bool MetaDataWidget::areTagsVisible() const void MetaDataWidget::setFile(const KUrl& url) { - kDebug() << url; KUrl::List urls; urls.append( url ); setFiles( urls ); @@ -284,6 +276,13 @@ void MetaDataWidget::setFile(const KUrl& url) void MetaDataWidget::setFiles(const KUrl::List& urls) { #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 ); + } + d->loadFilesThread->loadFiles( urls ); #else Q_UNUSED( urls ); @@ -294,12 +293,16 @@ void MetaDataWidget::setFiles(const KUrl::List& urls) void MetaDataWidget::slotCommentChanged( const QString& s ) { #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 ); 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 @@ -346,7 +349,7 @@ void MetaDataWidget::slotLoadingFinished() #ifdef HAVE_NEPOMUK QMutexLocker locker( &d->mutex ); d->ratingWidget->setRating( d->sharedData.rating ); - d->loadComment( d->sharedData.comment ); + d->commentWidget->setComment( d->sharedData.comment ); d->tagWidget->setResources( d->sharedData.fileRes ); #endif }