Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 769341 | Differences between
and this patch

Collapse All | Expand All

(-)unison-2.51.4/src/uigtk3.ml (-255 / +208 lines)
Lines 94-100 let icon = Link Here
94
let icon =
94
let icon =
95
  let p = GdkPixbuf.create ~width:48 ~height:48 ~has_alpha:true () in
95
  let p = GdkPixbuf.create ~width:48 ~height:48 ~has_alpha:true () in
96
  Gpointer.blit
96
  Gpointer.blit
97
    (Gpointer.region_of_bytes (Bytes.of_string Pixmaps.icon_data)) (GdkPixbuf.get_pixels p);
97
    ~src:(Gpointer.region_of_bytes (Bytes.of_string Pixmaps.icon_data))
98
    ~dst:(GdkPixbuf.get_pixels p);
98
  p
99
  p
99
100
100
let leftPtrWatch =
101
let leftPtrWatch =
Lines 119-131 type stateItem = { mutable ri : reconIte Link Here
119
let theState = ref [||]
120
let theState = ref [||]
120
let unsynchronizedPaths = ref None
121
let unsynchronizedPaths = ref None
121
122
122
module IntSet = Set.Make (struct type t = int let compare = compare end)
123
124
let current = ref IntSet.empty
125
126
let currentRow () =
127
  if IntSet.cardinal !current = 1 then Some (IntSet.choose !current) else None
128
129
(* ---- *)
123
(* ---- *)
130
124
131
let theToplevelWindow = ref None
125
let theToplevelWindow = ref None
Lines 591-601 let statistics () = Link Here
591
  let data_row = lst#append () in
585
  let data_row = lst#append () in
592
  ignore (lst#set data_row c_1 "File data written");
586
  ignore (lst#set data_row c_1 "File data written");
593
(*
587
(*
594
  ignore (t#event#connect#map (fun _ ->
588
  ignore (t#event#connect#map ~callback:(fun _ ->
595
    emission#activate true;
589
    emission#activate true;
596
    reception#activate true;
590
    reception#activate true;
597
    false));
591
    false));
598
  ignore (t#event#connect#unmap (fun _ ->
592
  ignore (t#event#connect#unmap ~callback:(fun _ ->
599
    emission#activate false;
593
    emission#activate false;
600
    reception#activate false;
594
    reception#activate false;
601
    false));*)
595
    false));*)
Lines 1488-1494 let createProfile parent = Link Here
1488
      options#as_widget
1482
      options#as_widget
1489
  in
1483
  in
1490
  ignore
1484
  ignore
