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