~ubuntu-branches/ubuntu/wily/marionnet/wily

« back to all changes in this revision

Viewing changes to gui/gui_menubar_MARIONNET.ml

  • Committer: Package Import Robot
  • Author(s): Lucas Nussbaum
  • Date: 2013-03-29 15:57:12 UTC
  • Revision ID: package-import@ubuntu.com-20130329155712-o0b9b96w8av68ktq
Tags: upstream-0.90.6+bzr407
ImportĀ upstreamĀ versionĀ 0.90.6+bzr407

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
(* This file is part of Marionnet, a virtual network laboratory
 
2
   Copyright (C) 2009, 2010  Jean-Vincent Loddo
 
3
   Copyright (C) 2009  Luca Saiu
 
4
   Copyright (C) 2009, 2010  UniversitĆ© Paris 13
 
5
 
 
6
   This program is free software: you can redistribute it and/or modify
 
7
   it under the terms of the GNU General Public License as published by
 
8
   the Free Software Foundation, either version 2 of the License, or
 
9
   (at your option) any later version.
 
10
 
 
11
   This program is distributed in the hope that it will be useful,
 
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
   GNU General Public License for more details.
 
15
 
 
16
   You should have received a copy of the GNU General Public License
 
17
   along with this program.  If not, see <http://www.gnu.org/licenses/>. *)
 
18
 
 
19
 
 
20
open Gettext;;
 
21
 
 
22
(** Gui completion for the menubar_MARIONNET widget defined with glade. *)
 
23
 
 
24
(* Shortcuts *)
 
25
module EDialog = Talking.EDialog
 
26
module Msg = Talking.Msg
 
27
let mkenv = Environment.make_string_env
 
28
let check_path_name_validity_and_add_extension_if_needed =
 
29
  Talking.check_path_name_validity_and_add_extension_if_needed
 
30
 
 
31
open GdkKeysyms
 
32
open GtkStock
 
33
 
 
34
module Make (State:sig val st:State.globalState end) = struct
 
35
 
 
36
open State
 
37
 
 
38
(* Create the factory linked to the menubar. *)
 
39
module F = Menu_factory.Make (struct
 
40
  let parent = Menu_factory.Menubar st#mainwin#menubar_MARIONNET
 
41
  let window = st#mainwin#window_MARIONNET
 
42
end)
 
43
include F
 
44
 
 
45
(* **************************************** *
 
46
                Menu "Project"
 
47
 * **************************************** *)
 
48
 
 
49
let project         = add_menu (s_ "_Project" )
 
50
 
 
51
module Common_dialogs = struct
 
52
 
 
53
 (* Dialog used both for "New" and "Open" *)
 
54
 let save_current () =
 
55
   if st#active_project
 
56
    then EDialog.ask_question ~help:None ~cancel:true
 
57
          ~gen_id:"save_current"
 
58
          ~title:(s_ "Close" )
 
59
          ~question:(s_ "Do you want to save the current project?") ()
 
60
    else (Some (mkenv [("save_current","no")]))
 
61
 
 
62
end
 
63
 
 
64
type env  = string Environment.string_env
 
65
let env_to_string (t:env) = t#to_string (fun s->s)
 
66
 
 
67
module Created_entry_project_new = Menu_factory.Make_entry
 
68
 (struct
 
69
   type t = env
 
70
   let to_string = env_to_string
 
71
   let text  = (s_ "New" )
 
72
   let stock = `NEW
 
73
   let key   = (Some _N)
 
74
 
 
75
   let dialog =
 
76
     let filename () =
 
77
       EDialog.ask_for_fresh_writable_filename
 
78
         ~title:(s_ "Name of the new project" )
 
79
         ~filter_names:[`MAR;`ALL]
 
80
         ~help:(Some Msg.help_nom_pour_le_projet) ()
 
81
     in
 
82
     (EDialog.sequence [Common_dialogs.save_current; filename])
 
83
 
 
84
   let reaction r = begin
 
85
     st#shutdown_everything ();
 
86
     let filename = check_path_name_validity_and_add_extension_if_needed (r#get "filename") in
 
87
     let actions () =
 
88
       begin
 
89
       st#close_project;
 
90
       st#new_project filename ;
 
91
       end in
 
92
     if (st#active_project) && ((r#get "save_current") = "yes")
 
93
      then
 
94
       (st#save_project;
 
95
        Task_runner.the_task_runner#schedule ~name:"new project" actions)
 
96
      else
 
97
       (actions ())
 
98
     end
 
99
 
 
100
  end) (F)
 
101
let project_new = Created_entry_project_new.item
 
102
 
 
103
 
 
104
module Created_entry_project_open = Menu_factory.Make_entry
 
105
 (struct
 
106
   type t = env
 
107
   let to_string = env_to_string
 
108
   let text  = (s_ "Open" )
 
109
   let stock = `OPEN
 
110
   let key   = (Some _O)
 
111
 
 
112
   let dialog =
 
113
     let filename_dialog () =
 
114
       EDialog.ask_for_existing_filename
 
115
         ~title:(s_ "Open an existing Marionnet project" )
 
116
         ~filter_names:[`MAR; `ALL]
 
117
         ~help:(Some Msg.help_nom_pour_le_projet) ()
 
118
     in
 
119
     (EDialog.sequence [Common_dialogs.save_current; filename_dialog])
 
120
 
 
121
   let reaction r =
 
122
     begin
 
123
      st#shutdown_everything ();
 
124
      let filename = (r#get "filename") in
 
125
      let actions () = begin
 
126
         st#close_project;
 
127
         try
 
128
          st#open_project filename;
 
129
         with e -> ((Simple_dialogs.error (s_ "Open a project") ((s_ "Failed to open the file ")^filename) ()); raise e)
 
130
        end in
 
131
      if (st#active_project) && ((r#get "save_current")="yes")
 
132
      then
 
133
       (st#save_project;
 
134
        Task_runner.the_task_runner#schedule ~name:"open_project" actions)
 
135
      else
 
136
       (actions ())
 
137
     end
 
138
 
 
139
  end) (F)
 
140
let project_open = Created_entry_project_open.item
 
141
 
 
142
 
 
143
let project_save =
 
144
  add_stock_item (s_ "Save" )
 
145
    ~stock:`SAVE
 
146
    ~callback:(fun () ->
 
147
      if st#is_there_something_on_or_sleeping ()
 
148
        then Msg.error_saving_while_something_up ()
 
149
        else st#save_project)
 
150
    ()
 
151
 
 
152
module Created_entry_project_save_as = Menu_factory.Make_entry
 
153
 (struct
 
154
   type t = env
 
155
   let to_string = env_to_string
 
156
   let text  = (s_ "Save as" )
 
157
   let stock = `SAVE_AS
 
158
   let key   = None
 
159
 
 
160
   let dialog () =
 
161
     EDialog.ask_for_fresh_writable_filename
 
162
       ~title:(s_ "Save as" )
 
163
       ~filter_names:[`MAR; `ALL]
 
164
       ~help:(Some Msg.help_nom_pour_le_projet) ()
 
165
 
 
166
   let reaction r =
 
167
     if st#is_there_something_on_or_sleeping () then Msg.error_saving_while_something_up () else
 
168
     let filename = check_path_name_validity_and_add_extension_if_needed ~extension:"mar" (r#get "filename") in
 
169
     try
 
170
      st#save_project_as filename;
 
171
     with _ -> (Simple_dialogs.error (s_ "Save project as") ((s_ "Failed to save the project into the file ")^filename) ())
 
172
 
 
173
  end) (F)
 
174
let project_save_as = Created_entry_project_save_as.item
 
175
 
 
176
 
 
177
module Created_entry_project_copy_to = Menu_factory.Make_entry
 
178
 (struct
 
179
   type t = env
 
180
   let to_string = env_to_string
 
181
   let text  = (s_ "Copy to" )
 
182
   let stock = `SAVE_AS
 
183
   let key   = None
 
184
 
 
185
   let dialog () =
 
186
     EDialog.ask_for_fresh_writable_filename
 
187
       ~title:(s_ "Copy to" )
 
188
       ~filter_names:[`MAR; `ALL]
 
189
       ~help:(Some Msg.help_nom_pour_le_projet) ()
 
190
 
 
191
   let reaction r =
 
192
     if st#is_there_something_on_or_sleeping () then Msg.error_saving_while_something_up () else
 
193
     let filename = check_path_name_validity_and_add_extension_if_needed ~extension:"mar" (r#get "filename") in
 
194
     try
 
195
       st#copy_project_into filename
 
196
     with _ -> (Simple_dialogs.error (s_ "Project copy to" ) ((s_ "Failed to copy the project into the file ")^filename) ())
 
197
 
 
198
  end) (F)
 
199
let project_copy_to = Created_entry_project_copy_to.item
 
200
 
 
201
 
 
202
module Created_entry_project_close = Menu_factory.Make_entry
 
203
 (struct
 
204
   type t = env
 
205
   let to_string = env_to_string
 
206
   let text  = (s_ "Close" )
 
207
   let stock = `CLOSE
 
208
   let key   = (Some _W)
 
209
 
 
210
   let dialog () =
 
211
     EDialog.ask_question ~help:None ~cancel:true
 
212
       ~title:(s_ "Close" )
 
213
       ~question:(s_ "Do you want to save the current project?") ()
 
214
 
 
215
   let reaction r = begin
 
216
    st#shutdown_everything ();
 
217
    let () = if (st#active_project) && ((r#get "answer") = "yes")
 
218
              then st#save_project
 
219
              else () in
 
220
    st#close_project;
 
221
    end
 
222
 
 
223
  end) (F)
 
224
let project_close = Created_entry_project_close.item
 
225
 
 
226
 
 
227
let separator       = project#add_separator ()
 
228
 
 
229
module Created_entry_project_export = Menu_factory.Make_entry
 
230
 (struct
 
231
   type t = env
 
232
   let to_string = env_to_string
 
233
   let text  = (s_ "Export image" )
 
234
   let stock = `CONVERT
 
235
   let key   = None
 
236
 
 
237
   let dialog () =
 
238
     let extra_widget =
 
239
       let (combo_box, get_selected) = Dot_widget.combo_of_working_output_formats ~active:`png () in
 
240
       let widget_reader () =
 
241
         let frm = get_selected () in
 
242
         Dot.string_of_output_format frm
 
243
       in
 
244
       let table = GPack.table ~rows:2 ~columns:1 ~row_spacings:10 ~homogeneous:false () in
 
245
       let _ = GMisc.label
 
246
         ~xalign:0.5
 
247
         ~markup:("<b>"^(s_ "Output format")^"</b>")
 
248
         ~packing:(table#attach ~left:0 ~top:0) ()
 
249
       in
 
250
       (table#attach ~left:0 ~top:1 combo_box#coerce);
 
251
       (table#coerce, widget_reader)
 
252
     in
 
253
     EDialog.ask_for_fresh_writable_filename
 
254
       ~title:(s_ "Export network image" )
 
255
       ~filters:(Dot_widget.make_all_working_filters ())
 
256
       ~filter_names:[`ALL]
 
257
       ~extra_widget
 
258
       ~help:None ()
 
259
 
 
260
   let reaction r =
 
261
     let output_format = (r#get "extra_widget") in
 
262
     let filename = check_path_name_validity_and_add_extension_if_needed ~extension:output_format (r#get "filename") in
 
263
     let command = Printf.sprintf "dot -T%s -o %s %s" output_format filename st#dotSketchFile in
 
264
     let on_error () =
 
265
        Simple_dialogs.error
 
266
          "Export network image"
 
267
          ((s_ "Failed to export network image to the file ")^filename^" (format "^output_format^")")
 
268
          ()
 
269
     in
 
270
     try
 
271
       Log.system_or_fail command;
 
272
       st#flash ~delay:8000 ((s_ "Network image correctly exported to the file ")^filename)
 
273
     with _ -> on_error ()
 
274
 
 
275
  end) (F)
 
276
let project_export = Created_entry_project_export.item
 
277
 
 
278
 
 
279
module Created_entry_project_quit = Menu_factory.Make_entry
 
280
 (struct
 
281
   type t = env
 
282
   let to_string = env_to_string
 
283
   let text  = (s_ "Quit")
 
284
   let stock = `QUIT
 
285
   let key   = (Some _Q)
 
286
 
 
287
   let dialog () =
 
288
    if ((not st#active_project) || st#project_already_saved)
 
289
     then (Some (mkenv [("answer","no")]))
 
290
     else Talking.EDialog.ask_question ~help:None ~cancel:true
 
291
           ~title:(s_ "Quit")
 
292
           ~question:(s_ "Do you want to save\nthe current project before quitting?")
 
293
           ()
 
294
 
 
295
   let reaction r =
 
296
    (* At this point the user really wants to quit the application. *)
 
297
    let save = (st#active_project) && ((r#get "answer") = "yes") in
 
298
    (match st#is_there_something_on_or_sleeping (), save with
 
299
     | true, true  ->
 
300
         st#shutdown_everything ();
 
301
         st#save_project;
 
302
     | true, false ->
 
303
         st#poweroff_everything ();
 
304
     | false, true ->
 
305
         st#save_project;
 
306
     | false, false -> ()
 
307
     );
 
308
    Log.printf "Killing the death monitor thread...\n";
 
309
    Death_monitor.stop_polling_loop ();
 
310
    st#network#destroy_process_before_quitting ();
 
311
    st#close_project;
 
312
    st#quit_async ()
 
313
 
 
314
  end) (F)
 
315
let project_quit = Created_entry_project_quit.item
 
316
 
 
317
 
 
318
(* **************************************** *
 
319
                Menu "Options"
 
320
 * **************************************** *)
 
321
 
 
322
let options         = add_menu (s_ "_Options")
 
323
 
 
324
module Created_entry_options_cwd = Menu_factory.Make_entry
 
325
 (struct
 
326
   type t = env
 
327
   let to_string = env_to_string
 
328
   let text  = (s_ "Change the temporary working directory")
 
329
   let stock = `DIRECTORY
 
330
   let key   = None
 
331
   let dialog () =
 
332
    Talking.EDialog.ask_for_existing_writable_folder_pathname_supporting_sparse_files
 
333
       ~title:(s_ "Choose the temporary working directory")
 
334
       ~help:(Some Msg.help_repertoire_de_travail) ()
 
335
   let reaction r = st#temporary_directory#set (r#get "foldername")
 
336
  end) (F)
 
337
let options_cwd = Created_entry_options_cwd.item
 
338
 
 
339
let options_autogenerate_ip_addresses =
 
340
 add_check_item (s_ "Auto-generation of IP address" )
 
341
  ~active:Global_options.autogenerate_ip_addresses_default
 
342
  ~callback:(fun active ->
 
343
         Log.printf "You toggled the option (IP)\n";
 
344
         Global_options.set_autogenerate_ip_addresses active)
 
345
   ()
 
346
 
 
347
let options_debug_mode =
 
348
 add_check_item (s_ "Debug mode")
 
349
  ~active:(Global_options.Debug_level.are_we_debugging ())
 
350
  ~callback:(fun active ->
 
351
         Log.printf "You toggled the option (debug)\n";
 
352
         Global_options.Debug_level.set 1)
 
353
 ()
 
354
 
 
355
let options_keep_all_snapshots_when_saving =
 
356
 add_check_item (s_ "Keep all snapshots when saving (not only the most recent ones)")
 
357
  ~active:(Global_options.Keep_all_snapshots_when_saving.extract ())
 
358
  ~callback:(fun active ->
 
359
         Log.printf "You toggled the option (keep al snapshots)\n";
 
360
         Global_options.Keep_all_snapshots_when_saving.set active)
 
361
 ()
 
362
 
 
363
(** Hidden to user in this version. *)
 
364
let workaround_wirefilter_problem =
 
365
 add_check_item "Workaround wirefilter problem"
 
366
  ~active:Global_options.workaround_wirefilter_problem_default
 
367
  ~callback:(fun active ->
 
368
         Log.printf "You toggled the option (wirefilter)\n"; flush_all ();
 
369
         Global_options.set_workaround_wirefilter_problem active)
 
370
 ()
 
371
 
 
372
let () = workaround_wirefilter_problem#coerce#misc#hide ()
 
373
 
 
374
(* **************************************** *
 
375
                Menu "Help"
 
376
 * **************************************** *)
 
377
 
 
378
let help         = add_menu (s_ "_Help")
 
379
let help_apropos =
 
380
 let module D = Gui_dialog_A_PROPOS.Make (State) in
 
381
 let callback () =
 
382
   let dialog = D.dialog () in
 
383
   let _ = dialog#closebutton_A_PROPOS#connect#clicked ~callback:(dialog#toplevel#destroy) in ()
 
384
 in add_stock_item (s_ "Help") ~stock:`ABOUT ~callback ()
 
385
 
 
386
 
 
387
(* **************************************** *
 
388
                Sensitiveness
 
389
 * **************************************** *)
 
390
 
 
391
let () = List.iter (* when Active *)
 
392
          (fun w -> st#sensitive_when_Active#insert w#coerce)
 
393
          [project_save; project_save_as; project_copy_to; project_close; project_export]
 
394
 
 
395
let () = List.iter (* when NoActive *)
 
396
          (fun w -> st#sensitive_when_NoActive#insert w#coerce)
 
397
          [options_cwd]
 
398
 
 
399
end