diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/kitemviews/kfileitemlistview.cpp | 5 | ||||
| -rw-r--r-- | src/kitemviews/kfileitemlistview.h | 3 | ||||
| -rw-r--r-- | src/kitemviews/kfileitemmodel.h | 7 | ||||
| -rw-r--r-- | src/kitemviews/kitemlistcontroller.cpp | 60 | ||||
| -rw-r--r-- | src/kitemviews/kitemlistview.cpp | 61 | ||||
| -rw-r--r-- | src/kitemviews/kitemlistview.h | 16 | ||||
| -rw-r--r-- | src/kitemviews/kitemmodelbase.cpp | 19 | ||||
| -rw-r--r-- | src/kitemviews/kitemmodelbase.h | 29 | ||||
| -rw-r--r-- | src/panels/folders/folderspanel.cpp | 132 | ||||
| -rw-r--r-- | src/panels/folders/folderspanel.h | 48 | ||||
| -rw-r--r-- | src/panels/folders/ktreeview_p.h | 46 | ||||
| -rw-r--r-- | src/panels/folders/treeviewcontextmenu.cpp | 52 | ||||
| -rw-r--r-- | src/panels/folders/treeviewcontextmenu.h | 16 | ||||
| -rw-r--r-- | src/views/dolphinview.cpp | 12 | ||||
| -rw-r--r-- | src/views/dolphinview.h | 1 | ||||
| -rw-r--r-- | src/views/dolphinviewautoscroller.cpp | 223 | ||||
| -rw-r--r-- | src/views/dolphinviewautoscroller.h | 79 |
18 files changed, 291 insertions, 519 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a10f6b448..af82e74fe 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -53,7 +53,6 @@ set(dolphinprivate_LIB_SRCS views/dolphinremoteencoding.cpp views/dolphinview.cpp views/dolphinviewactionhandler.cpp - views/dolphinviewautoscroller.cpp views/draganddrophelper.cpp views/renamedialog.cpp views/tooltips/filemetadatatooltip.cpp diff --git a/src/kitemviews/kfileitemlistview.cpp b/src/kitemviews/kfileitemlistview.cpp index b0ffd3c20..d7dd5cf67 100644 --- a/src/kitemviews/kfileitemlistview.cpp +++ b/src/kitemviews/kfileitemlistview.cpp @@ -222,6 +222,11 @@ QHash<QByteArray, QSizeF> KFileItemListView::visibleRolesSizes(const KItemRangeL return sizes; } +bool KFileItemListView::supportsItemExpanding() const +{ + return m_itemLayout == DetailsLayout; +} + QPixmap KFileItemListView::createDragPixmap(const QSet<int>& indexes) const { if (!model()) { diff --git a/src/kitemviews/kfileitemlistview.h b/src/kitemviews/kfileitemlistview.h index d90d8ecf9..a41d091b7 100644 --- a/src/kitemviews/kfileitemlistview.h +++ b/src/kitemviews/kfileitemlistview.h @@ -64,6 +64,9 @@ public: virtual QHash<QByteArray, QSizeF> visibleRolesSizes(const KItemRangeList& itemRanges) const; /** @reimp */ + virtual bool supportsItemExpanding() const; + + /** @reimp */ virtual QPixmap createDragPixmap(const QSet<int>& indexes) const; protected: diff --git a/src/kitemviews/kfileitemmodel.h b/src/kitemviews/kfileitemmodel.h index 17524b82a..8cbcb1216 100644 --- a/src/kitemviews/kfileitemmodel.h +++ b/src/kitemviews/kfileitemmodel.h @@ -116,9 +116,10 @@ public: void setRoles(const QSet<QByteArray>& roles); QSet<QByteArray> roles() const; - bool setExpanded(int index, bool expanded); - bool isExpanded(int index) const; - bool isExpandable(int index) const; + virtual bool setExpanded(int index, bool expanded); + virtual bool isExpanded(int index) const; + virtual bool isExpandable(int index) const; + QSet<KUrl> expandedUrls() const; /** diff --git a/src/kitemviews/kitemlistcontroller.cpp b/src/kitemviews/kitemlistcontroller.cpp index b24e6df14..60bfef518 100644 --- a/src/kitemviews/kitemlistcontroller.cpp +++ b/src/kitemviews/kitemlistcontroller.cpp @@ -135,17 +135,31 @@ bool KItemListController::hideEvent(QHideEvent* event) bool KItemListController::keyPressEvent(QKeyEvent* event) { + int index = m_selectionManager->currentItem(); + int key = event->key(); + + // Handle the expanding/collapsing of items + if (m_view->supportsItemExpanding() && m_model->isExpandable(index)) { + if (key == Qt::Key_Right) { + if (m_model->setExpanded(index, true)) { + return true; + } + } else if (key == Qt::Key_Left) { + if (m_model->setExpanded(index, false)) { + return true; + } + } + } + const bool shiftPressed = event->modifiers() & Qt::ShiftModifier; const bool controlPressed = event->modifiers() & Qt::ControlModifier; const bool shiftOrControlPressed = shiftPressed || controlPressed; - int index = m_selectionManager->currentItem(); const int itemCount = m_model->count(); const int itemsPerRow = m_view->itemsPerOffset(); // For horizontal scroll orientation, transform // the arrow keys to simplify the event handling. - int key = event->key(); if (m_view->scrollOrientation() == Qt::Horizontal) { switch (key) { case Qt::Key_Up: key = Qt::Key_Left; break; @@ -156,6 +170,7 @@ bool KItemListController::keyPressEvent(QKeyEvent* event) } } + switch (key) { case Qt::Key_Home: index = 0; @@ -234,6 +249,8 @@ bool KItemListController::keyPressEvent(QKeyEvent* event) if (!shiftPressed) { m_selectionManager->beginAnchoredSelection(index); } + + m_view->scrollToItem(index); } return true; } @@ -348,25 +365,27 @@ bool KItemListController::mousePressEvent(QGraphicsSceneMouseEvent* event, const return true; } - KItemListRubberBand* rubberBand = m_view->rubberBand(); - QPointF startPos = m_pressedMousePos; - if (m_view->scrollOrientation() == Qt::Vertical) { - startPos.ry() += m_view->scrollOffset(); - if (m_view->itemSize().width() < 0) { - // Use a special rubberband for views that have only one column and - // expand the rubberband to use the whole width of the view. - startPos.setX(0); + if (m_selectionBehavior == MultiSelection) { + QPointF startPos = m_pressedMousePos; + if (m_view->scrollOrientation() == Qt::Vertical) { + startPos.ry() += m_view->scrollOffset(); + if (m_view->itemSize().width() < 0) { + // Use a special rubberband for views that have only one column and + // expand the rubberband to use the whole width of the view. + startPos.setX(0); + } + } else { + startPos.rx() += m_view->scrollOffset(); } - } else { - startPos.rx() += m_view->scrollOffset(); - } - m_oldSelection = m_selectionManager->selectedItems(); - rubberBand->setStartPosition(startPos); - rubberBand->setEndPosition(startPos); - rubberBand->setActive(true); - connect(rubberBand, SIGNAL(endPositionChanged(QPointF,QPointF)), this, SLOT(slotRubberBandChanged())); - m_view->setAutoScroll(true); + m_oldSelection = m_selectionManager->selectedItems(); + KItemListRubberBand* rubberBand = m_view->rubberBand(); + rubberBand->setStartPosition(startPos); + rubberBand->setEndPosition(startPos); + rubberBand->setActive(true); + connect(rubberBand, SIGNAL(endPositionChanged(QPointF,QPointF)), this, SLOT(slotRubberBandChanged())); + m_view->setAutoScroll(true); + } return false; } @@ -461,6 +480,9 @@ bool KItemListController::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, con if (event->button() & Qt::LeftButton) { bool emitItemActivated = true; if (m_view->isAboveExpansionToggle(index, pos)) { + const bool expanded = m_model->isExpanded(index); + m_model->setExpanded(index, !expanded); + emit itemExpansionToggleClicked(index); emitItemActivated = false; } else if (shiftOrControlPressed) { diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp index 389069ce3..c4c1e3167 100644 --- a/src/kitemviews/kitemlistview.cpp +++ b/src/kitemviews/kitemlistview.cpp @@ -427,11 +427,45 @@ QHash<QByteArray, QSizeF> KItemListView::visibleRolesSizes(const KItemRangeList& return QHash<QByteArray, QSizeF>(); } +bool KItemListView::supportsItemExpanding() const +{ + return false; +} + QRectF KItemListView::itemRect(int index) const { return m_layouter->itemRect(index); } +void KItemListView::scrollToItem(int index) +{ + const QRectF viewGeometry = geometry(); + const QRectF currentRect = itemRect(index); + + if (!viewGeometry.contains(currentRect)) { + qreal newOffset = scrollOffset(); + if (currentRect.top() < viewGeometry.top()) { + Q_ASSERT(scrollOrientation() == Qt::Vertical); + newOffset += currentRect.top() - viewGeometry.top(); + } else if ((currentRect.bottom() > viewGeometry.bottom())) { + Q_ASSERT(scrollOrientation() == Qt::Vertical); + newOffset += currentRect.bottom() - viewGeometry.bottom(); + } else if (currentRect.left() < viewGeometry.left()) { + if (scrollOrientation() == Qt::Horizontal) { + newOffset += currentRect.left() - viewGeometry.left(); + } + } else if ((currentRect.right() > viewGeometry.right())) { + if (scrollOrientation() == Qt::Horizontal) { + newOffset += currentRect.right() - viewGeometry.right(); + } + } + + if (newOffset != scrollOffset()) { + emit scrollTo(newOffset); + } + } +} + int KItemListView::itemsPerOffset() const { return m_layouter->itemsPerOffset(); @@ -950,33 +984,6 @@ void KItemListView::slotCurrentChanged(int current, int previous) Q_ASSERT(!currentWidget->isCurrent()); currentWidget->setCurrent(true); } - - const QRectF viewGeometry = geometry(); - const QRectF currentRect = itemRect(current); - - if (!viewGeometry.contains(currentRect)) { - // Make sure that the new current item is fully visible in the view. - qreal newOffset = scrollOffset(); - if (currentRect.top() < viewGeometry.top()) { - Q_ASSERT(scrollOrientation() == Qt::Vertical); - newOffset += currentRect.top() - viewGeometry.top(); - } else if ((currentRect.bottom() > viewGeometry.bottom())) { - Q_ASSERT(scrollOrientation() == Qt::Vertical); - newOffset += currentRect.bottom() - viewGeometry.bottom(); - } else if (currentRect.left() < viewGeometry.left()) { - if (scrollOrientation() == Qt::Horizontal) { - newOffset += currentRect.left() - viewGeometry.left(); - } - } else if ((currentRect.right() > viewGeometry.right())) { - if (scrollOrientation() == Qt::Horizontal) { - newOffset += currentRect.right() - viewGeometry.right(); - } - } - - if (newOffset != scrollOffset()) { - emit scrollTo(newOffset); - } - } } void KItemListView::slotSelectionChanged(const QSet<int>& current, const QSet<int>& previous) diff --git a/src/kitemviews/kitemlistview.h b/src/kitemviews/kitemlistview.h index 481dd90f6..1da0cd7d2 100644 --- a/src/kitemviews/kitemlistview.h +++ b/src/kitemviews/kitemlistview.h @@ -169,12 +169,28 @@ public: virtual QHash<QByteArray, QSizeF> visibleRolesSizes(const KItemRangeList& itemRanges) const; /** + * @return True if the view supports the expanding of items. Per default false + * is returned. If expanding of items is supported, the methods + * KItemModelBase::setExpanded(), KItemModelBase::isExpanded() and + * KItemModelBase::isExpandable() must be reimplemented. The view-implementation + * has to take care itself how to visually represent the expanded items provided + * by the model. + */ + virtual bool supportsItemExpanding() const; + + /** * @return The rectangle of the item relative to the top/left of * the currently visible area (see KItemListView::offset()). */ QRectF itemRect(int index) const; /** + * Scrolls to the item with the index \a index so that the item + * will be fully visible. + */ + void scrollToItem(int index); + + /** * @return The number of items that can be shown in parallel for one offset. * Assuming the scrolldirection is vertical then a value of 4 means * that 4 columns for items are available. Assuming the scrolldirection diff --git a/src/kitemviews/kitemmodelbase.cpp b/src/kitemviews/kitemmodelbase.cpp index 3e6114027..e2b86d8a0 100644 --- a/src/kitemviews/kitemmodelbase.cpp +++ b/src/kitemviews/kitemmodelbase.cpp @@ -109,6 +109,25 @@ QList<QPair<int, QVariant> > KItemModelBase::groups() const return QList<QPair<int, QVariant> >(); } +bool KItemModelBase::setExpanded(int index, bool expanded) +{ + Q_UNUSED(index); + Q_UNUSED(expanded); + return false; +} + +bool KItemModelBase::isExpanded(int index) const +{ + Q_UNUSED(index); + return false; +} + +bool KItemModelBase::isExpandable(int index) const +{ + Q_UNUSED(index); + return false; +} + QMimeData* KItemModelBase::createMimeData(const QSet<int>& indexes) const { Q_UNUSED(indexes); diff --git a/src/kitemviews/kitemmodelbase.h b/src/kitemviews/kitemmodelbase.h index edca15bd1..1dffaf8cf 100644 --- a/src/kitemviews/kitemmodelbase.h +++ b/src/kitemviews/kitemmodelbase.h @@ -53,6 +53,9 @@ typedef QList<KItemRange> KItemRangeList; * One item consists of a variable number of role/value-pairs. * * A model can optionally provide sorting- and grouping-capabilities. + * + * Also optionally it is possible to provide a tree of items by implementing the methods + * setExpanded(), isExpanded() and isExpandable(). */ class LIBDOLPHINPRIVATE_EXPORT KItemModelBase : public QObject { @@ -117,6 +120,32 @@ public: virtual QList<QPair<int, QVariant> > groups() const; /** + * Expands the item with the index \a index if \a expanded is true. + * If \a expanded is false the item will be collapsed. + * + * Per default no expanding of items is implemented. When implementing + * this method it is mandatory to overwrite KItemModelBase::isExpandable() + * and KItemListView::supportsExpandableItems() to return true. + * + * @return True if the operation has been successful. + */ + virtual bool setExpanded(int index, bool expanded); + + /** + * @return True if the item with the index \a index is expanded. + * Per default no expanding of items is implemented. When implementing + * this method it is mandatory to overwrite KItemModelBase::isExpandable() + * and KItemListView::supportsExpandableItems() to return true. + */ + virtual bool isExpanded(int index) const; + + /** + * @return True if expanding and collapsing of the item with the index \a index + * is supported. Per default false is returned. + */ + virtual bool isExpandable(int index) const; + + /** * @return MIME-data for the items given by \a indexes. The default implementation * returns 0. The ownership of the returned instance is in the hand of the * caller of this method. diff --git a/src/panels/folders/folderspanel.cpp b/src/panels/folders/folderspanel.cpp index cf458e508..484d8c2ed 100644 --- a/src/panels/folders/folderspanel.cpp +++ b/src/panels/folders/folderspanel.cpp @@ -37,6 +37,7 @@ #include <QApplication> #include <QBoxLayout> #include <QGraphicsView> +#include <QPropertyAnimation> #include <QTimer> #include <views/renamedialog.h> @@ -45,11 +46,9 @@ FoldersPanel::FoldersPanel(QWidget* parent) : Panel(parent), - m_setLeafVisible(false), - m_mouseButtons(Qt::NoButton), + m_updateCurrentItem(false), m_dirLister(0), - m_controller(0), - m_leafDir() + m_controller(0) { setLayoutDirection(Qt::LeftToRight); } @@ -121,7 +120,6 @@ bool FoldersPanel::urlChanged() } if (m_dirLister) { - m_setLeafVisible = true; loadTree(url()); } @@ -158,6 +156,10 @@ void FoldersPanel::showEvent(QShowEvent* event) const qreal itemHeight = qMax(int(KIconLoader::SizeSmall), styleOption.fontMetrics.height()); view->setItemSize(QSizeF(-1, itemHeight + 2 * styleOption.margin)); view->setItemLayout(KFileItemListView::DetailsLayout); + // Set the opacity to 0 initially. The opacity will be increased after the loading of the initial tree + // has been finished in slotLoadingCompleted(). This prevents an unnecessary animation-mess when + // opening the folders panel. + view->setOpacity(0); KFileItemModel* model = new KFileItemModel(m_dirLister, this); // Use a QueuedConnection to give the view the possibility to react first on the @@ -168,6 +170,12 @@ void FoldersPanel::showEvent(QShowEvent* event) m_controller = container->controller(); m_controller->setView(view); m_controller->setModel(model); + m_controller->setSelectionBehavior(KItemListController::SingleSelection); + + connect(m_controller, SIGNAL(itemActivated(int)), this, SLOT(slotItemActivated(int))); + connect(m_controller, SIGNAL(itemMiddleClicked(int)), this, SLOT(slotItemMiddleClicked(int))); + connect(m_controller, SIGNAL(itemContextMenuRequested(int,QPointF)), this, SLOT(slotItemContextMenuRequested(int,QPointF))); + connect(m_controller, SIGNAL(viewContextMenuRequested(QPointF)), this, SLOT(slotViewContextMenuRequested(QPointF))); // TODO: Check whether it makes sense to make an explicit API for KItemListContainer // to make the background transparent. @@ -194,22 +202,6 @@ void FoldersPanel::showEvent(QShowEvent* event) Panel::showEvent(event); } -void FoldersPanel::contextMenuEvent(QContextMenuEvent* event) -{ - Panel::contextMenuEvent(event); - - KFileItem item; - /*const QModelIndex index = m_treeView->indexAt(event->pos()); - if (index.isValid()) { - const QModelIndex dolphinModelIndex = m_proxyModel->mapToSource(index); - item = m_dolphinModel->itemForIndex(dolphinModelIndex); - }*/ - - QPointer<TreeViewContextMenu> contextMenu = new TreeViewContextMenu(this, item); - contextMenu->open(); - delete contextMenu; -} - void FoldersPanel::keyPressEvent(QKeyEvent* event) { const int key = event->key(); @@ -221,17 +213,65 @@ void FoldersPanel::keyPressEvent(QKeyEvent* event) } } -void FoldersPanel::updateMouseButtons() +void FoldersPanel::slotItemActivated(int index) +{ + const KFileItem item = fileItemModel()->fileItem(index); + if (!item.isNull()) { + emit changeUrl(item.url(), Qt::LeftButton); + } +} + +void FoldersPanel::slotItemMiddleClicked(int index) { - m_mouseButtons = QApplication::mouseButtons(); + const KFileItem item = fileItemModel()->fileItem(index); + if (!item.isNull()) { + emit changeUrl(item.url(), Qt::MiddleButton); + } +} + +void FoldersPanel::slotItemContextMenuRequested(int index, const QPointF& pos) +{ + Q_UNUSED(pos); + + const KFileItem fileItem = fileItemModel()->fileItem(index); + + QWeakPointer<TreeViewContextMenu> contextMenu = new TreeViewContextMenu(this, fileItem); + contextMenu.data()->open(); + if (contextMenu.data()) { + delete contextMenu.data(); + } +} + +void FoldersPanel::slotViewContextMenuRequested(const QPointF& pos) +{ + Q_UNUSED(pos); + + QWeakPointer<TreeViewContextMenu> contextMenu = new TreeViewContextMenu(this, KFileItem()); + contextMenu.data()->open(); + if (contextMenu.data()) { + delete contextMenu.data(); + } } void FoldersPanel::slotLoadingCompleted() { - const int index = fileItemModel()->index(url()); - if (index >= 0) { - m_controller->selectionManager()->setCurrentItem(index); + if (m_controller->view()->opacity() == 0) { + // The loading of the initial tree after opening the Folders panel + // has been finished. Trigger the increasing of the opacity after + // a short delay to give the view the chance to finish its internal + // animations. + // TODO: Check whether it makes sense to allow accessing the + // view-internal delay for usecases like this. + QTimer::singleShot(250, this, SLOT(startFadeInAnimation())); + } + + if (!m_updateCurrentItem) { + return; } + + const int index = fileItemModel()->index(url()); + updateCurrentItem(index); + m_updateCurrentItem = false; } void FoldersPanel::slotHorizontalScrollBarMoved(int value) @@ -250,10 +290,21 @@ void FoldersPanel::slotVerticalScrollBarMoved(int value) //m_treeView->setAutoHorizontalScroll(FoldersPanelSettings::autoScrolling()); } +void FoldersPanel::startFadeInAnimation() +{ + QPropertyAnimation* anim = new QPropertyAnimation(m_controller->view(), "opacity", this); + anim->setStartValue(0); + anim->setEndValue(1); + anim->setEasingCurve(QEasingCurve::InOutQuad); + anim->start(QAbstractAnimation::DeleteWhenStopped); + anim->setDuration(200); +} + void FoldersPanel::loadTree(const KUrl& url) { Q_ASSERT(m_dirLister); - m_leafDir = url; + + m_updateCurrentItem = false; KUrl baseUrl; if (url.isLocalFile()) { @@ -266,6 +317,7 @@ void FoldersPanel::loadTree(const KUrl& url) } if (m_dirLister->url() != baseUrl) { + m_updateCurrentItem = true; m_dirLister->stop(); m_dirLister->openUrl(baseUrl, KDirLister::Reload); } @@ -273,29 +325,23 @@ void FoldersPanel::loadTree(const KUrl& url) KFileItemModel* model = fileItemModel(); const int index = model->index(url); if (index >= 0) { - m_controller->selectionManager()->setCurrentItem(index); + updateCurrentItem(index); } else { + m_updateCurrentItem = true; model->setExpanded(QSet<KUrl>() << url); + // slotLoadingCompleted() will be invoked after the model has + // expanded the url } } -void FoldersPanel::selectLeafDirectory() +void FoldersPanel::updateCurrentItem(int index) { - /*const QModelIndex dirIndex = m_dolphinModel->indexForUrl(m_leafDir); - const QModelIndex proxyIndex = m_proxyModel->mapFromSource(dirIndex); + KItemListSelectionManager* selectionManager = m_controller->selectionManager(); + selectionManager->setCurrentItem(index); + selectionManager->clearSelection(); + selectionManager->setSelected(index); - if (proxyIndex.isValid()) { - QItemSelectionModel* selModel = m_treeView->selectionModel(); - selModel->setCurrentIndex(proxyIndex, QItemSelectionModel::ClearAndSelect); - - if (m_setLeafVisible) { - // Invoke scrollToLeaf() asynchronously. This assures that - // the horizontal scrollbar is shown after resizing the column - // (otherwise the scrollbar might hide the leaf). - QTimer::singleShot(0, this, SLOT(scrollToLeaf())); - m_setLeafVisible = false; - } - }*/ + m_controller->view()->scrollToItem(index); } KFileItemModel* FoldersPanel::fileItemModel() const diff --git a/src/panels/folders/folderspanel.h b/src/panels/folders/folderspanel.h index 70390da60..d249f850f 100644 --- a/src/panels/folders/folderspanel.h +++ b/src/panels/folders/folderspanel.h @@ -63,37 +63,14 @@ protected: /** @see QWidget::showEvent() */ virtual void showEvent(QShowEvent* event); - /** @see QWidget::contextMenuEvent() */ - virtual void contextMenuEvent(QContextMenuEvent* event); - /** @see QWidget::keyPressEvent() */ virtual void keyPressEvent(QKeyEvent* event); private slots: - /** - * Updates the active view to the URL - * which is given by the item with the index \a index. - */ - //void updateActiveView(const QModelIndex& index); - - /** - * Is emitted if URLs have been dropped - * to the index \a index. - */ - //void dropUrls(const QModelIndex& index, QDropEvent* event); - - /** - * Expands the treeview to show the directory - * specified by \a index. - */ - //void expandToDir(const QModelIndex& index); - - /** - * Assures that the leaf folder gets visible. - */ - //void scrollToLeaf(); - - void updateMouseButtons(); + void slotItemActivated(int index); + void slotItemMiddleClicked(int index); + void slotItemContextMenuRequested(int index, const QPointF& pos); + void slotViewContextMenuRequested(const QPointF& pos); void slotLoadingCompleted(); @@ -101,6 +78,12 @@ private slots: void slotVerticalScrollBarMoved(int value); + /** + * Increases the opacity of the view step by step until it is fully + * opaque. + */ + void startFadeInAnimation(); + private: /** * Initializes the base URL of the tree and expands all @@ -110,20 +93,17 @@ private: void loadTree(const KUrl& url); /** - * Selects the current leaf directory m_leafDir and assures - * that the directory is visible if the leaf has been set by - * FoldersPanel::setUrl(). + * Sets the item with the index \a index as current item, selects + * the item and assures that the item will be visible. */ - void selectLeafDirectory(); + void updateCurrentItem(int index); KFileItemModel* fileItemModel() const; private: - bool m_setLeafVisible; - Qt::MouseButtons m_mouseButtons; + bool m_updateCurrentItem; KDirLister* m_dirLister; KItemListController* m_controller; - KUrl m_leafDir; }; #endif // FOLDERSPANEL_H diff --git a/src/panels/folders/ktreeview_p.h b/src/panels/folders/ktreeview_p.h deleted file mode 100644 index 9ea4ac7ee..000000000 --- a/src/panels/folders/ktreeview_p.h +++ /dev/null @@ -1,46 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by <haraldhv (at) stud.ntnu.no> * - * Copyright (C) 2008 by <[email protected]> * - * * - * 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 KTREEVIEW_P_H -#define KTREEVIEW_P_H - -#include <QObject> - -#include "ktreeview.h" - -class QTimeLine; - -class KTreeView::KTreeViewPrivate : public QObject -{ - Q_OBJECT - -public Q_SLOTS: - void startScrolling(); - void updateVerticalScrollBar(int value); - -public: - KTreeViewPrivate(KTreeView *parent); - KTreeView *parent; - - bool autoHorizontalScroll; - QTimeLine *timeLine; -}; - -#endif /* ifndef KTREEVIEW_P_H */ diff --git a/src/panels/folders/treeviewcontextmenu.cpp b/src/panels/folders/treeviewcontextmenu.cpp index 5db3e2c2a..daf14ab4a 100644 --- a/src/panels/folders/treeviewcontextmenu.cpp +++ b/src/panels/folders/treeviewcontextmenu.cpp @@ -39,7 +39,7 @@ TreeViewContextMenu::TreeViewContextMenu(FoldersPanel* parent, const KFileItem& fileInfo) : QObject(parent), m_parent(parent), - m_fileInfo(fileInfo) + m_fileItem(fileInfo) { } @@ -51,8 +51,8 @@ void TreeViewContextMenu::open() { KMenu* popup = new KMenu(m_parent); - if (!m_fileInfo.isNull()) { - KFileItemListProperties capabilities(KFileItemList() << m_fileInfo); + if (!m_fileItem.isNull()) { + KFileItemListProperties capabilities(KFileItemList() << m_fileItem); // insert 'Cut', 'Copy' and 'Paste' QAction* cutAction = new QAction(KIcon("edit-cut"), i18nc("@action:inmenu", "Cut"), this); @@ -85,7 +85,7 @@ void TreeViewContextMenu::open() KConfigGroup configGroup(globalConfig, "KDE"); bool showDeleteCommand = configGroup.readEntry("ShowDeleteCommand", false); - const KUrl url = m_fileInfo.url(); + const KUrl url = m_fileItem.url(); if (url.isLocalFile()) { QAction* moveToTrashAction = new QAction(KIcon("user-trash"), i18nc("@action:inmenu", "Move to Trash"), this); @@ -115,34 +115,40 @@ void TreeViewContextMenu::open() popup->addSeparator(); } - QAction* showHiddenFilesAction = new QAction(i18nc("@action:inmenu", "Show Hidden Files"), this); - showHiddenFilesAction->setCheckable(true); - showHiddenFilesAction->setChecked(m_parent->hiddenFilesShown()); - popup->addAction(showHiddenFilesAction); - connect(showHiddenFilesAction, SIGNAL(toggled(bool)), this, SLOT(setShowHiddenFiles(bool))); + if (m_fileItem.isNull()) { + QAction* showHiddenFilesAction = new QAction(i18nc("@action:inmenu", "Show Hidden Files"), this); + showHiddenFilesAction->setCheckable(true); + showHiddenFilesAction->setChecked(m_parent->hiddenFilesShown()); + popup->addAction(showHiddenFilesAction); + connect(showHiddenFilesAction, SIGNAL(toggled(bool)), this, SLOT(setShowHiddenFiles(bool))); - QAction* autoScrollingAction = new QAction(i18nc("@action:inmenu", "Automatic Scrolling"), this); - autoScrollingAction->setCheckable(true); - autoScrollingAction->setChecked(m_parent->autoScrolling()); - popup->addAction(autoScrollingAction); - connect(autoScrollingAction, SIGNAL(toggled(bool)), this, SLOT(setAutoScrolling(bool))); + QAction* autoScrollingAction = new QAction(i18nc("@action:inmenu", "Automatic Scrolling"), this); + autoScrollingAction->setCheckable(true); + autoScrollingAction->setChecked(m_parent->autoScrolling()); + // TODO: Temporary disabled. Horizontal autoscrolling will be implemented later either + // in KItemViews or manually as part of the FoldersPanel + //popup->addAction(autoScrollingAction); + connect(autoScrollingAction, SIGNAL(toggled(bool)), this, SLOT(setAutoScrolling(bool))); + } - popup->addSeparator(); foreach (QAction* action, m_parent->customContextMenuActions()) { popup->addAction(action); } + QWeakPointer<KMenu> popupPtr = popup; popup->exec(QCursor::pos()); - popup->deleteLater(); + if (popupPtr.data()) { + popupPtr.data()->deleteLater(); + } } void TreeViewContextMenu::populateMimeData(QMimeData* mimeData, bool cut) { KUrl::List kdeUrls; - kdeUrls.append(m_fileInfo.url()); + kdeUrls.append(m_fileItem.url()); KUrl::List mostLocalUrls; bool dummy; - mostLocalUrls.append(m_fileInfo.mostLocalUrl(dummy)); + mostLocalUrls.append(m_fileItem.mostLocalUrl(dummy)); KonqMimeData::populateMimeData(mimeData, kdeUrls, mostLocalUrls, cut); } @@ -166,7 +172,7 @@ void TreeViewContextMenu::paste() const QMimeData* mimeData = clipboard->mimeData(); const KUrl::List source = KUrl::List::fromMimeData(mimeData); - const KUrl& dest = m_fileInfo.url(); + const KUrl& dest = m_fileItem.url(); if (KonqMimeData::decodeIsCutSelection(mimeData)) { KonqOperations::copy(m_parent, KonqOperations::MOVE, source, dest); clipboard->clear(); @@ -177,22 +183,22 @@ void TreeViewContextMenu::paste() void TreeViewContextMenu::rename() { - m_parent->rename(m_fileInfo); + m_parent->rename(m_fileItem); } void TreeViewContextMenu::moveToTrash() { - KonqOperations::del(m_parent, KonqOperations::TRASH, m_fileInfo.url()); + KonqOperations::del(m_parent, KonqOperations::TRASH, m_fileItem.url()); } void TreeViewContextMenu::deleteItem() { - KonqOperations::del(m_parent, KonqOperations::DEL, m_fileInfo.url()); + KonqOperations::del(m_parent, KonqOperations::DEL, m_fileItem.url()); } void TreeViewContextMenu::showProperties() { - KPropertiesDialog* dialog = new KPropertiesDialog(m_fileInfo.url(), m_parent); + KPropertiesDialog* dialog = new KPropertiesDialog(m_fileItem.url(), m_parent); dialog->setAttribute(Qt::WA_DeleteOnClose); dialog->show(); } diff --git a/src/panels/folders/treeviewcontextmenu.h b/src/panels/folders/treeviewcontextmenu.h index e33bb70c5..0b3fd79bd 100644 --- a/src/panels/folders/treeviewcontextmenu.h +++ b/src/panels/folders/treeviewcontextmenu.h @@ -50,25 +50,25 @@ public: void open(); private slots: - /** Cuts the item m_fileInfo. */ + /** Cuts the item m_fileItem. */ void cut(); - /** Copies the item m_fileInfo. */ + /** Copies the item m_fileItem. */ void copy(); - /** Paste the clipboard to m_fileInfo. */ + /** Paste the clipboard to m_fileItem. */ void paste(); - /** Renames the item m_fileInfo. */ + /** Renames the item m_fileItem. */ void rename(); - /** Moves the item m_fileInfo to the trash. */ + /** Moves the item m_fileItem to the trash. */ void moveToTrash(); - /** Deletes the item m_fileInfo. */ + /** Deletes the item m_fileItem. */ void deleteItem(); - /** Shows the properties of the item m_fileInfo. */ + /** Shows the properties of the item m_fileItem. */ void showProperties(); /** @@ -88,7 +88,7 @@ private: private: FoldersPanel* m_parent; - KFileItem m_fileInfo; + KFileItem m_fileItem; }; #endif diff --git a/src/views/dolphinview.cpp b/src/views/dolphinview.cpp index c5c13e97f..379cd9f90 100644 --- a/src/views/dolphinview.cpp +++ b/src/views/dolphinview.cpp @@ -141,7 +141,6 @@ DolphinView::DolphinView(const KUrl& url, QWidget* parent) : connect(controller, SIGNAL(itemContextMenuRequested(int,QPointF)), this, SLOT(slotItemContextMenuRequested(int,QPointF))); connect(controller, SIGNAL(viewContextMenuRequested(QPointF)), this, SLOT(slotViewContextMenuRequested(QPointF))); connect(controller, SIGNAL(headerContextMenuRequested(QPointF)), this, SLOT(slotHeaderContextMenuRequested(QPointF))); - connect(controller, SIGNAL(itemExpansionToggleClicked(int)), this, SLOT(slotItemExpansionToggleClicked(int))); connect(controller, SIGNAL(itemHovered(int)), this, SLOT(slotItemHovered(int))); connect(controller, SIGNAL(itemUnhovered(int)), this, SLOT(slotItemUnhovered(int))); connect(controller, SIGNAL(itemDropEvent(int,QGraphicsSceneDragDropEvent*)), this, SLOT(slotItemDropEvent(int,QGraphicsSceneDragDropEvent*))); @@ -788,17 +787,6 @@ void DolphinView::slotHeaderContextMenuRequested(const QPointF& pos) delete menu.data(); } -void DolphinView::slotItemExpansionToggleClicked(int index) -{ - // TODO: When doing a model->setExpanded(false) it should - // be checked here whether the current index is part of the - // closed sub-tree. If this is the case, the current index - // should be adjusted to the parent index. - KFileItemModel* model = fileItemModel(); - const bool expanded = model->isExpanded(index); - model->setExpanded(index, !expanded); -} - void DolphinView::slotItemHovered(int index) { const KFileItem item = fileItemModel()->fileItem(index); diff --git a/src/views/dolphinview.h b/src/views/dolphinview.h index 2bbdf2b71..e0be25e42 100644 --- a/src/views/dolphinview.h +++ b/src/views/dolphinview.h @@ -559,7 +559,6 @@ private slots: void slotItemContextMenuRequested(int index, const QPointF& pos); void slotViewContextMenuRequested(const QPointF& pos); void slotHeaderContextMenuRequested(const QPointF& pos); - void slotItemExpansionToggleClicked(int index); void slotItemHovered(int index); void slotItemUnhovered(int index); void slotItemDropEvent(int index, QGraphicsSceneDragDropEvent* event); diff --git a/src/views/dolphinviewautoscroller.cpp b/src/views/dolphinviewautoscroller.cpp deleted file mode 100644 index 5b338cc37..000000000 --- a/src/views/dolphinviewautoscroller.cpp +++ /dev/null @@ -1,223 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Peter Penz <[email protected]> * - * * - * 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 "dolphinviewautoscroller.h" - -#include <QAbstractItemView> -#include <QApplication> -#include <QCursor> -#include <QEvent> -#include <QMouseEvent> -#include <QScrollBar> -#include <QTimer> -#include <math.h> - -DolphinViewAutoScroller::DolphinViewAutoScroller(QAbstractItemView* parent) : - QObject(parent), - m_rubberBandSelection(false), - m_keyPressed(false), - m_initializedTimestamp(false), - m_horizontalScrollInc(0), - m_verticalScrollInc(0), - m_itemView(parent), - m_timer(0), - m_timestamp() -{ - m_itemView->setAutoScroll(false); - m_itemView->viewport()->installEventFilter(this); - m_itemView->installEventFilter(this); - - m_timer = new QTimer(this); - m_timer->setSingleShot(false); - m_timer->setInterval(1000 / 25); // 25 frames per second - connect(m_timer, SIGNAL(timeout()), this, SLOT(scrollViewport())); -} - -DolphinViewAutoScroller::~DolphinViewAutoScroller() -{ -} - -bool DolphinViewAutoScroller::isActive() const -{ - return m_timer->isActive(); -} - -void DolphinViewAutoScroller::handleCurrentIndexChange(const QModelIndex& current, - const QModelIndex& previous) -{ - // When the autoscroller is inactive and a key has been pressed, it must be - // assured that the current item stays visible. The check whether the previous - // item is valid is important because of #197951. The keypress check is done - // because of #199833. - if (current.isValid() && (previous.isValid() || m_keyPressed) && !isActive()) { - m_itemView->scrollTo(current); - } -} - -bool DolphinViewAutoScroller::eventFilter(QObject* watched, QEvent* event) -{ - if (watched == m_itemView->viewport()) { - switch (event->type()) { - case QEvent::MouseButtonPress: - if (static_cast<QMouseEvent*>(event)->button() == Qt::LeftButton) { - m_rubberBandSelection = true; - } - break; - - case QEvent::MouseMove: - if (m_rubberBandSelection) { - triggerAutoScroll(); - } - break; - - case QEvent::MouseButtonRelease: - m_rubberBandSelection = false; - stopAutoScroll(); - break; - - case QEvent::DragEnter: - case QEvent::DragMove: - m_rubberBandSelection = false; - triggerAutoScroll(); - break; - - case QEvent::Drop: - case QEvent::DragLeave: - m_rubberBandSelection = false; - stopAutoScroll(); - break; - - default: - break; - } - } else if (watched == m_itemView) { - switch (event->type()) { - case QEvent::KeyPress: - m_keyPressed = true; - break; - - case QEvent::KeyRelease: - m_keyPressed = false; - break; - - default: - break; - } - } - - return QObject::eventFilter(watched, event); -} - -void DolphinViewAutoScroller::scrollViewport() -{ - if (m_timestamp.elapsed() < QApplication::startDragTime()) { - return; - } - - QScrollBar* verticalScrollBar = m_itemView->verticalScrollBar(); - if (verticalScrollBar) { - const int value = verticalScrollBar->value(); - verticalScrollBar->setValue(value + m_verticalScrollInc); - - } - QScrollBar* horizontalScrollBar = m_itemView->horizontalScrollBar(); - if (horizontalScrollBar) { - const int value = horizontalScrollBar->value(); - horizontalScrollBar->setValue(value + m_horizontalScrollInc); - - } - - if (m_rubberBandSelection) { - // The scrolling does not lead to an update of the rubberband - // selection. Fake a mouse move event to let the QAbstractItemView - // update the rubberband. - QWidget* viewport = m_itemView->viewport(); - const QPoint pos = viewport->mapFromGlobal(QCursor::pos()); - QMouseEvent event(QEvent::MouseMove, pos, Qt::LeftButton, Qt::LeftButton, QApplication::keyboardModifiers()); - QCoreApplication::sendEvent(viewport, &event); - } -} - -void DolphinViewAutoScroller::triggerAutoScroll() -{ - const bool verticalScrolling = m_itemView->verticalScrollBar() && - m_itemView->verticalScrollBar()->isVisible(); - const bool horizontalScrolling = m_itemView->horizontalScrollBar() && - m_itemView->horizontalScrollBar()->isVisible(); - if (!verticalScrolling && !horizontalScrolling) { - // no scrollbars are shown at all, so no autoscrolling is necessary - stopAutoScroll(); - return; - } - - QWidget* viewport = m_itemView->viewport(); - const QPoint pos = viewport->mapFromGlobal(QCursor::pos()); - if (verticalScrolling) { - m_verticalScrollInc = calculateScrollIncrement(pos.y(), viewport->height()); - } - if (horizontalScrolling) { - m_horizontalScrollInc = calculateScrollIncrement(pos.x(), viewport->width()); - } - - if (m_timer->isActive()) { - if ((m_horizontalScrollInc == 0) && (m_verticalScrollInc == 0)) { - stopAutoScroll(); - } - } else if ((m_horizontalScrollInc != 0) || (m_verticalScrollInc != 0)) { - if (!m_initializedTimestamp) { - m_initializedTimestamp = true; - m_timestamp.start(); - } - m_timer->start(); - } -} - -void DolphinViewAutoScroller::stopAutoScroll() -{ - m_timer->stop(); - m_horizontalScrollInc = 0; - m_verticalScrollInc = 0; - m_initializedTimestamp = false; -} - -int DolphinViewAutoScroller::calculateScrollIncrement(int cursorPos, int rangeSize) const -{ - int inc = 0; - - const int minSpeed = 4; - const int maxSpeed = 768; - const int speedLimiter = 48; - const int autoScrollBorder = 64; - - if (cursorPos < autoScrollBorder) { - inc = -minSpeed + qAbs(cursorPos - autoScrollBorder) * (cursorPos - autoScrollBorder) / speedLimiter; - if (inc < -maxSpeed) { - inc = -maxSpeed; - } - } else if (cursorPos > rangeSize - autoScrollBorder) { - inc = minSpeed + qAbs(cursorPos - rangeSize + autoScrollBorder) * (cursorPos - rangeSize + autoScrollBorder) / speedLimiter; - if (inc > maxSpeed) { - inc = maxSpeed; - } - } - - return inc; -} - -#include "dolphinviewautoscroller.moc" diff --git a/src/views/dolphinviewautoscroller.h b/src/views/dolphinviewautoscroller.h deleted file mode 100644 index 04d91a8f6..000000000 --- a/src/views/dolphinviewautoscroller.h +++ /dev/null @@ -1,79 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Peter Penz <[email protected]> * - * * - * 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 DOLPHINVIEWAUTOSCROLLER_H -#define DOLPHINVIEWAUTOSCROLLER_H - -#include <QTime> -#include <QObject> - -class QAbstractItemView; -class QModelIndex; -class QTimer; - -/** - * @brief Assures that an autoscrolling is done for item views. - * - * This is a workaround as QAbstractItemView::setAutoScroll() is not usable - * when selecting items (see Qt issue #214542). - */ -class DolphinViewAutoScroller : public QObject -{ - Q_OBJECT - -public: - DolphinViewAutoScroller(QAbstractItemView* parent); - virtual ~DolphinViewAutoScroller(); - bool isActive() const; - - /** - * Must be invoked by the parent item view, when QAbstractItemView::currentChanged() - * has been called. Assures that the current item stays visible when it has been - * changed by the keyboard. - */ - void handleCurrentIndexChange(const QModelIndex& current, const QModelIndex& previous); - -protected: - virtual bool eventFilter(QObject* watched, QEvent* event); - -private slots: - void scrollViewport(); - -private: - void triggerAutoScroll(); - void stopAutoScroll(); - - /** - * Calculates the scroll increment dependent from - * the cursor position \a cursorPos and the range 0 - \a rangeSize - 1. - */ - int calculateScrollIncrement(int cursorPos, int rangeSize) const; - -private: - bool m_rubberBandSelection; - bool m_keyPressed; - bool m_initializedTimestamp; - int m_horizontalScrollInc; - int m_verticalScrollInc; - QAbstractItemView* m_itemView; - QTimer* m_timer; - QTime m_timestamp; -}; - -#endif |
