home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2007 January, February, March & April
/
Chip-Cover-CD-2007-02.iso
/
boot
/
i386
/
root
/
usr
/
share
/
YaST2
/
modules
/
TablePopup.ycp
< prev
next >
Wrap
Text File
|
2006-11-29
|
28KB
|
914 lines
/**
* File: modules/TablePopup.ycp
* Package: Table/Popup dialogs backend
* Summary: Routines for Table/Popup interface
* Authors: Jiri Srain <jsrain@suse.cz>
*
* $Id: TablePopup.ycp 26946 2006-01-11 12:47:46Z jsrain $
*
*/
{
module "TablePopup";
textdomain "base";
import "CWM";
import "Label";
import "Mode";
import "Report";
// variables
/**
* Item, that is the last selected
* Used to decide if selected item should be moved up or down if separator
* clicked
* Loss of contents is no problem
*/
any previous_selected_item = nil;
// local functions
/**
* Get list of IDs of entries of the table
* @param descr map table description map
* @return list of IDs of the table
*/
define list getIdList (map<string, any> descr) ``{
list(map) toEval = (list(map)) (descr["ids"]:nil);
if (toEval != nil)
{
return toEval (descr);
}
return [];
}
/**
* Validate table options specifyign attributesA
* @param attr a map of table attributes
* @return boolean true if validation succeeded
*/
define boolean ValidateTableAttr (map<string,any> attr) {
map<string,string> types = $[
"add_delete_buttons" : "boolean",
"edit_button" : "boolean",
"changed_column" : "boolean",
"up_down_buttons" : "boolean",
"unique_keys" : "boolean",
];
boolean ret = true;
foreach (string k, any v, attr, {
string type = (string)types[k]:nil;
if (type == nil)
{
y2error ("Unknown attribute %1", k);
ret = false;
}
else
{
ret = CWM::ValidateBasicType (v, type) && ret;
}
});
return ret;
}
/**
* Validate type of entry of the option description map
* Also checks option description maps if present
* @param key string key of the map entry
* @param value any value of the map entry
* @param widget any name of the widget/option
* @param popup boolean true if is option of a popup
* @return boolean true if validation succeeded
*/
define boolean ValidateValueType (string key, any value, string widget, boolean popup) {
boolean success = true;
if (popup)
{
if (key == "init")
success = is (value, void(any,string));
else if (key == "handle")
success = is (value, void(any,string,map))
|| is (value, symbol);
else if (key == "store")
success = is (value, void(any,string));
else if (key == "cleanup")
success = is (value, void(any,string));
else if (key == "validate_function")
success = is (value, boolean(any,string,map));
else if (key == "optional")
success = is (value, boolean);
else if (key == "label_func")
success = is (value, string(any,string));
else
return CWM::ValidateValueType (key, value, widget);
}
else if (key == "id2key")
success = is (value, string(map,any));
else if (key == "ids")
success = is (value, list(map));
else if (key == "option_delete")
success = is (value, boolean(any,string));
else if (key == "summary")
success = is (value, string(any,string));
else if (key == "label_func")
success = is (value, string(any,string));
else if (key == "option_move")
success = is (value, any(any, string, symbol));
else if (key == "options")
success = is (value, map<string,any>);
else if (key == "add_items")
success = is (value, list);
if (! success)
y2error ("Wrong type of option %1 in description map of %2",
key, widget);
}
/**
* Validate the table description
* @param descr a map containing the table description
* @return boolean true if validation succeeded
*/
define boolean ValidateTableDescr (string key, map<string,any> descr) {
boolean ret = true;
foreach (string k, any v, descr, {
ret = ValidateValueType (k, v, key, false) && ret;
});
map<string,any> options = descr["options"]:$[];
foreach (string w_key, any v, options, {
map<string,map<string,any> > des = (map<string,map<string,any> >)v;
foreach (string group, map<string,any> d, des, {
if (group != "table" && group != "popup")
{
y2error ("Unknown entry in option %1: %2", w_key, group);
}
foreach (string key, any value, d, {
ValidateValueType (key, value, w_key, true);
});
});
});
return ret;
}
/**
* Get option key from the option id
* global only because of testsuites
* @param descr map description of the table
* @param opt_id any id of the option
* @return string option key
*/
global define string id2key (map<string, any> descr, any opt_id) ``{
if (opt_id != nil && is (opt_id, string) && size ((string)opt_id) >= 7
&& substring ((string)opt_id, 0, 7) == "____sep")
{
return "____sep";
}
string (map, any) toEval = (string(map, any)) (descr["id2key"]:nil);
if (toEval != nil)
return toEval (descr, opt_id);
else
return (string)opt_id;
}
/**
* Get option description map from the key
* global only because of testsuites
* @param descr map description of the table
* @param opt_key string option key
* @return map option description map
*/
global define map<string, any> key2descr (map<string, any> descr, string opt_key) ``{
map options = (map)(descr["options"]:$[]);
map<string, any> opt_descr = (map<string, any>)(options[opt_key]:$[]);
// a copy wanted here
opt_descr = (map<string, any>) add (opt_descr, "_cwm_key", opt_key);
// a deep copy
opt_descr["table"] = add ((map)(opt_descr["table"]:$[]), "_cwm_key", opt_key);
opt_descr["popup"] = add ((map)(opt_descr["popup"]:$[]), "_cwm_key", opt_key);
if (opt_descr["popup", "label"]:nil == nil)
opt_descr["popup", "label"] = opt_descr["table", "label"]:opt_key;
return opt_descr;
}
/**
* Update the option description map in order to contain handlers of
* all needed functions
* global only because of testsuites
* @param opt_descr map option description map
* @param fallbacks map of fallback handlers
* @return map updated option description map
*/
global define map<string, any> updateOptionMap (map<string, any> opt_descr, map fallbacks) ``{
// ensure that the submaps exist
opt_descr["table"] = opt_descr["table"]:$[];
opt_descr["popup"] = opt_descr["popup"]:$[];
foreach (string k, ["init", "store" ], ``{
if (! haskey (opt_descr["popup"]:$[], k) && haskey (fallbacks, k))
opt_descr["popup", k] = fallbacks[k]:nil;
});
if (! haskey (opt_descr["table"]:$[], "summary")
&& haskey (fallbacks, "summary"))
{
opt_descr["table", "summary"] = fallbacks["summary"]:nil;
}
if (! haskey (opt_descr["table"]:$[], "label_func")
&& haskey (fallbacks, "label_func"))
{
opt_descr["table", "label_func"] = fallbacks["label_func"]:nil;
}
if (! haskey (opt_descr["table"]:$[], "changed")
&& haskey (fallbacks, "changed"))
{
opt_descr["table", "changed"] = fallbacks["changed"]:nil;
}
if (opt_descr["_cwm_key"]:"" == "____sep"
&& opt_descr["table", "label"]:"" == "")
{
opt_descr["table", "label"] = "--------------------";
}
return opt_descr;
}
/**
* Get the left column of the table
* @param opt_id any option id
* @param opt_descr map option description map
* @return string text to the table
*/
define string tableEntryKey (any opt_id, map<string, any> opt_descr) ``{
string opt_key = opt_descr["_cwm_key"]:"";
string label = opt_descr["table", "label"]:sformat ("%1", opt_key);
if (haskey (opt_descr["table"]:$[], "label_func"))
{
string(any,string) label_func = (string(any,string))
opt_descr["table", "label_func"]:nil;
label = label_func (opt_id, opt_key);
}
return label;
}
/**
* Get value to the table entry
* @param opt_id any option id
* @param opt_descr map option description map
* @return string text to the table
*/
define string tableEntryValue (any opt_id, map<string, any> opt_descr) ``{
string opt_key = (string)(opt_descr["_cwm_key"]:"");
string (any, string) toEval = (string(any, string)) (opt_descr["table", "summary"]:nil);
if (toEval != nil)
{
return toEval (opt_id, opt_key);
}
return "";
}
/**
* Realize if table entry was changed
* @param opt_id any option id
* @param opt_descr map option description map
* @return boolean true if was changed
*/
global define boolean tableEntryChanged (any opt_id, map<string, any> opt_descr) ``{
string opt_key = (string)(opt_descr["_cwm_key"]:"");
boolean (any, string) toEval = (boolean(any, string)) (opt_descr["table", "changed"]:nil);
if (toEval != nil)
{
return toEval (opt_id, opt_key);
}
return false;
}
/**
* Delete an item from the table
* Just a wrapper for module-specific function
* @param opt_id any option id
* @param descr map table description map
* @return boolean true if was really deleted
*/
global define boolean deleteTableItem (any opt_id, map<string, any> descr) ``{
boolean(any, string) toEval = (boolean(any,string)) (descr["option_delete"]:nil);
if (nil != toEval)
{
string opt_key = id2key (descr, opt_id);
return toEval (opt_id, opt_key);
}
return false;
}
/**
* Enable or disable the Delete and up/down buttons
* @param descr map table description map
* @param opt_descr map selected option description map
*/
global define void updateButtons (map<string,any> descr, map<string,any> opt_descr) ``{
if (descr["_cwm_attrib", "add_delete_buttons"]:true)
{
UI::ChangeWidget (`id (`_tp_delete), `Enabled,
opt_descr["table", "optional"]:true);
}
if (descr["_cwm_attrib", "edit_button"]:true)
{
UI::ChangeWidget (`id (`_tp_edit), `Enabled,
! opt_descr["table", "immutable"]:false);
}
if (descr["_cwm_attrib", "up_down_buttons"]:false)
{
UI::ChangeWidget (`id (`_tp_up), `Enabled,
opt_descr["table", "ordering"]:true);
UI::ChangeWidget (`id (`_tp_down), `Enabled,
opt_descr["table", "ordering"]:true);
}
}
/**
* Move table item up or down
* Just a wrapper for module-specific function
* @param opt_id any option id
* @param descr map table description map
* @param dir symbol `up or `down (according to the button user pressed)
* @return any new id of selected option, nil if wasn't reordered
*/
define any moveTableItem (any opt_id, map<string, any> descr, symbol dir) ``{
any(any, string, symbol) toEval = (any(any, string, symbol)) (descr["option_move"]:nil);
if (nil != toEval)
{
return toEval (opt_id, id2key (descr, opt_id), dir);
}
return nil;
}
/**
* Redraw completely the table
* @param descr map description map of the whole table
* @param update_buttons boolean true if buttons status (enabled/disabled)
* should be updated according to currently selected item
*/
define void TableRedraw (map<string, any> descr, boolean update_buttons) ``{
list id_list = getIdList (descr);
if (previous_selected_item == nil)
{
previous_selected_item = id_list[0]:nil;
}
list<term> entries = maplist (any opt_id, id_list, ``{
string opt_val = "";
string val = "";
boolean opt_changed = false;
string opt_key = id2key (descr, opt_id);
map<string, any> opt_descr = key2descr (descr, opt_key);
opt_descr = updateOptionMap (opt_descr, descr["fallback"]:$[]);
string label = tableEntryKey (opt_id, opt_descr);
if (opt_key != "____sep")
{
opt_val = tableEntryValue (opt_id, opt_descr);
opt_changed = tableEntryChanged (opt_id, opt_descr);
}
if (update_buttons && opt_id == previous_selected_item)
updateButtons (descr, opt_descr);
if (descr["_cwm_attrib", "changed_column"]:false)
{
return (`item (
`id (opt_id),
opt_changed ? "*" : "",
label,
sformat ("%1", opt_val)));
}
return (`item (
`id (opt_id),
label,
sformat ("%1", opt_val)));
});
UI::ChangeWidget (`id (`_tp_table), `Items, entries);
UI::SetFocus (`id (`_tp_table));
}
/**
* Displaye popup for option to edit choosing
* @param possible a list of strings or items of all possible options
* to provide
* @param editable boolean true means that it is possible to add non-listed
* options
* @param descr a map table description map
* @return string option identifies, nil if canceled
*/
global define string askForNewOption (list possible, boolean editable, map<string,any> descr) ``{
boolean do_sort = ! descr["add_items_keep_order"]:false;
if (do_sort)
possible = sort (possible);
map<string,string> val2key = $[];
map<string,boolean> known_keys = $[];
possible = maplist (any p, possible, ``{
if (!is (p, string)) continue;
map<string, any> opt_descr = key2descr (descr, (string)p);
string label = opt_descr["table", "label"]:sformat ("%1", p);
known_keys[(string)p] = true;
val2key[label] = (string)p;
return `item (`id (p), label);
});
term widget = `HBox (`HSpacing (1), `VBox (
`VSpacing (1),
`ComboBox (`id (`optname), editable ? `opt (`editable) : `opt (),
// combobox header
_("&Selected Option"), possible),
`VSpacing (1),
`HBox (
`HStretch (),
`PushButton (`id (`_tp_ok), `opt (`key_F10, `default),
Label::OKButton ()),
`HSpacing (1),
`PushButton (`id (`_tp_cancel), `opt (`key_F9),
Label::CancelButton ()),
`HStretch ()
),
`VSpacing (1)
), `HSpacing (1));
UI::OpenDialog (widget);
UI::SetFocus (`id (`optname));
any ret = nil;
string option = nil;
while (ret != `_tp_ok && ret != `_tp_cancel)
{
ret = UI::UserInput ();
if (ret == `_tp_ok)
{
option = (string)(UI::QueryWidget (`id (`optname), `Value));
}
}
UI::CloseDialog ();
if (ret == `_tp_cancel)
return nil;
if (known_keys[option]:false)
return option;
return val2key[option]:option;
}
/**
* Display and handle the popup for option
* @param option map one option description map that is modified in order
* to contain the option name and more percise option identification
* @return symbol `_tp_ok or `_tp_cancel
*/
global define symbol singleOptionEditPopup (map<string,any> option)``{
string opt_key = option["_cwm_key"]:"";
any opt_id = option["_cwm_id"]:nil;
string label = sformat ("%1", option["table", "label"]:opt_key);
term header = `HBox (
// heading / label
`Heading (_("Current Option: ")),
`Label (label),
`HStretch ()
);
map<string, any> popup_descr = CWM::prepareWidget (option["popup"]:$[]);
term widget = (term)(popup_descr["widget"]:`VBox ());
string help = (string)(popup_descr["help"]:"");
if (help == nil)
{
help = "";
}
term contents = `HBox (`HSpacing (1), `VBox (
`VSpacing (1),
`Left (header),
`VSpacing (1),
help == "" ? `VSpacing (0)
: `Left (`Label (help)),
`VSpacing (help == "" ? 0 : 1),
`Left (`ReplacePoint(`id (`value_rp), widget)),
`VSpacing (1),
`HBox (
`HStretch(),
`PushButton (`id (`_tp_ok), `opt (`key_F10, `default),
Label::OKButton ()),
`HSpacing (1),
`PushButton (`id (`_tp_cancel), `opt (`key_F9),
Label::CancelButton ()),
`HStretch ()
),
`VSpacing (1)
), `HSpacing (1));
UI::OpenDialog (contents);
if (popup_descr["init"]:nil != nil)
{
void(any, string) toEval = (void(any, string)) (popup_descr["init"]:nil);
toEval (opt_id, opt_key);
}
any ret = nil;
map<string, any> event_descr = $[];
while (ret != `_tp_ok && ret != `_tp_cancel)
{
map<string, any> event_descr = (map<string, any>)(UI::WaitForEvent ());
if (Mode::test ())
event_descr = $[ "ID" : `_tp_ok];
ret = event_descr["ID"]:nil;
if (popup_descr["handle"]:nil != nil)
{
void(any, string, map) toEval = (void(any, string, map)) (popup_descr["handle"]:nil);
toEval (opt_id, opt_key, event_descr);
}
if (ret == `_tp_ok)
{
symbol val_type = (symbol) (popup_descr["validate_type"]:nil);
if (val_type == `function)
{
boolean (any, string, map) toEval
= (boolean(any, string, map)) (popup_descr["validate_function"]:nil);
if (toEval != nil)
{
if (! toEval (opt_id, opt_key, event_descr))
{
ret = nil;
}
}
}
else if (! CWM::validateWidget (popup_descr, event_descr,
opt_key))
{
ret = nil;
}
}
}
if (ret == `_tp_ok && popup_descr["store"]:nil != nil)
{
void(any, string) toEval = (void(any, string)) (popup_descr["store"]:nil);
toEval (opt_id, opt_key);
}
UI::CloseDialog ();
return (symbol)ret;
}
// functions
/**
* Disable whole table
* @param descr map table widget description map
*/
global define void DisableTable (map<string,any> descr) ``{
UI::ChangeWidget (`id (`_tp_table), `Enabled, false);
if (descr["_cwm_attrib", "edit_button"]:true)
{
UI::ChangeWidget (`id (`_tp_edit), `Enabled, false);
}
if (descr["_cwm_attrib", "add_delete_buttons"]:true)
{
UI::ChangeWidget (`id (`_tp_delete), `Enabled, false);
UI::ChangeWidget (`id (`_tp_add), `Enabled, false);
}
if (descr["_cwm_attrib", "up_down_buttons"]:false)
{
UI::ChangeWidget (`id (`_tp_up), `Enabled, false);
UI::ChangeWidget (`id (`_tp_down), `Enabled, false);
}
}
/**
* Enable whole table (except buttons that should be grayed according to
* currently selected table row
* @param descr map table widget description map
*/
global define void EnableTable (map<string, any> descr) ``{
UI::ChangeWidget (`id (`_tp_table), `Enabled, true);
if (descr["_cwm_attrib", "edit_button"]:true)
{
UI::ChangeWidget (`id (`_tp_edit), `Enabled, true);
}
if (descr["_cwm_attrib", "add_delete_buttons"]:true)
{
UI::ChangeWidget (`id (`_tp_add), `Enabled, false);
}
any opt_id = UI::QueryWidget (`id (`_tp_table), `CurrentItem);
string opt_key = id2key (descr, opt_id);
map<string,any> option_map = key2descr (descr, opt_key);
updateButtons (descr, option_map);
}
/**
* Initialize the displayed table
* @param descr map description map of the whole table
* @param key table widget key
*/
global define void TableInit (map<string, any> descr, string key) ``{
previous_selected_item = nil;
descr["_cwm_key"] = key;
TableRedraw (descr, true);
}
/**
* Handle the event that happened on the table
* @param descr map description of the table
* @param key table widget key
* @param event_descr map event to handle
* @return symbol modified event if needed
*/
global define symbol TableHandle (map<string, any> descr, string key, map event_descr) ``{
any event_id = event_descr["ID"]:nil;
UI::SetFocus (`id (`_tp_table));
if (event_id == `_tp_table)
{
if (event_descr["EventReason"]:"" == "Activated"
&& event_descr["EventType"]:"" == "WidgetEvent"
&& UI::WidgetExists (`id (`_tp_edit)))
{
event_id = `_tp_edit;
}
}
if (event_id == `_tp_edit || event_id == `_tp_add)
{
string opt_key = nil;
any opt_id = nil;
if (event_id == `_tp_add)
{
boolean add_unlisted = descr["add_unlisted"]:true;
if (! add_unlisted && size (descr["add_items"]:[]) == 1)
{
opt_key = descr["add_items", 0]:"";
}
else
{
list<string> add_opts = descr["add_items"]:[];
list ids = getIdList (descr);
list<string> present = maplist (any i, ids, ``(
id2key (descr, i)
));
if (! descr["_cwm_attrib", "unique_keys"]:false)
{
present = filter (string i, present, ``{
map opt_descr = key2descr (descr, i);
return ! opt_descr["table", "optional"]:true;
});
}
add_opts = filter (string o, add_opts, ``(
! contains (present, o)
));
boolean selected = false;
while (! selected)
{
opt_key = askForNewOption (add_opts, add_unlisted,
descr);
if (opt_key == nil)
return nil;
if (contains (present, opt_key))
Report::Error (
// error report
_("The selected option is already present."));
else
selected = true;
}
}
if (opt_key == nil)
return nil;
}
else if (event_id == `_tp_edit)
{
opt_id = UI::QueryWidget (`id (`_tp_table), `CurrentItem);
opt_key = id2key (descr, opt_id);
}
map<string, any> option_map = key2descr (descr, opt_key);
any toEval = option_map["table", "handle"]:nil;
if (toEval != nil)
{
// if (is (toEval, symbol))
if (! is (toEval, symbol(any, string, map)))
{
symbol ret = (symbol)toEval;
return ret;
}
else
{
symbol(any, string, map) toEval_c
= (symbol(any, string, map)) (option_map["table", "handle"]:nil);
symbol ret = toEval_c (opt_id, opt_key, event_descr);
if (ret != `_tp_normal)
return ret;
}
}
option_map["_cwm_id"] = opt_id;
option_map["_cwm_key"] = opt_key;
// add generic handlers if needed
option_map = updateOptionMap (option_map, (map<string, any>) (descr["fallback"]:$[]));
symbol ret = singleOptionEditPopup (option_map);
if (ret == `_tp_ok)
{
if (event_id == `_tp_add)
{
TableInit (descr, key);
}
else if (event_id == `_tp_edit)
{
integer column
= descr["_cwm_attrib", "changed_column"]:false
? 2
: 1;
UI::ChangeWidget (`id (`_tp_table),
`Item (opt_id, column),
tableEntryValue (opt_id, option_map));
// also redraw the key field as it can be changed
column = column - 1;
UI::ChangeWidget (`id (`_tp_table),
`Item (opt_id, column),
tableEntryKey (opt_id, option_map));
if (descr["_cwm_attrib", "changed_column"]:false)
{
UI::ChangeWidget (`id (`_tp_table),
`Item (opt_id, 0),
tableEntryChanged (opt_id, option_map) ? "*" : "");
}
}
}
}
else if (event_id == `_tp_delete)
{
any opt_id = UI::QueryWidget (`id (`_tp_table), `CurrentItem);
if (deleteTableItem (opt_id, descr))
TableInit (descr, key);
}
else if (event_id == `_tp_table)
{
any opt_id = UI::QueryWidget (`id (`_tp_table), `CurrentItem);
any key = id2key (descr, opt_id);
if (key == "____sep")
{
list id_list = getIdList (descr);
integer previous_index = 0;
if (previous_selected_item != nil)
{
previous_index = -1;
find (any e, id_list, ``{
previous_index = previous_index + 1;
return e == previous_selected_item;
});
}
integer current_index = -1;
find (any e, id_list, ``{
current_index = current_index + 1;
return e == opt_id;
});
integer step = 0;
if (current_index == 0)
step = 1;
else if (current_index + 1 == size (id_list))
step = -1;
else if (current_index >= previous_index)
step = 1;
else
step = -1;
integer new_index = current_index + step;
opt_id = id_list[new_index]:nil;
key = id2key (descr, opt_id);
UI::ChangeWidget (`id (`_tp_table), `CurrentItem, opt_id);
}
previous_selected_item = opt_id;
map<string,any> opt_descr
= key2descr (descr, id2key (descr, opt_id));
updateButtons (descr, opt_descr);
}
else if (event_id == `_tp_up || event_id == `_tp_down)
{
any opt_id = UI::QueryWidget (`id (`_tp_table), `CurrentItem);
opt_id = moveTableItem (opt_id, descr, event_id == `_tp_up
? `up
: `down);
if (nil != opt_id)
{
TableRedraw (descr, false);
UI::ChangeWidget (`id (`_tp_table), `CurrentItem, opt_id);
map<string,any> opt_descr
= key2descr (descr, id2key (descr, opt_id));
updateButtons (descr, opt_descr);
}
}
return nil;
}
/**
* Wrapper for TableInit using CWM::GetProcessedWidget () for getting
* widget description map
* @param key any widget key
*/
global define void TableInitWrapper (string key) ``{
TableInit (CWM::GetProcessedWidget (), key);
}
/**
* Wrapper for TableHandle using CWM::GetProcessedWidget () for getting
* widget description map
* @param key any widget key
* @param event_descr map event description map
* @return symbol return value for wizard sequencer or nil
*/
global define symbol TableHandleWrapper (string key, map event_descr) ``{
return TableHandle(CWM::GetProcessedWidget (), key, event_descr);
}
/**
* Get the map with the table widget
* @param attrib map table attributes
* @param widget_descr map widget description map of the table, will be
* unioned with the generated map
* @return map table widget
*/
global define map<string,any> CreateTableDescr (map<string,any> attrib, map<string,any> widget_descr) ``{
ValidateTableAttr (attrib);
term add_button = attrib["add_delete_buttons"]:true
? `PushButton (`id (`_tp_add), `opt (`key_F3), Label::AddButton ())
: `HSpacing (0);
term edit_button = attrib["edit_button"]:true
? `PushButton (`id (`_tp_edit), `opt (`key_F4), Label::EditButton ())
: `HSpacing (0);
term delete_button = attrib["add_delete_buttons"]:true
? `PushButton (`id (`_tp_delete), `opt (`key_F5), Label::DeleteButton ())
: `HSpacing (0);
term table_header = attrib["changed_column"]:false
? `header (
// table header, shortcut for changed, keep very short
_("Ch."),
// table header
_("Option"),
// table header
_("Value"))
: `header (
// table header
_("Option"),
// table header
_("Value"));
term replace_point = `ReplacePoint (`id (`_tp_table_repl), `HSpacing (0));
// help 1/4
string help = _("<p><b><big>Editing the Settings</big></b><br>
To edit the settings, choose the appropriate
entry of the table then click <b>Edit</b>.</p>");
if (attrib["add_delete_buttons"]:true)
// help 2/4, optional
help = help + _("<p>To add a new option, click <b>Add</b>. To remove
an option, select it and click <b>Delete</b>.</p>");
if (attrib["changed_column"]:false)
// help 3/4, optional
help = help + _("<P>The <B>Ch.</B> column of the table shows
whether the option was changed.</P>");
if (attrib["up_down_buttons"]:false)
// help 4/4, optional
help = help + _("<p>To reorder the options, select an option
and use <b>Up</b> and <b>Down</b> to move it up or down
in the list.</p>");
term up_down = attrib["up_down_buttons"]:false
? `VBox (
`VStretch (),
// push button
`PushButton (`id (`_tp_up), _("&Up")),
// push button
`PushButton (`id (`_tp_down), _("&Down")),
`VStretch ()
)
: `HSpacing (0);
map<string,any> ret = (map<string,any>)union ($[
"custom_widget" : (`HBox (`HSpacing (2), `VBox (
`HBox (
`Table (`id (`_tp_table),
`opt (`immediate, `notify, `keepSorting),
table_header,
[]),
up_down
),
`HBox (
add_button,
edit_button,
delete_button,
`HStretch (),
replace_point
)
), `HSpacing (2))),
"_cwm_attrib" : attrib,
"widget" : `custom,
"help" : help,
"_cwm_do_validate" : ValidateTableDescr,
], widget_descr);
if (! haskey (ret, "init"))
{
ret["init"] = TablePopup::TableInitWrapper;
}
if (! haskey (ret, "handle"))
{
ret["handle"] = TablePopup::TableHandleWrapper;
}
return ret;
}
}