diff options
author | Marcus Müller <marcus@hostalia.de> | 2018-09-21 00:00:57 +0200 |
---|---|---|
committer | Marcus Müller <marcus@hostalia.de> | 2018-09-21 00:00:57 +0200 |
commit | 267d669eb21c514c18a6ee979f5cf247d251f1ad (patch) | |
tree | c6120f5993f82daf13894e8bf905c4169493152e /grc/gui/VariableEditor.py | |
parent | 896d1c9da31963ecf5b0d90942c2af51ca998a69 (diff) | |
parent | 7b20b28a9e5aa4e32ee37e89e7f80d74485344e8 (diff) |
Merge branch 'merge_next' (which merges next)
This has been in the making far too long.
We finally merge the next branch into master, in preparation of
releasing GNU Radio 3.8.
There will be breakage.
There will be awesomeness.
There will be progress in the greatest SDR framework to ever grace the
surface of the earth.
Hold tight for now.
Diffstat (limited to 'grc/gui/VariableEditor.py')
-rw-r--r-- | grc/gui/VariableEditor.py | 183 |
1 files changed, 88 insertions, 95 deletions
diff --git a/grc/gui/VariableEditor.py b/grc/gui/VariableEditor.py index f3d0530ef1..ec4ad611ee 100644 --- a/grc/gui/VariableEditor.py +++ b/grc/gui/VariableEditor.py @@ -1,5 +1,5 @@ """ -Copyright 2015 Free Software Foundation, Inc. +Copyright 2015, 2016 Free Software Foundation, Inc. This file is part of GNU Radio GNU Radio Companion is free software; you can redistribute it and/or @@ -17,50 +17,45 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA """ -from operator import attrgetter +from __future__ import absolute_import -import pygtk -pygtk.require('2.0') -import gtk -import gobject +from gi.repository import Gtk, Gdk, GObject -from . import Actions -from . import Preferences -from . import Utils -from .Constants import DEFAULT_BLOCKS_WINDOW_WIDTH +from . import Actions, Constants, Utils BLOCK_INDEX = 0 ID_INDEX = 1 -class VariableEditorContextMenu(gtk.Menu): +class VariableEditorContextMenu(Gtk.Menu): """ A simple context menu for our variable editor """ + def __init__(self, var_edit): - gtk.Menu.__init__(self) + Gtk.Menu.__init__(self) - self.imports = gtk.MenuItem("Add _Import") + self.imports = Gtk.MenuItem(label="Add _Import") self.imports.connect('activate', var_edit.handle_action, var_edit.ADD_IMPORT) self.add(self.imports) - self.variables = gtk.MenuItem("Add _Variable") + self.variables = Gtk.MenuItem(label="Add _Variable") self.variables.connect('activate', var_edit.handle_action, var_edit.ADD_VARIABLE) self.add(self.variables) - self.add(gtk.SeparatorMenuItem()) + self.add(Gtk.SeparatorMenuItem()) - self.enable = gtk.MenuItem("_Enable") + self.enable = Gtk.MenuItem(label="_Enable") self.enable.connect('activate', var_edit.handle_action, var_edit.ENABLE_BLOCK) - self.disable = gtk.MenuItem("_Disable") + self.disable = Gtk.MenuItem(label="_Disable") self.disable.connect('activate', var_edit.handle_action, var_edit.DISABLE_BLOCK) self.add(self.enable) self.add(self.disable) - self.add(gtk.SeparatorMenuItem()) + self.add(Gtk.SeparatorMenuItem()) - self.delete = gtk.MenuItem("_Delete") + self.delete = Gtk.MenuItem(label="_Delete") self.delete.connect('activate', var_edit.handle_action, var_edit.DELETE_BLOCK) self.add(self.delete) - self.add(gtk.SeparatorMenuItem()) + self.add(Gtk.SeparatorMenuItem()) - self.properties = gtk.MenuItem("_Properties...") + self.properties = Gtk.MenuItem(label="_Properties...") self.properties.connect('activate', var_edit.handle_action, var_edit.OPEN_PROPERTIES) self.add(self.properties) self.show_all() @@ -72,7 +67,7 @@ class VariableEditorContextMenu(gtk.Menu): self.disable.set_sensitive(selected and enabled) -class VariableEditor(gtk.VBox): +class VariableEditor(Gtk.VBox): # Actions that are handled by the editor ADD_IMPORT = 0 @@ -83,23 +78,30 @@ class VariableEditor(gtk.VBox): ENABLE_BLOCK = 5 DISABLE_BLOCK = 6 - def __init__(self, platform, get_flow_graph): - gtk.VBox.__init__(self) - self.platform = platform - self.get_flow_graph = get_flow_graph + __gsignals__ = { + 'create_new_block': (GObject.SignalFlags.RUN_FIRST, None, (str,)), + 'remove_block': (GObject.SignalFlags.RUN_FIRST, None, (str,)) + } + + def __init__(self): + Gtk.VBox.__init__(self) + config = Gtk.Application.get_default().config + self._block = None self._mouse_button_pressed = False + self._imports = [] + self._variables = [] # Only use the model to store the block reference and name. # Generate everything else dynamically - self.treestore = gtk.TreeStore(gobject.TYPE_PYOBJECT, # Block reference - gobject.TYPE_STRING) # Category and block name - self.treeview = gtk.TreeView(self.treestore) + self.treestore = Gtk.TreeStore(GObject.TYPE_PYOBJECT, # Block reference + GObject.TYPE_STRING) # Category and block name + self.treeview = Gtk.TreeView(model=self.treestore) self.treeview.set_enable_search(False) self.treeview.set_search_column(-1) #self.treeview.set_enable_search(True) #self.treeview.set_search_column(ID_INDEX) - self.treeview.get_selection().set_mode('single') + self.treeview.get_selection().set_mode(Gtk.SelectionMode.SINGLE) self.treeview.set_headers_visible(True) self.treeview.connect('button-press-event', self._handle_mouse_button_press) self.treeview.connect('button-release-event', self._handle_mouse_button_release) @@ -107,67 +109,63 @@ class VariableEditor(gtk.VBox): self.treeview.connect('key-press-event', self._handle_key_button_press) # Block Name or Category - self.id_cell = gtk.CellRendererText() + self.id_cell = Gtk.CellRendererText() self.id_cell.connect('edited', self._handle_name_edited_cb) - id_column = gtk.TreeViewColumn("Id", self.id_cell, text=ID_INDEX) + id_column = Gtk.TreeViewColumn("Id", self.id_cell, text=ID_INDEX) id_column.set_name("id") id_column.set_resizable(True) id_column.set_max_width(Utils.scale_scalar(300)) id_column.set_min_width(Utils.scale_scalar(80)) id_column.set_fixed_width(Utils.scale_scalar(100)) - id_column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) + id_column.set_sizing(Gtk.TreeViewColumnSizing.FIXED) id_column.set_cell_data_func(self.id_cell, self.set_properties) self.id_column = id_column self.treeview.append_column(id_column) - self.treestore.set_sort_column_id(ID_INDEX, gtk.SORT_ASCENDING) + self.treestore.set_sort_column_id(ID_INDEX, Gtk.SortType.ASCENDING) # For forcing resize self._col_width = 0 # Block Value - self.value_cell = gtk.CellRendererText() + self.value_cell = Gtk.CellRendererText() self.value_cell.connect('edited', self._handle_value_edited_cb) - value_column = gtk.TreeViewColumn("Value", self.value_cell) + value_column = Gtk.TreeViewColumn("Value", self.value_cell) value_column.set_name("value") value_column.set_resizable(False) value_column.set_expand(True) value_column.set_min_width(Utils.scale_scalar(100)) - value_column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE) + value_column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) value_column.set_cell_data_func(self.value_cell, self.set_value) self.value_column = value_column self.treeview.append_column(value_column) # Block Actions (Add, Remove) - self.action_cell = gtk.CellRendererPixbuf() + self.action_cell = Gtk.CellRendererPixbuf() value_column.pack_start(self.action_cell, False) value_column.set_cell_data_func(self.action_cell, self.set_icon) # Make the scrolled window to hold the tree view - scrolled_window = gtk.ScrolledWindow() - scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) - scrolled_window.add_with_viewport(self.treeview) - scrolled_window.set_size_request(DEFAULT_BLOCKS_WINDOW_WIDTH, -1) - self.pack_start(scrolled_window) + scrolled_window = Gtk.ScrolledWindow() + scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) + scrolled_window.add(self.treeview) + scrolled_window.set_size_request(Constants.DEFAULT_BLOCKS_WINDOW_WIDTH, -1) + self.pack_start(scrolled_window, True, True, 0) # Context menus self._context_menu = VariableEditorContextMenu(self) - self._confirm_delete = Preferences.variable_editor_confirm_delete() + self._confirm_delete = config.variable_editor_confirm_delete() # Sets cell contents - def set_icon(self, col, cell, model, iter): + def set_icon(self, col, cell, model, iter, data): block = model.get_value(iter, BLOCK_INDEX) - if block: - pb = self.treeview.render_icon(gtk.STOCK_CLOSE, gtk.ICON_SIZE_MENU, None) - else: - pb = self.treeview.render_icon(gtk.STOCK_ADD, gtk.ICON_SIZE_MENU, None) - cell.set_property('pixbuf', pb) + cell.set_property('icon-name', 'window-close' if block else 'list-add') - def set_value(self, col, cell, model, iter): + def set_value(self, col, cell, model, iter, data): sp = cell.set_property block = model.get_value(iter, BLOCK_INDEX) # Set the default properties for this column first. # Some set in set_properties() may be overridden (editable for advanced variable blocks) - self.set_properties(col, cell, model, iter) + self.set_properties(col, cell, model, iter, data) # Set defaults value = None @@ -175,14 +173,14 @@ class VariableEditor(gtk.VBox): # Block specific values if block: - if block.get_key() == 'import': - value = block.get_param('import').get_value() - elif block.get_key() != "variable": + if block.key == 'import': + value = block.params['imports'].get_value() + elif block.key != "variable": value = "<Open Properties>" sp('editable', False) sp('foreground', '#0D47A1') else: - value = block.get_param('value').get_value() + value = block.params['value'].get_value() # Check if there are errors in the blocks. # Show the block error as a tooltip @@ -193,13 +191,13 @@ class VariableEditor(gtk.VBox): self.set_tooltip_text(error_message[-1]) else: # Evaluate and show the value (if it is a variable) - if block.get_key() == "variable": - evaluated = str(block.get_param('value').evaluate()) + if block.key == "variable": + evaluated = str(block.params['value'].evaluate()) self.set_tooltip_text(evaluated) # Always set the text value. sp('text', value) - def set_properties(self, col, cell, model, iter): + def set_properties(self, col, cell, model, iter, data): sp = cell.set_property block = model.get_value(iter, BLOCK_INDEX) # Set defaults @@ -209,7 +207,7 @@ class VariableEditor(gtk.VBox): # Block specific changes if block: - if not block.get_enabled(): + if not block.enabled: # Disabled block. But, this should still be editable sp('editable', True) sp('foreground', 'gray') @@ -218,39 +216,32 @@ class VariableEditor(gtk.VBox): if block.get_error_messages(): sp('foreground', 'red') - def update_gui(self): - if not self.get_flow_graph(): - return - self._update_blocks() + def update_gui(self, blocks): + self._imports = [block for block in blocks if block.is_import] + self._variables = [block for block in blocks if block.is_variable] self._rebuild() self.treeview.expand_all() - def _update_blocks(self): - self._imports = filter(attrgetter('is_import'), - self.get_flow_graph().blocks) - self._variables = filter(attrgetter('is_variable'), - self.get_flow_graph().blocks) - def _rebuild(self, *args): self.treestore.clear() imports = self.treestore.append(None, [None, 'Imports']) variables = self.treestore.append(None, [None, 'Variables']) for block in self._imports: - self.treestore.append(imports, [block, block.get_param('id').get_value()]) - for block in sorted(self._variables, key=lambda v: v.get_id()): - self.treestore.append(variables, [block, block.get_param('id').get_value()]) + self.treestore.append(imports, [block, block.params['id'].get_value()]) + for block in sorted(self._variables, key=lambda v: v.name): + self.treestore.append(variables, [block, block.params['id'].get_value()]) def _handle_name_edited_cb(self, cell, path, new_text): block = self.treestore[path][BLOCK_INDEX] - block.get_param('id').set_value(new_text) + block.params['id'].set_value(new_text) Actions.VARIABLE_EDITOR_UPDATE() def _handle_value_edited_cb(self, cell, path, new_text): block = self.treestore[path][BLOCK_INDEX] if block.is_import: - block.get_param('import').set_value(new_text) + block.params['import'].set_value(new_text) else: - block.get_param('value').set_value(new_text) + block.params['value'].set_value(new_text) Actions.VARIABLE_EDITOR_UPDATE() def handle_action(self, item, key, event=None): @@ -259,29 +250,31 @@ class VariableEditor(gtk.VBox): key presses or mouse clicks. Also triggers an update of the flow graph and editor. """ if key == self.ADD_IMPORT: - self.get_flow_graph().add_new_block('import') + self.emit('create_new_block', 'import') elif key == self.ADD_VARIABLE: - self.get_flow_graph().add_new_block('variable') + self.emit('create_new_block', 'variable') elif key == self.OPEN_PROPERTIES: - Actions.BLOCK_PARAM_MODIFY(self._block) + # TODO: This probably isn't working because the action doesn't expect a parameter + #Actions.BLOCK_PARAM_MODIFY() + pass elif key == self.DELETE_BLOCK: - self.get_flow_graph().remove_element(self._block) + self.emit('remove_block', self._block.name) elif key == self.DELETE_CONFIRM: if self._confirm_delete: # Create a context menu to confirm the delete operation - confirmation_menu = gtk.Menu() - block_id = self._block.get_param('id').get_value().replace("_", "__") - confirm = gtk.MenuItem("Delete {0}".format(block_id)) + confirmation_menu = Gtk.Menu() + block_id = self._block.params['id'].get_value().replace("_", "__") + confirm = Gtk.MenuItem(label="Delete {}".format(block_id)) confirm.connect('activate', self.handle_action, self.DELETE_BLOCK) confirmation_menu.add(confirm) confirmation_menu.show_all() - confirmation_menu.popup(None, None, None, event.button, event.time) + confirmation_menu.popup(None, None, None, None, event.button, event.time) else: self.handle_action(None, self.DELETE_BLOCK, None) elif key == self.ENABLE_BLOCK: - self._block.set_enabled(True) + self._block.state = 'enabled' elif key == self.DISABLE_BLOCK: - self._block.set_enabled(False) + self._block.state = 'disabled' Actions.VARIABLE_EDITOR_UPDATE() def _handle_mouse_button_press(self, widget, event): @@ -303,12 +296,12 @@ class VariableEditor(gtk.VBox): if event.button == 1 and col.get_name() == "value": # Make sure this has a block (not the import/variable rows) - if self._block and event.type == gtk.gdk._2BUTTON_PRESS: + if self._block and event.type == Gdk.EventType._2BUTTON_PRESS: # Open the advanced dialog if it is a gui variable - if self._block.get_key() not in ("variable", "import"): + if self._block.key not in ("variable", "import"): self.handle_action(None, self.OPEN_PROPERTIES, event=event) return True - if event.type == gtk.gdk.BUTTON_PRESS: + if event.type == Gdk.EventType.BUTTON_PRESS: # User is adding/removing blocks # Make sure this is the action cell (Add/Remove Icons) if path[2] > col.cell_get_position(self.action_cell)[0]: @@ -321,15 +314,15 @@ class VariableEditor(gtk.VBox): else: self.handle_action(None, self.DELETE_CONFIRM, event=event) return True - elif event.button == 3 and event.type == gtk.gdk.BUTTON_PRESS: + elif event.button == 3 and event.type == Gdk.EventType.BUTTON_PRESS: if self._block: - self._context_menu.update_sensitive(True, enabled=self._block.get_enabled()) + self._context_menu.update_sensitive(True, enabled=self._block.enabled) else: self._context_menu.update_sensitive(False) - self._context_menu.popup(None, None, None, event.button, event.time) + self._context_menu.popup(None, None, None, None, event.button, event.time) # Null handler. Stops the treeview from handling double click events. - if event.type == gtk.gdk._2BUTTON_PRESS: + if event.type == Gdk.EventType._2BUTTON_PRESS: return True return False @@ -346,10 +339,10 @@ class VariableEditor(gtk.VBox): def _handle_key_button_press(self, widget, event): model, path = self.treeview.get_selection().get_selected_rows() if path and self._block: - if self._block.get_enabled() and event.string == "d": + if self._block.enabled and event.string == "d": self.handle_action(None, self.DISABLE_BLOCK, None) return True - elif not self._block.get_enabled() and event.string == "e": + elif not self._block.enabled and event.string == "e": self.handle_action(None, self.ENABLE_BLOCK, None) return True return False |