]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/dolphinview.h
Fix temporary regression of sorting introduced by SVN commit 1126410
[dolphin.git] / src / dolphinview.h
index ea77024a6ce8a81ea6e4c4909d39681b01abe989..352841f4a0a28746bf8e36dee3153e1f40790405 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2006 by Peter Penz <peter.penz@gmx.at>                  *
+ *   Copyright (C) 2006-2009 by Peter Penz <peter.penz@gmx.at>             *
  *   Copyright (C) 2006 by Gregor Kališnik <gregor@podnapisi.net>          *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
 #include <QKeyEvent>
 #include <QLinkedList>
 #include <QListView>
+#include <QSet>
 #include <QWidget>
 
-class DolphinController;
-class DolphinColumnView;
+typedef KIO::FileUndoManager::CommandType CommandType;
+
+class DolphinColumnViewContainer;
 class DolphinDetailsView;
-class DolphinFileItemDelegate;
 class DolphinIconsView;
-class DolphinMainWindow;
 class DolphinModel;
 class DolphinSortFilterProxyModel;
+class DolphinViewController;
 class KFilePreviewGenerator;
 class KAction;
 class KActionCollection;
 class KDirLister;
 class KUrl;
-class KToggleAction;
-class ToolTipManager;
-class QModelIndex;
+class ViewModeController;
 class ViewProperties;
+class DolphinDetailsViewExpander;
 
 /**
  * @short Represents a view for the directory content.
@@ -113,26 +113,20 @@ public:
         SortByOwner,
         SortByGroup,
         SortByType,
-        SortByRating,
-        SortByTags,
-        MaxSortEnum = SortByTags
+        SortByDestination,
+        SortByPath,
+        MaxSortingEnum = SortByPath
     };
 
     /**
      * @param parent           Parent widget of the view.
      * @param url              Specifies the content which should be shown.
-     * @param dirLister        Used directory lister. The lister is not owned
-     *                         by the view and won't get deleted.
-     * @param dolphinModel     Used directory model. The model is not owned
-     *                         by the view and won't get deleted.
      * @param proxyModel       Used proxy model which specifies the sorting. The
      *                         model is not owned by the view and won't get
      *                         deleted.
      */
     DolphinView(QWidget* parent,
                 const KUrl& url,
-                KDirLister* dirLister,
-                DolphinModel* dolphinModel,
                 DolphinSortFilterProxyModel* proxyModel);
 
     virtual ~DolphinView();
@@ -141,7 +135,7 @@ public:
      * Returns the current active URL, where all actions are applied.
      * The URL navigator is synchronized with this URL.
      */
-    const KUrl& url() const;
+    KUrl url() const;
 
     /**
      * Returns the root URL of the view, which is defined as the first
@@ -188,22 +182,12 @@ public:
     bool supportsCategorizedSorting() const;
 
     /**
-     * Selects all items.
-     * @see DolphinView::selectedItems()
-     */
-    void selectAll();
-
-    /**
-     * Inverts the current selection: selected items get unselected,
-     * unselected items get selected.
-     * @see DolphinView::selectedItems()
+     * Marks the items indicated by \p urls to get selected after the
+     * directory DolphinView::url() has been loaded. Note that nothing
+     * gets selected if no loading of a directory has been triggered
+     * by DolphinView::setUrl() or DolphinView::reload().
      */
-    void invertSelection();
-
-    /** Returns true, if at least one item is selected. */
-    bool hasSelection() const;
-
-    void clearSelection();
+    void markUrlsAsSelected(const QList<KUrl>& urls);
 
     /**
      * Returns the selected items. The list is empty if no item has been
@@ -225,15 +209,7 @@ public:
      */
     int selectedItemsCount() const;
 
-    /**
-     * Sets the upper left position of the view content
-     * to (x,y). The content of the view might be larger than the visible area
-     * and hence a scrolling must be done.
-     */
-    void setContentsPosition(int x, int y);
-
-    /** Returns the upper left position of the view content. */
-    QPoint contentsPosition() const;
+    QItemSelectionModel* selectionModel() const;
 
     /**
      * Sets the zoom level to \a level. It is assured that the used
@@ -267,6 +243,12 @@ public:
     /** Returns the current used sort order (Qt::Ascending or Qt::Descending). */
     Qt::SortOrder sortOrder() const;
 
+    /** Sets a separate sorting with folders first (true) or a mixed sorting of files and folders (false). */
+    void setSortFoldersFirst(bool foldersFirst);
+
+    /** Returns if files and folders are sorted separately or not. */
+    bool sortFoldersFirst() const;
+
     /** Sets the additional information which should be shown for the items. */
     void setAdditionalInfo(KFileItemDelegate::InformationList info);
 
@@ -283,16 +265,6 @@ public:
      */
     void refresh();
 
-    /**
-     * Changes the directory of the view to \a url. If \a rootUrl is empty, the view
-     * properties from \a url are used for adjusting the view mode and the other properties.
-     * If \a rootUrl is not empty, the view properties from the root URL are considered
-     * instead. Specifying a root URL is only required if a view having a different root URL
-     * (e. g. the column view) should be restored. Usually using DolphinView::setUrl()
-     * is enough for changing the current URL.
-     */
-    void updateView(const KUrl& url, const KUrl& rootUrl);
-
     /**
      * Filters the currently shown items by \a nameFilter. All items
      * which contain the given filter string will be shown.
@@ -315,6 +287,12 @@ public:
      */
     QString statusBarText() const;
 
+    /**
+     * Returns the version control actions that are provided for the items \p items.
+     * Usually the actions are presented in the context menu.
+     */
+    QList<QAction*> versionControlActions(const KFileItemList& items) const;
+
     /**
      * Updates the state of the 'Additional Information' actions in \a collection.
      */
@@ -342,6 +320,16 @@ public:
      */
     bool itemsExpandable() const;
 
+    /**
+     * Restores the view state (current item, contents position, details view expansion state)
+     */
+    void restoreState(QDataStream& stream);
+
+    /**
+     * Saves the view state (current item, contents position, details view expansion state)
+     */
+    void saveState(QDataStream& stream);
+
 public slots:
     /**
      * Changes the directory to \a url. If the current directory is equal to
@@ -350,12 +338,22 @@ public slots:
     void setUrl(const KUrl& url);
 
     /**
-     * Request of a selection change. The view will do its best to accommodate
-     * the request, but it is not guaranteed that all items in \a selection
-     * will actually get selected. The view will e.g. not select items which
-     * are not in the currently displayed folder.
+     * Selects all items.
+     * @see DolphinView::selectedItems()
      */
-    void changeSelection(const KFileItemList& selection);
+    void selectAll();
+
+    /**
+     * Inverts the current selection: selected items get unselected,
+     * unselected items get selected.
+     * @see DolphinView::selectedItems()
+     */
+    void invertSelection();
+
+    /** Returns true, if at least one item is selected. */
+    bool hasSelection() const;
+
+    void clearSelection();
 
     /**
      * Triggers the renaming of the currently selected items, where
@@ -375,7 +373,7 @@ public slots:
 
     /**
      * Copies all selected items to the clipboard and marks
-     * the items as cutted.
+     * the items as cut.
      */
     void cutSelectedItems();
 
@@ -422,6 +420,9 @@ public slots:
     /** Switches between an ascending and descending sorting order. */
     void toggleSortOrder();
 
+    /** Switches between a separate sorting (with folders first) and a mixed sorting of files and folders. */
+    void toggleSortFoldersFirst();
+
     /**
      * Switches on or off the displaying of additional information
      * as specified by \a action.
@@ -437,12 +438,6 @@ signals:
     /** Is emitted if URL of the view has been changed to \a url. */
     void urlChanged(const KUrl& url);
 
-    /**
-     * Is emitted if the view requests a changing of the current
-     * URL to \a url (see DolphinController::triggerUrlChangeRequest()).
-     */
-    void requestUrlChange(const KUrl& url);
-
     /**
      * Is emitted when clicking on an item with the left mouse button.
      */
@@ -474,6 +469,9 @@ signals:
     /** Is emitted if the sort order (ascending or descending) has been changed. */
     void sortOrderChanged(Qt::SortOrder order);
 
+    /** Is emitted if the sorting of files and folders (separate with folders first or mixed) has been changed. */
+    void sortFoldersFirstChanged(bool foldersFirst);
+
     /** Is emitted if the additional information shown for this view has been changed. */
     void additionalInfoChanged();
 
@@ -486,9 +484,6 @@ signals:
      */
     void requestItemInfo(const KFileItem& item);
 
-    /** Is emitted if the contents has been moved to \a x, \a y. */
-    void contentsMoved(int x, int y);
-
     /**
      * Is emitted whenever the selection has been changed.
      */
@@ -496,10 +491,13 @@ signals:
 
     /**
      * Is emitted if a context menu is requested for the item \a item,
-     * which is part of \a url. If the item is 0, the context menu
-     * for the URL should be shown.
+     * which is part of \a url. If the item is null, the context menu
+     * for the URL should be shown and the custom actions \a customActions
+     * will be added.
      */
-    void requestContextMenu(const KFileItem& item, const KUrl& url);
+    void requestContextMenu(const KFileItem& item,
+                            const KUrl& url,
+                            const QList<QAction*>& customActions);
 
     /**
      * Is emitted if an information message with the content \a msg
@@ -536,7 +534,6 @@ signals:
 protected:
     /** @see QWidget::mouseReleaseEvent */
     virtual void mouseReleaseEvent(QMouseEvent* event);
-    virtual void wheelEvent(QWheelEvent* event);
     virtual bool eventFilter(QObject* watched, QEvent* event);
 
 private slots:
@@ -553,6 +550,19 @@ private slots:
      */
     void triggerItem(const KFileItem& index);
 
+    /**
+     * Emits the signal \a selectionChanged() with a small delay. This is
+     * because getting all file items for the signal can be an expensive
+     * operation. Fast selection changes are collected in this case and
+     * the signal is emitted only after no selection change has been done
+     * within a small delay.
+     */
+    void slotSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected);
+
+    /**
+     * Is called by emitDelayedSelectionChangedSignal() and emits the
+     * signal \a selectionChanged() with all selected file items as parameter.
+     */
     void emitSelectionChangedSignal();
 
     /**
@@ -560,7 +570,7 @@ private slots:
      * is used to check whether the context menu is related to an
      * item or to the viewport.
      */
-    void openContextMenu(const QPoint& pos);
+    void openContextMenu(const QPoint& pos, const QList<QAction*>& customActions);
 
     /**
      * Drops dragged URLs to the destination path \a destPath. If
@@ -585,15 +595,15 @@ private slots:
 
     /**
      * Updates the view properties of the current URL to the
-     * additional information given by \a info.
+     * sorting of files and folders (separate with folders first or mixed) given by \a foldersFirst.
      */
-    void updateAdditionalInfo(const KFileItemDelegate::InformationList& info);
+    void updateSortFoldersFirst(bool foldersFirst);
 
     /**
-     * Emits the signal contentsMoved with the current coordinates
-     * of the viewport as parameters.
+     * Updates the view properties of the current URL to the
+     * additional information given by \a info.
      */
-    void emitContentsMoved();
+    void updateAdditionalInfo(const KFileItemDelegate::InformationList& info);
 
     /**
      * Updates the status bar to show hover information for the
@@ -616,61 +626,64 @@ private slots:
     void slotDeleteFileFinished(KJob* job);
 
     /**
-     * Is emitted if the controller requests a changing of the current
-     * URL to \a url
+     * Invoked when the directory lister has completed the loading of
+     * items. Assures that pasted items and renamed items get seleced.
      */
-    void slotRequestUrlChange(const KUrl& url);
+    void slotDirListerCompleted();
 
     /**
-     * Restores the current item (= item that has the keyboard focus)
-     * to m_currentItemUrl.
+     * Invoked when the loading of the directory is finished.
+     * Restores the active item and the scroll position if possible.
      */
-    void restoreCurrentItem();
+    void slotLoadingCompleted();
 
     /**
-     * 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.
+     * Is invoked when the KDirLister indicates refreshed items.
      */
-    void deleteWhenNotDragSource(QAbstractItemView* view);
+    void slotRefreshItems();
 
-private:
-    void loadDirectory(const KUrl& url, bool reload = false);
+    /**
+     * Observes the item with the URL \a url. As soon as the directory
+     * model indicates that the item is available, the item will
+     * get selected and it is assure that the item stays visible.
+     *
+     * @see selectAndScrollToCreatedItem()
+     */
+    void observeCreatedItem(const KUrl& url);
 
     /**
-     * Returns the URL where the view properties should be stored. Usually
-     * DolphinView::url() is returned, but in the case of a Column View the
-     * view properties are always stored in the directory represented by the
-     * first column. It is recommendend whenever using the ViewProperties class
-     * to use DolphinView::viewPropertiesUrl() as URL.
+     * Selects and scrolls to the item that got observed
+     * by observeCreatedItem().
      */
-    KUrl viewPropertiesUrl() const;
+    void selectAndScrollToCreatedItem();
 
     /**
-     * Applies the view properties which are defined by the current URL
-     * m_url to the DolphinView properties.
+     * Called when a redirection happens.
+     * Testcase: fish://localhost
      */
-    void applyViewProperties(const KUrl& url);
+    void slotRedirection(const KUrl& oldUrl, const KUrl& newUrl);
 
     /**
-     * Creates a new view representing the given view mode (DolphinView::mode()).
-     * The current view will get deleted.
+     * Restores the contents position, if history information about the old position is available.
      */
-    void createView();
+    void restoreContentsPosition();
 
-    void deleteView();
+private:
+    void loadDirectory(const KUrl& url, bool reload = false);
 
     /**
-     * Returns a pointer to the currently used item view, which is either
-     * a ListView or a TreeView.
+     * Applies the view properties which are defined by the current URL
+     * to the DolphinView properties.
      */
-    QAbstractItemView* itemView() const;
+    void applyViewProperties();
 
     /**
-     * Returns true, if the item \a item has been cut into
-     * the clipboard.
+     * Creates a new view representing the given view mode (DolphinView::mode()).
+     * The current view will get deleted.
      */
-    bool isCutItem(const KFileItem& item) const;
+    void createView();
+
+    void deleteView();
 
     /**
      * Helper method for DolphinView::paste() and DolphinView::pasteIntoFolder().
@@ -694,56 +707,112 @@ private:
     KUrl::List simplifiedSelectedUrls() const;
 
     /**
-     * Returns true, if the ColumnView is activated. As the column view
-     * requires some special handling for iterating through directories,
-     * this method has been introduced for convenience.
+     * Returns the MIME data for all selected items.
      */
-    bool isColumnViewActive() const;
+    QMimeData* selectionMimeData() const;
 
     /**
-     * Returns the MIME data for all selected items.
+     * Is invoked after a paste operation or a drag & drop
+     * operation and adds the filenames of all URLs from \a mimeData to
+     * m_newFileNames. This allows to select all newly added
+     * items in slotDirListerCompleted().
      */
-    QMimeData* selectionMimeData() const;
+    void addNewFileNames(const QMimeData* mimeData);
 
 private:
