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