let config_doc_sources ~f_update_menu =
  let f_edit ds =
    ignore (C.simple_get Cam_messages.doc_file (params_for_doc_source ds)) ;
    ds
  in
  let f_add () =
    let ds = {
      ds_file = "" ;
      ds_label_com = None
    }
    in
    match C.simple_get Cam_messages.add
        (params_for_doc_source ds)
    with
      C.Return_cancel -> []
    | C.Return_apply
    | C.Return_ok -> [ds]
  in
  let p =
    C.list
      ~f: (fun l -> doc_sources#set l; Cam_rc.save_core (); f_update_menu ())
      ~eq: (fun ds1 ds2 -> ds1.ds_file = ds2.ds_file)
      ~edit: f_edit
      ~add: f_add
      ~titles: [ Cam_messages.file ;
                 Cam_messages.label ;
                 Cam_messages.command
               ]
      Cam_messages.doc_files
      (fun ds ->
        (ds.ds_file ::
         (match ds.ds_label_com with
           None -> [ "" ; "" ]
         | Some (l, c) -> [ l ; c ]
         )
        )
      )
      doc_sources#get
  in
  ignore (C.simple_get Cam_messages.configure_doc_sources [p])