ACC SHELL

Path : /usr/share/YaST2/clients/
File Upload :
Current File : //usr/share/YaST2/clients/OneClickInstallUI.ycp

/*
 * User Interface for the One Click Install Feature.
 */
{
	textdomain "oneclickinstall";

	import "OneClickInstall";
	import "OneClickInstallWidgets";
	import "OneClickInstallWorkerResponse";
	import "OneClickInstallWorkerFunctions";
	import "Wizard";
	import "Popup";
	import "Label";
	import "HTTP";
	import "FTP";
	import "UserSettings";

	list args = WFM::Args();

	string SU_CMD = "xdg-su -c";
	integer SU_CMD_FAILURE_CODE = 3;
	string FALLBACK_SU_CMD = "xdg_menu_su";
	string SEPARATOR = "/";

	string metaPackageUrl = "http://opensuse.org/repos.ymp";

	if (size(args) > 0)
		metaPackageUrl = args[0]:metaPackageUrl;

	
	if (substring(metaPackageUrl,0,1) != "/")
	{
		metaPackageUrl = OneClickInstallWorkerFunctions::GrabFile(metaPackageUrl);
		if (metaPackageUrl == nil)
			return false;
	}

	OneClickInstall::Load(metaPackageUrl);

	/** <region name="String constants"> **/

	string HELP1 = _("This wizard will install software on your computer.");
	string HELP2 = _("See <tt>http://en.opensuse.org/One_Click_Install</tt> for more information.");

	/** <region name="Define the UI components"> **/

    string HELP_TEXT =
	"<h3>" + _("Select the software components you wish to install:") + "</h3>"
	+ "<p>" + HELP1 + "</p>"
	+ "<p>" + HELP2 + "</p>";
	//xxx without this the width of the items in the multi-selection-box seems to be broken.
	string SPACER = "                                                                    ";


	boolean confirmCommit()
	{
		if (UserSettings::GetBooleanValue("OneClickInstallUI","CanRead"))
			return true;
		boolean confirmed = OneClickInstallWidgets::ConfirmUI();
		UserSettings::SetValue("OneClickInstallUI","CanRead",OneClickInstallWidgets::GetCanRead());
		return confirmed;
	}
	/** </region> **/
	/** <region name="Setup the Wizard Steps"> **/
	
	list<map> installation_steps_simple = [];
	list<map> installation_widgets_simple = [];

		installation_steps_simple =	
			[
				$[ "id": "splash",		"label": _("Software Description") ],
				$[ "id": "confirm",		"label": _("Installation Settings")	],
				$[ "id": "perform",		"label": _("Perform Installation") ],
				$[ "id": "result",		"label": _("Results") ]
			];

		installation_widgets_simple = 	
			[
				$["id": "splash", "widget":OneClickInstallWidgets::GetDescriptionUI()],
				$["id": "confirm", "widget":OneClickInstallWidgets::GetProposalUI()],
				$["id": "perform", "widget":OneClickInstallWidgets::GetPerformingUI()],
				$["id": "result", "widget":OneClickInstallWidgets::GetResultUI()]
			];	

	list<map> installation_steps = installation_steps_simple;
	list<map> installation_widgets = installation_widgets_simple;

	list<map> installation_steps_advanced  = [];
	list<map> installation_widgets_advanced = [];

	if (OneClickInstall::HaveRepositories() && OneClickInstall::HaveSoftware() && !OneClickInstall::HaveRemovals())
	{
		installation_steps_advanced =	
			[
				$[ "id": "repositoriesUI",	"label": _("Repositories") ],
				$[ "id": "softwareUI",	"label": _("Software")	],
				$[ "id": "confirm",		"label": _("Installation Settings")	],
				$[ "id": "perform",		"label": _("Perform Installation") ],
				$[ "id": "result",		"label": _("Results") ]
			];

		installation_widgets_advanced = 	
			[
				$["id": "repositoriesUI", "widget":OneClickInstallWidgets::GetRepositorySelectionUI()],
				$["id": "softwareUI", "widget":OneClickInstallWidgets::GetSoftwareSelectionUI()],
				$["id": "confirm", "widget":OneClickInstallWidgets::GetProposalUI()],
				$["id": "perform", "widget":OneClickInstallWidgets::GetPerformingUI()],
				$["id": "result", "widget":OneClickInstallWidgets::GetResultUI()]
			];	
	} else if (OneClickInstall::HaveRepositories() && OneClickInstall::HaveSoftware() && OneClickInstall::HaveRemovals())
	{
		installation_steps_advanced =	
			[
				$[ "id": "repositoriesUI",	"label": _("Repositories") ],
				$[ "id": "softwareUI",	"label": _("Software")	],
				$[ "id": "removeUI",	"label": _("Removals")	],
				$[ "id": "confirm",		"label": _("Installation Settings")	],
				$[ "id": "perform",		"label": _("Perform Installation") ],
				$[ "id": "result",		"label": _("Results") ]
			];
		installation_widgets_advanced = 	
			[
				$["id": "repositoriesUI", "widget":OneClickInstallWidgets::GetRepositorySelectionUI()],
				$["id": "softwareUI", "widget":OneClickInstallWidgets::GetSoftwareSelectionUI()],
				$["id": "removeUI", "widget":OneClickInstallWidgets::GetSoftwareRemovalSelectionUI()],
				$["id": "confirm", "widget":OneClickInstallWidgets::GetProposalUI()],
				$["id": "perform", "widget":OneClickInstallWidgets::GetPerformingUI()],
				$["id": "result", "widget":OneClickInstallWidgets::GetResultUI()]
			];	
	} else if (OneClickInstall::HaveRepositories() && !OneClickInstall::HaveSoftware())
	{
		installation_steps_advanced =	
			[
				$[ "id": "repositoriesUI",	"label": _("Repositories") ],
				$[ "id": "confirm",		"label": _("Installation Settings")	],
				$[ "id": "perform",		"label": _("Perform Installation") ],
				$[ "id": "result",		"label": _("Results") ]
			];
		installation_widgets_advanced = 	
			[
				$["id": "repositoriesUI", "widget":OneClickInstallWidgets::GetRepositorySelectionUI()],
				$["id": "confirm", "widget":OneClickInstallWidgets::GetProposalUI()],
				$["id": "perform", "widget":OneClickInstallWidgets::GetPerformingUI()],
				$["id": "result", "widget":OneClickInstallWidgets::GetResultUI()]
			];	
	} else if (!OneClickInstall::HaveRepositories() && OneClickInstall::HaveSoftware() && !OneClickInstall::HaveRemovals())
	{
		installation_steps_advanced =	
			[
				$[ "id": "softwareUI",	"label": _("Software")	],
				$[ "id": "confirm",		"label": _("Installation Settings")	],
				$[ "id": "perform",		"label": _("Perform Installation") ],
				$[ "id": "result",		"label": _("Results") ]
			];
		installation_widgets_advanced = 	
			[
				$["id": "softwareUI", "widget":OneClickInstallWidgets::GetSoftwareSelectionUI()],
				$["id": "confirm", "widget":OneClickInstallWidgets::GetProposalUI()],
				$["id": "perform", "widget":OneClickInstallWidgets::GetPerformingUI()],
				$["id": "result", "widget":OneClickInstallWidgets::GetResultUI()]
			];	
	} else if (!OneClickInstall::HaveRepositories() && OneClickInstall::HaveSoftware() && OneClickInstall::HaveRemovals())
	{
		installation_steps_advanced =	
			[
				$[ "id": "softwareUI",	"label": _("Software")	],
				$[ "id": "removeUI",	"label": _("Removals")	],
				$[ "id": "confirm",		"label": _("Installation Settings")	],
				$[ "id": "perform",		"label": _("Perform Installation") ],
				$[ "id": "result",		"label": _("Results") ]
			];
		installation_widgets_advanced = 	
			[
				$["id": "softwareUI", "widget":OneClickInstallWidgets::GetSoftwareSelectionUI()],
				$["id": "removeUI", "widget":OneClickInstallWidgets::GetSoftwareRemovalSelectionUI()],
				$["id": "confirm", "widget":OneClickInstallWidgets::GetProposalUI()],
				$["id": "perform", "widget":OneClickInstallWidgets::GetPerformingUI()],
				$["id": "result", "widget":OneClickInstallWidgets::GetResultUI()]
			];	
	} else
	{
		installation_steps_advanced = 
			[
				$[ "id": "nothing",	"label": _("Nothing to do.") ],
			];
		installation_widgets_advanced = 	
			[
				$["id": "nothing", "widget":OneClickInstallWidgets::GetIncompatibleYMPUI()]
			];
	}
	
	//Don't display simple mode if not appropriate
	if (!OneClickInstall::HaveAnythingToDo() || !OneClickInstall::HaveBundleDescription() || !OneClickInstall::HaveAnyRecommended())
	{
		installation_steps = installation_steps_advanced;
		installation_widgets = installation_widgets_advanced;
	} else if (OneClickInstall::HaveBundleDescription())
	{
		//Add the splash to the advanced steps too. Requested.
		installation_steps_advanced = prepend(installation_steps_advanced,$[ "id": "splash",		"label": _("Software Description") ]);
		installation_widgets_advanced = prepend(installation_widgets_advanced,$["id": "splash", "widget":OneClickInstallWidgets::GetDescriptionUI()]);
	}
	

	/** </region> **/

	/** <region name="wizardy bits"> **/


	define boolean is_performing(integer no)
	{
		string current_id = (installation_steps[ no ]:nil)["id"]:"";
		return (current_id == "perform");
	};

	define boolean is_confirming(integer no)
	{
		string current_id = (installation_steps[ no ]:nil)["id"]:"";
		return (current_id == "confirm");
	};

	define boolean is_selecting_repositories(integer no)
 	{
		string current_id = (installation_steps[ no ]:nil)["id"]:"";
		return (current_id == "repositoriesUI");
	};

	define boolean is_selecting_software(integer no)
 	{
		string current_id = (installation_steps[ no ]:nil)["id"]:"";
		return (current_id == "softwareUI");
	};

	define boolean is_selecting_removals(integer no)
 	{
		string current_id = (installation_steps[ no ]:nil)["id"]:"";
		return (current_id == "removeUI");
	};

	define boolean is_done(integer no)
 	{
		string current_id = (installation_steps[ no ]:nil)["id"]:"";
		return (current_id == "result");
	};

	define boolean is_viewing_splash(integer no)
 	{
		string current_id = (installation_steps[ no ]:nil)["id"]:"";
		return (current_id == "splash");
	};

	define void SetupWizard()
	{
		UI::WizardCommand(`DeleteSteps());
		Wizard::SetDesktopIcon("sw_single"); // #329644
		Wizard::SetContents (sformat(_("%1 Installation"),OneClickInstall::GetName()), `Empty(), HELP_TEXT, true, true);

		UI::WizardCommand(`AddStepHeading( _("Installation Steps") ) );
		
		foreach ( map step,installation_steps, ``{
			UI::WizardCommand(`AddStep( step["label"]:"", step["id"]:"" ) );
		});
	}
	Wizard::OpenNextBackStepsDialog();
	SetupWizard();


	integer current_step = 0;
	
	boolean done = false;

	/** </region> **/

	/** <region name="wire up the wizard UI to the OCI module">**/
	define list<term> StringListToTermList(list<string> strList,boolean checked)
	{
		list<term> items = [];
		foreach(string str, strList,
		{
			items = add(items,`item(`id(str),str,checked));
		});
		return items;
	}

    define void show_step(integer no)
    {
		if (no == 0)
		{	
			Wizard::DisableBackButton();
		} else
		{
			Wizard::EnableBackButton();
		}

		string current_id = (installation_steps[ no ]:nil)["id"]:"";
		if (is_done(no))
		{
			Wizard::SetNextButton (`finish, Label::FinishButton());
			Wizard::DisableAbortButton();
			Wizard::DisableBackButton();
		}

		UI::ReplaceWidget(`id(`contents),(installation_widgets[ no ]:$[])["widget"]:OneClickInstallWidgets::GetIncompatibleYMPUI());
		Wizard::SetTitleIcon ("yast-software");
	
		UI::WizardCommand(`SetCurrentStep( current_id ) );
		if (is_viewing_splash(no))
		{
			OneClickInstallWidgets::PopulateDescriptionUI(OneClickInstall::GetName(),OneClickInstall::GetSummary(),OneClickInstall::GetDescription());
		}

		if (is_selecting_repositories(no))
		{
			string firstUrl = OneClickInstall::GetRequiredRepositories()[0]:"";
			OneClickInstallWidgets::PopulateRepositorySelectionUI(
				OneClickInstall::GetRepositoryDescription(firstUrl),
				OneClickInstall::GetRequiredRepositories(),
				OneClickInstall::GetNonRequiredRepositories(),
				OneClickInstall::GetRemainSubscribed()
			);
			
		}
		if (is_selecting_software(no))
		{
			string firstname = OneClickInstall::GetRequiredSoftware()[0]:"";
			OneClickInstallWidgets::PopulateSoftwareSelectionUI(
				OneClickInstall::GetSoftwareDescription(firstname),
				OneClickInstall::GetRequiredSoftware(),
				OneClickInstall::GetNonRequiredSoftware()
			);
		}
		if (is_selecting_removals(no))
		{
			string firstname = OneClickInstall::GetRequiredRemoveSoftware()[0]:"";
			OneClickInstallWidgets::PopulateSoftwareRemovalSelectionUI(
				OneClickInstall::GetSoftwareDescription(firstname),
				OneClickInstall::GetRequiredRemoveSoftware(),
				OneClickInstall::GetNonRequiredRemoveSoftware()
			);
		}
    };

	
	void SwitchToAdvancedMode()
	{
		installation_steps = installation_steps_advanced;
		installation_widgets = installation_widgets_advanced;
		SetupWizard();
		if (OneClickInstall::HaveBundleDescription())
			current_step = 1;
		else
			current_step = 0;
		show_step(current_step);
	}

	define boolean events_before_stage_change(integer step, symbol button)
	{
		if (is_selecting_repositories(step))
		{
			OneClickInstall::SetRemainSubscribed(OneClickInstallWidgets::GetRepositoryRemainSubscribed());
		}
		if (is_confirming(step) && (button == `next) )
		{
			return confirmCommit();
		}
		return true;
	}


	define void events_after_stage_change(integer step, symbol button)
	{

		if (is_confirming(step))
		{
			OneClickInstallWidgets::PopulateProposalUI(
				maplist(string s,OneClickInstall::GetRequiredRepositories(), 
					{return s + " (" + OneClickInstall::GetRepositoryName(s) + ")";}),
				OneClickInstall::GetRequiredSoftware(),
				OneClickInstall::GetRequiredRemoveSoftware(),
				OneClickInstall::GetRemainSubscribed()
			);
		}
		if (is_performing(step))
		{
			Wizard::DisableBackButton();
			Wizard::DisableNextButton();

			//I don't think we need to include timestamp/random seed here as yast seems to generate its own for tmpdir.
			string communication_file =(string)SCR::Read (.target.tmpdir) + SEPARATOR + "oneclickinstall.xml";
			OneClickInstall::ToXML(communication_file);

			//Check if we are already root #305354
			map out = (map) SCR::Execute (.target.bash_output, "/usr/bin/id --user");
			boolean root = out["stdout"]:"" == "0\n";
			if(root)
			{
				WFM::call("OneClickInstallWorker",[communication_file]);
			} else
			{
				integer ret = (integer)SCR::Execute (.target.bash, SU_CMD + " '/sbin/yast2 OneClickInstallWorker " + communication_file + "'");
				if (ret == SU_CMD_FAILURE_CODE)
					ret = (integer)SCR::Execute (.target.bash, FALLBACK_SU_CMD + " '/sbin/yast2 OneClickInstallWorker " + communication_file + "'");
			}
			
			//Load the response.
			OneClickInstallWorkerResponse::FromXML(communication_file);

			
			
			current_step = current_step + 1;
			Wizard::EnableNextButton();
			
			show_step( current_step );
			
			OneClickInstallWidgets::PopulateResultUI(
				OneClickInstallWorkerResponse::GetSuccess(),
				OneClickInstallWorkerResponse::GetFailedRepositories(),
				OneClickInstallWorkerResponse::GetFailedPatterns(),
				OneClickInstallWorkerResponse::GetFailedPackages(),
				OneClickInstallWorkerResponse::GetFailureStage(),
				OneClickInstallWorkerResponse::GetErrorMessage(),
				OneClickInstallWorkerResponse::GetNote()
			);
		}
	}
	define void handle_input(symbol button)
	{

		if (button == `repositoriesCheckList)
		{
			//Get the description of this one.
			OneClickInstallWidgets::PopulateRepositorySelectionUIDescription(
				OneClickInstall::GetRepositoryDescription(
					OneClickInstallWidgets::GetCurrentlySelectedRepository()
				)
			);
			//Set all repositories to non-required

			//Set the currently selected repositories back to subscribed. 
			OneClickInstall::SetRequiredRepositories(OneClickInstallWidgets::GetRepositorySelectionItems());
		}

		if (button == `softwareCheckList)
		{
			OneClickInstallWidgets::PopulateSoftwareSelectionUIDescription(
				OneClickInstall::GetSoftwareDescription(
					OneClickInstallWidgets::GetCurrentlySelectedSoftware()
				)
			);
			OneClickInstall::SetRequiredSoftwares(OneClickInstallWidgets::GetSoftwareSelectionItems());
		}

		if (button == `removeCheckList)
		{
			OneClickInstallWidgets::PopulateSoftwareRemovalSelectionUIDescription(
				OneClickInstall::GetSoftwareDescription(
					OneClickInstallWidgets::GetCurrentlySelectedRemoval()
				)
			);
			//Set the currently selected removals back to remove. 
			OneClickInstall::SetRequiredSoftwares(OneClickInstallWidgets::GetSoftwareRemovalSelectionItems());
		}
	}

	/** </region> **/
	/** <region name="event loop">**/
	show_step(0);
    while( !done )
    {
		symbol button = nil;
		repeat
		{
			button = (symbol) UI::UserInput();
			handle_input(button);

		} until ((button != `repositoriesCheckList) && (button != `softwareCheckList));
		if ( button == `abort || button == `cancel)
			break;

		if (button == `alterProposal)
		{
			SwitchToAdvancedMode();
			continue;
		}

		if ( button == `next || button == `back )
		{
			if (events_before_stage_change(current_step,button))
			{

				if ( button == `next && current_step+1 < size( installation_steps ) )
				{
					current_step = current_step + 1;
				}

				if ( button == `back && current_step > 0 )
				{
					current_step = current_step - 1;
				}

				show_step( current_step );

				events_after_stage_change(current_step,button);

				if ( button == `finish )
				{
					done = true;
				}
			}
		}

		if ( button == `finish )
		{
			done = true;
		}
	}
	UI::CloseDialog();
	/** </region> **/
}

ACC SHELL 2018