changeset 129:9a1529f9625e

* Indentation patch by GreyGhost
author mvbarracuda@33b003aa-7bff-0310-803a-e67f0ece8222
date Thu, 07 Aug 2008 15:46:46 +0000
parents 6e1fd3571440
children b49714fff478
files clients/rio_de_hola/scripts/agents/agent.py clients/rio_de_hola/scripts/agents/beekeeper.py clients/rio_de_hola/scripts/agents/cloud.py clients/rio_de_hola/scripts/agents/girl.py clients/rio_de_hola/scripts/agents/hero.py clients/rio_de_hola/scripts/common/eventlistenerbase.py clients/rio_de_hola/scripts/world.py engine/extensions/basicapplication.py engine/extensions/fife_utils.py engine/extensions/fifelog.py engine/extensions/pychan/__init__.py engine/extensions/pychan/attrs.py engine/extensions/pychan/fonts.py engine/extensions/pychan/manager.py engine/extensions/pychan/tools.py engine/extensions/pychan/widgets.py engine/extensions/pythonize.py engine/extensions/savers.py engine/extensions/serializers/__init__.py engine/extensions/serializers/xmlanimation.py engine/extensions/serializers/xmlmap.py engine/extensions/serializers/xmlobject.py
diffstat 22 files changed, 279 insertions(+), 292 deletions(-) [+]
line wrap: on
line diff
--- a/clients/rio_de_hola/scripts/agents/agent.py	Wed Aug 06 22:35:27 2008 +0000
+++ b/clients/rio_de_hola/scripts/agents/agent.py	Thu Aug 07 15:46:46 2008 +0000
@@ -16,7 +16,7 @@
 
 	def start(self):
 		raise ProgrammingError('No start defined for Agent')
-	
+
 
 def create_anonymous_agents(model, objectName, layer, agentClass):
 	agents = []
--- a/clients/rio_de_hola/scripts/agents/beekeeper.py	Wed Aug 06 22:35:27 2008 +0000
+++ b/clients/rio_de_hola/scripts/agents/beekeeper.py	Thu Aug 07 15:46:46 2008 +0000
@@ -17,7 +17,7 @@
 		c.x += random.randint(-1, 1)
 		c.y += random.randint(-1, 1)
 		self.talk()
-	
+
 	def talk(self):
 		self.state = _STATE_TALK
 		self.agent.act('talk', self.facingLoc, True) # never calls back
--- a/clients/rio_de_hola/scripts/agents/cloud.py	Wed Aug 06 22:35:27 2008 +0000
+++ b/clients/rio_de_hola/scripts/agents/cloud.py	Thu Aug 07 15:46:46 2008 +0000
@@ -8,7 +8,7 @@
 	def __init__(self, model, agentName, layer, uniqInMap=False):
 		super(Cloud, self).__init__(model, agentName, layer, uniqInMap)
 		self.state = _STATE_NONE
-		
+
 	def isOutOfBounds(self, c):
 		return (c.x < 0) or (c.x > 100) or (c.y < 0) or (c.y > 100)
 
@@ -33,16 +33,15 @@
 		self.loc = self.agent.getLocation()
 		self.initialCoords = self.agent.getLocation().getExactLayerCoordinates()
 		self.appear()
-	
+
 	def appear(self):
 		self.state = _STATE_APPEAR
 		self.agent.act('appear', self.loc, False)
-	
+
 	def disappear(self):
 		self.state = _STATE_DISAPPEAR
 		self.agent.act('disappear', self.loc, False)
-	
+
 	def move(self):
 		self.state = _STATE_FLOATING
 		self.agent.act('default', self.loc, False)
-	
--- a/clients/rio_de_hola/scripts/agents/girl.py	Wed Aug 06 22:35:27 2008 +0000
+++ b/clients/rio_de_hola/scripts/agents/girl.py	Thu Aug 07 15:46:46 2008 +0000
@@ -30,19 +30,18 @@
 		l = fife.Location(self.layer)
 		l.setLayerCoordinates(fife.ModelCoordinate(*self.waypoints[self.waypoint_counter % len(self.waypoints)]))
 		return l
-	
+
 	def start(self):
 		self.follow_hero()
-	
+
 	def idle(self):
 		self.state = _STATE_IDLE
 		self.agent.act('stand', self.agent.getFacingLocation(), False)
-		
+
 	def follow_hero(self):
 		self.state = _STATE_FOLLOW
 		self.agent.follow('run', self.hero, GIRL_SPEED)
-		
+
 	def run(self, location):
 		self.state = _STATE_RUN
 		self.agent.move('run', location, GIRL_SPEED)
-	
--- a/clients/rio_de_hola/scripts/agents/hero.py	Wed Aug 06 22:35:27 2008 +0000
+++ b/clients/rio_de_hola/scripts/agents/hero.py	Thu Aug 07 15:46:46 2008 +0000
@@ -22,22 +22,22 @@
 			heroTexts = TDS.readSetting("heroTexts", type='list', text=True)
 			txtindex = random.randint(0, len(heroTexts) - 1)
 			instance.say(heroTexts[txtindex], 2500)
-	
+
 	def start(self):
 		self.idle()
-	
+
 	def idle(self):
 		self.state = _STATE_IDLE
 		self.agent.act('stand', self.agent.getFacingLocation())
-		
+
 	def run(self, location):
 		self.state = _STATE_RUN
 		self.agent.move('run', location, 4 * float(TDS.readSetting("TestAgentSpeed")))
-	
+
 	def kick(self, target):
 		self.state = _STATE_KICK
 		self.agent.act('kick', target)
-		
+
 	def talk(self, target):
 		self.state = _STATE_TALK
 		self.agent.act('talk', target)
--- a/clients/rio_de_hola/scripts/common/eventlistenerbase.py	Wed Aug 06 22:35:27 2008 +0000
+++ b/clients/rio_de_hola/scripts/common/eventlistenerbase.py	Thu Aug 07 15:46:46 2008 +0000
@@ -1,10 +1,9 @@
 import fife
 
-class EventListenerBase(fife.IKeyListener, fife.ICommandListener, fife.IMouseListener,
-	                fife.ConsoleExecuter, fife.IWidgetListener):
+class EventListenerBase(fife.IKeyListener, fife.ICommandListener, fife.IMouseListener, fife.ConsoleExecuter, fife.IWidgetListener):
 	def __init__(self, engine, regKeys=False, regCmd=False, regMouse=False, regConsole=False, regWidget=False):
 		self.eventmanager = engine.getEventManager()
-		
+
 		fife.IKeyListener.__init__(self)
 		if regKeys:
 			self.eventmanager.addKeyListener(self)
@@ -20,8 +19,8 @@
 		fife.IWidgetListener.__init__(self)
 		if regWidget:
 			self.eventmanager.addWidgetListener(self)
-		
-	
+
+
 	def mousePressed(self, evt):
 		pass
 	def mouseReleased(self, evt):
--- a/clients/rio_de_hola/scripts/world.py	Wed Aug 06 22:35:27 2008 +0000
+++ b/clients/rio_de_hola/scripts/world.py	Thu Aug 07 15:46:46 2008 +0000
@@ -18,17 +18,17 @@
 	def __init__(self, map):
 		fife.MapChangeListener.__init__(self)
 		map.addChangeListener(self)
-	
+
 	def onMapChanged(self, map, changedLayers):
 		return
 		print "Changes on map ", map.getId()
 		for layer in map.getLayers():
 			print layer.getId()
 			print "    ", ["%s, %x" % (i.getObject().getId(), i.getChangeInfo()) for i in layer.getChangedInstances()]
-	
+
 	def onLayerCreate(self, map, layer):
 		pass
-	
+
 	def onLayerDelete(self, map, layer):
 		pass
 
@@ -46,11 +46,11 @@
 		self.instancemenu = None
 		self.instance_to_agent = {}
 		self.dynamic_widgets = {}
-		
+
 	def show_instancemenu(self, clickpoint, instance):
 		if instance.getFifeId() == self.hero.agent.getFifeId():
 			return
-		
+
 		dynamicbuttons = ('moveButton', 'talkButton', 'kickButton', 'inspectButton')
 		if not self.instancemenu:
 			self.instancemenu = pychan.loadXML('gui/instancemenu.xml')
@@ -67,10 +67,10 @@
 				self.instancemenu.removeChild(self.dynamic_widgets[btn])
 			except pychan.exceptions.RuntimeError:
 				pass
-		
+
 		self.instancemenu.clickpoint = clickpoint
 		self.instancemenu.instance = instance
