/* Copyright (c) 2024 PTC Inc. and/or Its Subsidiary Companies. All Rights Reserved. */ #ifndef lint static char UtilMenu_c [] = "@(#)UtilMenu.c 1.2 11/26/96"; #endif /*--------------------------------------------------------------------*\ Pro/Toolkit includes -- include this first \*--------------------------------------------------------------------*/ #include <ProToolkit.h> #include <ProArray.h> #include <ProMenu.h> #include <ProUtil.h> /*--------------------------------------------------------------------*\ Application macros \*--------------------------------------------------------------------*/ #include <TestError.h> #include <UtilMenu.h> #include "UtilString.h" /*====================================================================*\ FUNCTION : ProUtilAssign PURPOSE : assigns option to a member (being dereferenced & casted to int) Can be used in promenu_on_button. The menu will diappear after the chosen menu button is pushed. \*====================================================================*/ int ProUtilAssign(ProAppData p_member, int option) { ProError status; *((int *)p_member) = option; status = ProMenuDelete(); TEST_CALL_REPORT("ProMenuDelete","ProUtilAssign", status, status != PRO_TK_NO_ERROR); return (0); } /*====================================================================*\ FUNCTION : ProUtilMenuKill PURPOSE : Deletes the number of menus given. \*====================================================================*/ int ProUtilMenuKill(ProAppData p_member, int n_menus) { ProError status; int i; for (i = 0; i < n_menus; i++) { status = ProMenuDelete(); TEST_CALL_REPORT("ProMenuDelete","ProUtilMenuKill", status, status != PRO_TK_NO_ERROR); } return (0); } /*=============================================================*\ FUNCTION: ProUtilMenubuttonActivate PURPOSE: Activate/Deactivate button \*=============================================================*/ ProError ProUtilMenubuttonActivate( char *menu, /* In : the menu name */ char *menubutton, /* In : the menubutton name */ int enable) /* In : 0 - dis, 1 - en */ { ProError err; if (enable) { err = ProMenubuttonActivate(menu, menubutton); TEST_CALL_REPORT("ProMenubuttonActivate()", "ProUtilMenubuttonActivate()", err, err != PRO_TK_NO_ERROR); } else { err = ProMenubuttonDeactivate(menu, menubutton); TEST_CALL_REPORT("ProMenubuttonDeactivate()", "ProUtilMenubuttonActivate()", err, err != PRO_TK_NO_ERROR); } return (err); } /*=============================================================*\ FUNCTION: ProUtilMenubuttonHighlight PURPOSE: Highlight / Unhighlight button \*=============================================================*/ ProError ProUtilMenubuttonHighlight( char *menu, /* In : the menu name */ char *menubutton, /* In : the menubutton name */ int enable) /* In : 0 - dis, 1 - en */ { ProError err; if (enable) { err = ProMenubuttonHighlight(menu, menubutton); TEST_CALL_REPORT("ProMenubuttonHighlight()", "ProUtilMenubuttonActivate()", err, err != PRO_TK_NO_ERROR); } else { err = ProMenubuttonUnhighlight(menu, menubutton); TEST_CALL_REPORT("ProMenubuttonUnhighlight()", "ProUtilMenubuttonActivate()", err, err != PRO_TK_NO_ERROR); } return (err); } /*=============================================================*\ FUNCTION: ProUtilMenubuttonDeleteWithStatus PURPOSE: Call DeleteWithStatus func \*=============================================================*/ int ProUtilMenubuttonDeleteWithStatus( ProAppData appdata, int status) { ProError err; err = ProMenuDeleteWithStatus(status); TEST_CALL_REPORT("ProMenuDeleteWithStatus()", "ProUtilMenubuttonDeleteWithStatus()", err, err != PRO_TK_NO_ERROR); return (0); } /*============================================================================*\ Function: ProUtilMenuIntValueSelect Purpose: Create menu/Select int value/Close menu Return: PRO_TK_NO_ERROR if value selected, or PRO_TK_GENERAL_ERROR \*============================================================================*/ ProError ProUtilMenuIntValueSelect( ProUtilMenuButtons *buttons_array, /* In : The menu button array */ int *output_value) { ProError err; int i, n_buttons, menu_id; wchar_t **w_menu_buttons; for (n_buttons = 0; buttons_array[n_buttons].button[0]!='\0'; n_buttons++); if (n_buttons <= 1) return PRO_TK_NO_ERROR; ProUtilMenuStringsAlloc(&w_menu_buttons); for (i=1; i<n_buttons; i++) ProUtilMenuStringsStrAdd(&w_menu_buttons, buttons_array[i].button); ProMenuFromStringsRegister ( buttons_array[0].button, NULL, w_menu_buttons, NULL, NULL, &menu_id); ProUtilMenuStringsFree(&w_menu_buttons); for (i=0; i<n_buttons; i++) { if (buttons_array[i].special_flag & (TEST_CALL_PRO_MENU_DELETE | TEST_CALL_PRO_MENU_HOLD)) ProMenubuttonActionSet(buttons_array[0].button, buttons_array[i].button, (ProMenubuttonAction) (buttons_array[i].special_flag & TEST_CALL_PRO_MENU_DELETE ? ProMenuDelete : ProMenuHold), NULL, 0); else ProMenubuttonActionSet(buttons_array[0].button, buttons_array[i].button, (ProMenubuttonAction) ProUtilMenubuttonDeleteWithStatus, NULL, buttons_array[i].value); } for (i=1; i<n_buttons; i++) { if (buttons_array[i].special_flag & TEST_CALL_PRO_MENUBUTTON_DELETE) ProMenubuttonDelete(buttons_array[0].button, buttons_array[i].button, &menu_id); } err = ProMenuCreate( PROMENUTYPE_MAIN, buttons_array[0].button, &menu_id ); for (i=1; i<n_buttons; i++) { if (buttons_array[i].special_flag & (TEST_CALL_PRO_MENU_ACTIVATE | TEST_CALL_PRO_MENU_DEACTIVATE)) ProUtilMenubuttonActivate(buttons_array[0].button, buttons_array[i].button, buttons_array[i].special_flag & TEST_CALL_PRO_MENU_ACTIVATE); if (buttons_array[i].special_flag & (TEST_CALL_PRO_MENU_HIGHLIGHT | TEST_CALL_PRO_MENU_UNHIGHLIGHT)) ProUtilMenubuttonActivate(buttons_array[0].button, buttons_array[i].button, buttons_array[i].special_flag & TEST_CALL_PRO_MENU_HIGHLIGHT); } err = ProMenuProcess(buttons_array[0].button, output_value); return (err); } /*============================================================================*\ Function: ProUtilMenuStringsAlloc Purpose: Alloc memory for array of wchar_t* used in ProMenu functions \*============================================================================*/ ProError ProUtilMenuStringsAlloc( wchar_t ***w_ptr) { ProError err; static wchar_t w_epmty[] = {'\0'}; wchar_t *w_p = w_epmty; err = ProArrayAlloc(0, sizeof(wchar_t*), 1, (ProArray*)w_ptr); if (err == PRO_TK_NO_ERROR) err = ProArrayObjectAdd((ProArray*)w_ptr, 0, 1, &w_p); return (err); } /*============================================================================*\ Function: ProUtilMenuStringsStrAdd Purpose: Alloc memory and add string to MenuStrings array \*============================================================================*/ ProError ProUtilMenuStringsStrAdd( wchar_t ***w_ptr, char *str) { ProError err; wchar_t *w_p; int len, n_str; len = strlen(str); w_p = (wchar_t*)calloc(len + 1, sizeof(wchar_t)); if (w_p == NULL) return (PRO_TK_GENERAL_ERROR); ProStringToWstring(w_p, str); err = ProArraySizeGet((ProArray)*w_ptr, &n_str); err = ProArrayObjectAdd((ProArray*)w_ptr, n_str-1, 1, &w_p); return (err); } /*============================================================================*\ Function: ProUtilMenuStringsWstrAdd Purpose: Alloc memory and add string to MenuStrings array \*============================================================================*/ ProError ProUtilMenuStringsWstrAdd( wchar_t ***w_ptr, wchar_t *w_str) { ProError err; wchar_t *w_p; int len, n_str; len = ProUtilWstrLen(w_str); w_p = (wchar_t*)calloc(len + 1, sizeof(wchar_t)); if (w_p == NULL) return (PRO_TK_GENERAL_ERROR); ProUtilWstrcpy(w_p, w_str); err = ProArraySizeGet((ProArray)*w_ptr, &n_str); err = ProArrayObjectAdd((ProArray*)w_ptr, n_str-1, 1, &w_p); return (err); } /*============================================================================*\ Function: ProUtilMenuStringsIntValueSelect Purpose: Select a string from menu and return it's number \*============================================================================*/ ProError ProUtilMenuStringsIntValueSelect( char *menu_name, wchar_t **w_ptr, int *output_value) { ProUtilMenuButtons *buttons_array; int i, n_buttons; ProError err; for(n_buttons=1; w_ptr[n_buttons-1][0] != '\0'; n_buttons++); buttons_array = (ProUtilMenuButtons *)calloc(n_buttons+1, sizeof(ProUtilMenuButtons)); ProUtilstrcpy(buttons_array[0].button, (const char *) menu_name); buttons_array[0].special_flag = TEST_CALL_PRO_MENU_DELETE; for(i=1; i<=n_buttons; i++) { ProWstringToString(buttons_array[i].button, w_ptr[i-1]); buttons_array[i].value = i - 1; } err = ProUtilMenuIntValueSelect(buttons_array, output_value); free(buttons_array); return (err); } /*============================================================================*\ Function: ProUtilMenuStringsFree Purpose: Free memory allocated by ..Alloc, ..StrAdd, ..WstrAdd \*============================================================================*/ ProError ProUtilMenuStringsFree( wchar_t ***w_ptr) { ProError err; int i, n_str; wchar_t **w_p = *w_ptr; err = ProArraySizeGet((ProArray)w_p, &n_str); for (i=n_str-2; i>0; i--) free(w_p[i]); err = ProArrayFree((ProArray*)w_ptr); return (err); } typedef struct menu_toggle_info { char *menu_name; wchar_t **w_menu_buttons; int *button_status; int n_buttons; } MenuToggleInfo; #define SELECT_ALL 0 #define UNSEL_ALL 1 #define DONE_SEL 2 #define QUIT_SEL 3 /*============================================================================*\ Function: ProUtilMenuToggleOne Purpose: Used from ProUtilMenuStringManySelect \*============================================================================*/ int ProUtilMenuToggleOne( MenuToggleInfo *p_toggle_info, int n_str) { p_toggle_info->button_status[n_str] = !p_toggle_info->button_status[n_str]; return (0); } /*============================================================================*\ Function: ProUtilMenuToggleDone Purpose: Used from ProUtilMenuStringManySelect \*============================================================================*/ int ProUtilMenuToggleDone( MenuToggleInfo *p_toggle_info, int action) { int i, sel; ProError err; ProCharName name; switch (action) { case SELECT_ALL: case UNSEL_ALL: sel = (action == SELECT_ALL); for (i=0; i<p_toggle_info->n_buttons; i++) if (p_toggle_info->button_status[i] != sel) { ProWstringToString(name, p_toggle_info->w_menu_buttons[i]); err = ProUtilMenubuttonHighlight(p_toggle_info->menu_name, name, sel); p_toggle_info->button_status[i] = sel; } break; case DONE_SEL: case QUIT_SEL: err = ProMenuDeleteWithStatus(action); err = ProMenuDeleteWithStatus(action); break; } return (0); } /*============================================================================*\ Function: ProUtilMenuStringManySelect Purpose: Select many string from menu with submenu Select All/Unsell All \*============================================================================*/ ProError ProUtilMenuStringManySelect( char *menu_name, /* In : Menu name */ wchar_t **w_menu_buttons, /* In : Menu buttons */ int **output_array, /* Out: ProArray of numbers of selected strings, use ProArrayFree to free memory */ int *p_n_sel) /* Out: Number of selected components */ { int i, n_but, n_sel, menu_id, action; ProError err, ret_status = PRO_TK_USER_ABORT; int *toggle_array; MenuToggleInfo toggle_info; ProCharName name; wchar_t **w_menus; for(n_but=0; w_menu_buttons[n_but][0] != '\0'; n_but++); err = ProArrayAlloc(n_but, sizeof(int), 1, (ProArray*)&toggle_array); toggle_info.w_menu_buttons = w_menu_buttons; toggle_info.button_status = toggle_array; toggle_info.n_buttons = n_but; toggle_info.menu_name = menu_name; err = ProMenuFromStringsRegister ( menu_name, NULL, w_menu_buttons, NULL, NULL, &menu_id); for (i=0; i<n_but; i++) { toggle_array[i] = 0; ProWstringToString(name, w_menu_buttons[i]); err = ProMenubuttonActionSet(menu_name, name, (ProMenubuttonAction)ProUtilMenuToggleOne, &toggle_info, i); } err = ProMenubuttonActionSet(menu_name, menu_name, (ProMenubuttonAction)ProMenuDelete, NULL, 0); err = ProMenuModeSet(menu_name, PROMENUMODE_DATA); err = ProMenuDatamodeSet(menu_name, PRO_B_TRUE ); err = ProMenuCreate(PROMENUTYPE_MAIN, menu_name, &menu_id); err = ProUtilMenuStringsAlloc(&w_menus); err = ProUtilMenuStringsStrAdd(&w_menus, (char *)"Select All"); err = ProUtilMenuStringsStrAdd(&w_menus, (char *)"Unsel All"); err = ProUtilMenuStringsStrAdd(&w_menus, (char *)"Done Sel"); err = ProUtilMenuStringsStrAdd(&w_menus, (char *)"Quit Sel"); ProMenuFromStringsRegister ( (char *)"TkMenuUtilSelect", NULL, w_menus, NULL, NULL, &menu_id); err = ProMenubuttonActionSet((char *)"TkMenuUtilSelect", (char *)"Select All", (ProMenubuttonAction)ProUtilMenuToggleDone, &toggle_info, SELECT_ALL); err = ProMenubuttonActionSet((char *)"TkMenuUtilSelect", (char *)"Unsel All", (ProMenubuttonAction)ProUtilMenuToggleDone, &toggle_info, UNSEL_ALL); err = ProMenubuttonActionSet((char *)"TkMenuUtilSelect", (char *)"Done Sel", (ProMenubuttonAction)ProUtilMenuToggleDone, &toggle_info, DONE_SEL); err = ProMenubuttonActionSet((char *)"TkMenuUtilSelect", (char *)"Quit Sel", (ProMenubuttonAction)ProUtilMenuToggleDone, &toggle_info, QUIT_SEL); err = ProMenubuttonActionSet((char *)"TkMenuUtilSelect", (char *)"TkMenuUtilSelect", (ProMenubuttonAction)ProUtilMenuToggleDone, &toggle_info, QUIT_SEL); err = ProMenuCreate(PROMENUTYPE_SUB, (char *)"TkMenuUtilSelect", &menu_id); err = ProMenuProcess((char *)"TkMenuUtilSelect", &action); if(err == PRO_TK_NO_ERROR && action == DONE_SEL) { err = ProArrayAlloc(0, sizeof(int), 1, (ProArray*)output_array); n_sel = 0; for (i=0; i<n_but; i++) if (toggle_array[i]) { ProArrayObjectAdd((ProArray*)output_array, PRO_VALUE_UNUSED, 1, &i); n_sel++; } if (n_sel>0) { *p_n_sel = n_sel; ret_status = PRO_TK_NO_ERROR; } else err = ProArrayFree((ProArray*)output_array); } err = ProArrayFree((ProArray*)&toggle_array); return (ret_status); } #undef SELECT_ALL #undef UNSEL_ALL #undef DONE_SEL #undef QUIT_SEL