1491
    (assistant#connect#prepare (fun () ->
1485
    (assistant#connect#prepare ~callback:(fun () ->
1492
       if assistant#current_page = p &&
1486
       if assistant#current_page = p &&
1493
          not (Util.osType <> `Win32 || React.state askUnicode)
1487
          not (Util.osType <> `Win32 || React.state askUnicode)
1494
       then
1488
       then
Lines 2697-2762 let createToplevelWindow () = Link Here
2697
    let ctx = mainWindowSW#misc#pango_context in
2691
    let ctx = mainWindowSW#misc#pango_context in
2698
    let metrics = ctx#get_metrics () in
2692
    let metrics = ctx#get_metrics () in
2699
    let h = GPango.to_pixels (metrics#ascent+metrics#descent) in
2693
    let h = GPango.to_pixels (metrics#ascent+metrics#descent) in
2700
    mainWindowSW#misc#set_size_request
2694
    toplevelWindow#set_default_height
2701
      ~height:((h + 1) * (Prefs.read Uicommon.mainWindowHeight + 1) + 10) ()
2695
      ((h + 3) * (Prefs.read Uicommon.mainWindowHeight + 1) + 200)
2702
  in
2696
  in
2703
  let mainWindow =
2704
    GList.clist ~columns:5 ~titles_show:true
2705
      ~selection_mode:`MULTIPLE ~packing:mainWindowSW#add ()
2706
  in
2707
(*
2708
  let cols = new GTree.column_list in
2697
  let cols = new GTree.column_list in
2709
  let c_replica1 = cols#add Gobject.Data.string in
2698
  let c_replica1 = cols#add Gobject.Data.string in
2710
  let c_action   = cols#add Gobject.Data.gobject in
2699
  let c_action   = cols#add Gobject.Data.gobject in
2711
  let c_replica2 = cols#add Gobject.Data.string in
2700
  let c_replica2 = cols#add Gobject.Data.string in
2712
  let c_status   = cols#add Gobject.Data.string in
2701
  let c_status   = cols#add Gobject.Data.gobject_option in
2702
  let c_statust  = cols#add Gobject.Data.string in
2713
  let c_path     = cols#add Gobject.Data.string in
2703
  let c_path     = cols#add Gobject.Data.string in
2714
  let lst_store = GTree.list_store cols in
2704
  (*let c_rowid    = cols#add Gobject.Data.uint in*)
2715
  let lst =
2705
  (* With current implementation the [list_store] view model and [theState]
2716
    GTree.view ~model:lst_store ~packing:(toplevelVBox#add)
2706
     array have one-to-one correspondence, so that list_store's tree path index
2717
      ~headers_clickable:false () in
2707
     is the same as theState array index.
2718
  let s = Uicommon.roots2string () in
2708
     This changes when, for example, [tree_store] would be used instead of
2719
  ignore (lst#append_column
2709
     list_store, or a separate view-only sorting is implemented without sorting
2710
     the backing theState array. In that case, the column [c_rowid] must be
2711
     used to store the index of [theState] array in the view model. Tree path
2712
     index must not be used directly as [theState] array index and vice versa. *)
2713
  let mainWindowModel = GTree.list_store cols in
2714
  let mainWindow =
2715
    GTree.view ~model:mainWindowModel ~packing:(mainWindowSW#add)
2716
      ~headers_clickable:false ~enable_search:false () in
2717
  mainWindow#selection#set_mode `MULTIPLE;
2718
  ignore (mainWindow#append_column
2720
    (GTree.view_column
2719
    (GTree.view_column
2721
       ~title:(" " ^ Unicode.protect (String.sub s  0 12) ^ " ")
2720
       ~title:(" ")
2722
       ~renderer:(GTree.cell_renderer_text [], ["text", c_replica1]) ()));
2721
       ~renderer:(GTree.cell_renderer_text [], ["text", c_replica1]) ()));
2723
  ignore (lst#append_column
2722
  ignore (mainWindow#append_column
2724
    (GTree.view_column ~title:"  Action  "
2723
    (GTree.view_column ~title:"  Action  "
2725
       ~renderer:(GTree.cell_renderer_pixbuf [], ["pixbuf", c_action]) ()));
2724
       ~renderer:(GTree.cell_renderer_pixbuf [], ["pixbuf", c_action]) ()));
2726
  ignore (lst#append_column
2725
  ignore (mainWindow#append_column
2727
    (GTree.view_column
2726
    (GTree.view_column
2728
       ~title:(" " ^ Unicode.protect (String.sub s  15 12) ^ " ")
2727
       ~title:(" ")
2729
       ~renderer:(GTree.cell_renderer_text [], ["text", c_replica2]) ()));
2728
       ~renderer:(GTree.cell_renderer_text [], ["text", c_replica2]) ()));
2730
  ignore (lst#append_column
2729
  let status_view_col = GTree.view_column ~title:"  Status  "
2731
    (GTree.view_column ~title:"  Status  " ()));
2730
       ~renderer:(GTree.cell_renderer_pixbuf [], ["pixbuf", c_status]) () in
2732
  ignore (lst#append_column
2731
  let status_t_rend = GTree.cell_renderer_text [] in
2732
  status_view_col#pack ~expand:false ~from:`END status_t_rend;
2733
  status_view_col#add_attribute status_t_rend "text" c_statust;
2734
  ignore (mainWindow#append_column status_view_col);
2735
  ignore (mainWindow#append_column
2733
    (GTree.view_column ~title:"  Path  "
2736
    (GTree.view_column ~title:"  Path  "
2734
       ~renderer:(GTree.cell_renderer_text [], ["text", c_path]) ()));
2737
       ~renderer:(GTree.cell_renderer_text [], ["text", c_path]) ()));
2735
*)
2736
2737
(*
2738
  let status_width =
2739
    let font = mainWindow#misc#style#font in
2740
    4 + max (max (Gdk.Font.string_width font "working")
2741
                 (Gdk.Font.string_width font "skipped"))
2742
                 (Gdk.Font.string_width font "  Action  ")
2743
  in
2744
*)
2745
  mainWindow#set_column ~justification:`CENTER 1;
2746
  mainWindow#set_column
2747
    ~justification:`CENTER (*~auto_resize:false ~width:status_width*) 3;
2748
2738
2749
  let setMainWindowColumnHeaders s =
2739
  let setMainWindowColumnHeaders s =
2750
    Array.iteri
2740
    Array.iteri
2751
      (fun i data ->
2741
      (fun i data ->
2752
         mainWindow#set_column
2742
         (mainWindow#get_column i)#set_title data)
2753
           ~title_active:false ~auto_resize:true ~title:data i)
2754
      [| " " ^ Unicode.protect (String.sub s  0 12) ^ " "; "  Action  ";
2743
      [| " " ^ Unicode.protect (String.sub s  0 12) ^ " "; "  Action  ";
2755
         " " ^ Unicode.protect (String.sub s 15 12) ^ " "; "  Status  ";
2744
         " " ^ Unicode.protect (String.sub s 15 12) ^ " "; "  Status  ";
2756
         " Path" |];
2745
         " Path" |];
2757
    sizeMainWindow ()
2758
  in
2746
  in
2759
  setMainWindowColumnHeaders "                                  ";
2747
  sizeMainWindow ();
2748
2749
  (* See above for comment about tree path index and [theState] array index
2750
     equivalence. *)
2751
  let siOfRow f path =
2752
    let row = mainWindowModel#get_iter path in
2753
    let i = (GTree.Path.get_indices path).(0) in
2754
    (*let i = mainWindowModel#get ~row ~column:c_rowid in*)
2755
    f i !theState.(i) row
2756
  in
2757
  let rowOfSi i = GTree.Path.create [i] in
2758
  let currentNumberRows () = mainWindow#selection#count_selected_rows in
2759
  let currentRow () =
2760
    match currentNumberRows () with
2761
    | 1 -> siOfRow (fun i si row -> Some (i, !theState.(i), row))
2762
             (List.hd mainWindow#selection#get_selected_rows)
2763
    | _ -> None
2764
  in
2765
  let currentSelectedIter f =
2766
    Safelist.iter (fun r -> siOfRow f r)
2767
      mainWindow#selection#get_selected_rows
2768
  in
2769
  let currentSelectedFold f a =
2770
    Safelist.fold_left (fun a r -> siOfRow (fun _ si _ -> f a si) r)
2771
      a mainWindow#selection#get_selected_rows
2772
  in
2773
  let currentSelectedExists pred =
2774
    Safelist.exists (fun r -> siOfRow (fun _ si _ -> pred si) r)
2775
      mainWindow#selection#get_selected_rows
2776
  in
2760
2777
2761
  (*********************************************************************
2778
  (*********************************************************************
2762
    Create the details window
2779
    Create the details window
Lines 2767-2781 let createToplevelWindow () = Link Here
2767
      match currentRow () with
2784
      match currentRow () with
2768
        None ->
2785
        None ->
2769
          None
2786
          None
2770
      | Some row ->
2787
      | Some (_, si, _) ->
2771
          let path = Path.toString !theState.(row).ri.path1 in
2788
          let path = Path.toString si.ri.path1 in
2772
          match !theState.(row).whatHappened with
2789
          match si.whatHappened with
2773
            Some (Util.Failed _, Some det) ->
2790
            Some (Util.Failed _, Some det) ->
2774
              Some ("Merge execution details for file" ^
2791
              Some ("Merge execution details for file" ^
2775
                    transcodeFilename path,
2792
                    transcodeFilename path,
2776
                    det)
2793
                    det)
2777
          | _ ->
2794
          | _ ->
2778
              match !theState.(row).ri.replicas with
2795
              match si.ri.replicas with
2779
                Problem err ->
2796
                Problem err ->
2780
                  Some ("Errors for file " ^ transcodeFilename path, err)
2797
                  Some ("Errors for file " ^ transcodeFilename path, err)
2781
              | Different diff ->
2798
              | Different diff ->
Lines 2788-2794 let createToplevelWindow () = Link Here
2788
                      (prefix "[root 2]: " diff.errors2)
2805
                      (prefix "[root 2]: " diff.errors2)
2789
                  in
2806
                  in
2790
                  let errors =
2807
                  let errors =
2791
                    match !theState.(row).whatHappened with
2808
                    match si.whatHappened with
2792
                       Some (Util.Failed err, _) -> err :: errors
2809
                       Some (Util.Failed err, _) -> err :: errors
2793
                    |  _                         -> errors
2810
                    |  _                         -> errors
2794
                  in
2811
                  in
Lines 2817-2850 let createToplevelWindow () = Link Here
2817
2834
2818
  let updateButtons () =
2835
  let updateButtons () =
2819
    if not !busy then
2836
    if not !busy then
2820
      let actionPossible row =
2837
      let actionPossible si =
2821
        let si = !theState.(row) in
2822
        match si.whatHappened, si.ri.replicas with
2838
        match si.whatHappened, si.ri.replicas with
2823
          None, Different _ -> true
2839
          None, Different _ -> true
2824
        | _                 -> false
2840
        | _                 -> false
2825
      in
2841
      in
2826
      match currentRow () with
2842
      match currentRow () with
2827
        None ->
2843
        None ->
2828
          grSet grAction (IntSet.exists actionPossible !current);
2844
          grSet grAction (currentSelectedExists actionPossible);
2829
          grSet grDiff false;
2845
          grSet grDiff false;
2830
          grSet grDetail false
2846
          grSet grDetail false
2831
      | Some row ->
2847
      | Some (_, si, _) ->
2832
          let details =
2848
          let details =
2833
            begin match !theState.(row).ri.replicas with
2849
            begin match si.ri.replicas with
2834
              Different diff -> diff.errors1 <> [] || diff.errors2 <> []
2850
              Different diff -> diff.errors1 <> [] || diff.errors2 <> []
2835
            | Problem _      -> true
2851
            | Problem _      -> true
2836
            end
2852
            end
2837
              ||
2853
              ||
2838
            begin match !theState.(row).whatHappened with
2854
            begin match si.whatHappened with
2839
              Some (Util.Failed _, _) -> true
2855
              Some (Util.Failed _, _) -> true
2840
            | _                       -> false
2856
            | _                       -> false
2841
            end
2857
            end
2842
          in
2858
          in
2843
          grSet grDetail details;
2859
          grSet grDetail details;
2844
          let activateAction = actionPossible row in
2860
          let activateAction = actionPossible si in
2845
          let activateDiff =
2861
          let activateDiff =
2846
            activateAction &&
2862
            activateAction &&
2847
            match !theState.(row).ri.replicas with
2863
            match si.ri.replicas with
2848
              Different {rc1 = {typ = `FILE}; rc2 = {typ = `FILE}} ->
2864
              Different {rc1 = {typ = `FILE}; rc2 = {typ = `FILE}} ->
2849
                true
2865
                true
2850
            | _ ->
2866
            | _ ->
Lines 2855-2868 let createToplevelWindow () = Link Here
2855
  in
2871
  in
2856
2872
2857
  let makeRowVisible row =
2873
  let makeRowVisible row =
2858
    if mainWindow#row_is_visible row <> `FULL then begin
2874
    mainWindow#scroll_to_cell row status_view_col (* just a dummy column *)
2859
      let adj = mainWindow#vadjustment in
2875
  in
2860
      let upper = adj#upper and lower = adj#lower in
2861
      let v =
2862
        float row /. float (mainWindow#rows + 1) *. (upper-.lower) +. lower
2863
      in
2864
      adj#set_value (min v (upper -. adj#page_size));
2865
    end in
2866
2876
2867
(*
2877
(*
2868
  let makeFirstUnfinishedVisible pRiInFocus =
2878
  let makeFirstUnfinishedVisible pRiInFocus =
Lines 2880-2899 let createToplevelWindow () = Link Here
2880
    begin match currentRow () with
2890
    begin match currentRow () with
2881
      None ->
2891
      None ->
2882
        detailsWindow#buffer#set_text ""
2892
        detailsWindow#buffer#set_text ""
2883
    | Some row ->
2893
    | Some (_, si, _) ->
2884
(*        makeRowVisible row;*)
2885
        let (formated, details) =
2894
        let (formated, details) =
2886
          match !theState.(row).whatHappened with
2895
          match si.whatHappened with
2887
          | Some(Util.Failed(s), _) ->
2896
          | Some(Util.Failed(s), _) ->
2888
               (false, s)
2897
               (false, s)
2889
          | None | Some(Util.Succeeded, _) ->
2898
          | None | Some(Util.Succeeded, _) ->
2890
              match !theState.(row).ri.replicas with
2899
              match si.ri.replicas with
2891
                Problem _ ->
2900
                Problem _ ->
2892
                  (false, Uicommon.details2string !theState.(row).ri "  ")
2901
                  (false, Uicommon.details2string si.ri "  ")
2893
              | Different _ ->
2902
              | Different _ ->
2894
                  (true, Uicommon.details2string !theState.(row).ri "  ")
2903
                  (true, Uicommon.details2string si.ri "  ")
2895
        in
2904
        in
2896
        let path = Path.toString !theState.(row).ri.path1 in
2905
        let path = Path.toString si.ri.path1 in
2897
        detailsWindow#buffer#set_text "";
2906
        detailsWindow#buffer#set_text "";
2898
        detailsWindow#buffer#insert ~tags:[detailsWindowPath]
2907
        detailsWindow#buffer#insert ~tags:[detailsWindowPath]
2899
          (transcodeFilename path);
2908
          (transcodeFilename path);
Lines 2948-3030 let createToplevelWindow () = Link Here
2948
    Functions used to print in the main window
2957
    Functions used to print in the main window
2949
   *********************************************************************)
2958
   *********************************************************************)
2950
  let delayUpdates = ref false in
2959
  let delayUpdates = ref false in
2951
  let hasFocus = ref false in
2952
2960
2953
  let select i scroll =
2961
  let select row scroll =
2954
    if !hasFocus then begin
2962
    delayUpdates := true;
2955
      (* If we have the focus, we move the focus row directely *)
2963
    mainWindow#selection#unselect_all ();
2956
      if scroll then begin
2964
    mainWindow#selection#select_path row;
2957
        let r = mainWindow#rows in
2965
    mainWindow#set_cursor row status_view_col (* just a dummy column *);
2958
        let p = if r < 2 then 0. else (float i +. 0.5) /. float (r - 1) in
2966
    delayUpdates := false;
2959
        mainWindow#scroll_vertical `JUMP (min p 1.)
2967
    if scroll then makeRowVisible row;
2960
      end;
2968
    updateDetails ()
2961
      if IntSet.is_empty !current then mainWindow#select i 0
2962
    end else begin
2963
      (* If we don't have the focus, we just move the selection.
2964
         We delay updates to make sure not to change the button
2965
         states unnecessarily (which could result in a button
2966
         losing the focus). *)
2967
      delayUpdates := true;
2968
      mainWindow#unselect_all ();
2969
      mainWindow#select i 0;
2970
      delayUpdates := false;
2971
      if scroll then makeRowVisible i;
2972
      updateDetails ()
2973
    end
2974
  in
2969
  in
2975
  ignore (mainWindow#event#connect#focus_in ~callback:
2970
  let selectI i scroll = select (rowOfSi i) scroll in
2976
      (fun _ ->
2971
2977
         hasFocus := true;
2972
  ignore (mainWindow#selection#connect#changed ~callback:
2978
         (* Adjust the focus row.  We cannot do it immediately,
2973
      (fun () -> if not !delayUpdates then updateDetails ()));
2979
            otherwise the focus row is not drawn correctly. *)
2980
         ignore (GMain.Idle.add (fun () ->
2981
           begin match currentRow () with
2982
             Some i -> select i false
2983
           | None -> ()
2984
           end;
2985
           false));
2986
         false));
2987
  ignore (mainWindow#event#connect#focus_out ~callback:
2988
      (fun _ -> hasFocus := false; false));
2989
2990
  ignore (mainWindow#connect#select_row ~callback:
2991
      (fun ~row ~column ~event ->
2992
         current := IntSet.add row !current;
2993
         if not !delayUpdates then updateDetails ()));
2994
  ignore (mainWindow#connect#unselect_row ~callback:
2995
      (fun ~row ~column ~event ->
2996
         current := IntSet.remove row !current;
2997
         if not !delayUpdates then updateDetails ()));
2998
2974
2999
  let nextInteresting () =
2975
  let nextInteresting () =
3000
    let l = Array.length !theState in
2976
    let l = Array.length !theState in
3001
    let start = match currentRow () with Some i -> i + 1 | None -> 0 in
2977
    let start = match currentRow () with Some (i, _, _) -> i + 1 | None -> 0 in
3002
    let rec loop i =
2978
    let rec loop i =
3003
      if i < l then
2979
      if i < l then
3004
        match !theState.(i).ri.replicas with
2980
        match !theState.(i).ri.replicas with
3005
          Different {direction = dir}
2981
          Different {direction = dir}
3006
              when not (Prefs.read Uicommon.auto) || isConflict dir ->
2982
              when not (Prefs.read Uicommon.auto) || isConflict dir ->
3007
            select i true
2983
            selectI i true
3008
        | _ ->
2984
        | _ ->
3009
            loop (i + 1) in
2985
            loop (i + 1) in
3010
    loop start in
2986
    loop start in
3011
  let selectSomethingIfPossible () =
2987
  let selectSomethingIfPossible () =
3012
    if IntSet.is_empty !current then nextInteresting () in
2988
    if currentNumberRows () = 0 then nextInteresting () in
3013
2989
3014
  let columnsOf i =
2990
  let columnsOf si =
3015
    let oldPath = if i = 0 then Path.empty else !theState.(i-1).ri.path1 in
2991
    let oldPath = Path.empty in
3016
    let status =
2992
    let status =
3017
      match !theState.(i).ri.replicas with
2993
      match si.ri.replicas with
3018
        Different {direction = Conflict _} | Problem _ ->
2994
        Different {direction = Conflict _} | Problem _ ->
3019
          NoStatus
2995
          NoStatus
3020
      | _ ->
2996
      | _ ->
3021
          match !theState.(i).whatHappened with
2997
          match si.whatHappened with
3022
            None                     -> NoStatus
2998
            None                     -> NoStatus
3023
          | Some (Util.Succeeded, _) -> Done
2999
          | Some (Util.Succeeded, _) -> Done
3024
          | Some (Util.Failed _, _)  -> Failed
3000
          | Some (Util.Failed _, _)  -> Failed
3025
    in
3001
    in
3026
    let (r1, action, r2, path) =
3002
    let (r1, action, r2, path) =
3027
      Uicommon.reconItem2stringList oldPath !theState.(i).ri in
3003
      Uicommon.reconItem2stringList oldPath si.ri in
3028
    (r1, action, r2, status, path)
3004
    (r1, action, r2, status, path)
3029
  in
3005
  in
3030
3006
Lines 3037-3043 let createToplevelWindow () = Link Here
3037
  let blackPixel  = "000000" in
3013
  let blackPixel  = "000000" in
3038
*)
3014
*)
3039
  let buildPixmap p =
3015
  let buildPixmap p =
3040
    GDraw.pixmap_from_xpm_d ~window:toplevelWindow ~data:p () in
3016
    GdkPixbuf.from_xpm_data p in
3041
  let buildPixmaps f c1 =
3017
  let buildPixmaps f c1 =
3042
    (buildPixmap (f c1), buildPixmap (f lightbluePixel)) in
3018
    (buildPixmap (f c1), buildPixmap (f lightbluePixel)) in
3043
3019
Lines 3056-3062 let createToplevelWindow () = Link Here
3056
  let mergeLogoBlack = buildPixmap (Pixmaps.mergeLogo blackPixel) in
3032
  let mergeLogoBlack = buildPixmap (Pixmaps.mergeLogo blackPixel) in
3057
*)
3033
*)
3058
3034
3059
  let displayArrow i j action =
