/* Copyright (c) 2024 PTC Inc. and/or Its Subsidiary Companies. All Rights Reserved. */ /*--------------------------------------------------------------------*\ Pro/TOOLKIT includes \*--------------------------------------------------------------------*/ #include <ProToolkit.h> #include <ProMdl.h> #include <ProMenu.h> #include <ProMessage.h> #include <ProUI.h> #include <ProUIDialog.h> #include <ProUIPushbutton.h> #include <ProUITable.h> #include <ProUIInputpanel.h> #include <ProTKRunTime.h> #include <ProWstring.h> #include <ProUtil.h> /*--------------------------------------------------------------------*\ C System includes \*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*\ Application includes \*--------------------------------------------------------------------*/ #include "TestError.h" #include "TestMenu.h" #include "UtilFiles.h" #include "UtilString.h" #define EX_DLG_NAME (char*)"uitableexample" #define EX_DLG_RES_FILE (char*)"uitableexample" #define EX_DLG_TABLE (char*)"Table2" #define EX_DLG_ADD (char*)"PushButton14" #define EX_DLG_REMOVE (char*)"PushButton15" #define EX_DLG_UP (char*)"PushButton16" #define EX_DLG_DOWN (char*)"PushButton17" #define EX_DLG_CLOSE (char*)"PushButton18" #define EX_DLG_IP (char*)"InputPanel8" static int row_number; static char* ip_row; static char* ip_col; /**********************************************************************\ Example which demonstrates UI Table usage. The user can add and remove rows and edit cells. \**********************************************************************/ /*====================================================================*\ FUNCTION: ProTestUITableGetLastRow PURPOSE: Get the last row in the table \*====================================================================*/ ProError ProTestUITableGetLastRow(char *dialog, char *table, char *last_row_name) { ProError status; int count; char **values; /*--------------------------------------------------------------------*\ Get all the rows in the table and the return the row with the greatest index. \*--------------------------------------------------------------------*/ status = ProUITableRownamesGet(dialog, table, &count, &values); TEST_CALL_REPORT("ProUITableRownamesGet()", "ProTestUITableGetLastRow()", status, status != PRO_TK_NO_ERROR); if((status != PRO_TK_NO_ERROR) || (count < 1)) { last_row_name = NULL; } else { ProUtilstrcpy(last_row_name, values[count-1]); } ProStringarrayFree(values, count); return (PRO_TK_NO_ERROR); } /*====================================================================*\ FUNCTION: ProTestUITableEditAddAction PURPOSE: Add a row to the table \*====================================================================*/ void ProTestUITableEditAddAction(char *dialog, char *component, ProAppData data) { ProError status; char last_row_name[3] = {'\0','\0','\0'}; char *last_row_name_ptr = &last_row_name[0]; char new_row_name[3] = {'\0','\0','\0'}; char *new_row_name_ptr = &new_row_name[0]; char str_row_data[32]; wchar_t row_data[32]; int col_number; /*--------------------------------------------------------------------*\ Add a row after the last row \*--------------------------------------------------------------------*/ ProTestUITableGetLastRow(EX_DLG_NAME, EX_DLG_TABLE, last_row_name_ptr); ProTKSprintf(new_row_name,"%d",(row_number+1)); status = ProUITableRowsInsert(EX_DLG_NAME, EX_DLG_TABLE, last_row_name_ptr, 1, &new_row_name_ptr); TEST_CALL_REPORT("ProUITableRowsInsert()", "ProTestUITableEditAddAction()", status, status != PRO_TK_NO_ERROR); /*--------------------------------------------------------------------*\ Enter data in the row \*--------------------------------------------------------------------*/ if(status == PRO_TK_NO_ERROR) { row_number++; ProTKSprintf(str_row_data, "R%d; C1", row_number); ProStringToWstring(row_data, str_row_data); ProUITableCellLabelSet(EX_DLG_NAME, EX_DLG_TABLE, new_row_name_ptr, (char*)"1", row_data); ProTKSprintf(str_row_data, "R%d; C2", row_number); ProStringToWstring(row_data, str_row_data); ProUITableCellLabelSet(EX_DLG_NAME, EX_DLG_TABLE, new_row_name_ptr, (char*)"2", row_data); ProTKSprintf(str_row_data, "R%d; C3", row_number); ProStringToWstring(row_data, str_row_data); ProUITableCellLabelSet(EX_DLG_NAME, EX_DLG_TABLE, new_row_name_ptr, (char*)"3", row_data); ProTKSprintf(str_row_data, "R%d; C4", row_number); ProStringToWstring(row_data, str_row_data); ProUITableCellLabelSet(EX_DLG_NAME, EX_DLG_TABLE, new_row_name_ptr, (char*)"4", row_data); } } /*====================================================================*\ FUNCTION: ProTestUITableEditRemoveAction PURPOSE: Remove selected rows from the table \*====================================================================*/ void ProTestUITableEditRemoveAction(char *dialog, char *component, ProAppData data) { ProError status; int count, i, sel_row, index; char **del_values; char **values; /*--------------------------------------------------------------------*\ Get all the selected rows \*--------------------------------------------------------------------*/ status = ProUITableSelectednamesGet(EX_DLG_NAME, EX_DLG_TABLE, &count, &del_values); TEST_CALL_REPORT("ProUITableSelectednamesGet()", "ProTestUITableEditRemoveAction()", status, status != PRO_TK_NO_ERROR); if((status == PRO_TK_NO_ERROR) && (count > 0)) { /*--------------------------------------------------------------------*\ Get the row with the lowest index \*--------------------------------------------------------------------*/ sel_row = -1; for(i=0; i<count; i=i+2) { status = ProUITableRowIndexGet(EX_DLG_NAME, EX_DLG_TABLE, del_values[i], &index); TEST_CALL_REPORT("ProUITableRowIndexGet()", "ProTestUITableEditRemoveAction()", status, status != PRO_TK_NO_ERROR); if((status == PRO_TK_NO_ERROR) && (sel_row == -1) || (sel_row > index)) { sel_row = index; } } /*--------------------------------------------------------------------*\ Delete the selected rows \*--------------------------------------------------------------------*/ for(i=0; i<count; i=i+2) { status = ProUITableRowsDelete(EX_DLG_NAME, EX_DLG_TABLE, 1, &(del_values[i])); TEST_CALL_REPORT("ProUITableRowsDelete()", "ProTestUITableEditRemoveAction()", status, status != PRO_TK_NO_ERROR); } /*--------------------------------------------------------------------*\ Highlight the row with the lowest index \*--------------------------------------------------------------------*/ if(sel_row > -1) { status = ProUITableRownamesGet(EX_DLG_NAME, EX_DLG_TABLE, &index, &values); TEST_CALL_REPORT("ProUITableRownamesGet()", "ProTestUITableEditRemoveAction()", status, status != PRO_TK_NO_ERROR); if((status == PRO_TK_NO_ERROR) && (index > 0)) { if(sel_row >= index) { sel_row = index - 1; } status = ProUITableRowCellsSelect(EX_DLG_NAME, EX_DLG_TABLE, 1, &(values[sel_row])); TEST_CALL_REPORT("ProUITableRowCellsSelect()", "ProTestUITableEditRemoveAction()", status, status != PRO_TK_NO_ERROR); } ProStringarrayFree(values, index); } } ProStringarrayFree(del_values, count); } /*====================================================================*\ FUNCTION: ProTestUITableEditSwapRows PURPOSE: Swap the two rows given their index \*====================================================================*/ ProError ProTestUITableEditSwapRows(int row1, int row2) { ProError status; int col_count, row_count, i; char **row_values; char **col_values; wchar_t *label_1, *label_2; if(row1 == row2) return PRO_TK_BAD_INPUTS; /*--------------------------------------------------------------------*\ Get the rows in the table \*--------------------------------------------------------------------*/ status = ProUITableRownamesGet(EX_DLG_NAME, EX_DLG_TABLE, &row_count, &row_values); TEST_CALL_REPORT("ProUITableRownamesGet()", "ProTestUITableEditSwapRows()", status, status != PRO_TK_NO_ERROR); if((status == PRO_TK_NO_ERROR) && (row_count > 1)) { if((row1 >= 0) && (row1 < row_count) && (row2 >= 0) && (row2 < row_count)) { /*--------------------------------------------------------------------*\ Get the columns in the table \*--------------------------------------------------------------------*/ status = ProUITableColumnnamesGet(EX_DLG_NAME, EX_DLG_TABLE, &col_count, &col_values); TEST_CALL_REPORT("ProUITableColumnnamesGet()", "ProTestUITableEditSwapRows()", status, status != PRO_TK_NO_ERROR); if((status == PRO_TK_NO_ERROR) && (col_count > 0)) { /*--------------------------------------------------------------------*\ Swap the cell values \*--------------------------------------------------------------------*/ for(i=0; i<col_count; i++) { ProUITableCellLabelGet(EX_DLG_NAME, EX_DLG_TABLE, row_values[row1], col_values[i], &label_1); ProUITableCellLabelGet(EX_DLG_NAME, EX_DLG_TABLE, row_values[row2], col_values[i], &label_2); ProUITableCellLabelSet(EX_DLG_NAME, EX_DLG_TABLE, row_values[row1], col_values[i], label_2); ProUITableCellLabelSet(EX_DLG_NAME, EX_DLG_TABLE, row_values[row2], col_values[i], label_1); } } ProStringarrayFree(col_values, col_count); } else { status = PRO_TK_BAD_INPUTS; } } ProStringarrayFree(row_values, row_count); return status; } /*====================================================================*\ FUNCTION: ProTestUITableEditMoveRows PURPOSE: Move selected row \*====================================================================*/ ProError ProTestUITableEditMoveRows(int direction) { ProError status; int count, i, sel_row, new_row, index; char **values; /*--------------------------------------------------------------------*\ Get all the selected rows \*--------------------------------------------------------------------*/ status = ProUITableSelectednamesGet(EX_DLG_NAME, EX_DLG_TABLE, &count, &values); TEST_CALL_REPORT("ProUITableSelectednamesGet()", "ProTestUITableEditMoveRows()", status, status != PRO_TK_NO_ERROR); if((status == PRO_TK_NO_ERROR) && (count > 0)) { /*--------------------------------------------------------------------*\ Get the row with the lowest index \*--------------------------------------------------------------------*/ sel_row = -1; for(i=0; i<count; i=i+2) { status = ProUITableRowIndexGet(EX_DLG_NAME, EX_DLG_TABLE, values[i], &index); TEST_CALL_REPORT("ProUITableRowIndexGet()", "ProTestUITableEditMoveRows()", status, status != PRO_TK_NO_ERROR); if((status == PRO_TK_NO_ERROR) && (sel_row == -1) || (sel_row > index)) { sel_row = index; } } /*--------------------------------------------------------------------*\ Swap the values of the selected row \*--------------------------------------------------------------------*/ new_row = sel_row + direction; status = ProTestUITableEditSwapRows(new_row, sel_row); if(status == PRO_TK_NO_ERROR) { /*--------------------------------------------------------------------*\ Deselect all the rows \*--------------------------------------------------------------------*/ for(i=0; i<count; i=i+2) { status = ProUITableRowCellsDeselect(EX_DLG_NAME, EX_DLG_TABLE, 1, &(values[i])); TEST_CALL_REPORT("ProUITableRowCellsDeselect()", "ProTestUITableEditMoveRows()", status, status != PRO_TK_NO_ERROR); } ProStringarrayFree(values, count); /*--------------------------------------------------------------------*\ Highlight the new row \*--------------------------------------------------------------------*/ status = ProUITableRownamesGet(EX_DLG_NAME, EX_DLG_TABLE, &count, &values); TEST_CALL_REPORT("ProUITableRownamesGet()", "ProTestUITableEditMoveRows()", status, status != PRO_TK_NO_ERROR); if((status == PRO_TK_NO_ERROR) && (count > 0)) { status = ProUITableRowCellsSelect(EX_DLG_NAME, EX_DLG_TABLE, 1, &(values[new_row])); TEST_CALL_REPORT("ProUITableRowCellsSelect()", "ProTestUITableEditMoveRows()", status, status != PRO_TK_NO_ERROR); } } } ProStringarrayFree(values, count); return (status); } /*====================================================================*\ FUNCTION: ProTestUITableEditUpAction PURPOSE: Move selected row up \*====================================================================*/ void ProTestUITableEditUpAction(char *dialog, char *component, ProAppData data) { ProTestUITableEditMoveRows(-1); } /*====================================================================*\ FUNCTION: ProTestUITableEditDownAction PURPOSE: Move selected row down \*====================================================================*/ void ProTestUITableEditDownAction(char *dialog, char *component, ProAppData data) { ProTestUITableEditMoveRows(1); } /*====================================================================*\ FUNCTION: ProTestUITableEditCloseAction PURPOSE: Close the dialog \*====================================================================*/ void ProTestUITableEditCloseAction(char *dialog, char *component, ProAppData data) { ProError status; status = ProUIDialogExit(dialog, PRO_TK_NO_ERROR); TEST_CALL_REPORT("ProUIDialogExit()", "ProTestUITableEditCloseAction()", status, status != PRO_TK_NO_ERROR); } /*====================================================================*\ FUNCTION: ProTestUITableEditLoseIPfocus PURPOSE: Action function for input panel at table cell \*====================================================================*/ void ProTestUITableEditLoseIPfocus(char *dialog, char *component, ProAppData data) { ProError status; wchar_t* label; char input_panel[8]; ProTKSprintf(input_panel, "%s_%s", ip_row, ip_col); /*--------------------------------------------------------------------*\ Copy the input panel label to the cell \*--------------------------------------------------------------------*/ status = ProUIInputpanelValueGet(EX_DLG_NAME, input_panel, &label); TEST_CALL_REPORT("ProUIInputpanelValueGet()", "ProTestUITableEditLoseIPfocus()", status, status != PRO_TK_NO_ERROR); if((status == PRO_TK_NO_ERROR) && (label != NULL)) { status = ProUITableCellLabelSet(EX_DLG_NAME, EX_DLG_TABLE, ip_row, ip_col, label); TEST_CALL_REPORT("ProUITableCellLabelSet()", "ProTestUITableEditLoseIPfocus()", status, status != PRO_TK_NO_ERROR); } /*--------------------------------------------------------------------*\ Delete the input panel label from the cell \*--------------------------------------------------------------------*/ status = ProUITableCellComponentDelete(EX_DLG_NAME, EX_DLG_TABLE, ip_row, ip_col); TEST_CALL_REPORT("ProUITableCellComponentDelete()", "ProTestUITableEditLoseIPfocus()", status, status != PRO_TK_NO_ERROR); ProWstringFree(label); ProStringFree(ip_row); ProStringFree(ip_col); } /*====================================================================*\ FUNCTION: ProTestUITableEditActivateCell PURPOSE: Edit action when user selects a cell \*====================================================================*/ void ProTestUITableEditActivateCell(char *dialog, char *component, ProAppData data) { ProError status; int count, i, width; char **values; char *row; wchar_t* label; char input_panel[8]; /*--------------------------------------------------------------------*\ Get all the selected rows. If more thatn one row is selected, do nothing \*--------------------------------------------------------------------*/ status = ProUITableSelectednamesGet(EX_DLG_NAME, EX_DLG_TABLE, &count, &values); TEST_CALL_REPORT("ProUITableSelectednamesGet()", "ProTestUITableEditActivateCell()", status, status != PRO_TK_NO_ERROR); if((status == PRO_TK_NO_ERROR) && (count > 0)) { row = values[0]; for(i=2; i<count; i++) { if(strcmp(row, values[i]) != 0) { ProStringarrayFree(values, count); return; } } } ProStringarrayFree(values, count); /*--------------------------------------------------------------------*\ Get the focus cell \*--------------------------------------------------------------------*/ status = ProUITableFocusCellGet(EX_DLG_NAME, EX_DLG_TABLE, &ip_row, &ip_col); TEST_CALL_REPORT("ProUITableFocusCellGet()", "ProTestUITableEditActivateCell()", status, status != PRO_TK_NO_ERROR); if(status == PRO_TK_NO_ERROR) { status = ProUITableCellLabelGet(EX_DLG_NAME, EX_DLG_TABLE, ip_row, ip_col, &label); TEST_CALL_REPORT("ProUITableCellLabelGet()", "ProTestUITableEditActivateCell()", status, status != PRO_TK_NO_ERROR); /*--------------------------------------------------------------------*\ Create an input panel at the focus cell \*--------------------------------------------------------------------*/ ProTKSprintf(input_panel, "%s_%s", ip_row, ip_col); status = ProUITableCellComponentCopy(EX_DLG_NAME, EX_DLG_TABLE, ip_row, ip_col, EX_DLG_NAME, EX_DLG_IP, input_panel); TEST_CALL_REPORT("ProUITableCellComponentCopy()", "ProTestUITableEditActivateCell()", status, status != PRO_TK_NO_ERROR); if(status == PRO_TK_NO_ERROR) { /*--------------------------------------------------------------------*\ Setup the properties of the input panel \*--------------------------------------------------------------------*/ ProUITableColumnWidthGet(EX_DLG_NAME, EX_DLG_TABLE, ip_col, &width); ProUIInputpanelColumnsSet(EX_DLG_NAME, input_panel, width); ProUIInputpanelEnable(EX_DLG_NAME, input_panel); ProUIInputpanelShow(EX_DLG_NAME, input_panel); ProUIInputpanelValueSet(EX_DLG_NAME, input_panel, label); ProUIInputpanelFocusoutActionSet(EX_DLG_NAME, input_panel, (ProUIAction)ProTestUITableEditLoseIPfocus, NULL); ProUIInputpanelActivateActionSet(EX_DLG_NAME, input_panel, (ProUIAction)ProTestUITableEditLoseIPfocus, NULL); ProUIDialogFocusSet(EX_DLG_NAME, input_panel); } else { ProStringFree(ip_row); ProStringFree(ip_col); } ProWstringFree(label); } } /*====================================================================*\ FUNCTION: UserUITableEditExample PURPOSE: Example which demonstrates UI Table usage. The user can add and remove rows and edit cells. \*====================================================================*/ int ProTestUITableEditExample() { ProError status; /*--------------------------------------------------------------------*\ Load the dialog from the resource file \*--------------------------------------------------------------------*/ status = ProUIDialogCreate(EX_DLG_NAME, EX_DLG_RES_FILE); TEST_CALL_REPORT("ProUIDialogCreate()", "ProTestUITableEditExample()", status, status != PRO_TK_NO_ERROR); if(status != PRO_TK_NO_ERROR) return (status); row_number = 0; /*--------------------------------------------------------------------*\ Set action function for buttons \*--------------------------------------------------------------------*/ status = ProUIPushbuttonActivateActionSet(EX_DLG_NAME, EX_DLG_ADD, (ProUIAction)ProTestUITableEditAddAction, NULL); TEST_CALL_REPORT("ProUIPushbuttonActivateActionSet()", "ProTestUITableEditExample()", status, status != PRO_TK_NO_ERROR); status = ProUIPushbuttonActivateActionSet(EX_DLG_NAME, EX_DLG_REMOVE, (ProUIAction)ProTestUITableEditRemoveAction, NULL); TEST_CALL_REPORT("ProUIPushbuttonActivateActionSet()", "ProTestUITableEditExample()", status, status != PRO_TK_NO_ERROR); status = ProUIPushbuttonActivateActionSet(EX_DLG_NAME, EX_DLG_UP, (ProUIAction)ProTestUITableEditUpAction, NULL); TEST_CALL_REPORT("ProUIPushbuttonActivateActionSet()", "ProTestUITableEditExample()", status, status != PRO_TK_NO_ERROR); status = ProUIPushbuttonActivateActionSet(EX_DLG_NAME, EX_DLG_DOWN, (ProUIAction)ProTestUITableEditDownAction, NULL); TEST_CALL_REPORT("ProUIPushbuttonActivateActionSet()", "ProTestUITableEditExample()", status, status != PRO_TK_NO_ERROR); status = ProUIPushbuttonActivateActionSet(EX_DLG_NAME, EX_DLG_CLOSE, (ProUIAction)ProTestUITableEditCloseAction, NULL); TEST_CALL_REPORT("ProUIPushbuttonActivateActionSet()", "ProTestUITableEditExample()", status, status != PRO_TK_NO_ERROR); status = ProUIDialogCloseActionSet(EX_DLG_NAME, (ProUIAction)ProTestUITableEditCloseAction, NULL); TEST_CALL_REPORT("ProUIDialogCloseActionSet()", "ProTestUITableEditExample()", status, status != PRO_TK_NO_ERROR); /*--------------------------------------------------------------------*\ Set action function for editing cells \*--------------------------------------------------------------------*/ status = ProUITableSelectActionSet(EX_DLG_NAME, EX_DLG_TABLE, (ProUIAction)ProTestUITableEditActivateCell, NULL); TEST_CALL_REPORT("ProUITableSelectActionSet()", "ProTestUITableEditExample()", status, status != PRO_TK_NO_ERROR); /*--------------------------------------------------------------------*\ Display and activate the dialog \*--------------------------------------------------------------------*/ status = ProUIDialogActivate(EX_DLG_NAME, NULL); TEST_CALL_REPORT("ProUIDialogActivate()", "ProTestUITableEditExample()", status, status != PRO_TK_NO_ERROR); /*--------------------------------------------------------------------*\ Remove the dialog from memory \*--------------------------------------------------------------------*/ status = ProUIDialogDestroy(EX_DLG_NAME); TEST_CALL_REPORT("ProUIDialogDestroy()", "ProTestUITableEditExample()", status, status != PRO_TK_NO_ERROR); return(1); }