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