/[ascend]/branches/adrian/pygtk/canvas/blocklist.py
ViewVC logotype

Contents of /branches/adrian/pygtk/canvas/blocklist.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2899 - (show annotations) (download) (as text)
Sun Apr 12 15:56:51 2015 UTC (3 years, 8 months ago) by adrian
File MIME type: text/x-python
File size: 30338 byte(s)
Fixed export svg dialog transient parent issue
1 #!/usr/bin/env python
2 from collections import namedtuple
3
4 if __name__ == '__main__':
5 print "ERROR: ASCEND Canvas should now be invoked using the file 'canvas.py' instead of 'blocklist.py'."
6 exit(1)
7
8 from gi.repository import Gtk, GdkPixbuf, Gdk
9 import os
10 import os.path
11 import glob
12 import cairo
13 import ascpy
14
15 class BlockIconView(Gtk.IconView):
16 """
17 IconView containing the palette of BlockTypes available for use in the
18 canvas. The list of blocks is supplied currently as an initialisation
19 parameter, but it is intended that this would be dynamic in a final system.
20
21 It should be possible drag icons from the palette into the canvas, but
22 that is not yet implemented.
23 """
24 def __init__(self,blocks=None,app=None):
25 self.model = Gtk.ListStore(str, GdkPixbuf.Pixbuf)
26 self.app = app
27 self.otank = {}
28 try:
29 for b in blocks:
30 pixbuf = b.get_icon(48,48)
31 #print pixbuf
32 iter = self.model.append([b.name, pixbuf])
33 path = self.model.get_path(iter)
34 self.otank[path.to_string()] = b
35 except Exception as e:
36 pass
37
38 Gtk.IconView.__init__(self)
39 self.set_model(self.model)
40 self.set_text_column(0)
41 self.set_pixbuf_column(1)
42 self.set_columns(-1)
43 self.set_size_request(180,100)
44 self.connect("item-activated", self.item_activated)
45 self.connect("selection-changed", self.selection_changed)
46
47 def refresh_view():
48 pass
49
50 def selection_changed(self,iconview):
51 s = self.get_selected_items()
52 if len(s)==1:
53 b = self.otank[s[0].to_string()]
54 self.app.set_placement_tool(b)
55
56 def item_activated(self,iconview, path):
57 self.app.set_placement_tool(self.otank[path])
58
59
60 from gaphas import GtkView, View
61 from gaphas.tool import HoverTool, PlacementTool, HandleTool, ToolChain
62 from gaphas.tool import ItemTool, RubberbandTool
63 from gaphas.painter import ItemPainter
64 from blockconnecttool import BlockConnectTool
65 from blockline import BlockLine
66 from blockitem import DefaultBlockItem, GraphicalBlockItem
67 from contextmenutool import ContextMenuTool
68 from connectortool import ConnectorTool
69 from blockcanvas import BlockCanvas
70 from gaphas.tool import PanTool, ZoomTool
71 from blockinstance import BlockInstance
72 from solverreporterforcanvas import PopupSolverReporter
73 import canvasproperties
74 import blockproperties
75 import undo
76 from undo import UndoMonitorTool
77 import errorreporter
78 import pickle as pickle
79 import obrowser
80 import help
81 from preferences import Preferences
82
83 def BlockToolChain():
84 """
85 ToolChain for working with BlockCanvas, including several custom Tools.
86 """
87 chain = ToolChain()
88 chain.append(UndoMonitorTool())
89 chain.append(HoverTool())
90 chain.append(BlockConnectTool()) # for connect/disconnect of lines
91 chain.append(ConnectorTool()) # for creating new lines by drag from Port
92 chain.append(ContextMenuTool()) # right-click
93 # chain.append(LineSegmentTool()) # for moving line 'elbows'
94 chain.append(ItemTool())
95 chain.append(PanTool())
96 chain.append(ZoomTool())
97 chain.append(RubberbandTool())
98 return chain
99
100 class mainWindow(Gtk.Window):
101
102 menu_xml = '''<ui>
103 <menubar name='MenuBar'>
104 <menu action='File'>
105 <menuitem action='New' />
106 <menuitem action='Open' />
107 <menuitem action='Save' />
108 <menuitem action='SaveAs' />
109 <separator />
110 <menuitem action='Export' />
111 <separator />
112 <menuitem action='Library' />
113 <separator />
114 <menuitem action='Quit' />
115 </menu>
116 <menu action='Edit'>
117 <menuitem action='Undo' />
118 <menuitem action='Redo' />
119 <separator />
120 <menuitem action='BlockProperties' />
121 <menuitem action='Delete' />
122 </menu>
123 <menu action='View'>
124 <menuitem action='Fullscreen' />
125 <separator />
126 <menuitem action='ZoomIn' />
127 <menuitem action='ZoomOut' />
128 </menu>
129 <menu action='Tools'>
130 <menuitem action='Debug' />
131 <menuitem action='Run' />
132 <menuitem action='Preview' />
133 </menu>
134 <menu action='Help'>
135 <menuitem action='Development' />
136 <menuitem action='ReportBug' />
137 <menuitem action='About' />
138 </menu>
139 </menubar>
140 </ui>
141 '''
142
143 def __init__(self,library,options=None):
144 """
145 Initialise the application -- create all the widgets, and populate
146 the icon palette.
147 TODO: separate the icon palette into a separate method.
148 """
149 self.ascwrap= library
150 self.errorvars = []
151 self.errorblocks = []
152 self.status = Gtk.Statusbar()
153 self.temp = []
154 self.act = 1 #to be used for storing canvas zoom in/out related data.
155 # the Gaphas canvas
156 canvas = BlockCanvas()
157
158 # the main window
159 Gtk.Window.__init__(self)
160 self.iconok = self.render_icon(Gtk.STOCK_YES,Gtk.IconSize.MENU)
161 self.iconinfo = self.render_icon(Gtk.STOCK_DIALOG_INFO,Gtk.IconSize.MENU)
162 self.iconwarning = self.render_icon(Gtk.STOCK_DIALOG_WARNING,Gtk.IconSize.MENU)
163 self.iconerror = self.render_icon(Gtk.STOCK_DIALOG_ERROR,Gtk.IconSize.MENU)
164
165 self.set_title("ASCEND Canvas Modeller")
166 self.set_default_size(650,650)
167 self.connect("destroy", Gtk.main_quit)
168
169 windowicon = Gtk.Image()
170 windowicon.set_from_file(os.path.join('..','glade','ascend.svg'))
171 self.set_icon(windowicon.get_pixbuf())
172
173 vbox = Gtk.VBox()
174
175 ui_manager = Gtk.UIManager()
176 accelgroup = ui_manager.get_accel_group()
177 self.add_accel_group(accelgroup)
178
179 actiongroup = Gtk.ActionGroup('CanvasActionGroup')
180
181 self.prefs = Preferences()
182
183 actions = [('File', None, '_File')
184 ,('Quit', Gtk.STOCK_QUIT, '_Quit', None,'Quit the Program', self.quit)
185 ,('New', Gtk.STOCK_NEW,'_New',None,'Start a new Simulation', self.new)
186 ,('Open', Gtk.STOCK_OPEN,'_Open',None,'Open a saved Canvas file', self.fileopen)
187 ,('Save', Gtk.STOCK_SAVE,'_Save',None,'Open a saved Canvas file', self.save_canvas)
188 ,('SaveAs', Gtk.STOCK_SAVE_AS,'_Save As...',None,'Open a saved Canvas file', self.filesave)
189 ,('Export', Gtk.STOCK_PRINT, '_Export SVG', None,'Quit the Program', self.export_svg_as)
190 ,('Library', Gtk.STOCK_OPEN, '_Load Library...', '<Control>l','Load Library', self.load_library_dialog)
191 ,('Edit', None, '_Edit')
192 ,('Undo', Gtk.STOCK_UNDO, '_Undo', '<Control>z', 'Undo Previous Action', self.undo_canvas)
193 ,('Redo',Gtk.STOCK_REDO, '_Redo', '<Control>y', 'Redo Previous Undo', self.redo_canvas)
194 ,('BlockProperties',Gtk.STOCK_PROPERTIES, '_Block Properties', None, 'Edit Block Properties', self.bp)
195 ,('Delete', Gtk.STOCK_DELETE, '_Delete', 'Delete', 'Delete Selected Item', self.delblock)
196 ,('View', None, '_View')
197 ,('Fullscreen', Gtk.STOCK_FULLSCREEN, '_Full Screen', 'F11', 'Toggle Full Screen', self.fullscrn)
198 ,('ZoomIn', Gtk.STOCK_ZOOM_IN, '_Zoom In', None, 'Zoom In Canvas', self.zoom)
199 ,('ZoomOut', Gtk.STOCK_ZOOM_OUT, '_Zoom Out', None, 'Zoom Out Canvas', self.zoom)
200 #,('BestFit', Gtk.STOCK_ZOOM_FIT, '_Best Fit', None, 'Best Fit Canvas',self.zoom)
201 ,('Tools', None, '_Tools')
202 ,('Debug', None, '_Debug', None, 'View Instance Browser',self.debug_canvas)
203 ,('Run', Gtk.STOCK_EXECUTE, '_Run', None, 'Solve Canvas', self.run_canvas)
204 ,('Preview', Gtk.STOCK_PRINT_PREVIEW, '_Preview', None, 'Preview Generated Code', self.preview_canvas)
205 ,('Help', None, '_Help')
206 ,('Development', Gtk.STOCK_INFO, '_Development', None, 'Check Development', self.on_get_help_online_click)
207 ,('ReportBug', None, '_Report Bug', None, 'Report a Bug!', self.on_report_a_bug_click)
208 ,('About', Gtk.STOCK_ABOUT, '_About', None, 'About Us', self.about)
209 ]
210
211 actiongroup.add_actions(actions)
212
213 ui_manager.insert_action_group(actiongroup,0)
214 ui_manager.add_ui_from_string(self.menu_xml)
215
216 #Creating Menu Bar
217 menubar = ui_manager.get_widget('/MenuBar')
218 vbox.pack_start(menubar,False,False,0)
219
220 #Creating Tool Bar
221 '''The Toolbar Definations start here'''
222
223 tb = Gtk.Toolbar()
224 #Load Button
225 loadbutton = Gtk.ToolButton(Gtk.STOCK_OPEN)
226 loadbutton.connect("clicked",self.fileopen)
227 tb.insert(loadbutton,0)
228
229 #Save Button
230 savebutton = Gtk.ToolButton(Gtk.STOCK_SAVE)
231 savebutton.connect("clicked",self.save_canvas)
232 tb.insert(savebutton,1)
233
234 #Debug Button
235 debugbutton = Gtk.ToolButton(Gtk.STOCK_PROPERTIES)
236 debugbutton.set_label("Debug")
237 debugbutton.connect("clicked",self.debug_canvas)
238 tb.insert(debugbutton,2)
239
240 #Preview Button
241 previewb = Gtk.ToolButton(Gtk.STOCK_PRINT_PREVIEW)
242 previewb.set_label("Preview")
243 previewb.connect("clicked",self.preview_canvas)
244 tb.insert(previewb,3)
245
246 #Export Button
247 exportbutton = Gtk.ToolButton(Gtk.STOCK_CONVERT)
248 exportbutton.set_label("Export SVG")
249 exportbutton.connect("clicked",self.export_svg_as)
250 tb.insert(exportbutton,2)
251
252 #Run Button
253 runb = Gtk.ToolButton(Gtk.STOCK_EXECUTE)
254 runb.set_label("Run")
255 runb.connect("clicked",self.run_canvas)
256 tb.insert(runb, 4)
257
258 ##Custom Entry
259 #m_entry = Gtk.ToolButton(Gtk.STOCK_SAVE_AS)
260 #m_entry.set_label("Custom METHOD")
261 #m_entry.connect("clicked",self.custommethod)
262 #tb.insert(m_entry,5)
263
264 vbox.pack_start(tb, False, False,0)
265
266 # hbox occupies top part of vbox, with icons on left & canvas on right.
267 paned = Gtk.HPaned()
268
269 # the 'view' widget implemented by Gaphas
270 #gaphas.view.DEBUG_DRAW_BOUNDING_BOX = True
271 self.view = GtkView()
272 # workaround to provide proper adjustments
273 d = {"name": "hadjustment"}
274 self.view.do_set_property(namedtuple('s', d.keys())(**d), None)
275
276 self.view.tool = BlockToolChain()
277
278 # table containing scrollbars and main canvas
279 t = Gtk.Table(2,2)
280 self.view.canvas = canvas
281 self.view.zoom(1)
282 self.view.set_size_request(450, 300)
283 hs = Gtk.HScrollbar(self.view.hadjustment)
284 vs = Gtk.VScrollbar(self.view.vadjustment)
285 t.attach(self.view, 0, 1, 0, 1)
286 t.attach(hs, 0, 1, 1, 2, xoptions=Gtk.AttachOptions.FILL, yoptions=Gtk.AttachOptions.FILL)
287 t.attach(vs, 1, 2, 0, 1, xoptions=Gtk.AttachOptions.FILL, yoptions=Gtk.AttachOptions.FILL)
288
289 # a scrolling window to contain the icon palette
290 self.scroll = Gtk.ScrolledWindow()
291 self.scroll.set_border_width(2)
292 self.scroll.set_shadow_type(Gtk.ShadowType.ETCHED_IN)
293
294 self.scroll.set_policy(Gtk.PolicyType.AUTOMATIC,Gtk.PolicyType.AUTOMATIC)
295
296 self.blockiconview = BlockIconView(blocks=self.ascwrap.canvas_blocks,app=self)
297 self.scroll.set_size_request(250, 300)
298 self.scroll.add(self.blockiconview)
299 self.reporter = self.ascwrap.reporter
300
301 paned.pack1(self.scroll, False, False)
302 paned.pack2(t)
303 vbox.pack_start(paned, True, True, 0)
304 vpane = Gtk.VPaned()
305 vpane.pack1(vbox, False, False)
306 lower_vbox = Gtk.VBox()
307
308 self.ET = errorreporter.ErrorReporter( self.reporter,self.iconok,self.iconinfo,self.iconwarning,self.iconerror)
309 self.notebook = Gtk.Notebook()
310 self.notebook.set_tab_pos(Gtk.PositionType.TOP)
311 label = Gtk.Label(label='Error / Status Reporter Console')
312 scrolledwindow = Gtk.ScrolledWindow()
313 scrolledwindow.set_policy(Gtk.PolicyType.AUTOMATIC,Gtk.PolicyType.AUTOMATIC)
314 scrolledwindow.add(self.ET.errorview)
315 self.notebook.append_page(scrolledwindow, label)
316 lower_vbox.pack_start(self.notebook,True, True, 0)
317 lower_vbox.pack_start(self.status, False, False, 0)
318 vpane.pack2(lower_vbox,False,False)
319
320 self.undo_manager = undo.undoManager(self)
321 self.undo_manager.start()
322
323 self.add(vpane)
324 self.show_all()
325
326 @undo.block_observed
327 def set_placement_tool(self,blocktype):
328 """
329 Prepare the canvas for drawing a block of the type selected in the
330 icon palette.
331 """
332 # TODO: add undo handler
333 graphic = blocktype.gr
334 def my_block_factory():
335 def wrapper():
336 b = BlockInstance(blocktype)
337 if len(graphic)==0:
338 bi = DefaultBlockItem(b)
339 else:
340 bi = GraphicalBlockItem(b)
341 self.view.canvas.add(bi)
342 return bi
343 return wrapper
344 self.view.unselect_all()
345 self.view.tool.grab(PlacementTool(self.view,my_block_factory(), HandleTool(), 2))
346 self.status.push(0,"Selected '%s'..." % blocktype.type.getName())
347
348 def set_connector_tool(self,foobar):
349 """
350 Prepare the canvas for drawing a connecting line (note that one can
351 alternatively just drag from a port to another port).
352 """
353
354 def my_line_factory():
355 def wrapper():
356 l = BlockLine()
357 self.view.canvas.add(l)
358 return l
359 return wrapper
360 self.view.tool.grab(PlacementTool(self.view,my_line_factory(), HandleTool(), 1))
361
362 @undo.block_observed
363 def delblock(self, widget = None):
364 '''Both individual and multiple selected items are deleted by the logic of following routine'''
365
366 if self.view.selected_items:
367 while(len(self.view.selected_items)!=0):
368 self.view.canvas.remove(self.view._selected_items.pop())
369 self.status.push(0,"Item deleted.")
370 self.view.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse('#FFF'))
371
372 '''if self.view.focused_item:
373 self.view.canvas.remove(self.view.focused_item)
374 self.status.push(0,"Item deleted.")
375 self.view.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse('#FFF'))'''
376
377
378
379 @undo.block_observed
380 def new(self, widget):
381 for item in self.view.canvas.get_all_items():
382 self.view.canvas.remove(item)
383 self.reporter.reportNote('Canvas cleared for new Model')
384 self.view.canvas.filestate = 0
385 self.view.canvas.filename = None
386 self.view.canvas.canvasmodelstate = 'Unsolved'
387 self.status.push(0,"Canvasmodel state : %s"% self.view.canvas.canvasmodelstate)
388 self.view.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse('#FFF'))
389
390 def debug_canvas(self,widget):
391 """
392 Display an 'object browser' to allow inspection of the objects
393 in the canvas.
394 """
395
396 b = obrowser.Browser("canvas",self.view.canvas, False)
397 self.status.push(0,"Canvasmodel state : %s"% self.view.canvas.canvasmodelstate)
398
399 def save_canvas(self,widget):
400 """
401 Save the canvas in 'pickle' format. Currently saving is jointly handled by both self.save_canvas and self.filesave methods
402 """
403 if not self.view.canvas.filestate:
404 self.filesave(widget)
405 return
406 else:
407 f = file(self.view.canvas.filename,"w")
408 try:
409 pickle.dump(self.view.canvas,f)
410 self.status.push(0,"Canvasmodel saved...")
411 except Exception,e:
412 print "ERROR:",str(e)
413 self.status.push(0,"Canvasmodel could not be saved : " + str(e))
414 b = obrowser.Browser("canvas",self.view.canvas)
415 d = Gtk.Dialog("Error",self,Gtk.DialogFlags.DESTROY_WITH_PARENT,(Gtk.STOCK_OK, Gtk.ResponseType.ACCEPT))
416 d.vbox.add(Gtk.Label(label=str(e)))
417 d.show_all()
418 d.run()
419 d.hide()
420 finally:
421 f.close()
422
423 def load_canvas(self,widget):
424 """
425 Restore a saved canvas in 'pickle' format. Currently not in use as loading now handled by self.fileopen().
426 """
427 f = file("./test.a4b","r")
428 try:
429 self.view.canvas = pickle.load(f)
430 if self.view.canvas.model_library is not None:
431 print "Loading Library...."
432 self.loadlib(self, self.view.canvas.model_library,0)
433 self.view.canvas.reattach_ascend(self.ascwrap.library,self.ascwrap.annodb)
434 self.view.canvas.update_now()
435 self.status.push(0,"Canvasmodel sucessfully loaded...")
436 except Exception,e:
437 self.status.push(0,"Canvasmodel could not be loaded : " + str(e))
438 self.reporter.ReportError("Canvasmodel could not be loaded : " + str(e))
439 self.reporter.ReportNote(" Error occured while attempting to load the file")
440 finally:
441 f.close()
442 self.load_presaved_canvas(None)
443 self.status.push(0,"Canvasmodel state : %s"% self.view.canvas.canvasmodelstate)
444
445
446 def temp_canvas(self,widget):
447 pass
448 """
449 NOTE: re-implementation needed
450 """
451
452 def undo_canvas(self,widget):
453 """
454 Undo
455
456 """
457 self.undo_manager.undo()
458 #pass
459
460 def redo_canvas(self,widget):
461 """
462 NOTE: re-implementation needed
463
464 """
465 self.undo_manager.redo()
466 #pass
467
468 def preview_canvas(self,widget):
469 """
470 Output an ASCEND representation of the canvas on the commandline.
471 Under development.
472 """
473 self.status.push(0,"Canvasmodel state : %s"% self.view.canvas.canvasmodelstate)
474 #info.Info(self.view.parent.parent.parent.parent.parent,str(self.view.canvas),"Canvas Preview").run()
475 canvasproperties.CanvasProperties(self).run()
476
477 def export_svg_as(self,widget):
478
479 f = None
480 dialog = Gtk.FileChooserDialog("Export Canvas As...", self,
481 Gtk.FileChooserAction.SAVE, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_SAVE, Gtk.ResponseType.OK))
482 dialog.set_default_response(Gtk.ResponseType.OK)
483 filter = Gtk.FileFilter()
484 filter.set_name("Image File")
485 filter.add_pattern("*.svg")
486 dialog.add_filter(filter)
487 dialog.show()
488 response = dialog.run()
489
490 svgview = View(self.view.canvas)
491 svgview.painter = ItemPainter()
492
493 # Update bounding boxes with a temporaly CairoContext
494 # (used for stuff like calculating font metrics)
495 tmpsurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 0, 0)
496 tmpcr = cairo.Context(tmpsurface)
497 svgview.update_bounding_box(tmpcr)
498 tmpcr.show_page()
499 tmpsurface.flush()
500
501 if response == Gtk.ResponseType.OK:
502 name = dialog.get_filename()
503 if '.svg' not in name:
504 name += '.svg'
505 if f == None and f != name:
506 f = open(name, 'w')
507 elif f != None and name == f:
508 dialog.set_do_overwrite_confirmation(True)
509 dialog.connect("confirm-overwrite", self.confirm_overwrite_callback)
510
511 fn = name
512 w, h = svgview.bounding_box.width, svgview.bounding_box.height
513 surface = cairo.SVGSurface(fn , w, h)
514 cr = cairo.Context(surface)
515 svgview.matrix.translate(-svgview.bounding_box.x, -svgview.bounding_box.y)
516 svgview.paint(cr)
517 cr.show_page()
518 surface.flush()
519 surface.finish()
520 self.reporter.reportNote(" File ' %s ' saved successfully." % name )
521 self.status.push(0,"Wrote SVG file '%s'." % fn)
522 dialog.destroy()
523
524
525 def export_svg(self,widget):
526 svgview = View(self.view.canvas)
527 svgview.painter = ItemPainter()
528
529 # Update bounding boxes with a temporaly CairoContext
530 # (used for stuff like calculating font metrics)
531 tmpsurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 0, 0)
532 tmpcr = cairo.Context(tmpsurface)
533 svgview.update_bounding_box(tmpcr)
534 tmpcr.show_page()
535 tmpsurface.flush()
536
537 fn = 'demo.svg'
538 w, h = svgview.bounding_box.width, svgview.bounding_box.height
539 surface = cairo.SVGSurface(fn , w, h)
540 cr = cairo.Context(surface)
541 svgview.matrix.translate(-svgview.bounding_box.x, -svgview.bounding_box.y)
542 svgview.paint(cr)
543 cr.show_page()
544 surface.flush()
545 surface.finish()
546
547 self.status.push(0,"Wrote SVG file '%s'." % fn)
548
549 #def run_presaved_canvas(self,widget):
550 ##TODO: Separate
551 #if self.view.canvas.saved_model is not None:
552 #model = self.view.canvas.saved_model
553 #self.ascwrap.library.loadString(model,"canvasmodel")
554
555 T = self.ascwrap.library.findType("canvasmodel")
556 M = T.getSimulation('canvassim',True)
557 M.setSolver(ascpy.Solver("QRSlv"))
558 M.solve(ascpy.Solver("QRSlv"),ascpy.SolverReporter())
559
560 #for item in self.view.canvas.get_all_items():
561 #if hasattr(item, 'blockinstance'):
562 #bi = item.blockinstance
563 #for i in self.ascwrap.library.modules.getChildren()[0].getChildren():
564 #if str(bi.name) == str(i.getName()):
565 #bi.instance = i
566
567 def load_presaved_canvas(self,widget):
568 #TODO: Separate
569 print self.view.canvas.saved_data
570 try:
571 if self.view.canvas.saved_data is not None:
572 model = str(self.view.canvas)
573 self.ascwrap.library.loadString(model,"canvasmodel")
574 T = self.ascwrap.library.findType("canvasmodel")
575 M = T.getSimulation("canvassim",True)
576
577 def assignval(sim_inst, name):
578 if sim_inst.isAtom():
579 try:
580 sim_inst.setRealValue(self.view.canvas.saved_data[name])
581 except Exception,e:
582 print e
583 elif sim_inst.isRelation():
584 pass
585 else:
586 for i in sim_inst.getChildren():
587 k = name+"."+str(i.getName())
588 assignval(i,k)
589
590 for i in M.getChildren()[0].getChildren():
591 assignval(i, str(i.getName()))
592
593 for item in self.view.canvas.get_all_items():
594 if hasattr(item, 'blockinstance'):
595 bi = item.blockinstance
596 for i in M.getChildren()[0].getChildren():
597 if str(bi.name) == str(i.getName()):
598 bi.instance = i
599 self.status.push(0,"Canvasmodel state : %s"% self.view.canvas.canvasmodelstate)
600 except AttributeError:
601 self.status.push(0,"Canvasmodel state : Unsolved")
602
603 def run_canvas(self,widget):
604 #TODO: Separate
605 """
606 Exports canvas to ASCEND solver and attempts to solve it. Also provides realtime feedback.
607 """
608 self.undo_manager.reset()
609 model = str(self.view.canvas)
610 #print model
611 self.view.canvas.saved_model = model
612 self.view.canvas.saved_data = {}
613
614 self.ascwrap.library.loadString(model,"canvasmodel")
615 T = self.ascwrap.library.findType("canvasmodel")
616
617
618 self.M = T.getSimulation("canvassim",True)
619 self.M.setSolver(ascpy.Solver("QRSlv"))
620 self.reporter = ascpy.getReporter()
621 reporter = PopupSolverReporter(self,self.M.getNumVars())
622
623 try:
624 self.M.build()
625 except RuntimeError,e:
626 print "Couldn't build system: %s" % str(e)
627 self.status.push(0,"Couldn't build system: %s" % str(e));
628 return
629 #try:
630 #met=T.getMethod('on_load')
631 #self.M.run(met)
632 #except Exception,e:
633 #print "Couldn't run on_load method: %s"% str(e)
634 #return
635
636 self.status.push(0,"Solving with 'QRSlv'. Please Wait...")
637
638 try:
639 self.M.solve(ascpy.Solver("QRSlv"),reporter)
640 self.reporterrorblock(self.M)
641 except RuntimeError:
642 self.reporterrorblock(self.M)
643
644 for item in self.view.canvas.get_all_items():
645 if hasattr(item, 'blockinstance'):
646 bi = item.blockinstance
647 for i in self.M.getChildren()[0].getChildren():
648 if str(bi.name) == str(i.getName()):
649 bi.instance = i
650
651 #Storing solved variables into a dictionary which will be pickled
652 for i in self.M.getallVariables():
653 self.view.canvas.saved_data[str(i.getName())] = i.getValue()
654
655 def about(self, widget):
656 about = Gtk.AboutDialog()
657 about.set_program_name("ASCEND CANVAS")
658 about.set_version("0.9.6x alpha")
659 about.set_copyright("Carnegie Mellon University")
660 about.set_comments("Canvas - Based GUI Modeller for Energy Systems")
661 about.set_website("http://www.ascend.cheme.cmu.edu")
662 windowicon = Gtk.Image()
663 windowicon.set_from_file(os.path.join("../glade/ascend.svg"))
664 about.set_icon(windowicon.get_pixbuf())
665 about.set_logo(GdkPixbuf.Pixbuf.new_from_file("../glade/ascend.png"))
666 about.run()
667 about.destroy()
668
669 def dummy(self, widget):
670 dum = Gtk.MessageDialog(self, Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.ERROR, Gtk.ButtonsType.CLOSE, "Sorry ! This fuctionality is not implemented yet.")
671 dum.run()
672 dum.destroy()
673
674 def fileopen(self, widget):
675 dialog = Gtk.FileChooserDialog("Open..",self,Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
676 dialog.set_default_response(Gtk.ResponseType.OK)
677 filter = Gtk.FileFilter()
678 filter.set_name("Canvas Files")
679 filter.add_mime_type("Canvas Files/a4b")
680 filter.add_pattern("*.a4b")
681 dialog.add_filter(filter)
682 filter = Gtk.FileFilter()
683 filter.set_name("All files")
684 filter.add_pattern("*")
685 dialog.add_filter(filter)
686
687 res = dialog.run()
688 if res == Gtk.ResponseType.OK:
689 result = dialog.get_filename()
690 self.load_canvas_file(result)
691 dialog.destroy()
692
693 def load_canvas_file(self,filename):
694 #TODO: Separate
695 f = file(filename,"r")
696 try:
697 self.view.canvas = pickle.load(f)
698 if self.view.canvas.model_library is not None:
699 self.loadlib(self, self.view.canvas.model_library)
700 self.view.canvas.reattach_ascend(self.ascwrap.library,self.ascwrap.annodb)
701 self.view.canvas.update_now()
702 self.view.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse('#FFF'))
703 self.load_presaved_canvas(None)
704 self.reporter.reportError(" File %s successfully loaded." % filename)
705 self.status.push(0,"File %s Loaded." % filename)
706 self.view.canvas.filename = filename
707 except Exception,e:
708 self.reporter.reportError(" Error occured while attempting to load the file. File could not be loaded properly.")
709 print e
710 finally:
711 f.close()
712
713 def filesave(self, widget):
714 f = None
715 dialog = Gtk.FileChooserDialog("Save..", self, Gtk.FileChooserAction.SAVE, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_SAVE, Gtk.ResponseType.OK))
716 dialog.set_default_response(Gtk.ResponseType.OK)
717 if self.view.canvas.filestate == 0:
718 dialog.set_filename("untitled")
719 filter = Gtk.FileFilter()
720 filter.set_name("Canvas File")
721 filter.add_pattern("*.a4b")
722 dialog.add_filter(filter)
723 dialog.show()
724 dialog.set_do_overwrite_confirmation(True)
725 #dialog.connect("confirm-overwrite", self.confirm_overwrite_callback)
726 response = dialog.run()
727 if response == Gtk.ResponseType.OK:
728 name = dialog.get_filename()
729 if '.a4b' not in name:
730 name += '.a4b'
731 if f == None and f != name:
732 f = open(name, 'w')
733 try:
734 pickle.dump(self.view.canvas,f)
735 self.reporter.reportNote(" File ' %s ' saved successfully." % name )
736 self.status.push(0,"CanvasModel Saved.")
737 self.view.canvas.filestate = 1
738 self.view.canvas.filename = name
739 except Exception,e:
740 print "ERROR:",str(e)
741 b = obrowser.Browser("canvas",self.view.canvas)
742 d = Gtk.Dialog("Error",self,Gtk.DialogFlags.DESTROY_WITH_PARENT,(Gtk.STOCK_OK, Gtk.ResponseType.ACCEPT))
743 d.vbox.add(Gtk.Label(label=str(e)))
744 d.show_all()
745 d.run()
746 d.hide()
747 finally:
748 f.close()
749 dialog.destroy()
750
751 def confirm_overwrite_callback(self, widget):
752
753 uri = widget.get_filename()
754 if is_uri_read_only(uri):
755 if user_wants_to_replace_read_only_file (uri):
756 return Gtk.FILE_CHOOSER_CONFIRMATION_ACCEPT_FILENAME
757 else:
758 return Gtk.FILE_CHOOSER_CONFIRMATION_SELECT_AGAIN
759 else:
760 return Gtk.FILE_CHOOSER_CONFIRMATION_CONFIRM
761 return
762
763
764 def bp(self, widget = None):
765 if self.view.focused_item:
766 blockproperties.BlockProperties(self, self.view.focused_item).run()
767 else:
768 m = Gtk.MessageDialog(self, Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.ERROR, Gtk.ButtonsType.CLOSE, "No Block was selected! Please select a Block to view its properties.")
769 m.run()
770 m.destroy()
771
772 def reporterrorblock(self, sim):
773 #TODO: Separate
774 self.errortext = "Canvasmodel could NOT be solved \n Blocks which couldnot be solved:"
775
776 def checkifsolved(sim_inst, name):
777 if sim_inst.getType().isRefinedSolverVar():
778 try:
779 #if sim_inst.getStatus() == 2 :
780 # print name + " -> " + str(sim_inst.getStatus())
781 # self.errorvars.append(name)
782 if sim_inst.getStatus() == 3:
783 self.errorvars.append(name)
784
785 except Exception,e:
786 print e
787 elif sim_inst.isRelation():
788 pass
789 else:
790 for i in sim_inst.getChildren():
791 k = name+"."+str(i.getName())
792 checkifsolved(i,k)
793
794 self.errorvars = []
795 self.errorblocks = []
796 self.activevar = []
797 for i in sim.getChildren()[0].getChildren():
798 print i.getName()
799 checkifsolved(i, str(i.getName()))
800
801 print self.errorvars
802 for i in sim.getChildren()[0].getChildren():
803 for j in self.errorvars:
804 if str(i.getName()) in j:
805 if str(i.getName()) in self.errorblocks:
806 pass
807 else:
808 self.errortext += '\n'
809 self.errortext += str(i.getName()) #+' --> ' + ' couldnot be solved'
810 self.errorblocks.append(str(i.getName()))
811 print self.errorblocks
812 self.fill_blocks()
813
814
815 def fill_blocks(self):
816 cr = self.view.canvas._obtain_cairo_context()
817 for item in self.view.canvas.get_all_items():
818 if hasattr(item, 'blockinstance'):
819 bi = item.blockinstance
820 bi.color_r = 1
821 bi.color_g = 1
822 bi.color_b = 1
823 flag = 0
824 for item in self.view.canvas.get_all_items():
825 if hasattr(item, 'blockinstance'):
826 bi = item.blockinstance
827 for i in self.errorblocks:
828 if str(bi.name) == str(i):
829 bi.color_r = .5
830 bi.color_g = 0
831 bi.color_b = 0
832 flag = 1
833
834 print "updating canvas"
835 self.view.canvas.update_now()
836 if flag == 1:
837 self.view.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse('#F88'))
838 flag = 0
839 else:
840 self.view.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse('#AFA'))
841
842 def load_library_dialog(self,widget):
843 #TODO: separate
844 dialog = Gtk.FileChooserDialog('Load Library...',self, Gtk.FileChooserAction.OPEN,(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
845 dialog.set_default_response(Gtk.ResponseType.OK)
846 dialog.set_current_folder(os.path.join(self.ascwrap.defaultlibraryfolder))
847
848 filter = Gtk.FileFilter()
849 filter.set_name("Canvas Files")
850 filter.add_mime_type("Canvas Files/a4c")
851 filter.add_pattern("*.a4c")
852 dialog.add_filter(filter)
853
854 filter = Gtk.FileFilter()
855 filter.set_name("All files")
856 filter.add_pattern("*")
857 dialog.add_filter(filter)
858
859 res = dialog.run()
860 if res == Gtk.ResponseType.OK:
861 result = dialog.get_filename()
862 self.loadlib(lib_name = os.path.basename(result))
863 dialog.destroy()
864
865
866 def loadlib(self, widget = None, lib_name = None):
867 ##TODO: Separate
868 #if loadcondition == 1:
869 #if self.view.canvas.model_library == lib_name:
870 #m = Gtk.MessageDialog(self, Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.WARNING, Gtk.ButtonsType.CLOSE, "The selected Library is already loaded. ")
871 #m.run()
872 #m.destroy()
873 #return
874 #if self.view.canvas.get_all_items():
875 #m = Gtk.MessageDialog(self, Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.ERROR, Gtk.ButtonsType.CLOSE, "Unable to switch Library ! The canvas contains models from present Model Library. ")
876 #m.run()
877 #m.destroy()
878 #return
879
880 #print lib_path
881 self.ascwrap.load_library(lib_name)
882
883 self.view.canvas.model_library = lib_name
884
885 self.scroll.remove(self.blockiconview)
886 self.blockiconview = BlockIconView(self.ascwrap.canvas_blocks, self)
887 self.scroll.add(self.blockiconview)
888 self.show_all()
889
890 #self.status.push(0, " Library '%s' loaded :: Found %d block types." %(lib_name, (len(blocks))))
891
892 def get_libraries_from_folder(self,path=None):
893 'Returns a dictionary of library names with their paths'
894 if path == None:
895 return
896 libs = {}
897 locs = glob.glob(os.path.join(path,'*.a4c'))
898 for loc in locs:
899 name = loc.strip(path)
900 libs[name] = loc
901 return libs
902
903 def zoom(self, widget):
904 zoom = {'ZoomIn':1.2,'ZoomOut':0.8,'BestFit':1.0}
905 x = zoom[widget.get_name()]
906 self.act = self.act*x
907 self.view.zoom(x)
908
909
910 def fullscrn(self, widget):
911 try:
912 if self.flag == 1:
913 self.unfullscreen()
914 self.flag = 0
915 else:
916 self.fullscreen()
917 self.flag = 1
918 except:
919 self.fullscreen()
920 self.flag = 1
921
922
923 def on_contents_click(self, widget):
924 _help = help.Help(url="http://ascendwiki.cheme.cmu.edu/Canvas-based_modeller_for_ASCEND ")
925 _help.run()
926
927 def on_get_help_online_click(self, widget):
928 _help = help.Help(url="http://ascendwiki.cheme.cmu.edu/Canvas_Development")
929 _help.run()
930
931 def on_report_a_bug_click(self, widget):
932 _help = help.Help(url="http://ascendbugs.cheme.cmu.edu/report/")
933 _help.run()
934
935 def quit(self,args):
936 del(self.prefs)
937 self.destroy()

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22