]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/selectionmanager.cpp
Increase version number to 1.5
[dolphin.git] / src / selectionmanager.cpp
index bdb4c5368f20c6a2aed3fbfb9073b8ee3d566e8a..0d3efae09b6aaa081d1bfd8f325cd29cb947f29a 100644 (file)
 #include <QAbstractButton>
 #include <QAbstractItemView>
 #include <QAbstractProxyModel>
+#include <QApplication>
 #include <QModelIndex>
 #include <QPainter>
 #include <QPaintEvent>
 #include <QRect>
+#include <QTimeLine>
 
 SelectionManager::SelectionManager(QAbstractItemView* parent) :
     QObject(parent),
     m_view(parent),
-    m_button(0),
-    m_item()
+    m_toggle(0),
+    m_connected(false)
 {
     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)),
+    m_toggle = new SelectionToggle(m_view->viewport());
+    m_toggle->setCheckable(true);
+    m_toggle->hide();
+    connect(m_toggle, SIGNAL(clicked(bool)),
             this, SLOT(setItemSelected(bool)));
 }
 
@@ -55,59 +57,84 @@ SelectionManager::~SelectionManager()
 
 void SelectionManager::reset()
 {
-    m_button->hide();
-    m_item = KFileItem();
+    m_toggle->reset();
 }
 
 void SelectionManager::slotEntered(const QModelIndex& index)
 {
-    m_button->hide();
-    if (index.isValid() && (index.column() == DolphinModel::Name)) {
-        m_item = itemForIndex(index);
+    m_toggle->hide();
+    const bool showToggle = index.isValid() &&
+                            (index.column() == DolphinModel::Name) &&
+                            (QApplication::mouseButtons() == Qt::NoButton);
+    if (showToggle) {
+        m_toggle->setUrl(urlForIndex(index));
+
+        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;
+        }
 
-        connect(m_view->model(), SIGNAL(rowsRemoved(const QModelIndex&, int, int)),
-                this, SLOT(slotRowsRemoved(const QModelIndex&, int, int)));
+        // increase the size of the toggle for large items
+        const int height = m_view->iconSize().height();
+        if (height >= KIconLoader::SizeEnormous) {
+            m_toggle->resize(KIconLoader::SizeMedium, KIconLoader::SizeMedium);
+        } else if (height >= KIconLoader::SizeLarge) {
+            m_toggle->resize(KIconLoader::SizeSmallMedium, KIconLoader::SizeSmallMedium);
+        } else {
+            m_toggle->resize(KIconLoader::SizeSmall, KIconLoader::SizeSmall);
+        }
 
         const QRect rect = m_view->visualRect(index);
-        const int gap = 2;
-        const int x = rect.right() - m_button->width() - gap;
+        int x = rect.left();
         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;
+        if (height < KIconLoader::SizeSmallMedium) {
+            // The height is nearly equal to the smallest toggle height.
+            // Assure that the toggle is vertically centered instead
+            // of aligned on the top and gets more horizontal gap.
+            x += 2;
+            y += (rect.height() - m_toggle->height()) / 2;
         }
-
-        m_button->move(QPoint(x, y));
+        m_toggle->move(QPoint(x, y));
 
         QItemSelectionModel* selModel = m_view->selectionModel();
-        m_button->setChecked(selModel->isSelected(index));
-        m_button->show();
+        m_toggle->setChecked(selModel->isSelected(index));
+        m_toggle->show();
     } else {
-        m_item = KFileItem();
+        m_toggle->setUrl(KUrl());
         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;
     }
 }
 
 void SelectionManager::slotViewportEntered()
 {
-    m_button->hide();
+    m_toggle->hide();
 }
 
 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);
+    if (!m_toggle->url().isEmpty()) {
+        const QModelIndex index = indexForUrl(m_toggle->url());
+        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);
         }
     }
 }
@@ -117,22 +144,42 @@ void SelectionManager::slotRowsRemoved(const QModelIndex& parent, int start, int
     Q_UNUSED(parent);
     Q_UNUSED(start);
     Q_UNUSED(end);
-    m_button->hide();
+    m_toggle->hide();
+}
+
+void SelectionManager::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->url().isEmpty()) {
+        const QModelIndex index = indexForUrl(m_toggle->url());
+        if (index.isValid()) {
+            if (selected.contains(index)) {
+                m_toggle->setChecked(true);
+            }
+
+            if (deselected.contains(index)) {
+                m_toggle->setChecked(false);
+            }
+        }
+    }
 }
 
-KFileItem SelectionManager::itemForIndex(const QModelIndex& index) const
+KUrl SelectionManager::urlForIndex(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);
+    return dirModel->itemForIndex(dirIndex).url();
 }
 
-const QModelIndex SelectionManager::indexForItem(const KFileItem& item) const
+const QModelIndex SelectionManager::indexForUrl(const KUrl& url) const
 {
     QAbstractProxyModel* proxyModel = static_cast<QAbstractProxyModel*>(m_view->model());
     KDirModel* dirModel = static_cast<KDirModel*>(proxyModel->sourceModel());
-    const QModelIndex dirIndex = dirModel->indexForItem(item);
+    const QModelIndex dirIndex = dirModel->indexForUrl(url);
     return proxyModel->mapFromSource(dirIndex);
 }