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 / clients / inst_target_part.ycp < prev    next >
Text File  |  2006-11-29  |  12KB  |  425 lines

  1. /**
  2.  * Module:        inst_target_part.ycp
  3.  *
  4.  * Authors:        Andreas Schwab (schwab@suse.de)
  5.  *            Klaus KΣmpf (kkaempf@suse.de)
  6.  *
  7.  * Purpose:        This module ask the user which partition to use:
  8.  *            -Determing possible partitions.
  9.  *            -Ask the user which partition to use.
  10.  *            -Check the input and return error-messages.
  11.  *
  12.  * $Id: inst_target_part.ycp 33868 2006-10-30 15:35:53Z fehr $
  13.  */
  14. {
  15.     textdomain "storage";
  16.  
  17.     import "Arch";
  18.     import "Mode";
  19.     import "Popup";
  20.     import "Storage";
  21.     import "Partitions";
  22.     import "Product";
  23.     import "FileSystems";
  24.  
  25.     // flag for deleting a windows partition
  26.     integer win_partition_to_delete = -1;
  27.  
  28.     // this is the device name !
  29.     string target_is = Storage::GetPartDisk();
  30.  
  31.     // fall through to inst_custom_part if target_is not "USE_DISK"
  32.     if ( Storage::GetPartMode()!="USE_DISK" || Storage::GetCustomDisplay() )
  33.     return Storage::GetExitKey();
  34.  
  35.     // Get test_mode flag from module Mode
  36.     boolean test_mode = Mode::test ();
  37.  
  38.     //-------------------------------------------------------------------------
  39.     // The action
  40.     //-------------------------------------------------------------------------
  41.  
  42.     integer max_partitions = 0;
  43.  
  44.     // The partition number of the first logical partition
  45.     integer first_logical_nr = 5;
  46.  
  47.     integer size_of_swap = 0;
  48.     integer size_of_boot = 0;
  49.     integer max_primary = 0;
  50.     // this will tell if automatic partitioning if feasible
  51.     boolean can_do_auto = false;
  52.  
  53.     list<integer> unused_region = [ 0, 0 ];
  54.  
  55.     include "partitioning/auto_part_functions.ycp";
  56.     include "partitioning/auto_part_prepare.ycp";
  57.     include "partitioning/auto_part_ui.ycp";
  58.     include "partitioning/partition_defines.ycp";
  59.     include "partitioning/auto_part_create.ycp";
  60.     import "Label";
  61.     import "Popup";
  62.  
  63.     // Displays a popup with the message (can be dismissed with OK).
  64.     // After that only `abort or `back is allowed
  65.     // Every other user action ==> redisplay message
  66.     // Parameter: message to be displayed
  67.     // Return   : `back or `abort
  68.     //
  69.     define symbol allow_back_abort_only( string message ) 
  70.     ``{
  71.     symbol ret = `next;
  72.  
  73.     // Enable back and next buttons independent of the settings
  74.     // in installation.ycp so the user has a chance to see the
  75.     // popup more than only once.
  76.     //
  77.     Wizard::EnableNextButton();
  78.     Wizard::EnableBackButton();
  79.  
  80.     repeat 
  81.         {
  82.         Popup::Message( message );    // Display the message
  83.  
  84.         ret= (symbol)UI::UserInput();        // get user input
  85.  
  86.         if( ret == `abort )
  87.         {
  88.         if( !Popup::ReallyAbort(true) )
  89.             {
  90.             // user didn't want to abort ==> stay in loop
  91.             ret = `dummy;
  92.             }
  93.         }
  94.         } until ( ret == `abort || ret == `back );
  95.  
  96.     return( ret );
  97.     };
  98.  
  99.     map win_partition = $[];    // may be needed later in the resize case (is also a flag)
  100.  
  101.     // --------------------------------------------------------------
  102.     // find the selected target in the map of all possible targets
  103.  
  104.     map<string,map> targetMap = Storage::GetTargetMap();
  105.  
  106.     // description of the choosen target disk
  107.     map target = targetMap[target_is]:$[];
  108.  
  109.     if (target == $[]) 
  110.     {
  111.         // popup text
  112.     Popup::Message(_("Your system can only be configured with the custom partitioning option."));
  113.     return `back;
  114.     }
  115.  
  116.     // user visible name of target
  117.     string targetname = target["name"]:"";
  118.  
  119.     // The current list of partitions
  120.     list< map > partitions = target["partitions"]:[];
  121.  
  122.     //-------------------------------------------------------------------------
  123.     // The action
  124.     //-------------------------------------------------------------------------
  125.  
  126.  
  127.     // --------------------------------------------------------------
  128.     // general settings for automatically created partitions
  129.  
  130.     max_partitions = compute_max_partitions(target);
  131.  
  132.     // How much to allocate for swap
  133.     size_of_swap = 1024*1024*Partitions::SwapSizeMb(0);
  134.  
  135.     // --------------------------------------------------------------
  136.     // set size of /boot partition
  137.     size_of_boot = Partitions::MinimalNeededBootsize();
  138.  
  139.     // The number of possible primary partitions
  140.     max_primary = target["max_primary"]:4;
  141.  
  142.     /*==================================================================
  143.      *
  144.      * prepare_partitions
  145.      *
  146.      *=================================================================*/
  147.  
  148.     partitions = prepare_partitions (target, partitions);
  149.  
  150.     SCR::Write( .target.ycp, Storage::SaveDumpPath("prepared_partitions"), 
  151.                 partitions);
  152.     
  153.     term vbox = `Empty();
  154.  
  155.     // show list of partitions if any found (else the disk is completely unpartitioned
  156.  
  157.     if( num_primary(partitions)>0 || contains_extended(partitions) ) 
  158.     {
  159.     // If there is an unpartitioned area on the disk, ask user to use it
  160.     // (this will automatically partition this area)
  161.  
  162.     if( !can_do_auto )
  163.         {
  164.         // There was not enough space to install Linux.
  165.         // Check if we could delete/shrink a windows partition.
  166.         //
  167.         win_partition = can_resize( partitions );
  168.         }
  169.  
  170.     if( win_partition != $[] )
  171.         {
  172.         // this is the resize case
  173.         //
  174.         vbox = create_resize_dialog (partitions, target["cyl_size"]:1 );
  175.         vbox = add_common_widgets( vbox );
  176.         y2milestone ("can resize !");
  177.         }
  178.     else
  179.         {
  180.         // this is the normal case
  181.         //
  182.         map tmp = construct_partition_dialog( partitions, 
  183.                                               target["label"]:"",
  184.                           target["cyl_size"]:1 );
  185.         vbox = add_common_widgets( tmp["term"]:`Empty() );
  186.         }
  187.     }
  188.  
  189.     // no partitions found
  190.  
  191.     else 
  192.     {
  193.     vbox = create_whole_disk_dialog();
  194.     vbox = add_common_widgets( vbox );
  195.     Storage::SetWholeDisk( true );
  196.     }
  197.  
  198.     // Since resize case and normal case have different help texts we need
  199.     // to open different dialogs
  200.     //
  201.     if ( win_partition != $[] ) open_auto_dialog_resize (targetname, vbox);
  202.     else            open_auto_dialog (targetname, vbox);
  203.  
  204.     // Event handling
  205.  
  206.     symbol ret = nil;
  207.  
  208.     boolean ok = false;
  209.     while(!ok)
  210.     {
  211.     ret = (symbol)Wizard::UserInput();
  212.     y2milestone( "USERINPUT ret %1", ret );
  213.  
  214.     if( ret == `lvm && UI::WidgetExists(`id(`evms)) )
  215.         UI::ChangeWidget( `id(`evms), `Value, false );
  216.     else if( ret == `evms && UI::WidgetExists(`id(`lvm)) )
  217.         UI::ChangeWidget( `id(`lvm), `Value, false );
  218.     else if( ret == `abort && Popup::ReallyAbort(true))
  219.         {
  220.         break;
  221.         }
  222.     else if (ret == `full)
  223.         {
  224.         // Set all checkboxes
  225.         foreach (map pentry, partitions, 
  226.         ``{
  227.         symbol ptype = pentry["type"]:`unknown;
  228.         integer ui_id = 0;
  229.         if( ptype != `extended && 
  230.             pentry["fsid"]:0 != Partitions::fsid_mac_hidden ) 
  231.             {
  232.             ui_id = pentry["ui_id"]:0;
  233.             if (ui_id != 0)
  234.             UI::ChangeWidget (`id (ui_id), `Value, true);
  235.             }
  236.         });
  237.         }
  238.     else if( ret == `back )
  239.         {
  240.         ok = true;
  241.         }
  242.     else if( ret == `next )
  243.         {
  244.         if( win_partition != $[] )
  245.         {
  246.         if( UI::QueryWidget( `id(`resize), `Value) == true)
  247.             {
  248.             // The user decided to shrink his windows.
  249.             // Check if this is Windows NT or Windows 2000 (curently not supported)
  250.             //
  251.             integer local_ret = check_win_nt_system( target );
  252.  
  253.             if( test_mode )
  254.             {
  255.             // In test mode we _always_ assume there is no system that could cause problem
  256.             // so the windows resizer is always accessible (e.g. for screen shots).
  257.             local_ret = 0;
  258.             }
  259.  
  260.             if( local_ret == 1 )    // Win NT / 2000
  261.             {
  262.             // The Windows version is Windows NT or Windows 2000. Tell the user that this is currently
  263.             // not supported and that he can go back in the installation or abort it.
  264.             string explanation =  sformat( _("An error has occurred.
  265.  
  266. The Windows version on your system is 
  267. not compatible with the resizing tool.
  268. Shrinking your Windows partition is not possible.
  269.  
  270. Choose a different disk or abort the installation and
  271. shrink your Windows partition by other means.
  272. "));
  273.  
  274.             ret = allow_back_abort_only( explanation );
  275.  
  276.             return( ret );
  277.             }
  278.             else if ( local_ret == 2 )    // local error
  279.             {
  280.             // The Windows version used could not be determined. Tell the user
  281.             // he can go back in the installation or abort it.
  282.             string explanation =  sformat( _("The Windows version of your system could not be determined.
  283.  
  284. It is therefore not possible to shrink your Windows partition.
  285.  
  286. Choose a different disk or abort the installation and
  287. shrink your Windows partition by other means.
  288. "));
  289.  
  290.             ret = allow_back_abort_only( explanation );
  291.  
  292.             return( ret );
  293.             }
  294.  
  295.             // OK --> No NT or 2000
  296.  
  297.             // Tell the user about the risks of resizing his windows.
  298.             // Ask him if he really wants to do it
  299.  
  300.             string explanation = sformat(_("You selected to shrink your Windows partition.
  301. In the next dialog, specify the amount of
  302. Windows space that should be freed for %1.
  303.  
  304. A data backup is strongly recommended
  305. because data must be reorganized. 
  306. Under rare circumstances, this could fail.
  307.  
  308. Only continue if you have successfully run
  309. the Windows system applications scandisk and defrag.
  310.  
  311. Really shrink your Windows partition?
  312. "),Product::name);
  313.  
  314.             if ( ! Popup::AnyQuestion( Popup::NoHeadline(), explanation,
  315.                          // button text
  316.                          _("&Shrink Windows"), Label::CancelButton(), `focus_yes ))
  317.             continue;
  318.             string fat_nr = ""+win_partition["nr"]:-1;
  319.             y2milestone ("Partition '%1' selected for resize", fat_nr);
  320.             Storage::SetDoResize( fat_nr );
  321.             break;
  322.             }
  323.         else 
  324.             {
  325.             // Tell the user about the consequences of deleting his windows.
  326.             // Ask him if he really wants to do it
  327.             string explanation = _("You selected to delete your Windows partition completely.
  328.  
  329. All data on this partition will be lost in the process.
  330.  
  331. Really delete your Windows partition?
  332. ");
  333.             if ( !Popup::AnyQuestion( Popup::NoHeadline(), explanation,
  334.                         // button text
  335.                         _("&Delete Windows"), 
  336.                         Label::CancelButton(), 
  337.                         `focus_yes ))
  338.             continue;
  339.             y2milestone ("Don't resize, use entire partition");
  340.             Storage::SetDoResize( "NO" );
  341.             win_partition_to_delete = tointeger( win_partition["nr"]:-1 );
  342.             Storage::SetWholeDisk( true );
  343.             }
  344.         }
  345.  
  346.         // this will be set when the first win partition is marked
  347.         // for deletion in the foreach() loop
  348.         boolean windows_part_marked_for_deletion = false;
  349.  
  350.         // now loop through partitions and check
  351.         // if the partition is selected
  352.         partitions = maplist( map p, partitions, 
  353.         ``{
  354.         y2milestone( "p:%1", p );
  355.         symbol ptype = p["type"]:`unknown;
  356.         integer ui_id = 0;
  357.         if( ptype != `extended ) 
  358.             {
  359.             ui_id = p["ui_id"]:0;
  360.             boolean selection = p["fsid"]:0 != Partitions::fsid_mac_hidden &&
  361.             (!UI::WidgetExists( `id(ui_id) ) ||
  362.              (UI::QueryWidget( `id(ui_id), `Value)==true));
  363.             y2milestone( "sel:%1", selection );
  364.                    
  365.             if( win_partition_to_delete == p["nr"]:-2 ) 
  366.                 { // -2 !! (not -1 to be different from init)
  367.             selection = true;
  368.             windows_part_marked_for_deletion = true;
  369.             y2milestone( "Windows partition marked for deletion: <%1>",
  370.                          win_partition_to_delete);
  371.             }
  372.             else if (windows_part_marked_for_deletion &&
  373.                  (p["type"]:`dummy == `free)) 
  374.             {
  375.             // trailing free partition after (deleted) windows partition
  376.             selection = true;
  377.             y2milestone ("Trailing `free partition marked for deletion");
  378.             }
  379.             p["delete"] = selection;
  380.             }
  381.         return( p );
  382.         });
  383.         partitions = try_remove_sole_extended( partitions );
  384.  
  385.         y2milestone ("partitions '%1'", partitions);
  386.  
  387.         // Check selection for plausability
  388.         string reason = nil;
  389.         Storage::SetProposalHome( (boolean)UI::QueryWidget( `id(`home), `Value ));
  390.             if( (boolean)UI::QueryWidget( `id(`lvm), `Value )==true )
  391.         Storage::SetProposalLvm(true);
  392.         else if( (boolean)UI::QueryWidget( `id(`evms), `Value )==true )
  393.         Storage::SetProposalEvms(true);
  394.         else
  395.         {
  396.         Storage::SetProposalEvms(false);
  397.         Storage::SetProposalLvm(false);
  398.         }
  399.         ok = create_partitions( targetMap, target, partitions );
  400.         Storage::SetProposalDefault();
  401.         if( !ok )
  402.         {
  403.         reason = _("Too few partitions are marked for removal
  404. or the disk is too small. 
  405. To install Linux, select more partitions to 
  406. remove or select a larger disk.");
  407.         display_error_box (reason);
  408.         }
  409.         }
  410.     } // while (true)
  411.  
  412.     if( ret == `next )
  413.     {
  414.     y2milestone( "Set to inactive" );
  415.     Storage::SetPartProposalActive(false);
  416.     }
  417.     else if( ret == `back || ret == `abort )
  418.         {
  419.     Storage::RestoreTargetBackup("disk");
  420.     }
  421.     Storage::SaveExitKey( ret );
  422.  
  423.     return ret;
  424. }
  425.