From 4e4dd52753523afcedc4af357a280defd1cb9070 Mon Sep 17 00:00:00 2001
From: Eugene Mutavchi <emutavchi@productengine.com>
Date: Fri, 16 Apr 2010 13:18:11 +0300
Subject: [PATCH] Fixed low bug EXT-6823 (Implement a possibility to select
 several residents by "Shift" button) - improved the selection of list items
 by mouse. Reviewed by Mike Antipov at
 https://codereview.productengine.com/secondlife/r/238/

--HG--
branch : product-engine
---
 indra/llui/llflatlistview.cpp | 63 ++++++++++++++++++++++++++++++++++-
 1 file changed, 62 insertions(+), 1 deletion(-)

diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp
index 35f5a6bbb93..82f054c4b7b 100644
--- a/indra/llui/llflatlistview.cpp
+++ b/indra/llui/llflatlistview.cpp
@@ -504,7 +504,68 @@ void LLFlatListView::onItemMouseClick(item_pair_t* item_pair, MASK mask)
 
 	//*TODO find a better place for that enforcing stuff
 	if (mKeepOneItemSelected && numSelected() == 1 && !select_item) return;
-	
+
+	if ( (mask & MASK_SHIFT) && !(mask & MASK_CONTROL)
+		 && mMultipleSelection && !mSelectedItemPairs.empty() )
+	{
+		item_pair_t* last_selected_pair = mSelectedItemPairs.back();
+
+		// If item_pair is already selected - do nothing
+		if (last_selected_pair == item_pair)
+			return;
+
+		bool grab_items = false;
+		pairs_list_t pairs_to_select;
+
+		// Pick out items from list between last selected and current clicked item_pair.
+		for (pairs_iterator_t
+				 iter = mItemPairs.begin(),
+				 iter_end = mItemPairs.end();
+			 iter != iter_end; ++iter)
+		{
+			item_pair_t* cur = *iter;
+			if (cur == last_selected_pair || cur == item_pair)
+			{
+				grab_items = !grab_items;
+				// Skip last selected and current clicked item pairs.
+				continue;
+			}
+			if (!cur->first->getVisible())
+			{
+				// Skip invisible item pairs.
+				continue;
+			}
+			if (grab_items)
+			{
+				pairs_to_select.push_back(cur);
+			}
+		}
+
+		if (select_item)
+		{
+			pairs_to_select.push_back(item_pair);
+		}
+
+		for (pairs_iterator_t
+				 iter = pairs_to_select.begin(),
+				 iter_end = pairs_to_select.end();
+			 iter != iter_end; ++iter)
+		{
+			item_pair_t* pair_to_select = *iter;
+			selectItemPair(pair_to_select, true);
+		}
+
+		if (!select_item)
+		{
+			// Item was already selected but there is a need to update last selected item and its border.
+			// Do it here to prevent extra mCommitOnSelectionChange in selectItemPair().
+			mSelectedItemPairs.remove(item_pair);
+			mSelectedItemPairs.push_back(item_pair);
+			mSelectedItemsBorder->setRect(getLastSelectedItemRect().stretch(-1));
+		}
+		return;
+	}
+
 	if (!(mask & MASK_CONTROL) || !mMultipleSelection) resetSelection();
 	selectItemPair(item_pair, select_item);
 }
-- 
GitLab