#include <QEvent>
#include <QGraphicsSceneEvent>
#include <QMimeData>
+#include <QTimer>
#include <KGlobalSettings>
#include <KDebug>
m_keyboardManager(new KItemListKeyboardSearchManager(this)),
m_pressedIndex(-1),
m_pressedMousePos(),
+ m_autoActivationTimer(0),
m_oldSelection()
{
connect(m_keyboardManager, SIGNAL(changeCurrentItem(QString,bool)),
this, SLOT(slotChangeCurrentItem(QString,bool)));
+
+ m_autoActivationTimer = new QTimer(this);
+ m_autoActivationTimer->setSingleShot(true);
+ m_autoActivationTimer->setInterval(-1);
+ connect(m_autoActivationTimer, SIGNAL(timeout()), this, SLOT(slotAutoActivationTimeout()));
}
KItemListController::~KItemListController()
return m_selectionBehavior;
}
+void KItemListController::setAutoActivationDelay(int delay)
+{
+ m_autoActivationTimer->setInterval(delay);
+}
+
+int KItemListController::autoActivationDelay() const
+{
+ return m_autoActivationTimer->interval();
+}
+
bool KItemListController::showEvent(QShowEvent* event)
{
Q_UNUSED(event);
break;
case Qt::Key_Enter:
- case Qt::Key_Return:
- emit itemActivated(index);
+ case Qt::Key_Return: {
+ const QSet<int> selectedItems = m_selectionManager->selectedItems();
+ if (selectedItems.count() >= 2) {
+ emit itemsActivated(selectedItems);
+ } else if (selectedItems.count() == 1) {
+ emit itemActivated(selectedItems.toList().first());
+ } else {
+ emit itemActivated(index);
+ }
break;
+ }
case Qt::Key_Space:
if (controlPressed) {
}
}
+void KItemListController::slotAutoActivationTimeout()
+{
+ if (!m_model || !m_view) {
+ return;
+ }
+
+ const int index = m_autoActivationTimer->property("index").toInt();
+ if (index < 0 || index >= m_model->count()) {
+ return;
+ }
+
+ if (m_model->supportsDropping(index)) {
+ if (m_view->supportsItemExpanding() && m_model->isExpandable(index)) {
+ const bool expanded = m_model->isExpanded(index);
+ m_model->setExpanded(index, !expanded);
+ } else {
+ emit itemActivated(index);
+ }
+ }
+}
+
bool KItemListController::inputMethodEvent(QInputMethodEvent* event)
{
Q_UNUSED(event);
}
KItemListWidget* oldHoveredWidget = hoveredWidget();
- KItemListWidget* newHoveredWidget = widgetForPos(event->pos());
+
+ const QPointF pos = transform.map(event->pos());
+ KItemListWidget* newHoveredWidget = widgetForPos(pos);
+
if (oldHoveredWidget != newHoveredWidget) {
+ m_autoActivationTimer->stop();
+
if (oldHoveredWidget) {
oldHoveredWidget->setHovered(false);
emit itemUnhovered(oldHoveredWidget->index());
newHoveredWidget->setHovered(true);
}
emit itemHovered(index);
+
+ if (m_autoActivationTimer->interval() >= 0) {
+ m_autoActivationTimer->setProperty("index", index);
+ m_autoActivationTimer->start();
+ }
}
}
return false;
}
+ m_autoActivationTimer->stop();
+
const QPointF pos = transform.map(event->pos());
const int index = m_view->itemAt(pos);
emit itemDropEvent(index, event);
}
KItemListWidget* oldHoveredWidget = hoveredWidget();
- KItemListWidget* newHoveredWidget = widgetForPos(event->pos());
+ const QPointF pos = transform.map(event->pos());
+ KItemListWidget* newHoveredWidget = widgetForPos(pos);
+
if (oldHoveredWidget != newHoveredWidget) {
if (oldHoveredWidget) {
oldHoveredWidget->setHovered(false);
void setSelectionBehavior(SelectionBehavior behavior);
SelectionBehavior selectionBehavior() const;
+ /**
+ * Sets the delay in milliseconds when dragging an object above an item
+ * until the item gets activated automatically. A value of -1 indicates
+ * that no automatic activation will be done at all (= default value).
+ *
+ * The hovered item must support dropping (see KItemModelBase::supportsDropping()),
+ * otherwise the automatic activation is not available.
+ *
+ * After activating the item the signal itemActivated() will be
+ * emitted. If the view supports the expanding of items
+ * (KItemListView::supportsItemExpanding() returns true) and the item
+ * itself is expandable (see KItemModelBase::isExpandable()) then instead
+ * of activating the item it gets expanded instead (see
+ * KItemModelBase::setExpanded()).
+ */
+ void setAutoActivationDelay(int delay);
+ int autoActivationDelay() const;
+
virtual bool showEvent(QShowEvent* event);
virtual bool hideEvent(QHideEvent* event);
virtual bool keyPressEvent(QKeyEvent* event);
virtual bool processEvent(QEvent* event, const QTransform& transform);
signals:
+ /**
+ * Is emitted if exactly one item has been activated by e.g. a mouse-click
+ * or by pressing Return/Enter.
+ */
void itemActivated(int index);
+
+ /**
+ * Is emitted if more than one item has been activated by pressing Return/Enter
+ * when having a selection.
+ */
+ void itemsActivated(const QSet<int>& indexes);
+
void itemMiddleClicked(int index);
/**
void slotChangeCurrentItem(const QString& text, bool searchFromNextItem);
+ void slotAutoActivationTimeout();
+
private:
/**
* Creates a QDrag object and initiates a drag-operation.
int m_pressedIndex;
QPointF m_pressedMousePos;
+ QTimer* m_autoActivationTimer;
+
/**
* When starting a rubberband selection during a Shift- or Control-key has been
* pressed the current selection should never be deleted. To be able to restore
m_controller->setView(view);
m_controller->setModel(model);
m_controller->setSelectionBehavior(KItemListController::SingleSelection);
+ m_controller->setAutoActivationDelay(750);
connect(m_controller, SIGNAL(itemActivated(int)), this, SLOT(slotItemActivated(int)));
connect(m_controller, SIGNAL(itemMiddleClicked(int)), this, SLOT(slotItemMiddleClicked(int)));
KItemListController* controller = m_container->controller();
controller->setSelectionBehavior(KItemListController::MultiSelection);
- connect(controller, SIGNAL(itemActivated(int)),
- this, SLOT(slotItemActivated(int)));
+ if (GeneralSettings::autoExpandFolders()) {
+ controller->setAutoActivationDelay(750);
+ }
+ connect(controller, SIGNAL(itemActivated(int)), this, SLOT(slotItemActivated(int)));
+ connect(controller, SIGNAL(itemsActivated(QSet<int>)), this, SLOT(slotItemsActivated(QSet<int>)));
connect(controller, SIGNAL(itemMiddleClicked(int)), this, SLOT(slotItemMiddleClicked(int)));
connect(controller, SIGNAL(itemContextMenuRequested(int,QPointF)), this, SLOT(slotItemContextMenuRequested(int,QPointF)));
connect(controller, SIGNAL(viewContextMenuRequested(QPointF)), this, SLOT(slotViewContextMenuRequested(QPointF)));
void DolphinView::slotItemActivated(int index)
{
- Q_UNUSED(index);
+ const KFileItem item = fileItemModel()->fileItem(index);
+ if (!item.isNull()) {
+ emit itemActivated(item);
+ }
+}
- const KFileItemList items = selectedItems();
- if (items.isEmpty()) {
- return;
+void DolphinView::slotItemsActivated(const QSet<int>& indexes)
+{
+ Q_ASSERT(indexes.count() >= 2);
+
+ KFileItemList items;
+
+ KFileItemModel* model = fileItemModel();
+ QSetIterator<int> it(indexes);
+ while (it.hasNext()) {
+ const int index = it.next();
+ items.append(model->fileItem(index));
}
- if (items.count() == 1) {
- emit itemActivated(items.at(0)); // caught by DolphinViewContainer or DolphinPart
- } else {
- foreach (const KFileItem& item, items) {
- if (item.isDir()) {
- emit tabRequested(item.url());
- } else {
- emit itemActivated(item);
- }
+ foreach (const KFileItem& item, items) {
+ if (item.isDir()) {
+ emit tabRequested(item.url());
+ } else {
+ emit itemActivated(item);
}
}
}
void activate();
void slotItemActivated(int index);
+ void slotItemsActivated(const QSet<int>& indexes);
void slotItemMiddleClicked(int index);
void slotItemContextMenuRequested(int index, const QPointF& pos);
void slotViewContextMenuRequested(const QPointF& pos);