Mercurial > MadButterfly
comparison inkscape/firefox/MBServer.py @ 262:c39b24036a75
Add proxy daemon and extention for the firefox integration. We need to implement javascript web client to repalce the unite test program testsoap.py
author | wycc@wycc-desktop |
---|---|
date | Fri, 23 Jan 2009 23:15:04 +0800 |
parents | |
children | 96aae15527c8 |
comparison
equal
deleted
inserted
replaced
261:11017576328c | 262:c39b24036a75 |
---|---|
1 #!/usr/bin/python | |
2 import inkex | |
3 import pygtk | |
4 import gtk | |
5 from copy import deepcopy | |
6 from lxml import etree | |
7 from twisted.web import server, resource,soap | |
8 from twisted.internet import reactor | |
9 | |
10 import random | |
11 | |
12 # Please refer to http://www.assembla.com/wiki/show/MadButterfly/Inkscape_extention for the designed document. | |
13 | |
14 | |
15 # Algorithm: | |
16 # | |
17 # We will parse the first two level of the SVG DOM. collect a table of layer and scene. | |
18 # 1. Collect the layer table which will be displayed as the first column of the grid. | |
19 # 2. Get the maximum scene number. This will decide the size of the grid. | |
20 # 3. When F6 is pressed, we will check if this scene has been defined. This can be done by scan all second level group and check if the current scene number is within the | |
21 # range specified by scene field. The function IsSceneDefined(scene) can be used for this purpose. | |
22 # 4. If this is a new scene, we will append a new group which duplication the content of the last scene in the same group. The scene field will contain the number from the | |
23 # last scene number of the last scene to the current scenen number. For example, if the last scene is from 4-7 and the new scene is 10, we will set the scene field as | |
24 # "8-10". | |
25 # 5. If this scene are filled screne, we will split the existing scene into two scenes with the same content. | |
26 | |
27 class Layer: | |
28 def __init__(self,node): | |
29 self.scene = [] | |
30 self.node = node | |
31 self.nodes=[] | |
32 class Scene: | |
33 def __init__(self, node, start,end): | |
34 self.node = node | |
35 self.start = int(start) | |
36 self.end = int(end) | |
37 | |
38 | |
39 class MBScene(inkex.Effect): | |
40 def confirm(self,msg): | |
41 vbox = gtk.VBox() | |
42 vbox.pack_start(gtk.Label(msg)) | |
43 self.button = gtk.Button('OK') | |
44 vbox.pack_start(self.button) | |
45 self.button.connect("clicked", self.onQuit) | |
46 self.window.add(vbox) | |
47 def dumpattr(self,n): | |
48 s = "" | |
49 for a,v in n.attrib.items(): | |
50 s = s + ("%s=%s" % (a,v)) | |
51 return s | |
52 | |
53 def dump(self,node,l=0): | |
54 print " " * l*2,"<", node.tag, self.dumpattr(node),">" | |
55 for n in node: | |
56 self.dump(n,l+1) | |
57 print " " * l * 2,"/>" | |
58 def parseMetadata(self,node): | |
59 self.current = 1 | |
60 for n in node: | |
61 if n.tag == '{http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd}scenes': | |
62 self.scenemap={} | |
63 cur = int(n.get("current")) | |
64 self.current = cur | |
65 | |
66 for s in n: | |
67 if s.tag == '{http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd}scene': | |
68 try: | |
69 start = int(s.get("start")) | |
70 except: | |
71 continue | |
72 try: | |
73 end = s.get("end") | |
74 if end == None: | |
75 end = start | |
76 except: | |
77 end = start | |
78 link = s.get("ref") | |
79 self.scenemap[link] = [int(start),int(end)] | |
80 if cur >= start and cur <= end: | |
81 self.currentscene = link | |
82 | |
83 pass | |
84 pass | |
85 pass | |
86 pass | |
87 | |
88 | |
89 def parseScene(self): | |
90 """ | |
91 In this function, we will collect all items for the current scene and then relocate them back to the appropriate scene object. | |
92 """ | |
93 self.layer = [] | |
94 self.scenemap = None | |
95 for node in self.document.getroot(): | |
96 if node.tag == '{http://www.w3.org/2000/svg}metadata': | |
97 self.parseMetadata(node) | |
98 elif node.tag == '{http://www.w3.org/2000/svg}g': | |
99 oldscene = None | |
100 #print layer.attrib.get("id") | |
101 lyobj = Layer(node) | |
102 self.layer.append(lyobj) | |
103 lyobj.current_scene = [] | |
104 for scene in node: | |
105 if scene.tag == '{http://www.w3.org/2000/svg}g': | |
106 try: | |
107 scmap = self.scenemap[scene.get("id")] | |
108 if scmap == None: | |
109 lyobj.current_scene.append(scene) | |
110 continue | |
111 if self.current <= scmap[1] and self.current >= scmap[0]: | |
112 oldscene = scene | |
113 except: | |
114 lyobj.current_scene.append(scene) | |
115 continue | |
116 | |
117 lyobj.scene.append(Scene(scene,scmap[0],scmap[1])) | |
118 else: | |
119 lyobj.current_scene.append(scene) | |
120 pass | |
121 pass | |
122 | |
123 if oldscene != None: | |
124 # Put the objects back to the current scene | |
125 for o in lyobj.current_scene: | |
126 #print o.tag | |
127 oldscene.append(o) | |
128 pass | |
129 pass | |
130 pass | |
131 pass | |
132 | |
133 self.collectID() | |
134 #self.dumpID() | |
135 def collectID(self): | |
136 self.ID = {} | |
137 root = self.document.getroot() | |
138 for n in root: | |
139 self.collectID_recursive(n) | |
140 def collectID_recursive(self,node): | |
141 self.ID[node.get("id")] = 1 | |
142 for n in node: | |
143 self.collectID_recursive(n) | |
144 def newID(self): | |
145 while True: | |
146 n = 's%d' % int(random.random()*10000) | |
147 #print "try %s" % n | |
148 if self.ID.has_key(n) == False: | |
149 return n | |
150 def dumpID(self): | |
151 for a,v in self.ID.items(): | |
152 print a | |
153 | |
154 | |
155 def getLayer(self, layer): | |
156 for l in self.layer: | |
157 if l.node.attrib.get("id") == layer: | |
158 return l | |
159 return None | |
160 | |
161 | |
162 def insertKeyScene(self): | |
163 """ | |
164 Insert a new key scene into the stage. If the nth is always a key scene, we will return without changing anything. | |
165 If the nth is a filled scene, we will break the original scene into two parts. If the nth is out of any scene, we will | |
166 append a new scene. | |
167 | |
168 """ | |
169 nth = self.last_cell.nScene | |
170 layer = self.getLayer(self.last_cell.layer) | |
171 x = self.last_cell.nScene | |
172 y = self.last_cell.nLayer | |
173 if layer == None: return | |
174 for i in range(0,len(layer.scene)): | |
175 s = layer.scene[i] | |
176 if nth >= s.start and nth <= s.end: | |
177 if nth == s.start: return | |
178 newscene = Scene(deepcopy(s.node),nth,s.end) | |
179 newscene.node.set("id", self.newID()) | |
180 layer.scene.insert(i+1,newscene) | |
181 layer.scene[i].end = nth-1 | |
182 btn = self.newCell('start.png') | |
183 btn.nScene = nth | |
184 btn.layer = layer | |
185 btn.nLayer = y | |
186 self.grid.remove(self.last_cell) | |
187 self.grid.attach(btn, x,x+1,y,y+1,0,0,0,0) | |
188 return | |
189 if len(layer.scene) > 0: | |
190 last = nth | |
191 lastscene = None | |
192 for s in layer.scene: | |
193 if s.end < nth and last < s.end: | |
194 last = s.end | |
195 lastscene = s | |
196 for x in range(last+1, nth): | |
197 btn = self.newCell('fill.png') | |
198 btn.nScene = x | |
199 btn.layer = layer.node.get('id') | |
200 btn.nLayer = y | |
201 self.grid.attach(btn, x, x+1, y , y+1,0,0,0,0) | |
202 if lastscene == None: | |
203 node = etree.Element('{http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd}scene') | |
204 node.set("id", self.newID()) | |
205 newscene = Scene(node,nth,nth) | |
206 else: | |
207 lastscene.end = nth-1 | |
208 newscene = Scene(deepcopy(lastscene.node),nth,nth) | |
209 newscene.node.set("id",self.newID()) | |
210 layer.scene.append(newscene) | |
211 btn = self.newCell('start.png') | |
212 x = self.last_cell.nScene | |
213 y = self.last_cell.nLayer | |
214 btn.nScene = nth | |
215 btn.layer = layer.node.get('id') | |
216 btn.nLayer = y | |
217 self.grid.attach(btn, x, x+1, y, y+1,0,0,0,0) | |
218 else: | |
219 # This is the first scene in the layer | |
220 node = etree.Element('{http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd}scene') | |
221 node.set("id", self.newID()) | |
222 newscene = Scene(node,nth,nth) | |
223 layer.scene.append(newscene) | |
224 btn = self.newCell('start.png') | |
225 btn.nScene = nth | |
226 btn.layer = layer.node.get('id') | |
227 btn.nLayer = y | |
228 self.grid.attach(btn, x, x+1, y, y+1,0,0,0,0) | |
229 | |
230 | |
231 | |
232 | |
233 def removeKeyScene(self): | |
234 nth = self.last_cell.nScene | |
235 try: | |
236 layer = self.getLayer(self.last_cell.layer) | |
237 except: | |
238 return | |
239 x = self.last_cell.nScene | |
240 y = self.last_cell.nLayer | |
241 for i in range(0,len(layer.scene)): | |
242 s = layer.scene[i] | |
243 if nth == s.start: | |
244 if i == 0: | |
245 for j in range(s.start,s.end+1): | |
246 btn = self.newCell('empty.png') | |
247 btn.nScene = nth | |
248 btn.layer = layer | |
249 btn.nLayer = y | |
250 self.grid.attach(btn, j,j+1,y,y+1,0,0,0,0) | |
251 layer.scene.remove(s) | |
252 else: | |
253 if s.start == layer.scene[i-1].end+1: | |
254 # If the start of the delete scene segment is the end of the last scene segmenet, convert all scenes in the deleted | |
255 # scene segmenet to the last one | |
256 layer.scene[i-1].end = s.end | |
257 layer.scene.remove(s) | |
258 btn = self.newCell('fill.png') | |
259 | |
260 btn.nScene = nth | |
261 btn.layer = layer | |
262 btn.nLayer = y | |
263 self.grid.attach(btn, x,x+1,y,y+1,0,0,0,0) | |
264 else: | |
265 # Convert all scenes into empty cell | |
266 layer.scene.remove(s) | |
267 for j in range(s.start,s.end+1): | |
268 btn = self.newCell('empty.png') | |
269 btn.nScene = nth | |
270 btn.layer = layer | |
271 btn.nLayer = y | |
272 self.grid.attach(btn, j,j+1,y,y+1,0,0,0,0) | |
273 | |
274 | |
275 return | |
276 | |
277 def extendScene(self): | |
278 nth = self.last_cell.nScene | |
279 try: | |
280 layer = self.getLayer(self.last_cell.layer) | |
281 except: | |
282 return | |
283 x = self.last_cell.nScene | |
284 y = self.last_cell.nLayer | |
285 if layer == None: return | |
286 | |
287 for i in range(0,len(layer.scene)-1): | |
288 s = layer.scene[i] | |
289 if nth >= layer.scene[i].start and nth <= layer.scene[i].end: | |
290 return | |
291 | |
292 for i in range(0,len(layer.scene)-1): | |
293 s = layer.scene[i] | |
294 if nth >= layer.scene[i].start and nth < layer.scene[i+1].start: | |
295 for j in range(layer.scene[i].end+1, nth+1): | |
296 btn = self.newCell('fill.png') | |
297 btn.nScene = nth | |
298 btn.nLayer = y | |
299 btn.layer = self.last_cell.layer | |
300 self.grid.attach(btn, j,j+1,y,y+1,0,0,0,0) | |
301 layer.scene[i].end = nth | |
302 return | |
303 if len(layer.scene) > 0 and nth > layer.scene[len(layer.scene)-1].end: | |
304 for j in range(layer.scene[len(layer.scene)-1].end+1, nth+1): | |
305 btn = self.newCell('fill.png') | |
306 btn.nScene = nth | |
307 btn.nLayer = y | |
308 btn.layer = self.last_cell.layer | |
309 self.grid.attach(btn, j,j+1,y,y+1,0,0,0,0) | |
310 layer.scene[len(layer.scene)-1].end = nth | |
311 def setCurrentScene(self,nth): | |
312 self.current = nth | |
313 for layer in self.layer: | |
314 for s in layer.scene: | |
315 if nth >= s.start and nth <= s.end: | |
316 s.node.set("style","") | |
317 #print "Put the elemenets out" | |
318 layer.nodes = [] | |
319 | |
320 for o in s.node: | |
321 #print " ",o.tag | |
322 layer.nodes.append(o) | |
323 for o in s.node: | |
324 s.node.remove(o) | |
325 else: | |
326 s.node.set("style","display:none") | |
327 def generate(self): | |
328 newdoc = deepcopy(self.document) | |
329 root = newdoc.getroot() | |
330 has_scene = False | |
331 for n in root: | |
332 if n.tag == '{http://www.w3.org/2000/svg}metadata': | |
333 for nn in n: | |
334 if nn.tag == '{http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd}scenes': | |
335 nn.clear() | |
336 nn.set("current", "%d" % self.current) | |
337 scenes = [] | |
338 for l in self.layer: | |
339 for s in l.scene: | |
340 id = s.node.get("id") | |
341 scene = etree.Element('{http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd}scene') | |
342 scene.set("ref", id) | |
343 if s.start == s.end: | |
344 scene.set("start", "%d" % s.start) | |
345 else: | |
346 scene.set("start", "%d" % s.start) | |
347 scene.set("end", "%d" % s.end) | |
348 | |
349 scenes.append(scene) | |
350 for s in scenes: | |
351 nn.append(s) | |
352 has_scene = True | |
353 if has_scene == False: | |
354 scenes = etree.Element('{http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd}scenes') | |
355 scenes.set("current","%d" % self.current) | |
356 for l in self.layer: | |
357 for s in l.scene: | |
358 scene = etree.Element('{http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd}scene') | |
359 scene.set("ref", s.node.get("id")) | |
360 if s.start == s.end: | |
361 scene.set("start", "%d" % s.start) | |
362 else: | |
363 scene.set("start", "%d" % s.start) | |
364 scene.set("end", "%d" % s.end) | |
365 scenes.append(scene) | |
366 n.append(scenes) | |
367 if n.tag == '{http://www.w3.org/2000/svg}g': | |
368 root.remove(n) | |
369 | |
370 for l in self.layer: | |
371 # Duplicate all attribute of the layer | |
372 lnode = etree.Element("{http://www.w3.org/2000/svg}g") | |
373 for a,v in l.node.attrib.items(): | |
374 lnode.set(a,v) | |
375 for n in l.nodes: | |
376 lnode.append(n) | |
377 root.append(lnode) | |
378 for s in l.scene: | |
379 snode = etree.Element("{http://www.w3.org/2000/svg}g") | |
380 for a,v in s.node.attrib.items(): | |
381 snode.set(a,v) | |
382 for n in s.node: | |
383 snode.append(deepcopy(n)) | |
384 lnode.append(snode) | |
385 self.document = newdoc | |
386 def newCell(self,file): | |
387 img = gtk.Image() | |
388 img.set_from_file(file) | |
389 btn = gtk.EventBox() | |
390 btn.add(img) | |
391 btn.connect("button_press_event", self.cellSelect) | |
392 btn.modify_bg(gtk.STATE_NORMAL, btn.get_colormap().alloc_color("gray")) | |
393 return btn | |
394 def showGrid(self): | |
395 max = 0 | |
396 for layer in self.layer: | |
397 for s in layer.scene: | |
398 if s.end > max: | |
399 max = s.end | |
400 max = 50 | |
401 | |
402 self.grid = gtk.Table(len(self.layer)+1, 50) | |
403 self.scrollwin = gtk.ScrolledWindow() | |
404 self.scrollwin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) | |
405 self.scrollwin.add_with_viewport(self.grid) | |
406 for i in range(1,max): | |
407 self.grid.attach(gtk.Label('%d'% i), i,i+1,0,1,0,0,0,0) | |
408 for i in range(1,len(self.layer)+1): | |
409 l = self.layer[i-1] | |
410 self.grid.attach(gtk.Label(l.node.get('{http://www.inkscape.org/namespaces/inkscape}label')), 0, 1, i, i+1,0,0,10,0) | |
411 for s in l.scene: | |
412 btn = self.newCell('start.png') | |
413 btn.nScene = s.start | |
414 btn.layer = l.node.get('id') | |
415 btn.nLayer = i | |
416 | |
417 self.grid.attach(btn, s.start, s.start+1, i, i+1,0,0,0,0) | |
418 for j in range(s.start+1,s.end+1): | |
419 btn = self.newCell('fill.png') | |
420 self.grid.attach(btn, j, j+1, i , i+1,0,0,0,0) | |
421 btn.modify_bg(gtk.STATE_NORMAL, btn.get_colormap().alloc_color("gray")) | |
422 btn.nScene = j | |
423 btn.layer = l.node.get('id') | |
424 btn.nLayer = i | |
425 if len(l.scene) == 0: | |
426 start = 0 | |
427 else: | |
428 start = l.scene[len(l.scene)-1].end | |
429 for j in range(start,max): | |
430 btn = self.newCell('empty.png') | |
431 self.grid.attach(btn, j+1, j+2,i,i+1,0,0,0,0) | |
432 btn.modify_bg(gtk.STATE_NORMAL, btn.get_colormap().alloc_color("gray")) | |
433 btn.nScene = j+1 | |
434 btn.layer = l.node.get('id') | |
435 btn.nLayer = i | |
436 self.last_cell = None | |
437 def cellSelect(self, cell, data): | |
438 if self.last_cell: | |
439 self.last_cell.modify_bg(gtk.STATE_NORMAL, self.last_cell.get_colormap().alloc_color("gray")) | |
440 | |
441 self.last_cell = cell | |
442 cell.modify_bg(gtk.STATE_NORMAL, cell.get_colormap().alloc_color("green")) | |
443 | |
444 def doEditScene(self,w): | |
445 self.setCurrentScene(self.last_cell.nScene) | |
446 self.generate() | |
447 gtk.main_quit() | |
448 def doInsertKeyScene(self,w): | |
449 self.insertKeyScene() | |
450 self.grid.show_all() | |
451 self.generate() | |
452 | |
453 def doRemoveScene(self,w): | |
454 self.removeKeyScene() | |
455 self.grid.show_all() | |
456 self.generate() | |
457 def doExtendScene(self,w): | |
458 self.extendScene() | |
459 self.grid.show_all() | |
460 self.generate() | |
461 def addButtons(self,hbox): | |
462 btn = gtk.Button('Edit') | |
463 btn.connect('clicked', self.doEditScene) | |
464 hbox.pack_start(btn) | |
465 btn = gtk.Button('Insert Key') | |
466 btn.connect('clicked',self.doInsertKeyScene) | |
467 hbox.pack_start(btn) | |
468 btn=gtk.Button('Remove Key') | |
469 btn.connect('clicked', self.doRemoveScene) | |
470 hbox.pack_start(btn) | |
471 btn=gtk.Button('Extend scene') | |
472 btn.connect('clicked', self.doExtendScene) | |
473 hbox.pack_start(btn) | |
474 def onQuit(self, event): | |
475 self.OK = False | |
476 gtk.main_quit() | |
477 def onOK(self,event): | |
478 self.OK = True | |
479 gtk.main_quit() | |
480 | |
481 def onConfirmDelete(self): | |
482 if self.scenemap == None: | |
483 vbox = gtk.VBox() | |
484 vbox.pack_start(gtk.Label('Convert the SVG into a MadButterfly SVG file. All current element will be delted')) | |
485 hbox = gtk.HBox() | |
486 self.button = gtk.Button('OK') | |
487 hbox.pack_start(self.button) | |
488 self.button.connect('clicked', self.onOK) | |
489 self.button = gtk.Button('Cancel') | |
490 hbox.pack_start(self.button) | |
491 self.button.connect("clicked", self.onQuit) | |
492 vbox.pack_start(hbox) | |
493 self.window.add(vbox) | |
494 self.window.show_all() | |
495 gtk.main() | |
496 self.window.remove(vbox) | |
497 | |
498 def start_server(self): | |
499 root = MB() | |
500 root.target = self | |
501 site = server.Site(root) | |
502 reactor.listenTCP(8080, site) | |
503 reactor.run() | |
504 | |
505 | |
506 def effect(self): | |
507 self.OK = False | |
508 self.parseScene() | |
509 self.start_server() | |
510 self.generate() | |
511 | |
512 class MB(soap.SOAPPublisher): | |
513 """ | |
514 SOAP server for inkscape extension. | |
515 """ | |
516 | |
517 def soap_PUBLISH(self): | |
518 reactor.callLater(1,self.quit) | |
519 return "OK" | |
520 def quit(self): | |
521 reactor.stop() | |
522 def soap_SCENE(self,n): | |
523 self.target.setCurrentScene(int(n)) | |
524 return "OK" | |
525 | |
526 | |
527 | |
528 | |
529 | |
530 import os | |
531 | |
532 os.chdir('/usr/share/inkscape/extensions') | |
533 | |
534 A = MBScene() | |
535 A.affect() | |
536 | |
537 |