ACC SHELL

Path : /usr/share/YaST2/include/bootloader/grub/
File Upload :
Current File : //usr/share/YaST2/include/bootloader/grub/options.ycp

/**
 * File:
 *      include/bootloader/routines/grub_options.ycp
 *
 * Module:
 *      Bootloader installation and configuration
 *
 * Summary:
 *      Grub widgets for bootloader options.
 *
 * Authors:
 *      Josef Reidinger<jreidinger@suse.cz>
 *
 * $Id: $
 *
 */

{
textdomain "bootloader";

import "Label";
import "BootStorage";
import "GfxMenu";
import "System::Bootloader_API";

include "bootloader/routines/common_options.ycp";
include "bootloader/routines/popups.ycp";
include "bootloader/routines/helps.ycp";
include "bootloader/grub/helps.ycp";

void InitGfx(string widget){
  boolean value = BootCommon::globals["trusted_grub"]:"false" != "true";
  UI::ChangeWidget(`id(`gfxinput),`Enabled, value);
  UI::ChangeWidget(`id(`gfxinput),`Value,BootCommon::globals[widget]:"");
}

void StoreGfx(string widget, map event){
  string result = (string)UI::QueryWidget(`id(`gfxinput),`Value);
  if (result == ""){
    BootCommon::global_options = remove(BootCommon::global_options, widget);
  } else {
    BootCommon::global_options[widget] = result;
  }
}

symbol HandleGfx(string widget, map event){
  string file = UI::AskForExistingFile("/boot", "",
                  _("Choose new graphical menu file"));

  if (file != nil){
     UI::ChangeWidget(`id(`gfxinput),`Value,file);
  }

  return nil;
}

map<string,any> GfxWidget(){
  return $[
    "widget" : `custom,
    "custom_widget" : 
	`VBox(
	    //`Left(`CheckBox(`id(`enable_acoustic_signals), _("Enable Acoustic &Signals"))),
	    `HBox(`Left(`InputField(`id(`gfxinput),`opt(`hstretch), grub_descriptions["gfxmenu"]:"gfxmenu")),
		`VBox(
		    `Left(`Label("")),
		    `Left(`PushButton(`id(`browsegfx),`opt(`notify), Label::BrowseButton()))
		)
            )
	),
    "init" : InitGfx,
    "store" : StoreGfx,
    "handle" : HandleGfx,
    "handle_events" : [`browsegfx],
    "help" : grub_help_messages["gfxmenu"]:"" + grub_help_messages["enable_acoustic_signals"]:""
  ];
}


void InitAcousticSignals(string widget){
  if (GfxMenu::enable_sound_signals)
     UI::ChangeWidget(`id(widget),`Value, true);
  else
     UI::ChangeWidget(`id(widget),`Value, false);
}

void StoreAcousticSignals(string widget, map event){
  GfxMenu::enable_sound_signals = (boolean) UI::QueryWidget(`id(widget),`Value);
}

map<string,any> AcousticSignals(){
  return $[
    "widget" : `checkbox,
    "label"  : _("Enable Acoustic &Signals"),
    "init" : InitAcousticSignals,
    "store" : StoreAcousticSignals,
    "help" : grub_help_messages["enable_acoustic_signals"]:""
  ];
}

symbol HandleTrusted (string widget, map event){
  boolean value =  (boolean)UI::QueryWidget(`id(widget),`Value);
  UI::ChangeWidget(`id(`gfxinput),`Enabled,!value);
  return nil;
}

map<string,any> TrustedWidget(){
  map<string,any> widget = CommonCheckboxWidget(
        grub_descriptions["trusted_grub"]:"trusted grub",
        grub_help_messages["trusted_grub"]:"");
  widget["opt"] = [`notify];
  widget["handle"] = HandleTrusted;
  return widget;
}

/**
 * Init function of widget
 * @param widget string id of the widget
 */