-		
+
 		self.instancemenu.addChild(self.dynamic_widgets['inspectButton'])
 		target_distance = self.hero.agent.getLocationRef().getLayerDistanceTo(instance.getLocationRef())
 		if target_distance > 3.0:
@@ -81,11 +81,11 @@
 				self.instancemenu.addChild(self.dynamic_widgets['kickButton'])
 		self.instancemenu.position = (clickpoint.x, clickpoint.y)
 		self.instancemenu.show()
-		
+
 	def hide_instancemenu(self):
 		if self.instancemenu:
 			self.instancemenu.hide()
-		
+
 	def reset(self):
 		self.map, self.agentlayer = None, None
 		self.cameras = {}
@@ -99,16 +99,16 @@
 		self.reset()
 		self.map = loadMapFile(filename, self.engine)
 		self.maplistener = MapListener(self.map)
-		
+
 		self.agentlayer = self.map.getLayer('TechdemoMapGroundObjectLayer')
 		self.hero = Hero(self.model, 'PC', self.agentlayer)
 		self.instance_to_agent[self.hero.agent.getFifeId()] = self.hero
 		self.hero.start()
-		
+
 		self.girl = Girl(self.model, 'NPC:girl', self.agentlayer)
 		self.instance_to_agent[self.girl.agent.getFifeId()] = self.girl
 		self.girl.start()
-		
+
 		self.beekeepers = create_anonymous_agents(self.model, 'beekeeper', self.agentlayer, Beekeeper)
 		for beekeeper in self.beekeepers:
 			self.instance_to_agent[beekeeper.agent.getFifeId()] = beekeeper
@@ -118,37 +118,37 @@
 		self.clouds = create_anonymous_agents(self.model, 'Cloud', cloudlayer, Cloud)
 		for cloud in self.clouds:
 			cloud.start(0.1, 0.05)
-		
+
 		for cam in self.view.getCameras():
 			self.cameras[cam.getId()] = cam
 		self.cameras['main'].attach(self.hero.agent)
-				
+
 		self.view.resetRenderers()
 		renderer = fife.FloatingTextRenderer.getInstance(self.cameras['main'])
 		textfont = self.engine.getGuiManager().createFont('fonts/rpgfont.png', 0, str(TDS.readSetting("FontGlyphs", strip=False)));
 		renderer.changeDefaultFont(textfont)
-		
+
 		renderer = fife.FloatingTextRenderer.getInstance(self.cameras['small'])
 		renderer.changeDefaultFont(None)
-		
+
 		renderer = self.cameras['main'].getRenderer('CoordinateRenderer')
 		renderer.clearActiveLayers()
 		renderer.addActiveLayer(self.map.getLayer(str(TDS.readSetting("CoordinateLayerName"))))
-		
+
 		renderer = self.cameras['main'].getRenderer('QuadTreeRenderer')
 		renderer.setEnabled(True)
 		renderer.clearActiveLayers()
 		if str(TDS.readSetting("QuadTreeLayerName")):
 			renderer.addActiveLayer(self.map.getLayer(str(TDS.readSetting("QuadTreeLayerName"))))
-		
+
 		self.cameras['small'].getLocationRef().setExactLayerCoordinates( fife.ExactModelCoordinate( 40.0, 40.0, 0.0 ))
 		self.initial_cam2_x = self.cameras['small'].getLocation().getExactLayerCoordinates().x
 		self.cur_cam2_x = self.initial_cam2_x
 		self.cam2_scrolling_right = True
 		self.cameras['small'].setEnabled(False)
-		
+
 		self.target_rotation = self.cameras['main'].getRotation()
-	
+
 	def save(self, filename):
 		saveMapFile(filename, self.engine, self.map)
 
@@ -174,29 +174,29 @@
 			self.target_rotation = (self.target_rotation + 90) % 360
 		elif keyval in (fife.Key.LEFT_CONTROL, fife.Key.RIGHT_CONTROL):
 			self.ctrldown = True
-	
+
 	def keyReleased(self, evt):
 		keyval = evt.getKey().getValue()
 		if keyval in (fife.Key.LEFT_CONTROL, fife.Key.RIGHT_CONTROL):
 			self.ctrldown = False
-	
+
 	def mouseWheelMovedUp(self, evt):
 		if self.ctrldown:
 			self.cameras['main'].setZoom(self.cameras['main'].getZoom() * 1.05)
-	
+
 	def mouseWheelMovedDown(self, evt):
 		if self.ctrldown:
 			self.cameras['main'].setZoom(self.cameras['main'].getZoom() / 1.05)
-	
+
 	def changeRotation(self):
 		currot = self.cameras['main'].getRotation()
 		if self.target_rotation != currot:
 			self.cameras['main'].setRotation((currot + 5) % 360)
-	
+
 	def mousePressed(self, evt):
 		if evt.isConsumedByWidgets():
 			return
-		
+
 		clickpoint = fife.ScreenPoint(evt.getX(), evt.getY())
 		if (evt.getButton() == fife.MouseEvent.LEFT):
 			self.hide_instancemenu()
@@ -205,13 +205,13 @@
 			l = fife.Location(self.agentlayer)
 			l.setMapCoordinates(target_mapcoord)
 			self.hero.run(l)
-			
+
 		if (evt.getButton() == fife.MouseEvent.RIGHT):
 			instances = self.cameras['main'].getMatchingInstances(clickpoint, self.agentlayer)
 			print "selected instances on agent layer: ", [i.getObject().getId() for i in instances]
 			if instances:
 				self.show_instancemenu(clickpoint, instances[0])
-	
+
 	def mouseMoved(self, evt):
 		renderer = fife.InstanceRenderer.getInstance(self.cameras['main'])
 		renderer.removeAllOutlines()
@@ -221,7 +221,7 @@
 		for i in instances:
 			if i.getObject().getId() in ('girl', 'beekeeper'):
 				renderer.addOutlined(i, 173, 255, 47, 2)
-	
+
 	def onConsoleCommand(self, command):
 		result = ''
 		try:
@@ -233,7 +233,7 @@
 	def onMoveButtonPress(self):
 		self.hide_instancemenu()
 		self.hero.run(self.instancemenu.instance.getLocationRef())
-	
+
 	def onTalkButtonPress(self):
 		self.hide_instancemenu()
 		instance = self.instancemenu.instance
@@ -246,12 +246,12 @@
 			girlTexts = TDS.readSetting("girlTexts", type='list', text=True)
 			txtindex = random.randint(0, len(girlTexts) - 1)
 			instance.say(girlTexts[txtindex], 5000)
-	
+
 	def onKickButtonPress(self):
 		self.hide_instancemenu()
 		self.hero.kick(self.instancemenu.instance.getLocationRef())
 		self.instancemenu.instance.say('Hey!', 1000)
-	
+
 	def onInspectButtonPress(self):
 		self.hide_instancemenu()
 		inst = self.instancemenu.instance
@@ -261,7 +261,7 @@
 		saytext.append(' ID %s and' % inst.getFifeId())
 		saytext.append(' object name %s' % inst.getObject().getId())
 		self.hero.agent.say('\n'.join(saytext), 3500)
-		
+
 	def pump(self):
 		if self.cameras['small'].isEnabled():
 			loc = self.cameras['small'].getLocation()
--- a/engine/extensions/basicapplication.py	Wed Aug 06 22:35:27 2008 +0000
+++ b/engine/extensions/basicapplication.py	Thu Aug 07 15:46:46 2008 +0000
@@ -13,7 +13,7 @@
 class ExitEventListener(fife.IKeyListener):
 	"""
 	Default, rudimentary event listener.
-	
+
 	Will cause the application to quit on pressing ESC.
 	"""
 	def __init__(self, app):
@@ -29,32 +29,32 @@
 		keyval = evt.getKey().getValue()
 		if keyval == fife.Key.ESCAPE:
 			self.app.quit()
-	
+
 	def keyReleased(self, evt):
 		pass
 
 class ApplicationBase(object):
 	"""
 	ApplicationBase is an extendable class that provides a basic environment for a FIFE-based client.
-	
+
 	The unextended application reads in and initializes engine settings, sets up a simple event
 	listener, and pumps the engine while listening for a quit message. Specialized applications can
 	modify settings.py to change initial engine settings. They can provide their own event listener
 	by overriding L{createListener}. And they can override the L{_pump} method
 	to define runtime behavior of the application.
-	
+
 	"""
 	def __init__(self):
 		self.engine = fife.Engine()
 
 		self.loadSettings()
 		self.initLogging()
-		
+
 		self.engine.init()
-		
+
 		self._animationloader = XMLAnimationLoader(self.engine.getImagePool(), self.engine.getVFS())
 		self.engine.getAnimationPool().addResourceLoader(self._animationloader)
