diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/dolphincolumnview.cpp | 501 | ||||
| -rw-r--r-- | src/dolphincolumnview.h | 38 | ||||
| -rw-r--r-- | src/dolphincolumnwidget.cpp | 446 | ||||
| -rw-r--r-- | src/dolphincolumnwidget.h | 177 | ||||
| -rw-r--r-- | src/dolphincontroller.cpp | 13 | ||||
| -rw-r--r-- | src/dolphincontroller.h | 19 | ||||
| -rw-r--r-- | src/dolphindetailsview.cpp | 27 | ||||
| -rw-r--r-- | src/dolphindetailsview.h | 2 | ||||
| -rw-r--r-- | src/dolphiniconsview.cpp | 16 | ||||
| -rw-r--r-- | src/dolphiniconsview.h | 1 | ||||
| -rw-r--r-- | src/dolphinview.cpp | 72 | ||||
| -rw-r--r-- | src/dolphinview.h | 9 | ||||
| -rw-r--r-- | src/dolphinviewcontainer.cpp | 3 |
14 files changed, 759 insertions, 566 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1405bf859..c06684d9c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,6 +12,7 @@ set(dolphinprivate_LIB_SRCS dolphindetailsview.cpp dolphiniconsview.cpp dolphincolumnview.cpp + dolphincolumnwidget.cpp kcategorizedview.cpp kcategorydrawer.cpp dolphinmodel.cpp diff --git a/src/dolphincolumnview.cpp b/src/dolphincolumnview.cpp index 0f4c962ac..b8be24bf0 100644 --- a/src/dolphincolumnview.cpp +++ b/src/dolphincolumnview.cpp @@ -20,7 +20,11 @@ #include "dolphincolumnview.h" #include "dolphinmodel.h" +#include "dolphincolumnwidget.h" #include "dolphincontroller.h" +#include "dolphindirlister.h" +#include "dolphinmodel.h" +#include "dolphinsortfilterproxymodel.h" #include "dolphinsettings.h" #include "dolphin_columnmodesettings.h" @@ -36,363 +40,6 @@ #include <QTimer> #include <QTimeLine> -/** - * 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); - bool isActive() const; - - /** - * Sets the directory URL of the child column that is shown next to - * this column. This property is only used for a visual indication - * of the shown directory, it does not trigger a loading of the model. - */ - void setChildUrl(const KUrl& url); - const KUrl& childUrl() const; - - /** Sets the directory URL that is shown inside the column widget. */ - void setUrl(const KUrl& url); - - /** Returns the directory URL that is shown inside the column widget. */ - const KUrl& url() const; - -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 paintEvent(QPaintEvent* event); - virtual void mousePressEvent(QMouseEvent* event); - virtual void keyPressEvent(QKeyEvent* event); - virtual void contextMenuEvent(QContextMenuEvent* event); - 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; - DolphinColumnView* m_view; - KUrl m_url; // URL of the directory that is shown - 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) : - QListView(parent), - m_active(true), - m_view(columnView), - m_url(url), - m_childUrl(), - m_dragging(false), - m_dropRect() -{ - setMouseTracking(true); - viewport()->setAttribute(Qt::WA_Hover); - setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - setSelectionBehavior(SelectItems); - setSelectionMode(QAbstractItemView::ExtendedSelection); - setDragDropMode(QAbstractItemView::DragDrop); - setDropIndicatorShown(false); - setFocusPolicy(Qt::NoFocus); - -// TODO: Remove this check when 4.3.2 is released and KDE requires it... this -// check avoids a division by zero happening on versions before 4.3.1. -// Right now KDE in theory can be shipped with Qt 4.3.0 and above. -// ereslibre -#if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 2) || defined(QT_KDE_QT_COPY)) - setVerticalScrollMode(QListView::ScrollPerPixel); - setHorizontalScrollMode(QListView::ScrollPerPixel); -#endif - - // apply the column mode settings to the widget - const ColumnModeSettings* settings = DolphinSettings::instance().columnModeSettings(); - Q_ASSERT(settings != 0); - - m_viewOptions = QListView::viewOptions(); - - QFont font(settings->fontFamily(), settings->fontSize()); - font.setItalic(settings->italicFont()); - font.setBold(settings->boldFont()); - m_viewOptions.font = font; - - const int iconSize = settings->iconSize(); - m_viewOptions.decorationSize = QSize(iconSize, iconSize); - - m_viewOptions.showDecorationSelected = true; - - KFileItemDelegate* delegate = new KFileItemDelegate(this); - setItemDelegate(delegate); - - activate(); - - connect(this, SIGNAL(entered(const QModelIndex&)), - m_view->m_controller, SLOT(emitItemEntered(const QModelIndex&))); - connect(this, SIGNAL(viewportEntered()), - m_view->m_controller, SLOT(emitViewportEntered())); -} - -ColumnWidget::~ColumnWidget() -{ -} - -void ColumnWidget::setDecorationSize(const QSize& size) -{ - m_viewOptions.decorationSize = size; - doItemsLayout(); -} - -void ColumnWidget::setActive(bool active) -{ - if (m_active == active) { - return; - } - - m_active = active; - - if (active) { - activate(); - } else { - deactivate(); - } -} - -inline bool ColumnWidget::isActive() const -{ - return m_active; -} - -inline void ColumnWidget::setChildUrl(const KUrl& url) -{ - m_childUrl = url; -} - -inline const KUrl& ColumnWidget::childUrl() const -{ - return m_childUrl; -} - -inline void ColumnWidget::setUrl(const KUrl& url) -{ - m_url = url; -} - -inline const KUrl& ColumnWidget::url() const -{ - return m_url; -} - -inline QStyleOptionViewItem ColumnWidget::viewOptions() const -{ - return m_viewOptions; -} - -void ColumnWidget::dragEnterEvent(QDragEnterEvent* event) -{ - if (event->mimeData()->hasUrls()) { - event->acceptProposedAction(); - } - - m_dragging = true; -} - -void ColumnWidget::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) -{ - 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, - url(), - indexAt(event->pos()), - event->source()); - } - QListView::dropEvent(event); - m_dragging = false; -} - -void ColumnWidget::paintEvent(QPaintEvent* event) -{ - if (!m_childUrl.isEmpty()) { - // indicate the shown URL of the next column by highlighting the shown folder item - const QModelIndex dirIndex = m_view->m_dolphinModel->indexForUrl(m_childUrl); - const QModelIndex proxyIndex = m_view->m_proxyModel->mapFromSource(dirIndex); - if (proxyIndex.isValid() && !selectionModel()->isSelected(proxyIndex)) { - const QRect itemRect = visualRect(proxyIndex); - QPainter painter(viewport()); - painter.save(); - - 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 ColumnWidget::mousePressEvent(QMouseEvent* event) -{ - if (!m_active) { - m_view->requestActivation(this); - } - - QListView::mousePressEvent(event); -} - -void ColumnWidget::keyPressEvent(QKeyEvent* event) -{ - QListView::keyPressEvent(event); - - const QItemSelectionModel* selModel = selectionModel(); - const QModelIndex currentIndex = selModel->currentIndex(); - const bool triggerItem = currentIndex.isValid() - && (event->key() == Qt::Key_Return) - && (selModel->selectedIndexes().count() <= 1); - if (triggerItem) { - m_view->m_controller->triggerItem(currentIndex); - } -} - -void ColumnWidget::contextMenuEvent(QContextMenuEvent* event) -{ - if (!m_active) { - m_view->requestActivation(this); - } - - QListView::contextMenuEvent(event); - - 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); - } -} - -void ColumnWidget::selectionChanged(const QItemSelection& selected, const QItemSelection& deselected) -{ - QListView::selectionChanged(selected, deselected); - - QItemSelectionModel* selModel = m_view->selectionModel(); - selModel->select(selected, QItemSelectionModel::Select); - selModel->select(deselected, QItemSelectionModel::Deselect); -} - -void ColumnWidget::activate() -{ - if (m_view->hasFocus()) { - setFocus(Qt::OtherFocusReason); - } - m_view->setFocusProxy(this); - - // TODO: Connecting to the signal 'activated()' is not possible, as kstyle - // does not forward the single vs. doubleclick to it yet (KDE 4.1?). Hence it is - // necessary connecting the signal 'singleClick()' or 'doubleClick'. - if (KGlobalSettings::singleClick()) { - connect(this, SIGNAL(clicked(const QModelIndex&)), - m_view->m_controller, SLOT(triggerItem(const QModelIndex&))); - } else { - connect(this, SIGNAL(doubleClicked(const QModelIndex&)), - m_view->m_controller, SLOT(triggerItem(const QModelIndex&))); - } - - const QColor bgColor = KColorScheme(QPalette::Active, KColorScheme::View).background().color(); - QPalette palette = viewport()->palette(); - palette.setColor(viewport()->backgroundRole(), bgColor); - viewport()->setPalette(palette); - - if (!m_childUrl.isEmpty()) { - // assure that the current index is set on the index that represents - // the child URL - const QModelIndex dirIndex = m_view->m_dolphinModel->indexForUrl(m_childUrl); - const QModelIndex proxyIndex = m_view->m_proxyModel->mapFromSource(dirIndex); - selectionModel()->setCurrentIndex(proxyIndex, QItemSelectionModel::Current); - } - - update(); -} - -void ColumnWidget::deactivate() -{ - // TODO: Connecting to the signal 'activated()' is not possible, as kstyle - // does not forward the single vs. doubleclick to it yet (KDE 4.1?). Hence it is - // necessary connecting the signal 'singleClick()' or 'doubleClick'. - if (KGlobalSettings::singleClick()) { - disconnect(this, SIGNAL(clicked(const QModelIndex&)), - m_view->m_controller, SLOT(triggerItem(const QModelIndex&))); - } else { - disconnect(this, SIGNAL(doubleClicked(const QModelIndex&)), - m_view->m_controller, SLOT(triggerItem(const QModelIndex&))); - } - - const QPalette palette = m_view->viewport()->palette(); - viewport()->setPalette(palette); - - selectionModel()->clear(); - update(); -} - -// --- - DolphinColumnView::DolphinColumnView(QWidget* parent, DolphinController* controller) : QAbstractItemView(parent), m_controller(controller), @@ -421,6 +68,10 @@ DolphinColumnView::DolphinColumnView(QWidget* parent, DolphinController* control this, SLOT(zoomOut())); connect(controller, SIGNAL(urlChanged(const KUrl&)), this, SLOT(showColumn(const KUrl&))); + connect(controller, SIGNAL(showHiddenFilesChanged(bool)), + this, SLOT(slotShowHiddenFilesChanged(bool))); + connect(controller, SIGNAL(showPreviewChanged(bool)), + this, SLOT(slotShowPreviewChanged(bool))); connect(horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(moveContentHorizontally(int))); @@ -428,7 +79,7 @@ DolphinColumnView::DolphinColumnView(QWidget* parent, DolphinController* control m_animation = new QTimeLine(500, this); connect(m_animation, SIGNAL(frameChanged(int)), horizontalScrollBar(), SLOT(setValue(int))); - ColumnWidget* column = new ColumnWidget(viewport(), this, m_controller->url()); + DolphinColumnWidget* column = new DolphinColumnWidget(viewport(), this, m_controller->url()); m_columns.append(column); setActiveColumnIndex(0); @@ -450,7 +101,7 @@ DolphinColumnView::~DolphinColumnView() QModelIndex DolphinColumnView::indexAt(const QPoint& point) const { - foreach (ColumnWidget* column, m_columns) { + foreach (DolphinColumnWidget* column, m_columns) { const QPoint topLeft = column->frameGeometry().topLeft(); const QPoint adjustedPoint(point.x() - topLeft.x(), point.y() - topLeft.y()); const QModelIndex index = column->indexAt(adjustedPoint); @@ -474,64 +125,29 @@ QRect DolphinColumnView::visualRect(const QModelIndex& index) const void DolphinColumnView::setModel(QAbstractItemModel* model) { - if (m_dolphinModel != 0) { - m_dolphinModel->disconnect(this); - } - m_proxyModel = static_cast<QAbstractProxyModel*>(model); m_dolphinModel = static_cast<DolphinModel*>(m_proxyModel->sourceModel()); - connect(m_dolphinModel, SIGNAL(expand(const QModelIndex&)), - this, SLOT(triggerReloadColumns(const QModelIndex&))); - - KDirLister* dirLister = m_dolphinModel->dirLister(); - connect(dirLister, SIGNAL(completed()), - this, SLOT(triggerExpandToActiveUrl())); - - activeColumn()->setModel(model); QAbstractItemView::setModel(model); } void DolphinColumnView::invertSelection() { - // TODO: this approach of inverting the selection is quite slow. It should - // be possible to speedup the implementation by using QItemSelection, but - // all adempts have failed yet... + QItemSelectionModel* selectionModel = activeColumn()->selectionModel(); + const QAbstractItemModel* itemModel = selectionModel->model(); - ColumnWidget* column = activeColumn(); - QItemSelectionModel* selModel = column->selectionModel(); + const QModelIndex topLeft = itemModel->index(0, 0); + const QModelIndex bottomRight = itemModel->index(itemModel->rowCount() - 1, + itemModel->columnCount() - 1); - KDirLister* dirLister = m_dolphinModel->dirLister(); - const KFileItemList list = dirLister->itemsForDir(column->url()); - foreach (const KFileItem item, list) { - const QModelIndex index = m_dolphinModel->indexForUrl(item.url()); - selModel->select(m_proxyModel->mapFromSource(index), QItemSelectionModel::Toggle); - } + const QItemSelection selection(topLeft, bottomRight); + selectionModel->select(selection, QItemSelectionModel::Toggle); } void DolphinColumnView::reload() { - // Due to the reloading of the model all columns will be reset to show - // the same content as the first column. As this is not wanted, all columns - // except of the first column are temporary hidden until the root index can - // be updated again. - m_restoreActiveColumnFocus = false; - QList<ColumnWidget*>::iterator start = m_columns.begin() + 1; - QList<ColumnWidget*>::iterator end = m_columns.end(); - for (QList<ColumnWidget*>::iterator it = start; it != end; ++it) { - ColumnWidget* column = (*it); - if (column->isActive() && column->hasFocus()) { - // because of hiding the column, it will lose the focus - // -> remember that the focus should be restored after reloading - m_restoreActiveColumnFocus = true; - } - column->hide(); + foreach (DolphinColumnWidget* column, m_columns) { + column->reload(); } - - // all columns are hidden, now reload the directory lister - KDirLister* dirLister = m_dolphinModel->dirLister(); - const KUrl& rootUrl = m_columns[0]->url(); - dirLister->openUrl(rootUrl, KDirLister::Reload); - updateColumns(); } void DolphinColumnView::showColumn(const KUrl& url) @@ -540,9 +156,9 @@ void DolphinColumnView::showColumn(const KUrl& url) if (!rootUrl.isParentOf(url)) { // the URL is no child URL of the column view, hence clear all columns // and reset the root column - QList<ColumnWidget*>::iterator start = m_columns.begin() + 1; - QList<ColumnWidget*>::iterator end = m_columns.end(); - for (QList<ColumnWidget*>::iterator it = start; it != end; ++it) { + QList<DolphinColumnWidget*>::iterator start = m_columns.begin() + 1; + QList<DolphinColumnWidget*>::iterator end = m_columns.end(); + for (QList<DolphinColumnWidget*>::iterator it = start; it != end; ++it) { (*it)->deleteLater(); } m_columns.erase(start, end); @@ -563,7 +179,7 @@ void DolphinColumnView::showColumn(const KUrl& url) } int columnIndex = 0; - foreach (ColumnWidget* column, m_columns) { + foreach (DolphinColumnWidget* column, m_columns) { if (column->url() == url) { // the column represents already the requested URL, hence activate it requestActivation(column); @@ -572,9 +188,9 @@ void DolphinColumnView::showColumn(const KUrl& url) // the column is no parent of the requested URL, hence // just delete all remaining columns if (columnIndex > 0) { - QList<ColumnWidget*>::iterator start = m_columns.begin() + columnIndex; - QList<ColumnWidget*>::iterator end = m_columns.end(); - for (QList<ColumnWidget*>::iterator it = start; it != end; ++it) { + QList<DolphinColumnWidget*>::iterator start = m_columns.begin() + columnIndex; + QList<DolphinColumnWidget*>::iterator end = m_columns.end(); + for (QList<DolphinColumnWidget*>::iterator it = start; it != end; ++it) { (*it)->deleteLater(); } m_columns.erase(start, end); @@ -621,9 +237,7 @@ void DolphinColumnView::showColumn(const KUrl& url) m_columns[columnIndex]->setChildUrl(childUrl); columnIndex++; - ColumnWidget* column = new ColumnWidget(viewport(), this, childUrl); - column->setModel(model()); - column->setRootIndex(proxyIndex); + DolphinColumnWidget* column = new DolphinColumnWidget(viewport(), this, childUrl); column->setActive(false); m_columns.append(column); @@ -637,7 +251,7 @@ void DolphinColumnView::showColumn(const KUrl& url) // the layout is finished, now let the column be invisible until it // gets a valid root index due to expandToActiveUrl() - column->hide(); + //column->hide(); } } @@ -774,7 +388,7 @@ void DolphinColumnView::updateDecorationSize() foreach (QObject* object, viewport()->children()) { if (object->inherits("QListView")) { - ColumnWidget* widget = static_cast<ColumnWidget*>(object); + DolphinColumnWidget* widget = static_cast<DolphinColumnWidget*>(object); widget->setDecorationSize(QSize(iconSize, iconSize)); } } @@ -785,55 +399,20 @@ void DolphinColumnView::updateDecorationSize() doItemsLayout(); } -void DolphinColumnView::expandToActiveUrl() +void DolphinColumnView::slotShowHiddenFilesChanged(bool show) { - const int lastIndex = m_columns.count() - 1; - Q_ASSERT(lastIndex >= 0); - const KUrl& activeUrl = m_columns[lastIndex]->url(); - const KUrl rootUrl = m_dolphinModel->dirLister()->url(); - const bool expand = rootUrl.isParentOf(activeUrl) - && !rootUrl.equals(activeUrl, KUrl::CompareWithoutTrailingSlash); - if (expand) { - m_dolphinModel->expandToUrl(activeUrl); + foreach (DolphinColumnWidget* column, m_columns) { + column->setShowHiddenFiles(show); } - updateColumns(); -} - -void DolphinColumnView::triggerUpdateColumns(const QModelIndex& index) -{ - Q_UNUSED(index); - // the updating of the columns may not be done in the context of this slot - QMetaObject::invokeMethod(this, "updateColumns", Qt::QueuedConnection); } -void DolphinColumnView::updateColumns() +void DolphinColumnView::slotShowPreviewChanged(bool show) { - const int end = m_columns.count() - 2; // next to last column - for (int i = 0; i <= end; ++i) { - ColumnWidget* nextColumn = m_columns[i + 1]; - const QModelIndex rootIndex = nextColumn->rootIndex(); - if (rootIndex.isValid()) { - nextColumn->show(); - } else { - const QModelIndex dirIndex = m_dolphinModel->indexForUrl(m_columns[i]->childUrl()); - const QModelIndex proxyIndex = m_proxyModel->mapFromSource(dirIndex); - if (proxyIndex.isValid()) { - nextColumn->setRootIndex(proxyIndex); - nextColumn->show(); - if (nextColumn->isActive() && m_restoreActiveColumnFocus) { - nextColumn->setFocus(); - m_restoreActiveColumnFocus = false; - } - } - } + foreach (DolphinColumnWidget* column, m_columns) { + column->setShowPreview(show); } } -void DolphinColumnView::triggerExpandToActiveUrl() -{ - QMetaObject::invokeMethod(this, "expandToActiveUrl", Qt::QueuedConnection); -} - bool DolphinColumnView::isZoomInPossible() const { ColumnModeSettings* settings = DolphinSettings::instance().columnModeSettings(); @@ -871,13 +450,13 @@ void DolphinColumnView::layoutColumns() const int columnWidth = settings->columnWidth(); if (isRightToLeft()) { int x = viewport()->width() - columnWidth + m_contentX; - foreach (ColumnWidget* column, m_columns) { + foreach (DolphinColumnWidget* column, m_columns) { column->setGeometry(QRect(x, 0, columnWidth, viewport()->height())); x -= columnWidth; } } else { int x = m_contentX; - foreach (ColumnWidget* column, m_columns) { + foreach (DolphinColumnWidget* column, m_columns) { column->setGeometry(QRect(x, 0, columnWidth, viewport()->height())); x += columnWidth; } @@ -887,7 +466,7 @@ void DolphinColumnView::layoutColumns() void DolphinColumnView::updateScrollBar() { int contentWidth = 0; - foreach (ColumnWidget* column, m_columns) { + foreach (DolphinColumnWidget* column, m_columns) { contentWidth += column->width(); } @@ -919,13 +498,13 @@ void DolphinColumnView::assureVisibleActiveColumn() } } -void DolphinColumnView::requestActivation(ColumnWidget* column) +void DolphinColumnView::requestActivation(DolphinColumnWidget* column) { if (column->isActive()) { assureVisibleActiveColumn(); } else { int index = 0; - foreach (ColumnWidget* currColumn, m_columns) { + foreach (DolphinColumnWidget* currColumn, m_columns) { if (currColumn == column) { setActiveColumnIndex(index); return; diff --git a/src/dolphincolumnview.h b/src/dolphincolumnview.h index 4a6e6140c..b473e790e 100644 --- a/src/dolphincolumnview.h +++ b/src/dolphincolumnview.h @@ -24,7 +24,7 @@ #include <QList> #include <QStyleOption> -class ColumnWidget; +class DolphinColumnWidget; class DolphinController; class DolphinModel; class KUrl; @@ -99,36 +99,14 @@ private slots: */ void updateDecorationSize(); - /** - * Expands the directory model the the currently active URL. - * Used by DolphinColumnView::reload() after the directory - * lister has been loaded. - */ - void expandToActiveUrl(); - - /** - * Triggers the updating of columns after the model index - * \a index has been expanded. Used by DolphinModel::expandToActiveUrl(). - */ - void triggerUpdateColumns(const QModelIndex& index); - - /** - * Adjusts the root index of all columns to represent the reloaded - * model. Used by DolphinModel::triggerUpdateColumns(). - */ - void updateColumns(); - - /** - * Is invoked when the directory lister has completed the loading - * and invokes expandToActiveUrl() asynchronously. - */ - void triggerExpandToActiveUrl(); + void slotShowHiddenFilesChanged(bool show); + void slotShowPreviewChanged(bool show); private: bool isZoomInPossible() const; bool isZoomOutPossible() const; - ColumnWidget* activeColumn() const; + DolphinColumnWidget* activeColumn() const; /** * Deactivates the currently active column and activates @@ -152,23 +130,23 @@ private: * that the columns gets fully visible by adjusting the horizontal * position of the content. */ - void requestActivation(ColumnWidget* column); + void requestActivation(DolphinColumnWidget* column); private: DolphinController* m_controller; bool m_restoreActiveColumnFocus; int m_index; int m_contentX; - QList<ColumnWidget*> m_columns; + QList<DolphinColumnWidget*> m_columns; QTimeLine* m_animation; DolphinModel* m_dolphinModel; QAbstractProxyModel* m_proxyModel; - friend class ColumnWidget; + friend class DolphinColumnWidget; }; -inline ColumnWidget* DolphinColumnView::activeColumn() const +inline DolphinColumnWidget* DolphinColumnView::activeColumn() const { return m_columns[m_index]; } diff --git a/src/dolphincolumnwidget.cpp b/src/dolphincolumnwidget.cpp new file mode 100644 index 000000000..94bee2bee --- /dev/null +++ b/src/dolphincolumnwidget.cpp @@ -0,0 +1,446 @@ +/*************************************************************************** + * Copyright (C) 2007 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 "dolphincolumnwidget.h" + +#include "dolphinmodel.h" +#include "dolphincolumnview.h" +#include "dolphincontroller.h" +#include "dolphindirlister.h" +#include "dolphinmodel.h" +#include "dolphinsortfilterproxymodel.h" +#include "dolphinsettings.h" + +#include "dolphin_columnmodesettings.h" + +#include <kcolorutils.h> +#include <kcolorscheme.h> +#include <kdirlister.h> +#include <kfileitem.h> +#include <kio/previewjob.h> +#include <kiconeffect.h> +#include <konqmimedata.h> + +#include <QAbstractProxyModel> +#include <QApplication> +#include <QClipboard> +#include <QPoint> +#include <QScrollBar> +#include <QTimer> +#include <QTimeLine> + +DolphinColumnWidget::DolphinColumnWidget(QWidget* parent, + DolphinColumnView* columnView, + const KUrl& url) : + QListView(parent), + m_active(true), + m_showPreview(false), + m_view(columnView), + m_url(url), + m_childUrl(), + m_viewOptions(), + m_dirLister(0), + m_dolphinModel(0), + m_proxyModel(0), + m_dragging(false), + m_dropRect() +{ + setMouseTracking(true); + viewport()->setAttribute(Qt::WA_Hover); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + setSelectionBehavior(SelectItems); + setSelectionMode(QAbstractItemView::ExtendedSelection); + setDragDropMode(QAbstractItemView::DragDrop); + setDropIndicatorShown(false); + setFocusPolicy(Qt::NoFocus); + +// TODO: Remove this check when 4.3.2 is released and KDE requires it... this +// check avoids a division by zero happening on versions before 4.3.1. +// Right now KDE in theory can be shipped with Qt 4.3.0 and above. +// ereslibre +#if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 2) || defined(QT_KDE_QT_COPY)) + setVerticalScrollMode(QListView::ScrollPerPixel); + setHorizontalScrollMode(QListView::ScrollPerPixel); +#endif + + // apply the column mode settings to the widget + const ColumnModeSettings* settings = DolphinSettings::instance().columnModeSettings(); + Q_ASSERT(settings != 0); + + m_viewOptions = QListView::viewOptions(); + + QFont font(settings->fontFamily(), settings->fontSize()); + font.setItalic(settings->italicFont()); + font.setBold(settings->boldFont()); + m_viewOptions.font = font; + + const int iconSize = settings->iconSize(); + m_viewOptions.decorationSize = QSize(iconSize, iconSize); + + m_viewOptions.showDecorationSelected = true; + + KFileItemDelegate* delegate = new KFileItemDelegate(this); + setItemDelegate(delegate); + + activate(); + + connect(this, SIGNAL(entered(const QModelIndex&)), + m_view->m_controller, SLOT(emitItemEntered(const QModelIndex&))); + connect(this, SIGNAL(viewportEntered()), + m_view->m_controller, SLOT(emitViewportEntered())); + connect(this, SIGNAL(viewportEntered()), + m_view->m_controller, SLOT(emitViewportEntered())); + + connect(this, SIGNAL(entered(const QModelIndex&)), + this, SLOT(slotEntered(const QModelIndex&))); + + //m_dirLister = new DolphinDirLister(); TODO + m_dirLister = new KDirLister(); + m_dirLister->setAutoUpdate(true); + m_dirLister->setMainWindow(this); + m_dirLister->setDelayedMimeTypes(true); + m_dirLister->setShowingDotFiles(m_view->m_controller->showHiddenFiles()); + connect(m_dirLister, SIGNAL(newItems(const KFileItemList&)), + this, SLOT(generatePreviews(const KFileItemList&))); + + 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); + + setModel(m_proxyModel); + + m_dirLister->openUrl(url, KDirLister::NoFlags); +} + +DolphinColumnWidget::~DolphinColumnWidget() +{ + delete m_dirLister; + m_dirLister = 0; +} + +void DolphinColumnWidget::setDecorationSize(const QSize& size) +{ + m_viewOptions.decorationSize = size; + doItemsLayout(); +} + +void DolphinColumnWidget::setActive(bool active) +{ + if (m_active == active) { + return; + } + + m_active = active; + + if (active) { + activate(); + } else { + deactivate(); + } +} + +void DolphinColumnWidget::reload() +{ + m_dirLister->stop(); + m_dirLister->openUrl(m_url, KDirLister::Reload); +} + +void DolphinColumnWidget::setShowHiddenFiles(bool show) +{ + if (show != m_dirLister->showingDotFiles()) { + m_dirLister->setShowingDotFiles(show); + m_dirLister->stop(); + m_dirLister->openUrl(m_url, KDirLister::Reload); + } +} + +void DolphinColumnWidget::setShowPreview(bool show) +{ + if (show != m_showPreview) { + m_dirLister->stop(); + m_dirLister->openUrl(m_url, KDirLister::Reload); + } +} + +void DolphinColumnWidget::dragEnterEvent(QDragEnterEvent* event) +{ + if (event->mimeData()->hasUrls()) { + event->acceptProposedAction(); + } + + m_dragging = true; +} + +void DolphinColumnWidget::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 DolphinColumnWidget::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 DolphinColumnWidget::dropEvent(QDropEvent* event) +{ + const KUrl::List urls = KUrl::List::fromMimeData(event->mimeData()); + if (!urls.isEmpty()) { + event->acceptProposedAction(); + m_view->m_controller->indicateDroppedUrls(urls, + url(), + indexAt(event->pos()), + event->source()); + } + QListView::dropEvent(event); + m_dragging = false; +} + +void DolphinColumnWidget::paintEvent(QPaintEvent* event) +{ + if (!m_childUrl.isEmpty()) { + // indicate the shown URL of the next column by highlighting the shown folder item + 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(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 DolphinColumnWidget::mousePressEvent(QMouseEvent* event) +{ + if (!m_active) { + m_view->requestActivation(this); + } + + QListView::mousePressEvent(event); +} + +void DolphinColumnWidget::keyPressEvent(QKeyEvent* event) +{ + QListView::keyPressEvent(event); + + const QItemSelectionModel* selModel = selectionModel(); + const QModelIndex currentIndex = selModel->currentIndex(); + const bool trigger = currentIndex.isValid() + && (event->key() == Qt::Key_Return) + && (selModel->selectedIndexes().count() <= 1); + if (trigger) { + triggerItem(currentIndex); + } +} + +void DolphinColumnWidget::contextMenuEvent(QContextMenuEvent* event) +{ + if (!m_active) { + m_view->requestActivation(this); + } + + QListView::contextMenuEvent(event); + + 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); + } +} + +void DolphinColumnWidget::selectionChanged(const QItemSelection& selected, const QItemSelection& deselected) +{ + QListView::selectionChanged(selected, deselected); + + QItemSelectionModel* selModel = m_view->selectionModel(); + selModel->select(selected, QItemSelectionModel::Select); + selModel->select(deselected, QItemSelectionModel::Deselect); +} +void DolphinColumnWidget::triggerItem(const QModelIndex& index) +{ + const Qt::KeyboardModifiers modifier = QApplication::keyboardModifiers(); + if ((modifier & Qt::ShiftModifier) || (modifier & Qt::ControlModifier)) { + // items are selected by the user, hence don't trigger the + // item specified by 'index' + return; + } + + // TODO: check ZIP support (see DolphinViewContainer::triggerItem) + KFileItem item = m_dolphinModel->itemForIndex(m_proxyModel->mapToSource(index)); + if (item.isDir()) { + bool isLocal; + const KUrl url = item.mostLocalUrl(isLocal); + m_view->showColumn(url); + m_view->m_controller->setUrl(url); + } else if (item.isFile()) { + item.run(); + } +} + +void DolphinColumnWidget::generatePreviews(const KFileItemList& items) +{ + // TODO: same implementation as in DolphinView; create helper class + // for generatePreviews(), showPreview() and isCutItem() + + if (m_view->m_controller->showPreview()) { + KIO::PreviewJob* job = KIO::filePreview(items, 128); + connect(job, SIGNAL(gotPreview(const KFileItem&, const QPixmap&)), + this, SLOT(showPreview(const KFileItem&, const QPixmap&))); + } +} + +void DolphinColumnWidget::showPreview(const KFileItem& item, const QPixmap& pixmap) +{ + // TODO: same implementation as in DolphinView; create helper class + // for generatePreviews(), showPreview() and isCutItem() + + Q_ASSERT(!item.isNull()); + if (item.url().directory() != m_dirLister->url().path()) { + // the preview job is still working on items of an older URL, hence + // the item is not part of the directory model anymore + return; + } + + const QModelIndex idx = m_dolphinModel->indexForItem(item); + if (idx.isValid() && (idx.column() == 0)) { + const QMimeData* mimeData = QApplication::clipboard()->mimeData(); + if (KonqMimeData::decodeIsCutSelection(mimeData) && isCutItem(item)) { + KIconEffect iconEffect; + const QPixmap cutPixmap = iconEffect.apply(pixmap, KIconLoader::Desktop, KIconLoader::DisabledState); + m_dolphinModel->setData(idx, QIcon(cutPixmap), Qt::DecorationRole); + } else { + m_dolphinModel->setData(idx, QIcon(pixmap), Qt::DecorationRole); + } + } +} + +void DolphinColumnWidget::slotEntered(const QModelIndex& index) +{ + const QModelIndex dirIndex = m_proxyModel->mapToSource(index); + const KFileItem item = m_dolphinModel->itemForIndex(dirIndex); + m_view->m_controller->emitItemEntered(item); +} + +void DolphinColumnWidget::activate() +{ + if (m_view->hasFocus()) { + setFocus(Qt::OtherFocusReason); + } + m_view->setFocusProxy(this); + + // TODO: Connecting to the signal 'activated()' is not possible, as kstyle + // does not forward the single vs. doubleclick to it yet (KDE 4.1?). Hence it is + // necessary connecting the signal 'singleClick()' or 'doubleClick'. + 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&))); + } + + const QColor bgColor = KColorScheme(QPalette::Active, KColorScheme::View).background().color(); + QPalette palette = viewport()->palette(); + palette.setColor(viewport()->backgroundRole(), bgColor); + viewport()->setPalette(palette); + + if (!m_childUrl.isEmpty()) { + // assure that the current index is set on the index that represents + // the child URL + const QModelIndex dirIndex = m_dolphinModel->indexForUrl(m_childUrl); + const QModelIndex proxyIndex = m_proxyModel->mapFromSource(dirIndex); + selectionModel()->setCurrentIndex(proxyIndex, QItemSelectionModel::Current); + } + + update(); +} + +void DolphinColumnWidget::deactivate() +{ + // TODO: Connecting to the signal 'activated()' is not possible, as kstyle + // does not forward the single vs. doubleclick to it yet (KDE 4.1?). Hence it is + // necessary connecting the signal 'singleClick()' or 'doubleClick'. + if (KGlobalSettings::singleClick()) { + disconnect(this, SIGNAL(clicked(const QModelIndex&)), + this, SLOT(triggerItem(const QModelIndex&))); + } else { + disconnect(this, SIGNAL(doubleClicked(const QModelIndex&)), + this, SLOT(triggerItem(const QModelIndex&))); + } + + const QPalette palette = m_view->viewport()->palette(); + viewport()->setPalette(palette); + + selectionModel()->clear(); + update(); +} + +bool DolphinColumnWidget::isCutItem(const KFileItem& item) const +{ + // TODO: same implementation as in DolphinView; create helper class + // for generatePreviews(), showPreview() and isCutItem() + + const QMimeData* mimeData = QApplication::clipboard()->mimeData(); + const KUrl::List cutUrls = KUrl::List::fromMimeData(mimeData); + + const KUrl& itemUrl = item.url(); + KUrl::List::const_iterator it = cutUrls.begin(); + const KUrl::List::const_iterator end = cutUrls.end(); + while (it != end) { + if (*it == itemUrl) { + return true; + } + ++it; + } + + return false; +} + +#include "dolphincolumnwidget.moc" diff --git a/src/dolphincolumnwidget.h b/src/dolphincolumnwidget.h new file mode 100644 index 000000000..0efce0902 --- /dev/null +++ b/src/dolphincolumnwidget.h @@ -0,0 +1,177 @@ +/*************************************************************************** + * Copyright (C) 2007 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 DOLPHINCOLUMNWIDGET_H +#define DOLPHINCOLUMNWIDGET_H + +#include <QListView> +#include <QStyleOption> + +#include <kurl.h> + +class DolphinColumnView; +class DolphinModel; +class DolphinSortFilterProxyModel; +class KDirLister; +class KFileItem; +class KFileItemList; +class QPixmap; + +/** + * Represents one column inside the DolphinColumnView and has been + * extended to respect view options and hovering information. + */ +class DolphinColumnWidget : public QListView +{ + Q_OBJECT + +public: + DolphinColumnWidget(QWidget* parent, + DolphinColumnView* columnView, + const KUrl& url); + virtual ~DolphinColumnWidget(); + + /** 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); + bool isActive() const; + + /** + * Sets the directory URL of the child column that is shown next to + * this column. This property is only used for a visual indication + * of the shown directory, it does not trigger a loading of the model. + */ + void setChildUrl(const KUrl& url); + const KUrl& childUrl() const; + + /** Sets the directory URL that is shown inside the column widget. */ + void setUrl(const KUrl& url); + + /** Returns the directory URL that is shown inside the column widget. */ + const KUrl& url() const; + + /** Reloads the directory DolphinColumnWidget::url(). */ + void reload(); + + void setShowHiddenFiles(bool show); + void setShowPreview(bool show); + +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 paintEvent(QPaintEvent* event); + virtual void mousePressEvent(QMouseEvent* event); + virtual void keyPressEvent(QKeyEvent* event); + virtual void contextMenuEvent(QContextMenuEvent* event); + virtual void selectionChanged(const QItemSelection& selected, const QItemSelection& deselected); + +private slots: + /** + * If the item specified by \a index is a directory, then this + * directory will be loaded in a new column. If the item is a + * file, the corresponding application will get started. + */ + void triggerItem(const QModelIndex& index); + + /** + * Generates a preview image for each file item in \a items. + * The current preview settings (maximum size, 'Show Preview' menu) + * are respected. + */ + void generatePreviews(const KFileItemList& items); + + /** + * Replaces the icon of the item \a item by the preview pixmap + * \a pixmap. + */ + void showPreview(const KFileItem& item, const QPixmap& pixmap); + + void slotEntered(const QModelIndex& index); + +private: + /** Used by DolphinColumnWidget::setActive(). */ + void activate(); + + /** Used by DolphinColumnWidget::setActive(). */ + void deactivate(); + + /** + * Returns true, if the item \a item has been cut into + * the clipboard. + */ + bool isCutItem(const KFileItem& item) const; + +private: + bool m_active; + bool m_showPreview; + DolphinColumnView* m_view; + KUrl m_url; // URL of the directory that is shown + KUrl m_childUrl; // URL of the next column that is shown + QStyleOptionViewItem m_viewOptions; + KDirLister* m_dirLister; + DolphinModel* m_dolphinModel; + DolphinSortFilterProxyModel* m_proxyModel; + + 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 +}; + +inline bool DolphinColumnWidget::isActive() const +{ + return m_active; +} + +inline void DolphinColumnWidget::setChildUrl(const KUrl& url) +{ + m_childUrl = url; +} + +inline const KUrl& DolphinColumnWidget::childUrl() const +{ + return m_childUrl; +} + +inline void DolphinColumnWidget::setUrl(const KUrl& url) +{ + if (url != m_url) { + m_url = url; + reload(); + } +} + +inline const KUrl& DolphinColumnWidget::url() const +{ + return m_url; +} + +inline QStyleOptionViewItem DolphinColumnWidget::viewOptions() const +{ + return m_viewOptions; +} + +#endif diff --git a/src/dolphincontroller.cpp b/src/dolphincontroller.cpp index 7723fd8ef..4666e617b 100644 --- a/src/dolphincontroller.cpp +++ b/src/dolphincontroller.cpp @@ -23,6 +23,7 @@ DolphinController::DolphinController(QObject* parent) : QObject(parent), + m_showHiddenFiles(false), m_showPreview(false), m_zoomInPossible(false), m_zoomOutPossible(false), @@ -73,6 +74,14 @@ void DolphinController::indicateSortOrderChange(Qt::SortOrder order) emit sortOrderChanged(order); } +void DolphinController::setShowHiddenFiles(bool show) +{ + if (m_showHiddenFiles != show) { + m_showHiddenFiles = show; + emit showHiddenFilesChanged(show); + } +} + void DolphinController::setShowPreview(bool show) { if (m_showPreview != show) { @@ -131,9 +140,9 @@ void DolphinController::triggerItem(const QModelIndex& index) emit itemTriggered(index); } -void DolphinController::emitItemEntered(const QModelIndex& index) +void DolphinController::emitItemEntered(const KFileItem& item) { - emit itemEntered(index); + emit itemEntered(item); } void DolphinController::emitViewportEntered() diff --git a/src/dolphincontroller.h b/src/dolphincontroller.h index d773a8548..3a2720471 100644 --- a/src/dolphincontroller.h +++ b/src/dolphincontroller.h @@ -74,6 +74,9 @@ public: void indicateSortOrderChange(Qt::SortOrder order); + void setShowHiddenFiles(bool show); + bool showHiddenFiles() const; + void setShowPreview(bool show); bool showPreview() const; @@ -103,7 +106,7 @@ public slots: * Emits the signal itemEntered(). The method should be invoked by * the controller parent whenever the mouse cursor is above an item. */ - void emitItemEntered(const QModelIndex& index); + void emitItemEntered(const KFileItem& item); /** * Emits the signal viewportEntered(). The method should be invoked by @@ -150,6 +153,12 @@ signals: void sortOrderChanged(Qt::SortOrder order); /** + * Is emitted if the state for showing hidden files has been + * changed to \a show. + */ + void showHiddenFilesChanged(bool show); + + /** * Is emitted if the state for showing previews has been * changed to \a show. */ @@ -173,7 +182,7 @@ signals: * Is emitted if the mouse cursor has entered the item * given by \a index. */ - void itemEntered(const QModelIndex& index); + void itemEntered(const KFileItem& item); /** * Is emitted if the mouse cursor has entered @@ -187,6 +196,7 @@ signals: void zoomOut(); private: + bool m_showHiddenFiles; bool m_showPreview; bool m_zoomInPossible; bool m_zoomOutPossible; @@ -199,6 +209,11 @@ inline const KUrl& DolphinController::url() const return m_url; } +inline bool DolphinController::showHiddenFiles() const +{ + return m_showHiddenFiles; +} + inline bool DolphinController::showPreview() const { return m_showPreview; diff --git a/src/dolphindetailsview.cpp b/src/dolphindetailsview.cpp index 15f108dbb..078f51bf1 100644 --- a/src/dolphindetailsview.cpp +++ b/src/dolphindetailsview.cpp @@ -28,9 +28,11 @@ #include "dolphin_detailsmodesettings.h" +#include <kdirmodel.h> #include <klocale.h> #include <kmenu.h> +#include <QAbstractProxyModel> #include <QAction> #include <QApplication> #include <QHeaderView> @@ -383,7 +385,7 @@ void DolphinDetailsView::slotEntered(const QModelIndex& index) const QPoint pos = viewport()->mapFromGlobal(QCursor::pos()); const int nameColumnWidth = header()->sectionSize(DolphinModel::Name); if (pos.x() < nameColumnWidth) { - m_controller->emitItemEntered(index); + m_controller->emitItemEntered(itemForIndex(index)); } else { m_controller->emitViewportEntered(); @@ -399,6 +401,13 @@ void DolphinDetailsView::updateElasticBand() setDirtyRegion(dirtyRegion); } +QRect DolphinDetailsView::elasticBandRect() const +{ + const QPoint pos(contentsPos()); + const QPoint topLeft(m_elasticBandOrigin.x() - pos.x(), m_elasticBandOrigin.y() - pos.y()); + return QRect(topLeft, m_elasticBandDestination).normalized(); +} + void DolphinDetailsView::zoomIn() { if (isZoomInPossible()) { @@ -431,7 +440,7 @@ void DolphinDetailsView::slotItemActivated(const QModelIndex& index) m_controller->triggerItem(index); } else { clearSelection(); - m_controller->emitItemEntered(index); + m_controller->emitItemEntered(itemForIndex(index)); } } @@ -518,16 +527,12 @@ QPoint DolphinDetailsView::contentsPos() const return QPoint(0, y); } -QRect DolphinDetailsView::elasticBandRect() const -{ - const QPoint pos(contentsPos()); - const QPoint topLeft(m_elasticBandOrigin.x() - pos.x(), m_elasticBandOrigin.y() - pos.y()); - return QRect(topLeft, m_elasticBandDestination).normalized(); -} - -static bool isValidNameIndex(const QModelIndex& index) +KFileItem DolphinDetailsView::itemForIndex(const QModelIndex& index) const { - return index.isValid() && (index.column() == KDirModel::Name); + QAbstractProxyModel* proxyModel = static_cast<QAbstractProxyModel*>(model()); + KDirModel* dirModel = static_cast<KDirModel*>(proxyModel->sourceModel()); + const QModelIndex dirIndex = proxyModel->mapToSource(index); + return dirModel->itemForIndex(dirIndex); } #include "dolphindetailsview.moc" diff --git a/src/dolphindetailsview.h b/src/dolphindetailsview.h index a0ef0eedf..06cd9a833 100644 --- a/src/dolphindetailsview.h +++ b/src/dolphindetailsview.h @@ -131,6 +131,8 @@ private: /** Return the upper left position in pixels of the viewport content. */ QPoint contentsPos() const; + KFileItem itemForIndex(const QModelIndex& index) const; + private: DolphinController* m_controller; QStyleOptionViewItem m_viewOptions; diff --git a/src/dolphiniconsview.cpp b/src/dolphiniconsview.cpp index 6b584612c..042c9a76c 100644 --- a/src/dolphiniconsview.cpp +++ b/src/dolphiniconsview.cpp @@ -26,6 +26,7 @@ #include "dolphin_iconsmodesettings.h" #include <kdialog.h> +#include <kdirmodel.h> #include <QAbstractProxyModel> #include <QApplication> @@ -58,8 +59,6 @@ DolphinIconsView::DolphinIconsView(QWidget* parent, DolphinController* controlle connect(this, SIGNAL(doubleClicked(const QModelIndex&)), controller, 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(showPreviewChanged(bool)), @@ -71,6 +70,9 @@ DolphinIconsView::DolphinIconsView(QWidget* parent, DolphinController* controlle connect(controller, SIGNAL(zoomOut()), this, SLOT(zoomOut())); + connect(this, SIGNAL(entered(const QModelIndex&)), + this, SLOT(slotEntered(const QModelIndex&))); + // apply the icons mode settings to the widget const IconsModeSettings* settings = DolphinSettings::instance().iconsModeSettings(); Q_ASSERT(settings != 0); @@ -228,6 +230,16 @@ void DolphinIconsView::keyPressEvent(QKeyEvent* event) } } +void DolphinIconsView::slotEntered(const QModelIndex& index) +{ + QAbstractProxyModel* proxyModel = static_cast<QAbstractProxyModel*>(model()); + KDirModel* dirModel = static_cast<KDirModel*>(proxyModel->sourceModel()); + const QModelIndex dirIndex = proxyModel->mapToSource(index); + + const KFileItem item = dirModel->itemForIndex(dirIndex); + m_controller->emitItemEntered(item); +} + void DolphinIconsView::slotShowPreviewChanged(bool showPreview) { updateGridSize(showPreview, m_controller->additionalInfoCount()); diff --git a/src/dolphiniconsview.h b/src/dolphiniconsview.h index 7e88f39bd..a95163f3a 100644 --- a/src/dolphiniconsview.h +++ b/src/dolphiniconsview.h @@ -59,6 +59,7 @@ protected: virtual void keyPressEvent(QKeyEvent* event); private slots: + void slotEntered(const QModelIndex& index); void slotShowPreviewChanged(bool show); void slotAdditionalInfoCountChanged(int count); void zoomIn(); diff --git a/src/dolphinview.cpp b/src/dolphinview.cpp index 94ed99b69..ad760fb13 100644 --- a/src/dolphinview.cpp +++ b/src/dolphinview.cpp @@ -60,7 +60,6 @@ DolphinView::DolphinView(QWidget* parent, QWidget(parent), m_active(true), m_loadingDirectory(false), - m_initializeColumnView(false), m_storedCategorizedSorting(false), m_mode(DolphinView::IconsView), m_topLayout(0), @@ -103,8 +102,8 @@ DolphinView::DolphinView(QWidget* parent, this, SLOT(triggerItem(const QModelIndex&))); connect(m_controller, SIGNAL(activated()), this, SLOT(activate())); - connect(m_controller, SIGNAL(itemEntered(const QModelIndex&)), - this, SLOT(showHoverInformation(const QModelIndex&))); + connect(m_controller, SIGNAL(itemEntered(const KFileItem&)), + this, SLOT(showHoverInformation(const KFileItem&))); connect(m_controller, SIGNAL(viewportEntered()), this, SLOT(clearHoverInformation())); @@ -181,7 +180,7 @@ void DolphinView::setMode(Mode mode) emit categorizedSortingChanged(); } - startDirLister(viewPropsUrl); + loadDirectory(viewPropsUrl); emit modeChanged(); } @@ -200,7 +199,7 @@ void DolphinView::setShowPreview(bool show) m_controller->setShowPreview(show); emit showPreviewChanged(); - startDirLister(viewPropsUrl, true); + loadDirectory(viewPropsUrl, true); } bool DolphinView::showPreview() const @@ -219,9 +218,10 @@ void DolphinView::setShowHiddenFiles(bool show) props.setShowHiddenFiles(show); m_dirLister->setShowingDotFiles(show); + m_controller->setShowHiddenFiles(show); emit showHiddenFilesChanged(); - startDirLister(viewPropsUrl, true); + loadDirectory(viewPropsUrl, true); } bool DolphinView::showHiddenFiles() const @@ -278,8 +278,8 @@ void DolphinView::invertSelection() // QAbstractItemView does not offer a virtual method invertSelection() // as counterpart to QAbstractItemView::selectAll(). This makes it // necessary to delegate the inverting of the selection to the - // column view, as only the selection of the active column should get - // inverted. + // column view, as only the selection of the active column should + // get inverted. m_columnView->invertSelection(); } else { QItemSelectionModel* selectionModel = itemView()->selectionModel(); @@ -416,7 +416,7 @@ void DolphinView::setAdditionalInfo(KFileItemDelegate::InformationList info) m_fileItemDelegate->setShowInformation(info); emit additionalInfoChanged(info); - startDirLister(viewPropsUrl, true); + loadDirectory(viewPropsUrl, true); } KFileItemDelegate::InformationList DolphinView::additionalInfo() const @@ -427,7 +427,7 @@ KFileItemDelegate::InformationList DolphinView::additionalInfo() const void DolphinView::reload() { setUrl(url()); - startDirLister(url(), true); + loadDirectory(url(), true); } void DolphinView::refresh() @@ -452,7 +452,7 @@ void DolphinView::updateView(const KUrl& url, const KUrl& rootUrl) if (restoreColumnView) { applyViewProperties(rootUrl); - startDirLister(rootUrl); + loadDirectory(rootUrl); // Restoring the column view relies on the URL-history. It might be possible // that the view properties have been changed or deleted in the meantime, so // it cannot be asserted that really a column view has been created: @@ -461,7 +461,7 @@ void DolphinView::updateView(const KUrl& url, const KUrl& rootUrl) } } else { applyViewProperties(url); - startDirLister(url); + loadDirectory(url); } itemView()->setFocus(); @@ -540,7 +540,7 @@ void DolphinView::emitSelectionChangedSignal() emit selectionChanged(DolphinView::selectedItems()); } -void DolphinView::startDirLister(const KUrl& url, bool reload) +void DolphinView::loadDirectory(const KUrl& url, bool reload) { if (!url.isValid()) { const QString location(url.pathOrUrl()); @@ -556,32 +556,12 @@ void DolphinView::startDirLister(const KUrl& url, bool reload) m_loadingDirectory = true; m_dirLister->stop(); + m_dirLister->openUrl(url, reload ? KDirLister::Reload : KDirLister::NoFlags); - bool keepOldDirs = isColumnViewActive() && !m_initializeColumnView; - m_initializeColumnView = false; - - if (keepOldDirs) { - // keeping old directories is only necessary for hierarchical views - // like the column view - if (reload) { - // for the column view it is not enough to reload the directory lister, - // so this task is delegated to the column view directly - m_columnView->reload(); - } else if (m_dirLister->directories().contains(url)) { - // The dir lister contains the directory already, so - // KDirLister::openUrl() may not get invoked twice. - m_dirLister->updateDirectory(url); - } else { - const KUrl& dirListerUrl = m_dirLister->url(); - if ((dirListerUrl == url) || !m_dirLister->url().isParentOf(url)) { - // The current URL is not a child of the dir lister - // URL. This may happen when e. g. a place has been selected - // and hence the view must be reset. - m_dirLister->openUrl(url, KDirLister::NoFlags); - } - } - } else { - m_dirLister->openUrl(url, reload ? KDirLister::Reload : KDirLister::NoFlags); + if (isColumnViewActive() && reload) { + // reloading the directory lister is not enough in the case of the + // column view, as each column has its own directory lister internally... + m_columnView->reload(); } } @@ -610,14 +590,6 @@ void DolphinView::applyViewProperties(const KUrl& url) m_mode = mode; createView(); emit modeChanged(); - - if (m_mode == ColumnView) { - // The mode has been changed to the Column View. When starting the dir - // lister with DolphinView::startDirLister() it is important to give a - // hint that the dir lister may not keep the current directory - // although this is the default for showing a hierarchy. - m_initializeColumnView = true; - } } if (itemView() == 0) { createView(); @@ -628,6 +600,7 @@ void DolphinView::applyViewProperties(const KUrl& url) const bool showHiddenFiles = props.showHiddenFiles(); if (showHiddenFiles != m_dirLister->showingDotFiles()) { m_dirLister->setShowingDotFiles(showHiddenFiles); + m_controller->setShowHiddenFiles(showHiddenFiles); emit showHiddenFilesChanged(); } @@ -782,16 +755,13 @@ void DolphinView::updateCutItems() applyCutItemEffect(); } -void DolphinView::showHoverInformation(const QModelIndex& index) +void DolphinView::showHoverInformation(const KFileItem& item) { if (hasSelection()) { return; } - const KFileItem item = fileItem(index); - if (!item.isNull()) { - emit requestItemInfo(item); - } + emit requestItemInfo(item); } void DolphinView::clearHoverInformation() diff --git a/src/dolphinview.h b/src/dolphinview.h index c3d1c7abc..d9d2f5cca 100644 --- a/src/dolphinview.h +++ b/src/dolphinview.h @@ -486,11 +486,11 @@ private slots: /** * Updates the status bar to show hover information for the - * item with the index \a index. If currently other items are selected, + * item \a item. If currently other items are selected, * no hover information is shown. * @see DolphinView::clearHoverInformation() */ - void showHoverInformation(const QModelIndex& index); + void showHoverInformation(const KFileItem& item); /** * Clears the hover information shown in the status bar. @@ -499,7 +499,7 @@ private slots: void clearHoverInformation(); private: - void startDirLister(const KUrl& url, bool reload = false); + void loadDirectory(const KUrl& url, bool reload = false); /** * Returns the URL where the view properties should be stored. Usually @@ -571,8 +571,7 @@ private: }; bool m_active; - bool m_loadingDirectory; - bool m_initializeColumnView; + bool m_loadingDirectory;; bool m_storedCategorizedSorting; Mode m_mode; diff --git a/src/dolphinviewcontainer.cpp b/src/dolphinviewcontainer.cpp index cb56f5c77..65e587fb2 100644 --- a/src/dolphinviewcontainer.cpp +++ b/src/dolphinviewcontainer.cpp @@ -94,11 +94,10 @@ DolphinViewContainer::DolphinViewContainer(DolphinMainWindow* mainWindow, m_dirLister->setMainWindow(this); m_dirLister->setDelayedMimeTypes(true); - m_dolphinModel = new DolphinModel(); + 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); |
