00001 """
00002 Copyright 2007 Free Software Foundation, Inc.
00003 This file is part of GNU Radio
00004
00005 GNU Radio Companion is free software; you can redistribute it and/or
00006 modify it under the terms of the GNU General Public License
00007 as published by the Free Software Foundation; either version 2
00008 of the License, or (at your option) any later version.
00009
00010 GNU Radio Companion is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013 GNU General Public License for more details.
00014
00015 You should have received a copy of the GNU General Public License
00016 along with this program; if not, write to the Free Software
00017 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
00018 """
00019
00020
00021
00022
00023 from grc.Constants import *
00024 import pygtk
00025 pygtk.require('2.0')
00026 import gtk
00027 import gobject
00028
00029 NAME_INDEX = 0
00030 KEY_INDEX = 1
00031
00032 class BlockTreeWindow(gtk.VBox):
00033 """The block selection panel."""
00034
00035 def __init__(self, platform, get_flow_graph):
00036 """!
00037 BlockTreeWindow constructor.
00038 Create a tree view of the possible blocks in the platform.
00039 The tree view nodes will be category names, the leaves will be block names.
00040 A mouse double click or button press action will trigger the add block event.
00041 @param platform the particular platform will all block prototypes
00042 @param get_flow_graph get the selected flow graph
00043 """
00044 gtk.VBox.__init__(self)
00045 self.platform = platform
00046 self.get_flow_graph = get_flow_graph
00047
00048 self.treestore = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
00049 self.treeview = gtk.TreeView(self.treestore)
00050 self.treeview.set_enable_search(False)
00051 self.treeview.add_events(gtk.gdk.BUTTON_PRESS_MASK)
00052 self.treeview.connect('button_press_event', self._handle_mouse_button_press)
00053 selection = self.treeview.get_selection()
00054 selection.set_mode('single')
00055 selection.connect('changed', self._handle_selection_change)
00056 renderer = gtk.CellRendererText()
00057 column = gtk.TreeViewColumn('Blocks', renderer, text=NAME_INDEX)
00058 self.treeview.append_column(column)
00059
00060 scrolled_window = gtk.ScrolledWindow()
00061 scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
00062 scrolled_window.add_with_viewport(self.treeview)
00063 scrolled_window.set_size_request(BLOCK_SELECTION_WINDOW_WIDTH, -1)
00064 self.pack_start(scrolled_window)
00065
00066 self.add_button = gtk.Button(None, 'gtk-add')
00067 self.add_button.connect('clicked', self._handle_add_button)
00068 self.pack_start(self.add_button, False)
00069
00070 self.categories = dict()
00071 self.categories[tuple()] = None
00072
00073 self.platform.load_block_tree(self)
00074
00075 self._update_add_button()
00076
00077
00078
00079
00080 def add_block(self, category, block=None):
00081 """!
00082 Add a block with category to this selection window.
00083 Add only the category when block is None.
00084 @param category the category string
00085 @param block the block object or None
00086 """
00087
00088 category = filter(lambda x: x, category.split('/'))
00089
00090 for i in range(len(category)):
00091 sub_category = tuple(category[:i+1])
00092 if sub_category not in self.categories.keys():
00093 iter = self.treestore.insert_before(self.categories[tuple(category[:i])], None)
00094 self.treestore.set_value(iter, NAME_INDEX, '[ %s ]'%category[i])
00095 self.treestore.set_value(iter, KEY_INDEX, '')
00096 self.categories[sub_category] = iter
00097
00098 if block is None: return
00099 iter = self.treestore.insert_before(self.categories[tuple(category)], None)
00100 self.treestore.set_value(iter, NAME_INDEX, block.get_name())
00101 self.treestore.set_value(iter, KEY_INDEX, block.get_key())
00102
00103
00104
00105
00106 def _get_selected_block_key(self):
00107 """!
00108 Get the currently selected block key.
00109 @return the key of the selected block or a empty string
00110 """
00111 selection = self.treeview.get_selection()
00112 treestore, iter = selection.get_selected()
00113 return iter and treestore.get_value(iter, KEY_INDEX) or ''
00114
00115 def _update_add_button(self):
00116 """!
00117 Update the add button's sensitivity.
00118 The button should be active only if a block is selected.
00119 """
00120 key = self._get_selected_block_key()
00121 self.add_button.set_sensitive(bool(key))
00122
00123 def _add_selected_block(self):
00124 """!
00125 Add the selected block with the given key to the flow graph.
00126 """
00127 key = self._get_selected_block_key()
00128 if key: self.get_flow_graph().add_new_block(key)
00129
00130
00131
00132
00133 def _handle_mouse_button_press(self, widget, event):
00134 """!
00135 Handle the mouse button press.
00136 If a left double click is detected, call add selected block.
00137 """
00138 if event.button == 1 and event.type == gtk.gdk._2BUTTON_PRESS:
00139 self._add_selected_block()
00140
00141 def _handle_selection_change(self, selection):
00142 """!
00143 Handle a selection change in the tree view.
00144 If a selection changes, set the add button sensitive.
00145 """
00146 self._update_add_button()
00147
00148 def _handle_add_button(self, widget):
00149 """!
00150 Handle the add button clicked signal.
00151 Call add selected block.
00152 """
00153 self._add_selected_block()
00154