Пример #1
0
class ShortcutsEditor(BasicDialog):
    size = (700, 400)
    title = _("Keyboard shortcuts")

    def __init__(self):
        BasicDialog.__init__(self, size=ShortcutsEditor.size,
                             title=ShortcutsEditor.title)
        self._create_ui()

    def _create_ui(self):
        self.cancel_button.hide()

        hbox = gtk.HBox(spacing=6)
        self.main.remove(self.main.get_child())
        self.main.add(hbox)
        hbox.show()

        self.categories = ObjectList(
            [Column('label', sorted=True, expand=True)],
            get_binding_categories(),
            gtk.SELECTION_BROWSE)
        self.categories.connect('selection-changed',
                                self._on_categories__selection_changed)
        self.categories.set_headers_visible(False)
        self.categories.set_size_request(200, -1)
        hbox.pack_start(self.categories, False, False)
        self.categories.show()

        box = gtk.VBox(spacing=6)
        hbox.pack_start(box)
        box.show()

        self.shortcuts = ObjectList(self._get_columns(), [],
                                    gtk.SELECTION_BROWSE)
        box.pack_start(self.shortcuts)
        self.shortcuts.show()

        self._label = gtk.Label(
            _("You need to restart Stoq for the changes to take effect"))
        box.pack_start(self._label, False, False, 6)

        box.show()

        defaults_button = gtk.Button(_("Reset defaults"))
        defaults_button.connect('clicked', self._on_defaults_button__clicked)
        self.action_area.pack_start(defaults_button, False, False, 6)
        self.action_area.reorder_child(defaults_button, 0)
        defaults_button.show()

    def _on_categories__selection_changed(self, categories, category):
        if not category:
            return
        self.shortcuts.add_list(get_bindings(category.name), clear=True)

    def _on_defaults_button__clicked(self, button):
        old = self.categories.get_selected()
        api.user_settings.remove('shortcuts')
        remove_user_bindings()
        self._label.show()
        self.categories.refresh()
        self.categories.select(old)

    def _get_columns(self):
        return [Column('description', _("Description"), data_type=str,
                       expand=True, sorted=True),
                ShortcutColumn('shortcut', _("Shortcut"), self)]

    def set_binding(self, binding):
        set_user_binding(binding.name, binding.shortcut)
        d = api.user_settings.get('shortcuts', {})
        d[binding.name] = binding.shortcut
        self._label.show()

    def remove_binding(self, binding):
        remove_user_binding(binding.name)
        d = api.user_settings.get('shortcuts', {})
        try:
            del d[binding.name]
        except KeyError:
            pass
        self._label.show()
