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 / include / bootloader / routines / global_widgets.ycp < prev    next >
Text File  |  2006-11-29  |  25KB  |  957 lines

  1. /**
  2.  * File:
  3.  *      include/bootloader/routines/widgets.ycp
  4.  *
  5.  * Module:
  6.  *      Bootloader installation and configuration
  7.  *
  8.  * Summary:
  9.  *      Common widgets for being used by several bootloaders
  10.  *
  11.  * Authors:
  12.  *      Jiri Srain <jsrain@suse.cz>
  13.  *
  14.  * $Id: global_widgets.ycp 33156 2006-09-27 00:26:18Z odabrunz $
  15.  *
  16.  */
  17.  
  18.  
  19. {
  20.  
  21. textdomain "bootloader";
  22.  
  23. import "CWM";
  24. import "CWMTab";
  25. import "Label";
  26. import "Mode";
  27. import "Storage";
  28. import "StorageDevices";
  29. import "Bootloader";
  30. import "Progress";
  31.  
  32. include "bootloader/routines/helps.ycp";
  33.  
  34. /**
  35.  * Init function of widget
  36.  * @param widget string id of the widget
  37.  */
  38. void GlobalOptionInit (string widget) {
  39.     if (widget == "adv_button")
  40.     return;
  41.     UI::ChangeWidget (`id (widget), `Value, BootCommon::globals[widget]:"");
  42. }
  43.  
  44. /**
  45.  * Store function of a widget
  46.  * @param widget string widget key
  47.  * @param event map event that caused the operation
  48.  */
  49. void GlobalOptionStore (string widget, map event) {
  50.     if (widget == "adv_button")
  51.     return;
  52.     BootCommon::globals[widget] = (string)
  53.     UI::QueryWidget (`id (widget), `Value);
  54. }
  55.  
  56. /**
  57.  * Map of default (fallback) handlers for widget events on global widgets
  58.  */
  59. map<string,any> global_handlers = $[
  60.     "init" : GlobalOptionInit,
  61.     "store" : GlobalOptionStore,
  62. ];
  63.  
  64. /**
  65.  * Handle function of a widget
  66.  * @param widget string widget key
  67.  * @param event map event description of event that occured
  68.  * @return symbol to return to wizard sequencer, or nil
  69.  */
  70. symbol InstDetailsButtonHandle (string widget, map event) {
  71.     string lt = Bootloader::getLoaderType ();
  72.     if (lt == "none" || lt == "default")
  73.     {
  74.     NoLoaderAvailable ();
  75.     return nil;
  76.     }
  77.     return `inst_details;
  78. }
  79.  
  80. /**
  81.  * Handle function of a widget
  82.  * @param widget string widget key
  83.  * @param event map event description of event that occured
  84.  * @return symbol to return to wizard sequencer, or nil
  85.  */
  86. symbol LoaderOptionsButtonHandle (string widget, map event) {
  87.     string lt = Bootloader::getLoaderType ();
  88.     if (lt == "none" || lt == "default")
  89.     {
  90.     NoLoaderAvailable ();
  91.     return nil;
  92.     }
  93.     return `loader_details;
  94. }
  95.  
  96. // sections list widget
  97.  
  98.  
  99. /**
  100.  * Refresh and redraw widget wits sections
  101.  * @param sects list of current sections
  102.  */
  103. void RedrawSectionsTable (list<map<string,any> > sects) {
  104.     boolean elilo = Bootloader::getLoaderType () == "elilo";
  105.     list sec = maplist (map<string,any> s, sects, {
  106.     string image = s["kernel"]:"";
  107.     string root = (BootCommon::getHintedPartitionList ([s["root"]:""]))[0]:"";
  108.         return `item (`id (s["name"]:""),
  109.         tolower (BootCommon::globals["default"]:"")
  110.             == tolower (s["name"]:"")
  111.         ? UI::Glyph (`CheckMark) : "",
  112.         s["name"]:"",
  113.         (image == nil || image == "")
  114.         // table header
  115.         ? _("Other")
  116.         // table header
  117.         : _("Image"),
  118.         (image != "" && image != nil)
  119.         ? sformat ("%1   (%2%3)",
  120.             image,
  121.             elilo
  122.             ? ""
  123.             : BootCommon::splitPath (image)[0]:"",
  124.             root == "" ? ""
  125.             : ((elilo ? "" : ", ")
  126.             + sformat ("root=%1", root)))
  127.         : s["chainloader"]:""
  128.         );
  129.     });
  130.     UI::ChangeWidget (`id (`sects), `Items, sec);
  131. }
  132.  
  133. /**
  134.  * Init function of widget
  135.  * @param widget string id of the widget
  136.  */
  137. void SectionsInit (string widget) {
  138.     RedrawSectionsTable (BootCommon::sections);
  139.     UI::SetFocus (`id (`sects));
  140. }
  141.  
  142.  
  143. /**
  144.  * Handle function of a widget
  145.  * @param widget string widget key
  146.  * @param event map event description of event that occured
  147.  * @return symbol to return to wizard sequencer, or nil
  148.  */
  149. symbol SectionsHandle (string widget, map event) {
  150.     any op = event["ID"]:nil;
  151.     if (event["ID"]:nil == `sects
  152.     && event["EventReason"]:"" == "Activated"
  153.     && event["EventType"]:"" == "WidgetEvent")
  154.     {
  155.     op = `edit;
  156.     }
  157.     y2milestone ("Handling sections widget, event %1", op);
  158.     string current = (string)UI::QueryWidget (`id (`sects), `CurrentItem);
  159.     integer counter = 0;
  160.     integer index = 0;
  161.     foreach (map<string,any> s, BootCommon::sections, {
  162.     if (s["name"]:"" == current)
  163.         index = counter;
  164.     counter = counter + 1;
  165.     });
  166.     list<map<string,any> > sects = BootCommon::sections;
  167.     if (op == `up)
  168.     {
  169.     if (index > 0)
  170.     {
  171.         sects = (list<map<string,any > >)
  172.         BootCommon::swapItems(sects, index, index - 1);
  173.         index = index - 1;
  174.         BootCommon::sections = sects;
  175.         RedrawSectionsTable (sects);
  176.         UI::ChangeWidget (`id (`sects), `CurrentItem,
  177.         sects[index, "name"]:"");
  178.         BootCommon::changed = true;
  179.     }
  180.     }
  181.     else if (op == `down)
  182.     {
  183.     if (index < (size(sects) - 1))
  184.     {
  185.         sects = (list<map<string,any> >)
  186.         BootCommon::swapItems(sects, index, index + 1);
  187.         index = index + 1;
  188.         BootCommon::sections = sects;
  189.         RedrawSectionsTable (sects);
  190.         UI::ChangeWidget (`id (`sects), `CurrentItem,
  191.         sects[index, "name"]:"");
  192.         BootCommon::changed = true;
  193.     }
  194.     }
  195.     else if (op == `default)
  196.     {
  197.     BootCommon::globals["default"] = current;
  198.     RedrawSectionsTable (sects);
  199.     UI::ChangeWidget (`id (`sects), `CurrentItem, current);
  200.     BootCommon::changed = true;
  201.     }
  202.     else if (op == `add || op == `edit)
  203.     {
  204.     map<string,any> selected = sects[index]:$[];
  205.     string name = selected["name"]:"";
  206.     BootCommon::current_section = selected;
  207.     BootCommon::current_section_index = op == `add ? -1 : index;
  208.     BootCommon::current_section_name = name;
  209.     y2internal ("Selected section: %1", BootCommon::current_section);
  210.     return (symbol)op;
  211.     }
  212.     else if (op == `delete && confirmSectionDeletePopup (current))
  213.     {
  214.     BootCommon::removed_sections = add (BootCommon::removed_sections,
  215.         sects[index, "original_name"]:"");
  216.     sects = remove (sects, index);
  217.     if (current == BootCommon::globals["default"]:"")
  218.     {
  219.         BootCommon::globals["default"] = BootCommon::sections[0, "name"]:"";
  220.     }
  221.     BootCommon::sections = sects;
  222.     RedrawSectionsTable (sects);
  223.     BootCommon::changed = true;
  224.     }
  225.     UI::SetFocus (`id (`sects));
  226.     return nil;
  227. }
  228.  
  229. /**
  230.  * Get map of widget
  231.  * @return a map of widget
  232.  */
  233. map<string,any> getSectionsWidget () {
  234.     return $[
  235.     "widget" : `custom,
  236.     "custom_widget" : `VBox (
  237.         `HBox (
  238.         `Table (`id (`sects),
  239.             `opt (`keepSorting, `notify),
  240.             `header (
  241.             // table header, Def stands for default
  242.             _("Def."),
  243.             // table header
  244.             _("Label"),
  245.             // table header
  246.             _("Type"),
  247.             // table header; header for section details, either
  248.             // the specification of the kernel image to load,
  249.             // or the specification of device to boot from
  250.             _("Image / Device")
  251.             ), []),
  252.         `HSpacing (1),
  253.         `VBox (
  254.             `VStretch (),
  255.             // pushbutton
  256.             `PushButton (`id (`up), _("&Up")),
  257.             // pushbutton
  258.             `PushButton (`id (`down), _("&Down")),
  259.             `VStretch ()
  260.         )
  261.         ),
  262.         `HBox (
  263.         `PushButton (`id (`add), `opt (`key_F3), Label::AddButton ()),
  264.         `PushButton (`id (`edit), `opt (`key_F4), Label::EditButton ()),
  265.         `PushButton (`id (`delete), `opt (`key_F5),
  266.             Label::DeleteButton ()),
  267.         `HStretch (),
  268.         // pushbutton
  269.         `PushButton (`id (`default), _("Set as De&fault"))
  270.         )
  271.     ),
  272.     "init" : SectionsInit,
  273.     "handle" : SectionsHandle,
  274.     "help" : SectionsHelp (),
  275.     ];
  276. }
  277.  
  278.  
  279.  
  280. // loader type widget
  281.  
  282. /**
  283.  * Get the widget for boot laoder selection combo
  284.  * @return term the widget
  285.  */
  286. term LoaderTypeComboWidget () {
  287.     return `ComboBox (`id ("loader_type"),
  288.     `opt (`notify),
  289.     // combo box
  290.     _("&Boot Loader"),
  291.     maplist (string l, BootCommon::getBootloaders (), {
  292.         return `item (`id (l), BootCommon::getLoaderName (l, `combo));
  293.     }));
  294. }
  295.  
  296. /**
  297.  * Init function of widget
  298.  * @param widget string id of the widget
  299.  */
  300. void LoaderTypeComboInit (string widget) {
  301.     UI::ChangeWidget (`id (widget), `Value, Bootloader::getLoaderType ());
  302. }
  303.  
  304. /**
  305.  * Handle function of a widget
  306.  * @param key any widget key
  307.  * @param event map event description of event that occured
  308.  * @return symbol to return to wizard sequencer, or nil
  309.  */
  310. symbol LoaderTypeComboHandle (string key, map event) {
  311.     if (event["ID"]:nil == key)
  312.     {
  313.     string old_bl = Bootloader::getLoaderType ();
  314.     string new_bl = (string)UI::QueryWidget (`id (key), `Value);
  315.     if (old_bl == new_bl)
  316.         return nil;
  317.  
  318.     if (new_bl == "none")
  319.     {
  320.         // popup - Continue/Cancel
  321.         if (Popup::ContinueCancel (_("
  322. If you do not install any boot loader, the system
  323. might not start.
  324.  
  325. Proceed?
  326. ")))
  327.         {
  328.         BootCommon::other_bl[old_bl] = Bootloader::Export ();
  329.         BootCommon::setLoaderType ("none");
  330.         BootCommon::location_changed = true;
  331.         }
  332.         return `redraw;
  333.     }
  334.  
  335.     // warning - popup, followed by radio buttons
  336.     string label = _("
  337. You chose to change your boot loader. When converting 
  338. the configuration, some settings might be lost.
  339.  
  340. The current configuration will be saved and you can
  341. restore it if you return to the current boot loader.
  342.  
  343. Select a course of action:
  344. ");
  345.  
  346.     term contents = `VBox (
  347.         // warning label
  348.         `Label (label),
  349.         `VSpacing (1),
  350.         `RadioButtonGroup (`id (`action), `VBox (
  351.         `Left (`RadioButton (`id (`propose),
  352.             // radiobutton
  353.             _("&Propose New Configuration"))),
  354.         `Left (`RadioButton (`id (`convert),
  355.             // radiobutton
  356.             _("Co&nvert Current Configuration"))),
  357.         Stage::initial () ? `VSpacing (0)
  358.         : `Left (`RadioButton (`id (`scratch),
  359.             // radiobutton
  360.             _("&Start New Configuration from Scratch"))),
  361.         Mode::normal ()
  362.             ? `Left (`RadioButton (`id (`read),
  363.             // radiobutton
  364.             _("&Read Configuration Saved on Disk")))
  365.             : `VSpacing (0),
  366.         BootCommon::other_bl[new_bl]:nil == nil || Stage::initial ()
  367.             ? `VSpacing (0)
  368.             : `Left (`RadioButton (`id (`prev),
  369.             // radiobutton
  370.             _("Res&tore Configuration Saved before Conversion")))
  371.         )),
  372.     `VSpacing (1),
  373.     `HBox (
  374.         `HStretch (),
  375.         `PushButton (`id (`ok), `opt (`key_F10), Label::OKButton ()),
  376.         `HSpacing (1),
  377.         `PushButton (`id (`cancel), `opt (`key_F9), Label::CancelButton ()),
  378.         `HStretch ()
  379.     ));
  380.     UI::OpenDialog (contents);
  381.     symbol def = `propose;
  382.     UI::ChangeWidget (`id (def), `Value, true);
  383.     symbol ret = (symbol)UI::UserInput ();
  384.     symbol action = (symbol)UI::QueryWidget (`id (`action), `CurrentButton);
  385.     UI::CloseDialog ();
  386.     if (ret != `ok)
  387.         return nil;
  388.  
  389.     if (nil != action)
  390.     {
  391.         y2milestone ("Switching bootloader");
  392.         if (old_bl != "none")
  393.         BootCommon::other_bl[old_bl] = Bootloader::Export ();
  394.         BootCommon::setLoaderType (new_bl);
  395.  
  396.             if (action == `scratch)
  397.         Bootloader::Reset ();
  398.             else if (action == `read)
  399.         {
  400.         boolean progress_status = Progress::set (false);
  401.                 Bootloader::Read ();
  402.         Progress::set (progress_status);
  403.         }
  404.             else if (action == `propose)
  405.         {
  406.         Bootloader::Reset ();
  407.         if (Bootloader::getLoaderType () == "grub")
  408.         {
  409.             import "BootGRUB";
  410.             BootGRUB::merge_level = `all;
  411.             Bootloader::Propose ();
  412.             BootGRUB::merge_level = `main;
  413.         }
  414.         else
  415.         {
  416.             Bootloader::Propose ();
  417.         }
  418.         }
  419.             else if (action == `prev)
  420.                 Bootloader::Import (BootCommon::other_bl[new_bl]:$[]);
  421.  
  422.     }
  423.     BootCommon::location_changed = true;
  424.     BootCommon::changed = true;
  425.     return `redraw;
  426.     }
  427.     return nil;
  428. }
  429.  
  430. /**
  431.  * Validate function of a widget
  432.  * @param widget string widget key
  433.  * @param event map event that caused validation
  434.  * @return boolean true if validation succeeded
  435.  */
  436. boolean LoaderTypeValidate (string widget, map event){
  437.     if (event["ID"]:nil == "sections"
  438.     && BootCommon::getLoaderType (false) == "none")
  439.     {
  440.     // popup message
  441.     Popup::Message (_("Select the boot loader before editing sections."));
  442.     return false;
  443.     }
  444.     return true;
  445. }
  446.  
  447. // loader target widget
  448.  
  449. /**
  450.  * Get the target widget to be displayed
  451.  * @return term widget to be displayed
  452.  */
  453. term TargetWidget () {
  454.     string lt = Bootloader::getLoaderType ();
  455.     if (lt == "none" || lt == "default")
  456.     {
  457.     return `Empty ();
  458.     }
  459.     list<string> boot_devices = BootCommon::getPartitionList(`boot);
  460.     boolean allow_boot = contains (boot_devices,
  461.     BootCommon::BootPartitionDevice);
  462.     boolean allow_root = contains (boot_devices,
  463.     BootCommon::RootPartitionDevice);
  464.     boolean all_mbr = size (BootCommon::Md2Partitions (
  465.     BootCommon::BootPartitionDevice)) > 1;
  466.  
  467.     term targetlist = `VBox (
  468.     `VSpacing (0.4),
  469.     `Left (`RadioButton (`id ("mbr"), `opt (`notify),
  470.         BootCommon::mbrDisk == ""
  471.             // radio button
  472.             ? _("&Master Boot Record")
  473.             // radiobutton, %1 is device (eg. /dev/hda)
  474.             : sformat(_("&Master Boot Record of %1"),
  475.             BootCommon::mbrDisk),
  476.                 (BootCommon::selected_location == "mbr")
  477.     ))
  478.     );
  479.  
  480.     if (all_mbr && Bootloader::getLoaderType () == "grub")
  481.     {
  482.         list<string> mbrs = maplist (string d, integer id,
  483.         BootCommon::Md2Partitions (BootCommon::BootPartitionDevice),
  484.         {
  485.         map p_dev = Storage::GetDiskPartition (d);
  486.         return p_dev["disk"]:"";
  487.         });
  488.         mbrs = toset (mbrs);
  489.         targetlist = add (targetlist, `VSpacing (0.4));
  490.             targetlist = add (targetlist, `Left (
  491.         `RadioButton (`id ("mbr_md"), `opt (`notify),
  492.         // radiobutton, %1 is a list of devices (eg. /dev/hda1)
  493.                 sformat(_("MB&Rs of Disks %1"),
  494.             mergestring (mbrs, ", ")),
  495.                 (BootCommon::selected_location == "mbr_md")
  496.             )));
  497.     }
  498.     if (allow_boot)
  499.     {
  500.         targetlist = add (targetlist, `VSpacing (0.4));
  501.             targetlist = add (targetlist, `Left (
  502.         `RadioButton (`id ("boot"), `opt (`notify),
  503.         // radiobutton, %1 is device (eg. /dev/hda1)
  504.                 sformat(_("Boot &Sector of Boot Partition %1"),
  505.                      BootCommon::BootPartitionDevice),
  506.                 (BootCommon::selected_location == "boot")
  507.             )));
  508.     };
  509.     if (allow_root
  510.     && BootCommon::BootPartitionDevice != BootCommon::RootPartitionDevice)
  511.     {
  512.         targetlist = add (targetlist, `VSpacing (0.4));
  513.         targetlist = add (targetlist, `Left (
  514.         `RadioButton (`id ("root"), `opt (`notify),
  515.         // radiobutton, %1 is device (eg. /dev/hda1)
  516.                 sformat(_("Boot Sector of Roo&t Partition %1"),
  517.                     BootCommon::RootPartitionDevice),
  518.                 (BootCommon::selected_location == "root")
  519.             )));
  520.     };
  521.  
  522.     if (StorageDevices::FloppyPresent)
  523.     {
  524.             targetlist = add (targetlist, `VSpacing (1));
  525.             targetlist = add (targetlist, `Left (`RadioButton (`id ("floppy"),
  526.          `opt (`notify),
  527.         // radiobutton, %1 is device name, typically /dev/fd0
  528.                 sformat (_("&Floppy Disk %1"), StorageDevices::FloppyDevice),
  529.                 (BootCommon::selected_location == "floppy")
  530.             )));
  531.     }
  532.  
  533.     targetlist = add (targetlist, `HBox (
  534.             `VBox (`Label (""), `RadioButton (`id ("custom"), `opt (`notify),
  535.         // radiobutton
  536.         _("Ot&her"),
  537.                 (BootCommon::selected_location == "custom"))),
  538.             `HSpacing (2),
  539.             `VBox (
  540.                 `ComboBox (`id (`loc), `opt (`editable, `hstretch, `notify, `notify, `immediate), "",
  541.             boot_devices),
  542.                 `HSpacing (15)
  543.             ),
  544.             `HStretch ()
  545.     ));
  546.  
  547.     targetlist = add (targetlist, `VSpacing (0.4));
  548.  
  549.     // frame
  550.     term widget = `Frame (_("Boot Loader Location"),
  551.     `RadioButtonGroup (`id (`location),
  552.         targetlist
  553.     )
  554.     );
  555.     return widget;
  556. }
  557.  
  558. /**
  559.  * Init function of a widget
  560.  * @param widget string widget key
  561.  */
  562. void TargetInit (string widget) {
  563.     string lt = Bootloader::getLoaderType ();
  564.     if (lt == "none" || lt == "default")
  565.     {
  566.     return;
  567.     }
  568.     if (BootCommon::BootPartitionDevice == BootCommon::RootPartitionDevice
  569.     && BootCommon::selected_location == "root")
  570.     {
  571.     BootCommon::selected_location = "boot";
  572.     }
  573.     if (BootCommon::loader_device != "mbr_md")
  574.     UI::ChangeWidget (`id (`loc), `Value, BootCommon::loader_device == "mbr_md"
  575.     ? BootCommon::getPartitionList(`boot)[0]:""
  576.     : BootCommon::loader_device);
  577.     UI::ChangeWidget (`id (`location), `CurrentButton,
  578.     BootCommon::selected_location);
  579.     UI::SetFocus (`id (`loc));
  580. }
  581.  
  582. symbol TargetHandle (string widget, map event) {
  583.     UI::ChangeWidget (`id (`location), `CurrentButton, "custom");
  584.     return nil;
  585. }
  586.  
  587. /**
  588.  * Store function of a widget
  589.  * @param widget string widget key
  590.  * @param event map event that caused the operation
  591.  */
  592. void TargetStore (string widget, map event) {
  593.     string lt = Bootloader::getLoaderType ();
  594.     if (lt == "none" || lt == "default")
  595.     {
  596.     return;
  597.     }
  598.     BootCommon::selected_location = (string)
  599.     UI::QueryWidget (`id (`location), `CurrentButton);
  600.     BootCommon::loader_device = (string)UI::QueryWidget (`id (`loc), `Value);
  601.     BootCommon::loader_device = BootCommon::GetBootloaderDevice ();
  602.     BootCommon::location_changed = true;
  603.     BootCommon::changed = true;
  604. }
  605.  
  606. /**
  607.  * Validate function of a widget
  608.  * @param widget string widget key
  609.  * @param event map event that caused validation
  610.  * @return boolean true if validation succeeded
  611.  */
  612. boolean TargetValidate (string widget, map event){
  613.     string lt = Bootloader::getLoaderType ();
  614.     if (lt == "none" || lt == "default")
  615.     {
  616.     return true;
  617.     }
  618.     string rb = (string)UI::QueryWidget (`id (`location), `CurrentButton);
  619.     if (rb == nil)
  620.     {
  621.     setLocationErrorPopup ();
  622.     UI::SetFocus (`id (`location));
  623.     return false;
  624.     }
  625.     if (rb == "custom" && UI::QueryWidget (`id (`loc), `Value) == "")
  626.     {
  627.     setLocationErrorPopup ();
  628.     UI::SetFocus (`id (`loc));
  629.     return false;
  630.     }
  631.     if (rb == "custom")
  632.     {
  633.     boolean ok = true;
  634.     string ld = (string)UI::QueryWidget (`id (`loc), `Value);
  635.     map<string,map> tm = Storage::GetTargetMap ();
  636.     foreach (string disk_dev, map disk, tm, {
  637.         list<map<string,any> > partitions
  638.         = (list<map<string,any> >) disk["partitions"]:[];
  639.         foreach (map<string,any> p, partitions, {
  640.         if (! p["delete"]:false)
  641.         {
  642.             symbol fs = (symbol)(p["used_fs"]:p["detected_fs"]:nil);
  643.             // FIXME this checking is performed on 3 places
  644.             if (p["device"]:"" == ld && fs == `xfs)
  645.             {
  646.             // yes-no popup
  647.             if (! Popup::YesNo (_("The partition selected for boot loader installation
  648. does not have enough free space in its boot sector
  649. to hold the boot loader because of the file system
  650. it contains. Using this partition for the boot loader
  651. may lead to corruption of data on the partition.
  652.  
  653. Continue?")))
  654.             {
  655.                 UI::SetFocus (`id (`loc));
  656.                 ok = false;
  657.             }
  658.             }
  659.         }
  660.         });
  661.     });
  662.     if (! ok)
  663.         return false;
  664.     }
  665.     return true;
  666. }
  667.  
  668.  
  669. // manual edit button
  670.  
  671.     /**
  672.       * Handle function of a widget
  673.       * @param key any widget key
  674.       * @param event map event description of event that occured
  675.       * @return symbol to return to wizard sequencer, or nil
  676.       */
  677.     symbol manualEditHandle(string key, map event)``{
  678.     return `manual;
  679.     }
  680.  
  681.     /**
  682.       * Get map of widget
  683.       * @return a map of widget
  684.       */
  685.     map<string,any> getManualEditWidget () ``{
  686.     return $[
  687.         "widget" : `custom,
  688.         "custom_widget" : `HBox (`HStretch (),
  689.         // pushbutton
  690.         `PushButton (`id (`manual), _("E&dit Configuration Files")),
  691.         `HStretch ()
  692.         ),
  693.         "handle_events" : [`manual],
  694.         "handle" : manualEditHandle,
  695. //        "help" : getManualEditHelp (),
  696.     ];
  697.     }
  698.  
  699. // reset menu button
  700.  
  701.  
  702.     /**
  703.       * Init function of widget
  704.       * @param widget any id of the widget
  705.       */
  706.     void resetButtonInit (string widget) ``{
  707.     list items = [];
  708.     items = add (items, `item (
  709.         `id (`manual),
  710.         // menu button entry
  711.         _("E&dit Configuration Files")));
  712.     if (BootCommon::getBooleanAttrib ("propose"))
  713.     {
  714.         items = add (items,
  715.         // menubutton item, keep as short as possible
  716.         `item (`id (`propose), _("&Propose New Configuration")));
  717.     }
  718.     if (BootCommon::getBooleanAttrib ("scratch"))
  719.     {
  720.         items = add (items,
  721.         // menubutton item, keep as short as possible
  722.         `item (`id (`scratch), _("&Start from Scratch")));
  723.     }
  724.         if ((Mode::normal () || Mode::config () || Mode::repair ())
  725.         && BootCommon::getBooleanAttrib ("read"))
  726.     {
  727.         items = add (items,
  728.         // menubutton item, keep as short as possible
  729.         `item (`id (`reread), _("&Reread Configuration from Disk")));
  730.     }
  731.     list additional_entries = (list)BootCommon::getAnyTypeAttrib (
  732.         "additional_entries", []);
  733.     items = merge (items, additional_entries);
  734.  
  735.     if ((Mode::normal () || Mode::repair ())
  736.         && BootCommon::getBooleanAttrib ("restore_mbr")
  737.         && SCR::Read (.target.size, "/boot/backup_mbr") > 0)
  738.     {
  739.         items = add (items,
  740.         // menubutton item, keep as short as possible
  741.         `item (`id (`restore_mbr), _("Restore MBR of Hard Disk")));
  742.     }
  743.  
  744.     if (Mode::normal () || Mode::repair ())
  745.     {
  746.         items = add (items,
  747.         // menubutton item, keep as short as possible
  748.         `item (`id (`init), _("Write bootloader boot code to disk")));
  749.     }
  750.  
  751.     if (size (items) > 0)
  752.     {
  753.         UI::ReplaceWidget (`id (`adv_rp),
  754.         // menu button
  755.         `MenuButton (`id (`reset), _("Other"), items));
  756.     }
  757.     else
  758.     {
  759.         UI::ReplaceWidget (`id (`adv_rp), `VSpacing (0));
  760.     }
  761.     }
  762.  
  763.     /**
  764.       * Handle function of a widget
  765.       * @param widget any widget key
  766.       * @param event map event description of event that occured
  767.       * @return symbol to return to wizard sequencer, or nil
  768.       */
  769.     symbol resetButtonHandle (string widget, map event) ``{
  770.     any op = event["ID"]:nil;
  771.     if (op == `manual)
  772.     {
  773.         return `manual;
  774.     }
  775.         if (op == `restore_mbr)
  776.         {
  777.             boolean doit = restoreMBRPopup (BootCommon::mbrDisk);
  778.         y2milestone ("Rewrite MBR with saved one: %1", doit);
  779.         if (doit)
  780.         {
  781.         boolean ret = BootCommon::restoreMBR (BootCommon::mbrDisk);
  782.         if (ret)
  783.             // message popup
  784.             Popup::Message (_("MBR restored successfully."));
  785.         else
  786.             // message popup
  787.             Popup::Message (_("Failed to restore MBR."));
  788.         }
  789.             return nil;
  790.         }
  791.  
  792.     if (! (is (op, symbol)
  793.         && contains ([`scratch, `reread, `propose_deep, `propose],
  794.         (symbol)op)))
  795.     {
  796.         return nil;
  797.     }
  798.     Bootloader::Reset ();
  799.     if (op == `scratch)
  800.     {
  801.         y2debug ("Not reading anything for starting from scratch");
  802.     }
  803.     else if (op == `reread)
  804.     {
  805.         Bootloader::Read ();
  806.     }
  807.     else if (op == `init)
  808.     {
  809.         // Bootloader::blSave (false, false, false);
  810.         BootCommon::InitializeBootloader ();
  811.     }
  812.     else if (op == `propose_deep)
  813.     {
  814.         import "BootGRUB";
  815.         BootGRUB::merge_level = `all;
  816.         Bootloader::Propose ();
  817.         BootGRUB::merge_level = `main;
  818.     }
  819.     else if (op == `propose)
  820.     {
  821.         Bootloader::Propose ();
  822.     }
  823.  
  824.     return `redraw;
  825.     }
  826.  
  827.  
  828.  
  829.  
  830.  
  831. /**
  832.  * Get map of widget
  833.  * @return a map of widget
  834.  */
  835. map<string,any> getAdvancedButtonWidget () {
  836.     return $[
  837.     "widget" : `custom,
  838.     "custom_widget" : `ReplacePoint (`id (`adv_rp), `VBox ()),
  839.     "handle" : resetButtonHandle,
  840.     "init" : resetButtonInit,
  841.     "help" : getAdvancedButtonHelp (),
  842.     ];
  843. }
  844.  
  845.  
  846. /**
  847.  * Get the main dialog tabs description
  848.  * @return a map the description of the tabs
  849.  */
  850. map TabsDescr () {
  851.     string lt = Bootloader::getLoaderType ();
  852.   return $[
  853.     "sections": $[
  854.     // tab header
  855.     "header" : _("&Section Management"),
  856.         "contents": `HBox (
  857.         `HSpacing (3), `VBox (
  858.         `VSpacing (1),
  859.         "sections",
  860.         `VSpacing (1)
  861.         ), `HSpacing (3)),
  862.         "widget_names": ["sections"]
  863.     ],
  864.     "installation": $[
  865.     // tab header
  866.     "header" : _("Boot Loader &Installation"),
  867.     "contents" : `HBox (`HStretch (), `VBox (
  868.         `VStretch (),
  869.         `Frame (_("Type"), `VBox (
  870.         `VSpacing (0.4),
  871.         `HBox (
  872.             `HSpacing (2),
  873.             "loader_type",
  874.             `HStretch (),
  875.             `VBox (
  876.             `Label (""),
  877.             "loader_options"
  878.             ),
  879.             `HSpacing (2)
  880.         ),
  881.         `VSpacing (0.4)
  882.         )),
  883.         `VStretch (),
  884.         (lt == "none" || lt == "default")
  885.         ? `Empty ()
  886.         : "loader_location",
  887.         `VStretch (),
  888.         (lt == "none" || lt == "default")
  889.         ? `Empty ()
  890.         : "inst_details",
  891.         `VStretch ()
  892.     ), `HStretch ()),
  893.         "widget_names": (lt == "none" || lt == "default")
  894.         ? [ "loader_type", "loader_options" ]
  895.         : [ "loader_type", "loader_options", "loader_location",
  896.         "inst_details" ]
  897.     ],
  898.   ];
  899. };
  900.  
  901. /**
  902.  * Cache for CommonGlobalWidgets function
  903.  */
  904. map<string,map<string,any> > _common_global_widgets = nil;
  905.  
  906. /**
  907.  * Get general widgets for global bootloader options
  908.  * @return a map describing all general widgets for global options
  909.  */
  910. map<string,map<string,any> > CommonGlobalWidgets () {
  911.   if (_common_global_widgets != nil)
  912.     return _common_global_widgets;
  913.   _common_global_widgets = $[
  914.     "adv_button"    : getAdvancedButtonWidget (),
  915.     "sections" : getSectionsWidget (),
  916.     "loader_type" : $[
  917.     "widget" : `func,
  918.     "widget_func" : LoaderTypeComboWidget,
  919.     "init" : LoaderTypeComboInit,
  920.     "handle" : LoaderTypeComboHandle,
  921.     "help" : LoaderTypeHelp (),
  922.     "validate_type" : `function,
  923.     "validate_function" : LoaderTypeValidate,
  924.     ],
  925.     "loader_options" : $[
  926.     "widget" : `push_button,
  927.     // push button
  928.     "label" : _("Boot &Loader Options"),
  929.     "handle_events" : ["loader_options"],
  930.     "handle" : LoaderOptionsButtonHandle,
  931.     "help" : LoaderOptionsHelp (),
  932.     ],
  933.     "loader_location" : $[
  934.     "widget" : `func,
  935.     "widget_func" : TargetWidget,
  936.     "init" : TargetInit,
  937.     "handle" : TargetHandle,
  938.     "handle_events" : [ `loc ],
  939.     "store" : TargetStore,
  940.     "help" : LocationsHelp (),
  941.     "validate_type" : `function,
  942.     "validate_function" : TargetValidate,
  943.     ],
  944.     "inst_details" : $[
  945.     "widget" : `push_button,
  946.     // push button
  947.     "label" : _("Boot Loader Installation &Details"),
  948.     "handle_events" : ["inst_details"],
  949.     "handle" : InstDetailsButtonHandle,
  950.     "help" : InstDetailsHelp (),
  951.     ],
  952.   ];
  953.   return _common_global_widgets;
  954. }
  955.  
  956. } // include end
  957.