]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Places Panel: Allow hiding of items
authorPeter Penz <peter.penz19@gmail.com>
Tue, 1 May 2012 21:11:06 +0000 (23:11 +0200)
committerPeter Penz <peter.penz19@gmail.com>
Tue, 1 May 2012 21:14:52 +0000 (23:14 +0200)
Related changes:
- Animate changed items for the details-view in case it is not expandable
- Remove the hardcoded "isHidden"-code in KStandardItemListWidget and
  allow derived widgets to define themselves what means "hidden" within
  their context.

The current code needs a lot of bugfixing, but lets make this in smaller
steps during the next days...

15 files changed:
src/CMakeLists.txt
src/kitemviews/kfileitemlistwidget.cpp
src/kitemviews/kfileitemlistwidget.h
src/kitemviews/kitemlistview.cpp
src/kitemviews/kstandarditem.cpp
src/kitemviews/kstandarditem.h
src/kitemviews/kstandarditemlistwidget.cpp
src/kitemviews/kstandarditemlistwidget.h
src/kitemviews/kstandarditemmodel.cpp
src/kitemviews/kstandarditemmodel.h
src/panels/places/placesitemlistwidget.cpp [new file with mode: 0644]
src/panels/places/placesitemlistwidget.h [new file with mode: 0644]
src/panels/places/placesitemmodel.cpp
src/panels/places/placesitemmodel.h
src/panels/places/placespanel.cpp

index 7af27606100174a848e76ec562697196ea002be9..20bbf187a9941f2d353e739520dc87f69bf8b27b 100644 (file)
@@ -145,6 +145,7 @@ set(dolphin_SRCS
     panels/places/placespanel.cpp
     panels/places/placesitemeditdialog.cpp
     panels/places/placesitemlistgroupheader.cpp
+    panels/places/placesitemlistwidget.cpp
     panels/places/placesitemmodel.cpp
     panels/panel.cpp
     panels/folders/treeviewcontextmenu.cpp
index a5a4f9c0b02bf717997b3cf18d726a5939450bbb..62a17710c948357e973bfe19c807e52996eacce0 100644 (file)
@@ -88,4 +88,9 @@ bool KFileItemListWidget::isRoleRightAligned(const QByteArray& role) const
     return role == "size";
 }
 
+bool KFileItemListWidget::isHidden() const
+{
+    return data().value("text").toString().startsWith(QLatin1Char('.'));
+}
+
 #include "kfileitemlistwidget.moc"
index 4bd37548165e5ef96200647739e70260f9d5b535..bb9034bfaccb9586250aac452df274493c8bad5d 100644 (file)
@@ -46,6 +46,7 @@ public:
 
 protected:
     virtual bool isRoleRightAligned(const QByteArray& role) const;
+    virtual bool isHidden() const;
 };
 
 #endif
index 48849a3c13c9880c7c6692c441d54067bf15b6a9..2177c629653f17ee33f4af07568b24091341b065 100644 (file)
@@ -1701,17 +1701,22 @@ bool KItemListView::moveWidget(KItemListWidget* widget,const QPointF& newPos)
 
     bool startMovingAnim = false;
 
