← Back to team overview

linuxdcpp-team team mailing list archive

[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2728: add string matching methods to searches within file lists

 

------------------------------------------------------------
revno: 2728
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Sun 2011-12-18 16:37:20 +0100
message:
  add string matching methods to searches within file lists
modified:
  help/window_file_list.html
  help/window_search.html
  win32/DirectoryListingFrame.cpp
  win32/DirectoryListingFrame.h
  win32/ListFilter.cpp
  win32/UserMatchDlg.cpp
  win32/WinUtil.cpp
  win32/WinUtil.h


--
lp:dcplusplus
https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk

Your team Dcplusplus-team is subscribed to branch lp:dcplusplus.
To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk/+edit-subscription
=== modified file 'help/window_file_list.html'
--- help/window_file_list.html	2011-03-19 15:32:48 +0000
+++ help/window_file_list.html	2011-12-18 15:37:20 +0000
@@ -32,7 +32,7 @@
 A search row may be shown right below the toolbar to allow looking for files in the current file
 list. Its visibility is controlled by the "Find" button.
 <dl style="margin-left: 40px;">
-  <dt>Text-box (left)</dt>
+  <dt>Text-box and method selection drop-down (left)</dt>
   <dd cshelp="IDH_FILE_LIST_SEARCH_BOX">Enter your search terms here. The most recent searches can
   be accessed by unfolding the list contained within this box.</dd>
   <dt><img src="Left.ico" width="16" height="16" alt="Previous"/> Previous</dt>

=== modified file 'help/window_search.html'
--- help/window_search.html	2011-12-18 13:41:12 +0000
+++ help/window_search.html	2011-12-18 15:37:20 +0000
@@ -111,17 +111,25 @@
 
 <h2>Filter search results</h2>
 <p cshelp="IDH_SEARCH_FILTER">
-These controls allow filtering the search results.
+These controls allow filtering current search results in order to only see specific ones. Eg
+selecting 'File' in the drop down, and writing "foo" in the filter, will only display results that
+have "foo" in their file name. When a filter is in effect, the "items" part of the status bar is
+updated to reflect it.  Note that filtered results are not removed; they can at any time be
+restored by just clearing the filter out.
 </p>
 
 <h2>Status bar</h2>
 <dl style="margin-left: 40px;">
-  <dt>Unnamed checkbox</dt>
-  <dd>Toggle the displayment of the search options.</dd>
-  <dt># items</dt>
-  <dd>The amount of items that are displayed in the window.</dd>
-  <dt># filtered</dt>
-  <dd>The amount of files that have been filtered away from the view.</dd>
+  <dt>+/- checkbox</dt>
+  <dd>Show or hide the search options group (left side of the search window).</dd>
+  <dt>X items or C / N items</dt>
+  <dd>Either the total amount of search results applicable to the running search query, if none has
+  been filtered away after applying the "Filter search results" filter ("X items" format), or the
+  current amount of items that are displayed in the list after applying the filter out of the total
+  amount of search results ("C / N items" format).</dd>
+  <dt># dropped</dt>
+  <dd>The amount of search results that have been received but do not satisfy the running search
+  query.</dd>
 </dl>
 </body>
 </html>

=== modified file 'win32/DirectoryListingFrame.cpp'
--- win32/DirectoryListingFrame.cpp	2011-11-21 19:04:08 +0000
+++ win32/DirectoryListingFrame.cpp	2011-12-18 15:37:20 +0000
@@ -26,7 +26,6 @@
 #include <dcpp/QueueManager.h>
 #include <dcpp/ShareManager.h>
 #include <dcpp/ScopedFunctor.h>
-#include <dcpp/StringSearch.h>
 #include <dcpp/WindowInfo.h>
 
 #include <dwt/widgets/FolderDialog.h>
@@ -66,7 +65,7 @@
 
 DirectoryListingFrame::UserMap DirectoryListingFrame::lists;
 
-TStringList DirectoryListingFrame::lastSearches;
+DirectoryListingFrame::LastSearches DirectoryListingFrame::lastSearches;
 
 int DirectoryListingFrame::ItemInfo::getImage(int col) const {
 	if(col != 0) {
@@ -214,6 +213,7 @@
 	grid(0),
 	searchGrid(0),
 	searchBox(0),
+	filterMethod(0),
 	dirs(0),
 	files(0),
 	speed(aSpeed),
@@ -235,28 +235,39 @@
 	grid->setSpacing(0);
 
 	{
-		Button::Seed cs = WinUtil::Seeds::button;
-
-		searchGrid = grid->addChild(Grid::Seed(1, 3));
+		searchGrid = grid->addChild(Grid::Seed(1, 4));
 		searchGrid->column(0).mode = GridInfo::FILL;
 
 		searchBox = searchGrid->addChild(WinUtil::Seeds::comboBoxEdit);
 		searchBox->setHelpId(IDH_FILE_LIST_SEARCH_BOX);
+		searchBox->getTextBox()->setCue(T_("Find files"));
 		addWidget(searchBox);
 		searchBox->getTextBox()->onKeyDown([this](int c) { return handleSearchKeyDown(c); });
 		searchBox->getTextBox()->onChar([this] (int c) { return handleSearchChar(c); });
 
-		cs.caption = T_("Find previous");
-		ButtonPtr button = searchGrid->addChild(cs);
+		searchBox->getTextBox()->addRemoveStyle(WS_CLIPCHILDREN, true);
+		WinUtil::addSearchIcon(searchBox->getTextBox());
+
+		filterMethod = searchGrid->addChild(WinUtil::Seeds::comboBox);
+		filterMethod->setHelpId(IDH_FILE_LIST_SEARCH_BOX);
+		addWidget(filterMethod);
+
+		WinUtil::addFilterMethods(filterMethod);
+		filterMethod->setSelected(StringMatch::PARTIAL);
+
+		searchBox->onSelectionChanged([this] { handleSearchSelChanged(); });
+
+		auto seed = WinUtil::Seeds::button;
+		seed.caption = T_("Find previous");
+		ButtonPtr button = searchGrid->addChild(seed);
 		button->setHelpId(IDH_FILE_LIST_FIND_PREV);
 		button->setImage(WinUtil::buttonIcon(IDI_LEFT));
 		button->onClicked([this] { handleFind(true); });
 		addWidget(button);
 
-		cs.caption = T_("Find next");
-		cs.style |= BS_DEFPUSHBUTTON;
-		button = searchGrid->addChild(cs);
-		cs.style &= ~BS_DEFPUSHBUTTON;
+		seed.caption = T_("Find next");
+		seed.style |= BS_DEFPUSHBUTTON;
+		button = searchGrid->addChild(seed);
 		button->setHelpId(IDH_FILE_LIST_FIND_NEXT);
 		button->setImage(WinUtil::buttonIcon(IDI_RIGHT));
 		button->onClicked([this] { handleFind(false); });
@@ -431,6 +442,13 @@
 	SettingsManager::getInstance()->set(SettingsManager::DIRECTORYLISTINGFRAME_WIDTHS, WinUtil::toString(files->getColumnWidths()));
 }
 
+void DirectoryListingFrame::handleSearchSelChanged() {
+	auto p = reinterpret_cast<LastSearchPair*>(searchBox->getData(searchBox->getSelected()));
+	if(p) {
+		filterMethod->setSelected(p->second);
+	}
+}
+
 void DirectoryListingFrame::handleFind(bool reverse) {
 	searching = true;
 	findFile(reverse);
@@ -470,8 +488,10 @@
 		searchGrid->setVisible(false);
 		grid->row(0).mode = GridInfo::STATIC;
 	} else {
-		for(auto i = lastSearches.crbegin(), iend = lastSearches.crend(); i != iend; ++i)
-			searchBox->addValue(*i);
+		for(auto i = lastSearches.crbegin(), iend = lastSearches.crend(); i != iend; ++i) {
+			auto p = i->get();
+			searchBox->setData(searchBox->addValue(p->first), reinterpret_cast<LPARAM>(p));
+		}
 		searchGrid->setEnabled(true);
 		searchGrid->setVisible(true);
 		grid->row(0).mode = GridInfo::AUTO;
@@ -999,10 +1019,13 @@
 	const tstring findStr = searchBox->getText();
 	if(findStr.empty())
 		return;
+	const auto method = static_cast<StringMatch::Method>(filterMethod->getSelected());
 
 	{
 		// make sure the new search string is at the top of the list
-		auto prev = std::find(lastSearches.begin(), lastSearches.end(), findStr);
+		auto p = make_pair(findStr, method);
+		auto prev = std::find_if(lastSearches.begin(), lastSearches.end(),
+			[p](const std::unique_ptr<LastSearchPair>& ptr) { return *ptr == p; });
 		if(prev == lastSearches.end()) {
 			size_t i = max(SETTING(SEARCH_HISTORY) - 1, 0);
 			while(lastSearches.size() > i) {
@@ -1013,8 +1036,9 @@
 			searchBox->setText(findStr); // it erases the text-box too...
 			lastSearches.erase(prev);
 		}
-		lastSearches.push_back(findStr);
-		searchBox->insertValue(0, findStr);
+		auto ptr = new LastSearchPair(p);
+		lastSearches.push_back(std::unique_ptr<LastSearchPair>(ptr));
+		searchBox->setData(searchBox->insertValue(0, findStr), reinterpret_cast<LPARAM>(ptr));
 	}
 
 	status->setText(STATUS_STATUS, str(TF_("Searching for: %1%") % findStr));
@@ -1046,7 +1070,11 @@
 		}
 	};
 
-	StringSearch search(Text::fromT(findStr));
+	StringMatch matcher;
+	matcher.pattern = Text::fromT(findStr);
+	matcher.setMethod(method);
+	matcher.prepare();
+
 	vector<HTREEITEM> collapse;
 	bool cycle = false;
 	const auto fileSel = files->getSelected();
@@ -1062,7 +1090,7 @@
 		bool found = false;
 		for(reverse ? --pos : ++pos; reverse ? (pos >= 0) : (pos < n); reverse ? --pos : ++pos) {
 			const ItemInfo& ii = *files->getData(pos);
-			if(search.match((ii.type == ItemInfo::FILE) ? ii.file->getName() : ii.dir->getName())) {
+			if(matcher.match((ii.type == ItemInfo::FILE) ? ii.file->getName() : ii.dir->getName())) {
 				found = true;
 				break;
 			}

=== modified file 'win32/DirectoryListingFrame.h'
--- win32/DirectoryListingFrame.h	2011-11-21 19:04:08 +0000
+++ win32/DirectoryListingFrame.h	2011-12-18 15:37:20 +0000
@@ -20,15 +20,16 @@
 #define DCPLUSPLUS_WIN32_DIRECTORY_LISTING_FRAME_H
 
 #include <dcpp/forward.h>
+#include <dcpp/ClientManagerListener.h>
+#include <dcpp/DirectoryListing.h>
 #include <dcpp/FastAlloc.h>
-#include <dcpp/DirectoryListing.h>
-#include <dcpp/ClientManagerListener.h>
+#include <dcpp/StringMatch.h>
 #include <dcpp/User.h>
 
+#include "AspectUserCommand.h"
+#include "IRecent.h"
 #include "MDIChildFrame.h"
-#include "IRecent.h"
 #include "UserInfoBase.h"
-#include "AspectUserCommand.h"
 
 using std::deque;
 
@@ -157,6 +158,7 @@
 
 	GridPtr searchGrid;
 	ComboBoxPtr searchBox;
+	ComboBoxPtr filterMethod;
 
 	typedef TypedTree<ItemInfo> WidgetDirs;
 	typedef WidgetDirs* WidgetDirsPtr;
@@ -191,7 +193,9 @@
 	bool updating;
 	bool searching;
 
-	static TStringList lastSearches;
+	typedef std::pair<tstring, StringMatch::Method> LastSearchPair;
+	typedef std::vector<std::unique_ptr<LastSearchPair>> LastSearches;
+	static LastSearches lastSearches;
 
 	ParamMap ucLineParams;
 
@@ -217,6 +221,7 @@
 	void addShellPaths(const ShellMenuPtr& menu, const vector<ItemInfo*>& sel);
 	void addUserMenu(const MenuPtr& menu);
 
+	void handleSearchSelChanged();
 	void handleFind(bool reverse);
 	void handleListDiff();
 	void handleMatchQueue();

=== modified file 'win32/ListFilter.cpp'
--- win32/ListFilter.cpp	2011-12-18 13:39:46 +0000
+++ win32/ListFilter.cpp	2011-12-18 15:37:20 +0000
@@ -19,10 +19,6 @@
 #include "stdafx.h"
 #include "ListFilter.h"
 
-#include <dwt/WidgetCreator.h>
-
-#include "resource.h"
-
 ListFilter::ListFilter(const ColumnInfo* columns, size_t colCount, UpdateF updateF) :
 columns(columns),
 colCount(colCount),
@@ -33,24 +29,11 @@
 void ListFilter::createTextBox(GridPtr grid) {
 	auto seed = WinUtil::Seeds::textBox;
 	seed.style |= ES_AUTOHSCROLL | WS_CLIPCHILDREN;
-	seed.exStyle |= WS_EX_TRANSPARENT;
 	text = grid->addChild(seed);
 
 	text->onUpdated([this] { textUpdated(); });
 
-	// add a search icon by creating a transparent label on top of the text control.
-
-	// structure of the right border: text | spacing | icon | margin | right border
-	const int spacing = 2, size = 16;
-	const auto margin = HIWORD(text->sendMessage(EM_GETMARGINS));
-	text->sendMessage(EM_SETMARGINS, EC_RIGHTMARGIN, MAKELONG(0, spacing + size + margin));
-
-	auto label = dwt::WidgetCreator<Label>::create(text, Label::Seed(IDI_SEARCH));
-	label->onRaw([](WPARAM, LPARAM) { return reinterpret_cast<LRESULT>(::GetStockObject(NULL_BRUSH)); }, dwt::Message(WM_CTLCOLOR));
-	text->onSized([this, label, size, margin](const dwt::SizedEvent&) {
-		auto box = text->getClientSize();
-		label->resize(dwt::Rectangle(box.x - margin - size, std::max(box.y - size, 0L) / 2, size, size));
-	});
+	WinUtil::addSearchIcon(text);
 }
 
 void ListFilter::createColumnBox(GridPtr grid) {
@@ -68,8 +51,7 @@
 void ListFilter::createMethodBox(GridPtr grid) {
 	method = grid->addChild(WinUtil::Seeds::comboBox);
 
-	tstring methods[StringMatch::METHOD_LAST] = { T_("Partial match"), T_("Exact match"), T_("Regular Expression") };
-	std::for_each(methods, methods + StringMatch::METHOD_LAST, [this](const tstring& str) { method->addValue(str); });
+	WinUtil::addFilterMethods(method);
 	method->setSelected(StringMatch::PARTIAL);
 
 	method->onSelectionChanged([this] { updateF(); });

=== modified file 'win32/UserMatchDlg.cpp'
--- win32/UserMatchDlg.cpp	2011-12-13 17:16:36 +0000
+++ win32/UserMatchDlg.cpp	2011-12-18 15:37:20 +0000
@@ -216,8 +216,7 @@
 	std::for_each(fields, fields + UserMatch::Rule::FIELD_LAST, [field](const tstring& str) { field->addValue(str); });
 	field->setSelected(rule ? rule->field : 0);
 
-	tstring methods[UserMatch::Rule::METHOD_LAST] = { T_("Partial match"), T_("Exact match"), T_("Regular Expression") };
-	std::for_each(methods, methods + UserMatch::Rule::METHOD_LAST, [method](const tstring& str) { method->addValue(str); });
+	WinUtil::addFilterMethods(method);
 	method->setSelected(rule ? rule->getMethod() : 0);
 
 	if(rule) {

=== modified file 'win32/WinUtil.cpp'
--- win32/WinUtil.cpp	2011-12-17 14:08:57 +0000
+++ win32/WinUtil.cpp	2011-12-18 15:37:20 +0000
@@ -25,22 +25,25 @@
 
 #include <boost/lexical_cast.hpp>
 
-#include <dcpp/SettingsManager.h>
-#include <dcpp/ShareManager.h>
 #include <dcpp/ClientManager.h>
+#include <dcpp/debug.h>
+#include <dcpp/File.h>
 #include <dcpp/HashManager.h>
 #include <dcpp/LogManager.h>
 #include <dcpp/QueueManager.h>
+#include <dcpp/SettingsManager.h>
+#include <dcpp/ShareManager.h>
+#include <dcpp/StringMatch.h>
 #include <dcpp/StringTokenizer.h>
-#include <dcpp/version.h>
-#include <dcpp/File.h>
+#include <dcpp/ThrottleManager.h>
 #include <dcpp/UserCommand.h>
 #include <dcpp/UploadManager.h>
-#include <dcpp/ThrottleManager.h>
 #include <dcpp/UserMatchManager.h>
+#include <dcpp/version.h>
 
 #include <dwt/DWTException.h>
 #include <dwt/LibraryLoader.h>
+#include <dwt/WidgetCreator.h>
 #include <dwt/util/GDI.h>
 #include <dwt/widgets/Grid.h>
 #include <dwt/widgets/LoadDialog.h>
@@ -1039,6 +1042,29 @@
 	return button;
 }
 
+void WinUtil::addSearchIcon(TextBoxPtr box) {
+	// add a search icon by creating a transparent label on top of the text control.
+
+	dcassert(box->hasStyle(WS_CLIPCHILDREN));
+
+	// structure of the right border: text | spacing | icon | margin | right border
+	const int spacing = 2, size = 16;
+	const auto margin = HIWORD(box->sendMessage(EM_GETMARGINS));
+	box->sendMessage(EM_SETMARGINS, EC_RIGHTMARGIN, MAKELONG(0, spacing + size + margin));
+
+	auto label = dwt::WidgetCreator<Label>::create(box, Label::Seed(IDI_SEARCH));
+	label->onRaw([](WPARAM, LPARAM) { return reinterpret_cast<LRESULT>(::GetStockObject(NULL_BRUSH)); }, dwt::Message(WM_CTLCOLOR));
+	box->onSized([box, label, size, margin](const dwt::SizedEvent&) {
+		auto sz = box->getClientSize();
+		label->resize(dwt::Rectangle(sz.x - margin - size, std::max(sz.y - size, 0L) / 2, size, size));
+	});
+}
+
+void WinUtil::addFilterMethods(ComboBoxPtr box) {
+	tstring methods[StringMatch::METHOD_LAST] = { T_("Partial match"), T_("Exact match"), T_("Regular Expression") };
+	std::for_each(methods, methods + StringMatch::METHOD_LAST, [box](const tstring& str) { box->addValue(str); });
+}
+
 void WinUtil::setColor(dwt::Control* widget) {
 	widget->setColor(textColor, bgColor);
 

=== modified file 'win32/WinUtil.h'
--- win32/WinUtil.h	2011-12-17 14:08:57 +0000
+++ win32/WinUtil.h	2011-12-18 15:37:20 +0000
@@ -232,8 +232,9 @@
 		ret.second->onClicked(f_cancel);
 		return ret;
 	}
-
 	static ButtonPtr addHelpButton(GridPtr grid);
+	static void addSearchIcon(TextBoxPtr box);
+	static void addFilterMethods(ComboBoxPtr box);
 
 	static void setColor(dwt::Control* widget);