pidgin/pidginstatusdisplay.c

changeset 42198
4df23def5fe0
equal deleted inserted replaced
42197:f3bece910126 42198:4df23def5fe0
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 }

mercurial