kitemviews/kitemlistkeyboardsearchmanager.cpp
kitemviews/kitemlistrubberband.cpp
kitemviews/kitemlistselectionmanager.cpp
+ kitemviews/kitemlistselectiontoggle.cpp
kitemviews/kitemlistsizehintresolver.cpp
kitemviews/kitemlistsmoothscroller.cpp
kitemviews/kitemliststyleoption.cpp
return m_isDir ? m_expansionArea : QRectF();
}
+QRectF KFileItemListWidget::selectionToggleRect() const
+{
+ const_cast<KFileItemListWidget*>(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<QByteArray, QVariant>& values)
{
QString text;
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.
KItemListController::KItemListController(QObject* parent) :
QObject(parent),
+ m_selectionTogglePressed(false),
m_selectionBehavior(NoSelection),
m_model(0),
m_view(0),
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;
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();
}
}
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;
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);
}
}
const QSet<int> selectedItems = m_selectionManager->selectedItems();
+ if (selectedItems.isEmpty()) {
+ return;
+ }
+
QMimeData* data = m_model->createMimeData(selectedItems);
if (!data) {
return;
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;
}
KItemListWidget* widgetForPos(const QPointF& pos) const;
private:
+ bool m_selectionTogglePressed;
SelectionBehavior m_selectionBehavior;
KItemModelBase* m_model;
KItemListView* m_view;
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com> *
+ * *
+ * 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 <KIconEffect>
+#include <KIconLoader>
+#include <QPainter>
+
+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"
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com> *
+ * *
+ * 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 <libdolphin_export.h>
+
+#include <QGraphicsWidget>
+#include <QPixmap>
+
+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
+
+
KItemListView::KItemListView(QGraphicsWidget* parent) :
QGraphicsWidget(parent),
+ m_enabledSelectionToggles(false),
m_grouped(false),
m_activeTransactions(0),
m_itemSize(),
return m_autoScrollTimer != 0;
}
+void KItemListView::setEnabledSelectionToggles(bool enabled)
+{
+ if (m_enabledSelectionToggles != enabled) {
+ m_enabledSelectionToggles = enabled;
+
+ QHashIterator<int, KItemListWidget*> 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;
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;
}
widget->setSelected(selectionManager->isSelected(index));
widget->setHovered(false);
widget->setAlternatingBackgroundColors(false);
+ widget->setEnabledSelectionToggle(enabledSelectionToggles());
widget->setIndex(index);
widget->setData(m_model->data(index));
}
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
static int calculateAutoScrollingIncrement(int pos, int range, int oldInc);
private:
+ bool m_enabledSelectionToggles;
bool m_grouped;
int m_activeTransactions; // Counter for beginTransaction()/endTransaction()
#include "kitemlistwidget.h"
+#include "kitemlistselectiontoggle_p.h"
#include "kitemlistview.h"
#include "kitemmodelbase.h"
#include <KDebug>
+#include <QApplication>
#include <QPainter>
#include <QPropertyAnimation>
#include <QStyle>
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)
{
}
void KItemListWidget::setIndex(int index)
{
if (m_index != index) {
+ delete m_selectionToggle;
+ m_selectionToggle = 0;
+
if (m_hoverAnimation) {
m_hoverAnimation->stop();
m_hoverOpacity = 0;
{
if (m_selected != selected) {
m_selected = selected;
+ if (m_selectionToggle) {
+ m_selectionToggle->setChecked(selected);
+ }
+
selectedChanged(selected);
update();
}
{
if (m_current != current) {
m_current = current;
+
currentChanged(current);
update();
}
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);
}
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)) {
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();
}
#include <QGraphicsWidget>
+class KItemListSelectionToggle;
class QPropertyAnimation;
/**
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;
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()
*/
qreal hoverOpacity() const;
+private slots:
+ void slotHoverAnimationFinished();
+
private:
+ void initializeSelectionToggle();
void setHoverOpacity(qreal opacity);
void clearHoverCache();
void drawTextBackground(QPainter* painter);
bool m_current;
bool m_hovered;
bool m_alternatingBackgroundColors;
+ bool m_enabledSelectionToggle;
QHash<QByteArray, QVariant> m_data;
QList<QByteArray> m_visibleRoles;
QHash<QByteArray, QSizeF> m_visibleRolesSizes;
qreal m_hoverOpacity;
mutable QPixmap* m_hoverCache;
QPropertyAnimation* m_hoverAnimation;
+
+ KItemListSelectionToggle* m_selectionToggle;
};
#endif
#include "dolphinitemlistcontainer.h"
+#include "dolphin_generalsettings.h"
#include "dolphin_iconsmodesettings.h"
#include "dolphin_detailsmodesettings.h"
#include "dolphin_compactmodesettings.h"
m_fileItemListView = new KFileItemListView();
m_fileItemListView->setWidgetCreator(new KItemListWidgetCreator<DolphinFileItemListWidget>());
+ 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()