void InitPasswdWidget (string widget) {
    string passwd = BootCommon::globals["password"]:"";
    if (passwd == nil || passwd == "")
    {
	UI::ChangeWidget (`id (`use_pas), `Value, false);
	UI::ChangeWidget (`id (`pw1), `Enabled, false);
	UI::ChangeWidget (`id (`pw1), `Value, "");
	UI::ChangeWidget (`id (`pw2), `Enabled, false);
	UI::ChangeWidget (`id (`pw2), `Value, "");
    }
    else
    {
	UI::ChangeWidget (`id (`use_pas), `Value, true);
	UI::ChangeWidget (`id (`pw1), `Enabled, true);
	UI::ChangeWidget (`id (`pw1), `Value, "**********");
	UI::ChangeWidget (`id (`pw2), `Enabled, true);
	UI::ChangeWidget (`id (`pw2), `Value, "**********");
    }
    if (Mode::installation()){
	UI::ChangeWidget (`id (`use_pas), `Enable, false);
    }
}

/**
 * Handle function of a widget
 * @param widget string id of the widget
 * @param event map event description of event that occured
 * @return symbol always nil
 */
symbol HandlePasswdWidget (string widget, map event) {
    if (event["ID"]:nil == `use_pas)
    {
	boolean enabled = (boolean)UI::QueryWidget (`id (`use_pas), `Value);
	UI::ChangeWidget (`id (`pw1), `Enabled, enabled);
	UI::ChangeWidget (`id (`pw2), `Enabled, enabled);
    }
    return nil;
}

/**
 * Store function of a popup
 * @param key any widget key
 * @param event map event that caused the operation
 */
void StorePasswdWidget (string key, map event) {
    string password = nil;
    boolean usepass = (boolean)UI::QueryWidget (`id (`use_pas), `Value);
    y2milestone ("Usepass: %1", usepass);
    if (usepass)
    {
	if (UI::QueryWidget (`id (`pw1), `Value) != "**********")
	{
	    password = (string)UI::QueryWidget (`id (`pw1), `Value);
            password = System::Bootloader_API::countGRUBPassword(password);
	    if (password != nil){
              BootCommon::globals["password"] = password; //TODO popup for error
            }
	}
    }
    else if (haskey (BootCommon::globals, "password"))
    {
	BootCommon::globals = remove (BootCommon::globals, "password");
    }
    return nil;
}


/**
 * Validate function of a popup
 * @param key any widget key
 * @param event map event that caused validation
 * @return boolean true if widget settings ok
 */
boolean ValidatePasswdWidget (string key, map event) {
    if (! (boolean)UI::QueryWidget (`id (`use_pas), `Value))
	return true;
    if (UI::QueryWidget (`id (`pw1), `Value) == "")
    {
	emptyPasswdErrorPopup ();
	UI::SetFocus (`id (`pw1));
	return false;
    }
    if (UI::QueryWidget (`id (`pw1), `Value)
	== UI::QueryWidget (`id (`pw2), `Value)
    )
	return true;
    passwdMissmatchPopup ();
    UI::SetFocus (`id (`pw1));
    return false;
}



/**
 * Build a map describing a widget
 * @return a map describing a widget
 */
map<string,any> PasswordWidget () {
    return $[
	"widget" : `custom,
	// frame
	"custom_widget" : `HBox(
	    `CheckBoxFrame (`id (`use_pas), 
			_("Prot&ect Boot Loader with Password"),true,
		    `HBox (
			`HSpacing(2),
			// text entry
			`Password (`id (`pw1), `opt(`hstretch), _("&Password")),
			// text entry
			`HSpacing(2),
			`Password (`id (`pw2),`opt(`hstretch), _("Re&type Password")),
			`HStretch()
		    )
	    )
	    ),
	"init" : InitPasswdWidget,
	"handle" : HandlePasswdWidget,
	"store" : StorePasswdWidget,
	"validate_type" : `function,
	"validate_function" : ValidatePasswdWidget,
	"help" : grub_help_messages["password"]:"",
    ];
}

