commit 2c2244d4589b46603ab5cb2c87d81cf0fe11dd6e
parent aeb112c07e76d70acdb72a1908527a47a85bebc5
Author: cfillion <cfillion@users.noreply.github.com>
Date: Sat, 5 Mar 2016 16:03:47 -0500
implement multi selection in the remote manager dialog
Diffstat:
5 files changed, 90 insertions(+), 45 deletions(-)
diff --git a/src/listview.cpp b/src/listview.cpp
@@ -185,7 +185,7 @@ void ListView::clear()
bool ListView::hasSelection() const
{
- return currentIndex() > -1;
+ return selectionSize() > 0;
}
int ListView::currentIndex() const
@@ -194,13 +194,35 @@ int ListView::currentIndex() const
if(internalIndex < 0)
return -1;
+ else
+ return translateBack(internalIndex);
+}
- LVITEM item{};
- item.iItem = internalIndex;
- item.mask |= LVIF_PARAM;
- ListView_GetItem(handle(), &item);
+vector<int> ListView::selection() const
+{
+ int index = -1;
+ vector<int> indexes;
- return (int)item.lParam;
+ while((index = ListView_GetNextItem(handle(), index, LVNI_SELECTED)) != -1) {
+ indexes.push_back(translateBack(index));
+ }
+
+ return indexes;
+}
+
+int ListView::selectionSize() const
+{
+ return ListView_GetSelectedCount(handle());
+}
+
+int ListView::itemUnderMouse() const
+{
+ LVHITTESTINFO info{};
+ GetCursorPos(&info.pt);
+ ScreenToClient(handle(), &info.pt);
+ ListView_HitTest(handle(), &info);
+
+ return translateBack(info.iItem);
}
void ListView::onNotify(LPNMHDR info, LPARAM lParam)
@@ -220,13 +242,10 @@ void ListView::onNotify(LPNMHDR info, LPARAM lParam)
void ListView::handleDoubleClick()
{
- LVHITTESTINFO info{};
- GetCursorPos(&info.pt);
- ScreenToClient(handle(), &info.pt);
- ListView_HitTest(handle(), &info);
+ const int index = itemUnderMouse();
// user double clicked on an item
- if(info.iItem > -1)
+ if(index > -1)
m_onActivate();
}
@@ -267,3 +286,16 @@ int ListView::translate(const int userIndex) const
return -1;
}
+
+int ListView::translateBack(const int internalIndex) const
+{
+ if(m_sortColumn < 0)
+ return internalIndex;
+
+ LVITEM item{};
+ item.iItem = internalIndex;
+ item.mask |= LVIF_PARAM;
+ ListView_GetItem(handle(), &item);
+
+ return (int)item.lParam;
+}
diff --git a/src/listview.hpp b/src/listview.hpp
@@ -47,8 +47,11 @@ public:
void sortByColumn(int index, SortOrder order = AscendingOrder);
void clear();
+ int selectionSize() const;
bool hasSelection() const;
int currentIndex() const;
+ std::vector<int> selection() const;
+ int itemUnderMouse() const;
int rowCount() const { return (int)m_rows.size(); }
void onSelect(const Callback &callback) { m_onSelect.connect(callback); }
@@ -63,7 +66,8 @@ private:
void setSortArrow(bool);
void handleDoubleClick();
void handleColumnClick(LPARAM lpnmlistview);
- int translate(int index) const;
+ int translate(int userIndex) const;
+ int translateBack(int internalIndex) const;
int m_columnSize;
int m_sortColumn;
diff --git a/src/manager.cpp b/src/manager.cpp
@@ -29,7 +29,7 @@
using namespace std;
-enum { ACTION_ENABLE = 300, ACTION_DISABLE, ACTION_UNINSTALL, ACTION_ABOUT };
+enum { ACTION_ENABLE = 80, ACTION_DISABLE, ACTION_UNINSTALL, ACTION_ABOUT };
Manager::Manager(ReaPack *reapack)
: Dialog(IDD_CONFIG_DIALOG), m_reapack(reapack), m_list(0)
@@ -51,7 +51,7 @@ void Manager::onInit()
{AUTO_STR("State"), 60},
});
- m_list->onActivate(bind(&Manager::about, this));
+ m_list->onActivate([=] { about(m_list->currentIndex()); });
}
void Manager::onCommand(const int id)
@@ -69,12 +69,9 @@ void Manager::onCommand(const int id)
case ACTION_UNINSTALL:
uninstall();
break;
- case ACTION_ABOUT:
- about();
- break;
case IDOK:
if(confirm())
- apply();
+ apply(); // continue to next case (IDCANCEL)
else {
m_uninstall.clear();
refresh();
@@ -84,6 +81,10 @@ void Manager::onCommand(const int id)
reset();
close();
break;
+ default:
+ if(id >> 8 == ACTION_ABOUT)
+ about(id & 0xff);
+ break;
}
}
@@ -92,7 +93,8 @@ void Manager::onContextMenu(HWND target, const int x, const int y)
if(target != m_list->handle())
return;
- const Remote &remote = currentRemote();
+ const int index = m_list->itemUnderMouse();
+ const Remote &remote = getRemote(index);
if(remote.isNull())
return;
@@ -115,7 +117,7 @@ void Manager::onContextMenu(HWND target, const int x, const int y)
const auto_string &name = make_autostring(remote.name());
auto_snprintf(aboutLabel, sizeof(aboutLabel),
AUTO_STR("&About %s..."), name.c_str());
- menu.addAction(aboutLabel, ACTION_ABOUT);
+ menu.addAction(aboutLabel, index | (ACTION_ABOUT << 8));
menu.disable(enableAction);
menu.disable(disableAction);
@@ -153,21 +155,22 @@ void Manager::refresh()
void Manager::setRemoteEnabled(const bool enabled)
{
- const Remote &remote = currentRemote();
+ for(const int index : m_list->selection()) {
+ const Remote &remote = getRemote(index);
- if(remote.isNull())
- return;
+ auto it = m_enableOverrides.find(remote);
- auto it = m_enableOverrides.find(remote);
-
- if(it == m_enableOverrides.end())
- m_enableOverrides.insert({remote, enabled});
- else if(remote.isEnabled() == enabled)
- m_enableOverrides.erase(it);
- else
- it->second = enabled;
+ if(it == m_enableOverrides.end()) {
+ if(remote.isEnabled() != enabled)
+ m_enableOverrides.insert({remote, enabled});
+ }
+ else if(remote.isEnabled() == enabled)
+ m_enableOverrides.erase(it);
+ else
+ it->second = enabled;
- m_list->replaceRow(m_list->currentIndex(), makeRow(remote));
+ m_list->replaceRow(index, makeRow(remote));
+ }
}
bool Manager::isRemoteEnabled(const Remote &remote) const
@@ -182,20 +185,22 @@ bool Manager::isRemoteEnabled(const Remote &remote) const
void Manager::uninstall()
{
- const Remote &remote = currentRemote();
- m_uninstall.insert(remote);
+ while(m_list->selectionSize() > 0) {
+ const Remote &remote = currentRemote();
+ m_uninstall.insert(remote);
- const auto it = m_enableOverrides.find(remote);
+ const auto it = m_enableOverrides.find(remote);
- if(it != m_enableOverrides.end())
- m_enableOverrides.erase(it);
+ if(it != m_enableOverrides.end())
+ m_enableOverrides.erase(it);
- m_list->removeRow(m_list->currentIndex());
+ m_list->removeRow(m_list->currentIndex());
+ }
}
-void Manager::about()
+void Manager::about(const int index)
{
- m_reapack->about(currentRemote(), handle());
+ m_reapack->about(getRemote(index), handle());
}
bool Manager::confirm() const
@@ -253,9 +258,12 @@ ListView::Row Manager::makeRow(const Remote &remote) const
Remote Manager::currentRemote() const
{
- const int index = m_list->currentIndex();
+ return getRemote(m_list->currentIndex());
+}
- if(index < 0)
+Remote Manager::getRemote(const int index) const
+{
+ if(index < 0 || index > m_list->rowCount() - 1)
return {};
const ListView::Row &row = m_list->row(index);
diff --git a/src/manager.hpp b/src/manager.hpp
@@ -43,10 +43,11 @@ private:
ListView::Row makeRow(const Remote &) const;
Remote currentRemote() const;
+ Remote getRemote(int index) const;
void setRemoteEnabled(bool);
bool isRemoteEnabled(const Remote &) const;
void uninstall();
- void about();
+ void about(int index);
bool confirm() const;
void apply();
diff --git a/src/resource.rc b/src/resource.rc
@@ -31,8 +31,8 @@ FONT DIALOG_FONT
CAPTION "ReaPack Configuration"
BEGIN
LTEXT "Remote repositories:", IDC_LABEL, 5, 5, 320, 10
- CONTROL "", IDC_LIST, WC_LISTVIEW, LVS_REPORT | LVS_SINGLESEL |
- LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, 5, 18, 320, 136
+ CONTROL "", IDC_LIST, WC_LISTVIEW, LVS_REPORT | LVS_SHOWSELALWAYS |
+ WS_BORDER | WS_TABSTOP, 5, 18, 320, 136
PUSHBUTTON "&Import...", IDC_IMPORT, 5, 160, 45, 14
DEFPUSHBUTTON "&OK", IDOK, 240, 160, 40, 14
PUSHBUTTON "&Cancel", IDCANCEL, 284, 160, 40, 14