MAJ terminée. Nous sommes passés en version 14.6.2 . Pour consulter les "releases notes" associées c'est ici :

https://about.gitlab.com/releases/2022/01/11/security-release-gitlab-14-6-2-released/
https://about.gitlab.com/releases/2022/01/04/gitlab-14-6-1-released/

chart_simul_controler.py 22.7 KB
Newer Older
VIGNET Pierre's avatar
VIGNET Pierre committed
1
2
3
## Filename    : chart_simul_controler.py
## Author(s)   : Michel Le Borgne
## Created     : 04/2010
4
5
## Revision    :
## Source      :
VIGNET Pierre's avatar
VIGNET Pierre committed
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
##
## Copyright 2012 : IRISA/IRSET
##
## This library is free software; you can redistribute it and/or modify it
## under the terms of the GNU General Public License  published
## by the Free Software Foundation; either version 2.1 of the License, or
## any later version.
##
## This library is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF
## MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  The software and
## documentation provided here under is on an "as is" basis, and IRISA has
## no obligations to provide maintenance, support, updates, enhancements
## or modifications.
## In no event shall IRISA be liable to any party for direct, indirect,
## special, incidental or consequential damages, including lost profits,
## arising out of the use of this software and its documentation, even if
## IRISA have been advised of the possibility of such damage.  See
## the GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this library; if not, write to the Free Software Foundation,
## Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
##
## The original code contained here was initially developed by:
##
##     Michel Le Borgne.
##     IRISA
##     Symbiose team
##     IRISA  Campus de Beaulieu
36
37
##     35042 RENNES Cedex, FRANCE
##
VIGNET Pierre's avatar
VIGNET Pierre committed
38
39
40
41
42
43
44
45
46
47
48
##
## Contributor(s): Geoffroy Andrieux, Nolwenn Le Meur
##
"""
Controller and auxiliary widgets for simulations with gui.
"""
import gtk
from time import clock


from chart_chrono import ChartChrono
49
from cadbiom_gui.gt_gui.utils.warn import cancel_warn
50
from cadbiom.models.guard_transitions.simulator.simul_exceptions import \
VIGNET Pierre's avatar
VIGNET Pierre committed
51
                              SimulException, SimulStopException
52
53
54
from cadbiom.models.guard_transitions.simulator.chart_simul import ChartSimulator
from cadbiom.models.guard_transitions.simulator.simul_aux import ModelExtractorVisitor
from cadbiom.models.guard_transitions.analyser.ana_visitors import FrontierVisitor
55
56
57
58
from cadbiom_gui.gt_gui.utils.listDisplay  import ToggleList
from cadbiom_gui.gt_gui.utils.fileHandling import FileChooser

import pkg_resources
VIGNET Pierre's avatar
VIGNET Pierre committed
59
60
61
62
63

class ChartSimulControler(object):
    """
    Control different parameters of a simulation and display panel
    """
64
    def __init__(self, emvc, sim_option, reporter,
VIGNET Pierre's avatar
VIGNET Pierre committed
65
66
67
68
69
70
71
72
                 init_places = None, icseq=None, parent = None):
        # loading and initializing the simulator model
        self.edit_mvc = emvc
        self.model = emvc.model                    # chart model
        self.option = sim_option                   # free clock treatment option
        self.reporter = reporter                   # display error messages
        self.sim = ChartSimulator()                # simulation model
        self.__reload = True
73
        if icseq: # simulation with conditions from checker
VIGNET Pierre's avatar
VIGNET Pierre committed
74
75
76
77
78
79
80
81
            self.sim.set_act_input_stream(icseq)
            self.__reload = False
        if init_places:
            self.__reload = False
        self.sim.build(self.model, sim_option, reporter)
        if reporter.error:
            DisplayError(reporter, self.model.name)
            return
82

VIGNET Pierre's avatar
VIGNET Pierre committed
83
84
85
86
        self.init_places = init_places
        if self.init_places:
            self.sim.simul_init_places(self.init_places)
        else:
87
88
            self.sim.simul_init()

VIGNET Pierre's avatar
VIGNET Pierre committed
89
90
91
92
93
94
        self.max_step = 0
        self.tempo = 0.0
        self.stop = False
        self.selected_chrono = False
        self.main_window = None
        self.selected_window = None
95

VIGNET Pierre's avatar
VIGNET Pierre committed
96
        # graphical interface
97
        # Set the Glade
98
99
100
101
102
        template = pkg_resources.resource_filename(
            __name__,
            "../chart_glade/chart_simulator.glade"
        )
        self.wtree = gtk.glade.XML(template)
103

VIGNET Pierre's avatar
VIGNET Pierre committed
104
105
106
107
108
109
110
        # Get the Main Window, and connect the "destroy" event
        self.main_window = self.wtree.get_widget("window1")
        self.main_window.set_title("Simulation: "+self.model.name)
        if (self.main_window):
            self.main_window.connect("destroy", self.on_destroy)
        self.main_window.set_position(gtk.WIN_POS_CENTER)
        self.main_window.set_keep_above(True)
111

VIGNET Pierre's avatar
VIGNET Pierre committed
112
113
114
115
116
        # frontier button (disconnected when icseq are computed)
        button = self.wtree.get_widget("frontier_button")
        button.connect("clicked", self.on_select_front)
        if icseq:
            button.set_sensitive(False)
117

VIGNET Pierre's avatar
VIGNET Pierre committed
118
119
120
121
122
        # whole button (disconnected when ic are computed)
        button = self.wtree.get_widget("whole_button")
        button.connect("clicked", self.on_select_whole)
        if icseq:
            button.set_sensitive(False)
123

VIGNET Pierre's avatar
VIGNET Pierre committed
124
125
126
        # start button
        button = self.wtree.get_widget("startbutton")
        button.connect("clicked", self.on_start)
127

VIGNET Pierre's avatar
VIGNET Pierre committed
128
129
130
        # chrono nutton
        button = self.wtree.get_widget("chronobutton")
        button.connect("clicked", self.on_chrono)
131

VIGNET Pierre's avatar
VIGNET Pierre committed
132
133
134
135
136
137
138
        # input file choser (disconnected when ic are computed)
        button = self.wtree.get_widget("input_file_button")
        if not self.sim.has_input():
            button.set_sensitive(False)
        button.connect("clicked", self.on_input_file_selected)
        if icseq:
            button.set_sensitive(False)
139

VIGNET Pierre's avatar
VIGNET Pierre committed
140
141
142
        # step button
        button = self.wtree.get_widget("stepbutton")
        button.connect("clicked", self.on_step_simul)
143

VIGNET Pierre's avatar
VIGNET Pierre committed
144
145
146

        # check button for chronogram
        self.cb_chrono = self.wtree.get_widget("cb_chrono")
147

VIGNET Pierre's avatar
VIGNET Pierre committed
148
149
        # nb of steps widget
        self.nb_step_entry = self.wtree.get_widget("nbsteps")
150

VIGNET Pierre's avatar
VIGNET Pierre committed
151
152
153
154
        # slider
        self.range = self.wtree.get_widget("hscale1")
        self.range.set_update_policy(gtk.UPDATE_DISCONTINUOUS)
        self.range.connect("value_changed", self.on_delay)
155

VIGNET Pierre's avatar
VIGNET Pierre committed
156
157
158
        # init button"
        button = self.wtree.get_widget("initbutton")
        button.connect("clicked", self.on_init)
159

VIGNET Pierre's avatar
VIGNET Pierre committed
160
161
162
163
164
        # reload button (disconnected when using computed input clocks)
        button = self.wtree.get_widget("reloadbutton")
        button.connect("clicked", self.on_reload)
        if not self.__reload:
            button.set_sensitive(False)
165

