1 /* Copyright (C) 2016-2017 Shengyu Zhang <i@silverrainz.me>
2  *
3  * This file is part of Srain.
4  *
5  * Srain is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 /**
20  * @file sui_server_buffer.c
21  * @brief
22  * @author Shengyu Zhang <i@silverrainz.me>
23  * @version 0.06.2
24  * @date 2017-11-26
25  */
26 
27 #include <gtk/gtk.h>
28 
29 #include "sui_event_hdr.h"
30 #include "sui_buffer.h"
31 #include "sui_server_buffer.h"
32 
33 #include "log.h"
34 #include "i18n.h"
35 
36 struct _SuiServerBuffer {
37     SuiBuffer parent;
38 
39     GList *buffer_list;
40 
41     GtkMenuItem *disconn_menu_item;
42     GtkMenuItem *quit_menu_item;
43     GtkMenuItem *reconn_menu_item;
44 
45     GtkListStore *chan_list_store;
46     SuiJoinPanel *join_panel;
47 };
48 
49 struct _SuiServerBufferClass {
50     SuiBufferClass parent_class;
51 };
52 
53 static void disconn_menu_item_on_activate(GtkWidget* widget, gpointer user_data);
54 static void quit_menu_item_on_activate(GtkWidget* widget, gpointer user_data);
55 static void reconn_menu_item_on_activate(GtkWidget* widget, gpointer user_data);
56 
57 /*****************************************************************************
58  * GObject functions
59  *****************************************************************************/
60 
61 enum {
62     // 0 for PROP_NOME
63     N_PROPERTIES = 1
64 };
65 
66 // static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
67 
68 G_DEFINE_TYPE(SuiServerBuffer, sui_server_buffer, SUI_TYPE_BUFFER);
69 
sui_server_buffer_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)70 static void sui_server_buffer_set_property(GObject *object, guint property_id,
71         const GValue *value, GParamSpec *pspec){
72   switch (property_id){
73     default:
74       /* We don't have any other property... */
75       G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
76       break;
77     }
78 }
79 
sui_server_buffer_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)80 static void sui_server_buffer_get_property(GObject *object, guint property_id,
81         GValue *value, GParamSpec *pspec){
82   switch (property_id){
83     default:
84       /* We don't have any other property... */
85       G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
86       break;
87     }
88 }
89 
sui_server_buffer_init(SuiServerBuffer * self)90 static void sui_server_buffer_init(SuiServerBuffer *self){
91     GtkBuilder *builder;
92 
93     /* Init menus */
94     builder = gtk_builder_new_from_resource("/im/srain/Srain/buffer_menu.glade");
95     self->disconn_menu_item =
96         (GtkMenuItem *)gtk_builder_get_object(builder, "disconn_menu_item");
97     gtk_menu_shell_append(
98             GTK_MENU_SHELL(sui_buffer_get_menu(SUI_BUFFER(self))),
99             GTK_WIDGET(self->disconn_menu_item));
100     self->quit_menu_item =
101         (GtkMenuItem *)gtk_builder_get_object(builder, "quit_menu_item");
102     gtk_menu_shell_append(
103             GTK_MENU_SHELL(sui_buffer_get_menu(SUI_BUFFER(self))),
104             GTK_WIDGET(self->quit_menu_item));
105     self->reconn_menu_item =
106         (GtkMenuItem *)gtk_builder_get_object(builder, "reconn_menu_item");
107     gtk_menu_shell_append(
108             GTK_MENU_SHELL(sui_buffer_get_menu(SUI_BUFFER(self))),
109             GTK_WIDGET(self->reconn_menu_item));
110     g_object_unref(builder);
111 
112     self->buffer_list = NULL;
113 
114     /* Init channel list */
115     self->chan_list_store = gtk_list_store_new(3,
116             G_TYPE_STRING,
117             G_TYPE_INT,
118             G_TYPE_STRING);
119     self->join_panel = g_object_ref(sui_join_panel_new());
120     sui_join_panel_set_model(self->join_panel,
121             GTK_TREE_MODEL(self->chan_list_store));
122 
123     g_signal_connect(self->disconn_menu_item, "activate",
124             G_CALLBACK(disconn_menu_item_on_activate),self);
125     g_signal_connect(self->quit_menu_item, "activate",
126             G_CALLBACK(quit_menu_item_on_activate),self);
127     g_signal_connect(self->reconn_menu_item, "activate",
128             G_CALLBACK(reconn_menu_item_on_activate),self);
129 }
130 
sui_server_buffer_finalize(GObject * object)131 static void sui_server_buffer_finalize(GObject *object){
132     SuiServerBuffer *self = SUI_SERVER_BUFFER(object);
133 
134     g_warn_if_fail(g_list_length(self->buffer_list) == 0);
135 
136     g_object_unref(self->chan_list_store);
137     g_object_unref(self->join_panel);
138 
139     G_OBJECT_CLASS(sui_server_buffer_parent_class)->finalize(object);
140 }
141 
sui_server_buffer_class_init(SuiServerBufferClass * class)142 static void sui_server_buffer_class_init(SuiServerBufferClass *class){
143     GObjectClass *object_class;
144 
145     object_class = G_OBJECT_CLASS(class);
146 
147     object_class->finalize = sui_server_buffer_finalize;
148     object_class->set_property = sui_server_buffer_set_property;
149     object_class->get_property = sui_server_buffer_get_property;
150 }
151 
152 /*****************************************************************************
153  * Exported functions
154  *****************************************************************************/
155 
sui_server_buffer_new(void * ctx,SuiBufferEvents * events,SuiBufferConfig * cfg)156 SuiServerBuffer* sui_server_buffer_new(void *ctx, SuiBufferEvents *events,
157         SuiBufferConfig *cfg){
158     SuiServerBuffer *self;
159 
160     self = g_object_new(SUI_TYPE_SERVER_BUFFER,
161             "context", ctx,
162             "events", events,
163             "config", cfg,
164             NULL);
165 
166     return self;
167 }
168 
sui_server_buffer_add_buffer(SuiServerBuffer * self,SuiBuffer * buf)169 void sui_server_buffer_add_buffer(SuiServerBuffer *self, SuiBuffer *buf){
170     GList *lst;
171 
172     g_return_if_fail(!SUI_IS_SERVER_BUFFER(buf));
173 
174     lst = self->buffer_list;
175     while (lst){
176         g_return_if_fail(lst->data != buf);
177         lst = g_list_next(lst);
178     }
179 
180     self->buffer_list = g_list_append(self->buffer_list, buf);
181 }
182 
sui_server_buffer_rm_buffer(SuiServerBuffer * self,SuiBuffer * buf)183 void sui_server_buffer_rm_buffer(SuiServerBuffer *self, SuiBuffer *buf){
184     GList *lst;
185 
186     g_return_if_fail(!SUI_IS_SERVER_BUFFER(buf));
187 
188     lst = self->buffer_list;
189     while (lst){
190         if (lst->data == buf){
191             self->buffer_list = g_list_delete_link(self->buffer_list, lst);
192             return;
193         }
194         lst = g_list_next(lst);
195     }
196 
197     g_return_if_reached();
198 }
199 
sui_server_buffer_get_buffer_list(SuiServerBuffer * self)200 GList* sui_server_buffer_get_buffer_list(SuiServerBuffer *self){
201     return self->buffer_list;
202 }
203 
sui_server_buffer_get_join_panel(SuiServerBuffer * self)204 SuiJoinPanel* sui_server_buffer_get_join_panel(SuiServerBuffer *self){
205     return self->join_panel;
206 }
207 
sui_server_buffer_add_channel(SuiServerBuffer * self,const char * chan,int users,const char * topic)208 void sui_server_buffer_add_channel(SuiServerBuffer *self,
209         const char *chan, int users, const char *topic){
210     GtkTreeIter iter;
211     GtkListStore *store;
212 
213     store = self->chan_list_store;
214     gtk_list_store_append(store, &iter);
215     gtk_list_store_set(store, &iter,
216             CHANNEL_LIST_STORE_COL_CHANNEL, chan,
217             CHANNEL_LIST_STORE_COL_USERS, users,
218             CHANNEL_LIST_STORE_COL_TOPIC, topic,
219             -1);
220 }
221 
sui_server_buffer_clear_channel(SuiServerBuffer * self)222 void sui_server_buffer_clear_channel(SuiServerBuffer *self){
223     gtk_list_store_clear(self->chan_list_store);
224 }
225 
226 /*****************************************************************************
227  * Static functions
228  *****************************************************************************/
229 
disconn_menu_item_on_activate(GtkWidget * widget,gpointer user_data)230 static void disconn_menu_item_on_activate(GtkWidget* widget, gpointer user_data){
231     SuiServerBuffer *self;
232 
233     self = user_data;
234 
235     sui_buffer_event_hdr(SUI_BUFFER(self), SUI_EVENT_DISCONNECT, NULL);
236 }
237 
quit_menu_item_on_activate(GtkWidget * widget,gpointer user_data)238 static void quit_menu_item_on_activate(GtkWidget* widget, gpointer user_data){
239     SuiServerBuffer *self;
240 
241     self = user_data;
242 
243     sui_buffer_event_hdr(SUI_BUFFER(self), SUI_EVENT_QUIT, NULL);
244 }
245 
reconn_menu_item_on_activate(GtkWidget * widget,gpointer user_data)246 static void reconn_menu_item_on_activate(GtkWidget *widget, gpointer user_data){
247     SuiServerBuffer *self;
248     self = user_data;
249     sui_buffer_event_hdr(SUI_BUFFER(self), SUI_EVENT_RECONNECT, NULL);
250 }
251