-		
+
 		self.quitRequested = False
 		self.breakRequested = False
 		self.returnValues = []
@@ -66,7 +66,7 @@
 		"""
 		import settings
 		self.settings = settings
-		
+
 		engineSetting = self.engine.getSettings()
 		engineSetting.setDefaultFontGlyphs(settings.FontGlyphs)
 		engineSetting.setDefaultFontPath(settings.Font)
@@ -89,7 +89,7 @@
 			engineSetting.setImageChunkingSize(settings.ImageChunkSize)
 		except:
 			pass
-	
+
 	def initLogging(self):
 		"""
 		Initialize the LogManager.
@@ -102,7 +102,7 @@
 		"""
 		This creates a default event listener, which will just close the program
 		after pressing ESC.
-		
+
 		You should override this method to provide your own event handling.
 		"""
 		return ExitEventListener(self)
@@ -116,11 +116,11 @@
 		retval = self.mainLoop()
 		self.engine.finalizePumping()
 		return retval
-	
+
 	def mainLoop(self):
 		"""
 		The programs main loop.
-		
+
 		Do not override this, instead provide your own L{_pump} method.
 		You can call this recursively, e.g. to provide synchronous
 		Dialogs :-) and break out of the current mainLoop by calling
@@ -139,23 +139,23 @@
 			if self.breakRequested:
 				self.breakRequested = False
 				break
-		
+
 		return self.returnValues.pop()
 
 	def breakFromMainLoop(self,returnValue):
 		"""
 		Break from the currently running L{mainLoop}.
-		
+
 		The passed argument will be returned by the mainLoop.
 		"""
 		self.returnValues[-1] = returnValue
 		self.breakRequested = True
 
-	
+
 	def _pump(self):
 		"""
 		Application pump.
-		
+
 		Derived classes can specialize this for unique behavior.
 		This is called every frame.
 		"""
--- a/engine/extensions/fife_utils.py	Wed Aug 06 22:35:27 2008 +0000
+++ b/engine/extensions/fife_utils.py	Thu Aug 07 15:46:46 2008 +0000
@@ -11,5 +11,3 @@
 		if m.group(1) == type('').getTypeStr():
 			ret = True
 	return ret
-
-
--- a/engine/extensions/fifelog.py	Wed Aug 06 22:35:27 2008 +0000
+++ b/engine/extensions/fifelog.py	Thu Aug 07 15:46:46 2008 +0000
@@ -6,7 +6,7 @@
 	You can set log targets individually (prompt, file). You can also adjust
 	things like visible modules through log manager.
 	'''
-	
+
 	def __init__(self, engine, promptlog=True, filelog=False):
 		'''
 		Constructs new log manager
@@ -23,7 +23,7 @@
 			if k.startswith('LM_') and k not in ('LM_CORE', 'LM_MODULE_MAX'):
 				self.mod2name[v] = self.lm.getModuleName(v)
 		self.name2mod = dict([(v.lower(), k) for k, v in self.mod2name.items()])
-	
+
 	def addVisibleModules(self, *names):
 		'''
 		Adds modules that are visible in logs. By default, all modules
@@ -41,7 +41,7 @@
 					self.lm.addVisibleModule(self.name2mod[m])
 				except KeyError:
 					print 'Tried to enable non-existing log module "%s"' % m
-	
+
 	def removeVisibleModules(self, *names):
 		'''
 		Removes modules that are visible in logs. By default, all modules
@@ -56,7 +56,7 @@
 		else:
 			for m in names:
 				self.lm.removeVisibleModule(self.name2mod[m])
-		
+
 	def getVisibleModules(self):
 		'''
 		Gets currently visible modules
@@ -75,4 +75,3 @@
 		'''
 		self.lm.clearVisibleModules()
 		self.addVisibleModules(*names)
-
--- a/engine/extensions/pychan/__init__.py	Wed Aug 06 22:35:27 2008 +0000
+++ b/engine/extensions/pychan/__init__.py	Thu Aug 07 15:46:46 2008 +0000
@@ -247,11 +247,10 @@
 	
 	@param engine: The FIFE engine object.
 	"""
-        from manager import Manager
+	from manager import Manager
 	global manager
 	manager = Manager(engine,debug)
 
-
 # XML Loader
 
 from xml.sax import saxutils, handler
@@ -327,7 +326,7 @@
 		if self.root:
 			self.root.addChild( obj )
 		self.root = obj
-	
+
 	def _createSpacer(self,cls,name,attrs):
 		obj = cls(parent=self.root)
 		if hasattr(self.root,'add'):
@@ -345,33 +344,33 @@
 def loadXML(filename_or_stream):
 	"""
 	Loads a PyChan XML file and generates a widget from it.
-	
+
 	@param filename_or_stream: A filename or a file-like object (for example using StringIO).
-	
+
 	The XML format is very dynamic, in the sense, that the actual allowed tags and attributes
 	depend on the PyChan code.
-	
+
 	So when a tag C{Button} is encountered, an instance of class Button will be generated,
 	and added to the parent object.
 	All attributes will then be parsed and then set in the following way:
-	
+
 	  - position,size,min_size,max_size,margins - These are assumed to be comma separated tuples
 	    of integers.
 	  - foreground_color,base_color,background_color - These are assumed to be triples of comma
 	    separated integers.
 	  - opaque,border_size,padding - These are assumed to be simple integers.
-	
+
 	All other attributes are set verbatim as strings on the generated instance.
 	In case a Widget does not accept an attribute to be set or the attribute can not be parsed
 	correctly, the function will raise a GuiXMLError.
-	
+
 	In short::
 		<VBox>
 			<Button text="X" min_size="20,20" base_color="255,0,0" border_size="2" />
 		</VBox>
-	
+
 	This result in the following code executed::
-	
+
 		vbox = VBox(parent=None)
 		button = Button(parent=vbox)
 		button.text = "X"
@@ -388,18 +387,18 @@
 def setupModalExecution(mainLoop,breakFromMainLoop):
 	"""
 	Setup the synchronous dialog execution feature.
-	
+
 	You can enable synchronous dialog execution by
 	passing to functions to this function.
-	
+
 	@param mainLoop: Function - This is regarded as the applications
 	main loop, which should be able to be called recursively.
 	It should not take no arguments and return the argument
 	passed to the second function (breakFromMainLoop).
-	
+
 	@param breakFromMainLoop: Function -This function should cause the
 	first function to finish and return the passed argument.
-	
+
 	With these to functions dialogs can be executed synchronously.
 	See L{widgets.Widget.execute}.
 	"""
--- a/engine/extensions/pychan/attrs.py	Wed Aug 06 22:35:27 2008 +0000
+++ b/engine/extensions/pychan/attrs.py	Thu Aug 07 15:46:46 2008 +0000
@@ -28,7 +28,7 @@
 	"""
 	def __init__(self,name):
 		self.name = name
-	
+
 	def set(self,obj,value):
 		"""
 		Parses the given value with the L{parse} method
--- a/engine/extensions/pychan/fonts.py	Wed Aug 06 22:35:27 2008 +0000
+++ b/engine/extensions/pychan/fonts.py	Thu Aug 07 15:46:46 2008 +0000
@@ -18,7 +18,7 @@
 			self.antialias = int(get("antialias",1))
 			self.color = map(int,get("color","255,255,255").split(','))
 			self.font = Manager.manager.guimanager.createFont(self.source,self.size,"")
-			
+
 			if self.font is None:
 				raise InitializationError("Could not load font %s" % name)
 
@@ -26,7 +26,7 @@
 			self.font.setColor(*self.color)
 		else:
 			raise InitializationError("Unsupported font type %s" % self.typename)
-		
+
 		self.font.setRowSpacing( self.row_spacing )
 		self.font.setGlyphSpacing( self.glyph_spacing )
 
@@ -36,12 +36,12 @@
 		Static method to load font definitions out of a PyChan config file.
 		"""
 		import ConfigParser
-		
+
 		fontdef = ConfigParser.ConfigParser()
 		fontdef.read(filename)
-		
+
 		sections = [section for section in fontdef.sections() if section.startswith("Font/")]
-	
+
 		fonts = []
 		for section in sections:
 			name = section[5:]
@@ -54,7 +54,7 @@
 
 	def __str__(self):
 		return "Font(source='%s')" % self.source
-	
+
 	def __repr__(self):
 		return "<Font(source='%s') at %x>" % (self.source,id(self))
 