VIGNET Pierre's avatar
VIGNET Pierre committed
166
167
168
169
        # extract button
        button = self.wtree.get_widget("extractbutton1")
        button.connect("clicked", self.on_extract, False)
        button = self.wtree.get_widget("extractbutton2")
170
171
        button.connect("clicked", self.on_extract, True)

VIGNET Pierre's avatar
VIGNET Pierre committed
172
173
174
175
176
177
178
179
180
181
        # register itself for parent or emvc
        if parent:
            parent.win_register(self)
        else:
            self.edit_mvc.win_register(self)
        self.parent = parent

        # display
        self.main_window.show_all()
        #gtk.main()
182

VIGNET Pierre's avatar
VIGNET Pierre committed
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
    def on_destroy(self, widget):
        """
        destroy the windows after all secondary windows
        """
        if self.selected_window:
            self.selected_window.destroy()
        if self.sim.chrono:
            self.sim.chrono.window.destroy()
        self.model.clean()
        self.model.notify()
        if self.parent:
            self.parent.win_remove(self)
        else:
            self.edit_mvc.win_remove(self)
        if self.main_window:
            self.main_window.destroy()
199

VIGNET Pierre's avatar
VIGNET Pierre committed
200
201
202
203
204
    def destroy(self):
        """
        Used if chart_simul_controller is itself a secondary window
        """
        self.on_destroy(None)
205

VIGNET Pierre's avatar
VIGNET Pierre committed
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
    def on_step_simul(self, widget):
        """
        callback for step by step simulation
        """
        # in case a selected chrono is open"
        if self.selected_chrono:
            self.sim.chrono.destroy()
            self.sim.chrono = None
            self.selected_chrono = False
        if self.sim.has_input() and not self.sim.input_buffer:
            # inputs present and no input file
            cancel_warn("Set input file before simulation")
            return
        try:
            self.sim.simul_step()
            if self.sim.chrono:
                self.sim.chrono.register(self.sim)
                self.sim.chrono.update()
        except SimulStopException:
            cancel_warn("Simulation reached end of input")
        except SimulException , exc:
            cancel_warn("Problem in simulation: " + exc.__str__())
228
229


VIGNET Pierre's avatar
VIGNET Pierre committed
230
231
232
233
    def on_input_file_selected(self, widget):
        """
        chose an input file
        """
234
        fch = FileChooser("Input file", "", "*", save_window=False)
VIGNET Pierre's avatar
VIGNET Pierre committed
235
        fch.do_action(self.set_input_file)
236

VIGNET Pierre's avatar
VIGNET Pierre committed
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
    def set_input_file(self, filename):
        """
        connect an input file
        """
        inputfile = open(filename, 'r')
        fline = inputfile.readline()
        line_split = fline.split()
        inputfile.close()
        # test type of file on first line
        if line_split[0] == "$inputs": # old coded input
            try:
                self.sim.set_cfile_input_stream(filename)
            except Exception , exc:
                cancel_warn("Error in coded input file loading" + exc.__str__())
            return
        elif  line_split[0] == "%": # activated input
            try:
                self.sim.set_act_file_input_stream(filename)
            except Exception , exc:
                mess = "Error in active input file loading" + exc.__str__()
                cancel_warn(mess)
            return
259
        else: # assume scenario
VIGNET Pierre's avatar
VIGNET Pierre committed
260
261
262
263
            try:
                self.sim.set_sce_file_input_stream(filename)
            except Exception , exc:
                cancel_warn("Error in scenario loading" + exc.__str__())
264
            return
VIGNET Pierre's avatar
VIGNET Pierre committed
265
266
267
268
269
270
271
272
273
274


    def on_init(self, widget):
        """
        initialisation of the simulator
        """
        if self.sim.init_places:
            self.sim.simul_init_places(self.sim.init_places)
        else:
            self.sim.simul_init() # standard init from graphics
275

