From 74eb0b9a9a685a32be21db30f097a22ddf3ec4cf Mon Sep 17 00:00:00 2001
From: Tim O'Shea <tim.oshea753@gmail.com>
Date: Mon, 8 Jul 2013 10:29:19 -0400
Subject: grc: Fix whitespace issue in grc to use proper spaces

Remove all \t's to match the rest of GNU Radio
---
 grc/base/Block.py                           |  704 +++++++++--------
 grc/base/Connection.py                      |  183 +++--
 grc/base/Element.py                         |  132 ++--
 grc/base/FlowGraph.py                       |  552 +++++++-------
 grc/base/Param.py                           |  314 ++++----
 grc/base/ParseXML.py                        |  166 ++---
 grc/base/Platform.py                        |  310 ++++----
 grc/base/Port.py                            |  173 +++--
 grc/base/block_tree.dtd                     |    6 +-
 grc/base/flow_graph.dtd                     |    6 +-
 grc/base/odict.py                           |  146 ++--
 grc/examples/xmlrpc/xmlrpc_client_script.py |   22 +-
 grc/grc_gnuradio/blks2/__init__.py          |    4 +-
 grc/grc_gnuradio/blks2/error_rate.py        |  204 ++---
 grc/grc_gnuradio/blks2/packet.py            |  344 ++++-----
 grc/grc_gnuradio/blks2/selector.py          |  214 +++---
 grc/grc_gnuradio/blks2/tcp.py               |   80 +-
 grc/gui/ActionHandler.py                    |  782 ++++++++++---------
 grc/gui/Actions.py                          |  370 ++++-----
 grc/gui/Bars.py                             |  206 ++---
 grc/gui/Block.py                            |  353 +++++----
 grc/gui/BlockTreeWindow.py                  |  336 ++++-----
 grc/gui/Connection.py                       |  256 +++----
 grc/gui/Dialogs.py                          |  130 ++--
 grc/gui/DrawingArea.py                      |  202 ++---
 grc/gui/Element.py                          |  445 ++++++-----
 grc/gui/FileDialogs.py                      |  244 +++---
 grc/gui/FlowGraph.py                        | 1079 +++++++++++++--------------
 grc/gui/MainWindow.py                       |  542 +++++++-------
 grc/gui/Messages.py                         |   84 +--
 grc/gui/NotebookPage.py                     |  364 ++++-----
 grc/gui/Param.py                            |  262 +++----
 grc/gui/Platform.py                         |    2 +-
 grc/gui/Port.py                             |  388 +++++-----
 grc/gui/Preferences.py                      |   84 +--
 grc/gui/PropsDialog.py                      |  294 ++++----
 grc/gui/StateCache.py                       |  146 ++--
 grc/gui/Utils.py                            |  154 ++--
 grc/python/Block.py                         |  376 +++++-----
 grc/python/Connection.py                    |   47 +-
 grc/python/Constants.py                     |   60 +-
 grc/python/FlowGraph.py                     |  419 +++++------
 grc/python/Generator.py                     |  236 +++---
 grc/python/Param.py                         |  810 ++++++++++----------
 grc/python/Platform.py                      |   66 +-
 grc/python/Port.py                          |  388 +++++-----
 grc/python/block.dtd                        |   16 +-
 grc/python/convert_hier.py                  |  172 ++---
 grc/python/default_flow_graph.grc           |   70 +-
 grc/python/expr_utils.py                    |  264 +++----
 grc/python/extract_docs.py                  |   94 +--
 grc/python/flow_graph.tmpl                  |  380 +++++-----
 grc/scripts/gnuradio-companion              |   54 +-
 53 files changed, 6804 insertions(+), 6931 deletions(-)

(limited to 'grc')

diff --git a/grc/base/Block.py b/grc/base/Block.py
index 1fb0db9ad8..b0b96422a7 100644
--- a/grc/base/Block.py
+++ b/grc/base/Block.py
@@ -25,376 +25,346 @@ from UserDict import UserDict
 from .. gui import Actions
 
 class TemplateArg(UserDict):
-	"""
-	A cheetah template argument created from a param.
-	The str of this class evaluates to the param's to code method.
-	The use of this class as a dictionary (enum only) will reveal the enum opts.
-	The __call__ or () method can return the param evaluated to a raw python data type.
-	"""
-
-	def __init__(self, param):
-		UserDict.__init__(self)
-		self._param = param
-		if param.is_enum():
-			for key in param.get_opt_keys():
-				self[key] = str(param.get_opt(key))
-
-	def __str__(self):
-		return str(self._param.to_code())
-
-	def __call__(self):
-		return self._param.get_evaluated()
+    """
+    A cheetah template argument created from a param.
+    The str of this class evaluates to the param's to code method.
+    The use of this class as a dictionary (enum only) will reveal the enum opts.
+    The __call__ or () method can return the param evaluated to a raw python data type.
+    """
+
+    def __init__(self, param):
+        UserDict.__init__(self)
+        self._param = param
+        if param.is_enum():
+            for key in param.get_opt_keys():
+                self[key] = str(param.get_opt(key))
+
+    def __str__(self):
+        return str(self._param.to_code())
+
+    def __call__(self):
+        return self._param.get_evaluated()
 
 def _get_keys(lst): return [elem.get_key() for elem in lst]
 def _get_elem(lst, key):
-	try: return lst[_get_keys(lst).index(key)]
-	except ValueError: raise ValueError, 'Key "%s" not found in %s.'%(key, _get_keys(lst))
+    try: return lst[_get_keys(lst).index(key)]
+    except ValueError: raise ValueError, 'Key "%s" not found in %s.'%(key, _get_keys(lst))
 
 class Block(Element):
 
-	def __init__(self, flow_graph, n):
-		"""
-		Make a new block from nested data.
-		
-		Args:
-		    flow: graph the parent element
-		    n: the nested odict
-		
-		Returns:
-		    block a new block
-		"""
-		#build the block
-
-		Element.__init__(self, flow_graph)
-		#grab the data
-		params = n.findall('param')
-		sources = n.findall('source')
-		sinks = n.findall('sink')
-		self._name = n.find('name')
-		self._key = n.find('key')
-		self._category = n.find('category') or ''
-		self._grc_source = n.find('grc_source') or ''
-		self._block_wrapper_path = n.find('block_wrapper_path')
-		self._bussify_sink = n.find('bus_sink')
-		self._bussify_source = n.find('bus_source')
-		
-		
-		#create the param objects
-		self._params = list()
-		#add the id param
-		self.get_params().append(self.get_parent().get_parent().Param(
-			block=self,
-			n=odict({
-				'name': 'ID',
-				'key': 'id',
-				'type': 'id',
-			})
-		))
-		self.get_params().append(self.get_parent().get_parent().Param(
-			block=self,
-			n=odict({
-				'name': 'Enabled',
-				'key': '_enabled',
-				'type': 'raw',
-				'value': 'True',
-				'hide': 'all',
-			})
-		))
-		for param in map(lambda n: self.get_parent().get_parent().Param(block=self, n=n), params):
-			key = param.get_key()
-			#test against repeated keys
-			if key in self.get_param_keys():
-				raise Exception, 'Key "%s" already exists in params'%key
-			#store the param
-			self.get_params().append(param)
-		#create the source objects
-		self._sources = list()
-		for source in map(lambda n: self.get_parent().get_parent().Port(block=self, n=n, dir='source'), sources):
-			key = source.get_key()
-			#test against repeated keys
-			if key in self.get_source_keys():
-				raise Exception, 'Key "%s" already exists in sources'%key
-			#store the port
-			self.get_sources().append(source)
-		self.back_ofthe_bus(self.get_sources())
-		#create the sink objects
-		self._sinks = list()
-		for sink in map(lambda n: self.get_parent().get_parent().Port(block=self, n=n, dir='sink'), sinks):
-			key = sink.get_key()
-			#test against repeated keys
-			if key in self.get_sink_keys():
-				raise Exception, 'Key "%s" already exists in sinks'%key
-			#store the port
-			self.get_sinks().append(sink)
-		self.back_ofthe_bus(self.get_sinks())
-		self.current_bus_structure = {'source':'','sink':''};
-		
-
-	def back_ofthe_bus(self, portlist):
-		portlist.sort(key=lambda a: a.get_type() == 'bus');
-		
-
-	def filter_bus_port(self, ports): 
-		buslist = [i for i in ports if i.get_type() == 'bus'];
-		if len(buslist) == 0:
-			return ports;
-		else:
-			return buslist;
-			
-	def get_enabled(self):
-		"""
-		Get the enabled state of the block.
-		
-		Returns:
-		    true for enabled
-		"""
-		try: return eval(self.get_param('_enabled').get_value())
-		except: return True
-
-	def set_enabled(self, enabled):
-		"""
-		Set the enabled state of the block.
-		
-		Args:
-		    enabled: true for enabled
-		"""
-		self.get_param('_enabled').set_value(str(enabled))
-
-	def __str__(self): return 'Block - %s - %s(%s)'%(self.get_id(), self.get_name(), self.get_key())
-
-	def get_id(self): return self.get_param('id').get_value()
-	def is_block(self): return True
-	def get_name(self): return self._name
-	def get_key(self): return self._key
-	def get_category(self): return self._category
-	def get_doc(self): return ''
-	def get_ports(self): return self.get_sources() + self.get_sinks()
-	def get_ports_gui(self): return self.filter_bus_port(self.get_sources()) + self.filter_bus_port(self.get_sinks());
-		
-
-
-	def get_children(self): return self.get_ports() + self.get_params()
-	def get_children_gui(self): return self.get_ports_gui() + self.get_params()
-	def get_block_wrapper_path(self): return self._block_wrapper_path
-
-	##############################################
-	# Access Params
-	##############################################
-	def get_param_keys(self): return _get_keys(self._params)
-	def get_param(self, key): return _get_elem(self._params, key)
-	def get_params(self): return self._params
-
-	##############################################
-	# Access Sinks
-	##############################################
-	def get_sink_keys(self): return _get_keys(self._sinks)
-	def get_sink(self, key): return _get_elem(self._sinks, key)
-	def get_sinks(self): return self._sinks
-	def get_sinks_gui(self): return self.filter_bus_port(self.get_sinks())
-
-	##############################################
-	# Access Sources
-	##############################################
-	def get_source_keys(self): return _get_keys(self._sources)
-	def get_source(self, key): return _get_elem(self._sources, key)
-	def get_sources(self): return self._sources
-	def get_sources_gui(self): return self.filter_bus_port(self.get_sources()); 
-		
-	
-
-	def get_connections(self):
-		return sum([port.get_connections() for port in self.get_ports()], [])
-
-	def resolve_dependencies(self, tmpl):
-		"""
-		Resolve a paramater dependency with cheetah templates.
-		
-		Args:
-		    tmpl: the string with dependencies
-		
-		Returns:
-		    the resolved value
-		"""
-		tmpl = str(tmpl)
-		if '$' not in tmpl: return tmpl
-		n = dict((p.get_key(), TemplateArg(p)) for p in self.get_params())
-
-		try: return str(Template(tmpl, n))
-		except Exception, e: return "-------->\n%s: %s\n<--------"%(e, tmpl)
-
-	##############################################
-	# Controller Modify
-	##############################################
-	def type_controller_modify(self, direction):
-		"""
-		Change the type controller.
-		
-		Args:
-		    direction: +1 or -1
-		
-		Returns:
-		    true for change
-		"""
-		changed = False
-		type_param = None
-		for param in filter(lambda p: p.is_enum(), self.get_params()):
-			children = self.get_ports() + self.get_params()
-			#priority to the type controller
-			if param.get_key() in ' '.join(map(lambda p: p._type, children)): type_param = param
-			#use param if type param is unset
-			if not type_param: type_param = param
-		if type_param:
-			#try to increment the enum by direction
-			try:
-				keys = type_param.get_option_keys()
-				old_index = keys.index(type_param.get_value())
-				new_index = (old_index + direction + len(keys))%len(keys)
-				type_param.set_value(keys[new_index])
-				changed = True
-			except: pass
-		return changed
-
-	def port_controller_modify(self, direction):
-		"""
-		Change the port controller.
-		
-		Args:
-		    direction: +1 or -1
-		
-		Returns:
-		    true for change
-		"""
-		return False
-
-
-	def form_bus_structure(self, direc):
-		if direc == 'source':
-			get_p = self.get_sources;
-			get_p_gui = self.get_sources_gui;
-			bus_structure = self.get_bus_structure('source');
-		else:
-			get_p = self.get_sinks;
-			get_p_gui = self.get_sinks_gui
-			bus_structure = self.get_bus_structure('sink');
-
-		struct = [range(len(get_p()))];
-		if True in map(lambda a: isinstance(a.get_nports(), int), get_p()):
-				
-
-			structlet = [];
-			last = 0;
-			for j in [i.get_nports() for i in get_p() if isinstance(i.get_nports(), int)]:
-				structlet.extend(map(lambda a: a+last, range(j)));
-				last = structlet[-1] + 1;
-				struct = [structlet];
-		if bus_structure:
-				
-			struct = bus_structure
-
-		self.current_bus_structure[direc] = struct;
-		return struct
-
-	def bussify(self, n, direc):
-		if direc == 'source':
-			get_p = self.get_sources;
-			get_p_gui = self.get_sources_gui;
-			bus_structure = self.get_bus_structure('source');
-		else:
-			get_p = self.get_sinks;
-			get_p_gui = self.get_sinks_gui
-			bus_structure = self.get_bus_structure('sink');
-
-
-		for elt in get_p():
-			for connect in elt.get_connections():
-				self.get_parent().remove_element(connect);
-
-		
-		
-		
-		
-
-		if (not 'bus' in map(lambda a: a.get_type(), get_p())) and len(get_p()) > 0:
-
-			struct = self.form_bus_structure(direc);
-			self.current_bus_structure[direc] = struct;
-			if get_p()[0].get_nports():
-				n['nports'] = str(1);
-		
-			for i in range(len(struct)):
-				n['key'] = str(len(get_p()));
-				n = odict(n);
-				port = self.get_parent().get_parent().Port(block=self, n=n, dir=direc);
-				get_p().append(port);
-				
-
-			
-				
-		elif 'bus' in map(lambda a: a.get_type(), get_p()):
-			for elt in get_p_gui():
-				get_p().remove(elt);
-			self.current_bus_structure[direc] = ''
-			
-		
-
-	##############################################
-	## Import/Export Methods
-	##############################################
-	def export_data(self):
-		"""
-		Export this block's params to nested data.
-		
-		Returns:
-		    a nested data odict
-		"""
-		n = odict()
-
-			
-		n['key'] = self.get_key()
-		n['param'] = map(lambda p: p.export_data(), self.get_params())
-		if 'bus' in map(lambda a: a.get_type(), self.get_sinks()):
-			n['bus_sink'] = str(1);
-		if 'bus' in map(lambda a: a.get_type(), self.get_sources()):
-			n['bus_source'] = str(1);
-		return n
-
-	def import_data(self, n):
-		"""
-		Import this block's params from nested data.
-		Any param keys that do not exist will be ignored.
-		Since params can be dynamically created based another param,
-		call rewrite, and repeat the load until the params stick.
-		This call to rewrite will also create any dynamic ports
-		that are needed for the connections creation phase.
-		
-		Args:
-		    n: the nested data odict
-		"""
-		
-		get_hash = lambda: hash(tuple(map(hash, self.get_params())))
-		my_hash = 0
-		while get_hash() != my_hash:
-			params_n = n.findall('param')
-			for param_n in params_n:
-				key = param_n.find('key')
-				value = param_n.find('value')
-				#the key must exist in this block's params
-				if key in self.get_param_keys():
-					self.get_param(key).set_value(value)
-			#store hash and call rewrite
-			my_hash = get_hash()
-			self.rewrite()
-		bussinks = n.findall('bus_sink');
-		if len(bussinks) > 0 and not self._bussify_sink:
-			self.bussify({'name':'bus','type':'bus'}, 'sink')
-		elif len(bussinks) > 0:
-			self.bussify({'name':'bus','type':'bus'}, 'sink')
-			self.bussify({'name':'bus','type':'bus'}, 'sink')
-		
-		bussrcs = n.findall('bus_source');
-		if len(bussrcs) > 0 and not self._bussify_source:
-			self.bussify({'name':'bus','type':'bus'}, 'source')
-		elif len(bussrcs) > 0:
-			self.bussify({'name':'bus','type':'bus'}, 'source')
-			self.bussify({'name':'bus','type':'bus'}, 'source')
-		
+    def __init__(self, flow_graph, n):
+        """
+        Make a new block from nested data.
+        
+        Args:
+            flow: graph the parent element
+            n: the nested odict
+        
+        Returns:
+            block a new block
+        """
+        #build the block
+        Element.__init__(self, flow_graph)
+        #grab the data
+        params = n.findall('param')
+        sources = n.findall('source')
+        sinks = n.findall('sink')
+        self._name = n.find('name')
+        self._key = n.find('key')
+        self._category = n.find('category') or ''
+        self._grc_source = n.find('grc_source') or ''
+        self._block_wrapper_path = n.find('block_wrapper_path')
+        self._bussify_sink = n.find('bus_sink')
+        self._bussify_source = n.find('bus_source')
+        #create the param objects
+        self._params = list()
+        #add the id param
+        self.get_params().append(self.get_parent().get_parent().Param(
+            block=self,
+            n=odict({
+                'name': 'ID',
+                'key': 'id',
+                'type': 'id',
+            })
+        ))
+        self.get_params().append(self.get_parent().get_parent().Param(
+            block=self,
+            n=odict({
+                'name': 'Enabled',
+                'key': '_enabled',
+                'type': 'raw',
+                'value': 'True',
+                'hide': 'all',
+            })
+        ))
+        for param in map(lambda n: self.get_parent().get_parent().Param(block=self, n=n), params):
+            key = param.get_key()
+            #test against repeated keys
+            if key in self.get_param_keys():
+                raise Exception, 'Key "%s" already exists in params'%key
+            #store the param
+            self.get_params().append(param)
+        #create the source objects
+        self._sources = list()
+        for source in map(lambda n: self.get_parent().get_parent().Port(block=self, n=n, dir='source'), sources):
+            key = source.get_key()
+            #test against repeated keys
+            if key in self.get_source_keys():
+                raise Exception, 'Key "%s" already exists in sources'%key
+            #store the port
+            self.get_sources().append(source)
+        self.back_ofthe_bus(self.get_sources())
+        #create the sink objects
+        self._sinks = list()
+        for sink in map(lambda n: self.get_parent().get_parent().Port(block=self, n=n, dir='sink'), sinks):
+            key = sink.get_key()
+            #test against repeated keys
+            if key in self.get_sink_keys():
+                raise Exception, 'Key "%s" already exists in sinks'%key
+            #store the port
+            self.get_sinks().append(sink)
+        self.back_ofthe_bus(self.get_sinks())
+        self.current_bus_structure = {'source':'','sink':''};
+        
+
+    def back_ofthe_bus(self, portlist):
+        portlist.sort(key=lambda a: a.get_type() == 'bus');
+        
+
+    def filter_bus_port(self, ports): 
+        buslist = [i for i in ports if i.get_type() == 'bus'];
+        if len(buslist) == 0:
+            return ports;
+        else:
+            return buslist;
+
+    def get_enabled(self):
+        """
+        Get the enabled state of the block.
+        
+        Returns:
+            true for enabled
+        """
+        try: return eval(self.get_param('_enabled').get_value())
+        except: return True
+
+    def set_enabled(self, enabled):
+        """
+        Set the enabled state of the block.
+        
+        Args:
+            enabled: true for enabled
+        """
+        self.get_param('_enabled').set_value(str(enabled))
+
+    def __str__(self): return 'Block - %s - %s(%s)'%(self.get_id(), self.get_name(), self.get_key())
+
+    def get_id(self): return self.get_param('id').get_value()
+    def is_block(self): return True
+    def get_name(self): return self._name
+    def get_key(self): return self._key
+    def get_category(self): return self._category
+    def get_doc(self): return ''
+    def get_ports(self): return self.get_sources() + self.get_sinks()
+    def get_ports_gui(self): return self.filter_bus_port(self.get_sources()) + self.filter_bus_port(self.get_sinks());
+    def get_children(self): return self.get_ports() + self.get_params()
+    def get_children_gui(self): return self.get_ports_gui() + self.get_params()
+    def get_block_wrapper_path(self): return self._block_wrapper_path
+
+    ##############################################
+    # Access Params
+    ##############################################
+    def get_param_keys(self): return _get_keys(self._params)
+    def get_param(self, key): return _get_elem(self._params, key)
+    def get_params(self): return self._params
+
+    ##############################################
+    # Access Sinks
+    ##############################################
+    def get_sink_keys(self): return _get_keys(self._sinks)
+    def get_sink(self, key): return _get_elem(self._sinks, key)
+    def get_sinks(self): return self._sinks
+    def get_sinks_gui(self): return self.filter_bus_port(self.get_sinks())
+
+    ##############################################
+    # Access Sources
+    ##############################################
+    def get_source_keys(self): return _get_keys(self._sources)
+    def get_source(self, key): return _get_elem(self._sources, key)
+    def get_sources(self): return self._sources
+    def get_sources_gui(self): return self.filter_bus_port(self.get_sources()); 
+
+    def get_connections(self):
+        return sum([port.get_connections() for port in self.get_ports()], [])
+
+    def resolve_dependencies(self, tmpl):
+        """
+        Resolve a paramater dependency with cheetah templates.
+        
+        Args:
+            tmpl: the string with dependencies
+        
+        Returns:
+            the resolved value
+        """
+        tmpl = str(tmpl)
+        if '$' not in tmpl: return tmpl
+        n = dict((p.get_key(), TemplateArg(p)) for p in self.get_params())
+        try: return str(Template(tmpl, n))
+        except Exception, e: return "-------->\n%s: %s\n<--------"%(e, tmpl)
+
+    ##############################################
+    # Controller Modify
+    ##############################################
+    def type_controller_modify(self, direction):
+        """
+        Change the type controller.
+        
+        Args:
+            direction: +1 or -1
+        
+        Returns:
+            true for change
+        """
+        changed = False
+        type_param = None
+        for param in filter(lambda p: p.is_enum(), self.get_params()):
+            children = self.get_ports() + self.get_params()
+            #priority to the type controller
+            if param.get_key() in ' '.join(map(lambda p: p._type, children)): type_param = param
+            #use param if type param is unset
+            if not type_param: type_param = param
+        if type_param:
+            #try to increment the enum by direction
+            try:
+                keys = type_param.get_option_keys()
+                old_index = keys.index(type_param.get_value())
+                new_index = (old_index + direction + len(keys))%len(keys)
+                type_param.set_value(keys[new_index])
+                changed = True
+            except: pass
+        return changed
+
+    def port_controller_modify(self, direction):
+        """
+        Change the port controller.
+        
+        Args:
+            direction: +1 or -1
+        
+        Returns:
+            true for change
+        """
+        return False
+
+    def form_bus_structure(self, direc):
+        if direc == 'source':
+            get_p = self.get_sources;
+            get_p_gui = self.get_sources_gui;
+            bus_structure = self.get_bus_structure('source');
+        else:
+            get_p = self.get_sinks;
+            get_p_gui = self.get_sinks_gui
+            bus_structure = self.get_bus_structure('sink');
+
+        struct = [range(len(get_p()))];
+        if True in map(lambda a: isinstance(a.get_nports(), int), get_p()):
+                
+
+            structlet = [];
+            last = 0;
+            for j in [i.get_nports() for i in get_p() if isinstance(i.get_nports(), int)]:
+                structlet.extend(map(lambda a: a+last, range(j)));
+                last = structlet[-1] + 1;
+                struct = [structlet];
+        if bus_structure:
+                
+            struct = bus_structure
+
+        self.current_bus_structure[direc] = struct;
+        return struct
+
+    def bussify(self, n, direc):
+        if direc == 'source':
+            get_p = self.get_sources;
+            get_p_gui = self.get_sources_gui;
+            bus_structure = self.get_bus_structure('source');
+        else:
+            get_p = self.get_sinks;
+            get_p_gui = self.get_sinks_gui
+            bus_structure = self.get_bus_structure('sink');
+
+
+        for elt in get_p():
+            for connect in elt.get_connections():
+                self.get_parent().remove_element(connect);
+
+        
+        
+        
+        
+
+        if (not 'bus' in map(lambda a: a.get_type(), get_p())) and len(get_p()) > 0:
+
+            struct = self.form_bus_structure(direc);
+            self.current_bus_structure[direc] = struct;
+            if get_p()[0].get_nports():
+                n['nports'] = str(1);
+        
+            for i in range(len(struct)):
+                n['key'] = str(len(get_p()));
+                n = odict(n);
+                port = self.get_parent().get_parent().Port(block=self, n=n, dir=direc);
+                get_p().append(port);
+                
+
+            
+                
+        elif 'bus' in map(lambda a: a.get_type(), get_p()):
+            for elt in get_p_gui():
+                get_p().remove(elt);
+            self.current_bus_structure[direc] = ''
+    ##############################################
+    ## Import/Export Methods
+    ##############################################
+    def export_data(self):
+        """
+        Export this block's params to nested data.
+        
+        Returns:
+            a nested data odict
+        """
+        n = odict()
+        n['key'] = self.get_key()
+        n['param'] = map(lambda p: p.export_data(), self.get_params())
+        if 'bus' in map(lambda a: a.get_type(), self.get_sinks()):
+            n['bus_sink'] = str(1);
+        if 'bus' in map(lambda a: a.get_type(), self.get_sources()):
+            n['bus_source'] = str(1);
+        return n
+
+    def import_data(self, n):
+        """
+        Import this block's params from nested data.
+        Any param keys that do not exist will be ignored.
+        Since params can be dynamically created based another param,
+        call rewrite, and repeat the load until the params stick.
+        This call to rewrite will also create any dynamic ports
+        that are needed for the connections creation phase.
+        
+        Args:
+            n: the nested data odict
+        """
+        get_hash = lambda: hash(tuple(map(hash, self.get_params())))
+        my_hash = 0
+        while get_hash() != my_hash:
+            params_n = n.findall('param')
+            for param_n in params_n:
+                key = param_n.find('key')
+                value = param_n.find('value')
+                #the key must exist in this block's params
+                if key in self.get_param_keys():
+                    self.get_param(key).set_value(value)
+            #store hash and call rewrite
+            my_hash = get_hash()
+            self.rewrite()
diff --git a/grc/base/Connection.py b/grc/base/Connection.py
index 654eedb357..252b7deac1 100644
--- a/grc/base/Connection.py
+++ b/grc/base/Connection.py
@@ -22,104 +22,99 @@ from . import odict
 
 class Connection(Element):
 
-	def __init__(self, flow_graph, porta, portb):
-		"""
-		Make a new connection given the parent and 2 ports.
-		
-		Args:
-		    flow_graph: the parent of this element
-		    porta: a port (any direction)
-		    portb: a port (any direction)
-		@throws Error cannot make connection
-		
-		Returns:
-		    a new connection
-		"""
-		Element.__init__(self, flow_graph)
-		source = sink = None
-		#separate the source and sink
-		for port in (porta, portb):
-			if port.is_source(): source = port
-			if port.is_sink(): sink = port
-		if not source: raise ValueError('Connection could not isolate source')
-		if not sink: raise ValueError('Connection could not isolate sink')
+    def __init__(self, flow_graph, porta, portb):
+        """
+        Make a new connection given the parent and 2 ports.
+        
+        Args:
+            flow_graph: the parent of this element
+            porta: a port (any direction)
+            portb: a port (any direction)
+        @throws Error cannot make connection
+        
+        Returns:
+            a new connection
+        """
+        Element.__init__(self, flow_graph)
+        source = sink = None
+        #separate the source and sink
+        for port in (porta, portb):
+            if port.is_source(): source = port
+            if port.is_sink(): sink = port
+        if not source: raise ValueError('Connection could not isolate source')
+        if not sink: raise ValueError('Connection could not isolate sink')
+        busses = len(filter(lambda a: a.get_type() == 'bus', [source, sink]))%2
+        if not busses == 0: raise ValueError('busses must get with busses')
 
-		busses = len(filter(lambda a: a.get_type() == 'bus', [source, sink]))%2
-		if not busses == 0: raise ValueError('busses must get with busses')
+        if not len(source.get_associated_ports()) == len(sink.get_associated_ports()):
+            raise ValueError('port connections must have same cardinality');
+        #ensure that this connection (source -> sink) is unique
+        for connection in self.get_parent().get_connections():
+            if connection.get_source() is source and connection.get_sink() is sink:
+                raise Exception('This connection between source and sink is not unique.')
+        self._source = source
+        self._sink = sink
+        if source.get_type() == 'bus':
+            
+            sources = source.get_associated_ports();
+            sinks = sink.get_associated_ports();
+            
+            for i in range(len(sources)):
+                try:
+                    flow_graph.connect(sources[i], sinks[i]);
+                except:
+                    pass
 
-		if not len(source.get_associated_ports()) == len(sink.get_associated_ports()):
-			raise ValueError('port connections must have same cardinality');
-		#ensure that this connection (source -> sink) is unique
-		for connection in self.get_parent().get_connections():
-			if connection.get_source() is source and connection.get_sink() is sink:
-				raise Exception('This connection between source and sink is not unique.')
-		self._source = source
-		self._sink = sink
-		
-		if source.get_type() == 'bus':
-			
-			sources = source.get_associated_ports();
-			sinks = sink.get_associated_ports();
-			
-			for i in range(len(sources)):
-				try:
-					flow_graph.connect(sources[i], sinks[i]);
-				except:
-					pass
-		
-				
-	def __str__(self):
-		return 'Connection (\n\t%s\n\t\t%s\n\t%s\n\t\t%s\n)'%(
-			self.get_source().get_parent(),
-			self.get_source(),
-			self.get_sink().get_parent(),
-			self.get_sink(),
-		)
+    def __str__(self):
+        return 'Connection (\n\t%s\n\t\t%s\n\t%s\n\t\t%s\n)'%(
+            self.get_source().get_parent(),
+            self.get_source(),
+            self.get_sink().get_parent(),
+            self.get_sink(),
+        )
 
-	def is_connection(self): return True
+    def is_connection(self): return True
 
-	def validate(self):
-		"""
-		Validate the connections.
-		The ports must match in type.
-		"""
-		Element.validate(self)
-		source_type = self.get_source().get_type()
-		sink_type = self.get_sink().get_type()
-		if source_type != sink_type:
-			self.add_error_message('Source type "%s" does not match sink type "%s".'%(source_type, sink_type))
+    def validate(self):
+        """
+        Validate the connections.
+        The ports must match in type.
+        """
+        Element.validate(self)
+        source_type = self.get_source().get_type()
+        sink_type = self.get_sink().get_type()
+        if source_type != sink_type:
+            self.add_error_message('Source type "%s" does not match sink type "%s".'%(source_type, sink_type))
 
-	
+    def get_enabled(self):
+        """
+        Get the enabled state of this connection.
+        
+        Returns:
+            true if source and sink blocks are enabled
+        """
+        return self.get_source().get_parent().get_enabled() and \
+            self.get_sink().get_parent().get_enabled()
 
-	def get_enabled(self):
-		"""
-		Get the enabled state of this connection.
-		
-		Returns:
-		    true if source and sink blocks are enabled
-		"""
-		return self.get_source().get_parent().get_enabled() and \
-			self.get_sink().get_parent().get_enabled()
+    #############################
+    # Access Ports
+    #############################
+    def get_sink(self): return self._sink
+    def get_source(self): return self._source
 
-	#############################
-	# Access Ports
-	#############################
-	def get_sink(self): return self._sink
-	def get_source(self): return self._source
-
-	##############################################
-	## Import/Export Methods
-	##############################################
-	def export_data(self):
-		"""
-		Export this connection's info.
-		
-		Returns:
-		    a nested data odict
-		"""
-		n = odict()
-		n['source_block_id'] = self.get_source().get_parent().get_id()
-		n['sink_block_id'] = self.get_sink().get_parent().get_id()
-		n['source_key'] = self.get_source().get_key()
-		n['sink_key'] = self.get_sink().get_key()
-		return n
+    ##############################################
+    ## Import/Export Methods
+    ##############################################
+    def export_data(self):
+        """
+        Export this connection's info.
+        
+        Returns:
+            a nested data odict
+        """
+        n = odict()
+        n['source_block_id'] = self.get_source().get_parent().get_id()
+        n['sink_block_id'] = self.get_sink().get_parent().get_id()
+        n['source_key'] = self.get_source().get_key()
+        n['sink_key'] = self.get_sink().get_key()
+        return n
diff --git a/grc/base/Element.py b/grc/base/Element.py
index 74097eea9a..17b2234a8c 100644
--- a/grc/base/Element.py
+++ b/grc/base/Element.py
@@ -19,77 +19,77 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 
 class Element(object):
 
-	def __init__(self, parent=None):
-		self._parent = parent
+    def __init__(self, parent=None):
+        self._parent = parent
 
-	##################################################
-	# Element Validation API
-	##################################################
-	def validate(self):
-		"""
-		Validate this element and call validate on all children.
-		Call this base method before adding error messages in the subclass.
-		"""
-		self._error_messages = list()
-		for child in self.get_children(): child.validate()
+    ##################################################
+    # Element Validation API
+    ##################################################
+    def validate(self):
+        """
+        Validate this element and call validate on all children.
+        Call this base method before adding error messages in the subclass.
+        """
+        self._error_messages = list()
+        for child in self.get_children(): child.validate()
 
-	def is_valid(self):
-		"""
-		Is this element valid?
-		
-		Returns:
-		    true when the element is enabled and has no error messages
-		"""
-		return not self.get_error_messages() or not self.get_enabled()
+    def is_valid(self):
+        """
+        Is this element valid?
+        
+        Returns:
+            true when the element is enabled and has no error messages
+        """
+        return not self.get_error_messages() or not self.get_enabled()
 
-	def add_error_message(self, msg):
-		"""
-		Add an error message to the list of errors.
-		
-		Args:
-		    msg: the error message string
-		"""
-		self._error_messages.append(msg)
+    def add_error_message(self, msg):
+        """
+        Add an error message to the list of errors.
+        
+        Args:
+            msg: the error message string
+        """
+        self._error_messages.append(msg)
 
-	def get_error_messages(self):
-		"""
-		Get the list of error messages from this element and all of its children.
-		Do not include the error messages from disabled children.
-		Cleverly indent the children error messages for printing purposes.
-		
-		Returns:
-		    a list of error message strings
-		"""
-		error_messages = list(self._error_messages) #make a copy
-		for child in filter(lambda c: c.get_enabled(), self.get_children()):
-			for msg in child.get_error_messages():
-				error_messages.append("%s:\n\t%s"%(child, msg.replace("\n", "\n\t")))
-		return error_messages
+    def get_error_messages(self):
+        """
+        Get the list of error messages from this element and all of its children.
+        Do not include the error messages from disabled children.
+        Cleverly indent the children error messages for printing purposes.
+        
+        Returns:
+            a list of error message strings
+        """
+        error_messages = list(self._error_messages) #make a copy
+        for child in filter(lambda c: c.get_enabled(), self.get_children()):
+            for msg in child.get_error_messages():
+                error_messages.append("%s:\n\t%s"%(child, msg.replace("\n", "\n\t")))
+        return error_messages
 
-	def rewrite(self):
-		"""
-		Rewrite this element and call rewrite on all children.
-		Call this base method before rewriting the element.
-		"""
-		for child in self.get_children(): child.rewrite()
+    def rewrite(self):
+        """
+        Rewrite this element and call rewrite on all children.
+        Call this base method before rewriting the element.
+        """
+        for child in self.get_children(): child.rewrite()
 
-	def get_enabled(self): return True
+    def get_enabled(self): return True
 
-	##############################################
-	## Tree-like API
-	##############################################
-	def get_parent(self): return self._parent
-	def get_children(self): return list()
+    ##############################################
+    ## Tree-like API
+    ##############################################
+    def get_parent(self): return self._parent
+    def get_children(self): return list()
 
-	##############################################
-	## Type testing methods
-	##############################################
-	def is_element(self): return True
-	def is_platform(self): return False
-	def is_flow_graph(self): return False
-	def is_connection(self): return False
-	def is_block(self): return False
-	def is_source(self): return False
-	def is_sink(self): return False
-	def is_port(self): return False
-	def is_param(self): return False
+    ##############################################
+    ## Type testing methods
+    ##############################################
+    def is_element(self): return True
+    def is_platform(self): return False
+    def is_flow_graph(self): return False
+    def is_connection(self): return False
+    def is_block(self): return False
+    def is_source(self): return False
+    def is_sink(self): return False
+    def is_port(self): return False
+    def is_param(self): return False
diff --git a/grc/base/FlowGraph.py b/grc/base/FlowGraph.py
index a35afa363b..2f2d8c65e1 100644
--- a/grc/base/FlowGraph.py
+++ b/grc/base/FlowGraph.py
@@ -23,296 +23,288 @@ from .. gui import Messages
 
 class FlowGraph(Element):
 
-	def __init__(self, platform):
-		"""
-		Make a flow graph from the arguments.
-		
-		Args:
-		    platform: a platforms with blocks and contrcutors
-		
-		Returns:
-		    the flow graph object
-		"""
-		#initialize
-		Element.__init__(self, platform)
-		#inital blank import
-		self.import_data()
+    def __init__(self, platform):
+        """
+        Make a flow graph from the arguments.
+        
+        Args:
+            platform: a platforms with blocks and contrcutors
+        
+        Returns:
+            the flow graph object
+        """
+        #initialize
+        Element.__init__(self, platform)
+        #inital blank import
+        self.import_data()
 
-	def _get_unique_id(self, base_id=''):
-		"""
-		Get a unique id starting with the base id.
-		
-		Args:
-		    base_id: the id starts with this and appends a count
-		
-		Returns:
-		    a unique id
-		"""
-		index = 0
-		while True:
-			id = '%s_%d'%(base_id, index)
-			index = index + 1
-			#make sure that the id is not used by another block
-			if not filter(lambda b: b.get_id() == id, self.get_blocks()): return id
+    def _get_unique_id(self, base_id=''):
+        """
+        Get a unique id starting with the base id.
+        
+        Args:
+            base_id: the id starts with this and appends a count
+        
+        Returns:
+            a unique id
+        """
+        index = 0
+        while True:
+            id = '%s_%d'%(base_id, index)
+            index = index + 1
+            #make sure that the id is not used by another block
+            if not filter(lambda b: b.get_id() == id, self.get_blocks()): return id
 
-	def __str__(self): return 'FlowGraph - %s(%s)'%(self.get_option('title'), self.get_option('id'))
-	def rewrite(self):
-		def refactor_bus_structure():
-			
-			for block in self.get_blocks():
-				for direc in ['source', 'sink']:
-					if direc == 'source':
-						get_p = block.get_sources;
-						get_p_gui = block.get_sources_gui;
-						bus_structure = block.form_bus_structure('source');
-					else:
-						get_p = block.get_sinks;
-						get_p_gui = block.get_sinks_gui
-						bus_structure = block.form_bus_structure('sink');
-				
-					if 'bus' in map(lambda a: a.get_type(), get_p_gui()):
-					
-				       		
-						
-						if len(get_p_gui()) > len(bus_structure):
-							times = range(len(bus_structure), len(get_p_gui()));
-							for i in times:
-								for connect in get_p_gui()[-1].get_connections():
-									block.get_parent().remove_element(connect);
-								get_p().remove(get_p_gui()[-1]);
-						elif len(get_p_gui()) < len(bus_structure):
-							n = {'name':'bus','type':'bus'};
-							if True in map(lambda a: isinstance(a.get_nports(), int), get_p()):
-								n['nports'] = str(1);
-							
-							times = range(len(get_p_gui()), len(bus_structure));	
-							
-	       						for i in times:
-								n['key'] = str(len(get_p()));
-								n = odict(n);
-								port = block.get_parent().get_parent().Port(block=block, n=n, dir=direc);
-								get_p().append(port);
-								
-								
-								
-		for child in self.get_children(): child.rewrite()
-		refactor_bus_structure();
-		
+    def __str__(self): return 'FlowGraph - %s(%s)'%(self.get_option('title'), self.get_option('id'))
+    def rewrite(self):
+        def refactor_bus_structure():
+            
+            for block in self.get_blocks():
+                for direc in ['source', 'sink']:
+                    if direc == 'source':
+                        get_p = block.get_sources;
+                        get_p_gui = block.get_sources_gui;
+                        bus_structure = block.form_bus_structure('source');
+                    else:
+                        get_p = block.get_sinks;
+                        get_p_gui = block.get_sinks_gui
+                        bus_structure = block.form_bus_structure('sink');
+                
+                    if 'bus' in map(lambda a: a.get_type(), get_p_gui()):
+                    
+                            
+                        
+                        if len(get_p_gui()) > len(bus_structure):
+                            times = range(len(bus_structure), len(get_p_gui()));
+                            for i in times:
+                                for connect in get_p_gui()[-1].get_connections():
+                                    block.get_parent().remove_element(connect);
+                                get_p().remove(get_p_gui()[-1]);
+                        elif len(get_p_gui()) < len(bus_structure):
+                            n = {'name':'bus','type':'bus'};
+                            if True in map(lambda a: isinstance(a.get_nports(), int), get_p()):
+                                n['nports'] = str(1);
+                            
+                            times = range(len(get_p_gui()), len(bus_structure));    
+                            
+                            for i in times:
+                                n['key'] = str(len(get_p()));
+                                n = odict(n);
+                                port = block.get_parent().get_parent().Port(block=block, n=n, dir=direc);
+                                get_p().append(port);
+                                
+                                
+                                
+        for child in self.get_children(): child.rewrite()
+        refactor_bus_structure();
 
-	def get_option(self, key):
-		"""
-		Get the option for a given key.
-		The option comes from the special options block.
-		
-		Args:
-		    key: the param key for the options block
-		
-		Returns:
-		    the value held by that param
-		"""
-		return self._options_block.get_param(key).get_evaluated()
+    def get_option(self, key):
+        """
+        Get the option for a given key.
+        The option comes from the special options block.
+        
+        Args:
+            key: the param key for the options block
+        
+        Returns:
+            the value held by that param
+        """
+        return self._options_block.get_param(key).get_evaluated()
 
-	def is_flow_graph(self): return True
+    def is_flow_graph(self): return True
 
-	##############################################
-	## Access Elements
-	##############################################
-	def get_block(self, id): return filter(lambda b: b.get_id() == id, self.get_blocks())[0]
-	def get_blocks_unordered(self): return filter(lambda e: e.is_block(), self.get_elements())
-	def get_blocks(self):
-		blocks = self.get_blocks_unordered();
-		for i in range(len(blocks)):
-			if blocks[i].get_key() == 'variable':
-				blk = blocks[i];
-				blocks.remove(blk);
-				blocks.insert(1, blk);
-		return blocks;
-	def get_connections(self): return filter(lambda e: e.is_connection(), self.get_elements())
-	def get_children(self): return self.get_elements()
-	def get_elements(self):
-		"""
-		Get a list of all the elements.
-		Always ensure that the options block is in the list (only once).
-		
-		Returns:
-		    the element list
-		"""
-		options_block_count = self._elements.count(self._options_block)
-		if not options_block_count:
-			self._elements.append(self._options_block)
-		for i in range(options_block_count-1):
-			self._elements.remove(self._options_block)
-		return self._elements
+    ##############################################
+    ## Access Elements
+    ##############################################
+    def get_block(self, id): return filter(lambda b: b.get_id() == id, self.get_blocks())[0]
+    def get_blocks_unordered(self): return filter(lambda e: e.is_block(), self.get_elements())
+    def get_blocks(self):
+        blocks = self.get_blocks_unordered();
+        for i in range(len(blocks)):
+            if blocks[i].get_key() == 'variable':
+                blk = blocks[i];
+                blocks.remove(blk);
+                blocks.insert(1, blk);
+        return blocks;
+    def get_connections(self): return filter(lambda e: e.is_connection(), self.get_elements())
+    def get_children(self): return self.get_elements()
+    def get_elements(self):
+        """
+        Get a list of all the elements.
+        Always ensure that the options block is in the list (only once).
+        
+        Returns:
+            the element list
+        """
+        options_block_count = self._elements.count(self._options_block)
+        if not options_block_count:
+            self._elements.append(self._options_block)
+        for i in range(options_block_count-1):
+            self._elements.remove(self._options_block)
+        return self._elements
 
-	def get_enabled_blocks(self):
-		"""
-		Get a list of all blocks that are enabled.
-		
-		Returns:
-		    a list of blocks
-		"""
-		return filter(lambda b: b.get_enabled(), self.get_blocks())
+    def get_enabled_blocks(self):
+        """
+        Get a list of all blocks that are enabled.
+        
+        Returns:
+            a list of blocks
+        """
+        return filter(lambda b: b.get_enabled(), self.get_blocks())
 
-	def get_enabled_connections(self):
-		"""
-		Get a list of all connections that are enabled.
-		
-		Returns:
-		    a list of connections
-		"""
-		return filter(lambda c: c.get_enabled(), self.get_connections())
+    def get_enabled_connections(self):
+        """
+        Get a list of all connections that are enabled.
+        
+        Returns:
+            a list of connections
+        """
+        return filter(lambda c: c.get_enabled(), self.get_connections())
 
-	def get_new_block(self, key):
-		"""
-		Get a new block of the specified key.
-		Add the block to the list of elements.
-		
-		Args:
-		    key: the block key
-		
-		Returns:
-		    the new block or None if not found
-		"""
-	
-		if key not in self.get_parent().get_block_keys(): return None
-		block = self.get_parent().get_new_block(self, key)
-		self.get_elements().append(block);
-		if block._bussify_sink:
-			block.bussify({'name':'bus','type':'bus'}, 'sink')
-		if block._bussify_source:
-			block.bussify({'name':'bus','type':'bus'}, 'source')
-		return block;
+    def get_new_block(self, key):
+        """
+        Get a new block of the specified key.
+        Add the block to the list of elements.
+        
+        Args:
+            key: the block key
+        
+        Returns:
+            the new block or None if not found
+        """
+        if key not in self.get_parent().get_block_keys(): return None
+        block = self.get_parent().get_new_block(self, key)
+        self.get_elements().append(block);
+        if block._bussify_sink:
+            block.bussify({'name':'bus','type':'bus'}, 'sink')
+        if block._bussify_source:
+            block.bussify({'name':'bus','type':'bus'}, 'source')
+        return block;
 
-	def connect(self, porta, portb):
-		"""
-		Create a connection between porta and portb.
-		
-		Args:
-		    porta: a port
-		    portb: another port
-		@throw Exception bad connection
-		
-		Returns:
-		    the new connection
-		"""
-		
-		connection = self.get_parent().Connection(flow_graph=self, porta=porta, portb=portb)
-		
-		
-		self.get_elements().append(connection)
-		return connection
+    def connect(self, porta, portb):
+        """
+        Create a connection between porta and portb.
+        
+        Args:
+            porta: a port
+            portb: another port
+        @throw Exception bad connection
+        
+        Returns:
+            the new connection
+        """
+        connection = self.get_parent().Connection(flow_graph=self, porta=porta, portb=portb)
+        self.get_elements().append(connection)
+        return connection
 
-	def remove_element(self, element):
-		"""
-		Remove the element from the list of elements.
-		If the element is a port, remove the whole block.
-		If the element is a block, remove its connections.
-		If the element is a connection, just remove the connection.
-		"""
+    def remove_element(self, element):
+        """
+        Remove the element from the list of elements.
+        If the element is a port, remove the whole block.
+        If the element is a block, remove its connections.
+        If the element is a connection, just remove the connection.
+        """
+        if element not in self.get_elements(): return
+        #found a port, set to parent signal block
+        if element.is_port():
+            element = element.get_parent()
+        #remove block, remove all involved connections
+        if element.is_block():
+            for port in element.get_ports():
+                map(self.remove_element, port.get_connections())
+        if element.is_connection():
+            if element.is_bus():
+                cons_list = []
+                for i in map(lambda a: a.get_connections(), element.get_source().get_associated_ports()):
+                    cons_list.extend(i);
+                map(self.remove_element, cons_list);
+        self.get_elements().remove(element)
 
-		if element not in self.get_elements(): return
-		#found a port, set to parent signal block
-		if element.is_port():
-			element = element.get_parent()
-		#remove block, remove all involved connections
-		if element.is_block():
-			for port in element.get_ports():
-				map(self.remove_element, port.get_connections())
-		if element.is_connection():
-			if element.is_bus():
-				cons_list = []
-				for i in map(lambda a: a.get_connections(), element.get_source().get_associated_ports()):
-					cons_list.extend(i);
-				map(self.remove_element, cons_list);
-		self.get_elements().remove(element)
-		
+    def evaluate(self, expr):
+        """
+        Evaluate the expression.
+        
+        Args:
+            expr: the string expression
+        @throw NotImplementedError
+        """
+        raise NotImplementedError
 
-	def evaluate(self, expr):
-		"""
-		Evaluate the expression.
-		
-		Args:
-		    expr: the string expression
-		@throw NotImplementedError
-		"""
-		raise NotImplementedError
+    ##############################################
+    ## Import/Export Methods
+    ##############################################
+    def export_data(self):
+        """
+        Export this flow graph to nested data.
+        Export all block and connection data.
+        
+        Returns:
+            a nested data odict
+        """
+        import time
+        n = odict()
+        n['timestamp'] = time.ctime()
+        n['block'] = [block.export_data() for block in self.get_blocks()]
+        n['connection'] = [connection.export_data() for connection in self.get_connections()]
+        return odict({'flow_graph': n})
 
-	##############################################
-	## Import/Export Methods
-	##############################################
-	def export_data(self):
-		"""
-		Export this flow graph to nested data.
-		Export all block and connection data.
-		
-		Returns:
-		    a nested data odict
-		"""
-		import time
-		n = odict()
-		n['timestamp'] = time.ctime()
-		n['block'] = [block.export_data() for block in self.get_blocks()]
-		n['connection'] = [connection.export_data() for connection in self.get_connections()]
-		return odict({'flow_graph': n})
-
-	def import_data(self, n=None):
-		"""
-		Import blocks and connections into this flow graph.
-		Clear this flowgraph of all previous blocks and connections.
-		Any blocks or connections in error will be ignored.
-		
-		Args:
-		    n: the nested data odict
-		"""
-		#remove previous elements
-		self._elements = list()
-		#use blank data if none provided
-		fg_n = n and n.find('flow_graph') or odict()
-		blocks_n = fg_n.findall('block')
-		connections_n = fg_n.findall('connection')
-		#create option block
-		self._options_block = self.get_parent().get_new_block(self, 'options')
-		#build the blocks
-		for block_n in blocks_n:
-			key = block_n.find('key')
-			if key == 'options': block = self._options_block
-			else: block = self.get_new_block(key)
-			#only load the block when the block key was valid
-			if block: block.import_data(block_n)
-			else: Messages.send_error_load('Block key "%s" not found in %s'%(key, self.get_parent()))
-			
-		#build the connections
-		for connection_n in connections_n:
-			#try to make the connection
-			try:
-				#get the block ids
-				source_block_id = connection_n.find('source_block_id')
-				sink_block_id = connection_n.find('sink_block_id')
-				#get the port keys
-				source_key = connection_n.find('source_key')
-				sink_key = connection_n.find('sink_key')
-				#verify the blocks
-				block_ids = map(lambda b: b.get_id(), self.get_blocks())
-				if source_block_id not in block_ids:
-					raise LookupError('source block id "%s" not in block ids'%source_block_id)
-				if sink_block_id not in block_ids:
-					raise LookupError('sink block id "%s" not in block ids'%sink_block_id)
-				#get the blocks
-				source_block = self.get_block(source_block_id)
-				sink_block = self.get_block(sink_block_id)
-				#verify the ports
-				if source_key not in source_block.get_source_keys():
-					raise LookupError('source key "%s" not in source block keys'%source_key)
-				if sink_key not in sink_block.get_sink_keys():
-					raise LookupError('sink key "%s" not in sink block keys'%sink_key)
-				#get the ports
-				source = source_block.get_source(source_key)
-				sink = sink_block.get_sink(sink_key)
-				#build the connection
-				self.connect(source, sink)
-			except LookupError, e: Messages.send_error_load(
-				'Connection between %s(%s) and %s(%s) could not be made.\n\t%s'%(
-					source_block_id, source_key, sink_block_id, sink_key, e
-				)
-			)
-		self.rewrite() #global rewrite
+    def import_data(self, n=None):
+        """
+        Import blocks and connections into this flow graph.
+        Clear this flowgraph of all previous blocks and connections.
+        Any blocks or connections in error will be ignored.
+        
+        Args:
+            n: the nested data odict
+        """
+        #remove previous elements
+        self._elements = list()
+        #use blank data if none provided
+        fg_n = n and n.find('flow_graph') or odict()
+        blocks_n = fg_n.findall('block')
+        connections_n = fg_n.findall('connection')
+        #create option block
+        self._options_block = self.get_parent().get_new_block(self, 'options')
+        #build the blocks
+        for block_n in blocks_n:
+            key = block_n.find('key')
+            if key == 'options': block = self._options_block
+            else: block = self.get_new_block(key)
+            #only load the block when the block key was valid
+            if block: block.import_data(block_n)
+            else: Messages.send_error_load('Block key "%s" not found in %s'%(key, self.get_parent()))
+        #build the connections
+        for connection_n in connections_n:
+            #try to make the connection
+            try:
+                #get the block ids
+                source_block_id = connection_n.find('source_block_id')
+                sink_block_id = connection_n.find('sink_block_id')
+                #get the port keys
+                source_key = connection_n.find('source_key')
+                sink_key = connection_n.find('sink_key')
+                #verify the blocks
+                block_ids = map(lambda b: b.get_id(), self.get_blocks())
+                if source_block_id not in block_ids:
+                    raise LookupError('source block id "%s" not in block ids'%source_block_id)
+                if sink_block_id not in block_ids:
+                    raise LookupError('sink block id "%s" not in block ids'%sink_block_id)
+                #get the blocks
+                source_block = self.get_block(source_block_id)
+                sink_block = self.get_block(sink_block_id)
+                #verify the ports
+                if source_key not in source_block.get_source_keys():
+                    raise LookupError('source key "%s" not in source block keys'%source_key)
+                if sink_key not in sink_block.get_sink_keys():
+                    raise LookupError('sink key "%s" not in sink block keys'%sink_key)
+                #get the ports
+                source = source_block.get_source(source_key)
+                sink = sink_block.get_sink(sink_key)
+                #build the connection
+                self.connect(source, sink)
+            except LookupError, e: Messages.send_error_load(
+                'Connection between %s(%s) and %s(%s) could not be made.\n\t%s'%(
+                    source_block_id, source_key, sink_block_id, sink_key, e
+                )
+            )
+        self.rewrite() #global rewrite
diff --git a/grc/base/Param.py b/grc/base/Param.py
index 76a74d3ed7..8b8362ac1a 100644
--- a/grc/base/Param.py
+++ b/grc/base/Param.py
@@ -22,166 +22,166 @@ from Element import Element
 
 def _get_keys(lst): return [elem.get_key() for elem in lst]
 def _get_elem(lst, key):
-	try: return lst[_get_keys(lst).index(key)]
-	except ValueError: raise ValueError, 'Key "%s" not found in %s.'%(key, _get_keys(lst))
+    try: return lst[_get_keys(lst).index(key)]
+    except ValueError: raise ValueError, 'Key "%s" not found in %s.'%(key, _get_keys(lst))
 
 class Option(Element):
 
-	def __init__(self, param, n):
-		Element.__init__(self, param)
-		self._name = n.find('name')
-		self._key = n.find('key')
-		self._opts = dict()
-		opts = n.findall('opt')
-		#test against opts when non enum
-		if not self.get_parent().is_enum() and opts:
-			raise Exception, 'Options for non-enum types cannot have sub-options'
-		#extract opts
-		for opt in opts:
-			#separate the key:value
-			try: key, value = opt.split(':')
-			except: raise Exception, 'Error separating "%s" into key:value'%opt
-			#test against repeated keys
-			if self._opts.has_key(key):
-				raise Exception, 'Key "%s" already exists in option'%key
-			#store the option
-			self._opts[key] = value
-
-	def __str__(self): return 'Option %s(%s)'%(self.get_name(), self.get_key())
-	def get_name(self): return self._name
-	def get_key(self): return self._key
-
-	##############################################
-	# Access Opts
-	##############################################
-	def get_opt_keys(self): return self._opts.keys()
-	def get_opt(self, key): return self._opts[key]
-	def get_opts(self): return self._opts.values()
+    def __init__(self, param, n):
+        Element.__init__(self, param)
+        self._name = n.find('name')
+        self._key = n.find('key')
+        self._opts = dict()
+        opts = n.findall('opt')
+        #test against opts when non enum
+        if not self.get_parent().is_enum() and opts:
+            raise Exception, 'Options for non-enum types cannot have sub-options'
+        #extract opts
+        for opt in opts:
+            #separate the key:value
+            try: key, value = opt.split(':')
+            except: raise Exception, 'Error separating "%s" into key:value'%opt
+            #test against repeated keys
+            if self._opts.has_key(key):
+                raise Exception, 'Key "%s" already exists in option'%key
+            #store the option
+            self._opts[key] = value
+
+    def __str__(self): return 'Option %s(%s)'%(self.get_name(), self.get_key())
+    def get_name(self): return self._name
+    def get_key(self): return self._key
+
+    ##############################################
+    # Access Opts
+    ##############################################
+    def get_opt_keys(self): return self._opts.keys()
+    def get_opt(self, key): return self._opts[key]
+    def get_opts(self): return self._opts.values()
 
 class Param(Element):
 
-	def __init__(self, block, n):
-		"""
-		Make a new param from nested data.
-		
-		Args:
-		    block: the parent element
-		    n: the nested odict
-		"""
-		#grab the data
-		self._name = n.find('name')
-		self._key = n.find('key')
-		value = n.find('value') or ''
-		self._type = n.find('type')
-		self._hide = n.find('hide') or ''
-		#build the param
-		Element.__init__(self, block)
-		#create the Option objects from the n data
-		self._options = list()
-		for option in map(lambda o: Option(param=self, n=o), n.findall('option')):
-			key = option.get_key()
-			#test against repeated keys
-			if key in self.get_option_keys():
-				raise Exception, 'Key "%s" already exists in options'%key
-			#store the option
-			self.get_options().append(option)
-		#test the enum options
-		if self.is_enum():
-			#test against options with identical keys
-			if len(set(self.get_option_keys())) != len(self.get_options()):
-				raise Exception, 'Options keys "%s" are not unique.'%self.get_option_keys()
-			#test against inconsistent keys in options
-			opt_keys = self.get_options()[0].get_opt_keys()
-			for option in self.get_options():
-				if set(opt_keys) != set(option.get_opt_keys()):
-					raise Exception, 'Opt keys "%s" are not identical across all options.'%opt_keys
-			#if a value is specified, it must be in the options keys
-			self._value = value if value or value in self.get_option_keys() else self.get_option_keys()[0]
-			if self.get_value() not in self.get_option_keys():
-				raise Exception, 'The value "%s" is not in the possible values of "%s".'%(self.get_value(), self.get_option_keys())
-		else: self._value = value or ''
-
-	def validate(self):
-		"""
-		Validate the param.
-		The value must be evaluated and type must a possible type.
-		"""
-		Element.validate(self)
-		if self.get_type() not in self.get_types():
-			self.add_error_message('Type "%s" is not a possible type.'%self.get_type())
-
-	def get_evaluated(self): raise NotImplementedError
-
-	def to_code(self):
-		"""
-		Convert the value to code.
-		@throw NotImplementedError
-		"""
-		raise NotImplementedError
-
-	def get_types(self):
-		"""
-		Get a list of all possible param types.
-		@throw NotImplementedError
-		"""
-		raise NotImplementedError
-
-	def get_color(self): return '#FFFFFF'
-	def __str__(self): return 'Param - %s(%s)'%(self.get_name(), self.get_key())
-	def is_param(self): return True
-	def get_name(self): return self._name
-	def get_key(self): return self._key
-	def get_hide(self): return self.get_parent().resolve_dependencies(self._hide).strip()
-
-	def get_value(self):
-		value = self._value
-		if self.is_enum() and value not in self.get_option_keys():
-			value = self.get_option_keys()[0]
-			self.set_value(value)
-		return value
-
-	def set_value(self, value): self._value = str(value) #must be a string
-
-	def get_type(self): return self.get_parent().resolve_dependencies(self._type)
-	def is_enum(self): return self._type == 'enum'
-
-	def __repr__(self):
-		"""
-		Get the repr (nice string format) for this param.
-		Just return the value (special case enum).
-		Derived classes can handle complex formatting.
-		
-		Returns:
-		    the string representation
-		"""
-		if self.is_enum(): return self.get_option(self.get_value()).get_name()
-		return self.get_value()
-
-	##############################################
-	# Access Options
-	##############################################
-	def get_option_keys(self): return _get_keys(self.get_options())
-	def get_option(self, key): return _get_elem(self.get_options(), key)
-	def get_options(self): return self._options
-
-	##############################################
-	# Access Opts
-	##############################################
-	def get_opt_keys(self): return self.get_option(self.get_value()).get_opt_keys()
-	def get_opt(self, key): return self.get_option(self.get_value()).get_opt(key)
-	def get_opts(self): return self.get_option(self.get_value()).get_opts()
-
-	##############################################
-	## Import/Export Methods
-	##############################################
-	def export_data(self):
-		"""
-		Export this param's key/value.
-		
-		Returns:
-		    a nested data odict
-		"""
-		n = odict()
-		n['key'] = self.get_key()
-		n['value'] = self.get_value()
-		return n
+    def __init__(self, block, n):
+        """
+        Make a new param from nested data.
+        
+        Args:
+            block: the parent element
+            n: the nested odict
+        """
+        #grab the data
+        self._name = n.find('name')
+        self._key = n.find('key')
+        value = n.find('value') or ''
+        self._type = n.find('type')
+        self._hide = n.find('hide') or ''
+        #build the param
+        Element.__init__(self, block)
+        #create the Option objects from the n data
+        self._options = list()
+        for option in map(lambda o: Option(param=self, n=o), n.findall('option')):
+            key = option.get_key()
+            #test against repeated keys
+            if key in self.get_option_keys():
+                raise Exception, 'Key "%s" already exists in options'%key
+            #store the option
+            self.get_options().append(option)
+        #test the enum options
+        if self.is_enum():
+            #test against options with identical keys
+            if len(set(self.get_option_keys())) != len(self.get_options()):
+                raise Exception, 'Options keys "%s" are not unique.'%self.get_option_keys()
+            #test against inconsistent keys in options
+            opt_keys = self.get_options()[0].get_opt_keys()
+            for option in self.get_options():
+                if set(opt_keys) != set(option.get_opt_keys()):
+                    raise Exception, 'Opt keys "%s" are not identical across all options.'%opt_keys
+            #if a value is specified, it must be in the options keys
+            self._value = value if value or value in self.get_option_keys() else self.get_option_keys()[0]
+            if self.get_value() not in self.get_option_keys():
+                raise Exception, 'The value "%s" is not in the possible values of "%s".'%(self.get_value(), self.get_option_keys())
+        else: self._value = value or ''
+
+    def validate(self):
+        """
+        Validate the param.
+        The value must be evaluated and type must a possible type.
+        """
+        Element.validate(self)
+        if self.get_type() not in self.get_types():
+            self.add_error_message('Type "%s" is not a possible type.'%self.get_type())
+
+    def get_evaluated(self): raise NotImplementedError
+
+    def to_code(self):
+        """
+        Convert the value to code.
+        @throw NotImplementedError
+        """
+        raise NotImplementedError
+
+    def get_types(self):
+        """
+        Get a list of all possible param types.
+        @throw NotImplementedError
+        """
+        raise NotImplementedError
+
+    def get_color(self): return '#FFFFFF'
+    def __str__(self): return 'Param - %s(%s)'%(self.get_name(), self.get_key())
+    def is_param(self): return True
+    def get_name(self): return self._name
+    def get_key(self): return self._key
+    def get_hide(self): return self.get_parent().resolve_dependencies(self._hide).strip()
+
+    def get_value(self):
+        value = self._value
+        if self.is_enum() and value not in self.get_option_keys():
+            value = self.get_option_keys()[0]
+            self.set_value(value)
+        return value
+
+    def set_value(self, value): self._value = str(value) #must be a string
+
+    def get_type(self): return self.get_parent().resolve_dependencies(self._type)
+    def is_enum(self): return self._type == 'enum'
+
+    def __repr__(self):
+        """
+        Get the repr (nice string format) for this param.
+        Just return the value (special case enum).
+        Derived classes can handle complex formatting.
+        
+        Returns:
+            the string representation
+        """
+        if self.is_enum(): return self.get_option(self.get_value()).get_name()
+        return self.get_value()
+
+    ##############################################
+    # Access Options
+    ##############################################
+    def get_option_keys(self): return _get_keys(self.get_options())
+    def get_option(self, key): return _get_elem(self.get_options(), key)
+    def get_options(self): return self._options
+
+    ##############################################
+    # Access Opts
+    ##############################################
+    def get_opt_keys(self): return self.get_option(self.get_value()).get_opt_keys()
+    def get_opt(self, key): return self.get_option(self.get_value()).get_opt(key)
+    def get_opts(self): return self.get_option(self.get_value()).get_opts()
+
+    ##############################################
+    ## Import/Export Methods
+    ##############################################
+    def export_data(self):
+        """
+        Export this param's key/value.
+        
+        Returns:
+            a nested data odict
+        """
+        n = odict()
+        n['key'] = self.get_key()
+        n['value'] = self.get_value()
+        return n
diff --git a/grc/base/ParseXML.py b/grc/base/ParseXML.py
index e8f9b0583e..56097395dd 100644
--- a/grc/base/ParseXML.py
+++ b/grc/base/ParseXML.py
@@ -21,99 +21,99 @@ from lxml import etree
 from . import odict
 
 class XMLSyntaxError(Exception):
-	def __init__(self, error_log):
-		self._error_log = error_log
-	def __str__(self):
-		return '\n'.join(map(str, self._error_log.filter_from_errors()))
+    def __init__(self, error_log):
+        self._error_log = error_log
+    def __str__(self):
+        return '\n'.join(map(str, self._error_log.filter_from_errors()))
 
 def validate_dtd(xml_file, dtd_file=None):
-	"""
-	Validate an xml file against its dtd.
-	
-	Args:
-	    xml_file: the xml file
-	    dtd_file: the optional dtd file
-	@throws Exception validation fails
-	"""
-	#perform parsing, use dtd validation if dtd file is not specified
-	parser = etree.XMLParser(dtd_validation=not dtd_file)
-	xml = etree.parse(xml_file, parser=parser)
-	if parser.error_log: raise XMLSyntaxError(parser.error_log)
-	#perform dtd validation if the dtd file is specified
-	if not dtd_file: return
-	dtd = etree.DTD(dtd_file)
-	if not dtd.validate(xml.getroot()): raise XMLSyntaxError(dtd.error_log)
+    """
+    Validate an xml file against its dtd.
+    
+    Args:
+        xml_file: the xml file
+        dtd_file: the optional dtd file
+    @throws Exception validation fails
+    """
+    #perform parsing, use dtd validation if dtd file is not specified
+    parser = etree.XMLParser(dtd_validation=not dtd_file)
+    xml = etree.parse(xml_file, parser=parser)
+    if parser.error_log: raise XMLSyntaxError(parser.error_log)
+    #perform dtd validation if the dtd file is specified
+    if not dtd_file: return
+    dtd = etree.DTD(dtd_file)
+    if not dtd.validate(xml.getroot()): raise XMLSyntaxError(dtd.error_log)
 
 def from_file(xml_file):
-	"""
-	Create nested data from an xml file using the from xml helper.
-	
-	Args:
-	    xml_file: the xml file path
-	
-	Returns:
-	    the nested data
-	"""
-	xml = etree.parse(xml_file).getroot()
-	return _from_file(xml)
+    """
+    Create nested data from an xml file using the from xml helper.
+    
+    Args:
+        xml_file: the xml file path
+    
+    Returns:
+        the nested data
+    """
+    xml = etree.parse(xml_file).getroot()
+    return _from_file(xml)
 
 def _from_file(xml):
-	"""
-	Recursivly parse the xml tree into nested data format.
-	
-	Args:
-	    xml: the xml tree
-	
-	Returns:
-	    the nested data
-	"""
-	tag = xml.tag
-	if not len(xml):
-		return odict({tag: xml.text or ''}) #store empty tags (text is None) as empty string
-	nested_data = odict()
-	for elem in xml:
-		key, value = _from_file(elem).items()[0]
-		if nested_data.has_key(key): nested_data[key].append(value)
-		else: nested_data[key] = [value]
-	#delistify if the length of values is 1
-	for key, values in nested_data.iteritems():
-		if len(values) == 1: nested_data[key] = values[0]
+    """
+    Recursivly parse the xml tree into nested data format.
+    
+    Args:
+        xml: the xml tree
+    
+    Returns:
+        the nested data
+    """
+    tag = xml.tag
+    if not len(xml):
+        return odict({tag: xml.text or ''}) #store empty tags (text is None) as empty string
+    nested_data = odict()
+    for elem in xml:
+        key, value = _from_file(elem).items()[0]
+        if nested_data.has_key(key): nested_data[key].append(value)
+        else: nested_data[key] = [value]
+    #delistify if the length of values is 1
+    for key, values in nested_data.iteritems():
+        if len(values) == 1: nested_data[key] = values[0]
 
-	return odict({tag: nested_data})
+    return odict({tag: nested_data})
 
 def to_file(nested_data, xml_file):
-	"""
-	Write an xml file and use the to xml helper method to load it.
-	
-	Args:
-	    nested_data: the nested data
-	    xml_file: the xml file path
-	"""
-	xml = _to_file(nested_data)[0]
-	open(xml_file, 'w').write(etree.tostring(xml, xml_declaration=True, pretty_print=True))
+    """
+    Write an xml file and use the to xml helper method to load it.
+    
+    Args:
+        nested_data: the nested data
+        xml_file: the xml file path
+    """
+    xml = _to_file(nested_data)[0]
+    open(xml_file, 'w').write(etree.tostring(xml, xml_declaration=True, pretty_print=True))
 
 def _to_file(nested_data):
-	"""
-	Recursivly parse the nested data into xml tree format.
-	
-	Args:
-	    nested_data: the nested data
-	
-	Returns:
-	    the xml tree filled with child nodes
-	"""
-	nodes = list()
-	for key, values in nested_data.iteritems():
-		#listify the values if not a list
-		if not isinstance(values, (list, set, tuple)):
-			values = [values]
-		for value in values:
-			node = etree.Element(key)
-			if isinstance(value, (str, unicode)): node.text = value
-			else: node.extend(_to_file(value))
-			nodes.append(node)
-	return nodes
+    """
+    Recursivly parse the nested data into xml tree format.
+    
+    Args:
+        nested_data: the nested data
+    
+    Returns:
+        the xml tree filled with child nodes
+    """
+    nodes = list()
+    for key, values in nested_data.iteritems():
+        #listify the values if not a list
+        if not isinstance(values, (list, set, tuple)):
+            values = [values]
+        for value in values:
+            node = etree.Element(key)
+            if isinstance(value, (str, unicode)): node.text = value
+            else: node.extend(_to_file(value))
+            nodes.append(node)
+    return nodes
 
 if __name__ == '__main__':
-	"""Use the main method to test parse xml's functions."""
-	pass
+    """Use the main method to test parse xml's functions."""
+    pass
diff --git a/grc/base/Platform.py b/grc/base/Platform.py
index f0f24a48a7..bb80e29552 100644
--- a/grc/base/Platform.py
+++ b/grc/base/Platform.py
@@ -30,159 +30,159 @@ from Constants import BLOCK_TREE_DTD, FLOW_GRAPH_DTD
 
 class Platform(_Element):
 
-	def __init__(self, name, version, key,
-		block_paths, block_dtd, default_flow_graph, generator,
-		license='', website=None, colors=[]):
-		"""
-		Make a platform from the arguments.
-		
-		Args:
-		    name: the platform name
-		    version: the version string
-		    key: the unique platform key
-		    block_paths: the file paths to blocks in this platform
-		    block_dtd: the dtd validator for xml block wrappers
-		    default_flow_graph: the default flow graph file path
-		    generator: the generator class for this platform
-		    colors: a list of title, color_spec tuples
-		    license: a multi-line license (first line is copyright)
-		    website: the website url for this platform
-		
-		Returns:
-		    a platform object
-		"""
-		_Element.__init__(self)
-		self._name = name
-		self._version = version
-		self._key = key
-		self._license = license
-		self._website = website
-		self._block_paths = block_paths
-		self._block_dtd = block_dtd
-		self._default_flow_graph = default_flow_graph
-		self._generator = generator
-		self._colors = colors
-		#create a dummy flow graph for the blocks
-		self._flow_graph = _Element(self)
-		#search for *.xml files in the given search path
-
-		self.loadblocks();
+    def __init__(self, name, version, key,
+        block_paths, block_dtd, default_flow_graph, generator,
+        license='', website=None, colors=[]):
+        """
+        Make a platform from the arguments.
+        
+        Args:
+            name: the platform name
+            version: the version string
+            key: the unique platform key
+            block_paths: the file paths to blocks in this platform
+            block_dtd: the dtd validator for xml block wrappers
+            default_flow_graph: the default flow graph file path
+            generator: the generator class for this platform
+            colors: a list of title, color_spec tuples
+            license: a multi-line license (first line is copyright)
+            website: the website url for this platform
+        
+        Returns:
+            a platform object
+        """
+        _Element.__init__(self)
+        self._name = name
+        self._version = version
+        self._key = key
+        self._license = license
+        self._website = website
+        self._block_paths = block_paths
+        self._block_dtd = block_dtd
+        self._default_flow_graph = default_flow_graph
+        self._generator = generator
+        self._colors = colors
+        #create a dummy flow graph for the blocks
+        self._flow_graph = _Element(self)
+        #search for *.xml files in the given search path
+
+        self.loadblocks();
     
-	def loadblocks(self):
-		xml_files = list()
-		for block_path in self._block_paths:
-			if os.path.isfile(block_path): xml_files.append(block_path)
-			elif os.path.isdir(block_path):
-				for dirpath, dirnames, filenames in os.walk(block_path):
-					for filename in sorted(filter(lambda f: f.endswith('.xml'), filenames)):
-						xml_files.append(os.path.join(dirpath, filename))
-		#load the blocks
-		self._blocks = odict()
-		self._blocks_n = odict()
-		self._block_tree_files = list()
-		for xml_file in xml_files:
-			try: #try to add the xml file as a block wrapper
-				ParseXML.validate_dtd(xml_file, self._block_dtd)
-				n = ParseXML.from_file(xml_file).find('block')
-				#inject block wrapper path
-				n['block_wrapper_path'] = xml_file
-				block = self.Block(self._flow_graph, n)
-				key = block.get_key()
-				#test against repeated keys
-				if key in self.get_block_keys():
-					print >> sys.stderr, 'Warning: Block with key "%s" already exists.\n\tIgnoring: %s'%(key, xml_file)
-				#store the block
-				else:
-					self._blocks[key] = block
-					self._blocks_n[key] = n
-			except ParseXML.XMLSyntaxError, e:
-				try: #try to add the xml file as a block tree
-					ParseXML.validate_dtd(xml_file, BLOCK_TREE_DTD)
-					self._block_tree_files.append(xml_file)
-				except ParseXML.XMLSyntaxError, e:
-					print >> sys.stderr, 'Warning: Block validation failed:\n\t%s\n\tIgnoring: %s'%(e, xml_file)
-			except Exception, e:
-				print >> sys.stderr, 'Warning: Block loading failed:\n\t%s\n\tIgnoring: %s'%(e, xml_file)
-
-	def parse_flow_graph(self, flow_graph_file):
-		"""
-		Parse a saved flow graph file.
-		Ensure that the file exists, and passes the dtd check.
-		
-		Args:
-		    flow_graph_file: the flow graph file
-		
-		Returns:
-		    nested data
-		@throws exception if the validation fails
-		"""
-		flow_graph_file = flow_graph_file or self._default_flow_graph
-		open(flow_graph_file, 'r') #test open
-		ParseXML.validate_dtd(flow_graph_file, FLOW_GRAPH_DTD)
-		return ParseXML.from_file(flow_graph_file)
-
-	def load_block_tree(self, block_tree):
-		"""
-		Load a block tree with categories and blocks.
-		Step 1: Load all blocks from the xml specification.
-		Step 2: Load blocks with builtin category specifications.
-		
-		Args:
-		    block_tree: the block tree object
-		"""
-		#recursive function to load categories and blocks
-		def load_category(cat_n, parent=[]):
-			#add this category
-			parent = parent + [cat_n.find('name')]
-			block_tree.add_block(parent)
-			#recursive call to load sub categories
-			map(lambda c: load_category(c, parent), cat_n.findall('cat'))
-			#add blocks in this category
-			for block_key in cat_n.findall('block'):
-				if block_key not in self.get_block_keys():
-					print >> sys.stderr, 'Warning: Block key "%s" not found when loading category tree.'%(block_key)
-					continue
-				block = self.get_block(block_key)
-				#if it exists, the block's category overrides the block tree
-				if not block.get_category(): block_tree.add_block(parent, block)
-		#load the block tree
-		for block_tree_file in self._block_tree_files:
-			#recursivly add all blocks in the tree
-			load_category(ParseXML.from_file(block_tree_file).find('cat'))
-		#add all other blocks, use the catgory tag
-		for block in self.get_blocks():
-			#blocks with empty categories are in the xml block tree or hidden
-			if not block.get_category(): continue
-			block_tree.add_block(block.get_category(), block)
-
-	def __str__(self): return 'Platform - %s(%s)'%(self.get_key(), self.get_name())
-
-	def is_platform(self): return True
-
-	def get_new_flow_graph(self): return self.FlowGraph(platform=self)
-
-	def get_generator(self): return self._generator
-
-	##############################################
-	# Access Blocks
-	##############################################
-	def get_block_keys(self): return self._blocks.keys()
-	def get_block(self, key): return self._blocks[key]
-	def get_blocks(self): return self._blocks.values()
-	def get_new_block(self, flow_graph, key): return self.Block(flow_graph, n=self._blocks_n[key])
-
-	def get_name(self): return self._name
-	def get_version(self): return self._version
-	def get_key(self): return self._key
-	def get_license(self): return self._license
-	def get_website(self): return self._website
-	def get_colors(self): return self._colors
-
-	##############################################
-	# Constructors
-	##############################################
-	FlowGraph = _FlowGraph
-	Connection = _Connection
-	Block = _Block
-	Port = _Port
-	Param = _Param
+    def loadblocks(self):
+        xml_files = list()
+        for block_path in self._block_paths:
+            if os.path.isfile(block_path): xml_files.append(block_path)
+            elif os.path.isdir(block_path):
+                for dirpath, dirnames, filenames in os.walk(block_path):
+                    for filename in sorted(filter(lambda f: f.endswith('.xml'), filenames)):
+                        xml_files.append(os.path.join(dirpath, filename))
+        #load the blocks
+        self._blocks = odict()
+        self._blocks_n = odict()
+        self._block_tree_files = list()
+        for xml_file in xml_files:
+            try: #try to add the xml file as a block wrapper
+                ParseXML.validate_dtd(xml_file, self._block_dtd)
+                n = ParseXML.from_file(xml_file).find('block')
+                #inject block wrapper path
+                n['block_wrapper_path'] = xml_file
+                block = self.Block(self._flow_graph, n)
+                key = block.get_key()
+                #test against repeated keys
+                if key in self.get_block_keys():
+                    print >> sys.stderr, 'Warning: Block with key "%s" already exists.\n\tIgnoring: %s'%(key, xml_file)
+                #store the block
+                else:
+                    self._blocks[key] = block
+                    self._blocks_n[key] = n
+            except ParseXML.XMLSyntaxError, e:
+                try: #try to add the xml file as a block tree
+                    ParseXML.validate_dtd(xml_file, BLOCK_TREE_DTD)
+                    self._block_tree_files.append(xml_file)
+                except ParseXML.XMLSyntaxError, e:
+                    print >> sys.stderr, 'Warning: Block validation failed:\n\t%s\n\tIgnoring: %s'%(e, xml_file)
+            except Exception, e:
+                print >> sys.stderr, 'Warning: Block loading failed:\n\t%s\n\tIgnoring: %s'%(e, xml_file)
+
+    def parse_flow_graph(self, flow_graph_file):
+        """
+        Parse a saved flow graph file.
+        Ensure that the file exists, and passes the dtd check.
+        
+        Args:
+            flow_graph_file: the flow graph file
+        
+        Returns:
+            nested data
+        @throws exception if the validation fails
+        """
+        flow_graph_file = flow_graph_file or self._default_flow_graph
+        open(flow_graph_file, 'r') #test open
+        ParseXML.validate_dtd(flow_graph_file, FLOW_GRAPH_DTD)
+        return ParseXML.from_file(flow_graph_file)
+
+    def load_block_tree(self, block_tree):
+        """
+        Load a block tree with categories and blocks.
+        Step 1: Load all blocks from the xml specification.
+        Step 2: Load blocks with builtin category specifications.
+        
+        Args:
+            block_tree: the block tree object
+        """
+        #recursive function to load categories and blocks
+        def load_category(cat_n, parent=[]):
+            #add this category
+            parent = parent + [cat_n.find('name')]
+            block_tree.add_block(parent)
+            #recursive call to load sub categories
+            map(lambda c: load_category(c, parent), cat_n.findall('cat'))
+            #add blocks in this category
+            for block_key in cat_n.findall('block'):
+                if block_key not in self.get_block_keys():
+                    print >> sys.stderr, 'Warning: Block key "%s" not found when loading category tree.'%(block_key)
+                    continue
+                block = self.get_block(block_key)
+                #if it exists, the block's category overrides the block tree
+                if not block.get_category(): block_tree.add_block(parent, block)
+        #load the block tree
+        for block_tree_file in self._block_tree_files:
+            #recursivly add all blocks in the tree
+            load_category(ParseXML.from_file(block_tree_file).find('cat'))
+        #add all other blocks, use the catgory tag
+        for block in self.get_blocks():
+            #blocks with empty categories are in the xml block tree or hidden
+            if not block.get_category(): continue
+            block_tree.add_block(block.get_category(), block)
+
+    def __str__(self): return 'Platform - %s(%s)'%(self.get_key(), self.get_name())
+
+    def is_platform(self): return True
+
+    def get_new_flow_graph(self): return self.FlowGraph(platform=self)
+
+    def get_generator(self): return self._generator
+
+    ##############################################
+    # Access Blocks
+    ##############################################
+    def get_block_keys(self): return self._blocks.keys()
+    def get_block(self, key): return self._blocks[key]
+    def get_blocks(self): return self._blocks.values()
+    def get_new_block(self, flow_graph, key): return self.Block(flow_graph, n=self._blocks_n[key])
+
+    def get_name(self): return self._name
+    def get_version(self): return self._version
+    def get_key(self): return self._key
+    def get_license(self): return self._license
+    def get_website(self): return self._website
+    def get_colors(self): return self._colors
+
+    ##############################################
+    # Constructors
+    ##############################################
+    FlowGraph = _FlowGraph
+    Connection = _Connection
+    Block = _Block
+    Port = _Port
+    Param = _Param
diff --git a/grc/base/Port.py b/grc/base/Port.py
index 1b2acb0582..b7de5301f1 100644
--- a/grc/base/Port.py
+++ b/grc/base/Port.py
@@ -21,97 +21,96 @@ from Element import Element
 
 class Port(Element):
 
-	def __init__(self, block, n, dir):
-		"""
-		Make a new port from nested data.
-		
-		Args:
-		    block: the parent element
-		    n: the nested odict
-		    dir: the direction source or sink
-		"""
-		#build the port
-		Element.__init__(self, block)
-		#grab the data
-		self._name = n['name']
-		self._key = n['key']
-		self._type = n['type']
-		self._dir = dir
+    def __init__(self, block, n, dir):
+        """
+        Make a new port from nested data.
+        
+        Args:
+            block: the parent element
+            n: the nested odict
+            dir: the direction source or sink
+        """
+        #build the port
+        Element.__init__(self, block)
+        #grab the data
+        self._name = n['name']
+        self._key = n['key']
+        self._type = n['type']
+        self._dir = dir
 
-	
-	def validate(self):
-		"""
-		Validate the port.
-		The port must be non-empty and type must a possible type.
-		"""
-		Element.validate(self)
-		if self.get_type() not in self.get_types():
-			self.add_error_message('Type "%s" is not a possible type.'%self.get_type())
+    def validate(self):
+        """
+        Validate the port.
+        The port must be non-empty and type must a possible type.
+        """
+        Element.validate(self)
+        if self.get_type() not in self.get_types():
+            self.add_error_message('Type "%s" is not a possible type.'%self.get_type())
 
-	def __str__(self):
-		if self.is_source():
-			return 'Source - %s(%s)'%(self.get_name(), self.get_key())
-		if self.is_sink():
-			return 'Sink - %s(%s)'%(self.get_name(), self.get_key())
+    def __str__(self):
+        if self.is_source():
+            return 'Source - %s(%s)'%(self.get_name(), self.get_key())
+        if self.is_sink():
+            return 'Sink - %s(%s)'%(self.get_name(), self.get_key())
 
-	def get_types(self):
-		"""
-		Get a list of all possible port types.
-		@throw NotImplementedError
-		"""
-		raise NotImplementedError
+    def get_types(self):
+        """
+        Get a list of all possible port types.
+        @throw NotImplementedError
+        """
+        raise NotImplementedError
 
-	def is_port(self): return True
-	def get_color(self): return '#FFFFFF'
-	def get_name(self):
-		number = ''
-		if self.get_type() == 'bus':
-			busses = filter(lambda a: a._dir == self._dir, self.get_parent().get_ports_gui());
-			
-			number = str(busses.index(self)) + '#' + str(len(self.get_associated_ports()));
-		return self._name + number
+    def is_port(self): return True
+    def get_color(self): return '#FFFFFF'
+    def get_name(self):
+        number = ''
+        if self.get_type() == 'bus':
+            busses = filter(lambda a: a._dir == self._dir, self.get_parent().get_ports_gui());
+            
+            number = str(busses.index(self)) + '#' + str(len(self.get_associated_ports()));
+        return self._name + number
 
-	def get_key(self): return self._key
-	def is_sink(self): return self._dir == 'sink'
-	def is_source(self): return self._dir == 'source'
-	def get_type(self): return self.get_parent().resolve_dependencies(self._type)
+    def get_key(self): return self._key
+    def is_sink(self): return self._dir == 'sink'
+    def is_source(self): return self._dir == 'source'
+    def get_type(self): return self.get_parent().resolve_dependencies(self._type)
 
-	def get_connections(self):
-		"""
-		Get all connections that use this port.
-		
-		Returns:
-		    a list of connection objects
-		"""
-		connections = self.get_parent().get_parent().get_connections()
-		connections = filter(lambda c: c.get_source() is self or c.get_sink() is self, connections)
-		return connections
+    def get_connections(self):
+        """
+        Get all connections that use this port.
+        
+        Returns:
+            a list of connection objects
+        """
+        connections = self.get_parent().get_parent().get_connections()
+        connections = filter(lambda c: c.get_source() is self or c.get_sink() is self, connections)
+        return connections
 
-	def get_enabled_connections(self):
-		"""
-		Get all enabled connections that use this port.
-		
-		Returns:
-		    a list of connection objects
-		"""
-		return filter(lambda c: c.get_enabled(), self.get_connections())
-	
-	def get_associated_ports(self):
-		if not self.get_type() == 'bus':
-			return [self];
-		else:
-			if self.is_source():
-				get_p = self.get_parent().get_sources;
-				bus_structure = self.get_parent().current_bus_structure['source'];
-				direc = 'source'
-			else:
-				get_p = self.get_parent().get_sinks;
-				bus_structure = self.get_parent().current_bus_structure['sink'];
-				direc = 'sink'
-			
-			ports = [i for i in get_p() if not i.get_type() == 'bus'];
-			if bus_structure:
-				busses = [i for i in get_p() if i.get_type() == 'bus'];
-				bus_index = busses.index(self);
-				ports = filter(lambda a: ports.index(a) in bus_structure[bus_index], ports);
-			return ports;
+    def get_enabled_connections(self):
+        """
+        Get all enabled connections that use this port.
+        
+        Returns:
+            a list of connection objects
+        """
+        return filter(lambda c: c.get_enabled(), self.get_connections())
+
+    def get_associated_ports(self):
+        if not self.get_type() == 'bus':
+            return [self];
+        else:
+            if self.is_source():
+                get_p = self.get_parent().get_sources;
+                bus_structure = self.get_parent().current_bus_structure['source'];
+                direc = 'source'
+            else:
+                get_p = self.get_parent().get_sinks;
+                bus_structure = self.get_parent().current_bus_structure['sink'];
+                direc = 'sink'
+            
+            ports = [i for i in get_p() if not i.get_type() == 'bus'];
+            if bus_structure:
+                busses = [i for i in get_p() if i.get_type() == 'bus'];
+                bus_index = busses.index(self);
+                ports = filter(lambda a: ports.index(a) in bus_structure[bus_index], ports);
+            return ports;
diff --git a/grc/base/block_tree.dtd b/grc/base/block_tree.dtd
index 7d4a13ccc3..9e23576477 100644
--- a/grc/base/block_tree.dtd
+++ b/grc/base/block_tree.dtd
@@ -17,9 +17,9 @@ along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 -->
 <!--
-	block_tree.dtd
-	Josh Blum
-	The document type definition for a block tree category listing.
+    block_tree.dtd
+    Josh Blum
+    The document type definition for a block tree category listing.
  -->
 <!ELEMENT cat (name, cat*, block*)>
 <!ELEMENT name (#PCDATA)>
diff --git a/grc/base/flow_graph.dtd b/grc/base/flow_graph.dtd
index becfc21e9b..bdfe1dc059 100644
--- a/grc/base/flow_graph.dtd
+++ b/grc/base/flow_graph.dtd
@@ -17,9 +17,9 @@ along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 -->
 <!--
-	flow_graph.dtd
-	Josh Blum
-	The document type definition for flow graph xml files.
+    flow_graph.dtd
+    Josh Blum
+    The document type definition for flow graph xml files.
  -->
 <!ELEMENT flow_graph (timestamp?, block*, connection*)> <!-- optional timestamp -->
 <!ELEMENT timestamp (#PCDATA)>
diff --git a/grc/base/odict.py b/grc/base/odict.py
index 302583163b..0c03d753f6 100644
--- a/grc/base/odict.py
+++ b/grc/base/odict.py
@@ -21,85 +21,85 @@ from UserDict import DictMixin
 
 class odict(DictMixin):
 
-	def __init__(self, d={}):
-		self._keys = list(d.keys())
-		self._data = dict(d.copy())
+    def __init__(self, d={}):
+        self._keys = list(d.keys())
+        self._data = dict(d.copy())
 
-	def __setitem__(self, key, value):
-		if key not in self._data:
-			self._keys.append(key)
-		self._data[key] = value
+    def __setitem__(self, key, value):
+        if key not in self._data:
+            self._keys.append(key)
+        self._data[key] = value
 
-	def __getitem__(self, key):
-		return self._data[key]
+    def __getitem__(self, key):
+        return self._data[key]
 
-	def __delitem__(self, key):
-		del self._data[key]
-		self._keys.remove(key)
+    def __delitem__(self, key):
+        del self._data[key]
+        self._keys.remove(key)
 
-	def keys(self):
-		return list(self._keys)
+    def keys(self):
+        return list(self._keys)
 
-	def copy(self):
-		copy_dict = odict()
-		copy_dict._data = self._data.copy()
-		copy_dict._keys = list(self._keys)
-		return copy_dict
+    def copy(self):
+        copy_dict = odict()
+        copy_dict._data = self._data.copy()
+        copy_dict._keys = list(self._keys)
+        return copy_dict
 
-	def insert_after(self, pos_key, key, val):
-		"""
-		Insert the new key, value entry after the entry given by the position key.
-		If the positional key is None, insert at the end.
-		
-		Args:
-		    pos_key: the positional key
-		    key: the key for the new entry
-		    val: the value for the new entry
-		"""
-		index = (pos_key is None) and len(self._keys) or self._keys.index(pos_key)
-		if key in self._keys: raise KeyError('Cannot insert, key "%s" already exists'%str(key))
-		self._keys.insert(index+1, key)
-		self._data[key] = val
+    def insert_after(self, pos_key, key, val):
+        """
+        Insert the new key, value entry after the entry given by the position key.
+        If the positional key is None, insert at the end.
+        
+        Args:
+            pos_key: the positional key
+            key: the key for the new entry
+            val: the value for the new entry
+        """
+        index = (pos_key is None) and len(self._keys) or self._keys.index(pos_key)
+        if key in self._keys: raise KeyError('Cannot insert, key "%s" already exists'%str(key))
+        self._keys.insert(index+1, key)
+        self._data[key] = val
 
-	def insert_before(self, pos_key, key, val):
-		"""
-		Insert the new key, value entry before the entry given by the position key.
-		If the positional key is None, insert at the begining.
-		
-		Args:
-		    pos_key: the positional key
-		    key: the key for the new entry
-		    val: the value for the new entry
-		"""
-		index = (pos_key is not None) and self._keys.index(pos_key) or 0
-		if key in self._keys: raise KeyError('Cannot insert, key "%s" already exists'%str(key))
-		self._keys.insert(index, key)
-		self._data[key] = val
+    def insert_before(self, pos_key, key, val):
+        """
+        Insert the new key, value entry before the entry given by the position key.
+        If the positional key is None, insert at the begining.
+        
+        Args:
+            pos_key: the positional key
+            key: the key for the new entry
+            val: the value for the new entry
+        """
+        index = (pos_key is not None) and self._keys.index(pos_key) or 0
+        if key in self._keys: raise KeyError('Cannot insert, key "%s" already exists'%str(key))
+        self._keys.insert(index, key)
+        self._data[key] = val
 
-	def find(self, key):
-		"""
-		Get the value for this key if exists.
-		
-		Args:
-		    key: the key to search for
-		
-		Returns:
-		    the value or None
-		"""
-		if self.has_key(key): return self[key]
-		return None
+    def find(self, key):
+        """
+        Get the value for this key if exists.
+        
+        Args:
+            key: the key to search for
+        
+        Returns:
+            the value or None
+        """
+        if self.has_key(key): return self[key]
+        return None
 
-	def findall(self, key):
-		"""
-		Get a list of values for this key.
-		
-		Args:
-		    key: the key to search for
-		
-		Returns:
-		    a list of values or empty list
-		"""
-		obj = self.find(key)
-		if obj is None: obj = list()
-		if isinstance(obj, list): return obj
-		return [obj]
+    def findall(self, key):
+        """
+        Get a list of values for this key.
+        
+        Args:
+            key: the key to search for
+        
+        Returns:
+            a list of values or empty list
+        """
+        obj = self.find(key)
+        if obj is None: obj = list()
+        if isinstance(obj, list): return obj
+        return [obj]
diff --git a/grc/examples/xmlrpc/xmlrpc_client_script.py b/grc/examples/xmlrpc/xmlrpc_client_script.py
index 8f00fa55d8..e96c4cbf83 100644
--- a/grc/examples/xmlrpc/xmlrpc_client_script.py
+++ b/grc/examples/xmlrpc/xmlrpc_client_script.py
@@ -9,15 +9,15 @@ s = xmlrpclib.Server("http://localhost:1234")
 
 #randomly change parameters of the sinusoid
 for i in range(10):
-	#generate random values
-	new_freq = random.uniform(0, 5000)
-	new_ampl = random.uniform(0, 2)
-	new_offset = random.uniform(-1, 1)
-	#set new values
-	time.sleep(1)
-	s.set_freq(new_freq)
-	time.sleep(1)
-	s.set_ampl(new_ampl)
-	time.sleep(1)
-	s.set_offset(new_offset)
+    #generate random values
+    new_freq = random.uniform(0, 5000)
+    new_ampl = random.uniform(0, 2)
+    new_offset = random.uniform(-1, 1)
+    #set new values
+    time.sleep(1)
+    s.set_freq(new_freq)
+    time.sleep(1)
+    s.set_ampl(new_ampl)
+    time.sleep(1)
+    s.set_offset(new_offset)
 
diff --git a/grc/grc_gnuradio/blks2/__init__.py b/grc/grc_gnuradio/blks2/__init__.py
index fde76f2563..e6941ab91b 100644
--- a/grc/grc_gnuradio/blks2/__init__.py
+++ b/grc/grc_gnuradio/blks2/__init__.py
@@ -20,7 +20,7 @@
 
 from selector import selector, valve
 from packet import options, packet_encoder, packet_decoder, \
-	packet_mod_b, packet_mod_s, packet_mod_i, packet_mod_f, packet_mod_c, \
-	packet_demod_b, packet_demod_s, packet_demod_i, packet_demod_f, packet_demod_c
+    packet_mod_b, packet_mod_s, packet_mod_i, packet_mod_f, packet_mod_c, \
+    packet_demod_b, packet_demod_s, packet_demod_i, packet_demod_f, packet_demod_c
 from error_rate import error_rate
 from tcp import tcp_source, tcp_sink
diff --git a/grc/grc_gnuradio/blks2/error_rate.py b/grc/grc_gnuradio/blks2/error_rate.py
index 7970f29bae..95ded7dadc 100644
--- a/grc/grc_gnuradio/blks2/error_rate.py
+++ b/grc/grc_gnuradio/blks2/error_rate.py
@@ -29,112 +29,112 @@ import numpy
 _1s_counts = [sum([1&(i>>j) for j in range(8)]) for i in range(2**8)]
 
 class input_watcher(_threading.Thread):
-	"""
-	Read samples from the message queue and hand them to the callback.
-	"""
+    """
+    Read samples from the message queue and hand them to the callback.
+    """
 
-	def __init__(self, msgq, callback):
-		self._msgq = msgq
-		self._callback = callback
-		_threading.Thread.__init__(self)
-		self.setDaemon(1)
-		self.keep_running = True
-		self.start()
+    def __init__(self, msgq, callback):
+        self._msgq = msgq
+        self._callback = callback
+        _threading.Thread.__init__(self)
+        self.setDaemon(1)
+        self.keep_running = True
+        self.start()
 
-	def run(self):
-		r = ''
-		while True:
-			msg = self._msgq.delete_head()
-			itemsize = int(msg.arg1())
-			nitems = int(msg.arg2())
-			s = r + msg.to_string()
-			i = (nitems-nitems%2)*itemsize
-			r = s[i:]
-			s = s[:i]
-			samples = numpy.fromstring(s, numpy.int8)
-			self._callback(samples)
+    def run(self):
+        r = ''
+        while True:
+            msg = self._msgq.delete_head()
+            itemsize = int(msg.arg1())
+            nitems = int(msg.arg2())
+            s = r + msg.to_string()
+            i = (nitems-nitems%2)*itemsize
+            r = s[i:]
+            s = s[:i]
+            samples = numpy.fromstring(s, numpy.int8)
+            self._callback(samples)
 
 class error_rate(gr.hier_block2):
-	"""
-	Sample the incoming data streams (byte) and calculate the bit or symbol error rate.
-	Write the running rate to the output data stream (float).
-	"""
+    """
+    Sample the incoming data streams (byte) and calculate the bit or symbol error rate.
+    Write the running rate to the output data stream (float).
+    """
 
-	def __init__(self, type='BER', win_size=default_win_size, bits_per_symbol=2):
-		"""
-		Error rate constructor.
-		
-		Args:
-		    type: a string 'BER' or 'SER'
-		    win_size: the number of samples to calculate over
-		    bits_per_symbol: the number of information bits per symbol (BER only)
-		"""
-		#init
-		gr.hier_block2.__init__(
-			self, 'error_rate',
-			gr.io_signature(2, 2, gr.sizeof_char),
-			gr.io_signature(1, 1, gr.sizeof_float),
-		)
-		assert type in ('BER', 'SER')
-		self._max_samples = win_size
-		self._bits_per_symbol = bits_per_symbol
-		#setup message queue
-		msg_source = blocks.message_source(gr.sizeof_float, 1)
-		self._msgq_source = msg_source.msgq()
-		msgq_sink = gr.msg_queue(2)
-		msg_sink = blocks.message_sink(gr.sizeof_char, msgq_sink, False) #False -> blocking
-		inter = blocks.interleave(gr.sizeof_char)
-		#start thread
-		self._num_errs = 0
-		self._err_index = 0
-		self._num_samps = 0
-		self._err_array = numpy.zeros(self._max_samples, numpy.int8)
-		if type == 'BER':
-			input_watcher(msgq_sink, self._handler_ber)
-		elif type == 'SER':
-			input_watcher(msgq_sink, self._handler_ser)
-		#connect
-		self.connect(msg_source, self)
-		self.connect((self, 0), (inter, 0))
-		self.connect((self, 1), (inter, 1))
-		self.connect(inter, msg_sink)
+    def __init__(self, type='BER', win_size=default_win_size, bits_per_symbol=2):
+        """
+        Error rate constructor.
+        
+        Args:
+            type: a string 'BER' or 'SER'
+            win_size: the number of samples to calculate over
+            bits_per_symbol: the number of information bits per symbol (BER only)
+        """
+        #init
+        gr.hier_block2.__init__(
+            self, 'error_rate',
+            gr.io_signature(2, 2, gr.sizeof_char),
+            gr.io_signature(1, 1, gr.sizeof_float),
+        )
+        assert type in ('BER', 'SER')
+        self._max_samples = win_size
+        self._bits_per_symbol = bits_per_symbol
+        #setup message queue
+        msg_source = blocks.message_source(gr.sizeof_float, 1)
+        self._msgq_source = msg_source.msgq()
+        msgq_sink = gr.msg_queue(2)
+        msg_sink = blocks.message_sink(gr.sizeof_char, msgq_sink, False) #False -> blocking
+        inter = blocks.interleave(gr.sizeof_char)
+        #start thread
+        self._num_errs = 0
+        self._err_index = 0
+        self._num_samps = 0
+        self._err_array = numpy.zeros(self._max_samples, numpy.int8)
+        if type == 'BER':
+            input_watcher(msgq_sink, self._handler_ber)
+        elif type == 'SER':
+            input_watcher(msgq_sink, self._handler_ser)
+        #connect
+        self.connect(msg_source, self)
+        self.connect((self, 0), (inter, 0))
+        self.connect((self, 1), (inter, 1))
+        self.connect(inter, msg_sink)
 
-	def _handler_ber(self, samples):
-		num = len(samples)/2
-		arr = numpy.zeros(num, numpy.float32)
-		for i in range(num):
-			old_err = self._err_array[self._err_index]
-			#record error
-			self._err_array[self._err_index] = _1s_counts[samples[i*2] ^ samples[i*2 + 1]]
-			self._num_errs = self._num_errs + self._err_array[self._err_index] - old_err
-			#increment index
-			self._err_index = (self._err_index + 1)%self._max_samples
-			self._num_samps = min(self._num_samps + 1, self._max_samples)
-			#write sample
-			arr[i] = float(self._num_errs)/float(self._num_samps*self._bits_per_symbol)
-		#write message
-		msg = blocks.message_from_string(arr.tostring(), 0, gr.sizeof_float, num)
-		self._msgq_source.insert_tail(msg)
+    def _handler_ber(self, samples):
+        num = len(samples)/2
+        arr = numpy.zeros(num, numpy.float32)
+        for i in range(num):
+            old_err = self._err_array[self._err_index]
+            #record error
+            self._err_array[self._err_index] = _1s_counts[samples[i*2] ^ samples[i*2 + 1]]
+            self._num_errs = self._num_errs + self._err_array[self._err_index] - old_err
+            #increment index
+            self._err_index = (self._err_index + 1)%self._max_samples
+            self._num_samps = min(self._num_samps + 1, self._max_samples)
+            #write sample
+            arr[i] = float(self._num_errs)/float(self._num_samps*self._bits_per_symbol)
+        #write message
+        msg = blocks.message_from_string(arr.tostring(), 0, gr.sizeof_float, num)
+        self._msgq_source.insert_tail(msg)
 
-	def _handler_ser(self, samples):
-		num = len(samples)/2
-		arr = numpy.zeros(num, numpy.float32)
-		for i in range(num):
-			old_err = self._err_array[self._err_index]
-			#record error
-			ref = samples[i*2]
-			res = samples[i*2 + 1]
-			if ref == res:
-				self._err_array[self._err_index] = 0
-			else:
-				self._err_array[self._err_index] = 1
-			#update number of errors
-			self._num_errs = self._num_errs + self._err_array[self._err_index] - old_err
-			#increment index
-			self._err_index = (self._err_index + 1)%self._max_samples
-			self._num_samps = min(self._num_samps + 1, self._max_samples)
-			#write sample
-			arr[i] = float(self._num_errs)/float(self._num_samps)
-		#write message
-		msg = blocks.message_from_string(arr.tostring(), 0, gr.sizeof_float, num)
-		self._msgq_source.insert_tail(msg)
+    def _handler_ser(self, samples):
+        num = len(samples)/2
+        arr = numpy.zeros(num, numpy.float32)
+        for i in range(num):
+            old_err = self._err_array[self._err_index]
+            #record error
+            ref = samples[i*2]
+            res = samples[i*2 + 1]
+            if ref == res:
+                self._err_array[self._err_index] = 0
+            else:
+                self._err_array[self._err_index] = 1
+            #update number of errors
+            self._num_errs = self._num_errs + self._err_array[self._err_index] - old_err
+            #increment index
+            self._err_index = (self._err_index + 1)%self._max_samples
+            self._num_samps = min(self._num_samps + 1, self._max_samples)
+            #write sample
+            arr[i] = float(self._num_errs)/float(self._num_samps)
+        #write message
+        msg = blocks.message_from_string(arr.tostring(), 0, gr.sizeof_float, num)
+        self._msgq_source.insert_tail(msg)
diff --git a/grc/grc_gnuradio/blks2/packet.py b/grc/grc_gnuradio/blks2/packet.py
index 4c7bd235dd..0cf89fbad0 100644
--- a/grc/grc_gnuradio/blks2/packet.py
+++ b/grc/grc_gnuradio/blks2/packet.py
@@ -36,176 +36,176 @@ DEFAULT_THRESHOLD = 12
 ## Options Class for OFDM
 ##################################################
 class options(object):
-	def __init__(self, **kwargs):
-		for key, value in kwargs.iteritems(): setattr(self, key, value)
+    def __init__(self, **kwargs):
+        for key, value in kwargs.iteritems(): setattr(self, key, value)
 
 ##################################################
 ## Packet Encoder
 ##################################################
 class _packet_encoder_thread(_threading.Thread):
 
-	def __init__(self, msgq, payload_length, send):
-		self._msgq = msgq
-		self._payload_length = payload_length
-		self._send = send
-		_threading.Thread.__init__(self)
-		self.setDaemon(1)
-		self.keep_running = True
-		self.start()
-
-	def run(self):
-		sample = '' #residual sample
-		while self.keep_running:
-			msg = self._msgq.delete_head() #blocking read of message queue
-			sample = sample + msg.to_string() #get the body of the msg as a string
-			while len(sample) >= self._payload_length:
-				payload = sample[:self._payload_length]
-				sample = sample[self._payload_length:]
-				self._send(payload)
+    def __init__(self, msgq, payload_length, send):
+        self._msgq = msgq
+        self._payload_length = payload_length
+        self._send = send
+        _threading.Thread.__init__(self)
+        self.setDaemon(1)
+        self.keep_running = True
+        self.start()
+
+    def run(self):
+        sample = '' #residual sample
+        while self.keep_running:
+            msg = self._msgq.delete_head() #blocking read of message queue
+            sample = sample + msg.to_string() #get the body of the msg as a string
+            while len(sample) >= self._payload_length:
+                payload = sample[:self._payload_length]
+                sample = sample[self._payload_length:]
+                self._send(payload)
 
 class packet_encoder(gr.hier_block2):
-	"""
-	Hierarchical block for wrapping packet-based modulators.
-	"""
-
-	def __init__(self, samples_per_symbol, bits_per_symbol, access_code='', pad_for_usrp=True):
-		"""
-		packet_mod constructor.
-		
-		Args:
-		    samples_per_symbol: number of samples per symbol
-		    bits_per_symbol: number of bits per symbol
-		    access_code: AKA sync vector
-		    pad_for_usrp: If true, packets are padded such that they end up a multiple of 128 samples
-		    payload_length: number of bytes in a data-stream slice
-		"""
-		#setup parameters
-		self._samples_per_symbol = samples_per_symbol
-		self._bits_per_symbol = bits_per_symbol
-		self._pad_for_usrp = pad_for_usrp
-		if not access_code: #get access code
-			access_code = packet_utils.default_access_code
-		if not packet_utils.is_1_0_string(access_code):
-			raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (access_code,)
-		self._access_code = access_code
-		self._pad_for_usrp = pad_for_usrp
-		#create blocks
-		msg_source = blocks.message_source(gr.sizeof_char, DEFAULT_MSGQ_LIMIT)
-		self._msgq_out = msg_source.msgq()
-		#initialize hier2
-		gr.hier_block2.__init__(
-			self,
-			"packet_encoder",
-			gr.io_signature(0, 0, 0), # Input signature
-			gr.io_signature(1, 1, gr.sizeof_char) # Output signature
-		)
-		#connect
-		self.connect(msg_source, self)
-
-	def send_pkt(self, payload):
-		"""
-		Wrap the payload in a packet and push onto the message queue.
-		
-		Args:
-		    payload: string, data to send
-		"""
-		packet = packet_utils.make_packet(
-			payload,
-			self._samples_per_symbol,
-			self._bits_per_symbol,
-			self._access_code,
-			self._pad_for_usrp
-		)
-		msg = gr.message_from_string(packet)
-		self._msgq_out.insert_tail(msg)
+    """
+    Hierarchical block for wrapping packet-based modulators.
+    """
+
+    def __init__(self, samples_per_symbol, bits_per_symbol, access_code='', pad_for_usrp=True):
+        """
+        packet_mod constructor.
+        
+        Args:
+            samples_per_symbol: number of samples per symbol
+            bits_per_symbol: number of bits per symbol
+            access_code: AKA sync vector
+            pad_for_usrp: If true, packets are padded such that they end up a multiple of 128 samples
+            payload_length: number of bytes in a data-stream slice
+        """
+        #setup parameters
+        self._samples_per_symbol = samples_per_symbol
+        self._bits_per_symbol = bits_per_symbol
+        self._pad_for_usrp = pad_for_usrp
+        if not access_code: #get access code
+            access_code = packet_utils.default_access_code
+        if not packet_utils.is_1_0_string(access_code):
+            raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (access_code,)
+        self._access_code = access_code
+        self._pad_for_usrp = pad_for_usrp
+        #create blocks
+        msg_source = blocks.message_source(gr.sizeof_char, DEFAULT_MSGQ_LIMIT)
+        self._msgq_out = msg_source.msgq()
+        #initialize hier2
+        gr.hier_block2.__init__(
+            self,
+            "packet_encoder",
+            gr.io_signature(0, 0, 0), # Input signature
+            gr.io_signature(1, 1, gr.sizeof_char) # Output signature
+        )
+        #connect
+        self.connect(msg_source, self)
+
+    def send_pkt(self, payload):
+        """
+        Wrap the payload in a packet and push onto the message queue.
+        
+        Args:
+            payload: string, data to send
+        """
+        packet = packet_utils.make_packet(
+            payload,
+            self._samples_per_symbol,
+            self._bits_per_symbol,
+            self._access_code,
+            self._pad_for_usrp
+        )
+        msg = gr.message_from_string(packet)
+        self._msgq_out.insert_tail(msg)
 
 ##################################################
 ## Packet Decoder
 ##################################################
 class _packet_decoder_thread(_threading.Thread):
 
-	def __init__(self, msgq, callback):
-		_threading.Thread.__init__(self)
-		self.setDaemon(1)
-		self._msgq = msgq
-		self.callback = callback
-		self.keep_running = True
-		self.start()
-
-	def run(self):
-		while self.keep_running:
-			msg = self._msgq.delete_head()
-			ok, payload = packet_utils.unmake_packet(msg.to_string(), int(msg.arg1()))
-			if self.callback:
-				self.callback(ok, payload)
+    def __init__(self, msgq, callback):
+        _threading.Thread.__init__(self)
+        self.setDaemon(1)
+        self._msgq = msgq
+        self.callback = callback
+        self.keep_running = True
+        self.start()
+
+    def run(self):
+        while self.keep_running:
+            msg = self._msgq.delete_head()
+            ok, payload = packet_utils.unmake_packet(msg.to_string(), int(msg.arg1()))
+            if self.callback:
+                self.callback(ok, payload)
 
 class packet_decoder(gr.hier_block2):
-	"""
-	Hierarchical block for wrapping packet-based demodulators.
-	"""
-
-	def __init__(self, access_code='', threshold=-1, callback=None):
-		"""
-		packet_demod constructor.
-		
-		Args:
-		    access_code: AKA sync vector
-		    threshold: detect access_code with up to threshold bits wrong (0 -> use default)
-		    callback: a function of args: ok, payload
-		"""
-		#access code
-		if not access_code: #get access code
-			access_code = packet_utils.default_access_code
-		if not packet_utils.is_1_0_string(access_code):
-			raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (access_code,)
-		self._access_code = access_code
-		#threshold
-		if threshold < 0: threshold = DEFAULT_THRESHOLD
-		self._threshold = threshold
-		#blocks
-		msgq = gr.msg_queue(DEFAULT_MSGQ_LIMIT) #holds packets from the PHY
-		correlator = digital.correlate_access_code_bb(self._access_code, self._threshold)
-		framer_sink = digital.framer_sink_1(msgq)
-		#initialize hier2
-		gr.hier_block2.__init__(
-			self,
-			"packet_decoder",
-			gr.io_signature(1, 1, gr.sizeof_char), # Input signature
-			gr.io_signature(0, 0, 0) # Output signature
-		)
-		#connect
-		self.connect(self, correlator, framer_sink)
-		#start thread
-		_packet_decoder_thread(msgq, callback)
+    """
+    Hierarchical block for wrapping packet-based demodulators.
+    """
+
+    def __init__(self, access_code='', threshold=-1, callback=None):
+        """
+        packet_demod constructor.
+        
+        Args:
+            access_code: AKA sync vector
+            threshold: detect access_code with up to threshold bits wrong (0 -> use default)
+            callback: a function of args: ok, payload
+        """
+        #access code
+        if not access_code: #get access code
+            access_code = packet_utils.default_access_code
+        if not packet_utils.is_1_0_string(access_code):
+            raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (access_code,)
+        self._access_code = access_code
+        #threshold
+        if threshold < 0: threshold = DEFAULT_THRESHOLD
+        self._threshold = threshold
+        #blocks
+        msgq = gr.msg_queue(DEFAULT_MSGQ_LIMIT) #holds packets from the PHY
+        correlator = digital.correlate_access_code_bb(self._access_code, self._threshold)
+        framer_sink = digital.framer_sink_1(msgq)
+        #initialize hier2
+        gr.hier_block2.__init__(
+            self,
+            "packet_decoder",
+            gr.io_signature(1, 1, gr.sizeof_char), # Input signature
+            gr.io_signature(0, 0, 0) # Output signature
+        )
+        #connect
+        self.connect(self, correlator, framer_sink)
+        #start thread
+        _packet_decoder_thread(msgq, callback)
 
 ##################################################
 ## Packet Mod for OFDM Mod and Packet Encoder
 ##################################################
 class packet_mod_base(gr.hier_block2):
-	"""
-	Hierarchical block for wrapping packet source block.
-	"""
-
-	def __init__(self, packet_source=None, payload_length=0):
-		if not payload_length: #get payload length
-			payload_length = DEFAULT_PAYLOAD_LEN
-		if payload_length%self._item_size_in != 0:	#verify that packet length is a multiple of the stream size
-			raise ValueError, 'The payload length: "%d" is not a mutiple of the stream size: "%d".'%(payload_length, self._item_size_in)
-		#initialize hier2
-		gr.hier_block2.__init__(
-			self,
-			"ofdm_mod",
-			gr.io_signature(1, 1, self._item_size_in), # Input signature
-			gr.io_signature(1, 1, packet_source._hb.output_signature().sizeof_stream_item(0)) # Output signature
-		)
-		#create blocks
-		msgq = gr.msg_queue(DEFAULT_MSGQ_LIMIT)
-		msg_sink = blocks.message_sink(self._item_size_in, msgq, False) #False -> blocking
-		#connect
-		self.connect(self, msg_sink)
-		self.connect(packet_source, self)
-		#start thread
-		_packet_encoder_thread(msgq, payload_length, packet_source.send_pkt)
+    """
+    Hierarchical block for wrapping packet source block.
+    """
+
+    def __init__(self, packet_source=None, payload_length=0):
+        if not payload_length: #get payload length
+            payload_length = DEFAULT_PAYLOAD_LEN
+        if payload_length%self._item_size_in != 0:  #verify that packet length is a multiple of the stream size
+            raise ValueError, 'The payload length: "%d" is not a mutiple of the stream size: "%d".'%(payload_length, self._item_size_in)
+        #initialize hier2
+        gr.hier_block2.__init__(
+            self,
+            "ofdm_mod",
+            gr.io_signature(1, 1, self._item_size_in), # Input signature
+            gr.io_signature(1, 1, packet_source._hb.output_signature().sizeof_stream_item(0)) # Output signature
+        )
+        #create blocks
+        msgq = gr.msg_queue(DEFAULT_MSGQ_LIMIT)
+        msg_sink = blocks.message_sink(self._item_size_in, msgq, False) #False -> blocking
+        #connect
+        self.connect(self, msg_sink)
+        self.connect(packet_source, self)
+        #start thread
+        _packet_encoder_thread(msgq, payload_length, packet_source.send_pkt)
 
 class packet_mod_b(packet_mod_base): _item_size_in = gr.sizeof_char
 class packet_mod_s(packet_mod_base): _item_size_in = gr.sizeof_short
@@ -217,32 +217,32 @@ class packet_mod_c(packet_mod_base): _item_size_in = gr.sizeof_gr_complex
 ## Packet Demod for OFDM Demod and Packet Decoder
 ##################################################
 class packet_demod_base(gr.hier_block2):
-	"""
-	Hierarchical block for wrapping packet sink block.
-	"""
-
-	def __init__(self, packet_sink=None):
-		#initialize hier2
-		gr.hier_block2.__init__(
-			self,
-			"ofdm_mod",
-			gr.io_signature(1, 1, packet_sink._hb.input_signature().sizeof_stream_item(0)), # Input signature
-			gr.io_signature(1, 1, self._item_size_out) # Output signature
-		)
-		#create blocks
-		msg_source = blocks.message_source(self._item_size_out, DEFAULT_MSGQ_LIMIT)
-		self._msgq_out = msg_source.msgq()
-		#connect
-		self.connect(self, packet_sink)
-		self.connect(msg_source, self)
-		if packet_sink._hb.output_signature().sizeof_stream_item(0):
-			self.connect(packet_sink,
+    """
+    Hierarchical block for wrapping packet sink block.
+    """
+
+    def __init__(self, packet_sink=None):
+        #initialize hier2
+        gr.hier_block2.__init__(
+            self,
+            "ofdm_mod",
+            gr.io_signature(1, 1, packet_sink._hb.input_signature().sizeof_stream_item(0)), # Input signature
+            gr.io_signature(1, 1, self._item_size_out) # Output signature
+        )
+        #create blocks
+        msg_source = blocks.message_source(self._item_size_out, DEFAULT_MSGQ_LIMIT)
+        self._msgq_out = msg_source.msgq()
+        #connect
+        self.connect(self, packet_sink)
+        self.connect(msg_source, self)
+        if packet_sink._hb.output_signature().sizeof_stream_item(0):
+            self.connect(packet_sink,
                                      blocks.null_sink(packet_sink._hb.output_signature().sizeof_stream_item(0)))
 
-	def recv_pkt(self, ok, payload):
-		msg = blocks.message_from_string(payload, 0, self._item_size_out,
+    def recv_pkt(self, ok, payload):
+        msg = blocks.message_from_string(payload, 0, self._item_size_out,
                                                  len(payload)/self._item_size_out)
-		if ok: self._msgq_out.insert_tail(msg)
+        if ok: self._msgq_out.insert_tail(msg)
 
 class packet_demod_b(packet_demod_base): _item_size_out = gr.sizeof_char
 class packet_demod_s(packet_demod_base): _item_size_out = gr.sizeof_short
diff --git a/grc/grc_gnuradio/blks2/selector.py b/grc/grc_gnuradio/blks2/selector.py
index bc393f84b6..7ae664823b 100644
--- a/grc/grc_gnuradio/blks2/selector.py
+++ b/grc/grc_gnuradio/blks2/selector.py
@@ -23,120 +23,120 @@ from gnuradio import gr
 from gnuradio import blocks
 
 class selector(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):
-		"""
-		Selector constructor.
-		
-		Args:
-		    item_size: the size of the gr data stream in bytes
-		    num_inputs: the number of inputs (integer)
-		    num_outputs: the number of outputs (integer)
-		    input_index: the index for the source data
-		    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 = [blocks.null_sink(item_size) for i in range(num_inputs)]
-		self.output_terminators = [blocks.head(item_size, 0) for i in range(num_outputs)]
-		self.copy = blocks.copy(item_size)
-		#connections
-		for i in range(num_inputs): self.connect((self, i), self.input_terminators[i])
-		for i in range(num_outputs): self.connect(blocks.null_source(item_size),
+    """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):
+        """
+        Selector constructor.
+        
+        Args:
+            item_size: the size of the gr data stream in bytes
+            num_inputs: the number of inputs (integer)
+            num_outputs: the number of outputs (integer)
+            input_index: the index for the source data
+            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 = [blocks.null_sink(item_size) for i in range(num_inputs)]
+        self.output_terminators = [blocks.head(item_size, 0) for i in range(num_outputs)]
+        self.copy = blocks.copy(item_size)
+        #connections
+        for i in range(num_inputs): self.connect((self, i), self.input_terminators[i])
+        for i in range(num_outputs): self.connect(blocks.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()
+        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?
-		
-		Returns:
-		    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 _indexes_valid(self):
+        """
+        Are the input and output indexes within range of the number of inputs and outputs?
+        
+        Returns:
+            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.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 _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.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])
-			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 _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])
+            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.
-		
-		Args:
-		    input_index: the new input index
-		"""
-		if self.input_index != input_index:
-			self.lock()
-			self._disconnect_current()
-			self.input_index = input_index
-			self._connect_current()
-			self.unlock()
+    def set_input_index(self, input_index):
+        """
+        Change the block to the new input index if the index changed.
+        
+        Args:
+            input_index: the new input index
+        """
+        if self.input_index != input_index:
+            self.lock()
+            self._disconnect_current()
+            self.input_index = input_index
+            self._connect_current()
+            self.unlock()
 
-	def set_output_index(self, output_index):
-		"""
-		Change the block to the new output index if the index changed.
-		
-		Args:
-		    output_index: the new output index
-		"""
-		if self.output_index != output_index:
-			self.lock()
-			self._disconnect_current()
-			self.output_index = output_index
-			self._connect_current()
-			self.unlock()
+    def set_output_index(self, output_index):
+        """
+        Change the block to the new output index if the index changed.
+        
+        Args:
+            output_index: the new output index
+        """
+        if self.output_index != output_index:
+            self.lock()
+            self._disconnect_current()
+            self.output_index = output_index
+            self._connect_current()
+            self.unlock()
 
 class valve(selector):
-	"""Wrapper for selector with 1 input and 1 output."""
+    """Wrapper for selector with 1 input and 1 output."""
 
-	def __init__(self, item_size, open):
-		"""
-		Constructor for valve.
-		
-		Args:
-		    item_size: the size of the gr data stream in bytes
-		    open: true if initial valve state is open
-		"""
-		if open: output_index = -1
-		else: output_index = 0
-		selector.__init__(self, item_size, 1, 1, 0, output_index)
+    def __init__(self, item_size, open):
+        """
+        Constructor for valve.
+        
+        Args:
+            item_size: the size of the gr data stream in bytes
+            open: true if initial valve state is open
+        """
+        if open: output_index = -1
+        else: output_index = 0
+        selector.__init__(self, item_size, 1, 1, 0, output_index)
 
-	def set_open(self, open):
-		"""
-		Callback to set open state.
-		
-		Args:
-		    open: true to set valve state to open
-		"""
-		if open: output_index = -1
-		else: output_index = 0
-		self.set_output_index(output_index)
+    def set_open(self, open):
+        """
+        Callback to set open state.
+        
+        Args:
+            open: true to set valve state to open
+        """
+        if open: output_index = -1
+        else: output_index = 0
+        self.set_output_index(output_index)
diff --git a/grc/grc_gnuradio/blks2/tcp.py b/grc/grc_gnuradio/blks2/tcp.py
index 33160020cb..8613c02a17 100644
--- a/grc/grc_gnuradio/blks2/tcp.py
+++ b/grc/grc_gnuradio/blks2/tcp.py
@@ -24,47 +24,47 @@ import socket
 import os
 
 def _get_sock_fd(addr, port, server):
-	"""
-	Get the file descriptor for the socket.
-	As a client, block on connect, dup the socket descriptor.
-	As a server, block on accept, dup the client descriptor.
-	
-	Args:
-	    addr: the ip address string
-	    port: the tcp port number
-	    server: true for server mode, false for client mode
-	
-	Returns:
-	    the file descriptor number
-	"""
-	sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-	if server:
-		sock.bind((addr, port))
-		sock.listen(1)
-		clientsock, address = sock.accept()
-		return os.dup(clientsock.fileno())
-	else:
-		sock.connect((addr, port))
-		return os.dup(sock.fileno())
+    """
+    Get the file descriptor for the socket.
+    As a client, block on connect, dup the socket descriptor.
+    As a server, block on accept, dup the client descriptor.
+    
+    Args:
+        addr: the ip address string
+        port: the tcp port number
+        server: true for server mode, false for client mode
+    
+    Returns:
+        the file descriptor number
+    """
+    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+    if server:
+        sock.bind((addr, port))
+        sock.listen(1)
+        clientsock, address = sock.accept()
+        return os.dup(clientsock.fileno())
+    else:
+        sock.connect((addr, port))
+        return os.dup(sock.fileno())
 
 class tcp_source(gr.hier_block2):
-	def __init__(self, itemsize, addr, port, server=True):
-		#init hier block
-		gr.hier_block2.__init__(
-			self, 'tcp_source',
-			gr.io_signature(0, 0, 0),
-			gr.io_signature(1, 1, itemsize),
-		)
-		fd = _get_sock_fd(addr, port, server)
-		self.connect(blocks.file_descriptor_source(itemsize, fd), self)
+    def __init__(self, itemsize, addr, port, server=True):
+        #init hier block
+        gr.hier_block2.__init__(
+            self, 'tcp_source',
+            gr.io_signature(0, 0, 0),
+            gr.io_signature(1, 1, itemsize),
+        )
+        fd = _get_sock_fd(addr, port, server)
+        self.connect(blocks.file_descriptor_source(itemsize, fd), self)
 
 class tcp_sink(gr.hier_block2):
-	def __init__(self, itemsize, addr, port, server=False):
-		#init hier block
-		gr.hier_block2.__init__(
-			self, 'tcp_sink',
-			gr.io_signature(1, 1, itemsize),
-			gr.io_signature(0, 0, 0),
-		)
-		fd = _get_sock_fd(addr, port, server)
-		self.connect(self, blocks.file_descriptor_sink(itemsize, fd))
+    def __init__(self, itemsize, addr, port, server=False):
+        #init hier block
+        gr.hier_block2.__init__(
+            self, 'tcp_sink',
+            gr.io_signature(1, 1, itemsize),
+            gr.io_signature(0, 0, 0),
+        )
+        fd = _get_sock_fd(addr, port, server)
+        self.connect(self, blocks.file_descriptor_sink(itemsize, fd))
diff --git a/grc/gui/ActionHandler.py b/grc/gui/ActionHandler.py
index fa3e960d26..71d62fc8f5 100644
--- a/grc/gui/ActionHandler.py
+++ b/grc/gui/ActionHandler.py
@@ -37,132 +37,132 @@ from FileDialogs import OpenFlowGraphFileDialog, SaveFlowGraphFileDialog, SaveIm
 gobject.threads_init()
 
 class ActionHandler:
-	"""
-	The action handler will setup all the major window components,
-	and handle button presses and flow graph operations from the GUI.
-	"""
-
-	def __init__(self, file_paths, platform):
-		"""
-		ActionHandler constructor.
-		Create the main window, setup the message handler, import the preferences,
-		and connect all of the action handlers. Finally, enter the gtk main loop and block.
-		
-		Args:
-		    file_paths: a list of flow graph file passed from command line
-		    platform: platform module
-		"""
-		self.clipboard = None
-		for action in Actions.get_all_actions(): action.connect('activate', self._handle_action)
-		#setup the main window
-		self.platform = platform;
-		self.main_window = MainWindow(platform)
-		self.main_window.connect('delete-event', self._quit)
-		self.main_window.connect('key-press-event', self._handle_key_press)
-		self.get_page = self.main_window.get_page
-		self.get_flow_graph = self.main_window.get_flow_graph
-		self.get_focus_flag = self.main_window.get_focus_flag
-		#setup the messages
-		Messages.register_messenger(self.main_window.add_report_line)
-		Messages.send_init(platform)
-		#initialize
-		self.init_file_paths = file_paths
-		Actions.APPLICATION_INITIALIZE()
-		#enter the mainloop
-		gtk.main()
-
-	def _handle_key_press(self, widget, event):
-		"""
-		Handle key presses from the keyboard and translate key combinations into actions.
-		This key press handler is called prior to the gtk key press handler.
-		This handler bypasses built in accelerator key handling when in focus because
-		* some keys are ignored by the accelerators like the direction keys,
-		* some keys are not registered to any accelerators but are still used.
-		When not in focus, gtk and the accelerators handle the the key press.
-		
-		Returns:
-		    false to let gtk handle the key action
-		"""
-		if not self.get_focus_flag(): return False
-		return Actions.handle_key_press(event)
-
-	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.
-		
-		Returns:
-		    true
-		"""
-		Actions.APPLICATION_QUIT()
-		return True
-
-	def _handle_action(self, action):
-		#print action
-		##################################################
-		# Initalize/Quit
-		##################################################
-		if action == Actions.APPLICATION_INITIALIZE:
-			for action in Actions.get_all_actions(): action.set_sensitive(False) #set all actions disabled
-			#enable a select few actions
-			for action in (
-				Actions.APPLICATION_QUIT, Actions.FLOW_GRAPH_NEW,
-				Actions.FLOW_GRAPH_OPEN, Actions.FLOW_GRAPH_SAVE_AS,
-				Actions.FLOW_GRAPH_CLOSE, Actions.ABOUT_WINDOW_DISPLAY,
-				Actions.FLOW_GRAPH_SCREEN_CAPTURE, Actions.HELP_WINDOW_DISPLAY,
-				Actions.TYPES_WINDOW_DISPLAY,
-			): action.set_sensitive(True)
-			if not self.init_file_paths:
-				self.init_file_paths = Preferences.files_open()
-			if not self.init_file_paths: self.init_file_paths = ['']
-			for file_path in self.init_file_paths:
-				if file_path: self.main_window.new_page(file_path) #load pages from file paths
-			if Preferences.file_open() in self.init_file_paths:
-				self.main_window.new_page(Preferences.file_open(), show=True)
-			if not self.get_page():	self.main_window.new_page() #ensure that at least a blank page exists
-		elif action == Actions.APPLICATION_QUIT:
-			if self.main_window.close_pages():
-				gtk.main_quit()
-				exit(0)
-		##################################################
-		# Selections
-		##################################################
-		elif action == Actions.ELEMENT_SELECT:
-			pass #do nothing, update routines below
-		elif action == Actions.NOTHING_SELECT:
-			self.get_flow_graph().unselect()
-		##################################################
-		# Enable/Disable
-		##################################################
-		elif action == Actions.BLOCK_ENABLE:
-			if self.get_flow_graph().enable_selected(True):
-				self.get_flow_graph().update()
-				self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
-				self.get_page().set_saved(False)
-		elif action == Actions.BLOCK_DISABLE:
-			if self.get_flow_graph().enable_selected(False):
-				self.get_flow_graph().update()
-				self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
-				self.get_page().set_saved(False)
-		##################################################
-		# Cut/Copy/Paste
-		##################################################
-		elif action == Actions.BLOCK_CUT:
-			Actions.BLOCK_COPY()
-			Actions.ELEMENT_DELETE()
-		elif action == Actions.BLOCK_COPY:
-			self.clipboard = self.get_flow_graph().copy_to_clipboard()
-		elif action == Actions.BLOCK_PASTE:
-			if self.clipboard:
-				self.get_flow_graph().paste_from_clipboard(self.clipboard)
-				self.get_flow_graph().update()
-				self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
-				self.get_page().set_saved(False)
+    """
+    The action handler will setup all the major window components,
+    and handle button presses and flow graph operations from the GUI.
+    """
+
+    def __init__(self, file_paths, platform):
+        """
+        ActionHandler constructor.
+        Create the main window, setup the message handler, import the preferences,
+        and connect all of the action handlers. Finally, enter the gtk main loop and block.
+        
+        Args:
+            file_paths: a list of flow graph file passed from command line
+            platform: platform module
+        """
+        self.clipboard = None
+        for action in Actions.get_all_actions(): action.connect('activate', self._handle_action)
+        #setup the main window
+        self.platform = platform;
+        self.main_window = MainWindow(platform)
+        self.main_window.connect('delete-event', self._quit)
+        self.main_window.connect('key-press-event', self._handle_key_press)
+        self.get_page = self.main_window.get_page
+        self.get_flow_graph = self.main_window.get_flow_graph
+        self.get_focus_flag = self.main_window.get_focus_flag
+        #setup the messages
+        Messages.register_messenger(self.main_window.add_report_line)
+        Messages.send_init(platform)
+        #initialize
+        self.init_file_paths = file_paths
+        Actions.APPLICATION_INITIALIZE()
+        #enter the mainloop
+        gtk.main()
+
+    def _handle_key_press(self, widget, event):
+        """
+        Handle key presses from the keyboard and translate key combinations into actions.
+        This key press handler is called prior to the gtk key press handler.
+        This handler bypasses built in accelerator key handling when in focus because
+        * some keys are ignored by the accelerators like the direction keys,
+        * some keys are not registered to any accelerators but are still used.
+        When not in focus, gtk and the accelerators handle the the key press.
+        
+        Returns:
+            false to let gtk handle the key action
+        """
+        if not self.get_focus_flag(): return False
+        return Actions.handle_key_press(event)
+
+    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.
+        
+        Returns:
+            true
+        """
+        Actions.APPLICATION_QUIT()
+        return True
+
+    def _handle_action(self, action):
+        #print action
+        ##################################################
+        # Initalize/Quit
+        ##################################################
+        if action == Actions.APPLICATION_INITIALIZE:
+            for action in Actions.get_all_actions(): action.set_sensitive(False) #set all actions disabled
+            #enable a select few actions
+            for action in (
+                Actions.APPLICATION_QUIT, Actions.FLOW_GRAPH_NEW,
+                Actions.FLOW_GRAPH_OPEN, Actions.FLOW_GRAPH_SAVE_AS,
+                Actions.FLOW_GRAPH_CLOSE, Actions.ABOUT_WINDOW_DISPLAY,
+                Actions.FLOW_GRAPH_SCREEN_CAPTURE, Actions.HELP_WINDOW_DISPLAY,
+                Actions.TYPES_WINDOW_DISPLAY,
+            ): action.set_sensitive(True)
+            if not self.init_file_paths:
+                self.init_file_paths = Preferences.files_open()
+            if not self.init_file_paths: self.init_file_paths = ['']
+            for file_path in self.init_file_paths:
+                if file_path: self.main_window.new_page(file_path) #load pages from file paths
+            if Preferences.file_open() in self.init_file_paths:
+                self.main_window.new_page(Preferences.file_open(), show=True)
+            if not self.get_page(): self.main_window.new_page() #ensure that at least a blank page exists
+        elif action == Actions.APPLICATION_QUIT:
+            if self.main_window.close_pages():
+                gtk.main_quit()
+                exit(0)
+        ##################################################
+        # Selections
+        ##################################################
+        elif action == Actions.ELEMENT_SELECT:
+            pass #do nothing, update routines below
+        elif action == Actions.NOTHING_SELECT:
+            self.get_flow_graph().unselect()
+        ##################################################
+        # Enable/Disable
+        ##################################################
+        elif action == Actions.BLOCK_ENABLE:
+            if self.get_flow_graph().enable_selected(True):
+                self.get_flow_graph().update()
+                self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
+                self.get_page().set_saved(False)
+        elif action == Actions.BLOCK_DISABLE:
+            if self.get_flow_graph().enable_selected(False):
+                self.get_flow_graph().update()
+                self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
+                self.get_page().set_saved(False)
+        ##################################################
+        # Cut/Copy/Paste
+        ##################################################
+        elif action == Actions.BLOCK_CUT:
+            Actions.BLOCK_COPY()
+            Actions.ELEMENT_DELETE()
+        elif action == Actions.BLOCK_COPY:
+            self.clipboard = self.get_flow_graph().copy_to_clipboard()
+        elif action == Actions.BLOCK_PASTE:
+            if self.clipboard:
+                self.get_flow_graph().paste_from_clipboard(self.clipboard)
+                self.get_flow_graph().update()
+                self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
+                self.get_page().set_saved(False)
                 ##################################################
                 # Create heir block 
                 ##################################################
-		elif action == Actions.BLOCK_CREATE_HIER:
+        elif action == Actions.BLOCK_CREATE_HIER:
 
                         # keeping track of coordinates for pasting later
                         coords = self.get_flow_graph().get_selected_blocks()[0].get_coordinate()
@@ -211,8 +211,8 @@ class ActionHandler:
 
                         # Copy the selected blocks and paste them into a new page
                         #   then move the flowgraph to a reasonable position
-			Actions.BLOCK_COPY()
-			self.main_window.new_page()
+                        Actions.BLOCK_COPY()
+                        self.main_window.new_page()
                         Actions.BLOCK_PASTE()
                         coords = (x_min,y_min)
                         self.get_flow_graph().move_selected(coords)
@@ -284,274 +284,272 @@ class ActionHandler:
                                 new_connection = self.get_flow_graph().connect(pad_source,sink)
 
                         # update the new heir block flow graph 
-		        self.get_flow_graph().update()
+                        self.get_flow_graph().update()
                                
 
-		##################################################
-		# Move/Rotate/Delete/Create
-		##################################################
-		elif action == Actions.BLOCK_MOVE:
-			self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
-			self.get_page().set_saved(False)
-		elif action == Actions.BLOCK_ROTATE_CCW:
-			if self.get_flow_graph().rotate_selected(90):
-				self.get_flow_graph().update()
-				self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
-				self.get_page().set_saved(False)
-		elif action == Actions.BLOCK_ROTATE_CW:
-			if self.get_flow_graph().rotate_selected(-90):
-				self.get_flow_graph().update()
-				self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
-				self.get_page().set_saved(False)
-		elif action == Actions.ELEMENT_DELETE:
-			if self.get_flow_graph().remove_selected():
-				self.get_flow_graph().update()
-				self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
-				Actions.NOTHING_SELECT()
-				self.get_page().set_saved(False)
-		elif action == Actions.ELEMENT_CREATE:
-			self.get_flow_graph().update()
-			self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
-			Actions.NOTHING_SELECT()
-			self.get_page().set_saved(False)
-		elif action == Actions.BLOCK_INC_TYPE:
-			if self.get_flow_graph().type_controller_modify_selected(1):
-				self.get_flow_graph().update()
-				self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
-				self.get_page().set_saved(False)
-		elif action == Actions.BLOCK_DEC_TYPE:
-			if self.get_flow_graph().type_controller_modify_selected(-1):
-				self.get_flow_graph().update()
-				self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
-				self.get_page().set_saved(False)
-		elif action == Actions.PORT_CONTROLLER_INC:
-			if self.get_flow_graph().port_controller_modify_selected(1):
-				self.get_flow_graph().update()
-				self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
-				self.get_page().set_saved(False)
-		elif action == Actions.PORT_CONTROLLER_DEC:
-			if self.get_flow_graph().port_controller_modify_selected(-1):
-				self.get_flow_graph().update()
-				self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
-				self.get_page().set_saved(False)
-		##################################################
-		# Window stuff
-		##################################################
-		elif action == Actions.ABOUT_WINDOW_DISPLAY:
-			Dialogs.AboutDialog(self.get_flow_graph().get_parent())
-		elif action == Actions.HELP_WINDOW_DISPLAY:
-			Dialogs.HelpDialog()
-		elif action == Actions.TYPES_WINDOW_DISPLAY:
-			Dialogs.TypesDialog(self.get_flow_graph().get_parent())
-		elif action == Actions.ERRORS_WINDOW_DISPLAY:
-			Dialogs.ErrorsDialog(self.get_flow_graph())
-		##################################################
-		# Param Modifications
-		##################################################
-		elif action == Actions.BLOCK_PARAM_MODIFY:
-			selected_block = self.get_flow_graph().get_selected_block()
-			if selected_block:
-				if PropsDialog(selected_block).run():
-					#save the new state
-					self.get_flow_graph().update()
-					self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
-					self.get_page().set_saved(False)
-				else:
-					#restore the current state
-					n = self.get_page().get_state_cache().get_current_state()
-					self.get_flow_graph().import_data(n)
-					self.get_flow_graph().update()
-		##################################################
-		# Undo/Redo
-		##################################################
-		elif action == Actions.FLOW_GRAPH_UNDO:
-			n = self.get_page().get_state_cache().get_prev_state()
-			if n:
-				self.get_flow_graph().unselect()
-				self.get_flow_graph().import_data(n)
-				self.get_flow_graph().update()
-				self.get_page().set_saved(False)
-		elif action == Actions.FLOW_GRAPH_REDO:
-			n = self.get_page().get_state_cache().get_next_state()
-			if n:
-				self.get_flow_graph().unselect()
-				self.get_flow_graph().import_data(n)
-				self.get_flow_graph().update()
-				self.get_page().set_saved(False)
-		##################################################
-		# New/Open/Save/Close
-		##################################################
-		elif action == Actions.FLOW_GRAPH_NEW:
-			self.main_window.new_page()
-		elif action == Actions.FLOW_GRAPH_OPEN:
-			file_paths = OpenFlowGraphFileDialog(self.get_page().get_file_path()).run()
-			if file_paths: #open a new page for each file, show only the first
-				for i,file_path in enumerate(file_paths):
-					self.main_window.new_page(file_path, show=(i==0))
-		elif action == Actions.FLOW_GRAPH_CLOSE:
-			self.main_window.close_page()
-		elif action == Actions.FLOW_GRAPH_SAVE:
-			#read-only or undefined file path, do save-as
-			if self.get_page().get_read_only() or not self.get_page().get_file_path():
-				Actions.FLOW_GRAPH_SAVE_AS()
-			#otherwise try to save
-			else:
-				try:
-					ParseXML.to_file(self.get_flow_graph().export_data(), self.get_page().get_file_path())
-                                        self.get_flow_graph().grc_file_path = self.get_page().get_file_path()
-					self.get_page().set_saved(True)
-				except IOError:
-					Messages.send_fail_save(self.get_page().get_file_path())
-					self.get_page().set_saved(False)
-		elif action == Actions.FLOW_GRAPH_SAVE_AS:
-			file_path = SaveFlowGraphFileDialog(self.get_page().get_file_path()).run()
-			if file_path is not None:
-				self.get_page().set_file_path(file_path)
-				Actions.FLOW_GRAPH_SAVE()
-		elif action == Actions.FLOW_GRAPH_SCREEN_CAPTURE:
-			file_path = SaveImageFileDialog(self.get_page().get_file_path()).run()
-			if file_path is not None:
-				pixbuf = self.get_flow_graph().get_drawing_area().get_pixbuf()
-				pixbuf.save(file_path, IMAGE_FILE_EXTENSION[1:])
-		##################################################
-		# Gen/Exec/Stop
-		##################################################
-		elif action == Actions.FLOW_GRAPH_GEN:
-			if not self.get_page().get_proc():
-				if not self.get_page().get_saved() or not self.get_page().get_file_path():
-					Actions.FLOW_GRAPH_SAVE() #only save if file path missing or not saved
-				if self.get_page().get_saved() and self.get_page().get_file_path():
-					generator = self.get_page().get_generator()
-					try:
-						Messages.send_start_gen(generator.get_file_path())
-						generator.write()
-					except Exception,e: Messages.send_fail_gen(e)
-				else: self.generator = None
-		elif action == Actions.FLOW_GRAPH_EXEC:
-			if not self.get_page().get_proc():
-				Actions.FLOW_GRAPH_GEN()
-				if self.get_page().get_saved() and self.get_page().get_file_path():
-					ExecFlowGraphThread(self)
-		elif action == Actions.FLOW_GRAPH_KILL:
-			if self.get_page().get_proc():
-				try: self.get_page().get_proc().kill()
-				except: print "could not kill process: %d"%self.get_page().get_proc().pid
-		elif action == Actions.PAGE_CHANGE: #pass and run the global actions
-			pass
-		elif action == Actions.RELOAD_BLOCKS:
-			self.platform.loadblocks()
-			self.main_window.btwin.clear();
-			self.platform.load_block_tree(self.main_window.btwin);
-		elif action == Actions.OPEN_HIER:
-			bn = [];
-			for b in self.get_flow_graph().get_selected_blocks():
-				if b._grc_source:
-				    self.main_window.new_page(b._grc_source, show=True);
-		elif action == Actions.BUSSIFY_SOURCES:
-			n = {'name':'bus', 'type':'bus'}
-			for b in self.get_flow_graph().get_selected_blocks():
-				b.bussify(n, 'source');
-			self.get_flow_graph()._old_selected_port = None;
-			self.get_flow_graph()._new_selected_port = None;
-			Actions.ELEMENT_CREATE();
-			
-		elif action == Actions.BUSSIFY_SINKS:
-			n = {'name':'bus', 'type':'bus'}
-			for b in self.get_flow_graph().get_selected_blocks():
-				b.bussify(n, 'sink')
-			self.get_flow_graph()._old_selected_port = None;
-			self.get_flow_graph()._new_selected_port = None;
-			Actions.ELEMENT_CREATE();
-			
-				
-		else: print '!!! Action "%s" not handled !!!'%action
-		##################################################
-		# Global Actions for all States
-		##################################################
-		#update general buttons
-		Actions.ERRORS_WINDOW_DISPLAY.set_sensitive(not self.get_flow_graph().is_valid())
-		Actions.ELEMENT_DELETE.set_sensitive(bool(self.get_flow_graph().get_selected_elements()))
-		Actions.BLOCK_PARAM_MODIFY.set_sensitive(bool(self.get_flow_graph().get_selected_block()))
-		Actions.BLOCK_ROTATE_CCW.set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
-		Actions.BLOCK_ROTATE_CW.set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
-		#update cut/copy/paste
-		Actions.BLOCK_CUT.set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
-		Actions.BLOCK_COPY.set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
-		Actions.BLOCK_PASTE.set_sensitive(bool(self.clipboard))
-		#update enable/disable
-		Actions.BLOCK_ENABLE.set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
-		Actions.BLOCK_DISABLE.set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
-		Actions.BLOCK_CREATE_HIER.set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
-		Actions.OPEN_HIER.set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
-		Actions.BUSSIFY_SOURCES.set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
-		Actions.BUSSIFY_SINKS.set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
-		Actions.RELOAD_BLOCKS.set_sensitive(True)
-		#set the exec and stop buttons
-		self.update_exec_stop()
-		#saved status
-		Actions.FLOW_GRAPH_SAVE.set_sensitive(not self.get_page().get_saved())
-		self.main_window.update()
-		try: #set the size of the flow graph area (if changed)
-			new_size = self.get_flow_graph().get_option('window_size')
-			if self.get_flow_graph().get_size() != tuple(new_size):
-				self.get_flow_graph().set_size(*new_size)
-		except: pass
-		#draw the flow graph
-		self.get_flow_graph().update_selected()
-		self.get_flow_graph().queue_draw()
-		return True #action was handled
-
-	def update_exec_stop(self):
-		"""
-		Update the exec and stop buttons.
-		Lock and unlock the mutex for race conditions with exec flow graph threads.
-		"""
-		sensitive = self.get_flow_graph().is_valid() and not self.get_page().get_proc()
-		Actions.FLOW_GRAPH_GEN.set_sensitive(sensitive)
-		Actions.FLOW_GRAPH_EXEC.set_sensitive(sensitive)
-		Actions.FLOW_GRAPH_KILL.set_sensitive(self.get_page().get_proc() != None)
+        ##################################################
+        # Move/Rotate/Delete/Create
+        ##################################################
+        elif action == Actions.BLOCK_MOVE:
+            self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
+            self.get_page().set_saved(False)
+        elif action == Actions.BLOCK_ROTATE_CCW:
+            if self.get_flow_graph().rotate_selected(90):
+                self.get_flow_graph().update()
+                self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
+                self.get_page().set_saved(False)
+        elif action == Actions.BLOCK_ROTATE_CW:
+            if self.get_flow_graph().rotate_selected(-90):
+                self.get_flow_graph().update()
+                self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
+                self.get_page().set_saved(False)
+        elif action == Actions.ELEMENT_DELETE:
+            if self.get_flow_graph().remove_selected():
+                self.get_flow_graph().update()
+                self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
+                Actions.NOTHING_SELECT()
+                self.get_page().set_saved(False)
+        elif action == Actions.ELEMENT_CREATE:
+            self.get_flow_graph().update()
+            self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
+            Actions.NOTHING_SELECT()
+            self.get_page().set_saved(False)
+        elif action == Actions.BLOCK_INC_TYPE:
+            if self.get_flow_graph().type_controller_modify_selected(1):
+                self.get_flow_graph().update()
+                self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
+                self.get_page().set_saved(False)
+        elif action == Actions.BLOCK_DEC_TYPE:
+            if self.get_flow_graph().type_controller_modify_selected(-1):
+                self.get_flow_graph().update()
+                self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
+                self.get_page().set_saved(False)
+        elif action == Actions.PORT_CONTROLLER_INC:
+            if self.get_flow_graph().port_controller_modify_selected(1):
+                self.get_flow_graph().update()
+                self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
+                self.get_page().set_saved(False)
+        elif action == Actions.PORT_CONTROLLER_DEC:
+            if self.get_flow_graph().port_controller_modify_selected(-1):
+                self.get_flow_graph().update()
+                self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
+                self.get_page().set_saved(False)
+        ##################################################
+        # Window stuff
+        ##################################################
+        elif action == Actions.ABOUT_WINDOW_DISPLAY:
+            Dialogs.AboutDialog(self.get_flow_graph().get_parent())
+        elif action == Actions.HELP_WINDOW_DISPLAY:
+            Dialogs.HelpDialog()
+        elif action == Actions.TYPES_WINDOW_DISPLAY:
+            Dialogs.TypesDialog(self.get_flow_graph().get_parent())
+        elif action == Actions.ERRORS_WINDOW_DISPLAY:
+            Dialogs.ErrorsDialog(self.get_flow_graph())
+        ##################################################
+        # Param Modifications
+        ##################################################
+        elif action == Actions.BLOCK_PARAM_MODIFY:
+            selected_block = self.get_flow_graph().get_selected_block()
+            if selected_block:
+                if PropsDialog(selected_block).run():
+                    #save the new state
+                    self.get_flow_graph().update()
+                    self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
+                    self.get_page().set_saved(False)
+                else:
+                    #restore the current state
+                    n = self.get_page().get_state_cache().get_current_state()
+                    self.get_flow_graph().import_data(n)
+                    self.get_flow_graph().update()
+        ##################################################
+        # Undo/Redo
+        ##################################################
+        elif action == Actions.FLOW_GRAPH_UNDO:
+            n = self.get_page().get_state_cache().get_prev_state()
+            if n:
+                self.get_flow_graph().unselect()
+                self.get_flow_graph().import_data(n)
+                self.get_flow_graph().update()
+                self.get_page().set_saved(False)
+        elif action == Actions.FLOW_GRAPH_REDO:
+            n = self.get_page().get_state_cache().get_next_state()
+            if n:
+                self.get_flow_graph().unselect()
+                self.get_flow_graph().import_data(n)
+                self.get_flow_graph().update()
+                self.get_page().set_saved(False)
+        ##################################################
+        # New/Open/Save/Close
+        ##################################################
+        elif action == Actions.FLOW_GRAPH_NEW:
+            self.main_window.new_page()
+        elif action == Actions.FLOW_GRAPH_OPEN:
+            file_paths = OpenFlowGraphFileDialog(self.get_page().get_file_path()).run()
+            if file_paths: #open a new page for each file, show only the first
+                for i,file_path in enumerate(file_paths):
+                    self.main_window.new_page(file_path, show=(i==0))
+        elif action == Actions.FLOW_GRAPH_CLOSE:
+            self.main_window.close_page()
+        elif action == Actions.FLOW_GRAPH_SAVE:
+            #read-only or undefined file path, do save-as
+            if self.get_page().get_read_only() or not self.get_page().get_file_path():
+                Actions.FLOW_GRAPH_SAVE_AS()
+            #otherwise try to save
+            else:
+                try:
+                    ParseXML.to_file(self.get_flow_graph().export_data(), self.get_page().get_file_path())
+                    self.get_flow_graph().grc_file_path = self.get_page().get_file_path()
+                    self.get_page().set_saved(True)
+                except IOError:
+                    Messages.send_fail_save(self.get_page().get_file_path())
+                    self.get_page().set_saved(False)
+        elif action == Actions.FLOW_GRAPH_SAVE_AS:
+            file_path = SaveFlowGraphFileDialog(self.get_page().get_file_path()).run()
+            if file_path is not None:
+                self.get_page().set_file_path(file_path)
+                Actions.FLOW_GRAPH_SAVE()
+        elif action == Actions.FLOW_GRAPH_SCREEN_CAPTURE:
+            file_path = SaveImageFileDialog(self.get_page().get_file_path()).run()
+            if file_path is not None:
+                pixbuf = self.get_flow_graph().get_drawing_area().get_pixbuf()
+                pixbuf.save(file_path, IMAGE_FILE_EXTENSION[1:])
+        ##################################################
+        # Gen/Exec/Stop
+        ##################################################
+        elif action == Actions.FLOW_GRAPH_GEN:
+            if not self.get_page().get_proc():
+                if not self.get_page().get_saved() or not self.get_page().get_file_path():
+                    Actions.FLOW_GRAPH_SAVE() #only save if file path missing or not saved
+                if self.get_page().get_saved() and self.get_page().get_file_path():
+                    generator = self.get_page().get_generator()
+                    try:
+                        Messages.send_start_gen(generator.get_file_path())
+                        generator.write()
+                    except Exception,e: Messages.send_fail_gen(e)
+                else: self.generator = None
+        elif action == Actions.FLOW_GRAPH_EXEC:
+            if not self.get_page().get_proc():
+                Actions.FLOW_GRAPH_GEN()
+                if self.get_page().get_saved() and self.get_page().get_file_path():
+                    ExecFlowGraphThread(self)
+        elif action == Actions.FLOW_GRAPH_KILL:
+            if self.get_page().get_proc():
+                try: self.get_page().get_proc().kill()
+                except: print "could not kill process: %d"%self.get_page().get_proc().pid
+        elif action == Actions.PAGE_CHANGE: #pass and run the global actions
+            pass
+        elif action == Actions.RELOAD_BLOCKS:
+            self.platform.loadblocks()
+            self.main_window.btwin.clear();
+            self.platform.load_block_tree(self.main_window.btwin);
+        elif action == Actions.OPEN_HIER:
+            bn = [];
+            for b in self.get_flow_graph().get_selected_blocks():
+                if b._grc_source:
+                    self.main_window.new_page(b._grc_source, show=True);
+        elif action == Actions.BUSSIFY_SOURCES:
+            n = {'name':'bus', 'type':'bus'}
+            for b in self.get_flow_graph().get_selected_blocks():
+                b.bussify(n, 'source');
+            self.get_flow_graph()._old_selected_port = None;
+            self.get_flow_graph()._new_selected_port = None;
+            Actions.ELEMENT_CREATE();
+            
+        elif action == Actions.BUSSIFY_SINKS:
+            n = {'name':'bus', 'type':'bus'}
+            for b in self.get_flow_graph().get_selected_blocks():
+                b.bussify(n, 'sink')
+            self.get_flow_graph()._old_selected_port = None;
+            self.get_flow_graph()._new_selected_port = None;
+            Actions.ELEMENT_CREATE();
+        else: print '!!! Action "%s" not handled !!!'%action
+        ##################################################
+        # Global Actions for all States
+        ##################################################
+        #update general buttons
+        Actions.ERRORS_WINDOW_DISPLAY.set_sensitive(not self.get_flow_graph().is_valid())
+        Actions.ELEMENT_DELETE.set_sensitive(bool(self.get_flow_graph().get_selected_elements()))
+        Actions.BLOCK_PARAM_MODIFY.set_sensitive(bool(self.get_flow_graph().get_selected_block()))
+        Actions.BLOCK_ROTATE_CCW.set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
+        Actions.BLOCK_ROTATE_CW.set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
+        #update cut/copy/paste
+        Actions.BLOCK_CUT.set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
+        Actions.BLOCK_COPY.set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
+        Actions.BLOCK_PASTE.set_sensitive(bool(self.clipboard))
+        #update enable/disable
+        Actions.BLOCK_ENABLE.set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
+        Actions.BLOCK_DISABLE.set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
+        Actions.BLOCK_CREATE_HIER.set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
+        Actions.OPEN_HIER.set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
+        Actions.BUSSIFY_SOURCES.set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
+        Actions.BUSSIFY_SINKS.set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
+        Actions.RELOAD_BLOCKS.set_sensitive(True)
+        #set the exec and stop buttons
+        self.update_exec_stop()
+        #saved status
+        Actions.FLOW_GRAPH_SAVE.set_sensitive(not self.get_page().get_saved())
+        self.main_window.update()
+        try: #set the size of the flow graph area (if changed)
+            new_size = self.get_flow_graph().get_option('window_size')
+            if self.get_flow_graph().get_size() != tuple(new_size):
+                self.get_flow_graph().set_size(*new_size)
+        except: pass
+        #draw the flow graph
+        self.get_flow_graph().update_selected()
+        self.get_flow_graph().queue_draw()
+        return True #action was handled
+
+    def update_exec_stop(self):
+        """
+        Update the exec and stop buttons.
+        Lock and unlock the mutex for race conditions with exec flow graph threads.
+        """
+        sensitive = self.get_flow_graph().is_valid() and not self.get_page().get_proc()
+        Actions.FLOW_GRAPH_GEN.set_sensitive(sensitive)
+        Actions.FLOW_GRAPH_EXEC.set_sensitive(sensitive)
+        Actions.FLOW_GRAPH_KILL.set_sensitive(self.get_page().get_proc() != None)
 
 class ExecFlowGraphThread(Thread):
-	"""Execute the flow graph as a new process and wait on it to finish."""
-
-	def __init__ (self, action_handler):
-		"""
-		ExecFlowGraphThread constructor.
-		
-		Args:
-		    action_handler: an instance of an ActionHandler
-		"""
-		Thread.__init__(self)
-		self.update_exec_stop = action_handler.update_exec_stop
-		self.flow_graph = action_handler.get_flow_graph()
-		#store page and dont use main window calls in run
-		self.page = action_handler.get_page()
-		Messages.send_start_exec(self.page.get_generator().get_file_path())
-		#get the popen
-		try:
-			self.p = self.page.get_generator().get_popen()
-			self.page.set_proc(self.p)
-			#update
-			self.update_exec_stop()
-			self.start()
-		except Exception, e:
-			Messages.send_verbose_exec(str(e))
-			Messages.send_end_exec()
-
-	def run(self):
-		"""
-		Wait on the executing process by reading from its stdout.
-		Use gobject.idle_add when calling functions that modify gtk objects.
-		"""
-		#handle completion
-		r = "\n"
-		while(r):
-			gobject.idle_add(Messages.send_verbose_exec, r)
-			r = os.read(self.p.stdout.fileno(), 1024)
-		gobject.idle_add(self.done)
-
-	def done(self):
-		"""Perform end of execution tasks."""
-		Messages.send_end_exec()
-		self.page.set_proc(None)
-		self.update_exec_stop()
+    """Execute the flow graph as a new process and wait on it to finish."""
+
+    def __init__ (self, action_handler):
+        """
+        ExecFlowGraphThread constructor.
+        
+        Args:
+            action_handler: an instance of an ActionHandler
+        """
+        Thread.__init__(self)
+        self.update_exec_stop = action_handler.update_exec_stop
+        self.flow_graph = action_handler.get_flow_graph()
+        #store page and dont use main window calls in run
+        self.page = action_handler.get_page()
+        Messages.send_start_exec(self.page.get_generator().get_file_path())
+        #get the popen
+        try:
+            self.p = self.page.get_generator().get_popen()
+            self.page.set_proc(self.p)
+            #update
+            self.update_exec_stop()
+            self.start()
+        except Exception, e:
+            Messages.send_verbose_exec(str(e))
+            Messages.send_end_exec()
+
+    def run(self):
+        """
+        Wait on the executing process by reading from its stdout.
+        Use gobject.idle_add when calling functions that modify gtk objects.
+        """
+        #handle completion
+        r = "\n"
+        while(r):
+            gobject.idle_add(Messages.send_verbose_exec, r)
+            r = os.read(self.p.stdout.fileno(), 1024)
+        gobject.idle_add(self.done)
+
+    def done(self):
+        """Perform end of execution tasks."""
+        Messages.send_end_exec()
+        self.page.set_proc(None)
+        self.update_exec_stop()
diff --git a/grc/gui/Actions.py b/grc/gui/Actions.py
index 5832e08bf0..a70109c021 100644
--- a/grc/gui/Actions.py
+++ b/grc/gui/Actions.py
@@ -30,26 +30,26 @@ _actions_keypress_dict = dict()
 _keymap = gtk.gdk.keymap_get_default()
 _used_mods_mask = NO_MODS_MASK
 def handle_key_press(event):
-	"""
-	Call the action associated with the key press event.
-	Both the key value and the mask must have a match.
-	
-	Args:
-	    event: a gtk key press event
-	
-	Returns:
-	    true if handled
-	"""
-	_used_mods_mask = reduce(lambda x, y: x | y, [mod_mask for keyval, mod_mask in _actions_keypress_dict], NO_MODS_MASK)
-	#extract the key value and the consumed modifiers
-	keyval, egroup, level, consumed = _keymap.translate_keyboard_state(
-		event.hardware_keycode, event.state, event.group)
-	#get the modifier mask and ignore irrelevant modifiers
-	mod_mask = event.state & ~consumed & _used_mods_mask
-	#look up the keypress and call the action
-	try: _actions_keypress_dict[(keyval, mod_mask)]()
-	except KeyError: return False #not handled
-	return True #handled here
+    """
+    Call the action associated with the key press event.
+    Both the key value and the mask must have a match.
+    
+    Args:
+        event: a gtk key press event
+    
+    Returns:
+        true if handled
+    """
+    _used_mods_mask = reduce(lambda x, y: x | y, [mod_mask for keyval, mod_mask in _actions_keypress_dict], NO_MODS_MASK)
+    #extract the key value and the consumed modifiers
+    keyval, egroup, level, consumed = _keymap.translate_keyboard_state(
+        event.hardware_keycode, event.state, event.group)
+    #get the modifier mask and ignore irrelevant modifiers
+    mod_mask = event.state & ~consumed & _used_mods_mask
+    #look up the keypress and call the action
+    try: _actions_keypress_dict[(keyval, mod_mask)]()
+    except KeyError: return False #not handled
+    return True #handled here
 
 _all_actions_list = list()
 def get_all_actions(): return _all_actions_list
@@ -58,250 +58,250 @@ _accel_group = gtk.AccelGroup()
 def get_accel_group(): return _accel_group
 
 class Action(gtk.Action):
-	"""
-	A custom Action class based on gtk.Action.
-	Pass additional arguments such as keypresses.
-	Register actions and keypresses with this module.
-	"""
+    """
+    A custom Action class based on gtk.Action.
+    Pass additional arguments such as keypresses.
+    Register actions and keypresses with this module.
+    """
 
-	def __init__(self, keypresses=(), name=None, label=None, tooltip=None, stock_id=None):
-		"""
-		Create a new Action instance.
-		
-		Args:
-		    key_presses: a tuple of (keyval1, mod_mask1, keyval2, mod_mask2, ...)
-		    the: regular gtk.Action parameters (defaults to None)
-		"""
-		if name is None: name = label
-		gtk.Action.__init__(self,
-			name=name, label=label,
-			tooltip=tooltip, stock_id=stock_id,
-		)
-		#register this action
-		_all_actions_list.append(self)
-		for i in range(len(keypresses)/2):
-			keyval, mod_mask = keypresses[i*2:(i+1)*2]
-			#register this keypress
-			if _actions_keypress_dict.has_key((keyval, mod_mask)):
-				raise KeyError('keyval/mod_mask pair already registered "%s"'%str((keyval, mod_mask)))
-			_actions_keypress_dict[(keyval, mod_mask)] = self
-			#set the accelerator group, and accelerator path
-			#register the key name and mod mask with the accelerator path
-			if label is None: continue #dont register accel
-			accel_path = '<main>/'+self.get_name()
-			self.set_accel_group(get_accel_group())
-			self.set_accel_path(accel_path)
-			gtk.accel_map_add_entry(accel_path, keyval, mod_mask)
+    def __init__(self, keypresses=(), name=None, label=None, tooltip=None, stock_id=None):
+        """
+        Create a new Action instance.
+        
+        Args:
+            key_presses: a tuple of (keyval1, mod_mask1, keyval2, mod_mask2, ...)
+            the: regular gtk.Action parameters (defaults to None)
+        """
+        if name is None: name = label
+        gtk.Action.__init__(self,
+            name=name, label=label,
+            tooltip=tooltip, stock_id=stock_id,
+        )
+        #register this action
+        _all_actions_list.append(self)
+        for i in range(len(keypresses)/2):
+            keyval, mod_mask = keypresses[i*2:(i+1)*2]
+            #register this keypress
+            if _actions_keypress_dict.has_key((keyval, mod_mask)):
+                raise KeyError('keyval/mod_mask pair already registered "%s"'%str((keyval, mod_mask)))
+            _actions_keypress_dict[(keyval, mod_mask)] = self
+            #set the accelerator group, and accelerator path
+            #register the key name and mod mask with the accelerator path
+            if label is None: continue #dont register accel
+            accel_path = '<main>/'+self.get_name()
+            self.set_accel_group(get_accel_group())
+            self.set_accel_path(accel_path)
+            gtk.accel_map_add_entry(accel_path, keyval, mod_mask)
 
-	def __str__(self):
-		"""
-		The string representation should be the name of the action id.
-		Try to find the action id for this action by searching this module.
-		"""
-		try:
-			import Actions
-			return filter(lambda attr: getattr(Actions, attr) == self, dir(Actions))[0]
-		except: return self.get_name()
+    def __str__(self):
+        """
+        The string representation should be the name of the action id.
+        Try to find the action id for this action by searching this module.
+        """
+        try:
+            import Actions
+            return filter(lambda attr: getattr(Actions, attr) == self, dir(Actions))[0]
+        except: return self.get_name()
 
-	def __repr__(self): return str(self)
+    def __repr__(self): return str(self)
 
-	def __call__(self):
-		"""
-		Emit the activate signal when called with ().
-		"""
-		self.emit('activate')
+    def __call__(self):
+        """
+        Emit the activate signal when called with ().
+        """
+        self.emit('activate')
 
 ########################################################################
 # Actions
 ########################################################################
 PAGE_CHANGE = Action()
 FLOW_GRAPH_NEW = Action(
-	label='_New',
-	tooltip='Create a new flow graph',
-	stock_id=gtk.STOCK_NEW,
-	keypresses=(gtk.keysyms.n, gtk.gdk.CONTROL_MASK),
+    label='_New',
+    tooltip='Create a new flow graph',
+    stock_id=gtk.STOCK_NEW,
+    keypresses=(gtk.keysyms.n, gtk.gdk.CONTROL_MASK),
 )
 FLOW_GRAPH_OPEN = Action(
-	label='_Open',
-	tooltip='Open an existing flow graph',
-	stock_id=gtk.STOCK_OPEN,
-	keypresses=(gtk.keysyms.o, gtk.gdk.CONTROL_MASK),
+    label='_Open',
+    tooltip='Open an existing flow graph',
+    stock_id=gtk.STOCK_OPEN,
+    keypresses=(gtk.keysyms.o, gtk.gdk.CONTROL_MASK),
 )
 FLOW_GRAPH_SAVE = Action(
-	label='_Save',
-	tooltip='Save the current flow graph',
-	stock_id=gtk.STOCK_SAVE,
-	keypresses=(gtk.keysyms.s, gtk.gdk.CONTROL_MASK),
+    label='_Save',
+    tooltip='Save the current flow graph',
+    stock_id=gtk.STOCK_SAVE,
+    keypresses=(gtk.keysyms.s, gtk.gdk.CONTROL_MASK),
 )
 FLOW_GRAPH_SAVE_AS = Action(
-	label='Save _As',
-	tooltip='Save the current flow graph as...',
-	stock_id=gtk.STOCK_SAVE_AS,
-	keypresses=(gtk.keysyms.s, gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK),
+    label='Save _As',
+    tooltip='Save the current flow graph as...',
+    stock_id=gtk.STOCK_SAVE_AS,
+    keypresses=(gtk.keysyms.s, gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK),
 )
 FLOW_GRAPH_CLOSE = Action(
-	label='_Close',
-	tooltip='Close the current flow graph',
-	stock_id=gtk.STOCK_CLOSE,
-	keypresses=(gtk.keysyms.w, gtk.gdk.CONTROL_MASK),
+    label='_Close',
+    tooltip='Close the current flow graph',
+    stock_id=gtk.STOCK_CLOSE,
+    keypresses=(gtk.keysyms.w, gtk.gdk.CONTROL_MASK),
 )
 APPLICATION_INITIALIZE = Action()
 APPLICATION_QUIT = Action(
-	label='_Quit',
-	tooltip='Quit program',
-	stock_id=gtk.STOCK_QUIT,
-	keypresses=(gtk.keysyms.q, gtk.gdk.CONTROL_MASK),
+    label='_Quit',
+    tooltip='Quit program',
+    stock_id=gtk.STOCK_QUIT,
+    keypresses=(gtk.keysyms.q, gtk.gdk.CONTROL_MASK),
 )
 FLOW_GRAPH_UNDO = Action(
-	label='_Undo',
-	tooltip='Undo a change to the flow graph',
-	stock_id=gtk.STOCK_UNDO,
-	keypresses=(gtk.keysyms.z, gtk.gdk.CONTROL_MASK),
+    label='_Undo',
+    tooltip='Undo a change to the flow graph',
+    stock_id=gtk.STOCK_UNDO,
+    keypresses=(gtk.keysyms.z, gtk.gdk.CONTROL_MASK),
 )
 FLOW_GRAPH_REDO = Action(
-	label='_Redo',
-	tooltip='Redo a change to the flow graph',
-	stock_id=gtk.STOCK_REDO,
-	keypresses=(gtk.keysyms.y, gtk.gdk.CONTROL_MASK),
+    label='_Redo',
+    tooltip='Redo a change to the flow graph',
+    stock_id=gtk.STOCK_REDO,
+    keypresses=(gtk.keysyms.y, gtk.gdk.CONTROL_MASK),
 )
 NOTHING_SELECT = Action()
 ELEMENT_SELECT = Action()
 ELEMENT_CREATE = Action()
 ELEMENT_DELETE = Action(
-	label='_Delete',
-	tooltip='Delete the selected blocks',
-	stock_id=gtk.STOCK_DELETE,
-	keypresses=(gtk.keysyms.Delete, NO_MODS_MASK),
+    label='_Delete',
+    tooltip='Delete the selected blocks',
+    stock_id=gtk.STOCK_DELETE,
+    keypresses=(gtk.keysyms.Delete, NO_MODS_MASK),
 )
 BLOCK_MOVE = Action()
 BLOCK_ROTATE_CCW = Action(
-	label='Rotate Counterclockwise',
-	tooltip='Rotate the selected blocks 90 degrees to the left',
-	stock_id=gtk.STOCK_GO_BACK,
-	keypresses=(gtk.keysyms.Left, NO_MODS_MASK),
+    label='Rotate Counterclockwise',
+    tooltip='Rotate the selected blocks 90 degrees to the left',
+    stock_id=gtk.STOCK_GO_BACK,
+    keypresses=(gtk.keysyms.Left, NO_MODS_MASK),
 )
 BLOCK_ROTATE_CW = Action(
-	label='Rotate Clockwise',
-	tooltip='Rotate the selected blocks 90 degrees to the right',
-	stock_id=gtk.STOCK_GO_FORWARD,
-	keypresses=(gtk.keysyms.Right, NO_MODS_MASK),
+    label='Rotate Clockwise',
+    tooltip='Rotate the selected blocks 90 degrees to the right',
+    stock_id=gtk.STOCK_GO_FORWARD,
+    keypresses=(gtk.keysyms.Right, NO_MODS_MASK),
 )
 BLOCK_PARAM_MODIFY = Action(
-	label='_Properties',
-	tooltip='Modify params for the selected block',
-	stock_id=gtk.STOCK_PROPERTIES,
-	keypresses=(gtk.keysyms.Return, NO_MODS_MASK),
+    label='_Properties',
+    tooltip='Modify params for the selected block',
+    stock_id=gtk.STOCK_PROPERTIES,
+    keypresses=(gtk.keysyms.Return, NO_MODS_MASK),
 )
 BLOCK_ENABLE = Action(
-	label='E_nable',
-	tooltip='Enable the selected blocks',
-	stock_id=gtk.STOCK_CONNECT,
-	keypresses=(gtk.keysyms.e, NO_MODS_MASK),
+    label='E_nable',
+    tooltip='Enable the selected blocks',
+    stock_id=gtk.STOCK_CONNECT,
+    keypresses=(gtk.keysyms.e, NO_MODS_MASK),
 )
 BLOCK_DISABLE = Action(
-	label='D_isable',
-	tooltip='Disable the selected blocks',
-	stock_id=gtk.STOCK_DISCONNECT,
-	keypresses=(gtk.keysyms.d, NO_MODS_MASK),
+    label='D_isable',
+    tooltip='Disable the selected blocks',
+    stock_id=gtk.STOCK_DISCONNECT,
+    keypresses=(gtk.keysyms.d, NO_MODS_MASK),
 )
 BLOCK_CREATE_HIER = Action(
-	label='C_reate Hier',
-	tooltip='Create hier block from selected blocks',
-	stock_id=gtk.STOCK_CONNECT,
-#	keypresses=(gtk.keysyms.c, NO_MODS_MASK),
+    label='C_reate Hier',
+    tooltip='Create hier block from selected blocks',
+    stock_id=gtk.STOCK_CONNECT,
+#   keypresses=(gtk.keysyms.c, NO_MODS_MASK),
 )
 BLOCK_CUT = Action(
-	label='Cu_t',
-	tooltip='Cut',
-	stock_id=gtk.STOCK_CUT,
-	keypresses=(gtk.keysyms.x, gtk.gdk.CONTROL_MASK),
+    label='Cu_t',
+    tooltip='Cut',
+    stock_id=gtk.STOCK_CUT,
+    keypresses=(gtk.keysyms.x, gtk.gdk.CONTROL_MASK),
 )
 BLOCK_COPY = Action(
-	label='_Copy',
-	tooltip='Copy',
-	stock_id=gtk.STOCK_COPY,
-	keypresses=(gtk.keysyms.c, gtk.gdk.CONTROL_MASK),
+    label='_Copy',
+    tooltip='Copy',
+    stock_id=gtk.STOCK_COPY,
+    keypresses=(gtk.keysyms.c, gtk.gdk.CONTROL_MASK),
 )
 BLOCK_PASTE = Action(
-	label='_Paste',
-	tooltip='Paste',
-	stock_id=gtk.STOCK_PASTE,
-	keypresses=(gtk.keysyms.v, gtk.gdk.CONTROL_MASK),
+    label='_Paste',
+    tooltip='Paste',
+    stock_id=gtk.STOCK_PASTE,
+    keypresses=(gtk.keysyms.v, gtk.gdk.CONTROL_MASK),
 )
 ERRORS_WINDOW_DISPLAY = Action(
-	label='_Errors',
-	tooltip='View flow graph errors',
-	stock_id=gtk.STOCK_DIALOG_ERROR,
+    label='_Errors',
+    tooltip='View flow graph errors',
+    stock_id=gtk.STOCK_DIALOG_ERROR,
 )
 ABOUT_WINDOW_DISPLAY = Action(
-	label='_About',
-	tooltip='About this program',
-	stock_id=gtk.STOCK_ABOUT,
+    label='_About',
+    tooltip='About this program',
+    stock_id=gtk.STOCK_ABOUT,
 )
 HELP_WINDOW_DISPLAY = Action(
-	label='_Help',
-	tooltip='Usage tips',
-	stock_id=gtk.STOCK_HELP,
-	keypresses=(gtk.keysyms.F1, NO_MODS_MASK),
+    label='_Help',
+    tooltip='Usage tips',
+    stock_id=gtk.STOCK_HELP,
+    keypresses=(gtk.keysyms.F1, NO_MODS_MASK),
 )
 TYPES_WINDOW_DISPLAY = Action(
-	label='_Types',
-	tooltip='Types color mapping',
-	stock_id=gtk.STOCK_DIALOG_INFO,
+    label='_Types',
+    tooltip='Types color mapping',
+    stock_id=gtk.STOCK_DIALOG_INFO,
 )
 FLOW_GRAPH_GEN = Action(
-	label='_Generate',
-	tooltip='Generate the flow graph',
-	stock_id=gtk.STOCK_CONVERT,
-	keypresses=(gtk.keysyms.F5, NO_MODS_MASK),
+    label='_Generate',
+    tooltip='Generate the flow graph',
+    stock_id=gtk.STOCK_CONVERT,
+    keypresses=(gtk.keysyms.F5, NO_MODS_MASK),
 )
 FLOW_GRAPH_EXEC = Action(
-	label='_Execute',
-	tooltip='Execute the flow graph',
-	stock_id=gtk.STOCK_EXECUTE,
-	keypresses=(gtk.keysyms.F6, NO_MODS_MASK),
+    label='_Execute',
+    tooltip='Execute the flow graph',
+    stock_id=gtk.STOCK_EXECUTE,
+    keypresses=(gtk.keysyms.F6, NO_MODS_MASK),
 )
 FLOW_GRAPH_KILL = Action(
-	label='_Kill',
-	tooltip='Kill the flow graph',
-	stock_id=gtk.STOCK_STOP,
-	keypresses=(gtk.keysyms.F7, NO_MODS_MASK),
+    label='_Kill',
+    tooltip='Kill the flow graph',
+    stock_id=gtk.STOCK_STOP,
+    keypresses=(gtk.keysyms.F7, NO_MODS_MASK),
 )
 FLOW_GRAPH_SCREEN_CAPTURE = Action(
-	label='S_creen Capture',
-	tooltip='Create a screen capture of the flow graph',
-	stock_id=gtk.STOCK_PRINT,
-	keypresses=(gtk.keysyms.Print, NO_MODS_MASK),
+    label='S_creen Capture',
+    tooltip='Create a screen capture of the flow graph',
+    stock_id=gtk.STOCK_PRINT,
+    keypresses=(gtk.keysyms.Print, NO_MODS_MASK),
 )
 PORT_CONTROLLER_DEC = Action(
-	keypresses=(gtk.keysyms.minus, NO_MODS_MASK, gtk.keysyms.KP_Subtract, NO_MODS_MASK),
+    keypresses=(gtk.keysyms.minus, NO_MODS_MASK, gtk.keysyms.KP_Subtract, NO_MODS_MASK),
 )
 PORT_CONTROLLER_INC = Action(
-	keypresses=(gtk.keysyms.plus, NO_MODS_MASK, gtk.keysyms.KP_Add, NO_MODS_MASK),
+    keypresses=(gtk.keysyms.plus, NO_MODS_MASK, gtk.keysyms.KP_Add, NO_MODS_MASK),
 )
 BLOCK_INC_TYPE = Action(
-	keypresses=(gtk.keysyms.Down, NO_MODS_MASK),
+    keypresses=(gtk.keysyms.Down, NO_MODS_MASK),
 )
 BLOCK_DEC_TYPE = Action(
-	keypresses=(gtk.keysyms.Up, NO_MODS_MASK),
+    keypresses=(gtk.keysyms.Up, NO_MODS_MASK),
 )
 RELOAD_BLOCKS = Action(
-	label='Reload _Blocks',
-	tooltip='Reload Blocks',
-	stock_id=gtk.STOCK_REFRESH
+    label='Reload _Blocks',
+    tooltip='Reload Blocks',
+    stock_id=gtk.STOCK_REFRESH
 )
 OPEN_HIER = Action(
-	label='Open H_ier',
-	tooltip='Open the source of the selected hierarchical block',
-	stock_id=gtk.STOCK_JUMP_TO,
+    label='Open H_ier',
+    tooltip='Open the source of the selected hierarchical block',
+    stock_id=gtk.STOCK_JUMP_TO,
 )
 BUSSIFY_SOURCES = Action(
-	label='Toggle So_urce Bus',
-	tooltip='Gang source ports into a single bus port',
-	stock_id=gtk.STOCK_JUMP_TO,
+    label='Toggle So_urce Bus',
+    tooltip='Gang source ports into a single bus port',
+    stock_id=gtk.STOCK_JUMP_TO,
 )
 BUSSIFY_SINKS = Action(
-	label='Toggle S_ink Bus',
-	tooltip='Gang sink ports into a single bus port',
-	stock_id=gtk.STOCK_JUMP_TO,
+    label='Toggle S_ink Bus',
+    tooltip='Gang sink ports into a single bus port',
+    stock_id=gtk.STOCK_JUMP_TO,
 )
diff --git a/grc/gui/Bars.py b/grc/gui/Bars.py
index 770e705ffc..e2b7f4f9bc 100644
--- a/grc/gui/Bars.py
+++ b/grc/gui/Bars.py
@@ -24,31 +24,31 @@ import gtk
 
 ##The list of actions for the toolbar.
 TOOLBAR_LIST = (
-	Actions.FLOW_GRAPH_NEW,
-	Actions.FLOW_GRAPH_OPEN,
-	Actions.FLOW_GRAPH_SAVE,
-	Actions.FLOW_GRAPH_CLOSE,
-	None,
-	Actions.FLOW_GRAPH_SCREEN_CAPTURE,
-	None,
-	Actions.BLOCK_CUT,
-	Actions.BLOCK_COPY,
-	Actions.BLOCK_PASTE,
-	Actions.ELEMENT_DELETE,
-	None,
-	Actions.FLOW_GRAPH_UNDO,
-	Actions.FLOW_GRAPH_REDO,
-	None,
-	Actions.ERRORS_WINDOW_DISPLAY,
-	Actions.FLOW_GRAPH_GEN,
-	Actions.FLOW_GRAPH_EXEC,
-	Actions.FLOW_GRAPH_KILL,
-	None,
-	Actions.BLOCK_ROTATE_CCW,
-	Actions.BLOCK_ROTATE_CW,
-	None,
-	Actions.BLOCK_ENABLE,
-	Actions.BLOCK_DISABLE,
+    Actions.FLOW_GRAPH_NEW,
+    Actions.FLOW_GRAPH_OPEN,
+    Actions.FLOW_GRAPH_SAVE,
+    Actions.FLOW_GRAPH_CLOSE,
+    None,
+    Actions.FLOW_GRAPH_SCREEN_CAPTURE,
+    None,
+    Actions.BLOCK_CUT,
+    Actions.BLOCK_COPY,
+    Actions.BLOCK_PASTE,
+    Actions.ELEMENT_DELETE,
+    None,
+    Actions.FLOW_GRAPH_UNDO,
+    Actions.FLOW_GRAPH_REDO,
+    None,
+    Actions.ERRORS_WINDOW_DISPLAY,
+    Actions.FLOW_GRAPH_GEN,
+    Actions.FLOW_GRAPH_EXEC,
+    Actions.FLOW_GRAPH_KILL,
+    None,
+    Actions.BLOCK_ROTATE_CCW,
+    Actions.BLOCK_ROTATE_CW,
+    None,
+    Actions.BLOCK_ENABLE,
+    Actions.BLOCK_DISABLE,
     None,
     Actions.RELOAD_BLOCKS,
     Actions.OPEN_HIER,
@@ -57,88 +57,88 @@ TOOLBAR_LIST = (
 
 ##The list of actions and categories for the menu bar.
 MENU_BAR_LIST = (
-	(gtk.Action('File', '_File', None, None), [
-		Actions.FLOW_GRAPH_NEW,
-		Actions.FLOW_GRAPH_OPEN,
-		None,
-		Actions.FLOW_GRAPH_SAVE,
-		Actions.FLOW_GRAPH_SAVE_AS,
-		None,
-		Actions.FLOW_GRAPH_SCREEN_CAPTURE,
-		None,
-		Actions.FLOW_GRAPH_CLOSE,
-		Actions.APPLICATION_QUIT,
-	]),
-	(gtk.Action('Edit', '_Edit', None, None), [
-		Actions.FLOW_GRAPH_UNDO,
-		Actions.FLOW_GRAPH_REDO,
-		None,
-		Actions.BLOCK_CUT,
-		Actions.BLOCK_COPY,
-		Actions.BLOCK_PASTE,
-		Actions.ELEMENT_DELETE,
-		None,
-		Actions.BLOCK_ROTATE_CCW,
-		Actions.BLOCK_ROTATE_CW,
-		None,
-		Actions.BLOCK_ENABLE,
-		Actions.BLOCK_DISABLE,
-		None,
-		Actions.BLOCK_PARAM_MODIFY,
-	]),
-	(gtk.Action('View', '_View', None, None), [
-		Actions.ERRORS_WINDOW_DISPLAY,
-	]),
-	(gtk.Action('Build', '_Build', None, None), [
-		Actions.FLOW_GRAPH_GEN,
-		Actions.FLOW_GRAPH_EXEC,
-		Actions.FLOW_GRAPH_KILL,
-	]),
-	(gtk.Action('Help', '_Help', None, None), [
-		Actions.HELP_WINDOW_DISPLAY,
-		Actions.TYPES_WINDOW_DISPLAY,
-		None,
-		Actions.ABOUT_WINDOW_DISPLAY,
-	]),
+    (gtk.Action('File', '_File', None, None), [
+        Actions.FLOW_GRAPH_NEW,
+        Actions.FLOW_GRAPH_OPEN,
+        None,
+        Actions.FLOW_GRAPH_SAVE,
+        Actions.FLOW_GRAPH_SAVE_AS,
+        None,
+        Actions.FLOW_GRAPH_SCREEN_CAPTURE,
+        None,
+        Actions.FLOW_GRAPH_CLOSE,
+        Actions.APPLICATION_QUIT,
+    ]),
+    (gtk.Action('Edit', '_Edit', None, None), [
+        Actions.FLOW_GRAPH_UNDO,
+        Actions.FLOW_GRAPH_REDO,
+        None,
+        Actions.BLOCK_CUT,
+        Actions.BLOCK_COPY,
+        Actions.BLOCK_PASTE,
+        Actions.ELEMENT_DELETE,
+        None,
+        Actions.BLOCK_ROTATE_CCW,
+        Actions.BLOCK_ROTATE_CW,
+        None,
+        Actions.BLOCK_ENABLE,
+        Actions.BLOCK_DISABLE,
+        None,
+        Actions.BLOCK_PARAM_MODIFY,
+    ]),
+    (gtk.Action('View', '_View', None, None), [
+        Actions.ERRORS_WINDOW_DISPLAY,
+    ]),
+    (gtk.Action('Build', '_Build', None, None), [
+        Actions.FLOW_GRAPH_GEN,
+        Actions.FLOW_GRAPH_EXEC,
+        Actions.FLOW_GRAPH_KILL,
+    ]),
+    (gtk.Action('Help', '_Help', None, None), [
+        Actions.HELP_WINDOW_DISPLAY,
+        Actions.TYPES_WINDOW_DISPLAY,
+        None,
+        Actions.ABOUT_WINDOW_DISPLAY,
+    ]),
 )
 
 class Toolbar(gtk.Toolbar):
-	"""The 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.
-		"""
-		gtk.Toolbar.__init__(self)
-		self.set_style(gtk.TOOLBAR_ICONS)
-		for action in TOOLBAR_LIST:
-			if action: #add a tool item
-				self.add(action.create_tool_item())
-				#this reset of the tooltip property is required (after creating the tool item) for the tooltip to show
-				action.set_property('tooltip', action.get_property('tooltip'))
-			else: self.add(gtk.SeparatorToolItem())
+    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.
+        """
+        gtk.Toolbar.__init__(self)
+        self.set_style(gtk.TOOLBAR_ICONS)
+        for action in TOOLBAR_LIST:
+            if action: #add a tool item
+                self.add(action.create_tool_item())
+                #this reset of the tooltip property is required (after creating the tool item) for the tooltip to show
+                action.set_property('tooltip', action.get_property('tooltip'))
+            else: self.add(gtk.SeparatorToolItem())
 
 class MenuBar(gtk.MenuBar):
-	"""The gtk menu bar with actions added from the menu bar 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 menu bar.
-		"""
-		gtk.MenuBar.__init__(self)
-		for main_action, actions in MENU_BAR_LIST:
-			#create the main menu item
-			main_menu_item = main_action.create_menu_item()
-			self.append(main_menu_item)
-			#create the menu
-			main_menu = gtk.Menu()
-			main_menu_item.set_submenu(main_menu)
-			for action in actions:
-				if action: #append a menu item
-					main_menu.append(action.create_menu_item())
-				else: main_menu.append(gtk.SeparatorMenuItem())
-			main_menu.show_all() #this show all is required for the separators to show
+    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 menu bar.
+        """
+        gtk.MenuBar.__init__(self)
+        for main_action, actions in MENU_BAR_LIST:
+            #create the main menu item
+            main_menu_item = main_action.create_menu_item()
+            self.append(main_menu_item)
+            #create the menu
+            main_menu = gtk.Menu()
+            main_menu_item.set_submenu(main_menu)
+            for action in actions:
+                if action: #append a menu item
+                    main_menu.append(action.create_menu_item())
+                else: main_menu.append(gtk.SeparatorMenuItem())
+            main_menu.show_all() #this show all is required for the separators to show
diff --git a/grc/gui/Block.py b/grc/gui/Block.py
index e69fe1a418..30031866c0 100644
--- a/grc/gui/Block.py
+++ b/grc/gui/Block.py
@@ -23,9 +23,9 @@ import Colors
 from .. base import odict
 from Constants import BORDER_PROXIMITY_SENSITIVITY
 from Constants import \
-	BLOCK_LABEL_PADDING, \
-	PORT_SEPARATION, LABEL_SEPARATION, \
-	PORT_BORDER_SEPARATION, POSSIBLE_ROTATIONS
+    BLOCK_LABEL_PADDING, \
+    PORT_SEPARATION, LABEL_SEPARATION, \
+    PORT_BORDER_SEPARATION, POSSIBLE_ROTATIONS
 import pygtk
 pygtk.require('2.0')
 import gtk
@@ -36,187 +36,184 @@ BLOCK_MARKUP_TMPL="""\
 <span foreground="$foreground" font_desc="Sans 8"><b>$encode($block.get_name())</b></span>"""
 
 class Block(Element):
-	"""The graphical signal block."""
+    """The graphical signal block."""
 
-	def __init__(self):
-		"""
-		Block contructor.
-		Add graphics related params to the block.
-		"""
-		#add the position param
-		self.get_params().append(self.get_parent().get_parent().Param(
-			block=self,
-			n=odict({
-				'name': 'GUI Coordinate',
-				'key': '_coordinate',
-				'type': 'raw',
-				'value': '(0, 0)',
-				'hide': 'all',
-			})
-		))
-		self.get_params().append(self.get_parent().get_parent().Param(
-			block=self,
-			n=odict({
-				'name': 'GUI Rotation',
-				'key': '_rotation',
-				'type': 'raw',
-				'value': '0',
-				'hide': 'all',
-			})
-		))
-		Element.__init__(self)
+    def __init__(self):
+        """
+        Block contructor.
+        Add graphics related params to the block.
+        """
+        #add the position param
+        self.get_params().append(self.get_parent().get_parent().Param(
+            block=self,
+            n=odict({
+                'name': 'GUI Coordinate',
+                'key': '_coordinate',
+                'type': 'raw',
+                'value': '(0, 0)',
+                'hide': 'all',
+            })
+        ))
+        self.get_params().append(self.get_parent().get_parent().Param(
+            block=self,
+            n=odict({
+                'name': 'GUI Rotation',
+                'key': '_rotation',
+                'type': 'raw',
+                'value': '0',
+                'hide': 'all',
+            })
+        ))
+        Element.__init__(self)
 
-	def get_coordinate(self):
-		"""
-		Get the coordinate from the position param.
-		
-		Returns:
-		    the coordinate tuple (x, y) or (0, 0) if failure
-		"""
-		try: #should evaluate to tuple
-			coor = eval(self.get_param('_coordinate').get_value())
-			x, y = map(int, coor)
-			fgW,fgH = self.get_parent().get_size()
-			if x <= 0:
-				x = 0
-			elif x >= fgW - BORDER_PROXIMITY_SENSITIVITY:
-				x = fgW - BORDER_PROXIMITY_SENSITIVITY
-			if y <= 0:
-				y = 0
-			elif y >= fgH - BORDER_PROXIMITY_SENSITIVITY:
-				y = fgH - BORDER_PROXIMITY_SENSITIVITY
-			return (x, y)
-		except:
-			self.set_coordinate((0, 0))
-			return (0, 0)
+    def get_coordinate(self):
+        """
+        Get the coordinate from the position param.
+        
+        Returns:
+            the coordinate tuple (x, y) or (0, 0) if failure
+        """
+        try: #should evaluate to tuple
+            coor = eval(self.get_param('_coordinate').get_value())
+            x, y = map(int, coor)
+            fgW,fgH = self.get_parent().get_size()
+            if x <= 0:
+                x = 0
+            elif x >= fgW - BORDER_PROXIMITY_SENSITIVITY:
+                x = fgW - BORDER_PROXIMITY_SENSITIVITY
+            if y <= 0:
+                y = 0
+            elif y >= fgH - BORDER_PROXIMITY_SENSITIVITY:
+                y = fgH - BORDER_PROXIMITY_SENSITIVITY
+            return (x, y)
+        except:
+            self.set_coordinate((0, 0))
+            return (0, 0)
 
-	def set_coordinate(self, coor):
-		"""
-		Set the coordinate into the position param.
-		
-		Args:
-		    coor: the coordinate tuple (x, y)
-		"""
-		self.get_param('_coordinate').set_value(str(coor))
+    def set_coordinate(self, coor):
+        """
+        Set the coordinate into the position param.
+        
+        Args:
+            coor: the coordinate tuple (x, y)
+        """
+        self.get_param('_coordinate').set_value(str(coor))
 
-	def get_rotation(self):
-		"""
-		Get the rotation from the position param.
-		
-		Returns:
-		    the rotation in degrees or 0 if failure
-		"""
-		try: #should evaluate to dict
-			rotation = eval(self.get_param('_rotation').get_value())
-			return int(rotation)
-		except:
-			self.set_rotation(POSSIBLE_ROTATIONS[0])
-			return POSSIBLE_ROTATIONS[0]
+    def get_rotation(self):
+        """
+        Get the rotation from the position param.
+        
+        Returns:
+            the rotation in degrees or 0 if failure
+        """
+        try: #should evaluate to dict
+            rotation = eval(self.get_param('_rotation').get_value())
+            return int(rotation)
+        except:
+            self.set_rotation(POSSIBLE_ROTATIONS[0])
+            return POSSIBLE_ROTATIONS[0]
 
-	def set_rotation(self, rot):
-		"""
-		Set the rotation into the position param.
-		
-		Args:
-		    rot: the rotation in degrees
-		"""
-		self.get_param('_rotation').set_value(str(rot))
+    def set_rotation(self, rot):
+        """
+        Set the rotation into the position param.
+        
+        Args:
+            rot: the rotation in degrees
+        """
+        self.get_param('_rotation').set_value(str(rot))
 
-	def create_shapes(self):
-		"""Update the block, parameters, and ports when a change occurs."""
-		
-		Element.create_shapes(self)
-		if self.is_horizontal(): self.add_area((0, 0), (self.W, self.H))
-		elif self.is_vertical(): self.add_area((0, 0), (self.H, self.W))
+    def create_shapes(self):
+        """Update the block, parameters, and ports when a change occurs."""
+        Element.create_shapes(self)
+        if self.is_horizontal(): self.add_area((0, 0), (self.W, self.H))
+        elif self.is_vertical(): self.add_area((0, 0), (self.H, self.W))
 
-	def create_labels(self):
-		"""Create the labels for the signal block."""
-		Element.create_labels(self)
-		self._bg_color = self.get_enabled() and Colors.BLOCK_ENABLED_COLOR or Colors.BLOCK_DISABLED_COLOR
-		layouts = list()
-		#create the main layout
-		layout = gtk.DrawingArea().create_pango_layout('')
-		layouts.append(layout)
-		layout.set_markup(Utils.parse_template(BLOCK_MARKUP_TMPL, block=self))
-		self.label_width, self.label_height = layout.get_pixel_size()
-		#display the params
-		markups = [param.get_markup() for param in self.get_params() if param.get_hide() not in ('all', 'part')]
-		if markups:
-			layout = gtk.DrawingArea().create_pango_layout('')
-			layout.set_spacing(LABEL_SEPARATION*pango.SCALE)
-			layout.set_markup('\n'.join(markups))
-			layouts.append(layout)
-			w,h = layout.get_pixel_size()
-			self.label_width = max(w, self.label_width)
-			self.label_height += h + LABEL_SEPARATION
-		width = self.label_width
-		height = self.label_height
-		#setup the pixmap
-		pixmap = self.get_parent().new_pixmap(width, height)
-		gc = pixmap.new_gc()
-		gc.set_foreground(self._bg_color)
-		pixmap.draw_rectangle(gc, True, 0, 0, width, height)
-		#draw the layouts
-		h_off = 0
-		for i,layout in enumerate(layouts):
-			w,h = layout.get_pixel_size()
-			if i == 0: w_off = (width-w)/2
-			else: w_off = 0
-			pixmap.draw_layout(gc, w_off, h_off, layout)
-			h_off = h + h_off + LABEL_SEPARATION
-		#create vertical and horizontal pixmaps
-		self.horizontal_label = pixmap
-		if self.is_vertical():
-			self.vertical_label = self.get_parent().new_pixmap(height, width)
-			Utils.rotate_pixmap(gc, self.horizontal_label, self.vertical_label)
-		#calculate width and height needed
-		self.W = self.label_width + 2*BLOCK_LABEL_PADDING
-		self.H = max(*(
-			[self.label_height+2*BLOCK_LABEL_PADDING] + [2*PORT_BORDER_SEPARATION + \
-			sum([port.H + PORT_SEPARATION for port in ports]) - PORT_SEPARATION
-			for ports in (self.get_sources_gui(), self.get_sinks_gui())] + 
-			[4*PORT_BORDER_SEPARATION + \
-			sum([(port.H) + PORT_SEPARATION for port in ports]) - PORT_SEPARATION
-			for ports in ([i for i in self.get_sources_gui() if i.get_type() == 'bus'], [i for i in self.get_sinks_gui() if i.get_type() == 'bus'])]
-		))
+    def create_labels(self):
+        """Create the labels for the signal block."""
+        Element.create_labels(self)
+        self._bg_color = self.get_enabled() and Colors.BLOCK_ENABLED_COLOR or Colors.BLOCK_DISABLED_COLOR
+        layouts = list()
+        #create the main layout
+        layout = gtk.DrawingArea().create_pango_layout('')
+        layouts.append(layout)
+        layout.set_markup(Utils.parse_template(BLOCK_MARKUP_TMPL, block=self))
+        self.label_width, self.label_height = layout.get_pixel_size()
+        #display the params
+        markups = [param.get_markup() for param in self.get_params() if param.get_hide() not in ('all', 'part')]
+        if markups:
+            layout = gtk.DrawingArea().create_pango_layout('')
+            layout.set_spacing(LABEL_SEPARATION*pango.SCALE)
+            layout.set_markup('\n'.join(markups))
+            layouts.append(layout)
+            w,h = layout.get_pixel_size()
+            self.label_width = max(w, self.label_width)
+            self.label_height += h + LABEL_SEPARATION
+        width = self.label_width
+        height = self.label_height
+        #setup the pixmap
+        pixmap = self.get_parent().new_pixmap(width, height)
+        gc = pixmap.new_gc()
+        gc.set_foreground(self._bg_color)
+        pixmap.draw_rectangle(gc, True, 0, 0, width, height)
+        #draw the layouts
+        h_off = 0
+        for i,layout in enumerate(layouts):
+            w,h = layout.get_pixel_size()
+            if i == 0: w_off = (width-w)/2
+            else: w_off = 0
+            pixmap.draw_layout(gc, w_off, h_off, layout)
+            h_off = h + h_off + LABEL_SEPARATION
+        #create vertical and horizontal pixmaps
+        self.horizontal_label = pixmap
+        if self.is_vertical():
+            self.vertical_label = self.get_parent().new_pixmap(height, width)
+            Utils.rotate_pixmap(gc, self.horizontal_label, self.vertical_label)
+        #calculate width and height needed
+        self.W = self.label_width + 2*BLOCK_LABEL_PADDING
+        self.H = max(*(
+            [self.label_height+2*BLOCK_LABEL_PADDING] + [2*PORT_BORDER_SEPARATION + \
+            sum([port.H + PORT_SEPARATION for port in ports]) - PORT_SEPARATION
+            for ports in (self.get_sources_gui(), self.get_sinks_gui())] + 
+            [4*PORT_BORDER_SEPARATION + \
+            sum([(port.H) + PORT_SEPARATION for port in ports]) - PORT_SEPARATION
+            for ports in ([i for i in self.get_sources_gui() if i.get_type() == 'bus'], [i for i in self.get_sinks_gui() if i.get_type() == 'bus'])]
+        ))
 
-	def draw(self, gc, window):
-		"""
-		Draw the signal block with label and inputs/outputs.
-		
-		Args:
-		    gc: the graphics context
-		    window: the gtk window to draw on
-		"""
-		x, y = self.get_coordinate()
-		#draw main block
-		Element.draw(
-			self, gc, window, bg_color=self._bg_color,
-			border_color=self.is_highlighted() and Colors.HIGHLIGHT_COLOR or Colors.BORDER_COLOR,
-		)
-		#draw label image
-		if self.is_horizontal():
-			window.draw_drawable(gc, self.horizontal_label, 0, 0, x+BLOCK_LABEL_PADDING, y+(self.H-self.label_height)/2, -1, -1)
-		elif self.is_vertical():
-			window.draw_drawable(gc, self.vertical_label, 0, 0, x+(self.H-self.label_height)/2, y+BLOCK_LABEL_PADDING, -1, -1)
-		#draw ports
-		
-		
-		for port in self.get_ports_gui():
-			port.draw(gc, window)
+    def draw(self, gc, window):
+        """
+        Draw the signal block with label and inputs/outputs.
+        
+        Args:
+            gc: the graphics context
+            window: the gtk window to draw on
+        """
+        x, y = self.get_coordinate()
+        #draw main block
+        Element.draw(
+            self, gc, window, bg_color=self._bg_color,
+            border_color=self.is_highlighted() and Colors.HIGHLIGHT_COLOR or Colors.BORDER_COLOR,
+        )
+        #draw label image
+        if self.is_horizontal():
+            window.draw_drawable(gc, self.horizontal_label, 0, 0, x+BLOCK_LABEL_PADDING, y+(self.H-self.label_height)/2, -1, -1)
+        elif self.is_vertical():
+            window.draw_drawable(gc, self.vertical_label, 0, 0, x+(self.H-self.label_height)/2, y+BLOCK_LABEL_PADDING, -1, -1)
+        #draw ports
+        for port in self.get_ports_gui():
+            port.draw(gc, window)
 
-	def what_is_selected(self, coor, coor_m=None):
-		"""
-		Get the element that is selected.
-		
-		Args:
-		    coor: the (x,y) tuple
-		    coor_m: the (x_m, y_m) tuple
-		
-		Returns:
-		    this block, a port, or None
-		"""
-		for port in self.get_ports_gui():
-			port_selected = port.what_is_selected(coor, coor_m)
-			if port_selected: return port_selected
-		return Element.what_is_selected(self, coor, coor_m)
+    def what_is_selected(self, coor, coor_m=None):
+        """
+        Get the element that is selected.
+        
+        Args:
+            coor: the (x,y) tuple
+            coor_m: the (x_m, y_m) tuple
+        
+        Returns:
+            this block, a port, or None
+        """
+        for port in self.get_ports_gui():
+            port_selected = port.what_is_selected(coor, coor_m)
+            if port_selected: return port_selected
+        return Element.what_is_selected(self, coor, coor_m)
diff --git a/grc/gui/BlockTreeWindow.py b/grc/gui/BlockTreeWindow.py
index 28867dce7c..7d52f730ed 100644
--- a/grc/gui/BlockTreeWindow.py
+++ b/grc/gui/BlockTreeWindow.py
@@ -38,172 +38,172 @@ undocumented#slurp
 CAT_MARKUP_TMPL="""Category: $cat"""
 
 class BlockTreeWindow(gtk.VBox):
-	"""The block selection panel."""
-
-	def __init__(self, platform, get_flow_graph):
-		"""
-		BlockTreeWindow constructor.
-		Create a tree view of the possible blocks in the platform.
-		The tree view nodes will be category names, the leaves will be block names.
-		A mouse double click or button press action will trigger the add block event.
-		
-		Args:
-		    platform: the particular platform will all block prototypes
-		    get_flow_graph: get the selected flow graph
-		"""
-		gtk.VBox.__init__(self)
-		self.platform = platform
-		self.get_flow_graph = get_flow_graph
-		#make the tree model for holding blocks
-		self.treestore = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING)
-		self.treeview = gtk.TreeView(self.treestore)
-		self.treeview.set_enable_search(False) #disable pop up search box
-		self.treeview.add_events(gtk.gdk.BUTTON_PRESS_MASK)
-		self.treeview.connect('button-press-event', self._handle_mouse_button_press)
-		selection = self.treeview.get_selection()
-		selection.set_mode('single')
-		selection.connect('changed', self._handle_selection_change)
-		renderer = gtk.CellRendererText()
-		column = gtk.TreeViewColumn('Blocks', renderer, text=NAME_INDEX)
-		self.treeview.append_column(column)
-		#setup the search
-		self.treeview.set_enable_search(True)
-		self.treeview.set_search_equal_func(self._handle_search)
-		#try to enable the tooltips (available in pygtk 2.12 and above)
-		try: self.treeview.set_tooltip_column(DOC_INDEX)
-		except: pass
+    """The block selection panel."""
+
+    def __init__(self, platform, get_flow_graph):
+        """
+        BlockTreeWindow constructor.
+        Create a tree view of the possible blocks in the platform.
+        The tree view nodes will be category names, the leaves will be block names.
+        A mouse double click or button press action will trigger the add block event.
+        
+        Args:
+            platform: the particular platform will all block prototypes
+            get_flow_graph: get the selected flow graph
+        """
+        gtk.VBox.__init__(self)
+        self.platform = platform
+        self.get_flow_graph = get_flow_graph
+        #make the tree model for holding blocks
+        self.treestore = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING)
+        self.treeview = gtk.TreeView(self.treestore)
+        self.treeview.set_enable_search(False) #disable pop up search box
+        self.treeview.add_events(gtk.gdk.BUTTON_PRESS_MASK)
+        self.treeview.connect('button-press-event', self._handle_mouse_button_press)
+        selection = self.treeview.get_selection()
+        selection.set_mode('single')
+        selection.connect('changed', self._handle_selection_change)
+        renderer = gtk.CellRendererText()
+        column = gtk.TreeViewColumn('Blocks', renderer, text=NAME_INDEX)
+        self.treeview.append_column(column)
+        #setup the search
+        self.treeview.set_enable_search(True)
+        self.treeview.set_search_equal_func(self._handle_search)
+        #try to enable the tooltips (available in pygtk 2.12 and above)
+        try: self.treeview.set_tooltip_column(DOC_INDEX)
+        except: pass
                 #setup sort order
-                column.set_sort_column_id(0)
-		#setup drag and drop
-		self.treeview.enable_model_drag_source(gtk.gdk.BUTTON1_MASK, DND_TARGETS, gtk.gdk.ACTION_COPY)
-		self.treeview.connect('drag-data-get', self._handle_drag_get_data)
-		#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(DEFAULT_BLOCKS_WINDOW_WIDTH, -1)
-		self.pack_start(scrolled_window)
-		#add button
-		self.add_button = gtk.Button(None, gtk.STOCK_ADD)
-		self.add_button.connect('clicked', self._handle_add_button)
-		self.pack_start(self.add_button, False)
-		#map categories to iters, automatic mapping for root
-		self._categories = {tuple(): None}
-		#add blocks and categories
-		self.platform.load_block_tree(self)
-		#initialize
-		self._update_add_button()
-
-	def clear(self):
-		self.treestore.clear();
-		self._categories = {tuple(): None}
-
-
-	############################################################
-	## Block Tree Methods
-	############################################################
-	def add_block(self, category, block=None):
-		"""
-		Add a block with category to this selection window.
-		Add only the category when block is None.
-		
-		Args:
-		    category: the category list or path string
-		    block: the block object or None
-		"""
-		if isinstance(category, str): category = category.split('/')
-		category = tuple(filter(lambda x: x, category)) #tuple is hashable
-		#add category and all sub categories
-		for i, cat_name in enumerate(category):
-			sub_category = category[:i+1]
-			if sub_category not in self._categories:
-				iter = self.treestore.insert_before(self._categories[sub_category[:-1]], None)
-				self.treestore.set_value(iter, NAME_INDEX, '[ %s ]'%cat_name)
-				self.treestore.set_value(iter, KEY_INDEX, '')
-				self.treestore.set_value(iter, DOC_INDEX, Utils.parse_template(CAT_MARKUP_TMPL, cat=cat_name))
-				self._categories[sub_category] = iter
-		#add block
-		if block is None: return
-		iter = self.treestore.insert_before(self._categories[category], None)
-		self.treestore.set_value(iter, NAME_INDEX, block.get_name())
-		self.treestore.set_value(iter, KEY_INDEX, block.get_key())
-		self.treestore.set_value(iter, DOC_INDEX, Utils.parse_template(DOC_MARKUP_TMPL, doc=block.get_doc()))
-
-	############################################################
-	## Helper Methods
-	############################################################
-	def _get_selected_block_key(self):
-		"""
-		Get the currently selected block key.
-		
-		Returns:
-		    the key of the selected block or a empty string
-		"""
-		selection = self.treeview.get_selection()
-		treestore, iter = selection.get_selected()
-		return iter and treestore.get_value(iter, KEY_INDEX) or ''
-
-	def _update_add_button(self):
-		"""
-		Update the add button's sensitivity.
-		The button should be active only if a block is selected.
-		"""
-		key = self._get_selected_block_key()
-		self.add_button.set_sensitive(bool(key))
-
-	def _add_selected_block(self):
-		"""
-		Add the selected block with the given key to the flow graph.
-		"""
-		key = self._get_selected_block_key()
-		if key: self.get_flow_graph().add_new_block(key)
-
-	############################################################
-	## Event Handlers
-	############################################################
-	def _handle_search(self, model, column, key, iter):
-		#determine which blocks match the search key
-		blocks = self.get_flow_graph().get_parent().get_blocks()
-		matching_blocks = filter(lambda b: key in b.get_key() or key in b.get_name().lower(), blocks)
-		#remove the old search category
-		try: self.treestore.remove(self._categories.pop((self._search_category, )))
-		except (KeyError, AttributeError): pass #nothing to remove
-		#create a search category
-		if not matching_blocks: return
-		self._search_category = 'Search: %s'%key
-		for block in matching_blocks: self.add_block(self._search_category, block)
-		#expand the search category
-		path = self.treestore.get_path(self._categories[(self._search_category, )])
-		self.treeview.collapse_all()
-		self.treeview.expand_row(path, open_all=False)
-
-	def _handle_drag_get_data(self, widget, drag_context, selection_data, info, time):
-		"""
-		Handle a drag and drop by setting the key to the selection object.
-		This will call the destination handler for drag and drop.
-		Only call set when the key is valid to ignore DND from categories.
-		"""
-		key = self._get_selected_block_key()
-		if key: selection_data.set(selection_data.target, 8, key)
-
-	def _handle_mouse_button_press(self, widget, event):
-		"""
-		Handle the mouse button press.
-		If a left double click is detected, call add selected block.
-		"""
-		if event.button == 1 and event.type == gtk.gdk._2BUTTON_PRESS:
-			self._add_selected_block()
-
-	def _handle_selection_change(self, selection):
-		"""
-		Handle a selection change in the tree view.
-		If a selection changes, set the add button sensitive.
-		"""
-		self._update_add_button()
-
-	def _handle_add_button(self, widget):
-		"""
-		Handle the add button clicked signal.
-		Call add selected block.
-		"""
-		self._add_selected_block()
+        column.set_sort_column_id(0)
+        #setup drag and drop
+        self.treeview.enable_model_drag_source(gtk.gdk.BUTTON1_MASK, DND_TARGETS, gtk.gdk.ACTION_COPY)
+        self.treeview.connect('drag-data-get', self._handle_drag_get_data)
+        #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(DEFAULT_BLOCKS_WINDOW_WIDTH, -1)
+        self.pack_start(scrolled_window)
+        #add button
+        self.add_button = gtk.Button(None, gtk.STOCK_ADD)
+        self.add_button.connect('clicked', self._handle_add_button)
+        self.pack_start(self.add_button, False)
+        #map categories to iters, automatic mapping for root
+        self._categories = {tuple(): None}
+        #add blocks and categories
+        self.platform.load_block_tree(self)
+        #initialize
+        self._update_add_button()
+
+    def clear(self):
+        self.treestore.clear();
+        self._categories = {tuple(): None}
+
+
+    ############################################################
+    ## Block Tree Methods
+    ############################################################
+    def add_block(self, category, block=None):
+        """
+        Add a block with category to this selection window.
+        Add only the category when block is None.
+        
+        Args:
+            category: the category list or path string
+            block: the block object or None
+        """
+        if isinstance(category, str): category = category.split('/')
+        category = tuple(filter(lambda x: x, category)) #tuple is hashable
+        #add category and all sub categories
+        for i, cat_name in enumerate(category):
+            sub_category = category[:i+1]
+            if sub_category not in self._categories:
+                iter = self.treestore.insert_before(self._categories[sub_category[:-1]], None)
+                self.treestore.set_value(iter, NAME_INDEX, '[ %s ]'%cat_name)
+                self.treestore.set_value(iter, KEY_INDEX, '')
+                self.treestore.set_value(iter, DOC_INDEX, Utils.parse_template(CAT_MARKUP_TMPL, cat=cat_name))
+                self._categories[sub_category] = iter
+        #add block
+        if block is None: return
+        iter = self.treestore.insert_before(self._categories[category], None)
+        self.treestore.set_value(iter, NAME_INDEX, block.get_name())
+        self.treestore.set_value(iter, KEY_INDEX, block.get_key())
+        self.treestore.set_value(iter, DOC_INDEX, Utils.parse_template(DOC_MARKUP_TMPL, doc=block.get_doc()))
+
+    ############################################################
+    ## Helper Methods
+    ############################################################
+    def _get_selected_block_key(self):
+        """
+        Get the currently selected block key.
+        
+        Returns:
+            the key of the selected block or a empty string
+        """
+        selection = self.treeview.get_selection()
+        treestore, iter = selection.get_selected()
+        return iter and treestore.get_value(iter, KEY_INDEX) or ''
+
+    def _update_add_button(self):
+        """
+        Update the add button's sensitivity.
+        The button should be active only if a block is selected.
+        """
+        key = self._get_selected_block_key()
+        self.add_button.set_sensitive(bool(key))
+
+    def _add_selected_block(self):
+        """
+        Add the selected block with the given key to the flow graph.
+        """
+        key = self._get_selected_block_key()
+        if key: self.get_flow_graph().add_new_block(key)
+
+    ############################################################
+    ## Event Handlers
+    ############################################################
+    def _handle_search(self, model, column, key, iter):
+        #determine which blocks match the search key
+        blocks = self.get_flow_graph().get_parent().get_blocks()
+        matching_blocks = filter(lambda b: key in b.get_key() or key in b.get_name().lower(), blocks)
+        #remove the old search category
+        try: self.treestore.remove(self._categories.pop((self._search_category, )))
+        except (KeyError, AttributeError): pass #nothing to remove
+        #create a search category
+        if not matching_blocks: return
+        self._search_category = 'Search: %s'%key
+        for block in matching_blocks: self.add_block(self._search_category, block)
+        #expand the search category
+        path = self.treestore.get_path(self._categories[(self._search_category, )])
+        self.treeview.collapse_all()
+        self.treeview.expand_row(path, open_all=False)
+
+    def _handle_drag_get_data(self, widget, drag_context, selection_data, info, time):
+        """
+        Handle a drag and drop by setting the key to the selection object.
+        This will call the destination handler for drag and drop.
+        Only call set when the key is valid to ignore DND from categories.
+        """
+        key = self._get_selected_block_key()
+        if key: selection_data.set(selection_data.target, 8, key)
+
+    def _handle_mouse_button_press(self, widget, event):
+        """
+        Handle the mouse button press.
+        If a left double click is detected, call add selected block.
+        """
+        if event.button == 1 and event.type == gtk.gdk._2BUTTON_PRESS:
+            self._add_selected_block()
+
+    def _handle_selection_change(self, selection):
+        """
+        Handle a selection change in the tree view.
+        If a selection changes, set the add button sensitive.
+        """
+        self._update_add_button()
+
+    def _handle_add_button(self, widget):
+        """
+        Handle the add button clicked signal.
+        Call add selected block.
+        """
+        self._add_selected_block()
diff --git a/grc/gui/Connection.py b/grc/gui/Connection.py
index 4f46e73ea9..0f631791db 100644
--- a/grc/gui/Connection.py
+++ b/grc/gui/Connection.py
@@ -23,137 +23,137 @@ import Colors
 from Constants import CONNECTOR_ARROW_BASE, CONNECTOR_ARROW_HEIGHT
 
 class Connection(Element):
-	"""
-	A graphical connection for ports.
-	The connection has 2 parts, the arrow and the wire.
-	The coloring of the arrow and wire exposes the status of 3 states:
-		enabled/disabled, valid/invalid, highlighted/non-highlighted.
-	The wire coloring exposes the enabled and highlighted states.
-	The arrow coloring exposes the enabled and valid states.
-	"""
+    """
+    A graphical connection for ports.
+    The connection has 2 parts, the arrow and the wire.
+    The coloring of the arrow and wire exposes the status of 3 states:
+        enabled/disabled, valid/invalid, highlighted/non-highlighted.
+    The wire coloring exposes the enabled and highlighted states.
+    The arrow coloring exposes the enabled and valid states.
+    """
 
-	def __init__(self): Element.__init__(self)
+    def __init__(self): Element.__init__(self)
 
-	def get_coordinate(self):
-		"""
-		Get the 0,0 coordinate.
-		Coordinates are irrelevant in connection.
-		
-		Returns:
-		    0, 0
-		"""
-		return (0, 0)
+    def get_coordinate(self):
+        """
+        Get the 0,0 coordinate.
+        Coordinates are irrelevant in connection.
+        
+        Returns:
+            0, 0
+        """
+        return (0, 0)
 
-	def get_rotation(self):
-		"""
-		Get the 0 degree rotation.
-		Rotations are irrelevant in connection.
-		
-		Returns:
-		    0
-		"""
-		return 0
+    def get_rotation(self):
+        """
+        Get the 0 degree rotation.
+        Rotations are irrelevant in connection.
+        
+        Returns:
+            0
+        """
+        return 0
 
-	def create_shapes(self):
-		"""Precalculate relative coordinates."""
-		Element.create_shapes(self)
-		self._sink_rot = None
-		self._source_rot = None
-		self._sink_coor = None
-		self._source_coor = None
-		#get the source coordinate
-		try:
-			connector_length = self.get_source().get_connector_length()
-		except:
-			return
-		self.x1, self.y1 = Utils.get_rotated_coordinate((connector_length, 0), self.get_source().get_rotation())
-		#get the sink coordinate
-		connector_length = self.get_sink().get_connector_length() + CONNECTOR_ARROW_HEIGHT
-		self.x2, self.y2 = Utils.get_rotated_coordinate((-connector_length, 0), self.get_sink().get_rotation())
-		#build the arrow
-		self.arrow = [(0, 0),
-			Utils.get_rotated_coordinate((-CONNECTOR_ARROW_HEIGHT, -CONNECTOR_ARROW_BASE/2), self.get_sink().get_rotation()),
-			Utils.get_rotated_coordinate((-CONNECTOR_ARROW_HEIGHT, CONNECTOR_ARROW_BASE/2), self.get_sink().get_rotation()),
-		]
-		self._update_after_move()
-		if not self.get_enabled(): self._arrow_color = Colors.CONNECTION_DISABLED_COLOR
-		elif not self.is_valid(): self._arrow_color = Colors.CONNECTION_ERROR_COLOR
-		else: self._arrow_color = Colors.CONNECTION_ENABLED_COLOR
+    def create_shapes(self):
+        """Precalculate relative coordinates."""
+        Element.create_shapes(self)
+        self._sink_rot = None
+        self._source_rot = None
+        self._sink_coor = None
+        self._source_coor = None
+        #get the source coordinate
+        try:
+            connector_length = self.get_source().get_connector_length()
+        except:
+            return
+        self.x1, self.y1 = Utils.get_rotated_coordinate((connector_length, 0), self.get_source().get_rotation())
+        #get the sink coordinate
+        connector_length = self.get_sink().get_connector_length() + CONNECTOR_ARROW_HEIGHT
+        self.x2, self.y2 = Utils.get_rotated_coordinate((-connector_length, 0), self.get_sink().get_rotation())
+        #build the arrow
+        self.arrow = [(0, 0),
+            Utils.get_rotated_coordinate((-CONNECTOR_ARROW_HEIGHT, -CONNECTOR_ARROW_BASE/2), self.get_sink().get_rotation()),
+            Utils.get_rotated_coordinate((-CONNECTOR_ARROW_HEIGHT, CONNECTOR_ARROW_BASE/2), self.get_sink().get_rotation()),
+        ]
+        self._update_after_move()
+        if not self.get_enabled(): self._arrow_color = Colors.CONNECTION_DISABLED_COLOR
+        elif not self.is_valid(): self._arrow_color = Colors.CONNECTION_ERROR_COLOR
+        else: self._arrow_color = Colors.CONNECTION_ENABLED_COLOR
 
-	def _update_after_move(self):
-		"""Calculate coordinates."""
-		self.clear() #FIXME do i want this here?
-		#source connector
-		source = self.get_source()
-		X, Y = source.get_connector_coordinate()
-		x1, y1 = self.x1 + X, self.y1 + Y
-		self.add_line((x1, y1), (X, Y))
-		#sink connector
-		sink = self.get_sink()
-		X, Y = sink.get_connector_coordinate()
-		x2, y2 = self.x2 + X, self.y2 + Y
-		self.add_line((x2, y2), (X, Y))
-		#adjust arrow
-		self._arrow = [(x+X, y+Y) for x,y in self.arrow]
-		#add the horizontal and vertical lines in this connection
-		if abs(source.get_connector_direction() - sink.get_connector_direction()) == 180:
-			#2 possible point sets to create a 3-line connector
-			mid_x, mid_y = (x1 + x2)/2.0, (y1 + y2)/2.0
-			points = [((mid_x, y1), (mid_x, y2)), ((x1, mid_y), (x2, mid_y))]
-			#source connector -> points[0][0] should be in the direction of source (if possible)
-			if Utils.get_angle_from_coordinates((x1, y1), points[0][0]) != source.get_connector_direction(): points.reverse()
-			#points[0][0] -> sink connector should not be in the direction of sink
-			if Utils.get_angle_from_coordinates(points[0][0], (x2, y2)) == sink.get_connector_direction(): points.reverse()
-			#points[0][0] -> source connector should not be in the direction of source
-			if Utils.get_angle_from_coordinates(points[0][0], (x1, y1)) == source.get_connector_direction(): points.reverse()
-			#create 3-line connector
-			p1, p2 = map(int, points[0][0]), map(int, points[0][1])
-			self.add_line((x1, y1), p1)
-			self.add_line(p1, p2)
-			self.add_line((x2, y2), p2)
-		else:
-			#2 possible points to create a right-angled connector
-			points = [(x1, y2), (x2, y1)]
-			#source connector -> points[0] should be in the direction of source (if possible)
-			if Utils.get_angle_from_coordinates((x1, y1), points[0]) != source.get_connector_direction(): points.reverse()
-			#points[0] -> sink connector should not be in the direction of sink
-			if Utils.get_angle_from_coordinates(points[0], (x2, y2)) == sink.get_connector_direction(): points.reverse()
-			#points[0] -> source connector should not be in the direction of source
-			if Utils.get_angle_from_coordinates(points[0], (x1, y1)) == source.get_connector_direction(): points.reverse()
-			#create right-angled connector
-			self.add_line((x1, y1), points[0])
-			self.add_line((x2, y2), points[0])
+    def _update_after_move(self):
+        """Calculate coordinates."""
+        self.clear() #FIXME do i want this here?
+        #source connector
+        source = self.get_source()
+        X, Y = source.get_connector_coordinate()
+        x1, y1 = self.x1 + X, self.y1 + Y
+        self.add_line((x1, y1), (X, Y))
+        #sink connector
+        sink = self.get_sink()
+        X, Y = sink.get_connector_coordinate()
+        x2, y2 = self.x2 + X, self.y2 + Y
+        self.add_line((x2, y2), (X, Y))
+        #adjust arrow
+        self._arrow = [(x+X, y+Y) for x,y in self.arrow]
+        #add the horizontal and vertical lines in this connection
+        if abs(source.get_connector_direction() - sink.get_connector_direction()) == 180:
+            #2 possible point sets to create a 3-line connector
+            mid_x, mid_y = (x1 + x2)/2.0, (y1 + y2)/2.0
+            points = [((mid_x, y1), (mid_x, y2)), ((x1, mid_y), (x2, mid_y))]
+            #source connector -> points[0][0] should be in the direction of source (if possible)
+            if Utils.get_angle_from_coordinates((x1, y1), points[0][0]) != source.get_connector_direction(): points.reverse()
+            #points[0][0] -> sink connector should not be in the direction of sink
+            if Utils.get_angle_from_coordinates(points[0][0], (x2, y2)) == sink.get_connector_direction(): points.reverse()
+            #points[0][0] -> source connector should not be in the direction of source
+            if Utils.get_angle_from_coordinates(points[0][0], (x1, y1)) == source.get_connector_direction(): points.reverse()
+            #create 3-line connector
+            p1, p2 = map(int, points[0][0]), map(int, points[0][1])
+            self.add_line((x1, y1), p1)
+            self.add_line(p1, p2)
+            self.add_line((x2, y2), p2)
+        else:
+            #2 possible points to create a right-angled connector
+            points = [(x1, y2), (x2, y1)]
+            #source connector -> points[0] should be in the direction of source (if possible)
+            if Utils.get_angle_from_coordinates((x1, y1), points[0]) != source.get_connector_direction(): points.reverse()
+            #points[0] -> sink connector should not be in the direction of sink
+            if Utils.get_angle_from_coordinates(points[0], (x2, y2)) == sink.get_connector_direction(): points.reverse()
+            #points[0] -> source connector should not be in the direction of source
+            if Utils.get_angle_from_coordinates(points[0], (x1, y1)) == source.get_connector_direction(): points.reverse()
+            #create right-angled connector
+            self.add_line((x1, y1), points[0])
+            self.add_line((x2, y2), points[0])
 
-	def draw(self, gc, window):
-		"""
-		Draw the connection.
-		
-		Args:
-		    gc: the graphics context
-		    window: the gtk window to draw on
-		"""
-		sink = self.get_sink()
-		source = self.get_source()
-		#check for changes
-		if self._sink_rot != sink.get_rotation() or self._source_rot != source.get_rotation(): self.create_shapes()
-		elif self._sink_coor != sink.get_coordinate() or self._source_coor != source.get_coordinate():
-			try:
-				self._update_after_move()
-			except:
-				return
-		#cache values
-		self._sink_rot = sink.get_rotation()
-		self._source_rot = source.get_rotation()
-		self._sink_coor = sink.get_coordinate()
-		self._source_coor = source.get_coordinate()
-		#draw
-		if self.is_highlighted(): border_color = Colors.HIGHLIGHT_COLOR
-		elif self.get_enabled(): border_color = Colors.CONNECTION_ENABLED_COLOR
-		else: border_color = Colors.CONNECTION_DISABLED_COLOR
-		Element.draw(self, gc, window, bg_color=None, border_color=border_color)
-		#draw arrow on sink port
-		try:
-			gc.set_foreground(self._arrow_color)
-			window.draw_polygon(gc, True, self._arrow)
-		except:
-			return
+    def draw(self, gc, window):
+        """
+        Draw the connection.
+        
+        Args:
+            gc: the graphics context
+            window: the gtk window to draw on
+        """
+        sink = self.get_sink()
+        source = self.get_source()
+        #check for changes
+        if self._sink_rot != sink.get_rotation() or self._source_rot != source.get_rotation(): self.create_shapes()
+        elif self._sink_coor != sink.get_coordinate() or self._source_coor != source.get_coordinate():
+            try:
+                self._update_after_move()
+            except:
+                return
+        #cache values
+        self._sink_rot = sink.get_rotation()
+        self._source_rot = source.get_rotation()
+        self._sink_coor = sink.get_coordinate()
+        self._source_coor = source.get_coordinate()
+        #draw
+        if self.is_highlighted(): border_color = Colors.HIGHLIGHT_COLOR
+        elif self.get_enabled(): border_color = Colors.CONNECTION_ENABLED_COLOR
+        else: border_color = Colors.CONNECTION_DISABLED_COLOR
+        Element.draw(self, gc, window, bg_color=None, border_color=border_color)
+        #draw arrow on sink port
+        try:
+            gc.set_foreground(self._arrow_color)
+            window.draw_polygon(gc, True, self._arrow)
+        except:
+            return
diff --git a/grc/gui/Dialogs.py b/grc/gui/Dialogs.py
index df424750b9..5b3b420d3b 100644
--- a/grc/gui/Dialogs.py
+++ b/grc/gui/Dialogs.py
@@ -23,46 +23,46 @@ import gtk
 import Utils
 
 class TextDisplay(gtk.TextView):
-	"""A non editable gtk text view."""
-
-	def __init__(self, text=''):
-		"""
-		TextDisplay constructor.
-		
-		Args:
-		    text: the text to display (string)
-		"""
-		text_buffer = gtk.TextBuffer()
-		text_buffer.set_text(text)
-		self.set_text = text_buffer.set_text
-		self.insert = lambda line: text_buffer.insert(text_buffer.get_end_iter(), line)
-		gtk.TextView.__init__(self, text_buffer)
-		self.set_editable(False)
-		self.set_cursor_visible(False)
-		self.set_wrap_mode(gtk.WRAP_WORD_CHAR)
+    """A non editable gtk text view."""
+
+    def __init__(self, text=''):
+        """
+        TextDisplay constructor.
+        
+        Args:
+            text: the text to display (string)
+        """
+        text_buffer = gtk.TextBuffer()
+        text_buffer.set_text(text)
+        self.set_text = text_buffer.set_text
+        self.insert = lambda line: text_buffer.insert(text_buffer.get_end_iter(), line)
+        gtk.TextView.__init__(self, text_buffer)
+        self.set_editable(False)
+        self.set_cursor_visible(False)
+        self.set_wrap_mode(gtk.WRAP_WORD_CHAR)
 
 def MessageDialogHelper(type, buttons, title=None, markup=None):
-	"""
-	Create a modal message dialog and run it.
-	
-	Args:
-	    type: the type of message: gtk.MESSAGE_INFO, gtk.MESSAGE_WARNING, gtk.MESSAGE_QUESTION or gtk.MESSAGE_ERROR
-	    buttons: the predefined set of buttons to use:
-		gtk.BUTTONS_NONE, gtk.BUTTONS_OK, gtk.BUTTONS_CLOSE, gtk.BUTTONS_CANCEL, gtk.BUTTONS_YES_NO, gtk.BUTTONS_OK_CANCEL
-	
-	Args:
-	    tittle: the title of the window (string)
-	    markup: the message text with pango markup
-	
-	Returns:
-	    the gtk response from run()
-	"""
-	message_dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, type, buttons)
-	if title: message_dialog.set_title(title)
-	if markup: message_dialog.set_markup(markup)
-	response = message_dialog.run()
-	message_dialog.destroy()
-	return response
+    """
+    Create a modal message dialog and run it.
+    
+    Args:
+        type: the type of message: gtk.MESSAGE_INFO, gtk.MESSAGE_WARNING, gtk.MESSAGE_QUESTION or gtk.MESSAGE_ERROR
+        buttons: the predefined set of buttons to use:
+        gtk.BUTTONS_NONE, gtk.BUTTONS_OK, gtk.BUTTONS_CLOSE, gtk.BUTTONS_CANCEL, gtk.BUTTONS_YES_NO, gtk.BUTTONS_OK_CANCEL
+    
+    Args:
+        tittle: the title of the window (string)
+        markup: the message text with pango markup
+    
+    Returns:
+        the gtk response from run()
+    """
+    message_dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, type, buttons)
+    if title: message_dialog.set_title(title)
+    if markup: message_dialog.set_markup(markup)
+    response = message_dialog.run()
+    message_dialog.destroy()
+    return response
 
 
 ERRORS_MARKUP_TMPL="""\
@@ -72,31 +72,31 @@ $encode($err_msg.replace('\t', '  '))
 
 #end for"""
 def ErrorsDialog(flowgraph): MessageDialogHelper(
-	type=gtk.MESSAGE_ERROR,
-	buttons=gtk.BUTTONS_CLOSE,
-	title='Flow Graph Errors',
-	markup=Utils.parse_template(ERRORS_MARKUP_TMPL, errors=flowgraph.get_error_messages()),
+    type=gtk.MESSAGE_ERROR,
+    buttons=gtk.BUTTONS_CLOSE,
+    title='Flow Graph Errors',
+    markup=Utils.parse_template(ERRORS_MARKUP_TMPL, errors=flowgraph.get_error_messages()),
 )
 
 class AboutDialog(gtk.AboutDialog):
-	"""A cute little about dialog."""
-
-	def __init__(self, platform):
-		"""AboutDialog constructor."""
-		gtk.AboutDialog.__init__(self)
-		self.set_name(platform.get_name())
-		self.set_version(platform.get_version())
-		self.set_license(platform.get_license())
-		self.set_copyright(platform.get_license().splitlines()[0])
-		self.set_website(platform.get_website())
-		self.run()
-		self.destroy()
+    """A cute little about dialog."""
+
+    def __init__(self, platform):
+        """AboutDialog constructor."""
+        gtk.AboutDialog.__init__(self)
+        self.set_name(platform.get_name())
+        self.set_version(platform.get_version())
+        self.set_license(platform.get_license())
+        self.set_copyright(platform.get_license().splitlines()[0])
+        self.set_website(platform.get_website())
+        self.run()
+        self.destroy()
 
 def HelpDialog(): MessageDialogHelper(
-	type=gtk.MESSAGE_INFO,
-	buttons=gtk.BUTTONS_CLOSE,
-	title='Help',
-	markup="""\
+    type=gtk.MESSAGE_INFO,
+    buttons=gtk.BUTTONS_CLOSE,
+    title='Help',
+    markup="""\
 <b>Usage Tips</b>
 
 <u>Add block</u>: drag and drop or double click a block in the block selection window.
@@ -112,15 +112,15 @@ COLORS_DIALOG_MARKUP_TMPL = """\
 <b>Color Mapping</b>
 
 #if $colors
-	#set $max_len = max([len(color[0]) for color in $colors]) + 10
-	#for $title, $color_spec in $colors
+    #set $max_len = max([len(color[0]) for color in $colors]) + 10
+    #for $title, $color_spec in $colors
 <span background="$color_spec"><tt>$($encode($title).center($max_len))</tt></span>
-	#end for
+    #end for
 #end if
 """
 
 def TypesDialog(platform): MessageDialogHelper(
-	type=gtk.MESSAGE_INFO,
-	buttons=gtk.BUTTONS_CLOSE,
-	title='Types',
-	markup=Utils.parse_template(COLORS_DIALOG_MARKUP_TMPL, colors=platform.get_colors()))
+    type=gtk.MESSAGE_INFO,
+    buttons=gtk.BUTTONS_CLOSE,
+    title='Types',
+    markup=Utils.parse_template(COLORS_DIALOG_MARKUP_TMPL, colors=platform.get_colors()))
diff --git a/grc/gui/DrawingArea.py b/grc/gui/DrawingArea.py
index da16eb7cf2..64be4d3ea6 100644
--- a/grc/gui/DrawingArea.py
+++ b/grc/gui/DrawingArea.py
@@ -23,113 +23,113 @@ import gtk
 from Constants import MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT, DND_TARGETS
 
 class DrawingArea(gtk.DrawingArea):
-	"""
-	DrawingArea is the gtk pixel map that graphical elements may draw themselves on.
-	The drawing area also responds to mouse and key events.
-	"""
+    """
+    DrawingArea is the gtk pixel map that graphical elements may draw themselves on.
+    The drawing area also responds to mouse and key events.
+    """
 
-	def __init__(self, flow_graph):
-		"""
-		DrawingArea contructor.
-		Connect event handlers.
-		
-		Args:
-		    main_window: the main_window containing all flow graphs
-		"""
-		self.ctrl_mask = False
-		self._flow_graph = flow_graph
-		gtk.DrawingArea.__init__(self)
-		self.set_size_request(MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT)
-		self.connect('realize', self._handle_window_realize)
-		self.connect('configure-event', self._handle_window_configure)
-		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.add_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 drag and drop
-		self.drag_dest_set(gtk.DEST_DEFAULT_ALL, DND_TARGETS, gtk.gdk.ACTION_COPY)
-		self.connect('drag-data-received', self._handle_drag_data_received)
-		#setup the focus flag
-		self._focus_flag = False
-		self.get_focus_flag = lambda: self._focus_flag
-		def _handle_focus_event(widget, event, focus_flag): self._focus_flag = focus_flag
-		self.connect('leave-notify-event', _handle_focus_event, False)
-		self.connect('enter-notify-event', _handle_focus_event, True)
+    def __init__(self, flow_graph):
+        """
+        DrawingArea contructor.
+        Connect event handlers.
+        
+        Args:
+            main_window: the main_window containing all flow graphs
+        """
+        self.ctrl_mask = False
+        self._flow_graph = flow_graph
+        gtk.DrawingArea.__init__(self)
+        self.set_size_request(MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT)
+        self.connect('realize', self._handle_window_realize)
+        self.connect('configure-event', self._handle_window_configure)
+        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.add_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 drag and drop
+        self.drag_dest_set(gtk.DEST_DEFAULT_ALL, DND_TARGETS, gtk.gdk.ACTION_COPY)
+        self.connect('drag-data-received', self._handle_drag_data_received)
+        #setup the focus flag
+        self._focus_flag = False
+        self.get_focus_flag = lambda: self._focus_flag
+        def _handle_focus_event(widget, event, focus_flag): self._focus_flag = focus_flag
+        self.connect('leave-notify-event', _handle_focus_event, False)
+        self.connect('enter-notify-event', _handle_focus_event, True)
 
-	def new_pixmap(self, width, height): return gtk.gdk.Pixmap(self.window, width, height, -1)
-	def get_pixbuf(self):
-		width, height = self._pixmap.get_size()
-		pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, 0, 8, width, height)
-		pixbuf.get_from_drawable(self._pixmap, self._pixmap.get_colormap(), 0, 0, 0, 0, width, height)
-		return pixbuf
+    def new_pixmap(self, width, height): return gtk.gdk.Pixmap(self.window, width, height, -1)
+    def get_pixbuf(self):
+        width, height = self._pixmap.get_size()
+        pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, 0, 8, width, height)
+        pixbuf.get_from_drawable(self._pixmap, self._pixmap.get_colormap(), 0, 0, 0, 0, width, height)
+        return pixbuf
 
-	##########################################################################
-	## Handlers
-	##########################################################################
-	def _handle_drag_data_received(self, widget, drag_context, x, y, selection_data, info, time):
-		"""
-		Handle a drag and drop by adding a block at the given coordinate.
-		"""
-		self._flow_graph.add_new_block(selection_data.data, (x, y))
+    ##########################################################################
+    ## Handlers
+    ##########################################################################
+    def _handle_drag_data_received(self, widget, drag_context, x, y, selection_data, info, time):
+        """
+        Handle a drag and drop by adding a block at the given coordinate.
+        """
+        self._flow_graph.add_new_block(selection_data.data, (x, y))
 
-	def _handle_mouse_button_press(self, widget, event):
-		"""
-		Forward button click information to the flow graph.
-		"""
-		self.ctrl_mask = event.state & gtk.gdk.CONTROL_MASK
-		if event.button == 1: self._flow_graph.handle_mouse_selector_press(
-			double_click=(event.type == gtk.gdk._2BUTTON_PRESS),
-			coordinate=(event.x, event.y),
-		)
-		if event.button == 3: self._flow_graph.handle_mouse_context_press(
-			coordinate=(event.x, event.y),
-			event=event,
-		)
+    def _handle_mouse_button_press(self, widget, event):
+        """
+        Forward button click information to the flow graph.
+        """
+        self.ctrl_mask = event.state & gtk.gdk.CONTROL_MASK
+        if event.button == 1: self._flow_graph.handle_mouse_selector_press(
+            double_click=(event.type == gtk.gdk._2BUTTON_PRESS),
+            coordinate=(event.x, event.y),
+        )
+        if event.button == 3: self._flow_graph.handle_mouse_context_press(
+            coordinate=(event.x, event.y),
+            event=event,
+        )
 
-	def _handle_mouse_button_release(self, widget, event):
-		"""
-		Forward button release information to the flow graph.
-		"""
-		self.ctrl_mask = event.state & gtk.gdk.CONTROL_MASK
-		if event.button == 1: self._flow_graph.handle_mouse_selector_release(
-			coordinate=(event.x, event.y),
-		)
+    def _handle_mouse_button_release(self, widget, event):
+        """
+        Forward button release information to the flow graph.
+        """
+        self.ctrl_mask = event.state & gtk.gdk.CONTROL_MASK
+        if event.button == 1: self._flow_graph.handle_mouse_selector_release(
+            coordinate=(event.x, event.y),
+        )
 
-	def _handle_mouse_motion(self, widget, event):
-		"""
-		Forward mouse motion information to the flow graph.
-		"""
-		self.ctrl_mask = event.state & gtk.gdk.CONTROL_MASK
-		self._flow_graph.handle_mouse_motion(
-			coordinate=(event.x, event.y),
-		)
+    def _handle_mouse_motion(self, widget, event):
+        """
+        Forward mouse motion information to the flow graph.
+        """
+        self.ctrl_mask = event.state & gtk.gdk.CONTROL_MASK
+        self._flow_graph.handle_mouse_motion(
+            coordinate=(event.x, event.y),
+        )
 
-	def _handle_window_realize(self, widget):
-		"""
-		Called when the window is realized.
-		Update the flowgraph, which calls new pixmap.
-		"""
-		self._flow_graph.update()
+    def _handle_window_realize(self, widget):
+        """
+        Called when the window is realized.
+        Update the flowgraph, which calls new pixmap.
+        """
+        self._flow_graph.update()
 
-	def _handle_window_configure(self, widget, event):
-		"""
-		Called when the window is resized.
-		Create a new pixmap for background buffer.
-		"""
-		self._pixmap = self.new_pixmap(*self.get_size_request())
+    def _handle_window_configure(self, widget, event):
+        """
+        Called when the window is resized.
+        Create a new pixmap for background buffer.
+        """
+        self._pixmap = self.new_pixmap(*self.get_size_request())
 
-	def _handle_window_expose(self, widget, event):
-		"""
-		Called when window is exposed, or queue_draw is called.
-		Double buffering: draw to pixmap, then draw pixmap to window.
-		"""
-		gc = self.window.new_gc()
-		self._flow_graph.draw(gc, self._pixmap)
-		self.window.draw_drawable(gc, self._pixmap, 0, 0, 0, 0, -1, -1)
+    def _handle_window_expose(self, widget, event):
+        """
+        Called when window is exposed, or queue_draw is called.
+        Double buffering: draw to pixmap, then draw pixmap to window.
+        """
+        gc = self.window.new_gc()
+        self._flow_graph.draw(gc, self._pixmap)
+        self.window.draw_drawable(gc, self._pixmap, 0, 0, 0, 0, -1, -1)
diff --git a/grc/gui/Element.py b/grc/gui/Element.py
index cd97a3fb21..915bdfb915 100644
--- a/grc/gui/Element.py
+++ b/grc/gui/Element.py
@@ -21,245 +21,244 @@ from Constants import LINE_SELECT_SENSITIVITY
 from Constants import POSSIBLE_ROTATIONS
 
 class Element(object):
-	"""
-	GraphicalElement 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 of those areas.
-	"""
+    """
+    GraphicalElement 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 of those areas.
+    """
 
-	def __init__(self):
-		"""
-		Make a new list of rectangular areas and lines, and set the coordinate and the rotation.
-		"""
-		self.set_rotation(POSSIBLE_ROTATIONS[0])
-		self.set_coordinate((0, 0))
-		self.clear()
-		self.set_highlighted(False)
+    def __init__(self):
+        """
+        Make a new list of rectangular areas and lines, and set the coordinate and the rotation.
+        """
+        self.set_rotation(POSSIBLE_ROTATIONS[0])
+        self.set_coordinate((0, 0))
+        self.clear()
+        self.set_highlighted(False)
 
-	def is_horizontal(self, rotation=None):
-		"""
-		Is this element horizontal?
-		If rotation is None, use this element's rotation.
-		
-		Args:
-		    rotation: the optional rotation
-		
-		Returns:
-		    true if rotation is horizontal
-		"""
-		rotation = rotation or self.get_rotation()
-		return rotation in (0, 180)
+    def is_horizontal(self, rotation=None):
+        """
+        Is this element horizontal?
+        If rotation is None, use this element's rotation.
+        
+        Args:
+            rotation: the optional rotation
+        
+        Returns:
+            true if rotation is horizontal
+        """
+        rotation = rotation or self.get_rotation()
+        return rotation in (0, 180)
 
-	def is_vertical(self, rotation=None):
-		"""
-		Is this element vertical?
-		If rotation is None, use this element's rotation.
-		
-		Args:
-		    rotation: the optional rotation
-		
-		Returns:
-		    true if rotation is vertical
-		"""
-		rotation = rotation or self.get_rotation()
-		return rotation in (90, 270)
+    def is_vertical(self, rotation=None):
+        """
+        Is this element vertical?
+        If rotation is None, use this element's rotation.
+        
+        Args:
+            rotation: the optional rotation
+        
+        Returns:
+            true if rotation is vertical
+        """
+        rotation = rotation or self.get_rotation()
+        return rotation in (90, 270)
 
-	def create_labels(self):
-		"""
-		Create labels (if applicable) and call on all children.
-		Call this base method before creating labels in the element.
-		"""
-		for child in self.get_children():child.create_labels()
+    def create_labels(self):
+        """
+        Create labels (if applicable) and call on all children.
+        Call this base method before creating labels in the element.
+        """
+        for child in self.get_children():child.create_labels()
 
-	def create_shapes(self):
-		"""
-		Create shapes (if applicable) and call on all children.
-		Call this base method before creating shapes in the element.
-		"""
-		self.clear()
-		for child in self.get_children(): child.create_shapes()
+    def create_shapes(self):
+        """
+        Create shapes (if applicable) and call on all children.
+        Call this base method before creating shapes in the element.
+        """
+        self.clear()
+        for child in self.get_children(): child.create_shapes()
 
-	def draw(self, gc, window, border_color, bg_color):
-		"""
-		Draw in the given window.
-		
-		Args:
-		    gc: the graphics context
-		    window: the gtk window to draw on
-		    border_color: the color for lines and rectangle borders
-		    bg_color: the color for the inside of the rectangle
-		"""
-		
-		X,Y = self.get_coordinate()
-		for (rX,rY),(W,H) in self._areas_list:
-			aX = X + rX
-			aY = Y + rY
-			gc.set_foreground(bg_color)
-			window.draw_rectangle(gc, True, aX, aY, W, H)
-			gc.set_foreground(border_color)
-			window.draw_rectangle(gc, False, aX, aY, W, H)
-		for (x1, y1),(x2, y2) in self._lines_list:
-			gc.set_foreground(border_color)
-			window.draw_line(gc, X+x1, Y+y1, X+x2, Y+y2)
+    def draw(self, gc, window, border_color, bg_color):
+        """
+        Draw in the given window.
+        
+        Args:
+            gc: the graphics context
+            window: the gtk window to draw on
+            border_color: the color for lines and rectangle borders
+            bg_color: the color for the inside of the rectangle
+        """
+        X,Y = self.get_coordinate()
+        for (rX,rY),(W,H) in self._areas_list:
+            aX = X + rX
+            aY = Y + rY
+            gc.set_foreground(bg_color)
+            window.draw_rectangle(gc, True, aX, aY, W, H)
+            gc.set_foreground(border_color)
+            window.draw_rectangle(gc, False, aX, aY, W, H)
+        for (x1, y1),(x2, y2) in self._lines_list:
+            gc.set_foreground(border_color)
+            window.draw_line(gc, X+x1, Y+y1, X+x2, Y+y2)
 
-	def rotate(self, rotation):
-		"""
-		Rotate all of the areas by 90 degrees.
-		
-		Args:
-		    rotation: multiple of 90 degrees
-		"""
-		self.set_rotation((self.get_rotation() + rotation)%360)
+    def rotate(self, rotation):
+        """
+        Rotate all of the areas by 90 degrees.
+        
+        Args:
+            rotation: multiple of 90 degrees
+        """
+        self.set_rotation((self.get_rotation() + rotation)%360)
 
-	def clear(self):
-		"""Empty the lines and areas."""
-		self._areas_list = list()
-		self._lines_list = list()
+    def clear(self):
+        """Empty the lines and areas."""
+        self._areas_list = list()
+        self._lines_list = list()
 
-	def set_coordinate(self, coor):
-		"""
-		Set the reference coordinate.
-		
-		Args:
-		    coor: the coordinate tuple (x,y)
-		"""
-		self.coor = coor
+    def set_coordinate(self, coor):
+        """
+        Set the reference coordinate.
+        
+        Args:
+            coor: the coordinate tuple (x,y)
+        """
+        self.coor = coor
 
-	def get_parent(self):
-		"""
-		Get the parent of this element.
-		
-		Returns:
-		    the parent
-		"""
-		return self.parent
+    def get_parent(self):
+        """
+        Get the parent of this element.
+        
+        Returns:
+            the parent
+        """
+        return self.parent
 
-	def set_highlighted(self, highlighted):
-		"""
-		Set the highlight status.
-		
-		Args:
-		    highlighted: true to enable highlighting
-		"""
-		self.highlighted = highlighted
+    def set_highlighted(self, highlighted):
+        """
+        Set the highlight status.
+        
+        Args:
+            highlighted: true to enable highlighting
+        """
+        self.highlighted = highlighted
 
-	def is_highlighted(self):
-		"""
-		Get the highlight status.
-		
-		Returns:
-		    true if highlighted
-		"""
-		return self.highlighted
+    def is_highlighted(self):
+        """
+        Get the highlight status.
+        
+        Returns:
+            true if highlighted
+        """
+        return self.highlighted
 
-	def get_coordinate(self):
-		"""Get the coordinate.
-		
-		Returns:
-		    the coordinate tuple (x,y)
-		"""
-		return self.coor
+    def get_coordinate(self):
+        """Get the coordinate.
+        
+        Returns:
+            the coordinate tuple (x,y)
+        """
+        return self.coor
 
-	def move(self, delta_coor):
-		"""
-		Move the element by adding the delta_coor to the current coordinate.
-		
-		Args:
-		    delta_coor: (delta_x,delta_y) tuple
-		"""
-		deltaX, deltaY = delta_coor
-		X, Y = self.get_coordinate()
-		self.set_coordinate((X+deltaX, Y+deltaY))
+    def move(self, delta_coor):
+        """
+        Move the element by adding the delta_coor to the current coordinate.
+        
+        Args:
+            delta_coor: (delta_x,delta_y) tuple
+        """
+        deltaX, deltaY = delta_coor
+        X, Y = self.get_coordinate()
+        self.set_coordinate((X+deltaX, Y+deltaY))
 
-	def add_area(self, rel_coor, area):
-		"""
-		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.
-		
-		Args:
-		    rel_coor: (x,y) offset from this element's coordinate
-		    area: (width,height) tuple
-		"""
-		self._areas_list.append((rel_coor, area))
+    def add_area(self, rel_coor, area):
+        """
+        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.
+        
+        Args:
+            rel_coor: (x,y) offset from this element's coordinate
+            area: (width,height) tuple
+        """
+        self._areas_list.append((rel_coor, area))
 
-	def add_line(self, rel_coor1, rel_coor2):
-		"""
-		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.
-		
-		Args:
-		    rel_coor1: relative (x1,y1) tuple
-		    rel_coor2: relative (x2,y2) tuple
-		"""
-		self._lines_list.append((rel_coor1, rel_coor2))
+    def add_line(self, rel_coor1, rel_coor2):
+        """
+        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.
+        
+        Args:
+            rel_coor1: relative (x1,y1) tuple
+            rel_coor2: relative (x2,y2) tuple
+        """
+        self._lines_list.append((rel_coor1, rel_coor2))
 
-	def what_is_selected(self, coor, coor_m=None):
-		"""
-		One coordinate specified:
-			Is this element selected at given coordinate?
-			ie: is the coordinate encompassed by one of the areas or lines?
-		Both coordinates specified:
-			Is this element within the rectangular region defined by both coordinates?
-			ie: do any area corners or line endpoints fall within the region?
-		
-		Args:
-		    coor: the selection coordinate, tuple x, y
-		    coor_m: an additional selection coordinate.
-		
-		Returns:
-		    self if one of the areas/lines encompasses coor, else None.
-		"""
-		#function to test if p is between a and b (inclusive)
-		in_between = lambda p, a, b: p >= min(a, b) and p <= max(a, b)
-		#relative coordinate
-		x, y = [a-b for a,b in zip(coor, self.get_coordinate())]
-		if coor_m:
-			x_m, y_m = [a-b for a,b in zip(coor_m, self.get_coordinate())]
-			#handle rectangular areas
-			for (x1,y1), (w,h) in self._areas_list:
-				if in_between(x1, x, x_m) and in_between(y1, y, y_m) or \
-					in_between(x1+w, x, x_m) and in_between(y1, y, y_m) or \
-					in_between(x1, x, x_m) and in_between(y1+h, y, y_m) or \
-					in_between(x1+w, x, x_m) and in_between(y1+h, y, y_m):
-					return self
-			#handle horizontal or vertical lines
-			for (x1, y1), (x2, y2) in self._lines_list:
-				if in_between(x1, x, x_m) and in_between(y1, y, y_m) or \
-					in_between(x2, x, x_m) and in_between(y2, y, y_m):
-					return self
-			return None
-		else:
-			#handle rectangular areas
-			for (x1,y1), (w,h) in self._areas_list:
-				if in_between(x, x1, x1+w) and in_between(y, y1, y1+h): return self
-			#handle horizontal or vertical lines
-			for (x1, y1), (x2, y2) in self._lines_list:
-				if x1 == x2: x1, x2 = x1-LINE_SELECT_SENSITIVITY, x2+LINE_SELECT_SENSITIVITY
-				if y1 == y2: y1, y2 = y1-LINE_SELECT_SENSITIVITY, y2+LINE_SELECT_SENSITIVITY
-				if in_between(x, x1, x2) and in_between(y, y1, y2): return self
-			return None
+    def what_is_selected(self, coor, coor_m=None):
+        """
+        One coordinate specified:
+            Is this element selected at given coordinate?
+            ie: is the coordinate encompassed by one of the areas or lines?
+        Both coordinates specified:
+            Is this element within the rectangular region defined by both coordinates?
+            ie: do any area corners or line endpoints fall within the region?
+        
+        Args:
+            coor: the selection coordinate, tuple x, y
+            coor_m: an additional selection coordinate.
+        
+        Returns:
+            self if one of the areas/lines encompasses coor, else None.
+        """
+        #function to test if p is between a and b (inclusive)
+        in_between = lambda p, a, b: p >= min(a, b) and p <= max(a, b)
+        #relative coordinate
+        x, y = [a-b for a,b in zip(coor, self.get_coordinate())]
+        if coor_m:
+            x_m, y_m = [a-b for a,b in zip(coor_m, self.get_coordinate())]
+            #handle rectangular areas
+            for (x1,y1), (w,h) in self._areas_list:
+                if in_between(x1, x, x_m) and in_between(y1, y, y_m) or \
+                    in_between(x1+w, x, x_m) and in_between(y1, y, y_m) or \
+                    in_between(x1, x, x_m) and in_between(y1+h, y, y_m) or \
+                    in_between(x1+w, x, x_m) and in_between(y1+h, y, y_m):
+                    return self
+            #handle horizontal or vertical lines
+            for (x1, y1), (x2, y2) in self._lines_list:
+                if in_between(x1, x, x_m) and in_between(y1, y, y_m) or \
+                    in_between(x2, x, x_m) and in_between(y2, y, y_m):
+                    return self
+            return None
+        else:
+            #handle rectangular areas
+            for (x1,y1), (w,h) in self._areas_list:
+                if in_between(x, x1, x1+w) and in_between(y, y1, y1+h): return self
+            #handle horizontal or vertical lines
+            for (x1, y1), (x2, y2) in self._lines_list:
+                if x1 == x2: x1, x2 = x1-LINE_SELECT_SENSITIVITY, x2+LINE_SELECT_SENSITIVITY
+                if y1 == y2: y1, y2 = y1-LINE_SELECT_SENSITIVITY, y2+LINE_SELECT_SENSITIVITY
+                if in_between(x, x1, x2) and in_between(y, y1, y2): return self
+            return None
 
-	def get_rotation(self):
-		"""
-		Get the rotation in degrees.
-		
-		Returns:
-		    the rotation
-		"""
-		return self.rotation
+    def get_rotation(self):
+        """
+        Get the rotation in degrees.
+        
+        Returns:
+            the rotation
+        """
+        return self.rotation
 
-	def set_rotation(self, rotation):
-		"""
-		Set the rotation in degrees.
-		
-		Args:
-		    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 set_rotation(self, rotation):
+        """
+        Set the rotation in degrees.
+        
+        Args:
+            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
diff --git a/grc/gui/FileDialogs.py b/grc/gui/FileDialogs.py
index 20172a7418..e8e859dc60 100644
--- a/grc/gui/FileDialogs.py
+++ b/grc/gui/FileDialogs.py
@@ -22,8 +22,8 @@ pygtk.require('2.0')
 import gtk
 from Dialogs import MessageDialogHelper
 from Constants import \
-	DEFAULT_FILE_PATH, IMAGE_FILE_EXTENSION, \
-	NEW_FLOGRAPH_TITLE
+    DEFAULT_FILE_PATH, IMAGE_FILE_EXTENSION, \
+    NEW_FLOGRAPH_TITLE
 import Preferences
 from os import path
 import Utils
@@ -46,139 +46,139 @@ File <b>$encode($filename)</b> Does not Exist!"""
 ##################################################
 ##the filter for flow graph files
 def get_flow_graph_files_filter():
-	filter = gtk.FileFilter()
-	filter.set_name('Flow Graph Files')
-	filter.add_pattern('*'+Preferences.file_extension())
-	return filter
+    filter = gtk.FileFilter()
+    filter.set_name('Flow Graph Files')
+    filter.add_pattern('*'+Preferences.file_extension())
+    return filter
 
 ##the filter for image files
 def get_image_files_filter():
-	filter = gtk.FileFilter()
-	filter.set_name('Image Files')
-	filter.add_pattern('*'+IMAGE_FILE_EXTENSION)
-	return filter
+    filter = gtk.FileFilter()
+    filter.set_name('Image Files')
+    filter.add_pattern('*'+IMAGE_FILE_EXTENSION)
+    return filter
 
 ##the filter for all files
 def get_all_files_filter():
-	filter = gtk.FileFilter()
-	filter.set_name('All Files')
-	filter.add_pattern('*')
-	return filter
+    filter = gtk.FileFilter()
+    filter.set_name('All Files')
+    filter.add_pattern('*')
+    return filter
 
 ##################################################
 # File Dialogs
 ##################################################
 class FileDialogHelper(gtk.FileChooserDialog):
-	"""
-	A wrapper class for the gtk file chooser dialog.
-	Implement a file chooser dialog with only necessary parameters.
-	"""
-
-	def __init__(self, action, title):
-		"""
-		FileDialogHelper contructor.
-		Create a save or open dialog with cancel and ok buttons.
-		Use standard settings: no multiple selection, local files only, and the * filter.
-		
-		Args:
-		    action: gtk.FILE_CHOOSER_ACTION_OPEN or gtk.FILE_CHOOSER_ACTION_SAVE
-		    title: the title of the dialog (string)
-		"""
-		ok_stock = {gtk.FILE_CHOOSER_ACTION_OPEN : 'gtk-open', gtk.FILE_CHOOSER_ACTION_SAVE : 'gtk-save'}[action]
-		gtk.FileChooserDialog.__init__(self, title, None, action, ('gtk-cancel', gtk.RESPONSE_CANCEL, ok_stock, gtk.RESPONSE_OK))
-		self.set_select_multiple(False)
-		self.set_local_only(True)
-		self.add_filter(get_all_files_filter())
+    """
+    A wrapper class for the gtk file chooser dialog.
+    Implement a file chooser dialog with only necessary parameters.
+    """
+
+    def __init__(self, action, title):
+        """
+        FileDialogHelper contructor.
+        Create a save or open dialog with cancel and ok buttons.
+        Use standard settings: no multiple selection, local files only, and the * filter.
+        
+        Args:
+            action: gtk.FILE_CHOOSER_ACTION_OPEN or gtk.FILE_CHOOSER_ACTION_SAVE
+            title: the title of the dialog (string)
+        """
+        ok_stock = {gtk.FILE_CHOOSER_ACTION_OPEN : 'gtk-open', gtk.FILE_CHOOSER_ACTION_SAVE : 'gtk-save'}[action]
+        gtk.FileChooserDialog.__init__(self, title, None, action, ('gtk-cancel', gtk.RESPONSE_CANCEL, ok_stock, gtk.RESPONSE_OK))
+        self.set_select_multiple(False)
+        self.set_local_only(True)
+        self.add_filter(get_all_files_filter())
 
 class FileDialog(FileDialogHelper):
-	"""A dialog box to save or open flow graph files. This is a base class, do not use."""
-
-	def __init__(self, current_file_path=''):
-		"""
-		FileDialog constructor.
-		
-		Args:
-		    current_file_path: the current directory or path to the open flow graph
-		"""
-		if not current_file_path: current_file_path = path.join(DEFAULT_FILE_PATH, NEW_FLOGRAPH_TITLE + Preferences.file_extension())
-		if self.type == OPEN_FLOW_GRAPH:
-			FileDialogHelper.__init__(self, gtk.FILE_CHOOSER_ACTION_OPEN, 'Open a Flow Graph from a File...')
-			self.add_and_set_filter(get_flow_graph_files_filter())
-			self.set_select_multiple(True)
-		elif self.type == SAVE_FLOW_GRAPH:
-			FileDialogHelper.__init__(self, gtk.FILE_CHOOSER_ACTION_SAVE, 'Save a Flow Graph to a File...')
-			self.add_and_set_filter(get_flow_graph_files_filter())
-			self.set_current_name(path.basename(current_file_path)) #show the current filename
-		elif self.type == SAVE_IMAGE:
-			FileDialogHelper.__init__(self, gtk.FILE_CHOOSER_ACTION_SAVE, 'Save a Flow Graph Screen Shot...')
-			self.add_and_set_filter(get_image_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
-
-	def add_and_set_filter(self, filter):
-		"""
-		Add the gtk file filter to the list of filters and set it as the default file filter.
-		
-		Args:
-		    filter: a gtk file filter.
-		"""
-		self.add_filter(filter)
-		self.set_filter(filter)
-
-	def get_rectified_filename(self):
-		"""
-		Run the dialog and get the filename.
-		If this is a save dialog and the file name is missing the extension, append the file extension.
-		If the file name with the extension already exists, show a overwrite dialog.
-		If this is an open dialog, return a list of filenames.
-		
-		Returns:
-		    the complete file path
-		"""
-		if gtk.FileChooserDialog.run(self) != gtk.RESPONSE_OK: return None #response was cancel
-		#############################################
-		# Handle Save Dialogs
-		#############################################
-		if self.type in (SAVE_FLOW_GRAPH, SAVE_IMAGE):
-			filename = self.get_filename()
-			extension = {
-				SAVE_FLOW_GRAPH: Preferences.file_extension(),
-				SAVE_IMAGE: IMAGE_FILE_EXTENSION,
-			}[self.type]
-			#append the missing file extension if the filter matches
-			if path.splitext(filename)[1].lower() != extension: filename += extension
-			self.set_current_name(path.basename(filename)) #show the filename with extension
-			if path.exists(filename): #ask the user to confirm overwrite
-				if MessageDialogHelper(
-					gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, 'Confirm Overwrite!',
-					Utils.parse_template(FILE_OVERWRITE_MARKUP_TMPL, filename=filename),
-				) == gtk.RESPONSE_NO: return self.get_rectified_filename()
-			return filename
-		#############################################
-		# Handle Open Dialogs
-		#############################################
-		elif self.type in (OPEN_FLOW_GRAPH,):
-			filenames = self.get_filenames()
-			for filename in filenames:
-				if not path.exists(filename): #show a warning and re-run
-					MessageDialogHelper(
-						gtk.MESSAGE_WARNING, gtk.BUTTONS_CLOSE, 'Cannot Open!',
-						Utils.parse_template(FILE_DNE_MARKUP_TMPL, filename=filename),
-					)
-					return self.get_rectified_filename()
-			return filenames
-
-	def run(self):
-		"""
-		Get the filename and destroy the dialog.
-		
-		Returns:
-		    the filename or None if a close/cancel occured.
-		"""
-		filename = self.get_rectified_filename()
-		self.destroy()
-		return filename
+    """A dialog box to save or open flow graph files. This is a base class, do not use."""
+
+    def __init__(self, current_file_path=''):
+        """
+        FileDialog constructor.
+        
+        Args:
+            current_file_path: the current directory or path to the open flow graph
+        """
+        if not current_file_path: current_file_path = path.join(DEFAULT_FILE_PATH, NEW_FLOGRAPH_TITLE + Preferences.file_extension())
+        if self.type == OPEN_FLOW_GRAPH:
+            FileDialogHelper.__init__(self, gtk.FILE_CHOOSER_ACTION_OPEN, 'Open a Flow Graph from a File...')
+            self.add_and_set_filter(get_flow_graph_files_filter())
+            self.set_select_multiple(True)
+        elif self.type == SAVE_FLOW_GRAPH:
+            FileDialogHelper.__init__(self, gtk.FILE_CHOOSER_ACTION_SAVE, 'Save a Flow Graph to a File...')
+            self.add_and_set_filter(get_flow_graph_files_filter())
+            self.set_current_name(path.basename(current_file_path)) #show the current filename
+        elif self.type == SAVE_IMAGE:
+            FileDialogHelper.__init__(self, gtk.FILE_CHOOSER_ACTION_SAVE, 'Save a Flow Graph Screen Shot...')
+            self.add_and_set_filter(get_image_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
+
+    def add_and_set_filter(self, filter):
+        """
+        Add the gtk file filter to the list of filters and set it as the default file filter.
+        
+        Args:
+            filter: a gtk file filter.
+        """
+        self.add_filter(filter)
+        self.set_filter(filter)
+
+    def get_rectified_filename(self):
+        """
+        Run the dialog and get the filename.
+        If this is a save dialog and the file name is missing the extension, append the file extension.
+        If the file name with the extension already exists, show a overwrite dialog.
+        If this is an open dialog, return a list of filenames.
+        
+        Returns:
+            the complete file path
+        """
+        if gtk.FileChooserDialog.run(self) != gtk.RESPONSE_OK: return None #response was cancel
+        #############################################
+        # Handle Save Dialogs
+        #############################################
+        if self.type in (SAVE_FLOW_GRAPH, SAVE_IMAGE):
+            filename = self.get_filename()
+            extension = {
+                SAVE_FLOW_GRAPH: Preferences.file_extension(),
+                SAVE_IMAGE: IMAGE_FILE_EXTENSION,
+            }[self.type]
+            #append the missing file extension if the filter matches
+            if path.splitext(filename)[1].lower() != extension: filename += extension
+            self.set_current_name(path.basename(filename)) #show the filename with extension
+            if path.exists(filename): #ask the user to confirm overwrite
+                if MessageDialogHelper(
+                    gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, 'Confirm Overwrite!',
+                    Utils.parse_template(FILE_OVERWRITE_MARKUP_TMPL, filename=filename),
+                ) == gtk.RESPONSE_NO: return self.get_rectified_filename()
+            return filename
+        #############################################
+        # Handle Open Dialogs
+        #############################################
+        elif self.type in (OPEN_FLOW_GRAPH,):
+            filenames = self.get_filenames()
+            for filename in filenames:
+                if not path.exists(filename): #show a warning and re-run
+                    MessageDialogHelper(
+                        gtk.MESSAGE_WARNING, gtk.BUTTONS_CLOSE, 'Cannot Open!',
+                        Utils.parse_template(FILE_DNE_MARKUP_TMPL, filename=filename),
+                    )
+                    return self.get_rectified_filename()
+            return filenames
+
+    def run(self):
+        """
+        Get the filename and destroy the dialog.
+        
+        Returns:
+            the filename or None if a close/cancel occured.
+        """
+        filename = self.get_rectified_filename()
+        self.destroy()
+        return filename
 
 class OpenFlowGraphFileDialog(FileDialog): type = OPEN_FLOW_GRAPH
 class SaveFlowGraphFileDialog(FileDialog): type = SAVE_FLOW_GRAPH
diff --git a/grc/gui/FlowGraph.py b/grc/gui/FlowGraph.py
index a238ed166a..4dff675afb 100644
--- a/grc/gui/FlowGraph.py
+++ b/grc/gui/FlowGraph.py
@@ -29,548 +29,537 @@ import random
 import Messages
 
 class FlowGraph(Element):
-	"""
-	FlowGraph is the data structure to store graphical signal blocks,
-	graphical inputs and outputs,
-	and the connections between inputs and outputs.
-	"""
-
-	def __init__(self):
-		"""
-		FlowGraph contructor.
-		Create a list for signal blocks and connections. Connect mouse handlers.
-		"""
-		Element.__init__(self)
-		#when is the flow graph selected? (used by keyboard event handler)
-		self.is_selected = lambda: bool(self.get_selected_elements())
-		#important vars dealing with mouse event tracking
-		self.element_moved = False
-		self.mouse_pressed = False
-		self.unselect()
-		self.press_coor = (0, 0)
-		#selected ports
-		self._old_selected_port = None
-		self._new_selected_port = None
-		#context menu
-		self._context_menu = gtk.Menu()
-		for action in [
-			Actions.BLOCK_CUT,
-			Actions.BLOCK_COPY,
-			Actions.BLOCK_PASTE,
-			Actions.ELEMENT_DELETE,
-			Actions.BLOCK_ROTATE_CCW,
-			Actions.BLOCK_ROTATE_CW,
-			Actions.BLOCK_ENABLE,
-			Actions.BLOCK_DISABLE,
-			Actions.BLOCK_PARAM_MODIFY,
-			Actions.BLOCK_CREATE_HIER,
-			Actions.OPEN_HIER,
-			Actions.BUSSIFY_SOURCES,
-			Actions.BUSSIFY_SINKS,
-		]: self._context_menu.append(action.create_menu_item())
-
-	###########################################################################
-	# Access Drawing Area
-	###########################################################################
-	def get_drawing_area(self): return self.drawing_area
-	def queue_draw(self): self.get_drawing_area().queue_draw()
-	def get_size(self): return self.get_drawing_area().get_size_request()
-	def set_size(self, *args): self.get_drawing_area().set_size_request(*args)
-	def get_scroll_pane(self): return self.drawing_area.get_parent()
-	def get_ctrl_mask(self): return self.drawing_area.ctrl_mask
-	def new_pixmap(self, *args): return self.get_drawing_area().new_pixmap(*args)
-
-	def add_new_block(self, key, coor=None):
-		"""
-		Add a block of the given key to this flow graph.
-		
-		Args:
-		    key: the block key
-		    coor: an optional coordinate or None for random
-		"""
-		id = self._get_unique_id(key)
-		#calculate the position coordinate
-		h_adj = self.get_scroll_pane().get_hadjustment()
-		v_adj = self.get_scroll_pane().get_vadjustment()
-		if coor is None: coor = (
-			int(random.uniform(.25, .75)*h_adj.page_size + h_adj.get_value()),
-			int(random.uniform(.25, .75)*v_adj.page_size + v_adj.get_value()),
-		)
-		#get the new block
-		block = self.get_new_block(key)
-		block.set_coordinate(coor)
-		block.set_rotation(0)
-		block.get_param('id').set_value(id)
-		Actions.ELEMENT_CREATE()
-
-                return id
-
-	###########################################################################
-	# Copy Paste
-	###########################################################################
-	def copy_to_clipboard(self):
-		"""
-		Copy the selected blocks and connections into the clipboard.
-		
-		Returns:
-		    the clipboard
-		"""
-		#get selected blocks
-		blocks = self.get_selected_blocks()
-		if not blocks: return None
-		#calc x and y min
-		x_min, y_min = blocks[0].get_coordinate()
-		for block in blocks:
-			x, y = block.get_coordinate()
-			x_min = min(x, x_min)
-			y_min = min(y, y_min)
-		#get connections between selected blocks
-		connections = filter(
-			lambda c: c.get_source().get_parent() in blocks and c.get_sink().get_parent() in blocks,
-			self.get_connections(),
-		)
-		clipboard = (
-			(x_min, y_min),
-			[block.export_data() for block in blocks],
-			[connection.export_data() for connection in connections],
-		)
-		return clipboard
-
-	def paste_from_clipboard(self, clipboard):
-		"""
-		Paste the blocks and connections from the clipboard.
-		
-		Args:
-		    clipboard: the nested data of blocks, connections
-		"""
-
-		selected = set()
-		(x_min, y_min), blocks_n, connections_n = clipboard
-		old_id2block = dict()
-		#recalc the position
-		h_adj = self.get_scroll_pane().get_hadjustment()
-		v_adj = self.get_scroll_pane().get_vadjustment()
-		x_off = h_adj.get_value() - x_min + h_adj.page_size/4
-		y_off = v_adj.get_value() - y_min + v_adj.page_size/4
-		#create blocks
-		for block_n in blocks_n:
-			block_key = block_n.find('key')
-			if block_key == 'options': continue
-			block = self.get_new_block(block_key)
-			selected.add(block)
-			#set params
-			params_n = block_n.findall('param')
-			for param_n in params_n:
-				
-				param_key = param_n.find('key')
-				param_value = param_n.find('value')
-				#setup id parameter
-				if param_key == 'id':
-					old_id2block[param_value] = block
-					#if the block id is not unique, get a new block id
-					if param_value in [bluck.get_id() for bluck in self.get_blocks()]:
-						param_value = self._get_unique_id(param_value)
-					
-				
-				#set value to key
-				
-				block.get_param(param_key).set_value(param_value)
-			#move block to offset coordinate
-			block.move((x_off, y_off))
-			
-		#update before creating connections
-		self.update()
-		#create connections
-		for connection_n in connections_n:
-			source = old_id2block[connection_n.find('source_block_id')].get_source(connection_n.find('source_key'))
-			sink = old_id2block[connection_n.find('sink_block_id')].get_sink(connection_n.find('sink_key'))
-			self.connect(source, sink)
-		#set all pasted elements selected
-		for block in selected: selected = selected.union(set(block.get_connections()))
-		self._selected_elements = list(selected)
-
-	###########################################################################
-	# Modify Selected
-	###########################################################################
-	def type_controller_modify_selected(self, direction):
-		"""
-		Change the registered type controller for the selected signal blocks.
-		
-		Args:
-		    direction: +1 or -1
-		
-		Returns:
-		    true for change
-		"""
-		return any([sb.type_controller_modify(direction) for sb in self.get_selected_blocks()])
-
-	def port_controller_modify_selected(self, direction):
-		"""
-		Change port controller for the selected signal blocks.
-		
-		Args:
-		    direction: +1 or -1
-		
-		Returns:
-		    true for changed
-		"""
-		return any([sb.port_controller_modify(direction) for sb in self.get_selected_blocks()])
-
-	def enable_selected(self, enable):
-		"""
-		Enable/disable the selected blocks.
-		
-		Args:
-		    enable: true to enable
-		
-		Returns:
-		    true if changed
-		"""
-		changed = False
-		for selected_block in self.get_selected_blocks():
-			if selected_block.get_enabled() != enable:
-				selected_block.set_enabled(enable)
-				changed = True
-		return changed
-
-	def move_selected(self, delta_coordinate):
-		"""
-		Move the element and by the change in coordinates.
-		
-		Args:
-		    delta_coordinate: the change in coordinates
-		"""
-		for selected_block in self.get_selected_blocks():
-			selected_block.move(delta_coordinate)
-			self.element_moved = True
-
-	def rotate_selected(self, rotation):
-		"""
-		Rotate the selected blocks by multiples of 90 degrees.
-		
-		Args:
-		    rotation: the rotation in degrees
-		
-		Returns:
-		    true if changed, otherwise false.
-		"""
-		if not self.get_selected_blocks(): return False
-		#initialize min and max coordinates
-		min_x, min_y = self.get_selected_block().get_coordinate()
-		max_x, max_y = self.get_selected_block().get_coordinate()
-		#rotate each selected block, and find min/max coordinate
-		for selected_block in self.get_selected_blocks():
-			selected_block.rotate(rotation)
-			#update the min/max coordinate
-			x, y = selected_block.get_coordinate()
-			min_x, min_y = min(min_x, x), min(min_y, y)
-			max_x, max_y = max(max_x, x), max(max_y, y)
-		#calculate center point of slected blocks
-		ctr_x, ctr_y = (max_x + min_x)/2, (max_y + min_y)/2
-		#rotate the blocks around the center point
-		for selected_block in self.get_selected_blocks():
-			x, y = selected_block.get_coordinate()
-			x, y = Utils.get_rotated_coordinate((x - ctr_x, y - ctr_y), rotation)
-			selected_block.set_coordinate((x + ctr_x, y + ctr_y))
-		return True
-
-	def remove_selected(self):
-		"""
-		Remove selected elements
-		
-		Returns:
-		    true if changed.
-		"""
-		changed = False
-		for selected_element in self.get_selected_elements():
-			self.remove_element(selected_element)
-			changed = True
-		return changed
-
-	def draw(self, gc, window):
-		"""
-		Draw the background and grid if enabled.
-		Draw all of the elements in this flow graph onto the pixmap.
-		Draw the pixmap to the drawable window of this flow graph.
-		"""
-		W,H = self.get_size()
-		#draw the background
-		gc.set_foreground(Colors.FLOWGRAPH_BACKGROUND_COLOR)
-		window.draw_rectangle(gc, True, 0, 0, W, H)
-		#draw multi select rectangle
-		if self.mouse_pressed and (not self.get_selected_elements() or self.get_ctrl_mask()):
-			#coordinates
-			x1, y1 = self.press_coor
-			x2, y2 = self.get_coordinate()
-			#calculate top-left coordinate and width/height
-			x, y = int(min(x1, x2)), int(min(y1, y2))
-			w, h = int(abs(x1 - x2)), int(abs(y1 - y2))
-			#draw
-			gc.set_foreground(Colors.HIGHLIGHT_COLOR)
-			window.draw_rectangle(gc, True, x, y, w, h)
-			gc.set_foreground(Colors.BORDER_COLOR)
-			window.draw_rectangle(gc, False, x, y, w, h)
-		#draw blocks on top of connections
-		for element in self.get_connections() + self.get_blocks():
-			element.draw(gc, window)
-		#draw selected blocks on top of selected connections
-		for selected_element in self.get_selected_connections() + self.get_selected_blocks():
-			selected_element.draw(gc, window)
-
-	def update_selected(self):
-		"""
-		Remove deleted elements from the selected elements list.
-		Update highlighting so only the selected are highlighted.
-		"""
-		selected_elements = self.get_selected_elements()
-		elements = self.get_elements()
-		#remove deleted elements
-		for selected in selected_elements:
-			if selected in elements: continue
-			selected_elements.remove(selected)
-		if self._old_selected_port and self._old_selected_port.get_parent() not in elements:
-			self._old_selected_port = None
-		if self._new_selected_port and self._new_selected_port.get_parent() not in elements:
-			self._new_selected_port = None
-		#update highlighting
-		for element in elements:
-			element.set_highlighted(element in selected_elements)
-
-	def update(self):
-		"""
-		Call the top level rewrite and validate.
-		Call the top level create labels and shapes.
-		"""
-	
-		self.rewrite()
-	
-		self.validate()
-	
-		self.create_labels()
-	
-		self.create_shapes()
-
-	##########################################################################
-	## Get Selected
-	##########################################################################
-	def unselect(self):
-		"""
-		Set selected elements to an empty set.
-		"""
-		self._selected_elements = []
-
-	def what_is_selected(self, coor, coor_m=None):
-		"""
-		What is selected?
-		At the given coordinate, return the elements found to be selected.
-		If coor_m is unspecified, return a list of only 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. Update the selected port information.
-		
-		Args:
-		    coor: the coordinate of the mouse click
-		    coor_m: the coordinate for multi select
-		
-		Returns:
-		    the selected blocks and connections or an empty list
-		"""
-		selected_port = None
-		selected = set()
-		#check the elements
-		for element in reversed(self.get_elements()):
-			selected_element = element.what_is_selected(coor, coor_m)
-			if not selected_element: continue
-			#update the selected port information
-			if selected_element.is_port():
-				if not coor_m: selected_port = selected_element
-				selected_element = selected_element.get_parent()
-			selected.add(selected_element)
-			#place at the end of the list
-			self.get_elements().remove(element)
-			self.get_elements().append(element)
-			#single select mode, break
-			if not coor_m: break
-		#update selected ports
-		self._old_selected_port = self._new_selected_port
-		self._new_selected_port = selected_port
-		return list(selected)
-
-	def get_selected_connections(self):
-		"""
-		Get a group of selected connections.
-		
-		Returns:
-		    sub set of connections in this flow graph
-		"""
-		selected = set()
-		for selected_element in self.get_selected_elements():
-			if selected_element.is_connection(): selected.add(selected_element)
-		return list(selected)
-
-	def get_selected_blocks(self):
-		"""
-		Get a group of selected blocks.
-		
-		Returns:
-		    sub set of blocks in this flow graph
-		"""
-		selected = set()
-		for selected_element in self.get_selected_elements():
-			if selected_element.is_block(): selected.add(selected_element)
-		return list(selected)
-
-	def get_selected_block(self):
-		"""
-		Get the selected block when a block or port is selected.
-		
-		Returns:
-		    a block or None
-		"""
-		return self.get_selected_blocks() and self.get_selected_blocks()[0] or None
-
-	def get_selected_elements(self):
-		"""
-		Get the group of selected elements.
-		
-		Returns:
-		    sub set of elements in this flow graph
-		"""
-		return self._selected_elements
-
-	def get_selected_element(self):
-		"""
-		Get the selected element.
-		
-		Returns:
-		    a block, port, or connection or None
-		"""
-		return self.get_selected_elements() and self.get_selected_elements()[0] or None
-
-	def update_selected_elements(self):
-		"""
-		Update the selected elements.
-		The update behavior depends on the state of the mouse button.
-		When the mouse button pressed the selection will change when
-		the control mask is set or the new selection is not in the current group.
-		When the mouse button is released the selection will change when
-		the mouse has moved and the control mask is set or the current group is empty.
-		Attempt to make a new connection if the old and ports are filled.
-		If the control mask is set, merge with the current elements.
-		"""
-		selected_elements = None
-		if self.mouse_pressed:
-			new_selections = self.what_is_selected(self.get_coordinate())
-			#update the selections if the new selection is not in the current selections
-			#allows us to move entire selected groups of elements
-			if self.get_ctrl_mask() or not (
-				new_selections and new_selections[0] in self.get_selected_elements()
-			): selected_elements = new_selections
-		else: #called from a mouse release
-			if not self.element_moved and (not self.get_selected_elements() or self.get_ctrl_mask()):
-				selected_elements = self.what_is_selected(self.get_coordinate(), self.press_coor)
-		#this selection and the last were ports, try to connect them
-		if self._old_selected_port and self._new_selected_port and \
-			self._old_selected_port is not self._new_selected_port:
-			try:
-				self.connect(self._old_selected_port, self._new_selected_port)
-				Actions.ELEMENT_CREATE()
-			except: Messages.send_fail_connection()
-			self._old_selected_port = None
-			self._new_selected_port = None
-			return
-		#update selected elements
-		if selected_elements is None: return
-		old_elements = set(self.get_selected_elements())
-		self._selected_elements = list(set(selected_elements))
-		new_elements = set(self.get_selected_elements())
-		#if ctrl, set the selected elements to the union - intersection of old and new
-		if self.get_ctrl_mask():
-			self._selected_elements = list(
-				set.union(old_elements, new_elements) - set.intersection(old_elements, new_elements)
-			)
-		Actions.ELEMENT_SELECT()
-
-	##########################################################################
-	## Event Handlers
-	##########################################################################
-	def handle_mouse_context_press(self, coordinate, event):
-		"""
-		The context mouse button was pressed:
-		If no elements were selected, perform re-selection at this coordinate.
-		Then, show the context menu at the mouse click location.
-		"""
-		selections = self.what_is_selected(coordinate)
-		if not set(selections).intersection(self.get_selected_elements()):
-			self.set_coordinate(coordinate)
-			self.mouse_pressed = True
-			self.update_selected_elements()
-			self.mouse_pressed = False
-		self._context_menu.popup(None, None, None, event.button, event.time)
-
-	def handle_mouse_selector_press(self, double_click, coordinate):
-		"""
-		The selector mouse button was pressed:
-		Find the selected element. Attempt a new connection if possible.
-		Open the block params window on a double click.
-		Update the selection state of the flow graph.
-		"""
-		self.press_coor = coordinate
-		self.set_coordinate(coordinate)
-		self.time = 0
-		self.mouse_pressed = True
-		if double_click: self.unselect()
-		self.update_selected_elements()
-		#double click detected, bring up params dialog if possible
-		if double_click and self.get_selected_block():
-			self.mouse_pressed = False
-			Actions.BLOCK_PARAM_MODIFY()
-
-	def handle_mouse_selector_release(self, coordinate):
-		"""
-		The selector mouse button was released:
-		Update the state, handle motion (dragging).
-		And update the selected flowgraph elements.
-		"""
-		self.set_coordinate(coordinate)
-		self.time = 0
-		self.mouse_pressed = False
-		if self.element_moved:
-			Actions.BLOCK_MOVE()
-			self.element_moved = False
-		self.update_selected_elements()
-
-	def handle_mouse_motion(self, coordinate):
-		"""
-		The mouse has moved, respond to mouse dragging.
-		Move a selected element to the new coordinate.
-		Auto-scroll the scroll bars at the boundaries.
-		"""
-		#to perform a movement, the mouse must be pressed
-		# (no longer checking pending events via gtk.events_pending() - always true in Windows)
-		if not self.mouse_pressed: return
-		#perform autoscrolling
-		width, height = self.get_size()
-		x, y = coordinate
-		h_adj = self.get_scroll_pane().get_hadjustment()
-		v_adj = self.get_scroll_pane().get_vadjustment()
-		for pos, length, adj, adj_val, adj_len in (
-			(x, width, h_adj, h_adj.get_value(), h_adj.page_size),
-			(y, height, v_adj, v_adj.get_value(), v_adj.page_size),
-		):
-			#scroll if we moved near the border
-			if pos-adj_val > adj_len-SCROLL_PROXIMITY_SENSITIVITY and adj_val+SCROLL_DISTANCE < length-adj_len:
-				adj.set_value(adj_val+SCROLL_DISTANCE)
-				adj.emit('changed')
-			elif pos-adj_val < SCROLL_PROXIMITY_SENSITIVITY:
-				adj.set_value(adj_val-SCROLL_DISTANCE)
-				adj.emit('changed')
-		#remove the connection if selected in drag event
-		if len(self.get_selected_elements()) == 1 and self.get_selected_element().is_connection():
-			Actions.ELEMENT_DELETE()
-		#move the selected elements and record the new coordinate
-		X, Y = self.get_coordinate()
-		if not self.get_ctrl_mask(): self.move_selected((int(x - X), int(y - Y)))
-		self.set_coordinate((x, y))
-		#queue draw for animation
-		self.queue_draw()
+    """
+    FlowGraph is the data structure to store graphical signal blocks,
+    graphical inputs and outputs,
+    and the connections between inputs and outputs.
+    """
+
+    def __init__(self):
+        """
+        FlowGraph contructor.
+        Create a list for signal blocks and connections. Connect mouse handlers.
+        """
+        Element.__init__(self)
+        #when is the flow graph selected? (used by keyboard event handler)
+        self.is_selected = lambda: bool(self.get_selected_elements())
+        #important vars dealing with mouse event tracking
+        self.element_moved = False
+        self.mouse_pressed = False
+        self.unselect()
+        self.press_coor = (0, 0)
+        #selected ports
+        self._old_selected_port = None
+        self._new_selected_port = None
+        #context menu
+        self._context_menu = gtk.Menu()
+        for action in [
+            Actions.BLOCK_CUT,
+            Actions.BLOCK_COPY,
+            Actions.BLOCK_PASTE,
+            Actions.ELEMENT_DELETE,
+            Actions.BLOCK_ROTATE_CCW,
+            Actions.BLOCK_ROTATE_CW,
+            Actions.BLOCK_ENABLE,
+            Actions.BLOCK_DISABLE,
+            Actions.BLOCK_PARAM_MODIFY,
+            Actions.BLOCK_CREATE_HIER,
+            Actions.OPEN_HIER,
+            Actions.BUSSIFY_SOURCES,
+            Actions.BUSSIFY_SINKS,
+        ]: self._context_menu.append(action.create_menu_item())
+
+    ###########################################################################
+    # Access Drawing Area
+    ###########################################################################
+    def get_drawing_area(self): return self.drawing_area
+    def queue_draw(self): self.get_drawing_area().queue_draw()
+    def get_size(self): return self.get_drawing_area().get_size_request()
+    def set_size(self, *args): self.get_drawing_area().set_size_request(*args)
+    def get_scroll_pane(self): return self.drawing_area.get_parent()
+    def get_ctrl_mask(self): return self.drawing_area.ctrl_mask
+    def new_pixmap(self, *args): return self.get_drawing_area().new_pixmap(*args)
+
+    def add_new_block(self, key, coor=None):
+        """
+        Add a block of the given key to this flow graph.
+        
+        Args:
+            key: the block key
+            coor: an optional coordinate or None for random
+        """
+        id = self._get_unique_id(key)
+        #calculate the position coordinate
+        h_adj = self.get_scroll_pane().get_hadjustment()
+        v_adj = self.get_scroll_pane().get_vadjustment()
+        if coor is None: coor = (
+            int(random.uniform(.25, .75)*h_adj.page_size + h_adj.get_value()),
+            int(random.uniform(.25, .75)*v_adj.page_size + v_adj.get_value()),
+        )
+        #get the new block
+        block = self.get_new_block(key)
+        block.set_coordinate(coor)
+        block.set_rotation(0)
+        block.get_param('id').set_value(id)
+        Actions.ELEMENT_CREATE()
+        return id
+
+    ###########################################################################
+    # Copy Paste
+    ###########################################################################
+    def copy_to_clipboard(self):
+        """
+        Copy the selected blocks and connections into the clipboard.
+        
+        Returns:
+            the clipboard
+        """
+        #get selected blocks
+        blocks = self.get_selected_blocks()
+        if not blocks: return None
+        #calc x and y min
+        x_min, y_min = blocks[0].get_coordinate()
+        for block in blocks:
+            x, y = block.get_coordinate()
+            x_min = min(x, x_min)
+            y_min = min(y, y_min)
+        #get connections between selected blocks
+        connections = filter(
+            lambda c: c.get_source().get_parent() in blocks and c.get_sink().get_parent() in blocks,
+            self.get_connections(),
+        )
+        clipboard = (
+            (x_min, y_min),
+            [block.export_data() for block in blocks],
+            [connection.export_data() for connection in connections],
+        )
+        return clipboard
+
+    def paste_from_clipboard(self, clipboard):
+        """
+        Paste the blocks and connections from the clipboard.
+        
+        Args:
+            clipboard: the nested data of blocks, connections
+        """
+        selected = set()
+        (x_min, y_min), blocks_n, connections_n = clipboard
+        old_id2block = dict()
+        #recalc the position
+        h_adj = self.get_scroll_pane().get_hadjustment()
+        v_adj = self.get_scroll_pane().get_vadjustment()
+        x_off = h_adj.get_value() - x_min + h_adj.page_size/4
+        y_off = v_adj.get_value() - y_min + v_adj.page_size/4
+        #create blocks
+        for block_n in blocks_n:
+            block_key = block_n.find('key')
+            if block_key == 'options': continue
+            block = self.get_new_block(block_key)
+            selected.add(block)
+            #set params
+            params_n = block_n.findall('param')
+            for param_n in params_n:
+                param_key = param_n.find('key')
+                param_value = param_n.find('value')
+                #setup id parameter
+                if param_key == 'id':
+                    old_id2block[param_value] = block
+                    #if the block id is not unique, get a new block id
+                    if param_value in [bluck.get_id() for bluck in self.get_blocks()]:
+                        param_value = self._get_unique_id(param_value)
+                #set value to key
+                block.get_param(param_key).set_value(param_value)
+            #move block to offset coordinate
+            block.move((x_off, y_off))
+        #update before creating connections
+        self.update()
+        #create connections
+        for connection_n in connections_n:
+            source = old_id2block[connection_n.find('source_block_id')].get_source(connection_n.find('source_key'))
+            sink = old_id2block[connection_n.find('sink_block_id')].get_sink(connection_n.find('sink_key'))
+            self.connect(source, sink)
+        #set all pasted elements selected
+        for block in selected: selected = selected.union(set(block.get_connections()))
+        self._selected_elements = list(selected)
+
+    ###########################################################################
+    # Modify Selected
+    ###########################################################################
+    def type_controller_modify_selected(self, direction):
+        """
+        Change the registered type controller for the selected signal blocks.
+        
+        Args:
+            direction: +1 or -1
+        
+        Returns:
+            true for change
+        """
+        return any([sb.type_controller_modify(direction) for sb in self.get_selected_blocks()])
+
+    def port_controller_modify_selected(self, direction):
+        """
+        Change port controller for the selected signal blocks.
+        
+        Args:
+            direction: +1 or -1
+        
+        Returns:
+            true for changed
+        """
+        return any([sb.port_controller_modify(direction) for sb in self.get_selected_blocks()])
+
+    def enable_selected(self, enable):
+        """
+        Enable/disable the selected blocks.
+        
+        Args:
+            enable: true to enable
+        
+        Returns:
+            true if changed
+        """
+        changed = False
+        for selected_block in self.get_selected_blocks():
+            if selected_block.get_enabled() != enable:
+                selected_block.set_enabled(enable)
+                changed = True
+        return changed
+
+    def move_selected(self, delta_coordinate):
+        """
+        Move the element and by the change in coordinates.
+        
+        Args:
+            delta_coordinate: the change in coordinates
+        """
+        for selected_block in self.get_selected_blocks():
+            selected_block.move(delta_coordinate)
+            self.element_moved = True
+
+    def rotate_selected(self, rotation):
+        """
+        Rotate the selected blocks by multiples of 90 degrees.
+        
+        Args:
+            rotation: the rotation in degrees
+        
+        Returns:
+            true if changed, otherwise false.
+        """
+        if not self.get_selected_blocks(): return False
+        #initialize min and max coordinates
+        min_x, min_y = self.get_selected_block().get_coordinate()
+        max_x, max_y = self.get_selected_block().get_coordinate()
+        #rotate each selected block, and find min/max coordinate
+        for selected_block in self.get_selected_blocks():
+            selected_block.rotate(rotation)
+            #update the min/max coordinate
+            x, y = selected_block.get_coordinate()
+            min_x, min_y = min(min_x, x), min(min_y, y)
+            max_x, max_y = max(max_x, x), max(max_y, y)
+        #calculate center point of slected blocks
+        ctr_x, ctr_y = (max_x + min_x)/2, (max_y + min_y)/2
+        #rotate the blocks around the center point
+        for selected_block in self.get_selected_blocks():
+            x, y = selected_block.get_coordinate()
+            x, y = Utils.get_rotated_coordinate((x - ctr_x, y - ctr_y), rotation)
+            selected_block.set_coordinate((x + ctr_x, y + ctr_y))
+        return True
+
+    def remove_selected(self):
+        """
+        Remove selected elements
+        
+        Returns:
+            true if changed.
+        """
+        changed = False
+        for selected_element in self.get_selected_elements():
+            self.remove_element(selected_element)
+            changed = True
+        return changed
+
+    def draw(self, gc, window):
+        """
+        Draw the background and grid if enabled.
+        Draw all of the elements in this flow graph onto the pixmap.
+        Draw the pixmap to the drawable window of this flow graph.
+        """
+        W,H = self.get_size()
+        #draw the background
+        gc.set_foreground(Colors.FLOWGRAPH_BACKGROUND_COLOR)
+        window.draw_rectangle(gc, True, 0, 0, W, H)
+        #draw multi select rectangle
+        if self.mouse_pressed and (not self.get_selected_elements() or self.get_ctrl_mask()):
+            #coordinates
+            x1, y1 = self.press_coor
+            x2, y2 = self.get_coordinate()
+            #calculate top-left coordinate and width/height
+            x, y = int(min(x1, x2)), int(min(y1, y2))
+            w, h = int(abs(x1 - x2)), int(abs(y1 - y2))
+            #draw
+            gc.set_foreground(Colors.HIGHLIGHT_COLOR)
+            window.draw_rectangle(gc, True, x, y, w, h)
+            gc.set_foreground(Colors.BORDER_COLOR)
+            window.draw_rectangle(gc, False, x, y, w, h)
+        #draw blocks on top of connections
+        for element in self.get_connections() + self.get_blocks():
+            element.draw(gc, window)
+        #draw selected blocks on top of selected connections
+        for selected_element in self.get_selected_connections() + self.get_selected_blocks():
+            selected_element.draw(gc, window)
+
+    def update_selected(self):
+        """
+        Remove deleted elements from the selected elements list.
+        Update highlighting so only the selected are highlighted.
+        """
+        selected_elements = self.get_selected_elements()
+        elements = self.get_elements()
+        #remove deleted elements
+        for selected in selected_elements:
+            if selected in elements: continue
+            selected_elements.remove(selected)
+        if self._old_selected_port and self._old_selected_port.get_parent() not in elements:
+            self._old_selected_port = None
+        if self._new_selected_port and self._new_selected_port.get_parent() not in elements:
+            self._new_selected_port = None
+        #update highlighting
+        for element in elements:
+            element.set_highlighted(element in selected_elements)
+
+    def update(self):
+        """
+        Call the top level rewrite and validate.
+        Call the top level create labels and shapes.
+        """
+        self.rewrite()
+        self.validate()
+        self.create_labels()
+        self.create_shapes()
+
+    ##########################################################################
+    ## Get Selected
+    ##########################################################################
+    def unselect(self):
+        """
+        Set selected elements to an empty set.
+        """
+        self._selected_elements = []
+
+    def what_is_selected(self, coor, coor_m=None):
+        """
+        What is selected?
+        At the given coordinate, return the elements found to be selected.
+        If coor_m is unspecified, return a list of only 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. Update the selected port information.
+        
+        Args:
+            coor: the coordinate of the mouse click
+            coor_m: the coordinate for multi select
+        
+        Returns:
+            the selected blocks and connections or an empty list
+        """
+        selected_port = None
+        selected = set()
+        #check the elements
+        for element in reversed(self.get_elements()):
+            selected_element = element.what_is_selected(coor, coor_m)
+            if not selected_element: continue
+            #update the selected port information
+            if selected_element.is_port():
+                if not coor_m: selected_port = selected_element
+                selected_element = selected_element.get_parent()
+            selected.add(selected_element)
+            #place at the end of the list
+            self.get_elements().remove(element)
+            self.get_elements().append(element)
+            #single select mode, break
+            if not coor_m: break
+        #update selected ports
+        self._old_selected_port = self._new_selected_port
+        self._new_selected_port = selected_port
+        return list(selected)
+
+    def get_selected_connections(self):
+        """
+        Get a group of selected connections.
+        
+        Returns:
+            sub set of connections in this flow graph
+        """
+        selected = set()
+        for selected_element in self.get_selected_elements():
+            if selected_element.is_connection(): selected.add(selected_element)
+        return list(selected)
+
+    def get_selected_blocks(self):
+        """
+        Get a group of selected blocks.
+        
+        Returns:
+            sub set of blocks in this flow graph
+        """
+        selected = set()
+        for selected_element in self.get_selected_elements():
+            if selected_element.is_block(): selected.add(selected_element)
+        return list(selected)
+
+    def get_selected_block(self):
+        """
+        Get the selected block when a block or port is selected.
+        
+        Returns:
+            a block or None
+        """
+        return self.get_selected_blocks() and self.get_selected_blocks()[0] or None
+
+    def get_selected_elements(self):
+        """
+        Get the group of selected elements.
+        
+        Returns:
+            sub set of elements in this flow graph
+        """
+        return self._selected_elements
+
+    def get_selected_element(self):
+        """
+        Get the selected element.
+        
+        Returns:
+            a block, port, or connection or None
+        """
+        return self.get_selected_elements() and self.get_selected_elements()[0] or None
+
+    def update_selected_elements(self):
+        """
+        Update the selected elements.
+        The update behavior depends on the state of the mouse button.
+        When the mouse button pressed the selection will change when
+        the control mask is set or the new selection is not in the current group.
+        When the mouse button is released the selection will change when
+        the mouse has moved and the control mask is set or the current group is empty.
+        Attempt to make a new connection if the old and ports are filled.
+        If the control mask is set, merge with the current elements.
+        """
+        selected_elements = None
+        if self.mouse_pressed:
+            new_selections = self.what_is_selected(self.get_coordinate())
+            #update the selections if the new selection is not in the current selections
+            #allows us to move entire selected groups of elements
+            if self.get_ctrl_mask() or not (
+                new_selections and new_selections[0] in self.get_selected_elements()
+            ): selected_elements = new_selections
+        else: #called from a mouse release
+            if not self.element_moved and (not self.get_selected_elements() or self.get_ctrl_mask()):
+                selected_elements = self.what_is_selected(self.get_coordinate(), self.press_coor)
+        #this selection and the last were ports, try to connect them
+        if self._old_selected_port and self._new_selected_port and \
+            self._old_selected_port is not self._new_selected_port:
+            try:
+                self.connect(self._old_selected_port, self._new_selected_port)
+                Actions.ELEMENT_CREATE()
+            except: Messages.send_fail_connection()
+            self._old_selected_port = None
+            self._new_selected_port = None
+            return
+        #update selected elements
+        if selected_elements is None: return
+        old_elements = set(self.get_selected_elements())
+        self._selected_elements = list(set(selected_elements))
+        new_elements = set(self.get_selected_elements())
+        #if ctrl, set the selected elements to the union - intersection of old and new
+        if self.get_ctrl_mask():
+            self._selected_elements = list(
+                set.union(old_elements, new_elements) - set.intersection(old_elements, new_elements)
+            )
+        Actions.ELEMENT_SELECT()
+
+    ##########################################################################
+    ## Event Handlers
+    ##########################################################################
+    def handle_mouse_context_press(self, coordinate, event):
+        """
+        The context mouse button was pressed:
+        If no elements were selected, perform re-selection at this coordinate.
+        Then, show the context menu at the mouse click location.
+        """
+        selections = self.what_is_selected(coordinate)
+        if not set(selections).intersection(self.get_selected_elements()):
+            self.set_coordinate(coordinate)
+            self.mouse_pressed = True
+            self.update_selected_elements()
+            self.mouse_pressed = False
+        self._context_menu.popup(None, None, None, event.button, event.time)
+
+    def handle_mouse_selector_press(self, double_click, coordinate):
+        """
+        The selector mouse button was pressed:
+        Find the selected element. Attempt a new connection if possible.
+        Open the block params window on a double click.
+        Update the selection state of the flow graph.
+        """
+        self.press_coor = coordinate
+        self.set_coordinate(coordinate)
+        self.time = 0
+        self.mouse_pressed = True
+        if double_click: self.unselect()
+        self.update_selected_elements()
+        #double click detected, bring up params dialog if possible
+        if double_click and self.get_selected_block():
+            self.mouse_pressed = False
+            Actions.BLOCK_PARAM_MODIFY()
+
+    def handle_mouse_selector_release(self, coordinate):
+        """
+        The selector mouse button was released:
+        Update the state, handle motion (dragging).
+        And update the selected flowgraph elements.
+        """
+        self.set_coordinate(coordinate)
+        self.time = 0
+        self.mouse_pressed = False
+        if self.element_moved:
+            Actions.BLOCK_MOVE()
+            self.element_moved = False
+        self.update_selected_elements()
+
+    def handle_mouse_motion(self, coordinate):
+        """
+        The mouse has moved, respond to mouse dragging.
+        Move a selected element to the new coordinate.
+        Auto-scroll the scroll bars at the boundaries.
+        """
+        #to perform a movement, the mouse must be pressed
+        # (no longer checking pending events via gtk.events_pending() - always true in Windows)
+        if not self.mouse_pressed: return
+        #perform autoscrolling
+        width, height = self.get_size()
+        x, y = coordinate
+        h_adj = self.get_scroll_pane().get_hadjustment()
+        v_adj = self.get_scroll_pane().get_vadjustment()
+        for pos, length, adj, adj_val, adj_len in (
+            (x, width, h_adj, h_adj.get_value(), h_adj.page_size),
+            (y, height, v_adj, v_adj.get_value(), v_adj.page_size),
+        ):
+            #scroll if we moved near the border
+            if pos-adj_val > adj_len-SCROLL_PROXIMITY_SENSITIVITY and adj_val+SCROLL_DISTANCE < length-adj_len:
+                adj.set_value(adj_val+SCROLL_DISTANCE)
+                adj.emit('changed')
+            elif pos-adj_val < SCROLL_PROXIMITY_SENSITIVITY:
+                adj.set_value(adj_val-SCROLL_DISTANCE)
+                adj.emit('changed')
+        #remove the connection if selected in drag event
+        if len(self.get_selected_elements()) == 1 and self.get_selected_element().is_connection():
+            Actions.ELEMENT_DELETE()
+        #move the selected elements and record the new coordinate
+        X, Y = self.get_coordinate()
+        if not self.get_ctrl_mask(): self.move_selected((int(x - X), int(y - Y)))
+        self.set_coordinate((x, y))
+        #queue draw for animation
+        self.queue_draw()
diff --git a/grc/gui/MainWindow.py b/grc/gui/MainWindow.py
index c2d661c668..677f202e1f 100644
--- a/grc/gui/MainWindow.py
+++ b/grc/gui/MainWindow.py
@@ -18,7 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
 
 from Constants import \
-	NEW_FLOGRAPH_TITLE, DEFAULT_REPORTS_WINDOW_WIDTH
+    NEW_FLOGRAPH_TITLE, DEFAULT_REPORTS_WINDOW_WIDTH
 import Actions
 import pygtk
 pygtk.require('2.0')
@@ -63,293 +63,293 @@ PAGE_TITLE_MARKUP_TMPL = """\
 ############################################################
 
 class MainWindow(gtk.Window):
-	"""The topmost window with menus, the tool bar, and other major windows."""
+    """The topmost window with menus, the tool bar, and other major windows."""
 
-	def __init__(self, platform):
-		"""
-		MainWindow contructor
-		Setup the menu, toolbar, flowgraph editor notebook, block selection window...
-		"""
-		self._platform = platform
-		#setup window
-		gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
-		vbox = gtk.VBox()
-		self.hpaned = gtk.HPaned()
-		self.add(vbox)
-		#create the menu bar and toolbar
-		self.add_accel_group(Actions.get_accel_group())
-		vbox.pack_start(Bars.MenuBar(), False)
-		vbox.pack_start(Bars.Toolbar(), False)
-		vbox.pack_start(self.hpaned)
-		#create the notebook
-		self.notebook = gtk.Notebook()
-		self.page_to_be_closed = None
-		self.current_page = None
-		self.notebook.set_show_border(False)
-		self.notebook.set_scrollable(True) #scroll arrows for page tabs
-		self.notebook.connect('switch-page', self._handle_page_change)
-		#setup containers
-		self.flow_graph_vpaned = gtk.VPaned()
-		#flow_graph_box.pack_start(self.scrolled_window)
-		self.flow_graph_vpaned.pack1(self.notebook)
-		self.hpaned.pack1(self.flow_graph_vpaned)
-		self.btwin = BlockTreeWindow(platform, self.get_flow_graph);
-		self.hpaned.pack2(self.btwin, False) #dont allow resize
-		#create the reports window
-		self.text_display = TextDisplay()
-		#house the reports in a scrolled window
-		self.reports_scrolled_window = gtk.ScrolledWindow()
-		self.reports_scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
-		self.reports_scrolled_window.add_with_viewport(self.text_display)
-		self.reports_scrolled_window.set_size_request(-1, DEFAULT_REPORTS_WINDOW_WIDTH)
-		self.flow_graph_vpaned.pack2(self.reports_scrolled_window, False) #dont allow resize
-		#load preferences and show the main window
-		Preferences.load(platform)
-		self.resize(*Preferences.main_window_size())
-		self.flow_graph_vpaned.set_position(Preferences.reports_window_position())
-		self.hpaned.set_position(Preferences.blocks_window_position())
-		self.show_all()
+    def __init__(self, platform):
+        """
+        MainWindow contructor
+        Setup the menu, toolbar, flowgraph editor notebook, block selection window...
+        """
+        self._platform = platform
+        #setup window
+        gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
+        vbox = gtk.VBox()
+        self.hpaned = gtk.HPaned()
+        self.add(vbox)
+        #create the menu bar and toolbar
+        self.add_accel_group(Actions.get_accel_group())
+        vbox.pack_start(Bars.MenuBar(), False)
+        vbox.pack_start(Bars.Toolbar(), False)
+        vbox.pack_start(self.hpaned)
+        #create the notebook
+        self.notebook = gtk.Notebook()
+        self.page_to_be_closed = None
+        self.current_page = None
+        self.notebook.set_show_border(False)
+        self.notebook.set_scrollable(True) #scroll arrows for page tabs
+        self.notebook.connect('switch-page', self._handle_page_change)
+        #setup containers
+        self.flow_graph_vpaned = gtk.VPaned()
+        #flow_graph_box.pack_start(self.scrolled_window)
+        self.flow_graph_vpaned.pack1(self.notebook)
+        self.hpaned.pack1(self.flow_graph_vpaned)
+        self.btwin = BlockTreeWindow(platform, self.get_flow_graph);
+        self.hpaned.pack2(self.btwin, False) #dont allow resize
+        #create the reports window
+        self.text_display = TextDisplay()
+        #house the reports in a scrolled window
+        self.reports_scrolled_window = gtk.ScrolledWindow()
+        self.reports_scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+        self.reports_scrolled_window.add_with_viewport(self.text_display)
+        self.reports_scrolled_window.set_size_request(-1, DEFAULT_REPORTS_WINDOW_WIDTH)
+        self.flow_graph_vpaned.pack2(self.reports_scrolled_window, False) #dont allow resize
+        #load preferences and show the main window
+        Preferences.load(platform)
+        self.resize(*Preferences.main_window_size())
+        self.flow_graph_vpaned.set_position(Preferences.reports_window_position())
+        self.hpaned.set_position(Preferences.blocks_window_position())
+        self.show_all()
 
-	############################################################
-	# Event Handlers
-	############################################################
+    ############################################################
+    # Event Handlers
+    ############################################################
 
-	def _quit(self, window, event):
-		"""
-		Handle the delete event from the main window.
-		Generated by pressing X to close, alt+f4, or right click+close.
-		This method in turns calls the state handler to quit.
-		
-		Returns:
-		    true
-		"""
-		Actions.APPLICATION_QUIT()
-		return True
+    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.
+        
+        Returns:
+            true
+        """
+        Actions.APPLICATION_QUIT()
+        return True
 
-	def _handle_page_change(self, notebook, page, page_num):
-		"""
-		Handle a page change. When the user clicks on a new tab,
-		reload the flow graph to update the vars window and
-		call handle states (select nothing) to update the buttons.
-		
-		Args:
-		    notebook: the notebook
-		    page: new page
-		    page_num: new page number
-		"""
-		self.current_page = self.notebook.get_nth_page(page_num)
-		Messages.send_page_switch(self.current_page.get_file_path())
-		Actions.PAGE_CHANGE()
+    def _handle_page_change(self, notebook, page, page_num):
+        """
+        Handle a page change. When the user clicks on a new tab,
+        reload the flow graph to update the vars window and
+        call handle states (select nothing) to update the buttons.
+        
+        Args:
+            notebook: the notebook
+            page: new page
+            page_num: new page number
+        """
+        self.current_page = self.notebook.get_nth_page(page_num)
+        Messages.send_page_switch(self.current_page.get_file_path())
+        Actions.PAGE_CHANGE()
 
-	############################################################
-	# Report Window
-	############################################################
+    ############################################################
+    # Report Window
+    ############################################################
 
-	def add_report_line(self, line):
-		"""
-		Place line at the end of the text buffer, then scroll its window all the way down.
-		
-		Args:
-		    line: the new text
-		"""
-		self.text_display.insert(line)
-		vadj = self.reports_scrolled_window.get_vadjustment()
-		vadj.set_value(vadj.upper)
-		vadj.emit('changed')
+    def add_report_line(self, line):
+        """
+        Place line at the end of the text buffer, then scroll its window all the way down.
+        
+        Args:
+            line: the new text
+        """
+        self.text_display.insert(line)
+        vadj = self.reports_scrolled_window.get_vadjustment()
+        vadj.set_value(vadj.upper)
+        vadj.emit('changed')
 
-	############################################################
-	# Pages: create and close
-	############################################################
+    ############################################################
+    # Pages: create and close
+    ############################################################
 
-	def new_page(self, file_path='', show=False):
-		"""
-		Create a new notebook page.
-		Set the tab to be selected.
-		
-		Args:
-		    file_path: optional file to load into the flow graph
-		    show: true if the page should be shown after loading
-		"""
-		#if the file is already open, show the open page and return
-		if file_path and file_path in self._get_files(): #already open
-			page = self.notebook.get_nth_page(self._get_files().index(file_path))
-			self._set_page(page)
-			return
-		try: #try to load from file
-			if file_path: Messages.send_start_load(file_path)
-			flow_graph = self._platform.get_new_flow_graph()
-			flow_graph.grc_file_path = file_path;
-			#print flow_graph
-			page = NotebookPage(
-				self,
-				flow_graph=flow_graph,
-				file_path=file_path,
-			)
-			if file_path: Messages.send_end_load()
-		except Exception, e: #return on failure
-			Messages.send_fail_load(e)
-			if isinstance(e, KeyError) and str(e) == "'options'":
-				# This error is unrecoverable, so crash gracefully
-				exit(-1)
-			return
-		#add this page to the notebook
-		self.notebook.append_page(page, page.get_tab())
-		try: self.notebook.set_tab_reorderable(page, True)
-		except: pass #gtk too old
-		self.notebook.set_tab_label_packing(page, False, False, gtk.PACK_START)
-		#only show if blank or manual
-		if not file_path or show: self._set_page(page)
+    def new_page(self, file_path='', show=False):
+        """
+        Create a new notebook page.
+        Set the tab to be selected.
+        
+        Args:
+            file_path: optional file to load into the flow graph
+            show: true if the page should be shown after loading
+        """
+        #if the file is already open, show the open page and return
+        if file_path and file_path in self._get_files(): #already open
+            page = self.notebook.get_nth_page(self._get_files().index(file_path))
+            self._set_page(page)
+            return
+        try: #try to load from file
+            if file_path: Messages.send_start_load(file_path)
+            flow_graph = self._platform.get_new_flow_graph()
+            flow_graph.grc_file_path = file_path;
+            #print flow_graph
+            page = NotebookPage(
+                self,
+                flow_graph=flow_graph,
+                file_path=file_path,
+            )
+            if file_path: Messages.send_end_load()
+        except Exception, e: #return on failure
+            Messages.send_fail_load(e)
+            if isinstance(e, KeyError) and str(e) == "'options'":
+                # This error is unrecoverable, so crash gracefully
+                exit(-1)
+            return
+        #add this page to the notebook
+        self.notebook.append_page(page, page.get_tab())
+        try: self.notebook.set_tab_reorderable(page, True)
+        except: pass #gtk too old
+        self.notebook.set_tab_label_packing(page, False, False, gtk.PACK_START)
+        #only show if blank or manual
+        if not file_path or show: self._set_page(page)
 
-	def close_pages(self):
-		"""
-		Close all the pages in this notebook.
-		
-		Returns:
-		    true if all closed
-		"""
-		open_files = filter(lambda file: file, self._get_files()) #filter blank files
-		open_file = self.get_page().get_file_path()
-		#close each page
-		for page in self._get_pages():
-			self.page_to_be_closed = page
-			self.close_page(False)
-		if self.notebook.get_n_pages(): return False
-		#save state before closing
-		Preferences.files_open(open_files)
-		Preferences.file_open(open_file)
-		Preferences.main_window_size(self.get_size())
-		Preferences.reports_window_position(self.flow_graph_vpaned.get_position())
-		Preferences.blocks_window_position(self.hpaned.get_position())
-		Preferences.save()
-		return True
+    def close_pages(self):
+        """
+        Close all the pages in this notebook.
+        
+        Returns:
+            true if all closed
+        """
+        open_files = filter(lambda file: file, self._get_files()) #filter blank files
+        open_file = self.get_page().get_file_path()
+        #close each page
+        for page in self._get_pages():
+            self.page_to_be_closed = page
+            self.close_page(False)
+        if self.notebook.get_n_pages(): return False
+        #save state before closing
+        Preferences.files_open(open_files)
+        Preferences.file_open(open_file)
+        Preferences.main_window_size(self.get_size())
+        Preferences.reports_window_position(self.flow_graph_vpaned.get_position())
+        Preferences.blocks_window_position(self.hpaned.get_position())
+        Preferences.save()
+        return True
 
-	def close_page(self, ensure=True):
-		"""
-		Close the current page.
-		If the notebook becomes empty, and ensure is true,
-		call new page upon exit to ensure that at least one page exists.
-		
-		Args:
-		    ensure: boolean
-		"""
-		if not self.page_to_be_closed: self.page_to_be_closed = self.get_page()
-		#show the page if it has an executing flow graph or is unsaved
-		if self.page_to_be_closed.get_proc() or not self.page_to_be_closed.get_saved():
-			self._set_page(self.page_to_be_closed)
-		#unsaved? ask the user
-		if not self.page_to_be_closed.get_saved() and self._save_changes():
-			Actions.FLOW_GRAPH_SAVE() #try to save
-			if not self.page_to_be_closed.get_saved(): #still unsaved?
-				self.page_to_be_closed = None #set the page to be closed back to None
-				return
-		#stop the flow graph if executing
-		if self.page_to_be_closed.get_proc(): Actions.FLOW_GRAPH_KILL()
-		#remove the page
-		self.notebook.remove_page(self.notebook.page_num(self.page_to_be_closed))
-		if ensure and self.notebook.get_n_pages() == 0: self.new_page() #no pages, make a new one
-		self.page_to_be_closed = None #set the page to be closed back to None
+    def close_page(self, ensure=True):
+        """
+        Close the current page.
+        If the notebook becomes empty, and ensure is true,
+        call new page upon exit to ensure that at least one page exists.
+        
+        Args:
+            ensure: boolean
+        """
+        if not self.page_to_be_closed: self.page_to_be_closed = self.get_page()
+        #show the page if it has an executing flow graph or is unsaved
+        if self.page_to_be_closed.get_proc() or not self.page_to_be_closed.get_saved():
+            self._set_page(self.page_to_be_closed)
+        #unsaved? ask the user
+        if not self.page_to_be_closed.get_saved() and self._save_changes():
+            Actions.FLOW_GRAPH_SAVE() #try to save
+            if not self.page_to_be_closed.get_saved(): #still unsaved?
+                self.page_to_be_closed = None #set the page to be closed back to None
+                return
+        #stop the flow graph if executing
+        if self.page_to_be_closed.get_proc(): Actions.FLOW_GRAPH_KILL()
+        #remove the page
+        self.notebook.remove_page(self.notebook.page_num(self.page_to_be_closed))
+        if ensure and self.notebook.get_n_pages() == 0: self.new_page() #no pages, make a new one
+        self.page_to_be_closed = None #set the page to be closed back to None
 
-	############################################################
-	# Misc
-	############################################################
+    ############################################################
+    # Misc
+    ############################################################
 
-	def update(self):
-		"""
-		Set the title of the main window.
-		Set the titles on the page tabs.
-		Show/hide the reports window.
-		
-		Args:
-		    title: the window title
-		"""
-		gtk.Window.set_title(self, Utils.parse_template(MAIN_WINDOW_TITLE_TMPL,
-				basename=os.path.basename(self.get_page().get_file_path()),
-				dirname=os.path.dirname(self.get_page().get_file_path()),
-				new_flowgraph_title=NEW_FLOGRAPH_TITLE,
-				read_only=self.get_page().get_read_only(),
-				saved=self.get_page().get_saved(),
-				platform_name=self._platform.get_name(),
-			)
-		)
-		#set tab titles
-		for page in self._get_pages(): page.set_markup(
-			Utils.parse_template(PAGE_TITLE_MARKUP_TMPL,
-				#get filename and strip out file extension
-				title=os.path.splitext(os.path.basename(page.get_file_path()))[0],
-				read_only=page.get_read_only(), saved=page.get_saved(),
-				new_flowgraph_title=NEW_FLOGRAPH_TITLE,
-			)
-		)
-		#show/hide notebook tabs
-		self.notebook.set_show_tabs(len(self._get_pages()) > 1)
+    def update(self):
+        """
+        Set the title of the main window.
+        Set the titles on the page tabs.
+        Show/hide the reports window.
+        
+        Args:
+            title: the window title
+        """
+        gtk.Window.set_title(self, Utils.parse_template(MAIN_WINDOW_TITLE_TMPL,
+                basename=os.path.basename(self.get_page().get_file_path()),
+                dirname=os.path.dirname(self.get_page().get_file_path()),
+                new_flowgraph_title=NEW_FLOGRAPH_TITLE,
+                read_only=self.get_page().get_read_only(),
+                saved=self.get_page().get_saved(),
+                platform_name=self._platform.get_name(),
+            )
+        )
+        #set tab titles
+        for page in self._get_pages(): page.set_markup(
+            Utils.parse_template(PAGE_TITLE_MARKUP_TMPL,
+                #get filename and strip out file extension
+                title=os.path.splitext(os.path.basename(page.get_file_path()))[0],
+                read_only=page.get_read_only(), saved=page.get_saved(),
+                new_flowgraph_title=NEW_FLOGRAPH_TITLE,
+            )
+        )
+        #show/hide notebook tabs
+        self.notebook.set_show_tabs(len(self._get_pages()) > 1)
 
-	def get_page(self):
-		"""
-		Get the selected page.
-		
-		Returns:
-		    the selected page
-		"""
-		return self.current_page
+    def get_page(self):
+        """
+        Get the selected page.
+        
+        Returns:
+            the selected page
+        """
+        return self.current_page
 
-	def get_flow_graph(self):
-		"""
-		Get the selected flow graph.
-		
-		Returns:
-		    the selected flow graph
-		"""
-		return self.get_page().get_flow_graph()
+    def get_flow_graph(self):
+        """
+        Get the selected flow graph.
+        
+        Returns:
+            the selected flow graph
+        """
+        return self.get_page().get_flow_graph()
 
-	def get_focus_flag(self):
-		"""
-		Get the focus flag from the current page.
-		
-		Returns:
-		    the focus flag
-		"""
-		return self.get_page().get_drawing_area().get_focus_flag()
+    def get_focus_flag(self):
+        """
+        Get the focus flag from the current page.
+        
+        Returns:
+            the focus flag
+        """
+        return self.get_page().get_drawing_area().get_focus_flag()
 
-	############################################################
-	# Helpers
-	############################################################
+    ############################################################
+    # Helpers
+    ############################################################
 
-	def _set_page(self, page):
-		"""
-		Set the current page.
-		
-		Args:
-		    page: the page widget
-		"""
-		self.current_page = page
-		self.notebook.set_current_page(self.notebook.page_num(self.current_page))
+    def _set_page(self, page):
+        """
+        Set the current page.
+        
+        Args:
+            page: the page widget
+        """
+        self.current_page = page
+        self.notebook.set_current_page(self.notebook.page_num(self.current_page))
 
-	def _save_changes(self):
-		"""
-		Save changes to flow graph?
-		
-		Returns:
-		    true if yes
-		"""
-		return MessageDialogHelper(
-			gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, 'Unsaved Changes!',
-			'Would you like to save changes before closing?'
-		) == gtk.RESPONSE_YES
+    def _save_changes(self):
+        """
+        Save changes to flow graph?
+        
+        Returns:
+            true if yes
+        """
+        return MessageDialogHelper(
+            gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, 'Unsaved Changes!',
+            'Would you like to save changes before closing?'
+        ) == gtk.RESPONSE_YES
 
-	def _get_files(self):
-		"""
-		Get the file names for all the pages, in order.
-		
-		Returns:
-		    list of file paths
-		"""
-		return map(lambda page: page.get_file_path(), self._get_pages())
+    def _get_files(self):
+        """
+        Get the file names for all the pages, in order.
+        
+        Returns:
+            list of file paths
+        """
+        return map(lambda page: page.get_file_path(), self._get_pages())
 
-	def _get_pages(self):
-		"""
-		Get a list of all pages in the notebook.
-		
-		Returns:
-		    list of pages
-		"""
-		return [self.notebook.get_nth_page(page_num) for page_num in range(self.notebook.get_n_pages())]
+    def _get_pages(self):
+        """
+        Get a list of all pages in the notebook.
+        
+        Returns:
+            list of pages
+        """
+        return [self.notebook.get_nth_page(page_num) for page_num in range(self.notebook.get_n_pages())]
diff --git a/grc/gui/Messages.py b/grc/gui/Messages.py
index a9f0e36b85..d903e40a45 100644
--- a/grc/gui/Messages.py
+++ b/grc/gui/Messages.py
@@ -24,22 +24,22 @@ import sys
 MESSENGERS_LIST = list()
 
 def register_messenger(messenger):
-	"""
-	Append the given messenger to the list of messengers.
-	
-	Args:
-	    messenger: a method thats takes a string
-	"""
-	MESSENGERS_LIST.append(messenger)
+    """
+    Append the given messenger to the list of messengers.
+    
+    Args:
+        messenger: a method thats takes a string
+    """
+    MESSENGERS_LIST.append(messenger)
 
 def send(message):
-	"""
-	Give the message to each of the messengers.
-	
-	Args:
-	    message: a message string
-	"""
-	for messenger in MESSENGERS_LIST: messenger(message)
+    """
+    Give the message to each of the messengers.
+    
+    Args:
+        message: a message string
+    """
+    for messenger in MESSENGERS_LIST: messenger(message)
 
 #register stdout by default
 register_messenger(sys.stdout.write)
@@ -48,61 +48,61 @@ register_messenger(sys.stdout.write)
 # Special functions for specific program functionalities
 ###########################################################################
 def send_init(platform):
-	send("""<<< Welcome to %s %s >>>\n"""%(platform.get_name(), platform.get_version()))
+    send("""<<< Welcome to %s %s >>>\n"""%(platform.get_name(), platform.get_version()))
 
 def send_page_switch(file_path):
-	send('\nShowing: "%s"\n'%file_path)
+    send('\nShowing: "%s"\n'%file_path)
 
-################# functions for loading flow graphs	########################################
+################# functions for loading flow graphs ########################################
 def send_start_load(file_path):
-	send('\nLoading: "%s"'%file_path + '\n')
+    send('\nLoading: "%s"'%file_path + '\n')
 
 def send_error_load(error):
-	send('>>> Error: %s\n'%error)
-	traceback.print_exc()
+    send('>>> Error: %s\n'%error)
+    traceback.print_exc()
 
 def send_end_load():
-	send('>>> Done\n')
+    send('>>> Done\n')
 
 def send_fail_load(error):
-	send('Error: %s\n'%error)
-	send('>>> Failure\n')
-	traceback.print_exc()
+    send('Error: %s\n'%error)
+    send('>>> Failure\n')
+    traceback.print_exc()
 
-################# functions for generating flow graphs	########################################
+################# functions for generating flow graphs  ########################################
 def send_start_gen(file_path):
-	send('\nGenerating: "%s"'%file_path + '\n')
+    send('\nGenerating: "%s"'%file_path + '\n')
 
 def send_fail_gen(error):
-	send('Generate Error: %s\n'%error)
-	send('>>> Failure\n')
-	traceback.print_exc()
+    send('Generate Error: %s\n'%error)
+    send('>>> Failure\n')
+    traceback.print_exc()
 
-################# functions for executing flow graphs	########################################
+################# functions for executing flow graphs   ########################################
 def send_start_exec(file_path):
-	send('\nExecuting: "%s"'%file_path + '\n')
+    send('\nExecuting: "%s"'%file_path + '\n')
 
 def send_verbose_exec(verbose):
-	send(verbose)
+    send(verbose)
 
 def send_end_exec():
-	send('\n>>> Done\n')
+    send('\n>>> Done\n')
 
-################# functions for saving flow graphs	########################################
+################# functions for saving flow graphs  ########################################
 def send_fail_save(file_path):
-	send('>>> Error: Cannot save: %s\n'%file_path)
+    send('>>> Error: Cannot save: %s\n'%file_path)
 
-################# functions for connections	########################################
+################# functions for connections ########################################
 def send_fail_connection():
-	send('>>> Error: Cannot create connection.\n')
+    send('>>> Error: Cannot create connection.\n')
 
-################# functions for preferences	########################################
+################# functions for preferences ########################################
 def send_fail_load_preferences(prefs_file_path):
-	send('>>> Error: Cannot load preferences file: "%s"\n'%prefs_file_path)
+    send('>>> Error: Cannot load preferences file: "%s"\n'%prefs_file_path)
 
 def send_fail_save_preferences(prefs_file_path):
-	send('>>> Error: Cannot save preferences file: "%s"\n'%prefs_file_path)
+    send('>>> Error: Cannot save preferences file: "%s"\n'%prefs_file_path)
 
-################# functions for warning	########################################
+################# functions for warning ########################################
 def send_warning(warning):
-	send('>>> Warning: %s\n'%warning)
+    send('>>> Warning: %s\n'%warning)
diff --git a/grc/gui/NotebookPage.py b/grc/gui/NotebookPage.py
index 095c045a66..10c5dde00d 100644
--- a/grc/gui/NotebookPage.py
+++ b/grc/gui/NotebookPage.py
@@ -31,185 +31,185 @@ import os
 ############################################################
 
 class NotebookPage(gtk.HBox):
-	"""A page in the notebook."""
-
-	def __init__(self, main_window, flow_graph, file_path=''):
-		"""
-		Page constructor.
-		
-		Args:
-		    main_window: main window
-		    file_path: path to a flow graph file
-		"""
-		self._flow_graph = flow_graph
-		self.set_proc(None)
-		#import the file
-		self.main_window = main_window
-		self.set_file_path(file_path)
-		initial_state = flow_graph.get_parent().parse_flow_graph(file_path)
-		self.state_cache = StateCache(initial_state)
-		self.set_saved(True)
-		#import the data to the flow graph
-		self.get_flow_graph().import_data(initial_state)
-		#initialize page gui
-		gtk.HBox.__init__(self, False, 0)
-		self.show()
-		#tab box to hold label and close button
-		self.tab = gtk.HBox(False, 0)
-		#setup tab label
-		self.label = gtk.Label()
-		self.tab.pack_start(self.label, False)
-		#setup button image
-		image = gtk.Image()
-		image.set_from_stock('gtk-close', gtk.ICON_SIZE_MENU)
-		#setup image box
-		image_box = gtk.HBox(False, 0)
-		image_box.pack_start(image, True, False, 0)
-		#setup the button
-		button = gtk.Button()
-		button.connect("clicked", self._handle_button)
-		button.set_relief(gtk.RELIEF_NONE)
-		button.add(image_box)
-		#button size
-		w, h = gtk.icon_size_lookup_for_settings(button.get_settings(), gtk.ICON_SIZE_MENU)
-		button.set_size_request(w+6, h+6)
-		self.tab.pack_start(button, False)
-		self.tab.show_all()
-		#setup scroll window and drawing area
-		self.scrolled_window = gtk.ScrolledWindow()
-		self.scrolled_window.set_size_request(MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT)
-		self.scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
-		self.drawing_area = DrawingArea(self.get_flow_graph())
-		self.scrolled_window.add_with_viewport(self.get_drawing_area())
-		self.pack_start(self.scrolled_window)
-		#inject drawing area into flow graph
-		self.get_flow_graph().drawing_area = self.get_drawing_area()
-		self.show_all()
-
-	def get_drawing_area(self): return self.drawing_area
-
-	def get_generator(self):
-		"""
-		Get the generator object for this flow graph.
-		
-		Returns:
-		    generator
-		"""
-		return self.get_flow_graph().get_parent().get_generator()(
-			self.get_flow_graph(),
-			self.get_file_path(),
-		)
-
-	def _handle_button(self, button):
-		"""
-		The button was clicked.
-		Make the current page selected, then close.
-		
-		Args:
-		    the: button
-		"""
-		self.main_window.page_to_be_closed = self
-		Actions.FLOW_GRAPH_CLOSE()
-
-	def set_markup(self, markup):
-		"""
-		Set the markup in this label.
-		
-		Args:
-		    markup: the new markup text
-		"""
-		self.label.set_markup(markup)
-
-	def get_tab(self):
-		"""
-		Get the gtk widget for this page's tab.
-		
-		Returns:
-		    gtk widget
-		"""
-		return self.tab
-
-	def get_proc(self):
-		"""
-		Get the subprocess for the flow graph.
-		
-		Returns:
-		    the subprocess object
-		"""
-		return self.process
-
-	def set_proc(self, process):
-		"""
-		Set the subprocess object.
-		
-		Args:
-		    process: the new subprocess
-		"""
-		self.process = process
-
-	def get_flow_graph(self):
-		"""
-		Get the flow graph.
-		
-		Returns:
-		    the flow graph
-		"""
-		return self._flow_graph
-
-	def get_read_only(self):
-		"""
-		Get the read-only state of the file.
-		Always false for empty path.
-		
-		Returns:
-		    true for read-only
-		"""
-		if not self.get_file_path(): return False
-		return os.path.exists(self.get_file_path()) and \
-		not os.access(self.get_file_path(), os.W_OK)
-
-	def get_file_path(self):
-		"""
-		Get the file path for the flow graph.
-		
-		Returns:
-		    the file path or ''
-		"""
-		return self.file_path
-
-	def set_file_path(self, file_path=''):
-		"""
-		Set the file path, '' for no file path.
-		
-		Args:
-		    file_path: file path string
-		"""
-		if file_path: self.file_path = os.path.abspath(file_path)
-		else: self.file_path = ''
-
-	def get_saved(self):
-		"""
-		Get the saved status for the flow graph.
-		
-		Returns:
-		    true if saved
-		"""
-		return self.saved
-
-	def set_saved(self, saved=True):
-		"""
-		Set the saved status.
-		
-		Args:
-		    saved: boolean status
-		"""
-		self.saved = saved
-
-	def get_state_cache(self):
-		"""
-		Get the state cache for the flow graph.
-		
-		Returns:
-		    the state cache
-		"""
-		return self.state_cache
+    """A page in the notebook."""
+
+    def __init__(self, main_window, flow_graph, file_path=''):
+        """
+        Page constructor.
+        
+        Args:
+            main_window: main window
+            file_path: path to a flow graph file
+        """
+        self._flow_graph = flow_graph
+        self.set_proc(None)
+        #import the file
+        self.main_window = main_window
+        self.set_file_path(file_path)
+        initial_state = flow_graph.get_parent().parse_flow_graph(file_path)
+        self.state_cache = StateCache(initial_state)
+        self.set_saved(True)
+        #import the data to the flow graph
+        self.get_flow_graph().import_data(initial_state)
+        #initialize page gui
+        gtk.HBox.__init__(self, False, 0)
+        self.show()
+        #tab box to hold label and close button
+        self.tab = gtk.HBox(False, 0)
+        #setup tab label
+        self.label = gtk.Label()
+        self.tab.pack_start(self.label, False)
+        #setup button image
+        image = gtk.Image()
+        image.set_from_stock('gtk-close', gtk.ICON_SIZE_MENU)
+        #setup image box
+        image_box = gtk.HBox(False, 0)
+        image_box.pack_start(image, True, False, 0)
+        #setup the button
+        button = gtk.Button()
+        button.connect("clicked", self._handle_button)
+        button.set_relief(gtk.RELIEF_NONE)
+        button.add(image_box)
+        #button size
+        w, h = gtk.icon_size_lookup_for_settings(button.get_settings(), gtk.ICON_SIZE_MENU)
+        button.set_size_request(w+6, h+6)
+        self.tab.pack_start(button, False)
+        self.tab.show_all()
+        #setup scroll window and drawing area
+        self.scrolled_window = gtk.ScrolledWindow()
+        self.scrolled_window.set_size_request(MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT)
+        self.scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+        self.drawing_area = DrawingArea(self.get_flow_graph())
+        self.scrolled_window.add_with_viewport(self.get_drawing_area())
+        self.pack_start(self.scrolled_window)
+        #inject drawing area into flow graph
+        self.get_flow_graph().drawing_area = self.get_drawing_area()
+        self.show_all()
+
+    def get_drawing_area(self): return self.drawing_area
+
+    def get_generator(self):
+        """
+        Get the generator object for this flow graph.
+        
+        Returns:
+            generator
+        """
+        return self.get_flow_graph().get_parent().get_generator()(
+            self.get_flow_graph(),
+            self.get_file_path(),
+        )
+
+    def _handle_button(self, button):
+        """
+        The button was clicked.
+        Make the current page selected, then close.
+        
+        Args:
+            the: button
+        """
+        self.main_window.page_to_be_closed = self
+        Actions.FLOW_GRAPH_CLOSE()
+
+    def set_markup(self, markup):
+        """
+        Set the markup in this label.
+        
+        Args:
+            markup: the new markup text
+        """
+        self.label.set_markup(markup)
+
+    def get_tab(self):
+        """
+        Get the gtk widget for this page's tab.
+        
+        Returns:
+            gtk widget
+        """
+        return self.tab
+
+    def get_proc(self):
+        """
+        Get the subprocess for the flow graph.
+        
+        Returns:
+            the subprocess object
+        """
+        return self.process
+
+    def set_proc(self, process):
+        """
+        Set the subprocess object.
+        
+        Args:
+            process: the new subprocess
+        """
+        self.process = process
+
+    def get_flow_graph(self):
+        """
+        Get the flow graph.
+        
+        Returns:
+            the flow graph
+        """
+        return self._flow_graph
+
+    def get_read_only(self):
+        """
+        Get the read-only state of the file.
+        Always false for empty path.
+        
+        Returns:
+            true for read-only
+        """
+        if not self.get_file_path(): return False
+        return os.path.exists(self.get_file_path()) and \
+        not os.access(self.get_file_path(), os.W_OK)
+
+    def get_file_path(self):
+        """
+        Get the file path for the flow graph.
+        
+        Returns:
+            the file path or ''
+        """
+        return self.file_path
+
+    def set_file_path(self, file_path=''):
+        """
+        Set the file path, '' for no file path.
+        
+        Args:
+            file_path: file path string
+        """
+        if file_path: self.file_path = os.path.abspath(file_path)
+        else: self.file_path = ''
+
+    def get_saved(self):
+        """
+        Get the saved status for the flow graph.
+        
+        Returns:
+            true if saved
+        """
+        return self.saved
+
+    def set_saved(self, saved=True):
+        """
+        Set the saved status.
+        
+        Args:
+            saved: boolean status
+        """
+        self.saved = saved
+
+    def get_state_cache(self):
+        """
+        Get the state cache for the flow graph.
+        
+        Returns:
+            the state cache
+        """
+        return self.state_cache
diff --git a/grc/gui/Param.py b/grc/gui/Param.py
index da76b6b82c..f0e5a2fcb2 100644
--- a/grc/gui/Param.py
+++ b/grc/gui/Param.py
@@ -25,110 +25,110 @@ import gtk
 import Colors
 
 class InputParam(gtk.HBox):
-	"""The base class for an input parameter inside the input parameters dialog."""
-
-	def __init__(self, param, callback=None):
-		gtk.HBox.__init__(self)
-		self.param = param
-		self._callback = callback
-		self.label = gtk.Label() #no label, markup is added by set_markup
-		self.label.set_size_request(150, -1)
-		self.pack_start(self.label, False)
-		self.set_markup = lambda m: self.label.set_markup(m)
-		self.tp = None
-		#connect events
-		self.connect('show', self._update_gui)
-	def set_color(self, color): pass
-	def set_tooltip_text(self, text): pass
-
-	def _update_gui(self, *args):
-		"""
-		Set the markup, color, tooltip, show/hide.
-		"""
-		#set the markup
-		has_cb = \
-			hasattr(self.param.get_parent(), 'get_callbacks') and \
-			filter(lambda c: self.param.get_key() in c, self.param.get_parent()._callbacks)
-		self.set_markup(Utils.parse_template(PARAM_LABEL_MARKUP_TMPL, param=self.param, has_cb=has_cb))
-		#set the color
-		self.set_color(self.param.get_color())
-		#set the tooltip
-		self.set_tooltip_text(
-			Utils.parse_template(TIP_MARKUP_TMPL, param=self.param).strip(),
-		)
-		#show/hide
-		if self.param.get_hide() == 'all': self.hide_all()
-		else: self.show_all()
-
-	def _handle_changed(self, *args):
-		"""
-		Handle a gui change by setting the new param value,
-		calling the callback (if applicable), and updating.
-		"""
-		#set the new value
-		self.param.set_value(self.get_text())
-		#call the callback
-		if self._callback: self._callback(*args)
-		else: self.param.validate()
-		#gui update
-		self._update_gui()
+    """The base class for an input parameter inside the input parameters dialog."""
+
+    def __init__(self, param, callback=None):
+        gtk.HBox.__init__(self)
+        self.param = param
+        self._callback = callback
+        self.label = gtk.Label() #no label, markup is added by set_markup
+        self.label.set_size_request(150, -1)
+        self.pack_start(self.label, False)
+        self.set_markup = lambda m: self.label.set_markup(m)
+        self.tp = None
+        #connect events
+        self.connect('show', self._update_gui)
+    def set_color(self, color): pass
+    def set_tooltip_text(self, text): pass
+
+    def _update_gui(self, *args):
+        """
+        Set the markup, color, tooltip, show/hide.
+        """
+        #set the markup
+        has_cb = \
+            hasattr(self.param.get_parent(), 'get_callbacks') and \
+            filter(lambda c: self.param.get_key() in c, self.param.get_parent()._callbacks)
+        self.set_markup(Utils.parse_template(PARAM_LABEL_MARKUP_TMPL, param=self.param, has_cb=has_cb))
+        #set the color
+        self.set_color(self.param.get_color())
+        #set the tooltip
+        self.set_tooltip_text(
+            Utils.parse_template(TIP_MARKUP_TMPL, param=self.param).strip(),
+        )
+        #show/hide
+        if self.param.get_hide() == 'all': self.hide_all()
+        else: self.show_all()
+
+    def _handle_changed(self, *args):
+        """
+        Handle a gui change by setting the new param value,
+        calling the callback (if applicable), and updating.
+        """
+        #set the new value
+        self.param.set_value(self.get_text())
+        #call the callback
+        if self._callback: self._callback(*args)
+        else: self.param.validate()
+        #gui update
+        self._update_gui()
 
 class EntryParam(InputParam):
-	"""Provide an entry box for strings and numbers."""
-
-	def __init__(self, *args, **kwargs):
-		InputParam.__init__(self, *args, **kwargs)
-		self._input = gtk.Entry()
-		self._input.set_text(self.param.get_value())
-		self._input.connect('changed', self._handle_changed)
-		self.pack_start(self._input, True)
-	def get_text(self): return self._input.get_text()
-	def set_color(self, color):
-		self._input.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse(color))
-		self._input.modify_text(gtk.STATE_NORMAL, Colors.PARAM_ENTRY_TEXT_COLOR)
-	def set_tooltip_text(self, text): self._input.set_tooltip_text(text)
+    """Provide an entry box for strings and numbers."""
+
+    def __init__(self, *args, **kwargs):
+        InputParam.__init__(self, *args, **kwargs)
+        self._input = gtk.Entry()
+        self._input.set_text(self.param.get_value())
+        self._input.connect('changed', self._handle_changed)
+        self.pack_start(self._input, True)
+    def get_text(self): return self._input.get_text()
+    def set_color(self, color):
+        self._input.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse(color))
+        self._input.modify_text(gtk.STATE_NORMAL, Colors.PARAM_ENTRY_TEXT_COLOR)
+    def set_tooltip_text(self, text): self._input.set_tooltip_text(text)
 
 class EnumParam(InputParam):
-	"""Provide an entry box for Enum types with a drop down menu."""
-
-	def __init__(self, *args, **kwargs):
-		InputParam.__init__(self, *args, **kwargs)
-		self._input = gtk.combo_box_new_text()
-		for option in self.param.get_options(): self._input.append_text(option.get_name())
-		self._input.set_active(self.param.get_option_keys().index(self.param.get_value()))
-		self._input.connect('changed', self._handle_changed)
-		self.pack_start(self._input, False)
-	def get_text(self): return self.param.get_option_keys()[self._input.get_active()]
-	def set_tooltip_text(self, text): self._input.set_tooltip_text(text)
+    """Provide an entry box for Enum types with a drop down menu."""
+
+    def __init__(self, *args, **kwargs):
+        InputParam.__init__(self, *args, **kwargs)
+        self._input = gtk.combo_box_new_text()
+        for option in self.param.get_options(): self._input.append_text(option.get_name())
+        self._input.set_active(self.param.get_option_keys().index(self.param.get_value()))
+        self._input.connect('changed', self._handle_changed)
+        self.pack_start(self._input, False)
+    def get_text(self): return self.param.get_option_keys()[self._input.get_active()]
+    def set_tooltip_text(self, text): self._input.set_tooltip_text(text)
 
 class EnumEntryParam(InputParam):
-	"""Provide an entry box and drop down menu for Raw Enum types."""
-
-	def __init__(self, *args, **kwargs):
-		InputParam.__init__(self, *args, **kwargs)
-		self._input = gtk.combo_box_entry_new_text()
-		for option in self.param.get_options(): self._input.append_text(option.get_name())
-		try: self._input.set_active(self.param.get_option_keys().index(self.param.get_value()))
-		except:
-			self._input.set_active(-1)
-			self._input.get_child().set_text(self.param.get_value())
-		self._input.connect('changed', self._handle_changed)
-		self._input.get_child().connect('changed', self._handle_changed)
-		self.pack_start(self._input, False)
-	def get_text(self):
-		if self._input.get_active() == -1: return self._input.get_child().get_text()
-		return self.param.get_option_keys()[self._input.get_active()]
-	def set_tooltip_text(self, text):
-		if self._input.get_active() == -1: #custom entry
-			self._input.get_child().set_tooltip_text(text)
-		else: self._input.set_tooltip_text(text)
-	def set_color(self, color):
-		if self._input.get_active() == -1: #custom entry, use color
-			self._input.get_child().modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse(color))
-			self._input.get_child().modify_text(gtk.STATE_NORMAL, Colors.PARAM_ENTRY_TEXT_COLOR)
-		else: #from enum, make pale background
-			self._input.get_child().modify_base(gtk.STATE_NORMAL, Colors.ENTRYENUM_CUSTOM_COLOR)
-			self._input.get_child().modify_text(gtk.STATE_NORMAL, Colors.PARAM_ENTRY_TEXT_COLOR)
+    """Provide an entry box and drop down menu for Raw Enum types."""
+
+    def __init__(self, *args, **kwargs):
+        InputParam.__init__(self, *args, **kwargs)
+        self._input = gtk.combo_box_entry_new_text()
+        for option in self.param.get_options(): self._input.append_text(option.get_name())
+        try: self._input.set_active(self.param.get_option_keys().index(self.param.get_value()))
+        except:
+            self._input.set_active(-1)
+            self._input.get_child().set_text(self.param.get_value())
+        self._input.connect('changed', self._handle_changed)
+        self._input.get_child().connect('changed', self._handle_changed)
+        self.pack_start(self._input, False)
+    def get_text(self):
+        if self._input.get_active() == -1: return self._input.get_child().get_text()
+        return self.param.get_option_keys()[self._input.get_active()]
+    def set_tooltip_text(self, text):
+        if self._input.get_active() == -1: #custom entry
+            self._input.get_child().set_tooltip_text(text)
+        else: self._input.set_tooltip_text(text)
+    def set_color(self, color):
+        if self._input.get_active() == -1: #custom entry, use color
+            self._input.get_child().modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse(color))
+            self._input.get_child().modify_text(gtk.STATE_NORMAL, Colors.PARAM_ENTRY_TEXT_COLOR)
+        else: #from enum, make pale background
+            self._input.get_child().modify_base(gtk.STATE_NORMAL, Colors.ENTRYENUM_CUSTOM_COLOR)
+            self._input.get_child().modify_text(gtk.STATE_NORMAL, Colors.PARAM_ENTRY_TEXT_COLOR)
 
 PARAM_MARKUP_TMPL="""\
 #set $foreground = $param.is_valid() and 'black' or 'red'
@@ -142,13 +142,13 @@ PARAM_LABEL_MARKUP_TMPL="""\
 TIP_MARKUP_TMPL="""\
 ########################################
 #def truncate(string)
-	#set $max_len = 100
-	#set $string = str($string)
-	#if len($string) > $max_len
+    #set $max_len = 100
+    #set $string = str($string)
+    #if len($string) > $max_len
 $('%s...%s'%($string[:$max_len/2], $string[-$max_len/2:]))#slurp
-	#else
+    #else
 $string#slurp
-	#end if
+    #end if
 #end def
 ########################################
 Key: $param.get_key()
@@ -159,35 +159,35 @@ Value: $truncate($param.get_evaluated())
 Error: $(param.get_error_messages()[0])
 #else
 Error:
-	#for $error_msg in $param.get_error_messages()
+    #for $error_msg in $param.get_error_messages()
  * $error_msg
-	#end for
+    #end for
 #end if"""
 
 class Param(Element):
-	"""The graphical parameter."""
-
-	def __init__(self): Element.__init__(self)
-
-	def get_input(self, *args, **kwargs):
-		"""
-		Get the graphical gtk class to represent this parameter.
-		An enum requires and combo parameter.
-		A non-enum with options gets a combined entry/combo parameter.
-		All others get a standard entry parameter.
-		
-		Returns:
-		    gtk input class
-		"""
-		if self.is_enum(): return EnumParam(self, *args, **kwargs)
-		if self.get_options(): return EnumEntryParam(self, *args, **kwargs)
-		return EntryParam(self, *args, **kwargs)
-
-	def get_markup(self):
-		"""
-		Get the markup for this param.
-		
-		Returns:
-		    a pango markup string
-		"""
-		return Utils.parse_template(PARAM_MARKUP_TMPL, param=self)
+    """The graphical parameter."""
+
+    def __init__(self): Element.__init__(self)
+
+    def get_input(self, *args, **kwargs):
+        """
+        Get the graphical gtk class to represent this parameter.
+        An enum requires and combo parameter.
+        A non-enum with options gets a combined entry/combo parameter.
+        All others get a standard entry parameter.
+        
+        Returns:
+            gtk input class
+        """
+        if self.is_enum(): return EnumParam(self, *args, **kwargs)
+        if self.get_options(): return EnumEntryParam(self, *args, **kwargs)
+        return EntryParam(self, *args, **kwargs)
+
+    def get_markup(self):
+        """
+        Get the markup for this param.
+        
+        Returns:
+            a pango markup string
+        """
+        return Utils.parse_template(PARAM_MARKUP_TMPL, param=self)
diff --git a/grc/gui/Platform.py b/grc/gui/Platform.py
index 8bbfaca232..6a8175b9fa 100644
--- a/grc/gui/Platform.py
+++ b/grc/gui/Platform.py
@@ -20,4 +20,4 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 from Element import Element
 
 class Platform(Element):
-	def __init__(self): Element.__init__(self)
+    def __init__(self): Element.__init__(self)
diff --git a/grc/gui/Port.py b/grc/gui/Port.py
index 2ccc394971..fe1dc5070a 100644
--- a/grc/gui/Port.py
+++ b/grc/gui/Port.py
@@ -19,9 +19,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 
 from Element import Element
 from Constants import \
-	PORT_SEPARATION, CONNECTOR_EXTENSION_MINIMAL, \
-	CONNECTOR_EXTENSION_INCREMENT, \
-	PORT_LABEL_PADDING, PORT_MIN_WIDTH
+    PORT_SEPARATION, CONNECTOR_EXTENSION_MINIMAL, \
+    CONNECTOR_EXTENSION_INCREMENT, \
+    PORT_LABEL_PADDING, PORT_MIN_WIDTH
 import Utils
 import Colors
 import pygtk
@@ -32,196 +32,192 @@ PORT_MARKUP_TMPL="""\
 <span foreground="black" font_desc="Sans 7.5">$encode($port.get_name())</span>"""
 
 class Port(Element):
-	"""The graphical port."""
-
-	def __init__(self):
-		"""
-		Port contructor.
-		Create list of connector coordinates.
-		"""
-		Element.__init__(self)
-		self.connector_coordinates = dict()
-
-	def create_shapes(self):
-		"""Create new areas and labels for the port."""
-		Element.create_shapes(self)
-		
-		#get current rotation
-		rotation = self.get_rotation()
-		#get all sibling ports
-		if self.is_source(): ports = self.get_parent().get_sources_gui()
-		elif self.is_sink(): ports = self.get_parent().get_sinks_gui()
-		#get the max width
-		self.W = max([port.W for port in ports] + [PORT_MIN_WIDTH])
-		#get a numeric index for this port relative to its sibling ports
-		try:
-			index = ports.index(self)
-		except:
-			if hasattr(self, '_connector_length'):
-				del self._connector_length;
-			return
-		
-		length = len(ports)
-		#reverse the order of ports	for these rotations
-		if rotation in (180, 270): index = length-index-1
-		offset = (self.get_parent().H - length*self.H - (length-1)*PORT_SEPARATION)/2
-		#create areas and connector coordinates
-		if (self.is_sink() and rotation == 0) or (self.is_source() and rotation == 180):
-			x = -1*self.W
-			y = (PORT_SEPARATION+self.H)*index+offset
-			self.add_area((x, y), (self.W, self.H))
-			self._connector_coordinate = (x-1, y+self.H/2)
-		elif (self.is_source() and rotation == 0) or (self.is_sink() and rotation == 180):
-			x = self.get_parent().W
-			y = (PORT_SEPARATION+self.H)*index+offset
-			self.add_area((x, y), (self.W, self.H))
-			self._connector_coordinate = (x+1+self.W, y+self.H/2)
-		elif (self.is_source() and rotation == 90) or (self.is_sink() and rotation == 270):
-			y = -1*self.W
-			x = (PORT_SEPARATION+self.H)*index+offset
-			self.add_area((x, y), (self.H, self.W))
-			self._connector_coordinate = (x+self.H/2, y-1)
-		elif (self.is_sink() and rotation == 90) or (self.is_source() and rotation == 270):
-			y = self.get_parent().W
-			x = (PORT_SEPARATION+self.H)*index+offset
-			self.add_area((x, y), (self.H, self.W))
-			self._connector_coordinate = (x+self.H/2, y+1+self.W)
-		#the connector length
-		self._connector_length = CONNECTOR_EXTENSION_MINIMAL + CONNECTOR_EXTENSION_INCREMENT*index
-	
-	def modify_height(self, start_height):
-		type_dict = {'bus':(lambda a: a * 3)};
-		
-		if self.get_type() in type_dict:
-			return type_dict[self.get_type()](start_height);
-		else:
-			return start_height;
-		
-	def create_labels(self):
-		"""Create the labels for the socket."""
-		Element.create_labels(self)
-		self._bg_color = Colors.get_color(self.get_color())
-		#create the layout
-		layout = gtk.DrawingArea().create_pango_layout('')
-		layout.set_markup(Utils.parse_template(PORT_MARKUP_TMPL, port=self))
-		self.w, self.h = layout.get_pixel_size()
-		self.W, self.H = 2*PORT_LABEL_PADDING+self.w, 2*PORT_LABEL_PADDING+self.h
-		self.H = self.modify_height(self.H);
-		#create the pixmap
-		pixmap = self.get_parent().get_parent().new_pixmap(self.w, self.h)
-		gc = pixmap.new_gc()
-		gc.set_foreground(self._bg_color)
-		pixmap.draw_rectangle(gc, True, 0, 0, self.w, self.h)
-		pixmap.draw_layout(gc, 0, 0, layout)
-		#create vertical and horizontal pixmaps
-		self.horizontal_label = pixmap
-		if self.is_vertical():
-			self.vertical_label = self.get_parent().get_parent().new_pixmap(self.h, self.w)
-			Utils.rotate_pixmap(gc, self.horizontal_label, self.vertical_label)
-
-	def draw(self, gc, window):
-		"""
-		Draw the socket with a label.
-		
-		Args:
-		    gc: the graphics context
-		    window: the gtk window to draw on
-		"""
-		
-		Element.draw(
-			self, gc, window, bg_color=self._bg_color,
-			border_color=self.is_highlighted() and Colors.HIGHLIGHT_COLOR or Colors.BORDER_COLOR,
-		)
-		X,Y = self.get_coordinate()
-		(x,y),(w,h) = self._areas_list[0] #use the first area's sizes to place the labels
-		if self.is_horizontal():
-			window.draw_drawable(gc, self.horizontal_label, 0, 0, x+X+(self.W-self.w)/2, y+Y+(self.H-self.h)/2, -1, -1)
-		elif self.is_vertical():
-			window.draw_drawable(gc, self.vertical_label, 0, 0, x+X+(self.H-self.h)/2, y+Y+(self.W-self.w)/2, -1, -1)
-
-	def get_connector_coordinate(self):
-		"""
-		Get the coordinate where connections may attach to.
-		
-		Returns:
-		    the connector coordinate (x, y) tuple
-		"""
-		x,y = self._connector_coordinate
-		X,Y = self.get_coordinate()
-		return (x+X, y+Y)
-
-	def get_connector_direction(self):
-		"""
-		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.
-		
-		Returns:
-		    the direction in degrees
-		"""
-		if self.is_source(): return self.get_rotation()
-		elif self.is_sink(): return (self.get_rotation() + 180)%360
-
-	def get_connector_length(self):
-		"""
-		Get the length of the connector.
-		The connector length increases as the port index changes.
-		
-		Returns:
-		    the length in pixels
-		"""
-		return self._connector_length
-
-	def get_rotation(self):
-		"""
-		Get the parent's rotation rather than self.
-		
-		Returns:
-		    the parent's rotation
-		"""
-		return self.get_parent().get_rotation()
-
-	def move(self, delta_coor):
-		"""
-		Move the parent rather than self.
-		
-		Args:
-		    delta_corr: the (delta_x, delta_y) tuple
-		"""
-		self.get_parent().move(delta_coor)
-
-	def rotate(self, direction):
-		"""
-		Rotate the parent rather than self.
-		
-		Args:
-		    direction: degrees to rotate
-		"""
-		self.get_parent().rotate(direction)
-
-	def get_coordinate(self):
-		"""
-		Get the parent's coordinate rather than self.
-		
-		Returns:
-		    the parents coordinate
-		"""
-		return self.get_parent().get_coordinate()
-
-	def set_highlighted(self, highlight):
-		"""
-		Set the parent highlight rather than self.
-		
-		Args:
-		    highlight: true to enable highlighting
-		"""
-		self.get_parent().set_highlighted(highlight)
-
-	def is_highlighted(self):
-		"""
-		Get the parent's is highlight rather than self.
-		
-		Returns:
-		    the parent's highlighting status
-		"""
-		return self.get_parent().is_highlighted()
+    """The graphical port."""
+
+    def __init__(self):
+        """
+        Port contructor.
+        Create list of connector coordinates.
+        """
+        Element.__init__(self)
+        self.connector_coordinates = dict()
+
+    def create_shapes(self):
+        """Create new areas and labels for the port."""
+        Element.create_shapes(self)
+        #get current rotation
+        rotation = self.get_rotation()
+        #get all sibling ports
+        if self.is_source(): ports = self.get_parent().get_sources_gui()
+        elif self.is_sink(): ports = self.get_parent().get_sinks_gui()
+        #get the max width
+        self.W = max([port.W for port in ports] + [PORT_MIN_WIDTH])
+        #get a numeric index for this port relative to its sibling ports
+        try:
+            index = ports.index(self)
+        except:
+            if hasattr(self, '_connector_length'):
+                del self._connector_length;
+            return
+        length = len(ports)
+        #reverse the order of ports for these rotations
+        if rotation in (180, 270): index = length-index-1
+        offset = (self.get_parent().H - length*self.H - (length-1)*PORT_SEPARATION)/2
+        #create areas and connector coordinates
+        if (self.is_sink() and rotation == 0) or (self.is_source() and rotation == 180):
+            x = -1*self.W
+            y = (PORT_SEPARATION+self.H)*index+offset
+            self.add_area((x, y), (self.W, self.H))
+            self._connector_coordinate = (x-1, y+self.H/2)
+        elif (self.is_source() and rotation == 0) or (self.is_sink() and rotation == 180):
+            x = self.get_parent().W
+            y = (PORT_SEPARATION+self.H)*index+offset
+            self.add_area((x, y), (self.W, self.H))
+            self._connector_coordinate = (x+1+self.W, y+self.H/2)
+        elif (self.is_source() and rotation == 90) or (self.is_sink() and rotation == 270):
+            y = -1*self.W
+            x = (PORT_SEPARATION+self.H)*index+offset
+            self.add_area((x, y), (self.H, self.W))
+            self._connector_coordinate = (x+self.H/2, y-1)
+        elif (self.is_sink() and rotation == 90) or (self.is_source() and rotation == 270):
+            y = self.get_parent().W
+            x = (PORT_SEPARATION+self.H)*index+offset
+            self.add_area((x, y), (self.H, self.W))
+            self._connector_coordinate = (x+self.H/2, y+1+self.W)
+        #the connector length
+        self._connector_length = CONNECTOR_EXTENSION_MINIMAL + CONNECTOR_EXTENSION_INCREMENT*index
+    def modify_height(self, start_height):
+        type_dict = {'bus':(lambda a: a * 3)};
+        
+        if self.get_type() in type_dict:
+            return type_dict[self.get_type()](start_height);
+        else:
+            return start_height;
+
+    def create_labels(self):
+        """Create the labels for the socket."""
+        Element.create_labels(self)
+        self._bg_color = Colors.get_color(self.get_color())
+        #create the layout
+        layout = gtk.DrawingArea().create_pango_layout('')
+        layout.set_markup(Utils.parse_template(PORT_MARKUP_TMPL, port=self))
+        self.w, self.h = layout.get_pixel_size()
+        self.W, self.H = 2*PORT_LABEL_PADDING+self.w, 2*PORT_LABEL_PADDING+self.h
+        self.H = self.modify_height(self.H);
+        #create the pixmap
+        pixmap = self.get_parent().get_parent().new_pixmap(self.w, self.h)
+        gc = pixmap.new_gc()
+        gc.set_foreground(self._bg_color)
+        pixmap.draw_rectangle(gc, True, 0, 0, self.w, self.h)
+        pixmap.draw_layout(gc, 0, 0, layout)
+        #create vertical and horizontal pixmaps
+        self.horizontal_label = pixmap
+        if self.is_vertical():
+            self.vertical_label = self.get_parent().get_parent().new_pixmap(self.h, self.w)
+            Utils.rotate_pixmap(gc, self.horizontal_label, self.vertical_label)
+
+    def draw(self, gc, window):
+        """
+        Draw the socket with a label.
+        
+        Args:
+            gc: the graphics context
+            window: the gtk window to draw on
+        """
+        Element.draw(
+            self, gc, window, bg_color=self._bg_color,
+            border_color=self.is_highlighted() and Colors.HIGHLIGHT_COLOR or Colors.BORDER_COLOR,
+        )
+        X,Y = self.get_coordinate()
+        (x,y),(w,h) = self._areas_list[0] #use the first area's sizes to place the labels
+        if self.is_horizontal():
+            window.draw_drawable(gc, self.horizontal_label, 0, 0, x+X+(self.W-self.w)/2, y+Y+(self.H-self.h)/2, -1, -1)
+        elif self.is_vertical():
+            window.draw_drawable(gc, self.vertical_label, 0, 0, x+X+(self.H-self.h)/2, y+Y+(self.W-self.w)/2, -1, -1)
+
+    def get_connector_coordinate(self):
+        """
+        Get the coordinate where connections may attach to.
+        
+        Returns:
+            the connector coordinate (x, y) tuple
+        """
+        x,y = self._connector_coordinate
+        X,Y = self.get_coordinate()
+        return (x+X, y+Y)
+
+    def get_connector_direction(self):
+        """
+        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.
+        
+        Returns:
+            the direction in degrees
+        """
+        if self.is_source(): return self.get_rotation()
+        elif self.is_sink(): return (self.get_rotation() + 180)%360
+
+    def get_connector_length(self):
+        """
+        Get the length of the connector.
+        The connector length increases as the port index changes.
+        
+        Returns:
+            the length in pixels
+        """
+        return self._connector_length
+
+    def get_rotation(self):
+        """
+        Get the parent's rotation rather than self.
+        
+        Returns:
+            the parent's rotation
+        """
+        return self.get_parent().get_rotation()
+
+    def move(self, delta_coor):
+        """
+        Move the parent rather than self.
+        
+        Args:
+            delta_corr: the (delta_x, delta_y) tuple
+        """
+        self.get_parent().move(delta_coor)
+
+    def rotate(self, direction):
+        """
+        Rotate the parent rather than self.
+        
+        Args:
+            direction: degrees to rotate
+        """
+        self.get_parent().rotate(direction)
+
+    def get_coordinate(self):
+        """
+        Get the parent's coordinate rather than self.
+        
+        Returns:
+            the parents coordinate
+        """
+        return self.get_parent().get_coordinate()
+
+    def set_highlighted(self, highlight):
+        """
+        Set the parent highlight rather than self.
+        
+        Args:
+            highlight: true to enable highlighting
+        """
+        self.get_parent().set_highlighted(highlight)
+
+    def is_highlighted(self):
+        """
+        Get the parent's is highlight rather than self.
+        
+        Returns:
+            the parent's highlighting status
+        """
+        return self.get_parent().is_highlighted()
diff --git a/grc/gui/Preferences.py b/grc/gui/Preferences.py
index 1d89920dd5..ce545cab6a 100644
--- a/grc/gui/Preferences.py
+++ b/grc/gui/Preferences.py
@@ -27,60 +27,60 @@ def file_extension(): return '.'+_platform.get_key()
 def _prefs_file(): return os.path.join(os.path.expanduser('~'), file_extension())
 
 def load(platform):
-	global _platform
-	_platform = platform
-	#create sections
-	_config_parser.add_section('main')
-	_config_parser.add_section('files_open')
-	try: _config_parser.read(_prefs_file())
-	except: pass
+    global _platform
+    _platform = platform
+    #create sections
+    _config_parser.add_section('main')
+    _config_parser.add_section('files_open')
+    try: _config_parser.read(_prefs_file())
+    except: pass
 def save():
-	try: _config_parser.write(open(_prefs_file(), 'w'))
-	except: pass
+    try: _config_parser.write(open(_prefs_file(), 'w'))
+    except: pass
 
 ###########################################################################
 # Special methods for specific program functionalities
 ###########################################################################
 
 def main_window_size(size=None):
-	if size is not None:
-		_config_parser.set('main', 'main_window_width', size[0])
-		_config_parser.set('main', 'main_window_height', size[1])
-	else:
-		try: return (
-			_config_parser.getint('main', 'main_window_width'),
-			_config_parser.getint('main', 'main_window_height'),
-		)
-		except: return (1, 1)
+    if size is not None:
+        _config_parser.set('main', 'main_window_width', size[0])
+        _config_parser.set('main', 'main_window_height', size[1])
+    else:
+        try: return (
+            _config_parser.getint('main', 'main_window_width'),
+            _config_parser.getint('main', 'main_window_height'),
+        )
+        except: return (1, 1)
 
 def file_open(file=None):
-	if file is not None: _config_parser.set('main', 'file_open', file)
-	else:
-		try: return _config_parser.get('main', 'file_open')
-		except: return ''
+    if file is not None: _config_parser.set('main', 'file_open', file)
+    else:
+        try: return _config_parser.get('main', 'file_open')
+        except: return ''
 
 def files_open(files=None):
-	if files is not None:
-		_config_parser.remove_section('files_open') #clear section
-		_config_parser.add_section('files_open')
-		for i, file in enumerate(files):
-			_config_parser.set('files_open', 'file_open_%d'%i, file)
-	else:
-		files = list()
-		i = 0
-		while True:
-			try: files.append(_config_parser.get('files_open', 'file_open_%d'%i))
-			except: return files
-			i = i + 1
+    if files is not None:
+        _config_parser.remove_section('files_open') #clear section
+        _config_parser.add_section('files_open')
+        for i, file in enumerate(files):
+            _config_parser.set('files_open', 'file_open_%d'%i, file)
+    else:
+        files = list()
+        i = 0
+        while True:
+            try: files.append(_config_parser.get('files_open', 'file_open_%d'%i))
+            except: return files
+            i = i + 1
 
 def reports_window_position(pos=None):
-	if pos is not None: _config_parser.set('main', 'reports_window_position', pos)
-	else:
-		try: return _config_parser.getint('main', 'reports_window_position') or 1 #greater than 0
-		except: return -1
+    if pos is not None: _config_parser.set('main', 'reports_window_position', pos)
+    else:
+        try: return _config_parser.getint('main', 'reports_window_position') or 1 #greater than 0
+        except: return -1
 
 def blocks_window_position(pos=None):
-	if pos is not None: _config_parser.set('main', 'blocks_window_position', pos)
-	else:
-		try: return _config_parser.getint('main', 'blocks_window_position') or 1 #greater than 0
-		except: return -1
+    if pos is not None: _config_parser.set('main', 'blocks_window_position', pos)
+    else:
+        try: return _config_parser.getint('main', 'blocks_window_position') or 1 #greater than 0
+        except: return -1
diff --git a/grc/gui/PropsDialog.py b/grc/gui/PropsDialog.py
index 5264857fab..5c09f7cac1 100644
--- a/grc/gui/PropsDialog.py
+++ b/grc/gui/PropsDialog.py
@@ -25,158 +25,158 @@ from Dialogs import TextDisplay
 from Constants import MIN_DIALOG_WIDTH, MIN_DIALOG_HEIGHT
 
 def get_title_label(title):
-	"""
-	Get a title label for the params window.
-	The title will be bold, underlined, and left justified.
-	
-	Args:
-	    title: the text of the title
-	
-	Returns:
-	    a gtk object
-	"""
-	label = gtk.Label()
-	label.set_markup('\n<b><span underline="low">%s</span>:</b>\n'%title)
-	hbox = gtk.HBox()
-	hbox.pack_start(label, False, False, padding=11)
-	return hbox
+    """
+    Get a title label for the params window.
+    The title will be bold, underlined, and left justified.
+    
+    Args:
+        title: the text of the title
+    
+    Returns:
+        a gtk object
+    """
+    label = gtk.Label()
+    label.set_markup('\n<b><span underline="low">%s</span>:</b>\n'%title)
+    hbox = gtk.HBox()
+    hbox.pack_start(label, False, False, padding=11)
+    return hbox
 
 class PropsDialog(gtk.Dialog):
-	"""
-	A dialog to set block parameters, view errors, and view documentation.
-	"""
+    """
+    A dialog to set block parameters, view errors, and view documentation.
+    """
 
-	def __init__(self, block):
-		"""
-		Properties dialog contructor.
-		
-		Args:
-		    block: a block instance
-		"""
-		self._hash = 0
-		LABEL_SPACING = 7
-		gtk.Dialog.__init__(self,
-			title='Properties: %s'%block.get_name(),
-			buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT),
-		)
-		self._block = block
-		self.set_size_request(MIN_DIALOG_WIDTH, MIN_DIALOG_HEIGHT)
-		vbox = gtk.VBox()
-		#Create the scrolled window to hold all the parameters
-		scrolled_window = gtk.ScrolledWindow()
-		scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
-		scrolled_window.add_with_viewport(vbox)
-		self.vbox.pack_start(scrolled_window, True)
-		#Params box for block parameters
-		self._params_box = gtk.VBox()
-		self._params_box.pack_start(get_title_label('Parameters'), False)
-		self._input_object_params = list()
-		#Error Messages for the block
-		self._error_box = gtk.VBox()
-		self._error_messages_text_display = TextDisplay()
-		self._error_box.pack_start(gtk.Label(), False, False, LABEL_SPACING)
-		self._error_box.pack_start(get_title_label('Error Messages'), False)
-		self._error_box.pack_start(self._error_messages_text_display, False)
-		#Docs for the block
-		self._docs_box = err_box = gtk.VBox()
-		self._docs_text_display = TextDisplay()
-		self._docs_box.pack_start(gtk.Label(), False, False, LABEL_SPACING)
-		self._docs_box.pack_start(get_title_label('Documentation'), False)
-		self._docs_box.pack_start(self._docs_text_display, False)
-		#Add the boxes
-		vbox.pack_start(self._params_box, False)
-		vbox.pack_start(self._error_box, False)
-		vbox.pack_start(self._docs_box, False)
-		#connect events
-		self.connect('key-press-event', self._handle_key_press)
-		self.connect('show', self._update_gui)
-		#show all (performs initial gui update)
-		self.show_all()
+    def __init__(self, block):
+        """
+        Properties dialog contructor.
+        
+        Args:
+            block: a block instance
+        """
+        self._hash = 0
+        LABEL_SPACING = 7
+        gtk.Dialog.__init__(self,
+            title='Properties: %s'%block.get_name(),
+            buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT),
+        )
+        self._block = block
+        self.set_size_request(MIN_DIALOG_WIDTH, MIN_DIALOG_HEIGHT)
+        vbox = gtk.VBox()
+        #Create the scrolled window to hold all the parameters
+        scrolled_window = gtk.ScrolledWindow()
+        scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+        scrolled_window.add_with_viewport(vbox)
+        self.vbox.pack_start(scrolled_window, True)
+        #Params box for block parameters
+        self._params_box = gtk.VBox()
+        self._params_box.pack_start(get_title_label('Parameters'), False)
+        self._input_object_params = list()
+        #Error Messages for the block
+        self._error_box = gtk.VBox()
+        self._error_messages_text_display = TextDisplay()
+        self._error_box.pack_start(gtk.Label(), False, False, LABEL_SPACING)
+        self._error_box.pack_start(get_title_label('Error Messages'), False)
+        self._error_box.pack_start(self._error_messages_text_display, False)
+        #Docs for the block
+        self._docs_box = err_box = gtk.VBox()
+        self._docs_text_display = TextDisplay()
+        self._docs_box.pack_start(gtk.Label(), False, False, LABEL_SPACING)
+        self._docs_box.pack_start(get_title_label('Documentation'), False)
+        self._docs_box.pack_start(self._docs_text_display, False)
+        #Add the boxes
+        vbox.pack_start(self._params_box, False)
+        vbox.pack_start(self._error_box, False)
+        vbox.pack_start(self._docs_box, False)
+        #connect events
+        self.connect('key-press-event', self._handle_key_press)
+        self.connect('show', self._update_gui)
+        #show all (performs initial gui update)
+        self.show_all()
 
-	def _params_changed(self):
-		"""
-		Have the params in this dialog changed?
-		Ex: Added, removed, type change, hide change...
-		To the props dialog, the hide setting of 'none' and 'part' are identical.
-		Therfore, the props dialog only cares if the hide setting is/not 'all'.
-		Make a hash that uniquely represents the params' state.
-		
-		Returns:
-		    true if changed
-		"""
-		old_hash = self._hash
-		#create a tuple of things from each param that affects the params box
-		self._hash = hash(tuple([(
-			hash(param), param.get_type(), param.get_hide() == 'all',
-		) for param in self._block.get_params()]))
-		return self._hash != old_hash
+    def _params_changed(self):
+        """
+        Have the params in this dialog changed?
+        Ex: Added, removed, type change, hide change...
+        To the props dialog, the hide setting of 'none' and 'part' are identical.
+        Therfore, the props dialog only cares if the hide setting is/not 'all'.
+        Make a hash that uniquely represents the params' state.
+        
+        Returns:
+            true if changed
+        """
+        old_hash = self._hash
+        #create a tuple of things from each param that affects the params box
+        self._hash = hash(tuple([(
+            hash(param), param.get_type(), param.get_hide() == 'all',
+        ) for param in self._block.get_params()]))
+        return self._hash != old_hash
 
-	def _handle_changed(self, *args):
-		"""
-		A change occured within a param:
-		Rewrite/validate the block and update the gui.
-		"""
-		#update for the block
-		self._block.rewrite()
-		self._block.validate()
-		self._update_gui()
+    def _handle_changed(self, *args):
+        """
+        A change occured within a param:
+        Rewrite/validate the block and update the gui.
+        """
+        #update for the block
+        self._block.rewrite()
+        self._block.validate()
+        self._update_gui()
 
-	def _update_gui(self, *args):
-		"""
-		Repopulate the parameters box (if changed).
-		Update all the input parameters.
-		Update the error messages box.
-		Hide the box if there are no errors.
-		Update the documentation block.
-		Hide the box if there are no docs.
-		"""
-		#update the params box
-		if self._params_changed():
-			#hide params box before changing
-			self._params_box.hide_all()
-			#empty the params box
-			for io_param in list(self._input_object_params):
-				self._params_box.remove(io_param)
-				self._input_object_params.remove(io_param)
-				io_param.destroy()
-			#repopulate the params box
-			for param in self._block.get_params():
-				if param.get_hide() == 'all': continue
-				io_param = param.get_input(self._handle_changed)
-				self._input_object_params.append(io_param)
-				self._params_box.pack_start(io_param, False)
-			#show params box with new params
-			self._params_box.show_all()
-		#update the errors box
-		if self._block.is_valid(): self._error_box.hide()
-		else: self._error_box.show()
-		messages = '\n\n'.join(self._block.get_error_messages())
-		self._error_messages_text_display.set_text(messages)
-		#update the docs box
-		if self._block.get_doc(): self._docs_box.show()
-		else: self._docs_box.hide()
-		self._docs_text_display.set_text(self._block.get_doc())
+    def _update_gui(self, *args):
+        """
+        Repopulate the parameters box (if changed).
+        Update all the input parameters.
+        Update the error messages box.
+        Hide the box if there are no errors.
+        Update the documentation block.
+        Hide the box if there are no docs.
+        """
+        #update the params box
+        if self._params_changed():
+            #hide params box before changing
+            self._params_box.hide_all()
+            #empty the params box
+            for io_param in list(self._input_object_params):
+                self._params_box.remove(io_param)
+                self._input_object_params.remove(io_param)
+                io_param.destroy()
+            #repopulate the params box
+            for param in self._block.get_params():
+                if param.get_hide() == 'all': continue
+                io_param = param.get_input(self._handle_changed)
+                self._input_object_params.append(io_param)
+                self._params_box.pack_start(io_param, False)
+            #show params box with new params
+            self._params_box.show_all()
+        #update the errors box
+        if self._block.is_valid(): self._error_box.hide()
+        else: self._error_box.show()
+        messages = '\n\n'.join(self._block.get_error_messages())
+        self._error_messages_text_display.set_text(messages)
+        #update the docs box
+        if self._block.get_doc(): self._docs_box.show()
+        else: self._docs_box.hide()
+        self._docs_text_display.set_text(self._block.get_doc())
 
-	def _handle_key_press(self, widget, event):
-		"""
-		Handle key presses from the keyboard.
-		Call the ok response when enter is pressed.
-		
-		Returns:
-		    false to forward the keypress
-		"""
-		if event.keyval == gtk.keysyms.Return:
-			self.response(gtk.RESPONSE_ACCEPT)
-			return True #handled here
-		return False #forward the keypress
+    def _handle_key_press(self, widget, event):
+        """
+        Handle key presses from the keyboard.
+        Call the ok response when enter is pressed.
+        
+        Returns:
+            false to forward the keypress
+        """
+        if event.keyval == gtk.keysyms.Return:
+            self.response(gtk.RESPONSE_ACCEPT)
+            return True #handled here
+        return False #forward the keypress
 
-	def run(self):
-		"""
-		Run the dialog and get its response.
-		
-		Returns:
-		    true if the response was accept
-		"""
-		response = gtk.Dialog.run(self)
-		self.destroy()
-		return response == gtk.RESPONSE_ACCEPT
+    def run(self):
+        """
+        Run the dialog and get its response.
+        
+        Returns:
+            true if the response was accept
+        """
+        response = gtk.Dialog.run(self)
+        self.destroy()
+        return response == gtk.RESPONSE_ACCEPT
diff --git a/grc/gui/StateCache.py b/grc/gui/StateCache.py
index 50d85bf960..558f507716 100644
--- a/grc/gui/StateCache.py
+++ b/grc/gui/StateCache.py
@@ -21,82 +21,82 @@ import Actions
 from Constants import STATE_CACHE_SIZE
 
 class StateCache(object):
-	"""
-	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.
-	"""
+    """
+    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):
-		"""
-		StateCache constructor.
-		
-		Args:
-		    initial_state: the intial state (nested data)
-		"""
-		self.states = [None] * STATE_CACHE_SIZE #fill states
-		self.current_state_index = 0
-		self.num_prev_states = 0
-		self.num_next_states = 0
-		self.states[0] = initial_state
-		self.update_actions()
+    def __init__(self, initial_state):
+        """
+        StateCache constructor.
+        
+        Args:
+            initial_state: the intial state (nested data)
+        """
+        self.states = [None] * STATE_CACHE_SIZE #fill states
+        self.current_state_index = 0
+        self.num_prev_states = 0
+        self.num_next_states = 0
+        self.states[0] = initial_state
+        self.update_actions()
 
-	def save_new_state(self, state):
-		"""
-		Save a new state.
-		Place the new state at the next index and add one to the number of previous states.
-		
-		Args:
-		    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
-		self.num_next_states = 0
-		self.update_actions()
+    def save_new_state(self, state):
+        """
+        Save a new state.
+        Place the new state at the next index and add one to the number of previous states.
+        
+        Args:
+            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
+        self.num_next_states = 0
+        self.update_actions()
 
-	def get_current_state(self):
-		"""
-		Get the state at the current index.
-		
-		Returns:
-		    the current state (nested data)
-		"""
-		self.update_actions()
-		return self.states[self.current_state_index]
+    def get_current_state(self):
+        """
+        Get the state at the current index.
+        
+        Returns:
+            the current state (nested data)
+        """
+        self.update_actions()
+        return self.states[self.current_state_index]
 
-	def get_prev_state(self):
-		"""
-		Get the previous state and decrement the current index.
-		
-		Returns:
-		    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
-			return self.get_current_state()
-		return None
+    def get_prev_state(self):
+        """
+        Get the previous state and decrement the current index.
+        
+        Returns:
+            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
+            return self.get_current_state()
+        return None
 
-	def get_next_state(self):
-		"""
-		Get the nest state and increment the current index.
-		
-		Returns:
-		    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
-			return self.get_current_state()
-		return None
+    def get_next_state(self):
+        """
+        Get the nest state and increment the current index.
+        
+        Returns:
+            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
+            return self.get_current_state()
+        return None
 
-	def update_actions(self):
-		"""
-		Update the undo and redo actions based on the number of next and prev states.
-		"""
-		Actions.FLOW_GRAPH_REDO.set_sensitive(self.num_next_states != 0)
-		Actions.FLOW_GRAPH_UNDO.set_sensitive(self.num_prev_states != 0)
+    def update_actions(self):
+        """
+        Update the undo and redo actions based on the number of next and prev states.
+        """
+        Actions.FLOW_GRAPH_REDO.set_sensitive(self.num_next_states != 0)
+        Actions.FLOW_GRAPH_UNDO.set_sensitive(self.num_prev_states != 0)
diff --git a/grc/gui/Utils.py b/grc/gui/Utils.py
index 407c875a87..cc1f8ceb12 100644
--- a/grc/gui/Utils.py
+++ b/grc/gui/Utils.py
@@ -25,86 +25,86 @@ import gtk
 import gobject
 
 def rotate_pixmap(gc, src_pixmap, dst_pixmap, angle=gtk.gdk.PIXBUF_ROTATE_COUNTERCLOCKWISE):
-	"""
-	Load the destination pixmap with a rotated version of the source pixmap.
-	The source pixmap will be loaded into a pixbuf, rotated, and drawn to the destination pixmap.
-	The pixbuf is a client-side drawable, where a pixmap is a server-side drawable.
-	
-	Args:
-	    gc: the graphics context
-	    src_pixmap: the source pixmap
-	    dst_pixmap: the destination pixmap
-	    angle: the angle to rotate by
-	"""
-	width, height = src_pixmap.get_size()
-	pixbuf = gtk.gdk.Pixbuf(
-		colorspace=gtk.gdk.COLORSPACE_RGB,
-		has_alpha=False, bits_per_sample=8,
-		width=width, height=height,
-	)
-	pixbuf.get_from_drawable(src_pixmap, src_pixmap.get_colormap(), 0, 0, 0, 0, -1, -1)
-	pixbuf = pixbuf.rotate_simple(angle)
-	dst_pixmap.draw_pixbuf(gc, pixbuf, 0, 0, 0, 0)
+    """
+    Load the destination pixmap with a rotated version of the source pixmap.
+    The source pixmap will be loaded into a pixbuf, rotated, and drawn to the destination pixmap.
+    The pixbuf is a client-side drawable, where a pixmap is a server-side drawable.
+    
+    Args:
+        gc: the graphics context
+        src_pixmap: the source pixmap
+        dst_pixmap: the destination pixmap
+        angle: the angle to rotate by
+    """
+    width, height = src_pixmap.get_size()
+    pixbuf = gtk.gdk.Pixbuf(
+        colorspace=gtk.gdk.COLORSPACE_RGB,
+        has_alpha=False, bits_per_sample=8,
+        width=width, height=height,
+    )
+    pixbuf.get_from_drawable(src_pixmap, src_pixmap.get_colormap(), 0, 0, 0, 0, -1, -1)
+    pixbuf = pixbuf.rotate_simple(angle)
+    dst_pixmap.draw_pixbuf(gc, pixbuf, 0, 0, 0, 0)
 
 def get_rotated_coordinate(coor, rotation):
-	"""
-	Rotate the coordinate by the given rotation.
-	
-	Args:
-	    coor: the coordinate x, y tuple
-	    rotation: the angle in degrees
-	
-	Returns:
-	    the rotated coordinates
-	"""
-	#handles negative angles
-	rotation = (rotation + 360)%360
-	if rotation not in POSSIBLE_ROTATIONS:
-		raise ValueError('unusable rotation angle "%s"'%str(rotation))
-	#determine the number of degrees to rotate
-	cos_r, sin_r = {
-		0: (1, 0),
-		90: (0, 1),
-		180: (-1, 0),
-		270: (0, -1),
-	}[rotation]
-	x, y = coor
-	return (x*cos_r + y*sin_r, -x*sin_r + y*cos_r)
+    """
+    Rotate the coordinate by the given rotation.
+    
+    Args:
+        coor: the coordinate x, y tuple
+        rotation: the angle in degrees
+    
+    Returns:
+        the rotated coordinates
+    """
+    #handles negative angles
+    rotation = (rotation + 360)%360
+    if rotation not in POSSIBLE_ROTATIONS:
+        raise ValueError('unusable rotation angle "%s"'%str(rotation))
+    #determine the number of degrees to rotate
+    cos_r, sin_r = {
+        0: (1, 0),
+        90: (0, 1),
+        180: (-1, 0),
+        270: (0, -1),
+    }[rotation]
+    x, y = coor
+    return (x*cos_r + y*sin_r, -x*sin_r + y*cos_r)
 
 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.
-	
-	Args:
-	    (x1,y1): the coordinate of point 1
-	    (x2,y2): the coordinate of point 2
-	
-	Returns:
-	    the direction in degrees
-	"""
-	if y1 == y2:#0 or 180
-		if x2 > x1: return 0
-		else: return 180
-	else:#90 or 270
-		if y2 > y1: return 270
-		else: return 90
+    """
+    Given two points, calculate the vector direction from point1 to point2, directions are multiples of 90 degrees.
+    
+    Args:
+        (x1,y1): the coordinate of point 1
+        (x2,y2): the coordinate of point 2
+    
+    Returns:
+        the direction in degrees
+    """
+    if y1 == y2:#0 or 180
+        if x2 > x1: return 0
+        else: return 180
+    else:#90 or 270
+        if y2 > y1: return 270
+        else: return 90
 
 def parse_template(tmpl_str, **kwargs):
-	"""
-	Parse the template string with the given args.
-	Pass in the xml encode method for pango escape chars.
-	
-	Args:
-	    tmpl_str: the template as a string
-	
-	Returns:
-	    a string of the parsed template
-	"""
-	kwargs['encode'] = gobject.markup_escape_text
-	#try:
-	#	cat = str(Template(tmpl_str, kwargs))
-	#except TypeError:
-	#	print 'guppy'
-	#	print tmpl_str
-	#	print str(kwargs['param'].get_error_messages())
-	return str(Template(tmpl_str, kwargs))
+    """
+    Parse the template string with the given args.
+    Pass in the xml encode method for pango escape chars.
+    
+    Args:
+        tmpl_str: the template as a string
+    
+    Returns:
+        a string of the parsed template
+    """
+    kwargs['encode'] = gobject.markup_escape_text
+    #try:
+    #   cat = str(Template(tmpl_str, kwargs))
+    #except TypeError:
+    #   print 'guppy'
+    #   print tmpl_str
+    #   print str(kwargs['param'].get_error_messages())
+    return str(Template(tmpl_str, kwargs))
diff --git a/grc/python/Block.py b/grc/python/Block.py
index d365c43319..e13b26c12f 100644
--- a/grc/python/Block.py
+++ b/grc/python/Block.py
@@ -23,195 +23,187 @@ import extract_docs
 
 class Block(_Block, _GUIBlock):
 
-	def is_virtual_sink(self): return self.get_key() == 'virtual_sink'
-	def is_virtual_source(self): return self.get_key() == 'virtual_source'
-
-	##for make source to keep track of indexes
-	_source_count = 0
-	##for make sink to keep track of indexes
-	_sink_count = 0
-
-	
-
-	def __init__(self, flow_graph, n):
-		"""
-		Make a new block from nested data.
-		
-		Args:
-		    flow: graph the parent element
-		    n: the nested odict
-		
-		Returns:
-		    block a new block
-		"""
-		#grab the data
-		self._doc = n.find('doc') or ''
-		self._imports = map(lambda i: i.strip(), n.findall('import'))
-		self._make = n.find('make')
-		self._var_make = n.find('var_make')
-		self._checks = n.findall('check')
-		self._callbacks = n.findall('callback')
-		self._throttle = n.find('throttle') or ''
-		self._bus_structure_source = n.find('bus_structure_source') or ''
-		self._bus_structure_sink = n.find('bus_structure_sink') or ''
-		#build the block
-		_Block.__init__(
-			self,
-			flow_graph=flow_graph,
-			n=n,
-		)
-		_GUIBlock.__init__(self)
-
-	def get_bus_structure(self, direction):
-		if direction == 'source':
-			bus_structure = self._bus_structure_source;
-		else:
-			bus_structure = self._bus_structure_sink;
-		
-		bus_structure = self.resolve_dependencies(bus_structure);
-		
-		if not bus_structure: return ''
-		try:
-			clean_bus_structure = self.get_parent().evaluate(bus_structure)
-			return clean_bus_structure
-	
-		except: return ''
-
-	def throttle(self): return bool(self._throttle)
-
-	def validate(self):
-		"""
-		Validate this block.
-		Call the base class validate.
-		Evaluate the checks: each check must evaluate to True.
-		"""
-		_Block.validate(self)
-		#evaluate the checks
-		for check in self._checks:
-			check_res = self.resolve_dependencies(check)
-			try:
-				if not self.get_parent().evaluate(check_res):
-					self.add_error_message('Check "%s" failed.'%check)
-			except: self.add_error_message('Check "%s" did not evaluate.'%check)
-
-	def rewrite(self):
-		"""
-		Add and remove ports to adjust for the nports.
-		"""
-		_Block.rewrite(self)
-
-		def rectify(ports):
-			#restore integer contiguity after insertion
-			#rectify the port names with the index
-			self.back_ofthe_bus(ports);
-			for i, port in enumerate(ports):
-				port._key = str(i)
-				port._name = port._n['name']
-				if len(ports) > 1 and not port._type == 'bus': port._name += str(i)
-
-		def insert_port(get_ports, get_port, key):
-			prev_port = get_port(str(int(key)-1))
-			get_ports().insert(
-				get_ports().index(prev_port)+1,
-				prev_port.copy(new_key=key),
-			)
-			rectify(get_ports())
-
-		def remove_port(get_ports, get_port, key):
-			port = get_port(key)
-			for connection in port.get_connections():
-				self.get_parent().remove_element(connection)
-			get_ports().remove(port)
-			rectify(get_ports())
-
-		#adjust nports
-		for get_ports, get_port in (
-			(self.get_sources, self.get_source),
-			(self.get_sinks, self.get_sink),
-		):
-			master_ports = filter(lambda p: p.get_nports(), get_ports())
-			for i, master_port in enumerate(master_ports):
-				nports = master_port.get_nports()
-				index_first = get_ports().index(master_port)
-				try: index_last = get_ports().index(master_ports[i+1])
-				except IndexError: index_last = len(get_ports())
-				num_ports = index_last - index_first
-				#do nothing if nports is already num ports
-				if nports == num_ports: continue
-				#remove excess ports and connections
-				if nports < num_ports:
-					for key in reversed(map(str, range(index_first+nports, index_first+num_ports))):
-						remove_port(get_ports, get_port, key);
-						
-								
-					continue
-				#add more ports
-				if nports > num_ports:
-					for key in map(str, range(index_first+num_ports, index_first+nports)):
-						insert_port(get_ports, get_port, key)
-					
-							
-					continue
-		
-			
-	def port_controller_modify(self, direction):
-		"""
-		Change the port controller.
-		
-		Args:
-		    direction: +1 or -1
-		
-		Returns:
-		    true for change
-		"""
-		changed = False
-		#concat the nports string from the private nports settings of all ports
-		nports_str = ' '.join([port._nports for port in self.get_ports()])
-		#modify all params whose keys appear in the nports string
-		for param in self.get_params():
-			if param.is_enum() or param.get_key() not in nports_str: continue
-			#try to increment the port controller by direction
-			try:
-				value = param.get_evaluated()
-				value = value + direction
-				if 0 < value:
-					param.set_value(value)
-					changed = True
-			except: pass
-		return changed
-
-	def get_doc(self):
-		doc = self._doc.strip('\n').replace('\\\n', '')
-		#merge custom doc with doxygen docs
-		return '\n'.join([doc, extract_docs.extract(self.get_key())]).strip('\n')
-
-	def get_category(self):
-		return _Block.get_category(self)
-
-	def get_imports(self):
-		"""
-		Resolve all import statements.
-		Split each import statement at newlines.
-		Combine all import statments into a list.
-		Filter empty imports.
-		
-		Returns:
-		    a list of import statements
-		"""
-		return filter(lambda i: i, sum(map(lambda i: self.resolve_dependencies(i).split('\n'), self._imports), []))
-
-	def get_make(self): return self.resolve_dependencies(self._make)
-	def get_var_make(self): return self.resolve_dependencies(self._var_make)
-
-	def get_callbacks(self):
-		"""
-		Get a list of function callbacks for this block.
-		
-		Returns:
-		    a list of strings
-		"""
-		def make_callback(callback):
-			callback = self.resolve_dependencies(callback)
-			if 'self.' in callback: return callback
-			return 'self.%s.%s'%(self.get_id(), callback)
-		return map(make_callback, self._callbacks)
+    def is_virtual_sink(self): return self.get_key() == 'virtual_sink'
+    def is_virtual_source(self): return self.get_key() == 'virtual_source'
+
+    ##for make source to keep track of indexes
+    _source_count = 0
+    ##for make sink to keep track of indexes
+    _sink_count = 0
+
+    def __init__(self, flow_graph, n):
+        """
+        Make a new block from nested data.
+        
+        Args:
+            flow: graph the parent element
+            n: the nested odict
+        
+        Returns:
+            block a new block
+        """
+        #grab the data
+        self._doc = n.find('doc') or ''
+        self._imports = map(lambda i: i.strip(), n.findall('import'))
+        self._make = n.find('make')
+        self._var_make = n.find('var_make')
+        self._checks = n.findall('check')
+        self._callbacks = n.findall('callback')
+        self._throttle = n.find('throttle') or ''
+        self._bus_structure_source = n.find('bus_structure_source') or ''
+        self._bus_structure_sink = n.find('bus_structure_sink') or ''
+        #build the block
+        _Block.__init__(
+            self,
+            flow_graph=flow_graph,
+            n=n,
+        )
+        _GUIBlock.__init__(self)
+
+    def get_bus_structure(self, direction):
+        if direction == 'source':
+            bus_structure = self._bus_structure_source;
+        else:
+            bus_structure = self._bus_structure_sink;
+        
+        bus_structure = self.resolve_dependencies(bus_structure);
+        
+        if not bus_structure: return ''
+        try:
+            clean_bus_structure = self.get_parent().evaluate(bus_structure)
+            return clean_bus_structure
+    
+        except: return ''
+    def throttle(self): return bool(self._throttle)
+
+    def validate(self):
+        """
+        Validate this block.
+        Call the base class validate.
+        Evaluate the checks: each check must evaluate to True.
+        """
+        _Block.validate(self)
+        #evaluate the checks
+        for check in self._checks:
+            check_res = self.resolve_dependencies(check)
+            try:
+                if not self.get_parent().evaluate(check_res):
+                    self.add_error_message('Check "%s" failed.'%check)
+            except: self.add_error_message('Check "%s" did not evaluate.'%check)
+
+    def rewrite(self):
+        """
+        Add and remove ports to adjust for the nports.
+        """
+        _Block.rewrite(self)
+
+        def rectify(ports):
+            #restore integer contiguity after insertion
+            #rectify the port names with the index
+            self.back_ofthe_bus(ports);
+            for i, port in enumerate(ports):
+                port._key = str(i)
+                port._name = port._n['name']
+                if len(ports) > 1 and not port._type == 'bus': port._name += str(i)
+
+        def insert_port(get_ports, get_port, key):
+            prev_port = get_port(str(int(key)-1))
+            get_ports().insert(
+                get_ports().index(prev_port)+1,
+                prev_port.copy(new_key=key),
+            )
+            rectify(get_ports())
+
+        def remove_port(get_ports, get_port, key):
+            port = get_port(key)
+            for connection in port.get_connections():
+                self.get_parent().remove_element(connection)
+            get_ports().remove(port)
+            rectify(get_ports())
+
+        #adjust nports
+        for get_ports, get_port in (
+            (self.get_sources, self.get_source),
+            (self.get_sinks, self.get_sink),
+        ):
+            master_ports = filter(lambda p: p.get_nports(), get_ports())
+            for i, master_port in enumerate(master_ports):
+                nports = master_port.get_nports()
+                index_first = get_ports().index(master_port)
+                try: index_last = get_ports().index(master_ports[i+1])
+                except IndexError: index_last = len(get_ports())
+                num_ports = index_last - index_first
+                #do nothing if nports is already num ports
+                if nports == num_ports: continue
+                #remove excess ports and connections
+                if nports < num_ports:
+                    for key in reversed(map(str, range(index_first+nports, index_first+num_ports))):
+                        remove_port(get_ports, get_port, key);
+                    continue
+                #add more ports
+                if nports > num_ports:
+                    for key in map(str, range(index_first+num_ports, index_first+nports)):
+                        insert_port(get_ports, get_port, key)
+                    continue
+
+    def port_controller_modify(self, direction):
+        """
+        Change the port controller.
+        
+        Args:
+            direction: +1 or -1
+        
+        Returns:
+            true for change
+        """
+        changed = False
+        #concat the nports string from the private nports settings of all ports
+        nports_str = ' '.join([port._nports for port in self.get_ports()])
+        #modify all params whose keys appear in the nports string
+        for param in self.get_params():
+            if param.is_enum() or param.get_key() not in nports_str: continue
+            #try to increment the port controller by direction
+            try:
+                value = param.get_evaluated()
+                value = value + direction
+                if 0 < value:
+                    param.set_value(value)
+                    changed = True
+            except: pass
+        return changed
+
+    def get_doc(self):
+        doc = self._doc.strip('\n').replace('\\\n', '')
+        #merge custom doc with doxygen docs
+        return '\n'.join([doc, extract_docs.extract(self.get_key())]).strip('\n')
+
+    def get_category(self):
+        return _Block.get_category(self)
+
+    def get_imports(self):
+        """
+        Resolve all import statements.
+        Split each import statement at newlines.
+        Combine all import statments into a list.
+        Filter empty imports.
+        
+        Returns:
+            a list of import statements
+        """
+        return filter(lambda i: i, sum(map(lambda i: self.resolve_dependencies(i).split('\n'), self._imports), []))
+
+    def get_make(self): return self.resolve_dependencies(self._make)
+    def get_var_make(self): return self.resolve_dependencies(self._var_make)
+
+    def get_callbacks(self):
+        """
+        Get a list of function callbacks for this block.
+        
+        Returns:
+            a list of strings
+        """
+        def make_callback(callback):
+            callback = self.resolve_dependencies(callback)
+            if 'self.' in callback: return callback
+            return 'self.%s.%s'%(self.get_id(), callback)
+        return map(make_callback, self._callbacks)
diff --git a/grc/python/Connection.py b/grc/python/Connection.py
index 97bf61d590..7f235b190b 100644
--- a/grc/python/Connection.py
+++ b/grc/python/Connection.py
@@ -24,27 +24,26 @@ from .. gui.Connection import Connection as _GUIConnection
 
 class Connection(_Connection, _GUIConnection):
 
-	def __init__(self, **kwargs):
-		_Connection.__init__(self, **kwargs)
-		_GUIConnection.__init__(self)
-
-	def is_msg(self):
-		return self.get_source().get_type() == self.get_sink().get_type() == 'msg'
-
-	def is_message(self):
-		return self.get_source().get_type() == self.get_sink().get_type() == 'message'
-	
-	def is_bus(self):
-		return self.get_source().get_type() == self.get_sink().get_type() == 'bus'
-	def validate(self):
-		"""
-		Validate the connections.
-		The ports must match in io size.
-		"""
-		Element.validate(self)
-		source_size = Constants.TYPE_TO_SIZEOF[self.get_source().get_type()] * self.get_source().get_vlen()
-		sink_size = Constants.TYPE_TO_SIZEOF[self.get_sink().get_type()] * self.get_sink().get_vlen()
-		if source_size != sink_size:
-			self.add_error_message('Source IO size "%s" does not match sink IO size "%s".'%(source_size, sink_size))
-
-	
+    def __init__(self, **kwargs):
+        _Connection.__init__(self, **kwargs)
+        _GUIConnection.__init__(self)
+
+    def is_msg(self):
+        return self.get_source().get_type() == self.get_sink().get_type() == 'msg'
+
+    def is_message(self):
+        return self.get_source().get_type() == self.get_sink().get_type() == 'message'
+
+    def is_bus(self):
+        return self.get_source().get_type() == self.get_sink().get_type() == 'bus'
+
+    def validate(self):
+        """
+        Validate the connections.
+        The ports must match in io size.
+        """
+        Element.validate(self)
+        source_size = Constants.TYPE_TO_SIZEOF[self.get_source().get_type()] * self.get_source().get_vlen()
+        sink_size = Constants.TYPE_TO_SIZEOF[self.get_sink().get_type()] * self.get_sink().get_vlen()
+        if source_size != sink_size:
+            self.add_error_message('Source IO size "%s" does not match sink IO size "%s".'%(source_size, sink_size))
diff --git a/grc/python/Constants.py b/grc/python/Constants.py
index 5666a2378b..15cc203b43 100644
--- a/grc/python/Constants.py
+++ b/grc/python/Constants.py
@@ -27,11 +27,11 @@ _gr_prefs = gr.prefs()
 PATH_SEP = {'/':':', '\\':';'}[os.path.sep]
 HIER_BLOCKS_LIB_DIR = os.path.join(os.path.expanduser('~'), '.grc_gnuradio')
 BLOCKS_DIRS = filter( #filter blank strings
-	lambda x: x, PATH_SEP.join([
-		os.environ.get('GRC_BLOCKS_PATH', ''),
-		_gr_prefs.get_string('grc', 'local_blocks_path', ''),
-		_gr_prefs.get_string('grc', 'global_blocks_path', ''),
-	]).split(PATH_SEP),
+    lambda x: x, PATH_SEP.join([
+        os.environ.get('GRC_BLOCKS_PATH', ''),
+        _gr_prefs.get_string('grc', 'local_blocks_path', ''),
+        _gr_prefs.get_string('grc', 'global_blocks_path', ''),
+    ]).split(PATH_SEP),
 ) + [HIER_BLOCKS_LIB_DIR]
 
 #file creation modes
@@ -45,40 +45,40 @@ BLOCK_DTD = os.path.join(DATA_DIR, 'block.dtd')
 DEFAULT_FLOW_GRAPH = os.path.join(DATA_DIR, 'default_flow_graph.grc')
 
 CORE_TYPES = ( #name, key, sizeof, color
-	('Complex Float 64', 'fc64', 16, '#CC8C69'),
-	('Complex Float 32', 'fc32', 8, '#3399FF'),
-	('Complex Integer 64', 'sc64', 16, '#66CC00'),
-	('Complex Integer 32', 'sc32', 8, '#33cc66'),
-	('Complex Integer 16', 'sc16', 4, '#cccc00'),
-	('Complex Integer 8', 'sc8', 2, '#cc00cc'),
-	('Float 64', 'f64', 8, '#66CCCC'),
-	('Float 32', 'f32', 4, '#FF8C69'),
-	('Integer 64', 's64', 8, '#99FF33'),
-	('Integer 32', 's32', 4, '#00FF99'),
-	('Integer 16', 's16', 2, '#FFFF66'),
-	('Integer 8', 's8', 1, '#FF66FF'),
-	('Message Queue', 'msg', 0, '#777777'),
-	('Async Message', 'message', 0, '#C0C0C0'),
-	('Bus Connection', 'bus', 0, '#FFFFFF'),
-	('Wildcard', '', 0, '#FFFFFF'),
+    ('Complex Float 64', 'fc64', 16, '#CC8C69'),
+    ('Complex Float 32', 'fc32', 8, '#3399FF'),
+    ('Complex Integer 64', 'sc64', 16, '#66CC00'),
+    ('Complex Integer 32', 'sc32', 8, '#33cc66'),
+    ('Complex Integer 16', 'sc16', 4, '#cccc00'),
+    ('Complex Integer 8', 'sc8', 2, '#cc00cc'),
+    ('Float 64', 'f64', 8, '#66CCCC'),
+    ('Float 32', 'f32', 4, '#FF8C69'),
+    ('Integer 64', 's64', 8, '#99FF33'),
+    ('Integer 32', 's32', 4, '#00FF99'),
+    ('Integer 16', 's16', 2, '#FFFF66'),
+    ('Integer 8', 's8', 1, '#FF66FF'),
+    ('Message Queue', 'msg', 0, '#777777'),
+    ('Async Message', 'message', 0, '#C0C0C0'),
+    ('Bus Connection', 'bus', 0, '#FFFFFF'),
+    ('Wildcard', '', 0, '#FFFFFF'),
 )
 
 ALIAS_TYPES = {
-	'complex' : (8, '#3399FF'),
-	'float'   : (4, '#FF8C69'),
-	'int'     : (4, '#00FF99'),
-	'short'   : (2, '#FFFF66'),
-	'byte'    : (1, '#FF66FF'),
+    'complex' : (8, '#3399FF'),
+    'float'   : (4, '#FF8C69'),
+    'int'     : (4, '#00FF99'),
+    'short'   : (2, '#FFFF66'),
+    'byte'    : (1, '#FF66FF'),
 }
 
 TYPE_TO_COLOR = dict()
 TYPE_TO_SIZEOF = dict()
 for name, key, sizeof, color in CORE_TYPES:
-	TYPE_TO_COLOR[key] = color
-	TYPE_TO_SIZEOF[key] = sizeof
+    TYPE_TO_COLOR[key] = color
+    TYPE_TO_SIZEOF[key] = sizeof
 for key, (sizeof, color) in ALIAS_TYPES.iteritems():
-	TYPE_TO_COLOR[key] = color
-	TYPE_TO_SIZEOF[key] = sizeof
+    TYPE_TO_COLOR[key] = color
+    TYPE_TO_SIZEOF[key] = sizeof
 
 #coloring
 COMPLEX_COLOR_SPEC = '#3399FF'
diff --git a/grc/python/FlowGraph.py b/grc/python/FlowGraph.py
index 89acfd89ef..22ed4f76d6 100644
--- a/grc/python/FlowGraph.py
+++ b/grc/python/FlowGraph.py
@@ -31,239 +31,192 @@ _bussrc_searcher = re.compile('^(bus_source)$')
 _bus_struct_sink_searcher = re.compile('^(bus_structure_sink)$')
 _bus_struct_src_searcher = re.compile('^(bus_structure_source)$')
 
-
 class FlowGraph(_FlowGraph, _GUIFlowGraph):
 
-	def __init__(self, **kwargs):
-		_FlowGraph.__init__(self, **kwargs)
-		_GUIFlowGraph.__init__(self)
-		self._eval_cache = dict()
-
-	def _eval(self, code, namespace, namespace_hash):
-		"""
-		Evaluate the code with the given namespace.
-		
-		Args:
-		    code: a string with python code
-		    namespace: a dict representing the namespace
-		    namespace_hash: a unique hash for the namespace
-		
-		Returns:
-		    the resultant object
-		"""
-		if not code: raise Exception, 'Cannot evaluate empty statement.'
-		my_hash = hash(code) ^ namespace_hash
-		#cache if does not exist
-		
-		if not self._eval_cache.has_key(my_hash):
-			self._eval_cache[my_hash] = eval(code, namespace, namespace)
-		#return from cache
-		return self._eval_cache[my_hash]
-
-	def get_io_signaturev(self, direction):
-		"""
-		Get a list of io signatures for this flow graph.
-		
-		Args:
-		    direction: a string of 'in' or 'out'
-		
-		Returns:
-		    a list of dicts with: type, label, vlen, size
-		"""
-		sorted_pads = {
-			'in': self.get_pad_sources(),
-			'out': self.get_pad_sinks(),
-		}[direction]
+    def __init__(self, **kwargs):
+        _FlowGraph.__init__(self, **kwargs)
+        _GUIFlowGraph.__init__(self)
+        self._eval_cache = dict()
+
+    def _eval(self, code, namespace, namespace_hash):
+        """
+        Evaluate the code with the given namespace.
+        
+        Args:
+            code: a string with python code
+            namespace: a dict representing the namespace
+            namespace_hash: a unique hash for the namespace
+        
+        Returns:
+            the resultant object
+        """
+        if not code: raise Exception, 'Cannot evaluate empty statement.'
+        my_hash = hash(code) ^ namespace_hash
+        #cache if does not exist
+        if not self._eval_cache.has_key(my_hash):
+            self._eval_cache[my_hash] = eval(code, namespace, namespace)
+        #return from cache
+        return self._eval_cache[my_hash]
+
+    def get_io_signaturev(self, direction):
+        """
+        Get a list of io signatures for this flow graph.
+        
+        Args:
+            direction: a string of 'in' or 'out'
+        
+        Returns:
+            a list of dicts with: type, label, vlen, size
+        """
+        sorted_pads = {
+            'in': self.get_pad_sources(),
+            'out': self.get_pad_sinks(),
+        }[direction]
         # we only want stream ports
-		sorted_pads = filter(lambda b: b.get_param('type').get_evaluated() != 'message', sorted_pads);
-		expanded_pads = [];
-		for i in sorted_pads:
-			for j in range(i.get_param('num_streams').get_evaluated()):
-				expanded_pads.append(i);
-		#load io signature
-		return [{
-			'label': str(pad.get_param('label').get_evaluated()),
-			'type': str(pad.get_param('type').get_evaluated()),
-			'vlen': str(pad.get_param('vlen').get_evaluated()),
-			'size': pad.get_param('type').get_opt('size'),
-			'optional': bool(pad.get_param('optional').get_evaluated()),
-		} for pad in expanded_pads]
-
-	def get_pad_sources(self):
-		"""
-		Get a list of pad source blocks sorted by id order.
-		
-		Returns:
-		    a list of pad source blocks in this flow graph
-		"""
-		pads = filter(lambda b: b.get_key() == 'pad_source', self.get_enabled_blocks())
-		return sorted(pads, lambda x, y: cmp(x.get_id(), y.get_id()))
-
-	def get_pad_sinks(self):
-		"""
-		Get a list of pad sink blocks sorted by id order.
-		
-		Returns:
-		    a list of pad sink blocks in this flow graph
-		"""
-		pads = filter(lambda b: b.get_key() == 'pad_sink', self.get_enabled_blocks())
-		return sorted(pads, lambda x, y: cmp(x.get_id(), y.get_id()))
-
-	def get_msg_pad_sources(self):
-		ps = self.get_pad_sources();
-		return filter(lambda b: b.get_param('type').get_evaluated() == 'message', ps);
-
-	def get_msg_pad_sinks(self):
-		ps = self.get_pad_sinks();
-		return filter(lambda b: b.get_param('type').get_evaluated() == 'message', ps);
-
-	def get_imports(self):
-		"""
-		Get a set of all import statments in this flow graph namespace.
-		
-		Returns:
-		    a set of import statements
-		"""
-		imports = sum([block.get_imports() for block in self.get_enabled_blocks()], [])
-		imports = sorted(set(imports))
-		return imports
-
-	def get_variables(self):
-		"""
-		Get a list of all variables in this flow graph namespace.
-		Exclude paramterized variables.
-		
-		Returns:
-		    a sorted list of variable blocks in order of dependency (indep -> dep)
-		"""
-		variables = filter(lambda b: _variable_matcher.match(b.get_key()), self.get_enabled_blocks())
-		return expr_utils.sort_objects(variables, lambda v: v.get_id(), lambda v: v.get_var_make())
-
-	def get_parameters(self):
-		"""
-		Get a list of all paramterized variables in this flow graph namespace.
-		
-		Returns:
-		    a list of paramterized variables
-		"""
-		parameters = filter(lambda b: _parameter_matcher.match(b.get_key()), self.get_enabled_blocks())
-		return parameters
-
-	def get_monitors(self):
-		"""
-		Get a list of all ControlPort monitors
-		"""
-		monitors = filter(lambda b: _monitors_searcher.search(b.get_key()), self.get_enabled_blocks())
-                return monitors
-
-	def get_bussink(self):
-		bussink = filter(lambda b: _bussink_searcher.search(b.get_key()), self.get_enabled_blocks())
-		
-		for i in bussink:
-			for j in i.get_params():
-				if j.get_name() == 'On/Off' and j.get_value() == 'on':
-					return True;
-			
-		return False
-		
-		
-
-	def get_bussrc(self):
-		bussrc = filter(lambda b: _bussrc_searcher.search(b.get_key()), self.get_enabled_blocks())
-
-		for i in bussrc:
-			for j in i.get_params():
-				if j.get_name() == 'On/Off' and j.get_value() == 'on':
-					return True;
-			
-		return False
-
-	def get_bus_structure_sink(self):
-		bussink = filter(lambda b: _bus_struct_sink_searcher.search(b.get_key()), self.get_enabled_blocks())
-			
-		return bussink
-
-	def get_bus_structure_src(self):
-		bussrc = filter(lambda b: _bus_struct_src_searcher.search(b.get_key()), self.get_enabled_blocks())
-		
-		return bussrc
-		
-
-	def rewrite(self):
-		"""
-		Flag the namespace to be renewed.
-		"""
-		
-		
-						
-		
-		def reconnect_bus_blocks():
-			for block in self.get_blocks():
-				
-				if 'bus' in map(lambda a: a.get_type(), block.get_sources_gui()):
-					
-					
-					for i in range(len(block.get_sources_gui())):
-						if len(block.get_sources_gui()[i].get_connections()) > 0:
-							source = block.get_sources_gui()[i]
-							sink = []
-							
-							for j in range(len(source.get_connections())):
-								sink.append(source.get_connections()[j].get_sink());
-						
-									    
-							for elt in source.get_connections():
-								self.remove_element(elt);
-							for j in sink:
-								self.connect(source, j);
-		self._renew_eval_ns = True
-		_FlowGraph.rewrite(self);
-		reconnect_bus_blocks();
-		
-		
-		
-		
-
-	def evaluate(self, expr):
-		"""
-		Evaluate the expression.
-		
-		Args:
-		    expr: the string expression
-		@throw Exception bad expression
-		
-		Returns:
-		    the evaluated data
-		"""
-		
-	
-		if self._renew_eval_ns:
-			self._renew_eval_ns = False
-			#reload namespace
-			n = dict()
-			#load imports
-			for imp in self.get_imports():
-				try: exec imp in n
-				except: pass
-			#load parameters
-			np = dict()
-			for parameter in self.get_parameters():
-				try:
-					e = eval(parameter.get_param('value').to_code(), n, n)
-					np[parameter.get_id()] = e
-				except: pass
-			n.update(np) #merge param namespace
-			#load variables
-			for variable in self.get_variables():
-				try:
-					e = eval(variable.get_param('value').to_code(), n, n)
-					n[variable.get_id()] = e
-				except: pass
-			#make namespace public
-			self.n = n
-			self.n_hash = hash(str(n))
-		
-		#evaluate
-		e = self._eval(expr, self.n, self.n_hash)
-		
-		return e
+        sorted_pads = filter(lambda b: b.get_param('type').get_evaluated() != 'message', sorted_pads);
+        expanded_pads = [];
+        for i in sorted_pads:
+            for j in range(i.get_param('num_streams').get_evaluated()):
+                expanded_pads.append(i);
+        #load io signature
+        return [{
+            'label': str(pad.get_param('label').get_evaluated()),
+            'type': str(pad.get_param('type').get_evaluated()),
+            'vlen': str(pad.get_param('vlen').get_evaluated()),
+            'size': pad.get_param('type').get_opt('size'),
+            'optional': bool(pad.get_param('optional').get_evaluated()),
+        } for pad in expanded_pads]
+
+    def get_pad_sources(self):
+        """
+        Get a list of pad source blocks sorted by id order.
+        
+        Returns:
+            a list of pad source blocks in this flow graph
+        """
+        pads = filter(lambda b: b.get_key() == 'pad_source', self.get_enabled_blocks())
+        return sorted(pads, lambda x, y: cmp(x.get_id(), y.get_id()))
+
+    def get_pad_sinks(self):
+        """
+        Get a list of pad sink blocks sorted by id order.
+        
+        Returns:
+            a list of pad sink blocks in this flow graph
+        """
+        pads = filter(lambda b: b.get_key() == 'pad_sink', self.get_enabled_blocks())
+        return sorted(pads, lambda x, y: cmp(x.get_id(), y.get_id()))
+
+    def get_msg_pad_sources(self):
+        ps = self.get_pad_sources();
+        return filter(lambda b: b.get_param('type').get_evaluated() == 'message', ps);
+
+    def get_msg_pad_sinks(self):
+        ps = self.get_pad_sinks();
+        return filter(lambda b: b.get_param('type').get_evaluated() == 'message', ps);
+
+    def get_imports(self):
+        """
+        Get a set of all import statments in this flow graph namespace.
+        
+        Returns:
+            a set of import statements
+        """
+        imports = sum([block.get_imports() for block in self.get_enabled_blocks()], [])
+        imports = sorted(set(imports))
+        return imports
+
+    def get_variables(self):
+        """
+        Get a list of all variables in this flow graph namespace.
+        Exclude paramterized variables.
+        
+        Returns:
+            a sorted list of variable blocks in order of dependency (indep -> dep)
+        """
+        variables = filter(lambda b: _variable_matcher.match(b.get_key()), self.get_enabled_blocks())
+        return expr_utils.sort_objects(variables, lambda v: v.get_id(), lambda v: v.get_var_make())
+
+    def get_parameters(self):
+        """
+        Get a list of all paramterized variables in this flow graph namespace.
+        
+        Returns:
+            a list of paramterized variables
+        """
+        parameters = filter(lambda b: _parameter_matcher.match(b.get_key()), self.get_enabled_blocks())
+        return parameters
+
+    def get_monitors(self):
+        """
+        Get a list of all ControlPort monitors
+        """
+        monitors = filter(lambda b: _monitors_searcher.search(b.get_key()), self.get_enabled_blocks())
+        return monitors
+
+    def rewrite(self):
+        """
+        Flag the namespace to be renewed.
+        """
+        def reconnect_bus_blocks():
+            for block in self.get_blocks():
+                
+                if 'bus' in map(lambda a: a.get_type(), block.get_sources_gui()):
+                    
+                    
+                    for i in range(len(block.get_sources_gui())):
+                        if len(block.get_sources_gui()[i].get_connections()) > 0:
+                            source = block.get_sources_gui()[i]
+                            sink = []
+                            
+                            for j in range(len(source.get_connections())):
+                                sink.append(source.get_connections()[j].get_sink());
+                        
+                                        
+                            for elt in source.get_connections():
+                                self.remove_element(elt);
+                            for j in sink:
+                                self.connect(source, j);
+        self._renew_eval_ns = True
+        _FlowGraph.rewrite(self);
+        reconnect_bus_blocks();
+
+    def evaluate(self, expr):
+        """
+        Evaluate the expression.
+        
+        Args:
+            expr: the string expression
+        @throw Exception bad expression
+        
+        Returns:
+            the evaluated data
+        """
+        if self._renew_eval_ns:
+            self._renew_eval_ns = False
+            #reload namespace
+            n = dict()
+            #load imports
+            for imp in self.get_imports():
+                try: exec imp in n
+                except: pass
+            #load parameters
+            np = dict()
+            for parameter in self.get_parameters():
+                try:
+                    e = eval(parameter.get_param('value').to_code(), n, n)
+                    np[parameter.get_id()] = e
+                except: pass
+            n.update(np) #merge param namespace
+            #load variables
+            for variable in self.get_variables():
+                try:
+                    e = eval(variable.get_param('value').to_code(), n, n)
+                    n[variable.get_id()] = e
+                except: pass
+            #make namespace public
+            self.n = n
+            self.n_hash = hash(str(n))
+        #evaluate
+        e = self._eval(expr, self.n, self.n_hash)
+        return e
diff --git a/grc/python/Generator.py b/grc/python/Generator.py
index 47fe1d98fd..005ed4c2b3 100644
--- a/grc/python/Generator.py
+++ b/grc/python/Generator.py
@@ -24,137 +24,137 @@ import tempfile
 from Cheetah.Template import Template
 import expr_utils
 from Constants import \
-	TOP_BLOCK_FILE_MODE, HIER_BLOCK_FILE_MODE, \
-	HIER_BLOCKS_LIB_DIR, FLOW_GRAPH_TEMPLATE
+    TOP_BLOCK_FILE_MODE, HIER_BLOCK_FILE_MODE, \
+    HIER_BLOCKS_LIB_DIR, FLOW_GRAPH_TEMPLATE
 import convert_hier
 from .. gui import Messages
 
 class Generator(object):
 
-	def __init__(self, flow_graph, file_path):
-		"""
-		Initialize the generator object.
-		Determine the file to generate.
-		
-		Args:
-		    flow_graph: the flow graph object
-		    file_path: the path to write the file to
-		"""
-		self._flow_graph = flow_graph
-		self._generate_options = self._flow_graph.get_option('generate_options')
-		if self._generate_options == 'hb':
-			self._mode = HIER_BLOCK_FILE_MODE
-			dirname = HIER_BLOCKS_LIB_DIR
-		else:
-			self._mode = TOP_BLOCK_FILE_MODE
-			dirname = os.path.dirname(file_path)
-			#handle the case where the directory is read-only
-			#in this case, use the system's temp directory
-			if not os.access(dirname, os.W_OK):
-				dirname = tempfile.gettempdir()
-		filename = self._flow_graph.get_option('id') + '.py'
-		self._file_path = os.path.join(dirname, filename)
+    def __init__(self, flow_graph, file_path):
+        """
+        Initialize the generator object.
+        Determine the file to generate.
+        
+        Args:
+            flow_graph: the flow graph object
+            file_path: the path to write the file to
+        """
+        self._flow_graph = flow_graph
+        self._generate_options = self._flow_graph.get_option('generate_options')
+        if self._generate_options == 'hb':
+            self._mode = HIER_BLOCK_FILE_MODE
+            dirname = HIER_BLOCKS_LIB_DIR
+        else:
+            self._mode = TOP_BLOCK_FILE_MODE
+            dirname = os.path.dirname(file_path)
+            #handle the case where the directory is read-only
+            #in this case, use the system's temp directory
+            if not os.access(dirname, os.W_OK):
+                dirname = tempfile.gettempdir()
+        filename = self._flow_graph.get_option('id') + '.py'
+        self._file_path = os.path.join(dirname, filename)
 
-	def get_file_path(self): return self._file_path
+    def get_file_path(self): return self._file_path
 
-	def write(self):
-		#do throttle warning
-		throttled = any(map(lambda b: b.throttle(), self._flow_graph.get_enabled_blocks()))
-		if not throttled and self._generate_options != 'hb':
-			Messages.send_warning('''\
+    def write(self):
+        #do throttle warning
+        throttled = any(map(lambda b: b.throttle(), self._flow_graph.get_enabled_blocks()))
+        if not throttled and self._generate_options != 'hb':
+            Messages.send_warning('''\
 This flow graph may not have flow control: no audio or usrp blocks found. \
 Add a Misc->Throttle block to your flow graph to avoid CPU congestion.''')
-		#generate
-		open(self.get_file_path(), 'w').write(str(self))
-		if self._generate_options == 'hb':
-			#convert hier block to xml wrapper
-			convert_hier.convert_hier(self._flow_graph, self.get_file_path())
-		os.chmod(self.get_file_path(), self._mode)
+        #generate
+        open(self.get_file_path(), 'w').write(str(self))
+        if self._generate_options == 'hb':
+            #convert hier block to xml wrapper
+            convert_hier.convert_hier(self._flow_graph, self.get_file_path())
+        os.chmod(self.get_file_path(), self._mode)
 
-	def get_popen(self):
-		"""
-		Execute this python flow graph.
-		
-		Returns:
-		    a popen object
-		"""
-		#extract the path to the python executable
-		python_exe = sys.executable
+    def get_popen(self):
+        """
+        Execute this python flow graph.
+        
+        Returns:
+            a popen object
+        """
+        #extract the path to the python executable
+        python_exe = sys.executable
 
-		#when using wx gui on mac os, execute with pythonw
-		#using pythonw is not necessary anymore, disabled below
-		#if self._generate_options == 'wx_gui' and 'darwin' in sys.platform.lower():
-		#	python_exe = 'pythonw'
+        #when using wx gui on mac os, execute with pythonw
+        #using pythonw is not necessary anymore, disabled below
+        #if self._generate_options == 'wx_gui' and 'darwin' in sys.platform.lower():
+        #   python_exe = 'pythonw'
 
-		#setup the command args to run
-		cmds = [python_exe, '-u', self.get_file_path()] #-u is unbuffered stdio
+        #setup the command args to run
+        cmds = [python_exe, '-u', self.get_file_path()] #-u is unbuffered stdio
 
-		#when in no gui mode on linux, use an xterm (looks nice)
-		if self._generate_options == 'no_gui' and 'linux' in sys.platform.lower():
-			cmds = ['xterm', '-e'] + cmds
+        #when in no gui mode on linux, use an xterm (looks nice)
+        if self._generate_options == 'no_gui' and 'linux' in sys.platform.lower():
+            cmds = ['xterm', '-e'] + cmds
 
-		p = subprocess.Popen(args=cmds, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=False, universal_newlines=True)
-		return p
+        p = subprocess.Popen(args=cmds, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=False, universal_newlines=True)
+        return p
 
-	def __str__(self):
-		"""
-		Convert the flow graph to python code.
-		
-		Returns:
-		    a string of python code
-		"""
-		title = self._flow_graph.get_option('title') or self._flow_graph.get_option('id').replace('_', ' ').title()
-		imports = self._flow_graph.get_imports()
-		variables = self._flow_graph.get_variables()
-		parameters = self._flow_graph.get_parameters()
-                monitors = self._flow_graph.get_monitors()
-		#list of blocks not including variables and imports and parameters and disabled
-		def _get_block_sort_text(block):
-			code = block.get_make().replace(block.get_id(), ' ')
-			try: code += block.get_param('notebook').get_value() #older gui markup w/ wxgui
-			except: pass
-			try: code += block.get_param('gui_hint').get_value() #newer gui markup w/ qtgui
-			except: pass
-			return code
-		blocks = expr_utils.sort_objects(
-			self._flow_graph.get_enabled_blocks(),
-			lambda b: b.get_id(), _get_block_sort_text
-		)
-		#list of regular blocks (all blocks minus the special ones)
-		blocks = filter(lambda b: b not in (imports + parameters), blocks)
-		#list of connections where each endpoint is enabled
-		connections = filter(lambda c: not (c.is_bus() or c.is_msg() or c.is_message()), self._flow_graph.get_enabled_connections())
-		messages = filter(lambda c: c.is_msg(), self._flow_graph.get_enabled_connections())
-		messages2 = filter(lambda c: c.is_message(), self._flow_graph.get_enabled_connections())
-		#list of variable names
-		var_ids = [var.get_id() for var in parameters + variables]
-		#prepend self.
-		replace_dict = dict([(var_id, 'self.%s'%var_id) for var_id in var_ids])
-		#list of callbacks
-		callbacks = [
-			expr_utils.expr_replace(cb, replace_dict)
-			for cb in sum([block.get_callbacks() for block in self._flow_graph.get_enabled_blocks()], [])
-		]
-		#map var id to callbacks
-		var_id2cbs = dict(
-			[(var_id, filter(lambda c: expr_utils.get_variable_dependencies(c, [var_id]), callbacks))
-			for var_id in var_ids]
-		)
-		#load the namespace
-		namespace = {
-			'title': title,
-			'imports': imports,
-			'flow_graph': self._flow_graph,
-			'variables': variables,
-			'parameters': parameters,
+    def __str__(self):
+        """
+        Convert the flow graph to python code.
+        
+        Returns:
+            a string of python code
+        """
+        title = self._flow_graph.get_option('title') or self._flow_graph.get_option('id').replace('_', ' ').title()
+        imports = self._flow_graph.get_imports()
+        variables = self._flow_graph.get_variables()
+        parameters = self._flow_graph.get_parameters()
+        monitors = self._flow_graph.get_monitors()
+        #list of blocks not including variables and imports and parameters and disabled
+        def _get_block_sort_text(block):
+            code = block.get_make().replace(block.get_id(), ' ')
+            try: code += block.get_param('notebook').get_value() #older gui markup w/ wxgui
+            except: pass
+            try: code += block.get_param('gui_hint').get_value() #newer gui markup w/ qtgui
+            except: pass
+            return code
+        blocks = expr_utils.sort_objects(
+            self._flow_graph.get_enabled_blocks(),
+            lambda b: b.get_id(), _get_block_sort_text
+        )
+        #list of regular blocks (all blocks minus the special ones)
+        blocks = filter(lambda b: b not in (imports + parameters), blocks)
+        #list of connections where each endpoint is enabled
+        connections = filter(lambda c: not (c.is_bus() or c.is_msg() or c.is_message()), self._flow_graph.get_enabled_connections())
+        messages = filter(lambda c: c.is_msg(), self._flow_graph.get_enabled_connections())
+        messages2 = filter(lambda c: c.is_message(), self._flow_graph.get_enabled_connections())
+        #list of variable names
+        var_ids = [var.get_id() for var in parameters + variables]
+        #prepend self.
+        replace_dict = dict([(var_id, 'self.%s'%var_id) for var_id in var_ids])
+        #list of callbacks
+        callbacks = [
+            expr_utils.expr_replace(cb, replace_dict)
+            for cb in sum([block.get_callbacks() for block in self._flow_graph.get_enabled_blocks()], [])
+        ]
+        #map var id to callbacks
+        var_id2cbs = dict(
+            [(var_id, filter(lambda c: expr_utils.get_variable_dependencies(c, [var_id]), callbacks))
+            for var_id in var_ids]
+        )
+        #load the namespace
+        namespace = {
+            'title': title,
+            'imports': imports,
+            'flow_graph': self._flow_graph,
+            'variables': variables,
+            'parameters': parameters,
                         'monitors': monitors,
-			'blocks': blocks,
-			'connections': connections,
-			'messages': messages,
-			'messages2': messages2,
-			'generate_options': self._generate_options,
-			'var_id2cbs': var_id2cbs,
-		}
-		#build the template
-		t = Template(open(FLOW_GRAPH_TEMPLATE, 'r').read(), namespace)
-		return str(t)
+            'blocks': blocks,
+            'connections': connections,
+            'messages': messages,
+            'messages2': messages2,
+            'generate_options': self._generate_options,
+            'var_id2cbs': var_id2cbs,
+        }
+        #build the template
+        t = Template(open(FLOW_GRAPH_TEMPLATE, 'r').read(), namespace)
+        return str(t)
diff --git a/grc/python/Param.py b/grc/python/Param.py
index 696f16cc94..e603d6cdbe 100644
--- a/grc/python/Param.py
+++ b/grc/python/Param.py
@@ -34,51 +34,51 @@ _check_id_matcher = re.compile('^[a-z|A-Z]\w*$')
 _show_id_matcher = re.compile('^(variable\w*|parameter|options|notebook)$')
 
 class FileParam(EntryParam):
-	"""Provide an entry box for filename and a button to browse for a file."""
+    """Provide an entry box for filename and a button to browse for a file."""
 
-	def __init__(self, *args, **kwargs):
-		EntryParam.__init__(self, *args, **kwargs)
-		input = gtk.Button('...')
-		input.connect('clicked', self._handle_clicked)
-		self.pack_start(input, False)
+    def __init__(self, *args, **kwargs):
+        EntryParam.__init__(self, *args, **kwargs)
+        input = gtk.Button('...')
+        input.connect('clicked', self._handle_clicked)
+        self.pack_start(input, False)
 
-	def _handle_clicked(self, widget=None):
-		"""
-		If the button was clicked, open a file dialog in open/save format.
-		Replace the text in the entry with the new filename from the file dialog.
-		"""
-		#get the paths
-		file_path = self.param.is_valid() and self.param.get_evaluated() or ''
-		(dirname, basename) = os.path.isfile(file_path) and os.path.split(file_path) or (file_path, '')
-		if not os.path.exists(dirname): dirname = os.getcwd() #fix bad paths
-		#build the dialog
-		if self.param.get_type() == 'file_open':
-			file_dialog = gtk.FileChooserDialog('Open a Data File...', None,
-				gtk.FILE_CHOOSER_ACTION_OPEN, ('gtk-cancel',gtk.RESPONSE_CANCEL,'gtk-open',gtk.RESPONSE_OK))
-		elif self.param.get_type() == 'file_save':
-			file_dialog = gtk.FileChooserDialog('Save a Data File...', None,
-				gtk.FILE_CHOOSER_ACTION_SAVE, ('gtk-cancel',gtk.RESPONSE_CANCEL, 'gtk-save',gtk.RESPONSE_OK))
-			file_dialog.set_do_overwrite_confirmation(True)
-			file_dialog.set_current_name(basename) #show the current filename
-		file_dialog.set_current_folder(dirname) #current directory
-		file_dialog.set_select_multiple(False)
-		file_dialog.set_local_only(True)
-		if gtk.RESPONSE_OK == file_dialog.run(): #run the dialog
-			file_path = file_dialog.get_filename() #get the file path
-			self._input.set_text(file_path)
-			self._handle_changed()
-		file_dialog.destroy() #destroy the dialog
+    def _handle_clicked(self, widget=None):
+        """
+        If the button was clicked, open a file dialog in open/save format.
+        Replace the text in the entry with the new filename from the file dialog.
+        """
+        #get the paths
+        file_path = self.param.is_valid() and self.param.get_evaluated() or ''
+        (dirname, basename) = os.path.isfile(file_path) and os.path.split(file_path) or (file_path, '')
+        if not os.path.exists(dirname): dirname = os.getcwd() #fix bad paths
+        #build the dialog
+        if self.param.get_type() == 'file_open':
+            file_dialog = gtk.FileChooserDialog('Open a Data File...', None,
+                gtk.FILE_CHOOSER_ACTION_OPEN, ('gtk-cancel',gtk.RESPONSE_CANCEL,'gtk-open',gtk.RESPONSE_OK))
+        elif self.param.get_type() == 'file_save':
+            file_dialog = gtk.FileChooserDialog('Save a Data File...', None,
+                gtk.FILE_CHOOSER_ACTION_SAVE, ('gtk-cancel',gtk.RESPONSE_CANCEL, 'gtk-save',gtk.RESPONSE_OK))
+            file_dialog.set_do_overwrite_confirmation(True)
+            file_dialog.set_current_name(basename) #show the current filename
+        file_dialog.set_current_folder(dirname) #current directory
+        file_dialog.set_select_multiple(False)
+        file_dialog.set_local_only(True)
+        if gtk.RESPONSE_OK == file_dialog.run(): #run the dialog
+            file_path = file_dialog.get_filename() #get the file path
+            self._input.set_text(file_path)
+            self._handle_changed()
+        file_dialog.destroy() #destroy the dialog
 
 #blacklist certain ids, its not complete, but should help
 import __builtin__
 ID_BLACKLIST = ['self', 'options', 'gr', 'blks2', 'wxgui', 'wx', 'math', 'forms', 'firdes'] + \
-	filter(lambda x: not x.startswith('_'), dir(gr.top_block())) + dir(__builtin__)
+    filter(lambda x: not x.startswith('_'), dir(gr.top_block())) + dir(__builtin__)
 #define types, native python + numpy
 VECTOR_TYPES = (tuple, list, set, numpy.ndarray)
 COMPLEX_TYPES = [complex, numpy.complex, numpy.complex64, numpy.complex128]
 REAL_TYPES = [float, numpy.float, numpy.float32, numpy.float64]
 INT_TYPES = [int, long, numpy.int, numpy.int8, numpy.int16, numpy.int32, numpy.uint64,
-	numpy.uint, numpy.uint8, numpy.uint16, numpy.uint32, numpy.uint64]
+    numpy.uint, numpy.uint8, numpy.uint16, numpy.uint32, numpy.uint64]
 #cast to tuple for isinstance, concat subtypes
 COMPLEX_TYPES = tuple(COMPLEX_TYPES + REAL_TYPES + INT_TYPES)
 REAL_TYPES = tuple(REAL_TYPES + INT_TYPES)
@@ -86,389 +86,389 @@ INT_TYPES = tuple(INT_TYPES)
 
 class Param(_Param, _GUIParam):
 
-	def __init__(self, **kwargs):
-		_Param.__init__(self, **kwargs)
-		_GUIParam.__init__(self)
-		self._init = False
-		self._hostage_cells = list()
+    def __init__(self, **kwargs):
+        _Param.__init__(self, **kwargs)
+        _GUIParam.__init__(self)
+        self._init = False
+        self._hostage_cells = list()
 
-	def get_types(self): return (
-		'raw', 'enum',
-		'complex', 'real', 'float', 'int',
-		'complex_vector', 'real_vector', 'float_vector', 'int_vector',
-		'hex', 'string', 'bool',
-		'file_open', 'file_save',
-		'id', 'stream_id',
-		'grid_pos', 'notebook', 'gui_hint',
-		'import',
-	)
+    def get_types(self): return (
+        'raw', 'enum',
+        'complex', 'real', 'float', 'int',
+        'complex_vector', 'real_vector', 'float_vector', 'int_vector',
+        'hex', 'string', 'bool',
+        'file_open', 'file_save',
+        'id', 'stream_id',
+        'grid_pos', 'notebook', 'gui_hint',
+        'import',
+    )
 
-	def __repr__(self):
-		"""
-		Get the repr (nice string format) for this param.
-		
-		Returns:
-		    the string representation
-		"""
-		##################################################
-		# truncate helper method
-		##################################################
-		def _truncate(string, style=0):
-			max_len = max(27 - len(self.get_name()), 3)
-			if len(string) > max_len:
-				if style < 0: #front truncate
-					string = '...' + string[3-max_len:]
-				elif style == 0: #center truncate
-					string = string[:max_len/2 -3] + '...' + string[-max_len/2:]
-				elif style > 0: #rear truncate
-					string = string[:max_len-3] + '...'
-			return string
-		##################################################
-		# simple conditions
-		##################################################
-		if not self.is_valid(): return _truncate(self.get_value())
-		if self.get_value() in self.get_option_keys(): return self.get_option(self.get_value()).get_name()
-		##################################################
-		# display logic for numbers
-		##################################################
-		def num_to_str(num):
-			if isinstance(num, COMPLEX_TYPES):
-				num = complex(num) #cast to python complex
-				if num == 0: return '0' #value is zero
-				elif num.imag == 0: return '%s'%eng_notation.num_to_str(num.real) #value is real
-				elif num.real == 0: return '%sj'%eng_notation.num_to_str(num.imag) #value is imaginary
-				elif num.imag < 0: return '%s-%sj'%(eng_notation.num_to_str(num.real), eng_notation.num_to_str(abs(num.imag)))
-				else: return '%s+%sj'%(eng_notation.num_to_str(num.real), eng_notation.num_to_str(num.imag))
-			else: return str(num)
-		##################################################
-		# split up formatting by type
-		##################################################
-		truncate = 0 #default center truncate
-		e = self.get_evaluated()
-		t = self.get_type()
-		if isinstance(e, bool): return str(e)
-		elif isinstance(e, COMPLEX_TYPES): dt_str = num_to_str(e)
-		elif isinstance(e, VECTOR_TYPES): #vector types
-			if len(e) > 8:
-				dt_str = self.get_value() #large vectors use code
-				truncate = 1
-			else: dt_str = ', '.join(map(num_to_str, e)) #small vectors use eval
-		elif t in ('file_open', 'file_save'):
-			dt_str = self.get_value()
-			truncate = -1
-		else: dt_str = str(e) #other types
-		##################################################
-		# done
-		##################################################
-		return _truncate(dt_str, truncate)
+    def __repr__(self):
+        """
+        Get the repr (nice string format) for this param.
+        
+        Returns:
+            the string representation
+        """
+        ##################################################
+        # truncate helper method
+        ##################################################
+        def _truncate(string, style=0):
+            max_len = max(27 - len(self.get_name()), 3)
+            if len(string) > max_len:
+                if style < 0: #front truncate
+                    string = '...' + string[3-max_len:]
+                elif style == 0: #center truncate
+                    string = string[:max_len/2 -3] + '...' + string[-max_len/2:]
+                elif style > 0: #rear truncate
+                    string = string[:max_len-3] + '...'
+            return string
+        ##################################################
+        # simple conditions
+        ##################################################
+        if not self.is_valid(): return _truncate(self.get_value())
+        if self.get_value() in self.get_option_keys(): return self.get_option(self.get_value()).get_name()
+        ##################################################
+        # display logic for numbers
+        ##################################################
+        def num_to_str(num):
+            if isinstance(num, COMPLEX_TYPES):
+                num = complex(num) #cast to python complex
+                if num == 0: return '0' #value is zero
+                elif num.imag == 0: return '%s'%eng_notation.num_to_str(num.real) #value is real
+                elif num.real == 0: return '%sj'%eng_notation.num_to_str(num.imag) #value is imaginary
+                elif num.imag < 0: return '%s-%sj'%(eng_notation.num_to_str(num.real), eng_notation.num_to_str(abs(num.imag)))
+                else: return '%s+%sj'%(eng_notation.num_to_str(num.real), eng_notation.num_to_str(num.imag))
+            else: return str(num)
+        ##################################################
+        # split up formatting by type
+        ##################################################
+        truncate = 0 #default center truncate
+        e = self.get_evaluated()
+        t = self.get_type()
+        if isinstance(e, bool): return str(e)
+        elif isinstance(e, COMPLEX_TYPES): dt_str = num_to_str(e)
+        elif isinstance(e, VECTOR_TYPES): #vector types
+            if len(e) > 8:
+                dt_str = self.get_value() #large vectors use code
+                truncate = 1
+            else: dt_str = ', '.join(map(num_to_str, e)) #small vectors use eval
+        elif t in ('file_open', 'file_save'):
+            dt_str = self.get_value()
+            truncate = -1
+        else: dt_str = str(e) #other types
+        ##################################################
+        # done
+        ##################################################
+        return _truncate(dt_str, truncate)
 
-	def get_input(self, *args, **kwargs):
-		if self.get_type() in ('file_open', 'file_save'): return FileParam(self, *args, **kwargs)
-		return _GUIParam.get_input(self, *args, **kwargs)
+    def get_input(self, *args, **kwargs):
+        if self.get_type() in ('file_open', 'file_save'): return FileParam(self, *args, **kwargs)
+        return _GUIParam.get_input(self, *args, **kwargs)
 
-	def get_color(self):
-		"""
-		Get the color that represents this param's type.
-		
-		Returns:
-		    a hex color code.
-		"""
-		try:
-			return {
-				#number types
-				'complex': Constants.COMPLEX_COLOR_SPEC,
-				'real': Constants.FLOAT_COLOR_SPEC,
-				'float': Constants.FLOAT_COLOR_SPEC,
-				'int': Constants.INT_COLOR_SPEC,
-				#vector types
-				'complex_vector': Constants.COMPLEX_VECTOR_COLOR_SPEC,
-				'real_vector': Constants.FLOAT_VECTOR_COLOR_SPEC,
+    def get_color(self):
+        """
+        Get the color that represents this param's type.
+        
+        Returns:
+            a hex color code.
+        """
+        try:
+            return {
+                #number types
+                'complex': Constants.COMPLEX_COLOR_SPEC,
+                'real': Constants.FLOAT_COLOR_SPEC,
+                'float': Constants.FLOAT_COLOR_SPEC,
+                'int': Constants.INT_COLOR_SPEC,
+                #vector types
+                'complex_vector': Constants.COMPLEX_VECTOR_COLOR_SPEC,
+                'real_vector': Constants.FLOAT_VECTOR_COLOR_SPEC,
                                 'float_vector': Constants.FLOAT_VECTOR_COLOR_SPEC,
-				'int_vector': Constants.INT_VECTOR_COLOR_SPEC,
-				#special
-				'bool': Constants.INT_COLOR_SPEC,
-				'hex': Constants.INT_COLOR_SPEC,
-				'string': Constants.BYTE_VECTOR_COLOR_SPEC,
-				'id': Constants.ID_COLOR_SPEC,
-				'stream_id': Constants.ID_COLOR_SPEC,
-				'grid_pos': Constants.INT_VECTOR_COLOR_SPEC,
-				'notebook': Constants.INT_VECTOR_COLOR_SPEC,
-				'raw': Constants.WILDCARD_COLOR_SPEC,
-			}[self.get_type()]
-		except: return _Param.get_color(self)
+                'int_vector': Constants.INT_VECTOR_COLOR_SPEC,
+                #special
+                'bool': Constants.INT_COLOR_SPEC,
+                'hex': Constants.INT_COLOR_SPEC,
+                'string': Constants.BYTE_VECTOR_COLOR_SPEC,
+                'id': Constants.ID_COLOR_SPEC,
+                'stream_id': Constants.ID_COLOR_SPEC,
+                'grid_pos': Constants.INT_VECTOR_COLOR_SPEC,
+                'notebook': Constants.INT_VECTOR_COLOR_SPEC,
+                'raw': Constants.WILDCARD_COLOR_SPEC,
+            }[self.get_type()]
+        except: return _Param.get_color(self)
 
-	def get_hide(self):
-		"""
-		Get the hide value from the base class.
-		Hide the ID parameter for most blocks. Exceptions below.
-		If the parameter controls a port type, vlen, or nports, return part.
-		If the parameter is an empty grid position, return part.
-		These parameters are redundant to display in the flow graph view.
-		
-		Returns:
-		    hide the hide property string
-		"""
-		hide = _Param.get_hide(self)
-		if hide: return hide
-		#hide ID in non variable blocks
-		if self.get_key() == 'id' and not _show_id_matcher.match(self.get_parent().get_key()): return 'part'
-		#hide port controllers for type and nports
-		if self.get_key() in ' '.join(map(
-			lambda p: ' '.join([p._type, p._nports]), self.get_parent().get_ports())
-		): return 'part'
-		#hide port controllers for vlen, when == 1
-		if self.get_key() in ' '.join(map(
-			lambda p: p._vlen, self.get_parent().get_ports())
-		):
-			try:
-				if int(self.get_evaluated()) == 1: return 'part'
-			except: pass
-		#hide empty grid positions
-		if self.get_key() in ('grid_pos', 'notebook') and not self.get_value(): return 'part'
-		return hide
+    def get_hide(self):
+        """
+        Get the hide value from the base class.
+        Hide the ID parameter for most blocks. Exceptions below.
+        If the parameter controls a port type, vlen, or nports, return part.
+        If the parameter is an empty grid position, return part.
+        These parameters are redundant to display in the flow graph view.
+        
+        Returns:
+            hide the hide property string
+        """
+        hide = _Param.get_hide(self)
+        if hide: return hide
+        #hide ID in non variable blocks
+        if self.get_key() == 'id' and not _show_id_matcher.match(self.get_parent().get_key()): return 'part'
+        #hide port controllers for type and nports
+        if self.get_key() in ' '.join(map(
+            lambda p: ' '.join([p._type, p._nports]), self.get_parent().get_ports())
+        ): return 'part'
+        #hide port controllers for vlen, when == 1
+        if self.get_key() in ' '.join(map(
+            lambda p: p._vlen, self.get_parent().get_ports())
+        ):
+            try:
+                if int(self.get_evaluated()) == 1: return 'part'
+            except: pass
+        #hide empty grid positions
+        if self.get_key() in ('grid_pos', 'notebook') and not self.get_value(): return 'part'
+        return hide
 
-	def validate(self):
-		"""
-		Validate the param.
-		A test evaluation is performed
-		"""
-		_Param.validate(self) #checks type
-		self._evaluated = None
-		try: self._evaluated = self.evaluate()
-		except Exception, e: self.add_error_message(str(e))
+    def validate(self):
+        """
+        Validate the param.
+        A test evaluation is performed
+        """
+        _Param.validate(self) #checks type
+        self._evaluated = None
+        try: self._evaluated = self.evaluate()
+        except Exception, e: self.add_error_message(str(e))
 
-	def get_evaluated(self): return self._evaluated
+    def get_evaluated(self): return self._evaluated
 
-	def evaluate(self):
-		"""
-		Evaluate the value.
-		
-		Returns:
-		    evaluated type
-		"""
-		self._init = True
-		self._lisitify_flag = False
-		self._stringify_flag = False
-		self._hostage_cells = list()
-		def eval_string(v):
-			try:
-				e = self.get_parent().get_parent().evaluate(v)
-				if isinstance(e, str): return e
-				raise Exception #want to stringify
-			except:
-				self._stringify_flag = True
-				return v
-		t = self.get_type()
-		v = self.get_value()
-		#########################
-		# Enum Type
-		#########################
-		if self.is_enum(): return v
-		#########################
-		# Numeric Types
-		#########################
-		elif t in ('raw', 'complex', 'real', 'float', 'int', 'hex', 'bool'):
-			#raise exception if python cannot evaluate this value
-			try: e = self.get_parent().get_parent().evaluate(v)
-			except Exception, e: raise Exception, 'Value "%s" cannot be evaluated:\n%s'%(v, e)
-			#raise an exception if the data is invalid
-			if t == 'raw': return e
-			elif t == 'complex':
-				if not isinstance(e, COMPLEX_TYPES):
-					raise Exception, 'Expression "%s" is invalid for type complex.'%str(e)
-				return e
-			elif t == 'real' or t == 'float':
-				if not isinstance(e, REAL_TYPES):
-					raise Exception, 'Expression "%s" is invalid for type float.'%str(e)
-				return e
-			elif t == 'int':
-				if not isinstance(e, INT_TYPES):
-					raise Exception, 'Expression "%s" is invalid for type integer.'%str(e)
-				return e
-			elif t == 'hex': return hex(e)
-			elif t == 'bool':
-				if not isinstance(e, bool):
-					raise Exception, 'Expression "%s" is invalid for type bool.'%str(e)
-				return e
-			else: raise TypeError, 'Type "%s" not handled'%t
-		#########################
-		# Numeric Vector Types
-		#########################
-		elif t in ('complex_vector', 'real_vector', 'float_vector', 'int_vector'):
-			if not v: v = '()' #turn a blank string into an empty list, so it will eval
-			#raise exception if python cannot evaluate this value
-			try: e = self.get_parent().get_parent().evaluate(v)
-			except Exception, e: raise Exception, 'Value "%s" cannot be evaluated:\n%s'%(v, e)
-			#raise an exception if the data is invalid
-			if t == 'complex_vector':
-				if not isinstance(e, VECTOR_TYPES):
-					self._lisitify_flag = True
-					e = [e]
-				if not all([isinstance(ei, COMPLEX_TYPES) for ei in e]):
-					raise Exception, 'Expression "%s" is invalid for type complex vector.'%str(e)
-				return e
-			elif t == 'real_vector' or t == 'float_vector':
-				if not isinstance(e, VECTOR_TYPES):
-					self._lisitify_flag = True
-					e = [e]
-				if not all([isinstance(ei, REAL_TYPES) for ei in e]):
-					raise Exception, 'Expression "%s" is invalid for type float vector.'%str(e)
-				return e
-			elif t == 'int_vector':
-				if not isinstance(e, VECTOR_TYPES):
-					self._lisitify_flag = True
-					e = [e]
-				if not all([isinstance(ei, INT_TYPES) for ei in e]):
-					raise Exception, 'Expression "%s" is invalid for type integer vector.'%str(e)
-				return e
-		#########################
-		# String Types
-		#########################
-		elif t in ('string', 'file_open', 'file_save'):
-			#do not check if file/directory exists, that is a runtime issue
-			e = eval_string(v)
-			return str(e)
-		#########################
-		# Unique ID Type
-		#########################
-		elif t == 'id':
-			#can python use this as a variable?
-			if not _check_id_matcher.match(v):
-				raise Exception, 'ID "%s" must begin with a letter and may contain letters, numbers, and underscores.'%v
-			ids = [param.get_value() for param in self.get_all_params(t)]
-			if ids.count(v) > 1: #id should only appear once, or zero times if block is disabled
-				raise Exception, 'ID "%s" is not unique.'%v
-			if v in ID_BLACKLIST:
-				raise Exception, 'ID "%s" is blacklisted.'%v
-			return v
-		#########################
-		# Stream ID Type
-		#########################
-		elif t == 'stream_id':
-			#get a list of all stream ids used in the virtual sinks
-			ids = [param.get_value() for param in filter(
-				lambda p: p.get_parent().is_virtual_sink(),
-				self.get_all_params(t),
-			)]
-			#check that the virtual sink's stream id is unique
-			if self.get_parent().is_virtual_sink():
-				if ids.count(v) > 1: #id should only appear once, or zero times if block is disabled
-					raise Exception, 'Stream ID "%s" is not unique.'%v
-			#check that the virtual source's steam id is found
-			if self.get_parent().is_virtual_source():
-				if v not in ids:
-					raise Exception, 'Stream ID "%s" is not found.'%v
-			return v
-		#########################
-		# GUI Position/Hint
-		#########################
-		elif t == 'gui_hint':
-			if ':' in v: tab, pos = v.split(':')
-			elif '@' in v: tab, pos = v, ''
-			else: tab, pos = '', v
+    def evaluate(self):
+        """
+        Evaluate the value.
+        
+        Returns:
+            evaluated type
+        """
+        self._init = True
+        self._lisitify_flag = False
+        self._stringify_flag = False
+        self._hostage_cells = list()
+        def eval_string(v):
+            try:
+                e = self.get_parent().get_parent().evaluate(v)
+                if isinstance(e, str): return e
+                raise Exception #want to stringify
+            except:
+                self._stringify_flag = True
+                return v
+        t = self.get_type()
+        v = self.get_value()
+        #########################
+        # Enum Type
+        #########################
+        if self.is_enum(): return v
+        #########################
+        # Numeric Types
+        #########################
+        elif t in ('raw', 'complex', 'real', 'float', 'int', 'hex', 'bool'):
+            #raise exception if python cannot evaluate this value
+            try: e = self.get_parent().get_parent().evaluate(v)
+            except Exception, e: raise Exception, 'Value "%s" cannot be evaluated:\n%s'%(v, e)
+            #raise an exception if the data is invalid
+            if t == 'raw': return e
+            elif t == 'complex':
+                if not isinstance(e, COMPLEX_TYPES):
+                    raise Exception, 'Expression "%s" is invalid for type complex.'%str(e)
+                return e
+            elif t == 'real' or t == 'float':
+                if not isinstance(e, REAL_TYPES):
+                    raise Exception, 'Expression "%s" is invalid for type float.'%str(e)
+                return e
+            elif t == 'int':
+                if not isinstance(e, INT_TYPES):
+                    raise Exception, 'Expression "%s" is invalid for type integer.'%str(e)
+                return e
+            elif t == 'hex': return hex(e)
+            elif t == 'bool':
+                if not isinstance(e, bool):
+                    raise Exception, 'Expression "%s" is invalid for type bool.'%str(e)
+                return e
+            else: raise TypeError, 'Type "%s" not handled'%t
+        #########################
+        # Numeric Vector Types
+        #########################
+        elif t in ('complex_vector', 'real_vector', 'float_vector', 'int_vector'):
+            if not v: v = '()' #turn a blank string into an empty list, so it will eval
+            #raise exception if python cannot evaluate this value
+            try: e = self.get_parent().get_parent().evaluate(v)
+            except Exception, e: raise Exception, 'Value "%s" cannot be evaluated:\n%s'%(v, e)
+            #raise an exception if the data is invalid
+            if t == 'complex_vector':
+                if not isinstance(e, VECTOR_TYPES):
+                    self._lisitify_flag = True
+                    e = [e]
+                if not all([isinstance(ei, COMPLEX_TYPES) for ei in e]):
+                    raise Exception, 'Expression "%s" is invalid for type complex vector.'%str(e)
+                return e
+            elif t == 'real_vector' or t == 'float_vector':
+                if not isinstance(e, VECTOR_TYPES):
+                    self._lisitify_flag = True
+                    e = [e]
+                if not all([isinstance(ei, REAL_TYPES) for ei in e]):
+                    raise Exception, 'Expression "%s" is invalid for type float vector.'%str(e)
+                return e
+            elif t == 'int_vector':
+                if not isinstance(e, VECTOR_TYPES):
+                    self._lisitify_flag = True
+                    e = [e]
+                if not all([isinstance(ei, INT_TYPES) for ei in e]):
+                    raise Exception, 'Expression "%s" is invalid for type integer vector.'%str(e)
+                return e
+        #########################
+        # String Types
+        #########################
+        elif t in ('string', 'file_open', 'file_save'):
+            #do not check if file/directory exists, that is a runtime issue
+            e = eval_string(v)
+            return str(e)
+        #########################
+        # Unique ID Type
+        #########################
+        elif t == 'id':
+            #can python use this as a variable?
+            if not _check_id_matcher.match(v):
+                raise Exception, 'ID "%s" must begin with a letter and may contain letters, numbers, and underscores.'%v
+            ids = [param.get_value() for param in self.get_all_params(t)]
+            if ids.count(v) > 1: #id should only appear once, or zero times if block is disabled
+                raise Exception, 'ID "%s" is not unique.'%v
+            if v in ID_BLACKLIST:
+                raise Exception, 'ID "%s" is blacklisted.'%v
+            return v
+        #########################
+        # Stream ID Type
+        #########################
+        elif t == 'stream_id':
+            #get a list of all stream ids used in the virtual sinks
+            ids = [param.get_value() for param in filter(
+                lambda p: p.get_parent().is_virtual_sink(),
+                self.get_all_params(t),
+            )]
+            #check that the virtual sink's stream id is unique
+            if self.get_parent().is_virtual_sink():
+                if ids.count(v) > 1: #id should only appear once, or zero times if block is disabled
+                    raise Exception, 'Stream ID "%s" is not unique.'%v
+            #check that the virtual source's steam id is found
+            if self.get_parent().is_virtual_source():
+                if v not in ids:
+                    raise Exception, 'Stream ID "%s" is not found.'%v
+            return v
+        #########################
+        # GUI Position/Hint
+        #########################
+        elif t == 'gui_hint':
+            if ':' in v: tab, pos = v.split(':')
+            elif '@' in v: tab, pos = v, ''
+            else: tab, pos = '', v
 
-			if '@' in tab: tab, index = tab.split('@')
-			else: index = '?'
+            if '@' in tab: tab, index = tab.split('@')
+            else: index = '?'
 
-			widget_str = ({
-				(True, True): 'self.%(tab)s_grid_layout_%(index)s.addWidget(%(widget)s, %(pos)s)',
-				(True, False): 'self.%(tab)s_layout_%(index)s.addWidget(%(widget)s)',
-				(False, True): 'self.top_grid_layout.addWidget(%(widget)s, %(pos)s)',
-				(False, False): 'self.top_layout.addWidget(%(widget)s)',
-			}[bool(tab), bool(pos)])%{'tab': tab, 'index': index, 'widget': '%s', 'pos': pos}
+            widget_str = ({
+                (True, True): 'self.%(tab)s_grid_layout_%(index)s.addWidget(%(widget)s, %(pos)s)',
+                (True, False): 'self.%(tab)s_layout_%(index)s.addWidget(%(widget)s)',
+                (False, True): 'self.top_grid_layout.addWidget(%(widget)s, %(pos)s)',
+                (False, False): 'self.top_layout.addWidget(%(widget)s)',
+            }[bool(tab), bool(pos)])%{'tab': tab, 'index': index, 'widget': '%s', 'pos': pos}
 
-			def gui_hint(ws, w):
-				if 'layout' in w: ws = ws.replace('addWidget', 'addLayout')
-				return ws%w
+            def gui_hint(ws, w):
+                if 'layout' in w: ws = ws.replace('addWidget', 'addLayout')
+                return ws%w
 
-			return lambda w: gui_hint(widget_str, w)
-		#########################
-		# Grid Position Type
-		#########################
-		elif t == 'grid_pos':
-			if not v: return '' #allow for empty grid pos
-			e = self.get_parent().get_parent().evaluate(v)
-			if not isinstance(e, (list, tuple)) or len(e) != 4 or not all([isinstance(ei, int) for ei in e]):
-				raise Exception, 'A grid position must be a list of 4 integers.'
-			row, col, row_span, col_span = e
-			#check row, col
-			if row < 0 or col < 0:
-				raise Exception, 'Row and column must be non-negative.'
-			#check row span, col span
-			if row_span <= 0 or col_span <= 0:
-				raise Exception, 'Row and column span must be greater than zero.'
-			#get hostage cell parent
-			try: my_parent = self.get_parent().get_param('notebook').evaluate()
-			except: my_parent = ''
-			#calculate hostage cells
-			for r in range(row_span):
-				for c in range(col_span):
-					self._hostage_cells.append((my_parent, (row+r, col+c)))
-			#avoid collisions
-			params = filter(lambda p: p is not self, self.get_all_params('grid_pos'))
-			for param in params:
-				for parent, cell in param._hostage_cells:
-					if (parent, cell) in self._hostage_cells:
-						raise Exception, 'Another graphical element is using parent "%s", cell "%s".'%(str(parent), str(cell))
-			return e
-		#########################
-		# Notebook Page Type
-		#########################
-		elif t == 'notebook':
-			if not v: return '' #allow for empty notebook
-			#get a list of all notebooks
-			notebook_blocks = filter(lambda b: b.get_key() == 'notebook', self.get_parent().get_parent().get_enabled_blocks())
-			#check for notebook param syntax
-			try: notebook_id, page_index = map(str.strip, v.split(','))
-			except: raise Exception, 'Bad notebook page format.'
-			#check that the notebook id is valid
-			try: notebook_block = filter(lambda b: b.get_id() == notebook_id, notebook_blocks)[0]
-			except: raise Exception, 'Notebook id "%s" is not an existing notebook id.'%notebook_id
-			#check that page index exists
-			if int(page_index) not in range(len(notebook_block.get_param('labels').evaluate())):
-				raise Exception, 'Page index "%s" is not a valid index number.'%page_index
-			return notebook_id, page_index
-		#########################
-		# Import Type
-		#########################
-		elif t == 'import':
-			n = dict() #new namespace
-			try: exec v in n
-			except ImportError: raise Exception, 'Import "%s" failed.'%v
-			except Exception: raise Exception, 'Bad import syntax: "%s".'%v
-			return filter(lambda k: str(k) != '__builtins__', n.keys())
-		#########################
-		else: raise TypeError, 'Type "%s" not handled'%t
+            return lambda w: gui_hint(widget_str, w)
+        #########################
+        # Grid Position Type
+        #########################
+        elif t == 'grid_pos':
+            if not v: return '' #allow for empty grid pos
+            e = self.get_parent().get_parent().evaluate(v)
+            if not isinstance(e, (list, tuple)) or len(e) != 4 or not all([isinstance(ei, int) for ei in e]):
+                raise Exception, 'A grid position must be a list of 4 integers.'
+            row, col, row_span, col_span = e
+            #check row, col
+            if row < 0 or col < 0:
+                raise Exception, 'Row and column must be non-negative.'
+            #check row span, col span
+            if row_span <= 0 or col_span <= 0:
+                raise Exception, 'Row and column span must be greater than zero.'
+            #get hostage cell parent
+            try: my_parent = self.get_parent().get_param('notebook').evaluate()
+            except: my_parent = ''
+            #calculate hostage cells
+            for r in range(row_span):
+                for c in range(col_span):
+                    self._hostage_cells.append((my_parent, (row+r, col+c)))
+            #avoid collisions
+            params = filter(lambda p: p is not self, self.get_all_params('grid_pos'))
+            for param in params:
+                for parent, cell in param._hostage_cells:
+                    if (parent, cell) in self._hostage_cells:
+                        raise Exception, 'Another graphical element is using parent "%s", cell "%s".'%(str(parent), str(cell))
+            return e
+        #########################
+        # Notebook Page Type
+        #########################
+        elif t == 'notebook':
+            if not v: return '' #allow for empty notebook
+            #get a list of all notebooks
+            notebook_blocks = filter(lambda b: b.get_key() == 'notebook', self.get_parent().get_parent().get_enabled_blocks())
+            #check for notebook param syntax
+            try: notebook_id, page_index = map(str.strip, v.split(','))
+            except: raise Exception, 'Bad notebook page format.'
+            #check that the notebook id is valid
+            try: notebook_block = filter(lambda b: b.get_id() == notebook_id, notebook_blocks)[0]
+            except: raise Exception, 'Notebook id "%s" is not an existing notebook id.'%notebook_id
+            #check that page index exists
+            if int(page_index) not in range(len(notebook_block.get_param('labels').evaluate())):
+                raise Exception, 'Page index "%s" is not a valid index number.'%page_index
+            return notebook_id, page_index
+        #########################
+        # Import Type
+        #########################
+        elif t == 'import':
+            n = dict() #new namespace
+            try: exec v in n
+            except ImportError: raise Exception, 'Import "%s" failed.'%v
+            except Exception: raise Exception, 'Bad import syntax: "%s".'%v
+            return filter(lambda k: str(k) != '__builtins__', n.keys())
+        #########################
+        else: raise TypeError, 'Type "%s" not handled'%t
 
-	def to_code(self):
-		"""
-		Convert the value to code.
-		For string and list types, check the init flag, call evaluate().
-		This ensures that evaluate() was called to set the xxxify_flags.
-		
-		Returns:
-		    a string representing the code
-		"""
-		v = self.get_value()
-		t = self.get_type()
-		if t in ('string', 'file_open', 'file_save'): #string types
-			if not self._init: self.evaluate()
-			if self._stringify_flag: return '"%s"'%v.replace('"', '\"')
-			else: return v
-		elif t in ('complex_vector', 'real_vector', 'float_vector', 'int_vector'): #vector types
-			if not self._init: self.evaluate()
-			if self._lisitify_flag: return '(%s, )'%v
-			else: return '(%s)'%v
-		else: return v
+    def to_code(self):
+        """
+        Convert the value to code.
+        For string and list types, check the init flag, call evaluate().
+        This ensures that evaluate() was called to set the xxxify_flags.
+        
+        Returns:
+            a string representing the code
+        """
+        v = self.get_value()
+        t = self.get_type()
+        if t in ('string', 'file_open', 'file_save'): #string types
+            if not self._init: self.evaluate()
+            if self._stringify_flag: return '"%s"'%v.replace('"', '\"')
+            else: return v
+        elif t in ('complex_vector', 'real_vector', 'float_vector', 'int_vector'): #vector types
+            if not self._init: self.evaluate()
+            if self._lisitify_flag: return '(%s, )'%v
+            else: return '(%s)'%v
+        else: return v
 
-	def get_all_params(self, type):
-		"""
-		Get all the params from the flowgraph that have the given type.
-		
-		Args:
-		    type: the specified type
-		
-		Returns:
-		    a list of params
-		"""
-		return sum([filter(lambda p: p.get_type() == type, block.get_params()) for block in self.get_parent().get_parent().get_enabled_blocks()], [])
+    def get_all_params(self, type):
+        """
+        Get all the params from the flowgraph that have the given type.
+        
+        Args:
+            type: the specified type
+        
+        Returns:
+            a list of params
+        """
+        return sum([filter(lambda p: p.get_type() == type, block.get_params()) for block in self.get_parent().get_parent().get_enabled_blocks()], [])
diff --git a/grc/python/Platform.py b/grc/python/Platform.py
index e036361ff0..f6adaf47a5 100644
--- a/grc/python/Platform.py
+++ b/grc/python/Platform.py
@@ -28,43 +28,43 @@ from Port import Port as _Port
 from Param import Param as _Param
 from Generator import Generator
 from Constants import \
-	HIER_BLOCKS_LIB_DIR, BLOCK_DTD, \
-	DEFAULT_FLOW_GRAPH, BLOCKS_DIRS
+    HIER_BLOCKS_LIB_DIR, BLOCK_DTD, \
+    DEFAULT_FLOW_GRAPH, BLOCKS_DIRS
 import Constants
 
 COLORS = [(name, color) for name, key, sizeof, color in Constants.CORE_TYPES]
 
 class Platform(_Platform, _GUIPlatform):
 
-	def __init__(self):
-		"""
-		Make a platform for gnuradio.
-		"""
-		#ensure hier dir
-		if not os.path.exists(HIER_BLOCKS_LIB_DIR): os.mkdir(HIER_BLOCKS_LIB_DIR)
-		#convert block paths to absolute paths
-		block_paths = set(map(os.path.abspath, BLOCKS_DIRS))
-		#init
-		_Platform.__init__(
-			self,
-			name='GNU Radio Companion',
-			version=gr.version(),
-			key='grc',
-			license=__doc__.strip(),
-			website='http://gnuradio.org/redmine/wiki/gnuradio/GNURadioCompanion',
-			block_paths=block_paths,
-			block_dtd=BLOCK_DTD,
-			default_flow_graph=DEFAULT_FLOW_GRAPH,
-			generator=Generator,
-			colors=COLORS,
-		)
-		_GUIPlatform.__init__(self)
+    def __init__(self):
+        """
+        Make a platform for gnuradio.
+        """
+        #ensure hier dir
+        if not os.path.exists(HIER_BLOCKS_LIB_DIR): os.mkdir(HIER_BLOCKS_LIB_DIR)
+        #convert block paths to absolute paths
+        block_paths = set(map(os.path.abspath, BLOCKS_DIRS))
+        #init
+        _Platform.__init__(
+            self,
+            name='GNU Radio Companion',
+            version=gr.version(),
+            key='grc',
+            license=__doc__.strip(),
+            website='http://gnuradio.org/redmine/wiki/gnuradio/GNURadioCompanion',
+            block_paths=block_paths,
+            block_dtd=BLOCK_DTD,
+            default_flow_graph=DEFAULT_FLOW_GRAPH,
+            generator=Generator,
+            colors=COLORS,
+        )
+        _GUIPlatform.__init__(self)
 
-	##############################################
-	# Constructors
-	##############################################
-	FlowGraph = _FlowGraph
-	Connection = _Connection
-	Block = _Block
-	Port = _Port
-	Param = _Param
+    ##############################################
+    # Constructors
+    ##############################################
+    FlowGraph = _FlowGraph
+    Connection = _Connection
+    Block = _Block
+    Port = _Port
+    Param = _Param
diff --git a/grc/python/Port.py b/grc/python/Port.py
index 8ebf5c7b05..247dbed3e6 100644
--- a/grc/python/Port.py
+++ b/grc/python/Port.py
@@ -22,209 +22,203 @@ from .. gui.Port import Port as _GUIPort
 import Constants
 
 def _get_source_from_virtual_sink_port(vsp):
-	"""
-	Resolve the source port that is connected to the given virtual sink port.
-	Use the get source from virtual source to recursively resolve subsequent ports.
-	"""
-	try: return _get_source_from_virtual_source_port(
-		vsp.get_enabled_connections()[0].get_source())
-	except: raise Exception, 'Could not resolve source for virtual sink port %s'%vsp
+    """
+    Resolve the source port that is connected to the given virtual sink port.
+    Use the get source from virtual source to recursively resolve subsequent ports.
+    """
+    try: return _get_source_from_virtual_source_port(
+        vsp.get_enabled_connections()[0].get_source())
+    except: raise Exception, 'Could not resolve source for virtual sink port %s'%vsp
 
 def _get_source_from_virtual_source_port(vsp, traversed=[]):
-	"""
-	Recursively resolve source ports over the virtual connections.
-	Keep track of traversed sources to avoid recursive loops.
-	"""
-	if not vsp.get_parent().is_virtual_source(): return vsp
-	if vsp in traversed: raise Exception, 'Loop found when resolving virtual source %s'%vsp
-	try: return _get_source_from_virtual_source_port(
-		_get_source_from_virtual_sink_port(
-			filter(#get all virtual sinks with a matching stream id
-				lambda vs: vs.get_param('stream_id').get_value() == vsp.get_parent().get_param('stream_id').get_value(),
-				filter(#get all enabled blocks that are also virtual sinks
-					lambda b: b.is_virtual_sink(),
-					vsp.get_parent().get_parent().get_enabled_blocks(),
-				),
-			)[0].get_sinks()[0]
-		), traversed + [vsp],
-	)
-	except: raise Exception, 'Could not resolve source for virtual source port %s'%vsp
+    """
+    Recursively resolve source ports over the virtual connections.
+    Keep track of traversed sources to avoid recursive loops.
+    """
+    if not vsp.get_parent().is_virtual_source(): return vsp
+    if vsp in traversed: raise Exception, 'Loop found when resolving virtual source %s'%vsp
+    try: return _get_source_from_virtual_source_port(
+        _get_source_from_virtual_sink_port(
+            filter(#get all virtual sinks with a matching stream id
+                lambda vs: vs.get_param('stream_id').get_value() == vsp.get_parent().get_param('stream_id').get_value(),
+                filter(#get all enabled blocks that are also virtual sinks
+                    lambda b: b.is_virtual_sink(),
+                    vsp.get_parent().get_parent().get_enabled_blocks(),
+                ),
+            )[0].get_sinks()[0]
+        ), traversed + [vsp],
+    )
+    except: raise Exception, 'Could not resolve source for virtual source port %s'%vsp
 
 def _get_sink_from_virtual_source_port(vsp):
-	"""
-	Resolve the sink port that is connected to the given virtual source port.
-	Use the get sink from virtual sink to recursively resolve subsequent ports.
-	"""
-	try: return _get_sink_from_virtual_sink_port(
-		vsp.get_enabled_connections()[0].get_sink())	# Could have many connections, but use first
-	except: raise Exception, 'Could not resolve source for virtual source port %s'%vsp
+    """
+    Resolve the sink port that is connected to the given virtual source port.
+    Use the get sink from virtual sink to recursively resolve subsequent ports.
+    """
+    try: return _get_sink_from_virtual_sink_port(
+        vsp.get_enabled_connections()[0].get_sink())    # Could have many connections, but use first
+    except: raise Exception, 'Could not resolve source for virtual source port %s'%vsp
 
 def _get_sink_from_virtual_sink_port(vsp, traversed=[]):
-	"""
-	Recursively resolve sink ports over the virtual connections.
-	Keep track of traversed sinks to avoid recursive loops.
-	"""
-	if not vsp.get_parent().is_virtual_sink(): return vsp
-	if vsp in traversed: raise Exception, 'Loop found when resolving virtual sink %s'%vsp
-	try: return _get_sink_from_virtual_sink_port(
-		_get_sink_from_virtual_source_port(
-			filter(#get all virtual source with a matching stream id
-				lambda vs: vs.get_param('stream_id').get_value() == vsp.get_parent().get_param('stream_id').get_value(),
-				filter(#get all enabled blocks that are also virtual sinks
-					lambda b: b.is_virtual_source(),
-					vsp.get_parent().get_parent().get_enabled_blocks(),
-				),
-			)[0].get_sources()[0]
-		), traversed + [vsp],
-	)
-	except: raise Exception, 'Could not resolve source for virtual sink port %s'%vsp
+    """
+    Recursively resolve sink ports over the virtual connections.
+    Keep track of traversed sinks to avoid recursive loops.
+    """
+    if not vsp.get_parent().is_virtual_sink(): return vsp
+    if vsp in traversed: raise Exception, 'Loop found when resolving virtual sink %s'%vsp
+    try: return _get_sink_from_virtual_sink_port(
+        _get_sink_from_virtual_source_port(
+            filter(#get all virtual source with a matching stream id
+                lambda vs: vs.get_param('stream_id').get_value() == vsp.get_parent().get_param('stream_id').get_value(),
+                filter(#get all enabled blocks that are also virtual sinks
+                    lambda b: b.is_virtual_source(),
+                    vsp.get_parent().get_parent().get_enabled_blocks(),
+                ),
+            )[0].get_sources()[0]
+        ), traversed + [vsp],
+    )
+    except: raise Exception, 'Could not resolve source for virtual sink port %s'%vsp
 
 class Port(_Port, _GUIPort):
 
-	def __init__(self, block, n, dir):
-		"""
-		Make a new port from nested data.
-		
-		Args:
-		    block: the parent element
-		    n: the nested odict
-		    dir: the direction
-		"""
-		self._n = n
-		if n['type'] == 'msg': n['key'] = 'msg'
-                if n['type'] == 'message': n['key'] = n['name']
-		if dir == 'source' and not n.find('key'):
-			n['key'] = str(block._source_count)
-			block._source_count += 1
-		if dir == 'sink' and not n.find('key'):
-			n['key'] = str(block._sink_count)
-			block._sink_count += 1
-		#build the port
-		_Port.__init__(
-			self,
-			block=block,
-			n=n,
-			dir=dir,
-		)
-		_GUIPort.__init__(self)
-		self._nports = n.find('nports') or ''
-		self._vlen = n.find('vlen') or ''
-		self._optional = bool(n.find('optional'))
-		
-	
-	def get_types(self): return Constants.TYPE_TO_SIZEOF.keys()
-
-	def is_type_empty(self): return not self._n['type']
-
-	def validate(self):
-		_Port.validate(self)
-		if not self.get_enabled_connections() and not self.get_optional():
-			self.add_error_message('Port is not connected.')
-		if not self.is_source() and (not self.get_type() == "message") and len(self.get_enabled_connections()) > 1:
-			self.add_error_message('Port has too many connections.')
-		#message port logic
-		if self.get_type() == 'msg':
-			if self.get_nports():
-				self.add_error_message('A port of type "msg" cannot have "nports" set.')
-			if self.get_vlen() != 1:
-				self.add_error_message('A port of type "msg" must have a "vlen" of 1.')
-
-	def rewrite(self):
-		"""
-		Handle the port cloning for virtual blocks.
-		"""
-		_Port.rewrite(self)
-		if self.is_type_empty():
-			try: #clone type and vlen
-				source = self.resolve_empty_type()
-				self._type = str(source.get_type())
-				self._vlen = str(source.get_vlen())
-			except: #reset type and vlen
-				self._type = ''
-				self._vlen = ''
-
-	def resolve_virtual_source(self):
-		if self.get_parent().is_virtual_sink(): return _get_source_from_virtual_sink_port(self)
-		if self.get_parent().is_virtual_source(): return _get_source_from_virtual_source_port(self)
-
-	def resolve_empty_type(self):
-		if self.is_sink():
-			try:
-				src = _get_source_from_virtual_sink_port(self)
-				if not src.is_type_empty(): return src
-			except: pass
-			sink = _get_sink_from_virtual_sink_port(self)
-			if not sink.is_type_empty(): return sink
-		if self.is_source():
-			try:
-				src = _get_source_from_virtual_source_port(self)
-				if not src.is_type_empty(): return src
-			except: pass
-			sink = _get_sink_from_virtual_source_port(self)
-			if not sink.is_type_empty(): return sink
-
-	def get_vlen(self):
-		"""
-		Get the vector length.
-		If the evaluation of vlen cannot be cast to an integer, return 1.
-		
-		Returns:
-		    the vector length or 1
-		"""
-		vlen = self.get_parent().resolve_dependencies(self._vlen)
-		try: return int(self.get_parent().get_parent().evaluate(vlen))
-		except: return 1
-
-	
-	
-
-	def get_nports(self):
-		"""
-		Get the number of ports.
-		If already blank, return a blank
-		If the evaluation of nports cannot be cast to an integer, return 1.
-		
-		Returns:
-		    the number of ports or 1
-		"""
-		nports = self.get_parent().resolve_dependencies(self._nports)
-		#return blank if nports is blank
-		if not nports: return ''
-		try:
-			nports = int(self.get_parent().get_parent().evaluate(nports))
-			if 0 < nports: return nports
-		except: return 1
-
-	
-
-	def get_optional(self): return bool(self._optional)
-
-	def get_color(self):
-		"""
-		Get the color that represents this port's type.
-		Codes differ for ports where the vec length is 1 or greater than 1.
-		
-		Returns:
-		    a hex color code.
-		"""
-		try:
-			color = Constants.TYPE_TO_COLOR[self.get_type()]
-			vlen = self.get_vlen()
-			if vlen == 1: return color
-			color_val = int(color[1:], 16)
-			r = (color_val >> 16) & 0xff
-			g = (color_val >> 8) & 0xff
-			b = (color_val >> 0) & 0xff
-			dark = (0, 0, 30, 50, 70)[min(4, vlen)]
-			r = max(r-dark, 0)
-			g = max(g-dark, 0)
-			b = max(b-dark, 0)
-			return '#%.2x%.2x%.2x'%(r, g, b)
-		except: return _Port.get_color(self)
-
-	def copy(self, new_key=None):
-		n = self._n.copy()
-		#remove nports from the key so the copy cannot be a duplicator
-		if n.has_key('nports'): n.pop('nports')
-		if new_key: n['key'] = new_key
-		return self.__class__(self.get_parent(), n, self._dir)
+    def __init__(self, block, n, dir):
+        """
+        Make a new port from nested data.
+        
+        Args:
+            block: the parent element
+            n: the nested odict
+            dir: the direction
+        """
+        self._n = n
+        if n['type'] == 'msg': n['key'] = 'msg'
+        if n['type'] == 'message': n['key'] = n['name']
+        if dir == 'source' and not n.find('key'):
+            n['key'] = str(block._source_count)
+            block._source_count += 1
+        if dir == 'sink' and not n.find('key'):
+            n['key'] = str(block._sink_count)
+            block._sink_count += 1
+        #build the port
+        _Port.__init__(
+            self,
+            block=block,
+            n=n,
+            dir=dir,
+        )
+        _GUIPort.__init__(self)
+        self._nports = n.find('nports') or ''
+        self._vlen = n.find('vlen') or ''
+        self._optional = bool(n.find('optional'))
+
+    def get_types(self): return Constants.TYPE_TO_SIZEOF.keys()
+
+    def is_type_empty(self): return not self._n['type']
+
+    def validate(self):
+        _Port.validate(self)
+        if not self.get_enabled_connections() and not self.get_optional():
+            self.add_error_message('Port is not connected.')
+        if not self.is_source() and (not self.get_type() == "message") and len(self.get_enabled_connections()) > 1:
+            self.add_error_message('Port has too many connections.')
+        #message port logic
+        if self.get_type() == 'msg':
+            if self.get_nports():
+                self.add_error_message('A port of type "msg" cannot have "nports" set.')
+            if self.get_vlen() != 1:
+                self.add_error_message('A port of type "msg" must have a "vlen" of 1.')
+
+    def rewrite(self):
+        """
+        Handle the port cloning for virtual blocks.
+        """
+        _Port.rewrite(self)
+        if self.is_type_empty():
+            try: #clone type and vlen
+                source = self.resolve_empty_type()
+                self._type = str(source.get_type())
+                self._vlen = str(source.get_vlen())
+            except: #reset type and vlen
+                self._type = ''
+                self._vlen = ''
+
+    def resolve_virtual_source(self):
+        if self.get_parent().is_virtual_sink(): return _get_source_from_virtual_sink_port(self)
+        if self.get_parent().is_virtual_source(): return _get_source_from_virtual_source_port(self)
+
+    def resolve_empty_type(self):
+        if self.is_sink():
+            try:
+                src = _get_source_from_virtual_sink_port(self)
+                if not src.is_type_empty(): return src
+            except: pass
+            sink = _get_sink_from_virtual_sink_port(self)
+            if not sink.is_type_empty(): return sink
+        if self.is_source():
+            try:
+                src = _get_source_from_virtual_source_port(self)
+                if not src.is_type_empty(): return src
+            except: pass
+            sink = _get_sink_from_virtual_source_port(self)
+            if not sink.is_type_empty(): return sink
+
+    def get_vlen(self):
+        """
+        Get the vector length.
+        If the evaluation of vlen cannot be cast to an integer, return 1.
+        
+        Returns:
+            the vector length or 1
+        """
+        vlen = self.get_parent().resolve_dependencies(self._vlen)
+        try: return int(self.get_parent().get_parent().evaluate(vlen))
+        except: return 1
+
+    def get_nports(self):
+        """
+        Get the number of ports.
+        If already blank, return a blank
+        If the evaluation of nports cannot be cast to an integer, return 1.
+        
+        Returns:
+            the number of ports or 1
+        """
+        nports = self.get_parent().resolve_dependencies(self._nports)
+        #return blank if nports is blank
+        if not nports: return ''
+        try:
+            nports = int(self.get_parent().get_parent().evaluate(nports))
+            if 0 < nports: return nports
+        except: return 1
+
+    def get_optional(self): return bool(self._optional)
+
+    def get_color(self):
+        """
+        Get the color that represents this port's type.
+        Codes differ for ports where the vec length is 1 or greater than 1.
+        
+        Returns:
+            a hex color code.
+        """
+        try:
+            color = Constants.TYPE_TO_COLOR[self.get_type()]
+            vlen = self.get_vlen()
+            if vlen == 1: return color
+            color_val = int(color[1:], 16)
+            r = (color_val >> 16) & 0xff
+            g = (color_val >> 8) & 0xff
+            b = (color_val >> 0) & 0xff
+            dark = (0, 0, 30, 50, 70)[min(4, vlen)]
+            r = max(r-dark, 0)
+            g = max(g-dark, 0)
+            b = max(b-dark, 0)
+            return '#%.2x%.2x%.2x'%(r, g, b)
+        except: return _Port.get_color(self)
+
+    def copy(self, new_key=None):
+        n = self._n.copy()
+        #remove nports from the key so the copy cannot be a duplicator
+        if n.has_key('nports'): n.pop('nports')
+        if new_key: n['key'] = new_key
+        return self.__class__(self.get_parent(), n, self._dir)
diff --git a/grc/python/block.dtd b/grc/python/block.dtd
index 99d38a0d46..21ffbe09af 100644
--- a/grc/python/block.dtd
+++ b/grc/python/block.dtd
@@ -17,25 +17,25 @@ along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 -->
 <!--
-	gnuradio_python.blocks.dtd
-	Josh Blum
-	The document type definition for blocks.
+    gnuradio_python.blocks.dtd
+    Josh Blum
+    The document type definition for blocks.
  -->
 <!--
-	Top level element.
-	A block contains a name, ...parameters list, and list of IO ports.
+    Top level element.
+    A block contains a name, ...parameters list, and list of IO ports.
  -->
 <!ELEMENT block (name, key, category?, throttle?, import*, var_make?, make, callback*, param*, bus_sink?, bus_source?, check*, sink*, source*, bus_structure_sink?, bus_structure_source?, doc?,  grc_source?)>
 <!--
-	Sub level elements.
+    Sub level elements.
  -->
 <!ELEMENT param (name, key, value?, type, hide?, option*)>
 <!ELEMENT option (name, key, opt*)>
 <!ELEMENT sink (name, type, vlen?, nports?, optional?)>
 <!ELEMENT source (name, type, vlen?, nports?, optional?)>
 <!--
-	Bottom level elements.
-	Character data only.
+    Bottom level elements.
+    Character data only.
  -->
 <!ELEMENT category (#PCDATA)>
 <!ELEMENT import (#PCDATA)>
diff --git a/grc/python/convert_hier.py b/grc/python/convert_hier.py
index de76827541..dc86daa0ef 100644
--- a/grc/python/convert_hier.py
+++ b/grc/python/convert_hier.py
@@ -22,89 +22,89 @@ from .. base import ParseXML
 from .. base import odict
 
 def convert_hier(flow_graph, python_file):
-	#extract info from the flow graph
-	input_sigs = flow_graph.get_io_signaturev('in')
-	output_sigs = flow_graph.get_io_signaturev('out')
-	input_msgp = flow_graph.get_msg_pad_sources();
-	output_msgp = flow_graph.get_msg_pad_sinks();
-	parameters = flow_graph.get_parameters()
-	bussink = flow_graph.get_bussink()
-	bussrc = flow_graph.get_bussrc()
-	bus_struct_sink = flow_graph.get_bus_structure_sink()
-	bus_struct_src = flow_graph.get_bus_structure_src()
-	block_key = flow_graph.get_option('id')
-	block_name = flow_graph.get_option('title') or flow_graph.get_option('id').replace('_', ' ').title()
-	block_category = flow_graph.get_option('category')
-	block_desc = flow_graph.get_option('description')
-	block_author = flow_graph.get_option('author')
-	#build the nested data
-	block_n = odict()
-	block_n['name'] = block_name
-	block_n['key'] = block_key
-	block_n['category'] = block_category
-	block_n['import'] = 'execfile("%s")'%python_file
-	#make data
-	if parameters: block_n['make'] = '%s(\n\t%s,\n)'%(
-		block_key,
-		',\n\t'.join(['%s=$%s'%(param.get_id(), param.get_id()) for param in parameters]),
-	)
-	else: block_n['make'] = '%s()'%block_key
-	#callback data
-	block_n['callback'] = ['set_%s($%s)'%(param.get_id(), param.get_id()) for param in parameters]
-	#param data
-	params_n = list()
-	for param in parameters:
-		param_n = odict()
-		param_n['name'] = param.get_param('label').get_value() or param.get_id()
-		param_n['key'] = param.get_id()
-		param_n['value'] = param.get_param('value').get_value()
-		param_n['type'] = 'raw'
-		params_n.append(param_n)
-	block_n['param'] = params_n
-	#sink data stream ports
-	if bussink:
-		block_n['bus_sink'] = '1';
-	if bussrc:
-		block_n['bus_source'] = '1';
-	block_n['sink'] = list()
-	for input_sig in input_sigs:
-		sink_n = odict()
-		sink_n['name'] = input_sig['label']
-		sink_n['type'] = input_sig['type']
-		sink_n['vlen'] = input_sig['vlen']
-		if input_sig['optional']: sink_n['optional'] = '1'
-		block_n['sink'].append(sink_n)
-	#sink data msg ports
-	for input_sig in input_msgp:
-		sink_n = odict()
-		sink_n['name'] = input_sig.get_param("label").get_value();
-		sink_n['type'] = "message"
-		sink_n['optional'] = input_sig.get_param("optional").get_value();
-		block_n['sink'].append(sink_n)
-	#source data stream ports
-	block_n['source'] = list()
-	if bus_struct_sink:
-		block_n['bus_structure_sink'] = bus_struct_sink[0].get_param('struct').get_value();
-	if bus_struct_src:
-		block_n['bus_structure_source'] = bus_struct_src[0].get_param('struct').get_value();
-	for output_sig in output_sigs:
-		source_n = odict()
-		source_n['name'] = output_sig['label']
-		source_n['type'] = output_sig['type']
-		source_n['vlen'] = output_sig['vlen']
-		if output_sig['optional']: source_n['optional'] = '1'
-		block_n['source'].append(source_n)
-	#source data msg ports
-	for output_sig in output_msgp:
-		source_n = odict()
-		source_n['name'] = output_sig.get_param("label").get_value();
-		source_n['type'] = "message"
-		source_n['optional'] = output_sig.get_param("optional").get_value();
-		block_n['source'].append(source_n)
-	#doc data
-	block_n['doc'] = "%s\n%s\n%s"%(block_author, block_desc, python_file)
-	block_n['grc_source'] = "%s"%(flow_graph.grc_file_path)
-	#write the block_n to file
-	xml_file = python_file + '.xml'
-	ParseXML.to_file({'block': block_n}, xml_file)
-	ParseXML.validate_dtd(xml_file, BLOCK_DTD)
+    #extract info from the flow graph
+    input_sigs = flow_graph.get_io_signaturev('in')
+    output_sigs = flow_graph.get_io_signaturev('out')
+    input_msgp = flow_graph.get_msg_pad_sources();
+    output_msgp = flow_graph.get_msg_pad_sinks();
+    parameters = flow_graph.get_parameters()
+    bussink = flow_graph.get_bussink()
+    bussrc = flow_graph.get_bussrc()
+    bus_struct_sink = flow_graph.get_bus_structure_sink()
+    bus_struct_src = flow_graph.get_bus_structure_src()
+    block_key = flow_graph.get_option('id')
+    block_name = flow_graph.get_option('title') or flow_graph.get_option('id').replace('_', ' ').title()
+    block_category = flow_graph.get_option('category')
+    block_desc = flow_graph.get_option('description')
+    block_author = flow_graph.get_option('author')
+    #build the nested data
+    block_n = odict()
+    block_n['name'] = block_name
+    block_n['key'] = block_key
+    block_n['category'] = block_category
+    block_n['import'] = 'execfile("%s")'%python_file
+    #make data
+    if parameters: block_n['make'] = '%s(\n    %s,\n)'%(
+        block_key,
+        ',\n    '.join(['%s=$%s'%(param.get_id(), param.get_id()) for param in parameters]),
+    )
+    else: block_n['make'] = '%s()'%block_key
+    #callback data
+    block_n['callback'] = ['set_%s($%s)'%(param.get_id(), param.get_id()) for param in parameters]
+    #param data
+    params_n = list()
+    for param in parameters:
+        param_n = odict()
+        param_n['name'] = param.get_param('label').get_value() or param.get_id()
+        param_n['key'] = param.get_id()
+        param_n['value'] = param.get_param('value').get_value()
+        param_n['type'] = 'raw'
+        params_n.append(param_n)
+    block_n['param'] = params_n
+    #sink data stream ports
+    if bussink:
+        block_n['bus_sink'] = '1';
+    if bussrc:
+        block_n['bus_source'] = '1';
+    block_n['sink'] = list()
+    for input_sig in input_sigs:
+        sink_n = odict()
+        sink_n['name'] = input_sig['label']
+        sink_n['type'] = input_sig['type']
+        sink_n['vlen'] = input_sig['vlen']
+        if input_sig['optional']: sink_n['optional'] = '1'
+        block_n['sink'].append(sink_n)
+    #sink data msg ports
+    for input_sig in input_msgp:
+        sink_n = odict()
+        sink_n['name'] = input_sig.get_param("label").get_value();
+        sink_n['type'] = "message"
+        sink_n['optional'] = input_sig.get_param("optional").get_value();
+        block_n['sink'].append(sink_n)
+    #source data stream ports
+    block_n['source'] = list()
+    if bus_struct_sink:
+        block_n['bus_structure_sink'] = bus_struct_sink[0].get_param('struct').get_value();
+    if bus_struct_src:
+        block_n['bus_structure_source'] = bus_struct_src[0].get_param('struct').get_value();
+    for output_sig in output_sigs:
+        source_n = odict()
+        source_n['name'] = output_sig['label']
+        source_n['type'] = output_sig['type']
+        source_n['vlen'] = output_sig['vlen']
+        if output_sig['optional']: source_n['optional'] = '1'
+        block_n['source'].append(source_n)
+    #source data msg ports
+    for output_sig in output_msgp:
+        source_n = odict()
+        source_n['name'] = output_sig.get_param("label").get_value();
+        source_n['type'] = "message"
+        source_n['optional'] = output_sig.get_param("optional").get_value();
+        block_n['source'].append(source_n)
+    #doc data
+    block_n['doc'] = "%s\n%s\n%s"%(block_author, block_desc, python_file)
+    block_n['grc_source'] = "%s"%(flow_graph.grc_file_path)
+    #write the block_n to file
+    xml_file = python_file + '.xml'
+    ParseXML.to_file({'block': block_n}, xml_file)
+    ParseXML.validate_dtd(xml_file, BLOCK_DTD)
diff --git a/grc/python/default_flow_graph.grc b/grc/python/default_flow_graph.grc
index dea26f3a5e..53d39e885a 100644
--- a/grc/python/default_flow_graph.grc
+++ b/grc/python/default_flow_graph.grc
@@ -2,42 +2,42 @@
 <!--
 ###################################################
 ##Default Flow Graph:
-##	include an options block and a variable for sample rate
+##  include an options block and a variable for sample rate
 ###################################################
  -->
 <flow_graph>
-	<block>
-		<key>options</key>
-		<param>
-			<key>id</key>
-			<value>top_block</value>
-		</param>
-		<param>
-			<key>_coordinate</key>
-			<value>(10, 10)</value>
-		</param>
-		<param>
-			<key>_rotation</key>
-			<value>0</value>
-		</param>
-	</block>
-	<block>
-		<key>variable</key>
-		<param>
-			<key>id</key>
-			<value>samp_rate</value>
-		</param>
-		<param>
-			<key>value</key>
-			<value>32000</value>
-		</param>
-		<param>
-			<key>_coordinate</key>
-			<value>(10, 170)</value>
-		</param>
-		<param>
-			<key>_rotation</key>
-			<value>0</value>
-		</param>
-	</block>
+    <block>
+        <key>options</key>
+        <param>
+            <key>id</key>
+            <value>top_block</value>
+        </param>
+        <param>
+            <key>_coordinate</key>
+            <value>(10, 10)</value>
+        </param>
+        <param>
+            <key>_rotation</key>
+            <value>0</value>
+        </param>
+    </block>
+    <block>
+        <key>variable</key>
+        <param>
+            <key>id</key>
+            <value>samp_rate</value>
+        </param>
+        <param>
+            <key>value</key>
+            <value>32000</value>
+        </param>
+        <param>
+            <key>_coordinate</key>
+            <value>(10, 170)</value>
+        </param>
+        <param>
+            <key>_rotation</key>
+            <value>0</value>
+        </param>
+    </block>
 </flow_graph>
diff --git a/grc/python/expr_utils.py b/grc/python/expr_utils.py
index 67580f6ffc..85f420f04c 100644
--- a/grc/python/expr_utils.py
+++ b/grc/python/expr_utils.py
@@ -21,157 +21,157 @@ import string
 VAR_CHARS = string.letters + string.digits + '_'
 
 class graph(object):
-	"""
-	Simple graph structure held in a dictionary.
-	"""
+    """
+    Simple graph structure held in a dictionary.
+    """
 
-	def __init__(self): self._graph = dict()
+    def __init__(self): self._graph = dict()
 
-	def __str__(self): return str(self._graph)
+    def __str__(self): return str(self._graph)
 
-	def add_node(self, node_key):
-		if self._graph.has_key(node_key): return
-		self._graph[node_key] = set()
+    def add_node(self, node_key):
+        if self._graph.has_key(node_key): return
+        self._graph[node_key] = set()
 
-	def remove_node(self, node_key):
-		if not self._graph.has_key(node_key): return
-		for edges in self._graph.values():
-			if node_key in edges: edges.remove(node_key)
-		self._graph.pop(node_key)
+    def remove_node(self, node_key):
+        if not self._graph.has_key(node_key): return
+        for edges in self._graph.values():
+            if node_key in edges: edges.remove(node_key)
+        self._graph.pop(node_key)
 
-	def add_edge(self, src_node_key, dest_node_key):
-		self._graph[src_node_key].add(dest_node_key)
+    def add_edge(self, src_node_key, dest_node_key):
+        self._graph[src_node_key].add(dest_node_key)
 
-	def remove_edge(self, src_node_key, dest_node_key):
-		self._graph[src_node_key].remove(dest_node_key)
+    def remove_edge(self, src_node_key, dest_node_key):
+        self._graph[src_node_key].remove(dest_node_key)
 
-	def get_nodes(self): return self._graph.keys()
+    def get_nodes(self): return self._graph.keys()
 
-	def get_edges(self, node_key): return self._graph[node_key]
+    def get_edges(self, node_key): return self._graph[node_key]
 
 def expr_split(expr):
-	"""
-	Split up an expression by non alphanumeric characters, including underscore.
-	Leave strings in-tact.
-	#TODO ignore escaped quotes, use raw strings.
-	
-	Args:
-	    expr: an expression string
-	
-	Returns:
-	    a list of string tokens that form expr
-	"""
-	toks = list()
-	tok = ''
-	quote = ''
-	for char in expr:
-		if quote or char in VAR_CHARS:
-			if char == quote: quote = ''
-			tok += char
-		elif char in ("'", '"'):
-			toks.append(tok)
-			tok = char
-			quote = char
-		else:
-			toks.append(tok)
-			toks.append(char)
-			tok = ''
-	toks.append(tok)
-	return filter(lambda t: t, toks)
+    """
+    Split up an expression by non alphanumeric characters, including underscore.
+    Leave strings in-tact.
+    #TODO ignore escaped quotes, use raw strings.
+    
+    Args:
+        expr: an expression string
+    
+    Returns:
+        a list of string tokens that form expr
+    """
+    toks = list()
+    tok = ''
+    quote = ''
+    for char in expr:
+        if quote or char in VAR_CHARS:
+            if char == quote: quote = ''
+            tok += char
+        elif char in ("'", '"'):
+            toks.append(tok)
+            tok = char
+            quote = char
+        else:
+            toks.append(tok)
+            toks.append(char)
+            tok = ''
+    toks.append(tok)
+    return filter(lambda t: t, toks)
 
 def expr_replace(expr, replace_dict):
-	"""
-	Search for vars in the expression and add the prepend.
-	
-	Args:
-	    expr: an expression string
-	    replace_dict: a dict of find:replace
-	
-	Returns:
-	    a new expression with the prepend
-	"""
-	expr_splits = expr_split(expr)
-	for i, es in enumerate(expr_splits):
-		if es in replace_dict.keys():
-			expr_splits[i] = replace_dict[es]
-	return ''.join(expr_splits)
+    """
+    Search for vars in the expression and add the prepend.
+    
+    Args:
+        expr: an expression string
+        replace_dict: a dict of find:replace
+    
+    Returns:
+        a new expression with the prepend
+    """
+    expr_splits = expr_split(expr)
+    for i, es in enumerate(expr_splits):
+        if es in replace_dict.keys():
+            expr_splits[i] = replace_dict[es]
+    return ''.join(expr_splits)
 
 def get_variable_dependencies(expr, vars):
-	"""
-	Return a set of variables used in this expression.
-	
-	Args:
-	    expr: an expression string
-	    vars: a list of variable names
-	
-	Returns:
-	    a subset of vars used in the expression
-	"""
-	expr_toks = expr_split(expr)
-	return set(filter(lambda v: v in expr_toks, vars))
+    """
+    Return a set of variables used in this expression.
+    
+    Args:
+        expr: an expression string
+        vars: a list of variable names
+    
+    Returns:
+        a subset of vars used in the expression
+    """
+    expr_toks = expr_split(expr)
+    return set(filter(lambda v: v in expr_toks, vars))
 
 def get_graph(exprs):
-	"""
-	Get a graph representing the variable dependencies
-	
-	Args:
-	    exprs: a mapping of variable name to expression
-	
-	Returns:
-	    a graph of variable deps
-	"""
-	vars = exprs.keys()
-	#get dependencies for each expression, load into graph
-	var_graph = graph()
-	for var in vars: var_graph.add_node(var)
-	for var, expr in exprs.iteritems():
-		for dep in get_variable_dependencies(expr, vars):
-			if dep != var: var_graph.add_edge(dep, var)
-	return var_graph
+    """
+    Get a graph representing the variable dependencies
+    
+    Args:
+        exprs: a mapping of variable name to expression
+    
+    Returns:
+        a graph of variable deps
+    """
+    vars = exprs.keys()
+    #get dependencies for each expression, load into graph
+    var_graph = graph()
+    for var in vars: var_graph.add_node(var)
+    for var, expr in exprs.iteritems():
+        for dep in get_variable_dependencies(expr, vars):
+            if dep != var: var_graph.add_edge(dep, var)
+    return var_graph
 
 def sort_variables(exprs):
-	"""
-	Get a list of variables in order of dependencies.
-	
-	Args:
-	    exprs: a mapping of variable name to expression
-	
-	Returns:
-	    a list of variable names
-	@throws Exception circular dependencies
-	"""
-	var_graph = get_graph(exprs)
-	sorted_vars = list()
-	#determine dependency order
-	while var_graph.get_nodes():
-		#get a list of nodes with no edges
-		indep_vars = filter(lambda var: not var_graph.get_edges(var), var_graph.get_nodes())
-		if not indep_vars: raise Exception('circular dependency caught in sort_variables')
-		#add the indep vars to the end of the list
-		sorted_vars.extend(sorted(indep_vars))
-		#remove each edge-less node from the graph
-		for var in indep_vars: var_graph.remove_node(var)
-	return reversed(sorted_vars)
+    """
+    Get a list of variables in order of dependencies.
+    
+    Args:
+        exprs: a mapping of variable name to expression
+    
+    Returns:
+        a list of variable names
+    @throws Exception circular dependencies
+    """
+    var_graph = get_graph(exprs)
+    sorted_vars = list()
+    #determine dependency order
+    while var_graph.get_nodes():
+        #get a list of nodes with no edges
+        indep_vars = filter(lambda var: not var_graph.get_edges(var), var_graph.get_nodes())
+        if not indep_vars: raise Exception('circular dependency caught in sort_variables')
+        #add the indep vars to the end of the list
+        sorted_vars.extend(sorted(indep_vars))
+        #remove each edge-less node from the graph
+        for var in indep_vars: var_graph.remove_node(var)
+    return reversed(sorted_vars)
 
 def sort_objects(objects, get_id, get_expr):
-	"""
-	Sort a list of objects according to their expressions.
-	
-	Args:
-	    objects: the list of objects to sort
-	    get_id: the function to extract an id from the object
-	    get_expr: the function to extract an expression from the object
-	
-	Returns:
-	    a list of sorted objects
-	"""
-	id2obj = dict([(get_id(obj), obj) for obj in objects])
-	#map obj id to expression code
-	id2expr = dict([(get_id(obj), get_expr(obj)) for obj in objects])
-	#sort according to dependency
-	sorted_ids = sort_variables(id2expr)
-	#return list of sorted objects
-	return [id2obj[id] for id in sorted_ids]
+    """
+    Sort a list of objects according to their expressions.
+    
+    Args:
+        objects: the list of objects to sort
+        get_id: the function to extract an id from the object
+        get_expr: the function to extract an expression from the object
+    
+    Returns:
+        a list of sorted objects
+    """
+    id2obj = dict([(get_id(obj), obj) for obj in objects])
+    #map obj id to expression code
+    id2expr = dict([(get_id(obj), get_expr(obj)) for obj in objects])
+    #sort according to dependency
+    sorted_ids = sort_variables(id2expr)
+    #return list of sorted objects
+    return [id2obj[id] for id in sorted_ids]
 
 if __name__ == '__main__':
-	for i in sort_variables({'x':'1', 'y':'x+1', 'a':'x+y', 'b':'y+1', 'c':'a+b+x+y'}): print i
+    for i in sort_variables({'x':'1', 'y':'x+1', 'a':'x+y', 'b':'y+1', 'c':'a+b+x+y'}): print i
diff --git a/grc/python/extract_docs.py b/grc/python/extract_docs.py
index 1d1c738dcc..b3b87e64ca 100644
--- a/grc/python/extract_docs.py
+++ b/grc/python/extract_docs.py
@@ -20,55 +20,55 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 import re
 
 def _extract(key):
-	"""
-	Extract the documentation from the python __doc__ strings.
-	If multiple modules match, combine the docs.
-	
-	Args:
-	    key: the block key
-	
-	Returns:
-	    a string with documentation
-	"""
-	#extract matches
-	try:
-		module_name, constructor_name = key.split('_', 1)
-		module = __import__('gnuradio.'+module_name)
-		module = getattr(module, module_name)
-        except ImportError:
-                try:
-                        module_name, constructor_name = key.split('_', 1)
-                        module = __import__(module_name)
-                except: return ''
-	except:
-                return ''
-	pattern = constructor_name.replace('_', '_*').replace('x', '\w')
-	pattern_matcher = re.compile('^%s\w*$'%pattern)
-	matches = filter(lambda x: pattern_matcher.match(x), dir(module))
-	#combine all matches
-	doc_strs = list()
-	for match in matches:
-		try:
-			title = '   ---   ' + match + '   ---   '
-			doc_strs.append('\n\n'.join([title, getattr(module, match).__doc__]).strip())
-		except: pass
-	return '\n\n'.join(doc_strs)
+    """
+    Extract the documentation from the python __doc__ strings.
+    If multiple modules match, combine the docs.
+    
+    Args:
+        key: the block key
+    
+    Returns:
+        a string with documentation
+    """
+    #extract matches
+    try:
+        module_name, constructor_name = key.split('_', 1)
+        module = __import__('gnuradio.'+module_name)
+        module = getattr(module, module_name)
+    except ImportError:
+            try:
+                    module_name, constructor_name = key.split('_', 1)
+                    module = __import__(module_name)
+            except: return ''
+    except:
+            return ''
+    pattern = constructor_name.replace('_', '_*').replace('x', '\w')
+    pattern_matcher = re.compile('^%s\w*$'%pattern)
+    matches = filter(lambda x: pattern_matcher.match(x), dir(module))
+    #combine all matches
+    doc_strs = list()
+    for match in matches:
+        try:
+            title = '   ---   ' + match + '   ---   '
+            doc_strs.append('\n\n'.join([title, getattr(module, match).__doc__]).strip())
+        except: pass
+    return '\n\n'.join(doc_strs)
 
 _docs_cache = dict()
 def extract(key):
-	"""
-	Call the private extract and cache the result.
-	
-	Args:
-	    key: the block key
-	
-	Returns:
-	    a string with documentation
-	"""
-	if not _docs_cache.has_key(key):
-		_docs_cache[key] = _extract(key)
-	return _docs_cache[key]
+    """
+    Call the private extract and cache the result.
+    
+    Args:
+        key: the block key
+    
+    Returns:
+        a string with documentation
+    """
+    if not _docs_cache.has_key(key):
+        _docs_cache[key] = _extract(key)
+    return _docs_cache[key]
 
 if __name__ == '__main__':
-	import sys
-	print extract(sys.argv[1])
+    import sys
+    print extract(sys.argv[1])
diff --git a/grc/python/flow_graph.tmpl b/grc/python/flow_graph.tmpl
index d104d4913d..550ecd78b5 100644
--- a/grc/python/flow_graph.tmpl
+++ b/grc/python/flow_graph.tmpl
@@ -13,7 +13,7 @@
 ##@param var_id2cbs variable id map to callback strings
 ########################################################
 #def indent($code)
-#set $code = '\n\t\t'.join(str($code).splitlines())
+#set $code = '\n        '.join(str($code).splitlines())
 $code#slurp
 #end def
 #import time
@@ -39,304 +39,304 @@ $imp
 
 ########################################################
 ##Create Class
-##	Write the class declaration for a top or hier block.
-##	The parameter names are the arguments to __init__.
-##	Determine the absolute icon path (wx gui only).
-##	Setup the IO signature (hier block only).
+##  Write the class declaration for a top or hier block.
+##  The parameter names are the arguments to __init__.
+##  Determine the absolute icon path (wx gui only).
+##  Setup the IO signature (hier block only).
 ########################################################
 #set $class_name = $flow_graph.get_option('id')
 #set $param_str = ', '.join(['self'] + ['%s=%s'%(param.get_id(), param.get_make()) for param in $parameters])
 #if $generate_options == 'wx_gui'
-	#import gtk
-	#set $icon = gtk.IconTheme().lookup_icon('gnuradio-grc', 32, 0)
+    #import gtk
+    #set $icon = gtk.IconTheme().lookup_icon('gnuradio-grc', 32, 0)
 class $(class_name)(grc_wxgui.top_block_gui):
 
-	def __init__($param_str):
-		grc_wxgui.top_block_gui.__init__(self, title="$title")
-	#if $icon
-		_icon_path = "$icon.get_filename()"
-		self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY))
-	#end if
+    def __init__($param_str):
+        grc_wxgui.top_block_gui.__init__(self, title="$title")
+    #if $icon
+        _icon_path = "$icon.get_filename()"
+        self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY))
+    #end if
 #elif $generate_options == 'qt_gui'
 class $(class_name)(gr.top_block, Qt.QWidget):
 
-	def __init__($param_str):
-		gr.top_block.__init__(self, "$title")
-		Qt.QWidget.__init__(self)
-		self.setWindowTitle("$title")
-		try:
-		     self.setWindowIcon(Qt.QIcon.fromTheme('gnuradio-grc'))
-		except:
-		     pass
-		self.top_scroll_layout = Qt.QVBoxLayout()
-		self.setLayout(self.top_scroll_layout)
-		self.top_scroll = Qt.QScrollArea()
-		self.top_scroll.setFrameStyle(Qt.QFrame.NoFrame)
-		self.top_scroll_layout.addWidget(self.top_scroll)
-		self.top_scroll.setWidgetResizable(True)
-		self.top_widget = Qt.QWidget()
-		self.top_scroll.setWidget(self.top_widget)
-		self.top_layout = Qt.QVBoxLayout(self.top_widget)
-		self.top_grid_layout = Qt.QGridLayout()
-		self.top_layout.addLayout(self.top_grid_layout)
+    def __init__($param_str):
+        gr.top_block.__init__(self, "$title")
+        Qt.QWidget.__init__(self)
+        self.setWindowTitle("$title")
+        try:
+             self.setWindowIcon(Qt.QIcon.fromTheme('gnuradio-grc'))
+        except:
+             pass
+        self.top_scroll_layout = Qt.QVBoxLayout()
+        self.setLayout(self.top_scroll_layout)
+        self.top_scroll = Qt.QScrollArea()
+        self.top_scroll.setFrameStyle(Qt.QFrame.NoFrame)
+        self.top_scroll_layout.addWidget(self.top_scroll)
+        self.top_scroll.setWidgetResizable(True)
+        self.top_widget = Qt.QWidget()
+        self.top_scroll.setWidget(self.top_widget)
+        self.top_layout = Qt.QVBoxLayout(self.top_widget)
+        self.top_grid_layout = Qt.QGridLayout()
+        self.top_layout.addLayout(self.top_grid_layout)
 
-		self.settings = Qt.QSettings("GNU Radio", "$class_name")
-		self.restoreGeometry(self.settings.value("geometry").toByteArray())
+        self.settings = Qt.QSettings("GNU Radio", "$class_name")
+        self.restoreGeometry(self.settings.value("geometry").toByteArray())
 
 #elif $generate_options == 'no_gui'
 class $(class_name)(gr.top_block):
 
-	def __init__($param_str):
-		gr.top_block.__init__(self, "$title")
+    def __init__($param_str):
+        gr.top_block.__init__(self, "$title")
 #elif $generate_options == 'hb'
-	#set $in_sigs = $flow_graph.get_io_signaturev('in')
-	#set $out_sigs = $flow_graph.get_io_signaturev('out')
+    #set $in_sigs = $flow_graph.get_io_signaturev('in')
+    #set $out_sigs = $flow_graph.get_io_signaturev('out')
 class $(class_name)(gr.hier_block2):
 #def make_io_sig($io_sigs)
-	#set $size_strs = ['%s*%s'%(io_sig['size'], io_sig['vlen']) for io_sig in $io_sigs]
-	#if len($io_sigs) == 0
+    #set $size_strs = ['%s*%s'%(io_sig['size'], io_sig['vlen']) for io_sig in $io_sigs]
+    #if len($io_sigs) == 0
 gr.io_signature(0, 0, 0)#slurp
-	#elif len($io_sigs) == 1
+    #elif len($io_sigs) == 1
 gr.io_signature(1, 1, $size_strs[0])#slurp
-	#else
+    #else
 gr.io_signaturev($(len($io_sigs)), $(len($io_sigs)), [$(', '.join($size_strs))])#slurp
-	#end if
+    #end if
 #end def
 
-	def __init__($param_str):
-		gr.hier_block2.__init__(
-			self, "$title",
-			$make_io_sig($in_sigs),
-			$make_io_sig($out_sigs),
-		)
+    def __init__($param_str):
+        gr.hier_block2.__init__(
+            self, "$title",
+            $make_io_sig($in_sigs),
+            $make_io_sig($out_sigs),
+        )
 #end if
 ########################################################
 ##Create Parameters
-##	Set the parameter to a property of self.
+##  Set the parameter to a property of self.
 ########################################################
 #if $parameters
 
-		$DIVIDER
-		# Parameters
-		$DIVIDER
+        $DIVIDER
+        # Parameters
+        $DIVIDER
 #end if
 #for $param in $parameters
-		$indent($param.get_var_make())
+        $indent($param.get_var_make())
 #end for
 ########################################################
 ##Create Variables
 ########################################################
 #if $variables
 
-		$DIVIDER
-		# Variables
-		$DIVIDER
+        $DIVIDER
+        # Variables
+        $DIVIDER
 #end if
 #for $var in $variables
-		$indent($var.get_var_make())
+        $indent($var.get_var_make())
 #end for
 ########################################################
 ##Create Message Queues
 ########################################################
 #if $messages
 
-		$DIVIDER
-		# Message Queues
-		$DIVIDER
+        $DIVIDER
+        # Message Queues
+        $DIVIDER
 #end if
 #for $msg in $messages
-		$(msg.get_source().get_parent().get_id())_msgq_out = $(msg.get_sink().get_parent().get_id())_msgq_in = gr.msg_queue(2)
+        $(msg.get_source().get_parent().get_id())_msgq_out = $(msg.get_sink().get_parent().get_id())_msgq_in = gr.msg_queue(2)
 #end for
 ########################################################
 ##Create Blocks
 ########################################################
 #if $blocks
 
-		$DIVIDER
-		# Blocks
-		$DIVIDER
+        $DIVIDER
+        # Blocks
+        $DIVIDER
 #end if
 #for $blk in filter(lambda b: b.get_make(), $blocks)
-	#if $blk in $variables
-		$indent($blk.get_make())
-	#else
-		self.$blk.get_id() = $indent($blk.get_make())
-	#end if
+    #if $blk in $variables
+        $indent($blk.get_make())
+    #else
+        self.$blk.get_id() = $indent($blk.get_make())
+    #end if
 #end for
 ########################################################
 ##Create Connections
-##	The port name should be the id of the parent block.
-##	However, port names for IO pads should be self.
+##  The port name should be the id of the parent block.
+##  However, port names for IO pads should be self.
 ########################################################
 #def make_port_sig($port)
-	#if $port.get_parent().get_key() == 'pad_source'
+    #if $port.get_parent().get_key() == 'pad_source'
 (self, $flow_graph.get_pad_sources().index($port.get_parent()))#slurp
-	#elif $port.get_parent().get_key() == 'pad_sink'
+    #elif $port.get_parent().get_key() == 'pad_sink'
 (self, $flow_graph.get_pad_sinks().index($port.get_parent()))#slurp
-	#else
+    #else
 (self.$port.get_parent().get_id(), $port.get_key())#slurp
-	#end if
+    #end if
 #end def
 #if $connections
 
-		$DIVIDER
-		# Connections
-		$DIVIDER
+        $DIVIDER
+        # Connections
+        $DIVIDER
 #end if
 #for $con in $connections
-	#set $source = $con.get_source()
-	#set $sink = $con.get_sink()
-	##resolve virtual sources to the actual sources
-	#if $source.get_parent().is_virtual_source()
-		#set $source = $source.resolve_virtual_source()
-	#end if
-	##do not generate connections with virtual sinks
-	#if not $sink.get_parent().is_virtual_sink()
-		self.connect($make_port_sig($source), $make_port_sig($sink))
-	#end if
+    #set $source = $con.get_source()
+    #set $sink = $con.get_sink()
+    ##resolve virtual sources to the actual sources
+    #if $source.get_parent().is_virtual_source()
+        #set $source = $source.resolve_virtual_source()
+    #end if
+    ##do not generate connections with virtual sinks
+    #if not $sink.get_parent().is_virtual_sink()
+        self.connect($make_port_sig($source), $make_port_sig($sink))
+    #end if
 #end for
 
 ########################################################
 ##Create Asynch Message Connections
 ########################################################
 #if $messages2
-		$DIVIDER
-		# Asynch Message Connections
-		$DIVIDER
+        $DIVIDER
+        # Asynch Message Connections
+        $DIVIDER
 #end if
 #for $msg in $messages2
-		#set $sr = $msg.get_source()
-		#set $source = "self.%s"%($sr.get_parent().get_id())
-		#set $source_port = $sr.get_name();
-		#if $sr.get_parent().get_key() == "pad_source"
-			#set $source = "self"
-			#set $source_port = $sr.get_parent().get_param("label").get_value();
-		#end if
-		#set $sk = $msg.get_sink()
-		#set $sink = "self.%s"%($sk.get_parent().get_id())
-		#set $sink_port = $sk.get_name();
-		#if $sk.get_parent().get_key() == "pad_sink"
-			#set $sink = "self"
-			#set $sink_port = $sk.get_parent().get_param("label").get_value();
-		#end if
-		self.msg_connect($source, "$source_port", $sink, "$sink_port")
+        #set $sr = $msg.get_source()
+        #set $source = "self.%s"%($sr.get_parent().get_id())
+        #set $source_port = $sr.get_name();
+        #if $sr.get_parent().get_key() == "pad_source"
+            #set $source = "self"
+            #set $source_port = $sr.get_parent().get_param("label").get_value();
+        #end if
+        #set $sk = $msg.get_sink()
+        #set $sink = "self.%s"%($sk.get_parent().get_id())
+        #set $sink_port = $sk.get_name();
+        #if $sk.get_parent().get_key() == "pad_sink"
+            #set $sink = "self"
+            #set $sink_port = $sk.get_parent().get_param("label").get_value();
+        #end if
+        self.msg_connect($source, "$source_port", $sink, "$sink_port")
 #end for
 
 ########################################################
 # QT sink close method reimplementation
 ########################################################
 #if $generate_options == 'qt_gui'
-	def closeEvent(self, event):
-		self.settings = Qt.QSettings("GNU Radio", "$class_name")
-		self.settings.setValue("geometry", self.saveGeometry())
-		event.accept()
+    def closeEvent(self, event):
+        self.settings = Qt.QSettings("GNU Radio", "$class_name")
+        self.settings.setValue("geometry", self.saveGeometry())
+        event.accept()
 #end if
 
 ########################################################
 ##Create Callbacks
-##	Write a set method for this variable that calls the callbacks
+##  Write a set method for this variable that calls the callbacks
 ########################################################
 #for $var in $parameters + $variables
-	#set $id = $var.get_id()
-	def get_$(id)(self):
-		return self.$id
+    #set $id = $var.get_id()
+    def get_$(id)(self):
+        return self.$id
 
-	def set_$(id)(self, $id):
-		self.$id = $id
-	#for $callback in $var_id2cbs[$id]
-		$indent($callback)
-	#end for
+    def set_$(id)(self, $id):
+        self.$id = $id
+    #for $callback in $var_id2cbs[$id]
+        $indent($callback)
+    #end for
 
 #end for
 ########################################################
 ##Create Main
-##	For top block code, generate a main routine.
-##	Instantiate the top block and run as gui or cli.
+##  For top block code, generate a main routine.
+##  Instantiate the top block and run as gui or cli.
 ########################################################
 #def make_default($type, $param)
-	#if $type == 'eng_float'
+    #if $type == 'eng_float'
 eng_notation.num_to_str($param.get_make())#slurp
-	#else
+    #else
 $param.get_make()#slurp
-	#end if
+    #end if
 #end def
 #def make_short_id($param)
-	#set $short_id = $param.get_param('short_id').get_evaluated()
-	#if $short_id
-		#set $short_id = '-' + $short_id
-	#end if
+    #set $short_id = $param.get_param('short_id').get_evaluated()
+    #if $short_id
+        #set $short_id = '-' + $short_id
+    #end if
 $short_id#slurp
 #end def
 #if $generate_options != 'hb'
 if __name__ == '__main__':
-	parser = OptionParser(option_class=eng_option, usage="%prog: [options]")
-	#set $params_eq_list = list()
-	#for $param in $parameters
-		#set $type = $param.get_param('type').get_value()
-		#if $type
-			#silent $params_eq_list.append('%s=options.%s'%($param.get_id(), $param.get_id()))
-	parser.add_option("$make_short_id($param)", "--$param.get_id().replace('_', '-')", dest="$param.get_id()", type="$type", default=$make_default($type, $param),
-		help="Set $($param.get_param('label').get_evaluated() or $param.get_id()) [default=%default]")
-		#end if
-	#end for
-	(options, args) = parser.parse_args()
-	#if $flow_graph.get_option('realtime_scheduling')
-	if gr.enable_realtime_scheduling() != gr.RT_OK:
-		print "Error: failed to enable realtime scheduling."
-	#end if
-	#if $generate_options == 'wx_gui'
-	tb = $(class_name)($(', '.join($params_eq_list)))
-		#if $flow_graph.get_option('max_nouts')
-	tb.Run($flow_graph.get_option('run'), $flow_graph.get_option('max_nouts'))
-		#else
-	tb.Start($flow_graph.get_option('run'))
+    parser = OptionParser(option_class=eng_option, usage="%prog: [options]")
+    #set $params_eq_list = list()
+    #for $param in $parameters
+        #set $type = $param.get_param('type').get_value()
+        #if $type
+            #silent $params_eq_list.append('%s=options.%s'%($param.get_id(), $param.get_id()))
+    parser.add_option("$make_short_id($param)", "--$param.get_id().replace('_', '-')", dest="$param.get_id()", type="$type", default=$make_default($type, $param),
+        help="Set $($param.get_param('label').get_evaluated() or $param.get_id()) [default=%default]")
+        #end if
+    #end for
+    (options, args) = parser.parse_args()
+    #if $flow_graph.get_option('realtime_scheduling')
+    if gr.enable_realtime_scheduling() != gr.RT_OK:
+        print "Error: failed to enable realtime scheduling."
+    #end if
+    #if $generate_options == 'wx_gui'
+    tb = $(class_name)($(', '.join($params_eq_list)))
+        #if $flow_graph.get_option('max_nouts')
+    tb.Run($flow_graph.get_option('run'), $flow_graph.get_option('max_nouts'))
+        #else
+    tb.Start($flow_graph.get_option('run'))
         #for $m in $monitors
-        (tb.$m.get_id()).start()
+    (tb.$m.get_id()).start()
         #end for
-        tb.Wait()
-		#end if
-	#elif $generate_options == 'qt_gui'
-	qapp = Qt.QApplication(sys.argv)
-	tb = $(class_name)($(', '.join($params_eq_list)))
-	#if $flow_graph.get_option('run')
-		#if $flow_graph.get_option('max_nouts')
-	tb.start($flow_graph.get_option('max_nouts'))
-		#else
-	tb.start()
-		#end if
-	#end if
-	tb.show()
+    tb.Wait()
+        #end if
+    #elif $generate_options == 'qt_gui'
+    qapp = Qt.QApplication(sys.argv)
+    tb = $(class_name)($(', '.join($params_eq_list)))
+    #if $flow_graph.get_option('run')
+        #if $flow_graph.get_option('max_nouts')
+    tb.start($flow_graph.get_option('max_nouts'))
+        #else
+    tb.start()
+        #end if
+    #end if
+    tb.show()
         #for $m in $monitors
-        (tb.$m.get_id()).start()
+    (tb.$m.get_id()).start()
         #end for
-	qapp.exec_()
-	tb.stop()
-	tb = None #to clean up Qt widgets
-	#elif $generate_options == 'no_gui'
-	tb = $(class_name)($(', '.join($params_eq_list)))
-		#set $run_options = $flow_graph.get_option('run_options')
-		#if $run_options == 'prompt'
-			#if $flow_graph.get_option('max_nouts')
-	tb.start($flow_graph.get_option('max_nouts'))
-			#else
-	tb.start()
-			#end if
+    qapp.exec_()
+    tb.stop()
+    tb = None #to clean up Qt widgets
+    #elif $generate_options == 'no_gui'
+    tb = $(class_name)($(', '.join($params_eq_list)))
+        #set $run_options = $flow_graph.get_option('run_options')
+        #if $run_options == 'prompt'
+            #if $flow_graph.get_option('max_nouts')
+    tb.start($flow_graph.get_option('max_nouts'))
+            #else
+    tb.start()
+            #end if
         #for $m in $monitors
-        (tb.$m.get_id()).start()
+    (tb.$m.get_id()).start()
         #end for
-	raw_input('Press Enter to quit: ')
-	tb.stop()
-		#elif $run_options == 'run'
-			#if $flow_graph.get_option('max_nouts')
-	tb.start($flow_graph.get_option('max_nouts'))
-			#else
-	tb.start()
-			#end if
-		#end if
+    raw_input('Press Enter to quit: ')
+    tb.stop()
+        #elif $run_options == 'run'
+            #if $flow_graph.get_option('max_nouts')
+    tb.start($flow_graph.get_option('max_nouts'))
+            #else
+    tb.start()
+            #end if
+        #end if
         #for $m in $monitors
-        (tb.$m.get_id()).start()
+    (tb.$m.get_id()).start()
         #end for
-        tb.wait()
-	#end if
+    tb.wait()
+    #end if
 #end if
 
diff --git a/grc/scripts/gnuradio-companion b/grc/scripts/gnuradio-companion
index dabca3028f..6d45ecc246 100755
--- a/grc/scripts/gnuradio-companion
+++ b/grc/scripts/gnuradio-companion
@@ -24,36 +24,36 @@ import gtk
 
 try: from gnuradio import gr
 except ImportError, e:
-	d = gtk.MessageDialog(type=gtk.MESSAGE_ERROR, buttons=gtk.BUTTONS_CLOSE, message_format="""
+    d = gtk.MessageDialog(type=gtk.MESSAGE_ERROR, buttons=gtk.BUTTONS_CLOSE, message_format="""
 Cannot import gnuradio.
 
 Is the python path environment variable set correctly?
-	All OS: PYTHONPATH
+    All OS: PYTHONPATH
 
 Is the library path environment variable set correctly?
-	Linux: LD_LIBRARY_PATH
-	Windows: PATH
-	MacOSX: DYLD_LIBRARY_PATH
+    Linux: LD_LIBRARY_PATH
+    Windows: PATH
+    MacOSX: DYLD_LIBRARY_PATH
 """)
-	d.set_title(str(e))
-	d.run()
-	exit(-1)
+    d.set_title(str(e))
+    d.run()
+    exit(-1)
 
 from optparse import OptionParser
 import os
 
 if __name__ == "__main__":
-	if ('GR_DONT_LOAD_PREFS' in os.environ.keys() and
-		(not 'GRC_BLOCKS_PATH' in os.environ.keys() or len(os.environ['GRC_BLOCKS_PATH']) == 0)):
-		d = gtk.MessageDialog(
-			type=gtk.MESSAGE_ERROR,
-			buttons=gtk.BUTTONS_CLOSE,
-			message_format="""Can't find block definitions. Use config.conf or GRC_BLOCKS_PATH. """)
-		d.set_title("No block definitions available.")
-		d.run()
-		exit(-1)
-	usage = 'usage: %prog [options] [saved flow graphs]'
-	version = """
+    if ('GR_DONT_LOAD_PREFS' in os.environ.keys() and
+        (not 'GRC_BLOCKS_PATH' in os.environ.keys() or len(os.environ['GRC_BLOCKS_PATH']) == 0)):
+        d = gtk.MessageDialog(
+            type=gtk.MESSAGE_ERROR,
+            buttons=gtk.BUTTONS_CLOSE,
+            message_format="""Can't find block definitions. Use config.conf or GRC_BLOCKS_PATH. """)
+        d.set_title("No block definitions available.")
+        d.run()
+        exit(-1)
+    usage = 'usage: %prog [options] [saved flow graphs]'
+    version = """
 GNU Radio Companion %s
 
 This program is part of GNU Radio
@@ -61,12 +61,12 @@ GRC comes with ABSOLUTELY NO WARRANTY.
 This is free software,
 and you are welcome to redistribute it.
 """%gr.version()
-	parser = OptionParser(usage=usage, version=version)
-	(options, args) = parser.parse_args()
-	from gnuradio.grc.python.Platform import Platform
-	from gnuradio.grc.gui.ActionHandler import ActionHandler
-	#setup icon using icon theme
-	try: gtk.window_set_default_icon(gtk.IconTheme().load_icon('gnuradio-grc', 256, 0))
-	except: pass
-	ActionHandler(args, Platform())
+    parser = OptionParser(usage=usage, version=version)
+    (options, args) = parser.parse_args()
+    from gnuradio.grc.python.Platform import Platform
+    from gnuradio.grc.gui.ActionHandler import ActionHandler
+    #setup icon using icon theme
+    try: gtk.window_set_default_icon(gtk.IconTheme().load_icon('gnuradio-grc', 256, 0))
+    except: pass
+    ActionHandler(args, Platform())
 
-- 
cgit v1.2.3