@@ -63,7 +63,6 @@
 	Load fonts from a config file. These are then available via their name.
 	"""
 	from manager import Manager
-	
+
 	for font in Font.loadFromFile(filename):
 		Manager.manager.addFont(font)
-
--- a/engine/extensions/pychan/manager.py	Wed Aug 06 22:35:27 2008 +0000
+++ b/engine/extensions/pychan/manager.py	Thu Aug 07 15:46:46 2008 +0000
@@ -17,15 +17,15 @@
 			raise InitializationError("No event manager installed.")
 		if not self.engine.getGuiManager():
 			raise InitializationError("No GUI manager installed.")
-		
+
 		self.guimanager = engine.getGuiManager()
 		self.fonts = {}
 		#glyphs = ' abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,!?-+/:();%`\'*#=[]"'
 		self.fonts['default'] = self.engine.getDefaultFont()
-		
+
 		self.styles = {}
 		self.addStyle('default',DEFAULT_STYLE)
-		
+
 		self.widgetEvents = {}
 		self.engine.getEventManager().addWidgetListener(self)
                 Manager.manager = self
@@ -60,11 +60,11 @@
 	def getFont(self,name):
 		"""
 		Returns a GuiFont identified by its name.
-		
+
 		@param name: A string identifier from the font definitions in pychans config files.
 		"""
 		font = self.fonts.get(name)
-		
+
 		# For the default font directly return it,
 		# otherwise the GuiFont is in the font attribute.
 		return getattr(font,"font",font)
@@ -74,7 +74,7 @@
 		Add a font to the font registry. It's not necessary to call this directly.
 		But it expects a L{Font} instance and throws an L{InitializationError}
 		otherwise.
-		
+
 		@param font: A L{Font} instance.
 		"""
 		if not isinstance(font,fonts.Font):
@@ -83,7 +83,7 @@
 
 	def addStyle(self,name,style):
 		style = self._remapStyleKeys(style)
-		
+
 		for k,v in self.styles.get('default',{}).items():
 			style[k] = style.get(k,v)
 		self.styles[name] = style
@@ -93,7 +93,7 @@
 		for k,v in style.get('default',{}).items():
 			v = kwargs.get(k,v)
 			setattr(widget,k,v)
-		
+
 		cls = widget.__class__
 		for applicable,specstyle in style.items():
 			if not isinstance(applicable,tuple):
@@ -108,13 +108,13 @@
 		def _toClass(class_):
 			if class_ == "default":
 				return class_
-			
+
 			if type(class_) == type(widgets.Widget) and issubclass(class_,widgets.Widget):
 				return class_
 			if not widgets.WIDGETS.has_key(str(class_)):
 				raise InitializationError("Can't resolve %s to a widget class." % repr(class_))
 			return widgets.WIDGETS[str(class_)]
-		
+
 		style_copy = {}
 		for k,v in style.items():
 			if isinstance(k,tuple):
--- a/engine/extensions/pychan/tools.py	Wed Aug 06 22:35:27 2008 +0000
+++ b/engine/extensions/pychan/tools.py	Thu Aug 07 15:46:46 2008 +0000
@@ -28,12 +28,12 @@
 	"""
 	Curries a function with extra arguments to
 	create a suitable callback.
-	
+
 	If you don't know what this means, don't worry.
 	It is designed for the case where you need
 	different buttons to execute basically the same code
 	with different argumnets.
-	
+
 	Usage::
 	  # The target callback
 	  def printStuff(text):
@@ -48,7 +48,6 @@
 		callback(*args,**kwargs)
 	return real_callback
 
-
 def this_is_deprecated(func,message=None):
 	if message is None:
 		message = repr(func)
--- a/engine/extensions/pychan/widgets.py	Wed Aug 06 22:35:27 2008 +0000
+++ b/engine/extensions/pychan/widgets.py	Thu Aug 07 15:46:46 2008 +0000
@@ -30,15 +30,15 @@
 	"""
 	This is the common widget base class, which provides most of the wrapping
 	functionality.
-	
+
 	Attributes
 	==========
-	
+
 	Widgets are manipulated (mostly) through attributes - and these can all be set by XML attributes.
 	Derived widgets will have other attributes. Please see their B{New Attributes} sections. The types of the
 	attributes are pretty straightforward, but note that Position and Color attribute types will also accept
 	C{fife.Point} and C{fife.Color} values.
-	
+
 	  - name: String: The identification of the widget, most useful if it is unique within a given widget hiarachy.
 	  This is used to find widgets by L{mapEvents},L{distributeInitialData},L{distributeData} and L{collectData}.
 	  - position: Position: The position relative to the parent widget - or on screen, if this is the root widget.
@@ -59,7 +59,7 @@
 
 	Convenience Attributes
 	======================
-	
+
 	These attributes are convenience/shorthand versions of above mentioned attributes and assignment will reflect
 	the associated attributes values. E.g. the following is equivalent::
 	   # Set X position, leave Y alone
@@ -76,20 +76,20 @@
 	   - height: Integer: The vertical part of the size attribute.
 
 	"""
-	
+
 	ATTRIBUTES = [ Attr('name'), PointAttr('position'),
 		PointAttr('min_size'), PointAttr('size'), PointAttr('max_size'),
 		ColorAttr('base_color'),ColorAttr('background_color'),ColorAttr('foreground_color'),
 		Attr('style'), Attr('font'),IntAttr('border_size')
 		]
-	
+
 	DEFAULT_NAME = '__unnamed__'
-	
+
 	HIDE_SHOW_ERROR = """\
 	You can only show/hide the top widget of a hierachy.
 	Use 'addChild' or 'removeChild' to add/remove labels for example.
 	"""
-	
+
 	def __init__(self,parent = None, name = DEFAULT_NAME,
 			size = (-1,-1), min_size=(0,0), max_size=(5000,5000),
 			style = None, **kwargs):
@@ -97,53 +97,53 @@
 		assert( hasattr(self,'real_widget') )
 		self._has_listener = False
 		self._visible = False
-		
+
 		# Data distribution & retrieval settings
 		self.accepts_data = False
 		self.accepts_initial_data = False
 
 		self._parent = parent
-		
+
 		# This will also set the _event_id and call real_widget.setActionEventId
 		self.name = name
-		
+
 		self.min_size = min_size
 		self.max_size = max_size
 		self.size = size
 		self.position_technique = "explicit"
 		self.font = 'default'
-		
+
 		# Inherit style
 		if style is None and parent:
 			style = parent.style
 		self.style = style or "default"
-		
+
 		# Not needed as attrib assignment will trigger manager.stylize call
 		#manager.stylize(self,self.style)
 
 	def execute(self,bind):
 		"""
 		Execute a dialog synchronously.
-		
+
 		As argument a dictionary mapping widget names to return values
 		is expected. Events from these widgets will cause this function
 		to return with the associated return value.
-		
+
 		This function will not return until such an event occurs.
 		The widget will be shown before execution and hidden afterwards.
 		You can only execute root widgets.
-		
+
 		Note: This feature is not tested well, and the API will probably
 		change. Otherwise have fun::
 		  # Okay this a very condensed example :-)
 		  return pychan.loadXML("contents/gui/dialog.xml").execute({ 'okButton' : True, 'closeButton' : False })
-		
+
 		"""
 		if not get_manager().can_execute:
 			raise RuntimeError("Synchronous execution is not set up!")
 		if self._parent:
 			raise RuntimeError("You can only 'execute' root widgets, not %s!" % str(self))
-		
+
 		for name,returnValue in bind.items():
 			def _quitThisDialog(returnValue = returnValue ):
 				get_manager().breakFromMainLoop( returnValue )
@@ -170,7 +170,7 @@
 		The old event handler (if any) will be overridden by the callback.
 		If None is given, the event will be disabled. You can query L{isCaptured}
 		wether this widgets events are currently captured.
-		
+
 		It might be useful to check out L{tools.callbackWithArguments}.
 		
 		"""
@@ -226,7 +226,7 @@
 		get_manager().hide(self)
 		self.afterHide()
 		self._visible = False
-	
+
 	def isVisible(self):
 		"""
 		Check whether the widget is currently shown,
@@ -236,7 +236,7 @@
 		while widget._parent:
 			widget = widget._parent
 		return widget._visible
-	
+
 	def adaptLayout(self):
 		"""
 		Execute the Layout engine. Automatically called by L{show}.
@@ -245,7 +245,7 @@
 		"""
 		self._recursiveResizeToContent()
 		self._recursiveExpandContent()
-	
+
 	def beforeShow(self):
 		"""
 		This method is called just before the widget is shown.
@@ -263,7 +263,7 @@
 	def findChildren(self,**kwargs):
 		"""
 		Find all contained child widgets by attribute values.
-		
+
 		Usage::
 		  closeButtons = root_widget.findChildren(name='close')
 		"""