VIGNET Pierre's avatar
VIGNET Pierre committed
276
277
278
279
280
281
282
283
284
285
286
        if self.sim.input_buffer:
            self.sim.input_buffer.rewind()
        if self.sim.chrono:
            if self.selected_chrono:
                self.sim.chrono.window.destroy()
                self.sim.chrono = None
                self.selected_chrono = False
            else:
                self.sim.chrono.rewind()
                self.sim.chrono.register(self.sim)
                self.sim.chrono.update()
287

VIGNET Pierre's avatar
VIGNET Pierre committed
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
    def on_start(self, widget):
        """
        start a simulation
        """
        # check inputs
        if self.sim.has_input() and not self.sim.input_buffer:
            # inputs present and no input file
            cancel_warn("Set input file before simulation")
            return
        # read nb of steps
        max_step = self.nb_step_entry.get_text()
        if max_step == "":
            self.max_step = 0
            cancel_warn("Set number of simulation steps")
        else:
            self.max_step = int(max_step)
        self.step_count = 0
        self.stop = False
#        a = threading.Thread(None, self.loop, None, (), None)
#        a.start()
#        return
        # selected chrono
        if self.cb_chrono.get_active():
            if self.sim.chrono:
                self.sim.chrono.destroy()
            self.sim.chrono = ChartChrono.for_trajectory(self.sim)
            self.selected_chrono = True
        self.loop()
        if self.selected_chrono:
            self.sim.chrono.display_selected_chrono()
318

VIGNET Pierre's avatar
VIGNET Pierre committed
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
    def loop(self):
        """
        temporized loop for automatic simulation
        """
        if self.sim.chrono:
            self.sim.chrono.register(self.sim)
        while not self.stop and self.step_count < self.max_step:
            start_time = clock()
            try:
                self.sim.simul_step()
                self.step_count = self.step_count + 1
            except SimulStopException:
                cancel_warn("Simulation reached end of input")
                return
            except SimulException , exc:
                cancel_warn("Problem in simulation:" + exc.__str__())
                return
            self.model.notify()
            if self.sim.chrono:
                self.sim.chrono.register(self.sim)
                self.sim.chrono.update()
            # tempo
            if self.tempo > 0.01:
                time = clock()
                delay = time - start_time
                while delay < self.tempo:
                    time = clock()
                    delay = time - start_time

    def on_chrono(self, widget):
        """
        setup chronogram
        """
        if not self.sim.chrono:
            # logical analyser
354
            self.sim.chrono = ChartChrono.from_simulation_model(self.sim)
VIGNET Pierre's avatar
VIGNET Pierre committed
355
356
357
358
359
360
            self.sim.chrono.register(self.sim)
            self.sim.chrono.update()
        else:
            self.sim.chrono.destroy()
            self.sim.chrono = None
            self.selected_chrono = False
361

VIGNET Pierre's avatar
VIGNET Pierre committed
362
363
364
365
366
    def on_delay(self, widget):
        """
        adjust the simulation timer
        """
        self.tempo = self.range.get_value()/50.0
367

VIGNET Pierre's avatar
VIGNET Pierre committed
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
    def on_reload(self, widget):
        """
        reset the simulator
        """
        if not self.__reload:
            cancel_warn("No reload allowed")
            return
        if self.sim.chrono:
            self.sim.chrono.destroy()
        input_file = self.sim.input_file
        self.sim = ChartSimulator()
        self.reporter.error = False
        self.sim.build(self.model, self.option, self.reporter)
        if self.reporter.error:
            DisplayError(self.reporter, self.model)
            return
        if input_file:
            try:
                self.set_input_file(input_file)
            except SimulException, exc:
                self.sim.input_buffer = None
                cancel_warn ("old input file inadequate - redefine input")
        if self.sim.chrono:
            self.sim.chrono.destroy()
            self.sim.chrono = ChartChrono.from_simulation_model(self.sim)
        if self.init_places:
            self.sim.simul_init_places(self.init_places)
        else:
            self.sim.simul_init() # standard init from graphics
        if self.sim.chrono:
            self.sim.chrono.register(self.sim)
            self.sim.chrono.update()
        self.max_step = 0
        self.tempo = 0.0
        self.stop = False
403

VIGNET Pierre's avatar
VIGNET Pierre committed
404
405
406
407
408
409
410
411
412
413
414
    def on_extract(self, widget, ex_type):
        """
        extract the part of a model used in last simulation
        """
        if self.sim.get_step() < 2:
            return
        mex = ModelExtractorVisitor('sim_extract', ex_type)
        self.model.accept(mex)
        model = mex.sub_model
        self.edit_mvc.charter.add_display_mvc(model.name, model, False)
        self.edit_mvc.charter.do_layout(None,"hierarchical_LR")
415

VIGNET Pierre's avatar
VIGNET Pierre committed
416
417
418
419
420
    def on_select_front(self, widget):
        """
        selection of frontier activated places at initialization
        """
        self.selected_window = SelectPlaceWindow(self, True)
421

VIGNET Pierre's avatar
VIGNET Pierre committed
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
    def on_select_whole(self, widget):
        """
        selection of activated places at initialization
        """
        self.selected_window = SelectPlaceWindow(self, False)




class DisplayError(object):
    """
    auxiliary widget for simulator
    """
    def __init__(self, report, model_name, text=None):
        self.main_window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        #self.main_window.connect("destroy", gtk.main_quit)
        self.main_window.set_title("Compiler errors or info: " + model_name)
        self.main_window.set_position(gtk.WIN_POS_CENTER)
        self.main_window.set_keep_above(True)
441
        self.main_window.set_default_size(500, 300)
442

VIGNET Pierre's avatar
VIGNET Pierre committed
443
444
445
446
        scroll = gtk.ScrolledWindow()
        scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        scroll.set_shadow_type(gtk.SHADOW_IN)
        self.main_window.add(scroll)
447

VIGNET Pierre's avatar
VIGNET Pierre committed
448
449
450
451
452
453
454
455
        write = gtk.TextView()
        if report:
            write.get_buffer().set_text(report.memory)
        else:
            write.get_buffer().set_text(text)
        scroll.add_with_viewport(write)
        self.main_window.show_all()
        #gtk.main()
456

VIGNET Pierre's avatar
VIGNET Pierre committed
457
458
459
460
461
class SelectPlaceWindow(object):
    """
    Select the activated place for initialization
    """
    def __init__(self,  simulator, frontier_bool):
462

VIGNET Pierre's avatar
VIGNET Pierre committed
463
464
465
        self.simulator = simulator
        # graphical interface
        # Set the Glade file
466
467
468
469
470
        template = pkg_resources.resource_filename(
            __name__,
            "../chart_glade/simu_places.glade"
        )
        self.wtree = gtk.glade.XML(template)
471

VIGNET Pierre's avatar
VIGNET Pierre committed
472
473
474
475
476
477
        # Get the Main Window, and connect the "destroy" event
        self.window = self.wtree.get_widget("window1")
        self.window.set_title("Selected window")
        self.window.set_size_request(250, 400)
        self.window.set_position(gtk.WIN_POS_NONE)
        self.window.set_keep_above(True)
478

VIGNET Pierre's avatar
VIGNET Pierre committed
479
480
481
        place_notebook = self.wtree.get_widget("place_notebook")
        # search
        if frontier_bool:
482
            self.search_area = ToggleFrontier(self.simulator.model,
VIGNET Pierre's avatar
VIGNET Pierre committed
483
484
                                              place_notebook, "Frontier")
        else:
485
486
            self.search_area = ToggleWholeModel(self.simulator.model,
                                                place_notebook,
VIGNET Pierre's avatar
VIGNET Pierre committed
487
488
                                                "Simple node list")

489

VIGNET Pierre's avatar
VIGNET Pierre committed
490
491
492
493
        # button
        button = self.wtree.get_widget("select_button")
        button.connect("clicked", self.on_select)
        button = self.wtree.get_widget("unselect_button")
494
        button.connect("clicked", self.on_deselect)
VIGNET Pierre's avatar
VIGNET Pierre committed
495
496
497
498
499
500
        button = self.wtree.get_widget("save_button")
        button.connect("clicked", self.on_save)
        button = self.wtree.get_widget("load_button")
        button.connect("clicked", self.on_load)
        button = self.wtree.get_widget("validate_button")
        button.connect("clicked", self.on_validate)
501

VIGNET Pierre's avatar
VIGNET Pierre committed
502
503
        # display
        self.window.show_all()
504

VIGNET Pierre's avatar
VIGNET Pierre committed
505
506
507
508
509

    def destroy(self):
        """
        as usual for aux widget
        """
510
511
        self.window.destroy()

VIGNET Pierre's avatar
VIGNET Pierre committed
512
513
514
515
    def on_select(self, widget):
        """
        ???
        """
516
        self.search_area.sn_viewer.select_all()
517

518
    def on_deselect(self, widget):
VIGNET Pierre's avatar
VIGNET Pierre committed
519
520
521
        """
        ???
        """
522
        self.search_area.sn_viewer.deselect_all()
523

VIGNET Pierre's avatar
VIGNET Pierre committed
524
525
526
527
    def on_save(self, widget):
        """
        open a window to save initialization
        """
528
        choice = gtk.FileChooserDialog("Save initialization", None,
VIGNET Pierre's avatar
VIGNET Pierre committed
529
530
531
532
                                       gtk.FILE_CHOOSER_ACTION_SAVE,
                                       (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
                                        gtk.STOCK_SAVE, gtk.RESPONSE_OK))
        choice.set_default_response(gtk.RESPONSE_OK)
533

VIGNET Pierre's avatar
VIGNET Pierre committed
534
535
536
537
538
        #add a filter to see only txt files
        filter = gtk.FileFilter()
        filter.set_name("text files")
        filter.add_pattern("*.txt")
        choice.add_filter(filter)
539

VIGNET Pierre's avatar
VIGNET Pierre committed
540
541
542
543
544
        #add a filter to see all
        no_filter = gtk.FileFilter()
        no_filter.set_name("all")
        no_filter.add_pattern("*")
        choice.add_filter(no_filter)
545

VIGNET Pierre's avatar
VIGNET Pierre committed
546
547
548
549
550
551
552
        response = choice.run()
        if response == gtk.RESPONSE_OK:
            self.create_init_file(choice.get_filename())
        elif response == gtk.RESPONSE_CANCEL:
            pass
            #print 'Closed, no files selected'
        choice.destroy()
553

VIGNET Pierre's avatar
VIGNET Pierre committed
554
555
556
557
    def on_load(self, widget):
        """
        open a window to search xml file coming from PID database
        """
558
        choice = gtk.FileChooserDialog("Import from xml", None,
VIGNET Pierre's avatar
VIGNET Pierre committed
559
560
561
562
                                       gtk.FILE_CHOOSER_ACTION_OPEN,
                                       (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
                                        gtk.STOCK_OPEN, gtk.RESPONSE_OK))
        choice.set_default_response(gtk.RESPONSE_OK)
563

VIGNET Pierre's avatar
VIGNET Pierre committed
564
565
566
567
568
        #add a filter to see only xml files
        filter = gtk.FileFilter()
        filter.set_name("text files")
        filter.add_pattern("*.txt")
        choice.add_filter(filter)
569

VIGNET Pierre's avatar
VIGNET Pierre committed
570
571
572
573
574
        #add a filter to see all
        no_filter = gtk.FileFilter()
        no_filter.set_name("all")
        no_filter.add_pattern("*")
        choice.add_filter(no_filter)
575

VIGNET Pierre's avatar
VIGNET Pierre committed
576
577
578
579
580
581
582
        response = choice.run()
        if response == gtk.RESPONSE_OK:
            self.load_init_file(choice.get_filename())
        elif response == gtk.RESPONSE_CANCEL:
            #print 'Closed, no files selected'
            pass
        choice.destroy()
