/***************************************************************************
- * Copyright (C) 2007 by Peter Penz <peter.penz@gmx.at> *
+ * Copyright (C) 2007-2009 by Peter Penz <peter.penz@gmx.at> *
* *
* 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 *
#include "dolphincolumnview.h"
+#include "dolphinmodel.h"
+#include "dolphincolumnviewcontainer.h"
#include "dolphincontroller.h"
-#include "dolphinsettings.h"
-
+#include "dolphindirlister.h"
+#include "dolphinsortfilterproxymodel.h"
+#include "settings/dolphinsettings.h"
+#include "dolphinviewautoscroller.h"
#include "dolphin_columnmodesettings.h"
+#include "dolphin_generalsettings.h"
+#include "draganddrophelper.h"
+#include "folderexpander.h"
+#include "tooltips/tooltipmanager.h"
+#include "versioncontrolobserver.h"
+#include "viewextensionsfactory.h"
+#include "zoomlevelinfo.h"
-#include <kcolorutils.h>
#include <kcolorscheme.h>
#include <kdirlister.h>
-#include <kdirmodel.h>
+#include <kfileitem.h>
+#include <kio/previewjob.h>
+#include <kiconeffect.h>
+#include <kjob.h>
+#include <konqmimedata.h>
-#include <QAbstractProxyModel>
#include <QApplication>
+#include <QClipboard>
+#include <QPainter>
#include <QPoint>
+#include <QScrollBar>
-/*
- * General implementation notes
- * ----------------------------
- *
- * In Qt4.3 the QColumnView widget has a default behavior regarding the
- * active column and the selection handling, which leads to some usability
- * problems within Dolphin:
- *
- * - No matter which mouse button has been clicked: If the mouse is above
- * a folder, the folder content will be loaded in the next column. The problem
- * is that this column also will marked as 'active column' within QColumnView,
- * hence it is not possible to select more than one folder within a column.
- *
- * - The currently opened folder is not always marked in the left column when
- * doing drag & drop and selections inside other columns.
- *
- * - The currently active column is visually not recognizable.
- *
- * - It is not possible for derived classes to remove inactive columns.
- *
- * DolphinView tries to bypass those points, but this required some workarounds:
- *
- * - QColumnView internally maps the selection model from the ColumnView to the
- * active column. As the active column from the Dolphin perspective is different
- * as the active column from QColumnView, the selection model is adjusted on
- * each interaction by the methods QColumnWidget::obtainSelectionModel(),
- * QColumnWidget::releaseSelectionModel() and QColumnView::requestSelectionModel().
- * QColumnView offers no hook to adjust this behavior, so those methods have to
- * be invoked throughout the code...
- *
- * - Some copy/paste code from QColumnView is part of DolphinColumnView::createColumn(), but Qt 4.4
- * will offer a solution for this.
- *
- * - The mousePressEvent() has been customized to prevent that folders are loaded on each
- * mouse click.
- *
- * We'll try to give some input for Trolltech if the Dolphin solution is stable enough, so hopefully
- * some workarounds can be removed when switching to Qt 4.4 or later.
- */
-
-/**
- * Represents one column inside the DolphinColumnView and has been
- * extended to respect view options and hovering information.
- */
-class ColumnWidget : public QListView
-{
-public:
- ColumnWidget(QWidget* parent,
- DolphinColumnView* columnView,
- const KUrl& url);
- virtual ~ColumnWidget();
-
- /** Sets the size of the icons. */
- void setDecorationSize(const QSize& size);
-
- /**
- * An active column is defined as column, which shows the same URL
- * as indicated by the URL navigator. The active column is usually
- * drawn in a lighter color. All operations are applied to this column.
- */
- void setActive(bool active);
- inline bool isActive() const;
-
- inline const KUrl& url() const;
-
- /**
- * Obtains the selection model from the column view. This assures that
- * selections of the column view will always applied to the active column.
- */
- void obtainSelectionModel();
-
- /**
- * Releases the selection model from the column view and replaces it by
- * a custom selection model.
- */
- void releaseSelectionModel();
-
-protected:
- virtual QStyleOptionViewItem viewOptions() const;
- virtual void dragEnterEvent(QDragEnterEvent* event);
- virtual void dragLeaveEvent(QDragLeaveEvent* event);
- virtual void dragMoveEvent(QDragMoveEvent* event);
- virtual void dropEvent(QDropEvent* event);
- virtual void mousePressEvent(QMouseEvent* event);
- virtual void mouseMoveEvent(QMouseEvent* event);
- virtual void mouseReleaseEvent(QMouseEvent* event);
- virtual void paintEvent(QPaintEvent* event);
- virtual void contextMenuEvent(QContextMenuEvent* event);
-
-protected slots:
- virtual void selectionChanged(const QItemSelection& selected, const QItemSelection& deselected);
-
-private:
- /** Used by ColumnWidget::setActive(). */
- void activate();
-
- /** Used by ColumnWidget::setActive(). */
- void deactivate();
-
-private:
- bool m_active;
- bool m_swallowMouseMoveEvents;
- DolphinColumnView* m_view;
- KUrl m_url;
- KUrl m_childUrl; // URL of the next column that is shown
- QStyleOptionViewItem m_viewOptions;
-
- bool m_dragging; // TODO: remove this property when the issue #160611 is solved in Qt 4.4
- QRect m_dropRect; // TODO: remove this property when the issue #160611 is solved in Qt 4.4
-};
-
-ColumnWidget::ColumnWidget(QWidget* parent,
- DolphinColumnView* columnView,
- const KUrl& url) :
+DolphinColumnView::DolphinColumnView(QWidget* parent,
+ DolphinColumnViewContainer* container,
+ const KUrl& url) :
QListView(parent),
- m_active(true),
- m_swallowMouseMoveEvents(false),
- m_view(columnView),
+ m_active(false),
+ m_container(container),
+ m_extensionsFactory(0),
m_url(url),
m_childUrl(),
- m_dragging(false),
+ m_font(),
+ m_decorationSize(),
+ m_dirLister(0),
+ m_dolphinModel(0),
+ m_proxyModel(0),
m_dropRect()
{
setMouseTracking(true);
- viewport()->setAttribute(Qt::WA_Hover);
+ setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ setSelectionBehavior(SelectItems);
+ setSelectionMode(QAbstractItemView::ExtendedSelection);
+ setDragDropMode(QAbstractItemView::DragDrop);
+ setDropIndicatorShown(false);
+ setSelectionRectVisible(true);
+ setEditTriggers(QAbstractItemView::NoEditTriggers);
+
+ setVerticalScrollMode(QListView::ScrollPerPixel);
+ setHorizontalScrollMode(QListView::ScrollPerPixel);
// apply the column mode settings to the widget
const ColumnModeSettings* settings = DolphinSettings::instance().columnModeSettings();
Q_ASSERT(settings != 0);
- m_viewOptions = QListView::viewOptions();
+ if (settings->useSystemFont()) {
+ m_font = KGlobalSettings::generalFont();
+ } else {
+ m_font = QFont(settings->fontFamily(),
+ settings->fontSize(),
+ settings->fontWeight(),
+ settings->italicFont());
+ }
- QFont font(settings->fontFamily(), settings->fontSize());
- font.setItalic(settings->italicFont());
- font.setBold(settings->boldFont());
- m_viewOptions.font = font;
+ activate();
- const int iconSize = settings->iconSize();
- m_viewOptions.decorationSize = QSize(iconSize, iconSize);
+ connect(this, SIGNAL(viewportEntered()),
+ m_container->m_controller, SLOT(emitViewportEntered()));
+ connect(this, SIGNAL(entered(const QModelIndex&)),
+ this, SLOT(slotEntered(const QModelIndex&)));
- activate();
-}
+ const DolphinView* dolphinView = m_container->m_controller->dolphinView();
+ connect(dolphinView, SIGNAL(showPreviewChanged()),
+ this, SLOT(slotShowPreviewChanged()));
-ColumnWidget::~ColumnWidget()
-{
+ m_dirLister = new DolphinDirLister();
+ m_dirLister->setAutoUpdate(true);
+ m_dirLister->setMainWindow(window());
+ m_dirLister->setDelayedMimeTypes(true);
+ const bool showHiddenFiles = m_container->m_controller->dolphinView()->showHiddenFiles();
+ m_dirLister->setShowingDotFiles(showHiddenFiles);
+
+ m_dolphinModel = new DolphinModel(this);
+ m_dolphinModel->setDirLister(m_dirLister);
+ m_dolphinModel->setDropsAllowed(DolphinModel::DropOnDirectory);
+
+ m_proxyModel = new DolphinSortFilterProxyModel(this);
+ m_proxyModel->setSourceModel(m_dolphinModel);
+ m_proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
+
+ m_proxyModel->setSorting(dolphinView->sorting());
+ m_proxyModel->setSortOrder(dolphinView->sortOrder());
+ m_proxyModel->setSortFoldersFirst(dolphinView->sortFoldersFirst());
+
+ setModel(m_proxyModel);
+
+ 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_container->m_controller, SLOT(triggerItem(const QModelIndex&)));
+
+ new VersionControlObserver(this);*/
+
+ DolphinController* controller = m_container->m_controller;
+ connect(controller, SIGNAL(zoomLevelChanged(int)),
+ this, SLOT(setZoomLevel(int)));
+
+ const QString nameFilter = controller->nameFilter();
+ if (!nameFilter.isEmpty()) {
+ m_proxyModel->setFilterRegExp(nameFilter);
+ }
+
+ updateDecorationSize(dolphinView->showPreview());
+ m_extensionsFactory = new ViewExtensionsFactory(this, controller);
}
-void ColumnWidget::setDecorationSize(const QSize& size)
+DolphinColumnView::~DolphinColumnView()
{
- m_viewOptions.decorationSize = size;
- doItemsLayout();
+ delete m_proxyModel;
+ m_proxyModel = 0;
+ delete m_dolphinModel;
+ m_dolphinModel = 0;
+ m_dirLister = 0; // deleted by m_dolphinModel
}
-void ColumnWidget::setActive(bool active)
+void DolphinColumnView::setActive(bool active)
{
- if (active) {
- obtainSelectionModel();
- } else {
- releaseSelectionModel();
+ if (active && (m_container->focusProxy() != this)) {
+ m_container->setFocusProxy(this);
}
- if (m_active == active) {
- return;
- }
+ if (m_active != active) {
+ m_active = active;
- m_active = active;
-
- if (active) {
- activate();
- } else {
- deactivate();
+ if (active) {
+ activate();
+ } else {
+ deactivate();
+ }
}
}
-inline bool ColumnWidget::isActive() const
+void DolphinColumnView::updateBackground()
{
- return m_active;
-}
+ // TODO: The alpha-value 150 is copied from DolphinView::setActive(). When
+ // cleaning up the cut-indication of DolphinColumnView with the code from
+ // DolphinView a common helper-class should be available which can be shared
+ // by all view implementations -> no hardcoded value anymore
+ const QPalette::ColorRole role = viewport()->backgroundRole();
+ QColor color = viewport()->palette().color(role);
+ color.setAlpha((m_active && m_container->m_active) ? 255 : 150);
-const KUrl& ColumnWidget::url() const
-{
- return m_url;
+ QPalette palette = viewport()->palette();
+ palette.setColor(role, color);
+ viewport()->setPalette(palette);
+
+ update();
}
-void ColumnWidget::obtainSelectionModel()
+KFileItem DolphinColumnView::itemAt(const QPoint& pos) const
{
- if (selectionModel() != m_view->selectionModel()) {
- selectionModel()->deleteLater();
- setSelectionModel(m_view->selectionModel());
- clearSelection();
+ KFileItem item;
+ const QModelIndex index = indexAt(pos);
+ if (index.isValid() && (index.column() == DolphinModel::Name)) {
+ const QModelIndex dolphinModelIndex = m_proxyModel->mapToSource(index);
+ item = m_dolphinModel->itemForIndex(dolphinModelIndex);
}
+ return item;
}
-void ColumnWidget::releaseSelectionModel()
+QStyleOptionViewItem DolphinColumnView::viewOptions() const
{
- if (selectionModel() == m_view->selectionModel()) {
- QItemSelectionModel* replacementModel = new QItemSelectionModel(model());
- setSelectionModel(replacementModel);
- }
+ QStyleOptionViewItem viewOptions = QListView::viewOptions();
+ viewOptions.font = m_font;
+ viewOptions.decorationSize = m_decorationSize;
+ viewOptions.showDecorationSelected = true;
+ return viewOptions;
}
-QStyleOptionViewItem ColumnWidget::viewOptions() const
+void DolphinColumnView::startDrag(Qt::DropActions supportedActions)
{
- return m_viewOptions;
+ DragAndDropHelper::instance().startDrag(this, supportedActions, m_container->m_controller);
}
-void ColumnWidget::dragEnterEvent(QDragEnterEvent* event)
+void DolphinColumnView::dragEnterEvent(QDragEnterEvent* event)
{
- if (event->mimeData()->hasUrls()) {
+ if (DragAndDropHelper::instance().isMimeDataSupported(event->mimeData())) {
event->acceptProposedAction();
+ requestActivation();
}
-
- m_dragging = true;
}
-void ColumnWidget::dragLeaveEvent(QDragLeaveEvent* event)
+void DolphinColumnView::dragLeaveEvent(QDragLeaveEvent* event)
{
QListView::dragLeaveEvent(event);
-
- // TODO: remove this code when the issue #160611 is solved in Qt 4.4
- m_dragging = false;
setDirtyRegion(m_dropRect);
}
-void ColumnWidget::dragMoveEvent(QDragMoveEvent* event)
+void DolphinColumnView::dragMoveEvent(QDragMoveEvent* event)
{
QListView::dragMoveEvent(event);
// TODO: remove this code when the issue #160611 is solved in Qt 4.4
const QModelIndex index = indexAt(event->pos());
setDirtyRegion(m_dropRect);
- m_dropRect = visualRect(index);
- setDirtyRegion(m_dropRect);
-}
-
-void ColumnWidget::dropEvent(QDropEvent* event)
-{
- const KUrl::List urls = KUrl::List::fromMimeData(event->mimeData());
- if (!urls.isEmpty()) {
- event->acceptProposedAction();
- m_view->m_controller->indicateDroppedUrls(urls,
- indexAt(event->pos()),
- event->source());
- }
- QListView::dropEvent(event);
- m_dragging = false;
-}
-void ColumnWidget::mousePressEvent(QMouseEvent* event)
-{
- // On each mouse press event QColumnView triggers the loading of the
- // current folder in the next column. This is not wanted for Dolphin when
- // opening a context menu or when the CTRL modifier is pressed. Beside usability
- // aspects the loading of the folder also implies losing the current selection,
- // which makes it impossible to select folders from the current column. To bypass
- // this behavior QListView::mousePressEvent() is not invoked in those cases, which
- // is not a nice solution. Maybe another solution can be found in future versions
- // of QColumnView.
-
- m_view->requestSelectionModel(this);
-
- bool swallowMousePressEvent = false;
- const QModelIndex index = indexAt(event->pos());
+ m_dropRect.setSize(QSize()); // set as invalid
if (index.isValid()) {
- // a click on an item has been done
- const QAbstractProxyModel* proxyModel = static_cast<const QAbstractProxyModel*>(m_view->model());
- const KDirModel* dirModel = static_cast<const KDirModel*>(proxyModel->sourceModel());
- const QModelIndex dirIndex = proxyModel->mapToSource(index);
- KFileItem item = dirModel->itemForIndex(dirIndex);
- if (!item.isNull()) {
- QItemSelectionModel* selModel = selectionModel();
-
- bool activate = true;
- const Qt::KeyboardModifiers modifier = QApplication::keyboardModifiers();
- if (modifier & Qt::ControlModifier) {
- m_view->requestActivation(this);
- if (!selModel->hasSelection()) {
- // Assure to set the current index, so that a selection by the SHIFT key
- // will work. TODO: If the index specifies a folder, the loading of the folder will
- // be triggered by QColumnView although this is not wanted by Dolphin.
- selModel->setCurrentIndex(index, QItemSelectionModel::Select);
- }
- selModel->select(index, QItemSelectionModel::Toggle);
- swallowMousePressEvent = true;
- } else if (item.isDir()) {
- m_childUrl = item.url();
- viewport()->update();
-
- // Only request the activation if not the left button is pressed.
- // The left button on a directory opens a new column, hence requesting
- // an activation is useless as the new column will request the activation
- // afterwards.
- if (event->button() == Qt::LeftButton) {
- activate = false;
- }
- }
-
- if (activate) {
- m_view->requestActivation(this);
- }
-
- // TODO: is the assumption OK that Qt::RightButton always represents the context menu button?
- if (event->button() == Qt::RightButton) {
- swallowMousePressEvent = true;
- if (!selModel->isSelected(index)) {
- clearSelection();
- }
- selModel->select(index, QItemSelectionModel::Select);
- }
+ m_container->m_controller->setItemView(this);
+ const KFileItem item = m_container->m_controller->itemForIndex(index);
+ if (!item.isNull() && item.isDir()) {
+ m_dropRect = visualRect(index);
}
- } else {
- // a click on the viewport has been done
- m_view->requestActivation(this);
-
- // Swallow mouse move events if a click is done on the viewport. Otherwise the QColumnView
- // triggers an unwanted loading of directories on hovering folder items.
- m_swallowMouseMoveEvents = true;
- clearSelection();
- }
-
- if (!swallowMousePressEvent) {
- QListView::mousePressEvent(event);
}
-}
+ setDirtyRegion(m_dropRect);
-void ColumnWidget::mouseMoveEvent(QMouseEvent* event)
-{
- // see description in ColumnView::mousePressEvent()
- if (!m_swallowMouseMoveEvents) {
- QListView::mouseMoveEvent(event);
+ if (DragAndDropHelper::instance().isMimeDataSupported(event->mimeData())) {
+ // accept url drops, independently from the destination item
+ event->acceptProposedAction();
}
}
-void ColumnWidget::mouseReleaseEvent(QMouseEvent* event)
+void DolphinColumnView::dropEvent(QDropEvent* event)
{
- QListView::mouseReleaseEvent(event);
- m_swallowMouseMoveEvents = false;
+ const QModelIndex index = indexAt(event->pos());
+ m_container->m_controller->setItemView(this);
+ const KFileItem item = m_container->m_controller->itemForIndex(index);
+ m_container->m_controller->indicateDroppedUrls(item, url(), event);
+ QListView::dropEvent(event);
}
-
-void ColumnWidget::paintEvent(QPaintEvent* event)
+void DolphinColumnView::paintEvent(QPaintEvent* event)
{
if (!m_childUrl.isEmpty()) {
// indicate the shown URL of the next column by highlighting the shown folder item
- const QAbstractProxyModel* proxyModel = static_cast<const QAbstractProxyModel*>(m_view->model());
- const KDirModel* dirModel = static_cast<const KDirModel*>(proxyModel->sourceModel());
- const QModelIndex dirIndex = dirModel->indexForUrl(m_childUrl);
- const QModelIndex proxyIndex = proxyModel->mapFromSource(dirIndex);
+ const QModelIndex dirIndex = m_dolphinModel->indexForUrl(m_childUrl);
+ const QModelIndex proxyIndex = m_proxyModel->mapFromSource(dirIndex);
if (proxyIndex.isValid() && !selectionModel()->isSelected(proxyIndex)) {
const QRect itemRect = visualRect(proxyIndex);
QPainter painter(viewport());
- painter.save();
-
- QColor color = KColorScheme(KColorScheme::View).foreground();
+ QColor color = KColorScheme(QPalette::Active, KColorScheme::View).foreground().color();
color.setAlpha(32);
painter.setPen(Qt::NoPen);
painter.setBrush(color);
painter.drawRect(itemRect);
-
- painter.restore();
}
}
QListView::paintEvent(event);
+}
- // TODO: remove this code when the issue #160611 is solved in Qt 4.4
- if (m_dragging) {
- const QBrush& brush = m_viewOptions.palette.brush(QPalette::Normal, QPalette::Highlight);
- DolphinController::drawHoverIndication(viewport(), m_dropRect, brush);
+void DolphinColumnView::mousePressEvent(QMouseEvent* event)
+{
+ requestActivation();
+ if (!indexAt(event->pos()).isValid()) {
+ if (QApplication::mouseButtons() & Qt::MidButton) {
+ m_container->m_controller->replaceUrlByClipboard();
+ }
+ } else if (event->button() == Qt::LeftButton) {
+ // TODO: see comment in DolphinIconsView::mousePressEvent()
+ setState(QAbstractItemView::DraggingState);
}
+ QListView::mousePressEvent(event);
}
-void ColumnWidget::contextMenuEvent(QContextMenuEvent* event)
+void DolphinColumnView::keyPressEvent(QKeyEvent* event)
{
- if (!m_active) {
- m_view->requestActivation(this);
+ QListView::keyPressEvent(event);
+ requestActivation();
+
+ DolphinController* controller = m_container->m_controller;
+ controller->handleKeyPressEvent(event);
+ switch (event->key()) {
+ case Qt::Key_Right: {
+ // Special key handling for the column: A Key_Right should
+ // open a new column for the currently selected folder.
+ const QModelIndex index = currentIndex();
+ const KFileItem item = controller->itemForIndex(index);
+ if (!item.isNull() && item.isDir()) {
+ controller->emitItemTriggered(item);
+ }
+ break;
}
- QListView::contextMenuEvent(event);
+ case Qt::Key_Escape:
+ selectionModel()->setCurrentIndex(selectionModel()->currentIndex(),
+ QItemSelectionModel::Current |
+ QItemSelectionModel::Clear);
+ break;
- const QModelIndex index = indexAt(event->pos());
- if (index.isValid() || m_active) {
- // Only open a context menu above an item or if the mouse is above
- // the active column.
- const QPoint pos = m_view->viewport()->mapFromGlobal(event->globalPos());
- m_view->m_controller->triggerContextMenuRequest(pos);
+ default:
+ break;
}
}
-void ColumnWidget::selectionChanged(const QItemSelection& selected, const QItemSelection& deselected)
+void DolphinColumnView::contextMenuEvent(QContextMenuEvent* event)
{
- // inactive views should not have any selection
if (!m_active) {
- clearSelection();
+ m_container->requestActivation(this);
+ Q_ASSERT(m_container->m_controller->itemView() == this);
+ m_container->m_controller->triggerUrlChangeRequest(m_url);
}
- QListView::selectionChanged(selected, deselected);
-}
-
-void ColumnWidget::activate()
-{
- const QColor bgColor = KColorScheme(KColorScheme::View).background();
- QPalette palette = viewport()->palette();
- palette.setColor(viewport()->backgroundRole(), bgColor);
- viewport()->setPalette(palette);
+ Q_ASSERT(m_active);
- update();
+ QListView::contextMenuEvent(event);
+ m_container->m_controller->triggerContextMenuRequest(event->pos());
}
-void ColumnWidget::deactivate()
+void DolphinColumnView::wheelEvent(QWheelEvent* event)
{
- QColor bgColor = KColorScheme(KColorScheme::View).background();
- const QColor fgColor = KColorScheme(KColorScheme::View).foreground();
- bgColor = KColorUtils::mix(bgColor, fgColor, 0.04);
+ // let Ctrl+wheel events propagate to the DolphinView for icon zooming
+ if (event->modifiers() & Qt::ControlModifier) {
+ event->ignore();
+ return;
+ }
- QPalette palette = viewport()->palette();
- palette.setColor(viewport()->backgroundRole(), bgColor);
- viewport()->setPalette(palette);
+ const int height = m_decorationSize.height();
+ const int step = (height >= KIconLoader::SizeHuge) ? height / 10 : (KIconLoader::SizeHuge - height) / 2;
+ verticalScrollBar()->setSingleStep(step);
- update();
+ QListView::wheelEvent(event);
}
-// ---
-
-DolphinColumnView::DolphinColumnView(QWidget* parent, DolphinController* controller) :
- QColumnView(parent),
- m_controller(controller)
+void DolphinColumnView::leaveEvent(QEvent* event)
{
- Q_ASSERT(controller != 0);
-
- setAcceptDrops(true);
- setDragDropMode(QAbstractItemView::DragDrop);
- setDropIndicatorShown(false);
- setSelectionMode(ExtendedSelection);
-
- if (KGlobalSettings::singleClick()) {
- connect(this, SIGNAL(clicked(const QModelIndex&)),
- this, SLOT(triggerItem(const QModelIndex&)));
- } else {
- connect(this, SIGNAL(doubleClicked(const QModelIndex&)),
- this, SLOT(triggerItem(const QModelIndex&)));
- }
- connect(this, SIGNAL(entered(const QModelIndex&)),
- controller, SLOT(emitItemEntered(const QModelIndex&)));
- connect(this, SIGNAL(viewportEntered()),
- controller, SLOT(emitViewportEntered()));
- connect(controller, SIGNAL(zoomIn()),
- this, SLOT(zoomIn()));
- connect(controller, SIGNAL(zoomOut()),
- this, SLOT(zoomOut()));
- connect(controller, SIGNAL(urlChanged(const KUrl&)),
- this, SLOT(updateColumnsState(const KUrl&)));
-
- updateDecorationSize();
+ QListView::leaveEvent(event);
+ // if the mouse is above an item and moved very fast outside the widget,
+ // no viewportEntered() signal might be emitted although the mouse has been moved
+ // above the viewport
+ m_container->m_controller->emitViewportEntered();
}
-DolphinColumnView::~DolphinColumnView()
+void DolphinColumnView::selectionChanged(const QItemSelection& selected, const QItemSelection& deselected)
{
-}
+ QListView::selectionChanged(selected, deselected);
-void DolphinColumnView::invertSelection()
-{
- selectActiveColumn(QItemSelectionModel::Toggle);
+ //QItemSelectionModel* selModel = m_container->selectionModel();
+ //selModel->select(selected, QItemSelectionModel::Select);
+ //selModel->select(deselected, QItemSelectionModel::Deselect);
}
-void DolphinColumnView::selectAll()
+void DolphinColumnView::currentChanged(const QModelIndex& current, const QModelIndex& previous)
{
- selectActiveColumn(QItemSelectionModel::Select);
+ QListView::currentChanged(current, previous);
+ m_extensionsFactory->handleCurrentIndexChange(current, previous);
}
-QAbstractItemView* DolphinColumnView::createColumn(const QModelIndex& index)
+void DolphinColumnView::setZoomLevel(int level)
{
- // let the column widget be aware about its URL...
- KUrl columnUrl;
- if (viewport()->children().count() == 0) {
- // For the first column widget the directory lister has not been started
- // yet, hence use the URL from the controller instead.
- columnUrl = m_controller->url();
- } else {
- const QAbstractProxyModel* proxyModel = static_cast<const QAbstractProxyModel*>(model());
- const KDirModel* dirModel = static_cast<const KDirModel*>(proxyModel->sourceModel());
-
- const QModelIndex dirModelIndex = proxyModel->mapToSource(index);
- KFileItem fileItem = dirModel->itemForIndex(dirModelIndex);
- if (!fileItem.isNull()) {
- columnUrl = fileItem.url();
- }
- }
+ const int size = ZoomLevelInfo::iconSizeForZoomLevel(level);
+ ColumnModeSettings* settings = DolphinSettings::instance().columnModeSettings();
- ColumnWidget* view = new ColumnWidget(viewport(), this, columnUrl);
-
- // The following code has been copied 1:1 from QColumnView::createColumn().
- // Copyright (C) 1992-2007 Trolltech ASA. In Qt 4.4 the new method
- // QColumnView::initializeColumn() will be available for this.
-
- view->setFrameShape(QFrame::NoFrame);
- view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
- view->setMinimumWidth(100);
- view->setAttribute(Qt::WA_MacShowFocusRect, false);
-
- // copy the 'view' behavior
- view->setDragDropMode(dragDropMode());
- view->setDragDropOverwriteMode(dragDropOverwriteMode());
- view->setDropIndicatorShown(showDropIndicator());
- view->setAlternatingRowColors(alternatingRowColors());
- view->setAutoScroll(hasAutoScroll());
- view->setEditTriggers(editTriggers());
- view->setHorizontalScrollMode(horizontalScrollMode());
- view->setIconSize(iconSize());
- view->setSelectionBehavior(selectionBehavior());
- view->setSelectionMode(selectionMode());
- view->setTabKeyNavigation(tabKeyNavigation());
- view->setTextElideMode(textElideMode());
- view->setVerticalScrollMode(verticalScrollMode());
-
- view->setModel(model());
-
- // set the delegate to be the columnview delegate
- QAbstractItemDelegate* delegate = view->itemDelegate();
- view->setItemDelegate(itemDelegate());
- delete delegate;
-
- view->setRootIndex(index);
-
- if (model()->canFetchMore(index)) {
- model()->fetchMore(index);
+ const bool showPreview = m_container->m_controller->dolphinView()->showPreview();
+ if (showPreview) {
+ settings->setPreviewSize(size);
+ } else {
+ settings->setIconSize(size);
}
- return view;
+ updateDecorationSize(showPreview);
}
-void DolphinColumnView::mousePressEvent(QMouseEvent* event)
+void DolphinColumnView::slotEntered(const QModelIndex& index)
{
- m_controller->triggerActivation();
- QColumnView::mousePressEvent(event);
+ m_container->m_controller->setItemView(this);
+ m_container->m_controller->emitItemEntered(index);
}
-void DolphinColumnView::dragEnterEvent(QDragEnterEvent* event)
+void DolphinColumnView::requestActivation()
{
- if (event->mimeData()->hasUrls()) {
- event->acceptProposedAction();
+ m_container->m_controller->setItemView(this);
+ m_container->m_controller->requestActivation();
+ if (!m_active) {
+ m_container->requestActivation(this);
+ m_container->m_controller->triggerUrlChangeRequest(m_url);
+ selectionModel()->clear();
}
}
-void DolphinColumnView::dropEvent(QDropEvent* event)
+void DolphinColumnView::updateFont()
{
- const KUrl::List urls = KUrl::List::fromMimeData(event->mimeData());
- if (!urls.isEmpty()) {
- m_controller->indicateDroppedUrls(urls,
- indexAt(event->pos()),
- event->source());
- event->acceptProposedAction();
- }
- QColumnView::dropEvent(event);
-}
+ const ColumnModeSettings* settings = DolphinSettings::instance().columnModeSettings();
+ Q_ASSERT(settings != 0);
-void DolphinColumnView::zoomIn()
-{
- if (isZoomInPossible()) {
- ColumnModeSettings* settings = DolphinSettings::instance().columnModeSettings();
- // TODO: get rid of K3Icon sizes
- switch (settings->iconSize()) {
- case K3Icon::SizeSmall: settings->setIconSize(K3Icon::SizeMedium); break;
- case K3Icon::SizeMedium: settings->setIconSize(K3Icon::SizeLarge); break;
- default: Q_ASSERT(false); break;
- }
- updateDecorationSize();
+ if (settings->useSystemFont()) {
+ m_font = KGlobalSettings::generalFont();
}
}
-void DolphinColumnView::zoomOut()
+void DolphinColumnView::slotShowPreviewChanged()
{
- if (isZoomOutPossible()) {
- ColumnModeSettings* settings = DolphinSettings::instance().columnModeSettings();
- // TODO: get rid of K3Icon sizes
- switch (settings->iconSize()) {
- case K3Icon::SizeLarge: settings->setIconSize(K3Icon::SizeMedium); break;
- case K3Icon::SizeMedium: settings->setIconSize(K3Icon::SizeSmall); break;
- default: Q_ASSERT(false); break;
- }
- updateDecorationSize();
- }
+ const DolphinView* view = m_container->m_controller->dolphinView();
+ updateDecorationSize(view->showPreview());
}
-void DolphinColumnView::triggerItem(const QModelIndex& index)
+void DolphinColumnView::activate()
{
- m_controller->triggerItem(index);
- updateColumnsState(m_controller->url());
-}
+ setFocus(Qt::OtherFocusReason);
-void DolphinColumnView::updateColumnsState(const KUrl& url)
-{
- foreach (QObject* object, viewport()->children()) {
- if (object->inherits("QListView")) {
- ColumnWidget* widget = static_cast<ColumnWidget*>(object);
- widget->setActive(widget->url() == url);
- }
+ if (KGlobalSettings::singleClick()) {
+ connect(this, SIGNAL(clicked(const QModelIndex&)),
+ m_container->m_controller, SLOT(triggerItem(const QModelIndex&)));
+ } else {
+ connect(this, SIGNAL(doubleClicked(const QModelIndex&)),
+ m_container->m_controller, SLOT(triggerItem(const QModelIndex&)));
}
-}
-
-
-void DolphinColumnView::updateDecorationSize()
-{
- ColumnModeSettings* settings = DolphinSettings::instance().columnModeSettings();
- const int iconSize = settings->iconSize();
- foreach (QObject* object, viewport()->children()) {
- if (object->inherits("QListView")) {
- ColumnWidget* widget = static_cast<ColumnWidget*>(object);
- widget->setDecorationSize(QSize(iconSize, iconSize));
- }
+ if (selectionModel() && selectionModel()->currentIndex().isValid()) {
+ selectionModel()->setCurrentIndex(selectionModel()->currentIndex(), QItemSelectionModel::SelectCurrent);
}
- m_controller->setZoomInPossible(isZoomInPossible());
- m_controller->setZoomOutPossible(isZoomOutPossible());
-
- doItemsLayout();
-}
-
-bool DolphinColumnView::isZoomInPossible() const
-{
- ColumnModeSettings* settings = DolphinSettings::instance().columnModeSettings();
- return settings->iconSize() < K3Icon::SizeLarge;
-}
-
-bool DolphinColumnView::isZoomOutPossible() const
-{
- ColumnModeSettings* settings = DolphinSettings::instance().columnModeSettings();
- return settings->iconSize() > K3Icon::SizeSmall;
+ updateBackground();
}
-void DolphinColumnView::requestActivation(QWidget* column)
+void DolphinColumnView::deactivate()
{
- foreach (QObject* object, viewport()->children()) {
- if (object->inherits("QListView")) {
- ColumnWidget* widget = static_cast<ColumnWidget*>(object);
- const bool isActive = (widget == column);
- widget->setActive(isActive);
- if (isActive) {
- m_controller->setUrl(widget->url());
- }
- }
+ clearFocus();
+ if (KGlobalSettings::singleClick()) {
+ disconnect(this, SIGNAL(clicked(const QModelIndex&)),
+ m_container->m_controller, SLOT(triggerItem(const QModelIndex&)));
+ } else {
+ disconnect(this, SIGNAL(doubleClicked(const QModelIndex&)),
+ m_container->m_controller, SLOT(triggerItem(const QModelIndex&)));
}
-}
-void DolphinColumnView::requestSelectionModel(QAbstractItemView* view)
-{
- foreach (QObject* object, viewport()->children()) {
- if (object->inherits("QListView")) {
- ColumnWidget* widget = static_cast<ColumnWidget*>(object);
- if (widget == view) {
- widget->obtainSelectionModel();
- } else {
- widget->releaseSelectionModel();
- }
- }
- }
+ const QModelIndex current = selectionModel()->currentIndex();
+ selectionModel()->clear();
+ selectionModel()->setCurrentIndex(current, QItemSelectionModel::NoUpdate);
+ updateBackground();
}
-void DolphinColumnView::selectActiveColumn(QItemSelectionModel::SelectionFlags flags)
+void DolphinColumnView::updateDecorationSize(bool showPreview)
{
- // TODO: this approach of selecting the active column is very slow. It should be
- // possible to speedup the implementation by using QItemSelection, but all adempts
- // have failed yet...
-
- // assure that the selection model of the active column is set properly, otherwise
- // no visual update of the selections is done
- const KUrl& activeUrl = m_controller->url();
- foreach (QObject* object, viewport()->children()) {
- if (object->inherits("QListView")) {
- ColumnWidget* widget = static_cast<ColumnWidget*>(object);
- if (widget->url() == activeUrl) {
- widget->obtainSelectionModel();
- } else {
- widget->releaseSelectionModel();
- }
- }
- }
-
- QItemSelectionModel* selModel = selectionModel();
+ ColumnModeSettings* settings = DolphinSettings::instance().columnModeSettings();
+ const int iconSize = showPreview ? settings->previewSize() : settings->iconSize();
+ const QSize size(iconSize, iconSize);
+ setIconSize(size);
- const QAbstractProxyModel* proxyModel = static_cast<const QAbstractProxyModel*>(model());
- const KDirModel* dirModel = static_cast<const KDirModel*>(proxyModel->sourceModel());
- KDirLister* dirLister = dirModel->dirLister();
+ m_decorationSize = size;
- const KFileItemList list = dirLister->itemsForDir(activeUrl);
- foreach (KFileItem* item, list) {
- const QModelIndex index = dirModel->indexForUrl(item->url());
- selModel->select(proxyModel->mapFromSource(index), flags);
- }
+ doItemsLayout();
}
#include "dolphincolumnview.moc"