comparison plugins/bcg/tokens.py @ 105:2f2bebe9c77f alpha

Traipse Alpha 'OpenRPG' {091006-03} Traipse is a distribution of OpenRPG that is designed to be easy to setup and go. Traipse also makes it easy for developers to work on code without fear of sacrifice. 'Ornery-Orc' continues the trend of 'Grumpy' and adds fixes to the code. 'Ornery-Orc's main goal is to offer more advanced features and enhance the productivity of the user. Update Summary: 00: Adds Bookmarks (Alpha) with cool Smiley Star and Plus Symbol images! 01: Forgot the default_server_bookmarks.xml; added. 02: Bookmarks working with no errors now! Sweet! 03: Changes made to the map for increased portability. SnowDog has changes planned in Core, though. Added an initial push to the BCG. Not much to see, just shows off how it is re-writing Main code.
author sirebral
date Tue, 06 Oct 2009 22:16:34 -0500
parents
children
comparison
equal deleted inserted replaced
104:15e32ec131cb 105:2f2bebe9c77f
1 # Copyright (C) 2000-2001 The OpenRPG Project
2 #
3 # openrpg-dev@lists.sourceforge.net
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 # --
19 #
20 # File: mapper/tokens.py
21 # Author: Chris Davis
22 # Maintainer:
23 # Version:
24 # $Id: tokens.py,v 1.46 2007/12/07 20:39:50 digitalxero Exp $
25 #
26 # Description: This file contains some of the basic definitions for the chat
27 # utilities in the orpg project.
28 #
29 __version__ = "$Id: tokens.py,v 1.46 2007/12/07 20:39:50 digitalxero Exp $"
30
31 from orpg.mapper.base import *
32 import thread
33 import time
34 import urllib
35 import os.path
36
37 from orpg.tools.orpg_settings import settings
38
39 MIN_STICKY_BACK = -0XFFFFFF
40 MIN_STICKY_FRONT = 0xFFFFFF
41
42 ##----------------------------------------
43 ## token object
44 ##----------------------------------------
45
46 FACE_NONE = 0
47 FACE_NORTH = 1
48 FACE_NORTHEAST = 2
49 FACE_EAST = 3
50 FACE_SOUTHEAST = 4
51 FACE_SOUTH = 5
52 FACE_SOUTHWEST = 6
53 FACE_WEST = 7
54 FACE_NORTHWEST = 8
55 SNAPTO_ALIGN_CENTER = 0
56 SNAPTO_ALIGN_TL = 1
57
58 def cmp_zorder(first,second):
59 f = first.zorder
60 s = second.zorder
61 if f == None: f = 0
62 if s == None: s = 0
63 if f == s: value = 0
64 elif f < s: value = -1
65 else: value = 1
66 return value
67
68 class BmpToken:
69 def __init__(self, id,path, bmp, pos=cmpPoint(0,0),
70 heading=FACE_NONE, rotate=0, label="",
71 locked=False, hide=False, snap_to_align=SNAPTO_ALIGN_CENTER,
72 zorder=0, width=0, height=0, log=None, local=False, localPath='', localTime=-1):
73 self.heading = heading
74 self.rotate = rotate
75 self.label = label
76 self.path = path
77 self.bmp = bmp
78 self.pos = pos
79 self.selected = False
80 self.locked = locked
81 self.snap_to_align = snap_to_align
82 self.hide = hide
83 self.id = id
84 self.zorder = zorder
85 self.left = 0
86 self.local = local
87 self.localPath = localPath
88 self.localTime = localTime
89 if not width: self.width = 0
90 else: self.width = width
91 if not height: self.height = 0
92 else: self.height = height
93 self.right = bmp.GetWidth()
94 self.top = 0
95 self.bottom = bmp.GetHeight()
96 self.isUpdated = False
97 self.gray = False
98 self.drawn = {}
99
100 def __del__(self):
101 del self.bmp
102 self.bmp = None
103
104 def set_bmp(self, bmp):
105 self.bmp = bmp
106
107 def set_min_props(self, heading=FACE_NONE, rotate=0, label="", locked=False, hide=False, width=0, height=0):
108 self.heading = heading
109 self.rotate = rotate
110 self.label = label
111 if locked: self.locked = True
112 else: self.locked = False
113 if hide: self.hide = True
114 else: self.hide = False
115 self.width = int(width)
116 self.height = int(height)
117 self.isUpdated = True
118
119 def hit_test(self, pt):
120 rect = self.get_rect()
121 result = None
122 result = rect.InsideXY(pt.x, pt.y)
123 return result
124
125 def get_rect(self):
126 ret = wx.Rect(self.pos.x, self.pos.y, self.bmp.GetWidth(), self.bmp.GetHeight())
127 return ret
128
129 def draw(self, dc, mini_layer, op=wx.COPY):
130 if isinstance(self.bmp, tuple):
131 self.bmp = wx.ImageFromMime(self.bmp[1], self.bmp[2]).ConvertToBitmap()
132 if self.bmp != None and self.bmp.Ok():
133 # check if hidden and GM: we outline the mini in grey (little bit smaller than the actual size)
134 # and write the label in the center of the mini
135 if self.hide and mini_layer.canvas.frame.session.my_role() == mini_layer.canvas.frame.session.ROLE_GM:
136 # set the width and height of the image
137 if self.width and self.height:
138 tmp_image = self.bmp.ConvertToImage()
139 tmp_image.Rescale(int(self.width), int(self.height))
140 tmp_image.ConvertAlphaToMask()
141 self.bmp = tmp_image.ConvertToBitmap()
142 mask = wx.Mask(self.bmp, wx.Colour(tmp_image.GetMaskRed(),
143 tmp_image.GetMaskGreen(), tmp_image.GetMaskBlue()))
144 self.bmp.SetMask(mask)
145 del tmp_image
146 del mask
147 self.left = 0
148 self.right = self.bmp.GetWidth()
149 self.top = 0
150 self.bottom = self.bmp.GetHeight()
151 # grey outline
152 graypen = wx.Pen("gray", 1, wx.DOT)
153 dc.SetPen(graypen)
154 dc.SetBrush(wx.TRANSPARENT_BRUSH)
155 #if width or height < 20 then offset = 1
156 if self.bmp.GetWidth() <= 20: xoffset = 1
157 else: xoffset = 5
158 if self.bmp.GetHeight() <= 20: yoffset = 1
159 else: yoffset = 5
160 dc.DrawRectangle(self.pos.x + xoffset,
161 self.pos.y + yoffset, self.bmp.GetWidth() - (xoffset * 2),
162 self.bmp.GetHeight() - (yoffset * 2))
163 dc.SetBrush(wx.NullBrush)
164 dc.SetPen(wx.NullPen)
165 ## draw label in the center of the mini
166 label = mini_layer.get_mini_label(self)
167 if len(label):
168 dc.SetTextForeground(wx.RED)
169 (textWidth,textHeight) = dc.GetTextExtent(label)
170 x = self.pos.x +((self.bmp.GetWidth() - textWidth) /2) - 1
171 y = self.pos.y + (self.bmp.GetHeight() / 2)
172 dc.SetPen(wx.GREY_PEN)
173 dc.SetBrush(wx.LIGHT_GREY_BRUSH)
174 dc.DrawRectangle(x, y, textWidth+2, textHeight+2)
175 if (textWidth+2 > self.right):
176 self.right += int((textWidth+2-self.right)/2)+1
177 self.left -= int((textWidth+2-self.right)/2)+1
178 self.bottom = y+textHeight+2-self.pos.y
179 dc.SetPen(wx.NullPen)
180 dc.SetBrush(wx.NullBrush)
181 dc.DrawText(label, x+1, y+1)
182
183 #selected outline
184 if self.selected:
185 dc.SetPen(wx.RED_PEN)
186 dc.SetBrush(wx.TRANSPARENT_BRUSH)
187 dc.DrawRectangle(self.pos.x, self.pos.y, self.bmp.GetWidth(), self.bmp.GetHeight())
188 dc.SetBrush(wx.NullBrush)
189 dc.SetPen(wx.NullPen)
190 return True
191 elif self.hide: return True
192
193 else:
194 # set the width and height of the image
195 bmp = self.bmp
196 if self.width and self.height:
197 tmp_image = self.bmp.ConvertToImage()
198 tmp_image.Rescale(int(self.width), int(self.height))
199 tmp_image.ConvertAlphaToMask()
200 self.bmp = tmp_image.ConvertToBitmap()
201 mask = wx.Mask(self.bmp, wx.Colour(tmp_image.GetMaskRed(),
202 tmp_image.GetMaskGreen(), tmp_image.GetMaskBlue()))
203 self.bmp.SetMask(mask)
204 if self.gray:
205 tmp_image = tmp_image.ConvertToGreyscale()
206 bmp = tmp_image.ConvertToBitmap()
207 else: bmp = self.bmp
208
209 if self.rotate != 0:
210 x = bmp.GetWidth(); print x
211 y = bmp.GetHeight(); print y
212 img = bmp.ConvertToImage()
213 img = img.Rotate(self.rotate, (3, 80), True)
214 img.ConvertAlphaToMask()
215
216 bmp = img.ConvertToBitmap()
217 mask = wx.Mask(bmp, wx.Colour(img.GetMaskRed(),
218 img.GetMaskGreen(), img.GetMaskBlue()))
219 bmp.SetMask(mask)
220
221 dc.DrawBitmap(bmp, self.pos.x, self.pos.y, True)
222 component.get('drawn')[bmp] = True
223 self.left = 0
224 self.right = self.bmp.GetWidth()
225 self.top = 0
226 self.bottom = self.bmp.GetHeight()
227
228 # Draw the heading if needed
229 if self.heading:
230 x_adjust = 0
231 y_adjust = 4
232 x_half = self.bmp.GetWidth()/2
233 y_half = self.bmp.GetHeight()/2
234 x_quarter = self.bmp.GetWidth()/4
235 y_quarter = self.bmp.GetHeight()/4
236 x_3quarter = x_quarter*3
237 y_3quarter = y_quarter*3
238 x_full = self.bmp.GetWidth()
239 y_full = self.bmp.GetHeight()
240 x_center = self.pos.x + x_half
241 y_center = self.pos.y + y_half
242 # Remember, the pen/brush must be a different color than the
243 # facing marker!!!! We'll use black/cyan for starters.
244 # Also notice that we will draw the heading on top of the
245 # larger facing marker.
246 dc.SetPen(wx.BLACK_PEN)
247 dc.SetBrush(wx.CYAN_BRUSH)
248 triangle = []
249
250 # Figure out which direction to draw the marker!!
251 if self.heading == FACE_NORTH:
252 triangle.append(cmpPoint(x_center - x_quarter, y_center - y_half ))
253 triangle.append(cmpPoint(x_center, y_center - y_3quarter ))
254 triangle.append(cmpPoint(x_center + x_quarter, y_center - y_half ))
255 elif self.heading == FACE_SOUTH:
256 triangle.append(cmpPoint(x_center - x_quarter, y_center + y_half ))
257 triangle.append(cmpPoint(x_center, y_center + y_3quarter ))
258 triangle.append(cmpPoint(x_center + x_quarter, y_center + y_half ))
259 elif self.heading == FACE_NORTHEAST:
260 triangle.append(cmpPoint(x_center + x_quarter, y_center - y_half ))
261 triangle.append(cmpPoint(x_center + x_3quarter, y_center - y_3quarter ))
262 triangle.append(cmpPoint(x_center + x_half, y_center - y_quarter ))
263 elif self.heading == FACE_EAST:
264 triangle.append(cmpPoint(x_center + x_half, y_center - y_quarter ))
265 triangle.append(cmpPoint(x_center + x_3quarter, y_center ))
266 triangle.append(cmpPoint(x_center + x_half, y_center + y_quarter ))
267 elif self.heading == FACE_SOUTHEAST:
268 triangle.append(cmpPoint(x_center + x_half, y_center + y_quarter ))
269 triangle.append(cmpPoint(x_center + x_3quarter, y_center + y_3quarter ))
270 triangle.append(cmpPoint(x_center + x_quarter, y_center + y_half ))
271 elif self.heading == FACE_SOUTHWEST:
272 triangle.append(cmpPoint(x_center - x_quarter, y_center + y_half ))
273 triangle.append(cmpPoint(x_center - x_3quarter, y_center + y_3quarter ))
274 triangle.append(cmpPoint(x_center - x_half, y_center + y_quarter ))
275 elif self.heading == FACE_WEST:
276 triangle.append(cmpPoint(x_center - x_half, y_center + y_quarter ))
277 triangle.append(cmpPoint(x_center - x_3quarter, y_center ))
278 triangle.append(cmpPoint(x_center - x_half, y_center - y_quarter ))
279 elif self.heading == FACE_NORTHWEST:
280 triangle.append(cmpPoint(x_center - x_half, y_center - y_quarter ))
281 triangle.append(cmpPoint(x_center - x_3quarter, y_center - y_3quarter ))
282 triangle.append(cmpPoint(x_center - x_quarter, y_center - y_half ))
283 dc.DrawPolygon(triangle)
284 dc.SetBrush(wx.NullBrush)
285 dc.SetPen(wx.NullPen)
286 #selected outline
287 if self.selected:
288 dc.SetPen(wx.RED_PEN)
289 dc.SetBrush(wx.TRANSPARENT_BRUSH)
290 dc.DrawRectangle(self.pos.x, self.pos.y, self.bmp.GetWidth(), self.bmp.GetHeight())
291 dc.SetBrush(wx.NullBrush)
292 dc.SetPen(wx.NullPen)
293 # draw label
294 label = mini_layer.get_mini_label(self)
295 if len(label):
296 dc.SetTextForeground(wx.RED)
297 (textWidth,textHeight) = dc.GetTextExtent(label)
298 x = self.pos.x +((self.bmp.GetWidth() - textWidth) /2) - 1
299 y = self.pos.y + self.bmp.GetHeight() + 6
300 dc.SetPen(wx.WHITE_PEN)
301 dc.SetBrush(wx.WHITE_BRUSH)
302 dc.DrawRectangle(x,y,textWidth+2,textHeight+2)
303 if (textWidth+2 > self.right):
304 self.right += int((textWidth+2-self.right)/2)+1
305 self.left -= int((textWidth+2-self.right)/2)+1
306 self.bottom = y+textHeight+2-self.pos.y
307 dc.SetPen(wx.NullPen)
308 dc.SetBrush(wx.NullBrush)
309 dc.DrawText(label,x+1,y+1)
310 self.top-=5
311 self.bottom+=5
312 self.left-=5
313 self.right+=5
314 return True
315 else: return False
316
317 def toxml(self, action="update"):
318 if action == "del":
319 xml_str = "<token action='del' id='" + self.id + "'/>"
320 return xml_str
321 xml_str = "<token"
322 xml_str += " action='" + action + "'"
323 xml_str += " label='" + self.label + "'"
324 xml_str+= " id='" + self.id + "'"
325 if self.pos != None:
326 xml_str += " posx='" + str(self.pos.x) + "'"
327 xml_str += " posy='" + str(self.pos.y) + "'"
328 if self.heading != None: xml_str += " heading='" + str(self.heading) + "'"
329 if self.rotate != None: xml_str += " rotate='" + str(self.rotate) + "'"
330 if self.path != None: xml_str += " path='" + urllib.quote(self.path).replace('%3A', ':') + "'"
331 if self.locked: xml_str += " locked='1'"
332 else: xml_str += " locked='0'"
333 if self.hide: xml_str += " hide='1'"
334 else: xml_str += " hide='0'"
335 if self.snap_to_align != None: xml_str += " align='" + str(self.snap_to_align) + "'"
336 if self.id != None: xml_str += " zorder='" + str(self.zorder) + "'"
337 if self.width != None: xml_str += " width='" + str(self.width) + "'"
338 if self.height != None: xml_str += " height='" + str(self.height) + "'"
339 if self.local:
340 xml_str += ' local="' + str(self.local) + '"'
341 xml_str += ' localPath="' + str(urllib.quote(self.localPath).replace('%3A', ':')) + '"'
342 xml_str += ' localTime="' + str(self.localTime) + '"'
343 xml_str += " />"
344 if (action == "update" and self.isUpdated) or action == "new":
345 self.isUpdated = False
346 return xml_str
347 else: return ''
348
349 def takedom(self, xml_dom):
350 self.id = xml_dom.getAttribute("id")
351 if xml_dom.hasAttribute("posx"):
352 self.pos.x = int(xml_dom.getAttribute("posx"))
353 if xml_dom.hasAttribute("posy"):
354 self.pos.y = int(xml_dom.getAttribute("posy"))
355 if xml_dom.hasAttribute("heading"):
356 self.heading = int(xml_dom.getAttribute("heading"))
357 if xml_dom.hasAttribute("rotate"):
358 self.rotate = int(xml_dom.getAttribute("rotate"))
359 if xml_dom.hasAttribute("path"):
360 self.path = urllib.unquote(xml_dom.getAttribute("path"))
361 self.set_bmp(ImageHandler.load(self.path, 'token', self.id))
362 if xml_dom.hasAttribute("locked"):
363 if xml_dom.getAttribute("locked") == '1' or xml_dom.getAttribute("locked") == 'True': self.locked = True
364 else: self.locked = False
365 if xml_dom.hasAttribute("hide"):
366 if xml_dom.getAttribute("hide") == '1' or xml_dom.getAttribute("hide") == 'True': self.hide = True
367 else: self.hide = False
368 if xml_dom.hasAttribute("label"):
369 self.label = xml_dom.getAttribute("label")
370 if xml_dom.hasAttribute("zorder"):
371 self.zorder = int(xml_dom.getAttribute("zorder"))
372 if xml_dom.hasAttribute("align"):
373 if xml_dom.getAttribute("align") == '1' or xml_dom.getAttribute("align") == 'True': self.snap_to_align = 1
374 else: self.snap_to_align = 0
375 if xml_dom.hasAttribute("width"):
376 self.width = int(xml_dom.getAttribute("width"))
377 if xml_dom.hasAttribute("height"):
378 self.height = int(xml_dom.getAttribute("height"))
379
380 ##-----------------------------
381 ## token layer
382 ##-----------------------------
383 class token_layer(layer_base):
384 def __init__(self, canvas):
385 self.canvas = canvas
386 layer_base.__init__(self)
387 self.id = -1 #added.
388 self.tokens = []
389 self.serial_number = 0
390
391 self.drawn = {}
392 component.add('drawn', self.drawn)
393 # Set the font of the labels to be the same as the chat window
394 # only smaller.
395 font_size = int(settings.get_setting('defaultfontsize'))
396 if (font_size >= 10): font_size -= 2
397 self.label_font = wx.Font(font_size, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL,
398 False, settings.get_setting('defaultfont'))
399
400 def next_serial(self):
401 self.serial_number += 1
402 return self.serial_number
403
404 def get_next_highest_z(self):
405 z = len(self.tokens)+1
406 return z
407
408 def cleanly_collapse_zorder(self):
409 # lock the zorder stuff
410 sorted_tokens = self.tokens[:]
411 sorted_tokens.sort(cmp_zorder)
412 i = 0
413 for mini in sorted_tokens:
414 mini.zorder = i
415 i = i + 1
416 # unlock the zorder stuff
417
418 def collapse_zorder(self):
419 # lock the zorder stuff
420 sorted_tokens = self.tokens[:]
421 sorted_tokens.sort(cmp_zorder)
422 i = 0
423 for mini in sorted_tokens:
424 if (mini.zorder != MIN_STICKY_BACK) and (mini.zorder != MIN_STICKY_FRONT): mini.zorder = i
425 else: pass
426 i = i + 1
427 # unlock the zorder stuff
428
429 def rollback_serial(self):
430 self.serial_number -= 1
431
432 def add_token(self, id, path, pos=cmpPoint(0,0), label="", heading=FACE_NONE,
433 rotate=0, width=0, height=0, local=False, localPath='', localTime=-1):
434 bmp = ImageHandler.load(path, 'token', id)
435 if bmp:
436 mini = BmpToken(id, path, bmp, pos, heading, rotate, label,
437 zorder=self. get_next_highest_z(), width=width,
438 height=height, local=local, localPath=localPath, localTime=localTime)
439 self.tokens.append(mini)
440 self.drawn[mini.bmp] = False
441 xml_str = "<map><tokens>"
442 xml_str += mini.toxml("new")
443 xml_str += "</tokens></map>"
444 component.get('session').send(xml_str)
445
446 def get_token_by_id(self, id):
447 for mini in self.tokens:
448 if str(mini.id) == str(id):
449 return mini
450 return None
451
452 def del_token(self, min):
453 xml_str = "<map><tokens>"
454 xml_str += min.toxml("del")
455 xml_str += "</tokens></map>"
456 self.canvas.frame.session.send(xml_str)
457 self.tokens.remove(min)
458 del min
459 self.collapse_zorder()
460
461 def del_all_tokens(self):
462 while len(self.tokens):
463 min = self.tokens.pop()
464 del min
465 self.collapse_zorder()
466
467 def layerDraw(self, dc, topleft, size):
468 dc.SetFont(self.label_font)
469 sorted_tokens = self.tokens[:]
470 sorted_tokens.sort(cmp_zorder)
471 for m in sorted_tokens:
472 if (m.pos.x>topleft[0]-m.right and
473 m.pos.y>topleft[1]-m.bottom and
474 m.pos.x<topleft[0]+size[0]-m.left and
475 m.pos.y<topleft[1]+size[1]-m.top):
476 """
477 if self.drawn.has_key(m.bmp):
478 if self.drawn[m.bmp] == True:
479 dc2 = wx.MemoryDC()
480 img = m.bmp.ConvertToImage()
481 bmp = img.ConvertToBitmap()
482
483 dc2.SelectObject(bmp)
484 dc.Blit(m.pos.x, m.pos.y, img.GetHeight(), img.GetWidth(), dc2, 0, 0, wx.COPY, True, 0, 0)
485 del dc2
486
487 else:
488 """
489 m.draw(dc, self)
490
491 def find_token(self, pt, only_unlocked=False):
492 min_list = []
493 for m in self.tokens:
494 if m.hit_test(pt):
495 if m.hide and self.canvas.frame.session.my_role() != self.canvas.frame.session.ROLE_GM: continue
496 if only_unlocked and not m.locked: min_list.append(m)
497 elif not only_unlocked and m.locked: min_list.append(m)
498 else: continue
499 if len(min_list) > 0:
500 return min_list
501 else: return None
502
503 def layerToXML(self, action="update"):
504 """ format """
505 minis_string = ""
506 if self.tokens:
507 for m in self.tokens: minis_string += m.toxml(action)
508 if minis_string != '':
509 s = "<tokens"
510 s += " serial='" + str(self.serial_number) + "'"
511 s += ">"
512 s += minis_string
513 s += "</tokens>"
514 return s
515 else: return ""
516
517 def layerTakeDOM(self, xml_dom):
518 if xml_dom.hasAttribute('serial'):
519 self.serial_number = int(xml_dom.getAttribute('serial'))
520 children = xml_dom._get_childNodes()
521 for c in children:
522 action = c.getAttribute("action")
523 id = c.getAttribute('id')
524 if action == "del":
525 mini = self.get_token_by_id(id)
526 if mini:
527 self.tokens.remove(mini)
528 del mini
529 elif action == "new":
530 pos = cmpPoint(int(c.getAttribute('posx')),int(c.getAttribute('posy')))
531 path = urllib.unquote(c.getAttribute('path'))
532 label = c.getAttribute('label')
533 height = width = heading = rotate = snap_to_align = zorder = 0
534 locked = hide = False
535 if c.hasAttribute('height'): height = int(c.getAttribute('height'))
536 if c.hasAttribute('width'): width = int(c.getAttribute('width'))
537 if c.getAttribute('locked') == 'True' or c.getAttribute('locked') == '1': locked = True
538 if c.getAttribute('hide') == 'True' or c.getAttribute('hide') == '1': hide = True
539 if c.getAttribute('heading'): heading = int(c.getAttribute('heading'))
540 if c.hasAttribute('rotate'): rotate = int(c.getAttribute('rotate'))
541 if c.hasAttribute('align'): snap_to_align = int(c.getAttribute('align'))
542 if c.getAttribute('zorder'): zorder = int(c.getAttribute('zorder'))
543 min = BmpToken(id, path, ImageHandler.load(path, 'token', id), pos, heading,
544 rotate, label, locked, hide, snap_to_align, zorder, width, height)
545 self.tokens.append(min)
546 if c.hasAttribute('local') and c.getAttribute('local') == 'True' and os.path.exists(urllib.unquote(c.getAttribute('localPath'))):
547 localPath = urllib.unquote(c.getAttribute('localPath'))
548 local = True
549 localTime = float(c.getAttribute('localTime'))
550 if localTime-time.time() <= 144000:
551 file = open(localPath, "rb")
552 imgdata = file.read()
553 file.close()
554 filename = os.path.split(localPath)
555 (imgtype,j) = mimetypes.guess_type(filename[1])
556 postdata = urllib.urlencode({'filename':filename[1], 'imgdata':imgdata, 'imgtype':imgtype})
557 thread.start_new_thread(self.upload, (postdata, localPath, True))
558 # collapse the zorder. If the client behaved well, then nothing should change.
559 # Otherwise, this will ensure that there's some kind of z-order
560 self.collapse_zorder()
561 else:
562 mini = self.get_token_by_id(id)
563 if mini: mini.takedom(c)
564
565 def upload(self, postdata, filename, modify=False, pos=cmpPoint(0,0)):
566 self.lock.acquire()
567 url = settings.get_setting('ImageServerBaseURL')
568 file = urllib.urlopen(url, postdata)
569 recvdata = file.read()
570 file.close()
571 try:
572 xml_dom = minidom.parseString(recvdata)._get_documentElement()
573 if xml_dom.nodeName == 'path':
574 path = xml_dom.getAttribute('url')
575 path = urllib.unquote(path)
576 if not modify:
577 start = path.rfind("/") + 1
578 if self.canvas.parent.layer_handlers[2].auto_label: min_label = path[start:len(path)-4]
579 else: min_label = ""
580 id = 'mini-' + self.canvas.frame.session.get_next_id()
581 self.add_token(id, path, pos=pos, label=min_label, local=True,
582 localPath=filename, localTime=time.time())
583 else:
584 self.tokens[len(self.tokens)-1].local = True
585 self.tokens[len(self.tokens)-1].localPath = filename
586 self.tokens[len(self.tokens)-1].localTime = time.time()
587 self.tokens[len(self.tokens)-1].path = path
588 else:
589 print xml_dom.getAttribute('msg')
590 except Exception, e:
591 print e
592 print recvdata
593 urllib.urlcleanup()
594 self.lock.release()
595 ####################################################################
596 ## helper function
597
598 def get_mini_label(self, mini):
599 # override this to change the label displayed under each mini (and the label on hidden minis)
600 return mini.label