dolphincategorydrawer.cpp
dolphinview.cpp
dolphinviewactionhandler.cpp
+ folderexpander.cpp
iconmanager.cpp
ktooltip.cpp
kballoontipdelegate.cpp
iconsizedialog.cpp
iconsviewsettingspage.cpp
infosidebarpage.cpp
- ktreeview.cpp
+ ktreeview.cpp
main.cpp
metadatawidget.cpp
metatextlabel.cpp
<entry name="ViewPropsTimestamp" type="DateTime" >
<label context="@label">Timestamp since when the view properties are valid</label>
</entry>
+ <entry name="AutoExpandFolders" type="Bool">
+ <label context="@label">Use auto-expanding folders for all view types</label>
+ <default>false</default>
+ </entry>
</group>
</kcfg>
#include "dolphin_columnmodesettings.h"
#include "dolphin_generalsettings.h"
#include "draganddrophelper.h"
+#include "folderexpander.h"
#include "iconmanager.h"
#include "selectionmanager.h"
#include "tooltipmanager.h"
connect(KGlobalSettings::self(), SIGNAL(kdisplayFontChanged()),
this, SLOT(updateFont()));
+
+ FolderExpander* folderExpander = new FolderExpander(this, m_proxyModel);
+ folderExpander->setEnabled(DolphinSettings::instance().generalSettings()->autoExpandFolders());
+ connect (folderExpander, SIGNAL(enterDir(const QModelIndex&)),
+ m_view->m_controller, SLOT(triggerItem(const QModelIndex&)));
}
DolphinColumnWidget::~DolphinColumnWidget()
#include "dolphincontroller.h"
#include "dolphinsortfilterproxymodel.h"
#include "dolphindetailsview.h"
+#include "dolphin_detailsmodesettings.h"
#include "dolphiniconsview.h"
#include "dolphinsettings.h"
#include "dolphin_generalsettings.h"
+#include "folderexpander.h"
#include "iconmanager.h"
#include "renamedialog.h"
#include "tooltipmanager.h"
}
}
-
void DolphinView::mouseReleaseEvent(QMouseEvent* event)
{
QWidget::mouseReleaseEvent(event);
Q_ASSERT(view != 0);
view->installEventFilter(this);
+ if (m_mode != ColumnView) {
+ // Give the view the ability to auto-expand its directories on hovering
+ // (the column view takes care about this itself). If the details view
+ // uses expandable folders, the auto-expanding should be used always.
+ DolphinSettings& settings = DolphinSettings::instance();
+ const bool enabled = settings.generalSettings()->autoExpandFolders() ||
+ ((m_detailsView != 0) && settings.detailsModeSettings()->expandableFolders());
+
+ FolderExpander* folderExpander = new FolderExpander(view, m_proxyModel);
+ folderExpander->setEnabled(enabled);
+ connect(folderExpander, SIGNAL(enterDir(const QModelIndex&)),
+ m_controller, SLOT(triggerItem(const QModelIndex&)));
+ }
+
m_controller->setItemView(view);
m_fileItemDelegate = new KFileItemDelegate(view);
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2008 by Simon St James <kdedevel@etotheipiplusone.com> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "folderexpander.h"
+#include "dolphinview.h"
+
+#include "dolphinsettings.h"
+#include "dolphin_generalsettings.h"
+
+#include <QtCore/QTimer>
+#include <QtGui/QAbstractItemView>
+#include <QtGui/QTreeView>
+#include <QtGui/QScrollBar>
+
+#include <QtCore/QEvent>
+#include <QtGui/QDragMoveEvent>
+
+#include <QtGui/QSortFilterProxyModel>
+
+#include <kdirmodel.h>
+#include <kdebug.h>
+
+FolderExpander::FolderExpander(QAbstractItemView *view, QSortFilterProxyModel *proxyModel) :
+ QObject(view),
+ m_enabled(true),
+ m_view(view),
+ m_proxyModel(proxyModel),
+ m_autoExpandTriggerTimer(0),
+ m_autoExpandPos()
+{
+ // Validation. If these fail, the event filter is never
+ // installed on the view and the FolderExpander is inactive.
+ if (m_view == 0) {
+ kWarning() << "Need a view!";
+ return; // Not valid.
+ }
+ if (m_proxyModel == 0) {
+ kWarning() << "Need a proxyModel!";
+ return; // Not valid.
+ }
+ KDirModel *m_dirModel = qobject_cast< KDirModel* >( m_proxyModel->sourceModel() );
+ if (m_dirModel == 0) {
+ kWarning() << "Expected m_proxyModel's sourceModel() to be a KDirModel!";
+ return; // Not valid.
+ }
+
+ // Initialise auto-expand timer.
+ m_autoExpandTriggerTimer = new QTimer(this);
+ m_autoExpandTriggerTimer->setSingleShot(true);
+ connect(m_autoExpandTriggerTimer, SIGNAL(timeout()),
+ this, SLOT(autoExpandTimeout()));
+
+ // The view scrolling complicates matters, so we want to
+ // be informed if they occur.
+ connect(m_view->horizontalScrollBar(), SIGNAL(valueChanged(int)),
+ this, SLOT(viewScrolled()));
+ connect(m_view->verticalScrollBar(), SIGNAL(valueChanged(int)),
+ this, SLOT(viewScrolled()));
+
+ // "Dragging" events are sent to the QAbstractItemView's viewport.
+ m_view->viewport()->installEventFilter(this);
+}
+
+void FolderExpander::setEnabled(bool enabled)
+{
+ m_enabled = enabled;
+}
+
+bool FolderExpander::enabled() const
+{
+ return m_enabled;
+}
+
+FolderExpander::~FolderExpander()
+{
+}
+
+void FolderExpander::viewScrolled()
+{
+ if (m_autoExpandTriggerTimer->isActive()) {
+ kDebug() << "Resetting time due to scrolling!";
+ // (Re-)set the timer while we're scrolling the view
+ // (or it's being scrolled by some external mechanism).
+ // TODO - experiment with this. Cancelling the timer,
+ // or adding a "penalty" on top of AUTO_EXPAND_DELAY
+ // might work more nicely when drilling down through the sidebar
+ // tree.
+ m_autoExpandTriggerTimer->start(AUTO_EXPAND_DELAY);
+ }
+}
+
+void FolderExpander::autoExpandTimeout()
+{
+ if (!m_enabled) {
+ return;
+ }
+
+ // We want to find whether the file currently being hovered over is a
+ // directory. TODO - is there a simpler way, preferably without
+ // needing to pass in m_proxyModel that has a KDirModel as its sourceModel() ... ?
+ QModelIndex proxyIndexToExpand = m_view->indexAt(m_autoExpandPos);
+ QModelIndex indexToExpand = m_proxyModel->mapToSource(proxyIndexToExpand);
+ KDirModel* m_dirModel = qobject_cast< KDirModel* >(m_proxyModel->sourceModel());
+ Q_ASSERT(m_dirModel != 0);
+ KFileItem itemToExpand = m_dirModel->itemForIndex(indexToExpand );
+
+ kDebug() << "Need to expand: " << itemToExpand.targetUrl() << " isDir? = " << itemToExpand.isDir();
+
+ if (itemToExpand.isDir()) {
+ QTreeView *viewAsTreeView = qobject_cast<QTreeView*>(m_view);
+ if (viewAsTreeView != 0) {
+ // Toggle expanded state of this directory.
+ viewAsTreeView->setExpanded(proxyIndexToExpand, !viewAsTreeView->isExpanded(proxyIndexToExpand));
+ }
+ else {
+ // Enter this directory.
+ emit enterDir(proxyIndexToExpand);
+ }
+ }
+}
+
+bool FolderExpander::eventFilter(QObject* watched, QEvent* event)
+{
+ Q_UNUSED(watched);
+ // We're interested in reading Drag* events, but not filtering them,
+ // so always return false.
+ // We just store the position of the hover, here; actually working out
+ // what the hovered item is and whether it is expandable is done in
+ // autoExpandTimeout.
+ if (event->type() == QEvent::DragMove) {
+ QDragMoveEvent *dragMoveEvent = static_cast<QDragMoveEvent*>(event);
+ // (Re-)set the timer while we're still moving and dragging.
+ m_autoExpandTriggerTimer->start(AUTO_EXPAND_DELAY);
+ m_autoExpandPos = dragMoveEvent->pos();
+ } else if (event->type() == QEvent::DragLeave || event->type() == QEvent::Drop) {
+ m_autoExpandTriggerTimer->stop();
+ }
+ return false;
+}
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2008 by Simon St James <kdedevel@etotheipiplusone.com> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef FOLDEREXPANDER_H
+#define FOLDEREXPANDER_H
+
+// Needs to be exported as treesidebarpage uses it.
+#include "libdolphin_export.h"
+
+#include <QObject>
+#include <QPoint>
+
+class QAbstractItemView;
+class QTreeView;
+class QTimer;
+class QSortFilterProxyModel;
+class QModelIndex;
+class KDirModel;
+
+/* Grants "auto expand"/ "spring-loaded folders" to
+ the provided view. Qt has its own auto-expand
+ mechanism, but this works only for QTreeView and
+ does not play well with our auto-scrolling in
+ the Folders pane. Auto-expansion is enabled by default.
+
+ If the provided view is a QTreeView, the expanded state
+ is automatically toggled on hover. Otherwise, the enterDir()
+ signal is emitted, and the caller needs to ensure that
+ the requested directory is entered.
+
+ The FolderExpander becomes a child of the provided view */
+
+/**
+ * Grants auto expanding functionality to the provided item view.
+ * Qt has its own auto expand mechanism, but this works only
+ * for QTreeView. Auto expanding of folders is turned on
+ * per default.
+ *
+ * If the provided view is an instance of the class QTreeView, the
+ * expanded of the directory is automatically done on hover. Otherwise
+ * the enterDir() signal is emitted and the caller needs to ensure that
+ * the requested directory is entered.
+ *
+ * The FolderExpander becomes a child of the provided view.
+ */
+class LIBDOLPHINPRIVATE_EXPORT FolderExpander : public QObject
+{
+ Q_OBJECT
+
+public:
+ FolderExpander(QAbstractItemView* view, QSortFilterProxyModel* proxyModel);
+ virtual ~FolderExpander();
+
+ void setEnabled(bool enabled);
+ bool enabled() const;
+
+signals:
+ /**
+ * Is emitted if the directory \a dirModelIndex should be entered. The
+ * signal is not emitted when a QTreeView is used, as the entering of
+ * the directory is already provided by expanding the tree node.
+ */
+ void enterDir(const QModelIndex& dirModelIndex);
+
+private slots:
+ void viewScrolled();
+ void autoExpandTimeout();
+
+private:
+ bool m_enabled;
+
+ QAbstractItemView* m_view;
+ QSortFilterProxyModel* m_proxyModel;
+
+ QTimer* m_autoExpandTriggerTimer;
+ QPoint m_autoExpandPos;
+
+ static const int AUTO_EXPAND_DELAY = 700;
+
+ /**
+ * Watchs the drag/move events for the view to decide
+ * whether auto expanding of a folder should be triggered.
+ */
+ bool eventFilter(QObject* watched, QEvent* event);
+};
+#endif
setFrameStyle(QFrame::NoFrame);
setDragDropMode(QAbstractItemView::DragDrop);
setDropIndicatorShown(false);
- setAutoExpandDelay(300);
setVerticalScrollMode(QListView::ScrollPerPixel);
setHorizontalScrollMode(QListView::ScrollPerPixel);
#include "dolphinsettings.h"
#include "dolphin_folderspanelsettings.h"
#include "dolphin_generalsettings.h"
+#include "folderexpander.h"
#include "renamedialog.h"
#include "sidebartreeview.h"
#include "treeviewcontextmenu.h"
m_treeView->setModel(m_proxyModel);
m_proxyModel->setSorting(DolphinView::SortByName);
m_proxyModel->setSortOrder(Qt::AscendingOrder);
+
+ new FolderExpander(m_treeView, m_proxyModel);
connect(m_treeView, SIGNAL(clicked(const QModelIndex&)),
this, SLOT(updateActiveView(const QModelIndex&)));