[setup - the official Cygwin setup program] branch master, updated. release_2.920-8-gc99e4c14

Christian Franke via Cygwin-apps-cvs <[email protected]> Tue, 23 Aug 2022 16:10:05 +0000 (GMT)
Newsgroups gmane.os.cygwin.cvs.apps
Message-ID <[email protected]>


https://sourceware.org/git/gitweb.cgi?p=cygwin-apps/setup.git;h=c99e4c14911181636892355a4f1855024051ea1d

commit c99e4c14911181636892355a4f1855024051ea1d
Author: Christian Franke <[email protected]>
Date:   Mon Aug 22 16:39:21 2022 +0200

    Keyboard accelerators for install/reinstall/uninstall
    
    Ctrl+I/R/U select install/reinstall/uninstall and then move selection
    to next row.


Diff:
---
 ListView.cc         | 64 +++++++++++++++++++++++++++++++++++++----------------
 ListView.h          | 10 ++++++++-
 PickCategoryLine.cc | 21 +++++++++---------
 PickCategoryLine.h  |  2 +-
 PickPackageLine.cc  | 27 ++++++++++++++++------
 PickPackageLine.h   |  2 +-
 package_meta.cc     | 11 +++++++++
 7 files changed, 97 insertions(+), 40 deletions(-)

diff --git a/ListView.cc b/ListView.cc
index 62a37ab1..7cc7f0f0 100644
--- a/ListView.cc
+++ b/ListView.cc
@@ -24,6 +24,18 @@
 // ListView Common Control
 // ---------------------------------------------------------------------------
 
+int ModifierKeys::get()
+{
+  int keys = 0;
+  if (GetKeyState(VK_SHIFT) & 0x8000)
+    keys |= Shift;
+  if (GetKeyState(VK_CONTROL) & 0x8000)
+    keys |= Control;
+  if (GetKeyState(VK_MENU) & 0x8000)
+    keys |= Alt;
+  return keys;
+}
+
 void
 ListView::init(HWND parent, int id, HeaderList headers)
 {
@@ -563,33 +575,47 @@ ListView::OnNotify (NMHDR *pNmHdr, LRESULT *pResult)
     {
       NMLVKEYDOWN *pNmLvKeyDown = (NMLVKEYDOWN *)pNmHdr;
       int iRow = ListView_GetSelectionMark(hWndListView);
+      int modkeys = ModifierKeys::get();
 #if DEBUG
-      Log (LOG_PLAIN) << "LVN_KEYDOWN vkey " << pNmLvKeyDown->wVKey << " on row " << iRow << endLog;
+      Log (LOG_PLAIN) << "LVN_KEYDOWN vkey " << pNmLvKeyDown->wVKey << " on row " << iRow
+                      << " Shift:" << !!(modkeys & ModifierKeys::Shift)
+                      << " Ctrl:" << !!(modkeys & ModifierKeys::Control)
+                      << " Alt:" << !!(modkeys & ModifierKeys::Alt) << endLog;
 #endif
 
       if (contents && iRow >= 0)
         {
-          int col_num;
-          int action_id;
-          if ((*contents)[iRow]->map_key_to_action(pNmLvKeyDown->wVKey, &col_num, &action_id))
+          int col_num = 0;
+          int action_id = 0;
+          int todo = (*contents)[iRow]->map_key_to_action(pNmLvKeyDown->wVKey, modkeys,
+                                                          col_num, action_id);
+          int update = 0;
+          if (todo & ListViewLine::Action::Direct)
+            update = (*contents)[iRow]->do_action(col_num, action_id);
+          else if (todo & ListViewLine::Action::PopUp)
             {
-              int update;
-              if (action_id >= 0)
-                update = (*contents)[iRow]->do_action(col_num, action_id);
-              else
-                {
-                  POINT p;
-                  RECT r;
-                  ListView_GetSubItemRect(hWndListView, iRow, col_num, LVIR_BOUNDS, &r);
-                  p.x = r.left;
-                  p.y = r.top;
-                  ClientToScreen(hWndListView, &p);
+              POINT p;
+              RECT r;
+              ListView_GetSubItemRect(hWndListView, iRow, col_num, LVIR_BOUNDS, &r);
+              p.x = r.left;
+              p.y = r.top;
+              ClientToScreen(hWndListView, &p);
+
+              update = popup_menu(iRow, col_num, p);
+            }
 
-                  update = popup_menu(iRow, col_num, p);
-                }
+          if (update > 0)
+            ListView_RedrawItems(hWndListView, iRow, iRow + update -1);
 
-              if (update > 0)
-                ListView_RedrawItems(hWndListView, iRow, iRow + update -1);
+          if ((todo & ListViewLine::Action::NextRow)
+              && iRow + 1 < ListView_GetItemCount(hWndListView))
+            {
+              // move selection to next row
+              ListView_SetItemState(hWndListView, -1, 0, LVIS_SELECTED | LVIS_FOCUSED);
+              ListView_SetItemState(hWndListView, iRow + 1, LVIS_SELECTED | LVIS_FOCUSED,
+                                    LVIS_SELECTED | LVIS_FOCUSED);
+              ListView_SetSelectionMark(hWndListView, iRow + 1);
+              ListView_EnsureVisible(hWndListView, iRow + 1, false);
             }
         }
     }
diff --git a/ListView.h b/ListView.h
index 95dd9ee6..6a1be0b5 100644
--- a/ListView.h
+++ b/ListView.h
@@ -25,10 +25,17 @@
 // ListView Common Control
 // ---------------------------------------------------------------------------
 
+struct ModifierKeys
+{
+  enum { Shift = 0x01, Control = 0x02, Alt = 0x04 };
+  static int get(); // get bitmask of currently pressed keys
+};
+
 class ListViewLine
 {
  public:
   enum class State { collapsed, expanded, nothing=-1 };
+  enum Action { None = 0x00, Direct = 0x01, PopUp = 0x02, NextRow = 0x04 };
 
   virtual ~ListViewLine() {};
   virtual const std::wstring get_text(int col) const = 0;
@@ -38,7 +45,8 @@ class ListViewLine
   virtual ActionList *get_actions(int col) const = 0;
   virtual int do_action(int col, int id) = 0;
   virtual int do_default_action(int col) = 0;
-  virtual bool map_key_to_action(WORD vkey, int *col_num, int *action_id) const = 0;
+  virtual int map_key_to_action(WORD vkey, int modkeys, int & col_num,
+                                int & action_id) const = 0;
 };
 
 typedef std::vector<ListViewLine *> ListViewContents;
diff --git a/PickCategoryLine.cc b/PickCategoryLine.cc
index d2ac8992..b13dbe4e 100644
--- a/PickCategoryLine.cc
+++ b/PickCategoryLine.cc
@@ -96,20 +96,19 @@ PickCategoryLine::get_tooltip(int col_num) const
   return "";
 }
 
