Hi, I add to CWM module CWMTable. This unify using table renderer of entries and its standard manipulation operations. At first Why you should start using it? Because now each yast module which uses table have different behavior and it is confusing to users. Also adding new features for all tables is not easy. E.g. I find confusing why in yast2-bootloader after double-click on cell it start edit dialog and in yast2-sudo it doesn't. Also handle up/down buttons is very incosistent (sometimes it is auto disabled, sometimes not). So what features provide this little module? - optional add/delete buttons - optional edit button - optional up/down button - optional additional button - each button have separated handle function except up/down which have one - up/down is automatic enabled/disabled on first/last cell (this doesn't work as good as expect and need little debugging) - up/down handle functions gets also index and is ensured that is called only if possible move item up/down (this prevents bugs) - double click on cell call edit handler (if enabled) - wrapper for whole table enable/disable (with all buttons) - better readable code - same ncurses shortcut for Add,Edit,Delete F3-F5 disadvantage - can place only one unified table in dialog because it has hard-coded id TODO: - context menu also for additional button - allows another widget instead of additional widget - document it Example usage is attached. I welcome any comments. Josef Reidinger { import "CWM"; import "CWMTable"; import "Popup"; import "Wizard"; list<string> items = []; integer counter =0; void redraw_table(list<string> values){ list<term> table_items = maplist(string s, values, { return `item(`id(s),s); }); UI::ChangeWidget(`id(`_tw_table),`Items, table_items); } symbol add_handle(string key, map event){ counter = counter +1; items = add(items,sformat("item %1",counter)); redraw_table(items); return nil; } symbol edit_handle(string key, map event){ Popup::Warning("edit"); return nil; } symbol delete_handle(string key, map event){ Popup::Warning("delete"); return nil; } symbol updown_handle(string key, map event, boolean up, integer index){ integer second = up ? (index-1):(index+1); y2milestone("updown with up %1 and index %2 and second %3",up,index,second); string value = items[second]:""; items[second] = items[index]:""; items[index] = value; redraw_table(items); return nil; } symbol custom_handle(string key, map event){ Popup::Warning("Custom button"); return nil; } map<string,any> table = CWMTable::CreateTableDescr( $[ "add_delete_buttons" : true, "edit_button" : true, "up_down_buttons" : true, "custom_button" : true, "custom_button_name" : "Additional button", "custom_handle" : custom_handle, "header" : `header("id"), "edit":edit_handle, "delete":delete_handle, "add" : add_handle, "updown" : updown_handle, ], $[ "help" : "", ] ); Wizard::CreateDialog(); symbol ret = CWM::ShowAndRun($[ "widget_names" : ["table"], "widget_descr" : $[ "table" : table], "contents" : `VBox("table"), "caption" : "test" ]); }