diff --git a/doc/ChangeLog b/doc/ChangeLog index b81b8d325..4fc5abae7 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -15,6 +15,12 @@ filter, all child elements (e.g. policies, interfaces) will be displayed as well. + * Fixed #2523: save the expanded/collapsed state of the tree when + the user starts typing something into the quick filter. When the + quick filter is cleared, re-expand any items that started off + expanded (so we get the union of expanded items displayed by quick + filter plus what the user started with expanded). + 2011-07-11 theron * Implemented #2514, support for address table alternate paths. There's a "data directory" setting under user preferences. If the diff --git a/src/libgui/ObjectTreeView.cpp b/src/libgui/ObjectTreeView.cpp index 25edf5d49..9d8f107a1 100644 --- a/src/libgui/ObjectTreeView.cpp +++ b/src/libgui/ObjectTreeView.cpp @@ -845,12 +845,14 @@ void ObjectTreeView::updateFilter() } static bool filterMatches(const QString &text, - ObjectTreeViewItem *item, - FWObject *obj) + ObjectTreeViewItem *item) { if (text.isEmpty()) return true; if (item->text(0).contains(text, Qt::CaseInsensitive)) return true; + if (item->getUserFolderParent() != 0) return false; + FWObject *obj = item->getFWObject(); + QByteArray utf8 = text.toUtf8(); set keys = obj->getKeywords(); set::const_iterator iter; @@ -862,22 +864,59 @@ static bool filterMatches(const QString &text, return false; } +static uint qHash(const QStringList &list) +{ + uint ret = 0; + for (int ii = 0; ii < list.size(); ii++) { + ret += qHash(list.at(ii)); + } + return ret; +} + +void ObjectTreeView::doExpandedState(bool save, QStringList &list, + QTreeWidgetItem *item) +{ + list.append(item->text(0)); + if (save) { + if (item->isExpanded()) expandedState.insert(list); + } else { + if (expandedState.contains(list)) item->setExpanded(true); + } + + for (int ii = 0; ii < item->childCount(); ii++) { + doExpandedState(save, list, item->child(ii)); + } + list.removeLast(); +} + void ObjectTreeView::setFilter(QString text) { + if (filter.isEmpty() && !text.isEmpty()) { + QStringList list; + for (int ii = 0; ii < topLevelItemCount(); ii++) { + doExpandedState(true, list, topLevelItem(ii)); + } + } else if (text.isEmpty() && !filter.isEmpty()) { + QStringList list; + for (int ii = 0; ii < topLevelItemCount(); ii++) { + doExpandedState(false, list, topLevelItem(ii)); + } + expandedState.clear(); + } + filter = text; + if (fwbdebug) qDebug() << "ObjectTreeView::setFilter " << text; list expand; for (QTreeWidgetItemIterator wit(this); *wit; ++wit) { ObjectTreeViewItem *otvi = dynamic_cast(*wit); - if (otvi->getUserFolderParent() != 0) continue; - FWObject *obj = otvi->getFWObject(); - if (filterMatches(text, otvi, obj)) { + if (filterMatches(text, otvi)) { (*wit)->setHidden(false); - if (Firewall::cast(obj) != 0) { + if (Firewall::cast(otvi->getFWObject()) != 0) { expand.push_back(otvi); } diff --git a/src/libgui/ObjectTreeView.h b/src/libgui/ObjectTreeView.h index d3a6c7b1a..21d0455db 100644 --- a/src/libgui/ObjectTreeView.h +++ b/src/libgui/ObjectTreeView.h @@ -72,6 +72,8 @@ class ObjectTreeView : public QTreeWidget QSet resolveParents(QTreeWidgetItem*); QString filter; + QSet expandedState; + void doExpandedState(bool save, QStringList &list, QTreeWidgetItem *item); protected: