YaST/Development/Pattern Selector Proposal

From openSUSE

About

This tiny article shows a Pattern Selector / Software Selector proposal in Graphical UI.

Screen-shots First

Wow, that sounds like a black magic has been used, which is (as far as I know) forbidden to be used in Novell, isn't it?

No, actually, a standard RichText widget has been used, some icons, and ... a HTML table :)

Source Code

Do you want to try that on your own?

First, copy these two images Image:CheckBox.png Image:CheckBox-Selected.png to /usr/share/YaST2 directory.

Then save this to a pattern_proposal.ycp file (run it with yast2 ./pattern_proposal.ycp).

 {
     import "Wizard";
     import "Stage";
     import "Installation";
     import "Icon";
 
     textdomain "installation";
 
     if (! Stage::initial()) {
       Wizard::OpenNextBackDialog();
 
         // Pkg::TargetInitialize (Installation::destdir);
         // not necessary  
         // Pkg::TargetLoad();
     }
     
     Pkg::SourceStartManager (true);
 
 
     // small bug in Icon module (lazy loading)
     Icon::Info();
 
   string SoftwareSelectionRichText () {
     list <map <string,any> > patterns = Pkg::ResolvableProperties ("", `pattern, "");
 
     map <string, list <map <string,any> > > groupped_patterns = $[];
 
     foreach (map <string,any> one_pattern, patterns, {
       if (one_pattern["user_visible"]:false == false) return;
 
       string groupname = one_pattern["category"]:_("Unsorted");
 
       if (! haskey (groupped_patterns, groupname)) groupped_patterns[groupname] = [];
       
       groupped_patterns[groupname] = add (groupped_patterns[groupname]:[], one_pattern);
     });
 
     string software_selection = "";
 
     foreach (string one_group_name, list <map <string,any> > patterns_in_group, groupped_patterns, {
       software_selection = software_selection + "<table border=\"0\">";
 
       software_selection = software_selection +
           "<tr>" +
           "<td valign=\"middle\" width=\"1%\"><img src=\"" + Icon::IconPath ("yast-software") + "\"></td>" +
           "<td valign=\"middle\" colspan=\"3\"><font size=\"+2\"><b>" + one_group_name + "</b></font></td>" +
           "</tr>\n";
 
       foreach (map <string,any> one_pattern, patterns_in_group, {
           string icon = one_pattern["icon"]:"yast-software";
 
           string check_box = "/usr/share/YaST2/CheckBox.png";
           string checkbox_alt = "[ ]";
           string checkbox_href = sformat ("PatternChanged_%1_%2", "select", one_pattern["name"]:"!?!");
 
           if (one_pattern["status"]:`nil == `selected || one_pattern["status"]:`nil == `installed) {
               check_box = "/usr/share/YaST2/CheckBox-Selected.png";
               checkbox_alt = "[x]";
               checkbox_href = sformat ("PatternChanged_%1_%2", "unselect", one_pattern["name"]:"!?!");
           }
 
           software_selection = software_selection +
               "<tr>" +
               "<td> </td>" +
               "<td valign=\"middle\" width=\"1%\"><a href=\"" + checkbox_href + "\"><img src=\"" + check_box + "\" alt=\"" + checkbox_alt + "\"></a></td>" +
               "<td valign=\"middle\" colspan=\"2\"><font size=\"+1\">" + one_pattern["summary"]:one_pattern["name"]:"?" + "</font></td>" +
               "</tr>\n";
 
           software_selection = software_selection +
               "<tr>" +
               "<td colspan=\"2\"> </td>" +
               "<td valign=\"middle\" width=\"1%\"><img src=\"" + Icon::IconPath (icon) + "\"></td>" +
               "<td><i>" + one_pattern["description"]:"" + "</i></td>" +
               "</tr>\n";
 
           // y2milestone ("%1", one_pattern);
       });
 
       software_selection = software_selection + "<tr><td colspan=\"4\"></td></tr>\n";
       software_selection = software_selection + "</table>\n";
     });
 
     return software_selection;
   }
 
     Wizard::SetContents (
       _("Software Selection"),
       `RichText (
           `id ("soft_sel"),
           SoftwareSelectionRichText()
       ),
       _("<p>Some help...</p>"),
       true,
       true
     );
 
     Wizard::SetTitleIcon ("yast-sw_single");
 
     symbol dialog_ret = `next;
     any ret = nil;
 
     while (true) {
       ret = UI::UserInput();
 
       // hack for buggy UI
       if (is (ret, symbol)) {
           string ret_test = tostring (ret);
           if (regexpmatch (ret_test, "^`PatternChanged_")) {
               ret = regexpsub (ret_test, "^`(.*)", "\\1");
           }
       }
 
       if (ret == `next) {
           dialog_ret = `next;
           break;
       } else if (ret == `back) {
           dialog_ret = `back;
           break;
       } else if (is (ret, string) && regexpmatch ((string) ret, "^PatternChanged_")) {
           y2milestone ("%1", ret);
           string pattern_change = regexpsub ((string) ret, "PatternChanged_(select|unselect)_(.*)", "\\1");
           string pattern_name   = regexpsub ((string) ret, "PatternChanged_(select|unselect)_(.*)", "\\2");
 
           y2milestone ("Pattern: %1 -> %2", pattern_name, pattern_change);
           if (pattern_change == "select") {
               y2milestone ("%1", Pkg::ResolvableProperties (pattern_name, `pattern, ""));
               y2milestone ("-> %1", Pkg::ResolvableInstall (pattern_name, `pattern));
               y2milestone ("%1", Pkg::ResolvableProperties (pattern_name, `pattern, ""));
           } else {
               y2milestone ("%1", Pkg::ResolvableProperties (pattern_name, `pattern, ""));
               y2milestone ("-> %1", Pkg::ResolvableNeutral (pattern_name, `pattern, false));
               y2milestone ("%1", Pkg::ResolvableProperties (pattern_name, `pattern, ""));
           }
       } else {
           y2warning ("Ret: '%1' not handled", ret);
       }
 
       Wizard::SetContents (
           _("Software Selection"),
           `RichText (
               `id ("soft_sel"),
               SoftwareSelectionRichText()
           ),
           _("<p>Some help...</p>"),
           true,
           true
       );
     }
 
     if (! Stage::initial()) {
       Wizard::CloseDialog();
     }
 
     return dialog_ret;
 }

And what can it really do?

Well, it currently only displays available/installed/... patterns and allows you to change their status. Their status is not written after the dialog is exited, don't worry.