From 872b4d7ed0bd532e349d3c177a63d48e17d0bdb3 Mon Sep 17 00:00:00 2001
From: Mike Antipov <mantipov@productengine.com>
Date: Wed, 28 Apr 2010 11:00:53 +0300
Subject: Fixed critical bug EXT-4837 ( [NUX] When filter results in null
 state, provide a message suggesting the user try global search.)

Implemented passing of entered filter substring without head spaces to search URI in help message for null filtered results.
* Updated setting "no item message" to use search term from filter editor for avatar & group lists and for inventory panels.
* Updated appropriate translatable strings to get [SEARCH_TERM] substitution.
* Updated processing of filter substring to pass original string to methods applied new filter.

Additional necessary changes
* Changed place to set "no item message" for group list from refresh to where filter is updated (like in avatar lists)
* Removed converting of filter substring to upper case in Places & My Appearance sidepanels (this conversion has already been implemented in where filter is applied)
* Added a separate message for Landmarks to set search URI to secondlife:///app/search/places for Lanmarks panel;
 other inventory related panels have URL to all searched categories (secondlife:///app/search/all)

Reviewed by Vadim Savchuk at https://codereview.productengine.com/secondlife/r/326/

--HG--
branch : product-engine
---
 indra/llui/llflatlistview.cpp                       |  9 +++++++--
 indra/llui/llflatlistview.h                         |  6 +++---
 indra/newview/llavatarlist.cpp                      |  8 +++++---
 indra/newview/llfolderview.cpp                      |  4 +++-
 indra/newview/llgrouplist.cpp                       | 13 ++++++++-----
 indra/newview/llinventoryfilter.cpp                 |  5 +++--
 indra/newview/llinventoryfilter.h                   |  2 ++
 indra/newview/llpanellandmarks.cpp                  |  1 +
 indra/newview/llpanelpeople.cpp                     | 20 ++++++++++++--------
 indra/newview/llpanelpeople.h                       |  1 +
 indra/newview/llpanelplaces.cpp                     |  3 +--
 indra/newview/llsidepanelappearance.cpp             |  3 +--
 indra/newview/skins/default/xui/en/panel_people.xml |  8 ++++----
 indra/newview/skins/default/xui/en/strings.xml      |  3 ++-
 14 files changed, 53 insertions(+), 33 deletions(-)

diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp
index e0b2244654..ec247b25c3 100644
--- a/indra/llui/llflatlistview.cpp
+++ b/indra/llui/llflatlistview.cpp
@@ -1147,12 +1147,17 @@ LLFlatListViewEx::LLFlatListViewEx(const Params& p)
 
 }
 
