Mercurial > pidgin.yaz
annotate src/gtkimhtml.c @ 13158:eed97963252a
[gaim-migrate @ 15521]
I think this'll fix a crash that hit me last night. What happened was,
Gaim couldn't fetch the buddy list on the first attempt. It set up a
timer to do it 30 seconds later. The timer callback set the reference
to the timer to 0, so Gaim was not able to remove the timer. Then at
some point I got disconnected and the timer callback got called and
exploded.
Unfortunately, I have a feeling this hit everyone using either of
the betas.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Tue, 07 Feb 2006 14:51:28 +0000 |
parents | 1ed228c65e89 |
children | 3a3538be5b6a |
rev | line source |
---|---|
1428 | 1 /* |
10297
ec140184437b
[gaim-migrate @ 11480]
Luke Schierer <lschiere@pidgin.im>
parents:
10243
diff
changeset
|
2 * @file gtkimhtml.c GTK+ IMHtml |
ec140184437b
[gaim-migrate @ 11480]
Luke Schierer <lschiere@pidgin.im>
parents:
10243
diff
changeset
|
3 * @ingroup gtkui |
ec140184437b
[gaim-migrate @ 11480]
Luke Schierer <lschiere@pidgin.im>
parents:
10243
diff
changeset
|
4 * |
ec140184437b
[gaim-migrate @ 11480]
Luke Schierer <lschiere@pidgin.im>
parents:
10243
diff
changeset
|
5 * gaim |
1428 | 6 * |
8046 | 7 * Gaim is the legal property of its developers, whose names are too numerous |
8 * to list here. Please refer to the COPYRIGHT file distributed with this | |
9 * source distribution. | |
1428 | 10 * |
11 * This program is free software; you can redistribute it and/or modify | |
12 * under the terms of the GNU General Public License as published by | |
13 * the Free Software Foundation; either version 2 of the License, or | |
14 * (at your option) any later version. | |
15 * | |
16 * This program is distributed in the hope that it will be useful, | |
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 * GNU General Public License for more details. | |
20 * | |
21 * You should have received a copy of the GNU General Public License | |
22 * along with this program; if not, write to the Free Software | |
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
24 * | |
25 */ | |
26 | |
2541
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2365
diff
changeset
|
27 #ifdef HAVE_CONFIG_H |
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2365
diff
changeset
|
28 #include <config.h> |
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2365
diff
changeset
|
29 #endif |
8526 | 30 #include "debug.h" |
8091 | 31 #include "util.h" |
1428 | 32 #include "gtkimhtml.h" |
7358 | 33 #include "gtksourceiter.h" |
1428 | 34 #include <gtk/gtk.h> |
4895 | 35 #include <glib/gerror.h> |
4046 | 36 #include <gdk/gdkkeysyms.h> |
1428 | 37 #include <string.h> |
38 #include <ctype.h> | |
39 #include <stdio.h> | |
4629 | 40 #include <stdlib.h> |
1428 | 41 #include <math.h> |
2541
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2365
diff
changeset
|
42 #ifdef HAVE_LANGINFO_CODESET |
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2365
diff
changeset
|
43 #include <langinfo.h> |
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2365
diff
changeset
|
44 #include <locale.h> |
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2365
diff
changeset
|
45 #endif |
8692 | 46 #ifdef _WIN32 |
10901
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
47 #include <gdk/gdkwin32.h> |
8692 | 48 #include <windows.h> |
49 #endif | |
1428 | 50 |
4417 | 51 #ifdef ENABLE_NLS |
52 # include <libintl.h> | |
53 # define _(x) gettext(x) | |
54 # ifdef gettext_noop | |
55 # define N_(String) gettext_noop (String) | |
56 # else | |
57 # define N_(String) (String) | |
58 # endif | |
59 #else | |
60 # define N_(String) (String) | |
61 # define _(x) (x) | |
62 #endif | |
63 | |
4735 | 64 #include <pango/pango-font.h> |
65 | |
10062 | 66 /* GTK+ < 2.4.x hack, see gtkgaim.h for details. */ |
67 #if (!GTK_CHECK_VERSION(2,4,0)) | |
5105 | 68 #define GTK_WRAP_WORD_CHAR GTK_WRAP_WORD |
69 #endif | |
70 | |
4735 | 71 #define TOOLTIP_TIMEOUT 500 |
72 | |
8786 | 73 /* GTK+ 2.0 hack */ |
74 #if (!GTK_CHECK_VERSION(2,2,0)) | |
75 #define gtk_widget_get_clipboard(x, y) gtk_clipboard_get(y) | |
76 #endif | |
77 | |
10100 | 78 static GtkTextViewClass *parent_class = NULL; |
79 | |
11224
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
80 struct scalable_data { |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
81 GtkIMHtmlScalable *scalable; |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
82 GtkTextMark *mark; |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
83 }; |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
84 |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
85 |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
86 struct im_image_data { |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
87 int id; |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
88 GtkTextMark *mark; |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
89 }; |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
90 |
9300 | 91 static gboolean |
92 gtk_text_view_drag_motion (GtkWidget *widget, | |
93 GdkDragContext *context, | |
94 gint x, | |
95 gint y, | |
96 guint time); | |
97 | |
8677 | 98 static void preinsert_cb(GtkTextBuffer *buffer, GtkTextIter *iter, gchar *text, gint len, GtkIMHtml *imhtml); |
8061 | 99 static void insert_cb(GtkTextBuffer *buffer, GtkTextIter *iter, gchar *text, gint len, GtkIMHtml *imhtml); |
12673
de93d4988ad4
[gaim-migrate @ 15016]
Richard Laager <rlaager@wiktel.com>
parents:
12672
diff
changeset
|
100 static void delete_cb(GtkTextBuffer *buffer, GtkTextIter *iter, GtkTextIter *end, GtkIMHtml *imhtml); |
10169 | 101 static void insert_ca_cb(GtkTextBuffer *buffer, GtkTextIter *arg1, GtkTextChildAnchor *arg2, gpointer user_data); |
102 static void gtk_imhtml_apply_tags_on_insert(GtkIMHtml *imhtml, GtkTextIter *start, GtkTextIter *end); | |
8505 | 103 static gboolean gtk_imhtml_is_amp_escape (const gchar *string, gchar **replace, gint *length); |
8698 | 104 void gtk_imhtml_close_tags(GtkIMHtml *imhtml, GtkTextIter *iter); |
9300 | 105 static void gtk_imhtml_link_drop_cb(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time, gpointer user_data); |
8091 | 106 static void gtk_imhtml_link_drag_rcv_cb(GtkWidget *widget, GdkDragContext *dc, guint x, guint y, GtkSelectionData *sd, guint info, guint t, GtkIMHtml *imhtml); |
8677 | 107 static void mark_set_cb(GtkTextBuffer *buffer, GtkTextIter *arg1, GtkTextMark *mark, GtkIMHtml *imhtml); |
8931 | 108 static void hijack_menu_cb(GtkIMHtml *imhtml, GtkMenu *menu, gpointer data); |
109 static void paste_received_cb (GtkClipboard *clipboard, GtkSelectionData *selection_data, gpointer data); | |
110 static void paste_plaintext_received_cb (GtkClipboard *clipboard, const gchar *text, gpointer data); | |
10901
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
111 static void imhtml_paste_insert(GtkIMHtml *imhtml, const char *text, gboolean plaintext); |
11267
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
112 static void imhtml_toggle_bold(GtkIMHtml *imhtml); |
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
113 static void imhtml_toggle_italic(GtkIMHtml *imhtml); |
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
114 static void imhtml_toggle_strike(GtkIMHtml *imhtml); |
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
115 static void imhtml_toggle_underline(GtkIMHtml *imhtml); |
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
116 static void imhtml_font_grow(GtkIMHtml *imhtml); |
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
117 static void imhtml_font_shrink(GtkIMHtml *imhtml); |
12672
4bd7e2ebb4cb
[gaim-migrate @ 15015]
Richard Laager <rlaager@wiktel.com>
parents:
12635
diff
changeset
|
118 static void imhtml_clear_formatting(GtkIMHtml *imhtml); |
8061 | 119 |
10899 | 120 /* POINT_SIZE converts from AIM font sizes to a point size scale factor. */ |
3922 | 121 #define MAX_FONT_SIZE 7 |
10900 | 122 #define POINT_SIZE(x) (_point_sizes [MIN ((x > 0 ? x : 1), MAX_FONT_SIZE) - 1]) |
8380 | 123 static gdouble _point_sizes [] = { .69444444, .8333333, 1, 1.2, 1.44, 1.728, 2.0736}; |
2349
60c716c32c40
[gaim-migrate @ 2362]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2348
diff
changeset
|
124 |
10184 | 125 enum { |
8677 | 126 TARGET_HTML, |
8061 | 127 TARGET_UTF8_STRING, |
128 TARGET_COMPOUND_TEXT, | |
129 TARGET_STRING, | |
130 TARGET_TEXT | |
131 }; | |
132 | |
8091 | 133 enum { |
8420 | 134 URL_CLICKED, |
135 BUTTONS_UPDATE, | |
136 TOGGLE_FORMAT, | |
8427 | 137 CLEAR_FORMAT, |
8506 | 138 UPDATE_FORMAT, |
10108 | 139 MESSAGE_SEND, |
8420 | 140 LAST_SIGNAL |
141 }; | |
142 static guint signals [LAST_SIGNAL] = { 0 }; | |
143 | |
10871 | 144 static GtkTargetEntry selection_targets[] = { |
8566 | 145 { "text/html", 0, TARGET_HTML }, |
8061 | 146 { "UTF8_STRING", 0, TARGET_UTF8_STRING }, |
147 { "COMPOUND_TEXT", 0, TARGET_COMPOUND_TEXT }, | |
148 { "STRING", 0, TARGET_STRING }, | |
149 { "TEXT", 0, TARGET_TEXT}}; | |
150 | |
10871 | 151 static GtkTargetEntry link_drag_drop_targets[] = { |
10145 | 152 GTK_IMHTML_DND_TARGETS |
153 }; | |
8091 | 154 |
8692 | 155 #ifdef _WIN32 |
156 /* Win32 clipboard format value, and functions to convert back and | |
157 * forth between HTML and the clipboard format. | |
158 */ | |
159 static UINT win_html_fmt; | |
160 | |
161 static gchar * | |
162 clipboard_win32_to_html(char *clipboard) { | |
9465 | 163 const char *header; |
8693 | 164 const char *begin, *end; |
10016
5b4a0af99bf7
[gaim-migrate @ 10935]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
165 gint start = 0; |
5b4a0af99bf7
[gaim-migrate @ 10935]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
166 gint finish = 0; |
8692 | 167 gchar *html; |
10016
5b4a0af99bf7
[gaim-migrate @ 10935]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
168 gchar **split; |
5b4a0af99bf7
[gaim-migrate @ 10935]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
169 int clipboard_length = 0; |
9465 | 170 |
171 #if 0 /* Debugging for Windows clipboard */ | |
9467 | 172 FILE *fd; |
173 | |
9465 | 174 gaim_debug_info("imhtml clipboard", "from clipboard: %s\n", clipboard); |
175 | |
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10574
diff
changeset
|
176 fd = g_fopen("e:\\gaimcb.txt", "wb"); |
9465 | 177 fprintf(fd, "%s", clipboard); |
178 fclose(fd); | |
179 #endif | |
180 | |
10016
5b4a0af99bf7
[gaim-migrate @ 10935]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
181 clipboard_length = strlen(clipboard); |
5b4a0af99bf7
[gaim-migrate @ 10935]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
182 |
5b4a0af99bf7
[gaim-migrate @ 10935]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
183 if (!(header = strstr(clipboard, "StartFragment:")) || (header - clipboard) >= clipboard_length) |
9465 | 184 return NULL; |
185 sscanf(header, "StartFragment:%d", &start); | |
186 | |
10016
5b4a0af99bf7
[gaim-migrate @ 10935]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
187 if (!(header = strstr(clipboard, "EndFragment:")) || (header - clipboard) >= clipboard_length) |
5b4a0af99bf7
[gaim-migrate @ 10935]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
188 return NULL; |
9465 | 189 sscanf(header, "EndFragment:%d", &finish); |
190 | |
10016
5b4a0af99bf7
[gaim-migrate @ 10935]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
191 if (finish > clipboard_length) |
5b4a0af99bf7
[gaim-migrate @ 10935]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
192 finish = clipboard_length; |
5b4a0af99bf7
[gaim-migrate @ 10935]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
193 |
5b4a0af99bf7
[gaim-migrate @ 10935]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
194 if (start > finish) |
5b4a0af99bf7
[gaim-migrate @ 10935]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
195 start = finish; |
5b4a0af99bf7
[gaim-migrate @ 10935]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
196 |
9465 | 197 begin = clipboard + start; |
198 | |
10016
5b4a0af99bf7
[gaim-migrate @ 10935]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
199 end = clipboard + finish; |
5b4a0af99bf7
[gaim-migrate @ 10935]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
200 |
5b4a0af99bf7
[gaim-migrate @ 10935]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
201 html = g_strndup(begin, end - begin); |
5b4a0af99bf7
[gaim-migrate @ 10935]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
202 |
5b4a0af99bf7
[gaim-migrate @ 10935]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
203 /* any newlines in the string will now be \r\n, so we need to strip out the \r */ |
5b4a0af99bf7
[gaim-migrate @ 10935]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
204 split = g_strsplit(html, "\r\n", 0); |
5b4a0af99bf7
[gaim-migrate @ 10935]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
205 g_free(html); |
5b4a0af99bf7
[gaim-migrate @ 10935]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
206 html = g_strjoinv("\n", split); |
5b4a0af99bf7
[gaim-migrate @ 10935]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
207 g_strfreev(split); |
5b4a0af99bf7
[gaim-migrate @ 10935]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
208 |
5b4a0af99bf7
[gaim-migrate @ 10935]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
209 html = g_strstrip(html); |
9465 | 210 |
211 #if 0 /* Debugging for Windows clipboard */ | |
10016
5b4a0af99bf7
[gaim-migrate @ 10935]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
212 gaim_debug_info("imhtml clipboard", "HTML fragment: '%s'\n", html); |
9465 | 213 #endif |
214 | |
8707 | 215 return html; |
8692 | 216 } |
217 | |
218 static gchar * | |
219 clipboard_html_to_win32(char *html) { | |
8693 | 220 int length; |
11240
2ab2de8add8b
[gaim-migrate @ 13399]
Richard Laager <rlaager@wiktel.com>
parents:
11234
diff
changeset
|
221 GString *clipboard; |
2ab2de8add8b
[gaim-migrate @ 13399]
Richard Laager <rlaager@wiktel.com>
parents:
11234
diff
changeset
|
222 gchar *tmp; |
8692 | 223 gchar *ret; |
224 | |
8693 | 225 if (html == NULL) |
226 return NULL; | |
8692 | 227 |
228 length = strlen(html); | |
9465 | 229 clipboard = g_string_new ("Version:1.0\r\n"); |
8692 | 230 g_string_append(clipboard, "StartHTML:0000000105\r\n"); |
11240
2ab2de8add8b
[gaim-migrate @ 13399]
Richard Laager <rlaager@wiktel.com>
parents:
11234
diff
changeset
|
231 tmp = g_strdup_printf("EndHTML:%010d\r\n", 147 + length); |
2ab2de8add8b
[gaim-migrate @ 13399]
Richard Laager <rlaager@wiktel.com>
parents:
11234
diff
changeset
|
232 g_string_append(clipboard, tmp); |
2ab2de8add8b
[gaim-migrate @ 13399]
Richard Laager <rlaager@wiktel.com>
parents:
11234
diff
changeset
|
233 g_free(tmp); |
9465 | 234 g_string_append(clipboard, "StartFragment:0000000127\r\n"); |
11240
2ab2de8add8b
[gaim-migrate @ 13399]
Richard Laager <rlaager@wiktel.com>
parents:
11234
diff
changeset
|
235 tmp = g_strdup_printf("EndFragment:%010d\r\n", 127 + length); |
2ab2de8add8b
[gaim-migrate @ 13399]
Richard Laager <rlaager@wiktel.com>
parents:
11234
diff
changeset
|
236 g_string_append(clipboard, tmp); |
2ab2de8add8b
[gaim-migrate @ 13399]
Richard Laager <rlaager@wiktel.com>
parents:
11234
diff
changeset
|
237 g_free(tmp); |
9465 | 238 g_string_append(clipboard, "<!--StartFragment-->\r\n"); |
8692 | 239 g_string_append(clipboard, html); |
9465 | 240 g_string_append(clipboard, "\r\n<!--EndFragment-->"); |
8692 | 241 ret = clipboard->str; |
242 g_string_free(clipboard, FALSE); | |
9465 | 243 |
244 #if 0 /* Debugging for Windows clipboard */ | |
245 gaim_debug_info("imhtml clipboard", "from gaim: %s\n", ret); | |
246 #endif | |
247 | |
8692 | 248 return ret; |
249 } | |
10901
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
250 |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
251 static void clipboard_copy_html_win32(GtkIMHtml *imhtml) { |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
252 gchar *clipboard = clipboard_html_to_win32(imhtml->clipboard_html_string); |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
253 if (clipboard != NULL) { |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
254 HWND hwnd = GDK_WINDOW_HWND(GTK_WIDGET(imhtml)->window); |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
255 if (OpenClipboard(hwnd)) { |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
256 if (EmptyClipboard()) { |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
257 gint length = strlen(clipboard); |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
258 HGLOBAL hdata = GlobalAlloc(GMEM_MOVEABLE, length); |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
259 if (hdata != NULL) { |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
260 gchar *buffer = GlobalLock(hdata); |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
261 memcpy(buffer, clipboard, length); |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
262 GlobalUnlock(hdata); |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
263 |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
264 if (SetClipboardData(win_html_fmt, hdata) == NULL) { |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
265 gchar *err_msg = |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
266 g_win32_error_message(GetLastError()); |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
267 gaim_debug_info("html clipboard", |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
268 "Unable to set clipboard data: %s\n", |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
269 err_msg ? err_msg : "Unknown Error"); |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
270 g_free(err_msg); |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
271 } |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
272 } |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
273 } |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
274 CloseClipboard(); |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
275 } |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
276 g_free(clipboard); |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
277 } |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
278 } |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
279 |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
280 static gboolean clipboard_paste_html_win32(GtkIMHtml *imhtml) { |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
281 gboolean pasted = FALSE; |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
282 |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
283 if (gtk_text_view_get_editable(GTK_TEXT_VIEW(imhtml)) |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
284 && IsClipboardFormatAvailable(win_html_fmt)) { |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
285 gboolean error_reading_clipboard = FALSE; |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
286 HWND hwnd = GDK_WINDOW_HWND(GTK_WIDGET(imhtml)->window); |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
287 |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
288 if (OpenClipboard(hwnd)) { |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
289 HGLOBAL hdata = GetClipboardData(win_html_fmt); |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
290 if (hdata == NULL) { |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
291 error_reading_clipboard = TRUE; |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
292 } else { |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
293 char *buffer = GlobalLock(hdata); |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
294 if (buffer == NULL) { |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
295 error_reading_clipboard = TRUE; |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
296 } else { |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
297 char *text = clipboard_win32_to_html( |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
298 buffer); |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
299 imhtml_paste_insert(imhtml, text, |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
300 FALSE); |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
301 g_free(text); |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
302 pasted = TRUE; |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
303 } |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
304 GlobalUnlock(hdata); |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
305 } |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
306 |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
307 CloseClipboard(); |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
308 |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
309 } else { |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
310 error_reading_clipboard = TRUE; |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
311 } |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
312 |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
313 if (error_reading_clipboard) { |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
314 gchar *err_msg = g_win32_error_message(GetLastError()); |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
315 gaim_debug_info("html clipboard", |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
316 "Unable to read clipboard data: %s\n", |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
317 err_msg ? err_msg : "Unknown Error"); |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
318 g_free(err_msg); |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
319 } |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
320 } |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
321 |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
322 return pasted; |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
323 } |
8692 | 324 #endif |
325 | |
4032 | 326 static GtkSmileyTree* |
327 gtk_smiley_tree_new () | |
328 { | |
329 return g_new0 (GtkSmileyTree, 1); | |
330 } | |
331 | |
332 static void | |
333 gtk_smiley_tree_insert (GtkSmileyTree *tree, | |
4263 | 334 GtkIMHtmlSmiley *smiley) |
4032 | 335 { |
336 GtkSmileyTree *t = tree; | |
4263 | 337 const gchar *x = smiley->smile; |
4032 | 338 |
12229
18f0dadb29cf
[gaim-migrate @ 14531]
Richard Laager <rlaager@wiktel.com>
parents:
12072
diff
changeset
|
339 if (!(*x)) |
4032 | 340 return; |
341 | |
12229
18f0dadb29cf
[gaim-migrate @ 14531]
Richard Laager <rlaager@wiktel.com>
parents:
12072
diff
changeset
|
342 do { |
4032 | 343 gchar *pos; |
344 gint index; | |
345 | |
346 if (!t->values) | |
347 t->values = g_string_new (""); | |
348 | |
349 pos = strchr (t->values->str, *x); | |
350 if (!pos) { | |
351 t->values = g_string_append_c (t->values, *x); | |
352 index = t->values->len - 1; | |
353 t->children = g_realloc (t->children, t->values->len * sizeof (GtkSmileyTree *)); | |
354 t->children [index] = g_new0 (GtkSmileyTree, 1); | |
355 } else | |
7386 | 356 index = GPOINTER_TO_INT(pos) - GPOINTER_TO_INT(t->values->str); |
8061 | 357 |
4032 | 358 t = t->children [index]; |
8061 | 359 |
4032 | 360 x++; |
12229
18f0dadb29cf
[gaim-migrate @ 14531]
Richard Laager <rlaager@wiktel.com>
parents:
12072
diff
changeset
|
361 } while (*x); |
8061 | 362 |
4263 | 363 t->image = smiley; |
4032 | 364 } |
4041 | 365 |
4263 | 366 |
11677 | 367 static void |
368 gtk_smiley_tree_destroy (GtkSmileyTree *tree) | |
4032 | 369 { |
11701
5d7da4056644
[gaim-migrate @ 13992]
Richard Laager <rlaager@wiktel.com>
parents:
11677
diff
changeset
|
370 GSList *list = g_slist_prepend (NULL, tree); |
4032 | 371 |
372 while (list) { | |
373 GtkSmileyTree *t = list->data; | |
12229
18f0dadb29cf
[gaim-migrate @ 14531]
Richard Laager <rlaager@wiktel.com>
parents:
12072
diff
changeset
|
374 gsize i; |
4032 | 375 list = g_slist_remove(list, t); |
7384 | 376 if (t && t->values) { |
4032 | 377 for (i = 0; i < t->values->len; i++) |
11701
5d7da4056644
[gaim-migrate @ 13992]
Richard Laager <rlaager@wiktel.com>
parents:
11677
diff
changeset
|
378 list = g_slist_prepend (list, t->children [i]); |
4032 | 379 g_string_free (t->values, TRUE); |
380 g_free (t->children); | |
381 } | |
382 g_free (t); | |
383 } | |
384 } | |
385 | |
11840
047f85200139
[gaim-migrate @ 14131]
Richard Laager <rlaager@wiktel.com>
parents:
11820
diff
changeset
|
386 static void gtk_size_allocate_cb(GtkIMHtml *widget, GtkAllocation *alloc, gpointer user_data) |
5967 | 387 { |
388 GdkRectangle rect; | |
8726 | 389 int xminus; |
5967 | 390 |
391 gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(widget), &rect); | |
392 if(widget->old_rect.width != rect.width || widget->old_rect.height != rect.height){ | |
393 GList *iter = GTK_IMHTML(widget)->scalables; | |
394 | |
8726 | 395 xminus = gtk_text_view_get_left_margin(GTK_TEXT_VIEW(widget)) + |
396 gtk_text_view_get_right_margin(GTK_TEXT_VIEW(widget)); | |
397 | |
5967 | 398 while(iter){ |
11224
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
399 struct scalable_data *sd = iter->data; |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
400 GtkIMHtmlScalable *scale = GTK_IMHTML_SCALABLE(sd->scalable); |
8726 | 401 scale->scale(scale, rect.width - xminus, rect.height); |
5967 | 402 |
403 iter = iter->next; | |
404 } | |
405 } | |
406 | |
407 widget->old_rect = rect; | |
11840
047f85200139
[gaim-migrate @ 14131]
Richard Laager <rlaager@wiktel.com>
parents:
11820
diff
changeset
|
408 return; |
5967 | 409 } |
410 | |
411 static gint | |
412 gtk_imhtml_tip_paint (GtkIMHtml *imhtml) | |
413 { | |
414 PangoLayout *layout; | |
415 | |
416 g_return_val_if_fail(GTK_IS_IMHTML(imhtml), FALSE); | |
417 | |
418 layout = gtk_widget_create_pango_layout(imhtml->tip_window, imhtml->tip); | |
419 | |
8061 | 420 gtk_paint_flat_box (imhtml->tip_window->style, imhtml->tip_window->window, |
5967 | 421 GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL, imhtml->tip_window, |
422 "tooltip", 0, 0, -1, -1); | |
423 | |
424 gtk_paint_layout (imhtml->tip_window->style, imhtml->tip_window->window, GTK_STATE_NORMAL, | |
425 FALSE, NULL, imhtml->tip_window, NULL, 4, 4, layout); | |
426 | |
427 g_object_unref(layout); | |
428 return FALSE; | |
429 } | |
430 | |
431 static gint | |
432 gtk_imhtml_tip (gpointer data) | |
433 { | |
434 GtkIMHtml *imhtml = data; | |
8526 | 435 PangoFontMetrics *font_metrics; |
5967 | 436 PangoLayout *layout; |
8526 | 437 PangoFont *font; |
5967 | 438 |
439 gint gap, x, y, h, w, scr_w, baseline_skip; | |
440 | |
441 g_return_val_if_fail(GTK_IS_IMHTML(imhtml), FALSE); | |
442 | |
443 if (!imhtml->tip || !GTK_WIDGET_DRAWABLE (GTK_WIDGET(imhtml))) { | |
444 imhtml->tip_timer = 0; | |
445 return FALSE; | |
446 } | |
8061 | 447 |
5967 | 448 if (imhtml->tip_window){ |
449 gtk_widget_destroy (imhtml->tip_window); | |
450 imhtml->tip_window = NULL; | |
451 } | |
452 | |
453 imhtml->tip_timer = 0; | |
454 imhtml->tip_window = gtk_window_new (GTK_WINDOW_POPUP); | |
455 gtk_widget_set_app_paintable (imhtml->tip_window, TRUE); | |
456 gtk_window_set_resizable (GTK_WINDOW (imhtml->tip_window), FALSE); | |
457 gtk_widget_set_name (imhtml->tip_window, "gtk-tooltips"); | |
458 g_signal_connect_swapped (G_OBJECT (imhtml->tip_window), "expose_event", | |
459 G_CALLBACK (gtk_imhtml_tip_paint), imhtml); | |
460 | |
461 gtk_widget_ensure_style (imhtml->tip_window); | |
462 layout = gtk_widget_create_pango_layout(imhtml->tip_window, imhtml->tip); | |
8526 | 463 font = pango_context_load_font(pango_layout_get_context(layout), |
464 imhtml->tip_window->style->font_desc); | |
465 | |
466 if (font == NULL) { | |
467 char *tmp = pango_font_description_to_string( | |
468 imhtml->tip_window->style->font_desc); | |
469 | |
470 gaim_debug(GAIM_DEBUG_ERROR, "gtk_imhtml_tip", | |
471 "pango_context_load_font() couldn't load font: '%s'\n", | |
472 tmp); | |
473 g_free(tmp); | |
474 | |
475 return FALSE; | |
476 } | |
477 | |
478 font_metrics = pango_font_get_metrics(font, NULL); | |
5967 | 479 |
480 pango_layout_get_pixel_size(layout, &scr_w, NULL); | |
8526 | 481 gap = PANGO_PIXELS((pango_font_metrics_get_ascent(font_metrics) + |
482 pango_font_metrics_get_descent(font_metrics))/ 4); | |
5967 | 483 |
484 if (gap < 2) | |
485 gap = 2; | |
8526 | 486 baseline_skip = PANGO_PIXELS(pango_font_metrics_get_ascent(font_metrics) + |
487 pango_font_metrics_get_descent(font_metrics)); | |
5967 | 488 w = 8 + scr_w; |
489 h = 8 + baseline_skip; | |
490 | |
491 gdk_window_get_pointer (NULL, &x, &y, NULL); | |
492 if (GTK_WIDGET_NO_WINDOW (GTK_WIDGET(imhtml))) | |
493 y += GTK_WIDGET(imhtml)->allocation.y; | |
494 | |
495 scr_w = gdk_screen_width(); | |
496 | |
497 x -= ((w >> 1) + 4); | |
498 | |
499 if ((x + w) > scr_w) | |
500 x -= (x + w) - scr_w; | |
501 else if (x < 0) | |
502 x = 0; | |
503 | |
8526 | 504 y = y + PANGO_PIXELS(pango_font_metrics_get_ascent(font_metrics) + |
505 pango_font_metrics_get_descent(font_metrics)); | |
5967 | 506 |
507 gtk_widget_set_size_request (imhtml->tip_window, w, h); | |
508 gtk_widget_show (imhtml->tip_window); | |
509 gtk_window_move (GTK_WINDOW(imhtml->tip_window), x, y); | |
510 | |
8526 | 511 pango_font_metrics_unref(font_metrics); |
5967 | 512 g_object_unref(layout); |
513 | |
514 return FALSE; | |
515 } | |
516 | |
11844 | 517 static gboolean |
518 gtk_motion_event_notify(GtkWidget *imhtml, GdkEventMotion *event, gpointer data) | |
8061 | 519 { |
5967 | 520 GtkTextIter iter; |
521 GdkWindow *win = event->window; | |
522 int x, y; | |
523 char *tip = NULL; | |
524 GSList *tags = NULL, *templist = NULL; | |
10799 | 525 GdkColor *norm, *pre; |
526 GtkTextTag *tag = NULL, *oldprelit_tag; | |
527 | |
528 oldprelit_tag = GTK_IMHTML(imhtml)->prelit_tag; | |
529 | |
5967 | 530 gdk_window_get_pointer(GTK_WIDGET(imhtml)->window, NULL, NULL, NULL); |
531 gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW(imhtml), GTK_TEXT_WINDOW_WIDGET, | |
10799 | 532 event->x, event->y, &x, &y); |
5967 | 533 gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(imhtml), &iter, x, y); |
534 tags = gtk_text_iter_get_tags(&iter); | |
535 | |
536 templist = tags; | |
537 while (templist) { | |
10799 | 538 tag = templist->data; |
5967 | 539 tip = g_object_get_data(G_OBJECT(tag), "link_url"); |
540 if (tip) | |
541 break; | |
542 templist = templist->next; | |
543 } | |
8061 | 544 |
10799 | 545 if (tip) { |
546 gtk_widget_style_get(GTK_WIDGET(imhtml), "hyperlink-prelight-color", &pre, NULL); | |
547 GTK_IMHTML(imhtml)->prelit_tag = tag; | |
548 if (tag != oldprelit_tag) { | |
549 if (pre) | |
550 g_object_set(G_OBJECT(tag), "foreground-gdk", pre, NULL); | |
551 else | |
12253 | 552 g_object_set(G_OBJECT(tag), "foreground", "#70a0ff", NULL); |
10799 | 553 } |
554 } else { | |
555 GTK_IMHTML(imhtml)->prelit_tag = NULL; | |
556 } | |
11572
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
557 |
10834 | 558 if ((oldprelit_tag != NULL) && (GTK_IMHTML(imhtml)->prelit_tag != oldprelit_tag)) { |
10799 | 559 gtk_widget_style_get(GTK_WIDGET(imhtml), "hyperlink-color", &norm, NULL); |
560 if (norm) | |
561 g_object_set(G_OBJECT(oldprelit_tag), "foreground-gdk", norm, NULL); | |
562 else | |
563 g_object_set(G_OBJECT(oldprelit_tag), "foreground", "blue", NULL); | |
564 } | |
565 | |
5967 | 566 if (GTK_IMHTML(imhtml)->tip) { |
567 if ((tip == GTK_IMHTML(imhtml)->tip)) { | |
568 return FALSE; | |
569 } | |
570 /* We've left the cell. Remove the timeout and create a new one below */ | |
571 if (GTK_IMHTML(imhtml)->tip_window) { | |
572 gtk_widget_destroy(GTK_IMHTML(imhtml)->tip_window); | |
573 GTK_IMHTML(imhtml)->tip_window = NULL; | |
574 } | |
8061 | 575 if (GTK_IMHTML(imhtml)->editable) |
576 gdk_window_set_cursor(win, GTK_IMHTML(imhtml)->text_cursor); | |
577 else | |
578 gdk_window_set_cursor(win, GTK_IMHTML(imhtml)->arrow_cursor); | |
5967 | 579 if (GTK_IMHTML(imhtml)->tip_timer) |
580 g_source_remove(GTK_IMHTML(imhtml)->tip_timer); | |
581 GTK_IMHTML(imhtml)->tip_timer = 0; | |
582 } | |
8061 | 583 |
10799 | 584 if (tip){ |
8061 | 585 if (!GTK_IMHTML(imhtml)->editable) |
586 gdk_window_set_cursor(win, GTK_IMHTML(imhtml)->hand_cursor); | |
587 GTK_IMHTML(imhtml)->tip_timer = g_timeout_add (TOOLTIP_TIMEOUT, | |
5967 | 588 gtk_imhtml_tip, imhtml); |
589 } | |
8061 | 590 |
5967 | 591 GTK_IMHTML(imhtml)->tip = tip; |
592 g_slist_free(tags); | |
593 return FALSE; | |
594 } | |
595 | |
11677 | 596 static gboolean |
597 gtk_enter_event_notify(GtkWidget *imhtml, GdkEventCrossing *event, gpointer data) | |
10946
2d30f151146d
[gaim-migrate @ 12742]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10936
diff
changeset
|
598 { |
2d30f151146d
[gaim-migrate @ 12742]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10936
diff
changeset
|
599 if (GTK_IMHTML(imhtml)->editable) |
2d30f151146d
[gaim-migrate @ 12742]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10936
diff
changeset
|
600 gdk_window_set_cursor( |
2d30f151146d
[gaim-migrate @ 12742]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10936
diff
changeset
|
601 gtk_text_view_get_window(GTK_TEXT_VIEW(imhtml), |
2d30f151146d
[gaim-migrate @ 12742]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10936
diff
changeset
|
602 GTK_TEXT_WINDOW_TEXT), |
2d30f151146d
[gaim-migrate @ 12742]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10936
diff
changeset
|
603 GTK_IMHTML(imhtml)->text_cursor); |
2d30f151146d
[gaim-migrate @ 12742]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10936
diff
changeset
|
604 else |
2d30f151146d
[gaim-migrate @ 12742]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10936
diff
changeset
|
605 gdk_window_set_cursor( |
2d30f151146d
[gaim-migrate @ 12742]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10936
diff
changeset
|
606 gtk_text_view_get_window(GTK_TEXT_VIEW(imhtml), |
2d30f151146d
[gaim-migrate @ 12742]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10936
diff
changeset
|
607 GTK_TEXT_WINDOW_TEXT), |
2d30f151146d
[gaim-migrate @ 12742]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10936
diff
changeset
|
608 GTK_IMHTML(imhtml)->arrow_cursor); |
2d30f151146d
[gaim-migrate @ 12742]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10936
diff
changeset
|
609 |
2d30f151146d
[gaim-migrate @ 12742]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10936
diff
changeset
|
610 /* propagate the event normally */ |
2d30f151146d
[gaim-migrate @ 12742]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10936
diff
changeset
|
611 return FALSE; |
2d30f151146d
[gaim-migrate @ 12742]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10936
diff
changeset
|
612 } |
2d30f151146d
[gaim-migrate @ 12742]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10936
diff
changeset
|
613 |
11677 | 614 static gboolean |
615 gtk_leave_event_notify(GtkWidget *imhtml, GdkEventCrossing *event, gpointer data) | |
5967 | 616 { |
617 /* when leaving the widget, clear any current & pending tooltips and restore the cursor */ | |
10799 | 618 if (GTK_IMHTML(imhtml)->prelit_tag) { |
619 GdkColor *norm; | |
620 gtk_widget_style_get(GTK_WIDGET(imhtml), "hyperlink-color", &norm, NULL); | |
621 if (norm) | |
622 g_object_set(G_OBJECT(GTK_IMHTML(imhtml)->prelit_tag), "foreground-gdk", norm, NULL); | |
623 else | |
624 g_object_set(G_OBJECT(GTK_IMHTML(imhtml)->prelit_tag), "foreground", "blue", NULL); | |
625 GTK_IMHTML(imhtml)->prelit_tag = NULL; | |
626 } | |
627 | |
5967 | 628 if (GTK_IMHTML(imhtml)->tip_window) { |
629 gtk_widget_destroy(GTK_IMHTML(imhtml)->tip_window); | |
630 GTK_IMHTML(imhtml)->tip_window = NULL; | |
631 } | |
632 if (GTK_IMHTML(imhtml)->tip_timer) { | |
633 g_source_remove(GTK_IMHTML(imhtml)->tip_timer); | |
634 GTK_IMHTML(imhtml)->tip_timer = 0; | |
635 } | |
10946
2d30f151146d
[gaim-migrate @ 12742]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10936
diff
changeset
|
636 gdk_window_set_cursor( |
2d30f151146d
[gaim-migrate @ 12742]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10936
diff
changeset
|
637 gtk_text_view_get_window(GTK_TEXT_VIEW(imhtml), |
2d30f151146d
[gaim-migrate @ 12742]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10936
diff
changeset
|
638 GTK_TEXT_WINDOW_TEXT), NULL); |
5967 | 639 |
8568 | 640 /* propagate the event normally */ |
5967 | 641 return FALSE; |
642 } | |
643 | |
10844 | 644 #if (!GTK_CHECK_VERSION(2,2,0)) |
6066 | 645 /* |
646 * XXX - This should be removed eventually. | |
647 * | |
8061 | 648 * This function exists to work around a gross bug in GtkTextView. |
649 * Basically, we short circuit ctrl+a and ctrl+end because they make | |
6066 | 650 * el program go boom. |
651 * | |
8061 | 652 * It's supposed to be fixed in gtk2.2. You can view the bug report at |
6066 | 653 * http://bugzilla.gnome.org/show_bug.cgi?id=107939 |
654 */ | |
10849 | 655 static gboolean |
656 gtk_key_pressed_cb(GtkIMHtml *imhtml, GdkEventKey *event, gpointer data) | |
8677 | 657 { |
10844 | 658 if (event->state & GDK_CONTROL_MASK) { |
6066 | 659 switch (event->keyval) { |
10844 | 660 case 'a': |
661 case GDK_Home: | |
662 case GDK_End: | |
663 return TRUE; | |
6066 | 664 } |
10844 | 665 } |
6066 | 666 return FALSE; |
667 } | |
10844 | 668 #endif /* !(GTK+ >= 2.2.0) */ |
10692 | 669 |
670 static gint | |
671 gtk_imhtml_expose_event (GtkWidget *widget, | |
672 GdkEventExpose *event) | |
673 { | |
10776 | 674 GtkTextIter start, end, cur; |
675 int buf_x, buf_y; | |
676 GdkRectangle visible_rect; | |
10777 | 677 GdkGC *gc = gdk_gc_new(GDK_DRAWABLE(event->window)); |
678 GdkColor gcolor; | |
10844 | 679 |
10776 | 680 gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(widget), &visible_rect); |
681 gtk_text_view_buffer_to_window_coords(GTK_TEXT_VIEW(widget), | |
682 GTK_TEXT_WINDOW_TEXT, | |
683 visible_rect.x, | |
684 visible_rect.y, | |
685 &visible_rect.x, | |
686 &visible_rect.y); | |
687 | |
688 gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW(widget), GTK_TEXT_WINDOW_TEXT, | |
689 event->area.x, event->area.y, &buf_x, &buf_y); | |
690 | |
10777 | 691 if (GTK_IMHTML(widget)->editable || GTK_IMHTML(widget)->wbfo) { |
11572
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
692 |
10777 | 693 if (GTK_IMHTML(widget)->edit.background) { |
694 gdk_color_parse(GTK_IMHTML(widget)->edit.background, &gcolor); | |
695 gdk_gc_set_rgb_fg_color(gc, &gcolor); | |
696 } else { | |
697 gdk_gc_set_rgb_fg_color(gc, &(widget->style->base[GTK_WIDGET_STATE(widget)])); | |
698 } | |
11572
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
699 |
10777 | 700 gdk_draw_rectangle(event->window, |
701 gc, | |
702 TRUE, | |
703 visible_rect.x, visible_rect.y, visible_rect.width, visible_rect.height); | |
704 gdk_gc_unref(gc); | |
11572
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
705 |
10777 | 706 if (GTK_WIDGET_CLASS (parent_class)->expose_event) |
707 return (* GTK_WIDGET_CLASS (parent_class)->expose_event) | |
708 (widget, event); | |
709 return FALSE; | |
710 | |
711 } | |
11572
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
712 |
10776 | 713 gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(widget), &start, buf_x, buf_y); |
714 gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(widget), &end, | |
715 buf_x + event->area.width, buf_y + event->area.height); | |
716 | |
717 | |
718 | |
719 cur = start; | |
720 | |
721 while (gtk_text_iter_in_range(&cur, &start, &end)) { | |
10795 | 722 GSList *tags = gtk_text_iter_get_tags(&cur); |
723 GSList *l; | |
10776 | 724 |
725 for (l = tags; l; l = l->next) { | |
726 GtkTextTag *tag = l->data; | |
727 GdkRectangle rect; | |
728 GdkRectangle tag_area; | |
729 const char *color; | |
11572
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
730 |
10776 | 731 if (strncmp(tag->name, "BACKGROUND ", 11)) |
732 continue; | |
733 | |
734 if (gtk_text_iter_ends_tag(&cur, tag)) | |
735 continue; | |
736 | |
737 gtk_text_view_get_iter_location(GTK_TEXT_VIEW(widget), &cur, &tag_area); | |
738 gtk_text_view_buffer_to_window_coords(GTK_TEXT_VIEW(widget), | |
739 GTK_TEXT_WINDOW_TEXT, | |
740 tag_area.x, | |
741 tag_area.y, | |
742 &tag_area.x, | |
743 &tag_area.y); | |
744 rect.x = visible_rect.x; | |
745 rect.y = tag_area.y; | |
11768
a9e9b76905b4
[gaim-migrate @ 14059]
Gary Kramlich <grim@reaperworld.com>
parents:
11760
diff
changeset
|
746 rect.width = visible_rect.width; |
10776 | 747 |
10795 | 748 do |
10776 | 749 gtk_text_iter_forward_to_tag_toggle(&cur, tag); |
10795 | 750 while (!gtk_text_iter_is_end(&cur) && gtk_text_iter_begins_tag(&cur, tag)); |
751 | |
10776 | 752 gtk_text_view_get_iter_location(GTK_TEXT_VIEW(widget), &cur, &tag_area); |
753 gtk_text_view_buffer_to_window_coords(GTK_TEXT_VIEW(widget), | |
754 GTK_TEXT_WINDOW_TEXT, | |
755 tag_area.x, | |
756 tag_area.y, | |
757 &tag_area.x, | |
758 &tag_area.y); | |
759 | |
11760 | 760 |
761 rect.height = tag_area.y + tag_area.height - rect.y | |
762 + gtk_text_view_get_pixels_below_lines(GTK_TEXT_VIEW(widget)); | |
11572
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
763 |
10776 | 764 color = tag->name + 11; |
765 | |
10857 | 766 if (!gdk_color_parse(color, &gcolor)) { |
10858 | 767 gchar tmp[8]; |
768 tmp[0] = '#'; | |
769 strncpy(&tmp[1], color, 7); | |
770 tmp[7] = '\0'; | |
10857 | 771 if (!gdk_color_parse(tmp, &gcolor)) |
772 gdk_color_parse("white", &gcolor); | |
773 } | |
10776 | 774 gdk_gc_set_rgb_fg_color(gc, &gcolor); |
775 | |
776 gdk_draw_rectangle(event->window, | |
777 gc, | |
778 TRUE, | |
779 rect.x, rect.y, rect.width, rect.height); | |
10795 | 780 gtk_text_iter_backward_char(&cur); /* go back one, in case the end is the begining is the end |
781 * note that above, we always moved cur ahead by at least | |
782 * one character */ | |
10776 | 783 break; |
784 } | |
785 | |
786 g_slist_free(tags); | |
10795 | 787 |
788 /* loop until another tag begins, or no tag begins */ | |
789 while (gtk_text_iter_forward_to_tag_toggle(&cur, NULL) && | |
790 !gtk_text_iter_is_end(&cur) && | |
791 !gtk_text_iter_begins_tag(&cur, NULL)); | |
11572
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
792 } |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
793 |
10777 | 794 gdk_gc_unref(gc); |
795 | |
10692 | 796 if (GTK_WIDGET_CLASS (parent_class)->expose_event) |
797 return (* GTK_WIDGET_CLASS (parent_class)->expose_event) | |
798 (widget, event); | |
10776 | 799 |
10692 | 800 return FALSE; |
801 } | |
802 | |
803 | |
8931 | 804 static void paste_unformatted_cb(GtkMenuItem *menu, GtkIMHtml *imhtml) |
805 { | |
806 GtkClipboard *clipboard = gtk_widget_get_clipboard(GTK_WIDGET(imhtml), GDK_SELECTION_CLIPBOARD); | |
807 | |
808 gtk_clipboard_request_text(clipboard, paste_plaintext_received_cb, imhtml); | |
809 | |
810 } | |
811 | |
12836
339d61ebca8a
[gaim-migrate @ 15184]
Richard Laager <rlaager@wiktel.com>
parents:
12833
diff
changeset
|
812 |
10692 | 813 |
8931 | 814 static void hijack_menu_cb(GtkIMHtml *imhtml, GtkMenu *menu, gpointer data) |
815 { | |
816 GtkWidget *menuitem; | |
817 | |
12635
8584cc19ee48
[gaim-migrate @ 14971]
Richard Laager <rlaager@wiktel.com>
parents:
12605
diff
changeset
|
818 menuitem = gtk_menu_item_new_with_mnemonic(_("Paste as Plain _Text")); |
8931 | 819 gtk_widget_show(menuitem); |
820 gtk_widget_set_sensitive(menuitem, | |
12836
339d61ebca8a
[gaim-migrate @ 15184]
Richard Laager <rlaager@wiktel.com>
parents:
12833
diff
changeset
|
821 (imhtml->editable && |
339d61ebca8a
[gaim-migrate @ 15184]
Richard Laager <rlaager@wiktel.com>
parents:
12833
diff
changeset
|
822 gtk_clipboard_wait_is_text_available( |
339d61ebca8a
[gaim-migrate @ 15184]
Richard Laager <rlaager@wiktel.com>
parents:
12833
diff
changeset
|
823 gtk_widget_get_clipboard(GTK_WIDGET(imhtml), GDK_SELECTION_CLIPBOARD)))); |
8931 | 824 /* put it after "Paste" */ |
825 gtk_menu_shell_insert(GTK_MENU_SHELL(menu), menuitem, 3); | |
826 | |
827 g_signal_connect(G_OBJECT(menuitem), "activate", | |
828 G_CALLBACK(paste_unformatted_cb), imhtml); | |
829 } | |
830 | |
11572
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
831 static char * |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
832 ucs2_order(gboolean swap) |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
833 { |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
834 gboolean be; |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
835 |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
836 be = G_BYTE_ORDER == G_BIG_ENDIAN; |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
837 be = swap ? be : !be; |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
838 |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
839 if (be) |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
840 return "UCS-2BE"; |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
841 else |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
842 return "UCS-2LE"; |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
843 |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
844 } |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
845 |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
846 /* Convert from UCS-2 to UTF-8, stripping the BOM if one is present.*/ |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
847 static gchar * |
11586 | 848 ucs2_to_utf8_with_bom_check(gchar *data, guint len) { |
11572
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
849 char *fromcode = NULL; |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
850 GError *error = NULL; |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
851 guint16 c; |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
852 gchar *utf8_ret; |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
853 |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
854 /* |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
855 * Unicode Techinical Report 20 |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
856 * ( http://www.unicode.org/unicode/reports/tr20/ ) says to treat an |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
857 * initial 0xfeff (ZWNBSP) as a byte order indicator so that is |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
858 * what we do. If there is no indicator assume it is in the default |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
859 * order |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
860 */ |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
861 |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
862 memcpy(&c, data, 2); |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
863 switch (c) { |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
864 case 0xfeff: |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
865 case 0xfffe: |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
866 fromcode = ucs2_order(c == 0xfeff); |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
867 data += 2; |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
868 len -= 2; |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
869 break; |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
870 default: |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
871 fromcode = "UCS-2"; |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
872 break; |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
873 } |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
874 |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
875 utf8_ret = g_convert(data, len, "UTF-8", fromcode, NULL, NULL, &error); |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
876 |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
877 if (error) { |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
878 gaim_debug_warning("gtkimhtml", "g_convert error: %s\n", error->message); |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
879 g_error_free(error); |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
880 } |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
881 return utf8_ret; |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
882 } |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
883 |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
884 |
8061 | 885 static void gtk_imhtml_clipboard_get(GtkClipboard *clipboard, GtkSelectionData *selection_data, guint info, GtkIMHtml *imhtml) { |
8681 | 886 char *text; |
8782
5a2b5e4abf3a
[gaim-migrate @ 9544]
Christian Hammond <chipx86@chipx86.com>
parents:
8758
diff
changeset
|
887 gboolean primary; |
8061 | 888 GtkTextIter start, end; |
889 GtkTextMark *sel = gtk_text_buffer_get_selection_bound(imhtml->text_buffer); | |
890 GtkTextMark *ins = gtk_text_buffer_get_insert(imhtml->text_buffer); | |
10013 | 891 |
8061 | 892 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &start, sel); |
893 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &end, ins); | |
8782
5a2b5e4abf3a
[gaim-migrate @ 9544]
Christian Hammond <chipx86@chipx86.com>
parents:
8758
diff
changeset
|
894 primary = gtk_widget_get_clipboard(GTK_WIDGET(imhtml), GDK_SELECTION_PRIMARY) == clipboard; |
8061 | 895 |
896 if (info == TARGET_HTML) { | |
8907 | 897 gsize len; |
8148 | 898 char *selection; |
8061 | 899 GString *str = g_string_new(NULL); |
8681 | 900 if (primary) { |
901 text = gtk_imhtml_get_markup_range(imhtml, &start, &end); | |
10013 | 902 } else |
8681 | 903 text = imhtml->clipboard_html_string; |
8061 | 904 |
905 /* Mozilla asks that we start our text/html with the Unicode byte order mark */ | |
906 str = g_string_append_unichar(str, 0xfeff); | |
907 str = g_string_append(str, text); | |
908 str = g_string_append_unichar(str, 0x0000); | |
8148 | 909 selection = g_convert(str->str, str->len, "UCS-2", "UTF-8", NULL, &len, NULL); |
11143 | 910 gtk_selection_data_set(selection_data, gdk_atom_intern("text/html", FALSE), 16, (const guchar *)selection, len); |
8061 | 911 g_string_free(str, TRUE); |
912 g_free(selection); | |
913 } else { | |
8681 | 914 if (primary) { |
915 text = gtk_imhtml_get_text(imhtml, &start, &end); | |
916 } else | |
917 text = imhtml->clipboard_text_string; | |
8061 | 918 gtk_selection_data_set_text(selection_data, text, strlen(text)); |
919 } | |
8681 | 920 if (primary) /* This was allocated here */ |
921 g_free(text); | |
922 } | |
8061 | 923 |
924 static void gtk_imhtml_primary_clipboard_clear(GtkClipboard *clipboard, GtkIMHtml *imhtml) | |
7749 | 925 { |
8061 | 926 GtkTextIter insert; |
927 GtkTextIter selection_bound; | |
928 | |
929 gtk_text_buffer_get_iter_at_mark (imhtml->text_buffer, &insert, | |
930 gtk_text_buffer_get_mark (imhtml->text_buffer, "insert")); | |
931 gtk_text_buffer_get_iter_at_mark (imhtml->text_buffer, &selection_bound, | |
932 gtk_text_buffer_get_mark (imhtml->text_buffer, "selection_bound")); | |
933 | |
934 if (!gtk_text_iter_equal (&insert, &selection_bound)) | |
935 gtk_text_buffer_move_mark (imhtml->text_buffer, | |
936 gtk_text_buffer_get_mark (imhtml->text_buffer, "selection_bound"), | |
937 &insert); | |
7749 | 938 } |
7742 | 939 |
8677 | 940 static void copy_clipboard_cb(GtkIMHtml *imhtml, gpointer unused) |
7749 | 941 { |
8681 | 942 GtkTextIter start, end; |
943 GtkTextMark *sel = gtk_text_buffer_get_selection_bound(imhtml->text_buffer); | |
944 GtkTextMark *ins = gtk_text_buffer_get_insert(imhtml->text_buffer); | |
945 | |
946 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &start, sel); | |
947 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &end, ins); | |
948 | |
8061 | 949 gtk_clipboard_set_with_owner(gtk_widget_get_clipboard(GTK_WIDGET(imhtml), GDK_SELECTION_CLIPBOARD), |
950 selection_targets, sizeof(selection_targets) / sizeof(GtkTargetEntry), | |
951 (GtkClipboardGetFunc)gtk_imhtml_clipboard_get, | |
952 (GtkClipboardClearFunc)NULL, G_OBJECT(imhtml)); | |
7346 | 953 |
8681 | 954 if (imhtml->clipboard_html_string) { |
955 g_free(imhtml->clipboard_html_string); | |
956 g_free(imhtml->clipboard_text_string); | |
957 } | |
958 | |
959 imhtml->clipboard_html_string = gtk_imhtml_get_markup_range(imhtml, &start, &end); | |
960 imhtml->clipboard_text_string = gtk_imhtml_get_text(imhtml, &start, &end); | |
961 | |
8692 | 962 #ifdef _WIN32 |
963 /* We're going to still copy plain text, but let's toss the "HTML Format" | |
964 we need into the windows clipboard now as well. */ | |
10901
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
965 clipboard_copy_html_win32(imhtml); |
8692 | 966 #endif |
967 | |
8061 | 968 g_signal_stop_emission_by_name(imhtml, "copy-clipboard"); |
969 } | |
970 | |
8698 | 971 static void cut_clipboard_cb(GtkIMHtml *imhtml, gpointer unused) |
972 { | |
973 GtkTextIter start, end; | |
974 GtkTextMark *sel = gtk_text_buffer_get_selection_bound(imhtml->text_buffer); | |
975 GtkTextMark *ins = gtk_text_buffer_get_insert(imhtml->text_buffer); | |
976 | |
977 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &start, sel); | |
978 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &end, ins); | |
979 | |
980 gtk_clipboard_set_with_owner(gtk_widget_get_clipboard(GTK_WIDGET(imhtml), GDK_SELECTION_CLIPBOARD), | |
981 selection_targets, sizeof(selection_targets) / sizeof(GtkTargetEntry), | |
982 (GtkClipboardGetFunc)gtk_imhtml_clipboard_get, | |
983 (GtkClipboardClearFunc)NULL, G_OBJECT(imhtml)); | |
984 | |
985 if (imhtml->clipboard_html_string) { | |
986 g_free(imhtml->clipboard_html_string); | |
987 g_free(imhtml->clipboard_text_string); | |
988 } | |
989 | |
990 imhtml->clipboard_html_string = gtk_imhtml_get_markup_range(imhtml, &start, &end); | |
991 imhtml->clipboard_text_string = gtk_imhtml_get_text(imhtml, &start, &end); | |
992 | |
993 #ifdef _WIN32 | |
994 /* We're going to still copy plain text, but let's toss the "HTML Format" | |
995 we need into the windows clipboard now as well. */ | |
10901
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
996 clipboard_copy_html_win32(imhtml); |
8698 | 997 #endif |
998 | |
999 if (imhtml->editable) | |
1000 gtk_text_buffer_delete_selection(imhtml->text_buffer, FALSE, FALSE); | |
1001 g_signal_stop_emission_by_name(imhtml, "cut-clipboard"); | |
1002 } | |
1003 | |
8931 | 1004 static void imhtml_paste_insert(GtkIMHtml *imhtml, const char *text, gboolean plaintext) |
1005 { | |
1006 GtkTextIter iter; | |
9465 | 1007 GtkIMHtmlOptions flags = plaintext ? 0 : (GTK_IMHTML_NO_NEWLINE | GTK_IMHTML_NO_COMMENTS); |
8931 | 1008 |
9028 | 1009 if (gtk_text_buffer_get_selection_bounds(imhtml->text_buffer, NULL, NULL)) |
1010 gtk_text_buffer_delete_selection(imhtml->text_buffer, TRUE, TRUE); | |
1011 | |
8931 | 1012 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, gtk_text_buffer_get_insert(imhtml->text_buffer)); |
1013 if (!imhtml->wbfo && !plaintext) | |
1014 gtk_imhtml_close_tags(imhtml, &iter); | |
1015 | |
1016 gtk_imhtml_insert_html_at_iter(imhtml, text, flags, &iter); | |
11267
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
1017 if (!imhtml->wbfo && !plaintext) |
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
1018 gtk_imhtml_close_tags(imhtml, &iter); |
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
1019 gtk_text_buffer_move_mark_by_name(imhtml->text_buffer, "insert", &iter); |
8931 | 1020 gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(imhtml), gtk_text_buffer_get_insert(imhtml->text_buffer), |
1021 0, FALSE, 0.0, 0.0); | |
1022 } | |
1023 | |
1024 static void paste_plaintext_received_cb (GtkClipboard *clipboard, const gchar *text, gpointer data) | |
1025 { | |
1026 char *tmp; | |
1027 | |
1028 if (text == NULL) | |
1029 return; | |
1030 | |
10732
c4cb90065e1d
[gaim-migrate @ 12334]
Luke Schierer <lschiere@pidgin.im>
parents:
10699
diff
changeset
|
1031 tmp = g_markup_escape_text(text, -1); |
8931 | 1032 imhtml_paste_insert(data, tmp, TRUE); |
1033 g_free(tmp); | |
1034 } | |
1035 | |
8061 | 1036 static void paste_received_cb (GtkClipboard *clipboard, GtkSelectionData *selection_data, gpointer data) |
1037 { | |
1038 char *text; | |
1039 GtkIMHtml *imhtml = data; | |
7809 | 1040 |
8123 | 1041 if (!gtk_text_view_get_editable(GTK_TEXT_VIEW(imhtml))) |
8105 | 1042 return; |
1043 | |
8061 | 1044 if (selection_data->length < 0) { |
8931 | 1045 gtk_clipboard_request_text(clipboard, paste_plaintext_received_cb, imhtml); |
1046 return; | |
8061 | 1047 } else { |
8719 | 1048 #if 0 |
1049 /* Here's some debug code, for figuring out what sent to us over the clipboard. */ | |
1050 { | |
1051 int i; | |
1052 | |
1053 gaim_debug_misc("gtkimhtml", "In paste_received_cb():\n\tformat = %d, length = %d\n\t", | |
1054 selection_data->format, selection_data->length); | |
1055 | |
1056 for (i = 0; i < (/*(selection_data->format / 8) **/ selection_data->length); i++) { | |
1057 if ((i % 70) == 0) | |
1058 printf("\n\t"); | |
1059 if (selection_data->data[i] == '\0') | |
1060 printf("."); | |
1061 else | |
1062 printf("%c", selection_data->data[i]); | |
1063 } | |
1064 printf("\n"); | |
1065 } | |
1066 #endif | |
1067 text = g_malloc(selection_data->length); | |
1068 memcpy(text, selection_data->data, selection_data->length); | |
7766 | 1069 } |
8061 | 1070 |
8869 | 1071 if (selection_data->length >= 2 && |
1072 (*(guint16 *)text == 0xfeff || *(guint16 *)text == 0xfffe)) { | |
1073 /* This is UCS-2 */ | |
11572
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
1074 char *utf8 = ucs2_to_utf8_with_bom_check(text, selection_data->length); |
8061 | 1075 g_free(text); |
1076 text = utf8; | |
8698 | 1077 if (!text) { |
8869 | 1078 gaim_debug_warning("gtkimhtml", "g_convert from UCS-2 failed in paste_received_cb\n"); |
8698 | 1079 return; |
1080 } | |
8061 | 1081 } |
11572
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
1082 |
8698 | 1083 if (!(*text) || !g_utf8_validate(text, -1, NULL)) { |
1084 gaim_debug_warning("gtkimhtml", "empty string or invalid UTF-8 in paste_received_cb\n"); | |
1085 g_free(text); | |
1086 return; | |
1087 } | |
1088 | |
8931 | 1089 imhtml_paste_insert(imhtml, text, FALSE); |
8681 | 1090 g_free(text); |
8061 | 1091 } |
1092 | |
1093 static void paste_clipboard_cb(GtkIMHtml *imhtml, gpointer blah) | |
1094 { | |
8931 | 1095 #ifdef _WIN32 |
1096 /* If we're on windows, let's see if we can get data from the HTML Format | |
10901
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
1097 clipboard before we try to paste from the GTK buffer */ |
0711078e0e2d
[gaim-migrate @ 12622]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10900
diff
changeset
|
1098 if (!clipboard_paste_html_win32(imhtml)) { |
8931 | 1099 #endif |
8061 | 1100 GtkClipboard *clipboard = gtk_widget_get_clipboard(GTK_WIDGET(imhtml), GDK_SELECTION_CLIPBOARD); |
1101 gtk_clipboard_request_contents(clipboard, gdk_atom_intern("text/html", FALSE), | |
1102 paste_received_cb, imhtml); | |
8931 | 1103 #ifdef _WIN32 |
1104 } | |
1105 #endif | |
8061 | 1106 g_signal_stop_emission_by_name(imhtml, "paste-clipboard"); |
7766 | 1107 } |
1108 | |
8677 | 1109 static void imhtml_realized_remove_primary(GtkIMHtml *imhtml, gpointer unused) |
1110 { | |
1111 gtk_text_buffer_remove_selection_clipboard(GTK_IMHTML(imhtml)->text_buffer, | |
1112 gtk_widget_get_clipboard(GTK_WIDGET(imhtml), GDK_SELECTION_PRIMARY)); | |
1113 | |
1114 } | |
1115 | |
8740
61a090413b93
[gaim-migrate @ 9495]
Christian Hammond <chipx86@chipx86.com>
parents:
8735
diff
changeset
|
1116 static void imhtml_destroy_add_primary(GtkIMHtml *imhtml, gpointer unused) |
61a090413b93
[gaim-migrate @ 9495]
Christian Hammond <chipx86@chipx86.com>
parents:
8735
diff
changeset
|
1117 { |
61a090413b93
[gaim-migrate @ 9495]
Christian Hammond <chipx86@chipx86.com>
parents:
8735
diff
changeset
|
1118 gtk_text_buffer_add_selection_clipboard(GTK_IMHTML(imhtml)->text_buffer, |
61a090413b93
[gaim-migrate @ 9495]
Christian Hammond <chipx86@chipx86.com>
parents:
8735
diff
changeset
|
1119 gtk_widget_get_clipboard(GTK_WIDGET(imhtml), GDK_SELECTION_PRIMARY)); |
61a090413b93
[gaim-migrate @ 9495]
Christian Hammond <chipx86@chipx86.com>
parents:
8735
diff
changeset
|
1120 } |
8677 | 1121 |
1122 static void mark_set_so_update_selection_cb(GtkTextBuffer *buffer, GtkTextIter *arg1, GtkTextMark *mark, GtkIMHtml *imhtml) | |
1123 { | |
1124 if (gtk_text_buffer_get_selection_bounds(buffer, NULL, NULL)) { | |
1125 gtk_clipboard_set_with_owner(gtk_widget_get_clipboard(GTK_WIDGET(imhtml), GDK_SELECTION_PRIMARY), | |
1126 selection_targets, sizeof(selection_targets) / sizeof(GtkTargetEntry), | |
1127 (GtkClipboardGetFunc)gtk_imhtml_clipboard_get, | |
1128 (GtkClipboardClearFunc)gtk_imhtml_primary_clipboard_clear, G_OBJECT(imhtml)); | |
1129 } | |
1130 } | |
1131 | |
1132 static gboolean gtk_imhtml_button_press_event(GtkIMHtml *imhtml, GdkEventButton *event, gpointer unused) | |
7346 | 1133 { |
8677 | 1134 if (event->button == 2) { |
1135 int x, y; | |
1136 GtkTextIter iter; | |
1137 GtkClipboard *clipboard = gtk_widget_get_clipboard(GTK_WIDGET(imhtml), GDK_SELECTION_PRIMARY); | |
1138 | |
1139 if (!imhtml->editable) | |
1140 return FALSE; | |
1141 | |
1142 gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW(imhtml), | |
1143 GTK_TEXT_WINDOW_TEXT, | |
1144 event->x, | |
1145 event->y, | |
1146 &x, | |
1147 &y); | |
1148 gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(imhtml), &iter, x, y); | |
1149 gtk_text_buffer_place_cursor(imhtml->text_buffer, &iter); | |
1150 | |
1151 gtk_clipboard_request_contents(clipboard, gdk_atom_intern("text/html", FALSE), | |
1152 paste_received_cb, imhtml); | |
1153 | |
1154 return TRUE; | |
1155 } | |
1156 | |
7346 | 1157 return FALSE; |
1158 } | |
4263 | 1159 |
10108 | 1160 static gboolean imhtml_message_send(GtkIMHtml *imhtml) |
1161 { | |
1162 return FALSE; | |
1163 } | |
1164 | |
10100 | 1165 static void imhtml_toggle_format(GtkIMHtml *imhtml, GtkIMHtmlButtons buttons) |
1166 { | |
10699 | 1167 /* since this function is the handler for the formatting keystrokes, |
1168 we need to check here that the formatting attempted is permitted */ | |
11275
ffc86d9ad8b7
[gaim-migrate @ 13461]
Richard Laager <rlaager@wiktel.com>
parents:
11269
diff
changeset
|
1169 buttons &= imhtml->format_functions; |
10699 | 1170 |
10100 | 1171 switch (buttons) { |
1172 case GTK_IMHTML_BOLD: | |
11267
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
1173 imhtml_toggle_bold(imhtml); |
10100 | 1174 break; |
1175 case GTK_IMHTML_ITALIC: | |
11267
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
1176 imhtml_toggle_italic(imhtml); |
10100 | 1177 break; |
1178 case GTK_IMHTML_UNDERLINE: | |
11267
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
1179 imhtml_toggle_underline(imhtml); |
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
1180 break; |
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
1181 case GTK_IMHTML_STRIKE: |
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
1182 imhtml_toggle_strike(imhtml); |
10100 | 1183 break; |
1184 case GTK_IMHTML_SHRINK: | |
11267
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
1185 imhtml_font_shrink(imhtml); |
10100 | 1186 break; |
1187 case GTK_IMHTML_GROW: | |
11267
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
1188 imhtml_font_grow(imhtml); |
10100 | 1189 break; |
1190 default: | |
1191 break; | |
1192 } | |
1193 } | |
4032 | 1194 |
1195 static void | |
1196 gtk_imhtml_finalize (GObject *object) | |
1197 { | |
1198 GtkIMHtml *imhtml = GTK_IMHTML(object); | |
4895 | 1199 GList *scalables; |
8962 | 1200 GSList *l; |
8061 | 1201 |
10798 | 1202 if (imhtml->scroll_src) |
1203 g_source_remove(imhtml->scroll_src); | |
1204 if (imhtml->scroll_time) | |
1205 g_timer_destroy(imhtml->scroll_time); | |
1206 | |
4138 | 1207 g_hash_table_destroy(imhtml->smiley_data); |
4032 | 1208 gtk_smiley_tree_destroy(imhtml->default_smilies); |
4138 | 1209 gdk_cursor_unref(imhtml->hand_cursor); |
1210 gdk_cursor_unref(imhtml->arrow_cursor); | |
8061 | 1211 gdk_cursor_unref(imhtml->text_cursor); |
8677 | 1212 |
4735 | 1213 if(imhtml->tip_window){ |
1214 gtk_widget_destroy(imhtml->tip_window); | |
1215 } | |
1216 if(imhtml->tip_timer) | |
1217 gtk_timeout_remove(imhtml->tip_timer); | |
1218 | |
4895 | 1219 for(scalables = imhtml->scalables; scalables; scalables = scalables->next) { |
11224
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
1220 struct scalable_data *sd = scalables->data; |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
1221 GtkIMHtmlScalable *scale = GTK_IMHTML_SCALABLE(sd->scalable); |
4895 | 1222 scale->free(scale); |
11224
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
1223 g_free(sd); |
4895 | 1224 } |
7991 | 1225 |
8962 | 1226 for (l = imhtml->im_images; l; l = l->next) { |
11224
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
1227 struct im_image_data *img_data = l->data; |
8962 | 1228 if (imhtml->funcs->image_unref) |
11224
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
1229 imhtml->funcs->image_unref(img_data->id); |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
1230 g_free(img_data); |
8962 | 1231 } |
1232 | |
8681 | 1233 if (imhtml->clipboard_text_string) { |
1234 g_free(imhtml->clipboard_text_string); | |
1235 g_free(imhtml->clipboard_html_string); | |
1236 } | |
1237 | |
4895 | 1238 g_list_free(imhtml->scalables); |
8962 | 1239 g_slist_free(imhtml->im_images); |
9029 | 1240 if (imhtml->protocol_name) |
1241 g_free(imhtml->protocol_name); | |
10574 | 1242 if (imhtml->search_string) |
1243 g_free(imhtml->search_string); | |
4032 | 1244 G_OBJECT_CLASS(parent_class)->finalize (object); |
1245 } | |
1428 | 1246 |
10814
364a2ef907ae
[gaim-migrate @ 12468]
Luke Schierer <lschiere@pidgin.im>
parents:
10799
diff
changeset
|
1247 /* Boring GTK+ stuff */ |
8519 | 1248 static void gtk_imhtml_class_init (GtkIMHtmlClass *klass) |
1428 | 1249 { |
9007 | 1250 GtkWidgetClass *widget_class = (GtkWidgetClass *) klass; |
3922 | 1251 GtkObjectClass *object_class; |
10100 | 1252 GtkBindingSet *binding_set; |
4032 | 1253 GObjectClass *gobject_class; |
8519 | 1254 object_class = (GtkObjectClass*) klass; |
1255 gobject_class = (GObjectClass*) klass; | |
4032 | 1256 parent_class = gtk_type_class(GTK_TYPE_TEXT_VIEW); |
4417 | 1257 signals[URL_CLICKED] = g_signal_new("url_clicked", |
1258 G_TYPE_FROM_CLASS(gobject_class), | |
1259 G_SIGNAL_RUN_FIRST, | |
1260 G_STRUCT_OFFSET(GtkIMHtmlClass, url_clicked), | |
1261 NULL, | |
1262 0, | |
1263 g_cclosure_marshal_VOID__POINTER, | |
1264 G_TYPE_NONE, 1, | |
1265 G_TYPE_POINTER); | |
8506 | 1266 signals[BUTTONS_UPDATE] = g_signal_new("format_buttons_update", |
8420 | 1267 G_TYPE_FROM_CLASS(gobject_class), |
1268 G_SIGNAL_RUN_FIRST, | |
1269 G_STRUCT_OFFSET(GtkIMHtmlClass, buttons_update), | |
1270 NULL, | |
1271 0, | |
10076 | 1272 g_cclosure_marshal_VOID__INT, |
8420 | 1273 G_TYPE_NONE, 1, |
1274 G_TYPE_INT); | |
1275 signals[TOGGLE_FORMAT] = g_signal_new("format_function_toggle", | |
1276 G_TYPE_FROM_CLASS(gobject_class), | |
10100 | 1277 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, |
8420 | 1278 G_STRUCT_OFFSET(GtkIMHtmlClass, toggle_format), |
1279 NULL, | |
1280 0, | |
10076 | 1281 g_cclosure_marshal_VOID__INT, |
1282 G_TYPE_NONE, 1, | |
8420 | 1283 G_TYPE_INT); |
8427 | 1284 signals[CLEAR_FORMAT] = g_signal_new("format_function_clear", |
1285 G_TYPE_FROM_CLASS(gobject_class), | |
11385
78cd70f4834c
[gaim-migrate @ 13612]
Luke Schierer <lschiere@pidgin.im>
parents:
11315
diff
changeset
|
1286 G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, |
8427 | 1287 G_STRUCT_OFFSET(GtkIMHtmlClass, clear_format), |
1288 NULL, | |
1289 0, | |
10100 | 1290 g_cclosure_marshal_VOID__VOID, |
1291 G_TYPE_NONE, 0); | |
8506 | 1292 signals[UPDATE_FORMAT] = g_signal_new("format_function_update", |
10100 | 1293 G_TYPE_FROM_CLASS(gobject_class), |
1294 G_SIGNAL_RUN_FIRST, | |
1295 G_STRUCT_OFFSET(GtkIMHtmlClass, update_format), | |
1296 NULL, | |
1297 0, | |
1298 g_cclosure_marshal_VOID__VOID, | |
1299 G_TYPE_NONE, 0); | |
10108 | 1300 signals[MESSAGE_SEND] = g_signal_new("message_send", |
1301 G_TYPE_FROM_CLASS(gobject_class), | |
1302 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, | |
1303 G_STRUCT_OFFSET(GtkIMHtmlClass, message_send), | |
1304 NULL, | |
1305 0, g_cclosure_marshal_VOID__VOID, | |
1306 G_TYPE_NONE, 0); | |
10100 | 1307 |
1308 klass->toggle_format = imhtml_toggle_format; | |
10108 | 1309 klass->message_send = imhtml_message_send; |
12672
4bd7e2ebb4cb
[gaim-migrate @ 15015]
Richard Laager <rlaager@wiktel.com>
parents:
12635
diff
changeset
|
1310 klass->clear_format = imhtml_clear_formatting; |
10184 | 1311 |
4032 | 1312 gobject_class->finalize = gtk_imhtml_finalize; |
10184 | 1313 widget_class->drag_motion = gtk_text_view_drag_motion; |
10692 | 1314 widget_class->expose_event = gtk_imhtml_expose_event; |
9007 | 1315 gtk_widget_class_install_style_property(widget_class, g_param_spec_boxed("hyperlink-color", |
1316 _("Hyperlink color"), | |
1317 _("Color to draw hyperlinks."), | |
1318 GDK_TYPE_COLOR, G_PARAM_READABLE)); | |
10799 | 1319 gtk_widget_class_install_style_property(widget_class, g_param_spec_boxed("hyperlink-prelight-color", |
1320 _("Hyperlink prelight color"), | |
1321 _("Color to draw hyperlinks when mouse is over them."), | |
1322 GDK_TYPE_COLOR, G_PARAM_READABLE)); | |
10100 | 1323 |
1324 binding_set = gtk_binding_set_by_class (parent_class); | |
10110 | 1325 gtk_binding_entry_add_signal (binding_set, GDK_b, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_BOLD); |
10100 | 1326 gtk_binding_entry_add_signal (binding_set, GDK_i, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_ITALIC); |
1327 gtk_binding_entry_add_signal (binding_set, GDK_u, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_UNDERLINE); | |
1328 gtk_binding_entry_add_signal (binding_set, GDK_plus, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_GROW); | |
1329 gtk_binding_entry_add_signal (binding_set, GDK_equal, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_GROW); | |
1330 gtk_binding_entry_add_signal (binding_set, GDK_minus, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_SHRINK); | |
10108 | 1331 binding_set = gtk_binding_set_by_class(klass); |
11385
78cd70f4834c
[gaim-migrate @ 13612]
Luke Schierer <lschiere@pidgin.im>
parents:
11315
diff
changeset
|
1332 gtk_binding_entry_add_signal (binding_set, GDK_r, GDK_CONTROL_MASK, "format_function_clear", 0); |
10108 | 1333 gtk_binding_entry_add_signal (binding_set, GDK_KP_Enter, 0, "message_send", 0); |
1334 gtk_binding_entry_add_signal (binding_set, GDK_Return, 0, "message_send", 0); | |
1428 | 1335 } |
1336 | |
3922 | 1337 static void gtk_imhtml_init (GtkIMHtml *imhtml) |
1428 | 1338 { |
3922 | 1339 GtkTextIter iter; |
1340 imhtml->text_buffer = gtk_text_buffer_new(NULL); | |
1341 gtk_text_buffer_get_end_iter (imhtml->text_buffer, &iter); | |
1342 gtk_text_view_set_buffer(GTK_TEXT_VIEW(imhtml), imhtml->text_buffer); | |
5105 | 1343 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(imhtml), GTK_WRAP_WORD_CHAR); |
3922 | 1344 gtk_text_view_set_pixels_below_lines(GTK_TEXT_VIEW(imhtml), 5); |
8677 | 1345 gtk_text_view_set_left_margin(GTK_TEXT_VIEW(imhtml), 2); |
1346 gtk_text_view_set_right_margin(GTK_TEXT_VIEW(imhtml), 2); | |
8061 | 1347 /*gtk_text_view_set_indent(GTK_TEXT_VIEW(imhtml), -15);*/ |
3922 | 1348 /*gtk_text_view_set_justification(GTK_TEXT_VIEW(imhtml), GTK_JUSTIFY_FILL);*/ |
8061 | 1349 |
3922 | 1350 /* These tags will be used often and can be reused--we create them on init and then apply them by name |
8932 | 1351 * other tags (color, size, face, etc.) will have to be created and applied dynamically |
9924 | 1352 * Note that even though we created SUB, SUP, and PRE tags here, we don't really |
8932 | 1353 * apply them anywhere yet. */ |
3922 | 1354 gtk_text_buffer_create_tag(imhtml->text_buffer, "BOLD", "weight", PANGO_WEIGHT_BOLD, NULL); |
1355 gtk_text_buffer_create_tag(imhtml->text_buffer, "ITALICS", "style", PANGO_STYLE_ITALIC, NULL); | |
1356 gtk_text_buffer_create_tag(imhtml->text_buffer, "UNDERLINE", "underline", PANGO_UNDERLINE_SINGLE, NULL); | |
1357 gtk_text_buffer_create_tag(imhtml->text_buffer, "STRIKE", "strikethrough", TRUE, NULL); | |
1358 gtk_text_buffer_create_tag(imhtml->text_buffer, "SUB", "rise", -5000, NULL); | |
1359 gtk_text_buffer_create_tag(imhtml->text_buffer, "SUP", "rise", 5000, NULL); | |
1360 gtk_text_buffer_create_tag(imhtml->text_buffer, "PRE", "family", "Monospace", NULL); | |
7295 | 1361 gtk_text_buffer_create_tag(imhtml->text_buffer, "search", "background", "#22ff00", "weight", "bold", NULL); |
8677 | 1362 |
3922 | 1363 /* When hovering over a link, we show the hand cursor--elsewhere we show the plain ol' pointer cursor */ |
1364 imhtml->hand_cursor = gdk_cursor_new (GDK_HAND2); | |
1365 imhtml->arrow_cursor = gdk_cursor_new (GDK_LEFT_PTR); | |
8061 | 1366 imhtml->text_cursor = gdk_cursor_new (GDK_XTERM); |
2993 | 1367 |
6124 | 1368 imhtml->show_comments = TRUE; |
4253 | 1369 |
4892 | 1370 imhtml->smiley_data = g_hash_table_new_full(g_str_hash, g_str_equal, |
4902 | 1371 g_free, (GDestroyNotify)gtk_smiley_tree_destroy); |
4032 | 1372 imhtml->default_smilies = gtk_smiley_tree_new(); |
4735 | 1373 |
4944 | 1374 g_signal_connect(G_OBJECT(imhtml), "size-allocate", G_CALLBACK(gtk_size_allocate_cb), NULL); |
4735 | 1375 g_signal_connect(G_OBJECT(imhtml), "motion-notify-event", G_CALLBACK(gtk_motion_event_notify), NULL); |
4944 | 1376 g_signal_connect(G_OBJECT(imhtml), "leave-notify-event", G_CALLBACK(gtk_leave_event_notify), NULL); |
10946
2d30f151146d
[gaim-migrate @ 12742]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10936
diff
changeset
|
1377 g_signal_connect(G_OBJECT(imhtml), "enter-notify-event", G_CALLBACK(gtk_enter_event_notify), NULL); |
10844 | 1378 #if (!GTK_CHECK_VERSION(2,2,0)) |
1379 /* See the comment for gtk_key_pressed_cb */ | |
6066 | 1380 g_signal_connect(G_OBJECT(imhtml), "key_press_event", G_CALLBACK(gtk_key_pressed_cb), NULL); |
10844 | 1381 #endif |
8677 | 1382 g_signal_connect(G_OBJECT(imhtml), "button_press_event", G_CALLBACK(gtk_imhtml_button_press_event), NULL); |
1383 g_signal_connect(G_OBJECT(imhtml->text_buffer), "insert-text", G_CALLBACK(preinsert_cb), imhtml); | |
12673
de93d4988ad4
[gaim-migrate @ 15016]
Richard Laager <rlaager@wiktel.com>
parents:
12672
diff
changeset
|
1384 g_signal_connect(G_OBJECT(imhtml->text_buffer), "delete_range", G_CALLBACK(delete_cb), imhtml); |
8061 | 1385 g_signal_connect_after(G_OBJECT(imhtml->text_buffer), "insert-text", G_CALLBACK(insert_cb), imhtml); |
10169 | 1386 g_signal_connect_after(G_OBJECT(imhtml->text_buffer), "insert-child-anchor", G_CALLBACK(insert_ca_cb), imhtml); |
8091 | 1387 gtk_drag_dest_set(GTK_WIDGET(imhtml), 0, |
1388 link_drag_drop_targets, sizeof(link_drag_drop_targets) / sizeof(GtkTargetEntry), | |
1389 GDK_ACTION_COPY); | |
1390 g_signal_connect(G_OBJECT(imhtml), "drag_data_received", G_CALLBACK(gtk_imhtml_link_drag_rcv_cb), imhtml); | |
9300 | 1391 g_signal_connect(G_OBJECT(imhtml), "drag_drop", G_CALLBACK(gtk_imhtml_link_drop_cb), imhtml); |
8091 | 1392 |
7353 | 1393 g_signal_connect(G_OBJECT(imhtml), "copy-clipboard", G_CALLBACK(copy_clipboard_cb), NULL); |
8698 | 1394 g_signal_connect(G_OBJECT(imhtml), "cut-clipboard", G_CALLBACK(cut_clipboard_cb), NULL); |
8061 | 1395 g_signal_connect(G_OBJECT(imhtml), "paste-clipboard", G_CALLBACK(paste_clipboard_cb), NULL); |
8677 | 1396 g_signal_connect_after(G_OBJECT(imhtml), "realize", G_CALLBACK(imhtml_realized_remove_primary), NULL); |
8740
61a090413b93
[gaim-migrate @ 9495]
Christian Hammond <chipx86@chipx86.com>
parents:
8735
diff
changeset
|
1397 g_signal_connect(G_OBJECT(imhtml), "unrealize", G_CALLBACK(imhtml_destroy_add_primary), NULL); |
8677 | 1398 |
1399 g_signal_connect_after(G_OBJECT(GTK_IMHTML(imhtml)->text_buffer), "mark-set", | |
1400 G_CALLBACK(mark_set_so_update_selection_cb), imhtml); | |
1401 | |
10946
2d30f151146d
[gaim-migrate @ 12742]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10936
diff
changeset
|
1402 gtk_widget_add_events(GTK_WIDGET(imhtml), |
2d30f151146d
[gaim-migrate @ 12742]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10936
diff
changeset
|
1403 GDK_LEAVE_NOTIFY_MASK | GDK_ENTER_NOTIFY_MASK); |
4735 | 1404 |
8681 | 1405 imhtml->clipboard_text_string = NULL; |
1406 imhtml->clipboard_html_string = NULL; | |
1407 | |
4735 | 1408 imhtml->tip = NULL; |
1409 imhtml->tip_timer = 0; | |
1410 imhtml->tip_window = NULL; | |
4895 | 1411 |
8677 | 1412 imhtml->edit.bold = FALSE; |
1413 imhtml->edit.italic = FALSE; | |
1414 imhtml->edit.underline = FALSE; | |
8061 | 1415 imhtml->edit.forecolor = NULL; |
1416 imhtml->edit.backcolor = NULL; | |
1417 imhtml->edit.fontface = NULL; | |
8677 | 1418 imhtml->edit.fontsize = 0; |
1419 imhtml->edit.link = NULL; | |
1420 | |
11572
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
1421 |
4895 | 1422 imhtml->scalables = NULL; |
8061 | 1423 |
1424 gtk_imhtml_set_editable(imhtml, FALSE); | |
11572
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
1425 g_signal_connect(G_OBJECT(imhtml), "populate-popup", |
8931 | 1426 G_CALLBACK(hijack_menu_cb), NULL); |
1427 | |
8692 | 1428 #ifdef _WIN32 |
1429 /* Register HTML Format as desired clipboard format */ | |
1430 win_html_fmt = RegisterClipboardFormat("HTML Format"); | |
1431 #endif | |
2993 | 1432 } |
1433 | |
3922 | 1434 GtkWidget *gtk_imhtml_new(void *a, void *b) |
1428 | 1435 { |
4635 | 1436 return GTK_WIDGET(g_object_new(gtk_imhtml_get_type(), NULL)); |
1428 | 1437 } |
1438 | |
9037 | 1439 GType gtk_imhtml_get_type() |
1428 | 1440 { |
9037 | 1441 static GType imhtml_type = 0; |
1428 | 1442 |
1443 if (!imhtml_type) { | |
9037 | 1444 static const GTypeInfo imhtml_info = { |
4635 | 1445 sizeof(GtkIMHtmlClass), |
1446 NULL, | |
1447 NULL, | |
1448 (GClassInitFunc) gtk_imhtml_class_init, | |
1449 NULL, | |
1450 NULL, | |
1428 | 1451 sizeof (GtkIMHtml), |
4635 | 1452 0, |
12600
e856f985a0b9
[gaim-migrate @ 14934]
Richard Laager <rlaager@wiktel.com>
parents:
12553
diff
changeset
|
1453 (GInstanceInitFunc) gtk_imhtml_init, |
e856f985a0b9
[gaim-migrate @ 14934]
Richard Laager <rlaager@wiktel.com>
parents:
12553
diff
changeset
|
1454 NULL |
1428 | 1455 }; |
4635 | 1456 |
1457 imhtml_type = g_type_register_static(gtk_text_view_get_type(), | |
1458 "GtkIMHtml", &imhtml_info, 0); | |
1428 | 1459 } |
1460 | |
1461 return imhtml_type; | |
1462 } | |
1463 | |
4417 | 1464 struct url_data { |
1465 GObject *object; | |
1466 gchar *url; | |
1467 }; | |
1468 | |
8677 | 1469 static void url_data_destroy(gpointer mydata) |
1470 { | |
1471 struct url_data *data = mydata; | |
1472 g_object_unref(data->object); | |
1473 g_free(data->url); | |
1474 g_free(data); | |
1475 } | |
1476 | |
4417 | 1477 static void url_open(GtkWidget *w, struct url_data *data) { |
1478 if(!data) return; | |
8061 | 1479 g_signal_emit(data->object, signals[URL_CLICKED], 0, data->url); |
7988 | 1480 |
4417 | 1481 } |
5582 | 1482 |
4417 | 1483 static void url_copy(GtkWidget *w, gchar *url) { |
1484 GtkClipboard *clipboard; | |
1485 | |
8931 | 1486 clipboard = gtk_widget_get_clipboard(w, GDK_SELECTION_PRIMARY); |
4417 | 1487 gtk_clipboard_set_text(clipboard, url, -1); |
5582 | 1488 |
8931 | 1489 clipboard = gtk_widget_get_clipboard(w, GDK_SELECTION_CLIPBOARD); |
5582 | 1490 gtk_clipboard_set_text(clipboard, url, -1); |
4417 | 1491 } |
1492 | |
1493 /* The callback for an event on a link tag. */ | |
10871 | 1494 static gboolean tag_event(GtkTextTag *tag, GObject *imhtml, GdkEvent *event, GtkTextIter *arg2, gpointer unused) { |
4417 | 1495 GdkEventButton *event_button = (GdkEventButton *) event; |
8061 | 1496 if (GTK_IMHTML(imhtml)->editable) |
1497 return FALSE; | |
3922 | 1498 if (event->type == GDK_BUTTON_RELEASE) { |
8957 | 1499 if ((event_button->button == 1) || (event_button->button == 2)) { |
4417 | 1500 GtkTextIter start, end; |
1501 /* we shouldn't open a URL if the user has selected something: */ | |
8677 | 1502 if (gtk_text_buffer_get_selection_bounds( |
1503 gtk_text_iter_get_buffer(arg2), &start, &end)) | |
4417 | 1504 return FALSE; |
1505 | |
1506 /* A link was clicked--we emit the "url_clicked" signal | |
1507 * with the URL as the argument */ | |
8677 | 1508 g_object_ref(G_OBJECT(tag)); |
1509 g_signal_emit(imhtml, signals[URL_CLICKED], 0, g_object_get_data(G_OBJECT(tag), "link_url")); | |
1510 g_object_unref(G_OBJECT(tag)); | |
4417 | 1511 return FALSE; |
1512 } else if(event_button->button == 3) { | |
4745 | 1513 GtkWidget *img, *item, *menu; |
4417 | 1514 struct url_data *tempdata = g_new(struct url_data, 1); |
5091 | 1515 tempdata->object = g_object_ref(imhtml); |
8677 | 1516 tempdata->url = g_strdup(g_object_get_data(G_OBJECT(tag), "link_url")); |
4745 | 1517 |
5091 | 1518 /* Don't want the tooltip around if user right-clicked on link */ |
1519 if (GTK_IMHTML(imhtml)->tip_window) { | |
1520 gtk_widget_destroy(GTK_IMHTML(imhtml)->tip_window); | |
1521 GTK_IMHTML(imhtml)->tip_window = NULL; | |
1522 } | |
1523 if (GTK_IMHTML(imhtml)->tip_timer) { | |
1524 g_source_remove(GTK_IMHTML(imhtml)->tip_timer); | |
1525 GTK_IMHTML(imhtml)->tip_timer = 0; | |
1526 } | |
8061 | 1527 if (GTK_IMHTML(imhtml)->editable) |
1528 gdk_window_set_cursor(event_button->window, GTK_IMHTML(imhtml)->text_cursor); | |
1529 else | |
1530 gdk_window_set_cursor(event_button->window, GTK_IMHTML(imhtml)->arrow_cursor); | |
4417 | 1531 menu = gtk_menu_new(); |
8677 | 1532 g_object_set_data_full(G_OBJECT(menu), "x-imhtml-url-data", tempdata, url_data_destroy); |
4745 | 1533 |
4417 | 1534 /* buttons and such */ |
1535 | |
8677 | 1536 if (!strncmp(tempdata->url, "mailto:", 7)) |
7140
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
1537 { |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
1538 /* Copy E-Mail Address */ |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
1539 img = gtk_image_new_from_stock(GTK_STOCK_COPY, |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
1540 GTK_ICON_SIZE_MENU); |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
1541 item = gtk_image_menu_item_new_with_mnemonic( |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
1542 _("_Copy E-Mail Address")); |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
1543 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), img); |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
1544 g_signal_connect(G_OBJECT(item), "activate", |
8677 | 1545 G_CALLBACK(url_copy), tempdata->url + 7); |
7140
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
1546 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
1547 } |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
1548 else |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
1549 { |
10936 | 1550 /* Open Link in Browser */ |
1551 img = gtk_image_new_from_stock(GTK_STOCK_JUMP_TO, | |
1552 GTK_ICON_SIZE_MENU); | |
1553 item = gtk_image_menu_item_new_with_mnemonic( | |
1554 _("_Open Link in Browser")); | |
1555 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), img); | |
1556 g_signal_connect(G_OBJECT(item), "activate", | |
1557 G_CALLBACK(url_open), tempdata); | |
1558 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); | |
1559 | |
7140
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
1560 /* Copy Link Location */ |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
1561 img = gtk_image_new_from_stock(GTK_STOCK_COPY, |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
1562 GTK_ICON_SIZE_MENU); |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
1563 item = gtk_image_menu_item_new_with_mnemonic( |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
1564 _("_Copy Link Location")); |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
1565 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), img); |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
1566 g_signal_connect(G_OBJECT(item), "activate", |
8677 | 1567 G_CALLBACK(url_copy), tempdata->url); |
7140
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
1568 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
1569 } |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
1570 |
4756 | 1571 |
4417 | 1572 gtk_widget_show_all(menu); |
4756 | 1573 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, |
1574 event_button->button, event_button->time); | |
4745 | 1575 |
4417 | 1576 return TRUE; |
1577 } | |
1428 | 1578 } |
4417 | 1579 if(event->type == GDK_BUTTON_PRESS && event_button->button == 3) |
1580 return TRUE; /* Clicking the right mouse button on a link shouldn't | |
1581 be caught by the regular GtkTextView menu */ | |
1582 else | |
1583 return FALSE; /* Let clicks go through if we didn't catch anything */ | |
1428 | 1584 } |
1585 | |
9300 | 1586 static gboolean |
1587 gtk_text_view_drag_motion (GtkWidget *widget, | |
1588 GdkDragContext *context, | |
1589 gint x, | |
1590 gint y, | |
1591 guint time) | |
1592 { | |
11572
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
1593 GdkDragAction suggested_action = 0; |
9300 | 1594 |
10145 | 1595 if (gtk_drag_dest_find_target (widget, context, NULL) == GDK_NONE) { |
11572
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
1596 /* can't accept any of the offered targets */ |
9300 | 1597 } else { |
1598 GtkWidget *source_widget; | |
1599 suggested_action = context->suggested_action; | |
1600 source_widget = gtk_drag_get_source_widget (context); | |
1601 if (source_widget == widget) { | |
1602 /* Default to MOVE, unless the user has | |
1603 * pressed ctrl or alt to affect available actions | |
1604 */ | |
1605 if ((context->actions & GDK_ACTION_MOVE) != 0) | |
1606 suggested_action = GDK_ACTION_MOVE; | |
1607 } | |
11572
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
1608 } |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
1609 |
10145 | 1610 gdk_drag_status (context, suggested_action, time); |
11572
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
1611 |
9300 | 1612 /* TRUE return means don't propagate the drag motion to parent |
1613 * widgets that may also be drop sites. | |
1614 */ | |
1615 return TRUE; | |
1616 } | |
1617 | |
1618 static void | |
1619 gtk_imhtml_link_drop_cb(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time, gpointer user_data) | |
1620 { | |
1621 GdkAtom target = gtk_drag_dest_find_target (widget, context, NULL); | |
11572
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
1622 |
9300 | 1623 if (target != GDK_NONE) |
1624 gtk_drag_get_data (widget, context, target, time); | |
1625 else | |
1626 gtk_drag_finish (context, FALSE, FALSE, time); | |
1627 | |
1628 return; | |
1629 } | |
1630 | |
8091 | 1631 static void |
1632 gtk_imhtml_link_drag_rcv_cb(GtkWidget *widget, GdkDragContext *dc, guint x, guint y, | |
11143 | 1633 GtkSelectionData *sd, guint info, guint t, GtkIMHtml *imhtml) |
8091 | 1634 { |
9300 | 1635 gchar **links; |
1636 gchar *link; | |
11143 | 1637 char *text = (char *)sd->data; |
9300 | 1638 GtkTextMark *mark = gtk_text_buffer_get_insert(imhtml->text_buffer); |
1639 GtkTextIter iter; | |
10782
93fd90cbf45c
[gaim-migrate @ 12410]
Luke Schierer <lschiere@pidgin.im>
parents:
10777
diff
changeset
|
1640 gint i = 0; |
9300 | 1641 |
1642 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, mark); | |
1643 | |
8091 | 1644 if(gtk_imhtml_get_editable(imhtml) && sd->data){ |
9300 | 1645 switch (info) { |
10145 | 1646 case GTK_IMHTML_DRAG_URL: |
11143 | 1647 /* TODO: Is it really ok to change sd->data...? */ |
11920 | 1648 gaim_str_strip_char((char *)sd->data, '\r'); |
11143 | 1649 |
1650 links = g_strsplit((char *)sd->data, "\n", 0); | |
10782
93fd90cbf45c
[gaim-migrate @ 12410]
Luke Schierer <lschiere@pidgin.im>
parents:
10777
diff
changeset
|
1651 while((link = links[i]) != NULL){ |
9300 | 1652 if(gaim_str_has_prefix(link, "http://") || |
1653 gaim_str_has_prefix(link, "https://") || | |
11820
2cf6d4cf2cb0
[gaim-migrate @ 14111]
Richard Laager <rlaager@wiktel.com>
parents:
11814
diff
changeset
|
1654 gaim_str_has_prefix(link, "ftp://")) |
10782
93fd90cbf45c
[gaim-migrate @ 12410]
Luke Schierer <lschiere@pidgin.im>
parents:
10777
diff
changeset
|
1655 { |
93fd90cbf45c
[gaim-migrate @ 12410]
Luke Schierer <lschiere@pidgin.im>
parents:
10777
diff
changeset
|
1656 gchar *label; |
93fd90cbf45c
[gaim-migrate @ 12410]
Luke Schierer <lschiere@pidgin.im>
parents:
10777
diff
changeset
|
1657 |
93fd90cbf45c
[gaim-migrate @ 12410]
Luke Schierer <lschiere@pidgin.im>
parents:
10777
diff
changeset
|
1658 if(links[i + 1]) |
93fd90cbf45c
[gaim-migrate @ 12410]
Luke Schierer <lschiere@pidgin.im>
parents:
10777
diff
changeset
|
1659 i++; |
93fd90cbf45c
[gaim-migrate @ 12410]
Luke Schierer <lschiere@pidgin.im>
parents:
10777
diff
changeset
|
1660 |
93fd90cbf45c
[gaim-migrate @ 12410]
Luke Schierer <lschiere@pidgin.im>
parents:
10777
diff
changeset
|
1661 label = links[i]; |
93fd90cbf45c
[gaim-migrate @ 12410]
Luke Schierer <lschiere@pidgin.im>
parents:
10777
diff
changeset
|
1662 |
93fd90cbf45c
[gaim-migrate @ 12410]
Luke Schierer <lschiere@pidgin.im>
parents:
10777
diff
changeset
|
1663 gtk_imhtml_insert_link(imhtml, mark, link, label); |
9300 | 1664 } else if (link=='\0') { |
1665 /* Ignore blank lines */ | |
1666 } else { | |
1667 /* Special reasons, aka images being put in via other tag, etc. */ | |
10345 | 1668 /* ... don't pretend we handled it if we didn't */ |
1669 gtk_drag_finish(dc, FALSE, FALSE, t); | |
10782
93fd90cbf45c
[gaim-migrate @ 12410]
Luke Schierer <lschiere@pidgin.im>
parents:
10777
diff
changeset
|
1670 g_strfreev(links); |
10345 | 1671 return; |
9300 | 1672 } |
10782
93fd90cbf45c
[gaim-migrate @ 12410]
Luke Schierer <lschiere@pidgin.im>
parents:
10777
diff
changeset
|
1673 |
93fd90cbf45c
[gaim-migrate @ 12410]
Luke Schierer <lschiere@pidgin.im>
parents:
10777
diff
changeset
|
1674 i++; |
8091 | 1675 } |
10782
93fd90cbf45c
[gaim-migrate @ 12410]
Luke Schierer <lschiere@pidgin.im>
parents:
10777
diff
changeset
|
1676 g_strfreev(links); |
9300 | 1677 break; |
10145 | 1678 case GTK_IMHTML_DRAG_HTML: |
10243 | 1679 { |
1680 char *utf8 = NULL; | |
1681 /* Ewww. This is all because mozilla thinks that text/html is 'for internal use only.' | |
1682 * as explained by this comment in gtkhtml: | |
1683 * | |
1684 * FIXME This hack decides the charset of the selection. It seems that | |
1685 * mozilla/netscape alway use ucs2 for text/html | |
1686 * and openoffice.org seems to always use utf8 so we try to validate | |
1687 * the string as utf8 and if that fails we assume it is ucs2 | |
1688 * | |
1689 * See also the comment on text/html here: | |
1690 * http://mail.gnome.org/archives/gtk-devel-list/2001-September/msg00114.html | |
1691 */ | |
1692 if (sd->length >= 2 && !g_utf8_validate(text, sd->length - 1, NULL)) { | |
11572
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
1693 utf8 = ucs2_to_utf8_with_bom_check(text, sd->length); |
10243 | 1694 |
1695 if (!utf8) { | |
9300 | 1696 gaim_debug_warning("gtkimhtml", "g_convert from UCS-2 failed in drag_rcv_cb\n"); |
1697 return; | |
1698 } | |
10243 | 1699 } else if (!(*text) || !g_utf8_validate(text, -1, NULL)) { |
9300 | 1700 gaim_debug_warning("gtkimhtml", "empty string or invalid UTF-8 in drag_rcv_cb\n"); |
1701 return; | |
1702 } | |
10243 | 1703 |
1704 gtk_imhtml_insert_html_at_iter(imhtml, utf8 ? utf8 : text, 0, &iter); | |
1705 g_free(utf8); | |
9300 | 1706 break; |
10243 | 1707 } |
10145 | 1708 case GTK_IMHTML_DRAG_TEXT: |
1709 if (!(*text) || !g_utf8_validate(text, -1, NULL)) { | |
1710 gaim_debug_warning("gtkimhtml", "empty string or invalid UTF-8 in drag_rcv_cb\n"); | |
1711 return; | |
1712 } else { | |
10732
c4cb90065e1d
[gaim-migrate @ 12334]
Luke Schierer <lschiere@pidgin.im>
parents:
10699
diff
changeset
|
1713 char *tmp = g_markup_escape_text(text, -1); |
10145 | 1714 gtk_imhtml_insert_html_at_iter(imhtml, tmp, 0, &iter); |
1715 g_free(tmp); | |
1716 } | |
1717 break; | |
9300 | 1718 default: |
10145 | 1719 gtk_drag_finish(dc, FALSE, FALSE, t); |
1720 return; | |
8091 | 1721 } |
1722 gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t); | |
1723 } else { | |
1724 gtk_drag_finish(dc, FALSE, FALSE, t); | |
1725 } | |
1726 } | |
1727 | |
4298 | 1728 /* this isn't used yet |
9300 | 1729 static void gtk_smiley_tree_remove (GtkSmileyTree *tree, |
4263 | 1730 GtkIMHtmlSmiley *smiley) |
4032 | 1731 { |
1732 GtkSmileyTree *t = tree; | |
4263 | 1733 const gchar *x = smiley->smile; |
4032 | 1734 gint len = 0; |
1735 | |
1736 while (*x) { | |
1737 gchar *pos; | |
1738 | |
1739 if (!t->values) | |
1740 return; | |
1741 | |
1742 pos = strchr (t->values->str, *x); | |
1743 if (pos) | |
1744 t = t->children [(int) pos - (int) t->values->str]; | |
1745 else | |
1746 return; | |
1747 | |
1748 x++; len++; | |
1749 } | |
1750 | |
4141
ccec4fde84f4
[gaim-migrate @ 4359]
Christian Hammond <chipx86@chipx86.com>
parents:
4140
diff
changeset
|
1751 if (t->image) { |
4032 | 1752 t->image = NULL; |
4141
ccec4fde84f4
[gaim-migrate @ 4359]
Christian Hammond <chipx86@chipx86.com>
parents:
4140
diff
changeset
|
1753 } |
4032 | 1754 } |
4298 | 1755 */ |
1756 | |
4032 | 1757 |
1758 static gint | |
1759 gtk_smiley_tree_lookup (GtkSmileyTree *tree, | |
1760 const gchar *text) | |
1761 { | |
1762 GtkSmileyTree *t = tree; | |
1763 const gchar *x = text; | |
1764 gint len = 0; | |
8505 | 1765 gchar *amp; |
1766 gint alen; | |
4032 | 1767 |
1768 while (*x) { | |
1769 gchar *pos; | |
1770 | |
1771 if (!t->values) | |
1772 break; | |
1773 | |
8505 | 1774 if(*x == '&' && gtk_imhtml_is_amp_escape(x, &, &alen)) { |
10865
c28766b87f64
[gaim-migrate @ 12549]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10858
diff
changeset
|
1775 gboolean matched = TRUE; |
c28766b87f64
[gaim-migrate @ 12549]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10858
diff
changeset
|
1776 /* Make sure all chars of the unescaped value match */ |
c28766b87f64
[gaim-migrate @ 12549]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10858
diff
changeset
|
1777 while (*(amp + 1)) { |
c28766b87f64
[gaim-migrate @ 12549]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10858
diff
changeset
|
1778 pos = strchr (t->values->str, *amp); |
c28766b87f64
[gaim-migrate @ 12549]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10858
diff
changeset
|
1779 if (pos) |
c28766b87f64
[gaim-migrate @ 12549]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10858
diff
changeset
|
1780 t = t->children [GPOINTER_TO_INT(pos) - GPOINTER_TO_INT(t->values->str)]; |
c28766b87f64
[gaim-migrate @ 12549]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10858
diff
changeset
|
1781 else { |
c28766b87f64
[gaim-migrate @ 12549]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10858
diff
changeset
|
1782 matched = FALSE; |
c28766b87f64
[gaim-migrate @ 12549]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10858
diff
changeset
|
1783 break; |
c28766b87f64
[gaim-migrate @ 12549]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10858
diff
changeset
|
1784 } |
c28766b87f64
[gaim-migrate @ 12549]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10858
diff
changeset
|
1785 amp++; |
c28766b87f64
[gaim-migrate @ 12549]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10858
diff
changeset
|
1786 } |
c28766b87f64
[gaim-migrate @ 12549]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10858
diff
changeset
|
1787 if (!matched) |
c28766b87f64
[gaim-migrate @ 12549]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10858
diff
changeset
|
1788 break; |
c28766b87f64
[gaim-migrate @ 12549]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10858
diff
changeset
|
1789 |
c28766b87f64
[gaim-migrate @ 12549]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10858
diff
changeset
|
1790 pos = strchr (t->values->str, *amp); |
8505 | 1791 } |
11572
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
1792 else if (*x == '<') /* Because we're all WYSIWYG now, a '<' |
9636 | 1793 * char should only appear as the start of a tag. Perhaps a safer (but costlier) |
1794 * check would be to call gtk_imhtml_is_tag on it */ | |
10600 | 1795 break; |
10865
c28766b87f64
[gaim-migrate @ 12549]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10858
diff
changeset
|
1796 else { |
c28766b87f64
[gaim-migrate @ 12549]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10858
diff
changeset
|
1797 alen = 1; |
c28766b87f64
[gaim-migrate @ 12549]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10858
diff
changeset
|
1798 pos = strchr (t->values->str, *x); |
c28766b87f64
[gaim-migrate @ 12549]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10858
diff
changeset
|
1799 } |
8505 | 1800 |
4032 | 1801 if (pos) |
7371 | 1802 t = t->children [GPOINTER_TO_INT(pos) - GPOINTER_TO_INT(t->values->str)]; |
4032 | 1803 else |
1804 break; | |
1805 | |
10865
c28766b87f64
[gaim-migrate @ 12549]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10858
diff
changeset
|
1806 x += alen; |
c28766b87f64
[gaim-migrate @ 12549]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10858
diff
changeset
|
1807 len += alen; |
4032 | 1808 } |
1809 | |
1810 if (t->image) | |
1811 return len; | |
1812 | |
1813 return 0; | |
1814 } | |
1815 | |
1816 void | |
4263 | 1817 gtk_imhtml_associate_smiley (GtkIMHtml *imhtml, |
10537 | 1818 const gchar *sml, |
4263 | 1819 GtkIMHtmlSmiley *smiley) |
4032 | 1820 { |
1821 GtkSmileyTree *tree; | |
1822 g_return_if_fail (imhtml != NULL); | |
1823 g_return_if_fail (GTK_IS_IMHTML (imhtml)); | |
7371 | 1824 |
4032 | 1825 if (sml == NULL) |
1826 tree = imhtml->default_smilies; | |
12833
cb2d493e1925
[gaim-migrate @ 15181]
Richard Laager <rlaager@wiktel.com>
parents:
12796
diff
changeset
|
1827 else if (!(tree = g_hash_table_lookup(imhtml->smiley_data, sml))) { |
4032 | 1828 tree = gtk_smiley_tree_new(); |
4892 | 1829 g_hash_table_insert(imhtml->smiley_data, g_strdup(sml), tree); |
4032 | 1830 } |
1831 | |
12335 | 1832 smiley->imhtml = imhtml; |
1833 | |
4263 | 1834 gtk_smiley_tree_insert (tree, smiley); |
4032 | 1835 } |
1836 | |
1837 static gboolean | |
1838 gtk_imhtml_is_smiley (GtkIMHtml *imhtml, | |
1839 GSList *fonts, | |
1840 const gchar *text, | |
1841 gint *len) | |
1842 { | |
1843 GtkSmileyTree *tree; | |
5967 | 1844 GtkIMHtmlFontDetail *font; |
4032 | 1845 char *sml = NULL; |
1846 | |
1847 if (fonts) { | |
1848 font = fonts->data; | |
1849 sml = font->sml; | |
1850 } | |
1851 | |
9029 | 1852 if (!sml) |
1853 sml = imhtml->protocol_name; | |
1854 | |
1855 if (!sml || !(tree = g_hash_table_lookup(imhtml->smiley_data, sml))) | |
4032 | 1856 tree = imhtml->default_smilies; |
9029 | 1857 |
4032 | 1858 if (tree == NULL) |
1859 return FALSE; | |
7371 | 1860 |
8505 | 1861 *len = gtk_smiley_tree_lookup (tree, text); |
4032 | 1862 return (*len > 0); |
1863 } | |
1864 | |
10526 | 1865 GtkIMHtmlSmiley * |
1866 gtk_imhtml_smiley_get(GtkIMHtml *imhtml, | |
1867 const gchar *sml, | |
1868 const gchar *text) | |
4032 | 1869 { |
1870 GtkSmileyTree *t; | |
1871 const gchar *x = text; | |
1872 if (sml == NULL) | |
1873 t = imhtml->default_smilies; | |
7371 | 1874 else |
4032 | 1875 t = g_hash_table_lookup(imhtml->smiley_data, sml); |
7371 | 1876 |
4032 | 1877 |
1878 if (t == NULL) | |
10526 | 1879 return sml ? gtk_imhtml_smiley_get(imhtml, NULL, text) : NULL; |
4032 | 1880 |
1881 while (*x) { | |
1882 gchar *pos; | |
1883 | |
1884 if (!t->values) { | |
10526 | 1885 return sml ? gtk_imhtml_smiley_get(imhtml, NULL, text) : NULL; |
4032 | 1886 } |
7371 | 1887 |
4032 | 1888 pos = strchr (t->values->str, *x); |
1889 if (pos) { | |
7371 | 1890 t = t->children [GPOINTER_TO_INT(pos) - GPOINTER_TO_INT(t->values->str)]; |
4032 | 1891 } else { |
10526 | 1892 return sml ? gtk_imhtml_smiley_get(imhtml, NULL, text) : NULL; |
4032 | 1893 } |
1894 x++; | |
1895 } | |
1896 | |
10526 | 1897 return t->image; |
1898 } | |
1899 | |
11677 | 1900 static GdkPixbufAnimation * |
10526 | 1901 gtk_smiley_tree_image (GtkIMHtml *imhtml, |
1902 const gchar *sml, | |
1903 const gchar *text) | |
1904 { | |
1905 | |
1906 GtkIMHtmlSmiley *smiley; | |
1907 | |
1908 smiley = gtk_imhtml_smiley_get(imhtml,sml,text); | |
1909 | |
11572
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
1910 if (!smiley) |
8890 | 1911 return NULL; |
1912 | |
10526 | 1913 if (!smiley->icon && smiley->file) { |
1914 smiley->icon = gdk_pixbuf_animation_new_from_file(smiley->file, NULL); | |
1915 } else if (!smiley->icon && smiley->loader) { | |
1916 smiley->icon = gdk_pixbuf_loader_get_animation(smiley->loader); | |
1917 if (smiley->icon) | |
1918 g_object_ref(G_OBJECT(smiley->icon)); | |
1919 } | |
11572
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
1920 |
10526 | 1921 return smiley->icon; |
4032 | 1922 } |
8890 | 1923 |
4793 | 1924 #define VALID_TAG(x) if (!g_ascii_strncasecmp (string, x ">", strlen (x ">"))) { \ |
3922 | 1925 *tag = g_strndup (string, strlen (x)); \ |
1926 *len = strlen (x) + 1; \ | |
1927 return TRUE; \ | |
1928 } \ | |
1929 (*type)++ | |
1428 | 1930 |
4793 | 1931 #define VALID_OPT_TAG(x) if (!g_ascii_strncasecmp (string, x " ", strlen (x " "))) { \ |
3922 | 1932 const gchar *c = string + strlen (x " "); \ |
1933 gchar e = '"'; \ | |
1934 gboolean quote = FALSE; \ | |
1935 while (*c) { \ | |
1936 if (*c == '"' || *c == '\'') { \ | |
1937 if (quote && (*c == e)) \ | |
1938 quote = !quote; \ | |
1939 else if (!quote) { \ | |
1940 quote = !quote; \ | |
1941 e = *c; \ | |
1942 } \ | |
1943 } else if (!quote && (*c == '>')) \ | |
1944 break; \ | |
1945 c++; \ | |
1946 } \ | |
1947 if (*c) { \ | |
1948 *tag = g_strndup (string, c - string); \ | |
1949 *len = c - string + 1; \ | |
1950 return TRUE; \ | |
1951 } \ | |
1952 } \ | |
1953 (*type)++ | |
1428 | 1954 |
1955 | |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1956 static gboolean |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1957 gtk_imhtml_is_amp_escape (const gchar *string, |
7280 | 1958 gchar **replace, |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1959 gint *length) |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1960 { |
7287 | 1961 static char buf[7]; |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1962 g_return_val_if_fail (string != NULL, FALSE); |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1963 g_return_val_if_fail (replace != NULL, FALSE); |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1964 g_return_val_if_fail (length != NULL, FALSE); |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1965 |
4793 | 1966 if (!g_ascii_strncasecmp (string, "&", 5)) { |
7280 | 1967 *replace = "&"; |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1968 *length = 5; |
4793 | 1969 } else if (!g_ascii_strncasecmp (string, "<", 4)) { |
7280 | 1970 *replace = "<"; |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1971 *length = 4; |
4793 | 1972 } else if (!g_ascii_strncasecmp (string, ">", 4)) { |
7280 | 1973 *replace = ">"; |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1974 *length = 4; |
4793 | 1975 } else if (!g_ascii_strncasecmp (string, " ", 6)) { |
7280 | 1976 *replace = " "; |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1977 *length = 6; |
4793 | 1978 } else if (!g_ascii_strncasecmp (string, "©", 6)) { |
7280 | 1979 *replace = "©"; |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1980 *length = 6; |
4793 | 1981 } else if (!g_ascii_strncasecmp (string, """, 6)) { |
7280 | 1982 *replace = "\""; |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1983 *length = 6; |
4793 | 1984 } else if (!g_ascii_strncasecmp (string, "®", 5)) { |
7280 | 1985 *replace = "®"; |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1986 *length = 5; |
5093 | 1987 } else if (!g_ascii_strncasecmp (string, "'", 6)) { |
7280 | 1988 *replace = "\'"; |
5093 | 1989 *length = 6; |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1990 } else if (*(string + 1) == '#') { |
2022
199ba82faacb
[gaim-migrate @ 2032]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2002
diff
changeset
|
1991 guint pound = 0; |
3004 | 1992 if ((sscanf (string, "&#%u;", £) == 1) && pound != 0) { |
7287 | 1993 int buflen; |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1994 if (*(string + 3 + (gint)log10 (pound)) != ';') |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1995 return FALSE; |
7287 | 1996 buflen = g_unichar_to_utf8((gunichar)pound, buf); |
1997 buf[buflen] = '\0'; | |
7280 | 1998 *replace = buf; |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1999 *length = 2; |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
2000 while (isdigit ((gint) string [*length])) (*length)++; |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
2001 if (string [*length] == ';') (*length)++; |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
2002 } else { |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
2003 return FALSE; |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
2004 } |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
2005 } else { |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
2006 return FALSE; |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
2007 } |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
2008 |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
2009 return TRUE; |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
2010 } |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
2011 |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2012 static gboolean |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2013 gtk_imhtml_is_tag (const gchar *string, |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2014 gchar **tag, |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2015 gint *len, |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2016 gint *type) |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2017 { |
8061 | 2018 char *close; |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2019 *type = 1; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2020 |
8118 | 2021 |
8061 | 2022 if (!(close = strchr (string, '>'))) |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2023 return FALSE; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2024 |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2025 VALID_TAG ("B"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2026 VALID_TAG ("BOLD"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2027 VALID_TAG ("/B"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2028 VALID_TAG ("/BOLD"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2029 VALID_TAG ("I"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2030 VALID_TAG ("ITALIC"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2031 VALID_TAG ("/I"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2032 VALID_TAG ("/ITALIC"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2033 VALID_TAG ("U"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2034 VALID_TAG ("UNDERLINE"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2035 VALID_TAG ("/U"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2036 VALID_TAG ("/UNDERLINE"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2037 VALID_TAG ("S"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2038 VALID_TAG ("STRIKE"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2039 VALID_TAG ("/S"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2040 VALID_TAG ("/STRIKE"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2041 VALID_TAG ("SUB"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2042 VALID_TAG ("/SUB"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2043 VALID_TAG ("SUP"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2044 VALID_TAG ("/SUP"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2045 VALID_TAG ("PRE"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2046 VALID_TAG ("/PRE"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2047 VALID_TAG ("TITLE"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2048 VALID_TAG ("/TITLE"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2049 VALID_TAG ("BR"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2050 VALID_TAG ("HR"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2051 VALID_TAG ("/FONT"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2052 VALID_TAG ("/A"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2053 VALID_TAG ("P"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2054 VALID_TAG ("/P"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2055 VALID_TAG ("H3"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2056 VALID_TAG ("/H3"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2057 VALID_TAG ("HTML"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2058 VALID_TAG ("/HTML"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2059 VALID_TAG ("BODY"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2060 VALID_TAG ("/BODY"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2061 VALID_TAG ("FONT"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2062 VALID_TAG ("HEAD"); |
2993 | 2063 VALID_TAG ("/HEAD"); |
2064 VALID_TAG ("BINARY"); | |
2065 VALID_TAG ("/BINARY"); | |
5093 | 2066 |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2067 VALID_OPT_TAG ("HR"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2068 VALID_OPT_TAG ("FONT"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2069 VALID_OPT_TAG ("BODY"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2070 VALID_OPT_TAG ("A"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2071 VALID_OPT_TAG ("IMG"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2072 VALID_OPT_TAG ("P"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2073 VALID_OPT_TAG ("H3"); |
5093 | 2074 VALID_OPT_TAG ("HTML"); |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2075 |
5101 | 2076 VALID_TAG ("CITE"); |
2077 VALID_TAG ("/CITE"); | |
2078 VALID_TAG ("EM"); | |
2079 VALID_TAG ("/EM"); | |
2080 VALID_TAG ("STRONG"); | |
2081 VALID_TAG ("/STRONG"); | |
2082 | |
5104 | 2083 VALID_OPT_TAG ("SPAN"); |
2084 VALID_TAG ("/SPAN"); | |
5174 | 2085 VALID_TAG ("BR/"); /* hack until gtkimhtml handles things better */ |
6982 | 2086 VALID_TAG ("IMG"); |
8026 | 2087 VALID_TAG("SPAN"); |
8061 | 2088 VALID_OPT_TAG("BR"); |
7988 | 2089 |
4793 | 2090 if (!g_ascii_strncasecmp(string, "!--", strlen ("!--"))) { |
2954
f6c4f2187c08
[gaim-migrate @ 2967]
Christian Hammond <chipx86@chipx86.com>
parents:
2898
diff
changeset
|
2091 gchar *e = strstr (string + strlen("!--"), "-->"); |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2092 if (e) { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2093 *len = e - string + strlen ("-->"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2094 *tag = g_strndup (string + strlen ("!--"), *len - strlen ("!---->")); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2095 return TRUE; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2096 } |
8118 | 2097 } |
2098 | |
8061 | 2099 *type = -1; |
2100 *len = close - string + 1; | |
2101 *tag = g_strndup(string, *len - 1); | |
2102 return TRUE; | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2103 } |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2104 |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2105 static gchar* |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2106 gtk_imhtml_get_html_opt (gchar *tag, |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2107 const gchar *opt) |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2108 { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2109 gchar *t = tag; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2110 gchar *e, *a; |
5177 | 2111 gchar *val; |
2112 gint len; | |
7280 | 2113 gchar *c; |
5177 | 2114 GString *ret; |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2115 |
4793 | 2116 while (g_ascii_strncasecmp (t, opt, strlen (opt))) { |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2117 gboolean quote = FALSE; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2118 if (*t == '\0') break; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2119 while (*t && !((*t == ' ') && !quote)) { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2120 if (*t == '\"') |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2121 quote = ! quote; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2122 t++; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2123 } |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2124 while (*t && (*t == ' ')) t++; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2125 } |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2126 |
4793 | 2127 if (!g_ascii_strncasecmp (t, opt, strlen (opt))) { |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2128 t += strlen (opt); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2129 } else { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2130 return NULL; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2131 } |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2132 |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2133 if ((*t == '\"') || (*t == '\'')) { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2134 e = a = ++t; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2135 while (*e && (*e != *(t - 1))) e++; |
2993 | 2136 if (*e == '\0') { |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2137 return NULL; |
5177 | 2138 } else |
2139 val = g_strndup(a, e - a); | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2140 } else { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2141 e = a = t; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2142 while (*e && !isspace ((gint) *e)) e++; |
5177 | 2143 val = g_strndup(a, e - a); |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2144 } |
5177 | 2145 |
2146 ret = g_string_new(""); | |
2147 e = val; | |
2148 while(*e) { | |
2149 if(gtk_imhtml_is_amp_escape(e, &c, &len)) { | |
7280 | 2150 ret = g_string_append(ret, c); |
5177 | 2151 e += len; |
2152 } else { | |
2153 ret = g_string_append_c(ret, *e); | |
2154 e++; | |
2155 } | |
2156 } | |
2157 | |
2158 g_free(val); | |
8568 | 2159 |
2160 return g_string_free(ret, FALSE); | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2161 } |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2162 |
8118 | 2163 /* Inline CSS Support - Douglas Thrift */ |
2164 static gchar* | |
2165 gtk_imhtml_get_css_opt (gchar *style, | |
2166 const gchar *opt) | |
2167 { | |
2168 gchar *t = style; | |
2169 gchar *e, *a; | |
2170 gchar *val; | |
2171 gint len; | |
2172 gchar *c; | |
2173 GString *ret; | |
2174 | |
2175 while (g_ascii_strncasecmp (t, opt, strlen (opt))) { | |
8177 | 2176 /* gboolean quote = FALSE; */ |
8118 | 2177 if (*t == '\0') break; |
2178 while (*t && !((*t == ' ') /*&& !quote*/)) { | |
2179 /* if (*t == '\"') | |
8177 | 2180 quote = ! quote; */ |
8118 | 2181 t++; |
2182 } | |
2183 while (*t && (*t == ' ')) t++; | |
2184 } | |
2185 | |
2186 if (!g_ascii_strncasecmp (t, opt, strlen (opt))) { | |
2187 t += strlen (opt); | |
10457 | 2188 while (*t && (*t == ' ')) t++; |
2189 if (!*t) | |
2190 return NULL; | |
8118 | 2191 } else { |
2192 return NULL; | |
2193 } | |
2194 | |
2195 /* if ((*t == '\"') || (*t == '\'')) { | |
2196 e = a = ++t; | |
2197 while (*e && (*e != *(t - 1))) e++; | |
2198 if (*e == '\0') { | |
2199 return NULL; | |
2200 } else | |
2201 val = g_strndup(a, e - a); | |
2202 } else { | |
2203 e = a = t; | |
2204 while (*e && !isspace ((gint) *e)) e++; | |
2205 val = g_strndup(a, e - a); | |
2206 }*/ | |
2207 | |
2208 e = a = t; | |
2209 while (*e && *e != ';') e++; | |
2210 val = g_strndup(a, e - a); | |
2211 | |
2212 ret = g_string_new(""); | |
2213 e = val; | |
2214 while(*e) { | |
2215 if(gtk_imhtml_is_amp_escape(e, &c, &len)) { | |
2216 ret = g_string_append(ret, c); | |
2217 e += len; | |
2218 } else { | |
2219 ret = g_string_append_c(ret, *e); | |
2220 e++; | |
2221 } | |
2222 } | |
2223 | |
2224 g_free(val); | |
2225 val = ret->str; | |
2226 g_string_free(ret, FALSE); | |
2227 return val; | |
2228 } | |
3922 | 2229 |
8334 | 2230 static const char *accepted_protocols[] = { |
2231 "http://", | |
2232 "https://", | |
2233 "ftp://" | |
2234 }; | |
11572
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
2235 |
8334 | 2236 static const int accepted_protocols_size = 3; |
2237 | |
2238 /* returns if the beginning of the text is a protocol. If it is the protocol, returns the length so | |
2239 the caller knows how long the protocol string is. */ | |
12412
a88ca6da0b38
[gaim-migrate @ 14719]
Richard Laager <rlaager@wiktel.com>
parents:
12335
diff
changeset
|
2240 static int gtk_imhtml_is_protocol(const char *text) |
8334 | 2241 { |
2242 gint i; | |
2243 | |
2244 for(i=0; i<accepted_protocols_size; i++){ | |
2245 if( strncasecmp(text, accepted_protocols[i], strlen(accepted_protocols[i])) == 0 ){ | |
2246 return strlen(accepted_protocols[i]); | |
2247 } | |
2248 } | |
2249 return 0; | |
2250 } | |
2251 | |
8677 | 2252 /* |
2253 <KingAnt> marv: The two IM image functions in oscar are gaim_odc_send_im and gaim_odc_incoming | |
2254 | |
2255 | |
2256 [19:58] <Robot101> marv: images go into the imgstore, a refcounted... well.. hash. :) | |
2257 [19:59] <KingAnt> marv: I think the image tag used by the core is something like <img id="#"/> | |
11572
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
2258 [19:59] Ro0tSiEgE robert42 RobFlynn Robot101 ross22 roz |
8677 | 2259 [20:00] <KingAnt> marv: Where the ID is the what is returned when you add the image to the imgstore using gaim_imgstore_add |
2260 [20:00] <marv> Robot101: so how does the image get passed to serv_got_im() and serv_send_im()? just as the <img id="#" and then the prpl looks it up from the store? | |
2261 [20:00] <KingAnt> marv: Right | |
2262 [20:00] <marv> alright | |
2263 | |
2264 Here's my plan with IMImages. make gtk_imhtml_[append|insert]_text_with_images instead just | |
2265 gtkimhtml_[append|insert]_text (hrm maybe it should be called html instead of text), add a | |
2266 function for gaim to register for look up images, i.e. gtk_imhtml_set_get_img_fnc, so that | |
2267 images can be looked up like that, instead of passing a GSList of them. | |
2268 */ | |
2269 | |
2270 void gtk_imhtml_append_text_with_images (GtkIMHtml *imhtml, | |
2271 const gchar *text, | |
2272 GtkIMHtmlOptions options, | |
2273 GSList *unused) | |
1428 | 2274 { |
8677 | 2275 GtkTextIter iter, ins, sel; |
2276 GdkRectangle rect; | |
2277 int y, height, ins_offset = 0, sel_offset = 0; | |
2278 gboolean fixins = FALSE, fixsel = FALSE; | |
2279 | |
2280 g_return_if_fail (imhtml != NULL); | |
2281 g_return_if_fail (GTK_IS_IMHTML (imhtml)); | |
2282 g_return_if_fail (text != NULL); | |
2283 | |
2284 | |
2285 gtk_text_buffer_get_end_iter(imhtml->text_buffer, &iter); | |
2286 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &ins, gtk_text_buffer_get_insert(imhtml->text_buffer)); | |
2287 if (gtk_text_iter_equal(&iter, &ins) && gtk_text_buffer_get_selection_bounds(imhtml->text_buffer, NULL, NULL)) { | |
2288 fixins = TRUE; | |
2289 ins_offset = gtk_text_iter_get_offset(&ins); | |
2290 } | |
2291 | |
2292 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &sel, gtk_text_buffer_get_selection_bound(imhtml->text_buffer)); | |
2293 if (gtk_text_iter_equal(&iter, &sel) && gtk_text_buffer_get_selection_bounds(imhtml->text_buffer, NULL, NULL)) { | |
2294 fixsel = TRUE; | |
2295 sel_offset = gtk_text_iter_get_offset(&sel); | |
2296 } | |
2297 | |
2298 gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(imhtml), &rect); | |
2299 gtk_text_view_get_line_yrange(GTK_TEXT_VIEW(imhtml), &iter, &y, &height); | |
2300 | |
2301 | |
2302 if(((y + height) - (rect.y + rect.height)) > height | |
2303 && gtk_text_buffer_get_char_count(imhtml->text_buffer)){ | |
2304 options |= GTK_IMHTML_NO_SCROLL; | |
2305 } | |
2306 | |
2307 gtk_imhtml_insert_html_at_iter(imhtml, text, options, &iter); | |
2308 | |
2309 if (fixins) { | |
2310 gtk_text_buffer_get_iter_at_offset(imhtml->text_buffer, &ins, ins_offset); | |
2311 gtk_text_buffer_move_mark(imhtml->text_buffer, gtk_text_buffer_get_insert(imhtml->text_buffer), &ins); | |
2312 } | |
2313 | |
2314 if (fixsel) { | |
2315 gtk_text_buffer_get_iter_at_offset(imhtml->text_buffer, &sel, sel_offset); | |
2316 gtk_text_buffer_move_mark(imhtml->text_buffer, gtk_text_buffer_get_selection_bound(imhtml->text_buffer), &sel); | |
2317 } | |
2318 | |
2319 if (!(options & GTK_IMHTML_NO_SCROLL)) { | |
12553 | 2320 gtk_imhtml_scroll_to_end(imhtml, (options & GTK_IMHTML_USE_SMOOTHSCROLLING)); |
8677 | 2321 } |
2322 } | |
2323 | |
11006 | 2324 #define MAX_SCROLL_TIME 0.4 /* seconds */ |
2325 #define SCROLL_DELAY 33 /* milliseconds */ | |
2326 | |
2327 /* | |
2328 * Smoothly scroll a GtkIMHtml. | |
2329 * | |
2330 * @return TRUE if the window needs to be scrolled further, FALSE if we're at the bottom. | |
2331 */ | |
10871 | 2332 static gboolean scroll_cb(gpointer data) |
10798 | 2333 { |
2334 GtkIMHtml *imhtml = data; | |
2335 GtkAdjustment *adj = GTK_TEXT_VIEW(imhtml)->vadjustment; | |
11006 | 2336 gdouble max_val = adj->upper - adj->page_size; |
2337 | |
2338 g_return_val_if_fail(imhtml->scroll_time != NULL, FALSE); | |
2339 | |
2340 if (g_timer_elapsed(imhtml->scroll_time, NULL) > MAX_SCROLL_TIME) { | |
2341 /* time's up. jump to the end and kill the timer */ | |
2342 gtk_adjustment_set_value(adj, max_val); | |
10798 | 2343 g_timer_destroy(imhtml->scroll_time); |
2344 imhtml->scroll_time = NULL; | |
2345 return FALSE; | |
11006 | 2346 } |
2347 | |
2348 /* scroll by 1/3rd the remaining distance */ | |
2349 gtk_adjustment_set_value(adj, gtk_adjustment_get_value(adj) + ((max_val - gtk_adjustment_get_value(adj)) / 3)); | |
2350 return TRUE; | |
10798 | 2351 } |
2352 | |
12553 | 2353 static gboolean smooth_scroll_idle_cb(gpointer data) |
10797 | 2354 { |
10798 | 2355 GtkIMHtml *imhtml = data; |
11006 | 2356 imhtml->scroll_src = g_timeout_add(SCROLL_DELAY, scroll_cb, imhtml); |
10797 | 2357 return FALSE; |
2358 } | |
2359 | |
12553 | 2360 static gboolean scroll_idle_cb(gpointer data) |
2361 { | |
2362 GtkIMHtml *imhtml = data; | |
2363 GtkAdjustment *adj = GTK_TEXT_VIEW(imhtml)->vadjustment; | |
2364 if(adj) { | |
2365 gtk_adjustment_set_value(adj, adj->upper - adj->page_size); | |
2366 } | |
2367 imhtml->scroll_src = 0; | |
2368 return FALSE; | |
2369 } | |
2370 | |
2371 void gtk_imhtml_scroll_to_end(GtkIMHtml *imhtml, gboolean smooth) | |
8729 | 2372 { |
10798 | 2373 if (imhtml->scroll_time) |
2374 g_timer_destroy(imhtml->scroll_time); | |
2375 if (imhtml->scroll_src) | |
2376 g_source_remove(imhtml->scroll_src); | |
12553 | 2377 if(smooth) { |
2378 imhtml->scroll_time = g_timer_new(); | |
2379 imhtml->scroll_src = g_idle_add_full(G_PRIORITY_LOW, smooth_scroll_idle_cb, imhtml, NULL); | |
2380 } else { | |
2381 imhtml->scroll_time = NULL; | |
2382 imhtml->scroll_src = g_idle_add_full(G_PRIORITY_LOW, scroll_idle_cb, imhtml, NULL); | |
2383 } | |
8729 | 2384 } |
2385 | |
8677 | 2386 void gtk_imhtml_insert_html_at_iter(GtkIMHtml *imhtml, |
2387 const gchar *text, | |
2388 GtkIMHtmlOptions options, | |
2389 GtkTextIter *iter) | |
2390 { | |
8061 | 2391 GdkRectangle rect; |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2392 gint pos = 0; |
3922 | 2393 gchar *ws; |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2394 gchar *tag; |
3922 | 2395 gchar *bg = NULL; |
6982 | 2396 gint len; |
4032 | 2397 gint tlen, smilelen, wpos=0; |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2398 gint type; |
3922 | 2399 const gchar *c; |
7280 | 2400 gchar *amp; |
8334 | 2401 gint len_protocol; |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2402 |
1428 | 2403 guint bold = 0, |
2404 italics = 0, | |
2405 underline = 0, | |
2406 strike = 0, | |
2407 sub = 0, | |
2408 sup = 0, | |
1691
d802b115800f
[gaim-migrate @ 1701]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1647
diff
changeset
|
2409 title = 0, |
8061 | 2410 pre = 0; |
1428 | 2411 |
10217 | 2412 gboolean br = FALSE; |
2413 | |
3922 | 2414 GSList *fonts = NULL; |
8506 | 2415 GObject *object; |
8061 | 2416 GtkIMHtmlScalable *scalable = NULL; |
8677 | 2417 |
2418 g_return_if_fail (imhtml != NULL); | |
2419 g_return_if_fail (GTK_IS_IMHTML (imhtml)); | |
2420 g_return_if_fail (text != NULL); | |
3922 | 2421 c = text; |
6982 | 2422 len = strlen(text); |
3922 | 2423 ws = g_malloc(len + 1); |
2424 ws[0] = 0; | |
1428 | 2425 |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2426 while (pos < len) { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2427 if (*c == '<' && gtk_imhtml_is_tag (c + 1, &tag, &tlen, &type)) { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2428 c++; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2429 pos++; |
8061 | 2430 ws[wpos] = '\0'; |
10217 | 2431 br = FALSE; |
8061 | 2432 switch (type) |
3922 | 2433 { |
2434 case 1: /* B */ | |
2435 case 2: /* BOLD */ | |
5101 | 2436 case 54: /* STRONG */ |
11485
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2437 if (!(options & GTK_IMHTML_NO_FORMATTING)) { |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2438 gtk_text_buffer_insert(imhtml->text_buffer, iter, ws, wpos); |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2439 |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2440 if ((bold == 0) && (imhtml->format_functions & GTK_IMHTML_BOLD)) |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2441 gtk_imhtml_toggle_bold(imhtml); |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2442 bold++; |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2443 ws[0] = '\0'; wpos = 0; |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2444 } |
3922 | 2445 break; |
2446 case 3: /* /B */ | |
2447 case 4: /* /BOLD */ | |
5101 | 2448 case 55: /* /STRONG */ |
11485
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2449 if (!(options & GTK_IMHTML_NO_FORMATTING)) { |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2450 gtk_text_buffer_insert(imhtml->text_buffer, iter, ws, wpos); |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2451 ws[0] = '\0'; wpos = 0; |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2452 |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2453 if (bold) |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2454 bold--; |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2455 if ((bold == 0) && (imhtml->format_functions & GTK_IMHTML_BOLD) && !imhtml->wbfo) |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2456 gtk_imhtml_toggle_bold(imhtml); |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2457 } |
3922 | 2458 break; |
2459 case 5: /* I */ | |
2460 case 6: /* ITALIC */ | |
5101 | 2461 case 52: /* EM */ |
11485
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2462 if (!(options & GTK_IMHTML_NO_FORMATTING)) { |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2463 gtk_text_buffer_insert(imhtml->text_buffer, iter, ws, wpos); |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2464 ws[0] = '\0'; wpos = 0; |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2465 if ((italics == 0) && (imhtml->format_functions & GTK_IMHTML_ITALIC)) |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2466 gtk_imhtml_toggle_italic(imhtml); |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2467 italics++; |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2468 } |
3922 | 2469 break; |
2470 case 7: /* /I */ | |
2471 case 8: /* /ITALIC */ | |
5101 | 2472 case 53: /* /EM */ |
11485
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2473 if (!(options & GTK_IMHTML_NO_FORMATTING)) { |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2474 gtk_text_buffer_insert(imhtml->text_buffer, iter, ws, wpos); |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2475 ws[0] = '\0'; wpos = 0; |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2476 if (italics) |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2477 italics--; |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2478 if ((italics == 0) && (imhtml->format_functions & GTK_IMHTML_ITALIC) && !imhtml->wbfo) |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2479 gtk_imhtml_toggle_italic(imhtml); |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2480 } |
3922 | 2481 break; |
2482 case 9: /* U */ | |
2483 case 10: /* UNDERLINE */ | |
11485
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2484 if (!(options & GTK_IMHTML_NO_FORMATTING)) { |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2485 gtk_text_buffer_insert(imhtml->text_buffer, iter, ws, wpos); |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2486 ws[0] = '\0'; wpos = 0; |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2487 if ((underline == 0) && (imhtml->format_functions & GTK_IMHTML_UNDERLINE)) |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2488 gtk_imhtml_toggle_underline(imhtml); |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2489 underline++; |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2490 } |
3922 | 2491 break; |
2492 case 11: /* /U */ | |
2493 case 12: /* /UNDERLINE */ | |
11485
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2494 if (!(options & GTK_IMHTML_NO_FORMATTING)) { |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2495 gtk_text_buffer_insert(imhtml->text_buffer, iter, ws, wpos); |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2496 ws[0] = '\0'; wpos = 0; |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2497 if (underline) |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2498 underline--; |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2499 if ((underline == 0) && (imhtml->format_functions & GTK_IMHTML_UNDERLINE) && !imhtml->wbfo) |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2500 gtk_imhtml_toggle_underline(imhtml); |
16b0da1f376f
[gaim-migrate @ 13727]
Richard Laager <rlaager@wiktel.com>
parents:
11385
diff
changeset
|
2501 } |
3922 | 2502 break; |
2503 case 13: /* S */ | |
2504 case 14: /* STRIKE */ | |
9924 | 2505 gtk_text_buffer_insert(imhtml->text_buffer, iter, ws, wpos); |
2506 ws[0] = '\0'; wpos = 0; | |
2507 if ((strike == 0) && (imhtml->format_functions & GTK_IMHTML_STRIKE)) | |
2508 gtk_imhtml_toggle_strike(imhtml); | |
3922 | 2509 strike++; |
2510 break; | |
2511 case 15: /* /S */ | |
2512 case 16: /* /STRIKE */ | |
9924 | 2513 gtk_text_buffer_insert(imhtml->text_buffer, iter, ws, wpos); |
2514 ws[0] = '\0'; wpos = 0; | |
3922 | 2515 if (strike) |
2516 strike--; | |
9924 | 2517 if ((strike == 0) && (imhtml->format_functions & GTK_IMHTML_STRIKE) && !imhtml->wbfo) |
2518 gtk_imhtml_toggle_strike(imhtml); | |
3922 | 2519 break; |
2520 case 17: /* SUB */ | |
8677 | 2521 /* FIXME: reimpliment this */ |
3922 | 2522 sub++; |
2523 break; | |
2524 case 18: /* /SUB */ | |
8677 | 2525 /* FIXME: reimpliment this */ |
3922 | 2526 if (sub) |
2527 sub--; | |
2528 break; | |
2529 case 19: /* SUP */ | |
8677 | 2530 /* FIXME: reimplement this */ |
3922 | 2531 sup++; |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2532 break; |
3922 | 2533 case 20: /* /SUP */ |
8677 | 2534 /* FIXME: reimplement this */ |
3922 | 2535 if (sup) |
2536 sup--; | |
2537 break; | |
2538 case 21: /* PRE */ | |
8677 | 2539 /* FIXME: reimplement this */ |
3922 | 2540 pre++; |
2541 break; | |
2542 case 22: /* /PRE */ | |
8677 | 2543 /* FIXME: reimplement this */ |
3922 | 2544 if (pre) |
2545 pre--; | |
2546 break; | |
2547 case 23: /* TITLE */ | |
8677 | 2548 /* FIXME: what was this supposed to do anyway? */ |
3922 | 2549 title++; |
2550 break; | |
2551 case 24: /* /TITLE */ | |
8677 | 2552 /* FIXME: make this undo whatever 23 was supposed to do */ |
3922 | 2553 if (title) { |
2554 if (options & GTK_IMHTML_NO_TITLE) { | |
2555 wpos = 0; | |
2556 ws [wpos] = '\0'; | |
2557 } | |
2558 title--; | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2559 } |
3922 | 2560 break; |
2561 case 25: /* BR */ | |
5174 | 2562 case 58: /* BR/ */ |
8061 | 2563 case 61: /* BR (opt) */ |
3922 | 2564 ws[wpos] = '\n'; |
2565 wpos++; | |
10217 | 2566 br = TRUE; |
6982 | 2567 break; |
3922 | 2568 case 26: /* HR */ |
2569 case 42: /* HR (opt) */ | |
8726 | 2570 { |
2571 int minus; | |
11224
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
2572 struct scalable_data *sd = g_new(struct scalable_data, 1); |
8726 | 2573 |
3922 | 2574 ws[wpos++] = '\n'; |
8677 | 2575 gtk_text_buffer_insert(imhtml->text_buffer, iter, ws, wpos); |
2576 | |
11224
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
2577 sd->scalable = scalable = gtk_imhtml_hr_new(); |
11233
f08d22130bb2
[gaim-migrate @ 13373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11224
diff
changeset
|
2578 sd->mark = gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, iter, TRUE); |
8061 | 2579 gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(imhtml), &rect); |
8677 | 2580 scalable->add_to(scalable, imhtml, iter); |
8726 | 2581 minus = gtk_text_view_get_left_margin(GTK_TEXT_VIEW(imhtml)) + |
2582 gtk_text_view_get_right_margin(GTK_TEXT_VIEW(imhtml)); | |
2583 scalable->scale(scalable, rect.width - minus, rect.height); | |
11224
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
2584 imhtml->scalables = g_list_append(imhtml->scalables, sd); |
8061 | 2585 ws[0] = '\0'; wpos = 0; |
7942 | 2586 ws[wpos++] = '\n'; |
8061 | 2587 |
3922 | 2588 break; |
8726 | 2589 } |
3922 | 2590 case 27: /* /FONT */ |
8677 | 2591 if (fonts && !imhtml->wbfo) { |
5967 | 2592 GtkIMHtmlFontDetail *font = fonts->data; |
8677 | 2593 gtk_text_buffer_insert(imhtml->text_buffer, iter, ws, wpos); |
8061 | 2594 ws[0] = '\0'; wpos = 0; |
8177 | 2595 /* NEW_BIT (NEW_TEXT_BIT); */ |
8677 | 2596 |
8698 | 2597 if (font->face && (imhtml->format_functions & GTK_IMHTML_FACE)) { |
8061 | 2598 gtk_imhtml_toggle_fontface(imhtml, NULL); |
3922 | 2599 g_free (font->face); |
8061 | 2600 } |
8698 | 2601 if (font->fore && (imhtml->format_functions & GTK_IMHTML_FORECOLOR)) { |
8061 | 2602 gtk_imhtml_toggle_forecolor(imhtml, NULL); |
3922 | 2603 g_free (font->fore); |
8061 | 2604 } |
8698 | 2605 if (font->back && (imhtml->format_functions & GTK_IMHTML_BACKCOLOR)) { |
8061 | 2606 gtk_imhtml_toggle_backcolor(imhtml, NULL); |
3922 | 2607 g_free (font->back); |
8061 | 2608 } |
4032 | 2609 if (font->sml) |
2610 g_free (font->sml); | |
8309 | 2611 |
8698 | 2612 if ((font->size != 3) && (imhtml->format_functions & (GTK_IMHTML_GROW|GTK_IMHTML_SHRINK))) |
8309 | 2613 gtk_imhtml_font_set_size(imhtml, 3); |
2614 | |
10761 | 2615 |
2616 fonts = g_slist_remove (fonts, font); | |
9245 | 2617 g_free(font); |
2618 | |
8309 | 2619 if (fonts) { |
2620 GtkIMHtmlFontDetail *font = fonts->data; | |
8677 | 2621 |
8698 | 2622 if (font->face && (imhtml->format_functions & GTK_IMHTML_FACE)) |
8309 | 2623 gtk_imhtml_toggle_fontface(imhtml, font->face); |
8698 | 2624 if (font->fore && (imhtml->format_functions & GTK_IMHTML_FORECOLOR)) |
8309 | 2625 gtk_imhtml_toggle_forecolor(imhtml, font->fore); |
8698 | 2626 if (font->back && (imhtml->format_functions & GTK_IMHTML_BACKCOLOR)) |
8309 | 2627 gtk_imhtml_toggle_backcolor(imhtml, font->back); |
8698 | 2628 if ((font->size != 3) && (imhtml->format_functions & (GTK_IMHTML_GROW|GTK_IMHTML_SHRINK))) |
8309 | 2629 gtk_imhtml_font_set_size(imhtml, font->size); |
2630 } | |
3922 | 2631 } |
8309 | 2632 break; |
3922 | 2633 case 28: /* /A */ |
8677 | 2634 gtk_text_buffer_insert(imhtml->text_buffer, iter, ws, wpos); |
2635 gtk_imhtml_toggle_link(imhtml, NULL); | |
2636 ws[0] = '\0'; wpos = 0; | |
8061 | 2637 break; |
8118 | 2638 |
3922 | 2639 case 29: /* P */ |
2640 case 30: /* /P */ | |
2641 case 31: /* H3 */ | |
2642 case 32: /* /H3 */ | |
2643 case 33: /* HTML */ | |
2644 case 34: /* /HTML */ | |
2645 case 35: /* BODY */ | |
10776 | 2646 break; |
3922 | 2647 case 36: /* /BODY */ |
10786 | 2648 gtk_text_buffer_insert(imhtml->text_buffer, iter, ws, wpos); |
2649 ws[0] = '\0'; wpos = 0; | |
10776 | 2650 gtk_imhtml_toggle_background(imhtml, NULL); |
2651 break; | |
3922 | 2652 case 37: /* FONT */ |
2653 case 38: /* HEAD */ | |
2654 case 39: /* /HEAD */ | |
6982 | 2655 case 40: /* BINARY */ |
2656 case 41: /* /BINARY */ | |
3922 | 2657 break; |
2658 case 43: /* FONT (opt) */ | |
2659 { | |
4032 | 2660 gchar *color, *back, *face, *size, *sml; |
5967 | 2661 GtkIMHtmlFontDetail *font, *oldfont = NULL; |
3922 | 2662 color = gtk_imhtml_get_html_opt (tag, "COLOR="); |
2663 back = gtk_imhtml_get_html_opt (tag, "BACK="); | |
2664 face = gtk_imhtml_get_html_opt (tag, "FACE="); | |
2665 size = gtk_imhtml_get_html_opt (tag, "SIZE="); | |
4032 | 2666 sml = gtk_imhtml_get_html_opt (tag, "SML="); |
2667 if (!(color || back || face || size || sml)) | |
3922 | 2668 break; |
8061 | 2669 |
8677 | 2670 gtk_text_buffer_insert(imhtml->text_buffer, iter, ws, wpos); |
8061 | 2671 ws[0] = '\0'; wpos = 0; |
2672 | |
5967 | 2673 font = g_new0 (GtkIMHtmlFontDetail, 1); |
3922 | 2674 if (fonts) |
2675 oldfont = fonts->data; | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2676 |
8677 | 2677 if (color && !(options & GTK_IMHTML_NO_COLOURS) && (imhtml->format_functions & GTK_IMHTML_FORECOLOR)) { |
3922 | 2678 font->fore = color; |
8061 | 2679 gtk_imhtml_toggle_forecolor(imhtml, font->fore); |
8677 | 2680 } |
2681 | |
2682 if (back && !(options & GTK_IMHTML_NO_COLOURS) && (imhtml->format_functions & GTK_IMHTML_BACKCOLOR)) { | |
3922 | 2683 font->back = back; |
8061 | 2684 gtk_imhtml_toggle_backcolor(imhtml, font->back); |
8309 | 2685 } |
8677 | 2686 |
2687 if (face && !(options & GTK_IMHTML_NO_FONTS) && (imhtml->format_functions & GTK_IMHTML_FACE)) { | |
3922 | 2688 font->face = face; |
8061 | 2689 gtk_imhtml_toggle_fontface(imhtml, font->face); |
8309 | 2690 } |
4032 | 2691 |
2692 if (sml) | |
2693 font->sml = sml; | |
2694 else if (oldfont && oldfont->sml) | |
2695 font->sml = g_strdup(oldfont->sml); | |
2696 | |
8677 | 2697 if (size && !(options & GTK_IMHTML_NO_SIZES) && (imhtml->format_functions & (GTK_IMHTML_GROW|GTK_IMHTML_SHRINK))) { |
3922 | 2698 if (*size == '+') { |
2699 sscanf (size + 1, "%hd", &font->size); | |
2700 font->size += 3; | |
2701 } else if (*size == '-') { | |
2702 sscanf (size + 1, "%hd", &font->size); | |
2703 font->size = MAX (0, 3 - font->size); | |
2704 } else if (isdigit (*size)) { | |
2705 sscanf (size, "%hd", &font->size); | |
8061 | 2706 } |
6042 | 2707 if (font->size > 100) |
2708 font->size = 100; | |
3922 | 2709 } else if (oldfont) |
2710 font->size = oldfont->size; | |
8309 | 2711 else |
2712 font->size = 3; | |
8698 | 2713 if ((imhtml->format_functions & (GTK_IMHTML_GROW|GTK_IMHTML_SHRINK))) |
2714 gtk_imhtml_font_set_size(imhtml, font->size); | |
3922 | 2715 g_free(size); |
2716 fonts = g_slist_prepend (fonts, font); | |
2717 } | |
2718 break; | |
2719 case 44: /* BODY (opt) */ | |
2720 if (!(options & GTK_IMHTML_NO_COLOURS)) { | |
2721 char *bgcolor = gtk_imhtml_get_html_opt (tag, "BGCOLOR="); | |
8677 | 2722 if (bgcolor && (imhtml->format_functions & GTK_IMHTML_BACKCOLOR)) { |
2723 gtk_text_buffer_insert(imhtml->text_buffer, iter, ws, wpos); | |
8061 | 2724 ws[0] = '\0'; wpos = 0; |
8177 | 2725 /* NEW_BIT(NEW_TEXT_BIT); */ |
3922 | 2726 if (bg) |
2727 g_free(bg); | |
2728 bg = bgcolor; | |
10776 | 2729 gtk_imhtml_toggle_background(imhtml, bg); |
2885
f72efa29c109
[gaim-migrate @ 2898]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2871
diff
changeset
|
2730 } |
1428 | 2731 } |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2732 break; |
3922 | 2733 case 45: /* A (opt) */ |
2734 { | |
2735 gchar *href = gtk_imhtml_get_html_opt (tag, "HREF="); | |
8677 | 2736 if (href && (imhtml->format_functions & GTK_IMHTML_LINK)) { |
2737 gtk_text_buffer_insert(imhtml->text_buffer, iter, ws, wpos); | |
8061 | 2738 ws[0] = '\0'; wpos = 0; |
8677 | 2739 gtk_imhtml_toggle_link(imhtml, href); |
3922 | 2740 } |
10504 | 2741 if (href) |
2742 g_free(href); | |
2993 | 2743 } |
3922 | 2744 break; |
4895 | 2745 case 46: /* IMG (opt) */ |
6982 | 2746 case 59: /* IMG */ |
4895 | 2747 { |
8962 | 2748 const char *id; |
2749 | |
2750 gtk_text_buffer_insert(imhtml->text_buffer, iter, ws, wpos); | |
2751 ws[0] = '\0'; wpos = 0; | |
4895 | 2752 |
8677 | 2753 if (!(imhtml->format_functions & GTK_IMHTML_IMAGE)) |
2754 break; | |
2755 | |
8962 | 2756 id = gtk_imhtml_get_html_opt(tag, "ID="); |
9186 | 2757 if (!id) |
2758 break; | |
8962 | 2759 gtk_imhtml_insert_image_at_iter(imhtml, atoi(id), iter); |
2760 break; | |
4895 | 2761 } |
3922 | 2762 case 47: /* P (opt) */ |
2763 case 48: /* H3 (opt) */ | |
5093 | 2764 case 49: /* HTML (opt) */ |
5101 | 2765 case 50: /* CITE */ |
2766 case 51: /* /CITE */ | |
8026 | 2767 case 56: /* SPAN (opt) */ |
8118 | 2768 /* Inline CSS Support - Douglas Thrift |
2769 * | |
2770 * color | |
8686 | 2771 * background |
8118 | 2772 * font-family |
2773 * font-size | |
8686 | 2774 * text-decoration: underline |
10483 | 2775 * |
2776 * TODO: | |
2777 * background-color | |
2778 * font-style | |
2779 * font-weight | |
8118 | 2780 */ |
2781 { | |
8686 | 2782 gchar *style, *color, *background, *family, *size; |
2783 gchar *textdec; | |
8118 | 2784 GtkIMHtmlFontDetail *font, *oldfont = NULL; |
2785 style = gtk_imhtml_get_html_opt (tag, "style="); | |
2786 | |
2787 if (!style) break; | |
2788 | |
10457 | 2789 color = gtk_imhtml_get_css_opt (style, "color:"); |
2790 background = gtk_imhtml_get_css_opt (style, "background:"); | |
8118 | 2791 family = gtk_imhtml_get_css_opt (style, |
10457 | 2792 "font-family:"); |
2793 size = gtk_imhtml_get_css_opt (style, "font-size:"); | |
2794 textdec = gtk_imhtml_get_css_opt (style, "text-decoration:"); | |
8686 | 2795 |
2796 if (!(color || family || size || background || textdec)) { | |
8120 | 2797 g_free(style); |
2798 break; | |
2799 } | |
8118 | 2800 |
8677 | 2801 |
2802 gtk_text_buffer_insert(imhtml->text_buffer, iter, ws, wpos); | |
8118 | 2803 ws[0] = '\0'; wpos = 0; |
8177 | 2804 /* NEW_BIT (NEW_TEXT_BIT); */ |
8118 | 2805 |
2806 font = g_new0 (GtkIMHtmlFontDetail, 1); | |
2807 if (fonts) | |
2808 oldfont = fonts->data; | |
2809 | |
8677 | 2810 if (color && !(options & GTK_IMHTML_NO_COLOURS) && (imhtml->format_functions & GTK_IMHTML_FORECOLOR)) |
8686 | 2811 { |
8118 | 2812 font->fore = color; |
8686 | 2813 gtk_imhtml_toggle_forecolor(imhtml, font->fore); |
2814 } | |
8118 | 2815 else if (oldfont && oldfont->fore) |
2816 font->fore = g_strdup(oldfont->fore); | |
2817 | |
8686 | 2818 if (background && !(options & GTK_IMHTML_NO_COLOURS) && (imhtml->format_functions & GTK_IMHTML_BACKCOLOR)) |
2819 { | |
2820 font->back = background; | |
2821 gtk_imhtml_toggle_backcolor(imhtml, font->back); | |
2822 } | |
2823 else if (oldfont && oldfont->back) | |
8118 | 2824 font->back = g_strdup(oldfont->back); |
2825 | |
8677 | 2826 if (family && !(options & GTK_IMHTML_NO_FONTS) && (imhtml->format_functions & GTK_IMHTML_FACE)) |
8686 | 2827 { |
8118 | 2828 font->face = family; |
8686 | 2829 gtk_imhtml_toggle_fontface(imhtml, font->face); |
2830 } | |
8118 | 2831 else if (oldfont && oldfont->face) |
2832 font->face = g_strdup(oldfont->face); | |
2833 if (font->face && (atoi(font->face) > 100)) { | |
8677 | 2834 /* WTF is this? */ |
11572
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
2835 /* Maybe it sets a max size on the font face? I seem to |
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
2836 * remember bad things happening if the font size was |
9696 | 2837 * 2 billion */ |
8118 | 2838 g_free(font->face); |
2839 font->face = g_strdup("100"); | |
2840 } | |
2841 | |
2842 if (oldfont && oldfont->sml) | |
2843 font->sml = g_strdup(oldfont->sml); | |
2844 | |
8677 | 2845 if (size && !(options & GTK_IMHTML_NO_SIZES) && (imhtml->format_functions & (GTK_IMHTML_SHRINK|GTK_IMHTML_GROW))) { |
8686 | 2846 if (g_ascii_strcasecmp(size, "xx-small") == 0) |
2847 font->size = 1; | |
2848 else if (g_ascii_strcasecmp(size, "smaller") == 0 | |
2849 || g_ascii_strcasecmp(size, "x-small") == 0) | |
8118 | 2850 font->size = 2; |
8686 | 2851 else if (g_ascii_strcasecmp(size, "larger") == 0 |
2852 || g_ascii_strcasecmp(size, "medium") == 0) | |
8118 | 2853 font->size = 4; |
8686 | 2854 else if (g_ascii_strcasecmp(size, "large") == 0) |
2855 font->size = 5; | |
2856 else if (g_ascii_strcasecmp(size, "x-large") == 0) | |
2857 font->size = 6; | |
2858 else if (g_ascii_strcasecmp(size, "xx-large") == 0) | |
2859 font->size = 7; | |
8118 | 2860 else |
2861 font->size = 3; | |
8686 | 2862 gtk_imhtml_font_set_size(imhtml, font->size); |
2863 } | |
2864 else if (oldfont) | |
2865 { | |
2866 font->size = oldfont->size; | |
2867 } | |
2868 | |
2869 if (oldfont) | |
2870 { | |
2871 font->underline = oldfont->underline; | |
2872 } | |
2873 if (textdec && font->underline != 1 | |
9025 | 2874 && g_ascii_strcasecmp(textdec, "underline") == 0 |
8686 | 2875 && (imhtml->format_functions & GTK_IMHTML_UNDERLINE)) |
2876 { | |
2877 gtk_imhtml_toggle_underline(imhtml); | |
2878 font->underline = 1; | |
2879 } | |
8118 | 2880 |
2881 g_free(style); | |
2882 g_free(size); | |
2883 fonts = g_slist_prepend (fonts, font); | |
2884 } | |
2885 break; | |
5104 | 2886 case 57: /* /SPAN */ |
8118 | 2887 /* Inline CSS Support - Douglas Thrift */ |
8677 | 2888 if (fonts && !imhtml->wbfo) { |
8686 | 2889 GtkIMHtmlFontDetail *oldfont = NULL; |
8118 | 2890 GtkIMHtmlFontDetail *font = fonts->data; |
8677 | 2891 gtk_text_buffer_insert(imhtml->text_buffer, iter, ws, wpos); |
8118 | 2892 ws[0] = '\0'; wpos = 0; |
8177 | 2893 /* NEW_BIT (NEW_TEXT_BIT); */ |
8118 | 2894 fonts = g_slist_remove (fonts, font); |
8692 | 2895 if (fonts) |
2896 oldfont = fonts->data; | |
2897 | |
2898 if (!oldfont) { | |
2899 gtk_imhtml_font_set_size(imhtml, 3); | |
2900 if (font->underline) | |
2901 gtk_imhtml_toggle_underline(imhtml); | |
2902 gtk_imhtml_toggle_fontface(imhtml, NULL); | |
2903 gtk_imhtml_toggle_forecolor(imhtml, NULL); | |
2904 gtk_imhtml_toggle_backcolor(imhtml, NULL); | |
8686 | 2905 } |
8692 | 2906 else |
8686 | 2907 { |
8692 | 2908 |
2909 if (font->size != oldfont->size) | |
2910 gtk_imhtml_font_set_size(imhtml, oldfont->size); | |
2911 | |
2912 if (font->underline != oldfont->underline) | |
2913 gtk_imhtml_toggle_underline(imhtml); | |
2914 | |
9286 | 2915 if (font->face && (!oldfont->face || strcmp(font->face, oldfont->face) != 0)) |
8692 | 2916 gtk_imhtml_toggle_fontface(imhtml, oldfont->face); |
2917 | |
9286 | 2918 if (font->fore && (!oldfont->fore || strcmp(font->fore, oldfont->fore) != 0)) |
8692 | 2919 gtk_imhtml_toggle_forecolor(imhtml, oldfont->fore); |
2920 | |
9286 | 2921 if (font->back && (!oldfont->back || strcmp(font->back, oldfont->back) != 0)) |
8692 | 2922 gtk_imhtml_toggle_backcolor(imhtml, oldfont->back); |
8686 | 2923 } |
8692 | 2924 |
2925 g_free (font->face); | |
2926 g_free (font->fore); | |
2927 g_free (font->back); | |
2928 g_free (font->sml); | |
2929 | |
8118 | 2930 g_free (font); |
2931 } | |
2932 break; | |
8026 | 2933 case 60: /* SPAN */ |
2993 | 2934 break; |
8061 | 2935 case 62: /* comment */ |
8177 | 2936 /* NEW_BIT (NEW_TEXT_BIT); */ |
8317 | 2937 ws[wpos] = '\0'; |
9465 | 2938 |
8677 | 2939 gtk_text_buffer_insert(imhtml->text_buffer, iter, ws, wpos); |
2940 | |
10815 | 2941 if (imhtml->show_comments && !(options & GTK_IMHTML_NO_COMMENTS)) { |
6124 | 2942 wpos = g_snprintf (ws, len, "%s", tag); |
10815 | 2943 gtk_text_buffer_insert(imhtml->text_buffer, iter, ws, wpos); |
2944 } | |
2945 ws[0] = '\0'; wpos = 0; | |
2946 | |
8177 | 2947 /* NEW_BIT (NEW_COMMENT_BIT); */ |
3922 | 2948 break; |
2949 default: | |
6882 | 2950 break; |
2993 | 2951 } |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2952 c += tlen; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2953 pos += tlen; |
13137
1ed228c65e89
[gaim-migrate @ 15499]
Richard Laager <rlaager@wiktel.com>
parents:
13136
diff
changeset
|
2954 g_free(tag); /* This was allocated back in VALID_TAG() */ |
9029 | 2955 } else if (gtk_imhtml_is_smiley(imhtml, fonts, c, &smilelen)) { |
8473 | 2956 GtkIMHtmlFontDetail *fd; |
2957 | |
2958 gchar *sml = NULL; | |
2959 if (fonts) { | |
2960 fd = fonts->data; | |
2961 sml = fd->sml; | |
2962 } | |
9029 | 2963 if (!sml) |
2964 sml = imhtml->protocol_name; | |
2965 | |
8677 | 2966 gtk_text_buffer_insert(imhtml->text_buffer, iter, ws, wpos); |
8505 | 2967 wpos = g_snprintf (ws, smilelen + 1, "%s", c); |
8473 | 2968 |
8677 | 2969 gtk_imhtml_insert_smiley_at_iter(imhtml, sml, ws, iter); |
8473 | 2970 |
8505 | 2971 c += smilelen; |
2972 pos += smilelen; | |
8473 | 2973 wpos = 0; |
2974 ws[0] = 0; | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2975 } else if (*c == '&' && gtk_imhtml_is_amp_escape (c, &, &tlen)) { |
7280 | 2976 while(*amp) { |
2977 ws [wpos++] = *amp++; | |
2978 } | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2979 c += tlen; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
2980 pos += tlen; |
1428 | 2981 } else if (*c == '\n') { |
2982 if (!(options & GTK_IMHTML_NO_NEWLINE)) { | |
3922 | 2983 ws[wpos] = '\n'; |
2984 wpos++; | |
8677 | 2985 gtk_text_buffer_insert(imhtml->text_buffer, iter, ws, wpos); |
8061 | 2986 ws[0] = '\0'; |
2987 wpos = 0; | |
8177 | 2988 /* NEW_BIT (NEW_TEXT_BIT); */ |
10217 | 2989 } else if (!br) { /* Don't insert a space immediately after an HTML break */ |
9621 | 2990 /* A newline is defined by HTML as whitespace, which means we have to replace it with a word boundary. |
2991 * word breaks vary depending on the language used, so the correct thing to do is to use Pango to determine | |
2992 * what language this is, determine the proper word boundary to use, and insert that. I'm just going to insert | |
2993 * a space instead. What are the non-English speakers going to do? Complain in a language I'll understand? | |
2994 * Bu-wahaha! */ | |
2995 ws[wpos] = ' '; | |
2996 wpos++; | |
2997 gtk_text_buffer_insert(imhtml->text_buffer, iter, ws, wpos); | |
2998 ws[0] = '\0'; | |
2999 wpos = 0; | |
1428 | 3000 } |
3001 c++; | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
3002 pos++; |
8334 | 3003 } else if ((len_protocol = gtk_imhtml_is_protocol(c)) > 0){ |
3004 while(len_protocol--){ | |
8677 | 3005 /* Skip the next len_protocol characters, but make sure they're |
8334 | 3006 copied into the ws array. |
3007 */ | |
3008 ws [wpos++] = *c++; | |
3009 pos++; | |
3010 } | |
8061 | 3011 } else if (*c) { |
1428 | 3012 ws [wpos++] = *c++; |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
3013 pos++; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
3014 } else { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
3015 break; |
1428 | 3016 } |
3017 } | |
8677 | 3018 gtk_text_buffer_insert(imhtml->text_buffer, iter, ws, wpos); |
8061 | 3019 ws[0] = '\0'; wpos = 0; |
3020 | |
8177 | 3021 /* NEW_BIT(NEW_TEXT_BIT); */ |
8061 | 3022 |
4032 | 3023 while (fonts) { |
5967 | 3024 GtkIMHtmlFontDetail *font = fonts->data; |
4032 | 3025 fonts = g_slist_remove (fonts, font); |
3026 if (font->face) | |
3027 g_free (font->face); | |
3028 if (font->fore) | |
3029 g_free (font->fore); | |
3030 if (font->back) | |
3031 g_free (font->back); | |
3032 if (font->sml) | |
3033 g_free (font->sml); | |
3034 g_free (font); | |
3035 } | |
8932 | 3036 |
3037 g_free(ws); | |
13137
1ed228c65e89
[gaim-migrate @ 15499]
Richard Laager <rlaager@wiktel.com>
parents:
13136
diff
changeset
|
3038 g_free(bg); |
8677 | 3039 |
3040 if (!imhtml->wbfo) | |
8698 | 3041 gtk_imhtml_close_tags(imhtml, iter); |
8506 | 3042 |
3043 object = g_object_ref(G_OBJECT(imhtml)); | |
3044 g_signal_emit(object, signals[UPDATE_FORMAT], 0); | |
3045 g_object_unref(object); | |
3046 | |
3922 | 3047 } |
3048 | |
4892 | 3049 void gtk_imhtml_remove_smileys(GtkIMHtml *imhtml) |
3050 { | |
4288 | 3051 g_hash_table_destroy(imhtml->smiley_data); |
3052 gtk_smiley_tree_destroy(imhtml->default_smilies); | |
4892 | 3053 imhtml->smiley_data = g_hash_table_new_full(g_str_hash, g_str_equal, |
4902 | 3054 g_free, (GDestroyNotify)gtk_smiley_tree_destroy); |
4288 | 3055 imhtml->default_smilies = gtk_smiley_tree_new(); |
3056 } | |
8481 | 3057 |
3922 | 3058 void gtk_imhtml_show_comments (GtkIMHtml *imhtml, |
4253 | 3059 gboolean show) |
3060 { | |
6124 | 3061 imhtml->show_comments = show; |
4253 | 3062 } |
1780
d7cbedd1d651
[gaim-migrate @ 1790]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1738
diff
changeset
|
3063 |
11814
fa17fc619f17
[gaim-migrate @ 14105]
Richard Laager <rlaager@wiktel.com>
parents:
11768
diff
changeset
|
3064 const char * |
fa17fc619f17
[gaim-migrate @ 14105]
Richard Laager <rlaager@wiktel.com>
parents:
11768
diff
changeset
|
3065 gtk_imhtml_get_protocol_name(GtkIMHtml *imhtml) { |
fa17fc619f17
[gaim-migrate @ 14105]
Richard Laager <rlaager@wiktel.com>
parents:
11768
diff
changeset
|
3066 return imhtml->protocol_name; |
fa17fc619f17
[gaim-migrate @ 14105]
Richard Laager <rlaager@wiktel.com>
parents:
11768
diff
changeset
|
3067 } |
fa17fc619f17
[gaim-migrate @ 14105]
Richard Laager <rlaager@wiktel.com>
parents:
11768
diff
changeset
|
3068 |
8962 | 3069 void |
9029 | 3070 gtk_imhtml_set_protocol_name(GtkIMHtml *imhtml, const gchar *protocol_name) { |
3071 if (imhtml->protocol_name) | |
3072 g_free(imhtml->protocol_name); | |
3073 imhtml->protocol_name = protocol_name ? g_strdup(protocol_name) : NULL; | |
8456 | 3074 } |
3075 | |
1780
d7cbedd1d651
[gaim-migrate @ 1790]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1738
diff
changeset
|
3076 void |
11224
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3077 gtk_imhtml_delete(GtkIMHtml *imhtml, GtkTextIter *start, GtkTextIter *end) { |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3078 GList *l; |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3079 GSList *sl; |
11234
7d5e8bed8018
[gaim-migrate @ 13377]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11233
diff
changeset
|
3080 GtkTextIter i, i_s, i_e; |
8427 | 3081 GObject *object = g_object_ref(G_OBJECT(imhtml)); |
11224
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3082 |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3083 if (start == NULL) { |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3084 gtk_text_buffer_get_start_iter(imhtml->text_buffer, &i_s); |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3085 start = &i_s; |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3086 } |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3087 |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3088 if (end == NULL) { |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3089 gtk_text_buffer_get_end_iter(imhtml->text_buffer, &i_e); |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3090 end = &i_e; |
7991 | 3091 } |
11224
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3092 |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3093 l = imhtml->scalables; |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3094 while (l) { |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3095 GList *next = l->next; |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3096 struct scalable_data *sd = l->data; |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3097 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3098 &i, sd->mark); |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3099 if (gtk_text_iter_in_range(&i, start, end)) { |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3100 GtkIMHtmlScalable *scale = sd->scalable; |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3101 scale->free(scale); |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3102 imhtml->scalables = g_list_remove_link(imhtml->scalables, l); |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3103 } |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3104 l = next; |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3105 } |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3106 |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3107 sl = imhtml->im_images; |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3108 while (sl) { |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3109 GSList *next = sl->next; |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3110 struct im_image_data *img_data = sl->data; |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3111 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3112 &i, img_data->mark); |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3113 if (gtk_text_iter_in_range(&i, start, end)) { |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3114 if (imhtml->funcs->image_unref) |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3115 imhtml->funcs->image_unref(img_data->id); |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3116 imhtml->im_images = g_slist_delete_link(imhtml->im_images, sl); |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3117 g_free(img_data); |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3118 } |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3119 sl = next; |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3120 } |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
3121 gtk_text_buffer_delete(imhtml->text_buffer, start, end); |
8061 | 3122 |
8427 | 3123 g_object_unref(object); |
1780
d7cbedd1d651
[gaim-migrate @ 1790]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1738
diff
changeset
|
3124 } |
2363
08c66712364c
[gaim-migrate @ 2376]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2349
diff
changeset
|
3125 |
4046 | 3126 void gtk_imhtml_page_up (GtkIMHtml *imhtml) |
3127 { | |
5282 | 3128 GdkRectangle rect; |
3129 GtkTextIter iter; | |
4046 | 3130 |
5282 | 3131 gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(imhtml), &rect); |
3132 gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(imhtml), &iter, rect.x, | |
3133 rect.y - rect.height); | |
3134 gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(imhtml), &iter, 0, TRUE, 0, 0); | |
8061 | 3135 |
4046 | 3136 } |
5282 | 3137 void gtk_imhtml_page_down (GtkIMHtml *imhtml) |
3138 { | |
3139 GdkRectangle rect; | |
3140 GtkTextIter iter; | |
3141 | |
3142 gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(imhtml), &rect); | |
3143 gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(imhtml), &iter, rect.x, | |
3144 rect.y + rect.height); | |
3145 gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(imhtml), &iter, 0, TRUE, 0, 0); | |
3146 } | |
4735 | 3147 |
5967 | 3148 /* GtkIMHtmlScalable, gtk_imhtml_image, gtk_imhtml_hr */ |
8962 | 3149 GtkIMHtmlScalable *gtk_imhtml_image_new(GdkPixbuf *img, const gchar *filename, int id) |
4735 | 3150 { |
5967 | 3151 GtkIMHtmlImage *im_image = g_malloc(sizeof(GtkIMHtmlImage)); |
5012 | 3152 GtkImage *image = GTK_IMAGE(gtk_image_new_from_pixbuf(img)); |
4895 | 3153 |
5967 | 3154 GTK_IMHTML_SCALABLE(im_image)->scale = gtk_imhtml_image_scale; |
3155 GTK_IMHTML_SCALABLE(im_image)->add_to = gtk_imhtml_image_add_to; | |
3156 GTK_IMHTML_SCALABLE(im_image)->free = gtk_imhtml_image_free; | |
5046 | 3157 |
3158 im_image->pixbuf = img; | |
5012 | 3159 im_image->image = image; |
4895 | 3160 im_image->width = gdk_pixbuf_get_width(img); |
3161 im_image->height = gdk_pixbuf_get_height(img); | |
3162 im_image->mark = NULL; | |
6982 | 3163 im_image->filename = filename ? g_strdup(filename) : NULL; |
8962 | 3164 im_image->id = id; |
9573 | 3165 im_image->filesel = NULL; |
4895 | 3166 |
5046 | 3167 g_object_ref(img); |
4895 | 3168 return GTK_IMHTML_SCALABLE(im_image); |
3169 } | |
3170 | |
5967 | 3171 void gtk_imhtml_image_scale(GtkIMHtmlScalable *scale, int width, int height) |
4895 | 3172 { |
11867
ff02464a079f
[gaim-migrate @ 14158]
Richard Laager <rlaager@wiktel.com>
parents:
11844
diff
changeset
|
3173 GtkIMHtmlImage *im_image = (GtkIMHtmlImage *)scale; |
ff02464a079f
[gaim-migrate @ 14158]
Richard Laager <rlaager@wiktel.com>
parents:
11844
diff
changeset
|
3174 |
ff02464a079f
[gaim-migrate @ 14158]
Richard Laager <rlaager@wiktel.com>
parents:
11844
diff
changeset
|
3175 if (im_image->width > width || im_image->height > height) { |
11840
047f85200139
[gaim-migrate @ 14131]
Richard Laager <rlaager@wiktel.com>
parents:
11820
diff
changeset
|
3176 double ratio_w, ratio_h, ratio; |
047f85200139
[gaim-migrate @ 14131]
Richard Laager <rlaager@wiktel.com>
parents:
11820
diff
changeset
|
3177 int new_h, new_w; |
4895 | 3178 GdkPixbuf *new_image = NULL; |
11840
047f85200139
[gaim-migrate @ 14131]
Richard Laager <rlaager@wiktel.com>
parents:
11820
diff
changeset
|
3179 |
11867
ff02464a079f
[gaim-migrate @ 14158]
Richard Laager <rlaager@wiktel.com>
parents:
11844
diff
changeset
|
3180 ratio_w = ((double)width - 2) / im_image->width; |
ff02464a079f
[gaim-migrate @ 14158]
Richard Laager <rlaager@wiktel.com>
parents:
11844
diff
changeset
|
3181 ratio_h = ((double)height - 2) / im_image->height; |
11840
047f85200139
[gaim-migrate @ 14131]
Richard Laager <rlaager@wiktel.com>
parents:
11820
diff
changeset
|
3182 |
047f85200139
[gaim-migrate @ 14131]
Richard Laager <rlaager@wiktel.com>
parents:
11820
diff
changeset
|
3183 ratio = (ratio_w < ratio_h) ? ratio_w : ratio_h; |
047f85200139
[gaim-migrate @ 14131]
Richard Laager <rlaager@wiktel.com>
parents:
11820
diff
changeset
|
3184 |
11867
ff02464a079f
[gaim-migrate @ 14158]
Richard Laager <rlaager@wiktel.com>
parents:
11844
diff
changeset
|
3185 new_w = (int)(im_image->width * ratio); |
ff02464a079f
[gaim-migrate @ 14158]
Richard Laager <rlaager@wiktel.com>
parents:
11844
diff
changeset
|
3186 new_h = (int)(im_image->height * ratio); |
ff02464a079f
[gaim-migrate @ 14158]
Richard Laager <rlaager@wiktel.com>
parents:
11844
diff
changeset
|
3187 |
ff02464a079f
[gaim-migrate @ 14158]
Richard Laager <rlaager@wiktel.com>
parents:
11844
diff
changeset
|
3188 new_image = gdk_pixbuf_scale_simple(im_image->pixbuf, new_w, new_h, GDK_INTERP_BILINEAR); |
ff02464a079f
[gaim-migrate @ 14158]
Richard Laager <rlaager@wiktel.com>
parents:
11844
diff
changeset
|
3189 gtk_image_set_from_pixbuf(im_image->image, new_image); |
ff02464a079f
[gaim-migrate @ 14158]
Richard Laager <rlaager@wiktel.com>
parents:
11844
diff
changeset
|
3190 g_object_unref(G_OBJECT(new_image)); |
ff02464a079f
[gaim-migrate @ 14158]
Richard Laager <rlaager@wiktel.com>
parents:
11844
diff
changeset
|
3191 } else if (gdk_pixbuf_get_width(gtk_image_get_pixbuf(im_image->image)) != im_image->width) { |
ff02464a079f
[gaim-migrate @ 14158]
Richard Laager <rlaager@wiktel.com>
parents:
11844
diff
changeset
|
3192 /* Enough space to show the full-size of the image. */ |
ff02464a079f
[gaim-migrate @ 14158]
Richard Laager <rlaager@wiktel.com>
parents:
11844
diff
changeset
|
3193 GdkPixbuf *new_image; |
ff02464a079f
[gaim-migrate @ 14158]
Richard Laager <rlaager@wiktel.com>
parents:
11844
diff
changeset
|
3194 |
ff02464a079f
[gaim-migrate @ 14158]
Richard Laager <rlaager@wiktel.com>
parents:
11844
diff
changeset
|
3195 new_image = gdk_pixbuf_scale_simple(im_image->pixbuf, im_image->width, im_image->height, GDK_INTERP_BILINEAR); |
ff02464a079f
[gaim-migrate @ 14158]
Richard Laager <rlaager@wiktel.com>
parents:
11844
diff
changeset
|
3196 gtk_image_set_from_pixbuf(im_image->image, new_image); |
4895 | 3197 g_object_unref(G_OBJECT(new_image)); |
3198 } | |
3199 } | |
3200 | |
9573 | 3201 static void |
3202 image_save_yes_cb(GtkIMHtmlImage *image, const char *filename) | |
5012 | 3203 { |
3204 gchar *type = NULL; | |
5019 | 3205 GError *error = NULL; |
5015 | 3206 #if GTK_CHECK_VERSION(2,2,0) |
5012 | 3207 GSList *formats = gdk_pixbuf_get_formats(); |
6162 | 3208 #else |
3209 char *basename = g_path_get_basename(filename); | |
3210 char *ext = strrchr(basename, '.'); | |
5959 | 3211 #endif |
5012 | 3212 |
9573 | 3213 gtk_widget_destroy(image->filesel); |
3214 image->filesel = NULL; | |
5959 | 3215 |
3216 #if GTK_CHECK_VERSION(2,2,0) | |
9573 | 3217 while (formats) { |
5012 | 3218 GdkPixbufFormat *format = formats->data; |
3219 gchar **extensions = gdk_pixbuf_format_get_extensions(format); | |
3220 gpointer p = extensions; | |
3221 | |
3222 while(gdk_pixbuf_format_is_writable(format) && extensions && extensions[0]){ | |
3223 gchar *fmt_ext = extensions[0]; | |
3224 const gchar* file_ext = filename + strlen(filename) - strlen(fmt_ext); | |
3225 | |
3226 if(!strcmp(fmt_ext, file_ext)){ | |
3227 type = gdk_pixbuf_format_get_name(format); | |
3228 break; | |
3229 } | |
3230 | |
3231 extensions++; | |
3232 } | |
3233 | |
3234 g_strfreev(p); | |
3235 | |
9573 | 3236 if (type) |
5012 | 3237 break; |
3238 | |
3239 formats = formats->next; | |
3240 } | |
3241 | |
5020 | 3242 g_slist_free(formats); |
3243 #else | |
3244 /* this is really ugly code, but I think it will work */ | |
9573 | 3245 if (ext) { |
5020 | 3246 ext++; |
9573 | 3247 if (!g_ascii_strcasecmp(ext, "jpeg") || !g_ascii_strcasecmp(ext, "jpg")) |
5020 | 3248 type = g_strdup("jpeg"); |
9573 | 3249 else if (!g_ascii_strcasecmp(ext, "png")) |
5020 | 3250 type = g_strdup("png"); |
3251 } | |
3252 | |
3253 g_free(basename); | |
3254 #endif | |
3255 | |
5012 | 3256 /* If I can't find a valid type, I will just tell the user about it and then assume |
3257 it's a png */ | |
9573 | 3258 if (!type){ |
11069
65db26d0bc90
[gaim-migrate @ 13065]
Richard Laager <rlaager@wiktel.com>
parents:
11019
diff
changeset
|
3259 #if GTK_CHECK_VERSION(2,4,0) |
11019 | 3260 GtkWidget *dialog = gtk_message_dialog_new_with_markup(NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, |
3261 _("<span size='larger' weight='bold'>Unrecognized file type</span>\n\nDefaulting to PNG.")); | |
11069
65db26d0bc90
[gaim-migrate @ 13065]
Richard Laager <rlaager@wiktel.com>
parents:
11019
diff
changeset
|
3262 #else |
65db26d0bc90
[gaim-migrate @ 13065]
Richard Laager <rlaager@wiktel.com>
parents:
11019
diff
changeset
|
3263 GtkWidget *dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, |
65db26d0bc90
[gaim-migrate @ 13065]
Richard Laager <rlaager@wiktel.com>
parents:
11019
diff
changeset
|
3264 _("Unrecognized file type\n\nDefaulting to PNG.")); |
65db26d0bc90
[gaim-migrate @ 13065]
Richard Laager <rlaager@wiktel.com>
parents:
11019
diff
changeset
|
3265 #endif |
65db26d0bc90
[gaim-migrate @ 13065]
Richard Laager <rlaager@wiktel.com>
parents:
11019
diff
changeset
|
3266 |
11019 | 3267 g_signal_connect_swapped(dialog, "response", G_CALLBACK (gtk_widget_destroy), dialog); |
3268 gtk_widget_show(dialog); | |
9717 | 3269 type = g_strdup("png"); |
5012 | 3270 } |
3271 | |
5046 | 3272 gdk_pixbuf_save(image->pixbuf, filename, type, &error, NULL); |
5012 | 3273 |
9573 | 3274 if (error){ |
11069
65db26d0bc90
[gaim-migrate @ 13065]
Richard Laager <rlaager@wiktel.com>
parents:
11019
diff
changeset
|
3275 #if GTK_CHECK_VERSION(2,4,0) |
11019 | 3276 GtkWidget *dialog = gtk_message_dialog_new_with_markup(NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, |
3277 _("<span size='larger' weight='bold'>Error saving image</span>\n\n%s"), error->message); | |
11069
65db26d0bc90
[gaim-migrate @ 13065]
Richard Laager <rlaager@wiktel.com>
parents:
11019
diff
changeset
|
3278 #else |
65db26d0bc90
[gaim-migrate @ 13065]
Richard Laager <rlaager@wiktel.com>
parents:
11019
diff
changeset
|
3279 GtkWidget *dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, |
65db26d0bc90
[gaim-migrate @ 13065]
Richard Laager <rlaager@wiktel.com>
parents:
11019
diff
changeset
|
3280 _("Error saving image\n\n%s"), error->message); |
65db26d0bc90
[gaim-migrate @ 13065]
Richard Laager <rlaager@wiktel.com>
parents:
11019
diff
changeset
|
3281 #endif |
11019 | 3282 g_signal_connect_swapped(dialog, "response", G_CALLBACK (gtk_widget_destroy), dialog); |
3283 gtk_widget_show(dialog); | |
5012 | 3284 g_error_free(error); |
3285 } | |
3286 | |
3287 g_free(type); | |
3288 } | |
3289 | |
9573 | 3290 #if GTK_CHECK_VERSION(2,4,0) /* FILECHOOSER */ |
3291 static void | |
3292 image_save_check_if_exists_cb(GtkWidget *widget, gint response, GtkIMHtmlImage *image) | |
3293 { | |
3294 gchar *filename; | |
3295 | |
3296 if (response != GTK_RESPONSE_ACCEPT) { | |
3297 gtk_widget_destroy(widget); | |
3298 image->filesel = NULL; | |
3299 return; | |
3300 } | |
3301 | |
3302 filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(widget)); | |
3303 #else /* FILECHOOSER */ | |
3304 static void | |
3305 image_save_check_if_exists_cb(GtkWidget *button, GtkIMHtmlImage *image) | |
5012 | 3306 { |
9573 | 3307 gchar *filename; |
3308 | |
3309 filename = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION(image->filesel))); | |
3310 | |
3311 if (g_file_test(filename, G_FILE_TEST_IS_DIR)) { | |
3312 gchar *dirname; | |
3313 /* append a / is needed */ | |
3314 if (filename[strlen(filename) - 1] != G_DIR_SEPARATOR) { | |
3315 dirname = g_strconcat(filename, G_DIR_SEPARATOR_S, NULL); | |
3316 } else { | |
3317 dirname = g_strdup(filename); | |
3318 } | |
9574 | 3319 gtk_file_selection_set_filename(GTK_FILE_SELECTION(image->filesel), dirname); |
9573 | 3320 g_free(dirname); |
3321 g_free(filename); | |
3322 return; | |
3323 } | |
3324 #endif /* FILECHOOSER */ | |
3325 | |
3326 /* | |
3327 * XXX - We should probably prompt the user to determine if they really | |
3328 * want to overwrite the file or not. However, I don't feel like doing | |
3329 * that, so we're just always going to overwrite if the file exists. | |
3330 */ | |
3331 /* | |
3332 if (g_file_test(filename, G_FILE_TEST_EXISTS)) { | |
3333 } else | |
3334 image_save_yes_cb(image, filename); | |
3335 */ | |
3336 | |
3337 image_save_yes_cb(image, filename); | |
3338 | |
3339 g_free(filename); | |
3340 } | |
3341 | |
3342 #if !GTK_CHECK_VERSION(2,4,0) /* FILECHOOSER */ | |
3343 static void | |
3344 image_save_cancel_cb(GtkIMHtmlImage *image) | |
3345 { | |
3346 gtk_widget_destroy(image->filesel); | |
3347 image->filesel = NULL; | |
3348 } | |
3349 #endif /* FILECHOOSER */ | |
3350 | |
3351 static void | |
3352 gtk_imhtml_image_save(GtkWidget *w, GtkIMHtmlImage *image) | |
3353 { | |
3354 if (image->filesel != NULL) { | |
3355 gtk_window_present(GTK_WINDOW(image->filesel)); | |
3356 return; | |
3357 } | |
3358 | |
3359 #if GTK_CHECK_VERSION(2,4,0) /* FILECHOOSER */ | |
3360 image->filesel = gtk_file_chooser_dialog_new(_("Save Image"), | |
3361 NULL, | |
3362 GTK_FILE_CHOOSER_ACTION_SAVE, | |
3363 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, | |
3364 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, | |
3365 NULL); | |
3366 gtk_dialog_set_default_response(GTK_DIALOG(image->filesel), GTK_RESPONSE_ACCEPT); | |
3367 if (image->filename != NULL) | |
3368 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(image->filesel), image->filename); | |
3369 g_signal_connect(G_OBJECT(GTK_FILE_CHOOSER(image->filesel)), "response", | |
3370 G_CALLBACK(image_save_check_if_exists_cb), image); | |
3371 #else /* FILECHOOSER */ | |
3372 image->filesel = gtk_file_selection_new(_("Save Image")); | |
3373 if (image->filename != NULL) | |
3374 gtk_file_selection_set_filename(GTK_FILE_SELECTION(image->filesel), image->filename); | |
9574 | 3375 g_signal_connect_swapped(G_OBJECT(GTK_FILE_SELECTION(image->filesel)), "delete_event", |
3376 G_CALLBACK(image_save_cancel_cb), image); | |
3377 g_signal_connect_swapped(G_OBJECT(GTK_FILE_SELECTION(image->filesel)->cancel_button), | |
3378 "clicked", G_CALLBACK(image_save_cancel_cb), image); | |
9573 | 3379 g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(image->filesel)->ok_button), "clicked", |
3380 G_CALLBACK(image_save_check_if_exists_cb), image); | |
3381 #endif /* FILECHOOSER */ | |
3382 | |
3383 gtk_widget_show(image->filesel); | |
5012 | 3384 } |
3385 | |
9815 | 3386 /* |
3387 * So, um, AIM Direct IM lets you send any file, not just images. You can | |
3388 * just insert a sound or a file or whatever in a conversation. It's | |
3389 * basically like file transfer, except there is an icon to open the file | |
3390 * embedded in the conversation. Someone should make the Gaim core handle | |
3391 * all of that. | |
3392 */ | |
5967 | 3393 static gboolean gtk_imhtml_image_clicked(GtkWidget *w, GdkEvent *event, GtkIMHtmlImage *image) |
5012 | 3394 { |
3395 GdkEventButton *event_button = (GdkEventButton *) event; | |
3396 | |
3397 if (event->type == GDK_BUTTON_RELEASE) { | |
3398 if(event_button->button == 3) { | |
3399 GtkWidget *img, *item, *menu; | |
3400 gchar *text = g_strdup_printf(_("_Save Image...")); | |
3401 menu = gtk_menu_new(); | |
3402 | |
3403 /* buttons and such */ | |
3404 img = gtk_image_new_from_stock(GTK_STOCK_SAVE, GTK_ICON_SIZE_MENU); | |
3405 item = gtk_image_menu_item_new_with_mnemonic(text); | |
3406 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), img); | |
5967 | 3407 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(gtk_imhtml_image_save), image); |
5012 | 3408 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); |
3409 | |
3410 gtk_widget_show_all(menu); | |
3411 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, | |
3412 event_button->button, event_button->time); | |
3413 | |
3414 g_free(text); | |
3415 return TRUE; | |
3416 } | |
3417 } | |
3418 if(event->type == GDK_BUTTON_PRESS && event_button->button == 3) | |
3419 return TRUE; /* Clicking the right mouse button on a link shouldn't | |
3420 be caught by the regular GtkTextView menu */ | |
3421 else | |
3422 return FALSE; /* Let clicks go through if we didn't catch anything */ | |
3423 | |
3424 } | |
5967 | 3425 void gtk_imhtml_image_free(GtkIMHtmlScalable *scale) |
3426 { | |
3427 GtkIMHtmlImage *image = (GtkIMHtmlImage *)scale; | |
3428 | |
3429 g_object_unref(image->pixbuf); | |
6982 | 3430 if (image->filename) |
3431 g_free(image->filename); | |
9573 | 3432 if (image->filesel) |
3433 gtk_widget_destroy(image->filesel); | |
5967 | 3434 g_free(scale); |
3435 } | |
3436 | |
3437 void gtk_imhtml_image_add_to(GtkIMHtmlScalable *scale, GtkIMHtml *imhtml, GtkTextIter *iter) | |
3438 { | |
3439 GtkIMHtmlImage *image = (GtkIMHtmlImage *)scale; | |
3440 GtkWidget *box = gtk_event_box_new(); | |
8962 | 3441 char *tag; |
5967 | 3442 GtkTextChildAnchor *anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, iter); |
3443 | |
3444 gtk_container_add(GTK_CONTAINER(box), GTK_WIDGET(image->image)); | |
9229 | 3445 |
3446 if(!gtk_check_version(2, 4, 0)) | |
3447 g_object_set(G_OBJECT(box), "visible-window", FALSE, NULL); | |
5967 | 3448 |
3449 gtk_widget_show(GTK_WIDGET(image->image)); | |
3450 gtk_widget_show(box); | |
3451 | |
8962 | 3452 tag = g_strdup_printf("<IMG ID=\"%d\">", image->id); |
3453 g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_htmltext", tag, g_free); | |
3454 g_object_set_data(G_OBJECT(anchor), "gtkimhtml_plaintext", "[Image]"); | |
3455 | |
5967 | 3456 gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), box, anchor); |
3457 g_signal_connect(G_OBJECT(box), "event", G_CALLBACK(gtk_imhtml_image_clicked), image); | |
3458 } | |
3459 | |
3460 GtkIMHtmlScalable *gtk_imhtml_hr_new() | |
3461 { | |
3462 GtkIMHtmlHr *hr = g_malloc(sizeof(GtkIMHtmlHr)); | |
3463 | |
3464 GTK_IMHTML_SCALABLE(hr)->scale = gtk_imhtml_hr_scale; | |
3465 GTK_IMHTML_SCALABLE(hr)->add_to = gtk_imhtml_hr_add_to; | |
3466 GTK_IMHTML_SCALABLE(hr)->free = gtk_imhtml_hr_free; | |
3467 | |
3468 hr->sep = gtk_hseparator_new(); | |
3469 gtk_widget_set_size_request(hr->sep, 5000, 2); | |
3470 gtk_widget_show(hr->sep); | |
3471 | |
3472 return GTK_IMHTML_SCALABLE(hr); | |
3473 } | |
3474 | |
3475 void gtk_imhtml_hr_scale(GtkIMHtmlScalable *scale, int width, int height) | |
3476 { | |
8588 | 3477 gtk_widget_set_size_request(((GtkIMHtmlHr *)scale)->sep, width - 2, 2); |
5967 | 3478 } |
3479 | |
3480 void gtk_imhtml_hr_add_to(GtkIMHtmlScalable *scale, GtkIMHtml *imhtml, GtkTextIter *iter) | |
3481 { | |
3482 GtkIMHtmlHr *hr = (GtkIMHtmlHr *)scale; | |
3483 GtkTextChildAnchor *anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, iter); | |
8698 | 3484 g_object_set_data(G_OBJECT(anchor), "gtkimhtml_htmltext", "<hr>"); |
3485 g_object_set_data(G_OBJECT(anchor), "gtkimhtml_plaintext", "\n---\n"); | |
5967 | 3486 gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), hr->sep, anchor); |
3487 } | |
3488 | |
3489 void gtk_imhtml_hr_free(GtkIMHtmlScalable *scale) | |
3490 { | |
3491 g_free(scale); | |
3492 } | |
7295 | 3493 |
3494 gboolean gtk_imhtml_search_find(GtkIMHtml *imhtml, const gchar *text) | |
3495 { | |
3496 GtkTextIter iter, start, end; | |
3497 gboolean new_search = TRUE; | |
3498 | |
3499 g_return_val_if_fail(imhtml != NULL, FALSE); | |
3500 g_return_val_if_fail(text != NULL, FALSE); | |
8061 | 3501 |
7295 | 3502 if (imhtml->search_string && !strcmp(text, imhtml->search_string)) |
3503 new_search = FALSE; | |
8061 | 3504 |
7295 | 3505 if (new_search) { |
3506 gtk_imhtml_search_clear(imhtml); | |
3507 gtk_text_buffer_get_start_iter(imhtml->text_buffer, &iter); | |
3508 } else { | |
3509 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, | |
8061 | 3510 gtk_text_buffer_get_mark(imhtml->text_buffer, "search")); |
7295 | 3511 } |
10574 | 3512 g_free(imhtml->search_string); |
7295 | 3513 imhtml->search_string = g_strdup(text); |
3514 | |
7358 | 3515 if (gtk_source_iter_forward_search(&iter, imhtml->search_string, |
3516 GTK_SOURCE_SEARCH_VISIBLE_ONLY | GTK_SOURCE_SEARCH_CASE_INSENSITIVE, | |
7295 | 3517 &start, &end, NULL)) { |
3518 | |
3519 gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(imhtml), &start, 0, TRUE, 0, 0); | |
3520 gtk_text_buffer_create_mark(imhtml->text_buffer, "search", &end, FALSE); | |
3521 if (new_search) { | |
3522 gtk_text_buffer_remove_tag_by_name(imhtml->text_buffer, "search", &iter, &end); | |
8061 | 3523 do |
7295 | 3524 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "search", &start, &end); |
8061 | 3525 while (gtk_source_iter_forward_search(&end, imhtml->search_string, |
3526 GTK_SOURCE_SEARCH_VISIBLE_ONLY | | |
7358 | 3527 GTK_SOURCE_SEARCH_CASE_INSENSITIVE, |
7295 | 3528 &start, &end, NULL)); |
3529 } | |
3530 return TRUE; | |
3531 } | |
8061 | 3532 |
3533 gtk_imhtml_search_clear(imhtml); | |
3534 | |
7295 | 3535 return FALSE; |
3536 } | |
3537 | |
3538 void gtk_imhtml_search_clear(GtkIMHtml *imhtml) | |
3539 { | |
3540 GtkTextIter start, end; | |
8061 | 3541 |
7295 | 3542 g_return_if_fail(imhtml != NULL); |
8061 | 3543 |
7295 | 3544 gtk_text_buffer_get_start_iter(imhtml->text_buffer, &start); |
3545 gtk_text_buffer_get_end_iter(imhtml->text_buffer, &end); | |
3546 | |
3547 gtk_text_buffer_remove_tag_by_name(imhtml->text_buffer, "search", &start, &end); | |
3548 if (imhtml->search_string) | |
3549 g_free(imhtml->search_string); | |
3550 imhtml->search_string = NULL; | |
3551 } | |
8061 | 3552 |
8677 | 3553 static GtkTextTag *find_font_forecolor_tag(GtkIMHtml *imhtml, gchar *color) |
3554 { | |
3555 gchar str[18]; | |
3556 GtkTextTag *tag; | |
3557 | |
3558 g_snprintf(str, sizeof(str), "FORECOLOR %s", color); | |
3559 | |
3560 tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(imhtml->text_buffer), str); | |
10858 | 3561 if (!tag) { |
3562 GdkColor gcolor; | |
3563 if (!gdk_color_parse(color, &gcolor)) { | |
3564 gchar tmp[8]; | |
3565 tmp[0] = '#'; | |
3566 strncpy(&tmp[1], color, 7); | |
3567 tmp[7] = '\0'; | |
3568 if (!gdk_color_parse(tmp, &gcolor)) | |
3569 gdk_color_parse("black", &gcolor); | |
3570 } | |
3571 tag = gtk_text_buffer_create_tag(imhtml->text_buffer, str, "foreground-gdk", &gcolor, NULL); | |
3572 } | |
8677 | 3573 |
3574 return tag; | |
3575 } | |
3576 | |
3577 static GtkTextTag *find_font_backcolor_tag(GtkIMHtml *imhtml, gchar *color) | |
3578 { | |
3579 gchar str[18]; | |
3580 GtkTextTag *tag; | |
3581 | |
3582 g_snprintf(str, sizeof(str), "BACKCOLOR %s", color); | |
3583 | |
3584 tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(imhtml->text_buffer), str); | |
10858 | 3585 if (!tag) { |
3586 GdkColor gcolor; | |
3587 if (!gdk_color_parse(color, &gcolor)) { | |
3588 gchar tmp[8]; | |
3589 tmp[0] = '#'; | |
3590 strncpy(&tmp[1], color, 7); | |
3591 tmp[7] = '\0'; | |
3592 if (!gdk_color_parse(tmp, &gcolor)) | |
3593 gdk_color_parse("white", &gcolor); | |
3594 } | |
3595 tag = gtk_text_buffer_create_tag(imhtml->text_buffer, str, "background-gdk", &gcolor, NULL); | |
3596 } | |
8677 | 3597 |
3598 return tag; | |
3599 } | |
3600 | |
10776 | 3601 static GtkTextTag *find_font_background_tag(GtkIMHtml *imhtml, gchar *color) |
3602 { | |
3603 gchar str[19]; | |
3604 GtkTextTag *tag; | |
3605 | |
3606 g_snprintf(str, sizeof(str), "BACKGROUND %s", color); | |
3607 | |
3608 tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(imhtml->text_buffer), str); | |
3609 if (!tag) | |
3610 tag = gtk_text_buffer_create_tag(imhtml->text_buffer, str, NULL); | |
3611 | |
3612 return tag; | |
3613 } | |
3614 | |
8677 | 3615 static GtkTextTag *find_font_face_tag(GtkIMHtml *imhtml, gchar *face) |
8061 | 3616 { |
8677 | 3617 gchar str[256]; |
3618 GtkTextTag *tag; | |
3619 | |
3620 g_snprintf(str, sizeof(str), "FONT FACE %s", face); | |
3621 str[255] = '\0'; | |
3622 | |
3623 tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(imhtml->text_buffer), str); | |
3624 if (!tag) | |
3625 tag = gtk_text_buffer_create_tag(imhtml->text_buffer, str, "family", face, NULL); | |
3626 | |
3627 return tag; | |
3628 } | |
3629 | |
3630 static GtkTextTag *find_font_size_tag(GtkIMHtml *imhtml, int size) | |
3631 { | |
3632 gchar str[24]; | |
3633 GtkTextTag *tag; | |
3634 | |
3635 g_snprintf(str, sizeof(str), "FONT SIZE %d", size); | |
3636 str[23] = '\0'; | |
3637 | |
3638 tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(imhtml->text_buffer), str); | |
3639 if (!tag) { | |
10525
ddea15f4cbc2
[gaim-migrate @ 11842]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10524
diff
changeset
|
3640 /* For reasons I don't understand, setting "scale" here scaled |
ddea15f4cbc2
[gaim-migrate @ 11842]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10524
diff
changeset
|
3641 * based on some default size other than my theme's default |
ddea15f4cbc2
[gaim-migrate @ 11842]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10524
diff
changeset
|
3642 * size. Our size 4 was actually smaller than our size 3 for |
ddea15f4cbc2
[gaim-migrate @ 11842]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10524
diff
changeset
|
3643 * me. So this works around that oddity. |
8677 | 3644 */ |
10525
ddea15f4cbc2
[gaim-migrate @ 11842]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10524
diff
changeset
|
3645 GtkTextAttributes *attr = gtk_text_view_get_default_attributes(GTK_TEXT_VIEW(imhtml)); |
8677 | 3646 tag = gtk_text_buffer_create_tag(imhtml->text_buffer, str, "size", |
10525
ddea15f4cbc2
[gaim-migrate @ 11842]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10524
diff
changeset
|
3647 (gint) (pango_font_description_get_size(attr->font) * |
10899 | 3648 (double) POINT_SIZE(size)), NULL); |
10525
ddea15f4cbc2
[gaim-migrate @ 11842]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10524
diff
changeset
|
3649 gtk_text_attributes_unref(attr); |
8061 | 3650 } |
3651 | |
8677 | 3652 return tag; |
3653 } | |
3654 | |
3655 static void remove_tag_by_prefix(GtkIMHtml *imhtml, const GtkTextIter *i, const GtkTextIter *e, | |
3656 const char *prefix, guint len, gboolean homo) | |
3657 { | |
3658 GSList *tags, *l; | |
3659 GtkTextIter iter; | |
3660 | |
3661 tags = gtk_text_iter_get_tags(i); | |
3662 | |
3663 for (l = tags; l; l = l->next) { | |
3664 GtkTextTag *tag = l->data; | |
3665 | |
3666 if (tag->name && !strncmp(tag->name, prefix, len)) | |
3667 gtk_text_buffer_remove_tag(imhtml->text_buffer, tag, i, e); | |
8061 | 3668 } |
3669 | |
8677 | 3670 g_slist_free(tags); |
3671 | |
3672 if (homo) | |
3673 return; | |
3674 | |
3675 iter = *i; | |
3676 | |
3677 while (gtk_text_iter_forward_char(&iter) && !gtk_text_iter_equal(&iter, e)) { | |
3678 if (gtk_text_iter_begins_tag(&iter, NULL)) { | |
3679 tags = gtk_text_iter_get_toggled_tags(&iter, TRUE); | |
3680 | |
3681 for (l = tags; l; l = l->next) { | |
3682 GtkTextTag *tag = l->data; | |
3683 | |
3684 if (tag->name && !strncmp(tag->name, prefix, len)) | |
3685 gtk_text_buffer_remove_tag(imhtml->text_buffer, tag, &iter, e); | |
3686 } | |
3687 | |
3688 g_slist_free(tags); | |
3689 } | |
8061 | 3690 } |
8677 | 3691 } |
3692 | |
3693 static void remove_font_size(GtkIMHtml *imhtml, GtkTextIter *i, GtkTextIter *e, gboolean homo) | |
3694 { | |
3695 remove_tag_by_prefix(imhtml, i, e, "FONT SIZE ", 10, homo); | |
3696 } | |
3697 | |
3698 static void remove_font_face(GtkIMHtml *imhtml, GtkTextIter *i, GtkTextIter *e, gboolean homo) | |
3699 { | |
3700 remove_tag_by_prefix(imhtml, i, e, "FONT FACE ", 10, homo); | |
3701 } | |
3702 | |
3703 static void remove_font_forecolor(GtkIMHtml *imhtml, GtkTextIter *i, GtkTextIter *e, gboolean homo) | |
3704 { | |
3705 remove_tag_by_prefix(imhtml, i, e, "FORECOLOR ", 10, homo); | |
3706 } | |
3707 | |
3708 static void remove_font_backcolor(GtkIMHtml *imhtml, GtkTextIter *i, GtkTextIter *e, gboolean homo) | |
3709 { | |
3710 remove_tag_by_prefix(imhtml, i, e, "BACKCOLOR ", 10, homo); | |
3711 } | |
3712 | |
10776 | 3713 static void remove_font_background(GtkIMHtml *imhtml, GtkTextIter *i, GtkTextIter *e, gboolean homo) |
3714 { | |
3715 remove_tag_by_prefix(imhtml, i, e, "BACKGROUND ", 10, homo); | |
3716 } | |
3717 | |
8677 | 3718 static void remove_font_link(GtkIMHtml *imhtml, GtkTextIter *i, GtkTextIter *e, gboolean homo) |
3719 { | |
3720 remove_tag_by_prefix(imhtml, i, e, "LINK ", 5, homo); | |
3721 } | |
3722 | |
12672
4bd7e2ebb4cb
[gaim-migrate @ 15015]
Richard Laager <rlaager@wiktel.com>
parents:
12635
diff
changeset
|
3723 static void |
4bd7e2ebb4cb
[gaim-migrate @ 15015]
Richard Laager <rlaager@wiktel.com>
parents:
12635
diff
changeset
|
3724 imhtml_clear_formatting(GtkIMHtml *imhtml) |
4bd7e2ebb4cb
[gaim-migrate @ 15015]
Richard Laager <rlaager@wiktel.com>
parents:
12635
diff
changeset
|
3725 { |
4bd7e2ebb4cb
[gaim-migrate @ 15015]
Richard Laager <rlaager@wiktel.com>
parents:
12635
diff
changeset
|
3726 GtkTextIter start, end; |
4bd7e2ebb4cb
[gaim-migrate @ 15015]
Richard Laager <rlaager@wiktel.com>
parents:
12635
diff
changeset
|
3727 |
12796
e8db8f94a2db
[gaim-migrate @ 15143]
Richard Laager <rlaager@wiktel.com>
parents:
12673
diff
changeset
|
3728 if (!imhtml->editable) |
e8db8f94a2db
[gaim-migrate @ 15143]
Richard Laager <rlaager@wiktel.com>
parents:
12673
diff
changeset
|
3729 return; |
e8db8f94a2db
[gaim-migrate @ 15143]
Richard Laager <rlaager@wiktel.com>
parents:
12673
diff
changeset
|
3730 |
e8db8f94a2db
[gaim-migrate @ 15143]
Richard Laager <rlaager@wiktel.com>
parents:
12673
diff
changeset
|
3731 if (imhtml->wbfo) |
e8db8f94a2db
[gaim-migrate @ 15143]
Richard Laager <rlaager@wiktel.com>
parents:
12673
diff
changeset
|
3732 gtk_text_buffer_get_bounds(imhtml->text_buffer, &start, &end); |
e8db8f94a2db
[gaim-migrate @ 15143]
Richard Laager <rlaager@wiktel.com>
parents:
12673
diff
changeset
|
3733 else |
e8db8f94a2db
[gaim-migrate @ 15143]
Richard Laager <rlaager@wiktel.com>
parents:
12673
diff
changeset
|
3734 if (!gtk_text_buffer_get_selection_bounds(imhtml->text_buffer, &start, &end)) |
e8db8f94a2db
[gaim-migrate @ 15143]
Richard Laager <rlaager@wiktel.com>
parents:
12673
diff
changeset
|
3735 gtk_text_buffer_get_bounds(imhtml->text_buffer, &start, &end); |
12672
4bd7e2ebb4cb
[gaim-migrate @ 15015]
Richard Laager <rlaager@wiktel.com>
parents:
12635
diff
changeset
|
3736 |
4bd7e2ebb4cb
[gaim-migrate @ 15015]
Richard Laager <rlaager@wiktel.com>
parents:
12635
diff
changeset
|
3737 gtk_text_buffer_remove_tag_by_name(imhtml->text_buffer, "BOLD", &start, &end); |
4bd7e2ebb4cb
[gaim-migrate @ 15015]
Richard Laager <rlaager@wiktel.com>
parents:
12635
diff
changeset
|
3738 gtk_text_buffer_remove_tag_by_name(imhtml->text_buffer, "ITALICS", &start, &end); |
4bd7e2ebb4cb
[gaim-migrate @ 15015]
Richard Laager <rlaager@wiktel.com>
parents:
12635
diff
changeset
|
3739 gtk_text_buffer_remove_tag_by_name(imhtml->text_buffer, "UNDERLINE", &start, &end); |
4bd7e2ebb4cb
[gaim-migrate @ 15015]
Richard Laager <rlaager@wiktel.com>
parents:
12635
diff
changeset
|
3740 gtk_text_buffer_remove_tag_by_name(imhtml->text_buffer, "STRIKE", &start, &end); |
4bd7e2ebb4cb
[gaim-migrate @ 15015]
Richard Laager <rlaager@wiktel.com>
parents:
12635
diff
changeset
|
3741 remove_font_size(imhtml, &start, &end, TRUE); |
4bd7e2ebb4cb
[gaim-migrate @ 15015]
Richard Laager <rlaager@wiktel.com>
parents:
12635
diff
changeset
|
3742 remove_font_face(imhtml, &start, &end, TRUE); |
4bd7e2ebb4cb
[gaim-migrate @ 15015]
Richard Laager <rlaager@wiktel.com>
parents:
12635
diff
changeset
|
3743 remove_font_forecolor(imhtml, &start, &end, TRUE); |
4bd7e2ebb4cb
[gaim-migrate @ 15015]
Richard Laager <rlaager@wiktel.com>
parents:
12635
diff
changeset
|
3744 remove_font_backcolor(imhtml, &start, &end, TRUE); |
4bd7e2ebb4cb
[gaim-migrate @ 15015]
Richard Laager <rlaager@wiktel.com>
parents:
12635
diff
changeset
|
3745 remove_font_background(imhtml, &start, &end, TRUE); |
4bd7e2ebb4cb
[gaim-migrate @ 15015]
Richard Laager <rlaager@wiktel.com>
parents:
12635
diff
changeset
|
3746 remove_font_link(imhtml, &start, &end, TRUE); |
4bd7e2ebb4cb
[gaim-migrate @ 15015]
Richard Laager <rlaager@wiktel.com>
parents:
12635
diff
changeset
|
3747 |
4bd7e2ebb4cb
[gaim-migrate @ 15015]
Richard Laager <rlaager@wiktel.com>
parents:
12635
diff
changeset
|
3748 imhtml->edit.bold = 0; |
4bd7e2ebb4cb
[gaim-migrate @ 15015]
Richard Laager <rlaager@wiktel.com>
parents:
12635
diff
changeset
|
3749 imhtml->edit.italic = 0; |
4bd7e2ebb4cb
[gaim-migrate @ 15015]
Richard Laager <rlaager@wiktel.com>
parents:
12635
diff
changeset
|
3750 imhtml->edit.underline = 0; |
4bd7e2ebb4cb
[gaim-migrate @ 15015]
Richard Laager <rlaager@wiktel.com>
parents:
12635
diff
changeset
|
3751 imhtml->edit.strike = 0; |
4bd7e2ebb4cb
[gaim-migrate @ 15015]
Richard Laager <rlaager@wiktel.com>
parents:
12635
diff
changeset
|
3752 imhtml->edit.fontsize = 0; |
4bd7e2ebb4cb
[gaim-migrate @ 15015]
Richard Laager <rlaager@wiktel.com>
parents:
12635
diff
changeset
|
3753 imhtml->edit.forecolor = NULL; |
4bd7e2ebb4cb
[gaim-migrate @ 15015]
Richard Laager <rlaager@wiktel.com>
parents:
12635
diff
changeset
|
3754 imhtml->edit.backcolor = NULL; |
4bd7e2ebb4cb
[gaim-migrate @ 15015]
Richard Laager <rlaager@wiktel.com>
parents:
12635
diff
changeset
|
3755 imhtml->edit.background = NULL; |
4bd7e2ebb4cb
[gaim-migrate @ 15015]
Richard Laager <rlaager@wiktel.com>
parents:
12635
diff
changeset
|
3756 } |
4bd7e2ebb4cb
[gaim-migrate @ 15015]
Richard Laager <rlaager@wiktel.com>
parents:
12635
diff
changeset
|
3757 |
8677 | 3758 /* Editable stuff */ |
3759 static void preinsert_cb(GtkTextBuffer *buffer, GtkTextIter *iter, gchar *text, gint len, GtkIMHtml *imhtml) | |
3760 { | |
3761 imhtml->insert_offset = gtk_text_iter_get_offset(iter); | |
3762 } | |
3763 | |
10169 | 3764 static void insert_ca_cb(GtkTextBuffer *buffer, GtkTextIter *arg1, GtkTextChildAnchor *arg2, gpointer user_data) |
3765 { | |
3766 GtkTextIter start; | |
3767 | |
3768 start = *arg1; | |
3769 gtk_text_iter_backward_char(&start); | |
3770 | |
3771 gtk_imhtml_apply_tags_on_insert(user_data, &start, arg1); | |
3772 } | |
3773 | |
8677 | 3774 static void insert_cb(GtkTextBuffer *buffer, GtkTextIter *end, gchar *text, gint len, GtkIMHtml *imhtml) |
3775 { | |
3776 GtkTextIter start; | |
3777 | |
3778 if (!len) | |
3779 return; | |
3780 | |
3781 start = *end; | |
3782 gtk_text_iter_set_offset(&start, imhtml->insert_offset); | |
3783 | |
10169 | 3784 gtk_imhtml_apply_tags_on_insert(imhtml, &start, end); |
3785 } | |
3786 | |
12673
de93d4988ad4
[gaim-migrate @ 15016]
Richard Laager <rlaager@wiktel.com>
parents:
12672
diff
changeset
|
3787 static void delete_cb(GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, GtkIMHtml *imhtml) |
de93d4988ad4
[gaim-migrate @ 15016]
Richard Laager <rlaager@wiktel.com>
parents:
12672
diff
changeset
|
3788 { |
de93d4988ad4
[gaim-migrate @ 15016]
Richard Laager <rlaager@wiktel.com>
parents:
12672
diff
changeset
|
3789 GSList *tags, *l; |
de93d4988ad4
[gaim-migrate @ 15016]
Richard Laager <rlaager@wiktel.com>
parents:
12672
diff
changeset
|
3790 |
de93d4988ad4
[gaim-migrate @ 15016]
Richard Laager <rlaager@wiktel.com>
parents:
12672
diff
changeset
|
3791 tags = gtk_text_iter_get_tags(start); |
de93d4988ad4
[gaim-migrate @ 15016]
Richard Laager <rlaager@wiktel.com>
parents:
12672
diff
changeset
|
3792 for (l = tags; l != NULL; l = l->next) { |
de93d4988ad4
[gaim-migrate @ 15016]
Richard Laager <rlaager@wiktel.com>
parents:
12672
diff
changeset
|
3793 GtkTextTag *tag = GTK_TEXT_TAG(l->data); |
de93d4988ad4
[gaim-migrate @ 15016]
Richard Laager <rlaager@wiktel.com>
parents:
12672
diff
changeset
|
3794 |
de93d4988ad4
[gaim-migrate @ 15016]
Richard Laager <rlaager@wiktel.com>
parents:
12672
diff
changeset
|
3795 if (tag && /* Remove the formatting only if */ |
de93d4988ad4
[gaim-migrate @ 15016]
Richard Laager <rlaager@wiktel.com>
parents:
12672
diff
changeset
|
3796 gtk_text_iter_starts_word(start) && /* beginning of a word */ |
de93d4988ad4
[gaim-migrate @ 15016]
Richard Laager <rlaager@wiktel.com>
parents:
12672
diff
changeset
|
3797 gtk_text_iter_begins_tag(start, tag) && /* the tag starts with the selection */ |
de93d4988ad4
[gaim-migrate @ 15016]
Richard Laager <rlaager@wiktel.com>
parents:
12672
diff
changeset
|
3798 (!gtk_text_iter_has_tag(end, tag) || /* the tag ends within the selection */ |
de93d4988ad4
[gaim-migrate @ 15016]
Richard Laager <rlaager@wiktel.com>
parents:
12672
diff
changeset
|
3799 gtk_text_iter_ends_tag(end, tag))) { |
de93d4988ad4
[gaim-migrate @ 15016]
Richard Laager <rlaager@wiktel.com>
parents:
12672
diff
changeset
|
3800 gtk_text_buffer_remove_tag(imhtml->text_buffer, tag, start, end); |
de93d4988ad4
[gaim-migrate @ 15016]
Richard Laager <rlaager@wiktel.com>
parents:
12672
diff
changeset
|
3801 if (tag->name && |
de93d4988ad4
[gaim-migrate @ 15016]
Richard Laager <rlaager@wiktel.com>
parents:
12672
diff
changeset
|
3802 strncmp(tag->name, "LINK ", 5) == 0 && imhtml->edit.link) { |
de93d4988ad4
[gaim-migrate @ 15016]
Richard Laager <rlaager@wiktel.com>
parents:
12672
diff
changeset
|
3803 gtk_imhtml_toggle_link(imhtml, NULL); |
de93d4988ad4
[gaim-migrate @ 15016]
Richard Laager <rlaager@wiktel.com>
parents:
12672
diff
changeset
|
3804 } |
de93d4988ad4
[gaim-migrate @ 15016]
Richard Laager <rlaager@wiktel.com>
parents:
12672
diff
changeset
|
3805 } |
de93d4988ad4
[gaim-migrate @ 15016]
Richard Laager <rlaager@wiktel.com>
parents:
12672
diff
changeset
|
3806 } |
de93d4988ad4
[gaim-migrate @ 15016]
Richard Laager <rlaager@wiktel.com>
parents:
12672
diff
changeset
|
3807 g_slist_free(tags); |
de93d4988ad4
[gaim-migrate @ 15016]
Richard Laager <rlaager@wiktel.com>
parents:
12672
diff
changeset
|
3808 } |
de93d4988ad4
[gaim-migrate @ 15016]
Richard Laager <rlaager@wiktel.com>
parents:
12672
diff
changeset
|
3809 |
10169 | 3810 static void gtk_imhtml_apply_tags_on_insert(GtkIMHtml *imhtml, GtkTextIter *start, GtkTextIter *end) |
3811 { | |
8677 | 3812 if (imhtml->edit.bold) |
10169 | 3813 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "BOLD", start, end); |
8677 | 3814 else |
10169 | 3815 gtk_text_buffer_remove_tag_by_name(imhtml->text_buffer, "BOLD", start, end); |
8677 | 3816 |
3817 if (imhtml->edit.italic) | |
10169 | 3818 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "ITALICS", start, end); |
8677 | 3819 else |
10169 | 3820 gtk_text_buffer_remove_tag_by_name(imhtml->text_buffer, "ITALICS", start, end); |
8677 | 3821 |
3822 if (imhtml->edit.underline) | |
10169 | 3823 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "UNDERLINE", start, end); |
8677 | 3824 else |
10169 | 3825 gtk_text_buffer_remove_tag_by_name(imhtml->text_buffer, "UNDERLINE", start, end); |
8677 | 3826 |
9924 | 3827 if (imhtml->edit.strike) |
10169 | 3828 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "STRIKE", start, end); |
9924 | 3829 else |
10169 | 3830 gtk_text_buffer_remove_tag_by_name(imhtml->text_buffer, "STRIKE", start, end); |
9924 | 3831 |
8677 | 3832 if (imhtml->edit.forecolor) { |
10169 | 3833 remove_font_forecolor(imhtml, start, end, TRUE); |
8677 | 3834 gtk_text_buffer_apply_tag(imhtml->text_buffer, |
3835 find_font_forecolor_tag(imhtml, imhtml->edit.forecolor), | |
10169 | 3836 start, end); |
8061 | 3837 } |
3838 | |
8677 | 3839 if (imhtml->edit.backcolor) { |
10169 | 3840 remove_font_backcolor(imhtml, start, end, TRUE); |
8677 | 3841 gtk_text_buffer_apply_tag(imhtml->text_buffer, |
3842 find_font_backcolor_tag(imhtml, imhtml->edit.backcolor), | |
10169 | 3843 start, end); |
8677 | 3844 } |
3845 | |
10776 | 3846 if (imhtml->edit.background) { |
3847 remove_font_background(imhtml, start, end, TRUE); | |
3848 gtk_text_buffer_apply_tag(imhtml->text_buffer, | |
3849 find_font_background_tag(imhtml, imhtml->edit.background), | |
3850 start, end); | |
3851 } | |
8677 | 3852 if (imhtml->edit.fontface) { |
10169 | 3853 remove_font_face(imhtml, start, end, TRUE); |
8677 | 3854 gtk_text_buffer_apply_tag(imhtml->text_buffer, |
3855 find_font_face_tag(imhtml, imhtml->edit.fontface), | |
10169 | 3856 start, end); |
8061 | 3857 } |
8677 | 3858 |
3859 if (imhtml->edit.fontsize) { | |
10169 | 3860 remove_font_size(imhtml, start, end, TRUE); |
8677 | 3861 gtk_text_buffer_apply_tag(imhtml->text_buffer, |
3862 find_font_size_tag(imhtml, imhtml->edit.fontsize), | |
10169 | 3863 start, end); |
8677 | 3864 } |
3865 | |
3866 if (imhtml->edit.link) { | |
10169 | 3867 remove_font_link(imhtml, start, end, TRUE); |
8677 | 3868 gtk_text_buffer_apply_tag(imhtml->text_buffer, |
3869 imhtml->edit.link, | |
10169 | 3870 start, end); |
8677 | 3871 } |
8061 | 3872 } |
3873 | |
3874 void gtk_imhtml_set_editable(GtkIMHtml *imhtml, gboolean editable) | |
3875 { | |
3876 gtk_text_view_set_editable(GTK_TEXT_VIEW(imhtml), editable); | |
8177 | 3877 /* |
3878 * We need a visible caret for accessibility, so mouseless | |
3879 * people can highlight stuff. | |
3880 */ | |
3881 /* gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(imhtml), editable); */ | |
8061 | 3882 imhtml->editable = editable; |
8677 | 3883 imhtml->format_functions = GTK_IMHTML_ALL; |
3884 | |
3885 if (editable) | |
3886 g_signal_connect_after(G_OBJECT(GTK_IMHTML(imhtml)->text_buffer), "mark-set", | |
3887 G_CALLBACK(mark_set_cb), imhtml); | |
3888 } | |
3889 | |
3890 void gtk_imhtml_set_whole_buffer_formatting_only(GtkIMHtml *imhtml, gboolean wbfo) | |
3891 { | |
3892 g_return_if_fail(imhtml != NULL); | |
3893 | |
3894 imhtml->wbfo = wbfo; | |
8420 | 3895 } |
3896 | |
3897 void gtk_imhtml_set_format_functions(GtkIMHtml *imhtml, GtkIMHtmlButtons buttons) | |
3898 { | |
3899 GObject *object = g_object_ref(G_OBJECT(imhtml)); | |
8677 | 3900 imhtml->format_functions = buttons; |
8420 | 3901 g_signal_emit(object, signals[BUTTONS_UPDATE], 0, buttons); |
3902 g_object_unref(object); | |
8061 | 3903 } |
3904 | |
8788 | 3905 GtkIMHtmlButtons gtk_imhtml_get_format_functions(GtkIMHtml *imhtml) |
3906 { | |
3907 return imhtml->format_functions; | |
3908 } | |
8516 | 3909 |
3910 void gtk_imhtml_get_current_format(GtkIMHtml *imhtml, gboolean *bold, | |
3911 gboolean *italic, gboolean *underline) | |
8481 | 3912 { |
12900
778d08e87ad0
[gaim-migrate @ 15253]
Richard Laager <rlaager@wiktel.com>
parents:
12836
diff
changeset
|
3913 if (bold != NULL) |
778d08e87ad0
[gaim-migrate @ 15253]
Richard Laager <rlaager@wiktel.com>
parents:
12836
diff
changeset
|
3914 (*bold) = imhtml->edit.bold; |
778d08e87ad0
[gaim-migrate @ 15253]
Richard Laager <rlaager@wiktel.com>
parents:
12836
diff
changeset
|
3915 if (italic != NULL) |
778d08e87ad0
[gaim-migrate @ 15253]
Richard Laager <rlaager@wiktel.com>
parents:
12836
diff
changeset
|
3916 (*italic) = imhtml->edit.italic; |
778d08e87ad0
[gaim-migrate @ 15253]
Richard Laager <rlaager@wiktel.com>
parents:
12836
diff
changeset
|
3917 if (underline != NULL) |
778d08e87ad0
[gaim-migrate @ 15253]
Richard Laager <rlaager@wiktel.com>
parents:
12836
diff
changeset
|
3918 (*underline) = imhtml->edit.underline; |
8481 | 3919 } |
3920 | |
9025 | 3921 char * |
3922 gtk_imhtml_get_current_fontface(GtkIMHtml *imhtml) | |
3923 { | |
3924 if (imhtml->edit.fontface) | |
3925 return g_strdup(imhtml->edit.fontface); | |
3926 else | |
3927 return NULL; | |
3928 } | |
3929 | |
3930 char * | |
3931 gtk_imhtml_get_current_forecolor(GtkIMHtml *imhtml) | |
3932 { | |
3933 if (imhtml->edit.forecolor) | |
3934 return g_strdup(imhtml->edit.forecolor); | |
3935 else | |
3936 return NULL; | |
3937 } | |
3938 | |
3939 char * | |
3940 gtk_imhtml_get_current_backcolor(GtkIMHtml *imhtml) | |
3941 { | |
3942 if (imhtml->edit.backcolor) | |
3943 return g_strdup(imhtml->edit.backcolor); | |
3944 else | |
3945 return NULL; | |
3946 } | |
3947 | |
11267
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
3948 char * |
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
3949 gtk_imhtml_get_current_background(GtkIMHtml *imhtml) |
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
3950 { |
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
3951 if (imhtml->edit.background) |
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
3952 return g_strdup(imhtml->edit.background); |
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
3953 else |
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
3954 return NULL; |
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
3955 } |
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
3956 |
9025 | 3957 gint |
3958 gtk_imhtml_get_current_fontsize(GtkIMHtml *imhtml) | |
3959 { | |
3960 return imhtml->edit.fontsize; | |
3961 } | |
3962 | |
8061 | 3963 gboolean gtk_imhtml_get_editable(GtkIMHtml *imhtml) |
3964 { | |
3965 return imhtml->editable; | |
3966 } | |
3967 | |
11269
1cbe76d30e81
[gaim-migrate @ 13451]
Richard Laager <rlaager@wiktel.com>
parents:
11267
diff
changeset
|
3968 void |
1cbe76d30e81
[gaim-migrate @ 13451]
Richard Laager <rlaager@wiktel.com>
parents:
11267
diff
changeset
|
3969 gtk_imhtml_clear_formatting(GtkIMHtml *imhtml) |
1cbe76d30e81
[gaim-migrate @ 13451]
Richard Laager <rlaager@wiktel.com>
parents:
11267
diff
changeset
|
3970 { |
11275
ffc86d9ad8b7
[gaim-migrate @ 13461]
Richard Laager <rlaager@wiktel.com>
parents:
11269
diff
changeset
|
3971 GObject *object; |
ffc86d9ad8b7
[gaim-migrate @ 13461]
Richard Laager <rlaager@wiktel.com>
parents:
11269
diff
changeset
|
3972 |
ffc86d9ad8b7
[gaim-migrate @ 13461]
Richard Laager <rlaager@wiktel.com>
parents:
11269
diff
changeset
|
3973 object = g_object_ref(G_OBJECT(imhtml)); |
ffc86d9ad8b7
[gaim-migrate @ 13461]
Richard Laager <rlaager@wiktel.com>
parents:
11269
diff
changeset
|
3974 g_signal_emit(object, signals[CLEAR_FORMAT], 0); |
11276
17ebda61c6ce
[gaim-migrate @ 13463]
Richard Laager <rlaager@wiktel.com>
parents:
11275
diff
changeset
|
3975 |
11269
1cbe76d30e81
[gaim-migrate @ 13451]
Richard Laager <rlaager@wiktel.com>
parents:
11267
diff
changeset
|
3976 gtk_widget_grab_focus(GTK_WIDGET(imhtml)); |
11276
17ebda61c6ce
[gaim-migrate @ 13463]
Richard Laager <rlaager@wiktel.com>
parents:
11275
diff
changeset
|
3977 |
17ebda61c6ce
[gaim-migrate @ 13463]
Richard Laager <rlaager@wiktel.com>
parents:
11275
diff
changeset
|
3978 g_object_unref(object); |
11269
1cbe76d30e81
[gaim-migrate @ 13451]
Richard Laager <rlaager@wiktel.com>
parents:
11267
diff
changeset
|
3979 } |
1cbe76d30e81
[gaim-migrate @ 13451]
Richard Laager <rlaager@wiktel.com>
parents:
11267
diff
changeset
|
3980 |
8677 | 3981 /* |
3982 * I had this crazy idea about changing the text cursor color to reflex the foreground color | |
3983 * of the text about to be entered. This is the place you'd do it, along with the place where | |
3984 * we actually set a new foreground color. | |
3985 * I may not do this, because people will bitch about Gaim overriding their gtk theme's cursor | |
3986 * colors. | |
3987 * | |
3988 * Just in case I do do this, I asked about what to set the secondary text cursor to. | |
3989 * | |
8719 | 3990 * (12:45:27) ?? ???: secondary_cursor_color = (rgb(background) + rgb(primary_cursor_color) ) / 2 |
3991 * (12:45:55) ?? ???: understand? | |
8677 | 3992 * (12:46:14) Tim: yeah. i didn't know there was an exact formula |
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8729
diff
changeset
|
3993 * (12:46:56) ?? ???: u might need to extract separate each color from RGB |
8677 | 3994 */ |
3995 | |
3996 static void mark_set_cb(GtkTextBuffer *buffer, GtkTextIter *arg1, GtkTextMark *mark, | |
3997 GtkIMHtml *imhtml) | |
3998 { | |
3999 GSList *tags, *l; | |
4000 GtkTextIter iter; | |
4001 | |
4002 if (mark != gtk_text_buffer_get_insert(buffer)) | |
4003 return; | |
4004 | |
4005 if (!gtk_text_buffer_get_char_count(buffer)) | |
4006 return; | |
4007 | |
9924 | 4008 imhtml->edit.bold = imhtml->edit.italic = imhtml->edit.underline = imhtml->edit.strike = FALSE; |
8677 | 4009 if (imhtml->edit.forecolor) |
4010 g_free(imhtml->edit.forecolor); | |
4011 imhtml->edit.forecolor = NULL; | |
4012 if (imhtml->edit.backcolor) | |
4013 g_free(imhtml->edit.backcolor); | |
4014 imhtml->edit.backcolor = NULL; | |
4015 if (imhtml->edit.fontface) | |
4016 g_free(imhtml->edit.fontface); | |
4017 imhtml->edit.fontface = NULL; | |
4018 imhtml->edit.fontsize = 0; | |
4019 imhtml->edit.link = NULL; | |
4020 | |
4021 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, mark); | |
4022 | |
4023 | |
4024 if (gtk_text_iter_is_end(&iter)) | |
4025 tags = gtk_text_iter_get_toggled_tags(&iter, FALSE); | |
4026 else | |
4027 tags = gtk_text_iter_get_tags(&iter); | |
4028 | |
4029 for (l = tags; l != NULL; l = l->next) { | |
4030 GtkTextTag *tag = GTK_TEXT_TAG(l->data); | |
4031 | |
4032 if (tag->name) { | |
4033 if (strcmp(tag->name, "BOLD") == 0) | |
4034 imhtml->edit.bold = TRUE; | |
13137
1ed228c65e89
[gaim-migrate @ 15499]
Richard Laager <rlaager@wiktel.com>
parents:
13136
diff
changeset
|
4035 else if (strcmp(tag->name, "ITALICS") == 0) |
8677 | 4036 imhtml->edit.italic = TRUE; |
13137
1ed228c65e89
[gaim-migrate @ 15499]
Richard Laager <rlaager@wiktel.com>
parents:
13136
diff
changeset
|
4037 else if (strcmp(tag->name, "UNDERLINE") == 0) |
8677 | 4038 imhtml->edit.underline = TRUE; |
13137
1ed228c65e89
[gaim-migrate @ 15499]
Richard Laager <rlaager@wiktel.com>
parents:
13136
diff
changeset
|
4039 else if (strcmp(tag->name, "STRIKE") == 0) |
9924 | 4040 imhtml->edit.strike = TRUE; |
13137
1ed228c65e89
[gaim-migrate @ 15499]
Richard Laager <rlaager@wiktel.com>
parents:
13136
diff
changeset
|
4041 else if (strncmp(tag->name, "FORECOLOR ", 10) == 0) |
8677 | 4042 imhtml->edit.forecolor = g_strdup(&(tag->name)[10]); |
13137
1ed228c65e89
[gaim-migrate @ 15499]
Richard Laager <rlaager@wiktel.com>
parents:
13136
diff
changeset
|
4043 else if (strncmp(tag->name, "BACKCOLOR ", 10) == 0) |
8677 | 4044 imhtml->edit.backcolor = g_strdup(&(tag->name)[10]); |
13137
1ed228c65e89
[gaim-migrate @ 15499]
Richard Laager <rlaager@wiktel.com>
parents:
13136
diff
changeset
|
4045 else if (strncmp(tag->name, "FONT FACE ", 10) == 0) |
8677 | 4046 imhtml->edit.fontface = g_strdup(&(tag->name)[10]); |
13137
1ed228c65e89
[gaim-migrate @ 15499]
Richard Laager <rlaager@wiktel.com>
parents:
13136
diff
changeset
|
4047 else if (strncmp(tag->name, "FONT SIZE ", 10) == 0) |
8677 | 4048 imhtml->edit.fontsize = strtol(&(tag->name)[10], NULL, 10); |
13137
1ed228c65e89
[gaim-migrate @ 15499]
Richard Laager <rlaager@wiktel.com>
parents:
13136
diff
changeset
|
4049 else if ((strncmp(tag->name, "LINK ", 5) == 0) && !gtk_text_iter_is_end(&iter)) |
8677 | 4050 imhtml->edit.link = tag; |
4051 } | |
4052 } | |
4053 | |
4054 g_slist_free(tags); | |
4055 } | |
4056 | |
12605
cd1d0131e07f
[gaim-migrate @ 14940]
Richard Laager <rlaager@wiktel.com>
parents:
12600
diff
changeset
|
4057 static void imhtml_emit_signal_for_format(GtkIMHtml *imhtml, GtkIMHtmlButtons button) |
cd1d0131e07f
[gaim-migrate @ 14940]
Richard Laager <rlaager@wiktel.com>
parents:
12600
diff
changeset
|
4058 { |
cd1d0131e07f
[gaim-migrate @ 14940]
Richard Laager <rlaager@wiktel.com>
parents:
12600
diff
changeset
|
4059 GObject *object; |
cd1d0131e07f
[gaim-migrate @ 14940]
Richard Laager <rlaager@wiktel.com>
parents:
12600
diff
changeset
|
4060 |
cd1d0131e07f
[gaim-migrate @ 14940]
Richard Laager <rlaager@wiktel.com>
parents:
12600
diff
changeset
|
4061 g_return_if_fail(imhtml != NULL); |
cd1d0131e07f
[gaim-migrate @ 14940]
Richard Laager <rlaager@wiktel.com>
parents:
12600
diff
changeset
|
4062 |
cd1d0131e07f
[gaim-migrate @ 14940]
Richard Laager <rlaager@wiktel.com>
parents:
12600
diff
changeset
|
4063 object = g_object_ref(G_OBJECT(imhtml)); |
cd1d0131e07f
[gaim-migrate @ 14940]
Richard Laager <rlaager@wiktel.com>
parents:
12600
diff
changeset
|
4064 g_signal_emit(object, signals[TOGGLE_FORMAT], 0, button); |
cd1d0131e07f
[gaim-migrate @ 14940]
Richard Laager <rlaager@wiktel.com>
parents:
12600
diff
changeset
|
4065 g_object_unref(object); |
cd1d0131e07f
[gaim-migrate @ 14940]
Richard Laager <rlaager@wiktel.com>
parents:
12600
diff
changeset
|
4066 } |
cd1d0131e07f
[gaim-migrate @ 14940]
Richard Laager <rlaager@wiktel.com>
parents:
12600
diff
changeset
|
4067 |
11267
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4068 static void imhtml_toggle_bold(GtkIMHtml *imhtml) |
8061 | 4069 { |
8677 | 4070 GtkTextIter start, end; |
4071 | |
4072 imhtml->edit.bold = !imhtml->edit.bold; | |
4073 | |
4074 if (imhtml->wbfo) { | |
4075 gtk_text_buffer_get_bounds(imhtml->text_buffer, &start, &end); | |
4076 if (imhtml->edit.bold) | |
4077 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "BOLD", &start, &end); | |
4078 else | |
4079 gtk_text_buffer_remove_tag_by_name(imhtml->text_buffer, "BOLD", &start, &end); | |
11276
17ebda61c6ce
[gaim-migrate @ 13463]
Richard Laager <rlaager@wiktel.com>
parents:
11275
diff
changeset
|
4080 } else if (imhtml->editable && gtk_text_buffer_get_selection_bounds(imhtml->text_buffer, &start, &end)) { |
8677 | 4081 if (imhtml->edit.bold) |
4082 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "BOLD", &start, &end); | |
4083 else | |
4084 gtk_text_buffer_remove_tag_by_name(imhtml->text_buffer, "BOLD", &start, &end); | |
11276
17ebda61c6ce
[gaim-migrate @ 13463]
Richard Laager <rlaager@wiktel.com>
parents:
11275
diff
changeset
|
4085 |
8061 | 4086 } |
4087 } | |
4088 | |
11267
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4089 void gtk_imhtml_toggle_bold(GtkIMHtml *imhtml) |
8061 | 4090 { |
12605
cd1d0131e07f
[gaim-migrate @ 14940]
Richard Laager <rlaager@wiktel.com>
parents:
12600
diff
changeset
|
4091 imhtml_emit_signal_for_format(imhtml, GTK_IMHTML_BOLD); |
11267
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4092 } |
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4093 |
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4094 static void imhtml_toggle_italic(GtkIMHtml *imhtml) |
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4095 { |
8677 | 4096 GtkTextIter start, end; |
4097 | |
4098 imhtml->edit.italic = !imhtml->edit.italic; | |
4099 | |
4100 if (imhtml->wbfo) { | |
4101 gtk_text_buffer_get_bounds(imhtml->text_buffer, &start, &end); | |
4102 if (imhtml->edit.italic) | |
4103 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "ITALICS", &start, &end); | |
4104 else | |
4105 gtk_text_buffer_remove_tag_by_name(imhtml->text_buffer, "ITALICS", &start, &end); | |
11276
17ebda61c6ce
[gaim-migrate @ 13463]
Richard Laager <rlaager@wiktel.com>
parents:
11275
diff
changeset
|
4106 } else if (imhtml->editable && gtk_text_buffer_get_selection_bounds(imhtml->text_buffer, &start, &end)) { |
17ebda61c6ce
[gaim-migrate @ 13463]
Richard Laager <rlaager@wiktel.com>
parents:
11275
diff
changeset
|
4107 if (imhtml->edit.italic) |
8677 | 4108 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "ITALICS", &start, &end); |
4109 else | |
4110 gtk_text_buffer_remove_tag_by_name(imhtml->text_buffer, "ITALICS", &start, &end); | |
8061 | 4111 } |
4112 } | |
4113 | |
11267
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4114 void gtk_imhtml_toggle_italic(GtkIMHtml *imhtml) |
8061 | 4115 { |
12605
cd1d0131e07f
[gaim-migrate @ 14940]
Richard Laager <rlaager@wiktel.com>
parents:
12600
diff
changeset
|
4116 imhtml_emit_signal_for_format(imhtml, GTK_IMHTML_ITALIC); |
cd1d0131e07f
[gaim-migrate @ 14940]
Richard Laager <rlaager@wiktel.com>
parents:
12600
diff
changeset
|
4117 } |
11267
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4118 |
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4119 static void imhtml_toggle_underline(GtkIMHtml *imhtml) |
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4120 { |
8677 | 4121 GtkTextIter start, end; |
4122 | |
4123 imhtml->edit.underline = !imhtml->edit.underline; | |
4124 | |
4125 if (imhtml->wbfo) { | |
4126 gtk_text_buffer_get_bounds(imhtml->text_buffer, &start, &end); | |
4127 if (imhtml->edit.underline) | |
4128 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "UNDERLINE", &start, &end); | |
4129 else | |
4130 gtk_text_buffer_remove_tag_by_name(imhtml->text_buffer, "UNDERLINE", &start, &end); | |
11276
17ebda61c6ce
[gaim-migrate @ 13463]
Richard Laager <rlaager@wiktel.com>
parents:
11275
diff
changeset
|
4131 } else if (imhtml->editable && gtk_text_buffer_get_selection_bounds(imhtml->text_buffer, &start, &end)) { |
17ebda61c6ce
[gaim-migrate @ 13463]
Richard Laager <rlaager@wiktel.com>
parents:
11275
diff
changeset
|
4132 if (imhtml->edit.underline) |
8677 | 4133 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "UNDERLINE", &start, &end); |
4134 else | |
4135 gtk_text_buffer_remove_tag_by_name(imhtml->text_buffer, "UNDERLINE", &start, &end); | |
8061 | 4136 } |
4137 } | |
4138 | |
11267
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4139 void gtk_imhtml_toggle_underline(GtkIMHtml *imhtml) |
9924 | 4140 { |
12605
cd1d0131e07f
[gaim-migrate @ 14940]
Richard Laager <rlaager@wiktel.com>
parents:
12600
diff
changeset
|
4141 imhtml_emit_signal_for_format(imhtml, GTK_IMHTML_UNDERLINE); |
11267
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4142 } |
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4143 |
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4144 static void imhtml_toggle_strike(GtkIMHtml *imhtml) |
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4145 { |
9924 | 4146 GtkTextIter start, end; |
4147 | |
4148 imhtml->edit.strike = !imhtml->edit.strike; | |
4149 | |
4150 if (imhtml->wbfo) { | |
4151 gtk_text_buffer_get_bounds(imhtml->text_buffer, &start, &end); | |
4152 if (imhtml->edit.strike) | |
4153 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "STRIKE", &start, &end); | |
4154 else | |
4155 gtk_text_buffer_remove_tag_by_name(imhtml->text_buffer, "STRIKE", &start, &end); | |
11276
17ebda61c6ce
[gaim-migrate @ 13463]
Richard Laager <rlaager@wiktel.com>
parents:
11275
diff
changeset
|
4156 } else if (imhtml->editable && gtk_text_buffer_get_selection_bounds(imhtml->text_buffer, &start, &end)) { |
17ebda61c6ce
[gaim-migrate @ 13463]
Richard Laager <rlaager@wiktel.com>
parents:
11275
diff
changeset
|
4157 if (imhtml->edit.strike) |
9924 | 4158 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "STRIKE", &start, &end); |
4159 else | |
4160 gtk_text_buffer_remove_tag_by_name(imhtml->text_buffer, "STRIKE", &start, &end); | |
4161 } | |
11267
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4162 } |
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4163 |
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4164 void gtk_imhtml_toggle_strike(GtkIMHtml *imhtml) |
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4165 { |
12605
cd1d0131e07f
[gaim-migrate @ 14940]
Richard Laager <rlaager@wiktel.com>
parents:
12600
diff
changeset
|
4166 imhtml_emit_signal_for_format(imhtml, GTK_IMHTML_STRIKE); |
9924 | 4167 } |
4168 | |
8061 | 4169 void gtk_imhtml_font_set_size(GtkIMHtml *imhtml, gint size) |
4170 { | |
9025 | 4171 GObject *object; |
8677 | 4172 GtkTextIter start, end; |
8061 | 4173 |
4174 imhtml->edit.fontsize = size; | |
4175 | |
8677 | 4176 if (imhtml->wbfo) { |
4177 gtk_text_buffer_get_bounds(imhtml->text_buffer, &start, &end); | |
4178 remove_font_size(imhtml, &start, &end, TRUE); | |
4179 gtk_text_buffer_apply_tag(imhtml->text_buffer, | |
4180 find_font_size_tag(imhtml, imhtml->edit.fontsize), &start, &end); | |
11276
17ebda61c6ce
[gaim-migrate @ 13463]
Richard Laager <rlaager@wiktel.com>
parents:
11275
diff
changeset
|
4181 } else if (imhtml->editable && gtk_text_buffer_get_selection_bounds(imhtml->text_buffer, &start, &end)) { |
8677 | 4182 remove_font_size(imhtml, &start, &end, FALSE); |
4183 gtk_text_buffer_apply_tag(imhtml->text_buffer, | |
4184 find_font_size_tag(imhtml, imhtml->edit.fontsize), &start, &end); | |
8061 | 4185 } |
8677 | 4186 |
9025 | 4187 object = g_object_ref(G_OBJECT(imhtml)); |
11267
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4188 g_signal_emit(object, signals[TOGGLE_FORMAT], 0, GTK_IMHTML_SHRINK | GTK_IMHTML_GROW); |
9025 | 4189 g_object_unref(object); |
8061 | 4190 } |
4191 | |
11267
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4192 static void imhtml_font_shrink(GtkIMHtml *imhtml) |
8061 | 4193 { |
8677 | 4194 GtkTextIter start, end; |
4195 | |
8061 | 4196 if (imhtml->edit.fontsize == 1) |
4197 return; | |
4198 | |
8677 | 4199 if (!imhtml->edit.fontsize) |
4200 imhtml->edit.fontsize = 2; | |
4201 else | |
4202 imhtml->edit.fontsize--; | |
4203 | |
4204 if (imhtml->wbfo) { | |
4205 gtk_text_buffer_get_bounds(imhtml->text_buffer, &start, &end); | |
4206 remove_font_size(imhtml, &start, &end, TRUE); | |
4207 gtk_text_buffer_apply_tag(imhtml->text_buffer, | |
4208 find_font_size_tag(imhtml, imhtml->edit.fontsize), &start, &end); | |
11276
17ebda61c6ce
[gaim-migrate @ 13463]
Richard Laager <rlaager@wiktel.com>
parents:
11275
diff
changeset
|
4209 } else if (imhtml->editable && gtk_text_buffer_get_selection_bounds(imhtml->text_buffer, &start, &end)) { |
8677 | 4210 remove_font_size(imhtml, &start, &end, FALSE); |
4211 gtk_text_buffer_apply_tag(imhtml->text_buffer, | |
4212 find_font_size_tag(imhtml, imhtml->edit.fontsize), &start, &end); | |
8061 | 4213 } |
11267
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4214 } |
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4215 |
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4216 void gtk_imhtml_font_shrink(GtkIMHtml *imhtml) |
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4217 { |
12605
cd1d0131e07f
[gaim-migrate @ 14940]
Richard Laager <rlaager@wiktel.com>
parents:
12600
diff
changeset
|
4218 imhtml_emit_signal_for_format(imhtml, GTK_IMHTML_SHRINK); |
8061 | 4219 } |
4220 | |
11267
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4221 static void imhtml_font_grow(GtkIMHtml *imhtml) |
8061 | 4222 { |
8677 | 4223 GtkTextIter start, end; |
4224 | |
8061 | 4225 if (imhtml->edit.fontsize == MAX_FONT_SIZE) |
4226 return; | |
4227 | |
8677 | 4228 if (!imhtml->edit.fontsize) |
4229 imhtml->edit.fontsize = 4; | |
4230 else | |
4231 imhtml->edit.fontsize++; | |
4232 | |
4233 if (imhtml->wbfo) { | |
4234 gtk_text_buffer_get_bounds(imhtml->text_buffer, &start, &end); | |
4235 remove_font_size(imhtml, &start, &end, TRUE); | |
4236 gtk_text_buffer_apply_tag(imhtml->text_buffer, | |
4237 find_font_size_tag(imhtml, imhtml->edit.fontsize), &start, &end); | |
11276
17ebda61c6ce
[gaim-migrate @ 13463]
Richard Laager <rlaager@wiktel.com>
parents:
11275
diff
changeset
|
4238 } else if (imhtml->editable && gtk_text_buffer_get_selection_bounds(imhtml->text_buffer, &start, &end)) { |
8677 | 4239 remove_font_size(imhtml, &start, &end, FALSE); |
4240 gtk_text_buffer_apply_tag(imhtml->text_buffer, | |
4241 find_font_size_tag(imhtml, imhtml->edit.fontsize), &start, &end); | |
8061 | 4242 } |
11267
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4243 } |
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4244 |
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4245 void gtk_imhtml_font_grow(GtkIMHtml *imhtml) |
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4246 { |
12605
cd1d0131e07f
[gaim-migrate @ 14940]
Richard Laager <rlaager@wiktel.com>
parents:
12600
diff
changeset
|
4247 imhtml_emit_signal_for_format(imhtml, GTK_IMHTML_GROW); |
8061 | 4248 } |
4249 | |
11267
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4250 #define gtk_imhtml_toggle_str_tag(imhtml, color, edit_field, remove_func, find_func, button) { \ |
10776 | 4251 GObject *object; \ |
4252 GtkTextIter start, end; \ | |
4253 \ | |
4254 g_free(edit_field); \ | |
4255 edit_field = NULL; \ | |
4256 \ | |
4257 if (color && strcmp(color, "") != 0) { \ | |
4258 edit_field = g_strdup(color); \ | |
4259 \ | |
4260 if (imhtml->wbfo) { \ | |
4261 gtk_text_buffer_get_bounds(imhtml->text_buffer, &start, &end); \ | |
4262 remove_func(imhtml, &start, &end, TRUE); \ | |
4263 gtk_text_buffer_apply_tag(imhtml->text_buffer, \ | |
4264 find_func(imhtml, edit_field), &start, &end); \ | |
4265 } else { \ | |
4266 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &start, \ | |
4267 gtk_text_buffer_get_mark(imhtml->text_buffer, "insert")); \ | |
11276
17ebda61c6ce
[gaim-migrate @ 13463]
Richard Laager <rlaager@wiktel.com>
parents:
11275
diff
changeset
|
4268 if (imhtml->editable && gtk_text_buffer_get_selection_bounds(imhtml->text_buffer, &start, &end)) { \ |
10776 | 4269 remove_func(imhtml, &start, &end, FALSE); \ |
4270 gtk_text_buffer_apply_tag(imhtml->text_buffer, \ | |
4271 find_func(imhtml, \ | |
4272 edit_field), \ | |
4273 &start, &end); \ | |
4274 } \ | |
4275 } \ | |
4276 } else { \ | |
4277 if (imhtml->wbfo) { \ | |
4278 gtk_text_buffer_get_bounds(imhtml->text_buffer, &start, &end); \ | |
4279 remove_func(imhtml, &start, &end, TRUE); \ | |
11968 | 4280 } else { \ |
13136
d38aadce44c5
[gaim-migrate @ 15498]
Richard Laager <rlaager@wiktel.com>
parents:
12900
diff
changeset
|
4281 if (imhtml->editable && gtk_text_buffer_get_selection_bounds(imhtml->text_buffer, &start, &end)) \ |
11968 | 4282 remove_func(imhtml, &start, &end, TRUE); \ |
10776 | 4283 } \ |
4284 } \ | |
4285 \ | |
4286 object = g_object_ref(G_OBJECT(imhtml)); \ | |
11267
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4287 g_signal_emit(object, signals[TOGGLE_FORMAT], 0, button); \ |
10776 | 4288 g_object_unref(object); \ |
4289 \ | |
4290 return edit_field != NULL; \ | |
4291 } | |
4292 | |
8061 | 4293 gboolean gtk_imhtml_toggle_forecolor(GtkIMHtml *imhtml, const char *color) |
4294 { | |
11267
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4295 gtk_imhtml_toggle_str_tag(imhtml, color, imhtml->edit.forecolor, remove_font_forecolor, find_font_forecolor_tag, GTK_IMHTML_FORECOLOR); |
8061 | 4296 } |
4297 | |
4298 gboolean gtk_imhtml_toggle_backcolor(GtkIMHtml *imhtml, const char *color) | |
4299 { | |
11267
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4300 gtk_imhtml_toggle_str_tag(imhtml, color, imhtml->edit.backcolor, remove_font_backcolor, find_font_backcolor_tag, GTK_IMHTML_BACKCOLOR); |
10776 | 4301 } |
4302 | |
4303 gboolean gtk_imhtml_toggle_background(GtkIMHtml *imhtml, const char *color) | |
4304 { | |
11267
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4305 gtk_imhtml_toggle_str_tag(imhtml, color, imhtml->edit.background, remove_font_background, find_font_background_tag, GTK_IMHTML_BACKGROUND); |
8061 | 4306 } |
4307 | |
4308 gboolean gtk_imhtml_toggle_fontface(GtkIMHtml *imhtml, const char *face) | |
4309 { | |
11267
477e5cca8287
[gaim-migrate @ 13449]
Richard Laager <rlaager@wiktel.com>
parents:
11240
diff
changeset
|
4310 gtk_imhtml_toggle_str_tag(imhtml, face, imhtml->edit.fontface, remove_font_face, find_font_face_tag, GTK_IMHTML_FACE); |
8061 | 4311 } |
4312 | |
8677 | 4313 void gtk_imhtml_toggle_link(GtkIMHtml *imhtml, const char *url) |
8061 | 4314 { |
9025 | 4315 GObject *object; |
8677 | 4316 GtkTextIter start, end; |
4317 GtkTextTag *linktag; | |
4318 static guint linkno = 0; | |
4319 gchar str[48]; | |
9007 | 4320 GdkColor *color = NULL; |
8677 | 4321 |
4322 imhtml->edit.link = NULL; | |
4323 | |
4324 if (url) { | |
4325 g_snprintf(str, sizeof(str), "LINK %d", linkno++); | |
4326 str[47] = '\0'; | |
4327 | |
9007 | 4328 gtk_widget_style_get(GTK_WIDGET(imhtml), "hyperlink-color", &color, NULL); |
9008 | 4329 if (color) { |
9007 | 4330 imhtml->edit.link = linktag = gtk_text_buffer_create_tag(imhtml->text_buffer, str, "foreground-gdk", color, "underline", PANGO_UNDERLINE_SINGLE, NULL); |
9008 | 4331 gdk_color_free(color); |
4332 } else { | |
9007 | 4333 imhtml->edit.link = linktag = gtk_text_buffer_create_tag(imhtml->text_buffer, str, "foreground", "blue", "underline", PANGO_UNDERLINE_SINGLE, NULL); |
9008 | 4334 } |
8677 | 4335 g_object_set_data_full(G_OBJECT(linktag), "link_url", g_strdup(url), g_free); |
4336 g_signal_connect(G_OBJECT(linktag), "event", G_CALLBACK(tag_event), NULL); | |
4337 | |
11276
17ebda61c6ce
[gaim-migrate @ 13463]
Richard Laager <rlaager@wiktel.com>
parents:
11275
diff
changeset
|
4338 if (imhtml->editable && gtk_text_buffer_get_selection_bounds(imhtml->text_buffer, &start, &end)) { |
8677 | 4339 remove_font_link(imhtml, &start, &end, FALSE); |
4340 gtk_text_buffer_apply_tag(imhtml->text_buffer, linktag, &start, &end); | |
4341 } | |
4342 } | |
9025 | 4343 |
4344 object = g_object_ref(G_OBJECT(imhtml)); | |
4345 g_signal_emit(object, signals[TOGGLE_FORMAT], 0, GTK_IMHTML_LINK); | |
4346 g_object_unref(object); | |
8677 | 4347 } |
4348 | |
4349 void gtk_imhtml_insert_link(GtkIMHtml *imhtml, GtkTextMark *mark, const char *url, const char *text) | |
4350 { | |
8061 | 4351 GtkTextIter iter; |
8677 | 4352 |
9599 | 4353 if (gtk_text_buffer_get_selection_bounds(imhtml->text_buffer, NULL, NULL)) |
4354 gtk_text_buffer_delete_selection(imhtml->text_buffer, TRUE, TRUE); | |
4355 | |
8677 | 4356 gtk_imhtml_toggle_link(imhtml, url); |
8061 | 4357 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, mark); |
8677 | 4358 gtk_text_buffer_insert(imhtml->text_buffer, &iter, text, -1); |
4359 gtk_imhtml_toggle_link(imhtml, NULL); | |
8061 | 4360 } |
4361 | |
4362 void gtk_imhtml_insert_smiley(GtkIMHtml *imhtml, const char *sml, char *smiley) | |
4363 { | |
8677 | 4364 GtkTextMark *mark; |
8061 | 4365 GtkTextIter iter; |
8677 | 4366 |
11750 | 4367 if (gtk_text_buffer_get_selection_bounds(imhtml->text_buffer, NULL, NULL)) |
4368 gtk_text_buffer_delete_selection(imhtml->text_buffer, TRUE, TRUE); | |
4369 | |
8677 | 4370 mark = gtk_text_buffer_get_insert(imhtml->text_buffer); |
4371 | |
4372 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, mark); | |
4373 gtk_imhtml_insert_smiley_at_iter(imhtml, sml, smiley, &iter); | |
4374 } | |
4375 | |
4376 void gtk_imhtml_insert_smiley_at_iter(GtkIMHtml *imhtml, const char *sml, char *smiley, GtkTextIter *iter) | |
4377 { | |
8061 | 4378 GdkPixbuf *pixbuf = NULL; |
4379 GdkPixbufAnimation *annipixbuf = NULL; | |
4380 GtkWidget *icon = NULL; | |
4381 GtkTextChildAnchor *anchor; | |
8505 | 4382 char *unescaped = gaim_unescape_html(smiley); |
11525 | 4383 GtkIMHtmlSmiley *imhtml_smiley = gtk_imhtml_smiley_get(imhtml, sml, unescaped); |
8061 | 4384 |
10526 | 4385 if (imhtml->format_functions & GTK_IMHTML_SMILEY) { |
10522 | 4386 annipixbuf = gtk_smiley_tree_image(imhtml, sml, unescaped); |
10526 | 4387 if (annipixbuf) { |
4388 if (gdk_pixbuf_animation_is_static_image(annipixbuf)) { | |
10522 | 4389 pixbuf = gdk_pixbuf_animation_get_static_image(annipixbuf); |
10526 | 4390 if (pixbuf) |
10522 | 4391 icon = gtk_image_new_from_pixbuf(pixbuf); |
4392 } else { | |
4393 icon = gtk_image_new_from_animation(annipixbuf); | |
4394 } | |
8061 | 4395 } |
4396 } | |
4397 | |
4398 if (icon) { | |
8890 | 4399 anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, iter); |
4400 g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_plaintext", g_strdup(unescaped), g_free); | |
4401 g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_htmltext", g_strdup(smiley), g_free); | |
4402 | |
8061 | 4403 gtk_widget_show(icon); |
4404 gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), icon, anchor); | |
11525 | 4405 } else if (imhtml_smiley != NULL && (imhtml->format_functions & GTK_IMHTML_SMILEY)) { |
4406 anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, iter); | |
4407 imhtml_smiley->anchors = g_slist_append(imhtml_smiley->anchors, anchor); | |
8890 | 4408 } else { |
4409 gtk_text_buffer_insert(imhtml->text_buffer, iter, smiley, -1); | |
8061 | 4410 } |
8890 | 4411 |
4412 g_free(unescaped); | |
8061 | 4413 } |
4414 | |
8962 | 4415 void gtk_imhtml_insert_image_at_iter(GtkIMHtml *imhtml, int id, GtkTextIter *iter) |
4416 { | |
4417 GdkPixbuf *pixbuf = NULL; | |
4418 const char *filename = NULL; | |
4419 gpointer image; | |
4420 GdkRectangle rect; | |
4421 GtkIMHtmlScalable *scalable = NULL; | |
11224
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
4422 struct scalable_data *sd; |
8962 | 4423 int minus; |
4424 | |
4425 if (!imhtml->funcs || !imhtml->funcs->image_get || | |
4426 !imhtml->funcs->image_get_size || !imhtml->funcs->image_get_data || | |
4427 !imhtml->funcs->image_get_filename || !imhtml->funcs->image_ref || | |
4428 !imhtml->funcs->image_unref) | |
4429 return; | |
4430 | |
4431 image = imhtml->funcs->image_get(id); | |
4432 | |
4433 if (image) { | |
4434 gpointer data; | |
4435 size_t len; | |
4436 | |
4437 data = imhtml->funcs->image_get_data(image); | |
4438 len = imhtml->funcs->image_get_size(image); | |
4439 | |
4440 if (data && len) { | |
4441 GdkPixbufLoader *loader = gdk_pixbuf_loader_new(); | |
4442 gdk_pixbuf_loader_write(loader, data, len, NULL); | |
12230
423323aa0dbe
[gaim-migrate @ 14532]
Richard Laager <rlaager@wiktel.com>
parents:
12229
diff
changeset
|
4443 gdk_pixbuf_loader_close(loader, NULL); |
8962 | 4444 pixbuf = gdk_pixbuf_loader_get_pixbuf(loader); |
9337 | 4445 if (pixbuf) |
4446 g_object_ref(G_OBJECT(pixbuf)); | |
4447 g_object_unref(G_OBJECT(loader)); | |
8962 | 4448 } |
4449 | |
4450 } | |
4451 | |
4452 if (pixbuf) { | |
11299
421007f39e53
[gaim-migrate @ 13499]
Richard Laager <rlaager@wiktel.com>
parents:
11276
diff
changeset
|
4453 struct im_image_data *t = g_new(struct im_image_data, 1); |
8962 | 4454 filename = imhtml->funcs->image_get_filename(image); |
4455 imhtml->funcs->image_ref(id); | |
11224
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
4456 t->id = id; |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
4457 t->mark = gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, iter, TRUE); |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
4458 imhtml->im_images = g_slist_prepend(imhtml->im_images, t); |
8962 | 4459 } else { |
4460 pixbuf = gtk_widget_render_icon(GTK_WIDGET(imhtml), GTK_STOCK_MISSING_IMAGE, | |
4461 GTK_ICON_SIZE_BUTTON, "gtkimhtml-missing-image"); | |
4462 } | |
4463 | |
11224
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
4464 sd = g_new(struct scalable_data, 1); |
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
4465 sd->scalable = scalable = gtk_imhtml_image_new(pixbuf, filename, id); |
11233
f08d22130bb2
[gaim-migrate @ 13373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11224
diff
changeset
|
4466 sd->mark = gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, iter, TRUE); |
8962 | 4467 gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(imhtml), &rect); |
4468 scalable->add_to(scalable, imhtml, iter); | |
4469 minus = gtk_text_view_get_left_margin(GTK_TEXT_VIEW(imhtml)) + | |
4470 gtk_text_view_get_right_margin(GTK_TEXT_VIEW(imhtml)); | |
4471 scalable->scale(scalable, rect.width - minus, rect.height); | |
11224
409d6a11da51
[gaim-migrate @ 13360]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11143
diff
changeset
|
4472 imhtml->scalables = g_list_append(imhtml->scalables, sd); |
8962 | 4473 |
4474 g_object_unref(G_OBJECT(pixbuf)); | |
4475 } | |
4476 | |
8677 | 4477 static const gchar *tag_to_html_start(GtkTextTag *tag) |
8061 | 4478 { |
8677 | 4479 const gchar *name; |
4480 static gchar buf[1024]; | |
4481 | |
4482 name = tag->name; | |
4483 g_return_val_if_fail(name != NULL, ""); | |
4484 | |
4485 if (strcmp(name, "BOLD") == 0) { | |
4486 return "<b>"; | |
4487 } else if (strcmp(name, "ITALICS") == 0) { | |
4488 return "<i>"; | |
4489 } else if (strcmp(name, "UNDERLINE") == 0) { | |
4490 return "<u>"; | |
9924 | 4491 } else if (strcmp(name, "STRIKE") == 0) { |
4492 return "<s>"; | |
8677 | 4493 } else if (strncmp(name, "LINK ", 5) == 0) { |
4494 char *tmp = g_object_get_data(G_OBJECT(tag), "link_url"); | |
4495 if (tmp) { | |
4496 g_snprintf(buf, sizeof(buf), "<a href=\"%s\">", tmp); | |
4497 buf[sizeof(buf)-1] = '\0'; | |
4498 return buf; | |
4499 } else { | |
4500 return ""; | |
4501 } | |
4502 } else if (strncmp(name, "FORECOLOR ", 10) == 0) { | |
4503 g_snprintf(buf, sizeof(buf), "<font color=\"%s\">", &name[10]); | |
4504 return buf; | |
4505 } else if (strncmp(name, "BACKCOLOR ", 10) == 0) { | |
4506 g_snprintf(buf, sizeof(buf), "<font back=\"%s\">", &name[10]); | |
4507 return buf; | |
10776 | 4508 } else if (strncmp(name, "BACKGROUND ", 10) == 0) { |
4509 g_snprintf(buf, sizeof(buf), "<body bgcolor=\"%s\">", &name[11]); | |
4510 return buf; | |
8677 | 4511 } else if (strncmp(name, "FONT FACE ", 10) == 0) { |
4512 g_snprintf(buf, sizeof(buf), "<font face=\"%s\">", &name[10]); | |
4513 return buf; | |
4514 } else if (strncmp(name, "FONT SIZE ", 10) == 0) { | |
4515 g_snprintf(buf, sizeof(buf), "<font size=\"%s\">", &name[10]); | |
4516 return buf; | |
4517 } else { | |
4518 return ""; | |
4519 } | |
8061 | 4520 } |
4521 | |
8677 | 4522 static const gchar *tag_to_html_end(GtkTextTag *tag) |
8061 | 4523 { |
8677 | 4524 const gchar *name; |
4525 | |
4526 name = tag->name; | |
4527 g_return_val_if_fail(name != NULL, ""); | |
4528 | |
4529 if (strcmp(name, "BOLD") == 0) { | |
4530 return "</b>"; | |
4531 } else if (strcmp(name, "ITALICS") == 0) { | |
4532 return "</i>"; | |
4533 } else if (strcmp(name, "UNDERLINE") == 0) { | |
4534 return "</u>"; | |
9924 | 4535 } else if (strcmp(name, "STRIKE") == 0) { |
4536 return "</s>"; | |
8677 | 4537 } else if (strncmp(name, "LINK ", 5) == 0) { |
4538 return "</a>"; | |
4539 } else if (strncmp(name, "FORECOLOR ", 10) == 0) { | |
4540 return "</font>"; | |
4541 } else if (strncmp(name, "BACKCOLOR ", 10) == 0) { | |
4542 return "</font>"; | |
10776 | 4543 } else if (strncmp(name, "BACKGROUND ", 10) == 0) { |
4544 return "</body>"; | |
8677 | 4545 } else if (strncmp(name, "FONT FACE ", 10) == 0) { |
4546 return "</font>"; | |
4547 } else if (strncmp(name, "FONT SIZE ", 10) == 0) { | |
4548 return "</font>"; | |
4549 } else { | |
4550 return ""; | |
4551 } | |
4552 } | |
4553 | |
4554 static gboolean tag_ends_here(GtkTextTag *tag, GtkTextIter *iter, GtkTextIter *niter) | |
4555 { | |
4556 return ((gtk_text_iter_has_tag(iter, GTK_TEXT_TAG(tag)) && | |
4557 !gtk_text_iter_has_tag(niter, GTK_TEXT_TAG(tag))) || | |
4558 gtk_text_iter_is_end(niter)); | |
8061 | 4559 } |
4560 | |
4561 /* Basic notion here: traverse through the text buffer one-by-one, non-character elements, such | |
4562 * as smileys and IM images are represented by the Unicode "unknown" character. Handle them. Else | |
8677 | 4563 * check for tags that are toggled on, insert their html form, and push them on the queue. Then insert |
4564 * the actual text. Then check for tags that are toggled off and insert them, after checking the queue. | |
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8729
diff
changeset
|
4565 * Finally, replace <, >, &, and " with their HTML equivalent. |
8677 | 4566 */ |
8061 | 4567 char *gtk_imhtml_get_markup_range(GtkIMHtml *imhtml, GtkTextIter *start, GtkTextIter *end) |
4568 { | |
4569 gunichar c; | |
8677 | 4570 GtkTextIter iter, nextiter; |
8061 | 4571 GString *str = g_string_new(""); |
8677 | 4572 GSList *tags, *sl; |
4573 GQueue *q, *r; | |
4574 GtkTextTag *tag; | |
4575 | |
4576 q = g_queue_new(); | |
4577 r = g_queue_new(); | |
4578 | |
8061 | 4579 |
4580 gtk_text_iter_order(start, end); | |
8677 | 4581 nextiter = iter = *start; |
4582 gtk_text_iter_forward_char(&nextiter); | |
4583 | |
9071 | 4584 /* First add the tags that are already in progress (we don't care about non-printing tags)*/ |
8677 | 4585 tags = gtk_text_iter_get_tags(start); |
4586 | |
4587 for (sl = tags; sl; sl = sl->next) { | |
4588 tag = sl->data; | |
4589 if (!gtk_text_iter_toggles_tag(start, GTK_TEXT_TAG(tag))) { | |
9071 | 4590 if (strlen(tag_to_html_end(tag)) > 0) |
11572
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
4591 g_string_append(str, tag_to_html_start(tag)); |
8677 | 4592 g_queue_push_tail(q, tag); |
8061 | 4593 } |
4594 } | |
8677 | 4595 g_slist_free(tags); |
8061 | 4596 |
4597 while ((c = gtk_text_iter_get_char(&iter)) != 0 && !gtk_text_iter_equal(&iter, end)) { | |
8677 | 4598 |
4599 tags = gtk_text_iter_get_tags(&iter); | |
4600 | |
4601 for (sl = tags; sl; sl = sl->next) { | |
4602 tag = sl->data; | |
4603 if (gtk_text_iter_begins_tag(&iter, GTK_TEXT_TAG(tag))) { | |
9071 | 4604 if (strlen(tag_to_html_end(tag)) > 0) |
11572
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
4605 g_string_append(str, tag_to_html_start(tag)); |
8677 | 4606 g_queue_push_tail(q, tag); |
4607 } | |
4608 } | |
4609 | |
4610 | |
8061 | 4611 if (c == 0xFFFC) { |
4612 GtkTextChildAnchor* anchor = gtk_text_iter_get_child_anchor(&iter); | |
9071 | 4613 if (anchor) { |
4614 char *text = g_object_get_data(G_OBJECT(anchor), "gtkimhtml_htmltext"); | |
4615 if (text) | |
4616 str = g_string_append(str, text); | |
4617 } | |
11572
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
4618 } else if (c == '<') { |
8677 | 4619 str = g_string_append(str, "<"); |
4620 } else if (c == '>') { | |
4621 str = g_string_append(str, ">"); | |
4622 } else if (c == '&') { | |
4623 str = g_string_append(str, "&"); | |
4624 } else if (c == '"') { | |
4625 str = g_string_append(str, """); | |
4626 } else if (c == '\n') { | |
4627 str = g_string_append(str, "<br>"); | |
8061 | 4628 } else { |
8677 | 4629 str = g_string_append_unichar(str, c); |
4630 } | |
4631 | |
4632 tags = g_slist_reverse(tags); | |
4633 for (sl = tags; sl; sl = sl->next) { | |
4634 tag = sl->data; | |
9071 | 4635 /** don't worry about non-printing tags ending */ |
4636 if (tag_ends_here(tag, &iter, &nextiter) && strlen(tag_to_html_end(tag)) > 0) { | |
8677 | 4637 |
4638 GtkTextTag *tmp; | |
4639 | |
4640 while ((tmp = g_queue_pop_tail(q)) != tag) { | |
4641 if (tmp == NULL) | |
4642 break; | |
4643 | |
9071 | 4644 if (!tag_ends_here(tmp, &iter, &nextiter) && strlen(tag_to_html_end(tmp)) > 0) |
8677 | 4645 g_queue_push_tail(r, tmp); |
11572
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
4646 g_string_append(str, tag_to_html_end(GTK_TEXT_TAG(tmp))); |
8677 | 4647 } |
4648 | |
4649 if (tmp == NULL) | |
4650 gaim_debug_warning("gtkimhtml", "empty queue, more closing tags than open tags!\n"); | |
11572
7be60d01519f
[gaim-migrate @ 13840]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11525
diff
changeset
|
4651 else |
8677 | 4652 g_string_append(str, tag_to_html_end(GTK_TEXT_TAG(tag))); |
4653 | |
4654 while ((tmp = g_queue_pop_head(r))) { | |
4655 g_string_append(str, tag_to_html_start(GTK_TEXT_TAG(tmp))); | |
4656 g_queue_push_tail(q, tmp); | |
8061 | 4657 } |
4658 } | |
4659 } | |
8677 | 4660 |
4661 g_slist_free(tags); | |
8061 | 4662 gtk_text_iter_forward_char(&iter); |
8677 | 4663 gtk_text_iter_forward_char(&nextiter); |
8061 | 4664 } |
8677 | 4665 |
4666 while ((tag = g_queue_pop_tail(q))) | |
4667 g_string_append(str, tag_to_html_end(GTK_TEXT_TAG(tag))); | |
4668 | |
4669 g_queue_free(q); | |
4670 g_queue_free(r); | |
8061 | 4671 return g_string_free(str, FALSE); |
4672 } | |
4673 | |
8698 | 4674 void gtk_imhtml_close_tags(GtkIMHtml *imhtml, GtkTextIter *iter) |
8061 | 4675 { |
4676 if (imhtml->edit.bold) | |
4677 gtk_imhtml_toggle_bold(imhtml); | |
4678 | |
4679 if (imhtml->edit.italic) | |
4680 gtk_imhtml_toggle_italic(imhtml); | |
4681 | |
4682 if (imhtml->edit.underline) | |
4683 gtk_imhtml_toggle_underline(imhtml); | |
4684 | |
9924 | 4685 if (imhtml->edit.strike) |
4686 gtk_imhtml_toggle_strike(imhtml); | |
4687 | |
8061 | 4688 if (imhtml->edit.forecolor) |
4689 gtk_imhtml_toggle_forecolor(imhtml, NULL); | |
4690 | |
4691 if (imhtml->edit.backcolor) | |
4692 gtk_imhtml_toggle_backcolor(imhtml, NULL); | |
4693 | |
4694 if (imhtml->edit.fontface) | |
4695 gtk_imhtml_toggle_fontface(imhtml, NULL); | |
4696 | |
8677 | 4697 imhtml->edit.fontsize = 0; |
4698 | |
8719 | 4699 if (imhtml->edit.link) |
4700 gtk_imhtml_toggle_link(imhtml, NULL); | |
4701 | |
8698 | 4702 gtk_text_buffer_remove_all_tags(imhtml->text_buffer, iter, iter); |
8061 | 4703 |
4704 } | |
4705 | |
4706 char *gtk_imhtml_get_markup(GtkIMHtml *imhtml) | |
4707 { | |
4708 GtkTextIter start, end; | |
4709 | |
4710 gtk_text_buffer_get_start_iter(imhtml->text_buffer, &start); | |
4711 gtk_text_buffer_get_end_iter(imhtml->text_buffer, &end); | |
4712 return gtk_imhtml_get_markup_range(imhtml, &start, &end); | |
4713 } | |
4714 | |
8677 | 4715 char **gtk_imhtml_get_markup_lines(GtkIMHtml *imhtml) |
4716 { | |
4717 int i, j, lines; | |
4718 GtkTextIter start, end; | |
4719 char **ret; | |
4720 | |
4721 lines = gtk_text_buffer_get_line_count(imhtml->text_buffer); | |
4722 ret = g_new0(char *, lines + 1); | |
4723 gtk_text_buffer_get_start_iter(imhtml->text_buffer, &start); | |
4724 end = start; | |
4725 gtk_text_iter_forward_to_line_end(&end); | |
4726 | |
4727 for (i = 0, j = 0; i < lines; i++) { | |
9612 | 4728 if (gtk_text_iter_get_char(&start) != '\n') { |
4729 ret[j] = gtk_imhtml_get_markup_range(imhtml, &start, &end); | |
4730 if (ret[j] != NULL) | |
4731 j++; | |
4732 } | |
4733 | |
8677 | 4734 gtk_text_iter_forward_line(&start); |
4735 end = start; | |
4736 gtk_text_iter_forward_to_line_end(&end); | |
4737 } | |
4738 | |
4739 return ret; | |
4740 } | |
4741 | |
4742 char *gtk_imhtml_get_text(GtkIMHtml *imhtml, GtkTextIter *start, GtkTextIter *stop) | |
8061 | 4743 { |
8519 | 4744 GString *str = g_string_new(""); |
4745 GtkTextIter iter, end; | |
4746 gunichar c; | |
4747 | |
8677 | 4748 if (start == NULL) |
4749 gtk_text_buffer_get_start_iter(imhtml->text_buffer, &iter); | |
4750 else | |
4751 iter = *start; | |
4752 | |
4753 if (stop == NULL) | |
4754 gtk_text_buffer_get_end_iter(imhtml->text_buffer, &end); | |
4755 else | |
4756 end = *stop; | |
4757 | |
4758 gtk_text_iter_order(&iter, &end); | |
8519 | 4759 |
4760 while ((c = gtk_text_iter_get_char(&iter)) != 0 && !gtk_text_iter_equal(&iter, &end)) { | |
4761 if (c == 0xFFFC) { | |
8677 | 4762 GtkTextChildAnchor* anchor; |
4763 char *text = NULL; | |
4764 | |
4765 anchor = gtk_text_iter_get_child_anchor(&iter); | |
4766 if (anchor) | |
8698 | 4767 text = g_object_get_data(G_OBJECT(anchor), "gtkimhtml_plaintext"); |
8677 | 4768 if (text) |
4769 str = g_string_append(str, text); | |
8519 | 4770 } else { |
4771 g_string_append_unichar(str, c); | |
4772 } | |
4773 gtk_text_iter_forward_char(&iter); | |
4774 } | |
4775 | |
4776 return g_string_free(str, FALSE); | |
8061 | 4777 } |
8962 | 4778 |
4779 void gtk_imhtml_set_funcs(GtkIMHtml *imhtml, GtkIMHtmlFuncs *f) | |
4780 { | |
4781 g_return_if_fail(imhtml != NULL); | |
4782 imhtml->funcs = f; | |
4783 } |