/**
 * Init function for console
 * @param string widget
 */
void InitConsole( string widget){
  boolean enable = BootCommon::globals["terminal"]:"" == "serial";
  UI::ChangeWidget(`id(`console_frame),`Value, enable);
  string args = BootCommon::globals["serial"]:"";
  UI::ChangeWidget(`id(`console_args),`Value, args);
}

/**
 * Store function of a console
 * @param widget any widget key
 * @param event map event description of event that occured
 */
void StoreConsole(string widget, map event){
  boolean use_serial = (boolean) UI::QueryWidget(`id(`console_frame),`Value);
  if (use_serial)
  {
     BootCommon::globals["terminal"] = "serial";
     string console_value = (string) UI::QueryWidget(`id(`console_args),`Value);
     if (console_value != "")
	BootCommon::globals["serial"] = console_value;
  } else {
     if (haskey(BootCommon::globals, "terminal"))
	BootCommon::globals = remove(BootCommon::globals, "terminal");
     if (haskey(BootCommon::globals, "serial"))
	BootCommon::globals = remove(BootCommon::globals, "serial");
  }
  // FATE: #110038: Serial console
  // add or remove console key with value for sections 
  BootCommon::HandleConsole();
}

/**
 * Handle function of  a console
 * @param widget any widget key
 * @param event map event description of event that occured
 * @return symbol nil
 */
symbol HandleConsole(string widget, map event){
  boolean enable = (boolean) UI::QueryWidget(`id(`enable_console),`Value);
  UI::ChangeWidget(`id(`console_args),`Enabled, enable);
  return nil;
}

/**
 * Common widget of a console
 * @return map<string,any> CWS widget
 */