Пример #2
0
class ShowLastPackets(InformationWindow):
    ## @var win
    #  window
    ## @var visualizer
    #  visualizer
    ## @var viz_node
    #  visualizer node
    ## @var node
    #  the node
    ## @var tx_list
    #  packet transmit list
    ## @var rx_list
    #  packet receive list
    ## @var drop_list
    #  packet drop list
    ## @var packet_capture_options
    #  packet capture options
    ## @var packet_filter_widget
    #  packet filter widget
    ## @var packet_filter_list
    #  list of TypeIdConfig instances
    ## @var op_AND_button
    #  AND button
    ## @var op_OR_button
    #  OR button
    class PacketList(gtk.ScrolledWindow):
        """
        PacketList class
        """
        ## @var table_model
        #  table model
        (
            COLUMN_TIME,
            COLUMN_INTERFACE,
            COLUMN_SIZE,
            COLUMN_CONTENTS,
        ) = range(4)

        def __init__(self):
            """
            Initializer
            @param self this object
            """
            super(ShowLastPackets.PacketList, self).__init__()
            self.set_properties(hscrollbar_policy=gtk.POLICY_AUTOMATIC,
                                vscrollbar_policy=gtk.POLICY_AUTOMATIC)
            self.table_model = gtk.ListStore(*([str] * 4))
            treeview = gtk.TreeView(self.table_model)
            treeview.show()
            self.add(treeview)

            def add_column(descr, colid):
                column = gtk.TreeViewColumn(descr,
                                            gtk.CellRendererText(),
                                            text=colid)
                treeview.append_column(column)

            add_column("Time", self.COLUMN_TIME)
            add_column("Interface", self.COLUMN_INTERFACE)
            add_column("Size", self.COLUMN_SIZE)
            add_column("Contents", self.COLUMN_CONTENTS)

        def update(self, node, packet_list):
            """!
            Update function
            @param self this object
            @param node the node
            @param packet_list packet list
            @return none
            """
            self.table_model.clear()
            for sample in packet_list:
                tree_iter = self.table_model.append()
                if sample.device is None:
                    interface_name = "(unknown)"
                else:
                    interface_name = ns.core.Names.FindName(sample.device)
                    if not interface_name:
                        interface_name = "(interface %i)" % sample.device.GetIfIndex(
                        )
                self.table_model.set(tree_iter, self.COLUMN_TIME,
                                     str(sample.time.GetSeconds()),
                                     self.COLUMN_INTERFACE, interface_name,
                                     self.COLUMN_SIZE,
                                     str(sample.packet.GetSize()),
                                     self.COLUMN_CONTENTS, str(sample.packet))

    def __init__(self, visualizer, node_index):
        """
        Initializer
        @param self this object
        @param visualizer the visualizer object
        @param node_index the node index
        """
        InformationWindow.__init__(self)
        self.win = gtk.Dialog(parent=visualizer.window,
                              flags=gtk.DIALOG_DESTROY_WITH_PARENT
                              | gtk.DIALOG_NO_SEPARATOR,
                              buttons=(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE))
        self.win.connect("response", self._response_cb)
        self.win.set_title("Last packets for node %i" % node_index)
        self.visualizer = visualizer
        self.viz_node = visualizer.get_node(node_index)
        self.node = ns.network.NodeList.GetNode(node_index)

        def smart_expand(expander, vbox):
            if expander.get_expanded():
                vbox.set_child_packing(expander,
                                       expand=True,
                                       fill=True,
                                       padding=0,
                                       pack_type=gtk.PACK_START)
            else:
                vbox.set_child_packing(expander,
                                       expand=False,
                                       fill=False,
                                       padding=0,
                                       pack_type=gtk.PACK_START)

        main_hbox = gtk.HBox(False, 4)
        main_hbox.show()
        main_vbox = gtk.VBox(False, 4)
        main_vbox.show()
        self.win.vbox.add(main_hbox)
        main_hbox.add(main_vbox)

        self.tx_list = self.PacketList()
        self.tx_list.show()
        group = gtk.Expander("Last transmitted packets")
        group.show()
        group.add(self.tx_list)
        main_vbox.pack_start(group, expand=False, fill=False)
        group.connect_after("activate", smart_expand, main_vbox)

        self.rx_list = self.PacketList()
        self.rx_list.show()
        group = gtk.Expander("Last received packets")
        group.show()
        group.add(self.rx_list)
        main_vbox.pack_start(group, expand=False, fill=False)
        group.connect_after("activate", smart_expand, main_vbox)

        self.drop_list = self.PacketList()
        self.drop_list.show()
        group = gtk.Expander("Last dropped packets")
        group.show()
        group.add(self.drop_list)
        main_vbox.pack_start(group, expand=False, fill=False)
        group.connect_after("activate", smart_expand, main_vbox)

        # Packet Filter

        # - options
        self.packet_capture_options = ns.visualizer.PyViz.PacketCaptureOptions(
        )
        self.packet_capture_options.numLastPackets = 100

        packet_filter_vbox = gtk.VBox(False, 4)
        packet_filter_vbox.show()
        main_hbox.add(packet_filter_vbox)

        sel_buttons_box = gtk.HButtonBox()
        sel_buttons_box.show()
        packet_filter_vbox.pack_start(sel_buttons_box, False, False, 4)
        select_all_button = gobject.new(gtk.Button,
                                        label="Sel. All",
                                        visible=True)
        select_none_button = gobject.new(gtk.Button,
                                         label="Sel. None",
                                         visible=True)
        sel_buttons_box.add(select_all_button)
        sel_buttons_box.add(select_none_button)

        self.packet_filter_widget = ObjectList([
            Column('selected', title="Sel.", data_type=bool, editable=True),
            Column('name', title="Header"),
        ],
                                               sortable=True)
        self.packet_filter_widget.show()
        packet_filter_vbox.pack_start(self.packet_filter_widget, True, True, 4)

        class TypeIdConfig(object):
            __slots__ = ['name', 'selected', 'typeid']

        self.packet_filter_list = []  # list of TypeIdConfig instances

        Header = ns.core.TypeId.LookupByName("ns3::Header")
        Trailer = ns.core.TypeId.LookupByName("ns3::Trailer")
        for typeid_i in range(ns.core.TypeId.GetRegisteredN()):
            typeid = ns.core.TypeId.GetRegistered(typeid_i)
            # check if this is a header or trailer subtype
            typeid_tmp = typeid
            type_is_good = False
            while 1:
                if typeid_tmp == Header or typeid_tmp == Trailer:
                    type_is_good = True
                    break
                if typeid_tmp.HasParent():
                    typeid_tmp = typeid_tmp.GetParent()
                else:
                    break
            if not type_is_good:
                continue
            if typeid in [Header, Trailer]:
                continue
            c = TypeIdConfig()
            c.selected = True
            c.name = typeid.GetName()
            c.typeid = typeid
            self.packet_filter_list.append(c)
        self.packet_filter_widget.add_list(self.packet_filter_list)

        def update_capture_options():
            if self.op_AND_button.props.active:
                self.packet_capture_options.mode = ns.visualizer.PyViz.PACKET_CAPTURE_FILTER_HEADERS_AND
            else:
                self.packet_capture_options.mode = ns.visualizer.PyViz.PACKET_CAPTURE_FILTER_HEADERS_OR
            self.packet_capture_options.numLastPackets = 100
            self.packet_capture_options.headers = [
                c.typeid for c in self.packet_filter_list if c.selected
            ]
            self.visualizer.simulation.lock.acquire()
            try:
                self.visualizer.simulation.sim_helper.SetPacketCaptureOptions(
                    self.node.GetId(), self.packet_capture_options)
            finally:
                self.visualizer.simulation.lock.release()

        def sel_all_cb(bt):
            for c in self.packet_filter_list:
                c.selected = True
            self.packet_filter_widget.refresh()
            update_capture_options()

        def sel_none_cb(bt):
            for c in self.packet_filter_list:
                c.selected = False
            self.packet_filter_widget.refresh()
            update_capture_options()

        select_all_button.connect("clicked", sel_all_cb)
        select_none_button.connect("clicked", sel_none_cb)

        op_buttons_box = gtk.HButtonBox()
        op_buttons_box.show()
        packet_filter_vbox.pack_start(op_buttons_box, False, False, 4)
        self.op_AND_button = gobject.new(gtk.RadioButton,
                                         label="AND",
                                         visible=True)
        self.op_OR_button = gobject.new(gtk.RadioButton,
                                        label="OR",
                                        visible=True,
                                        group=self.op_AND_button)
        op_buttons_box.add(self.op_AND_button)
        op_buttons_box.add(self.op_OR_button)
        self.op_OR_button.props.active = True

        self.op_AND_button.connect("toggled",
                                   lambda b: update_capture_options())

        def cell_edited(l, obj, attribute):
            update_capture_options()

        self.packet_filter_widget.connect("cell-edited", cell_edited)

        update_capture_options()

        self.visualizer.add_information_window(self)
        self.win.set_default_size(600, 300)
        self.win.show()

    def _response_cb(self, win, response):
        """!
        Response callback function
        @param self this object
        @param win the window
        @param response the response
        @return none
        """
        self.win.destroy()
        self.visualizer.remove_information_window(self)

    def update(self):
        """!
        Update function
        @param self this object
        @return none
        """
        last_packets = self.visualizer.simulation.sim_helper.GetLastPackets(
            self.node.GetId())

        self.tx_list.update(self.node, last_packets.lastTransmittedPackets)
        self.rx_list.update(self.node, last_packets.lastReceivedPackets)
        self.drop_list.update(self.node, last_packets.lastDroppedPackets)
