diff --git a/src/filetransfer/activity.c b/src/filetransfer/activity.c index bde2f57..2ae52ef 100644 --- a/src/filetransfer/activity.c +++ b/src/filetransfer/activity.c @@ -65,7 +65,7 @@ PROP_REMOTE }; - G_DEFINE_TYPE(V3270FTActivity, V3270FTActivity, G_TYPE_OBJECT); + G_DEFINE_TYPE(V3270FTActivity, V3270FTActivity, G_TYPE_INITIALLY_UNOWNED); /*--[ Implement ]------------------------------------------------------------------------------------*/ @@ -148,16 +148,16 @@ return g_object_new(G_TYPE_V3270_FT_ACTIVITY, NULL); } - LIB3270_EXPORT const gchar * v3270_ft_activity_get_local_filename(GObject *object) + LIB3270_EXPORT const gchar * v3270_ft_activity_get_local_filename(const GObject *object) { - gchar **ptr = & G_V3270_FT_ACTIVITY(object)->file.local; - return(*ptr ? *ptr : ""); + const gchar *ptr = G_V3270_FT_ACTIVITY(object)->file.local; + return (ptr ? ptr : ""); } - LIB3270_EXPORT const gchar * v3270_ft_activity_get_remote_filename(GObject *object) + LIB3270_EXPORT const gchar * v3270_ft_activity_get_remote_filename(const GObject *object) { - gchar **ptr = & G_V3270_FT_ACTIVITY(object)->file.remote; - return(*ptr ? *ptr : ""); + const gchar *ptr = G_V3270_FT_ACTIVITY(object)->file.remote; + return(ptr ? ptr : ""); } LIB3270_EXPORT void v3270_ft_activity_set_local_filename(GObject *object, const gchar *filename) @@ -181,12 +181,12 @@ G_V3270_FT_ACTIVITY(object)->options = options; } - LIB3270_EXPORT LIB3270_FT_OPTION v3270_ft_activity_get_options(GObject *object) + LIB3270_EXPORT LIB3270_FT_OPTION v3270_ft_activity_get_options(const GObject *object) { return G_V3270_FT_ACTIVITY(object)->options; } - guint v3270_ft_activity_get_value(GObject * object, LIB3270_FT_VALUE id) + guint v3270_ft_activity_get_value(const GObject * object, LIB3270_FT_VALUE id) { return G_V3270_FT_ACTIVITY(object)->values[id]; } diff --git a/src/filetransfer/activitylist.c b/src/filetransfer/activitylist.c index 052f94c..847360e 100644 --- a/src/filetransfer/activitylist.c +++ b/src/filetransfer/activitylist.c @@ -40,6 +40,11 @@ V3270_ACTIVITY_LIST_LAST_SIGNAL }; + typedef struct _activities + { + + } Activities; + struct _V3270FTActivityListClass { GtkTreeViewClass parent_class; @@ -65,14 +70,31 @@ static void dispose(GObject *object) { - debug("%s",__FUNCTION__); + debug("%s (model=%p)",__FUNCTION__,gtk_tree_view_get_model(GTK_TREE_VIEW(object))); V3270FTActivityList * list = GTK_V3270_FT_ACTIVITY_LIST(object); + // Release filename debug("Freeing %s",list->filename); g_free(list->filename); list->filename = NULL; + GtkTreeIter iter; + GtkTreeModel * model = gtk_tree_view_get_model(GTK_TREE_VIEW(object)); + + while(model && gtk_tree_model_get_iter_first(model,&iter)) + { + GObject * activity = NULL; + gtk_tree_model_get(model, &iter, 0, &activity, -1); + + gtk_list_store_remove(GTK_LIST_STORE(model),&iter); + debug("Disposing activity %p",activity); + + g_clear_object(&activity); + + } + + G_OBJECT_CLASS(V3270FTActivityList_parent_class)->dispose(object); } @@ -118,7 +140,7 @@ static void V3270FTActivityList_init(V3270FTActivityList *widget) { - GtkTreeModel * model = GTK_TREE_MODEL(gtk_list_store_new(1,G_TYPE_OBJECT)); + GtkTreeModel * model = GTK_TREE_MODEL(gtk_list_store_new(1,G_TYPE_POINTER)); // Using pointer type because I take care of refcounts. widget->filename = NULL; @@ -157,6 +179,8 @@ GtkTreeIter iter; gtk_list_store_append((GtkListStore *) model,&iter); gtk_list_store_set((GtkListStore *) model, &iter, 0, activity, -1); + g_object_ref_sink(activity); + } void v3270_activity_list_remove(GtkWidget *widget, GObject *activity) @@ -176,7 +200,9 @@ if(stored == activity) { + debug("Removing activity %p",activity); gtk_list_store_remove(GTK_LIST_STORE(model),&iter); + g_object_unref(stored); return; } diff --git a/src/filetransfer/dialog.c b/src/filetransfer/dialog.c index df7792b..e7a1223 100644 --- a/src/filetransfer/dialog.c +++ b/src/filetransfer/dialog.c @@ -155,6 +155,50 @@ static void begin_clicked(GtkButton G_GNUC_UNUSED(*button), V3270FTDialog *widge gtk_dialog_response(GTK_DIALOG(widget),GTK_RESPONSE_ACCEPT); } +static gboolean v3270_activity_compare_filenames(const GObject *a, const GObject *b) +{ + if(strcmp(v3270_ft_activity_get_local_filename(a),v3270_ft_activity_get_local_filename(b))) + return FALSE; + + if(strcmp(v3270_ft_activity_get_remote_filename(a),v3270_ft_activity_get_remote_filename(b))) + return FALSE; + + return TRUE; +} + +int v3270_ft_dialog_append_activity(GtkWidget *widget, GObject *activity, GError **error) +{ + V3270FTDialog *dialog = GTK_V3270_FT_DIALOG(widget); + + GtkTreeIter iter; + GtkTreeModel * model = gtk_tree_view_get_model(GTK_TREE_VIEW(dialog->queue.view)); + + if(gtk_tree_model_get_iter_first(model,&iter)) + { + do + { + GObject * a = NULL; + gtk_tree_model_get(model, &iter, 0, &a, -1); + + if(a && v3270_activity_compare_filenames(activity, a)) + { + // Activity already exist + if(error && !*error) + *error = g_error_new_literal(g_quark_from_static_string(PACKAGE_NAME),EPERM,_("Activity already on the queue")); + + return -1; + } + + } + while(gtk_tree_model_iter_next(model,&iter)); + } + + // Not found, insert it. + v3270_activity_list_append(dialog->queue.view,activity); + + return 0; +} + static void insert_clicked(GtkWidget *button, V3270FTDialog *widget) { GtkTreeIter iter; diff --git a/src/filetransfer/worker.c b/src/filetransfer/worker.c index c1c39a9..bf70884 100644 --- a/src/filetransfer/worker.c +++ b/src/filetransfer/worker.c @@ -131,11 +131,15 @@ pulse_stop(worker); timer_stop(worker); + g_clear_object(&worker->activity); + + /* if(worker->activity) { g_object_unref(worker->activity); worker->activity = NULL; } + */ G_OBJECT_CLASS(V3270FTWorker_parent_class)->finalize(object); @@ -294,16 +298,12 @@ lib3270_ft_destroy(worker->hSession,NULL); } - if(worker->activity) - { - g_object_unref(worker->activity); - worker->activity = NULL; - } + g_clear_object(&worker->activity); if(activity) { worker->activity = activity; - g_object_ref(worker->activity); + g_object_ref_sink(activity); gtk_entry_set_text(worker->field[PROGRESS_FIELD_LOCAL],v3270_ft_activity_get_local_filename(activity)); gtk_entry_set_text(worker->field[PROGRESS_FIELD_REMOTE],v3270_ft_activity_get_remote_filename(activity)); diff --git a/src/include/v3270/filetransfer.h b/src/include/v3270/filetransfer.h index 3d23568..cb687cf 100644 --- a/src/include/v3270/filetransfer.h +++ b/src/include/v3270/filetransfer.h @@ -120,10 +120,10 @@ LIB3270_EXPORT void v3270_ft_activity_set_from_context(GObject * activity, GMarkupParseContext * context); - LIB3270_EXPORT const gchar * v3270_ft_activity_get_local_filename(GObject *object); - LIB3270_EXPORT const gchar * v3270_ft_activity_get_remote_filename(GObject *object); - LIB3270_EXPORT LIB3270_FT_OPTION v3270_ft_activity_get_options(GObject *object); - LIB3270_EXPORT guint v3270_ft_activity_get_value(GObject * object, LIB3270_FT_VALUE id); + LIB3270_EXPORT const gchar * v3270_ft_activity_get_local_filename(const GObject *object); + LIB3270_EXPORT const gchar * v3270_ft_activity_get_remote_filename(const GObject *object); + LIB3270_EXPORT LIB3270_FT_OPTION v3270_ft_activity_get_options(const GObject *object); + LIB3270_EXPORT guint v3270_ft_activity_get_value(const GObject * object, LIB3270_FT_VALUE id); LIB3270_EXPORT void v3270_ft_activity_set_local_filename(GObject *object, const gchar *filename); LIB3270_EXPORT void v3270_ft_activity_set_remote_filename(GObject *object, const gchar *filename); @@ -144,6 +144,7 @@ LIB3270_EXPORT GtkWidget * v3270_ft_dialog_new(GtkWidget *parent); LIB3270_EXPORT void v3270_ft_dialog_set_session(GtkWidget *widget, H3270 *hSession); + LIB3270_EXPORT int v3270_ft_dialog_append_activity(GtkWidget *widget, GObject *activity, GError **error); G_END_DECLS diff --git a/src/testprogram/testprogram.c b/src/testprogram/testprogram.c index fe89cab..8d40629 100644 --- a/src/testprogram/testprogram.c +++ b/src/testprogram/testprogram.c @@ -149,23 +149,32 @@ static void disconnect_clicked(GtkButton G_GNUC_UNUSED(*button), GtkWidget *term static void ft_clicked(GtkButton G_GNUC_UNUSED(*button), GtkWidget *terminal) { - GtkWidget * dialog = v3270_dialog_new(terminal, _("test"), _("test")); - GtkWidget * worker = v3270_ft_worker_new(); - gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),worker,TRUE,TRUE,2); - - v3270_ft_worker_set_session(worker,v3270_get_session(terminal)); - + // + // Test activity + // GObject * activity = v3270_ft_activity_new(); + debug("Activity %p is %s",activity,(g_object_is_floating(activity) ? "floating" : "non floating")); v3270_ft_activity_set_local_filename(activity,"/tmp/test.txt"); v3270_ft_activity_set_remote_filename(activity,"remote_file"); v3270_ft_activity_set_options(activity,LIB3270_FT_OPTION_RECEIVE|LIB3270_FT_OPTION_ASCII|LIB3270_FT_OPTION_REMAP); - v3270_ft_worker_set_activity(worker,activity); - g_object_unref(activity); - v3270_ft_worker_start(worker); + /* + // + // Test settings dialog + // + GtkWidget * dialog = v3270_ft_dialog_new(terminal); + v3270_ft_dialog_append_activity(dialog,activity,NULL); + */ - // GtkWidget * dialog = v3270ftprogress_new(); - // GtkWidget * dialog = v3270_ft_dialog_new(terminal); + // + // Test worker widget + // + GtkWidget * dialog = v3270_dialog_new(terminal, _("test"), _("test")); + GtkWidget * worker = v3270_ft_worker_new(); + gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),worker,TRUE,TRUE,2); + v3270_ft_worker_set_session(worker,v3270_get_session(terminal)); + v3270_ft_worker_set_activity(worker,activity); + v3270_ft_worker_start(worker); gtk_widget_show_all(dialog); gtk_dialog_run(GTK_DIALOG(dialog)); -- libgit2 0.21.2