map<string,any> ConsoleWidget() {
  return $[
    "widget" : `custom,
    "custom_widget" : `HBox(
        `CheckBoxFrame(`id(`console_frame),_("Use &serial console"),true,
          `HBox(
          `HSpacing(2),
          `InputField(`id(`console_args),`opt(`hstretch), _("&Console arguments")),
          `HStretch()))
        ),
    "init" : InitConsole,
    "store" : StoreConsole,
    "help" : grub_help_messages["serial"]:""
  ];
}

map<string,map<string,any> > GrubOptions(){
  map<string,map<string,any> >  grub_specific = $[
    "activate" : CommonCheckboxWidget(grub_descriptions["activate"]:"activate",
                                      grub_help_messages["activate"]:""),
    "debug" : CommonCheckboxWidget(grub_descriptions["debug"]:"debug",
                                    grub_help_messages["debug"]:""),
    "generic_mbr" : CommonCheckboxWidget(grub_descriptions["generic_mbr"]:"generic mbr",
                                          grub_help_messages["generic_mbr"]:""),
    "trusted_grub" : TrustedWidget(),
    "hiddenmenu" : CommonCheckboxWidget(grub_descriptions["hiddenmenu"]:"hidden menu",
                                          grub_help_messages["hiddenmenu"]:""),
    "gfxmenu" : GfxWidget(),
    "password" : PasswordWidget(),
    "console" : ConsoleWidget(),
    "acoustic_signals" : AcousticSignals(),
  ];
  return (map<string,map<string,any> >)union(grub_specific,CommonOptions());
}



void InitDiskOrder(string widget) {
  list<string> disksOrder = BootStorage::DisksOrder ();

  UI::ChangeWidget ( `id(`disks), `Items, disksOrder);
  UI::ChangeWidget (`id (`disks), `CurrentItem, disksOrder[0]:"");
}

string GetItemID(term t){
  return argsof((term)argsof(t)[0]:`id(""))[0]:"";
}

void StoreDiskOrder(string widget, map event) {
  list<term> disksOrder = (list<term>)UI::QueryWidget(`id(`disks), `Items);
  list<string> result = (list<string>) maplist(term t, disksOrder, {
    return GetItemID(t);
  });
  BootCommon::mbrDisk = result[0]:"";
  integer index = 0;
  BootStorage::device_mapping = listmap (string d, result, {
    string indexs = tostring(index);
    index = index + 1;
    return $[ d : sformat ("hd%1", indexs)];
  });
}

string NewDevicePopup(){
  term popup = `VBox (`VSpacing (1),
      // textentry header
      `InputField (`id (`devname), `opt (`hstretch), _("&Device")),
      `VSpacing (1),
       `HBox (`HStretch (),
          `PushButton (`id (`ok), `opt (`key_F10, `default),
              Label::OKButton ()),
          `HStretch (),
          `PushButton (`id (`cancel), `opt (`key_F8),
              Label::CancelButton ()),
          `HStretch ()
      ),
      `VSpacing (1)
  );
  UI::OpenDialog (popup);
  symbol pushed = (symbol)UI::UserInput ();
  string new_dev = (string) UI::QueryWidget (`id (`devname), `Value);
  UI::CloseDialog ();
  string ret = "";
  if (pushed == `ok){
    ret = new_dev;
  }
  return ret;
}


symbol HandleDiskOrder( string widget, map event ){
  any action = event["ID"]:nil;
  boolean changed = false;
  list<term> disksOrder = (list<term>)UI::QueryWidget(`id(`disks), `Items);
  string current = (string)UI::QueryWidget (`id (`disks), `CurrentItem);
  integer pos = 0;
  while (pos < size (disksOrder)
    && GetItemID(disksOrder[pos]:`Item(`id(""))) != current)
        pos = pos + 1;

  //disabling & enabling up/down
  UI::ChangeWidget (`id (`up), `Enabled, pos > 0 && pos < size (disksOrder));
  UI::ChangeWidget (`id (`down), `Enabled, pos < size (disksOrder) - 1);

  if (action == `up){
    changed= true;
    disksOrder =
      (list<term>) list::swap (disksOrder, pos, pos - 1);
  } else if (action == `down){
    changed= true;
    disksOrder =
          (list<term>) list::swap (disksOrder, pos, pos + 1);
  } else if (action == `delete){
    changed = true;
    disksOrder = remove(disksOrder,pos);
    UI::ChangeWidget (`id (`disks), `CurrentItem,
        (pos > 0) ? GetItemID(disksOrder[(pos-1)]:`Item(`id("")))
                  : GetItemID(disksOrder[0]:`Item(`id(""))));
  } else if (action == `add) {
    string new_dev = NewDevicePopup();
    if (new_dev != ""){
      changed = true;
      disksOrder = add(disksOrder, `item(`id(new_dev),new_dev));
    }
  }

  if (changed){
    UI::ChangeWidget (`id (`disks), `Items, disksOrder);
  }
}

boolean ValidateDiskOrder(string key, map event) {
  list<term> disksOrder = (list<term>)UI::QueryWidget(`id(`disks), `Items);
  if (size(disksOrder)>0)
    return true;
  Popup::Warning(_("Device map must contain at least one device"));
  return false;
}

map<string,any> DisksOrderWidget(){
  term contents = `HBox (`HSpacing (2), `VBox (
                        `VSpacing (1),
                        `SelectionBox (`id (`disks),
                          `opt (`notify, `immediate),_("D&isks"), []),
                        `HBox(
                                `HStretch (),
                                `PushButton (`id (`add),
                                `opt (`key_F3), Label::AddButton ()),
                                `PushButton (`id (`delete),
                                `opt(`key_F5), Label::DeleteButton ()),
                                `HStretch ()
                        ),
                        `VSpacing (1)
                       ),
                       `HSquash (
                            `VBox (
                                 `VStretch (),
                                 `PushButton (`id (`up),
                                 `opt (`hstretch), _("&Up")),
                                 `PushButton (`id (`down),
                                 `opt (`hstretch), _("&Down")),
                                 `VStretch ()
                            )
                       ),
                       `HSpacing (2)
                     );
  return $[
    "widget" : `custom,
    "custom_widget" : contents,
    "init" : InitDiskOrder,
    "handle" : HandleDiskOrder,
    "store" : StoreDiskOrder,
    "help" : grub_help_messages["disk_order"]:"",
    "validate_type" : `function,
    "validate_function" : ValidateDiskOrder
  ];
}

/**
 * Init function of a widget
 * @param widget string widget key
 */
void  InitBootLoaderLocationWidget(string widget) {
    list<string> boot_devices = BootStorage::getPartitionList(`boot, "grub");
    string value = "";
    if (BootCommon::VerifyMDArray ())
    {
	if ((BootCommon::enable_md_array_redundancy == nil) || (BootCommon::enable_md_array_redundancy))
	    UI::ChangeWidget (`id ("enable_redundancy"), `Value, true);
	else
	    UI::ChangeWidget (`id ("enable_redundancy"), `Value, false);

	value = BootCommon::globals["boot_mbr"]:nil;
	UI::ChangeWidget (`id ("boot_mbr"), `Value, (value == "true")? true: false);
    } else {
	list <string> list_global_target_keys = ["boot_mbr", "boot_boot", "boot_root", "boot_extended"];
	foreach(string key, list_global_target_keys, 
	{
	    value = BootCommon::globals[key]:nil;
	    if (value != nil)
		UI::ChangeWidget (`id (key), `Value, (value == "true")? true: false);
	});
	UI::ChangeWidget (`id ("boot_custom_list"),`Items, boot_devices);

	if (BootStorage::BootPartitionDevice == BootStorage::RootPartitionDevice)
	    UI::ChangeWidget (`id ("boot_boot"), `Enabled, false);
	else
	    UI::ChangeWidget (`id ("boot_boot"), `Enabled, true);

	if (BootStorage::ExtendedPartitionDevice != nil)
	    UI::ChangeWidget (`id ("boot_extended"), `Enabled, true);
	else
	    UI::ChangeWidget (`id ("boot_extended"), `Enabled, false);
    }

    if ((!haskey(BootCommon::globals,"boot_custom")) || 
        (BootCommon::globals["boot_custom"]:"" == ""))
    {
	UI::ChangeWidget (`id ("boot_custom_list"),`Enabled, false);
    } else {
	UI::ChangeWidget (`id ("boot_custom"), `Value, true);
	UI::ChangeWidget (`id ("boot_custom_list"),`Enabled, true);
	UI::ChangeWidget (`id ("boot_custom_list"),`Value, BootCommon::globals["boot_custom"]:"");
    }
}
/**
 * handle function of a widget
 * @param widget string widget key
 * @param event map event that caused the operation
 * @return symbol
 */
symbol HandleBootLoaderLocationWidget (string widget, map event) {
    any ret = event["ID"]:nil;
    if (ret == "boot_custom")
    {
	if ((boolean)UI::QueryWidget(`id("boot_custom"), `Value))
	    UI::ChangeWidget (`id ("boot_custom_list"),`Enabled, true);
	else
	    UI::ChangeWidget (`id ("boot_custom_list"),`Enabled, false);
    }
    return nil;
}


/**
 * Store function of a widget
 * @param widget string widget key
 * @param event map event that caused the operation
 */
void StoreBootLoaderLocationWidget (string widget, map event) {

    if (BootCommon::VerifyMDArray ())
    {
        BootCommon::enable_md_array_redundancy = (boolean)UI::QueryWidget(`id("enable_redundancy"), `Value);
	BootCommon::globals["boot_mbr"]=  ((boolean)UI::QueryWidget(`id("boot_mbr"), `Value))?"true":"false";
    } else {
	list <string> list_global_target_keys = ["boot_mbr", "boot_boot", "boot_root", "boot_extended"];
	foreach(string key, list_global_target_keys, 
	{
	    string value = ((boolean)UI::QueryWidget(`id(key), `Value))?"true":"false";
	    BootCommon::globals[key]= value;
	});
    }
    if ((boolean)UI::QueryWidget(`id("boot_custom"), `Value))
	BootCommon::globals["boot_custom"]= (string)UI::QueryWidget(`id("boot_custom_list"), `Value);
    //bnc#544809 Custom Boot Partition cannot be deleted
    else
	BootCommon::globals["boot_custom"]="";
}

/** FIXME: merge help text to one for BootLoaderLocationWidget
 *  Function merge help text from ../grub/helps.ycp
 *
 * @return string help text for widget BootLoaderLocationWidget 
 */
string  HelpBootLoaderLocationWidget()
{
    string ret = "";
    ret = grub_help_messages["boot_mbr"]:"";
    ret = ret + "\n";
    ret = ret + grub_help_messages["boot_custom"]:"";
    ret = ret + "\n";
    if (BootCommon::VerifyMDArray ())
    {
	ret = ret + grub_help_messages["enable_redundancy"]:"";
    } else {
	ret = ret + grub_help_messages["boot_root"]:"";
	ret = ret + "\n";
	ret = ret + grub_help_messages["boot_boot"]:"";
	ret = ret + "\n";
	ret = ret + grub_help_messages["boot_extended"]:"";
    }
    return ret;
}

/**
 * Create Frame "Boot Loader Location"
 *
 * @return term with widgets
 */

map<string,any> grubBootLoaderLocationWidget ()
{
    term contents = `VBox (
	`Frame (_("Boot Loader Location"),
	   `VBox (`HBox(`HSpacing(1),`VBox(
	       `Left(`CheckBox( `id("boot_mbr"), _("Boot from &Master Boot Record"))),
	       `Left(`CheckBox( `id("boot_root"), _("Boot from &Root Partition"))),
	       `Left(`CheckBox( `id("boot_boot"), _("Boo&t from Boot Partition"))),
	       `Left(`CheckBox( `id("boot_extended"), _("Boot from &Extended Partition"))),
	       `Left(`CheckBox( `id("boot_custom"), `opt(`notify), _("C&ustom Boot Partition"))),
	       `Left(`ComboBox( `id("boot_custom_list"), `opt (`editable, `hstretch),"", [])),
	       `VStretch()
            )))
         ),
	`VStretch()	
    );
 
    if (BootCommon::VerifyMDArray ())
    {
	contents = `VBox (
	`Frame (_("Boot Loader Location"),
	   `VBox (`HBox(`HSpacing(1),`VBox(
	       `Left(`CheckBox( `id("boot_mbr"), _("Boot from &Master Boot Record"))),
	       `Left(`CheckBox( `id("enable_redundancy"), _("Enable Red&undancy for MD Array"))),
	       `Left(`CheckBox( `id("boot_custom"), `opt(`notify), _("C&ustom Boot Partition"))),
	       `Left(`ComboBox( `id("boot_custom_list"), `opt (`editable, `hstretch),"", [])),
	       `VStretch()
            )))
         ),
	`VStretch()	
        );
    }
    return $[
      "widget" : `custom,
      "custom_widget" : contents,
      "init" : InitBootLoaderLocationWidget,
      "handle" : HandleBootLoaderLocationWidget,
      "store" : StoreBootLoaderLocationWidget,
      "help" : HelpBootLoaderLocationWidget(),
  ];
}

/**
 * Handle function of a widget
 * @param widget string widget key
 * @param event map event description of event that occured
 * @return symbol to return to wizard sequencer, or nil
 */
symbol InstDetailsButtonHandle (string widget, map event) 
{
    return `inst_details;
}


map<string,any> grubInstalationDetials ()
{
    return $[
      "widget" : `push_button,
      // push button
      "label" : _("Boot Loader Installation &Details"),
      "handle_events" : ["inst_details"],
      "handle" : InstDetailsButtonHandle,
      "help" : InstDetailsHelp (),
    ];
}




}

ACC SHELL 2018