diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7af2760610..20bbf187a9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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 diff --git a/src/kitemviews/kfileitemlistwidget.cpp b/src/kitemviews/kfileitemlistwidget.cpp index a5a4f9c0b0..62a17710c9 100644 --- a/src/kitemviews/kfileitemlistwidget.cpp +++ b/src/kitemviews/kfileitemlistwidget.cpp @@ -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" diff --git a/src/kitemviews/kfileitemlistwidget.h b/src/kitemviews/kfileitemlistwidget.h index 4bd3754816..bb9034bfac 100644 --- a/src/kitemviews/kfileitemlistwidget.h +++ b/src/kitemviews/kfileitemlistwidget.h @@ -46,6 +46,7 @@ public: protected: virtual bool isRoleRightAligned(const QByteArray& role) const; + virtual bool isHidden() const; }; #endif diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp index 48849a3c13..2177c62965 100644 --- a/src/kitemviews/kitemlistview.cpp +++ b/src/kitemviews/kitemlistview.cpp @@ -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; } diff --git a/src/kitemviews/kstandarditem.cpp b/src/kitemviews/kstandarditem.cpp index 1754c531ba..e7655f9c81 100644 --- a/src/kitemviews/kstandarditem.cpp +++ b/src/kitemviews/kstandarditem.cpp @@ -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& values) +{ + m_data = values; +} + QHash KStandardItem::data() const { return m_data; diff --git a/src/kitemviews/kstandarditem.h b/src/kitemviews/kstandarditem.h index a108572a78..3628989a2d 100644 --- a/src/kitemviews/kstandarditem.h +++ b/src/kitemviews/kstandarditem.h @@ -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& values); QHash data() const; + QList children() const; private: diff --git a/src/kitemviews/kstandarditemlistwidget.cpp b/src/kitemviews/kstandarditemlistwidget.cpp index 43df72f953..14a3db0666 100644 --- a/src/kitemviews/kstandarditemlistwidget.cpp +++ b/src/kitemviews/kstandarditemlistwidget.cpp @@ -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 values = data(); m_isExpandable = m_supportsItemExpanding && values["isExpandable"].toBool(); - m_isHidden = values["text"].toString().startsWith(QLatin1Char('.')); + m_isHidden = isHidden(); updateExpansionArea(); updateTextsCache(); diff --git a/src/kitemviews/kstandarditemlistwidget.h b/src/kitemviews/kstandarditemlistwidget.h index 1bd44e2f6a..d942b89a99 100644 --- a/src/kitemviews/kstandarditemlistwidget.h +++ b/src/kitemviews/kstandarditemlistwidget.h @@ -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; diff --git a/src/kitemviews/kstandarditemmodel.cpp b/src/kitemviews/kstandarditemmodel.cpp index 04749b9b5b..d0be1325f7 100644 --- a/src/kitemviews/kstandarditemmodel.cpp +++ b/src/kitemviews/kstandarditemmodel.cpp @@ -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 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 > 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" diff --git a/src/kitemviews/kstandarditemmodel.h b/src/kitemviews/kstandarditemmodel.h index 5cf60085b6..d1a036fd09 100644 --- a/src/kitemviews/kstandarditemmodel.h +++ b/src/kitemviews/kstandarditemmodel.h @@ -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 data(int index) const; virtual bool setData(int index, const QHash& values); @@ -59,6 +76,25 @@ public: virtual QString roleDescription(const QByteArray& role) const; virtual QList > 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 m_items; QHash m_indexesForItems; diff --git a/src/panels/places/placesitemlistwidget.cpp b/src/panels/places/placesitemlistwidget.cpp new file mode 100644 index 0000000000..3f4c92dfad --- /dev/null +++ b/src/panels/places/placesitemlistwidget.cpp @@ -0,0 +1,36 @@ +/*************************************************************************** + * Copyright (C) 2012 by Peter Penz * + * * + * 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 index 0000000000..28e0f00e83 --- /dev/null +++ b/src/panels/places/placesitemlistwidget.h @@ -0,0 +1,39 @@ +/*************************************************************************** + * Copyright (C) 2012 by Peter Penz * + * * + * 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 + +class PlacesItemListWidget : public KStandardItemListWidget +{ + Q_OBJECT + +public: + PlacesItemListWidget(KItemListWidgetInformant* informant, QGraphicsItem* parent); + virtual ~PlacesItemListWidget(); + +protected: + virtual bool isHidden() const; +}; + +#endif + + diff --git a/src/panels/places/placesitemmodel.cpp b/src/panels/places/placesitemmodel.cpp index 023e873ebe..060c77f81f 100644 --- a/src/panels/places/placesitemmodel.cpp +++ b/src/panels/places/placesitemmodel.cpp @@ -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"); diff --git a/src/panels/places/placesitemmodel.h b/src/panels/places/placesitemmodel.h index f8f2b5bc8a..50f2be9d4e 100644 --- a/src/panels/places/placesitemmodel.h +++ b/src/panels/places/placesitemmodel.h @@ -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 m_systemBookmarks; QHash m_systemBookmarksIndexes; + + QList m_hiddenItems; }; #endif diff --git a/src/panels/places/placespanel.cpp b/src/panels/places/placespanel.cpp index ea2ec30727..dc0f2b8baa 100644 --- a/src/panels/places/placespanel.cpp +++ b/src/panels/places/placespanel.cpp @@ -40,6 +40,7 @@ #include #include "placesitemeditdialog.h" #include "placesitemlistgroupheader.h" +#include "placesitemlistwidget.h" #include "placesitemmodel.h" #include #include @@ -77,6 +78,7 @@ void PlacesPanel::showEvent(QShowEvent* event) m_model->setSortRole("group"); KStandardItemListView* view = new KStandardItemListView(); + view->setWidgetCreator(new KItemListWidgetCreator()); view->setGroupHeaderCreator(new KItemListGroupHeaderCreator()); 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) { }