@@ -277,7 +277,7 @@
 
 	def findChild(self,**kwargs):
 		""" Find the first contained child widgets by attribute values.
-		
+
 		Usage::
 		  closeButton = root_widget.findChild(name='close')
 		"""
@@ -312,7 +312,7 @@
 		"""
 		Convenience function to map widget events to functions
 		in a batch.
-		
+
 		Subsequent calls of mapEvents will merge events with different
 		widget names and override the previously set callback.
 		You can also pass C{None} instead of a callback, which will
@@ -337,7 +337,7 @@
 		if not self.accepts_initial_data:
 			raise RuntimeError("Trying to set data on a widget that does not accept initial data. Widget: %s Data: %s " % (repr(self),repr(data)))
 		self._realSetInitialData(data)
-	
+
 	def setData(self,data):
 		"""
 		Set the user-mutable data on a widget, what this means depends on the Widget.
@@ -364,19 +364,19 @@
 		using the keys as names and the values as the data (which is set via L{setInitialData}).
 		If more than one widget matches - the data is set on ALL matching widgets.
 		By default a missing widget is just ignored.
-		
+
 		Use it like this::
 		  guiElement.distributeInitialData({
 		       'myTextField' : 'Hello World!',
 		       'myListBox' : ["1","2","3"]
 		  })
-		
+
 		"""
 		for name,data in initialDataMap.items():
 			widgetList = self.findChildren(name = name)
 			for widget in widgetList:
 				widget.setInitialData(data)
-	
+
 	def distributeData(self,dataMap):
 		"""
 		Distribute data from a dictionary over the widgets in the hierachy
@@ -402,18 +402,18 @@
 		This can only handle UNIQUE widget names (in the hierachy)
 		and will raise a RuntimeError if the number of matching widgets
 		is not equal to one.
-		
+
 		Usage::
 		  data = guiElement.collectDataAsDict(['myTextField','myListBox'])
 		  print "You entered:",data['myTextField']," and selected ",data['myListBox']
-		
+
 		"""
 		dataMap = {}
 		for name in widgetNames:
 			widgetList = self.findChildren(name = name)
 			if len(widgetList) != 1:
 				raise RuntimeError("CollectData can only handle widgets with unique names.")
-			
+
 			dataMap[name] = widgetList[0].getData()
 		return dataMap
 
@@ -423,20 +423,20 @@
 		This can only handle UNIQUE widget names (in the hierachy)
 		and will raise a RuntimeError if the number of matching widgets
 		is not equal to one.
-		
+
 		This function takes an arbitrary number of widget names and
 		returns a list of the collected data in the same order.
-		
+
 		In case only one argument is given, it will return just the
 		data, with out putting it into a list.
-		
+
 		Usage::
 		  # Multiple element extraction:
 		  text, selected = guiElement.collectData('myTextField','myListBox')
 		  print "You entered:",text," and selected item nr",selected
 		  # Single elements are handled gracefully, too:
 		  test = guiElement.collectData('testElement')
-		
+
 		"""
 		dataList = []
 		for name in widgetNames:
@@ -460,7 +460,6 @@
 		print "name".ljust(20),"widget".ljust(50),"parent"
 		self.deepApply(_printNamedWidget)
 
-
 	def stylize(self,style,**kwargs):
 		"""
 		Recursively apply a style to all widgets.
@@ -480,7 +479,7 @@
 		Try to expand any spacer in the widget within the current size.
 		Do not call directly.
 		"""
-		
+
 
 	def _recursiveResizeToContent(self):
 		"""
@@ -516,7 +515,7 @@
 
 	def __str__(self):
 		return "%s(name='%s')" % (self.__class__.__name__,self.name)
-	
+
 	def __repr__(self):
 		return "<%s(name='%s') at %x>" % (self.__class__.__name__,self.name,id(self))
 
@@ -573,7 +572,7 @@
 			color = fife.Color(*color)
 		self.real_widget.setBaseColor(color)
 	base_color = property(_getBaseColor,_setBaseColor)
-	
+
 	def _getBackgroundColor(self): return self.real_widget.getBackgroundColor()
 	def _setBackgroundColor(self,color):
 		if isinstance(color,type(())):
@@ -587,14 +586,14 @@
 			color = fife.Color(*color)
 		self.real_widget.setForegroundColor(color)
 	foreground_color = property(_getForegroundColor,_setForegroundColor)
-	
+
 	def _getSelectionColor(self): return self.real_widget.getSelectionColor()
 	def _setSelectionColor(self,color):
 		if isinstance(color,type(())):
 			color = fife.Color(*color)
 		self.real_widget.setSelectionColor(color)
 	selection_color = property(_getSelectionColor,_setSelectionColor)
-	
+
 	def _getName(self): return self._name
 	def _setName(self,name):
 		from pychan import manager
@@ -631,10 +630,10 @@
 	be position via the position attribute. If you want to use the layout engine,
 	you have to use derived containers with vertical or horizontal orientation
 	(L{VBox} or L{HBox})
-	
+
 	New Attributes
 	==============
-	
+
 	  - padding - Integer: Not used in the Container class istelf, distance between child widgets.
 	  - background_image - Set this to a GuiImage or a resource location (simply a filename).
 	    The image will be tiled over the background area.
@@ -642,9 +641,9 @@
 	    to make the widget transparent.
 	  - children - Just contains the list of contained child widgets. Do NOT modify.
 	"""
-	
+
 	ATTRIBUTES = Widget.ATTRIBUTES + [ IntAttr('padding'), Attr('background_image'), BoolAttr('opaque'),PointAttr('margins') ]
-	
+
 	def __init__(self,padding=5,margins=(5,5),_real_widget=None, **kwargs):
 		self.real_widget = _real_widget or fife.Container()
 		self.children = []
@@ -690,12 +689,12 @@
 		image = self._background_image
 		if image is None:
 			return
-		
+
 		back_w,back_h = self.width, self.height
 		image_w, image_h = image.getWidth(), image.getHeight()
 
 		map(self.real_widget.remove,self._background)
-		
+
 		# Now tile the background over the widget
 		self._background = []
 		icon = fife.Icon(image)
@@ -724,7 +723,7 @@
 		if not isinstance(image, fife.GuiImage):
 			image = get_manager().loadImage(image)
 		self._background_image = image
-	
+
 	def getBackgroundImage(self): return self._background_image
 	background_image = property(getBackgroundImage,setBackgroundImage)
 
@@ -739,15 +738,15 @@
 	This class is at the core of the layout engine. The two MixIn classes L{VBoxLayoutMixin}
 	and L{HBoxLayoutMixin} specialise on this by reimplementing the C{resizeToContent} and
 	the C{expandContent} methods.
-	
+
 	At the core the layout engine works in two passes:
-	
+
 	Before a root widget loaded by the XML code is shown, its resizeToContent method
 	is called recursively (walking the widget containment relation in post order).
 	This shrinks all HBoxes and VBoxes to their minimum heigt and width.
 	After that the expandContent method is called recursively in the same order,
 	which will re-align the widgets if there is space left AND if a Spacer is contained.
-	
+
 	Inside bare Container instances (without a Layout MixIn) absolute positioning
 	can be used.
 	"""
@@ -766,7 +765,6 @@
 	def ydelta(self,widget):return 0
 
 	def _adjustHeight(self):
-		
 		if self.align[1] == AlignTop:return #dy = 0
 		if self.align[1] == AlignBottom:
 			y = self.height - self.childarea[1] - self.border_size - self.margins[1]
@@ -780,7 +778,6 @@
 		pass
 
 	def _adjustWidth(self):
-
 		if self.align[0] == AlignLeft:return #dx = 0
 		if self.align[0] == AlignRight:
 			x = self.width - self.childarea[0] - self.border_size - self.margins[0]
@@ -793,11 +790,11 @@
 	def _expandWidthSpacer(self):
 		x = self.border_size + self.margins[0]
 		xdelta = map(self.xdelta,self.children)
-		
+
 		for widget in self.children[:self.spacer.index]:
 			widget.x = x
 			x += xdelta.pop(0)
-		
+
 		x = self.width - sum(xdelta) - self.border_size - self.margins[0]
 		for widget in self.children[self.spacer.index:]:
 			widget.x = x
@@ -806,11 +803,11 @@
 	def _expandHeightSpacer(self):
 		y = self.border_size + self.margins[1]
 		ydelta = map(self.ydelta,self.children)
-		
+
 		for widget in self.children[:self.spacer.index]:
 			widget.y = y
 			y += ydelta.pop(0)
-		
+
 		y = self.height - sum(ydelta) - self.border_size - self.margins[1]
 		for widget in self.children[self.spacer.index:]:
 			widget.y = y
@@ -833,7 +830,7 @@
 			widget.y = y
 			widget.width = max_w
 			y += widget.height + self.padding
-		
+
 		#Add the padding for the spacer.
 		if self.spacer:
 			y += self.padding
@@ -867,7 +864,7 @@
 			widget.y = y
 			widget.height = max_h
 			x += widget.width + self.padding
-		
+
 		#Add the padding for the spacer.
 		if self.spacer:
 			x += self.padding
@@ -875,7 +872,7 @@
 		self.width = x + self.margins[0] - self.padding
 		self.height = max_h + 2*y
 		self.childarea = x - self.margins[0] - self.padding, max_h
-		
+
 		self._adjustHeight()
 		self._adjustWidth()
 
@@ -889,11 +886,11 @@
 class VBox(VBoxLayoutMixin,Container):
 	"""
 	A vertically aligned box - for containement of child widgets.
