root/branch/k0p/umitInterfaceEditor/Profile.py @ 1230

Revision 1230, 19.0 kB (checked in by kop-labs, 6 years ago)

Began integration with ProfileCore? ( Move up and Move down options done)

Line 
1# Copyright (C) 2005 Insecure.Com LLC.
2#
3# Author: Luis A. Bastiao Silva <luis.kop@gmail.com>
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 2 of the License, or
8# (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19
20import gtk 
21
22import sys
23# Testing at devel
24from os.path import split, join
25
26from umitCore.Paths import Path
27Path.set_umit_conf(join(split(__file__)[0], 'config', 'umit.conf'))
28#END DEV TEST
29options = Path.options
30profile_editor = Path.profile_editor
31#XXX This path is too wrong
32sys.path.append("selectborder")
33from WidgetsPlace import EditArea
34from WrapperWidgets import NotebookLabel, SpecialHBox
35from higwidgets.higscrollers import HIGScrolledWindow
36from higwidgets.hignotebooks import HIGNotebook
37from higwidgets.higlabels import HIGSectionLabel, HIGEntryLabel
38
39from umitCore.NmapCommand import CommandConstructor
40from umitCore.UmitConf import Profile, CommandProfile
41from umitGUI.OptionBuilder import *
42from higwidgets.higboxes import HIGVBox
43from umitCore.Logging import log
44from umitCore.I18N import _
45from higwidgets.higtables import HIGTable
46import gobject
47
48TARGET_STRING = 0
49TARGET_ROOTWIN = 1
50
51target = [
52    ('STRING', 0, TARGET_STRING),
53    ('text/plain', 0, TARGET_STRING),
54    ('application/x-rootwin-drop', 0, TARGET_ROOTWIN)
55]
56
57
58
59# XXX : Should be put in other file to using by OptionBuilder too
60type_mapping = { 
61    "str": OptionEntry,
62    "int": OptionIntSpin,
63    "float": OptionFloatSpin,
64    "level": OptionLevelSpin, 
65    "path": OptionFile,
66    "interface": OptionInterface, 
67    "scriptlist": OptionScriptList
68    }
69
70
71from ProfileCore import ProfileCore, ProfileOption
72from Command import Command, TwiceCommand, command_manager
73from Tools import ToolBarInterface
74
75
76class CommandAddRemoveLabel(TwiceCommand, Command):
77    '''
78    Add or Remove Label from Title pages of NotebookEditable
79    ###
80    trik : state is a inicial value if it is remove or add.
81    '''
82    def __init__(self, widget, text, state):
83        TwiceCommand.__init__(self, state)
84        Command.__init__(self, _('Add Label'))
85        self._widget = widget
86        self._text = text
87       
88   
89    def _add_label(self):
90        self._widget.unload_voidplace()
91        self._widget.set_text(self._text) 
92        log.debug('Adding label')
93    _execute_1 = _add_label
94    def _remove_label(self):
95        self._widget.voidplace()
96        log.debug('Removing label, Adding Void Place')
97    _execute_2 = _remove_label
98
99class CommandAddRemoveVoidplace(TwiceCommand, Command):
100    '''
101    Add or Remove A voidplace on the Editor-Mode
102   
103    '''
104    def __init__(self, table, widget, coords, state): 
105        TwiceCommand.__init__(self, state)
106        Command.__init__(self, _('Add/Remove Voidplace'))
107        self._table = table
108        self._widget = widget
109        self._x,self._y = coords[widget] 
110       
111        self._spacing = self._table.get_row_spacing(self._x)
112    def _add(self):
113        if self._widget.is_voidplace():
114            self._widget.show_voidplace()
115       
116        #self._widget.do_draw()
117        self._widget.show()     
118        #self._table.attach(self._widget, 0,2,self._x,self._y)
119        self._table.set_row_spacing(self._x,self._spacing)
120        #self._widget.do_voidplace()
121        #self._widget.do_voidplace()
122
123        log.debug('CommandVoidplace: add voidplace')
124       
125
126       
127    _execute_1 = _add
128    def _remove(self):
129       
130        if self._widget != None and self._widget.is_voidplace():
131            log.debug('CommandVoidplace: remove voidplace')
132            self._widget.hide_voidplace()
133            self._widget.set_select(False)
134            self._widget.hide()
135            self._table.set_row_spacing(self._x,0)
136           
137           
138           
139           
140            #self._widget.unload_voidplace()
141            #self._table.remove(self._widget)
142           
143    _execute_2 = _remove
144   
145
146
147class CommandMove(TwiceCommand, Command):
148    '''
149    Move items to down or up
150    #Trick:
151    - Add other colums to save row and do a swap. Use a temporary widget.
152    '''
153    def __init__(self, widget_container, widget, coords , profilecore,  state):
154        TwiceCommand.__init__(self, state)
155        Command.__init__(self, _('Move item'))
156        self._parent = widget_container
157        self._section_name = widget_container.get_name()
158        self._table = widget_container.get_table()
159        self._move = widget
160        self._coords = coords
161        self._profilecore = profilecore
162        self._x, self._y = self._coords[widget]
163        self._name = widget.get_name()
164       
165       
166       
167    def _determine_child(self, list, num): 
168        result = None 
169        x, y = self._coords[self._move]
170        x = x + num
171        y = y + num
172        for i in list : 
173            x_tmp, y_tmp = self._coords[i]
174            if x_tmp == x and y_tmp == y  :
175                result= i
176                break 
177        return result
178    def _get_next(self):
179         
180        childs = self._table.get_children()
181        return self._determine_child(childs, 1)
182    def _get_prev(self): 
183       
184        childs = self._table.get_children()
185        childs.reverse()
186        return self._determine_child(childs,-1) 
187    def _swap(self, widget1, widget2):
188        x1, y1 = self._coords[widget1]
189        x2, y2 = self._coords[widget2]
190        list_vp = []
191        if widget1.is_voidplace():
192            widget1.unload_voidplace()
193            list_vp.append(widget1)
194           
195        if widget2.is_voidplace():
196            list_vp.append(widget2)
197            widget2.unload_voidplace()
198
199       
200        widget1.set_select(False)
201        widget2.set_select(False)
202        w_tmp = gtk.Label('tmp')
203        self._table.attach(w_tmp, 1,2, x1, y1)
204        self._table.remove(widget1)
205        self._table.attach(widget1, 0,2, x2, y2)
206        self._table.remove(widget2)
207        self._table.attach(widget2, 0,2, x1, y1)
208        self._table.remove(w_tmp)
209       
210        self._coords[widget1] = [x2, y2]
211        self._coords[widget2] = [x1,y1]
212        #self._move = widget2
213        for i in list_vp:
214            i.do_voidplace()
215            #i.do_resize_voidplace()
216           
217           
218    def _move_up(self):
219       
220        widget_swap = self._get_prev()
221        self._profilecore.move_option_up(self._section_name, 
222                                         self._name,
223                                         widget_swap.get_name())
224        self._swap(self._move, widget_swap)
225        #widget_swap.do_resize_voidplace()
226        self._parent.send_signal()
227        log.debug('<<< Moving item up')
228    _execute_1 = _move_up
229   
230    def _move_down(self):
231       
232        widget_swap = self._get_next()
233        self._profilecore.move_option_down(self._section_name, 
234                                           self._name, 
235                                           widget_swap.get_name())
236        self._swap( widget_swap, self._move)
237        #x, y = self._coords[widget_swap]
238        #self._move.set_select(False)
239        #widget_swap.set_select(False)
240
241        #w_tmp = gtk.Label('tmp')
242        #self._table.attach(w_tmp, 1,2, x, y)
243        #self._table.remove(widget_swap)
244        #self._table.attach(widget_swap, 0,2, self._x, self._x+1)
245        #self._table.remove(self._move)
246       
247        #self._table.attach(self._move, 0,2, x, y)
248        #self._table.remove(w_tmp)
249       
250        #self._coords[widget_swap] = [self._x, self._y]
251        #self._coords[self._move] = [x,y]
252        self._parent.send_signal()
253        log.debug('<<< Moving item down')
254       
255    _execute_2 = _move_down
256
257
258
259
260
261class CommandAddRemoveOption(TwiceCommand, Command):
262    '''
263    Add or Remove Option from BoxEditable
264    ###
265    trik : state is a inicial value if it is remove or add.
266    '''
267    def __init__(self, widget_container, widget_option, state):
268        TwiceCommand.__init__(self, state)
269        Command.__init__(self, _('Add/Remove Option'))
270        self._widget = widget_container
271        self._widget_option = widget_option
272       
273   
274    def _add_option(self):
275       
276        widget_option = self._widget_option
277        widget = self._widget
278        childs = widget.get_children()
279        widget.remove(childs[0])
280        widget.unload_voidplace()
281        for k in widget_option:
282            widget.pack_start(k)
283        #widget_option.show() # XXX - may be need
284       
285        log.debug('Adding option')
286    _execute_1 = _add_option
287    def _remove_option(self):
288       
289        widget = self._widget
290        childs = widget.get_children()
291        for i in childs:
292            widget.remove(i)
293        t = gtk.Label('-')
294        t.show()
295       
296        widget.pack_start(t)
297        widget.do_voidplace()
298        log.debug('Removing option, Adding Void Place')
299    _execute_2 = _remove_option
300
301
302class BoxEditable(HIGVBox):
303    def __init__(self, section_name, profile, listoptions, notebook_parent):
304        '''
305        A Box Editable contains a options of each tab
306        @param section_name: section name <tab>
307        @type section_name: str
308        @param profile: A class that view and modify xml file
309        @type profile: ProfileCore
310        '''
311       
312        HIGVBox.__init__(self)
313        self._coords = {}
314        self._parent = notebook_parent
315        #Profile Core do a manage at profile_editor.xml file
316        self._profilecore = None 
317        self._profile = profile
318        self._listoptions = listoptions
319        self._table = HIGTable()
320        self._section_name = section_name
321        self._options = self._profile.get_section(section_name)
322        self._table.set_border_width(3)
323        c = self.get_colormap()
324        color = c.alloc_color(0,0,0)   
325        self._table.modify_fg(gtk.STATE_NORMAL,color )
326        self._fill_table()
327       
328        box_tmp = HIGVBox()
329        box_tmp.pack_start(self._table, False, False)
330        self._sw = HIGScrolledWindow()
331        #self._sw.set_size_request(400,200)
332        vp = gtk.Viewport()
333        vp.add(box_tmp)
334        vp.set_shadow_type(gtk.SHADOW_NONE)
335        self._sw.add(vp)
336        self.pack_start(self._sw, True, True)
337        self._old_selected = None 
338        self._x = 0
339        self._y = 0 
340       
341
342    #Private API
343    def _fill_table(self):
344        k = 0
345        for i in self._options:
346            t = SpecialHBox()
347            type = i.get_type()
348            if type== 'option_check':
349               
350                name_option = i.get_option()
351                hint = self._listoptions.get_hint(name_option)
352                tmp_widget = OptionCheckIcon(i.get_label(),name_option,hint)
353                t.pack_start(tmp_widget)
354                arg_type = self._listoptions.get_arg_type(name_option)
355                if arg_type!= '':
356                    additional = type_mapping[arg_type]()
357                    t.pack_start(additional)
358               
359            elif type == 'option_list': 
360                eventbox = gtk.EventBox()
361                label = HIGEntryLabel(i.get_label())
362               
363                eventbox.add(label)
364                tmp_widget = OptionList()
365                for j in i.get_option_list():
366                    d = {}
367                    d['name'] = j
368                    tmp_widget.append(d)
369                t.pack_start(eventbox)         
370                t.pack_start(tmp_widget)
371                #t.drag_source_set(gtk.gdk.BUTTON1_MASK |
372                                                  #gtk.gdk.BUTTON3_MASK,
373                                                  #target,
374                                                  #gtk.gdk.ACTION_COPY |
375                                                  #gtk.gdk.ACTION_MOVE)
376                #t.connect('drag_data_get', self.source_drag_data_get)
377            t.set_flags( t.flags() |  gtk.CAN_FOCUS)
378            t.connect('button-press-event', self._button_press_event)
379            t.connect('key-press-event', self._key_press_event)
380            t.set_name(i.get_label())
381            t.connect('drag_data_received', self.drag_received)
382            t.drag_dest_set(gtk.DEST_DEFAULT_ALL, target[:-1],
383                                gtk.gdk.ACTION_COPY | gtk.gdk.ACTION_MOVE)
384           
385            self._table.attach(t, 0,2, k,k+1)
386            self._coords[t] = [k, k+1]
387            self._x = k
388            self._y = k+1
389            k =k +1
390       
391
392       
393    def _key_press_event(self, widget, event):
394        print "key pressed"
395        _keyval = gtk.gdk.keyval_name(event.keyval)
396        if _keyval == "Delete" and self._old_selected!=None :
397            if not widget.is_voidplace(): 
398                # remove widgets like checkbuttons or others and put voidplace
399                childs = widget.get_children()
400                cmd = CommandAddRemoveOption(widget,childs, False)
401                widget.set_select(False)
402                command_manager.add_command(cmd)
403                log.debug(' Remove Widgets like CheckButtons or others and put voidplace')
404               
405            else:
406                # remove voidplace and delete the widget from table/box
407                #XXX
408                cmd = CommandAddRemoveVoidplace(self._table, 
409                                                widget, self._coords, False)
410                #widget.unload_voidplace()
411                command_manager.add_command(cmd)
412                log.debug('Remove voidplace and delete the widget from table')
413               
414        #self._table.remove(widget)
415        #childs = self._table.get_children()
416        #for i in childs:
417            #if i.is_voidplace():
418                #i.do_resize_voidplace()
419       
420    def _button_press_event(self,widget, event):
421        #XXX: See, may be this is import for bug of assertation GObject
422        widget.set_select(True) 
423        self._parent.select(False)
424        if widget == self._old_selected :
425            log.debug('Do nothing')
426            if widget.is_voidplace():
427                widget.do_draw()
428            widget.grab_focus()
429            return 
430        widget.do_draw()
431        if self._old_selected != None:
432            self._old_selected.set_select(False)
433        log.debug('drawing')
434        self._old_selected = widget
435        widget.grab_focus()
436        self._parent.emit('changed', 'Options', self._parent.get_current_page())
437
438    #Public API
439    def get_name(self):
440        return self._section_name
441   
442    def can_move_up(self):
443       
444        widget = self._old_selected
445        x = 0 
446        if widget!= None :
447            x,y = self._coords[widget]
448        return x != 0
449    def can_move_down(self):
450       
451        widget = self._old_selected
452        y = len(self._coords)
453        if widget!= None :
454            x,y = self._coords[widget]
455        return y != (len(self._coords))
456    def send_signal(self):
457        self._parent.emit('changed', 'Options', self._parent.get_current_page())
458       
459    def move_item_down(self):
460        '''
461        Move selected item to down
462        '''
463        assert self.can_move_down()
464       
465        cmd = CommandMove(self, self._old_selected, self._coords, self._profilecore, False)
466        command_manager.add_command(cmd)
467        self.send_signal()
468    def move_item_up(self):
469        '''
470        Move selected item to up
471        '''
472        assert self.can_move_up()
473       
474        cmd = CommandMove(self, self._old_selected, self._coords, self._profilecore, True)
475        command_manager.add_command(cmd)
476        self.send_signal()
477   
478   
479    def set_profile_core(self, profile_core):
480        self._profilecore = profile_core
481   
482    def option_builder(self, option_name, type):
483        '''
484        construct a widget with the name of the option
485        @return: A widget
486        @rtype: Widget like OptionCheck or others
487        '''
488        result = []
489        hint = self._listoptions.get_hint(option_name)
490        #label, option_name, hint
491        tmp_widget = OptionCheckIcon(option_name,option_name,hint) 
492        result.append(tmp_widget)
493        arg_type = self._listoptions.get_arg_type(option_name)
494        if arg_type!= '':
495            additional = type_mapping[arg_type]()
496            result.append(additional)
497        return result
498       
499       
500       
501       
502    def _is_widget(self, name):
503        return name[0:3] == '_wid'
504
505    def drag_received(self,w, context, x, y, data, info, time):
506        print "drag received"
507        option_name = data.data
508        if self._is_widget(option_name) or not  w.is_voidplace():
509            return
510       
511        arg_type = self._listoptions.get_arg_type(data.data)
512        widgets = self.option_builder(option_name, arg_type)
513       
514        #Remove child
515        childs = w.get_children()
516        w.remove(childs[0])
517        #Add
518        for child in widgets:
519            #t = gtk.Label('fsck')
520            w.pack_start(child)
521            child.show_all()
522       
523        w.unload_voidplace()
524    def get_table(self):
525        return self._table
526    def source_drag_data_get(self, btn, context, selection_data, info, time):
527        selection_data.set(selection_data.target, 8, "I'm Data!")   
528
529class NotebookEditable(HIGNotebook):
530    '''
531    Editable Notebook to Edit Profile Editor
532    '''
533    __gsignals__ = {
534        'changed':  (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, 
535                     (gobject.TYPE_STRING,object))
536    }
537    def __init__(self, listoption, profilecore):
538        self._listoption = listoption
539        HIGNotebook.__init__(self)
540        self.sections_widgets = {}
541        self.connect('key-press-event', self.on_key_press)
542        self.connect('switch-page', self.on_switch_page)
543        self._old_select = None 
544        self._profilecore = profilecore
545
546    def save(self):
547        self._profilecore.write_file(profile_editor)
548    def reset(self):
549        pass
550   
551    def load_data(self):
552        self.profile = CommandProfile()
553        options_used = {}
554       
555        self.constructor = CommandConstructor(options_used)
556        self.options = ProfileCore(profile_editor) 
557        i = 0
558        for tab in self.options.groups:
559            self.create_tab(tab, self.options.section_names[tab], 
560                            self.options.tabs[tab], i)
561            i = i+1 
562    def create_tab(self, tab_name, section_name, tab, number):
563        box = BoxEditable(tab_name, self.options, self._listoption, self)
564        box.set_profile_core(self._profilecore)
565        label = NotebookLabel(tab_name)
566        #eventbox = gtk.EventBox()
567
568        #eventbox.add(label)
569        label.set_flags( label.flags() |  gtk.CAN_FOCUS) 
570        label.connect('key-press-event', self.on_key_press)
571        label.connect('button-press-event', self.on_button_press) 
572
573       
574        label.connect('drag_data_received', self.label_drag_data_received)
575        label.drag_dest_set(gtk.DEST_DEFAULT_ALL, target[:-1],
576                            gtk.gdk.ACTION_COPY | gtk.gdk.ACTION_MOVE)
577        #eventbox.show_all()
578        label.show_all()
579        self.sections_widgets[label] = number
580        self.append_page(box, label)
581   
582    def select(self, value):
583        if self._old_select!=None:
584            self._old_select.set_select(value)
585   
586    def on_button_press(self, widget, event):
587        log.debug('Button press on Notebook')
588        if self._old_select != None:
589            self._old_select.set_select(False)
590        widget.set_select(True)
591        self._old_select = widget
592        self.set_current_page(self.sections_widgets[widget])
593        #XXX - this focus owns drag-n-drop received :(
594        #widget.grab_focus()
595        return True
596    def on_switch_page(self, widget, event, page):
597        self.emit('changed','Sections', page)
598        self.grab_focus()
599    def on_key_press(self, widget, event):
600        _keyval = gtk.gdk.keyval_name(event.keyval)
601        log.debug('Key press event on NotebookEditable')
602        if self._old_select==None:
603            return
604
605        if _keyval == "Delete" :
606            if self._old_select.is_voidplace():
607                self._old_select.unload_voidplace()
608                self.remove_page(self.get_current_page())
609            else: 
610                cmd = CommandAddRemoveLabel(self._old_select, 
611                                            self._old_select.get_text(), False)
612                command_manager.add_command(cmd)
613        else: 
614            self._old_select.unload_voidplace()
615    def label_drag_data_received(self, w, context, x, y, data, info, time):
616        print "received"
617
618        if data and data.format == 8:
619            print 'Received "%s" in label' % data.data
620            context.finish(True, False, time)
621            cmd = CommandAddRemoveLabel(self._old_select, 'New Label', True)
622            command_manager.add_command(cmd)
623           
624        #else:
625        #    context.finish(False, False, time)
626class ProfileEdit(gtk.HBox):
627   
628    def __init__(self, listoption):
629        gtk.HBox.__init__(self)
630        self._toolbar = ToolBarInterface()
631        #MAIN SCROLLED
632        self._scroolledmain = HIGScrolledWindow()
633        #NOTEBOOKEDITABLE :
634        self._profilecore = ProfileCore(profile_editor)
635        self.notebook = NotebookEditable(listoption, self._profilecore)
636        self.notebook.connect('changed', self.update_toolbar)
637        self.notebook.load_data()
638        self.pack_start(self._toolbar, False, False)
639        self.pack_start(self._scroolledmain, True, True)
640        self._scroolledmain.add_with_viewport(self.notebook)
641        self.show_all()
642        self._edit_area = EditArea()
643   
644    def update_toolbar(self, action, others, page):
645        #print action
646        #print others
647        #print page
648        boxeditable = self.get_box_editable()
649        self._toolbar.set_box_editable(boxeditable)
650        self._toolbar.update_toolbar()
651   
652    def get_box_editable(self):
653        current_page = self.notebook.get_current_page()
654        current_box = self.notebook.get_nth_page(current_page)
655        return current_box
656   
657    def save(self):
658        pass
659   
660       
661    def create_events(self):
662        #....
663        pass
664
665       
Note: See TracBrowser for help on using the browser.