]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Blend in a toggle button when hovering items. This allows selecting items without...
authorPeter Penz <peter.penz19@gmail.com>
Sat, 26 Jan 2008 21:45:28 +0000 (21:45 +0000)
committerPeter Penz <peter.penz19@gmail.com>
Sat, 26 Jan 2008 21:45:28 +0000 (21:45 +0000)
svn path=/trunk/KDE/kdebase/apps/; revision=766901

14 files changed:
src/CMakeLists.txt
src/dolphin_generalsettings.kcfg
src/dolphincolumnwidget.cpp
src/dolphincolumnwidget.h
src/dolphindetailsview.cpp
src/dolphindetailsview.h
src/dolphiniconsview.cpp
src/dolphiniconsview.h
src/generalviewsettingspage.cpp
src/generalviewsettingspage.h
src/selectionmanager.cpp [new file with mode: 0644]
src/selectionmanager.h [new file with mode: 0644]
src/selectiontoggle.cpp [new file with mode: 0644]
src/selectiontoggle.h [new file with mode: 0644]

index f11b62817760e589138357a2337350151ce55114..4d0d097dda234e8dae50c64bd04ec958855e318b 100644 (file)
@@ -27,6 +27,8 @@ set(dolphinprivate_LIB_SRCS
     iconmanager.cpp
     ratingpainter.cpp
     renamedialog.cpp
+    selectiontoggle.cpp
+    selectionmanager.cpp
     viewproperties.cpp
     )
 
index 7bf41d03044a06afc8ce6908694838f2065c23b8..6149480b31e9d9f6fb6d86b03c132a3340ce5a24 100644 (file)
             <label context="@label">Browse through archives</label>
             <default>false</default>
         </entry>
+        <entry name="ShowSelectionToggle" type="Bool">
+            <label context="@label">Show selection toggle</label>
+            <default>true</default>
+        </entry>
         <entry name="ViewPropsTimestamp" type="DateTime" >
             <label context="@label">Timestamp since when the view properties are valid</label>
         </entry>
index ae5f32fcfbe857879b6cf32242d476127e3069c0..8bf66b2c8874e0eb17acccfbb448b70f19cac9de 100644 (file)
@@ -26,7 +26,9 @@
 #include "dolphinsortfilterproxymodel.h"
 #include "dolphinsettings.h"
 #include "dolphin_columnmodesettings.h"
+#include "dolphin_generalsettings.h"
 #include "draganddrophelper.h"
+#include "selectionmanager.h"
 
 #include <kcolorscheme.h>
 #include <kdirlister.h>
@@ -118,6 +120,13 @@ DolphinColumnWidget::DolphinColumnWidget(QWidget* parent,
     m_proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
 
     setModel(m_proxyModel);
+    const bool useSelManager = KGlobalSettings::singleClick() &&
+                               DolphinSettings::instance().generalSettings()->showSelectionToggle();
+    if (useSelManager) {
+        SelectionManager* selManager = new SelectionManager(this);
+        connect(selManager, SIGNAL(selectionChanged()),
+                this, SLOT(requestActivation()));
+    }
     new KMimeTypeResolver(this, m_dolphinModel);
     m_iconManager = new IconManager(this, m_proxyModel);
     m_iconManager->setShowPreview(m_view->m_controller->dolphinView()->showPreview());
@@ -304,12 +313,7 @@ void DolphinColumnWidget::paintEvent(QPaintEvent* event)
 
 void DolphinColumnWidget::mousePressEvent(QMouseEvent* event)
 {
-    m_view->m_controller->requestActivation();
-    if (!m_active) {
-        m_view->requestActivation(this);
-        m_view->m_controller->triggerUrlChangeRequest(m_url);
-    }
-
+    requestActivation();
     QListView::mousePressEvent(event);
 }
 
@@ -367,6 +371,16 @@ void DolphinColumnWidget::slotEntered(const QModelIndex& index)
     m_view->m_controller->emitItemEntered(item);
 }
 
