]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Refactor the folder expansion system. Main effect: instead of having a list of m_exp...
authorSimon Paul St James <kdedevel@etotheipiplusone.com>
Sun, 25 Jan 2009 19:46:08 +0000 (19:46 +0000)
committerSimon Paul St James <kdedevel@etotheipiplusone.com>
Sun, 25 Jan 2009 19:46:08 +0000 (19:46 +0000)
This also fixes folder-expansion not working in Column view.

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

src/dolphincolumnview.cpp
src/dolphincolumnview.h
src/dolphincontroller.cpp
src/dolphincontroller.h
src/dolphinview.cpp
src/dolphinview.h
src/draganddrophelper.cpp
src/draganddrophelper.h
src/folderexpander.cpp
src/folderexpander.h

index bc488b8ae5626efb0799ecd59fd8d4988a9c3cf7..3b3e86a75578dbd352299f8e6116db2e161ca5c6 100644 (file)
@@ -26,6 +26,8 @@
 
 #include "dolphin_columnmodesettings.h"
 
+#include <kfilepreviewgenerator.h>
+
 #include <QPoint>
 #include <QScrollBar>
 #include <QTimeLine>
@@ -594,8 +596,16 @@ void DolphinColumnView::deleteColumn(DolphinColumnWidget* column)
         if (m_controller->itemView() == column) {
             m_controller->setItemView(0);
         }
+        // deleteWhenNotDragSource(column) does not necessarily delete column,
+        // and we want its preview generator destroyed immediately.
+        column->m_previewGenerator->deleteLater();
+        column->m_previewGenerator = 0;
+        column->hide();
+        // Prevent automatic destruction of column when this DolphinColumnView 
+        // is destroyed.
+        column->setParent(0); 
         column->disconnect();
-        column->deleteLater();
+        emit requestColumnDeletion(column);
     }
 }
 
index 1fdd75850b0d61c01a94233f633b3e2d5fa5e2dd..caa54eab84aba56b7d42198e692bda640ea10c56 100644 (file)
@@ -123,6 +123,13 @@ public slots:
     /** @see QAbstractItemView::selectAll() */
     virtual void selectAll();
 
+signals:
+    /**
+     * Requests that the given column be deleted at the discretion
+     * of the receiver of the signal.
+     */
+    void requestColumnDeletion(QAbstractItemView* column);
+
 protected:
     virtual bool isIndexHidden(const QModelIndex& index) const;
     virtual QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers);
index 81cec286889b4f9231ecac65838424d10ba9982d..980e160590611fce3dbb4e8f8d969d7bce29a57c 100644 (file)
 #include <QClipboard>
 #include <QDir>
 
+Qt::MouseButtons DolphinController::m_mouseButtons = Qt::NoButton;
+
 DolphinController::DolphinController(DolphinView* dolphinView) :
     QObject(dolphinView),
     m_zoomLevel(0),
-    m_mouseButtons(Qt::NoButton),
     m_url(),
     m_dolphinView(dolphinView),
     m_itemView(0)
index 542f21b3b3b4bcfaf6026ccd6993664ddaf131a6..3260ab63fdce61fdfdc6db745a0a246d87597836 100644 (file)
@@ -359,7 +359,7 @@ private slots:
 
 private:
     int m_zoomLevel;
-    Qt::MouseButtons m_mouseButtons; // TODO: this is a workaround until  Qt-issue 176832 has been fixed
+    static Qt::MouseButtons m_mouseButtons; // TODO: this is a workaround until  Qt-issue 176832 has been fixed
     KUrl m_url;
     DolphinView* m_dolphinView;
     QAbstractItemView* m_itemView;