3035
  let getArrow j action =
3060
    let changedFromDefault = match !theState.(j).ri.replicas with
3036
    let changedFromDefault = match !theState.(j).ri.replicas with
3061
        Different diff -> diff.direction <> diff.default_direction
3037
        Different diff -> diff.direction <> diff.default_direction
3062
      | _ -> false in
3038
      | _ -> false in
Lines 3072-3144 let createToplevelWindow () = Link Here
3072
      | Uicommon.ARtoL true  -> orangeLeftArrow
3048
      | Uicommon.ARtoL true  -> orangeLeftArrow
3073
      | Uicommon.AMerge      -> mergeLogo
3049
      | Uicommon.AMerge      -> mergeLogo
3074
    in
3050
    in
3075
    mainWindow#set_cell ~pixmap:(sel pixmaps) i 1
3051
    sel pixmaps
3076
  in
3052
  in
3077
3053
3078
3054
3079
  let displayStatusIcon i status =
3055
  let getStatusIcon = function
3080
    match status with
3056
    | Failed   -> Some failedIcon
3081
    | Failed   -> mainWindow#set_cell ~pixmap:failedIcon i 3
3057
    | Done     -> Some doneIcon
3082
    | Done     -> mainWindow#set_cell ~pixmap:doneIcon i 3
