commit-gnuradio
[Top][All Lists]
Advanced

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

[Commit-gnuradio] r9036 - in grc/trunk: . notes src/grc src/grc/elements


From: jblum
Subject: [Commit-gnuradio] r9036 - in grc/trunk: . notes src/grc src/grc/elements src/grc/gui src/grc/gui/elements src/grc_gnuradio
Date: Mon, 28 Jul 2008 20:06:09 -0600 (MDT)

Author: jblum
Date: 2008-07-28 20:06:09 -0600 (Mon, 28 Jul 2008)
New Revision: 9036

Modified:
   grc/trunk/Makefile
   grc/trunk/notes/todo.txt
   grc/trunk/src/grc/ActionHandler.py
   grc/trunk/src/grc/elements/Block.py
   grc/trunk/src/grc/elements/Element.py
   grc/trunk/src/grc/elements/FlowGraph.py
   grc/trunk/src/grc/gui/Dialogs.py
   grc/trunk/src/grc/gui/elements/Block.py
   grc/trunk/src/grc/gui/elements/Element.py
   grc/trunk/src/grc/gui/elements/FlowGraph.py
   grc/trunk/src/grc/gui/elements/Port.py
   grc/trunk/src/grc_gnuradio/Block.py
Log:
multi selection

Modified: grc/trunk/Makefile
===================================================================
--- grc/trunk/Makefile  2008-07-28 23:34:17 UTC (rev 9035)
+++ grc/trunk/Makefile  2008-07-29 02:06:09 UTC (rev 9036)
@@ -21,13 +21,12 @@
 
 DOCS_URL = http://www.ece.jhu.edu/~jblum/downloads/grc_gnuradio_docs.tar.gz
 DOCS_DEST = /usr/local/share/doc/
-PREFIX = /usr/local
 
 all:
        @echo Options: install, uninstall, docs_install, docs_uninstall
 
 install:
-       python setup.py install --prefix=$(PREFIX)
+       python setup.py install
        rm -rf build
 
 uninstall:

Modified: grc/trunk/notes/todo.txt
===================================================================
--- grc/trunk/notes/todo.txt    2008-07-28 23:34:17 UTC (rev 9035)
+++ grc/trunk/notes/todo.txt    2008-07-29 02:06:09 UTC (rev 9036)
@@ -10,7 +10,6 @@
 -command line option for additional block wrappers
 -hotkeys in action descriptions
 -log slider gui control
--multi block selection
 
 ############ Maybe: ####################
 -icons for certain blocks, + for add
@@ -21,7 +20,7 @@
 -auto generate hier library
 -auto clean hier library
 -add hier blocks to tree without restart?
--block looses highlight on nports grow
+-multi select, enable, disable, repeat, undo = error?
 
 ############ Suggestions: ####################
 -simple usrp

Modified: grc/trunk/src/grc/ActionHandler.py
===================================================================
--- grc/trunk/src/grc/ActionHandler.py  2008-07-28 23:34:17 UTC (rev 9035)
+++ grc/trunk/src/grc/ActionHandler.py  2008-07-29 02:06:09 UTC (rev 9036)
@@ -205,10 +205,12 @@
                
##############################################################################################
                elif state == 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 state == 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)
                
##############################################################################################
@@ -218,11 +220,13 @@
                        self.handle_states(BLOCK_COPY)
                        self.handle_states(ELEMENT_DELETE)
                elif state == BLOCK_COPY:
-                       block = self.get_flow_graph().get_selected_block()
-                       if block: self.clipboard = block.export_data()
-               elif state == BLOCK_PASTE: 
+                       self.clipboard = 
self.get_flow_graph().copy_to_clipboard()
+               elif state == BLOCK_PASTE:
                        if self.clipboard:
-                               block = 
self.get_flow_graph().add_new_block(key=self.clipboard['key'], n=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)
                
##############################################################################################
                #       Move/Rotate/Delete/Create
                
##############################################################################################
@@ -248,18 +252,24 @@
                        self.get_page().set_saved(False)
                elif state == 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 state == 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 state == PORT_CONTROLLER_INC:
                        if 
self.get_flow_graph().port_controller_modify_selected(1):
+                               self.get_flow_graph().update()
+                               self.get_flow_graph().update() #2 times
                                
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
                                self.get_page().set_saved(False)
                elif state == PORT_CONTROLLER_DEC:
                        if 
self.get_flow_graph().port_controller_modify_selected(-1):
+                               self.get_flow_graph().update()
+                               self.get_flow_graph().update() #2 times
                                
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
                                self.get_page().set_saved(False)
                
##############################################################################################
@@ -361,20 +371,24 @@
                #       Global Actions for all States
                
##############################################################################################
                #update general buttons
-               
get_action_from_name(ELEMENT_DELETE).set_sensitive(bool(self.get_flow_graph().get_selected_element()))
+               
get_action_from_name(ELEMENT_DELETE).set_sensitive(bool(self.get_flow_graph().get_selected_elements()))
                
get_action_from_name(BLOCK_PARAM_MODIFY).set_sensitive(bool(self.get_flow_graph().get_selected_block()))
-               
get_action_from_name(BLOCK_ROTATE_RIGHT).set_sensitive(bool(self.get_flow_graph().get_selected_block()))
-               
get_action_from_name(BLOCK_ROTATE_LEFT).set_sensitive(bool(self.get_flow_graph().get_selected_block()))
+               
get_action_from_name(BLOCK_ROTATE_RIGHT).set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
+               
get_action_from_name(BLOCK_ROTATE_LEFT).set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
                #update cut/copy/paste
