[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] r8956 - in grc/trunk: notes src/grc src/grc/elements s
From: |
jblum |
Subject: |
[Commit-gnuradio] r8956 - in grc/trunk: notes src/grc src/grc/elements src/grc/gui src/grc/gui/elements src/grc_gnuradio |
Date: |
Sun, 20 Jul 2008 14:50:26 -0600 (MDT) |
Author: jblum
Date: 2008-07-20 14:50:25 -0600 (Sun, 20 Jul 2008)
New Revision: 8956
Added:
grc/trunk/src/grc/BlockTree.py
grc/trunk/src/grc/gui/BlockTreeWindow.py
grc/trunk/src/grc/gui/ParamsDialog.py
Removed:
grc/trunk/src/grc/gui/SignalBlockParamsDialog.py
grc/trunk/src/grc/gui/SignalBlockSelectionWindow.py
Modified:
grc/trunk/notes/todo.txt
grc/trunk/src/grc/Constants.py
grc/trunk/src/grc/elements/Block.py
grc/trunk/src/grc/elements/Platform.py
grc/trunk/src/grc/gui/MainWindow.py
grc/trunk/src/grc/gui/elements/FlowGraph.py
grc/trunk/src/grc_gnuradio/Generator.py
Log:
block tree class and better handling of categories
Modified: grc/trunk/notes/todo.txt
===================================================================
--- grc/trunk/notes/todo.txt 2008-07-20 20:47:16 UTC (rev 8955)
+++ grc/trunk/notes/todo.txt 2008-07-20 20:50:25 UTC (rev 8956)
@@ -1,25 +1,26 @@
-############ Blocks to Add: ####################
--pad source/sink
+############ Blocks to Add: ####################
-hier block
-optparse block
-ofdm wrappers
-############ Features to Add: ####################
+############ Features to Add: ####################
-save working directory after close
-create sub-flow graphs to be used in larger flow graphs
-param editor, expand entry boxes in focus
-change param dialog to panel within main window
-default platform for preferences block
-command line option for additional block wrappers
--block tree class
--dtd for external blocks
-hotkeys in action descriptions
--variables dependent on variables that change
-log slider gui control
-variable resolution graph structure
+-move checks from grc Block to grc_gnuradio specific
+
+############ Problems: ####################
-catch error on open non-existant files
+-block tree window maps block by name
+-variables dependent on variables that change
-############ Suggestions: ####################
+############ Suggestions: ####################
-simple usrp
-tune_result in usrp.py needs __str__ method
Added: grc/trunk/src/grc/BlockTree.py
===================================================================
--- grc/trunk/src/grc/BlockTree.py (rev 0)
+++ grc/trunk/src/grc/BlockTree.py 2008-07-20 20:50:25 UTC (rev 8956)
@@ -0,0 +1,67 @@
+"""
+Copyright 2008 Free Software Foundation, Inc.
+This file is part of GNU Radio
+
+GNU Radio Companion is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+GNU Radio Companion is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+"""
address@hidden grc.BlockTree
+#A Block Tree categorizes blocks keys.
address@hidden Josh Blum
+
+class BlockTree(object):
+
+ def __init__(self):
+ self._block_tree = list()
+
+ def add_block(self, block, category):
+ """!
+ Add the block with category to the block tree.
+ If the category does not exist, create it.
+ @param block the block object
+ @param category the category string
+ """
+ if not self.has_category(category):
+ self.add_category(category)
+ if not self.has_block(block):
+ for _category, _blocks in self._block_tree:
+ if category == _category: _blocks.append(block)
+
+ def has_block(self, block):
+ """!
+ Does the block exist in this block tree?
+ @param block the block object
+ @return true if it exists
+ """
+ for _category, _blocks in self._block_tree:
+ if block in _blocks: return False
+ return False
+
+ def add_category(self, category):
+ """!
+ Add the category to the block tree.
+ @param category the category string
+ """
+ if self.has_category(category): return
+ self._block_tree.append((category, list()))
+
+ def has_category(self, category):
+ """!
+ Does the category exist in this block tree?
+ @param category the category string (case matters)
+ @return true if it exists
+ """
+ for _category, _blocks in self._block_tree:
+ if category == _category: return True
+ return False
Modified: grc/trunk/src/grc/Constants.py
===================================================================
--- grc/trunk/src/grc/Constants.py 2008-07-20 20:47:16 UTC (rev 8955)
+++ grc/trunk/src/grc/Constants.py 2008-07-20 20:50:25 UTC (rev 8956)
@@ -125,7 +125,7 @@
address@hidden
######################################################################################################
-# A state is recorded for each change to the flow graph, the size
dictates how many states we can record
+# A state is recorded for each change to the flow graph, the size dictates how
many states we can record
######################################################################################################
##The size of the state saving cache in the flow graph (for undo/redo
functionality)
@@ -154,6 +154,6 @@
PY_GTK_ICON = os.path.join(DATA_DIR, 'grc-icon-256.png')
##The default user preferences file.
-PREFERENCES_FILE_PATH = os.path.join(DEFAULT_FILE_PATH, '.grc.xml')
+PREFERENCES_FILE_PATH = os.path.join(DEFAULT_FILE_PATH,
FLOW_GRAPH_FILE_EXTENSION)
address@hidden
Modified: grc/trunk/src/grc/elements/Block.py
===================================================================
--- grc/trunk/src/grc/elements/Block.py 2008-07-20 20:47:16 UTC (rev 8955)
+++ grc/trunk/src/grc/elements/Block.py 2008-07-20 20:50:25 UTC (rev 8956)
@@ -63,6 +63,7 @@
#grab the data
name = n['name']
key = n['key']
+ category = Utils.exists_or_else(n, 'category', '')
params = Utils.listify(n, 'param')
checks = Utils.listify(n, 'check')
sources = Utils.listify(n, 'source')
@@ -72,6 +73,7 @@
#store the data
self._name = name
self._key = key
+ self._category = category
#create the param objects
self._params = odict()
#add the id param
@@ -175,6 +177,8 @@
def get_key(self): return self._key
+ def get_category(self): return self._category
+
def get_doc(self): return ''
##############################################
Modified: grc/trunk/src/grc/elements/Platform.py
===================================================================
--- grc/trunk/src/grc/elements/Platform.py 2008-07-20 20:47:16 UTC (rev
8955)
+++ grc/trunk/src/grc/elements/Platform.py 2008-07-20 20:50:25 UTC (rev
8956)
@@ -53,14 +53,6 @@
self._block_tree = block_tree
self._default_flow_graph = default_flow_graph
self._generator = generator
- #load the block tree
- f = self._block_tree
- try: ParseXML.validate_dtd(f, os.path.join(DATA_DIR,
'block_tree.dtd'))
- except ParseXML.XMLSyntaxError, e: self._exit_with_error('Block
tree "%s" failed: \n\t%s'%(f, e))
- n = ParseXML.from_file(f)['block_tree']
- #build nested tree object
- self._block_tree_nested = [(c['name'], Utils.listify(c,
'block')) for c in Utils.listify(n, 'cat')]
- self._keys_in_tree = sum([Utils.listify(c, 'block') for c in
Utils.listify(n, 'cat')], [])
#create a dummy flow graph for the blocks
self._flow_graph = _Element(self)
#load the blocks
@@ -72,17 +64,6 @@
for dirpath,dirnames,filenames in
os.walk(block_path):
for filename in filter(lambda f:
f.endswith('.xml'), filenames):
self._load_block(os.path.join(dirpath, filename))
- #handle blocks not in the tree
- custom_keys = set(self.get_block_keys()) -
set(self._keys_in_tree)
- custom_keys = filter(lambda k:
self._blocks_n[k].has_key('category') , custom_keys)
- for custom_key in custom_keys:
- custom_category = self._blocks_n[custom_key]['category']
- found = False
- for category, keys in self._block_tree_nested:
- if category == custom_category:
- category.append(custom_key)
- found = True
- if not found:
self._block_tree_nested.append((custom_category, [custom_key]))
def _load_block(self, f):
try: ParseXML.validate_dtd(f, self._block_dtd)
@@ -97,14 +78,34 @@
self._blocks[key] = block
self._blocks_n[key] = n
+ def load_block_tree(self, block_tree):
+ """!
+ Load a block tree with categories and blocks.
+ Step 1: Load all blocks from the xml specification.
+ Step 2: Load blocks with builtin category specifications.
+ @param block_tree the block tree object
+ """
+ #load the block tree
+ f = self._block_tree
+ try: ParseXML.validate_dtd(f, os.path.join(DATA_DIR,
'block_tree.dtd'))
+ except ParseXML.XMLSyntaxError, e: self._exit_with_error('Block
tree "%s" failed: \n\t%s'%(f, e))
+ n = ParseXML.from_file(f)['block_tree']
+ #add all blocks in the tree
+ for category, block_keys in [(c['name'], Utils.listify(c,
'block')) for c in Utils.listify(n, 'cat')]:
+ block_tree.add_category(category)
+ for block_key in block_keys:
block_tree.add_block(self.get_block(block_key), category)
+ #add all other blocks, use the catgory
+ for block in self.get_blocks():
+ #blocks with empty categories are in the xml block tree
or hidden
+ if block.get_category() and not
block_tree.has_block(block):
+ block_tree.add_block(block,
block.get_category())
+
def __str__(self): return 'Platform - %s(%s)'%(self.get_name(),
self.get_key())
def is_platform(self): return True
def get_new_flow_graph(self): return self.FlowGraph(self)
- def get_block_tree(self): return self._block_tree_nested
-
def get_default_flow_graph(self): return self._default_flow_graph
def get_generator(self): return self._generator
Copied: grc/trunk/src/grc/gui/BlockTreeWindow.py (from rev 8924,
grc/trunk/src/grc/gui/SignalBlockSelectionWindow.py)
===================================================================
--- grc/trunk/src/grc/gui/BlockTreeWindow.py (rev 0)
+++ grc/trunk/src/grc/gui/BlockTreeWindow.py 2008-07-20 20:50:25 UTC (rev
8956)
@@ -0,0 +1,134 @@
+"""
+Copyright 2007 Free Software Foundation, Inc.
+This file is part of GNU Radio
+
+GNU Radio Companion is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+GNU Radio Companion is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+"""
address@hidden grc.gui.BlockTreeWindow
+#The block selection panel gives the user a tree selection to choose a block.
address@hidden Josh Blum
+
+from grc.BlockTree import BlockTree as _BlockTree
+from grc.Constants import *
+import pygtk
+pygtk.require('2.0')
+import gtk
+import gobject
+
+class BlockTreeWindow(gtk.VBox, _BlockTree):
+ """The block selection panel."""
+
+ def __init__(self, platform, get_flow_graph):
+ """!
+ SignalBlockSelectionWindow constructor.
+ Show all possible signal blocks in this dialog.
+ Each signal block is represented by a gtk label of its tag and
an add button.
+ The add button tells the flow graph to create the selected
block. and add it to the flow graph.
+ @param platform the particular platform will all block
prototypes
+ @param get_flow_graph get the selected flow graph
+ """
+ gtk.VBox.__init__(self)
+ _BlockTree.__init__(self)
+ self.platform = platform
+ self.get_flow_graph = get_flow_graph
+ #make the tree model for holding blocks
+ self.treestore = gtk.TreeStore(gobject.TYPE_STRING)
+ self.treeview = gtk.TreeView(self.treestore)
+ self.treeview.set_enable_search(False) #disable pop up search
box
+ self.treeview.add_events(gtk.gdk.BUTTON_PRESS_MASK)
+ self.treeview.connect('button_press_event',
self._handle_mouse_button_press)
+ selection = self.treeview.get_selection()
+ selection.set_mode('single')
+ selection.connect('changed', self._handle_selection_change)
+ renderer = gtk.CellRendererText()
+ column = gtk.TreeViewColumn('Blocks', renderer, text=0)
+ self.treeview.append_column(column)
+ #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(BLOCK_SELECTION_WINDOW_WIDTH,
-1)
+ self.pack_start(scrolled_window)
+ #add button
+ self.add_button = gtk.Button(None, 'gtk-add')
+ self.add_button.connect('clicked', self._handle_add_button)
+ self.pack_start(self.add_button, False)
+ #map names to keys
+ self.names = dict()
+ #map categories to iters
+ self.categories = dict()
+ #add blocks and categories
+ self.platform.load_block_tree(self)
+ #initialize
+ self._handle_selection_change()
+
+ def add_block(self, block, category):
+ """!
+ Add a block with category to this selection window.
+ Call base class add block, then add to the tree store.
+ @param block the block object
+ @param category the category string
+ """
+ if block.get_name() in self.names.keys():
+ print '%s has more than one block with name
"%s".'%(self.platform, block.get_name())
+ print 'Although block names do not have to be unique,
this gui requires that that are.'
+ print 'Please rename the block to avoid problems.'
+ return
+ _BlockTree.add_block(self, block, category)
+ new_iter =
self.treestore.insert_before(self.categories[category], None)
+ self.treestore.set_value(new_iter, 0, block.get_name())
+ self.names[block.get_name()] = block.get_key()
+
+ def add_category(self, category):
+ """!
+ Add a category to this selection window.
+ Call base class add category, then add to the tree store.
+ @param category the category string
+ """
+ _BlockTree.add_category(self, category)
+ iter = self.treestore.insert_before(None, None)
+ self.treestore.set_value(iter, 0, category)
+ self.categories[category] = iter
+
+ def _handle_mouse_button_press(self, widget, event):
+ """!
+ Handle the mouse button press.
+ If a left double click is detected,
+ let the handler for the add button decide to add a block.
+ """
+ if event.button == 1 and event.type == gtk.gdk._2BUTTON_PRESS:
self._handle_add_button(widget)
+
+ def _handle_selection_change(self, selection=None):
+ """!
+ Handle a selection change in the tree view.
+ If a selection changes, set the add button sensitive.
+ """
+ selection = self.treeview.get_selection()
+ model, iter = selection.get_selected()
+ sensitive = bool(iter and not model.iter_has_child(iter))
+ self.add_button.set_sensitive(sensitive)
+
+ def _handle_add_button(self, widget):
+ """!
+ Handle the add button clicked signal.
+ Add the signal block to the flow graph.
+ """
+ selection = self.treeview.get_selection()
+ treestore, iter = selection.get_selected()
+ if iter and not treestore.iter_has_child(iter):
+ name = treestore.get_value(iter, 0)
+ key = self.names[name]
+ self.get_flow_graph().add_new_block(key)
+
Modified: grc/trunk/src/grc/gui/MainWindow.py
===================================================================
--- grc/trunk/src/grc/gui/MainWindow.py 2008-07-20 20:47:16 UTC (rev 8955)
+++ grc/trunk/src/grc/gui/MainWindow.py 2008-07-20 20:50:25 UTC (rev 8956)
@@ -26,7 +26,7 @@
pygtk.require('2.0')
import gtk
import Bars
-from SignalBlockSelectionWindow import SignalBlockSelectionWindow
+from BlockTreeWindow import BlockTreeWindow
from Dialogs import TextDisplay,MessageDialogHelper
from DrawingArea import DrawingArea
from grc import Preferences
@@ -36,11 +36,11 @@
############################################################
## Main window
-############################################################
-
+############################################################
+
class MainWindow(gtk.Window):
"""The topmost window with menus, the tool bar, and other major
windows."""
-
+
def __init__(self, handle_states, platform):
"""!
MainWindow contructor.
@@ -49,16 +49,16 @@
self._platform = platform
#setup window
self.handle_states = handle_states
- gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
+ gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
vbox = gtk.VBox()
hbox = gtk.HBox()
self.add(vbox)
- #create the menu bar and toolbar
- vbox.pack_start(Bars.MenuBar(), False)
- vbox.pack_start(Bars.Toolbar(), False)
+ #create the menu bar and toolbar
+ vbox.pack_start(Bars.MenuBar(), False)
+ vbox.pack_start(Bars.Toolbar(), False)
#setup scrolled window
self.scrolled_window = gtk.ScrolledWindow()
- self.scrolled_window.set_size_request(MIN_WINDOW_WIDTH,
MIN_WINDOW_HEIGHT)
+ self.scrolled_window.set_size_request(MIN_WINDOW_WIDTH,
MIN_WINDOW_HEIGHT)
self.scrolled_window.set_policy(gtk.POLICY_AUTOMATIC,
gtk.POLICY_AUTOMATIC)
self.drawing_area = DrawingArea(self)
self.scrolled_window.add_with_viewport(self.drawing_area)
@@ -73,24 +73,24 @@
fg_and_report_box.pack_start(self.notebook, False, False, 0)
fg_and_report_box.pack_start(self.scrolled_window)
hbox.pack_start(fg_and_report_box)
- vbox.pack_start(hbox)
+ vbox.pack_start(hbox)
#create the side windows
side_box = gtk.VBox()
hbox.pack_start(side_box, False)
- side_box.pack_start(SignalBlockSelectionWindow(platform,
self.get_flow_graph)) #allow resize, selection window can have more space
- #create the reports window
+ side_box.pack_start(BlockTreeWindow(platform,
self.get_flow_graph)) #allow resize, selection window can have more space
+ #create the reports window
self.text_display = TextDisplay()
#house the reports in a scrolled window
self.reports_scrolled_window = gtk.ScrolledWindow()
self.reports_scrolled_window.set_size_request(-1,
REPORTS_WINDOW_HEIGHT)
self.reports_scrolled_window.set_policy(gtk.POLICY_AUTOMATIC,
gtk.POLICY_AUTOMATIC)
-
self.reports_scrolled_window.add_with_viewport(self.text_display)
+
self.reports_scrolled_window.add_with_viewport(self.text_display)
fg_and_report_box.pack_end(self.reports_scrolled_window, False)
#dont allow resize, fg should get all the space
- #show all but the main window container and the reports window
+ #show all but the main window container and the reports window
vbox.show_all()
self.notebook.hide()
- self._show_reports_window(False)
- # load preferences and show the main window
+ self._show_reports_window(False)
+ # load preferences and show the main window
Preferences.load()
self.resize(*Preferences.window_size())
self.show()#show after resize in preferences
@@ -98,21 +98,21 @@
############################################################
## Event Handlers
############################################################
-
+
def _quit(self, window, event):
"""!
Handle the delete event from the main window.
- Generated by pressing X to close, alt+f4, or right click+close.
+ Generated by pressing X to close, alt+f4, or right click+close.
This method in turns calls the state handler to quit.
- @return true
+ @return true
"""
self.handle_states(APPLICATION_QUIT)
- return True
-
+ return True
+
def _handle_page_change(self, notebook, page, page_num):
"""!
Handle a page change. When the user clicks on a new tab,
- reload the flow graph to update the vars window and
+ reload the flow graph to update the vars window and
call handle states (select nothing) to update the buttons.
@param notebook the notebook
@param page new page
@@ -123,21 +123,21 @@
state = self.get_page().get_state_cache().get_current_state()
self.get_flow_graph().import_data(state)
self.get_flow_graph().update()
- self.handle_states(NOTHING_SELECT)
-
+ self.handle_states(NOTHING_SELECT)
+
############################################################
## Report Window
############################################################
-
+
def add_report_line(self, line):
"""!
Place line at the end of the text buffer, then scroll its
window all the way down.
@param line the new text
"""
- self.text_display.insert(line)
+ self.text_display.insert(line)
vadj = self.reports_scrolled_window.get_vadjustment()
vadj.set_value(vadj.upper)
-
+
def _show_reports_window(self, show):
"""!
Show the reports window when show is True.
@@ -146,11 +146,11 @@
"""
if show: self.reports_scrolled_window.show()
else: self.reports_scrolled_window.hide()
-
+
############################################################
## Pages: create and close
############################################################
-
+
def new_page(self, file_path='', show=False):
"""!
Create a new notebook page.
@@ -162,7 +162,7 @@
if file_path and file_path in self._get_files(): #already open
page =
self.notebook.get_nth_page(self._get_files().index(file_path))
self._set_page(page)
- return
+ return
try: #try to load from file
if file_path: Messages.send_start_load(file_path)
flow_graph = self._platform.get_new_flow_graph()
@@ -170,25 +170,25 @@
flow_graph.drawing_area = self.drawing_area
flow_graph.handle_states = self.handle_states
page = Page(
- self,
+ self,
flow_graph=flow_graph,
file_path=file_path,
)
if file_path: Messages.send_end_load()
except Exception, e: #return on failure
Messages.send_fail_load(e)
- return
+ return
#add this page to the notebook
self.notebook.append_page(page, page.get_tab())
try: self.notebook.set_tab_reorderable(page, True)
except: pass #gtk too old
self.notebook.set_tab_label_packing(page, False, False,
gtk.PACK_START)
- #only show if blank or manual
- if not file_path or show: self._set_page(page)
-
+ #only show if blank or manual
+ if not file_path or show: self._set_page(page)
+
def close_pages(self):
"""
- Close all the pages in this notebook.
+ Close all the pages in this notebook.
@return true if all closed
"""
open_files = filter(lambda file: file, self._get_files())
#filter blank files
@@ -203,7 +203,7 @@
Preferences.window_size(self.get_size())
Preferences.save()
return True
-
+
def close_page(self, ensure=True):
"""
Close the current page.
@@ -216,7 +216,7 @@
if self.page_to_be_closed.get_pid() or not
self.page_to_be_closed.get_saved():
self._set_page(self.page_to_be_closed)
#unsaved? ask the user
- if not self.page_to_be_closed.get_saved() and
self._save_changes():
+ if not self.page_to_be_closed.get_saved() and
self._save_changes():
self.handle_states(FLOW_GRAPH_SAVE) #try to save
if not self.page_to_be_closed.get_saved(): #still
unsaved?
self.page_to_be_closed = None #set the page
to be closed back to None
@@ -227,7 +227,7 @@
self.notebook.remove_page(self.notebook.page_num(self.page_to_be_closed))
if ensure and self.notebook.get_n_pages() == 0: self.new_page()
#no pages, make a new one
self.page_to_be_closed = None #set the page to be closed back
to None
-
+
############################################################
## Misc
############################################################
@@ -238,7 +238,7 @@
Set the titles on the page tabs.
Show/hide the reports window.
@param title the window title
- """
+ """
if self.get_page():
title = ''.join((
MAIN_WINDOW_PREFIX,
@@ -248,7 +248,7 @@
)
)
else: title = MAIN_WINDOW_PREFIX + ' - Editor '
- gtk.Window.set_title(self, title)
+ gtk.Window.set_title(self, title)
#set tab titles
for page in self._get_pages():
title =
os.path.basename(page.get_file_path()).replace(FLOW_GRAPH_FILE_EXTENSION, '')
@@ -260,10 +260,10 @@
)
#reports window
self._show_reports_window(Preferences.show_reports_window())
- #show/hide notebook tabs
+ #show/hide notebook tabs
if len(self._get_pages()) > 1: self.notebook.show()
else: self.notebook.hide()
-
+
def get_page(self):
"""!
Get the selected page.
@@ -288,18 +288,18 @@
@param page the page widget
"""
self.current_page = page
-
self.notebook.set_current_page(self.notebook.page_num(self.current_page))
+
self.notebook.set_current_page(self.notebook.page_num(self.current_page))
def _save_changes(self):
"""!
- Save changes to flow graph?
+ Save changes to flow graph?
@return true if yes
"""
return MessageDialogHelper(
- gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, 'Unsaved
Changes!',
+ gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, 'Unsaved
Changes!',
'Would you like to save changes before closing?'
) == gtk.RESPONSE_YES
-
+
def _get_files(self):
"""
Get the file names for all the pages, in order.
@@ -312,5 +312,5 @@
Get a list of all pages in the notebook.
@return list of pages
"""
- return [self.notebook.get_nth_page(page_num) for page_num in
range(self.notebook.get_n_pages())]
+ return [self.notebook.get_nth_page(page_num) for page_num in
range(self.notebook.get_n_pages())]
Copied: grc/trunk/src/grc/gui/ParamsDialog.py (from rev 8924,
grc/trunk/src/grc/gui/SignalBlockParamsDialog.py)
===================================================================
--- grc/trunk/src/grc/gui/ParamsDialog.py (rev 0)
+++ grc/trunk/src/grc/gui/ParamsDialog.py 2008-07-20 20:50:25 UTC (rev
8956)
@@ -0,0 +1,131 @@
+"""
+Copyright 2007 Free Software Foundation, Inc.
+This file is part of GNU Radio
+
+GNU Radio Companion is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+GNU Radio Companion is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+"""
address@hidden grc.gui.ParamsDialog
+#A dialog for editing a block's parameters.
address@hidden Josh Blum
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+
+from Dialogs import TextDisplay
+from grc.Constants import MIN_DIALOG_WIDTH,MIN_DIALOG_HEIGHT
+
+def get_title_label(title):
+ """!
+ Get a title label for the params window.
+ The title will be bold, underlined, and left justified.
+ @param title the text of the title
+ @return a gtk object
+ """
+ label = gtk.Label()
+ label.set_markup('\n<b><span underline="low">%s</span>:</b>\n'%title)
+ hbox = gtk.HBox()
+ hbox.pack_start(label, False, False, padding=11)
+ return hbox
+
+class ParamsDialog(gtk.Dialog):
+ """A dialog box to set block parameters."""
+
+ def __init__(self, block):
+ """!
+ SignalBlockParamsDialog contructor.
+ @param block the signal block
+ """
+ gtk.Dialog.__init__(self, buttons=('gtk-close',
gtk.RESPONSE_CLOSE))
+ self.block = block
+ self.set_title('Properties: %s'%block.get_name())
+ self.set_size_request(MIN_DIALOG_WIDTH, MIN_DIALOG_HEIGHT)
+ vbox = gtk.VBox()
+ #Add the title label
+ vbox.pack_start(get_title_label('Parameters'), False)
+ #Create the scrolled window to hold all the parameters
+ scrolled_window = gtk.ScrolledWindow()
+ scrolled_window.set_policy(gtk.POLICY_AUTOMATIC,
gtk.POLICY_AUTOMATIC)
+ scrolled_window.add_with_viewport(vbox)
+ self.vbox.pack_start(scrolled_window, True)
+ #Error Messages for the block
+ self._error_messages_box = err_box = gtk.VBox()
+ self._error_messages_text_display = TextDisplay('')
+ err_box.pack_start(gtk.Label(''), False, False, 7) #spacing
+ err_box.pack_start(get_title_label('Error Messages'), False)
+ err_box.pack_start(self._error_messages_text_display, False)
+ #Add all the parameters
+ for param in filter(lambda p: not
(p.get_key().startswith('gui_') or p.get_key().startswith('_')),
self.block.get_params()):
+
vbox.pack_start(param.get_input_object(self._handle_changed), False)
+ vbox.pack_start(err_box, False)
+ #Done adding parameters
+ if self.block.get_doc():
+ vbox.pack_start(gtk.Label(''), False, False, 7) #spacing
+ vbox.pack_start(get_title_label('Documentation'), False)
+ #Create the text box to display notes about the block
+ vbox.pack_start(TextDisplay(self.block.get_doc()),
False)
+ self.connect('key_press_event', self._handle_key_press)
+ self.show_all()
+ self._update_error_messages()
+
+ def _update_error_messages(self):
+ """
+ Update the error messages in the error messages box.
+ Hide the box if there are no errors.
+ """
+ if self.block.is_valid(): self._error_messages_box.hide()
+ else: self._error_messages_box.show()
+ messages = '\n'.join(self.block.get_error_messages())
+ self._error_messages_text_display.set_text(messages)
+
+ def _handle_key_press(self, widget, event):
+ """!
+ Handle key presses from the keyboard.
+ Call the ok response when enter is pressed.
+ @return false to forward the keypress
+ """
+ keyname = gtk.gdk.keyval_name(event.keyval)
+ if keyname == 'Return': self.response(gtk.RESPONSE_OK)
+ return False #forward the keypress
+
+ def _handle_changed(self, param):
+ """!
+ A change occured, update any dependent parameters:
+ The enum inside the variable type may have changed and,
+ the variable param will need an external update.
+ @param param the graphical parameter that initiated the callback
+ """
+ self._update_error_messages()
+ #update dependent params
+ if param.is_enum():
+ for other_param in param.get_parent().get_params():
+ if param.get_key() in other_param._type:
other_param.update()
+ return True
+
+ def run(self):
+ """!
+ Call run().
+ @return true if a change occured.
+ """
+ original_data = list()
+ for param in self.block.get_params():
+ original_data.append(param.get_value())
+ gtk.Dialog.run(self)
+ self.destroy()
+ new_data = list()
+ for param in self.block.get_params():
+ new_data.append(param.get_value())
+ return original_data != new_data
+
Deleted: grc/trunk/src/grc/gui/SignalBlockParamsDialog.py
Deleted: grc/trunk/src/grc/gui/SignalBlockSelectionWindow.py
Modified: grc/trunk/src/grc/gui/elements/FlowGraph.py
===================================================================
--- grc/trunk/src/grc/gui/elements/FlowGraph.py 2008-07-20 20:47:16 UTC (rev
8955)
+++ grc/trunk/src/grc/gui/elements/FlowGraph.py 2008-07-20 20:50:25 UTC (rev
8956)
@@ -24,7 +24,7 @@
from grc.Constants import *
from grc.Actions import *
from Colors import BACKGROUND_COLOR, TXT_COLOR
-from grc.gui.SignalBlockParamsDialog import SignalBlockParamsDialog
+from grc.gui.ParamsDialog import ParamsDialog
from Element import Element
from grc.elements import FlowGraph as _FlowGraph
@@ -165,7 +165,7 @@
@return true if parameters were changed
"""
if self.get_selected_block():
- signal_block_params_dialog =
SignalBlockParamsDialog(self.get_selected_block())
+ signal_block_params_dialog =
ParamsDialog(self.get_selected_block())
changed = signal_block_params_dialog.run()
self.update()
return changed #changes were made?
Modified: grc/trunk/src/grc_gnuradio/Generator.py
===================================================================
--- grc/trunk/src/grc_gnuradio/Generator.py 2008-07-20 20:47:16 UTC (rev
8955)
+++ grc/trunk/src/grc_gnuradio/Generator.py 2008-07-20 20:50:25 UTC (rev
8956)
@@ -25,7 +25,6 @@
import sys
import stat
from Cheetah.Template import Template
-from grc.Constants import FLOW_GRAPH_FILE_EXTENSION
##The default binary to execute python files.
PYEXEC = 'python'
@@ -39,6 +38,12 @@
class Generator(object):
def __init__(self, flow_graph, file_path):
+ """!
+ Initialize the generator object.
+ Determine the file to generate.
+ @param flow_graph the flow graph object
+ @param file_path the path to write the file to
+ """
self._flow_graph = flow_graph
filename = self._flow_graph.get_option('id') + '.py'
dirname = os.path.dirname(file_path)
@@ -56,8 +61,7 @@
def get_popen(self):
"""!
- Generate and execute this python flow graph.
- @param file_path the file path of the flow graph
+ Execute this python flow graph.
@return a popen object
"""
#execute
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Commit-gnuradio] r8956 - in grc/trunk: notes src/grc src/grc/elements src/grc/gui src/grc/gui/elements src/grc_gnuradio,
jblum <=