3058
    | NoStatus -> None in
3083
    | NoStatus -> mainWindow#set_cell ~text:" " i 3 in
3059
3060
  let displayRowAction row i action =
3061
    mainWindowModel#set ~row ~column:c_action (getArrow i action) in
3062
  let displayRowStatus row status =
3063
    mainWindowModel#set ~row ~column:c_status (getStatusIcon status);
3064
    if status <> NoStatus then
3065
      mainWindowModel#set ~row ~column:c_statust "" in
3066
  let displayRowPath row path =
3067
    mainWindowModel#set ~row ~column:c_path (transcodeFilename path) in
3068
  let displayRow row i r1 r2 action status path =
3069
    mainWindowModel#set ~row ~column:c_replica1 r1;
3070
    mainWindowModel#set ~row ~column:c_replica2 r2;
3071
    displayRowAction row i action;
3072
    displayRowStatus row status;
3073
    displayRowPath row path;
3074
    (*mainWindowModel#set ~row ~column:c_rowid i;*)
3075
  in
3084
3076
3085
  let displayMain() =
3077
  let displayMain() =
3086
    (* The call to mainWindow#clear below side-effect current,
3078
    (* The call to mainWindow#clear below side-effect current,
3087
       so we save the current value before we clear out the main window and
3079
       so we save the current value before we clear out the main window and
3088
       rebuild it. *)
3080
       rebuild it. *)
3089
    let savedCurrent = currentRow () in
3081
    let savedCurrent = mainWindow#selection#get_selected_rows in
3090
    mainWindow#freeze ();
3082
    mainWindow#set_model None;
3091
    mainWindow#clear ();
3083
    mainWindowModel#clear ();
3092
    for i = Array.length !theState - 1 downto 0 do
3084
    let tot = Array.length !theState - 1 in
3093
      let (r1, action, r2, status, path) = columnsOf i in
3085
    let totf = float_of_int (tot + 1) in
3094
(*
3086
    progressBar#set_text (Printf.sprintf "Displaying %i items..." (tot + 1));
3095
let row = lst_store#prepend () in
3087
    for i = 0 to tot do
3096
lst_store#set ~row ~column:c_replica1 r1;
3088
      if i mod 1024 = 0 then begin
3097
lst_store#set ~row ~column:c_replica2 r2;
3089
        progressBar#set_fraction (max 0. (min 1. ((float_of_int i) /. totf)));
3098
lst_store#set ~row ~column:c_status status;
3090
        gtk_sync false
3099
lst_store#set ~row ~column:c_path path;
3091
      end;
3100
*)
3092
3101
      ignore (mainWindow#prepend
3093
      let (r1, action, r2, status, path) = columnsOf !theState.(i) in
3102
                [ r1; ""; r2; ""; transcodeFilename path ]);
3094
3103
      displayArrow 0 i action;
3095
      let row = mainWindowModel#append () in
3104
      displayStatusIcon i status
3096
      displayRow row i r1 r2 action status path;
3105
    done;
3097
    done;
3106
    debug (fun()-> Util.msg "reset current to %s\n"
3098
    mainWindow#set_model (Some mainWindowModel#coerce);
3107
             (match savedCurrent with None->"None" | Some(i) -> string_of_int i));
3099
    match savedCurrent with
3108
    begin match savedCurrent with
3100
    | []  -> selectSomethingIfPossible ()
3109
      None     -> selectSomethingIfPossible ()
3101
    | [x] -> select x true
3110
    | Some idx -> select idx true
3102
    | _   -> Safelist.iter (fun p -> mainWindow#selection#select_path p) savedCurrent;
3111
    end;
3103
3112
    mainWindow#thaw ();
3104
    progressBar#set_text ""; progressBar#set_fraction 0.;
3113
    updateDetails ();  (* Do we need this line? *)
3105
    updateDetails ();  (* Do we need this line? *)
3114
 in
3106
 in
3115
3107
3116
  let redisplay i =
3108
  let redisplay i si iter =
3117
    let (r1, action, r2, status, path) = columnsOf i in
3109
    let (_, action, _, status, path) = columnsOf si in
3118
    (*mainWindow#freeze ();*)
3110
    displayRowAction iter i action;
3119
    mainWindow#set_cell ~text:r1     i 0;
3111
    displayRowStatus iter status;
3120
    displayArrow i i action;
3112
    if status = Failed then displayRowPath iter (path ^
3121
    mainWindow#set_cell ~text:r2     i 2;
3113
               "       [failed: click on this line for details]");
3122
    displayStatusIcon i status;
3123
    mainWindow#set_cell ~text:(transcodeFilename path)   i 4;
3124
    if status = Failed then
3125
      mainWindow#set_cell
3126
        ~text:(transcodeFilename path ^
3127
               "       [failed: click on this line for details]") i 4;
3128
    (*mainWindow#thaw ();*)
3129
    if currentRow () = Some i then begin
3130
      updateDetails (); updateButtons ()
3131
    end
3132
  in
3114
  in
3133
3115
3134
  let fastRedisplay i =
3116
  let fastRedisplay i =
3135
    let (r1, action, r2, status, path) = columnsOf i in
3117
    let si = !theState.(i) in
3136
    displayStatusIcon i status;
3118
    let iter = mainWindowModel#get_iter (rowOfSi i) in
3137
    if status = Failed then
3119
    let (_, action, _, status, path) = columnsOf si in
3138
      mainWindow#set_cell
3120
    displayRowStatus iter status;
3139
        ~text:(transcodeFilename path ^
3121
    if status = Failed then begin
3140
               "       [failed: click on this line for details]") i 4;
3122
      displayRowPath iter (path ^
3141
    if currentRow () = Some i then updateDetails ();
3123
               "       [failed: click on this line for details]");
3124
      match currentRow () with
3125
      | Some (_, csi, _) when csi = si -> updateDetails ()
3126
      | Some _ | None -> ()
3127
    end
3128
  in
3129
3130
  let updateRowStatus i newstatus =
3131
    let row = mainWindowModel#get_iter (rowOfSi i) in
3132
    let oldstatus = mainWindowModel#get ~row ~column:c_statust in
3133
    if oldstatus <> newstatus then mainWindowModel#set ~row ~column:c_statust newstatus
3142
  in
3134
  in
3143
3135
3144
  let totalBytesToTransfer = ref Uutil.Filesize.zero in
3136
  let totalBytesToTransfer = ref Uutil.Filesize.zero in
Lines 3221-3228 lst_store#set ~row ~column:c_path path; Link Here
3221
      else Util.percent2string (Uutil.Filesize.percentageOfTotalSize b len) in
3213
      else Util.percent2string (Uutil.Filesize.percentageOfTotalSize b len) in
3222
    let dbg = if Trace.enabled "progress" then dbg ^ "/" else "" in
3214
    let dbg = if Trace.enabled "progress" then dbg ^ "/" else "" in
3223
    let newstatus = dbg ^ newstatus in
3215
    let newstatus = dbg ^ newstatus in
3224
    let oldstatus = mainWindow#cell_text i 3 in
3216
    updateRowStatus i newstatus;
3225
    if oldstatus <> newstatus then mainWindow#set_cell ~text:newstatus i 3;
3226
    showGlobalProgress bytes;
3217
    showGlobalProgress bytes;
3227
    gtk_sync false;
3218
    gtk_sync false;
3228
    begin match item.ri.replicas with
3219
    begin match item.ri.replicas with
Lines 3259-3284 lst_store#set ~row ~column:c_path path; Link Here
3259
    let lst = Array.to_list !theState in
3250
    let lst = Array.to_list !theState in
3260
    (* FIX: we should actually test whether any prefix is now ignored *)
3251
    (* FIX: we should actually test whether any prefix is now ignored *)
3261
    let keep sI = not (Globals.shouldIgnore sI.ri.path1) in
3252
    let keep sI = not (Globals.shouldIgnore sI.ri.path1) in
3262
    begin match currentRow () with
3253
    theState := Array.of_list (Safelist.filter keep lst);
3263
      None ->
3264
        theState := Array.of_list (Safelist.filter keep lst);
3265
        current := IntSet.empty
3266
    | Some index ->
3267
        let i = ref index in
3268
        let l = ref [] in
3269
        Array.iteri
3270
          (fun j sI -> if keep sI then l := sI::!l
3271
                       else if j < !i then decr i)
3272
          !theState;
3273
        theState := Array.of_list (Safelist.rev !l);
3274
        current :=
3275
          if !l = [] then IntSet.empty
3276
          else IntSet.singleton (min (!i) ((Array.length !theState) - 1))
3277
    end;
3278
    displayMain() in
3254
    displayMain() in
3279
3255
3280
  let sortAndRedisplay () =
3256
  let sortAndRedisplay () =
3281
    current := IntSet.empty;
3282
    let compareRIs = Sortri.compareReconItems() in
3257
    let compareRIs = Sortri.compareReconItems() in
3283
    Array.stable_sort (fun si1 si2 -> compareRIs si1.ri si2.ri) !theState;
3258
    Array.stable_sort (fun si1 si2 -> compareRIs si1.ri si2.ri) !theState;
3284
    displayMain() in
3259
    displayMain() in
Lines 3298-3304 lst_store#set ~row ~column:c_path path; Link Here
3298
  let clearMainWindow () =
3273
  let clearMainWindow () =
3299
    grDisactivateAll ();
3274
    grDisactivateAll ();
3300
    make_busy toplevelWindow;
3275
    make_busy toplevelWindow;
3301
    mainWindow#clear();
3276
    mainWindowModel#clear ();
3302
    detailsWindow#buffer#set_text ""
3277
    detailsWindow#buffer#set_text ""
3303
  in
3278
  in
3304
3279
Lines 3340-3346 lst_store#set ~row ~column:c_path path; Link Here
3340
            reconItemList);
3315
            reconItemList);
3341
    unsynchronizedPaths :=
3316
    unsynchronizedPaths :=
3342
      Some (Safelist.map (fun ri -> ri.path1) reconItemList, []);
3317
      Some (Safelist.map (fun ri -> ri.path1) reconItemList, []);
3343
    current := IntSet.empty;
3318
    progressBarPulse := false; sync_action := None; displayGlobalProgress 0.;
3344
    displayMain();
3319
    displayMain();
3345
    progressBarPulse := false; sync_action := None; displayGlobalProgress 0.;
3320
    progressBarPulse := false; sync_action := None; displayGlobalProgress 0.;
3346
    stopStats ();
3321
    stopStats ();
Lines 3374-3382 lst_store#set ~row ~column:c_path path; Link Here
3374
   *********************************************************************)
3349
   *********************************************************************)
