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 / partitioning / custom_part_dialogs.ycp < prev    next >
Text File  |  2006-11-29  |  47KB  |  1,704 lines

  1. /*
  2.  *************************************************************
  3.  *
  4.  *     YaST2      SuSE Labs                        -o)
  5.  *     --------------------                        /\\
  6.  *                                                _\_v
  7.  *           www.suse.de / www.suse.com
  8.  * ----------------------------------------------------------
  9.  *
  10.  * Author:        Michael Hager <mike@suse.de>
  11.  *                Johannes Buchhold <jbuch@suse.de>
  12.  *
  13.  *
  14.  * Description:   Partitioner for experts.
  15.  *                include for dialogs
  16.  *
  17.  *************************************************************
  18.  
  19.  $Id: custom_part_dialogs.ycp 33576 2006-10-23 13:25:11Z fehr $
  20.  
  21. */
  22. {
  23.   textdomain "storage";
  24.  
  25.   import "Storage";
  26.   import "Partitions";
  27.   import "FileSystems";
  28.   import "Mode";
  29.   import "Arch";
  30.   import "Label";
  31.  
  32.   //////////////////////////////////////////////////////////////////////////////
  33.   // Dialog Password for Crypted FS
  34.   //////////////////////////////////////////////////////////////////////////////
  35.  
  36.   include "partitioning/partition_defines.ycp";
  37.   include "partitioning/custom_part_helptexts.ycp";
  38.  
  39.   include "partitioning/signatures.ycp";
  40.  
  41.  
  42. define string DlgCreateCryptFs( string device, integer minpwlen, boolean format )
  43.   ``{
  44.     string helptext = GetCreateCryptFsHelptext(minpwlen, format);
  45.     y2milestone( "DlgCreateCryptFs minpwlen:%1 format:%2", minpwlen, format );
  46.  
  47.     // heading text
  48.     string h = _("Enter your password for the encrypted file system");
  49.  
  50.     if( size(device)>0 )
  51.     // heading text, %1 is replaced by device name (e.g. /dev/hda1)
  52.     h = sformat( _("Password for Encrypted File System on %1"), device );
  53.  
  54.     UI::OpenDialog(
  55.          `opt(`decorated ),
  56.          `HBox(
  57.            `HWeight(3, `RichText( helptext ) ),
  58.            `HWeight(6, `VBox(
  59.                     `VSpacing(0.3),
  60.                     `HBox(
  61.                       `HSpacing(1),
  62.                       `Heading(h),
  63.                       `HSpacing(1)
  64.                      ),
  65.                     `VSpacing(4),
  66.                     `HBox(
  67.                       `HSpacing(4),
  68.                       `VBox(
  69.                         // label text
  70.                         `Label(_("Don't forget what you enter here!")),
  71.                         `VSpacing(),
  72.  
  73.                         `HBox(
  74.                             `Password(`id("pw1"),
  75.                             // Label: get password for user root
  76.                             // Please use newline if label is longer than 40 characters
  77.                                 _("&Enter a password for your file system:"), ""),
  78.                             `HSpacing(15)),
  79.  
  80.                         `VSpacing(0.5),
  81.  
  82.                         `HBox(
  83.                             `Password(`id("pw2"),
  84.                              // Label: get same password again for verification
  85.                              // Please use newline if label is longer than 40 characters
  86.                                 _("Reenter the password for &verification:"), ""),
  87.                              `HSpacing(15))
  88.                         ),
  89.                       `HSpacing(4)
  90.                      ),
  91.                     `VSpacing(3),
  92.                     `HBox(
  93.                       // Ok button
  94.                       `PushButton(`id("ok"), `opt(`default),  Label::OKButton()),
  95.                       // Cancel button
  96.                       `PushButton(`id("cancel"),   Label::CancelButton())
  97.                       ),
  98.                     `VSpacing(0.5)
  99.                     )
  100.                )
  101.          ));
  102.  
  103.       string  ret         = "";
  104.       boolean input_is_ok = false;
  105.       string pw1       = "";
  106.       string pw2       = "";
  107.  
  108.       repeat
  109.       {
  110.       // Clear password fields on every round.
  111.       UI::ChangeWidget(`id("pw1"), `Value, "");
  112.       UI::ChangeWidget(`id("pw2"), `Value, "");
  113.  
  114.       UI::SetFocus(`id("pw1"));
  115.  
  116.       ret = (string) UI::UserInput();
  117.  
  118.  
  119.       if (ret != "cancel")
  120.       {
  121.           pw1 = (string)UI::QueryWidget(`id("pw1"), `Value);
  122.           pw2 = (string)UI::QueryWidget(`id("pw2"), `Value);
  123.  
  124.           if ( pw1 != pw2 )
  125.           {
  126.           // popup text
  127.           Popup::Message(_("The first and the second version\nof the password do not match!\nPlease try again."));
  128.           }
  129.           else  if (pw1 == "")
  130.           {
  131.           // popup text
  132.           Popup::Message(_("You did not enter a password.
  133. Try again.
  134. "));
  135.           }
  136.           else if (size (pw1) < minpwlen)
  137.           {
  138.           // popup text
  139.           Popup::Message(sformat(_("The password must have at least %1 characters.
  140. Try again.
  141. "),minpwlen));
  142.           }
  143.           else if ( size(pw1) >= minpwlen )
  144.           {
  145.           any ret2 = findfirstnotof( pw1, "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ#* ,.;:._-+!$%&/|\?{[()]}@" );
  146.  
  147.           if ( ret2 != nil )
  148.           {
  149.               // popup text
  150.               Popup::Message(_("The password may only contain the following characters:
  151.  0..9, a..z, A..Z, and any of \"@#* ,.;:._-+!$%&/|\?{[()]}\".
  152. Try again."));
  153.           }
  154.           else
  155.           {
  156.               input_is_ok = true;
  157.           }
  158.           }
  159.       }
  160.  
  161.       } until ( input_is_ok || ret == "cancel" );
  162.  
  163.       UI::CloseDialog();
  164.  
  165.       if (ret == "cancel")
  166.       {
  167.       pw1 = "";
  168.       }
  169.     y2milestone( "DlgCreateCryptFs size(ret):%1", size(pw1) );
  170.     return( pw1 );
  171.   }
  172.  
  173.  
  174. //////////////////////////////////////////////////////////////////////////////
  175. // Dialog Password for Crypted FS Update
  176. //////////////////////////////////////////////////////////////////////////////
  177.  
  178.  
  179. define string DlgUpdateCryptFs( string device, string mount )
  180.     ``{
  181.     string helptext = GetUpdateCryptFsHelptext();
  182.  
  183. // translator comment: %1 is the device name, %2 is a directory
  184. //            example: "...password for device /dev/hda6 mounted on /var"
  185.     string enter = sformat(_("Enter your crypt password for
  186. device %1 mounted on %2.
  187. "),device,mount);
  188.  
  189.     UI::OpenDialog(
  190.          `opt(`decorated ),
  191.          `HBox(
  192.            `HWeight(3, `RichText( helptext ) ),
  193.            `HWeight(6, `VBox(
  194.                     `VSpacing(0.3),
  195.                     `HBox(
  196.                       `HSpacing(1),
  197.                       // heading text
  198.                       `Heading(_("Enter your password for the encrypted file system")),
  199.                       `HSpacing(1)
  200.                      ),
  201.                     `VSpacing(2),
  202.                     `HBox(
  203.                       `HSpacing(4),
  204.                       `VBox(
  205.                         // advise user to remember his new password
  206.                         `Label(enter),
  207.                         `VSpacing(),
  208.  
  209.                         `HBox(
  210.                             `Password(`id("pw1"),
  211.                             // Label: get password for user root
  212.                             // Please use newline if label is longer than 40 characters
  213.                                 _("&Enter a password for your file system:"), ""),
  214.                             `HSpacing(15)),
  215.                         `VSpacing(0.5),
  216.  
  217.                         `HBox(
  218.                             `Password(`id("pw2"),
  219.                             // Label: get same password again for verification
  220.                             // Please use newline if label is longer than 40 characters
  221.                                 _("Reenter the password for &verification:"), ""),
  222.                             `HSpacing(15))
  223.                         ),
  224.                       `HSpacing(4)
  225.                       ),
  226.                     `VSpacing(2),
  227.                     `HBox(
  228.                       // Ok button
  229.                       `PushButton(`id("ok"), `opt(`default),  Label::OKButton()),
  230.                       // Cancel button
  231.                       `PushButton(`id("cancel"),  _("&Skip") )
  232.                       ),
  233.                     `VSpacing(0.5)
  234.                     )
  235.                )
  236.          ));
  237.  
  238.       string ret         = "";
  239.       boolean input_is_ok = false;
  240.       string pw1       = "";
  241.       string pw2       = "";
  242.  
  243.       repeat
  244.       {
  245.       // Clear password fields on every round.
  246.       UI::ChangeWidget(`id("pw1"), `Value, "");
  247.       UI::ChangeWidget(`id("pw2"), `Value, "");
  248.  
  249.       UI::SetFocus(`id("pw1"));
  250.  
  251.       ret = (string)UI::UserInput();
  252.  
  253.  
  254.       if (ret != "cancel")
  255.       {
  256.           pw1 = (string)UI::QueryWidget(`id("pw1"), `Value);
  257.           pw2 = (string)UI::QueryWidget(`id("pw2"), `Value);
  258.  
  259.           if ( pw1 != pw2 )
  260.           {
  261.           // popup text
  262.           Popup::Message(_("The first and the second version\nof the password do not match!\nPlease try again."));
  263.           }
  264.           else  if (pw1 == "")
  265.           {
  266.           // popup text
  267.           Popup::Message(_("You did not enter a password.
  268. Try again.
  269. "));
  270.           }
  271.           else if ( size(pw1) >= 5 )
  272.           {
  273.           input_is_ok = true;
  274.           }
  275.           else
  276.           {
  277.           // popup text
  278.           Popup::Message(sformat(_("The password must have at least %1 characters.
  279. Try again.
  280. "),5));
  281.           }
  282.       }
  283.  
  284.       } until ( input_is_ok || ret == "cancel" );
  285.  
  286.       UI::CloseDialog();
  287.  
  288.       if (ret != "cancel")
  289.       {
  290.       return( pw1 );
  291.       }
  292.       else
  293.       {
  294.       return( "" );
  295.       }
  296.  
  297.   }
  298.  
  299. define symbol DoInputChecks( map entry, string query )
  300.     ``{
  301.     symbol ret = `ok;
  302.     list between = entry[`between]:[];
  303.     string valid_chars = entry[`valid_chars]:"";
  304.     integer str_length = entry[`str_length]:0;
  305.  
  306.     if( between != [] && (size(query)>0 || !entry[`empty_allowed]:false))
  307.     {
  308.     y2milestone( "DoInputChecks entry:%1 query:\"%2\"", entry, query );
  309.     if( between[0]:0 > tointeger(query)  ||
  310.         ( (between[1]:0 != -1) && (between[1]:0 < tointeger(query) ) ) )
  311.         {
  312.         Popup::Error(entry[`error_text]:"");
  313.         ret = `error;
  314.         }
  315.     }
  316.  
  317.     if( valid_chars != "" && size(query)>0 && ret != `error )
  318.     {
  319.     if( nil != findfirstnotof( query, valid_chars ))
  320.         {
  321.         Popup::Error(entry[`error_text]:"");
  322.         ret = `error;
  323.         }
  324.     }
  325.  
  326.     if( str_length != 0 && size(query) > str_length && ret != `error )
  327.     {
  328.     Popup::Error(entry[`error_text]:"");
  329.     ret = `error;
  330.     }
  331.     y2milestone( "DoInputChecks value %1 ret %2", query, ret );
  332.     return( ret );
  333.     }
  334.  
  335.   /**
  336.    * Dialog: Filesystem options
  337.    * @parm new_val map that contains a partition
  338.    * @parm file_systems filesystem definitions
  339.    */
  340. define map FileSystemOptions( map< any, map<string,any> > org_fs_options, 
  341.                               map fs_define  )
  342.     ``{
  343.     y2milestone( "FileSystemOptions org_fs_options %1", org_fs_options );
  344.     map<any, map<string,any> > fs_options = org_fs_options;
  345.     term contents     = `VBox(`VSpacing (1));
  346.     string helptext   = "";
  347.  
  348.     foreach( map option, fs_define[`options]:[],
  349.     ``{
  350.     term emptyterm = `Empty();
  351.     contents = add( contents, option[`widget]:emptyterm);
  352.     string add_help = option[`help_text]:"";
  353.     if( add_help != "")
  354.         helptext = helptext + add_help ;
  355.     });
  356.  
  357.     UI::OpenDialog( `opt(`decorated),
  358.             `HBox(
  359.             `HWeight(4, `RichText( helptext )),
  360.             `HWeight(7,
  361.                 `VBox(
  362.                 `HSpacing(50),
  363.                 // heading text
  364.                 `Left(`Heading(_("File system options:"))),
  365.                 `VStretch(),
  366.                 `VSpacing(1),
  367.                 `HBox(
  368.                     `HStretch(),
  369.                     `HSpacing(1),
  370.                     contents,
  371.                     `HStretch(),
  372.                     `HSpacing(1)),
  373.                     `VSpacing(1),
  374.                     `VStretch(),
  375.                     `HBox(
  376.                     `Bottom(`PushButton(`id(`ok),
  377.                                 `opt(`default),
  378.                                 Label::OKButton())),
  379.                     `Bottom(
  380.                       `PushButton(`id(`cancel),
  381.                               Label::CancelButton())))
  382.                     ))));
  383.  
  384.     foreach(any query_key, map<string, any> option_map, fs_options,
  385.     ``{
  386.     UI::ChangeWidget( `id(query_key), `Value,
  387.               option_map["option_value"]:(any)"" );
  388.     });
  389.  
  390.     list<any> iglist = ["auto", "none", "default"];
  391.     symbol ret = `ok;
  392.     repeat
  393.     {
  394.     ret = (symbol)UI::UserInput();
  395.     if( ret == `ok )
  396.         {
  397.         foreach( map entry, fs_define[`options]:[],
  398.         ``{
  399.         y2milestone( "FileSystemOptions entry %1", entry );
  400.         if( ret != `error )
  401.             {
  402.             any query = UI::QueryWidget( `id(entry[`query_key]:nil),
  403.                                          `Value );
  404.             y2milestone( "FileSystemOptions query %1", query );
  405.             map<string,any> fs_option =
  406.             $[ "option_str"   : entry[`option_str]:"",
  407.                "option_value" : query ];
  408.             y2milestone( "FileSystemOptions fs_option %1", fs_option );
  409.  
  410.             if( entry[`option_blank]:false )
  411.             {
  412.             fs_option["option_blank"] = true;
  413.             }
  414.  
  415.             if( is( query, string) && !contains( iglist, query ))
  416.             {
  417.             ret = DoInputChecks( entry, (string)query );
  418.             }
  419.  
  420.             if( ret!=`error )
  421.             {
  422.             if( query!=entry[`default]:nil && 
  423.                 !contains( iglist, query ))
  424.                 {
  425.                 fs_options[entry[`query_key]:nil] = fs_option;
  426.                 }
  427.             else if( haskey( fs_options, entry[`query_key]:nil ))
  428.                 {
  429.                 fs_options = remove( fs_options, 
  430.                                      entry[`query_key]:nil );
  431.                 }
  432.             }
  433.             y2milestone( "FileSystemOptions fs_options %1", fs_options );
  434.             }
  435.         });
  436.         }
  437.     } until ( ret == `ok || ret == `cancel );
  438.  
  439.     UI::CloseDialog();
  440.  
  441.     if( ret != `ok )
  442.     fs_options = org_fs_options;
  443.     y2milestone("FileSystemOptions ret %1", fs_options );
  444.     return( fs_options );
  445.     }
  446.  
  447. void PopupNoSlashLabel()
  448.     {
  449.     // popup text
  450.     Popup::Error( _("The character '/' is no longer permitted in a volume label.
  451. Change your volume label so that it does not contain this character.
  452. "));
  453.     }
  454.  
  455.   /**
  456.    * Dialog: Fstab options
  457.    * @parm old map with original partition
  458.    * @parm new map with changes filled in
  459.    */
  460. define map<string,any> FstabOptions( map<string,any> old, map<string,any> new )
  461.     ``{
  462.     string helptext = "";
  463.     term contents = `VBox();
  464.     term emptyterm = `Empty();
  465.  
  466.     if( new["enc_type"]:`none==`none) // && new["mount"]:"" != "swap" )
  467.     {
  468.     // help text, richtext format
  469.     helptext = helptext + _("<p><b>Mount in /etc/fstab By:</b>
  470. Normally, a file system to mount is identified in /etc/fstab
  471. by the device name. This identification can be changed so the file system to mount
  472. is found by searching for a UUID or a volume label. Not all file systems can be
  473. mounted by UUID or a volume label. If an option is disabled, it is not possible.
  474. ");
  475.  
  476.     // help text, richtext format
  477.     helptext = helptext + _("<p><b>Volume Label:</b>
  478. The name entered in this field is used as the volume label. This normally only
  479. makes sense when you activate the option for mounting by volume label.
  480. A volume label cannot contain the / character or spaces.
  481. ");
  482.  
  483.     contents = add( contents,
  484.             `VBox(
  485.                 `RadioButtonGroup(
  486.                 `id(`mt_group),
  487.                 `VBox(
  488.                      // label text
  489.                     `Left( `Label(_("Mount in /etc/fstab by"))),
  490.                     `HBox(
  491.                     `VBox(
  492.                         `Left( `RadioButton( `id(`device),
  493.                                  // label text
  494.                                  _("&Device name") )),
  495.                         `Left( `RadioButton( `id(`label),
  496.                                  // label text
  497.                                  _("Volume &label") )),
  498.                         `Left( `RadioButton( `id(`uuid),
  499.                                  // label text
  500.                                  "U&UID" ))
  501.                         ),
  502.                     `Top(`VBox(
  503.                         `Left( `RadioButton( `id(`id),
  504.                                  // label text
  505.                                  _("Device &ID") )),
  506.                         `Left( `RadioButton( `id(`path),
  507.                                  // label text
  508.                                  _("Device &Path") ))
  509.                         ))
  510.                     )
  511.                      )
  512.                 ),
  513.                `TextEntry( `id(`vol_label), `opt(`hstretch),
  514.                        // label text
  515.                        _("Volume &Label")),
  516.                `VSpacing(1)
  517.                ));
  518.     }
  519.     list<map> opt_list = [];
  520.     if( new["mount"]:"" != "swap" )
  521.     {
  522.     foreach( map entry, FileSystems::GetGeneralFstabOptions(),
  523.         ``{
  524.         opt_list = add( opt_list, entry );
  525.  
  526.         contents = add( contents, entry[`widget]:emptyterm );
  527.         helptext = helptext + entry[`help_text]:"";
  528.         });
  529.     contents = add( contents, `VSpacing(1) );
  530.     }
  531.     foreach( map entry, FileSystems::GetFstabOptWidgets( new["used_fs"]:`ext2 ),
  532.     ``{
  533.     opt_list = add( opt_list, entry );
  534.     contents = add( contents, entry[`widget]:emptyterm );
  535.     helptext = helptext + entry[`help_text]:"";
  536.     });
  537.     contents = add( contents, `VSpacing(1) );
  538.     map entry = FileSystems::GetArbitraryOptionField();
  539.     opt_list = add( opt_list, entry );
  540.     contents = add( contents, entry[`widget]:emptyterm );
  541.     helptext = helptext + entry[`help_text]:"";
  542.  
  543.     string fstopt = deletechars( new["fstopt"]:"", " \t" );
  544.     if( fstopt == "defaults" )
  545.     fstopt = "";
  546.  
  547.     list<string> opt_lstr = splitstring( fstopt, "," );
  548.     map old_state = $[];
  549.     integer pos = 0;
  550.     foreach( map opt, opt_list,
  551.     ``{
  552.     if( opt[`type]:`text == `boolean )
  553.         {
  554.         boolean value = opt[`default]:false;
  555.         pos = 0;
  556.         while( pos < size(opt_lstr) )
  557.         {
  558.         foreach( list list_el, opt[`str_scan]:[],
  559.             ``{
  560.             if( list_el[0]:""==opt_lstr[pos]:"" )
  561.             {
  562.             value = list_el[1]:0 == 1;
  563.             opt_lstr[pos] = "";
  564.             }
  565.             });
  566.         pos = pos + 1;
  567.         }
  568.         old_state[opt[`query_key]:""] = value;
  569.         }
  570.     else
  571.         {
  572.         string value = opt[`default]:"";
  573.         integer pos = 0;
  574.         while( pos < size(opt_lstr) )
  575.         {
  576.         if( size(opt[`str_scan]:"")>0 &&
  577.             regexpmatch( opt_lstr[pos]:"", opt[`str_scan]:"" ))
  578.             {
  579.             value = regexpsub( opt_lstr[pos]:"",
  580.                                opt[`str_scan]:"", "\\1" );
  581.             opt_lstr[pos] = "";
  582.             }
  583.         pos = pos + 1;
  584.         }
  585.         old_state[opt[`query_key]:""] = value;
  586.         }
  587.     });
  588.  
  589.     pos = size(opt_lstr)-1;
  590.     while( pos>=0 )
  591.     {
  592.     if( size(opt_lstr[pos]:"")==0 )
  593.         {
  594.         opt_lstr = remove( opt_lstr, pos );
  595.         }
  596.     pos = pos - 1;
  597.     };
  598.     y2milestone( "FstabOptions key=%1 val:%2", 
  599.                  opt_list[size(opt_list)-1,`query_key]:"",
  600.                  mergestring( opt_lstr, "," ) );
  601.     string arb_opt = mergestring( opt_lstr, "," );
  602.     if( !new["noauto"]:false && new["enc_type"]:`none!=`none )
  603.     {
  604.     arb_opt = FileSystems::RemoveCryptOpts( arb_opt );
  605.     }
  606.  
  607.     old_state[opt_list[size(opt_list)-1,`query_key]:""] = arb_opt;
  608.     y2milestone( "FstabOptions old_state=%1", old_state );
  609.  
  610.     UI::OpenDialog( `opt(`decorated),
  611.                     `HBox(
  612.             `HWeight(4, `RichText( helptext )),
  613.             `HWeight(7,
  614.                 `VBox(
  615.                 `HSpacing(50),
  616.                     // heading text
  617.                 `Left(`Heading(_("Fstab options:"))),
  618.                 `VStretch(),
  619.                 `VSpacing(1),
  620.                 `HBox(`HStretch(),
  621.                 `HSpacing(1),
  622.                 contents,
  623.                 `HStretch(),
  624.                 `HSpacing(1)),
  625.                 `VSpacing(1),
  626.                 `VStretch(),
  627.                 `HBox(
  628.                     `Bottom(`PushButton(`id(`ok),
  629.                             `opt(`default),
  630.                             Label::OKButton())),
  631.                     `Bottom(`PushButton(`id(`cancel),
  632.                                         Label::CancelButton()))
  633.                     )
  634.                 )
  635.                 )
  636.             )
  637.           );
  638.     if( UI::WidgetExists( `id(`mt_group) ))
  639.     {
  640.     list no_mountby_type = [ `loop ];
  641.     list mountby_id_path_type = [ `primary, `logical ];
  642.     UI::ChangeWidget( `id(`mt_group), `CurrentButton,
  643.                       new["mountby"]:`device );
  644.     UI::ChangeWidget( `id(`label), `Enabled,
  645.               FileSystems::MountLabel( new["used_fs"]:`unknown ) &&
  646.               new["enc_type"]:`none==`none &&
  647.               !contains( no_mountby_type, new["type"]:`primary ) );
  648.     UI::ChangeWidget( `id(`uuid), `Enabled,
  649.               (new["format"]:false || size(new["uuid"]:"")>0) &&
  650.               FileSystems::MountUuid( new["used_fs"]:`unknown ) &&
  651.               !contains( no_mountby_type, new["type"]:`primary ) );
  652.     UI::ChangeWidget( `id(`id), `Enabled, contains(mountby_id_path_type, new["type"]:`none) );
  653.     UI::ChangeWidget( `id(`path), `Enabled, contains(mountby_id_path_type, new["type"]:`none) );
  654.     }
  655.  
  656.     if( UI::WidgetExists( `id(`vol_label) ))
  657.     {
  658.     UI::ChangeWidget( `id(`vol_label), `Enabled,
  659.               FileSystems::MountLabel( new["used_fs"]:`unknown ) &&
  660.               new["enc_type"]:`none==`none );
  661.     UI::ChangeWidget( `id(`vol_label), `ValidChars,
  662.               FileSystems::nchars + "-._:/" );
  663.     UI::ChangeWidget( `id(`vol_label), `Value, new["label"]:"" );
  664.     }
  665.  
  666.     y2milestone( "FstabOptions Exists opt_user %1", 
  667.                  UI::WidgetExists( `id("opt_user")));
  668.     y2milestone( "FstabOptions new=%1", new );
  669.     if( UI::WidgetExists( `id("opt_user") ))
  670.     {
  671.     UI::ChangeWidget( `id("opt_user"), `Enabled,
  672.               new["enc_type"]:`none==`none || new["noauto"]:false );
  673.     }
  674.     foreach( any key, any value, old_state,
  675.     ``{
  676.     UI::ChangeWidget( `id(key), `Value, value );
  677.     });
  678.  
  679.     any ret = `ok;
  680.     repeat
  681.     {
  682.     ret = UI::UserInput();
  683.     y2milestone( "FstabOptions ret %1", ret );
  684.     if( ret == "opt_noauto" )
  685.         {
  686.         if( UI::WidgetExists( `id("opt_user") ))
  687.         {
  688.         boolean val = (boolean)UI::QueryWidget( `id("opt_noauto" ), `Value );
  689.         UI::ChangeWidget( `id("opt_user"), `Enabled,
  690.                           new["enc_type"]:`none==`none || val );
  691.         }
  692.         }
  693.     if( ret == `ok )
  694.         {
  695.         if( UI::WidgetExists( `id(`mt_group) ))
  696.         {
  697.         new["mountby"] = UI::QueryWidget( `id(`mt_group),
  698.                                           `CurrentButton );
  699.         if( !new["format"]:false && !new["create"]:false &&
  700.             new["mountby"]:`device != old["mountby"]:`device )
  701.             {
  702.             if( !haskey( new, "ori_mountby" ) )
  703.             new["ori_mountby"] = old["mountby"]:`device;
  704.             }
  705.         new["label"] = UI::QueryWidget( `id(`vol_label), `Value );
  706.         if( new["label"]:"" != old["label"]:"" )
  707.             {
  708.             integer max_len =
  709.             FileSystems::LabelLength( new["used_fs"]:`unknown );
  710.             if( size(new["label"]:"") > max_len )
  711.             {
  712.             new["label"] = substring( new["label"]:"", 0, max_len );
  713.             // popup text %1 is a number
  714.             Popup::Error( sformat(_("
  715. Maximum volume label length for the selected file system
  716. is %1. Your volume label was truncated to this size.
  717. "), max_len ));
  718.             }
  719.             if( search(new["label"]:"","/")!=nil )
  720.             {
  721.             PopupNoSlashLabel();
  722.             ret = `again;
  723.             }
  724.             if( !new["format"]:false && !new["create"]:false &&
  725.             !haskey( new, "ori_label" ) )
  726.             {
  727.             new["ori_label"] = old["label"]:"";
  728.             }
  729.             }
  730.         if( new["mountby"]:`device == `label && size(new["label"]:"")==0 )
  731.             {
  732.             ret = `again;
  733.             // popup text
  734.             Popup::Error( _("Provide a volume label to mount by label."));
  735.             continue;
  736.             }
  737.         if( new["mountby"]:`device == `label &&
  738.             !check_unique_label( Storage::GetTargetMap(), new ))
  739.             {
  740.             ret = `again;
  741.             // popup text
  742.             Popup::Error( _("This volume label is already in use. Select a different one."));
  743.             continue;
  744.             }
  745.         if( new["mountby"]:`device == `label &&
  746.             search(new["label"]:"","/")!=nil )
  747.             {
  748.             ret = `again;
  749.             PopupNoSlashLabel();
  750.             continue;
  751.             }
  752.         }
  753.         if( UI::WidgetExists( `id("opt_noauto") ))
  754.         {
  755.         new["noauto"] = UI::QueryWidget( `id("opt_noauto"), `Value );
  756.         }
  757.         map new_state = $[];
  758.         string text = "";
  759.         string new_fstopt = "";
  760.         foreach( map entry, opt_list,
  761.         ``{
  762.         text = "";
  763.         any value = UI::QueryWidget( `id(entry[`query_key]:""),
  764.                                      `Value );
  765.         new_state[entry[`query_key]:""] = value;
  766.         if( entry[`type]:`text == `boolean )
  767.             {
  768.             text = entry[`str_opt,"default"]:"";
  769.             if( value == true && haskey( entry[`str_opt]:$[], 1 ))
  770.             {
  771.             text = entry[`str_opt,1]:"";
  772.             }
  773.             else if( value == false && haskey( entry[`str_opt]:$[], 0 ))
  774.             {
  775.             text = entry[`str_opt,0]:"";
  776.             }
  777.             }
  778.         else
  779.             {
  780.             if( DoInputChecks( entry, (string)value ) != `ok )
  781.             {
  782.             ret = `again;
  783.             }
  784.             else if( size((string)value)>0 )
  785.             {
  786.             text = sformat( entry[`str_opt]:"%1", value );
  787.             }
  788.             /* this is the default journal mode, no option needed for it */
  789.             if( text == "data=ordered" )
  790.             {
  791.             text = "";
  792.             }
  793.             }
  794.         if( size(text)>0 )
  795.             {
  796.             if( size(new_fstopt)>0 )
  797.             new_fstopt = new_fstopt + ",";
  798.             new_fstopt = new_fstopt + text;
  799.             }
  800.         });
  801.         y2milestone( "FstabOptions new_state=%1", new_state );
  802.         y2milestone( "FstabOptions old_fstopt=%1 new_fstopt=%2", 
  803.                      old["fstopt"]:"", new_fstopt );
  804.         if( old_state!=new_state && old["fstopt"]:"" != new_fstopt )
  805.         {
  806.         if( !new["format"]:false && !new["create"]:false &&
  807.             !haskey( new, "ori_fstopt" ) )
  808.             {
  809.             new["ori_fstopt"] = old["fstopt"]:"";
  810.             }
  811.         new["fstopt"] = new_fstopt;
  812.         }
  813.         if( !CheckFstabOptions( new ))
  814.         {
  815.         new["fstopt"] = old["fstopt"]:"";
  816.         ret = `again;
  817.         }
  818.         }
  819.     } until ( ret == `ok || ret == `cancel );
  820.  
  821.     UI::CloseDialog();
  822.     y2milestone( "FstabOptions fstopt %1 mountby:%2 label:%3", 
  823.                  new["fstopt"]:"", new["mountby"]:`device, 
  824.          new["label"]:"" );
  825.     return( new );
  826.     };
  827.  
  828.  
  829. /**
  830.    * Dialogpart: Filesystem
  831.    * @parm new_val map that contains a partition
  832.    * @parm file_systems filesystem definitions
  833.    * @return term the term contains a ComboBox with the different filesystems
  834.    */
  835. define term FileSystemsComboBox( map new_val, map<symbol,map> file_systems )
  836.     ``{
  837.     map<symbol,map> fs_sel = $[];
  838.     list filesystems = [ ];
  839.     boolean is_swap = new_val["fsid"]:0 == Partitions::fsid_swap;
  840.  
  841.     y2debug( "new=%1 swap=%2", new_val, is_swap );
  842.     foreach( symbol file_system_name, map file_system_map, file_systems,
  843.     ``{
  844.     if( file_system_map[`supports_format]:false )
  845.         {
  846.         fs_sel[file_system_name] = $[];
  847.         fs_sel[file_system_name,"text"] = file_system_map[`name]:"Ext2";
  848.         if( is_swap )
  849.         fs_sel[file_system_name,"selected"] = file_system_name == `swap;
  850.         else
  851.         fs_sel[file_system_name,"selected"] =
  852.             new_val["used_fs"]:Partitions::DefaultFs() == file_system_name;
  853.         }
  854.     });
  855.     y2debug( "fs_sel=%1", fs_sel );
  856.     if( haskey( fs_sel, Partitions::DefaultFs() ) &&
  857.     size(filter( any k, map e, fs_sel, ``(e["selected"]:false) ))==0 )
  858.     {
  859.     fs_sel[Partitions::DefaultFs(),"selected"] = true;
  860.     }
  861.     foreach( symbol fs_type, map entry, fs_sel,
  862.     ``{
  863.     if( fs_type != `swap )
  864.         filesystems = add( filesystems,
  865.         `item(`id(fs_type), entry["text"]:"Ext2", entry["selected"]:false ));
  866.     });
  867.     if( haskey( fs_sel, `swap ))
  868.     {
  869.     filesystems = add( filesystems,
  870.         `item( `id(`swap), fs_sel[`swap,"text"]:"Swap",
  871.             fs_sel[`swap,"selected"]:false ));
  872.     }
  873.  
  874.     term CryptWidget = `Empty();
  875.     if( !Arch::s390 () )
  876.     {
  877.     boolean cr = new_val["enc_type"]:`none != `none;
  878.     CryptWidget = `VBox( `VSpacing(0.7),
  879.                          `Left(`CheckBox(`id(`crypt_fs), `opt(`notify),
  880.                         // button text
  881.                                  _("&Encrypt file system"), cr )));
  882.     }
  883.  
  884.     return `VBox(
  885.                `ReplacePoint( `id(`type_dlg_rp),
  886.                   `ComboBox(`id(`fs), `opt(`hstretch, `notify),
  887.                     // label text
  888.                     _("File &system"), filesystems )),
  889.                   `PushButton( `id(`fs_options ),`opt(`hstretch),
  890.                        // button text
  891.                        _("O&ptions") ),
  892.                   CryptWidget );
  893.     }
  894.  
  895. /**
  896.  * Dialogpart: Filesystem ID
  897.  * @parm new_val map that contains a partition
  898.  * @parm file_systems filesystem definitions
  899.  * @return term the term contains a ComboBox that allow the user to  edit the filesystem ID
  900.  */
  901. define term FsidComboBox( map new_val, map<symbol, map> file_systems  )
  902.     ``{
  903.     list items = [];
  904.     list added_items = [];
  905.     list added_fsids = [];
  906.     foreach( any fs_name, map fs_map, file_systems,
  907.     ``{
  908.     string fsid_item =  fs_map[`fsid_item]:" ";
  909.     if( !contains( added_items, fsid_item ))
  910.         {
  911.         items = add( items,
  912.         `item( `id(fsid_item), fsid_item,
  913.             fs_map[`fsid]:0 == new_val["fsid"]:0));
  914.         added_fsids = add( added_fsids, fs_map[`fsid]:0 );
  915.         added_items = add( added_items, fsid_item );
  916.         }
  917.     });
  918.  
  919.     integer id = new_val["fsid"]:0;
  920.     if( id != 0 && !contains( added_fsids, id ) )
  921.     {
  922.     string part_id = Partitions::ToHexString(id) + " " +
  923.              Partitions::FsIdToString(id);
  924.     items = add( items, `item( `id(part_id), part_id, true ));
  925.     }
  926.  
  927.     return( `ComboBox(`id(`fsid_point), `opt(`notify,`editable, `hstretch),
  928.         // label text
  929.         _("File system &ID:"), items ));
  930.     };
  931.  
  932.  
  933. /**
  934.  * Dialogpart: Size Dialog
  935.  * @parm new_val map that contains a partition
  936.  *á@parm edit_size flag
  937.  * @return term the term contains two TextEntries or to Labels with the start and the end cylinder of
  938.  * the partition in new_val
  939.  */
  940. define term SizeDlg( map new_val, integer cyl_size, boolean edit_size, boolean disk )
  941.     ``{
  942.     string start_cyl = sformat( "%1", new_val["region",0]:0 );
  943.     string end_part  = sformat( "%1", (integer)(new_val["region",0]:0) +
  944.                       (integer)(new_val["region",1]:1) -1 );
  945.  
  946.     float mb_cyl_size   =  ( tofloat(cyl_size) /1024.0 /1024.0 );
  947.     string str_cyl_size =  substring( sformat( "%1", mb_cyl_size ), 0, 4);
  948.  
  949.  
  950.     if( new_val["create"]:false && edit_size )
  951.     {
  952.     // label text
  953.     return `Frame ( _("Size"),
  954.         `VBox(
  955.             // label text
  956.             `Left(`Label(_("Cylinder size: ")+ str_cyl_size + " M" )),
  957.             `VSpacing(0.5),
  958.             // label text
  959.             `TextEntry(`id(`start_cyl), _("S&tart cylinder:"), start_cyl ),
  960.             `VSpacing(0.5),
  961.             // label text
  962.             `TextEntry(`id(`end_part), _("En&d:  (9 or +9M or +3.2GB)"), end_part)
  963.             )
  964.         );
  965.     }
  966.     else if( disk )
  967.     {
  968.     return (
  969.         `HBox(
  970.             // label text
  971.             `Left(`Label( _("Type of partition: ")
  972.                 // label text
  973.                 +  _("\nStart cylinder:")
  974.                 // label text
  975.                 +  _("\nEnd cylinder:  ") )),
  976.             `Left(`Label( new_val["fstype"]:""
  977.                 + "\n " + start_cyl
  978.                 + "\n " + end_part ))
  979.             ));
  980.     }
  981.     else 
  982.     return( `Empty() );
  983. }
  984.  
  985.  
  986. define term FormatDlg( map new_val, map<symbol, map> file_systems )
  987.     ``{
  988.     y2debug( "FormatDlg val:%1", new_val );
  989.  
  990.     term fsid = `Empty();
  991.  
  992.     if( new_val["type"]:`primary != `lvm &&
  993.     new_val["type"]:`primary != `sw_raid &&
  994.     new_val["type"]:`primary != `evms &&
  995.     new_val["type"]:`primary != `loop && !Partitions::no_fsid_menu )
  996.     {
  997.     fsid = `VBox(
  998.         `HBox( `HSpacing(2),
  999.             `ReplacePoint( `id(`fsid_dlg_rp),
  1000.             FsidComboBox( new_val, file_systems ))
  1001.             ),
  1002.         `VSpacing(0.5),
  1003.         `VStretch()
  1004.         );
  1005.     }
  1006.     else
  1007.     {
  1008.     fsid = `VSpacing(0.5);
  1009.     }
  1010.  
  1011.             // label text
  1012.     return `Frame (substring(_("2:Format"),2),
  1013.         `RadioButtonGroup(`id(`format),
  1014.         `VBox(
  1015.             `VSpacing(1),
  1016.             // button text
  1017.             `Left(`RadioButton(`id(`format_false), `opt(`notify),
  1018.                                _("Do ¬ format"), !new_val["format"]:false )),
  1019.             fsid,
  1020.             `Left(`RadioButton(`id(`format_true), `opt(`notify),
  1021.                     // button text
  1022.                                 _("&Format"), new_val["format"]:false )),
  1023.             `HBox(
  1024.             `HSpacing(2),
  1025.             FileSystemsComboBox( new_val, file_systems )),
  1026.             `VSpacing(0.5)
  1027.                      )));
  1028.  
  1029.  
  1030.     }
  1031.  
  1032.  
  1033.  
  1034. define term RaidOptionsDlg( map new_val, boolean edit_raid_type )
  1035.     ``{
  1036.     integer chunk_size = new_val["chunk_size"]:0;
  1037.     string parity_algorithm = new_val["parity_algorithm"]:"left_asymmetric";
  1038.     string raid_type = new_val["raid_type"]:"raid1";
  1039.     term editRaid = `VSpacing(1);
  1040.  
  1041.     // 4KB .. 4096KB
  1042.     list     chunk_list = [];
  1043.     integer  i          = 4;
  1044.     while(  i <= 4096 )
  1045.     {
  1046.         integer chunk_item = i;
  1047.         chunk_list = add( chunk_list,
  1048.                       `item(`id(chunk_item), tostring(chunk_item),
  1049.                     chunk_size==chunk_item ));
  1050.         i = i*2;
  1051.         }
  1052.  
  1053.     if( edit_raid_type )
  1054.     {
  1055.     editRaid = `VBox(
  1056.              `VSpacing(),
  1057.              `Left (`ComboBox( `id(`raid_combo),
  1058.                                `opt(`notify, `hstretch ),
  1059.                        // button text
  1060.                        _("RAID T&ype"),
  1061.                     [ `item(`id("raid0"), "raid0",
  1062.                             "raid0"==raid_type ),
  1063.                       `item(`id("raid1"), "raid1",
  1064.                             "raid1"==raid_type ),
  1065.                       `item(`id("raid5"), "raid5",
  1066.                             "raid5"==raid_type ),
  1067.                       `item(`id("multipath"), "multipath",
  1068.                             "multipath"==raid_type )
  1069.                     ])),
  1070.              `VSpacing()
  1071.             );
  1072.     }
  1073.  
  1074.     return `VSquash(
  1075.             `VBox(
  1076.          editRaid,
  1077.          // Raid combobox description (don't translate to much ..)
  1078.          `Left (`ComboBox ( `id(`chunk_size),`opt(`hstretch ), _("Chunk s&ize in KB"), chunk_list )),
  1079.          `VSpacing (),
  1080.          // Raid combobox description (don't translate to much ..)
  1081.          `Left (`ComboBox ( `id(`parity),`opt(`hstretch ), _("Parity &algorithm (only for RAID 5)"),
  1082.                     [ `item(`id("left_asymmetric"),  "left-asymmetric",  "left_asymmetric" == parity_algorithm ),
  1083.                     `item(`id("left_symmetric"),   "left-symmetric",   "left_symmetric" == parity_algorithm ),
  1084.                     `item(`id("right_asymmetric"), "right-asymmetric", "right_asymmetric" == parity_algorithm ),
  1085.                     `item(`id("right_symmetric"),  "right-symmetric",  "right_symmetric" == parity_algorithm )
  1086.                     ])),
  1087.          `VSpacing ()
  1088.          ));
  1089.  
  1090.     }
  1091.  
  1092. define term LoopOptionsDlg( string pb, string cb, string sb )
  1093.     ``{
  1094.     term widget =
  1095.     `VSquash(
  1096.         `VBox(
  1097.          `VSpacing(),
  1098.          `Left( `TextEntry( `id(`loop_path), `opt(`notify), pb )),
  1099.          `VSpacing(1),
  1100.          `Left( `CheckBox( `id(`loop_create), `opt(`notify), cb )),
  1101.          `Left( `TextEntry( `id(`loop_size), `opt(`notify), sb )),
  1102.          `VSpacing()
  1103.          ));
  1104.     return widget;
  1105.     }
  1106.  
  1107.   /**
  1108.    * Change the state of all symbol from the list symbols
  1109.    * @parm symbols all symbols
  1110.    * @parm what true or false
  1111.    * @return nil
  1112.    */
  1113. define void ChangeExistingSymbolsState( list symbols , boolean what )
  1114.     ``{
  1115.     foreach( any sym, symbols, ``{
  1116.       UI::ChangeWidget(`id(sym), `Enabled, what );
  1117.       });
  1118.     }
  1119.  
  1120.  
  1121.   /**
  1122.    * Return a map with the filesystem definitions for the map new_val
  1123.    * @parm new_val map that contains a partition
  1124.    * @parm file_systems filesystem definitions
  1125.    * @return map
  1126.    */
  1127. define map GetFirstFilesystemDefinition( integer fsid, map<symbol,map> file_systems )
  1128.     ``{
  1129.     map<symbol,map> define_map  = filter( symbol key, map val, file_systems,
  1130.                               ``(fsid == val[`fsid]:Partitions::fsid_native ));
  1131.     list<map> define_list = maplist( symbol k, map v , define_map, ``( v ));
  1132.     if( size( define_list ) == 0)
  1133.     return $[];
  1134.     else
  1135.     return define_list[0]:$[];
  1136.     }
  1137.  
  1138.  
  1139.   /**
  1140.    * Dialogpart: Mount part
  1141.    * @parm new_val map that contains a partition
  1142.    * @parm file_systems filesystem definitions
  1143.    * @return term ComboBox with all mountpoints
  1144.    */
  1145. define term MountDlg( map new_val, list mountpoints )
  1146.     ``{
  1147.     if( mountpoints == nil  )
  1148.     mountpoints = [ "/", "/usr", Partitions::BootMount(), "/var", "/home",
  1149.                     "/opt" , ""];
  1150.  
  1151.     if( !contains( mountpoints, "" ) && new_val["enc_type"]:`none==`none )
  1152.     mountpoints = add( mountpoints , "");
  1153.     string mount = new_val["mount"]:"";
  1154.  
  1155.     if( !contains( mountpoints, mount ))
  1156.     mountpoints = union( [mount], mountpoints);
  1157.  
  1158.     term dlg = `VBox(
  1159.            `PushButton( `id(`fstab_options), `opt(`hstretch),
  1160.                     // button text
  1161.                 _("Fs&tab Options")),
  1162.            `VSpacing(1),
  1163.            `ComboBox(`id(`mount_point), `opt(`editable, `hstretch),
  1164.                  // label text
  1165.                  _("&Mount Point"), mountpoints  )
  1166.            );
  1167.     // return term
  1168.     return ( dlg );
  1169.     }
  1170.  
  1171.  
  1172.  
  1173.  
  1174. define boolean UseChangedPartitionContinueCancelPopup()
  1175.     ``{
  1176.     // popup text
  1177.     if( Popup::ContinueCancel(_("You have changed the parameters of a partition currently
  1178. mounted. In some cases, this can damage your Linux installation.
  1179.  
  1180. Proceed only if you know what you are doing. If you are unsure,
  1181. press Cancel.
  1182.  
  1183. ")))
  1184.     return true;
  1185.  
  1186.      return false;
  1187.      };
  1188.  
  1189. define boolean ModifyPartitionInSystemWarningPopup( string part, string mount )
  1190.     ``{
  1191.  
  1192.     // popup text %1 is a partition name, %2 a dirctory
  1193.     string warning = sformat(_("
  1194. The selected partition (%1) is currently mounted on %2.
  1195. If you change parameters (such as the mount point or the file system type),
  1196. your Linux installation might be damaged.
  1197.  
  1198. Unmount the partition if possible. If you are unsure,
  1199. it is recommended to abort. Do not proceed unless you know
  1200. exactly what you are doing.
  1201.  
  1202. Continue?
  1203. "), part, mount );
  1204.  
  1205.       boolean ret = false;
  1206.  
  1207.       ret = Popup::YesNo( warning );
  1208.  
  1209.       return( ret );
  1210.   };
  1211.  
  1212.  
  1213. define string AddLvm( boolean lvm, string txt )
  1214.     ``{
  1215.     txt = sformat( txt, lvm ? _("logical volume") : _("partition") );
  1216.     return( txt );
  1217.     }
  1218.  
  1219. define boolean FsysCannotShrinkPopup( boolean ask, boolean lvm )
  1220.     ``{
  1221.     boolean ret = true;
  1222.     // Popup text
  1223.     // %1 is either replaced by "logical volume" or by "partition"
  1224.     string txt =  AddLvm( lvm, _("
  1225. The file system on the %1 cannot be shrunk by YaST2.
  1226. Only fat, ext2, ext3, and reiser allow shrinking of a file system."));
  1227.     if( ask )
  1228.     {
  1229.     txt = txt + "\n";
  1230.     txt = txt + AddLvm( lvm,
  1231.                 // Popup text
  1232.                 // %1 is either replaced by "logical volume" or by "partition"
  1233.                         _("You risk losing data if you shrink this %1."));
  1234.     txt = txt + "\n\n";
  1235.     txt = txt + _("Continue?");
  1236.     }
  1237.     if( ask )
  1238.     {
  1239.     ret = Popup::YesNo( txt );
  1240.     }
  1241.     else
  1242.     {
  1243.     Popup::Error( txt );
  1244.     ret = false;
  1245.     }
  1246.     return( ret );
  1247.     }
  1248.  
  1249. define boolean FsysCannotGrowPopup( boolean ask, boolean lvm )
  1250.     ``{
  1251.     boolean ret = true;
  1252.     // Popup text
  1253.     // %1 is either replaced by "logical volume" or by "partition"
  1254.     string txt =  AddLvm( lvm, _("
  1255. The file system on the selected %1 cannot be extended by YaST2.
  1256. Only fat, ext2, ext3, xfs, and reiser allow extending a file system."));
  1257.     if( ask )
  1258.     {
  1259.     txt = txt + "\n\n";
  1260.     // Popup text
  1261.     // %1 is either replaced by "logical volume" or by "partition"
  1262.     txt = txt + AddLvm( lvm, _("Continue resizing the %1?"));
  1263.     }
  1264.     if( ask )
  1265.     {
  1266.     ret = Popup::YesNo( txt );
  1267.     }
  1268.     else
  1269.     {
  1270.     Popup::Error( txt );
  1271.     ret = false;
  1272.     }
  1273.     return( ret );
  1274.     }
  1275.  
  1276. define void FsysCannotResizeMountPopup( boolean lvm, string mount )
  1277.     ``{
  1278.     // %1 is either replaced by "logical volume" or by "partition"
  1279.     string txt = sformat( _("
  1280. The %1 is currently mounted on %2.
  1281. It is not possible to resize the file system while it is mounted.
  1282.  
  1283. Unmount the file system and retry resizing.
  1284. "),
  1285.                           AddLvm( lvm, "%1"), mount );
  1286.     Popup::Error( txt );
  1287.     }
  1288.  
  1289. define boolean FsysShrinkReiserWarning( boolean lvm )
  1290.     ``{
  1291.     boolean ret = true;
  1292.     // Popup text
  1293.     // %1 is either replaced by "logical volume" or by "partition"
  1294.     ret = Popup::YesNo( AddLvm( lvm, _("
  1295. You decreased a %1 with a reiser file system on it.
  1296. It is possible to shrink a reiser file system, but this feature is not
  1297. very thoroughly tested. A backup of your data is recommended.
  1298.  
  1299. Shrink the file system now?")));
  1300.     return( ret );
  1301.     }
  1302.  
  1303.  
  1304. /**
  1305.   * Scan exiting partitions for fstab files and if one found read the mountpoints
  1306.   * from the fstab file and build a new targetMap.
  1307.   * Ask the user if he like to use the new or old targetMap
  1308.   * (with or without found mountpoints)
  1309.   *------------------------------------
  1310.   * @parm targetMap all targets
  1311.   * @parm installation !!
  1312.   * @parm file_systems  filesystems definition map
  1313.   * @return targetMap new or unmodified targetMap
  1314.   *---------------------------------------------------------------------
  1315.   */
  1316. define integer FstabAddDialog( list table_input )
  1317.     ``{
  1318.     y2milestone( "FstabAddDialog start %1", table_input );
  1319.     if( table_input == [] || table_input == nil )
  1320.     {
  1321.     // popup text
  1322.     Popup::Message(_("No previous system with mount points was detected."));
  1323.     return -1;
  1324.     }
  1325.  
  1326.     // heading text
  1327.     term header = `header( _("Device      "),  _("Mount       "));
  1328.  
  1329.     // help text, richtext format
  1330.     string help_text = _("<P><B><BIG>Attention:</BIG></B><BR>YaST2 has scanned your hard disks and found an old Linux system
  1331. with mount points. On the right, see a list with the mount points found. </P>
  1332. ")+
  1333.     // help text, richtext format
  1334. _("<P>To use these mount points, <BR>press <B>Yes</B>.</P>")+
  1335.     // help text, richtext format
  1336. _("<P>To ignore these mount points, <BR> press <B>No</B>.</P>");
  1337.  
  1338.     UI::OpenDialog(
  1339.     `opt(`decorated ),
  1340.         `HBox(
  1341.         `VBox( `HSpacing(20), `RichText(help_text)),
  1342.         `VBox( `VSpacing(1),
  1343.            `ReplacePoint( `id(`heading), `Empty() ),
  1344.            `HBox(
  1345.                `HSpacing(3.0),
  1346.                `VSpacing(8),
  1347.                `VBox( `VSpacing(1),
  1348.                    `Table(`id(`table), header, [] )
  1349.                 ),
  1350.                `HSpacing(3.0)
  1351.                ),
  1352.  
  1353.            `VSpacing(1),
  1354.            // popup text
  1355.            `Heading(_("Would you like to use these mount points
  1356. for your new installation?")),
  1357.            `VSpacing(1),
  1358.            `ReplacePoint( `id(`bbox), `Empty() )
  1359.          ))
  1360.          );
  1361.  
  1362.     symbol userinput = `none;
  1363.     integer idx = 0;
  1364.     repeat
  1365.     {
  1366.     // popup text %1 is replaced by a device name (e.g. /dev/hda1)
  1367.     string tmp = sformat(
  1368. _("A previous system with the following mount points was detected:
  1369. /etc/fstab found on %1"), table_input[idx,"root"]:"/dev/emil" );
  1370.     UI::ReplaceWidget( `id(`heading), `Heading( tmp ) );
  1371.  
  1372.     UI::ChangeWidget( `id(`table), `Items, table_input[idx,"tbl"]:[] );
  1373.  
  1374.     term bbox = `HBox( `PushButton( `id(`ok), `opt(`default),
  1375.                     Label::YesButton() ),
  1376.                `PushButton(`id(`cancel), Label::NoButton())
  1377.              );
  1378.     if( size(table_input)>0 )
  1379.         {
  1380.         bbox = add( bbox, `HSpacing(5) );
  1381.         if( idx>0 )
  1382.         {
  1383.         bbox = add( bbox,
  1384.                     `PushButton( `id(`show_p), _("Show &Previous") ));
  1385.         }
  1386.         if( idx<size(table_input)-1 )
  1387.         {
  1388.         bbox = add( bbox,
  1389.                     `PushButton( `id(`show_n), _("Show &Next") ));
  1390.         }
  1391.         }
  1392.     y2milestone( "userinput UI::ReplaceWidget" );
  1393.     UI::ReplaceWidget( `id(`bbox), bbox );
  1394.     y2milestone( "after UI::ReplaceWidget" );
  1395.  
  1396.     userinput = (symbol)UI::UserInput();
  1397.     y2milestone( "userinput %1", userinput );
  1398.  
  1399.     if( userinput == `show_n )
  1400.         {
  1401.         idx = idx+1;
  1402.         }
  1403.     else if( userinput == `show_p )
  1404.         {
  1405.         idx = idx-1;
  1406.         }
  1407.     y2milestone( "idx %1", idx );
  1408.     }
  1409.     until( userinput == `ok || userinput == `cancel );
  1410.     UI::CloseDialog();
  1411.  
  1412.     integer ret = userinput == `ok ? idx : -1;
  1413.     y2milestone( "ret %1", ret );
  1414.     return ret;
  1415.     };
  1416.  
  1417.  
  1418. define term TargetShowBarGraph( map target, string dev )
  1419.     ``{
  1420.     list partitions_size = [];
  1421.     list partitions_text = [];
  1422.     integer sum_used     = 0;
  1423.     integer cyl_size     = target["cyl_size"]:1;
  1424.     integer cyl_count    = target["cyl_count"]:1;
  1425.     integer min_size     = tointeger( cyl_count / 8 );
  1426.  
  1427.  
  1428.     y2milestone( " target %1" ,target );
  1429.     y2milestone( " parts %1", target["partitions"]:[] );
  1430.  
  1431.     foreach( map part, target["partitions"]:[],
  1432.     ``{
  1433.     if( part["type"]:`primary != `extended )
  1434.         {
  1435.         integer part_size =  part["region",1]:0;
  1436.         string  part_size_str = "";
  1437.  
  1438.         part_size_str = ByteToHumanString(part_size * cyl_size);
  1439.  
  1440.         sum_used        = sum_used + part_size;
  1441.         if( part_size < min_size )
  1442.         part_size = min_size;
  1443.  
  1444.         partitions_size = add( partitions_size , part_size);
  1445.  
  1446.         string part_text =  part["mount"]:"";
  1447.  
  1448.         if( part_text  == "" || part_text == nil )
  1449.         part_text = dev + sformat("%1", part["nr"]:(any)0);
  1450.  
  1451.         part_text = part_text + "\n" + part_size_str;
  1452.  
  1453.         partitions_text = add( partitions_text, part_text );
  1454.         }
  1455.     });
  1456.  
  1457.     integer free  = cyl_count - sum_used;
  1458.  
  1459.     if( free > 0 )
  1460.     {
  1461.     if( free > min_size )
  1462.         partitions_size = add( partitions_size, free );
  1463.     else partitions_size = add( partitions_size, min_size );
  1464.     // label text
  1465.     partitions_text = add( partitions_text, _("free"));
  1466.     }
  1467.  
  1468.     if( Mode::test () )
  1469.     {
  1470.     y2milestone(" partitions_size : %1", partitions_size);
  1471.     y2milestone(" partitions_text : %1", partitions_text);
  1472.     }
  1473.  
  1474.     return `BarGraph(`opt(`vstretch), partitions_size , partitions_text );
  1475.     };
  1476.  
  1477.  
  1478.  
  1479. define boolean TargetAllocationDlg( map target, string dev)
  1480.     ``{
  1481.     if( ! UI::HasSpecialWidget(`BarGraph) )
  1482.     {
  1483.     // %1 is a disk device, example: You have selected the disk /dev/hda, but can only edit a partition like /dev/hda11, /dev/hda2,
  1484.     Popup::Warning(sformat(_("\n You have selected the disk %1, but you can \n  only edit a partition like %11, %12, ... \n"), dev));
  1485.     }
  1486.     else
  1487.     {
  1488.     UI::OpenDialog(`opt(`decorated ),
  1489.                `VBox(
  1490.                  `VSpacing(1),
  1491.                  `Left( `Heading( dev + ":")),
  1492.                  `VSpacing(1),
  1493.                  `VStretch(),
  1494.                  `HSpacing(80),
  1495.                  TargetShowBarGraph(target ,dev),
  1496.                  `VStretch(),
  1497.                  `VSpacing(1),
  1498.                  `HBox(
  1499.                    `PushButton(`id(`close), Label::CloseButton()  )
  1500.                    )
  1501.                  ));
  1502.  
  1503.     UI::UserInput();
  1504.     UI::CloseDialog();
  1505.     }
  1506.  
  1507.     return true;
  1508.     };
  1509.  
  1510.  
  1511.  
  1512.  
  1513. define boolean DDZeroPartitionTable( string del_dev )
  1514.     ``{
  1515.     // popup text
  1516.     if( Popup::YesNo(sformat(_("CAUTION
  1517. If you delete the partition table and disk label of
  1518. device %1, data on this device will be lost.
  1519.  
  1520. Really do this?
  1521. "), del_dev)))
  1522.     {
  1523.     Storage::DeletePartitionTable(del_dev);
  1524.     return true;
  1525.     }
  1526.     return false;
  1527.     };
  1528.  
  1529.  
  1530. define symbol ReallyInstPrepdisk( )
  1531.     ``{
  1532.     map<string,map> targetMap = Storage::GetTargetMap();
  1533.     symbol ret = `none;
  1534.  
  1535.     string doto = Storage::ChangeText();
  1536.     y2milestone( "ReallyInstPrepdisk doto:%1", doto );
  1537.     term dlg = `Empty();
  1538.     if( size(doto) == 0 )
  1539.     {
  1540.     // popup text
  1541.     Popup::Message( _("No changes made so far could be performed."));
  1542.     ret = `back;
  1543.     }
  1544.     else
  1545.     {
  1546.     dlg = `VBox( `VSpacing(1),
  1547.              `HSpacing(60),
  1548.              // label text
  1549.              `Left(`Heading(_("Changes:"))),
  1550.              `RichText( doto ) );
  1551.  
  1552.     UI::OpenDialog(`opt(`decorated, `warncolor),
  1553.                `HBox(
  1554.                  `HSpacing(1),
  1555.                  `VBox(
  1556.                    dlg,
  1557.                    `VSpacing(1),
  1558.                    // popup text
  1559.                    `Heading(_(" Do you really want to execute these changes?")),
  1560.                    `VSpacing(1),
  1561.  
  1562.                    `HBox(
  1563.                      // all right, start installation *now*
  1564.  
  1565.                      `PushButton(`id(`back), Label::CancelButton()),
  1566.                      `HStretch(),
  1567.                      // button text
  1568.                      `PushButton(`id(`apply),   _("&Apply")),
  1569.                      `PushButton(`id(`finish),  Label::FinishButton() )
  1570.                      // no, don't go on, i just changed my mind
  1571.                      ),
  1572.                    `VSpacing(0.2)
  1573.                    ),
  1574.                  `HSpacing(1)
  1575.                  )
  1576.                       );
  1577.  
  1578.     ret = (symbol)UI::UserInput();
  1579.     UI::CloseDialog();
  1580.     }
  1581.  
  1582.     y2milestone( "ReallyInstPrepdisk ret=%1", ret );
  1583.  
  1584.     return ret;
  1585.     };
  1586.  
  1587.  
  1588. /**
  1589.  * Delete all partition in targetMap from the device "del_dev" and return
  1590.  * a new targetMap.
  1591.  * Check if LVM partition exists on the device.
  1592.  * Check if at least on partition is mounted.
  1593.  * @return map targetMap
  1594.  */
  1595. define boolean deleteAllDevPartitions( map<string, any> disk,
  1596.                                        boolean installation, boolean bsd_label )
  1597.     ``{
  1598.     boolean go_on     = true;
  1599.     string del_dev = disk["device"]:"";
  1600.     y2milestone( "deleteAllDevPartitions disk:%1", remove( disk, "partitions" ));
  1601.  
  1602.     /////////////////////////////////////////////////////////////////
  1603.     // check mount points if not installation
  1604.  
  1605.     if( !installation )
  1606.     {
  1607.     list<map> mounts = Storage::mountedPartitionsOnDisk( del_dev );
  1608.     if( size( mounts ) != 0 )
  1609.         {
  1610.         /////////////////////////////////////////////////////////
  1611.         // mount points found
  1612.  
  1613.         string mounted_parts  = "";
  1614.         foreach( map mount, mounts,
  1615.         ``{
  1616.         //  %1 is replaced by device name, %1 by directory e.g /dev/hdd1 on /usr
  1617.         mounted_parts = mounted_parts +
  1618.                         sformat("%1 on %2", mount["device"]:"",
  1619.                     mount["mount"]:"") + "\n";
  1620.         });
  1621.  
  1622.         // popup text, %1 is replaced by device name
  1623.         string message = sformat(_("The selected device contains partitions that are currently mounted:
  1624. %1
  1625. It is *strongly* recommended to unmount these partitions before deleting the partition table.
  1626. Choose Cancel unless you know exactly what you are doing.
  1627. "), mounted_parts );
  1628.  
  1629.         if( !Popup::ContinueCancel(message))
  1630.         {
  1631.         go_on = false;
  1632.         }
  1633.         }
  1634.     }
  1635.  
  1636.     if( go_on )
  1637.     {
  1638.     list<map> partitions = disk["partitions"]:[];
  1639.  
  1640.     symbol used = check_devices_used( partitions );
  1641.  
  1642.     go_on = used == `UB_NONE;
  1643.  
  1644.     if( used == `UB_LVM )
  1645.         {
  1646.         // popup text, Do not translate LVM.
  1647.         Popup::Message(_("
  1648. The selected device contains at least one LVM partition
  1649. assigned to a volume group. Remove all
  1650. partitions from their respective volume groups
  1651. before deleting the device.
  1652. "));
  1653.         }
  1654.     else if( used == `UB_MD )
  1655.         {
  1656.         // popup text, Do not translate RAID.
  1657.         Popup::Message(_("
  1658. The selected device contains at least one partition
  1659. that is part of a RAID system. Unassign the
  1660. partitions from their respective RAID systems before
  1661. before deleting the device.
  1662. "));
  1663.         }
  1664.     else if( used == `UB_EVMS )
  1665.         {
  1666.         // popup text, Do not translate EVMS.
  1667.         Popup::Message(_("
  1668. The selected device contains at least one partition
  1669. that is used by an EVMS device. Delete the EVMS device
  1670. before deleting the device.
  1671. "));
  1672.         }
  1673.     else if( used != `UB_NONE )
  1674.         {
  1675.         // popup text
  1676.         Popup::Message(_("
  1677. The selected device contains at least one partition
  1678. that is used by another volume. Delete the volume using it
  1679. before deleting the device.
  1680. "));
  1681.         }
  1682.  
  1683.     if( go_on && disk["type"]:`CT_UNKNONW!=`CT_DMRAID )
  1684.         {
  1685.         /////////////////////////////////////////////////
  1686.         // delete all partitions of disk
  1687.         // logical partitions get removed when extended is deleted
  1688.         foreach( map part, partitions,
  1689.         ``{
  1690.         if( part["nr"]:0 <= disk["max_primary"]:4 )
  1691.             {
  1692.             go_on = go_on &&
  1693.                     Storage::DeleteDevice( del_dev, part["device"]:"" );
  1694.             }
  1695.         });
  1696.         }
  1697.     }
  1698.     y2milestone( "deleteAllDevPartitions ret:%1", go_on );
  1699.     return(go_on);
  1700.     };
  1701.  
  1702.  
  1703. }
  1704.