Hello community,

here is the log from the commit of package yast2-ycp-ui-bindings for 
openSUSE:Factory checked in at 2019-11-20 10:26:02
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/yast2-ycp-ui-bindings (Old)
 and      /work/SRC/openSUSE:Factory/.yast2-ycp-ui-bindings.new.26869 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "yast2-ycp-ui-bindings"

Wed Nov 20 10:26:02 2019 rev:75 rq:747538 version:4.2.4

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/yast2-ycp-ui-bindings/yast2-ycp-ui-bindings.changes  
    2019-09-30 15:52:09.794371999 +0200
+++ 
/work/SRC/openSUSE:Factory/.yast2-ycp-ui-bindings.new.26869/yast2-ycp-ui-bindings.changes
   2019-11-20 10:26:04.262548339 +0100
@@ -1,0 +2,12 @@
+Tue Nov 12 09:27:46 UTC 2019 - Steffen Winterfeldt <[email protected]>
+
+- require correct libyui version (bsc#1153103)
+- 4.2.5
+
+-------------------------------------------------------------------
+Thu Nov  7 13:26:47 UTC 2019 - Stefan Hundhammer <[email protected]>
+
+- Support for CustomStatusItemSelector (bsc#1084674)
+- 4.2.4
+
+-------------------------------------------------------------------

Old:
----
  yast2-ycp-ui-bindings-4.2.3.tar.bz2

New:
----
  yast2-ycp-ui-bindings-4.2.4.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ yast2-ycp-ui-bindings.spec ++++++
--- /var/tmp/diff_new_pack.E3KUDs/_old  2019-11-20 10:26:04.822548450 +0100
+++ /var/tmp/diff_new_pack.E3KUDs/_new  2019-11-20 10:26:04.822548450 +0100
@@ -16,8 +16,12 @@
 #
 
 
+# YUIWidget_CustomStatusItemSelector
+%define min_yui_version        3.8.4
+%define yui_so         10
+
 Name:           yast2-ycp-ui-bindings
-Version:        4.2.3
+Version:        4.2.4
 Release:        0
 
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
@@ -36,8 +40,8 @@
 Requires:       yast2-core
 BuildRequires:  yast2-core-devel
 
-# YWidgetFactory::createSingleItemSelector()
-BuildRequires:  libyui-devel >= 3.8.0
+BuildRequires:  libyui-devel >= %min_yui_version
+Requires:       libyui%yui_so >= %min_yui_version
 
 # libyui ImplPtr
 BuildRequires:  boost-devel
@@ -60,7 +64,7 @@
 Requires:       boost-devel
 Requires:       glibc-devel
 Requires:       libstdc++-devel
-Requires:       libyui-devel
+Requires:       libyui-devel >= %min_yui_version
 Requires:       yast2-core-devel
 Requires:       yast2-devtools
 

++++++ yast2-ycp-ui-bindings-4.2.3.tar.bz2 -> 
yast2-ycp-ui-bindings-4.2.4.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-ycp-ui-bindings-4.2.3/examples/CustomStatusItemSelector1.rb 
new/yast2-ycp-ui-bindings-4.2.4/examples/CustomStatusItemSelector1.rb
--- old/yast2-ycp-ui-bindings-4.2.3/examples/CustomStatusItemSelector1.rb       
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-ycp-ui-bindings-4.2.4/examples/CustomStatusItemSelector1.rb       
2019-11-12 11:18:46.000000000 +0100
@@ -0,0 +1,156 @@
+# encoding: utf-8
+
+module Yast
+  class ExampleClient < Client
+    Yast.import "UI"
+    include Yast::Logger
+
+    def main
+      UI.OpenDialog(main_dialog)
+      set_visible_items
+      handle_events
+      UI.CloseDialog
+    end
+
+    protected
+
+    VISIBLE_ITEMS    = 6
+
+    # Some constants to make handling the numeric status values better 
readable.
+    # Those constants correspond to the index of the status in the status
+    # definition (see custom_states).
+
+    MOD_DONT_INSTALL = 0
+    MOD_INSTALL      = 1
+    MOD_AUTOINSTALL  = 2
+
+    # The custom status values. Each one has an icon name, a text equivalent to
+    # indicate that status in the NCurses UI, and an optional next status.
+    #
+    # If a next status is specified, a click on that item will automatically
+    # cycle to that next status. If not specified (or -1), the application
+    # needs to handle status transitions from that status to another one.
+    def custom_states
+      [
+        # icon,          NCurses indicator, next status (optional)
+        ["checkbox-off",            "[  ]", MOD_INSTALL     ],
+        ["checkbox-on",             "[ +]", MOD_DONT_INSTALL],
+        ["checkbox-auto-selected",  "[a+]", MOD_DONT_INSTALL]
+      ]
+    end
+
+    def items
+      [
+        #       item ID,      heading label ,     description text (optional)
+        Item(Id(:mod_kde   ), "KDE Plasma",      "Full-fledged desktop"        
     ),
+        Item(Id(:mod_xfce  ), "Xfce",            "Lightweight desktop"         
     ),
+        Item(Id(:mod_x11   ), "X Window System", "X11, simple window manager, 
xterm"),
+        Item(Id(:mod_office), "LibreOffice",     "Office suite"                
     ),
+        Item(Id(:mod_server), "Server Tools",    "Web server, database, file 
server"),
+        Item(Id(:mod_sdk   ), "SDK",             "Development tools"           
     )
+      ]
+    end
+
+    def main_dialog
+      MarginBox(2, 0.4,
+        VBox(
+          Heading("Add-on Software"),
+          VSpacing(0.2),
+          CustomStatusItemSelector(Id(:modules), Opt(:notify), custom_states, 
items),
+          VSpacing(0.4),
+          Label(Id(:result_field), Opt(:outputField, :hstretch), "\n\n\n\n\n"),
+          VSpacing(0.3),
+          Right(
+            PushButton(Id(:close), "&Close")
+          )
+        )
+      )
+    end
+
+    def set_visible_items
+      UI.ChangeWidget(:modules, :VisibleItems, VISIBLE_ITEMS)
+      UI.RecalcLayout # needed for the change to have an effect
+    end
+
+    def handle_events
+      while true
+        event = UI.WaitForEvent
+        log.info("Event: #{event}")
+
+        break if event["WidgetID"] == :close
+        break if event["EventType"] == "CancelEvent"  # WM_CLOSE (Alt-F4)
+
+        # If Opt(:notify) is set, the CustomStatusItemSelector sends MenuEvents
+        # with the ID of the item the user clicked or activated via keyboard.
+        handle_item_click(event["ID"]) if event["EventType"] == "MenuEvent"
+      end
+      nil
+    end
+
+    # Handle an item click (or a keyboard action on an item).
+    def handle_item_click(item_id)
+      return if item_id.nil?
+      log.info("Item #{item_id} clicked")
+
+      # The ItemSelector already handled the common status transitions that we
+      # defined in the status definition: 0 -> 1, 1 -> 0, 2 -> 0.
+      #
+      # Now check if we need to change the status of other items because of
+      # dependencies to demonstrate sample business logic.
+      handle_dependencies
+      update_result
+    end
+
+    # Example business logic: Change the status of some of the example software
+    # modules based on dependencies of other modules.
+    def handle_dependencies
+      # ItemStatus return a hash ov IDs (in our case symbols) to integers (the 
status):
+      # { :mod_kde => 1, :mod_xfce => 0, :mod_x11 = 2, ... }
+
+      status = UI.QueryWidget(:modules, :ItemStatus) # Fetch current status of 
all items
+      log.info("Old status values: #{status}")
+
+      need_office = true if status[:mod_kde]     == MOD_INSTALL
+      need_x11    = true if status[:mod_kde]     == MOD_INSTALL
+      need_x11    = true if status[:mod_xfce]    == MOD_INSTALL
+      need_x11    = true if status[:mod_office]  == MOD_INSTALL
+
+      need_x11    = false if status[:mod_x11]    == MOD_INSTALL # manually 
selected
+      need_office = false if status[:mod_office] == MOD_INSTALL # manually 
selected
+
+      old_status = status.select { |k, v| [:mod_x11, :mod_office].include?(k) }
+      new_status = old_status.dup
+      new_status[:mod_x11]    = auto_select_status(new_status, :mod_x11,    
need_x11)
+      new_status[:mod_office] = auto_select_status(new_status, :mod_office, 
need_office)
+
+      log.info("Auto-modules old status: #{old_status}")
+      log.info("Auto-modules new status: #{new_status}")
+
+      UI.ChangeWidget(:modules, :ItemStatus, new_status) unless new_status == 
old_status
+    end
+
+    # Example business logic: Return a module's effective status based on its
+    # old status and a flag indicating if it is needed because of dependencies
+    def auto_select_status(status_map, mod, needed)
+      old_status = status_map[mod]
+      return MOD_AUTOINSTALL  if needed  && old_status == MOD_DONT_INSTALL
+      return MOD_DONT_INSTALL if !needed && old_status == MOD_AUTOINSTALL
+      old_status
+    end
+
+    # Update the "Result" field
+    def update_result
+      status = UI.QueryWidget(:modules, :ItemStatus)
+
+      status.reject! { |k, v| v == MOD_DONT_INSTALL }
+      actions = [ "", "Install", "Auto-install"]
+      result = status.collect{ |mod, stat| actions[stat] + " " + mod.to_s }
+      log.info("Result: #{result}")
+
+      UI.ChangeWidget(:result_field, :Value, result.join("\n"))
+    end
+
+  end
+end
+
+Yast::ExampleClient.new.main
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-ycp-ui-bindings-4.2.3/examples/CustomStatusItemSelector2-minimalistic.rb
 
new/yast2-ycp-ui-bindings-4.2.4/examples/CustomStatusItemSelector2-minimalistic.rb
--- 
old/yast2-ycp-ui-bindings-4.2.3/examples/CustomStatusItemSelector2-minimalistic.rb
  1970-01-01 01:00:00.000000000 +0100
+++ 
new/yast2-ycp-ui-bindings-4.2.4/examples/CustomStatusItemSelector2-minimalistic.rb
  2019-11-12 11:18:46.000000000 +0100
@@ -0,0 +1,60 @@
+# encoding: utf-8
+
+module Yast
+  class ExampleClient < Client
+    def main
+      Yast.import "UI"
+
+      UI.OpenDialog(
+       VBox(
+         CustomStatusItemSelector(
+           Id(:pizza),
+           [
+             # Icon, NCursesIndicator, NextStatus
+             ["checkbox-off", "[ ]", 1],
+             ["checkbox-on",  "[x]", 0]
+           ],
+           [
+             # Notice no item IDs, so we'll get the item label as the result.
+             # Even the descriptions are optional.
+             Item("Pizza Margherita",       "Very basic with just tomatoes and 
cheese"),
+             Item("Pizza Capricciosa",      "Ham and vegetables"               
       ),
+             Item("Pizza Funghi",           "Mushrooms"                        
       ),
+             Item("Pizza Prosciutto",       "Ham"                              
       ),
+             Item("Pizza Quattro Stagioni", "Different toppings in each 
quarter"      ),
+             Item("Calzone",                "Folded over"                      
       )
+           ]
+          ),
+         PushButton("&OK")
+       )
+      )
+
+      widget = UI.UserInput
+
+      if widget == :cancel      # WM_CLOSE
+        UI.CloseDialog
+        return
+      end
+
+      # Fetch the result as long as the widget still exists, i.e. BEFORE 
UI.CloseDialog
+
+      result = UI.QueryWidget(:pizza, :SelectedItems).join(", ")
+      result = "(nothing)" if result.empty?
+      UI.CloseDialog
+
+      # Show the result in a pop-up dialog
+      UI.OpenDialog(
+       VBox(
+         Label("\n  Selected:\n\n  #{result}  \n"),
+         PushButton("&OK")
+       )
+      )
+      UI.UserInput
+      UI.CloseDialog
+
+      nil
+    end
+  end
+end
+
+Yast::ExampleClient.new.main
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-ycp-ui-bindings-4.2.3/examples/CustomStatusItemSelector3-modular.rb 
new/yast2-ycp-ui-bindings-4.2.4/examples/CustomStatusItemSelector3-modular.rb
--- 
old/yast2-ycp-ui-bindings-4.2.3/examples/CustomStatusItemSelector3-modular.rb   
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/yast2-ycp-ui-bindings-4.2.4/examples/CustomStatusItemSelector3-modular.rb   
    2019-11-12 11:18:46.000000000 +0100
@@ -0,0 +1,76 @@
+# encoding: utf-8
+
+module Yast
+  class ExampleClient < Client
+    def main
+      Yast.import "UI"
+
+      create_widgets
+      widget = UI.UserInput
+
+      if widget == :cancel # WM_CLOSE (Alt-F4)
+        UI.CloseDialog
+        return
+      end
+
+      result = fetch_result # As long as the widget still exists!
+      UI.CloseDialog
+      show_result(result)
+    end
+
+    protected
+
+    def custom_states
+      [
+        # Icon, NCursesIndicator, NextStatus
+        ["checkbox-off", "[ ]", 1],
+        ["checkbox-on",  "[x]", 0]
+      ]
+    end
+
+    def items
+      [
+        # Notice no item IDs, so we'll get the item label as the result.
+        # Even the descriptions are optional.
+        Item("Pizza Margherita",       "Very basic with just tomatoes and 
cheese"),
+        Item("Pizza Capricciosa",      "Ham and vegetables"                    
  ),
+        Item("Pizza Funghi",           "Mushrooms"                             
  ),
+        Item("Pizza Prosciutto",       "Ham"                                   
  ),
+        Item("Pizza Quattro Stagioni", "Different toppings in each quarter"    
  ),
+        Item("Calzone",                "Folded over"                           
  )
+      ]
+    end
+
+    def create_widgets
+      UI.OpenDialog(
+        VBox(
+          CustomStatusItemSelector(Id(:pizza), custom_states, items),
+          PushButton("&OK")
+        )
+      )
+    end
+
+    def fetch_result
+      UI.QueryWidget(:pizza, :SelectedItems)
+    end
+
+    def show_result(result)
+      result = result.join(", ")
+      result = "(nothing)" if result.empty?
+
+      # Show the result in a pop-up dialog
+      UI.OpenDialog(
+        VBox(
+          Label("\n  Selected:\n\n  #{result}  \n"),
+          PushButton("&OK")
+        )
+      )
+      UI.UserInput
+      UI.CloseDialog
+
+      nil
+    end
+  end
+end
+
+Yast::ExampleClient.new.main
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-ycp-ui-bindings-4.2.3/examples/CustomStatusItemSelector4-no-desc.rb 
new/yast2-ycp-ui-bindings-4.2.4/examples/CustomStatusItemSelector4-no-desc.rb
--- 
old/yast2-ycp-ui-bindings-4.2.3/examples/CustomStatusItemSelector4-no-desc.rb   
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/yast2-ycp-ui-bindings-4.2.4/examples/CustomStatusItemSelector4-no-desc.rb   
    2019-11-12 11:18:46.000000000 +0100
@@ -0,0 +1,76 @@
+# encoding: utf-8
+
+module Yast
+  class ExampleClient < Client
+    def main
+      Yast.import "UI"
+
+      create_widgets
+      widget = UI.UserInput
+
+      if widget == :cancel # WM_CLOSE (Alt-F4)
+        UI.CloseDialog
+        return
+      end
+
+      result = fetch_result # As long as the widget still exists!
+      UI.CloseDialog
+      show_result(result)
+    end
+
+    protected
+
+    def custom_states
+      [
+        # Icon, NCursesIndicator, NextStatus
+        ["checkbox-off", "[ ]", 1],
+        ["checkbox-on",  "[x]", 0]
+      ]
+    end
+
+    def items
+      [
+        # Notice no item IDs, so we'll get the item label as the result.
+        # Also no descriptions.
+        Item("Pizza Margherita"      ),
+        Item("Pizza Capricciosa"     ),
+        Item("Pizza Funghi"          ),
+        Item("Pizza Prosciutto"      ),
+        Item("Pizza Quattro Stagioni"),
+        Item("Calzone"               )
+      ]
+    end
+
+    def create_widgets
+      UI.OpenDialog(
+        VBox(
+          CustomStatusItemSelector(Id(:pizza), custom_states, items),
+          PushButton("&OK")
+        )
+      )
+    end
+
+    def fetch_result
+      UI.QueryWidget(:pizza, :SelectedItems)
+    end
+
+    def show_result(result)
+      result = result.join(", ")
+      result = "(nothing)" if result.empty?
+
+      # Show the result in a pop-up dialog
+      UI.OpenDialog(
+        VBox(
+          Label("\n  Selected:\n\n  #{result}  \n"),
+          PushButton("&OK")
+        )
+      )
+      UI.UserInput
+      UI.CloseDialog
+
+      nil
+    end
+  end
+end
+
+Yast::ExampleClient.new.main
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-ycp-ui-bindings-4.2.3/examples/ItemSelector2-minimalistic.rb 
new/yast2-ycp-ui-bindings-4.2.4/examples/ItemSelector2-minimalistic.rb
--- old/yast2-ycp-ui-bindings-4.2.3/examples/ItemSelector2-minimalistic.rb      
2019-09-24 15:44:02.000000000 +0200
+++ new/yast2-ycp-ui-bindings-4.2.4/examples/ItemSelector2-minimalistic.rb      
2019-11-12 11:18:46.000000000 +0100
@@ -6,22 +6,22 @@
       Yast.import "UI"
 
       UI.OpenDialog(
-        VBox(
-          SingleItemSelector(
-           Id(:pizza),
-           [
-             # Notice no item IDs, so we'll get the item label as the result.
-             # Even the descriptions are optional.
-             Item("Pizza Margherita",       "Very basic with just tomatoes and 
cheese"),
-             Item("Pizza Capricciosa",      "Ham and vegetables"               
       ),
-             Item("Pizza Funghi",           "Mushrooms"                        
       ),
-             Item("Pizza Prosciutto",       "Ham"                              
       ),
-             Item("Pizza Quattro Stagioni", "Different toppings in each 
quarter"      ),
-             Item("Calzone",                "Folded over"                      
       )
-           ]
-          ),
-          PushButton("&OK")
-        )
+       VBox(
+         SingleItemSelector(
+           Id(:pizza),
+           [
+             # Notice no item IDs, so we'll get the item label as the result.
+             # Even the descriptions are optional.
+             Item("Pizza Margherita",       "Very basic with just tomatoes and 
cheese"),
+             Item("Pizza Capricciosa",      "Ham and vegetables"               
       ),
+             Item("Pizza Funghi",           "Mushrooms"                        
       ),
+             Item("Pizza Prosciutto",       "Ham"                              
       ),
+             Item("Pizza Quattro Stagioni", "Different toppings in each 
quarter"      ),
+              Item("Calzone",               "Folded over"                      
       )
+           ]
+         ),
+         PushButton("&OK")
+       )
       )
       UI.UserInput
 
@@ -37,10 +37,10 @@
 
       # Show the result in a pop-up dialog
       UI.OpenDialog(
-        VBox(
-          Label("Selected:\n#{result}"),
-          PushButton("&OK")
-        )
+       VBox(
+         Label("Selected:\n#{result}"),
+         PushButton("&OK")
+       )
       )
       UI.UserInput
       UI.CloseDialog
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-ycp-ui-bindings-4.2.3/examples/ItemSelector3-no-desc.rb 
new/yast2-ycp-ui-bindings-4.2.4/examples/ItemSelector3-no-desc.rb
--- old/yast2-ycp-ui-bindings-4.2.3/examples/ItemSelector3-no-desc.rb   
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-ycp-ui-bindings-4.2.4/examples/ItemSelector3-no-desc.rb   
2019-11-12 11:18:46.000000000 +0100
@@ -0,0 +1,53 @@
+# encoding: utf-8
+
+module Yast
+  class ExampleClient < Client
+    def main
+      Yast.import "UI"
+
+      UI.OpenDialog(
+       VBox(
+         SingleItemSelector(
+           Id(:pizza),
+           [
+             # Notice no item IDs, so we'll get the item label as the result.
+             # Also no descriptions.
+             Item("Pizza Margherita"      ),
+             Item("Pizza Capricciosa"     ),
+             Item("Pizza Funghi"          ),
+             Item("Pizza Prosciutto"      ),
+             Item("Pizza Quattro Stagioni"),
+             Item("Calzone"               )
+           ]
+         ),
+         PushButton("&OK")
+       )
+      )
+      UI.UserInput
+
+      # Fetch the result as long as the widget still exists, i.e. BEFORE 
UI.CloseDialog
+      # For a SingleItemSelector, use :Value (i.e. the first selected item);
+      # for a MultiItemSelector,  use :SelectedItems
+      #
+      # :SelectedItems returns an array of the the ID (or the label string if
+      # there is no ID) of each selected item, not the complete item.
+
+      result = UI.QueryWidget(:pizza, :Value)
+      UI.CloseDialog
+
+      # Show the result in a pop-up dialog
+      UI.OpenDialog(
+       VBox(
+         Label("Selected:\n#{result}"),
+         PushButton("&OK")
+       )
+      )
+      UI.UserInput
+      UI.CloseDialog
+
+      nil
+    end
+  end
+end
+
+Yast::ExampleClient.new.main
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-ycp-ui-bindings-4.2.3/package/yast2-ycp-ui-bindings.changes 
new/yast2-ycp-ui-bindings-4.2.4/package/yast2-ycp-ui-bindings.changes
--- old/yast2-ycp-ui-bindings-4.2.3/package/yast2-ycp-ui-bindings.changes       
2019-09-24 15:44:02.000000000 +0200
+++ new/yast2-ycp-ui-bindings-4.2.4/package/yast2-ycp-ui-bindings.changes       
2019-11-12 11:18:46.000000000 +0100
@@ -1,4 +1,16 @@
 -------------------------------------------------------------------
+Tue Nov 12 09:27:46 UTC 2019 - Steffen Winterfeldt <[email protected]>
+
+- require correct libyui version (bsc#1153103)
+- 4.2.5
+
+-------------------------------------------------------------------
+Thu Nov  7 13:26:47 UTC 2019 - Stefan Hundhammer <[email protected]>
+
+- Support for CustomStatusItemSelector (bsc#1084674)
+- 4.2.4
+
+-------------------------------------------------------------------
 Tue Sep 24 13:15:45 UTC 2019 - Stefan Hundhammer <[email protected]>
 
 - Added example for icons in ItemSelector widget (bsc#1084674)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-ycp-ui-bindings-4.2.3/package/yast2-ycp-ui-bindings.spec 
new/yast2-ycp-ui-bindings-4.2.4/package/yast2-ycp-ui-bindings.spec
--- old/yast2-ycp-ui-bindings-4.2.3/package/yast2-ycp-ui-bindings.spec  
2019-09-24 15:44:02.000000000 +0200
+++ new/yast2-ycp-ui-bindings-4.2.4/package/yast2-ycp-ui-bindings.spec  
2019-11-12 11:18:46.000000000 +0100
@@ -15,9 +15,12 @@
 # Please submit bugfixes or comments via http://bugs.opensuse.org/
 #
 
+# YUIWidget_CustomStatusItemSelector
+%define min_yui_version        3.8.4
+%define yui_so         10
 
 Name:           yast2-ycp-ui-bindings
-Version:        4.2.3
+Version:        4.2.4
 Release:        0
 
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
@@ -38,8 +41,8 @@
 Requires:      yast2-core
 BuildRequires: yast2-core-devel
 
-# YWidgetFactory::createSingleItemSelector()
-BuildRequires: libyui-devel >= 3.8.0
+BuildRequires: libyui-devel >= %min_yui_version
+Requires:      libyui%yui_so >= %min_yui_version
 
 # libyui ImplPtr
 BuildRequires: boost-devel
@@ -60,7 +63,7 @@
 Requires:      glibc-devel
 Requires:      libstdc++-devel
 Requires:      boost-devel
-Requires:      libyui-devel
+Requires:      libyui-devel >= %min_yui_version
 Requires:      yast2-core-devel
 Requires:      yast2-devtools
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-ycp-ui-bindings-4.2.3/src/YCPDialogParser.cc 
new/yast2-ycp-ui-bindings-4.2.4/src/YCPDialogParser.cc
--- old/yast2-ycp-ui-bindings-4.2.3/src/YCPDialogParser.cc      2019-09-24 
15:44:02.000000000 +0200
+++ new/yast2-ycp-ui-bindings-4.2.4/src/YCPDialogParser.cc      2019-11-12 
11:18:46.000000000 +0100
@@ -267,6 +267,7 @@
     else if ( s == YUIWidget_CheckBox          )       w = parseCheckBox       
        ( p, opt, term, ol, n );
     else if ( s == YUIWidget_CheckBoxFrame     )       w = parseCheckBoxFrame  
        ( p, opt, term, ol, n );
     else if ( s == YUIWidget_ComboBox          )       w = parseComboBox       
        ( p, opt, term, ol, n );
+    else if ( s == YUIWidget_CustomStatusItemSelector )        w = 
parseCustomStatusItemSelector( p, opt, term, ol, n );
     else if ( s == YUIWidget_Empty             )       w = parseEmpty          
        ( p, opt, term, ol, n );
     else if ( s == YUIWidget_Frame             )       w = parseFrame          
        ( p, opt, term, ol, n );
     else if ( s == YUIWidget_HBox              )       w = parseLayoutBox      
        ( p, opt, term, ol, n, YD_HORIZ );
@@ -833,8 +834,9 @@
                             const YCPTerm & term, const YCPList & optList, int 
argnr )
 {
 
-    int s = term->size() - argnr;
-    if ( s != 2
+    int numArgs = term->size() - argnr;
+
+    if ( numArgs != 2
         || ! term->value( argnr )->isString()
         || ! term->value( argnr+1 )->isTerm() )
     {
@@ -1528,11 +1530,11 @@
 YCPDialogParser::parseMenuButton( YWidget * parent, YWidgetOpt & opt,
                                  const YCPTerm & term, const YCPList & 
optList, int argnr )
 {
-    int numargs = term->size() - argnr;
+    int numArgs = term->size() - argnr;
 
-    if ( numargs < 1 || numargs > 2
+    if ( numArgs < 1 || numArgs > 2
         || ! term->value( argnr )->isString()
-        || ( numargs >= 2 && ! term->value( argnr+1 )->isList() ) )
+        || ( numArgs >= 2 && ! term->value( argnr+1 )->isList() ) )
     {
        THROW_BAD_ARGS( term );
     }
@@ -1543,7 +1545,7 @@
 
     YMenuButton * menuButton = YUI::widgetFactory()->createMenuButton( parent, 
label );
 
-    if ( numargs >= 2 )
+    if ( numArgs >= 2 )
     {
        YCPList itemList = term->value( argnr+1 )->asList();
        menuButton->addItems( YCPMenuItemParser::parseMenuItemList( itemList ) 
);
@@ -1577,10 +1579,11 @@
 YCPDialogParser::parseCheckBox( YWidget * parent, YWidgetOpt & opt,
                                const YCPTerm & term, const YCPList & optList, 
int argnr )
 {
-    int size = term->size() - argnr;
-    if ( size < 1 || size > 2
+    int numArgs = term->size() - argnr;
+
+    if ( numArgs < 1 || numArgs > 2
         || ! term->value( argnr )->isString()
-        || ( size == 2 && ! term->value( argnr+1 )->isBoolean() ) )
+        || ( numArgs == 2 && ! term->value( argnr+1 )->isBoolean() ) )
     {
        THROW_BAD_ARGS( term );
     }
@@ -1590,7 +1593,7 @@
     string label   = term->value( argnr )->asString()->value();
     bool   checked = false;
 
-    if ( size == 2 )
+    if ( numArgs == 2 )
        checked = term->value( argnr+1 )->asBoolean()->value();
 
     YCheckBox * checkBox = YUI::widgetFactory()->createCheckBox( parent, 
label, checked );
@@ -1640,8 +1643,9 @@
 YCPDialogParser::parseCheckBoxFrame( YWidget * parent, YWidgetOpt & opt,
                                     const YCPTerm & term, const YCPList & 
optList, int argnr )
 {
-    int s = term->size() - argnr;
-    if ( s != 3
+    int numArgs = term->size() - argnr;
+
+    if ( numArgs != 3
         || ! term->value( argnr   )->isString()
         || ! term->value( argnr+1 )->isBoolean()
         || ! term->value( argnr+2 )->isTerm()
@@ -1712,10 +1716,11 @@
                                   const YCPTerm & term, const YCPList & 
optList, int argnr )
 {
 
-    int s = term->size() - argnr;
-    if ( s < 1 || s > 2
+    int numArgs = term->size() - argnr;
+
+    if ( numArgs < 1 || numArgs > 2
         || ! term->value( argnr )->isString()
-        || ( s == 2 && ! term->value( argnr+1 )->isBoolean() ) )
+        || ( numArgs == 2 && ! term->value( argnr+1 )->isBoolean() ) )
     {
        THROW_BAD_ARGS( term );
     }
@@ -1724,7 +1729,8 @@
 
     string label     = term->value( argnr )->asString()->value();
     bool   isChecked = false;
-    if ( s == 2 )
+
+    if ( numArgs == 2 )
        isChecked = term->value( argnr+1 )->asBoolean()->value();
 
     YRadioButton * radioButton = YUI::widgetFactory()->createRadioButton( 
parent, label, isChecked );
@@ -1945,11 +1951,11 @@
 YCPDialogParser::parseSelectionBox( YWidget * parent, YWidgetOpt & opt,
                                    const YCPTerm & term, const YCPList & 
optList, int argnr )
 {
-    int numargs = term->size() - argnr;
+    int numArgs = term->size() - argnr;
 
-    if ( numargs < 1 || numargs > 2
+    if ( numArgs < 1 || numArgs > 2
         || ! term->value( argnr )->isString()
-        || ( numargs >= 2 && ! term->value( argnr+1 )->isList() ) )
+        || ( numArgs >= 2 && ! term->value( argnr+1 )->isList() ) )
     {
        THROW_BAD_ARGS( term );
     }
@@ -1974,7 +1980,7 @@
     if ( immediate )
        selBox->setImmediateMode( true ); // includes setNotify()
 
-    if ( numargs >= 2 )
+    if ( numArgs >= 2 )
     {
        YCPList itemList = term->value( argnr+1 )->asList();
        selBox->addItems( YCPItemParser::parseItemList( itemList ) );
@@ -2014,11 +2020,11 @@
 YCPDialogParser::parseMultiSelectionBox( YWidget * parent, YWidgetOpt & opt,
                                         const YCPTerm & term, const YCPList & 
optList, int argnr )
 {
-    int numargs = term->size() - argnr;
+    int numArgs = term->size() - argnr;
 
-    if ( numargs < 1 || numargs > 2
+    if ( numArgs < 1 || numArgs > 2
         || ! term->value( argnr )->isString()
-        || ( numargs >= 2 && ! term->value( argnr+1 )->isList() ) )
+        || ( numArgs >= 2 && ! term->value( argnr+1 )->isList() ) )
     {
        THROW_BAD_ARGS( term );
     }
@@ -2037,7 +2043,7 @@
     if ( shrinkable )
        multiSelectionBox->setShrinkable( true );
 
-    if ( numargs >= 2 )
+    if ( numArgs >= 2 )
     {
        YCPList itemList = term->value( argnr+1 )->asList();
        multiSelectionBox->addItems( YCPItemParser::parseItemList( itemList ) );
@@ -2052,8 +2058,12 @@
  * @short      Scrollable list of radio buttons or check boxes with a 
description text
  * @class      YItemSelector
  * @optarg     list    items   the initial items
- * @example    SingleItemselector1.rb
- * @example    MultiItemselector1.rb
+ *
+ * @example    ItemSelector1.rb
+ * @example    ItemSelector2-minimalistic.rb
+ * @example    MultiItemSelector1.rb
+ * @example    SingleItemSelector1.rb
+ * @example    SingleItemSelector2-icons.rb
  *
  *
  * This is a scrollable list of radio buttons (SingleItemSelector) or check
@@ -2075,10 +2085,10 @@
                                     const YCPTerm & term, const YCPList & 
optList, int argnr,
                                     bool singleSelection )
 {
-    int numargs = term->size() - argnr;
+    int numArgs = term->size() - argnr;
 
-    if ( numargs > 1 ||
-         ( numargs == 1 && ! term->value( argnr )->isList() ) )
+    if ( numArgs > 1 ||
+         ( numArgs == 1 && ! term->value( argnr )->isList() ) )
     {
        THROW_BAD_ARGS( term );
     }
@@ -2087,7 +2097,7 @@
 
     YItemSelector * itemSelector = YUI::widgetFactory()->createItemSelector( 
parent, singleSelection );
 
-    if ( numargs == 1 )
+    if ( numArgs == 1 )
     {
        YCPList itemList = term->value( argnr )->asList();
        itemSelector->addItems( YCPItemParser::parseDescribedItemList( itemList 
) );
@@ -2099,6 +2109,124 @@
 
 
 /**
+ * @widget     CustomStatusItemSelector
+ * @short      Scrollable list of items with a custom status with a 
description text
+ * @class      YItemSelector
+ * @optarg     list    states  definition of the custom status values
+ * @optarg     list    items   the initial items
+ *
+ * @example    ItemSelector1.rb
+ * @example    ItemSelector2-minimalistic.rb
+ * @example    MultiItemSelector1.rb
+ * @example    SingleItemSelector1.rb
+ * @example    SingleItemSelector2-icons.rb
+ *
+ *
+ * This is very much like the MultiItemSelector, but each item can have more
+ * different status values than just 0 or 1 (or true or false). The list of
+ * possible status values is the first list in the widget's arguments.
+ *
+ * Each status value has a string for the icon to use, a string for the text
+ * equivalent (for the NCurses UI) of the status indicator ("[ ]", "[x]" or "[
+ * ]", "[ +]", "[a+]") and an optional integer for the next status to
+ * automatically go to when the user clicks on an item with that status (-1
+ * means the application will handle it; this is the default if not specified).
+ *
+ * The icons use the usual fallback chain for UI icons: Use compiled-in icons
+ * if available, use the theme, or, if an absolute path is specified, use that
+ * absolute path.
+ *
+ * For the text indicator it is highly recommended to use strings of the same
+ * length to line up items properly.
+ *
+ * If the application chooses to handle the next status, it is recommended to
+ * set the notify option for the widget. In that case, the widget sends menu
+ * events (not widget events!) with the ID of the item the user clicked (or
+ * activated with the keyboard).
+ **/
+YWidget *
+YCPDialogParser::parseCustomStatusItemSelector( YWidget * parent, YWidgetOpt & 
opt,
+                                                const YCPTerm & term, const 
YCPList & optList, int argnr )
+{
+    int numArgs = term->size() - argnr;
+
+    if ( numArgs < 1 || numArgs > 2 ||
+         ( ! term->value( argnr )->isList() ) ||
+         ( numArgs == 2 && ! term->value( argnr+1 )->isList() ) )
+    {
+       THROW_BAD_ARGS( term );
+    }
+
+    rejectAllOptions( term, optList );
+
+    YItemCustomStatusVector customStates = parseCustomStates( term->value( 
argnr )->asList() );
+    YItemSelector * itemSelector = 
YUI::widgetFactory()->createCustomStatusItemSelector( parent, customStates );
+
+    if ( numArgs == 2 )
+    {
+       YCPList itemList = term->value( argnr+1 )->asList();
+       itemSelector->addItems( YCPItemParser::parseDescribedItemList( itemList 
) );
+    }
+
+    return itemSelector;
+}
+
+
+/**
+ * Parse a custom status definition list (minimum 2 entries):
+ *
+ *      iconName          Ncurses nextStatus  no.
+ *   [
+ *     ["iconDontInstall", "[  ]",  1],      // 0
+ *     ["iconInstall",     "[++]",  0],      // 1
+ *     ["iconAutoInstall", "[a+]"    ],      // 2
+ *     ["iconKeep",        "[ x]"   4],      // 3
+ *     ["iconRemove",      "[--]",  3],      // 4
+ *     ["iconAutoRemove",  "[a-]"    ]       // 5
+ *   ]
+ **/
+YItemCustomStatusVector
+YCPDialogParser::parseCustomStates( const YCPList & statesList )
+{
+    const char * usage = "Expected: [ [\"iconName1\", \"textIndicator1\", int 
nextStatus], [...], ...]";
+    
+    YItemCustomStatusVector customStates;
+
+    for ( int i=0; i < statesList.size(); i++ )
+    {
+        YCPValue val = statesList->value( i );
+
+        if ( ! val->isList() )
+            YUI_THROW( YCPDialogSyntaxErrorException( usage, statesList ) );
+        
+        YCPList stat = val->asList();
+
+        if ( stat->size() < 2 || stat->size() > 3 ||
+             ! stat->value( 0 )->isString() ||
+             ! stat->value( 1 )->isString() ||
+             ( stat->size() == 3 && ! stat->value( 2 )->isInteger() ) )
+        {
+            YUI_THROW( YCPDialogSyntaxErrorException( usage, statesList ) );
+        }
+
+        string iconName      = stat->value( 0 )->asString()->value();
+        string textIndicator = stat->value( 1 )->asString()->value();
+        int    nextStatus    = stat->size() == 3 ? stat->value( 2 
)->asInteger()->value() : -1;
+
+        if ( nextStatus > statesList.size() - 1 )
+            YUI_THROW( YCPDialogSyntaxErrorException( "nextStatus > 
maxStatus", statesList ) );
+
+        customStates.push_back( YItemCustomStatus( iconName, textIndicator, 
nextStatus ) );
+    }
+
+    if ( customStates.size() < 2 )
+        YUI_THROW( YCPDialogSyntaxErrorException( "Need at least 2 custom 
status values", statesList ) );
+    
+    return customStates;
+}
+
+
+/**
  * @widget     ComboBox
  * @short      drop-down list selection (optionally editable)
  * @class      YComboBox
@@ -2135,11 +2263,11 @@
 YCPDialogParser::parseComboBox( YWidget * parent, YWidgetOpt & opt,
                                const YCPTerm & term, const YCPList & optList, 
int argnr )
 {
-    int numargs = term->size() - argnr;
+    int numArgs = term->size() - argnr;
 
-    if ( numargs < 1 || numargs > 2
+    if ( numArgs < 1 || numArgs > 2
         || ! term->value(argnr)->isString()
-        || ( numargs >= 2 && ! term->value( argnr+1 )->isList() ) )
+        || ( numArgs >= 2 && ! term->value( argnr+1 )->isList() ) )
     {
        THROW_BAD_ARGS( term );
     }
@@ -2155,7 +2283,7 @@
 
     YComboBox * comboBox = YUI::widgetFactory()->createComboBox( parent, 
label, editable );
 
-    if ( numargs >= 2 )
+    if ( numArgs >= 2 )
     {
        YCPList itemList = term->value( argnr+1 )->asList();
        comboBox->addItems( YCPItemParser::parseItemList( itemList ) );
@@ -2500,12 +2628,12 @@
 YCPDialogParser::parseProgressBar( YWidget * parent, YWidgetOpt & opt,
                                   const YCPTerm & term, const YCPList & 
optList, int argnr )
 {
-    int s = term->size() - argnr;
-    if ( s < 1
-        || s > 3
-        || (s >= 1 && ! term->value(argnr)->isString())
-        || (s >= 2 && ! term->value( argnr+1 )->isInteger())
-        || (s >= 3 && ! term->value( argnr+2 )->isInteger()))
+    int numArgs = term->size() - argnr;
+    if ( numArgs < 1
+        || numArgs > 3
+        || ( numArgs >= 1 && ! term->value(argnr)->isString() )
+        || ( numArgs >= 2 && ! term->value( argnr+1 )->isInteger() )
+        || ( numArgs >= 3 && ! term->value( argnr+2 )->isInteger()) )
     {
        THROW_BAD_ARGS( term );
     }
@@ -2516,8 +2644,8 @@
     int            maxValue     = 100;
     int            initialValue = 0;
 
-    if ( s >= 2 ) maxValue     = term->value( argnr+1 )->asInteger()->value();
-    if ( s >= 3 ) initialValue = term->value( argnr+2 )->asInteger()->value();
+    if ( numArgs >= 2 ) maxValue       = term->value( argnr+1 
)->asInteger()->value();
+    if ( numArgs >= 3 ) initialValue   = term->value( argnr+2 
)->asInteger()->value();
 
     YProgressBar * progressBar = YUI::widgetFactory()->createProgressBar( 
parent, label, maxValue );
 
@@ -3641,11 +3769,12 @@
 YCPDialogParser::parseBusyIndicator( YWidget * parent, YWidgetOpt & opt,
                                   const YCPTerm & term, const YCPList & 
optList, int argnr )
 {
-    int s = term->size() - argnr;
-    if ( s < 1
-        || s > 2
-        || ( s >= 1 && ! term->value(argnr)->isString()      )
-        || ( s >= 2 && ! term->value( argnr+1 )->isInteger() ) )
+    int numArgs = term->size() - argnr;
+
+    if ( numArgs < 1
+        || numArgs > 2
+        || ( numArgs >= 1 && ! term->value(argnr)->isString()      )
+        || ( numArgs >= 2 && ! term->value( argnr+1 )->isInteger() ) )
     {
        THROW_BAD_ARGS( term );
     }
@@ -3655,7 +3784,7 @@
     string  label       = term->value( argnr )->asString()->value();
     int            timeout      = 1000;
 
-    if ( s >= 2 ) timeout      = term->value( argnr+1 )->asInteger()->value();
+    if ( numArgs >= 2 ) timeout        = term->value( argnr+1 
)->asInteger()->value();
 
     YBusyIndicator * busyIndicator = 
YUI::widgetFactory()->createBusyIndicator( parent, label, timeout );
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-ycp-ui-bindings-4.2.3/src/YCPDialogParser.h 
new/yast2-ycp-ui-bindings-4.2.4/src/YCPDialogParser.h
--- old/yast2-ycp-ui-bindings-4.2.3/src/YCPDialogParser.h       2019-09-24 
15:44:02.000000000 +0200
+++ new/yast2-ycp-ui-bindings-4.2.4/src/YCPDialogParser.h       2019-11-12 
11:18:46.000000000 +0100
@@ -34,6 +34,7 @@
 #include <ycp/YCPList.h>
 
 #include <yui/YTypes.h>
+#include <yui/YItemCustomStatus.h>
 
 using std::vector;
 
@@ -222,9 +223,15 @@
     static YWidget * parseMultiSelectionBox( YWidget *parent, YWidgetOpt & opt,
                                             const YCPTerm & term, const 
YCPList & optList, int argnr );
 
+    /**
+     * SingleItemSelector, MultiItemSelector
+     **/
     static YWidget * parseItemSelector( YWidget *parent, YWidgetOpt & opt,
                                         const YCPTerm & term, const YCPList & 
optList, int argnr,
                                         bool singleSelection );
+    
+    static YWidget * parseCustomStatusItemSelector( YWidget *parent, 
YWidgetOpt & opt,
+                                                    const YCPTerm & term, 
const YCPList & optList, int argnr );
 
     static YWidget * parseComboBox( YWidget *parent, YWidgetOpt & opt,
                                    const YCPTerm & term, const YCPList & 
optList, int argnr );
@@ -291,6 +298,10 @@
 
     static YWidget * parseBusyIndicator( YWidget *parent, YWidgetOpt & opt,
                                          const YCPTerm & term, const YCPList & 
optList, int argnr );
+
+
+    static YItemCustomStatusVector parseCustomStates( const YCPList & 
statesList );
+    
     /**
      * Look for a widget id in a widget term. If it finds one, returns
      * it and sets argnr to point after `id(), whether it turned out valid
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-ycp-ui-bindings-4.2.3/src/YCPPropertyHandler.cc 
new/yast2-ycp-ui-bindings-4.2.4/src/YCPPropertyHandler.cc
--- old/yast2-ycp-ui-bindings-4.2.3/src/YCPPropertyHandler.cc   2019-09-24 
15:44:02.000000000 +0200
+++ new/yast2-ycp-ui-bindings-4.2.4/src/YCPPropertyHandler.cc   2019-11-12 
11:18:46.000000000 +0100
@@ -76,7 +76,7 @@
 
 bool
 YCPPropertyHandler::setComplexProperty( YWidget *              widget,
-                                       const string &          propertyName,
+                                       const string &          propertyName,
                                        const YCPValue &        val )
 {
     // y2debug( "%s::%s", widget->widgetClass(), propertyName.c_str() );
@@ -95,7 +95,7 @@
     else if ( propertyName == YUIProperty_Values )
     {
        if ( trySetMultiProgressMeterValues ( widget, val ) )           return 
true;
-       if ( trySetBarGraphValues       ( widget, val ) )               return 
true;
+       if ( trySetBarGraphValues       ( widget, val ) )               return 
true;
     }
     else if ( propertyName == YUIProperty_Labels )
     {
@@ -109,7 +109,7 @@
        if ( trySetTableValue           ( widget, val ) )               return 
true;
        if ( trySetDumbTabValue         ( widget, val ) )               return 
true;
 
-       if ( trySetMultiSelectionBoxCurrentItem( widget, val ) )        return 
true;
+       if ( trySetMultiSelectionBoxCurrentItem ( widget, val ) )       return 
true;
     }
     else if ( propertyName == YUIProperty_Items )
     {
@@ -122,6 +122,10 @@
        if ( trySetItemSelectorItems    ( widget, val ) )               return 
true;
        if ( trySetSelectionWidgetItems ( widget, val ) )               return 
true;
     }
+    else if ( propertyName == YUIProperty_ItemStatus )
+    {
+       if ( trySetSelectionWidgetItemStatus    ( widget, val ) )       return 
true;
+    }
     else if ( propertyName == YUIProperty_CurrentButton )
     {
        if ( trySetRadioButtonGroupCurrentButton( widget, val ) )       return 
true;
@@ -129,9 +133,9 @@
     else if ( propertyName == YUIProperty_SelectedItems )
     {
        if ( trySetMultiSelectionBoxSelectedItems( widget, val ) )      return 
true;
-       if ( trySetItemSelectorSelectedItems    ( widget, val ) )       return 
true;
-       if ( trySetTableSelectedItems           ( widget, val ) )       return 
true;
-       if ( trySetTreeSelectedItems            ( widget, val ) )       return 
true;
+       if ( trySetItemSelectorSelectedItems    ( widget, val ) )       return 
true;
+       if ( trySetTableSelectedItems           ( widget, val ) )       return 
true;
+       if ( trySetTreeSelectedItems            ( widget, val ) )       return 
true;
     }
 
     y2error( "Can't handle property %s::%s - not changing anything",
@@ -143,8 +147,8 @@
 
 bool
 YCPPropertyHandler::setComplexProperty( YWidget *              widget,
-                                       const YCPTerm &         propertyTerm,
-                                       const YCPValue &        val             
)
+                                       const YCPTerm &         propertyTerm,
+                                       const YCPValue &        val             
)
 {
     string propertyName = propertyTerm->name();
 
@@ -172,12 +176,12 @@
     {
        val = tryGetCheckBoxValue       ( widget );     if ( ! val.isNull() ) 
return val;
        val = tryGetSelectionBoxValue   ( widget );     if ( ! val.isNull() ) 
return val;
-        val = tryGetItemSelectorValue   ( widget );     if ( ! val.isNull() ) 
return val;
+       val = tryGetItemSelectorValue   ( widget );     if ( ! val.isNull() ) 
return val;
        val = tryGetTreeValue           ( widget );     if ( ! val.isNull() ) 
return val;
        val = tryGetTableValue          ( widget );     if ( ! val.isNull() ) 
return val;
        val = tryGetComboBoxValue       ( widget );     if ( ! val.isNull() ) 
return val;
        val = tryGetDumbTabValue        ( widget );     if ( ! val.isNull() ) 
return val;
-        val = tryGetRadioButtonGroupCurrentButton( widget );   if ( ! 
val.isNull() ) return val;
+       val = tryGetRadioButtonGroupCurrentButton( widget );    if ( ! 
val.isNull() ) return val;
     }
     else if ( propertyName == YUIProperty_Values )
     {
@@ -186,7 +190,7 @@
     else if ( propertyName == YUIProperty_CurrentItem )
     {
        val = tryGetSelectionBoxValue   ( widget );     if ( ! val.isNull() ) 
return val;
-        val = tryGetItemSelectorValue   ( widget );     if ( ! val.isNull() ) 
return val;
+       val = tryGetItemSelectorValue   ( widget );     if ( ! val.isNull() ) 
return val;
        val = tryGetTreeCurrentItem     ( widget );     if ( ! val.isNull() ) 
return val;
        val = tryGetTableValue          ( widget );     if ( ! val.isNull() ) 
return val;
        val = tryGetComboBoxValue       ( widget );     if ( ! val.isNull() ) 
return val;
@@ -201,10 +205,10 @@
     }
     else if ( propertyName == YUIProperty_SelectedItems )
     {
-       val = tryGetMultiSelectionBoxSelectedItems( widget );   if ( ! 
val.isNull() ) return val;
-       val = tryGetItemSelectorSelectedItems   ( widget );     if ( ! 
val.isNull() ) return val;
-       val = tryGetTableSelectedItems          ( widget );     if ( ! 
val.isNull() ) return val;
-       val = tryGetTreeSelectedItems           ( widget );     if ( ! 
val.isNull() ) return val;
+       val = tryGetItemSelectorSelectedItems   ( widget );     if ( ! 
val.isNull() ) return val;
+       val = tryGetTableSelectedItems          ( widget );     if ( ! 
val.isNull() ) return val;
+       val = tryGetTreeSelectedItems           ( widget );     if ( ! 
val.isNull() ) return val;
+       val = tryGetMultiSelectionBoxSelectedItems( widget );   if ( ! 
val.isNull() ) return val;
     }
     else if ( propertyName == YUIProperty_OpenItems )
     {
@@ -219,11 +223,15 @@
        // Make sure to try YMenuButton, YTable, YTree, before YSelectionWidget:
        // they all inherit YSelectionWidget!
 
-       val = tryGetMenuButtonItems     ( widget );     if ( ! val.isNull() ) 
return val;
-       val = tryGetTableItems          ( widget );     if ( ! val.isNull() ) 
return val;
-       val = tryGetTreeItems           ( widget );     if ( ! val.isNull() ) 
return val;
-       val = tryGetItemSelectorItems   ( widget );     if ( ! val.isNull() ) 
return val;
-       val = tryGetSelectionWidgetItems( widget );     if ( ! val.isNull() ) 
return val;
+       val = tryGetMenuButtonItems             ( widget );     if ( ! 
val.isNull() ) return val;
+       val = tryGetTableItems                  ( widget );     if ( ! 
val.isNull() ) return val;
+       val = tryGetTreeItems                   ( widget );     if ( ! 
val.isNull() ) return val;
+       val = tryGetItemSelectorItems           ( widget );     if ( ! 
val.isNull() ) return val;
+       val = tryGetSelectionWidgetItems        ( widget );     if ( ! 
val.isNull() ) return val;
+    }
+    else if ( propertyName == YUIProperty_ItemStatus )
+    {
+       val = tryGetSelectionWidgetItemStatus   ( widget );     if ( ! 
val.isNull() ) return val;
     }
     else if ( propertyName == YUIProperty_Labels )
     {
@@ -515,7 +523,7 @@
        return true;
     }
 
-    YUI_THROW( YUIBadPropertyArgException( YProperty( YUIProperty_Items,
+    YUI_THROW( YUIBadPropertyArgException( YProperty( YUIProperty_ItemStatus,
                                                      YOtherProperty ),
                                           widget ) );
     return false;
@@ -523,6 +531,77 @@
 
 
 bool
+YCPPropertyHandler::trySetSelectionWidgetItemStatus( YWidget * widget, const 
YCPValue & val )
+{
+    YSelectionWidget * selWidget = dynamic_cast<YSelectionWidget *>( widget );
+
+    if ( ! selWidget )
+       return false;
+
+    bool ok = val->isMap();
+
+    if ( ok )
+    {
+       YCPMap statusMap = val->asMap();
+
+       for ( YCPMap::const_iterator it = statusMap->begin();
+             it != statusMap->end() && ok;
+             ++it )
+       {
+           ok = setItemStatus( selWidget, it->first, it->second );
+       }
+    }
+
+    if ( ! ok )
+    {
+       YUI_THROW( YUIBadPropertyArgException( YProperty( 
YUIProperty_ItemStatus,
+                                                         YOtherProperty ),
+                                              widget ) );
+    }
+
+    return ok;
+}
+
+
+bool
+YCPPropertyHandler::setItemStatus( YSelectionWidget *  widget,
+                                  const YCPValue &     itemId,
+                                  const YCPValue &     newStatus )
+{
+    int status;
+
+    if ( newStatus->isInteger() )
+       status = newStatus->asInteger()->value();
+    else if ( newStatus->isBoolean() )
+       status = newStatus->asBoolean()->value() ? 1 : 0;
+    else
+    {
+       y2error( "Setting ItemStatus for item with ID %s: "
+                "Expected integer or boolean, not %s",
+                itemId->toString().c_str(), newStatus->toString().c_str() );
+
+       return false;
+    }
+
+    YCPItem * item = findItem<YCPItem>( widget, itemId );
+
+    if ( ! item )
+    {
+       y2error( "%s %s has no item with ID %s",
+                widget->widgetClass(),
+                widget->debugLabel().c_str(),
+                itemId->toString().c_str() );
+
+       return false;
+    }
+
+    widget->setItemStatus( item, status );
+
+    return true;
+}
+
+
+bool
 YCPPropertyHandler::trySetTableItems( YWidget * widget, const YCPValue & val )
 {
     YTable * table = dynamic_cast<YTable *> (widget );
@@ -888,7 +967,7 @@
 
     switch ( checkBox->value() )
     {
-       case YCheckBox_on:              return YCPBoolean( true  );
+       case YCheckBox_on:              return YCPBoolean( true  );
        case YCheckBox_off:             return YCPBoolean( false );
        case YCheckBox_dont_care:       return YCPVoid();       // nil
     }
@@ -1124,8 +1203,8 @@
 
 void
 YCPPropertyHandler::getTreeOpenItems( YCPMap &                 openItems,
-                                     YItemConstIterator        begin,
-                                     YItemConstIterator        end )
+                                     YItemConstIterator        begin,
+                                     YItemConstIterator        end )
 {
     for ( YItemConstIterator it = begin; it != end; ++it )
     {
@@ -1161,7 +1240,7 @@
     // YTree::CurrentBranch: The path from the root to the current item as a
     // list of IDs or, if an item doesn't have an ID, its label
     //
-    //     "/" -> `usr -> `share -> "doc"
+    //    "/" -> `usr -> `share -> "doc"
     //
     // -> [ "/", `usr, `share, "doc" ]
 
@@ -1316,13 +1395,13 @@
     YTree * tree = dynamic_cast<YTree *> (widget);
 
     if ( ! tree )
-        return YCPNull();
+       return YCPNull();
 
     YItem * currentItem = tree->currentItem();
     YCPTreeItem * item = dynamic_cast<YCPTreeItem *> (currentItem);
 
     if ( item )
-        return item->id();
+       return item->id();
 
     return YCPVoid();
 
@@ -1351,7 +1430,7 @@
        return YCPNull();
 
     return YCPItemWriter::describedItemList( itemSelector->itemsBegin(),
-                                             itemSelector->itemsEnd() );
+                                            itemSelector->itemsEnd() );
 }
 
 
@@ -1367,6 +1446,36 @@
 }
 
 
+YCPValue
+YCPPropertyHandler::tryGetSelectionWidgetItemStatus( YWidget * widget )
+{
+    YSelectionWidget * selWidget = dynamic_cast<YSelectionWidget *> (widget);
+
+    if ( ! selWidget )
+       return YCPNull();
+
+    YCPMap result;
+
+    for ( YItemConstIterator it = selWidget->itemsBegin(); it != 
selWidget->itemsEnd(); ++it )
+    {
+        YItem * item = *it;
+
+        if ( item )
+        {
+            YItem   * item = *it;
+            YCPItem * ycpItem = dynamic_cast<YCPItem *>( item );
+
+            if ( ycpItem && ycpItem->hasId() )
+                result->add( ycpItem->id(), YCPInteger( item->status() ) );
+            else
+                result->add( YCPString( item->label() ), YCPInteger( 
item->status() ) );
+        }
+    }
+
+    return result;
+}
+
+
 YCPValue
 YCPPropertyHandler::tryGetBarGraphValues( YWidget * widget )
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-ycp-ui-bindings-4.2.3/src/YCPPropertyHandler.h 
new/yast2-ycp-ui-bindings-4.2.4/src/YCPPropertyHandler.h
--- old/yast2-ycp-ui-bindings-4.2.3/src/YCPPropertyHandler.h    2019-09-24 
15:44:02.000000000 +0200
+++ new/yast2-ycp-ui-bindings-4.2.4/src/YCPPropertyHandler.h    2019-11-12 
11:18:46.000000000 +0100
@@ -66,7 +66,7 @@
      * Return 'true' on success, 'false' on failure.
      **/
     static bool setComplexProperty( YWidget *          widget,
-                                   const string &      propertyName,
+                                   const string &      propertyName,
                                    const YCPValue &    val );
 
     /**
@@ -75,15 +75,15 @@
      * Return 'true' on success, 'false' on failure.
      **/
     static bool setComplexProperty( YWidget *          widget,
-                                   const YCPTerm &     propertyTerm,
-                                   const YCPValue &    val             );
+                                   const YCPTerm &     propertyTerm,
+                                   const YCPValue &    val             );
 
     /**
      * Get a complex property.
      *
      * Return YCPNull upon failure, a non-null YCPValue (the result) upon 
success.
      **/
-    static YCPValue getComplexProperty( YWidget *      widget,
+    static YCPValue getComplexProperty( YWidget *      widget,
                                        const string &  propertyName );
 
     /**
@@ -91,7 +91,7 @@
      *
      * Return YCPNull upon failure, a non-null YCPValue (the result) upon 
success.
      **/
-    static YCPValue getComplexProperty( YWidget *      widget,
+    static YCPValue getComplexProperty( YWidget *      widget,
                                        const YCPTerm & propertyTerm );
 
 
@@ -114,11 +114,12 @@
     static bool trySetTreeItems                                ( YWidget * 
widget, const YCPValue & val );
     static bool trySetTableItems                       ( YWidget * widget, 
const YCPValue & val );
     static bool trySetTableCell                                ( YWidget * 
widget, const YCPTerm  & propTerm, const YCPValue & val );
-    static bool trySetItemSelectorItems                 ( YWidget * widget, 
const YCPValue & val );
+    static bool trySetItemSelectorItems                        ( YWidget * 
widget, const YCPValue & val );
     static bool trySetSelectionWidgetItems             ( YWidget * widget, 
const YCPValue & val );
+    static bool trySetSelectionWidgetItemStatus                ( YWidget * 
widget, const YCPValue & val );
     static bool trySetRadioButtonGroupCurrentButton    ( YWidget * widget, 
const YCPValue & val );
     static bool trySetMultiSelectionBoxSelectedItems   ( YWidget * widget, 
const YCPValue & val );
-    static bool trySetItemSelectorSelectedItems         ( YWidget * widget, 
const YCPValue & val );
+    static bool trySetItemSelectorSelectedItems                ( YWidget * 
widget, const YCPValue & val );
     static bool trySetTableSelectedItems               ( YWidget * widget, 
const YCPValue & val );
     static bool trySetTreeSelectedItems                        ( YWidget * 
widget, const YCPValue & val );
     static bool trySetMultiSelectionBoxCurrentItem     ( YWidget * widget, 
const YCPValue & val );
@@ -141,7 +142,7 @@
     static YCPValue tryGetComboBoxValue                        ( YWidget * 
widget );
     static YCPValue tryGetRadioButtonGroupCurrentButton        ( YWidget * 
widget );
     static YCPValue tryGetMultiSelectionBoxSelectedItems( YWidget * widget );
-    static YCPValue tryGetItemSelectorSelectedItems     ( YWidget * widget );
+    static YCPValue tryGetItemSelectorSelectedItems    ( YWidget * widget );
     static YCPValue tryGetTableSelectedItems           ( YWidget * widget );
     static YCPValue tryGetTreeSelectedItems            ( YWidget * widget );
     static YCPValue tryGetMultiSelectionBoxCurrentItem ( YWidget * widget );
@@ -152,22 +153,28 @@
     static YCPValue tryGetTableItem                    ( YWidget * widget, 
const YCPTerm & propertyTerm );
     static YCPValue tryGetTableItems                   ( YWidget * widget );
     static YCPValue tryGetTreeItems                    ( YWidget * widget );
-    static YCPValue tryGetItemSelectorItems             ( YWidget * widget );
+    static YCPValue tryGetItemSelectorItems            ( YWidget * widget );
     static YCPValue tryGetMenuButtonItems              ( YWidget * widget );
     static YCPValue tryGetSelectionWidgetItems         ( YWidget * widget );
+    static YCPValue tryGetSelectionWidgetItemStatus    ( YWidget * widget );
     static YCPValue tryGetBarGraphValues               ( YWidget * widget );
     static YCPValue tryGetBarGraphLabels               ( YWidget * widget );
-    static YCPValue tryGetTreeCurrentItem               ( YWidget * widget );
-
+    static YCPValue tryGetTreeCurrentItem              ( YWidget * widget );
 
 
     /**
+     * Set the status of a widget's item to a new value.
+     **/
+    static bool setItemStatus( YSelectionWidget *   widget,
+                              const YCPValue &     itemId,
+                              const YCPValue &     newStatus );
+    /**
      * Helper function for tryGetTreeOpenItems(): Get any open tree items
      * between iterators 'begin' and 'end' and add them to the 'openItems' map.
      **/
-    static void getTreeOpenItems( YCPMap &             openItems,
-                                 YItemConstIterator    begin,
-                                 YItemConstIterator    end );
+    static void getTreeOpenItems( YCPMap &             openItems,
+                                 YItemConstIterator    begin,
+                                 YItemConstIterator    end );
 };
 
 


Reply via email to