root/branch/NetworkInventory/umit/gui/OptionBuilder.py @ 4252

Revision 4252, 15.6 kB (checked in by gpolo, 4 years ago)

Merged revisions 4240-4248 via svnmerge from
http://svn.umitproject.org/svnroot/umit/trunk

........

r4240 | gpolo | 2009-03-02 13:15:33 -0300 (Mon, 02 Mar 2009) | 1 line


Restructuring umit, second step. See ticket #229.

........

r4241 | gpolo | 2009-03-02 13:19:09 -0300 (Mon, 02 Mar 2009) | 1 line


Removing old directories

........

r4242 | gpolo | 2009-03-02 13:19:42 -0300 (Mon, 02 Mar 2009) | 1 line


Removed umitInterfaceEditor now

........

r4243 | gpolo | 2009-03-02 13:21:20 -0300 (Mon, 02 Mar 2009) | 1 line


Fixed some remaining old umitCore imports

........

r4244 | gpolo | 2009-03-02 15:26:14 -0300 (Mon, 02 Mar 2009) | 1 line


Renamed UMIT_CONFIG_DIR to UMIT_CFG_DIR so the unix installer doesn't replace its content when installing umit.

........

r4245 | gpolo | 2009-03-02 15:50:36 -0300 (Mon, 02 Mar 2009) | 1 line


Adjusted installers for the new structure. This concludes ticket #229.

........

r4246 | gpolo | 2009-03-02 15:59:02 -0300 (Mon, 02 Mar 2009) | 1 line


Removed unused shell scripts.

........

r4247 | gpolo | 2009-03-02 16:03:54 -0300 (Mon, 02 Mar 2009) | 1 line


Updated version_update.py and ran it.

........

r4248 | gpolo | 2009-03-02 16:06:01 -0300 (Mon, 02 Mar 2009) | 1 line


test_paths.sh has been abandoned too, gone now.

