[kde-doc-english] [calligra] /: Additional quick action buttons when mouse is over items, in Stage

Paul Mendez paulestebanms at gmail.com
Wed Jun 13 03:45:21 UTC 2012


Git commit da26e15952695155bc63af7b69736c62b440cfd8 by Paul Mendez.
Committed on 13/06/2012 at 05:42.
Pushed by mendez into branch 'master'.

Additional quick action buttons when mouse is over items, in Stage
slides sorter.

Stage slides sorter has +/- buttons that appear when you move the mouse
over an item to allow you select or deselect multiple items without
using the keyboard.  This patch add extra actions (remove/duplicate
slide and start slideshow from here) like gwenview, digikam quick actions.

REVIEW: 103538
GUI: Hover buttons for quick actions in Stage Slide Sorter

M  +6    -2    libs/kopageapp/KoPADocumentStructureDocker.cpp
M  +2    -0    libs/kopageapp/KoPADocumentStructureDocker.h
M  +2    -2    libs/widgets/CMakeLists.txt
A  +192  -0    libs/widgets/KoContextBarButton.cpp     [License: GPL]
A  +63   -0    libs/widgets/KoContextBarButton.h     [License: GPL]
D  +0    -260  libs/widgets/KoSelectionManager.cpp
D  +0    -244  libs/widgets/KoSelectionToggle.cpp
D  +0    -101  libs/widgets/KoSelectionToggle.h
A  +278  -0    libs/widgets/KoViewItemContextBar.cpp     [License: LGPL (v2+)]
R  +44   -18   libs/widgets/KoViewItemContextBar.h [from: libs/widgets/KoSelectionManager.h - 051% similarity]
M  +6    -7    stage/part/KPrSlidesManagerView.cpp
M  +0    -8    stage/part/KPrSlidesManagerView.h
M  +1    -0    stage/part/KPrSlidesSorterDocumentModel.cpp
M  +59   -21   stage/part/KPrViewModeSlidesSorter.cpp
M  +7    -5    stage/part/KPrViewModeSlidesSorter.h

http://commits.kde.org/calligra/da26e15952695155bc63af7b69736c62b440cfd8

diff --git a/libs/kopageapp/KoPADocumentStructureDocker.cpp b/libs/kopageapp/KoPADocumentStructureDocker.cpp
index 7b31e54..18449ce 100644
--- a/libs/kopageapp/KoPADocumentStructureDocker.cpp
+++ b/libs/kopageapp/KoPADocumentStructureDocker.cpp
@@ -45,7 +45,7 @@
 #include <KoShapeReorderCommand.h>
 #include <KoShapeLayer.h>
 #include <KoShapePaste.h>
-#include <KoSelectionManager.h>
+#include <KoViewItemContextBar.h>
 
 #include <KMenu>
 #include <klocale.h>