3375
  let addRegExpByPath pathfunc =
3350
  let addRegExpByPath pathfunc =
3376
    Util.StringSet.iter (fun pat -> Uicommon.addIgnorePattern pat)
3351
    Util.StringSet.iter (fun pat -> Uicommon.addIgnorePattern pat)
3377
      (IntSet.fold
3352
      (currentSelectedFold
3378
         (fun i s -> Util.StringSet.add (pathfunc !theState.(i).ri.path1) s)
3353
         (fun s si -> Util.StringSet.add (pathfunc si.ri.path1) s)
3379
         !current Util.StringSet.empty);
3354
         Util.StringSet.empty);
3380
    ignoreAndRedisplay ()
3355
    ignoreAndRedisplay ()
3381
  in
3356
  in
3382
  grAdd grAction
3357
  grAdd grAction
Lines 3671-3719 lst_store#set ~row ~column:c_path path; Link Here
3671
  (*********************************************************************
3646
  (*********************************************************************
3672
    Buttons for -->, M, <--, Skip
3647
    Buttons for -->, M, <--, Skip
3673
   *********************************************************************)
3648
   *********************************************************************)
3674
  let doActionOnRow f i =
3649
  let doActionOnRow f i theSI iter =
3675
    let theSI = !theState.(i) in
