1811.1.1
by Jeremy Wootten
Code clean: tabs, trailing space, headers, comments |
1 |
/***
|
2432.1.1
by Leonardo Lemos
Bump copyright years |
2 |
Copyright (c) 2015-2017 elementary LLC (http://launchpad.net/elementary)
|
1811.1.1
by Jeremy Wootten
Code clean: tabs, trailing space, headers, comments |
3 |
|
4 |
This program is free software; you can redistribute it and/or modify
|
|
5 |
it under the terms of the GNU General Public License as published by
|
|
2484.2.1
by Jeremy Wootten
Fix licensecheck warnings |
6 |
the Free Software Foundation, Inc.,; either version 2 of the License, or
|
1811.1.1
by Jeremy Wootten
Code clean: tabs, trailing space, headers, comments |
7 |
(at your option) any later version.
|
8 |
||
9 |
This program is distributed in the hope that it will be useful,
|
|
10 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12 |
GNU General Public License for more details.
|
|
13 |
||
14 |
You should have received a copy of the GNU General Public License
|
|
15 |
along with this program; if not, write to the Free Software
|
|
16 |
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
17 |
MA 02110-1301, USA.
|
|
18 |
||
19 |
Authors: Jeremy Wootten <jeremy@elementaryos.org>
|
|
20 |
***/
|
|
1459.1.50
by jeremy at elementaryos
Some reorganisation; Add new widgets etc to bzr |
21 |
|
1953.1.2
by Jeremy Wootten
Move Enums MimeActions and DndHandler into libcore |
22 |
namespace Marlin { |
1459.1.50
by jeremy at elementaryos
Some reorganisation; Add new widgets etc to bzr |
23 |
public class DndHandler : GLib.Object { |
24 |
Gdk.DragAction chosen = Gdk.DragAction.DEFAULT; |
|
25 |
||
1459.1.169
by jeremy at elementaryos
Adjust code formatting for consistency; remove temporary debugging code; rename DirectoryView to AbstractDirectoryView for consistency |
26 |
public DndHandler () {} |
1459.1.50
by jeremy at elementaryos
Some reorganisation; Add new widgets etc to bzr |
27 |
|
28 |
public bool dnd_perform (Gtk.Widget widget, |
|
29 |
GOF.File drop_target, |
|
1459.1.68
by jeremy at elementaryos
Fix multiple drag with right-click |
30 |
GLib.List<GLib.File> drop_file_list, |
1459.1.50
by jeremy at elementaryos
Some reorganisation; Add new widgets etc to bzr |
31 |
Gdk.DragAction action) { |
32 |
||
33 |
if (drop_target.is_folder ()) { |
|
1459.1.68
by jeremy at elementaryos
Fix multiple drag with right-click |
34 |
Marlin.FileOperations.copy_move (drop_file_list, |
1459.1.50
by jeremy at elementaryos
Some reorganisation; Add new widgets etc to bzr |
35 |
null, |
36 |
drop_target.get_target_location (), |
|
37 |
action, |
|
38 |
widget, |
|
1710.1.2
by jeremy at elementaryos
Fix cursor overlay when dropping into trash, silence some warnings |
39 |
null, |
1459.1.50
by jeremy at elementaryos
Some reorganisation; Add new widgets etc to bzr |
40 |
null); |
41 |
return true; |
|
42 |
} else if (drop_target.is_executable ()) { |
|
43 |
GLib.Error error; |
|
1459.1.68
by jeremy at elementaryos
Fix multiple drag with right-click |
44 |
if (!drop_target.execute (widget.get_screen (), drop_file_list, out error)) { |
1459.1.50
by jeremy at elementaryos
Some reorganisation; Add new widgets etc to bzr |
45 |
Eel.show_error_dialog (_("Failed to execute \"%s\"").printf (drop_target.get_display_name ()), |
46 |
error.message, |
|
47 |
null); |
|
48 |
return false; |
|
49 |
} else |
|
50 |
return true; |
|
51 |
}
|
|
52 |
return false; |
|
53 |
}
|
|
54 |
||
55 |
public Gdk.DragAction? drag_drop_action_ask (Gtk.Widget dest_widget, |
|
56 |
Gtk.ApplicationWindow win, |
|
57 |
Gdk.DragAction possible_actions) { |
|
58 |
this.chosen = Gdk.DragAction.DEFAULT; |
|
59 |
add_action (win); |
|
60 |
var ask_menu = build_menu (possible_actions); |
|
61 |
ask_menu.set_screen (dest_widget.get_screen ()); |
|
62 |
ask_menu.show_all (); |
|
63 |
var loop = new GLib.MainLoop (null, false); |
|
1459.1.169
by jeremy at elementaryos
Adjust code formatting for consistency; remove temporary debugging code; rename DirectoryView to AbstractDirectoryView for consistency |
64 |
|
1459.1.50
by jeremy at elementaryos
Some reorganisation; Add new widgets etc to bzr |
65 |
ask_menu.deactivate.connect (() => { |
66 |
if (loop.is_running ()) |
|
67 |
loop.quit (); |
|
68 |
||
69 |
remove_action (win); |
|
70 |
});
|
|
1459.1.169
by jeremy at elementaryos
Adjust code formatting for consistency; remove temporary debugging code; rename DirectoryView to AbstractDirectoryView for consistency |
71 |
|
1459.1.50
by jeremy at elementaryos
Some reorganisation; Add new widgets etc to bzr |
72 |
ask_menu.popup (null, null, null, 0, Gdk.CURRENT_TIME); |
73 |
loop.run (); |
|
74 |
Gtk.grab_remove (ask_menu); |
|
1459.1.169
by jeremy at elementaryos
Adjust code formatting for consistency; remove temporary debugging code; rename DirectoryView to AbstractDirectoryView for consistency |
75 |
|
1459.1.50
by jeremy at elementaryos
Some reorganisation; Add new widgets etc to bzr |
76 |
return this.chosen; |
77 |
}
|
|
78 |
||
79 |
private void add_action (Gtk.ApplicationWindow win) { |
|
80 |
var action = new GLib.SimpleAction ("choice", GLib.VariantType.STRING); |
|
81 |
action.activate.connect (this.on_choice); |
|
1811.1.1
by Jeremy Wootten
Code clean: tabs, trailing space, headers, comments |
82 |
|
1459.1.50
by jeremy at elementaryos
Some reorganisation; Add new widgets etc to bzr |
83 |
win.add_action (action); |
84 |
}
|
|
85 |
||
86 |
private void remove_action (Gtk.ApplicationWindow win) { |
|
87 |
win.remove_action ("choice"); |
|
88 |
}
|
|
89 |
||
90 |
private Gtk.Menu build_menu (Gdk.DragAction possible_actions) { |
|
91 |
var menu = new Gtk.Menu (); |
|
92 |
||
93 |
build_and_append_menu_item (menu, _("Move Here"), Gdk.DragAction.MOVE, possible_actions); |
|
94 |
build_and_append_menu_item (menu, _("Copy Here"), Gdk.DragAction.COPY, possible_actions); |
|
95 |
build_and_append_menu_item (menu, _("Link Here"), Gdk.DragAction.LINK, possible_actions); |
|
96 |
||
97 |
menu.append (new Gtk.SeparatorMenuItem ()); |
|
98 |
menu.append (new Gtk.MenuItem.with_label (_("Cancel"))); |
|
99 |
||
100 |
return menu; |
|
101 |
}
|
|
102 |
||
103 |
private void build_and_append_menu_item (Gtk.Menu menu, string label, Gdk.DragAction? action, Gdk.DragAction possible_actions) { |
|
104 |
if ((possible_actions & action) != 0) { |
|
105 |
var item = new Gtk.MenuItem.with_label (label); |
|
1459.1.169
by jeremy at elementaryos
Adjust code formatting for consistency; remove temporary debugging code; rename DirectoryView to AbstractDirectoryView for consistency |
106 |
|
1459.1.50
by jeremy at elementaryos
Some reorganisation; Add new widgets etc to bzr |
107 |
item.activate.connect (() => { |
108 |
this.chosen = action; |
|
109 |
});
|
|
1459.1.169
by jeremy at elementaryos
Adjust code formatting for consistency; remove temporary debugging code; rename DirectoryView to AbstractDirectoryView for consistency |
110 |
|
1459.1.50
by jeremy at elementaryos
Some reorganisation; Add new widgets etc to bzr |
111 |
menu.append (item); |
112 |
}
|
|
113 |
}
|
|
114 |
||
115 |
public void on_choice (GLib.Variant? param) { |
|
116 |
if (param == null || !param.is_of_type (GLib.VariantType.STRING)) { |
|
117 |
critical ("Invalid variant type in DndHandler Menu"); |
|
118 |
return; |
|
119 |
}
|
|
120 |
||
121 |
string choice = param.get_string (); |
|
1459.1.169
by jeremy at elementaryos
Adjust code formatting for consistency; remove temporary debugging code; rename DirectoryView to AbstractDirectoryView for consistency |
122 |
|
1459.1.50
by jeremy at elementaryos
Some reorganisation; Add new widgets etc to bzr |
123 |
switch (choice) { |
124 |
case "move": |
|
125 |
this.chosen = Gdk.DragAction.MOVE; |
|
126 |
break; |
|
127 |
case "copy": |
|
128 |
this.chosen = Gdk.DragAction.COPY; |
|
129 |
break; |
|
130 |
case "link": |
|
131 |
this.chosen = Gdk.DragAction.LINK; |
|
132 |
break; |
|
133 |
case "background": /* not implemented yet */ |
|
134 |
case "cancel": |
|
135 |
default: |
|
136 |
this.chosen = Gdk.DragAction.DEFAULT; |
|
137 |
break; |
|
138 |
}
|
|
139 |
}
|
|
140 |
||
141 |
public string? get_source_filename (Gdk.DragContext context) { |
|
142 |
uchar []? data = null; |
|
143 |
Gdk.Atom property_name = Gdk.Atom.intern_static_string ("XdndDirectSave0"); |
|
144 |
Gdk.Atom property_type = Gdk.Atom.intern_static_string ("text/plain"); |
|
145 |
||
146 |
bool exists = Gdk.property_get (context.get_source_window (), |
|
147 |
property_name, |
|
148 |
property_type, |
|
149 |
0, /* offset into property to start getting */ |
|
150 |
1024, /* max bytes of data to retrieve */ |
|
151 |
0, /* do not delete after retrieving */ |
|
152 |
null, null, /* actual property type and format got disregarded */ |
|
153 |
out data |
|
154 |
);
|
|
1811.1.1
by Jeremy Wootten
Code clean: tabs, trailing space, headers, comments |
155 |
|
1459.1.50
by jeremy at elementaryos
Some reorganisation; Add new widgets etc to bzr |
156 |
if (exists && data != null) { |
2228.1.1
by Jeremy Wootten
Rewrite ClipboardManager in Vala |
157 |
string name = DndHandler.data_to_string (data); |
1459.1.50
by jeremy at elementaryos
Some reorganisation; Add new widgets etc to bzr |
158 |
if (GLib.Path.DIR_SEPARATOR.to_string () in name) { |
159 |
warning ("invalid source filename"); |
|
160 |
return null; /* not a valid filename */ |
|
161 |
} else |
|
162 |
return name; |
|
163 |
} else { |
|
164 |
warning ("source file does not exist"); |
|
165 |
return null; |
|
166 |
}
|
|
167 |
}
|
|
168 |
||
169 |
public void set_source_uri (Gdk.DragContext context, string uri) { |
|
1459.1.169
by jeremy at elementaryos
Adjust code formatting for consistency; remove temporary debugging code; rename DirectoryView to AbstractDirectoryView for consistency |
170 |
debug ("DNDHANDLER: set source uri to %s", uri); |
1459.1.50
by jeremy at elementaryos
Some reorganisation; Add new widgets etc to bzr |
171 |
Gdk.Atom property_name = Gdk.Atom.intern_static_string ("XdndDirectSave0"); |
172 |
Gdk.Atom property_type = Gdk.Atom.intern_static_string ("text/plain"); |
|
173 |
Gdk.property_change (context.get_source_window (), |
|
174 |
property_name, |
|
175 |
property_type, |
|
176 |
8, |
|
177 |
Gdk.PropMode.REPLACE, |
|
178 |
uri.data, |
|
179 |
uri.length); |
|
180 |
}
|
|
181 |
||
1459.1.169
by jeremy at elementaryos
Adjust code formatting for consistency; remove temporary debugging code; rename DirectoryView to AbstractDirectoryView for consistency |
182 |
public bool handle_xdnddirectsave (Gdk.DragContext context, |
183 |
GOF.File drop_target, |
|
184 |
Gtk.SelectionData selection) { |
|
1459.1.50
by jeremy at elementaryos
Some reorganisation; Add new widgets etc to bzr |
185 |
bool success = false; |
1459.1.169
by jeremy at elementaryos
Adjust code formatting for consistency; remove temporary debugging code; rename DirectoryView to AbstractDirectoryView for consistency |
186 |
|
1459.1.50
by jeremy at elementaryos
Some reorganisation; Add new widgets etc to bzr |
187 |
if (selection.get_length () == 1 && selection.get_format () == 8) { |
188 |
uchar result = selection.get_data ()[0]; |
|
1459.1.169
by jeremy at elementaryos
Adjust code formatting for consistency; remove temporary debugging code; rename DirectoryView to AbstractDirectoryView for consistency |
189 |
|
1459.1.50
by jeremy at elementaryos
Some reorganisation; Add new widgets etc to bzr |
190 |
switch (result) { |
191 |
case 'F': |
|
192 |
/* No fallback for XdndDirectSave stage (3), result "F" ("Failed") yet */
|
|
193 |
break; |
|
1871.1.1
by Jeremy Wootten
Fix drop from other apps - text/uri-list and XdndDirectSave0 |
194 |
case 'E': |
195 |
/* No fallback for XdndDirectSave stage (3), result "E" ("Error") yet.
|
|
196 |
* Note this result may be obtained even if the file was successfully saved */
|
|
197 |
break; |
|
1459.1.50
by jeremy at elementaryos
Some reorganisation; Add new widgets etc to bzr |
198 |
case 'S': |
199 |
/* XdndDirectSave "Success" */
|
|
200 |
success = true; |
|
201 |
break; |
|
202 |
default: |
|
203 |
warning ("Unhandled XdndDirectSave result %s", result.to_string ()); |
|
204 |
break; |
|
205 |
}
|
|
206 |
}
|
|
1459.1.169
by jeremy at elementaryos
Adjust code formatting for consistency; remove temporary debugging code; rename DirectoryView to AbstractDirectoryView for consistency |
207 |
|
1459.1.50
by jeremy at elementaryos
Some reorganisation; Add new widgets etc to bzr |
208 |
if (!success) |
209 |
set_source_uri (context, ""); |
|
210 |
||
211 |
return success; |
|
212 |
}
|
|
213 |
||
214 |
public bool handle_netscape_url (Gdk.DragContext context, GOF.File drop_target, Gtk.SelectionData selection) { |
|
215 |
string [] parts = (selection.get_text ()).split ("\n"); |
|
1459.1.169
by jeremy at elementaryos
Adjust code formatting for consistency; remove temporary debugging code; rename DirectoryView to AbstractDirectoryView for consistency |
216 |
|
1459.1.50
by jeremy at elementaryos
Some reorganisation; Add new widgets etc to bzr |
217 |
/* _NETSCAPE_URL looks like this: "$URL\n$TITLE" - should be 2 parts */
|
218 |
if (parts.length != 2) |
|
219 |
return false; |
|
220 |
||
1459.1.193
by jeremy at elementaryos
Remove unnecessary comment lines, remove redundant files, remove or revise TODOs and FIXMEs, update about dialog authors list and AUTHORS file |
221 |
/* NETSCAPE URLs are not currently handled. No current bug reports */
|
1459.1.50
by jeremy at elementaryos
Some reorganisation; Add new widgets etc to bzr |
222 |
return false; |
223 |
}
|
|
224 |
||
225 |
public bool handle_file_drag_actions (Gtk.Widget dest_widget, |
|
226 |
Gtk.ApplicationWindow win, |
|
227 |
Gdk.DragContext context, |
|
228 |
GOF.File drop_target, |
|
229 |
GLib.List<GLib.File> drop_file_list, |
|
230 |
Gdk.DragAction possible_actions, |
|
231 |
Gdk.DragAction suggested_action, |
|
232 |
uint32 timestamp) { |
|
233 |
bool success = false; |
|
234 |
Gdk.DragAction action = suggested_action; |
|
235 |
||
236 |
if ((possible_actions & Gdk.DragAction.ASK) != 0) |
|
237 |
action = drag_drop_action_ask (dest_widget, win, possible_actions); |
|
238 |
||
239 |
if (action != Gdk.DragAction.DEFAULT) { |
|
240 |
success = dnd_perform (dest_widget, |
|
241 |
drop_target, |
|
242 |
drop_file_list, |
|
243 |
action); |
|
244 |
}
|
|
245 |
return success; |
|
246 |
}
|
|
247 |
||
248 |
||
2228.1.1
by Jeremy Wootten
Rewrite ClipboardManager in Vala |
249 |
public static bool selection_data_is_uri_list (Gtk.SelectionData selection_data, uint info, out string? text) { |
1459.1.50
by jeremy at elementaryos
Some reorganisation; Add new widgets etc to bzr |
250 |
text = null; |
1459.1.169
by jeremy at elementaryos
Adjust code formatting for consistency; remove temporary debugging code; rename DirectoryView to AbstractDirectoryView for consistency |
251 |
|
1953.1.2
by Jeremy Wootten
Move Enums MimeActions and DndHandler into libcore |
252 |
if (info == Marlin.TargetType.TEXT_URI_LIST && |
1459.1.169
by jeremy at elementaryos
Adjust code formatting for consistency; remove temporary debugging code; rename DirectoryView to AbstractDirectoryView for consistency |
253 |
selection_data.get_format () == 8 && |
254 |
selection_data.get_length () > 0) { |
|
1459.1.50
by jeremy at elementaryos
Some reorganisation; Add new widgets etc to bzr |
255 |
|
2228.1.1
by Jeremy Wootten
Rewrite ClipboardManager in Vala |
256 |
text = DndHandler.data_to_string (selection_data.get_data_with_length ()); |
1459.1.50
by jeremy at elementaryos
Some reorganisation; Add new widgets etc to bzr |
257 |
}
|
1459.1.169
by jeremy at elementaryos
Adjust code formatting for consistency; remove temporary debugging code; rename DirectoryView to AbstractDirectoryView for consistency |
258 |
debug ("DNDHANDLER selection data is uri list returning %s", (text != null).to_string ()); |
1459.1.50
by jeremy at elementaryos
Some reorganisation; Add new widgets etc to bzr |
259 |
return (text != null); |
260 |
}
|
|
261 |
||
2228.1.1
by Jeremy Wootten
Rewrite ClipboardManager in Vala |
262 |
public static string data_to_string (uchar [] cdata) { |
1459.1.50
by jeremy at elementaryos
Some reorganisation; Add new widgets etc to bzr |
263 |
var sb = new StringBuilder (""); |
264 |
||
1459.1.169
by jeremy at elementaryos
Adjust code formatting for consistency; remove temporary debugging code; rename DirectoryView to AbstractDirectoryView for consistency |
265 |
foreach (uchar u in cdata) |
1459.1.50
by jeremy at elementaryos
Some reorganisation; Add new widgets etc to bzr |
266 |
sb.append_c ((char)u); |
267 |
||
268 |
return sb.str; |
|
269 |
}
|
|
2228.1.1
by Jeremy Wootten
Rewrite ClipboardManager in Vala |
270 |
|
271 |
public static void set_selection_data_from_file_list (Gtk.SelectionData selection_data, |
|
272 |
GLib.List<GOF.File> file_list, |
|
273 |
string? prefix = "") { |
|
274 |
||
275 |
GLib.StringBuilder sb = new GLib.StringBuilder (prefix); |
|
2228.1.3
by Jeremy Wootten
Merge trunk to r2319 |
276 |
bool in_recent = file_list.data.is_recent_uri_scheme (); |
2228.1.1
by Jeremy Wootten
Rewrite ClipboardManager in Vala |
277 |
|
278 |
file_list.@foreach ((file) => { |
|
2228.1.3
by Jeremy Wootten
Merge trunk to r2319 |
279 |
var target = in_recent ? file.get_display_target_uri () : file.get_target_location ().get_uri (); |
280 |
sb.append (target); |
|
2228.1.1
by Jeremy Wootten
Rewrite ClipboardManager in Vala |
281 |
sb.append ("\r\n"); /* Drop onto Filezilla does not work without the "\r" */ |
282 |
});
|
|
283 |
||
284 |
selection_data.@set (selection_data.get_target (), |
|
285 |
8, |
|
286 |
sb.data); |
|
2228.1.3
by Jeremy Wootten
Merge trunk to r2319 |
287 |
|
2228.1.1
by Jeremy Wootten
Rewrite ClipboardManager in Vala |
288 |
}
|
1459.1.50
by jeremy at elementaryos
Some reorganisation; Add new widgets etc to bzr |
289 |
}
|
290 |
}
|