Added basic linkdrag

This commit is contained in:
Jesse van den Kieboom 2005-12-23 13:23:35 +00:00
parent cffb76dd66
commit 7d59e50bb8
1 changed files with 82 additions and 6 deletions

View File

@ -1,6 +1,6 @@
#include <gtk/gtk.h>
#include <string.h>
#include <gdk/gdk.h>
#include "gm-world-text-view.h"
#include "../gm-color-table.h"
#include "../gm-marshal.h"
@ -24,11 +24,15 @@ void on_gm_world_text_view_color_table_font_changed(GmColorTable *table,
gchar *font_description, GmWorldTextView *view);
void on_gm_world_text_view_populate_popup(GmWorldTextView *view, GtkMenu *menu,
gpointer user_data);
void on_gm_world_text_view_drag_data_get(GmWorldTextView *view,
GdkDragContext *context, GtkSelectionData *data, guint info,
guint time, gpointer user_data);
void gm_world_text_view_create_tags(GmWorldTextView *view);
void gm_world_text_view_init_tags(GmWorldTextView *view);
void gm_world_text_view_update_font(GmWorldTextView *view);
#define GM_WORLD_TEXT_VIEW_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GM_TYPE_WORLD_TEXT_VIEW, GmWorldTextViewPrivate))
#define GM_WORLD_TEXT_VIEW_BUFFER(view) gtk_text_view_get_buffer(GTK_TEXT_VIEW(view))
@ -49,6 +53,11 @@ struct _GmWorldTextViewPrivate {
gint max_lines;
GmWorldTextViewInsertInfo last_info;
GmColorTable *color_table;
gboolean drag_url;
gchar *drag_url_text;
guint drag_x;
guint drag_y;
GtkTargetList *source_target_list;
};
/* Signals */
@ -72,6 +81,7 @@ gm_world_text_view_finalize(GObject *object) {
g_list_free(view->priv->last_info.tags);
g_free(view->priv->last_info.text);
gtk_target_list_unref(view->priv->source_target_list);
G_OBJECT_CLASS(gm_world_text_view_parent_class)->finalize(object);
}
@ -107,6 +117,15 @@ gm_world_text_view_class_init(GmWorldTextViewClass *klass) {
g_type_class_add_private(object_class, sizeof(GmWorldTextViewPrivate));
}
enum {
DRAG_URL,
NUM_TARGETS
};
static const GtkTargetEntry drag_targets[] = {
{"_NETSCAPE_URL", 0, DRAG_URL}
};
static void
gm_world_text_view_init(GmWorldTextView *view) {
view->priv = GM_WORLD_TEXT_VIEW_GET_PRIVATE(view);
@ -138,11 +157,16 @@ gm_world_text_view_init(GmWorldTextView *view) {
view->priv->last_info.tags = NULL;
view->priv->last_info.text = NULL;
view->priv->source_target_list = gtk_target_list_new(drag_targets,
NUM_TARGETS);
// Connect style set signal
g_signal_connect(view, "style-set",
G_CALLBACK(on_gm_world_text_view_style_set), NULL);
g_signal_connect(view, "populate_popup",
G_CALLBACK(on_gm_world_text_view_populate_popup), NULL);
g_signal_connect(view, "drag_data_get",
G_CALLBACK(on_gm_world_text_view_drag_data_get), NULL);
}
/* Private functions */
@ -527,7 +551,7 @@ gm_world_text_view_tags_overlap(GtkTextTag *t1, GtkTextTag *t2) {
return TRUE;
}
i++;
++i;
}
return FALSE;
@ -886,13 +910,52 @@ gboolean
on_gm_world_text_view_url_event(GtkTextTag *tag, GObject *object,
GdkEvent *event, GtkTextIter *iter, GmWorldTextView *view) {
GtkTextIter start, end;
gchar *str;
gchar *str = NULL;
GtkTextBuffer *buffer = GM_WORLD_TEXT_VIEW_BUFFER(view);
start = end = *iter;
if (gtk_text_iter_backward_to_tag_toggle(&start, tag) &&
gtk_text_iter_forward_to_tag_toggle(&end, tag)) {
str = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
}
if (str == NULL) {
return FALSE;
}
if (event->type == GDK_MOTION_NOTIFY && view->priv->drag_url &&
!(event->motion.state & GDK_CONTROL_MASK) &&
gtk_drag_check_threshold(GTK_WIDGET(view), view->priv->drag_x,
view->priv->drag_y, event->motion.x, event->motion.y)) {
view->priv->drag_url = FALSE;
view->priv->drag_url_text = g_strdup(str);
gtk_drag_begin(GTK_WIDGET(view), view->priv->source_target_list,
GDK_ACTION_COPY | GDK_ACTION_LINK | GDK_ACTION_ASK,
1, event);
GM_DEBUG("Drag started!");
}
if (event->type == GDK_BUTTON_PRESS &&
!(event->button.state & GDK_CONTROL_MASK)) {
GM_DEBUG("Possible drag init!");
view->priv->drag_x = event->button.x;
view->priv->drag_y = event->button.y;
view->priv->drag_url = TRUE;
}
if (event->type == GDK_BUTTON_RELEASE && view->priv->drag_url &&
event->button.button == 1) {
GM_DEBUG("Drag stopped!");
view->priv->drag_url = FALSE;
}
/* If the link is being selected, don't do anything. */
gtk_text_buffer_get_selection_bounds(buffer, &start, &end);
if (gtk_text_iter_get_offset(&start) != gtk_text_iter_get_offset(&end)) {
g_free(str);
return FALSE;
}
@ -901,12 +964,11 @@ on_gm_world_text_view_url_event(GtkTextTag *tag, GObject *object,
if (gtk_text_iter_backward_to_tag_toggle(&start, tag) &&
gtk_text_iter_forward_to_tag_toggle(&end, tag)) {
str = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
g_signal_emit(view, world_text_view_signals[URL_ACTIVATE], 0, str);
g_free(str);
}
}
g_free(str);
return FALSE;
}
@ -994,7 +1056,11 @@ on_gm_world_text_view_event(GmWorldTextView *view, GdkEventMotion *event,
if (type != GTK_TEXT_WINDOW_TEXT) {
return FALSE;
}
if (event->type != GDK_MOTION_NOTIFY) {
return FALSE;
}
/* Get where the pointer really is. */
win = gtk_text_view_get_window(GTK_TEXT_VIEW(view), type);
gdk_window_get_pointer(win, &x, &y, NULL);
@ -1088,3 +1154,13 @@ on_gm_world_text_view_color_table_font_changed(GmColorTable *table,
gchar *font_description, GmWorldTextView *view) {
gm_world_text_view_update_font(view);
}
void on_gm_world_text_view_drag_data_get(GmWorldTextView *view,
GdkDragContext *context, GtkSelectionData *data, guint info,
guint time, gpointer user_data) {
switch (info) {
case DRAG_URL:
gtk_selection_data_set_text(data, view->priv->drag_url_text, -1);
break;
}
}