From: Peter Penz Date: Sun, 13 Nov 2011 15:20:42 +0000 (+0100) Subject: Bring back the selection-markers X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/commitdiff_plain/2438b61d8e76f8ea016217150be711a1467c32d0?ds=inline Bring back the selection-markers Still some finetuning is necessary, but lets first bring back the missing features from Dolphin 1.x to 2.0 before starting with this. --- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 934619000..6956a196c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -30,6 +30,7 @@ set(dolphinprivate_LIB_SRCS kitemviews/kitemlistkeyboardsearchmanager.cpp kitemviews/kitemlistrubberband.cpp kitemviews/kitemlistselectionmanager.cpp + kitemviews/kitemlistselectiontoggle.cpp kitemviews/kitemlistsizehintresolver.cpp kitemviews/kitemlistsmoothscroller.cpp kitemviews/kitemliststyleoption.cpp diff --git a/src/kitemviews/kfileitemlistwidget.cpp b/src/kitemviews/kfileitemlistwidget.cpp index d6b892658..8fd00fa02 100644 --- a/src/kitemviews/kfileitemlistwidget.cpp +++ b/src/kitemviews/kfileitemlistwidget.cpp @@ -172,6 +172,22 @@ QRectF KFileItemListWidget::expansionToggleRect() const return m_isDir ? m_expansionArea : QRectF(); } +QRectF KFileItemListWidget::selectionToggleRect() const +{ + const_cast(this)->triggerCacheRefreshing(); + + const int iconHeight = m_pixmap.height(); + + int toggleSize = KIconLoader::SizeSmall; + if (iconHeight >= KIconLoader::SizeEnormous) { + toggleSize = KIconLoader::SizeMedium; + } else if (iconHeight >= KIconLoader::SizeLarge) { + toggleSize = KIconLoader::SizeSmallMedium; + } + + return QRectF(m_pixmapPos, QSizeF(toggleSize, toggleSize)); +} + QString KFileItemListWidget::roleText(const QByteArray& role, const QHash& values) { QString text; diff --git a/src/kitemviews/kfileitemlistwidget.h b/src/kitemviews/kfileitemlistwidget.h index bebc3e168..3c9a1d73a 100644 --- a/src/kitemviews/kfileitemlistwidget.h +++ b/src/kitemviews/kfileitemlistwidget.h @@ -51,6 +51,7 @@ public: virtual QRectF iconRect() const; virtual QRectF textRect() const; virtual QRectF expansionToggleRect() const; + virtual QRectF selectionToggleRect() const; /** * @return Shown string for the role \p role of the item with the values \p values. diff --git a/src/kitemviews/kitemlistcontroller.cpp b/src/kitemviews/kitemlistcontroller.cpp index a9885f285..8b135fbb5 100644 --- a/src/kitemviews/kitemlistcontroller.cpp +++ b/src/kitemviews/kitemlistcontroller.cpp @@ -38,6 +38,7 @@ KItemListController::KItemListController(QObject* parent) : QObject(parent), + m_selectionTogglePressed(false), m_selectionBehavior(NoSelection), m_model(0), m_view(0), @@ -274,10 +275,17 @@ bool KItemListController::mousePressEvent(QGraphicsSceneMouseEvent* event, const m_pressedIndex = m_view->itemAt(m_pressedMousePos); if (m_view->isAboveExpansionToggle(m_pressedIndex, m_pressedMousePos)) { + m_selectionTogglePressed = true; m_selectionManager->setCurrentItem(m_pressedIndex); return true; } + m_selectionTogglePressed = m_view->isAboveSelectionToggle(m_pressedIndex, m_pressedMousePos); + if (m_selectionTogglePressed) { + m_selectionManager->setSelected(m_pressedIndex, 1, KItemListSelectionManager::Toggle); + return true; + } + const bool shiftPressed = event->modifiers() & Qt::ShiftModifier; const bool controlPressed = event->modifiers() & Qt::ControlModifier; @@ -375,6 +383,12 @@ bool KItemListController::mouseMoveEvent(QGraphicsSceneMouseEvent* event, const if (event->buttons() & Qt::LeftButton) { const QPointF pos = transform.map(event->pos()); if ((pos - m_pressedMousePos).manhattanLength() >= QApplication::startDragDistance()) { + if (!m_selectionManager->isSelected(m_pressedIndex)) { + // Always assure that the dragged item gets selected. Usually this is already + // done on the mouse-press event, but when using the selection-toggle on a + // selected item the dragged item is not selected yet. + m_selectionManager->setSelected(m_pressedIndex, 1, KItemListSelectionManager::Toggle); + } startDragging(); } } @@ -405,6 +419,18 @@ bool KItemListController::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, con return false; } + const bool isAboveSelectionToggle = m_view->isAboveSelectionToggle(m_pressedIndex, m_pressedMousePos); + if (isAboveSelectionToggle) { + m_selectionTogglePressed = false; + return true; + } + + if (!isAboveSelectionToggle && m_selectionTogglePressed) { + m_selectionManager->setSelected(m_pressedIndex, 1, KItemListSelectionManager::Toggle); + m_selectionTogglePressed = false; + return true; + } + const bool shiftOrControlPressed = event->modifiers() & Qt::ShiftModifier || event->modifiers() & Qt::ControlModifier; @@ -465,8 +491,8 @@ bool KItemListController::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event, const int index = m_view->itemAt(pos); bool emitItemActivated = !KGlobalSettings::singleClick() && - (event->button() & Qt::LeftButton) && - index >= 0 && index < m_model->count(); + (event->button() & Qt::LeftButton) && + index >= 0 && index < m_model->count(); if (emitItemActivated) { emit itemActivated(index); } @@ -749,6 +775,10 @@ void KItemListController::startDragging() } const QSet selectedItems = m_selectionManager->selectedItems(); + if (selectedItems.isEmpty()) { + return; + } + QMimeData* data = m_model->createMimeData(selectedItems); if (!data) { return; @@ -786,8 +816,7 @@ KItemListWidget* KItemListController::widgetForPos(const QPointF& pos) const const QPointF mappedPos = widget->mapFromItem(m_view, pos); const bool hovered = widget->contains(mappedPos) && - !widget->expansionToggleRect().contains(mappedPos) && - !widget->selectionToggleRect().contains(mappedPos); + !widget->expansionToggleRect().contains(mappedPos); if (hovered) { return widget; } diff --git a/src/kitemviews/kitemlistcontroller.h b/src/kitemviews/kitemlistcontroller.h index d6205ea0a..aa2fe2176 100644 --- a/src/kitemviews/kitemlistcontroller.h +++ b/src/kitemviews/kitemlistcontroller.h @@ -179,6 +179,7 @@ private: KItemListWidget* widgetForPos(const QPointF& pos) const; private: + bool m_selectionTogglePressed; SelectionBehavior m_selectionBehavior; KItemModelBase* m_model; KItemListView* m_view; diff --git a/src/kitemviews/kitemlistselectiontoggle.cpp b/src/kitemviews/kitemlistselectiontoggle.cpp new file mode 100644 index 000000000..43725e0de --- /dev/null +++ b/src/kitemviews/kitemlistselectiontoggle.cpp @@ -0,0 +1,91 @@ +/*************************************************************************** + * Copyright (C) 2011 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 "kitemlistselectiontoggle_p.h" + +#include +#include +#include + +KItemListSelectionToggle::KItemListSelectionToggle(QGraphicsItem* parent) : + QGraphicsWidget(parent, 0), + m_checked(false), + m_hovered(false) +{ + setAcceptHoverEvents(true); +} + +KItemListSelectionToggle::~KItemListSelectionToggle() +{ +} + +void KItemListSelectionToggle::setChecked(bool checked) +{ + if (m_checked != checked) { + m_checked = checked; + m_pixmap = QPixmap(); + update(); + } +} + +bool KItemListSelectionToggle::isChecked() const +{ + return m_checked; +} + +void KItemListSelectionToggle::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) +{ + Q_UNUSED(option); + Q_UNUSED(widget); + + if (m_pixmap.isNull()) { + updatePixmap(); + } + + const qreal x = (size().width() - qreal(m_pixmap.width())) / 2; + const qreal y = (size().height() - qreal(m_pixmap.height())) / 2; + painter->drawPixmap(x, y, m_pixmap); +} + +void KItemListSelectionToggle::hoverEnterEvent(QGraphicsSceneHoverEvent* event) +{ + QGraphicsWidget::hoverEnterEvent(event); + m_hovered = true; + m_pixmap = QPixmap(); +} + +void KItemListSelectionToggle::hoverLeaveEvent(QGraphicsSceneHoverEvent* event) +{ + QGraphicsWidget::hoverLeaveEvent(event); + m_hovered = false; + m_pixmap = QPixmap(); +} + +void KItemListSelectionToggle::updatePixmap() +{ + const char* icon = m_checked ? "list-remove" : "list-add"; + const int iconSize = qMin(size().width(), size().height()); + m_pixmap = KIconLoader::global()->loadIcon(QLatin1String(icon), KIconLoader::NoGroup, iconSize); + + if (m_hovered) { + KIconLoader::global()->iconEffect()->apply(m_pixmap, KIconLoader::Desktop, KIconLoader::ActiveState); + } +} + +#include "kitemlistselectiontoggle_p.moc" diff --git a/src/kitemviews/kitemlistselectiontoggle_p.h b/src/kitemviews/kitemlistselectiontoggle_p.h new file mode 100644 index 000000000..a8050d811 --- /dev/null +++ b/src/kitemviews/kitemlistselectiontoggle_p.h @@ -0,0 +1,61 @@ +/*************************************************************************** + * Copyright (C) 2011 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 KITEMLISTSELECTIONTOGGLE_H +#define KITEMLISTSELECTIONTOGGLE_H + +#include + +#include +#include + +class QPropertyAnimation; + +/** + * @brief Allows to toggle between the selected and unselected state of an item. + */ +class LIBDOLPHINPRIVATE_EXPORT KItemListSelectionToggle : public QGraphicsWidget +{ + Q_OBJECT + +public: + KItemListSelectionToggle(QGraphicsItem* parent); + virtual ~KItemListSelectionToggle(); + + void setChecked(bool checked); + bool isChecked() const; + + virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0); + +protected: + virtual void hoverEnterEvent(QGraphicsSceneHoverEvent* event); + virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent* event); + +private: + void updatePixmap(); + +private: + bool m_checked; + bool m_hovered; + QPixmap m_pixmap; +}; + +#endif + + diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp index 7976f397b..4ded4a93e 100644 --- a/src/kitemviews/kitemlistview.cpp +++ b/src/kitemviews/kitemlistview.cpp @@ -52,6 +52,7 @@ namespace { KItemListView::KItemListView(QGraphicsWidget* parent) : QGraphicsWidget(parent), + m_enabledSelectionToggles(false), m_grouped(false), m_activeTransactions(0), m_itemSize(), @@ -269,6 +270,24 @@ bool KItemListView::autoScroll() const return m_autoScrollTimer != 0; } +void KItemListView::setEnabledSelectionToggles(bool enabled) +{ + if (m_enabledSelectionToggles != enabled) { + m_enabledSelectionToggles = enabled; + + QHashIterator it(m_visibleItems); + while (it.hasNext()) { + it.next(); + it.value()->setEnabledSelectionToggle(enabled); + } + } +} + +bool KItemListView::enabledSelectionToggles() const +{ + return m_enabledSelectionToggles; +} + KItemListController* KItemListView::controller() const { return m_controller; @@ -362,8 +381,14 @@ int KItemListView::itemAt(const QPointF& pos) const bool KItemListView::isAboveSelectionToggle(int index, const QPointF& pos) const { - Q_UNUSED(index); - Q_UNUSED(pos); + const KItemListWidget* widget = m_visibleItems.value(index); + if (widget) { + const QRectF selectionToggleRect = widget->selectionToggleRect(); + if (!selectionToggleRect.isEmpty()) { + const QPointF mappedPos = widget->mapFromItem(this, pos); + return selectionToggleRect.contains(mappedPos); + } + } return false; } @@ -1486,6 +1511,7 @@ void KItemListView::updateWidgetProperties(KItemListWidget* widget, int index) widget->setSelected(selectionManager->isSelected(index)); widget->setHovered(false); widget->setAlternatingBackgroundColors(false); + widget->setEnabledSelectionToggle(enabledSelectionToggles()); widget->setIndex(index); widget->setData(m_model->data(index)); } diff --git a/src/kitemviews/kitemlistview.h b/src/kitemviews/kitemlistview.h index ff908000a..481dd90f6 100644 --- a/src/kitemviews/kitemlistview.h +++ b/src/kitemviews/kitemlistview.h @@ -100,6 +100,13 @@ public: void setAutoScroll(bool enabled); bool autoScroll() const; + /** + * If set to true selection-toggles will be shown when hovering + * an item. Per default the selection-toggles are disabled. + */ + void setEnabledSelectionToggles(bool enabled); + bool enabledSelectionToggles() const; + /** * @return Controller of the item-list. The controller gets * initialized by KItemListController::setView() and will @@ -410,6 +417,7 @@ private: static int calculateAutoScrollingIncrement(int pos, int range, int oldInc); private: + bool m_enabledSelectionToggles; bool m_grouped; int m_activeTransactions; // Counter for beginTransaction()/endTransaction() diff --git a/src/kitemviews/kitemlistwidget.cpp b/src/kitemviews/kitemlistwidget.cpp index 21bfe707f..04438262f 100644 --- a/src/kitemviews/kitemlistwidget.cpp +++ b/src/kitemviews/kitemlistwidget.cpp @@ -22,11 +22,13 @@ #include "kitemlistwidget.h" +#include "kitemlistselectiontoggle_p.h" #include "kitemlistview.h" #include "kitemmodelbase.h" #include +#include #include #include #include @@ -39,13 +41,15 @@ KItemListWidget::KItemListWidget(QGraphicsItem* parent) : m_current(false), m_hovered(false), m_alternatingBackgroundColors(false), + m_enabledSelectionToggle(false), m_data(), m_visibleRoles(), m_visibleRolesSizes(), m_styleOption(), m_hoverOpacity(0), m_hoverCache(0), - m_hoverAnimation(0) + m_hoverAnimation(0), + m_selectionToggle(0) { } @@ -57,6 +61,9 @@ KItemListWidget::~KItemListWidget() void KItemListWidget::setIndex(int index) { if (m_index != index) { + delete m_selectionToggle; + m_selectionToggle = 0; + if (m_hoverAnimation) { m_hoverAnimation->stop(); m_hoverOpacity = 0; @@ -195,6 +202,10 @@ void KItemListWidget::setSelected(bool selected) { if (m_selected != selected) { m_selected = selected; + if (m_selectionToggle) { + m_selectionToggle->setChecked(selected); + } + selectedChanged(selected); update(); } @@ -209,6 +220,7 @@ void KItemListWidget::setCurrent(bool current) { if (m_current != current) { m_current = current; + currentChanged(current); update(); } @@ -230,11 +242,15 @@ void KItemListWidget::setHovered(bool hovered) if (!m_hoverAnimation) { m_hoverAnimation = new QPropertyAnimation(this, "hoverOpacity", this); m_hoverAnimation->setDuration(200); + connect(m_hoverAnimation, SIGNAL(finished()), this, SLOT(slotHoverAnimationFinished())); } m_hoverAnimation->stop(); if (hovered) { m_hoverAnimation->setEndValue(1.0); + if (m_enabledSelectionToggle && !(QApplication::mouseButtons() & Qt::LeftButton)) { + initializeSelectionToggle(); + } } else { m_hoverAnimation->setEndValue(0.0); } @@ -265,6 +281,19 @@ bool KItemListWidget::alternatingBackgroundColors() const return m_alternatingBackgroundColors; } +void KItemListWidget::setEnabledSelectionToggle(bool enable) +{ + if (m_enabledSelectionToggle != enable) { + m_enabledSelectionToggle = enable; + update(); + } +} + +bool KItemListWidget::enabledSelectionToggle() const +{ + return m_enabledSelectionToggle; +} + bool KItemListWidget::contains(const QPointF& point) const { if (!QGraphicsWidget::contains(point)) { @@ -350,9 +379,35 @@ qreal KItemListWidget::hoverOpacity() const return m_hoverOpacity; } +void KItemListWidget::slotHoverAnimationFinished() +{ + if (!m_hovered) { + delete m_selectionToggle; + m_selectionToggle = 0; + } +} + +void KItemListWidget::initializeSelectionToggle() +{ + Q_ASSERT(m_enabledSelectionToggle); + + if (!m_selectionToggle) { + m_selectionToggle = new KItemListSelectionToggle(this); + } + + const QRectF toggleRect = selectionToggleRect(); + m_selectionToggle->setPos(toggleRect.topLeft()); + m_selectionToggle->resize(toggleRect.size()); + + m_selectionToggle->setChecked(isSelected()); +} + void KItemListWidget::setHoverOpacity(qreal opacity) { m_hoverOpacity = opacity; + if (m_selectionToggle) { + m_selectionToggle->setOpacity(opacity); + } update(); } diff --git a/src/kitemviews/kitemlistwidget.h b/src/kitemviews/kitemlistwidget.h index 2df19a610..a624950b8 100644 --- a/src/kitemviews/kitemlistwidget.h +++ b/src/kitemviews/kitemlistwidget.h @@ -29,6 +29,7 @@ #include +class KItemListSelectionToggle; class QPropertyAnimation; /** @@ -68,6 +69,8 @@ public: void setStyleOption(const KItemListStyleOption& option); const KItemListStyleOption& styleOption() const; + // TODO: Hides QGraphicsItem::setSelected()/isSelected(). Replace + // this by using the default mechanism. void setSelected(bool selected); bool isSelected() const; @@ -80,6 +83,9 @@ public: void setAlternatingBackgroundColors(bool enable); bool alternatingBackgroundColors() const; + void setEnabledSelectionToggle(bool enabled); + bool enabledSelectionToggle() const; + /** * @return True if \a point is inside KItemListWidget::hoverRect(), * KItemListWidget::textRect(), KItemListWidget::selectionToggleRect() @@ -129,7 +135,11 @@ protected: */ qreal hoverOpacity() const; +private slots: + void slotHoverAnimationFinished(); + private: + void initializeSelectionToggle(); void setHoverOpacity(qreal opacity); void clearHoverCache(); void drawTextBackground(QPainter* painter); @@ -142,6 +152,7 @@ private: bool m_current; bool m_hovered; bool m_alternatingBackgroundColors; + bool m_enabledSelectionToggle; QHash m_data; QList m_visibleRoles; QHash m_visibleRolesSizes; @@ -150,6 +161,8 @@ private: qreal m_hoverOpacity; mutable QPixmap* m_hoverCache; QPropertyAnimation* m_hoverAnimation; + + KItemListSelectionToggle* m_selectionToggle; }; #endif diff --git a/src/views/dolphinitemlistcontainer.cpp b/src/views/dolphinitemlistcontainer.cpp index 6a6a51fb5..cd26ec876 100644 --- a/src/views/dolphinitemlistcontainer.cpp +++ b/src/views/dolphinitemlistcontainer.cpp @@ -19,6 +19,7 @@ #include "dolphinitemlistcontainer.h" +#include "dolphin_generalsettings.h" #include "dolphin_iconsmodesettings.h" #include "dolphin_detailsmodesettings.h" #include "dolphin_compactmodesettings.h" @@ -48,58 +49,10 @@ DolphinItemListContainer::DolphinItemListContainer(KDirLister* dirLister, m_fileItemListView = new KFileItemListView(); m_fileItemListView->setWidgetCreator(new KItemListWidgetCreator()); + m_fileItemListView->setEnabledSelectionToggles(GeneralSettings::showSelectionToggle()); controller()->setView(m_fileItemListView); - KItemListStyleOption option; - - // TODO: - option.font = parent->font(); - option.fontMetrics = QFontMetrics(parent->font()); - updateGridSize(); -/* - connect(this, SIGNAL(clicked(QModelIndex)), - dolphinViewController, SLOT(requestTab(QModelIndex)));*/ -/* - connect(this, SIGNAL(entered(QModelIndex)), - dolphinViewController, SLOT(emitItemEntered(QModelIndex))); - connect(this, SIGNAL(viewportEntered()), - dolphinViewController, SLOT(emitViewportEntered()));*/ - - // apply the icons mode settings to the widget - //const IconsModeSettings* settings = DolphinSettings::instance().iconsModeSettings(); - //Q_ASSERT(settings); - - /*if (settings->useSystemFont()) { - m_font = KGlobalSettings::generalFont(); - } else { - m_font = QFont(settings->fontFamily(), - qRound(settings->fontSize()), - settings->fontWeight(), - settings->italicFont()); - m_font.setPointSizeF(settings->fontSize()); - } - - setWordWrap(settings->numberOfTextlines() > 1); - - if (settings->arrangement() == QListView::TopToBottom) { - setFlow(QListView::LeftToRight); - m_decorationPosition = QStyleOptionViewItem::Top; - m_displayAlignment = Qt::AlignHCenter; - } else { - setFlow(QListView::TopToBottom); - m_decorationPosition = QStyleOptionViewItem::Left; - m_displayAlignment = Qt::AlignLeft | Qt::AlignVCenter; - } - - connect(m_categoryDrawer, SIGNAL(actionRequested(int,QModelIndex)), this, SLOT(categoryDrawerActionRequested(int,QModelIndex))); - setCategoryDrawer(m_categoryDrawer); - - connect(KGlobalSettings::self(), SIGNAL(settingsChanged(int)), - this, SLOT(slotGlobalSettingsChanged(int)));*/ - - //updateGridSize(dolphinView->showPreview(), 0); - /*m_extensionsFactory = new ViewExtensionsFactory(this, dolphinViewController, viewModeController);*/ } DolphinItemListContainer::~DolphinItemListContainer()