summaryrefslogtreecommitdiff
path: root/grc/gui/VariableEditor.py
diff options
context:
space:
mode:
authorAndrej Rode <mail@andrejro.de>2018-06-23 23:41:42 +0200
committerAndrej Rode <mail@andrejro.de>2018-06-24 00:03:35 +0200
commit167a6152bad060fc53dd29e0fa79ef83eff1be5b (patch)
treea01049672d9d7d1bf3d295ed96698a323941f8e8 /grc/gui/VariableEditor.py
parent3c8e6008b092287246234001db7cf1a4038300da (diff)
parentfcd002b6ac82e1e0c1224e24506410ff0833e1aa (diff)
Merge branch 'python3_fix' into next
Manual merge conflict resolution has been applied to following conflicts: * Typos: * gnuradio-runtime/python/gnuradio/ctrlport/GrDataPlotter.py * gr-blocks/python/blocks/qa_wavfile.py * gr-filter/examples/gr_filtdes_api.py * grc/blocks/parameter.xml * gr-uhd/python/uhd/__init__.py * ValueError -> RuntimeError: * gr-blocks/python/blocks/qa_hier_block2.py * relative Imports & other Py3k: * gr-digital/python/digital/psk_constellations.py * gr-digital/python/digital/qam_constellations.py * gr-digital/python/digital/test_soft_decisions.py * gr-digital/python/digital/gfsk.py * SequenceCompleter: * gr-utils/python/modtool/modtool_add.py * gr-utils/python/modtool/modtool_rename.py * gr-utils/python/modtool/modtool_rm.py * Updated API on next: * gr-blocks/grc/blocks_file_source.xml * gr-blocks/python/blocks/qa_file_source_sink.py * gr-qtgui/grc/qtgui_time_sink_x.xml * GRC Py3k Updates: * grc/core/Block.py * grc/core/Constants.py * grc/core/Platform.py * grc/core/utils/odict.py * grc/gui/Actions.py * grc/gui/Block.py * grc/gui/Executor.py * grc/gui/Port.py
Diffstat (limited to 'grc/gui/VariableEditor.py')
-rw-r--r--grc/gui/VariableEditor.py183
1 files changed, 88 insertions, 95 deletions
diff --git a/grc/gui/VariableEditor.py b/grc/gui/VariableEditor.py
index 45f0bb75fc..c179c8bc84 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['import'].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 {}".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