diff --git a/src/sui/nick_menu.c b/src/sui/nick_menu.c index cfe7c0b9..87254cbf 100644 --- a/src/sui/nick_menu.c +++ b/src/sui/nick_menu.c @@ -23,6 +23,9 @@ #include "srain_app.h" #include "srain_window.h" #include "srain_buffer.h" +#include "srain_server_buffer.h" +#include "srain_chat_buffer.h" +#include "srain_channel_buffer.h" #include "log.h" @@ -60,15 +63,16 @@ static void nick_menu_item_on_activate(GtkWidget* widget, gpointer user_data){ } void nick_menu_popup(GdkEventButton *event, const char *nick){ - GList *buffers; + int n; + GSList *lst; GtkBuilder *builder; GtkMenu *nick_menu; - GtkMenuItem *item; GtkMenuItem *whois_menu_item; GtkMenuItem *ignore_menu_item; GtkMenuItem *kick_menu_item; GtkMenuItem *buffer_menu_item; GtkMenuItem *invite_menu_item; + GtkMenu *invite_submenu; SrainBuffer *buffer; builder = gtk_builder_new_from_resource ("/org/gtk/srain/nick_menu.glade"); @@ -89,33 +93,46 @@ void nick_menu_popup(GdkEventButton *event, const char *nick){ g_signal_connect(buffer_menu_item, "activate", G_CALLBACK(nick_menu_item_on_activate), (char *)nick); - /******************************************/ - buffer = srain_window_get_cur_buffer(srain_win); - buffers = srain_window_get_buffers_by_remark(srain_win, - srain_buffer_get_remark(buffer)); - - /* Skip META_SERVER */ - buffers = g_list_next(buffers); - /* Create subitem of invite_menu_item */ - GtkMenu *invite_submenu = GTK_MENU(gtk_menu_new()); - gtk_menu_item_set_submenu(invite_menu_item, GTK_WIDGET(invite_submenu)); + buffer = srain_window_get_cur_buffer(srain_win); + if (SRAIN_IS_CHAT_BUFFER(buffer)){ + buffer = SRAIN_BUFFER(srain_chat_buffer_get_server_buffer( + SRAIN_CHAT_BUFFER(buffer))); + } + if (!SRAIN_IS_SERVER_BUFFER(buffer)){ + goto FIN; + } - while (buffers){ - item = GTK_MENU_ITEM(gtk_menu_item_new_with_label( - srain_buffer_get_name(buffers->data))); + n = 0; + invite_submenu = GTK_MENU(gtk_menu_new()); + lst = srain_server_buffer_get_buffer_list(SRAIN_SERVER_BUFFER(buffer)); + while (lst){ + GtkMenuItem *item; + + if (!SRAIN_IS_CHANNEL_BUFFER(lst->data)){ + lst = g_slist_next(lst); + continue; + } + item = GTK_MENU_ITEM(gtk_menu_item_new_with_label( + srain_buffer_get_name(lst->data))); gtk_widget_show(GTK_WIDGET(item)); gtk_widget_set_name(GTK_WIDGET(item), "invite_submenu_item"); g_signal_connect(item, "activate", G_CALLBACK(nick_menu_item_on_activate), (char *)nick); gtk_menu_shell_append(GTK_MENU_SHELL(invite_submenu), GTK_WIDGET(item)); - buffers = g_list_next(buffers); + n++; + lst = g_slist_next(lst); } - g_list_free(buffers); + if (n > 0) { + gtk_menu_item_set_submenu(invite_menu_item, GTK_WIDGET(invite_submenu)); + } else { + g_object_ref_sink(invite_submenu); // remove the floating reference + g_object_unref(invite_submenu); + } +FIN: gtk_menu_popup(nick_menu, NULL, NULL, NULL, NULL, event->button, event->time); - g_object_unref(builder); } diff --git a/src/sui/srain_msg.c b/src/sui/srain_msg.c index 300040bf..915a4045 100644 --- a/src/sui/srain_msg.c +++ b/src/sui/srain_msg.c @@ -34,6 +34,8 @@ #include "nick_menu.h" #include "srain_window.h" #include "srain_buffer.h" +#include "srain_chat_buffer.h" +#include "srain_server_buffer.h" #include "srain_msg.h" #include "plugin.h" @@ -137,9 +139,13 @@ static void froward_submenu_item_on_activate(GtkWidget* widget, gpointer user_da static void msg_label_on_popup(GtkLabel *label, GtkMenu *menu, gpointer user_data){ + int n; + GSList *lst; GtkMenuItem *copy_menu_item; GtkMenuItem *forward_menu_item; + GtkMenu *forward_submenu; SrainRecvMsg *smsg; + SrainBuffer *buffer; smsg = SRAIN_RECV_MSG(user_data); @@ -156,33 +162,36 @@ static void msg_label_on_popup(GtkLabel *label, GtkMenu *menu, gtk_menu_shell_append(GTK_MENU_SHELL(menu), GTK_WIDGET(forward_menu_item)); /* Create submenu of forward_menu_item */ - GList *buffers; - GtkMenuItem *item; - GtkMenu *forward_submenu = GTK_MENU(gtk_menu_new()); - SrainBuffer *buffer; - buffer = srain_window_get_cur_buffer(srain_win); + if (SRAIN_IS_CHAT_BUFFER(buffer)){ + buffer = SRAIN_BUFFER(srain_chat_buffer_get_server_buffer( + SRAIN_CHAT_BUFFER(buffer))); + } + g_return_if_fail(SRAIN_IS_SERVER_BUFFER(buffer)); - buffers = srain_window_get_buffers_by_remark(srain_win, - srain_buffer_get_remark(buffer)); - if (!buffers) return; - /* Skip META_SERVER */ - buffers = g_list_next(buffers); - - gtk_menu_item_set_submenu(forward_menu_item, GTK_WIDGET(forward_submenu)); + n = 0; + forward_submenu = GTK_MENU(gtk_menu_new()); + lst = srain_server_buffer_get_buffer_list(SRAIN_SERVER_BUFFER(buffer)); + while (lst){ + GtkMenuItem *item; - while (buffers){ item = GTK_MENU_ITEM(gtk_menu_item_new_with_label( - srain_buffer_get_name(buffers->data))); + srain_buffer_get_name(SRAIN_BUFFER(lst->data)))); gtk_widget_show(GTK_WIDGET(item)); g_signal_connect(item, "activate", G_CALLBACK(froward_submenu_item_on_activate), smsg); gtk_menu_shell_append(GTK_MENU_SHELL(forward_submenu), GTK_WIDGET(item)); - buffers = g_list_next(buffers); + n++; + lst = g_slist_next(lst); } - g_list_free(buffers); + if (n > 0) { + gtk_menu_item_set_submenu(forward_menu_item, GTK_WIDGET(forward_submenu)); + } else { + g_object_ref_sink(forward_submenu); // remove the floating reference + g_object_unref(forward_submenu); + } } static gboolean nick_button_on_popup(GtkWidget *widget, diff --git a/src/sui/srain_server_buffer.c b/src/sui/srain_server_buffer.c index 44c13c7c..b90174cb 100644 --- a/src/sui/srain_server_buffer.c +++ b/src/sui/srain_server_buffer.c @@ -117,7 +117,7 @@ void srain_server_buffer_add_buffer(SrainServerBuffer *self, SrainBuffer *buffer lst = self->buffer_list; while (lst){ - g_return_if_fail(lst->data == buffer); + g_return_if_fail(lst->data != buffer); lst = g_slist_next(lst); } diff --git a/src/sui/srain_server_buffer.h b/src/sui/srain_server_buffer.h index 57c9c98c..bf1209a1 100644 --- a/src/sui/srain_server_buffer.h +++ b/src/sui/srain_server_buffer.h @@ -32,4 +32,8 @@ typedef struct _SrainServerBufferClass SrainServerBufferClass; GType srain_server_buffer_get_type(void); 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); + #endif /* __SRAIN_SERVER_BUFFER_H */ diff --git a/src/sui/srain_window.c b/src/sui/srain_window.c index 6d990ef5..a21934f3 100644 --- a/src/sui/srain_window.c +++ b/src/sui/srain_window.c @@ -264,32 +264,6 @@ SrainBuffer* srain_window_get_buffer(SrainWindow *win, return buffer; } -/** - * @brief Find out all SrainBuffers with the server_name given as argument - * - * @param win - * @param server_name - * - * @return a GList, may be NULL, should be freed by caller - */ -GList* srain_window_get_buffers_by_remark(SrainWindow *win, const char *remark){ - GList *all_buffers; - GList *buffers = NULL; - SrainBuffer *buffer = NULL; - - all_buffers = gtk_container_get_children(GTK_CONTAINER(win->stack)); - while (all_buffers){ - buffer = SRAIN_BUFFER(all_buffers->data); - - if (strcmp(remark, srain_buffer_get_remark(buffer)) == 0){ - buffers = g_list_append(buffers, buffer); - } - all_buffers = g_list_next(all_buffers); - } - - return buffers; -} - void srain_window_spinner_toggle(SrainWindow *win, gboolean is_busy){ is_busy ? gtk_spinner_start(win->spinner) diff --git a/src/sui/srain_window.h b/src/sui/srain_window.h index 8b74ea8c..cc97bd82 100644 --- a/src/sui/srain_window.h +++ b/src/sui/srain_window.h @@ -39,7 +39,6 @@ void srain_window_add_buffer(SrainWindow *win, SrainBuffer *buffer); void srain_window_rm_buffer(SrainWindow *win, SrainBuffer *buffer); SrainBuffer *srain_window_get_cur_buffer(SrainWindow *win); SrainBuffer *srain_window_get_buffer(SrainWindow *win, const char *name, const char *remark); -GList* srain_window_get_buffers_by_remark(SrainWindow *win, const char *remark); void srain_window_spinner_toggle(SrainWindow *win, gboolean is_busy); void srain_window_stack_sidebar_update(SrainWindow *win, SrainBuffer *buffer, const char *nick, const char *msg); diff --git a/src/sui/sui.c b/src/sui/sui.c index 6790c6a8..5c70b9d6 100644 --- a/src/sui/sui.c +++ b/src/sui/sui.c @@ -32,6 +32,7 @@ #include "srain_app.h" #include "srain_window.h" #include "srain_buffer.h" +#include "srain_server_buffer.h" #include "srain_chat_buffer.h" #include "srain_channel_buffer.h" #include "srain_private_buffer.h" @@ -119,7 +120,7 @@ void sui_free_session(SuiSession *sui){ g_return_if_fail(sui); if (sui->buffer){ - srain_window_rm_buffer(srain_win, sui->buffer); + sui_end_session(sui); } g_free(sui); } @@ -142,22 +143,24 @@ SrnRet sui_server_session(SuiSession *sui, const char *srv){ return SRN_OK; } -SrnRet sui_channel_session(SuiSession *sui, SuiSession *sui_srv, const char *chan){ +SrnRet sui_channel_session(SuiSession *sui, SuiSession *srv_sui, const char *chan){ SrainChannelBuffer *buffer; g_return_val_if_fail(sui, SRN_ERR); - g_return_val_if_fail(sui_srv, SRN_ERR); - g_return_val_if_fail(SRAIN_IS_SERVER_BUFFER(sui_srv->buffer), SRN_ERR); + g_return_val_if_fail(srv_sui, SRN_ERR); + g_return_val_if_fail(SRAIN_IS_SERVER_BUFFER(srv_sui->buffer), SRN_ERR); g_return_val_if_fail(chan, SRN_ERR); buffer = srain_channel_buffer_new( - sui, SRAIN_SERVER_BUFFER(sui_srv->buffer), chan); + sui, SRAIN_SERVER_BUFFER(srv_sui->buffer), chan); if (!buffer) { return RET_ERR(_("Failed to create channel buffer")); } sui->buffer = SRAIN_BUFFER(buffer); srain_window_add_buffer(srain_win, SRAIN_BUFFER(sui->buffer)); + srain_server_buffer_add_buffer( + SRAIN_SERVER_BUFFER(srv_sui->buffer), SRAIN_BUFFER(buffer)); srain_buffer_show_topic(SRAIN_BUFFER(sui->buffer), sui->prefs->show_topic); srain_chat_buffer_show_user_list( SRAIN_CHAT_BUFFER(sui->buffer), sui->prefs->show_user_list); @@ -165,22 +168,24 @@ SrnRet sui_channel_session(SuiSession *sui, SuiSession *sui_srv, const char *cha return SRN_OK; } -SrnRet sui_private_session(SuiSession *sui, SuiSession *sui_srv, const char *nick){ +SrnRet sui_private_session(SuiSession *sui, SuiSession *srv_sui, const char *nick){ SrainPrivateBuffer *buffer; g_return_val_if_fail(sui, SRN_ERR); - g_return_val_if_fail(sui_srv, SRN_ERR); - g_return_val_if_fail(SRAIN_IS_SERVER_BUFFER(sui_srv->buffer), SRN_ERR); + g_return_val_if_fail(srv_sui, SRN_ERR); + g_return_val_if_fail(SRAIN_IS_SERVER_BUFFER(srv_sui->buffer), SRN_ERR); g_return_val_if_fail(nick, SRN_ERR); buffer = srain_private_buffer_new( - sui, SRAIN_SERVER_BUFFER(sui_srv->buffer), nick); + sui, SRAIN_SERVER_BUFFER(srv_sui->buffer), nick); if (!buffer) { return RET_ERR(_("Failed to create private buffer")); } sui->buffer = SRAIN_BUFFER(buffer); srain_window_add_buffer(srain_win, SRAIN_BUFFER(sui->buffer)); + srain_server_buffer_add_buffer( + SRAIN_SERVER_BUFFER(srv_sui->buffer), SRAIN_BUFFER(buffer)); srain_buffer_show_topic(SRAIN_BUFFER(sui->buffer), sui->prefs->show_topic); srain_chat_buffer_show_user_list( SRAIN_CHAT_BUFFER(sui->buffer), sui->prefs->show_user_list); @@ -190,8 +195,19 @@ SrnRet sui_private_session(SuiSession *sui, SuiSession *sui_srv, const char *nic void sui_end_session(SuiSession *sui){ g_return_if_fail(sui); + g_return_if_fail(SRAIN_IS_BUFFER(sui->buffer)); + + if (SRAIN_IS_CHAT_BUFFER(sui->buffer)) { + SrainChatBuffer *chat_buf; + SrainServerBuffer *srv_buf; + + chat_buf = SRAIN_CHAT_BUFFER(sui->buffer); + srv_buf = SRAIN_SERVER_BUFFER(srain_chat_buffer_get_server_buffer(chat_buf)); + srain_server_buffer_rm_buffer(srv_buf, SRAIN_BUFFER(chat_buf)); + } srain_window_rm_buffer(srain_win, sui->buffer); + // FIXME: unref? sui->buffer = NULL; }