-               
get_action_from_name(BLOCK_CUT).set_sensitive(bool(self.get_flow_graph().get_selected_block()))
-               
get_action_from_name(BLOCK_COPY).set_sensitive(bool(self.get_flow_graph().get_selected_block()))
+               
get_action_from_name(BLOCK_CUT).set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
+               
get_action_from_name(BLOCK_COPY).set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
                
get_action_from_name(BLOCK_PASTE).set_sensitive(bool(self.clipboard))
                #update enable/disable
                get_action_from_name(BLOCK_ENABLE).set_sensitive(bool(
-                       self.get_flow_graph().get_selected_block() and not 
self.get_flow_graph().get_selected_block().get_enabled()
+                       self.get_flow_graph().get_selected_blocks() or \
+                       self.get_flow_graph().get_selected_block() and \
+                       not 
self.get_flow_graph().get_selected_block().get_enabled()
                ))
                get_action_from_name(BLOCK_DISABLE).set_sensitive(bool(
-                       self.get_flow_graph().get_selected_block() and 
self.get_flow_graph().get_selected_block().get_enabled()
+                       self.get_flow_graph().get_selected_blocks() or \
+                       self.get_flow_graph().get_selected_block() and \
+                       self.get_flow_graph().get_selected_block().get_enabled()
                ))
                #set the exec and stop buttons
                self.update_exec_stop()

Modified: grc/trunk/src/grc/elements/Block.py
===================================================================
--- grc/trunk/src/grc/elements/Block.py 2008-07-28 23:34:17 UTC (rev 9035)
+++ grc/trunk/src/grc/elements/Block.py 2008-07-29 02:06:09 UTC (rev 9036)
@@ -171,6 +171,8 @@
 
        def get_doc(self): return ''
 
+       def get_ports(self): return self.get_sources() + self.get_sinks()
+
        ##############################################
        # Access Params
        ##############################################
@@ -193,7 +195,7 @@
        def get_sources(self): return self._sources.values()
 
        def get_connections(self):
-               return sum([port.get_connections() for port in 
self.get_sources() + self.get_sinks()], [])
+               return sum([port.get_connections() for port in 
self.get_ports()], [])
 
        def resolve_dependencies(self, tmpl):
                """

Modified: grc/trunk/src/grc/elements/Element.py
===================================================================
--- grc/trunk/src/grc/elements/Element.py       2008-07-28 23:34:17 UTC (rev 
9035)
+++ grc/trunk/src/grc/elements/Element.py       2008-07-29 02:06:09 UTC (rev 
9036)
@@ -85,19 +85,13 @@
        ##############################################
        ## 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
+

Modified: grc/trunk/src/grc/elements/FlowGraph.py
===================================================================
--- grc/trunk/src/grc/elements/FlowGraph.py     2008-07-28 23:34:17 UTC (rev 
9035)
+++ grc/trunk/src/grc/elements/FlowGraph.py     2008-07-29 02:06:09 UTC (rev 
9036)
@@ -129,11 +129,11 @@
                self.flag()
                if element not in self.get_elements(): return
                #found a port, set to parent signal block
-               if element.is_source() or element.is_sink():
+               if element.is_port():
                        element = element.get_parent()
                #remove block, remove all involved connections
                if element.is_block():
-                       for port in element.get_sources() + element.get_sinks():
+                       for port in element.get_ports():
                                map(lambda c: self.remove_element(c), 
port.get_connections())
                #remove a connection
                elif element.is_connection(): pass

Modified: grc/trunk/src/grc/gui/Dialogs.py
===================================================================
--- grc/trunk/src/grc/gui/Dialogs.py    2008-07-28 23:34:17 UTC (rev 9035)
+++ grc/trunk/src/grc/gui/Dialogs.py    2008-07-29 02:06:09 UTC (rev 9036)
@@ -24,6 +24,7 @@
 pygtk.require('2.0')
 import gtk
 from grc.Constants import *
+from grc import Preferences
 
 class TextDisplay(gtk.TextView):
        """A non editable gtk text view."""
@@ -48,7 +49,6 @@
 
        def __init__(self):
                """PreferencesDialog constructor."""
-               from grc import Preferences
                gtk.Dialog.__init__(self, buttons=('gtk-close', 
gtk.RESPONSE_CLOSE))
                self.set_title("Preferences")
                self.set_size_request(MIN_DIALOG_WIDTH, MIN_DIALOG_HEIGHT)

Modified: grc/trunk/src/grc/gui/elements/Block.py
===================================================================
--- grc/trunk/src/grc/gui/elements/Block.py     2008-07-28 23:34:17 UTC (rev 
9035)
+++ grc/trunk/src/grc/gui/elements/Block.py     2008-07-29 02:06:09 UTC (rev 
9036)
@@ -20,6 +20,7 @@
 #The graphical signal block.
 address@hidden Josh Blum
 
+from grc import Preferences
 from Element import Element
 import Utils
 import Colors
@@ -130,7 +131,6 @@
                layout.set_font_description(desc)
                self.label_width,self.label_height = layout.get_pixel_size()
                #display the params (except for the special params id and 
position)
-               from grc import Preferences
                if Preferences.show_params():
                        for param in filter(lambda p: not 
(p.get_key().startswith('gui_') or p.get_key().startswith('_')), 
self.get_params()):
                                if not Preferences.show_id() and 
param.get_key() == 'id': continue
@@ -175,16 +175,17 @@
                        window.draw_image(gc, self.horizontal_label, 0, 0, 
X+LABEL_PADDING_WIDTH, Y+(self.H-self.label_height)/2, -1, -1)
                elif self.is_vertical():
                        window.draw_image(gc, self.vertical_label, 0, 0, 
X+(self.H-self.label_height)/2, Y+LABEL_PADDING_WIDTH, -1, -1)
-               map(lambda p: p.draw(window), self.get_sources() + 
self.get_sinks())
+               map(lambda p: p.draw(window), self.get_ports())
 
-       def what_is_selected(self, coor):
+       def what_is_selected(self, coor, coor_m=None):
                """!
                Get the element that is selected.
                @param coor the (x,y) tuple
