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