-bool
-PickCategoryLine::map_key_to_action(WORD vkey, int *col_num, int *action_id) const
+int
+PickCategoryLine::map_key_to_action(WORD vkey, int modkeys, int & col_num,
+                                    int & action_id) const
 {
   switch (vkey)
     {
-    case VK_SPACE:
-      *col_num = pkgname_col;
-      *action_id = 0;
-      return true;
-    case VK_APPS:
-      *col_num = new_col;
-      *action_id = -1;
-      return true;
+    case VK_SPACE: // expand <> collapse category
+      col_num = pkgname_col;
+      return Action::Direct;
+    case VK_APPS: // install/reinstall/uninstall context menu for category
+      col_num = new_col;
+      return Action::PopUp;
     }
 
-  return false;
+  return Action::None;
 }
diff --git a/PickCategoryLine.h b/PickCategoryLine.h
index 6a7321d1..7616b151 100644
--- a/PickCategoryLine.h
+++ b/PickCategoryLine.h
@@ -41,7 +41,7 @@ public:
   ActionList *get_actions(int col) const;
   int do_action(int col, int action_id);
   int do_default_action(int col);
-  bool map_key_to_action(WORD vkey, int *col_num, int *action_id) const;
+  int map_key_to_action(WORD vkey, int modkeys, int & col_num, int & action_id) const;
 
 private:
   CategoryTree * cat_tree;
diff --git a/PickPackageLine.cc b/PickPackageLine.cc
index ae1e5204..c1e2a150 100644
--- a/PickPackageLine.cc
+++ b/PickPackageLine.cc
@@ -144,17 +144,30 @@ PickPackageLine::get_indent() const
   return indent;
 }
 
-bool
-PickPackageLine::map_key_to_action(WORD vkey, int *col_num, int *action_id) const
+int
+PickPackageLine::map_key_to_action(WORD vkey, int modkeys, int & col_num,
+                                   int & action_id) const
 {
   switch (vkey)
     {
-    case VK_SPACE:
+    case VK_SPACE: // install/reinstall/uninstall context menu for package
     case VK_APPS:
-      *col_num = new_col;
-      *action_id = -1;
-      return true;
+      col_num = new_col;
+      return Action::PopUp;
+    case 'I': // Ctrl+I: select install default version and move to next row
+    case 'R': // Ctrl+R: select reinstall and move to next row
+    case 'U': // Ctrl+U: select uninstall and move to next row
+      if (modkeys != ModifierKeys::Control)
+        break;
+      col_num = new_col;
+      switch (vkey)
+        {
+        case 'I': action_id = packagemeta::Install_action; break;
+        case 'R': action_id = packagemeta::Reinstall_action; break;
+        default:  action_id = packagemeta::Uninstall_action; break;
+        }
+      return Action::Direct | Action::NextRow;
     }
 
-  return false;
+  return Action::None;
 }
diff --git a/PickPackageLine.h b/PickPackageLine.h
index 2c59e902..0bf4ae68 100644
--- a/PickPackageLine.h
+++ b/PickPackageLine.h
@@ -37,7 +37,7 @@ public:
   ActionList *get_actions(int col_num) const;
   int do_action(int col, int action_id);
   int do_default_action(int col);
-  bool map_key_to_action(WORD vkey, int *col_num, int *action_id) const;
+  int map_key_to_action(WORD vkey, int modkeys, int & col_num, int & action_id) const;
 private:
   packagemeta & pkg;
   PickView & theView;
diff --git a/package_meta.cc b/package_meta.cc
index 8a695257..a5dc4364 100644
--- a/package_meta.cc
+++ b/package_meta.cc
@@ -651,6 +651,13 @@ packagemeta::set_action (_actions action, packageversion const &default_version,
 	      srcpick (false);
 	    }
 	}
+      else
+	{
+	  action = NoChange_action;
+	  desired = installed;
+	  pick (false);
+	  srcpick (false);
+	}
     }
   else if (action == Reinstall_action)
     {
@@ -670,6 +677,10 @@ packagemeta::set_action (_actions action, packageversion const &default_version,
   else if (action == Uninstall_action)
     {
       desired = packageversion ();
+      pick (false);
+      srcpick (false);
+      if (!installed)
+	action = NoChange_action;
     }
 
   _action = action;