diff --git a/python/mine/ri_cmd.py b/python/mine/ri_cmd.py index 4871481..1e60ef8 100644 --- a/python/mine/ri_cmd.py +++ b/python/mine/ri_cmd.py @@ -8,6 +8,7 @@ import ri_data import re import copy +import sys def quit(): ''' correspond to quit button ''' @@ -153,22 +154,39 @@ def ncm_static(): for n in ('network_domain_name','network_ip','network_subnet_mask','network_gateway','network_primary_dns','network_secondary_dns'): ri_widget.Widget.dict[n].tk_widget.configure(state='normal') +class GroupCheck(object): + ''' A function class called whenever the group checkbox is clicked ''' + dict={} + def __init__(self, n): + self.name = n + GroupCheck.dict[n] = self + + def __call__(self): + print self.name + display.SoftwarePackageWindow.dict[self.name].show() + def software_group_construct(w): ''' draw group information on, based on actual data w - Widget instance ''' + for g in ri_data.Group.dict.values(): + display.SoftwarePackageWindow(g) + mdt = [ m for m in ri_data.Group.dict.values() if m.install == 'mandatory' ] opt = [ o for o in ri_data.Group.dict.values() if o.install != 'mandatory' ] wit = w.widgets.pop() for i in mdt: - print i wi = copy.deepcopy(wit) wi.attr['text'] = i.name vn = "software_group_%s" %(i.name) wi.attr['variable'] = vn wi.variables = [(vn, 'StringVar', ''),] - wi.grid_location.dict['column'] = mdt.index(i) - wi.grid_location.dict['row'] = 0 + idx = mdt.index(i) + wi.grid_location.dict['column'] = idx % int(w.grid_management.columns) + wi.grid_location.dict['row'] = idx / int(w.grid_management.columns) + gc = GroupCheck(i.name) + setattr(sys.modules[__name__], vn, gc) + wi.attr['command'] = vn w.add_sub_widget(wi) def software_group_init(): @@ -179,3 +197,5 @@ def software_group_quit(): def software_group_item(): pass + + diff --git a/python/mine/ri_data.py b/python/mine/ri_data.py index b42880f..4cdeb0b 100644 --- a/python/mine/ri_data.py +++ b/python/mine/ri_data.py @@ -309,7 +309,7 @@ g_node - group node ''' if n.attributes['install'].value == 'mandatory': g.mandatory.append(n.attributes['package'].value.encode('ascii')) else: - g.optional.append(n.attributes['package'].value.encode('ascii'), 'no') + g.optional.append([n.attributes['package'].value.encode('ascii'), 'no']) @staticmethod def init_from_config_xml(node): @@ -338,7 +338,7 @@ g_node - group node ''' g.mandatory.extend([pkg.attributes['name'].value for pkg in grp_chld.childNodes if pkg.nodeType == pkg.ELEMENT_NODE and pkg.nodeName == 'package']) elif grp_chld.nodeName == 'optional': - g.optional.extend([(pkg.attributes['name'].value, pkg.attributes['install'].value) for pkg in grp_chld.childNodes + g.optional.extend([[pkg.attributes['name'].value, pkg.attributes['install'].value] for pkg in grp_chld.childNodes if pkg.nodeType == pkg.ELEMENT_NODE and pkg.nodeName == 'package']) init_from_xml = init_from_install_xml @staticmethod @@ -469,6 +469,16 @@ p_node - xml node (parent node)''' srvs.appendChild(srv) p_node.appendChild(srvs) +def init(): + ''' initialize ''' + Partition.init_from_os() + Raid.init_from_os() + MountPoint.init_from_internal() + xmldoc_cfg = minidom.parse(config_xml) + root_cfg = xmldoc_cfg.firstChild + Group.init_from_config_xml(root_cfg) + Service.init_from_config_xml(root_cfg) + def init_from_xml(): ''' init all classes in this module based input file (install xml) ''' xmldoc = minidom.parse(install_xml) diff --git a/python/mine/ri_tk.py b/python/mine/ri_tk.py index ea0bcd8..7959272 100644 --- a/python/mine/ri_tk.py +++ b/python/mine/ri_tk.py @@ -166,3 +166,115 @@ def destroy_top_window(w): ''' w - Toplevel instance ''' w.tk_widget.destroy() +class SoftwarePackageWindow(): + ''' Toplevel window for a group of software packages ''' + dict = {} + def __init__(self, g): + self.group = g + self.optional = [] + SoftwarePackageWindow.dict[g.name] = self + + def select_all(self): + ''' callback function for check button select_all ''' + self.group.selection = self.selection.get() + print self.group.selection + + def ok(self): + ''' callback function for button OK ''' + self.group.selection = self.selection.get() + for i in range(len(self.group.optional)): + # install field, yes or no + self.group.optional[i][1] = self.optional[i].get() + self.win.destroy() + + def cancel(self): + ''' callback function for button cancel ''' + self.win.destroy() + + def show(self): + win = Tkinter.Toplevel(root_window) + self.win = win + win.geometry("%sx%s+%s+%s" %(int(root_window.winfo_screenwidth()*0.8),\ + int(root_window.winfo_screenheight()*0.8),\ + int(root_window.winfo_screenwidth()*0.1),\ + int(root_window.winfo_screenheight()*0.1))) + win.columnconfigure(0, weight=1) + win.rowconfigure(1, weight=1) + win.rowconfigure(4, weight=1) + Tkinter.Label(win, text='Mandatory').grid(column=0, row=0) + cnv1 = Tkinter.Canvas(win) + hs1 = Tkinter.Scrollbar(win, orient='horizontal') + hs1.configure(command=cnv1.xview) + vs1 = Tkinter.Scrollbar(win, orient='vertical') + vs1.configure(command=cnv1.yview) + cnv1.grid(column=0, row=1, sticky='NWES') + vs1.grid(column=1, row=1, sticky='NSW') + hs1.grid(column=0, row=2, sticky='NWE') + cnv1.configure(yscrollcommand=vs1.set, xscrollcommand=hs1.set) + fr1 = Tkinter.Frame(cnv1) + cnv1.create_window((0,0), window=fr1, anchor='nw') + #column set to 5 + fr1.columnconfigure(0, weight=1) + fr1.columnconfigure(1, weight=1) + fr1.columnconfigure(2, weight=1) + fr1.columnconfigure(3, weight=1) + fr1.columnconfigure(4, weight=1) + + for i in range(len(self.group.mandatory)): + Tkinter.Label(fr1, text=self.group.mandatory[i]).grid(column=i%5, row=i/5, sticky='NWES') + + Tkinter.Label(win, text='Optional').grid(column=0, row=3) + self.selection = Tkinter.StringVar(value="") + chk_sa = Tkinter.Checkbutton(win, text='Select all', command=self.select_all, variable=self.selection, onvalue='all', offvalue='manual') + chk_sa.grid(column=1, row=3) + if self.group.selection == 'all': + chk_sa.select() + else: + chk_sa.deselect() + + cnv2 = Tkinter.Canvas(win) + hs2 = Tkinter.Scrollbar(win, orient='horizontal') + hs2.configure(command=cnv2.xview) + vs2 = Tkinter.Scrollbar(win, orient='vertical') + vs2.configure(command=cnv2.yview) + cnv2.grid(column=0, row=4, sticky='NWES') + vs2.grid(column=1, row=4, sticky='NSW') + hs2.grid(column=0, row=5, sticky='NWE') + cnv2.configure(yscrollcommand=vs2.set, xscrollcommand=hs2.set) + fr2 = Tkinter.Frame(cnv2) + cnv2.create_window((0,0), window=fr2, anchor='nw') + #column set to 5 + fr2.columnconfigure(0, weight=1) + fr2.columnconfigure(1, weight=1) + fr2.columnconfigure(2, weight=1) + fr2.columnconfigure(3, weight=1) + fr2.columnconfigure(4, weight=1) + + for i in range(len(self.group.optional)): + name, y_n = self.group.optional[i] + v = Tkinter.StringVar(value='no') + self.optional.append(v) + chk = Tkinter.Checkbutton(fr2, text=name, onvalue='yes', offvalue='no', variable=self.optional[i]) + chk.grid(column=i%5, row=i/5, sticky='NWES') + if y_n == 'yes': + chk.select() + else: + chk.deselect() + + Tkinter.Button(win, text='OK', command=self.ok).grid(column=0, row=6) + Tkinter.Button(win, text='Cancel', command=self.cancel).grid(column=1, row=6) + + win.after_idle(lambda : cnv1.configure(scrollregion=(0,0, fr1.winfo_width(), fr1.winfo_height()))) + win.after_idle(lambda : cnv2.configure(scrollregion=(0,0, fr2.winfo_width(), fr2.winfo_height()))) + + win.transient(root_window) + # grab all events into it + while True: + try: + win.grab_set() + except Tkinter.TclError: + pass + else: + break + + win.wait_window() diff --git a/python/mine/ri_widget.py b/python/mine/ri_widget.py index 86fd76b..144fc50 100644 --- a/python/mine/ri_widget.py +++ b/python/mine/ri_widget.py @@ -7,6 +7,8 @@ import ri_cmd class GridManagement: ''' implement grid management ''' def __init__(self, xml_node): + self.rows = xml_node.attributes['rows'].value + self.columns = xml_node.attributes['columns'].value self.cf_list=[] for cf in xml_node.childNodes: if cf.nodeType != cf.ELEMENT_NODE or cf.nodeName != "configure": diff --git a/python/mine/test.py b/python/mine/test.py index 136ac8b..ad55cf1 100644 --- a/python/mine/test.py +++ b/python/mine/test.py @@ -36,6 +36,7 @@ else: xmldoc = minidom.parse(itf_xml) ri_data.install_xml = ins_xml ri_data.init_from_xml() +#ri_data.init() ri_widget.construct(xmldoc.firstChild) ri_seq.construct(xmldoc.firstChild) diff --git a/xml/install.xml b/xml/install.xml index abe5a6a..36ad59f 100644 --- a/xml/install.xml +++ b/xml/install.xml @@ -1,40 +1,469 @@ - 0123 - - - - + + + + + + + + + + + - - /dev/hda1 - /dev/hda2 - - - /dev/hda3 - /dev/hda5 - /dev/hda6 + + sda1 + sdb1 - - + + + + + + + - + - - base software packages + + + 开发类包括 C、C++(Fortran)、DDD 等开发工具。 + 开发类软件包分为必选包和可选包,当选择安装该类后,必选包是默认安装的,可选包可以自由选择安装。 + - + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 办公类包括 OpenOffice.org 等办公软件。 + 办公类都是必选软件包,当选择安装该类后,必选包是默认安装的。 + + + + + + + + KDE是一种著名的自由图形工作环境,整个系统采用Qt程序库 + KDE桌面类都是可选软件包,可以自由选择安装。 + + + + + + + + + + + + + + + + + + + + + + + + + + 图形类包括 X11 相关的各种程序。 + 图形类软件包分为必选包和可选包,当选择安装该类后,必选包是默认安装的,可选包可以自由选择安装。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 网络工具类包括 tcpdump 等网络工具。 + 网络工具类都是可选软件包,可以自由选择安装。 + + + + + + + + + + 通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的完整计算机系统 + 虚拟机类都是可选软件包,可以自由选择安装 + + + + + + + + + + 基础类是包括字符界面的最小系统,可以独立运行各种不依靠图形界面的程序, + 除 ssh(d) 外不包括其它网络服务。 + 基础类软件包分为必选包和可选包,必选包是默认安装的,可选包可以自由选择安装。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 网络服务类包括各种网络服务包。 + 网络服务类都是可选软件包,可以自由选择安装。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 因特网类包括万维网浏览器 Firefox 等。 + 因特网类软件包都是必选包,当选择安装该类后,必选包是默认安装的。 + + + + + + + + + + + + + + 多媒体类包括各种媒体库。 + 多媒体类都是可选软件包,可以自由选择安装。 + + + + + + + + + + + + + + + + + - - + + + + diff --git a/xml/interface_ng.xml b/xml/interface_ng.xml index b6daa23..1158a15 100644 --- a/xml/interface_ng.xml +++ b/xml/interface_ng.xml @@ -109,6 +109,12 @@ on special cases --> + + + + + + @@ -216,6 +222,9 @@ on special cases --> + + + diff --git a/xml/interface_t.xml b/xml/interface_t.xml index bfa9920..413fe45 100644 --- a/xml/interface_t.xml +++ b/xml/interface_t.xml @@ -398,7 +398,7 @@ row 4 | | --> - + @@ -411,6 +411,11 @@ row 4 | | + + + + + @@ -497,6 +502,46 @@ row 4 | | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Rocky 4.2 磐石 4.2