diff options
| author | Peter Penz <[email protected]> | 2012-04-17 18:13:31 +0200 |
|---|---|---|
| committer | Peter Penz <[email protected]> | 2012-04-17 18:15:12 +0200 |
| commit | b2e54c3a316b502ab4f7a95250f8316dc591c057 (patch) | |
| tree | 227eda97fcf699633f49fa7ea6ccdf38a19626e7 /src/kitemviews | |
| parent | eb1b53103d67784c68bb33e5fe3fefcad4cdbdea (diff) | |
Implement inline-renaming for the new view-engine
BUG: 286893
FIXED-IN: 4.9.0
Diffstat (limited to 'src/kitemviews')
| -rw-r--r-- | src/kitemviews/kfileitemlistview.cpp | 1 | ||||
| -rw-r--r-- | src/kitemviews/kfileitemlistwidget.cpp | 109 | ||||
| -rw-r--r-- | src/kitemviews/kfileitemlistwidget.h | 10 | ||||
| -rw-r--r-- | src/kitemviews/kitemlistview.cpp | 32 | ||||
| -rw-r--r-- | src/kitemviews/kitemlistview.h | 16 | ||||
| -rw-r--r-- | src/kitemviews/kitemlistwidget.cpp | 27 | ||||
| -rw-r--r-- | src/kitemviews/kitemlistwidget.h | 17 | ||||
| -rw-r--r-- | src/kitemviews/private/kitemlistroleeditor.cpp | 113 | ||||
| -rw-r--r-- | src/kitemviews/private/kitemlistroleeditor.h | 67 |
9 files changed, 386 insertions, 6 deletions
diff --git a/src/kitemviews/kfileitemlistview.cpp b/src/kitemviews/kfileitemlistview.cpp index 6464ec38a..c5c444875 100644 --- a/src/kitemviews/kfileitemlistview.cpp +++ b/src/kitemviews/kfileitemlistview.cpp @@ -29,6 +29,7 @@ #include <KDebug> #include <KIcon> +#include <KTextEdit> #include <QPainter> #include <QTextLine> diff --git a/src/kitemviews/kfileitemlistwidget.cpp b/src/kitemviews/kfileitemlistwidget.cpp index 5c5690c40..39ed02f07 100644 --- a/src/kitemviews/kfileitemlistwidget.cpp +++ b/src/kitemviews/kfileitemlistwidget.cpp @@ -31,10 +31,13 @@ #include <KDebug> #include "private/kfileitemclipboard.h" +#include "private/kitemlistroleeditor.h" #include "private/kpixmapmodifier.h" #include <QFontMetricsF> +#include <QGraphicsScene> #include <QGraphicsSceneResizeEvent> +#include <QGraphicsView> #include <QPainter> #include <QStyleOption> #include <QTextLayout> @@ -64,7 +67,8 @@ KFileItemListWidget::KFileItemListWidget(QGraphicsItem* parent) : m_customTextColor(), m_additionalInfoTextColor(), m_overlay(), - m_rating() + m_rating(), + m_roleEditor(0) { } @@ -72,6 +76,8 @@ KFileItemListWidget::~KFileItemListWidget() { qDeleteAll(m_textInfo); m_textInfo.clear(); + + delete m_roleEditor; } void KFileItemListWidget::setLayout(Layout layout) @@ -482,10 +488,76 @@ void KFileItemListWidget::siblingsInformationChanged(const QBitArray& current, c m_dirtyLayout = true; } +void KFileItemListWidget::editedRoleChanged(const QByteArray& current, const QByteArray& previous) +{ + Q_UNUSED(previous); + + QGraphicsView* parent = scene()->views()[0]; + if (current.isEmpty() || !parent || current != "name") { + if (m_roleEditor) { + emit roleEditingCanceled(index(), current, data().value(current)); + m_roleEditor->deleteLater(); + m_roleEditor = 0; + } + return; + } + + Q_ASSERT(!m_roleEditor); + + const TextInfo* textInfo = m_textInfo.value("name"); + + m_roleEditor = new KItemListRoleEditor(parent); + m_roleEditor->setIndex(index()); + m_roleEditor->setRole(current); + + const QString text = data().value(current).toString(); + m_roleEditor->setPlainText(text); + + QTextOption textOption = textInfo->staticText.textOption(); + m_roleEditor->document()->setDefaultTextOption(textOption); + + // Select the text without MIME-type extension + int selectionLength = text.length(); + + const QString extension = KMimeType::extractKnownExtension(text); + if (!extension.isEmpty()) { + selectionLength -= extension.length() + 1; + } + + if (selectionLength > 0) { + QTextCursor cursor = m_roleEditor->textCursor(); + cursor.movePosition(QTextCursor::StartOfBlock); + cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, selectionLength); + m_roleEditor->setTextCursor(cursor); + } + + connect(m_roleEditor, SIGNAL(roleEditingCanceled(int,QByteArray,QVariant)), + this, SLOT(slotRoleEditingCanceled(int,QByteArray,QVariant))); + connect(m_roleEditor, SIGNAL(roleEditingFinished(int,QByteArray,QVariant)), + this, SLOT(slotRoleEditingFinished(int,QByteArray,QVariant))); + + // Adjust the geometry of the editor + QRectF rect = roleEditingRect(current); + const int frameWidth = m_roleEditor->frameWidth(); + rect.adjust(-frameWidth, -frameWidth, frameWidth, frameWidth); + rect.translate(pos()); + if (rect.right() > parent->width()) { + rect.setWidth(parent->width() - rect.left()); + } + m_roleEditor->setGeometry(rect.toRect()); + m_roleEditor->show(); + m_roleEditor->setFocus(); +} void KFileItemListWidget::resizeEvent(QGraphicsSceneResizeEvent* event) { + if (m_roleEditor) { + setEditedRole(QByteArray()); + Q_ASSERT(!m_roleEditor); + } + KItemListWidget::resizeEvent(event); + m_dirtyLayout = true; } @@ -523,6 +595,26 @@ void KFileItemListWidget::slotCutItemsChanged() } } +void KFileItemListWidget::slotRoleEditingCanceled(int index, + const QByteArray& role, + const QVariant& value) +{ + m_roleEditor->deleteLater(); + m_roleEditor = 0; + emit roleEditingCanceled(index, role, value); + setEditedRole(QByteArray()); +} + +void KFileItemListWidget::slotRoleEditingFinished(int index, + const QByteArray& role, + const QVariant& value) +{ + m_roleEditor->deleteLater(); + m_roleEditor = 0; + emit roleEditingFinished(index, role, value); + setEditedRole(QByteArray()); +} + void KFileItemListWidget::triggerCacheRefreshing() { if ((!m_dirtyContent && !m_dirtyLayout) || index() < 0) { @@ -1043,6 +1135,21 @@ void KFileItemListWidget::drawSiblingsInformation(QPainter* painter) } } +QRectF KFileItemListWidget::roleEditingRect(const QByteArray& role) const +{ + const TextInfo* textInfo = m_textInfo.value(role); + if (!textInfo) { + return QRectF(); + } + + QRectF rect(textInfo->pos, textInfo->staticText.size()); + if (m_layout == DetailsLayout) { + rect.setWidth(columnWidth(role) - rect.x()); + } + + return rect; +} + QPixmap KFileItemListWidget::pixmapForIcon(const QString& name, int size) { const KIcon icon(name); diff --git a/src/kitemviews/kfileitemlistwidget.h b/src/kitemviews/kfileitemlistwidget.h index 551b47fc3..33d348bab 100644 --- a/src/kitemviews/kfileitemlistwidget.h +++ b/src/kitemviews/kfileitemlistwidget.h @@ -28,8 +28,9 @@ #include <QPointF> #include <QStaticText> -class KItemListView; +class KItemListRoleEditor; class KItemListStyleOption; +class KItemListView; class LIBDOLPHINPRIVATE_EXPORT KFileItemListWidget : public KItemListWidget { @@ -102,12 +103,15 @@ protected: virtual void hoveredChanged(bool hovered); virtual void selectedChanged(bool selected); virtual void siblingsInformationChanged(const QBitArray& current, const QBitArray& previous); + virtual void editedRoleChanged(const QByteArray& current, const QByteArray& previous); virtual void resizeEvent(QGraphicsSceneResizeEvent* event); virtual void showEvent(QShowEvent* event); virtual void hideEvent(QHideEvent* event); private slots: void slotCutItemsChanged(); + void slotRoleEditingCanceled(int index, const QByteArray& role, const QVariant& value); + void slotRoleEditingFinished(int index, const QByteArray& role, const QVariant& value); private: /** @@ -137,6 +141,8 @@ private: void drawPixmap(QPainter* painter, const QPixmap& pixmap); void drawSiblingsInformation(QPainter* painter); + QRectF roleEditingRect(const QByteArray &role) const; + static QPixmap pixmapForIcon(const QString& name, int size); static void applyCutEffect(QPixmap& pixmap); static void applyHiddenEffect(QPixmap& pixmap); @@ -196,6 +202,8 @@ private: QPixmap m_overlay; QPixmap m_rating; + + KItemListRoleEditor* m_roleEditor; }; #endif diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp index c62523410..d53c24589 100644 --- a/src/kitemviews/kitemlistview.cpp +++ b/src/kitemviews/kitemlistview.cpp @@ -57,6 +57,7 @@ KItemListView::KItemListView(QGraphicsWidget* parent) : m_enabledSelectionToggles(false), m_grouped(false), m_supportsItemExpanding(false), + m_editingRole(false), m_activeTransactions(0), m_endTransactionAnimationHint(Animation), m_itemSize(), @@ -667,6 +668,23 @@ QPixmap KItemListView::createDragPixmap(const QSet<int>& indexes) const return QPixmap(); } +void KItemListView::editRole(int index, const QByteArray& role) +{ + KItemListWidget* widget = m_visibleItems.value(index); + if (!widget) { + return; + } + + Q_ASSERT(!m_editingRole); + m_editingRole = true; + widget->setEditedRole(role); + + connect(widget, SIGNAL(roleEditingCanceled(int,QByteArray,QVariant)), + this, SLOT(slotRoleEditingCanceled(int,QByteArray,QVariant))); + connect(widget, SIGNAL(roleEditingFinished(int,QByteArray,QVariant)), + this, SLOT(slotRoleEditingFinished(int,QByteArray,QVariant))); +} + void KItemListView::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { QGraphicsWidget::paint(painter, option, widget); @@ -760,7 +778,7 @@ void KItemListView::onTransactionEnd() bool KItemListView::event(QEvent* event) { // Forward all events to the controller and handle them there - if (m_controller && m_controller->processEvent(event, transform())) { + if (!m_editingRole && m_controller && m_controller->processEvent(event, transform())) { event->accept(); return true; } @@ -1331,6 +1349,18 @@ void KItemListView::slotGeometryOfGroupHeaderParentChanged() updateGroupHeaderLayout(widget); } +void KItemListView::slotRoleEditingCanceled(int index, const QByteArray& role, const QVariant& value) +{ + emit roleEditingCanceled(index, role, value); + m_editingRole = false; +} + +void KItemListView::slotRoleEditingFinished(int index, const QByteArray& role, const QVariant& value) +{ + emit roleEditingFinished(index, role, value); + m_editingRole = false; +} + void KItemListView::setController(KItemListController* controller) { if (m_controller != controller) { diff --git a/src/kitemviews/kitemlistview.h b/src/kitemviews/kitemlistview.h index a3c11a6bf..13f62f89b 100644 --- a/src/kitemviews/kitemlistview.h +++ b/src/kitemviews/kitemlistview.h @@ -266,6 +266,11 @@ public: virtual QPixmap createDragPixmap(const QSet<int>& indexes) const; /** + * Lets the user edit the role \a role for item with the index \a index. + */ + void editRole(int index, const QByteArray& role); + + /** * @reimp */ virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0); @@ -304,7 +309,14 @@ signals: */ void visibleRolesChanged(const QList<QByteArray>& current, const QList<QByteArray>& previous); + void roleEditingCanceled(int index, const QByteArray& role, const QVariant& value); + void roleEditingFinished(int index, const QByteArray& role, const QVariant& value); + protected: + /** + * Is called when creating a new KItemListWidget instance and allows derived + * classes to do a custom initialization. + */ virtual void initializeItemListWidget(KItemListWidget* item); /** @@ -394,6 +406,9 @@ private slots: */ void slotGeometryOfGroupHeaderParentChanged(); + void slotRoleEditingCanceled(int index, const QByteArray& role, const QVariant& value); + void slotRoleEditingFinished(int index, const QByteArray& role, const QVariant& value); + private: enum LayoutAnimationHint { @@ -633,6 +648,7 @@ private: bool m_enabledSelectionToggles; bool m_grouped; bool m_supportsItemExpanding; + bool m_editingRole; int m_activeTransactions; // Counter for beginTransaction()/endTransaction() LayoutAnimationHint m_endTransactionAnimationHint; diff --git a/src/kitemviews/kitemlistwidget.cpp b/src/kitemviews/kitemlistwidget.cpp index 74b96ca1f..542b781f1 100644 --- a/src/kitemviews/kitemlistwidget.cpp +++ b/src/kitemviews/kitemlistwidget.cpp @@ -51,7 +51,8 @@ KItemListWidget::KItemListWidget(QGraphicsItem* parent) : m_hoverOpacity(0), m_hoverCache(0), m_hoverAnimation(0), - m_selectionToggle(0) + m_selectionToggle(0), + m_editedRole() { } @@ -112,7 +113,7 @@ void KItemListWidget::paint(QPainter* painter, const QStyleOptionGraphicsItem* o painter->fillRect(backgroundRect, backgroundColor); } - if (m_selected) { + if (m_selected && m_editedRole.isEmpty()) { const QStyle::State activeState(isActiveWindow() ? QStyle::State_Active : 0); drawItemStyleOption(painter, widget, activeState | QStyle::State_Enabled | @@ -120,7 +121,7 @@ void KItemListWidget::paint(QPainter* painter, const QStyleOptionGraphicsItem* o QStyle::State_Item); } - if (isCurrent()) { + if (m_current && m_editedRole.isEmpty()) { QStyleOptionFocusRect focusRectOption; focusRectOption.initFrom(widget); focusRectOption.rect = textFocusRect().toRect(); @@ -309,6 +310,20 @@ QBitArray KItemListWidget::siblingsInformation() const return m_siblingsInfo; } +void KItemListWidget::setEditedRole(const QByteArray& role) +{ + if (m_editedRole != role) { + const QByteArray previous = m_editedRole; + m_editedRole = role; + editedRoleChanged(role, previous); + } +} + +QByteArray KItemListWidget::editedRole() const +{ + return m_editedRole; +} + bool KItemListWidget::contains(const QPointF& point) const { if (!QGraphicsWidget::contains(point)) { @@ -392,6 +407,12 @@ void KItemListWidget::siblingsInformationChanged(const QBitArray& current, const Q_UNUSED(previous); } +void KItemListWidget::editedRoleChanged(const QByteArray& current, const QByteArray& previous) +{ + Q_UNUSED(current); + Q_UNUSED(previous); +} + void KItemListWidget::resizeEvent(QGraphicsSceneResizeEvent* event) { QGraphicsWidget::resizeEvent(event); diff --git a/src/kitemviews/kitemlistwidget.h b/src/kitemviews/kitemlistwidget.h index 4c8ff1a95..8a28913b6 100644 --- a/src/kitemviews/kitemlistwidget.h +++ b/src/kitemviews/kitemlistwidget.h @@ -103,6 +103,16 @@ public: QBitArray siblingsInformation() const; /** + * Allows the user to edit the role \a role. The signals + * roleEditingCanceled() or roleEditingFinished() will be + * emitted after editing. An ongoing editing gets canceled if + * the role is empty. Derived classes must implement + * editedRoleChanged(). + */ + void setEditedRole(const QByteArray& role); + QByteArray editedRole() const; + + /** * @return True if \a point is inside KItemListWidget::hoverRect(), * KItemListWidget::textRect(), KItemListWidget::selectionToggleRect() * or KItemListWidget::expansionToggleRect(). @@ -143,6 +153,10 @@ public: */ virtual QRectF expansionToggleRect() const; +signals: + void roleEditingCanceled(int index, const QByteArray& role, const QVariant& value); + void roleEditingFinished(int index, const QByteArray& role, const QVariant& value); + protected: virtual void dataChanged(const QHash<QByteArray, QVariant>& current, const QSet<QByteArray>& roles = QSet<QByteArray>()); virtual void visibleRolesChanged(const QList<QByteArray>& current, const QList<QByteArray>& previous); @@ -153,6 +167,7 @@ protected: virtual void hoveredChanged(bool hovered); virtual void alternateBackgroundChanged(bool enabled); virtual void siblingsInformationChanged(const QBitArray& current, const QBitArray& previous); + virtual void editedRoleChanged(const QByteArray& current, const QByteArray& previous); virtual void resizeEvent(QGraphicsSceneResizeEvent* event); /** @@ -190,6 +205,8 @@ private: QPropertyAnimation* m_hoverAnimation; KItemListSelectionToggle* m_selectionToggle; + + QByteArray m_editedRole; }; #endif diff --git a/src/kitemviews/private/kitemlistroleeditor.cpp b/src/kitemviews/private/kitemlistroleeditor.cpp new file mode 100644 index 000000000..55af6a9c7 --- /dev/null +++ b/src/kitemviews/private/kitemlistroleeditor.cpp @@ -0,0 +1,113 @@ +/*************************************************************************** + * Copyright (C) 2012 by Peter Penz <[email protected]> * + * * + * 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 "kitemlistroleeditor.h" + +#include <KDebug> +#include <QKeyEvent> + +KItemListRoleEditor::KItemListRoleEditor(QWidget *parent) : + KTextEdit(parent), + m_index(0), + m_role() +{ + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + document()->setDocumentMargin(0); + + if (parent) { + parent->installEventFilter(this); + } +} + +KItemListRoleEditor::~KItemListRoleEditor() +{ +} + +void KItemListRoleEditor::setIndex(int index) +{ + m_index = index; +} + +int KItemListRoleEditor::index() const +{ + return m_index; +} + +void KItemListRoleEditor::setRole(const QByteArray& role) +{ + m_role = role; +} + +QByteArray KItemListRoleEditor::role() const +{ + return m_role; +} + +bool KItemListRoleEditor::eventFilter(QObject* watched, QEvent* event) +{ + if (watched == parentWidget() && event->type() == QEvent::Resize) { + autoAdjustSize(); + } + + return KTextEdit::eventFilter(watched, event); +} + +bool KItemListRoleEditor::event(QEvent* event) +{ + if (event->type() == QEvent::FocusOut) { + emit roleEditingFinished(m_index, m_role, toPlainText()); + } + return KTextEdit::event(event); +} + +void KItemListRoleEditor::keyPressEvent(QKeyEvent* event) +{ + switch (event->key()) { + case Qt::Key_Escape: + emit roleEditingCanceled(m_index, m_role, toPlainText()); + event->accept(); + return; + case Qt::Key_Enter: + case Qt::Key_Return: + emit roleEditingFinished(m_index, m_role, toPlainText()); + event->accept(); + return; + default: + break; + } + + KTextEdit::keyPressEvent(event); + autoAdjustSize(); +} + +void KItemListRoleEditor::autoAdjustSize() +{ + const qreal requiredWidth = document()->size().width(); + const qreal availableWidth = size().width() - 2 * frameWidth(); + if (requiredWidth > availableWidth) { + qreal newWidth = requiredWidth + 2 * frameWidth(); + if (parentWidget() && pos().x() + newWidth > parentWidget()->width()) { + newWidth = parentWidget()->width() - pos().x(); + } + resize(newWidth, size().height()); + } +} + +#include "kitemlistroleeditor.moc" diff --git a/src/kitemviews/private/kitemlistroleeditor.h b/src/kitemviews/private/kitemlistroleeditor.h new file mode 100644 index 000000000..14aa694ce --- /dev/null +++ b/src/kitemviews/private/kitemlistroleeditor.h @@ -0,0 +1,67 @@ +/*************************************************************************** + * Copyright (C) 2012 by Peter Penz <[email protected]> * + * * + * 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 KITEMLISTROLEEDITOR_H +#define KITEMLISTROLEEDITOR_H + +#include "libdolphin_export.h" + +#include <KTextEdit> + +/** + * @brief + */ +class LIBDOLPHINPRIVATE_EXPORT KItemListRoleEditor : public KTextEdit +{ + Q_OBJECT + +public: + explicit KItemListRoleEditor(QWidget* parent); + virtual ~KItemListRoleEditor(); + + void setIndex(int index); + int index() const; + + void setRole(const QByteArray& role); + QByteArray role() const; + + virtual bool eventFilter(QObject* watched, QEvent* event); + +signals: + void roleEditingFinished(int index, const QByteArray& role, const QVariant& value); + void roleEditingCanceled(int index, const QByteArray& role, const QVariant& value); + +protected: + virtual bool event(QEvent* event); + virtual void keyPressEvent(QKeyEvent* event); + +private slots: + /** + * Increases the width of the editor in case if there is not + * enough room for the text. + */ + void autoAdjustSize(); + +private: + int m_index; + QByteArray m_role; + +}; + +#endif |
