| 329 } |
329 } |
| 330 |
330 |
| 331 return FALSE; |
331 return FALSE; |
| 332 } |
332 } |
| 333 |
333 |
| |
334 static GtkIMHtmlCopyable *gtk_imhtml_copyable_new(GtkIMHtml *imhtml, GtkTextMark *mark, const gchar *text) |
| |
335 { |
| |
336 GtkIMHtmlCopyable *copy = g_malloc(sizeof(GtkIMHtmlCopyable)); |
| |
337 copy->mark = mark; |
| |
338 copy->text = g_strdup(text); |
| |
339 imhtml->copyables = g_slist_append(imhtml->copyables, copy); |
| |
340 return copy; |
| |
341 } |
| |
342 |
| |
343 static void copy_clipboard_cb(GtkIMHtml *imhtml, GtkClipboard *clipboard) |
| |
344 { |
| |
345 GtkTextMark *sel = gtk_text_buffer_get_selection_bound(imhtml->text_buffer); |
| |
346 GtkTextMark *ins = gtk_text_buffer_get_insert(imhtml->text_buffer); |
| |
347 GtkTextIter start, end, smiley, last; |
| |
348 GString *str = g_string_new(NULL); |
| |
349 char *text; |
| |
350 |
| |
351 GSList *copyables; |
| |
352 |
| |
353 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &start, sel); |
| |
354 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &end, ins); |
| |
355 |
| |
356 if (gtk_text_iter_equal(&start, &end)) |
| |
357 return; |
| |
358 |
| |
359 gtk_text_iter_order(&start, &end); |
| |
360 last = start; |
| |
361 |
| |
362 for (copyables = imhtml->copyables; copyables != NULL; copyables = copyables->next) { |
| |
363 GtkIMHtmlCopyable *copy = GTK_IMHTML_COPYABLE(copyables->data); |
| |
364 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &smiley, copy->mark); |
| |
365 if (gtk_text_iter_compare(&end, &smiley) < 0) { |
| |
366 break; |
| |
367 } |
| |
368 if (gtk_text_iter_compare(&last, &smiley) <= 0) { |
| |
369 text = gtk_text_buffer_get_text(imhtml->text_buffer, &last, &smiley, FALSE); |
| |
370 str = g_string_append(str, text); |
| |
371 str = g_string_append(str, copy->text); |
| |
372 last = smiley; |
| |
373 g_free(text); |
| |
374 } |
| |
375 } |
| |
376 text = gtk_text_buffer_get_text(imhtml->text_buffer, &last, &end, FALSE); |
| |
377 str = g_string_append(str, text); |
| |
378 g_free(text); |
| |
379 |
| |
380 gtk_clipboard_set_text(clipboard, str->str, str->len); |
| |
381 g_string_free(str, TRUE); |
| |
382 } |
| |
383 |
| |
384 static gboolean button_release_cb(GtkIMHtml *imhtml, GdkEventButton event, gpointer the_foibles_of_man) |
| |
385 { |
| |
386 copy_clipboard_cb(imhtml, gtk_widget_get_clipboard(GTK_WIDGET(imhtml), GDK_SELECTION_PRIMARY)); |
| |
387 return FALSE; |
| |
388 } |
| 334 |
389 |
| 335 |
390 |
| 336 static GtkTextViewClass *parent_class = NULL; |
391 static GtkTextViewClass *parent_class = NULL; |
| 337 |
392 |
| 338 /* GtkIMHtml has one signal--URL_CLICKED */ |
393 /* GtkIMHtml has one signal--URL_CLICKED */ |
| 345 static void |
400 static void |
| 346 gtk_imhtml_finalize (GObject *object) |
401 gtk_imhtml_finalize (GObject *object) |
| 347 { |
402 { |
| 348 GtkIMHtml *imhtml = GTK_IMHTML(object); |
403 GtkIMHtml *imhtml = GTK_IMHTML(object); |
| 349 GList *scalables; |
404 GList *scalables; |
| 350 |
405 GSList *copyables; |
| |
406 |
| 351 g_hash_table_destroy(imhtml->smiley_data); |
407 g_hash_table_destroy(imhtml->smiley_data); |
| 352 gtk_smiley_tree_destroy(imhtml->default_smilies); |
408 gtk_smiley_tree_destroy(imhtml->default_smilies); |
| 353 gdk_cursor_unref(imhtml->hand_cursor); |
409 gdk_cursor_unref(imhtml->hand_cursor); |
| 354 gdk_cursor_unref(imhtml->arrow_cursor); |
410 gdk_cursor_unref(imhtml->arrow_cursor); |
| 355 if(imhtml->tip_window){ |
411 if(imhtml->tip_window){ |
| 360 |
416 |
| 361 for(scalables = imhtml->scalables; scalables; scalables = scalables->next) { |
417 for(scalables = imhtml->scalables; scalables; scalables = scalables->next) { |
| 362 GtkIMHtmlScalable *scale = GTK_IMHTML_SCALABLE(scalables->data); |
418 GtkIMHtmlScalable *scale = GTK_IMHTML_SCALABLE(scalables->data); |
| 363 scale->free(scale); |
419 scale->free(scale); |
| 364 } |
420 } |
| 365 |
421 |
| |
422 for (copyables = imhtml->copyables; copyables; copyables = copyables->next) { |
| |
423 GtkIMHtmlCopyable *copy = GTK_IMHTML_COPYABLE(copyables->data); |
| |
424 g_free(copy->text); |
| |
425 g_free(copy); |
| |
426 } |
| |
427 |
| 366 g_list_free(imhtml->scalables); |
428 g_list_free(imhtml->scalables); |
| 367 G_OBJECT_CLASS(parent_class)->finalize (object); |
429 G_OBJECT_CLASS(parent_class)->finalize (object); |
| 368 } |
430 } |
| 369 |
431 |
| 370 /* Boring GTK stuff */ |
432 /* Boring GTK stuff */ |
| 424 |
486 |
| 425 g_signal_connect(G_OBJECT(imhtml), "size-allocate", G_CALLBACK(gtk_size_allocate_cb), NULL); |
487 g_signal_connect(G_OBJECT(imhtml), "size-allocate", G_CALLBACK(gtk_size_allocate_cb), NULL); |
| 426 g_signal_connect(G_OBJECT(imhtml), "motion-notify-event", G_CALLBACK(gtk_motion_event_notify), NULL); |
488 g_signal_connect(G_OBJECT(imhtml), "motion-notify-event", G_CALLBACK(gtk_motion_event_notify), NULL); |
| 427 g_signal_connect(G_OBJECT(imhtml), "leave-notify-event", G_CALLBACK(gtk_leave_event_notify), NULL); |
489 g_signal_connect(G_OBJECT(imhtml), "leave-notify-event", G_CALLBACK(gtk_leave_event_notify), NULL); |
| 428 g_signal_connect(G_OBJECT(imhtml), "key_press_event", G_CALLBACK(gtk_key_pressed_cb), NULL); |
490 g_signal_connect(G_OBJECT(imhtml), "key_press_event", G_CALLBACK(gtk_key_pressed_cb), NULL); |
| |
491 g_signal_connect(G_OBJECT(imhtml), "copy-clipboard", G_CALLBACK(copy_clipboard_cb), |
| |
492 gtk_widget_get_clipboard(GTK_WIDGET(imhtml), GDK_SELECTION_CLIPBOARD)); |
| |
493 g_signal_connect(G_OBJECT(imhtml), "button-release-event", G_CALLBACK(button_release_cb), imhtml); |
| 429 gtk_widget_add_events(GTK_WIDGET(imhtml), GDK_LEAVE_NOTIFY_MASK); |
494 gtk_widget_add_events(GTK_WIDGET(imhtml), GDK_LEAVE_NOTIFY_MASK); |
| 430 |
495 |
| 431 imhtml->tip = NULL; |
496 imhtml->tip = NULL; |
| 432 imhtml->tip_timer = 0; |
497 imhtml->tip_timer = 0; |
| 433 imhtml->tip_window = NULL; |
498 imhtml->tip_window = NULL; |
| 434 |
499 |
| 435 imhtml->scalables = NULL; |
500 imhtml->scalables = NULL; |
| |
501 imhtml->copyables = NULL; |
| 436 } |
502 } |
| 437 |
503 |
| 438 GtkWidget *gtk_imhtml_new(void *a, void *b) |
504 GtkWidget *gtk_imhtml_new(void *a, void *b) |
| 439 { |
505 { |
| 440 return GTK_WIDGET(g_object_new(gtk_imhtml_get_type(), NULL)); |
506 return GTK_WIDGET(g_object_new(gtk_imhtml_get_type(), NULL)); |
| 1392 } |
1459 } |
| 1393 |
1460 |
| 1394 if (icon) { |
1461 if (icon) { |
| 1395 gtk_widget_show(icon); |
1462 gtk_widget_show(icon); |
| 1396 gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), icon, anchor); |
1463 gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), icon, anchor); |
| |
1464 gtk_imhtml_copyable_new(imhtml, |
| |
1465 gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, &iter, TRUE), |
| |
1466 ws); |
| 1397 } |
1467 } |
| 1398 |
1468 |
| 1399 copy = iter; |
1469 copy = iter; |
| 1400 gtk_text_iter_backward_char(©); |
1470 gtk_text_iter_backward_char(©); |
| 1401 if (bg) { |
1471 if (bg) { |