-               @return this signal block, a port, or None
+               @param coor_m the (x_m, y_m) tuple
+               @return this block, a port, or None
                """
-               for port in self.get_sources() + self.get_sinks():
-                       if port.what_is_selected(coor):
-                               return port.what_is_selected(coor)
-               return Element.what_is_selected(self, coor)
+               for port in self.get_ports():
+                       port_selected = port.what_is_selected(coor, coor_m)
+                       if port_selected: return port_selected
+               return Element.what_is_selected(self, coor, coor_m)
 

Modified: grc/trunk/src/grc/gui/elements/Element.py
===================================================================
--- grc/trunk/src/grc/gui/elements/Element.py   2008-07-28 23:34:17 UTC (rev 
9035)
+++ grc/trunk/src/grc/gui/elements/Element.py   2008-07-29 02:06:09 UTC (rev 
9036)
@@ -148,42 +148,72 @@
        def add_area(self, rel_coor, area, rotation=None):
                """!
                Add an area to the area list.
-               An area is actually a coordinate relative to the main 
coordinate with a width/height pair relative to the area coordinate.
-               A positive width is to the right of the coordinate. A positive 
height is above the coordinate.
-               The area is associated with a rotation. If rotation is not 
specified, the element's current rotation is used.
+               An area is actually a coordinate relative to the main coordinate
+               with a width/height pair relative to the area coordinate.
+               A positive width is to the right of the coordinate.
+               A positive height is above the coordinate.
+               The area is associated with a rotation.
+               If rotation is not specified, the element's current rotation is 
used.
                @param rel_coor (x,y) offset from this element's coordinate
                @param area (width,height) tuple
                @param rotation rotation in degrees
                """
-               if rotation == None: rotation = self.get_rotation()
-               self.areas_dict[rotation].append((rel_coor, area))
+               self.areas_dict[rotation or 
self.get_rotation()].append((rel_coor, area))
 
        def add_line(self, rel_coor1, rel_coor2, rotation=None):
                """!
                Add a line to the line list.
-               A line is defined by 2 relative coordinates.    Lines must be 
horizontal or vertical.
-               The line is associated with a rotation. If rotation is not 
specified, the element's current rotation is used.
+               A line is defined by 2 relative coordinates.
+               Lines must be horizontal or vertical.
+               The line is associated with a rotation.
+               If rotation is not specified, the element's current rotation is 
used.
                @param rel_coor1 relative (x1,y1) tuple
                @param rel_coor2 relative (x2,y2) tuple
                @param rotation rotation in degrees
                """
-               if rotation == None: rotation = self.get_rotation()
-               self.lines_dict[rotation].append((rel_coor1, rel_coor2))
+               self.lines_dict[rotation or 
self.get_rotation()].append((rel_coor1, rel_coor2))
 
-       def what_is_selected(self, coor):
+       def what_is_selected(self, coor, coor_m=None):
                """!
-               Is this Element selected at given coordinate/is the coordinate 
encompassed by one of the areas or lines?
+               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?
+               @param coor the selection coordinate, tuple x, y
+               @param coor_m an additional selection coordinate.
                @return 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)