3676
    begin match theSI.whatHappened, theSI.ri.replicas with
3650
    begin match theSI.whatHappened, theSI.ri.replicas with
3677
      None, Different diff ->
3651
      None, Different diff ->
3678
        f theSI.ri diff;
3652
        f theSI.ri diff;
3679
        redisplay i
3653
        redisplay i theSI iter
3680
    | _ ->
3654
    | _ ->
3681
        ()
3655
        ()
3682
    end
3656
    end
3683
  in
3657
  in
3684
  let updateCurrent () =
3685
    let n = mainWindow#rows in
3686
    (* This has quadratic complexity, thus we only do it when
3687
       the list is not too long... *)
3688
    if n < 300 then begin
3689
      current := IntSet.empty;
3690
      for i = 0 to n -1 do
3691
        if mainWindow#get_row_state i = `SELECTED then
3692
          current := IntSet.add i !current
3693
      done
3694
    end
3695
  in
3696
  let doAction f =
3658
  let doAction f =
3697
    (* FIX: when the window does not have the focus, we are not notified
3698
       immediately from changes to the list of selected items.  So, we
3699
       update our view of the current selection here. *)
3700
    updateCurrent ();
3701
    match currentRow () with
3659
    match currentRow () with
3702
      Some i ->
3660
      Some (i, si, iter) ->
