37 #define _FILE_OFFSET_BITS 64 41 #include <glib/gi18n.h> 42 #include <glib/gstdio.h> 55 #define REMMINA_TYPE_CELL_RENDERER_PIXBUF \ 56 (remmina_cell_renderer_pixbuf_get_type()) 57 #define REMMINA_CELL_RENDERER_PIXBUF(obj) \ 58 (G_TYPE_CHECK_INSTANCE_CAST((obj), REMMINA_TYPE_CELL_RENDERER_PIXBUF, RemminaCellRendererPixbuf)) 59 #define REMMINA_CELL_RENDERER_PIXBUF_CLASS(klass) \ 60 (G_TYPE_CHECK_CLASS_CAST((klass), REMMINA_TYPE_CELL_RENDERER_PIXBUF, RemminaCellRendererPixbufClass)) 61 #define REMMINA_IS_CELL_RENDERER_PIXBUF(obj) \ 62 (G_TYPE_CHECK_INSTANCE_TYPE((obj), REMMINA_TYPE_CELL_RENDERER_PIXBUF)) 79 static guint remmina_cell_renderer_pixbuf_signals[1] =
83 const gchar *path,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
84 GtkCellRendererState flags)
87 g_signal_emit(G_OBJECT(renderer), remmina_cell_renderer_pixbuf_signals[0], 0, path);
94 GtkCellRendererClass *renderer_class = GTK_CELL_RENDERER_CLASS(klass);
98 remmina_cell_renderer_pixbuf_signals[0] = g_signal_new(
"activate", G_TYPE_FROM_CLASS(klass),
100 NULL, g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING);
105 TRACE_CALL(__func__);
106 g_object_set(G_OBJECT(renderer),
"mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE, NULL);
109 static GtkCellRenderer*
112 TRACE_CALL(__func__);
115 renderer = GTK_CELL_RENDERER(g_object_new(REMMINA_TYPE_CELL_RENDERER_PIXBUF, NULL));
122 #define BUSY_CURSOR \ 123 if (GDK_IS_WINDOW(gtk_widget_get_window(GTK_WIDGET(client)))) \ 125 gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(client)), gdk_cursor_new_for_display(gdk_display_get_default(), GDK_WATCH)); \ 126 gdk_display_flush(gdk_display_get_default()); \ 129 #define NORMAL_CURSOR \ 130 if (GDK_IS_WINDOW(gtk_widget_get_window(GTK_WIDGET(client)))) \ 132 gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(client)), NULL); \ 135 struct _RemminaFTPClientPriv {
136 GtkWidget *directory_combo;
139 GtkTreeModel *file_list_model;
140 GtkTreeModel *file_list_filter;
141 GtkTreeModel *file_list_sort;
142 GtkWidget *file_list_view;
143 gboolean file_list_show_hidden;
145 GtkTreeModel *task_list_model;
146 GtkWidget *task_list_view;
148 gchar *current_directory;
149 gchar *working_directory;
151 GtkWidget *file_action_widgets[10];
153 gboolean overwrite_all;
167 TRACE_CALL(__func__);
168 remmina_ftp_client_signals[
OPEN_DIR_SIGNAL] = g_signal_new(
"open-dir", G_TYPE_FROM_CLASS(klass),
170 g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING);
171 remmina_ftp_client_signals[
NEW_TASK_SIGNAL] = g_signal_new(
"new-task", G_TYPE_FROM_CLASS(klass),
173 g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
174 remmina_ftp_client_signals[
CANCEL_TASK_SIGNAL] = g_signal_new(
"cancel-task", G_TYPE_FROM_CLASS(klass),
175 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET(
RemminaFTPClientClass, cancel_task), NULL, NULL,
177 remmina_ftp_client_signals[
DELETE_FILE_SIGNAL] = g_signal_new(
"delete-file", G_TYPE_FROM_CLASS(klass),
178 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET(
RemminaFTPClientClass, delete_file), NULL, NULL,
184 TRACE_CALL(__func__);
186 g_free(priv->current_directory);
187 g_free(priv->working_directory);
192 GtkTreeIter *iter, gpointer user_data)
194 TRACE_CALL(__func__);
202 g_object_set(renderer,
"stock-id",
"folder", NULL);
205 g_object_set(renderer,
"stock-id",
"text-x-generic", NULL);
211 GtkTreeIter *iter, gpointer user_data)
213 TRACE_CALL(__func__);
214 gint tasktype, status;
221 g_object_set(renderer,
"stock-id",
"P_ause", NULL);
224 g_object_set(renderer,
"stock-id",
228 g_object_set(renderer,
"stock-id",
"_Yes", NULL);
231 g_object_set(renderer,
"stock-id",
"_No", NULL);
239 TRACE_CALL(__func__);
241 return g_format_size_full((guint64)size, G_FORMAT_SIZE_IEC_UNITS);
245 GtkTreeIter *iter, gpointer user_data)
247 TRACE_CALL(__func__);
254 g_object_set(renderer,
"text", str, NULL);
255 g_object_set(renderer,
"xalign", 1.0, NULL);
260 GtkTreeIter *iter, gpointer user_data)
262 TRACE_CALL(__func__);
268 buf[0] = ((permission & 040000) ?
'd' :
'-');
269 buf[1] = ((permission & 0400) ?
'r' :
'-');
270 buf[2] = ((permission & 0200) ?
'w' :
'-');
271 buf[3] = ((permission & 0100) ?
'x' :
'-');
272 buf[4] = ((permission & 040) ?
'r' :
'-');
273 buf[5] = ((permission & 020) ?
'w' :
'-');
274 buf[6] = ((permission & 010) ?
'x' :
'-');
275 buf[7] = ((permission & 04) ?
'r' :
'-');
276 buf[8] = ((permission & 02) ?
'w' :
'-');
277 buf[9] = ((permission & 01) ?
'x' :
'-');
280 g_object_set(renderer,
"text", buf, NULL);
284 GtkTreeIter *iter, gpointer user_data)
286 TRACE_CALL(__func__);
288 gfloat size, donesize;
289 gchar *strsize, *strdonesize, *str;
299 str = g_strdup_printf(
"%s / %s", strdonesize, strsize);
304 g_object_set(renderer,
"text", str, NULL);
305 g_object_set(renderer,
"xalign", 1.0, NULL);
310 GtkTreeIter *iter, gpointer user_data)
312 TRACE_CALL(__func__);
314 gfloat size, donesize;
325 progress = (gint)(donesize / size * 100);
330 g_object_set(renderer,
"value", progress, NULL);
335 TRACE_CALL(__func__);
337 g_signal_emit(G_OBJECT(client), remmina_ftp_client_signals[
OPEN_DIR_SIGNAL], 0, dir);
343 TRACE_CALL(__func__);
349 TRACE_CALL(__func__);
350 GtkWidget *entry = gtk_bin_get_child(GTK_BIN(widget));
352 if (!gtk_widget_is_focus(entry)) {
353 gtk_widget_grab_focus(entry);
362 TRACE_CALL(__func__);
364 for (i = 0; client->
priv->file_action_widgets[i]; i++) {
365 gtk_widget_set_sensitive(client->
priv->file_action_widgets[i], sensitive);
367 client->
priv->sensitive = sensitive;
372 TRACE_CALL(__func__);
375 list = gtk_tree_selection_get_selected_rows(selection, NULL);
383 TRACE_CALL(__func__);
386 gchar *localdir = NULL;
388 dialog = gtk_file_chooser_dialog_new(_(
"Choose download location"),
389 GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(client))), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
390 "_Cancel", GTK_RESPONSE_CANCEL,
"_OK", GTK_RESPONSE_ACCEPT, NULL);
391 if (priv->working_directory) {
392 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), priv->working_directory);
394 if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
395 g_free(priv->working_directory);
396 priv->working_directory = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(dialog));
397 localdir = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
399 gtk_widget_destroy(dialog);
405 TRACE_CALL(__func__);
407 GtkListStore *store = GTK_LIST_STORE(priv->task_list_model);
416 gtk_list_store_append(store, &iter);
426 g_signal_emit(G_OBJECT(client), remmina_ftp_client_signals[
NEW_TASK_SIGNAL], 0);
432 TRACE_CALL(__func__);
435 GtkTreePath *path = NULL;
438 if (!gtk_tree_view_get_tooltip_context(GTK_TREE_VIEW(priv->task_list_view), &x, &y, keyboard_tip, NULL, &path, &iter)) {
446 gtk_tooltip_set_text(tooltip, tmp);
448 gtk_tree_view_set_tooltip_row(GTK_TREE_VIEW(priv->task_list_view), tooltip, path);
450 gtk_tree_path_free(path);
458 TRACE_CALL(__func__);
464 TRACE_CALL(__func__);
470 TRACE_CALL(__func__);
476 TRACE_CALL(__func__);
478 GtkTreeSelection *selection;
480 GList *list, *list_iter;
483 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->file_list_view));
486 list = gtk_tree_selection_get_selected_rows(selection, NULL);
496 list_iter = g_list_first(list);
498 gtk_tree_model_get_iter(priv->file_list_sort, &iter, (GtkTreePath*)list_iter->data);
500 list_iter = g_list_next(list_iter);
508 TRACE_CALL(__func__);
511 GtkTreeSelection *selection;
512 GList *list, *list_iter;
520 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->file_list_view));
523 list = gtk_tree_selection_get_selected_rows(selection, NULL);
527 dialog = gtk_message_dialog_new(GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(client))), GTK_DIALOG_MODAL,
528 GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, _(
"Are you sure to delete the selected files on server?"));
529 response = gtk_dialog_run(GTK_DIALOG(dialog));
530 gtk_widget_destroy(dialog);
531 if (response != GTK_RESPONSE_YES)
536 list_iter = g_list_first(list);
538 gtk_tree_model_get_iter(priv->file_list_sort, &iter, (GtkTreePath*)list_iter->data);
544 g_signal_emit(G_OBJECT(client), remmina_ftp_client_signals[
DELETE_FILE_SIGNAL], 0, type, path, &ret);
550 list_iter = g_list_next(list_iter);
563 TRACE_CALL(__func__);
564 gtk_file_chooser_set_action(
565 GTK_FILE_CHOOSER(widget),
566 gtk_toggle_button_get_active(togglebutton) ?
567 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER : GTK_FILE_CHOOSER_ACTION_OPEN);
572 TRACE_CALL(__func__);
574 GtkListStore *store = GTK_LIST_STORE(priv->task_list_model);
577 GtkWidget *upload_folder_check;
579 GSList *files = NULL;
585 dialog = gtk_file_chooser_dialog_new(_(
"Choose a file to upload"),
586 GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(client))), GTK_FILE_CHOOSER_ACTION_OPEN,
"_Cancel",
587 GTK_RESPONSE_CANCEL,
"_OK", GTK_RESPONSE_ACCEPT, NULL);
588 gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE);
589 if (priv->working_directory) {
590 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), priv->working_directory);
592 upload_folder_check = gtk_check_button_new_with_label(_(
"Upload folder"));
593 gtk_widget_show(upload_folder_check);
596 gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(dialog), upload_folder_check);
597 if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
598 g_free(priv->working_directory);
599 priv->working_directory = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(dialog));
600 files = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog));
602 type = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(upload_folder_check)) ?
604 gtk_widget_destroy(dialog);
608 for (element = files; element; element = element->next) {
609 path = (gchar*)element->data;
611 if (g_stat(path, &st) < 0)
614 name = g_strrstr(path,
"/");
623 gtk_list_store_append(store, &iter);
636 g_signal_emit(G_OBJECT(client), remmina_ftp_client_signals[
NEW_TASK_SIGNAL], 0);
641 TRACE_CALL(__func__);
646 menu = gtk_menu_new();
648 menuitem = gtk_menu_item_new_with_label(_(
"Download"));
649 gtk_widget_show(menuitem);
650 image = gtk_image_new_from_icon_name(
"remmina-document-save-symbolic", GTK_ICON_SIZE_MENU);
651 gtk_widget_show(image);
652 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
655 menuitem = gtk_menu_item_new_with_label(_(
"Upload"));
656 gtk_widget_show(menuitem);
657 image = gtk_image_new_from_icon_name(
"remmina-document-send-symbolic", GTK_ICON_SIZE_MENU);
658 gtk_widget_show(image);
659 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
662 menuitem = gtk_menu_item_new_with_mnemonic(_(
"_Delete"));
663 gtk_widget_show(menuitem);
664 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
667 #if GTK_CHECK_VERSION(3, 22, 0) 668 gtk_menu_popup_at_pointer(GTK_MENU(menu), (GdkEvent*)event);
670 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, event->button, event->time);
676 TRACE_CALL(__func__);
684 if (event->button == 3) {
686 }
else if (event->button == 1 && event->type == GDK_2BUTTON_PRESS) {
687 list = gtk_tree_selection_get_selected_rows(
688 gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->file_list_view)), NULL);
690 gtk_tree_model_get_iter(priv->file_list_sort, &iter, (GtkTreePath*)list->data);
716 TRACE_CALL(__func__);
719 GtkTreePath *treepath;
721 gboolean ret = FALSE;
723 treepath = gtk_tree_path_new_from_string(path);
724 gtk_tree_model_get_iter(priv->task_list_model, &iter, treepath);
725 gtk_tree_path_free(treepath);
729 g_signal_emit(G_OBJECT(client), remmina_ftp_client_signals[
CANCEL_TASK_SIGNAL], 0, taskid, &ret);
732 gtk_list_store_remove(GTK_LIST_STORE(priv->task_list_model), &iter);
738 TRACE_CALL(__func__);
744 box = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
745 gtk_widget_show(box);
746 gtk_button_box_set_layout(GTK_BUTTON_BOX(box), GTK_BUTTONBOX_START);
747 gtk_grid_attach(GTK_GRID(client), box, 0, 0, 1, 1);
749 button = gtk_button_new_with_label(_(
"Home"));
750 gtk_widget_show(button);
751 gtk_widget_set_tooltip_text(button, _(
"Go to home folder"));
752 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
753 gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0);
756 button = gtk_button_new_with_label(_(
"Up"));
757 gtk_widget_show(button);
758 gtk_widget_set_tooltip_text(button, _(
"Go to parent folder"));
759 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
760 gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0);
763 button = gtk_button_new_with_label(_(
"Refresh"));
764 gtk_widget_show(button);
765 gtk_widget_set_tooltip_text(button, _(
"Refresh current folder"));
766 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
767 gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0);
770 button = gtk_button_new_with_label(_(
"Download"));
771 gtk_widget_show(button);
772 gtk_widget_set_tooltip_text(button, _(
"Download from server"));
773 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
774 image = gtk_image_new_from_icon_name(
"remmina-document-save-symbolic", GTK_ICON_SIZE_BUTTON);
775 gtk_button_set_image(GTK_BUTTON(button), image);
776 gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0);
779 client->
priv->file_action_widgets[i++] = button;
781 button = gtk_button_new_with_label(_(
"Upload"));
782 gtk_widget_show(button);
783 gtk_widget_set_tooltip_text(button, _(
"Upload to server"));
784 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
785 image = gtk_image_new_from_icon_name(
"remmina-document-send-symbolic", GTK_ICON_SIZE_BUTTON);
786 gtk_button_set_image(GTK_BUTTON(button), image);
787 gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0);
790 button = gtk_button_new_with_label(_(
"Delete"));
791 gtk_widget_show(button);
792 gtk_widget_set_tooltip_text(button, _(
"Delete files on server"));
793 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
794 gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0);
797 client->
priv->file_action_widgets[i++] = button;
804 TRACE_CALL(__func__);
805 client->
priv->file_list_show_hidden = show_hidden;
806 gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(client->
priv->file_list_filter));
811 TRACE_CALL(__func__);
813 gboolean result = TRUE;
815 if (client->
priv->file_list_show_hidden)
819 if (name && name[0] ==
'.') {
829 TRACE_CALL(__func__);
830 client->
priv->overwrite_all = status;
836 TRACE_CALL(__func__);
837 return client->
priv->overwrite_all;
842 TRACE_CALL(__func__);
846 GtkWidget *scrolledwindow;
849 GtkTreeViewColumn *column;
856 client->
priv->overwrite_all = FALSE;
859 gtk_widget_set_vexpand(GTK_WIDGET(client), TRUE);
860 gtk_widget_set_hexpand(GTK_WIDGET(client), TRUE);
866 vpaned = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
867 gtk_widget_set_vexpand(GTK_WIDGET(vpaned), TRUE);
868 gtk_widget_set_hexpand(GTK_WIDGET(vpaned), TRUE);
869 gtk_widget_show(vpaned);
870 gtk_grid_attach_next_to(GTK_GRID(client), vpaned, toolbar, GTK_POS_BOTTOM, 1, 1);
872 priv->vpaned = vpaned;
875 vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
876 gtk_widget_show(vbox);
877 gtk_paned_pack1(GTK_PANED(vpaned), vbox, TRUE, FALSE);
880 widget = gtk_combo_box_text_new_with_entry();
881 gtk_widget_show(widget);
882 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(widget),
"/");
883 gtk_box_pack_start(GTK_BOX(vbox), widget, FALSE, TRUE, 0);
885 priv->directory_combo = widget;
888 scrolledwindow = gtk_scrolled_window_new(NULL, NULL);
889 gtk_widget_show(scrolledwindow);
890 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
891 gtk_box_pack_start(GTK_BOX(vbox), scrolledwindow, TRUE, TRUE, 0);
893 widget = gtk_tree_view_new();
894 gtk_widget_show(widget);
895 gtk_container_add(GTK_CONTAINER(scrolledwindow), widget);
897 gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(widget)), GTK_SELECTION_MULTIPLE);
899 priv->file_list_view = widget;
902 column = gtk_tree_view_column_new();
903 gtk_tree_view_column_set_title(column, _(
"Filename"));
904 gtk_tree_view_column_set_expand(column, TRUE);
905 gtk_tree_view_column_set_resizable(column, TRUE);
907 renderer = gtk_cell_renderer_pixbuf_new();
908 gtk_tree_view_column_pack_start(column, renderer, FALSE);
910 renderer = gtk_cell_renderer_text_new();
911 gtk_tree_view_column_pack_start(column, renderer, FALSE);
913 gtk_tree_view_append_column(GTK_TREE_VIEW(priv->file_list_view), column);
915 renderer = gtk_cell_renderer_text_new();
916 column = gtk_tree_view_column_new_with_attributes(_(
"Size"), renderer, NULL);
917 gtk_tree_view_column_set_alignment(column, 1.0);
918 gtk_tree_view_column_set_resizable(column, TRUE);
921 gtk_tree_view_append_column(GTK_TREE_VIEW(priv->file_list_view), column);
923 renderer = gtk_cell_renderer_text_new();
925 gtk_tree_view_column_set_resizable(column, TRUE);
927 gtk_tree_view_append_column(GTK_TREE_VIEW(priv->file_list_view), column);
929 renderer = gtk_cell_renderer_text_new();
931 gtk_tree_view_column_set_resizable(column, TRUE);
933 gtk_tree_view_append_column(GTK_TREE_VIEW(priv->file_list_view), column);
935 renderer = gtk_cell_renderer_text_new();
938 gtk_tree_view_column_set_resizable(column, TRUE);
941 gtk_tree_view_append_column(GTK_TREE_VIEW(priv->file_list_view), column);
944 priv->file_list_model = GTK_TREE_MODEL(
946 G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING));
948 priv->file_list_filter = gtk_tree_model_filter_new(priv->file_list_model, NULL);
949 gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(priv->file_list_filter),
952 priv->file_list_sort = gtk_tree_model_sort_new_with_model(priv->file_list_filter);
955 gtk_tree_view_set_model(GTK_TREE_VIEW(priv->file_list_view), priv->file_list_sort);
958 scrolledwindow = gtk_scrolled_window_new(NULL, NULL);
959 gtk_widget_show(scrolledwindow);
960 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
961 gtk_paned_pack2(GTK_PANED(vpaned), scrolledwindow, FALSE, TRUE);
963 widget = gtk_tree_view_new();
964 gtk_widget_show(widget);
965 gtk_container_add(GTK_CONTAINER(scrolledwindow), widget);
966 g_object_set(widget,
"has-tooltip", TRUE, NULL);
968 priv->task_list_view = widget;
971 column = gtk_tree_view_column_new();
972 gtk_tree_view_column_set_title(column, _(
"Filename"));
973 gtk_tree_view_column_set_resizable(column, TRUE);
974 gtk_tree_view_column_set_expand(column, TRUE);
976 renderer = gtk_cell_renderer_pixbuf_new();
977 gtk_tree_view_column_pack_start(column, renderer, FALSE);
979 renderer = gtk_cell_renderer_pixbuf_new();
980 gtk_tree_view_column_pack_start(column, renderer, FALSE);
982 renderer = gtk_cell_renderer_text_new();
983 gtk_tree_view_column_pack_start(column, renderer, FALSE);
985 gtk_tree_view_append_column(GTK_TREE_VIEW(priv->task_list_view), column);
987 renderer = gtk_cell_renderer_text_new();
990 gtk_tree_view_column_set_resizable(column, TRUE);
992 gtk_tree_view_append_column(GTK_TREE_VIEW(priv->task_list_view), column);
994 renderer = gtk_cell_renderer_text_new();
996 gtk_tree_view_column_set_resizable(column, TRUE);
998 gtk_tree_view_append_column(GTK_TREE_VIEW(priv->task_list_view), column);
1000 renderer = gtk_cell_renderer_text_new();
1001 column = gtk_tree_view_column_new_with_attributes(_(
"Size"), renderer, NULL);
1002 gtk_tree_view_column_set_alignment(column, 1.0);
1003 gtk_tree_view_column_set_resizable(column, TRUE);
1006 gtk_tree_view_append_column(GTK_TREE_VIEW(priv->task_list_view), column);
1008 renderer = gtk_cell_renderer_progress_new();
1009 column = gtk_tree_view_column_new_with_attributes(_(
"Progress"), renderer, NULL);
1010 gtk_tree_view_column_set_resizable(column, TRUE);
1012 gtk_tree_view_append_column(GTK_TREE_VIEW(priv->task_list_view), column);
1015 column = gtk_tree_view_column_new_with_attributes(NULL, renderer, NULL);
1016 g_object_set(G_OBJECT(renderer),
"stock-id",
"_Cancel", NULL);
1017 gtk_tree_view_column_set_resizable(column, FALSE);
1018 gtk_tree_view_append_column(GTK_TREE_VIEW(priv->task_list_view), column);
1023 priv->task_list_model = GTK_TREE_MODEL(
1025 G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_FLOAT, G_TYPE_STRING));
1026 gtk_tree_view_set_model(GTK_TREE_VIEW(priv->task_list_view), priv->task_list_model);
1030 g_signal_connect(G_OBJECT(gtk_bin_get_child(GTK_BIN(priv->directory_combo))),
"activate",
1033 g_signal_connect(G_OBJECT(priv->file_list_view),
"button-press-event",
1035 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->file_list_view))),
"changed",
1037 g_signal_connect(G_OBJECT(priv->task_list_view),
"query-tooltip",
1044 TRACE_CALL(__func__);
1047 client = REMMINA_FTP_CLIENT(g_object_new(REMMINA_TYPE_FTP_CLIENT, NULL));
1049 return GTK_WIDGET(client);
1054 TRACE_CALL(__func__);
1057 pos = gtk_paned_get_position(GTK_PANED(client->
priv->vpaned));
1063 TRACE_CALL(__func__);
1069 gtk_widget_get_allocation(client->
priv->vpaned, &a);
1070 if (a.height > 0 && pos > a.height - 60) {
1071 pos = a.height - 60;
1073 gtk_paned_set_position(GTK_PANED(client->
priv->vpaned), pos);
1079 TRACE_CALL(__func__);
1082 gtk_list_store_clear(GTK_LIST_STORE(priv->file_list_model));
1088 TRACE_CALL(__func__);
1090 GtkListStore *store = GTK_LIST_STORE(priv->file_list_model);
1097 va_start(args, client);
1098 gtk_list_store_append(store, &iter);
1099 gtk_list_store_set_valist(store, &iter, args);
1102 gtk_tree_model_get(GTK_TREE_MODEL(store), &iter,
1107 ptr = g_strdup_printf(
"%i%s", type, name);
1115 TRACE_CALL(__func__);
1117 GtkTreeModel *model;
1122 if (priv->current_directory && g_strcmp0(priv->current_directory, dir) == 0)
1125 model = gtk_combo_box_get_model(GTK_COMBO_BOX(priv->directory_combo));
1126 for (ret = gtk_tree_model_get_iter_first(model, &iter); ret; ret = gtk_tree_model_iter_next(model, &iter)) {
1127 gtk_tree_model_get(model, &iter, 0, &t, -1);
1128 if (g_strcmp0(t, dir) == 0) {
1129 gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
1136 gtk_combo_box_text_prepend_text(GTK_COMBO_BOX_TEXT(priv->directory_combo), dir);
1137 gtk_combo_box_set_active(GTK_COMBO_BOX(priv->directory_combo), 0);
1139 g_free(priv->current_directory);
1140 priv->current_directory = g_strdup(dir);
1146 TRACE_CALL(__func__);
1149 return g_strdup(priv->current_directory);
1155 TRACE_CALL(__func__);
1166 d->
func = FUNC_FTP_CLIENT_GET_WAITING_TASK;
1174 if (!gtk_tree_model_get_iter_first(priv->task_list_model, &iter))
1185 path = gtk_tree_model_get_path(priv->task_list_model, &iter);
1186 task.rowref = gtk_tree_row_reference_new(priv->task_list_model, path);
1187 gtk_tree_path_free(path);
1190 if (!gtk_tree_model_iter_next(priv->task_list_model, &iter))
1199 TRACE_CALL(__func__);
1201 GtkListStore *store = GTK_LIST_STORE(priv->task_list_model);
1209 d->
func = FUNC_FTP_CLIENT_UPDATE_TASK;
1219 path = gtk_tree_row_reference_get_path(task->
rowref);
1222 gtk_tree_model_get_iter(priv->task_list_model, &iter, path);
1223 gtk_tree_path_free(path);
1230 TRACE_CALL(__func__);
static gboolean remmina_ftp_client_file_list_on_button_press(GtkWidget *widget, GdkEventButton *event, RemminaFTPClient *client)
void remmina_ftp_client_load_state(RemminaFTPClient *client, RemminaFile *remminafile)
void remmina_ftp_client_set_overwrite_status(RemminaFTPClient *client, gboolean status)
static gchar * remmina_ftp_client_size_to_str(gfloat size)
GtkCellRendererPixbufClass parent_class
void remmina_ftp_client_set_show_hidden(RemminaFTPClient *client, gboolean show_hidden)
static guint remmina_ftp_client_signals[LAST_SIGNAL]
static void remmina_ftp_client_cell_data_permission(GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
static void remmina_ftp_client_action_home(GObject *object, RemminaFTPClient *client)
struct _RemminaFTPClientPriv RemminaFTPClientPriv
static void remmina_ftp_client_popup_menu(RemminaFTPClient *client, GdkEventButton *event)
typedefG_BEGIN_DECLS struct _RemminaFile RemminaFile
static GtkWidget * remmina_ftp_client_create_toolbar(RemminaFTPClient *client)
GtkCellRendererPixbuf renderer
static gboolean remmina_ftp_client_task_list_on_query_tooltip(GtkWidget *widget, gint x, gint y, gboolean keyboard_tip, GtkTooltip *tooltip, RemminaFTPClient *client)
struct remmina_masterthread_exec_data::@11::@16 ftp_client_update_task
static void remmina_ftp_client_file_selection_on_changed(GtkTreeSelection *selection, RemminaFTPClient *client)
static void remmina_ftp_client_download(RemminaFTPClient *client, GtkTreeIter *piter, const gchar *localdir)
static void remmina_ftp_client_upload_folder_on_toggled(GtkToggleButton *togglebutton, GtkWidget *widget)
enum remmina_masterthread_exec_data::@10 func
static void remmina_ftp_client_class_init(RemminaFTPClientClass *klass)
gchar * remmina_ftp_client_get_dir(RemminaFTPClient *client)
static void remmina_cell_renderer_pixbuf_class_init(RemminaCellRendererPixbufClass *klass)
static void remmina_ftp_client_set_file_action_sensitive(RemminaFTPClient *client, gboolean sensitive)
static void remmina_ftp_client_cell_data_progress(GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
RemminaFTPTask * remmina_ftp_client_get_waiting_task(RemminaFTPClient *client)
void remmina_ftp_client_update_task(RemminaFTPClient *client, RemminaFTPTask *task)
RemminaFTPClientPriv * priv
gchar * remmina_public_combine_path(const gchar *path1, const gchar *path2)
static gchar * remmina_ftp_client_get_download_dir(RemminaFTPClient *client)
static void remmina_ftp_client_open_dir(RemminaFTPClient *client, const gchar *dir)
gboolean remmina_ftp_client_get_overwrite_status(RemminaFTPClient *client)
static void remmina_cell_renderer_pixbuf_init(RemminaCellRendererPixbuf *renderer)
struct _RemminaCellRendererPixbuf RemminaCellRendererPixbuf
struct remmina_masterthread_exec_data::@11::@17 ftp_client_get_waiting_task
static void remmina_ftp_client_dir_on_changed(GtkWidget *widget, RemminaFTPClient *client)
static void remmina_ftp_client_action_refresh(GObject *object, RemminaFTPClient *client)
gboolean remmina_masterthread_exec_is_main_thread()
static void remmina_ftp_client_destroy(RemminaFTPClient *client, gpointer data)
union remmina_masterthread_exec_data::@11 p
struct _RemminaCellRendererPixbufClass RemminaCellRendererPixbufClass
void remmina_ftp_task_free(RemminaFTPTask *task)
void remmina_ftp_client_add_file(RemminaFTPClient *client,...)
static void remmina_ftp_client_dir_on_activate(GtkWidget *widget, RemminaFTPClient *client)
void remmina_ftp_client_set_dir(RemminaFTPClient *client, const gchar *dir)
void remmina_file_set_int(RemminaFile *remminafile, const gchar *setting, gint value)
static void remmina_ftp_client_cell_data_size_progress(GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
static void remmina_ftp_client_cell_data_progress_pixbuf(GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
static void remmina_ftp_client_action_upload(GObject *object, RemminaFTPClient *client)
static void remmina_ftp_client_action_parent(GObject *object, RemminaFTPClient *client)
static gint remmina_ftp_client_taskid
static gboolean remmina_cell_renderer_pixbuf_activate(GtkCellRenderer *renderer, GdkEvent *event, GtkWidget *widget, const gchar *path, const GdkRectangle *background_area, const GdkRectangle *cell_area, GtkCellRendererState flags)
void remmina_marshal_BOOLEAN__INT_STRING(GClosure *closure, GValue *return_value G_GNUC_UNUSED, guint n_param_values, const GValue *param_values, gpointer invocation_hint G_GNUC_UNUSED, gpointer marshal_data)
void remmina_masterthread_exec_and_wait(RemminaMTExecData *d)
GtkWidget * remmina_ftp_client_new(void)
static void remmina_ftp_client_cell_data_filetype_pixbuf(GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
GType remmina_cell_renderer_pixbuf_get_type(void)
gint remmina_file_get_int(RemminaFile *remminafile, const gchar *setting, gint default_value)
static void remmina_ftp_client_init(RemminaFTPClient *client)
static void remmina_ftp_client_task_list_cell_on_activate(GtkCellRenderer *renderer, gchar *path, RemminaFTPClient *client)
void remmina_ftp_client_clear_file_list(RemminaFTPClient *client)
static void remmina_ftp_client_action_download(GObject *object, RemminaFTPClient *client)
G_DEFINE_TYPE(RemminaFTPClient, remmina_ftp_client, GTK_TYPE_GRID)
static void remmina_ftp_client_cell_data_size(GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
static void remmina_ftp_client_action_delete(GObject *object, RemminaFTPClient *client)
static GtkCellRenderer * remmina_cell_renderer_pixbuf_new(void)
void remmina_marshal_BOOLEAN__INT(GClosure *closure, GValue *return_value G_GNUC_UNUSED, guint n_param_values, const GValue *param_values, gpointer invocation_hint G_GNUC_UNUSED, gpointer marshal_data)
void remmina_ftp_client_save_state(RemminaFTPClient *client, RemminaFile *remminafile)
GtkTreeRowReference * rowref
static gboolean remmina_ftp_client_filter_visible_func(GtkTreeModel *model, GtkTreeIter *iter, RemminaFTPClient *client)