-               x,y = [a-b for a,b in zip(coor, self.get_coordinate())]
-               for (x1,y1), (w,h) in self.areas_dict[self.get_rotation()]:
-                       if in_between(x, x1, x1+w) and in_between(y, y1, y1+h): 
return self
-               for (x1, y1), (x2, y2) in self.lines_dict[self.get_rotation()]: 
#assume horizontal or vertical lines
-                       if x1 == x2: x1, x2 = x1-CONNECTION_SELECT_SENSITIVITY, 
x2+CONNECTION_SELECT_SENSITIVITY
-                       if y1 == y2: y1, y2 = y1-CONNECTION_SELECT_SENSITIVITY, 
y2+CONNECTION_SELECT_SENSITIVITY
-                       if in_between(x, x1, x2) and in_between(y, y1, y2): 
return self
-               return None
+               #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_dict[self.get_rotation()]:
+                               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_dict[self.get_rotation()]:
+                               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_dict[self.get_rotation()]:
+                               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_dict[self.get_rotation()]:
+                               if x1 == x2: x1, x2 = 
x1-CONNECTION_SELECT_SENSITIVITY, x2+CONNECTION_SELECT_SENSITIVITY
+                               if y1 == y2: y1, y2 = 
y1-CONNECTION_SELECT_SENSITIVITY, y2+CONNECTION_SELECT_SENSITIVITY
+                               if in_between(x, x1, x2) and in_between(y, y1, 
y2): return self
+                       return None
 
        def get_rotation(self):
                """!

Modified: grc/trunk/src/grc/gui/elements/FlowGraph.py
===================================================================
--- grc/trunk/src/grc/gui/elements/FlowGraph.py 2008-07-28 23:34:17 UTC (rev 
9035)
+++ grc/trunk/src/grc/gui/elements/FlowGraph.py 2008-07-29 02:06:09 UTC (rev 
9036)
@@ -20,10 +20,11 @@
 #A flow graph structure for storing signal blocks and their connections.
 address@hidden Josh Blum
 
+from grc import Preferences
 from grc import Utils
 from grc.Constants import *
 from grc.Actions import *
-from Colors import BACKGROUND_COLOR, TXT_COLOR
+import Colors
 from grc.gui.ParamsDialog import ParamsDialog
 from Element import Element
 from grc.elements import FlowGraph as _FlowGraph
@@ -49,78 +50,143 @@
                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.has_moved = False
+               self.element_moved = False
                self.mouse_pressed = False
-               self._selected_element = None
-               self.is_selected = lambda: bool(self.get_selected_element())
+               self.unselect()
                self.time = 0
+               self.press_coor = (0, 0)
 
+       def _get_unique_id(self, base_id=''):
+               """!
+               Get a unique id starting with the base id.
+               @param base_id the id starts with this and appends a count
+               @return a unique id
+               """
+               index = -1
+               while True:
+                       id = (index < 0) and base_id or '%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
+
+###########################################################################
+# Access Drawing Area
+###########################################################################
        def get_drawing_area(self): return self.drawing_area
-
        def get_gc(self): return self.get_drawing_area().gc
-
        def get_pixmap(self): return self.get_drawing_area().pixmap
-
        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_window(self): return self.get_drawing_area().window
-
        def get_scroll_pane(self): return self.drawing_area.get_parent()
 
-###########################################################################
-#      Flow Graph Access Methods
-###########################################################################
-
-       def add_new_block(self, key, n=None):
+       def add_new_block(self, key):
                """!
                Add a block of the given key to this flow graph.
                @param key the block key
-               @param n nested data preloader for block
                """
-               index = -1
-               while True:
-                       id = (index < 0) and key or '%s%d'%(key, index)
-                       index = index + 1
-                       #make sure that the id is not used by another block
-                       if not filter(lambda e: e.is_block() and e.get_id() == 
id, self.get_elements()):
-                               v_val = 
self.get_scroll_pane().get_vadjustment().get_value()
-                               h_val = 
self.get_scroll_pane().get_hadjustment().get_value()
-                               x = random.randint(100,200) + int(h_val)
-                               y = random.randint(100,200) + int(v_val)
-                               #get the new block
-                               block = self.get_new_block(key)
-                               block.set_coordinate((x, y))
-                               block.set_rotation(0)
-                               block.get_param('id').set_value(id)
-                               #set params from n
-                               if n:
-                                       params_n = Utils.listify(n, 'param')
-                                       for param_n in params_n:
-                                               key = param_n['key']
-                                               value = param_n['value']
-                                               if not (key.startswith('_') or 
key.startswith('gui') or key == 'id'):
-                                                       
block.get_param(key).set_value(value)
-                               #handle new state
-                               self.handle_states(ELEMENT_CREATE)
-                               self.update()
-                               return
+               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()
+               x = random.randint(h_adj.page_size/4, 3*h_adj.page_size/4) + 
h_adj.get_value()
+               y = random.randint(v_adj.page_size/4, 3*v_adj.page_size/4) + 
v_adj.get_value()
+               #get the new block
+               block = self.get_new_block(key)
+               block.set_coordinate((x, y))
+               block.set_rotation(0)
+               block.get_param('id').set_value(id)
+               self.handle_states(ELEMENT_CREATE)
 
+       
###########################################################################
+       # Copy Paste
+       
###########################################################################
+       def copy_to_clipboard(self):
+               """!
+               Copy the selected blocks and connections into the clipboard.
+               @return 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.
+               @param 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['key']
+                       if block_key == 'options': continue
+                       block_id = self._get_unique_id(block_key)
+                       block = self.get_new_block(block_key)
+                       selected.add(block)
+                       #set params
+                       params_n = Utils.listify(block_n, 'param')
+                       for param_n in params_n:
+                               param_key = param_n['key']
+                               param_value = param_n['value']
+                               #setup id parameter
+                               if param_key == 'id':
+                                       old_id2block[param_value] = block
+                                       param_value = block_id
+                               #set value to key
+                               
block.get_param(param_key).set_value(param_value)
+                       #move block to offset coordinate
+                       block.move((x_off, y_off))
+               #create connections
+               for connection_n in connections_n:
+                       source = 
old_id2block[connection_n['source_block_id']].get_source(connection_n['source_key'])
+                       sink = 
old_id2block[connection_n['sink_block_id']].get_sink(connection_n['sink_key'])
+                       self.connect(source, sink)
+               #set all pasted elements selected
+               for block in selected: selected = 
selected.union(set(block.get_connections()))
+               self._selected_group = list(selected)
+
+       
###########################################################################
+       # Modify Selected
+       
###########################################################################
        def type_controller_modify_selected(self, direction):
                """
-               !Change the registered type controller for the selected signal 
block.
+               !Change the registered type controller for the selected signal 
blocks.
                @param direction +1 or -1
-               @return true for success
+               @return true for change
                """
-               if self.get_selected_block():
-                       for child in self.get_selected_block().get_params() + \
-                               self.get_selected_block().get_sources() + \
-                               self.get_selected_block().get_sinks():
+               changed = False
+               for selected_block in self.get_selected_blocks():
+                       for child in selected_block.get_params() + 
selected_block.get_ports():
                                #find a param that controls a type
                                type_param = None
