root/trunk/umit/gui/ProfileEditor.py @ 5535

Revision 5535, 14.8 kB (checked in by nopper, 7 months ago)

Fixes for #374

Line 
1#!/usr/bin/env python
2# Copyright (C) 2005 Insecure.Com LLC.
3# Authors:
4#  Adriano Monteiro Marques <py.adriano@gmail.com>
5#  Luis Antonio Bastiao Silva <luis.kop@gmail.com>
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
21
22import gtk
23
24from higwidgets.higwindows import HIGWindow
25from higwidgets.higboxes import HIGVBox, HIGHBox
26from higwidgets.higboxes import HIGSpacer, hig_box_space_holder
27from higwidgets.higexpanders import HIGExpander
28from higwidgets.higlabels import HIGSectionLabel, HIGEntryLabel
29from higwidgets.higscrollers import HIGScrolledWindow
30from higwidgets.higtextviewers import HIGTextView
31from higwidgets.higbuttons import HIGButton
32from higwidgets.higtables import HIGTable
33from higwidgets.higdialogs import HIGAlertDialog, HIGDialog
34
35from umit.gui.OptionBuilder import *
36from umit.gui.Help import show_help
37
38from umit.core.ProfileEditorConf import profile_editor_file
39from umit.core.NmapCommand import CommandConstructor
40from umit.core.UmitConf import Profile, CommandProfile
41from umit.core.UmitLogging import log
42from umit.core.I18N import _
43
44
45class ProfileEditor(HIGWindow):
46
47    def __init__(self, profile_name=None, delete=False):
48        HIGWindow.__init__(self)
49        self.set_title(_('Profile Editor'))
50        self.set_position(gtk.WIN_POS_CENTER)
51        self.profile_name=profile_name
52        self.__create_widgets()
53        self.__pack_widgets()
54
55        self.scan_notebook = None
56        self.profilemanager = None
57
58        self.profile = CommandProfile()
59
60        self.deleted = False
61        options_used = {}
62
63        if profile_name:
64            log.debug("Showing profile %s" % profile_name)
65            prof = self.profile.get_profile(profile_name)
66            options_used = prof['options']
67
68            # Interface settings
69            self.profile_name_entry.set_text(profile_name)
70            self.profile_hint_entry.set_text(prof['hint'])
71            self.profile_description_text.get_buffer().set_text(prof['description'])
72            self.profile_annotation_text.get_buffer().set_text(prof['annotation'])
73
74            if delete:
75                # Removing profile. It must be saved again
76                self.remove_profile()
77
78        self.constructor = CommandConstructor(options_used)
79        self.options = OptionBuilder(profile_editor_file, self.constructor, self.update_command)
80        log.debug("Option groups: %s" % str(self.options.groups))
81        log.debug("Option section names: %s" % str(self.options.section_names))
82        #log.debug("Option tabs: %s" % str(self.options.tabs))
83
84        for tab in self.options.groups:
85            self.__create_tab(tab, self.options.section_names[tab], self.options.tabs[tab])
86
87        self.update_command()
88
89    def update_command(self):
90        """Regenerate command with target '<target>' and set the value for the command entry"""
91        self.command_entry.set_text(self.constructor.get_command('<target>'))
92
93    def help(self, widget):
94        """
95        Show help documentation of Profile Editor
96        """
97        show_help(self,"profile_editor.html#introduction")
98
99    def __create_widgets(self):
100        self.main_vbox = HIGVBox()
101
102
103
104        self.command_expander = HIGExpander('<b>'+_('Command')+'</b>')
105        self.command_expander.set_expanded(True)
106        self.command_entry = gtk.Entry()
107
108        self.notebook = gtk.Notebook()
109
110        # Profile info page
111        self.profile_info_vbox = HIGVBox()
112        self.profile_info_label = HIGSectionLabel(_('Profile Information'))
113        self.profile_name_label = HIGEntryLabel(_('Profile name'))
114        self.profile_name_entry = gtk.Entry()
115        self.profile_hint_label = HIGEntryLabel(_('Hint'))
116        self.profile_hint_entry = gtk.Entry()
117        self.profile_description_label = HIGEntryLabel(_('Description'))
118        #self.profile_description_label = HIGHBox()
119        self.profile_description_scroll = HIGScrolledWindow()
120        self.profile_description_text = HIGTextView()
121        self.profile_annotation_label = HIGEntryLabel(_('Annotation'))
122        #self.profile_annotation_label = HIGHBox()
123        self.profile_annotation_scroll = HIGScrolledWindow()
124        self.profile_annotation_text = HIGTextView()
125
126        # Buttons
127        self.buttons_hbox = HIGHBox()
128
129        self.help_button = HIGButton(stock=gtk.STOCK_HELP)
130        self.help_button.connect('clicked', self.help)
131
132        #self.delete_button = HIGButton(stock=gtk.STOCK_DELETE)
133        #self.delete_button.connect('clicked', self.delete_profile)
134
135        self.cancel_button = HIGButton(stock=gtk.STOCK_CANCEL)
136        self.cancel_button.connect('clicked', self.quit_without_saving)
137
138        self.ok_button = HIGButton(stock=gtk.STOCK_OK)
139        self.ok_button.connect('clicked', self.save_profile)
140
141    def __pack_widgets(self):
142        self.add(self.main_vbox)
143
144        # Packing widgets to main_vbox
145
146        self.main_vbox._pack_noexpand_nofill(self.command_expander)
147        self.main_vbox._pack_expand_fill(self.notebook)
148        self.main_vbox._pack_noexpand_nofill(self.buttons_hbox)
149
150        # Packing command_entry on command_expander
151        self.command_expander.hbox.pack_start(self.command_entry)
152
153        # Packing profile information tab on notebook
154        self.notebook.append_page(self.profile_info_vbox, gtk.Label(_('Profile')))
155        self.profile_info_vbox.set_border_width(5)
156        table = HIGTable()
157        self.profile_info_vbox._pack_noexpand_nofill(self.profile_info_label)
158        self.profile_info_vbox._pack_noexpand_nofill(HIGSpacer(table))
159
160        self.profile_annotation_scroll.add(self.profile_annotation_text)
161        self.profile_description_scroll.add(self.profile_description_text)
162
163        vbox_desc = HIGVBox()
164        vbox_desc._pack_noexpand_nofill(self.profile_description_label)
165        vbox_desc._pack_expand_fill(hig_box_space_holder())
166
167        vbox_ann = HIGVBox()
168        vbox_ann._pack_noexpand_nofill(self.profile_annotation_label)
169        vbox_ann._pack_expand_fill(hig_box_space_holder())
170        table.attach(self.profile_name_label,0,1,0,1)
171        table.attach(self.profile_name_entry,1,2,0,1)
172        #table.attach(self.profile_hint_label,0,1,1,2,xoptions=0)
173        table.attach(self.profile_hint_label,0,1,1,2)
174        table.attach(self.profile_hint_entry,1,2,1,2)
175        table.attach(vbox_desc,0,1,2,3)
176        table.attach(self.profile_description_scroll,1,2,2,3)
177        table.attach(vbox_ann,0,1,3,4)
178        table.attach(self.profile_annotation_scroll,1,2,3,4)
179
180        # Packing buttons on button_hbox
181        self.buttons_hbox.pack_start(self.help_button)
182        #self.buttons_hbox.pack_start(self.delete_button)
183        self.buttons_hbox.pack_start(self.cancel_button)
184        self.buttons_hbox.pack_start(self.ok_button)
185
186        self.buttons_hbox.set_border_width(5)
187        self.buttons_hbox.set_spacing(6)
188
189    def __create_tab(self, tab_name, section_name, tab):
190        log.debug(">>> Tab name: %s" % tab_name)
191        log.debug(">>>Creating profile editor section: %s" % section_name)
192
193        vbox = HIGVBox()
194        table = HIGTable()
195        section = HIGSectionLabel(section_name)
196
197        vbox._pack_noexpand_nofill(section)
198        vbox._pack_noexpand_nofill(HIGSpacer(table))
199        vbox.set_border_width(6)
200
201        tab.fill_table(table, True)
202        self.scrollwindow = HIGScrolledWindow()
203        self.scrollwindow.set_size_request(600,300)
204        vp = gtk.Viewport()
205        vp.add(vbox)
206        vp.set_shadow_type(gtk.SHADOW_NONE)
207        self.scrollwindow.add(vp)
208
209        vbox_tmp = HIGVBox()
210        vbox_tmp.set_border_width(6)
211        vbox_tmp.set_spacing(12)
212        vbox_tmp.pack_start(self.scrollwindow)
213
214
215        self.notebook.append_page(vbox_tmp, gtk.Label(tab_name))
216    def set_profilemanager(self, model):
217        """
218        give a model of treeview to update profile manager
219        after run wizard
220        """
221        assert model != None
222
223        self.model = model
224        self.profilemanager = True 
225
226    def update_profilemanager(self):
227        """
228        Update treeview of ProfileManager"
229        """
230        assert self.profilemanager;
231
232        profiles = self.profile.sections()
233        profiles.sort()
234        self.model.clear()
235
236
237        for command in profiles:
238            myiter = self.model.insert_before(None, None)
239            self.model.set_value(myiter, 0, command)
240            self.model.set_value(myiter,1, self.profile.get_hint(command))
241
242
243    def save_profile(self, widget):
244        profile_name = self.profile_name_entry.get_text()
245
246        if profile_name == '':
247            alert = HIGAlertDialog(message_format=_('Unnamed profile'),\
248                                   secondary_text=_('You must provide a name \
249for this profile.'))
250
251        elif profile_name.lower() == 'default':
252            alert = HIGAlertDialog(message_format=_('Reserved profile name'),\
253                                   secondary_text=_('Cannot assign "default" \
254name to this profile. Please rename it and retry.'))
255        else:
256            alert = None
257
258        if alert:
259            alert.run()
260            alert.destroy()
261
262            self.notebook.set_current_page(0)
263            self.profile_name_entry.grab_focus()
264
265            return None
266
267        if not self.deleted:
268            self.remove_profile()
269
270        command = self.constructor.get_command('%s')
271        hint = self.profile_hint_entry.get_text()
272
273        buf = self.profile_description_text.get_buffer()
274        description = buf.get_text(buf.get_start_iter(),\
275                                   buf.get_end_iter())
276
277        buf = self.profile_annotation_text.get_buffer()
278        annotation = buf.get_text(buf.get_start_iter(),\
279                                  buf.get_end_iter())
280        self.profile.add_profile(profile_name,\
281                                 command=command,\
282                                 hint=hint,\
283                                 description=description,\
284                                 annotation=annotation,\
285                                 options=self.constructor.get_options())
286        self.deleted = False
287        if self.profilemanager:
288            self.update_profilemanager()
289
290        self.quit()
291
292
293    def clean_profile_info(self):
294        self.profile_name_entry.set_text('')
295        self.profile_hint_entry.set_text('')
296        self.profile_description_text.get_buffer().set_text('')
297        self.profile_annotation_text.get_buffer().set_text('')
298
299    def set_notebook(self, notebook):
300        self.scan_notebook = notebook
301
302    def quit(self, widget=None, extra=None):
303        if self.deleted:
304            dialog = HIGDialog(buttons=(gtk.STOCK_OK, gtk.RESPONSE_OK,
305                                        gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
306            alert = HIGEntryLabel('<b>'+_("Deleting Profile")+'</b>')
307            text = HIGEntryLabel(_('Your profile is going to be deleted! Click\
308                                   Ok to continue, or Cancel to go back to Profile Editor.'))
309            hbox = HIGHBox()
310            hbox.set_border_width(5)
311            hbox.set_spacing(12)
312
313            vbox = HIGVBox()
314            vbox.set_border_width(5)
315            vbox.set_spacing(12)
316
317            image = gtk.Image()
318            image.set_from_stock(gtk.STOCK_DIALOG_WARNING, gtk.ICON_SIZE_DIALOG)
319
320            vbox.pack_start(alert)
321            vbox.pack_start(text)
322            hbox.pack_start(image)
323            hbox.pack_start(vbox)
324
325            dialog.vbox.pack_start(hbox)
326            dialog.vbox.show_all()
327
328            response = dialog.run()
329            dialog.destroy()
330
331            if response == gtk.RESPONSE_CANCEL:
332                return None
333        self.destroy()       
334        if self.scan_notebook != None:
335
336            for i in xrange(self.scan_notebook.get_n_pages()):
337                page = self.scan_notebook.get_nth_page(i)
338                page.toolbar.profile_entry.update()
339
340        #page.toolbar.scan_profile.profile_entry.child.\
341        #    set_text(self.profile_name_entry.get_text())
342    def quit_without_saving(self, widget=None):
343        self.deleted=False
344        self.quit()
345
346    def on_delete(self, widget=None):
347        if not self.profile_name:
348            return self.on_cancel()
349
350        dialog = HIGDialog(buttons=(gtk.STOCK_OK, gtk.RESPONSE_OK,
351                                    gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
352        alert = HIGEntryLabel('<b>'+_("Deleting Profile")+'</b>')
353        text = HIGEntryLabel(_('Your profile is going to be deleted! Click \
354Ok to continue, or Cancel to go back to Profile Editor.'))
355        hbox = HIGHBox()
356        hbox.set_border_width(5)
357        hbox.set_spacing(12)
358
359        vbox = HIGVBox()
360        vbox.set_border_width(5)
361        vbox.set_spacing(12)
362
363        image = gtk.Image()
364        image.set_from_stock(gtk.STOCK_DIALOG_WARNING, gtk.ICON_SIZE_DIALOG)
365
366        vbox.pack_start(alert)
367        vbox.pack_start(text)
368        hbox.pack_start(image)
369        hbox.pack_start(vbox)
370
371        dialog.vbox.pack_start(hbox)
372        dialog.vbox.show_all()
373
374        response = dialog.run()
375        dialog.destroy()
376
377        if response == gtk.RESPONSE_CANCEL:
378            return None
379
380        self.deleted = True
381        self.profile.remove_profile(self.profile_name)
382        self.on_cancel()
383
384
385    def on_cancel(self, widget=None):
386        self.destroy()
387        self.update_profile_entry()
388
389    def update_profile_entry(self):
390        page = None
391        for i in xrange(self.scan_notebook.get_n_pages()):
392            page = self.scan_notebook.get_nth_page(i)
393
394            page.toolbar.profile_entry.update(\
395                self.profile_name_entry.get_text())
396
397            list = page.toolbar.profile_entry.get_model()
398            length = len(list)
399            if self.deleted and length > 0 :
400                page.toolbar.profile_entry.set_active(0)
401            elif self.deleted and length == 0:
402                page.toolbar.profile_entry.child.set_text("")
403
404        if page is not None:
405            page.toolbar.profile_entry.update()
406
407
408
409    def remove_profile(self,profile_name=None):
410        '''
411        Remove current profile
412        '''
413        if not profile_name:
414            profile_name = self.profile_name
415        self.profile.remove_profile(profile_name)
416        self.deleted = True       
417
418    def delete_profile(self, widget=None):
419        """
420        delete profile
421        """
422        self.remove_profile()
423        self.deleted=False       
424        self.quit()
425
426
427
428if __name__ == '__main__':
429    p = ProfileEditor()
430    p.show_all()
431
432    gtk.main()
433
Note: See TracBrowser for help on using the browser.