diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 3d7afdb1a7..2d63816113 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -2514,6 +2514,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask )
if (selected_item)
{
handleRightMouseDown(selected_item->getRect().getCenterX(), selected_item->getRect().getCenterY(), MASK_NONE);
+ handled = TRUE;
}
break;
}
@@ -2523,11 +2524,139 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask )
}
}
// TODO: multiple: shift-up, shift-down, shift-home, shift-end, select all
+ // Let's just do this!
+ else if (mask == MASK_CONTROL)
+ {
+ switch (key)
+ {
+ case 'A':
+ if (canSelectAll())
+ {
+ selectAll();
+ handled = TRUE;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ else if (mask == MASK_SHIFT)
+ {
+ switch (key)
+ {
+ case KEY_UP:
+ if (mAllowKeyboardMovement || hasFocus())
+ {
+ auto selected_items = getAllSelected();
+ auto last = selected_items.back();
+
+ if (mLastSelected == last && selected_items.size() > 1)
+ {
+ deselectItem(last);
+ mLastSelected = getAllSelected().back(); // Use updated selection
+ }
+ else
+ {
+ auto items = getAllData();
+ auto first = std::find(items.begin(), items.end(), selected_items.front());
+ if (first != items.end() && first > items.begin())
+ {
+ selectItem(*(--first), FALSE);
+ }
+ }
+
+ handled = TRUE;
+ }
+
+ break;
+ case KEY_DOWN:
+ if (mAllowKeyboardMovement || hasFocus())
+ {
+ auto selected_items = getAllSelected();
+ auto first = selected_items.front();
+
+ if (mLastSelected == first && selected_items.size() > 1)
+ {
+ deselectItem(first);
+ mLastSelected = getAllSelected().front(); // Use updated selection
+ }
+ else
+ {
+ auto items = getAllData();
+ auto last = std::find(items.begin(), items.end(), selected_items.back());
+ if (last != items.end() && last < items.end() - 1)
+ {
+ selectItem(*(++last), FALSE);
+ }
+ }
+
+ handled = TRUE;
+ }
+ break;
+ case KEY_HOME:
+ if (mAllowKeyboardMovement || hasFocus())
+ {
+ auto items = getAllData();
+ auto first = std::find(items.begin(), items.end(), getAllSelected().front());
+ for (auto it = items.begin(); it != items.end(); ++it)
+ {
+ if (it <= first)
+ {
+ selectItem(*it, FALSE);
+ }
+ else
+ {
+ deselectItem(*it);
+ }
+ }
+
+ handled = TRUE;
+ }
+ break;
+ case KEY_END:
+ if (mAllowKeyboardMovement || hasFocus())
+ {
+ auto items = getAllData();
+ auto last = std::find(items.begin(), items.end(), getAllSelected().back());
+ for (auto it = items.begin(); it != items.end(); ++it)
+ {
+ if (it >= last)
+ {
+ selectItem(*it, FALSE);
+ }
+ else
+ {
+ deselectItem(*it);
+ }
+ }
+
+ handled = TRUE;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ //
}
return handled;
}
+// Needed for keyboard selection in radar
+void LLScrollListCtrl::setLastSelectedItem(const LLUUID& id)
+{
+ for (auto item : getAllSelected())
+ {
+ if (item->getUUID() == id)
+ {
+ mLastSelected = item;
+ break;
+ }
+ }
+}
+//
+
BOOL LLScrollListCtrl::handleUnicodeCharHere(llwchar uni_char)
{
if ((uni_char < 0x20) || (uni_char == 0x7F)) // Control character or DEL
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index 40eaa4e9d4..aa176e318b 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -275,6 +275,7 @@ public:
std::vector getAllSelected() const;
S32 getNumSelected() const;
LLScrollListItem* getLastSelectedItem() const { return mLastSelected; }
+ void setLastSelectedItem(const LLUUID& id); // Needed for keyboard selection in radar
// iterate over all items
LLScrollListItem* getFirstData() const;
diff --git a/indra/newview/fspanelradar.cpp b/indra/newview/fspanelradar.cpp
index c20c1278d9..8334d58e28 100644
--- a/indra/newview/fspanelradar.cpp
+++ b/indra/newview/fspanelradar.cpp
@@ -326,6 +326,11 @@ void FSPanelRadar::updateList(const std::vector& entries, const LLSD& stat
static const std::string typingColumnIcon = getString("TypingColumnIcon");
// Store current selection and scroll position
+ LLUUID last_selected_id;
+ if (mRadarList->getLastSelectedItem())
+ {
+ last_selected_id = mRadarList->getLastSelectedItem()->getUUID();
+ }
std::vector selected_items = mRadarList->getAllSelected();
uuid_vec_t selected_ids;
for (std::vector::iterator it = selected_items.begin(); it != selected_items.end(); ++it)
@@ -458,6 +463,10 @@ void FSPanelRadar::updateList(const std::vector& entries, const LLSD& stat
if (!selected_ids.empty())
{
mRadarList->selectMultiple(selected_ids);
+ if (last_selected_id.notNull())
+ {
+ mRadarList->setLastSelectedItem(last_selected_id);
+ }
}
updateButtons();