diff --git a/src/gtk/actions.c b/src/gtk/actions.c index 6321491..1395f8d 100644 --- a/src/gtk/actions.c +++ b/src/gtk/actions.c @@ -307,7 +307,7 @@ static void action_select_field(GtkAction *action, GtkWidget *widget) static void action_select_none(GtkAction *action, GtkWidget *widget) { - lib3270_unselect(v3270_get_session(widget)); + v3270_unselect(widget); } static void action_select_last(GtkAction *action, GtkWidget *widget) diff --git a/src/gtk/print.c b/src/gtk/print.c index 4cce1bd..f25625f 100644 --- a/src/gtk/print.c +++ b/src/gtk/print.c @@ -501,7 +501,7 @@ static gchar * enum_to_string(GType type, guint enum_value) trace("Action %s activated on widget %p",gtk_action_get_name(action),widget); - if(lib3270_get_selected_addr(info->session,&start,&end)) + if(!lib3270_get_selection_bounds(info->session,&start,&end)) { g_warning("Can't get selected addresses for action %s",gtk_action_get_name(action)); g_object_unref(print); diff --git a/src/gtk/v3270/accessible.c b/src/gtk/v3270/accessible.c index 73f9297..daa9a0f 100644 --- a/src/gtk/v3270/accessible.c +++ b/src/gtk/v3270/accessible.c @@ -431,6 +431,40 @@ static gboolean v3270_set_caret_offset(AtkText *text, gint offset) return TRUE; } +static gboolean v3270_accessible_remove_selection(AtkText *text, gint selection_num) +{ + GtkWidget * widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); + + if (widget == NULL || selection_num != 0) + return FALSE; + + v3270_unselect(widget); + + return TRUE; +} + +static gint v3270_accessible_get_n_selections (AtkText *text) +{ + GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); + + if(!widget) + return 0; + + return v3270_get_selection_bounds(widget, NULL, NULL) ? 1 : 0; +} + +static gchar * v3270_accessible_get_selection (AtkText *atk_text, gint selection_num, gint *start_pos, gint *end_pos) +{ + GtkWidget *widget = gtk_accessible_get_widget(GTK_ACCESSIBLE (atk_text)); + + if (widget == NULL ||selection_num != 0) + return NULL; + + if(v3270_get_selection_bounds(widget, start_pos, end_pos)) + return v3270_get_region(widget, *start_pos, *end_pos, FALSE); + + return NULL; +} static void atk_text_interface_init(AtkTextIface *iface) { iface->get_text = v3270_accessible_get_text; @@ -444,14 +478,18 @@ static void atk_text_interface_init(AtkTextIface *iface) iface->get_character_extents = v3270_accessible_get_character_extents; iface->get_offset_at_point = v3270_accessible_get_offset_at_point; + iface->remove_selection = v3270_accessible_remove_selection; + + iface->get_n_selections = v3270_accessible_get_n_selections; + iface->get_selection = v3270_accessible_get_selection; /* +http://git.gnome.org/browse/gtk+/tree/gtk/a11y/gtklabelaccessible.c + iface->get_text_before_offset = gtk_label_accessible_get_text_before_offset; iface->get_text_after_offset = gtk_label_accessible_get_text_after_offset; - iface->get_n_selections = gtk_label_accessible_get_n_selections; - iface->get_selection = gtk_label_accessible_get_selection; iface->add_selection = gtk_label_accessible_add_selection; iface->remove_selection = gtk_label_accessible_remove_selection; iface->set_selection = gtk_label_accessible_set_selection; @@ -461,14 +499,12 @@ static void atk_text_interface_init(AtkTextIface *iface) */ } - static void v3270_accessible_init(v3270Accessible *widget) { - AtkObject *obj = ATK_OBJECT(widget); - obj->role = ATK_ROLE_TEXT; + AtkObject *obj = ATK_OBJECT(widget); + obj->role = ATK_ROLE_TEXT; } - void v3270_accessible_get_extents(AtkComponent *component, gint *x, gint *y,gint *width,gint *height, AtkCoordType coord_type) { GtkWidget *widget = gtk_accessible_get_widget(GTK_ACCESSIBLE (component)); @@ -546,18 +582,33 @@ static gboolean v3270_accessible_grab_focus(AtkComponent *component) return TRUE; } +static AtkLayer v3270_accessible_get_layer (AtkComponent *component) +{ + return ATK_LAYER_WIDGET; +} + +static gboolean v3270_accessible_set_size(AtkComponent *component, gint width, gint height) +{ + GtkWidget *widget = gtk_accessible_get_widget(GTK_ACCESSIBLE (component)); + + if (widget == NULL) + return FALSE; + + gtk_widget_set_size_request(widget, width, height); + return TRUE; +} static void atk_component_interface_init(AtkComponentIface *iface) { iface->get_extents = v3270_accessible_get_extents; iface->get_size = v3270_accessible_get_size; iface->grab_focus = v3270_accessible_grab_focus; + iface->get_layer = v3270_accessible_get_layer; + iface->set_size = v3270_accessible_set_size; /* - iface->get_layer = gtk_widget_accessible_get_layer; iface->set_extents = gtk_widget_accessible_set_extents; iface->set_position = gtk_widget_accessible_set_position; - iface->set_size = gtk_widget_accessible_set_size; */ } diff --git a/src/gtk/v3270/clipboard.c b/src/gtk/v3270/clipboard.c index 3d502d0..6acd96d 100644 --- a/src/gtk/v3270/clipboard.c +++ b/src/gtk/v3270/clipboard.c @@ -438,3 +438,33 @@ void v3270_paste(GtkWidget *widget) gtk_clipboard_request_text(gtk_widget_get_clipboard(widget,GDK_SELECTION_CLIPBOARD),(GtkClipboardTextReceivedFunc) text_received,(gpointer) widget); } +void v3270_unselect(GtkWidget *widget) +{ + lib3270_unselect(v3270_get_session(widget)); +} + +gboolean v3270_get_selection_bounds(GtkWidget *widget, gint *start, gint *end) +{ + g_return_val_if_fail(GTK_IS_V3270(widget),FALSE); + return lib3270_get_selection_bounds(GTK_V3270(widget)->host,start,end) == 0 ? FALSE : TRUE; +} + +gchar * v3270_get_region(GtkWidget *widget, gint start_pos, gint end_pos, gboolean all) +{ + char * str; + gchar * utftext; + + g_return_val_if_fail(GTK_IS_V3270(widget),NULL); + + str = lib3270_get_region(GTK_V3270(widget)->host,start_pos,end_pos,all); + if(!str) + return NULL; + + utftext = g_convert(str, -1, "UTF-8", lib3270_get_charset(GTK_V3270(widget)->host), NULL, NULL, NULL); + + free(str); + + return utftext; +} + + diff --git a/src/gtk/v3270/v3270.h b/src/gtk/v3270/v3270.h index 8cb52f2..6652ee8 100644 --- a/src/gtk/v3270/v3270.h +++ b/src/gtk/v3270/v3270.h @@ -156,7 +156,11 @@ const gchar * v3270_get_selected_text(GtkWidget *widget); const gchar * v3270_get_copy(GtkWidget *widget); gchar * v3270_get_text(GtkWidget *widget,int offset, int len); + gchar * v3270_get_region(GtkWidget *widget, gint start_pos, gint end_pos, gboolean all); + // Cut & Paste + gboolean v3270_get_selection_bounds(GtkWidget *widget, gint *start, gint *end); + void v3270_unselect(GtkWidget *widget); void v3270_paste(GtkWidget *widget); void v3270_paste_string(GtkWidget *widget, const gchar *text, const gchar *encoding); diff --git a/src/include/lib3270/selection.h b/src/include/lib3270/selection.h index b12ed80..b298731 100644 --- a/src/include/lib3270/selection.h +++ b/src/include/lib3270/selection.h @@ -101,16 +101,16 @@ LIB3270_EXPORT int lib3270_drag_selection(H3270 *h, unsigned char flag, int origin, int baddr); /** - * Get addresses of selected area. + * Gets the selected range of characters in the screen * * @param h Session handle. - * @param begin Pointer to the begin value. - * @param end Pointer to the end value. + * @param start return location for start of selection, as a character offset. + * @param end return location for end of selection, as a character offset. * - * @return 0 if the selected area was get, non zero if unselected or unavailable. + * @return Non 0 if selection is non-empty * */ - LIB3270_EXPORT int lib3270_get_selected_addr(H3270 *hSession, int *begin, int *end); + LIB3270_EXPORT int lib3270_get_selection_bounds(H3270 *hSession, int *start, int *end); /** * Get bitmasked flag for the current selection. @@ -124,4 +124,17 @@ */ LIB3270_EXPORT unsigned char lib3270_get_selection_flags(H3270 *h, int baddr); + /** + * Get a string from required region. + * + * @param h Session handle. + * @param start_pos First char to get. + * @param end_pos Last char to get. + * @param all zero to get only selected chars. + * + * @return String with selected region (release it with free() + * + */ + LIB3270_EXPORT char * lib3270_get_region(H3270 *h, int start_pos, int end_pos, unsigned char all); + #endif // LIB3270_SELECTION_H_INCLUDED diff --git a/src/lib3270/selection.c b/src/lib3270/selection.c index 8eedc7c..6a2c92c 100644 --- a/src/lib3270/selection.c +++ b/src/lib3270/selection.c @@ -407,6 +407,41 @@ static char * get_text(H3270 *hSession,unsigned char all) return ret; } +LIB3270_EXPORT char * lib3270_get_region(H3270 *h, int start_pos, int end_pos, unsigned char all) +{ + char * text; + int maxlen; + int sz = 0; + int baddr; + + CHECK_SESSION_HANDLE(h); + + if(!lib3270_connected(h)) + return NULL; + + maxlen = h->rows * (h->cols+1); + + if(start_pos < 0 || start_pos > maxlen || end_pos < 0 || end_pos > maxlen || end_pos < start_pos) + return NULL; + + text = malloc(maxlen); + + for(baddr=start_pos;baddrtext[baddr].attr & LIB3270_ATTR_SELECTED) + text[sz++] = (h->text[baddr].attr & LIB3270_ATTR_CG) ? ' ' : h->text[baddr].chr; + + if((baddr%h->cols) == 0 && sz > 0) + text[sz++] = '\n'; + } + text[sz++] = 0; + + return realloc(text,sz); +} + + + + LIB3270_EXPORT char * lib3270_get_text(H3270 *h, int offset, int len) { char * buffer; @@ -468,25 +503,33 @@ LIB3270_EXPORT char * lib3270_get_selected(H3270 *hSession) return get_text(hSession,0); } -LIB3270_EXPORT int lib3270_get_selected_addr(H3270 *hSession, int *begin, int *end) +LIB3270_EXPORT int lib3270_get_selection_bounds(H3270 *hSession, int *start, int *end) { + int first, last; + CHECK_SESSION_HANDLE(hSession); if(!hSession->selected || hSession->select.begin == hSession->select.end) - return -1; + return 0; if(hSession->select.end > hSession->select.begin) { - *begin = hSession->select.begin; - *end = hSession->select.end; + first = hSession->select.begin; + last = hSession->select.end; } else { - *begin = hSession->select.end; - *end = hSession->select.begin; + first = hSession->select.end; + last = hSession->select.begin; } - return 0; + if(start) + *start = first; + + if(end) + *end = last; + + return 1; } LIB3270_EXPORT int lib3270_move_selected_area(H3270 *hSession, int from, int to) @@ -494,7 +537,7 @@ LIB3270_EXPORT int lib3270_move_selected_area(H3270 *hSession, int from, int to) int pos[2]; int rows, cols, f, step; - if(lib3270_get_selected_addr(hSession,&pos[0],&pos[1])) + if(!lib3270_get_selection_bounds(hSession,&pos[0],&pos[1])) return from; rows = (to / hSession->cols) - (from / hSession->cols); @@ -533,7 +576,7 @@ LIB3270_EXPORT int lib3270_drag_selection(H3270 *h, unsigned char flag, int orig { int first, last, row, col; - if(lib3270_get_selected_addr(h,&first,&last)) + if(!lib3270_get_selection_bounds(h,&first,&last)) return origin; flag &= 0x1f; -- libgit2 0.21.2