-	
+
 	Widgets added to this container widget, will layout on top of each other.
 	Also the minimal width of the container will be the maximum of the minimal
 	widths of the contained widgets.
-	
+
 	The default alignment is to the top. This can be changed by adding a Spacer
 	to the widget at any point (but only one!). The spacer will expand, so that
 	widgets above the spacer are aligned to the top, while widgets below the spacer
@@ -907,7 +904,7 @@
 class HBox(HBoxLayoutMixin,Container):
 	"""
 	A horizontally aligned box - for containement of child widgets.
-	
+
 	Please see L{VBox} for details - just change the directions :-).
 	"""	
 	def __init__(self,padding=5,**kwargs):
@@ -917,16 +914,16 @@
 class Window(VBoxLayoutMixin,Container):
 	"""
 	A L{VBox} with a draggable title bar aka a window
-	
+
 	New Attributes
 	==============
-	
+
 	  - title: The Caption of the window
 	  - titlebar_height: The height of the window title bar
 	"""
-	
+
 	ATTRIBUTES = Container.ATTRIBUTES + [ Attr('title'), IntAttr('titlebar_height') ]
-	
+
 	def __init__(self,title="title",titlebar_height=0,**kwargs):
 		super(Window,self).__init__(_real_widget = fife.Window(), **kwargs)
 		if titlebar_height == 0:
@@ -941,7 +938,7 @@
 	def _getTitle(self): return self.real_widget.getCaption()
 	def _setTitle(self,text): self.real_widget.setCaption(text)
 	title = property(_getTitle,_setTitle)
-	
+
 	def _getTitleBarHeight(self): return self.real_widget.getTitleBarHeight()
 	def _setTitleBarHeight(self,h): self.real_widget.setTitleBarHeight(h)
 	titlebar_height = property(_getTitleBarHeight,_setTitleBarHeight)
@@ -961,25 +958,25 @@
 	"""
 	The base class for widgets which display a string - L{Label},L{ClickLabel},L{Button}, etc.
 	Do not use directly.
-	
+
 	New Attributes
 	==============
-	
+
 	  - text: The text (depends on actual widget)
-	
+
 	Data
 	====
-	
+
 	The text can be set via the L{distributeInitialData} method.
 	"""
-	
+
 	ATTRIBUTES = Widget.ATTRIBUTES + [Attr('text')]
-	
+
 	def __init__(self, text = "",**kwargs):
 		self.margins = (5,5)
 		self.text = text
 		super(BasicTextWidget,self).__init__(**kwargs)
-		
+
 		# Prepare Data collection framework
 		self.accepts_initial_data = True
 		self._realSetInitialData = self._setText
@@ -995,10 +992,10 @@
 class Icon(Widget):
 	"""
 	An image icon.
-	
+
 	New Attributes
 	==============
-	
+
 	  - image: String or GuiImage: The source location of the Image or a direct GuiImage
 	"""
 	ATTRIBUTES = Widget.ATTRIBUTES + [Attr('image')]
@@ -1034,20 +1031,20 @@
 class Label(BasicTextWidget):
 	"""
 	A basic label - displaying a string.
-	
+
 	Also allows text wrapping.
-	
+
 	New Attributes
 	==============
-	
+
 	 - wrap_text: Boolean: Enable/Disable automatic text wrapping. Disabled by default.
 	 Currently to actually see text wrapping you have to explicitly set a max_size with
 	 the desired width of the text, as the layout engine is not capable of deriving
 	 the maximum width from a parent container.
 	"""
-	
+
 	ATTRIBUTES = BasicTextWidget.ATTRIBUTES + [BoolAttr('wrap_text')]
-	
+
 	def __init__(self,wrap_text=False,**kwargs):
 		self.real_widget = fife.Label("")
 		self.wrap_text = wrap_text
@@ -1085,37 +1082,37 @@
 		self.btn = btn
 		self.entercb = None
 		self.exitcb = None
-	
+
 	def mouseEntered(self, btn):
 		if self.entercb:
 			self.entercb(self.btn)
-	
+
 	def mouseExited(self, btn):
 		if self.exitcb:
 			self.exitcb(self.btn)
-	
+
 class ImageButton(BasicTextWidget):
 	"""
 	A basic push button with three different images for the up, down and hover state.
-	
+
 	B{Work in progress.}
-	
+
 	New Attributes
 	==============
-	
+
 	  - up_image: String: The source location of the Image for the B{unpressed} state.
 	  - down_image: String: The source location of the Image for the B{pressed} state.
 	  - hover_image: String: The source location of the Image for the B{unpressed hovered} state.
 	"""
-	
+
 	ATTRIBUTES = BasicTextWidget.ATTRIBUTES + [Attr('up_image'),Attr('down_image'),PointAttr('offset'),Attr('helptext'),Attr('hover_image')]
-	
+
 	def __init__(self,up_image="",down_image="",hover_image="",offset=(0,0),**kwargs):
 		self.real_widget = fife.TwoButton()
 		super(ImageButton,self).__init__(**kwargs)
 		self.listener = ImageButtonListener(self)
 		self.real_widget.setListener(self.listener)
-		
+
 		self.up_image = up_image
 		self.down_image = down_image
 		self.hover_image = hover_image
@@ -1150,7 +1147,7 @@
 			self._hoverimage = _DummyImage()
 	def _getHoverImage(self): return self._hoverimage_source
 	hover_image = property(_getHoverImage,_setHoverImage)	
-	
+
 	def _setOffset(self, offset):
 		self.real_widget.setDownOffset(offset[0], offset[1])
 	def _getOffset(self):
@@ -1162,7 +1159,7 @@
 	def _getHelpText(self):
 		return self.real_widget.getHelpText()
 	helptext = property(_getHelpText,_setHelpText)
-	
+
 	def resizeToContent(self):
 		self.height = max(self._upimage.getHeight(),self._downimage.getHeight(),self._hoverimage.getHeight()) + self.margins[1]*2
 		self.width = max(self._upimage.getWidth(),self._downimage.getWidth(),self._hoverimage.getWidth()) + self.margins[1]*2
