root/branch/ggpolo/umitInventory/Viewer.py @ 1421

Revision 1421, 30.4 kB (checked in by ggpolo, 6 years ago)

Added docs for network inventory graphs and search system. Better sample for the higframe. Function to check how to open help pages placed in umitCore/Utils

Line 
1# Copyright (C) 2007 Insecure.Com LLC.
2#
3# Authors: Guilherme Polo <ggpolo@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
18# USA
19
20"""
21Inventories Viewer main window.
22"""
23
24import os
25import gtk
26import gobject
27import webbrowser
28from ConfigParser import ConfigParser
29
30from higwidgets.higwindows import HIGMainWindow
31from higwidgets.hignotebooks import HIGNotebook, HIGAnimatedTabLabel
32from higwidgets.higscrollers import HIGScrolledWindow
33from higwidgets.higboxes import HIGHBox
34
35from umitCore.I18N import _
36from umitCore.Paths import Path
37from umitCore.DataDecay import get_decays
38from umitCore.Utils import open_url_as
39
40from umitDB.Retrieve import InventoryRetrieve
41from umitDB.Search import SearchDB
42
43from umitGUI.BugReport import BugReport
44from umitGUI.SchedulerControl import SchedControl
45
46from umitInventory.StartupSettings import startup_options
47from umitInventory.NewInventory import NewInventory
48from umitInventory.SearchBar import SearchBar
49from umitInventory.ChangesList import ChangesList
50from umitInventory.ChangesDiff import ChangesDiff
51from umitInventory.InventoryTree import InventoryTree
52from umitInventory.Timeline import TLHolder
53from umitInventory.InventoryLoad import InventoryLoad
54from umitInventory.DataRemoval import ConfigureDataRemoval, RemoveOldData
55from umitInventory.SchedulerLog import SchedLog
56from umitInventory.SettingsWin import NISettings
57from umitInventory.About import About
58
59umitdb = Path.umitdb_ng
60inventory_info = _("Info")
61
62class InventoryNB(gtk.Notebook):
63    """
64    Inventory Notebook for each Inventory.
65    """
66
67    def __init__(self, daddy):
68        gtk.Notebook.__init__(self)
69        self.set_scrollable(True)
70        self.popup_enable()
71       
72        self.daddy = daddy
73        self.pages = [ ]
74               
75        self.__layout()
76   
77
78    def append_inv(self, title="Info", box=None):
79        """
80        Add info page.
81        """
82        if self.page_exists(title):
83            return
84       
85        custom_title = self.__create_custom_title(title, box)
86        box.show()
87        custom_title.show()
88        self.append_page(box, custom_title)
89        self.pages.append(title)
90           
91        self.__layout()
92       
93       
94    def append_host(self, host_addr, box):
95        """
96        Add host page.
97        """
98        if self.page_exists(host_addr):
99            return
100       
101        custom_title = self.__create_custom_title(host_addr, box)
102        box.show()
103        custom_title.show()
104        self.append_page(box, custom_title)
105        self.pages.append(host_addr)
106           
107        self.__layout()
108
109   
110    def page_exists(self, pagetitle):
111        """
112        Check if there is a page with pagetitle in this notebook.
113        """
114        if pagetitle in self.pages:
115            return True
116       
117        return False
118
119
120    def remove_page(self, button, page, text):
121        """
122        Remove a page from notebook and from self.pages
123        """
124        del self.pages[self.pages.index(text)]
125        self.remove(page)
126       
127        if not len(self.pages): # last page in this inventory was just removed
128            self.daddy._delete_inventory_page() # delete notebook
129
130
131    def __add_close_icon_to_button(self, button):
132        """
133        Adds a close image to the page title close button.
134        """
135        image = gtk.Image()
136        image.set_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_MENU)
137        image.show()
138
139        gtk.Button.set_relief(button, gtk.RELIEF_NONE)
140        settings = gtk.Widget.get_settings(button)
141
142        (w,h) = gtk.icon_size_lookup_for_settings(settings, gtk.ICON_SIZE_MENU)
143
144        gtk.Widget.set_size_request(button, w + 4, h + 4)
145       
146        icon_hbox = gtk.HBox(False, 0)
147        icon_hbox.pack_start(image, True, False, 0)
148        icon_hbox.show()
149       
150        button.add(icon_hbox)
151
152
153    def __create_custom_title(self, title, widget):
154        """
155        Creates a title with close button.
156        """
157        title_eb = gtk.EventBox()
158       
159        label = gtk.Label(_("%s" % title))
160        label.show()
161
162        title_hbox = gtk.HBox(False)       
163        title_hbox.pack_start(label, False, False, 0)
164
165        title_eb.add(title_hbox)
166       
167        if self.daddy.invnb_close_btn:
168            button = gtk.Button()
169            button.connect('clicked', self.remove_page, widget, title)
170            button.show()
171
172            self.__add_close_icon_to_button(button)
173            title_hbox.pack_end(button, False, False, 0)
174       
175        title_hbox.show()
176       
177        return title_eb
178
179       
180    def __layout(self):
181        """
182        Update notebook.
183        """
184        self.show()
185
186
187class InventoryViewer(HIGMainWindow):
188    """
189    UMIT Network Inventory, Main Window.
190    """
191
192    def __init__(self, daddy=None):
193        HIGMainWindow.__init__(self)
194       
195        self.daddy = daddy
196
197        self.tip_timer = -1
198        self.main_accel_group = gtk.AccelGroup()
199        self.add_accel_group(self.main_accel_group)
200       
201        self.viewernb = HIGNotebook()
202       
203        self.invsearch = SearchDB(umitdb)
204        self.invdb = InventoryRetrieve(umitdb)
205        self.invtree = InventoryTree(self)
206        self.invnb = HIGNotebook()
207        self.invnb_close_btn = startup_options()["tabs_close_btn"]
208        self.invnbpages_titles = [ ]
209        self.invnbpages_objects = [ ]
210        self.invdataload = InventoryLoad()
211        self.invdata = None
212       
213        # timeline tab
214        self.timeline = TLHolder()
215       
216        # statusbars
217        self.std_statusbar = gtk.Statusbar()
218        self.std_sb = self.std_statusbar.get_context_id("stdbar")
219        self._write_statusbar("                              ")
220       
221        self.tip_statusbar = gtk.Statusbar()
222        self.tip_statusbar.set_has_resize_grip(False)
223        self.tip_sb = self.tip_statusbar.get_context_id("tipbar")
224        self.write_tips = startup_options()["tips"]
225       
226        # timer for checking updates
227        self.db_stat = os.stat(umitdb).st_mtime
228        self.schema_stat = os.stat(Path.sched_schemas).st_mtime
229        self.timer_updater = gobject.timeout_add(4200, # nice number
230                                                 self.__check_for_updates)
231       
232        # gui scheduler controller
233        self.schedctrl = SchedControl(self)
234
235        self.invtree.fill_tree()
236        self._create_ui_manager()
237        self.__set_props()
238        self.__do_layout()
239       
240        self.connect('inventory-activated', self._inventory_activated)
241        self.connect('delete-event', self._exit_ni)
242        self.connect('realize', self.on_realize)
243       
244
245    def on_realize(self, event):
246        """
247        After realizing, change to first page in main notebook (Historic page).
248        """
249        self.viewernb.set_current_page(0)
250   
251   
252    def _close_current_hosttab(self, event):
253        """
254        Closes current active Host tab.
255        """
256        holder = self.invnb.get_nth_page(self.invnb.get_current_page())
257        if holder:
258            title = self.invnb.get_tab_label_text(holder)
259            p = self.invnbpages_objects[self.invnbpages_titles.index(title)]
260           
261            if len(p.pages):
262                tab_label = p.pages[p.get_current_page()]
263                content = p.get_nth_page(p.get_current_page())
264                p.remove_page(None, content, tab_label)
265           
266
267    def _close_current_invtab(self, event):
268        """
269        Closes current active inventory notebook.
270        """
271        holder = self.invnb.get_nth_page(self.invnb.get_current_page())
272        if holder:
273            label = self.invnb.get_tab_label_text(holder)
274            del_index = self.invnbpages_titles.index(label)
275           
276            page = self.invnbpages_objects[del_index]
277            for p in xrange(page.get_n_pages()-1):
278                tab_label = page.pages[p]
279                content = page.get_nth_page(p)
280                page.remove_page(None, content, tab_label)
281            self._delete_inventory_page()
282       
283
284    def _delete_inventory_page(self):
285        """
286        Removed last page from an Inventory notebook, now remove the Inventory
287        notebook.
288        """
289        cur_page = self.invnb.get_current_page()
290        page = self.invnb.get_nth_page(cur_page)
291        page_label = self.invnb.get_tab_label_text(page)
292        del_index = self.invnbpages_titles.index(page_label)
293        del self.invnbpages_titles[del_index]
294        del self.invnbpages_objects[del_index]
295       
296        self.invnb.remove_page(cur_page)
297   
298   
299    def _inventory_activated(self, event, data):
300        """
301        Activated some item on Inventory tree.
302        """
303        if not data['host_addr']: # empty inventory was selected
304            # clicked on Inventory title, dont do nothing
305            return
306           
307        title = data["root"] # inventory name
308       
309        # check if activated inventory isnt open already
310        if not title in self.invnbpages_titles:
311            # create new notebook to hold this Inventory
312            newinvnb = InventoryNB(self)
313            self.invnb.append_page(newinvnb, gtk.Label(_("%s" % title)))
314               
315            self.invnbpages_titles.append(title)
316            self.invnbpages_objects.append(newinvnb)
317           
318            # check if a host was activated
319            if data["host_addr"][0] != inventory_info: 
320                box = self._load_inventory_host_data(title, 
321                                                     data["host_addr"][1])
322                newinvnb.append_host(data["host_addr"][0], box)
323            else:
324                # inventory info
325                box = self._load_inventory_data(title)
326                if box:
327                    newinvnb.append_inv(box=box)
328               
329        else:
330            # get Inventory notebook
331            p = self.invnbpages_objects[self.invnbpages_titles.index(title)]
332           
333            # check if a host was activated
334            if data["host_addr"][0] != inventory_info and \
335                not p.page_exists(data["host_addr"]):
336                box = self._load_inventory_host_data(title, 
337                                                     data["host_addr"][1])
338                p.append_host(data["host_addr"][0], box)
339               
340            # if it is not a host, it was inventory info
341            elif data["host_addr"][0] == inventory_info:
342                box = self._load_inventory_data(title)
343                if box:
344                    p.append_inv(box=box)
345               
346   
347    def _load_inventory_data(self, inventory_name):
348        """
349        Load data for activated Inventory.
350        """
351        fk_inventory = self.invdb.get_inventory_id_for_name(inventory_name)
352        scans = self.invdb.get_scans_id_for_inventory(fk_inventory)
353        last_scan_id = scans[len(scans)-1][0]
354        hosts = self.invtree.invdata[inventory_name]
355       
356        box = gtk.VBox()
357       
358        # scan info
359        hb = gtk.HBox()
360        hb.pack_start(gtk.Label(_("Scan count: %d" % len(scans))), False, 
361                      False, 0)
362        box.pack_start(hb, False, False, 0)
363       
364        hb = gtk.HBox()
365        last_scan_date = self.invdb.get_finish_timestamp_for_scan_from_db(last_scan_id)
366        hb.pack_start(gtk.Label(_("Last scan date: %s" % last_scan_date)), 
367                      False, False, 0)
368        box.pack_start(hb, False, False, 0)
369       
370        details = self.invdb.get_scan_details_for_scan_from_db(scans[0][0])
371        detc = [ _("Scan args"), _("XML output version"), _("Verbose"), 
372                 _("Debugging"), _("Scanner name"), _("Scanner version") ]
373        for indx, item in enumerate(details):
374            hb = gtk.HBox()
375            hb.pack_start(gtk.Label("%s: %s" % (detc[indx], item)), False, 
376                          False, 0)
377            box.pack_start(hb, False, False, 0)
378       
379        # "separator"
380        box.pack_start(gtk.HSeparator(), False, False, 6)
381       
382        # hosts info
383        hb = gtk.HBox()
384        hb.pack_start(gtk.Label(_("Hosts: %s" % ', '.join(host[0] for host in hosts))), 
385                      False, False, 0)
386        box.pack_start(hb, False, False, 0)
387       
388        hb = gtk.HBox()
389        hb.pack_start(gtk.Label(_("Host count: %s" % len(hosts))), False, 
390                      False, 0)
391        box.pack_start(hb, False, False, 0)
392       
393        sw = gtk.ScrolledWindow()
394        sw.add_with_viewport(box)
395        sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
396        sw.show_all()
397       
398        return sw
399
400
401    def _load_inventory_host_data(self, inventory_name, host_addr):
402        """
403        Load data for a host in an inventory.
404        """
405        changesd = ChangesDiff(self.invdb)
406        changesl = ChangesList(self, changesd, 
407                               data={-1: (inventory_name, host_addr)})
408
409        paned = gtk.VPaned()
410        paned.add1(changesl)
411        paned.add2(changesd)
412
413        return paned
414
415
416    def _write_statusbar(self, msg):
417        """
418        Write some message at standard statusbar.
419        """
420        self.std_statusbar.pop(self.std_sb)
421        self.std_statusbar.push(self.std_sb, msg)
422       
423       
424    def _clear_statusbar(self):
425        """
426        Clear standard statusbar.
427        """
428        self.std_statusbar.pop(self.std_sb)
429       
430
431    def _write_statusbar_tip(self, tipmsg, timeout=True):
432        """
433        Write a tip at statusbar.
434        """
435        if not self.write_tips:
436            # tips disabled
437            return
438
439        if not self.window: # widget being destroyed
440            gobject.source_remove(self.tip_timer)
441            return
442
443        self.tip_statusbar.pop(self.tip_sb)
444        self.tip_statusbar.push(self.tip_sb, tipmsg)
445
446        if self.tip_timer != -1:
447            gobject.source_remove(self.tip_timer)
448
449        if timeout:
450            # remove tip after 15 seconds
451            self.tip_timer = gobject.timeout_add(15000, 
452                                                 self._clear_tip_statusbar)
453           
454           
455    def _clear_tip_statusbar(self):
456        """
457        Clear statusbar.
458        """
459        self.tip_statusbar.pop(self.tip_sb)
460        gobject.source_remove(self.tip_timer)
461        self.tip_timer = -1
462       
463        return False
464       
465
466    def _update_viewer(self):
467        """
468        Call this when needed to update Network Inventory Viewer.
469        """
470        self.invtree.fill_tree()
471        # For now at least it won't reload data on open tabs, this seems
472        # somewhat "intrusive".
473       
474       
475    def _build_results_view(self, query, returned, buildnow=False):
476        """
477        Build a TreeView with returned results from search or perform search
478        and then Build TreeView.
479        """
480        def close_page(widget, data):
481            """
482            Close search page.
483            """
484            page_num = self.viewernb.page_num(data)
485            self.viewernb.remove_page(page_num)
486           
487           
488        def row_activated(tv, path, tvcolumn):
489            """
490            Activated some row in results treeview.
491            """
492            # create page at "Inventory"
493            model = tv.get_model()
494            tv_iter = model.get_iter(path)
495            host_addr = model.get_value(tv_iter, 1)
496           
497            data = { }
498            root = model[path[0]][0]
499            data["root"] = root
500            data["host_addr"] = (host_addr, host_addr) # new format
501
502            self.emit('inventory-activated', data)
503           
504            # write tip to statusbar
505            self._write_statusbar_tip(_("A page was open at Historic tab!"))
506       
507           
508        def buildtv(*args):
509            """
510            Build treeview and append results.
511            """
512            lsmodel = gtk.ListStore(str, str, str, str)
513            tview = gtk.TreeView(lsmodel)
514            columns = 4
515            columns_text = ( _("Inventory"), _("Host"), 
516                             _("First Matched Category"), _("Entry Date") )
517            tview.columns = [None]*columns
518       
519            for n in range(columns):
520                tview.columns[n] = gtk.TreeViewColumn(columns_text[n])
521                tview.columns[n].cell = gtk.CellRendererText()
522                tview.columns[n].pack_start(tview.columns[n].cell, True)
523                tview.columns[n].set_attributes(tview.columns[n].cell, text=n)
524
525                tview.append_column(tview.columns[n])
526               
527            tview.connect('row-activated', row_activated)
528
529            # layout
530            matches = len(args[1])
531            plural = (matches > 1 or matches == 0) and 's' or ''
532            upper_title = gtk.Label()
533            upper_title.set_markup(_("<b>%d result%s found.</b>" % (matches,
534                                                                    plural)))
535            hutbox = HIGHBox()
536            hutbox._pack_noexpand_nofill(upper_title)
537            sw = HIGScrolledWindow()
538            sw.add(tview)
539            vbox = gtk.VBox()
540            vbox.pack_start(hutbox, False, False, 3)
541            vbox.pack_start(sw, True, True, 0)
542
543            vbox.show_all()
544
545            # append results to treeview
546            results = args[1]
547
548            for res, date in results.items():
549                invname = self.invdb.get_inventory_name_for_id(res[0])
550                lsmodel.append((invname, res[1], res[2], str(date)))
551
552            title = _("Search: %s") % args[0]
553            tab_label = HIGAnimatedTabLabel(title)
554            tab_label.connect("close-clicked", close_page, vbox)
555            self.viewernb.append_page(vbox, tab_label)
556
557
558        if buildnow:
559            # uhm.. nice, we already have the results.
560            buildtv(query, returned)
561           
562        else:
563            # no results yet, will get them now!
564            host_matches = { }
565
566            for key, values in returned.items():
567                host_id = key
568                inv_id = values[0]
569                host_addr = values[1]
570                date = values[2]
571                res = self.invsearch.search(host_id, query)
572                if res: # res = category returned
573                    host_matches[(inv_id, host_addr, res)] = date
574                   
575            # build treeview now
576            buildtv(query, host_matches)
577           
578
579    def _create_ui_manager(self):
580        """
581        Set up user interface.
582        """
583        self.ui_manager = gtk.UIManager()
584        self.main_action_group = gtk.ActionGroup("MainActionGroup")
585       
586        about_icon = None
587        try: about_icon = gtk.STOCK_ABOUT
588        except: pass
589       
590        main_actions = [ \
591            ("File", None, _("_File"), None),
592            ("Edit", None, _("_Edit"), None),
593            ("Scheduler", None, _("_Scheduler"), None),
594            ("Help", None, _("_Help"), None),
595           
596            ("ToolbarOpt", None, _("Tool_bar"), None),
597            ("InvTabs", None, _("Devices _tab"), None),
598            ("Inventory", None, _("_Inventories"), None),
599
600            # File
601            ("New", 
602             gtk.STOCK_NEW, _("_New Inventory"), 
603             None, _("Create new Inventory"), 
604             self._create_new),
605           
606            ("CloseHostTab", 
607             None, _("Close Device tab"), 
608             "<Control>W", _("Close current host tab"), 
609             self._close_current_hosttab),
610           
611            ("CloseInvTab", 
612             None, _("Close Inventory tab"),
613             "<Shift><Control>W", _("Close current Inventory tab"), 
614             self._close_current_invtab),
615           
616            ("Quit", 
617             gtk.STOCK_QUIT, _("_Quit"), 
618             None, _("Close Network Inventory"), 
619             self._exit_ni),
620           
621            # Edit
622            ('Control Data Removal', 
623             None, _("Data Removal"), 
624             None, _("Data Removal"), 
625             self._edit_data_removal),
626
627            ('Startup', 
628             None, _("Startup settings"), 
629             None, _("Startup settings"), 
630             self._edit_startup),
631           
632            # Scheduler
633            # Scheduler log
634            ('Sched Log', 
635             None, _("Scheduler log"), 
636             None, _("View Scheduler log"), 
637             self._open_sched_log),
638           
639            # Scheduler status
640            ('Sched Control', 
641             self.schedctrl.stock_icon, self.schedctrl.status_text,
642             None, self.schedctrl.status_text,
643             self.schedctrl._scheduler_control),
644           
645            # Help
646            ('Show Help',
647             gtk.STOCK_HELP, _('_Help'),
648             None, _('Shows the application help'),
649             self._show_help),
650
651            ('Report a bug',
652             gtk.STOCK_DIALOG_INFO, _('_Report a bug'),
653             '<Control>b', _("Report a bug"),
654             self._show_bug_report),
655           
656            ('About', 
657             about_icon, _("_About"), 
658             '<Control>a', _("About UMIT Network Inventory"), 
659             self._show_about)
660           
661        ]
662       
663        inventories = [ ]
664        invmenu = ''
665        schemas = ConfigParser()
666        schemas.read(Path.sched_schemas)
667        for section in schemas.sections():
668            for item in schemas.items(section):
669                if item[0] == 'addtoinv':
670                    if item[1] in ('1', '2'):
671                        inventories.append((section, None, section, None,
672                                            _("Edit Inventory %s") % section,
673                                            self._edit_inventory))
674                        invmenu += "<menuitem action='%s' />" % section
675   
676        toggle_actions = [ \
677            # Edit
678            ("ShowTips", 
679             None, _("Show ti_ps"), 
680             None, _("Enable disable tip showing"),
681             lambda c: self.set_write_tips(not self.write_tips),
682             self.write_tips),
683
684            # Edit/Notebooks
685            ("TabCloseBtn", 
686             None, _("Place close button"), 
687             None, _("Place a close button upon tab creation"),
688             lambda c: self.set_invnb_cbtn(not self.invnb_close_btn),
689             self.invnb_close_btn)
690        ]
691       
692        default_ui = """
693            <menubar>
694                <menu action='File'>
695                    <menuitem action='New' />
696                    <separator />
697                    <menuitem action='CloseHostTab' />
698                    <menuitem action='CloseInvTab' />
699                    <menuitem action='Quit' />
700                </menu>
701                <menu action='Edit'>
702                    <menu action='InvTabs'>
703                         <menuitem action='TabCloseBtn' />
704                    </menu>
705                    <menu action='Inventory'>
706                         %s
707                    </menu>
708                    <menuitem action='ShowTips' />
709                    <menuitem action='Control Data Removal' />
710                    <menuitem action='Startup' />
711                </menu>
712                <menu action='Scheduler'>
713                    <menuitem action='Sched Log' />
714                    <menuitem action='Sched Control' />
715                </menu>
716                <menu action='Help'>
717                    <menuitem action='Show Help' />
718                    <menuitem action='Report a bug' />
719                    <menuitem action='About' />
720                </menu>
721            </menubar>
722            <toolbar>
723                <toolitem action='Sched Control' />
724                <separator />
725                <toolitem action='Report a bug' />
726                <toolitem action='Show Help' />
727            </toolbar>
728            """ % invmenu
729
730        self.main_action_group.add_actions(main_actions)
731        self.main_action_group.add_actions(inventories)
732        self.main_action_group.add_toggle_actions(toggle_actions)
733
734        for action in self.main_action_group.list_actions():
735            action.set_accel_group(self.main_accel_group)
736            action.connect_accelerator()
737       
738        self.ui_manager.insert_action_group(self.main_action_group, 0)
739        self.ui_manager.add_ui_from_string(default_ui)
740       
741        self.schedctrl.ui_action = self.main_action_group.get_action('Sched Control')
742
743       
744    def _edit_data_removal(self, event):
745        """
746        Open window for editing data removal for Inventories.
747        """
748        w = ConfigureDataRemoval()
749        w.show_all()
750       
751       
752    def _edit_inventory(self, event):
753        """
754        Open inventory for editing.
755        """
756        w = NewInventory(event.get_name(), edit_mode=True)
757        w.show_all()
758   
759       
760    def _create_new(self, event):
761        """
762        Open dialog for creating New Inventory.
763        """
764        w = NewInventory()
765        w.show_all()
766       
767       
768    def _open_sched_log(self, event):
769        """
770        Open scheduler log.
771        """
772        winlog = SchedLog()
773        winlog.show_all()
774   
775   
776    def _edit_startup(self, event):
777        """
778        Open window for editing startup settings.
779        """
780        settwin = NISettings()
781        settwin.show_all()
782
783
784    def _show_help(self, event):
785        """
786        Open help manual.
787        """
788        webbrowser.open("file://%s" % os.path.join(Path.docs_dir, 
789                                                   "help.html"), 
790                                                   new=open_url_as())
791
792
793    def _show_bug_report(self, event):
794        """
795        Open bug report window.
796        """
797        bug = BugReport()
798        bug.show_all()
799
800
801    def _show_about(self, event):
802        """
803        Open about window.
804        """
805        awin = About()
806        awin.show_all()
807       
808
809    def _exit_ni(self, *args):
810        """
811        Do necessary cleanup before destroying window.
812        """
813        # remove tip timer if still running
814        if self.tip_timer != -1:
815            gobject.source_remove(self.tip_timer)
816            self._clear_tip_statusbar()
817       
818        # stop updater timer
819        gobject.source_remove(self.timer_updater)
820       
821        self.hide()
822
823        # remove old data
824        if get_decays()[1]:
825            win = RemoveOldData()
826            win.show_all()
827            win.connect('destroy', self.__leave_ni)
828        else:
829            self.__leave_ni()
830
831
832    def __leave_ni(self, *args):
833        """
834        If you are here, Network Inventory has been cleanedup succesfully.
835        """
836        if self.daddy:
837            self.daddy.running_ni = False
838            self.destroy()
839        else:
840            gtk.main_quit()
841
842
843    def __check_for_updates(self):
844        """
845        Check for some possible visual update needed to be done.
846        """
847        # check for database changes
848        prev_stat = self.db_stat
849        try:
850            possibly_new = os.stat(umitdb).st_mtime
851        except OSError:
852            return True
853
854        if prev_stat != possibly_new:
855            # update viewer
856            self._update_viewer()
857            self.db_stat = possibly_new
858
859        # check for changes in schemas
860        prev_state = self.schema_stat
861        try:
862            possibly_new = os.stat(Path.sched_schemas).st_mtime
863        except OSError:
864            return True
865
866        if prev_state != possibly_new:
867            # update viewer
868            self._update_viewer()
869            self.schema_stat = possibly_new
870           
871        return True
872       
873
874    def __set_props(self):
875        """
876        Set window properties.
877        """
878        self.set_title(_("UMIT Network Inventory"))
879        self.invnb.set_scrollable(True)
880        self.viewernb.set_scrollable(True)
881        # a size for testing
882        self.set_position(gtk.WIN_POS_CENTER)
883        width, height = gtk.gdk.get_default_root_window().get_size()
884        self.set_default_size((width * 3) / 4, (height * 3) / 4)
885       
886
887    def __do_layout(self):
888        """
889        Layout window widgets.
890        """
891        main_vbox = gtk.VBox()
892        main_hpaned = gtk.HPaned()
893        nb_tl_hpaned = gtk.HPaned()
894
895        menubar = self.ui_manager.get_widget('/menubar')
896        main_vbox.pack_start(menubar, False, False, 0)
897       
898        schedbar = self.ui_manager.get_widget('/toolbar')
899        schedbar.set_show_arrow(False)
900        schedbar.set_style(gtk.TOOLBAR_ICONS)
901        toolbar = SearchBar(self, self.invdb)
902       
903        toolbar_box = gtk.HBox()
904        toolbar_box.pack_start(schedbar, False, False, 0)
905        toolbar_box.pack_start(toolbar, True, True, 0)
906        main_vbox.pack_start(toolbar_box, False, False, 0)
907
908        left_pane_box = gtk.VBox()
909        left_pane_box.pack_start(self.invtree, True, True, 0)
910       
911        main_hpaned.add1(left_pane_box)
912        main_hpaned.add2(nb_tl_hpaned)
913
914        # inventories notebook
915        nb_tl_hpaned.pack1(self.invnb, True, False) 
916       
917        self.viewernb.append_page(main_hpaned, gtk.Label(_(" Historic "))) 
918        self.viewernb.append_page(self.timeline, gtk.Label(_(" Timeline ")))
919
920        self.timeline.show_all()
921
922        main_vbox.pack_start(self.viewernb, True, True, 0)
923       
924        sbs_box = gtk.HBox()
925        sbs_box.add(self.tip_statusbar)
926        sbs_box.add(self.std_statusbar)
927        main_vbox.pack_end(sbs_box, False, False, 0)
928
929        self.add(main_vbox)
930   
931   
932    def get_write_tips(self):
933        """
934        Returns True if tips should be written at statusbar, otherwise, False.
935        """
936        return self.__wtips
937   
938   
939    def set_write_tips(self, write):
940        """
941        Sets to write tips or not at statusbar.
942        """
943        self.__wtips = write
944        if not self.write_tips:
945            self.tip_statusbar.pop(self.tip_sb)
946       
947       
948    def get_invnb_cbtn(self):
949        """
950        Returns True if Inventory tabs have a close button placed on them.
951        """
952        return self.__invcbtn
953   
954   
955    def set_invnb_cbtn(self, enable):
956        """
957        Sets to show or not close button in each Inventory tab.
958        """
959        self.__invcbtn = enable
960   
961   
962    # Properties
963    write_tips = property(get_write_tips, set_write_tips)
964    invnb_close_btn = property(get_invnb_cbtn, set_invnb_cbtn)
965   
966
967gobject.signal_new("inventory-activated", InventoryViewer,
968                   gobject.SIGNAL_RUN_LAST,
969                   gobject.TYPE_NONE,
970                   (gobject.TYPE_PYOBJECT,))
971
Note: See TracBrowser for help on using the browser.