Mercurial > pidgin.yaz
annotate src/gtkhtml.c @ 914:215fe9039ae1
[gaim-migrate @ 924]
now i just need to do the same for pixmaps and we're set.
pixmaps are going to be harder to do though because we add the pixmaps, not gtkhtml, which means we're going to have to figure out what the font is supposed to be ourselves.
committer: Tailor Script <tailor@pidgin.im>
author | Eric Warmenhoven <eric@warmenhoven.org> |
---|---|
date | Fri, 15 Sep 2000 16:51:31 +0000 |
parents | 65c8bd1feec5 |
children | 5871e1eec10c |
rev | line source |
---|---|
12 | 1 |
1 | 2 /* |
3 * gaim | |
4 * | |
5 * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net> | |
6 * | |
7 * This program is free software; you can redistribute it and/or modify | |
8 * it under the terms of the GNU General Public License as published by | |
9 * the Free Software Foundation; either version 2 of the License, or | |
10 * (at your option) any later version. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, | |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 * GNU General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU General Public License | |
18 * along with this program; if not, write to the Free Software | |
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
20 * | |
21 */ | |
22 | |
349
b402a23f35df
[gaim-migrate @ 359]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
337
diff
changeset
|
23 #ifdef HAVE_CONFIG_H |
b402a23f35df
[gaim-migrate @ 359]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
337
diff
changeset
|
24 #include "../config.h" |
b402a23f35df
[gaim-migrate @ 359]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
337
diff
changeset
|
25 #endif |
1 | 26 #include <stdio.h> |
27 #include <stdlib.h> | |
28 #include <string.h> | |
29 #include <gtk/gtk.h> | |
30 #include <gdk/gdkprivate.h> | |
31 #include <gdk/gdkx.h> | |
32 #include <gdk/gdkkeysyms.h> | |
604
0b1a132e0f75
[gaim-migrate @ 614]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
574
diff
changeset
|
33 #include <ctype.h> |
12 | 34 |
35 #ifndef _WIN32 | |
1 | 36 #include <X11/Xlib.h> |
37 #include <X11/Xatom.h> | |
12 | 38 #endif |
39 | |
69 | 40 #include "gaim.h" |
1 | 41 #include "gtkhtml.h" |
42 | |
549 | 43 #include "pixmaps/aol_icon.xpm" |
44 #include "pixmaps/admin_icon.xpm" | |
45 #include "pixmaps/free_icon.xpm" | |
46 #include "pixmaps/dt_icon.xpm" | |
1 | 47 #define MAX_SIZE 7 |
48 #define MIN_HTML_WIDTH_LINES 20 | |
49 #define MIN_HTML_HEIGHT_LINES 10 | |
50 #define BORDER_WIDTH 2 | |
51 #define SCROLL_TIME 100 | |
52 #define SCROLL_PIXELS 5 | |
53 #define KEY_SCROLL_PIXELS 10 | |
54 | |
55 int font_sizes[] = { 80, 100, 120, 140, 200, 300, 400 }; | |
56 | |
12 | 57 /* |
1 | 58 GdkFont *fixed_font[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; |
59 GdkFont *fixed_bold_font[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; | |
60 GdkFont *fixed_italic_font[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; | |
12 | 61 GdkFont *fixed_bold_italic_font[] = |
62 { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; | |
1 | 63 GdkFont *prop_font[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; |
64 GdkFont *prop_bold_font[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; | |
65 GdkFont *prop_italic_font[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; | |
66 GdkFont *prop_bold_italic_font[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; | |
12 | 67 */ |
68 | |
69 GData * font_cache; | |
70 static gboolean cache_init = FALSE; | |
71 | |
72 struct font_state | |
73 { | |
74 int size; | |
75 int owncolor; | |
76 int ownbg; | |
77 gchar font[1024]; | |
78 GdkColor *color; | |
79 GdkColor *bgcol; | |
80 struct font_state *next; | |
1 | 81 }; |
82 | |
83 struct font_state *push_state(struct font_state *current) | |
84 { | |
12 | 85 struct font_state *tmp; |
86 tmp = (struct font_state *) g_new0(struct font_state, 1); | |
1 | 87 tmp->next = current; |
88 tmp->color = current->color; | |
89 tmp->bgcol = current->bgcol; | |
90 tmp->size = current->size; | |
91 tmp->owncolor = 0; | |
92 tmp->ownbg = 0; | |
12 | 93 strcpy( tmp->font, current->font ); |
1 | 94 return tmp; |
95 } | |
96 | |
12 | 97 enum |
98 { | |
99 ARG_0, | |
100 ARG_HADJUSTMENT, | |
101 ARG_VADJUSTMENT, | |
1 | 102 }; |
103 | |
104 | |
12 | 105 enum |
106 { | |
107 TARGET_STRING, | |
108 TARGET_TEXT, | |
109 TARGET_COMPOUND_TEXT | |
1 | 110 }; |
111 | |
112 | |
12 | 113 static void gtk_html_class_init(GtkHtmlClass * klass); |
114 static void gtk_html_set_arg(GtkObject * object, GtkArg * arg, guint arg_id); | |
115 static void gtk_html_get_arg(GtkObject * object, GtkArg * arg, guint arg_id); | |
116 static void gtk_html_init(GtkHtml * html); | |
117 static void gtk_html_destroy(GtkObject * object); | |
118 static void gtk_html_finalize(GtkObject * object); | |
119 static void gtk_html_realize(GtkWidget * widget); | |
120 static void gtk_html_unrealize(GtkWidget * widget); | |
121 static void gtk_html_style_set(GtkWidget * widget, GtkStyle * previous_style); | |
122 static void gtk_html_draw_focus(GtkWidget * widget); | |
123 static void gtk_html_size_request(GtkWidget * widget, | |
124 GtkRequisition * requisition); | |
125 static void gtk_html_size_allocate(GtkWidget * widget, | |
126 GtkAllocation * allocation); | |
127 static void gtk_html_adjustment(GtkAdjustment * adjustment, GtkHtml * html); | |
128 static void gtk_html_disconnect(GtkAdjustment * adjustment, GtkHtml * html); | |
914
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
129 static void gtk_html_add_seperator(GtkHtml *, GdkFont *, GdkColor *, GdkColor *); |
337 | 130 // static void gtk_html_add_pixmap(GtkHtml * html, GdkPixmap * pm, gint fit); |
12 | 131 static void gtk_html_add_text(GtkHtml * html, |
132 GdkFont * font, | |
133 GdkColor * fore, | |
134 GdkColor * back, | |
135 gchar * chars, | |
136 gint length, | |
137 gint uline, gint strike, gchar * url); | |
138 static void gtk_html_draw_bit(GtkHtml * html, | |
139 GtkHtmlBit * htmlbit, gint redraw); | |
140 static void gtk_html_selection_get(GtkWidget * widget, | |
141 GtkSelectionData * selection_data, | |
142 guint sel_info, guint32 time); | |
143 static gint gtk_html_selection_clear(GtkWidget * widget, | |
144 GdkEventSelection * event); | |
145 static gint gtk_html_visibility_notify(GtkWidget * widget, | |
146 GdkEventVisibility * event); | |
1 | 147 |
148 | |
149 /* Event handlers */ | |
12 | 150 static void gtk_html_draw(GtkWidget * widget, GdkRectangle * area); |
151 static gint gtk_html_expose(GtkWidget * widget, GdkEventExpose * event); | |
152 static gint gtk_html_button_press(GtkWidget * widget, GdkEventButton * event); | |
153 static gint gtk_html_button_release(GtkWidget * widget, GdkEventButton * event); | |
154 static gint gtk_html_motion_notify(GtkWidget * widget, GdkEventMotion * event); | |
155 static gint gtk_html_key_press(GtkWidget * widget, GdkEventKey * event); | |
156 static gint gtk_html_leave_notify(GtkWidget * widget, GdkEventCrossing * event); | |
1 | 157 |
158 static gint gtk_html_tooltip_timeout(gpointer data); | |
159 | |
160 | |
12 | 161 static void clear_area(GtkHtml * html, GdkRectangle * area); |
162 static void expose_html(GtkHtml * html, GdkRectangle * area, gboolean cursor); | |
163 static void scroll_down(GtkHtml * html, gint diff0); | |
164 static void scroll_up(GtkHtml * html, gint diff0); | |
165 | |
166 static void adjust_adj(GtkHtml * html, GtkAdjustment * adj); | |
167 static void resize_html(GtkHtml * html); | |
168 static gint html_bit_is_onscreen(GtkHtml * html, GtkHtmlBit * hb); | |
169 static void draw_cursor(GtkHtml * html); | |
170 static void undraw_cursor(GtkHtml * html); | |
1 | 171 |
895 | 172 static int get_line_height(GtkHtml *, GtkHtmlBit *); |
173 | |
1 | 174 static GtkWidgetClass *parent_class = NULL; |
175 | |
176 GtkType gtk_html_get_type(void) | |
177 { | |
12 | 178 static GtkType html_type = 0; |
179 | |
180 if (!html_type) | |
181 { | |
182 static const GtkTypeInfo html_info = { | |
183 "GtkHtml", | |
184 sizeof(GtkHtml), | |
185 sizeof(GtkHtmlClass), | |
186 (GtkClassInitFunc) gtk_html_class_init, | |
187 (GtkObjectInitFunc) gtk_html_init, | |
188 NULL, | |
189 NULL, | |
190 NULL, | |
191 }; | |
192 html_type = gtk_type_unique(GTK_TYPE_WIDGET, &html_info); | |
193 } | |
194 return html_type; | |
1 | 195 } |
196 | |
197 | |
12 | 198 static void gtk_html_class_init(GtkHtmlClass * class) |
1 | 199 { |
12 | 200 GtkObjectClass *object_class; |
201 GtkWidgetClass *widget_class; | |
202 | |
203 object_class = (GtkObjectClass *) class; | |
204 widget_class = (GtkWidgetClass *) class; | |
205 parent_class = gtk_type_class(GTK_TYPE_WIDGET); | |
206 | |
207 | |
208 gtk_object_add_arg_type("GtkHtml::hadjustment", | |
209 GTK_TYPE_ADJUSTMENT, | |
210 GTK_ARG_READWRITE | GTK_ARG_CONSTRUCT, | |
211 ARG_HADJUSTMENT); | |
212 | |
213 gtk_object_add_arg_type("GtkHtml::vadjustment", | |
214 GTK_TYPE_ADJUSTMENT, | |
215 GTK_ARG_READWRITE | GTK_ARG_CONSTRUCT, | |
216 ARG_VADJUSTMENT); | |
217 | |
218 object_class->set_arg = gtk_html_set_arg; | |
219 object_class->get_arg = gtk_html_get_arg; | |
220 object_class->destroy = gtk_html_destroy; | |
221 object_class->finalize = gtk_html_finalize; | |
222 | |
223 widget_class->realize = gtk_html_realize; | |
224 widget_class->unrealize = gtk_html_unrealize; | |
225 widget_class->style_set = gtk_html_style_set; | |
226 widget_class->draw_focus = gtk_html_draw_focus; | |
227 widget_class->size_request = gtk_html_size_request; | |
228 widget_class->size_allocate = gtk_html_size_allocate; | |
229 widget_class->draw = gtk_html_draw; | |
230 widget_class->expose_event = gtk_html_expose; | |
231 widget_class->button_press_event = gtk_html_button_press; | |
232 widget_class->button_release_event = gtk_html_button_release; | |
1 | 233 widget_class->motion_notify_event = gtk_html_motion_notify; |
234 widget_class->leave_notify_event = gtk_html_leave_notify; | |
12 | 235 widget_class->selection_get = gtk_html_selection_get; |
1 | 236 widget_class->selection_clear_event = gtk_html_selection_clear; |
237 widget_class->key_press_event = gtk_html_key_press; | |
238 widget_class->visibility_notify_event = gtk_html_visibility_notify; | |
12 | 239 |
240 | |
241 widget_class->set_scroll_adjustments_signal = | |
242 gtk_signal_new("set_scroll_adjustments", | |
243 GTK_RUN_LAST, | |
244 object_class->type, | |
245 GTK_SIGNAL_OFFSET(GtkHtmlClass, set_scroll_adjustments), | |
246 gtk_marshal_NONE__POINTER_POINTER, | |
247 GTK_TYPE_NONE, 2, GTK_TYPE_ADJUSTMENT, | |
248 GTK_TYPE_ADJUSTMENT); | |
249 | |
250 | |
251 class->set_scroll_adjustments = gtk_html_set_adjustments; | |
1 | 252 |
253 } | |
254 | |
12 | 255 static void gtk_html_set_arg(GtkObject * object, GtkArg * arg, guint arg_id) |
1 | 256 { |
12 | 257 GtkHtml *html; |
258 | |
259 html = GTK_HTML(object); | |
260 | |
261 switch (arg_id) | |
262 { | |
263 case ARG_HADJUSTMENT: | |
264 gtk_html_set_adjustments(html, GTK_VALUE_POINTER(*arg), html->vadj); | |
265 break; | |
266 case ARG_VADJUSTMENT: | |
267 gtk_html_set_adjustments(html, html->hadj, GTK_VALUE_POINTER(*arg)); | |
268 break; | |
269 default: | |
270 break; | |
271 } | |
1 | 272 } |
273 | |
12 | 274 static void gtk_html_get_arg(GtkObject * object, GtkArg * arg, guint arg_id) |
1 | 275 { |
12 | 276 GtkHtml *html; |
277 | |
278 html = GTK_HTML(object); | |
279 | |
280 switch (arg_id) | |
281 { | |
282 case ARG_HADJUSTMENT: | |
283 GTK_VALUE_POINTER(*arg) = html->hadj; | |
284 break; | |
285 case ARG_VADJUSTMENT: | |
286 GTK_VALUE_POINTER(*arg) = html->vadj; | |
287 break; | |
288 default: | |
289 arg->type = GTK_TYPE_INVALID; | |
290 break; | |
291 } | |
1 | 292 } |
293 | |
12 | 294 static void gtk_html_init(GtkHtml * html) |
1 | 295 { |
12 | 296 static const GtkTargetEntry targets[] = { |
297 {"STRING", 0, TARGET_STRING}, | |
298 {"TEXT", 0, TARGET_TEXT}, | |
299 {"COMPOUND_TEXT", 0, TARGET_COMPOUND_TEXT} | |
300 }; | |
301 | |
302 static const gint n_targets = sizeof(targets) / sizeof(targets[0]); | |
303 | |
304 GTK_WIDGET_SET_FLAGS(html, GTK_CAN_FOCUS); | |
305 | |
306 html->html_area = NULL; | |
307 html->hadj = NULL; | |
308 html->vadj = NULL; | |
1 | 309 html->current_x = 0; |
310 html->current_y = 0; | |
12 | 311 html->start_sel = html->end_sel = NULL; |
312 html->start_sel_x = html->start_sel_y = -1; | |
313 html->num_end = html->num_start = -1; | |
314 | |
1 | 315 html->html_bits = NULL; |
316 html->urls = NULL; | |
317 html->selected_text = NULL; | |
318 html->tooltip_hb = NULL; | |
319 html->tooltip_timer = -1; | |
320 html->tooltip_window = NULL; | |
12 | 321 html->cursor_hb = NULL; |
1 | 322 html->cursor_pos = 0; |
323 | |
324 html->pm = NULL; | |
325 | |
326 html->editable = 0; | |
327 html->transparent = 0; | |
328 | |
12 | 329 html->frozen = 0; |
330 | |
331 gtk_selection_add_targets(GTK_WIDGET(html), GDK_SELECTION_PRIMARY, | |
332 targets, n_targets); | |
333 | |
334 | |
335 | |
1 | 336 } |
337 | |
338 | |
12 | 339 GtkWidget *gtk_html_new(GtkAdjustment * hadj, GtkAdjustment * vadj) |
1 | 340 { |
12 | 341 GtkWidget *html; |
342 if(!cache_init) | |
343 { | |
344 g_datalist_init(&font_cache); | |
345 cache_init = TRUE; | |
346 } | |
347 | |
348 if (hadj) | |
349 g_return_val_if_fail(GTK_IS_ADJUSTMENT(hadj), NULL); | |
350 if (vadj) | |
351 g_return_val_if_fail(GTK_IS_ADJUSTMENT(vadj), NULL); | |
352 | |
353 html = gtk_widget_new(GTK_TYPE_HTML, | |
354 "hadjustment", hadj, "vadjustment", vadj, NULL); | |
355 | |
356 return html; | |
1 | 357 } |
358 | |
359 | |
12 | 360 void gtk_html_set_editable(GtkHtml * html, gboolean is_editable) |
1 | 361 { |
12 | 362 g_return_if_fail(html != NULL); |
363 g_return_if_fail(GTK_IS_HTML(html)); | |
364 | |
365 | |
366 html->editable = (is_editable != FALSE); | |
367 | |
368 if (is_editable) | |
369 draw_cursor(html); | |
370 else | |
371 undraw_cursor(html); | |
1 | 372 |
373 } | |
374 | |
12 | 375 void gtk_html_set_transparent(GtkHtml * html, gboolean is_transparent) |
1 | 376 { |
12 | 377 GdkRectangle rect; |
378 gint width, | |
379 height; | |
380 GtkWidget *widget; | |
381 | |
382 g_return_if_fail(html != NULL); | |
383 g_return_if_fail(GTK_IS_HTML(html)); | |
384 | |
385 | |
386 widget = GTK_WIDGET(html); | |
387 html->transparent = (is_transparent != FALSE); | |
388 | |
389 if (!GTK_WIDGET_REALIZED(widget)) | |
390 return; | |
391 | |
392 html->bg_gc = NULL; | |
393 gdk_window_get_size(widget->window, &width, &height); | |
394 rect.x = 0; | |
395 rect.y = 0; | |
396 rect.width = width; | |
397 rect.height = height; | |
398 gdk_window_clear_area(widget->window, rect.x, rect.y, rect.width, | |
399 rect.height); | |
400 | |
401 expose_html(html, &rect, FALSE); | |
402 gtk_html_draw_focus((GtkWidget *) html); | |
1 | 403 } |
404 | |
405 | |
12 | 406 void gtk_html_set_adjustments(GtkHtml * html, |
407 GtkAdjustment * hadj, GtkAdjustment * vadj) | |
1 | 408 { |
12 | 409 g_return_if_fail(html != NULL); |
410 g_return_if_fail(GTK_IS_HTML(html)); | |
411 if (hadj) | |
412 g_return_if_fail(GTK_IS_ADJUSTMENT(hadj)); | |
413 else | |
414 hadj = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)); | |
415 if (vadj) | |
416 g_return_if_fail(GTK_IS_ADJUSTMENT(vadj)); | |
417 else | |
418 vadj = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)); | |
419 | |
420 if (html->hadj && (html->hadj != hadj)) | |
421 { | |
422 gtk_signal_disconnect_by_data(GTK_OBJECT(html->hadj), html); | |
423 gtk_object_unref(GTK_OBJECT(html->hadj)); | |
424 } | |
425 | |
426 if (html->vadj && (html->vadj != vadj)) | |
427 { | |
428 gtk_signal_disconnect_by_data(GTK_OBJECT(html->vadj), html); | |
429 gtk_object_unref(GTK_OBJECT(html->vadj)); | |
430 } | |
431 | |
432 if (html->hadj != hadj) | |
433 { | |
434 html->hadj = hadj; | |
435 gtk_object_ref(GTK_OBJECT(html->hadj)); | |
436 gtk_object_sink(GTK_OBJECT(html->hadj)); | |
437 | |
438 gtk_signal_connect(GTK_OBJECT(html->hadj), "changed", | |
439 (GtkSignalFunc) gtk_html_adjustment, html); | |
440 gtk_signal_connect(GTK_OBJECT(html->hadj), "value_changed", | |
441 (GtkSignalFunc) gtk_html_adjustment, html); | |
442 gtk_signal_connect(GTK_OBJECT(html->hadj), "disconnect", | |
443 (GtkSignalFunc) gtk_html_disconnect, html); | |
444 gtk_html_adjustment(hadj, html); | |
445 } | |
446 | |
447 if (html->vadj != vadj) | |
448 { | |
449 html->vadj = vadj; | |
450 gtk_object_ref(GTK_OBJECT(html->vadj)); | |
451 gtk_object_sink(GTK_OBJECT(html->vadj)); | |
452 | |
453 gtk_signal_connect(GTK_OBJECT(html->vadj), "changed", | |
454 (GtkSignalFunc) gtk_html_adjustment, html); | |
455 gtk_signal_connect(GTK_OBJECT(html->vadj), "value_changed", | |
456 (GtkSignalFunc) gtk_html_adjustment, html); | |
457 gtk_signal_connect(GTK_OBJECT(html->vadj), "disconnect", | |
458 (GtkSignalFunc) gtk_html_disconnect, html); | |
459 gtk_html_adjustment(vadj, html); | |
460 } | |
1 | 461 } |
462 | |
463 | |
464 | |
12 | 465 GdkColor *get_color(int colorv, GdkColormap * map) |
1 | 466 { |
467 GdkColor *color; | |
12 | 468 #if 0 |
469 fprintf(stdout, "color is %x\n", colorv); | |
470 #endif | |
471 color = (GdkColor *) g_new0(GdkColor, 1); | |
1 | 472 color->red = ((colorv & 0xff0000) >> 16) * 256; |
473 color->green = ((colorv & 0xff00) >> 8) * 256; | |
474 color->blue = ((colorv & 0xff)) * 256; | |
475 #if 0 | |
12 | 476 fprintf(stdout, "Colors are %d, %d, %d\n", color->red, color->green, |
477 color->blue); | |
1 | 478 #endif |
479 gdk_color_alloc(map, color); | |
480 return color; | |
481 } | |
482 | |
483 | |
286 | 484 int load_font_with_cache(const char *name, const char *weight, char slant, |
485 int size, GdkFont **font_return) | |
1 | 486 { |
286 | 487 gchar font_spec[1024]; |
488 | |
306
a8f964718837
[gaim-migrate @ 316]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
305
diff
changeset
|
489 if (size > 0) |
a8f964718837
[gaim-migrate @ 316]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
305
diff
changeset
|
490 g_snprintf(font_spec, sizeof font_spec, |
a8f964718837
[gaim-migrate @ 316]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
305
diff
changeset
|
491 "-*-%s-%s-%c-*-*-*-%d-*-*-*-*-*-*", |
a8f964718837
[gaim-migrate @ 316]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
305
diff
changeset
|
492 name, weight, slant, size); |
852
836d5a02a35c
[gaim-migrate @ 862]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
851
diff
changeset
|
493 else |
791
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
494 g_snprintf(font_spec, sizeof font_spec, |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
495 "-*-%s-%s-%c-*-*-*-*-*-*-*-*-*-*", |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
496 name, weight, slant); |
286 | 497 |
498 if((*font_return = g_datalist_id_get_data(&font_cache, | |
499 g_quark_from_string(font_spec)))) { | |
500 return TRUE; | |
501 } else if ((*font_return = gdk_font_load(font_spec))) { | |
502 g_datalist_id_set_data(&font_cache, | |
503 g_quark_from_string(font_spec), *font_return); | |
504 return TRUE; | |
505 } else { | |
506 return FALSE; | |
12 | 507 } |
286 | 508 } |
509 | |
510 | |
511 GdkFont *getfont(const char *font, int bold, int italic, int fixed, int size) | |
512 { | |
513 GdkFont *my_font = NULL; | |
514 gchar *weight, slant; | |
515 | |
516 if (!font || !strlen(font)) font = fixed ? "courier" : "helvetica"; | |
517 weight = bold ? "bold" : "medium"; | |
518 slant = italic ? 'i' : 'r'; | |
519 | |
520 if (size > MAX_SIZE) size = MAX_SIZE; | |
521 if (size < 1) size = 1; | |
522 size = font_sizes[size-1]; | |
523 | |
852
836d5a02a35c
[gaim-migrate @ 862]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
851
diff
changeset
|
524 /* try both 'i'talic and 'o'blique for italic fonts */ |
286 | 525 |
791
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
526 if (load_font_with_cache(font, weight, slant, size, &my_font)) |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
527 return my_font; |
852
836d5a02a35c
[gaim-migrate @ 862]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
851
diff
changeset
|
528 if (load_font_with_cache(font, weight, 'o', size, &my_font)) |
836d5a02a35c
[gaim-migrate @ 862]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
851
diff
changeset
|
529 return my_font; |
836d5a02a35c
[gaim-migrate @ 862]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
851
diff
changeset
|
530 if (italic && load_font_with_cache(font, weight, slant, 0, &my_font)) |
836d5a02a35c
[gaim-migrate @ 862]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
851
diff
changeset
|
531 return my_font; |
791
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
532 if (italic && load_font_with_cache(font, weight, 'o', 0, &my_font)) |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
533 return my_font; |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
534 |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
535 /* since we couldn't get the right font, fall back to the default fonts. */ |
286 | 536 |
537 font = fixed ? "courier" : "helvetica"; | |
791
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
538 if (load_font_with_cache(font, weight, slant, size, &my_font)) |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
539 return my_font; |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
540 if (load_font_with_cache(font, weight, slant, 0, &my_font)) |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
541 return my_font; |
305
77404a4692b1
[gaim-migrate @ 315]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
286
diff
changeset
|
542 |
77404a4692b1
[gaim-migrate @ 315]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
286
diff
changeset
|
543 font = fixed ? "helvetica" : "courier"; |
791
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
544 if (load_font_with_cache(font, weight, slant, size, &my_font)) |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
545 return my_font; |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
546 if (load_font_with_cache(font, weight, slant, 0, &my_font)) |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
547 return my_font; |
305
77404a4692b1
[gaim-migrate @ 315]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
286
diff
changeset
|
548 |
721
8e7ad10b5f26
[gaim-migrate @ 731]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
720
diff
changeset
|
549 /* whoops, couldn't do any of those. maybe they have a default outgoing |
8e7ad10b5f26
[gaim-migrate @ 731]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
720
diff
changeset
|
550 * font? maybe we can use that. */ |
8e7ad10b5f26
[gaim-migrate @ 731]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
720
diff
changeset
|
551 if (fontface[0]) { |
8e7ad10b5f26
[gaim-migrate @ 731]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
720
diff
changeset
|
552 /* woohoo! */ |
791
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
553 if (load_font_with_cache(fontface, "medium", 'r', size, &my_font)) |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
554 return my_font; |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
555 if (load_font_with_cache(fontface, "medium", 'r', 0, &my_font)) |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
556 return my_font; |
721
8e7ad10b5f26
[gaim-migrate @ 731]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
720
diff
changeset
|
557 } |
8e7ad10b5f26
[gaim-migrate @ 731]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
720
diff
changeset
|
558 |
305
77404a4692b1
[gaim-migrate @ 315]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
286
diff
changeset
|
559 /* ok, now we're in a pickle. if we can't do any of the above, let's |
77404a4692b1
[gaim-migrate @ 315]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
286
diff
changeset
|
560 * try doing the most boring font we can find. */ |
791
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
561 if (load_font_with_cache("helvetica", "medium", 'r', size, &my_font)) |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
562 return my_font; |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
563 if (load_font_with_cache("helvetica", "medium", 'r', 0, &my_font)) |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
564 return my_font; |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
565 |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
566 if (load_font_with_cache("courier", "medium", 'r', size, &my_font)) |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
567 return my_font; |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
568 if (load_font_with_cache("courier", "medium", 'r', 0, &my_font)) |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
569 return my_font; |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
570 |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
571 if (load_font_with_cache("times", "medium", 'r', size, &my_font)) |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
572 return my_font; |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
573 if (load_font_with_cache("times", "medium", 'r', 0, &my_font)) |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
574 return my_font; |
305
77404a4692b1
[gaim-migrate @ 315]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
286
diff
changeset
|
575 |
77404a4692b1
[gaim-migrate @ 315]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
286
diff
changeset
|
576 /* my god, how did we end up here. is there a 'generic font' function |
77404a4692b1
[gaim-migrate @ 315]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
286
diff
changeset
|
577 * in gdk? that would be incredibly useful here. there's gotta be a |
77404a4692b1
[gaim-migrate @ 315]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
286
diff
changeset
|
578 * better way to do this. */ |
77404a4692b1
[gaim-migrate @ 315]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
286
diff
changeset
|
579 |
306
a8f964718837
[gaim-migrate @ 316]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
305
diff
changeset
|
580 /* well, if they can't do any of the fonts above, they'll take whatever |
a8f964718837
[gaim-migrate @ 316]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
305
diff
changeset
|
581 * they can get, and be happy about it, damn it. :) */ |
852
836d5a02a35c
[gaim-migrate @ 862]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
851
diff
changeset
|
582 load_font_with_cache("*", "*", '*', 0, &my_font); |
306
a8f964718837
[gaim-migrate @ 316]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
305
diff
changeset
|
583 return my_font; |
1 | 584 } |
585 | |
586 | |
587 /* 'Borrowed' from ETerm */ | |
12 | 588 GdkWindow *get_desktop_window(GtkWidget * widget) |
1 | 589 { |
12 | 590 #ifndef _WIN32 |
591 GdkAtom prop, | |
592 type, | |
593 prop2; | |
594 int format; | |
595 gint length; | |
596 guchar *data; | |
1 | 597 GtkWidget *w; |
598 | |
12 | 599 prop = gdk_atom_intern("_XROOTPMAP_ID", 1); |
600 prop2 = gdk_atom_intern("_XROOTCOLOR_PIXEL", 1); | |
601 | |
602 if (prop == None && prop2 == None) | |
603 { | |
604 return NULL; | |
605 } | |
606 | |
607 | |
608 | |
609 for (w = widget; w; w = w->parent) | |
610 { | |
611 | |
612 if (prop != None) | |
613 { | |
1 | 614 gdk_property_get(w->window, prop, AnyPropertyType, 0L, 1L, 0, |
12 | 615 &type, &format, &length, &data); |
616 } | |
617 else if (prop2 != None) | |
618 { | |
1 | 619 gdk_property_get(w->window, prop2, AnyPropertyType, 0L, 1L, 0, |
12 | 620 &type, &format, &length, &data); |
621 } | |
622 else | |
623 { | |
1 | 624 continue; |
625 } | |
12 | 626 if (type != None) |
627 { | |
1 | 628 return (w->window); |
629 } | |
630 } | |
12 | 631 #endif |
1 | 632 return NULL; |
633 | |
634 } | |
635 | |
636 | |
637 | |
12 | 638 GdkPixmap *get_desktop_pixmap(GtkWidget * widget) |
1 | 639 { |
12 | 640 #ifndef _WIN32 |
641 GdkPixmap *p; | |
642 GdkAtom prop, | |
643 type, | |
644 prop2; | |
645 int format; | |
646 gint length; | |
647 guint32 id; | |
648 guchar *data; | |
649 | |
650 prop = gdk_atom_intern("_XROOTPMAP_ID", 1); | |
651 prop2 = gdk_atom_intern("_XROOTCOLOR_PIXEL", 1); | |
652 | |
653 | |
654 if (prop == None && prop2 == None) | |
655 { | |
656 return NULL; | |
657 } | |
658 | |
659 if (prop != None) | |
660 { | |
661 gdk_property_get(get_desktop_window(widget), prop, AnyPropertyType, 0L, | |
662 1L, 0, &type, &format, &length, &data); | |
663 if (type == XA_PIXMAP) | |
664 { | |
1 | 665 id = data[0]; |
666 id += data[1] << 8; | |
667 id += data[2] << 16; | |
668 id += data[3] << 24; | |
12 | 669 p = gdk_pixmap_foreign_new(id); |
670 return p; | |
671 } | |
672 } | |
673 if (prop2 != None) | |
674 { | |
675 | |
1 | 676 /* XGetWindowProperty(Xdisplay, desktop_window, prop2, 0L, 1L, False, AnyPropertyType, |
677 &type, &format, &length, &after, &data);*/ | |
12 | 678 |
1 | 679 /* if (type == XA_CARDINAL) {*/ |
12 | 680 /* |
681 * D_PIXMAP((" Solid color not yet supported.\n")); | |
682 */ | |
683 | |
1 | 684 /* return NULL; |
685 }*/ | |
12 | 686 } |
687 /* | |
688 * D_PIXMAP(("No suitable attribute found.\n")); | |
689 */ | |
690 #endif | |
691 return NULL; | |
1 | 692 } |
693 | |
694 | |
12 | 695 static void clear_focus_area(GtkHtml * html, |
696 gint area_x, | |
697 gint area_y, gint area_width, gint area_height) | |
1 | 698 { |
12 | 699 GtkWidget *widget = GTK_WIDGET(html); |
700 gint x, | |
701 y; | |
702 | |
703 gint ythick = BORDER_WIDTH + widget->style->klass->ythickness; | |
704 gint xthick = BORDER_WIDTH + widget->style->klass->xthickness; | |
705 | |
706 gint width, | |
707 height; | |
708 | |
709 if (html->frozen > 0) | |
710 return; | |
711 | |
712 if (html->transparent) | |
713 { | |
1 | 714 if (html->pm == NULL) |
715 html->pm = get_desktop_pixmap(widget); | |
716 | |
12 | 717 if (html->pm == NULL) |
718 return; | |
719 | |
720 if (html->bg_gc == NULL) | |
721 { | |
1 | 722 GdkGCValues values; |
723 | |
12 | 724 values.tile = html->pm; |
725 values.fill = GDK_TILED; | |
726 | |
727 html->bg_gc = gdk_gc_new_with_values(html->html_area, &values, | |
728 GDK_GC_FILL | GDK_GC_TILE); | |
729 | |
730 } | |
731 | |
732 gdk_window_get_deskrelative_origin(widget->window, &x, &y); | |
1 | 733 |
734 gdk_draw_pixmap(widget->window, html->bg_gc, html->pm, | |
12 | 735 x + area_x, y + area_y, area_x, area_y, area_width, |
736 area_height); | |
737 | |
738 | |
739 } | |
740 else | |
741 { | |
742 gdk_window_get_size(widget->style->bg_pixmap[GTK_STATE_NORMAL], &width, | |
743 &height); | |
744 | |
745 gdk_gc_set_ts_origin(html->bg_gc, | |
746 (-html->xoffset + xthick) % width, | |
747 (-html->yoffset + ythick) % height); | |
748 | |
749 gdk_draw_rectangle(widget->window, html->bg_gc, TRUE, | |
750 area_x, area_y, area_width, area_height); | |
751 } | |
1 | 752 } |
753 | |
12 | 754 static void gtk_html_draw_focus(GtkWidget * widget) |
1 | 755 { |
12 | 756 GtkHtml *html; |
757 gint width, | |
758 height; | |
759 gint x, | |
760 y; | |
761 | |
762 g_return_if_fail(widget != NULL); | |
763 g_return_if_fail(GTK_IS_HTML(widget)); | |
1 | 764 |
765 html = GTK_HTML(widget); | |
766 | |
12 | 767 if (GTK_WIDGET_DRAWABLE(widget)) |
768 { | |
769 gint ythick = widget->style->klass->ythickness; | |
770 gint xthick = widget->style->klass->xthickness; | |
771 gint xextra = BORDER_WIDTH; | |
772 gint yextra = BORDER_WIDTH; | |
773 | |
774 x = 0; | |
775 y = 0; | |
776 width = widget->allocation.width; | |
777 height = widget->allocation.height; | |
778 | |
779 if (GTK_WIDGET_HAS_FOCUS(widget)) | |
780 { | |
781 x += 1; | |
782 y += 1; | |
783 width -= 2; | |
784 height -= 2; | |
785 xextra -= 1; | |
786 yextra -= 1; | |
787 | |
788 gtk_paint_focus(widget->style, widget->window, | |
789 NULL, widget, "text", | |
790 0, 0, | |
791 widget->allocation.width - 1, | |
792 widget->allocation.height - 1); | |
793 } | |
794 | |
795 gtk_paint_shadow(widget->style, widget->window, | |
796 GTK_STATE_NORMAL, GTK_SHADOW_IN, | |
797 NULL, widget, "text", x, y, width, height); | |
798 | |
799 x += xthick; | |
800 y += ythick; | |
801 width -= 2 * xthick; | |
802 height -= 2 * ythick; | |
803 | |
804 | |
805 if (widget->style->bg_pixmap[GTK_STATE_NORMAL] || html->transparent) | |
806 { | |
807 /* | |
808 * top rect | |
809 */ | |
810 clear_focus_area(html, x, y, width, yextra); | |
811 /* | |
812 * left rect | |
813 */ | |
814 clear_focus_area(html, x, y + yextra, | |
815 xextra, y + height - 2 * yextra); | |
816 /* | |
817 * right rect | |
818 */ | |
819 clear_focus_area(html, x + width - xextra, y + yextra, | |
820 xextra, height - 2 * ythick); | |
821 /* | |
822 * bottom rect | |
823 */ | |
824 clear_focus_area(html, x, x + height - yextra, width, yextra); | |
825 } | |
826 } | |
1 | 827 } |
828 | |
12 | 829 static void gtk_html_size_request(GtkWidget * widget, |
830 GtkRequisition * requisition) | |
1 | 831 { |
12 | 832 gint xthickness; |
833 gint ythickness; | |
834 gint char_height; | |
835 gint char_width; | |
836 | |
837 g_return_if_fail(widget != NULL); | |
838 g_return_if_fail(GTK_IS_HTML(widget)); | |
839 g_return_if_fail(requisition != NULL); | |
840 | |
841 xthickness = widget->style->klass->xthickness + BORDER_WIDTH; | |
842 ythickness = widget->style->klass->ythickness + BORDER_WIDTH; | |
843 | |
844 char_height = MIN_HTML_HEIGHT_LINES * (widget->style->font->ascent + | |
845 widget->style->font->descent); | |
846 | |
847 char_width = MIN_HTML_WIDTH_LINES * (gdk_text_width(widget->style->font, | |
848 "ABCDEFGHIJKLMNOPQRSTUVWXYZ", | |
849 26) / 26); | |
850 | |
851 requisition->width = char_width + xthickness * 2; | |
852 requisition->height = char_height + ythickness * 2; | |
1 | 853 } |
854 | |
12 | 855 static void gtk_html_size_allocate(GtkWidget * widget, |
856 GtkAllocation * allocation) | |
1 | 857 { |
12 | 858 GtkHtml *html; |
859 | |
860 g_return_if_fail(widget != NULL); | |
861 g_return_if_fail(GTK_IS_HTML(widget)); | |
862 g_return_if_fail(allocation != NULL); | |
863 | |
864 html = GTK_HTML(widget); | |
865 | |
866 widget->allocation = *allocation; | |
867 if (GTK_WIDGET_REALIZED(widget)) | |
868 { | |
869 gdk_window_move_resize(widget->window, | |
870 allocation->x, allocation->y, | |
871 allocation->width, allocation->height); | |
872 | |
873 gdk_window_move_resize(html->html_area, | |
874 widget->style->klass->xthickness + BORDER_WIDTH, | |
875 widget->style->klass->ythickness + BORDER_WIDTH, | |
876 MAX(1, (gint) widget->allocation.width - | |
877 (gint) (widget->style->klass->xthickness + | |
878 (gint) BORDER_WIDTH) * 2), | |
879 MAX(1, (gint) widget->allocation.height - | |
880 (gint) (widget->style->klass->ythickness + | |
881 (gint) BORDER_WIDTH) * 2)); | |
882 | |
883 resize_html(html); | |
884 } | |
885 } | |
886 | |
887 static void gtk_html_draw(GtkWidget * widget, GdkRectangle * area) | |
888 { | |
889 g_return_if_fail(widget != NULL); | |
890 g_return_if_fail(GTK_IS_HTML(widget)); | |
891 g_return_if_fail(area != NULL); | |
892 | |
893 if (GTK_WIDGET_DRAWABLE(widget)) | |
894 { | |
895 expose_html(GTK_HTML(widget), area, TRUE); | |
896 gtk_widget_draw_focus(widget); | |
897 } | |
898 } | |
899 | |
900 | |
901 static gint gtk_html_expose(GtkWidget * widget, GdkEventExpose * event) | |
902 { | |
903 GtkHtml *html; | |
904 | |
905 g_return_val_if_fail(widget != NULL, FALSE); | |
906 g_return_val_if_fail(GTK_IS_HTML(widget), FALSE); | |
907 g_return_val_if_fail(event != NULL, FALSE); | |
908 | |
909 html = GTK_HTML(widget); | |
910 | |
911 if (event->window == html->html_area) | |
912 { | |
913 expose_html(html, &event->area, TRUE); | |
914 } | |
915 else if (event->count == 0) | |
916 { | |
917 gtk_widget_draw_focus(widget); | |
918 } | |
919 | |
920 return FALSE; | |
1 | 921 |
922 } | |
923 | |
924 | |
12 | 925 static gint gtk_html_selection_clear(GtkWidget * widget, |
926 GdkEventSelection * event) | |
1 | 927 { |
12 | 928 GtkHtml *html; |
929 | |
930 g_return_val_if_fail(widget != NULL, FALSE); | |
931 g_return_val_if_fail(GTK_IS_HTML(widget), FALSE); | |
932 g_return_val_if_fail(event != NULL, FALSE); | |
933 | |
934 /* | |
935 * Let the selection handling code know that the selection | |
936 * * has been changed, since we've overriden the default handler | |
937 */ | |
938 if (!gtk_selection_clear(widget, event)) | |
939 return FALSE; | |
940 | |
941 html = GTK_HTML(widget); | |
942 | |
943 if (event->selection == GDK_SELECTION_PRIMARY) | |
944 { | |
945 if (html->selected_text) | |
946 { | |
947 GList *hbits = html->html_bits; | |
948 GtkHtmlBit *hb; | |
949 | |
1 | 950 g_free(html->selected_text); |
951 html->selected_text = NULL; | |
952 html->start_sel = NULL; | |
953 html->end_sel = NULL; | |
954 html->num_start = 0; | |
955 html->num_end = 0; | |
12 | 956 while (hbits) |
957 { | |
958 hb = (GtkHtmlBit *) hbits->data; | |
1 | 959 if (hb->was_selected) |
960 gtk_html_draw_bit(html, hb, 1); | |
961 hbits = hbits->prev; | |
962 } | |
963 hbits = g_list_last(html->html_bits); | |
964 } | |
12 | 965 } |
966 | |
967 return TRUE; | |
1 | 968 } |
969 | |
970 | |
971 | |
12 | 972 static void gtk_html_selection_get(GtkWidget * widget, |
973 GtkSelectionData * selection_data, | |
974 guint sel_info, guint32 time) | |
1 | 975 { |
976 gchar *str; | |
12 | 977 gint len; |
978 GtkHtml *html; | |
979 | |
980 g_return_if_fail(widget != NULL); | |
981 g_return_if_fail(GTK_IS_HTML(widget)); | |
982 | |
983 html = GTK_HTML(widget); | |
984 | |
985 | |
1 | 986 if (selection_data->selection != GDK_SELECTION_PRIMARY) |
987 return; | |
988 | |
989 str = html->selected_text; | |
990 | |
991 if (!str) | |
992 return; | |
12 | 993 |
1 | 994 len = strlen(str); |
995 | |
12 | 996 if (sel_info == TARGET_STRING) |
997 { | |
1 | 998 gtk_selection_data_set(selection_data, |
12 | 999 GDK_SELECTION_TYPE_STRING, |
1000 8 * sizeof(gchar), (guchar *) str, len); | |
1001 } | |
1002 else if ((sel_info == TARGET_TEXT) || (sel_info == TARGET_COMPOUND_TEXT)) | |
1003 { | |
1 | 1004 guchar *text; |
1005 GdkAtom encoding; | |
1006 gint format; | |
1007 gint new_length; | |
1008 | |
12 | 1009 gdk_string_to_compound_text(str, &encoding, &format, &text, |
1010 &new_length); | |
1011 gtk_selection_data_set(selection_data, encoding, format, text, | |
1012 new_length); | |
1013 gdk_free_compound_text(text); | |
1 | 1014 } |
1015 | |
1016 | |
1017 | |
1018 } | |
1019 | |
12 | 1020 static void do_select(GtkHtml * html, int x, int y) |
1 | 1021 { |
1022 GList *hbits = g_list_last(html->html_bits); | |
12 | 1023 int epos, |
1024 spos; | |
1 | 1025 GtkHtmlBit *hb; |
12 | 1026 |
1 | 1027 if (!hbits) |
1028 return; | |
12 | 1029 |
1030 hb = (GtkHtmlBit *) hbits->data; | |
1031 | |
1032 while (hbits) | |
1033 { | |
1034 hb = (GtkHtmlBit *) hbits->data; | |
1035 if (hb->type == HTML_BIT_TEXT) | |
1 | 1036 break; |
1037 hbits = hbits->prev; | |
12 | 1038 } |
1039 | |
1 | 1040 if (!hb) |
12 | 1041 return; |
1042 | |
1043 | |
1044 if (y > hb->y) | |
1045 { | |
1 | 1046 html->num_end = strlen(hb->text) - 1; |
1047 html->end_sel = hb; | |
12 | 1048 } |
1049 else if (y < 0) | |
1050 { | |
1 | 1051 html->num_end = 0; |
12 | 1052 html->end_sel = (GtkHtmlBit *) html->html_bits->data; |
1053 } | |
1054 else | |
1055 while (hbits) | |
1056 { | |
1057 hb = (GtkHtmlBit *) hbits->data; | |
1058 if ((y < hb->y && y > (hb->y - hb->height)) && | |
1059 (x > hb->x + hb->width)) | |
1060 { | |
1061 if (hb->type != HTML_BIT_TEXT) | |
1062 { | |
1063 html->num_end = 0; | |
1064 html->end_sel = hb; | |
1065 break; | |
1066 } | |
1067 | |
1068 html->num_end = strlen(hb->text) - 1; | |
1 | 1069 html->end_sel = hb; |
1070 break; | |
1071 } | |
12 | 1072 else if ((x > hb->x && x < (hb->x + hb->width)) && |
1073 (y < hb->y && y > (hb->y - hb->height))) | |
1074 { | |
1075 int i, | |
1076 len; | |
1077 int w = x - hb->x; | |
1078 | |
1079 if (hb->type != HTML_BIT_TEXT) | |
1080 { | |
1081 html->num_end = 0; | |
1 | 1082 html->end_sel = hb; |
1083 break; | |
1084 } | |
12 | 1085 |
1086 len = strlen(hb->text); | |
1087 | |
1088 for (i = 1; i <= len; i++) | |
1089 { | |
1090 if (gdk_text_measure(hb->font, hb->text, i) > w) | |
1091 { | |
1092 html->num_end = i - 1; | |
1093 html->end_sel = hb; | |
1094 break; | |
1095 } | |
1096 } | |
1097 break; | |
1 | 1098 } |
12 | 1099 hbits = hbits->prev; |
1 | 1100 } |
1101 | |
1102 if (html->end_sel == NULL) | |
1103 return; | |
12 | 1104 if (html->start_sel == NULL) |
1105 { | |
1 | 1106 html->start_sel = html->end_sel; |
1107 html->num_start = html->num_end; | |
1108 } | |
12 | 1109 |
1 | 1110 epos = g_list_index(html->html_bits, html->end_sel); |
1111 spos = g_list_index(html->html_bits, html->start_sel); | |
1112 g_free(html->selected_text); | |
1113 html->selected_text = NULL; | |
1114 | |
12 | 1115 if (epos == spos) |
1116 { | |
1 | 1117 char *str; |
12 | 1118 if (html->start_sel->type != HTML_BIT_TEXT) |
1119 { | |
1 | 1120 html->selected_text = NULL; |
1121 return; | |
1122 } | |
12 | 1123 if (html->num_end == html->num_start) |
1124 { | |
1 | 1125 str = g_malloc(2); |
12 | 1126 if (strlen(html->start_sel->text)) |
1 | 1127 str[0] = html->start_sel->text[html->num_end]; |
1128 else | |
12 | 1129 str[0] = 0; |
1 | 1130 str[1] = 0; |
1131 gtk_html_draw_bit(html, html->start_sel, 0); | |
1132 html->selected_text = str; | |
12 | 1133 } |
1134 else | |
1135 { | |
79 | 1136 size_t st, |
12 | 1137 en; |
1 | 1138 char *str; |
12 | 1139 if (html->num_end > html->num_start) |
1140 { | |
1 | 1141 en = html->num_end; |
1142 st = html->num_start; | |
12 | 1143 } |
1144 else | |
1145 { | |
1 | 1146 en = html->num_start; |
1147 st = html->num_end; | |
1148 } | |
1149 | |
1150 str = g_malloc(en - st + 2); | |
1151 strncpy(str, html->start_sel->text + st, (en - st + 1)); | |
1152 str[en - st + 1] = 0; | |
12 | 1153 gtk_html_draw_bit(html, html->start_sel, 0); |
1 | 1154 html->selected_text = str; |
12 | 1155 |
1 | 1156 } |
12 | 1157 } |
1158 else | |
1159 { | |
1160 GtkHtmlBit *shb, | |
1161 *ehb; | |
79 | 1162 size_t en, |
12 | 1163 st; |
1164 int len, | |
1165 nlen; | |
1 | 1166 char *str; |
12 | 1167 if (epos > spos) |
1168 { | |
1 | 1169 shb = html->start_sel; |
1170 ehb = html->end_sel; | |
1171 en = html->num_end; | |
1172 st = html->num_start; | |
12 | 1173 } |
1174 else | |
1175 { | |
1 | 1176 shb = html->end_sel; |
1177 ehb = html->start_sel; | |
1178 en = html->num_start; | |
1179 st = html->num_end; | |
1180 } | |
12 | 1181 |
1 | 1182 hbits = g_list_find(html->html_bits, shb); |
1183 | |
1184 if (!hbits) | |
1185 return; | |
12 | 1186 |
1187 if (shb->type == HTML_BIT_TEXT) | |
1188 { | |
1 | 1189 len = strlen(shb->text) - st + 1; |
1190 str = g_malloc(len); | |
1191 strcpy(str, shb->text + st); | |
1192 str[len - 1] = 0; | |
1193 gtk_html_draw_bit(html, shb, 0); | |
12 | 1194 if (shb->newline) |
1195 { | |
1196 len += 1; | |
1 | 1197 str = g_realloc(str, len); |
1198 str[len - 2] = '\n'; | |
1199 str[len - 1] = 0; | |
1200 } | |
12 | 1201 } |
1202 else | |
1203 { | |
1 | 1204 len = 1; |
1205 str = g_malloc(1); | |
1206 str[0] = 0; | |
1207 } | |
12 | 1208 if (hbits->next == NULL) |
1209 { | |
1 | 1210 html->selected_text = str; |
1211 return; | |
1212 } | |
1213 | |
12 | 1214 |
1215 hbits = hbits->next; | |
1216 while (1) | |
1217 { /* | |
1218 * Yah I know is dangerous :P | |
1219 */ | |
1220 hb = (GtkHtmlBit *) hbits->data; | |
1221 if (hb->type != HTML_BIT_TEXT) | |
1222 { | |
1 | 1223 if (hb == ehb) |
1224 break; | |
1225 hbits = hbits->next; | |
1226 continue; | |
1227 } | |
12 | 1228 if (hb != ehb) |
1229 { | |
1 | 1230 nlen = len + strlen(hb->text); |
1231 str = g_realloc(str, nlen); | |
1232 strcpy(str + (len - 1), hb->text); | |
1233 len = nlen; | |
1234 str[len - 1] = 0; | |
1235 gtk_html_draw_bit(html, hb, 0); | |
12 | 1236 if (hb->newline) |
1237 { | |
1238 len += 1; | |
1 | 1239 str = g_realloc(str, len); |
1240 str[len - 2] = '\n'; | |
1241 str[len - 1] = 0; | |
1242 } | |
12 | 1243 } |
1244 else | |
1245 { | |
1 | 1246 nlen = len + en + 1; |
1247 str = g_realloc(str, nlen); | |
1248 strncpy(str + (len - 1), hb->text, en + 1); | |
1249 len = nlen; | |
1250 str[len - 1] = 0; | |
12 | 1251 |
1 | 1252 gtk_html_draw_bit(html, hb, 0); |
12 | 1253 if (hb->newline && en == strlen(hb->text)) |
1254 { | |
1255 len += 1; | |
1 | 1256 str = g_realloc(str, len); |
1257 str[len - 2] = '\n'; | |
1258 str[len - 1] = 0; | |
1259 } | |
1260 break; | |
1261 } | |
1262 hbits = hbits->next; | |
1263 } | |
1264 html->selected_text = str; | |
1265 } | |
1266 | |
1267 } | |
1268 | |
12 | 1269 static gint scroll_timeout(GtkHtml * html) |
1 | 1270 { |
12 | 1271 GdkEventMotion event; |
1272 gint x, | |
1273 y; | |
1274 GdkModifierType mask; | |
1 | 1275 |
1276 html->timer = 0; | |
12 | 1277 gdk_window_get_pointer(html->html_area, &x, &y, &mask); |
1278 | |
1 | 1279 if (mask & GDK_BUTTON1_MASK) |
1280 { | |
1281 event.is_hint = 0; | |
1282 event.x = x; | |
1283 event.y = y; | |
1284 event.state = mask; | |
1285 | |
12 | 1286 gtk_html_motion_notify(GTK_WIDGET(html), &event); |
1 | 1287 } |
1288 | |
1289 return FALSE; | |
1290 | |
1291 } | |
1292 | |
1293 | |
12 | 1294 static gint gtk_html_tooltip_paint_window(GtkHtml * html) |
1 | 1295 { |
1296 GtkStyle *style; | |
12 | 1297 gint y, |
1298 baseline_skip, | |
1299 gap; | |
1 | 1300 |
1301 style = html->tooltip_window->style; | |
1302 | |
1303 gap = (style->font->ascent + style->font->descent) / 4; | |
1304 if (gap < 2) | |
1305 gap = 2; | |
1306 baseline_skip = style->font->ascent + style->font->descent + gap; | |
1307 | |
1308 if (!html->tooltip_hb) | |
1309 return FALSE; | |
1310 | |
1311 gtk_paint_flat_box(style, html->tooltip_window->window, | |
12 | 1312 GTK_STATE_NORMAL, GTK_SHADOW_OUT, |
1313 NULL, GTK_WIDGET(html->tooltip_window), "tooltip", | |
1314 0, 0, -1, -1); | |
1 | 1315 |
1316 y = style->font->ascent + 4; | |
1317 | |
12 | 1318 gtk_paint_string(style, html->tooltip_window->window, |
1319 GTK_STATE_NORMAL, | |
1320 NULL, GTK_WIDGET(html->tooltip_window), "tooltip", | |
1321 4, y, "HTML Link:"); | |
1 | 1322 y += baseline_skip; |
12 | 1323 gtk_paint_string(style, html->tooltip_window->window, |
1324 GTK_STATE_NORMAL, | |
1325 NULL, GTK_WIDGET(html->tooltip_window), "tooltip", | |
1326 4, y, html->tooltip_hb->url); | |
1327 | |
1 | 1328 return FALSE; |
1329 | |
1330 | |
1331 } | |
1332 | |
1333 static gint gtk_html_tooltip_timeout(gpointer data) | |
1334 { | |
12 | 1335 GtkHtml *html = (GtkHtml *) data; |
1336 | |
1337 | |
1 | 1338 GDK_THREADS_ENTER(); |
1339 | |
12 | 1340 if (html->tooltip_hb && GTK_WIDGET_DRAWABLE(GTK_WIDGET(html))) |
1341 { | |
1 | 1342 GtkWidget *widget; |
1343 GtkStyle *style; | |
12 | 1344 gint gap, |
1345 x, | |
1346 y, | |
1347 w, | |
1348 h, | |
1349 scr_w, | |
1350 scr_h, | |
1351 baseline_skip; | |
1 | 1352 |
1353 if (html->tooltip_window) | |
1354 gtk_widget_destroy(html->tooltip_window); | |
12 | 1355 |
1356 html->tooltip_window = gtk_window_new(GTK_WINDOW_POPUP); | |
1357 gtk_widget_set_app_paintable(html->tooltip_window, TRUE); | |
1358 gtk_window_set_policy(GTK_WINDOW(html->tooltip_window), FALSE, FALSE, | |
1359 TRUE); | |
1360 gtk_widget_set_name(html->tooltip_window, "gtk-tooltips"); | |
1361 gtk_signal_connect_object(GTK_OBJECT(html->tooltip_window), | |
1362 "expose_event", | |
1363 GTK_SIGNAL_FUNC | |
1364 (gtk_html_tooltip_paint_window), | |
1365 GTK_OBJECT(html)); | |
1366 gtk_signal_connect_object(GTK_OBJECT(html->tooltip_window), "draw", | |
1367 GTK_SIGNAL_FUNC | |
1368 (gtk_html_tooltip_paint_window), | |
1369 GTK_OBJECT(html)); | |
1370 | |
1371 gtk_widget_ensure_style(html->tooltip_window); | |
1 | 1372 style = html->tooltip_window->style; |
12 | 1373 |
1 | 1374 widget = GTK_WIDGET(html); |
1375 | |
12 | 1376 scr_w = gdk_screen_width(); |
1377 scr_h = gdk_screen_height(); | |
1 | 1378 |
1379 gap = (style->font->ascent + style->font->descent) / 4; | |
1380 if (gap < 2) | |
1381 gap = 2; | |
1382 baseline_skip = style->font->ascent + style->font->descent + gap; | |
1383 | |
353
a4df8f1cc61a
[gaim-migrate @ 363]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
349
diff
changeset
|
1384 w = 8 + MAX(gdk_string_width(style->font, _("HTML Link:")), |
12 | 1385 gdk_string_width(style->font, html->tooltip_hb->url)); |
1386 ; | |
1 | 1387 h = 8 - gap; |
12 | 1388 h += (baseline_skip * 2); |
1389 | |
1390 gdk_window_get_pointer(NULL, &x, &y, NULL); | |
1391 /* | |
1392 * gdk_window_get_origin (widget->window, NULL, &y); | |
1393 */ | |
1394 if (GTK_WIDGET_NO_WINDOW(widget)) | |
1 | 1395 y += widget->allocation.y; |
1396 | |
1397 x -= ((w >> 1) + 4); | |
1398 | |
1399 if ((x + w) > scr_w) | |
1400 x -= (x + w) - scr_w; | |
1401 else if (x < 0) | |
1402 x = 0; | |
1403 | |
1404 if ((y + h + 4) > scr_h) | |
12 | 1405 y = |
1406 y - html->tooltip_hb->font->ascent + | |
1407 html->tooltip_hb->font->descent; | |
1 | 1408 else |
12 | 1409 y = |
1410 y + html->tooltip_hb->font->ascent + | |
1411 html->tooltip_hb->font->descent; | |
1412 | |
1413 gtk_widget_set_usize(html->tooltip_window, w, h); | |
1414 gtk_widget_popup(html->tooltip_window, x, y); | |
1415 | |
1 | 1416 } |
1417 | |
1418 html->tooltip_timer = -1; | |
12 | 1419 |
1 | 1420 GDK_THREADS_LEAVE(); |
1421 | |
1422 return FALSE; | |
1423 } | |
1424 | |
1425 | |
12 | 1426 static gint gtk_html_leave_notify(GtkWidget * widget, GdkEventCrossing * event) |
1 | 1427 { |
12 | 1428 GtkHtml *html; |
1429 | |
1430 html = GTK_HTML(widget); | |
1431 | |
1432 if (html->tooltip_timer != -1) | |
1433 gtk_timeout_remove(html->tooltip_timer); | |
1434 if (html->tooltip_window) | |
1435 { | |
1436 gtk_widget_destroy(html->tooltip_window); | |
1437 html->tooltip_window = NULL; | |
1438 } | |
1439 | |
1440 | |
1441 html->tooltip_hb = NULL; | |
1442 return TRUE; | |
1 | 1443 } |
1444 | |
1445 | |
12 | 1446 static gint gtk_html_motion_notify(GtkWidget * widget, GdkEventMotion * event) |
1 | 1447 { |
12 | 1448 int x, |
1449 y; | |
1450 gint width, | |
1451 height; | |
1452 GdkModifierType state; | |
1453 int realx, | |
1454 realy; | |
1455 GtkHtml *html = GTK_HTML(widget); | |
1456 | |
1457 if (event->is_hint) | |
1458 gdk_window_get_pointer(event->window, &x, &y, &state); | |
1459 else | |
1460 { | |
1461 x = event->x; | |
1462 y = event->y; | |
1463 state = event->state; | |
1464 } | |
1465 | |
1466 gdk_window_get_size(html->html_area, &width, &height); | |
1467 | |
1 | 1468 realx = x; |
1469 realy = y + html->yoffset; | |
1470 | |
1471 | |
12 | 1472 if (state & GDK_BUTTON1_MASK) |
1473 { | |
1474 if (realx != html->start_sel_x || realy != html->start_sel_y) | |
1475 { | |
1 | 1476 char *tmp = NULL; |
1477 | |
12 | 1478 if (y < 0 || y > height) |
1479 { | |
1 | 1480 int diff; |
12 | 1481 if (html->timer == 0) |
1482 { | |
1 | 1483 html->timer = gtk_timeout_add(100, |
12 | 1484 (GtkFunction) scroll_timeout, |
1485 html); | |
1 | 1486 if (y < 0) |
1487 diff = y / 2; | |
1488 else | |
1489 diff = (y - height) / 2; | |
1490 | |
1491 if (html->vadj->value + diff > | |
12 | 1492 html->vadj->upper - height + 20) |
1 | 1493 gtk_adjustment_set_value(html->vadj, |
12 | 1494 html->vadj->upper - height + |
1495 20); | |
1 | 1496 else |
1497 gtk_adjustment_set_value(html->vadj, | |
12 | 1498 html->vadj->value + diff); |
1 | 1499 |
1500 } | |
1501 } | |
12 | 1502 |
1 | 1503 if (html->selected_text != NULL) |
1504 tmp = g_strdup(html->selected_text); | |
1505 do_select(html, realx, realy); | |
12 | 1506 if (tmp) |
1507 { | |
1508 if (!html->selected_text || strcmp(tmp, html->selected_text)) | |
1509 { | |
1 | 1510 GtkHtmlBit *hb; |
1511 GList *hbits = html->html_bits; | |
12 | 1512 while (hbits) |
1513 { | |
1514 hb = (GtkHtmlBit *) hbits->data; | |
1 | 1515 if (hb->was_selected) |
1516 gtk_html_draw_bit(html, hb, 0); | |
1517 hbits = hbits->next; | |
1518 } | |
1519 } | |
1520 g_free(tmp); | |
1521 } | |
1522 } | |
12 | 1523 } |
1524 else | |
1525 { | |
1 | 1526 GtkHtmlBit *hb; |
1527 GList *urls; | |
1528 | |
1529 urls = html->urls; | |
12 | 1530 while (urls) |
1531 { | |
1532 hb = (GtkHtmlBit *) urls->data; | |
1 | 1533 if ((realx > hb->x && realx < (hb->x + hb->width)) && |
12 | 1534 (realy < hb->y && realy > (hb->y - hb->height))) |
1535 { | |
26 | 1536 GdkCursor *cursor = NULL; |
1537 | |
12 | 1538 if (html->tooltip_hb != hb) |
1539 { | |
1 | 1540 html->tooltip_hb = hb; |
1541 if (html->tooltip_timer != -1) | |
1542 gtk_timeout_remove(html->tooltip_timer); | |
12 | 1543 if (html->tooltip_window) |
1544 { | |
1 | 1545 gtk_widget_destroy(html->tooltip_window); |
1546 html->tooltip_window = NULL; | |
1547 } | |
12 | 1548 html->tooltip_timer = |
1549 gtk_timeout_add(HTML_TOOLTIP_DELAY, | |
1550 gtk_html_tooltip_timeout, html); | |
1 | 1551 } |
26 | 1552 |
1553 cursor = gdk_cursor_new(GDK_HAND2); | |
1554 gdk_window_set_cursor(html->html_area, cursor); | |
1555 gdk_cursor_destroy(cursor); | |
1556 | |
1 | 1557 return TRUE; |
1558 } | |
12 | 1559 urls = urls->next; |
1 | 1560 } |
1561 if (html->tooltip_timer != -1) | |
1562 gtk_timeout_remove(html->tooltip_timer); | |
12 | 1563 if (html->tooltip_window) |
1564 { | |
1 | 1565 gtk_widget_destroy(html->tooltip_window); |
1566 html->tooltip_window = NULL; | |
1567 } | |
12 | 1568 |
1569 | |
1570 html->tooltip_hb = NULL; | |
1 | 1571 gdk_window_set_cursor(html->html_area, NULL); |
1572 | |
1573 | |
1574 } | |
1575 | |
1576 return TRUE; | |
1577 } | |
1578 | |
12 | 1579 static gint gtk_html_button_release(GtkWidget * widget, GdkEventButton * event) |
1 | 1580 { |
12 | 1581 GtkHtml *html; |
1582 | |
1583 html = GTK_HTML(widget); | |
1584 | |
1585 if (html->frozen > 0) | |
1586 return TRUE; | |
1587 | |
1588 if (event->button == 1) | |
1589 { | |
1590 int realx, | |
1591 realy; | |
1592 GtkHtmlBit *hb; | |
1593 GList *urls = html->urls; | |
1594 | |
1595 realx = event->x; | |
1596 realy = event->y + html->yoffset; | |
1597 if (realx != html->start_sel_x || realy != html->start_sel_y) | |
1598 { | |
1599 if (gtk_selection_owner_set(widget, | |
1600 GDK_SELECTION_PRIMARY, event->time)) | |
1601 { | |
1602 } | |
1603 else | |
1604 { | |
1605 } | |
1606 } | |
1607 else | |
1608 { | |
1609 if (gdk_selection_owner_get(GDK_SELECTION_PRIMARY) == | |
1610 widget->window) | |
1 | 1611 gtk_selection_owner_set(NULL, GDK_SELECTION_PRIMARY, |
12 | 1612 event->time); |
1613 | |
1614 | |
1615 while (urls) | |
1616 { | |
1617 void open_url_nw(GtkWidget * w, char *url); | |
1618 hb = (GtkHtmlBit *) urls->data; | |
1 | 1619 if ((realx > hb->x && realx < (hb->x + hb->width)) && |
12 | 1620 (realy < hb->y && realy > (hb->y - hb->height))) |
1621 { | |
1622 open_url_nw(NULL, hb->url); | |
1623 // else | |
1624 // open_url(NULL, hb->url); | |
1 | 1625 break; |
1626 } | |
1627 urls = urls->next; | |
1628 } | |
1629 } | |
1630 } | |
1631 return TRUE; | |
1632 } | |
1633 | |
1634 | |
1635 | |
12 | 1636 static gint gtk_html_button_press(GtkWidget * widget, GdkEventButton * event) |
1 | 1637 { |
12 | 1638 GtkHtml *html; |
1639 gfloat value; | |
1640 | |
1641 | |
1642 html = GTK_HTML(widget); | |
1643 value = html->vadj->value; | |
1644 | |
1645 if (html->frozen > 0) | |
1646 return TRUE; | |
1647 | |
1648 if (event->button == 4) | |
1649 { | |
1 | 1650 value -= html->vadj->step_increment; |
1651 if (value < html->vadj->lower) | |
1652 value = html->vadj->lower; | |
12 | 1653 gtk_adjustment_set_value(html->vadj, value); |
1654 } | |
1655 else if (event->button == 5) | |
1656 { | |
1 | 1657 value += html->vadj->step_increment; |
1658 if (value > html->vadj->upper) | |
1659 value = html->vadj->upper; | |
12 | 1660 gtk_adjustment_set_value(html->vadj, value); |
1661 | |
1662 } | |
1663 else if (event->button == 1) | |
1664 { | |
1665 GList *hbits = g_list_last(html->html_bits); | |
1666 int realx, | |
1667 realy; | |
1 | 1668 GtkHtmlBit *hb; |
1669 | |
1670 realx = event->x; | |
1671 realy = event->y + html->yoffset; | |
1672 | |
1673 html->start_sel_x = realx; | |
1674 html->start_sel_y = realy; | |
1675 | |
1676 if (!hbits) | |
1677 return TRUE; | |
1678 | |
12 | 1679 if (html->selected_text) |
1680 { | |
894
b5b3aa06111d
[gaim-migrate @ 904]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
871
diff
changeset
|
1681 gboolean forcedraw = FALSE; |
b5b3aa06111d
[gaim-migrate @ 904]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
871
diff
changeset
|
1682 hbits = html->html_bits; |
1 | 1683 g_free(html->selected_text); |
1684 html->selected_text = NULL; | |
1685 html->start_sel = NULL; | |
1686 html->end_sel = NULL; | |
1687 html->num_start = 0; | |
1688 html->num_end = 0; | |
12 | 1689 while (hbits) |
1690 { | |
1691 hb = (GtkHtmlBit *) hbits->data; | |
894
b5b3aa06111d
[gaim-migrate @ 904]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
871
diff
changeset
|
1692 if (hb->was_selected || forcedraw) { |
1 | 1693 gtk_html_draw_bit(html, hb, 1); |
894
b5b3aa06111d
[gaim-migrate @ 904]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
871
diff
changeset
|
1694 forcedraw = TRUE; |
b5b3aa06111d
[gaim-migrate @ 904]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
871
diff
changeset
|
1695 } |
b5b3aa06111d
[gaim-migrate @ 904]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
871
diff
changeset
|
1696 hbits = hbits->next; |
1 | 1697 } |
1698 hbits = g_list_last(html->html_bits); | |
1699 } | |
1700 | |
12 | 1701 hb = (GtkHtmlBit *) hbits->data; |
1702 if (realy > hb->y) | |
1703 { | |
1 | 1704 if (hb->text) |
1705 html->num_start = strlen(hb->text) - 1; | |
1706 else | |
12 | 1707 html->num_start = 0; |
1 | 1708 html->start_sel = hb; |
12 | 1709 } |
1710 else | |
1711 while (hbits) | |
1712 { | |
1713 hb = (GtkHtmlBit *) hbits->data; | |
1714 if ((realy < hb->y && realy > (hb->y - hb->height)) && | |
1715 (realx > hb->x + hb->width)) | |
1716 { | |
1717 if (hb->type != HTML_BIT_TEXT) | |
1718 { | |
1719 html->num_end = 0; | |
1720 html->end_sel = hb; | |
1721 break; | |
1722 } | |
1723 | |
1724 if (hb->text) | |
1725 html->num_start = strlen(hb->text) - 1; | |
1726 else | |
1727 html->num_start = 0; | |
1728 | |
1729 html->start_sel = hb; | |
1 | 1730 break; |
1731 } | |
12 | 1732 else if ((realx > hb->x && realx < (hb->x + hb->width)) && |
1733 (realy < hb->y && realy > (hb->y - hb->height))) | |
1734 { | |
1735 int i, | |
1736 len; | |
1737 int w = realx - hb->x; | |
1738 | |
1739 if (hb->type != HTML_BIT_TEXT) | |
1740 { | |
1741 html->num_end = 0; | |
1742 html->end_sel = hb; | |
1743 break; | |
1744 } | |
1745 | |
1746 if (hb->text) | |
1747 len = strlen(hb->text); | |
1748 else | |
1749 len = 0; | |
1750 | |
1751 for (i = 1; i <= len; i++) | |
1752 { | |
1753 if (gdk_text_measure(hb->font, hb->text, i) > w) | |
1754 { | |
1755 html->num_start = i - 1; | |
1756 html->start_sel = hb; | |
1757 break; | |
1758 } | |
1759 } | |
1 | 1760 break; |
1761 } | |
12 | 1762 hbits = hbits->prev; |
1 | 1763 } |
12 | 1764 } |
1765 else if (event->button == 3 && event->type == GDK_BUTTON_PRESS) | |
1766 { | |
1 | 1767 GtkHtmlBit *hb = NULL; |
12 | 1768 int realx, |
1769 realy; | |
1770 GList *urls; | |
1771 | |
1 | 1772 realx = event->x; |
1773 realy = event->y + html->yoffset; | |
12 | 1774 |
1 | 1775 urls = html->urls; |
12 | 1776 while (urls) |
1777 { | |
1778 hb = (GtkHtmlBit *) urls->data; | |
1 | 1779 if ((realx > hb->x && realx < (hb->x + hb->width)) && |
12 | 1780 (realy < hb->y && realy > (hb->y - hb->height))) |
1781 { | |
1 | 1782 break; |
1783 } | |
12 | 1784 urls = urls->next; |
1 | 1785 hb = NULL; |
1786 } | |
12 | 1787 |
1788 if (hb != NULL) | |
1789 { | |
69 | 1790 |
1791 GtkWidget *menu, *button; | |
1792 | |
1793 menu = gtk_menu_new(); | |
1794 | |
1795 if (web_browser == BROWSER_NETSCAPE) { | |
1796 | |
353
a4df8f1cc61a
[gaim-migrate @ 363]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
349
diff
changeset
|
1797 button = gtk_menu_item_new_with_label(_("Open URL in existing window")); |
69 | 1798 gtk_signal_connect(GTK_OBJECT(button), "activate", |
1799 GTK_SIGNAL_FUNC(open_url), hb->url); | |
1800 gtk_menu_append(GTK_MENU(menu), button); | |
1801 gtk_widget_show(button); | |
1802 | |
1803 } | |
1804 | |
1805 | |
353
a4df8f1cc61a
[gaim-migrate @ 363]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
349
diff
changeset
|
1806 button = gtk_menu_item_new_with_label(_("Open URL in new window")); |
69 | 1807 gtk_signal_connect(GTK_OBJECT(button), "activate", |
1808 GTK_SIGNAL_FUNC(open_url_nw), hb->url); | |
1809 gtk_menu_append(GTK_MENU(menu), button); | |
1810 gtk_widget_show(button); | |
1811 | |
1812 if (web_browser == BROWSER_NETSCAPE) { | |
1813 | |
353
a4df8f1cc61a
[gaim-migrate @ 363]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
349
diff
changeset
|
1814 button = gtk_menu_item_new_with_label(_("Add URL as bookmark")); |
69 | 1815 gtk_signal_connect(GTK_OBJECT(button), "activate", |
1816 GTK_SIGNAL_FUNC(add_bookmark), hb->url); | |
1817 gtk_menu_append(GTK_MENU(menu), button); | |
1818 gtk_widget_show(button); | |
1819 | |
1820 } | |
1821 | |
1822 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, | |
1823 event->button, event->time); | |
1824 | |
12 | 1825 } |
1 | 1826 } |
12 | 1827 |
1 | 1828 return TRUE; |
1829 } | |
1830 | |
871
75b05911234a
[gaim-migrate @ 881]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
869
diff
changeset
|
1831 |
12 | 1832 static void gtk_html_draw_bit(GtkHtml * html, GtkHtmlBit * hb, int redraw) |
1 | 1833 { |
12 | 1834 int mypos, |
1835 epos, | |
871
75b05911234a
[gaim-migrate @ 881]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
869
diff
changeset
|
1836 spos; |
12 | 1837 GdkGC *gc = html->gc; |
1 | 1838 int shift; |
12 | 1839 GtkStateType selected_state; |
1840 GtkWidget *widget = GTK_WIDGET(html); | |
1 | 1841 GdkRectangle area; |
895 | 1842 GList *hbits; |
1843 GtkHtmlBit *hbit; | |
1844 | |
1 | 1845 if (html->frozen > 0) |
1846 return; | |
1847 | |
895 | 1848 hbits = g_list_find(html->html_bits, hb); |
1849 | |
12 | 1850 if (hb->type == HTML_BIT_TEXT) |
1851 { | |
1 | 1852 |
716 | 1853 if (!(hb->text)) |
1 | 1854 return; |
720
8b3412f3ac2a
[gaim-migrate @ 730]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
716
diff
changeset
|
1855 /* this is possible, don't comment it out >:P */ |
8b3412f3ac2a
[gaim-migrate @ 730]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
716
diff
changeset
|
1856 if (!strlen(hb->text)) |
8b3412f3ac2a
[gaim-migrate @ 730]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
716
diff
changeset
|
1857 return; |
12 | 1858 |
1 | 1859 mypos = g_list_index(html->html_bits, hb); |
1860 epos = g_list_index(html->html_bits, html->end_sel); | |
1861 spos = g_list_index(html->html_bits, html->start_sel); | |
1862 | |
12 | 1863 if (((html->end_sel == NULL) || (html->start_sel == NULL)) || |
1864 ((epos < mypos) && (spos < mypos)) || | |
1865 ((epos > mypos) && (spos > mypos))) | |
1866 { | |
1867 selected_state = GTK_STATE_NORMAL; | |
1868 } | |
1869 else | |
1870 { | |
1 | 1871 selected_state = GTK_STATE_SELECTED; |
1872 } | |
1873 | |
1874 gdk_text_extents(hb->font, hb->text, 1, &shift, NULL, NULL, NULL, NULL); | |
1875 | |
12 | 1876 if (selected_state == GTK_STATE_SELECTED) |
1877 { | |
1878 int schar = 0, | |
1879 echar = 0; | |
1880 int startx = 0, | |
1881 xwidth = 0; | |
1882 | |
1883 if (epos > spos || | |
1884 (epos == spos && html->num_end >= html->num_start)) | |
1885 { | |
1886 if (mypos == epos) | |
1887 { | |
1 | 1888 echar = html->num_end; |
12 | 1889 xwidth = |
1890 gdk_text_width(hb->font, hb->text, html->num_end + 1); | |
1891 } | |
1892 else | |
1893 { | |
1 | 1894 echar = strlen(hb->text); |
1895 xwidth = hb->width; | |
1896 } | |
12 | 1897 if (mypos == spos) |
1898 { | |
1 | 1899 schar = html->num_start; |
12 | 1900 startx = |
1901 gdk_text_width(hb->font, hb->text, html->num_start); | |
1 | 1902 xwidth -= startx; |
1903 } | |
12 | 1904 } |
1905 else | |
1906 { | |
1907 if (mypos == spos) | |
1908 { | |
1 | 1909 echar = html->num_start; |
12 | 1910 xwidth = |
1911 gdk_text_width(hb->font, hb->text, | |
1912 html->num_start + 1); | |
1913 } | |
1914 else | |
1915 { | |
1 | 1916 echar = strlen(hb->text); |
1917 xwidth = hb->width; | |
1918 } | |
12 | 1919 if (mypos == epos) |
1920 { | |
1 | 1921 schar = html->num_end; |
12 | 1922 startx = |
1923 gdk_text_width(hb->font, hb->text, html->num_end); | |
1 | 1924 xwidth -= startx; |
1925 } | |
1926 } | |
1927 | |
1928 if (!redraw && echar == hb->sel_e && schar == hb->sel_s) | |
1929 return; | |
12 | 1930 |
1 | 1931 hb->sel_e = echar; |
1932 hb->sel_s = schar; | |
12 | 1933 |
1 | 1934 startx += hb->x; |
1935 | |
12 | 1936 area.x = hb->x - html->xoffset; |
1937 area.y = hb->y - hb->height + 3 - html->yoffset; | |
1938 area.width = hb->width + 2; | |
1939 area.height = hb->height; | |
1940 clear_area(html, &area); | |
1941 | |
1942 gtk_paint_flat_box(widget->style, html->html_area, | |
1943 selected_state, GTK_SHADOW_NONE, | |
1944 NULL, widget, "text", | |
1945 startx, | |
1946 hb->y - hb->height + 3 - html->yoffset, | |
1947 xwidth + 2, hb->height); | |
1948 hb->was_selected = 1; | |
1949 } | |
1950 else if (hb->was_selected) | |
1951 { | |
1952 area.x = hb->x - html->xoffset; | |
1953 area.y = hb->y - hb->height + 3 - html->yoffset; | |
1954 area.width = hb->width + 2; | |
1955 area.height = hb->height; | |
1956 clear_area(html, &area); | |
1957 | |
1958 hb->sel_e = -1; | |
1959 hb->sel_s = -1; | |
1960 | |
1 | 1961 hb->was_selected = 0; |
1962 } | |
12 | 1963 |
1964 if (selected_state == GTK_STATE_SELECTED && (mypos == epos | |
1965 || mypos == spos)) | |
1966 { | |
1 | 1967 char *s = hb->text; |
12 | 1968 int num = 0, |
1969 width = 0, | |
1970 fsel = 0, | |
1971 esel = strlen(hb->text); | |
1972 int lbearing, | |
1973 rbearing, | |
1974 w; | |
1975 | |
1976 if (epos > spos || | |
1977 (epos == spos && html->num_end >= html->num_start)) | |
1978 { | |
1 | 1979 if (mypos == epos) |
1980 esel = html->num_end; | |
1981 if (mypos == spos) | |
1982 fsel = html->num_start; | |
12 | 1983 } |
1984 else | |
1985 { | |
1 | 1986 if (mypos == spos) |
1987 esel = html->num_start; | |
12 | 1988 if (mypos == epos) |
1989 fsel = html->num_end; | |
1 | 1990 } |
1991 | |
12 | 1992 while (*s) |
1993 { | |
1 | 1994 |
1995 if (num < fsel || num > esel) | |
1996 selected_state = GTK_STATE_NORMAL; | |
1997 else | |
1998 selected_state = GTK_STATE_SELECTED; | |
1999 if (hb->fore != NULL) | |
2000 gdk_gc_set_foreground(gc, hb->fore); | |
2001 else | |
12 | 2002 gdk_gc_set_foreground(gc, |
2003 &widget->style->fg[selected_state]); | |
1 | 2004 |
2005 gdk_gc_set_font(gc, hb->font); | |
2006 | |
12 | 2007 gdk_text_extents(hb->font, s, 1, &lbearing, &rbearing, &w, NULL, |
2008 NULL); | |
2009 | |
2010 gdk_draw_text(html->html_area, hb->font, gc, | |
2011 shift + hb->x + width, hb->y - html->yoffset, s, | |
2012 1); | |
2013 | |
2014 if (hb->uline) | |
2015 gdk_draw_line(html->html_area, gc, shift + hb->x + width, | |
2016 hb->y - html->yoffset, | |
2017 shift + hb->x + width + w, | |
2018 hb->y - html->yoffset); | |
1 | 2019 |
2020 if (hb->strike) | |
12 | 2021 gdk_draw_line(html->html_area, gc, shift + hb->x + width, |
2022 hb->y - html->yoffset - (hb->height / 3), | |
2023 shift + hb->x + width + w, | |
2024 hb->y - html->yoffset - (hb->height / 3)); | |
1 | 2025 |
2026 width += w; | |
12 | 2027 |
1 | 2028 s++; |
2029 num++; | |
2030 } | |
2031 | |
2032 | |
12 | 2033 } |
2034 else | |
2035 { | |
2036 /*my stuff here*/ | |
2037 | |
2038 if(!hb->was_selected) | |
2039 { | |
2040 area.x = hb->x - html->xoffset; | |
2041 area.y = hb->y - hb->height + 3 - html->yoffset; | |
2042 area.width = hb->width + 2; | |
2043 area.height = hb->height; | |
2044 clear_area(html, &area); | |
2045 } | |
2046 | |
2047 /*end my stuff*/ | |
2048 | |
1 | 2049 |
914
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2050 if (hb->text && hb->back != NULL) { |
897
b2ce6a6a8633
[gaim-migrate @ 907]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
896
diff
changeset
|
2051 int hwidth, hheight, hei, tmpcnt; |
895 | 2052 hei = get_line_height(html, hb); |
860
a8633715fb5b
[gaim-migrate @ 870]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
853
diff
changeset
|
2053 gdk_window_get_size(html->html_area, &hwidth, &hheight); |
629
ce8d8608d05b
[gaim-migrate @ 639]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
627
diff
changeset
|
2054 gdk_gc_set_foreground(gc, hb->back); |
635
2ad1a8234ef1
[gaim-migrate @ 645]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
632
diff
changeset
|
2055 gdk_draw_rectangle(html->html_area, gc, TRUE /* filled */, |
868
d828bdc3854b
[gaim-migrate @ 878]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
860
diff
changeset
|
2056 hb->x, hb->y - html->yoffset - hei - 6, |
860
a8633715fb5b
[gaim-migrate @ 870]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
853
diff
changeset
|
2057 hwidth - shift - hb->x + 1, hei + hei + 2); |
897
b2ce6a6a8633
[gaim-migrate @ 907]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
896
diff
changeset
|
2058 for (tmpcnt = 1; tmpcnt < hb->newline; tmpcnt++) { |
b2ce6a6a8633
[gaim-migrate @ 907]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
896
diff
changeset
|
2059 int eoff = hei + hei + 2; |
b2ce6a6a8633
[gaim-migrate @ 907]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
896
diff
changeset
|
2060 eoff *= tmpcnt; |
b2ce6a6a8633
[gaim-migrate @ 907]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
896
diff
changeset
|
2061 gdk_draw_rectangle(html->html_area, gc, TRUE, |
b2ce6a6a8633
[gaim-migrate @ 907]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
896
diff
changeset
|
2062 1, hb->y - html->yoffset - hei - 6 + eoff, |
b2ce6a6a8633
[gaim-migrate @ 907]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
896
diff
changeset
|
2063 hwidth, hei + hei + 2); |
b2ce6a6a8633
[gaim-migrate @ 907]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
896
diff
changeset
|
2064 } |
629
ce8d8608d05b
[gaim-migrate @ 639]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
627
diff
changeset
|
2065 } |
ce8d8608d05b
[gaim-migrate @ 639]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
627
diff
changeset
|
2066 |
1 | 2067 if (hb->fore != NULL) |
2068 gdk_gc_set_foreground(gc, hb->fore); | |
2069 else | |
12 | 2070 gdk_gc_set_foreground(gc, &widget->style->fg[selected_state]); |
1 | 2071 |
2072 gdk_gc_set_font(gc, hb->font); | |
2073 | |
12 | 2074 gdk_draw_string(html->html_area, hb->font, gc, shift + hb->x, |
2075 hb->y - html->yoffset, hb->text); | |
1 | 2076 if (hb->uline) |
12 | 2077 gdk_draw_line(html->html_area, gc, shift + hb->x, |
2078 hb->y - html->yoffset, | |
2079 hb->x + gdk_string_measure(hb->font, hb->text), | |
2080 hb->y - html->yoffset); | |
1 | 2081 |
2082 if (hb->strike) | |
12 | 2083 gdk_draw_line(html->html_area, gc, shift + hb->x, |
2084 hb->y - html->yoffset - (hb->height / 3), | |
2085 hb->x + gdk_string_measure(hb->font, hb->text), | |
2086 hb->y - html->yoffset - (hb->height / 3)); | |
1 | 2087 |
2088 } | |
12 | 2089 } |
2090 else if (hb->type == HTML_BIT_SEP) | |
2091 { | |
914
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2092 if (hb->back != NULL) { |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2093 int hwidth, hheight, hei, tmpcnt; |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2094 hei = get_line_height(html, hb); |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2095 gdk_window_get_size(html->html_area, &hwidth, &hheight); |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2096 gdk_gc_set_foreground(gc, hb->back); |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2097 gdk_draw_rectangle(html->html_area, gc, TRUE, |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2098 1, hb->y - html->yoffset, |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2099 hwidth, 5); |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2100 for (tmpcnt = 0; tmpcnt < hb->newline; tmpcnt++) { |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2101 int eoff = hei + hei + 2; |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2102 eoff *= tmpcnt; |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2103 eoff += 5; |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2104 gdk_draw_rectangle(html->html_area, gc, TRUE, |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2105 1, hb->y - html->yoffset + eoff, |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2106 hwidth, hei + hei + 2); |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2107 } |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2108 } |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2109 |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2110 if (hb->fore != NULL) |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2111 gdk_gc_set_foreground(gc, hb->fore); |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2112 else |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2113 gdk_gc_set_foreground(gc, &widget->style->fg[GTK_STATE_NORMAL]); |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2114 |
12 | 2115 gdk_draw_line(html->html_area, gc, hb->x + 2, |
2116 hb->y - html->yoffset - (hb->height / 2 - 1), | |
2117 hb->x + hb->width, | |
2118 hb->y - html->yoffset - (hb->height / 2 - 1)); | |
2119 | |
2120 } | |
2121 else if (hb->type == HTML_BIT_PIXMAP) | |
2122 { | |
907
08d5037c9296
[gaim-migrate @ 917]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
897
diff
changeset
|
2123 area.x = hb->x - html->xoffset; |
08d5037c9296
[gaim-migrate @ 917]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
897
diff
changeset
|
2124 area.y = hb->y - hb->height + 5 - html->yoffset; |
911
65c8bd1feec5
[gaim-migrate @ 921]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
907
diff
changeset
|
2125 area.width = hb->width; |
907
08d5037c9296
[gaim-migrate @ 917]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
897
diff
changeset
|
2126 area.height = hb->height; |
08d5037c9296
[gaim-migrate @ 917]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
897
diff
changeset
|
2127 clear_area(html, &area); |
914
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2128 if (hb->back != NULL && selected_state != GTK_STATE_SELECTED) { |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2129 int hwidth, hheight, hei, tmpcnt; |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2130 hei = get_line_height(html, hb); |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2131 gdk_window_get_size(html->html_area, &hwidth, &hheight); |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2132 gdk_gc_set_foreground(gc, hb->back); |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2133 for (tmpcnt = 1; tmpcnt < hb->newline; tmpcnt++) { |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2134 int eoff = hei + hei + 2; |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2135 eoff *= tmpcnt - 1; |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2136 eoff += 5; |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2137 gdk_draw_rectangle(html->html_area, gc, TRUE, |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2138 1, hb->y - html->yoffset - 11 + eoff, |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2139 hwidth, hei + hei + 2); |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2140 } |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2141 } |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2142 |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2143 if (hb->fore != NULL) |
1 | 2144 gdk_gc_set_background(gc, &widget->style->base[GTK_STATE_NORMAL]); |
12 | 2145 gdk_draw_pixmap(html->html_area, gc, hb->pm, 0, 0, hb->x, |
492
56399273ed8d
[gaim-migrate @ 502]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
481
diff
changeset
|
2146 hb->y - html->yoffset - (hb->height) + 4, -1, -1); |
1 | 2147 } |
2148 } | |
2149 | |
2150 | |
2151 | |
12 | 2152 gint compare_types(GtkHtmlBit * hb, GtkHtmlBit * hb2) |
1 | 2153 { |
12 | 2154 /* |
2155 * In this function, it's OK to accidently return a | |
2156 * * 0, but will cause problems on an accidental 1 | |
2157 */ | |
1 | 2158 |
2159 if (!hb || !hb2) | |
2160 return 0; | |
12 | 2161 |
2162 | |
1 | 2163 if (hb->uline != hb2->uline) |
2164 return 0; | |
2165 if (hb->strike != hb2->strike) | |
12 | 2166 return 0; |
2167 if (hb->font && hb2->font) | |
2168 { | |
1 | 2169 if (!gdk_font_equal(hb->font, hb2->font)) |
2170 return 0; | |
12 | 2171 } |
2172 else if (hb->font && !hb2->font) | |
2173 { | |
1 | 2174 return 0; |
12 | 2175 } |
2176 else if (!hb->font && hb2->font) | |
2177 { | |
1 | 2178 return 0; |
2179 } | |
2180 if (hb->type != hb2->type) | |
2181 return 0; | |
12 | 2182 |
2183 if (hb->fore && hb2->fore) | |
2184 { | |
1 | 2185 if (!gdk_color_equal(hb->fore, hb2->fore)) |
2186 return 0; | |
12 | 2187 } |
2188 else if (hb->fore && !hb2->fore) | |
2189 { | |
1 | 2190 return 0; |
12 | 2191 } |
2192 else if (!hb->fore && hb2->fore) | |
2193 { | |
1 | 2194 return 0; |
2195 } | |
2196 | |
12 | 2197 if (hb->back && hb2->back) |
2198 { | |
1 | 2199 if (!gdk_color_equal(hb->back, hb2->back)) |
2200 return 0; | |
12 | 2201 } |
2202 else if (hb->back && !hb2->back) | |
2203 { | |
1 | 2204 return 0; |
12 | 2205 } |
2206 else if (!hb->back && hb2->back) | |
2207 { | |
1 | 2208 return 0; |
2209 } | |
2210 | |
2211 if ((hb->url != NULL && hb2->url == NULL) || | |
12 | 2212 (hb->url == NULL && hb2->url != NULL)) |
1 | 2213 return 0; |
12 | 2214 |
2215 if (hb->url != NULL && hb2->url != NULL) | |
1 | 2216 if (strcasecmp(hb->url, hb2->url)) |
2217 return 0; | |
12 | 2218 |
1 | 2219 return 1; |
2220 } | |
2221 | |
12 | 2222 static gint html_bit_is_onscreen(GtkHtml * html, GtkHtmlBit * hb) |
1 | 2223 { |
12 | 2224 gint width, |
2225 height; | |
1 | 2226 |
2227 gdk_window_get_size(html->html_area, &width, &height); | |
12 | 2228 |
2229 if (hb->y < html->yoffset) | |
2230 { | |
1 | 2231 return 0; |
2232 } | |
2233 | |
12 | 2234 if ((hb->y - hb->height) > (html->yoffset + height)) |
2235 { | |
1 | 2236 return 0; |
2237 } | |
2238 return 1; | |
2239 } | |
2240 | |
12 | 2241 static void draw_cursor(GtkHtml * html) |
1 | 2242 { |
12 | 2243 if (html->editable && |
2244 html->cursor_hb && | |
2245 GTK_WIDGET_DRAWABLE(html) && | |
2246 html_bit_is_onscreen(html, html->cursor_hb)) | |
2247 { | |
2248 gint x, | |
2249 y; | |
1 | 2250 gint width; |
2251 | |
2252 GdkFont *font = html->cursor_hb->font; | |
2253 | |
12 | 2254 gdk_text_extents(font, html->cursor_hb->text, html->cursor_pos, NULL, |
2255 NULL, &width, NULL, NULL); | |
2256 | |
2257 gdk_gc_set_foreground(html->gc, | |
2258 >K_WIDGET(html)->style->text[GTK_STATE_NORMAL]); | |
1 | 2259 |
2260 y = html->cursor_hb->y - html->yoffset; | |
2261 x = html->cursor_hb->x + width; | |
2262 | |
2263 | |
12 | 2264 gdk_draw_line(html->html_area, html->gc, x, y, x, y - font->ascent); |
1 | 2265 |
2266 } | |
2267 } | |
2268 | |
12 | 2269 static void undraw_cursor(GtkHtml * html) |
1 | 2270 { |
12 | 2271 if (html->editable && |
2272 html->cursor_hb && | |
2273 GTK_WIDGET_DRAWABLE(html) && | |
2274 html_bit_is_onscreen(html, html->cursor_hb)) | |
2275 { | |
2276 gint x, | |
2277 y; | |
1 | 2278 gint width; |
12 | 2279 GdkRectangle area; |
2280 | |
1 | 2281 GdkFont *font = html->cursor_hb->font; |
2282 | |
12 | 2283 gdk_text_extents(font, html->cursor_hb->text, html->cursor_pos, NULL, |
2284 NULL, &width, NULL, NULL); | |
1 | 2285 |
2286 y = html->cursor_hb->y - html->yoffset; | |
2287 x = html->cursor_hb->x + width; | |
2288 | |
2289 area.x = x; | |
2290 area.y = y - font->ascent; | |
2291 area.height = font->ascent + 1; | |
2292 area.width = 1; | |
2293 | |
2294 | |
12 | 2295 clear_area(html, &area); |
1 | 2296 |
897
b2ce6a6a8633
[gaim-migrate @ 907]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
896
diff
changeset
|
2297 gtk_html_draw_bit(html, html->cursor_hb, 1); |
12 | 2298 |
2299 | |
2300 } | |
1 | 2301 } |
2302 | |
2303 | |
12 | 2304 static void expose_html(GtkHtml * html, GdkRectangle * area, gboolean cursor) |
1 | 2305 { |
12 | 2306 GList *hbits; |
2307 GtkHtmlBit *hb; | |
2308 gint width, | |
2309 height; | |
2310 gint realy; | |
2311 | |
2312 | |
2313 if (html->frozen > 0) | |
2314 return; | |
2315 | |
2316 | |
2317 hbits = html->html_bits; | |
1 | 2318 |
2319 gdk_window_get_size(html->html_area, &width, &height); | |
2320 | |
12 | 2321 realy = area->y + html->yoffset; |
2322 | |
895 | 2323 /* this is needed since background colors draw across the entire window width |
2324 if anyone knows of a cleaner way to work bg colors, please submit code =) */ | |
2325 area->x = 0; | |
2326 area->width = width; | |
2327 | |
12 | 2328 clear_area(html, area); |
2329 | |
2330 while (hbits) | |
2331 { | |
2332 | |
2333 hb = (GtkHtmlBit *) hbits->data; | |
1 | 2334 |
2335 if (html_bit_is_onscreen(html, hb)) | |
12 | 2336 gtk_html_draw_bit(html, hb, 1); |
2337 | |
2338 | |
2339 hbits = hbits->next; | |
2340 } | |
1 | 2341 } |
2342 | |
12 | 2343 static void resize_html(GtkHtml * html) |
1 | 2344 { |
2345 GList *hbits = html->html_bits; | |
2346 GList *html_bits = html->html_bits; | |
12 | 2347 GtkHtmlBit *hb, |
2348 *hb2; | |
1 | 2349 char *str; |
2350 gint height; | |
2351 | |
12 | 2352 if (!hbits) |
2353 return; | |
2354 | |
2355 | |
2356 html->html_bits = NULL; | |
2357 | |
2358 html->current_x = 0; | |
1 | 2359 html->current_y = 0; |
2360 | |
12 | 2361 html->vadj->upper = 0; |
2362 | |
2363 gtk_html_freeze(html); | |
2364 | |
2365 while (hbits) | |
2366 { | |
2367 hb = (GtkHtmlBit *) hbits->data; | |
2368 if (hb->type == HTML_BIT_SEP) | |
2369 { | |
2370 | |
914
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2371 gtk_html_add_seperator(html, hb->font, hb->fore, hb->back); |
1 | 2372 |
2373 g_free(hb); | |
2374 | |
2375 hbits = hbits->next; | |
2376 continue; | |
2377 } | |
12 | 2378 if (hb->type == HTML_BIT_PIXMAP) |
2379 { | |
1 | 2380 |
536
c9f994ea5833
[gaim-migrate @ 546]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
526
diff
changeset
|
2381 gtk_html_add_pixmap(html, hb->pm, hb->fit, hb->newline); |
1 | 2382 |
2383 g_free(hb); | |
2384 | |
2385 hbits = hbits->next; | |
2386 continue; | |
2387 } | |
12 | 2388 |
2389 if (hb->newline) | |
2390 { | |
1 | 2391 int i; |
2392 | |
12 | 2393 if (!hb->text) |
2394 { | |
1 | 2395 hb->text = g_malloc(1); |
2396 hb->text[0] = 0; | |
2397 } | |
12 | 2398 for (i = 0; i < hb->newline; i++) |
2399 { | |
2400 str = hb->text; | |
1 | 2401 hb->text = g_strconcat(str, "\n", NULL); |
506
58af37870fdd
[gaim-migrate @ 516]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
499
diff
changeset
|
2402 if (str) g_free(str); |
1 | 2403 } |
2404 } | |
2405 | |
12 | 2406 if (hbits->next) |
2407 { | |
2408 hb2 = (GtkHtmlBit *) hbits->next->data; | |
2409 } | |
2410 else | |
2411 { | |
2412 hb2 = NULL; | |
2413 } | |
2414 | |
2415 | |
2416 | |
2417 if (!hb->newline && compare_types(hb, hb2)) | |
2418 { | |
1 | 2419 str = hb2->text; |
2420 hb2->text = g_strconcat(hb->text, hb2->text, NULL); | |
537
d050f88321a1
[gaim-migrate @ 547]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
536
diff
changeset
|
2421 if (str) g_free(str); |
1 | 2422 hb2 = NULL; |
12 | 2423 } |
2424 else if (hb->text) | |
2425 { | |
1 | 2426 gtk_html_add_text(html, hb->font, hb->fore, hb->back, |
12 | 2427 hb->text, strlen(hb->text), hb->uline, hb->strike, |
2428 hb->url); | |
1 | 2429 } |
2430 | |
12 | 2431 |
2432 | |
2433 /* | |
2434 * Font stays, so do colors (segfaults if I free) | |
2435 */ | |
1 | 2436 if (hb->fore) |
2437 gdk_color_free(hb->fore); | |
2438 if (hb->back) | |
2439 gdk_color_free(hb->back); | |
2440 if (hb->text) | |
2441 g_free(hb->text); | |
2442 if (hb->url) | |
2443 g_free(hb->url); | |
2444 | |
12 | 2445 g_free(hb); |
1 | 2446 |
2447 hbits = hbits->next; | |
2448 } | |
2449 | |
12 | 2450 g_list_free(html_bits); |
2451 | |
2452 | |
2453 gtk_html_thaw(html); | |
2454 | |
1 | 2455 gdk_window_get_size(html->html_area, NULL, &height); |
12 | 2456 gtk_adjustment_set_value(html->vadj, html->vadj->upper - height); |
1 | 2457 |
2458 } | |
2459 | |
12 | 2460 static GdkGC *create_bg_gc(GtkHtml * html) |
1 | 2461 { |
12 | 2462 GdkGCValues values; |
2463 | |
2464 values.tile = GTK_WIDGET(html)->style->bg_pixmap[GTK_STATE_NORMAL]; | |
2465 values.fill = GDK_TILED; | |
2466 | |
2467 return gdk_gc_new_with_values(html->html_area, &values, | |
2468 GDK_GC_FILL | GDK_GC_TILE); | |
1 | 2469 } |
2470 | |
12 | 2471 static void clear_area(GtkHtml * html, GdkRectangle * area) |
1 | 2472 { |
12 | 2473 GtkWidget *widget = GTK_WIDGET(html); |
2474 gint x, | |
2475 y; | |
2476 | |
2477 | |
2478 if (html->transparent) | |
2479 { | |
1 | 2480 if (html->pm == NULL) |
2481 html->pm = get_desktop_pixmap(widget); | |
2482 | |
12 | 2483 if (html->pm == NULL) |
2484 return; | |
2485 | |
2486 if (html->bg_gc == NULL) | |
2487 { | |
2488 GdkGCValues values; | |
2489 | |
2490 values.tile = html->pm; | |
2491 values.fill = GDK_TILED; | |
2492 | |
2493 html->bg_gc = gdk_gc_new_with_values(html->html_area, &values, | |
2494 GDK_GC_FILL | GDK_GC_TILE); | |
2495 | |
2496 } | |
2497 | |
1 | 2498 gdk_window_get_deskrelative_origin(html->html_area, &x, &y); |
2499 | |
12 | 2500 gdk_draw_pixmap(html->html_area, html->bg_gc, html->pm, |
2501 x + area->x, y + area->y, area->x, area->y, area->width, | |
2502 area->height); | |
1 | 2503 |
2504 return; | |
2505 | |
2506 } | |
12 | 2507 if (html->bg_gc) |
2508 { | |
2509 | |
2510 gint width, | |
2511 height; | |
2512 | |
2513 gdk_window_get_size(widget->style->bg_pixmap[GTK_STATE_NORMAL], &width, | |
2514 &height); | |
2515 | |
2516 gdk_gc_set_ts_origin(html->bg_gc, | |
2517 (-html->xoffset) % width, | |
2518 (-html->yoffset) % height); | |
2519 | |
2520 gdk_draw_rectangle(html->html_area, html->bg_gc, TRUE, | |
2521 area->x, area->y, area->width, area->height); | |
2522 } | |
2523 else | |
2524 gdk_window_clear_area(html->html_area, area->x, area->y, area->width, | |
2525 area->height); | |
1 | 2526 } |
2527 | |
2528 | |
2529 | |
2530 | |
12 | 2531 static void gtk_html_destroy(GtkObject * object) |
1 | 2532 { |
12 | 2533 GtkHtml *html; |
2534 | |
2535 g_return_if_fail(object != NULL); | |
2536 g_return_if_fail(GTK_IS_HTML(object)); | |
2537 | |
2538 html = (GtkHtml *) object; | |
2539 | |
2540 | |
2541 gtk_signal_disconnect_by_data(GTK_OBJECT(html->hadj), html); | |
2542 gtk_signal_disconnect_by_data(GTK_OBJECT(html->vadj), html); | |
2543 | |
2544 if (html->timer) | |
2545 { | |
2546 gtk_timeout_remove(html->timer); | |
2547 html->timer = 0; | |
1 | 2548 } |
2549 | |
12 | 2550 if (html->tooltip_timer) |
2551 { | |
2552 gtk_timeout_remove(html->tooltip_timer); | |
1 | 2553 html->tooltip_timer = -1; |
2554 } | |
2555 | |
12 | 2556 |
2557 GTK_OBJECT_CLASS(parent_class)->destroy(object); | |
2558 | |
1 | 2559 } |
2560 | |
12 | 2561 static void gtk_html_finalize(GtkObject * object) |
1 | 2562 { |
12 | 2563 GList *hbits; |
2564 GtkHtml *html; | |
1 | 2565 GtkHtmlBit *hb; |
2566 | |
2567 | |
12 | 2568 g_return_if_fail(object != NULL); |
2569 g_return_if_fail(GTK_IS_HTML(object)); | |
2570 | |
2571 html = (GtkHtml *) object; | |
2572 | |
2573 gtk_object_unref(GTK_OBJECT(html->hadj)); | |
2574 gtk_object_unref(GTK_OBJECT(html->vadj)); | |
2575 | |
2576 hbits = html->html_bits; | |
2577 | |
2578 while (hbits) | |
2579 { | |
2580 hb = (GtkHtmlBit *) hbits->data; | |
2581 if (hb->fore) | |
2582 gdk_color_free(hb->fore); | |
2583 if (hb->back) | |
2584 gdk_color_free(hb->back); | |
2585 if (hb->text) | |
2586 g_free(hb->text); | |
2587 if (hb->url) | |
2588 g_free(hb->url); | |
2589 if (hb->pm) | |
2590 gdk_pixmap_unref(hb->pm); | |
2591 | |
2592 g_free(hb); | |
2593 hbits = hbits->next; | |
2594 } | |
2595 if (html->html_bits) | |
2596 g_list_free(html->html_bits); | |
2597 | |
2598 if (html->urls) | |
2599 g_list_free(html->urls); | |
2600 | |
2601 if (html->selected_text) | |
2602 g_free(html->selected_text); | |
2603 | |
2604 if (html->gc) | |
2605 gdk_gc_destroy(html->gc); | |
2606 | |
2607 if (html->bg_gc) | |
2608 gdk_gc_destroy(html->bg_gc); | |
1 | 2609 |
2610 if (html->tooltip_window) | |
2611 gtk_widget_destroy(html->tooltip_window); | |
12 | 2612 |
2613 GTK_OBJECT_CLASS(parent_class)->finalize(object); | |
1 | 2614 } |
2615 | |
12 | 2616 static void gtk_html_realize(GtkWidget * widget) |
1 | 2617 { |
12 | 2618 GtkHtml *html; |
2619 GdkWindowAttr attributes; | |
2620 gint attributes_mask; | |
2621 | |
2622 g_return_if_fail(widget != NULL); | |
2623 g_return_if_fail(GTK_IS_HTML(widget)); | |
2624 | |
2625 html = GTK_HTML(widget); | |
2626 GTK_WIDGET_SET_FLAGS(html, GTK_REALIZED); | |
2627 | |
2628 attributes.window_type = GDK_WINDOW_CHILD; | |
2629 attributes.x = widget->allocation.x; | |
2630 attributes.y = widget->allocation.y; | |
2631 attributes.width = widget->allocation.width; | |
2632 attributes.height = widget->allocation.height; | |
2633 attributes.wclass = GDK_INPUT_OUTPUT; | |
2634 attributes.visual = gtk_widget_get_visual(widget); | |
2635 attributes.colormap = gtk_widget_get_colormap(widget); | |
2636 attributes.event_mask = gtk_widget_get_events(widget); | |
2637 attributes.event_mask |= (GDK_EXPOSURE_MASK | | |
2638 GDK_BUTTON_PRESS_MASK | | |
2639 GDK_BUTTON_RELEASE_MASK | | |
2640 GDK_BUTTON_MOTION_MASK | | |
2641 GDK_ENTER_NOTIFY_MASK | | |
2642 GDK_LEAVE_NOTIFY_MASK | | |
2643 GDK_POINTER_MOTION_MASK | | |
2644 GDK_POINTER_MOTION_HINT_MASK | | |
2645 GDK_VISIBILITY_NOTIFY_MASK | GDK_KEY_PRESS_MASK); | |
2646 | |
2647 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; | |
2648 | |
2649 widget->window = | |
2650 gdk_window_new(gtk_widget_get_parent_window(widget), &attributes, | |
2651 attributes_mask); | |
2652 gdk_window_set_user_data(widget->window, html); | |
2653 | |
2654 attributes.x = (widget->style->klass->xthickness + BORDER_WIDTH); | |
2655 attributes.y = (widget->style->klass->ythickness + BORDER_WIDTH); | |
2656 attributes.width = | |
2657 MAX(1, (gint) widget->allocation.width - (gint) attributes.x * 2); | |
2658 attributes.height = | |
2659 MAX(1, (gint) widget->allocation.height - (gint) attributes.y * 2); | |
2660 | |
2661 html->html_area = | |
2662 gdk_window_new(widget->window, &attributes, attributes_mask); | |
2663 gdk_window_set_user_data(html->html_area, html); | |
2664 | |
2665 widget->style = gtk_style_attach(widget->style, widget->window); | |
2666 | |
2667 /* | |
2668 * Can't call gtk_style_set_background here because it's handled specially | |
2669 */ | |
2670 gdk_window_set_background(widget->window, | |
2671 &widget->style->base[GTK_STATE_NORMAL]); | |
2672 gdk_window_set_background(html->html_area, | |
2673 &widget->style->base[GTK_STATE_NORMAL]); | |
2674 | |
2675 if (widget->style->bg_pixmap[GTK_STATE_NORMAL]) | |
2676 html->bg_gc = create_bg_gc(html); | |
2677 | |
2678 html->gc = gdk_gc_new(html->html_area); | |
2679 gdk_gc_set_exposures(html->gc, TRUE); | |
2680 gdk_gc_set_foreground(html->gc, &widget->style->text[GTK_STATE_NORMAL]); | |
2681 | |
2682 gdk_window_show(html->html_area); | |
1 | 2683 |
2684 } | |
2685 | |
12 | 2686 static void gtk_html_style_set(GtkWidget * widget, GtkStyle * previous_style) |
1 | 2687 { |
12 | 2688 GtkHtml *html; |
2689 | |
2690 g_return_if_fail(widget != NULL); | |
2691 g_return_if_fail(GTK_IS_HTML(widget)); | |
2692 | |
2693 html = GTK_HTML(widget); | |
2694 if (GTK_WIDGET_REALIZED(widget)) | |
2695 { | |
2696 gdk_window_set_background(widget->window, | |
2697 &widget->style->base[GTK_STATE_NORMAL]); | |
2698 gdk_window_set_background(html->html_area, | |
2699 &widget->style->base[GTK_STATE_NORMAL]); | |
2700 | |
2701 if (html->bg_gc) | |
2702 { | |
2703 gdk_gc_destroy(html->bg_gc); | |
2704 html->bg_gc = NULL; | |
2705 } | |
2706 | |
2707 if (widget->style->bg_pixmap[GTK_STATE_NORMAL]) | |
2708 { | |
2709 html->bg_gc = create_bg_gc(html); | |
2710 } | |
2711 | |
2712 } | |
1 | 2713 } |
2714 | |
12 | 2715 static void gtk_html_unrealize(GtkWidget * widget) |
1 | 2716 { |
12 | 2717 GtkHtml *html; |
2718 | |
2719 g_return_if_fail(widget != NULL); | |
2720 g_return_if_fail(GTK_IS_HTML(widget)); | |
2721 | |
2722 html = GTK_HTML(widget); | |
2723 | |
2724 gdk_window_set_user_data(html->html_area, NULL); | |
2725 gdk_window_destroy(html->html_area); | |
2726 html->html_area = NULL; | |
2727 | |
2728 gdk_gc_destroy(html->gc); | |
2729 html->gc = NULL; | |
2730 | |
2731 if (html->bg_gc) | |
2732 { | |
2733 gdk_gc_destroy(html->bg_gc); | |
2734 html->bg_gc = NULL; | |
2735 } | |
2736 | |
2737 if (GTK_WIDGET_CLASS(parent_class)->unrealize) | |
2738 (*GTK_WIDGET_CLASS(parent_class)->unrealize) (widget); | |
1 | 2739 } |
2740 | |
2741 | |
536
c9f994ea5833
[gaim-migrate @ 546]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
526
diff
changeset
|
2742 void gtk_html_add_pixmap(GtkHtml * html, GdkPixmap * pm, int fit, int newline) |
1 | 2743 { |
12 | 2744 GtkHtmlBit *last_hb; |
2745 GtkHtmlBit *hb = g_new0(GtkHtmlBit, 1); | |
2746 GdkWindowPrivate *private = (GdkWindowPrivate *) pm; | |
536
c9f994ea5833
[gaim-migrate @ 546]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
526
diff
changeset
|
2747 int width, height; |
12 | 2748 |
2749 last_hb = (GtkHtmlBit *) g_list_last(html->html_bits)->data; | |
1 | 2750 |
536
c9f994ea5833
[gaim-migrate @ 546]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
526
diff
changeset
|
2751 /* wrap pixmaps */ |
c9f994ea5833
[gaim-migrate @ 546]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
526
diff
changeset
|
2752 gdk_window_get_size(html->html_area, &width, &height); |
c9f994ea5833
[gaim-migrate @ 546]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
526
diff
changeset
|
2753 if ((html->current_x + private->width) >= width) { |
c9f994ea5833
[gaim-migrate @ 546]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
526
diff
changeset
|
2754 html->current_x = 0; |
c9f994ea5833
[gaim-migrate @ 546]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
526
diff
changeset
|
2755 } |
499
3ebd3ca4c3d4
[gaim-migrate @ 509]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
492
diff
changeset
|
2756 |
1 | 2757 hb->fit = fit; |
542
872d68495410
[gaim-migrate @ 552]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
540
diff
changeset
|
2758 html->current_x += 2; |
1 | 2759 hb->x = html->current_x; |
2760 hb->y = html->current_y; | |
12 | 2761 if (fit) |
1 | 2762 hb->height = last_hb->height; |
2763 else | |
2764 hb->height = private->height; | |
2765 hb->type = HTML_BIT_PIXMAP; | |
2766 hb->width = private->width; | |
2767 hb->text = NULL; | |
2768 hb->url = NULL; | |
2769 hb->fore = NULL; | |
2770 hb->back = NULL; | |
2771 hb->font = NULL; | |
12 | 2772 hb->uline = 0; |
2773 hb->strike = 0; | |
1 | 2774 hb->was_selected = 0; |
536
c9f994ea5833
[gaim-migrate @ 546]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
526
diff
changeset
|
2775 hb->newline = newline; |
12 | 2776 hb->pm = pm; |
2777 | |
2778 if (html->current_x == BORDER_WIDTH) | |
2779 { | |
540
f586c3819574
[gaim-migrate @ 550]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
537
diff
changeset
|
2780 html->current_y += hb->height + 3; |
f586c3819574
[gaim-migrate @ 550]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
537
diff
changeset
|
2781 hb->y += hb->height + 3; |
1 | 2782 } |
2783 | |
2784 | |
542
872d68495410
[gaim-migrate @ 552]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
540
diff
changeset
|
2785 html->current_x += hb->width + 1; |
12 | 2786 |
1 | 2787 gtk_html_draw_bit(html, hb, 1); |
2788 | |
536
c9f994ea5833
[gaim-migrate @ 546]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
526
diff
changeset
|
2789 if (hb->newline) |
c9f994ea5833
[gaim-migrate @ 546]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
526
diff
changeset
|
2790 html->current_x = 0; |
c9f994ea5833
[gaim-migrate @ 546]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
526
diff
changeset
|
2791 |
1 | 2792 html->html_bits = g_list_append(html->html_bits, hb); |
2793 | |
2794 | |
2795 } | |
2796 | |
914
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2797 static void gtk_html_add_seperator(GtkHtml * html, GdkFont *font, GdkColor *fore, GdkColor *back) |
1 | 2798 { |
12 | 2799 GtkHtmlBit *hb = g_new0(GtkHtmlBit, 1); |
2800 gint width, | |
2801 height; | |
2802 | |
1 | 2803 html->current_x = 0; |
2804 html->current_y += 5; | |
2805 | |
12 | 2806 gdk_window_get_size(html->html_area, &width, &height); |
2807 | |
1 | 2808 hb->x = html->current_x; |
2809 hb->y = html->current_y; | |
2810 hb->height = 5; | |
2811 hb->type = HTML_BIT_SEP; | |
12 | 2812 hb->width = |
2813 width - | |
2814 GTK_SCROLLED_WINDOW(GTK_WIDGET(html)->parent)->vscrollbar->allocation. | |
2815 width - 10; | |
1 | 2816 hb->text = NULL; |
2817 hb->url = NULL; | |
914
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2818 if (fore) |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2819 hb->fore = gdk_color_copy(fore); |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2820 else |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2821 hb->fore = NULL; |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2822 |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2823 if (back) |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2824 hb->back = gdk_color_copy(back); |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2825 else |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2826 hb->back = NULL; |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2827 hb->font = font; |
12 | 2828 hb->uline = 0; |
2829 hb->strike = 0; | |
1 | 2830 hb->was_selected = 0; |
12 | 2831 hb->newline = 0; |
2832 hb->pm = NULL; | |
1 | 2833 |
2834 gtk_html_draw_bit(html, hb, 1); | |
2835 | |
2836 html->html_bits = g_list_append(html->html_bits, hb); | |
2837 | |
2838 } | |
2839 | |
12 | 2840 static void gtk_html_add_text(GtkHtml * html, |
2841 GdkFont * cfont, | |
2842 GdkColor * fore, | |
2843 GdkColor * back, | |
2844 char *chars, | |
2845 gint length, gint uline, gint strike, char *url) | |
1 | 2846 { |
12 | 2847 char *nextline = NULL, |
2848 *c, | |
2849 *text, | |
2850 *tmp; | |
2851 GdkGC *gc; | |
2852 int nl = 0, | |
2853 nl2 = 0; | |
2854 int maxwidth; | |
2855 gint lb; | |
2856 GList *hbits; | |
79 | 2857 size_t num = 0; |
2858 int i, | |
12 | 2859 height; |
2860 GtkHtmlBit *hb; | |
2861 gint hwidth, | |
2862 hheight; | |
2863 | |
2864 if (length == 1 && chars[0] == '\n') | |
2865 { | |
2866 GtkHtmlBit *h; | |
2867 hbits = g_list_last(html->html_bits); | |
2868 if (!hbits) | |
2869 return; | |
2870 /* | |
2871 * I realize this loses a \n sometimes | |
2872 * * if it's the first thing in the widget. | |
2873 * * so fucking what. | |
2874 */ | |
2875 | |
2876 h = (GtkHtmlBit *) hbits->data; | |
2877 h->newline++; | |
2878 if (html->current_x > 0) | |
2879 html->current_x = 0; | |
2880 else | |
540
f586c3819574
[gaim-migrate @ 550]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
537
diff
changeset
|
2881 html->current_y += cfont->ascent + cfont->descent + 5; |
12 | 2882 return; |
2883 } | |
2884 | |
2885 | |
2886 | |
2887 c = text = g_malloc(length + 2); | |
2888 strncpy(text, chars, length); | |
2889 text[length] = 0; | |
2890 | |
2891 | |
2892 gc = html->gc; | |
2893 | |
2894 if (gc == NULL) | |
2895 gc = html->gc = gdk_gc_new(html->html_area); | |
2896 | |
2897 gdk_gc_set_font(gc, cfont); | |
2898 | |
2899 | |
2900 while (*c) | |
2901 { | |
2902 if (*c == '\n') | |
2903 { | |
2904 if (*(c + 1) == '\0') | |
2905 { | |
2906 nl = 1; | |
2907 length--; | |
2908 c[0] = '\0'; | |
2909 break; | |
2910 } | |
2911 if (*c) | |
2912 { | |
2913 gtk_html_add_text(html, cfont, fore, back, text, num + 1, uline, | |
2914 strike, url); | |
2915 tmp = text; | |
2916 length -= (num + 1); | |
2917 text = g_malloc(length + 2); | |
2918 strncpy(text, (c + 1), length); | |
2919 text[length] = 0; | |
2920 c = text; | |
2921 num = 0; | |
2922 g_free(tmp); | |
1 | 2923 continue; |
12 | 2924 } |
2925 } | |
2926 | |
2927 num++; | |
2928 c++; | |
2929 } | |
2930 | |
2931 /* | |
2932 * Note, yG is chosen because G is damn high, and y is damn low, | |
2933 */ | |
2934 /* | |
2935 * it should be just fine. :) | |
2936 */ | |
2937 | |
2938 gdk_window_get_size(html->html_area, &hwidth, &hheight); | |
2939 | |
2940 num = strlen(text); | |
2941 | |
2942 while (GTK_WIDGET(html)->allocation.width < 20) | |
2943 { | |
2944 while (gtk_events_pending()) | |
1 | 2945 gtk_main_iteration(); |
2946 } | |
2947 | |
12 | 2948 maxwidth = (hwidth - html->current_x - 8); |
2949 /* | |
2950 * HTK_SCROLLED_WINDOW(GTK_WIDGET(layout)->parent)->vscrollbar->allocation.width) - 8; | |
2951 */ | |
2952 | |
851
2cee5577224b
[gaim-migrate @ 861]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
850
diff
changeset
|
2953 if ((maxwidth == (hwidth - 8) && gdk_text_measure(cfont, text, num) > 2 * maxwidth) || |
2cee5577224b
[gaim-migrate @ 861]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
850
diff
changeset
|
2954 gdk_text_measure(cfont, text, num) < 0) { |
847
430a88eb4a68
[gaim-migrate @ 857]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
842
diff
changeset
|
2955 int pos = num / 2; |
842
2804dc8e9ba0
[gaim-migrate @ 852]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
829
diff
changeset
|
2956 static int count = 0; |
2804dc8e9ba0
[gaim-migrate @ 852]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
829
diff
changeset
|
2957 count ++; |
850
902be73a6a43
[gaim-migrate @ 860]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
847
diff
changeset
|
2958 while (pos < num && (!isspace(text[pos]) || text[pos] == '\n')) pos++; |
847
430a88eb4a68
[gaim-migrate @ 857]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
842
diff
changeset
|
2959 if (pos == num) { |
430a88eb4a68
[gaim-migrate @ 857]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
842
diff
changeset
|
2960 pos = num/2; |
850
902be73a6a43
[gaim-migrate @ 860]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
847
diff
changeset
|
2961 while (pos > 0 && (!isspace(text[pos]) || text[pos] == '\n')) pos--; |
847
430a88eb4a68
[gaim-migrate @ 857]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
842
diff
changeset
|
2962 if (!pos) pos = num / 2; |
430a88eb4a68
[gaim-migrate @ 857]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
842
diff
changeset
|
2963 } |
850
902be73a6a43
[gaim-migrate @ 860]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
847
diff
changeset
|
2964 gtk_html_add_text(html, cfont, fore, back, text, pos + 1, uline, strike, url); |
902be73a6a43
[gaim-migrate @ 860]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
847
diff
changeset
|
2965 gtk_html_add_text(html, cfont, fore, back, &text[pos+1], 1, uline, strike, url); |
902be73a6a43
[gaim-migrate @ 860]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
847
diff
changeset
|
2966 gtk_html_add_text(html, cfont, fore, back, &text[pos+2], num - pos + 1, uline, strike, url); |
842
2804dc8e9ba0
[gaim-migrate @ 852]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
829
diff
changeset
|
2967 g_free(text); |
2804dc8e9ba0
[gaim-migrate @ 852]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
829
diff
changeset
|
2968 count--; |
2804dc8e9ba0
[gaim-migrate @ 852]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
829
diff
changeset
|
2969 if (!count) { |
853
050f244b6829
[gaim-migrate @ 863]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
852
diff
changeset
|
2970 /* FIXME : sometimes we need to add newline, sometimes we don't */ |
842
2804dc8e9ba0
[gaim-migrate @ 852]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
829
diff
changeset
|
2971 hbits = g_list_last(html->html_bits); |
2804dc8e9ba0
[gaim-migrate @ 852]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
829
diff
changeset
|
2972 if (!hbits) return; /* does this ever happen? */ |
2804dc8e9ba0
[gaim-migrate @ 852]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
829
diff
changeset
|
2973 hb = (GtkHtmlBit *)hbits->data; |
850
902be73a6a43
[gaim-migrate @ 860]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
847
diff
changeset
|
2974 hb->newline++; |
842
2804dc8e9ba0
[gaim-migrate @ 852]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
829
diff
changeset
|
2975 } |
2804dc8e9ba0
[gaim-migrate @ 852]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
829
diff
changeset
|
2976 return; |
2804dc8e9ba0
[gaim-migrate @ 852]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
829
diff
changeset
|
2977 } |
2804dc8e9ba0
[gaim-migrate @ 852]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
829
diff
changeset
|
2978 |
12 | 2979 while (gdk_text_measure(cfont, text, num) > maxwidth) |
2980 { | |
2981 if (num > 1) | |
2982 num--; | |
2983 else | |
2984 { | |
26 | 2985 if (html->current_x != 0) { |
2986 html->current_x = 0; | |
2987 if (nl) { | |
2988 text[length] = '\n'; | |
2989 length++; | |
2990 } | |
2991 gtk_html_add_text(html, cfont, fore, back, text, length, uline, strike, url); | |
2992 g_free(text); | |
2993 return; | |
2994 } else { | |
2995 num = strlen (text); | |
2996 break; | |
1 | 2997 } |
2998 } | |
2999 | |
3000 } | |
3001 | |
12 | 3002 height = cfont->ascent + cfont->descent + 2; |
3003 | |
3004 | |
3005 if ((int) (html->vadj->upper - html->current_y) < (int) (height * 2)) | |
3006 { | |
3007 int val; | |
3008 val = (height * 2) + html->current_y; | |
3009 html->vadj->upper = val; | |
3010 adjust_adj(html, html->vadj); | |
1 | 3011 } |
3012 | |
12 | 3013 |
3014 if (html->current_x == 0) | |
3015 { | |
540
f586c3819574
[gaim-migrate @ 550]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
537
diff
changeset
|
3016 html->current_y += height + 3; |
12 | 3017 gdk_text_extents(cfont, text, 1, &lb, NULL, NULL, NULL, NULL); |
3018 html->current_x += (2 - lb); | |
3019 } | |
3020 else if ((hbits = g_list_last(html->html_bits)) != NULL) | |
3021 { | |
3022 int diff, | |
3023 y; | |
3024 hb = (GtkHtmlBit *) hbits->data; | |
3025 if (height > hb->height) | |
3026 { | |
1 | 3027 diff = height - hb->height; |
3028 y = hb->y; | |
3029 html->current_y += diff; | |
12 | 3030 while (hbits) |
3031 { | |
3032 hb = (GtkHtmlBit *) hbits->data; | |
1 | 3033 if (hb->y != y) |
12 | 3034 break; |
492
56399273ed8d
[gaim-migrate @ 502]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
481
diff
changeset
|
3035 if (hb->type != HTML_BIT_PIXMAP) |
56399273ed8d
[gaim-migrate @ 502]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
481
diff
changeset
|
3036 hb->height = height; |
12 | 3037 hb->y += diff; ////////////my thing here ///////////////// |
3038 gtk_html_draw_bit(html, hb, FALSE); | |
3039 | |
3040 hbits = hbits->prev; | |
1 | 3041 } |
3042 } | |
3043 } | |
3044 | |
3045 | |
3046 | |
3047 | |
12 | 3048 if (num != strlen(text)) |
3049 { | |
3050 /* | |
3051 * This is kinda cheesy but it may make things | |
3052 * * much better lookin | |
3053 */ | |
26 | 3054 |
842
2804dc8e9ba0
[gaim-migrate @ 852]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
829
diff
changeset
|
3055 for (i=2; (num > i); i++) { |
26 | 3056 if (text[num - i] == ' ') { |
12 | 3057 num = num - (i - 1); |
1 | 3058 nl2 = 1; |
3059 break; | |
3060 } | |
3061 } | |
3062 | |
3063 nextline = g_malloc(length - num + 2); | |
12 | 3064 strncpy(nextline, (char *) (text + num), length - num); |
1 | 3065 nextline[length - num] = 0; |
12 | 3066 if (nl) |
3067 { | |
1 | 3068 nextline[length - num] = '\n'; |
3069 nextline[length - num + 1] = 0; | |
3070 nl = 0; | |
3071 } | |
3072 | |
3073 | |
3074 text[num] = 0; | |
3075 } | |
3076 | |
3077 | |
52 | 3078 if (url != NULL) { |
53 | 3079 fore = get_color(3355647, gdk_window_get_colormap(html->html_area)); |
52 | 3080 } |
1 | 3081 |
3082 hb = g_new0(GtkHtmlBit, 1); | |
3083 | |
3084 hb->text = g_strdup(text); | |
3085 | |
52 | 3086 if (fore) |
3087 hb->fore = gdk_color_copy(fore); | |
3088 else | |
3089 hb->fore = NULL; | |
49 | 3090 |
1 | 3091 if (back) |
3092 hb->back = gdk_color_copy(back); | |
3093 else | |
3094 hb->back = NULL; | |
3095 hb->font = cfont; | |
3096 hb->uline = uline; | |
3097 hb->strike = strike; | |
3098 hb->height = height; | |
3099 gdk_text_extents(cfont, text, num, &lb, NULL, &hb->width, NULL, NULL); | |
3100 hb->x = html->current_x; | |
3101 hb->y = html->current_y; | |
12 | 3102 hb->type = HTML_BIT_TEXT; |
3103 hb->pm = NULL; | |
3104 if (url != NULL) | |
3105 { | |
1 | 3106 uline = 1; |
3107 hb->uline = 1; | |
3108 hb->url = g_strdup(url); | |
12 | 3109 } |
3110 else | |
3111 { | |
1 | 3112 hb->url = NULL; |
3113 } | |
3114 html->current_x += hb->width; | |
3115 | |
3116 html->html_bits = g_list_append(html->html_bits, hb); | |
12 | 3117 if (url != NULL) |
3118 { | |
3119 html->urls = g_list_append(html->urls, hb); | |
3120 } | |
3121 | |
3122 | |
3123 | |
3124 gtk_html_draw_bit(html, hb, 1); | |
3125 | |
3126 if (nl || nl2) | |
3127 { | |
3128 if (nl) | |
3129 hb->newline = 1; | |
3130 html->current_x = 0; | |
3131 } | |
3132 else | |
3133 hb->newline = 0; | |
3134 | |
3135 | |
3136 if (nextline != NULL) | |
3137 { | |
3138 gtk_html_add_text(html, cfont, fore, back, nextline, strlen(nextline), | |
3139 uline, strike, url); | |
3140 g_free(nextline); | |
3141 } | |
3142 | |
3143 g_free(text); | |
137 | 3144 if (url != NULL) |
3145 g_free(fore); | |
1 | 3146 } |
3147 | |
12 | 3148 static char * html_strtok( char * input, char delim ) |
1 | 3149 { |
12 | 3150 static char * end; |
3151 static char * curr_offset; | |
3152 int i; | |
3153 int num_quotes=0; | |
3154 | |
3155 if( input != NULL) | |
3156 { | |
3157 curr_offset = input; | |
3158 end = input+strlen(input); | |
3159 } | |
3160 else | |
3161 { | |
3162 if( curr_offset + strlen(curr_offset) < end ) | |
3163 { | |
3164 curr_offset += strlen(curr_offset) + 1; | |
3165 } | |
3166 else | |
3167 { | |
3168 return NULL; | |
3169 } | |
3170 } | |
3171 for( i=0; curr_offset+i < end && | |
3172 (curr_offset[i] != delim || num_quotes != 0) | |
3173 ; i++ ) | |
3174 { | |
3175 if( curr_offset[i] == '\"' ) | |
3176 { | |
3177 num_quotes = (num_quotes+1)%2; | |
3178 } | |
3179 } | |
3180 curr_offset[i] = '\0'; | |
3181 return curr_offset; | |
3182 } | |
3183 | |
3184 | |
3185 void gtk_html_append_text(GtkHtml * html, char *text, gint options) | |
3186 { | |
3187 GdkColormap *map; | |
1 | 3188 GdkFont *cfont; |
12 | 3189 GdkRectangle area; |
829
9a123b171f46
[gaim-migrate @ 839]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
791
diff
changeset
|
3190 char *ws, |
12 | 3191 tag[BUF_LONG], |
3192 *c, | |
3193 *url = NULL; | |
3194 gint intag = 0, | |
3195 wpos = 0, | |
481
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3196 tpos = 0; |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3197 static gint colorv, |
12 | 3198 bold = 0, |
3199 italic = 0, | |
3200 fixed = 0, | |
3201 uline = 0, | |
3202 strike = 0, | |
481
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3203 title = 0, |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3204 height; |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3205 static struct font_state *current = NULL, |
12 | 3206 *tmp; |
481
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3207 static struct font_state def_state = { 3, 0, 0, "", NULL, NULL, NULL }; |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3208 |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3209 if (text == NULL) { |
740
01d3c96867e2
[gaim-migrate @ 750]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
737
diff
changeset
|
3210 bold = 0; |
01d3c96867e2
[gaim-migrate @ 750]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
737
diff
changeset
|
3211 italic = 0; |
01d3c96867e2
[gaim-migrate @ 750]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
737
diff
changeset
|
3212 fixed = 0; |
01d3c96867e2
[gaim-migrate @ 750]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
737
diff
changeset
|
3213 uline = 0; |
01d3c96867e2
[gaim-migrate @ 750]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
737
diff
changeset
|
3214 strike = 0; |
01d3c96867e2
[gaim-migrate @ 750]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
737
diff
changeset
|
3215 title = 0; |
481
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3216 while (current->next) |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3217 { |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3218 if (current->ownbg) |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3219 g_free(current->bgcol); |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3220 if (current->owncolor) |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3221 g_free(current->color); |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3222 tmp = current; |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3223 current = current->next; |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3224 g_free(tmp); |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3225 } |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3226 return; |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3227 } |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3228 |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3229 if (!current) current = &def_state; |
12 | 3230 map = gdk_window_get_colormap(html->html_area); |
3231 cfont = getfont(current->font, bold, italic, fixed, current->size); | |
1 | 3232 c = text; |
3233 | |
829
9a123b171f46
[gaim-migrate @ 839]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
791
diff
changeset
|
3234 ws = g_malloc(strlen(text) + 2); |
1 | 3235 |
12 | 3236 while (*c) |
3237 { | |
3238 if (*c == '<') | |
3239 { | |
3240 if (!intag) | |
3241 { | |
3242 ws[wpos] = 0; | |
3243 if (wpos) | |
3244 { | |
3245 if (title) | |
3246 { | |
3247 if (html->title) | |
3248 g_free(html->title); | |
3249 html->title = g_strdup(ws); | |
3250 } | |
3251 else | |
3252 gtk_html_add_text(html, cfont, current->color, | |
3253 current->bgcol, ws, strlen(ws), uline, | |
3254 strike, url); | |
3255 } | |
3256 wpos = 0; | |
3257 intag = 1; | |
3258 } | |
3259 else | |
3260 { | |
3261 /* | |
3262 * Assuming you NEVER have nested tags | |
3263 * * (and I mean <tag <tag>> by this, not | |
3264 * * <tag><tag2></tag2><tag>.. | |
3265 */ | |
3266 tag[tpos] = 0; | |
3267 gtk_html_add_text(html, cfont, current->color, current->bgcol, | |
3268 "<", 1, 0, 0, NULL); | |
3269 gtk_html_add_text(html, cfont, current->color, current->bgcol, | |
3270 tag, strlen(tag), 0, 0, NULL); | |
1 | 3271 tpos = 0; |
12 | 3272 |
3273 tag[0] = *c; | |
1 | 3274 } |
12 | 3275 } |
3276 else if (*c == '>') | |
3277 { | |
3278 if (intag) | |
3279 { | |
3280 tag[tpos] = 0; | |
1 | 3281 if (!strcasecmp(tag, "B")) |
3282 bold = 1; | |
732 | 3283 else if (!strcasecmp(tag, "STRIKE") || !strcasecmp(tag, "S")) |
1 | 3284 strike = 1; |
3285 else if (!strcasecmp(tag, "I")) | |
3286 italic = 1; | |
3287 else if (!strcasecmp(tag, "U")) | |
3288 uline = 1; | |
3289 else if (!strcasecmp(tag, "PRE")) | |
3290 fixed = 1; | |
3291 else if (!strcasecmp(tag, "HR")) | |
914
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
3292 gtk_html_add_seperator(html, cfont, current->color, current->bgcol); |
1 | 3293 else if (!strcasecmp(tag, "/B")) |
3294 bold = 0; | |
732 | 3295 else if (!strcasecmp(tag, "/STRIKE") || !strcasecmp(tag, "/S")) |
1 | 3296 strike = 0; |
3297 else if (!strcasecmp(tag, "/I")) | |
3298 italic = 0; | |
3299 else if (!strcasecmp(tag, "/U")) | |
3300 uline = 0; | |
3301 else if (!strcasecmp(tag, "/PRE")) | |
3302 fixed = 0; | |
3303 else if (!strcasecmp(tag, "TITLE")) | |
3304 title = 1; | |
3305 else if (!strcasecmp(tag, "/TITLE")) | |
3306 title = 0; | |
12 | 3307 else if (!strncasecmp(tag, "IMG", 3)) |
3308 { | |
549 | 3309 GdkPixmap *legend_i; |
3310 GdkBitmap *legend_m; | |
3311 | |
3312 if (strstr(tag, "SRC=\"aol_icon.gif\"") != NULL) | |
3313 { | |
3314 legend_i = gdk_pixmap_create_from_xpm_d(GTK_WIDGET(html)->window, &legend_m, NULL, aol_icon_xpm); | |
3315 gtk_html_add_pixmap(html, legend_i, 0, 0); | |
3316 } | |
3317 | |
3318 if (strstr(tag, "SRC=\"admin_icon.gif\"") != NULL) | |
3319 { | |
3320 legend_i = gdk_pixmap_create_from_xpm_d(GTK_WIDGET(html)->window, &legend_m, NULL, admin_icon_xpm); | |
3321 gtk_html_add_pixmap(html, legend_i, 0, 0); | |
3322 } | |
3323 if (strstr(tag, "SRC=\"dt_icon.gif\"") != NULL) | |
3324 { | |
3325 legend_i = gdk_pixmap_create_from_xpm_d(GTK_WIDGET(html)->window, &legend_m, NULL, dt_icon_xpm); | |
3326 gtk_html_add_pixmap(html, legend_i, 0, 0); | |
3327 } | |
3328 if (strstr(tag, "SRC=\"free_icon.gif\"") != NULL) | |
3329 { | |
3330 legend_i = gdk_pixmap_create_from_xpm_d(GTK_WIDGET(html)->window, &legend_m, NULL, free_icon_xpm); | |
3331 gtk_html_add_pixmap(html, legend_i, 0, 0); | |
3332 } | |
12 | 3333 } |
3334 else if (!strcasecmp(tag, "H3")) | |
3335 { | |
1 | 3336 current = push_state(current); |
3337 current->size = 4; | |
12 | 3338 } |
3339 else if (!strcasecmp(tag, "/H3")) | |
3340 { | |
3341 gtk_html_add_text(html, cfont, current->color, | |
3342 current->bgcol, "\n", 1, 0, 0, NULL); | |
3343 | |
3344 if (current->next) | |
3345 { | |
1 | 3346 if (current->ownbg) |
3347 g_free(current->bgcol); | |
3348 if (current->owncolor) | |
3349 g_free(current->color); | |
12 | 3350 tmp = current; |
3351 current = current->next; | |
3352 g_free(tmp); | |
1 | 3353 } |
12 | 3354 } |
3355 else if (!strcasecmp(tag, "TABLE")) | |
3356 { | |
3357 } | |
3358 else if (!strcasecmp(tag, "/TABLE")) | |
3359 { | |
3360 } | |
3361 else if (!strcasecmp(tag, "TR")) | |
3362 { | |
3363 } | |
3364 else if (!strcasecmp(tag, "/TR")) | |
3365 { | |
3366 } | |
3367 else if (!strcasecmp(tag, "/TD")) | |
3368 { | |
3369 } | |
3370 else if (!strcasecmp(tag, "TD")) | |
3371 { | |
3372 gtk_html_add_text(html, cfont, current->color, | |
3373 current->bgcol, " ", 2, 0, 0, NULL); | |
3374 } | |
3375 else if (!strncasecmp(tag, "A ", 2)) | |
3376 { | |
1 | 3377 char *d; |
3378 char *temp = d = g_strdup(tag); | |
3379 int flag = 0; | |
12 | 3380 strtok(tag, " "); |
3381 while ((d = strtok(NULL, " "))) | |
3382 { | |
1 | 3383 if (strlen(d) < 7) |
3384 break; | |
12 | 3385 if (!strncasecmp(d, "HREF=\"", strlen("HREF=\""))) |
3386 { | |
3387 d += strlen("HREF=\""); | |
1 | 3388 d[strlen(d) - 1] = 0; |
3389 url = g_malloc(strlen(d) + 1); | |
3390 strcpy(url, d); | |
3391 flag = 1; | |
12 | 3392 } |
3393 } | |
1 | 3394 g_free(temp); |
12 | 3395 if (!flag) |
3396 { | |
3397 gtk_html_add_text(html, cfont, current->color, | |
3398 current->bgcol, "<", 1, 0, 0, NULL); | |
3399 gtk_html_add_text(html, cfont, current->color, | |
3400 current->bgcol, tag, strlen(tag), 0, | |
3401 0, NULL); | |
3402 gtk_html_add_text(html, cfont, current->color, | |
3403 current->bgcol, ">", 1, 0, 0, NULL); | |
1 | 3404 } |
12 | 3405 } |
3406 else if (!strcasecmp(tag, "/A")) | |
3407 { | |
3408 if (url) | |
3409 { | |
1 | 3410 g_free(url); |
3411 url = NULL; | |
3412 } | |
12 | 3413 } |
3414 else if (!strncasecmp(tag, "FONT", strlen("FONT"))) | |
3415 { | |
3416 char *d; | |
3417 /* | |
3418 * Push a new state onto the stack, based on the old state | |
3419 */ | |
3420 current = push_state(current); | |
3421 html_strtok(tag, ' '); | |
3422 while ((d = html_strtok(NULL, ' '))) | |
3423 { | |
3424 if (!strncasecmp(d, "COLOR=", strlen("COLOR="))) | |
3425 { | |
3426 d += strlen("COLOR="); | |
3427 if (*d == '\"') | |
3428 { | |
3429 d++; | |
3430 } | |
3431 if (*d == '#') | |
3432 d++; | |
3433 if (d[strlen(d) - 1] == '\"') | |
3434 d[strlen(d) - 1] = 0; | |
3435 if (sscanf(d, "%x", &colorv) | |
3436 && !(options & HTML_OPTION_NO_COLOURS)) | |
3437 { | |
677
05f6f7dabb7e
[gaim-migrate @ 687]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
674
diff
changeset
|
3438 current->color = get_color(colorv, map); |
05f6f7dabb7e
[gaim-migrate @ 687]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
674
diff
changeset
|
3439 current->owncolor = 1; |
12 | 3440 } |
3441 else | |
3442 { | |
1 | 3443 } |
12 | 3444 } |
3445 if (!strncasecmp(d, "FACE=", strlen("FACE="))) | |
3446 { | |
3447 d += strlen("FACE="); | |
3448 if (*d == '\"') | |
3449 { | |
3450 d++; | |
3451 } | |
1 | 3452 if (d[strlen(d) - 1] == '\"') |
3453 d[strlen(d) - 1] = 0; | |
12 | 3454 strcpy(current->font, d); |
3455 } | |
3456 else if (!strncasecmp(d, "BACK=", strlen("BACK="))) | |
3457 { | |
3458 d += strlen("BACK="); | |
3459 if (*d == '\"') | |
3460 d++; | |
3461 if (*d == '#') | |
3462 d++; | |
3463 if (d[strlen(d) - 1] == '\"') | |
3464 d[strlen(d) - 1] = 0; | |
3465 if (sscanf(d, "%x", &colorv) | |
3466 && !(options & HTML_OPTION_NO_COLOURS)) | |
3467 { | |
1 | 3468 current->bgcol = get_color(colorv, map); |
3469 current->ownbg = 1; | |
12 | 3470 } |
3471 else | |
3472 { | |
3473 } | |
3474 } | |
3475 else if (!strncasecmp(d, "SIZE=", strlen("SIZE="))) | |
3476 { | |
3477 d += strlen("SIZE="); | |
3478 if (*d == '\"') | |
3479 d++; | |
3480 if (*d == '+') | |
3481 d++; | |
3482 if (sscanf(d, "%d", &colorv)) | |
3483 { | |
3484 current->size = colorv; | |
3485 } | |
3486 else | |
3487 { | |
1 | 3488 } |
12 | 3489 } |
3490 else if (strncasecmp(d, "PTSIZE=", strlen("PTSIZE="))) | |
3491 { | |
3492 } | |
1 | 3493 } |
12 | 3494 } |
669
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3495 else if (!strncasecmp(tag, "BODY", strlen("BODY"))) |
12 | 3496 { |
3497 | |
669
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3498 char *d; |
632
21c63b26c604
[gaim-migrate @ 642]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
629
diff
changeset
|
3499 current = push_state(current); |
669
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3500 html_strtok(tag, ' '); |
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3501 while ((d = html_strtok(NULL, ' '))) |
12 | 3502 { |
669
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3503 if (!strncasecmp(d, "BGCOLOR=", strlen("BGCOLOR="))) |
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3504 { |
677
05f6f7dabb7e
[gaim-migrate @ 687]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
674
diff
changeset
|
3505 d += strlen("BGCOLOR="); |
669
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3506 if (*d == '\"') |
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3507 d++; |
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3508 if (*d == '#') |
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3509 d++; |
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3510 if (d[strlen(d) - 1] == '\"') |
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3511 d[strlen(d) - 1] = 0; |
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3512 if (sscanf(d, "%x", &colorv) |
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3513 && !(options & HTML_OPTION_NO_COLOURS)) |
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3514 { |
677
05f6f7dabb7e
[gaim-migrate @ 687]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
674
diff
changeset
|
3515 if (colorv != 0xffffff || |
669
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3516 !(display_options & OPT_DISP_IGN_WHITE)) { |
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3517 current->bgcol = get_color(colorv, map); |
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3518 current->ownbg = 1; |
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3519 } |
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3520 } |
667
45ed2ca0756e
[gaim-migrate @ 677]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
666
diff
changeset
|
3521 } |
12 | 3522 } |
3523 } | |
3524 else if (!strncasecmp(tag, "/FONT", strlen("/FONT"))) | |
3525 { | |
3526 /* | |
3527 * Pop a font state off the list if possible, freeing | |
3528 * any resources it used | |
3529 */ | |
3530 if (current->next) | |
3531 { | |
1 | 3532 if (current->ownbg) |
3533 g_free(current->bgcol); | |
3534 if (current->owncolor) | |
3535 g_free(current->color); | |
12 | 3536 tmp = current; |
3537 current = current->next; | |
3538 g_free(tmp); | |
3539 } | |
3540 | |
3541 } | |
3542 else if (!strcasecmp(tag, "/BODY")) | |
3543 { | |
3544 if (current->next) | |
3545 { | |
3546 if (current->ownbg) | |
3547 g_free(current->bgcol); | |
3548 if (current->owncolor) | |
3549 g_free(current->color); | |
3550 tmp = current; | |
3551 current = current->next; | |
1 | 3552 g_free(tmp); |
12 | 3553 } /* |
3554 * tags we ignore below | |
3555 */ | |
3556 } | |
3557 else if (!strncasecmp(tag, "BR", 2)) | |
3558 { | |
3559 gtk_html_add_text(html, cfont, current->color, | |
3560 current->bgcol, "\n", 1, 0, 0, NULL); | |
3561 } | |
3562 else if (strncasecmp(tag, "HTML", 4) | |
3563 && strncasecmp(tag, "/HTML", 5) | |
3564 && strncasecmp(tag, "BODY", 4) | |
3565 && strncasecmp(tag, "/BODY", 5) | |
627
da0a1238874d
[gaim-migrate @ 637]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
604
diff
changeset
|
3566 && (strncasecmp(tag, "P", 1) || tag[1] != '>') |
da0a1238874d
[gaim-migrate @ 637]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
604
diff
changeset
|
3567 && (strncasecmp(tag, "/P", 2) || tag[3] != '>') |
12 | 3568 && strncasecmp(tag, "HEAD", 4) |
3569 && strncasecmp(tag, "/HEAD", 5)) | |
3570 { | |
3571 if (tpos) | |
3572 { | |
3573 gtk_html_add_text(html, cfont, current->color, | |
3574 current->bgcol, "<", 1, 0, 0, NULL); | |
3575 gtk_html_add_text(html, cfont, current->color, | |
3576 current->bgcol, tag, strlen(tag), 0, | |
3577 0, NULL); | |
3578 gtk_html_add_text(html, cfont, current->color, | |
3579 current->bgcol, ">", 1, 0, 0, NULL); | |
1 | 3580 |
3581 } | |
3582 } | |
12 | 3583 cfont = getfont(current->font, bold, italic, fixed, current->size); |
3584 tpos = 0; | |
1 | 3585 intag = 0; |
3586 } | |
12 | 3587 else |
3588 { | |
1 | 3589 ws[wpos++] = *c; |
3590 } | |
12 | 3591 } |
3592 else if (!intag && *c == '&') | |
3593 { | |
3594 if (!strncasecmp(c, "&", 5)) | |
3595 { | |
3596 ws[wpos++] = '&'; | |
3597 c += 4; | |
3598 } | |
3599 else if (!strncasecmp(c, "<", 4)) | |
3600 { | |
3601 ws[wpos++] = '<'; | |
3602 c += 3; | |
3603 } | |
3604 else if (!strncasecmp(c, ">", 4)) | |
3605 { | |
3606 ws[wpos++] = '>'; | |
3607 c += 3; | |
3608 } | |
3609 else if (!strncasecmp(c, " ", 6)) | |
3610 { | |
3611 ws[wpos++] = ' '; | |
3612 c += 5; | |
3613 } | |
526
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3614 else if (!strncasecmp(c, "©", 6)) |
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3615 { |
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3616 ws[wpos++] = '©'; |
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3617 c += 5; |
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3618 } |
737
c3a920cee3fc
[gaim-migrate @ 747]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
732
diff
changeset
|
3619 else if (!strncasecmp(c, """, 6)) |
c3a920cee3fc
[gaim-migrate @ 747]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
732
diff
changeset
|
3620 { |
c3a920cee3fc
[gaim-migrate @ 747]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
732
diff
changeset
|
3621 ws[wpos++] = '\"'; |
c3a920cee3fc
[gaim-migrate @ 747]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
732
diff
changeset
|
3622 c += 5; |
c3a920cee3fc
[gaim-migrate @ 747]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
732
diff
changeset
|
3623 } |
c3a920cee3fc
[gaim-migrate @ 747]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
732
diff
changeset
|
3624 else if (!strncasecmp(c, "®", 5)) |
c3a920cee3fc
[gaim-migrate @ 747]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
732
diff
changeset
|
3625 { |
c3a920cee3fc
[gaim-migrate @ 747]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
732
diff
changeset
|
3626 ws[wpos++] = 174; |
c3a920cee3fc
[gaim-migrate @ 747]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
732
diff
changeset
|
3627 c += 4; |
c3a920cee3fc
[gaim-migrate @ 747]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
732
diff
changeset
|
3628 } |
526
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3629 else if (*(c + 1) == '#') |
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3630 { |
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3631 int pound = 0; |
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3632 debug_print("got &#;\n"); |
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3633 if (sscanf(c, "&#%d;", £) > 0) { |
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3634 ws[wpos++] = (char)pound; |
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3635 c += 2; |
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3636 while (isdigit(*c)) c++; |
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3637 if (*c != ';') c--; |
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3638 } else { |
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3639 ws[wpos++] = *c; |
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3640 } |
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3641 } |
12 | 3642 else |
3643 { | |
3644 ws[wpos++] = *c; | |
3645 } | |
3646 } | |
3647 else | |
3648 { | |
3649 if (intag) | |
3650 { | |
3651 tag[tpos++] = *c; | |
3652 } | |
3653 else | |
3654 { | |
3655 ws[wpos++] = *c; | |
1 | 3656 } |
3657 } | |
3658 c++; | |
3659 } | |
12 | 3660 ws[wpos] = 0; |
3661 tag[tpos] = 0; | |
3662 if (wpos) | |
3663 { | |
3664 gtk_html_add_text(html, cfont, current->color, current->bgcol, ws, | |
3665 strlen(ws), uline, strike, url); | |
1 | 3666 } |
12 | 3667 if (tpos) |
3668 { | |
3669 gtk_html_add_text(html, cfont, current->color, current->bgcol, "<", 1, | |
3670 0, 0, NULL); | |
3671 gtk_html_add_text(html, cfont, current->color, current->bgcol, tag, | |
3672 strlen(tag), 0, 0, NULL); | |
523
023c3851db0a
[gaim-migrate @ 533]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
506
diff
changeset
|
3673 /* gtk_html_add_text(html, cfont, current->color, current->bgcol, ">", 1, |
12 | 3674 0, 0, NULL); |
523
023c3851db0a
[gaim-migrate @ 533]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
506
diff
changeset
|
3675 */ } |
12 | 3676 |
3677 | |
829
9a123b171f46
[gaim-migrate @ 839]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
791
diff
changeset
|
3678 g_free(ws); |
12 | 3679 |
3680 gdk_window_get_size(html->html_area, NULL, &height); | |
3681 area.height = height; | |
1 | 3682 gtk_adjustment_set_value(html->vadj, html->vadj->upper - area.height); |
3683 | |
12 | 3684 return; |
1 | 3685 } |
3686 | |
3687 | |
12 | 3688 static void adjust_adj(GtkHtml * html, GtkAdjustment * adj) |
1 | 3689 { |
12 | 3690 gint height; |
3691 | |
3692 gdk_window_get_size(html->html_area, NULL, &height); | |
3693 | |
3694 adj->step_increment = MIN(adj->upper, (float) SCROLL_PIXELS); | |
3695 adj->page_increment = MIN(adj->upper, height - (float) KEY_SCROLL_PIXELS); | |
3696 adj->page_size = MIN(adj->upper, height); | |
3697 adj->value = MIN(adj->value, adj->upper - adj->page_size); | |
3698 adj->value = MAX(adj->value, 0.0); | |
3699 | |
3700 gtk_signal_emit_by_name(GTK_OBJECT(adj), "changed"); | |
1 | 3701 } |
3702 | |
3703 | |
12 | 3704 static void scroll_down(GtkHtml * html, gint diff0) |
1 | 3705 { |
12 | 3706 GdkRectangle rect; |
3707 gint width, | |
3708 height; | |
3709 | |
3710 html->yoffset += diff0; | |
3711 | |
3712 gdk_window_get_size(html->html_area, &width, &height); | |
3713 | |
3714 if (html->transparent) | |
3715 { | |
1 | 3716 rect.x = 0; |
3717 rect.y = 0; | |
3718 rect.width = width; | |
3719 rect.height = height; | |
12 | 3720 } |
3721 else | |
3722 { | |
3723 | |
1 | 3724 |
3725 if (height > diff0 && !html->transparent) | |
12 | 3726 gdk_draw_pixmap(html->html_area, |
3727 html->gc, | |
3728 html->html_area, | |
3729 0, diff0, 0, 0, width, height - diff0); | |
3730 | |
3731 rect.x = 0; | |
3732 rect.y = MAX(0, height - diff0); | |
3733 rect.width = width; | |
3734 rect.height = MIN(height, diff0); | |
1 | 3735 } |
12 | 3736 |
3737 expose_html(html, &rect, FALSE); | |
3738 gtk_html_draw_focus((GtkWidget *) html); | |
1 | 3739 |
3740 } | |
3741 | |
12 | 3742 static void scroll_up(GtkHtml * html, gint diff0) |
1 | 3743 { |
12 | 3744 GdkRectangle rect; |
3745 gint width, | |
3746 height; | |
3747 | |
1 | 3748 html->yoffset -= diff0; |
3749 | |
3750 | |
12 | 3751 gdk_window_get_size(html->html_area, &width, &height); |
3752 | |
3753 if (html->transparent) | |
3754 { | |
1 | 3755 rect.x = 0; |
3756 rect.y = 0; | |
3757 rect.width = width; | |
3758 rect.height = height; | |
12 | 3759 } |
3760 else | |
3761 { | |
3762 | |
1 | 3763 if (height > diff0) |
12 | 3764 gdk_draw_pixmap(html->html_area, |
3765 html->gc, | |
3766 html->html_area, | |
3767 0, 0, 0, diff0, width, height - diff0); | |
3768 | |
3769 rect.x = 0; | |
3770 rect.y = 0; | |
3771 rect.width = width; | |
3772 rect.height = MIN(height, diff0); | |
1 | 3773 } |
3774 | |
12 | 3775 expose_html(html, &rect, FALSE); |
3776 gtk_html_draw_focus((GtkWidget *) html); | |
1 | 3777 |
3778 } | |
3779 | |
3780 | |
3781 | |
12 | 3782 static void gtk_html_adjustment(GtkAdjustment * adjustment, GtkHtml * html) |
1 | 3783 { |
12 | 3784 g_return_if_fail(adjustment != NULL); |
3785 g_return_if_fail(GTK_IS_ADJUSTMENT(adjustment)); | |
3786 g_return_if_fail(html != NULL); | |
3787 g_return_if_fail(GTK_IS_HTML(html)); | |
3788 | |
3789 /* | |
3790 * Just ignore it if we haven't been size-allocated and realized yet | |
3791 */ | |
3792 if (html->html_area == NULL) | |
3793 return; | |
3794 | |
3795 if (adjustment == html->hadj) | |
3796 { | |
3797 g_warning("horizontal scrolling not implemented"); | |
3798 } | |
3799 else | |
3800 { | |
3801 gint diff = ((gint) adjustment->value) - html->last_ver_value; | |
3802 | |
3803 if (diff != 0) | |
3804 { | |
3805 /* | |
3806 * undraw_cursor (text, FALSE); | |
3807 */ | |
3808 | |
3809 if (diff > 0) | |
3810 { | |
3811 scroll_down(html, diff); | |
3812 } | |
3813 else | |
3814 { /* | |
3815 * if (diff < 0) | |
3816 */ | |
3817 scroll_up(html, -diff); | |
3818 } | |
3819 /* | |
3820 * draw_cursor (text, FALSE); | |
3821 */ | |
3822 | |
3823 html->last_ver_value = adjustment->value; | |
3824 } | |
3825 } | |
1 | 3826 } |
12 | 3827 |
3828 static gint gtk_html_visibility_notify(GtkWidget * widget, | |
3829 GdkEventVisibility * event) | |
1 | 3830 { |
3831 GtkHtml *html; | |
3832 GdkRectangle rect; | |
12 | 3833 gint width, |
3834 height; | |
3835 | |
3836 g_return_val_if_fail(widget != NULL, FALSE); | |
3837 g_return_val_if_fail(GTK_IS_HTML(widget), FALSE); | |
3838 | |
3839 html = GTK_HTML(widget); | |
3840 | |
3841 if (GTK_WIDGET_REALIZED(widget) && html->transparent) | |
3842 { | |
3843 gdk_window_get_size(html->html_area, &width, &height); | |
3844 rect.x = 0; | |
3845 rect.y = 0; | |
3846 rect.width = width; | |
3847 rect.height = height; | |
3848 expose_html(html, &rect, FALSE); | |
3849 gtk_html_draw_focus((GtkWidget *) html); | |
3850 } | |
3851 else | |
3852 { | |
1 | 3853 } |
3854 | |
3855 | |
12 | 3856 return FALSE; |
1 | 3857 } |
3858 | |
3859 | |
3860 | |
12 | 3861 static void gtk_html_disconnect(GtkAdjustment * adjustment, GtkHtml * html) |
1 | 3862 { |
12 | 3863 g_return_if_fail(adjustment != NULL); |
3864 g_return_if_fail(GTK_IS_ADJUSTMENT(adjustment)); | |
3865 g_return_if_fail(html != NULL); | |
3866 g_return_if_fail(GTK_IS_HTML(html)); | |
3867 | |
3868 if (adjustment == html->hadj) | |
3869 gtk_html_set_adjustments(html, NULL, html->vadj); | |
3870 if (adjustment == html->vadj) | |
3871 gtk_html_set_adjustments(html, html->hadj, NULL); | |
1 | 3872 } |
3873 | |
12 | 3874 static void move_cursor_ver(GtkHtml * html, int count) |
1 | 3875 { |
3876 GList *hbits = g_list_find(html->html_bits, html->cursor_hb); | |
12 | 3877 GtkHtmlBit *hb = NULL, |
3878 *hb2 = NULL; | |
1 | 3879 gint y; |
79 | 3880 size_t len, |
12 | 3881 len2 = 0; |
3882 | |
1 | 3883 undraw_cursor(html); |
3884 | |
3885 if (!html->html_bits) | |
3886 return; | |
12 | 3887 |
1 | 3888 if (!html->cursor_hb) |
12 | 3889 html->cursor_hb = (GtkHtmlBit *) html->html_bits->data; |
1 | 3890 |
3891 hb = html->cursor_hb; | |
3892 | |
3893 len = html->cursor_pos; | |
3894 hbits = hbits->prev; | |
12 | 3895 while (hbits) |
3896 { | |
3897 hb2 = (GtkHtmlBit *) hbits->data; | |
1 | 3898 |
3899 if (hb2->y != hb->y) | |
3900 break; | |
3901 | |
12 | 3902 len += strlen(hb2->text); |
3903 | |
1 | 3904 hbits = hbits->prev; |
3905 } | |
3906 | |
12 | 3907 hbits = g_list_find(html->html_bits, html->cursor_hb); |
3908 | |
3909 if (count < 0) | |
3910 { | |
3911 while (hbits) | |
3912 { | |
3913 hb2 = (GtkHtmlBit *) hbits->data; | |
1 | 3914 |
3915 if (hb2->y != hb->y) | |
3916 break; | |
12 | 3917 |
1 | 3918 hbits = hbits->prev; |
3919 } | |
12 | 3920 if (!hbits) |
3921 { | |
1 | 3922 draw_cursor(html); |
3923 return; | |
3924 } | |
3925 y = hb2->y; | |
3926 hb = hb2; | |
12 | 3927 while (hbits) |
3928 { | |
3929 hb2 = (GtkHtmlBit *) hbits->data; | |
1 | 3930 |
3931 if (hb2->y != y) | |
3932 break; | |
3933 | |
3934 hb = hb2; | |
12 | 3935 |
1 | 3936 hbits = hbits->prev; |
3937 } | |
3938 hbits = g_list_find(html->html_bits, hb); | |
12 | 3939 while (hbits) |
3940 { | |
3941 hb2 = (GtkHtmlBit *) hbits->data; | |
3942 | |
3943 if (hb->y != hb2->y) | |
3944 { | |
1 | 3945 html->cursor_hb = hb; |
3946 html->cursor_pos = strlen(hb->text); | |
12 | 3947 break; |
1 | 3948 } |
3949 | |
3950 | |
12 | 3951 if (len < len2 + strlen(hb2->text)) |
3952 { | |
1 | 3953 html->cursor_hb = hb2; |
3954 html->cursor_pos = len - len2; | |
3955 break; | |
3956 } | |
3957 | |
3958 len2 += strlen(hb2->text); | |
3959 | |
3960 hb = hb2; | |
3961 | |
12 | 3962 hbits = hbits->next; |
1 | 3963 } |
12 | 3964 } |
3965 else | |
3966 { | |
3967 while (hbits) | |
3968 { | |
3969 hb2 = (GtkHtmlBit *) hbits->data; | |
1 | 3970 |
3971 if (hb2->y != hb->y) | |
3972 break; | |
12 | 3973 |
1 | 3974 hbits = hbits->next; |
3975 } | |
12 | 3976 if (!hbits) |
3977 { | |
1 | 3978 draw_cursor(html); |
3979 return; | |
3980 } | |
3981 hb = hb2; | |
12 | 3982 while (hbits) |
3983 { | |
3984 hb2 = (GtkHtmlBit *) hbits->data; | |
3985 | |
3986 if (hb->y != hb2->y) | |
3987 { | |
1 | 3988 html->cursor_hb = hb; |
3989 html->cursor_pos = strlen(hb->text); | |
12 | 3990 break; |
1 | 3991 } |
3992 | |
3993 | |
12 | 3994 if (len < len2 + strlen(hb2->text)) |
3995 { | |
1 | 3996 html->cursor_hb = hb2; |
3997 html->cursor_pos = len - len2; | |
3998 break; | |
3999 } | |
4000 | |
4001 len2 += strlen(hb2->text); | |
4002 | |
4003 hb = hb2; | |
4004 | |
12 | 4005 hbits = hbits->next; |
1 | 4006 } |
4007 } | |
4008 | |
4009 draw_cursor(html); | |
4010 | |
4011 } | |
4012 | |
12 | 4013 static void move_cursor_hor(GtkHtml * html, int count) |
1 | 4014 { |
4015 GList *hbits = g_list_find(html->html_bits, html->cursor_hb); | |
12 | 4016 GtkHtmlBit *hb, |
4017 *hb2; | |
1 | 4018 |
4019 undraw_cursor(html); | |
4020 | |
4021 if (!html->html_bits) | |
4022 return; | |
12 | 4023 |
1 | 4024 if (!html->cursor_hb) |
12 | 4025 html->cursor_hb = (GtkHtmlBit *) html->html_bits->data; |
4026 | |
4027 html->cursor_pos += count; | |
4028 | |
4029 if (html->cursor_pos < 0) | |
4030 { | |
4031 if (hbits->prev) | |
4032 { | |
1 | 4033 gint diff; |
4034 hb = html->cursor_hb; | |
12 | 4035 hb2 = (GtkHtmlBit *) hbits->prev->data; |
1 | 4036 diff = html->cursor_pos + strlen(hb2->text) + 1; |
4037 if (hb->y == hb2->y) | |
4038 --diff; | |
12 | 4039 |
1 | 4040 html->cursor_pos = diff; |
12 | 4041 |
4042 html->cursor_hb = (GtkHtmlBit *) hbits->prev->data; | |
4043 } | |
4044 else | |
4045 { | |
1 | 4046 html->cursor_pos = 0; |
4047 } | |
12 | 4048 } |
79 | 4049 else if ((unsigned) html->cursor_pos > strlen(html->cursor_hb->text)) |
12 | 4050 { |
4051 if (hbits->next) | |
4052 { | |
1 | 4053 gint diff; |
4054 hb = html->cursor_hb; | |
12 | 4055 hb2 = (GtkHtmlBit *) hbits->next->data; |
1 | 4056 |
4057 diff = html->cursor_pos - strlen(html->cursor_hb->text) - 1; | |
4058 if (hb->y == hb2->y) | |
12 | 4059 ++diff; |
1 | 4060 html->cursor_pos = diff; |
12 | 4061 html->cursor_hb = (GtkHtmlBit *) hbits->next->data; |
4062 } | |
4063 else | |
4064 { | |
1 | 4065 html->cursor_pos = strlen(html->cursor_hb->text); |
4066 } | |
4067 | |
4068 } | |
4069 | |
4070 draw_cursor(html); | |
4071 } | |
4072 | |
12 | 4073 static void move_beginning_of_line(GtkHtml * html) |
1 | 4074 { |
4075 GList *hbits = g_list_find(html->html_bits, html->cursor_hb); | |
4076 GtkHtmlBit *hb = NULL; | |
12 | 4077 gint y; |
4078 | |
1 | 4079 undraw_cursor(html); |
4080 | |
4081 if (!html->html_bits) | |
4082 return; | |
4083 | |
4084 if (!html->cursor_hb) | |
12 | 4085 html->cursor_hb = (GtkHtmlBit *) html->html_bits->data; |
1 | 4086 |
4087 y = html->cursor_hb->y; | |
12 | 4088 |
4089 while (hbits) | |
4090 { | |
4091 hb = (GtkHtmlBit *) hbits->data; | |
4092 | |
4093 if (y != hb->y) | |
4094 { | |
4095 hb = (GtkHtmlBit *) hbits->next->data; | |
1 | 4096 break; |
4097 } | |
12 | 4098 |
1 | 4099 hbits = hbits->prev; |
4100 } | |
4101 if (!hbits) | |
12 | 4102 html->cursor_hb = (GtkHtmlBit *) html->html_bits->data; |
1 | 4103 else |
4104 html->cursor_hb = hb; | |
4105 | |
4106 html->cursor_pos = 0; | |
4107 | |
4108 | |
4109 draw_cursor(html); | |
4110 | |
4111 | |
4112 } | |
4113 | |
12 | 4114 static void move_end_of_line(GtkHtml * html) |
1 | 4115 { |
4116 GList *hbits = g_list_find(html->html_bits, html->cursor_hb); | |
4117 GtkHtmlBit *hb = NULL; | |
12 | 4118 gint y; |
4119 | |
1 | 4120 undraw_cursor(html); |
4121 | |
4122 if (!html->html_bits) | |
4123 return; | |
4124 | |
4125 if (!html->cursor_hb) | |
12 | 4126 html->cursor_hb = (GtkHtmlBit *) html->html_bits->data; |
1 | 4127 |
4128 y = html->cursor_hb->y; | |
12 | 4129 |
4130 while (hbits) | |
4131 { | |
4132 hb = (GtkHtmlBit *) hbits->data; | |
4133 | |
4134 if (y != hb->y) | |
4135 { | |
4136 hb = (GtkHtmlBit *) hbits->prev->data; | |
1 | 4137 break; |
4138 } | |
12 | 4139 |
1 | 4140 hbits = hbits->next; |
4141 } | |
4142 if (!hbits) | |
12 | 4143 html->cursor_hb = (GtkHtmlBit *) g_list_last(html->html_bits)->data; |
1 | 4144 else |
4145 html->cursor_hb = hb; | |
4146 | |
4147 html->cursor_pos = strlen(html->cursor_hb->text); | |
4148 | |
4149 | |
4150 draw_cursor(html); | |
4151 | |
4152 | |
4153 } | |
4154 | |
4155 | |
4156 | |
12 | 4157 static gint gtk_html_key_press(GtkWidget * widget, GdkEventKey * event) |
1 | 4158 { |
4159 GtkHtml *html; | |
4160 gchar key; | |
4161 gint return_val; | |
12 | 4162 |
4163 g_return_val_if_fail(widget != NULL, FALSE); | |
4164 g_return_val_if_fail(GTK_IS_HTML(widget), FALSE); | |
4165 g_return_val_if_fail(event != NULL, FALSE); | |
4166 | |
1 | 4167 return_val = FALSE; |
12 | 4168 |
4169 html = GTK_HTML(widget); | |
4170 | |
1 | 4171 key = event->keyval; |
4172 return_val = TRUE; | |
4173 | |
4174 | |
12 | 4175 if (html->editable == FALSE) |
4176 { | |
4177 /* | |
4178 * switch (event->keyval) { | |
4179 * case GDK_Home: | |
4180 * if (event->state & GDK_CONTROL_MASK) | |
4181 * scroll_int (text, -text->vadj->value); | |
4182 * else | |
4183 * return_val = FALSE; | |
4184 * break; | |
4185 * case GDK_End: | |
4186 * if (event->state & GDK_CONTROL_MASK) | |
4187 * scroll_int (text, +text->vadj->upper); | |
4188 * else | |
4189 * return_val = FALSE; | |
4190 * break; | |
4191 * case GDK_Page_Up: scroll_int (text, -text->vadj->page_increment); break; | |
4192 * case GDK_Page_Down: scroll_int (text, +text->vadj->page_increment); break; | |
4193 * case GDK_Up: scroll_int (text, -KEY_SCROLL_PIXELS); break; | |
4194 * case GDK_Down: scroll_int (text, +KEY_SCROLL_PIXELS); break; | |
4195 * case GDK_Return: | |
4196 * if (event->state & GDK_CONTROL_MASK) | |
4197 * gtk_signal_emit_by_name (GTK_OBJECT (text), "activate"); | |
4198 * else | |
4199 * return_val = FALSE; | |
4200 * break; | |
4201 * default: | |
4202 * return_val = FALSE; | |
4203 * break; | |
4204 * } | |
4205 */ | |
4206 } | |
4207 else | |
4208 { | |
4209 | |
4210 switch (event->keyval) | |
4211 { | |
1 | 4212 case GDK_Home: |
12 | 4213 move_beginning_of_line(html); |
1 | 4214 break; |
4215 case GDK_End: | |
12 | 4216 move_end_of_line(html); |
1 | 4217 break; |
4218 /* | |
12 | 4219 * case GDK_Page_Up: |
4220 * move_cursor_page_ver (html, -1); | |
4221 * break; | |
4222 * case GDK_Page_Down: | |
4223 * move_cursor_page_ver (html, +1); | |
4224 * break; | |
4225 */ | |
4226 /* | |
4227 * CUA has Ctrl-Up/Ctrl-Down as paragraph up down | |
4228 */ | |
1 | 4229 case GDK_Up: |
12 | 4230 move_cursor_ver(html, -1); |
1 | 4231 break; |
4232 case GDK_Down: | |
12 | 4233 move_cursor_ver(html, +1); |
1 | 4234 break; |
4235 case GDK_Left: | |
12 | 4236 move_cursor_hor(html, -1); |
1 | 4237 break; |
4238 case GDK_Right: | |
12 | 4239 move_cursor_hor(html, +1); |
1 | 4240 break; |
4241 #if 0 | |
4242 case GDK_BackSpace: | |
4243 if (event->state & GDK_CONTROL_MASK) | |
12 | 4244 gtk_text_delete_backward_word(text); |
1 | 4245 else |
12 | 4246 gtk_text_delete_backward_character(text); |
1 | 4247 break; |
4248 case GDK_Clear: | |
12 | 4249 gtk_text_delete_line(text); |
1 | 4250 break; |
4251 case GDK_Insert: | |
4252 if (event->state & GDK_SHIFT_MASK) | |
4253 { | |
4254 extend_selection = FALSE; | |
12 | 4255 gtk_editable_paste_clipboard(editable); |
1 | 4256 } |
4257 else if (event->state & GDK_CONTROL_MASK) | |
4258 { | |
12 | 4259 gtk_editable_copy_clipboard(editable); |
1 | 4260 } |
4261 else | |
4262 { | |
12 | 4263 /* |
4264 * gtk_toggle_insert(text) -- IMPLEMENT | |
4265 */ | |
1 | 4266 } |
4267 break; | |
4268 case GDK_Delete: | |
4269 if (event->state & GDK_CONTROL_MASK) | |
12 | 4270 gtk_text_delete_forward_word(text); |
1 | 4271 else if (event->state & GDK_SHIFT_MASK) |
4272 { | |
4273 extend_selection = FALSE; | |
12 | 4274 gtk_editable_cut_clipboard(editable); |
1 | 4275 } |
4276 else | |
12 | 4277 gtk_text_delete_forward_character(text); |
1 | 4278 break; |
4279 case GDK_Tab: | |
4280 position = text->point.index; | |
12 | 4281 gtk_editable_insert_text(editable, "\t", 1, &position); |
1 | 4282 break; |
4283 case GDK_Return: | |
4284 if (event->state & GDK_CONTROL_MASK) | |
12 | 4285 gtk_signal_emit_by_name(GTK_OBJECT(text), "activate"); |
1 | 4286 else |
4287 { | |
4288 position = text->point.index; | |
12 | 4289 gtk_editable_insert_text(editable, "\n", 1, &position); |
1 | 4290 } |
4291 break; | |
4292 case GDK_Escape: | |
12 | 4293 /* |
4294 * Don't insert literally | |
4295 */ | |
1 | 4296 return_val = FALSE; |
4297 break; | |
4298 #endif | |
4299 default: | |
4300 return_val = FALSE; | |
4301 | |
4302 #if 0 | |
12 | 4303 if (event->state & GDK_CONTROL_MASK) |
4304 { | |
1 | 4305 if ((key >= 'A') && (key <= 'Z')) |
4306 key -= 'A' - 'a'; | |
4307 | |
12 | 4308 if ((key >= 'a') && (key <= 'z') |
4309 && control_keys[(int) (key - 'a')]) | |
1 | 4310 { |
12 | 4311 (*control_keys[(int) (key - 'a')]) (editable, event->time); |
1 | 4312 return_val = TRUE; |
4313 } | |
4314 | |
4315 break; | |
4316 } | |
4317 else if (event->state & GDK_MOD1_MASK) | |
4318 { | |
4319 if ((key >= 'A') && (key <= 'Z')) | |
4320 key -= 'A' - 'a'; | |
4321 | |
4322 if ((key >= 'a') && (key <= 'z') && alt_keys[(int) (key - 'a')]) | |
4323 { | |
12 | 4324 (*alt_keys[(int) (key - 'a')]) (editable, event->time); |
1 | 4325 return_val = TRUE; |
4326 } | |
4327 break; | |
4328 } | |
4329 #endif | |
4330 /* | |
12 | 4331 * if (event->length > 0) { |
4332 * html->cursor_pos++; | |
4333 * gtk_editable_insert_text (editable, event->string, event->length, &position); | |
4334 * | |
4335 * return_val = TRUE; | |
4336 * } | |
4337 * else | |
4338 * return_val = FALSE; | |
4339 */ | |
1 | 4340 } |
4341 | |
4342 } | |
4343 | |
4344 return return_val; | |
4345 } | |
12 | 4346 |
4347 void gtk_html_freeze(GtkHtml * html) | |
1 | 4348 { |
12 | 4349 g_return_if_fail(html != NULL); |
4350 g_return_if_fail(GTK_IS_HTML(html)); | |
1 | 4351 |
4352 html->frozen++; | |
4353 } | |
4354 | |
12 | 4355 void gtk_html_thaw(GtkHtml * html) |
1 | 4356 { |
4357 GdkRectangle area; | |
12 | 4358 |
4359 g_return_if_fail(html != NULL); | |
4360 g_return_if_fail(GTK_IS_HTML(html)); | |
1 | 4361 |
481
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
4362 gtk_html_append_text(html, NULL, 0); |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
4363 |
1 | 4364 html->frozen--; |
4365 | |
4366 if (html->frozen < 0) | |
12 | 4367 html->frozen = 0; |
4368 | |
4369 if (html->frozen == 0) | |
4370 { | |
4371 if (html->html_area) | |
4372 { | |
4373 gint width, | |
4374 height; | |
1 | 4375 area.x = 0; |
4376 area.y = 0; | |
4377 | |
4378 gdk_window_get_size(html->html_area, &width, &height); | |
4379 | |
12 | 4380 area.width = width; |
4381 area.height = height; | |
4382 | |
1 | 4383 expose_html(html, &area, TRUE); |
4384 } | |
4385 } | |
4386 } | |
895 | 4387 |
4388 static int get_line_height(GtkHtml *html, GtkHtmlBit *start) | |
4389 { | |
4390 int height, max_height = 0; | |
4391 GList *hbits = html->html_bits; | |
4392 GtkHtmlBit *hbit; | |
4393 | |
4394 hbits = g_list_find(hbits, start); | |
4395 | |
896 | 4396 while (hbits) |
895 | 4397 { |
4398 hbit = hbits->data; | |
4399 if (hbit->font) | |
4400 height = gdk_text_height(hbit->font, "C", 1); | |
4401 | |
4402 if (max_height < height) | |
4403 max_height = height; | |
4404 if (hbit->newline) | |
4405 break; | |
4406 hbits = hbits->next; | |
4407 } | |
4408 | |
896 | 4409 if (max_height == 0) |
4410 max_height = gdk_text_height(hbit->font, "C", 1); | |
4411 | |
895 | 4412 return max_height; |
4413 } |