Version: svn snapshot (using KDE Devel) Installed from: Compiled sources Compiler: gcc 4.1.1 with gentoo patches OS: Linux I hope a search lineedit, probably something like KListViewSearchLine, will be added to the browser interface. It should be handy when trying to pick up some files from a dir with huge number of items. An alternative approach could be improving the "Path" lineedit so that wildcard like "A*.tar.bz2" could be used.
Currently filters are supported by right-clicking on the list view and selecting "Set filter...". However, it might be better to move this option to the toolbar - what do you think ?
Sorry I never noticed that item in the popup menu, move it to the toolbar will certainly improve the usibility. And how about embed the lineedit to the main UI instead of a dialog. I mean that I press the filter button, some lineedit appeared in above the list, so that I can just type and filter?
Yep, I was thinking about the same thing. See how the filtering is done in the queue view, you can toggle the visibility of the filter widget.
Great, that's exactly what I thought.
SVN commit 578111 by kostko: Moved filtering to it's own toolbar and added a toggle button to improve usability. FEATURE: 133069 M +12 -19 actions.cpp M +2 -4 actions.h M +1 -4 listview.cpp M +8 -1 listview.h M +23 -1 view.cpp M +3 -0 view.h --- trunk/extragear/network/kftpgrabber/src/widgets/browser/actions.cpp #578110:578111 @@ -96,6 +96,7 @@ m_abortAction = new KAction(i18n("&Abort"), "stop", KShortcut(), this, SLOT(slotAbort()), actionCollection()); m_toggleTreeViewAction = new KToggleAction(i18n("&Show Tree View"), "view_tree", KShortcut(), this, SLOT(slotShowHideTree()), actionCollection()); + m_toggleFilterAction = new KToggleAction(i18n("Show &Filter"), "filter", KShortcut(), this, SLOT(slotShowHideFilter()), actionCollection(), "filter"); m_transferAction = new KAction(i18n("&Transfer"), KShortcut(), this, SLOT(slotTransfer()), actionCollection()); m_queueTransferAction = new KAction(i18n("&Queue Transfer"), "queue", KShortcut(), this, SLOT(slotQueueTransfer()), actionCollection()); @@ -103,8 +104,6 @@ m_renameAction = new KAction(i18n("&Rename"), KShortcut(), this, SLOT(slotRename()), actionCollection()); m_deleteAction = new KAction(i18n("&Delete"), "editdelete", KShortcut(), this, SLOT(slotDelete()), actionCollection()); m_propsAction = new KAction(i18n("&Properties"), KShortcut(), this, SLOT(slotProps()), actionCollection()); - m_setFilterAction = new KAction(i18n("&Set Filter..."), "filter", KShortcut(), this, SLOT(slotSetFilter()), actionCollection()); - m_clearFilterAction = new KAction(i18n("Clear Filter"), KShortcut(), this, SLOT(slotClearFilter()), actionCollection()); m_shredAction = new KAction(i18n("&Shred"), "editshred", KShortcut(), this, SLOT(slotShred()), actionCollection()); m_fileEditAction = new KAction(i18n("&Open file"), "fileopen", KShortcut(), this, SLOT(slotFileEdit()), actionCollection()); m_verifyAction = new KAction(i18n("&Verify..."), "ok", KShortcut(), this, SLOT(slotVerify()), actionCollection()); @@ -176,6 +175,7 @@ m_reloadAction->setEnabled(m_dirView->m_list->canMoveTo(ListView::Reload)); m_abortAction->setEnabled(m_dirView->m_ftpClient->socket()->isBusy()); m_toggleTreeViewAction->setEnabled(true); + m_toggleFilterAction->setEnabled(true); m_quickConnectAction->setEnabled(m_dirView->m_list->m_curURL.isLocalFile()); m_connectAction->setEnabled(true); @@ -207,9 +207,6 @@ m_exportListingAction->setEnabled(true); m_rawCmdAction->setEnabled(!m_dirView->m_list->m_curURL.isLocalFile() && m_dirView->m_ftpClient->socket()->features() & SF_RAW_COMMAND); - - m_setFilterAction->setEnabled(true); - m_clearFilterAction->setEnabled(!m_dirView->m_list->m_filter.isNull()); } void Actions::slotQuickConnect() @@ -475,20 +472,6 @@ } } -void Actions::slotSetFilter() -{ - bool ok; - QString filterStr = KInputDialog::getText(i18n("Filter"), i18n("Enter filter:"), m_dirView->m_list->m_filter, &ok); - - if (ok) - m_dirView->m_list->setFilter(filterStr); -} - -void Actions::slotClearFilter() -{ - m_dirView->m_list->setFilter(QString::null); -} - void Actions::slotAbort() { KFTPSession::Session *session = KFTPSession::Manager::self()->find(m_dirView); @@ -512,6 +495,16 @@ m_dirView->setTreeVisible(m_toggleTreeViewAction->isChecked()); } +void Actions::slotShowHideFilter() +{ + if (m_toggleFilterAction->isChecked()) { + m_dirView->m_searchToolBar->show(); + } else { + m_dirView->m_list->setFilter(QString::null); + m_dirView->m_searchToolBar->hide(); + } +} + void Actions::slotCharsetChanged(int id) { if (!m_changeEncodingAction->popupMenu()->isItemChecked(id)) { --- trunk/extragear/network/kftpgrabber/src/widgets/browser/actions.h #578110:578111 @@ -70,6 +70,7 @@ KAction *m_reloadAction; KAction *m_abortAction; KToggleAction *m_toggleTreeViewAction; + KToggleAction *m_toggleFilterAction; KAction *m_transferAction; KAction *m_queueTransferAction; @@ -77,8 +78,6 @@ KAction *m_renameAction; KAction *m_deleteAction; KAction *m_propsAction; - KAction *m_setFilterAction; - KAction *m_clearFilterAction; KAction *m_shredAction; KAction *m_fileEditAction; KAction *m_verifyAction; @@ -114,6 +113,7 @@ void slotReload(); void slotAbort(); void slotShowHideTree(); + void slotShowHideFilter(); void slotTransfer(); void slotQueueTransfer(); @@ -121,8 +121,6 @@ void slotRename(); void slotDelete(); void slotProps(); - void slotSetFilter(); - void slotClearFilter(); void slotShred(); void slotFileEdit(); void slotVerify(); --- trunk/extragear/network/kftpgrabber/src/widgets/browser/listview.cpp #578110:578111 @@ -861,11 +861,8 @@ actions->m_pasteAction->plug(contextMenu); } - // Always show properties and filters + // Always show properties contextMenu->insertSeparator(); - actions->m_setFilterAction->plug(contextMenu); - actions->m_clearFilterAction->plug(contextMenu); - contextMenu->insertSeparator(); actions->m_propsAction->plug(contextMenu); contextMenu->exec(p); --- trunk/extragear/network/kftpgrabber/src/widgets/browser/listview.h #578110:578111 @@ -102,7 +102,6 @@ void setCompanion(ListView *companion) { m_companion = companion; } void setTreeView(TreeView *tree); void setHomeURL(const KURL &url) { m_homeURL = url; } - void setFilter(const QString &filter); void setShowHidden(bool value) { m_showHiddenFiles = value; } void resetView(const KURL url, const QString &rootText = 0); @@ -112,6 +111,14 @@ KURL::List getCurrentSelection(); ListItems getCurrentSelectionLI(); +public slots: + /** + * Set a filter for displaying entries in the current directory listing. The + * filter is passed to QRegExp with wildcard syntax set to on. + * + * @param filter The wanted filter pattern + */ + void setFilter(const QString &filter); private: KFTPSession::Session *m_session; KFTPEngine::Thread *m_ftpClient; /* Ftp client if remote */ --- trunk/extragear/network/kftpgrabber/src/widgets/browser/view.cpp #578110:578111 @@ -52,6 +52,7 @@ #include <kaction.h> #include <kmessagebox.h> #include <ksslinfodlg.h> +#include <klineedit.h> #include <qdir.h> #include <qlabel.h> @@ -105,7 +106,8 @@ // Create the toolbars m_toolBarFirst = new KToolBar(this, "first toolbar", false, false); m_toolBarSecond = new KToolBar(this, "second toolbar", false, false); - + m_searchToolBar = new KToolBar(this, "search toolbar", false, false); + m_toolBarFirst->setEnableContextMenu(false); m_toolBarFirst->setMovingEnabled(false); m_toolBarFirst->setFullSize(true); @@ -113,6 +115,21 @@ m_toolBarSecond->setEnableContextMenu(false); m_toolBarSecond->setMovingEnabled(false); m_toolBarSecond->setFullSize(true); + + + m_searchToolBar->setEnableContextMenu(false); + m_searchToolBar->setMovingEnabled(false); + m_searchToolBar->setFullSize(true); + + QLabel *filterLabel = new QLabel(i18n("Filter: "), m_searchToolBar); + m_searchToolBar->insertWidget(1, 35, filterLabel); + + m_searchFilter = new KLineEdit(m_searchToolBar); + m_searchToolBar->setItemAutoSized(2, true); + m_searchToolBar->setStretchableWidget(m_searchFilter); + + m_searchToolBar->updateRects(true); + m_searchToolBar->hide(); // Create the erase button m_toolBarSecond->insertButton(QApplication::reverseLayout() ? "clear_left" :"locationbar_erase", 0, SIGNAL(clicked()), this, SLOT(slotHistoryEraseClicked()), true); @@ -167,6 +184,7 @@ layout->addWidget(m_toolBarFirst); layout->addWidget(m_toolBarSecond); layout->addWidget(m_splitter, 10); + layout->addWidget(m_searchToolBar); layout->addLayout(statusLayout); // Now add some stuff to the splitter @@ -180,6 +198,9 @@ m_list->setTreeView(m_tree); m_list->openURL(KURL(KFTPCore::Config::defLocalDir())); m_list->setFilter(QString::null); + + // Connect the filter edit to the list view + connect(m_searchFilter, SIGNAL(returnPressed(const QString&)), m_list, SLOT(setFilter(const QString&))); } void View::slotConfigUpdate() @@ -218,6 +239,7 @@ m_actions->m_abortAction->plug(m_toolBarFirst); m_actions->m_toggleTreeViewAction->plug(m_toolBarFirst); + m_actions->m_toggleFilterAction->plug(m_toolBarFirst); m_toolBarFirst->insertSeparator(); --- trunk/extragear/network/kftpgrabber/src/widgets/browser/view.h #578110:578111 @@ -51,6 +51,7 @@ class KToolBar; class KComboBox; class KAction; +class KLineEdit; namespace KFTPEngine { class Thread; @@ -98,6 +99,7 @@ KToolBar *m_toolBarFirst; /* Upper toolbar */ KToolBar *m_toolBarSecond; /* Lower toolbar */ + KToolBar *m_searchToolBar; QLabel *m_statusMsg; QLabel *m_connDurationMsg; @@ -108,6 +110,7 @@ QTime m_connDuration; KComboBox *m_historyCombo; + KLineEdit *m_searchFilter; public slots: void updateActions(); void updateBookmarks();
I've tried the filter bar, it does not behave exactly like the filter bar in the queue view. First it looks like it only accept regular expression, a little bit hard for the normal users ;). And it will refecth the file list when the filter changed, why is that necessary? Cannot we just filter the local list? Finally, the return key is needed to active the filter, active it automatically after enough charactor is inputed is definitely a plus :P
You don't need to input full regular expressions, QRegExp is used in wildcard mode - that means that things like "*.png" or "*.i??" work :) Regarding that reloading thing, it will be fixed.
Oh, btw do you think directories should be subject to filter or not ?
SVN commit 578161 by kostko: Implemented a better filtering widget. CCBUG: 133069 M +4 -2 Makefile.am M +3 -1 actions.cpp A filterwidget.cpp [License: GPL (v2+) (wrong address)] A filterwidget.h [License: GPL (v2+) (wrong address)] M +1 -15 listview.cpp M +8 -10 listview.h M +8 -10 view.cpp M +4 -3 view.h --- trunk/extragear/network/kftpgrabber/src/widgets/browser/Makefile.am #578160:578161 @@ -7,5 +7,7 @@ METASOURCES = AUTO noinst_LIBRARIES = libbrowser.a -noinst_HEADERS = listview.h view.h actions.h treeview.h propsplugin.h -libbrowser_a_SOURCES = listview.cpp view.cpp actions.cpp treeview.cpp propsplugin.cpp +noinst_HEADERS = listview.h view.h actions.h treeview.h propsplugin.h \ + filterwidget.h +libbrowser_a_SOURCES = listview.cpp view.cpp actions.cpp treeview.cpp \ + propsplugin.cpp filterwidget.cpp --- trunk/extragear/network/kftpgrabber/src/widgets/browser/actions.cpp #578160:578161 @@ -37,6 +37,7 @@ #include "browser/view.h" #include "browser/listview.h" #include "browser/propsplugin.h" +#include "browser/filterwidget.h" #include "widgets/quickconnect.h" #include "kftpbookmarks.h" @@ -499,9 +500,10 @@ { if (m_toggleFilterAction->isChecked()) { m_dirView->m_searchToolBar->show(); + m_dirView->m_searchFilter->clear(); m_dirView->m_searchFilter->setFocus(); } else { - m_dirView->m_list->setFilter(QString::null); + m_dirView->m_searchFilter->clear(); m_dirView->m_searchToolBar->hide(); } } --- trunk/extragear/network/kftpgrabber/src/widgets/browser/listview.cpp #578160:578161 @@ -376,14 +376,6 @@ connect(m_tree, SIGNAL(pathChanged(const KURL)), this, SLOT(slotTreeClicked(const KURL))); } -void ListView::setFilter(const QString &filter) -{ - m_filter = filter; - - // Reload the view - moveTo(Reload); -} - void ListView::resetView(const KURL url, const QString &rootText) { // Clear all the views @@ -600,10 +592,6 @@ // Generate file url KURL fileUrlBase = m_ftpClient->socket()->getCurrentUrl(); - // Regexp for filtering - QRegExp filter(m_filter); - filter.setWildcard(true); - // Process the directory listing int curNum = 0; QValueList<DirectoryEntry>::iterator end(list.end()); @@ -611,8 +599,7 @@ fileUrlBase.setPath(url.path(1) + (*i).filename()); ListViewItem *item = new ListViewItem(this, (*i), fileUrlBase); - if ((m_filter.isEmpty() || filter.exactMatch((*i).filename()) || item->m_dirEntry.isDirectory()) && - (m_showHiddenFiles || (*i).filename().at(0) != '.')) { + if (m_showHiddenFiles || (*i).filename().at(0) != '.') { // If we have a tree view and this is a directory if (item->m_dirEntry.isDirectory() && m_tree) m_tree->createFolder(fileUrlBase, *item->pixmap(0)); @@ -694,7 +681,6 @@ m_dirLister->setAutoUpdate(true); m_dirLister->setShowingDotFiles(m_showHiddenFiles); - m_dirLister->setNameFilter(m_filter); m_dirLister->emitChanges(); m_dirLister->openURL(url, false, true); --- trunk/extragear/network/kftpgrabber/src/widgets/browser/listview.h #578160:578161 @@ -111,14 +111,6 @@ KURL::List getCurrentSelection(); ListItems getCurrentSelectionLI(); -public slots: - /** - * Set a filter for displaying entries in the current directory listing. The - * filter is passed to QRegExp with wildcard syntax set to on. - * - * @param filter The wanted filter pattern - */ - void setFilter(const QString &filter); private: KFTPSession::Session *m_session; KFTPEngine::Thread *m_ftpClient; /* Ftp client if remote */ @@ -134,7 +126,6 @@ History m_history; /* Filter */ - QString m_filter; bool m_addHistory; bool m_showHiddenFiles; @@ -201,7 +192,14 @@ void createColumns(); int compare(QListViewItem *i, int col, bool asc) const; - virtual void paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int alignment); + void paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int alignment); + + /** + * Get the directory entry associated with this item. + * + * @return A valid KFTPEngine::DirectoryEntry + */ + KFTPEngine::DirectoryEntry getDirectoryEntry() const { return m_dirEntry; } private: KFTPEngine::DirectoryEntry m_dirEntry; KURL m_url; --- trunk/extragear/network/kftpgrabber/src/widgets/browser/view.cpp #578160:578161 @@ -37,6 +37,7 @@ #include "browser/listview.h" #include "browser/treeview.h" #include "browser/actions.h" +#include "browser/filterwidget.h" #include "kftpbookmarks.h" #include "misc/config.h" @@ -123,13 +124,6 @@ QLabel *filterLabel = new QLabel(i18n("Filter: "), m_searchToolBar); m_searchToolBar->insertWidget(1, 35, filterLabel); - - m_searchFilter = new KLineEdit(m_searchToolBar); - m_searchToolBar->setItemAutoSized(2, true); - m_searchToolBar->setStretchableWidget(m_searchFilter); - - m_searchToolBar->updateRects(true); - m_searchToolBar->hide(); // Create the erase button m_toolBarSecond->insertButton(QApplication::reverseLayout() ? "clear_left" :"locationbar_erase", 0, SIGNAL(clicked()), this, SLOT(slotHistoryEraseClicked()), true); @@ -197,10 +191,14 @@ m_list->setTreeView(m_tree); m_list->openURL(KURL(KFTPCore::Config::defLocalDir())); - m_list->setFilter(QString::null); - // Connect the filter edit to the list view - connect(m_searchFilter, SIGNAL(returnPressed(const QString&)), m_list, SLOT(setFilter(const QString&))); + // Create the filter widget + m_searchFilter = new FilterWidget(m_searchToolBar, m_list); + m_searchToolBar->setItemAutoSized(2, true); + m_searchToolBar->setStretchableWidget(m_searchFilter); + + m_searchToolBar->updateRects(true); + m_searchToolBar->hide(); } void View::slotConfigUpdate() --- trunk/extragear/network/kftpgrabber/src/widgets/browser/view.h #578160:578161 @@ -65,10 +65,11 @@ class ListView; class TreeView; class Actions; +class FilterWidget; /** -@author Jernej Kos -*/ + * @author Jernej Kos + */ class View : public QWidget { Q_OBJECT @@ -110,7 +111,7 @@ QTime m_connDuration; KComboBox *m_historyCombo; - KLineEdit *m_searchFilter; + FilterWidget *m_searchFilter; public slots: void updateActions(); void updateBookmarks();
This new widget support wildcard filtering, operates on the in-memory list, the list is updated as you type and you can select (right click, Filter Options) if you wish to apply filter to directories or not.
Great work, and two minor suggestion :), how about change the filter operation from exactMatch() to search(), then after inputing "ge" we will have "gentoo" stay in the result. Also currently the filter is case sensitive, I think maybe case insensitive is more convenient.
SVN commit 578396 by kostko: Further filter improvements as suggested by LuRan. CCBUG: 133069 M +8 -2 filterwidget.cpp M +3 -1 filterwidget.h --- trunk/extragear/network/kftpgrabber/src/widgets/browser/filterwidget.cpp #578395:578396 @@ -49,7 +49,8 @@ FilterWidget::FilterWidget(QWidget *parent, ListView *view) : KListViewSearchLine(parent, view), m_filterDirectories(true), - m_filterSymlinks(true) + m_filterSymlinks(true), + m_caseSensitive(false) { } @@ -64,9 +65,10 @@ return true; QRegExp filter(pattern); + filter.setCaseSensitive(m_caseSensitive); filter.setWildcard(true); - return filter.exactMatch(item->text(0)); + return filter.search(item->text(0)) > -1; } return true; @@ -88,6 +90,9 @@ subMenu->insertItem(i18n("Filter Symlinks"), FilterWidget::FilterSymlinks); subMenu->setItemChecked(FilterWidget::FilterSymlinks, m_filterSymlinks); + subMenu->insertItem(i18n("Case Sensitive"), FilterWidget::CaseSensitive); + subMenu->setItemChecked(FilterWidget::CaseSensitive, m_caseSensitive); + return popup; } @@ -96,6 +101,7 @@ switch (id) { case FilterDirectories: m_filterDirectories = !m_filterDirectories; break; case FilterSymlinks: m_filterSymlinks = !m_filterSymlinks; break; + case CaseSensitive: m_caseSensitive = !m_caseSensitive; break; default: break; } --- trunk/extragear/network/kftpgrabber/src/widgets/browser/filterwidget.h #578395:578396 @@ -64,7 +64,8 @@ protected: enum { FilterDirectories = 1, - FilterSymlinks = 2 + FilterSymlinks = 2, + CaseSensitive = 3 }; /** @@ -84,6 +85,7 @@ private: bool m_filterDirectories; bool m_filterSymlinks; + bool m_caseSensitive; private slots: void slotOptionsMenuActivated(int id); };