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