-                               for param in 
self.get_selected_block().get_params():
+                               for param in selected_block.get_params():
                                        if not type_param and param.is_enum(): 
type_param = param
                                        if param.is_enum() and param.get_key() 
in child._type: type_param = param
                                if type_param:
@@ -130,22 +196,22 @@
                                                old_index = 
keys.index(type_param.get_value())
                                                new_index = (old_index + 
direction + len(keys))%len(keys)
                                                
type_param.set_value(keys[new_index])
-                                               self.update()
-                                               return True
-                                       except: return False
-               return False
+                                               changed = True
+                                       except: pass
+               return changed
 
        def port_controller_modify_selected(self, direction):
                """!
-               Change port controller for the selected signal block.
+               Change port controller for the selected signal blocks.
                @param direction +1 or -1
-               @return true for success
+               @return true for changed
                """
-               if self.get_selected_block():
-                       for ports in (self.get_selected_block().get_sources(), 
self.get_selected_block().get_sinks()):
+               changed = False
+               for selected_block in self.get_selected_blocks():
+                       for ports in (selected_block.get_sources(), 
selected_block.get_sinks()):
                                if ports and hasattr(ports[0], 'get_nports') 
and ports[0].get_nports():
                                        #find the param that controls port0
-                                       for param in 
self.get_selected_block().get_params():
+                                       for param in 
selected_block.get_params():
                                                if param.get_key() in 
ports[0]._nports:
                                                        #try to increment the 
port controller by direction
                                                        try:
@@ -153,134 +219,104 @@
                                                                value = value + 
direction
                                                                assert(0 < 
value <= MAX_NUM_PORTS)
                                                                
param.set_value(value)
-                                                               self.update()
-                                                               return True
-                                                       except: return False
-               return False
+                                                               changed = True
+                                                       except: pass
+               return changed
 
        def param_modify_selected(self):
                """!
-               Create and show a param modification dialog for the selected 
element (port and signal block only).
+               Create and show a param modification dialog for the selected 
block.
                @return true if parameters were changed
                """
                if self.get_selected_block():
                        signal_block_params_dialog = 
ParamsDialog(self.get_selected_block())
-                       changed = signal_block_params_dialog.run()
-                       return changed #changes were made?
+                       return signal_block_params_dialog.run()
                return False
 
        def enable_selected(self, enable):
                """!
-               Enable/disable the selected block.
+               Enable/disable the selected blocks.
                @param enable true to enable
                @return true if changed
                """
-               if self.get_selected_block():
-                       if self.get_selected_block().get_enabled() == enable: 
return False
-                       self.get_selected_block().set_enabled(enable)
-                       self.update()
-                       return True
-               return False
+               changed = False
+               for selected_block in self.get_selected_blocks():
+                       if selected_block.get_enabled() != enable: changed = 
True
+                       selected_block.set_enabled(enable)
+                       changed = True
+               return changed
 
        def move_selected(self, delta_coordinate):
                """!
                Move the element and by the change in coordinates.
                @param delta_coordinate the change in coordinates
                """
-               if self.get_selected_element():
-                       self.get_selected_element().move(delta_coordinate)
-                       self.has_moved = True
-                       self.draw()
+               for selected_block in self.get_selected_blocks():
+                       selected_block.move(delta_coordinate)
+                       self.element_moved = True
 
        def rotate_selected(self, direction):
                """!
-               Rotate the selected element by 90 degrees. Only rotate 
SignalBlocks and Sockets.
+               Rotate the selected blocks by 90 degrees.
                @param direction DIR_LEFT or DIR_RIGHT
-               @return true if rotated, otherwise false.
+               @return true if changed, otherwise false.
                """
-               if self.get_selected_element() and 
(self.get_selected_element().is_block() or \
-                       self.get_selected_element().is_source() or 
self.get_selected_element().is_sink()):
-                       self.get_selected_element().rotate(direction)
-                       self.draw()
-                       return True
-               return False
+               changed = False
+               for selected_block in self.get_selected_blocks():
+                       selected_block.rotate(direction)
+                       changed = True
+               return changed
 
        def remove_selected(self):
                """!
-               If an element is selected, remove it and its attached parts 
from the element list.
-               @return true if the element was deleted, otherwise false.
+               Remove selected elements
+               @return true if changed.
                """
-               if self.get_selected_element():
-                       self.remove_element(self.get_selected_element())
-                       self.unselect()
-                       return True
-               return False
+               changed = False
+               for selected_element in self.get_selected_blocks() + 
self.get_selected_connections():
+                       self.remove_element(selected_element)
+                       changed = True
+               return changed
 
-       def unselect(self):
-               """Set selected element to None."""
-               self._selected_element = None
-
-       def what_is_selected(self, coor):
+       def draw(self):
                """!
-               What is selected?
-               At the given coordinate, return the first element found to be 
selected
-               - iterate though the elements backwards since top elements are 
at the end of the list
-               - if an element is selected, place it at the end of the list so 
that is is drawn last,
-                       and hence on top.
-               @param coor the coordinate of the mouse click
-               @return the selected element or None
+               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.
                """
