let edit ?(with_apply=true)
    ?(apply=(fun () -> ()))
    title ?(width=400) ?(height=400)
    conf_struct_list =
  let dialog = GWindow.dialog
      ~modal: true ~title: title
      ~height ~width
      ()
  in
  let tooltips = GData.tooltips () in
  let wnote = GPack.notebook
      (*homogeneous_tabs: true*)
      ~scrollable: true
      ~show_tabs: true
      ~tab_border: 3
      ~packing: (dialog#vbox#pack ~expand: true)
      ()
  in
  let list_param_box =
    List.map
      (fun conf_struct -> new configuration_box tooltips conf_struct wnote)
      conf_struct_list
  in

  if with_apply then
    dialog#add_button Configwin_messages.mApply `APPLY;

  dialog#add_button Configwin_messages.mOk `OK;
  dialog#add_button Configwin_messages.mCancel `CANCEL;

  let f_apply () =
    List.iter (fun param_box -> param_box#apply) list_param_box  ;
    apply ()
  in
  let f_ok () =
    List.iter (fun param_box -> param_box#apply) list_param_box  ;
    Return_ok
  in
  let destroy () =
    tooltips#destroy () ;
    dialog#destroy ();
  in
  let rec iter rep =
    try
      match dialog#run () with
      | `APPLY  -> f_apply (); iter Return_apply
      | `OK -> destroy (); f_ok ()
      | _ -> destroy (); rep
    with
      Failure s ->
        GToolbox.message_box "Error" s; iter rep
    | e ->
        GToolbox.message_box "Error" (Printexc.to_string e); iter rep
  in
  iter Return_cancel