X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/81fcd720a2cc095262e52b8a40dd1472d774a415..647e1469b51fbdaf3cf52ea7e6b81048cce3d3fc:/src/dolphincolumnview.cpp diff --git a/src/dolphincolumnview.cpp b/src/dolphincolumnview.cpp index e4669442c..2d3bcb826 100644 --- a/src/dolphincolumnview.cpp +++ b/src/dolphincolumnview.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2007 by Peter Penz * + * Copyright (C) 2007-2009 by Peter Penz * * * * 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 * @@ -19,710 +19,458 @@ #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 #include #include -#include +#include +#include +#include +#include +#include -#include #include +#include +#include #include +#include -/* - * 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(m_view->model()); - const KDirModel* dirModel = static_cast(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(m_view->model()); - const KDirModel* dirModel = static_cast(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(model()); - const KDirModel* dirModel = static_cast(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(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(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(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(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(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(model()); - const KDirModel* dirModel = static_cast(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"