textview: add extend-selection signal
To be able to customize the double-click and triple-click behaviors, to provide custom selection boundaries. https://bugzilla.gnome.org/show_bug.cgi?id=111503
This commit is contained in:
parent
7ff3c6df80
commit
020258f85a
@ -3825,6 +3825,7 @@ GtkTextView
|
|||||||
GtkTextViewClass
|
GtkTextViewClass
|
||||||
GtkTextViewLayer
|
GtkTextViewLayer
|
||||||
GtkTextWindowType
|
GtkTextWindowType
|
||||||
|
GtkTextExtendSelection
|
||||||
GtkWrapMode
|
GtkWrapMode
|
||||||
gtk_text_view_new
|
gtk_text_view_new
|
||||||
gtk_text_view_new_with_buffer
|
gtk_text_view_new_with_buffer
|
||||||
|
@ -281,6 +281,7 @@ enum
|
|||||||
SELECT_ALL,
|
SELECT_ALL,
|
||||||
TOGGLE_CURSOR_VISIBLE,
|
TOGGLE_CURSOR_VISIBLE,
|
||||||
PREEDIT_CHANGED,
|
PREEDIT_CHANGED,
|
||||||
|
EXTEND_SELECTION,
|
||||||
LAST_SIGNAL
|
LAST_SIGNAL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -561,6 +562,12 @@ static void gtk_text_view_queue_draw_region (GtkWidget *widget,
|
|||||||
static void gtk_text_view_get_rendered_rect (GtkTextView *text_view,
|
static void gtk_text_view_get_rendered_rect (GtkTextView *text_view,
|
||||||
GdkRectangle *rect);
|
GdkRectangle *rect);
|
||||||
|
|
||||||
|
static gboolean gtk_text_view_extend_selection (GtkTextView *text_view,
|
||||||
|
GtkTextExtendSelection granularity,
|
||||||
|
const GtkTextIter *location,
|
||||||
|
GtkTextIter *start,
|
||||||
|
GtkTextIter *end);
|
||||||
|
|
||||||
|
|
||||||
/* FIXME probably need the focus methods. */
|
/* FIXME probably need the focus methods. */
|
||||||
|
|
||||||
@ -714,6 +721,7 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
|
|||||||
klass->paste_clipboard = gtk_text_view_paste_clipboard;
|
klass->paste_clipboard = gtk_text_view_paste_clipboard;
|
||||||
klass->toggle_overwrite = gtk_text_view_toggle_overwrite;
|
klass->toggle_overwrite = gtk_text_view_toggle_overwrite;
|
||||||
klass->create_buffer = gtk_text_view_create_buffer;
|
klass->create_buffer = gtk_text_view_create_buffer;
|
||||||
|
klass->extend_selection = gtk_text_view_extend_selection;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Properties
|
* Properties
|
||||||
@ -1278,6 +1286,34 @@ G_GNUC_END_IGNORE_DEPRECATIONS
|
|||||||
G_TYPE_NONE, 1,
|
G_TYPE_NONE, 1,
|
||||||
G_TYPE_STRING);
|
G_TYPE_STRING);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GtkTextView::extend-selection:
|
||||||
|
* @text_view: the object which received the signal
|
||||||
|
* @granularity: the granularity type
|
||||||
|
* @location: the location where to extend the selection
|
||||||
|
* @start: where the selection should start
|
||||||
|
* @end: where the selection should end
|
||||||
|
*
|
||||||
|
* The ::extend-selection signal is emitted when the selection needs to be
|
||||||
|
* extended at @location.
|
||||||
|
*
|
||||||
|
* Returns: %GDK_EVENT_STOP to stop other handlers from being invoked for the
|
||||||
|
* event. %GDK_EVENT_PROPAGATE to propagate the event further.
|
||||||
|
* Since: 3.16
|
||||||
|
*/
|
||||||
|
signals[EXTEND_SELECTION] =
|
||||||
|
g_signal_new (I_("extend-selection"),
|
||||||
|
G_OBJECT_CLASS_TYPE (gobject_class),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
G_STRUCT_OFFSET (GtkTextViewClass, extend_selection),
|
||||||
|
_gtk_boolean_handled_accumulator, NULL,
|
||||||
|
NULL, /* generic marshaller */
|
||||||
|
G_TYPE_BOOLEAN, 4,
|
||||||
|
GTK_TYPE_TEXT_EXTEND_SELECTION,
|
||||||
|
GTK_TYPE_TEXT_ITER | G_SIGNAL_TYPE_STATIC_SCOPE,
|
||||||
|
GTK_TYPE_TEXT_ITER | G_SIGNAL_TYPE_STATIC_SCOPE,
|
||||||
|
GTK_TYPE_TEXT_ITER | G_SIGNAL_TYPE_STATIC_SCOPE);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Key bindings
|
* Key bindings
|
||||||
*/
|
*/
|
||||||
@ -6869,23 +6905,63 @@ drag_scan_timeout (gpointer data)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Move @start and @end to the boundaries of the selection unit (indicated by
|
|
||||||
* @granularity) which contained @start initially.
|
|
||||||
* If the selction unit is SELECT_WORDS and @start is not contained in a word
|
|
||||||
* the selection is extended to all the white spaces between the end of the
|
|
||||||
* word preceding @start and the start of the one following.
|
|
||||||
*/
|
|
||||||
static void
|
static void
|
||||||
extend_selection (GtkTextView *text_view,
|
extend_selection (GtkTextView *text_view,
|
||||||
SelectionGranularity granularity,
|
SelectionGranularity granularity,
|
||||||
|
const GtkTextIter *location,
|
||||||
GtkTextIter *start,
|
GtkTextIter *start,
|
||||||
GtkTextIter *end)
|
GtkTextIter *end)
|
||||||
{
|
{
|
||||||
*end = *start;
|
GtkTextExtendSelection extend_selection_granularity;
|
||||||
|
gboolean handled = FALSE;
|
||||||
|
|
||||||
if (granularity == SELECT_WORDS)
|
switch (granularity)
|
||||||
{
|
{
|
||||||
|
case SELECT_CHARACTERS:
|
||||||
|
*start = *location;
|
||||||
|
*end = *location;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case SELECT_WORDS:
|
||||||
|
extend_selection_granularity = GTK_TEXT_EXTEND_SELECTION_WORD;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SELECT_LINES:
|
||||||
|
extend_selection_granularity = GTK_TEXT_EXTEND_SELECTION_LINE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
|
||||||
|
g_signal_emit (text_view,
|
||||||
|
signals[EXTEND_SELECTION], 0,
|
||||||
|
extend_selection_granularity,
|
||||||
|
location,
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
&handled);
|
||||||
|
|
||||||
|
if (!handled)
|
||||||
|
{
|
||||||
|
*start = *location;
|
||||||
|
*end = *location;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gtk_text_view_extend_selection (GtkTextView *text_view,
|
||||||
|
GtkTextExtendSelection granularity,
|
||||||
|
const GtkTextIter *location,
|
||||||
|
GtkTextIter *start,
|
||||||
|
GtkTextIter *end)
|
||||||
|
{
|
||||||
|
*start = *location;
|
||||||
|
*end = *location;
|
||||||
|
|
||||||
|
switch (granularity)
|
||||||
|
{
|
||||||
|
case GTK_TEXT_EXTEND_SELECTION_WORD:
|
||||||
if (gtk_text_iter_inside_word (start))
|
if (gtk_text_iter_inside_word (start))
|
||||||
{
|
{
|
||||||
if (!gtk_text_iter_starts_word (start))
|
if (!gtk_text_iter_starts_word (start))
|
||||||
@ -6901,6 +6977,11 @@ extend_selection (GtkTextView *text_view,
|
|||||||
{
|
{
|
||||||
GtkTextIter tmp;
|
GtkTextIter tmp;
|
||||||
|
|
||||||
|
/* @start is not contained in a word: the selection is extended to all
|
||||||
|
* the white spaces between the end of the word preceding @start and
|
||||||
|
* the start of the one following.
|
||||||
|
*/
|
||||||
|
|
||||||
tmp = *start;
|
tmp = *start;
|
||||||
if (gtk_text_iter_backward_visible_word_start (&tmp))
|
if (gtk_text_iter_backward_visible_word_start (&tmp))
|
||||||
gtk_text_iter_forward_visible_word_end (&tmp);
|
gtk_text_iter_forward_visible_word_end (&tmp);
|
||||||
@ -6922,9 +7003,9 @@ extend_selection (GtkTextView *text_view,
|
|||||||
else
|
else
|
||||||
gtk_text_iter_forward_to_line_end (end);
|
gtk_text_iter_forward_to_line_end (end);
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
else if (granularity == SELECT_LINES)
|
|
||||||
{
|
case GTK_TEXT_EXTEND_SELECTION_LINE:
|
||||||
if (gtk_text_view_starts_display_line (text_view, start))
|
if (gtk_text_view_starts_display_line (text_view, start))
|
||||||
{
|
{
|
||||||
/* If on a display line boundary, we assume the user
|
/* If on a display line boundary, we assume the user
|
||||||
@ -6943,9 +7024,14 @@ extend_selection (GtkTextView *text_view,
|
|||||||
if (!gtk_text_view_starts_display_line (text_view, end))
|
if (!gtk_text_view_starts_display_line (text_view, end))
|
||||||
gtk_text_view_forward_display_line_end (text_view, end);
|
gtk_text_view_forward_display_line_end (text_view, end);
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_return_val_if_reached (GDK_EVENT_STOP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return GDK_EVENT_STOP;
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -7061,8 +7147,8 @@ gtk_text_view_drag_gesture_update (GtkGestureDrag *gesture,
|
|||||||
|
|
||||||
get_iter_from_gesture (text_view, text_view->priv->drag_gesture,
|
get_iter_from_gesture (text_view, text_view->priv->drag_gesture,
|
||||||
&cursor, NULL, NULL);
|
&cursor, NULL, NULL);
|
||||||
start = cursor;
|
|
||||||
extend_selection (text_view, data->granularity, &start, &end);
|
extend_selection (text_view, data->granularity, &cursor, &start, &end);
|
||||||
|
|
||||||
/* either the selection extends to the front, or end (or not) */
|
/* either the selection extends to the front, or end (or not) */
|
||||||
if (gtk_text_iter_compare (&cursor, &orig_start) < 0)
|
if (gtk_text_iter_compare (&cursor, &orig_start) < 0)
|
||||||
@ -7193,9 +7279,8 @@ gtk_text_view_start_selection_drag (GtkTextView *text_view,
|
|||||||
buffer = get_buffer (text_view);
|
buffer = get_buffer (text_view);
|
||||||
|
|
||||||
cursor = *iter;
|
cursor = *iter;
|
||||||
ins = cursor;
|
extend_selection (text_view, data->granularity, &cursor, &ins, &bound);
|
||||||
|
|
||||||
extend_selection (text_view, data->granularity, &ins, &bound);
|
|
||||||
orig_start = ins;
|
orig_start = ins;
|
||||||
orig_end = bound;
|
orig_end = bound;
|
||||||
gdk_event_get_state (event, &state);
|
gdk_event_get_state (event, &state);
|
||||||
|
@ -81,6 +81,24 @@ typedef enum
|
|||||||
GTK_TEXT_VIEW_LAYER_ABOVE
|
GTK_TEXT_VIEW_LAYER_ABOVE
|
||||||
} GtkTextViewLayer;
|
} GtkTextViewLayer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GtkTextExtendSelection:
|
||||||
|
* @GTK_TEXT_EXTEND_SELECTION_WORD: Selects the current word. It is triggered by
|
||||||
|
* a double-click for example.
|
||||||
|
* @GTK_TEXT_EXTEND_SELECTION_LINE: Selects the current line. It is triggered by
|
||||||
|
* a triple-click for example.
|
||||||
|
*
|
||||||
|
* Granularity types that extend the text selection. Use the
|
||||||
|
* #GtkTextView::extend-selection signal to customize the selection.
|
||||||
|
*
|
||||||
|
* Since: 3.16
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GTK_TEXT_EXTEND_SELECTION_WORD,
|
||||||
|
GTK_TEXT_EXTEND_SELECTION_LINE
|
||||||
|
} GtkTextExtendSelection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GTK_TEXT_VIEW_PRIORITY_VALIDATE:
|
* GTK_TEXT_VIEW_PRIORITY_VALIDATE:
|
||||||
*
|
*
|
||||||
@ -160,6 +178,11 @@ struct _GtkTextViewClass
|
|||||||
void (* draw_layer) (GtkTextView *text_view,
|
void (* draw_layer) (GtkTextView *text_view,
|
||||||
GtkTextViewLayer layer,
|
GtkTextViewLayer layer,
|
||||||
cairo_t *cr);
|
cairo_t *cr);
|
||||||
|
gboolean (* extend_selection) (GtkTextView *text_view,
|
||||||
|
GtkTextExtendSelection granularity,
|
||||||
|
const GtkTextIter *location,
|
||||||
|
GtkTextIter *start,
|
||||||
|
GtkTextIter *end);
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
|
|
||||||
@ -169,7 +192,6 @@ struct _GtkTextViewClass
|
|||||||
void (*_gtk_reserved3) (void);
|
void (*_gtk_reserved3) (void);
|
||||||
void (*_gtk_reserved4) (void);
|
void (*_gtk_reserved4) (void);
|
||||||
void (*_gtk_reserved5) (void);
|
void (*_gtk_reserved5) (void);
|
||||||
void (*_gtk_reserved6) (void);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
|
Loading…
Reference in New Issue
Block a user