]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Refactored DolphinColumnWidget so that it does not need a hierarchical KDirLister...
authorPeter Penz <peter.penz19@gmail.com>
Fri, 5 Oct 2007 21:00:44 +0000 (21:00 +0000)
committerPeter Penz <peter.penz19@gmail.com>
Fri, 5 Oct 2007 21:00:44 +0000 (21:00 +0000)
- the loading of columns is a lot faster
- preview in columns is working
- no side effects in combination with the treeview-panel because of caching

svn path=/trunk/KDE/kdebase/apps/; revision=721678

14 files changed:
src/CMakeLists.txt
src/dolphincolumnview.cpp
src/dolphincolumnview.h
src/dolphincolumnwidget.cpp [new file with mode: 0644]
src/dolphincolumnwidget.h [new file with mode: 0644]
src/dolphincontroller.cpp
src/dolphincontroller.h
src/dolphindetailsview.cpp
src/dolphindetailsview.h
src/dolphiniconsview.cpp
src/dolphiniconsview.h
src/dolphinview.cpp
src/dolphinview.h
src/dolphinviewcontainer.cpp

index 1405bf85981da9ac72d49e0a7604a78de43d37a9..c06684d9cf95b0da67e350772b1e2bf890fda4c9 100644 (file)
@@ -12,6 +12,7 @@ set(dolphinprivate_LIB_SRCS
     dolphindetailsview.cpp
     dolphiniconsview.cpp
     dolphincolumnview.cpp
+    dolphincolumnwidget.cpp
     kcategorizedview.cpp
     kcategorydrawer.cpp
     dolphinmodel.cpp
index 0f4c962acfdd7bb9f2d95edf463a3f3fc8ea16fa..b8be24bf04ca83467615b32550df485ed1b9e157 100644 (file)
 #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"
 #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;
index 4a6e6140c6a966b7f58a3847c1ddd9b854cba47a..b473e790ee3c7e145bda238eb922a9b2e5141993 100644 (file)
@@ -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 (file)
index 0000000..94bee2b
--- /dev/null
@@ -0,0 +1,446 @@
+/***************************************************************************
+ *   Copyright (C) 2007 by Peter Penz <peter.penz@gmx.at>                  *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   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 (file)
index 0000000..0efce09
--- /dev/null
@@ -0,0 +1,177 @@
+/***************************************************************************
+ *   Copyright (C) 2007 by Peter Penz <peter.penz@gmx.at>                  *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   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
index 7723fd8ef693582e40d8d906ceeee86b96df051b..4666e617b5a12dcfc81ba1fc4a1b825c2e10fbe9 100644 (file)
@@ -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()
index d773a8548e9686f9fb8c40955d90d5b269ca951a..3a2720471a127f5f020c264718bcdc6424af451a 100644 (file)
@@ -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
@@ -149,6 +152,12 @@ signals:
     /** Is emitted if the sort order has been changed to \a sort order. */
     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;
index 15f108dbb174fc975c5952a30f9c6b8536b19761..078f51bf1ac41aa084fa41f16983173ae0485377 100644 (file)
 
 #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"
index a0ef0eedf3832733c33ae3b123e422115c09b0be..06cd9a83335ead816bb19bfba00de6d8882b32ca 100644 (file)
@@ -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;
index 6b584612cc9cec51fcfb74ba9b84370c314f132e..042c9a76c84a1c15de46e2ceadba98d3fc18a171 100644 (file)
@@ -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());
index 7e88f39bde3ae0161efb3fff70e8427465a1093d..a95163f3aacac9f1795b7ccfcb37a64540c0b6c3 100644 (file)
@@ -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();
index 94ed99b690b50939d012a16b871c615e2c9f3ff1..ad760fb134a55967ca9038af7f9c9ba08d12118b 100644 (file)
@@ -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()
index c3d1c7abc6a50b3fdcd3bc9a6a8ee42cdb9b39d8..d9d2f5cca33c4827341bc3180d6b4d1efb3e66ff 100644 (file)
@@ -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;
 
index cb56f5c77c41392fed8b1ffe7a272ee3c7f70192..65e587fb244e9b2c9ec1bf7ed3fee143d870e1ac 100644 (file)
@@ -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);