diff --git a/src/sui/srain_app.c b/src/sui/srain_app.c index 81f81a36..4b08c010 100644 --- a/src/sui/srain_app.c +++ b/src/sui/srain_app.c @@ -148,7 +148,7 @@ static void srain_app_class_init(SrainAppClass *class){ SrainApp* srain_app_new(void){ return g_object_new(SRAIN_TYPE_APP, - "application-id", "org.srain.srain", + "application-id", "org.srain.srain-dev", "flags", G_APPLICATION_HANDLES_COMMAND_LINE, NULL); } diff --git a/src/sui/srain_join_popover.c b/src/sui/srain_join_popover.c index 8fc0c50f..946d3a64 100644 --- a/src/sui/srain_join_popover.c +++ b/src/sui/srain_join_popover.c @@ -30,6 +30,9 @@ #include "sui_event_hdr.h" #include "srain_window.h" #include "srain_join_popover.h" +#include "srain_buffer.h" +#include "srain_server_buffer.h" +#include "srain_chat_buffer.h" #include "srain.h" #include "i18n.h" @@ -46,15 +49,10 @@ #define MATCH_LIST_STORE_COL_INDEX 0 #define MATCH_LIST_STORE_COL_COMMENT 1 -#define CHAN_LIST_STORE_COL_CHANNEL 0 -#define CHAN_LIST_STORE_COL_USERS 1 -#define CHAN_LIST_STORE_COL_TOPIC 2 - struct _SrainJoinPopover { GtkPopover parent; int match; - bool adding; GtkStack *stack; @@ -84,8 +82,6 @@ struct _SrainJoinPopover { /* Data model */ GtkListStore *match_list_store; - GtkListStore *chan_list_store; - GtkTreeModel *chan_tree_model_filter; // FilterTreeModel of chan_list_store }; struct _SrainJoinPopoverClass { @@ -94,10 +90,7 @@ struct _SrainJoinPopoverClass { G_DEFINE_TYPE(SrainJoinPopover, srain_join_popover, GTK_TYPE_POPOVER); -static void srain_join_popover_init(SrainJoinPopover *self); -static void srain_join_popover_class_init(SrainJoinPopoverClass *class); static void match_combo_box_set_model(SrainJoinPopover *popover); -static void chan_tree_view_set_model(SrainJoinPopover *popover); static void popover_on_visible(GObject *object, GParamSpec *pspec, gpointer data); static void cancel_button_on_click(gpointer user_data); @@ -111,63 +104,116 @@ gboolean chan_tree_visible_func(GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data); static void chan_tree_model_filter_refilter(gpointer user_data); -SrainJoinPopover* srain_join_popover_new(GtkWidget *relative){ - SrainJoinPopover *popover; +static void on_adding_channel (GtkWidget *widget, GParamSpec *pspec, gpointer user_data); +static void update_status(SrainJoinPopover *popover, bool adding); - popover = g_object_new(SRAIN_TYPE_JOIN_POPOVER, NULL); +/***************************************************************************** + * GLib functions + *****************************************************************************/ - gtk_popover_set_relative_to(GTK_POPOVER(popover), relative); +static void srain_join_popover_init(SrainJoinPopover *popover){ + gtk_widget_init_template(GTK_WIDGET(popover)); - return popover; -} +#if GTK_CHECK_VERSION(3, 18, 0) + gtk_stack_set_interpolate_size(popover->stack, TRUE); +#endif + + popover->match = MATCH_CHANNEL; + match_combo_box_set_model(popover); + + g_signal_connect(popover, "notify::visible", + G_CALLBACK(popover_on_visible), NULL); + + g_signal_connect_swapped(popover->chan_entry, "activate", + G_CALLBACK(join_button_on_click), popover); + g_signal_connect_swapped(popover->passwd_entry, "activate", + G_CALLBACK(join_button_on_click), popover); -void srain_join_popover_start_chan(SrainJoinPopover *popover){ - popover->adding = TRUE; - gtk_list_store_clear(popover->chan_list_store); - gtk_spinner_start(popover->status_spinner); + g_signal_connect_swapped(popover->search_entry, "activate", + G_CALLBACK(join_button_on_click), popover); + g_signal_connect_swapped(popover->refresh_button, "clicked", + G_CALLBACK(refresh_button_on_clicked), popover); + g_signal_connect(popover->match_combo_box, "changed", + G_CALLBACK(match_combo_box_on_changed), popover); + g_signal_connect(popover->chan_tree_view, "row-activated", + G_CALLBACK(chan_tree_view_on_row_activate), popover); + + /* Filter condition changed */ + g_signal_connect_swapped(popover->search_entry, "changed", + G_CALLBACK(chan_tree_model_filter_refilter), popover); + g_signal_connect_swapped(popover->match_combo_box, "changed", + G_CALLBACK(chan_tree_model_filter_refilter), popover); + g_signal_connect_swapped(popover->min_users_spin_button, "changed", + G_CALLBACK(chan_tree_model_filter_refilter), popover); + g_signal_connect_swapped(popover->max_users_spin_button, "changed", + G_CALLBACK(chan_tree_model_filter_refilter), popover); + g_signal_connect_swapped(popover->max_users_spin_button, "changed", + G_CALLBACK(chan_tree_model_filter_refilter), popover); + + g_signal_connect_swapped(popover->cancel_button, "clicked", + G_CALLBACK(cancel_button_on_click), popover); + g_signal_connect_swapped(popover->join_button, "clicked", + G_CALLBACK(join_button_on_click), popover); } -void srain_join_popover_add_chan(SrainJoinPopover *popover, - const char *chan, int users, const char *topic){ - char *status; - GtkTreeIter iter; - GtkListStore *store; +static void srain_join_popover_class_init(SrainJoinPopoverClass *class){ + GtkWidgetClass *widget_class; - store = popover->chan_list_store; + widget_class = GTK_WIDGET_CLASS(class); + gtk_widget_class_set_template_from_resource(widget_class, + "/org/gtk/srain/join_popover.glade"); - /* Adding new channel is not allowed while adding = FALSE */ - if (!popover->adding) { - return; - } + gtk_widget_class_bind_template_child(widget_class, SrainJoinPopover, stack); - gtk_list_store_append(store, &iter); - gtk_list_store_set(store, &iter, - CHAN_LIST_STORE_COL_CHANNEL, chan, - CHAN_LIST_STORE_COL_USERS, users, - CHAN_LIST_STORE_COL_TOPIC, topic, - -1); + gtk_widget_class_bind_template_child(widget_class, SrainJoinPopover, chan_entry); + gtk_widget_class_bind_template_child(widget_class, SrainJoinPopover, passwd_entry ); - /* Update status */ - status = g_strdup_printf(_("Loading %d channnels..."), - gtk_tree_model_iter_n_children( - GTK_TREE_MODEL(store), NULL)); - gtk_label_set_text(popover->status_label, status); - g_free(status); + gtk_widget_class_bind_template_child(widget_class, SrainJoinPopover, search_entry); + gtk_widget_class_bind_template_child(widget_class, SrainJoinPopover, refresh_button); + gtk_widget_class_bind_template_child(widget_class, SrainJoinPopover, match_combo_box); + gtk_widget_class_bind_template_child(widget_class, SrainJoinPopover, min_users_spin_button); + gtk_widget_class_bind_template_child(widget_class, SrainJoinPopover, max_users_spin_button); + + gtk_widget_class_bind_template_child(widget_class, SrainJoinPopover, chan_tree_view); + gtk_widget_class_bind_template_child(widget_class, SrainJoinPopover, chan_tree_view_column); + gtk_widget_class_bind_template_child(widget_class, SrainJoinPopover, users_tree_view_column); + gtk_widget_class_bind_template_child(widget_class, SrainJoinPopover, topic_tree_view_column); + + gtk_widget_class_bind_template_child(widget_class, SrainJoinPopover, status_label); + gtk_widget_class_bind_template_child(widget_class, SrainJoinPopover, status_spinner); + + gtk_widget_class_bind_template_child(widget_class, SrainJoinPopover, cancel_button); + gtk_widget_class_bind_template_child(widget_class, SrainJoinPopover, join_button); } -void srain_join_popover_end_chan(SrainJoinPopover *popover){ - char *status; +SrainJoinPopover* srain_join_popover_new(GtkWidget *relative){ + SrainJoinPopover *popover; + + popover = g_object_new(SRAIN_TYPE_JOIN_POPOVER, NULL); + gtk_popover_set_relative_to(GTK_POPOVER(popover), relative); - popover->adding = FALSE; - gtk_spinner_stop(popover->status_spinner); + return popover; +} - status = g_strdup_printf(_("Showing %d of %d channnels"), - gtk_tree_model_iter_n_children( - GTK_TREE_MODEL(popover->chan_tree_model_filter), NULL), - gtk_tree_model_iter_n_children( - GTK_TREE_MODEL(popover->chan_list_store), NULL)); - gtk_label_set_text(popover->status_label, status); - g_free(status); +/***************************************************************************** + * Exported functions + *****************************************************************************/ + +void srain_join_popover_prepare_model(SrainJoinPopover *popover, + SrainServerBuffer *buf){ + g_signal_connect(buf, "notify::adding-channel", + G_CALLBACK(on_adding_channel), popover); + + // Can only be called once for a given filter model + gtk_tree_model_filter_set_visible_func( + srain_server_buffer_get_channel_model(buf), + chan_tree_visible_func, popover, NULL); +} + +void srain_join_popover_set_model(SrainJoinPopover *popover, + SrainServerBuffer *buf){ + gtk_tree_view_set_model(popover->chan_tree_view, + GTK_TREE_MODEL(srain_server_buffer_get_channel_model(buf))); } void srain_join_popover_clear(SrainJoinPopover *popover){ @@ -180,84 +226,11 @@ void srain_join_popover_clear(SrainJoinPopover *popover){ gtk_spin_button_set_value(popover->min_users_spin_button, -1); gtk_spin_button_set_value(popover->max_users_spin_button, -1); } + /***************************************************************************** * Static functions *****************************************************************************/ -static void srain_join_popover_init(SrainJoinPopover *self){ - gtk_widget_init_template(GTK_WIDGET(self)); - -#if GTK_CHECK_VERSION(3, 18, 0) - gtk_stack_set_interpolate_size(self->stack, TRUE); -#endif - - self->adding = FALSE; - self->match = MATCH_CHANNEL; - match_combo_box_set_model(self); - chan_tree_view_set_model(self); - - g_signal_connect(self, "notify::visible", - G_CALLBACK(popover_on_visible), NULL); - - g_signal_connect_swapped(self->chan_entry, "activate", - G_CALLBACK(join_button_on_click), self); - g_signal_connect_swapped(self->passwd_entry, "activate", - G_CALLBACK(join_button_on_click), self); - - g_signal_connect_swapped(self->search_entry, "activate", - G_CALLBACK(join_button_on_click), self); - g_signal_connect_swapped(self->refresh_button, "clicked", - G_CALLBACK(refresh_button_on_clicked), self); - g_signal_connect(self->match_combo_box, "changed", - G_CALLBACK(match_combo_box_on_changed), self); - g_signal_connect(self->chan_tree_view, "row-activated", - G_CALLBACK(chan_tree_view_on_row_activate), self); - - /* Filter condition changed */ - g_signal_connect_swapped(self->search_entry, "changed", - G_CALLBACK(chan_tree_model_filter_refilter), self); - g_signal_connect_swapped(self->match_combo_box, "changed", - G_CALLBACK(chan_tree_model_filter_refilter), self); - g_signal_connect_swapped(self->min_users_spin_button, "changed", - G_CALLBACK(chan_tree_model_filter_refilter), self); - g_signal_connect_swapped(self->max_users_spin_button, "changed", - G_CALLBACK(chan_tree_model_filter_refilter), self); - g_signal_connect_swapped(self->max_users_spin_button, "changed", - G_CALLBACK(chan_tree_model_filter_refilter), self); - - g_signal_connect_swapped(self->cancel_button, "clicked", - G_CALLBACK(cancel_button_on_click), self); - g_signal_connect_swapped(self->join_button, "clicked", - G_CALLBACK(join_button_on_click), self); -} - -static void srain_join_popover_class_init(SrainJoinPopoverClass *class){ - gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS(class), - "/org/gtk/srain/join_popover.glade"); - - gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), SrainJoinPopover, stack); - - gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), SrainJoinPopover, chan_entry); - gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), SrainJoinPopover, passwd_entry ); - - gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), SrainJoinPopover, search_entry); - gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), SrainJoinPopover, refresh_button); - gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), SrainJoinPopover, match_combo_box); - gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), SrainJoinPopover, min_users_spin_button); - gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), SrainJoinPopover, max_users_spin_button); - - gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), SrainJoinPopover, chan_tree_view); - gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), SrainJoinPopover, chan_tree_view_column); - gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), SrainJoinPopover, users_tree_view_column); - gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), SrainJoinPopover, topic_tree_view_column); - - gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), SrainJoinPopover, status_label); - gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), SrainJoinPopover, status_spinner); - - gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), SrainJoinPopover, cancel_button); - gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), SrainJoinPopover, join_button); -} - static void match_combo_box_set_model(SrainJoinPopover *popover){ GtkListStore *store; GtkComboBox *combobox; @@ -287,31 +260,34 @@ static void match_combo_box_set_model(SrainJoinPopover *popover){ gtk_combo_box_set_model(combobox, GTK_TREE_MODEL(store)); } -static void chan_tree_view_set_model(SrainJoinPopover *popover){ - GtkListStore *store; - GtkTreeModel *filter; - GtkTreeView *view; - - /* 3 columns: channel name, users, topic */ - popover->chan_list_store = gtk_list_store_new(3, - G_TYPE_STRING, - G_TYPE_INT, - G_TYPE_STRING); - store = popover->chan_list_store; - view = popover->chan_tree_view; - - popover->chan_tree_model_filter = gtk_tree_model_filter_new( - GTK_TREE_MODEL(store), NULL); - filter = popover->chan_tree_model_filter; +static void popover_on_visible(GObject *object, GParamSpec *pspec, gpointer data){ + SrainWindow *win; + SrainBuffer *buf; + SrainJoinPopover *popover; - gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(filter), - chan_tree_visible_func, popover, NULL); + win = srain_win; + popover = SRAIN_JOIN_POPOVER(object); + buf = srain_window_get_cur_buffer(win); - gtk_tree_view_set_model(view, filter); -} + if (!gtk_widget_is_visible(GTK_WIDGET(popover))){ + return; + } + if (!SRAIN_IS_BUFFER(buf)){ + return; + } + if (SRAIN_IS_CHAT_BUFFER(buf)){ + buf = SRAIN_BUFFER( + srain_chat_buffer_get_server_buffer( + SRAIN_CHAT_BUFFER(buf))); + } + if (!SRAIN_IS_SERVER_BUFFER(buf)){ + return; + } -static void popover_on_visible(GObject *object, GParamSpec *pspec, gpointer data){ - /* Nothing to do... */ + srain_join_popover_set_model(popover, SRAIN_SERVER_BUFFER(buf)); + update_status( + popover, + srain_server_buffer_is_adding_channel(SRAIN_SERVER_BUFFER(buf))); } static void join_button_on_click(gpointer user_data){ @@ -346,7 +322,7 @@ static void join_button_on_click(gpointer user_data){ if (gtk_tree_selection_get_selected(selection, &model, &iter)){ /* If row in chan_tree_view has selected, use it as channel name */ gtk_tree_model_get(model, &iter, - CHAN_LIST_STORE_COL_CHANNEL, &_chan, + CHANNEL_LIST_STORE_COL_CHANNEL, &_chan, -1); chan = _chan; } else { @@ -434,7 +410,7 @@ static void chan_tree_view_on_row_activate(GtkTreeView *view, } gtk_tree_model_get(model, &iter, - CHAN_LIST_STORE_COL_CHANNEL, &chan, + CHANNEL_LIST_STORE_COL_CHANNEL, &chan, -1); g_return_if_fail(chan); @@ -447,23 +423,23 @@ static void chan_tree_view_on_row_activate(GtkTreeView *view, } static void chan_tree_model_filter_refilter(gpointer user_data){ + char *status; + GtkTreeModel *model; + GtkTreeModelFilter *filter; SrainJoinPopover *popover; popover = user_data; + filter = GTK_TREE_MODEL_FILTER(gtk_tree_view_get_model(popover->chan_tree_view)); + model = gtk_tree_model_filter_get_model(filter); - gtk_tree_model_filter_refilter( - GTK_TREE_MODEL_FILTER(popover->chan_tree_model_filter)); + gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(filter)); /* Update status while all channels have loaded */ - if (!popover->adding) { - char *status = g_strdup_printf(_("Showing %d of %d channnels"), - gtk_tree_model_iter_n_children( - GTK_TREE_MODEL(popover->chan_tree_model_filter), NULL), - gtk_tree_model_iter_n_children( - GTK_TREE_MODEL(popover->chan_list_store), NULL)); - gtk_label_set_text(popover->status_label, status); - g_free(status); - } + status = g_strdup_printf(_("Showing %d of %d channnels"), + gtk_tree_model_iter_n_children(GTK_TREE_MODEL(filter), NULL), + gtk_tree_model_iter_n_children(model, NULL)); + gtk_label_set_text(popover->status_label, status); + g_free(status); } gboolean chan_tree_visible_func(GtkTreeModel *model, GtkTreeIter *iter, @@ -480,9 +456,9 @@ gboolean chan_tree_visible_func(GtkTreeModel *model, GtkTreeIter *iter, visable = FALSE; popover = user_data; gtk_tree_model_get(model, iter, - CHAN_LIST_STORE_COL_CHANNEL, &chan, - CHAN_LIST_STORE_COL_USERS, &users, - CHAN_LIST_STORE_COL_TOPIC, &topic, + CHANNEL_LIST_STORE_COL_CHANNEL, &chan, + CHANNEL_LIST_STORE_COL_USERS, &users, + CHANNEL_LIST_STORE_COL_TOPIC, &topic, -1); DBG_FR("cha: %s, users: %d, topic: %s", chan, users, topic); @@ -526,3 +502,41 @@ gboolean chan_tree_visible_func(GtkTreeModel *model, GtkTreeIter *iter, return visable; } + +static void on_adding_channel(GtkWidget *widget, GParamSpec *pspec, + gpointer user_data){ + SrainJoinPopover *popover; + SrainServerBuffer *buf; + + popover = user_data; + buf = SRAIN_SERVER_BUFFER(widget); + + // This buffer is not the one which showing on join popover + if (gtk_tree_view_get_model(popover->chan_tree_view) != + GTK_TREE_MODEL(srain_server_buffer_get_channel_model(buf))){ + return; + } + + update_status(popover, srain_server_buffer_is_adding_channel(buf)); +} + +static void update_status(SrainJoinPopover *popover, bool adding){ + if (adding) { + gtk_spinner_start(popover->status_spinner); + gtk_label_set_text(popover->status_label, _("Loading channels...")); + } else { + char *status; + GtkTreeModel *model; + GtkTreeModelFilter *filter; + + gtk_spinner_stop(popover->status_spinner); + + filter = GTK_TREE_MODEL_FILTER(gtk_tree_view_get_model(popover->chan_tree_view)); + model = gtk_tree_model_filter_get_model(filter); + status = g_strdup_printf(_("Showing %d of %d channnels"), + gtk_tree_model_iter_n_children(GTK_TREE_MODEL(filter), NULL), + gtk_tree_model_iter_n_children(model, NULL)); + gtk_label_set_text(popover->status_label, status); + g_free(status); + } +} diff --git a/src/sui/srain_join_popover.h b/src/sui/srain_join_popover.h index c0479892..b212acf6 100644 --- a/src/sui/srain_join_popover.h +++ b/src/sui/srain_join_popover.h @@ -20,6 +20,7 @@ #define __SRAIN_JOIN_POPOVER_H #include +#include "srain_server_buffer.h" #define SRAIN_TYPE_JOIN_POPOVER (srain_join_popover_get_type()) #define SRAIN_JOIN_POPOVER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SRAIN_TYPE_JOIN_POPOVER, SrainJoinPopover)) @@ -33,6 +34,10 @@ typedef struct _SrainJoinPopoverClass SrainJoinPopoverClass; GType srain_join_popover_get_type(void); SrainJoinPopover* srain_join_popover_new(GtkWidget *relative); + +void srain_join_popover_prepare_model(SrainJoinPopover *popover, SrainServerBuffer *buf); +void srain_join_popover_set_model(SrainJoinPopover *popover, SrainServerBuffer *buf); + void srain_join_popover_start_chan(SrainJoinPopover *dialog); void srain_join_popover_add_chan(SrainJoinPopover *dialog, const char *chan, int users, const char *topic); diff --git a/src/sui/srain_server_buffer.c b/src/sui/srain_server_buffer.c index b90174cb..6a8a2602 100644 --- a/src/sui/srain_server_buffer.c +++ b/src/sui/srain_server_buffer.c @@ -35,11 +35,14 @@ struct _SrainServerBuffer { SrainBuffer parent; + bool adding_chan; + GtkMenuItem *disconn_menu_item; GtkMenuItem *quit_menu_item; GSList *buffer_list; GtkListStore *chan_list_store; + GtkTreeModelFilter *chan_tree_model_filter; // FilterTreeModel of chan_list_store }; struct _SrainServerBufferClass { @@ -48,18 +51,68 @@ struct _SrainServerBufferClass { static void disconn_menu_item_on_activate(GtkWidget* widget, gpointer user_data); static void quit_menu_item_on_activate(GtkWidget* widget, gpointer user_data); +static void srain_server_buffer_set_adding_channel(SrainServerBuffer *self, bool adding_chan); +static bool srain_server_buffer_get_adding_channel(SrainServerBuffer *self); /***************************************************************************** * GObject functions *****************************************************************************/ +enum +{ + // 0 for PROP_NOME + PROP_ADDING_CHANNEL = 1, + N_PROPERTIES +}; + +static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, }; + G_DEFINE_TYPE(SrainServerBuffer, srain_server_buffer, SRAIN_TYPE_BUFFER); +static void srain_server_buffer_set_property(GObject *object, guint property_id, + const GValue *value, GParamSpec *pspec){ + SrainServerBuffer *self = SRAIN_SERVER_BUFFER(object); + + switch (property_id){ + case PROP_ADDING_CHANNEL: + srain_server_buffer_set_adding_channel(self, g_value_get_boolean(value)); + break; + default: + /* We don't have any other property... */ + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void srain_server_buffer_get_property(GObject *object, guint property_id, + GValue *value, GParamSpec *pspec){ + SrainServerBuffer *self = SRAIN_SERVER_BUFFER(object); + + switch (property_id){ + case PROP_ADDING_CHANNEL: + g_value_set_boolean(value, srain_server_buffer_get_adding_channel(self)); + break; + default: + /* We don't have any other property... */ + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + static void srain_server_buffer_init(SrainServerBuffer *self){ GtkBuilder *builder; + self->adding_chan = FALSE; self->buffer_list = NULL; + /* Init data model */ + self->chan_list_store = gtk_list_store_new(3, + G_TYPE_STRING, + G_TYPE_INT, + G_TYPE_STRING); + self->chan_tree_model_filter = GTK_TREE_MODEL_FILTER( + gtk_tree_model_filter_new(GTK_TREE_MODEL(self->chan_list_store), NULL)); + /* Init menus */ builder = gtk_builder_new_from_resource("/org/gtk/srain/buffer_menu.glade"); self->disconn_menu_item = @@ -84,6 +137,8 @@ static void srain_server_buffer_finalize(GObject *object){ SrainServerBuffer *self = SRAIN_SERVER_BUFFER(object); g_slist_free(self->buffer_list); + g_object_unref(self->chan_list_store); + // FIXME G_OBJECT_CLASS(srain_server_buffer_parent_class)->finalize(object); } @@ -92,6 +147,15 @@ static void srain_server_buffer_class_init(SrainServerBufferClass *class){ GObjectClass *object_class = G_OBJECT_CLASS(class); object_class->finalize = srain_server_buffer_finalize; + object_class->set_property = srain_server_buffer_set_property; + object_class->get_property = srain_server_buffer_get_property; + + obj_properties[PROP_ADDING_CHANNEL] = + g_param_spec_boolean("adding-channel", + "Adding channel", + "A flag represents that whether this buffer is adding channel.", + FALSE, + G_PARAM_READWRITE); } /***************************************************************************** @@ -145,6 +209,40 @@ GSList* srain_server_buffer_get_buffer_list(SrainServerBuffer *self){ return self->buffer_list; } +GtkTreeModelFilter* srain_server_buffer_get_channel_model( + SrainServerBuffer *self){ + return self->chan_tree_model_filter; +} + +void srain_server_buffer_start_add_channel(SrainServerBuffer *self){ + gtk_list_store_clear(self->chan_list_store); + srain_server_buffer_set_adding_channel(self, TRUE); +} + +void srain_server_buffer_add_channel(SrainServerBuffer *self, + const char *chan, int users, const char *topic){ + GtkTreeIter iter; + GtkListStore *store; + + g_return_if_fail(self->adding_chan); + + store = self->chan_list_store; + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, + CHANNEL_LIST_STORE_COL_CHANNEL, chan, + CHANNEL_LIST_STORE_COL_USERS, users, + CHANNEL_LIST_STORE_COL_TOPIC, topic, + -1); +} + +void srain_server_buffer_end_add_channel(SrainServerBuffer *self){ + srain_server_buffer_set_adding_channel(self, FALSE); +} + +bool srain_server_buffer_is_adding_channel(SrainServerBuffer *self){ + return srain_server_buffer_get_adding_channel(self); +} + /***************************************************************************** * Static functions *****************************************************************************/ @@ -167,3 +265,19 @@ static void quit_menu_item_on_activate(GtkWidget* widget, gpointer user_data){ sui_event_hdr(srain_buffer_get_session(SRAIN_BUFFER(self)), SUI_EVENT_DISCONNECT, NULL); } + +static void srain_server_buffer_set_adding_channel(SrainServerBuffer *self, + bool adding_chan){ + g_object_freeze_notify(G_OBJECT(self)); + + self->adding_chan = adding_chan; + + g_object_notify_by_pspec(G_OBJECT(self), + obj_properties[PROP_ADDING_CHANNEL]); + + g_object_thaw_notify(G_OBJECT(self)); +} + +static bool srain_server_buffer_get_adding_channel(SrainServerBuffer *self){ + return self->adding_chan; +} diff --git a/src/sui/srain_server_buffer.h b/src/sui/srain_server_buffer.h index bf1209a1..5f3ed3cf 100644 --- a/src/sui/srain_server_buffer.h +++ b/src/sui/srain_server_buffer.h @@ -22,6 +22,10 @@ #include #include "sui/sui.h" +#define CHANNEL_LIST_STORE_COL_CHANNEL 0 +#define CHANNEL_LIST_STORE_COL_USERS 1 +#define CHANNEL_LIST_STORE_COL_TOPIC 2 + #define SRAIN_TYPE_SERVER_BUFFER (srain_server_buffer_get_type()) #define SRAIN_SERVER_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SRAIN_TYPE_SERVER_BUFFER, SrainServerBuffer)) #define SRAIN_IS_SERVER_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SRAIN_TYPE_SERVER_BUFFER)) @@ -35,5 +39,11 @@ SrainServerBuffer* srain_server_buffer_new(SuiSession *sui, const char *server); void srain_server_buffer_add_buffer(SrainServerBuffer *self, SrainBuffer *buffer); void srain_server_buffer_rm_buffer(SrainServerBuffer *self, SrainBuffer *buffer); GSList* srain_server_buffer_get_buffer_list(SrainServerBuffer *self); +GtkTreeModelFilter* srain_server_buffer_get_channel_model(SrainServerBuffer *self); + +bool srain_server_buffer_is_adding_channel(SrainServerBuffer *self); +void srain_server_buffer_start_add_channel(SrainServerBuffer *self); +void srain_server_buffer_add_channel(SrainServerBuffer *self, const char *chan, int users, const char *topic); +void srain_server_buffer_end_add_channel(SrainServerBuffer *self); #endif /* __SRAIN_SERVER_BUFFER_H */ diff --git a/src/sui/sui.c b/src/sui/sui.c index 5c70b9d6..6a2e4699 100644 --- a/src/sui/sui.c +++ b/src/sui/sui.c @@ -127,6 +127,7 @@ void sui_free_session(SuiSession *sui){ SrnRet sui_server_session(SuiSession *sui, const char *srv){ SrainServerBuffer *buffer; + SrainJoinPopover *popover; g_return_val_if_fail(sui, SRN_ERR); g_return_val_if_fail(srv, SRN_ERR); @@ -135,11 +136,14 @@ SrnRet sui_server_session(SuiSession *sui, const char *srv){ if (!buffer) { return RET_ERR(_("Failed to create server buffer")); } - sui->buffer = SRAIN_BUFFER(buffer); + srain_window_add_buffer(srain_win, sui->buffer); srain_buffer_show_topic(sui->buffer, sui->prefs->show_topic); + popover = srain_window_get_join_popover(srain_win); + srain_join_popover_prepare_model(popover, buffer); + return SRN_OK; } @@ -599,34 +603,29 @@ void sui_message_box(const char *title, const char *msg){ } void sui_chan_list_start(SuiSession *sui){ - SrainJoinPopover *popover; - g_return_if_fail(sui); + g_return_if_fail(SRAIN_IS_SERVER_BUFFER(sui->buffer)); - popover = srain_window_get_join_popover(srain_win); - srain_join_popover_start_chan(popover); + srain_server_buffer_start_add_channel(SRAIN_SERVER_BUFFER(sui->buffer)); } void sui_chan_list_add(SuiSession *sui, const char *chan, int users, const char *topic){ - SrainJoinPopover *popover; - g_return_if_fail(sui); + g_return_if_fail(SRAIN_IS_SERVER_BUFFER(sui->buffer)); g_return_if_fail(chan); g_return_if_fail(topic); - popover = srain_window_get_join_popover(srain_win); - srain_join_popover_add_chan(popover, chan, users, topic); + srain_server_buffer_add_channel(SRAIN_SERVER_BUFFER(sui->buffer), + chan, users, topic); sui_proc_pending_event(); } void sui_chan_list_end(SuiSession *sui){ - SrainJoinPopover *popover; - g_return_if_fail(sui); + g_return_if_fail(SRAIN_IS_SERVER_BUFFER(sui->buffer)); - popover = srain_window_get_join_popover(srain_win); - srain_join_popover_end_chan(popover); + srain_server_buffer_end_add_channel(SRAIN_SERVER_BUFFER(sui->buffer)); } void sui_server_list_add(const char *server){