ACC SHELL

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

/**
 * Module: 		repositories.ycp
 *
 * Author:		Cornelius Schumacher <cschum@suse.de>
 *			Ladislav Slezak <lslezak@suse.cz>
 *
 * Purpose:
 * Adding, removing and prioritizing of repositories for packagemanager.
 *
 * $Id: repositories.ycp 62077 2010-05-31 19:42:12Z lslezak $
 *
 */

{
    textdomain "packager";

    import "Confirm";
    import "Mode";
    import "PackageCallbacks";
    import "PackageLock";
    import "Report";
    // SourceManager overlaps quite a bit with inst_source,
    // so far we only use it for ZMD sync, TODO refactor better
    import "SourceManager";
    import "SourceDialogs";
    import "Wizard";

    import "Label";
    import "Popup";
    import "Sequencer";
    import "CommandLine";
    import "Progress";
    import "Directory";
    import "URL";

    include "packager/inst_source_dialogs.ycp";
    include "packager/key_manager_dialogs.ycp";
    include "packager/repositories_include.ycp";

    boolean full_mode = false;

    // cache for textmode value
    boolean text_mode = nil;

    boolean textmode()
    {
	if (text_mode == nil)
	{
	    text_mode = Mode::commandline() ? true : UI::GetDisplayInfo()["TextMode"]:false;
	}

	return text_mode;
    }


    list<integer> sourcesToDelete = [];
    list<integer> reposFromDeletedServices = [];

    // default (minimal) priority of a repository
    const integer default_priority = 99;

    const string priority_label = _("&Priority");

    const string keeppackages_label = _("Keep Downloaded Packages");

    // current view:
    // selected service (or empty) if all services are selected
    string displayed_service = "";
    // service/repository view flag
    boolean repository_view = true;

    void RemoveDeletedAddNewRepos () {
	list<map<string,any> > ret = [];

	list <integer> current_sources = Pkg::SourceGetCurrent (false);
	list <integer> known_repos = [];
	list <integer> deleted_repos = [];

	// sources deleted during this script run
	foreach (map<string,any> one_source, sourceStatesIn, {
	    integer src_id = tointeger (one_source["SrcId"]:nil);
	    if (src_id != nil) deleted_repos = add (deleted_repos, src_id);
	});

	// sources is a copy of sourceStatesOut
	foreach (map<string,any> one_source, sourceStatesOut, {
	    integer src_id = tointeger (one_source["SrcId"]:nil);

	    if (contains (current_sources, src_id)) {
		if (src_id != nil) known_repos = add (known_repos, src_id);
		ret = add (ret, one_source);
	    } else {
		y2milestone ("Source %1 has been removed already", one_source);
	    }
	});

	foreach (integer one_srcid, current_sources, {
	    // already known repository
	    if (contains (known_repos, one_srcid)) return;
	    // already deleted repository
	    if (contains (deleted_repos, one_srcid)) return;
	    // already deleted repository
	    if (contains (SourceManager::just_removed_sources, one_srcid)) return;

	    // repository has been added recently (by some external functionality
	    // that doesn't use these internal variables)
	    map <string,any> generalData = Pkg::SourceGeneralData (one_srcid);
	    generalData["enabled"] = true;
	    generalData["SrcId"] = one_srcid;
	    y2milestone ("New repository found: %1", generalData);
	    ret = add (ret, generalData);
	});

	sourceStatesOut = ret;
    }

    string PriorityToString(integer priority)
    {
	string ret = tostring(priority);

	// pad to 3 characters
	integer rest = 3 - size(ret);
	while(rest > 0) {
	    ret = " " + ret;
	    rest = rest - 1;
	}

	if (priority == default_priority)
	{
	    ret = ret + " (" + _("Default") + ")";
	}

	return ret;
    }

    list<map<string,any> > ReposFromService(string service, list<map<string,any> > input)
    {
	return filter(map<string,any> repo, input,
	    {
		return repo["service"]:"" == service;
	    }
	);
    }

    /**
        Create a table item from a map as returned by the InstSrcManager agent.
        @param source The map describing the source as returned form the agent.
        @return An item suitable for addition to a Table.
    */
    define term createItem( integer index, map source, boolean repository_mode ) ``{
        integer id = source[ "SrcId" ]:0;
        map generalData = Pkg::SourceGeneralData( id );
	y2milestone("generalData(%1): %2", id, generalData);

	string name = repository_mode ? (haskey(source, "name") ?
	    source["name"]:"" :
	    // unkown name (alias) of the source
	    generalData[ "alias" ]:generalData[ "type" ]: _("Unknown Name"))
	    : source["name"]:"";

	integer priority = source["priority"]:default_priority;
	string url = repository_mode ? generalData["url"]:"" : source["url"]:"";
	string service_alias = source["service"]:"";
	string service_name = service_alias != "" ? Pkg::ServiceGet(service_alias)["name"]:"" : "";

        term item = repository_mode ?
	    `item(
		`id( index ),
		PriorityToString(priority),
		// corresponds to the "Enable/Disable" button
		source[ "enabled" ]:true ? UI::Glyph (`CheckMark) : "",
		source[ "autorefresh" ]:true ? UI::Glyph (`CheckMark) : "",
		// translators: unknown name for a given source
		name,
		service_name,
		url
	    )
	    : `item(
		`id( index ),
		// corresponds to the "Enable/Disable" button
		source[ "enabled" ]:true ? UI::Glyph (`CheckMark) : "",
		source[ "autorefresh" ]:true ? UI::Glyph (`CheckMark) : "",
		// translators: unknown name for a given source
		name,
		url
	    );

        return item;
    }

    map<string,any> getSourceInfo (integer index, map source) {
        integer id = source[ "SrcId" ]:0;
        map generalData = Pkg::SourceGeneralData( id );
	y2milestone("generalData(%1): %2", id, generalData);

	// get the editable propertis from 'source' parameter,
	// get the fixed propertis from the package manager
	map<string,any> out = $[
	    "enabled" : source["enabled"]:true,
	    "autorefresh" : source["autorefresh"]:true,
	    "name" : source["name"]:_("Unknown Name"),
	    "url" : generalData[ "url" ]:"",
	    "type" : generalData["type"]:"",
	    "priority" : source["priority"]:default_priority,
	    "service" : source["service"]:"",
	    "keeppackages" : source["keeppackages"]:false,
	];
        return out;

    }

    /**
     * Fill sources table with entries from the InstSrcManager agent.
     */
    define void fillTable(boolean repo_mode, string service_name)
    {
	y2milestone ("Filling repository table: repository mode: %1, service: %2", repo_mode, service_name);
        list items = [];

	if (repo_mode)
	{
	    // because Online Repositories / Community Repositories don't use
	    // these internal data maps
	    RemoveDeletedAddNewRepos();
	}

	list<map<string,any> > itemList = repo_mode ? sourceStatesOut : serviceStatesOut;

	// displaye only repositories from the selected service
	if (repo_mode && service_name != "")
	{
	    itemList = ReposFromService(service_name, itemList);
	}

        integer numItems = size(itemList);

        integer i = 0;
        while ( i < numItems ) {
            items = add( items, createItem( i, itemList[ i ]:$[], repo_mode ) );
            i = i + 1;
        }

	y2milestone("New table content: %1", items);

        UI::ChangeWidget( `id( `table ), `Items, items );
    }

    string repoInfoRichText(string name, string raw_url, string category)
    {
	string schema  = tolower(URL::Parse(raw_url)["scheme"]:"");
	string icon_tag = "<IMG SRC=\"" + Directory::icondir + "/22x22/apps/"
	    + ((schema == "cd" || schema == "dvd" || schema == "iso") ? "yast-cd_update.png" : "yast-http-server.png")
	    + "\">&nbsp;&nbsp;&nbsp;";

	if (raw_url == "")
	{
	    raw_url = _("Unknown");
	}

	string url  = sformat (_("URL: %1"), raw_url);

	return sformat("<P>%1<B><BIG>%2</BIG></B></P><P>%3<BR>%4</P>", icon_tag, name, url, category);
    }

    term repoInfoTerm()
    {
	return textmode() ?
	`VBox (
	     `Left(`Heading(`id(`name), `opt(`hstretch), "")),
	     `Left(`Label(`id(`url), `opt(`hstretch), "")),
	     `Left(`Label(`id(`category), `opt(`hstretch), ""))
	     )
	:
	`VSquash(`MinHeight(4, `RichText(`id(`repo_info), "")));
    }

    void fillRepoInfo(integer index, map source, boolean repo_mode, string service_name)
    {
	map<string,any> info = repo_mode ? getSourceInfo (index, source) : source;
	if (repo_mode)
	{
	    y2milestone("getSourceInfo(%1, %2): %3", index, source, info);
	}

	// heading - in case repo name not found
	string name = info["name"]:_("Unknown repository name");

	// label to be used instead of URL if not found
	string url  = sformat (_("URL: %1"), info["url"]:_("Unknown") );

	// label, %1 is repo category (eg. YUM)
	string category = sformat (_("Category: %1"), info["type"]:_("Unknown"));

	// label, %1 is repo category (eg. YUM)
	string service = info["service"]:"";

	if (service != "")
	{
	    map service_info = Pkg::ServiceGet(service);
	    service = sformat (_("Service: %1"), service_info["name"]:"");
	}

	// don't display category for services
	if (!repo_mode)
	{
	    category = "";
	}

	if (textmode())
	{
	    UI::ChangeWidget(`id(`name), `Label, name);
	    UI::ChangeWidget(`id(`url), `Label, url);
	    UI::ChangeWidget(`id(`category), `Label, category);
	}
	else
	{
	    UI::ChangeWidget(`id(`repo_info), `Value, repoInfoRichText(name, info["url"]:"", category));
	}

	UI::ChangeWidget (`id (`enable), `Value, info["enabled"]:true);
	UI::ChangeWidget (`id (`autorefresh), `Value, info["autorefresh"]:true);

	if (repo_mode)
	{
	    // priority and keeppackages are displayed only for repositories
	    UI::ChangeWidget (`id (`priority), `Value, info["priority"]:default_priority);
	    UI::ChangeWidget (`id (`keeppackages), `Value, info["keeppackages"]:false);
	}
    }

    void clearRepoInfo()
    {
	if (textmode())
	{
	    UI::ChangeWidget(`id(`name), `Label, "");
	    UI::ChangeWidget(`id(`url), `Label, "");
	    UI::ChangeWidget(`id(`category), `Label, "");
	}
	else
	{
	    UI::ChangeWidget(`id(`repo_info), `Value, "");
	}

	UI::ChangeWidget (`id (`enable), `Value, false);
	UI::ChangeWidget (`id (`autorefresh), `Value, false);

	if (UI::WidgetExists(`id(`priority)))
	{
	    // priority is displayed only for repositories
	    UI::ChangeWidget (`id (`priority), `Value, default_priority);
	}
    }

    void fillCurrentRepoInfo () {
	integer selected = (integer)UI::QueryWidget (`id (`table), `CurrentItem);
	if (selected == nil)
	{
	    clearRepoInfo();
	    return;
	}

	map data = (repository_view) ?
	    ((displayed_service == "") ? sourceStatesOut[selected]:$[] :
		ReposFromService(displayed_service, sourceStatesOut)[selected]:$[]
	    )
	    : serviceStatesOut[selected]:$[];

	fillRepoInfo (selected, data, repository_view, displayed_service);
    }

    /**
     * Find which repositories have to be added or deleted to ZENworks.
     * #182992: formerly we did not consider the enabled attribute.
     * But ZENworks cannot completely disable a repository (unsubscribing a
     * repository merely decreases its priority) so we consider a disabled repository
     * like a deleted one.
     * @param statesOld sourceStates{In or Out}
     * @param statesNew sourceStates{In or Out}
     * @return the list of SrcId's that are enabled in statesNew
     *  but are not enabled in statesOld
     */
    list<integer> newSources (list<map<string,any> > statesOld,
			      list<map<string,any> > statesNew) {
	y2milestone ("From %1 To %2", statesOld, statesNew);
	list<integer> ret = [];
	map<integer, boolean> seen = listmap (
	    map<string, any> src, statesOld,
	    ``( $[(src["SrcId"]:-1) : (src["enabled"]:true) ] ));
	foreach (map<string, any> src, statesNew, {
	    integer newid = src["SrcId"]:-1;
	    boolean newena = src["enabled"]:true;
	    if (newena && ! seen[newid]:false)
		ret = add (ret, newid);
	});
	y2milestone ("Difference %1", ret);
	return ret;
    }

    list<string> newServices (list<map<string,any> > statesOld,
			      list<map<string,any> > statesNew) {
	y2milestone ("Services from %1 To %2", statesOld, statesNew);
	list<string> ret = [];

	list<string> seen = maplist (
	    map<string, any> srv, statesOld,
	    {
		return srv["alias"]:"";
	    }
	);

	foreach (map<string, any> srv, statesNew, {
	    string alias = srv["alias"]:"";

	    y2milestone("Checking %1", alias);

	    if (!contains(seen, alias))
	    {
		ret = add (ret, alias);
	    }
	});
	y2milestone ("Difference %1", ret);
	return ret;
    }

    define void deleteSource( integer index ) ``{
	integer srcid = sourceStatesOut[index, "SrcId"]:-1;

	if (srcid != -1) {
	    sourcesToDelete = add (sourcesToDelete, srcid);
	    SourceManager::just_removed_sources = add (SourceManager::just_removed_sources, srcid);
	}

        sourceStatesOut = remove( sourceStatesOut, index );
    }

    define void deleteService(integer index)
    {
	y2milestone("Removing service: %1", index);
        serviceStatesOut = remove(serviceStatesOut, index);
    }

    boolean Write() {
	boolean success = true;

	// evaluate removed and new services
	list<string> deleted_services = newServices(serviceStatesOut, serviceStatesIn);
	y2milestone("Deleted services: %1", deleted_services);
	list<string> added_services   = newServices(serviceStatesIn, serviceStatesOut);
	y2milestone("Added services: %1", added_services);

	foreach(string alias, deleted_services,
	    {
		y2milestone("Removing service %1", alias);
		success = success && Pkg::ServiceDelete(alias);
	    }
	);

	y2milestone("New service config: %1", serviceStatesOut);
	foreach(map<string,any> s, serviceStatesOut,
	    {
		string alias = s["alias"]:"";

		if (contains(added_services, alias))
		{
		    y2milestone("Adding service %1", alias);
		    string new_url = s["url"]:"";

		    if (new_url != "")
		    {
			y2milestone("aliases: %1", Pkg::ServiceAliases());
			success = success && Pkg::ServiceAdd(alias, new_url);
			// set enabled and autorefresh flags
			success = success && Pkg::ServiceSet(alias, s);
		    }
		    else
		    {
			y2error("Empty URL for service %1", alias);
		    }
		}
		else
		{
		    y2milestone("Modifying service %1", alias);
		    success = success && Pkg::ServiceSet(alias, s);
		}
	    }
	);

	y2milestone("New repo config: %1", sourceStatesOut);
	success = success && Pkg::SourceEditSet( sourceStatesOut );

	// we must sync before the repositories are deleted from zypp
	// otherwise we will not get their details
	list<integer> added   = newSources (sourceStatesIn, sourceStatesOut);
	list<integer> deleted = newSources (sourceStatesOut, sourceStatesIn);

	foreach( integer id, sourcesToDelete, ``{
	    if (contains(reposFromDeletedServices, id))
	    {
		y2milestone("Repository %1 has been already removed (belongs to a deleted service)", id);
	    }
	    else
	    {
		success = success && Pkg::SourceDelete(id);
	    }
	});

	boolean refresh_enabled = contains(WFM::Args(), "refresh-enabled");

	foreach(map<string,any> src_state, sourceStatesOut,
	    {
		integer srcid = src_state["SrcId"]:-1;

		if (refresh_enabled && contains(added, srcid))
		{
		    y2milestone("Refreshing enabled repository: %1", srcid);
		    src_state["do_refresh"] = true;
		}

		if (src_state["do_refresh"]:false)
		{
		    y2milestone("Downloading metadata for source %1", srcid);

		    success = success && Pkg::SourceRefreshNow(srcid);
		}
	    }
	);

	success = success && KeyManager::Write();

	// store repositories and services in the persistent libzypp storage
	success = success && Pkg::SourceSaveAll(); // #176013

	return success;
   }

list<term> buildList()
{
    list<term> ret = [
	`item(`id(`all_repositories), _("All repositories"), repository_view),
	`item(`id(`all_services), _("All services"), !repository_view && displayed_service == "")
    ];

    foreach(map<string,any> srv_state, serviceStatesOut,
	{
	    term t = `item(`id(srv_state["alias"]:""), sformat(_("Service '%1'"), srv_state["name"]:""), repository_view && displayed_service == srv_state["alias"]:"");
	    ret = add(ret, t);
	}
    );

    return ret;
}

term RepoFilterWidget()
{
    // combobox label
    return `ComboBox(`id(`service_filter), `opt(`notify), _("View"), buildList());
}

