ACC SHELL

Path : /usr/share/YaST2/include/bootloader/routines/
File Upload :
Current File : //usr/share/YaST2/include/bootloader/routines/global_widgets.ycp

/**
 * File:
 *      include/bootloader/routines/widgets.ycp
 *
 * Module:
 *      Bootloader installation and configuration
 *
 * Summary:
 *      Common widgets for being used by several bootloaders
 *
 * Authors:
 *      Jiri Srain <jsrain@suse.cz>
 *
 * $Id: global_widgets.ycp 56933 2009-04-23 12:56:26Z juhliarik $
 *
 */


{

textdomain "bootloader";

import "CWM";
import "CWMTab";
import "CWMTable";
import "Label";
import "Mode";
import "Storage";
import "StorageDevices";
import "Bootloader";
import "Progress";
import "PackageSystem";
import "Package";
import "Message";



include "bootloader/routines/helps.ycp";

/**
 * Init function of widget
 * @param widget string id of the widget
 */
void GlobalOptionInit (string widget) {
    if (widget == "adv_button")
	return;
    UI::ChangeWidget (`id (widget), `Value, BootCommon::globals[widget]:"");
}

/**
 * Store function of a widget
 * @param widget string widget key
 * @param event map event that caused the operation
 */
void GlobalOptionStore (string widget, map event) {
    if (widget == "adv_button")
	return;
    BootCommon::globals[widget] = (string)
	UI::QueryWidget (`id (widget), `Value);
}

/**
 * Map of default (fallback) handlers for widget events on global widgets
 */
map<string,any> global_handlers = $[
    "init" : GlobalOptionInit,
    "store" : GlobalOptionStore,
];

/**
 * 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) {
    string lt = Bootloader::getLoaderType ();
    if (lt == "none" || lt == "default")
    {
	NoLoaderAvailable ();
	return nil;
    }
    return `inst_details;
}

/**
 * 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 LoaderOptionsButtonHandle (string widget, map event) {
    string lt = Bootloader::getLoaderType ();
    if (lt == "none" || lt == "default")
    {
	NoLoaderAvailable ();
	return nil;
    }
    return `loader_details;
}

// sections list widget


/**
 * Refresh and redraw widget wits sections
 * @param sects list of current sections
 */
void RedrawSectionsTable (list<map<string,any> > sects) {
    list sec = maplist (map<string,any> s, sects, {
        string info = "";
	
	string type = _("Other");
	if (s["type"]:"" == "image")
        {
	    type = _("Image");
            string image = s["image"]:"";
            string root = (BootStorage::getHintedPartitionList ([s["root"]:""]))[0]:"";
            boolean elilo = Bootloader::getLoaderType () == "elilo";
            info = (image != "" && image != nil) ?  sformat ("%1   (%2%3)",
                image, elilo ? "" : BootCommon::splitPath (image)[0]:"",
                root == "" ? "": ((elilo ? "" : ", ")+ sformat ("root=%1", root))):"";
        }
	else if (s["type"]:"" == "xen"){
	    type = _("Xen");
            string image = s["image"]:"";
            string root = (BootStorage::getHintedPartitionList ([s["root"]:""]))[0]:"";
            boolean elilo = Bootloader::getLoaderType () == "elilo";
            info = (image != "" && image != nil) ?  sformat ("%1   (%2%3)",
                image, elilo ? "" : BootCommon::splitPath (image)[0]:"",
                root == "" ? "": ((elilo ? "" : ", ")+ sformat ("root=%1", root))):"";
        }
	else if (s["type"]:"" == "floppy"){
	    type = _("Floppy");
        }
	else if (s["type"]:"" == "menu"){
	    type = _("Menu");
            if (Bootloader::getLoaderType () == "grub"){
              string paths = s["configfile"]:"";
              string root = s["root"]:"";
              info = sformat ("dev=%1 path=%2", root, paths);
            } else if (Bootloader::getLoaderType () == "zipl"){
              info = s["list"]:"";
            }
        }
	else if (s["type"]:"" == "dump"){
	    type = _("Dump");
            info = s["dumpto"]:(s["dumptofs"]:"");
        } else if (s["type"]:"" == "other"){
            info = s["chainloader"]:"";
        }
        return `item (`id (s["name"]:""),
	    tolower (BootCommon::globals["default"]:"")
		    == tolower (s["name"]:"")
		? UI::Glyph (`CheckMark) : "",
	    s["name"]:"",
	    type,
	    info
        );
    });
    UI::ChangeWidget (`id (`_tw_table), `Items, sec);
}

/**
 * Init function of widget
 * @param widget string id of the widget
 */
void SectionsInit (string widget) {
    RedrawSectionsTable (BootCommon::sections);
}


symbol defaultHandle(string key, map event, integer index){
    string current = (string)UI::QueryWidget (`id (`_tw_table), `CurrentItem);
    BootCommon::globals["default"] = current;
    RedrawSectionsTable (BootCommon::sections);
    UI::ChangeWidget (`id (`_tw_table), `CurrentItem, current);
    return nil;
}

symbol updownHandle(string key, map event, boolean up, integer index){
    integer second = up ? (index-1):(index+1);
    BootCommon::sections = (list<map<string,any> >)
                     list::swap(BootCommon::sections, index, second);
    RedrawSectionsTable (BootCommon::sections);
    return nil;
}

void markSelected(integer index){
    map<string,any> selected = BootCommon::sections[index]:$[];
    string name = selected["name"]:"";
    BootCommon::current_section = selected;
    BootCommon::current_section_index = index;
    BootCommon::current_section_name = name;
}

symbol addHandle(string key, map event, integer index){
    markSelected(index);
    BootCommon::current_section_index = -1;
    return `add;
}

symbol editHandle(string key, map event, integer index){
    markSelected(index);
    return `edit;
}

symbol deleteHandle(string key, map event, integer index){
  string current = (string)UI::QueryWidget (`id (`_tw_table), `CurrentItem);
  if (confirmSectionDeletePopup (current)){
    BootCommon::removed_sections = add (BootCommon::removed_sections,
          BootCommon::sections[index, "original_name"]:"");
    BootCommon::sections = remove(BootCommon::sections, index);
    RedrawSectionsTable (BootCommon::sections);
    BootCommon::changed = true;
  }
}
/**
 * Get map of widget
 * @return a map of widget
 */
map<string,any> getSectionsWidget () {
  term head = `header(
                    // table header, Def stands for default
                    _("Def."),
                    // table header
                    _("Label"),
                    // table header
                    _("Type"),
                    // table header; header for section details, either
                    // the specification of the kernel image to load,
                    // or the specification of device to boot from
                    _("Image / Device")
                    );
  return CWMTable::CreateTableDescr( $[
    "add_delete_buttons" : true,
    "edit_button" : true,
    "up_down_buttons" : true,
    "custom_button" : true,
    "custom_button_name" :  _("Set as De&fault"),
    "custom_handle" : defaultHandle,
    "header" : head,
    "edit":editHandle,
    "delete":deleteHandle,
    "add" : addHandle,
    "updown" : updownHandle,
   ],$[
     "init" : SectionsInit,
     "help" : SectionsHelp ()
   ]);
}



// loader type widget

/**
 * Get the widget for boot laoder selection combo
 * @return term the widget
 */
term LoaderTypeComboWidget () {
    return `ComboBox (`id ("loader_type"),
	`opt (`notify),
	// combo box
	_("&Boot Loader"),
	maplist (string l, BootCommon::getBootloaders (), {
	    return `item (`id (l), BootCommon::getLoaderName (l, `combo));
	}));
}

/**
 * Init function of widget
 * @param widget string id of the widget
 */
void LoaderTypeComboInit (string widget) {
    UI::ChangeWidget (`id (widget), `Value, Bootloader::getLoaderType ());
}

/**
 * Handle function of a widget
 * @param key any widget key
 * @param event map event description of event that occured
 * @return symbol to return to wizard sequencer, or nil
 */
symbol LoaderTypeComboHandle (string key, map event) {
    if (event["ID"]:nil == key)
    {
	string old_bl = Bootloader::getLoaderType ();
	string new_bl = (string)UI::QueryWidget (`id (key), `Value);

	if (old_bl == new_bl)
	    return nil;


	if (new_bl == "lilo")
	{
		Popup::Warning(_("The LILO is not supported now."));
	}

	if (new_bl == "none")
	{
	    // popup - Continue/Cancel
	    if (Popup::ContinueCancel (_("
If you do not install any boot loader, the system
might not start.

Proceed?
")))
	    {
		BootCommon::other_bl[old_bl] = Bootloader::Export ();
		BootCommon::setLoaderType ("none");
		BootCommon::location_changed = true;
	    }
	    return `redraw;
	}

	if (Arch::x86_64 ()) {
	    if (new_bl == "elilo") {
// continue/cancel pop-up
		if (! Popup::ContinueCancel (_("
ELILO supports only the EFI boot architecture. If yor
firmware does not support it, your computer will not
boot.")))
		{
		    UI::ChangeWidget (`id ("loader_type"), `Value, Bootloader::getLoaderType ());
		    return nil;
		}
	    }
	    else if (old_bl == "elilo") {
// continue/cancel pop-up
		if (! Popup::ContinueCancel (_("
Bootloader you selected does not support the EFI boot
architecture. If your firmware does not support legacy
booting, your computer will not boot.")))
		{
		    UI::ChangeWidget (`id ("loader_type"), `Value, Bootloader::getLoaderType ());
		    return nil;
		}
	    }
	}

	// warning - popup, followed by radio buttons
	string label = _("
You chose to change your boot loader. When converting 
the configuration, some settings might be lost.

The current configuration will be saved and you can
restore it if you return to the current boot loader.

Select a course of action:
");

	term contents = `VBox (
		// warning label
	    `Label (label),
	    `VSpacing (1),
	    `RadioButtonGroup (`id (`action), `VBox (
		`Left (`RadioButton (`id (`propose),
		    // radiobutton
		    _("&Propose New Configuration"))),
		`Left (`RadioButton (`id (`convert),
			// radiobutton
			_("Co&nvert Current Configuration"))),
		Stage::initial () ? `VSpacing (0)
		: `Left (`RadioButton (`id (`scratch),
		    // radiobutton
		    _("&Start New Configuration from Scratch"))),
		Mode::normal ()
		    ? `Left (`RadioButton (`id (`read),
			// radiobutton
			_("&Read Configuration Saved on Disk")))
		    : `VSpacing (0),
		BootCommon::other_bl[new_bl]:nil == nil || Stage::initial ()
		    ? `VSpacing (0)
		    : `Left (`RadioButton (`id (`prev),
			// radiobutton
			_("Res&tore Configuration Saved before Conversion")))
	    )),
	`VSpacing (1),
	`HBox (
	    `HStretch (),
	    `PushButton (`id (`ok), `opt (`key_F10), Label::OKButton ()),
	    `HSpacing (1),
	    `PushButton (`id (`cancel), `opt (`key_F9), Label::CancelButton ()),
	    `HStretch ()
	));
	UI::OpenDialog (contents);
	symbol def = `propose;
	UI::ChangeWidget (`id (def), `Value, true);
	symbol ret = (symbol)UI::UserInput ();
	symbol action = (symbol)UI::QueryWidget (`id (`action), `CurrentButton);
	UI::CloseDialog ();
	if (ret != `ok)
	{
	    UI::ChangeWidget (`id ("loader_type"), `Value, Bootloader::getLoaderType ());
	    return nil;
	}

	if (nil != action)
	{
	    y2milestone ("Switching bootloader");
	    if (old_bl != "none")
		BootCommon::other_bl[old_bl] = Bootloader::Export ();
	    BootCommon::setLoaderType (new_bl);

            if (action == `scratch)
		Bootloader::Reset ();
            else if (action == `read)
	    {
		boolean progress_status = Progress::set (false);
                Bootloader::Read ();
		Progress::set (progress_status);
	    }
            else if (action == `propose)
	    {
		Bootloader::Reset ();
		if (Bootloader::getLoaderType () == "grub")
		{
		    import "BootGRUB";
		    BootGRUB::merge_level = `all;
		    Bootloader::Propose ();
		    BootGRUB::merge_level = `main;
		}
		else
		{
		    Bootloader::Propose ();
		}
	    }
            else if (action == `prev)
                Bootloader::Import (BootCommon::other_bl[new_bl]:$[]);

	    else if (action == `convert)
	    {
		//filter out uknown type of section e.g. chainloader for elilo etc.
		BootCommon::sections = (list <map<string,any> >)filter(map<string, any> sec, BootCommon::sections, {
			list<string> section_types = Bootloader::blsection_types();
			if (contains(section_types, sec["type"]:"" ))
				return true;
			else
				return false;
		});

	    }

	}
	BootCommon::location_changed = true;
	BootCommon::changed = true;
	return `redraw;
    }
    return nil;
}

/**
 * Validate function of a widget
 * @param widget string widget key
 * @param event map event that caused validation
 * @return boolean true if validation succeeded
 */
boolean LoaderTypeValidate (string widget, map event){
    if (event["ID"]:nil == "sections"
	&& BootCommon::getLoaderType (false) == "none")
    {
	// popup message
	Popup::Message (_("Select the boot loader before editing sections."));
	return false;
    }
    return true;
}


/**
 * Store function of a widget
 * @param widget string widget key
 * @param event map event that caused the operation
 */
void LoaderTypeStore (string widget, map event) {
	boolean ret = false;
	if (BootCommon::globals["trusted_grub"]:"" == "true")
	{
		if ((!Package::Installed("trustedgrub")) && (Mode::normal())) 
		{
			if (! PackageSystem::CheckAndInstallPackages(["trustedgrub"])) 
			{
				if (!Mode::commandline())
					Popup::Error(Message::CannotContinueWithoutPackagesInstalled());
        			y2error("Installation of package trustedgrub failed or aborted");

			}
		}
	}
}

// manual edit button

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

    /**
      * Get map of widget
      * @return a map of widget
      */
    map<string,any> getManualEditWidget () ``{
	return $[
	    "widget" : `custom,
	    "custom_widget" : `HBox (`HStretch (),
		// pushbutton
		`PushButton (`id (`manual), _("E&dit Configuration Files")),
		`HStretch ()
	    ),
	    "handle_events" : [`manual],
	    "handle" : manualEditHandle,
//	    "help" : getManualEditHelp (),
	];
    }

// reset menu button


    /**
      * Init function of widget
      * @param widget any id of the widget
      */
    void resetButtonInit (string widget) ``{
	list items = [];
	items = add (items, `item (
	    `id (`manual),
	    // menu button entry
	    _("E&dit Configuration Files")));
	if (BootCommon::getBooleanAttrib ("propose"))
	{
	    items = add (items,
		// menubutton item, keep as short as possible
		`item (`id (`propose), _("&Propose New Configuration")));
	}
	if (BootCommon::getBooleanAttrib ("scratch"))
	{
	    items = add (items,
		// menubutton item, keep as short as possible
		`item (`id (`scratch), _("&Start from Scratch")));
	}
        if ((Mode::normal () || Mode::config () || Mode::repair ())
	    && BootCommon::getBooleanAttrib ("read"))
	{
	    items = add (items,
		// menubutton item, keep as short as possible
		`item (`id (`reread), _("&Reread Configuration from Disk")));
	}
	list additional_entries = (list)BootCommon::getAnyTypeAttrib (
	    "additional_entries", []);
	items = merge (items, additional_entries);

	if ((Mode::normal () || Mode::repair ())
	    && BootCommon::getBooleanAttrib ("restore_mbr")
	    && SCR::Read (.target.size, "/boot/backup_mbr") > 0)
	{
	    items = add (items,
		// menubutton item, keep as short as possible
		`item (`id (`restore_mbr), _("Restore MBR of Hard Disk")));
	}

	if (Mode::normal () || Mode::repair ())
	{
	    items = add (items,
		// menubutton item, keep as short as possible
		`item (`id (`init), _("Write bootloader boot code to disk")));
	}

	if (size (items) > 0)
	{
	    UI::ReplaceWidget (`id (`adv_rp),
		// menu button
		`MenuButton (`id (`reset), _("Other"), items));
	}
	else
	{
	    UI::ReplaceWidget (`id (`adv_rp), `VSpacing (0));
	}
    }

    /**
      * Handle function of a widget
      * @param widget any widget key
      * @param event map event description of event that occured
      * @return symbol to return to wizard sequencer, or nil
      */
    symbol resetButtonHandle (string widget, map event) ``{
	any op = event["ID"]:nil;
	if (op == `manual)
	{
	    return `manual;
	}
        if (op == `restore_mbr)
        {
            boolean doit = restoreMBRPopup (BootCommon::mbrDisk);
	    y2milestone ("Rewrite MBR with saved one: %1", doit);
	    if (doit)
	    {
		boolean ret = BootCommon::restoreMBR (BootCommon::mbrDisk);
		if (ret)
		    // message popup
		    Popup::Message (_("MBR restored successfully."));
		else
		    // message popup
		    Popup::Message (_("Failed to restore MBR."));
	    }
            return nil;
        }

	if (! (is (op, symbol)
	    && contains ([`scratch, `reread, `propose_deep, `propose],
		(symbol)op)))
	{
	    return nil;
	}
	Bootloader::Reset ();
	if (op == `scratch)
	{
	    y2debug ("Not reading anything for starting from scratch");
	}
	else if (op == `reread)
	{
	    Bootloader::Read ();
	}
	else if (op == `init)
	{
	    // Bootloader::blSave (false, false, false);
	    boolean ret = BootCommon::InitializeBootloader ();
	    if (ret == nil)
		ret = false;

	    if (!ret)
		Popup::Warning(_("Writing bootloader settings failed."));

	}
	else if (op == `propose_deep)
	{
	    import "BootGRUB";
	    BootGRUB::merge_level = `all;
	    Bootloader::Propose ();
	    BootGRUB::merge_level = `main;
	}
	else if (op == `propose)
	{
	    Bootloader::Propose ();
	}

	return `redraw;
    }





/**
 * Get map of widget
 * @return a map of widget
 */
map<string,any> getAdvancedButtonWidget () {
    return $[
	"widget" : `custom,
	"custom_widget" : `ReplacePoint (`id (`adv_rp), `VBox ()),
	"handle" : resetButtonHandle,
	"init" : resetButtonInit,
	"help" : getAdvancedButtonHelp (),
    ];
}

/**
 * Get the main dialog tabs description
 * @return a map the description of the tabs
 */
map TabsDescr () {
    string lt = Bootloader::getLoaderType ();
  return $[
    "sections": $[
	// tab header
	"header" : _("&Section Management"),
        "contents": `HBox (
	    `HSpacing (3), `VBox (
		`VSpacing (1),
		"sections",
		`VSpacing (1)
	    ), `HSpacing (3)),
        "widget_names": ["DisBackButton", "sections"]

    ],
    "installation": $[
	// tab header
	"header" : _("Boot Loader &Installation"),
	"contents" : `HBox (`HStretch (), `VBox (
	    `VStretch (),
	    `Frame (_("Type"), `VBox (
		`VSpacing (0.4),
		`HBox (
		    `HSpacing (2),
		    "loader_type",
		    `HStretch (),
		    `VBox (
			`Label (""),
			 (lt == "none" || lt == "default" || lt == "zipl" || lt == "lilo")
                         ? `Empty()  : "loader_options"
		    ),
		    `HSpacing (2)
		),
		`VSpacing (0.4)
	    )),
	    `VStretch (),
	    (lt == "none" || lt == "default" || lt == "zipl" || lt == "lilo")
		? `Empty ()
		: "loader_location",
	    `VStretch (),
	    (lt != "grub")
		? `Empty ()
		: "inst_details",
	    `VStretch ()
	), `HStretch ()),
        "widget_names": (lt == "none" || lt == "default" || lt=="zipl")
	    ? [ "loader_type", "loader_options"]
	    : [ "loader_type", "loader_options", "loader_location",
	    "inst_details"]
    ],
  ];
};

/**
 * Cache for CommonGlobalWidgets function
 */
map<string,map<string,any> > _common_global_widgets = nil;

/**
 * Get general widgets for global bootloader options
 * @return a map describing all general widgets for global options
 */
map<string,map<string,any> > CommonGlobalWidgets () {
  if (_common_global_widgets != nil)
	return _common_global_widgets;
  _common_global_widgets = $[
    "adv_button"	: getAdvancedButtonWidget (),
    "sections" : getSectionsWidget (),
    "loader_type" : $[
	"widget" : `func,
	"widget_func" : LoaderTypeComboWidget,
	"init" : LoaderTypeComboInit,
	"handle" : LoaderTypeComboHandle,
	"help" : LoaderTypeHelp (),
	"store": LoaderTypeStore,
	"validate_type" : `function,
	"validate_function" : LoaderTypeValidate,
    ],
    "loader_options" : $[
	"widget" : `push_button,
	// push button
	"label" : _("Boot &Loader Options"),
	"handle_events" : ["loader_options"],
	"handle" : LoaderOptionsButtonHandle,
	"help" : LoaderOptionsHelp (),
    ],
    //FIXME: after deleting all using of metadata delete widget from
    // from CommonGlobalWidgets the button is only for GRUB...
    "inst_details" : $[
	"widget" : `push_button,
	// push button
	"label" : _("Boot Loader Installation &Details"),
	"handle_events" : ["inst_details"],
	"handle" : InstDetailsButtonHandle,
	"help" : InstDetailsHelp (),
    ],

  ];



  return _common_global_widgets;
}

} // include end

ACC SHELL 2018