Пример #3
0
class ListContainer(gtk.HBox):
    """A ListContainer is an :class:`ObjectList` with buttons to be able
    to modify the content of the list.
    Depending on the list_mode, @see :class:`set_list_mode` you will
    have add, remove and edit buttons.

    Signals
    =======
      - B{add-item} (returns item):
        - emitted when the add button is clicked, you're expected to
          return an object here
      - B{remove-item} (item, returns bool):
        - emitted when removing an item,
          you can block the removal from the list by returning False
      - B{edit-item} (item):
        - emitted when editing an item
          you can block the update afterwards by returning False

    :ivar add_button: add button
    :type add_button: :class:`gtk.Button`
    :ivar remove_button: remove button
    :type remove_button: :class:`gtk.Button`
    :ivar edit_button: edit button
    :type edit_button: :class:`gtk.Button`
    """

    gsignal('add-item', retval=object)
    gsignal('remove-item', object, retval=bool)
    gsignal('edit-item', object, retval=bool)
    gsignal('selection-changed', object)

    def __init__(self, columns, orientation=gtk.ORIENTATION_VERTICAL):
        """
        Create a new ListContainer object.
        :param columns: columns for the :class:`kiwi.ui.objectlist.ObjectList`
        :type columns: a list of :class:`kiwi.ui.objectlist.Columns`
        :param orientation: the position where the buttons will be
            placed: at the right (vertically) or at the bottom (horizontally)
            of the list. Defaults to the right of the list.
        :type: gtk.ORIENTATION_HORIZONTAL or gtk.ORIENTATION_VERTICAL
        """
        self._list_type = None

        gtk.HBox.__init__(self)

        self._orientation = orientation

        self._create_ui(columns)
        self.set_list_type(ListType.NORMAL)

    # Private API

    def _create_ui(self, columns):
        self.list = ObjectList(columns)
        self.list.connect('selection-changed',
                          self._on_list__selection_changed)
        self.list.connect('row-activated', self._on_list__row_activated)

        self.add_button = gtk.Button(stock=gtk.STOCK_ADD)
        self.add_button.connect('clicked', self._on_add_button__clicked)

        self.remove_button = gtk.Button(stock=gtk.STOCK_REMOVE)
        self.remove_button.set_sensitive(False)
        self.remove_button.connect('clicked', self._on_remove_button__clicked)

        self.edit_button = gtk.Button(stock=gtk.STOCK_EDIT)
        self.edit_button.set_sensitive(False)
        self.edit_button.connect('clicked', self._on_edit_button__clicked)

        self._vbox = gtk.VBox(spacing=6)

        if self._orientation == gtk.ORIENTATION_VERTICAL:
            self.pack_start(self.list)
            self.list.show()
            self._add_buttons_to_box(self._vbox)
            self._pack_vbox()
        elif self._orientation == gtk.ORIENTATION_HORIZONTAL:
            self._vbox.pack_start(self.list)
            self.list.show()
            hbox = gtk.HBox(spacing=6)
            self._add_buttons_to_box(hbox)
            self._vbox.pack_start(hbox, expand=False)
            hbox.show()
            self._pack_vbox()
        else:
            raise TypeError(
                "buttons_orientation must be gtk.ORIENTATION_VERTICAL "
                " or gtk.ORIENTATION_HORIZONTAL")

    def _add_buttons_to_box(self, box):
        box.pack_start(self.add_button, expand=False)
        box.pack_start(self.remove_button, expand=False)
        box.pack_start(self.edit_button, expand=False)

    def _pack_vbox(self):
        self.pack_start(self._vbox, expand=False, padding=6)
        self._vbox.show()

    def _set_child_packing(self, padding):
        expand = self._orientation == gtk.ORIENTATION_HORIZONTAL

        self.set_child_packing(self._vbox, expand, True, padding,
                               gtk.PACK_START)

    def _add_item(self):
        retval = self.emit('add-item')
        if retval is None:
            return
        elif isinstance(retval, NotImplementedError):
            raise retval

        self.list.append(retval)
        self.list.refresh()

    def _remove_item(self, item):
        retval = self.emit('remove-item', item)
        if retval:
            self.list.remove(item)

    def _edit_item(self, item):
        retval = self.emit('edit-item', item)
        if retval:
            self.list.update(item)

    # Public API

    def add_item(self, item):
        """Appends an item to the list
        :param item: item to append
        """
        self.list.append(item)

    def add_items(self, items):
        """Appends a list of items to the list
        :param items: items to add
        :type items: a sequence of items
        """
        self.list.extend(items)

    def remove_item(self, item):
        """Removes an item from the list
        :param item: item to remove
        """
        self.list.remove(item)

    def update_item(self, item):
        """Updates an item in the list.
        You should call this if you change the object
        :param item: item to update
        """
        self.list.update(item)

    def default_remove(self, item):
        """Asks the user confirmation for removal of an item.
        :param item: a description of the item that will be removed
        :returns: True if the user confirm the removal, False otherwise
        """
        response = yesno(_('Do you want to remove %s ?') %
                         (glib.markup_escape_text(str(item)), ),
                         parent=None,
                         default=gtk.RESPONSE_OK,
                         buttons=((gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
                                  (gtk.STOCK_REMOVE, gtk.RESPONSE_OK)))
        return response == gtk.RESPONSE_OK

    def set_list_type(self, list_type):
        """Sets the kind of list type.
        :param list_type:
        """
        if not isinstance(list_type, ListType):
            raise TypeError("list_type must be a ListType enum")

        self.add_button.set_property(
            'visible', list_type not in [
                ListType.READONLY, ListType.REMOVEONLY, ListType.UNADDABLE
            ])
        self.remove_button.set_property(
            'visible', list_type
            not in [ListType.READONLY, ListType.ADDONLY, ListType.UNREMOVABLE])
        self.edit_button.set_property(
            'visible', list_type not in [
                ListType.READONLY, ListType.ADDONLY, ListType.UNEDITABLE,
                ListType.REMOVEONLY
            ])
        if list_type in [ListType.READONLY, ListType.REMOVEONLY]:
            padding = 0
        else:
            padding = 6
        self._set_child_packing(padding)
        self._list_type = list_type

    def clear(self):
        """Removes all the items in the list"""
        self.list.clear()

    # Callbacks

    def _on_list__selection_changed(self, list, selection):
        object_selected = selection is not None
        self.remove_button.set_sensitive(object_selected)
        self.edit_button.set_sensitive(object_selected)
        self.emit('selection-changed', selection)

    def _on_list__row_activated(self, list, item):
        if self._list_type not in [
                ListType.READONLY, ListType.ADDONLY, ListType.UNEDITABLE
        ]:
            self._edit_item(item)

    def _on_add_button__clicked(self, button):
        self._add_item()

    def _on_remove_button__clicked(self, button):
        self._remove_item(self.list.get_selected())

    def _on_edit_button__clicked(self, button):
        self._edit_item(self.list.get_selected())
Пример #4
0
class ShowLastPackets(InformationWindow):
    ## @var win
    #  window
    ## @var visualizer
    #  visualizer
    ## @var viz_node
    #  visualizer node
    ## @var node
    #  the node
    ## @var tx_list
    #  packet transmit list
    ## @var rx_list
    #  packet receive list
    ## @var drop_list
    #  packet drop list
    ## @var packet_capture_options
    #  packet capture options
    ## @var packet_filter_widget
    #  packet filter widget
    ## @var packet_filter_list
    #  list of TypeIdConfig instances
    ## @var op_AND_button
    #  AND button
    ## @var op_OR_button
    #  OR button
    class PacketList(Gtk.ScrolledWindow):
        """
        PacketList class
        """
        ## @var table_model
        #  table model
        (
            COLUMN_TIME,
            COLUMN_INTERFACE,
            COLUMN_SIZE,
            COLUMN_CONTENTS,
            ) = range(4)

        def __init__(self):
            """
            Initializer
            @param self this object
            """
            super(ShowLastPackets.PacketList, self).__init__()
            self.set_properties(hscrollbar_policy=Gtk.PolicyType.AUTOMATIC,
                                vscrollbar_policy=Gtk.PolicyType.AUTOMATIC)
            self.table_model = Gtk.ListStore(*([str]*4))
            treeview = Gtk.TreeView(self.table_model)
            treeview.show()
            self.add(treeview)

            def add_column(descr, colid):
                column = Gtk.TreeViewColumn(descr, Gtk.CellRendererText(), text=colid)
                treeview.append_column(column)

            add_column("Time", self.COLUMN_TIME)
            add_column("Interface", self.COLUMN_INTERFACE)
            add_column("Size", self.COLUMN_SIZE)
            add_column("Contents", self.COLUMN_CONTENTS)

        def update(self, node, packet_list):
            """!
            Update function
            @param self this object
            @param node the node
            @param packet_list packet list
            @return none
            """
            self.table_model.clear()
            for sample in packet_list:
                tree_iter = self.table_model.append()
                if sample.device is None:
                    interface_name = "(unknown)"
                else:
                    interface_name = ns.core.Names.FindName(sample.device)
                    if not interface_name:
                        interface_name = "(interface %i)" % sample.device.GetIfIndex()
                self.table_model.set(tree_iter,
                                     self.COLUMN_TIME, str(sample.time.GetSeconds()),
                                     self.COLUMN_INTERFACE, interface_name,
                                     self.COLUMN_SIZE, str(sample.packet.GetSize ()),
                                     self.COLUMN_CONTENTS, str(sample.packet)
                                     )


    def __init__(self, visualizer, node_index):
        """
        Initializer
        @param self this object
        @param visualizer the visualizer object
        @param node_index the node index
        """
        InformationWindow.__init__(self)
        self.win = Gtk.Dialog(parent=visualizer.window,
                              flags=Gtk.DialogFlags.DESTROY_WITH_PARENT|Gtk.DialogFlags.NO_SEPARATOR,
                              buttons=(Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE))
        self.win.connect("response", self._response_cb)
        self.win.set_title("Last packets for node %i" % node_index)
        self.visualizer = visualizer
        self.viz_node = visualizer.get_node(node_index)
        self.node = ns.network.NodeList.GetNode(node_index)

        def smart_expand(expander, vbox):
            if expander.get_expanded():
                vbox.set_child_packing(expander, expand=True, fill=True, padding=0, pack_type=Gtk.PACK_START)
            else:
                vbox.set_child_packing(expander, expand=False, fill=False, padding=0, pack_type=Gtk.PACK_START)

        main_hbox = Gtk.HBox(False, 4)
        main_hbox.show()
        main_vbox = Gtk.VBox(False, 4)
        main_vbox.show()
        self.win.vbox.add(main_hbox)
        main_hbox.add(main_vbox)

        self.tx_list = self.PacketList()
        self.tx_list.show()
        group = Gtk.Expander("Last transmitted packets")
        group.show()
        group.add(self.tx_list)
        main_vbox.pack_start(group, expand=False, fill=False)
        group.connect_after("activate", smart_expand, main_vbox)

        self.rx_list = self.PacketList()
        self.rx_list.show()
        group = Gtk.Expander("Last received packets")
        group.show()
        group.add(self.rx_list)
        main_vbox.pack_start(group, expand=False, fill=False)
        group.connect_after("activate", smart_expand, main_vbox)

        self.drop_list = self.PacketList()
        self.drop_list.show()
        group = Gtk.Expander("Last dropped packets")
        group.show()
        group.add(self.drop_list)
        main_vbox.pack_start(group, expand=False, fill=False)
        group.connect_after("activate", smart_expand, main_vbox)


        # Packet Filter

        # - options
        self.packet_capture_options = ns.visualizer.PyViz.PacketCaptureOptions()
        self.packet_capture_options.numLastPackets = 100

        packet_filter_vbox = Gtk.VBox(False, 4)
        packet_filter_vbox.show()
        main_hbox.add(packet_filter_vbox)

        sel_buttons_box = Gtk.HButtonBox()
        sel_buttons_box.show()
        packet_filter_vbox.pack_start(sel_buttons_box, False, False, 4)
        select_all_button = GObject.new(Gtk.Button, label="Sel. All", visible=True)
        select_none_button = GObject.new(Gtk.Button, label="Sel. None", visible=True)
        sel_buttons_box.add(select_all_button)
        sel_buttons_box.add(select_none_button)

        self.packet_filter_widget = ObjectList([
                Column('selected', title="Sel.", data_type=bool, editable=True),
                Column('name', title="Header"),
                ], sortable=True)
        self.packet_filter_widget.show()
        packet_filter_vbox.pack_start(self.packet_filter_widget, True, True, 4)

        class TypeIdConfig(object):
            __slots__ = ['name', 'selected', 'typeid']

        self.packet_filter_list = [] # list of TypeIdConfig instances

        Header = ns.core.TypeId.LookupByName("ns3::Header")
        Trailer = ns.core.TypeId.LookupByName("ns3::Trailer")
        for typeid_i in range(ns.core.TypeId.GetRegisteredN()):
            typeid = ns.core.TypeId.GetRegistered(typeid_i)
            # check if this is a header or trailer subtype
            typeid_tmp = typeid
            type_is_good = False
            while 1:
                if typeid_tmp == Header or typeid_tmp == Trailer:
                    type_is_good = True
                    break
                if typeid_tmp.HasParent():
                    typeid_tmp = typeid_tmp.GetParent()
                else:
                    break
            if not type_is_good:
                continue
            if typeid in [Header, Trailer]:
                continue
            c = TypeIdConfig()
            c.selected = True
            c.name = typeid.GetName()
            c.typeid = typeid
            self.packet_filter_list.append(c)
        self.packet_filter_widget.add_list(self.packet_filter_list)

        def update_capture_options():
            if self.op_AND_button.props.active:
                self.packet_capture_options.mode = ns.visualizer.PyViz.PACKET_CAPTURE_FILTER_HEADERS_AND
            else:
                self.packet_capture_options.mode = ns.visualizer.PyViz.PACKET_CAPTURE_FILTER_HEADERS_OR
            self.packet_capture_options.numLastPackets = 100
            self.packet_capture_options.headers = [c.typeid for c in self.packet_filter_list if c.selected]
            self.visualizer.simulation.lock.acquire()
            try:
                self.visualizer.simulation.sim_helper.SetPacketCaptureOptions(
                    self.node.GetId(), self.packet_capture_options)
            finally:
                self.visualizer.simulation.lock.release()

        def sel_all_cb(bt):
            for c in self.packet_filter_list:
                c.selected = True
            self.packet_filter_widget.refresh()
            update_capture_options()

        def sel_none_cb(bt):
            for c in self.packet_filter_list:
                c.selected = False
            self.packet_filter_widget.refresh()
            update_capture_options()

        select_all_button.connect("clicked", sel_all_cb)
        select_none_button.connect("clicked", sel_none_cb)

        op_buttons_box = Gtk.HButtonBox()
        op_buttons_box.show()
        packet_filter_vbox.pack_start(op_buttons_box, False, False, 4)
        self.op_AND_button = GObject.new(Gtk.RadioButton, label="AND", visible=True)
        self.op_OR_button = GObject.new(Gtk.RadioButton, label="OR", visible=True, group=self.op_AND_button)
        op_buttons_box.add(self.op_AND_button)
        op_buttons_box.add(self.op_OR_button)
        self.op_OR_button.props.active = True

        self.op_AND_button.connect("toggled", lambda b: update_capture_options())

        def cell_edited(l, obj, attribute):
            update_capture_options()
        self.packet_filter_widget.connect("cell-edited", cell_edited)

        update_capture_options()

        self.visualizer.add_information_window(self)
        self.win.set_default_size(600, 300)
        self.win.show()

    def _response_cb(self, win, response):
        """!
        Response callback function
        @param self this object
        @param win the window
        @param response the response
        @return none
        """
        self.win.destroy()
        self.visualizer.remove_information_window(self)

    def update(self):
        """!
        Update function
        @param self this object
        @return none
        """
        last_packets = self.visualizer.simulation.sim_helper.GetLastPackets(self.node.GetId())

        self.tx_list.update(self.node, last_packets.lastTransmittedPackets)
        self.rx_list.update(self.node, last_packets.lastReceivedPackets)
        self.drop_list.update(self.node, last_packets.lastDroppedPackets)
Пример #5
0
class ListDialog:
    """ Diálogo de edição de uma tabela com botões padrão e uma lista de campos. """
    def __init__(self, controle, tabela, titulo):
        """ controle é um objeto da classe Controle.
            tabela é o nome de uma instancia de Classe no Controle que referencia um tabela no Modelo.
            titulo é nome de leitura da tabela sendo editada (ex. 'Categorias') """
        self.controle = controle
        self.tabela = tabela
        self.data = []
        self.buttons = []
        self.new_method = self.create_new_record
        self.save_method = self.salvar
        self.populate_method = self.populate
        self.titulo = titulo or self.tabela.nome_tabela
        self.edit_mode = False
        self.editing_new = False
        self.editing = False
        self.selection = None
        self.do_nothing = False

    def make_widget(self, fields, custom_buttons = []):
        """ Cria e retorna o widget que contém o toolbar, a lista e os campos para edição.
            fields é uma lista de FieldType.
            custom_buttons é uma lista de ListToolButton que substitui os botões padrão. """
#-------Campos
        self.fields = []
        
        for field in fields:
            if field.show_field:
                field.label = gtk.Label(field.titulo + ":")
                if field.tabelacombo:
                    field.entry = ComboEntry()
                    tabelacombo = getattr(self.controle, field.tabelacombo)
                    itens = tabelacombo.combo()
                    field.entry.prefill(itens)
                else:
                    field.entry = ProxyEntry(field.tipo)
                    field.entry.set_mask(field.mask)
            self.fields.append(field)
        
        vbox_main = gtk.VBox()
        hbox_topo = gtk.HBox()
        
        self.widget = gtk.EventBox()
#-------Toolbar
        toolbar = gtk.Toolbar()
        toolbar.set_orientation(gtk.ORIENTATION_VERTICAL)
        toolbar.set_style(gtk.TOOLBAR_BOTH)
        
        if not custom_buttons:
            self.tb_novo = ListToolButton(self.default_new, gtk.STOCK_NEW)
            self.tb_edit = ListToolButton(self.default_edit, gtk.STOCK_EDIT)
            self.custom_buttons = [self.tb_novo, self.tb_edit]
        else:
            self.custom_buttons = custom_buttons 

        for tool_button in self.custom_buttons:
            toolbar.insert(tool_button.button, -1)
        
#-------Lista
        vbox_lista = gtk.VBox()
        hbox_entry = gtk.HBox()
        
        self.entry_localizar = gtk.Entry()
        self.entry_localizar.connect('activate', self.localizar)
        label = gtk.Label('Localizar')
        
        frame_lista = gtk.Frame(self.titulo)
        self.listview = self.create_list()
        self.listview.connect("row_activated", self.on_row_activated)
        self.listview.connect('selection-changed',self.on_selection_changed)
        
#-------Frame
        frame_dados = gtk.Frame("Informações")
        hbox_dados = gtk.HBox(False, 6)
        vbox_label = gtk.VBox(True, 4)
        vbox_entry = gtk.VBox(True, 4)
         
        for field in self.fields:
            if field.show_field:
                vbox_label.pack_start(field.label, False, True, 8)
                vbox_entry.pack_start(field.entry, False, True, 8)
        
        #Botões
        self.button_save = gtk.Button(stock=gtk.STOCK_SAVE)
        self.button_save.connect("clicked", self.save_method)
        self.button_cancel = gtk.Button(stock=gtk.STOCK_CANCEL)
        self.button_cancel.connect("clicked", self.cancel)
        
        vbox_dados_buttons = gtk.VButtonBox()
        vbox_dados_buttons.set_layout(gtk.BUTTONBOX_SPREAD)
        vbox_dados_buttons.add(self.button_save)
        vbox_dados_buttons.add(self.button_cancel)
        
#-------Notify
        self.notify = self.controle.notify()
        self.notify_box = self.notify.get_widget()
        self.notify.show_notify('info','Clique em NOVO para adicionar um novo item')
        self.tabela.set_notify(self.notify)

#-------Posicionar todos
        frame_lista.add(self.listview)
        vbox_lista.pack_start(hbox_entry, False, False, 2)
        vbox_lista.pack_start(frame_lista, True, True, 2)
        hbox_entry.pack_end(self.entry_localizar, False, False, 2)
        hbox_entry.pack_end(label, False, False, 2)
        hbox_topo.pack_start(toolbar, False, False, 5)
        hbox_topo.pack_start(vbox_lista, True, True, 2)
        hbox_dados.pack_start(vbox_label, False, False, 2)
        hbox_dados.pack_start(vbox_entry, True, True, 2)
        hbox_dados.pack_start(vbox_dados_buttons, False, False, 2)
        frame_dados.add(hbox_dados)
        vbox_main.pack_start(hbox_topo, True, True, 2)
        vbox_main.pack_start(frame_dados, False, False, 2)
        vbox_main.pack_start(self.notify_box, False, True, 2)
        self.widget.add(vbox_main)
        
        self.set_edit_mode(False)
        return self.widget

    def create_list(self):
        columns = []
        for field in self.fields:
            if field.show_in_list:
                columns.append(Column(field.field_name, data_type = field.tipo, title = field.titulo))
        self.lista = ObjectList(columns)
        self.data = self.populate_method()
        self.lista.extend(self.data)
        return self.lista

    def localizar(self, entry):
        text = self.entry_localizar.get_text().lower()
        searches = text.split(" ")
        if not searches: #lista vazia
            lista = self.data
        else:
            lista = []
            for item in self.data:
                itemtext = ""
                #reúne o texto inteiro do item (separado por espaço):
                for field in self.fields:
                    if field.searchable:
                        itemtext += str(getattr(item, field.field_name)).lower() + " "
                contain_all = True
                for searchtext in searches:
                    if searchtext not in itemtext:
                        contain_all = False
                if contain_all:
                    lista.append(item)
        self.lista.add_list(lista)

    def set_edit_mode(self, edit_mode):
        """ Coloca ou tira os campos em modo de edição. """
        for field in self.fields:
            if field.entry:
                field.entry.set_sensitive(edit_mode)
        
        for tool_button in self.custom_buttons:
            tool_button.button.set_sensitive(not edit_mode)
        
        self.entry_localizar.set_sensitive(not edit_mode)
        self.button_save.set_sensitive(edit_mode)
        self.button_cancel.set_sensitive(edit_mode)
        self.editing = edit_mode
        
    def cancel(self, widget):
        """Cancela a edição de um item"""
        self.set_edit_mode(False)
        self.clear_entry()
        self.lista.refresh()
        if self.editing_new:
            self.lista.remove(self.newobj)
            self.editing_new = False
            
        self.notify.show_notify('info','Clique em NOVO para adicionar um novo item')
            
    def create_new_record(self):
        """Adiciona um item padrão a lista para depois ser editado"""
        self.notify.hide()
        obj = ListItem()
        for field in self.fields:
            if field.tipo == str or field.tabelacombo:
                setattr(obj, field.field_name, '')
            else:
                setattr(obj, field.field_name, converter.from_string(field.tipo, '0'))
        return obj

    def populate(self):
        """Popula a lista com os itens"""
        itens = self.tabela.listar()
        objetos = []
        for item in itens:
            obj = ListItem()
            for field in self.fields:
                if not field.tabelacombo:
                    setattr(obj, field.field_name, item[field.field_name])
                else:
                    tabelacombo = getattr(self.controle, field.tabelacombo)
                    descricao = tabelacombo.item_descricao(item[field.field_name])
                    try:
                        setattr(obj, field.field_name, descricao[0][0])
                    except:
                        setattr(obj, field.field_name, descricao)
            objetos.append(obj)
        return objetos
        
    def default_new(self, sender):
        self.newobj = self.new_method() #Chama new_method para criar um novo item
        self.data.append(self.newobj)
        self.listview.append(self.newobj)
        self.listview.refresh()
        self.listview.select(self.newobj)
        self.set_edit_mode(True)
        self.editing_new = True
        self.item = self.selection
        
    def default_edit(self, sender):
        if self.selection:
            self.populate_entry(self.selection)
            self.set_edit_mode(True)
            self.item = self.selection
        
    def on_row_activated(self, list, item):
        """Preenche os campos com os valores da coluna clicada e coloca em modo de edição"""
        self.item = item
        self.populate_entry(item)
        
    def populate_entry(self, item):
        """Preenche os campos com os itens"""
        self.notify.hide()
        for field in self.fields:
            if field.entry:
                if field.tabelacombo:
                    field.entry.select_item_by_label(str(getattr(item, field.field_name)))
                else:
                    field.entry.set_text(str(getattr(item, field.field_name)))
        self.set_edit_mode(True)
        
    def clear_entry(self):
        """Limpa os campos apos edicao ou cancelar"""
        for field in self.fields:
            if field.entry:
                field.entry.set_text('')
        self.set_edit_mode(False)
        
    def on_selection_changed(self, list, selection):
        """Verifica se o usuario editou os campos e não salvou"""
        if self.do_nothing:
            self.do_nothing = False
            return
            
        self.selection = selection
        response = False
        if self.editing == True:
            for field in self.fields:
                if field.entry:
                    if not field.identificador:
                        user_edited = field.entry.get_text()
                        
                        #Se for um novo item
                        if self.editing_new == True:
                            if user_edited:
                                response = self.ask_to_save(field)
                                if response == True:
                                    self.salvar(None)
                                else:
                                    self.cancel(None)
                            else:
                                if response:
                                        self.do_nothing = True
                                        self.listview.select(self.item)
                                else:
                                    self.cancel(None)

                        #Se editando item da lista
                        elif self.editing == True:
                            field_in_list = (str(getattr(self.item, field.field_name)))
                            if user_edited != field_in_list:
                                response = self.ask_to_save(field)
                                if response == True:
                                    self.salvar(None)
                                else:
                                    self.cancel(None)
                            else:
                                if response:
                                        self.do_nothing = True
                                        self.listview.select(self.item)
        
    def ask_to_save(self, field):
        """Pergunta ao usuario sobre a edicao de campos"""
        #Criando um novo
        if self.editing_new : 
            question =str('Deseja salvar %s ?')
            for field in self.fields:
                if field.searchable:
                    registro = quote(str(field.entry.get_text()))
        #Editando
        else:
            question =str('Deseja salvar alterações em %s ?')
            registro = quote(str(getattr(self.item, field.field_name)))
            
        response = yesno((question) % (registro,),
                         parent=None,
                         default=gtk.RESPONSE_OK,
                         buttons=((gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
                                  (gtk.STOCK_SAVE, gtk.RESPONSE_OK)))
        return response == gtk.RESPONSE_OK
        
    def salvar(self, widget):
        """Insere ou edita um registro na tabela"""
        record = {}
        #Insere novo
        if self.editing_new :
            record = self.tabela.insert(self.fields)
            if record :
                for field in self.fields:
                    if field.identificador:
                        setattr(self.newobj, field.field_name, record['last_id'])
                    elif field.tabelacombo:
                        tabelacombo = getattr(self.controle, field.tabelacombo)
                        descricao = tabelacombo.item_descricao(record[field.field_name])
                        setattr(self.newobj, field.field_name, descricao[0][0])
                    else:
                        setattr(self.newobj, field.field_name, record[field.field_name])
                self.editing_new = False
                self.lista.refresh()
                self.clear_entry()
                self.hide_notify()
         #Edita
        else:
            record = self.tabela.update(self.fields, self.item)
            if record:
                for field in self.fields:
                    if field.identificador:
                        pass
                    elif field.tabelacombo:
                        tabelacombo = getattr(self.controle, field.tabelacombo)
                        descricao = tabelacombo.item_descricao(record[field.field_name])
                        try:
                            setattr(self.item, field.field_name, descricao[0][0])
                        except:
                            setattr(self.item, field.field_name, descricao)
                    else:
                        setattr(self.item, field.field_name, record[field.field_name])
                self.lista.refresh()
                self.clear_entry()
                self.hide_notify()
        
    def hide_notify(self):
        self.notify.hide()
Пример #6
0
class ListContainer(gtk.HBox):
    """A ListContainer is an :class:`ObjectList` with buttons to be able
    to modify the content of the list.
    Depending on the list_mode, @see :class:`set_list_mode` you will
    have add, remove and edit buttons.

    Signals
    =======
      - B{add-item} (returns item):
        - emitted when the add button is clicked, you're expected to
          return an object here
      - B{remove-item} (item, returns bool):
        - emitted when removing an item,
          you can block the removal from the list by returning False
      - B{edit-item} (item):
        - emitted when editing an item
          you can block the update afterwards by returning False

    :ivar add_button: add button
    :type add_button: :class:`gtk.Button`
    :ivar remove_button: remove button
    :type remove_button: :class:`gtk.Button`
    :ivar edit_button: edit button
    :type edit_button: :class:`gtk.Button`
    """

    gsignal('add-item', retval=object)
    gsignal('remove-item', object, retval=bool)
    gsignal('edit-item', object, retval=bool)
    gsignal('selection-changed', object)

    def __init__(self, columns, orientation=gtk.ORIENTATION_VERTICAL):
        """
        Create a new ListContainer object.
        :param columns: columns for the :class:`kiwi.ui.objectlist.ObjectList`
        :type columns: a list of :class:`kiwi.ui.objectlist.Columns`
        :param orientation: the position where the buttons will be
            placed: at the right (vertically) or at the bottom (horizontally)
            of the list. Defaults to the right of the list.
        :type: gtk.ORIENTATION_HORIZONTAL or gtk.ORIENTATION_VERTICAL
        """
        self._list_type = None

        gtk.HBox.__init__(self)

        self._orientation = orientation

        self._create_ui(columns)
        self.set_list_type(ListType.NORMAL)

    # Private API

    def _create_ui(self, columns):
        self.list = ObjectList(columns)
        self.list.connect('selection-changed',
                          self._on_list__selection_changed)
        self.list.connect('row-activated',
                          self._on_list__row_activated)

        self.add_button = gtk.Button(stock=gtk.STOCK_ADD)
        self.add_button.connect('clicked', self._on_add_button__clicked)

        self.remove_button = gtk.Button(stock=gtk.STOCK_REMOVE)
        self.remove_button.set_sensitive(False)
        self.remove_button.connect('clicked', self._on_remove_button__clicked)

        self.edit_button = gtk.Button(stock=gtk.STOCK_EDIT)
        self.edit_button.set_sensitive(False)
        self.edit_button.connect('clicked', self._on_edit_button__clicked)

        self._vbox = gtk.VBox(spacing=6)

        if self._orientation == gtk.ORIENTATION_VERTICAL:
            self.pack_start(self.list)
            self.list.show()
            self._add_buttons_to_box(self._vbox)
            self._pack_vbox()
        elif self._orientation == gtk.ORIENTATION_HORIZONTAL:
            self._vbox.pack_start(self.list)
            self.list.show()
            hbox = gtk.HBox(spacing=6)
            self._add_buttons_to_box(hbox)
            self._vbox.pack_start(hbox, expand=False)
            hbox.show()
            self._pack_vbox()
        else:
            raise TypeError(
                "buttons_orientation must be gtk.ORIENTATION_VERTICAL "
                " or gtk.ORIENTATION_HORIZONTAL")

    def _add_buttons_to_box(self, box):
        box.pack_start(self.add_button, expand=False)
        box.pack_start(self.remove_button, expand=False)
        box.pack_start(self.edit_button, expand=False)

    def _pack_vbox(self):
        self.pack_start(self._vbox, expand=False, padding=6)
        self._vbox.show()

    def _set_child_packing(self, padding):
        expand = self._orientation == gtk.ORIENTATION_HORIZONTAL

        self.set_child_packing(self._vbox, expand, True, padding,
                               gtk.PACK_START)

    def _add_item(self):
        retval = self.emit('add-item')
        if retval is None:
            return
        elif isinstance(retval, NotImplementedError):
            raise retval

        self.list.append(retval)
        self.list.refresh()

    def _remove_item(self, item):
        retval = self.emit('remove-item', item)
        if retval:
            self.list.remove(item)

    def _edit_item(self, item):
        retval = self.emit('edit-item', item)
        if retval:
            self.list.update(item)

    # Public API

    def add_item(self, item):
        """Appends an item to the list
        :param item: item to append
        """
        self.list.append(item)

    def add_items(self, items):
        """Appends a list of items to the list
        :param items: items to add
        :type items: a sequence of items
        """
        self.list.extend(items)

    def remove_item(self, item):
        """Removes an item from the list
        :param item: item to remove
        """
        self.list.remove(item)

    def update_item(self, item):
        """Updates an item in the list.
        You should call this if you change the object
        :param item: item to update
        """
        self.list.update(item)

    def default_remove(self, item):
        """Asks the user confirmation for removal of an item.
        :param item: a description of the item that will be removed
        :returns: True if the user confirm the removal, False otherwise
        """
        response = yesno(_('Do you want to remove %s ?') %
                        (glib.markup_escape_text(str(item)),),
                         parent=None,
                         default=gtk.RESPONSE_OK,
                         buttons=((gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
                                  (gtk.STOCK_REMOVE, gtk.RESPONSE_OK)))
        return response == gtk.RESPONSE_OK

    def set_list_type(self, list_type):
        """Sets the kind of list type.
        :param list_type:
        """
        if not isinstance(list_type, ListType):
            raise TypeError("list_type must be a ListType enum")

        self.add_button.set_property(
            'visible',
            list_type not in [ListType.READONLY, ListType.REMOVEONLY,
                              ListType.UNADDABLE])
        self.remove_button.set_property(
            'visible',
            list_type not in [ListType.READONLY, ListType.ADDONLY,
                              ListType.UNREMOVABLE])
        self.edit_button.set_property(
            'visible',
            list_type not in [ListType.READONLY, ListType.ADDONLY,
                              ListType.UNEDITABLE, ListType.REMOVEONLY])
        if list_type in [ListType.READONLY, ListType.REMOVEONLY]:
            padding = 0
        else:
            padding = 6
        self._set_child_packing(padding)
        self._list_type = list_type

    def clear(self):
        """Removes all the items in the list"""
        self.list.clear()

    # Callbacks

    def _on_list__selection_changed(self, list, selection):
        object_selected = selection is not None
        self.remove_button.set_sensitive(object_selected)
        self.edit_button.set_sensitive(object_selected)
        self.emit('selection-changed', selection)

    def _on_list__row_activated(self, list, item):
        if self._list_type not in [ListType.READONLY, ListType.ADDONLY,
                                   ListType.UNEDITABLE]:
            self._edit_item(item)

    def _on_add_button__clicked(self, button):
        self._add_item()

    def _on_remove_button__clicked(self, button):
        self._remove_item(self.list.get_selected())

    def _on_edit_button__clicked(self, button):
        self._edit_item(self.list.get_selected())
Пример #7
0
class ShortcutsEditor(BasicDialog):
    size = (700, 400)
    title = _("Keyboard shortcuts")

    def __init__(self):
        BasicDialog.__init__(self,
                             size=ShortcutsEditor.size,
                             title=ShortcutsEditor.title)
        self._create_ui()

    def _create_ui(self):
        self.cancel_button.hide()

        hbox = gtk.HBox(spacing=6)
        self.main.remove(self.main.get_child())
        self.main.add(hbox)
        hbox.show()

        self.categories = ObjectList(
            [Column('label', sorted=True, expand=True)],
            get_binding_categories(), gtk.SELECTION_BROWSE)
        self.categories.connect('selection-changed',
                                self._on_categories__selection_changed)
        self.categories.set_headers_visible(False)
        self.categories.set_size_request(200, -1)
        hbox.pack_start(self.categories, False, False)
        self.categories.show()

        box = gtk.VBox(spacing=6)
        hbox.pack_start(box)
        box.show()

        self.shortcuts = ObjectList(self._get_columns(), [],
                                    gtk.SELECTION_BROWSE)
        box.pack_start(self.shortcuts)
        self.shortcuts.show()

        self._label = gtk.Label(
            _("You need to restart Stoq for the changes to take effect"))
        box.pack_start(self._label, False, False, 6)

        box.show()

        defaults_button = gtk.Button(_("Reset defaults"))
        defaults_button.connect('clicked', self._on_defaults_button__clicked)
        self.action_area.pack_start(defaults_button, False, False, 6)
        self.action_area.reorder_child(defaults_button, 0)
        defaults_button.show()

    def _on_categories__selection_changed(self, categories, category):
        if not category:
            return
        self.shortcuts.add_list(get_bindings(category.name), clear=True)

    def _on_defaults_button__clicked(self, button):
        old = self.categories.get_selected()
        api.user_settings.remove('shortcuts')
        remove_user_bindings()
        self._label.show()
        self.categories.refresh()
        self.categories.select(old)

    def _get_columns(self):
        return [
            Column('description',
                   _("Description"),
                   data_type=str,
                   expand=True,
                   sorted=True),
            ShortcutColumn('shortcut', _("Shortcut"), self)
        ]

    def set_binding(self, binding):
        set_user_binding(binding.name, binding.shortcut)
        d = api.user_settings.get('shortcuts', {})
        d[binding.name] = binding.shortcut
        self._label.show()

    def remove_binding(self, binding):
        remove_user_binding(binding.name)
        d = api.user_settings.get('shortcuts', {})
        try:
            del d[binding.name]
        except KeyError:
            pass
        self._label.show()