void UpdateCombobox()
{
    UI::ReplaceWidget(`id(`filter_rp), RepoFilterWidget());
}

// return table widget definition
// layout of the table depends on the current mode (services do not have priorities)
term TableWidget(boolean repository_mode)
{
    term tabheader = repository_mode ?
	    `header(
		// table header - priority of the repository - keep the translation as short as possible!
		_("Priority"),
		// table header - is the repo enabled? - keep the translation as short as possible!
		`Center(_("Enabled")),
		// table header - is autorefresh enabled for the repo?
		// keep the translation as short as possible!
		`Center(_("Autorefresh")),
		// table header - name of the repo
		_("Name"),
		// table header - service to which the repo belongs
		_("Service"),
		// table header - URL of the repo
		_("URL") )
	    :
	    `header(
		// table header - is the repo enabled? - keep the translation as short as possible!
		`Center(_("Enabled")),
		// table header - is autorefresh enabled for the repo?
		// keep the translation as short as possible!
		`Center(_("Autorefresh")),
		// table header - name of the repo
		_("Name"),
		// table header - URL of the repo
		_("URL") );


    return `Table(`id(`table),`opt(`notify, `immediate), tabheader, []);
}

void ReplaceWidgets(boolean repo_mode)
{
    y2milestone("Replacing the table widget");
    UI::ReplaceWidget(`id(`tabrp), TableWidget(repo_mode));

    UI::ReplaceWidget(`id(`priorp), repo_mode ? `IntField(`id(`priority), `opt(`notify), priority_label, 0, 200, default_priority) : `Empty());
    UI::ReplaceWidget(`id(`keeppkg_rp), repo_mode ? `CheckBox(`id(`keeppackages), `opt(`notify), keeppackages_label) : `Empty());
}

void RemoveReposFromService(string service_alias)
{
    // delete the repositories belonging to the service
    list<map<string,any> > repos = ReposFromService(service_alias, sourceStatesOut);
    y2milestone("Removing repos from service alias=%1: %2", service_alias, repos);

    foreach(map<string,any> repo, repos,
	{
	    integer srcid = repo["SrcId"]:-1;

	    if (srcid != -1) {
		sourcesToDelete = add (sourcesToDelete, srcid);
		SourceManager::just_removed_sources = add (SourceManager::just_removed_sources, srcid);
	    }

	    sourceStatesOut = filter (map<string,any> srcstate, sourceStatesOut,
		{
		    if (srcstate["SrcId"]:-1 == srcid)
		    {
			y2milestone("Removing repository %1", srcstate);
			reposFromDeletedServices = add(reposFromDeletedServices, srcid);
			return false;
		    }

		    return true;
		}
	    );
	}
    );
}

void SetReposStatusFromService(string service_alias, boolean enable)
{
    // delete the repositories belonging to the service
    list<map<string,any> > repos = ReposFromService(service_alias, sourceStatesOut);
    y2milestone("%1 repos from service alias=%2: %3", enable ? "Enabling" : "Disabling", service_alias, repos);

    foreach(map<string,any> repo, repos,
	{
	    integer srcid = repo["SrcId"]:-1;

	    sourceStatesOut = maplist (map<string,any> srcstate, sourceStatesOut,
		{
		    if (srcstate["SrcId"]:-1 == srcid)
		    {
			y2milestone("%1 repository %2", enable ? "Enabling" : "Disabling", srcstate);
			srcstate["enabled"] = enable;
		    }

		    return srcstate;
		}
	    );
	}
    );
}

any SummaryDialog () {
    y2milestone ("Running Summary dialog");

    // push button - change URL of the selected repository
    string replaceButtonLabel = _("&Replace...");
    // push button - refresh the selected repository now
    string refreshButtonLabel = _("Re&fresh Selected");
    // push button - disable/enable the selected repository
    string enableButtonLabel = _("Status &On or Off");
    // push button - disable/enable automatic refresh of the selected repository
    string refreshOnOffButtonLabel = _("Refre&sh On or Off");
    // push button - set name of the selected repository
    string setAliasButtonLabel = _("Set &Name...");

    term contents =
	`VBox(
	    `Right(`ReplacePoint(`id(`filter_rp), RepoFilterWidget())),
	    `VWeight(1, `ReplacePoint(`id(`tabrp), TableWidget(repository_view))),
	    repoInfoTerm(),

	    // label
	    `Left (`Label (_("Properties"))),

	    `HBox(
		`HSquash(
		    `VBox(
			 // check box
			 `Left (`CheckBox (`id (`enable), `opt(`notify), _("&Enabled"))),
			 // check box
			 `Left (`CheckBox (`id (`autorefresh), `opt(`notify), _("Automatically &Refresh")))
		    )
		),
		`HSpacing(1),
		`HSquash(
		    `Bottom(
			 // check box
			`ReplacePoint(`id(`keeppkg_rp), `CheckBox(`id(`keeppackages), `opt(`notify), keeppackages_label))
		    )
		),
		`HSpacing(1),
		`HSquash(`ReplacePoint(`id(`priorp), `IntField(`id(`priority), `opt(`notify), priority_label, 0, 200, default_priority))),
		`HStretch()
	    ),
	    `VSpacing (0.4),

	    `HBox(
		`PushButton (`id (`add), `opt(`key_F3),
		    Label::AddButton ()),
		`PushButton(`id(`replace), `opt(`key_F4),
		    Label::EditButton ()),
		`PushButton (`id(`delete), `opt(`key_F5),
		    Label::DeleteButton ()),
		`HStretch (),
		// push button label
		`PushButton (`id (`key_mgr), _("&GPG Keys...")),
		// menu button label
		`MenuButton (`id(`menu_button), `opt(`key_F6), _("Refresh"), [
		    `item(`id(`refresh), refreshButtonLabel ),
		    // menu button label
		    `item(`id(`autorefresh_all), _("Refresh All Autor&efreshed")),
		    // menu button label
		    `item(`id(`refresh_enabled), _("Refresh All &Enabled"))
		])
	    )
        );

    // dialog caption
    string title = _("Configured Software Repositories");

    // help
    string help_text = _("<p>
In this dialog, manage configured software repositories and services.</p>");

    help_text = help_text + _("<P>A <B>service</B> or <B>Repository Index Service (RIS) </B> is a protocol for package repository management. A service can offer one or more software repositories which can be dynamically changed by the service administrator.</P>");

    help_text = help_text + _("<p>
<b>Adding a New Repository or a Service</b><br>
To add a new repository, use <b>Add</b> and specify the software repository or service.
Yast will automatically detect whether a service or a repository is available at the entered location.
</p>");

    // help, continued
    help_text = help_text + _("<p>
To install packages from <b>CD</b>,
have the CD set or the DVD available.
</p>
");

    // help, continued
    help_text = help_text + _("<p>
The CDs can be copied to <b>hard disk</b>
and then used as a repository.
Insert the path name where the first
CD is located, for example, /data1/<b>CD1</b>.
Only the base path is required if all CDs are copied
into one directory.
</p>
");


    // help, continued
    help_text = help_text + _("<p>
<b>Modifying Status of a Repository or a Service</b><br>
To change a repository location, use <b>Edit</b>. To remove a repository, use
<b>Delete</b>. To enable or disable the repository or to change the refresh status at initialization time, select the repository in the table and use the check boxes below.
</p>
");

    // help text, continued
    help_text = help_text + _("<P><B>Priority of a Repository</B><BR>
Priority of a repository is an integer value between 0 (the highest priority) and 200 (the lowest priority). Default priority is 99. If a package is available in more repositories the repository with the highest priority is used.</P>");

    // help text, continued
    help_text = help_text + _("<P>Select the appropriate option on top of the window for navigation in repositories and services.</P>"); 
    // help text, continued
    help_text = help_text + _("<P><B>Keep Downloaded Packages</B><BR>Check this option to keep downloaded packages in a local cache so they can be reused later when the packages are reinstalled. If unchecked the downloaded packages are deleted after installation.</P>") + _("<P>The default local cache is located in directory <B>/var/cache/zypp/packages</B>, the location can be changed in <B>/etc/zypp/zypp.conf</B> file.</P>");

    Wizard::SetNextButton(`next, Label::OKButton() );
    Wizard::SetAbortButton(`abort, Label::CancelButton() );

    Wizard::SetContents(title, contents, help_text, false, true);
    Wizard::HideBackButton();

    fillTable(repository_view, displayed_service);
    fillCurrentRepoInfo();

    symbol input = nil;

    integer current = -1;

    string url = "";

    boolean exit = false;

    repeat {

	if ( current != nil && current >= 0 ) {
	    UI::ChangeWidget( `id( `table ), `CurrentItem, current );
	    fillCurrentRepoInfo ();
	}

	current = -1;

	map event = UI::WaitForEvent();
	input	= event["ID"]:`nothing;
	y2debug( "Input: %1", input );
	if (input == `table && event["EventReason"]:"" == "Activated")
	    input	= `enable;

	symbol createResult = `again;

	if (input == `add)
	{
	    return `add;
	}
	if ( input == `next )
        {
	  // store the new state
          boolean success = Write();
          if ( !success ) {
		// popup message part 1
                string _msg1 = _("Unable to save changes to the repository
configuration.");
                string details = Pkg::LastError();
		y2milestone("LastError: %1", details);
		// popup message part 2 followed by other info
                string _msg2 = details != "" ? (_("Details:") + "\n" + details)
		    : "";
		// popup message part 3
                _msg2 = _msg2 + "\n" + _("Try again?");

                boolean tryagain = Popup::YesNo( _msg1 + "\n" + _msg2 );
                if ( !tryagain ) exit = true;
          } else {
            exit = true;
          }
        }
	// Wizard::UserInput returns `back instead of `cancel when window is closed by WM
        else if (input == `abort || input == `cancel)
        {
	    // handle cancel as abort
	    input = `abort;

	    // no change, do not confirm exit
	    if (sourceStatesOut == sourceStatesIn)
	    {
		exit = true;
	    }
	    else
	    {
		// popup headline
		string headline = _("Abort Repository Configuration");
		// popup message
		string msg = _("Abort the repository configuration?
All changes will be lost.");
		if ( Popup::YesNoHeadline( headline, msg ) )
		{
		    exit = true;
		}
	    }
        }
	else if (input == `key_mgr)
	{
	    exit = true;
	    //return `key_mgr;
	    // start the GPG key manager
	    //RunGPGKeyMgmt();
	}
	else if (input == `service_filter)
	{
	    // handle the combobox events here...
	    any current_item = UI::QueryWidget(`id(`service_filter), `Value);

	    // rebuild the dialog if needed
	    y2milestone("Current combobox item: %1", current_item);
	    boolean update_table_widget = false;

	    if (current_item == `all_repositories)
	    {
		update_table_widget = !repository_view || displayed_service != "";
		y2milestone("Switching to repository view");
		repository_view = true;
		displayed_service = "";
	    }
	    else if (current_item == `all_services)
	    {
		update_table_widget = repository_view;
		y2milestone("Switching to service view");
		repository_view = false;
		// display all services
		displayed_service = "";
	    }
	    else if (is(current_item, string))
	    {
		// switch to the selected repository
		y2milestone("Switching to service %1", current_item);
		repository_view = true;
		// display the selected service
		displayed_service = (string)current_item;

		// FIXME: always update the table?
		update_table_widget = true;
	    }

	    // update table widget
	    if (update_table_widget)
	    {
		ReplaceWidgets(repository_view);
	    }

	    // update table content
	    fillTable(repository_view, displayed_service);
	    fillCurrentRepoInfo();

	    // update the current item
	    current = (integer) UI::QueryWidget( `id( `table ), `CurrentItem );
	}
        else
        {
            current = (integer) UI::QueryWidget( `id( `table ), `CurrentItem );

            y2debug( "Current item: %1", current );

            map<string, any> sourceState = $[];

	    // global_current - 'current' that points to global sourceStatesOut
	    integer global_current = -1;

	    if (repository_view)
	    {
		if (displayed_service == "")
		{
		    sourceState = sourceStatesOut[ current ]:$[];
		    global_current = current;
		}
		else
		{
		    if (current != nil)
		    {
			list<map<string,any> > sources_from_service = ReposFromService(displayed_service, sourceStatesOut);
			sourceState = sources_from_service[current]:$[];

			find(map<string,any> s, sourceStatesOut,
			    {
				global_current = global_current + 1;
				return s["SrcId"]:nil == sourceState["SrcId"]:-1;
			    }
			);

			y2milestone("global_current: %1", global_current);
		    }
		}
	    }

            integer id = sourceState[ "SrcId" ]:-1;

            if ( id < 0 && repository_view && displayed_service == "") {
              y2internal("Unable to determine repository id, broken repository?");
              continue;
            }

            if ( input == `replace )
            {
		if (repository_view)
		{
		    map generalData = Pkg::SourceGeneralData( id );
		    string url = generalData[ "url" ]:"";
		    string old_url = url;
		    boolean plaindir = generalData["type"]:"YaST" == plaindir_type;

		    SourceDialogs::SetRepoName (sourceState["name"]:"");

		    do {
			url = SourceDialogs::EditPopupType(url, plaindir);

			if ( size( url ) == 0 ) break;

			boolean same_url = (url == old_url);

			y2debug("same_url: %1 (old: %2, new: %3)", same_url, old_url, url);

			// special check for cd:// and dvd:// repositories
			if (!same_url)
			{
			    map new_url_parsed = URL::Parse(url);
			    map old_url_parsed = URL::Parse(old_url);

			    string new_url_scheme = tolower(new_url_parsed["scheme"]:"");
			    string old_url_scheme = tolower(old_url_parsed["scheme"]:"");

			    // ignore cd:// <-> dvd:// changes if the path is not changed
			    if ((new_url_scheme == "cd" || new_url_scheme == "dvd")
				&& (old_url_scheme == "cd" || old_url_scheme == "dvd"))
			    {
				// compare only directories, ignore e.g. ?device=/dev/sr0 options
				if (new_url_parsed["path"]:"" == old_url_parsed["path"]:"")
				{
				    Pkg::SourceChangeUrl(sourceState[ "SrcId" ]:-1, url);
				    same_url = true;
				}
			    }
			}

			if (!same_url || plaindir != SourceDialogs::IsPlainDir())
			{
			  y2milestone ("URL or plaindir flag changed, recreating the source");
			  // copy the refresh flag
			  createResult = createSource( url, SourceDialogs::IsPlainDir(), sourceState["do_refresh"]:false, SourceDialogs::GetRepoName ());
			  if ( createResult == `ok ) {
			    // restore the origonal properties (enabled, autorefresh, keeppackages)
			    // the added repository is at the end of the list
			    integer idx = size(sourceStatesOut) - 1;
			    map<string, any> addedSource = sourceStatesOut[idx]:$[];

			    y2milestone("Orig repo: %1", sourceState);
			    y2milestone("Added repo: %1", addedSource);

			    if (addedSource != $[])
			    {
				boolean auto_refresh = sourceState["autorefresh"]:true;
				boolean keeppackages = sourceState["keeppackages"]:false;
				boolean enabled = sourceState["enabled"]:true;
				integer priority = sourceState["priority"]:default_priority;
				y2milestone("Restoring the original properties: enabled: %1, autorefresh: %2, keeppackages: %3, priority: %4", enabled, auto_refresh, keeppackages, priority);

				// set the original properties
				addedSource["autorefresh"] = auto_refresh;
				addedSource["keeppackages"] = keeppackages;
				addedSource["enabled"] = enabled;
				addedSource["priority"] = priority;

				// get the ID of the old repo and mark it for removal
				integer srcid = sourceStatesOut[global_current, "SrcId"]:-1;
				if (srcid != -1)
				{
				    sourcesToDelete = add (sourcesToDelete, srcid);
				    SourceManager::just_removed_sources = add (SourceManager::just_removed_sources, srcid);
				}

				// replace the data
				sourceStatesOut[global_current] = addedSource;
				// remove the duplicate at the end
				sourceStatesOut = remove(sourceStatesOut, idx);

				// refresh only the name and URL in the table
				UI::ChangeWidget(`id(`table), `Cell( global_current, 3), addedSource["name"]:"");
				UI::ChangeWidget(`id(`table), `Cell( global_current, 5), url);

				fillCurrentRepoInfo();
			    }
			  }
			}
			else
			{
			    y2milestone ("URL is the same, not recreating the source");

			    string new_name = SourceDialogs::GetRepoName();
			    if (new_name != sourceState["name"]:"")
			    {
				sourceState["name"] = new_name;
				sourceStatesOut[ global_current ] = sourceState;

				// update only the name cell in the table
				UI::ChangeWidget(`id(`table), `Cell( global_current, 3), new_name);

				fillCurrentRepoInfo();
			    }
			    else
			    {
				y2milestone("The repository name has not been changed");
			    }

			    createResult = `ok;
			}

		    } while ( createResult == `again );
		}
		else // service view
		{
		    map <string, any> service_info = serviceStatesOut[current]:$[];
		    y2milestone("Editing service %1...", current);
		    string url = service_info["url"]:"";
		    string old_url = url;

		    SourceDialogs::SetRepoName(service_info["name"]:"");
		    do {
			url = SourceDialogs::EditPopupService(url);

			if ( size( url ) == 0 ) break;
			if (url != old_url)
			{
			    y2milestone ("URL of the service has been changed, recreating the service");
			    // createSource() can potentially create a repository instead of a service
			    // Probe for a service first must be done before creating a new service
			    string service_type = Pkg::ServiceProbe(url);
			    y2milestone("Probed service type: %1", service_type);

			    if (service_type != nil && service_type != "NONE")
			    {
				createResult = createSource(url, false /*plaindir*/, false /*do_refresh*/, SourceDialogs::GetRepoName());
				if ( createResult == `ok )
				{
				    deleteService( current );
				    fillTable(repository_view, displayed_service);
				    fillCurrentRepoInfo();

				    // refresh also the combobox widget
				    UpdateCombobox();
				}
			    }
			    else
			    {
				Report::Error(sformat(_("There is no service at URL:
%1"), url));
			    }
			}
			else
			{
			    y2milestone ("URL is the same, not recreating the service");
			    string entered_service_name = SourceDialogs::GetRepoName();
			    string old_service_name = service_info["name"]:"";

			    if (old_service_name != entered_service_name)
			    {
				y2milestone("Updating name of the service to '%1'", entered_service_name);
				service_info["name"] = entered_service_name;
				serviceStatesOut[ current ] = service_info;
				fillTable(repository_view, displayed_service);
				fillCurrentRepoInfo();
				createResult = `ok;

				// update the reference
				sourceStatesOut = maplist(map<string,any> src_state, sourceStatesOut,
				    {
					if (src_state["service"]:"" == old_service_name)
					{
					    src_state["service"] = entered_service_name;
					}

					return src_state;
				    }
				);

				// refresh also the combobox widget
				UpdateCombobox();
			    }
			}

		    } while ( createResult == `again );
		}
            }
	    else if ( input == `refresh )
            {
		if (repository_view)
		{
		    Pkg::SourceRefreshNow (id);

		    if (full_mode && sourceState["enabled"]:false)
		    {
			// force loading of the resolvables
			Pkg::SourceSetEnabled(id, false);
			Pkg::SourceSetEnabled(id, true);
		    }
		}
		else
		{
		    // refresh a service
		    string service_alias = (serviceStatesOut[current]:$[])["alias"]:"";

		    y2milestone("Refreshing service %1...", service_alias);
		    Pkg::ServiceRefresh(service_alias);
		}
            }
	    else if ( input == `autorefresh_all || input == `refresh_enabled)
            {
		y2milestone("Refreshing all %1 %2%3...", input == `refresh_enabled ? "enabled" : "autorefreshed",
		    repository_view ? "repositories" : "services",
		    repository_view && displayed_service != "" ? " from service " + displayed_service : "");

		boolean refresh_autorefresh_only = input == `autorefresh_all;
		integer to_refresh = 0;

		list<map<string,any> > data = (repository_view) ?
		    (displayed_service == "" ? sourceStatesOut : ReposFromService(displayed_service, sourceStatesOut))
		    : serviceStatesOut;

		y2internal("data: %1", data);

		foreach(map<string,any> src_state, data,
		    {
			if (src_state["enabled"]:false && (!refresh_autorefresh_only || src_state["autorefresh"]:false))
			{
			    string url = repository_view ? 
				(Pkg::SourceGeneralData(src_state["SrcId"]:-1)["url"]:"")
				: src_state["url"]:"";
			    string schema = tolower(substring(url, 0, 3));

			    if (schema != "cd:" && schema != "dvd")
			    {
				to_refresh = to_refresh + 1;
			    }
			}
		    }
		);

		y2milestone("%1 %2 will be refreshed", to_refresh, repository_view ? "repositories" : "services");

		if (to_refresh > 0)
		{
		    Wizard::CreateDialog ();
		    // TODO: add help text
		    Progress::New(repository_view ? _("Refreshing Repositories") : _("Refreshing Services"),
			"", to_refresh + 1, [ repository_view ? _("Refresh Repositories") : _("Refresh Services") ],
			[], "");

		    foreach(map<string,any> src_state, data,
			{
			    if (src_state["enabled"]:false && (!refresh_autorefresh_only || src_state["autorefresh"]:false))
			    {
				string name = src_state["name"]:"";
				if (repository_view)
				{
				    integer srcid = src_state["SrcId"]:-1;

				    string url = Pkg::SourceGeneralData(src_state["SrcId"]:-1)["url"]:"";
				    string schema = tolower(substring(url, 0, 3));

				    if (schema != "cd:" && schema != "dvd")
				    {
					y2milestone("Autorefreshing repository %1 (%2)", srcid, name);

					// progress bar label
					Progress::Title(sformat(_("Refreshing Repository %1..."), name));

					Pkg::SourceRefreshNow(srcid);

					if (full_mode && src_state["enabled"]:false)
					{
					    // force loading of the resolvables
					    Pkg::SourceSetEnabled(srcid, false);
					    Pkg::SourceSetEnabled(srcid, true);
					}

					Progress::NextStep();
				    }
				    else
				    {
					y2milestone("Skipping a CD/DVD repository %1 (%2)", srcid, name);
				    }
				}
				else
				{
				    string service_alias = src_state["alias"]:"";

				    // refreshing services
				    // progress bar label
				    Progress::Title(sformat(_("Refreshing Service %1..."), name));
				    y2milestone("Refreshing service %1 (alias: %2)...", name, service_alias);
				    Pkg::ServiceRefresh(service_alias);
				}
			    }
			}
		    );

		    Progress::Finish();
		    Wizard::CloseDialog();
		}
            }
            else if ( input == `delete )
            {
		if (repository_view)
		{
		    // yes-no popup
		    if ( Popup::YesNo( _("Delete the selected repository from the list?") ) )
		    {
			deleteSource(global_current);
			fillTable(repository_view, displayed_service);
			fillCurrentRepoInfo();
		    }
		}
		else
		{
		    string selected_service = (serviceStatesOut[current]:$[])["name"]:"";
		    // yes-no popup
		    if ( Popup::YesNo(sformat(_("Delete service %1\nand its repositories?"), selected_service)))
		    {
			string service_alias = (serviceStatesOut[current]:$[])["alias"]:"";
			RemoveReposFromService(service_alias);

			deleteService( current );
			fillTable(repository_view, displayed_service);
			fillCurrentRepoInfo();

			// refresh also the combobox widget
			UpdateCombobox();
		    }
		}
            }
            else if (input == `enable)
            {
		if (repository_view)
		{
		    boolean state = sourceState[ "enabled" ]:true;
		    state = !state;
		    // corresponds to the "Enable/Disable" button
		    string newstate = ( state ? UI::Glyph (`CheckMark) : "");
		    UI::ChangeWidget( `id( `table ), `Item( current, 1 ), newstate );
		    sourceState[ "enabled" ] = state;
		    sourceStatesOut[ global_current ] = sourceState;

		    if (full_mode)
		    {
			Pkg::SourceSetEnabled(sourceState["SrcId"]:-1, state);
		    }
		}
		else
		{
		    map<string,any> srv = serviceStatesOut[current]:$[];
		    y2milestone("Selected service: %1", srv);

		    boolean state = srv["enabled"]:false;
		    state = !state;

		    // disable/enable the repositories belonging to the service
		    string service_alias = (serviceStatesOut[current]:$[])["alias"]:"";
		    SetReposStatusFromService(service_alias, state);

		    // update the table
		    string newstate = ( state ? UI::Glyph (`CheckMark) : "");
		    UI::ChangeWidget( `id( `table ), `Item( current, 0 ), newstate );

		    // store the change
		    srv["enabled"] = state;
		    serviceStatesOut[current] = srv;
		}
            }
            else if ( input == `autorefresh)
            {
		if (repository_view)
		{
		    integer source_id = sourceState["SrcId"]:0;
		    map src_data = Pkg::SourceGeneralData (source_id);
		    string type = src_data["type"]:"";
		    boolean state = sourceState[ "autorefresh" ]:true;

		    if (type == "PlainDir" && ! state)
		    {
			// popup message
			Popup::Message (_("For the selected repository, refresh
cannot be set."));
		    }
		    else
		    {
			state = !state;

			string newstate = (state ? UI::Glyph(`CheckMark) : "");
			UI::ChangeWidget(`id(`table), `Item(current, 2), newstate);
		    }

		    sourceState["autorefresh"] = state;
		    sourceStatesOut[ global_current ] = sourceState;
		}
		else
		{
		    map<string,any> srv = serviceStatesOut[current]:$[];
		    y2milestone("Selected service: %1", srv);

		    boolean state = srv["autorefresh"]:false;
		    state = !state;

		    // update the table
		    string newstate = ( state ? UI::Glyph (`CheckMark) : "");
		    UI::ChangeWidget( `id( `table ), `Item( current, 1 ), newstate );

		    // store the change
		    srv["autorefresh"] = state;
		    serviceStatesOut[current] = srv;
		}

		// do not refresh the item in the table
		current = -1;
            }
	    else if (input == `priority)
	    {
		if (repository_view)
		{
		    // refresh the value in the table
		    integer new_priority = (integer)UI::QueryWidget(`id(`priority), `Value);
		    y2debug("New priority: %1", new_priority);

		    UI::ChangeWidget( `id( `table ), `Item( current, 0 ), PriorityToString(new_priority));
		    sourceState[ "priority" ] = new_priority;
		    sourceStatesOut[ global_current ] = sourceState;

		    // do not refresh the item in the table
		    current = -1;
		}
		else
		{
		    y2error("Ignoring event `priority: the widget should NOT be displayed in service mode!");
		}
	    }
	    else if (input == `keeppackages)
	    {
		if (repository_view)
		{
		    // refresh the value in the table
		    boolean new_keep = (boolean)UI::QueryWidget(`id(`keeppackages), `Value);
		    y2internal("New keep packages option: %1", new_keep);

		    sourceState[ "keeppackages" ] = new_keep;
		    sourceStatesOut[ global_current ] = sourceState;

		    // do not refresh the item in the table
		    current = -1;
		}
		else
		{
		    y2error("Ignoring event `keeppackages: the widget should NOT be displayed in service mode!");
		}
	    }
	    else if (input != `table)
	    {
		y2warning("Unknown user input: %1", input);
	    }
        }

    } until ( exit );

    y2debug( "Return: %1", input );

    return input;
}

list<map<string,any> > SortReposByPriority(list<map<string,any> > repos)
{
    // check the input
    if (repos == nil)
    {
	return repos;
    }

    // sort the maps by "repos" key (in ascending order)
    list<map<string,any> > ret = sort(map<string,any> repo1, map<string,any> repo2, repos, {return repo1["priority"]:default_priority < repo2["priority"]:default_priority;});

    y2milestone("SortReposByPriority: %1 -> %2", repos, ret);

    return ret;
}

// remember the original selected URL scheme
string selected_url_scheme = "";

symbol StartTypeDialog()
{
    string seturl = selected_url_scheme;

    if (seturl != nil && seturl != "")
    {
	seturl = selected_url_scheme + "://";
    }

    symbol ret = TypeDialogOpts(true, seturl);

    if (ret == `back)
    {
	selected_url_scheme = "";
    }
    else
    {
	selected_url_scheme = URL::Parse(SourceDialogs::GetRawURL())["scheme"]:"";
	y2milestone("Selected URL scheme: %1", selected_url_scheme);

	if (selected_url_scheme == nil || selected_url_scheme == "")
	{
	    selected_url_scheme = "url";
	}
    }

    return ret;
}

boolean KnownURL(string url)
{
    string scheme = tolower(URL::Parse(url)["scheme"]:"");

    // alway create CD/DVD repository
    if (scheme == "cd" || scheme == "dvd")
    {
	return false;
    }

    boolean ret = false;

    foreach (map<string,any> src, sourceStatesOut,
	{
	    integer src_id = tointeger(src["SrcId"]:nil);
	    map generalData = Pkg::SourceGeneralData(src_id);
	    string src_url = generalData["url"]:"";

	    if (src_url == url)
	    {
		ret = true;
	    }
	}
    );

    y2milestone("URL exists: %1", ret);

    return ret;
}

symbol StartEditDialog()
{
    y2milestone("Edit URL with protocol %1", selected_url_scheme);
    symbol ret = nil;

    do
    {
	ret = SourceDialogs::EditDialogProtocol(selected_url_scheme);

	if (ret == `next)
	{
	    string url = SourceDialogs::GetURL();
	    boolean known_url = KnownURL(url);

	    if (known_url)
	    {
		// popup question, %1 is repository URL
		if (!Popup::AnyQuestion("",
		    sformat(_("Repository %1
has been already added. Each repository should be added only once.

Really add the repository again?"), URL::HidePassword(url)),
		    Label::YesButton(),
		    Label::NoButton(),
		    `focus_no
		    )
		)
		{
		    // ask again
		    ret = nil;
		}
	    }
	}
    }
    while (ret == nil);

    y2milestone("Result: %1", ret);

    return ret;
}

symbol StartStoreSource()
{
    symbol ret = StoreSource();

    if (ret == `next || ret == `abort || ret == `close)
    {
	y2milestone("Resetting selected URL scheme");
	selected_url_scheme = "";
    }

    return ret;
}

// main function - start the workflow
symbol StartInstSource()
{
    Wizard::CreateDialog();
    Wizard::SetDesktopIcon("sw_source");

    if (!full_mode)
    {
	// dialog caption
	Wizard::SetContents(_("Initializing..."), `Empty (), "", false, true);
	Pkg::TargetInit("/", true);
    }

   // check whether running as root
   if (! Confirm::MustBeRoot () || !PackageLock::Connect(false)["connected"]:false)
   {
	UI::CloseDialog ();
	return `abort;
   }

    if (!full_mode)
    {
	PackageCallbacks::InitPackageCallbacks ();
    }

    // read repositories & services
    boolean restore = (!full_mode) ? Pkg::SourceRestore() : true;

    y2milestone("Known services: %1", Pkg::ServiceAliases());

    if( ! restore )
    {
	boolean cont = Popup::AnyQuestionRichText(
	    Label::ErrorMsg(),
	    // Error popup
	    _("<p>There were errors while restoring the repository configuration.</p>\n") + "<p>" + Pkg::LastError() + "</p>",
	    50, 15,
	    Label::ContinueButton(), Label::CancelButton(), `focus_no
	);

	// really continue?
	if (!cont) {
	    return `abort;
	}
    }

    // read known GPG keys
    KeyManager::Read();

    sourceStatesIn = SortReposByPriority(Pkg::SourceEditGet());
    y2milestone( "Found repositories: %1", sourceStatesIn);
    sourceStatesOut = sourceStatesIn;

    list<string> srv_aliases = Pkg::ServiceAliases();
    // get the current services
    foreach(string srv_alias, srv_aliases,
	{
	    serviceStatesIn = add(serviceStatesIn, Pkg::ServiceGet(srv_alias));
	}
    );

    y2milestone("Loaded services: %1", serviceStatesIn);

    serviceStatesOut = serviceStatesIn;

    map<string,any> aliases = $[
	"summary" : ``(SummaryDialog ()),
	"type" : ``(StartTypeDialog()),
	"edit" : ``(StartEditDialog ()),
	"store" : ``(StartStoreSource ()),
	"keymgr" : [``(RunGPGKeyMgmt(false)), true]
    ];

    map sequence = $[
	"ws_start" : "summary",
	"summary" : $[
	    `add : "type",
	    `edit : "edit",
	    `key_mgr : "keymgr",
	    `abort : `abort,
	    `next : `next,
	],
	"keymgr" : $[
	    `next : "summary",
	    `abort : "summary"
	],
	"type" : $[
	    `next : "edit",
	    `finish : "store",
	    `abort : `abort,
	],
	"edit" : $[
	    `next : "store",
	    `abort : `abort,
	],
	"store" : $[
	    `next : "summary",
	    `abort : `abort,
	],
    ];

    y2milestone ("Starting repository sequence");
    symbol ret = Sequencer::Run (aliases, sequence);

    UI::CloseDialog ();
    return ret;
}

map cmdline_description = $[
    "id"	: "inst_source",
    /* Command line help text for the repository module, %1 is "zypper" */
    "help"	: sformat(_("Installation Repositories - this module doesn't support the command line interface, use '%1' instead."), "zypper"),
    "guihandler"        : StartInstSource,
];

if (WFM::Args() == [ `sw_single_mode ])
{
    y2milestone("Started from sw_single, switching the mode");

    full_mode = true;
    any ret = StartInstSource();

    // load objects from the new repositories
    if (ret != `abort)
    {
        Pkg::SourceLoad();
    }

    return ret;
}

if (WFM::Args() == [ "refresh-enabled" ])
{
    y2milestone("Refresh enabled option set");
    return StartInstSource();
}

return CommandLine::Run(cmdline_description);

} // EOF

ACC SHELL 2018