From de7b2c60c257a8b9298f1a0d2b7ec137e2562fce Mon Sep 17 00:00:00 2001
From: "Rob Swindell (on Debian Linux)" <rob@synchro.net>
Date: Mon, 17 Jun 2024 19:33:31 -0700
Subject: [PATCH] Add suport for option/item tagging using the WIN_TAG ulist()
 mode flag

For use with fileman.js:

The space bar can be used by the user to "tag" items, or Ctrl-A to toggle
tag status for *all* items. Returns MSK_TAG|with the option tagged/untagged
or MSG_TAGALL when all tags are being toggled (via ^A).

Also, fix bug where ^Find command would not restore the status bar after
ulist() would overwrite it with the string-input/edit hot-keys available.
---
 src/uifc/uifc.h   |  4 ++++
 src/uifc/uifc32.c | 24 +++++++++++++++++++++---
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/src/uifc/uifc.h b/src/uifc/uifc.h
index 4cb1d1d7ae..c4a19718d7 100644
--- a/src/uifc/uifc.h
+++ b/src/uifc/uifc.h
@@ -88,6 +88,9 @@
 #define MSK_CUT 			0x40000000
 #define MSK_PASTE			0x50000000	/* Overwrite selected item with previously copied item */
 #define MSK_EDIT			0x60000000
+#define MSK_TAG				0x70000000
+
+#define MSK_TAGALL			(MSK_TAG | MSK_OFF)
 
 /* Legacy terms (get/put instead of copy/paste) */
 #define MSK_GET		MSK_COPY
@@ -140,6 +143,7 @@
 #define WIN_DYN 	(1LL<<16) /* Dynamic window - return at least every second */
 #define WIN_CUT		(1LL<<17)	/* Allow ^X (cut) a menu item */
 #define WIN_HLP 	(1LL<<17) /* Parse 'Help codes' - showbuf() */
+#define WIN_TAG		(1LL<<18)	/* Allow space bar to toggle tagged options */
 #define WIN_PACK 	(1LL<<18) /* Pack text in window (No padding) - showbuf() */
 #define WIN_IMM 	(1LL<<19) /* Draw window and return immediately */
 #define WIN_FAT		(1LL<<20)	/* Do not pad outside borders */
diff --git a/src/uifc/uifc32.c b/src/uifc/uifc32.c
index 940a98523a..124c544ffd 100644
--- a/src/uifc/uifc32.c
+++ b/src/uifc/uifc32.c
@@ -1222,6 +1222,10 @@ int ulist(uifc_winmode_t mode, int left, int top, int width, int *cur, int *bar
 				case DEL:
 					gotkey=CIO_KEY_DC;	/* delete */
 					break;
+				case CTRL_A:
+					if(mode & WIN_TAG)
+						return MSK_TAGALL;
+					break;
 				case CTRL_B:
 					if(!(api->mode&UIFC_NOCTRL))
 						gotkey=CIO_KEY_HOME;
@@ -1730,6 +1734,10 @@ int ulist(uifc_winmode_t mode, int left, int top, int width, int *cur, int *bar
 				}
 				else
 					switch(gotkey) {
+						case ' ':
+							if(mode & WIN_TAG)
+								return MSK_TAG | (*cur);
+							break;
 						case CR:
 							if(!opts)
 								break;
@@ -1878,7 +1886,7 @@ int ulist(uifc_winmode_t mode, int left, int top, int width, int *cur, int *bar
 int uinput(uifc_winmode_t mode, int left, int top, const char *inprompt, char *str,
 	int max, int kmode)
 {
-	struct vmem_cell shade[MAX_COLS], save_buf[MAX_COLS*4], in_win[MAX_COLS*3];
+	struct vmem_cell shade[MAX_COLS], save_buf[MAX_COLS*4], in_win[MAX_COLS*3], save_bottomline[MAX_COLS];
 	int	width;
 	int height=3;
 	int i,plen,slen,j;
@@ -1933,9 +1941,11 @@ int uinput(uifc_winmode_t mode, int left, int top, const char *inprompt, char *s
 		left=-(s_left)+1;
 	if(top<0)
 		top=0;
-	if(mode&WIN_SAV)
+	if(mode&WIN_SAV) {
 		vmem_gettext(s_left+left,s_top+top,s_left+left+width+(shadow*2)-1
 			,s_top+top+height+(!shadow),save_buf);
+		vmem_gettext(1, api->scrn_len + 1, api->scrn_width, api->scrn_len + 1, save_bottomline);
+	}
 	if(mode&WIN_ORG) { /* Clear around menu */
 		if(top)
 			vmem_puttext(1,2,api->scrn_width,s_top+top-1,blk_scrn);
@@ -2032,9 +2042,11 @@ int uinput(uifc_winmode_t mode, int left, int top, const char *inprompt, char *s
 		api->bottomline(WIN_COPY|WIN_CUT|WIN_PASTE);
 	textattr(api->lclr|(api->bclr<<4));
 	i=ugetstr(s_left+left+plen+offset,s_top+top+tbrdrwidth,iwidth,str,max,kmode,NULL);
-	if(mode&WIN_SAV)
+	if(mode&WIN_SAV) {
 		vmem_puttext(s_left+left,s_top+top,s_left+left+width+(shadow*2)-1
 			,s_top+top+height+(!shadow),save_buf);
+		vmem_puttext(1, api->scrn_len + 1, api->scrn_width, api->scrn_len + 1, save_bottomline);
+	}
 	free(prompt);
 	return(i);
 }
@@ -2543,6 +2555,12 @@ void bottomline(uifc_winmode_t mode)
 		i += uprintf(i,api->scrn_len+1,api->bclr|(api->cclr<<4),"F2 ");
 		i += uprintf(i,api->scrn_len+1,BLACK|(api->cclr<<4),"Edit Item  ");
 	}
+	if(mode&WIN_TAG) {
+		i += uprintf(i,api->scrn_len+1,api->bclr|(api->cclr<<4),"Space ");
+		i += uprintf(i,api->scrn_len+1,BLACK|(api->cclr<<4),"Tag Item  ");
+		i += uprintf(i,api->scrn_len+1,api->bclr|(api->cclr<<4),"^A ");
+		i += uprintf(i,api->scrn_len+1,BLACK|(api->cclr<<4),"Tag All  ");
+	}
 	if(mode&WIN_COPY) {
 		if(api->mode&UIFC_NOCTRL) {
 			i += uprintf(i,api->scrn_len+1,api->bclr|(api->cclr<<4),"F5 ");
-- 
GitLab