+void DolphinColumnWidget::requestActivation()
+{
+    m_view->m_controller->requestActivation();
+    if (!m_active) {
+        m_view->requestActivation(this);
+        m_view->m_controller->triggerUrlChangeRequest(m_url);
+        selectionModel()->clear();
+    }
+}
+
 void DolphinColumnWidget::activate()
 {
     setFocus(Qt::OtherFocusReason);
index de14576e7bb98c7369ca69110e188525b1d1814f..87c7ab5771b8f3d2fba1aec2513e290a099785ca 100644 (file)
@@ -117,6 +117,8 @@ private slots:
 
     void slotEntered(const QModelIndex& index);
 
+    void requestActivation();
+
 private:
     /** Used by DolphinColumnWidget::setActive(). */
     void activate();
index c5852fa683564a920d76681dec898be79bc81333..09645a489ff723bd29625e5ec999fc773fb28a97 100644 (file)
 #include "dolphinsettings.h"
 #include "dolphinsortfilterproxymodel.h"
 #include "draganddrophelper.h"
+#include "selectionmanager.h"
 #include "viewproperties.h"
 
 #include "dolphin_detailsmodesettings.h"
+#include "dolphin_generalsettings.h"
 
 #include <kdirmodel.h>
 #include <klocale.h>
@@ -94,6 +96,11 @@ DolphinDetailsView::DolphinDetailsView(QWidget* parent, DolphinController* contr
     if (KGlobalSettings::singleClick()) {
         connect(this, SIGNAL(clicked(const QModelIndex&)),
                 this, SLOT(triggerItem(const QModelIndex&)));
+        if (DolphinSettings::instance().generalSettings()->showSelectionToggle()) {
+            SelectionManager* selManager = new SelectionManager(this);
+            connect(selManager, SIGNAL(selectionChanged()),
+                    this, SLOT(requestActivation()));
+        }
     } else {
         connect(this, SIGNAL(doubleClicked(const QModelIndex&)),
                 this, SLOT(triggerItem(const QModelIndex&)));
@@ -508,6 +515,11 @@ void DolphinDetailsView::disableAutoResizing()
     m_autoResize = false;
 }
 
+void DolphinDetailsView::requestActivation()
+{
+    m_controller->requestActivation();
+}
+
 bool DolphinDetailsView::isZoomInPossible() const
 {
     DetailsModeSettings* settings = DolphinSettings::instance().detailsModeSettings();
index a9201d8b3401b8f0d536bb51650d40b1764f4b6b..316620a5a43ef54144874a6d72b1b23849599dce 100644 (file)
@@ -130,6 +130,8 @@ private slots:
      */
     void disableAutoResizing();
 
+    void requestActivation();
+
 private:
     bool isZoomInPossible() const;
     bool isZoomOutPossible() const;
index c867ce61109ab1459a19d90a17741d0c49429258..18d4accec5291f74bb85c1c26523d07f82bf8cfa 100644 (file)
@@ -23,7 +23,9 @@
 #include "dolphincontroller.h"
 #include "dolphinsettings.h"
 #include "dolphin_iconsmodesettings.h"
+#include "dolphin_generalsettings.h"
 #include "draganddrophelper.h"
+#include "selectionmanager.h"
 
 #include <kcategorizedsortfilterproxymodel.h>
 #include <kdialog.h>
@@ -65,6 +67,11 @@ DolphinIconsView::DolphinIconsView(QWidget* parent, DolphinController* controlle
     if (KGlobalSettings::singleClick()) {
         connect(this, SIGNAL(clicked(const QModelIndex&)),
                 this, SLOT(triggerItem(const QModelIndex&)));
+        if (DolphinSettings::instance().generalSettings()->showSelectionToggle()) {
+            SelectionManager* selManager = new SelectionManager(this);
+            connect(selManager, SIGNAL(selectionChanged()),
+                    this, SLOT(requestActivation()));
+        }
     } else {
         connect(this, SIGNAL(doubleClicked(const QModelIndex&)),
                 this, SLOT(triggerItem(const QModelIndex&)));
@@ -389,6 +396,11 @@ void DolphinIconsView::zoomOut()
     }
 }
 
+void DolphinIconsView::requestActivation()
+{
+    m_controller->requestActivation();
+}
+
 bool DolphinIconsView::isZoomInPossible() const
 {
     IconsModeSettings* settings = DolphinSettings::instance().iconsModeSettings();
index ade58e156d02894b91deee7a70a9dd23ef634f66..05b21a2b0c53c44c55f120c35992aca3cc470e1a 100644 (file)
@@ -71,6 +71,7 @@ private slots:
     void slotAdditionalInfoChanged();
     void zoomIn();
     void zoomOut();
+    void requestActivation();
 
 private:
     bool isZoomInPossible() const;
index b9fbc17beaddd9754102aa3a6c42a784a6726f13..ebf235f2a392ae165f56f39e44de4d51fd8d4e94 100644 (file)
@@ -47,7 +47,8 @@ GeneralViewSettingsPage::GeneralViewSettingsPage(DolphinMainWindow* mainWindow,
     m_globalProps(0),
     m_maxPreviewSize(0),
     m_spinBox(0),
-    m_useFileThumbnails(0)
+    m_useFileThumbnails(0),
+    m_showSelectionToggle(0)
 {
     const int spacing = KDialog::spacingHint();
     const int margin = KDialog::marginHint();
@@ -87,6 +88,8 @@ GeneralViewSettingsPage::GeneralViewSettingsPage(DolphinMainWindow* mainWindow,
     previewBoxLayout->addWidget(vBox);
     previewBoxLayout->addWidget(m_useFileThumbnails);
 
+    m_showSelectionToggle = new QCheckBox(i18nc("option:check", "Show selection toggle"), this);
+
     // Add a dummy widget with no restriction regarding
     // a vertical resizing. This assures that the dialog layout
     // is not stretched vertically.
@@ -128,6 +131,8 @@ void GeneralViewSettingsPage::applySettings()
                             m_useFileThumbnails->isChecked(),
                             KConfigBase::Normal | KConfigBase::Global);
     globalConfig.sync();
+
+    settings->setShowSelectionToggle(m_showSelectionToggle->isChecked());
 }
 
 void GeneralViewSettingsPage::restoreDefaults()
@@ -174,6 +179,8 @@ void GeneralViewSettingsPage::loadSettings()
 
     const bool useFileThumbnails = globalConfig.readEntry("UseFileThumbnails", true);
     m_useFileThumbnails->setChecked(useFileThumbnails);
+
+    m_showSelectionToggle->setChecked(settings->showSelectionToggle());
 }
 
 #include "generalviewsettingspage.moc"
index 5aad4be4fc1146b5ecd8a091f1d03a14bbd40a8b..c84335dc1e655011ab320820177e7c36d257c9ba 100644 (file)
@@ -60,6 +60,7 @@ private:
     QSlider* m_maxPreviewSize;
     QSpinBox* m_spinBox;
     QCheckBox* m_useFileThumbnails;
+    QCheckBox* m_showSelectionToggle;
 };
 
 #endif
diff --git a/src/selectionmanager.cpp b/src/selectionmanager.cpp
new file mode 100644 (file)
index 0000000..1f9d99b
--- /dev/null
@@ -0,0 +1,132 @@
+/***************************************************************************
+ *   Copyright (C) 2008 by Peter Penz <peter.penz@gmx.at>                  *
+ *                                                                         *
+ *   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 "selectionmanager.h"
+
+#include "dolphinmodel.h"
+#include "selectiontoggle.h"
+#include <kdirmodel.h>
+#include <kiconeffect.h>
+
+#include <QAbstractButton>
+#include <QAbstractItemView>
+#include <QAbstractProxyModel>
+#include <QModelIndex>
+#include <QPainter>
+#include <QPaintEvent>
+#include <QRect>
+
+SelectionManager::SelectionManager(QAbstractItemView* parent) :
+    QObject(parent),
+    m_view(parent),
+    m_button(0),
+    m_item()
+{
+    connect(parent, SIGNAL(entered(const QModelIndex&)),
+            this, SLOT(slotEntered(const QModelIndex&)));
+    connect(parent, SIGNAL(viewportEntered()),
+            this, SLOT(slotViewportEntered()));
+    m_button = new SelectionToggle(m_view->viewport());
+    m_button->setCheckable(true);
+    m_button->hide();
+    connect(m_button, SIGNAL(clicked(bool)),
+            this, SLOT(setItemSelected(bool)));
+    connect(m_view->selectionModel(), SIGNAL(selectionChanged()),
+            this, SLOT(slotSelectionChanged()));
+}
+
+SelectionManager::~SelectionManager()
+{
+}
+
+void SelectionManager::slotEntered(const QModelIndex& index)
+{
+    m_button->hide();
+    if (index.isValid() && (index.column() == DolphinModel::Name)) {
+        m_item = itemForIndex(index);
+
+        const QRect rect = m_view->visualRect(index);
+        const int gap = 2;
+        const int x = rect.right() - m_button->width() - gap;
+        int y = rect.top();
+        if (rect.height() <= m_button->height() * 2) {
+            // center the button vertically
+            y += (rect.height() - m_button->height()) / 2;
+        } else {
+            y += gap;
+        }
+
+        m_button->move(QPoint(x, y));
+
+        QItemSelectionModel* selModel = m_view->selectionModel();
+        m_button->setChecked(selModel->isSelected(index));
+        m_button->show();
+    } else {
+        m_item = KFileItem();
+    }
+}
+
+void SelectionManager::slotViewportEntered()
+{
+    m_button->hide();
+    m_item = KFileItem();
+}
+
+void SelectionManager::slotSelectionChanged()
+{
+    const QModelIndex index = indexForItem(m_item);
+    if (index.isValid()) {
+        QItemSelectionModel* selModel = m_view->selectionModel();
+        m_button->setChecked(selModel->isSelected(index));
+    }
+}
+
+void SelectionManager::setItemSelected(bool selected)
+{
+    emit selectionChanged();
+    Q_ASSERT(!m_item.isNull());
+
+    const QModelIndex index = indexForItem(m_item);
+    if (index.isValid()) {
+        QItemSelectionModel* selModel = m_view->selectionModel();
+        if (selected) {
+            selModel->select(index, QItemSelectionModel::Select);
+        } else {
+            selModel->select(index, QItemSelectionModel::Deselect);
+        }
+    }
+}
+
+KFileItem SelectionManager::itemForIndex(const QModelIndex& index) const
+{
+    QAbstractProxyModel* proxyModel = static_cast<QAbstractProxyModel*>(m_view->model());
+    KDirModel* dirModel = static_cast<KDirModel*>(proxyModel->sourceModel());
+    const QModelIndex dirIndex = proxyModel->mapToSource(index);
+    return dirModel->itemForIndex(dirIndex);
+}
+
+const QModelIndex SelectionManager::indexForItem(const KFileItem& item) const
+{
+    QAbstractProxyModel* proxyModel = static_cast<QAbstractProxyModel*>(m_view->model());
+    KDirModel* dirModel = static_cast<KDirModel*>(proxyModel->sourceModel());
+    const QModelIndex dirIndex = dirModel->indexForItem(item);
+    return proxyModel->mapFromSource(dirIndex);
+}
+
+#include "selectionmanager.moc"
diff --git a/src/selectionmanager.h b/src/selectionmanager.h
new file mode 100644 (file)
index 0000000..1bf4f8b
--- /dev/null
@@ -0,0 +1,66 @@
+/***************************************************************************
+ *   Copyright (C) 2008 by Peter Penz <peter.penz@gmx.at>                  *
+ *                                                                         *
+ *   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 SELECTIONMANAGER_H
+#define SELECTIONMANAGER_H
+
+#include <kfileitem.h>
+
+#include <QObject>
+
+class DolphinSortFilterProxyModel;
+class QAbstractItemView;
+class QModelIndex;
+class QAbstractButton;
+
+/**
+ * @brief Allows to select and deselect items for the single-click mode.
+ *
+ * Whenever an item is hovered by the mouse, a toggle button is shown
+ * which allows to select/deselect the current item.
+ */
+class SelectionManager : public QObject
+{
+    Q_OBJECT
+
+public:
+    SelectionManager(QAbstractItemView* parent);
+    virtual ~SelectionManager();
+
+signals:
+    /** Is emitted if the selection has been changed by the toggle button. */
+    void selectionChanged();
+
+private slots:
+    void slotEntered(const QModelIndex& index);
+    void slotViewportEntered();
+    void slotSelectionChanged();
+    void setItemSelected(bool selected);
+
+private:
+    KFileItem itemForIndex(const QModelIndex& index) const;
+    const QModelIndex indexForItem(const KFileItem& item) const;
+
+private:
+    QAbstractItemView* m_view;
+    QAbstractButton* m_button;
+    KFileItem m_item;
+};
+
+#endif
diff --git a/src/selectiontoggle.cpp b/src/selectiontoggle.cpp
new file mode 100644 (file)
index 0000000..244f515
--- /dev/null
@@ -0,0 +1,113 @@
+/***************************************************************************
+ *   Copyright (C) 2008 by Peter Penz <peter.penz@gmx.at>                  *
+ *                                                                         *
+ *   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 "selectiontoggle.h"
+
+#include <kicon.h>
+#include <kiconloader.h>
+#include <kiconeffect.h>
+
+#include <QPainter>
+#include <QPaintEvent>
+#include <QRect>
+#include <QTimer>
+
+#include <kdebug.h>
+
+SelectionToggle::SelectionToggle(QWidget* parent) :
+    QAbstractButton(parent),
+    m_showIcon(false),
+    m_isHovered(false),
+    m_icon(),
+    m_timer(0)
+{
+    parent->installEventFilter(this);
+    resize(sizeHint());
+    m_icon = KIconLoader::global()->loadIcon("dialog-ok",
+                                             KIconLoader::NoGroup,
+                                             KIconLoader::SizeSmall);
+    m_timer = new QTimer(this);
+    connect(m_timer, SIGNAL(timeout()),
+            this, SLOT(showIcon()));
+}
+
+SelectionToggle::~SelectionToggle()
+{
+}
+
+QSize SelectionToggle::sizeHint() const
+{
+    return QSize(16, 16);
+}
+
+void SelectionToggle::setVisible(bool visible)
+{
+    QAbstractButton::setVisible(visible);
+    if (visible) {
+        m_timer->start(1000);
+    } else {
+        m_timer->stop();
+        m_showIcon = false;
+    }
+}
+
+bool SelectionToggle::eventFilter(QObject* obj, QEvent* event)
+{
+    if ((obj == parent()) && (event->type() == QEvent::Leave)) {
+        hide();
+    }
+    return QAbstractButton::eventFilter(obj, event);
+}
+
+void SelectionToggle::enterEvent(QEvent* event)
+{
+    QAbstractButton::enterEvent(event);
+    m_isHovered = true;
+    m_showIcon = true;
+    update();
+}
+
+void SelectionToggle::leaveEvent(QEvent* event)
+{
+    QAbstractButton::leaveEvent(event);
+    m_isHovered = false;
+    update();
+}
+
+void SelectionToggle::paintEvent(QPaintEvent* event)
+{
+    QPainter painter(this);
+    painter.setClipRect(event->rect());
+
+    if (m_isHovered) {
+        KIconEffect iconEffect;
+        QPixmap activeIcon = iconEffect.apply(m_icon, KIconLoader::Desktop, KIconLoader::ActiveState);
+        painter.drawPixmap(0, 0, activeIcon);
+    } else if (m_showIcon) {
+        painter.drawPixmap(0, 0, m_icon);
+    }
+}
+
+void SelectionToggle::showIcon()
+{
+    m_showIcon = true;
+    update();
+}
+
+#include "selectiontoggle.moc"
diff --git a/src/selectiontoggle.h b/src/selectiontoggle.h
new file mode 100644 (file)
index 0000000..5815c5d
--- /dev/null
@@ -0,0 +1,59 @@
+/***************************************************************************
+ *   Copyright (C) 2008 by Peter Penz <peter.penz@gmx.at>                  *
+ *                                                                         *
+ *   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 SELECTIONTOGGLE_H
+#define SELECTIONTOGGLE_H
+
+#include <QAbstractButton>
+#include <QPixmap>
+#include <QTimer>
+
+/**
+ * @brief Toggle button for changing the selection of an hovered item.
+ * @see SelectionManager
+ */
+class SelectionToggle : public QAbstractButton
+{
+    Q_OBJECT
+
+public:
+    explicit SelectionToggle(QWidget* parent);
+    virtual ~SelectionToggle();
+    virtual QSize sizeHint() const;
+
+public slots:
+    virtual void setVisible(bool visible);
+
+protected:
+    virtual bool eventFilter(QObject* obj, QEvent* event);
+    virtual void enterEvent(QEvent* event);
+    virtual void leaveEvent(QEvent* event);
+    virtual void paintEvent(QPaintEvent* event);
+
+private slots:
+    void showIcon();
+
+private:
+    bool m_showIcon;
+    bool m_isHovered;
+    QPixmap m_icon;
+    QTimer* m_timer;
+};
+
+#endif