-    // When having a grid the moving-animation should only be started, if it is done within
-    // one row in the vertical scroll-orientation or one column in the horizontal scroll-orientation.
-    // Otherwise instead of a moving-animation a create-animation on the new position will be used
-    // instead. This is done to prevent overlapping (and confusing) moving-animations.
-    const int index = widget->index();
-    const Cell cell = m_visibleCells.value(index);
-    if (cell.column >= 0 && cell.row >= 0) {
-        if (scrollOrientation() == Qt::Vertical) {
-            startMovingAnim = (cell.row == m_layouter->itemRow(index));
-        } else {
-            startMovingAnim = (cell.column == m_layouter->itemColumn(index));
+    if (m_itemSize.isEmpty()) {
+        // The items are not aligned in a grid but either as columns or rows.
+        startMovingAnim = !supportsItemExpanding();
+    } else {
+        // When having a grid the moving-animation should only be started, if it is done within
+        // one row in the vertical scroll-orientation or one column in the horizontal scroll-orientation.
+        // Otherwise instead of a moving-animation a create-animation on the new position will be used
+        // instead. This is done to prevent overlapping (and confusing) moving-animations.
+        const int index = widget->index();
+        const Cell cell = m_visibleCells.value(index);
+        if (cell.column >= 0 && cell.row >= 0) {
+            if (scrollOrientation() == Qt::Vertical) {
+                startMovingAnim = (cell.row == m_layouter->itemRow(index));
+            } else {
+                startMovingAnim = (cell.column == m_layouter->itemColumn(index));
+            }
         }
     }
 
@@ -2221,6 +2226,12 @@ bool KItemListView::changesItemGridLayout(const QSizeF& newGridSize,
 
 bool KItemListView::animateChangedItemCount(int changedItemCount) const
 {
+    if (m_itemSize.isEmpty()) {
+        // We have only columns or only rows, but no grid: An animation is usually
+        // welcome when inserting or removing items.
+        return !supportsItemExpanding();
+    }
+
     if (m_layouter->size().isEmpty() || m_layouter->itemSize().isEmpty()) {
         return false;
     }
index 1754c531bac472b822016f7dbc3e5b5a81b6dfb9..e7655f9c8113b50d68ab53c4277c61fc8b9e90de 100644 (file)
@@ -48,6 +48,14 @@ KStandardItem::KStandardItem(const QIcon& icon, const QString& text, KStandardIt
     setText(text);
 }
 
+KStandardItem::KStandardItem(const KStandardItem& item) :
+    m_parent(item.m_parent),
+    m_children(item.m_children),
+    m_model(item.m_model),
+    m_data(item.m_data)
+{
+}
+
 KStandardItem::~KStandardItem()
 {
 }
@@ -103,6 +111,11 @@ KStandardItem* KStandardItem::parent() const
     return m_parent;
 }
 
+void KStandardItem::setData(const QHash<QByteArray, QVariant>& values)
+{
+    m_data = values;
+}
+
 QHash<QByteArray, QVariant> KStandardItem::data() const
 {
     return m_data;
index a108572a78110db56296215bf180ede0e939e0ab..3628989a2d285e8922a1770479047f5aa9cb0b01 100644 (file)
@@ -44,6 +44,7 @@ public:
     explicit KStandardItem(KStandardItem* parent = 0);
     explicit KStandardItem(const QString& text, KStandardItem* parent = 0);
     KStandardItem(const QIcon& icon, const QString& text, KStandardItem* parent = 0);
+    KStandardItem(const KStandardItem& item);
     virtual ~KStandardItem();
 
     /**
@@ -70,7 +71,9 @@ public:
     void setParent(KStandardItem* parent);
     KStandardItem* parent() const;
 
+    void setData(const QHash<QByteArray, QVariant>& values);
     QHash<QByteArray, QVariant> data() const;
+
     QList<KStandardItem*> children() const;
 
 private:
index 43df72f9532cbec99dccfca280890d1fc492b5bb..14a3db066616f675640acffae6ad0d779f49a20a 100644 (file)
@@ -426,6 +426,11 @@ bool KStandardItemListWidget::isRoleRightAligned(const QByteArray& role) const
     return false;
 }
 
+bool KStandardItemListWidget::isHidden() const
+{
+    return false;
+}
+
 void KStandardItemListWidget::setTextColor(const QColor& color)
 {
     if (color != m_customTextColor) {
@@ -671,7 +676,7 @@ void KStandardItemListWidget::triggerCacheRefreshing()
 
     const QHash<QByteArray, QVariant> values = data();
     m_isExpandable = m_supportsItemExpanding && values["isExpandable"].toBool();
-    m_isHidden = values["text"].toString().startsWith(QLatin1Char('.'));
+    m_isHidden = isHidden();
 
     updateExpansionArea();
     updateTextsCache();
index 1bd44e2f6aedbad33622a3b1945c88ac42fd6bd3..d942b89a99852c732bac85142b0d1be15280c3fb 100644 (file)
@@ -108,6 +108,12 @@ protected:
      */
     virtual bool isRoleRightAligned(const QByteArray& role) const;
 
+    /**
+     * @return True if the item should be visually marked as hidden item. Per default
+     *         false is returned.
+     */
+    virtual bool isHidden() const;
+
     void setTextColor(const QColor& color);
     QColor textColor() const;
 
index 04749b9b5bdbd40fdd3e470bc40b194a4b57e51f..d0be1325f7b288c436196bf56b096f5aa8fbce2e 100644 (file)
@@ -38,19 +38,22 @@ KStandardItemModel::~KStandardItemModel()
 
 void KStandardItemModel::insertItem(int index, KStandardItem* item)
 {
-    if (!m_indexesForItems.contains(item) && !item->m_model) {
+    if (item && !m_indexesForItems.contains(item) && !item->m_model) {
+        item->m_model = this;
         m_items.insert(index, item);
         m_indexesForItems.insert(item, index);
-        item->m_model = this;
         // TODO: no hierarchical items are handled yet
 
+        onItemInserted(index);
         emit itemsInserted(KItemRangeList() << KItemRange(index, 1));
     }
 }
 
 void KStandardItemModel::replaceItem(int index, KStandardItem* item)
 {
-    if (index >= 0 && index < count()) {
+    if (item && index >= 0 && index < count() && !item->m_model) {
+        item->m_model = this;
+
         QSet<QByteArray> changedRoles;
 
         KStandardItem* oldItem= m_items[index];
@@ -75,6 +78,7 @@ void KStandardItemModel::replaceItem(int index, KStandardItem* item)
         m_items[index] = item;
         m_indexesForItems.insert(item, index);
 
+        onItemReplaced(index);
         emit itemsChanged(KItemRangeList() << KItemRange(index, 1), changedRoles);
     } else {
         kWarning() << "No item available to replace on the given index" << index;
@@ -83,11 +87,6 @@ void KStandardItemModel::replaceItem(int index, KStandardItem* item)
     }
 }
 
-void KStandardItemModel::appendItem(KStandardItem *item)
-{
-    insertItem(m_items.count(), item);
-}
-
 void KStandardItemModel::removeItem(int index)
 {
     if (index >= 0 && index < count()) {
@@ -97,6 +96,7 @@ void KStandardItemModel::removeItem(int index)
         delete item;
         item = 0;
 
+        onItemRemoved(index);
         emit itemsRemoved(KItemRangeList() << KItemRange(index, 1));
         // TODO: no hierarchical items are handled yet
     }
@@ -115,6 +115,11 @@ int KStandardItemModel::index(const KStandardItem* item) const
     return m_indexesForItems.value(item, -1);
 }
 
+void KStandardItemModel::appendItem(KStandardItem *item)
+{
+    insertItem(m_items.count(), item);
+}
+
 int KStandardItemModel::count() const
 {
     return m_items.count();
@@ -186,4 +191,20 @@ QList<QPair<int, QVariant> > KStandardItemModel::groups() const
     return groups;
 }
 
+void KStandardItemModel::onItemInserted(int index)
+{
+    Q_UNUSED(index);
+}
+
+void KStandardItemModel::onItemReplaced(int index)
+{
+    Q_UNUSED(index);
+}
+
+void KStandardItemModel::onItemRemoved(int index)
+{
+    Q_UNUSED(index);
+}
+
+
 #include "kstandarditemmodel.moc"
index 5cf60085b621cc0c4b9de330f7ae904ace28f0d3..d1a036fd09329ec6962aa79a4ea3b147f48f3074 100644 (file)
@@ -43,13 +43,30 @@ public:
     explicit KStandardItemModel(QObject* parent = 0);
     virtual ~KStandardItemModel();
 
+    /**
+     * Inserts the item \a item at the index \a index. If the index
+     * is equal to the number of items of the model, the item
+     * gets appended as last element. KStandardItemModel takes
+     * the ownership of the item.
+     */
     void insertItem(int index, KStandardItem* item);
+
+    /**
+     * Replaces the item on the index \a index by \a item.
+     * KStandardItemModel takes the ownership of the item. The
+     * old item gets deleted.
+     */
     void replaceItem(int index, KStandardItem* item);
-    void appendItem(KStandardItem* item);
+
     void removeItem(int index);
     KStandardItem* item(int index) const;
     int index(const KStandardItem* item) const;
 
+    /**
+     * Convenience method for insertItem(count(), item).
+     */
+    void appendItem(KStandardItem* item);
+
     virtual int count() const;
     virtual QHash<QByteArray, QVariant> data(int index) const;
     virtual bool setData(int index, const QHash<QByteArray, QVariant>& values);
@@ -59,6 +76,25 @@ public:
     virtual QString roleDescription(const QByteArray& role) const;
     virtual QList<QPair<int, QVariant> > groups() const;
 
+protected:
+    /**
+     * Is invoked after an item has been inserted and before the signal
+     * itemsInserted() gets emitted.
+     */
+    virtual void onItemInserted(int index);
+
+    /**
+     * Is invoked after an item has been replaced and before the signal
+     * itemsChanged() gets emitted.
+     */
+    virtual void onItemReplaced(int index);
+
+    /**
+     * Is invoked after an item has been removed and before the signal
+     * itemsRemoved() gets emitted.
+     */
+    virtual void onItemRemoved(int index);
+
 private:
     QList<KStandardItem*> m_items;
     QHash<const KStandardItem*, int> m_indexesForItems;
diff --git a/src/panels/places/placesitemlistwidget.cpp b/src/panels/places/placesitemlistwidget.cpp
new file mode 100644 (file)
index 0000000..3f4c92d
--- /dev/null
@@ -0,0 +1,36 @@
+/***************************************************************************
+ *   Copyright (C) 2012 by Peter Penz <peter.penz19@gmail.com>             *
+ *                                                                         *
+ *   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 "placesitemlistwidget.h"
+
+PlacesItemListWidget::PlacesItemListWidget(KItemListWidgetInformant* informant, QGraphicsItem* parent) :
+    KStandardItemListWidget(informant, parent)
+{
+}
+
+PlacesItemListWidget::~PlacesItemListWidget()
+{
+}
+
+bool PlacesItemListWidget::isHidden() const
+{
+    return data().value("isHidden").toBool();
+}
+
+#include "placesitemlistwidget.moc"
diff --git a/src/panels/places/placesitemlistwidget.h b/src/panels/places/placesitemlistwidget.h
new file mode 100644 (file)
index 0000000..28e0f00
--- /dev/null
@@ -0,0 +1,39 @@
+/***************************************************************************
+ *   Copyright (C) 2012 by Peter Penz <peter.penz19@gmail.com>             *
+ *                                                                         *
+ *   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 PLACESITEMLISTWIDGET_H
+#define PLACESITEMLISTWIDGET_H
+
+#include <kitemviews/kstandarditemlistwidget.h>
+
+class PlacesItemListWidget : public KStandardItemListWidget
+{
+    Q_OBJECT
+
+public:
+    PlacesItemListWidget(KItemListWidgetInformant* informant, QGraphicsItem* parent);
+    virtual ~PlacesItemListWidget();
+
+protected:
+    virtual bool isHidden() const;
+};
+
+#endif
+
+
index 023e873ebe995ab355ccdaa376247608fe1e61e9..060c77f81f3e73a0dfefd1a4ac8986ca8c296db5 100644 (file)
@@ -52,7 +52,8 @@ PlacesItemModel::PlacesItemModel(QObject* parent) :
     m_availableDevices(),
     m_bookmarkManager(0),
     m_systemBookmarks(),
-    m_systemBookmarksIndexes()
+    m_systemBookmarksIndexes(),
+    m_hiddenItems()
 {
 #ifdef HAVE_NEPOMUK
     m_nepomukRunning = (Nepomuk::ResourceManager::instance()->initialized());
@@ -66,11 +67,40 @@ PlacesItemModel::PlacesItemModel(QObject* parent) :
 
 PlacesItemModel::~PlacesItemModel()
 {
+    qDeleteAll(m_hiddenItems);
+    m_hiddenItems.clear();
 }
 
 int PlacesItemModel::hiddenCount() const
 {
-    return 0;
+    int itemCount = 0;
+    foreach (const KStandardItem* item, m_hiddenItems) {
+        if (item) {
+            ++itemCount;
+        }
+    }
+
+    return itemCount;
+}
+
+void PlacesItemModel::setItemHidden(int index, bool hide)
+{
+    if (index >= 0 && index < count()) {
+        KStandardItem* shownItem = this->item(index);
+        shownItem->setDataValue("isHidden", hide);
+        if (!m_hiddenItemsShown && hide) {
+            KStandardItem* hiddenItem = new KStandardItem(*shownItem);
+            removeItem(index);
+            index = hiddenIndex(index);
+            Q_ASSERT(!m_hiddenItems[index]);
+            m_hiddenItems[index] = hiddenItem;
+        }
+    }
+}
+
+bool PlacesItemModel::isItemHidden(int index) const
+{
+    return (index >= 0 && index < count()) ? m_hiddenItems[index] != 0 : false;
 }
 
 void PlacesItemModel::setHiddenItemsShown(bool show)
@@ -140,6 +170,18 @@ QAction* PlacesItemModel::tearDownAction(int index) const
     return 0;
 }
 
+void PlacesItemModel::onItemInserted(int index)
+{
+    m_hiddenItems.insert(hiddenIndex(index), 0);
+}
+
+void PlacesItemModel::onItemRemoved(int index)
+{
+    const int removeIndex = hiddenIndex(index);
+    Q_ASSERT(!m_hiddenItems[removeIndex]);
+    m_hiddenItems.removeAt(removeIndex);
+}
+
 void PlacesItemModel::loadBookmarks()
 {
     KBookmarkGroup root = m_bookmarkManager->root();
@@ -187,7 +229,11 @@ void PlacesItemModel::loadBookmarks()
                 item->setGroup(i18nc("@item", "Places"));
             }
 
-            appendItem(item);
+            if (bookmark.metaDataItem("IsHidden") == QLatin1String("true")) {
+                m_hiddenItems.append(item);
+            } else {
+                appendItem(item);
+            }
         }
 
         bookmark = root.next(bookmark);
@@ -276,6 +322,20 @@ void PlacesItemModel::createSystemBookmarks()
     }
 }
 
+int PlacesItemModel::hiddenIndex(int index) const
+{
+    int hiddenIndex = 0;
+    int visibleItemIndex = 0;
+    while (visibleItemIndex < index && hiddenIndex < m_hiddenItems.count()) {
+        if (!m_hiddenItems[hiddenIndex]) {
+            ++visibleItemIndex;
+        }
+        ++hiddenIndex;
+    }
+
+    return hiddenIndex;
+}
+
 QString PlacesItemModel::placesGroupName()
 {
     return i18nc("@item", "Places");
index f8f2b5bc8ad99ffd8410a90c404379a8b8ca6903..50f2be9d4eb3c4ef3973056a8932582be957e82d 100644 (file)
@@ -55,6 +55,9 @@ public:
 
     int hiddenCount() const;
 
+    void setItemHidden(int index, bool hide);
+    bool isItemHidden(int index) const;
+
     /**
      * @return True if the item is a default item created by
      *         the system (e.g. the places for home, root, trash etc.)
@@ -79,11 +82,17 @@ public:
     QAction* ejectAction(int index) const;
     QAction* tearDownAction(int index) const;
 
+protected:
+    virtual void onItemInserted(int index);
+    virtual void onItemRemoved(int index);
+
 private:
     void loadBookmarks();
 
     void createSystemBookmarks();
 
+    int hiddenIndex(int index) const;
+
     static QString placesGroupName();
     static QString recentlyAccessedGroupName();
     static QString searchForGroupName();
@@ -140,6 +149,8 @@ private:
 
     QList<SystemBookmarkData> m_systemBookmarks;
     QHash<KUrl, int> m_systemBookmarksIndexes;
+
+    QList<KStandardItem*> m_hiddenItems;
 };
 
 #endif
index ea2ec307271fcdeb0290e1cc28335634a7b1b769..dc0f2b8baa9865a95f4ebbb0ea2631791accc034 100644 (file)
@@ -40,6 +40,7 @@
 #include <KNotification>
 #include "placesitemeditdialog.h"
 #include "placesitemlistgroupheader.h"
+#include "placesitemlistwidget.h"
 #include "placesitemmodel.h"
 #include <views/draganddrophelper.h>
 #include <QVBoxLayout>
@@ -77,6 +78,7 @@ void PlacesPanel::showEvent(QShowEvent* event)
         m_model->setSortRole("group");
 
         KStandardItemListView* view = new KStandardItemListView();
+        view->setWidgetCreator(new KItemListWidgetCreator<PlacesItemListWidget>());
         view->setGroupHeaderCreator(new KItemListGroupHeaderCreator<PlacesItemListGroupHeader>());
 
         m_controller = new KItemListController(m_model, view, this);
@@ -167,7 +169,7 @@ void PlacesPanel::slotItemContextMenuRequested(int index, const QPointF& pos)
 
     QAction* hideAction = menu.addAction(i18nc("@item:inmenu", "Hide Entry '%1'", label));
     hideAction->setCheckable(true);
-    //hideEntry->setChecked(data.value("hidden").toBool());
+    hideAction->setChecked(data.value("isHidden").toBool());
 
     QAction* showAllAction = 0;
     if (m_model->hiddenCount() > 0) {
@@ -176,7 +178,7 @@ void PlacesPanel::slotItemContextMenuRequested(int index, const QPointF& pos)
         }
         showAllAction = menu.addAction(i18nc("@item:inmenu", "Show All Entries"));
         showAllAction->setCheckable(true);
-        //showAllEntries->setChecked(showAll)
+        showAllAction->setChecked(m_model->hiddenItemsShown());
     }
 
     QAction* removeAction = 0;
@@ -200,7 +202,9 @@ void PlacesPanel::slotItemContextMenuRequested(int index, const QPointF& pos)
         } else if (action == removeAction) {
             m_model->removeItem(index);
         } else if (action == hideAction) {
+            m_model->setItemHidden(index, hideAction->isChecked());
         } else if (action == showAllAction) {
+            m_model->setHiddenItemsShown(showAllAction->isChecked());
         } else if (action == tearDownAction) {
         } else if (action == ejectAction) {
         }