# # patch "ui.ml" # from [7d156a725cc388c4495bc8b46dbb062386ac0845] # to [2ab3b05377540a6ddfc6d893d74691e495c1ee58] # # patch "view.ml" # from [93359e592e49c18a122c0fe1d2ce4ad103481fd9] # to [762e4cf45b09e19c3275a5c995b585e1fd432e8e] # # patch "view.mli" # from [ea0d6527fe87a36240b73f80ceb15dd2f256baee] # to [892722ed6f7f65f92555cc5b7609554a07f5c2ea] # ======================================================================== --- ui.ml 7d156a725cc388c4495bc8b46dbb062386ac0845 +++ ui.ml 2ab3b05377540a6ddfc6d893d74691e495c1ee58 @@ -73,8 +73,8 @@ add "Diff_one" ~label:"Diff with ancestor" ; add "Diff_many" ~label:"Diff with ancestor" ; add "Diff_other" ~label:"Diff with selected node" ; - add "Copy_revision" ~label:"Copy revision id to the clipboard" ; - add "Copy_manifest" ~label:"Copy manifest id to the clipboard" ] ; + add "Copy_revision" ~stock:`COPY ~label:"Copy revision id to the clipboard" ; + add "Copy_manifest" ~stock:`COPY ~label:"Copy manifest id to the clipboard" ] ; let g_view = GAction.action_group ~name:"view" () in GAction.add_actions g_view [ add "ViewMenu" ~label:"_View" ; @@ -94,7 +94,7 @@ group = g ; signals = [] ; popup_id = "" ; - clipboard = GData.clipboard Gdk.Atom.primary + clipboard = GData.clipboard Gdk.Atom.clipboard } let make_manager () = ======================================================================== --- view.ml 93359e592e49c18a122c0fe1d2ce4ad103481fd9 +++ view.ml 762e4cf45b09e19c3275a5c995b585e1fd432e8e @@ -104,6 +104,7 @@ event_signal : event Signal.t ; mutable selected_node : string option ; status_reporter : Status.reporter Lazy.t ; + mutable drag_active : bool ; } let get_cnodes v = @@ -765,6 +766,7 @@ | 1 -> KeyNav.select v id ; Signal.emit v.event_signal (`NODE_SELECT id) ; + v.drag_active <- true ; true | 3 -> Signal.emit v.event_signal (`NODE_POPUP (id, 3)) ; @@ -1004,7 +1006,8 @@ agraph = None ; event_signal = Signal.make () ; selected_node = None ; - status_reporter = lazy (Status.new_reporter "monotone") + status_reporter = lazy (Status.new_reporter "monotone") ; + drag_active = false } in Branch_selector.connect v (handle_query v) ; @@ -1022,6 +1025,52 @@ | _ -> false)) end ; + begin + let canvas = v.canvas.w in + let setup_drag v = + canvas#drag#source_set + ~modi:[`BUTTON1] ~actions:[`COPY] + [ { Gtk.target = "text/plain" ; Gtk.flags = [] ; Gtk.info = 1 } ] in + + setup_drag v ; + + (* OK, this is a bit complicated: GTK+ supports DnD at the widget + level but here I want DnD for a GnomeCanvasItem (a node in the + ancestry graph. So the GnomeCanvas is set up as a + DragSource. In the button press event handler of the canvas + item, the drag_active field is set to true. In a event handler + of the canvas widget for button press (connected with after so + that it runs after the canvas item ones), I check drag_active: + if false, that means the click was outside a node and I call + gtk_drag_source_unset(). In the button release handler, I reset + drag_active to false and re-setup the canvas as a drag + source. *) + + ignore (canvas#event#connect#after#button_press + (fun ev -> + if GdkEvent.Button.button ev = 1 && not v.drag_active + then canvas#drag#source_unset () ; + false)) ; + + ignore (canvas#event#connect#button_release + (fun ev -> + if GdkEvent.Button.button ev = 1 + then begin + if v.drag_active + then v.drag_active <- false + else setup_drag v + end ; + false)) ; + + ignore (canvas#drag#connect#data_get + (fun ctx sel_ctx ~info ~time -> + match v.selected_node with + | Some id when info = 1 -> + sel_ctx#return id + | _ -> ())) + end ; + + connect_event v (function | `NODE_SELECT id -> Canvas.display_selection_marker v id ; ======================================================================== --- view.mli ea0d6527fe87a36240b73f80ceb15dd2f256baee +++ view.mli 892722ed6f7f65f92555cc5b7609554a07f5c2ea @@ -30,6 +30,7 @@ event_signal : event Viz_misc.Signal.t; mutable selected_node : string option; status_reporter : Status.reporter Lazy.t; + mutable drag_active : bool; } module Info_Display :