summaryrefslogtreecommitdiff
path: root/grc/gui/VariableEditor.py
diff options
context:
space:
mode:
authorMarcus Müller <marcus@hostalia.de>2018-09-21 00:00:57 +0200
committerMarcus Müller <marcus@hostalia.de>2018-09-21 00:00:57 +0200
commit267d669eb21c514c18a6ee979f5cf247d251f1ad (patch)
treec6120f5993f82daf13894e8bf905c4169493152e /grc/gui/VariableEditor.py
parent896d1c9da31963ecf5b0d90942c2af51ca998a69 (diff)
parent7b20b28a9e5aa4e32ee37e89e7f80d74485344e8 (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.py183
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