qulogic/libgnt

propagate from branch 'im.pidgin.pidgin' (head 1842d086cbc0c2d27de9e49f5c3a4fd452a1f066)
to branch 'im.pidgin.cpw.malu.xmpp.google_refactor' (head 199b6ca254059e71e56ea84dee0df9aa14890325)
  • +58 -59
    gntbox.c
  • +60 -0
    gntentry.c
  • +2 -0
    gntentry.h
  • --- a/gntbox.c Sun Feb 21 00:11:56 2010 +0000
    +++ b/gntbox.c Fri Apr 09 22:14:51 2010 +0000
    @@ -27,6 +27,9 @@
    #include <string.h>
    +#define PROP_LAST_RESIZE_S "last-resize"
    +#define PROP_SIZE_QUEUED_S "size-queued"
    +
    enum
    {
    PROP_0,
    @@ -194,7 +197,7 @@
    GntBox *box = GNT_BOX(widget);
    GList *iter;
    int maxw = 0, maxh = 0;
    -
    +
    g_list_foreach(box->list, (GFunc)gnt_widget_size_request, NULL);
    for (iter = box->list; iter; iter = iter->next)
    @@ -398,6 +401,7 @@
    GList *iter;
    GntBox *box = GNT_BOX(widget);
    int wchange, hchange;
    + GntWidget *child, *last;
    if (!box->list)
    return TRUE;
    @@ -406,67 +410,62 @@
    hchange = widget->priv.height - height;
    if (wchange == 0 && hchange == 0)
    - return TRUE; /* Quit playing games */
    + return TRUE; /* Quit playing games with my size */
    - /* XXX: Right now, I am trying to just apply all the changes to
    - * just one widget. It should be possible to distribute the
    - * changes to all the widgets in the box. */
    - for (iter = box->list; iter; iter = iter->next)
    - {
    + child = NULL;
    + last = g_object_get_data(G_OBJECT(box), PROP_LAST_RESIZE_S);
    +
    + /* First, make sure all the widgets will fit into the box after resizing. */
    + for (iter = box->list; iter; iter = iter->next) {
    GntWidget *wid = iter->data;
    int w, h;
    gnt_widget_get_size(wid, &w, &h);
    - if (gnt_widget_confirm_size(wid, w - wchange, h - hchange))
    - {
    - GList *i;
    -
    - for (i = box->list; i; i = i->next)
    - {
    - int tw, th;
    - if (i == iter) continue;
    - gnt_widget_get_size(GNT_WIDGET(i->data), &tw, &th);
    - if (box->vertical)
    - {
    - if (!gnt_widget_confirm_size(i->data, tw - wchange, th)) {
    - /* If we are decreasing the size and the widget is going
    - * to be too large to fit into the box, then do not allow
    - * resizing. */
    - if (wchange > 0 && tw >= widget->priv.width)
    - return FALSE;
    - }
    - }
    - else
    - {
    - if (!gnt_widget_confirm_size(i->data, tw, th - hchange)) {
    - if (hchange > 0 && th >= widget->priv.height)
    - return FALSE;
    - return FALSE;
    - }
    - }
    - }
    -#if 0
    - gnt_widget_set_size(wid, w - wchange, h - hchange);
    - if (box->vertical)
    - hchange = 0;
    - else
    - wchange = 0;
    -
    - for (i = box->list; i; i = i->next)
    - {
    - int tw, th;
    - if (i == iter) continue;
    - gnt_widget_get_size(GNT_WIDGET(i->data), &tw, &th);
    - gnt_widget_set_size(i->data, tw - wchange, th - hchange);
    - }
    -#endif
    - g_object_set_data(G_OBJECT(box), "size-queued", wid);
    - return TRUE;
    + if (wid != last && !child && w > 0 && h > 0 && gnt_widget_confirm_size(wid, w - wchange, h - hchange)) {
    + child = wid;
    + break;
    }
    }
    - return FALSE;
    + if (!child && (child = last)) {
    + int w, h;
    + gnt_widget_get_size(child, &w, &h);
    + if (!gnt_widget_confirm_size(child, w - wchange, h - hchange))
    + child = NULL;
    + }
    +
    + g_object_set_data(G_OBJECT(box), PROP_SIZE_QUEUED_S, child);
    +
    + if (child) {
    + for (iter = box->list; iter; iter = iter->next) {
    + GntWidget *wid = iter->data;
    + int w, h;
    +
    + if (wid == child)
    + continue;
    +
    + gnt_widget_get_size(wid, &w, &h);
    + if (box->vertical) {
    + /* For a vertical box, if we are changing the width, make sure the widgets
    + * in the box will fit after resizing the width. */
    + if (wchange > 0 &&
    + w >= child->priv.width &&
    + !gnt_widget_confirm_size(wid, w - wchange, h))
    + return FALSE;
    + } else {
    + /* If we are changing the height, make sure the widgets in the box fit after
    + * the resize. */
    + if (hchange > 0 &&
    + h >= child->priv.height &&
    + !gnt_widget_confirm_size(wid, w, h - hchange))
    + return FALSE;
    + }
    +
    + }
    + }
    +
    + return (child != NULL);
    }
    static void
    @@ -477,16 +476,16 @@
    GntBox *box = GNT_BOX(widget);
    GntWidget *wid;
    int tw, th;
    -
    +
    wchange = widget->priv.width - oldw;
    hchange = widget->priv.height - oldh;
    -
    - wid = g_object_get_data(G_OBJECT(box), "size-queued");
    - if (wid)
    - {
    +
    + wid = g_object_get_data(G_OBJECT(box), PROP_SIZE_QUEUED_S);
    + if (wid) {
    gnt_widget_get_size(wid, &tw, &th);
    gnt_widget_set_size(wid, tw + wchange, th + hchange);
    - g_object_set_data(G_OBJECT(box), "size-queued", NULL);
    + g_object_set_data(G_OBJECT(box), PROP_SIZE_QUEUED_S, NULL);
    + g_object_set_data(G_OBJECT(box), PROP_LAST_RESIZE_S, wid);
    }
    if (box->vertical)
    --- a/gntentry.c Sun Feb 21 00:11:56 2010 +0000
    +++ b/gntentry.c Fri Apr 09 22:14:51 2010 +0000
    @@ -55,6 +55,11 @@
    GntEntryAction last;
    };
    +struct _GntEntrySearch
    +{
    + char *needle;
    +};
    +
    static guint signals[SIGS] = { 0 };
    static GntWidgetClass *parent_class = NULL;
    @@ -471,6 +476,55 @@
    }
    static gboolean
    +history_search(GntBindable *bind, GList *null)
    +{
    + GntEntry *entry = GNT_ENTRY(bind);
    + GList *iter;
    + const char *current , *pos;
    + int len;
    +
    + if (entry->history->prev && entry->search->needle)
    + current = entry->search->needle;
    + else
    + current = gnt_entry_get_text(entry);
    +
    + if (!entry->histlength || !entry->history->next || !*current)
    + return FALSE;
    +
    + len = g_utf8_strlen(current, -1);
    +
    + for (iter = entry->history->next; iter; iter = iter->next) {
    + const char *str = iter->data;
    + /* A more utf8-friendly version of strstr would have been better, but
    + * for now, this will have to do. */
    + if ((pos = strstr(str, current)))
    + break;
    + }
    +
    + if (!iter)
    + return TRUE;
    +
    + if (entry->history->prev == NULL) {
    + /* We are doing it for the first time. Save the current contents */
    + char *text = g_strdup(gnt_entry_get_text(entry));
    +
    + g_free(entry->search->needle);
    + entry->search->needle = g_strdup(current);
    +
    + g_free(entry->history->data);
    + entry->history->data = text;
    + }
    +
    + entry->history = iter;
    + gnt_entry_set_text_internal(entry, entry->history->data);
    + destroy_suggest(entry);
    + entry_text_changed(entry);
    +
    + update_kill_ring(entry, ENTRY_JAIL, NULL, 0);
    + return TRUE;
    +}
    +
    +static gboolean
    clipboard_paste(GntBindable *bind, GList *n)
    {
    GntEntry *entry = GNT_ENTRY(bind);
    @@ -833,6 +887,9 @@
    gnt_widget_destroy(entry->ddown->parent);
    }
    + g_free(entry->search->needle);
    + g_free(entry->search);
    +
    jail_killring(entry->killring);
    }
    @@ -935,6 +992,8 @@
    GNT_KEY_CTRL_UP, NULL);
    gnt_bindable_register_binding(bindable, "history-prev", GNT_KEY_CTRL_P, NULL);
    gnt_bindable_register_binding(bindable, "history-next", GNT_KEY_CTRL_N, NULL);
    + gnt_bindable_class_register_action(bindable, "history-search", history_search,
    + GNT_KEY_CTRL_R, NULL);
    gnt_bindable_class_register_action(bindable, "clipboard-paste", clipboard_paste,
    GNT_KEY_CTRL_V, NULL);
    @@ -966,6 +1025,7 @@
    entry->always = FALSE;
    entry->suggests = NULL;
    entry->killring = new_killring();
    + entry->search = g_new0(GntEntrySearch, 1);
    GNT_WIDGET_SET_FLAGS(GNT_WIDGET(entry),
    GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW | GNT_WIDGET_CAN_TAKE_FOCUS);
    --- a/gntentry.h Sun Feb 21 00:11:56 2010 +0000
    +++ b/gntentry.h Fri Apr 09 22:14:51 2010 +0000
    @@ -49,6 +49,7 @@
    typedef struct _GntEntryPriv GntEntryPriv;
    typedef struct _GntEntryClass GntEntryClass;
    typedef struct _GntEntryKillRing GntEntryKillRing;
    +typedef struct _GntEntrySearch GntEntrySearch;
    typedef enum
    {
    @@ -86,6 +87,7 @@
    gboolean always; /* Should the list of suggestions show at all times, or only on tab-press? */
    GntWidget *ddown; /* The dropdown with the suggested list */
    GntEntryKillRing *killring; /**< @since 2.3.0 */
    + GntEntrySearch *search; /**< @since 2.7.0 */
    };
    struct _GntEntryClass