583

VIGNET Pierre's avatar
VIGNET Pierre committed
584
585
586
587
588
589
590
591
592
593
594
595
    def on_validate(self, widget):
        """
        validate the choice of activated places
        """
        self.set_places()
        self.destroy()

    def create_init_file(self, file_name):
        """
        make a txt file with the current selected places
        """
        file = open(file_name,'w')
596
        list_of_places = self.search_area.get_selected_items()
VIGNET Pierre's avatar
VIGNET Pierre committed
597
        for place in list_of_places :
598
            file.write(str(place)+'\n')
VIGNET Pierre's avatar
VIGNET Pierre committed
599
600
        file.close()
        return
601

VIGNET Pierre's avatar
VIGNET Pierre committed
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
    def load_init_file(self, file_name):
        """
        load a file to initialize the simulator
        """
        list_of_places = []
        file = open(file_name,'r')
        for line in file:
            name = line[:-1]
            if name not in self.search_area.list_nodes :
                cancel_warn("Name in the file not in the model")
                return
            list_of_places.append(name)
        self.search_area.sn_viewer.set_selected_items(list_of_places)
#        self.simulator.sim.simul_init_places(list_of_places)
#        self.destroy()

    def set_places(self):
        """
        set the chosen activated places
        """
622
623
        self.simulator.init_places = self.search_area.get_selected_items()
        skw = list(self.simulator.init_places)
VIGNET Pierre's avatar
VIGNET Pierre committed
624
625
626
627
628
629
630
631
632
633
        self.simulator.sim.simul_init_places(skw)

class ToggleWholeModel(object):
    """
    List of simple nodes for searching
    """
    def __init__(self, model, notebook, label):
        self.model = model
        self.model_changed = True
        self.notebook = notebook
634

VIGNET Pierre's avatar
VIGNET Pierre committed
635
636
637
638
639
640
641
642
643
644
645
        # simple nodes
        sn_frame = gtk.Frame()
        vbox = gtk.VBox(False, 0)
        sn_frame.add(vbox)
        # simple nodes list
        self.sn_viewer = ToggleList()
        label = gtk.Label(label)
        # wrap into scrollwindow
        scroll = gtk.ScrolledWindow()
        scroll.add_with_viewport(self.sn_viewer)
        vbox.pack_start(scroll, True, True, 0)
646

VIGNET Pierre's avatar
VIGNET Pierre committed
647
        notebook.append_page(sn_frame, label)
648

VIGNET Pierre's avatar
VIGNET Pierre committed
649
650
651
652
653
654
        # get node names
        lnode = model.get_simple_node_names()
        lnode.sort()
        self.list_nodes = lnode
        # display node names
        self.sn_viewer.refresh(lnode)
655

656
    def get_selected_items(self):
VIGNET Pierre's avatar
VIGNET Pierre committed
657
658
659
660
        """
        retrieve the selected items
        """
        return self.sn_viewer.get_selected_items()
661

VIGNET Pierre's avatar
VIGNET Pierre committed
662
663
664
665
666
667
class ToggleFrontier(ToggleWholeModel):
    """
    List of frontier nodes for searching
    """
    def __init__(self, model, notebook, label):
        ToggleWholeModel.__init__(self, model, notebook, label)
668

VIGNET Pierre's avatar
VIGNET Pierre committed
669
670
671
672
673
674
        self.model = model
        # get node names
        lnode = self.get_frontier_node_names()
        lnode.sort()
        self.list_nodes = lnode
        # display node names
675
676
        self.sn_viewer.refresh(lnode)

VIGNET Pierre's avatar
VIGNET Pierre committed
677
678
679
680
681
682
    def get_frontier_node_names(self):
        """
        retrieve frontier nodes from the model
        """
        fvi = FrontierVisitor()
        self.model.accept(fvi)
683
        return fvi.frontier