Provide a new list_multisel_dialog() function Avaliable as a patch: http://sourceforge.net/tracker/index.php?func=detail&aid=988172&group_id=11005&atid=311005 [ 988172 ] Provide a new list_multisel_dialog() function ListMultiSel.diff 2004-07-09 12:00 The new builtin macro function, list_multisel_dialog(), acts as a complement to the current list_dialog() function. It works in exactly the same way, except that the user can choose more than one of the presented lines in the list. These lines are returned to the user as a single string, with the lines separated by the newline "\n" character. (Note that there is no "\n" at the end of the last of the selected lines returned in the string.) The same pseudovariable, $list_dialog_button, is used by both functions to return the number of the dialog button pressed. I decided to use a single string return value rather than an array value for two reasons. Firstly, the input and output are in the same format. Second, doing things this way avoids having to deal with indices to an array, and conversion to an array can already be performed very readily using split. It was also easier to implement this way. As part of this patch I increased the list's maximum display length on dialog creation from 10 to 25. (I spend a lot of time simply resizing such dialogs since 10 lines is usually too small a window for me.) Ideally, this should be configurable (through a non-saved X resource would be sufficient). diff -ur nedit_official/source/macro.c nedit_mod/source/macro.c --- nedit_official/source/macro.c 2004-06-10 13:01:26.000000000 -0400 +++ nedit_mod/source/macro.c 2004-07-09 13:02:04.118937000 -0400 @@ -235,8 +235,12 @@ static int killCalltipMS(WindowInfo *window, DataValue *argList, int nArgs, DataValue *result, char **errMsg); /* T Balinski */ +static int listDialogBase(WindowInfo *window, DataValue *argList, int nArgs, + DataValue *result, char **errMsg, Boolean isMultiLine); static int listDialogMS(WindowInfo *window, DataValue *argList, int nArgs, DataValue *result, char **errMsg); +static int listMultiselDialogMS(WindowInfo *window, DataValue *argList, + int nArgs, DataValue *result, char **errMsg); static void listDialogBtnCB(Widget w, XtPointer clientData, XtPointer callData); static void listDialogCloseCB(Widget w, XtPointer clientData, @@ -405,7 +409,7 @@ writeFileMS, appendFileMS, beepMS, getSelectionMS, validNumberMS, replaceInStringMS, selectMS, selectRectangleMS, focusWindowMS, shellCmdMS, stringToClipboardMS, clipboardToStringMS, toupperMS, - tolowerMS, listDialogMS, getenvMS, + tolowerMS, listDialogMS, listMultiselDialogMS, getenvMS, stringCompareMS, splitMS, calltipMS, killCalltipMS, /* DISABLED for 5.4 setBacklightStringMS,*/ rangesetCreateMS, rangesetDestroyMS, @@ -424,7 +428,7 @@ "write_file", "append_file", "beep", "get_selection", "valid_number", "replace_in_string", "select", "select_rectangle", "focus_window", "shell_command", "string_to_clipboard", "clipboard_to_string", - "toupper", "tolower", "list_dialog", "getenv", + "toupper", "tolower", "list_dialog", "list_multisel_dialog", "getenv", "string_compare", "split", "calltip", "kill_calltip", /* DISABLED for 5.4 "set_backlight_string", */ "rangeset_create", "rangeset_destroy", @@ -3247,8 +3251,8 @@ } /* T Balinski */ -static int listDialogMS(WindowInfo *window, DataValue *argList, int nArgs, - DataValue *result, char **errMsg) +static int listDialogBase(WindowInfo *window, DataValue *argList, int nArgs, + DataValue *result, char **errMsg, Boolean isMultiLine) { macroCmdInfo *cmdData; char stringStorage[9][TYPE_INT_STR_SIZE(int)]; @@ -3266,7 +3270,6 @@ Arg al[20]; int ac; - /* Ignore the focused window passed as the function argument and put the dialog up over the window which is executing the macro */ window = MacroRunWindow(); @@ -3391,7 +3394,7 @@ XtSetArg(al[ac], XmNlistLabelString, s1=MKSTRING(message)); ac++; XtSetArg(al[ac], XmNlistItems, test_strings); ac++; XtSetArg(al[ac], XmNlistItemCount, nlines); ac++; - XtSetArg(al[ac], XmNlistVisibleItemCount, (nlines > 10) ? 10 : nlines); ac++; + XtSetArg(al[ac], XmNlistVisibleItemCount, (nlines > 25) ? 25 : nlines); ac++; XtSetArg(al[ac], XmNokLabelString, s2=XmStringCreateSimple(btnLabels[0])); ac++; dialog = CreateSelectionDialog(window->shell, "macroListDialog", al, ac); AddMotifCloseCallback(XtParent(dialog), listDialogCloseCB, window); @@ -3409,7 +3412,8 @@ /* modify the list */ XtVaSetValues(XmSelectionBoxGetChild(dialog, XmDIALOG_LIST), - XmNselectionPolicy, XmSINGLE_SELECT, + XmNselectionPolicy, + isMultiLine ? XmMULTIPLE_SELECT : XmSINGLE_SELECT, XmNuserData, (XtPointer)text_lines, NULL); /* Unmanage unneeded widgets */ @@ -3457,6 +3461,18 @@ return True; } +static int listDialogMS(WindowInfo *window, DataValue *argList, int nArgs, + DataValue *result, char **errMsg) +{ + return listDialogBase(window, argList, nArgs, result, errMsg, False); +} + +static int listMultiselDialogMS(WindowInfo *window, DataValue *argList, + int nArgs, DataValue *result, char **errMsg) +{ + return listDialogBase(window, argList, nArgs, result, errMsg, True); +} + static void listDialogBtnCB(Widget w, XtPointer clientData, XtPointer callData) { @@ -3468,6 +3484,8 @@ char **text_lines; int btnNum; int n_sel, *seltable, sel_index = 0; + int selPolicy; + Boolean isMultiLine; Widget theList; size_t length; @@ -3479,21 +3497,36 @@ /* Return the string selected in the selection list area */ XtVaGetValues(theList, XmNuserData, &text_lines, NULL); if (!XmListGetSelectedPos(theList, &seltable, &n_sel)) { - n_sel = 0; - } - else { - sel_index = seltable[0] - 1; - XtFree((XtPointer)seltable); + n_sel = -1; } - if (!n_sel) { + if (n_sel < 0) { text = PERM_ALLOC_STR(""); length = 0; + n_sel = 0; } else { - length = strlen((char *)text_lines[sel_index]); - text = AllocString(length + 1); - strcpy(text, text_lines[sel_index]); + /* count up the total size of the result */ + int i; + size_t len; + char *cp; + length = 0; + for (i = 0; i < n_sel; i++) { + sel_index = seltable[i] - 1; + length += strlen((char *)text_lines[sel_index]) + 1; + } + /* allocate result */ + cp = text = AllocString(length); + /* and copy strings, separated by '\n' */ + for (i = 0; i < n_sel; i++) { + sel_index = seltable[i] - 1; + len = strlen((char *)text_lines[sel_index]); + strcpy(cp, text_lines[sel_index]); + cp += len; + *cp++ = '\n'; + } + text[--length] = '\0'; + XtFree((XtPointer)seltable); } /* don't need text_lines anymore: free it */ Only in nedit_mod/util: Makefile.solaris