ACC SHELL

Path : /usr/share/YaST2/include/partitioning/
File Upload :
Current File : //usr/share/YaST2/include/partitioning/ep-main.ycp

/**
 * File:        ep-main.ycp
 * Package:     yast2-storage
 * Summary:     Expert Partitioner
 * Authors:     Arvin Schnell <aschnell@suse.de>
 */
{
    textdomain "storage";

    import "Arch";
    import "Mode";
    import "Stage";
    import "Label";
    import "Hostname";
    import "Event";
    import "ContextMenu";
    import "TabPanel";
    import "TreePanel";
    import "Popup";
    import "Storage";
    import "StorageFields";
    import "StorageIcons";
    import "StorageSettings";
    import "Wizard";
    import "MiniWorkflow";
    import "Greasemonkey";
    import "Partitions";
    import "FileSystems";
    import "DevicesSelectionBox";
    import "Integer";
    import "String";
    import "Region";
    import "ProductFeatures";
    import "Directory";
    import "HTML";
    import "Map";
    import "Icon";

    include "partitioning/lvm_ui_dialogs.ycp";
    include "partitioning/raid_lib.ycp";
    include "partitioning/custom_part_check_generated.ycp";


    // dialog caption
    string caption = _("Expert Partitioner");


    void UpdateMainStatus();


    void UpdateNavigationTree(any new_focus);


    void UpdateTableFocus(string device)
    {
	if (UI::WidgetExists(`id(`table)))
	    UI::ChangeWidget(`id(`table), `CurrentItem, device);
    }


    void EpContextMenuDevice(string device);


    include "partitioning/ep-lib.ycp";
    include "partitioning/ep-dialogs.ycp";
    include "partitioning/ep-import.ycp";

    include "partitioning/ep-all.ycp";
    include "partitioning/ep-hd.ycp";
    include "partitioning/ep-lvm.ycp";
    include "partitioning/ep-raid.ycp";
    include "partitioning/ep-loop.ycp";
    include "partitioning/ep-dm.ycp";
    include "partitioning/ep-nfs.ycp";
    include "partitioning/ep-unused.ycp";

    include "partitioning/ep-graph.ycp";
    include "partitioning/ep-summary.ycp";
    include "partitioning/ep-settings.ycp";
    include "partitioning/ep-log.ycp";


    void UpdateMainStatus()
    {
	if (Mode::normal())
	{
	    string next_label = Storage::EqualBackupStates("expert-partitioner", "", true) ?
		Label::FinishButton() : Label::NextButton();

	    Wizard::SetNextButton(`next, next_label);
	}
    }


    void MakeNavigationTree(map open_items, list<term>& tree, map<any, map>& data)
    {
	// TODO: somehow use AlwaysHideDisk

	data = $[ `all : $[ `create : CreateAllPanel, `handle : HandleAllPanel ],
		  `hd : $[ `create : CreateHdMainPanel, `handle : HandleHdMainPanel ],
		  `lvm : $[ `create : CreateLvmMainPanel, `handle : HandleLvmMainPanel ],
		  `md : $[ `create : CreateRaidMainPanel, `handle : HandleRaidMainPanel ],
		  `loop : $[ `create : CreateLoopMainPanel, `handle : HandleLoopMainPanel ],
		  `dm : $[ `create : CreateDmMainPanel, `handle : HandleDmMainPanel ],
		  `nfs : $[ `create : CreateNfsMainPanel, `handle : HandleNfsMainPanel ],
		  `unused : $[ `create : CreateUnusedPanel, `handle : HandleUnusedPanel ],
		  `devicegraph : $[ `create : CreateDeviceGraphPanel, `refresh : RefreshDeviceGraphPanel, `handle : HandleDeviceGraphPanel ],
		  `mountgraph : $[ `create : CreateMountGraphPanel, `refresh : RefreshDeviceGraphPanel, `handle : HandleMountGraphPanel ],
		  `summary : $[ `create : CreateSummaryPanel ],
		  `settings : $[ `create : CreateSettingsPanel, `handle : HandleSettingsPanel, `destroy : DestroySettingsPanel ],
		  `log : $[ `create : CreateLogPanel, `handle : HandleLogPanel, `destroy : DestroyLogPanel ] ];

	map<symbol, list> subtree = $[];

	map<string, map> target_map = Storage::GetTargetMap();


	boolean open(any id)
	{
	    return open_items[id]:"" == "ID";
	}


	void huhu(map disk, symbol type, map a, map b)
	{
	    string disk_device = disk["device"]:"";

	    list<map> partitions = disk["partitions"]:[];
	    partitions = filter(map partition, partitions, {
		return !StorageFields::AlwaysHidePartition(target_map, disk, partition);
	    });

	    list<term> tmp = [];
	    foreach(map partition, partitions, {
		string part_device = partition["device"]:"";
		string part_displayname = StorageSettings::DisplayName(partition);
		tmp = add(tmp, `item(`id(part_device), part_displayname, open(part_device)));
		data = add(data, part_device, union(a, $[ `user_data : part_device ]));
	    });

	    if (b != nil)
	    {
		string disk_displayname = StorageSettings::DisplayName(disk);
		subtree[type] = add(subtree[type]:[], `item(`id(disk_device), disk_displayname, open(disk_device), tmp));
		data = add(data, disk_device, union(b, $[ `user_data : disk_device ]));
	    }
	    else
	    {
		subtree[type] = merge(subtree[type]:[], tmp);
	    }
	}


	void callback(map<string, map> target_map, map disk)
	{
	    symbol type = disk["type"]:`CT_UNKNOWN;

	    switch(type)
	    {
		case `CT_DISK:
		case `CT_DMRAID:
		case `CT_DMMULTIPATH:
		case `CT_MDPART:
		    huhu(disk, `hd, $[ `create : CreateHdPartitionPanel, `handle : HandleHdPartitionPanel ],
			 $[ `create : CreateHdDiskPanel, `handle : HandleHdDiskPanel ]);
		    break;
		case `CT_LVM:
		    huhu(disk, `lvm, $[ `create : CreateLvmLvPanel, `handle : HandleLvmLvPanel ],
			 $[ `create : CreateLvmVgPanel, `handle : HandleLvmVgPanel ]);
		    break;
		case `CT_MD:
		    huhu(disk, `md, $[ `create : CreateRaidPanel, `handle : HandleRaidPanel ], nil);
		    break;
		case `CT_LOOP:
		    huhu(disk, `loop, $[ `create : CreateLoopPanel, `handle : HandleLoopPanel ], nil);
		    break;
		case `CT_DM:
		    huhu(disk, `dm, $[ `create : CreateDmPanel, `handle : HandleDmPanel ], nil);
		    break;
		case `CT_NFS:
		    huhu(disk, `nfs, $[ `create : CreateNfsPanel, `handle: HandleNfsMainPanel ], nil);
		    break;
	    }
	}


	StorageFields::IterateTargetMap(target_map, callback);

	string short_hostname = Hostname::CurrentHostname();

	// TODO: same ordering as with IterateTargetMap
	tree = [ `item(`id(`all), `icon(StorageIcons::all_icon), short_hostname, open(`all), [
			   // tree node label
			   `item(`id(`hd), `icon(StorageIcons::hd_icon), _("Hard Disks"), open(`hd), subtree[`hd]:[]),
			   // tree node label
			   `item(`id(`md), `icon(StorageIcons::raid_icon), _("RAID"), open(`md), subtree[`md]:[]),
			   // tree node label
			   `item(`id(`lvm), `icon(StorageIcons::lvm_icon), _("Volume Management"), open(`lvm), subtree[`lvm]:[]),
			   // tree node label
			   `item(`id(`loop), `icon(StorageIcons::loop_icon), _("Crypt Files"), open(`loop), subtree[`loop]:[]),
			   // tree node label
			   `item(`id(`dm), `icon(StorageIcons::dm_icon), _("Device Mapper"), open(`dm), subtree[`dm]:[]),
			   // tree node label
			   `item(`id(`nfs), `icon(StorageIcons::nfs_icon), _("NFS"), open(`nfs)),
			   // tree node label
			   `item(`id(`unused), `icon(StorageIcons::unused_icon), _("Unused Devices"), open(`unused))
			   ])
	    ];

	if (UI::HasSpecialWidget(`Graph))
	{
	    // tree node label
	    tree = add(tree, `item(`id(`devicegraph), `icon(StorageIcons::graph_icon), _("Device Graph"), open(`devicegraph)));
	    // tree node label
	    tree = add(tree, `item(`id(`mountgraph), `icon(StorageIcons::graph_icon), _("Mount Graph"), open(`mountgraph)));
	}
	

	// tree node label
	tree = add(tree, `item(`id(`summary), `icon(StorageIcons::summary_icon), _("Installation Summary"), open(`summary)));

	// tree node label
	tree = add(tree, `item(`id(`settings), `icon(StorageIcons::settings_icon), _("Settings"), open(`settings)));

	if (Mode::normal())
	    // tree node label
	    tree = add(tree, `item(`id(`log), `icon(StorageIcons::log_icon), _("Log"), open(`log)));
    }


    void UpdateNavigationTree(any new_focus)
    {
	list<term> tree = [];
	map<any, map> data = $[];
	map open_items = (map) UI::QueryWidget(`id(`tree), `OpenItems);
	MakeNavigationTree(open_items, tree, data);
	TreePanel::Update(data, tree, new_focus);
    }


    void EpContextMenuDevice(string device)
    {
	map<string, map> target_map = Storage::GetTargetMap();

	map disk = nil;
	map part = nil;

	SplitDevice(target_map, device, disk, part);

	switch (disk["type"]:`unknown)
	{
	    case `CT_DISK:  
	    case `CT_MDPART:
	    case `CT_DMRAID:
	    case `CT_DMMULTIPATH:
		if (part == nil)
		    EpContextMenuHdDisk(device);
		else
		    EpContextMenuHdPartition(device);
		break;

	    case `CT_MD:
		if (part != nil)
		    EpContextMenuRaid(device);
		break;

	    case `CT_LOOP:
		if (part != nil)
		    EpContextMenuLoop(device);
		break;

	    case `CT_LVM:
		if (part == nil)
		    EpContextMenuLvmVg(device);
		else
		    EpContextMenuLvmLv(device);
		break;

	    case `CT_DM:
		if (part != nil)
		    EpContextMenuDm(device);
		break;
	}
    }


    /**
     * Confirm leaving the module
     */
    boolean ReallyQuit( string label )
    {
	// popup text, %1 will be replaces with button text
	string text = sformat(_("You have changed the partitioning or storage settings. These changes
will be lost if you exit the partitioner with %1.
Really exit?"), deletechars(label, "&"));

	return Popup::YesNo(text);
    }


    string SummaryDialogHelptext()
    {
	// helptext
	string helptext = _("<p>Here you can see the partitioning summary.</p>");

	return helptext;
    }


    /**
     * Fullscreen summary of changes
     */
    symbol SummaryDialog()
    {
	symbol ret = `none;

	Wizard::CreateDialog();
	Wizard::SetContentsButtons(caption + _(": Summary"),
				   `VBox(`RichText(CompleteSummary())),
				   SummaryDialogHelptext(),
				   Label::BackButton(),
				   Label::FinishButton());
	Wizard::SetDesktopIcon("disk");

	while (true)
	{
	    ret = (symbol) UI::UserInput();

	    if (ret == `next || ret == `back)
		break;

	    if( ret == `abort && ReallyQuit( Label::AbortButton() ))
	    {
		ret =`abort;
		break;
	    }
	}

	Wizard::CloseDialog();
	y2milestone("Summary dialog returned %1", ret);
	return ret;
    }


    /**
     * apply changes in running system
     */
    symbol DoApply()
    {
	symbol ret1 = SummaryDialog();

	if (ret1 == `back)
	{
	    return `back;
	}
	else if (ret1 == `next)
	{
	    Wizard::CreateDialog();
	    Wizard::SetDesktopIcon("disk");
	    symbol ret2 = (symbol) WFM::CallFunction("inst_prepdisk", [true, true]);
	    StorageSettings::Save();
	    Wizard::CloseDialog();

	    Storage::CreateTargetBackup("expert-partitioner");

	    if (ret2 != `next)
		return `back;
	    else
		return `next;
	}
    }


    symbol ExpertPartitioner()
    {
	SCR::Write(.target.ycp, Storage::SaveDumpPath("targetmap-ep-start"), Storage::GetTargetMap());

	Storage::CreateTargetBackup("expert-partitioner");

	list<term> tree = [];
	map<any, map> data = $[];
	MakeNavigationTree($[`all : "ID"], tree, data);

	string back_label = Label::BackButton();
	string next_label = Mode::normal() ? Label::FinishButton() : Label::AcceptButton();
	string abort_label = Label::AbortButton();

	term contents = `MarginBox(0.5, 0.5,
				  `HBox(
				      `HWeight(30,
					       // tree node label
					       `Tree(`id(`tree), `opt(`notify), _("System View"), tree)
					  ),
				      `HWeight(70,
					       `ReplacePoint(`id(`tree_panel), TreePanel::empty_panel)
					  )
				      )
	    );

	// heading text
	Wizard::SetContentsButtons(caption, contents, "", back_label, next_label);
	if (Mode::normal())
	   Wizard::HideBackButton();

	TreePanel::Init(data);

	symbol widget = nil;

	repeat
	{
	    map event = Wizard::WaitForEvent();

	    TreePanel::Handle(event);

	    widget = event["ID"]:(symbol) nil;

	    switch (widget)
	    {
		case `back:
		case `abort: {
		    if (!Storage::EqualBackupStates("expert-partitioner", "", true))
		    {
			if (!ReallyQuit(widget == `back ? back_label : abort_label))
			    widget = `again;
		    }
		} break;

		case `next: {
		    if (!Storage::EqualBackupStates("expert-partitioner", "", true) || StorageSettings::GetModified())
		    {
		        if (!check_created_partition_table(Storage::GetTargetMap(),
							   Stage::initial() && !Mode::repair()))
		        {
		            widget = `again;
		        }
		        else
		        {
		            if (Mode::normal())
		            {
		                if (DoApply() == `back)
				    widget = `again;
		            }
		        }
		    }
		    else
		    {
			y2milestone("No changes to partitioning - nothing to do");
			widget = `abort;
		    }
		} break;
	    }

	    switch (Event::IsWidgetActivated(event))
	    {
		case `table: {
		    any citem = UI::QueryWidget(`id(`table), `CurrentItem);
		    TreePanel::SwitchToNew(citem);
		    UI::SetFocus( UI::WidgetExists(`id(`table)) ? `id(`table) : `id(`text));
		} break;
	    }
	}
	until (widget == `back || widget == `abort || widget == `next);

	TreePanel::Destroy();

	switch (widget)
	{
	    case `back:
	    case `abort:

		if (Storage::GetPartMode() == "NORMAL")
		    Storage::SetPartMode("CUSTOM");

		break;

	    case `next:

		if (!Storage::EqualBackupStates("expert-partitioner", "", true))
		{
		    Storage::SetPartMode("CUSTOM");
		    Storage::UpdateChangeTime();
		}

		break;
	}

	Storage::DisposeTargetBackup("expert-partitioner");

	SCR::Write(.target.ycp, Storage::SaveDumpPath("targetmap-ep-end"), Storage::GetTargetMap());

	return widget;
    }
}

ACC SHELL 2018