Changeset 8956
- Timestamp:
- 07/20/08 14:50:25
- Files:
-
- grc/trunk/notes/todo.txt (modified) (2 diffs)
- grc/trunk/src/grc/BlockTree.py (added)
- grc/trunk/src/grc/Constants.py (modified) (2 diffs)
- grc/trunk/src/grc/elements/Block.py (modified) (3 diffs)
- grc/trunk/src/grc/elements/Platform.py (modified) (4 diffs)
- grc/trunk/src/grc/gui/BlockTreeWindow.py (moved) (moved from grc/trunk/src/grc/gui/SignalBlockSelectionWindow.py) (5 diffs)
- grc/trunk/src/grc/gui/MainWindow.py (modified) (21 diffs)
- grc/trunk/src/grc/gui/ParamsDialog.py (moved) (moved from grc/trunk/src/grc/gui/SignalBlockParamsDialog.py) (2 diffs)
- grc/trunk/src/grc/gui/elements/FlowGraph.py (modified) (2 diffs)
- grc/trunk/src/grc_gnuradio/Generator.py (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
grc/trunk/notes/todo.txt
r8939 r8956 1 ############ Blocks to Add: #################### 2 -pad source/sink 1 ############ Blocks to Add: #################### 3 2 -hier block 4 3 -optparse block 5 4 -ofdm wrappers 6 5 7 ############ Features to Add:####################6 ############ Features to Add: #################### 8 7 -save working directory after close 9 8 -create sub-flow graphs to be used in larger flow graphs … … 12 11 -default platform for preferences block 13 12 -command line option for additional block wrappers 14 -block tree class15 -dtd for external blocks16 13 -hotkeys in action descriptions 17 -variables dependent on variables that change18 14 -log slider gui control 19 15 -variable resolution graph structure 16 -move checks from grc Block to grc_gnuradio specific 17 18 ############ Problems: #################### 20 19 -catch error on open non-existant files 20 -block tree window maps block by name 21 -variables dependent on variables that change 21 22 22 ############ Suggestions:####################23 ############ Suggestions: #################### 23 24 -simple usrp 24 25 -tune_result in usrp.py needs __str__ method grc/trunk/src/grc/Constants.py
r8651 r8956 126 126 127 127 ###################################################################################################### 128 # A state is recorded for each change to the flow graph, the size dictates how many states we can record128 # A state is recorded for each change to the flow graph, the size dictates how many states we can record 129 129 ###################################################################################################### 130 130 … … 155 155 156 156 ##The default user preferences file. 157 PREFERENCES_FILE_PATH = os.path.join(DEFAULT_FILE_PATH, '.grc.xml')157 PREFERENCES_FILE_PATH = os.path.join(DEFAULT_FILE_PATH, FLOW_GRAPH_FILE_EXTENSION) 158 158 ##@} 159 159 grc/trunk/src/grc/elements/Block.py
r8808 r8956 64 64 name = n['name'] 65 65 key = n['key'] 66 category = Utils.exists_or_else(n, 'category', '') 66 67 params = Utils.listify(n, 'param') 67 68 checks = Utils.listify(n, 'check') … … 73 74 self._name = name 74 75 self._key = key 76 self._category = category 75 77 #create the param objects 76 78 self._params = odict() … … 176 178 def get_key(self): return self._key 177 179 180 def get_category(self): return self._category 181 178 182 def get_doc(self): return '' 179 183 grc/trunk/src/grc/elements/Platform.py
r8939 r8956 54 54 self._default_flow_graph = default_flow_graph 55 55 self._generator = generator 56 #load the block tree57 f = self._block_tree58 try: ParseXML.validate_dtd(f, os.path.join(DATA_DIR, 'block_tree.dtd'))59 except ParseXML.XMLSyntaxError, e: self._exit_with_error('Block tree "%s" failed: \n\t%s'%(f, e))60 n = ParseXML.from_file(f)['block_tree']61 #build nested tree object62 self._block_tree_nested = [(c['name'], Utils.listify(c, 'block')) for c in Utils.listify(n, 'cat')]63 self._keys_in_tree = sum([Utils.listify(c, 'block') for c in Utils.listify(n, 'cat')], [])64 56 #create a dummy flow graph for the blocks 65 57 self._flow_graph = _Element(self) … … 73 65 for filename in filter(lambda f: f.endswith('.xml'), filenames): 74 66 self._load_block(os.path.join(dirpath, filename)) 75 #handle blocks not in the tree76 custom_keys = set(self.get_block_keys()) - set(self._keys_in_tree)77 custom_keys = filter(lambda k: self._blocks_n[k].has_key('category') , custom_keys)78 for custom_key in custom_keys:79 custom_category = self._blocks_n[custom_key]['category']80 found = False81 for category, keys in self._block_tree_nested:82 if category == custom_category:83 category.append(custom_key)84 found = True85 if not found: self._block_tree_nested.append((custom_category, [custom_key]))86 67 87 68 def _load_block(self, f): … … 98 79 self._blocks_n[key] = n 99 80 81 def load_block_tree(self, block_tree): 82 """! 83 Load a block tree with categories and blocks. 84 Step 1: Load all blocks from the xml specification. 85 Step 2: Load blocks with builtin category specifications. 86 @param block_tree the block tree object 87 """ 88 #load the block tree 89 f = self._block_tree 90 try: ParseXML.validate_dtd(f, os.path.join(DATA_DIR, 'block_tree.dtd')) 91 except ParseXML.XMLSyntaxError, e: self._exit_with_error('Block tree "%s" failed: \n\t%s'%(f, e)) 92 n = ParseXML.from_file(f)['block_tree'] 93 #add all blocks in the tree 94 for category, block_keys in [(c['name'], Utils.listify(c, 'block')) for c in Utils.listify(n, 'cat')]: 95 block_tree.add_category(category) 96 for block_key in block_keys: block_tree.add_block(self.get_block(block_key), category) 97 #add all other blocks, use the catgory 98 for block in self.get_blocks(): 99 #blocks with empty categories are in the xml block tree or hidden 100 if block.get_category() and not block_tree.has_block(block): 101 block_tree.add_block(block, block.get_category()) 102 100 103 def __str__(self): return 'Platform - %s(%s)'%(self.get_name(), self.get_key()) 101 104 … … 103 106 104 107 def get_new_flow_graph(self): return self.FlowGraph(self) 105 106 def get_block_tree(self): return self._block_tree_nested107 108 108 109 def get_default_flow_graph(self): return self._default_flow_graph grc/trunk/src/grc/gui/BlockTreeWindow.py
r8924 r8956 17 17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 18 18 """ 19 ##@package grc.gui. SignalBlockSelectionWindow20 #The signal block selection window gives the user a tree selection to choose a signalblock.19 ##@package grc.gui.BlockTreeWindow 20 #The block selection panel gives the user a tree selection to choose a block. 21 21 #@author Josh Blum 22 22 23 from grc.BlockTree import BlockTree as _BlockTree 23 24 from grc.Constants import * 24 25 import pygtk … … 27 28 import gobject 28 29 29 class SignalBlockSelectionWindow(gtk.VBox):30 """The signal block selection window."""30 class BlockTreeWindow(gtk.VBox, _BlockTree): 31 """The block selection panel.""" 31 32 32 33 def __init__(self, platform, get_flow_graph): … … 40 41 """ 41 42 gtk.VBox.__init__(self) 43 _BlockTree.__init__(self) 44 self.platform = platform 42 45 self.get_flow_graph = get_flow_graph 43 46 #make the tree model for holding blocks … … 51 54 selection.connect('changed', self._handle_selection_change) 52 55 renderer = gtk.CellRendererText() 53 column = gtk.TreeViewColumn( "Signal Blocks", renderer, text=0)56 column = gtk.TreeViewColumn('Blocks', renderer, text=0) 54 57 self.treeview.append_column(column) 55 58 #make the scrolled window to hold the tree view … … 65 68 #map names to keys 66 69 self.names = dict() 70 #map categories to iters 71 self.categories = dict() 67 72 #add blocks and categories 68 for category, keys in platform.get_block_tree(): 69 iter = self.treestore.insert_before(None, None) 70 self.treestore.set_value(iter, 0, category) 71 for key in keys: 72 if key not in platform.get_block_keys(): 73 print 'Block with key "%s" cannot be found in %s -> ignoring...'%(key, platform) 74 continue 75 name = platform.get_block(key).get_name() 76 if name in self.names.keys(): 77 print '%s has more than one block with name "%s".'%(platform, name) 78 print 'Although block names do not have to be unique, this gui requires that that are.' 79 print 'Please rename the block to avoid problems.' 80 continue 81 self.names[name] = key 82 new_iter = self.treestore.insert_before(iter, None) 83 self.treestore.set_value(new_iter, 0, name) 73 self.platform.load_block_tree(self) 84 74 #initialize 85 75 self._handle_selection_change() 76 77 def add_block(self, block, category): 78 """! 79 Add a block with category to this selection window. 80 Call base class add block, then add to the tree store. 81 @param block the block object 82 @param category the category string 83 """ 84 if block.get_name() in self.names.keys(): 85 print '%s has more than one block with name "%s".'%(self.platform, block.get_name()) 86 print 'Although block names do not have to be unique, this gui requires that that are.' 87 print 'Please rename the block to avoid problems.' 88 return 89 _BlockTree.add_block(self, block, category) 90 new_iter = self.treestore.insert_before(self.categories[category], None) 91 self.treestore.set_value(new_iter, 0, block.get_name()) 92 self.names[block.get_name()] = block.get_key() 93 94 def add_category(self, category): 95 """! 96 Add a category to this selection window. 97 Call base class add category, then add to the tree store. 98 @param category the category string 99 """ 100 _BlockTree.add_category(self, category) 101 iter = self.treestore.insert_before(None, None) 102 self.treestore.set_value(iter, 0, category) 103 self.categories[category] = iter 86 104 87 105 def _handle_mouse_button_press(self, widget, event): grc/trunk/src/grc/gui/MainWindow.py
r8590 r8956 27 27 import gtk 28 28 import Bars 29 from SignalBlockSelectionWindow import SignalBlockSelectionWindow29 from BlockTreeWindow import BlockTreeWindow 30 30 from Dialogs import TextDisplay,MessageDialogHelper 31 31 from DrawingArea import DrawingArea … … 37 37 ############################################################ 38 38 ## Main window 39 ############################################################ 40 39 ############################################################ 40 41 41 class MainWindow(gtk.Window): 42 42 """The topmost window with menus, the tool bar, and other major windows.""" 43 43 44 44 def __init__(self, handle_states, platform): 45 45 """! … … 50 50 #setup window 51 51 self.handle_states = handle_states 52 gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL) 52 gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL) 53 53 vbox = gtk.VBox() 54 54 hbox = gtk.HBox() 55 55 self.add(vbox) 56 #create the menu bar and toolbar 57 vbox.pack_start(Bars.MenuBar(), False) 58 vbox.pack_start(Bars.Toolbar(), False) 56 #create the menu bar and toolbar 57 vbox.pack_start(Bars.MenuBar(), False) 58 vbox.pack_start(Bars.Toolbar(), False) 59 59 #setup scrolled window 60 60 self.scrolled_window = gtk.ScrolledWindow() 61 self.scrolled_window.set_size_request(MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT) 61 self.scrolled_window.set_size_request(MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT) 62 62 self.scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) 63 63 self.drawing_area = DrawingArea(self) … … 74 74 fg_and_report_box.pack_start(self.scrolled_window) 75 75 hbox.pack_start(fg_and_report_box) 76 vbox.pack_start(hbox) 76 vbox.pack_start(hbox) 77 77 #create the side windows 78 78 side_box = gtk.VBox() 79 79 hbox.pack_start(side_box, False) 80 side_box.pack_start( SignalBlockSelectionWindow(platform, self.get_flow_graph)) #allow resize, selection window can have more space81 #create the reports window 80 side_box.pack_start(BlockTreeWindow(platform, self.get_flow_graph)) #allow resize, selection window can have more space 81 #create the reports window 82 82 self.text_display = TextDisplay() 83 83 #house the reports in a scrolled window … … 85 85 self.reports_scrolled_window.set_size_request(-1, REPORTS_WINDOW_HEIGHT) 86 86 self.reports_scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) 87 self.reports_scrolled_window.add_with_viewport(self.text_display) 87 self.reports_scrolled_window.add_with_viewport(self.text_display) 88 88 fg_and_report_box.pack_end(self.reports_scrolled_window, False) #dont allow resize, fg should get all the space 89 #show all but the main window container and the reports window 89 #show all but the main window container and the reports window 90 90 vbox.show_all() 91 91 self.notebook.hide() 92 self._show_reports_window(False) 93 # load preferences and show the main window 92 self._show_reports_window(False) 93 # load preferences and show the main window 94 94 Preferences.load() 95 95 self.resize(*Preferences.window_size()) … … 99 99 ## Event Handlers 100 100 ############################################################ 101 101 102 102 def _quit(self, window, event): 103 103 """! 104 104 Handle the delete event from the main window. 105 Generated by pressing X to close, alt+f4, or right click+close. 105 Generated by pressing X to close, alt+f4, or right click+close. 106 106 This method in turns calls the state handler to quit. 107 @return true 107 @return true 108 108 """ 109 109 self.handle_states(APPLICATION_QUIT) 110 return True 111 110 return True 111 112 112 def _handle_page_change(self, notebook, page, page_num): 113 113 """! 114 114 Handle a page change. When the user clicks on a new tab, 115 reload the flow graph to update the vars window and 115 reload the flow graph to update the vars window and 116 116 call handle states (select nothing) to update the buttons. 117 117 @param notebook the notebook … … 124 124 self.get_flow_graph().import_data(state) 125 125 self.get_flow_graph().update() 126 self.handle_states(NOTHING_SELECT) 127 126 self.handle_states(NOTHING_SELECT) 127 128 128 ############################################################ 129 129 ## Report Window 130 130 ############################################################ 131 131 132 132 def add_report_line(self, line): 133 133 """! … … 135 135 @param line the new text 136 136 """ 137 self.text_display.insert(line) 137 self.text_display.insert(line) 138 138 vadj = self.reports_scrolled_window.get_vadjustment() 139 139 vadj.set_value(vadj.upper) 140 140 141 141 def _show_reports_window(self, show): 142 142 """! … … 147 147 if show: self.reports_scrolled_window.show() 148 148 else: self.reports_scrolled_window.hide() 149 149 150 150 ############################################################ 151 151 ## Pages: create and close 152 152 ############################################################ 153 153 154 154 def new_page(self, file_path='', show=False): 155 155 """! … … 163 163 page = self.notebook.get_nth_page(self._get_files().index(file_path)) 164 164 self._set_page(page) 165 return 165 return 166 166 try: #try to load from file 167 167 if file_path: Messages.send_start_load(file_path) … … 171 171 flow_graph.handle_states = self.handle_states 172 172 page = Page( 173 self, 173 self, 174 174 flow_graph=flow_graph, 175 175 file_path=file_path, … … 178 178 except Exception, e: #return on failure 179 179 Messages.send_fail_load(e) 180 return 180 return 181 181 #add this page to the notebook 182 182 self.notebook.append_page(page, page.get_tab()) … … 184 184 except: pass #gtk too old 185 185 self.notebook.set_tab_label_packing(page, False, False, gtk.PACK_START) 186 #only show if blank or manual 187 if not file_path or show: self._set_page(page) 188 186 #only show if blank or manual 187 if not file_path or show: self._set_page(page) 188 189 189 def close_pages(self): 190 190 """ 191 Close all the pages in this notebook. 191 Close all the pages in this notebook. 192 192 @return true if all closed 193 193 """ … … 204 204 Preferences.save() 205 205 return True 206 206 207 207 def close_page(self, ensure=True): 208 208 """ … … 217 217 self._set_page(self.page_to_be_closed) 218 218 #unsaved? ask the user 219 if not self.page_to_be_closed.get_saved() and self._save_changes(): 219 if not self.page_to_be_closed.get_saved() and self._save_changes(): 220 220 self.handle_states(FLOW_GRAPH_SAVE) #try to save 221 221 if not self.page_to_be_closed.get_saved(): #still unsaved? … … 228 228 if ensure and self.notebook.get_n_pages() == 0: self.new_page() #no pages, make a new one 229 229 self.page_to_be_closed = None #set the page to be closed back to None 230 230 231 231 ############################################################ 232 232 ## Misc … … 239 239 Show/hide the reports window. 240 240 @param title the window title 241 """ 241 """ 242 242 if self.get_page(): 243 243 title = ''.join(( … … 249 249 ) 250 250 else: title = MAIN_WINDOW_PREFIX + ' - Editor ' 251 gtk.Window.set_title(self, title) 251 gtk.Window.set_title(self, title) 252 252 #set tab titles 253 253 for page in self._get_pages(): … … 261 261 #reports window 262 262 self._show_reports_window(Preferences.show_reports_window()) 263 #show/hide notebook tabs 263 #show/hide notebook tabs 264 264 if len(self._get_pages()) > 1: self.notebook.show() 265 265 else: self.notebook.hide() 266 266 267 267 def get_page(self): 268 268 """! … … 289 289 """ 290 290 self.current_page = page 291 self.notebook.set_current_page(self.notebook.page_num(self.current_page)) 291 self.notebook.set_current_page(self.notebook.page_num(self.current_page)) 292 292 293 293 def _save_changes(self): 294 294 """! 295 Save changes to flow graph? 295 Save changes to flow graph? 296 296 @return true if yes 297 297 """ 298 298 return MessageDialogHelper( 299 gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, 'Unsaved Changes!', 299 gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, 'Unsaved Changes!', 300 300 'Would you like to save changes before closing?' 301 301 ) == gtk.RESPONSE_YES 302 302 303 303 def _get_files(self): 304 304 """ … … 313 313 @return list of pages 314 314 """ 315 return [self.notebook.get_nth_page(page_num) for page_num in range(self.notebook.get_n_pages())] 316 315 return [self.notebook.get_nth_page(page_num) for page_num in range(self.notebook.get_n_pages())] 316 grc/trunk/src/grc/gui/ParamsDialog.py
r8924 r8956 17 17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 18 18 """ 19 ##@package grc.gui. SignalBlockParamsDialog20 #A dialog for editing a signalblock's parameters.19 ##@package grc.gui.ParamsDialog 20 #A dialog for editing a block's parameters. 21 21 #@author Josh Blum 22 22 … … 41 41 return hbox 42 42 43 class SignalBlockParamsDialog(gtk.Dialog):44 """A dialog box to set signalblock parameters."""43 class ParamsDialog(gtk.Dialog): 44 """A dialog box to set block parameters.""" 45 45 46 46 def __init__(self, block): grc/trunk/src/grc/gui/elements/FlowGraph.py
r8810 r8956 25 25 from grc.Actions import * 26 26 from Colors import BACKGROUND_COLOR, TXT_COLOR 27 from grc.gui. SignalBlockParamsDialog import SignalBlockParamsDialog27 from grc.gui.ParamsDialog import ParamsDialog 28 28 from Element import Element 29 29 from grc.elements import FlowGraph as _FlowGraph … … 166 166 """ 167 167 if self.get_selected_block(): 168 signal_block_params_dialog = SignalBlockParamsDialog(self.get_selected_block())168 signal_block_params_dialog = ParamsDialog(self.get_selected_block()) 169 169 changed = signal_block_params_dialog.run() 170 170 self.update() grc/trunk/src/grc_gnuradio/Generator.py
r8910 r8956 26 26 import stat 27 27 from Cheetah.Template import Template 28 from grc.Constants import FLOW_GRAPH_FILE_EXTENSION29 28 30 29 ##The default binary to execute python files. … … 40 39 41 40 def __init__(self, flow_graph, file_path): 41 """! 42 Initialize the generator object. 43 Determine the file to generate. 44 @param flow_graph the flow graph object 45 @param file_path the path to write the file to 46 """ 42 47 self._flow_graph = flow_graph 43 48 filename = self._flow_graph.get_option('id') + '.py' … … 57 62 def get_popen(self): 58 63 """! 59 Generate and execute this python flow graph. 60 @param file_path the file path of the flow graph 64 Execute this python flow graph. 61 65 @return a popen object 62 66 """