3703
        doActionOnRow f i;
3661
        doActionOnRow f i si iter;
3704
        nextInteresting ()
3662
        nextInteresting ()
3705
    | None ->
3663
    | None ->
3706
        (* FIX: this is quadratic when all items are selected.
3664
        currentSelectedIter (fun i si iter -> doActionOnRow f i si iter);
3707
           We could trigger a redisplay instead, but it may be tricky
3665
        updateDetails ()
3708
           to preserve the set of selected rows, the focus row and the
3709
           scrollbar position.
3710
           The right fix is probably to move to a GTree.column_list. *)
3711
        let n = IntSet.cardinal !current in
3712
        if n > 0 then begin
3713
          if n > 20 then mainWindow#freeze ();
3714
          IntSet.iter (fun i -> doActionOnRow f i) !current;
3715
          if n > 20 then mainWindow#thaw ()
3716
        end
3717
  in
3666
  in
3718
  let leftAction _ =
3667
  let leftAction _ =
3719
    doAction (fun _ diff -> diff.direction <- Replica2ToReplica1) in
3668
    doAction (fun _ diff -> diff.direction <- Replica2ToReplica1) in
Lines 3764-3772 lst_store#set ~row ~column:c_path path; Link Here
3764
   *********************************************************************)
3713
   *********************************************************************)
