commit-gnuradio
[Top][All Lists]
Advanced

[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





reply via email to

[Prev in Thread] Current Thread [Next in Thread]