Added basic linkdrag
This commit is contained in:
parent
cffb76dd66
commit
7d59e50bb8
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Reference in New Issue