3765
  let diffCmd () =
3714
  let diffCmd () =
3766
    match currentRow () with
3715
    match currentRow () with
3767
      Some i ->
3716
      Some (i, item, _) ->
3768
        getLock (fun () ->
3717
        getLock (fun () ->
3769
          let item = !theState.(i) in
3770
          let len =
3718
          let len =
3771
            match item.ri.replicas with
3719
            match item.ri.replicas with
3772
              Problem _ ->
3720
              Problem _ ->
Lines 3844-3852 lst_store#set ~row ~column:c_path path; Link Here
3844
    debug (fun()-> Util.msg "Loading profile %s..." p);
3792
    debug (fun()-> Util.msg "Loading profile %s..." p);
3845
    Trace.status "Loading profile";
3793
    Trace.status "Loading profile";
3846
    unsynchronizedPaths := None;
3794
    unsynchronizedPaths := None;
3847
    Uicommon.initPrefs p
3795
    Uicommon.initPrefs ~profileName:p
3848
      (fun () -> if not reload then displayWaitMessage ())
3796
      ~displayWaitMessage:(fun () -> if not reload then displayWaitMessage ())
3849
      getFirstRoot getSecondRoot termInteract;
3797
      ~getFirstRoot ~getSecondRoot ~termInteract;
3850
    !updateFromProfile ()
3798
    !updateFromProfile ()
3851
  in
3799
  in
3852
3800
Lines 3858-3864 lst_store#set ~row ~column:c_path path; Link Here
3858
    in
3806
    in
3859
    clearMainWindow ();
3807
    clearMainWindow ();
3860
    if not (Prefs.profileUnchanged ()) then loadProfile n true
3808
    if not (Prefs.profileUnchanged ()) then loadProfile n true
3861
    else Uicommon.refreshConnection displayWaitMessage termInteract
3809
    else Uicommon.refreshConnection ~displayWaitMessage ~termInteract
3862
  in
3810
  in
3863
3811
3864
  let detectCmd () =
3812
  let detectCmd () =
Lines 3908-3923 lst_store#set ~row ~column:c_path path; Link Here
3908
    Action menu
3856
    Action menu
3909
   *********************************************************************)
3857
   *********************************************************************)
3910
  let buildActionMenu init =
3858
  let buildActionMenu init =
3859
    let withDelayedUpdates f x =
3860
      delayUpdates := true;
3861
      f x;
3862
      delayUpdates := false;
3863
      updateDetails () in
3911
    let actionMenu = replace_submenu "_Actions" actionItem in
3864
    let actionMenu = replace_submenu "_Actions" actionItem in
3912
    grAdd grRescan
3865
    grAdd grRescan
3913
      (actionMenu#add_image_item
3866
      (actionMenu#add_image_item
3914
         ~callback:(fun _ -> mainWindow#select_all ())
3867
         ~callback:(fun _ -> withDelayedUpdates mainWindow#selection#select_all ())
3915
         ~image:((GMisc.image ~stock:`SELECT_ALL ~icon_size:`MENU ())#coerce)
3868
         ~image:((GMisc.image ~stock:`SELECT_ALL ~icon_size:`MENU ())#coerce)
3916
         ~modi:[`CONTROL] ~key:GdkKeysyms._A
3869
         ~modi:[`CONTROL] ~key:GdkKeysyms._A
3917
         "Select _All");
3870
         "Select _All");
3918
    grAdd grRescan
3871
    grAdd grRescan
3919
      (actionMenu#add_item
3872
      (actionMenu#add_item
3920
         ~callback:(fun _ -> mainWindow#unselect_all ())
3873
         ~callback:(fun _ -> withDelayedUpdates mainWindow#selection#unselect_all ())
3921
         ~modi:[`SHIFT; `CONTROL] ~key:GdkKeysyms._A
3874
         ~modi:[`SHIFT; `CONTROL] ~key:GdkKeysyms._A
3922
         "_Deselect All");
3875
         "_Deselect All");
3923
3876
Lines 4213-4225 let start _ = Link Here
4213
    let detectCmd = createToplevelWindow() in
4166
    let detectCmd = createToplevelWindow() in
4214
4167
4215
    Uicommon.uiInit
4168
    Uicommon.uiInit
4216
      fatalError
4169
      ~reportError:fatalError
4217
      tryAgainOrQuit
4170
      ~tryAgainOrQuit
4218
      displayWaitMessage
4171
      ~displayWaitMessage
4219
      (fun () -> getProfile true)
4172
      ~getProfile:(fun () -> getProfile true)
4220
      getFirstRoot
4173
      ~getFirstRoot
4221
      getSecondRoot
4174
      ~getSecondRoot
4222
      termInteract;
4175
      ~termInteract;
4223
    detectCmd ();
4176
    detectCmd ();
4224
4177
4225
    (* Display the ui *)
4178
    (* Display the ui *)

Return to bug 769341