-               #check the elements
-               for element in reversed(self.get_elements()):
-                       if element.what_is_selected(coor):
-                               self.get_elements().remove(element)
-                               self.get_elements().append(element)
-                               return element.what_is_selected(coor)
-               return None
-
-       def get_selected_element(self):
-               """!
-               Get the selected element.
-               @return a block, port, or connection or None
-               """
-               return self._selected_element
-
-       def get_selected_block(self):
-               """!
-               Get the selected block when a block or port is selected.
-               @return a block or None
-               """
-               #determine the selected block or None
-               if self.get_selected_element() and 
self.get_selected_element().is_block():
-                       return self.get_selected_element()
-               elif self.get_selected_element() and 
(self.get_selected_element().is_source() or 
self.get_selected_element().is_sink()):
-                       return self.get_selected_element().get_parent()
-               else: return None
-
-       def draw(self):
-               """Draw the background and then all of the Elements in this 
FlowGraph on the pixmap,
-               then draw the pixmap to the drawable window of this 
FlowGraph."""
                if self.get_gc():
                        W,H = self.get_size()
                        #draw the background
-                       self.get_gc().foreground = BACKGROUND_COLOR
+                       self.get_gc().foreground = Colors.BACKGROUND_COLOR
                        self.get_pixmap().draw_rectangle(self.get_gc(), True, 
0, 0, W, H)
                        #draw grid (depends on prefs)
-                       from grc import Preferences
                        if Preferences.show_grid():
                                grid_size = Preferences.get_grid_size()
                                points = list()
                                for i in range(W/grid_size):
                                        for j in range(H/grid_size):
                                                points.append((i*grid_size, 
j*grid_size))
-                               self.get_gc().foreground = TXT_COLOR
+                               self.get_gc().foreground = Colors.TXT_COLOR
                                self.get_pixmap().draw_points(self.get_gc(), 
points)
+                       #draw multi select rectangle
+                       if self.mouse_pressed and not 
self.get_selected_elements():
+                               #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
+                               self.get_gc().foreground = Colors.H_COLOR
+                               self.get_pixmap().draw_rectangle(self.get_gc(), 
True, x, y, w, h)
+                               self.get_gc().foreground = Colors.TXT_COLOR
+                               self.get_pixmap().draw_rectangle(self.get_gc(), 
False, x, y, w, h)
                        #draw blocks on top of connections
                        for element in self.get_connections() + 
self.get_blocks():
                                element.draw(self.get_pixmap())
                        #draw any selected element as the topmost
-                       if self.get_selected_element():
-                               
self.get_selected_element().draw(self.get_pixmap())
+                       for selected_element in self.get_selected_blocks() + 
self.get_selected_connections():
+                               selected_element.draw(self.get_pixmap())
                        self.get_drawing_area().draw()
 
        def update(self):
@@ -291,8 +327,8 @@
                """
                #update highlighting
                map(lambda e: e.set_highlighted(False), self.get_elements())
-               if self.get_selected_element():
-                       self.get_selected_element().set_highlighted(True)
+               for selected_element in self.get_selected_elements(): 
+                       selected_element.set_highlighted(True)
                #update all elements
                map(lambda e: e.update(), self.get_elements())
                #set the size of the flow graph area
@@ -302,9 +338,81 @@
                if new_x != old_x or new_y != old_y: self.set_size(new_x, new_y)
 
        
##########################################################################
-       ##      Handlers
+       ## Get Selected
        
##########################################################################
+       def unselect(self):
+               """Set selected element to None."""
+               self._selected_group = []
 
+       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.
+               @param coor the coordinate of the mouse click
+               @param coor_m the coordinate for multi select
+               @return the selected elements or empty list
+               """
+               selected = set()
+               #check the elements
+               for element in reversed(self.get_elements()):
+                       selected_element = element.what_is_selected(coor, 
coor_m)
+                       if selected_element:
+                               if not coor_m:
+                                       self.get_elements().remove(element)
+                                       self.get_elements().append(element)
+                                       return [selected_element]
+                               selected.add(selected_element)
+               return list(selected)
+
+       def get_selected_connections(self):
+               """!
+               Get a group of selected connections.
+               @return 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.
+               @return sub set of blocks in this flow graph
+               """
+               selected = set()
+               for selected_element in self.get_selected_elements():
+                       if selected_element.is_port(): 
selected.add(selected_element.get_parent())
+                       elif 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.
+               @return 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.
+               @return sub set of elements in this flow graph
+               """
+               return self._selected_group
+
+       def get_selected_element(self):
+               """!
+               Get the selected element.
+               @return a block, port, or connection or None
+               """
+               return self.get_selected_elements() and 
self.get_selected_elements()[0] or None
+
+       
##########################################################################
+       ## Event Handlers
+       
##########################################################################
        def handle_mouse_button_press(self, left_click, double_click, 
coordinate):
                """!
                A mouse button is pressed, only respond to left clicks.
@@ -312,17 +420,24 @@
                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)
                if left_click:
                        self.time = 0
                        self.mouse_pressed = True
                        old_selection = self.get_selected_element()
-                       self._selected_element = 
self.what_is_selected(self.get_coordinate())
+                       new_selection = 
self.what_is_selected(self.get_coordinate())
+                       #update the selections if the new selection is not in 
the current blocks/connections
+                       #allows us to move entire selected groups of 
blocks/connections
+                       if not (
+                               new_selection and new_selection[0] in \
+                               self.get_selected_blocks() + 
self.get_selected_connections()
+                       ): self._selected_group = new_selection
                        #this selection and the last were ports, try to connect 
them
                        if old_selection and self.get_selected_element() and \
                                old_selection is not 
