/[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 2906 - (show annotations) (download) (as text)
Tue Apr 14 07:50:52 2015 UTC (2 years, 7 months ago) by adrian
File MIME type: text/x-python
File size: 30351 byte(s)
Fixed transient parent for about dialog issue
1 #!/usr/bin/env python
2
3 if __name__ == '__main__':
4 print "ERROR: ASCEND Canvas should now be invoked using the file 'canvas.py' instead of 'blocklist.py'."
5 exit(1)
6
7 from gi.repository import Gtk, GdkPixbuf, Gdk, GObject
8 import os
9 import os.path
10 import glob
11 import cairo
12 import ascpy
13
14 class BlockIconView(Gtk.IconView):
15 """
16 IconView containing the palette of BlockTypes available for use in the
17 canvas. The list of blocks is supplied currently as an initialisation
18 parameter, but it is intended that this would be dynamic in a final system.
19
20 It should be possible drag icons from the palette into the canvas, but
21 that is not yet implemented.
22 """
23 def __init__(self,blocks=None,app=None):
24 self.model = Gtk.ListStore(str, GdkPixbuf.Pixbuf)
25 self.app = app
26 self.otank = {}
27 try:
28 for b in blocks:
29 pixbuf = b.get_icon(48,48)
30 #print pixbuf
31 iter = self.model.append([b.name, pixbuf])
32 path = self.model.get_path(iter)
33 self.otank[path.to_string()] = b
34 except Exception as e:
35 pass
36
37 Gtk.IconView.__init__(self)
38 self.set_model(self.model)
39 self.set_text_column(0)
40 self.set_pixbuf_column(1)
41 self.set_columns(-1)
42 self.set_size_request(180,100)
43 self.connect("item-activated", self.item_activated)
44 self.connect("selection-changed", self.selection_changed)
45
46 def refresh_view():
47 pass
48
49 def selection_changed(self,iconview):
50 s = self.get_selected_items()
51 if len(s)==1:
52 b = self.otank[s[0].to_string()]
53 self.app.set_placement_tool(b)
54
55 def item_activated(self,iconview, path):
56 self.app.set_placement_tool(self.otank[path])
57
58
59 from gaphas import GtkView, View
60 from gaphas.tool import HoverTool, PlacementTool, HandleTool, ToolChain
61 from gaphas.tool import ItemTool, RubberbandTool
62 from gaphas.painter import ItemPainter
63 from blockconnecttool import BlockConnectTool
64 from blockline import BlockLine
65 from blockitem import DefaultBlockItem, GraphicalBlockItem
66 from contextmenutool import ContextMenuTool
67 from connectortool import ConnectorTool
68 from blockcanvas import BlockCanvas
69 from gaphas.tool import PanTool, ZoomTool
70 from blockinstance import BlockInstance
71 from solverreporterforcanvas import PopupSolverReporter
72 import canvasproperties
73 import blockproperties
74 import undo
75 from undo import UndoMonitorTool
76 import errorreporter
77 import pickle as pickle
78 import obrowser
79 import help
80 from preferences import Preferences
81
82 def BlockToolChain():
83 """
84 ToolChain for working with BlockCanvas, including several custom Tools.
85 """
86 chain = ToolChain()
87 chain.append(UndoMonitorTool())
88 chain.append(HoverTool())
89 chain.append(BlockConnectTool()) # for connect/disconnect of lines
90 chain.append(ConnectorTool()) # for creating new lines by drag from Port
91 chain.append(ContextMenuTool()) # right-click
92 # chain.append(LineSegmentTool()) # for moving line 'elbows'
93 chain.append(ItemTool())
94 chain.append(PanTool())
95 chain.append(ZoomTool())
96 chain.append(RubberbandTool())
97 return chain
98
99 class mainWindow(Gtk.Window):
100
101 menu_xml = '''<ui>
102 <menubar name='MenuBar'>
103 <menu action='File'>
104 <menuitem action='New' />
105 <menuitem action='Open' />
106 <menuitem action='Save' />
107 <menuitem action='SaveAs' />
108 <separator />
109 <menuitem action='Export' />
110 <separator />
111 <menuitem action='Library' />
112 <separator />
113 <menuitem action='Quit' />
114 </menu>
115 <menu action='Edit'>
116 <menuitem action='Undo' />
117 <menuitem action='Redo' />
118 <separator />
119 <menuitem action='BlockProperties' />
120 <menuitem action='Delete' />
121 </menu>
122 <menu action='View'>
123 <menuitem action='Fullscreen' />
124 <separator />
125 <menuitem action='ZoomIn' />
126 <menuitem action='ZoomOut' />
127 </menu>
128 <menu action='Tools'>
129 <menuitem action='Debug' />
130 <menuitem action='Run' />
131 <menuitem action='Preview' />
132 </menu>
133 <menu action='Help'>
134 <menuitem action='Development' />
135 <menuitem action='ReportBug' />
136 <menuitem action='About' />
137 </menu>
138 </menubar>
139 </ui>
140 '''
141
142 def __init__(self,library,options=None):
143 """
144 Initialise the application -- create all the widgets, and populate
145 the icon palette.
146 TODO: separate the icon palette into a separate method.
147 """
148 self.ascwrap= library
149 self.errorvars = []
150 self.errorblocks = []
151 self.status = Gtk.Statusbar()
152 self.temp = []
153 self.act = 1 #to be used for storing canvas zoom in/out related data.
154 # the Gaphas canvas
155 canvas = BlockCanvas()
156
157 # the main window
158 Gtk.Window.__init__(self)
159 self.iconok = self.render_icon(Gtk.STOCK_YES,Gtk.IconSize.MENU)
160 self.iconinfo = self.render_icon(Gtk.STOCK_DIALOG_INFO,Gtk.IconSize.MENU)
161 self.iconwarning = self.render_icon(Gtk.STOCK_DIALOG_WARNING,Gtk.IconSize.MENU)
162 self.iconerror = self.render_icon(Gtk.STOCK_DIALOG_ERROR,Gtk.IconSize.MENU)
163
164 self.set_title("ASCEND Canvas Modeller")
165 self.set_default_size(650,650)
166 self.connect("destroy", Gtk.main_quit)
167
168 windowicon = Gtk.Image()
169 windowicon.set_from_file(os.path.join('..','glade','ascend.svg'))
170 self.set_icon(windowicon.get_pixbuf())
171
172 vbox = Gtk.VBox()
173
174 ui_manager = Gtk.UIManager()
175 accelgroup = ui_manager.get_accel_group()
176 self.add_accel_group(accelgroup)
177
178 actiongroup = Gtk.ActionGroup('CanvasActionGroup')
179
180 self.prefs = Preferences()
181
182 actions = [('File', None, '_File')
183 ,('Quit', Gtk.STOCK_QUIT, '_Quit', None,'Quit the Program', self.quit)
184 ,('New', Gtk.STOCK_NEW,'_New',None,'Start a new Simulation', self.new)
185 ,('Open', Gtk.STOCK_OPEN,'_Open',None,'Open a saved Canvas file', self.fileopen)
186 ,('Save', Gtk.STOCK_SAVE,'_Save',None,'Open a saved Canvas file', self.save_canvas)
187 ,('SaveAs', Gtk.STOCK_SAVE_AS,'_Save As...',None,'Open a saved Canvas file', self.filesave)
188 ,('Export', Gtk.STOCK_PRINT, '_Export SVG', None,'Quit the Program', self.export_svg_as)
189 ,('Library', Gtk.STOCK_OPEN, '_Load Library...', '<Control>l','Load Library', self.load_library_dialog)
190 ,('Edit', None, '_Edit')
191 ,('Undo', Gtk.STOCK_UNDO, '_Undo', '<Control>z', 'Undo Previous Action', self.undo_canvas)
192 ,('Redo',Gtk.STOCK_REDO, '_Redo', '<Control>y', 'Redo Previous Undo', self.redo_canvas)
193 ,('BlockProperties',Gtk.STOCK_PROPERTIES, '_Block Properties', None, 'Edit Block Properties', self.bp)
194 ,('Delete', Gtk.STOCK_DELETE, '_Delete', 'Delete', 'Delete Selected Item', self.delblock)
195 ,('View', None, '_View')
196 ,('Fullscreen', Gtk.STOCK_FULLSCREEN, '_Full Screen', 'F11', 'Toggle Full Screen', self.fullscrn)
197 ,('ZoomIn', Gtk.STOCK_ZOOM_IN, '_Zoom In', None, 'Zoom In Canvas', self.zoom)
198 ,('ZoomOut', Gtk.STOCK_ZOOM_OUT, '_Zoom Out', None, 'Zoom Out Canvas', self.zoom)
199 #,('BestFit', Gtk.STOCK_ZOOM_FIT, '_Best Fit', None, 'Best Fit Canvas',self.zoom)
200 ,('Tools', None, '_Tools')
201 ,('Debug', None, '_Debug', None, 'View Instance Browser',self.debug_canvas)
202 ,('Run', Gtk.STOCK_EXECUTE, '_Run', None, 'Solve Canvas', self.run_canvas)
203 ,('Preview', Gtk.STOCK_PRINT_PREVIEW, '_Preview', None, 'Preview Generated Code', self.preview_canvas)
204 ,('Help', None, '_Help')
205 ,('Development', Gtk.STOCK_INFO, '_Development', None, 'Check Development', self.on_get_help_online_click)
206 ,('ReportBug', None, '_Report Bug', None, 'Report a Bug!', self.on_report_a_bug_click)
207 ,('About', Gtk.STOCK_ABOUT, '_About', None, 'About Us', self.about)
208 ]
209
210 actiongroup.add_actions(actions)
211
212 ui_manager.insert_action_group(actiongroup,0)
213 ui_manager.add_ui_from_string(self.menu_xml)
214
215 #Creating Menu Bar
216 menubar = ui_manager.get_widget('/MenuBar')
217 vbox.pack_start(menubar,False,False,0)
218
219 #Creating Tool Bar
220 '''The Toolbar Definations start here'''
221
222 tb = Gtk.Toolbar()
223 #Load Button
224 loadbutton = Gtk.ToolButton(Gtk.STOCK_OPEN)
225 loadbutton.connect("clicked",self.fileopen)
226 tb.insert(loadbutton,0)
227
228 #Save Button
229 savebutton = Gtk.ToolButton(Gtk.STOCK_SAVE)
230 savebutton.connect("clicked",self.save_canvas)
231 tb.insert(savebutton,1)
232
233 #Debug Button
234 debugbutton = Gtk.ToolButton(Gtk.STOCK_PROPERTIES)
235 debugbutton.set_label("Debug")
236 debugbutton.connect("clicked",self.debug_canvas)
237 tb.insert(debugbutton,2)
238
239 #Preview Button
240 previewb = Gtk.ToolButton(Gtk.STOCK_PRINT_PREVIEW)
241 previewb.set_label("Preview")
242 previewb.connect("clicked",self.preview_canvas)
243 tb.insert(previewb,3)
244
245 #Export Button
246 exportbutton = Gtk.ToolButton(Gtk.STOCK_CONVERT)
247 exportbutton.set_label("Export SVG")
248 exportbutton.connect("clicked",self.export_svg_as)
249 tb.insert(exportbutton,2)
250
251 #Run Button
252 runb = Gtk.ToolButton(Gtk.STOCK_EXECUTE)
253 runb.set_label("Run")
254 runb.connect("clicked",self.run_canvas)
255 tb.insert(runb, 4)
256
257 ##Custom Entry
258 #m_entry = Gtk.ToolButton(Gtk.STOCK_SAVE_AS)
259 #m_entry.set_label("Custom METHOD")
260 #m_entry.connect("clicked",self.custommethod)
261 #tb.insert(m_entry,5)
262
263 vbox.pack_start(tb, False, False,0)
264
265 # hbox occupies top part of vbox, with icons on left & canvas on right.
266 paned = Gtk.HPaned()
267
268 # the 'view' widget implemented by Gaphas
269 #gaphas.view.DEBUG_DRAW_BOUNDING_BOX = True
270 self.view = GtkView()
271 # workaround to provide proper adjustments
272 hadj = GObject.ParamSpecObject
273 hadj.name = "hadjustment"
274 self.view.do_set_property(hadj, 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.set_transient_for(self)
667 about.run()
668 about.destroy()
669
670 def dummy(self, widget):
671 dum = Gtk.MessageDialog(self, Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.ERROR, Gtk.ButtonsType.CLOSE, "Sorry ! This fuctionality is not implemented yet.")
672 dum.run()
673 dum.destroy()
674
675 def fileopen(self, widget):
676 dialog = Gtk.FileChooserDialog("Open..",self,Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
677 dialog.set_default_response(Gtk.ResponseType.OK)
678 filter = Gtk.FileFilter()
679 filter.set_name("Canvas Files")
680 filter.add_mime_type("Canvas Files/a4b")
681 filter.add_pattern("*.a4b")
682 dialog.add_filter(filter)
683 filter = Gtk.FileFilter()
684 filter.set_name("All files")
685 filter.add_pattern("*")
686 dialog.add_filter(filter)
687
688 res = dialog.run()
689 if res == Gtk.ResponseType.OK:
690 result = dialog.get_filename()
691 self.load_canvas_file(result)
692 dialog.destroy()
693
694 def load_canvas_file(self,filename):
695 #TODO: Separate
696 f = file(filename,"r")
697 try:
698 self.view.canvas = pickle.load(f)
699 if self.view.canvas.model_library is not None:
700 self.loadlib(self, self.view.canvas.model_library)
701 self.view.canvas.reattach_ascend(self.ascwrap.library,self.ascwrap.annodb)
702 self.view.canvas.update_now()
703 self.view.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse('#FFF'))
704 self.load_presaved_canvas(None)
705 self.reporter.reportSuccess(" File %s successfully loaded." % filename)
706 self.status.push(0,"File %s Loaded." % filename)
707 self.view.canvas.filename = filename
708 except Exception,e:
709 self.reporter.reportError(" Error occured while attempting to load the file. File could not be loaded properly.")
710 print e
711 finally:
712 f.close()
713
714 def filesave(self, widget):
715 f = None
716 dialog = Gtk.FileChooserDialog("Save..", self, Gtk.FileChooserAction.SAVE, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_SAVE, Gtk.ResponseType.OK))
717 dialog.set_default_response(Gtk.ResponseType.OK)
718 if self.view.canvas.filestate == 0:
719 dialog.set_filename("untitled")
720 filter = Gtk.FileFilter()
721 filter.set_name("Canvas File")
722 filter.add_pattern("*.a4b")
723 dialog.add_filter(filter)
724 dialog.show()
725 dialog.set_do_overwrite_confirmation(True)
726 #dialog.connect("confirm-overwrite", self.confirm_overwrite_callback)
727 response = dialog.run()
728 if response == Gtk.ResponseType.OK:
729 name = dialog.get_filename()
730 if '.a4b' not in name:
731 name += '.a4b'
732 if f == None and f != name:
733 f = open(name, 'w')
734 try:
735 pickle.dump(self.view.canvas,f)
736 self.reporter.reportNote(" File ' %s ' saved successfully." % name )
737 self.status.push(0,"CanvasModel Saved.")
738 self.view.canvas.filestate = 1
739 self.view.canvas.filename = name
740 except Exception,e:
741 print "ERROR:",str(e)
742 b = obrowser.Browser("canvas",self.view.canvas)
743 d = Gtk.Dialog("Error",self,Gtk.DialogFlags.DESTROY_WITH_PARENT,(Gtk.STOCK_OK, Gtk.ResponseType.ACCEPT))
744 d.vbox.add(Gtk.Label(label=str(e)))
745 d.show_all()
746 d.run()
747 d.hide()
748 finally:
749 f.close()
750 dialog.destroy()
751
752 def confirm_overwrite_callback(self, widget):
753
754 uri = widget.get_filename()
755 if is_uri_read_only(uri):
756 if user_wants_to_replace_read_only_file (uri):
757 return Gtk.FILE_CHOOSER_CONFIRMATION_ACCEPT_FILENAME
758 else:
759 return Gtk.FILE_CHOOSER_CONFIRMATION_SELECT_AGAIN
760 else:
761 return Gtk.FILE_CHOOSER_CONFIRMATION_CONFIRM
762 return
763
764
765 def bp(self, widget = None):
766 if self.view.focused_item:
767 blockproperties.BlockProperties(self, self.view.focused_item).run()
768 else:
769 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.")
770 m.run()
771 m.destroy()
772
773 def reporterrorblock(self, sim):
774 #TODO: Separate
775 self.errortext = "Canvasmodel could NOT be solved \n Blocks which couldnot be solved:"
776
777 def checkifsolved(sim_inst, name):
778 if sim_inst.getType().isRefinedSolverVar():
779 try:
780 #if sim_inst.getStatus() == 2 :
781 # print name + " -> " + str(sim_inst.getStatus())
782 # self.errorvars.append(name)
783 if sim_inst.getStatus() == 3:
784 self.errorvars.append(name)
785
786 except Exception,e:
787 print e
788 elif sim_inst.isRelation():
789 pass
790 else:
791 for i in sim_inst.getChildren():
792 k = name+"."+str(i.getName())
793 checkifsolved(i,k)
794
795 self.errorvars = []
796 self.errorblocks = []
797 self.activevar = []
798 for i in sim.getChildren()[0].getChildren():
799 print i.getName()
800 checkifsolved(i, str(i.getName()))
801
802 print self.errorvars
803 for i in sim.getChildren()[0].getChildren():
804 for j in self.errorvars:
805 if str(i.getName()) in j:
806 if str(i.getName()) in self.errorblocks:
807 pass
808 else:
809 self.errortext += '\n'
810 self.errortext += str(i.getName()) #+' --> ' + ' couldnot be solved'
811 self.errorblocks.append(str(i.getName()))
812 print self.errorblocks
813 self.fill_blocks()
814
815
816 def fill_blocks(self):
817 cr = self.view.canvas._obtain_cairo_context()
818 for item in self.view.canvas.get_all_items():
819 if hasattr(item, 'blockinstance'):
820 bi = item.blockinstance
821 bi.color_r = 1
822 bi.color_g = 1
823 bi.color_b = 1
824 flag = 0
825 for item in self.view.canvas.get_all_items():
826 if hasattr(item, 'blockinstance'):
827 bi = item.blockinstance
828 for i in self.errorblocks:
829 if str(bi.name) == str(i):
830 bi.color_r = .5
831 bi.color_g = 0
832 bi.color_b = 0
833 flag = 1
834
835 print "updating canvas"
836 self.view.canvas.update_now()
837 if flag == 1:
838 self.view.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse('#F88'))
839 flag = 0
840 else:
841 self.view.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse('#AFA'))
842
843 def load_library_dialog(self,widget):
844 #TODO: separate
845 dialog = Gtk.FileChooserDialog('Load Library...',self, Gtk.FileChooserAction.OPEN,(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
846 dialog.set_default_response(Gtk.ResponseType.OK)
847 dialog.set_current_folder(os.path.join(self.ascwrap.defaultlibraryfolder))
848
849 filter = Gtk.FileFilter()
850 filter.set_name("Canvas Files")
851 filter.add_mime_type("Canvas Files/a4c")
852 filter.add_pattern("*.a4c")
853 dialog.add_filter(filter)
854
855 filter = Gtk.FileFilter()
856 filter.set_name("All files")
857 filter.add_pattern("*")
858 dialog.add_filter(filter)
859
860 res = dialog.run()
861 if res == Gtk.ResponseType.OK:
862 result = dialog.get_filename()
863 self.loadlib(lib_name = os.path.basename(result))
864 dialog.destroy()
865
866
867 def loadlib(self, widget = None, lib_name = None):
868 ##TODO: Separate
869 #if loadcondition == 1:
870 #if self.view.canvas.model_library == lib_name:
871 #m = Gtk.MessageDialog(self, Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.WARNING, Gtk.ButtonsType.CLOSE, "The selected Library is already loaded. ")
872 #m.run()
873 #m.destroy()
874 #return
875 #if self.view.canvas.get_all_items():
876 #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. ")
877 #m.run()
878 #m.destroy()
879 #return
880
881 #print lib_path
882 self.ascwrap.load_library(lib_name)
883
884 self.view.canvas.model_library = lib_name
885
886 self.scroll.remove(self.blockiconview)
887 self.blockiconview = BlockIconView(self.ascwrap.canvas_blocks, self)
888 self.scroll.add(self.blockiconview)
889 self.show_all()
890
891 #self.status.push(0, " Library '%s' loaded :: Found %d block types." %(lib_name, (len(blocks))))
892
893 def get_libraries_from_folder(self,path=None):
894 'Returns a dictionary of library names with their paths'
895 if path == None:
896 return
897 libs = {}
898 locs = glob.glob(os.path.join(path,'*.a4c'))
899 for loc in locs:
900 name = loc.strip(path)
901 libs[name] = loc
902 return libs
903
904 def zoom(self, widget):
905 zoom = {'ZoomIn':1.2,'ZoomOut':0.8,'BestFit':1.0}
906 x = zoom[widget.get_name()]
907 self.act = self.act*x
908 self.view.zoom(x)
909
910
911 def fullscrn(self, widget):
912 try:
913 if self.flag == 1:
914 self.unfullscreen()
915 self.flag = 0
916 else:
917 self.fullscreen()
918 self.flag = 1
919 except:
920 self.fullscreen()
921 self.flag = 1
922
923
924 def on_contents_click(self, widget):
925 _help = help.Help(url="http://ascendwiki.cheme.cmu.edu/Canvas-based_modeller_for_ASCEND ")
926 _help.run()
927
928 def on_get_help_online_click(self, widget):
929 _help = help.Help(url="http://ascendwiki.cheme.cmu.edu/Canvas_Development")
930 _help.run()
931
932 def on_report_a_bug_click(self, widget):
933 _help = help.Help(url="http://ascendbugs.cheme.cmu.edu/report/")
934 _help.run()
935
936 def quit(self,args):
937 del(self.prefs)
938 self.destroy()

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