........

Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3#
4# Copyright (C) 2005-2006 Insecure.Com LLC.
5# Copyright (C) 2007-2008 Adriano Monteiro Marques
6#
7# Author: Adriano Monteiro Marques <adriano@umitproject.org>
8#
9# This program is free software; you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation; either version 2 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program; if not, write to the Free Software
21# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22
23import gtk
24
25from xml.dom import minidom
26
27from higwidgets.higboxes import HIGHBox
28from higwidgets.higlabels import HIGEntryLabel
29from higwidgets.higbuttons import HIGButton
30
31from umit.gui.ScriptManager import ScriptChooserDialog #MAX
32from umit.gui.FileChoosers import AllFilesFileChooserDialog
33
34#from umit.core.UmitConf import is_maemo
35
36from umit.core.NmapOptions import NmapOptions
37from umit.core.I18N import _
38from umit.core.OptionsConf import options_file
39import os, sys
40
41## Integration
42#class OptionTab(object):
43    #def __init__(self, root_tab, options, constructor, update_func):
44        #actions = {'option_list':self.__parse_option_list,\
45                   #'option_check':self.__parse_option_check}
46
47#<<<<<<< .working
48class OptionTab(object):
49    def __init__(self, root_tab, options, constructor, update_func):
50        actions = {'option_list':self.__parse_option_list,\
51                   'option_check':self.__parse_option_check}
52
53        self.options = options
54        self.constructor = constructor
55        self.update_func = update_func
56        self.widgets_list = []
57
58        options_used = self.constructor.get_options()
59       
60        # Cannot use list comprehhension because text nodes raise exception
61        # when tagName is called
62        for option_element in root_tab.childNodes:
63            try:option_element.tagName
64            except:pass
65            else:
66                if option_element.tagName in actions.keys():
67                    self.widgets_list.append(actions[option_element.tagName](option_element, options_used))
68
69    def __parse_option_list(self, option_list, options_used):
70        options = option_list.getElementsByTagName(u'option')
71       
72        label = HIGEntryLabel(option_list.getAttribute(u'label'))
73        opt_list = OptionList()
74       
75        for opt in options:
76            opt_list.append(self.options.get_option(opt.getAttribute(u'name')))
77       
78        for i, row in enumerate(opt_list.list):
79            if row[0] in options_used:
80                opt_list.set_active(i)
81               
82        return label, opt_list
83   
84    def is_root(self):
85        """
86        Returns if is a root users
87        """
88       
89        root = False
90        try:
91            if sys.platform == 'win32': root = True
92            elif os.getuid() == 0: root = True
93        except: pass
94        return root
95   
96    def _disable_option(self, need_root):
97        """
98        enable / disable option if non-root user.
99        """
100        is_root = self.is_root()
101
102        return not is_root and need_root
103   
104   
105    def __with_icon(self, hint):
106        """
107        Return true or false: if is a option with icon or without.
108        """
109        return hint!=""
110   
111    def __parse_option_check(self, option_check, options_used):
112        #arg_type = option_check.getAttribute(u'arg_type')
113       
114        option = option_check.getAttribute(u'option')
115        arg_type = self.options.get_arg_type(option)
116        label = option_check.getAttribute(u'label')
117        opt_parse = self.options.get_option(option)
118        opt_hint = self.options.get_hint(option)
119        need_root = self.options.get_need_root(option)
120        with_icon = self.__with_icon(opt_hint)
121        if with_icon:
122            check = OptionCheckIcon(label, opt_parse, opt_hint )
123
124        else:
125            check = OptionCheck(label, opt_parse)
126        check.set_active(option in options_used) 
127        if self._disable_option(need_root):
128            check.disable_widget()
129        type_mapping = { 
130            "str": OptionEntry,
131            "int": OptionIntSpin,
132            "float": OptionFloatSpin,
133            "level": OptionLevelSpin, 
134            "path": OptionFile,
135            "interface": OptionInterface, 
136            "scriptlist": OptionScriptList
137            }
138
139        additional = None
140        if type_mapping.has_key(arg_type):
141            value = options_used.get(option, None)
142            if value:
143                additional = type_mapping[arg_type](value)
144            else:
145                additional = type_mapping[arg_type]()
146        check.connect('toggled', self.update_check, additional)
147
148        return check, additional
149
150    def fill_table(self, table, expand_fill = True):
151        yopt = (0, gtk.EXPAND | gtk.FILL)[expand_fill]
152        for y, widget in enumerate(self.widgets_list):
153            if widget[1] == None:
154                table.attach(widget[0], 0, 2, y, y+1, yoptions=yopt)
155            else:
156                table.attach(widget[0], 0, 1, y, y+1, yoptions=yopt)
157                table.attach(widget[1], 1, 2, y, y+1, yoptions=yopt)
158
159        for widget in self.widgets_list:
160            te = type(widget[1])
161            if te == type(OptionList()):
162                widget[1].connect('changed',self.update_list_option)
163            elif te == type(OptionIntSpin()) or\
164                 te == type(OptionFloatSpin()) or\
165                 te == type(OptionEntry()):
166                widget[1].connect('changed', self.update_entry, widget[0])
167            elif te == type(OptionLevelSpin()):
168                widget[1].connect('changed', self.update_level, widget[0])
169            elif te == type(OptionFile()):
170                widget[1].entry.connect('changed', self.update_entry, widget[0])
171            elif te == type(OptionInterface()):
172                widget[1].child.connect('changed', self.update_entry, widget[0])
173           
174    def update_check(self, check, extra):
175        if check.get_active():
176            te = type(extra)
177            if te == type(OptionEntry()) or\
178               te == type(OptionIntSpin()) or\
179               te == type(OptionFloatSpin()):
180                self.update_entry(extra, check)
181            elif te == type(OptionLevelSpin()):
182                self.update_level(extra, check)
183            elif te == type(OptionFile()):
184                self.update_entry(extra.entry, check)
185            elif te == type(OptionInterface()):
186                self.update_entry(extra.child, check)
187            else:
188                self.constructor.add_option(check.option['name'])
189        else:
190            self.constructor.remove_option(check.option['name'])
191
192        self.update_command()
193       
194    def update_entry(self, widget, check):
195        if not check.get_active():
196            check.set_active(True)
197
198        self.constructor.remove_option(check.option['name'])
199        self.constructor.add_option(check.option['name'], widget.get_text())
200       
201        self.update_command()
202   
203    def update_level(self, widget, check):
204        if not check.get_active():
205            check.set_active(True)
206       
207        try:
208            self.constructor.remove_option(check.option['name'])
209            if int(widget.get_text()) == 0:
210                check.set_active(False)
211            else:
212                self.constructor.add_option(check.option['name'],\
213                                        level=int(widget.get_text()))
214        except:pass
215       
216        self.update_command()
217
218    def update_list_option(self, widget):
219        try:widget.last_selected
220        except:pass
221        else:
222            self.constructor.remove_option(widget.last_selected)
223       
224        option_name = widget.options[widget.get_active()]['name']
225     
226        self.constructor.add_option(option_name)
227        widget.last_selected = option_name
228       
229        self.update_command()
230
231    def update_command(self):
232        if self.update_func:
233            self.update_func()
234   
235                 
236class OptionBuilder(object):
237    def __init__(self, xml_file, constructor, update_func):
238        """ OptionBuilder(xml_file, constructor)
239
240        xml_file is a UI description xml-file
241        constructor is a CommandConstructor instance
242        """
243        xml_desc = open(xml_file)
244        self.xml = minidom.parse(xml_desc)
245        # Closing file to avoid problems with file descriptors
246        xml_desc.close()
247
248        self.constructor = constructor
249        self.update_func = update_func
250       
251        self.root_tag = "interface"
252       
253        self.xml = self.xml.getElementsByTagName(self.root_tag)[0]
254        self.options = NmapOptions(options_file)
255       
256        self.groups = self.__parse_groups()
257        self.section_names = self.__parse_section_names()
258        self.tabs = self.__parse_tabs()
259   
260
261    def __parse_section_names(self):
262        dic = {}
263        for group in self.groups:
264            grp = self.xml.getElementsByTagName(group)[0]
265            dic[group] = grp.getAttribute(u'label')
266        return dic
267   
268    def __parse_groups(self):
269        return [g_name.getAttribute(u'name') for g_name in \
270                  self.xml.getElementsByTagName(u'groups')[0].\
271                  getElementsByTagName(u'group')]
272
273    def __parse_tabs(self):
274        dic = {}
275        for tab_name in self.groups:
276            dic[tab_name] = OptionTab(self.xml.getElementsByTagName(tab_name)[0],
277                                      self.options,
278                                      self.constructor,
279                                      self.update_func)
280        return dic
281
282
283class OptionWidget:
284    def enable_widget(self):
285        self.set_sensitive(True)
286   
287    def disable_widget(self):
288        self.set_sensitive(False)
289
290class OptionInterface(gtk.ComboBoxEntry, OptionWidget):
291    def __init__(self):
292        self.list = gtk.ListStore(str)
293        gtk.ComboBoxEntry.__init__(self, self.list)
294       
295        cell = gtk.CellRendererText()
296        self.pack_start(cell, True)
297        self.add_attribute(cell, 'text', 0)
298
299class OptionList(gtk.ComboBox, OptionWidget):
300    def __init__(self):
301        self.list = gtk.ListStore(str)
302        gtk.ComboBox.__init__(self, self.list)
303       
304        cell = gtk.CellRendererText()
305        self.pack_start(cell, True)
306        self.add_attribute(cell, 'text', 0)
307       
308        self.options = []
309   
310    def append(self, option):
311        self.list.append([option[u'name']])
312        self.options.append(option)
313
314class OptionCheckIcon(HIGHBox, OptionWidget):
315    def __init__(self, label=None, option=None, hint=None):
316       
317        HIGHBox.__init__(self)
318       
319        self.cbutton = OptionCheck(label,option)
320        self.option = option
321        self.hint = Hint(hint)
322        self.pack_start(self.cbutton, False, False)
323        self.pack_start(self.hint, False, False, 5)
324   
325    def connect(self, action, func, additional):
326        """
327        connect checkbox
328        """
329        self.cbutton.connect(action, func, additional)
330   
331    def set_active(self, value):
332        """
333        set enable or disable checkbox
334        """
335        self.cbutton.set_active(value)
336       
337    def get_active(self):
338        return self.cbutton.get_active()
339   
340    def get_checkbox(self):
341        """
342        Returns checkbox
343        example, to do connection
344        """
345        return self.cbutton
346   
347    def get_option(self):
348        return self.cbutton.get_option()
349
350class OptionScriptList(HIGHBox, OptionWidget, object):
351    # From MAX
352    def __init__(self):
353        HIGHBox.__init__(self)
354       
355        self.entry = OptionEntry()
356        self.button = HIGButton(stock=gtk.STOCK_EDIT)
357       
358        self._pack_expand_fill(self.entry)
359        self._pack_noexpand_nofill(self.button)
360       
361        self.button.connect('clicked', self.open_dialog_cb)
362    def open_dialog_cb(self, widget):
363        dialog = ScriptChooserDialog(self.entry.get_text())
364        if dialog.run() == gtk.RESPONSE_OK:
365            self.entry.set_text(dialog.get_scripts())
366        dialog.destroy()
367
368class OptionCheck(gtk.CheckButton, OptionWidget):
369    def __init__(self, label=None, option=None):
370        gtk.CheckButton.__init__(self, label)
371       
372        self.option = option
373   
374    def get_option(self):
375        return self.option
376
377
378class OptionEntry(gtk.Entry, OptionWidget):
379    def __init__(self, param = ""):
380        gtk.Entry.__init__(self)
381        self.set_text(param)
382
383class OptionLevelSpin(gtk.SpinButton, OptionWidget):
384    def __init__(self, initial=0):
385        gtk.SpinButton.__init__(self,gtk.Adjustment(int(initial),0,10,1),0.0,0)
386
387class OptionIntSpin(gtk.SpinButton, OptionWidget):
388    def __init__(self, initial=1):
389        gtk.SpinButton.__init__(self,
390                                gtk.Adjustment(int(initial),0,10**100,1),
391                                0.0,0)
392
393class OptionFloatSpin(gtk.SpinButton, OptionWidget):
394    def __init__(self, initial=1):
395        gtk.SpinButton.__init__(self,
396                                gtk.Adjustment(float(initial),0,10**100,1),
397                                0.1,2)
398
399class OptionFile(HIGHBox, OptionWidget, object):
400    def __init__(self, param=""):
401        HIGHBox.__init__(self)
402       
403        self.entry = OptionEntry()
404        self.button = HIGButton(stock=gtk.STOCK_OPEN)
405       
406        self._pack_expand_fill(self.entry)
407        self._pack_noexpand_nofill(self.button)
408
409        self.entry.set_text(param)
410        self.button.connect('clicked', self.open_dialog_cb)
411   
412    def open_dialog_cb(self, widget):
413        dialog = AllFilesFileChooserDialog(_("Choose file"))
414        if dialog.run() == gtk.RESPONSE_OK:
415            self.entry.set_text(dialog.get_filename())
416        dialog.destroy()
417
418    def get_filename(self):
419        return "\ ".join(self.entry.get_text().split(" "))
420
421    def set_filename(self, filename):
422        self.entry.set_text(" ".join(filename.split("\ ")))
423
424    filename = property(get_filename, set_filename)
425class Hint(gtk.EventBox, object):
426    def __init__(self, hint):
427        gtk.EventBox.__init__(self)
428        self.hint = hint
429
430        self.hint_image = gtk.Image()
431        self.hint_image.set_from_stock(gtk.STOCK_DIALOG_INFO, gtk.ICON_SIZE_SMALL_TOOLBAR)
432
433        self.add(self.hint_image)
434        self.add_events(gtk.gdk.BUTTON_MOTION_MASK)
435        self.connect("button-press-event", self.show_hint)
436        #self.connect("enter-notify-event", self.show_hint)
437         
438
439    def show_hint(self, widget, event=None):
440        hint_window = HintWindow(self.hint)
441        hint_window.show_all()
442
443   
444class HintWindow(gtk.Window):
445   
446    def __init__(self, hint):
447        gtk.Window.__init__(self, gtk.WINDOW_POPUP)
448        self.set_position(gtk.WIN_POS_MOUSE)
449        bg_color = gtk.gdk.color_parse("#fbff99")
450       
451        self.modify_bg(gtk.STATE_NORMAL, bg_color)
452
453        self.event = gtk.EventBox()
454        self.event.modify_bg(gtk.STATE_NORMAL, bg_color)
455        self.event.set_border_width(10)
456        self.event.connect("button-press-event", self.close)
457        #self.event.connect("leave-notify-event", self.close)       
458        self.hint_label = gtk.Label(hint)
459        self.hint_label.set_use_markup(True)
460        self.hint_label.set_line_wrap(True)
461       
462        self.event.add(self.hint_label)
463        self.add(self.event)
464
465    def close(self, widget, event=None):
466        self.destroy()
467       
468if __name__ == '__main__':
469    o = OptionBuilder('profile_editor.xml')
470
471    ol = OptionFile()
472    w = gtk.Window()
473    w.add(ol)
474    w.show_all()
475    w.connect('delete-event', lambda x,y,z=None: gtk.main_quit())
476    gtk.main()
Note: See TracBrowser for help on using the browser.