self.get_selected_element() and \
-                               (self.get_selected_element().is_source() or 
self.get_selected_element().is_sink()) and \
-                               (old_selection.is_source() or 
old_selection.is_sink()):
+                               self.get_selected_element().is_port() and \
+                               old_selection.is_port():
                                try:
                                        self.connect(old_selection, 
self.get_selected_element())
                                        self.handle_states(ELEMENT_CREATE)
@@ -342,8 +457,7 @@
                if left_click:
                        self.time = 0
                        self.mouse_pressed = False
-                       if self.has_moved:
-                               from grc import Preferences
+                       if self.element_moved:
                                if Preferences.snap_to_grid():
                                        grid_size = Preferences.get_grid_size()
                                        X,Y = 
self.get_selected_element().get_coordinate()
@@ -355,7 +469,11 @@
                                        else: deltaY = grid_size - deltaY
                                        self.move_selected((deltaX, deltaY))
                                self.handle_states(BLOCK_MOVE)
-                               self.has_moved = False
+                               self.element_moved = False
+                       elif not self.element_moved and not 
self.get_selected_elements():
+                               self._selected_group = 
self.what_is_selected(self.get_coordinate(), self.press_coor)
+                               self.update()
+                               self.draw()
 
        def handle_mouse_motion(self, coordinate):
                """!
@@ -363,14 +481,13 @@
                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, an element 
selected, timediff large enough.
-               if time.time() - self.time >= 
MOTION_DETECT_REDRAWING_SENSITIVITY and \
-                       self.mouse_pressed and self.get_selected_element():
+               #to perform a movement, the mouse must be pressed, timediff 
large enough.
+               if time.time() - self.time >= 
MOTION_DETECT_REDRAWING_SENSITIVITY and self.mouse_pressed:
                        #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()
-                       h_adj = self.get_scroll_pane().get_hadjustment()
                        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),
@@ -385,6 +502,7 @@
                        #move the selected element and record the new coordinate
                        X, Y = self.get_coordinate()
                        self.move_selected((int(x - X), int(y - Y)))
+                       self.draw()
                        self.set_coordinate((x, y))
                        #update time
                        self.time = time.time()

Modified: grc/trunk/src/grc/gui/elements/Port.py
===================================================================
--- grc/trunk/src/grc/gui/elements/Port.py      2008-07-28 23:34:17 UTC (rev 
9035)
+++ grc/trunk/src/grc/gui/elements/Port.py      2008-07-29 02:06:09 UTC (rev 
9036)
@@ -29,64 +29,64 @@
 import pango
 
 class Port(Element):
-       """The graphical port."""       
-                               
+       """The graphical port."""
+
        def __init__(self, *args, **kwargs):
                """!
                Port contructor.
                Create list of connector coordinates.
-               """     
+               """
                Element.__init__(self)
                self.connector_coordinates = dict()
-                               
+
        def update(self):
                """Create new areas and labels for the port."""
                self.clear()
                self.BG_color = Colors.get_color(self.get_color())
-               self._create_labels()   
+               self._create_labels()
                #get current rotation
-               rotation = self.get_rotation()          
-               #get all sibling ports  
+               rotation = self.get_rotation()
+               #get all sibling ports
                if self.is_source(): ports = self.get_parent().get_sources()
-               elif self.is_sink(): ports = self.get_parent().get_sinks()      
        
+               elif self.is_sink(): ports = self.get_parent().get_sinks()
                #get a numeric index for this port relative to its sibling ports
                index = ports.index(self)
-               length = len(ports)     
-               #reverse the order of ports     for these rotations             
+               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*PORT_HEIGHT - 
(length-1)*PORT_SEPARATION)/2                      
+               offset = (self.get_parent().H - length*PORT_HEIGHT - 
(length-1)*PORT_SEPARATION)/2
                #create areas and connector coordinates
-               if (self.is_sink() and rotation == 0) or (self.is_source() and 
rotation == 180):                
+               if (self.is_sink() and rotation == 0) or (self.is_source() and 
rotation == 180):
                        x = -1*PORT_WIDTH
                        y = (PORT_SEPARATION+PORT_HEIGHT)*index+offset
                        self.add_area((x, y), (PORT_WIDTH, PORT_HEIGHT))
                        self._connector_coordinate = (x-1, y+PORT_HEIGHT/2)
-               elif (self.is_source() and rotation == 0) or (self.is_sink() 
and rotation == 180):      
+               elif (self.is_source() and rotation == 0) or (self.is_sink() 
and rotation == 180):
                        x = self.get_parent().W
                        y = (PORT_SEPARATION+PORT_HEIGHT)*index+offset
                        self.add_area((x, y), (PORT_WIDTH, PORT_HEIGHT))
                        self._connector_coordinate = (x+1+PORT_WIDTH, 
y+PORT_HEIGHT/2)
-               elif (self.is_source() and rotation == 90) or (self.is_sink() 
and rotation == 270):             
+               elif (self.is_source() and rotation == 90) or (self.is_sink() 
and rotation == 270):
                        y = -1*PORT_WIDTH
                        x = (PORT_SEPARATION+PORT_HEIGHT)*index+offset
                        self.add_area((x, y), (PORT_HEIGHT, PORT_WIDTH))
                        self._connector_coordinate = (x+PORT_HEIGHT/2, y-1)
-               elif (self.is_sink() and rotation == 90) or (self.is_source() 
and rotation == 270):     
+               elif (self.is_sink() and rotation == 90) or (self.is_source() 
and rotation == 270):
                        y = self.get_parent().W
                        x = (PORT_SEPARATION+PORT_HEIGHT)*index+offset
                        self.add_area((x, y), (PORT_HEIGHT, PORT_WIDTH))
                        self._connector_coordinate = (x+PORT_HEIGHT/2, 
y+1+PORT_WIDTH)
                #the connector length
                self._connector_length = CONNECTOR_EXTENSION_INITIAL_LENGTH + 
