ACC SHELL
/**
* File: include/sysconfig/complex.ycp
* Package: Configuration of sysconfig
* Summary: Dialogs definitions
* Authors: Ladislav Slezak <lslezak@suse.cz>
*
* $Id: complex.ycp 48330 2008-06-16 12:26:13Z lslezak $
*/
{
textdomain "sysconfig";
import "Wizard";
import "Sysconfig";
import "Mode";
import "String";
import "Popup";
import "Label";
include "sysconfig/helps.ycp";
include "sysconfig/routines.ycp";
include "sysconfig/dialogs.ycp";
/**
* current selected variable in the tree widget
*/
string selected_variable = "";
string empty_string = " ";
empty_string = empty_string + empty_string;
empty_string = empty_string + empty_string;
/**
* Return a modification status
* @return true if data was modified
*/
define boolean Modified() ``{
return Sysconfig::Modified();
}
/**
* Read settings dialog
* @return `abort if aborted and `next otherwise
*/
define symbol ReadDialog() ``{
Wizard::SetHelpText(HELPS["read"]:"");
Sysconfig::Read();
return `next;
}
/**
* Write settings dialog
* @return `abort if aborted and `next otherwise
*/
define symbol WriteDialog() ``{
Wizard::SetHelpText(HELPS["write"]:"");
boolean ret = true;
if (Sysconfig::Modified() == true)
{
y2milestone("Changes will be written.");
// write and activate changes
if (Sysconfig::Write() == false)
{
// error popup message
Popup::Error(_("An error occurred while saving and activating the changes."));
}
else
{
sleep(500); // small delay, user should see 100% progress
}
//Popup::Message(_("The changes were saved and successfully activated."));
}
return `next;
}
/**
* Get string representation of type definition. Used at richtext description.
* @param description Variable description
* @param richtext result is rich/plain text
* @return string Textual description of the type
*/
define string possible_values(map description, boolean richtext) ``{
string ret = "";
string type = description["Type"]:"";
if (type == "")
{
return ret;
}
else if (type == "yesno")
{
ret = ret + "yes,no";
}
else if (type == "boolean")
{
ret = "true,false";
}
else if (regexpmatch(type, "^list\\(.*\\)"))
{
list<string> spaces = [];
list<string> values = String::ParseOptions(regexpsub(type, "^list\\((.*)\\)", "\\1"), Sysconfig::parse_param);
foreach(string value, values, ``{
spaces = add(spaces, mergestring(splitstring(value, " "), " "));
}
);
ret = mergestring(spaces, ", ");
}
else if (regexpmatch(type, "^string\\(.*\\)"))
{
list<string> spaces = [];
list<string> values = String::ParseOptions(regexpsub(type, "^string\\((.*)\\)", "\\1"), Sysconfig::parse_param);
foreach(string value, values, ``{
spaces = add(spaces, mergestring(splitstring(value, " "), " "));
}
);
// suffix added to the allowed (predefined) values
ret = mergestring(spaces, ", ") + (richtext?" <I>":" ") + _("or any value") + (richtext?"</I>":"");
}
else if (regexpmatch(type, "^regexp\\(.*\\)"))
{
string regex = regexpsub(type, "^regexp\\((.*)\\)", "\\1");
// Translation: description of possible values, regular expression string is added after the text
ret = (richtext?"<I>":"") + _("Value Matching Regular Expression:") + (richtext?"</I>":"") + regex;
}
else if (type == "integer")
{
// allowed value description
ret = (richtext?"<I>":"") + _("Any integer value") + (richtext?"</I>":"");
}
else if (regexpmatch(type, "^integer\\(.*:.*\\)"))
{
string min = regexpsub(type, "^integer\\((.*):.*\\)", "\\1");
string max = regexpsub(type, "^integer\\(.*:(.*)\\)", "\\1");
y2milestone("min: %1, max: %2", min, max);
if (max == "" && min != "")
{
// allowed value description
ret = (richtext?"<I>":"") + sformat(_("Integer value greater or equal to %1"), min) + (richtext?"</I>":"");
}
else if (min == "" && max != "")
{
// allowed value description
ret = (richtext?"<I>":"") + sformat(_("Integer value less or equal to %1"), max) + (richtext?"</I>":"");
}
else
{
// Translation: allowed value description, %1 is minimum value, %2 is maximum integer value
ret = (richtext?"<I>":"") + sformat(_("Any integer value from %1 to %2"), min, max) + (richtext?"</I>":"");
}
}
else if (type == "string")
{
// allowed value description - any value is allowed
ret = (richtext?"<I>":"") + _("Any value") + (richtext?"</I>":"");
}
else if (type == "ip")
{
// allowed value description - IP adress
ret = (richtext?"<I>":"") + _("IPv4 or IPv6 address") + (richtext?"</I>":"");
}
else if (type == "ip4")
{
// allowed value description - IPv4 adress
ret = (richtext?"<I>":"") + _("IPv4 address") + (richtext?"</I>":"");
}
else if (type == "ip6")
{
// allowed value description - IPv6 adress
ret = (richtext?"<I>":"") + _("IPv6 address") + (richtext?"</I>":"");
}
else
{
y2warning("Unknown type definition: %1", type);
}
return ret;
}
/**
* Create rich text description string from description values
* @param description Description
* @param richtext if true result is rich text, if false result is plain text
* @return string Rich text string
*/
define string create_description(map<string, any> description, boolean richtext) ``{
string varname = description["name"]:"";
string file = description["file"]:"";
string default_value = (string) (description["Default"]:nil);
string comment = description["comment"]:"";
string possible_vals = possible_values(description, richtext);
string result = "";
if (file != "" && file != nil)
{
// rich text item
result = result + ((richtext) ? "<P><B>":"") + _("File: ") + ((richtext) ?"</B> ":"") + file + ((richtext) ? "</P>":"\n");
}
if (possible_vals != "" && possible_vals != nil)
{
// rich text item
result = result + ((richtext) ? "<P><B>":"") + _("Possible Values: ") + ((richtext) ?"</B> ":"") + possible_vals + ((richtext) ?"</P>":"\n");
}
if (default_value != nil && size(file) > 0)
{
// TODO: replace empty value by special text (e.g. "</I>empty</I>")
// rich text value
result = result + ((richtext) ?"<P><B>":"") + _("Default Value: ") + ((richtext) ?"</B> ":"") + default_value + ((richtext) ?"</P>":"\n");
}
// if value was modified add original value
if (haskey(description, "new_value"))
{
string original = description["value"]:"";
// quote empty value
if (original == "")
{
original = "\"\"";
}
// rich text value
result = result + ((richtext) ?"<P><B>":"") + _("Original Value: ") + ((richtext) ?"</B> ":"") + original + ((richtext) ?"</P>":"\n");
}
if (haskey(description, "actions"))
{
// display specified action command
string conf_modules = (string) (description["actions", "Cfg"]:nil);
string restart = (string) (description["actions", "Rest"]:nil);
string reload = (string) (description["actions", "Reld"]:nil);
string command = (string) (description["actions", "Cmd"]:nil);
string precommand = (string) (description["actions", "Pre"]:nil);
// check whether action is defined
if (precommand != nil && size(precommand) > 0)
{
// header in the variable description text, bash command is appended
result = result + ((richtext) ?"<P><B>":"") + _("Prepare Command: ") + ((richtext) ?"</B> ":"") + precommand + ((richtext) ?"</P>":"\n");
}
if (conf_modules != nil && size(conf_modules) > 0)
{
// parse string with options, then add them to the rich text
list<string> conf = String::ParseOptions(conf_modules, Sysconfig::parse_param);
// header in the variable description text, SuSEconfig/ULconfig module names are appended
result = result + ((richtext) ?"<P><B>":"") + _("Configuration Script: ") + ((richtext) ?"</B> ":"") + mergestring(conf, ", ") + ((richtext) ?"</P>":"\n");
}
if (reload != nil && size(reload) > 0)
{
list<string> services = String::ParseOptions(reload, Sysconfig::parse_param);
// header in the variable description text, service names (e.g. "apache") are appended
result = result + ((richtext) ?"<P><B>":"") + _("Service to Reload: ") + ((richtext) ?"</B> ":"") + mergestring(services, ", ") + ((richtext) ?"</P>":"\n");
}
if (restart != nil && size(restart) > 0)
{
list<string> services = String::ParseOptions(restart, Sysconfig::parse_param);
// header in the variable description text, service names (e.g. "apache") are appended
result = result + ((richtext) ?"<P><B>":"") + _("Service to Restart: ") + ((richtext) ?"</B> ":"") + mergestring(services, ", ") + ((richtext) ?"</P>":"\n");
}
if (command != nil && size(command) > 0)
{
// header in the variable description text, bash command is appended
result = result + ((richtext) ?"<P><B>":"") + _("Activation Command: ") + ((richtext) ?"</B> ":"") + command + ((richtext) ?"</P>":"\n");
}
}
if (comment != "" && comment != nil)
{
if (richtext)
{
// convert '<' and '>' to '<' '>'
comment = mergestring(splitstring(comment, "<"), "<");
comment = mergestring(splitstring(comment, ">"), ">");
// keep comment formatting:
// convert '\n' => '<BR>'
comment = mergestring(splitstring(comment, "\n"), "<BR>");
// do not change node descriptions
if (file != "" )
{
// convert ' ' => ' '
comment = mergestring(splitstring(comment, " "), " ");
}
y2debug("formatted comment: %1", comment);
}
// rich text value
result = result + ((richtext) ?"<P><B>":"") + _("Description: ") + ((richtext) ?"</B><BR> ":"") + comment + ((richtext) ?"</P>":"");
}
y2debug("variable description : %1", result);
return result;
}
/**
* Get combo box editable status - depends on Type value
* @param description Description of variable
* @return boolean True if combo box should be editable
*/
define boolean combo_editable(map description) ``{
string type = description["Type"]:"";
return (type == "" || regexpmatch(type, "^integer\\(.*:.*\\)$") || type == "integer"
|| type == "string" || regexpmatch(type, "^string\\(.*\\)$") || type == "ip"
|| regexpmatch(type, "^regexp\\(.*\\)$"));
}
/**
* Generic list function - add value to the list if it isn't already there
* @param l Input list
* @param v Input value
* @return list List with value v
*/
define list add_if_missing(list l, string v) ``{
return (!contains(l, v)) ? add(l, v) : l;
}
/**
* Escape double quotes and back slash characters by back slash
* @param input String to escape
* @return Escaped string
*/
define string backslash_add(string input) ``{
// escape double quotes and back slashes
string escaped = "";
integer pos = 0;
while (pos < size(input))
{
string ch = substring(input, pos, 1);
string ch_1 = substring(input, pos + 1, 1);
// don't add backslash before \$ (#34809)
if (ch == "\\" && ch_1 != nil && ch_1 != "$")
{
escaped = escaped + "\\\\";
}
else
{
if (ch == "\"")
{
escaped = escaped + "\\\"";
}
else if (ch == "\n")
{
// multi line value
escaped = escaped + "\\\n";
}
else
{
escaped = escaped + ch;
}
}
pos = pos + 1;
}
return escaped;
}
/**
* Remove backslashes from string - opposite funtion to the backslash_add function.
* @param input Escaped string
* @return string String without escape chars
*/
define string backslash_remove(string input) ``{
if (input == nil)
{
return nil;
}
string ret = "";
integer index = 0;
boolean backslash = false;
while (index < size(input))
{
string ch = substring(input, index, 1);
string ch_1 = substring(input, index + 1, 1);
if (backslash == false)
{
// don't remove backslash before \$ (#34809)
if (ch == "\\" && ch_1 != nil && ch_1 != "$")
{
backslash = true;
}
else
{
ret = ret + ch;
}
}
else
{
ret = ret + ch;
backslash = false;
}
index = index + 1;
}
return ret;
}
/**
* Create list of values for combo box widget
* @param description Variable description
* @param set_default If true add default value to the list
* @return list List of values for combo box widget
*/
define list combo_list(map<string, any> description, boolean set_default) ``{
string new_value = (string) (description["new_value"]:nil);
string value = description["value"]:"";
// use default value (or emty string) instead of the curent value in autoyast
if (Mode::config())
{
value = (haskey(description, "Default")) ? description["Default"]:"" : "";
}
if (description["actions","SingleQt"]:"" == "")
{
new_value = backslash_remove(new_value);
value = backslash_remove(value);
}
list ret = [];
string deflt = (string) (description["Default"]:nil);
if (set_default == true && deflt != nil)
{
y2debug("Adding default value: %1", deflt);
if (!contains(ret, deflt)) ret = add(ret, deflt);
}
if (new_value != nil)
{
if (!contains(ret, new_value)) ret = add(ret, new_value);
}
else if (value != nil)
{
if (!contains(ret, value)) ret = add(ret, value);
}
string type = description["Type"]:"";
if (type == "yesno")
{
if (!contains(ret, "yes")) ret = add(ret, "yes");
if (!contains(ret, "no")) ret = add(ret, "no");
}
else if (type == "boolean")
{
if (!contains(ret, "true")) ret = add(ret, "true");
if (!contains(ret, "false")) ret = add(ret, "false");
}
else if (regexpmatch(type, "^list\\(.*\\)"))
{
string values_string = regexpsub(type, "^list\\((.*)\\)", "\\1");
list<string> parsed = String::ParseOptions(values_string, Sysconfig::parse_param);
// add missing items
foreach(string option, parsed,
``{
if (!contains(ret, option)) ret = add(ret, option);
}
);
}
else if (regexpmatch(type, "^string\\(.*\\)"))
{
string values_string = regexpsub(type, "^string\\((.*)\\)", "\\1");
list<string> parsed = String::ParseOptions(values_string, Sysconfig::parse_param);
// add missing items
foreach(string option, parsed,
``{
if (!contains(ret, option)) ret = add(ret, option);
}
);
}
// add default value to the list
if (deflt != nil && !contains(ret, deflt)) ret = add(ret, deflt);
// add old value to the list if variable was modified
if (new_value != nil)
{
if (!contains(ret, value)) ret = add(ret, value);
}
y2debug("combo list: %1", ret);
return ret;
}
/**
* Update combo box in dialog
* @param description Variable description
* @param set_default Set to true ifdefault value should be in the combo box
*/
define void update_combo(map<string, any> description, boolean set_default) ``{
string varname = description["name"]:"";
// modification flag added to variable name (if it was changed)
string modif_flag = (haskey(description, "new_value")) ? " " + _("(changed)") : "";
if (combo_editable(description))
{
// combo box widget label - variable name is appended to the string
UI::ReplaceWidget(`id(`replace), `ComboBox (`id(`combo), `opt(`editable, `hstretch), _("S&etting of: ") + varname + modif_flag, combo_list(description, set_default)));
}
else
{
// combo box widget label - variable name is appended to the string
UI::ReplaceWidget(`id(`replace), `ComboBox (`id(`combo), `opt(`hstretch), _("S&etting of: ") + varname + modif_flag, combo_list(description, set_default)));
}
// disable combo for non-leaf nodes
UI::ChangeWidget(`id(`combo), `Enabled, ((description["file"]:"") != ""));
// display warning if value is not single line
// combobox is one line entry, multiline values are merged to one line
// (new lines are displayed as spaces, but they are correctly preserved
string val = (description["new_value"]:nil != nil) ? description["new_value"]:"" : description["value"]:"";
if (val != nil)
{
list<string> lines = splitstring(val, "\n");
if (size(lines) > 1)
{
// current value has more than one line - it is displayed incorrectly
// because combobox widget has single line entry (lines are merged)
Popup::Warning(_("The currently selected value has more than one line.
Joined lines are displayed in the combo box.
"));
}
}
}
/**
* Update "Default" button state (enable/disable) in the dialog
* @param description Variable description
*/
define void update_button_state(map<string, any> description) ``{
string def = (string) (description["Default"]:nil);
UI::ChangeWidget(`id(`def), `Enabled, (def != nil));
}
/**
* Update location text in the dialog
* @param description Variable description
*/
define void update_location(map description) ``{
string l = description["location"]:"";
// header label
UI::ChangeWidget(`id(`heading), `Value, _("Current Selection: ") + l + empty_string);
}
/**
* Is selected item in the tree widget leaf node?
* @param id Value from tree widget
* @return boolean True if node is not leaf-node
*/
define boolean is_node(string id) ``{
return (findfirstof(id, "$") == nil);
}
/**
* Set new value for variable, warn user if new value does not match type definition.
* @param force_change force value as changed even if it is equal to the old one
*/
define void check_set_current_value(boolean force_change)
``{
// check current value
if (selected_variable != "")
{
string new_value = (string)UI::QueryWidget(`id(`combo), `Value);
map d = Sysconfig::get_description(selected_variable);
// check whether single quotes are used in the configuration file
if (d["actions", "SingleQt"]:"" == "")
{
new_value = backslash_add(new_value);
}
if (Sysconfig::get_name_from_id(selected_variable) != "")
{
// variable was selected (not category)
symbol result = Sysconfig::set_value(selected_variable, new_value, false, force_change);
if (result == `not_valid)
{
string t = d["Type"]:"string";
// popup question dialog: variable value does not match defined type - ask user to set value (%1 is value entered by user, %2 is allowed type - e.g. integer
if (Popup::AnyQuestion(Label::WarningMsg(), sformat(_("Value '%1'
does not match type '%2'.
Really set this value?
"), new_value, t), Label::YesButton(), Label::NoButton(), `focus_no) == true)
{
// force setting of value
Sysconfig::set_value(selected_variable, new_value, true, force_change);
}
}
}
}
}
/**
* Create table content list for selected variables
* @param varids Variables which will be contained in the table
* @return list Table content
*/
define list create_table_content(list<string> varids)
``{
list table_content = [];
foreach(string varid, varids,
``{
map descr = Sysconfig::get_description(varid);
string name = descr["name"]:"";
string old = descr["value"]:"";
string new = descr["new_value"]:"";
string file = descr["file"]:"";
// display only beginning of comment (to limit table space used)
string comm = descr["comment"]:"";
// remove newlines
comm = Sysconfig::remove_whitespaces(mergestring(splitstring(comm, "\n"), " "));
if (size(comm) > 90)
{
comm = substring(comm, 0, 90);
// when a comment is too long to display it in the table
// it is shortened and mark (three dot characters) is added to the end
comm = comm + _("...");
}
table_content = add(table_content, `item(`id(varid), name, new, old, file, comm));
}
);
return table_content;
}
list<map> GenerateTree(list<map> Tree, string parent, list<list> input) {
foreach(list i, input, ``{
string id = i[0,0]:"";
string title = i[1]:"";
boolean enabled = i[2]:false;
list<list> children = i[3]:[];
Tree = Wizard::AddTreeItem(Tree , parent, title, id );
if (size(children) > 0 ) {
Tree = GenerateTree(Tree, id, children);
}
});
return Tree;
}
/**
* Display main configuration dialog
* @return dialog result
*/
define symbol MainDialog() ``{
term button_box = `HBox(
// back pushbutton: the user input is ignored and the last dialog is called
`PushButton(`id(`abort), `opt(`key_F9), Label::AbortButton()),
`HStretch(),
`PushButton(`id(`help), `opt(`key_F1), Label::HelpButton()),
`HStretch(),
// Translation: push button label
`PushButton(`id(`search), _("&Search")),
`HStretch(),
`PushButton(`id(`next), `opt(`key_F10), Label::FinishButton())
);
// tree widget label
// term help_space_content = `Tree(`id(`tree), `opt(`notify, `vstretch), _("&Configuration Options"), Sysconfig::tree_content);
// Wizard::OpenCustomDialog(help_space_content, button_box);
Wizard::CreateTreeDialog();
list<map> Tree = GenerateTree([], "", Sysconfig::tree_content) ;
Wizard::CreateTree(Tree, _("&Configuration Options"));
string helptext =
// helptext for popup - part 1/3
_("<p>After you save your changes, this editor changes the variables in the
corresponding sysconfig file. Then it starts activation commands, which changes the underlying configuration files, stops and starts daemons,
and runs low-level configuration tools so your configuration in sysconfig takes effect.</p>
") +
// helptext for popup - part 2/3
_("<p><b>Important:</b> You still can edit each individual configuration file manually. The name of file is displayed in the variable description.</p>") +
// helptext for popup - part 3/3
_("<p> SuSEconfig saves a checksum of each configuration file, so it can detect if
you have manually changed any of them. If you have changed a configuration file manually,
it will not touch it.</p>
");
Wizard::SetContents(_("/etc/sysconfig Editor"),
`VBox(
// label widget
`Left(`Label(`id(`heading), `opt(`hstretch), _("Current Selection: ") + empty_string)),
`VSpacing(0.5),
`HBox(
`HWeight(1,
`ReplacePoint(`id(`replace),
// combo box label
`ComboBox (`id(`combo), `opt(`disabled, `hstretch), _("S&etting of: "), [""])
)
),
`VBox(
// dummy widget used to align button
`Label(""),
// push button label
`PushButton(`id(`def), `opt(`disabled), _("&Default"))
)
),
`VSpacing(1),
// help rich text displayed after module start (1/2)
`RichText(`id(`rt), _("<P><B>System Configuration Editor</B></P><P>With the system configuration editor, you can change some system settings. You can also use YaST2 to configure your hardware and system settings.</P>") +
// help rich text displayed after module start (2/2)
_("<P><B>Note:</B> Descriptions are not translated because they are read directly from configuration files.</P>")),
// push button label - displayed only in autoinstallation config mode
(Mode::config() == true) ? `HBox(`PushButton(`id(`use_current), _("&Use Current Value")),
// push button label - displayed only in autoinstallation config mode
`PushButton(`id(`add_new), `opt(`key_F3), _("&Add New Variable..."))
) : `Empty()
),
helptext, true, true);
// push button label
Wizard::SetBackButton(`back, _("&Search"));
Wizard::SetNextButton(`next, Label::OKButton());
Wizard::SetAbortButton(`abort, Label::CancelButton());
if (UI::WidgetExists(`id(`wizardTree)))
{
UI::ReplaceWidget(`id(`rep_button_box ), button_box );
}
Wizard::SetDesktopIcon("sysconfig");
any ret = nil;
while(ret != `cancel && ret != `abort && ret != `next )
{
map event = UI::WaitForEvent();
ret = event["ID"]:nil;
// "Default" button
if (ret == `def)
{
map<string, any> description = Sysconfig::get_description(selected_variable);
update_combo(description, true);
}
else if (ret == `next)
{
// check if current value was modified
check_set_current_value(false);
list<string> modified = Sysconfig::get_modified();
// show table with modified variables
if (size(modified) > 0)
{
y2milestone("Modified variables: %1", modified);
// popup dialog header
map result = display_variables_dialog(_("Modified Variables"),
// help text in popup dialog
_("Here, see the values YaST2 will change.
Choose \"OK\" for YaST2 to save these changes.
Choose \"Cancel\" to edit the values again.
"), create_table_content(modified), Label::OKButton(), Label::CancelButton(), _("Confirm Each Activation Command"), false);
if (result["ui"]:`dummy == `cancel)
{
ret = `again;
}
// set confirmation flag
Sysconfig::ConfirmActions = result["checkbox"]:false;
}
}
else if (ret == `back || ret == `search) // This is for Search actually FIXME
{
map search_parameters = display_search_dialog();
if (search_parameters != $[])
{
list<string> found = Sysconfig::Search(search_parameters, true);
if (size(found) > 0)
{
// // popup dialog header
map<string, any> input = display_variables_dialog(_("Search Result"),
// help text in popup dialog
_("The search results are displayed here. If you see the item you want, select it then click \"Go to\". Otherwise, click \"Cancel\" to close this dialog."), create_table_content(found),
// push button label
_("&Go to"), Label::CancelButton(), "", nil);
if (input["ui"]:`dummy == `cancel)
{
ret = `again;
}
else
{
string sel = (string) (input["selected"]:nil);
if (sel != nil)
{
// select variable in the tree
//UI::ChangeWidget(`id(`tree), `CurrentItem, sel);
Wizard::SelectTreeItem(sel);
// display selected variable
if (UI::WidgetExists(`id(`wizardTree)))
ret = `wizardTree;
else
ret = sel;
}
}
}
else
{
// popup message - search result message
Popup::Message(_("No entries found"));
}
}
}
else if (ret == `help)
{
UI::OpenDialog( `opt(`decorated ),
`HBox( `VSpacing(16),
`VBox(
`HSpacing(60),
// popup window header
`Heading(_("Help")),
`VSpacing(0.5),
`RichText(helptext),
`VSpacing(1.5),
// push button label
`PushButton(`id(`ok), `opt(`default, `key_F10), Label::OKButton())
)
)
);
UI::SetFocus(`id(`ok));
UI::UserInput();
UI::CloseDialog();
}
else if (ret == `abort || ret == `cancel)
{
if (!ReallyAbort())
{
ret = nil;
}
else
{
// `cancel is same as `abort
ret = `abort;
}
}
// autoinstallation config mode only
else if (ret == `use_current)
{
// force current value as changed
check_set_current_value(true);
map<string, any> description = Sysconfig::get_description(selected_variable);
// update combo box - add "changed" status
update_combo(description, false);
}
// autoinstallation config mode only
else if (ret == `add_new)
{
// ask user for new variable name, value and location (file name)
map in = add_new_variable();
symbol ui = in["ui"]:`cancel;
string name = in["name"]:"";
string file = in["file"]:"";
string value = in["value"]:"";
if (ui == `ok)
{
Sysconfig::set_value(sformat("%1$%2", name, file), value, false, true);
}
}
if (ret == `wizardTree || is(ret, string))
{
check_set_current_value(false);
// string selected = (string)UI::QueryWidget(`id(`tree), `CurrentItem);
string selected = Wizard::QueryTreeItem();
selected_variable = selected;
y2milestone("Selected: %1", selected);
map<string, any> description = Sysconfig::get_description(selected);
y2milestone("Descr: %1", description);
// update richtext content
UI::ChangeWidget(`id(`rt), `Value, create_description(description, true));
// update combo box
update_combo(description, false);
// update "Default" button state (enable/disable)
update_button_state(description);
// update location in header
update_location(description);
}
}
UI::CloseDialog();
return (symbol)ret;
}
}
ACC SHELL 2018