-void LLFlatListViewEx::updateNoItemsMessage(bool items_filtered)
+void LLFlatListViewEx::updateNoItemsMessage(const std::string& filter_string)
 {
+	bool items_filtered = !filter_string.empty();
 	if (items_filtered)
 	{
 		// items were filtered
-		setNoItemsCommentText(mNoFilteredItemsMsg);
+		LLStringUtil::format_map_t args;
+		args["[SEARCH_TERM]"] = LLURI::escape(filter_string);
+		std::string text = mNoFilteredItemsMsg;
+		LLStringUtil::format(text, args);
+		setNoItemsCommentText(text);
 	}
 	else
 	{
diff --git a/indra/llui/llflatlistview.h b/indra/llui/llflatlistview.h
index f7d094f7e7..4f718ab0dc 100644
--- a/indra/llui/llflatlistview.h
+++ b/indra/llui/llflatlistview.h
@@ -470,10 +470,10 @@ protected:
 	/**
 	 * Applies a message for empty list depend on passed argument.
 	 *
-	 * @param items_filtered - if true message for filtered items will be set, otherwise for
-	 * completely empty list.
+	 * @param filter_string - if is not empty, message for filtered items will be set, otherwise for
+	 * completely empty list. Value of filter string will be passed as search_term in SLURL.
 	 */
-	void updateNoItemsMessage(bool items_filtered);
+	void updateNoItemsMessage(const std::string& filter_string);
 
 private:
 	std::string mNoFilteredItemsMsg;
diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp
index 8ba47b5198..e32daf55ca 100644
--- a/indra/newview/llavatarlist.cpp
+++ b/indra/newview/llavatarlist.cpp
@@ -176,13 +176,15 @@ void LLAvatarList::clear()
 
 void LLAvatarList::setNameFilter(const std::string& filter)
 {
-	if (mNameFilter != filter)
+	std::string filter_upper = filter;
+	LLStringUtil::toUpper(filter_upper);
+	if (mNameFilter != filter_upper)
 	{
-		mNameFilter = filter;
+		mNameFilter = filter_upper;
 
 		// update message for empty state here instead of refresh() to avoid blinking when switch
 		// between tabs.
-		updateNoItemsMessage(!mNameFilter.empty());
+		updateNoItemsMessage(filter);
 		setDirty();
 	}
 }
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index c492bfcef1..eba4cdfa31 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -946,7 +946,9 @@ void LLFolderView::draw()
 		}
 		else
 		{
-			mStatusText = LLTrans::getString(getFilter()->getEmptyLookupMessage());
+			LLStringUtil::format_map_t args;
+			args["[SEARCH_TERM]"] = LLURI::escape(getFilter()->getFilterSubStringOrig());
+			mStatusText = LLTrans::getString(getFilter()->getEmptyLookupMessage(), args);
 			//font->renderUTF8(mStatusText, 0, 2, 1, sSearchStatusColor, LLFontGL::LEFT, LLFontGL::TOP, LLFontGL::NORMAL,  LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE );
 		}
 		mStatusTextBox->setValue(mStatusText);
diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp
index f21b6e1085..252c34cf9c 100644
--- a/indra/newview/llgrouplist.cpp
+++ b/indra/newview/llgrouplist.cpp
@@ -131,9 +131,15 @@ BOOL LLGroupList::handleRightMouseDown(S32 x, S32 y, MASK mask)
 
 void LLGroupList::setNameFilter(const std::string& filter)
 {
-	if (mNameFilter != filter)
+	std::string filter_upper = filter;
+	LLStringUtil::toUpper(filter_upper);
+	if (mNameFilter != filter_upper)
 	{
-		mNameFilter = filter;
+		mNameFilter = filter_upper;
+
+		// set no items message depend on filter state
+		updateNoItemsMessage(filter);
+
 		setDirty();
 	}
 }
@@ -151,9 +157,6 @@ void LLGroupList::refresh()
 	LLUUID				id;
 	bool				have_filter		= !mNameFilter.empty();
 
-	// set no items message depend on filter state & total count of groups
-	updateNoItemsMessage(have_filter);
-
 	clear();
 
 	for(S32 i = 0; i < count; ++i)
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index 1a488175ac..901a570487 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -329,9 +329,10 @@ void LLInventoryFilter::setFilterSubString(const std::string& string)
 		// appending new characters
 		const BOOL more_restrictive = mFilterSubString.size() < string.size() && !string.substr(0, mFilterSubString.size()).compare(mFilterSubString);
 
-		mFilterSubString = string;
+		mFilterSubStringOrig = string;
+		LLStringUtil::trimHead(mFilterSubStringOrig);
+		mFilterSubString = mFilterSubStringOrig;
 		LLStringUtil::toUpper(mFilterSubString);
-		LLStringUtil::trimHead(mFilterSubString);
 		if (less_restrictive)
 		{
 			setModified(FILTER_LESS_RESTRICTIVE);
diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h
index b01554edc8..2376ba5d22 100644
--- a/indra/newview/llinventoryfilter.h
+++ b/indra/newview/llinventoryfilter.h
@@ -84,6 +84,7 @@ public:
 
 	void 				setFilterSubString(const std::string& string);
 	const std::string& 	getFilterSubString(BOOL trim = FALSE) const;
+	const std::string& 	getFilterSubStringOrig() const { return mFilterSubStringOrig; } 
 	BOOL 				hasFilterString() const;
 
 	void 				setFilterPermissions(PermissionMask perms);
@@ -181,6 +182,7 @@ private:
 
 	std::string::size_type	mSubStringMatchOffset;
 	std::string				mFilterSubString;
+	std::string				mFilterSubStringOrig;
 	const std::string		mName;
 
 	S32						mFilterGeneration;
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index 67d40a39b1..0a978d1b26 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -583,6 +583,7 @@ void LLLandmarksPanel::initLandmarksPanel(LLPlacesInventoryPanel* inventory_list
 	if (!inventory_list->getFilter())
 		return;
 
+	inventory_list->getFilter()->setEmptyLookupMessage("PlacesNoMatchingItems");
 	inventory_list->setFilterTypes(0x1 << LLInventoryType::IT_LANDMARK);
 	inventory_list->setSelectCallback(boost::bind(&LLLandmarksPanel::onSelectionChange, this, inventory_list, _1, _2));
 
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index f60951ca66..f2c0f92f9b 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -443,6 +443,7 @@ public:
 LLPanelPeople::LLPanelPeople()
 	:	LLPanel(),
 		mFilterSubString(LLStringUtil::null),
+		mFilterSubStringOrig(LLStringUtil::null),
 		mFilterEditor(NULL),
 		mTabContainer(NULL),
 		mOnlineFriendList(NULL),
@@ -658,7 +659,9 @@ void LLPanelPeople::updateFriendListHelpText()
 	{
 		//update help text for empty lists
 		std::string message_name = mFilterSubString.empty() ? "no_friends_msg" : "no_filtered_friends_msg";
-		no_friends_text->setText(getString(message_name));
+		LLStringUtil::format_map_t args;
+		args["[SEARCH_TERM]"] = LLURI::escape(mFilterSubStringOrig);
+		no_friends_text->setText(getString(message_name, args));
 	}
 }
 
@@ -981,10 +984,11 @@ bool LLPanelPeople::isRealGroup()
 
 void LLPanelPeople::onFilterEdit(const std::string& search_string)
 {
-	std::string search_upper = search_string;
+	mFilterSubStringOrig = search_string;
+	LLStringUtil::trimHead(mFilterSubStringOrig);
 	// Searches are case-insensitive
+	std::string search_upper = mFilterSubStringOrig;
 	LLStringUtil::toUpper(search_upper);
-	LLStringUtil::trimHead(search_upper);
 
 	if (mFilterSubString == search_upper)
 		return;
@@ -999,11 +1003,11 @@ void LLPanelPeople::onFilterEdit(const std::string& search_string)
 
 
 	// Apply new filter.
-	mNearbyList->setNameFilter(mFilterSubString);
-	mOnlineFriendList->setNameFilter(mFilterSubString);
-	mAllFriendList->setNameFilter(mFilterSubString);
-	mRecentList->setNameFilter(mFilterSubString);
-	mGroupList->setNameFilter(mFilterSubString);
+	mNearbyList->setNameFilter(mFilterSubStringOrig);
+	mOnlineFriendList->setNameFilter(mFilterSubStringOrig);
+	mAllFriendList->setNameFilter(mFilterSubStringOrig);
+	mRecentList->setNameFilter(mFilterSubStringOrig);
+	mGroupList->setNameFilter(mFilterSubStringOrig);
 
 	setAccordionCollapsedByUser("tab_online", false);
 	setAccordionCollapsedByUser("tab_all", false);
diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h
index 1bd3ea471c..17c45a034b 100644
--- a/indra/newview/llpanelpeople.h
+++ b/indra/newview/llpanelpeople.h
@@ -169,6 +169,7 @@ private:
 	Updater*				mRecentListUpdater;
 
 	std::string				mFilterSubString;
+	std::string				mFilterSubStringOrig;
 };
 
 #endif //LL_LLPANELPEOPLE_H
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index 89293d0e50..51a11e97e4 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -528,8 +528,7 @@ void LLPanelPlaces::onFilterEdit(const std::string& search_string, bool force_fi
 		std::string string = search_string;
 
 		// Searches are case-insensitive
-		LLStringUtil::toUpper(string);
-		LLStringUtil::trimHead(string);
+		// but we don't convert the typed string to upper-case so that it can be fed to the web search as-is.
 
 		mActivePanel->onSearchEdit(string);
 	}
diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp
index 87494daaa9..f38df19de0 100644
--- a/indra/newview/llsidepanelappearance.cpp
+++ b/indra/newview/llsidepanelappearance.cpp
@@ -197,8 +197,7 @@ void LLSidepanelAppearance::onFilterEdit(const std::string& search_string)
 		mFilterSubString = search_string;
 
 		// Searches are case-insensitive
-		LLStringUtil::toUpper(mFilterSubString);
-		LLStringUtil::trimHead(mFilterSubString);
+		// but we don't convert the typed string to upper-case so that it can be fed to the web search as-is.
 
 		mPanelOutfitsInventory->onSearchEdit(mFilterSubString);
 	}
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index fa4213667b..066ea3be6e 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -16,13 +16,13 @@
      value="No recent people. Looking for people to hang out with? Try [secondlife:///app/search/people Search] or the [secondlife:///app/worldmap World Map]." />
     <string
      name="no_filtered_recent_people"
-     value="Didn't find what you're looking for? Try [secondlife:///app/search/people Search]." />
+     value="Didn't find what you're looking for? Try [secondlife:///app/search/people/[SEARCH_TERM] Search]." />
     <string
      name="no_one_near"
      value="No one nearby. Looking for people to hang out with? Try [secondlife:///app/search/people Search] or the [secondlife:///app/worldmap World Map]." />
     <string
      name="no_one_filtered_near"
-     value="Didn't find what you're looking for? Try [secondlife:///app/search/people Search]." />
+     value="Didn't find what you're looking for? Try [secondlife:///app/search/people/[SEARCH_TERM] Search]." />
     <string
      name="no_friends_online"
      value="No friends online" />
@@ -36,7 +36,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
     </string>
     <string
      name="no_filtered_friends_msg">
-         Didn't find what you're looking for? Try [secondlife:///app/search/people Search].
+         Didn't find what you're looking for? Try [secondlife:///app/search/people/[SEARCH_TERM] Search].
     </string>
     <string
      name="people_filter_label"
@@ -50,7 +50,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
      -->
     <string
      name="no_filtered_groups_msg"
-     value="Didn't find what you're looking for? Try [secondlife:///app/search/groups Search]." />
+     value="Didn't find what you're looking for? Try [secondlife:///app/search/groups/[SEARCH_TERM] Search]." />
     <string
      name="no_groups_msg"
      value="Looking for Groups to join? Try [secondlife:///app/search/groups Search]." />
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index bf30e89a59..b0e43e72ed 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -1842,7 +1842,8 @@ Clears (deletes) the media and all params from the given face.
 	<string name="LeaveMouselook">Press ESC to return to World View</string>
 
 	<!-- inventory -->
-	<string name="InventoryNoMatchingItems">Didn't find what you're looking for? Try [secondlife:///app/search/all Search].</string>
+	<string name="InventoryNoMatchingItems">Didn't find what you're looking for? Try [secondlife:///app/search/all/[SEARCH_TERM] Search].</string>
+	<string name="PlacesNoMatchingItems">Didn't find what you're looking for? Try [secondlife:///app/search/places/[SEARCH_TERM] Search].</string>
 	<string name="FavoritesNoMatchingItems">Drag a landmark here to add it to your favorites.</string>
 	<string name="InventoryNoTexture">You do not have a copy of this texture in your inventory</string>
     <!-- use value="" because they have preceding spaces -->
-- 
cgit v1.2.3