index cfe447e37c4042cfaff22db233d1f1c7c4db39ac..fdf93a1dae9db75fe561e6b112f35d9f9c6319ca 100644 (file)
@@ -103,7 +103,7 @@ DolphinView::DolphinView(QWidget* parent,
     m_toolTipManager(0),
     m_rootUrl(),
     m_currentItemUrl(),
-    m_expandedViews()
+    m_expandedDragSource(0)
 {
     m_topLayout = new QVBoxLayout(this);
     m_topLayout->setSpacing(0);
@@ -149,7 +149,9 @@ DolphinView::DolphinView(QWidget* parent,
 
 DolphinView::~DolphinView()
 {
-    deleteExpandedViews();
+    kDebug() << "Deleted view " << m_expandedDragSource;
+    delete m_expandedDragSource;
+    m_expandedDragSource = 0;
 }
 
 const KUrl& DolphinView::url() const
@@ -847,13 +849,16 @@ bool DolphinView::eventFilter(QObject* watched, QEvent* event)
         break;
 
     case QEvent::MouseButtonPress:
-        if ((watched == itemView()->viewport()) && (m_expandedViews.count() > 0)) {
+        kDebug() << "m_expandedDragSource = " << m_expandedDragSource;
+        if ((watched == itemView()->viewport()) && (m_expandedDragSource != 0)) {
             // Listening to a mousebutton press event to delete expanded views is a
             // workaround, as it seems impossible for the FolderExpander to know when
             // a dragging outside a view has been finished. However it works quite well:
             // A mousebutton press event indicates that a drag operation must be
             // finished already.
-            deleteExpandedViews();
+            kDebug() << "Deleted view " << m_expandedDragSource;
+            m_expandedDragSource->deleteLater();
+            m_expandedDragSource = 0;
         }
         break;
 
@@ -1061,6 +1066,29 @@ bool DolphinView::itemsExpandable() const
     return (m_detailsView != 0) && m_detailsView->itemsExpandable();
 }
 
+void DolphinView::deleteWhenNotDragSource(QAbstractItemView *view)
+{
+    if (view == 0)
+        return;
+
+    if (DragAndDropHelper::instance().isDragSource(view)) {
+        kDebug() << "Is current drag source";
+        // We must store for later deletion.
+        if (m_expandedDragSource != 0) {
+            // The old stored view is obviously not the drag source anymore.
+            kDebug() << "Deleted old view " << m_expandedDragSource;
+            m_expandedDragSource->deleteLater();
+            m_expandedDragSource = 0;
+        }
+        view->hide();
+        m_expandedDragSource = view;
+    }
+    else {
+        kDebug() << "Deleted new view " << view;
+        view->deleteLater();
+    }
+}
+
 void DolphinView::emitContentsMoved()
 {
     // only emit the contents moved signal if:
@@ -1113,16 +1141,6 @@ void DolphinView::restoreCurrentItem()
     }
 }
 
-void DolphinView::enterDir(const QModelIndex& index, QAbstractItemView* view)
-{
-    // Deleting a view that is the root of a drag operation is not allowed, otherwise
-    // the dragging gets automatically cancelled by Qt. So before entering a new
-    // directory, the current view is remembered in m_expandedViews and deleted
-    // later when the drag operation has been finished (see DolphinView::eventFilter()).
-    m_expandedViews.append(view);
-    m_controller->triggerItem(index);
-}
-
 void DolphinView::loadDirectory(const KUrl& url, bool reload)
 {
     if (!url.isValid()) {
@@ -1285,8 +1303,13 @@ void DolphinView::createView()
 
         FolderExpander* folderExpander = new FolderExpander(view, m_proxyModel);
         folderExpander->setEnabled(enabled);
-        connect(folderExpander, SIGNAL(enterDir(const QModelIndex&, QAbstractItemView*)),
-                this, SLOT(enterDir(const QModelIndex&, QAbstractItemView*)));
+        connect(folderExpander, SIGNAL(enterDir(const QModelIndex&)),
+                m_controller, SLOT(triggerItem(const QModelIndex&)));
+    }
+    else {
+        // Listen out for requests to delete the current column.
+        connect(m_columnView, SIGNAL(requestColumnDeletion(QAbstractItemView*)),
+                this, SLOT(deleteWhenNotDragSource(QAbstractItemView*)));
     }
 
     m_controller->setItemView(view);
@@ -1342,29 +1365,18 @@ void DolphinView::deleteView()
         m_topLayout->removeWidget(view);
         view->close();
 
+        // m_previewGenerator's parent is not always destroyed, and we
+        // don't want two active at once - manually delete.
+        delete m_previewGenerator;
+        m_previewGenerator = 0;
+
         disconnect(view);
         m_controller->disconnect(view);
         view->disconnect();
 
-        bool deleteView = true;
-        foreach (const QAbstractItemView* expandedView, m_expandedViews) {
-            if (view == expandedView) {
-                // the current view got already expanded and must stay alive
-                // until the dragging has been completed
-                deleteView = false;
-                break;
-            }
-        }
-        if (deleteView) {
-            view->deleteLater();
-        }
+        deleteWhenNotDragSource(view);
         view = 0;
 
-        // m_previewGenerator's parent is not always destroyed, and we
-        // don't want two active at once - manually delete.
-        delete m_previewGenerator;
-        m_previewGenerator = 0;
-
         m_iconsView = 0;
         m_detailsView = 0;
         m_columnView = 0;
@@ -1434,17 +1446,6 @@ KUrl::List DolphinView::simplifiedSelectedUrls() const
     return list;
 }
 
-void DolphinView::deleteExpandedViews()
-{
-    const QAbstractItemView* view = itemView();
-    foreach (QAbstractItemView* expandedView, m_expandedViews) {
-        if (expandedView != view) {
-            expandedView->deleteLater();
-        }
-    }
-    m_expandedViews.clear();
-}
-
 QMimeData* DolphinView::selectionMimeData() const
 {
     if (isColumnViewActive()) {
index 9dd001c8e7cda7661d1f0fb305b4fc2db42db3d3..ea77024a6ce8a81ea6e4c4909d39681b01abe989 100644 (file)
@@ -628,10 +628,11 @@ private slots:
     void restoreCurrentItem();
 
     /**
-     * Is connected to the enterDir() signal from the FolderExpander
-     * and triggers the entering of the directory indicated by \a index.
+     * If \a view can be positively identified as not being the source for the 
+     * current drag operation, deleteLater() it immediately.  Else stores 
+     * it for later deletion.
      */
-    void enterDir(const QModelIndex& index, QAbstractItemView* view);
+    void deleteWhenNotDragSource(QAbstractItemView* view);
 
 private:
     void loadDirectory(const KUrl& url, bool reload = false);
@@ -699,12 +700,6 @@ private:
      */
     bool isColumnViewActive() const;
 
-    /**
-     * Deletes all views from m_expandedViews except if the view
-     * is currently shown.
-     */
-    void deleteExpandedViews();
-
     /**
      * Returns the MIME data for all selected items.
      */
@@ -741,7 +736,7 @@ private:
     KUrl m_rootUrl;
     KUrl m_currentItemUrl;
 
-    QList<QAbstractItemView*> m_expandedViews;
+    QAbstractItemView*  m_expandedDragSource;
 };
 
 inline bool DolphinView::isColumnViewActive() const
index 3ff7d296a520b900c503a0a08fd3d8fe69e48af1..002394155f74b4fdb97a529dfa54ae00a37c0e76 100644 (file)
@@ -80,10 +80,18 @@ void DragAndDropHelper::startDrag(QAbstractItemView* itemView,
         }
         drag->setPixmap(pixmap);
         drag->setMimeData(data);
+
+        m_dragSource = itemView;
         drag->exec(supportedActions, Qt::IgnoreAction);
+        m_dragSource = 0;
     }
 }
 
+bool DragAndDropHelper::isDragSource(QAbstractItemView* itemView)
+{
+    return (m_dragSource != 0) && (m_dragSource == itemView);
+}
+
 void DragAndDropHelper::dropUrls(const KFileItem& destItem,
                                  const KUrl& destPath,
                                  QDropEvent* event,
@@ -115,6 +123,7 @@ void DragAndDropHelper::dropUrls(const KFileItem& destItem,
 }
 
 DragAndDropHelper::DragAndDropHelper()
+    : m_dragSource(0)
 {
 }
 
index e362fd508fba8c3b2917b5fff82eeffe5564b693..4859740cd9dc02a4ea920ac8cc14363d455b6680 100644 (file)
@@ -61,6 +61,12 @@ public:
                    Qt::DropActions supportedActions,
                    DolphinController* controller = 0);
 
+    /**
+     * Returns true if and only if the view \a itemView was the last view to 
+     * be passed to startDrag(...), and that drag is still in progress.
+     */
+    bool isDragSource(QAbstractItemView* itemView);
+
     /**
      * Handles the dropping of URLs to the given
      * destination. A context menu with the options
@@ -80,6 +86,9 @@ signals:
 
 private:
     DragAndDropHelper();
+    // The last view passed in startDrag(...), or 0 if
+    // no startDrag(...) initiated drag is in progress.
+    QAbstractItemView *m_dragSource;
 
     friend class DragAndDropHelperSingleton;
 };
index 091cd0c2c8bba57f01a77cb1f861a805b4dbd4a2..1aaf09ded6e02441ada8fecce36fc501bd7e246f 100644 (file)
@@ -123,7 +123,7 @@ void FolderExpander::autoExpandTimeout()
             treeView->setExpanded(proxyIndexToExpand, !treeView->isExpanded(proxyIndexToExpand));
         }
         else {
-            emit enterDir(proxyIndexToExpand, m_view);
+            emit enterDir(proxyIndexToExpand);
         }
     }
 }
index 57b8e9e5505e819b2f13626c9c8159d4d56efc0b..73d16c5c42dd77f84be25edeaaec66230c461d88 100644 (file)
@@ -63,7 +63,7 @@ signals:
      * signal is not emitted when a QTreeView is used, as the entering of
      * the directory is already provided by expanding the tree node.
      */
-    void enterDir(const QModelIndex& dirModelIndex, QAbstractItemView* view);
+    void enterDir(const QModelIndex& dirModelIndex);
 
 
 private slots: