| |
1 /* |
| |
2 * Pidgin - Internet Messenger |
| |
3 * Copyright (C) Pidgin Developers <devel@pidgin.im> |
| |
4 * |
| |
5 * Pidgin is the legal property of its developers, whose names are too numerous |
| |
6 * to list here. Please refer to the COPYRIGHT file distributed with this |
| |
7 * source distribution. |
| |
8 * |
| |
9 * This program is free software; you can redistribute it and/or modify |
| |
10 * it under the terms of the GNU General Public License as published by |
| |
11 * the Free Software Foundation; either version 2 of the License, or |
| |
12 * (at your option) any later version. |
| |
13 * |
| |
14 * This program is distributed in the hope that it will be useful, |
| |
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| |
17 * GNU General Public License for more details. |
| |
18 * |
| |
19 * You should have received a copy of the GNU General Public License |
| |
20 * along with this program; if not, see <https://www.gnu.org/licenses/>. |
| |
21 */ |
| |
22 #include <glib/gi18n-lib.h> |
| |
23 |
| |
24 #include <gtk/gtk.h> |
| |
25 |
| |
26 #include "pidginstatusdisplay.h" |
| |
27 #include "pidginiconname.h" |
| |
28 |
| |
29 struct _PidginStatusDisplay { |
| |
30 GtkBox parent; |
| |
31 |
| |
32 GtkImage *image; |
| |
33 GtkLabel *label; |
| |
34 |
| |
35 PurpleStatusPrimitive primitive; |
| |
36 PurpleSavedStatus *status; |
| |
37 }; |
| |
38 |
| |
39 enum { |
| |
40 PROP_0, |
| |
41 PROP_PRIMITIVE, |
| |
42 PROP_SAVED_STATUS, |
| |
43 PROP_LAST |
| |
44 }; |
| |
45 |
| |
46 static GParamSpec *properties[PROP_LAST] = {NULL}; |
| |
47 |
| |
48 /****************************************************************************** |
| |
49 * Callbacks |
| |
50 *****************************************************************************/ |
| |
51 static void |
| |
52 pidgin_status_display_refresh(PidginStatusDisplay *display) { |
| |
53 const char *icon_name = NULL; |
| |
54 char *label = NULL; |
| |
55 |
| |
56 if(display->status != NULL) { |
| |
57 PurpleSavedStatus *status = display->status; |
| |
58 PurpleStatusPrimitive primitive; |
| |
59 GString *text = NULL; |
| |
60 |
| |
61 primitive = purple_savedstatus_get_primitive_type(status); |
| |
62 icon_name = pidgin_icon_name_from_status_primitive(primitive, NULL); |
| |
63 |
| |
64 text = g_string_new(purple_savedstatus_get_title(status)); |
| |
65 |
| |
66 /* Transient statuses do not have a title, so the savedstatus API |
| |
67 * returns the message when purple_savedstatus_get_title() is called, |
| |
68 * so we don't need to get the message a second time. |
| |
69 */ |
| |
70 if(!purple_savedstatus_is_transient(status)) { |
| |
71 const char *message = NULL; |
| |
72 |
| |
73 message = purple_savedstatus_get_message(status); |
| |
74 if(message != NULL) { |
| |
75 char *stripped = purple_markup_strip_html(message); |
| |
76 |
| |
77 purple_util_chrreplace(stripped, '\n', ' '); |
| |
78 g_string_append_printf(text, " - %s", stripped); |
| |
79 g_free(stripped); |
| |
80 } |
| |
81 } |
| |
82 |
| |
83 label = g_string_free(text, FALSE); |
| |
84 |
| |
85 } else if(display->primitive != PURPLE_STATUS_UNSET) { |
| |
86 icon_name = pidgin_icon_name_from_status_primitive(display->primitive, |
| |
87 NULL); |
| |
88 label = g_strdup(purple_primitive_get_name_from_type(display->primitive)); |
| |
89 } |
| |
90 |
| |
91 gtk_image_set_from_icon_name(display->image, icon_name); |
| |
92 gtk_label_set_text(display->label, label); |
| |
93 |
| |
94 g_free(label); |
| |
95 } |
| |
96 |
| |
97 /****************************************************************************** |
| |
98 * GObject implementation |
| |
99 *****************************************************************************/ |
| |
100 G_DEFINE_TYPE(PidginStatusDisplay, pidgin_status_display, GTK_TYPE_BOX) |
| |
101 |
| |
102 static void |
| |
103 pidgin_status_display_get_property(GObject *object, guint prop_id, |
| |
104 GValue *value, GParamSpec *pspec) |
| |
105 { |
| |
106 PidginStatusDisplay *display = PIDGIN_STATUS_DISPLAY(object); |
| |
107 |
| |
108 switch (prop_id) { |
| |
109 case PROP_PRIMITIVE: |
| |
110 g_value_set_enum(value, |
| |
111 pidgin_status_display_get_primitive(display)); |
| |
112 break; |
| |
113 case PROP_SAVED_STATUS: |
| |
114 g_value_set_pointer(value, |
| |
115 pidgin_status_display_get_saved_status(display)); |
| |
116 break; |
| |
117 default: |
| |
118 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); |
| |
119 break; |
| |
120 } |
| |
121 } |
| |
122 |
| |
123 static void |
| |
124 pidgin_status_display_set_property(GObject *object, guint prop_id, |
| |
125 const GValue *value, GParamSpec *pspec) |
| |
126 { |
| |
127 PidginStatusDisplay *display = PIDGIN_STATUS_DISPLAY(object); |
| |
128 |
| |
129 switch (prop_id) { |
| |
130 case PROP_PRIMITIVE: |
| |
131 pidgin_status_display_set_primitive(display, |
| |
132 g_value_get_enum(value)); |
| |
133 break; |
| |
134 case PROP_SAVED_STATUS: |
| |
135 pidgin_status_display_set_saved_status(display, |
| |
136 g_value_get_pointer(value)); |
| |
137 break; |
| |
138 default: |
| |
139 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); |
| |
140 break; |
| |
141 } |
| |
142 } |
| |
143 |
| |
144 static void |
| |
145 pidgin_status_display_class_init(PidginStatusDisplayClass *klass) { |
| |
146 GObjectClass *obj_class = G_OBJECT_CLASS(klass); |
| |
147 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); |
| |
148 |
| |
149 /* Properties */ |
| |
150 obj_class->get_property = pidgin_status_display_get_property; |
| |
151 obj_class->set_property = pidgin_status_display_set_property; |
| |
152 |
| |
153 /** |
| |
154 * PidginStatusDisplay:primitive: |
| |
155 * |
| |
156 * The status primitive that is currently displayed. |
| |
157 * |
| |
158 * Since: 3.0.0 |
| |
159 */ |
| |
160 properties[PROP_PRIMITIVE] = g_param_spec_enum( |
| |
161 "primitive", "primitive", |
| |
162 "The status primitive that is currently displayed.", |
| |
163 PURPLE_TYPE_STATUS_PRIMITIVE, PURPLE_STATUS_UNSET, |
| |
164 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); |
| |
165 |
| |
166 /** |
| |
167 * PidginStatusDisplay:saved-status: |
| |
168 * |
| |
169 * The saved status that is currently displayed. |
| |
170 * |
| |
171 * Since: 3.0.0 |
| |
172 */ |
| |
173 properties[PROP_SAVED_STATUS] = g_param_spec_pointer( |
| |
174 "saved-status", "saved-status", |
| |
175 "The saved status that is currently displayed.", |
| |
176 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); |
| |
177 |
| |
178 g_object_class_install_properties(obj_class, PROP_LAST, properties); |
| |
179 |
| |
180 /* Widget template */ |
| |
181 gtk_widget_class_set_template_from_resource( |
| |
182 widget_class, "/im/pidgin/Pidgin3/Status/display.ui"); |
| |
183 |
| |
184 gtk_widget_class_bind_template_child(widget_class, PidginStatusDisplay, |
| |
185 image); |
| |
186 gtk_widget_class_bind_template_child(widget_class, PidginStatusDisplay, |
| |
187 label); |
| |
188 } |
| |
189 |
| |
190 static void |
| |
191 pidgin_status_display_init(PidginStatusDisplay *display) { |
| |
192 gtk_widget_init_template(GTK_WIDGET(display)); |
| |
193 } |
| |
194 |
| |
195 /****************************************************************************** |
| |
196 * Public API |
| |
197 *****************************************************************************/ |
| |
198 GtkWidget * |
| |
199 pidgin_status_display_new(void) { |
| |
200 return g_object_new(PIDGIN_TYPE_STATUS_DISPLAY, NULL); |
| |
201 } |
| |
202 |
| |
203 GtkWidget * |
| |
204 pidgin_status_display_new_for_primitive(PurpleStatusPrimitive primitive) { |
| |
205 return g_object_new(PIDGIN_TYPE_STATUS_DISPLAY, |
| |
206 "primitive", primitive, |
| |
207 NULL); |
| |
208 } |
| |
209 |
| |
210 GtkWidget * |
| |
211 pidgin_status_display_new_for_saved_status(PurpleSavedStatus *status) { |
| |
212 return g_object_new(PIDGIN_TYPE_STATUS_DISPLAY, |
| |
213 "saved-status", status, |
| |
214 NULL); |
| |
215 } |
| |
216 |
| |
217 PurpleStatusPrimitive |
| |
218 pidgin_status_display_get_primitive(PidginStatusDisplay *display) { |
| |
219 g_return_val_if_fail(PIDGIN_IS_STATUS_DISPLAY(display), |
| |
220 PURPLE_STATUS_UNSET); |
| |
221 |
| |
222 return display->primitive; |
| |
223 } |
| |
224 |
| |
225 void |
| |
226 pidgin_status_display_set_primitive(PidginStatusDisplay *display, |
| |
227 PurpleStatusPrimitive primitive) |
| |
228 { |
| |
229 g_return_if_fail(PIDGIN_IS_STATUS_DISPLAY(display)); |
| |
230 |
| |
231 g_object_freeze_notify(G_OBJECT(display)); |
| |
232 |
| |
233 display->status = NULL; |
| |
234 g_object_notify_by_pspec(G_OBJECT(display), properties[PROP_SAVED_STATUS]); |
| |
235 |
| |
236 if(display->primitive != primitive) { |
| |
237 display->primitive = primitive; |
| |
238 g_object_notify_by_pspec(G_OBJECT(display), |
| |
239 properties[PROP_PRIMITIVE]); |
| |
240 } |
| |
241 |
| |
242 pidgin_status_display_refresh(display); |
| |
243 |
| |
244 g_object_thaw_notify(G_OBJECT(display)); |
| |
245 } |
| |
246 |
| |
247 PurpleSavedStatus * |
| |
248 pidgin_status_display_get_saved_status(PidginStatusDisplay *display) { |
| |
249 g_return_val_if_fail(PIDGIN_IS_STATUS_DISPLAY(display), NULL); |
| |
250 |
| |
251 return display->status; |
| |
252 } |
| |
253 |
| |
254 void |
| |
255 pidgin_status_display_set_saved_status(PidginStatusDisplay *display, |
| |
256 PurpleSavedStatus *status) |
| |
257 { |
| |
258 g_return_if_fail(PIDGIN_IS_STATUS_DISPLAY(display)); |
| |
259 |
| |
260 g_object_freeze_notify(G_OBJECT(display)); |
| |
261 |
| |
262 display->primitive = PURPLE_STATUS_UNSET; |
| |
263 g_object_notify_by_pspec(G_OBJECT(display), properties[PROP_PRIMITIVE]); |
| |
264 |
| |
265 if(display->status != status) { |
| |
266 display->status = status; |
| |
267 g_object_notify_by_pspec(G_OBJECT(display), |
| |
268 properties[PROP_SAVED_STATUS]); |
| |
269 } |
| |
270 |
| |
271 pidgin_status_display_refresh(display); |
| |
272 |
| |
273 g_object_thaw_notify(G_OBJECT(display)); |
| |
274 } |