@@ -1173,32 +1170,32 @@
 		callback should have form of function(button)
 		'''
 		self.listener.entercb = cb
-	
+
 	def setExitCallback(self, cb):
 		'''
 		Callback is called when mouse enters the area of ImageButton
 		callback should have form of function(button)
 		'''
 		self.listener.exitcb = cb
-	
+
 
 
 class CheckBox(BasicTextWidget):
 	"""
 	A basic checkbox.
-	
+
 	New Attributes
 	==============
-	
+
 	  - marked: Boolean value, whether the checkbox is checked or not.
-	
+
 	Data
 	====
 	The marked status can be read and set via L{distributeData} and L{collectData}
 	"""
-	
+
 	ATTRIBUTES = BasicTextWidget.ATTRIBUTES + [BoolAttr('marked')]
-	
+
 	def __init__(self,**kwargs):
 		self.real_widget = fife.CheckBox()
 		super(CheckBox,self).__init__(**kwargs)
@@ -1207,9 +1204,9 @@
 		self.accepts_data = True
 		self._realGetData = self._isMarked
 		self._realSetData = self._setMarked
-		
+
 		# Initial data stuff inherited.
-	
+
 	def _isMarked(self): return self.real_widget.isSelected()
 	def _setMarked(self,mark): self.real_widget.setSelected(mark)
 	marked = property(_isMarked,_setMarked)
@@ -1217,21 +1214,21 @@
 class RadioButton(BasicTextWidget):
 	"""
 	A basic radiobutton (an exclusive checkbox).
-	
+
 	New Attributes
 	==============
-	
+
 	  - marked: Boolean: Whether the checkbox is checked or not.
 	  - group: String: All RadioButtons with the same group name
 	  can only be checked exclusively.
-	
+
 	Data
 	====
 	The marked status can be read and set via L{distributeData} and L{collectData}
 	"""
-	
+
 	ATTRIBUTES = BasicTextWidget.ATTRIBUTES + [BoolAttr('marked'),Attr('group')]
-	
+
 	def __init__(self,group="_no_group_",**kwargs):
 		self.real_widget = fife.RadioButton()
 		super(RadioButton,self).__init__(**kwargs)
@@ -1242,9 +1239,9 @@
 		self.accepts_data = True
 		self._realGetData = self._isMarked
 		self._realSetData = self._setMarked
-		
+
 		# Initial data stuff inherited.
-	
+
 	def _isMarked(self): return self.real_widget.isSelected()
 	def _setMarked(self,mark): self.real_widget.setSelected(mark)
 	marked = property(_isMarked,_setMarked)
@@ -1270,7 +1267,7 @@
 			self.pop()
 	def getNumberOfElements(self):
 		return len(self)
-		
+
 	def getElementAt(self, i):
 		i = max(0,min(i,len(self) - 1))
 		return str(self[i])
@@ -1279,16 +1276,16 @@
 	"""
 	A basic list box widget for displaying lists of strings. It makes most sense to wrap
 	this into a L{ScrollArea}.
-	
+
 	New Attributes
 	==============
-	
+
 	  - items: A List of strings. This can be treated like an ordinary python list.
 	    but only strings are allowed.
 	  - selected: The index of the selected item in the list. Starting from C{0} to C{len(items)-1}.
 	    A negative value indicates, that no item is selected.
 	  - selected_item: The selected string itself, or C{None} - if no string is selected.
-	
+
 	Data
 	====
 	The selected attribute can be read and set via L{distributeData} and L{collectData}.
@@ -1302,7 +1299,7 @@
 		# Prepare Data collection framework
 		self.accepts_initial_data = True
 		self._realSetInitialData = self._setItems
-		
+
 		self.accepts_data = True
 		self._realSetData = self._setSelected
 		self._realGetData = self._getSelected
@@ -1319,7 +1316,7 @@
 	def _setItems(self,items):
 		# Note we cannot use real_widget.setListModel
 		# for some reason ???
-		
+
 		# Also self assignment can kill you
 		if id(items) != id(self._items):
 			self._items.clear()
@@ -1339,16 +1336,16 @@
 class DropDown(Widget):
 	"""
 	A dropdown or combo box widget for selecting lists of strings.
-	
+
 	New Attributes
 	==============
-	
+
 	  - items: A List of strings. This can be treated like an ordinary python list.
 	    but only strings are allowed.
 	  - selected: The index of the selected item in the list. Starting from C{0} to C{len(items)-1}.
 	    A negative value indicates, that no item is selected.
 	  - selected_item: The selected string itself, or C{None} - if no string is selected.
-	
+
 	Data
 	====
 	The selected attribute can be read and set via L{distributeData} and L{collectData}.
@@ -1362,7 +1359,7 @@
 		# Prepare Data collection framework
 		self.accepts_initial_data = True
 		self._realSetInitialData = self._setItems
-		
+
 		self.accepts_data = True
 		self._realSetData = self._setSelected
 		self._realGetData = self._getSelected
@@ -1379,13 +1376,13 @@
 	def _setItems(self,items):
 		# Note we cannot use real_widget.setListModel
 		# for some reason ???
-		
+
 		# Also self assignment can kill you
 		if id(items) != id(self._items):
 			self._items.clear()
 			self._items.extend(items)
 	items = property(_getItems,_setItems)
-	
+
 	def _getSelected(self): return self.real_widget.getSelected()
 	def _setSelected(self,index): self.real_widget.setSelected(index)
 	selected = property(_getSelected,_setSelected)
@@ -1398,13 +1395,13 @@
 class TextBox(Widget):
 	"""
 	An editable B{multiline} text edit widget.
-	
+
 	New Attributes
 	==============
-	
+
 	  - text: The text in the TextBox.
 	  - filename: A write-only attribute - assigning a filename will cause the widget to load it's text from it.
-	
+
 	Data
 	====
 	The text can be read and set via L{distributeData} and L{collectData}.
@@ -1452,12 +1449,12 @@
 class TextField(Widget):
 	"""
 	An editable B{single line} text edit widget.
-	
+
 	New Attributes
 	==============
-	
+
 	  - text: The text in the TextBox.
-	
+
 	Data
 	====
 	The text can be read and set via L{distributeData} and L{collectData}.
@@ -1495,18 +1492,18 @@
 class ScrollArea(Widget):
 	"""
 	A wrapper around another (content) widget.
-	
+
 	New Attributes
 	==============
-	
+
 	  - content: The wrapped widget.
 	  - vertical_scrollbar: Boolean: Set this to False to hide the Vertcial scrollbar
 	  - horizontal_scrollbar: Boolean: Set this to False to hide the Horizontal scrollbar
-	
+
 	"""
-	
+
 	ATTRIBUTES = Widget.ATTRIBUTES + [ BoolAttr("vertical_scrollbar"),BoolAttr("horizontal_scrollbar") ]
-	
+
 	def __init__(self,**kwargs):
 		self.real_widget = fife.ScrollArea()
 		self._content = None
@@ -1541,7 +1538,7 @@
 		if visibility: 
 			return fife.ScrollArea.SHOW_AUTO
 		return fife.ScrollArea.SHOW_NEVER
-	
+
 	def _scrollPolicyToVisibility(self,policy):
 		if policy == fife.ScrollArea.SHOW_NEVER:
 			return False
@@ -1549,13 +1546,13 @@
 
 	def _setHorizontalScrollbar(self,visibility):
 		self.real_widget.setHorizontalScrollPolicy( self._visibilityToScrollPolicy(visibility) )
-	
+
 	def _setVerticalScrollbar(self,visibility):
 		self.real_widget.setVerticalScrollPolicy( self._visibilityToScrollPolicy(visibility) )
 
 	def _getHorizontalScrollbar(self):
 		return self._scrollPolicyToVisibility( self.real_widget.getHorizontalScrollPolicy() )
-	
+
 	def _getVerticalScrollbar(self):
 		return self._scrollPolicyToVisibility( self.real_widget.getVerticalScrollPolicy() )
 
@@ -1566,13 +1563,13 @@
 
 class Spacer(object):
 	""" A spacer represents expandable 'whitespace' in the GUI.
-	
+
 	In a XML file you can get this by adding a <Spacer /> inside a VBox or
 	HBox element (Windows implicitly are VBox elements).
-	
+
 	The effect is, that elements before the spacer will be left (top)
 	and elements after the spacer will be right (bottom) aligned.
-	
+
 	There can only be one spacer in VBox (HBox).
 	"""
 	def __init__(self,parent=None,**kwargs):
@@ -1580,7 +1577,7 @@
 
 	def __str__(self):
 		return "Spacer(parent.name='%s')" % getattr(self._parent,'name','None')
-	
+
 	def __repr__(self):
 		return "<Spacer(parent.name='%s') at %x>" % (getattr(self._parent,'name','None'),id(self))
 
@@ -1594,18 +1591,18 @@
 	"VBox" : VBox,
 	"HBox" : HBox,
 	"ScrollArea" :ScrollArea,
-	
+
 	# Simple Widgets
 	"Icon" : Icon,
 	"Label" : Label,
 	"ClickLabel" : ClickLabel,
-	
+
 	# Button Widgets
 	"Button" : Button,
 	"CheckBox" : CheckBox,
 	"RadioButton" : RadioButton,
 	"ImageButton" : ImageButton,
-	
+
 	#Complexer Widgets / Text io
 	"TextField" : TextField,
 	"TextBox" : TextBox,
--- a/engine/extensions/pythonize.py	Wed Aug 06 22:35:27 2008 +0000
+++ b/engine/extensions/pythonize.py	Thu Aug 07 15:46:46 2008 +0000
@@ -51,7 +51,7 @@
 		except TypeError, e:
 			#print func, e
 			return False
-	
+
 	def createNames(name):
 		for prefix in ('get', 'is', 'are'):
 			if name.startswith(prefix):
@@ -60,7 +60,7 @@
 		settername   = 'set' + new_name
 		propertyname = new_name[0].lower() + new_name[1:]
 		return settername, propertyname
-		
+
 	getter = re.compile(r"^(get|are|is)[A-Z]")
 	for class_ in classes:
 		methods = [(name,attr) for name,attr in class_.__dict__.items()
@@ -75,7 +75,7 @@
 				#print name, settername, "--->",propertyname,'(',method,',',setter,')'
 				setattr(class_,propertyname,property(method,setter))
 		if not getters: continue
-		
+
 		# We need to override the swig setattr function
 		# to get properties to work.
 		class_._property_names = set([name for name,method in getters])
--- a/engine/extensions/savers.py	Wed Aug 06 22:35:27 2008 +0000
+++ b/engine/extensions/savers.py	Thu Aug 07 15:46:46 2008 +0000
@@ -72,7 +72,7 @@
 	def write_imports(self, map, importList):
 		for importdir in importList:
 			self.write_importdir(root_subfile(map.getResourceFile(), importdir))
-		
+
 		imports = []
 		for layer in map.getLayers():
 			for instance in layer.getInstances():
@@ -117,14 +117,14 @@
 		self.xmlout.startElementNS((None, 'import'), 'import', attrs)
 		self.xmlout.endElementNS((None, 'import'), 'import')
 		self.file.write('\n')
-	
+
 	def pathing_val_to_str(self, val):
 		if val == fife.CELL_EDGES_AND_DIAGONALS:
 			return "cell_edges_and_diagonals"
 		if val == fife.FREEFORM:
 			return "freeform"
 		return "cell_edges_only"
-	
+
 	def write_layers(self, map):
 		for layer in map.getLayers():
 			cellgrid = layer.getCellGrid()
@@ -189,7 +189,7 @@
 			self.xmlout.startElementNS((None, 'i'), 'i', attrs)
 			self.xmlout.endElementNS((None, 'i'), 'i')
 			self.file.write('\n')
-	
+
 		self.endElement('instances')
 
 	# Save the linked camera of a map.
--- a/engine/extensions/serializers/__init__.py	Wed Aug 06 22:35:27 2008 +0000
+++ b/engine/extensions/serializers/__init__.py	Thu Aug 07 15:46:46 2008 +0000
@@ -34,16 +34,16 @@
 	NOTE: masterfile is expected to be *file*, not directory. subfile can be either
 	'''
 	s = '/'