CONNECTOR_EXTENSION_LENGTH*index
-                       
+
        def _create_labels(self):
                """Create the labels for the socket."""
                #create the layout
                layout = gtk.DrawingArea().create_pango_layout(self.get_name())
                desc = pango.FontDescription(PORT_FONT)
-               layout.set_font_description(desc) 
-               w,h = self.w,self.h = layout.get_pixel_size()   
-               #create the pixmap      
+               layout.set_font_description(desc)
+               w,h = self.w,self.h = layout.get_pixel_size()
+               #create the pixmap
                pixmap = 
gtk.gdk.Pixmap(self.get_parent().get_parent().get_window(), w, h, -1)
                gc = pixmap.new_gc()
                gc.foreground = self.BG_color
@@ -94,46 +94,46 @@
                gc.foreground = Colors.TXT_COLOR
                pixmap.draw_layout(gc, 0, 0, layout)
                #create the images
-               self.horizontal_label = image = pixmap.get_image(0, 0, w, h)    
-               if self.is_vertical():  
+               self.horizontal_label = image = pixmap.get_image(0, 0, w, h)
+               if self.is_vertical():
                        self.vertical_label = vimage = 
gtk.gdk.Image(gtk.gdk.IMAGE_NORMAL, pixmap.get_visual(), h, w)
                        for i in range(w):
                                for j in range(h): vimage.put_pixel(j, w-i-1, 
image.get_pixel(i, j))
-                               
+
        def draw(self, window):
                """!
                Draw the socket with a label.
                @param window the gtk window to draw on
                """
-               Element.draw(self, window, BG_color=self.BG_color)              
                
-               gc = self.get_gc()                              
+               Element.draw(self, window, BG_color=self.BG_color)
+               gc = self.get_gc()
                gc.foreground = Colors.TXT_COLOR
                X,Y = self.get_coordinate()
                (x,y),(w,h) = self.areas_dict[self.get_rotation()][0] #use the 
first area's sizes to place the labels
-               if self.is_horizontal(): 
+               if self.is_horizontal():
                        window.draw_image(gc, self.horizontal_label, 0, 0, 
x+X+(PORT_WIDTH-self.w)/2, y+Y+(PORT_HEIGHT-self.h)/2, -1, -1)
-               elif self.is_vertical(): 
+               elif self.is_vertical():
                        window.draw_image(gc, self.vertical_label, 0, 0, 
x+X+(PORT_HEIGHT-self.h)/2, y+Y+(PORT_WIDTH-self.w)/2, -1, -1)
-       
+
        def get_connector_coordinate(self):
                """!
                Get the coordinate where connections may attach to.
                @return the connector coordinate (x, y) tuple
                """
                x,y = self._connector_coordinate
-               X,Y = self.get_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.
                @return the direction in degrees
-               """     
+               """
                if self.is_source(): return self.get_rotation()
-               elif self.is_sink(): return (self.get_rotation() + 180)%360     
-               
+               elif self.is_sink(): return (self.get_rotation() + 180)%360
+
        def get_connector_length(self):
                """!
                Get the length of the connector.
@@ -141,45 +141,45 @@
                @return the length in pixels
                """
                return self._connector_length
-               
+
        def get_rotation(self):
                """!
                Get the parent's rotation rather than self.
                @return the parent's rotation
                """
                return self.get_parent().get_rotation()
-               
+
        def move(self, delta_coor):
                """!
                Move the parent rather than self.
                @param delta_corr the (delta_x, delta_y) tuple
                """
                self.get_parent().move(delta_coor)
-               
+
        def rotate(self, direction):
                """!
                Rotate the parent rather than self.
                @param direction degrees to rotate
                """
                self.get_parent().rotate(direction)
-               
+
        def get_coordinate(self):
                """!
                Get the parent's coordinate rather than self.
                @return the parents coordinate
                """
                return self.get_parent().get_coordinate()
-               
+
        def set_highlighted(self, highlight):
                """!
                Set the parent highlight rather than self.
                @param highlight true to enable highlighting
                """
                self.get_parent().set_highlighted(highlight)
-               
+
        def is_highlighted(self):
                """!
                Get the parent's is highlight rather than self.
                @return the parent's highlighting status
                """
-               return self.get_parent().is_highlighted()               
+               return self.get_parent().is_highlighted()

Modified: grc/trunk/src/grc_gnuradio/Block.py
===================================================================
--- grc/trunk/src/grc_gnuradio/Block.py 2008-07-28 23:34:17 UTC (rev 9035)
+++ grc/trunk/src/grc_gnuradio/Block.py 2008-07-29 02:06:09 UTC (rev 9036)
@@ -97,7 +97,6 @@
                                                
self.get_parent().remove_element(connection)
                                #remove the ports
                                for key in map(str, range(nports, num_ports)): 
ports.pop(key)
-                               self.get_parent().is_valid() #FIXME: 
inappropriate solution
                                continue
                        #add more ports
                        if nports > num_ports:
@@ -106,7 +105,6 @@
                                        n['key'] = key
                                        port = Port(self, n)
                                        ports[key] = port
-                               self.get_parent().is_valid() #FIXME: 
inappropriate solution
                                continue
 
        def get_doc(self):





reply via email to

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