1 /*
2  *
3  *   Copyright (C) 2005-2018 by C.H. Huang
4  *   plushuang.tw@gmail.com
5  *
6  *  This library is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU Lesser General Public
8  *  License as published by the Free Software Foundation; either
9  *  version 2.1 of the License, or (at your option) any later version.
10  *
11  *  This library is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  *  Lesser General Public License for more details.
15  *
16  *  You should have received a copy of the GNU Lesser General Public
17  *  License along with this library; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  *  ---
21  *
22  *  In addition, as a special exception, the copyright holders give
23  *  permission to link the code of portions of this program with the
24  *  OpenSSL library under certain conditions as described in each
25  *  individual source file, and distribute linked combinations
26  *  including the two.
27  *  You must obey the GNU Lesser General Public License in all respects
28  *  for all of the code used other than OpenSSL.  If you modify
29  *  file(s) with this exception, you may extend this exception to your
30  *  version of the file(s), but you are not obligated to do so.  If you
31  *  do not wish to do so, delete this exception statement from your
32  *  version.  If you delete this exception statement from all source
33  *  files in the program, then also delete it here.
34  *
35  */
36 
37 #include <UgUri.h>
38 #include <UgString.h>
39 #include <UgtkDownloadForm.h>
40 #include <UgetData.h>
41 #include <UgtkApp.h>		// UGTK_APP_NAME
42 
43 #include <glib/gi18n.h>
44 
45 
46 static void ugtk_download_form_init_page1 (UgtkDownloadForm* dform, UgtkProxyForm* proxy);
47 static void ugtk_download_form_init_page2 (UgtkDownloadForm* dform);
48 //	signal handler
49 static void on_spin_changed (GtkEditable *editable, UgtkDownloadForm* dform);
50 static void on_entry_changed (GtkEditable *editable, UgtkDownloadForm* dform);
51 static void on_uri_entry_changed (GtkEditable *editable, UgtkDownloadForm* dform);
52 static void on_http_entry_changed (GtkEditable *editable, UgtkDownloadForm* dform);
53 static void on_select_folder (GtkEntry* entry, GtkEntryIconPosition icon_pos, GdkEvent* event, UgtkDownloadForm* dform);
54 static void on_select_cookie (GtkEntry* entry, GtkEntryIconPosition icon_pos, GdkEvent* event, UgtkDownloadForm* dform);
55 static void on_select_post   (GtkEntry* entry, GtkEntryIconPosition icon_pos, GdkEvent* event, UgtkDownloadForm* dform);
56 
57 
58 void  ugtk_download_form_init (UgtkDownloadForm* dform, UgtkProxyForm* proxy, GtkWindow* parent)
59 {
60 	dform->changed.enable   = TRUE;
61 	dform->changed.uri      = FALSE;
62 	dform->changed.file     = FALSE;
63 	dform->changed.folder   = FALSE;
64 	dform->changed.user     = FALSE;
65 	dform->changed.password = FALSE;
66 	dform->changed.referrer = FALSE;
67 	dform->changed.cookie   = FALSE;
68 	dform->changed.post     = FALSE;
69 	dform->changed.agent    = FALSE;
70 	dform->changed.retry    = FALSE;
71 	dform->changed.delay    = FALSE;
72 	dform->changed.timestamp= FALSE;
73 	dform->parent = parent;
74 
75 	ugtk_download_form_init_page1 (dform, proxy);
76 	ugtk_download_form_init_page2 (dform);
77 
78 	gtk_widget_show_all (dform->page1);
79 	gtk_widget_show_all (dform->page2);
80 }
81 
82 static void ugtk_download_form_init_page1 (UgtkDownloadForm* dform, UgtkProxyForm* proxy)
83 {
84 	GtkWidget*  widget;
85 	GtkGrid*    top_grid;
86 	GtkGrid*    grid;
87 	GtkWidget*  frame;
88 	GtkBox*	    top_vbox;
89 	GtkWidget*  vbox;
90 	GtkWidget*  hbox;
91 
92 	dform->page1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
93 	top_vbox = (GtkBox*) dform->page1;
94 	gtk_container_set_border_width (GTK_CONTAINER (top_vbox), 2);
95 
96 	top_grid = (GtkGrid*) gtk_grid_new ();
97 	gtk_box_pack_start (top_vbox, (GtkWidget*) top_grid, FALSE, FALSE, 0);
98 
99 	// URL - entry
100 	widget = gtk_entry_new ();
101 //	gtk_entry_set_width_chars (GTK_ENTRY (widget), 20); // remove for GTK+ 3.12
102 	gtk_entry_set_activates_default (GTK_ENTRY (widget), TRUE);
103 	g_object_set (widget, "margin-left", 1, "margin-right", 1, NULL);
104 	g_object_set (widget, "margin-top", 2, "margin-bottom", 2, NULL);
105 	g_object_set (widget, "hexpand", TRUE, NULL);
106 	gtk_grid_attach (top_grid, widget, 1, 0, 2, 1);
107 	g_signal_connect (GTK_EDITABLE (widget), "changed",
108 			G_CALLBACK (on_uri_entry_changed), dform);
109 	dform->uri_entry = widget;
110 	// URL - label
111 	widget = gtk_label_new_with_mnemonic (_("_URI:"));
112 	gtk_label_set_mnemonic_widget (GTK_LABEL(widget), dform->uri_entry);
113 	g_object_set (widget, "margin-left", 3, "margin-right", 3, NULL);
114 	g_object_set (widget, "margin-top", 2, "margin-bottom", 2, NULL);
115 	gtk_grid_attach (top_grid, widget, 0, 0, 1, 1);
116 	dform->uri_label = widget;
117 
118 	// Mirrors - entry
119 	widget = gtk_entry_new ();
120 //	gtk_entry_set_width_chars (GTK_ENTRY (widget), 20); // remove for GTK+ 3.12
121 	gtk_entry_set_activates_default (GTK_ENTRY (widget), TRUE);
122 	g_object_set (widget, "margin-left", 1, "margin-right", 1, NULL);
123 	g_object_set (widget, "margin-top", 2, "margin-bottom", 2, NULL);
124 	g_object_set (widget, "hexpand", TRUE, NULL);
125 	gtk_grid_attach (top_grid, widget, 1, 1, 2, 1);
126 	g_signal_connect (GTK_EDITABLE (widget), "changed",
127 			G_CALLBACK (on_uri_entry_changed), dform);
128 	dform->mirrors_entry = widget;
129 	// Mirrors - label
130 	widget = gtk_label_new_with_mnemonic (_("Mirrors:"));
131 	gtk_label_set_mnemonic_widget (GTK_LABEL(widget), dform->mirrors_entry);
132 	g_object_set (widget, "margin-left", 3, "margin-right", 3, NULL);
133 	g_object_set (widget, "margin-top", 2, "margin-bottom", 2, NULL);
134 	gtk_grid_attach (top_grid, widget, 0, 1, 1, 1);
135 	dform->mirrors_label = widget;
136 
137 	// File - entry
138 	widget = gtk_entry_new ();
139 	gtk_entry_set_activates_default (GTK_ENTRY (widget), TRUE);
140 	gtk_entry_set_placeholder_text (GTK_ENTRY (widget),
141 			_("Leave blank to use default filename ..."));
142 	g_object_set (widget, "margin", 1, "hexpand", TRUE, NULL);
143 	gtk_grid_attach (top_grid, widget,  1, 2, 2, 1);
144 	g_signal_connect (GTK_EDITABLE (widget), "changed",
145 			G_CALLBACK (on_entry_changed), dform);
146 	dform->file_entry = widget;
147 	// File - label
148 	widget = gtk_label_new_with_mnemonic (_("File:"));
149 	gtk_label_set_mnemonic_widget (GTK_LABEL (widget), dform->file_entry);
150 	g_object_set (widget, "margin-left", 3, "margin-right", 3, NULL);
151 	g_object_set (widget, "margin-top", 1, "margin-bottom", 1, NULL);
152 	gtk_grid_attach (top_grid, widget,  0, 2, 1, 1);
153 	dform->file_label = widget;
154 
155 	// Folder - combo entry + icon
156 	dform->folder_combo = gtk_combo_box_text_new_with_entry ();
157 	dform->folder_entry = gtk_bin_get_child (GTK_BIN (dform->folder_combo));
158 	widget = dform->folder_entry;
159 	gtk_entry_set_activates_default (GTK_ENTRY (widget), TRUE);
160 #if GTK_MAJOR_VERSION >= 3 && GTK_MINOR_VERSION >= 10
161 	gtk_entry_set_icon_from_icon_name (GTK_ENTRY (widget),
162 			GTK_ENTRY_ICON_SECONDARY, "folder");
163 #else
164 	gtk_entry_set_icon_from_stock (GTK_ENTRY (widget),
165 			GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_DIRECTORY);
166 #endif
167 	gtk_entry_set_icon_tooltip_text (GTK_ENTRY (widget),
168 			GTK_ENTRY_ICON_SECONDARY, _("Select Folder"));
169 	g_object_set (dform->folder_combo, "margin", 1, "hexpand", TRUE, NULL);
170 	gtk_grid_attach (top_grid, dform->folder_combo,  1, 3, 1, 1);
171 	g_signal_connect (widget, "icon-release",
172 			G_CALLBACK (on_select_folder), dform);
173 	g_signal_connect (GTK_EDITABLE (widget), "changed",
174 			G_CALLBACK (on_entry_changed), dform);
175 	// Folder - label
176 	widget = gtk_label_new_with_mnemonic (_("_Folder:"));
177 	gtk_label_set_mnemonic_widget(GTK_LABEL (widget), dform->folder_combo);
178 	g_object_set (widget, "margin-left", 3, "margin-right", 3, NULL);
179 	g_object_set (widget, "margin-top", 1, "margin-bottom", 1, NULL);
180 	gtk_grid_attach (top_grid, widget,  0, 3, 1, 1);
181 
182 	// Referrer - entry
183 	widget = gtk_entry_new ();
184 	gtk_entry_set_activates_default (GTK_ENTRY (widget), TRUE);
185 	g_object_set (widget, "margin", 1, "hexpand", TRUE, NULL);
186 	gtk_grid_attach (top_grid, widget, 1, 4, 2, 1);
187 	g_signal_connect (GTK_EDITABLE (widget), "changed",
188 			G_CALLBACK (on_http_entry_changed), dform);
189 	dform->referrer_entry = widget;
190 	// Referrer - label
191 	widget = gtk_label_new_with_mnemonic (_("Referrer:"));
192 	gtk_label_set_mnemonic_widget (GTK_LABEL (widget), dform->referrer_entry);
193 	g_object_set (widget, "margin-left", 3, "margin-right", 3, NULL);
194 	g_object_set (widget, "margin-top", 1, "margin-bottom", 1, NULL);
195 	gtk_grid_attach (top_grid, widget, 0, 4, 1, 1);
196 //	dform->referrer_label = widget;
197 
198 	// ----------------------------------------------------
199 	// Connections
200 	// HBox for Connections
201 	hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
202 	gtk_box_pack_start (top_vbox, hbox, FALSE, FALSE, 2);
203 	// connections - label
204 //	widget = gtk_label_new (_("connections"));
205 //	gtk_box_pack_end (GTK_BOX (hbox), widget, FALSE, FALSE, 2);
206 //	dform->label_connections = widget;
207 	// connections - spin button
208 	widget = gtk_spin_button_new_with_range (1.0, 16.0, 1.0);
209 	gtk_entry_set_activates_default (GTK_ENTRY (widget), TRUE);
210 //	gtk_entry_set_width_chars (GTK_ENTRY (widget), 3); // remove for GTK+ 3.12
211 	gtk_box_pack_end (GTK_BOX (hbox), widget, FALSE, FALSE, 2);
212 	dform->spin_connections = widget;
213 	// "Max Connections:" - title label
214 	widget = gtk_label_new_with_mnemonic (_("_Max Connections:"));
215 	gtk_label_set_mnemonic_widget ((GtkLabel*)widget, dform->spin_connections);
216 	gtk_box_pack_end (GTK_BOX (hbox), widget, FALSE, FALSE, 2);
217 	dform->title_connections = widget;
218 
219 	// ----------------------------------------------------
220 	// HBox for "Status" and "Login"
221 	hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
222 	gtk_box_pack_start (top_vbox, hbox, FALSE, FALSE, 2);
223 
224 	// ----------------------------------------------------
225 	// frame for Status (start mode)
226 	frame = gtk_frame_new (_("Status"));
227 	vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
228 	gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
229 	gtk_container_add (GTK_CONTAINER (frame), vbox);
230 	gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, FALSE, 0);
231 	dform->radio_runnable = gtk_radio_button_new_with_mnemonic (NULL,
232 				_("_Runnable"));
233 	dform->radio_pause = gtk_radio_button_new_with_mnemonic_from_widget (
234 				(GtkRadioButton*)dform->radio_runnable, _("P_ause"));
235 	gtk_box_pack_start (GTK_BOX (vbox), dform->radio_runnable, FALSE, FALSE, 0);
236 	gtk_box_pack_start (GTK_BOX (vbox), dform->radio_pause, FALSE, FALSE, 0);
237 
238 	// ----------------------------------------------------
239 	// frame for login
240 	frame = gtk_frame_new (_("Login"));
241 	grid  = (GtkGrid*) gtk_grid_new ();
242 	gtk_container_set_border_width (GTK_CONTAINER (grid), 2);
243 	gtk_container_add (GTK_CONTAINER (frame), (GtkWidget*) grid);
244 	gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 2);
245 	// User - entry
246 	widget = gtk_entry_new ();
247 	gtk_entry_set_activates_default (GTK_ENTRY (widget), TRUE);
248 	g_object_set (widget, "margin", 1, "hexpand", TRUE, NULL);
249 	gtk_grid_attach (grid, widget, 1, 0, 1, 1);
250 	g_signal_connect (GTK_EDITABLE (widget), "changed",
251 			G_CALLBACK (on_entry_changed), dform);
252 	dform->username_entry = widget;
253 	// User - label
254 	widget = gtk_label_new (_("User:"));
255 	g_object_set (widget, "margin-left", 2, "margin-right", 2, NULL);
256 	g_object_set (widget, "margin-top", 1, "margin-bottom", 1, NULL);
257 	gtk_grid_attach (grid, widget, 0, 0, 1, 1);
258 //	dform->username_label = widget;
259 
260 	// Password - entry
261 	widget = gtk_entry_new ();
262 	gtk_entry_set_visibility (GTK_ENTRY (widget), FALSE);
263 	gtk_entry_set_activates_default (GTK_ENTRY (widget), TRUE);
264 	g_object_set (widget, "margin", 1, "hexpand", TRUE, NULL);
265 	gtk_grid_attach (grid, widget, 1, 1, 1, 1);
266 	g_signal_connect (GTK_EDITABLE (widget), "changed",
267 			G_CALLBACK (on_entry_changed), dform);
268 	dform->password_entry = widget;
269 	// Password - label
270 	widget = gtk_label_new (_("Password:"));
271 	g_object_set (widget, "margin-left", 2, "margin-right", 2, NULL);
272 	g_object_set (widget, "margin-top", 1, "margin-bottom", 1, NULL);
273 	gtk_grid_attach (grid, widget, 0, 1, 1, 1);
274 //	dform->password_label = widget;
275 
276 	// ----------------------------------------------------
277 	// proxy
278 //	ug_proxy_widget_init (&dform->proxy_dform);
279 	if (proxy) {
280 		widget = proxy->self;
281 		gtk_box_pack_start (top_vbox, widget, FALSE, FALSE, 2);
282 	}
283 }
284 
285 static void ugtk_download_form_init_page2 (UgtkDownloadForm* dform)
286 {
287 	GtkWidget*  widget;
288 	GtkGrid*    grid;
289 
290 	dform->page2 = gtk_grid_new ();
291 	grid = (GtkGrid*) dform->page2;
292 	gtk_container_set_border_width (GTK_CONTAINER (grid), 2);
293 
294 	// label - cookie file
295 	widget = gtk_label_new (_("Cookie file:"));
296 	gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);	// left, center
297 	g_object_set (widget, "margin-left", 2, "margin-right", 2, NULL);
298 	g_object_set (widget, "margin-top", 1, "margin-bottom", 1, NULL);
299 	gtk_grid_attach (grid, widget, 0, 0, 1, 1);
300 	dform->cookie_label = widget;
301 	// entry - cookie file
302 	widget = gtk_entry_new ();
303 	gtk_entry_set_activates_default (GTK_ENTRY (widget), TRUE);
304 #if GTK_MAJOR_VERSION >= 3 && GTK_MINOR_VERSION >= 10
305 	gtk_entry_set_icon_from_icon_name (GTK_ENTRY (widget),
306 			GTK_ENTRY_ICON_SECONDARY, "text-x-generic");
307 #else
308 	gtk_entry_set_icon_from_stock (GTK_ENTRY (widget),
309 			GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_FILE);
310 #endif
311 	gtk_entry_set_icon_tooltip_text (GTK_ENTRY (widget),
312 			GTK_ENTRY_ICON_SECONDARY, _("Select Cookie File"));
313 	g_object_set (widget, "margin", 1, "hexpand", TRUE, NULL);
314 	gtk_grid_attach (grid, widget, 1, 0, 3, 1);
315 	g_signal_connect (widget, "icon-release",
316 			G_CALLBACK (on_select_cookie), dform);
317 	g_signal_connect (GTK_EDITABLE (widget), "changed",
318 			G_CALLBACK (on_http_entry_changed), dform);
319 	dform->cookie_entry = widget;
320 	// label - post file
321 	widget = gtk_label_new (_("Post file:"));
322 	gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);	// left, center
323 	g_object_set (widget, "margin-left", 2, "margin-right", 2, NULL);
324 	g_object_set (widget, "margin-top", 1, "margin-bottom", 1, NULL);
325 	gtk_grid_attach (grid, widget, 0, 1, 1, 1);
326 	dform->post_label = widget;
327 	// entry - post file
328 	widget = gtk_entry_new ();
329 	gtk_entry_set_activates_default (GTK_ENTRY (widget), TRUE);
330 #if GTK_MAJOR_VERSION >= 3 && GTK_MINOR_VERSION >= 10
331 	gtk_entry_set_icon_from_icon_name (GTK_ENTRY (widget),
332 			GTK_ENTRY_ICON_SECONDARY, "text-x-generic");
333 #else
334 	gtk_entry_set_icon_from_stock (GTK_ENTRY (widget),
335 			GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_FILE);
336 #endif
337 	gtk_entry_set_icon_tooltip_text (GTK_ENTRY (widget),
338 			GTK_ENTRY_ICON_SECONDARY, _("Select Post File"));
339 	g_object_set (widget, "margin", 1, "hexpand", TRUE, NULL);
340 	gtk_grid_attach (grid, widget, 1, 1, 3, 1);
341 	g_signal_connect (widget, "icon-release",
342 			G_CALLBACK (on_select_post), dform);
343 	g_signal_connect (GTK_EDITABLE (widget), "changed",
344 			G_CALLBACK (on_http_entry_changed), dform);
345 	dform->post_entry = widget;
346 
347 	// label - user agent
348 	widget = gtk_label_new (_("User Agent:"));
349 	gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);	// left, center
350 	g_object_set (widget, "margin-left", 2, "margin-right", 2, NULL);
351 	g_object_set (widget, "margin-top", 1, "margin-bottom", 1, NULL);
352 	gtk_grid_attach (grid, widget, 0, 2, 1, 1);
353 	dform->agent_label = widget;
354 	// entry - user agent
355 	widget = gtk_entry_new ();
356 	gtk_entry_set_activates_default (GTK_ENTRY (widget), TRUE);
357 	g_object_set (widget, "margin", 1, "hexpand", TRUE, NULL);
358 	gtk_grid_attach (grid, widget, 1, 2, 3, 1);
359 	g_signal_connect (GTK_EDITABLE (widget), "changed",
360 			G_CALLBACK (on_http_entry_changed), dform);
361 	dform->agent_entry = widget;
362 
363 	// Retry limit - label
364 	widget = gtk_label_new_with_mnemonic (_("Retry _limit:"));
365 	gtk_label_set_mnemonic_widget (GTK_LABEL (widget), dform->spin_retry);
366 	g_object_set (widget, "margin-left", 2, "margin-right", 2, NULL);
367 	g_object_set (widget, "margin-top", 1, "margin-bottom", 1, NULL);
368 	gtk_grid_attach (grid, widget, 0, 3, 2, 1);
369 	// Retry limit - spin button
370 	widget = gtk_spin_button_new_with_range (0.0, 99.0, 1.0);
371 	gtk_entry_set_activates_default (GTK_ENTRY (widget), TRUE);
372 	g_object_set (widget, "margin-left", 2, "margin-right", 2, NULL);
373 	g_object_set (widget, "margin-top", 1, "margin-bottom", 1, NULL);
374 	gtk_grid_attach (grid, widget, 2, 3, 1, 1);
375 	g_signal_connect (GTK_EDITABLE (widget), "changed",
376 			G_CALLBACK (on_spin_changed), dform);
377 	dform->spin_retry = widget;
378 	// counts - label
379 	widget = gtk_label_new (_("counts"));
380 	gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
381 	g_object_set (widget, "margin-left", 2, "margin-right", 2, NULL);
382 	g_object_set (widget, "margin-top", 1, "margin-bottom", 1, NULL);
383 	gtk_grid_attach (grid, widget, 3, 3, 1, 1);
384 
385 	// Retry delay - label
386 	widget = gtk_label_new_with_mnemonic (_("Retry _delay:"));
387 	gtk_label_set_mnemonic_widget (GTK_LABEL (widget), dform->spin_delay);
388 	g_object_set (widget, "margin-left", 2, "margin-right", 2, NULL);
389 	g_object_set (widget, "margin-top", 1, "margin-bottom", 1, NULL);
390 	gtk_grid_attach (grid, widget, 0, 4, 2, 1);
391 	// Retry delay - spin button
392 	widget = gtk_spin_button_new_with_range (0.0, 600.0, 1.0);
393 	gtk_entry_set_activates_default (GTK_ENTRY (widget), TRUE);
394 	g_object_set (widget, "margin-left", 2, "margin-right", 2, NULL);
395 	g_object_set (widget, "margin-top", 1, "margin-bottom", 1, NULL);
396 	gtk_grid_attach (grid, widget, 2, 4, 1, 1);
397 	g_signal_connect (GTK_EDITABLE (widget), "changed",
398 			G_CALLBACK (on_spin_changed), dform);
399 	dform->spin_delay = widget;
400 	// seconds - label
401 	widget = gtk_label_new (_("seconds"));
402 	gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
403 	g_object_set (widget, "margin-left", 2, "margin-right", 2, NULL);
404 	g_object_set (widget, "margin-top", 1, "margin-bottom", 1, NULL);
405 	gtk_grid_attach (grid, widget, 3, 4, 1, 1);
406 
407 	// label - Max upload speed
408 	widget = gtk_label_new (_("Max upload speed:"));
409 	g_object_set (widget, "margin-left", 2, "margin-right", 2, NULL);
410 	g_object_set (widget, "margin-top", 1, "margin-bottom", 1, NULL);
411 	gtk_grid_attach (grid, widget, 0, 5, 2, 1);
412 	// spin - Max upload speed
413 	widget = gtk_spin_button_new_with_range (0, 99999999, 1);
414 	gtk_entry_set_activates_default (GTK_ENTRY (widget), TRUE);
415 //	gtk_entry_set_width_chars (GTK_ENTRY (widget), 8);
416 	g_object_set (widget, "margin", 1, NULL);
417 	gtk_grid_attach (grid, widget, 2, 5, 1, 1);
418 	dform->spin_upload_speed = (GtkSpinButton*) widget;
419 	// label - "KiB/s"
420 	widget = gtk_label_new (_("KiB/s"));
421 	gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);	// left, center
422 	g_object_set (widget, "margin", 2, "hexpand", TRUE, NULL);
423 	gtk_grid_attach (grid, widget, 3, 5, 1, 1);
424 
425 	// label - Max download speed
426 	widget = gtk_label_new (_("Max download speed:"));
427 	g_object_set (widget, "margin-left", 2, "margin-right", 2, NULL);
428 	g_object_set (widget, "margin-top", 1, "margin-bottom", 1, NULL);
429 	gtk_grid_attach (grid, widget, 0, 6, 2, 1);
430 	// spin - Max download speed
431 	widget = gtk_spin_button_new_with_range (0, 99999999, 1);
432 	gtk_entry_set_activates_default (GTK_ENTRY (widget), TRUE);
433 //	gtk_entry_set_width_chars (GTK_ENTRY (widget), 8);
434 	g_object_set (widget, "margin", 1, NULL);
435 	gtk_grid_attach (grid, widget, 2, 6, 1, 1);
436 	dform->spin_download_speed = (GtkSpinButton*) widget;
437 	// label - "KiB/s"
438 	widget = gtk_label_new (_("KiB/s"));
439 	gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);	// left, center
440 	g_object_set (widget, "margin", 2, "hexpand", TRUE, NULL);
441 	gtk_grid_attach (grid, widget, 3, 6, 1, 1);
442 
443 	// Retrieve timestamp
444 	widget = gtk_check_button_new_with_label (_("Retrieve timestamp"));
445 	g_object_set (widget, "margin-top", 3, "margin-bottom", 1, NULL);
446 	gtk_grid_attach (grid, widget, 0, 7, 3, 1);
447 	dform->timestamp = (GtkToggleButton*) widget;
448 }
449 
450 void  ugtk_download_form_get (UgtkDownloadForm* dform, UgData* node_data)
451 {
452 	UgUri         uuri;
453 	const gchar*  text;
454 	gint          number;
455 	union {
456 		UgetRelation* relation;
457 		UgetCommon*   common;
458 		UgetHttp*     http;
459 	} temp;
460 
461 	// ------------------------------------------
462 	// UgetCommon
463 	temp.common = ug_data_realloc(node_data, UgetCommonInfo);
464 	// folder
465 	text = gtk_entry_get_text ((GtkEntry*)dform->folder_entry);
466 	ug_free (temp.common->folder);
467 	temp.common->folder = (*text) ? ug_strdup (text) : NULL;
468 	ug_str_remove_crlf (temp.common->folder, temp.common->folder);
469 	// user
470 	text = gtk_entry_get_text ((GtkEntry*)dform->username_entry);
471 	ug_free (temp.common->user);
472 	temp.common->user = (*text) ? ug_strdup (text) : NULL;
473 	ug_str_remove_crlf (temp.common->user, temp.common->user);
474 	// password
475 	text = gtk_entry_get_text ((GtkEntry*)dform->password_entry);
476 	ug_free (temp.common->password);
477 	temp.common->password = (*text) ? ug_strdup (text) : NULL;
478 	ug_str_remove_crlf (temp.common->password, temp.common->password);
479 	// retry_limit
480 	number = gtk_spin_button_get_value_as_int ((GtkSpinButton*) dform->spin_retry);
481 	temp.common->retry_limit = number;
482 	// retry_delay
483 	number = gtk_spin_button_get_value_as_int ((GtkSpinButton*) dform->spin_delay);
484 	temp.common->retry_delay = number;
485 
486 	// max_upload_speed
487 	number = gtk_spin_button_get_value_as_int ((GtkSpinButton*) dform->spin_upload_speed) * 1024;
488 	temp.common->max_upload_speed = number;
489 	// max_download_speed
490 	number = gtk_spin_button_get_value_as_int ((GtkSpinButton*) dform->spin_download_speed) * 1024;
491 	temp.common->max_download_speed = number;
492 
493 	// max_connections
494 	number = gtk_spin_button_get_value_as_int ((GtkSpinButton*) dform->spin_connections);
495 	temp.common->max_connections = number;
496 	// timestamp
497 	temp.common->timestamp = gtk_toggle_button_get_active (dform->timestamp);
498 
499 	// URI
500 	if (gtk_widget_is_sensitive (dform->uri_entry) == TRUE) {
501 		text = gtk_entry_get_text ((GtkEntry*)dform->uri_entry);
502 		ug_free (temp.common->uri);
503 		temp.common->uri = (*text) ? ug_strdup (text) : NULL;
504 		ug_str_remove_crlf (temp.common->uri, temp.common->uri);
505 		if (temp.common->uri) {
506 			ug_uri_init (&uuri, temp.common->uri);
507 			// set user
508 			number = ug_uri_user (&uuri, &text);
509 			if (number > 0) {
510 				ug_free (temp.common->user);
511 				temp.common->user = ug_strndup (text, number);
512 			}
513 			// set password
514 			number = ug_uri_password (&uuri, &text);
515 			if (number > 0) {
516 				ug_free (temp.common->password);
517 				temp.common->password = ug_strndup (text, number);
518 			}
519 			// Remove user & password from URL
520 			if (uuri.authority != uuri.host) {
521 				memmove ((char*)uuri.uri + uuri.authority, (char*)uuri.uri + uuri.host,
522 						strlen (uuri.uri + uuri.host) + 1);
523 			}
524 		}
525 	}
526 	// mirrors
527 	if (gtk_widget_is_sensitive (dform->mirrors_entry) == TRUE) {
528 		text = gtk_entry_get_text ((GtkEntry*)dform->mirrors_entry);
529 		ug_free (temp.common->mirrors);
530 		temp.common->mirrors = (*text) ? ug_strdup (text) : NULL;
531 		ug_str_remove_crlf (temp.common->mirrors, temp.common->mirrors);
532 	}
533 	// file
534 	if (gtk_widget_is_sensitive (dform->file_entry) == TRUE) {
535 		text = gtk_entry_get_text ((GtkEntry*)dform->file_entry);
536 		ug_free (temp.common->file);
537 		temp.common->file = (*text) ? ug_strdup (text) : NULL;
538 		ug_str_remove_crlf (temp.common->file, temp.common->file);
539 	}
540 
541 	// ------------------------------------------
542 	// UgetHttp
543 	temp.http = ug_data_realloc(node_data, UgetHttpInfo);
544 	// referrer
545 	text = gtk_entry_get_text ((GtkEntry*) dform->referrer_entry);
546 	ug_free (temp.http->referrer);
547 	temp.http->referrer = (*text) ? ug_strdup (text) : NULL;
548 	ug_str_remove_crlf (temp.http->referrer, temp.http->referrer);
549 	// cookie_file
550 	text = gtk_entry_get_text ((GtkEntry*) dform->cookie_entry);
551 	ug_free (temp.http->cookie_file);
552 	temp.http->cookie_file = (*text) ? ug_strdup (text) : NULL;
553 	ug_str_remove_crlf (temp.http->cookie_file, temp.http->cookie_file);
554 	// post_file
555 	text = gtk_entry_get_text ((GtkEntry*) dform->post_entry);
556 	ug_free (temp.http->post_file);
557 	temp.http->post_file = (*text) ? ug_strdup (text) : NULL;
558 	ug_str_remove_crlf (temp.http->post_file, temp.http->post_file);
559 	// user_agent
560 	text = gtk_entry_get_text ((GtkEntry*) dform->agent_entry);
561 	ug_free (temp.http->user_agent);
562 	temp.http->user_agent = (*text) ? ug_strdup (text) : NULL;
563 	ug_str_remove_crlf (temp.http->user_agent, temp.http->user_agent);
564 
565 	// ------------------------------------------
566 	// UgetRelation
567 	if (gtk_widget_get_sensitive (dform->radio_pause)) {
568 		temp.relation = ug_data_realloc(node_data, UgetRelationInfo);
569 		if (gtk_toggle_button_get_active ((GtkToggleButton*) dform->radio_pause))
570 			temp.relation->group |= UGET_GROUP_PAUSED;
571 		else
572 			temp.relation->group &= ~UGET_GROUP_PAUSED;
573 	}
574 }
575 
576 void  ugtk_download_form_set (UgtkDownloadForm* dform, UgData* node_data, gboolean keep_changed)
577 {
578 	UgetRelation* relation;
579 	UgetCommon*   common;
580 	UgetHttp*     http;
581 
582 	common = ug_data_realloc(node_data, UgetCommonInfo);
583 	http   = ug_data_get(node_data, UgetHttpInfo);
584 
585 	// disable changed flags
586 	dform->changed.enable = FALSE;
587 	// ------------------------------------------
588 	// UgetCommon
589 	// set changed flags
590 	if (keep_changed == FALSE && common) {
591 		dform->changed.uri      = common->keeping.uri;
592 		dform->changed.mirrors  = common->keeping.mirrors;
593 		dform->changed.file     = common->keeping.file;
594 		dform->changed.folder   = common->keeping.folder;
595 		dform->changed.user     = common->keeping.user;
596 		dform->changed.password = common->keeping.password;
597 		dform->changed.retry    = common->keeping.retry_limit;
598 		dform->changed.delay    = common->keeping.retry_delay;
599 		dform->changed.max_upload_speed   = common->keeping.max_upload_speed;
600 		dform->changed.max_download_speed = common->keeping.max_download_speed;
601 		dform->changed.timestamp = common->keeping.timestamp;
602 	}
603 	// set data
604 	if (keep_changed==FALSE || dform->changed.uri==FALSE) {
605 		if (gtk_widget_is_sensitive (dform->uri_entry)) {
606 			gtk_entry_set_text ((GtkEntry*) dform->uri_entry,
607 					(common && common->uri)  ? common->uri : "");
608 		}
609 	}
610 	if (keep_changed==FALSE || dform->changed.mirrors==FALSE) {
611 		if (gtk_widget_is_sensitive (dform->mirrors_entry)) {
612 			gtk_entry_set_text ((GtkEntry*) dform->mirrors_entry,
613 					(common && common->mirrors)  ? common->mirrors : "");
614 		}
615 	}
616 	if (keep_changed==FALSE || dform->changed.file==FALSE) {
617 		if (gtk_widget_is_sensitive (dform->file_entry)) {
618 			gtk_entry_set_text ((GtkEntry*) dform->file_entry,
619 					(common && common->file) ? common->file : "");
620 			// set changed flags
621 			if (common && common->file)
622 				dform->changed.file = TRUE;
623 		}
624 	}
625 	if (keep_changed==FALSE || dform->changed.folder==FALSE) {
626 		g_signal_handlers_block_by_func (GTK_EDITABLE (dform->folder_entry),
627 				on_entry_changed, dform);
628 		gtk_entry_set_text ((GtkEntry*) dform->folder_entry,
629 				(common && common->folder) ? common->folder : "");
630 		g_signal_handlers_unblock_by_func (GTK_EDITABLE (dform->folder_entry),
631 				on_entry_changed, dform);
632 	}
633 	if (keep_changed==FALSE || dform->changed.user==FALSE) {
634 		gtk_entry_set_text ((GtkEntry*) dform->username_entry,
635 				(common && common->user) ? common->user : "");
636 	}
637 	if (keep_changed==FALSE || dform->changed.password==FALSE) {
638 		gtk_entry_set_text ((GtkEntry*) dform->password_entry,
639 				(common && common->password) ? common->password : "");
640 	}
641 	if (keep_changed==FALSE || dform->changed.retry==FALSE) {
642 		gtk_spin_button_set_value ((GtkSpinButton*) dform->spin_retry,
643 				(common) ? common->retry_limit : 99);
644 	}
645 	if (keep_changed==FALSE || dform->changed.delay==FALSE) {
646 		gtk_spin_button_set_value ((GtkSpinButton*) dform->spin_delay,
647 				(common) ? common->retry_delay : 6);
648 	}
649 
650 	if (keep_changed==FALSE || dform->changed.max_upload_speed==FALSE) {
651 		gtk_spin_button_set_value ((GtkSpinButton*) dform->spin_upload_speed,
652 				(gdouble) (common->max_upload_speed / 1024));
653 	}
654 	if (keep_changed==FALSE || dform->changed.max_download_speed==FALSE) {
655 		gtk_spin_button_set_value ((GtkSpinButton*) dform->spin_download_speed,
656 				(gdouble) (common->max_download_speed / 1024));
657 	}
658 
659 	if (keep_changed==FALSE || dform->changed.connections==FALSE) {
660 		gtk_spin_button_set_value ((GtkSpinButton*) dform->spin_connections,
661 			common->max_connections);
662 	}
663 	if (keep_changed==FALSE || dform->changed.timestamp==FALSE)
664 		gtk_toggle_button_set_active (dform->timestamp, common->timestamp);
665 
666 	// ------------------------------------------
667 	// UgetHttp
668 	// set data
669 	if (keep_changed==FALSE || dform->changed.referrer==FALSE) {
670 		gtk_entry_set_text ((GtkEntry*) dform->referrer_entry,
671 				(http && http->referrer) ? http->referrer : "");
672 	}
673 	if (keep_changed==FALSE || dform->changed.cookie==FALSE) {
674 		gtk_entry_set_text ((GtkEntry*) dform->cookie_entry,
675 				(http && http->cookie_file) ? http->cookie_file : "");
676 	}
677 	if (keep_changed==FALSE || dform->changed.post==FALSE) {
678 		gtk_entry_set_text ((GtkEntry*) dform->post_entry,
679 				(http && http->post_file) ? http->post_file : "");
680 	}
681 	if (keep_changed==FALSE || dform->changed.agent==FALSE) {
682 		gtk_entry_set_text ((GtkEntry*) dform->agent_entry,
683 				(http && http->user_agent) ? http->user_agent : "");
684 	}
685 	// set changed flags
686 	if (keep_changed==FALSE && http) {
687 		dform->changed.referrer = http->keeping.referrer;
688 		dform->changed.cookie   = http->keeping.cookie_file;
689 		dform->changed.post     = http->keeping.post_file;
690 		dform->changed.agent    = http->keeping.user_agent;
691 	}
692 
693 	// ------------------------------------------
694 	// UgetRelation
695 	if (gtk_widget_get_sensitive (dform->radio_pause)) {
696 		relation = ug_data_realloc(node_data, UgetRelationInfo);
697 		if (relation->group & UGET_GROUP_PAUSED)
698 			gtk_toggle_button_set_active ((GtkToggleButton*) dform->radio_pause, TRUE);
699 		else
700 			gtk_toggle_button_set_active ((GtkToggleButton*) dform->radio_runnable, TRUE);
701 	}
702 
703 	// enable changed flags
704 	dform->changed.enable = TRUE;
705 	// complete entry
706 	ugtk_download_form_complete_entry (dform);
707 }
708 
709 void  ugtk_download_form_set_multiple (UgtkDownloadForm* dform, gboolean multiple_mode)
710 {
711 //	dform->multiple = multiple_mode;
712 
713 	if (multiple_mode) {
714 		gtk_widget_hide (dform->uri_label);
715 		gtk_widget_hide (dform->uri_entry);
716 		gtk_widget_hide (dform->mirrors_label);
717 		gtk_widget_hide (dform->mirrors_entry);
718 		gtk_widget_hide (dform->file_label);
719 		gtk_widget_hide (dform->file_entry);
720 	}
721 	else {
722 		gtk_widget_show (dform->uri_label);
723 		gtk_widget_show (dform->uri_entry);
724 		gtk_widget_show (dform->mirrors_label);
725 		gtk_widget_show (dform->mirrors_entry);
726 		gtk_widget_show (dform->file_label);
727 		gtk_widget_show (dform->file_entry);
728 	}
729 
730 	multiple_mode = !multiple_mode;
731 	gtk_widget_set_sensitive (dform->uri_label,  multiple_mode);
732 	gtk_widget_set_sensitive (dform->uri_entry,  multiple_mode);
733 	gtk_widget_set_sensitive (dform->mirrors_label, multiple_mode);
734 	gtk_widget_set_sensitive (dform->mirrors_entry, multiple_mode);
735 	gtk_widget_set_sensitive (dform->file_label, multiple_mode);
736 	gtk_widget_set_sensitive (dform->file_entry, multiple_mode);
737 }
738 
739 void  ugtk_download_form_set_folders (UgtkDownloadForm* dform, UgtkSetting* setting)
740 {
741 	GtkComboBoxText* combo;
742 	UgLink*  link;
743 
744 	dform->changed.enable = FALSE;
745 	g_signal_handlers_block_by_func (GTK_EDITABLE (dform->folder_entry),
746 			on_entry_changed, dform);
747 	combo = GTK_COMBO_BOX_TEXT (dform->folder_combo);
748 	for (link = setting->folder_history.head;  link;  link = link->next)
749 		gtk_combo_box_text_append_text (combo, link->data);
750 	// set default folder
751 	gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
752 	g_signal_handlers_unblock_by_func (GTK_EDITABLE (dform->folder_entry),
753 			on_entry_changed, dform);
754 	dform->changed.enable = TRUE;
755 }
756 
757 void  ugtk_download_form_get_folders (UgtkDownloadForm* dform, UgtkSetting* setting)
758 {
759 	const gchar* current;
760 
761 	current = gtk_entry_get_text ((GtkEntry*) dform->folder_entry);
762 	ugtk_setting_add_folder (setting, current);
763 }
764 
765 void  ugtk_download_form_complete_entry (UgtkDownloadForm* dform)
766 {
767 	const gchar*  text;
768 //	gchar*    temp;
769 	UgUri     upart;
770 	gboolean  completed = FALSE;
771 
772 	// URL
773 	text = gtk_entry_get_text ((GtkEntry*) dform->uri_entry);
774 	ug_uri_init (&upart, text);
775 	if (upart.host != -1) {
776 		// disable changed flags
777 		dform->changed.enable = FALSE;
778 #if 0
779 		// complete file entry
780 		text = gtk_entry_get_text ((GtkEntry*) dform->file_entry);
781 		if (text[0] == 0 || dform->changed.file == FALSE) {
782 			temp = ug_uri_get_file (&upart);
783 			gtk_entry_set_text ((GtkEntry*) dform->file_entry,
784 					(temp) ? temp : "index.htm");
785 			g_free (temp);
786 		}
787 		// complete user entry
788 		text = gtk_entry_get_text ((GtkEntry*) dform->username_entry);
789 		if (text[0] == 0 || dform->changed.user == FALSE) {
790 			temp = ug_uri_get_user (&upart);
791 			gtk_entry_set_text ((GtkEntry*) dform->username_entry,
792 					(temp) ? temp : "");
793 			g_free (temp);
794 		}
795 		// complete password entry
796 		text = gtk_entry_get_text ((GtkEntry*) dform->password_entry);
797 		if (text[0] == 0 || dform->changed.password == FALSE) {
798 			temp = ug_uri_get_password (&upart);
799 			gtk_entry_set_text ((GtkEntry*) dform->password_entry,
800 					(temp) ? temp : "");
801 			g_free (temp);
802 		}
803 #endif
804 		// enable changed flags
805 		dform->changed.enable = TRUE;
806 		// status
807 		completed = TRUE;
808 	}
809 #if 1    // check existing for file name
810 	else if (ug_uri_part_file (&upart, &text) > 0) {
811 		completed = TRUE;
812 	}
813 #else    // file extension
814 	else if (ug_uri_part_file_ext (&upart, &text) > 0) {
815 		// torrent or metalink file path
816 		if (*text == 'm' || *text == 'M' || *text == 't' || *text == 'T')
817 			completed = TRUE;
818 	}
819 #endif
820 	else if (upart.path > 0 && upart.uri[upart.path] != 0)
821 		completed = TRUE;
822 	else if (gtk_widget_is_sensitive (dform->uri_entry) == FALSE)
823 		completed = TRUE;
824 
825 	dform->completed = completed;
826 }
827 
828 // ----------------------------------------------------------------------------
829 // signal handler
830 static void on_spin_changed (GtkEditable* editable, UgtkDownloadForm* dform)
831 {
832 	if (dform->changed.enable) {
833 		if (editable == GTK_EDITABLE (dform->spin_retry))
834 			dform->changed.retry = TRUE;
835 		else if (editable == GTK_EDITABLE (dform->spin_delay))
836 			dform->changed.delay = TRUE;
837 	}
838 }
839 
840 static void on_entry_changed (GtkEditable* editable, UgtkDownloadForm* dform)
841 {
842 	if (dform->changed.enable) {
843 		if (editable == GTK_EDITABLE (dform->file_entry))
844 			dform->changed.file = TRUE;
845 		else if (editable == GTK_EDITABLE (dform->folder_entry))
846 			dform->changed.folder = TRUE;
847 		else if (editable == GTK_EDITABLE (dform->username_entry))
848 			dform->changed.user = TRUE;
849 		else if (editable == GTK_EDITABLE (dform->password_entry))
850 			dform->changed.password = TRUE;
851 	}
852 }
853 
854 static void on_uri_entry_changed (GtkEditable* editable, UgtkDownloadForm* dform)
855 {
856 	if (dform->changed.enable) {
857 		dform->changed.uri = TRUE;
858 		ugtk_download_form_complete_entry (dform);
859 	}
860 }
861 
862 static void on_http_entry_changed (GtkEditable* editable, UgtkDownloadForm* dform)
863 {
864 	if (dform->changed.enable) {
865 		if (editable == GTK_EDITABLE (dform->referrer_entry))
866 			dform->changed.referrer = TRUE;
867 		else if (editable == GTK_EDITABLE (dform->cookie_entry))
868 			dform->changed.cookie = TRUE;
869 		else if (editable == GTK_EDITABLE (dform->post_entry))
870 			dform->changed.post = TRUE;
871 		else if (editable == GTK_EDITABLE (dform->agent_entry))
872 			dform->changed.agent = TRUE;
873 	}
874 }
875 
876 static void on_select_folder_response (GtkDialog* chooser, gint response, UgtkDownloadForm* dform)
877 {
878 	gchar*	file;
879 	gchar*	path;
880 
881 	if (response == GTK_RESPONSE_OK ) {
882 		file = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser));
883 		path = g_filename_to_utf8 (file, -1, NULL, NULL, NULL);
884 		gtk_entry_set_text (GTK_ENTRY (dform->folder_entry), path);
885 		g_free (path);
886 		g_free (file);
887 	}
888 	gtk_widget_destroy (GTK_WIDGET (chooser));
889 
890 	if (dform->parent)
891 		gtk_widget_set_sensitive ((GtkWidget*) dform->parent, TRUE);
892 }
893 
894 static void on_select_folder (GtkEntry* entry, GtkEntryIconPosition icon_pos, GdkEvent* event, UgtkDownloadForm* dform)
895 {
896 	GtkWidget*	chooser;
897 	gchar*		path;
898 	gchar*		title;
899 
900 	// disable sensitive of parent window
901 	// enable sensitive in function on_file_chooser_response()
902 	if (dform->parent)
903 		gtk_widget_set_sensitive ((GtkWidget*) dform->parent, FALSE);
904 
905 	title = g_strconcat (UGTK_APP_NAME " - ", _("Select Folder"), NULL);
906 	chooser = gtk_file_chooser_dialog_new (title, dform->parent,
907 			GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
908 			GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
909 			GTK_STOCK_OK,     GTK_RESPONSE_OK,
910 			NULL);
911 	g_free (title);
912 	gtk_window_set_transient_for ((GtkWindow*) chooser, dform->parent);
913 	gtk_window_set_destroy_with_parent ((GtkWindow*) chooser, TRUE);
914 
915 	path = (gchar*) gtk_entry_get_text ((GtkEntry*) dform->folder_entry);
916 	if (*path) {
917 		path = g_filename_from_utf8 (path, -1, NULL, NULL, NULL);
918 		gtk_file_chooser_select_filename (GTK_FILE_CHOOSER (chooser), path);
919 		g_free (path);
920 	}
921 	g_signal_connect (chooser, "response",
922 			G_CALLBACK (on_select_folder_response), dform);
923 
924 	if (gtk_window_get_modal (dform->parent))
925 		gtk_dialog_run ((GtkDialog*) chooser);
926 	else {
927 		gtk_window_set_modal ((GtkWindow*) chooser, FALSE);
928 		gtk_widget_show (chooser);
929 	}
930 }
931 
932 static void on_select_cookie_response (GtkDialog* chooser, gint response, UgtkDownloadForm* dform)
933 {
934 	gchar*	file;
935 	gchar*	path;
936 
937 	if (response == GTK_RESPONSE_OK ) {
938 		file = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser));
939 		path = g_filename_to_utf8 (file, -1, NULL, NULL, NULL);
940 		gtk_entry_set_text (GTK_ENTRY (dform->cookie_entry), path);
941 		g_free (path);
942 		g_free (file);
943 	}
944 	gtk_widget_destroy (GTK_WIDGET (chooser));
945 
946 	if (dform->parent)
947 		gtk_widget_set_sensitive ((GtkWidget*) dform->parent, TRUE);
948 }
949 
950 static void on_select_cookie (GtkEntry* entry, GtkEntryIconPosition icon_pos, GdkEvent* event, UgtkDownloadForm* dform)
951 {
952 	GtkWidget*	chooser;
953 	gchar*		path;
954 	gchar*		title;
955 
956 	// disable sensitive of parent window
957 	// enable sensitive in function on_file_chooser_response()
958 	if (dform->parent)
959 		gtk_widget_set_sensitive ((GtkWidget*) dform->parent, FALSE);
960 
961 	title = g_strconcat (UGTK_APP_NAME " - ", _("Select Cookie File"), NULL);
962 	chooser = gtk_file_chooser_dialog_new (title, dform->parent,
963 			GTK_FILE_CHOOSER_ACTION_OPEN,
964 			GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
965 			GTK_STOCK_OK,     GTK_RESPONSE_OK,
966 			NULL);
967 	g_free (title);
968 	gtk_window_set_transient_for ((GtkWindow*) chooser, dform->parent);
969 	gtk_window_set_destroy_with_parent ((GtkWindow*) chooser, TRUE);
970 
971 	path = (gchar*) gtk_entry_get_text ((GtkEntry*) dform->cookie_entry);
972 	if (*path) {
973 		path = g_filename_from_utf8 (path, -1, NULL, NULL, NULL);
974 		gtk_file_chooser_select_filename (GTK_FILE_CHOOSER (chooser), path);
975 		g_free (path);
976 	}
977 	g_signal_connect (chooser, "response",
978 			G_CALLBACK (on_select_cookie_response), dform);
979 
980 	if (gtk_window_get_modal (dform->parent))
981 		gtk_dialog_run ((GtkDialog*) chooser);
982 	else {
983 		gtk_window_set_modal ((GtkWindow*) chooser, FALSE);
984 		gtk_widget_show (chooser);
985 	}
986 }
987 
988 static void on_select_post_response (GtkDialog* chooser, gint response, UgtkDownloadForm* dform)
989 {
990 	gchar*	file;
991 	gchar*	path;
992 
993 	if (response == GTK_RESPONSE_OK ) {
994 		file = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser));
995 		path = g_filename_to_utf8 (file, -1, NULL, NULL, NULL);
996 		gtk_entry_set_text (GTK_ENTRY (dform->post_entry), path);
997 		g_free (path);
998 		g_free (file);
999 	}
1000 	gtk_widget_destroy (GTK_WIDGET (chooser));
1001 
1002 	if (dform->parent)
1003 		gtk_widget_set_sensitive ((GtkWidget*) dform->parent, TRUE);
1004 }
1005 
1006 static void on_select_post (GtkEntry* entry, GtkEntryIconPosition icon_pos, GdkEvent* event, UgtkDownloadForm* dform)
1007 {
1008 	GtkWidget*	chooser;
1009 	gchar*		path;
1010 	gchar*		title;
1011 
1012 	// disable sensitive of parent window
1013 	// enable sensitive in function on_file_chooser_response()
1014 	if (dform->parent)
1015 		gtk_widget_set_sensitive ((GtkWidget*) dform->parent, FALSE);
1016 
1017 	title = g_strconcat (UGTK_APP_NAME " - ", _("Select Post File"), NULL);
1018 	chooser = gtk_file_chooser_dialog_new (title, dform->parent,
1019 			GTK_FILE_CHOOSER_ACTION_OPEN,
1020 			GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1021 			GTK_STOCK_OK,     GTK_RESPONSE_OK,
1022 			NULL);
1023 	g_free (title);
1024 	gtk_window_set_transient_for ((GtkWindow*) chooser, dform->parent);
1025 	gtk_window_set_destroy_with_parent ((GtkWindow*) chooser, TRUE);
1026 
1027 	path = (gchar*) gtk_entry_get_text ((GtkEntry*) dform->post_entry);
1028 	if (*path) {
1029 		path = g_filename_from_utf8 (path, -1, NULL, NULL, NULL);
1030 		gtk_file_chooser_select_filename (GTK_FILE_CHOOSER (chooser), path);
1031 		g_free (path);
1032 	}
1033 	g_signal_connect (chooser, "response",
1034 			G_CALLBACK (on_select_post_response), dform);
1035 
1036 	if (gtk_window_get_modal (dform->parent))
1037 		gtk_dialog_run ((GtkDialog*) chooser);
1038 	else {
1039 		gtk_window_set_modal ((GtkWindow*) chooser, FALSE);
1040 		gtk_widget_show (chooser);
1041 	}
1042 }
1043 
1044