-	
+
 	masterfile = norm_path(os.path.abspath(masterfile))
 	subfile = norm_path(os.path.abspath(subfile))
-	
+
 	master_fragments = masterfile.split(s)
 	sub_fragments = subfile.split(s)
-	
+
 	master_leftovers = []
 	sub_leftovers = []
-	
+
 	for i in xrange(len(master_fragments)):
 		try:
 			if master_fragments[i] == sub_fragments[i]:
@@ -51,7 +51,7 @@
 				sub_leftovers = sub_fragments[i+1:]
 		except IndexError:
 			break
-	
+
 	pathstr = ''
 	for f in master_leftovers[:-1]:
 		pathstr += '..' + s
@@ -67,12 +67,12 @@
 	NOTE: masterfile is expected to be *file*, not directory. subfile can be either
 	'''
 	s = '/'
-	
+
 	masterfile = norm_path(os.path.abspath(masterfile)).split(s)[:-1]
 	subfile = norm_path(os.path.abspath( s.join(masterfile) + s + subfile ))
 	masterfile = norm_path(os.getcwd()) + s + 'foo.bar' # cheat a little to satisfy root_subfile
 	return root_subfile(masterfile, subfile)
-	
+
 def norm_path(path):
 	'''
 	Makes the path use '/' delimited separators. FIFE always uses these delimiters, but some os-related
@@ -80,5 +80,5 @@
 	'''
 	if os.path.sep == '/':
 		return path
-	
+
 	return '/'.join(path.split(os.path.sep))	
--- a/engine/extensions/serializers/xmlanimation.py	Wed Aug 06 22:35:27 2008 +0000
+++ b/engine/extensions/serializers/xmlanimation.py	Thu Aug 07 15:46:46 2008 +0000
@@ -9,7 +9,7 @@
 		self.thisown = 0
 		self.filename = ''
 		self.node = None
-	
+
 	def loadResource(self, location):
 		self.filename = location.getFilename()
 		return self.do_load_resource()
@@ -19,17 +19,17 @@
 		f.thisown = 1
 		tree = ET.parse(f)
 		self.node = tree.getroot()
-		
+
 		animation = fife.Animation()
 		common_frame_delay = int(self.node.get('delay', 0))
 		x_offset = int(self.node.get('x_offset', 0))
 		y_offset = int(self.node.get('y_offset', 0))
 		animation.setActionFrame(int(self.node.get('action', 0)))
-		
+
 		frames = self.node.findall('frame')
 		if not frames:
 			raise InvalidFormat('animation without <frame>s')
-		
+
 		for frame in frames:
 			source = frame.get('source')
 			if not source:
--- a/engine/extensions/serializers/xmlmap.py	Wed Aug 06 22:35:27 2008 +0000
+++ b/engine/extensions/serializers/xmlmap.py	Thu Aug 07 15:46:46 2008 +0000
@@ -44,7 +44,7 @@
 
 		if not format == FORMAT: self._err(''.join(['This file has format ', format, ' but this loader has format ', FORMAT]))
 		if not id: self._err('Map declared without an identifier.')
-		
+
 		map = None
 		try:
 			self.map = self.model.createMap(str(id))
@@ -120,7 +120,7 @@
 				print e.getMessage()
 				print 'The layer ' + str(id) + ' already exists! Ignoring this layer.'
 				continue
-		
+
 			strgy = fife.CELL_EDGES_ONLY
 			if pathing == "cell_edges_and_diagonals":
 				strgy = fife.CELL_EDGES_AND_DIAGONALS
@@ -129,7 +129,7 @@
 			layer_obj.setPathingStrategy(strgy)
 
 			self.parse_instances(layer, layer_obj)
-		
+
 	def parse_instances(self, layerelt, layer):
 		instelt = layerelt.find('instances')
 
@@ -179,19 +179,19 @@
 				self.y = y
 			else:
 				y = self.y
-		
+
 			if z:
 				z = float(z)
 			else:
 				z = 0.0
-		
+
 			if not id:
 				id = ''
 			else:
 				id = str(id)
 
 			inst = layer.createInstance(object, fife.ExactModelCoordinate(x,y,z), str(id))
-			
+
 			rotation = instance.get('r')
 			if not rotation:
 				rotation = instance.get('rotation')
@@ -204,7 +204,7 @@
 			else:
 				rotation = int(rotation)
 			inst.setRotation(rotation)
-			
+
 			fife.InstanceVisual.create(inst)
 			if (stackpos):
 				inst.get2dGfxVisual().setStackPosition(int(stackpos))
--- a/engine/extensions/serializers/xmlobject.py	Wed Aug 06 22:35:27 2008 +0000
+++ b/engine/extensions/serializers/xmlobject.py	Thu Aug 07 15:46:46 2008 +0000
@@ -28,16 +28,16 @@
 			isobjectfile = True
 			f = self.vfs.open(self.filename)
 			f.thisown = 1
-			
+
 			obj_identifier = '<?fife type="object"?>'
 			try:
 				s = f.readString(len(obj_identifier))
 			except fife.IndexOverflow:
 				isobjectfile = False
-			
+
 			if isobjectfile and s != obj_identifier:
 				isobjectfile = False
-			
+
 			if not isobjectfile:
 				raise WrongFileType('Tried to open non-object file %s with XMLObjectLoader.' % self.filename)
 		self.do_load_resource(f)
@@ -51,7 +51,7 @@
 	def parse_object(self, object):
 		if self.node.tag != 'object':
 			raise InvalidFormat('Expected <object> tag, but found <%s>.' % self.node.tag)
-		
+
 		id = object.get('id')
 		if not id:
 			raise InvalidFormat('<object> declared without an id attribute.')
@@ -59,7 +59,7 @@
 		nspace = object.get('namespace')
 		if not nspace:
 			raise InvalidFormat('<object> %s declared without a namespace attribute.' % str(id))
-		
+
 		obj = None
 		parent = object.get('parent', None)
 		if parent:
@@ -81,7 +81,7 @@
 		fife.ObjectVisual.create(obj)
 		obj.setBlocking(bool( object.get('blocking', False) ))
 		obj.setStatic(bool( object.get('static', False) ))
-		
+
 		pather = object.get('pather', 'RoutePather')
 		obj.setPather( self.model.getPather(pather) )
 
@@ -110,7 +110,7 @@
 			id = action.get('id')
 			if not id:
 				raise InvalidFormat('<action> declared without an id attribute.')
-	
+
 			act_obj = object.createAction(str(id))
 			fife.ActionVisual.create(act_obj)
 			self.parse_animations(action, act_obj)
@@ -130,4 +130,3 @@
 			animation = self.anim_pool.getAnimation(anim_id)
 			action.get2dGfxVisual().addAnimation(int( anim.get('direction', 0) ), anim_id)
 			action.setDuration(animation.getDuration())
-