Generating the band-edge filter taps based on the oversampling ratio (samples per...
[debian/gnuradio] / grc / gui / PropsDialog.py
index 200cff1f53fdf5a2f11159a1e03ec12c1d09abf2..cc84fd0888007f14d768b13d71ba7792fcc58818 100644 (file)
@@ -38,69 +38,116 @@ def get_title_label(title):
        return hbox
 
 class PropsDialog(gtk.Dialog):
-       """A dialog box to set block parameters."""
+       """
+       A dialog to set block parameters, view errors, and view documentation.
+       """
 
        def __init__(self, block):
                """
-               SignalBlockParamsDialog contructor.
-               @param block the signal block
+               Properties dialog contructor.
+               @param block a block instance
                """
+               self._hash = 0
+               LABEL_SPACING = 7
                gtk.Dialog.__init__(self,
                        title='Properties: %s'%block.get_name(),
-                       buttons=(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE),
+                       buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT),
                )
-               self.block = block
+               self._block = block
                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)
+               #Params box for block parameters
+               self._params_box = gtk.VBox()
+               self._params_box.pack_start(get_title_label('Parameters'), False)
+               self._input_object_params = list()
                #Error Messages for the block
                self._error_box = gtk.VBox()
                self._error_messages_text_display = TextDisplay()
-               self._error_box.pack_start(gtk.Label(), False, False, 7) #spacing
+               self._error_box.pack_start(gtk.Label(), False, False, LABEL_SPACING)
                self._error_box.pack_start(get_title_label('Error Messages'), False)
                self._error_box.pack_start(self._error_messages_text_display, False)
                #Docs for the block
                self._docs_box = err_box = gtk.VBox()
                self._docs_text_display = TextDisplay()
-               self._docs_box.pack_start(gtk.Label(), False, False, 7) #spacing
+               self._docs_box.pack_start(gtk.Label(), False, False, LABEL_SPACING)
                self._docs_box.pack_start(get_title_label('Documentation'), False)
                self._docs_box.pack_start(self._docs_text_display, False)
-               #Add all the parameters
-               for param in self.block.get_params():
-                       vbox.pack_start(param.get_input_object(self._handle_changed), False)
-               #Add the error and docs box
+               #Add the boxes
+               vbox.pack_start(self._params_box, False)
                vbox.pack_start(self._error_box, False)
                vbox.pack_start(self._docs_box, False)
-               #connect and show
-               self.connect('key_press_event', self._handle_key_press)
+               #connect events
+               self.connect('key-press-event', self._handle_key_press)
+               self.connect('show', self._update_gui)
+               #show all (performs initial gui update)
                self.show_all()
-               #initial update
-               for param in self.block.get_params(): param.update()
-               self._update()
 
-       def _update(self):
+       def _params_changed(self):
+               """
+               Have the params in this dialog changed?
+               Ex: Added, removed, type change, hide change...
+               To the props dialog, the hide setting of 'none' and 'part' are identical.
+               Therfore, the props dialog only cares if the hide setting is/not 'all'.
+               Make a hash that uniquely represents the params' state.
+               @return true if changed
+               """
+               old_hash = self._hash
+               #create a tuple of things from each param that affects the params box
+               self._hash = hash(tuple([(
+                       hash(param), param.get_type(), param.get_hide() == 'all',
+               ) for param in self._block.get_params()]))
+               return self._hash != old_hash
+
+       def _handle_changed(self, *args):
+               """
+               A change occured within a param:
+               Rewrite/validate the block and update the gui.
                """
+               #update for the block
+               self._block.rewrite()
+               self._block.validate()
+               self._update_gui()
+
+       def _update_gui(self, *args):
+               """
+               Repopulate the parameters box (if changed).
+               Update all the input parameters.
                Update the error messages box.
                Hide the box if there are no errors.
                Update the documentation block.
                Hide the box if there are no docs.
                """
-               self.block.validate()
+               #update the params box
+               if self._params_changed():
+                       #hide params box before changing
+                       self._params_box.hide_all()
+                       #empty the params box
+                       for io_param in list(self._input_object_params):
+                               self._params_box.remove(io_param)
+                               self._input_object_params.remove(io_param)
+                               io_param.destroy()
+                       #repopulate the params box
+                       for param in self._block.get_params():
+                               if param.get_hide() == 'all': continue
+                               io_param = param.get_input(self._handle_changed)
+                               self._input_object_params.append(io_param)
+                               self._params_box.pack_start(io_param, False)
+                       #show params box with new params
+                       self._params_box.show_all()
                #update the errors box
-               if self.block.is_valid(): self._error_box.hide()
+               if self._block.is_valid(): self._error_box.hide()
                else: self._error_box.show()
-               messages = '\n\n'.join(self.block.get_error_messages())
+               messages = '\n\n'.join(self._block.get_error_messages())
                self._error_messages_text_display.set_text(messages)
                #update the docs box
-               if self.block.get_doc(): self._docs_box.show()
+               if self._block.get_doc(): self._docs_box.show()
                else: self._docs_box.hide()
-               self._docs_text_display.set_text(self.block.get_doc())
+               self._docs_text_display.set_text(self._block.get_doc())
 
        def _handle_key_press(self, widget, event):
                """
@@ -108,38 +155,16 @@ class PropsDialog(gtk.Dialog):
                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)
+               if event.keyval == gtk.keysyms.Return:
+                       self.response(gtk.RESPONSE_ACCEPT)
+                       return True #handled here
                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
-               """
-               #update dependent params
-               if param.is_enum():
-                       for other_param in param.get_parent().get_params():
-                               if param.get_key() is not other_param.get_key() and (
-                               param.get_key() in other_param._type or \
-                               param.get_key() in other_param._hide): other_param.update()
-               #update
-               self._update()
-               return True
-
        def run(self):
                """
-               Call run().
-               @return true if a change occured.
+               Run the dialog and get its response.
+               @return true if the response was accept
                """
-               original_data = list()
-               for param in self.block.get_params():
-                       original_data.append(param.get_value())
-               gtk.Dialog.run(self)
+               response = 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
+               return response == gtk.RESPONSE_ACCEPT