@@ -175,7 +175,6 @@ KoPADocumentStructureDocker::KoPADocumentStructureDocker(KoDocumentSectionView::
     m_sectionView->setSelectionBehavior(QAbstractItemView::SelectRows);
     m_sectionView->setSelectionMode(QAbstractItemView::ExtendedSelection);
     m_sectionView->setDragDropMode(QAbstractItemView::InternalMove);
-    new KoSelectionManager(m_sectionView);
 
     connect(m_sectionView, SIGNAL(pressed(const QModelIndex&)), this, SLOT(itemClicked(const QModelIndex&)));
     connect(m_sectionView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
@@ -191,6 +190,8 @@ KoPADocumentStructureDocker::KoPADocumentStructureDocker(KoDocumentSectionView::
         setViewMode(mode);
     else
         setViewMode(viewModeFromString(viewModeString));
+
+    m_itemsContextBar = new KoViewItemContextBar(m_sectionView);
 }
 
 KoPADocumentStructureDocker::~KoPADocumentStructureDocker()
@@ -516,16 +517,19 @@ void KoPADocumentStructureDocker::setMasterMode(bool master)
 void KoPADocumentStructureDocker::minimalView()
 {
     setViewMode(KoDocumentSectionView::MinimalMode);
+    m_itemsContextBar->disableContextBar();
 }
 
 void KoPADocumentStructureDocker::detailedView()
 {
     setViewMode(KoDocumentSectionView::DetailedMode);
+    m_itemsContextBar->disableContextBar();
 }
 
 void KoPADocumentStructureDocker::thumbnailView()
 {
     setViewMode(KoDocumentSectionView::ThumbnailMode);
+    m_itemsContextBar->enableContextBar();
 }
 
 void KoPADocumentStructureDocker::setViewMode(KoDocumentSectionView::DisplayMode mode)
diff --git a/libs/kopageapp/KoPADocumentStructureDocker.h b/libs/kopageapp/KoPADocumentStructureDocker.h
index c49c429..0718a8c 100644
--- a/libs/kopageapp/KoPADocumentStructureDocker.h
+++ b/libs/kopageapp/KoPADocumentStructureDocker.h
@@ -32,6 +32,7 @@ class KoShapeLayer;
 class KoPADocument;
 class KoPADocumentModel;
 class KoPAPageBase;
+class KoViewItemContextBar;
 class QModelIndex;
 class QAction;
 class QButtonGroup;
@@ -122,6 +123,7 @@ private:
     QList<KoShape *> m_selectedShapes;
     QButtonGroup *m_buttonGroup;
     QAction* m_addLayerAction;
+    KoViewItemContextBar *m_itemsContextBar;
 };
 
 #endif // KOPADOCUMENTSTRUCTUREDOCKER_H
diff --git a/libs/widgets/CMakeLists.txt b/libs/widgets/CMakeLists.txt
index 9c25397..61df2d6 100644
--- a/libs/widgets/CMakeLists.txt
+++ b/libs/widgets/CMakeLists.txt
@@ -59,8 +59,8 @@ set(kowidgets_LIB_SRCS
     KoMarkerSelector.cpp
     KoDockWidgetTitleBar.cpp
     KoDockWidgetTitleBarButton.cpp
-    KoSelectionManager.cpp
-    KoSelectionToggle.cpp
+    KoViewItemContextBar.cpp
+    KoContextBarButton.cpp
 )
 
 kde4_add_ui_files( kowidgets_LIB_SRCS
diff --git a/libs/widgets/KoContextBarButton.cpp b/libs/widgets/KoContextBarButton.cpp
new file mode 100644
index 0000000..83cf549
--- /dev/null
+++ b/libs/widgets/KoContextBarButton.cpp
@@ -0,0 +1,192 @@
+// vim: set tabstop=4 shiftwidth=4 noexpandtab:
+/* This file is part of the KDE project
+Copyright 2011 Aurélien Gâteau <agateau at kde.org>
+Copyright 2011 Paul Mendez <paulestebanms at 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, Cambridge, MA 02110-1301, USA.
+
+*/
+
+#include "KoContextBarButton.h"
+
+// KDE
+#include <kiconloader.h>
+#include <KGlobalSettings>
+
+// Qt
+#include <QStyleOptionToolButton>
+#include <QStylePainter>
+#include <QPainterPath>
+
+/** How lighter is the border of context bar buttons */
+const int CONTEXTBAR_BORDER_LIGHTNESS = 140;
+
+/** How darker is the background of context bar buttons */
+const int CONTEXTBAR_BACKGROUND_DARKNESS = 80;
+
+/** How lighter are context bar buttons when under mouse */
+const int CONTEXTBAR_MOUSEOVER_LIGHTNESS = 120;
+
+/** Radius of ContextBarButtons */
+const int CONTEXTBAR_RADIUS = 50;
+
+KoContextBarButton::KoContextBarButton(const QString &iconName, QWidget* parent)
+: QToolButton(parent)
+, m_isHovered(false)
+, m_leftMouseButtonPressed(false)
+, m_fadingValue(0)
+, m_fadingTimeLine(0)
+{
+    const int size = KIconLoader::global()->currentSize(KIconLoader::Small);
+    setIconSize(QSize(size, size));
+    setAutoRaise(true);
+    setIcon(SmallIcon(iconName));
+}
+
+
+KoContextBarButton::~KoContextBarButton()
+{
+}
+
+
+void KoContextBarButton::paintEvent(QPaintEvent*)
+{
+    QStylePainter painter(this);
+    painter.setRenderHint(QPainter::Antialiasing);
+    QStyleOptionToolButton opt;
+    initStyleOption(&opt);
+
+    const QColor bgColor = palette().color(QPalette::Highlight);
+    QColor color = bgColor.dark(CONTEXTBAR_BACKGROUND_DARKNESS);
+    QColor borderColor = bgColor.light(CONTEXTBAR_BORDER_LIGHTNESS);
+
+    if (opt.state & QStyle::State_MouseOver && opt.state & QStyle::State_Enabled) {
+            color = color.light(CONTEXTBAR_MOUSEOVER_LIGHTNESS);
+            borderColor = borderColor.lighter(CONTEXTBAR_MOUSEOVER_LIGHTNESS);
+    }
+
+    const QRectF rectF = QRectF(opt.rect).adjusted(0.5, 0.5, -0.5, -0.5);
+    QPainterPath path;
+    path.addRoundRect(rectF, CONTEXTBAR_RADIUS, CONTEXTBAR_RADIUS);
+
+    if (m_fadingValue < 255) {
+        color.setAlpha(m_fadingValue);
+    }
+
+    // Background
+    painter.fillPath(path, color);
+
+    if (opt.state & QStyle::State_Raised && opt.state & QStyle::State_Enabled) {
+        // Botton shadow
+        QLinearGradient gradient(rectF.bottomLeft(), rectF.bottomLeft() - QPoint(0, 5));
+        gradient.setColorAt(0, QColor::fromHsvF(0, 0, 0, .3));
+        gradient.setColorAt(1, Qt::transparent);
+        painter.fillPath(path, gradient);
+
+        // Left shadow
+        gradient.setFinalStop(rectF.bottomLeft() + QPoint(3, 0));
+        painter.fillPath(path, gradient);
+    }
+    else {
+        // Top shadow
+        QLinearGradient gradient(rectF.topLeft(), rectF.topLeft() + QPoint(0, 5));
+        gradient.setColorAt(0, QColor::fromHsvF(0, 0, 0, .3));
+        gradient.setColorAt(1, Qt::transparent);
+        painter.fillPath(path, gradient);
+
+        // Left shadow
+        gradient.setFinalStop(rectF.topLeft() + QPoint(5, 0));
+        painter.fillPath(path, gradient);
+    }
+
+    // Border
+    painter.setPen(borderColor);
+    painter.drawPath(path);
+
+    // Content
+    painter.drawControl(QStyle::CE_ToolButtonLabel, opt);
+}
+
+void KoContextBarButton::startFading()
+{
+    Q_ASSERT(!m_fadingTimeLine);
+
+    const bool animate = KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects;
+    const int duration = animate ? 300 : 1;
+
+    m_fadingTimeLine = new QTimeLine(duration, this);
+    connect(m_fadingTimeLine, SIGNAL(frameChanged(int)),
+            this, SLOT(setFadingValue(int)));
+    m_fadingTimeLine->setFrameRange(0, 255);
+    m_fadingTimeLine->start();
+    m_fadingValue = 0;
+}
+
+void KoContextBarButton::stopFading()
+{
+    if (m_fadingTimeLine) {
+        m_fadingTimeLine->stop();
+        delete m_fadingTimeLine;
+        m_fadingTimeLine = 0;
+    }
+    m_fadingValue = 0;
+}
+
+void KoContextBarButton::enterEvent(QEvent *event)
+{
+    QToolButton::enterEvent(event);
+
+    // if the mouse cursor is above the selection toggle, display
+    // it immediately without fading timer
+    m_isHovered = true;
+    if (m_fadingTimeLine) {
+        m_fadingTimeLine->stop();
+    }
+    m_fadingValue = 255;
+    update();
+}
+
+void KoContextBarButton::leaveEvent(QEvent *event)
+{
+    QToolButton::leaveEvent(event);
+
+    m_isHovered = false;
+    update();
+}
+
+void KoContextBarButton::setFadingValue(int value)
+{
+    m_fadingValue = value;
+    if (m_fadingValue >= 255) {
+        Q_ASSERT(m_fadingTimeLine);
+        m_fadingTimeLine->stop();
+    }
+    update();
+}
+
+void KoContextBarButton::showEvent(QShowEvent *event)
+{
+    stopFading();
+    startFading();
+    QToolButton::showEvent(event);
+}
+
+void KoContextBarButton::hideEvent(QHideEvent *event)
+{
+    stopFading();
+    QToolButton::hideEvent(event);
+}
+// Self
+#include "KoContextBarButton.moc"
diff --git a/libs/widgets/KoContextBarButton.h b/libs/widgets/KoContextBarButton.h
new file mode 100644
index 0000000..717f505
--- /dev/null
+++ b/libs/widgets/KoContextBarButton.h
@@ -0,0 +1,63 @@
+// vim: set tabstop=4 shiftwidth=4 noexpandtab:
+/* This file is part of the KDE project
+Copyright 2011 Aurélien Gâteau <agateau at kde.org>
+Copyright 2011 Paul Mendez <paulestebanms at 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, Cambridge, MA 02110-1301, USA.
+
+*/
+#ifndef KOCONTEXTBARBUTTON_H
+#define KOCONTEXTBARBUTTON_H
+
+// KDE
+
+// Qt
+#include <QToolButton>
+#include <QTimeLine>
+
+class QTimeLine;
+/**
+ * A button with a special look, appears when hovering over thumbnails
+ */
+class KoContextBarButton : public QToolButton {
+    Q_OBJECT
+public:
+    KoContextBarButton(const QString &iconName, QWidget* parent=0);
+    ~KoContextBarButton();
+
+public slots:
+    void setFadingValue(int value);
+
+protected:
+    void paintEvent(QPaintEvent*);
+    virtual void enterEvent(QEvent *event);
+    virtual void leaveEvent(QEvent *event);
+    virtual void showEvent(QShowEvent *event);
+    virtual void hideEvent(QHideEvent *event);
+
+
+private:
+    /** Starts button fading animation */
+    void startFading();
+
+    /** Stops button fading animation */
+    void stopFading();
+    bool m_isHovered;
+    bool m_leftMouseButtonPressed;
+    int m_fadingValue;
+    QTimeLine *m_fadingTimeLine;
+};
+
+#endif /* KOCONTEXTBARBUTTON_H */
diff --git a/libs/widgets/KoSelectionManager.cpp b/libs/widgets/KoSelectionManager.cpp
deleted file mode 100644
index 23d0d88..0000000
--- a/libs/widgets/KoSelectionManager.cpp
+++ /dev/null
@@ -1,260 +0,0 @@
-/* This file is part of the KDE project
-*
-* Copyright (C) 2008 Peter Penz <peter.penz19 at gmail.com>
-* Copyright (C) 2011 Paul Mendez <paulestebanms at gmail.com>
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Library General Public
-* License as published by the Free Software Foundation; either
-* version 2 of the License, or (at your option) any later version.
-*
-* This library 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
-* Library General Public License for more details.
-*
-* You should have received a copy of the GNU Library General Public License
-* along with this library; see the file COPYING.LIB.  If not, write to
-* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-* Boston, MA 02110-1301, USA.
-*/
-
-#include "KoSelectionManager.h"
-
-//Calligra headers
-#include "KoSelectionToggle.h"
-
-//KDE headers
-#include <KGlobalSettings>
-#include <KIconLoader>
-
-//Qt Headers
-#include <QAbstractItemView>
-#include <QModelIndex>
-#include <QApplication>
-
-KoSelectionManager::KoSelectionManager(QAbstractItemView *parent)
-    : QObject(parent)
-    , m_view(parent)
-    , m_toggle(0)
-    , m_connected(false)
-    , m_appliedPointingHandCursor(false)
-{
-    connect(parent, SIGNAL(entered(const QModelIndex&)),
-            this, SLOT(slotEntered(const QModelIndex&)));
-    connect(parent, SIGNAL(viewportEntered()),
-            this, SLOT(slotViewportEntered()));
-
-    //TODO: Setting to enable selectiontoggle
-    m_toggle = new KoSelectionToggle(m_view->viewport());
-    m_toggle->setCheckable(true);
-    m_toggle->hide();
-    connect(m_toggle, SIGNAL(clicked(bool)),
-            this, SLOT(setItemSelected(bool)));
-    m_toggle->installEventFilter(this);
-
-    m_view->viewport()->installEventFilter(this);
-    m_view->setMouseTracking(true);
-}
-
-KoSelectionManager::~KoSelectionManager()
-{
-}
-
-bool KoSelectionManager::eventFilter(QObject *watched, QEvent *event)
-{
-    if (watched == m_view->viewport()) {
-        switch (event->type()) {
-        case QEvent::Leave:
-            if (m_toggle) {
-                m_toggle->hide();
-            }
-            restoreCursor();
-            break;
-
-        case QEvent::MouseButtonPress: {
-            // Set the toggle invisible, if a mouse button has been pressed
-            // outside the toggle boundaries. This e.g. assures, that the toggle
-            // gets invisible during dragging items.
-            if (m_toggle) {
-                const QRect toggleBounds(m_toggle->mapToGlobal(QPoint(0, 0)), m_toggle->size());
-                m_toggle->setVisible(toggleBounds.contains(QCursor::pos()));
-            }
-            break;
-        }
-
-        default:
-            break;
-        }
-    }
-    else if (watched == m_toggle) {
-        switch (event->type()) {
-        case QEvent::Enter:
-            QApplication::changeOverrideCursor(Qt::ArrowCursor);
-            break;
-
-        case QEvent::Leave:
-            QApplication::changeOverrideCursor(Qt::PointingHandCursor);
-            break;
-
-        default:
-            break;
-        }
-    }
-
-    return QObject::eventFilter(watched, event);
-}
-
-void KoSelectionManager::reset()
-{
-    if (m_toggle) {
-        m_toggle->reset();
-    }
-}
-
-void KoSelectionManager::slotEntered(const QModelIndex &index)
-{
-    const bool isSelectionCandidate = index.isValid() &&
-                                      (QApplication::mouseButtons() == Qt::NoButton);
-
-    restoreCursor();
-    if (isSelectionCandidate && KGlobalSettings::singleClick()) {
-        applyPointingHandCursor();
-    }
-
-    if (isSelectionCandidate) {
-        if (!m_connected) {
-            connect(m_view->model(), SIGNAL(rowsRemoved(const QModelIndex&, int, int)),
-                    this, SLOT(slotRowsRemoved(const QModelIndex&, int, int)));
-            connect(m_view->selectionModel(),
-                    SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
-                    this,
-                    SLOT(slotSelectionChanged(const QItemSelection&, const QItemSelection&)));
-            m_connected = true;
-        }
-    }
-    else {
-        disconnect(m_view->model(), SIGNAL(rowsRemoved(const QModelIndex&, int, int)),
-                   this, SLOT(slotRowsRemoved(const QModelIndex&, int, int)));
-        disconnect(m_view->selectionModel(),
-                   SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
-                   this,
-                   SLOT(slotSelectionChanged(const QItemSelection&, const QItemSelection&)));
-        m_connected = false;
-    }
-
-    if (!m_toggle) {
-        return;
-    }
-
-    m_toggle->hide();
-    if (isSelectionCandidate) {
-        m_toggle->setIndex(index);
-
-        // Increase the size of the toggle for large items
-        const int iconHeight = m_view->visualRect(index).height();
-
-        int toggleSize = KIconLoader::SizeSmall;
-        if (iconHeight >= KIconLoader::SizeEnormous) {
-            toggleSize = KIconLoader::SizeLarge/2;
-        }
-        else if (iconHeight >= KIconLoader::SizeLarge) {
-            toggleSize = KIconLoader::SizeSmallMedium;
-        }
-
-        // Add a small invisible margin, if the item-height is nearly
-        // equal to the toggleSize (#169494).
-        const QRect rect = m_view->visualRect(index);
-        int margin = (rect.height() - toggleSize) / 2;
-        if (margin > 4) {
-            margin = 0;
-        }
-        toggleSize += 2 * margin;
-        m_toggle->setMargin(margin);
-        m_toggle->resize(toggleSize, toggleSize);
-        m_toggle->move(rect.topLeft());
-
-        QItemSelectionModel *selModel = m_view->selectionModel();
-        m_toggle->setChecked(selModel->isSelected(index));
-        m_toggle->show();
-    }
-    else {
-        m_toggle->setIndex(QModelIndex());
-    }
-}
-
-void KoSelectionManager::slotViewportEntered()
-{
-    if (m_toggle) {
-        m_toggle->hide();
-    }
-    restoreCursor();
-}
-
-void KoSelectionManager::setItemSelected(bool selected)
-{
-    emit selectionChanged();
-
-    if (m_toggle && m_toggle->index().isValid()) {
-        QModelIndex index = m_toggle->index();
-        if (index.isValid()) {
-            QItemSelectionModel *selModel = m_view->selectionModel();
-            if (selected) {
-                selModel->select(index, QItemSelectionModel::Select);
-            }
-            else {
-                selModel->select(index, QItemSelectionModel::Deselect);
-            }
-            selModel->setCurrentIndex(index, QItemSelectionModel::Current);
-        }
-    }
-}
-
-void KoSelectionManager::slotRowsRemoved(const QModelIndex &parent, int start, int end)
-{
-    Q_UNUSED(parent);
-    Q_UNUSED(start);
-    Q_UNUSED(end);
-    if (m_toggle) {
-        m_toggle->hide();
-    }
-    restoreCursor();
-}
-
-void KoSelectionManager::slotSelectionChanged(const QItemSelection &selected,
-                                            const QItemSelection &deselected)
-{
-    // The selection has been changed outside the scope of the selection manager
-    // (e. g. by the rubberband or the "Select All" action). Take care updating
-    // the state of the toggle button.
-    if (m_toggle && m_toggle->index().isValid()) {
-        const QModelIndex index = m_toggle->index();
-        if (index.isValid()) {
-            if (selected.contains(index)) {
-                m_toggle->setChecked(true);
-            }
-
-            if (deselected.contains(index)) {
-                m_toggle->setChecked(false);
-            }
-        }
-    }
-}
-
-void KoSelectionManager::applyPointingHandCursor()
-{
-    if (!m_appliedPointingHandCursor) {
-        QApplication::setOverrideCursor(QCursor(Qt::PointingHandCursor));
-        m_appliedPointingHandCursor = true;
-    }
-}
-
-void KoSelectionManager::restoreCursor()
-{
-    if (m_appliedPointingHandCursor) {
-        QApplication::restoreOverrideCursor();
-        m_appliedPointingHandCursor = false;
-    }
-}
-
-#include "KoSelectionManager.moc"
diff --git a/libs/widgets/KoSelectionToggle.cpp b/libs/widgets/KoSelectionToggle.cpp
deleted file mode 100644
index 6ad6866..0000000
--- a/libs/widgets/KoSelectionToggle.cpp
+++ /dev/null
@@ -1,244 +0,0 @@
-/* This file is part of the KDE project
-*
-* Copyright (C) 2008 Peter Penz <peter.penz19 at gmail.com>
-* Copyright (C) 2011 Paul Mendez <paulestebanms at gmail.com>
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Library General Public
-* License as published by the Free Software Foundation; either
-* version 2 of the License, or (at your option) any later version.
-*
-* This library 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
-* Library General Public License for more details.
-*
-* You should have received a copy of the GNU Library General Public License
-* along with this library; see the file COPYING.LIB.  If not, write to
-* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-* Boston, MA 02110-1301, USA.
-*/
-
-#include "KoSelectionToggle.h"
-
-//KDE Headers
-#include <KGlobalSettings>
-#include <KIcon>
-#include <KIconLoader>
-#include <KIconEffect>
-#include <KLocale>
-#include <KDebug>
-
-//Qt Headers
-#include <QPainter>
-#include <QPaintEvent>
-#include <QRect>
-#include <QTimeLine>
-
-KoSelectionToggle::KoSelectionToggle(QWidget *parent)
-    : QAbstractButton(parent)
-    , m_isHovered(false)
-    , m_leftMouseButtonPressed(false)
-    , m_fadingValue(0)
-    , m_margin(0)
-    , m_icon()
-    , m_fadingTimeLine(0)
-{
-    setFocusPolicy(Qt::NoFocus);
-    parent->installEventFilter(this);
-    resize(sizeHint());
-    setIconOverlay(isChecked());
-    connect(this, SIGNAL(toggled(bool)),
-            this, SLOT(setIconOverlay(bool)));
-    connect(KGlobalSettings::self(), SIGNAL(iconChanged(int)),
-            this, SLOT(refreshIcon()));
-}
-
-KoSelectionToggle::~KoSelectionToggle()
-{
-}
-
-QSize KoSelectionToggle::sizeHint() const
-{
-    return QSize(16, 16);
-}
-
-void KoSelectionToggle::reset()
-{
-    m_index = QModelIndex();
-    hide();
-}
-
-void KoSelectionToggle::setIndex(const QModelIndex &index)
-{
-    m_index = index;
-    if (m_index.isValid()) {
-        startFading();
-    }
-}
-
-void KoSelectionToggle::setMargin(int margin)
-{
-    if (margin != m_margin) {
-        m_margin = margin;
-        update();
-    }
-}
-
-int KoSelectionToggle::margin() const
-{
-    return m_margin;
-}
-
-QModelIndex KoSelectionToggle::index() const
-{
-    return m_index;
-}
-
-void KoSelectionToggle::setVisible(bool visible)
-{
-    QAbstractButton::setVisible(visible);
-
-    stopFading();
-    if (visible) {
-        startFading();
-    }
-
-}
-
-bool KoSelectionToggle::eventFilter(QObject *obj, QEvent *event)
-{
-    if ((obj == parent()) && (event->type() == QEvent::MouseMove) && m_leftMouseButtonPressed) {
-        // Don't forward mouse move events to the viewport,
-        // otherwise a rubberband selection will be shown when
-        // clicking on the selection toggle and moving the mouse
-        // above the viewport.
-        return true;
-    }
-
-    return QAbstractButton::eventFilter(obj, event);
-}
-
-void KoSelectionToggle::enterEvent(QEvent *event)
-{
-    QAbstractButton::enterEvent(event);
-
-    // if the mouse cursor is above the selection toggle, display
-    // it immediately without fading timer
-    m_isHovered = true;
-    if (m_fadingTimeLine) {
-        m_fadingTimeLine->stop();
-    }
-    m_fadingValue = 255;
-    setToolTip(isChecked() ? i18nc("@info:tooltip", "Deselect Item") :
-                             i18nc("@info:tooltip", "Select Item"));
-    update();
-}
-
-void KoSelectionToggle::leaveEvent(QEvent *event)
-{
-    QAbstractButton::leaveEvent(event);
-
-    m_isHovered = false;
-    update();
-}
-
-void KoSelectionToggle::mousePressEvent(QMouseEvent *event)
-{
-    QAbstractButton::mousePressEvent(event);
-    m_leftMouseButtonPressed = (event->buttons() & Qt::LeftButton);
-}
-
-void KoSelectionToggle::mouseReleaseEvent(QMouseEvent *event)
-{
-    QAbstractButton::mouseReleaseEvent(event);
-    m_leftMouseButtonPressed = (event->buttons() & Qt::LeftButton);
-}
-
-void KoSelectionToggle::resizeEvent(QResizeEvent *event)
-{
-    QAbstractButton::resizeEvent(event);
-    setIconOverlay(isChecked());
-}
-
-void KoSelectionToggle::paintEvent(QPaintEvent *event)
-{
-    QPainter painter(this);
-    painter.setClipRect(event->rect());
-
-    // draw the icon overlay
-    const QPoint pos(m_margin, m_margin);
-    if (m_isHovered) {
-        KIconEffect *iconEffect = KIconLoader::global()->iconEffect();
-        QPixmap activeIcon = iconEffect->apply(m_icon, KIconLoader::Desktop, KIconLoader::ActiveState);
-        painter.drawPixmap(pos, activeIcon);
-    }
-    else {
-        if (m_fadingValue < 255) {
-            // apply an alpha mask respecting the fading value to the icon
-            QPixmap icon = m_icon;
-            QPixmap alphaMask(icon.width(), icon.height());
-            const QColor color(m_fadingValue, m_fadingValue, m_fadingValue);
-            alphaMask.fill(color);
-            icon.setAlphaChannel(alphaMask);
-            painter.drawPixmap(pos, icon);
-        }
-        else {
-            // no fading is required
-            painter.drawPixmap(pos, m_icon);
-        }
-    }
-
-}
-
-void KoSelectionToggle::setFadingValue(int value)
-{
-    m_fadingValue = value;
-    if (m_fadingValue >= 255) {
-        Q_ASSERT(m_fadingTimeLine);
-        m_fadingTimeLine->stop();
-    }
-    update();
-}
-
-void KoSelectionToggle::setIconOverlay(bool checked)
-{
-    const char *icon = checked ? "list-remove" : "list-add";
-    const int size = qMin(width() - 2 * m_margin, height() - 2 * m_margin);
-    m_icon = KIconLoader::global()->loadIcon(icon,
-                                             KIconLoader::NoGroup,
-                                             size);
-    update();
-}
-
-void KoSelectionToggle::refreshIcon()
-{
-    setIconOverlay(isChecked());
-}
-
-void KoSelectionToggle::startFading()
-{
-    Q_ASSERT(!m_fadingTimeLine);
-
-    const bool animate = KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects;
-    const int duration = animate ? 600 : 1;
-
-    m_fadingTimeLine = new QTimeLine(duration, this);
-    connect(m_fadingTimeLine, SIGNAL(frameChanged(int)),
-            this, SLOT(setFadingValue(int)));
-    m_fadingTimeLine->setFrameRange(0, 255);
-    m_fadingTimeLine->start();
-    m_fadingValue = 0;
-}
-
-void KoSelectionToggle::stopFading()
-{
-    if (m_fadingTimeLine) {
-        m_fadingTimeLine->stop();
-        delete m_fadingTimeLine;
-        m_fadingTimeLine = 0;
-    }
-    m_fadingValue = 0;
-}
-
-#include "KoSelectionToggle.moc"
diff --git a/libs/widgets/KoSelectionToggle.h b/libs/widgets/KoSelectionToggle.h
deleted file mode 100644
index e83409f..0000000
--- a/libs/widgets/KoSelectionToggle.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/* This file is part of the KDE project
-*
-* Copyright (C) 2008 Peter Penz <peter.penz19 at gmail.com>
-* Copyright (C) 2011 Paul Mendez <paulestebanms at gmail.com>
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Library General Public
-* License as published by the Free Software Foundation; either
-* version 2 of the License, or (at your option) any later version.
-*
-* This library 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
-* Library General Public License for more details.
-*
-* You should have received a copy of the GNU Library General Public License
-* along with this library; see the file COPYING.LIB.  If not, write to
-* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-* Boston, MA 02110-1301, USA.
-*/
-
-#ifndef KOSELECTIONTOGGLE_H
-#define KOSELECTIONTOGGLE_H
-
-#include <QAbstractButton>
-#include <QPixmap>
-#include <QModelIndex>
-#include "kowidgets_export.h"
-
-class QTimeLine;
-
-/**
- * @brief Toggle button for changing the selection of an hovered item.
- *
- * The toggle button is visually invisible until it is displayed at least
- * for one second.
- *
- * @see SelectionManager
- */
-class KOWIDGETS_EXPORT KoSelectionToggle : public QAbstractButton
-{
-    Q_OBJECT
-
-public:
-    explicit KoSelectionToggle(QWidget *parent);
-    virtual ~KoSelectionToggle();
-    virtual QSize sizeHint() const;
-
-    /**
-     * Resets the selection toggle so that it is hidden and stays
-     * visually invisible for at least one second after it is shown again.
-     */
-    void reset();
-
-    void setIndex(const QModelIndex &index);
-    QModelIndex index() const;
-
-    /**
-     * Sets the margin around the selection-icon in pixels. Per default
-     * the value is 0.
-     */
-    void setMargin(int margin);
-    int margin() 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 mousePressEvent(QMouseEvent *event);
-    virtual void mouseReleaseEvent(QMouseEvent *event);
-    virtual void resizeEvent(QResizeEvent *event);
-    virtual void paintEvent(QPaintEvent *event);
-
-private slots:
-    /**
-     * Sets the alpha value for the fading animation and is
-     * connected with m_fadingTimeLine.
-     */
-    void setFadingValue(int value);
-
-    void setIconOverlay(bool checked);
-    void refreshIcon();
-
-private:
-    void startFading();
-    void stopFading();
-
-private:
-    bool m_isHovered;
-    bool m_leftMouseButtonPressed;
-    int m_fadingValue;
-    int m_margin;
-    QPixmap m_icon;
-    QTimeLine *m_fadingTimeLine;
-    QModelIndex m_index;
-};
-
-#endif // KOSELECTIONTOGGLE_H
diff --git a/libs/widgets/KoViewItemContextBar.cpp b/libs/widgets/KoViewItemContextBar.cpp
new file mode 100644
index 0000000..7d22e25
--- /dev/null
+++ b/libs/widgets/KoViewItemContextBar.cpp
@@ -0,0 +1,278 @@
+/* This file is part of the KDE project
+*
+* Copyright (C) 2008 Peter Penz <peter.penz19 at gmail.com>
+* Copyright (C) 2011 Paul Mendez <paulestebanms at gmail.com>
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Library General Public
+* License as published by the Free Software Foundation; either
+* version 2 of the License, or (at your option) any later version.
+*
+* This library 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
+* Library General Public License for more details.
+*
+* You should have received a copy of the GNU Library General Public License
+* along with this library; see the file COPYING.LIB.  If not, write to
+* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+* Boston, MA 02110-1301, USA.
+*/
+
+#include "KoViewItemContextBar.h"
+
+//Calligra headers
+#include "KoContextBarButton.h"
+
+//KDE headers
+#include <KGlobalSettings>
+#include <KIconLoader>
+#include <klocale.h>
+
+//Qt Headers
+#include <QAbstractItemView>
+#include <QModelIndex>
+#include <QApplication>
+#include <QHBoxLayout>
+#include <QHoverEvent>
+
+/** Space between the item outer rect and the context bar */
+const int CONTEXTBAR_MARGIN = 4;
+
+KoViewItemContextBar::KoViewItemContextBar(QAbstractItemView *parent)
+    : QObject(parent)
+    , m_view(parent)
+    , m_enabled(true)
+    , m_appliedPointingHandCursor(false)
+{
+    connect(parent, SIGNAL(entered(const QModelIndex&)),
+            this, SLOT(slotEntered(const QModelIndex&)));
+    connect(parent, SIGNAL(viewportEntered()),
+            this, SLOT(slotViewportEntered()));
+
+    m_ContextBar = new QWidget(m_view->viewport());
+    m_ContextBar->hide();
+    m_ToggleSelectionButton = new KoContextBarButton("list-add");
+
+    m_Layout = new QHBoxLayout(m_ContextBar);
+    m_Layout->setMargin(2);
+    m_Layout->setSpacing(2);
+    m_Layout->addWidget(m_ToggleSelectionButton);
+
+    connect(m_ToggleSelectionButton, SIGNAL(clicked()),
+            this, SLOT(setItemSelected()));
+    // Hides context bar if item removed
+    connect(m_view->model(), SIGNAL(rowsRemoved(const QModelIndex&, int, int)),
+            this, SLOT(slotRowsRemoved(const QModelIndex&, int, int)));
+
+    m_ContextBar->installEventFilter(this);
+    m_view->viewport()->installEventFilter(this);
+    m_view->setMouseTracking(true);
+}
+
+KoViewItemContextBar::~KoViewItemContextBar()
+{
+}
+
+bool KoViewItemContextBar::eventFilter(QObject *watched, QEvent *event)
+{
+    if (watched == m_view->viewport()) {
+        switch (event->type()) {
+        case QEvent::Leave:
+            if (m_ContextBar->isVisible()) {
+                m_ContextBar->hide();
+            }
+            break;
+        default:
+            break;
+        }
+    }
+    else if (watched == m_ContextBar) {
+            switch (event->type()) {
+            case QEvent::Enter:
+                QApplication::changeOverrideCursor(Qt::PointingHandCursor);
+                break;
+
+            case QEvent::Leave:
+                QApplication::changeOverrideCursor(Qt::ArrowCursor);
+                break;
+
+            default:
+                break;
+            }
+        }
+    return QObject::eventFilter(watched, event);
+}
+
+void KoViewItemContextBar::slotEntered(const QModelIndex &index)
+{
+    const bool isSelectionCandidate = index.isValid() &&
+            (QApplication::mouseButtons() == Qt::NoButton);
+    restoreCursor();
+    if (isSelectionCandidate && KGlobalSettings::singleClick()) {
+        applyPointingHandCursor();
+    }
+
+    if (!m_ContextBar || !m_enabled) {
+        return;
+    }
+
+    m_ContextBar->hide();
+    if (isSelectionCandidate) {
+        updateHoverUi(index);
+    }
+    else {
+        updateHoverUi(QModelIndex());
+    }
+}
+
+void KoViewItemContextBar::updateHoverUi(const QModelIndex &index)
+{
+    QModelIndex oldIndex = m_IndexUnderCursor;
+    m_IndexUnderCursor = index;
+    m_view->update(oldIndex);
+
+    const bool isSelectionCandidate = index.isValid();
+
+    m_ContextBar->hide();
+    if (isSelectionCandidate) {
+        updateToggleSelectionButton();
+        const QRect rect = m_view->visualRect(m_IndexUnderCursor);
+        showContextBar(rect);
+        m_view->update(m_IndexUnderCursor);
+    } else {
+        m_ContextBar->hide();
+    }
+}
+
+void KoViewItemContextBar::showContextBar(const QRect &rect)
+{
+    // Center bar in FullContextBar mode, left align in
+    // SelectionOnlyContextBar mode
+    const int posX = 0;
+    const int posY = CONTEXTBAR_MARGIN;
+    int numButtons = 0;
+    m_ContextBar->move(rect.topLeft() + QPoint(posX, posY));
+    //Hide buttons if item is too small
+    for (int i=m_contextBarButtons.size()-1; i>=0; --i) {
+        if ((rect.width() - 2*CONTEXTBAR_MARGIN) > ((i+1)*m_ToggleSelectionButton->width())) {
+            m_contextBarButtons.at(i)->setVisible(true);
+            numButtons++;
+            continue;
+        }
+        m_contextBarButtons.at(i)->setVisible(false);
+    }
+    m_ContextBar->adjustSize();
+    if (numButtons > 0) {
+        const int centerX = (rect.width() - m_ContextBar->rect().width()) / 2;
+        m_ContextBar->move(rect.topLeft() + QPoint(centerX, posY));
+    }
+    m_ContextBar->show();
+}
+
+void KoViewItemContextBar::slotViewportEntered()
+{
+    m_ContextBar->hide();
+    restoreCursor();
+}
+
+void KoViewItemContextBar::setItemSelected()
+{
+    emit selectionChanged();
+
+    if (m_IndexUnderCursor.isValid()) {
+        QItemSelectionModel *selModel = m_view->selectionModel();
+        if (!selModel->isSelected(m_IndexUnderCursor)) {
+            selModel->select(m_IndexUnderCursor, QItemSelectionModel::Select);
+        }
+        else {
+            selModel->select(m_IndexUnderCursor, QItemSelectionModel::Deselect);
+        }
+        selModel->setCurrentIndex(m_IndexUnderCursor, QItemSelectionModel::Current);
+    }
+    updateHoverUi(m_IndexUnderCursor);
+}
+
+void KoViewItemContextBar::slotRowsRemoved(const QModelIndex &parent, int start, int end)
+{
+    Q_UNUSED(parent);
+    Q_UNUSED(start);
+    Q_UNUSED(end);
+    if (m_ContextBar) {
+        m_ContextBar->hide();
+    }
+    restoreCursor();
+}
+
+void KoViewItemContextBar::applyPointingHandCursor()
+{
+    if (!m_appliedPointingHandCursor) {
+        QApplication::setOverrideCursor(QCursor(Qt::PointingHandCursor));
+        m_appliedPointingHandCursor = true;
+    }
+}
+
+void KoViewItemContextBar::restoreCursor()
+{
+    if (m_appliedPointingHandCursor) {
+        QApplication::restoreOverrideCursor();
+        m_appliedPointingHandCursor = false;
+    }
+}
+
+void KoViewItemContextBar::updateToggleSelectionButton()
+{
+    m_ToggleSelectionButton->setIcon(SmallIcon(
+            m_view->selectionModel()->isSelected(m_IndexUnderCursor) ? "list-remove" : "list-add"));
+    m_ToggleSelectionButton->setToolTip( m_view->selectionModel()->isSelected(m_IndexUnderCursor) ? i18n("deselect item") : i18n("select item"));
+}
+
+void KoViewItemContextBar::update()
+{
+    // Check if the current index is still valid and then update the context bar
+    if (m_view->model()->index(currentIndex().row(), currentIndex().column(), currentIndex().parent()).isValid()) {
+        updateHoverUi(currentIndex());
+    }
+    else {
+        updateHoverUi(QModelIndex());
+    }
+}
+
+QToolButton * KoViewItemContextBar::addContextButton(QString text, QString iconName)
+{
+    KoContextBarButton *newContexButton = new KoContextBarButton(iconName);
+    newContexButton->setToolTip(text);
+    m_Layout->addWidget(newContexButton);
+    m_contextBarButtons.append(newContexButton);
+    return newContexButton;
+}
+
+QModelIndex KoViewItemContextBar::currentIndex()
+{
+    return m_IndexUnderCursor;
+}
+
+int KoViewItemContextBar::preferredWidth()
+{
+    return ((m_contextBarButtons.count()+1)*m_ToggleSelectionButton->sizeHint().width() + 2*CONTEXTBAR_MARGIN);
+}
+
+void KoViewItemContextBar::reset()
+{
+    if (m_ContextBar) {
+        m_ContextBar->hide();
+    }
+    restoreCursor();
+}
+
+void KoViewItemContextBar::enableContextBar()
+{
+    m_enabled = true;
+}
+
+void KoViewItemContextBar::disableContextBar()
+{
+    m_enabled = false;
+}
+
+#include "KoViewItemContextBar.moc"
diff --git a/libs/widgets/KoSelectionManager.h b/libs/widgets/KoViewItemContextBar.h
similarity index 51%
rename from libs/widgets/KoSelectionManager.h
rename to libs/widgets/KoViewItemContextBar.h
index a2db231..c8a7017 100644
--- a/libs/widgets/KoSelectionManager.h
+++ b/libs/widgets/KoViewItemContextBar.h
@@ -19,56 +19,82 @@
 * Boston, MA 02110-1301, USA.
 */
 
-#ifndef KOSELECTIONMANAGER_H
-#define KOSELECTIONMANAGER_H
+#ifndef KOVIEWITEMCONTEXTBAR_H
+#define KOVIEWITEMCONTEXTBAR_H
 
 #include <QObject>
 #include "kowidgets_export.h"
+#include <QModelIndex>
 
 class QAbstractItemView;
-class QModelIndex;
 class QItemSelection;
-class KoSelectionToggle;
+class QToolButton;
+class QHBoxLayout;
+class QRect;
 
 /**
- * @brief Allows to select and deselect items for item views.
+ * @brief Add context buttons to items of QAbstractView subclasses
  *
  * Whenever an item is hovered by the mouse, a toggle button is shown
- * which allows to select/deselect the current item.
+ * which allows to select/deselect the current item, other buttons for
+ * custom actions could be added using addContextButton method.
  */
-class KOWIDGETS_EXPORT KoSelectionManager : public QObject
+class KOWIDGETS_EXPORT KoViewItemContextBar : public QObject
 {
     Q_OBJECT
 
 public:
-    KoSelectionManager(QAbstractItemView *parent);
-    virtual ~KoSelectionManager();
+    KoViewItemContextBar(QAbstractItemView *parent);
+    virtual ~KoViewItemContextBar();
     virtual bool eventFilter(QObject *watched, QEvent *event);
 
-public slots:
     /**
-     * Resets the selection manager so that the toggle button gets
-     * invisible.
+     * Add a button to the context bar
+     * @param text to be used for button tool tip
+     * @param iconName or name of the icon displayed on the button
+     * @return a QToolButton, so it could be connected to a slot.
      */
-    void reset();
+    QToolButton *addContextButton(QString text, QString iconName);
+    //Returns the index of the item under the mouse cursor
+    QModelIndex currentIndex();
+
+    int preferredWidth();
 
 signals:
     /** Is emitted if the selection has been changed by the toggle button. */
     void selectionChanged();
 
+public slots:
+    /** Hide context bar */
+    void reset();
+    void enableContextBar();
+    void disableContextBar();
+
 private slots:
     void slotEntered(const QModelIndex &index);
     void slotViewportEntered();
-    void setItemSelected(bool selected);
+    void setItemSelected();
+    /** Hide context bar if the selectem item has been removed */
     void slotRowsRemoved(const QModelIndex &parent, int start, int end);
-    void slotSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
+    /** Updates contex bar buttons state*/
+    void updateHoverUi(const QModelIndex& index);
+    void showContextBar(const QRect &rect);
+    /** Updates Selection Button state*/
+    void updateToggleSelectionButton();
+    /** Update Bar */
+    void update();
 
 private:
     void applyPointingHandCursor();
     void restoreCursor();
     QAbstractItemView *m_view;
-    KoSelectionToggle *m_toggle;
-    bool m_connected;
+    bool m_enabled;
     bool m_appliedPointingHandCursor;
+    QModelIndex m_IndexUnderCursor;
+    QWidget *m_ContextBar;
+    QToolButton *m_ToggleSelectionButton;
+    QHBoxLayout *m_Layout;
+    QList <QToolButton*> m_contextBarButtons;
 };
-#endif // KOSELECTIONMANAGER_H
+
+#endif // KOVIEWITEMCONTEXTBAR_H
diff --git a/stage/part/KPrSlidesManagerView.cpp b/stage/part/KPrSlidesManagerView.cpp
index 1026dd2..4f01561 100644
--- a/stage/part/KPrSlidesManagerView.cpp
+++ b/stage/part/KPrSlidesManagerView.cpp
@@ -192,13 +192,12 @@ void KPrSlidesManagerView::selectionChanged(const QItemSelection &selected, cons
 
 QRect KPrSlidesManagerView::itemSize() const
 {
-    return m_itemSize;
-}
-
-void KPrSlidesManagerView::setItemSize(QRect size)
-{
-    m_itemSize = size;
-    setSpacing(m_itemSize.width() / 10);
+    if (model()) {
+        return (this->visualRect(model()->index(0,0,QModelIndex())));
+    }
+    else {
+        return QRect();
+    }
 }
 
 void KPrSlidesManagerView::setDraggingFlag(bool flag)
diff --git a/stage/part/KPrSlidesManagerView.h b/stage/part/KPrSlidesManagerView.h
index 30a6c4d..0a7de48 100644
--- a/stage/part/KPrSlidesManagerView.h
+++ b/stage/part/KPrSlidesManagerView.h
@@ -67,13 +67,6 @@ public:
     void focusInEvent(QFocusEvent *event);
 
     /**
-     * Setter of the size with a rect
-     *
-     * @param size which is a QRect
-     */
-    void setItemSize(QRect size);
-
-    /**
      * Creates a pixmap the contains the all icons of the items
      * that are dragged.
      */
@@ -125,7 +118,6 @@ signals:
     void zoomOut();
 
 private:
-
     /**
      * The rect of an items, essentialy used to have the size of the full icon
      *
diff --git a/stage/part/KPrSlidesSorterDocumentModel.cpp b/stage/part/KPrSlidesSorterDocumentModel.cpp
index 74e7e7b..084e59a 100644
--- a/stage/part/KPrSlidesSorterDocumentModel.cpp
+++ b/stage/part/KPrSlidesSorterDocumentModel.cpp
@@ -378,6 +378,7 @@ bool KPrSlidesSorterDocumentModel::removeSlides(const QList<KoPAPageBase *> &sli
         KPrDocument *doc = static_cast<KPrDocument *>(m_document);
         KUndo2Command *cmd = new KPrDeleteSlidesCommand(doc, slides);
         if (cmd) {
+            removeRows(m_document->pageIndex(slides.first()), slides.count(), QModelIndex());
             m_document->addCommand(cmd);
             return true;
         }
diff --git a/stage/part/KPrViewModeSlidesSorter.cpp b/stage/part/KPrViewModeSlidesSorter.cpp
index 16d0bc0..29d22b3 100644
--- a/stage/part/KPrViewModeSlidesSorter.cpp
+++ b/stage/part/KPrViewModeSlidesSorter.cpp
@@ -52,7 +52,7 @@
 #include <KoCanvasController.h>
 #include <KoCopyController.h>
 #include <KoCutController.h>
-#include <KoSelectionManager.h>
+#include <KoViewItemContextBar.h>
 
 //KDE Headers
 #include <klocale.h>
@@ -64,6 +64,8 @@
 #include <KMessageBox>
 #include <KActionCollection>
 
+const int DEFAULT_ICON_SIZE = 200;
+
 KPrViewModeSlidesSorter::KPrViewModeSlidesSorter(KoPAView *view, KoPACanvasBase *canvas)
     : KoPAViewMode(view, canvas)
     , m_slidesSorterView(new KPrSlidesManagerView())
@@ -144,6 +146,7 @@ KPrViewModeSlidesSorter::KPrViewModeSlidesSorter(KoPAView *view, KoPACanvasBase
     m_customSlideShowView->setSelectionBehavior(QAbstractItemView::SelectRows);
     m_customSlideShowView->setSelectionMode(QAbstractItemView::ExtendedSelection);
     m_customSlideShowView->setDragDropMode(QAbstractItemView::InternalMove);
+    m_customSlideShowView->setSpacing(10);
 
     //Setup slides sorter view
     m_slidesSorterModel->setDocument(m_view->kopaDocument());
@@ -151,6 +154,7 @@ KPrViewModeSlidesSorter::KPrViewModeSlidesSorter(KoPAView *view, KoPACanvasBase
     m_slidesSorterView->setSelectionBehavior(QAbstractItemView::SelectRows);
     m_slidesSorterView->setSelectionMode(QAbstractItemView::ExtendedSelection);
     m_slidesSorterView->setDragDropMode(QAbstractItemView::InternalMove);
+    m_slidesSorterView->setSpacing(10);
 
     //setup signals
     connect(m_slidesSorterView, SIGNAL(requestContextMenu(QContextMenuEvent*)), this, SLOT(slidesSorterContextMenu(QContextMenuEvent*)));
@@ -178,8 +182,17 @@ KPrViewModeSlidesSorter::KPrViewModeSlidesSorter(KoPAView *view, KoPACanvasBase
     connect(m_customSlideShowView, SIGNAL(focusGot()), SLOT(manageAddRemoveSlidesButtons()));
 
     //install selection manager for Slides Sorter View and Custom Shows View
-    new KoSelectionManager(m_slidesSorterView);
-    new KoSelectionManager(m_customSlideShowView);
+    m_slidesSorterItemContextBar = new KoViewItemContextBar(m_slidesSorterView);
+    new KoViewItemContextBar(m_customSlideShowView);
+    QToolButton *duplicateButton = m_slidesSorterItemContextBar->addContextButton(i18n("Duplicate Slide"),QString("edit-copy"));
+    QToolButton *deleteButton = m_slidesSorterItemContextBar->addContextButton(i18n("Delete Slide"),QString("edit-delete"));
+    QToolButton *startPresentation = m_slidesSorterItemContextBar->addContextButton(i18n("Start Slideshow"),QString("view-presentation"));
+    connect(view->kopaDocument(), SIGNAL(pageRemoved(KoPAPageBase*)), m_slidesSorterItemContextBar, SLOT(update()));
+
+    //setup signals for item context bar buttons
+    connect(duplicateButton, SIGNAL(clicked()), this, SLOT(contextBarDuplicateSlide()));
+    connect(deleteButton, SIGNAL(clicked()), this, SLOT(contextBarDeleteSlide()));
+    connect(startPresentation, SIGNAL(clicked()), this, SLOT(contextBarStartSlideshow()));
 
     //install delegate for Slides Sorter View
     KPrSlidesSorterItemDelegate *slidesSorterDelegate = new KPrSlidesSorterItemDelegate(m_slidesSorterView);
@@ -253,7 +266,6 @@ void KPrViewModeSlidesSorter::wheelEvent(QWheelEvent *event, const QPointF &poin
 void KPrViewModeSlidesSorter::activate(KoPAViewMode *previousViewMode)
 {
     Q_UNUSED(previousViewMode);
-    populate();
     KoPAView *view = dynamic_cast<KoPAView *>(m_view);
     if (view) {
         view->replaceCentralWidget(m_centralWidget);
@@ -340,16 +352,6 @@ void KPrViewModeSlidesSorter::removeShape( KoShape *shape )
     Q_UNUSED(shape);
 }
 
-void KPrViewModeSlidesSorter::populate()
-{
-    //Init m_slidesSorter view
-    QModelIndex item = m_slidesSorterModel->index(0, 0, QModelIndex());
-    m_slidesSorterView->setItemSize(m_slidesSorterView->visualRect(item));
-
-    //Init m_customSlidesShowsView
-    m_customSlideShowView->setItemSize(m_slidesSorterView->visualRect(item));
-}
-
 QSize KPrViewModeSlidesSorter::iconSize() const
 {
     return m_iconSize;
@@ -482,16 +484,17 @@ void KPrViewModeSlidesSorter::updateZoom(KoZoomMode::Mode mode, qreal zoom)
     Q_UNUSED(mode);
     //at zoom 100%, iconSize is set in 200 x 200
     //KPrSlidesSorterDocumentModel uses iconSize function in decorate Role.
-    setIconSize(QSize(qRound(zoom*200),qRound(zoom*200)));
+    //Check if is enough room for context bar
+    int newIconSize = (zoom*DEFAULT_ICON_SIZE > m_slidesSorterItemContextBar->preferredWidth()) ?
+                qRound(zoom*DEFAULT_ICON_SIZE) : m_slidesSorterItemContextBar->preferredWidth();
+    //Check if slide is not too big
+    newIconSize = (newIconSize < qMin(m_centralWidget->size().height(), m_centralWidget->size().width())) ?
+                newIconSize : qMin(m_centralWidget->size().height(), m_centralWidget->size().width());
+
+    setIconSize(QSize(newIconSize, newIconSize));
     m_slidesSorterView->setIconSize(iconSize());
     m_customSlideShowModel->setIconSize(iconSize());
     m_customSlideShowView->setIconSize(iconSize());
-
-    //update item size
-    QModelIndex item = m_slidesSorterModel->index(0, 0, QModelIndex());
-    m_slidesSorterView->setItemSize(m_slidesSorterView->visualRect(item));
-    m_customSlideShowView->setItemSize(m_slidesSorterView->visualRect(item));
-
     setZoom(qRound(zoom * 100.));
 }
 
@@ -728,3 +731,38 @@ void KPrViewModeSlidesSorter::setActiveCustomSlideShow(int index)
 
     connect(m_customSlideShowsList, SIGNAL(currentIndexChanged(int)), this, SLOT(customShowChanged(int)));
 }
+
+void KPrViewModeSlidesSorter::contextBarDuplicateSlide()
+{
+    QList<KoPAPageBase *> slides;
+    KoPAPageBase *page = m_view->kopaDocument()->pageByIndex(m_slidesSorterItemContextBar->currentIndex().row (), false);
+    if (page) {
+        slides.append(page);
+        updateActivePage(page);
+        m_slidesSorterModel->copySlides(slides);
+        editPaste();
+    }
+}
+
+void KPrViewModeSlidesSorter::contextBarDeleteSlide()
+{
+    QList<KoPAPageBase *> slides;
+    if ((m_slidesSorterItemContextBar->currentIndex().row() >= 0) &&
+            (m_slidesSorterItemContextBar->currentIndex().row() < m_slidesSorterModel->rowCount(QModelIndex()))) {
+        KoPAPageBase *page = m_view->kopaDocument()->pageByIndex(m_slidesSorterItemContextBar->currentIndex().row(), false);
+        if (page) {
+            slides.append(page);
+            m_slidesSorterModel->removeSlides(slides);
+        }
+    }
+}
+
+void KPrViewModeSlidesSorter::contextBarStartSlideshow()
+{
+    KoPAPageBase *page = m_view->kopaDocument()->pageByIndex(m_slidesSorterItemContextBar->currentIndex().row (), false);
+    updateActivePage(page);
+    KPrView *kPrview = dynamic_cast<KPrView *>(m_view);
+    if (kPrview) {
+       kPrview->startPresentation();
+    }
+}
diff --git a/stage/part/KPrViewModeSlidesSorter.h b/stage/part/KPrViewModeSlidesSorter.h
index 705fd2a..73014f8 100644
--- a/stage/part/KPrViewModeSlidesSorter.h
+++ b/stage/part/KPrViewModeSlidesSorter.h
@@ -28,6 +28,7 @@
 class KoPAView;
 class KoPACanvas;
 class KoPAPageBase;
+class KoViewItemContextBar;
 class KPrSlidesSorterDocumentModel;
 class KPrSlidesManagerView;
 class KPrSelectionManager;
@@ -99,11 +100,6 @@ public:
 protected:
 
     /**
-     * Fills the editor with presentation slides and ordored them in the KPrSlidesSorter
-     */
-    void populate();
-
-    /**
      * Setter of the icon size
      *
      * @param size which is a QSize
@@ -148,6 +144,7 @@ private:
     QToolButton *m_buttonAddSlideToCurrentShow;
     QToolButton *m_buttonDelSlideFromCurrentShow;
     QComboBox *m_customSlideShowsList;
+    KoViewItemContextBar *m_slidesSorterItemContextBar;
 
 private slots:
     /** Changes the view active page to match the slides sorter current index*/
@@ -165,6 +162,11 @@ private slots:
     /** add a new slide after the current active page*/
     void addSlide();
 
+    /** Item context bar actions */
+    void contextBarDuplicateSlide();
+    void contextBarDeleteSlide();
+    void contextBarStartSlideshow();
+
     /** Rename current slide on Slides Sorter View */
     void renameCurrentSlide();
 


More information about the kde-doc-english mailing list