Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package yast2-gpmc for openSUSE:Factory 
checked in at 2021-01-15 19:46:38
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/yast2-gpmc (Old)
 and      /work/SRC/openSUSE:Factory/.yast2-gpmc.new.28504 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "yast2-gpmc"

Fri Jan 15 19:46:38 2021 rev:8 rq:863189 version:1.5.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/yast2-gpmc/yast2-gpmc.changes    2019-09-30 
15:59:15.925237946 +0200
+++ /work/SRC/openSUSE:Factory/.yast2-gpmc.new.28504/yast2-gpmc.changes 
2021-01-15 19:47:24.882127801 +0100
@@ -1,0 +2,7 @@
+Wed Jan 13 16:46:07 UTC 2021 - dmul...@suse.com
+
+- Fix unable to parse samba admx templates; (bsc#1180896);
+- Removing ad-dc dependency breaks gpmc; (jsc#ECO-2527);
+- 1.5.1
+
+-------------------------------------------------------------------

Old:
----
  yast2-gpmc-1.5.0.tar.bz2

New:
----
  yast2-gpmc-1.5.1.tar.bz2

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

Other differences:
------------------
++++++ yast2-gpmc.spec ++++++
--- /var/tmp/diff_new_pack.L3G2T9/_old  2021-01-15 19:47:25.434128623 +0100
+++ /var/tmp/diff_new_pack.L3G2T9/_new  2021-01-15 19:47:25.438128629 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package yast2-gpmc
 #
-# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2021 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -12,17 +12,17 @@
 # license that conforms to the Open Source Definition (Version 1.9)
 # published by the Open Source Initiative.
 
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
 #
 
 
 Name:           yast2-gpmc
-Version:        1.5.0
+Version:        1.5.1
 Release:        0
 Summary:        Group Policy Management Console for YaST
 License:        GPL-3.0-only
 Group:          Productivity/Networking/Samba
-Url:            https://github.com/yast/yast2-gpmc
+URL:            https://github.com/yast/yast2-gpmc
 
 Source:         %{name}-%{version}.tar.bz2
 
@@ -36,6 +36,7 @@
 
 Requires:       krb5-client
 Requires:       python3-ldap
+Requires:       samba-ad-dc
 Requires:       samba-client
 Requires:       samba-python3 >= 4.10.0
 Requires:       yast2
@@ -66,5 +67,6 @@
 %{yast_desktopdir}
 %{yast_metainfodir}
 %license COPYING
+%doc %{yast_docdir}
 
 %changelog

++++++ yast2-gpmc-1.5.0.tar.bz2 -> yast2-gpmc-1.5.1.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-gpmc-1.5.0/.github/workflows/ci.yml 
new/yast2-gpmc-1.5.1/.github/workflows/ci.yml
--- old/yast2-gpmc-1.5.0/.github/workflows/ci.yml       1970-01-01 
01:00:00.000000000 +0100
+++ new/yast2-gpmc-1.5.1/.github/workflows/ci.yml       2021-01-14 
21:41:29.000000000 +0100
@@ -0,0 +1,38 @@
+
+# See 
https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions
+
+name: CI
+
+on: [push, pull_request]
+
+jobs:
+
+  Package:
+    runs-on: ubuntu-latest
+    container: registry.opensuse.org/yast/head/containers/yast-ruby:latest
+
+    steps:
+
+    - name: Git Checkout
+      uses: actions/checkout@v2
+
+    - name: Package Build
+      run: yast-ci-ruby -o package
+
+  # downloading the Docker image takes some time so bundling several fast
+  # checks into one job avoids that overhead
+  Checks:
+    runs-on: ubuntu-latest
+    container: registry.opensuse.org/yast/head/containers/yast-ruby:latest
+
+    steps:
+
+    - name: Git Checkout
+      uses: actions/checkout@v2
+
+    - name: Perl Syntax
+      run: yast-ci-ruby -o perl_syntax
+
+    - name: POT Check
+      run: rake check:pot
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-gpmc-1.5.0/.travis.yml 
new/yast2-gpmc-1.5.1/.travis.yml
--- old/yast2-gpmc-1.5.0/.travis.yml    2019-09-27 23:28:34.000000000 +0200
+++ new/yast2-gpmc-1.5.1/.travis.yml    1970-01-01 01:00:00.000000000 +0100
@@ -1,11 +0,0 @@
-sudo: required
-language: bash
-services:
-  - docker
-
-before_install:
-  - docker build -t yast2-gpmc-image .
-script:
-  # the "yast-travis-cpp" script is included in the base yastdevel/cpp image
-  # see https://github.com/yast/docker-yast-cpp/blob/master/yast-travis-cpp
-  - docker run -it -e TRAVIS=1 -e TRAVIS_JOB_ID="$TRAVIS_JOB_ID" 
yast2-gpmc-image yast-travis-cpp
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-gpmc-1.5.0/Dockerfile 
new/yast2-gpmc-1.5.1/Dockerfile
--- old/yast2-gpmc-1.5.0/Dockerfile     2019-09-27 23:28:34.000000000 +0200
+++ new/yast2-gpmc-1.5.1/Dockerfile     1970-01-01 01:00:00.000000000 +0100
@@ -1,2 +0,0 @@
-FROM yastdevel/cpp
-COPY . /usr/src/app
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-gpmc-1.5.0/README.md 
new/yast2-gpmc-1.5.1/README.md
--- old/yast2-gpmc-1.5.0/README.md      1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-gpmc-1.5.1/README.md      2021-01-14 21:41:29.000000000 +0100
@@ -0,0 +1,6 @@
+# YaST - The Group Policy Management Console Module #
+
+[![Workflow 
Status](https://github.com/yast/yast2-gpmc/workflows/CI/badge.svg?branch=master)](
+https://github.com/yast/yast2-gpmc/actions?query=branch%3Amaster)
+[![Jenkins 
Status](https://ci.opensuse.org/buildStatus/icon?job=yast-yast2-gpmc-master)](
+https://ci.opensuse.org/view/Yast/job/yast-yast2-gpmc-master/)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-gpmc-1.5.0/package/yast2-gpmc.changes 
new/yast2-gpmc-1.5.1/package/yast2-gpmc.changes
--- old/yast2-gpmc-1.5.0/package/yast2-gpmc.changes     2019-09-27 
23:28:34.000000000 +0200
+++ new/yast2-gpmc-1.5.1/package/yast2-gpmc.changes     2021-01-14 
21:41:29.000000000 +0100
@@ -1,4 +1,11 @@
 -------------------------------------------------------------------
+Wed Jan 13 16:46:07 UTC 2021 - dmul...@suse.com
+
+- Fix unable to parse samba admx templates; (bsc#1180896);
+- Removing ad-dc dependency breaks gpmc; (jsc#ECO-2527);
+- 1.5.1
+
+-------------------------------------------------------------------
 Fri Sep 27 21:18:31 UTC 2019 - dmul...@suse.com
 
 - Create a stub smb.conf for s3_lp if no smb.conf exists.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-gpmc-1.5.0/package/yast2-gpmc.spec 
new/yast2-gpmc-1.5.1/package/yast2-gpmc.spec
--- old/yast2-gpmc-1.5.0/package/yast2-gpmc.spec        2019-09-27 
23:28:34.000000000 +0200
+++ new/yast2-gpmc-1.5.1/package/yast2-gpmc.spec        2021-01-14 
21:41:29.000000000 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           yast2-gpmc
-Version:        1.5.0
+Version:        1.5.1
 Release:        0
 Summary:        Group Policy Management Console for YaST
 License:        GPL-3.0-only
@@ -41,6 +41,7 @@
 Requires:       yast2
 Requires:       yast2-python3-bindings >= 4.0.0
 Requires:       yast2-adcommon-python >= 1.0
+Requires:       samba-ad-dc
 
 Provides:       yast-gpmc = %{version}
 Obsoletes:      yast-gpmc < %{version}
@@ -66,5 +67,6 @@
 %{yast_desktopdir}
 %{yast_metainfodir}
 %license COPYING
+%doc %{yast_docdir}
 
 %changelog
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-gpmc-1.5.0/src/include/gpmc/complex.py 
new/yast2-gpmc-1.5.1/src/include/gpmc/complex.py
--- old/yast2-gpmc-1.5.0/src/include/gpmc/complex.py    2019-09-27 
23:28:34.000000000 +0200
+++ new/yast2-gpmc-1.5.1/src/include/gpmc/complex.py    2021-01-14 
21:41:29.000000000 +0100
@@ -34,6 +34,9 @@
 from samba.netcmd import gpo
 from samba.netcmd import CommandError
 from samba import NTSTATUSError, WERRORError
+from samba.samdb import SamDB
+from samba.auth import system_session
+import ldapurl
 
 def open_bytes(filename):
     if six.PY3:
@@ -534,7 +537,9 @@
         super().__init__()
         self.sambaopts = SambaOptions(lp)
         self.credopts = CredentialsOptions(creds)
-        self.samdb = samdb
+        self.samdb = SamDB(url=ldapurl.LDAPUrl('ldap://%s' % 
lp.get('realm')).initializeUrl(),
+                           session_info=system_session(),
+                           credentials=creds, lp=lp)
         self.outf = StringIO()
 
     def samdb_connect(self):
@@ -556,7 +561,9 @@
         super().__init__()
         self.sambaopts = SambaOptions(lp)
         self.credopts = CredentialsOptions(creds)
-        self.samdb = samdb
+        self.samdb = SamDB(url=ldapurl.LDAPUrl('ldap://%s' % 
lp.get('realm')).initializeUrl(),
+                           session_info=system_session(),
+                           credentials=creds, lp=lp)
         self.outf = StringIO()
 
     def samdb_connect(self):
@@ -575,7 +582,9 @@
         super().__init__()
         self.sambaopts = SambaOptions(lp)
         self.credopts = CredentialsOptions(creds)
-        self.samdb = samdb
+        self.samdb = SamDB(url=ldapurl.LDAPUrl('ldap://%s' % 
lp.get('realm')).initializeUrl(),
+                           session_info=system_session(),
+                           credentials=creds, lp=lp)
         self.outf = StringIO()
 
     def samdb_connect(self):
@@ -594,7 +603,9 @@
         super().__init__()
         self.sambaopts = SambaOptions(lp)
         self.credopts = CredentialsOptions(creds)
-        self.samdb = samdb
+        self.samdb = SamDB(url=ldapurl.LDAPUrl('ldap://%s' % 
lp.get('realm')).initializeUrl(),
+                           session_info=system_session(),
+                           credentials=creds, lp=lp)
         self.outf = StringIO()
 
     def samdb_connect(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-gpmc-1.5.0/src/include/gpmc/defaults.py 
new/yast2-gpmc-1.5.1/src/include/gpmc/defaults.py
--- old/yast2-gpmc-1.5.0/src/include/gpmc/defaults.py   2019-09-27 
23:28:34.000000000 +0200
+++ new/yast2-gpmc-1.5.1/src/include/gpmc/defaults.py   2021-01-14 
21:41:29.000000000 +0100
@@ -34,24 +34,52 @@
     elif val_type == 'CheckBox':
         e.type = 4
         e.data = 1 if val else 0
+
     entries = []
-    for x in conf.entries:
-        if not (strcmp(x.keyname, reg_key) and strcmp(x.valuename, key)):
-            entries.append(x)
-    entries.append(e)
+    if val_type == 'ListBox':
+        for v in val:
+            e = preg.entry()
+            e.keyname = six.b(reg_key)
+            e.valuename = six.b(v)
+            e.type = 1
+            e.data = six.b(v)
+            entries.append(e)
+    else:
+        for x in conf.entries:
+            if not (strcmp(x.keyname, reg_key) and strcmp(x.valuename, key)):
+                entries.append(x)
+        entries.append(e)
+
     conf.num_entries = len(entries)
     conf.entries = entries
 
-def get_admx_value(conf, reg_key, key):
-    for e in conf.entries:
-        if strcmp(e.keyname, reg_key) and strcmp(e.valuename, key):
-            return e.data
+def get_admx_value(conf, val_type, reg_key, key):
+    if val_type == 'ListBox':
+        ret = []
+        for e in conf.entries:
+            if strcmp(e.keyname, reg_key):
+                if e.data.strip():
+                    ret.append(e.data)
+        return ret
+    else:
+        for e in conf.entries:
+            if strcmp(e.keyname, reg_key) and strcmp(e.valuename, key):
+                return e.data
     return None
 
-def get_admx_configured(conf, reg_key, key):
-    for e in conf.entries:
-        if strcmp(e.keyname, reg_key) and strcmp(e.valuename, key):
+def get_admx_configured(conf, val_type, reg_key, key):
+    if val_type == 'ListBox':
+        ret = []
+        for e in conf.entries:
+            if strcmp(e.keyname, reg_key):
+                if e.data.strip():
+                    ret.append(e.data)
+        if len(ret) > 0:
             return True
+    else:
+        for e in conf.entries:
+            if strcmp(e.keyname, reg_key) and strcmp(e.valuename, key):
+                return True
     return False
 
 def select_script(title, policy, conn):
@@ -172,7 +200,7 @@
 Policies = {
     'comp_passwd' : {
         'file' : '\\MACHINE\\Microsoft\\Windows NT\\SecEdit\\GptTmpl.inf',
-        'opts' : (lambda inf_conf : {
+        'opts' : (lambda inf_conf, label : {
             'MinimumPasswordAge' : {
                 'values' : Policies['comp_passwd']['values'](
                     inf_conf, 'MinimumPasswordAge', 'Minimum password age',
@@ -262,7 +290,7 @@
     },
     'comp_lockout' : {
         'file' : '\\MACHINE\\Microsoft\\Windows NT\\SecEdit\\GptTmpl.inf',
-        'opts' : (lambda inf_conf : {
+        'opts' : (lambda inf_conf, label : {
             'LockoutDuration' : {
                 'values' : Policies['comp_lockout']['values'](
                     inf_conf, 'LockoutDuration', 'Account lockout duration',
@@ -322,7 +350,7 @@
     },
     'comp_krb' : {
         'file' : '\\MACHINE\\Microsoft\\Windows NT\\SecEdit\\GptTmpl.inf',
-        'opts' : (lambda inf_conf : {
+        'opts' : (lambda inf_conf, label : {
             'MaxTicketAge' : {
                 'values' : Policies['comp_krb']['values'](
                     inf_conf, 'MaxTicketAge', 'Maximum lifetime for user 
ticket',
@@ -402,7 +430,7 @@
     },
     'comp_env_var' : {
         'file': 
'\\MACHINE\\Preferences\\EnvironmentVariables\\EnvironmentVariables.xml',
-        'opts' : (lambda xml_conf : {
+        'opts' : (lambda xml_conf, label : {
             a.attrib['name']: {
                 'values' : Policies['comp_env_var']['values'](a),
             } for a in xml_conf.findall('EnvironmentVariable')
@@ -471,7 +499,7 @@
     },
     'comp_scripts_startup': {
         'file' : '\\MACHINE\\Scripts\\scripts.ini',
-        'opts' : (lambda inf_conf : {
+        'opts' : (lambda inf_conf, label : {
             option : {
                 'values' : 
Policies['comp_scripts_startup']['values'](inf_conf, option),
             } for option in iter_scripts_conf(inf_conf, 'Startup')
@@ -508,7 +536,7 @@
     },
     'comp_scripts_shutdown': {
         'file' : '\\MACHINE\\Scripts\\scripts.ini',
-        'opts' : (lambda inf_conf : {
+        'opts' : (lambda inf_conf, label : {
             option : {
                 'values' : 
Policies['comp_scripts_shutdown']['values'](inf_conf, option),
             } for option in iter_scripts_conf(inf_conf, 'Shutdown')
@@ -545,7 +573,7 @@
     },
     'comp_software_install': {
         'file' : 'CN=Packages,CN=Class Store,CN=Machine,%s',
-        'opts' : (lambda ldap_conf : {
+        'opts' : (lambda ldap_conf, label : {
             option : {
                 'values' : 
Policies['comp_software_install']['values'](ldap_conf, option)
             } for option in ldap_conf.keys()
@@ -593,7 +621,7 @@
     },
     'user_internet_maint_conn' : {
         'file': '\\USER\\MICROSOFT\\IEAK\\install.ins',
-        'opts' : (lambda ins_conf : {
+        'opts' : (lambda ins_conf, label : {
             'Proxy Settings' : {
                 'values' : {
                     'Name' : {
@@ -834,7 +862,7 @@
     },
     'user_internet_maint_urls' : {
         'file': '\\USER\\MICROSOFT\\IEAK\\install.ins',
-        'opts' : (lambda ins_conf : {
+        'opts' : (lambda ins_conf, label : {
             'Important URLs' : {
                 'values' : {
                     'Name' : {
@@ -902,7 +930,7 @@
     },
     'user_internet_maint_links' : {
         'file': '\\USER\\MICROSOFT\\IEAK\\install.ins',
-        'opts' : (lambda ins_conf : {
+        'opts' : (lambda ins_conf, label : {
 # need to handle these in a sub folder, and not like the others, since you can 
add multiple url links
             option : {
                 'values' : 
Policies['user_internet_maint_links']['values'](ins_conf, option),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-gpmc-1.5.0/src/include/gpmc/dialogs.py 
new/yast2-gpmc-1.5.1/src/include/gpmc/dialogs.py
--- old/yast2-gpmc-1.5.0/src/include/gpmc/dialogs.py    2019-09-27 
23:28:34.000000000 +0200
+++ new/yast2-gpmc-1.5.1/src/include/gpmc/dialogs.py    2021-01-14 
21:41:29.000000000 +0100
@@ -61,16 +61,19 @@
                     conf = Policies[policy]['new']()
                 if str(ret) == 'policy_table':
                     selection = UI.QueryWidget(str(ret), 'CurrentItem')
-                    values = 
Policies[policy]['opts'](conf)[selection]['values']
+                    values = Policies[policy]['opts'](conf, 
policy)[selection]['values']
                 elif str(ret) == 'add_policy':
                     values = Policies[policy]['add'](conf)
                 UI.SetApplicationTitle('%s Properties' % selection)
                 UI.OpenDialog(self.__change_setting(values))
+                list_results = None
                 while True:
                     subret = UI.UserInput()
                     if str(subret) == 'ok_change_setting' or str(subret) == 
'apply_change_setting':
                         for k in values.keys():
-                            if 'configurable' in values[k]['input'] and 
values[k]['input']['configurable']:
+                            if list_results:
+                                value = list_results
+                            elif 'configurable' in values[k]['input'] and 
values[k]['input']['configurable']:
                                 configured = UI.QueryWidget('configured_%s' % 
k, 'Value')
                                 if configured or configured == None:
                                     value = UI.QueryWidget('entry_%s' % k, 
'Value')
@@ -95,6 +98,8 @@
                         for k in others.keys():
                             UI.ReplaceWidget('text_entry_%s' % k, 
self.__button_entry(k, values, others[k]))
                         continue
+                    elif str(subret) == 'show':
+                        list_results = self.__change_list(values)
                     if str(subret) == 'cancel_change_setting' or str(subret) 
== 'ok_change_setting':
                         UI.CloseDialog()
                         UI.SetApplicationTitle('Group Policy Management 
Editor')
@@ -107,6 +112,73 @@
 
         return Symbol(ret)
 
+    def __change_list(self, values):
+        head = values['value']['input']['options']['present'] if 
values['value']['input']['options'] and 'present' in 
values['value']['input']['options'] else ''
+        vals = values['value']['get']
+        items = []
+        for i in range(0, len(vals)):
+            items.append(Item(Id(i), vals[i]))
+        dialog = MinHeight(20, MinWidth(50, HBox(HSpacing(), VBox(
+            VSpacing(),
+            Table(Id('values_table'), Opt('notify'), Header(head), items),
+            VSpacing(),
+            Right(HBox(
+                PushButton(Id('ok_list_item'), 'OK'),
+                PushButton(Id('cancel_list_item'), 'Cancel'),
+                PushButton(Id('add_list_item'), 'Add...'),
+                PushButton(Id('remove_list_item'), 'Remove'),
+            )),
+            VSpacing(),
+        ), HSpacing() )))
+        UI.OpenDialog(dialog)
+        while True:
+            subret = UI.UserInput()
+            if str(subret) == 'cancel_list_item':
+                UI.CloseDialog()
+                return None
+            elif str(subret) == 'add_list_item':
+                item = self.__add_item()
+                vals = UI.QueryWidget('values_table', 'Items')
+                items = []
+                for i in range(0, len(vals)):
+                    items.append(Item(Id(i), vals[i][1]))
+                items.append(Item(Id(i+1), item))
+                UI.ChangeWidget('values_table', 'Items', items)
+            elif str(subret) == 'remove_list_item':
+                highlighted = UI.QueryWidget('values_table', 'CurrentItem')
+                vals = UI.QueryWidget('values_table', 'Items')
+                items = [Item(Id(i[0][0]), i[1]) for i in vals if i[0][0] != 
highlighted]
+                UI.ChangeWidget('values_table', 'Items', items)
+            elif str(subret) == 'ok_list_item':
+                out = UI.QueryWidget('values_table', 'Items')
+                UI.CloseDialog()
+                return [i[1] for i in out]
+
+    def __add_item(self):
+        dialog = HBox(
+            HSpacing(),
+            VBox(
+                Label('Enter the item to be added:'),
+                TextEntry(Id('add_item'), Opt('hstretch'), ''),
+            ),
+            HSpacing(),
+            VBox(
+                PushButton(Id('ok_add_item'), 'OK'),
+                PushButton(Id('cancel_add_item'), 'Cancel'),
+            ),
+            HSpacing(),
+        )
+        UI.OpenDialog(dialog)
+        while True:
+            subret = UI.UserInput()
+            if str(subret) == 'cancel_add_item':
+                UI.CloseDialog()
+                return None
+            elif str(subret) == 'ok_add_item':
+                ret = UI.QueryWidget('add_item', 'Value')
+                UI.CloseDialog()
+                return ret
+
     def __button_entry(self, k, values, value):
         return TextEntry(Id('entry_%s' % k), Opt('hstretch'), 
values[k]['title'], value)
 
@@ -126,6 +198,7 @@
             k = value[0]
             if not value[-1]['input']:
                 continue
+            summary = value[-1]['input']['options']['present'] if 
value[-1]['input']['options'] and 'present' in value[-1]['input']['options'] 
else ''
             if strcmp(value[-1]['input']['type'], 'TextEntry'):
                 configurable = Empty()
                 configured = value[-1]['get'] != None
@@ -166,23 +239,36 @@
                 items.append(Top(MinWidth(30, Left(
                     ReplacePoint(Id('int_field_%s' % k), VBox(
                         configurable,
+                        Label(summary),
                         IntField(Id('entry_%s' % k), Opt('hstretch'), 
value[-1]['title'], 0, 999999999, value[-1]['get'] if value[-1]['get'] else 0)
                     ))
                 ))))
             elif strcmp(value[-1]['input']['type'], 'CheckBox'):
                 if 'configurable' in value[-1]['input'] and 
value[-1]['input']['configurable']:
                     disp = value[-1]['valstr'](value[-1]['get'])
-                    items.append(Top(Left(
+                    items.append(Top(Left(VBox(
+                        Label(summary),
                         ReplacePoint(Id('check_box_%s' % k), 
RadioButtonGroup(Id('entry_%s' % k), VBox(
                             Left(RadioButton(Id(None), 'Not Configured', 
strcmp(disp, 'Not configured'))),
                             Left(RadioButton(Id(True), 'Enabled', strcmp(disp, 
'Enabled'))),
                             Left(RadioButton(Id(False), 'Disabled', 
strcmp(disp, 'Disabled')))
                         )))
-                    )))
+                    ))))
                 else:
                     items.append(Top(Left(
                         ReplacePoint(Id('check_box_%s' % k), 
CheckBox(Id('entry_%s' % k), Opt('hstretch'), value[-1]['title'], 
bool(value[-1]['get']) if value[-1]['get'] else False))
                     )))
+            elif strcmp(value[-1]['input']['type'], 'ListBox'):
+                disp = value[-1]['valstr'](value[-1]['get'])
+                items.append(Top(Left(VBox(
+                    Label(summary),
+                    ReplacePoint(Id('list_box_%s' % k), 
RadioButtonGroup(Id('entry_%s' % k), VBox(
+                        Left(RadioButton(Id(None), 'Not Configured', 
strcmp(disp, 'Not configured'))),
+                        Left(RadioButton(Id(True), 'Enabled', strcmp(disp, 
'Enabled'))),
+                        Left(RadioButton(Id(False), 'Disabled', strcmp(disp, 
'Disabled'))),
+                        Left(PushButton(Id('show'), 'Show...'))
+                    )))
+                ))))
         if reverse:
             items.reverse()
         items = tuple(items)
@@ -216,7 +302,7 @@
         conf = self.conn.parse(terms['file'])
         if conf is None:
             conf = terms['new']()
-        opts = terms['opts'](conf)
+        opts = terms['opts'](conf, label)
         header = tuple(terms['header']())
         header = Header(*header)
         for key in opts:
@@ -281,7 +367,11 @@
                 for category in categories:
                     disp = fetch_attr(category, 'displayName', strings, 
presentations)
                     my_ref = category.attrib['name']
-                    par_ref = category.find('parentCategory').attrib['ref']
+                    par = category.find('parentCategory')
+                    if par is None:
+                        par_ref = ''
+                    else:
+                        par_ref = par.attrib['ref']
 
                     if my_ref not in items.keys():
                         items[my_ref] = {}
@@ -323,14 +413,18 @@
                                 'value' : {
                                     'order' : 1,
                                     'title' : key,
-                                    'get' : get_admx_value(conf, reg_key, key),
+                                    'get' : get_admx_value(conf, val_type, 
reg_key, key),
                                     'set' : (lambda v : set_admx_value(conf, 
reg_key, key, v, val_type)),
-                                    'valstr' : (lambda v : valstr(v) if 
get_admx_configured(conf, reg_key, key) else 'Not configured'),
+                                    'valstr' : (lambda v : valstr(v) if 
get_admx_configured(conf, val_type, reg_key, key) else 'Not configured'),
                                     'input' : _input,
                                 },
                             } )
 
-                    def policy_generator(conf):
+                    def policy_generator(conf, parent):
+                        def fetch_presentation(pid, typ):
+                            pres = presentations.find('presentation[@id="%s"]' 
% pid)
+                            if pres:
+                                return pres.find(typ).text
                         values = {}
                         for policy in policies:
                             if policy.find('parentCategory').attrib['ref'] != 
parent:
@@ -340,7 +434,10 @@
                             values[disp] = {}
                             val_type = None
                             elements = policy.find('elements')
-                            defined = get_admx_configured(conf, 
policy.attrib['key'], disp)
+                            reg_key = policy.attrib['key']
+                            opts = None
+                            elist = elements.find('list')
+                            pid = policy.attrib['name']
                             if elements.find('text') is not None:
                                 val_type = 'TextEntry'
                                 val_str = (lambda v : v if v else '')
@@ -350,12 +447,20 @@
                             elif elements.find('boolean') is not None:
                                 val_type = 'CheckBox'
                                 val_str = (lambda v : 'Disabled' if int(v) == 
0 else 'Enabled')
+                            elif elist is not None:
+                                val_type = 'ListBox'
+                                val_str = (lambda v : 'Disabled' if len(v) == 
0 else 'Enabled')
+                                reg_key = elist.attrib['key']
+                                opts = {}
+                                opts['present'] = fetch_presentation(pid, 
'listBox')
+                            else:
+                                raise NotImplementedError('Element of \'%s\' 
unknown' % disp)
                             values[disp]['values'] = 
Policies[parent]['values'](
-                                conf, policy.attrib['key'], disp, desc, 
val_str, val_type,
+                                conf, reg_key, disp, desc, val_str, val_type,
                                 {
                                     'type' : val_type,
                                     'configurable' : True,
-                                    'options' : None,
+                                    'options' : opts,
                                 },
                             )
                         return values

Reply via email to