root/branch/PacketManipulator/Tabs/MainTab.py @ 3311

Revision 3311, 7.4 kB (checked in by nopper, 5 years ago)

Implemented the block selection in the hexview

Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3# Copyright (C) 2008 Adriano Monteiro Marques
4#
5# Author: Francesco Piccinno <stack.box@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
21import gtk
22import Backend
23
24from widgets.HexView import HexView
25from widgets.Expander import AnimatedExpander
26
27from views import UmitView
28
29class ProtocolHierarchy(gtk.ScrolledWindow):
30    def __init__(self, packet):
31        gtk.ScrolledWindow.__init__(self)
32
33        self.__create_widgets()
34        self.__pack_widgets()
35        self.__connect_signals()
36
37        self.proto_icon = None
38
39        root = None
40
41        # We pray to be ordered :(
42        for proto in Backend.get_packet_protos(packet):
43            root = self.store.append(root, [self.proto_icon, "blahh", proto])
44
45    def __create_widgets(self):
46        # Icon / string (like TCP packet with some info?) / hidden
47        self.store = gtk.TreeStore(gtk.gdk.Pixbuf, str, object)
48        self.view = gtk.TreeView(self.store)
49
50        pix = gtk.CellRendererPixbuf()
51        txt = gtk.CellRendererText()
52
53        col = gtk.TreeViewColumn('Name')
54
55        col.pack_start(pix, False)
56        col.pack_start(txt, True)
57
58        col.set_attributes(pix, pixbuf=0)
59        col.set_attributes(txt, text=1)
60
61        self.view.append_column(col)
62
63        self.view.set_grid_lines(gtk.TREE_VIEW_GRID_LINES_BOTH)
64        self.view.set_enable_tree_lines(True)
65        self.view.set_rules_hint(True)
66
67    def __pack_widgets(self):
68        self.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
69        self.set_shadow_type(gtk.SHADOW_ETCHED_IN)
70
71        self.add(self.view)
72
73    def __connect_signals(self):
74        self.view.enable_model_drag_dest([('text/plain', 0, 0)], gtk.gdk.ACTION_COPY)
75        self.view.connect('drag-data-received', self.__on_drag_data)
76
77    def __on_drag_data(self, widget, ctx, x, y, data, info, time):
78        if data and data.format == 8:
79            ret = self.view.get_dest_row_at_pos(x, y)
80
81            if not ret:
82                self.store.append(None, [None, data.data, data.data, None])
83            else:
84                path, pos = ret
85                print path, pos
86
87            ctx.finish(True, False, time)
88        else:
89            ctx.finish(False, False, time)
90
91    def get_active_protocol(self):
92        """
93        Return the selected protocol or the most
94        important protocol if no selection.
95
96        @return an instance of Protocol or None
97        """
98
99        model, iter = self.view.get_selection().get_selected()
100
101        if not iter:
102            iter = model.get_iter_first()
103
104            if not iter:
105                return None
106
107        obj = model.get_value(iter, 2)
108       
109        assert (isinstance(obj, Backend.Protocol), "Should be a Protocol instance.")
110
111        return obj
112
113
114class SessionPage(gtk.VBox):
115    def __init__(self, proto_name):
116        gtk.VBox.__init__(self)
117
118        self.__create_widgets(Backend.get_proto(proto_name))
119        self.__pack_widgets()
120        self.__connect_signals()
121
122    def __create_widgets(self, proto):
123        self._label = gtk.Label("*" + proto.__name__)
124
125        self.packet = Backend.Packet(proto())
126
127        self.vpaned = gtk.VPaned()
128        self.proto_hierarchy = ProtocolHierarchy(self.packet)
129        self.hexview = HexView()
130
131        self.redraw_hexview()
132
133    def __pack_widgets(self):
134        self.vpaned.pack1(self.proto_hierarchy)
135        self.vpaned.pack2(self.hexview)
136        self.pack_start(self.vpaned)
137
138        self.show_all()
139
140    def __connect_signals(self):
141        pass
142
143    def redraw_hexview(self):
144        """
145        Redraws the hexview
146        """
147        if self.packet:
148            self.hexview.payload = self.packet.get_raw()
149        else:
150            print "redraw_hexview(): no packet!!!"
151            self.hexview.payload = ""
152
153    def get_label(self):
154        return self._label
155
156    label = property(get_label)
157
158class SessionNotebook(gtk.Notebook):
159    def __init__(self):
160        gtk.Notebook.__init__(self)
161
162        self.set_show_border(False)
163        self.set_scrollable(True)
164
165    def create_session(self, proto_name):
166        session = SessionPage(proto_name)
167        self.append_page(session, session.label)
168        self.set_tab_reorderable(session, True)
169
170    def get_current_session(self):
171        """
172        Get the current SessionPage
173
174        @return a SessionPage instance or None
175        """
176
177        idx = self.get_current_page()
178        obj = self.get_nth_page(idx)
179
180        if obj and isinstance(obj, SessionPage):
181            return obj
182
183        return None
184
185class MainTab(UmitView):
186    tab_position = None
187    label_text = "MainTab"
188
189    def __create_widgets(self):
190        "Create the widgets"
191        self.vbox = gtk.VBox(False, 2)
192
193        self.sniff_expander = AnimatedExpander("<b>Sniff perspective</b>", 'sniff_small')
194        self.packet_expander = AnimatedExpander("<b>Packet perspective</b>", 'packet_small')
195
196        self.session_notebook = SessionNotebook()
197
198    def __pack_widgets(self):
199        "Pack the widgets"
200
201        # In the main window we have a perspective like
202        # + Sniff (expander)
203        # |- Protocol Hierarchy (like wireshark)
204        # |_ Hex View (containing the dump of the packet)
205       
206        self.vbox.pack_start(self.sniff_expander)
207        self.vbox.pack_start(self.packet_expander)
208
209        self.packet_expander.add(self.session_notebook)
210        self.sniff_expander.add(gtk.Button("Miao"))
211        #self.vbox.pack_start(self.session_notebook)
212
213        self.session_notebook.drag_dest_set(
214            gtk.DEST_DEFAULT_ALL,
215            [('text/plain', 0, 0)],
216            gtk.gdk.ACTION_COPY
217        )
218
219        self._main_widget.add(self.vbox)
220        self._main_widget.show_all()
221
222    def __connect_signals(self):
223        self.session_notebook.connect('drag-data-received', self.__on_drag_data)
224
225    def create_ui(self):
226        "Create the ui"
227        self.__create_widgets()
228        self.__pack_widgets()
229        self.__connect_signals()
230
231    def get_current_session(self):
232        "@returns the current SessionPage or None"
233        page = self.get_current_page()
234
235        if page and isinstance(page, SessionPage):
236            return page
237        return None
238
239    def get_current_page(self):
240        "@return the current page in notebook or None"
241
242        idx = self.session_notebook.get_current_page()
243        return self.session_notebook.get_nth_page(idx)
244
245    #===========================================================================
246
247    def __on_drag_data(self, widget, ctx, x, y, data, info, time):
248        "drag-data-received callback"
249
250        if data and data.format == 8:
251            proto = data.data
252
253            if Backend.get_proto(proto):
254                self.session_notebook.create_session(data.data)
255                ctx.finish(True, False, time)
256                return True
257
258        ctx.finish(False, False, time)
Note: See TracBrowser for help on using the browser.