Mercurial > pidgin.yaz
annotate src/gtkutils.c @ 4770:c4c28874ecd3
[gaim-migrate @ 5088]
I want to go to sleep. This is drag-n-drop moving of buddies in the list.
I think it works, but I didn't actually test it... I really should have though;
I can't imagine it working fine as-is. ;)
I'm holding off on the rest of my Edit Buddy List stuff for tomorrow... I love
last minute things, don't I?
Note: I created gaim_blist_members and gaim_blist_groups to reproduce the
effects of the old groups GSList and the members GSList of the group struct
that I removed. This is really sub-optimal and should be replaced to iterate
the Buddy List directly. If someone wants to do that, please do. Even if you
don't want to do that, just review the changes I made and make sure I didn't
do anything stupid. It is past 6am and I'm a bit tired and prone to mistake
making.
Thanks.
committer: Tailor Script <tailor@pidgin.im>
author | Sean Egan <seanegan@gmail.com> |
---|---|
date | Fri, 14 Mar 2003 11:38:21 +0000 |
parents | 283fb289c510 |
children | 677d3cb193a1 |
rev | line source |
---|---|
4359 | 1 /* |
2 * gaim | |
3 * | |
4 * Copyright (C) 2002-2003, Christian Hammond <chipx86@gnupdate.org> | |
5 * | |
6 * This program is free software; you can redistribute it and/or modify | |
7 * it under the terms of the GNU General Public License as published by | |
8 * the Free Software Foundation; either version 2 of the License, or | |
9 * (at your option) any later version. | |
10 * | |
11 * This program is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 * GNU General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU General Public License | |
17 * along with this program; if not, write to the Free Software | |
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
19 * | |
20 */ | |
21 #ifdef HAVE_CONFIG_H | |
22 #include <config.h> | |
23 #endif | |
24 #include <string.h> | |
25 #ifndef _WIN32 | |
26 #include <sys/time.h> | |
27 #include <unistd.h> | |
28 #include <gdk/gdkx.h> | |
29 #include <X11/Xlib.h> | |
30 #else | |
31 #ifdef small | |
32 #undef small | |
33 #endif | |
34 #endif /*_WIN32*/ | |
35 #include <sys/types.h> | |
36 #include <sys/stat.h> | |
37 #include <stdio.h> | |
38 #include <stdlib.h> | |
39 #include <errno.h> | |
40 #include <ctype.h> | |
41 #include <gtk/gtk.h> | |
42 #ifdef USE_GTKSPELL | |
43 #include <gtkspell/gtkspell.h> | |
44 #endif | |
45 #include "gtkimhtml.h" | |
46 #include <gdk/gdkkeysyms.h> | |
47 #include "prpl.h" | |
48 #include "ui.h" | |
49 | |
50 | |
51 void | |
52 gaim_setup_imhtml(GtkWidget *imhtml) | |
53 { | |
54 g_return_if_fail(imhtml != NULL); | |
55 g_return_if_fail(GTK_IS_IMHTML(imhtml)); | |
56 | |
57 if (!(convo_options & OPT_CONVO_SHOW_SMILEY)) | |
58 gtk_imhtml_show_smileys(GTK_IMHTML(imhtml), FALSE); | |
59 | |
60 g_signal_connect(G_OBJECT(imhtml), "url_clicked", | |
61 G_CALLBACK(open_url), NULL); | |
62 | |
63 smiley_themeize(imhtml); | |
64 } | |
65 | |
66 void | |
67 toggle_sensitive(GtkWidget *widget, GtkWidget *to_toggle) | |
68 { | |
69 gboolean sensitivity = GTK_WIDGET_IS_SENSITIVE(to_toggle); | |
70 | |
71 gtk_widget_set_sensitive(to_toggle, !sensitivity); | |
72 } | |
73 | |
74 static void | |
75 gaim_gtk_remove_tags(struct gaim_gtk_conversation *gtkconv, const char *tag) | |
76 { | |
77 GtkTextIter start, end, m_start, m_end; | |
78 | |
79 if (gtkconv == NULL || tag == NULL) | |
80 return; | |
81 | |
82 if (!gtk_text_buffer_get_selection_bounds(gtkconv->entry_buffer, | |
83 &start, &end)) | |
84 return; | |
85 | |
86 /* FIXMEif (strstr(tag, "<FONT SIZE=")) { | |
87 while ((t = strstr(t, "<FONT SIZE="))) { | |
88 if (((t - s) < finish) && ((t - s) >= start)) { | |
89 gtk_editable_delete_text(GTK_EDITABLE(entry), (t - s), | |
90 (t - s) + strlen(tag)); | |
91 g_free(s); | |
92 s = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1); | |
93 t = s; | |
94 } else | |
95 t++; | |
96 } | |
97 } else*/ { | |
98 while (gtk_text_iter_forward_search(&start, tag, 0, &m_start, | |
99 &m_end, &end)) { | |
100 | |
101 gtk_text_buffer_delete(gtkconv->entry_buffer, &m_start, &m_end); | |
102 gtk_text_buffer_get_selection_bounds(gtkconv->entry_buffer, | |
103 &start, &end); | |
104 } | |
105 } | |
106 } | |
107 | |
108 void | |
109 gaim_gtk_surround(struct gaim_gtk_conversation *gtkconv, | |
110 const char *pre, const char *post) | |
111 { | |
112 GtkTextIter start, end; | |
113 GtkTextMark *mark_start, *mark_end; | |
114 GtkTextBuffer *entry_buffer; | |
115 | |
116 if (gtkconv == NULL || pre == NULL || post == NULL) | |
117 return; | |
118 | |
119 entry_buffer = gtkconv->entry_buffer; | |
120 | |
121 if (gtk_text_buffer_get_selection_bounds(entry_buffer, | |
122 &start, &end)) { | |
123 gaim_gtk_remove_tags(gtkconv, pre); | |
124 gaim_gtk_remove_tags(gtkconv, post); | |
125 | |
126 mark_start = gtk_text_buffer_create_mark(entry_buffer, "m1", | |
127 &start, TRUE); | |
128 mark_end = gtk_text_buffer_create_mark(entry_buffer, "m2", | |
129 &end, FALSE); | |
130 gtk_text_buffer_insert(entry_buffer, &start, pre, -1); | |
131 gtk_text_buffer_get_selection_bounds(entry_buffer, &start, &end); | |
132 gtk_text_buffer_insert(entry_buffer, &end, post, -1); | |
133 gtk_text_buffer_get_iter_at_mark(entry_buffer, &start, mark_start); | |
134 gtk_text_buffer_move_mark_by_name(entry_buffer, "selection_bound", | |
135 &start); | |
136 } else { | |
137 gtk_text_buffer_insert(entry_buffer, &start, pre, -1); | |
138 gtk_text_buffer_insert(entry_buffer, &start, post, -1); | |
139 mark_start = gtk_text_buffer_get_insert(entry_buffer); | |
140 gtk_text_buffer_get_iter_at_mark(entry_buffer, &start, mark_start); | |
141 gtk_text_iter_backward_chars(&start, strlen(post)); | |
142 gtk_text_buffer_place_cursor(entry_buffer, &start); | |
143 } | |
144 | |
145 gtk_widget_grab_focus(gtkconv->entry); | |
146 } | |
147 | |
148 static gboolean | |
149 invert_tags(GtkTextBuffer *buffer, const char *s1, const char *s2, | |
150 gboolean really) | |
151 { | |
152 GtkTextIter start1, start2, end1, end2; | |
153 char *b1, *b2; | |
154 | |
155 if (gtk_text_buffer_get_selection_bounds(buffer, &start1, &end2)) { | |
156 start2 = start1; | |
157 end1 = end2; | |
158 | |
159 if (!gtk_text_iter_forward_chars(&start2, strlen(s1))) | |
160 return FALSE; | |
161 | |
162 if (!gtk_text_iter_backward_chars(&end1, strlen(s2))) | |
163 return FALSE; | |
164 | |
165 b1 = gtk_text_buffer_get_text(buffer, &start1, &start2, FALSE); | |
166 b2 = gtk_text_buffer_get_text(buffer, &end1, &end2, FALSE); | |
167 | |
168 if (!g_strncasecmp(b1, s1, strlen(s1)) && | |
169 !g_strncasecmp(b2, s2, strlen(s2))) { | |
170 | |
171 if (really) { | |
172 GtkTextMark *m_end1, *m_end2; | |
173 | |
174 m_end1= gtk_text_buffer_create_mark(buffer, "m1", &end1, TRUE); | |
175 m_end2= gtk_text_buffer_create_mark(buffer, "m2", &end2, TRUE); | |
176 | |
177 gtk_text_buffer_delete(buffer, &start1, &start2); | |
178 gtk_text_buffer_get_iter_at_mark(buffer, &end1, m_end1); | |
179 gtk_text_buffer_get_iter_at_mark(buffer, &end2, m_end2); | |
180 gtk_text_buffer_delete(buffer, &end1, &end2); | |
181 gtk_text_buffer_delete_mark(buffer, m_end1); | |
182 gtk_text_buffer_delete_mark(buffer, m_end2); | |
183 } | |
184 | |
185 g_free(b1); | |
186 g_free(b2); | |
187 | |
188 return TRUE; | |
189 } | |
190 | |
191 g_free(b1); | |
192 g_free(b2); | |
193 } | |
194 | |
195 return FALSE; | |
196 } | |
197 | |
198 void | |
199 gaim_gtk_advance_past(struct gaim_gtk_conversation *gtkconv, | |
200 const char *pre, const char *post) | |
201 { | |
202 GtkTextIter current_pos, start, end; | |
203 | |
204 if (invert_tags(gtkconv->entry_buffer, pre, post, TRUE)) | |
205 return; | |
206 | |
207 gtk_text_buffer_get_iter_at_mark(gtkconv->entry_buffer, ¤t_pos, | |
208 gtk_text_buffer_get_insert(gtkconv->entry_buffer)); | |
209 | |
210 if (gtk_text_iter_forward_search(¤t_pos, post, 0, | |
211 &start, &end, NULL)) | |
212 gtk_text_buffer_place_cursor(gtkconv->entry_buffer, &end); | |
213 else | |
214 gtk_text_buffer_insert_at_cursor(gtkconv->entry_buffer, post, -1); | |
215 | |
216 gtk_widget_grab_focus(gtkconv->entry); | |
217 } | |
218 | |
219 void | |
220 gaim_gtk_set_font_face(struct gaim_gtk_conversation *gtkconv, | |
221 const char *font) | |
222 { | |
223 char *pre_fontface; | |
224 | |
225 if (gtkconv == NULL || font == NULL) | |
226 return; | |
227 | |
228 strncpy(gtkconv->fontface, | |
229 (font && *font ? font : DEFAULT_FONT_FACE), | |
230 sizeof(gtkconv->fontface)); | |
231 | |
232 gtkconv->has_font = TRUE; | |
233 | |
234 pre_fontface = g_strconcat("<FONT FACE=\"", | |
235 gtkconv->fontface, "\">", NULL); | |
236 gaim_gtk_surround(gtkconv, pre_fontface, "</FONT>"); | |
237 | |
238 gtk_widget_grab_focus(gtkconv->entry); | |
239 | |
240 g_free(pre_fontface); | |
241 } | |
242 | |
243 static int | |
244 des_save_icon(GtkObject *obj, GdkEvent *e, | |
245 struct gaim_gtk_conversation *gtkconv) | |
246 { | |
247 gtk_widget_destroy(gtkconv->u.im->save_icon); | |
248 gtkconv->u.im->save_icon = NULL; | |
249 | |
250 return TRUE; | |
251 } | |
252 | |
253 static void | |
254 do_save_icon(GtkObject *obj, struct gaim_conversation *c) | |
255 { | |
256 struct gaim_gtk_conversation *gtkconv; | |
257 FILE *file; | |
258 const char *f; | |
259 | |
260 gtkconv = GAIM_GTK_CONVERSATION(c); | |
261 | |
262 f = gtk_file_selection_get_filename( | |
263 GTK_FILE_SELECTION(gtkconv->u.im->save_icon)); | |
264 | |
265 if (file_is_dir(f, gtkconv->u.im->save_icon)) | |
266 return; | |
267 | |
268 if ((file = fopen(f, "w")) != NULL) { | |
269 int len; | |
270 void *data = get_icon_data(gaim_conversation_get_gc(c), | |
271 normalize(gaim_conversation_get_name(c)), | |
272 &len); | |
273 | |
274 if (data) | |
275 fwrite(data, 1, len, file); | |
276 | |
277 fclose(file); | |
278 } else { | |
279 do_error_dialog("Can't save icon file to disk", | |
280 strerror(errno), GAIM_ERROR); | |
281 } | |
282 | |
283 gtk_widget_destroy(gtkconv->u.im->save_icon); | |
284 gtkconv->u.im->save_icon = NULL; | |
285 } | |
286 | |
287 static void | |
288 cancel_save_icon(GtkObject *obj, struct gaim_gtk_conversation *gtkconv) | |
289 { | |
290 gtk_widget_destroy(gtkconv->u.im->save_icon); | |
291 gtkconv->u.im->save_icon = NULL; | |
292 } | |
293 | |
294 | |
295 void | |
296 gaim_gtk_save_icon_dialog(GtkObject *obj, struct gaim_conversation *conv) | |
297 { | |
298 struct gaim_gtk_conversation *gtkconv; | |
299 char buf[BUF_LEN]; | |
300 | |
301 if (conv == NULL || gaim_conversation_get_type(conv) != GAIM_CONV_IM) | |
302 return; | |
303 | |
4398
a8249a5250b6
[gaim-migrate @ 4667]
Christian Hammond <chipx86@chipx86.com>
parents:
4359
diff
changeset
|
304 if (!GAIM_IS_GTK_CONVERSATION(conv)) |
4359 | 305 return; |
306 | |
307 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
308 | |
309 if (gtkconv->u.im->save_icon != NULL) | |
310 { | |
311 gdk_window_raise(gtkconv->u.im->save_icon->window); | |
312 return; | |
313 } | |
314 | |
315 gtkconv->u.im->save_icon = gtk_file_selection_new(_("Gaim - Save Icon")); | |
316 | |
317 gtk_file_selection_hide_fileop_buttons( | |
318 GTK_FILE_SELECTION(gtkconv->u.im->save_icon)); | |
319 | |
320 g_snprintf(buf, BUF_LEN - 1, | |
321 "%s" G_DIR_SEPARATOR_S "%s.icon", | |
322 gaim_home_dir(), gaim_conversation_get_name(conv)); | |
323 | |
324 gtk_file_selection_set_filename( | |
325 GTK_FILE_SELECTION(gtkconv->u.im->save_icon), buf); | |
326 | |
327 g_signal_connect(GTK_OBJECT(gtkconv->u.im->save_icon), "delete_event", | |
328 G_CALLBACK(des_save_icon), gtkconv); | |
329 g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(gtkconv->u.im->save_icon)->ok_button), "clicked", | |
330 G_CALLBACK(do_save_icon), conv); | |
331 g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(gtkconv->u.im->save_icon)->cancel_button), "clicked", | |
332 G_CALLBACK(cancel_save_icon), gtkconv); | |
333 | |
334 gtk_widget_show(gtkconv->u.im->save_icon); | |
335 } | |
336 | |
337 int | |
338 gaim_gtk_get_dispstyle(GaimConversationType type) | |
339 { | |
340 int dispstyle = 2; | |
341 | |
342 if (type == GAIM_CONV_CHAT) { | |
343 switch (chat_options & (OPT_CHAT_BUTTON_TEXT | OPT_CHAT_BUTTON_XPM)) { | |
344 | |
345 case OPT_CHAT_BUTTON_TEXT: dispstyle = 1; break; | |
346 case OPT_CHAT_BUTTON_XPM: dispstyle = 0; break; | |
347 default: dispstyle = 2; break; /* both/neither */ | |
348 } | |
349 } | |
350 else if (type == GAIM_CONV_IM) { | |
351 switch (im_options & (OPT_IM_BUTTON_TEXT | OPT_IM_BUTTON_XPM)) { | |
352 | |
353 case OPT_IM_BUTTON_TEXT: dispstyle = 1; break; | |
354 case OPT_IM_BUTTON_XPM: dispstyle = 0; break; | |
355 default: dispstyle = 2; break; /* both/neither */ | |
356 } | |
357 } | |
358 | |
359 return dispstyle; | |
360 } | |
361 | |
362 GtkWidget * | |
363 gaim_gtk_change_text(const char *text, GtkWidget *button, | |
364 const char *stock, GaimConversationType type) | |
365 { | |
366 int dispstyle = gaim_gtk_get_dispstyle(type); | |
367 | |
368 if (button != NULL) | |
369 gtk_widget_destroy(button); | |
370 | |
371 button = gaim_pixbuf_button_from_stock((dispstyle == 0 ? NULL : text), | |
372 (dispstyle == 1 ? NULL : stock), | |
373 GAIM_BUTTON_VERTICAL); | |
374 | |
375 gtk_widget_show(button); | |
376 | |
377 return button; | |
378 } | |
379 | |
380 void | |
381 gaim_gtk_toggle_sensitive(GtkWidget *widget, GtkWidget *to_toggle) | |
382 { | |
383 gboolean sensitivity; | |
384 | |
385 if (to_toggle == NULL) | |
386 return; | |
387 | |
388 sensitivity = GTK_WIDGET_IS_SENSITIVE(to_toggle); | |
389 | |
390 gtk_widget_set_sensitive(to_toggle, !sensitivity); | |
391 } | |
392 | |
4687 | 393 void gaim_separator(GtkWidget *menu) |
394 { | |
395 GtkWidget *menuitem; | |
396 | |
397 menuitem = gtk_separator_menu_item_new(); | |
398 gtk_widget_show(menuitem); | |
399 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
400 } |