Commit 3f6c86e1 authored by Aidan Sojourner's avatar Aidan Sojourner Committed by Nate Graham

Add search/filter bar

Summary:
This diff contains a much-requested feature: adding a search or filter bar to KMenuEdit's application tree view. The search bar automatically expands categories as you search, then un-expands when search is cleared.

FEATURE: 57314
FIXED-IN: 5.16.0

Before:
{F6610037}

After:
{F6612274}

Test Plan: KMenuEdit's codebase is a mess; I noticed that there was only one unit test run by ctest! I'd love to write more tests in the future, but for this feature we don't need much.

Reviewers: ngraham, #plasma, cfeck

Reviewed By: ngraham

Subscribers: ognarb, mlaurent, ngraham, plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D18939
parent 074289a9
......@@ -20,6 +20,8 @@
#include "kmenuedit.h"
#include <QSplitter>
#include <QVBoxLayout>
#include <QFrame>
#include <QAction>
#include <KActionCollection>
......@@ -31,6 +33,7 @@
#include <KService>
#include <KStandardAction>
#include <KStandardShortcut>
#include <KTreeWidgetSearchLine>
#include <sonnet/configdialog.h>
#include "treeview.h"
......@@ -127,13 +130,33 @@ void KMenuEdit::slotConfigure()
void KMenuEdit::setupView()
{
// setup search and tree view
m_tree = new TreeView(actionCollection(), this);
m_searchLine = new KTreeWidgetSearchLine(this, m_tree);
m_searchLine->setCaseSensitivity(Qt::CaseSensitivity::CaseInsensitive);
m_searchLine->setKeepParentsVisible(true);
m_searchLine->setPlaceholderText(i18n("Search..."));
m_searchLine->setToolTip(i18n("Search through the list of applications below"));
QVBoxLayout *treeLayout = new QVBoxLayout;
treeLayout->addWidget(m_searchLine);
treeLayout->addWidget(m_tree);
treeLayout->setContentsMargins(0, 0, 0, 0); // no padding, fixes alignment issues
QFrame *treeFrame = new QFrame; // required to insert tree + search into splitter
treeFrame->setLayout(treeLayout);
m_splitter = new QSplitter(this);
m_splitter->setOrientation(Qt::Horizontal);
m_tree = new TreeView(actionCollection(), this);
m_splitter->addWidget(m_tree);
m_splitter->addWidget(treeFrame);
// setup info tab view
m_basicTab = new BasicTab;
m_splitter->addWidget(m_basicTab);
// add padding to splitter
m_splitter->setContentsMargins(/*left=*/5, /*top=*/0, /*right=*/5, /*bottom=*/0);
connect(m_tree, SIGNAL(entrySelected(MenuFolderInfo*)),
m_basicTab, SLOT(setFolderInfo(MenuFolderInfo*)));
connect(m_tree, SIGNAL(entrySelected(MenuEntryInfo*)),
......@@ -150,6 +173,8 @@ void KMenuEdit::setupView()
connect(m_basicTab, &BasicTab::findServiceShortcut,
m_tree, &TreeView::findServiceShortcut);
connect(m_searchLine, &KTreeWidgetSearchLine::searchUpdated,
m_tree, &TreeView::searchUpdated);
// restore splitter sizes
QList<int> sizes = ConfigurationManager::getInstance()->getSplitterSizes();
if (sizes.isEmpty()) {
......
......@@ -26,6 +26,7 @@ class QSplitter;
class QAction;
class BasicTab;
class TreeView;
class KTreeWidgetSearchLine;
class KMenuEdit : public KXmlGuiWindow
{
......@@ -56,6 +57,7 @@ protected:
TreeView *m_tree = nullptr;
BasicTab *m_basicTab = nullptr;
QSplitter *m_splitter = nullptr;
KTreeWidgetSearchLine *m_searchLine = nullptr;
QAction *m_actionDelete = nullptr;
bool m_showHidden = false;
......
......@@ -54,6 +54,7 @@
#include <kio/netaccess.h>
#include <KUrlMimeData>
#include <KUrl>
#include <KStringHandler>
#include "menufile.h"
#include "menuinfo.h"
......@@ -497,15 +498,6 @@ void TreeView::fillBranch(MenuFolderInfo *folderInfo, TreeItem *parent)
}
}
}
void TreeView::closeAllItems(QTreeWidgetItem *item)
{
item->setExpanded(false);
for (int i = 0; i < item->childCount(); ++i) {
closeAllItems(item->child(i));
}
}
TreeItem *TreeView::expandPath(TreeItem *item, const QString &path)
{
int i = path.indexOf(QStringLiteral("/"));
......@@ -534,9 +526,10 @@ TreeItem *TreeView::expandPath(TreeItem *item, const QString &path)
void TreeView::selectMenu(const QString &menu)
{
for (int i = 0; i < topLevelItemCount(); ++i) {
closeAllItems(topLevelItem(i));
}
// close all parent expansions and deselect everything
collapseAll();
setCurrentIndex(rootIndex());
if (menu.length() <= 1) {
setCurrentItem(topLevelItem(0));
......@@ -1926,6 +1919,18 @@ void TreeView::sendReloadMenu()
QDBusConnection::sessionBus().send(message);
}
// Slot to expand or retract items in tree based on length of search string
void TreeView::searchUpdated(const QString &searchString) {
// expand all categories if we typed more than a few characters, otherwise collapse and un-select everything
// use logicalLength for CJK users
if (KStringHandler::logicalLength(searchString) > 2) {
expandAll();
} else {
collapseAll();
setCurrentIndex(rootIndex());
}
}
MenuItemMimeData::MenuItemMimeData(TreeItem *item)
: QMimeData()
, m_item(item)
......
......@@ -182,6 +182,7 @@ public Q_SLOTS:
void currentDataChanged(MenuFolderInfo *folderInfo);
void currentDataChanged(MenuEntryInfo *entryInfo);
void findServiceShortcut(const QKeySequence &, KService::Ptr &);
void searchUpdated(const QString &searchString);
Q_SIGNALS:
void entrySelected(MenuFolderInfo *folderInfo);
......@@ -229,7 +230,6 @@ protected:
TreeItem *getParentItem(QTreeWidgetItem *item) const;
void moveUpOrDownItem(bool isMovingUpAction);
void closeAllItems(QTreeWidgetItem *item);
TreeItem *expandPath(TreeItem *item, const QString &path);
// moving = src will be removed later
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment