comparison src/gtksavedstatuses.c @ 10420:854c972ea863

[gaim-migrate @ 11671] The ability to add, modify and _save_ new statuses. This hopefully brings our functionality slightly past where it is in oldstatus. This could use a bit of testing, but I think it's pretty good. We still can't edit substatuses. Primitive types like "unset" should be hidden from the status selector dropdown. "Online" and "offline" should maybe be hidden... but someone in #gaim mentioned that it might be a good way to choose which accounts are offline for a given status. Eh. committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Sun, 26 Dec 2004 05:23:51 +0000
parents c9b1f3fac753
children ee56a3e54fbd
comparison
equal deleted inserted replaced
10419:c9b1f3fac753 10420:854c972ea863
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */ 24 */
25 25
26 #include "account.h" 26 #include "account.h"
27 #include "internal.h" 27 #include "internal.h"
28 #include "notify.h"
28 #include "request.h" 29 #include "request.h"
29 #include "savedstatuses.h" 30 #include "savedstatuses.h"
30 #include "status.h" 31 #include "status.h"
31 #include "util.h" 32 #include "util.h"
32 33
48 }; 49 };
49 50
50 enum 51 enum
51 { 52 {
52 STATUS_WINDOW_COLUMN_TITLE, 53 STATUS_WINDOW_COLUMN_TITLE,
54 STATUS_WINDOW_COLUMN_TYPE,
53 STATUS_WINDOW_COLUMN_MESSAGE, 55 STATUS_WINDOW_COLUMN_MESSAGE,
54 STATUS_WINDOW_NUM_COLUMNS 56 STATUS_WINDOW_NUM_COLUMNS
55 }; 57 };
56 58
57 typedef struct 59 typedef struct
58 { 60 {
59 GtkWidget *window; 61 GtkWidget *window;
60 GtkListStore *model; 62 GtkListStore *model;
61 GtkWidget *treeview; 63 GtkWidget *treeview;
64 GtkWidget *save_button;
65
66 gchar *original_title;
67 GtkEntry *title;
68 GtkOptionMenu *type;
69 GtkIMHtml *message;
62 } StatusEditor; 70 } StatusEditor;
63 71
64 typedef struct 72 typedef struct
65 { 73 {
66 GtkWidget *window; 74 GtkWidget *window;
70 GtkWidget *delete_button; 78 GtkWidget *delete_button;
71 } StatusWindow; 79 } StatusWindow;
72 80
73 static StatusWindow *status_window = NULL; 81 static StatusWindow *status_window = NULL;
74 82
83 static void add_status_to_saved_status_list(GtkListStore *model, GaimSavedStatus *saved_status);
84 static gboolean status_window_find_savedstatus(GtkTreeIter *iter, const char *title);
85
75 static gboolean 86 static gboolean
76 status_editor_destroy_cb(GtkWidget *widget, GdkEvent *event, gpointer user_data) 87 status_editor_destroy_cb(GtkWidget *widget, GdkEvent *event, gpointer user_data)
77 { 88 {
78 StatusWindow *dialog = user_data; 89 StatusWindow *dialog = user_data;
79 90
93 } 104 }
94 105
95 static void 106 static void
96 status_editor_save_cb(GtkButton *button, gpointer user_data) 107 status_editor_save_cb(GtkButton *button, gpointer user_data)
97 { 108 {
98 /* TODO: Save the status */ 109 StatusEditor *dialog = user_data;
110 const char *title;
111 GaimStatusPrimitive type;
112 char *message, *unformatted;
113 GaimSavedStatus *status;
114
115 title = gtk_entry_get_text(dialog->title);
116
117 /*
118 * If the title is already taken then show an error dialog and
119 * don't do anything.
120 */
121 if ((gaim_savedstatus_find(title) != NULL) &&
122 ((dialog->original_title == NULL) || (strcmp(title, dialog->original_title))))
123 {
124 gaim_notify_error(NULL, NULL, _("Title already in use. You must "
125 "choose a unique title."), NULL);
126 return;
127 }
128
129 type = gtk_option_menu_get_history(dialog->type);
130 message = gtk_imhtml_get_markup(dialog->message);
131 unformatted = gaim_markup_strip_html(message);
132
133 /*
134 * If we're editing an existing status, remove the old one to
135 * make way for the modified one.
136 */
137 if (dialog->original_title != NULL)
138 {
139 GtkTreeIter iter;
140
141 gaim_savedstatus_delete(dialog->original_title);
142
143 if (status_window_find_savedstatus(&iter, dialog->original_title))
144 {
145 gtk_list_store_remove(status_window->model, &iter);
146 }
147
148 g_free(dialog->original_title);
149 }
150
151 status = gaim_savedstatus_new(title, type);
152 if (*unformatted != '\0')
153 gaim_savedstatus_set_message(status, message);
154 g_free(message);
155 g_free(unformatted);
156
157 gtk_widget_destroy(dialog->window);
158 g_free(dialog);
159
160 add_status_to_saved_status_list(status_window->model, status);
161 }
162
163 static void
164 status_editor_custom_status_cb(GtkCellRendererToggle *renderer, gchar *path_str, gpointer data)
165 {
166 /* StatusEditor *dialog = (StatusEditor *)data; */
167
168 /* TODO: Need to allow user to set a custom status for the highlighted account, somehow */
169 }
170
171 static void
172 editor_title_changed_cb(GtkWidget *widget, gpointer user_data)
173 {
174 StatusEditor *dialog = user_data;
175 const gchar *text;
176
177 text = gtk_entry_get_text(dialog->title);
178
179 gtk_widget_set_sensitive(dialog->save_button, (*text != '\0'));
99 } 180 }
100 181
101 static GtkWidget * 182 static GtkWidget *
102 create_status_type_menu(GaimStatusPrimitive type) 183 create_status_type_menu(GaimStatusPrimitive type)
103 { 184 {
119 gtk_menu_set_active(GTK_MENU(menu), type); 200 gtk_menu_set_active(GTK_MENU(menu), type);
120 gtk_option_menu_set_menu(GTK_OPTION_MENU(dropdown), menu); 201 gtk_option_menu_set_menu(GTK_OPTION_MENU(dropdown), menu);
121 gtk_widget_show(menu); 202 gtk_widget_show(menu);
122 203
123 return dropdown; 204 return dropdown;
124 }
125
126 static void
127 status_editor_custom_status_cb(GtkCellRendererToggle *renderer, gchar *path_str, gpointer data)
128 {
129 /* StatusEditor *dialog = (StatusEditor *)data; */
130
131 /* TODO: Need to allow user to set a custom status for the highlighted account, somehow */
132 } 205 }
133 206
134 static void 207 static void
135 status_editor_add_columns(StatusEditor *dialog) 208 status_editor_add_columns(StatusEditor *dialog)
136 { 209 {
237 GtkWidget *vbox; 310 GtkWidget *vbox;
238 GtkWidget *win; 311 GtkWidget *win;
239 312
240 dialog = g_new0(StatusEditor, 1); 313 dialog = g_new0(StatusEditor, 1);
241 314
315 if (status != NULL)
316 dialog->original_title = g_strdup(gaim_savedstatus_get_title(status));
317
242 dialog->window = win = gtk_window_new(GTK_WINDOW_TOPLEVEL); 318 dialog->window = win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
243 gtk_window_set_role(GTK_WINDOW(win), "status"); 319 gtk_window_set_role(GTK_WINDOW(win), "status");
244 gtk_window_set_title(GTK_WINDOW(win), _("Status")); 320 gtk_window_set_title(GTK_WINDOW(win), _("Status"));
245 gtk_window_set_resizable(GTK_WINDOW(win), FALSE); 321 gtk_window_set_resizable(GTK_WINDOW(win), FALSE);
246 gtk_container_set_border_width(GTK_CONTAINER(win), 12); 322 gtk_container_set_border_width(GTK_CONTAINER(win), 12);
265 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); 341 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
266 gtk_widget_show(label); 342 gtk_widget_show(label);
267 gtk_size_group_add_widget(sg, label); 343 gtk_size_group_add_widget(sg, label);
268 344
269 entry = gtk_entry_new(); 345 entry = gtk_entry_new();
346 dialog->title = GTK_ENTRY(entry);
270 if (status != NULL) 347 if (status != NULL)
271 gtk_entry_set_text(GTK_ENTRY(entry), gaim_savedstatus_get_title(status)); 348 gtk_entry_set_text(GTK_ENTRY(entry), dialog->original_title);
272 else 349 else
273 gtk_entry_set_text(GTK_ENTRY(entry), _("Out of the office")); 350 gtk_entry_set_text(GTK_ENTRY(entry), _("Out of the office"));
274 gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0); 351 gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
275 gtk_widget_show(entry); 352 gtk_widget_show(entry);
353 g_signal_connect(G_OBJECT(entry), "changed",
354 G_CALLBACK(editor_title_changed_cb), dialog);
276 355
277 /* Status type */ 356 /* Status type */
278 hbox = gtk_hbox_new(FALSE, 6); 357 hbox = gtk_hbox_new(FALSE, 6);
279 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); 358 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
280 gtk_widget_show(hbox); 359 gtk_widget_show(hbox);
287 366
288 if (status != NULL) 367 if (status != NULL)
289 dropdown = create_status_type_menu(gaim_savedstatus_get_type(status)); 368 dropdown = create_status_type_menu(gaim_savedstatus_get_type(status));
290 else 369 else
291 dropdown = create_status_type_menu(GAIM_STATUS_AWAY); 370 dropdown = create_status_type_menu(GAIM_STATUS_AWAY);
371 dialog->type = GTK_OPTION_MENU(dropdown);
292 gtk_box_pack_start(GTK_BOX(hbox), dropdown, TRUE, TRUE, 0); 372 gtk_box_pack_start(GTK_BOX(hbox), dropdown, TRUE, TRUE, 0);
293 gtk_widget_show(dropdown); 373 gtk_widget_show(dropdown);
294 374
295 /* Status message */ 375 /* Status message */
296 hbox = gtk_hbox_new(FALSE, 6); 376 hbox = gtk_hbox_new(FALSE, 6);
302 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); 382 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
303 gtk_widget_show(label); 383 gtk_widget_show(label);
304 gtk_size_group_add_widget(sg, label); 384 gtk_size_group_add_widget(sg, label);
305 385
306 frame = gaim_gtk_create_imhtml(TRUE, &text, &toolbar); 386 frame = gaim_gtk_create_imhtml(TRUE, &text, &toolbar);
387 dialog->message = GTK_IMHTML(text);
307 gtk_box_pack_start(GTK_BOX(hbox), frame, TRUE, TRUE, 0); 388 gtk_box_pack_start(GTK_BOX(hbox), frame, TRUE, TRUE, 0);
308 gtk_widget_show(frame); 389 gtk_widget_show(frame);
309 390
310 if (status != NULL) 391 if (status != NULL)
311 gtk_imhtml_append_text(GTK_IMHTML(text), 392 gtk_imhtml_append_text(GTK_IMHTML(text),
368 449
369 g_signal_connect(G_OBJECT(button), "clicked", 450 g_signal_connect(G_OBJECT(button), "clicked",
370 G_CALLBACK(status_editor_cancel_cb), dialog); 451 G_CALLBACK(status_editor_cancel_cb), dialog);
371 452
372 /* Save button */ 453 /* Save button */
373 /* TODO: This button needs to be made sensitive when the title box contains text */
374 button = gtk_button_new_from_stock(GTK_STOCK_SAVE); 454 button = gtk_button_new_from_stock(GTK_STOCK_SAVE);
455 dialog->save_button = button;
375 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); 456 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
376 gtk_widget_set_sensitive(button, FALSE);
377 gtk_widget_show(button); 457 gtk_widget_show(button);
378 458
379 g_signal_connect(G_OBJECT(button), "clicked", 459 g_signal_connect(G_OBJECT(button), "clicked",
380 G_CALLBACK(status_editor_save_cb), dialog); 460 G_CALLBACK(status_editor_save_cb), dialog);
381 461
507 gtk_widget_set_sensitive(dialog->modify_button, selected); 587 gtk_widget_set_sensitive(dialog->modify_button, selected);
508 gtk_widget_set_sensitive(dialog->delete_button, selected); 588 gtk_widget_set_sensitive(dialog->delete_button, selected);
509 } 589 }
510 590
511 static void 591 static void
592 add_status_to_saved_status_list(GtkListStore *model, GaimSavedStatus *saved_status)
593 {
594 GtkTreeIter iter;
595 const char *title;
596 const char *type;
597 char *message;
598
599 title = gaim_savedstatus_get_title(saved_status);
600 type = gaim_primitive_get_name_from_type(gaim_savedstatus_get_type(saved_status));
601 message = gaim_markup_strip_html(gaim_savedstatus_get_message(saved_status));
602 if (strlen(message) > 70)
603 strcpy(&message[68], "...");
604
605 gtk_list_store_append(model, &iter);
606 gtk_list_store_set(model, &iter,
607 STATUS_WINDOW_COLUMN_TITLE, title,
608 STATUS_WINDOW_COLUMN_TYPE, type,
609 STATUS_WINDOW_COLUMN_MESSAGE, message,
610 -1);
611 free(message);
612 }
613
614 static void
512 populate_saved_status_list(StatusWindow *dialog) 615 populate_saved_status_list(StatusWindow *dialog)
513 { 616 {
514 GtkTreeIter iter;
515 const GList *saved_statuses; 617 const GList *saved_statuses;
516 GaimSavedStatus *saved_status;
517 char *message;
518 618
519 gtk_list_store_clear(dialog->model); 619 gtk_list_store_clear(dialog->model);
520 620
521 for (saved_statuses = gaim_savedstatuses_get_all(); saved_statuses != NULL; 621 for (saved_statuses = gaim_savedstatuses_get_all(); saved_statuses != NULL;
522 saved_statuses = g_list_next(saved_statuses)) 622 saved_statuses = g_list_next(saved_statuses))
523 { 623 {
524 saved_status = (GaimSavedStatus *)saved_statuses->data; 624 add_status_to_saved_status_list(dialog->model, saved_statuses->data);
525 message = gaim_markup_strip_html(gaim_savedstatus_get_message(saved_status));
526 if (strlen(message) > 70)
527 strcpy(&message[68], "...");
528
529 gtk_list_store_append(dialog->model, &iter);
530 gtk_list_store_set(dialog->model, &iter,
531 STATUS_WINDOW_COLUMN_TITLE, gaim_savedstatus_get_title(saved_status),
532 STATUS_WINDOW_COLUMN_MESSAGE, message,
533 -1);
534 free(message);
535 } 625 }
536 } 626 }
537 627
538 static GtkWidget * 628 static GtkWidget *
539 create_saved_status_list(StatusWindow *dialog) 629 create_saved_status_list(StatusWindow *dialog)
553 GTK_SHADOW_IN); 643 GTK_SHADOW_IN);
554 gtk_widget_show(sw); 644 gtk_widget_show(sw);
555 645
556 /* Create the list model */ 646 /* Create the list model */
557 dialog->model = gtk_list_store_new(STATUS_WINDOW_NUM_COLUMNS, 647 dialog->model = gtk_list_store_new(STATUS_WINDOW_NUM_COLUMNS,
648 G_TYPE_STRING,
558 G_TYPE_STRING, 649 G_TYPE_STRING,
559 G_TYPE_STRING); 650 G_TYPE_STRING);
560 651
561 /* Create the treeview */ 652 /* Create the treeview */
562 treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(dialog->model)); 653 treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(dialog->model));
583 gtk_tree_view_column_pack_start(column, renderer, TRUE); 674 gtk_tree_view_column_pack_start(column, renderer, TRUE);
584 gtk_tree_view_column_add_attribute(column, renderer, "text", 675 gtk_tree_view_column_add_attribute(column, renderer, "text",
585 STATUS_WINDOW_COLUMN_TITLE); 676 STATUS_WINDOW_COLUMN_TITLE);
586 677
587 column = gtk_tree_view_column_new(); 678 column = gtk_tree_view_column_new();
679 gtk_tree_view_column_set_title(column, _("Type"));
680 gtk_tree_view_column_set_resizable(column, TRUE);
681 gtk_tree_view_column_set_sort_column_id(column,
682 STATUS_WINDOW_COLUMN_TYPE);
683 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
684 renderer = gtk_cell_renderer_text_new();
685 gtk_tree_view_column_pack_start(column, renderer, TRUE);
686 gtk_tree_view_column_add_attribute(column, renderer, "text",
687 STATUS_WINDOW_COLUMN_TYPE);
688
689 column = gtk_tree_view_column_new();
588 gtk_tree_view_column_set_title(column, _("Message")); 690 gtk_tree_view_column_set_title(column, _("Message"));
589 gtk_tree_view_column_set_resizable(column, TRUE); 691 gtk_tree_view_column_set_resizable(column, TRUE);
590 gtk_tree_view_column_set_sort_column_id(column, 692 gtk_tree_view_column_set_sort_column_id(column,
591 STATUS_WINDOW_COLUMN_MESSAGE); 693 STATUS_WINDOW_COLUMN_MESSAGE);
592 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); 694 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);