pidgin/pidginstatuseditor.c

changeset 42526
c73c0cf2b554
parent 42525
56a4fd2844ae
child 42527
1954265c38f0
equal deleted inserted replaced
42525:56a4fd2844ae 42526:c73c0cf2b554
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
23 #include "pidginstatuseditor.h"
24
25 #include "pidginstatusprimitivechooser.h"
26
27 enum {
28 PROP_0,
29 PROP_STATUS,
30 N_PROPERTIES
31 };
32 static GParamSpec *properties[N_PROPERTIES] = {NULL, };
33
34 enum {
35 RESPONSE_USE,
36 RESPONSE_SAVE
37 };
38
39 struct _PidginStatusEditor {
40 GtkDialog parent;
41
42 PurpleSavedStatus *status;
43
44 GtkTextBuffer *buffer;
45
46 GtkWidget *title;
47 GtkWidget *primitive;
48 };
49
50 G_DEFINE_TYPE(PidginStatusEditor, pidgin_status_editor, GTK_TYPE_DIALOG)
51
52 /******************************************************************************
53 * Helpers
54 *****************************************************************************/
55 static void
56 pidgin_status_editor_set_status(PidginStatusEditor *editor,
57 PurpleSavedStatus *status)
58 {
59 PurpleStatusPrimitive primitive;
60 PidginStatusPrimitiveChooser *chooser = NULL;
61 const gchar *title = NULL, *message = NULL;
62
63 editor->status = status;
64
65 if(editor->status != NULL) {
66 title = purple_savedstatus_get_title(editor->status);
67 primitive = purple_savedstatus_get_primitive_type(editor->status);
68 message = purple_savedstatus_get_message(editor->status);
69 } else {
70 primitive = PURPLE_STATUS_AWAY;
71 }
72
73 if(title == NULL) {
74 title = "";
75 }
76
77 if(message == NULL) {
78 message = "";
79 }
80
81 gtk_editable_set_text(GTK_EDITABLE(editor->title), title);
82 chooser = PIDGIN_STATUS_PRIMITIVE_CHOOSER(editor->primitive);
83 pidgin_status_primitive_chooser_set_selected(chooser, primitive);
84 gtk_text_buffer_set_text(editor->buffer, message, -1);
85
86 g_object_notify_by_pspec(G_OBJECT(editor), properties[PROP_STATUS]);
87 }
88
89 static void
90 pidgin_status_editor_save_status(PidginStatusEditor *editor) {
91 PidginStatusPrimitiveChooser *chooser = NULL;
92 PurpleStatusPrimitive primitive;
93 GtkTextIter start;
94 GtkTextIter end;
95 gchar *message = NULL;
96 const gchar *title = NULL;
97
98 title = gtk_editable_get_text(GTK_EDITABLE(editor->title));
99
100 chooser = PIDGIN_STATUS_PRIMITIVE_CHOOSER(editor->primitive);
101 primitive = pidgin_status_primitive_chooser_get_selected(chooser);
102
103 gtk_text_buffer_get_start_iter(editor->buffer, &start);
104 gtk_text_buffer_get_end_iter(editor->buffer, &end);
105 message = gtk_text_buffer_get_text(editor->buffer, &start, &end, FALSE);
106
107 if(editor->status == NULL) {
108 editor->status = purple_savedstatus_new(title, primitive);
109 } else {
110 const gchar *current_title = NULL;
111
112 /* purple_savedstatus_set_title throws a warning if you try to save a
113 * status with an existing title, which means we can't just save the
114 * title if it hasn't changed.
115 */
116 current_title = purple_savedstatus_get_title(editor->status);
117 if(!purple_strequal(title, current_title)) {
118 purple_savedstatus_set_title(editor->status, title);
119 }
120
121 purple_savedstatus_set_primitive_type(editor->status, primitive);
122 }
123
124 purple_savedstatus_set_message(editor->status, message);
125
126 g_free(message);
127 }
128
129 /******************************************************************************
130 * Callbacks
131 *****************************************************************************/
132 static void
133 pidgin_status_editor_response_cb(GtkDialog *dialog, gint response_id,
134 gpointer data)
135 {
136 PidginStatusEditor *editor = data;
137
138 switch(response_id) {
139 case RESPONSE_USE:
140 pidgin_status_editor_save_status(editor);
141 purple_savedstatus_activate(editor->status);
142 break;
143 case RESPONSE_SAVE:
144 pidgin_status_editor_save_status(editor);
145 break;
146 }
147
148 gtk_window_destroy(GTK_WINDOW(dialog));
149 }
150
151 static void
152 pidgin_status_editor_title_changed_cb(G_GNUC_UNUSED GtkEditable *editable,
153 gpointer data)
154 {
155 PidginStatusEditor *editor = data;
156 gboolean title_changed = FALSE, sensitive = FALSE;
157 const gchar *title = NULL;
158
159 title = gtk_editable_get_text(GTK_EDITABLE(editor->title));
160
161 if(editor->status != NULL) {
162 /* If we're editing a status, check if the title is the same. */
163 title_changed = !purple_strequal(title,
164 purple_savedstatus_get_title(editor->status));
165 } else {
166 /* If this is a new status, check if the title is empty or not. */
167 title_changed = !purple_strequal(title, "");
168 }
169
170 if(title_changed) {
171 gboolean duplicated = purple_savedstatus_find(title) != NULL;
172
173 if(duplicated) {
174 gtk_dialog_set_response_sensitive(GTK_DIALOG(editor),
175 RESPONSE_USE, FALSE);
176 gtk_dialog_set_response_sensitive(GTK_DIALOG(editor),
177 RESPONSE_SAVE, FALSE);
178
179 return;
180 }
181 }
182
183 sensitive = !purple_strequal(title, "");
184
185 gtk_dialog_set_response_sensitive(GTK_DIALOG(editor), RESPONSE_USE,
186 sensitive);
187 gtk_dialog_set_response_sensitive(GTK_DIALOG(editor), RESPONSE_SAVE,
188 sensitive);
189 }
190
191 /******************************************************************************
192 * GObject Implementation
193 *****************************************************************************/
194 static void
195 pidgin_status_editor_get_property(GObject *obj, guint param_id, GValue *value,
196 GParamSpec *pspec)
197 {
198 PidginStatusEditor *editor = PIDGIN_STATUS_EDITOR(obj);
199
200 switch(param_id) {
201 case PROP_STATUS:
202 g_value_set_pointer(value,
203 pidgin_status_editor_get_status(editor));
204 break;
205 default:
206 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
207 break;
208 }
209 }
210
211 static void
212 pidgin_status_editor_set_property(GObject *obj, guint param_id,
213 const GValue *value, GParamSpec *pspec)
214 {
215 PidginStatusEditor *editor = PIDGIN_STATUS_EDITOR(obj);
216
217 switch(param_id) {
218 case PROP_STATUS:
219 pidgin_status_editor_set_status(editor,
220 g_value_get_pointer(value));
221 break;
222 default:
223 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
224 break;
225 }
226 }
227
228 static void
229 pidgin_status_editor_init(PidginStatusEditor *manager) {
230 gtk_widget_init_template(GTK_WIDGET(manager));
231 }
232
233 static void
234 pidgin_status_editor_class_init(PidginStatusEditorClass *klass) {
235 GObjectClass *obj_class = G_OBJECT_CLASS(klass);
236 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
237
238 obj_class->get_property = pidgin_status_editor_get_property;
239 obj_class->set_property = pidgin_status_editor_set_property;
240
241 /**
242 * PidginStatusEditor:status:
243 *
244 * The [type@Purple.SavedStatus] that this editor is responsible for.
245 * This may be %NULL if it is creating a new status.
246 *
247 * Since: 3.0.0.
248 */
249 /* we don't used boxed here because of the way status are currently
250 * managed.
251 */
252 properties[PROP_STATUS] = g_param_spec_pointer(
253 "status", "status",
254 "The saved status we're editing",
255 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
256
257 g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
258
259 gtk_widget_class_set_template_from_resource(
260 widget_class,
261 "/im/pidgin/Pidgin3/Status/editor.ui"
262 );
263
264 gtk_widget_class_bind_template_child(widget_class, PidginStatusEditor,
265 buffer);
266
267 gtk_widget_class_bind_template_child(widget_class, PidginStatusEditor,
268 title);
269 gtk_widget_class_bind_template_child(widget_class, PidginStatusEditor,
270 primitive);
271
272 gtk_widget_class_bind_template_callback(widget_class,
273 pidgin_status_editor_response_cb);
274 gtk_widget_class_bind_template_callback(widget_class,
275 pidgin_status_editor_title_changed_cb);
276 }
277
278 /******************************************************************************
279 * Public API
280 *****************************************************************************/
281 GtkWidget *
282 pidgin_status_editor_new(PurpleSavedStatus *status) {
283 return g_object_new(
284 PIDGIN_TYPE_STATUS_EDITOR,
285 "status", status,
286 NULL);
287 }
288
289 PurpleSavedStatus *
290 pidgin_status_editor_get_status(PidginStatusEditor *editor) {
291 g_return_val_if_fail(PIDGIN_IS_STATUS_EDITOR(editor), NULL);
292
293 return editor->status;
294 }

mercurial