| 182 |
185 |
| 183 static void do_add(GtkWidget *widget, PidginSmiley *s) |
186 static void do_add(GtkWidget *widget, PidginSmiley *s) |
| 184 { |
187 { |
| 185 const gchar *entry; |
188 const gchar *entry; |
| 186 PurpleSmiley *emoticon; |
189 PurpleSmiley *emoticon; |
| 187 gchar *file; |
|
| 188 |
190 |
| 189 entry = gtk_entry_get_text(GTK_ENTRY(s->smile)); |
191 entry = gtk_entry_get_text(GTK_ENTRY(s->smile)); |
| 190 |
192 emoticon = purple_smileys_find_by_shortcut(entry); |
| 191 if (s->filename == NULL || *entry == 0) { |
193 if (emoticon && emoticon != s->smiley) { |
| 192 purple_notify_error(s->parent, _("Custom Smiley"), |
194 purple_notify_error(s->parent, _("Custom Smiley"), |
| 193 _("More Data needed"), |
195 _("Duplicate Shortcut"), |
| 194 s->filename ? _("Please provide a shortcut to associate with the smiley.") |
196 _("A custom smiley for the selected shortcut already exists. Please specify a different shortcut.")); |
| |
197 return; |
| |
198 } |
| |
199 |
| |
200 if (s->smiley) { |
| |
201 if (s->filename) { |
| |
202 gchar *data = NULL; |
| |
203 size_t len; |
| |
204 GError *err = NULL; |
| |
205 |
| |
206 if (!g_file_get_contents(s->filename, &data, &len, &err)) { |
| |
207 purple_debug_error("gtksmiley", "Error reading %s: %s\n", |
| |
208 s->filename, err->message); |
| |
209 g_error_free(err); |
| |
210 |
| |
211 return; |
| |
212 } |
| |
213 purple_smiley_set_data(s->smiley, (guchar*)data, len, FALSE); |
| |
214 } |
| |
215 purple_smiley_set_shortcut(s->smiley, entry); |
| |
216 } else { |
| |
217 if ((s->filename == NULL || *entry == 0)) { |
| |
218 purple_notify_error(s->parent, _("Custom Smiley"), |
| |
219 _("More Data needed"), |
| |
220 s->filename ? _("Please provide a shortcut to associate with the smiley.") |
| 195 : _("Please select an image for the smiley.")); |
221 : _("Please select an image for the smiley.")); |
| 196 return; |
222 return; |
| 197 } |
223 } |
| 198 |
224 |
| 199 purple_debug_info("gtksmiley", "adding a new smiley\n"); |
225 purple_debug_info("gtksmiley", "adding a new smiley\n"); |
| 200 file = g_path_get_basename(s->filename); |
226 emoticon = purple_smiley_new_from_file(entry, s->filename); |
| 201 emoticon = purple_smiley_new_from_file(entry, s->filename, file); |
227 purple_smileys_add(emoticon); |
| 202 purple_smileys_add(emoticon); |
228 if (gtk_smileys != NULL) |
| 203 g_free(file); |
229 pidgin_smiley_add_to_list(emoticon); |
| 204 |
230 } |
| 205 if (gtk_smileys != NULL) |
|
| 206 pidgin_smiley_add_to_list(emoticon); |
|
| 207 |
231 |
| 208 if (smiley_manager != NULL) |
232 if (smiley_manager != NULL) |
| 209 refresh_list(); |
233 refresh_list(); |
| 210 |
234 |
| 211 gtk_widget_destroy(s->parent); |
235 gtk_widget_destroy(s->parent); |
| 225 purple_debug_error("gtksmiley", "no valid response\n"); |
249 purple_debug_error("gtksmiley", "no valid response\n"); |
| 226 break; |
250 break; |
| 227 } |
251 } |
| 228 } |
252 } |
| 229 |
253 |
| 230 static void do_add_file_cb(GtkWidget *widget, gint resp, PidginSmiley *s) |
254 static void do_add_file_cb(const char *filename, gpointer data) |
| 231 { |
255 { |
| 232 if (resp == GTK_RESPONSE_ACCEPT) |
256 PidginSmiley *s = data; |
| 233 s->filename = gtk_file_chooser_get_filename( |
257 GdkPixbuf *pixbuf; |
| 234 GTK_FILE_CHOOSER(s->file_chooser)); |
258 |
| 235 } |
259 if (!filename) |
| 236 |
260 return; |
| 237 void pidgin_smiley_add(GtkWidget *widget) |
261 |
| |
262 g_free(s->filename); |
| |
263 s->filename = g_strdup(filename); |
| |
264 pixbuf = gdk_pixbuf_new_from_file_at_scale(filename, 64, 64, FALSE, NULL); |
| |
265 gtk_image_set_from_pixbuf(GTK_IMAGE(s->smiley_image), pixbuf); |
| |
266 if (pixbuf) |
| |
267 gdk_pixbuf_unref(pixbuf); |
| |
268 } |
| |
269 |
| |
270 static void |
| |
271 open_image_selector(GtkWidget *widget, PidginSmiley *psmiley) |
| |
272 { |
| |
273 GtkWidget *file_chooser; |
| |
274 file_chooser = pidgin_buddy_icon_chooser_new(GTK_WINDOW(gtk_widget_get_toplevel(widget)), |
| |
275 do_add_file_cb, psmiley); |
| |
276 gtk_window_set_title(GTK_WINDOW(file_chooser), _("Custom Smiley")); |
| |
277 gtk_window_set_role(GTK_WINDOW(file_chooser), "file-selector-custom-smiley"); |
| |
278 gtk_widget_show_all(file_chooser); |
| |
279 } |
| |
280 |
| |
281 void pidgin_smiley_edit(GtkWidget *widget, PurpleSmiley *smiley) |
| 238 { |
282 { |
| 239 GtkWidget *vbox; |
283 GtkWidget *vbox; |
| 240 GtkWidget *hbox; |
284 GtkWidget *hbox; |
| 241 GtkWidget *label; |
285 GtkWidget *label; |
| 242 GtkWidget *filech; |
286 GtkWidget *filech; |
| 243 GtkWidget *window; |
287 GtkWidget *window; |
| |
288 GdkPixbuf *pixbuf = NULL; |
| |
289 PurpleStoredImage *stored_img; |
| 244 |
290 |
| 245 PidginSmiley *s = g_new0(PidginSmiley, 1); |
291 PidginSmiley *s = g_new0(PidginSmiley, 1); |
| 246 |
292 s->smiley = smiley; |
| 247 window = gtk_dialog_new_with_buttons(_("Add Smiley"), |
293 |
| |
294 window = gtk_dialog_new_with_buttons(smiley ? _("Edit Smiley") : _("Add Smiley"), |
| 248 GTK_WINDOW(widget), |
295 GTK_WINDOW(widget), |
| 249 GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR, |
296 GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR, |
| 250 GTK_STOCK_ADD, GTK_RESPONSE_ACCEPT, |
297 smiley ? GTK_STOCK_SAVE : GTK_STOCK_ADD, GTK_RESPONSE_ACCEPT, |
| 251 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, |
298 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, |
| 252 NULL); |
299 NULL); |
| 253 s->parent = window; |
300 s->parent = window; |
| 254 |
301 |
| 255 gtk_container_set_border_width(GTK_CONTAINER(window), PIDGIN_HIG_BORDER); |
302 gtk_container_set_border_width(GTK_CONTAINER(window), PIDGIN_HIG_BORDER); |
| 263 |
310 |
| 264 /* The hbox */ |
311 /* The hbox */ |
| 265 hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER); |
312 hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER); |
| 266 gtk_container_add(GTK_CONTAINER(GTK_VBOX(vbox)), hbox); |
313 gtk_container_add(GTK_CONTAINER(GTK_VBOX(vbox)), hbox); |
| 267 |
314 |
| 268 label = gtk_label_new(_("Select the file:")); |
315 label = gtk_label_new_with_mnemonic(_("Smiley _Image")); |
| 269 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); |
316 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); |
| 270 gtk_widget_show(label); |
317 gtk_widget_show(label); |
| 271 |
318 |
| 272 s->file_chooser = gtk_file_chooser_dialog_new(_("Custom Smiley"), |
319 filech = gtk_button_new(); |
| 273 GTK_WINDOW(window), |
320 gtk_box_pack_end(GTK_BOX(hbox), filech, FALSE, FALSE, 0); |
| 274 GTK_FILE_CHOOSER_ACTION_OPEN, |
321 pidgin_set_accessible_label(filech, label); |
| 275 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, |
322 |
| 276 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, |
323 s->smiley_image = gtk_image_new(); |
| 277 NULL); |
324 gtk_container_add(GTK_CONTAINER(filech), s->smiley_image); |
| 278 |
325 if (smiley && (stored_img = purple_smiley_get_stored_image(smiley))) { |
| 279 g_signal_connect(s->file_chooser, "response", G_CALLBACK(do_add_file_cb), s); |
326 pixbuf = pidgin_pixbuf_from_imgstore(stored_img); |
| 280 |
327 purple_imgstore_unref(stored_img); |
| 281 filech = gtk_file_chooser_button_new_with_dialog(GTK_WIDGET(s->file_chooser)); |
328 } else { |
| 282 |
329 GtkIconSize icon_size = gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_SMALL); |
| 283 gtk_box_pack_end(GTK_BOX(hbox), filech, TRUE, TRUE, 0); |
330 pixbuf = gtk_widget_render_icon(window, PIDGIN_STOCK_TOOLBAR_SELECT_AVATAR, |
| 284 gtk_widget_show(filech); |
331 icon_size, "PidginSmiley"); |
| 285 |
332 } |
| 286 gtk_widget_show(hbox); |
333 |
| |
334 gtk_image_set_from_pixbuf(GTK_IMAGE(s->smiley_image), pixbuf); |
| |
335 if (pixbuf != NULL) |
| |
336 g_object_unref(G_OBJECT(pixbuf)); |
| |
337 g_signal_connect(G_OBJECT(filech), "clicked", G_CALLBACK(open_image_selector), s); |
| |
338 |
| |
339 gtk_widget_show_all(hbox); |
| 287 |
340 |
| 288 /* info */ |
341 /* info */ |
| 289 hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER); |
342 hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER); |
| 290 gtk_container_add(GTK_CONTAINER(GTK_VBOX(vbox)),hbox); |
343 gtk_container_add(GTK_CONTAINER(GTK_VBOX(vbox)),hbox); |
| 291 |
344 |
| 292 /* Smiley shortcut */ |
345 /* Smiley shortcut */ |
| 293 label = gtk_label_new(_("Define Smiley's shortcut")); |
346 label = gtk_label_new_with_mnemonic(_("Smiley S_hortcut")); |
| 294 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); |
347 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); |
| 295 gtk_widget_show(label); |
348 gtk_widget_show(label); |
| 296 |
349 |
| 297 s->smile = gtk_entry_new(); |
350 s->smile = gtk_entry_new(); |
| 298 gtk_entry_set_activates_default(GTK_ENTRY(s->smile), TRUE); |
351 gtk_entry_set_activates_default(GTK_ENTRY(s->smile), TRUE); |
| 299 gtk_label_set_mnemonic_widget(GTK_LABEL(label), GTK_WIDGET(s->smile)); |
352 pidgin_set_accessible_label(s->smile, label); |
| |
353 if (smiley) |
| |
354 gtk_entry_set_text(GTK_ENTRY(s->smile), purple_smiley_get_shortcut(smiley)); |
| 300 |
355 |
| 301 g_signal_connect(s->smile, "activate", G_CALLBACK(do_add), s); |
356 g_signal_connect(s->smile, "activate", G_CALLBACK(do_add), s); |
| 302 |
357 |
| 303 gtk_box_pack_end(GTK_BOX(hbox), s->smile, FALSE, FALSE, 0); |
358 gtk_box_pack_end(GTK_BOX(hbox), s->smile, FALSE, FALSE, 0); |
| 304 gtk_widget_show(s->smile); |
359 gtk_widget_show(s->smile); |
| 386 return; |
441 return; |
| 387 |
442 |
| 388 img = purple_smiley_get_stored_image(smiley); |
443 img = purple_smiley_get_stored_image(smiley); |
| 389 |
444 |
| 390 if (img != NULL) { |
445 if (img != NULL) { |
| 391 GdkPixbufLoader *loader = gdk_pixbuf_loader_new(); |
446 GdkPixbuf *smiley_image = pidgin_pixbuf_from_imgstore(img); |
| 392 GdkPixbuf *smiley_image = NULL; |
|
| 393 |
|
| 394 gdk_pixbuf_loader_write(loader, purple_imgstore_get_data(img), |
|
| 395 purple_imgstore_get_size(img), NULL); |
|
| 396 gdk_pixbuf_loader_close(loader, NULL); |
|
| 397 smiley_image = gdk_pixbuf_loader_get_pixbuf(loader); |
|
| 398 |
|
| 399 purple_imgstore_unref(img); |
447 purple_imgstore_unref(img); |
| 400 |
448 |
| 401 if (smiley_image != NULL) |
449 if (smiley_image != NULL) |
| 402 sized_smiley = gdk_pixbuf_scale_simple(smiley_image, |
450 sized_smiley = gdk_pixbuf_scale_simple(smiley_image, |
| 403 22, 22, GDK_INTERP_HYPER); |
451 22, 22, GDK_INTERP_HYPER); |
| 404 |
|
| 405 g_object_unref(loader); |
|
| 406 } |
452 } |
| 407 |
453 |
| 408 |
454 |
| 409 gtk_list_store_append(smiley_manager->model, &iter); |
455 gtk_list_store_append(smiley_manager->model, &iter); |
| 410 |
456 |
| 411 gtk_list_store_set(smiley_manager->model, &iter, |
457 gtk_list_store_set(smiley_manager->model, &iter, |
| 412 ICON, sized_smiley, |
458 ICON, sized_smiley, |
| 413 SHORTCUT, purple_smiley_get_shortcut(smiley), |
459 SHORTCUT, purple_smiley_get_shortcut(smiley), |
| 414 DATA, NULL, |
460 SMILEY, smiley, |
| 415 -1); |
461 -1); |
| 416 |
462 |
| 417 if (sized_smiley != NULL) |
463 if (sized_smiley != NULL) |
| 418 g_object_unref(G_OBJECT(sized_smiley)); |
464 g_object_unref(G_OBJECT(sized_smiley)); |
| 419 } |
465 } |
| 439 |
485 |
| 440 selected = gtk_tree_selection_count_selected_rows(sel); |
486 selected = gtk_tree_selection_count_selected_rows(sel); |
| 441 |
487 |
| 442 gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog->window), |
488 gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog->window), |
| 443 GTK_RESPONSE_NO, selected > 0); |
489 GTK_RESPONSE_NO, selected > 0); |
| |
490 } |
| |
491 |
| |
492 static void smiley_edit_cb(GtkTreeView *treeview, GtkTreePath *path, GtkTreeViewColumn *col, gpointer data) |
| |
493 { |
| |
494 GtkTreeIter iter; |
| |
495 SmileyManager *dialog = data; |
| |
496 PurpleSmiley *smiley = NULL; |
| |
497 |
| |
498 gtk_tree_model_get_iter(GTK_TREE_MODEL(dialog->model), &iter, path); |
| |
499 gtk_tree_model_get(GTK_TREE_MODEL(dialog->model), &iter, SMILEY, &smiley, -1); |
| |
500 pidgin_smiley_edit(gtk_widget_get_toplevel(GTK_WIDGET(treeview)), smiley); |
| 444 } |
501 } |
| 445 |
502 |
| 446 static GtkWidget *smiley_list_create(SmileyManager *dialog) |
503 static GtkWidget *smiley_list_create(SmileyManager *dialog) |
| 447 { |
504 { |
| 448 GtkWidget *sw; |
505 GtkWidget *sw; |
| 452 sw = gtk_scrolled_window_new(NULL, NULL); |
509 sw = gtk_scrolled_window_new(NULL, NULL); |
| 453 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), |
510 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), |
| 454 GTK_POLICY_AUTOMATIC, |
511 GTK_POLICY_AUTOMATIC, |
| 455 GTK_POLICY_AUTOMATIC); |
512 GTK_POLICY_AUTOMATIC); |
| 456 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), |
513 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), |
| 457 GTK_SHADOW_NONE); |
514 GTK_SHADOW_IN); |
| 458 gtk_widget_show(sw); |
515 gtk_widget_show(sw); |
| 459 |
516 |
| 460 /* Create the list model */ |
517 /* Create the list model */ |
| 461 dialog->model = gtk_list_store_new(N_COL, |
518 dialog->model = gtk_list_store_new(N_COL, |
| 462 GDK_TYPE_PIXBUF, /* ICON */ |
519 GDK_TYPE_PIXBUF, /* ICON */ |
| 463 G_TYPE_STRING, /* SHORTCUT */ |
520 G_TYPE_STRING, /* SHORTCUT */ |
| 464 G_TYPE_POINTER /* DATA */ |
521 G_TYPE_POINTER /* SMILEY */ |
| 465 ); |
522 ); |
| 466 |
523 |
| 467 /* the actual treeview */ |
524 /* the actual treeview */ |
| 468 treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(dialog->model)); |
525 treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(dialog->model)); |
| 469 dialog->treeview = treeview; |
526 dialog->treeview = treeview; |
| 470 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE); |
527 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE); |
| 471 |
528 |
| |
529 |
| 472 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); |
530 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); |
| 473 gtk_tree_selection_set_mode(sel, GTK_SELECTION_MULTIPLE); |
531 gtk_tree_selection_set_mode(sel, GTK_SELECTION_MULTIPLE); |
| 474 gtk_container_add(GTK_CONTAINER(sw), treeview); |
532 gtk_container_add(GTK_CONTAINER(sw), treeview); |
| 475 |
533 |
| 476 g_signal_connect(G_OBJECT(sel), "changed", |
534 g_signal_connect(G_OBJECT(sel), "changed", G_CALLBACK(smile_selected_cb), dialog); |
| 477 G_CALLBACK(smile_selected_cb), dialog); |
535 g_signal_connect(G_OBJECT(treeview), "row_activated", G_CALLBACK(smiley_edit_cb), dialog); |
| 478 |
536 |
| 479 gtk_widget_show(treeview); |
537 gtk_widget_show(treeview); |
| 480 |
538 |
| 481 add_columns(treeview, dialog); |
539 add_columns(treeview, dialog); |
| 482 populate_smiley_list(dialog); |
540 populate_smiley_list(dialog); |