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