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