commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] r5878 - in grc/trunk: . examples examples/audio exampl


From: jblum
Subject: [Commit-gnuradio] r5878 - in grc/trunk: . examples examples/audio examples/xmlrpc notes src src/Elements src/Graphics src/SignalBlockDefs
Date: Fri, 29 Jun 2007 11:41:27 -0600 (MDT)

Author: jblum
Date: 2007-06-29 11:41:26 -0600 (Fri, 29 Jun 2007)
New Revision: 5878

Added:
   grc/trunk/examples/audio/b_flat_scale.grc.xml
   grc/trunk/examples/audio/phone_tones.grc.xml
   grc/trunk/examples/channel_distortion.grc.xml
   grc/trunk/examples/noisy_sinusoid.grc.xml
   grc/trunk/examples/null_to_null.grc.xml
   grc/trunk/examples/packet_mod_demod.grc.xml
   grc/trunk/examples/selector.grc.xml
   grc/trunk/examples/valve.grc.xml
   grc/trunk/examples/xmlrpc/
   grc/trunk/examples/xmlrpc/client.py
   grc/trunk/examples/xmlrpc/readme.txt
   grc/trunk/examples/xmlrpc/server.sh
   grc/trunk/examples/xmlrpc/tone.grc.xml
   grc/trunk/notes/programming_style.txt
   grc/trunk/readme.txt
   grc/trunk/src/DataTypes.py
   grc/trunk/src/ExecFlowGraphXMLRPC.py
   grc/trunk/src/Graphics/FileDialogs.py
   grc/trunk/src/SignalBlockDefs/Custom.py
   grc/trunk/src/SignalBlockDefs/Packet.py
Removed:
   grc/trunk/README.txt
   grc/trunk/examples/audio/B flat.grc.xml
   grc/trunk/examples/audio/phone tones.grc.xml
   grc/trunk/examples/channel noise.grc.xml
   grc/trunk/examples/noisy sinusoid.grc.xml
   grc/trunk/examples/null to null.grc.xml
   grc/trunk/examples/qam.grc.xml
   grc/trunk/examples/xmlrpc/client.py
   grc/trunk/examples/xmlrpc/readme.txt
   grc/trunk/examples/xmlrpc/server.sh
   grc/trunk/examples/xmlrpc/tone.grc.xml
   grc/trunk/src/DataType.py
   grc/trunk/src/Graphics/FlowGraphFileDialog.py
Modified:
   grc/trunk/examples/variable_sink.grc.xml
   grc/trunk/notes/notes.txt
   grc/trunk/src/
   grc/trunk/src/ActionHandler.py
   grc/trunk/src/Actions.py
   grc/trunk/src/Colors.py
   grc/trunk/src/Constants.py
   grc/trunk/src/Editor.py
   grc/trunk/src/Elements/
   grc/trunk/src/Elements/Connection.py
   grc/trunk/src/Elements/Element.py
   grc/trunk/src/Elements/GraphicalConnection.py
   grc/trunk/src/Elements/GraphicalElement.py
   grc/trunk/src/Elements/GraphicalParam.py
   grc/trunk/src/Elements/GraphicalSignalBlock.py
   grc/trunk/src/Elements/GraphicalSocket.py
   grc/trunk/src/Elements/Param.py
   grc/trunk/src/Elements/SignalBlock.py
   grc/trunk/src/Elements/Socket.py
   grc/trunk/src/Elements/Utils.py
   grc/trunk/src/Elements/__init__.py
   grc/trunk/src/ExecFlowGraph.py
   grc/trunk/src/ExecFlowGraphGUI.py
   grc/trunk/src/Graphics/
   grc/trunk/src/Graphics/Bars.py
   grc/trunk/src/Graphics/Dialogs.py
   grc/trunk/src/Graphics/FlowGraph.py
   grc/trunk/src/Graphics/MainWindow.py
   grc/trunk/src/Graphics/SignalBlockParamsDialog.py
   grc/trunk/src/Graphics/SignalBlockSelectionWindow.py
   grc/trunk/src/Graphics/USRPDiagnostics.py
   grc/trunk/src/Graphics/VariableModificationWindow.py
   grc/trunk/src/Graphics/__init__.py
   grc/trunk/src/MathExprParser.py
   grc/trunk/src/Messages.py
   grc/trunk/src/ParseXML.py
   grc/trunk/src/Preferences.py
   grc/trunk/src/SignalBlockDefs/
   grc/trunk/src/SignalBlockDefs/Coders.py
   grc/trunk/src/SignalBlockDefs/Conversions.py
   grc/trunk/src/SignalBlockDefs/Filters.py
   grc/trunk/src/SignalBlockDefs/GraphicalSinks.py
   grc/trunk/src/SignalBlockDefs/Misc.py
   grc/trunk/src/SignalBlockDefs/Modulators.py
   grc/trunk/src/SignalBlockDefs/Operators.py
   grc/trunk/src/SignalBlockDefs/SignalBlockConstants.py
   grc/trunk/src/SignalBlockDefs/SignalBlockTree.py
   grc/trunk/src/SignalBlockDefs/Sinks.py
   grc/trunk/src/SignalBlockDefs/Sources.py
   grc/trunk/src/SignalBlockDefs/Trellis.py
   grc/trunk/src/SignalBlockDefs/USRP.py
   grc/trunk/src/SignalBlockDefs/__init__.py
   grc/trunk/src/StateCache.py
   grc/trunk/src/Variables.py
Log:
merged branch/jblum_work into trunk

Deleted: grc/trunk/README.txt

Deleted: grc/trunk/examples/audio/B flat.grc.xml

Copied: grc/trunk/examples/audio/b_flat_scale.grc.xml (from rev 5877, 
grc/branches/jblum_work/examples/audio/b_flat_scale.grc.xml)
===================================================================
--- grc/trunk/examples/audio/b_flat_scale.grc.xml                               
(rev 0)
+++ grc/trunk/examples/audio/b_flat_scale.grc.xml       2007-06-29 17:41:26 UTC 
(rev 5878)
@@ -0,0 +1,116 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<flow_graph>
+  <timestamp>1179256591.06</timestamp>
+  <hostname>bowlcut</hostname>
+  <version>0.70 alpha</version>
+  <valid>True</valid>
+  <window_width>800</window_width>
+  <window_height>600</window_height>
+  <vars>
+    <var>
+      <key>samp_rate</key>
+      <value>32000</value>
+      <min/>
+      <max/>
+      <step/>
+    </var>
+    <var>
+      <key>A</key>
+      <value>440</value>
+      <min/>
+      <max/>
+      <step/>
+    </var>
+    <var>
+      <key>n</key>
+      <value>0</value>
+      <min>-4</min>
+      <max>8</max>
+      <step>1</step>
+    </var>
+    <var>
+      <key>volume</key>
+      <value>.1</value>
+      <min>0</min>
+      <max>.5</max>
+      <step>0.005</step>
+    </var>
+  </vars>
+  <signal_blocks>
+    <signal_block>
+      <tag>About</tag>
+      <id>About0</id>
+      <x_coordinate>91</x_coordinate>
+      <y_coordinate>41</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>B flat</param>
+        <param>Josh Blum</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Note</tag>
+      <id>Note0</id>
+      <x_coordinate>30</x_coordinate>
+      <y_coordinate>136</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>Generate pure musical tones.</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Scope Sink</tag>
+      <id>Scope Sink0</id>
+      <x_coordinate>31</x_coordinate>
+      <y_coordinate>251</y_coordinate>
+      <rotation>180</rotation>
+      <params>
+        <param>1</param>
+        <param>Scope</param>
+        <param>$samp_rate</param>
+        <param>1</param>
+        <param>.1</param>
+        <param>.001</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Audio Sink</tag>
+      <id>Audio Sink0</id>
+      <x_coordinate>27</x_coordinate>
+      <y_coordinate>429</y_coordinate>
+      <rotation>180</rotation>
+      <params>
+        <param>3</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Signal Source</tag>
+      <id>Signal Source0</id>
+      <x_coordinate>411</x_coordinate>
+      <y_coordinate>344</y_coordinate>
+      <rotation>180</rotation>
+      <params>
+        <param>1</param>
+        <param>$samp_rate</param>
+        <param>1</param>
+        <param>$A*2^($n/12)</param>
+        <param>$volume</param>
+        <param>0</param>
+      </params>
+    </signal_block>
+  </signal_blocks>
+  <connections>
+    <connection>
+      <input_signal_block_id>Audio Sink0</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>Signal Source0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+    <connection>
+      <input_signal_block_id>Scope Sink0</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>Signal Source0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+  </connections>
+</flow_graph>

Deleted: grc/trunk/examples/audio/phone tones.grc.xml

Copied: grc/trunk/examples/audio/phone_tones.grc.xml (from rev 5877, 
grc/branches/jblum_work/examples/audio/phone_tones.grc.xml)
===================================================================
--- grc/trunk/examples/audio/phone_tones.grc.xml                                
(rev 0)
+++ grc/trunk/examples/audio/phone_tones.grc.xml        2007-06-29 17:41:26 UTC 
(rev 5878)
@@ -0,0 +1,206 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<flow_graph>
+  <timestamp>1179256705.05</timestamp>
+  <hostname>bowlcut</hostname>
+  <version>0.70 alpha</version>
+  <valid>True</valid>
+  <window_width>1200</window_width>
+  <window_height>800</window_height>
+  <vars>
+    <var>
+      <key>samp_rate</key>
+      <value>32e3</value>
+      <min/>
+      <max/>
+      <step/>
+    </var>
+    <var>
+      <key>volume</key>
+      <value>.1</value>
+      <min>0</min>
+      <max>.5</max>
+      <step>0.005</step>
+    </var>
+    <var>
+      <key>noise</key>
+      <value>.01</value>
+      <min>0</min>
+      <max>.1</max>
+      <step>0.001</step>
+    </var>
+  </vars>
+  <signal_blocks>
+    <signal_block>
+      <tag>Signal Source</tag>
+      <id>Signal Source1</id>
+      <x_coordinate>192</x_coordinate>
+      <y_coordinate>377</y_coordinate>
+      <rotation>90</rotation>
+      <params>
+        <param>1</param>
+        <param>$samp_rate</param>
+        <param>1</param>
+        <param>440</param>
+        <param>1</param>
+        <param>0</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Noise Source</tag>
+      <id>Noise Source0</id>
+      <x_coordinate>335</x_coordinate>
+      <y_coordinate>364</y_coordinate>
+      <rotation>90</rotation>
+      <params>
+        <param>1</param>
+        <param>1</param>
+        <param>$noise</param>
+        <param>71</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>FFT Sink</tag>
+      <id>FFT Sink0</id>
+      <x_coordinate>856</x_coordinate>
+      <y_coordinate>366</y_coordinate>
+      <rotation>270</rotation>
+      <params>
+        <param>1</param>
+        <param>FFT</param>
+        <param>$samp_rate</param>
+        <param>20</param>
+        <param>20</param>
+        <param>512</param>
+        <param>15</param>
+        <param>0</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Signal Source</tag>
+      <id>Signal Source0</id>
+      <x_coordinate>34</x_coordinate>
+      <y_coordinate>366</y_coordinate>
+      <rotation>90</rotation>
+      <params>
+        <param>1</param>
+        <param>$samp_rate</param>
+        <param>1</param>
+        <param>350</param>
+        <param>1</param>
+        <param>0</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Scope Sink</tag>
+      <id>Scope Sink0</id>
+      <x_coordinate>562</x_coordinate>
+      <y_coordinate>387</y_coordinate>
+      <rotation>270</rotation>
+      <params>
+        <param>1</param>
+        <param>Scope</param>
+        <param>$samp_rate</param>
+        <param>1</param>
+        <param>0</param>
+        <param>0.001</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Audio Sink</tag>
+      <id>Audio Sink0</id>
+      <x_coordinate>742</x_coordinate>
+      <y_coordinate>409</y_coordinate>
+      <rotation>270</rotation>
+      <params>
+        <param>3</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Multiply Constant</tag>
+      <id>Multiply Constant0</id>
+      <x_coordinate>594</x_coordinate>
+      <y_coordinate>221</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>1</param>
+        <param>$volume</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Add</tag>
+      <id>Add0</id>
+      <x_coordinate>420</x_coordinate>
+      <y_coordinate>133</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>1</param>
+        <param>3</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Note</tag>
+      <id>Note0</id>
+      <x_coordinate>362</x_coordinate>
+      <y_coordinate>58</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>350 hz + 440 hz + AWGN</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>About</tag>
+      <id>About0</id>
+      <x_coordinate>71</x_coordinate>
+      <y_coordinate>48</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>The Famous Phone Tones</param>
+        <param>Josh Blum</param>
+      </params>
+    </signal_block>
+  </signal_blocks>
+  <connections>
+    <connection>
+      <input_signal_block_id>Add0</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>Signal Source0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+    <connection>
+      <input_signal_block_id>Add0</input_signal_block_id>
+      <input_socket_index>1</input_socket_index>
+      <output_signal_block_id>Signal Source1</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+    <connection>
+      <input_signal_block_id>Multiply Constant0</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>Add0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+    <connection>
+      <input_signal_block_id>Audio Sink0</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>Multiply Constant0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+    <connection>
+      <input_signal_block_id>Add0</input_signal_block_id>
+      <input_socket_index>2</input_socket_index>
+      <output_signal_block_id>Noise Source0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+    <connection>
+      <input_signal_block_id>FFT Sink0</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>Multiply Constant0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+    <connection>
+      <input_signal_block_id>Scope Sink0</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>Multiply Constant0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+  </connections>
+</flow_graph>

Deleted: grc/trunk/examples/channel noise.grc.xml

Copied: grc/trunk/examples/channel_distortion.grc.xml (from rev 5877, 
grc/branches/jblum_work/examples/channel_distortion.grc.xml)
===================================================================
--- grc/trunk/examples/channel_distortion.grc.xml                               
(rev 0)
+++ grc/trunk/examples/channel_distortion.grc.xml       2007-06-29 17:41:26 UTC 
(rev 5878)
@@ -0,0 +1,120 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<flow_graph>
+  <timestamp>1182222914.4</timestamp>
+  <hostname>tiggle</hostname>
+  <version>0.70 alpha</version>
+  <valid>True</valid>
+  <window_width>1200</window_width>
+  <window_height>800</window_height>
+  <vars>
+    <var>
+      <key>samp_rate</key>
+      <value>32e3</value>
+      <min/>
+      <max/>
+      <step/>
+    </var>
+    <var>
+      <key>freq</key>
+      <value>1000</value>
+      <min>0</min>
+      <max>5000</max>
+      <step>50.0</step>
+    </var>
+  </vars>
+  <signal_blocks>
+    <signal_block>
+      <tag>FFT Sink</tag>
+      <id>FFT Sink0</id>
+      <x_coordinate>571</x_coordinate>
+      <y_coordinate>76</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>0</param>
+        <param>FFT - Distorted</param>
+        <param>$samp_rate</param>
+        <param>20</param>
+        <param>20</param>
+        <param>512</param>
+        <param>15</param>
+        <param>0</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>FFT Sink</tag>
+      <id>FFT Sink1</id>
+      <x_coordinate>573</x_coordinate>
+      <y_coordinate>266</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>0</param>
+        <param>FFT - Input</param>
+        <param>$samp_rate</param>
+        <param>20</param>
+        <param>20</param>
+        <param>512</param>
+        <param>15</param>
+        <param>0</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Channel Model</tag>
+      <id>Channel Model0</id>
+      <x_coordinate>317</x_coordinate>
+      <y_coordinate>101</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>.2</param>
+        <param>0.0</param>
+        <param>1.0</param>
+        <param>1.0,0.0</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Signal Source</tag>
+      <id>Signal Source0</id>
+      <x_coordinate>66</x_coordinate>
+      <y_coordinate>193</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>0</param>
+        <param>$samp_rate</param>
+        <param>1</param>
+        <param>$freq</param>
+        <param>1</param>
+        <param>0</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>About</tag>
+      <id>About0</id>
+      <x_coordinate>59</x_coordinate>
+      <y_coordinate>75</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>Channel Distortion</param>
+        <param>Josh Blum</param>
+      </params>
+    </signal_block>
+  </signal_blocks>
+  <connections>
+    <connection>
+      <input_signal_block_id>Channel Model0</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>Signal Source0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+    <connection>
+      <input_signal_block_id>FFT Sink1</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>Signal Source0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+    <connection>
+      <input_signal_block_id>FFT Sink0</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>Channel Model0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+  </connections>
+</flow_graph>

Deleted: grc/trunk/examples/noisy sinusoid.grc.xml

Copied: grc/trunk/examples/noisy_sinusoid.grc.xml (from rev 5877, 
grc/branches/jblum_work/examples/noisy_sinusoid.grc.xml)
===================================================================
--- grc/trunk/examples/noisy_sinusoid.grc.xml                           (rev 0)
+++ grc/trunk/examples/noisy_sinusoid.grc.xml   2007-06-29 17:41:26 UTC (rev 
5878)
@@ -0,0 +1,168 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<flow_graph>
+  <timestamp>1179256658.68</timestamp>
+  <hostname>bowlcut</hostname>
+  <version>0.70 alpha</version>
+  <valid>True</valid>
+  <window_width>1000</window_width>
+  <window_height>600</window_height>
+  <vars>
+    <var>
+      <key>samp_rate</key>
+      <value>32000</value>
+      <min/>
+      <max/>
+      <step/>
+    </var>
+    <var>
+      <key>source_freq</key>
+      <value>350</value>
+      <min>300</min>
+      <max>1e3</max>
+      <step>7.0</step>
+    </var>
+    <var>
+      <key>noise_amp</key>
+      <value>.005</value>
+      <min>.005</min>
+      <max>.05</max>
+      <step>0.001</step>
+    </var>
+  </vars>
+  <signal_blocks>
+    <signal_block>
+      <tag>Note</tag>
+      <id>Note0</id>
+      <x_coordinate>514</x_coordinate>
+      <y_coordinate>24</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>An example of additive noise.</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>About</tag>
+      <id>About0</id>
+      <x_coordinate>333</x_coordinate>
+      <y_coordinate>26</y_coordinate>
+      <rotation>180</rotation>
+      <params>
+        <param>Noisy Sinusoid</param>
+        <param>Josh Blum</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Noise Source</tag>
+      <id>Noise Source0</id>
+      <x_coordinate>615</x_coordinate>
+      <y_coordinate>357</y_coordinate>
+      <rotation>90</rotation>
+      <params>
+        <param>1</param>
+        <param>1</param>
+        <param>$noise_amp</param>
+        <param>79</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Audio Sink</tag>
+      <id>Audio Sink0</id>
+      <x_coordinate>280</x_coordinate>
+      <y_coordinate>377</y_coordinate>
+      <rotation>270</rotation>
+      <params>
+        <param>3</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Signal Source</tag>
+      <id>Signal Source0</id>
+      <x_coordinate>625</x_coordinate>
+      <y_coordinate>133</y_coordinate>
+      <rotation>180</rotation>
+      <params>
+        <param>1</param>
+        <param>$samp_rate</param>
+        <param>1</param>
+        <param>$source_freq</param>
+        <param>.1</param>
+        <param>0</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>FFT Sink</tag>
+      <id>FFT Sink0</id>
+      <x_coordinate>71</x_coordinate>
+      <y_coordinate>70</y_coordinate>
+      <rotation>180</rotation>
+      <params>
+        <param>1</param>
+        <param>FFT</param>
+        <param>$samp_rate</param>
+        <param>20</param>
+        <param>20</param>
+        <param>512</param>
+        <param>15</param>
+        <param>0</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Scope Sink</tag>
+      <id>Scope Sink0</id>
+      <x_coordinate>53</x_coordinate>
+      <y_coordinate>238</y_coordinate>
+      <rotation>180</rotation>
+      <params>
+        <param>1</param>
+        <param>Scope</param>
+        <param>$samp_rate</param>
+        <param>1</param>
+        <param>0</param>
+        <param>0.001</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Add</tag>
+      <id>Add0</id>
+      <x_coordinate>427</x_coordinate>
+      <y_coordinate>217</y_coordinate>
+      <rotation>180</rotation>
+      <params>
+        <param>1</param>
+        <param>2</param>
+      </params>
+    </signal_block>
+  </signal_blocks>
+  <connections>
+    <connection>
+      <input_signal_block_id>Add0</input_signal_block_id>
+      <input_socket_index>1</input_socket_index>
+      <output_signal_block_id>Signal Source0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+    <connection>
+      <input_signal_block_id>Add0</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>Noise Source0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+    <connection>
+      <input_signal_block_id>Audio Sink0</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>Add0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+    <connection>
+      <input_signal_block_id>FFT Sink0</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>Add0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+    <connection>
+      <input_signal_block_id>Scope Sink0</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>Add0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+  </connections>
+</flow_graph>

Deleted: grc/trunk/examples/null to null.grc.xml

Copied: grc/trunk/examples/null_to_null.grc.xml (from rev 5877, 
grc/branches/jblum_work/examples/null_to_null.grc.xml)
===================================================================
--- grc/trunk/examples/null_to_null.grc.xml                             (rev 0)
+++ grc/trunk/examples/null_to_null.grc.xml     2007-06-29 17:41:26 UTC (rev 
5878)
@@ -0,0 +1,52 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<flow_graph>
+  <timestamp>1179256695.11</timestamp>
+  <hostname>bowlcut</hostname>
+  <version>0.70 alpha</version>
+  <valid>True</valid>
+  <window_width>1200</window_width>
+  <window_height>800</window_height>
+  <vars/>
+  <signal_blocks>
+    <signal_block>
+      <tag>Null Source</tag>
+      <id>Null Source0</id>
+      <x_coordinate>168</x_coordinate>
+      <y_coordinate>250</y_coordinate>
+      <rotation>270</rotation>
+      <params>
+        <param>1</param>
+        <param>1</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Null Sink</tag>
+      <id>Null Sink0</id>
+      <x_coordinate>307</x_coordinate>
+      <y_coordinate>270</y_coordinate>
+      <rotation>270</rotation>
+      <params>
+        <param>1</param>
+        <param>1</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Note</tag>
+      <id>Note0</id>
+      <x_coordinate>172</x_coordinate>
+      <y_coordinate>121</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>Use 100% CPU</param>
+      </params>
+    </signal_block>
+  </signal_blocks>
+  <connections>
+    <connection>
+      <input_signal_block_id>Null Sink0</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>Null Source0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+  </connections>
+</flow_graph>

Copied: grc/trunk/examples/packet_mod_demod.grc.xml (from rev 5877, 
grc/branches/jblum_work/examples/packet_mod_demod.grc.xml)
===================================================================
--- grc/trunk/examples/packet_mod_demod.grc.xml                         (rev 0)
+++ grc/trunk/examples/packet_mod_demod.grc.xml 2007-06-29 17:41:26 UTC (rev 
5878)
@@ -0,0 +1,216 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<flow_graph>
+  <timestamp>1182980737.28</timestamp>
+  <hostname>tiggle</hostname>
+  <version>0.70 alpha</version>
+  <valid>True</valid>
+  <window_width>1600</window_width>
+  <window_height>1200</window_height>
+  <vars>
+    <var>
+      <key>samp_rate</key>
+      <value>100e3</value>
+      <min/>
+      <max/>
+      <step/>
+    </var>
+    <var>
+      <key>freq</key>
+      <value>2500</value>
+      <min>0</min>
+      <max>5000</max>
+      <step>50.0</step>
+    </var>
+    <var>
+      <key>amp</key>
+      <value>1</value>
+      <min>0</min>
+      <max>2</max>
+      <step>0.02</step>
+    </var>
+    <var>
+      <key>off</key>
+      <value>0</value>
+      <min>-1</min>
+      <max>1</max>
+      <step>0.02</step>
+    </var>
+  </vars>
+  <signal_blocks>
+    <signal_block>
+      <tag>Note</tag>
+      <id>Note0</id>
+      <x_coordinate>408</x_coordinate>
+      <y_coordinate>270</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>A demonstration of the packet framework.</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Packet Demodulator</tag>
+      <id>Packet Demodulator0</id>
+      <x_coordinate>535</x_coordinate>
+      <y_coordinate>427</y_coordinate>
+      <rotation>180</rotation>
+      <params>
+        <param>1</param>
+        <param/>
+        <param>-1</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Scope Sink</tag>
+      <id>Scope Sink0</id>
+      <x_coordinate>219</x_coordinate>
+      <y_coordinate>402</y_coordinate>
+      <rotation>180</rotation>
+      <params>
+        <param>1</param>
+        <param>Output</param>
+        <param>$samp_rate</param>
+        <param>1</param>
+        <param>0</param>
+        <param>0.001</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Signal Source</tag>
+      <id>Signal Source0</id>
+      <x_coordinate>26</x_coordinate>
+      <y_coordinate>354</y_coordinate>
+      <rotation>90</rotation>
+      <params>
+        <param>1</param>
+        <param>$samp_rate</param>
+        <param>1</param>
+        <param>$freq</param>
+        <param>$amp</param>
+        <param>$off</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Scope Sink</tag>
+      <id>Scope Sink1</id>
+      <x_coordinate>125</x_coordinate>
+      <y_coordinate>178</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>1</param>
+        <param>Input</param>
+        <param>$samp_rate</param>
+        <param>1</param>
+        <param>0</param>
+        <param>0.001</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Packet Modulator</tag>
+      <id>Packet Modulator0</id>
+      <x_coordinate>129</x_coordinate>
+      <y_coordinate>19</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>1</param>
+        <param>0</param>
+        <param>2</param>
+        <param>512</param>
+        <param/>
+        <param>0</param>
+        <param>1</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>GMSK Modulator</tag>
+      <id>GMSK Modulator0</id>
+      <x_coordinate>399</x_coordinate>
+      <y_coordinate>36</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>2</param>
+        <param>0.35</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>About</tag>
+      <id>About0</id>
+      <x_coordinate>480</x_coordinate>
+      <y_coordinate>176</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>Packet Mod/Demod</param>
+        <param>Josh Blum</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>GMSK Demodulator</tag>
+      <id>GMSK Demodulator0</id>
+      <x_coordinate>871</x_coordinate>
+      <y_coordinate>189</y_coordinate>
+      <rotation>270</rotation>
+      <params>
+        <param>2</param>
+        <param>0.05</param>
+        <param>0.5</param>
+        <param>0.005</param>
+        <param>0</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Throttle</tag>
+      <id>Throttle0</id>
+      <x_coordinate>703</x_coordinate>
+      <y_coordinate>36</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>0</param>
+        <param>$samp_rate*25</param>
+        <param>1</param>
+      </params>
+    </signal_block>
+  </signal_blocks>
+  <connections>
+    <connection>
+      <input_signal_block_id>Scope Sink1</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>Signal Source0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+    <connection>
+      <input_signal_block_id>Scope Sink0</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>Packet Demodulator0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+    <connection>
+      <input_signal_block_id>Packet Modulator0</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>Signal Source0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+    <connection>
+      <input_signal_block_id>GMSK Modulator0</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>Packet Modulator0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+    <connection>
+      <input_signal_block_id>Packet Demodulator0</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>GMSK Demodulator0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+    <connection>
+      <input_signal_block_id>Throttle0</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>GMSK Modulator0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+    <connection>
+      <input_signal_block_id>GMSK Demodulator0</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>Throttle0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+  </connections>
+</flow_graph>

Deleted: grc/trunk/examples/qam.grc.xml

Copied: grc/trunk/examples/selector.grc.xml (from rev 5877, 
grc/branches/jblum_work/examples/selector.grc.xml)
===================================================================
--- grc/trunk/examples/selector.grc.xml                         (rev 0)
+++ grc/trunk/examples/selector.grc.xml 2007-06-29 17:41:26 UTC (rev 5878)
@@ -0,0 +1,193 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<flow_graph>
+  <timestamp>1183066964.1</timestamp>
+  <hostname>tiggle</hostname>
+  <version>0.70 alpha</version>
+  <valid>True</valid>
+  <window_width>1400</window_width>
+  <window_height>600</window_height>
+  <vars>
+    <var>
+      <key>samp_rate</key>
+      <value>100e3</value>
+      <min/>
+      <max/>
+      <step/>
+    </var>
+    <var>
+      <key>index</key>
+      <value>1</value>
+      <min>-1</min>
+      <max>1</max>
+      <step>1</step>
+    </var>
+    <var>
+      <key>packet_len</key>
+      <value>128</value>
+      <min/>
+      <max/>
+      <step/>
+    </var>
+  </vars>
+  <signal_blocks>
+    <signal_block>
+      <tag>PSK Modulator</tag>
+      <id>PSK Modulator0</id>
+      <x_coordinate>500</x_coordinate>
+      <y_coordinate>341</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>1</param>
+        <param>2</param>
+        <param>0.35</param>
+        <param>0</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>GMSK Modulator</tag>
+      <id>GMSK Modulator0</id>
+      <x_coordinate>544</x_coordinate>
+      <y_coordinate>58</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>2</param>
+        <param>0.35</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Note</tag>
+      <id>Note0</id>
+      <x_coordinate>485</x_coordinate>
+      <y_coordinate>259</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>0=gmsk, 1=dqpsk, -1=disconnected</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Selector</tag>
+      <id>Selector1</id>
+      <x_coordinate>924</x_coordinate>
+      <y_coordinate>330</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>0</param>
+        <param>$index</param>
+        <param>0</param>
+        <param>2</param>
+        <param>1</param>
+        <param>1</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Selector</tag>
+      <id>Selector0</id>
+      <x_coordinate>264</x_coordinate>
+      <y_coordinate>68</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>4</param>
+        <param>0</param>
+        <param>$index</param>
+        <param>1</param>
+        <param>2</param>
+        <param>1</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Random Source</tag>
+      <id>Random Source0</id>
+      <x_coordinate>170</x_coordinate>
+      <y_coordinate>196</y_coordinate>
+      <rotation>180</rotation>
+      <params>
+        <param>3</param>
+        <param>1000</param>
+        <param>0</param>
+        <param>1</param>
+        <param>422291</param>
+        <param>0</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Constellation Sink</tag>
+      <id>Constellation Sink0</id>
+      <x_coordinate>886</x_coordinate>
+      <y_coordinate>114</y_coordinate>
+      <rotation>180</rotation>
+      <params>
+        <param>Ouput Constellation</param>
+        <param>$samp_rate</param>
+        <param>1</param>
+        <param>0</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Throttle</tag>
+      <id>Throttle0</id>
+      <x_coordinate>5</x_coordinate>
+      <y_coordinate>150</y_coordinate>
+      <rotation>90</rotation>
+      <params>
+        <param>4</param>
+        <param>$samp_rate</param>
+        <param>1</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>About</tag>
+      <id>About0</id>
+      <x_coordinate>504</x_coordinate>
+      <y_coordinate>164</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>Selecting Between Modulators</param>
+        <param>Josh Blum</param>
+      </params>
+    </signal_block>
+  </signal_blocks>
+  <connections>
+    <connection>
+      <input_signal_block_id>Selector1</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>GMSK Modulator0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+    <connection>
+      <input_signal_block_id>Selector1</input_signal_block_id>
+      <input_socket_index>1</input_socket_index>
+      <output_signal_block_id>PSK Modulator0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+    <connection>
+      <input_signal_block_id>Constellation Sink0</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>Selector1</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+    <connection>
+      <input_signal_block_id>GMSK Modulator0</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>Selector0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+    <connection>
+      <input_signal_block_id>PSK Modulator0</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>Selector0</output_signal_block_id>
+      <output_socket_index>1</output_socket_index>
+    </connection>
+    <connection>
+      <input_signal_block_id>Throttle0</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>Random Source0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+    <connection>
+      <input_signal_block_id>Selector0</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>Throttle0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+  </connections>
+</flow_graph>

Copied: grc/trunk/examples/valve.grc.xml (from rev 5877, 
grc/branches/jblum_work/examples/valve.grc.xml)
===================================================================
--- grc/trunk/examples/valve.grc.xml                            (rev 0)
+++ grc/trunk/examples/valve.grc.xml    2007-06-29 17:41:26 UTC (rev 5878)
@@ -0,0 +1,146 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<flow_graph>
+  <timestamp>1182897525.03</timestamp>
+  <hostname>tiggle</hostname>
+  <version>0.70 alpha</version>
+  <valid>True</valid>
+  <window_width>800</window_width>
+  <window_height>600</window_height>
+  <vars>
+    <var>
+      <key>samp_rate</key>
+      <value>100e3</value>
+      <min/>
+      <max/>
+      <step/>
+    </var>
+    <var>
+      <key>freq</key>
+      <value>2500</value>
+      <min>0</min>
+      <max>5000</max>
+      <step>50.0</step>
+    </var>
+    <var>
+      <key>amp</key>
+      <value>1</value>
+      <min>0</min>
+      <max>2</max>
+      <step>0.02</step>
+    </var>
+    <var>
+      <key>off</key>
+      <value>0</value>
+      <min>-1</min>
+      <max>1</max>
+      <step>0.02</step>
+    </var>
+    <var>
+      <key>open</key>
+      <value>0</value>
+      <min>-1</min>
+      <max>0</max>
+      <step>1</step>
+    </var>
+  </vars>
+  <signal_blocks>
+    <signal_block>
+      <tag>About</tag>
+      <id>About0</id>
+      <x_coordinate>20</x_coordinate>
+      <y_coordinate>20</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>Valve Demonstration</param>
+        <param>Josh Blum</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Valve</tag>
+      <id>Valve0</id>
+      <x_coordinate>270</x_coordinate>
+      <y_coordinate>150</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>1</param>
+        <param>$open</param>
+        <param>1</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Note</tag>
+      <id>Note0</id>
+      <x_coordinate>255</x_coordinate>
+      <y_coordinate>42</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>The valve is open and the data flow is allowed when open is 
0.</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Signal Source</tag>
+      <id>Signal Source0</id>
+      <x_coordinate>47</x_coordinate>
+      <y_coordinate>350</y_coordinate>
+      <rotation>90</rotation>
+      <params>
+        <param>1</param>
+        <param>$samp_rate</param>
+        <param>1</param>
+        <param>$freq</param>
+        <param>$amp</param>
+        <param>$off</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Scope Sink</tag>
+      <id>Scope Sink1</id>
+      <x_coordinate>241</x_coordinate>
+      <y_coordinate>248</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>1</param>
+        <param>Input</param>
+        <param>$samp_rate</param>
+        <param>1</param>
+        <param>0</param>
+        <param>0.001</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Scope Sink</tag>
+      <id>Scope Sink0</id>
+      <x_coordinate>276</x_coordinate>
+      <y_coordinate>405</y_coordinate>
+      <rotation>180</rotation>
+      <params>
+        <param>1</param>
+        <param>Output</param>
+        <param>$samp_rate</param>
+        <param>1</param>
+        <param>0</param>
+        <param>0.001</param>
+      </params>
+    </signal_block>
+  </signal_blocks>
+  <connections>
+    <connection>
+      <input_signal_block_id>Valve0</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>Signal Source0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+    <connection>
+      <input_signal_block_id>Scope Sink0</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>Valve0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+    <connection>
+      <input_signal_block_id>Scope Sink1</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>Signal Source0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+  </connections>
+</flow_graph>

Modified: grc/trunk/examples/variable_sink.grc.xml
===================================================================
--- grc/trunk/examples/variable_sink.grc.xml    2007-06-29 17:29:46 UTC (rev 
5877)
+++ grc/trunk/examples/variable_sink.grc.xml    2007-06-29 17:41:26 UTC (rev 
5878)
@@ -1,11 +1,11 @@
 <?xml version='1.0' encoding='UTF-8'?>
 <flow_graph>
-  <timestamp>1179795210.8</timestamp>
+  <timestamp>1182877130.19</timestamp>
   <hostname>tiggle</hostname>
   <version>0.70 alpha</version>
   <valid>True</valid>
-  <window_width>1600</window_width>
-  <window_height>1200</window_height>
+  <window_width>800</window_width>
+  <window_height>500</window_height>
   <vars>
     <var>
       <key>samp_rate_out</key>

Copied: grc/trunk/examples/xmlrpc (from rev 5877, 
grc/branches/jblum_work/examples/xmlrpc)

Deleted: grc/trunk/examples/xmlrpc/client.py

Copied: grc/trunk/examples/xmlrpc/client.py (from rev 5877, 
grc/branches/jblum_work/examples/xmlrpc/client.py)
===================================================================
--- grc/trunk/examples/xmlrpc/client.py                         (rev 0)
+++ grc/trunk/examples/xmlrpc/client.py 2007-06-29 17:41:26 UTC (rev 5878)
@@ -0,0 +1,33 @@
+#! /usr/bin/env python
+"""
+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
+"""
+
+from xmlrpclib import ServerProxy,Error
+import time
+
+server = ServerProxy("http://localhost:3030";)
+print server
+
+try:
+       for i in list(range(-4, 8))+list(reversed(range(-4, 9))):
+               print server.set_var('freq', 440*2**(i/12.0))
+               time.sleep(1)   
+       server.set_var('freq', 0) 
+except Error, v:
+    print "ERROR", v

Deleted: grc/trunk/examples/xmlrpc/readme.txt

Copied: grc/trunk/examples/xmlrpc/readme.txt (from rev 5877, 
grc/branches/jblum_work/examples/xmlrpc/readme.txt)
===================================================================
--- grc/trunk/examples/xmlrpc/readme.txt                                (rev 0)
+++ grc/trunk/examples/xmlrpc/readme.txt        2007-06-29 17:41:26 UTC (rev 
5878)
@@ -0,0 +1,22 @@
+##############################################
+#      XMLRPC
+##############################################
+
+XMLRPC allows a program to make remote function call over tcp.
+ExecFlowGraphXMLRPC.py executes a flow graph with an XMLRPC server.
+Any programing language can control the flow graph by making remote function 
calls.
+The functions calls can read and write to the flow graph's variables.
+The functions are documented at the top of ExecFlowGraphXMLRPC.py.
+
+##############################################
+#      Executing the example
+##############################################
+
+This example requires audio support in gnuradio!
+
+Start the server by executing server.sh in this directory.
+The server.sh script will execute ExecFlowGraphXMLRPC.py on tone.grc.xml
+
+Start the client by executing client.py. 
+The client will change the frequency of the tone once per second.
+The client changes the tone by making XMLRPC calls that set the variable 
'freq'.

Deleted: grc/trunk/examples/xmlrpc/server.sh

Copied: grc/trunk/examples/xmlrpc/server.sh (from rev 5877, 
grc/branches/jblum_work/examples/xmlrpc/server.sh)
===================================================================
--- grc/trunk/examples/xmlrpc/server.sh                         (rev 0)
+++ grc/trunk/examples/xmlrpc/server.sh 2007-06-29 17:41:26 UTC (rev 5878)
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+ADDR=localhost
+PORT=3030
+FLOWGRAPH=./tone.grc.xml
+
+python ../../src/ExecFlowGraphXMLRPC.py $FLOWGRAPH -a $ADDR -P $PORT

Deleted: grc/trunk/examples/xmlrpc/tone.grc.xml

Copied: grc/trunk/examples/xmlrpc/tone.grc.xml (from rev 5877, 
grc/branches/jblum_work/examples/xmlrpc/tone.grc.xml)
===================================================================
--- grc/trunk/examples/xmlrpc/tone.grc.xml                              (rev 0)
+++ grc/trunk/examples/xmlrpc/tone.grc.xml      2007-06-29 17:41:26 UTC (rev 
5878)
@@ -0,0 +1,60 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<flow_graph>
+  <timestamp>1181338235.34</timestamp>
+  <hostname>tiggle</hostname>
+  <version>0.70 alpha</version>
+  <valid>True</valid>
+  <window_width>1600</window_width>
+  <window_height>1200</window_height>
+  <vars>
+    <var>
+      <key>samp_rate</key>
+      <value>100e3</value>
+      <min/>
+      <max/>
+      <step/>
+    </var>
+    <var>
+      <key>freq</key>
+      <value>0</value>
+      <min>0</min>
+      <max>5000</max>
+      <step>50.0</step>
+    </var>
+  </vars>
+  <signal_blocks>
+    <signal_block>
+      <tag>Audio Sink</tag>
+      <id>Audio Sink0</id>
+      <x_coordinate>529</x_coordinate>
+      <y_coordinate>67</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>3</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Signal Source</tag>
+      <id>Signal Source0</id>
+      <x_coordinate>282</x_coordinate>
+      <y_coordinate>227</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>1</param>
+        <param>$samp_rate</param>
+        <param>1</param>
+        <param>$freq</param>
+        <param>.5</param>
+        <param>0</param>
+      </params>
+    </signal_block>
+  </signal_blocks>
+  <connections>
+    <connection>
+      <input_signal_block_id>Audio Sink0</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>Signal Source0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+  </connections>
+</flow_graph>

Modified: grc/trunk/notes/notes.txt
===================================================================
--- grc/trunk/notes/notes.txt   2007-06-29 17:29:46 UTC (rev 5877)
+++ grc/trunk/notes/notes.txt   2007-06-29 17:41:26 UTC (rev 5878)
@@ -1,26 +1,23 @@
 ############   Blocks to Add:  ####################
--blks.pkt mod/demod? (needs an instance of a mod/demod for a param)
+-ofdm
+-usrp misc settings
 -usrp dual and quad souce 
--blks blocks, add filesave for message reports
+-blks blocks, add filesave for logging
 -combine add/mult with add/mult vector
--selector blocks
+-tun/tap block (with input and output)
 
 ############   Known Problems: ####################
--in vars window, stop_editing doesnt work
 -file save, ask for overwrite even when appending file extension
 -blocks need to fix themselves when they go out of bounds, like in a resize
 -socket controllers should be intelligent on shrinkage
--the nested data variables should indicate that they are nested data -> 
variable_data
--rearanging variables doesnt have a handler
--changing an enum doesnt call update for params with variable datatypes 
 
 ############   Features to Add:        ####################
+-startup tips
+-math expr from file
 -save settings after close (working directory)
 -create sub-flow graphs to be used in larger flow graphs
--stdin/out communication protocal (non graphical)
 -include dtd in saved flow graphs
 -immediate display of tool tips in entry boxes
--function to import taps from a file
 -fm demod example with expansion of wfm_recv block
 
 ############   wxPython Features:      ####################
@@ -44,5 +41,9 @@
 -press enter to close params
 
 ############   Get GTK Stock IDs:      ####################
-       gtk.stock_list_ids()
+gtk.stock_list_ids()
+
+############   connect packet mod to demod:    ####################    
+gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST)
+gr.unpack_k_bits_bb(self.bits_per_symbol())
        
\ No newline at end of file

Copied: grc/trunk/notes/programming_style.txt (from rev 5877, 
grc/branches/jblum_work/notes/programming_style.txt)
===================================================================
--- grc/trunk/notes/programming_style.txt                               (rev 0)
+++ grc/trunk/notes/programming_style.txt       2007-06-29 17:41:26 UTC (rev 
5878)
@@ -0,0 +1,27 @@
+Programming Style
+
+1) Indentation:
+       Python dependends on correct indentation levels.
+       A tab character equals a single indentation level.
+       Most editors can display a tab as a user-defined width or number of 
spaces.
+       The expand command can convert a file with tab indentations to a file 
with space indentation. 
+       
+2)     Naming Conventions:
+       CamelCaseNames for files and classes.   
+       UPPER_CASE_NAMES for constants.
+       lower_case_names for public methods and all variables.
+       _underscored_lower_case_names for private methods.
+
+3) Documentation:
+       Source code follows the doxygen/javadoc conventions (and will be parsed 
by doxygen).
+       Files begin with a ##comment block, a package name, brief description, 
and author.
+       Constants follow a ##comment line.
+       All methods and classes require docstrings.
+       Docstrings with javadoc style entries need a leading "!".   
+
+4) Blank Lines:
+       Separate all classes and methods with a blank line.
+       Group related constants and separate unrelated constants with a blank 
line.
+       Leave 2 blank lines at the end of every file.
+       
+       
\ No newline at end of file

Copied: grc/trunk/readme.txt (from rev 5877, grc/branches/jblum_work/readme.txt)
===================================================================
--- grc/trunk/readme.txt                                (rev 0)
+++ grc/trunk/readme.txt        2007-06-29 17:41:26 UTC (rev 5878)
@@ -0,0 +1,13 @@
+Hello!
+
+Thank you for downloading GNU Radio Companion.
+This program is free software. 
+A GPL license is distributed with this program.
+This license covers all the source code/python files. 
+You will also find a "creative common license" for the grc icon.
+
+Intructions for GRC are available at:
+http://gnuradio.org/trac/wiki/GNURadioCompanion
+
+If you have questions, problems, suggestions, or want to contribute,
+please email me at jblum at jhu dot edu


Property changes on: grc/trunk/src
___________________________________________________________________
Name: svn:ignore
   - *.pyc


Modified: grc/trunk/src/ActionHandler.py
===================================================================
--- grc/trunk/src/ActionHandler.py      2007-06-29 17:29:46 UTC (rev 5877)
+++ grc/trunk/src/ActionHandler.py      2007-06-29 17:41:26 UTC (rev 5878)
@@ -16,12 +16,10 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       ActionHandler.py 
-       Josh Blum
-       ActionHandler puts the entire application together by setting up all 
the windows 
-               including the flow graph and ActionHandler handles most of the 
user inputs.             
-"""
address@hidden ActionHandler
+#ActionHandler builds the interface and handles most of the user inputs.       
        
address@hidden Josh Blum
+
 import os, sys
 from Constants import *
 from Actions import *
@@ -36,13 +34,20 @@
 import Messages
 
 class ActionHandler:
-       """     The action handler will create all the major window components 
and handle state changes. 
-       The action handler also contains methods to handle the action buttons 
and state changes.        """
+       """
+       The action handler will setup all the major window components,
+       and handle button presses and flow graph operations from the GUI.
+       """
        def __init__(self, input_arg_file_path=''): 
-               """ Parse the config files for signals blocks and gtk actions. 
Connect the actions to the handler method.
-               Create a new Flow Graph and main_window as well as a few misc 
dialog boxes. Enter the gtk main loop.    """                             
+               """!
+               ActionHandler constructor.
+               Parse the config files for signals blocks and gtk actions. 
Connect the actions to the handler method.
+               Create a new main window, intialize preferences and the message 
handler. 
+               Finally, enter the gtk main loop and block
+               @param input_arg_file_path a flow graph file passed from 
command line           
+               """                             
                if PY_GTK_ICON: 
gtk.window_set_default_icon_from_file(PY_GTK_ICON)
-               for action in ACTIONS_LIST: action.connect('activate', 
self.handle_actions)     
+               for action in ACTIONS_LIST: action.connect('activate', 
self._handle_actions)    
                self.pid_file = None                            
                ### create the main window and setup the Messages       ###
                self.main_window = Graphics.MainWindow(self.handle_states)
@@ -50,13 +55,12 @@
                Messages.register_messenger(sys.stdout.write)
                Messages.send_init()
                self.flow_graph = self.main_window.flow_graph
-               self.main_window.connect('delete_event', self.quit)
-               self.main_window.connect('key_press_event', 
self.handle_key_press)
-               Preferences.load(self.main_window)
-               self.main_window.show()#show after resize in preferences
+               self.main_window.connect('delete_event', self._quit)
+               self.main_window.connect('key_press_event', 
self._handle_key_press)
                #       determine the initial flow graph file, preference to 
command line input #
                if input_arg_file_path: self.flow_graph_file_path = 
os.path.abspath(input_arg_file_path)        
                else: self.flow_graph_file_path = 
Preferences.get_default_flow_graph()
+               self.saved = True
                self.handle_states(APPLICATION_INITIALIZE)
                # enter the mainloop            
                gtk.gdk.threads_init()
@@ -64,15 +68,19 @@
                gtk.main()
                gtk.gdk.threads_leave()         
                
-       def handle_key_press(self, widget, event):
-               """ Handle key press events and translate key combos into 
actions.      
-                       Key combinations that do not include special keys, such 
as ctrl or Fcn*,
-                       require that the flow graph has mouse focus."""
+       def _handle_key_press(self, widget, event):
+               """
+               Handle key presses from the keyboard.           
+               Translate key combos into actions.      
+               Key combinations that do not include special keys, such as ctrl 
or Fcn*,
+               Also, require that the flow graph has mouse focus when choosing 
to handle keys.
+               @return true if the flow graph is in active use
+               """
                keyname = gtk.gdk.keyval_name(event.keyval)
                #print 'Key "%s" (%d) was pressed' % (keyname, event.keyval)
-               if event.state & gtk.gdk.CONTROL_MASK: print "Control was being 
held down"
-               if event.state & gtk.gdk.MOD1_MASK: print "Alt was being held 
down"
-               if event.state & gtk.gdk.SHIFT_MASK: print "Shift was being 
held down"          
+               #if event.state & gtk.gdk.CONTROL_MASK: print "Control was 
being held down"
+               #if event.state & gtk.gdk.MOD1_MASK: print "Alt was being held 
down"
+               #if event.state & gtk.gdk.SHIFT_MASK: print "Shift was being 
held down"         
                ####################    save/open/new/undo/redo 
############################### 
                if event.state & gtk.gdk.CONTROL_MASK and keyname == 's':
                        self.handle_states(FLOW_GRAPH_SAVE)
@@ -112,25 +120,34 @@
                #propagate this if the fg is not in focus or nothing is selected
                return self.flow_graph.get_focus_flag() and 
self.flow_graph.is_selected()
         
-       def quit(self, window, event):
-               """     Handle the delete event from the main window, like 
pressing X to close, alt+f4, or right click+close.   
-               This method in turns calls the state handler with a 'quit' 
string so all quitting can be handled in one place.  """
+       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. 
+               This method in turns calls the state handler to quit.
+               @return true            
+               """
                self.handle_states(APPLICATION_QUIT)
                return True     
        
-       def handle_actions(self, event):                
-               """ Handle all of the activate signals from the gtk actions. 
The action signals derive from clicking on a
-                       toolbar or menu bar button. The name of the action is 
passed through the event and a series of 
-                       if/elif statements handle the action appropriately.     
"""
-               name = event.get_name()
-               self.handle_states(name)                
+       def _handle_actions(self, event):               
+               """
+               Handle all of the activate signals from the gtk actions. 
+               The action signals derive from clicking on a    toolbar or menu 
bar button. 
+               Forward the action to the state handler.
+               """
+               self.handle_states(event.get_name())            
                
        def handle_states(self, state):
-               """ Handle all of the state changes that arise from the action 
handler or other Graphics and 
-                       inputs in the application. The state passed to the 
handle_states method is a string descriping 
-                       the change. A series of if/elif statements handle the 
state by greying out action buttons, causing 
-                       changes in the flow graph, saving/opening files...      
The handle_states method is passed to the
-                       contructors of many of the classes used in this 
application enabling them to report any state change.   """
+               """!
+               Handle the state changes in the GUI.            
+               Handle all of the state changes that arise from the action 
handler or other Graphics and 
+               inputs in the application. The state passed to the 
handle_states method is a string descriping 
+               the change. A series of if/elif statements handle the state by 
greying out action buttons, causing 
+               changes in the flow graph, saving/opening files...      The 
handle_states method is passed to the
+               contructors of many of the classes used in this application 
enabling them to report any state change.
+               @param state a string describing the state change
+               """
                print '>>>',state
                
##############################################################################################
                #       Initalize/Quit
@@ -139,10 +156,11 @@
                        for action in ACTIONS_LIST: action.set_sensitive(False) 
#set all actions disabled
                        # enable a select few actions 
                        Graphics.enable_usrp_diagnostics()      #try to enable 
usrp diagnostics
-                       for action in (APPLICATION_QUIT, FLOW_GRAPH_NEW, 
FLOW_GRAPH_OPEN, FLOW_GRAPH_SAVE_AS, 
-                                                                       
ABOUT_WINDOW_DISPLAY, COLORS_WINDOW_DISPLAY, HOTKEYS_WINDOW_DISPLAY, 
MATH_EXPR_WINDOW_DISPLAY,
-                                                                       
FLOW_GRAPH_WINDOW_RESIZE, PREFS_WINDOW_DISPLAY, FLOW_GRAPH_SCREEN_CAPTURE): 
-                               get_action_from_name(action).set_sensitive(True)
+                       for action in (
+                               APPLICATION_QUIT, FLOW_GRAPH_NEW, 
FLOW_GRAPH_OPEN, FLOW_GRAPH_SAVE_AS, 
+                               ABOUT_WINDOW_DISPLAY, COLORS_WINDOW_DISPLAY, 
HOTKEYS_WINDOW_DISPLAY, MATH_EXPR_WINDOW_DISPLAY,
+                               FLOW_GRAPH_WINDOW_RESIZE, PREFS_WINDOW_DISPLAY, 
FLOW_GRAPH_SCREEN_CAPTURE,
+                       ): get_action_from_name(action).set_sensitive(True)
                        if self.flow_graph_file_path == '':
                                initial_state = 
ParseXML.from_xml(ParseXML.from_file(INITIAL_FLOW_GRAPH_FILE))
                                self.flow_graph.from_nested_data(initial_state)
@@ -159,9 +177,9 @@
                                        Messages.send_fail_load(e)
                                        self.flow_graph_file_path = ''
                                        
self.handle_states(APPLICATION_INITIALIZE)                                      
-                       self.set_saved_state(True)      
+                       self.saved = True       
                elif state == APPLICATION_QUIT:                 
-                       if self.loose_changes(): 
+                       if self._loose_changes(): 
                                self.handle_states(FLOW_GRAPH_STOP)             
                                
Preferences.set_default_flow_graph(self.flow_graph_file_path)
                                Preferences.save(self.main_window)
@@ -185,40 +203,40 @@
                
##############################################################################################
          
                elif state == SIGNAL_BLOCK_MOVE:                        
                        
self.state_cache.save_new_state(self.flow_graph.to_nested_data())
-                       self.set_saved_state(False)
+                       self.saved = False
                elif state == SIGNAL_BLOCK_ROTATE_LEFT:
                        if self.flow_graph.rotate_selected(DIR_LEFT):           
                
                                
self.state_cache.save_new_state(self.flow_graph.to_nested_data())       
-                               self.set_saved_state(False)             
+                               self.saved = False              
                elif state == SIGNAL_BLOCK_ROTATE_RIGHT:
                        if self.flow_graph.rotate_selected(DIR_RIGHT):          
                
                                
self.state_cache.save_new_state(self.flow_graph.to_nested_data())       
-                               self.set_saved_state(False)             
+                               self.saved = False              
                elif state == ELEMENT_DELETE:
                        if self.flow_graph.delete_selected():                   
        
                                
self.state_cache.save_new_state(self.flow_graph.to_nested_data())               
                
                                self.handle_states(NOTHING_SELECT)
-                               self.set_saved_state(False)
+                               self.saved = False
                elif state == CONNECTION_CREATE or state == 
SIGNAL_BLOCK_CREATE:                        
                        
self.state_cache.save_new_state(self.flow_graph.to_nested_data())
                        self.handle_states(NOTHING_SELECT)      
-                       self.set_saved_state(False)
+                       self.saved = False
                elif state == SIGNAL_BLOCK_INC_TYPE:
                        if self.flow_graph.type_controller_modify_selected(1):
                                
self.state_cache.save_new_state(self.flow_graph.to_nested_data())       
-                               self.set_saved_state(False)
+                               self.saved = False
                elif state == SIGNAL_BLOCK_DEC_TYPE:
                        if self.flow_graph.type_controller_modify_selected(-1):
                                
self.state_cache.save_new_state(self.flow_graph.to_nested_data())       
-                               self.set_saved_state(False)     
+                               self.saved = False      
                elif state == SOCKET_CONTROLLER_INC:
                        if self.flow_graph.socket_controller_modify_selected(1):
                                
self.state_cache.save_new_state(self.flow_graph.to_nested_data())       
-                               self.set_saved_state(False)
+                               self.saved = False
                elif state == SOCKET_CONTROLLER_DEC:
                        if 
self.flow_graph.socket_controller_modify_selected(-1):
                                
self.state_cache.save_new_state(self.flow_graph.to_nested_data())       
-                               self.set_saved_state(False)             
+                               self.saved = False              
                
##############################################################################################
                #       Window stuff
                
##############################################################################################
@@ -236,22 +254,25 @@
                elif state == MATH_EXPR_WINDOW_DISPLAY:
                        Graphics.MathExprDialog()
                elif state == FLOW_GRAPH_WINDOW_RESIZE:
-                       dimensions = 
Graphics.FlowGraphWindowSizeDialog(self.flow_graph).run()
+                       dimensions = 
Graphics.FlowGraphWindowSizeDialog(self.flow_graph.get_size_request()).run()
                        if dimensions != None:
                                self.flow_graph.set_size_request(dimensions[0], 
dimensions[1])
                                
self.state_cache.save_new_state(self.flow_graph.to_nested_data())               
                        
-                               self.set_saved_state(False)
+                               self.saved = False
                
##############################################################################################
                #       Variable and Param Modifications
                
##############################################################################################
                elif state == SIGNAL_BLOCK_PARAM_MODIFY:
                        if self.flow_graph.param_modify_selected():
                                
self.state_cache.save_new_state(self.flow_graph.to_nested_data())       
-                               self.set_saved_state(False)             
+                               self.saved = False              
                elif state == VARIABLE_MODIFY:
                        
self.state_cache.save_new_state(self.flow_graph.to_nested_data())       
-                       self.set_saved_state(False)     
+                       self.saved = False      
                        self.flow_graph.update()
+               elif state == VARIABLE_REORDER:
+                       
self.state_cache.save_new_state(self.flow_graph.to_nested_data())       
+                       self.saved = False      
                
##############################################################################################
                #       Undo/Redo
                
##############################################################################################
@@ -260,24 +281,23 @@
                        if nested_data  != None:                
                                self.handle_states(NOTHING_SELECT)
                                self.flow_graph.from_nested_data(nested_data)
-                               self.set_saved_state(False)
+                               self.saved = False
                elif state == FLOW_GRAPH_REDO:                                  
        
                        nested_data = self.state_cache.get_next_state()
                        if nested_data  != None:                
                                self.handle_states(NOTHING_SELECT)
                                self.flow_graph.from_nested_data(nested_data)
-                               self.set_saved_state(False)
+                               self.saved = False
                
##############################################################################################
                #       New/Open/Save
                
##############################################################################################
                elif state == FLOW_GRAPH_NEW:
-                       if self.loose_changes(): 
+                       if self._loose_changes(): 
                                self.flow_graph_file_path = ''
                                self.handle_states(APPLICATION_INITIALIZE)
                elif state == FLOW_GRAPH_OPEN:
-                       if self.loose_changes():                                
-                               fc = Graphics.FlowGraphFileDialog('open', 
self.flow_graph_file_path)    
-                               file_path = fc.run()
+                       if self._loose_changes():               
+                               file_path = 
Graphics.OpenFlowGraphFileDialog(self.flow_graph_file_path).run()
                                if file_path != None:
                                        self.flow_graph_file_path = file_path
                                        
self.handle_states(APPLICATION_INITIALIZE)
@@ -286,19 +306,17 @@
                        else:
                                try:
                                        
ParseXML.to_file(ParseXML.to_xml(self.flow_graph.to_nested_data()), 
self.flow_graph_file_path)
-                                       self.set_saved_state(True)              
+                                       self.saved = True               
                                except IOError: 
                                        
Messages.send_fail_save(self.flow_graph_file_path)
-                                       self.set_saved_state(False)
+                                       self.saved = False
                elif state == FLOW_GRAPH_SAVE_AS:
-                       fc = Graphics.FlowGraphFileDialog('save', 
self.flow_graph_file_path)
-                       file_path = fc.run()
+                       file_path = 
Graphics.SaveFlowGraphFileDialog(self.flow_graph_file_path).run()
                        if file_path != None:                   
                                self.flow_graph_file_path = file_path
                                self.handle_states(FLOW_GRAPH_SAVE)     
                elif state == FLOW_GRAPH_SCREEN_CAPTURE:
-                       fc = Graphics.FlowGraphFileDialog('save image', 
self.flow_graph_file_path)
-                       file_path = fc.run()
+                       file_path = 
Graphics.SaveImageFileDialog(self.flow_graph_file_path).run()
                        if file_path != None: 
                                pixmap = self.flow_graph.pixmap
                                width, height = pixmap.get_size()
@@ -311,43 +329,48 @@
                elif state == FLOW_GRAPH_EXEC:
                        if self.pid_file == None:
                                self.handle_states(FLOW_GRAPH_SAVE)
-                               if self.flow_graph_file_path != '': RUN(self)   
                                                        
+                               if self.flow_graph_file_path != '': 
ExecFlowGraphThread(self)                                                       
    
                elif state == FLOW_GRAPH_STOP:
-                       while not MUTEX.testandset(): pass      #try to lock 
repeatedly until lock is aquired
+                       MUTEX.lock()
                        if self.pid_file!= None: 
                                try: os.kill(int(open(self.pid_file, 
'r').read()), 9)
                                except: print "could not kill pid file: 
%s"%self.pid_file
                        MUTEX.unlock()
                else: print "!!! State not handled !!!" 
-               # set the exec button if the flow graph is valid and is not 
already running     #
-               while not MUTEX.testandset(): pass      #try to lock repeatedly 
until lock is aquired
-               
get_action_from_name(FLOW_GRAPH_EXEC).set_sensitive(self.flow_graph.is_valid() 
and self.pid_file == None)       
+               #set the exec button if the flow graph is valid and is not 
already running
+               MUTEX.lock()
+               
get_action_from_name(FLOW_GRAPH_EXEC).set_sensitive(self.flow_graph.is_valid() 
and self.pid_file == None)
+               
get_action_from_name(FLOW_GRAPH_STOP).set_sensitive(self.pid_file != None)      
                MUTEX.unlock()
-               # hide/show the reports window based on the preferences #
-               
self.main_window.show_reports_window(Preferences.show_reports_window())
-                       
-       def set_saved_state(self, saved):
-               ''' If saved is True, disable the save button and modify the 
title.
-               If saved is False, enable the save button and modify the title 
with a *. '''
-               if saved:
+               #saved status           
+               if self.saved: #set the window title and grey out the save 
button
                        
get_action_from_name(FLOW_GRAPH_SAVE).set_sensitive(False)
                        if self.flow_graph_file_path == '':                     
        
                                self.main_window.set_title(NEW_FLOGRAPH_TITLE)
                        else: 
self.main_window.set_title(self.flow_graph_file_path)                           
          
-               else: 
+               else: #set the window title with a * and activate the save 
button
                        
get_action_from_name(FLOW_GRAPH_SAVE).set_sensitive(True)
                        if self.flow_graph_file_path == '':                     
        
                                self.main_window.set_title(NEW_FLOGRAPH_TITLE + 
'*')
-                       else: 
self.main_window.set_title(self.flow_graph_file_path + '*')                     
  
+                       else: 
self.main_window.set_title(self.flow_graph_file_path + '*')                     
          
+               #hide/show the reports window based on the preferences
+               Preferences.show_reports_window(self.main_window)               
                
-       def loose_changes(self):
-               ''' True if the save is disabled or the user says to discard 
changes.   '''
-               return not 
get_action_from_name(FLOW_GRAPH_SAVE).get_sensitive() or\
-                               (Graphics.LooseChangesMessage().run())
+       def _loose_changes(self):
+               """!
+               Loose unsaved changes to flow graph?            
+               If the save was not greyed-out, the user is presented with a 
dialog.
+               @return true if save is greyed-out, or the user's choice.
+               """
+               return not 
get_action_from_name(FLOW_GRAPH_SAVE).get_sensitive() or 
Graphics.LooseChangesMessage().run()
                                
-class RUN(Thread):
-       ''' Run the flow graph as a new process and wait on it to finish        
'''
+class ExecFlowGraphThread(Thread):
+       """Execute the flow graph as a new process and wait on it to finish."""
        def __init__ (self, action_handler):
+               """!
+               ExecFlowGraphThread constructor.
+               @param action_handler an instance of an ActionHandler
+               """
                Thread.__init__(self)
                self.action_handler = action_handler            
                self.pid_file = self.action_handler.pid_file = 
'/tmp/grc-%d.pid'%os.getpid()
@@ -355,22 +378,23 @@
                self.flow_graph_file_path = 
self.action_handler.flow_graph_file_path
                get_action_from_name(FLOW_GRAPH_EXEC).set_sensitive(False)
                get_action_from_name(FLOW_GRAPH_STOP).set_sensitive(True)
-               Messages.send_start_run(self.flow_graph_file_path)
+               Messages.send_start_exec(self.flow_graph_file_path)
                self.start()
                
        def run(self):  
+               """Execute the flow graph."""
                cmd = '%s "%s" --pid_file="%s" 2> 
"%s"'%(DEFAULT_FLOW_GRAPH_EXEC, self.flow_graph_file_path, self.pid_file, 
self.report_file)
                os.system(cmd)  
                try:                                            
                        report = open(self.report_file, 'r')    
                        #       read all the lines of the report file into a 
list       #
-                       Messages.send_end_run(report.readlines())
+                       Messages.send_end_exec(report.readlines())
                        report.close()  
                        os.remove(self.report_file)
                except IOError: print "could not read report file: 
%s"%self.report_file
                try: os.remove(self.pid_file)
                except: print "could not remove pid file: %s"%self.pid_file
-               while not MUTEX.testandset(): pass      #try to lock repeatedly 
until lock is aquired
+               MUTEX.lock()
                self.action_handler.pid_file = None     
                get_action_from_name(FLOW_GRAPH_STOP).set_sensitive(False)      
                get_action_from_name(FLOW_GRAPH_EXEC).set_sensitive(True)

Modified: grc/trunk/src/Actions.py
===================================================================
--- grc/trunk/src/Actions.py    2007-06-29 17:29:46 UTC (rev 5877)
+++ grc/trunk/src/Actions.py    2007-06-29 17:41:26 UTC (rev 5878)
@@ -16,11 +16,9 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""    
-       Actions.py      
-       Josh Blum
-       Global actions for gui elements to communicate state changes to the 
action handler.
-"""
address@hidden Actions
+#Global actions for gui elements to communicate state changes to the action 
handler.           
address@hidden Josh Blum
 
 import pygtk
 pygtk.require('2.0')
@@ -56,6 +54,7 @@
 ELEMENT_DELETE = 'element delete'
 
 VARIABLE_MODIFY = 'variable modify'
+VARIABLE_REORDER = 'variable reorder'
 
 FLOW_GRAPH_OPEN = 'flow graph open'
 FLOW_GRAPH_UNDO = 'flow graph undo'
@@ -79,7 +78,7 @@
 #      actions
 
######################################################################################################
 
-ACTIONS_LIST = [
+ACTIONS_LIST = (
        gtk.Action(FLOW_GRAPH_NEW, '_New', 'Create a new flow graph', 
'gtk-new'),
        gtk.Action(FLOW_GRAPH_OPEN, '_Open', 'Open a flow graph from file', 
'gtk-open'),
        gtk.Action(FLOW_GRAPH_SAVE, '_Save', 'Save this flow graph', 
'gtk-save'),
@@ -101,12 +100,18 @@
        gtk.Action(FLOW_GRAPH_EXEC, '_Execute', 'Execute the flow graph', 
'gtk-execute'),
        gtk.Action(FLOW_GRAPH_STOP, '_Stop', 'Stop the flow graph', 'gtk-stop'),
        gtk.Action(FLOW_GRAPH_SCREEN_CAPTURE, 'S_creen Capture', 'Create a 
screen capture of the flow graph', 'gtk-print'),
-]
+)
                                        
 def get_action_from_name(action_name): 
-       """ Retrieve the action from the above list given its name.     """     
+       """!
+       Retrieve the action from the action list.
+       Search the list and find an action with said name.
+       @param action_name the action name(string)
+       @throw KeyError bad action name
+       @return a gtk action object
+       """     
        for action in ACTIONS_LIST: 
                if action.get_name() == action_name: return action
-       return None
+       raise KeyError('Action Name: "%s" does not exist'%action_name)
        
        
\ No newline at end of file

Modified: grc/trunk/src/Colors.py
===================================================================
--- grc/trunk/src/Colors.py     2007-06-29 17:29:46 UTC (rev 5877)
+++ grc/trunk/src/Colors.py     2007-06-29 17:41:26 UTC (rev 5878)
@@ -16,11 +16,9 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""    
-       Colors.py       
-       Josh Blum
-       Colors and color-specs used to identify a socket's data type.
-"""
address@hidden Colors
+#Colors and color-specs used to identify a socket's data type. 
address@hidden Josh Blum
 
 import pygtk
 pygtk.require('2.0')
@@ -60,4 +58,3 @@
 SHORT_VECTOR_COLOR = COLORMAP.alloc_color(SHORT_VECTOR_COLOR_SPEC, True, True) 
#background for shorts (yellowish)
 INT_VECTOR_COLOR = COLORMAP.alloc_color(INT_VECTOR_COLOR_SPEC, True, True)     
#background for ints (greenish)
 BYTE_VECTOR_COLOR = COLORMAP.alloc_color(BYTE_VECTOR_COLOR_SPEC, True, True)   
#background for bytes (purplish)
-

Modified: grc/trunk/src/Constants.py
===================================================================
--- grc/trunk/src/Constants.py  2007-06-29 17:29:46 UTC (rev 5877)
+++ grc/trunk/src/Constants.py  2007-06-29 17:41:26 UTC (rev 5878)
@@ -16,76 +16,78 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""    
-       Constants.py    
-       Josh Blum
-       Global constants
-"""
address@hidden Constants
+#Global constants
address@hidden Josh Blum
 
 import sys, os
 import mutex
-MUTEX = mutex.mutex()  #mutex used when running a flow graph
 
+##mutex used when running a flow graph.
+MUTEX = mutex.mutex()  
+def lock(mutex):
+       while not mutex.testandset(): pass      #try to lock repeatedly until 
lock is aquired
+MUTEX.lock = lambda: lock(MUTEX)
+
 
######################################################################################################
-#      Global Titles
+## Global Titles @{
 
######################################################################################################
 
-""" The current version of this code   """
+##The current version of this code
 VERSION = '0.70 alpha'
 
-"""    The name to appear in the main window for a flow graph that has not 
been saved to file. """
+##The name to appear in the main window for a flow graph that has not been 
saved to file.
 NEW_FLOGRAPH_TITLE = 'untitled'
 
-"""    The prefix title on the main window.    """     
+##The prefix title on the main window.
 MAIN_WINDOW_PREFIX = "GRC"
address@hidden
 
 
######################################################################################################
-#      Length of connector buds on Sockets(s) in pixels and 
-#              allowable rotation angles for Element(s) in degrees
+##     Length of connector buds on Sockets(s) in pixels and 
+# allowable rotation angles for Element(s) in degrees @{
 
######################################################################################################
 
-"""    The length that a connection must extend from the socket 
-       until the length depends on the index of the socket.    """
+##The length that a connection must extend from the socket until the length 
depends on the index of the socket.
 CONNECTOR_EXTENSION_INITIAL_LENGTH = 11
 
-"""    The length that a connection must extend from the initial 
-       length times the index of the socket, after this length, 
-       the connection may have a bend. """
+##The length that a connection must extend from the initial length times the 
index of the socket, after this length, the connection may have a bend.
 CONNECTOR_EXTENSION_LENGTH = 11
 
-"""     list of possible angles (in degrees) that a signal block and its 
parameters
-       can be rotated to.      """
+##List of possible angles (in degrees) that a signal block and its parameters 
can be rotated to.
 POSSIBLE_ROTATIONS = (0, 90, 180, 270)
 
-""" directions of rotation """
+##direction of rotation left.
 DIR_LEFT = 'left'
+
+##direction of rotation right.
 DIR_RIGHT = 'right'
address@hidden
 
 
######################################################################################################
-#      Dimension constraints for the various windows (in pixels)
+## Dimension constraints for the various windows (in pixels)
 
######################################################################################################
 
-#      main window constraints #
-
+##main window constraints      @{
 DEFAULT_MAIN_WINDOW_WIDTH = 750
 
 DEFAULT_MAIN_WINDOW_HEIGHT = 550
address@hidden
 
-#      flow graph window constraints   #
-
+##flow graph window constraints        @{
 MIN_WINDOW_WIDTH = 600
 MAX_WINDOW_WIDTH = 2400
 
 MIN_WINDOW_HEIGHT = 400
 MAX_WINDOW_HEIGHT = 1800
address@hidden
 
-#      dialog constraints      #
-
+##dialog constraints   @{
 MIN_DIALOG_WIDTH = 400
 MIN_DIALOG_HEIGHT = 500
address@hidden
 
-#      misc window constraints #
-
+##misc window constraints      @{
 REPORTS_WINDOW_HEIGHT = 80
 
 SIGNAL_BLOCK_SELECTION_WINDOW_WIDTH = 250
@@ -93,27 +95,31 @@
 
 VARIABLE_MODIFICATION_WINDOW_WIDTH = 250
 VARIABLE_MODIFICATION_WINDOW_HEIGHT = 150
address@hidden
 
 
######################################################################################################
-#      Constraints for the sliders in the runnable flow graph
+## Constraints for the sliders in the runnable flow graph @{
 
######################################################################################################
 
-''' The number of tics for a slider.   '''
+##The number of tics for a slider.
 DEFAULT_SLIDER_STEPS = 100
 
-''' The max width that a row of sliders can use '''
+##The max width that a row of sliders can use.
 MAX_SLIDERS_WIDTH = 600
 
-'''    The width in pixels.    '''
+##Slider width in pixels
 DEFAULT_SLIDER_WIDTH = 200
+##Slider width in pixels
 MAX_SLIDER_WIDTH = 300
+##Slider width in pixels
 MIN_SLIDER_WIDTH = 100
 
-'''    The height in pixels.   '''
+##The height in pixels.
 SLIDER_HEIGHT = 20
address@hidden
 
 
######################################################################################################
-#      Constraints on displayable labels and sockets
+## Constraints on displayable labels and sockets @{
 
######################################################################################################
 
 LABEL_SEPARATION = 4
@@ -128,70 +134,71 @@
 PARAM_FONT = 'Sans 8'
 SIGNAL_BLOCK_FONT = 'Sans 9 Bold'
 SOCKET_FONT = 'Sans 8'
address@hidden
 
 
######################################################################################################
-#      Dragging, scrolling, and redrawing constants for the flow graph window 
in pixels
+## Dragging, scrolling, and redrawing constants for the flow graph window in 
pixels @{
 
######################################################################################################
 
-"""    How close can the mouse get to the window border before mouse events 
are ignored.       """
+##How close can the mouse get to the window border before mouse events are 
ignored.
 BORDER_PROXIMITY_SENSITIVITY = 10
 
-"""    How close can the mouse get to the edge of the visible window before 
scrolling is invoked.      """
+##How close can the mouse get to the edge of the visible window before 
scrolling is invoked.
 SCROLL_PROXIMITY_SENSITIVITY = 30
 
-"""    When the window has to be scrolled, move it this distance in the 
required direction.    """
+##When the window has to be scrolled, move it this distance in the required 
direction.
 SCROLL_DISTANCE = 15
 
-"""    Do not draw more than this many sockets on one side of a signal block.  
"""
-MAX_NUM_SOCKETS = 20
-
-"""    The redrawing sensitivity, how many motion detection events must occur 
before a redraw? """
+##The redrawing sensitivity, how many motion detection events must occur 
before a redraw?
 MOTION_DETECT_REDRAWING_SENSITIVITY = 3
address@hidden
 
 
######################################################################################################
 #      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)      """
+##The size of the state saving cache in the flow graph (for undo/redo 
functionality)
 STATE_CACHE_SIZE = 42
 
 
######################################################################################################
-#      Constansts dealing with File Paths
+## Constansts dealing with File Paths @{
 
######################################################################################################
 
-"""    Location of the python src directory.   """
+##Location of the python src directory.
 SRC_DIR = os.path.abspath(os.path.dirname(__file__))
 
-"""    Location of external data files """
+##Location of external data files.
 DATA_DIR = os.path.abspath(SRC_DIR+'/../data/')
 
-"""    The setting for a blank flow graph      """
+##The setting for a blank flow graph.
 INITIAL_FLOW_GRAPH_FILE = 
os.path.abspath(DATA_DIR+'/initial_flow_graph.grc.xml')
 
-"""    The default file extension for file open and save dialogs.      """
-DEFAULT_FILE_EXTENSION = '.grc.xml'
+##The default file extension for flow graphs.
+FLOW_GRAPH_FILE_EXTENSION = '.grc.xml'
 
-""" The default file extension for saving flow graph snap shots.       """
+##The default file extension for saving flow graph snap shots.
 IMAGE_FILE_EXTENSION = '.png'
 
-"""    The default path for the open/save dialogs.     """
+##The default path for the open/save dialogs.
 DEFAULT_FILE_PATH = os.path.expanduser('~')+'/'
 
-"""    The default icon for all windows.       """
+##The default icon for the gtk windows.
 PY_GTK_ICON = os.path.abspath(DATA_DIR+'/grc-icon-256.png')
+
+##The default icon for the wx windows.
 WX_APP_ICON = os.path.abspath(DATA_DIR+'/grc-icon-32.png')
 #>>> platform dependency! wx under cygwin has issues with icon paths   #
 if sys.platform == 'cygwin': WX_APP_ICON = None
 
-""" The default binary to execute python files.        """
+##The default binary to execute python files.
 PYEXEC = 'python'
 #>>> platform dependency! MacOS requires pythonw to run wx apps        #
 if sys.platform == 'darwin': PYEXEC = 'pythonw'
 
-""" The default command to run a flow graph file       """
+##The default command to run a flow graph file.
 DEFAULT_FLOW_GRAPH_EXEC = '%s %s/ExecFlowGraphGUI.py'%(PYEXEC, SRC_DIR)
 
-"""    The default user preferences file.      """
+##The default user preferences file.
 PREFERENCES_FILE_PATH = os.path.abspath(DEFAULT_FILE_PATH + '/.grc.xml')
address@hidden
 
-

Deleted: grc/trunk/src/DataType.py

Copied: grc/trunk/src/DataTypes.py (from rev 5877, 
grc/branches/jblum_work/src/DataTypes.py)
===================================================================
--- grc/trunk/src/DataTypes.py                          (rev 0)
+++ grc/trunk/src/DataTypes.py  2007-06-29 17:41:26 UTC (rev 5878)
@@ -0,0 +1,546 @@
+"""
+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 DataTypes
+#All the data types for sockets and params. Contains parsing and validity 
checks.
address@hidden Josh Blum
+
+import MathExprParser
+import Variables
+from gnuradio import gr
+
+class DataType:
+       """
+       The base class for all data types.
+       Hold data and provide parsing.  
+       Do not use, this is a base class only. 
+       """
+       base_type = None
+       
+       def __init__(self, data='0', min=None, max=None):
+               """!
+               DataType constructor.           
+               @param data the data
+               @param min the minimum
+               @param max the maximum  
+               """
+               self.set_data(data)     
+               self.max = max  
+               self.min = min  
+               ##parser messages
+               self.msg = ''   
+
+       def __str__(self):
+               """!
+               Get the string representation of this data type.
+               This will be the parsed value, or an error message if invalid.
+               @return the string representation.
+               """
+               return self.msg
+
+       def set_data(self, data):
+               """!
+               Store the data as a string.
+               @param data the data            
+               """
+               self.data = str(data)           
+
+       def get_data(self):
+               """!
+               Get the data as a string.
+               @return the data """
+               return self.data                
+
+       def parse(self):
+               """!
+               Substitute in variables.                        
+               Replace all variable instances with the variable's string 
representation.
+               @return the data without variables"""
+               return Variables.replace_var_instances(self.get_data()) 
+       
+       def is_valid(self):
+               """!
+               Is this data type valid?                                
+               True if the data can be parsed, otherwise False. 
+               If min or max was specified, 
+               the parsed value must be less than or equal to min and/or 
+               greater than or equal to max. If the parsed value is a vector, 
+               then the value is the length of the vector.     
+               @return boolean, true if valid
+               """             
+               try: 
+                       value = self.parse() 
+                       self.msg = str(value)
+                       return True
+               except Exception, e: 
+                       self.msg = str(e)
+                       return False    
+       
+       def get_type(self):
+               """!
+               Get a string describing the specific data type. 
+               @return type string             
+               """
+               return self.type
+       
+       def get_base_type(self):
+               """!
+               Get a string describing the base (category) of this data type.  
+               @return base type string                
+               """
+               return self.base_type
+       
+       def get_num_bytes(self):
+               """!
+               How man bytes in this data type?        
+               @return number of bytes
+               """
+               return self.num_bytes
+
+       def _verify_bounds(self, value):
+               """!
+               Is the value within the bounds of this data type?               
+               @throw ValueError out of bounds.
+               """
+               if self.max != None and value > self.max: raise 
ValueError('Value "%s" was greater than the max "%s".'%(value, self.max))
+               if self.min != None and value < self.min: raise 
ValueError('Value "%s" was greater than the min "%s".'%(value, self.min))
+
+#############################################################################################
  
+#      Regular Types
+#############################################################################################
          
+class Number(DataType):
+       """
+       A number data type.
+       The base class for numeric data types.  
+       Do not use, this is a base class only.          
+       """
+       base_type = 'number'
+
+       def parse(self):
+               """!
+               Evaluate the math expressions in the data type.
+               @return a number
+               """
+               num = MathExprParser.eval_expr(DataType.parse(self))
+               parsed = self.parser(num)       
+               self._verify_bounds(parsed)
+               return parsed
+
+class Int(Number):
+       """The integer data type."""
+       type = 'int'
+       num_bytes = gr.sizeof_int       
+       
+       def parser(self, value):
+               """!
+               Parse the data for an integer value or raise an error.  
+               @throw Exception non integer
+               @return integer         
+               """
+               return MathExprParser.verify_int(value)
+
+class Byte(Int):
+       """The byte data type is identical to int.      """
+       type = 'byte'
+       num_bytes = gr.sizeof_char
+
+class Short(Int):
+       """The short data type is identical to int."""
+       type = 'short'
+       num_bytes = gr.sizeof_short
+
+class Float(Number):
+       """The float data type."""
+       type = 'float'
+       num_bytes = gr.sizeof_float
+       
+       def parser(self, value):
+               """!
+               Parse the data for an float value or raise an error.    
+               @throw Exception non float
+               @return float           
+               """
+               return MathExprParser.verify_float(value)
+
+class Complex(Number):
+       """The complex data type."""
+       type = 'complex'        
+       num_bytes = gr.sizeof_gr_complex
+       
+       def parser(self, value):
+               """!
+               Parse the data for an complex value or raise an error.  
+               @throw Exception non complex
+               @return complex         
+               """
+               return MathExprParser.verify_complex(value)
+       
+#############################################################################################
  
+#      Special Types
+#############################################################################################
+class RawExpr(DataType):
+       """A raw mathematical expression."""
+       type = 'raw'
+
+       def __init__(self, data=''):
+               """!
+               Raw data type contructor.
+               @param data the data            
+               """
+               DataType.__init__(self, data)
+
+       def parse(self):
+               """!
+               Get the raw data returned by the math parser.
+               @throw Exception malformed expression
+               @return the evaluated mathematical expression   
+               """
+               data = DataType.parse(self)
+               return MathExprParser.eval_expr(data)
+
+class String(DataType):
+       """The string data type."""
+       type = 'string'
+       
+       def __init__(self, data='', min=None, max=None):
+               """!
+               String data type contructor.
+               @param data the data
+               @param min the minimum length of the string
+               @param max the maximum length of the string
+               """
+               DataType.__init__(self, data, min, max)
+       
+       def parse(self):
+               """!
+               Get the data as a string.
+               @throw Exception string length out of bounds
+               @return the data
+               """
+               string = DataType.parse(self)
+               self._verify_bounds(len(string))
+               return string
+                       
+class Hex(DataType):
+       """The hex data type."""
+       type = 'hex'
+       
+       def parse(self):
+               """!
+               Get the data as an integer parsed from a hex string.    
+               @return the data                
+               """
+               return int(DataType.parse(self),16)
+       
+class File(String):
+       """A file data type. Do not use, this is a base class only."""
+       base_type = 'file'
+       
+       def __init__(self, data='', allow_blank=False):
+               """!
+               File data type contructor. 
+               Allow blank lets blank filename pass validation.
+               @param data the file path
+               @param allow_blank allow empty paths(true/false)
+               """
+               String.__init__(self, data)
+               self.allow_blank = allow_blank
+
+class FileOpen(File):
+       """A file data type for choosing existing files."""
+       type = 'fileopen'
+       
+       def is_valid(self):
+               """!
+               Does the file path exist?
+               @return true if valid
+               """
+               if self.allow_blank and self.parse() == '': return True
+               from os import path                     
+               return path.isfile(self.parse())
+       
+class FileSave(File):
+       """A file data type for choosing files to save."""
+       type = 'filesave'               
+       
+       def is_valid(self):     
+               """!
+               Is the file path possible?
+               The directory must exist and the filename must not be an 
existing directory.
+               @return true if validcannonical name
+               """
+               if self.allow_blank and self.parse() == '': return True
+               from os import path
+               my_path = self.parse()
+               # Return False if the directory does not exist or the path is 
just a directory. #
+               if not path.exists(path.dirname(my_path)) or 
path.isdir(my_path): return False
+               # True if the basename is not an empty string.  #
+               return path.basename(my_path) != '' 
+               
+class Variable(DataType):
+       """
+       The variable data type. 
+       Takes properties from an enumerated data type of data types.    
+       """
+       
+       def __init__(self, enum_data_type, data='0', index=None, min=None, 
max=None):
+               """!
+               Variable constructor.
+               The enumerated type must contain other data types in its 
choices.
+               The index is the index of the data type in the enum's tuple.
+               If index is None, enum must parse to a data type.
+               @param enum_data_type an enumerated data type
+               @param data the data
+               @param index the index of the data type in the enum's choice
+               @param min the minimum
+               @param max the maximum
+               """
+               DataType.__init__(self, data, min, max)
+               self.enum_data_type = enum_data_type
+               self.index = index
+       
+       def _parse_enum_data_type(self):
+               """!
+               Parse the selected data type. 
+               If there is an index, get the data type from a tuple instead.
+               @return the data type
+               """
+               if self.index is None: return self.enum_data_type.parse()
+               else: return self.enum_data_type.parse()[self.index]
+       
+       def get_type(self):
+               """!
+               Get the type from the enumerated data type.
+               @return the type
+               """
+               return self._parse_enum_data_type().get_type()
+       
+       def get_base_type(self):
+               """!
+               Get the base type from the enumerated data type.
+               @return the base type
+               """
+               return self._parse_enum_data_type().get_base_type()
+       
+       def get_num_bytes(self):
+               """!
+               Get the number of bytes from the enumerated data type.
+               @return the number of bytes.
+               """
+               return self._parse_enum_data_type().get_num_bytes()
+               
+       def parse(self):
+               """!
+               Use the parser from the enumerated data type.
+               @return the parsed data
+               """
+               data_type = self._parse_enum_data_type()
+               data_type.set_data(self.get_data())
+               return data_type.parse()
+               
+class Enum(DataType):
+       """The enumerated data type.
+       The enumerated type holds a finite set of choices. 
+       The selected choice is determined by the data. 
+       The data must represent an integer index.       """
+       type = 'enum'
+       base_type = 'enum'
+       
+       def __init__(self, choices=[('',0)], data='0'):
+               """!
+               Enum constructor.               
+               choices = [(cname0, choice0),(cname1, choice1),...]
+               @param choices the list of choices
+               @param data the choice index 0-> len(choices)-1
+               """
+               self.choices = choices  
+               DataType.__init__(self, data)   
+                               
+       def set_data(self, data):
+               """!
+               Set the data.
+               Try to use data as an index for choices. 
+               @param data the data
+               @throw Exception bad index
+               """
+               self.choices[int(data)] 
+               DataType.set_data(self, data)
+               
+       def parse(self):
+               """!
+               Parse the data by returning the current selection pointed to by 
the data.
+               @return the choice at the index held in data
+               """
+               return self.choices[int(self.get_data())][1]
+               
+       def get_cname(self):
+               """!
+               Get the cannonical name of the currently selected choice.
+               @return the cannonical name
+               """
+               return self.choices[int(self.get_data())][0]
+               
+       def get_cnames_list(self):
+               """!
+               Get a list of the cannonical names from the choices (in order).
+               @return a list of all the cannonical names
+               """
+               cnames = list()
+               for cname,choice in self.choices: cnames.append(cname)
+               return cnames
+               
+class VariableKeySelector(DataType):
+       """
+       The variable key selector data type.
+       This data type allows the user to select a variable key in the variable 
registry.
+       """
+       type = 'variable enum'
+       base_type = 'variable enum'
+       
+       def __init__(self, data='', all_variables=False):
+               """! 
+               Variable key selector contructor.       
+               If the all variables flag is true, this data type can represent 
any variable key.
+               If the all variables flag is false, variables with ranges will 
not be allowed.
+               @param data the variable key
+               @param all_variables boolean to allow certain variables
+               """
+               DataType.__init__(self, data)   
+               self.all_variables = all_variables      
+                       
+       def parse(self):
+               """!
+               Parse the data by returning the current key.
+               @return the var key
+               """
+               return self.get_data().strip()
+               
+       def is_valid(self):     
+               """!
+               Is the variable key valid?
+               The data must be in the keys list.
+               @return true if valid"""
+               return self.parse() in self.get_variables_list()
+               
+       def get_variables_list(self):
+               """!
+               Get a list of the keys.
+               Use all_variables to restrict the list.
+               @return a list of possible keys
+               """
+               var_keys = list()
+               for key in Variables.get_keys():
+                       # use the key if we specified all variables or the key 
was not for a ranged variable
+                       if self.all_variables or not Variables.is_ranged(key): 
var_keys.append(key)
+               return var_keys 
+               
+class Bool(Enum):
+       """
+       The boolean data type.
+       This boolean type is an Enum with two choices.
+       One choice will parse to True, the other False. """
+       type = 'bool'
+       
+       def __init__(self, true='True', false='False', default=True):
+               """!
+               Bool contructor.
+               @param true the cname for the true choice
+               @param false the cname for the false choice
+               @param default the default choice
+               """
+               if default: data = 0    #determine the default index
+               else: data = 1
+               Enum.__init__(self, choices=[(true, True), (false, False)], 
data=data)
+               
+#############################################################################################
  
+#      Vectors Types
+#############################################################################################
  
+class Vector(DataType):
+       """
+       A vector data type.
+       The base class for vectors.
+       Do not use, this is a base class only.          
+       """
+       base_type = 'vector'
+       
+       def parse(self):
+               """!
+               Parse the vector data type.
+               The length of the vector must be within bounds.
+               The data must pass the math expression parser.
+               @throw Exception not in bounds
+               @throw Exception invalid syntax
+               @return the vector
+               """
+               elements = MathExprParser.eval_expr(DataType.parse(self))
+               if type(elements) != type(list()): elements = [elements]        
#ensure that elements is a list         
+               self._verify_bounds(len(elements))
+               return map(lambda v: self.parser(v), elements)
+
+class ByteVector(Vector, Byte):
+       """A vector of bytes."""
+       type = 'byte vector'
+
+class IntVector(Vector, Int):
+       """A vector of ints."""
+       type = 'int vector'
+       
+class ShortVector(Vector, Short):
+       """A vector of shorts."""
+       type = 'short vector'
+       
+class FloatVector(Vector, Float):
+       """A vector of floats."""
+       type = 'float vector'
+       
+class ComplexVector(Vector, Complex):
+       """A vector of complex."""
+       type = 'complex vector'
+                       
+def can_connect(dt1, dt2):
+       """!
+       Can these data types connect?
+       @param dt1 a data type
+       @param dt2 another data type    
+       @return true if the types match
+       """
+       return dt1.get_type() == dt2.get_type()
+       
+def vectorize(data_type):
+       """!
+       Take a regular data type and return its vector form.
+       @param data_type a regular data type    
+       @return a vector data type
+       """
+       type = data_type.get_type()
+       regular_to_vector_dict = {
+               Byte().get_type() : ByteVector(),
+               Short().get_type() : ShortVector(),
+               Int().get_type() : IntVector(),
+               Float().get_type() : FloatVector(),
+               Complex().get_type() : ComplexVector(),
+       }
+       if type in regular_to_vector_dict.keys():
+               return regular_to_vector_dict[type]
+       return data_type        #otherwise return the input data type
+       
+if __name__ == '__main__':     
+       """Use the main method to test data types."""
+       pass
+       
+       
\ No newline at end of file

Modified: grc/trunk/src/Editor.py
===================================================================
--- grc/trunk/src/Editor.py     2007-06-29 17:29:46 UTC (rev 5877)
+++ grc/trunk/src/Editor.py     2007-06-29 17:41:26 UTC (rev 5878)
@@ -17,21 +17,19 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       Editor.py 
-       Josh Blum
-       Execute the flow graph editor GUI. This file must be called by the 
python interpreter.
-"""
address@hidden Editor 
+#Execute the flow graph editor GUI. This file must be called by the python 
interpreter.
address@hidden Josh Blum
 
-from Constants import VERSION,DEFAULT_FILE_EXTENSION
+from Constants import VERSION,FLOW_GRAPH_FILE_EXTENSION
 from optparse import OptionParser
 
 if __name__ == "__main__": 
-       usage = "usage: %prog optional_flow_graph"+DEFAULT_FILE_EXTENSION
+       usage = "usage: %prog optional_flow_graph"+FLOW_GRAPH_FILE_EXTENSION
        version = """
 GNU Radio Companion %s
 
-This file is part of GNU Radio
+This program is part of GNU Radio
 GRC comes with ABSOLUTELY NO WARRANTY. 
 This is free software, 
 and you are welcome to redistribute it.
@@ -39,16 +37,11 @@
        parser = OptionParser(usage=usage, version=version)     
        (options, args) = parser.parse_args()   
        # "test" import modules that this program will use #
-       try:    
-               import pygtk
-               pygtk.require('2.0')
-               import gtk
-               import xml.dom.minidom
-               import xml.dom.ext
-               import gnuradio
-       except ImportError, e: #print error and exit
-               print '\nMissing critical component: "%s"\nExiting!'%(e,)
-               exit(-1)
+       for module in ('pygtk', 'gtk', 'wx', 'numpy', 'xml.dom.minidom', 
'xml.dom.ext', 'gnuradio', 'gnuradio.gr.hier_block2'):
+               try: __import__(module)         
+               except ImportError: #print error and exit
+                       print '\nMissing critical module: 
"%s"\nExiting!\n'%module
+                       exit(-1)
        # end import of modules #
        from ActionHandler import ActionHandler
        if len(args): ActionHandler(args[0])


Property changes on: grc/trunk/src/Elements
___________________________________________________________________
Name: svn:ignore
   - *.pyc


Modified: grc/trunk/src/Elements/Connection.py
===================================================================
--- grc/trunk/src/Elements/Connection.py        2007-06-29 17:29:46 UTC (rev 
5877)
+++ grc/trunk/src/Elements/Connection.py        2007-06-29 17:41:26 UTC (rev 
5878)
@@ -16,33 +16,33 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       Elements/Connection.py 
-       Josh Blum
-       The elemental connection of input and output sockets.
-"""
address@hidden Elements.Connection
+#The elemental connection of input and output sockets.
address@hidden Josh Blum
 
-from Element import Element            
+import Element         
 import Utils
 
-class InvalidConnectionException(Exception):   
-       def __str__(self): return 'A connection requires a valid input and 
output socket!'
+class ConnectionException(Exception): pass
 
-class TooManyConnectionsException(Exception):  
-       def __str__(self): return 'An input socket may only have one 
connection!'
-
-class Connection(Element):
-       """     Connection provides elemental interfaces for a connection of 
sockets.   """     
+class Connection(Element.Element):
+       """Connection provides elemental interfaces for a connection of 
sockets."""     
        type = 'connection'
        def __init__(self, parent, socket1, socket2):
-               """ Initialize the Element and set the parent, coor, and 
rotation.      
-               Try to connect a pair of sockets. The sockets must be an input 
and an output. 
-               Also the input must have no existing connections. 
-               If an input socket that is already connected is passed to the 
constructor,
-               the logic will use the output socket that it is connected to.
-               This way, a user could try to connect an unconnected input 
socket to a signal on another input.
-               Then, the program will translate this to the cooresponding 
output socket on that signal.        """
-               Element.__init__(self, parent, (0,0), 0)
+               """!
+               Connection constructor.         
+               Initialize the Element with the given parent and a rotation and 
coordinate of zeros.    
+               Connect a pair of sockets. The sockets must be an input and an 
output. The input must have no existing connections. 
+               @param parent the flow graph
+               @param socket1 an input/output socket
+               @param socket2 another input/output socket
+               @throw InvalidConnectionException cant connect          
+               """
+               Element.Element.__init__(self, parent, (0,0), 0)
+               #If an input socket that is already connected is passed to the 
constructor,
+               #the logic will use the output socket that it is connected to.
+               #This way, a user could try to connect an unconnected input 
socket to a signal on another input.
+               #Then, the program will translate this to the cooresponding 
output socket on that signal.
                #>>>I dont like this functionality, uncomment it to pick the 
output socket              
                #if is_input_socket(socket1) and socket1.is_connected(): 
#socket1 is input and connected
                #       socket1 = 
socket1.get_connections()[0].get_output_socket()      #so we use its output 
socket
@@ -56,26 +56,38 @@
                        socket2.connect(self) #order is important, try input 
socket first (since input can throw an exception)
                        socket1.connect(self)
                        self.sockets = [socket2, socket1]
-               else: raise InvalidConnectionException()                
+               else: raise ConnectionException, 'A connection requires a valid 
input and output socket!'
                
        def get_coordinate(self):
-               '''     always get the 0,0 coordinate   '''
+               """!Get the 0,0 coordinate.
+               Coordinates are irrelevant in connection.
+               @return 0,0
+               """
                return (0,0)
                
        def get_rotation(self):
-               ''' always get the 0 degree rotation    '''
+               """!Get the 0 degree rotation.
+               Rotations are irrelevant in connection.
+               @return 0
+               """
                return 0
                
        def get_input_socket(self):
-               """get the input socket"""
+               """!
+               Get the input socket.
+               @return input socket
+               """
                return self.sockets[0]
                
        def get_output_socket(self):
-               """get the output socket"""
+               """!
+               Get the output socket.
+               @return output socket
+               """
                return self.sockets[1]  
                
        def disconnect(self):
-               """ delete this connection by calling the socket's disconnect 
methods.  """
+               """Disconnect the sockets by calling each socket's disconnect 
methods and removing the sockets from the parent."""
                print "disconnecting"
                for socket in self.sockets: socket.disconnect(self)
                self.get_parent().remove_element(self)

Modified: grc/trunk/src/Elements/Element.py
===================================================================
--- grc/trunk/src/Elements/Element.py   2007-06-29 17:29:46 UTC (rev 5877)
+++ grc/trunk/src/Elements/Element.py   2007-06-29 17:41:26 UTC (rev 5878)
@@ -16,36 +16,41 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       Elements/Element.py 
-       Josh Blum
-       The base class for graphical elements such as:
-       signal blocks, input sockets, output sockets and connections
-"""
address@hidden Elements.Element
+#The base class for graphical elements such as:
+#signal blocks, input sockets, output sockets and connections.
address@hidden Josh Blum
 
 from Constants import POSSIBLE_ROTATIONS,DIR_LEFT,DIR_RIGHT
 
 class Element:
-       """     Element is the base class for all elements. It contains an X,Y 
coordinate, a list
-       of rectangular areas that the element occupies and methods to detect 
selection. """     
-       
-       def rotate(self, direction):
-               """ rotate all of the areas by 90 degrees, direction is 
"left"/"right"  """
-               if direction == DIR_LEFT: delta_rotation = 90
-               elif direction == DIR_RIGHT: delta_rotation = 270               
        
-               self.set_rotation((self.get_rotation() + delta_rotation)%360)
-               self.update()
-               
+       """Element is the base class for all elements. It contains an X,Y 
coordinate, a list
+       of rectangular areas (and lines) that the element occupies and methods 
to detect selection."""                  
        def __init__(self, parent, coor, rotation):
-               """     make a new list of rectangular areas and lines, and set 
the coordinate and the rotation """     
+               """!
+               Make a new list of rectangular areas and lines, and set the 
coordinate and the rotation.
+               @param parent the parent of this element
+               @param coor the coordinate tuple (x,y)
+               @param rotation an angle in degrees 0, 90, 180, 270
+               """     
                self.parent = parent            
                self.set_rotation(rotation)
                self.set_coordinate(coor)               
                self.clear()
-               self.highlighted = False                        
+               self.highlighted = False
+               
+       def rotate(self, direction):
+               """!
+               Rotate all of the areas by 90 degrees.
+               @param direction DIR_RIGHT or DIR_LEFT
+               """
+               if direction == DIR_LEFT: delta_rotation = 90
+               elif direction == DIR_RIGHT: delta_rotation = 270               
        
+               self.set_rotation((self.get_rotation() + delta_rotation)%360)
+               self.update()                   
        
        def clear(self):
-               '''     make the lines and areas empty. '''
+               """Empty the lines and areas."""
                self.areas_dict = dict()
                self.lines_dict = dict()
                for rotation in POSSIBLE_ROTATIONS:
@@ -53,48 +58,78 @@
                        self.lines_dict[rotation] = list()      
                        
        def set_coordinate(self, coor):
-               '''     set the reference coordinate.   '''
+               """!
+               Set the reference coordinate.
+               @param coor the coordinate tuple (x,y)
+               """
                self.coor = coor
        
        def get_parent(self):
-               '''     get the parent  '''     
+               """!
+               Get the parent of this element.
+               @return the parent
+               """     
                return self.parent
        
        def set_highlighted(self, highlighted):
-               """     set the highlight status        """
+               """!
+               Set the highlight status.
+               @param highlighted true to enable highlighting
+               """
                self.highlighted = highlighted          
        
        def is_highlighted(self):
-               """     get the highlight status        """
+               """!
+               Get the highlight status.
+               @return true if highlighted
+               """
                return self.highlighted
                        
        def get_coordinate(self):
-               """     get the coordinate (X,Y) pair   """
+               """!Get the coordinate.
+               @return the coordinate tuple (x,y)
+               """
                return self.coor
                
        def move(self, delta_coor):
-               """     we move the element by adding the X and Y values of 
deltaCoor to this coordinate        """
+               """!
+               Move the element by adding the delta_coor to the current 
coordinate.
+               @param delta_coor (delta_x,delta_y) tuple
+               """
                deltaX,deltaY = delta_coor
                X,Y = self.get_coordinate()     
                self.coor = (X+deltaX, Y+deltaY)        
        
        def add_area(self, rel_coor, area, rotation=None):
-               """     add an area to the area list, an area is actually a 
coordinate relative to the main coordinate
-               with a width/height pair relative to the area coordinate. A 
positive width is to the right of the
-               coordinate. A positive height is above the coordinate   """
+               """!
+               Add an area to the area list. 
+               An area is actually a coordinate relative to the main 
coordinate with a width/height pair relative to the area coordinate. 
+               A positive width is to the right of the coordinate. A positive 
height is above the coordinate.
+               The area is associated with a rotation. If rotation is not 
specified, the element's current rotation is used.
+               @param rel_coor (x,y) offset from this element's coordinate
+               @param area (width,height) tuple
+               @param rotation rotation in degrees
+               """
                if rotation == None: rotation = self.get_rotation()
                self.areas_dict[rotation].append((rel_coor, area))
                
        def add_line(self, rel_coor1, rel_coor2, rotation=None):
-               """     add a line to the line list. A line is defined by 2 
relative coordinates.       
-               Lines must be horizontal or vertical!   """
+               """!
+               Add a line to the line list. 
+               A line is defined by 2 relative coordinates.    Lines must be 
horizontal or vertical.
+               The line is associated with a rotation. If rotation is not 
specified, the element's current rotation is used.
+               @param rel_coor1 relative (x1,y1) tuple
+               @param rel_coor2 relative (x2,y2) tuple
+               @param rotation rotation in degrees
+               """
                if rotation == None: rotation = self.get_rotation()
                self.lines_dict[rotation].append((rel_coor1, rel_coor2))        
        
        def what_is_selected(self, coor):
-               """     is this Element selected at given coor? Or is coor 
encompassed by one of the areas or lines. 
-               We determine the absolute coordinate of each area and 
coordinate on the other diagonal of the area. 
-               return self if one of the areas/lines encompasses the coor, or 
None.    """
+               """!
+               Is this Element selected at given coordinate/is the coordinate 
encompassed by one of the areas or lines?
+               @return self if one of the areas/lines encompasses coor, else 
None.     
+               """
                in_between = lambda A, B, point: point >= min(A,B) and point <= 
max(A,B)
                X,Y = self.get_coordinate()     
                x,y = coor      
@@ -116,17 +151,22 @@
                return None             
                                
        def get_rotation(self):
-               """     get the rotation        """
+               """!
+               Get the rotation in degrees.
+               @return the rotation
+               """
                return self.rotation                    
        
        def set_rotation(self, rotation):
-               """     set the rotation        """
+               """!
+               Set the rotation in degrees.
+               @param rotation the rotation"""
                if rotation not in POSSIBLE_ROTATIONS:
                        raise Exception('"%s" is not one of the possible 
rotations: (%s)'%(rotation,POSSIBLE_ROTATIONS))
                self.rotation = rotation                
                
        def update(self): 
-               """ Do nothing for the update. """
+               """Do nothing for the update. Dummy method."""
                pass
 
        
\ No newline at end of file

Modified: grc/trunk/src/Elements/GraphicalConnection.py
===================================================================
--- grc/trunk/src/Elements/GraphicalConnection.py       2007-06-29 17:29:46 UTC 
(rev 5877)
+++ grc/trunk/src/Elements/GraphicalConnection.py       2007-06-29 17:41:26 UTC 
(rev 5878)
@@ -16,23 +16,21 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       Elements/GraphicalConnection.py 
-       Josh Blum
-       The graphical connection for input/output sockets.
-"""
address@hidden Elements.GraphicalConnection
+#The graphical connection for input/output sockets.
address@hidden Josh Blum
 
-import DataType
+import DataTypes
 import Utils
-from Connection import Connection
-from GraphicalElement import GraphicalElement
+import Connection
+import GraphicalElement
 import Colors
 
-class GraphicalConnection(Connection, GraphicalElement):
-       """     Connection is a graphical connection for sockets        """     
                
+class GraphicalConnection(Connection.Connection, 
GraphicalElement.GraphicalElement):
+       """A graphical connection for sockets."""                       
        
        def update(self):
-               """     add the horizontal and vertical lines that will connect 
the two parameters      """
+               """Add the horizontal and vertical lines that will connect the 
two parameters."""
                self.clear()            
                input_socket = self.get_input_socket()
                output_socket = self.get_output_socket()
@@ -70,9 +68,12 @@
                        self.add_line((x2,y2),p)        
                
        def draw(self, window):
-               """     draw the Connection     """
+               """!
+               Draw the connection.
+               @param window the gtk window to draw on
+               """
                self.update()   
-               GraphicalElement.draw(self, window)     
+               GraphicalElement.GraphicalElement.draw(self, window)    
                gc = self.gc                                    
                '''     draw error lines around the existing lines when data 
types do not match '''
                if not self.is_valid():
@@ -86,9 +87,12 @@
                                        window.draw_line(gc, x1, y1+1, x2, y2+1)
                
        def is_valid(self):
-               """ is this connection valid, ie: do the input and output data 
types match?     """
+               """!
+               Is this connection valid, ie: do the input and output data 
types match?
+               User preferences can override this validity check.
+               @return true if the data types match or if check connections is 
off
+               """
                import Preferences      #preferences
                return not Preferences.check_connections() or\
-                       DataType.can_connect(self.sockets[0].get_data_type(), 
self.sockets[1].get_data_type())
-       
+                       DataTypes.can_connect(self.sockets[0].get_data_type(), 
self.sockets[1].get_data_type()) 
                                                        

Modified: grc/trunk/src/Elements/GraphicalElement.py
===================================================================
--- grc/trunk/src/Elements/GraphicalElement.py  2007-06-29 17:29:46 UTC (rev 
5877)
+++ grc/trunk/src/Elements/GraphicalElement.py  2007-06-29 17:41:26 UTC (rev 
5878)
@@ -16,26 +16,30 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       Elements/GraphicalElement.py 
-       Josh Blum
-       base class for graphical elements such as:
-       signal blocks, input sockets, output sockets and connections
-"""
address@hidden Elements.GraphicalElement
+#Base class for graphical elements such as:
+#signal blocks, input sockets, output sockets and connections.
address@hidden Josh Blum
+
 from Constants import *
-from Element import Element
+import Element
 import Colors
 import pygtk
 pygtk.require('2.0')
 import gtk
 import pango
 
-class GraphicalElement(Element):
+class GraphicalElement(Element.Element):
        """     Element is the base class for all graphical elements. It 
contains an X,Y coordinate, a list
        of rectangular areas that the element occupies and methods to detect 
selection. """             
        
        def draw(self, window, BG_color=Colors.BG_COLOR, 
FG_color=Colors.FG_COLOR):
-               """     draw in the given window.       """
+               """!
+               Draw in the given window.
+               @param window the gtk window to draw on
+               @param BG_color the background color
+               @param FG_color the foreground color
+               """
                gc = self.get_parent().gc       
                self.gc = gc
                X,Y = self.get_coordinate()
@@ -51,7 +55,5 @@
                        if self.is_highlighted(): gc.foreground = Colors.H_COLOR
                        else: gc.foreground = FG_color
                        window.draw_line(gc, X+x1, Y+y1, X+x2, Y+y2)
-                               
-       
 
        
\ No newline at end of file

Modified: grc/trunk/src/Elements/GraphicalParam.py
===================================================================
--- grc/trunk/src/Elements/GraphicalParam.py    2007-06-29 17:29:46 UTC (rev 
5877)
+++ grc/trunk/src/Elements/GraphicalParam.py    2007-06-29 17:41:26 UTC (rev 
5878)
@@ -16,14 +16,12 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       Elements/GraphicalParam.py 
-       Josh Blum
-       GTK objects for handling input and the signal block parameter class.
-"""
address@hidden Elements.GraphicalParam
+#GTK objects for handling input and the signal block parameter class.
address@hidden Josh Blum
 
-from Param import Param
-from DataType import *
+import Param
+from DataTypes import *
 import pygtk
 pygtk.require('2.0')
 import gtk
@@ -38,14 +36,12 @@
 
 class InputParam(gtk.HBox):
        """ The base class for an input parameter inside the input parameters 
dialog.   """
-       def __init__(self, data_type, handle_changed):
+       def __init__(self, data_type, _handle_changed):
                gtk.HBox.__init__(self)
-               self.show()
                self.data_type = data_type
-               self.handle_changed = handle_changed
-               self.label = gtk.Label('')      #no label, markup is added by 
set_markup
-               self.label.set_size_request(140,30)
-               self.label.show()
+               self._handle_changed = _handle_changed
+               self.label = gtk.Label()        #no label, markup is added by 
set_markup
+               self.label.set_size_request(140,-1)
                self.pack_start(self.label, False)
                self.set_markup = lambda m: self.label.set_markup(m)    
                self.tp = None          
@@ -54,11 +50,10 @@
        """ Provide an entry box for strings and numbers.       """
        def __init__(self, *args):
                InputParam.__init__(self, *args)
-               self.entry = input = gtk.Entry()                                
+               self.entry = input = gtk.Entry()                
                input.set_text(self.data_type.get_data())
-               input.connect("changed", self.handle_changed)
-               input.show()
-               self.pack_start(input, False)
+               input.connect("changed", self._handle_changed)
+               self.pack_start(input, True)
                self.get_text = input.get_text
                # tool tip fun #
                self.tp = gtk.Tooltips()
@@ -68,10 +63,9 @@
 class FileParam(EntryParam):
        """ Provide an entry box for filename and a button to browse for a 
file.        """
        def __init__(self, *args):
-               EntryParam.__init__(self, *args)
+               EntryParam.__init__(self, *args)                
                input = gtk.Button('...')
                input.connect('clicked', self.handle_clicked)
-               input.show()
                self.pack_start(input, False)
        
        def handle_clicked(self, widget=None):
@@ -94,7 +88,7 @@
                if gtk.RESPONSE_OK == file_dialog.run():        #run the dialog
                        file_path = file_dialog.get_filename()  #get the file 
path
                        self.entry.set_text(file_path)
-                       self.handle_changed()
+                       self._handle_changed()
                file_dialog.destroy()   #destroy the dialog                     
                        
                
 class EnumParam(InputParam):
@@ -107,8 +101,7 @@
                input.add_attribute(cell, 'text', 0)
                for cname in self.data_type.get_cnames_list(): 
input.append_text(cname)
                input.set_active(int(self.data_type.get_data()))
-               input.show()
-               input.connect("changed", self.handle_changed)
+               input.connect("changed", self._handle_changed)
                self.pack_start(input, False)
                self.get_text = lambda: str(input.get_active()) #the get text 
parses the selected index to a string
 
@@ -116,38 +109,54 @@
 #      A Parameter, hold a data type and a cname
 
######################################################################################################
 
-class GraphicalParam(Param):
-                       
-       def get_input_object(self):
-               """ Get the graphical gtk class to represent this parameter.    
-               Create the input object with this data type and the handle 
changed method."""
+class GraphicalParam(Param.Param):
+       """The graphical parameter."""  
+
+       def update(self):
+               """Called when an external change occurs.
+               Update the graphical input by calling the change handler."""
+               if self.input: self._handle_changed()   
+               
+       def get_input_object(self, callback=None):
+               """!
+               Get the graphical gtk class to represent this parameter.        
+               Create the input object with this data type and the handle 
changed method.
+               @param callback a function of one argument(this param) to be 
called from the change handler
+               @return gtk input object
+               """
+               self.callback=callback
                if self.get_data_type().get_base_type() == 
Enum().get_base_type(): input = EnumParam
                elif self.get_data_type().get_base_type() == 
File().get_base_type(): input = FileParam
                else: input = EntryParam
-               self.input = input(self.get_data_type(), self.handle_changed)
-               self.handle_changed()
+               self.input = input(self.get_data_type(), self._handle_changed)
+               self._handle_changed()
                return self.input
                
-       def handle_changed(self, widget=None):
-               ''' if the input changed, write the inputs to the param.        
'''
+       def _handle_changed(self, widget=None):
+               """When the input changes, write the inputs to the data type.
+               Finish by calling the exteral callback."""
                data_type = self.get_data_type()
                new_data = self.input.get_text()
                old_data = data_type.get_data()
                if old_data != new_data: data_type.set_data(new_data)
-               #       Set the markup on the label, red for errors in 
cooresponding data type. #
+               #set the markup on the label, red for errors in corresponding 
data type.
                cname = self.get_cname()
-               if not data_type.is_valid(): 
-                       self.input.set_markup('<span 
foreground="red"><b>'+cname+'</b></span>')
-                       if self.input.tp: 
self.input.tp.set_tip(self.input.entry, data_type.msg)
-               else: 
-                       self.input.set_markup(cname)    
-                       if self.input.tp: 
self.input.tp.set_tip(self.input.entry, str(data_type.parse()))
+               if self.variable: cname = '<span 
underline="low">%s</span>'%cname #alter format if the param is variable
+               if not data_type.is_valid(): self.input.set_markup('<span 
foreground="red"><b>%s</b></span>'%cname)
+               else: self.input.set_markup(cname)
+               #set the tooltip                
+               if self.input.tp: self.input.tp.set_tip(self.input.entry, 
str(data_type))       
+               #execute the external callback 
+               if self.callback: self.callback(self)
 
        def get_markup(self):
-               """ Create a markup to display the Param as a label on the 
SignalBlock. 
+               """!
+               Create a markup to display the Param as a label on the 
SignalBlock.     
                If the data type is an Enum type, use the cname of the Enum's 
current choice.   
                Otherwise, use parsed the data type and use its string 
representation.
-               If the data type is not valid, use a red foreground color.      
"""
+               If the data type is not valid, use a red foreground color.
+               @return pango markup string
+               """
                
###########################################################################
                #       display logic for numbers
                
###########################################################################
@@ -197,7 +206,10 @@
                else:   return '<span foreground="red"><b>%s:</b> 
error</span>'%self.cname
                        
        def get_layout(self):
-               """ Create a layout based on the current Param's Markup.        
"""
+               """!
+               Create a layout based on the current markup.
+               @return the pango layout
+               """
                layout = gtk.DrawingArea().create_pango_layout('')
                layout.set_markup(self.get_markup())
                desc = pango.FontDescription(PARAM_FONT)

Modified: grc/trunk/src/Elements/GraphicalSignalBlock.py
===================================================================
--- grc/trunk/src/Elements/GraphicalSignalBlock.py      2007-06-29 17:29:46 UTC 
(rev 5877)
+++ grc/trunk/src/Elements/GraphicalSignalBlock.py      2007-06-29 17:41:26 UTC 
(rev 5878)
@@ -16,34 +16,31 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       Elements/GraphicalSignalBlock.py 
-       Josh Blum
-       the graphical signal block
-"""
address@hidden Elements.GraphicalSignalBlock
+#The graphical signal block.
address@hidden Josh Blum
 
-from SignalBlock import SignalBlock
+import SignalBlock
 import Utils
 import Colors
 from GraphicalParam import GraphicalParam
-from GraphicalElement import GraphicalElement
+import GraphicalElement
 from GraphicalSocket import GraphicalInputSocket,GraphicalOutputSocket
 from Constants import *
-from DataType import Enum,Int
+from DataTypes import Enum,Int
 import pygtk
 pygtk.require('2.0')
 import gtk
 import pango
 
-class GraphicalSignalBlock(SignalBlock, GraphicalElement):
-       """     SignalBlock is a graphical signal block. It is a Element with 
an index from the list of 
-       possible signal blocks and graphical input/output elements.     """     
        
+class GraphicalSignalBlock(SignalBlock.SignalBlock, 
GraphicalElement.GraphicalElement):
+       """The graphical signal block."""               
        param_constructor = GraphicalParam
        input_socket_constructor = GraphicalInputSocket
        output_socket_constructor = GraphicalOutputSocket
        
        def update(self):
-               """ update the block and parameters and sockets when a change 
occurs    """
+               """Update the block, parameters, and sockets when a change 
occurs."""
                self.clear()
                self._adjust_sockets()          
                self._create_labels()                           
@@ -55,7 +52,7 @@
                for socket in self.get_sockets(): socket.update()               
        
        
        def _create_labels(self):
-               '''     Create the labels for the signal block.         '''
+               """Create the labels for the signal block."""
                layouts = list()
                #       create the main layout  #
                layout = gtk.DrawingArea().create_pango_layout(self.cname)
@@ -95,8 +92,11 @@
                                for j in range(height): vimage.put_pixel(j, 
width-i-1, image.get_pixel(i, j))
                
        def draw(self, window):
-               """     draw the signal block with label and inputs/outputs     
"""
-               GraphicalElement.draw(self, window)             
+               """!
+               Draw the signal block with label and inputs/outputs.
+               @param window the gtk window to draw on
+               """
+               GraphicalElement.GraphicalElement.draw(self, window)            
                gc = self.gc            
                gc.foreground = Colors.TXT_COLOR
                X,Y = self.get_coordinate()             
@@ -107,7 +107,11 @@
                for socket in self.get_sockets(): socket.draw(window)
                
        def is_valid(self):             
-               ''' This block is valid if all the params are valid and all 
sockets connected.  '''
+               """!
+               Is this block is valid/are all the params valid and all sockets 
connected?
+               User preferences can override certain validity checks.
+               @return true if valid
+               """
                import Preferences
                if Preferences.check_params():  #preferences
                        for param in self.params:
@@ -118,8 +122,10 @@
                return True
                
        def modify_type_controller(self, direction):
-               """ If a type controller was set, increment/decrement its index 
by 1, use a % to stay in bounds.        
-                       Direction may be +1 or -1"""
+               """!
+               If a type controller was set, increment/decrement its index by 
1, use a % to stay in bounds.    
+               @param direction +1 or -1
+               """
                if self.type_controller != None and 
self.type_controller.get_type() == Enum().get_type():
                        num_choices = 
len(self.type_controller.get_cnames_list())
                        index = int(self.type_controller.get_data())
@@ -129,10 +135,12 @@
                return False
                
        def modify_socket_controller(self, direction):
-               """ If a socket controller was set, increment/decrement its 
data type by 1, DO NOT go out of bounds.
-                       Return True if operation was done. Return False if 
operation could not be completed.
-                       If there is a controller on input and outputs, show 
preference to the output controller. 
-                       Direction may be +1 or -1.      """
+               """!
+               If a socket controller was set, increment/decrement its data 
type by 1, DO NOT go out of bounds.
+               If there is a controller on input and outputs, show preference 
to the output controller. 
+               @param direction +1 or -1
+               @return true if operation was done, false if operation could 
not be completed.
+               """
                # Get the socket controller, if there is an input and output 
controller, use output     #
                socket_controller = None                
                if self.input_sockets_controller != None: socket_controller = 
self.input_sockets_controller

Modified: grc/trunk/src/Elements/GraphicalSocket.py
===================================================================
--- grc/trunk/src/Elements/GraphicalSocket.py   2007-06-29 17:29:46 UTC (rev 
5877)
+++ grc/trunk/src/Elements/GraphicalSocket.py   2007-06-29 17:41:26 UTC (rev 
5878)
@@ -16,16 +16,14 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       Elements/GraphicalSocket.py 
-       Josh Blum
-       the graphical input/output sockets of the signal block
-"""
address@hidden Elements.GraphicalSocket
+#The graphical input/output sockets of the signal block.
address@hidden Josh Blum
 
 import Utils
-from Socket import Socket
-from GraphicalElement import GraphicalElement
-from DataType import *
+import Socket
+import GraphicalElement
+from DataTypes import *
 from Constants import *
 import Colors
 import pygtk
@@ -33,12 +31,11 @@
 import gtk
 import pango
 
-class GraphicalSocket(Socket, GraphicalElement):
-       """     Socket is a graphical signal block input/output parameter. 
-       It has an index, input/output setting, and a data type. """     
+class GraphicalSocket(Socket.Socket, GraphicalElement.GraphicalElement):
+       """The graphical socket."""     
                                
        def update(self):
-               """     update the coloring, a change may have occured in the 
block params      """
+               """Create new areas and labels for the socket."""
                self.clear()
                self.BG_color = {
                        Complex().get_type():Colors.COMPLEX_COLOR,
@@ -51,7 +48,7 @@
                        FloatVector().get_type():Colors.FLOAT_VECTOR_COLOR,
                        IntVector().get_type():Colors.INT_VECTOR_COLOR,
                        ShortVector().get_type():Colors.SHORT_VECTOR_COLOR,     
                
-                       ByteVector().get_type():Colors.BYTE_VECTOR_COLOR,       
+                       ByteVector().get_type():Colors.BYTE_VECTOR_COLOR,
                }[self.get_data_type().get_type()]
                self._create_labels()           
                #       add the input/output area for each rotation angle       
#       
@@ -86,7 +83,7 @@
                        if self.is_connected(): 
self.__set_connector_coordinates((x+conOff, y+1+SOCKET_WIDTH),(x+conOff, 
y+SOCKET_WIDTH+conExtInitLen+conExtLen*index))
                        
        def _create_labels(self):
-               '''     Create the labels for the socket.               '''
+               """Create the labels for the socket."""
                #       create the layout       #
                layout = gtk.DrawingArea().create_pango_layout(self.cname)
                desc = pango.FontDescription(SOCKET_FONT)
@@ -107,8 +104,11 @@
                                for j in range(h): vimage.put_pixel(j, w-i-1, 
image.get_pixel(i, j))
                                
        def draw(self, window):
-               """     draw the paramter with labels   """
-               GraphicalElement.draw(self, window, BG_color=self.BG_color)     
                        
+               """!
+               Draw the socket with a label.
+               @param window the gtk window to draw on
+               """
+               GraphicalElement.GraphicalElement.draw(self, window, 
BG_color=self.BG_color)                            
                gc = self.gc                            
                gc.foreground = Colors.TXT_COLOR
                X,Y = self.get_coordinate()
@@ -117,29 +117,42 @@
                elif Utils.is_vertical(self.get_rotation()): 
window.draw_image(gc, self.vertical_label, 0, 0, x+X+(SOCKET_HEIGHT-self.h)/2, 
y+Y+(SOCKET_WIDTH-self.w)/2, -1, -1)
        
        def __set_connector_coordinates(self, coor_inner, coor_outer, 
rotation=None):
-               """ Set the coordinates that connectors may attach to.  """
+               """!
+               Set the coordinates that connectors may attach to.
+               The connector coordinates are associated with a rotation. If 
rotation is not specified, the element's current rotation is used.
+               @param coor_inner the corrdinate on the socket
+               @param coor_outer the coordinate out of the socket
+               @param rotation rotation in degrees
+               """
                if rotation == None: rotation = self.get_rotation()     
                self.connector_coordinates[rotation] = coor_inner, coor_outer   
        
        def get_connector_coordinates(self, rotation=None):
-               """     Get the coordinates that Connections may attach to.     
"""
+               """!
+               Get the coordinates that Connections may attach to.
+               @param rotation rotation in degrees
+               @return the connector coordinates ((xin, yin), (xout, yout)) 
tuple
+               """
                if rotation == None: rotation = self.get_rotation()     
                X,Y = self.get_coordinate()     
                (x1,y1),(x2,y2)= self.connector_coordinates[rotation]
                return (x1+X, y1+Y), (x2+X, y2+Y)
                        
        def get_connector_direction(self):
-               """     the direction that the socket points in 0,90,180,270
-               this is the rotation degree if the socket is an output or
-               the rotation degree + 180 if the socket is an input     """     
+               """!
+               Get the direction that the socket points: 0,90,180,270.
+               This is the rotation degree if the socket is an output or
+               the rotation degree + 180 if the socket is an input.
+               @return the direction in degrees
+               """     
                if Utils.is_output_socket(self): return self.get_rotation()
                elif Utils.is_input_socket(self): return (self.get_rotation() + 
180)%360                                
        
 class GraphicalInputSocket(GraphicalSocket):
-       ''' The socket for input        '''
-       type = 'input socket'
+       """ The socket for input        """
+       type = Socket.InputSocket.type
 
 class GraphicalOutputSocket(GraphicalSocket):
-       ''' The socket for output       '''
-       type = 'output socket'
+       """ The socket for output       """
+       type = Socket.OutputSocket.type
                
\ No newline at end of file

Modified: grc/trunk/src/Elements/Param.py
===================================================================
--- grc/trunk/src/Elements/Param.py     2007-06-29 17:29:46 UTC (rev 5877)
+++ grc/trunk/src/Elements/Param.py     2007-06-29 17:41:26 UTC (rev 5878)
@@ -16,26 +16,36 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       Elements/Param.py 
-       Josh Blum
-       A signal block parameter.
-"""
address@hidden Elements.Param
+#A signal block parameter.
address@hidden Josh Blum
 
 class Param:
-       """ This class holds a single signal block parameter, 
-       a data type and a cname.        """
-       def __init__(self, cname, data_type):
-               """ Initialize by setting the data type and cname.      """
+       """A param holds a single signal block parameter: a data type and a 
canonical name."""
+       def __init__(self, cname, data_type, variable=False):
+               """!
+               Param constructor. Set the data type and cname.
+               @param cname the canonical name
+               @param data_type the data type
+               @param variable true if the param can be changed at runtime
+               """
                self.cname = cname
                self.data_type = data_type
-               self.input = None
+               ##the graphical input object            
+               self.input = None       
+               self.variable = variable
                
        def get_cname(self):
-               """ Get the cname.      """
+               """!
+               Get the cname.
+               @return the canonical name
+               """
                return self.cname
                
        def get_data_type(self):
-               """ Get the data type.  """
+               """!
+               Get the data type.
+               @return the data type
+               """
                return self.data_type
 

Modified: grc/trunk/src/Elements/SignalBlock.py
===================================================================
--- grc/trunk/src/Elements/SignalBlock.py       2007-06-29 17:29:46 UTC (rev 
5877)
+++ grc/trunk/src/Elements/SignalBlock.py       2007-06-29 17:41:26 UTC (rev 
5878)
@@ -16,34 +16,38 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       Elements/SignalBlock.py 
-       Josh Blum
-       The elemental signal block
-"""
address@hidden Elements.SignalBlock
+#The elemental signal block.
address@hidden Josh Blum
 
-from Element import Element
+import Element
 import Utils
 from Socket import OutputSocket,InputSocket
 from Param import Param
-from DataType import Enum,Int,Vector
+from DataTypes import Enum,Int,Vector
 
-class SignalBlock(Element):
-       """     SignalBlock is an Element with an index from the list of 
-       possible signal blocks and graphical input/output elements.     """     
+class SignalBlock(Element.Element):
+       """A SignalBlock is an Element with an index from the list of possible 
signal blocks and input/output sockets."""       
        type = 'signal block'
        param_constructor = Param
        input_socket_constructor = InputSocket
        output_socket_constructor = OutputSocket
        def __init__(self, parent, coor, rotation, tag, id):
-               """ initialize the signalblock, adding lists for sockets, 
params        """
-               Element.__init__(self, parent, coor, rotation)
+               """!
+               SignalBlock constructor.
+               @param parent the flow graph
+               @param coordinate the (x,y) tuple
+               @param rotation the rotation in degrees
+               @param tag a string unique to signal blocks of this type
+               @param id a string unique to this signal block
+               """
+               Element.Element.__init__(self, parent, coor, rotation)
                self.tag = tag
                self.input_sockets = list()
                self.output_sockets = list()
                self.params = list()
                self.displayed_params = list()
-               self.cname = tag        #this may change
+               self.cname = tag        
                self.id = id
                self.input_sockets_controller = self.output_sockets_controller 
= None
                self.type_controller = None
@@ -51,70 +55,120 @@
                self.docs = None
                
        def get_docs(self):
-               ''' Get a string with helpful hints, suggestions, and 
documentation on using this block.        '''
+               """!
+               Get a string with helpful hints, suggestions, and documentation 
on using this block.
+               @return the documentation string
+               """
                return self.docs
                
        def set_docs(self, docs):
-               ''' Set the documentation for this block.       '''
+               """!
+               Set the documentation for this block.
+               @param docs the documentation string
+               """
                self.docs = docs
                
        def get_sockets(self):
-               '''     Get a list of all sockets.      '''
+               """!
+               Get all sockets for this signal block.
+               @return a list of sockets
+               """
                return self.input_sockets + self.output_sockets
        
        def get_input_socket(self, index):
-               ''' Get the input socket at index.      '''
+               """!
+               Get the input socket at index.
+               @param index the input socket index
+               @return an input socket
+               """
                self._adjust_sockets() #a parameter change may have altered the 
sockets
                for socket in filter(Utils.is_input_socket, self.get_sockets()):
                        if socket.get_index() == index: return socket
                return None
                
        def get_output_socket(self, index):
-               ''' Get the output socket at index.     '''
+               """!
+               Get the output socket at index.
+               @param index the output socket index
+               @return an output socket
+               """
                self._adjust_sockets() #a parameter change may have altered the 
sockets
                for socket in filter(Utils.is_output_socket, 
self.get_sockets()):
                        if socket.get_index() == index: return socket
                return None
                
        def get_id(self):
-               ''' Get the id. '''
+               """!
+               Get the id.
+               @return the id string
+               """
                return self.id
                
        def get_tag(self):      
-               ''' Get the tag.        '''
+               """!
+               Get the tag.
+               @return the tag string
+               """
                return self.tag
                
        def get_cname(self):
-               ''' Get the cname.      '''
+               """!
+               Get the canonical name.
+               @return the cname string
+               """
                return self.cname
                
        def get_params(self):
-               ''' Get the params list.        '''
+               """!
+               Get all of the parameters for this signal block.
+               @return a list of parameters
+               """
                return self.params              
        
        def get_num_input_sockets(self):
-               '''     Get the number of sockets of input type.        '''
+               """!
+               Get the number of sockets of input type.
+               @return an integer number of sockets
+               """
                return len(self.input_sockets)
                
        def get_num_output_sockets(self):
-               '''     Get the number of sockets of output type.       '''
+               """!
+               Get the number of sockets of output type.
+               @return an integer number of sockets
+               """
                return len(self.output_sockets)
                
        def add_input_socket(self, cname, data_type, optional=False, vlen=None):
-               '''     Append an input socket with its cname and data type.    
'''
+               """!
+               Add an input socket with its cname and data type.
+               @param cname the canonical name
+               @param data_type the data type
+               @param optional true if connections are optional
+               @param vlen the width of each sample (how many numbers are in 
each sample?)
+               """
                self.input_sockets.append(self.input_socket_constructor(self, 
cname, self.get_num_input_sockets(), data_type, optional, vlen))
                
        def add_output_socket(self, cname, data_type, optional=False, 
vlen=None):
-               '''     Append an output socket with its cname and data type.   
'''
+               """!
+               Add an output socket with its cname and data type.
+               @param cname the canonical name
+               @param data_type the data type
+               @param optional true if connections are optional
+               @param vlen the width of each sample (how many numbers are in 
each sample?)
+               """
                self.output_sockets.append(self.output_socket_constructor(self, 
cname, self.get_num_output_sockets(), data_type, optional, vlen))
                
-       def add_param(self, cname, data_type, show_label=True, type=False, 
output_sockets_controller=False, input_sockets_controller=False):
-               '''     Append a param with its cname and data type.
-                       The show_label boolean flag tells the signal blocks to 
display the parameter in its label.
-                       The type boolean flag registers this parameter to be 
controlled via keypress.
-                       The output_sockets_controller registers this parameter 
to set the number of output sockets. 
-                       The input_sockets_controller registers this parameter 
to set the number of input sockets.       '''
-               param = self.param_constructor(cname, data_type)
+       def add_param(self, cname, data_type, show_label=True, type=False, 
output_sockets_controller=False, input_sockets_controller=False, 
variable=False):
+               """!
+               Add a parameter with its cname and data type.
+               @param show_label true to display the parameter in the signal 
block's label
+               @param type true if this param is an enum to be controlled via 
a keypress
+               @param output_sockets_controller register this parameter to set 
the number of output sockets 
+               @param input_sockets_controller register this parameter to set 
the number of input sockets
+               @param variable true if the param can be changed at runtime
+               """
+               param = self.param_constructor(cname, data_type, variable)
                if show_label: self.displayed_params.append(param)
                if type: self.type_controller = data_type
                if output_sockets_controller: self.output_sockets_controller = 
data_type
@@ -122,20 +176,27 @@
                self.params.append(param)               
        
        def what_is_selected(self, coor):       
-               """ get the element that is selected, signal block itself or a 
socket   """
+               """!
+               Get the element that is selected.
+               @param coor the (x,y) tuple
+               @return this signal block, a socket, or None
+               """
                for socket in self.get_sockets():       
                        if socket.what_is_selected(coor) != None:
                                return socket.what_is_selected(coor)            
-               return Element.what_is_selected(self, coor)
+               return Element.Element.what_is_selected(self, coor)
                
        def get_connections(self):
-               ''' Get a set of all connections from every socket.     '''
+               """!
+               Get all connections from every socket.
+               @return a set of connections
+               """
                connections = list()
                for socket in self.get_sockets(): connections = connections + 
socket.get_connections()
                return set(connections)
        
        def _adjust_sockets(self):
-               ''' Use the input/output socket controllers to adjust the 
number of sockets.    '''     
+               """Use the input/output socket controllers to adjust the number 
of sockets."""  
                for sockets_list,controller,constructor in (
                        (self.input_sockets, self.input_sockets_controller, 
self.input_socket_constructor), 
                        (self.output_sockets, self.output_sockets_controller, 
self.output_socket_constructor)
@@ -160,11 +221,16 @@
 ##     Import a Signal Block
 ##########################################################################
        def from_nested_data(fg, nested_data, sb_constructor):
-               ''' Create a signal block from the nested data.
-                       Pass the flow graph/parent of the signal block,
-                       the nested data for a signal block, 
-                       and the contructor for the signal block.
-                       Return (the signal block, the runnable signal block) 
tuple.     '''
+               """!
+               Create a signal block from the nested data.
+               Pass the flow graph/parent of the signal block,
+               the nested data for a signal block, 
+               and the contructor for the signal block.
+               Return (the signal block, the runnable signal block) tuple.
+               @param fg the flow graph
+               @param nested_data the nested data
+               @param sb_contructor the contructor used to make a new signal 
block
+               """
                import ParseXML,Messages,SignalBlockDefs
                find_data = ParseXML.find_data
                signal_block = find_data([nested_data], 'signal_block')

Modified: grc/trunk/src/Elements/Socket.py
===================================================================
--- grc/trunk/src/Elements/Socket.py    2007-06-29 17:29:46 UTC (rev 5877)
+++ grc/trunk/src/Elements/Socket.py    2007-06-29 17:41:26 UTC (rev 5878)
@@ -16,23 +16,30 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       Elements/Socket.py 
-       Josh Blum
-       The elemental input and output sockets of a signal block
-"""
address@hidden Elements.Socket
+#The elemental input and output sockets of a signal block.
address@hidden Josh Blum
 
-from Element import Element
-import Utils,DataType
-from Connection import TooManyConnectionsException
+import Element
+import Utils,DataTypes
+from Connection import ConnectionException
 
-class Socket(Element):
-       """     Socket is an input/output element of a signal block. 
-       It has an index, input/output setting, and a data type. """     
+class Socket(Element.Element):
+       """
+       A Socket is an input/output element of a signal block. 
+       It has an index, input/output setting, and a data type.
+       """     
        type = 'socket'
        def __init__(self, parent, cname, index, data_type, optional=False, 
vlen=None):
-               """ Initialize the Element and set the parent, coor, and 
rotation       """
-               Element.__init__(self, parent, (0,0), 0) #use zeros since the 
parent contains this information
+               """!
+               Socket constructor. 
+               @param parent the signal block
+               @param coordinate the (x,y) tuple
+               @param rotation the rotation in degrees
+               @param optional true if connections are optional
+               @param vlen the width of each sample (how many numbers are in 
each sample?)
+               """
+               Element.Element.__init__(self, parent, (0,0), 0) #use zeros 
since the parent contains this information
                self.connections = list()       
                self.w = self.h = 0
                self.index = index      
@@ -43,71 +50,114 @@
                self.vlen = vlen
                                
        def move(self, delta_coor):
-               ''' Move the parent rather than self.   '''
+               """!
+               Move the parent rather than self.
+               @param delta_corr the (delta_x, delta_y) tuple
+               """
                self.get_parent().move(delta_coor)
                
        def rotate(self, direction):
-               ''' Rotate the parent rather than self. '''
+               """!
+               Rotate the parent rather than self.
+               @param direction degrees to rotate
+               """
                self.get_parent().rotate(direction)
                
        def get_coordinate(self):
-               '''     Use the parent's coordinate rather th.an self   '''
+               """!
+               Get the parent's coordinate rather than self.
+               @return the parents coordinate
+               """
                return self.get_parent().get_coordinate()
                
        def set_highlighted(self, highlight):
-               ''' Set the parent highlight rather than self.  '''
+               """!
+               Set the parent highlight rather than self.
+               @param highlight true to enable highlighting
+               """
                self.get_parent().set_highlighted(highlight)
                
        def is_highlighted(self):
-               ''' Use the parent's is highlight rather than self.     '''
+               """!
+               Get the parent's is highlight rather than self.
+               @return the parent's highlighting status
+               """
                return self.get_parent().is_highlighted()       
                
        def is_valid(self):     
-               ''' True if connected or the optional flag is True.     '''
+               """!
+               Is this socket valid?
+               @return true if connected or the optional flag is true
+               """
                return self.optional or self.is_connected()
        
        def get_rotation(self):
-               '''     use the parent's rotation as our own    '''
+               """!
+               Get the parent's rotation rather than self.
+               @return the parent's rotation
+               """
                return self.get_parent().get_rotation()
                
        def get_data_type(self):
-               ''' Get the data type. If the parsed vlen > 1, then return the 
vectorized data type.'''
-               if self.vlen != None and self.vlen.is_valid() and 
self.vlen.parse() > 1: return DataType.vectorize(self.data_type)
+               """!
+               Get the data type. If the parsed vlen > 1, then return the 
vectorized data type.
+               @return the data type
+               """
+               if self.vlen != None and self.vlen.is_valid() and 
self.vlen.parse() > 1: return DataTypes.vectorize(self.data_type)
                return self.data_type
                        
        def get_index(self):
-               """ get the index 0, 1, 2...    """
+               """!
+               Get the index of this socket.
+               @return the index (integer)     
+               """
                return self.index       
                        
        def get_cname(self):
-               """ get the cname       """
+               """!
+               Get the canonical name.
+               @return the cname (string)
+               """
                return self.cname
                
        def is_connected(self):
-               """ have a Connection (or more)?        """
+               """!
+               Have one or more connections?
+               @return true if at least one connection exists
+               """
                return len(self.connections) > 0 
                        
        def connect(self, connection):
-               """     Add a Connection to this socket, 
-               raise exception if this is an input with an existing 
connection.        """
-               if Utils.is_input_socket(self) and self.is_connected(): raise 
TooManyConnectionsException()
+               """!
+               Add a connection to this socket.
+               @param connection the connection
+               @throw TooManyConnectionsException input socket with an 
existing connection
+               """
+               if Utils.is_input_socket(self) and self.is_connected(): 
+                       raise ConnectionException, 'An input socket may only 
have one connection!'
                self.connections.append(connection)
                self.update()
                        
        def disconnect(self, connection):
-               """     Remove a Connection from this socket.   """
+               """!
+               Remove a Connection from this socket.
+               @param connection the connection
+               """
                self.connections.remove(connection)             
                self.update()   
                
        def get_connections(self):
-               ''' Get the list of connections.        '''
+               """!
+               Get all connections for this socket.
+               @return a list of connections
+               """
                return self.connections                 
 
 class InputSocket(Socket):
-       ''' The socket for input        '''
+       """ The socket for input        """
        type = 'input socket'
 
 class OutputSocket(Socket):
-       ''' The socket for output       '''
+       """ The socket for output       """
        type = 'output socket'
                
\ No newline at end of file

Modified: grc/trunk/src/Elements/Utils.py
===================================================================
--- grc/trunk/src/Elements/Utils.py     2007-06-29 17:29:46 UTC (rev 5877)
+++ grc/trunk/src/Elements/Utils.py     2007-06-29 17:41:26 UTC (rev 5878)
@@ -16,24 +16,27 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       Elements/Utils.py
-       Shared fucntions and exceptions for flow graph elements.
-"""
address@hidden Elements.Utils
+#Shared functions for flow graph elements.
address@hidden Josh Blum
 
 from SignalBlock import SignalBlock
 from Socket import OutputSocket,InputSocket
 from Connection import Connection      
 
-#      True if the rotation is 90 or 270 degrees.      #
+##     True if the rotation is 90 or 270 degrees.
 is_vertical = lambda rot: rot in (90, 270)     
 
-#      True if the rotation is 0 or 180 degrees.       #
+##     True if the rotation is 0 or 180 degrees.
 is_horizontal = lambda rot: rot in (0, 180)
 
 def get_angle_from_coordinates((x1,y1), (x2,y2)):
-       """ given two points, calculate the vector direction from point1 to 
point2, 
-       directions are multiples of 90 degrees. """
+       """!
+       Given two points, calculate the vector direction from point1 to point2, 
directions are multiples of 90 degrees.
+       @param (x1,y1) the coordinate of point 1
+       @param (x2,y2) the coordinate of point 2
+       @return the direction in degrees
+       """
        if y1 == y2:#0 or 180           
                if x2 > x1: return 0
                else: return 180                
@@ -44,13 +47,14 @@
 ##################################################################
 # Test methods for elements
 #################################################################
-#      test method for signal blocks #
+##     test method for signal blocks 
 is_signal_block = lambda obj: obj!= None and obj.type == SignalBlock.type
-# test methods for sockets     #
+## test methods for sockets @{
 is_input_socket = lambda obj: obj!= None and obj.type == InputSocket.type
 is_output_socket = lambda obj: obj!= None and obj.type == OutputSocket.type
 is_socket = lambda obj: is_input_socket(obj) or is_output_socket(obj)
-#      test method for connections #
address@hidden
+##     test method for connections 
 is_connection = lambda obj: obj!= None and obj.type == Connection.type
 
 

Modified: grc/trunk/src/Elements/__init__.py
===================================================================
--- grc/trunk/src/Elements/__init__.py  2007-06-29 17:29:46 UTC (rev 5877)
+++ grc/trunk/src/Elements/__init__.py  2007-06-29 17:41:26 UTC (rev 5878)
@@ -16,10 +16,9 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       Elements/__init__.py
-       All elements used in a flow graph go into this package.
-"""
address@hidden Elements.__init__
+#All elements used in a flow graph go into this package.
address@hidden Josh Blum
 
 import Utils
 

Modified: grc/trunk/src/ExecFlowGraph.py
===================================================================
--- grc/trunk/src/ExecFlowGraph.py      2007-06-29 17:29:46 UTC (rev 5877)
+++ grc/trunk/src/ExecFlowGraph.py      2007-06-29 17:41:26 UTC (rev 5878)
@@ -17,63 +17,84 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       ExecFlowGraph.py 
-       Josh Blum
-       Use a xml input file to build and run a gnu radio flow graph without 
graphics.
-"""
address@hidden ExecFlowGraph 
+#Use an xml input file to build and run a gnu radio flow graph without 
graphics.
address@hidden Josh Blum
 
 import ParseXML
 import Variables
-import SignalBlockDefs
 from Elements import SignalBlock
 from gnuradio import gr
 import os
-from Constants import DEFAULT_FILE_EXTENSION
+from Constants import FLOW_GRAPH_FILE_EXTENSION,MUTEX
 from optparse import OptionParser
 
 
##############################################################################################
 #      Flow Graph Builder
 
##############################################################################################
 
-class FlowGraphBuilder(gr.flow_graph):
+class FlowGraphBuilder(gr.top_block):
        """ Parse the input file to build the gnuradio flow graph.
                Register the variables, handle signal block callbacks.  """
-       def __init__(self, file_path):                  
-               nested_data = ParseXML.from_xml(ParseXML.from_file(file_path))
-               gr.flow_graph.__init__(self)
+       def __init__(self, file_path):          
+               gr.top_block.__init__(self, file_path)  
+               #internal data structures               
                self.callbacks = list()
-               self.var_keys = list()
-               self.parse_nested_data(nested_data)     
+               self.var_keys = list()          
+               self.runtime = gr.runtime(self)
+               self.started = False
+               #build the flow graph
+               
self._parse_nested_data(ParseXML.from_xml(ParseXML.from_file(file_path)))       
+               
+       def start(self):
+               """Start the flow graph."""
+               self.runtime.start()
+               self.started = True
+               
+       def stop(self):
+               """Stop the flow graph."""
+               self.runtime.stop()
+               self.started = False
                        
-       def add_window(self, window, type='', title=''):
-               ''' Empty method for adding a window in the GUI flow graph.     
'''
+       def add_window(self, *args):
+               """Empty method for adding a window in the GUI flow graph."""
                pass
                
        def get_panel(self):
-               ''' Empty method for getting the wx panel in the GUI flow 
graph.        ''' 
-               print '''
+               """Empty method for getting the wx panel in the GUI flow 
graph.""" 
+               print """
 Graphical Sinks are not supported in ExecFlowGraph.py:
  use ExecFlowGraphGUI.py [-d] or remove the Graphical Sink.
-Exiting!'''
+Exiting!"""
                exit(-1)
                
        def add_callback(self, function, data_type_params):
-               """ Register a callback function with its associated data.      
"""
+               """Register a callback function with its associated data."""
                self.callbacks.append((function, data_type_params))
                
        def parse_callbacks(self):
-               """ For each call back, parse all of the data and 
-               call the registered callback function on that data.     """
+               """For each call back, parse all of the data and 
+               call the registered callback function on that data."""
+               MUTEX.lock()
+               print "***\n\nCallback Time BEGIN\n\n***"
+               started = self.started
+               if started: self._hb.lock()
                for function, data_type_params in self.callbacks:
+                       print "***\nBegin A callback\n%s\n\n***"%function
                        try:
                                if type(data_type_params) in (type(list()), 
type(tuple())):
                                        function(*map(lambda param: 
param.parse(), data_type_params))
                                else: function(data_type_params.parse())        
        
-                       except: print "error parsing a callback -> ignoring..." 
+                       except Exception, e: print "***\n\nerror parsing a 
callback -> ignoring\n%s...\n\n***"%e
+                       print "***\nEnd A callback\n***"
+               if started: self._hb.unlock()
+               print "***\n\nCallback Time END\n\n***"
+               MUTEX.unlock()
                
-       def parse_nested_data(self, nested_data):
-               """ Parse nested data from a flow graph file and build the 
graphics. 
-               This code is partially copied from FlowGraph.py, with 
unnecessary code removed. """
+       def _parse_nested_data(self, nested_data):
+               """!
+               Parse nested data from a flow graph file and build the 
graphics. 
+               @param nested_data the nested flow graph data
+               """
                find_data = ParseXML.find_data
                flow_graph = find_data([nested_data], 'flow_graph')     
                vars = find_data(flow_graph, 'vars')
@@ -94,22 +115,46 @@
                        input_socket_index = int(find_data(connection, 
'input_socket_index'))
                        output_signal_block_id = find_data(connection, 
'output_signal_block_id')
                        output_socket_index = int(find_data(connection, 
'output_socket_index')) 
+                       input_signal_block = 
signal_blocks_dict[input_signal_block_id]
+                       output_signal_block = 
signal_blocks_dict[output_signal_block_id]                        
                        self.connect(#  use this flow graph's connect method    
#
-                               (signal_blocks_dict[output_signal_block_id], 
output_socket_index),
-                               (signal_blocks_dict[input_signal_block_id], 
input_socket_index))
+                               (output_signal_block, output_socket_index),
+                               (input_signal_block, input_socket_index))
                                
+##############################################################################################
+#      Option Parser for running a flow graph
+##############################################################################################
                         
+class FlowGraphOptionParser(OptionParser):
+       """This flow graph option parser provides a basic help, 
+       and ensures that a flow graph is passed on the command line."""
+       def __init__(self):
+               """Create the base option parser and add usage and basic 
options."""                    
+               usage = "usage: %prog [options] 
flow_graph"+FLOW_GRAPH_FILE_EXTENSION
+               OptionParser.__init__(self, usage=usage)                
+               self.add_option("-p", "--pid_file", action="store", 
type="string", dest="pid_file", help="record process id")   
+               
+       def parse_args(self):
+               """Call the base parse_args, handle the basic options,
+               and ensure a flow graph was passed in args. Return the 
(options, args)."""
+               (options, args) = OptionParser.parse_args(self)
+               if options.pid_file:
+                       try: open(options.pid_file, 'w').write('%d\n' % 
os.getpid())
+                       except: 
+                               print '\nCould not create pid file: 
"%s".\nExiting!'%options.pid_file
+                               exit(-1)
+               if not len(args): 
+                       self.print_help()
+                       exit(-1)
+               return options, args
+
+##############################################################################################
+#      Main
+##############################################################################################
                                 
 if __name__ == '__main__':     
-       usage = "usage: %prog [-p] flow_graph"+DEFAULT_FILE_EXTENSION
-       parser = OptionParser(usage=usage)
-       parser.add_option("-p", "--pid_file", action="store", type="string", 
dest="pid_file", help="record process id") 
-       (options, args) = parser.parse_args()
-       if options.pid_file:
-               try: open(options.pid_file, 'w').write('%d\n' % os.getpid())
-               except: print "could not create pid file: %s"%options.pid_file
-       if len(args): #only create the flow graph if a file was passed
-               fg = FlowGraphBuilder(args[0])
-               fg.start()
-               raw_input('Flow Graph Running...\nPress Enter to Exit: ')
-               fg.stop()       
-       else: parser.print_help()       
+       parser = FlowGraphOptionParser()
+       (options, args) = parser.parse_args()   
+       fg = FlowGraphBuilder(args[0])
+       fg.start()
+       raw_input('Flow Graph Running...\nPress Enter to Exit: ')
+       fg.stop()       
                        
\ No newline at end of file

Modified: grc/trunk/src/ExecFlowGraphGUI.py
===================================================================
--- grc/trunk/src/ExecFlowGraphGUI.py   2007-06-29 17:29:46 UTC (rev 5877)
+++ grc/trunk/src/ExecFlowGraphGUI.py   2007-06-29 17:41:26 UTC (rev 5878)
@@ -17,28 +17,31 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       ExecFlowGraphGUI.py 
-       Josh Blum       
-       Use a xml input file to build and run a gnu radio flow graph with wx 
GUI elements.
-"""
address@hidden ExecFlowGraphGUI 
+#Use an xml input file to build and run a gnu radio flow graph with wx GUI 
elements.
address@hidden Josh Blum
 
 import Variables
-from ExecFlowGraph import FlowGraphBuilder
+from ExecFlowGraph import FlowGraphBuilder,FlowGraphOptionParser
 import wx
 import os
 from Constants import *
 import math
-from optparse import OptionParser
 
 
##############################################################################################
 #      Variable Control
 
##############################################################################################
 class VariableControl(wx.BoxSizer):
-       """ House a Slider and a Text Box for variable control. """
+       """House a Slider and a Text Box for variable control."""
        def __init__(self, parent, key, parse_callbacks):
-               """ Create the slider, text box, and label given the variable 
key.
-                       parse_callbacks is a method to update the registered 
signal block callback methods.     """
+               """!
+               VariableControl contructor.
+               Create the slider, text box, and label given the variable key.
+               parse_callbacks is a method to update the registered signal 
block callback methods.
+               @param parent the wx parent window
+               @param key the variable key
+               @param parse_callbacksa the callback function for variables
+               """
                self.key = key
                self.parse_callbacks = parse_callbacks
                value, min, max, step = Variables.get_values(key)
@@ -46,7 +49,7 @@
                label_text_sizer = wx.BoxSizer(wx.HORIZONTAL) #label and text 
box container 
                label = wx.StaticText(parent, -1, key+' -> ')
                self.text_box = text_box = wx.TextCtrl(parent, -1, value, 
style=wx.TE_PROCESS_ENTER)
-               text_box.Bind(wx.EVT_TEXT_ENTER, self.handle_enter)     #bind 
this special enter hotkey event
+               text_box.Bind(wx.EVT_TEXT_ENTER, self._handle_enter)    #bind 
this special enter hotkey event
                for obj in (label, text_box):   #fill the container with label 
and text entry box
                        label_text_sizer.Add(obj, 0, 
wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL)
                self.Add(label_text_sizer, 0, wx.ALIGN_CENTER)
@@ -64,69 +67,74 @@
                except Exception, e:
                        sys.stderr.write('Slider, "%s", has too many 
steps!\n'%key)
                        sys.exit(1)
-               slider.Bind(wx.EVT_SCROLL, self.handle_scroll)  #bind the 
scrolling event               
+               slider.Bind(wx.EVT_SCROLL, self._handle_scroll) #bind the 
scrolling event               
                self.Add(slider, 0, wx.ALIGN_CENTER)
-               self.handle_enter()#sets the slider's value
+               self._set_slider_value(value)#sets the slider's value
        
        def get_slider_width(self):
-               """ Get the width of the slider in pixels.      """
+               """!
+               Get the width of the slider.
+               @return the slider width in pixels
+               """
                return self.slider_width
                
-       def get_slider_value(self):
-               """ Read the value from the slider slider. 
-               Translate the slider value into a real numerical value. """
+       def _get_slider_value(self):
+               """!
+               Read the value from the slider and,  
+               translate the slider value into a real numerical value.
+               @return the numeric representation of the slider
+               """
                slider_value = self.slider.GetValue()           
                value, min, max, step = Variables.get_values(self.key)          
                return str(slider_value*(float(max)-float(min))/self.num_steps 
+ float(min))
                
-       def set_slider_value(self, real_value):
-               """ Translate the real numerical value into a slider value. 
-               Write the value to the slider. """      
+       def _set_slider_value(self, real_value):
+               """!
+               Translate the real numerical value into a slider value and,  
+               write the value to the slider.
+               @param real_value the numeric value the slider should represent
+               """     
                value, min, max, step = Variables.get_values(self.key)          
                slider_value = 
(float(real_value)-float(min))*self.num_steps/(float(max)-float(min))
                self.slider.SetValue(slider_value)
        
-       def handle_scroll(self, event=None):
-               """ A scroll event is detected. Read the slider. Try to 
register the new entry:
+       def _handle_scroll(self, event=None):
+               """A scroll event is detected. Read the slider. Try to register 
the new entry:
                If the registration passes, update the text box, and parse the 
callbacks.
-               If the registration fails, restore the slider to the previous 
registered values. """
+               If the registration fails, restore the slider to the previous 
registered values. """            
                key = self.key          
-               new_value = str(self.get_slider_value())        #the new value 
must be a string!
-               value, min, max, step = Variables.get_values(key)               
-               Variables.unregister(key)
+               new_value = str(self._get_slider_value())       #the new value 
must be a string!
                try:
-                       Variables.register(key, new_value, min, max, step)
-                       self.text_box.SetValue(str(new_value))
-                       self.parse_callbacks()
-               except: 
-                       Variables.register(key, value, min, max, step)
-                       self.set_slider_value(value)            
+                       if Variables.reregister(key, new_value): 
self.parse_callbacks()
+               except Exception, e: print 'Error in handle scroll: "%s".'%e 
+               self._set_slider_value(Variables.get_value(key))
+               self.text_box.SetValue(Variables.get_value(key))
                
-       def handle_enter(self, event=None):
-               """ An enter key was pressed. Read the text box. Try to 
register the new entry: 
-                If the registration passes, move the slider, and parse the 
callbacks.  
-                If the registration fails, restore the text box to the 
previous registered value.      """
+       def _handle_enter(self, event=None):
+               """An enter key was pressed. Read the text box. Try to register 
the new entry: 
+               If the registration passes, move the slider, and parse the 
callbacks.   
+               If the registration fails, restore the text box to the previous 
registered value."""    
                key = self.key
                new_value = str(self.text_box.GetValue())       #the new value 
must be a string!        
-               value, min, max, step = Variables.get_values(key)
-               Variables.unregister(key)
                try:
-                       Variables.register(key, new_value, min, max, step)
-                       self.set_slider_value(new_value)                        
                
-                       self.parse_callbacks()
-               except: 
-                       Variables.register(key, value, min, max, step)          
                
-                       self.text_box.SetValue(value)                   
+                       if Variables.reregister(key, new_value): 
self.parse_callbacks()
+               except Exception, e: print 'Error in handle enter: "%s".'%e 
+               self._set_slider_value(Variables.get_value(key))
+               self.text_box.SetValue(Variables.get_value(key))
 
 
##############################################################################################
 #      Flow Graph Frame
 
##############################################################################################
 
 class FlowGraphFrame(wx.Frame, FlowGraphBuilder):
-       """ A FlowGraphFrame is a wx.Frame and a FlowGraphBuilder. 
+       """A FlowGraphFrame is a wx.Frame and a FlowGraphBuilder. 
        This flow graph frame parses a saved flow graph file,
        houses all the sliders and graphical sinks, 
-       and starts the flow graph.      """
+       and starts the flow graph."""
        def __init__(self, file_path):
+               """!
+               FlowGraphFrame contructor.
+               @param file_path the file path to the flow graph
+               """
                file_path = os.path.abspath(file_path)
                wx.Frame.__init__(self, None , -1, MAIN_WINDOW_PREFIX+' - 
Executing: '+file_path)
                if WX_APP_ICON: self.SetIcon(wx.Icon(WX_APP_ICON, 
wx.BITMAP_TYPE_ANY))
@@ -142,35 +150,44 @@
                self.sliders_box = wx.BoxSizer(wx.VERTICAL)
                main_box.Add(self.sliders_box, 0, wx.ALIGN_CENTER)
                main_box.Add(panel, 0, wx.EXPAND)               
-               self.Bind(wx.EVT_CLOSE, self.Quit)
+               self.Bind(wx.EVT_CLOSE, self._quit)
                #       fill in all the sliders and graphs      #               
                FlowGraphBuilder.__init__(self, file_path)              
-               self.create_sliders()
+               self._create_sliders()
                graphs_box.SetCols(int(math.sqrt(len(self.sink_windows))))
                for key in sorted(self.sink_windows.keys()): 
graphs_box.Add(self.sink_windows[key], 0, wx.EXPAND)               
                self.SetSizerAndFit(main_box)
                self.Show()     
                self.start() #start the flow graph      
                        
-       def Quit(self, event):
-               '''     Exit the application.   '''
+       def _quit(self, event):
+               """Exit the application."""
                self.stop()     #stop the flow graph
                self.Destroy() #destroy the wx frame
                sys.exit(0)
                
        def add_window(self, window, type='', title=''):
-               ''' Register the scope/fft window with a unique key.    '''
+               """!
+               Register the graphical sink window with a unique key.
+               The key is based on the type and title.
+               @param window the new gui window
+               @param type an integer used to categorize the window
+               @param title the title of the window
+               """
                key = str(type) + str(title)
                while self.sink_windows.has_key(key): key = key + '_'   
                self.sink_windows[key] = window         
                
        def get_panel(self):
-               ''' Get the panel that will parent the graphical blocks.        
''' 
+               """!
+               Get the panel that will parent the graphical blocks.
+               @return the wx panel
+               """ 
                return self.panel
                
-       def create_sliders(self):
-               ''' Using the list of variable keys imported by the builder, 
-                       create sliders for those variables with ranges. '''     
+       def _create_sliders(self):
+               """Using the list of variable keys imported by the builder, 
+               create sliders for those variables with ranges."""      
                len = 0         
                for key in self.var_keys:
                        value, min, max, step = Variables.get_values(key)
@@ -189,33 +206,38 @@
 #      Flow Graph App
 
##############################################################################################
 class FlowGraphApp(wx.App):
-       """     The FlowGraphApp is the wx.App containing the FlowGraphFrame.   
"""
+       """The FlowGraphApp is the wx.App containing the FlowGraphFrame."""
        def __init__(self, flow_graph_file_path):
+               """!
+               FlowGraphApp constructor.
+               @param flow_graph_file_path the file path to the flow graph
+               """
                self.flow_graph_file_path = flow_graph_file_path
                wx.App.__init__(self, 0)        
                        
        def OnInit(self):
-               """ If the creation of the frame fails, return False so the 
program will exit.  """
+               """!
+               Create the top level flow graph frame.
+               If the creation of the frame fails, exit with error.
+               @return true if the flow graph frame is created
+               """
                try:
                        
self.SetTopWindow(FlowGraphFrame(self.flow_graph_file_path))#first argument is 
the flow graph
                        return True
-               except Exception, e:
-                       sys.stderr.write(str(e)+'\n')
+               except Exception:
+                       import traceback
+                       traceback.print_exc()
                        sys.exit(1)
-
+                       
+##############################################################################################
+#      Main
+##############################################################################################
 
 if __name__ == '__main__':     
-       usage = "usage: %prog [-p] flow_graph"+DEFAULT_FILE_EXTENSION
-       parser = OptionParser(usage=usage)
-       parser.add_option("-p", "--pid_file", action="store", type="string", 
dest="pid_file", help="record process id")
+       parser = FlowGraphOptionParser()
        parser.add_option("-d", "--disable-wx", action="store_true", 
dest="no_wx", default=False, help="disable the wx gui")
        (options, args) = parser.parse_args()
-       if options.pid_file:
-               try: open(options.pid_file, 'w').write('%d\n' % os.getpid())
-               except: print "could not create pid file: %s"%options.pid_file
-       if len(args): #only create the wx app if a flow graph was passed
-               app = FlowGraphApp(args[0])
-               if options.no_wx: raw_input('Flow Graph Running...\nPress Enter 
to Exit: ')     #do not start wx
-               else: app.MainLoop()    #start the wxApp MainLoop
-       else: parser.print_help()       
+       app = FlowGraphApp(args[0])
+       if options.no_wx: raw_input('Flow Graph Running...\nPress Enter to 
Exit: ')     #do not start wx
+       else: app.MainLoop()    #start the wxApp MainLoop               
                
                
\ No newline at end of file

Copied: grc/trunk/src/ExecFlowGraphXMLRPC.py (from rev 5877, 
grc/branches/jblum_work/src/ExecFlowGraphXMLRPC.py)
===================================================================
--- grc/trunk/src/ExecFlowGraphXMLRPC.py                                (rev 0)
+++ grc/trunk/src/ExecFlowGraphXMLRPC.py        2007-06-29 17:41:26 UTC (rev 
5878)
@@ -0,0 +1,93 @@
+#! /usr/bin/env python
+"""
+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 ExecFlowGraphXMLRPC 
+#Use a xml input file to build and run a gnu radio flow graph without graphics.
+#Create an XMLRPC sever to control the running flow graph.
address@hidden @n XMLRPC access functions:
address@hidden var_has_range(key): returns true if the variable represented by 
key has a range @n
address@hidden var_exists(key): returns true if the variable represented by key 
exists @n
address@hidden get_var_key_list(): returns a list of keys representing all 
registered variables @n
address@hidden get_var(key): returns the value of the variable represented by 
key @n
address@hidden get_var_range(key): returns the (min,max) of the variable 
represented by key @n
address@hidden set_var(key, new_value): sets the new value of the variable 
represented by key @n
address@hidden start_fg(): starts the flow graph @n
address@hidden stop_fg(): stops the flow graph @n
+#
address@hidden Josh Blum
+
+from SimpleXMLRPCServer import SimpleXMLRPCServer
+from xmlrpclib import Error
+from ExecFlowGraph import FlowGraphBuilder,FlowGraphOptionParser
+import Variables               
+
+DEFAULT_ADDR = 'localhost'
+DEFAULT_PORT = 3030
+
+##############################################################################################
+#      Flow Graph Access
+##############################################################################################
 
+class FlowGraphAccess(FlowGraphBuilder):                       
+       """Implement a flow graph builder, and provide access functions for the 
xmlrpc server."""
+               
+       def get_var_range(self, key):
+               """!
+               Get the min and the max of a variable (strings).
+               @return the min,max tuple 
+               """             
+               value, min, max, step = Variables.get_values(key)       
+               return str(min), str(max)               
+               
+       def set_var(self, key, new_value):
+               """!
+               Register the new value and call parse callbacks.
+               Value can be any type (will be cast to a string).
+               @param key the variable key
+               @param new_value the new value for the variable         
+               @return the new value as a string or the old value if failed
+               """             
+               try: 
+                       if Variables.reregister(key, str(new_value)): 
self.parse_callbacks()
+               except: pass
+               return Variables.get_value(key)
+                       
+##############################################################################################
+#      Main
+##############################################################################################
 
+if __name__ == '__main__':     
+       parser = FlowGraphOptionParser()
+       parser.add_option("-a", "--addr", action="store", type="string", 
dest="addr", default=DEFAULT_ADDR, help='bind address for XMLRPC server')
+       parser.add_option("-P", "--port", action="store", type="int", 
dest="port", default=DEFAULT_PORT, help='tcp port for XMLRPC server')
+       (options, args) = parser.parse_args()
+       fg = FlowGraphAccess(args[0])   #create the flow graph  
+       server = SimpleXMLRPCServer((options.addr, options.port))       #create 
the xmlrpc server
+       # register access methods #
+       server.register_function(lambda key: bool(Variables.is_ranged(key)), 
"var_has_range")
+       server.register_function(lambda key: bool(Variables.has_key(key)), 
"var_exists")
+       server.register_function(lambda: fg.var_keys, "get_var_key_list")
+       server.register_function(lambda key: str(Variables.get_value(key)), 
"get_var")
+       server.register_function(fg.get_var_range, "get_var_range")
+       server.register_function(fg.set_var, "set_var")
+       server.register_function(fg.start, "start_fg")
+       server.register_function(fg.stop, "stop_fg")            
+       fg.start()      #start the flow graph 
+       print 'Starting XMLRPC server on address: "%s" and port: 
"%d"'%(options.addr, options.port)
+       server.serve_forever()  #start the xmlrpc server        
+       
+       
\ No newline at end of file


Property changes on: grc/trunk/src/Graphics
___________________________________________________________________
Name: svn:ignore
   - *.pyc


Modified: grc/trunk/src/Graphics/Bars.py
===================================================================
--- grc/trunk/src/Graphics/Bars.py      2007-06-29 17:29:46 UTC (rev 5877)
+++ grc/trunk/src/Graphics/Bars.py      2007-06-29 17:41:26 UTC (rev 5878)
@@ -16,18 +16,17 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       Graphics/Bars.py 
-       Josh Blum
-       this file will create the GUI's toolbar and menubar
-"""
address@hidden Graphics.Bars
+#Create the GUI's toolbar and menubar
address@hidden Josh Blum
 
 from Actions import *
 import pygtk
 pygtk.require('2.0')
 import gtk
                                        
-TOOLBAR_LIST = [
+##The list of actions for the toolbar.
+TOOLBAR_LIST = (
        FLOW_GRAPH_NEW,
        FLOW_GRAPH_OPEN,
        FLOW_GRAPH_SAVE,
@@ -43,9 +42,10 @@
        ELEMENT_DELETE,
        SIGNAL_BLOCK_ROTATE_LEFT,
        SIGNAL_BLOCK_ROTATE_RIGHT,                                              
-]
-                                       
-MENU_BAR_LIST = [
+)
+
+##The list of actions and categories for the menu bar.                         
        
+MENU_BAR_LIST = (
        (gtk.Action('File', '_File', None, None), [
                FLOW_GRAPH_NEW,
                FLOW_GRAPH_OPEN,
@@ -80,15 +80,14 @@
                HOTKEYS_WINDOW_DISPLAY,
                MATH_EXPR_WINDOW_DISPLAY,
                USRP_DIAGNOSTICS_DISPLAY,
-       ])
-                                                                               
                
-]
+       ]),                                                                     
                        
+)
 
 class Toolbar(gtk.Toolbar):
-       """     Toolbar is a gtk Toolbar with actions added from the toolbar 
list       """     
+       """The gtk toolbar with actions added from the toolbar list.""" 
        def __init__(self):
-               """     Parse the list of action names in the toolbar list. 
Look up the action for each name
-               in the action list and add it to the toolbar    """     
+               """Parse the list of action names in the toolbar list. 
+               Look up the action for each name        in the action list and 
add it to the toolbar."""        
                gtk.Toolbar.__init__(self)              
                self.set_style(gtk.TOOLBAR_ICONS) 
                for action_name in TOOLBAR_LIST:
@@ -104,11 +103,10 @@
                        
        
 class MenuBar(gtk.MenuBar):
-       """     MenuBar is a gtk MenuBar with actions added from the menuBar 
list       """                             
+       """The gtk menu bar with actions added from the menu bar list."""       
                        
        def __init__(self):
-               """     Parse the list of submenus from the menubar list. For 
each submenu, get a list of action names.
-               Look up the action for each name in the action list and add it 
to the submenu.
-               Add the submenu to the menuBar  """
+               """Parse the list of submenus from the menubar list. For each 
submenu, get a list of action names.
+               Look up the action for each name in the action list and add it 
to the submenu. Add the submenu to the menu bar."""
                gtk.MenuBar.__init__(self)
                for main_action,action_names in MENU_BAR_LIST:
                        # Create the MenuItem

Modified: grc/trunk/src/Graphics/Dialogs.py
===================================================================
--- grc/trunk/src/Graphics/Dialogs.py   2007-06-29 17:29:46 UTC (rev 5877)
+++ grc/trunk/src/Graphics/Dialogs.py   2007-06-29 17:41:26 UTC (rev 5878)
@@ -16,25 +16,26 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       Graphics/Dialogs.py 
-       Josh Blum
-       Misc Dialogs
-"""
address@hidden Graphics.Dialogs
+#Misc dialogs.
address@hidden Josh Blum
 
 import Colors
 import pygtk
 pygtk.require('2.0')
 import gtk
-from DataType import *
+from DataTypes import *
 from Constants import *
 from Elements import GraphicalParam
 import Preferences
 
 class TextDisplay(gtk.TextView):
-       """ A non editable gtk text view.       """
+       """A non editable gtk text view."""
        def __init__(self, text=''):
-               """ Create a new TextDisplay with the given text.       """
+               """!
+               TextDisplay constructor.
+               @param text the text to display (string)
+               """
                text_buffer = gtk.TextBuffer()
                text_buffer.set_text(text)      
                self.set_text = text_buffer.set_text            
@@ -42,23 +43,21 @@
                gtk.TextView.__init__(self, text_buffer)
                self.set_editable(False)
                self.set_cursor_visible(False)
-               self.set_wrap_mode(gtk.WRAP_WORD)       
-               self.show()
+               self.set_wrap_mode(gtk.WRAP_WORD)
 
 
######################################################################################################
 class PreferencesDialog(gtk.Dialog):
-       """     A dialog box to display each preference parameter.      """
+       """A dialog box to display the preferences."""
        def __init__(self):
+               """PreferencesDialog constructor."""
                gtk.Dialog.__init__(self, buttons=('gtk-close', 
gtk.RESPONSE_CLOSE))
                self.set_title("Preferences")   
                self.set_size_request(MIN_DIALOG_WIDTH, MIN_DIALOG_HEIGHT)
                vbox = gtk.VBox()
-               vbox.show()
                for title,notes,params in Preferences.PREFS_LIST:               
        
                        if title:                               
                                label = gtk.Label()
-                               label.set_markup('<b> ----- '+title+' ----- 
</b>')                      
-                               label.show()
+                               label.set_markup('<b> ----- '+title+' ----- 
</b>')      
                                vbox.pack_start(label, False, padding=5)        
        
                                for param in params: 
vbox.pack_start(param.get_input_object(), False)           
                                if notes: vbox.pack_start(TextDisplay(notes), 
False, padding=5)         
@@ -66,36 +65,40 @@
                scrolled_window = gtk.ScrolledWindow()
                scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, 
gtk.POLICY_AUTOMATIC)
                scrolled_window.add_with_viewport(vbox)
-               scrolled_window.show()          
                self.vbox.pack_start(scrolled_window, True)
+               self.show_all()
                self.run()
                self.destroy()
 
 
######################################################################################################
 class FlowGraphWindowSizeDialog(gtk.Dialog):
-       """     A dialog box to set the window size, width and heigh in pixels. 
"""
-       def __init__(self, flow_graph):
+       """A dialog box to set the window size, width and heigh in pixels."""
+       def __init__(self, dimensions):
+               """!
+               FlowGraphWindowSizeDialog constructor.
+               @param dimensions the (width,height) tuple from the flow graph
+               """
                gtk.Dialog.__init__(self, buttons=('gtk-close', 
gtk.RESPONSE_CLOSE))
-               self.flow_graph = flow_graph
                self.set_title("Set the Window Size")           
                #       the helpful dimension constraints label #
-               windowSizeDesc = '''
+               window_size_label = gtk.Label()
+               window_size_label.set_markup("""<i>
 Minimum window (width/height) in pixels is (%d/%d).
 Maximum window (width/height) in pixels is (%d/%d).
-'''%(MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT, MAX_WINDOW_WIDTH, MAX_WINDOW_HEIGHT)
-               windowSizeDescLabel = gtk.Label()
-               windowSizeDescLabel.set_markup('<i>'+windowSizeDesc+'</i>')
-               windowSizeDescLabel.show()
-               self.vbox.pack_end(windowSizeDescLabel, False)                  
                
-               self.original_dimensions = width,height = 
self.flow_graph.get_size_request()    # get the window dimensions             
+</i>"""%(MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT, MAX_WINDOW_WIDTH, 
MAX_WINDOW_HEIGHT))
+               self.vbox.pack_end(window_size_label, False)                    
                
+               self.original_dimensions = width,height = dimensions    
                self.width = Int(width, min=MIN_WINDOW_WIDTH, 
max=MAX_WINDOW_WIDTH)
                self.height = Int(height, min=MIN_WINDOW_HEIGHT, 
max=MAX_WINDOW_HEIGHT)
                self.vbox.pack_start(GraphicalParam('width (pixels)', 
self.width).get_input_object(), False)
                self.vbox.pack_start(GraphicalParam('height (pixels)', 
self.height).get_input_object(), False)  
+               self.show_all()
                
        def run(self):
-               ''' Return the new dimensions rather than a response.
-                       If the dimensions were invalid, return None.    '''
+               """!
+               Get the new dimensions.
+               @return the new dimensions (width,height) or None if invalid.
+               """
                self.dimensions = None                  
                gtk.Dialog.run(self)
                if self.width.is_valid() and self.height.is_valid():
@@ -106,14 +109,18 @@
 
 
######################################################################################################
 class LooseChangesMessage(gtk.MessageDialog):
-       """     This message dialog will ask about discarding unsaved changes.  
"""
+       """Message dialog to ask about discarding unsaved changes."""
        def __init__(self):
+               """LooseChangesMessage constructor."""
                gtk.MessageDialog.__init__(self, None, gtk.DIALOG_MODAL, 
gtk.MESSAGE_WARNING, 
                        gtk.BUTTONS_OK_CANCEL, "Would you like to discard your 
unsaved changes?")
                self.set_title('Unsaved Changes!')      
        
        def run(self):
-               """     call parent class run(), destroy the dialog. Return 
True if OK was clicked, or False.   """     
+               """!
+               Get the user's response.
+               @return true if ok was clicked, otherwise false
+               """     
                response = gtk.MessageDialog.run(self)
                self.destroy()
                if response == gtk.RESPONSE_OK: return True
@@ -121,8 +128,9 @@
                
 
######################################################################################################
 class AboutDialog(gtk.AboutDialog):
-       """     cute little about dialog        """
+       """A cute little about dialog."""
        def __init__(self):
+               """AboutDialog constructor."""
                gtk.AboutDialog.__init__(self)
                self.set_version(VERSION)
                self.set_name(MAIN_WINDOW_PREFIX)       
@@ -146,62 +154,77 @@
                                        
 
######################################################################################################
                 
 class DataTypeColorsDialog(gtk.Dialog):
-       """ Display each data type with its associated color.   """
+       """Display each data type with its associated color."""
        def __init__(self):
+               """DataTypeColorsDialog constructor."""
                gtk.Dialog.__init__(self, buttons=('gtk-close', 
gtk.RESPONSE_CLOSE))
                self.set_title('Colors')
                self.set_size_request(150, -1)
-               for dt_name, color in (('Complex', Colors.COMPLEX_COLOR_SPEC),
-                                                                               
('Float', Colors.FLOAT_COLOR_SPEC),
-                                                                               
('Int', Colors.INT_COLOR_SPEC),
-                                                                               
('Short', Colors.SHORT_COLOR_SPEC),                                             
                                
-                                                                               
('Byte', Colors.BYTE_COLOR_SPEC),
-                                                                               
#       and for the vectors     #
-                                                                               
('Complex Vector', Colors.COMPLEX_VECTOR_COLOR_SPEC),
-                                                                               
('Float Vector', Colors.FLOAT_VECTOR_COLOR_SPEC),
-                                                                               
('Int Vector', Colors.INT_VECTOR_COLOR_SPEC),
-                                                                               
('Short Vector', Colors.SHORT_VECTOR_COLOR_SPEC),                               
                                                
-                                                                               
('Byte Vector', Colors.BYTE_VECTOR_COLOR_SPEC),):
-                       label = gtk.Label('')
-                       label.set_markup('<span 
background="%s">%s</span>'%(color, dt_name))
-                       label.show()
-                       self.vbox.pack_start(label)
+               markup = ''
+               for color_spec in (
+                       'Regular Types:',
+                       ('Complex', Colors.COMPLEX_COLOR_SPEC),
+                       ('Float', Colors.FLOAT_COLOR_SPEC),
+                       ('Int', Colors.INT_COLOR_SPEC),
+                       ('Short', Colors.SHORT_COLOR_SPEC),                     
                                                        
+                       ('Byte', Colors.BYTE_COLOR_SPEC),
+                       'Vector Types:',
+                       ('Complex Vector', Colors.COMPLEX_VECTOR_COLOR_SPEC),
+                       ('Float Vector', Colors.FLOAT_VECTOR_COLOR_SPEC),
+                       ('Int Vector', Colors.INT_VECTOR_COLOR_SPEC),
+                       ('Short Vector', Colors.SHORT_VECTOR_COLOR_SPEC),       
                                                                        
+                       ('Byte Vector', Colors.BYTE_VECTOR_COLOR_SPEC),
+               ):
+                       width = 20 #width in monospace characters
+                       if type(color_spec) == type(str()): markup = 
'%s\n\n<b>%s</b>'%(markup, color_spec.center(width, ' '))
+                       else:   
+                               tag,spec = color_spec                           
        
+                               markup = '%s\n<span 
background="%s">%s</span>'%(markup, spec, tag.center(width, ' '))
+               label = gtk.Label()
+               label.set_markup('<tt>%s</tt>\n'%markup[1:])    #strip 1st 
newline, append newline
+               self.vbox.pack_start(label, False)
+               self.show_all()
                self.run()
                self.destroy()                  
                        
 
######################################################################################################
                 
 class HotKeysDialog(gtk.Dialog):
-       """ Display each action with the associated hotkey.     """
+       """Display each action with the associated hotkey."""
        def __init__(self):
+               """HotKeysDialog constructor."""
                gtk.Dialog.__init__(self, buttons=('gtk-close', 
gtk.RESPONSE_CLOSE))
                self.set_title('Hot Keys')
-               for action, hotkey in (('New Flow Graph', 'Ctrl + n'),
-                                                                               
('Open Flow Graph', 'Ctrl + o'),
-                                                                               
('Save Flow Graph', 'Ctrl + s'),
-                                                                               
('Undo Change', 'Ctrl + z'),
-                                                                               
('Redo Change', 'Ctrl + y'),
-                                                                               
('Redo Change', 'Ctrl + Z'),
-                                                                               
('Delete Block', 'Delete'),
-                                                                               
('Rotate Block', 'Right'),
-                                                                               
('Rotate Block', 'Left'),
-                                                                               
('Modify Data Type', 'Up'),
-                                                                               
('Modify Data Type', 'Down'),
-                                                                               
('Add a Socket', '+'),
-                                                                               
('Remove a Socket', '-'),
-                                                                               
('Close GraphicalParams Dialog', 'Esc'),
-                                                                               
('Flow Graph Run', 'F5'),
-                                                                               
('Flow Graph Stop', 'F7'),
-                                                                               
('Screen Shot', 'PrintScreen'),):
-                       label = gtk.Label('')
-                       label.set_markup('<b>%s:</b> %s'%(action, hotkey))
-                       label.show()
-                       self.vbox.pack_start(label)
+               markup = ''
+               for action, hotkey in (
+                       ('New Flow Graph', 'Ctrl + n'),
+                       ('Open Flow Graph', 'Ctrl + o'),
+                       ('Save Flow Graph', 'Ctrl + s'),
+                       ('Undo Change', 'Ctrl + z'),
+                       ('Redo Change', 'Ctrl + y'),
+                       ('Redo Change', 'Ctrl + Z'),
+                       ('Delete Block', 'Delete'),
+                       ('Rotate Block', 'Right'),
+                       ('Rotate Block', 'Left'),
+                       ('Modify Data Type', 'Up'),
+                       ('Modify Data Type', 'Down'),
+                       ('Add a Socket', '+'),
+                       ('Remove a Socket', '-'),
+                       ('Close Dialog', 'Esc'),
+                       ('Flow Graph Run', 'F5'),
+                       ('Flow Graph Stop', 'F7'),
+                       ('Screen Shot', 'PrintScreen'),
+               ): markup = '%s\n<b>%s:</b>%s'%(markup, action, 
hotkey.rjust(25-len(action),' '))
+               label = gtk.Label()
+               label.set_markup('<tt>%s</tt>\n'%markup)        #append newline
+               self.vbox.pack_start(label, False)
+               self.show_all()
                self.run()
                self.destroy()          
                
 
######################################################################################################
                 
 class MathExprDialog(gtk.Dialog):
-       """ A dialog to test math expressions for the parser.   """
+       """A dialog to test math expressions for the parser."""
+       ##the help message
        HELP_MSG = """\
 <b>Operators - Complex   <i>(complex arguments)</i></b> 
        + - * / ^       
@@ -233,39 +256,31 @@
 <b>Test Your Expressions Below:</b>\
 """
        def __init__(self):
-               """     Create a new gtk Dialog with a close button, an extry 
box, and an output text box.      """             
+               """MathExprDialog constrcutor. Create a new gtk Dialog with a 
close button, an extry box, and an output text box."""            
                gtk.Dialog.__init__(self, buttons=('gtk-close', 
gtk.RESPONSE_CLOSE))
                #       Create the title and label      #
                self.set_title('Mathematical Expressions')
                label = gtk.Label()
                label.set_markup(self.HELP_MSG)
-               label.show()
                self.vbox.pack_start(label, False)              
                self.set_size_request(800, 600)
-               # create the entry box and connect it to a new handler #
-               self.param = GraphicalParam('Expression', RawExpr(''))
-               self.input_obj = self.param.get_input_object()
-               self.input_obj.entry.connect("changed", self.handle_changed)
-               self.vbox.pack_start(self.input_obj, False)             
                #       create a text box for parser output     #
                self.text_box = TextDisplay()
                self.text_box.set_text('')                      
+               # create the entry box and give it the change handler #
+               self.param = GraphicalParam('Expression', RawExpr(''))
+               self.input_obj = 
self.param.get_input_object(self._handle_changed)
+               self.vbox.pack_start(self.input_obj, False)                     
                # add the scrolled window for the text box #
                scrolled_window = gtk.ScrolledWindow()
                scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, 
gtk.POLICY_AUTOMATIC)
                scrolled_window.add_with_viewport(self.text_box)
-               scrolled_window.show()          
                self.vbox.pack_start(scrolled_window, True)     
-               self.handle_changed()   #initial display
+               self.show_all()
                self.run()
                self.destroy()
                
-       def handle_changed(self, widget=None):
-               ''' Handle changed in the param's entry box.
-                       Call the default change handler and then update the 
text box.   '''
-               self.param.handle_changed()
-               if self.param.get_data_type().is_valid():
-                       text = str(self.param.get_data_type().parse())
-               else: text = self.param.get_data_type().msg
-               self.text_box.set_text(text)    
+       def _handle_changed(self, param=None):
+               """Handle changed in the param's entry box by updating the text 
box."""
+               self.text_box.set_text(str(self.param.get_data_type())) 
                
\ No newline at end of file

Copied: grc/trunk/src/Graphics/FileDialogs.py (from rev 5877, 
grc/branches/jblum_work/src/Graphics/FileDialogs.py)
===================================================================
--- grc/trunk/src/Graphics/FileDialogs.py                               (rev 0)
+++ grc/trunk/src/Graphics/FileDialogs.py       2007-06-29 17:41:26 UTC (rev 
5878)
@@ -0,0 +1,107 @@
+"""
+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 Graphics.FileDialogs
+#The open/save dialog for flow graph fFileDialogiles and screen shots.
address@hidden Josh Blum
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+from Constants import 
DEFAULT_FILE_PATH,FLOW_GRAPH_FILE_EXTENSION,IMAGE_FILE_EXTENSION,NEW_FLOGRAPH_TITLE
+from os import path
+
+OPEN_FLOW_GRAPH = 'open flow graph'
+SAVE_FLOW_GRAPH = 'save flow graph'
+SAVE_IMAGE = 'save image'
+
+class FileDialog(gtk.FileChooserDialog):
+       """A dialog box to save or open flow graph files. This is a base class, 
do not use."""
+       
+       ##the filter for flow graph files
+       flow_graph_files_filter = gtk.FileFilter()
+       flow_graph_files_filter.set_name('FG Files')
+       flow_graph_files_filter.add_pattern('*'+FLOW_GRAPH_FILE_EXTENSION)
+       
+       ##the filter for image files
+       image_files_filter = gtk.FileFilter()
+       image_files_filter.set_name('Image Files')
+       image_files_filter.add_pattern('*'+IMAGE_FILE_EXTENSION)
+       #image_files_filter.add_pixbuf_formats()
+       
+       ##the filter for all files
+       all_files_filter = gtk.FileFilter()
+       all_files_filter.set_name('All Files')
+       all_files_filter.add_pattern('*')       
+       
+       def __init__(self, current_file_path):
+               """!
+               FileDialog constructor.         
+               Create a new gtk.FileChooserDialog, type specifies what filter 
to use:
+               open and save are for flow graphs, save image is for 
screenshots.
+               @param current_file_path the current directory
+               """
+               if current_file_path == '': current_file_path = 
DEFAULT_FILE_PATH+NEW_FLOGRAPH_TITLE+FLOW_GRAPH_FILE_EXTENSION
+               if self.type == OPEN_FLOW_GRAPH:
+                       gtk.FileChooserDialog.__init__(self, 'Open a Flow Graph 
from a File...', None,
+                               gtk.FILE_CHOOSER_ACTION_OPEN, 
('gtk-cancel',gtk.RESPONSE_CANCEL,'gtk-open',gtk.RESPONSE_OK))
+                       self.add_filter(self.flow_graph_files_filter)
+                       self.set_filter(self.flow_graph_files_filter)
+                       self.add_filter(self.all_files_filter)
+               elif self.type == SAVE_FLOW_GRAPH:
+                       gtk.FileChooserDialog.__init__(self, 'Save a Flow Graph 
to a File...', None,
+                               gtk.FILE_CHOOSER_ACTION_SAVE, 
('gtk-cancel',gtk.RESPONSE_CANCEL, 'gtk-save',gtk.RESPONSE_OK))
+                       #self.set_do_overwrite_confirmation(True) #enable this 
when u get it working with auto-extension        
+                       self.add_filter(self.flow_graph_files_filter)
+                       self.set_filter(self.flow_graph_files_filter)
+                       self.add_filter(self.all_files_filter)  
+                       self.set_current_name(path.basename(current_file_path)) 
#show the current filename
+               elif self.type == SAVE_IMAGE:
+                       gtk.FileChooserDialog.__init__(self, 'Save a Flow Graph 
Screen Shot...', None,
+                               gtk.FILE_CHOOSER_ACTION_SAVE, 
('gtk-cancel',gtk.RESPONSE_CANCEL, 'gtk-save',gtk.RESPONSE_OK))
+                       #self.set_do_overwrite_confirmation(True) #enable this 
when u get it working with auto-extension        
+                       self.add_filter(self.image_files_filter)
+                       self.set_filter(self.image_files_filter)
+                       self.add_filter(self.all_files_filter)          
+                       current_file_path = current_file_path + 
IMAGE_FILE_EXTENSION    
+                       self.set_current_name(path.basename(current_file_path)) 
#show the current filename              
+               self.set_current_folder(path.dirname(current_file_path))        
#current directory 
+               #self.set_show_hidden(False)    #doesnt seem to work ;-)
+               self.set_select_multiple(False)
+               self.set_local_only(True)
+
+       def run(self):
+               """!
+               Call run, wait for user response, and destroy the dialog.
+               @return the filename or None if a close/cancel occured.
+               """             
+               response = gtk.FileChooserDialog.run(self)      
+               if response == gtk.RESPONSE_OK: 
+                       filename = self.get_filename()
+                       if 
filename[len(filename)-len(FLOW_GRAPH_FILE_EXTENSION):] != 
FLOW_GRAPH_FILE_EXTENSION and\
+                               self.flow_graph_files_filter == 
self.get_filter(): filename = filename + FLOW_GRAPH_FILE_EXTENSION
+                       elif filename[len(filename)-len(IMAGE_FILE_EXTENSION):] 
!= IMAGE_FILE_EXTENSION and\
+                               self.image_files_filter == self.get_filter(): 
filename = filename + IMAGE_FILE_EXTENSION
+               else: filename = None
+               self.destroy()
+               return filename 
+               
+class OpenFlowGraphFileDialog(FileDialog): type = OPEN_FLOW_GRAPH      
+class SaveFlowGraphFileDialog(FileDialog): type = SAVE_FLOW_GRAPH      
+class SaveImageFileDialog(FileDialog): type = SAVE_IMAGE       
+

Modified: grc/trunk/src/Graphics/FlowGraph.py
===================================================================
--- grc/trunk/src/Graphics/FlowGraph.py 2007-06-29 17:29:46 UTC (rev 5877)
+++ grc/trunk/src/Graphics/FlowGraph.py 2007-06-29 17:41:26 UTC (rev 5878)
@@ -16,18 +16,16 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-""" 
-       Graphics/FlowGraph.py   
-       Josh Blum
-       flow graph structure for storing signal blocks and their connections
-"""
address@hidden Graphics.FlowGraph
+#A flow graph structure for storing signal blocks and their connections.
address@hidden Josh Blum
 
 from Constants import *
 from Actions import *
 from Colors import BACKGROUND_COLOR, TXT_COLOR
 from Elements import GraphicalSignalBlock,GraphicalConnection
 from Elements import Utils
-from Elements.Connection import 
InvalidConnectionException,TooManyConnectionsException
+from Elements.Connection import ConnectionException
 import Variables
 import pygtk
 pygtk.require('2.0')
@@ -42,29 +40,34 @@
 import Messages
 
 class FlowGraph(gtk.DrawingArea):
-       """     FlowGraph is the data structure to store graphical signal 
blocks, their graphical input/output
-       parameters, and the connections between inputs and outputs.     """     
        
+       """FlowGraph is the data structure to store graphical signal blocks, 
+       their graphical input/output parameters, and the connections between 
inputs and outputs."""             
        signal_block_constructor = GraphicalSignalBlock
        connection_contructor = GraphicalConnection     
        def __init__(self, handle_states, variable_modification_window):
-               """ Create a list for signal blocks and connections. Connect 
mouse handlers.    """     
+               """!
+               FlowGraph contructor.
+               Create a list for signal blocks and connections. Connect mouse 
handlers.
+               @param handle_states the callback function
+               @param variable_modification_window var mod window also for 
callbacks
+               """     
                self.elements = list()
                self.remove_element = lambda e: self.elements.remove(e)
                self.gc = None
                self.handle_states = handle_states
                self.variable_modification_window = variable_modification_window
                gtk.DrawingArea.__init__(self)
-               self.connect('expose-event', self.__on_expose)
-               self.connect('motion-notify-event', 
self.__motion_notify_event_cb)
-               self.connect('button-press-event', 
self.__button_press_event_cb)  
-               self.connect('button-release-event', 
self.__button_release_event_cb)            
+               self.connect('expose-event', self._handle_window_expose)
+               self.connect('motion-notify-event', self._handle_mouse_motion)
+               self.connect('button-press-event', 
self._handle_mouse_button_press)  
+               self.connect('button-release-event', 
self._handle_mouse_button_release)         
                self.set_events(gtk.gdk.BUTTON_PRESS_MASK | 
gtk.gdk.POINTER_MOTION_MASK | gtk.gdk.BUTTON_RELEASE_MASK\
                 | gtk.gdk.LEAVE_NOTIFY_MASK | gtk.gdk.ENTER_NOTIFY_MASK)       
                #       setup the focus flag    #               
                self.focus_flag = False
                self.get_focus_flag = lambda: self.focus_flag           
-               self.connect("leave-notify-event", self.__handle_focus_event, 
False)
-               self.connect("enter-notify-event", self.__handle_focus_event, 
True)             
+               self.connect("leave-notify-event", self._handle_focus_event, 
False)
+               self.connect("enter-notify-event", self._handle_focus_event, 
True)              
                #       important vars dealing with mouse event tracking        
#       
                self.has_moved = False
                self.mouse_pressed = False
@@ -73,14 +76,16 @@
                self.is_selected = lambda: self.selected_element != None
                self.count = 0
                self.pixmap = None
-               self.show()
                
-       def __handle_focus_event(self, widget, event, focus_flag):
-               """ Record the focus state of the flow graph window.    """
+       def _handle_focus_event(self, widget, event, focus_flag):
+               """Record the focus state of the flow graph window."""
                self.focus_flag = focus_flag
                                
        def add_signal_block(self, tag):        
-               ''' Add a signal block of the given tag to this flow graph.     
'''
+               """!
+               Add a signal block of the given tag to this flow graph.
+               @param tag the signal block tag
+               """
                index = 0
                while True:
                        id = tag+str(index)
@@ -104,21 +109,30 @@
                                return          
        
        def type_controller_modify_selected(self, direction):
-               """ Change the registered type controller for the selected 
signal block.
-                       direction may be +1 or -1       """
+               """
+               !Change the registered type controller for the selected signal 
block.
+               @param direction +1 or -1
+               @return true for success
+               """
                if Utils.is_socket(self.selected_element): 
self.selected_element = self.selected_element.get_parent()
                if Utils.is_signal_block(self.selected_element): return 
self.selected_element.modify_type_controller(direction)
                return False
                
        def socket_controller_modify_selected(self, direction):
-               """ Change socket controller for the selected signal block.
-                       direction may be +1 or -1       """
+               """!
+               Change socket controller for the selected signal block.
+               @param direction +1 or -1
+               @return true for success
+               """
                if Utils.is_socket(self.selected_element): 
self.selected_element = self.selected_element.get_parent()
                if Utils.is_signal_block(self.selected_element): return 
self.selected_element.modify_socket_controller(direction)
                return False
 
        def param_modify_selected(self):
-               """ Create and show a param modification dialog for the 
selected element (socket and signal block only) """
+               """!
+               Create and show a param modification dialog for the selected 
element (socket and signal block only).
+               @return true if parameters were changed
+               """
                if Utils.is_socket(self.selected_element): 
self.selected_element = self.selected_element.get_parent()
                if Utils.is_signal_block(self.selected_element):
                        signal_block_params_dialog = 
SignalBlockParamsDialog(self.selected_element)
@@ -128,27 +142,37 @@
                return False    
                
        def connect_sockets(self, s1, s2):
-               """     Connect input and output sockets. Ignore state change 
if creation of connection fails.  """
+               """!
+               Connect input and output sockets. Ignore state change if 
creation of connection fails.
+               @param s1 a socket
+               @param s2 another socket
+               """
                try:            
                        connection = GraphicalConnection(self, s1, s2)
                        self.elements.append(connection)
                        self.selected_element = None
                        self.handle_states(CONNECTION_CREATE)   
                        self.update()   
-               except (InvalidConnectionException, 
TooManyConnectionsException), e: 
+               except ConnectionException: 
                        Messages.send_fail_connection() 
                        self.handle_states(NOTHING_SELECT)      
        
        def move_selected(self, delta_coordinate):
-               """     Move the element and by the change in coordinate 
(delta_coordinate)     """
+               """!
+               Move the element and by the change in coordinates.
+               @param delta_coordinate the change in coordinates
+               """
                if self.selected_element != None:                               
        
                        self.selected_element.move(delta_coordinate)    
                        self.has_moved = True   
                        self.draw()
                        
        def rotate_selected(self, direction):
-               """     Rotate the selected element by 90 degrees, direction 
can be "left"/"right"      
-                       True if rotated, otherwise False. Only rotate 
SignalBlocks and Sockets. """
+               """!
+               Rotate the selected element by 90 degrees. Only rotate 
SignalBlocks and Sockets.
+               @param direction DIR_LEFT or DIR_RIGHT
+               @return         true if rotated, otherwise false. 
+               """
                if self.selected_element != None and 
(Utils.is_signal_block(self.selected_element) or 
Utils.is_socket(self.selected_element)):                                  
                        self.selected_element.rotate(direction) 
                        self.draw()
@@ -156,8 +180,10 @@
                return False    
        
        def delete_selected(self):
-               """     If an element is selected, remove it and its attached 
parts from the element list.
-                       True if the element was deleted, otherwise False.       
"""
+               """!
+               If an element is selected, remove it and its attached parts 
from the element list.
+               @return true if the element was deleted, otherwise false.
+               """
                if self.selected_element != None:
                        if Utils.is_socket(self.selected_element):      # found 
a socket, set to parent signal block
                                self.selected_element = 
self.selected_element.get_parent()                                              
@@ -173,17 +199,22 @@
                return False
                
        def unselect(self):
-               """ If an element is selected, un-highlight it and set selected 
to None.        """
+               """If an element is selected, un-highlight it and set selected 
to None."""
                if self.selected_element != None: 
                        self.selected_element.set_highlighted(False)            
        
                        self.selected_element = None    
                        self.update()   
                                        
        def what_is_selected(self, coor):               
-               """     At the given coordinate, return the first element found 
to be selected  
+               """!
+               What is selected?
+               At the given coordinate, return the first element found to be 
selected  
                - iterate though the elements backwards since top elements are 
at the end of the list   
                - if an element is selected, place it at the end of the list so 
that is is drawn last, 
-                       and hence on top.       """              
+                       and hence on top.
+               @param coor the coordinate of the mouse click
+               @return the selected element or None
+               """              
                #       check the elements      #                       
                for i,element in enumerate(reversed(self.elements)):
                        if element.what_is_selected(coor) != None:
@@ -192,9 +223,51 @@
                                return element.what_is_selected(coor)           
                return None
                
-       def __button_press_event_cb(self, widget, event):
-               """      A mouse button is pressed. Record the state of the 
mouse, find the selected element,
-               set the Element highlighted, handle the state change, and 
redraw the FlowGraph. """             
+       def draw(self, drawable=None):          
+               """Draw the background and then all of the Elements in this 
FlowGraph on the pixmap, 
+               then draw the pixmap to the drawable window of this 
FlowGraph."""
+               if self.gc != None:                             
+                       #       draw the background     #               
+                       W,H = self.get_size_request()
+                       self.gc.foreground = BACKGROUND_COLOR
+                       self.pixmap.draw_rectangle(self.gc, True, 0, 0, W, H)   
+                       if Preferences.show_grid():                             
+                               grid_size = Preferences.get_grid_size()         
                
+                               points = list()
+                               for i in range(W/grid_size):
+                                       for j in range(H/grid_size): 
+                                               
points.append((i*grid_size,j*grid_size))                                        
+                               self.gc.foreground = TXT_COLOR                  
                
+                               self.pixmap.draw_points(self.gc, points)        
+                       #       draw the foreground     #
+                       for element in filter(Utils.is_signal_block, 
self.elements) + filter(Utils.is_connection, self.elements): 
+                               element.draw(self.pixmap)       # draw signal 
blocks first, then connections on the top                 
+                       if self.mouse_pressed and self.selected_element != None:
+                               self.selected_element.draw(self.pixmap)
+                       self.window.draw_drawable(self.gc, self.pixmap, 0, 0, 
0, 0, -1, -1)      
+                       
+       def is_valid(self):
+               """!
+               Is the flow graph valid, ie: are all elements valid?
+               @return true if flow graph is valid
+               """             
+               for element in self.elements: 
+                       if not element.is_valid(): return False
+               return True
+               
+       def update(self):
+               """Call update on all elements."""      
+               print "Updating entire flow graph..."
+               for element in self.elements: element.update()  
+               self.draw()
+               
+       
##########################################################################
+       ##      Handlers
+       
##########################################################################      
+               
+       def _handle_mouse_button_press(self, widget, event):
+               """ A mouse button is pressed. Record the state of the mouse, 
find the selected element,
+               set the Element highlighted, handle the state change, and 
redraw the FlowGraph."""              
                #       unselect anything in the vars mod window        #
                self.variable_modification_window.unselect_all()
                if event.button == 1:
@@ -221,8 +294,8 @@
                        self.draw()
                return True
                
-       def __button_release_event_cb(self, widget, event):
-               """     A mouse button is released, record the state.   """
+       def _handle_mouse_button_release(self, widget, event):
+               """A mouse button is released, record the state."""
                if event.button == 1:
                        self.mouse_pressed = False
                        if self.has_moved:
@@ -240,22 +313,9 @@
                                self.has_moved = False
                return True
                
-       def is_valid(self):
-               """ is the flow graph valid, ie: are all elements valid?        
"""             
-               for element in self.elements: 
-                       if not element.is_valid(): return False
-               return True
-               
-       def update(self):
-               '''call update on all elements'''       
-               print "Updating entire flow graph..."
-               for element in self.elements: element.update()  
-               self.draw()
-               
-       def __motion_notify_event_cb(self, widget, event):              
-               """ The mouse is moved. If mouse_pressed is true, react to the 
motions: 
-               -       if an Element is highlighted, this will move the 
Element by 
-                       redrawing it at the new position        """
+       def _handle_mouse_motion(self, widget, event):          
+               """The mouse has moved. If mouse_pressed is true, react to the 
motions: 
+               -       if an Element is highlighted, this will move the 
Element by redrawing it at the new position."""
                fgW,fgH = self.get_size_request()
                self.count = (1 + 
self.count)%MOTION_DETECT_REDRAWING_SENSITIVITY
                #       to perform a movement, the mouse must be pressed, an 
element selected, count of zero.   #
@@ -297,37 +357,14 @@
                        self.move_selected((deltaX, deltaY))    
                        self.coordinate = (x, y)        
                                        
-       def __on_expose(self, widget, event):   
-               """     The window initially appears or is resized, create a 
new pixmap, draw the flow graph.   """
+       def _handle_window_expose(self, widget, event): 
+               """Called when the window initially appears or is resized: 
create a new pixmap, draw the flow graph."""
                self.gc = self.window.new_gc()
                width, height = self.get_size_request()
                if self.pixmap == None or (width, height) != 
self.pixmap.get_size():            
                        self.pixmap = gtk.gdk.Pixmap(self.window, width, 
height, -1)
                        print "Main Pixmap Created!"
                self.draw()
-                       
-       def draw(self, drawable=None):          
-               """     draw the background and then all of the Elements in 
this FlowGraph on the pixmap, 
-               then draw the pixmap to the drawable window of this FlowGraph.  
"""
-               if self.gc != None:                             
-                       #       draw the background     #               
-                       W,H = self.get_size_request()
-                       self.gc.foreground = BACKGROUND_COLOR
-                       self.pixmap.draw_rectangle(self.gc, True, 0, 0, W, H)   
-                       if Preferences.show_grid():                             
-                               grid_size = Preferences.get_grid_size()         
                
-                               points = list()
-                               for i in range(W/grid_size):
-                                       for j in range(H/grid_size): 
-                                               
points.append((i*grid_size,j*grid_size))                                        
-                               self.gc.foreground = TXT_COLOR                  
                
-                               self.pixmap.draw_points(self.gc, points)        
-                       #       draw the foreground     #
-                       for element in filter(Utils.is_signal_block, 
self.elements) + filter(Utils.is_connection, self.elements): 
-                               element.draw(self.pixmap)       # draw signal 
blocks first, then connections on the top                 
-                       if self.mouse_pressed and self.selected_element != None:
-                               self.selected_element.draw(self.pixmap)
-                       self.window.draw_drawable(self.gc, self.pixmap, 0, 0, 
0, 0, -1, -1)      
 
 ##########################################################################
 ##
@@ -335,7 +372,10 @@
 ##
 ##########################################################################     
                                        
        def to_nested_data(self):
-               '''     Dump all the values in this flow graph into a nested 
data format.       '''
+               """!
+               Dump all the values in this flow graph into a nested data 
format.
+               @return nested data representing a flow graph
+               """
                vars_list = list()
                signal_blocks_list = list()
                connections_list = list()
@@ -397,10 +437,12 @@
 ##
 ##########################################################################     
        
        def from_nested_data(self, nested_data):
-               '''     Set all the values in this flow graph using the nested 
data.
-                       Return a string of errors, one error per line.  '''
+               """!
+               Set all the values in this flow graph using the nested data.
+               @param nested_data nested data representing a flow graph
+               """
                #print 'From',nested_data
-               #TODO: use a non-destructive methode to clear the elements list
+               #TODO: use a non-destructive method to clear the elements list
                self.elements = list()  #clear the elements
                find_data = ParseXML.find_data
                flow_graph = find_data([nested_data], 'flow_graph')
@@ -438,7 +480,7 @@
                                if element.get_id() == input_signal_block_id: 
input_socket = element.get_input_socket(input_socket_index)
                                if element.get_id() == output_signal_block_id: 
output_socket = element.get_output_socket(output_socket_index)
                        try: self.elements.append(GraphicalConnection(self, 
input_socket, output_socket))
-                       except (InvalidConnectionException, 
TooManyConnectionsException): 
+                       except ConnectionException: 
                                Messages.send_error_load('Could not connect 
"%s" input[%d] and "%s" output[%d].'%(
                                        input_signal_block_id, 
input_socket_index, output_signal_block_id, output_socket_index))        
                self.selected_element = None            

Deleted: grc/trunk/src/Graphics/FlowGraphFileDialog.py

Modified: grc/trunk/src/Graphics/MainWindow.py
===================================================================
--- grc/trunk/src/Graphics/MainWindow.py        2007-06-29 17:29:46 UTC (rev 
5877)
+++ grc/trunk/src/Graphics/MainWindow.py        2007-06-29 17:41:26 UTC (rev 
5878)
@@ -16,11 +16,9 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       Graphics/MainWindow.py 
-       Josh Blum
-       The main window, containing all windows, tool bars, and menu bars.
-"""
address@hidden Graphics.MainWindow
+#The main window, containing all windows, tool bars, and menu bars.
address@hidden Josh Blum
 
 from Constants import *
 import pygtk
@@ -31,27 +29,24 @@
 from SignalBlockSelectionWindow import SignalBlockSelectionWindow
 from VariableModificationWindow import VariableModificationWindow
 from Dialogs import TextDisplay
+import Preferences
 
 class MainWindow(gtk.Window):
-       """     The main topmost window with menus and toolbars and flow graph  
"""
+       """The topmost window with menus, the tool bar, and other major 
windows."""
        def __init__(self, handle_states):
-               """     add menu bar, toolbar, and flowgraph    """     
+               """!
+               MainWindow contructor.
+               @param handle_states the callback function
+               """     
                self.handle_states = handle_states
                gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)          
                vbox = gtk.VBox()
                hbox = gtk.HBox()
-               vbox.show()     
-               hbox.show()
                self.add(vbox)
                self.set_title("")      
-               #create the menu bar            
-               menuBar = Bars.MenuBar()
-               menuBar.show()
-               vbox.pack_start(menuBar, False)         
-               #create the toolbar
-               toolbar = Bars.Toolbar()
-               toolbar.show()
-               vbox.pack_start(toolbar, False)                 
+               #create the menu bar    and toolbar     
+               vbox.pack_start(Bars.MenuBar(), False)  
+               vbox.pack_start(Bars.Toolbar(), False)                  
                # create variable modification window   #
                variable_modification_window = 
VariableModificationWindow(self.handle_states)           
                #       create a flow_graph     #
@@ -61,15 +56,12 @@
                scrolled_window.set_size_request(MIN_WINDOW_WIDTH, 
MIN_WINDOW_HEIGHT)   
                scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, 
gtk.POLICY_AUTOMATIC)
                scrolled_window.add_with_viewport(self.flow_graph)
-               scrolled_window.show()
                fg_and_report_box = gtk.VBox()
-               fg_and_report_box.show()
                fg_and_report_box.pack_start(scrolled_window)
                hbox.pack_start(fg_and_report_box)
                vbox.pack_start(hbox)           
                #create the side windows
                side_box = gtk.VBox()
-               side_box.show()
                hbox.pack_start(side_box, False)
                side_box.pack_start(variable_modification_window, False)        
        #dont allow resize
                
side_box.pack_start(SignalBlockSelectionWindow(self.flow_graph)) #all resize, 
selection window can have more space
@@ -79,25 +71,48 @@
                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.show_reports_window(False) #hide the window by default
+               
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
-               #self.show()            
+               # show all but the main window container and the reports window 
+               vbox.show_all()                 
+               self.show_reports_window(False) 
+               # load preferences and show the main window 
+               Preferences.load(self)
+               self.show()#show after resize in preferences
                
+       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. 
+               This method in turns calls the state handler to quit.
+               @return true            
+               """
+               self.handle_states(APPLICATION_QUIT)
+               return True     
+               
        def add_report_line(self, line):
-               """ place line plus a newline at the end of the text buffer, 
then scroll its window all the way down.   """
+               """!
+               Place line plus a newline 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)          
                vadj = self.reports_scrolled_window.get_vadjustment()
                vadj.set_value(vadj.upper)
                                
        def set_title(self, title):
-               """     set the title and prepend the program name      """
+               """!
+               Set the title and prepend the program name.
+               @param title the window title
+               """
                prepend_str = MAIN_WINDOW_PREFIX + ' - Editing: '
                gtk.Window.set_title(self, prepend_str + str(title))    
                
        def show_reports_window(self, show):
-               """ Show the reports window when show is True.
-               Hide the reports window when show is False.     """
+               """!
+               Show the reports window when show is True.
+               Hide the reports window when show is False.
+               @param show boolean flag
+               """
                if show: self.reports_scrolled_window.show()
                else: self.reports_scrolled_window.hide()
                
\ No newline at end of file

Modified: grc/trunk/src/Graphics/SignalBlockParamsDialog.py
===================================================================
--- grc/trunk/src/Graphics/SignalBlockParamsDialog.py   2007-06-29 17:29:46 UTC 
(rev 5877)
+++ grc/trunk/src/Graphics/SignalBlockParamsDialog.py   2007-06-29 17:41:26 UTC 
(rev 5878)
@@ -16,11 +16,9 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       Graphics/SignalBlockParamsDialog.py 
-       Josh Blum
-       A dialog for editing a signal block's parameters.
-"""
address@hidden Graphics.SignalBlockParamsDialog
+#A dialog for editing a signal block's parameters.
address@hidden Josh Blum
 
 import pygtk
 pygtk.require('2.0')
@@ -29,42 +27,57 @@
 from Constants import MIN_DIALOG_WIDTH,MIN_DIALOG_HEIGHT
 
 class SignalBlockParamsDialog(gtk.Dialog):
-       """     A dialog box to set signal block parameters such as sampling 
rate and decimation values.        """
+       """A dialog box to set signal block parameters."""
        def __init__(self, signal_block):
+               """!
+               SignalBlockParamsDialog contructor.
+               @param signal_block the signal block
+               """
                gtk.Dialog.__init__(self, buttons=('gtk-close', 
gtk.RESPONSE_CLOSE))
                self.signal_block = signal_block
-               self.set_title(signal_block.get_id()+' properties')
+               self.set_title('Properties: %s'%signal_block.get_id())
                self.set_size_request(MIN_DIALOG_WIDTH, MIN_DIALOG_HEIGHT)
                vbox = gtk.VBox()
-               vbox.show()             
                #       Create the title label  #
                label = gtk.Label()
-               label.set_markup('<b>'+self.signal_block.get_id()+' 
Parameters:</b>')
-               label.show()
-               self.vbox.pack_start(label, False)
+               label.set_markup('\n<b>Parameters: 
%s</b>\n'%self.signal_block.get_id())
+               vbox.pack_start(label, 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)
-               scrolled_window.show()
                self.vbox.pack_start(scrolled_window, True)
                self.original_data = list()
                #       Add all the parameters  #
                for param in self.signal_block.get_params(): 
                        
self.original_data.append(param.get_data_type().get_data())
-                       vbox.pack_start(param.get_input_object(), False)        
+                       
vbox.pack_start(param.get_input_object(self._handle_changed), False)    
                # Done adding parameters        #                               
                                
-               if self.signal_block.get_docs() != None:        
+               if self.signal_block.get_docs():        
                        #       Create the title label  #
                        label = gtk.Label()
-                       label.set_markup('<b>'+self.signal_block.get_cname()+' 
Documentation:</b>')
-                       label.show()
-                       self.vbox.pack_start(label, False)      
+                       label.set_markup('\n\n<b>Documentation: 
%s</b>\n'%self.signal_block.get_cname())
+                       vbox.pack_start(label, False)   
                        #       Create the text box to display notes about the 
block    #       
-                       
self.vbox.pack_start(TextDisplay(self.signal_block.get_docs()), False)
+                       
vbox.pack_start(TextDisplay(self.signal_block.get_docs()), False)
+               self.show_all()
+                       
+       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                
+               """
+               for p in self.signal_block.get_params():
+                       if hasattr(p.get_data_type(), 'enum_data_type') and \
+                               param.get_data_type() == 
getattr(p.get_data_type(), 'enum_data_type'): p.update()
                
        def run(self):
-               ''' Call the parent class run and return True if a change 
occured.      '''
+               """!
+               Call run().
+               @return true if a change occured.
+               """
                gtk.Dialog.run(self)            
                self.destroy()
                self.data = list()

Modified: grc/trunk/src/Graphics/SignalBlockSelectionWindow.py
===================================================================
--- grc/trunk/src/Graphics/SignalBlockSelectionWindow.py        2007-06-29 
17:29:46 UTC (rev 5877)
+++ grc/trunk/src/Graphics/SignalBlockSelectionWindow.py        2007-06-29 
17:41:26 UTC (rev 5878)
@@ -16,12 +16,9 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       Graphics/SignalBlockSelectionWindow.py 
-       Josh Blum
-       The signal block selection window.
-       Gives the user a tree selection to choose a signal block.
-"""
address@hidden Graphics.SignalBlockSelectionWindow
+#The signal block selection window gives the user a tree selection to choose a 
signal block.
address@hidden Josh Blum
 
 from Constants import *
 import pygtk
@@ -31,67 +28,73 @@
 from SignalBlockDefs import SB_TREE
 
 class SignalBlockSelectionWindow(gtk.VBox):
-       """     The signal block selection window.      """
+       """The signal block selection window."""
        def __init__(self, flow_graph):
-               """     Show all possible signal blocks in this dialog. Each 
signal block is represented by a
-                       gtk label of its CNAME and an add button. The add 
button tells the flow graph to add the chosen block.  """     
+               """!
+               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 flow_graph the flow graph
+               """     
                gtk.VBox.__init__(self)
                self.flow_graph = flow_graph
                #title label
                label = gtk.Label()
                label.set_markup('<b>Signal Blocks</b>')
-               label.show()            
                self.pack_start(label, False)           
-               #       make the tree model for holding blocks  #
+               #make the tree model for holding blocks 
                self.model = gtk.TreeStore(gobject.TYPE_STRING)
                self.treeview = gtk.TreeView(self.model)                
                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_button_press)
+               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)      
+               selection.connect('changed', self._handle_selection_change)     
                renderer = gtk.CellRendererText()
                column = gtk.TreeViewColumn("Category", renderer, text=0)
                self.treeview.append_column(column)
-               self.treeview.show()
-               # make the scrolled window to hold the tree view        #
+               #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(SIGNAL_BLOCK_SELECTION_WINDOW_WIDTH,
-                                                                               
                        SIGNAL_BLOCK_SELECTION_WINDOW_HEIGHT)
-               scrolled_window.show()
+               scrolled_window.set_size_request(
+                       SIGNAL_BLOCK_SELECTION_WINDOW_WIDTH,
+                       SIGNAL_BLOCK_SELECTION_WINDOW_HEIGHT,
+               )
                self.pack_start(scrolled_window)
-               #       add button      #
+               #add button
                self.add_button = gtk.Button(None, 'gtk-add')           
-               self.add_button.connect('clicked', self.handle_add_button)
-               self.add_button.show()
+               self.add_button.connect('clicked', self._handle_add_button)
                self.pack_start(self.add_button, False)
-               #       add blocks and categories       #
+               #add blocks and categories      
                for category, tags in SB_TREE:
                        iter = self.model.insert_before(None, None)
                        self.model.set_value(iter, 0, category)
                        for tag in tags:
                                new_iter = self.model.insert_before(iter, None) 
                                                
                                self.model.set_value(new_iter, 0, tag[0])
-               self.handle_selection_change(None)
-               self.show()
+               #initialize
+               self._handle_selection_change()
                
-       def handle_button_press(self, widget, event):
-               ''' 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_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, event):
-               '''     If a selection changes, set the add button sensitive.   
'''
+       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()
                if iter != None and not model.iter_has_child(iter): 
self.add_button.set_sensitive(True)
                else: self.add_button.set_sensitive(False)
        
-       def handle_add_button(self, widget):
-               """     add the signal block to the flow graph and redraw the 
flow graph        """
+       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()
                model, iter = selection.get_selected()
                if iter != None and not model.iter_has_child(iter): 
self.flow_graph.add_signal_block(model.get_value(iter, 0))

Modified: grc/trunk/src/Graphics/USRPDiagnostics.py
===================================================================
--- grc/trunk/src/Graphics/USRPDiagnostics.py   2007-06-29 17:29:46 UTC (rev 
5877)
+++ grc/trunk/src/Graphics/USRPDiagnostics.py   2007-06-29 17:41:26 UTC (rev 
5878)
@@ -16,57 +16,58 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""    
-       Graphics/USRPDiagnostics.py     
-       Josh Blum
-       A dialog for querying USRP subdevices. USRP interfacing methods 
encapsulated here.
-"""
address@hidden Graphics.USRPDiagnostics
+#A dialog for querying USRP subdevices. USRP interfacing methods encapsulated 
here.
address@hidden Josh Blum
 
 import pygtk
 pygtk.require('2.0')
 import gtk
 from Actions import USRP_DIAGNOSTICS_DISPLAY,get_action_from_name
 from Elements import GraphicalParam
-from DataType import *
+from DataTypes import *
 from Dialogs import TextDisplay
 
 def enable_usrp_diagnostics():
-       """     Only enable the action for USRP diganostics if gnuradio.usrp 
can be imported.   """
+       """Enable the action for USRP diganostics if gnuradio.usrp can be 
imported."""
        try: 
                from gnuradio import usrp
                
get_action_from_name(USRP_DIAGNOSTICS_DISPLAY).set_sensitive(True)
        except ImportError: print "USRP support missing -> USRP diagnostics 
disabled..."        
 
 class USRPDiagnosticsDialog(gtk.Dialog):
-       """ The main dialog window for USRP Dignostics. 
-       The USRP parameters and feedback will be located inside this dialog.    
"""
+       """The main dialog window for USRP Dignostics. 
+       The USRP parameters and feedback will be located inside this dialog."""
        def __init__(self):
-               """     Create a new gtk Dialog with a close button, USRP input 
paramaters, and output labels.  """             
+               """USRPDiagnosticsDialog contructor.
+               Create a new gtk Dialog with a close button, USRP input 
paramaters, and output labels."""               
                gtk.Dialog.__init__(self, buttons=('gtk-close', 
gtk.RESPONSE_CLOSE))
                #       Create the title label  #
                self.set_title('USRP Diagnostics')
                self.USRP_number = Int(0, min=0)
                self.USRP_type = Enum([('Receive', 'rx'), ('Transmit', 'tx'),])
-               self.USRP_subdev = Enum([('Side A:0', (0, 0)), 
-                                                                               
('Side B:0', (1, 0)),
-                                                                               
('Side A:1', (0, 1)), 
-                                                                               
('Side B:1', (1, 1)),])
+               self.USRP_subdev = Enum([
+                       ('Side A:0', (0, 0)), 
+                       ('Side B:0', (1, 0)),
+                       ('Side A:1', (0, 1)), 
+                       ('Side B:1', (1, 1)),
+               ])
                self.vbox.pack_start(GraphicalParam('Unit Number', 
self.USRP_number).get_input_object(), False)
                self.vbox.pack_start(GraphicalParam('Transmit/Receive', 
self.USRP_type).get_input_object(), False)
                self.vbox.pack_start(GraphicalParam('Side:Subdevice', 
self.USRP_subdev).get_input_object(), False)
                self.diagnose_button = gtk.Button('Query')
-               self.diagnose_button.connect('clicked', self.diagnose_usrp)
-               self.diagnose_button.show()
+               self.diagnose_button.connect('clicked', self._diagnose_usrp)
                self.vbox.pack_start(self.diagnose_button, False)               
                #       Create a text box for USRP queries      #
                self.query_buffer = TextDisplay()
                self.query_buffer.set_text('Press "Query" to retrieve USRP 
information...')                     
-               self.vbox.pack_start(self.query_buffer)         
+               self.vbox.pack_start(self.query_buffer) 
+               self.show_all() 
                self.run()
                self.destroy()
                
-       def diagnose_usrp(self, widget=None):
-               """ Query the USRP device and append the results into the query 
text box.       """
+       def _diagnose_usrp(self, widget=None):
+               """Query the USRP device and copy the results into the query 
text box."""
                from gnuradio import usrp
                type = self.USRP_type.parse()
                if type == 'rx':        #for the rx query, use the source and 
rx methods

Modified: grc/trunk/src/Graphics/VariableModificationWindow.py
===================================================================
--- grc/trunk/src/Graphics/VariableModificationWindow.py        2007-06-29 
17:29:46 UTC (rev 5877)
+++ grc/trunk/src/Graphics/VariableModificationWindow.py        2007-06-29 
17:41:26 UTC (rev 5878)
@@ -16,15 +16,12 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       Graphics/Windows/VariableModificationWindow.py 
-       Josh Blum
-       The variable modification window. 
-       Allows the user to enter variables and slider information.
-"""
address@hidden Graphics.VariableModificationWindow
+#The variable modification window allows the user to enter variables (keys, 
values, ranges).
address@hidden Josh Blum
 
 from Constants import *
-from Actions import VARIABLE_MODIFY, NOTHING_SELECT
+from Actions import VARIABLE_MODIFY,VARIABLE_REORDER,NOTHING_SELECT
 import pygtk
 pygtk.require('2.0')
 import gtk
@@ -32,87 +29,144 @@
 import Variables
 
 class VariableModificationWindow(gtk.VBox):
-       '''     A scrollable window to add/remove variables in the variable 
registry    '''
+       """A scrollable window to add/remove variables in the variable 
registry."""
        def __init__(self, handle_states):
-               ''' create a scrolled window, and add buttons and lists '''
+               """!
+               VariableModificationWindow constructor.Create a scrolled 
window, and add buttons and lists.
+               @param handle_states callback function to handle the variable 
changes
+               """
                gtk.VBox.__init__(self) 
                self.handle_states = handle_states                      
                #title label
                label = gtk.Label()
                label.set_markup('<b>Variables</b>')
-               label.show()            
                self.pack_start(label, False)           
-               # create a srolled window to hold the vars      #
+               #create a srolled window to hold the tree view
                scrolled_window = gtk.ScrolledWindow()
-               scrolled_window.show()
                scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, 
gtk.POLICY_AUTOMATIC)
                scrolled_window.set_size_request(
                        VARIABLE_MODIFICATION_WINDOW_WIDTH, 
                        VARIABLE_MODIFICATION_WINDOW_HEIGHT
                )
                self.pack_start(scrolled_window)                
-               #       liststore hold the graphical list       #
+               #liststore holds the graphical list
                self.liststore = gtk.ListStore(
                        gobject.TYPE_STRING,    #key
                        gobject.TYPE_STRING,    #value
                        gobject.TYPE_STRING,    #min
                        gobject.TYPE_STRING,            #max
-                       gobject.TYPE_STRING             #step
+                       gobject.TYPE_STRING,            #step
                )               
                self.treeview = gtk.TreeView(self.liststore)    
                self.treeview.set_enable_search(False) #disable pop up search 
box
                self.renderers = list()
                for i,title in enumerate(['Variable', 'Default', 'Min', 'Max', 
'Step']):        #create each data column
+                       #renderer for column i          
                        renderer = gtk.CellRendererText()
                        renderer.set_property('editable', True)
-                       renderer.connect('edited', 
self.__handle_renderer_edited)
                        self.renderers.append(renderer)
+                       #connect signal handlers
+                       renderer.connect('edited', self._handle_renderer_edited)
+                       renderer.connect('editing-started', 
self._handle_start_editing)
+                       renderer.connect('editing-canceled', 
self._handle_cancel_editing)
+                       #tree view for column i
                        tree_view_column = gtk.TreeViewColumn(title, renderer, 
text=i)
                        
tree_view_column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE) #allow the column to 
shrink
                        self.treeview.append_column(tree_view_column)
                self.treeview.set_reorderable(True)     
                selection = self.treeview.get_selection()
                selection.set_mode('single')
-               selection.connect('changed', self.__handle_selection_change)    
                                
-               self.treeview.show()            
+               selection.connect('changed', self._handle_selection_change)
                scrolled_window.add_with_viewport(self.treeview)
-               #       buttons #
+               #buttons add and remove
                buttons_hbox = gtk.HBox()
-               buttons_hbox.show()
-               self.pack_start(buttons_hbox, False)            
-               # add, edit, and remove buttons #
+               self.pack_start(buttons_hbox, False)    
                add_button = gtk.Button(None, 'gtk-add')                
-               add_button.connect('clicked', self.__handle_add_button)
-               add_button.show()
+               add_button.connect('clicked', self._handle_add_button)
                buttons_hbox.pack_start(add_button, False)
                self.remove_button = gtk.Button(None, 'gtk-remove')
-               self.remove_button.connect('clicked', 
self.__handle_remove_button)
-               self.remove_button.show()
+               self.remove_button.connect('clicked', 
self._handle_remove_button)
                buttons_hbox.pack_start(self.remove_button, False)
-               self.treeview.connect("cursor-changed", 
self.__handle_cursor_changed)
-               self.__handle_selection_change()        
-               self.show()                             
+               #connect signal handlers
+               self.treeview.connect("cursor-changed", 
self._handle_cursor_changed)    
+               self.treeview.connect("drag_begin", self._handle_drag_begin)    
+               self.treeview.connect("drag_end", self._handle_drag_end)
+               #initialize
+               self._handle_cancel_editing()
+               self._handle_selection_change() 
                
+       
#############################################################################################
   
+       #       Access Methods
+       
#############################################################################################
   
+               
+       def to_key_list(self):
+               """!
+               Get a list of the keys in the current order. 
+               @return a list of ordered variable keys
+               """
+               key_list = list()
+               for row in self.liststore: key_list.append(row[0])
+               return key_list
+       
+       def from_key_list(self, key_list):
+               """!
+               Clear the rows and refill the list with keys from the key list.
+               @param key_list a list of ordered keys
+               """             
+               self.liststore.clear()
+               for key in key_list: 
self.liststore.append((key,)+Variables.get_values(key))
+                                                       
        def unselect_all(self):         
-               ''' Stop editing in each renderer and unselect every row in the 
tree view.      '''
-               #TODO: stop editing doesnt work
-               for renderer in self.renderers: renderer.stop_editing(True)
+               """Stop any editing and unselect every row in the tree view."""
+               if self.editable: self.editable.remove_widget()
                self.treeview.get_selection().unselect_all()    
+
+       
#############################################################################################
   
+       #       Row Manipulation Handlers
+       
#############################################################################################
   
                
-       def __handle_cursor_changed(self, event=None):
-               ''' Called when the cursor is placed on a row or in a cell.
-               Unselect any selected element in the flow graph.        '''
+       def _handle_drag_begin(self, drag_context, data):
+               """A drag event has begun, make a backup of the key list."""
+               self.backup_key_list = self.to_key_list()
+               
+       def _handle_drag_end(self, drag_context, data):
+               """A drag event has ended. 
+               If the backup key list does not match the current key list, 
+               handle the variable state change."""
+               if self.backup_key_list != self.to_key_list(): 
self.handle_states(VARIABLE_REORDER)     
+               
+       def _handle_cursor_changed(self, treeview):
+               """Called when the cursor is placed on a row or in a cell.
+               Unselect any selected element in the flow graph."""
                self.handle_states(NOTHING_SELECT)
                                
-       def __handle_selection_change(self, event=None):
-               '''     If a selection changes, set the edit and remove buttons 
sensitive.      '''
+       def _handle_selection_change(self, selection=None):
+               """If a selection changes, set the edit and remove buttons 
sensitive."""
                selection = self.treeview.get_selection()
                model, iter = selection.get_selected()
                if iter != None: self.remove_button.set_sensitive(True)
                else: self.remove_button.set_sensitive(False)
                        
-       def __handle_renderer_edited(self, renderer, row_index, new_text):
-               ''' A cell was edited, determine what was edited and how to 
handle it.  '''
+       
#############################################################################################
   
+       #       Cell Editing Handlers
+       
#############################################################################################
                           
+                       
+       def _handle_start_editing(self, cellrenderer, editable, path):
+               """Editing of a cell has begun, record the editable object."""
+               self.editable = editable
+               
+       def _handle_cancel_editing(self, cellrenderer=None):
+               """Editing of a cell has been canceled."""
+               self.editable = None                                    
+                       
+       def _handle_renderer_edited(self, renderer, row_index, new_text):
+               """!
+               A cell was edited, determine what was edited and how to handle 
it.
+               @param renderer the renderer
+               @param row_index the index of the row that changes
+               @param new_text the new text in the cell
+               """
+               self._handle_cancel_editing()
                column_index = self.renderers.index(renderer)
                if new_text == self.liststore[row_index][column_index]: return 
#no change
                old_list = self.liststore[row_index]
@@ -134,8 +188,12 @@
                        self.liststore[row_index][i] = value    
                self.handle_states(VARIABLE_MODIFY)     
                        
-       def __handle_remove_button(self, widget, data=None):
-               ''' Remove the selected element from the list and from the 
VarReg.      '''
+       
#############################################################################################
   
+       #       Button Handlers
+       
#############################################################################################
                           
+                               
+       def _handle_remove_button(self, widget):
+               """Handle the remove button by removing the selected element 
from the list and from the variables registry."""
                selection = self.treeview.get_selection()
                model, iter = selection.get_selected()
                if iter != None: 
@@ -143,9 +201,9 @@
                        model.remove(iter)                      
                        self.handle_states(VARIABLE_MODIFY)
                        
-       def __handle_add_button(self, widget, data=None):       
-               ''' Handle the add button by adding a variable with key and 
value. 
-                       The key will be unique in the form 'new_var' + index.   
'''
+       def _handle_add_button(self, widget):   
+               """Handle the add button by adding a variable with key and 
value. 
+               The key will be unique in the form 'new_var' + index."""
                new_key_index = 0
                while True:
                        new_key_name = 'new_var'+str(new_key_index)
@@ -157,16 +215,6 @@
                                
self.liststore.append((new_key_name,)+Variables.get_values(new_key_name))
                                self.handle_states(VARIABLE_MODIFY)
                                return  #leave the while loop
-               
-       def to_key_list(self):
-               '''     Return a list of the keys in the current order.         
'''
-               key_list = list()
-               for row in self.liststore: key_list.append(row[0])
-               return key_list
-       
-       def from_key_list(self, key_list):
-               ''' Clear the rows and refill the list with keys from the list. 
'''             
-               self.liststore.clear()
-               for key in key_list: 
self.liststore.append((key,)+Variables.get_values(key))
                                
+                               
                                
\ No newline at end of file

Modified: grc/trunk/src/Graphics/__init__.py
===================================================================
--- grc/trunk/src/Graphics/__init__.py  2007-06-29 17:29:46 UTC (rev 5877)
+++ grc/trunk/src/Graphics/__init__.py  2007-06-29 17:41:26 UTC (rev 5878)
@@ -16,13 +16,12 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       Graphics/__init__.py    
-       gtk based classes go into this package
-"""
address@hidden Graphics.__init__
+#GTK based classes go into this package.
address@hidden Josh Blum
 
 #      only import the modules that need external access #
 from MainWindow import MainWindow
-from FlowGraphFileDialog import FlowGraphFileDialog
+from FileDialogs import 
OpenFlowGraphFileDialog,SaveFlowGraphFileDialog,SaveImageFileDialog
 from Dialogs import 
PreferencesDialog,FlowGraphWindowSizeDialog,LooseChangesMessage,AboutDialog,DataTypeColorsDialog,HotKeysDialog,MathExprDialog
 from USRPDiagnostics import USRPDiagnosticsDialog,enable_usrp_diagnostics

Modified: grc/trunk/src/MathExprParser.py
===================================================================
--- grc/trunk/src/MathExprParser.py     2007-06-29 17:29:46 UTC (rev 5877)
+++ grc/trunk/src/MathExprParser.py     2007-06-29 17:41:26 UTC (rev 5878)
@@ -16,14 +16,9 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       MathExprParser.py 
-       Josh Blum
-       This file provides:
-       eval_expr for evaluating string expressions,
-       verify_complex, verify_float, verify_int for casting numbers,
-       and verify_number for picking the best representation.
-"""
address@hidden MathExprParser
+#Evaluate mathematical expressions and provide utilties to cast numbers.
address@hidden Josh Blum
 
 import math,cmath
 from gnuradio import gr
@@ -32,7 +27,7 @@
 
 _WHITESPACE = (' ', '\t', '')
 
-_CONSTANTS = { #constans must be lower case
+_CONSTANTS = { #constants must be lower case
        'pi' : cmath.pi,
        'e' : cmath.e,
        'j' : 1j,
@@ -45,50 +40,66 @@
 }
        
 #########################################################
-##     Number parsers
+#      Number parsers
 #########################################################
 
 def verify_complex(num):
-       ''' Verify that the number is a complex number.
-               Raise an exception if number cannot be cast to a complex.
-               Return the value as a complex.  '''
+       """!
+       Verify that the number is a complex number.
+       @param num the potential complex number
+       @throw ValueError not a number
+       @return a complex number
+       """
        try: c_num = complex(num)       #ensure that the num can be complex
-       except: raise ValueError('"%s" is not a number.'%(num,))
+       except: raise ValueError, '"%s" is not a number.'%(num,)
        return c_num
 
 def verify_float(num):
-       ''' Verify that the number has no imaginary part.
-               Raise an exception if the imaginary part is non zero.
-               Return the value as a float.    '''
+       """!
+       Verify the number as a float.
+       The number can have no imaginary part.
+       @param num the potential float number
+       @throw ValueError imaginary part is non zero.
+       @return a float number
+       """
        c_num = verify_complex(num)     #ensure that the num can be complex
-       if c_num.imag != 0: raise ValueError('Expected a float but found 
"%s".'%(c_num,))
+       if c_num.imag != 0: raise ValueError, 'Expected a float but found 
"%s".'%(c_num,)
        return float(c_num.real)
 
 def verify_int(num):
-       ''' Verify that the number has no imaginary part.
-               Verify that the number has no decimal part.
-               Otherwise raise an exception.
-               Return the value as a int       '''
+       """!
+       Verify the number as an integer.
+       The number can have no imaginary part.
+       The number can have no decimal part.
+       @param num the potential integer number
+       @throw ValueError imaginary or decimal part is non zero.
+       @return an integer number
+       """
        f_num = verify_float(num)
-       if f_num - int(f_num) != 0: raise ValueError('Expected an integer but 
found "%s".'%(f_num,))
+       if f_num - int(f_num) != 0: raise ValueError, 'Expected an integer but 
found "%s".'%(f_num,)
        return int(f_num)
        
 def verify_number(num):
-       ''' Try to cast the number into its most primative form.
-               In this order: int, float, or complex. 
-               Raise an exception if num is not a number.
-               Return a number of type listed above. '''
+       """!
+       Try to cast the number into its most primative form: int, float, or 
complex. 
+       @throw ValueError num is not a number.
+       @return a number of int, float, or complex type 
+       """
        try: return verify_int(num)     #try int
        except:
                try: return verify_float(num)   #try float
                except: return verify_complex(num)      #complex or fail
 
 #########################################################
-##     Complex mathematical functions 
+#      Complex mathematical functions 
 #########################################################
        
 def _complex_abs_v(*args):
-       ''' Compute the abs of a complex number or vector.      '''
+       """!
+       Compute the abs of a complex number or vector (recursively).
+       @param args list of numbers
+       @return the abs of args
+       """
        sum = 0
        for arg in args: 
                if _is_list(arg): sum = sum + _complex_abs_v(*arg)
@@ -98,7 +109,11 @@
        return verify_number(cmath.sqrt(sum))                   
 
 def _complex_real_v(*args):
-       ''' Get the real part of a number or vector.    '''
+       """!
+       Get the real part of a number or vector (recursively).
+       @param args list of numbers
+       @return the real of args
+       """
        result = list()
        for arg in args: 
                if _is_list(arg): result.append(_complex_real_v(*arg))
@@ -106,7 +121,11 @@
        return result
 
 def _complex_imag_v(*args):
-       ''' Get the imaginary part of a number or vector.       '''
+       """!
+       Get the imaginary part of a number or vector (recursively).
+       @param args list of numbers
+       @return the imaginary of args
+       """
        result = list()
        for arg in args:  
                if _is_list(arg): result.append(_complex_imag_v(*arg))
@@ -114,7 +133,11 @@
        return result
 
 def _complex_conj_v(*args):
-       ''' Get the complex conjugate of a number or vector.    '''
+       """!
+       Get the conjugate part of a number or vector (recursively).
+       @param args list of numbers
+       @return the conjugate of args
+       """
        result = list()
        for arg in args:  
                if _is_list(arg): result.append(_complex_conj_v(*arg))
@@ -122,14 +145,20 @@
        return result
 
 def _complex_arg(arg):
-       ''' Get the angle of the complex number (radians).      '''
+       """!
+       Get the angle of the complex number.
+       @param arg a complex number
+       @return the angle in radians    
+       """
        return verify_number(math.atan2(verify_complex(arg).imag, 
verify_complex(arg).real))
 
 def _handle_filter(filter, *filter_args):
-       ''' Pass the filter arguments to the filter function. 
-               Format the arguments to floats and ints.
-               Raise errors for invalid filter arguments.
-               Return a list of taps.  '''
+       """!
+       Pass the filter arguments to the filter function. 
+       Use a look up method to format the arguments to floats and ints before 
calling the filter function.
+       @throw Exception invalid filter arguments.
+       @return a list of taps. 
+       """
        filter_args = list(filter_args) #make filter args a list
        filter_props = {        # map a filter to filter argument properties:
                # (allowed lengths of args), (args that are floats), (args that 
are ints)
@@ -147,7 +176,7 @@
        }
        arg_lens, floats, ints = filter_props[filter]
        # handle the filter arguments #
-       if len(filter_args) not in arg_lens: raise SyntaxError('Invalid number 
of arguments for "%s".'%filter)  
+       if len(filter_args) not in arg_lens: raise SyntaxError, 'Invalid number 
of arguments for "%s".'%filter  
        for i,arg in enumerate(filter_args):
                if i in floats: filter_args[i] = verify_float(arg)
                if i in ints: filter_args[i] = verify_int(arg)  
@@ -208,7 +237,7 @@
 }
 
 #########################################################
-##     Boolean tests for special characters and symbols
+#      Boolean tests for special characters and symbols
 #########################################################
 
 def _is_list(symbol): return type(symbol) == type(list())
@@ -253,14 +282,22 @@
        }[bracket]
        
 #########################################################
-##     Symbolic operations
+#      Symbolic operations
 #########################################################              
        
 def _handle_operation(op, arg1, arg2):
-       ''' Handle basic operations specified in the order of operations.
-               All calculations are complex, some vector operations are 
supported.
-               Return the number/list representing the result. '''
-       if op not in _ORDER_OF_OPS: raise NameError('Unknown operator: 
"%s".'%(op))     
+       """!
+       Handle basic operations specified in the order of operations 
(recursively).
+       All calculations are complex, some vector operations are supported.
+       @param op the operator
+       @param arg1 first argument to the operator      
+       @param arg2 second argument to the operator
+       @throw NameError unknown operations     
+       @throw ZeroDivisionError divide by zero
+       @throw ArithmeticError impossible operations
+       @return the nested data representing the result (numbers and lists)
+       """
+       if op not in _ORDER_OF_OPS: raise NameError, 'Unknown operator: 
"%s".'%(op)
        arg1_is_list = _is_list(arg1)
        arg2_is_list = _is_list(arg2)
        # addition and subtraction of vectors #
@@ -288,24 +325,27 @@
                        return verify_number(arg1 * arg2)
                elif op == '/':
                        try: return verify_number(verify_complex(arg1) / 
verify_complex(arg2))  #make sure to use non-integer division
-                       except ZeroDivisionError: raise 
ZeroDivisionError('Cannot divide "%s" by 0.'%(arg1,))
+                       except ZeroDivisionError: raise ZeroDivisionError, 
'Cannot divide "%s" by 0.'%(arg1,)
                elif op == '+':
                        return verify_number(arg1 + arg2)
                elif op == '-':
                        return verify_number(arg1 - arg2)
-       raise ArithmeticError('Operation of "%s" cannot be performed on "%s", 
"%s".'%(op, arg1, arg2))  
+       raise ArithmeticError, 'Operation of "%s" cannot be performed on "%s", 
"%s".'%(op, arg1, arg2)
        
 #########################################################
-##     Evaluate the expression string 
+#      Evaluate the expression string 
 #########################################################      
 
 def _separate_expression(expr_str):
-       '''     Separate the string into a list of elements.
-               Use only the lower-cased version of the expression string.
-               Terminating characters will dictate the separations.
-               Terminating characters will be included in the list.
-               Whitespace characters will be removed from the list.
-               Return a list of strings representing each element.     '''
+       """!
+       Separate the string into a list of elements.
+       Use only the lower-cased version of the expression string.
+       Terminating characters will dictate the separations.
+       Terminating characters will be included in the list.
+       Whitespace characters will be removed from the list.
+       @param expr_str the expression string   
+       @return a list of strings representing each element
+       """
        elements = list()
        element = ''
        for char_str in expr_str.lower():
@@ -319,11 +359,14 @@
        return filter(lambda elem: not _is_whitespace(elem), elements)
 
 def _rectify_operators(elements):
-       '''     Rectify the functionality of the minus sign (-),
-               and the plus sign (+) (in the floating point format).
-               Determine if the minus sign is used as a negative, 
-               and replace it with -1* or ^-. Also rejoin floating point 
formats. 
-               Return the list of elements with minus and plus used only as 
operators. '''
+       """!
+       Rectify operators.      
+       Fix the functionality of the minus sign (-)     and the plus sign (+) 
in the floating point format,
+       which would have been separated by separate_expression.
+       If the minus sign is used as a negative replace it with -1* or ^-. 
+       @param elements a list of strings 
+       @return the list of elements with minus and plus used only as operators
+       """
        rectified_elements = list()
        for i,element in enumerate(elements):
                if i == 0 and element == '-':   #first element was a minus
@@ -348,10 +391,15 @@
        return rectified_elements
 
 def _nest_elements(elements, open_bracket=''):
-       '''     Read through the elements, recursing at each open bracket.
-               Put elements inside bracket pairs into a list.  
-               Raise an Error if bracket pairs do not match.   
-               Return the nested elements.     '''
+       """!
+       Put the elements into a nested data format (recursively).
+       Read through the elements, recursing at each open bracket.
+       Put elements inside bracket pairs into a list.  
+       @param a list of strings (rectified)
+       @param open_bracket the last open bracket
+       @throw SyntaxError bracket pairs do not match
+       @return the nested elements.    
+       """
        nested_elements = list()
        while elements: #continue until elements is empty
                element = elements.pop(0)
@@ -359,19 +407,24 @@
                        nested_elements.append(_nest_elements(elements, 
element))
                elif _is_close_bracket(element):        
                        if element != _get_oposing_bracket(open_bracket):       
#matching open/close brackets?
-                               raise SyntaxError('Expected "%s", but found 
"%s".'%(_get_oposing_bracket(open_bracket), element))
+                               raise SyntaxError, 'Expected "%s", but found 
"%s".'%(_get_oposing_bracket(open_bracket), element)
                        return nested_elements
                else: nested_elements.append(element)
        if open_bracket:        #any unclosed bracket pairs? 
-               raise SyntaxError('Expected "%s", but found 
nothing.'%(_get_oposing_bracket(open_bracket),))
+               raise SyntaxError, 'Expected "%s", but found 
nothing.'%(_get_oposing_bracket(open_bracket),)
        return nested_elements
        
 def _simplify_nested_elements(nested_elements):
-       '''     Read through the nested elements and simplify expressions.
-               Work according to the order of operations specified above.
-               Recurse at each list, substitute constans, parse numbers, 
handle functions.
-               Make comma separated values into lists (represent vectors).
-               Return the final value of the expression.       '''
+       """!
+       Read through the nested elements and simplify expressions (recursively).
+       Work according to the order of operations.
+       Recurse at each list, substitute constans, parse numbers, handle 
functions.
+       Make comma separated values into lists to represent vectors.
+       @param nested_elements nested elements (strings and lists)
+       @throw SyntaxError bad syntax
+       @throw NameError unknown symbol
+       @return the final value of the expression.
+       """
        for i,element in enumerate(nested_elements):    
                # simplify the nested lists #
                if _is_list(element): nested_elements[i] = 
_simplify_nested_elements(element)
@@ -379,20 +432,22 @@
                elif _is_constant(element): nested_elements[i] = 
_CONSTANTS[element]
                # substitute in values for numbers #
                elif _is_number(element): nested_elements[i] = 
verify_number(element)                   
+       def comma_separate(ans):
+               if not _is_list(ans): ans = [ans]       #must be a list
+               ans_with_commas = list()
+               for an in ans: ans_with_commas.extend([an, ','])
+               return ans_with_commas[0:-1]    #remove last comma      
        # handle functions #
        for function in _FUNCTIONS.keys():
                while function in nested_elements:
                        i = nested_elements.index(function)                     
        
-                       if i+1 == len(nested_elements): raise 
SyntaxError('Function "%s" has no arguments.'%(function))
+                       if i+1 == len(nested_elements): raise SyntaxError, 
'Function "%s" has no arguments.'%(function)
                        args = nested_elements[i+1]
                        if not _is_list(args): args = [args]
                        try: ans = _FUNCTIONS[function](*args)
                        except Exception, e: 
-                               raise ValueError('Function "%s" with arguments 
"%s" failed.\n\t%s'%(function, nested_elements[i+1], e))
-                       if not _is_list(ans): ans = [ans]       # ans must be a 
list
-                       ans_with_commas = list()
-                       for an in ans: ans_with_commas.extend([an, ','])
-                       nested_elements = nested_elements[0:i] + 
ans_with_commas[0:-1] + nested_elements[i+2:]          
+                               raise SyntaxError, 'Function "%s" with 
arguments "%s" failed.\n\t%s'%(function, nested_elements[i+1], e)
+                       nested_elements = nested_elements[0:i] + 
comma_separate(ans) + nested_elements[i+2:]            
        # simplify operations #
        for operator in _ORDER_OF_OPS:
                while operator in nested_elements:
@@ -401,32 +456,33 @@
                        if i > 0: arg1 = nested_elements[i-1]
                        if i+1 < len(nested_elements): arg2 = 
nested_elements[i+1]
                        #raise error if arg1 or arg2 is None
-                       if arg1 == None or arg2 == None: raise 
SyntaxError('Operator "%s" is missing argument.'%(operator))
+                       if arg1 == None or arg2 == None: raise SyntaxError, 
'Operator "%s" is missing argument.'%(operator)
                        ans = _handle_operation(operator, arg1, arg2)
-                       if not _is_list(ans): ans = [ans]       # ans must be a 
list
-                       ans_with_commas = list()
-                       for an in ans: ans_with_commas.extend([an, ','])
-                       nested_elements = nested_elements[0:i-1] + 
ans_with_commas[0:-1] + nested_elements[i+2:]                
+                       nested_elements = nested_elements[0:i-1] + 
comma_separate(ans) + nested_elements[i+2:]          
        # convert comma separated elements into a list #
        vector = list() 
        last_element = None
        for element in nested_elements:
                if not _is_comma(element): 
                        if not _is_list(element) and not _is_number(element) 
and element not in _CONSTANTS.values(): 
-                               raise NameError('Unknown symbol 
"%s".'%(element))
-                       if last_element and not _is_comma(last_element): 
-                               raise SyntaxError('Expected comma, but found 
"%s".'%(element))
-                       vector.append(element)
-               elif _is_comma(element) and _is_comma(last_element):
-                       raise SyntaxError('Commas must be separated by 
non-commas.')
+                               raise NameError, 'Unknown symbol 
"%s".'%(element)
+                       if last_element and not _is_comma(last_element): 
#elements not separated by commas
+                               raise SyntaxError, 'Expected comma, but found 
"%s".'%(element)
+                       vector.append(element)  #good syntax, record the element
+               elif _is_comma(element) and _is_comma(last_element):    #2 
commas in a row
+                       raise SyntaxError, 'Commas must be separated by 
non-commas.'
+               elif _is_comma(element) and not last_element:   #a comma was 
the first element
+                       raise SyntaxError, 'A non-comma must precede a comma.'
                last_element = element
        if len(vector) == 1 and not _is_comma(last_element): return vector[0]   
#return single number
        return vector   #otherwise return vector
 
 def eval_expr(expr_str):
-       '''     Evaluate a mathematical expression string with numbers, and 
operators.
-               Raise an exception on failue.   
-               Return a list containing the parsed expression. '''     
+       """!
+       Evaluate a mathematical expression string with numbers, and operators.
+       @throw Exception failue 
+       @return nested data (numbers and lists)
+       """     
        separated_elements = _separate_expression(expr_str)
        #print "separated", separated_elements
        rectified_elements = _rectify_operators(separated_elements)
@@ -437,8 +493,8 @@
        return simplified
        
 if __name__ == '__main__':
-       ''' Evaluate expressions passed by argv(1).     '''
+       """Evaluate expressions passed by arg1."""
        import sys
        if len(sys.argv) > 1: print eval_expr(sys.argv[1])
-       else: print "No expressions passed!"
+       else: print "The mathematical expression parser will evaluate a string 
(in quotes) passed via the command line."
        
\ No newline at end of file

Modified: grc/trunk/src/Messages.py
===================================================================
--- grc/trunk/src/Messages.py   2007-06-29 17:29:46 UTC (rev 5877)
+++ grc/trunk/src/Messages.py   2007-06-29 17:41:26 UTC (rev 5878)
@@ -16,23 +16,28 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       Messages.py 
-       Josh Blum
-       Handle all of the system messages and error reports.
-"""
address@hidden Messages
+#Handle all of the system messages and error reports.
address@hidden Josh Blum
 
 from Constants import VERSION,PREFERENCES_FILE_PATH
+import traceback
 
-#      A list of methods that can receive a message.   #
+##     A list of methods that can receive a message.   
 MESSENGERS_LIST = list()
 
 def register_messenger(messenger):
-       """ Append the given messenger to the list of messengers.       """
+       """!
+       Append the given messenger to the list of messengers.
+       @param messenger a method thats takes a string
+       """
        MESSENGERS_LIST.append(messenger)
        
 def send(message):
-       """ Give the given message to each of the messengers.   """
+       """!
+       Give the message to each of the messengers.
+       @param message a message string
+       """
        for messenger in MESSENGERS_LIST: messenger(message)
        
 ###########################################################################
@@ -50,6 +55,7 @@
                                                        
 def send_error_load(error):
        send('>>> Error: %s\n'%error)
+       traceback.print_exc()
 
 def send_end_load():
        send(">>> Done\n")
@@ -57,14 +63,15 @@
 def send_fail_load(error):
        send('Parser Error: %s\n'%error)
        send(">>> Failue\n")            
+       traceback.print_exc()
 
-#################      methods for running flow graphs 
########################################        
-def send_start_run(file_path):
+#################      methods for executing flow graphs       
########################################        
+def send_start_exec(file_path):
        send("""\
                                                        ------------------   
Running Flow Graph   ------------------\n""")
-       send('Trying to run: "%s"'%file_path + '\n')
+       send('Trying to execute: "%s"'%file_path + '\n')
 
-def send_end_run(verbose):
+def send_end_exec(verbose):
        if verbose: 
                send(">>> Verbose:      \n")            
                for verb in verbose: send(verb)

Modified: grc/trunk/src/ParseXML.py
===================================================================
--- grc/trunk/src/ParseXML.py   2007-06-29 17:29:46 UTC (rev 5877)
+++ grc/trunk/src/ParseXML.py   2007-06-29 17:41:26 UTC (rev 5878)
@@ -16,27 +16,39 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       ParseXML.py 
-       Josh Blum
-       methods for parsing xml files to and from nested data
-"""
address@hidden ParseXML
+#Parse xml files to nested data and vice-versa.
address@hidden Josh Blum
 
 import xml.dom.minidom
 import xml.dom.ext
 
 def find_data(nested_data, my_tag):
-       """ Helper function for dealing with nested data.       """
+       """!
+       Find a tag one level deep.      
+       Helper function for dealing with nested data.   
+       @param nested_data the data to search
+       @param my_tag the tag to search for
+       @return the data associated with the tag, None if not found
+       """
        for tag,data in nested_data:
                if tag == my_tag: return data
        return None
 
 def from_xml(doc):
-       ''' Create nested data from an xml doc using the from xml helper.       
'''
+       """!
+       Create nested data from an xml doc using the from xml helper.
+       @param doc the xml doc
+       @return the nested data
+       """
        return __from_xml(doc.firstChild)
        
 def __from_xml(doc):
-       ''' Recursivly parse the xml doc into nested data format.       '''
+       """!
+       Recursivly parse the xml doc into nested data format.   
+       @param doc the xml doc
+       @return the nested data
+       """
        #print doc.nodeType,doc.localName,doc.nodeValue,doc.childNodes
        tag_name = doc.localName
        if len(doc.childNodes) == 0:
@@ -50,13 +62,22 @@
        return tag_name,nested_data     
        
 def to_xml(nested_data):
-       ''' Create an xml doc and use the to xml helper method to load it.      
'''
+       """!
+       Create an xml doc and use the to xml helper method to load it.
+       @param nested_data the nested data
+       @return the xml doc
+       """
        doc = xml.dom.minidom.Document()
        doc.appendChild(__to_xml(nested_data, doc))
        return doc
        
 def __to_xml(nested_data, doc):
-       ''' Recursivly parse the nested data into xml doc format.       '''     
+       """!
+       Recursivly parse the nested data into xml doc format.
+       @param nested_data the nested data
+       @param the xml doc
+       @return the xml doc
+       """     
        tag_name,value = nested_data
        child = doc.createElementNS(None, tag_name)
        if type(value) == type(list()):         
@@ -69,16 +90,22 @@
        return child
 
 def to_file(doc, file_path):
-       ''' Save the xml doc to the file path.  ''' 
+       """!
+       Save the xml doc to the file path.
+       @param doc the xml doc
+       @param file_path the destination xml-file
+       """ 
        xml.dom.ext.PrettyPrint(doc, open(file_path,'w'))
        
 def from_file(file_path):
-       '''     Load an xml doc from the file path.     '''
+       """!
+       Load an xml doc from the file path.
+       @param file_path the source xml-file
+       @return the xml doc
+       """
        return xml.dom.minidom.parse(open(file_path, 'r'))
 
 if __name__ == '__main__':     
-       nested = ('version', [('one',[('k','l'),('h','y')]),('two','2')])
-       xml.dom.ext.PrettyPrint(to_xml(nested), open('test.xml','w'))
-       print from_xml(xml.dom.minidom.parse(open('test.xml', 'r')))
-       print nested
+       """Use the main method to test parse xml's functions."""
+       pass
        
\ No newline at end of file

Modified: grc/trunk/src/Preferences.py
===================================================================
--- grc/trunk/src/Preferences.py        2007-06-29 17:29:46 UTC (rev 5877)
+++ grc/trunk/src/Preferences.py        2007-06-29 17:41:26 UTC (rev 5878)
@@ -16,13 +16,11 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       Preferences.py 
-       Josh Blum
-       Holds global preferences stored as GraphicalParams.
-"""
address@hidden Preferences
+#Holds global preferences stored as GraphicalParams.
address@hidden Josh Blum
 
-from DataType import Bool,FileOpen,Enum,Int
+from DataTypes import Bool,FileOpen,Enum,Int
 from Elements import GraphicalParam
 import time,socket #for tagging saved files
 from Constants import *
@@ -55,8 +53,7 @@
 #      List of Preferences
 ###########################################################################
 
-PREFS_LIST = [ #list of all prefs the be saved, restored, and displayed in the 
pref's dialog 
-#(title, notes, list of preferences)
+PREFS_LIST = [ #(title, notes, list of preferences)
        ("Verification", '', [  
                CONNECTION_CHECKING_PREF,
                PARAM_CHECKING_PREF,
@@ -91,14 +88,21 @@
 #      Preference Access Methods
 ###########################################################################
 
-def get_value(param):
-       """ If the param is valid, return the parsed value of the param.        
-               Otherwise return a blank string.        """
+def _get_value(param):
+       """!
+       Get the value of the given parameter.
+       If the param is valid, return the parsed value of the param, otherwise 
return a blank string.   
+       @param param the parameter
+       @return the value of the parameter
+       """
        if param.get_data_type().is_valid(): return 
param.get_data_type().parse()
        else: return ''
        
-def to_nested():
-       """     Convert the param's data to nested format       """
+def _to_nested():
+       """!
+       Convert the param's data to nested format.
+       @return the nested format
+       """
        categories = list()
        nested_data = ('preferences', [
                                                                                
        ('timestamp', str(time.time())),
@@ -111,8 +115,11 @@
                for param in params: prefs.append(('pref', 
param.get_data_type().get_data()))
        return nested_data
        
-def from_nested(nested_data):
-       """ Parse the nested data to retrieve each preference.  """
+def _from_nested(nested_data):
+       """!
+       Parse the nested data to retrieve each preference.
+       @param nested_data the nested data
+       """
        find_data = ParseXML.find_data
        preferences = find_data([nested_data], 'preferences')
        categories = find_data(preferences, 'categories')
@@ -125,17 +132,25 @@
                        except: pass
                
 def load(window=None):
+       """!
+       Load the preferences from the preferences file.
+       @param window optional flow graph window
+       """
        try: 
-               
from_nested(ParseXML.from_xml(ParseXML.from_file(PREFERENCES_FILE_PATH)))
-               if window: window.resize(get_value(MAIN_WINDOW_WIDTH_PREF), 
get_value(MAIN_WINDOW_HEIGHT_PREF))
+               
_from_nested(ParseXML.from_xml(ParseXML.from_file(PREFERENCES_FILE_PATH)))
+               if window: window.resize(_get_value(MAIN_WINDOW_WIDTH_PREF), 
_get_value(MAIN_WINDOW_HEIGHT_PREF))
        except: Messages.send_fail_load_preferences()           
 
 def save(window=None):
+       """!
+       Save the preferences to the preferences file.
+       @param window optional flow graph window
+       """
        if window:
                width,height = window.get_size()
                MAIN_WINDOW_WIDTH_PREF.get_data_type().set_data(width)
                MAIN_WINDOW_HEIGHT_PREF.get_data_type().set_data(height)
-       try: ParseXML.to_file(ParseXML.to_xml(to_nested()), 
PREFERENCES_FILE_PATH)              
+       try: ParseXML.to_file(ParseXML.to_xml(_to_nested()), 
PREFERENCES_FILE_PATH)             
        except IOError: Messages.send_fail_save_preferences()
                
 ###########################################################################
@@ -143,34 +158,34 @@
 ###########################################################################
 def set_default_flow_graph(file_path):
        ''' Set the new default flow graph path, only if the restore option is 
true.    '''
-       if get_value(RESTORE_FLOW_GRAPH_PREF):
+       if _get_value(RESTORE_FLOW_GRAPH_PREF):
                DEFAULT_FLOW_GRAPH_PREF.get_data_type().set_data(file_path)
 
 def get_default_flow_graph():
        ''' Get the default flow graph path. Return a blank string if the path 
is invalid.      '''
        if DEFAULT_FLOW_GRAPH_PREF.get_data_type().is_valid():
-               return get_value(DEFAULT_FLOW_GRAPH_PREF)
+               return _get_value(DEFAULT_FLOW_GRAPH_PREF)
        return ''
        
 def check_connections():
-       return get_value(CONNECTION_CHECKING_PREF)
+       return _get_value(CONNECTION_CHECKING_PREF)
        
 def check_sockets():
-       return get_value(SOCKET_CHECKING_PREF)
+       return _get_value(SOCKET_CHECKING_PREF)
 
 def check_params():
-       return get_value(PARAM_CHECKING_PREF)
+       return _get_value(PARAM_CHECKING_PREF)
        
-def show_reports_window():
-       return get_value(REPORTS_WIN_SHOW_PREF)
+def show_reports_window(window):
+       return window.show_reports_window(_get_value(REPORTS_WIN_SHOW_PREF))
        
 def get_grid_size():
-       return get_value(GRID_SIZE_PREF)        
+       return _get_value(GRID_SIZE_PREF)       
        
 def snap_to_grid():
-       return get_value(SNAP_TO_GRID_PREF)
+       return _get_value(SNAP_TO_GRID_PREF)
        
 def show_grid():
-       return get_value(SHOW_GRID_PREF)
+       return _get_value(SHOW_GRID_PREF)
                
        
\ No newline at end of file


Property changes on: grc/trunk/src/SignalBlockDefs
___________________________________________________________________
Name: svn:ignore
   - *.pyc


Modified: grc/trunk/src/SignalBlockDefs/Coders.py
===================================================================
--- grc/trunk/src/SignalBlockDefs/Coders.py     2007-06-29 17:29:46 UTC (rev 
5877)
+++ grc/trunk/src/SignalBlockDefs/Coders.py     2007-06-29 17:41:26 UTC (rev 
5878)
@@ -16,13 +16,11 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       SignalBlockDefs/Coders.py 
-       Josh Blum
-       Encode and Decode.
-"""
address@hidden SignalBlockDefs.Coders
+#Encode and decode.
address@hidden Josh Blum
 
-from DataType import *
+from DataTypes import *
 from gnuradio import gr
 
 def ConstellationDecoder(sb):

Modified: grc/trunk/src/SignalBlockDefs/Conversions.py
===================================================================
--- grc/trunk/src/SignalBlockDefs/Conversions.py        2007-06-29 17:29:46 UTC 
(rev 5877)
+++ grc/trunk/src/SignalBlockDefs/Conversions.py        2007-06-29 17:41:26 UTC 
(rev 5878)
@@ -16,26 +16,25 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       SignalBlockDefs/Conversions.py 
-       Josh Blum
-       Convert between data types.
-"""
address@hidden SignalBlockDefs.Conversions
+#Convert between data types.
address@hidden Josh Blum
 
-from DataType import *
+from DataTypes import *
 from gnuradio import gr
-from SignalBlockConstants import all_choices,all_vector_choices
-from Constants import MAX_NUM_SOCKETS
+from SignalBlockConstants import 
all_choices,all_vector_choices,default_samp_rate,MAX_NUM_SOCKETS
 
 def ComplexComponents(sb):             
        vlen = Int(1, min=1)
        sb.add_input_socket('in', Complex(), vlen=vlen)
        sb.add_output_socket('out', Float(), vlen=vlen)
-       sb.add_param('Output Type', Enum([('Real', gr.complex_to_real),
-                                                                               
                ('Imaginary', gr.complex_to_imag),
-                                                                               
                ('Magnitude', gr.complex_to_mag),
-                                                                               
                ('Magnitude Squared', gr.complex_to_mag_squared),
-                                                                               
                ('Phase Angle', gr.complex_to_arg)]), type=True)        
+       sb.add_param('Output Type', Enum([
+               ('Real', gr.complex_to_real),
+               ('Imaginary', gr.complex_to_imag),
+               ('Magnitude', gr.complex_to_mag),
+               ('Magnitude Squared', gr.complex_to_mag_squared),
+               ('Phase Angle', gr.complex_to_arg),
+       ]), type=True)  
        sb.add_param('Vector Length', vlen)
        return sb, lambda fg, type, vlen: type.parse()(vlen.parse())
        
@@ -103,9 +102,11 @@
        return sb, lambda fg: fcn()
        
 def UnpackedToPacked(sb):
-       type = Enum([('Byte', (gr.unpacked_to_packed_bb, Byte())),
-                                       ('Short', (gr.unpacked_to_packed_ss, 
Short())),
-                                       ('Int', (gr.unpacked_to_packed_ii, 
Int())),])   
+       type = Enum([
+               ('Byte', (gr.unpacked_to_packed_bb, Byte())),
+               ('Short', (gr.unpacked_to_packed_ss, Short())),
+               ('Int', (gr.unpacked_to_packed_ii, Int())),
+       ])      
        sb.add_input_socket('in', Variable(type, index=1))
        sb.add_output_socket('out', Variable(type, index=1))
        sb.add_param('Type', type, False, type=True)
@@ -115,9 +116,11 @@
        return sb, lambda fg, type, bits_per_chunk, endianness: 
type.parse()[0](bits_per_chunk.parse(), endianness.parse())
        
 def PackedToUnpacked(sb):
-       type = Enum([('Byte', (gr.packed_to_unpacked_bb, Byte())),
-                                       ('Short', (gr.packed_to_unpacked_ss, 
Short())),
-                                       ('Int', (gr.packed_to_unpacked_ii, 
Int())),])   
+       type = Enum([
+               ('Byte', (gr.packed_to_unpacked_bb, Byte())),
+               ('Short', (gr.packed_to_unpacked_ss, Short())),
+               ('Int', (gr.packed_to_unpacked_ii, Int())),
+       ])      
        sb.add_input_socket('in', Variable(type, index=1))
        sb.add_output_socket('out', Variable(type, index=1))
        sb.add_param('Type', type, False, type=True)
@@ -141,12 +144,14 @@
        
 def ChunksToSymbols(sb):
                                        #name, fcn, input, output, symbol 
table, dimensions
-       type = Enum([('Byte->Complex', (gr.chunks_to_symbols_bc, Byte(), 
Complex(), ComplexVector())),
-                                       ('Byte->Float', 
(gr.chunks_to_symbols_bf, Byte(), Float(), FloatVector())),
-                                       ('Int->Complex', 
(gr.chunks_to_symbols_ic, Int(), Complex(), ComplexVector())),
-                                       ('Int->Float', 
(gr.chunks_to_symbols_if, Int(), Float(), FloatVector())),
-                                       ('Short->Complex', 
(gr.chunks_to_symbols_sc, Short(), Complex(), ComplexVector())),
-                                       ('Short->Float', 
(gr.chunks_to_symbols_sf, Short(), Float(), FloatVector())),])
+       type = Enum([
+               ('Byte->Complex', (gr.chunks_to_symbols_bc, Byte(), Complex(), 
ComplexVector())),
+               ('Byte->Float', (gr.chunks_to_symbols_bf, Byte(), Float(), 
FloatVector())),
+               ('Int->Complex', (gr.chunks_to_symbols_ic, Int(), Complex(), 
ComplexVector())),
+               ('Int->Float', (gr.chunks_to_symbols_if, Int(), Float(), 
FloatVector())),
+               ('Short->Complex', (gr.chunks_to_symbols_sc, Short(), 
Complex(), ComplexVector())),
+               ('Short->Float', (gr.chunks_to_symbols_sf, Short(), Float(), 
FloatVector())),
+       ])
        sb.add_input_socket('in', Variable(type, index=1))
        sb.add_output_socket('out', Variable(type, index=2))
        sb.add_param('Type', type, type=True)   
@@ -161,7 +166,7 @@
        sb.add_output_socket('out', Variable(type), vlen=vlen)
        sb.add_param('Type', type, False, type=True)
        sb.add_param('Num Inputs', Int(3, min=1, max=MAX_NUM_SOCKETS), 
-                                       show_label=False, 
input_sockets_controller=True)
+               show_label=False, input_sockets_controller=True)
        sb.add_param('Vector Length', vlen)
        sb.set_docs('''1 <= Num Inputs <= %d'''%MAX_NUM_SOCKETS)        
        return sb, lambda fg, type, num_inputs, vlen: 
gr.interleave(type.parse().get_num_bytes()*vlen.parse())
@@ -173,7 +178,7 @@
        sb.add_output_socket('out', Variable(type), vlen=vlen)
        sb.add_param('Type', type, False, type=True)
        sb.add_param('Num Outputs', Int(3, min=1, max=MAX_NUM_SOCKETS), 
-                                       show_label=False, 
output_sockets_controller=True)       
+               show_label=False, output_sockets_controller=True)       
        sb.add_param('Vector Length', vlen)
        sb.set_docs('''1 <= Num Outputs <= %d'''%MAX_NUM_SOCKETS)       
        return sb, lambda fg, type, num_outputs, vlen: 
gr.deinterleave(type.parse().get_num_bytes()*vlen.parse())
@@ -186,7 +191,7 @@
        sb.add_output_socket('out', Variable(type), vlen=vlen)
        sb.add_param('Type', type, False, type=True)
        sb.add_param('Num Streams', Int(3, min=1, max=MAX_NUM_SOCKETS), 
-                                       show_label=False, 
input_sockets_controller=True)
+               show_label=False, input_sockets_controller=True)
        sb.add_param('Vector Length', vlen)
        sb.set_docs('''\
 Interleave N streams into a single stream.     
@@ -201,7 +206,7 @@
        sb.add_output_socket('out', Variable(type), vlen=vlen)
        sb.add_param('Type', type, False, type=True)
        sb.add_param('Num Streams', Int(3, min=1, max=MAX_NUM_SOCKETS), 
-                                       show_label=False, 
output_sockets_controller=True)       
+               show_label=False, output_sockets_controller=True)       
        sb.add_param('Vector Length', vlen)
        sb.set_docs('''\
 Deinterleave a stream into N streams.
@@ -216,7 +221,7 @@
        sb.add_output_socket('vout', Variable(type, index=0))
        sb.add_param('Type', type, False, type=True)
        sb.add_param('Num Streams', Int(3, min=1, max=MAX_NUM_SOCKETS), 
-                                       show_label=False, 
input_sockets_controller=True)        
+               show_label=False, input_sockets_controller=True)        
        sb.add_param('Vector Length', vlen)
        sb.set_docs('''\
 Convert N streams into a vector-stream of length N.
@@ -231,7 +236,7 @@
        sb.add_output_socket('out', Variable(type, index=1), vlen=vlen)
        sb.add_param('Type', type, False, type=True)
        sb.add_param('Num Streams', Int(3, min=1, max=MAX_NUM_SOCKETS), 
-                                       show_label=False, 
output_sockets_controller=True)       
+               show_label=False, output_sockets_controller=True)       
        sb.add_param('Vector Length', vlen)     
        sb.set_docs('''\
 Convert a vector-stream of length N into N streams.
@@ -262,4 +267,28 @@
        sb.set_docs('''Merge a vector-stream of size N into a single 
stream.''')        
        return sb, lambda fg, type, items_per_block, vlen: 
fcn(type.parse()[1].get_num_bytes()*vlen.parse(), items_per_block.parse())
        
+def Map(sb):
+       fcn = gr.map_bb
+       sb.add_input_socket('in', Byte())
+       sb.add_output_socket('out', Byte())
+       sb.add_param('Vector', IntVector(''))
+       sb.set_docs('''output[i] = map[input[i]]''')    
+       return sb, lambda fg, vector: fcn(vector.parse())
+       
+def VCO(sb):
+       fcn = gr.vco_f
+       sb.add_input_socket('in', Float())
+       sb.add_output_socket('out', Float())
+       sb.add_param('Sampling Rate', Float(default_samp_rate))
+       sb.add_param('Sensitivity', Float(1))
+       sb.add_param('Amplitude', Float(1))
+       sb.set_docs('''\
+VCO - Voltage controlled oscillator.
+
+Parameters:
+       sampling_rate   sampling rate (Hz)
+       sensitivity     units are radians/sec/volt
+       amplitude       output amplitude        
+''')   
+       return sb, lambda fg, samp_rate, sense, amp: fcn(samp_rate.parse(), 
sense.parse(), amp.parse())
        
\ No newline at end of file

Copied: grc/trunk/src/SignalBlockDefs/Custom.py (from rev 5877, 
grc/branches/jblum_work/src/SignalBlockDefs/Custom.py)
===================================================================
--- grc/trunk/src/SignalBlockDefs/Custom.py                             (rev 0)
+++ grc/trunk/src/SignalBlockDefs/Custom.py     2007-06-29 17:41:26 UTC (rev 
5878)
@@ -0,0 +1,46 @@
+"""
+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 SignalBlockDefs.Custom
+#Create your own custom blocks.
address@hidden You!
+
+from DataTypes import *
+from SignalBlockConstants import *
+from gnuradio import gr,blks
+
+###########################################################################
+#Read "creating_a_signal_block_def.txt" in the notes directory, 
+#and add your own signal block definitions below:
+###########################################################################
+
+#def CustomBlockDef1(sb):
+#...
+#...
+
+###########################################################################
+#Add custom blocks to the list below, 
+#and the blocks will appear under the "Custom" category:
+###########################################################################
+
+##custom block list
+CUSTOM_BLOCKS = [
+#('Custom Block 1', CustomBlockDef1),
+#('Custom Block 2', CustomBlockDef2),  
+]
+

Modified: grc/trunk/src/SignalBlockDefs/Filters.py
===================================================================
--- grc/trunk/src/SignalBlockDefs/Filters.py    2007-06-29 17:29:46 UTC (rev 
5877)
+++ grc/trunk/src/SignalBlockDefs/Filters.py    2007-06-29 17:41:26 UTC (rev 
5878)
@@ -16,15 +16,13 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       SignalBlockDefs/Filters.py 
-       Josh Blum
-       Taps generators are from gr.firdes. Most FIR filters are implemented 
and a few misc ones.
-"""
address@hidden SignalBlockDefs.Filters
+#Taps generators are from gr.firdes. Most FIR filters are implemented and a 
few misc ones.
address@hidden Josh Blum
 
-from DataType import *
-from gnuradio import gr
-from SignalBlockConstants import default_samp_rate,all_choices
+from DataTypes import *
+from gnuradio import gr,gru,blks
+from SignalBlockConstants import default_samp_rate,all_choices,HierHelper
 
 ###########################################################################
 #      Generic filters with taps parameters
@@ -37,13 +35,13 @@
                ('Float->Float (Float Taps)', (gr.fir_filter_fff, 
gr.interp_fir_filter_fff, Float(), Float(), FloatVector())),  
                ('Float->Short (Float Taps)', (gr.fir_filter_fsf, 
gr.interp_fir_filter_fsf, Float(), Short(), FloatVector())),  
                ('Short->Complex (Complex Taps)', (gr.fir_filter_scc, 
gr.interp_fir_filter_scc, Short(), Complex(), ComplexVector())),          
-               ])
+       ])
        sb.add_input_socket('in', Variable(filters, index=2))
        sb.add_output_socket('out', Variable(filters, index=3))
        sb.add_param('Filter Type', filters, False, type=True)
        sb.add_param('Type', Enum([('Decimating', 0), ('Interpolating', 1)]))   
#this parses into an index for the filters Enum
        sb.add_param('Decimation', Int(1, min=1))       
-       sb.add_param('Taps', Variable(filters, index=4, min=1)) 
+       sb.add_param('Taps', Variable(filters, index=4, min=1), variable=True)  
        sb.set_docs('''\
 The decimation parameter becomes interpolation if the filter type is set to 
interpolation. ''')
        def make(fg, filter_type, type, decim, taps):
@@ -57,19 +55,19 @@
                ('Complex', (gr.freq_xlating_fir_filter_ccc, 
gr.freq_xlating_fir_filter_ccf, Complex())),       
                ('Float', (gr.freq_xlating_fir_filter_fcc, 
gr.freq_xlating_fir_filter_fcf, Float())),
                ('Short', (gr.freq_xlating_fir_filter_scc, 
gr.freq_xlating_fir_filter_scf, Short())),                   
-               ])
+       ])
        taps = Enum([
                ('Complex', (0, ComplexVector())),
                ('Float', (1, FloatVector())),
-               ])
+       ])
        sb.add_input_socket('in', Variable(filters, index=2))
        sb.add_output_socket('out', Complex())
        sb.add_param('Input Type', filters, False, type=True)
        sb.add_param('Taps Type', taps) #this parses into an index for the 
filters Enum
        sb.add_param('Samp Rate', Float(default_samp_rate))
-       sb.add_param('Center Freq', Float())
+       sb.add_param('Center Freq', Float(), variable=True)
        sb.add_param('Decimation', Int(1, min=1))       
-       sb.add_param('Taps', Variable(taps, index=1, min=1))
+       sb.add_param('Taps', Variable(taps, index=1, min=1), variable=True)
        def make(fg, filter_type, taps_type, samp_rate, center_freq, decim, 
taps):
                block = 
filter_type.parse()[taps_type.parse()[0]](decim.parse(), taps.parse(), 
center_freq.parse(), samp_rate.parse())
                fg.add_callback(block.set_taps, taps)
@@ -81,12 +79,12 @@
        filters = Enum([
                ('Complex', (gr.fft_filter_ccc, Complex(), ComplexVector())),   
                ('Float', (gr.fft_filter_fff, Float(), FloatVector())),         
        
-               ])      
+       ])      
        sb.add_input_socket('in', Variable(filters, index=1))
        sb.add_output_socket('out', Variable(filters, index=1))
        sb.add_param('Type', filters, False, type=True)
        sb.add_param('Decimation', Int(1, min=1))       
-       sb.add_param('Taps', Variable(filters, index=2, min=1))
+       sb.add_param('Taps', Variable(filters, index=2, min=1), variable=True)
        sb.set_docs('''The type selection controls the data type of the input, 
output, and taps.''')
        def make(fg, type, decim, taps):
                block = type.parse()[0](decim.parse(), taps.parse())
@@ -102,13 +100,13 @@
                ('Float->Float (Float Taps)', (gr.rational_resampler_base_fff, 
Float(), Float(), FloatVector())),
                ('Float->Short (Float Taps)', (gr.rational_resampler_base_fsf, 
Float(), Short(), FloatVector())),
                ('Short->Complex (Complex Taps)', 
(gr.rational_resampler_base_scc, Short(), Complex(), ComplexVector())),
-               ])      
+       ])      
        sb.add_input_socket('in', Variable(filters, index=1))
        sb.add_output_socket('out', Variable(filters, index=2))
        sb.add_param('Filter Type', filters, False, type=True)
        sb.add_param('Interpolation', Int(1, min=1))    
        sb.add_param('Decimation', Int(1, min=1))       
-       sb.add_param('Taps', Variable(filters, index=3, min=1))
+       sb.add_param('Taps', Variable(filters, index=3, min=1), variable=True)
        def make(fg, filter_type, interp, decim, taps):
                block = filter_type.parse()[0](interp.parse(), decim.parse(), 
taps.parse())
                fg.add_callback(block.set_taps, taps)
@@ -139,6 +137,22 @@
 The delay in the real path accounts for the group delay introduced by the 
filter in the imaginary path.\
 ''')
        return sb, lambda fg, taps: fcn(taps.parse())
+       
+def ChannelModel(sb):
+       fcn = blks.channel_model
+       sb.add_input_socket('in', Complex())
+       sb.add_output_socket('out', Complex())
+       sb.add_param('Noise Voltage', Float(0.0))
+       sb.add_param('Freq Offset', Float(0.0))
+       sb.add_param('Epsilon', Float(1.0))
+       sb.add_param('Taps', ComplexVector('1.0,0.0'))
+       sb.set_docs('''Simulate channel distortion.''')
+       def make(fg, noise_voltage, frequency_offset, epsilon, taps):
+               return HierHelper(
+                       fcn(fg, noise_voltage.parse(), 
frequency_offset.parse(), epsilon.parse(), taps.parse()), 
+                       Complex().get_num_bytes(), Complex().get_num_bytes(), 
+               )
+       return sb, make
 
 ###########################################################################
 #      Special filters using taps generators
@@ -206,17 +220,17 @@
        sb.add_input_socket('in', Variable(filters, index=1))
        sb.add_output_socket('out', Variable(filters, index=2))
        sb.add_param('Filter Type', filters, type=True)
-       sb.add_param('Gain', Float(1))
-       sb.add_param('Sampling Rate', Float(default_samp_rate))
+       sb.add_param('Gain', Float(1), variable=True)
+       sb.add_param('Sampling Rate', Float(default_samp_rate), variable=True)
        if taps_maker in (gr.firdes.low_pass, gr.firdes.high_pass): 
-               sb.add_param('Cutoff Freq', Float(1000))
+               sb.add_param('Cutoff Freq', Float(1000), variable=True)
        elif taps_maker in (gr.firdes.band_pass, gr.firdes.band_reject):
-               sb.add_param('Low Cutoff Freq', Float(500))
-               sb.add_param('High Cutoff Freq', Float(1500))
-       sb.add_param('Transition Width', Float(100))            
+               sb.add_param('Low Cutoff Freq', Float(500), variable=True)
+               sb.add_param('High Cutoff Freq', Float(1500), variable=True)
+       sb.add_param('Transition Width', Float(100), variable=True)             
        sb.add_param('Decimation', Int(1, min=1))
        sb.add_param('Window Type', windows)
-       sb.add_param('Beta', Float(6.76))
+       sb.add_param('Beta', Float(6.76), variable=True)
        sb.set_docs('''\
 The decimation parameter becomes interpolation if the filter type is set to 
interpolation.''')
 
@@ -229,8 +243,8 @@
        sb.add_param('Filter Type', filters, type=True)
        sb.add_param('Decimation', Int(1, min=1))
        sb.add_param('Window Type', windows)
-       sb.add_param('Num Taps', Int(20, min=0))
-       sb.add_param('Beta', Float(6.76))
+       sb.add_param('Num Taps', Int(20, min=0), variable=True)
+       sb.add_param('Beta', Float(6.76), variable=True)
        def make(fg, filter_type, decimation, window, ntaps, beta):
                taps_args = (window, ntaps, beta)
                return make_filter(fg, filter_type, decimation, taps_maker, 
taps_args)
@@ -243,11 +257,11 @@
        sb.add_output_socket('out', Variable(filters, index=2))
        sb.add_param('Filter Type', filters, type=True)         
        sb.add_param('Decimation', Int(1, min=1))
-       sb.add_param('Gain', Float(1))
-       sb.add_param('Sampling Rate', Float(default_samp_rate), False)
-       sb.add_param('Symbol Rate', Float(100))
-       sb.add_param('Alpha', Float(6.76))
-       sb.add_param('Num Taps', Int(20, min=0))                
+       sb.add_param('Gain', Float(1), variable=True)
+       sb.add_param('Sampling Rate', Float(default_samp_rate), variable=True)
+       sb.add_param('Symbol Rate', Float(100), variable=True)
+       sb.add_param('Alpha', Float(6.76), variable=True)
+       sb.add_param('Num Taps', Int(20, min=0), variable=True)         
        def make(fg, filter_type, decimation, gain, samp_freq, symbol_rate, 
alpha, ntaps):              
                taps_args = (gain, samp_freq, symbol_rate, alpha, ntaps)
                return make_filter(fg, filter_type, decimation, taps_maker, 
taps_args)
@@ -276,8 +290,8 @@
        fcn = gr.simple_squelch_cc
        sb.add_input_socket('in', Complex())
        sb.add_output_socket('out', Complex())
-       sb.add_param('Threshold (dB)', Float(30))
-       sb.add_param('Alpha', Float(.5))
+       sb.add_param('Threshold (dB)', Float(30), variable=True)
+       sb.add_param('Alpha', Float(.5), variable=True)
        sb.set_docs('''Power levels below the threshold are not passed 
through.''')
        def make(fg, threshold, alpha):
                block = fcn(threshold.parse(), alpha.parse())
@@ -288,12 +302,14 @@
        
 def SinglePoleIIRFilter(sb):
        vlen = Int(1, min=1)
-       type = Enum([('Float', (gr.single_pole_iir_filter_ff, Float())),
-                                       ('Complex', 
(gr.single_pole_iir_filter_cc, Complex())),])
+       type = Enum([
+               ('Float', (gr.single_pole_iir_filter_ff, Float())),
+               ('Complex', (gr.single_pole_iir_filter_cc, Complex())),
+       ])
        sb.add_input_socket('in', Variable(type, index=1))
        sb.add_output_socket('out', Variable(type, index=1), vlen=vlen)
        sb.add_param('Type', type, False, type=True)
-       sb.add_param('Alpha', Float(1))
+       sb.add_param('Alpha', Float(1), variable=True)
        sb.add_param('Vector Length', vlen)
        def make(fg, type, alpha, vlen):
                block = type.parse()[0](alpha.parse(), vlen.parse())
@@ -325,6 +341,15 @@
        sb.add_param('Max Gain', Float(0))      
        return sb, lambda fg, type, attack_rate, decay_rate, ref, gain, 
max_gain: \
                type.parse()[0](attack_rate.parse(), decay_rate.parse(), 
ref.parse(), gain.parse(), max_gain.parse())
+               
+def FeedForwardAGC(sb):
+       fcn = gr.feedforward_agc_cc
+       sb.add_input_socket('in', Complex())
+       sb.add_output_socket('out', Complex())
+       sb.add_param('Num Samples', Int(100, min=1))
+       sb.add_param('Reference', Float(0))
+       sb.set_docs('''Non-causal AGC which computes required gain based on max 
absolute value over nsamples.''')
+       return sb, lambda fg, nsamps, ref: fcn(nsamps.parse(), ref.parse())     
        
 def CMAFilter(sb):
        fcn = gr.cma_equalizer_cc
@@ -337,15 +362,17 @@
        return sb, lambda fg, num_taps, mod, mu: fcn(num_taps.parse(), 
mod.parse(), mu.parse())
        
 def ClockRecovery(sb):
-       type = Enum([('Complex', (gr.clock_recovery_mm_cc, Complex())),
-                                       ('Float', (gr.clock_recovery_mm_ff, 
Float())),])
+       type = Enum([
+               ('Complex', (gr.clock_recovery_mm_cc, Complex())),
+               ('Float', (gr.clock_recovery_mm_ff, Float())),
+       ])
        sb.add_input_socket('in', Variable(type, index=1))
        sb.add_output_socket('out', Variable(type, index=1))
        sb.add_param('Type', type, False, type=True)
-       sb.add_param('Omega', Float())
-       sb.add_param('Gain Omega', Float())
-       sb.add_param('Mu', Float())
-       sb.add_param('Gain Mu', Float())
+       sb.add_param('Omega', Float(), variable=True)
+       sb.add_param('Gain Omega', Float(), variable=True)
+       sb.add_param('Mu', Float(), variable=True)
+       sb.add_param('Gain Mu', Float(), variable=True)
        sb.add_param('Omega Relative Limit', Float())
        sb.set_docs('''Mueller & Mueller clock recovery.''')
        def make(fg, type, omega, gain_omega, mu, gain_mu, omega_rel_limit): 
@@ -359,16 +386,18 @@
        
 def FFT(sb):
        taps_maker = gr.firdes.window
-       type = Enum([('Complex', (gr.fft_vcc, ComplexVector())),
-                                       ('Float', (gr.fft_vfc, 
FloatVector())),])
+       type = Enum([
+               ('Complex', (gr.fft_vcc, ComplexVector())),
+               ('Float', (gr.fft_vfc, FloatVector())),
+       ])
        sb.add_input_socket('vin', Variable(type, index=1))
        sb.add_output_socket('vout', ComplexVector())
        sb.add_param('Input Type', type, False, type=True)
        sb.add_param('FFT Size', Int(512, min=1))
        sb.add_param('Window', Enum(window_choices, 1)) 
        sb.add_param('Beta', Float(6.76))
-       return sb, lambda fg, type, size, window, beta: 
type.parse()[0](size.parse(), True, 
-                                                                               
        taps_maker(window.parse(), size.parse(), beta.parse()))
+       return sb, lambda fg, type, size, window, beta: \
+               type.parse()[0](size.parse(), True, taps_maker(window.parse(), 
size.parse(), beta.parse()))
 
 def IFFT(sb):
        fcn = gr.fft_vcc
@@ -378,14 +407,15 @@
        sb.add_param('FFT Size', Int(512, min=1))
        sb.add_param('Window', Enum(window_choices, 1), type=True)      
        sb.add_param('Beta', Float(6.76))
-       return sb, lambda fg, size, window, beta: fcn(size.parse(), False, 
-                                                                               
                                        taps_maker(window.parse(), 
-                                                                               
                                        size.parse(), beta.parse()))
+       return sb, lambda fg, size, window, beta: \
+               fcn(size.parse(), False, taps_maker(window.parse(), 
size.parse(), beta.parse()))
                                                                                
                                        
 def Upsample(sb):
        taps_maker = gr.firdes.window
-       type = Enum([('Complex', (gr.rational_resampler_base_ccf, Complex())),
-                                       ('Float', 
(gr.rational_resampler_base_fff, Float())),], 1)
+       type = Enum([
+               ('Complex', (gr.rational_resampler_base_ccf, Complex())),
+               ('Float', (gr.rational_resampler_base_fff, Float())),
+       ], 1)
        sb.add_input_socket('in', Variable(type, index=1))      
        sb.add_output_socket('out', Variable(type, index=1))    
        sb.add_param('Type', type, False, type=True)
@@ -401,7 +431,7 @@
        sb.add_input_socket('in', Variable(type))
        sb.add_output_socket('out', Variable(type))
        sb.add_param('Type', type, False, type=True)
-       sb.add_param('Decimation (M)', Int(1, min=1))
+       sb.add_param('Decimation (M)', Int(1, min=1), variable=True)
        sb.set_docs('''\
 Reduce the sample rate by keeping every Mth sample.
 >>> Implements the gr.keep_one_in_n block.''')
@@ -413,11 +443,11 @@
        return sb, make
 
 def FractionalResampler(sb):
-       from gnuradio import gru, blks
+       lcm = gru.lcm 
        filters = Enum([
                ('Complex', (blks.rational_resampler_ccc, Complex())),
                ('Float', (blks.rational_resampler_fff, Float())),
-               ], 1)
+       ], 1)
        sb.add_input_socket('in', Variable(filters, index=1))
        sb.add_output_socket('out', Variable(filters, index=1))
        sb.add_param('Type', filters, False, type=True)
@@ -431,7 +461,25 @@
        def make(fg, filter_type, inrate, outrate, fractional_bw):
                in_rate = inrate.parse()
                out_rate = outrate.parse()
-               interp = int(gru.lcm(in_rate, out_rate)/in_rate)
-               decim = int(gru.lcm(in_rate, out_rate)/out_rate)
-               return filter_type.parse()[0](fg, interp, decim, taps=None, 
fractional_bw=fractional_bw.parse())
+               interp = int(lcm(in_rate, out_rate)/in_rate)
+               decim = int(lcm(in_rate, out_rate)/out_rate)
+               return HierHelper(
+                       filter_type.parse()[0](fg, interp, decim, taps=None, 
fractional_bw=fractional_bw.parse()),
+                       filter_type.parse()[1].get_num_bytes(), 
filter_type.parse()[1].get_num_bytes(), 
+               )
        return sb, make
+       
+def FractionalInterpolator(sb):
+       filters = Enum([
+               ('Complex', (gr.fractional_interpolator_cc, Complex())),
+               ('Float', (gr.fractional_interpolator_ff, Float())),
+       ], 1)
+       sb.add_input_socket('in', Variable(filters, index=1))
+       sb.add_output_socket('out', Variable(filters, index=1))
+       sb.add_param('Type', filters, False, type=True)
+       sb.add_param('Phase Shift', Float())
+       sb.add_param('Interp Ratio', Float())   
+       def make(fg, filter_type, phase_shit, interp_ratio):
+               return filter_type.parse()[0](phase_shift.parse(), 
interp_ratio.parse())
+       return sb, make
+       

Modified: grc/trunk/src/SignalBlockDefs/GraphicalSinks.py
===================================================================
--- grc/trunk/src/SignalBlockDefs/GraphicalSinks.py     2007-06-29 17:29:46 UTC 
(rev 5877)
+++ grc/trunk/src/SignalBlockDefs/GraphicalSinks.py     2007-06-29 17:41:26 UTC 
(rev 5878)
@@ -16,15 +16,13 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       SignalBlockDefs/GraphicalSinks.py 
-       Josh Blum
-       Various graphical sinks.
-"""
address@hidden SignalBlockDefs.GraphicalSinks
+#Various graphical sinks.
address@hidden Josh Blum
 
-from DataType import *
+from DataTypes import *
 from gnuradio import gr
-from SignalBlockConstants import default_samp_rate
+from SignalBlockConstants import default_samp_rate,ThrottleHelper,HierHelper
 
 number_display_pritority = 0
 fft_display_priority = 1
@@ -34,14 +32,16 @@
 
 def FFTSink(sb):
        from gnuradio.wxgui import fftsink
-       type = Enum([('Complex', (fftsink.fft_sink_c, Complex())),
-                                       ('Float', (fftsink.fft_sink_f, 
Float())),], 1)
+       type = Enum([
+               ('Complex', (fftsink.fft_sink_c, Complex())),
+               ('Float', (fftsink.fft_sink_f, Float())),
+       ], 1)
        sb.add_input_socket('in', Variable(type, index=1))
        sb.add_param('Type', type, False, type=True)
        sb.add_param('Title', String('FFT'))    
        sb.add_param('Sampling Rate', Int(default_samp_rate))
-       sb.add_param('Y per div', Int(20))
-       sb.add_param('Reference Level', Int(20))
+       sb.add_param('Y per div', Int(20), variable=True)
+       sb.add_param('Reference Level', Int(20), variable=True)
        sb.add_param('FFT Size', Int(512))      
        sb.add_param('FFT Rate', Int(15))       
        sb.add_param('Options', Enum([('Off', None), ('Average Values', 1), 
('Peak Hold', 2)]))
@@ -58,20 +58,20 @@
                fg.add_window(block.win, fft_display_priority, title.parse())
                fg.add_callback(block.set_ref_level, ref_lvl)
                fg.add_callback(block.set_y_per_div, y_per_div)
-               th = gr.throttle(type.parse()[1].get_num_bytes(), 
samp_rate.parse())
-               fg.connect(th, block)
-               return th
+               return ThrottleHelper(type.parse()[1].get_num_bytes(), 
samp_rate.parse(), HierHelper(block, type.parse()[1].get_num_bytes()), True)
        return sb, make
        
 def WaterfallSink(sb):
        from gnuradio.wxgui import waterfallsink
-       type = Enum([('Complex', (waterfallsink.waterfall_sink_c, Complex())),
-                                       ('Float', 
(waterfallsink.waterfall_sink_f, Float())),], 1)
+       type = Enum([
+               ('Complex', (waterfallsink.waterfall_sink_c, Complex())),
+               ('Float', (waterfallsink.waterfall_sink_f, Float())),
+       ], 1)
        sb.add_input_socket('in', Variable(type, index=1))
        sb.add_param('Type', type, False, type=True)
        sb.add_param('Title', String('Waterfall'))
        sb.add_param('Sampling Rate', Int(default_samp_rate))
-       sb.add_param('Baseband Freq', Int(0))
+       sb.add_param('Baseband Freq', Int(0), variable=True)
        sb.add_param('Y per div', Int(20))
        sb.add_param('Reference Level', Int(20))
        sb.add_param('FFT Size', Int(512))      
@@ -87,15 +87,15 @@
                block.set_average(average)                      #set the 
average option outside the contructor
                fg.add_window(block.win, waterfall_display_priority, 
title.parse())
                fg.add_callback(block.set_baseband_freq, baseband_freq)
-               th = gr.throttle(type.parse()[1].get_num_bytes(), 
samp_rate.parse())
-               fg.connect(th, block)
-               return th
+               return ThrottleHelper(type.parse()[1].get_num_bytes(), 
samp_rate.parse(), HierHelper(block, type.parse()[1].get_num_bytes()), True)
        return sb, make
        
 def ScopeSink(sb):
        from gnuradio.wxgui import scopesink
-       type = Enum([('Complex', (scopesink.scope_sink_c, Complex())),
-                                       ('Float', (scopesink.scope_sink_f, 
Float())),], 1)
+       type = Enum([
+               ('Complex', (scopesink.scope_sink_c, Complex())),
+               ('Float', (scopesink.scope_sink_f, Float())),
+       ], 1)
        sb.add_input_socket('in', Variable(type, index=1))
        sb.add_param('Type', type, False, type=True)
        sb.add_param('Title', String('Scope'))
@@ -114,14 +114,12 @@
                        sample_rate=samp_rate.parse(), 
frame_decim=frame_decim.parse(), 
                        v_scale=v_scale, t_scale=t_scale.parse())
                fg.add_window(block.win, scope_display_priority, title.parse()) 
-               th = gr.throttle(type.parse()[1].get_num_bytes(), 
samp_rate.parse())
-               fg.connect(th, block)
-               return th
+               return ThrottleHelper(type.parse()[1].get_num_bytes(), 
samp_rate.parse(), HierHelper(block, type.parse()[1].get_num_bytes()), True)
        return sb, make
        
 def ConstellationSink(sb):
        from gnuradio.wxgui import scopesink
-       fcn = scopesink.scope_sink_c
+       fcn = scopesink.scope_sink_c    #dont tell anyone that its really a 
scope sink
        sb.add_input_socket('in', Complex())
        sb.add_param('Title', String('Constellation'))
        sb.add_param('Sampling Rate', Int(default_samp_rate))   
@@ -138,26 +136,26 @@
                elif marker == 1: block.win.set_format_dot()
                elif marker == 2: block.win.set_format_line()
                fg.add_window(block.win, constellation_display_pritority, 
title.parse())        
-               th = gr.throttle(Complex().get_num_bytes(), samp_rate.parse())
-               fg.connect(th, block)
-               return th
+               return ThrottleHelper(Complex().get_num_bytes(), 
samp_rate.parse(), HierHelper(block, Complex().get_num_bytes()), True)
        return sb, make
 
 def NumericalSink(sb):
        from gnuradio.wxgui import numbersink
-       type = Enum([('Complex', (numbersink.number_sink_c, Complex())),
-                                       ('Float', (numbersink.number_sink_f, 
Float())),], 1)
+       type = Enum([
+               ('Complex', (numbersink.number_sink_c, Complex())),
+               ('Float', (numbersink.number_sink_f, Float())),
+       ], 1)
        sb.add_input_socket('in', Variable(type, index=1))
        sb.add_param('Type', type, False, type=True)
        sb.add_param('Title', String('Number'))
        sb.add_param('Unit', String('Units'))
        sb.add_param('Sampling Rate', Int(default_samp_rate))
-       sb.add_param('Base Value', Float(0.0))
+       sb.add_param('Base Value', Float(0.0), variable=True)
        sb.add_param('Min Value', Float(-100))
        sb.add_param('Max Value', Float(100))
        sb.add_param('Factor', Float(1.0))
-       sb.add_param('Decimal Places', Int(6))
-       sb.add_param('Reference Level', Int(50))
+       sb.add_param('Decimal Places', Int(6), variable=True)
+       sb.add_param('Reference Level', Int(50), variable=True)
        sb.add_param('Number Rate', Int(15))    
        sb.add_param('Options', Enum([('Off', None), ('Average Values', 1), 
('Peak Hold', 2)]))
        sb.add_param('Gauge', Bool(true='Show', false='Hide', default=True))
@@ -178,9 +176,7 @@
                fg.add_callback(block.set_base_value, base)
                fg.add_callback(block.set_ref_level, ref_lvl)
                fg.add_callback(block.set_decimal_places, decimals)
-               th = gr.throttle(type.parse()[1].get_num_bytes(), 
samp_rate.parse())
-               fg.connect(th, block)
-               return th
+               return ThrottleHelper(type.parse()[1].get_num_bytes(), 
samp_rate.parse(), HierHelper(block, type.parse()[1].get_num_bytes()), True)
        return sb, make
                
        
\ No newline at end of file

Modified: grc/trunk/src/SignalBlockDefs/Misc.py
===================================================================
--- grc/trunk/src/SignalBlockDefs/Misc.py       2007-06-29 17:29:46 UTC (rev 
5877)
+++ grc/trunk/src/SignalBlockDefs/Misc.py       2007-06-29 17:41:26 UTC (rev 
5878)
@@ -16,16 +16,14 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       SignalBlockDefs/Misc.py 
-       Josh Blum
-       These blocks were not categorized. Try to keep the number of misc 
blocks small.
-"""
address@hidden SignalBlockDefs.Misc
+#These blocks were not categorized. Try to keep the number of misc blocks 
small.
address@hidden Josh Blum
 
-from DataType import *
-from gnuradio import gr
-from SignalBlockConstants import default_samp_rate,all_choices
-from Constants import MAX_NUM_SOCKETS
+import gnuradio.gr.gr_threading as threading
+from DataTypes import *
+from gnuradio import gr,blks
+from SignalBlockConstants import default_samp_rate,all_choices,MAX_NUM_SOCKETS
 
 def Throttle(sb):
        fcn = gr.throttle
@@ -64,13 +62,14 @@
        return sb, lambda fg, type, num_items, vlen: 
fcn(type.parse().get_num_bytes()*vlen.parse(), num_items.parse())
        
 def RMS(sb):
-       type = Enum([('Complex', (gr.rms_cf, Complex())),
-                                       ('Float', (gr.rms_ff, Float())),
-                                       ], 1)
+       type = Enum([
+               ('Complex', (gr.rms_cf, Complex())),
+               ('Float', (gr.rms_ff, Float())),
+       ], 1)
        sb.add_input_socket('in', Variable(type, index=1))
        sb.add_output_socket('out', Float())
        sb.add_param('Input Type', type, False, type=True)
-       sb.add_param('Alpha', Float(0.0001))
+       sb.add_param('Alpha', Float(0.0001), variable=True)
        def make(fg, type, alpha):
                block = type.parse()[0](alpha.parse())
                fg.add_callback(block.set_alpha, alpha)
@@ -85,3 +84,140 @@
 def Note(sb):
        sb.add_param('Note', String(''))
        return sb, lambda *args: None   
+
+#######################################################################################
+##     Selector Def, and Helper Block
+#######################################################################################
+
+class SelectorHelper(gr.hier_block2):
+       """A hier2 block with N inputs and M outputs, where data is only 
forwarded through input n to output m."""
+       def __init__(self, item_size, num_inputs, num_outputs, input_index, 
output_index):      
+               """!
+               SelectorHelper constructor.
+               @param item_size the size of the gr data stream in bytes
+               @param num_inputs the number of inputs (integer)
+               @param num_outputs the number of outputs (integer)
+               @param input_index the index for the source data
+               @param output_index the index for the destination data
+               """     
+               gr.hier_block2.__init__(
+                       self, 'selector', 
+                       gr.io_signature(num_inputs, num_inputs, item_size), 
+                       gr.io_signature(num_outputs, num_outputs, item_size)
+               )
+               #terminator blocks for unused inputs and outputs        
+               self.input_terminators = [gr.null_sink(item_size) for i in 
range(num_inputs)]
+               self.output_terminators = [gr.head(item_size, 0) for i in 
range(num_outputs)]           
+               self.copy = None
+               #connections            
+               for i in range(num_inputs): self.connect((self, i), 
self.input_terminators[i])
+               for i in range(num_outputs): 
self.connect(gr.null_source(item_size), self.output_terminators[i], (self, i))  
   
+               self.item_size = item_size              
+               self.input_index = input_index
+               self.output_index = output_index        
+               self.num_inputs = num_inputs
+               self.num_outputs = num_outputs
+               self._connect_current()
+               
+       def _indexes_valid(self):
+               """!
+               Are the input and output indexes within range of the number of 
inputs and outputs?
+               @return true if input index and output index are in range
+               """
+               return self.input_index in range(self.num_inputs) and 
self.output_index in range(self.num_outputs)
+               
+       def _connect_current(self):
+               """If the input and output indexes are valid: 
+               disconnect the blocks at the input and output index from their 
terminators, 
+               and connect them to one another. Then connect the terminators 
to one another."""
+               if self._indexes_valid():
+                       self.disconnect((self, self.input_index), 
self.input_terminators[self.input_index])                             
+                       
self.disconnect(self.output_terminators[self.output_index], (self, 
self.output_index))
+                       self.copy = gr.skiphead(self.item_size, 0)
+                       self.connect((self, self.input_index), self.copy)
+                       self.connect(self.copy, (self, self.output_index))      
        
+                       
self.connect(self.output_terminators[self.output_index], 
self.input_terminators[self.input_index])      
+               
+       def _disconnect_current(self):
+               """If the input and output indexes are valid: 
+               disconnect the blocks at the input and output index from one 
another, 
+               and the terminators at the input and output index from one 
another.
+               Reconnect the blocks to the terminators."""
+               if self._indexes_valid():
+                       self.disconnect((self, self.input_index), self.copy)
+                       self.disconnect(self.copy, (self, self.output_index))
+                       
self.disconnect(self.output_terminators[self.output_index], 
self.input_terminators[self.input_index])
+                       del self.copy                   
+                       self.copy = None                        
+                       self.connect((self, self.input_index), 
self.input_terminators[self.input_index])
+                       
self.connect(self.output_terminators[self.output_index], (self, 
self.output_index))
+               
+       def set_input_index(self, input_index):
+               """!
+               Change the block to the new input index if the index changed.
+               @param input_index the new input index
+               """
+               if self.input_index != input_index:
+                       self._hb.lock()
+                       self._disconnect_current()
+                       self.input_index = input_index
+                       self._connect_current()
+                       self._hb.unlock()               
+               
+       def set_output_index(self, output_index):
+               """!
+               Change the block to the new output index if the index changed.
+               @param output_index the new output index
+               """             
+               if self.output_index != output_index:   
+                       self._hb.lock()
+                       self._disconnect_current()
+                       self.output_index = output_index
+                       self._connect_current()                 
+                       self._hb.unlock()               
+                       
+def Selector(sb):
+       type = Enum(all_choices, 1)
+       vlen = Int(1, min=1)
+       sb.add_input_socket('in', Variable(type), vlen=vlen)
+       sb.add_output_socket('out', Variable(type), vlen=vlen)
+       sb.add_param('Type', type, False, type=True)
+       sb.add_param('Input Index', Int(0), variable=True)
+       sb.add_param('Output Index', Int(0), variable=True)     
+       sb.add_param('Num Inputs', Int(1, min=1, max=MAX_NUM_SOCKETS), 
+               show_label=False, input_sockets_controller=True)
+       sb.add_param('Num Outputs', Int(1, min=1, max=MAX_NUM_SOCKETS), 
+               show_label=False, output_sockets_controller=True)
+       sb.add_param('Vector Length', vlen)
+       sb.set_docs('''Forward data from the input index to the output 
index.''')       
+       def make(fg, type, input_index, output_index, num_inputs, num_outputs, 
vlen):
+               item_size = type.parse().get_num_bytes()*vlen.parse()
+               block = SelectorHelper(
+                       item_size, 
+                       num_inputs.parse(), 
+                       num_outputs.parse(), 
+                       input_index.parse(), 
+                       output_index.parse(),
+               )
+               fg.add_callback(block.set_input_index, input_index)
+               fg.add_callback(block.set_output_index, output_index)
+               return block
+       return sb, make
+
+def Valve(sb):
+       type = Enum(all_choices, 1)
+       vlen = Int(1, min=1)
+       sb.add_input_socket('in', Variable(type), vlen=vlen)
+       sb.add_output_socket('out', Variable(type), vlen=vlen)
+       sb.add_param('Type', type, False, type=True)
+       sb.add_param('Open', Int(0), variable=True)     
+       sb.add_param('Vector Length', vlen)
+       sb.set_docs('''When open is 0, the valve will forward data.''') 
+       def make(fg, type, open, vlen):
+               item_size = type.parse().get_num_bytes()*vlen.parse()
+               block = SelectorHelper(fg, item_size, 1, 1, 0, open.parse())
+               fg.add_callback(block.set_output_index, open)
+               return block
+       return sb, make
+       
+       
\ No newline at end of file

Modified: grc/trunk/src/SignalBlockDefs/Modulators.py
===================================================================
--- grc/trunk/src/SignalBlockDefs/Modulators.py 2007-06-29 17:29:46 UTC (rev 
5877)
+++ grc/trunk/src/SignalBlockDefs/Modulators.py 2007-06-29 17:41:26 UTC (rev 
5878)
@@ -16,36 +16,39 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       SignalBlockDefs/Modulations.py 
-       Josh Blum
-       Various modulation schemes.
-"""
address@hidden SignalBlockDefs.Modulations
+#Various modulation schemes.
address@hidden Josh Blum
 
-from DataType import *
+from DataTypes import *
 from gnuradio import gr
+from SignalBlockConstants import HierHelper
 
-def FrequencyModulation(sb):
+def FrequencyMod(sb):
        fcn = gr.frequency_modulator_fc
        sb.add_input_socket('in', Float())
        sb.add_output_socket('out', Complex())  
        sb.add_param('Sensitivity', Float(.01)) 
        return sb, lambda fg, sensitivity: fcn(sensitivity.parse())
        
-def PhaseModulation(sb):
+def PhaseMod(sb):
        fcn = gr.phase_modulator_fc
        sb.add_input_socket('in', Float())
        sb.add_output_socket('out', Complex())  
        sb.add_param('Sensitivity', Float(.01)) 
        return sb, lambda fg, sensitivity: fcn(sensitivity.parse())
        
-def QuadratureDemodulation(sb):
+def QuadratureDemod(sb):
        fcn = gr.quadrature_demod_cf
        sb.add_input_socket('in', Complex())
        sb.add_output_socket('out', Float())    
        sb.add_param('Gain', Float(1))  
-       return sb, lambda fg, gain: fcn(gain.parse())   
+       return sb, lambda fg, gain: fcn(gain.parse())
        
+###########################################################################
+#      Narrow band and Wide band FM
+###########################################################################    
        
+       
 def WFMReceive(sb):
        from gnuradio import blks
        fcn = blks.wfm_rcv
@@ -56,7 +59,8 @@
        sb.set_docs('''\
 Wide Band FM Receiver.
 The audio rate is the quad rate/audio decimation.''')
-       return sb, lambda fg, quad_rate, audio_dec: fcn(fg, quad_rate.parse(), 
audio_dec.parse())       
+       return sb, lambda fg, quad_rate, audio_dec: \
+               HierHelper(fcn(fg, quad_rate.parse(), audio_dec.parse()), 
Complex().get_num_bytes(), Float().get_num_bytes())
        
 def WFMTransmit(sb):
        from gnuradio import blks
@@ -76,7 +80,7 @@
                #       make sure that the quad rate is an integer multiple of 
the audio rate   #
                audio_rate = quad_rate/audio_decimation
                quad_rate = audio_decimation * (quad_rate/audio_decimation)
-               return fcn(fg, audio_rate, quad_rate, tau.parse(), 
max_dev.parse())
+               return HierHelper(fcn(fg, audio_rate, quad_rate, tau.parse(), 
max_dev.parse()), Float().get_num_bytes(), Complex().get_num_bytes())
        return sb, make
        
 def NBFMReceive(sb):
@@ -97,7 +101,7 @@
                #       make sure that the quad rate is an integer multiple of 
the audio rate   #
                audio_rate = quad_rate/audio_decimation
                quad_rate = audio_decimation * (quad_rate/audio_decimation)
-               return fcn(fg, audio_rate, quad_rate, tau.parse(), 
max_dev.parse())
+               return HierHelper(fcn(fg, audio_rate, quad_rate, tau.parse(), 
max_dev.parse()), Complex().get_num_bytes(), Float().get_num_bytes())
        return sb, make 
        
 def NBFMTransmit(sb):
@@ -118,9 +122,13 @@
                #       make sure that the quad rate is an integer multiple of 
the audio rate   #
                audio_rate = quad_rate/audio_decimation
                quad_rate = audio_decimation * (quad_rate/audio_decimation)
-               return fcn(fg, audio_rate, quad_rate, tau.parse(), 
max_dev.parse())
+               return HierHelper(fcn(fg, audio_rate, quad_rate, tau.parse(), 
max_dev.parse()), Float().get_num_bytes(), Complex().get_num_bytes())
        return sb, make 
                
+###########################################################################
+#      AM and FM demodulation
+###########################################################################    
                
+               
 def AMDemod(sb):
        from gnuradio import blks
        fcn = blks.am_demod_cf
@@ -130,7 +138,8 @@
        sb.add_param('Audio Decimation', Int(1, min=1)) 
        sb.add_param('Audio Passband (Hz)', Float(5e3))
        sb.add_param('Audio Stopband (Hz)', Float(5.5e3))
-       return sb, lambda fg, *args: fcn(fg, *map(lambda a: a.parse(), args))
+       return sb, lambda fg, *args: \
+               HierHelper(fcn(fg, *map(lambda a: a.parse(), args)), 
Complex().get_num_bytes(), Float().get_num_bytes())
                
 def FMDemod(sb):
        from gnuradio import blks
@@ -144,55 +153,114 @@
        sb.add_param('Audio Stopband (Hz)', Float(4e3))
        sb.add_param('Gain', Float(1))
        sb.add_param('Tau', Float(75e-6))
-       return sb, lambda fg, *args: fcn(fg, *map(lambda a: a.parse(), args))
+       return sb, lambda fg, *args: \
+               HierHelper(fcn(fg, *map(lambda a: a.parse(), args)), 
Complex().get_num_bytes(), Float().get_num_bytes())
        
+###########################################################################
+#      Phase shift keying
+###########################################################################    
+       
 def PSKMod(sb):
        from gnuradio import blks
        sb.add_input_socket('in', Byte())
        sb.add_output_socket('out', Complex())  
-       sb.add_param('Type', Enum([('DBPSK', blks.dbpsk_mod), ('DQPSK', 
blks.dqpsk_mod)]), type=True)
-       sb.add_param('Samples/Symbol', Int(2, min=1))
+       sb.add_param('Type', Enum([
+               ('DBPSK', blks.dbpsk_mod), 
+               ('DQPSK', blks.dqpsk_mod),
+               ('D8PSK', blks.d8psk_mod),
+       ]), type=True)
+       sb.add_param('Samples/Symbol', Int(2, min=2))
        sb.add_param('Excess BW', Float(0.35))
-       sb.add_param('Use Gray Code', Enum([('Yes', True), ('No', False)]))
-       return sb, lambda fg, type, *args: type.parse()(fg, *map(lambda a: 
a.parse(), args))
+       sb.add_param('Use Gray Code', Bool(true='Yes', false='No', 
default=True))
+       return sb, lambda fg, type, *args: \
+               HierHelper(type.parse()(fg, *map(lambda a: a.parse(), args)), 
Byte().get_num_bytes(), Complex().get_num_bytes())
        
 def PSKDemod(sb):
        from gnuradio import blks
        sb.add_input_socket('in', Complex())
        sb.add_output_socket('out', Byte())     
-       sb.add_param('Type', Enum([('DBPSK', blks.dbpsk_demod), ('DQPSK', 
blks.dqpsk_demod)]), type=True)
-       sb.add_param('Samples/Symbol', Int(2, min=1))
+       sb.add_param('Type', Enum([
+               ('DBPSK', blks.dbpsk_demod), 
+               ('DQPSK', blks.dqpsk_demod),
+               ('D8PSK', blks.d8psk_demod),
+       ]), type=True)
+       sb.add_param('Samples/Symbol', Int(2, min=2))
        sb.add_param('Excess BW', Float(0.35))
        sb.add_param('Costas Alpha', Float(0.03))
        sb.add_param('Gain Mu', Float(0.05))
        sb.add_param('Mu', Float(0.005))
        sb.add_param('Omega Relative Limit', Float(0.05))
-       sb.add_param('Use Gray Code', Enum([('Yes', True), ('No', False)]))
-       return sb, lambda fg, type, *args: type.parse()(fg, *map(lambda a: 
a.parse(), args))
+       sb.add_param('Use Gray Code', Bool(true='Yes', false='No', 
default=True))
+       return sb, lambda fg, type, *args: \
+               HierHelper(type.parse()(fg, *map(lambda a: a.parse(), args)), 
Complex().get_num_bytes(), Byte().get_num_bytes())
+
+###########################################################################
+#      Gaussian minimum shift keying
+###########################################################################    
        
 def GMSKMod(sb):
        from gnuradio import blks
        fcn = blks.gmsk_mod
        sb.add_input_socket('in', Byte())
        sb.add_output_socket('out', Complex())  
-       sb.add_param('Samples/Symbol', Int(2, min=1))
+       sb.add_param('Samples/Symbol', Int(2, min=2))
        sb.add_param('Filter BW', Float(0.35))
-       return sb, lambda fg, *args: fcn(fg, *map(lambda a: a.parse(), args))
+       return sb, lambda fg, *args: \
+               HierHelper(fcn(fg, *map(lambda a: a.parse(), args)), 
Byte().get_num_bytes(), Complex().get_num_bytes())
        
 def GMSKDemod(sb):
        from gnuradio import blks
        fcn = blks.gmsk_demod
        sb.add_input_socket('in', Complex())
        sb.add_output_socket('out', Byte())     
-       sb.add_param('Samples/Symbol', Int(2, min=1))
+       sb.add_param('Samples/Symbol', Int(2, min=2))
        sb.add_param('Gain Mu', Float(0.05))
        sb.add_param('Mu', Float(0.5, min=0, max=1))
        sb.add_param('Omega Relative Limit', Float(0.005))
        sb.add_param('Frequency Error', Float(0))
        sb.set_docs('''Mu is the fractional delay between 0 and 1''')
-       return sb, lambda fg, *args: fcn(fg, *map(lambda a: a.parse(), args))
+       return sb, lambda fg, *args: \
+               HierHelper(fcn(fg, *map(lambda a: a.parse(), args)), 
Complex().get_num_bytes(), Byte().get_num_bytes())
        
 ###########################################################################
+#      Quadrature amplitude modulation
+###########################################################################
+       
+def QAMMod(sb):
+       from gnuradio import blks
+       sb.add_input_socket('in', Byte())
+       sb.add_output_socket('out', Complex())  
+       sb.add_param('Type', Enum([
+               ('QAM 8', blks.qam8_mod), 
+               ('QAM 64', blks.qam64_mod),
+               ('QAM 256', blks.qam256_mod),
+       ]), type=True)
+       sb.add_param('Samples/Symbol', Int(2, min=2))
+       sb.add_param('Excess BW', Float(0.35))
+       sb.add_param('Use Gray Code', Bool(true='Yes', false='No', 
default=True))
+       return sb, lambda fg, type, *args: \
+               HierHelper(type.parse()(fg, *map(lambda a: a.parse(), args)), 
Byte().get_num_bytes(), Complex().get_num_bytes())
+       
+def QAMDemod(sb):
+       from gnuradio import blks
+       sb.add_input_socket('in', Complex())
+       sb.add_output_socket('out', Byte())     
+       sb.add_param('Type', Enum([
+               ('QAM 8', blks.qam8_demod), 
+               ('QAM 64', blks.qam64_demod),
+               ('QAM 256', blks.qam256_demod),
+       ]), type=True)
+       sb.add_param('Samples/Symbol', Int(2, min=2))
+       sb.add_param('Excess BW', Float(0.35))
+       sb.add_param('Costas Alpha', Float(0.03))
+       sb.add_param('Gain Mu', Float(0.05))
+       sb.add_param('Mu', Float(0.005))
+       sb.add_param('Omega Relative Limit', Float(0.05))
+       sb.add_param('Use Gray Code', Bool(true='Yes', false='No', 
default=True))
+       return sb, lambda fg, type, *args: \
+               HierHelper(type.parse()(fg, *map(lambda a: a.parse(), args)), 
Complex().get_num_bytes(), Byte().get_num_bytes())
+               
+###########################################################################
 #      Phase Locked Loops
 ###########################################################################    
        

Modified: grc/trunk/src/SignalBlockDefs/Operators.py
===================================================================
--- grc/trunk/src/SignalBlockDefs/Operators.py  2007-06-29 17:29:46 UTC (rev 
5877)
+++ grc/trunk/src/SignalBlockDefs/Operators.py  2007-06-29 17:41:26 UTC (rev 
5878)
@@ -16,157 +16,175 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       SignalBlockDefs/Operations.py 
-       Josh Blum
-       These blocks implement basic mathematical operations + - * / log10...
-"""
address@hidden SignalBlockDefs.Operators
+#These blocks implement basic mathematical operations + - * / log10...
address@hidden Josh Blum
 
-from DataType import *
+from DataTypes import *
 from gnuradio import gr
-from Constants import *
+from SignalBlockConstants import MAX_NUM_SOCKETS
 
 variable_inputs_doc_string = '''2 <= Num Inputs <= %d.'''%MAX_NUM_SOCKETS
 
 def Add(sb):
-       type = Enum([('Complex', (gr.add_cc, Complex())), 
-                                       ('Float', (gr.add_ff, Float())), 
-                                       ('Int', (gr.add_ii, Int())), 
-                                       ('Short', (gr.add_ss, Short())),], 1)   
        
+       type = Enum([
+               ('Complex', (gr.add_cc, Complex())), 
+               ('Float', (gr.add_ff, Float())), 
+               ('Int', (gr.add_ii, Int())), 
+               ('Short', (gr.add_ss, Short())),
+       ], 1)           
        sb.add_input_socket('in', Variable(type, index=1))
        sb.add_output_socket('out', Variable(type, index=1))
        sb.add_param('Type', type, False, type=True)
        sb.add_param('Num Inputs', Int(2, min=2, max=MAX_NUM_SOCKETS), 
-                                                       show_label=False, 
input_sockets_controller=True)
+               show_label=False, input_sockets_controller=True)
        sb.set_docs(variable_inputs_doc_string) 
        return sb, lambda fg, type, num_inputs: type.parse()[0]()
        
 def AddVector(sb):
-       type = Enum([('Complex Vector', (gr.add_vcc, ComplexVector())), 
-                                       ('Float Vector', (gr.add_vff, 
FloatVector())), 
-                                       ('Int Vector', (gr.add_vii, 
IntVector())), 
-                                       ('Short Vector', (gr.add_vss, 
ShortVector())),], 1)             
+       type = Enum([
+               ('Complex Vector', (gr.add_vcc, ComplexVector())), 
+               ('Float Vector', (gr.add_vff, FloatVector())), 
+               ('Int Vector', (gr.add_vii, IntVector())), 
+               ('Short Vector', (gr.add_vss, ShortVector())),
+       ], 1)           
        sb.add_input_socket('vin', Variable(type, index=1))
        sb.add_output_socket('vout', Variable(type, index=1))
        sb.add_param('Type', type, False, type=True)
        sb.add_param('Num Inputs', Int(2, min=2, max=MAX_NUM_SOCKETS), 
-                                                       show_label=False, 
input_sockets_controller=True)
+               show_label=False, input_sockets_controller=True)
        sb.add_param('Items / Block', Int(1, min=1))
        sb.set_docs(variable_inputs_doc_string) 
        return sb, lambda fg, type, num_inputs, items_per_block: 
type.parse()[0](items_per_block.parse())
        
 def AddConstant(sb):
-       type = Enum([('Complex', (gr.add_const_cc, Complex())), 
-                                       ('Float', (gr.add_const_ff, Float())), 
-                                       ('Int', (gr.add_const_ii, Int())), 
-                                       ('Short', (gr.add_const_ss, 
Short())),], 1)             
+       type = Enum([
+               ('Complex', (gr.add_const_cc, Complex())), 
+               ('Float', (gr.add_const_ff, Float())), 
+               ('Int', (gr.add_const_ii, Int())), 
+               ('Short', (gr.add_const_ss, Short())),
+       ], 1)           
        sb.add_input_socket('in', Variable(type, index=1))
        sb.add_output_socket('out', Variable(type, index=1))
        sb.add_param('Type', type, False, type=True)
-       sb.add_param('Constant', Variable(type, 1, index=1))
+       sb.add_param('Constant', Variable(type, 1, index=1), variable=True)
        def make(fg, type, constant): 
                block = type.parse()[0](constant.parse())
-               if fg != None: fg.add_callback(block.set_k, constant)   
+               fg.add_callback(block.set_k, constant)  
                return block
        return sb, make
        
 def AddConstantVector(sb):
-       type = Enum([('Complex Vector', (gr.add_const_vcc, ComplexVector())), 
-                                       ('Float Vector', (gr.add_const_vff, 
FloatVector())), 
-                                       ('Int Vector', (gr.add_const_vii, 
IntVector())), 
-                                       ('Short Vector', (gr.add_const_vss, 
ShortVector())),], 1)               
+       type = Enum([
+               ('Complex Vector', (gr.add_const_vcc, ComplexVector())), 
+               ('Float Vector', (gr.add_const_vff, FloatVector())), 
+               ('Int Vector', (gr.add_const_vii, IntVector())), 
+               ('Short Vector', (gr.add_const_vss, ShortVector())),
+       ], 1)           
        sb.add_input_socket('vin', Variable(type, index=1))
        sb.add_output_socket('vout', Variable(type, index=1))
        sb.add_param('Type', type, False, type=True)
-       sb.add_param('Constant', Variable(type, 1, index=1))
+       sb.add_param('Constant', Variable(type, 1, index=1), variable=True)
        def make(fg, type, constant): 
                block = type.parse()[0](constant.parse())
-               if fg != None: fg.add_callback(block.set_k, constant)   
+               fg.add_callback(block.set_k, constant)  
                return block
        return sb, make
        
 def Multiply(sb):
-       type = Enum([('Complex', (gr.multiply_cc, Complex())), 
-                                       ('Float', (gr.multiply_ff, Float())), 
-                                       ('Int', (gr.multiply_ii, Int())), 
-                                       ('Short', (gr.multiply_ss, Short())),], 
1)              
+       type = Enum([
+               ('Complex', (gr.multiply_cc, Complex())), 
+               ('Float', (gr.multiply_ff, Float())), 
+               ('Int', (gr.multiply_ii, Int())), 
+               ('Short', (gr.multiply_ss, Short())),
+       ], 1)           
        sb.add_input_socket('in', Variable(type, index=1))
        sb.add_output_socket('out', Variable(type, index=1))
        sb.add_param('Type', type, False, type=True)
        sb.add_param('Num Inputs', Int(2, min=2, max=MAX_NUM_SOCKETS), 
-                                                       show_label=False, 
input_sockets_controller=True)
+               show_label=False, input_sockets_controller=True)
        sb.set_docs(variable_inputs_doc_string) 
        return sb, lambda fg, type, num_inputs: type.parse()[0]()
        
 def MultiplyVector(sb):
-       type = Enum([('Complex Vector', (gr.multiply_vcc, ComplexVector())), 
-                                       ('Float Vector', (gr.multiply_vff, 
FloatVector())), 
-                                       ('Int Vector', (gr.multiply_vii, 
IntVector())), 
-                                       ('Short Vector', (gr.multiply_vss, 
ShortVector())),], 1)                
+       type = Enum([
+               ('Complex Vector', (gr.multiply_vcc, ComplexVector())), 
+               ('Float Vector', (gr.multiply_vff, FloatVector())), 
+               ('Int Vector', (gr.multiply_vii, IntVector())), 
+               ('Short Vector', (gr.multiply_vss, ShortVector())),
+       ], 1)           
        sb.add_input_socket('vin', Variable(type, index=1))
        sb.add_output_socket('vout', Variable(type, index=1))
        sb.add_param('Type', type, False, type=True)
        sb.add_param('Num Inputs', Int(2, min=2, max=MAX_NUM_SOCKETS), 
-                                                       show_label=False, 
input_sockets_controller=True)
+               show_label=False, input_sockets_controller=True)
        sb.add_param('Items / Block', Int(1, min=1))
        sb.set_docs(variable_inputs_doc_string) 
        return sb, lambda fg, type, num_inputs, items_per_block: 
type.parse()[0](items_per_block.parse())
        
 def MultiplyConstant(sb):
-       type = Enum([('Complex', (gr.multiply_const_cc, Complex())), 
-                                       ('Float', (gr.multiply_const_ff, 
Float())), 
-                                       ('Int', (gr.multiply_const_ii, Int())), 
-                                       ('Short', (gr.multiply_const_ss, 
Short())),], 1)                
+       type = Enum([
+               ('Complex', (gr.multiply_const_cc, Complex())), 
+               ('Float', (gr.multiply_const_ff, Float())), 
+               ('Int', (gr.multiply_const_ii, Int())), 
+               ('Short', (gr.multiply_const_ss, Short())),
+       ], 1)           
        sb.add_input_socket('in', Variable(type, index=1))
        sb.add_output_socket('out', Variable(type, index=1))
        sb.add_param('Type', type, False, type=True)
-       sb.add_param('Constant', Variable(type, 1, index=1))
+       sb.add_param('Constant', Variable(type, 1, index=1), variable=True)
        def make(fg, type, constant): 
                block = type.parse()[0](constant.parse())
-               if fg != None: fg.add_callback(block.set_k, constant)   
+               fg.add_callback(block.set_k, constant)  
                return block
        return sb, make
        
 def MultiplyConstantVector(sb):
-       type = Enum([('Complex Vector', (gr.multiply_const_vcc, 
ComplexVector())), 
-                                       ('Float Vector', 
(gr.multiply_const_vff, FloatVector())), 
-                                       ('Int Vector', (gr.multiply_const_vii, 
IntVector())), 
-                                       ('Short Vector', 
(gr.multiply_const_vss, ShortVector())),], 1)          
+       type = Enum([
+               ('Complex Vector', (gr.multiply_const_vcc, ComplexVector())), 
+               ('Float Vector', (gr.multiply_const_vff, FloatVector())), 
+               ('Int Vector', (gr.multiply_const_vii, IntVector())), 
+               ('Short Vector', (gr.multiply_const_vss, ShortVector())),
+       ], 1)           
        sb.add_input_socket('vin', Variable(type, index=1))
        sb.add_output_socket('vout', Variable(type, index=1))
        sb.add_param('Type', type, False, type=True)
-       sb.add_param('Constant', Variable(type, 1, index=1))
+       sb.add_param('Constant', Variable(type, 1, index=1), variable=True)
        def make(fg, type, constant): 
                block = type.parse()[0](constant.parse())
-               if fg != None: fg.add_callback(block.set_k, constant)   
+               fg.add_callback(block.set_k, constant)  
                return block
        return sb, make
        
 def Subtract(sb):
-       type = Enum([('Complex', (gr.sub_cc, Complex())), 
-                                       ('Float', (gr.sub_ff, Float())), 
-                                       ('Int', (gr.sub_ii, Int())), 
-                                       ('Short', (gr.sub_ss, Short())),], 1)   
        
+       type = Enum([
+               ('Complex', (gr.sub_cc, Complex())), 
+               ('Float', (gr.sub_ff, Float())), 
+               ('Int', (gr.sub_ii, Int())), 
+               ('Short', (gr.sub_ss, Short())),
+       ], 1)           
        sb.add_input_socket('in', Variable(type, index=1))
        sb.add_input_socket('-in', Variable(type, index=1))
        sb.add_output_socket('out', Variable(type, index=1))
        sb.add_param('Type', type, False, type=True)
        sb.add_param('Num Inputs', Int(2, min=2, max=MAX_NUM_SOCKETS), 
-                                                       show_label=False, 
input_sockets_controller=True)
+               show_label=False, input_sockets_controller=True)
        sb.set_docs(variable_inputs_doc_string)
        return sb, lambda fg, type, num_inputs: type.parse()[0]()
        
 def Divide(sb):
-       type = Enum([('Complex', (gr.divide_cc, Complex())), 
-                                       ('Float', (gr.divide_ff, Float())), 
-                                       ('Int', (gr.divide_ii, Int())), 
-                                       ('Short', (gr.divide_ss, Short())),], 
1)                
+       type = Enum([
+               ('Complex', (gr.divide_cc, Complex())), 
+               ('Float', (gr.divide_ff, Float())), 
+               ('Int', (gr.divide_ii, Int())), 
+               ('Short', (gr.divide_ss, Short())),
+       ], 1)           
        sb.add_input_socket('in', Variable(type, index=1))
        sb.add_input_socket('/in', Variable(type, index=1))
        sb.add_output_socket('out', Variable(type, index=1))
        sb.add_param('Type', type, False, type=True)
        sb.add_param('Num Inputs', Int(2, min=2, max=MAX_NUM_SOCKETS), 
-                                                       show_label=False, 
input_sockets_controller=True)
+               show_label=False, input_sockets_controller=True)
        sb.set_docs(variable_inputs_doc_string)
        return sb, lambda fg, type, num_inputs: type.parse()[0]()
        
@@ -178,5 +196,5 @@
        sb.add_param('k', Float(0))
        sb.add_param('Vector Length', vlen)
        sb.set_docs('''output = n*log10(input) + k''')  
-       return sb, lambda fg, n, k, vlen: gr.nlog10_ff(n.parse(), vlen, 
k.parse())
+       return sb, lambda fg, n, k, vlen: gr.nlog10_ff(n.parse(), vlen.parse(), 
k.parse())
        
\ No newline at end of file

Copied: grc/trunk/src/SignalBlockDefs/Packet.py (from rev 5877, 
grc/branches/jblum_work/src/SignalBlockDefs/Packet.py)
===================================================================
--- grc/trunk/src/SignalBlockDefs/Packet.py                             (rev 0)
+++ grc/trunk/src/SignalBlockDefs/Packet.py     2007-06-29 17:41:26 UTC (rev 
5878)
@@ -0,0 +1,312 @@
+"""
+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 SignalBlockDefs.Packet
+#Support for the gr packet framework.
address@hidden Josh Blum
+
+import struct
+import os
+import gnuradio.gr.gr_threading as threading
+from DataTypes import *
+from gnuradio import gr,blks,packet_utils
+from SignalBlockConstants import all_choices,DEFAULT_QUEUE_LIMIT
+
+MAX_ACCESS_CODE_LENGTH = 64
+MAX_PACKET_LENGTH = len(packet_utils.random_mask_tuple)#4096
+DEFAULT_PACKET_LENGTH = 512
+
+#######################################################################################
+##     Packet Modulator and Demodulator Hier Block
+#######################################################################################
+
+class PacketModThread(threading.Thread):
+       """
+       Thread to forward data between the message queue and the packet 
modulator.
+       Read messages from the message queue, slice them up to the packet 
length, 
+       and pass them to the send packet function.
+       """
+       def __init__(self, msgq, send_packet, packet_length):
+               """!
+               PacketModThread contructor.
+               @param msgq the message queue with incoming data
+               @param send_packet a function of one argument to send a packet
+               """
+               self.msgq = msgq
+               self.send_packet = send_packet
+               self.packet_length = packet_length
+               threading.Thread.__init__(self)
+               self.setDaemon(1)
+               self.keep_running = True
+               self.start()
+               print 'Created packet modulator thread.'
+               
+       def run(self):
+               """In an endless while loop: read the msgq and call send 
packet."""
+               r = '' #residual message
+               while self.keep_running:
+                       msg = self.msgq.delete_head()  # blocking read of 
message queue
+                       sr = r + msg.to_string()
+                       num_packets = len(sr)/int(self.packet_length) #integer 
arithmetic
+                       r_index = self.packet_length*num_packets
+                       s = sr[0:r_index]       #portion of message divisible 
by packet size                            
+                       r = sr[r_index:]        #residual portion of message 
smaller then packet size   
+                       #print len(s), len(r), msg.type(), msg.arg1(), 
msg.arg2()               
+                       for i in range(num_packets): 
self.send_packet(s[i*self.packet_length:(i+1)*self.packet_length])
+               
+class PacketModHelper(gr.hier_block2):
+       """Forward data from the gr data stream to the mod packet."""
+       def __init__(self, item_size, packet_length, samples_per_symbol, 
bits_per_symbol, access_code, pad_for_usrp, use_whitener_offset):
+               """!
+               PacketModHelper constructor.
+               @param item_size the size in bytes of the input data stream
+               @param packet_length the length in bytes of the packets
+               @param *args the arguments for blks.mod_pkts
+               """
+               #create hier block
+               gr.hier_block2.__init__(
+                       self, 'packet_mod', 
+                       gr.io_signature(1, 1, item_size), 
+                       gr.io_signature(1, 1, Byte().get_num_bytes())
+               )
+               #dummy modulator with access functions          
+               modulator = gr.skiphead(Byte().get_num_bytes(), 0)      
+               modulator.samples_per_symbol = lambda: samples_per_symbol
+               modulator.bits_per_symbol = lambda: bits_per_symbol
+               #create the packet modulator (handles the output data stream)
+               packet_mod = blks.mod_pkts(     
+                       fg=self, 
+                       modulator=modulator, 
+                       access_code=access_code, 
+                       msgq_limit=DEFAULT_QUEUE_LIMIT, 
+                       pad_for_usrp=pad_for_usrp, 
+                       use_whitener_offset=use_whitener_offset,
+               )
+               #the message sink (handles the input data stream)
+               msgq = gr.msg_queue(DEFAULT_QUEUE_LIMIT)
+               msg_sink = gr.message_sink(item_size, msgq, False)              
+               #connections
+               self.connect(packet_mod.tail, self)
+               self.connect(self, msg_sink)            
+               #create/start the thread
+               PacketModThread(msgq, packet_mod.send_pkt, packet_length)
+
+class PacketDemodHelper(gr.hier_block2):
+       """Forward data from demod packet to the gr data stream."""
+       def __init__(self, item_size, access_code, threshold):
+               """!
+               PacketDemodHelper constructor.
+               @param item_size the size in bytes of the output data stream
+               @param *args the arguments for blks.demod_pkts
+               @param msgq_limit the queue limit for the message source
+               """
+               #create hier block
+               gr.hier_block2.__init__(
+                       self, 'packet_demod', 
+                       gr.io_signature(1, 1, Byte().get_num_bytes()), 
+                       gr.io_signature(1, 1, item_size)
+               )
+               #the message source (handles the output data stream)
+               msg_source = gr.message_source(item_size, DEFAULT_QUEUE_LIMIT)
+               msgq = msg_source.msgq()
+               def callback(ok, payload):
+                       if ok: msgq.insert_tail(gr.message_from_string(payload, 
0, item_size, len(payload)/item_size))
+               #dummy demodulator
+               demodulator = gr.skiphead(Byte().get_num_bytes(), 0)    
+               #create the packet demodulator (handles the input data stream)
+               packet_demod = blks.demod_pkts( 
+                       fg=self, 
+                       demodulator=demodulator, 
+                       access_code=access_code, 
+                       callback=callback,
+                       threshold=threshold,
+               )
+               #connections
+               self.connect(msg_source, self)
+               self.connect(self, packet_demod.head)
+
+#######################################################################################
+##     Packet Modulator and Demodulator Defs
+#######################################################################################
+
+def PacketMod(sb):
+       blks.mod_pkts, gr.throttle, gr.message_sink     #uses
+       type = Enum(all_choices, 1)
+       sb.add_input_socket('in', Variable(type))               #packet input
+       sb.add_output_socket('out', Byte())
+       sb.add_param('Type', type, False, type=True)
+       sb.add_param('Modulator Type', Enum([
+               ('GMSK', blks.gmsk_mod),
+               ('DBPSK', blks.dbpsk_mod),
+               ('DQPSK', blks.dqpsk_mod),
+               ('D8PSK', blks.d8psk_mod),
+               ('QAM 8', blks.qam8_mod),
+               ('QAM 64', blks.qam64_mod),
+               ('QAM 256', blks.qam256_mod),
+       ]))
+       sb.add_param('Samples/Symbol', Int(2, min=2))
+       sb.add_param('Packet Length', Int(DEFAULT_PACKET_LENGTH, min=1, 
max=MAX_PACKET_LENGTH))
+       sb.add_param('Access Code', String('', max=MAX_ACCESS_CODE_LENGTH))
+       sb.add_param('Pad for USRP', Bool(true='Yes', false='No', default=True))
+       sb.add_param('Use Whitener Offset', Bool(true='Yes', false='No', 
default=False))
+       sb.set_docs('''\
+The packet modulator wraps a data stream into packets.
+---
+Modulator type: tells the packet modulator how many bits per symbol to use. \
+A modulator block should still be connected to the output of this block.
+
+Packet length: length of a packet in bytes, must be a multiple of the size of 
the input data stream, and no greater than %d.
+
+Access code/sync vector: string of 1's and 0's between 1 and %d long. Leave 
blank for default.
+
+Pad for USRP: If true, packets are padded such that they end up a multiple of 
128 samples.
+
+Use whitener offset: If true, start of whitener XOR string is incremented each 
packet.
+'''%(MAX_PACKET_LENGTH, MAX_ACCESS_CODE_LENGTH))
+       def make(fg, type, mod_type, samples_per_symbol, packet_length, 
access_code, pad_for_usrp, use_whitener_offset):
+               access_code = access_code.parse()
+               if access_code == '': access_code = None        #access code 
should be None if blank
+               item_size = type.parse().get_num_bytes()                        
+               packet_length = packet_length.parse()
+               if packet_length%item_size != 0:        #verify that packet 
length is a multiple of the stream size
+                       raise ValueError('The packet length: "%d" is not a 
mutiple of the stream size: "%d".'%(packet_length, item_size))
+               return PacketModHelper(
+                       item_size=item_size, 
+                       packet_length=packet_length,
+                       samples_per_symbol=samples_per_symbol.parse(), 
+                       bits_per_symbol=mod_type.parse().bits_per_symbol(),
+                       access_code=access_code, 
+                       pad_for_usrp=pad_for_usrp.parse(), 
+                       use_whitener_offset=use_whitener_offset.parse(),
+               )       #build packet modulator
+       return sb, make
+       
+def PacketDemod(sb):
+       blks.demod_pkts, gr.throttle, gr.message_source #uses
+       type = Enum(all_choices, 1)
+       sb.add_output_socket('out', Variable(type))             #packet output
+       sb.add_input_socket('in', Byte())       
+       sb.add_param('Type', type, False, type=True)
+       sb.add_param('Access Code', String('', max=MAX_ACCESS_CODE_LENGTH))
+       sb.add_param('Threshold', Int(-1))      
+       sb.set_docs('''\
+The packet demodulator unwraps packets from a data stream.
+---
+Access code/sync vector: string of 1's and 0's between 1 and %d long. Leave 
blank for default.
+
+Threshold: detect access_code with up to threshold bits wrong.
+
+Queue limit: maximum number of messages in message queue.
+'''%MAX_ACCESS_CODE_LENGTH)
+       def make(fg, type, access_code, threshold):
+               access_code = access_code.parse()
+               if access_code == '': access_code = None        #access code 
should be None if blank
+               return PacketDemodHelper(
+                       item_size=type.parse().get_num_bytes(),
+                       access_code=access_code, 
+                       threshold=threshold.parse(),
+               )       #build packet demodulator               
+       return sb, make
+
+#######################################################################################
+##     TUN/TAP Access Threads
+#######################################################################################
+
+IFF_TUN                = 0x0001   # tunnel IP packets
+IFF_TAP                = 0x0002   # tunnel ethernet frames
+IFF_NO_PI      = 0x1000   # don't pass extra packet info
+IFF_ONE_QUEUE  = 0x2000   # beats me ;)
+DEFAULT_TUN_DEVICE = '/dev/net/tun'
+DEFAULT_VIRTUAL_DEVICE = 'tun%d'
+DEFAULT_IP_ADDR = '10.0.0.1'
+
+def open_tun_interface(tun_device_filename=DEFAULT_TUN_DEVICE, 
virtual_device_filename=DEFAULT_VIRTUAL_DEVICE):
+       """!
+       Open a virtual ethernet interface via the Tun/Tap framework.
+       An alternative function can be found: "from eunuchs.tuntap import 
opentuntap"
+       @param tun_device_filename the path to the tun device
+       @param virtual_device_filename the name of the virtual device (to be 
created)
+       @return a file descriptor to rw the device, name of the virtual device 
(created)
+       """
+       from fcntl import ioctl    
+       mode = IFF_TAP | IFF_NO_PI
+       TUNSETIFF = 0x400454ca
+       tun_fd = os.open(tun_device_filename, os.O_RDWR)
+       ifs = ioctl(tun_fd, TUNSETIFF, struct.pack("16sH", 
virtual_device_filename, mode))
+       ifname = ifs[:16].strip("\x00")
+       return tun_fd, ifname
+    
+class TunSinkThread(threading.Thread):
+       """
+       Thread to forward data from the message queue and to the virtual device.
+       """
+       def __init__(self, msgq, tun_fd, ifname):
+               """!
+               TunSinkThread contructor.
+               @param msgq the message queue with incoming data
+               @param tun_fd the file descriptor for the virtual device
+               @param ifname the name of virtual interface
+               """
+               self.msgq = msgq
+               self.tun_fd = tun_fd            
+               threading.Thread.__init__(self)
+               self.setDaemon(1)
+               self.keep_running = True
+               self.start()
+               print 'Created tun sink thread for device "%s".'%ifname
+               
+       def run(self):
+               """In an endless while loop: read the msgq and write to tun.""" 
        
+               while self.keep_running:
+                       msg = self.msgq.delete_head()  # blocking read of 
message queue
+                       os.write(self.tun_fd, msg.to_string())
+                                               
+#######################################################################################
+##     TUN/TAP Block Defs
+#######################################################################################
                        
+
+def TunSink(sb):
+       gr.message_sink #uses
+       type = Enum(all_choices, 1)
+       sb.add_input_socket('in', Variable(type))               
+       sb.add_param('Type', type, False, type=True)
+       sb.add_param('Tun Device', String(DEFAULT_TUN_DEVICE))
+       sb.add_param('Virtual Device', String(DEFAULT_VIRTUAL_DEVICE))
+       sb.add_param('IP Address', String(DEFAULT_IP_ADDR))
+       sb.set_docs('''\
+Write data from a gnuradio data stream into a virtual ethernet interface.
+---
+Tun Device: File path to the tun device.
+
+Virtual Device: Desired name for the virtual ethernet device. \
+"%d" will give the device a number starting at zero.
+
+IP Address: IP address for the virtual device, leave blank and device will not 
be configured.
+''')
+       def make(fg, type, tun, virt, ip_addr):
+               item_size = type.parse().get_num_bytes()
+               msgq = gr.msg_queue(DEFAULT_QUEUE_LIMIT)
+               tun_fd, ifname = open_tun_interface(tun.parse(), virt.parse())
+               #try to set the ip address
+               ip_addr = ip_addr.parse()
+               if ip_addr: os.system('ifconfig %s %s'%(ifname, ip_addr))
+               TunSinkThread(msgq, tun_fd, ifname)
+               return gr.message_sink(item_size, msgq, False)
+       return sb, make
+       
+       
\ No newline at end of file

Modified: grc/trunk/src/SignalBlockDefs/SignalBlockConstants.py
===================================================================
--- grc/trunk/src/SignalBlockDefs/SignalBlockConstants.py       2007-06-29 
17:29:46 UTC (rev 5877)
+++ grc/trunk/src/SignalBlockDefs/SignalBlockConstants.py       2007-06-29 
17:41:26 UTC (rev 5878)
@@ -16,14 +16,60 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       SignalBlockDefs/SignalBlockConstants.py 
-       Josh Blum
-       Constants used by the signal block definitions.
-"""
address@hidden SignalBlockDefs.SignalBlockConstants
+#Constants used by the signal block definitions.
address@hidden Josh Blum
 
-from DataType import *
+from DataTypes import *
+from gnuradio import gr
 
+class ThrottleHelper(gr.hier_block2):
+       """A block with a throttle on the input or output."""
+       def __init__(self, item_size, samp_rate, block, position):
+               """!
+               ThrottleHelper contructor.
+               Create a throttle and append it to the block.
+               @param item_size the size of the gr data stream in bytes
+               @param block the gr block
+               @param position if true connect a throttle to the input of 
block, otherwise the output
+               """             
+               gr.hier_block2.__init__(
+                       self, "throttle_helper",
+                       gr.io_signature(1, 1, item_size),
+                       gr.io_signature(1, 1, item_size)
+               )
+               throttle = gr.throttle(item_size, samp_rate)
+               if position: self.connect(self, throttle, block, self)
+               else: self.connect(self, block, throttle, self)
+                       
+class HierHelper(gr.hier_block2):
+       """Wrap a hier2 block around a hier block."""
+       def __init__(self, hier_block, item_size_in=0, item_size_out=0):
+               """!
+               HierHelper constructor.
+               An item size of zero means that there is no connection.
+               @param hier_block a regular hier block
+               @param item_size_in the size of the input data stream in bytes
+               @param item_size_out the size of the output data stream in 
bytes                
+               """
+               #io signatures
+               if item_size_in > 0: io_sig_in = gr.io_signature(1, 1, 
item_size_in)
+               else: io_sig_in = gr.io_signature(0, 0, 0)
+               if item_size_out > 0: io_sig_out = gr.io_signature(1, 1, 
item_size_out)
+               else: io_sig_out = gr.io_signature(0, 0, 0)
+               #initialize
+               gr.hier_block2.__init__(self, "hier_helper", io_sig_in, 
io_sig_out)
+               #connect
+               if item_size_in > 0: self.connect(self, hier_block.head)        
+               if item_size_out > 0: self.connect(hier_block.tail, self)
+
+##max number of sockets to draw on one side of a signal block.
+MAX_NUM_SOCKETS = 20
+
+##default message queue limit
+DEFAULT_QUEUE_LIMIT = 1
+
+##choices for an Enum of regular data types
 all_choices = [
        ('Complex', Complex()),
        ('Float', Float()),
@@ -32,6 +78,7 @@
        ('Byte', Byte()),
 ]
 
+##choices for an Enum of vector data types
 all_vector_choices = [
        ('Complex Vector', (ComplexVector(), Complex())),
        ('Float Vector', (FloatVector(), Float())),
@@ -40,8 +87,10 @@
        ('Byte Vector', (ByteVector(), Byte()))
 ]
 
+##default sampling rate
 default_samp_rate = '$samp_rate'
 
+##possible audio rates for audio source/sink
 audio_rates = [
        ('16KHz', int(16e3)),
        ('22.05KHz', int(22.05e3)),
@@ -50,8 +99,11 @@
        ('44.1KHz', int(44.1e3)),
        ('48KHz', int(48e3)),
 ]
+
+##index of the default audio rate
 default_audio_rate_index = 3
 
+##default udp port for udp source/sink
 default_udp_port = 3456
 
                
\ No newline at end of file

Modified: grc/trunk/src/SignalBlockDefs/SignalBlockTree.py
===================================================================
--- grc/trunk/src/SignalBlockDefs/SignalBlockTree.py    2007-06-29 17:29:46 UTC 
(rev 5877)
+++ grc/trunk/src/SignalBlockDefs/SignalBlockTree.py    2007-06-29 17:41:26 UTC 
(rev 5878)
@@ -16,12 +16,9 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       SignalBlockDefs/SignalBlockTree.py 
-       Josh Blum
-       The data structure to categorize the signal blocks,
-       and to map id tags to block building functions.
-"""
address@hidden SignalBlockDefs.SignalBlockTree
+#The data structure to categorize the signal blocks, and to map id tags to 
block building functions.
address@hidden Josh Blum
 
 from Elements import SignalBlock
 import Sources
@@ -35,7 +32,10 @@
 import USRP
 import Coders
 import Trellis
+import Packet
+import Custom
 
+##A categorized list of all signal blocks
 SB_TREE = [
                        ('Sources', [           
                                ('Signal Source', Sources.SignalSource),
@@ -56,6 +56,7 @@
                                ('Audio Sink', Sinks.AudioSink),
                                ('USRP Sink', USRP.USRPSink),
                                ('USRP Dual Sink', USRP.USRPDualSink),
+                               ('Tun Sink', Packet.TunSink),
                        ]),
                        ('Graphical Sinks', [                   
                                ('Numerical Sink', 
GraphicalSinks.NumericalSink),       
@@ -64,7 +65,7 @@
                                ('Waterfall Sink', 
GraphicalSinks.WaterfallSink),
                                ('Constellation Sink', 
GraphicalSinks.ConstellationSink),
                        ]),
-                       ('Operations', [                                        
                
+                       ('Operators', [                                         
        
                                ('Add', Operators.Add),
                                ('Subtract', Operators.Subtract),
                                ('Multiply', Operators.Multiply),               
                
@@ -95,6 +96,8 @@
                                ('Unpack k Bits', Conversions.UnpackKBits),
                                ('Binary Slicer', Conversions.BinarySlicer),
                                ('Chunks to Symbols', 
Conversions.ChunksToSymbols),
+                               ('Map', Conversions.Map),
+                               ('VCO', Conversions.VCO),
                                ('Interleave', Conversions.Interleave),
                                ('Deinterleave', Conversions.Deinterleave),
                                ('Streams to Stream', 
Conversions.StreamsToStream),
@@ -111,6 +114,7 @@
                                ('Rational Resampler', 
Filters.RationalResampler),      
                                ('IIR Filer', Filters.IIRFiler),        
                                ('Filter Delay', Filters.FilterDelay),
+                               ('Channel Model', Filters.ChannelModel),
                        ]),             
                        ('Filters', [                   
                                ('Low Pass Filter', Filters.LowPassFilter),
@@ -126,29 +130,35 @@
                                ('Downsample', Filters.Downsample),
                                ('Upsample', Filters.Upsample),                 
        
                                ('Fractional Resampler', 
Filters.FractionalResampler),
+                               ('Fractional Interpolator', 
Filters.FractionalInterpolator),
                                ('Automatic Gain Control', 
Filters.AutomaticGainControl),
                                ('Automatic Gain Control2', 
Filters.AutomaticGainControl2),
+                               ('Feed Forward AGC', Filters.FeedForwardAGC),
                                ('CMA Filter', Filters.CMAFilter),
                                ('Clock Recovery', Filters.ClockRecovery),
                                ('FFT', Filters.FFT),
                                ('IFFT', Filters.IFFT),
                        ]),
                        ('Modulators', [                        
-                               ('Frequency Modulation', 
Modulators.FrequencyModulation),
-                               ('Phase Modulation', 
Modulators.PhaseModulation),
-                               ('Quadrature Demodulation', 
Modulators.QuadratureDemodulation),
+                               ('Frequency Modulator', 
Modulators.FrequencyMod),
+                               ('Phase Modulator', Modulators.PhaseMod),
+                               ('Quadrature Demodulator', 
Modulators.QuadratureDemod),
                                ('Costas Loop', Modulators.CostasLoop),
                                ('Phase Locked Loop', Modulators.PLL),
                                ('WFM Receive', Modulators.WFMReceive),         
        
                                ('WFM Transmit', Modulators.WFMTransmit),       
                                ('NBFM Receive', Modulators.NBFMReceive),       
                
                                ('NBFM Transmit', Modulators.NBFMTransmit),     
-                               ('AM Demodulation', Modulators.AMDemod),
-                               ('FM Demodulation', Modulators.FMDemod),
-                               ('PSK Modulation', Modulators.PSKMod),
-                               ('PSK Demodulation', Modulators.PSKDemod),
-                               ('GMSK Modulation', Modulators.GMSKMod),
-                               ('GMSK Demodulation', Modulators.GMSKDemod),
+                               ('AM Demodulator', Modulators.AMDemod),
+                               ('FM Demodulator', Modulators.FMDemod),
+                               ('PSK Modulator', Modulators.PSKMod),
+                               ('PSK Demodulator', Modulators.PSKDemod),
+                               ('GMSK Modulator', Modulators.GMSKMod),
+                               ('GMSK Demodulator', Modulators.GMSKDemod),
+                               ('QAM Modulator', Modulators.QAMMod),
+                               ('QAM Demodulator', Modulators.QAMDemod),
+                               ('Packet Modulator', Packet.PacketMod),
+                               ('Packet Demodulator', Packet.PacketDemod),
                        ]),
                        ('Coders', [
                                ('Constellation Decoder', 
Coders.ConstellationDecoder),                         
@@ -169,16 +179,29 @@
                        ]),
                        ('Misc', [      
                                ('Throttle', Misc.Throttle),
+                               ('Valve', Misc.Valve),
+                               ('Selector', Misc.Selector),
                                ('Head', Misc.Head),    
                                ('Skip Head', Misc.SkipHead),                   
                                ('RMS', Misc.RMS),      
                                ('About', Misc.About),
                                ('Note', Misc.Note),    
                        ]),
+                       ('Custom', Custom.CUSTOM_BLOCKS),
                ] 
                
-def get_signal_block(parent, coor, rot, lookup_tag, id, 
signal_block_constructor=SignalBlock):
-       """ Create a new signal based on a few input parameters.        """
+def get_signal_block(parent=None, coor=(0,0), rot=0, lookup_tag='', id='', 
signal_block_constructor=SignalBlock):
+       """!
+       Create a new signal block.
+       @param parent the flow graph
+       @param coor the (x,y) corrdinate
+       @param rot the rotation in degrees
+       @param lookup_tag the tag of the desired signal block
+       @param id the unique id for the new signal block
+       @param signal_block_constructor the contructor for a new signal block
+       @throw TagNotFoundException tag not found
+       @return (the signal block, a gnuradio signal block builder function) 
tuple
+       """
        sb = signal_block_constructor(parent, coor, rot, lookup_tag, id)
        for category, signal_blocks in SB_TREE:
                for tag, builder in signal_blocks:
@@ -191,7 +214,7 @@
        tags_to_remove = list()
        for tag in tags:
                try: 
-                       get_signal_block(None, (0,0), 0, tag[0], '')
+                       get_signal_block(lookup_tag=tag[0])
                        if tag[0] in tags_set:  #       remove redundant tags   
#
                                print 'Removing redundant tag "%s" in category 
"%s"...'%(tag[0], category)
                                tags_to_remove.append(tag)      
@@ -205,7 +228,7 @@
 cats_to_remove = list()
 for category,tags in SB_TREE:
        if len(tags) == 0: 
-               print 'Removing category "%s", it was emptied...'%category
+               print 'Removing empty category "%s"...'%category
                cats_to_remove.append((category,tags))
 for cat in cats_to_remove: SB_TREE.remove(cat)
         
@@ -214,7 +237,8 @@
        def __init__(self, value):      self.value = value
        def __str__(self): return 'Exception! The tag: %s could not be 
found'%repr(self.value)
                
-def print_tags():
+def print_sb_tree():
+       """Print the signal block tree."""
        for category,tags in TAGS:
                print category
                for tag in tags: print '\t%s'%tag[0]

Modified: grc/trunk/src/SignalBlockDefs/Sinks.py
===================================================================
--- grc/trunk/src/SignalBlockDefs/Sinks.py      2007-06-29 17:29:46 UTC (rev 
5877)
+++ grc/trunk/src/SignalBlockDefs/Sinks.py      2007-06-29 17:41:26 UTC (rev 
5878)
@@ -16,16 +16,14 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       SignalBlockDefs/Sinks.py 
-       Josh Blum
-       Various data sinks.
-"""
address@hidden SignalBlockDefs.Sinks
+#Various data sinks.
address@hidden Josh Blum
 
-from DataType import *
+from DataTypes import *
 from gnuradio import gr
 from SignalBlockConstants import *
-from Constants import DEFAULT_FILE_PATH
+from Constants import DEFAULT_FILE_PATH,MUTEX
 
 def NullSink(sb):
        type = Enum(all_choices, 1)
@@ -39,7 +37,6 @@
        return sb, lambda fg, type, vlen: 
gr.null_sink(type.parse().get_num_bytes()*vlen.parse())
 
 def FileSink(sb):
-       import Constants
        type = Enum(all_choices, 1)
        vlen = Int(1, min=1)
        sb.add_input_socket('in', Variable(type), vlen=vlen)
@@ -85,44 +82,55 @@
        
 import threading
 import Variables
-import Numeric
+import numpy
        
 class VariableSinkThread(threading.Thread):
-       """ This thread will read the vector sink at the sampling rate,
-               write the numeric value back to the variable,
-               and re-parse the flow graph's callbacks.        """
+       """
+       This thread will read the vector sink,
+       write the numeric value back to the variable,
+       and re-parse the flow graph's callbacks.
+       """
        def __init__(self, fg, var_key, msgq):
-               """ Create a new variable sink thread.  """
+               """!
+               VariableSinkThread constructor.
+               @param fg the gr flow graph
+               @param var_key the variable key
+               @param msgq the message queue
+               """
                self.fg = fg
                self.var_key = var_key
                self.msgq = msgq
                threading.Thread.__init__(self)
-               print 'Created variable sink thread for variable "%s"'%var_key
+               self.setDaemon(1)
+               self.keep_running = True
+               self.start()
+               print 'Created variable sink thread for variable "%s".'%var_key
                                
        def run(self):
-               """ In a endless while loop: read the vector sink,
-                       write to the variable, and parse the callbacks. """
-               while True:
-                       try:            
-                               msg = self.msgq.delete_head()  # blocking read 
of message queue
-                               itemsize = int(msg.arg1())
-                               nitems = int(msg.arg2())                        
        
-                               s = msg.to_string()            # get the body 
of the msg as a string                            
-                               # There may be more than one number in the 
message.
-                               # If so, we take only the last one
-                               if nitems > 1:
-                                       start = itemsize * (nitems - 1)
-                                       s = s[start:start+itemsize]             
                
-                               #       parse the data to a complex or 
float/int string #
-                               complex_data = Numeric.fromstring (s, 
Numeric.Float32)
-                               if len(complex_data) == 2: new_value = "%f + 
%fj"%(complex_data[0], complex_data[1])
-                               else: new_value = "%f"%(complex_data[0],) 
-                               # write the new value #         
-                               Variables.unregister(self.var_key)
-                               Variables.register(self.var_key, new_value)     
                        
-                               #       parse the call backs    #               
                
-                               self.fg.parse_callbacks()       
-                       except: break                   
+               """
+               In an endless while loop: read the vector sink,
+               write to the variable, and parse the callbacks.
+               """
+               while self.keep_running:
+                       msg = self.msgq.delete_head()  # blocking read of 
message queue
+                       itemsize = int(msg.arg1())
+                       nitems = int(msg.arg2())                                
+                       s = msg.to_string()            # get the body of the 
msg as a string                            
+                       # There may be more than one number in the message.
+                       # If so, we take only the last one
+                       if nitems > 1:
+                               start = itemsize * (nitems - 1)
+                               s = s[start:start+itemsize]                     
        
+                       #       parse the data to a complex or float/int string 
#
+                       complex_data = numpy.fromstring (s, numpy.float32)
+                       if len(complex_data) == 2: new_value = "%f + 
%fj"%(complex_data[0], complex_data[1])
+                       else: new_value = "%f"%(complex_data[0],)
+                       #MUTEX.lock()   
+                       # write the new value #         
+                       Variables.reregister(self.var_key, new_value)           
                
+                       #       parse the call backs    #                       
        
+                       self.fg.parse_callbacks()       
+                       #MUTEX.unlock()
                
 def VariableSink(sb):
        type = Enum(all_choices, 1)
@@ -136,14 +144,11 @@
 The variable must be specified using its name without the "$" symbol. \
 The variable sink has a throttle automatically attatched to it at runtime to 
save the CPU.''') 
        def make(fg, type, var_key, samp_rate):
-               msgq = gr.msg_queue(1)  #msg size of 1
-               block = gr.message_sink(type.parse().get_num_bytes(), msgq, 
True)
+               msgq = gr.msg_queue(DEFAULT_QUEUE_LIMIT)
+               item_size = type.parse().get_num_bytes()
+               block = gr.message_sink(item_size, msgq, True)
                var_sink_thread = VariableSinkThread(fg, var_key.parse(), msgq)
-               var_sink_thread.start() #the thread begins
-               th = gr.throttle(type.parse().get_num_bytes(), 
samp_rate.parse())
-               fg.connect(th, block)
-               return th
-       return sb, make
+               return ThrottleHelper(item_size, samp_rate.parse(), block, True)
+       return sb, make 
        
-       
        
\ No newline at end of file

Modified: grc/trunk/src/SignalBlockDefs/Sources.py
===================================================================
--- grc/trunk/src/SignalBlockDefs/Sources.py    2007-06-29 17:29:46 UTC (rev 
5877)
+++ grc/trunk/src/SignalBlockDefs/Sources.py    2007-06-29 17:41:26 UTC (rev 
5878)
@@ -16,16 +16,15 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       SignalBlockDefs/Sources.py 
-       Josh Blum
-       Various data sources.
-"""
address@hidden SignalBlockDefs.Sources
+#Various data sources.
address@hidden Josh Blum
 
-from DataType import *
+from DataTypes import *
 from gnuradio import gr
 from SignalBlockConstants import *
 from Constants import DEFAULT_FILE_PATH
+import random
 
 MAX_SEED = 1000000     #constraint for seed generation in noise and random 
source 
 
@@ -38,10 +37,12 @@
        return sb, lambda fg, type, vlen: 
gr.null_source(type.parse().get_num_bytes()*vlen.parse())
        
 def SignalSource(sb):
-       type = Enum([('Complex', (gr.sig_source_c, Complex())), 
-                                       ('Float', (gr.sig_source_f, Float())), 
-                                       ('Int', (gr.sig_source_i, Int())), 
-                                       ('Short', (gr.sig_source_s, 
Short())),], 1)
+       type = Enum([
+               ('Complex', (gr.sig_source_c, Complex())), 
+               ('Float', (gr.sig_source_f, Float())), 
+               ('Int', (gr.sig_source_i, Int())), 
+               ('Short', (gr.sig_source_s, Short())),
+       ], 1)
        wfm_types = [('Constant', gr.GR_CONST_WAVE), 
                                        ('Cosine', gr.GR_COS_WAVE), 
                                        ('Sine', gr.GR_SIN_WAVE),]
@@ -51,11 +52,11 @@
        except: print ">>> sig source missing sqr, tri, saw waveform types"
        sb.add_output_socket('out', Variable(type, index=1))
        sb.add_param('Type', type, False, type=True)
-       sb.add_param('Sampling Rate', Float(default_samp_rate))
+       sb.add_param('Sampling Rate', Float(default_samp_rate), variable=True)
        sb.add_param('Wave Form', Enum(wfm_types, 1))
-       sb.add_param('Frequency', Float(1000))
-       sb.add_param('Ampliude', Float(1))
-       sb.add_param('Offset', Variable(type, index=1))
+       sb.add_param('Frequency', Float(1000), variable=True)
+       sb.add_param('Ampliude', Float(1), variable=True)
+       sb.add_param('Offset', Variable(type, index=1), variable=True)
        def make(fg, type, samp_freq, waveform, freq, amplitude, offset):
                block = type.parse()[0](samp_freq.parse(), waveform.parse(), 
freq.parse(), amplitude.parse(), offset.parse())           
                fg.add_callback(block.set_sampling_freq, samp_freq)
@@ -66,18 +67,19 @@
        return sb, make
        
 def NoiseSource(sb):
-       import random
-       type = Enum([('Complex', (gr.noise_source_c, Complex())), 
-                                       ('Float', (gr.noise_source_f, 
Float())), 
-                                       ('Int', (gr.noise_source_i, Int())), 
-                                       ('Short', (gr.noise_source_s, 
Short())),], 1)
+       type = Enum([
+               ('Complex', (gr.noise_source_c, Complex())), 
+               ('Float', (gr.noise_source_f, Float())), 
+               ('Int', (gr.noise_source_i, Int())), 
+               ('Short', (gr.noise_source_s, Short())),
+       ], 1)
        sb.add_output_socket('out', Variable(type, index=1))
        sb.add_param('Type', type, False, type=True)
        sb.add_param('Noise Type', Enum([('Uniform', gr.GR_UNIFORM), 
                                                                                
                ('Gaussian', gr.GR_GAUSSIAN), 
                                                                                
                ('Laplacian', gr.GR_LAPLACIAN),
                                                                                
                ('Impulse', gr.GR_IMPULSE)],1))
-       sb.add_param('Ampliude', Float(.1))
+       sb.add_param('Ampliude', Float(.1), variable=True)
        sb.add_param('Seed', Int(random.randint(0, MAX_SEED), min=0, 
max=MAX_SEED))     
        def make(fg, type, noise_type, amplitude, seed):
                block = type.parse()[0](noise_type.parse(), amplitude.parse(), 
seed.parse())    
@@ -86,7 +88,6 @@
        return sb, make 
        
 def FileSource(sb):
-       import Constants
        type = Enum(all_choices, 1)     
        vlen = Int(1, min=1)
        sb.add_output_socket('out', Variable(type), vlen=vlen)
@@ -105,11 +106,13 @@
        return sb, lambda fg, samp_rate: audio.source(samp_rate.parse())
                
 def VectorSource(sb):
-       enum_all_vector_data_types = Enum([('Complex Vector', 
(gr.vector_source_c, ComplexVector(), Complex())),
-                                                                       ('Float 
Vector', (gr.vector_source_f, FloatVector(), Float())),
-                                                                       ('Int 
Vector', (gr.vector_source_i, IntVector(), Int())),
-                                                                       ('Short 
Vector', (gr.vector_source_s, ShortVector(), Short())),
-                                                                       ('Byte 
Vector', (gr.vector_source_b, ByteVector(), Byte()))], 1)#index of 1 makes the 
default float
+       enum_all_vector_data_types = Enum([
+               ('Complex Vector', (gr.vector_source_c, ComplexVector(), 
Complex())),
+               ('Float Vector', (gr.vector_source_f, FloatVector(), Float())),
+               ('Int Vector', (gr.vector_source_i, IntVector(), Int())),
+               ('Short Vector', (gr.vector_source_s, ShortVector(), Short())),
+               ('Byte Vector', (gr.vector_source_b, ByteVector(), Byte()))
+       ], 1)#index of 1 makes the default float
        sb.add_output_socket('out', Variable(enum_all_vector_data_types, 
index=2))
        sb.add_param('Type', enum_all_vector_data_types, False, type=True)
        sb.add_param('Vector', Variable(enum_all_vector_data_types, "0, 1", 
index=1))
@@ -120,11 +123,12 @@
        return sb, lambda fg, type, vector, repeat: 
type.parse()[0](vector.parse(), repeat.parse())     
        
 def RandomVector(sb):
-       import random
-       enum_all_vector_data_types = Enum([('Float', (gr.vector_source_f, 
Float())),
-                                                                       ('Int', 
(gr.vector_source_i, Int())),
-                                                                       
('Short', (gr.vector_source_s, Short())),
-                                                                       
('Byte', (gr.vector_source_b, Byte()))])
+       enum_all_vector_data_types = Enum([
+               ('Float', (gr.vector_source_f, Float())),
+               ('Int', (gr.vector_source_i, Int())),
+               ('Short', (gr.vector_source_s, Short())),
+               ('Byte', (gr.vector_source_b, Byte()))
+       ])
        sb.add_output_socket('out', Variable(enum_all_vector_data_types, 
index=1))
        sb.add_param('Type', enum_all_vector_data_types, False, type=True)
        sb.add_param('Vector Length', Int(1000, min=1))

Modified: grc/trunk/src/SignalBlockDefs/Trellis.py
===================================================================
--- grc/trunk/src/SignalBlockDefs/Trellis.py    2007-06-29 17:29:46 UTC (rev 
5877)
+++ grc/trunk/src/SignalBlockDefs/Trellis.py    2007-06-29 17:41:26 UTC (rev 
5878)
@@ -16,13 +16,11 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       SignalBlockDefs/Trellis.py 
-       Josh Blum
-       Trellis Blocks by: Achilleas Anastasopoulos
-"""
address@hidden SignalBlockDefs.Trellis
+#Trellis blocks.
address@hidden Achilleas Anastasopoulos
 
-from DataType import *
+from DataTypes import *
 from gnuradio import gr
 from SignalBlockConstants import all_choices
 from Constants import DEFAULT_FILE_PATH

Modified: grc/trunk/src/SignalBlockDefs/USRP.py
===================================================================
--- grc/trunk/src/SignalBlockDefs/USRP.py       2007-06-29 17:29:46 UTC (rev 
5877)
+++ grc/trunk/src/SignalBlockDefs/USRP.py       2007-06-29 17:41:26 UTC (rev 
5878)
@@ -16,18 +16,21 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       SignalBlockDefs/USRP.py 
-       Josh Blum
-       The source and sink blocks for the USRP.
-"""
address@hidden SignalBlockDefs.USRP
+#The source and sink blocks for the USRP.
address@hidden Josh Blum
 
-from DataType import *
+from DataTypes import *
 from gnuradio import gr
 
 def set_freq(u, which, subdev, freq, verbose=False):
-       """ Set the center frequency for the given subdevice.   
-       The which paramater specifies which DDC/DUC to use      """
+       """!
+       Set the carrier frequency for the given subdevice.      
+       @param u the usrp source/sink
+       @param which specifies the DDC/DUC number
+       @param freq the carrier frequency in Hz
+       @param verbose if true, print usrp tuning information
+       """
        r = u.tune(which, subdev, freq)
        if verbose:     
                if r:
@@ -36,29 +39,24 @@
                        print "  r.dxc_freq      =", r.dxc_freq
                        print "  r.residual_freq =", r.residual_freq
                        print "  r.inverted      =", r.inverted
-               else:
-                       print "  Failed!"       
+               else: print "  Failed!" 
 
-usrp_rx_choices = [('Auto', None),
-                                               ('Side A:0', (0, 0)), 
-                                               ('Side B:0', (1, 0)),
-                                               ('Side A:1', (0, 1)), 
-                                               ('Side B:1', (1, 1)),]
-
-usrp_tx_choices = [('Auto', None),
-                                               ('Side A', (0, 0)), 
-                                               ('Side B', (1, 0)),]
-                                       
 def USRPSource(sb):
        from gnuradio import usrp
        type = Enum([('Complex', (usrp.source_c, Complex())), ('IShort', 
(usrp.source_s, Short()))])
        sb.add_output_socket('out', Variable(type, index=1))
        sb.add_param('Output Type', type, False, type=True)
        sb.add_param('Unit Number', Int(0, min=0))
-       sb.add_param('Side:Subdevice', Enum(usrp_rx_choices))
-       sb.add_param('Frequency', Float())
+       sb.add_param('Side:Subdevice', Enum([
+               ('Auto', None),
+               ('Side A:0', (0, 0)), 
+               ('Side B:0', (1, 0)),
+               ('Side A:1', (0, 1)), 
+               ('Side B:1', (1, 1)),
+       ]))
+       sb.add_param('Frequency', Float(), variable=True)
        sb.add_param('Decimation', Int(200, min=1))
-       sb.add_param('Gain', Float(100))
+       sb.add_param('Gain', Float(100), variable=True)
        sb.add_param('Mux', Hex())
        sb.set_docs('''\
 The USRP source outputs 64 Megasamples per second / decimation.
@@ -88,10 +86,14 @@
        sb.add_input_socket('in', Variable(type, index=1))
        sb.add_param('Input Type', type, False, type=True)
        sb.add_param('Unit Number', Int(0, min=0))
-       sb.add_param('Side', Enum(usrp_tx_choices))
-       sb.add_param('Frequency', Float())
+       sb.add_param('Side', Enum([
+               ('Auto', None),
+               ('Side A', (0, 0)), 
+               ('Side B', (1, 0)),
+       ]))
+       sb.add_param('Frequency', Float(), variable=True)
        sb.add_param('Interpolation', Int(200, min=1))
-       sb.add_param('Gain', Float(0))  
+       sb.add_param('Gain', Float(0), variable=True)   
        sb.add_param('Mux', Hex())
        sb.set_docs('''\
 The USRP sink inputs 128 Megasamples per second / interpolation.
@@ -123,11 +125,11 @@
        sb.add_input_socket('Bin', Variable(type, index=1))
        sb.add_param('Input Type', type, False, type=True)
        sb.add_param('Unit Number', Int(0, min=0))
-       sb.add_param('FrequencyA', Float())
-       sb.add_param('FrequencyB', Float())
+       sb.add_param('FrequencyA', Float(), variable=True)
+       sb.add_param('FrequencyB', Float(), variable=True)
        sb.add_param('Interpolation', Int(200, min=1))
-       sb.add_param('GainA', Float(0)) 
-       sb.add_param('GainB', Float(0))
+       sb.add_param('GainA', Float(0), variable=True)  
+       sb.add_param('GainB', Float(0), variable=True)
        sb.add_param('Mux', Hex(default_mux))   
        sb.set_docs('''\
 The USRP sink inputs 128 Megasamples per second / interpolation. \

Modified: grc/trunk/src/SignalBlockDefs/__init__.py
===================================================================
--- grc/trunk/src/SignalBlockDefs/__init__.py   2007-06-29 17:29:46 UTC (rev 
5877)
+++ grc/trunk/src/SignalBlockDefs/__init__.py   2007-06-29 17:41:26 UTC (rev 
5878)
@@ -16,11 +16,8 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       SignalBlockDefs/__init__.py 
-       Josh Blum
-       Build a signal block represented by a specific tag.
-"""
address@hidden SignalBlockDefs.__init__
+#Package for signal block definitions.
address@hidden Josh Blum
 
-from DataType import *
 from SignalBlockTree import SB_TREE,get_signal_block,TagNotFoundException

Modified: grc/trunk/src/StateCache.py
===================================================================
--- grc/trunk/src/StateCache.py 2007-06-29 17:29:46 UTC (rev 5877)
+++ grc/trunk/src/StateCache.py 2007-06-29 17:41:26 UTC (rev 5878)
@@ -16,23 +16,25 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""    
-       StateCache.py   
-       Josh Blum
-       Stores the flow graph states to drive the undo/redo and save interface.
-"""
address@hidden StateCache
+#Stores the flow graph states to drive the undo/redo and save interface.
address@hidden Josh Blum
 
 from Actions import FLOW_GRAPH_UNDO, FLOW_GRAPH_REDO, get_action_from_name
 from Constants import STATE_CACHE_SIZE
 
 class StateCache:
-       """ The state cache is an interface to a list to record data/states and 
to revert to previous states.   """     
+       """
+       The state cache is an interface to a list to record data/states and to 
revert to previous states.
+       States are recorded into the list in a circular fassion by using an 
index for the current state,
+       and counters for the range where states are stored.
+       """     
        def __init__(self, initial_state):
-               """ The initial state is given as well as the handler for the 
windows 
-               so that redo/undo/save can be properly handled. """
-               self.states = list()
-               for i in range(STATE_CACHE_SIZE):
-                       self.states.append(None)
+               """!
+               StateCache constructor.
+               @param initial_state the intial state (nested data)
+               """
+               self.states = [None for i in range(STATE_CACHE_SIZE)] #fill 
states
                self.current_state_index = 0
                self.num_prev_states = 0
                self.num_next_states = 0
@@ -41,40 +43,50 @@
                get_action_from_name(FLOW_GRAPH_REDO).set_sensitive(False)
                        
        def save_new_state(self, state):
-               """ Place the new state at the next index and add one to the 
number of previous states. """
+               """!
+               Save a new state.
+               Place the new state at the next index and add one to the number 
of previous states.
+               @param state the new state
+               """
                self.current_state_index = (self.current_state_index + 
1)%STATE_CACHE_SIZE
                self.states[self.current_state_index] = state           
                self.num_prev_states = self.num_prev_states + 1
-               if self.num_prev_states == STATE_CACHE_SIZE:
-                       self.num_prev_states = STATE_CACHE_SIZE - 1
+               if self.num_prev_states == STATE_CACHE_SIZE: 
self.num_prev_states = STATE_CACHE_SIZE - 1
                self.num_next_states = 0
                get_action_from_name(FLOW_GRAPH_UNDO).set_sensitive(True)
                get_action_from_name(FLOW_GRAPH_REDO).set_sensitive(False)
                        
        def get_current_state(self):
-               """     get the state at the current index      """
+               """!
+               Get the state at the current index.
+               @return the current state (nested data)
+               """
                return self.states[self.current_state_index]            
        
        def get_prev_state(self):
-               """     get the previous state if possible and decrement the 
current index.     """
+               """!
+               Get the previous state and decrement the current index.
+               @return the previous state or None
+               """
                if self.num_prev_states > 0:
                        self.current_state_index = (self.current_state_index + 
STATE_CACHE_SIZE -1)%STATE_CACHE_SIZE
                        self.num_next_states = self.num_next_states + 1
                        self.num_prev_states = self.num_prev_states - 1
-                       if self.num_prev_states == 0:
-                               
get_action_from_name(FLOW_GRAPH_UNDO).set_sensitive(False)
+                       if self.num_prev_states == 0: 
get_action_from_name(FLOW_GRAPH_UNDO).set_sensitive(False)
                        
get_action_from_name(FLOW_GRAPH_REDO).set_sensitive(True)
                        return self.get_current_state()
                return None             
        
        def get_next_state(self):
-               """     get the next state if possible and increment the 
current index. """
+               """!
+               Get the nest state and increment the current index.
+               @return the next state or None
+               """
                if self.num_next_states > 0:
                        self.current_state_index = (self.current_state_index + 
1)%STATE_CACHE_SIZE
                        self.num_next_states = self.num_next_states - 1
                        self.num_prev_states = self.num_prev_states + 1
-                       if self.num_next_states == 0:
-                               
get_action_from_name(FLOW_GRAPH_REDO).set_sensitive(False)
+                       if self.num_next_states == 0: 
get_action_from_name(FLOW_GRAPH_REDO).set_sensitive(False)
                        
get_action_from_name(FLOW_GRAPH_UNDO).set_sensitive(True)
                        return self.get_current_state()
                return None

Modified: grc/trunk/src/Variables.py
===================================================================
--- grc/trunk/src/Variables.py  2007-06-29 17:29:46 UTC (rev 5877)
+++ grc/trunk/src/Variables.py  2007-06-29 17:41:26 UTC (rev 5878)
@@ -16,40 +16,48 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
-"""
-       Variables.py 
-       Josh Blum
-       Holds variable names, their values, and ranges.
-"""
address@hidden Variables
+#Holds variable names, their values, and ranges.
address@hidden Josh Blum
 
 from Constants import DEFAULT_SLIDER_STEPS
 
-''' Hold the current variables for the running program. The dictionary 
-       maps keys to values,ranges.     '''
+##Hold the variables for the executing program. This dictionary maps keys to 
values,ranges.
 VARS_DICT = dict()
 
-VAR_MARKER = '$' #place this character before a variable
+##place this character before a variable
+VAR_MARKER = '$' 
 
-get_keys = VARS_DICT.keys      #get a list of variable keys
+##get a list of variable keys
+get_keys = VARS_DICT.keys      
 
 def clear_vars():
-       ''' Call unregister on every var.       '''
+       """Call unregister on every var key."""
        for key in VARS_DICT.keys(): unregister(key)
 
 def register(key, value, min='', max='', step=''):
-       ''' Change/Add the value,range for a given key. 
+       """!
+       Register the value and a [range] for a given key.       
+       The range is a min, max, and a step size.
        If no range is specified, value can be any string.
        If a range is specified min, max, and step numbers have to be parsable 
as floats.
        Partially completed ranges will be intelligently filled in.
        Partially blanked ranges will be cleared.       
-       All parameters must be strings! '''
+       All parameters must be strings! 
+       @param key the variable key
+       @param value the value
+       @param min the mimimum of the variable's range
+       @param max the maximum of the variable's range
+       @param step the step size for the variable's range
+       @throw Exception invalid arguments      
+       """
        #       make sure that all parameters are strings #
        for var in (key, value, min, max, step):
-               if type(var) != type(str()): raise TypeError('"%s" var is not 
of type string'%var)
+               if type(var) != type(str()): raise TypeError, '"%s" var is not 
of type string'%var
        #       make sure that the key does not already exists #        
-       if has_key(key): raise KeyError('"%s" already exists!'%key)
+       if has_key(key): raise KeyError, '"%s" already exists!'%key
        #       make sure that the key name is valid #
-       if not is_key_name_valid(key): raise KeyError('"%s" is a invalid key 
name!'%key)        
+       if not is_key_name_valid(key): raise KeyError, '"%s" is a invalid key 
name!'%key        
        #       count the number of blank strings in min, max, and step #
        num_blanks = 0
        for var in (min, max, step):
@@ -57,32 +65,57 @@
        if num_blanks == 3: pass #allow the vars to be registered normally
        else:   #num_blanks is less than 3
                try: float(value)       #make sure that value is a float
-               except ValueError: raise TypeError('"%s" must be parseable to 
type float'%value)
+               except ValueError: raise TypeError, '"%s" must be parseable to 
type float'%value
                if num_blanks == 2:     #do something intelligent to fill the 
two blanks
                        #       make sure that the non-blank value is a float   
#
                        for var in (min, max, step):
                                if var != '':   #only try to parse the 
non-blank variable
                                        try: float(var) #make sure that value 
is a float
-                                       except ValueError: raise 
TypeError('"%s" must be parseable to type float'%var)
+                                       except ValueError: raise TypeError, 
'"%s" must be parseable to type float'%var
                        #       determine the non-blank var and generate the 
other two vars     #
                        if min != '': max = value
                        elif max != '': min = value
-                       elif step != '': raise ValueError('step cannot have a 
value when min and max are blank')
+                       elif step != '': raise ValueError, 'step cannot have a 
value when min and max are blank'
                elif num_blanks == 1:   #clear all vars for min, max, and step
                        if step != '': min = max = step = '' #only if step was 
not the blank one
                elif num_blanks == 0: pass #none were blank, move onto the 
validity check
        # check the values for validity #       
        if min != '' and max != '': #only check for validity if min and max are 
non blank
                if float(value) < float(min) or float(value) > float(max) or 
float(min) >= float(max):
-                       raise ValueError('%s is not greater than or equal to %s 
and less than and equal to %s'%(value, min, max))               
+                       raise ValueError, '%s is not greater than or equal to 
%s and less than and equal to %s'%(value, min, max)       
                if step == '': step = str((float(max) - 
float(min))/float(DEFAULT_SLIDER_STEPS))
-               if (float(max) - float(min))/float(step) < 1: raise 
ValueError('%s step size is too large'%step) 
+               if (float(max) - float(min))/float(step) < 1: raise ValueError, 
'%s step size is too large'%step
        ###     register        the values ###
        VARS_DICT[key] = (value, min, max, step)
        
+def reregister(key, new_value):
+       """!
+       Register a new value for variable: 
+       Unregister the variable and try to register it with the new values.
+       If an exception is raised, register the old values.
+       @param key the variable key
+       @param new_value the value      
+       @throw Exception invalid arguments      
+       @return true if the variable was registered
+       """
+       value, min, max, step = get_values(key)         
+       if new_value != value:
+               unregister(key)
+               try: 
+                       register(key, new_value, min, max, step)
+                       return True
+               except Exception, e: 
+                       register(key, value, min, max, step)
+                       raise e
+       else: return False
+       
 def is_key_name_valid(key_name):
-       ''' True if the key name is valid. Valid keys start with a letter and 
-       may contain only letters, numbers, underscrores(_).     '''
+       """!
+       Is the key valid?
+       Valid keys start with a letter and may contain only letters, numbers, 
underscrores(_).
+       @param key_name the potential key name (string)
+       @return true if the key name is valid
+       """
        if len(key_name) == 0 or len(key_name) > 20: return False
        for i,char in enumerate(key_name):
                if i == 0 and not char.isalpha(): return False
@@ -90,31 +123,52 @@
        return True
 
 def unregister(key):
-       '''     Remove a key if it exisits      '''     
+       """!
+       Remove a key if it exisits.
+       @param key the variable key to remove
+       """     
        if has_key(key): del VARS_DICT[key]
                                                        
 def has_key(key):
-       ''' Is the key in this dict?    '''     
+       """!
+       Is the key in this registry?
+       @param key the variable key potentially in the registry
+       @return true if key is in the registry
+       """     
        return key in VARS_DICT
 
 def get_values(key):
-       ''' Get the tuple for this key, otherwise None. '''
-       if has_key(key): return VARS_DICT[key]
-       else: return None
+       """!
+       Get the valuesfor this key.
+       @param key the variable key
+       @return the (value,min,max,step) tuple
+       """
+       return VARS_DICT[key]
        
 def is_ranged(key):
-       ''' Does this variable have a range:
-               min, max, and step are not blank.       '''
+       """!
+       Does this variable have a range?
+       The variable has a range if min, max, and step are non-blank.
+       Only check the minimum for non-blankness.
+       @param key the variable key
+       @return true if the variable has a range
+       """
        return get_values(key)[1] != ''
                
 def get_value(key):
-       ''' Get the value for this key, otherwise None. '''
-       if has_key(key): return VARS_DICT[key][0]
-       else: return None
+       """!
+       Get the value for this key.
+       @param key the variable key
+       @return the value
+       """
+       return get_values(key)[0]
        
 def replace_var_instances(string):
-       ''' Replace every instance of a marker + variable key 
-               with the string representation of the variable. '''
+       """!
+       Replace every instance of a marker + variable key with the string 
representation of the variable.
+       @param string the input string
+       @return the string with variables substituted out
+       """
        for key in get_keys(): string = string.replace(VAR_MARKER + key, 
get_value(key))
        return string           
 
@@ -122,9 +176,13 @@
 ##     Import the Variables
 ##########################################################################     
 def from_nested_data(nested_data):
-       ''' Clear all of the registered variables,
-               and load all variables from nested data.        
-               Return a list of keys, in the order they were added.    '''
+       """!
+       Load the variables from nested data.    
+       Clear all of the registered variables,
+       and load all variables from nested data.        
+       @param nested_data the nested data for variables        
+       @return a list of keys, in the order
+       """
        import ParseXML,Messages
        find_data = ParseXML.find_data
        clear_vars()
@@ -155,9 +213,8 @@
                                pass    #dont register!         
        return keys
        
-if __name__ == '__main__':
-       print is_key_name_valid('sdfa13_fsf_dsd')               
-       print is_key_name_valid('2sdfa13_fsf_dsd')              
-       print is_key_name_valid('sdfa13._fsf_fdsd')             
+if __name__ == '__main__':     
+       """Use the main method to test variable's functions."""
+       pass
 
                
\ No newline at end of file





reply via email to

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