[PATCH] Backport to 1.2.4 of snake_oil+mem cleanups
- From: Emmanuel <e allaud wanadoo fr>
- To: balsa-list gnome org
- Subject: [PATCH] Backport to 1.2.4 of snake_oil+mem cleanups
- Date: Thu, 31 Jan 2002 11:57:14 +0100
Hi all,
here is the backport of Peter's snake_oil patch + my cleanups for
address-entry.c.
Bye
Manu
--- ../balsa-1.2.4/libbalsa/address-entry.c Tue Jan 15 20:47:56 2002
+++ balsa-1.2.4-peter/libbalsa/address-entry.c Wed Jan 30 19:34:16 2002
@@ -21,21 +21,6 @@
*/
/*
- * FIXME:
- *
- * Need to add credits, I think... How do we do that?
- *
- * Parts of this code is copied out of GTK+. GTK+ is licensed
- * under the LGPL, and Balsa under the GPL. The consensus among
- * all parties involved (Balsa maintainers, GTK+, and GNU (for
- * writing the license)) this is legal. The new and cut&pasted
- * code has to be GPL-ed.
- *
- * I would like to thank the GTK+ Authors at this point
- * for their work.
- */
-
-/*
* A subclass of gtkentry to support alias completion.
*/
@@ -49,12 +34,6 @@
#include <sys/stat.h>
#include <ctype.h>
-/* pawsa: the update of cursor pos is completely reduntant with gtk+-1.2.9
- and since the char_offsets happens to be shorter than computed cursor_pos,
- the entry tends to move the alignment left and right.
- I disable it.
-*/
-#define DISABLE_UPDATE_CUR_POS
/*
* LibBalsa includes.
*/
@@ -62,12 +41,6 @@
#include "address-entry.h"
/*
- * Internal API definitiions.
- */
-#define DRAW_TIMEOUT 20
-#define INNER_BORDER 2
-
-/*
* Global variable. We need this for destroying this widget.
*/
static GtkWidgetClass *parent_class = NULL;
@@ -87,25 +60,12 @@
inputData *libbalsa_inputData_new(void);
emailData *libbalsa_emailData_new(void);
void libbalsa_emailData_free(emailData *addy);
-static gint libbalsa_address_entry_timer(gpointer);
-static gint libbalsa_address_entry_find_position(LibBalsaAddressEntry *, gint);
-static void libbalsa_address_entry_make_backing_pixmap(LibBalsaAddressEntry *,
- gint, gint);
-static void libbalsa_address_entry_queue_draw(LibBalsaAddressEntry *);
-static void libbalsa_address_entry_draw_cursor_on_drawable(
- LibBalsaAddressEntry *, GdkDrawable *);
-static void libbalsa_address_entry_delete_text(GtkEditable *,
- unsigned, unsigned);
-static void libbalsa_address_entry_draw(GtkWidget *, GdkRectangle *);
static gint libbalsa_address_entry_button_press(GtkWidget *, GdkEventButton *);
-static void libbalsa_address_entry_draw_cursor(LibBalsaAddressEntry *);
-static void libbalsa_address_entry_draw_text(LibBalsaAddressEntry *);
static gint libbalsa_address_entry_key_press(GtkWidget *, GdkEventKey *);
inputData *libbalsa_address_entry_get_input(LibBalsaAddressEntry *entry);
void libbalsa_address_entry_set_input(LibBalsaAddressEntry *entry,
inputData *data);
void libbalsa_address_entry_show(LibBalsaAddressEntry *entry);
-void libbalsa_address_entry_set_text(LibBalsaAddressEntry *, const gchar *);
void libbalsa_force_no_match(emailData *);
void libbalsa_address_entry_clear_match(LibBalsaAddressEntry *);
void libbalsa_address_entry_set_focus(LibBalsaAddressEntry *, gint);
@@ -245,35 +205,10 @@
object_class->destroy = libbalsa_address_entry_destroy;
- gtk_widget_class->draw = libbalsa_address_entry_draw;
klass->gtk_entry_button_press = gtk_widget_class->button_press_event;
gtk_widget_class->button_press_event = libbalsa_address_entry_button_press;
gtk_widget_class->key_press_event = libbalsa_address_entry_key_press;
- /*
- * FIXME: PLEASE HELP!
- *
- * If I set the focus_out function here, GTK+ spits out error messages
- * a few times a second. According to gdb, these happen inside poll(),
- * inside GTK+.
- *
- * If src/sendmsg-window.c() assigns this function via
- * gtk_signal_connect(), and nothing else changes, the bug does
- * NOT appear.
- *
- * It is reproducable with:
- * - The current source.
- * - Using gtk+-1.2.8/gtk/gtkentry.c's focus_out() function.
- * - An empty focus_out() function.
- *
- * It appears to be a stray GtkObject reference somewhere, that
- * doesn't get released, which makes gtk/poll() call an invalid
- * widget.
- *
- * Berend De Schouwer <bds@jhb.ucs.co.za>
- */
-#if 0
gtk_widget_class->focus_out_event = libbalsa_address_entry_focus_out;
-#endif
}
@@ -468,6 +403,7 @@
g_return_if_fail(data != NULL);
g_list_foreach(data->list, (GFunc) libbalsa_emailData_free, NULL);
+ g_list_free(data->list);
g_free(data);
}
@@ -538,36 +474,25 @@
libbalsa_strsplit(const gchar *str, gchar delimiter)
{
GList *glist;
- gchar *data;
const gchar *old, *current;
- gint i, previous;
gboolean quoted;
- g_return_val_if_fail(str != NULL, NULL);
+ if (!str) return NULL;
quoted = FALSE;
glist = NULL;
- previous = 0;
- old = current = str;
- for (i = 0; str[i]; i++) {
- if (str[i] == '"') quoted = !quoted;
- if ( (!quoted) && (str[i] == delimiter) ) {
- data = g_strndup(old, i - previous);
- glist = g_list_append(glist, data);
- previous = i + 1;
- old = current;
- old++;
+ old = str;
+ for (current=str;*current;current++) {
+ if (*current == '"') quoted = !quoted;
+ else if ( (!quoted) && (*current == delimiter) ) {
+ glist = g_list_append(glist, g_strndup(old, current-old));
+ old=current+1;
}
- current++;
- }
- if (str) {
- data = g_strndup(old, i - previous);
- glist = g_list_append(glist, data);
}
+ glist = g_list_append(glist, g_strndup(old, current-old));
return glist;
}
-
/*************************************************************
* libbalsa_length_of_address:
* Calculated how long an address would be when it is
@@ -706,7 +631,7 @@
static inputData *
libbalsa_fill_input(LibBalsaAddressEntry *address_entry)
{
- gint cursor = 0, size = 0, prev = 0;
+ gint cursor, size, prev=0;
gchar *typed = NULL;
GList *el, *current;
GList *list = NULL;
@@ -723,30 +648,28 @@
input = libbalsa_inputData_new();
cursor = (gint) gtk_editable_get_position(GTK_EDITABLE(address_entry));
typed = gtk_editable_get_chars(GTK_EDITABLE(address_entry), 0, -1);
- if (typed == NULL)
+ if (!typed)
typed = g_strdup("");
/*
* Split the input string by comma, and store the result in
* input->list.
* str contains a list of e-mail addresses seperated by ','.
- *
- * FIXME: Breaks for '"Doe, John" <john@doe.com>'
*/
el = libbalsa_strsplit(typed, ',');
g_free(typed);
/*
* Store it all in a glist.
*/
- if (el != NULL) {
+ if (el) {
for (current = el;
- current != NULL;
+ current;
current = g_list_next(current)) {
addy = libbalsa_emailData_new();
- addy->user = g_strdup((gchar *)current->data);
+ addy->user = (gchar *)current->data;
input->list = g_list_append(input->list, addy);
}
- g_list_foreach(el, (GFunc)g_free, NULL);
+ g_list_free(el);
} else {
addy = libbalsa_emailData_new();
addy->user = g_strdup("");
@@ -758,69 +681,34 @@
* We have to match the cursor in GtkEntry to the list.
*/
g_assert(input->list != NULL);
- size = prev = 0;
- for (list = g_list_first(input->list);
- list != NULL;
- list = g_list_next(list)) {
- if (cursor >= size) {
- prev = size;
- input->active = list;
- }
+ size = 0;
+ for (list = g_list_first(input->list);list;list=g_list_next(list)) {
+ prev=size;
+ addy = (emailData *)list->data;
+ size += strlen(addy->user) + 1;
+ addy->user = g_strchug(addy->user);
+ if (cursor<size) break;
+ }
+ input->active = list;
+ /* Don't forget to strip out the leading space added because
+ the delimiter to split the addresses was just ',' so each
+ address begins with the space following the coma */
+ for (list = g_list_next(list);list;list=g_list_next(list)) {
addy = (emailData *)list->data;
- size = size + strlen(addy->user) + 1;
addy->user = g_strchug(addy->user);
}
-
addy = (emailData *)input->active->data;
addy->cursor = cursor - prev;
if (input->active != input->list)
- addy->cursor = addy->cursor - 1; /* Compensate for the ',' */
+ addy->cursor--; /* Compensate for the ',' */
if (addy->cursor < 0) addy->cursor = 0;
- if (addy->cursor > (tmp = strlen(addy->user)))
- addy->cursor = tmp;
+ tmp = strlen(addy->user);
+ if (addy->cursor > tmp)
+ addy->cursor = tmp;
return input;
}
-
-/*************************************************************
- * libbalsa_address_entry_set_text:
- * Sets the text string of a LibBalsaAddressEntry without
- * drawing the text.
- *
- * credits:
- * Modified from gtk+-1.2.8/gtk/gtkentry.c
- *
- * arguments:
- * address_entry: The LibBalsaAddressEntry to act on.
- * text: A gchar* string to set the text to.
- *
- * results:
- * Sets the text in the widget.
- *************************************************************/
-void
-libbalsa_address_entry_set_text(LibBalsaAddressEntry *address,
- const gchar *text)
-{
- gint tmp_pos;
-
- GtkEditable *editable;
-
- g_return_if_fail(address != NULL);
- g_return_if_fail(LIBBALSA_IS_ADDRESS_ENTRY(address));
- g_return_if_fail(text != NULL);
-
- editable = GTK_EDITABLE(address);
- libbalsa_address_entry_delete_text(editable, 0, -1);
-
- tmp_pos = 0;
- gtk_editable_insert_text(editable, text, strlen(text), &tmp_pos);
-
- editable->selection_start_pos = 0;
- editable->selection_end_pos = 0;
-}
-
-
/*************************************************************
* libbalsa_delete_line:
* Deletes the text string of a LibBalsaAddressEntry.
@@ -878,7 +766,7 @@
if (list != NULL) {
input->list = g_list_remove_link(input->list, list);
libbalsa_emailData_free(list->data);
- g_list_free(list);
+ g_list_free_1(list);
}
/*
@@ -894,13 +782,13 @@
input->active = NULL;
input->list = g_list_remove_link(input->list, list);
libbalsa_emailData_free(list->data);
- g_list_free(list);
+ g_list_free_1(list);
if (input->active != NULL) {
addy = input->active->data;
g_assert(addy != NULL);
addy->cursor = 0;
} else {
- libbalsa_address_entry_set_text(address_entry, "");
+ gtk_entry_set_text(GTK_ENTRY(address_entry), "");
libbalsa_inputData_free(address_entry->input);
address_entry->input = libbalsa_fill_input(address_entry);
}
@@ -947,7 +835,7 @@
if (list != NULL) {
input->list = g_list_remove_link(input->list, list);
libbalsa_emailData_free(list->data);
- g_list_free(list);
+ g_list_free_1(list);
}
/*
@@ -964,17 +852,13 @@
}
input->list = g_list_remove_link(input->list, list);
libbalsa_emailData_free(list->data);
- /*
- list->next = NULL;
- list->prev = NULL;
- */
- g_list_free(list);
+ g_list_free_1(list);
if (input->active != NULL) {
addy = input->active->data;
g_assert(addy != NULL);
addy->cursor = strlen(addy->user);
} else {
- libbalsa_address_entry_set_text(address_entry, "");
+ gtk_entry_set_text(GTK_ENTRY(address_entry), "");
libbalsa_inputData_free(address_entry->input);
address_entry->input = libbalsa_fill_input(address_entry);
}
@@ -1019,440 +903,18 @@
/*
* Free all the following data.
*/
- for (list = g_list_next(input->active);
- list != NULL;
- list = g_list_next(input->active)) {
- /*
- * Concatenate the two e-mails.
- */
- libbalsa_emailData_free(list->data);
- input->list = g_list_remove_link(input->list, list);
- list->data = NULL;
- list->prev = NULL;
- list->next = NULL;
- g_list_free(list);
- }
+ g_list_foreach(g_list_next(input->active),(GFunc)libbalsa_emailData_free,NULL);
+ g_list_free(g_list_next(input->active));
+
+ /* input->active must be the last address */
+ input->active->next=NULL;
+
/* libbalsa_inputData_free(address_entry->input);
* look above: the line below is not necessary */
/* address_entry->input = input; */
libbalsa_address_entry_show(address_entry);
}
-
-/*************************************************************
- * libbalsa_address_entry_timer:
- * Is this used to keep it thread-safe? (late at night)
- * Attempts to call draw_text() if the timer expires.
- *
- * credits:
- * This is stolen from gtk+-1.2.8/gtk/gtkentry.c
- *
- * arguments:
- * address_entry: The LibBalsaAddressEntry to act on.
- *
- * results:
- * ???
- *************************************************************/
-static gint
-libbalsa_address_entry_timer(gpointer data)
-{
- LibBalsaAddressEntry *address_entry;
- GtkEntry *entry;
-
- GDK_THREADS_ENTER ();
-
- address_entry = LIBBALSA_ADDRESS_ENTRY(data);
- entry = GTK_ENTRY(data);
- entry->timer = 0;
-
- GDK_THREADS_LEAVE ();
- return TRUE;
-}
-
-
-/*************************************************************
- * libbalsa_address_entry_find_position:
- * Find the cursor position?
- *
- * credits:
- * This is stolen from gtk+-1.2.8/gtk/gtkentry.c
- *
- * arguments:
- * address_entry: The LibBalsaAddressEntry to act on.
- * x: ???
- *
- * results:
- * ???
- *************************************************************/
-static gint
-libbalsa_address_entry_find_position(LibBalsaAddressEntry *address_entry,
- gint x)
-{
- GtkEntry *entry;
- gint start = 0;
- gint end;
- gint half;
-
- g_return_val_if_fail(address_entry != NULL, 0);
- g_return_val_if_fail(LIBBALSA_IS_ADDRESS_ENTRY(address_entry), 0);
-
- entry = GTK_ENTRY(address_entry);
- end = entry->text_length;
- if (x <= 0)
- return 0;
- if (x >= entry->char_offset[end])
- return end;
-
- /* invariant - char_offset[start] <= x < char_offset[end] */
-
- while (start != end) {
- half = (start+end)/2;
- if (half == start)
- return half;
- else if (entry->char_offset[half] <= x)
- start = half;
- else
- end = half;
- }
- return start;
-}
-
-
-/*************************************************************
- * libbalsa_address_entry_make_backing_pixmap:
- * Makes a pixmap to draw on if we don't use the widget
- * directly.
- *
- * credits:
- * This is stolen from gtk+-1.2.8/gtk/gtkentry.c
- *
- * arguments:
- * address_entry: The LibBalsaAddressEntry to act on.
- * width: ???
- * height: ???
- *
- * results:
- * ???
- *************************************************************/
-static void
-libbalsa_address_entry_make_backing_pixmap(LibBalsaAddressEntry *address_entry,
- gint width, gint height)
-{
- GtkEntry *entry;
- gint pixmap_width, pixmap_height;
-
- g_return_if_fail(address_entry != NULL);
- g_return_if_fail(LIBBALSA_IS_ADDRESS_ENTRY(address_entry));
-
- entry = GTK_ENTRY(address_entry);
- if (!entry->backing_pixmap) {
- /* allocate */
- entry->backing_pixmap = gdk_pixmap_new(entry->text_area,
- width, height, -1);
- } else {
- /* reallocate if sizes don't match */
- gdk_window_get_size(entry->backing_pixmap,
- &pixmap_width, &pixmap_height);
- if ((pixmap_width != width) || (pixmap_height != height)) {
- gdk_pixmap_unref(entry->backing_pixmap);
- entry->backing_pixmap = gdk_pixmap_new(entry->text_area,
- width, height, -1);
- }
- }
-}
-
-
-/*************************************************************
- * libbalsa_address_entry_queue_draw:
- * ???
- *
- * credits:
- * This is stolen from gtk+-1.2.8/gtk/gtkentry.c
- *
- * arguments:
- * address_entry: The LibBalsaAddressEntry to act on.
- *
- * results:
- * Sets the text in the widget.
- *************************************************************/
-static void
-libbalsa_address_entry_queue_draw(LibBalsaAddressEntry *address_entry)
-{
- GtkEntry *entry;
- g_return_if_fail(address_entry != NULL);
- g_return_if_fail(LIBBALSA_IS_ADDRESS_ENTRY(address_entry));
-
- entry = GTK_ENTRY(address_entry);
- if (!entry->timer)
- entry->timer = gtk_timeout_add(DRAW_TIMEOUT,
- libbalsa_address_entry_timer, entry);
-}
-
-
-/*************************************************************
- * libbalsa_address_entry_delete_text:
- * ???
- *
- * credits:
- * This is stolen from gtk+-1.2.8/gtk/gtkentry.c
- *
- * arguments:
- * editable: ???
- * start_pos: ???
- * end_pos: ???
- *
- * results:
- * Modifies the text in the widget.
- *************************************************************/
-static void
-libbalsa_address_entry_delete_text(GtkEditable *editable,
- unsigned start_pos, unsigned end_pos)
-{
- GdkWChar *text;
- gint deletion_length;
- unsigned i;
- GtkEntry *entry;
-
- g_return_if_fail(editable != NULL);
- g_return_if_fail(LIBBALSA_IS_ADDRESS_ENTRY(editable));
-
- entry = GTK_ENTRY(editable);
-
- if (end_pos == (unsigned) -1)
- end_pos = entry->text_length;
-
- if (editable->selection_start_pos > start_pos)
- editable->selection_start_pos -= MIN(end_pos, editable->selection_start_pos) - start_pos;
- if (editable->selection_end_pos > start_pos)
- editable->selection_end_pos -= MIN(end_pos, editable->selection_end_pos) - start_pos;
-
- if ((start_pos < end_pos) &&
- (start_pos >= 0) &&
- (end_pos <= entry->text_length)) {
- text = entry->text;
- deletion_length = end_pos - start_pos;
-
- /* Fix up the character offsets */
- if (GTK_WIDGET_REALIZED (entry)) {
- gint deletion_width =
- entry->char_offset[end_pos] - entry->char_offset[start_pos];
- for (i = 0; i <= entry->text_length - end_pos; i++)
- entry->char_offset[start_pos+i] =
- entry->char_offset[end_pos+i] - deletion_width;
- }
-
- for (i = end_pos; i < entry->text_length; i++)
- text[i - deletion_length] = text[i];
-
- for (i = entry->text_length - deletion_length; i < entry->text_length; i++)
- text[i] = '\0';
- entry->text_length -= deletion_length;
- editable->current_pos = start_pos;
- }
-
- entry->text_mb_dirty = 1;
- libbalsa_address_entry_queue_draw (LIBBALSA_ADDRESS_ENTRY(editable));
-}
-
-
-/*************************************************************
- * libbalsa_address_entry_draw_cursor_on_drawable:
- * For once, its clear :) Maybe.
- * Usually you'll want to use
- * libbalsa_address_entry_draw_cursor() instead.
- *
- * credits:
- * This is stolen from gtk+-1.2.8/gtk/gtkentry.c
- *
- * arguments:
- * address_entry: the widget.
- * drawable: foreground or background.
- *
- * results:
- * None? Changes the appearance of the widget.
- *************************************************************/
-static void
-libbalsa_address_entry_draw_cursor_on_drawable(
- LibBalsaAddressEntry *address_entry, GdkDrawable *drawable)
-{
- GtkWidget *widget;
- GtkEditable *editable;
- GtkEntry *entry;
- gint xoffset;
- gint text_area_height;
-
- g_return_if_fail(address_entry != NULL);
- g_return_if_fail(LIBBALSA_IS_ADDRESS_ENTRY(address_entry));
-
- entry = GTK_ENTRY(address_entry);
- widget = GTK_WIDGET (entry);
- editable = GTK_EDITABLE (entry);
-
- if (! (GTK_WIDGET_DRAWABLE(entry))) return;
-
- xoffset = INNER_BORDER + entry->char_offset[editable->current_pos];
- xoffset -= entry->scroll_offset;
- gdk_window_get_size (entry->text_area, NULL, &text_area_height);
-
- if (GTK_WIDGET_HAS_FOCUS(widget) &&
- (editable->selection_start_pos == editable->selection_end_pos)) {
- gdk_draw_line(drawable, widget->style->fg_gc[GTK_STATE_NORMAL],
- xoffset, INNER_BORDER,
- xoffset, text_area_height - INNER_BORDER);
- } else {
- gint yoffset =
- (text_area_height -
- (widget->style->font->ascent + widget->style->font->descent)) / 2
- + widget->style->font->ascent;
- gtk_paint_flat_box(widget->style, drawable,
- GTK_WIDGET_STATE(widget), GTK_SHADOW_NONE,
- NULL, widget, "entry_bg",
- xoffset, INNER_BORDER,
- 1, text_area_height - INNER_BORDER);
-
- /*
- * Draw the character under the cursor again
- */
- if ((editable->current_pos < entry->text_length) &&
- (editable->selection_start_pos == editable->selection_end_pos)) {
- GdkWChar c = editable->visible ?
- *(entry->text + editable->current_pos) :
- '*';
-
- gdk_draw_text_wc(drawable, widget->style->font,
- widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
- xoffset, yoffset, &c, 1);
- }
- }
-
- /*
- * This #ifdef won't ever be true in Balsa. Does this break
- * things if GTK was compiled with USE_XIM?
- */
-#ifdef USE_XIM
- if (GTK_WIDGET_HAS_FOCUS(widget) && gdk_im_ready() && editable->ic &&
- (gdk_ic_get_style (editable->ic) & GDK_IM_PREEDIT_POSITION)) {
- editable->ic_attr->spot_location.x = xoffset;
- editable->ic_attr->spot_location.y =
- (text_area_height + (widget->style->font->ascent
- - widget->style->font->descent) + 1) / 2;
- gdk_ic_set_attr(editable->ic, editable->ic_attr, GDK_IC_SPOT_LOCATION);
- }
-#endif
-}
-
-
-/*************************************************************
- * libbalsa_address_entry_draw_cursor:
- * Draws the cursor.
- *
- * credits:
- * This is stolen from gtk+-1.2.8/gtk/gtkentry.c
- *
- * arguments:
- * address_entry: the widget.
- *
- * results:
- * None? Changes the appearance of the widget.
- *************************************************************/
-static void
-libbalsa_address_entry_draw_cursor(LibBalsaAddressEntry *address_entry)
-{
- g_return_if_fail(address_entry != NULL);
- g_return_if_fail(LIBBALSA_IS_ADDRESS_ENTRY(address_entry));
-
- libbalsa_address_entry_draw_cursor_on_drawable(address_entry,
- GTK_ENTRY(address_entry)->text_area);
-}
-
-
-/*************************************************************
- * libbalsa_address_entry_draw:
- * Draws the entire widget.
- *
- * credits:
- * This is stolen from gtk+-1.2.8/gtk/gtkentry.c
- *
- * arguments:
- * widget: the widget.
- * area: ignored.
- *
- * results:
- * None? Changes the appearance of the widget.
- *************************************************************/
-static void
-libbalsa_address_entry_draw(GtkWidget *widget, GdkRectangle *area)
-{
- g_return_if_fail(widget != NULL);
- g_return_if_fail(LIBBALSA_IS_ADDRESS_ENTRY(widget));
- g_return_if_fail(area != NULL);
-
- if (GTK_WIDGET_DRAWABLE(widget)) {
- gtk_widget_draw_focus(widget);
- libbalsa_address_entry_draw_text(LIBBALSA_ADDRESS_ENTRY(widget));
- }
-}
-
-
-/*************************************************************
- * libbalsa_address_entry_adjust_scroll:
- * ???
- *
- * credits:
- * This is stolen from gtk+-1.2.8/gtk/gtkentry.c
- *
- * arguments:
- * address_entry: the widget.
- *
- * results:
- * None? Changes the appearance of the widget.
- *************************************************************/
-static void
-libbalsa_address_entry_adjust_scroll(LibBalsaAddressEntry *address_entry)
-{
- GtkEntry *entry;
- gint xoffset, max_offset;
- gint text_area_width;
-
- g_return_if_fail(address_entry != NULL);
- g_return_if_fail(LIBBALSA_IS_ADDRESS_ENTRY(address_entry));
-
- entry = GTK_ENTRY(address_entry);
- if (!entry->text_area)
- return;
-
- gdk_window_get_size(entry->text_area, &text_area_width, NULL);
- text_area_width -= 2 * INNER_BORDER;
-
- /* Display as much text as we can */
- max_offset = MAX(0,
- entry->char_offset[entry->text_length] - text_area_width);
-
- if (entry->scroll_offset > max_offset)
- entry->scroll_offset = max_offset;
-
- /* And make sure cursor is on screen. Note that the cursor is
- * actually drawn one pixel into the INNER_BORDER space on
- * the right, when the scroll is at the utmost right. This
- * looks better to to me than confining the cursor inside the
- * border entirely, though it means that the cursor gets one
- * pixel closer to the the edge of the widget on the right than
- * on the left. This might need changing if one changed
- * INNER_BORDER from 2 to 1, as one would do on a
- * small-screen-real-estate display.
- */
- xoffset = entry->char_offset[GTK_EDITABLE(entry)->current_pos];
- xoffset -= entry->scroll_offset;
-
- if (xoffset < 0)
- entry->scroll_offset += xoffset;
- else if (xoffset > text_area_width)
- entry->scroll_offset += xoffset - text_area_width;
-
- gtk_widget_queue_draw(GTK_WIDGET(entry));
-}
-
-
/*************************************************************
* libbalsa_address_entry_button_press:
* This gets called when the user clicks a mouse button.
@@ -1545,7 +1007,7 @@
{
GtkEditable *editable;
emailData *addy, *extra;
- gchar *left, *right, *str;
+ gchar *p,*str;
GList *list;
unsigned i;
inputData *input;
@@ -1592,8 +1054,7 @@
*/
input->list = g_list_remove_link(input->list, input->active);
libbalsa_emailData_free(addy);
- input->active->data = NULL;
- g_list_free(input->active);
+ g_list_free_1(input->active);
input->active = list;
}
@@ -1601,18 +1062,12 @@
* Normal character needs deleting.
*/
} else {
- left = g_strndup(addy->user, (addy->cursor - 1));
- right = addy->user;
- for (i = 0; i < addy->cursor; i++) right++;
- str = g_strconcat(left, right, NULL);
- g_free(addy->user);
- g_free(left);
- addy->user = str;
- addy->cursor--;
- if (*str == '\0')
- libbalsa_force_no_match(addy);
- else if (address_entry->find_match)
- (*address_entry->find_match) (addy, TRUE);
+ addy->cursor--;
+ for (p=addy->user+addy->cursor;*p;p++) *p=*(p+1);
+ if (!*(addy->user))
+ libbalsa_force_no_match(addy);
+ else if (address_entry->find_match)
+ (*address_entry->find_match) (addy, TRUE);
}
}
@@ -1640,7 +1095,7 @@
{
GtkEditable *editable;
emailData *addy, *extra;
- gchar *left, *right, *str;
+ gchar *p, *str;
GList *list;
inputData *input;
@@ -1680,21 +1135,13 @@
*/
input->list = g_list_remove_link(input->list, list);
libbalsa_emailData_free(extra);
- list->data = NULL;
- g_list_free(list);
+ g_list_free_1(list);
}
/*
* Normal character needs deleting.
*/
} else {
- unsigned i;
- left = g_strndup(addy->user, addy->cursor);
- right = addy->user;
- for (i = 0; i <= addy->cursor; i++) right++;
- str = g_strconcat(left, right, NULL);
- g_free(addy->user);
- g_free(left);
- addy->user = str;
+ for (p=addy->user+addy->cursor;*p;p++) *p=*(p+1);
}
}
@@ -2118,7 +1565,7 @@
*/
input = address_entry->input;
addy = input->active->data;
- if (input->active == g_list_last(input->list)) {
+ if (!g_list_next(input->active)) {
if (addy->cursor >= strlen(addy->user) && (addy->match == NULL)) {
libbalsa_accept_match(address_entry);
gtk_widget_activate(GTK_WIDGET(address_entry));
@@ -2161,7 +1608,7 @@
gint address_start;
gboolean found;
emailData *addy;
- gint pos;
+ gint pos,tmp;
g_return_val_if_fail(address_entry != NULL, NULL);
g_return_val_if_fail(LIBBALSA_IS_ADDRESS_ENTRY(address_entry), NULL);
@@ -2174,17 +1621,20 @@
(list != NULL) && (found == FALSE);
list = g_list_next(list)) {
addy = (emailData *)list->data;
- address_start += libbalsa_length_of_address(addy);
+ tmp=libbalsa_length_of_address(addy);
+ address_start += tmp;
if (pos <= address_start) {
found = TRUE;
- *cursor = libbalsa_length_of_address(addy) - (address_start - pos);
+ *cursor = tmp - (address_start - pos);
}
address_start += 2; /* strlen(", ") */
previous = list;
}
g_assert(found == TRUE);
if(*cursor<0) { /* error, correct it and print a warning.
- This needs to be fixed in long term. */
+ This needs to be fixed in long term.
+ I found where this is triggered, I'll try
+ to fix it definitely (MANU)*/
*cursor = 0;
g_warning("libbalsa_find_list_entry failed to compute the cursor.\n"
"find a way to reproduce it and report it.");
@@ -2192,46 +1642,6 @@
return previous;
}
-#ifndef DISABLE_UPDATE_CUR_POS
-/*************************************************************
- * libbalsa_address_entry_update_cursor_pos:
- * Sets the cursor position without modifying the
- * selection information.
- *
- * arguments:
- * address_entry: the widget.
- *
- * results:
- * modifies address_entry->current_pos;
- *************************************************************/
-static void
-libbalsa_address_entry_update_cursor_pos(LibBalsaAddressEntry *address_entry)
-{
- GList *list;
- gint i;
- gboolean found;
- emailData *addy;
-
- g_return_if_fail(address_entry != NULL);
- g_return_if_fail(LIBBALSA_IS_ADDRESS_ENTRY(address_entry));
-
- i = 0;
- found = FALSE;
- for (list = address_entry->input->list;
- (list != NULL) && (found == FALSE);
- list = g_list_next(list)) {
- if (list == address_entry->input->active) {
- found = TRUE;
- addy = (emailData *)list->data;
- i = i + addy->cursor;
- } else {
- addy = (emailData *)list->data;
- i = i + strlen(addy->user) + 2;
- }
- }
- GTK_EDITABLE(address_entry)->current_pos = i;
-}
-#endif
/*************************************************************
* libbalsa_force_expand:
* force alias expansion.
@@ -2296,7 +1706,7 @@
GtkEditable *editable;
GList *start, *end, *list;
gint start_pos, end_pos;
- gchar *str, *left, *right, *new;
+ gchar *str, *left, *new;
emailData *addy;
gint i;
size_t tmp;
@@ -2328,12 +1738,11 @@
addy = start->data;
str = libbalsa_make_address_string(addy);
libbalsa_force_no_match(addy);
- left = g_strndup(str, start_pos);
- right = str;
- for (i = 0; i < end_pos; i++) right++;
- new = g_strconcat(left, right, NULL);
- g_free(str); /* also does g_free(right); */
- g_free(left);
+ /* First we cut the string at the start_pos */
+ str[start_pos]='\0';
+ /* The we concat the first part with the end part */
+ new = g_strconcat(str, str+end_pos, NULL);
+ g_free(str);
g_free(addy->user);
addy->user = new;
addy->cursor = start_pos;
@@ -2363,10 +1772,8 @@
addy = end->data;
str = libbalsa_make_address_string(addy);
libbalsa_force_no_match(addy);
- right = str;
- for (i = 0; i < end_pos; i++) right++;
g_free(addy->user);
- addy->user = g_strdup(right);
+ addy->user = g_strdup(str+end_pos);
g_free(str);
/*
@@ -2379,13 +1786,15 @@
/*
* Delete the GList inbetween(!)
*/
- for (list = g_list_next(start);
- list != end;
- list = g_list_next(start)) {
- libbalsa_emailData_free(list->data);
- list->data = NULL;
- g_list_remove_link(address_entry->input->list, list);
- }
+ /* Unlink the part of the list to be deleted */
+ start->next->prev=NULL;
+ end->prev->next=NULL;
+ /* Free the unlinked part */
+ g_list_foreach(start->next,(GFunc)libbalsa_emailData_free,NULL);
+ g_list_free(start->next);
+ /* Re-link the remaining parts */
+ start->next=end;
+ end->prev=start;
}
editable->selection_start_pos = editable->selection_end_pos = 0;
@@ -2595,10 +2004,6 @@
break;
}
-#ifndef DISABLE_UPDATE_CUR_POS
- libbalsa_address_entry_update_cursor_pos(address_entry);
-#endif
-
/*
* Since we emit signals from within the above code,
* the widget might already be destroyed or at least
@@ -2624,8 +2029,6 @@
gtk_editable_claim_selection(editable,
editable->selection_start_pos != editable->selection_end_pos,
event->time);
- libbalsa_address_entry_adjust_scroll(address_entry);
- libbalsa_address_entry_queue_draw(address_entry);
}
/*
@@ -2635,217 +2038,6 @@
return return_val;
}
-
-/*************************************************************
- * libbalsa_address_entry_draw_text:
- * Draws the widget.
- *
- * credits:
- * Most of this comes from gtk+-1.2.8/gtk/gtkentry.c
- *
- * arguments:
- * address_entry: the widget.
- *
- * results:
- * modifies address_entry
- *
- * caveat:
- * GTK doesn't offer multiple highlight colours, so we can
- * only highlight either the selection, or the alias.
- * Since the selection is a USER action, the selection
- * gets preference in the highlight.
- *************************************************************/
-static void
-libbalsa_address_entry_draw_text(LibBalsaAddressEntry *address_entry)
-{
- GtkWidget *widget;
- GtkEditable *editable;
- GtkEntry *entry;
-
- GtkStateType selected_state;
- gint start_pos;
- gint end_pos;
- gint start_xoffset;
- gint colour_start_pos;
- gint colour_end_pos;
- gint colour_start_xoffset;
- gint colour_end_xoffset;
- gint width, height;
- gint y;
- GdkDrawable *drawable;
- gint use_backing_pixmap;
- GdkWChar *stars;
- GdkWChar *toprint;
-
- g_return_if_fail(address_entry != NULL);
- g_return_if_fail(LIBBALSA_IS_ADDRESS_ENTRY(address_entry));
-
- widget = GTK_WIDGET(address_entry);
- editable = GTK_EDITABLE(address_entry);
- entry = GTK_ENTRY(address_entry);
-
- /*
- * What is this used for???
- */
- if (entry->timer) {
- gtk_timeout_remove(entry->timer);
- entry->timer = 0;
- }
-
- /*
- * Don't draw it if we don't have to.
- */
- if (! (GTK_WIDGET_DRAWABLE(address_entry))) return;
-
- /*
- * If there is no text, draw a rectangle.
- */
- if (!entry->text) {
- gtk_paint_flat_box(widget->style, entry->text_area,
- GTK_WIDGET_STATE(widget), GTK_SHADOW_NONE,
- NULL, widget, "entry_bg",
- 0, 0, -1, -1);
- if (editable->editable)
- libbalsa_address_entry_draw_cursor(address_entry);
- return;
- }
-
- gdk_window_get_size (entry->text_area, &width, &height);
-
- g_assert(entry->text != NULL);
- /*
- * If the widget has focus, draw on a backing pixmap to avoid flickering
- * and copy it to the text_area.
- * Otherwise draw to text_area directly for better speed.
- */
- use_backing_pixmap = GTK_WIDGET_HAS_FOCUS(widget) && (entry->text != NULL);
- if (use_backing_pixmap) {
- libbalsa_address_entry_make_backing_pixmap
- (address_entry, width, height);
- drawable = entry->backing_pixmap;
- } else {
- drawable = entry->text_area;
- }
-
- gtk_paint_flat_box(widget->style, drawable,
- GTK_WIDGET_STATE(widget), GTK_SHADOW_NONE,
- NULL, widget, "entry_bg",
- 0, 0, width, height);
-
- y = (height - (widget->style->font->ascent + widget->style->font->descent))
- / 2;
- y += widget->style->font->ascent;
-
- start_pos = libbalsa_address_entry_find_position(address_entry,
- entry->scroll_offset);
- start_xoffset = entry->char_offset[start_pos] - entry->scroll_offset;
-
- end_pos = libbalsa_address_entry_find_position(address_entry,
- entry->scroll_offset + width);
- if (end_pos < entry->text_length)
- end_pos += 1;
-
- /*
- * First, grab the selection...
- */
- colour_start_pos = MIN(editable->selection_start_pos,
- editable->selection_end_pos);
- colour_end_pos = MAX(editable->selection_start_pos,
- editable->selection_end_pos);
-
- /*
- * If there was no selection, grab the alias colour positions.
- */
- if (colour_start_pos == colour_end_pos) {
- colour_start_pos = MIN(address_entry->alias_start_pos,
- address_entry->alias_end_pos);
- colour_end_pos = MAX(address_entry->alias_start_pos,
- address_entry->alias_end_pos);
- }
-
- /*
- * Do we need to colour at all?
- */
- if (editable->has_selection || (colour_start_pos != colour_end_pos))
- selected_state = GTK_STATE_SELECTED;
- else
- selected_state = GTK_STATE_ACTIVE;
-
- /*
- * Now clamp the values: Make sure they are valid.
- */
- colour_start_pos = CLAMP(colour_start_pos, start_pos, end_pos);
- colour_end_pos = CLAMP(colour_end_pos, start_pos, end_pos);
-
- colour_start_xoffset =
- entry->char_offset[colour_start_pos] - entry->scroll_offset;
- colour_end_xoffset =
- entry->char_offset[colour_end_pos] - entry->scroll_offset;
-
- /*
- * if editable->visible, print a bunch of stars.
- * If not, print the standard text.
- */
- if (editable->visible) {
- toprint = entry->text + start_pos;
- } else {
- gint i;
- stars = g_new(GdkWChar, end_pos - start_pos);
- for (i = 0; i < end_pos - start_pos; i++)
- stars[i] = '*';
- toprint = stars;
- }
-
- if (colour_start_pos > start_pos) {
- gdk_draw_text_wc(drawable, widget->style->font,
- widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
- INNER_BORDER + start_xoffset, y,
- toprint,
- colour_start_pos - start_pos);
- }
-
- if ((colour_end_pos >= start_pos) &&
- (colour_start_pos < end_pos) &&
- (colour_start_pos != colour_end_pos)) {
- gtk_paint_flat_box(widget->style, drawable,
- selected_state, GTK_SHADOW_NONE,
- NULL, widget, "text",
- INNER_BORDER + colour_start_xoffset,
- INNER_BORDER,
- colour_end_xoffset - colour_start_xoffset,
- height - 2*INNER_BORDER);
- gdk_draw_text_wc(drawable, widget->style->font,
- widget->style->fg_gc[selected_state],
- INNER_BORDER + colour_start_xoffset, y,
- toprint + colour_start_pos - start_pos,
- colour_end_pos - colour_start_pos);
- }
-
- if (colour_end_pos < end_pos) {
- gdk_draw_text_wc(drawable, widget->style->font,
- widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
- INNER_BORDER + colour_end_xoffset, y,
- toprint + colour_end_pos - start_pos,
- end_pos - colour_end_pos);
- }
-
- /*
- * free the space allocated for the stars if it's neccessary.
- */
- if (!editable->visible)
- g_free (toprint);
-
- if (editable->editable)
- libbalsa_address_entry_draw_cursor_on_drawable(address_entry, drawable);
-
- if (use_backing_pixmap)
- gdk_draw_pixmap(entry->text_area,
- widget->style->fg_gc[GTK_STATE_NORMAL],
- entry->backing_pixmap,
- 0, 0, 0, 0, width, height);
-}
-
-
/*************************************************************
* libbalsa_address_entry_show:
* Shows the widget. This will work out the aliases,
@@ -2898,11 +2090,7 @@
*/
addy = (emailData *)list->data;
g_assert(addy != NULL);
- if (addy->match != NULL) {
- out = g_strconcat("", addy->user, " (", addy->match, ")", NULL);
- } else {
- out = g_strdup(addy->user);
- }
+ out = libbalsa_make_address_string(addy);
/*
* Copy the string, adding a delimiter if need be.
*/
@@ -2938,13 +2126,11 @@
start = editable->selection_start_pos;
end = editable->selection_end_pos;
tmp_pos = 0;
- libbalsa_address_entry_delete_text(editable, 0, -1);
+ gtk_editable_delete_text(editable, 0, -1);
gtk_editable_insert_text(editable, show->str, show->len, &tmp_pos);
- gtk_editable_set_position(GTK_EDITABLE(address_entry), cursor);
- editable->selection_start_pos = start;
- editable->selection_end_pos = end;
- libbalsa_address_entry_draw_text(address_entry);
+ gtk_editable_set_position(editable, cursor);
g_string_free(show, TRUE);
+ gtk_editable_select_region(editable, start, end);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]