+    /**
+     * Abstracts the access to the different view implementations
+     * for icons-, details- and column-view.
+     */
+    class ViewAccessor
+    {
+    public:
+        ViewAccessor(DolphinSortFilterProxyModel* proxyModel);
+        ~ViewAccessor();
+
+        void createView(QWidget* parent,
+                        DolphinViewController* dolphinViewController,
+                        const ViewModeController* viewModeController,
+                        Mode mode);
+        void deleteView();
+
+        /**
+         * Must be invoked before the URL has been changed and allows view implementations
+         * like the column view to create a new column.
+         */
+        void prepareUrlChange(const KUrl& url);
+
+        QAbstractItemView* itemView() const;
+        KFileItemDelegate* itemDelegate() const;
+
+        /**
+         * Returns the widget that should be added to the layout as target. Usually
+         * the item view itself is returned, but in the case of the column view
+         * a container widget is returned.
+         */
+        QWidget* layoutTarget() const;
+
+        KUrl rootUrl() const;
+
+        bool supportsCategorizedSorting() const;
+        bool itemsExpandable() const;
+        QSet<KUrl> expandedUrls() const;
+        const DolphinDetailsViewExpander* setExpandedUrls(const QSet<KUrl>& urlsToExpand);
+
+        /**
+         * Returns true, if a reloading of the items is required
+         * when the additional information properties have been changed
+         * by the user.
+         */
+        bool reloadOnAdditionalInfoChange() const;
+
+        DolphinModel* dirModel() const;
+        DolphinSortFilterProxyModel* proxyModel() const;
+        KDirLister* dirLister() const;
+
+    private:
+        DolphinIconsView* m_iconsView;
+        DolphinDetailsView* m_detailsView;
+        DolphinColumnViewContainer* m_columnsContainer;
+        DolphinSortFilterProxyModel* m_proxyModel;
+        QAbstractItemView* m_dragSource;
+        QPointer<DolphinDetailsViewExpander> m_detailsViewExpander;
+    };
+
     bool m_active : 1;
     bool m_showPreview : 1;
-    bool m_loadingDirectory : 1;
     bool m_storedCategorizedSorting : 1;
     bool m_tabsForFiles : 1;
     bool m_isContextMenuOpen : 1;   // TODO: workaround for Qt-issue 207192
     bool m_ignoreViewProperties : 1;
+    bool m_assureVisibleCurrentIndex : 1;
+    bool m_expanderActive : 1;
 
     Mode m_mode;
 
-    DolphinMainWindow* m_mainWindow;
     QVBoxLayout* m_topLayout;
 
-    DolphinController* m_controller;
-    DolphinIconsView* m_iconsView;
-    DolphinDetailsView* m_detailsView;
-    DolphinColumnView* m_columnView;
-    DolphinFileItemDelegate* m_fileItemDelegate;
-    QItemSelectionModel* m_selectionModel;
-
-    DolphinModel* m_dolphinModel;
-    KDirLister* m_dirLister;
-    DolphinSortFilterProxyModel* m_proxyModel;
+    DolphinViewController* m_dolphinViewController;
+    ViewModeController* m_viewModeController;
+    ViewAccessor m_viewAccessor;
 
-    KFilePreviewGenerator* m_previewGenerator;
-    ToolTipManager* m_toolTipManager;
+    QItemSelectionModel* m_selectionModel; // allow to switch views without losing the selection
+    QTimer* m_selectionChangedTimer;
 
     KUrl m_rootUrl;
-    KUrl m_currentItemUrl;
+    KUrl m_activeItemUrl;
+    QPoint m_restoredContentsPosition;
+    KUrl m_createdItemUrl; // URL for a new item that got created by the "Create New..." menu
+    KFileItemList m_selectedItems; // this is used for making the View to remember selections after F5
 
-    QAbstractItemView*  m_expandedDragSource;
+    /**
+     * Remembers the filenames that have been added by a paste operation
+     * or a drag & drop operation. Allows to select the items in
+     * slotDirListerCompleted().
+     */
+    QSet<QString> m_newFileNames;
 };
 
-inline bool DolphinView::isColumnViewActive() const
-{
-    return m_columnView != 0;
-}
-
 /// Allow using DolphinView::Mode in QVariant
 Q_DECLARE_METATYPE(DolphinView::Mode)