root/trunk/umitGUI/OptionBuilder.py @ 765

Revision 765, 11.0 kB (checked in by boltrix, 6 years ago)

Merged the changes sent by Max, and fixed a bug related to his fix. Also, fixed a bug on setup.py which were installing the docs in the wrong place.

Line 
1#!/usr/bin/env python
2# Copyright (C) 2005 Insecure.Com LLC.
3#
4# Author: Adriano Monteiro Marques <py.adriano@gmail.com>
5#
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 2 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program; if not, write to the Free Software
18# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20import gtk
21
22from xml.dom import minidom
23
24from higwidgets.higboxes import HIGHBox
25from higwidgets.higlabels import HIGEntryLabel
26from higwidgets.higbuttons import HIGButton
27
28from umitGUI.FileChoosers import AllFilesFileChooserDialog
29
30from umitCore.NmapOptions import NmapOptions
31from umitCore.I18N import _
32from umitCore.Paths import Path
33
34options = Path.options
35
36
37class OptionTab(object):
38    def __init__(self, root_tab, options, constructor, update_func):
39        actions = {'option_list':self.__parse_option_list,\
40                   'option_check':self.__parse_option_check}
41
42        self.options = options
43        self.constructor = constructor
44        self.update_func = update_func
45        self.widgets_list = []
46
47        options_used = self.constructor.get_options()
48       
49        # Cannot use list comprehhension because text nodes raise exception
50        # when tagName is called
51        for option_element in root_tab.childNodes:
52            try:option_element.tagName
53            except:pass
54            else:
55                if option_element.tagName in actions.keys():
56                    self.widgets_list.append(actions[option_element.tagName](option_element, options_used))
57
58    def __parse_option_list(self, option_list, options_used):
59        options = option_list.getElementsByTagName(u'option')
60       
61        label = HIGEntryLabel(option_list.getAttribute(u'label'))
62        opt_list = OptionList()
63       
64        for opt in options:
65            opt_list.append(self.options.get_option(opt.getAttribute(u'name')))
66       
67        for i, row in enumerate(opt_list.list):
68            if row[0] in options_used:
69                opt_list.set_active(i)
70               
71        return label, opt_list
72   
73    def __parse_option_check(self, option_check, options_used):
74        arg_type = option_check.getAttribute(u'arg_type')
75        option = option_check.getAttribute(u'option')
76        label = option_check.getAttribute(u'label')
77       
78        check = OptionCheck(label, self.options.get_option(option))
79        check.set_active(option in options_used)
80           
81        type_mapping = { 
82            "str": OptionEntry,
83            "int": OptionIntSpin,
84            "float": OptionFloatSpin,
85            "level": OptionLevelSpin, 
86            "path": OptionFile,
87            "interface": OptionInterface
88            }
89
90        additional = None
91        if type_mapping.has_key(arg_type):
92            value = options_used.get(option, None)
93            if value:
94                additional = type_mapping[arg_type](value)
95            else:
96                additional = type_mapping[arg_type]()
97
98        check.connect('toggled', self.update_check, additional)
99       
100        return check, additional
101
102    def fill_table(self, table, expand_fill = True):
103        yopt = (0, gtk.EXPAND | gtk.FILL)[expand_fill]
104        for y, widget in enumerate(self.widgets_list):
105            if widget[1] == None:
106                table.attach(widget[0], 0, 2, y, y+1, yoptions=yopt)
107            else:
108                table.attach(widget[0], 0, 1, y, y+1, yoptions=yopt)
109                table.attach(widget[1], 1, 2, y, y+1, yoptions=yopt)
110
111        for widget in self.widgets_list:
112            te = type(widget[1])
113            if te == type(OptionList()):
114                widget[1].connect('changed',self.update_list_option)
115            elif te == type(OptionIntSpin()) or\
116                 te == type(OptionFloatSpin()) or\
117                 te == type(OptionEntry()):
118                widget[1].connect('changed', self.update_entry, widget[0])
119            elif te == type(OptionLevelSpin()):
120                widget[1].connect('changed', self.update_level, widget[0])
121            elif te == type(OptionFile()):
122                widget[1].entry.connect('changed', self.update_entry, widget[0])
123            elif te == type(OptionInterface()):
124                widget[1].child.connect('changed', self.update_entry, widget[0])
125           
126    def update_check(self, check, extra):
127        if check.get_active():
128            te = type(extra)
129            if te == type(OptionEntry()) or\
130               te == type(OptionIntSpin()) or\
131               te == type(OptionFloatSpin()):
132                self.update_entry(extra, check)
133            elif te == type(OptionLevelSpin()):
134                self.update_level(extra, check)
135            elif te == type(OptionFile()):
136                self.update_entry(extra.entry, check)
137            elif te == type(OptionInterface()):
138                self.update_entry(extra.child, check)
139            else:
140                self.constructor.add_option(check.option['name'])
141        else:
142            self.constructor.remove_option(check.option['name'])
143
144        self.update_command()
145       
146    def update_entry(self, widget, check):
147        if not check.get_active():
148            check.set_active(True)
149
150        self.constructor.remove_option(check.option['name'])
151        self.constructor.add_option(check.option['name'], widget.get_text())
152       
153        self.update_command()
154   
155    def update_level(self, widget, check):
156        if not check.get_active():
157            check.set_active(True)
158       
159        try:
160            self.constructor.remove_option(check.option['name'])
161            if int(widget.get_text()) == 0:
162                check.set_active(False)
163            else:
164                self.constructor.add_option(check.option['name'],\
165                                        level=int(widget.get_text()))
166        except:pass
167       
168        self.update_command()
169
170    def update_list_option(self, widget):
171        try:widget.last_selected
172        except:pass
173        else:
174            self.constructor.remove_option(widget.last_selected)
175       
176        option_name = widget.options[widget.get_active()]['name']
177     
178        self.constructor.add_option(option_name)
179        widget.last_selected = option_name
180       
181        self.update_command()
182
183    def update_command(self):
184        if self.update_func:
185            self.update_func()
186   
187                 
188class OptionBuilder(object):
189    def __init__(self, xml_file, constructor, update_func):
190        """ OptionBuilder(xml_file, constructor)
191
192        xml_file is a UI description xml-file
193        constructor is a CommandConstructor instance
194        """
195        xml_desc = open(xml_file)
196        self.xml = minidom.parse(xml_desc)
197        # Closing file to avoid problems with file descriptors
198        xml_desc.close()
199
200        self.constructor = constructor
201        self.update_func = update_func
202       
203        self.root_tag = "interface"
204       
205        self.xml = self.xml.getElementsByTagName(self.root_tag)[0]
206        self.options = NmapOptions(options)
207       
208        self.groups = self.__parse_groups()
209        self.section_names = self.__parse_section_names()
210        self.tabs = self.__parse_tabs()
211   
212    def __parse_section_names(self):
213        dic = {}
214        for group in self.groups:
215            grp = self.xml.getElementsByTagName(group)[0]
216            dic[group] = grp.getAttribute(u'label')
217        return dic
218   
219    def __parse_groups(self):
220        return [g_name.getAttribute(u'name') for g_name in \
221                  self.xml.getElementsByTagName(u'groups')[0].\
222                  getElementsByTagName(u'group')]
223
224    def __parse_tabs(self):
225        dic = {}
226        for tab_name in self.groups:
227            dic[tab_name] = OptionTab(self.xml.getElementsByTagName(tab_name)[0],
228                                      self.options, self.constructor, self.update_func)
229        return dic
230
231   
232class OptionWidget:
233    def enable_widget(self):
234        self.set_sensitive(True)
235   
236    def disable_widget(self):
237        self.set_sensitive(False)
238
239class OptionInterface(gtk.ComboBoxEntry, OptionWidget):
240    def __init__(self):
241        self.list = gtk.ListStore(str)
242        gtk.ComboBoxEntry.__init__(self, self.list)
243       
244        cell = gtk.CellRendererText()
245        self.pack_start(cell, True)
246        self.add_attribute(cell, 'text', 0)
247
248class OptionList(gtk.ComboBox, OptionWidget):
249    def __init__(self):
250        self.list = gtk.ListStore(str)
251        gtk.ComboBox.__init__(self, self.list)
252       
253        cell = gtk.CellRendererText()
254        self.pack_start(cell, True)
255        self.add_attribute(cell, 'text', 0)
256       
257        self.options = []
258   
259    def append(self, option):
260        self.list.append([option[u'name']])
261        self.options.append(option)
262
263class OptionCheck(gtk.CheckButton, OptionWidget):
264    def __init__(self, label=None, option=None):
265        gtk.CheckButton.__init__(self, label)
266       
267        self.option = option
268   
269    def get_option(self):
270        return self.option
271
272
273class OptionEntry(gtk.Entry, OptionWidget):
274    def __init__(self, param = ""):
275        gtk.Entry.__init__(self)
276        self.set_text(param)
277
278class OptionLevelSpin(gtk.SpinButton, OptionWidget):
279    def __init__(self, initial=0):
280        gtk.SpinButton.__init__(self,gtk.Adjustment(int(initial),0,10,1),0.0,0)
281
282class OptionIntSpin(gtk.SpinButton, OptionWidget):
283    def __init__(self, initial=1):
284        gtk.SpinButton.__init__(self,gtk.Adjustment(int(initial),0,10**100,1),0.0,0)
285
286class OptionFloatSpin(gtk.SpinButton, OptionWidget):
287    def __init__(self, initial=1):
288        gtk.SpinButton.__init__(self,gtk.Adjustment(float(initial),0,10**100,1),0.1,2)
289
290class OptionFile(HIGHBox, OptionWidget, object):
291    def __init__(self, param=""):
292        HIGHBox.__init__(self)
293       
294        self.entry = OptionEntry()
295        self.button = HIGButton(stock=gtk.STOCK_OPEN)
296       
297        self._pack_expand_fill(self.entry)
298        self._pack_noexpand_nofill(self.button)
299
300        self.entry.set_text(param)
301        self.button.connect('clicked', self.open_dialog_cb)
302   
303    def open_dialog_cb(self, widget):
304        dialog = AllFilesFileChooserDialog(_("Choose file"))
305        if dialog.run() == gtk.RESPONSE_OK:
306            self.entry.set_text(dialog.get_filename())
307        dialog.destroy()
308
309    def get_filename(self):
310        return "\ ".join(self.entry.get_text().split(" "))
311
312    def set_filename(self, filename):
313        self.entry.set_text(" ".join(filename.split("\ ")))
314
315    filename = property(get_filename, set_filename)
316
317if __name__ == '__main__':
318    o = OptionBuilder('profile_editor.xml')
319   
320    ol = OptionFile()
321    w = gtk.Window()
322    w.add(ol)
323    w.show_all()
324    w.connect('delete-event', lambda x,y,z=None: gtk.main_quit())
325    gtk.main()
Note: See TracBrowser for help on using the browser.