source: trunk/third/gtkhtml/src/htmlselect.c @ 18136

Revision 18136, 9.6 KB checked in by ghudson, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18135, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2/*  This file is part of the GtkHTML library.
3
4    Copyright (C) 2000 Jonas Borgström <jonas_b@bitsmart.com>.
5    Copyright (C) 2000, 2001, 2002 Ximian, Inc.
6
7    This library is free software; you can redistribute it and/or
8    modify it under the terms of the GNU Library General Public
9    License as published by the Free Software Foundation; either
10    version 2 of the License, or (at your option) any later version.
11
12    This library is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    Library General Public License for more details.
16
17    You should have received a copy of the GNU Library General Public License
18    along with this library; see the file COPYING.LIB.  If not, write to
19    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20    Boston, MA 02111-1307, USA.
21*/
22
23#include <config.h>
24#include <gtk/gtkclist.h>
25#include <gtk/gtkcombo.h>
26#include <gtk/gtkentry.h>
27#include <gtk/gtkscrolledwindow.h>
28#include "htmlselect.h"
29#include <string.h>
30#include <gal/widgets/e-unicode.h>
31
32
33HTMLSelectClass html_select_class;
34static HTMLEmbeddedClass *parent_class = NULL;
35
36
37static void
38free_strings (gpointer o, gpointer data)
39{
40        g_free (o);
41}
42
43static void
44destroy (HTMLObject *o)
45{
46        HTMLSelect *select;
47
48        select = HTML_SELECT (o);
49
50        if (select->default_selection)
51                g_list_free (select->default_selection);
52
53        if (select->values) {
54
55                g_list_foreach (select->values, free_strings, NULL);
56                g_list_free (select->values);
57        }
58
59        if (select->strings) {
60
61                g_list_foreach (select->strings, free_strings, NULL);
62                g_list_free (select->strings);
63        }
64
65        HTML_OBJECT_CLASS (parent_class)->destroy (o);
66}
67
68static void
69copy (HTMLObject *self,
70      HTMLObject *dest)
71{
72        /* FIXME TODO */
73        HTMLSelect *s = HTML_SELECT (self);
74        HTMLSelect *d = HTML_SELECT (dest);
75
76        (* HTML_OBJECT_CLASS (parent_class)->copy) (self,dest);
77
78        g_warning ("HTMLSelect::copy() is broken");
79        d->size =    s->size;
80        d->multi =   s->multi;
81       
82        d->values = NULL;
83        d->strings = NULL;
84        d->default_selection = NULL;
85
86        d->clist = NULL;
87}
88
89static void
90draw (HTMLObject *o,
91      HTMLPainter *p,
92      gint x, gint y,
93      gint width, gint height,
94      gint tx, gint ty)
95{
96        HTMLSelect *select = HTML_SELECT (o);
97
98        if (select->needs_update) {
99                if (GTK_IS_COMBO (HTML_EMBEDDED (select)->widget))
100                        gtk_combo_set_popdown_strings (GTK_COMBO (HTML_EMBEDDED (o)->widget), select->strings);
101        }
102
103        select->needs_update = FALSE;   
104
105        (* HTML_OBJECT_CLASS (parent_class)->draw) (o, p, x, y, width, height, tx, ty);
106}
107
108
109static void
110reset (HTMLEmbedded *e)
111{
112        HTMLSelect *s = HTML_SELECT(e);
113        GList *i = s->default_selection;
114        gint row = 0;
115
116        if (s->multi) {
117                while (i) {
118                        if (i->data)
119                                gtk_clist_select_row (GTK_CLIST(s->clist), row, 0);
120                        else
121                                gtk_clist_unselect_row (GTK_CLIST(s->clist), row, 0);
122
123                        i = i->next;
124                        row++;
125                }               
126        } else if (s->size > 1) {
127                gtk_clist_select_row (GTK_CLIST(s->clist), s->default_selected, 0);
128        } else {
129                e_utf8_gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(e->widget)->entry), (gchar *)g_list_nth(s->strings, s->default_selected)->data);
130        }
131}
132
133static gchar *
134encode (HTMLEmbedded *e)
135{
136        HTMLSelect *s = HTML_SELECT(e);
137        GList *i;
138        GString *encoding = g_string_new ("");
139        gchar *txt, *ptr;
140
141        if(strlen (e->name)) {
142                if (s->size > 1) {
143                        gint i, rows = g_list_length (s->values);
144                        GList *work;
145                       
146                        for (i = 0; i < rows; i++) {
147                                work = g_list_nth (GTK_CLIST (s->clist)->row_list, i);
148                               
149                                if (GTK_CLIST_ROW (work)->state == GTK_STATE_SELECTED) {
150                                       
151                                        if (encoding->len) {
152                                                encoding = g_string_append_c (encoding, '&');
153                                        }
154                                        ptr = html_embedded_encode_string (e->name);
155                                        encoding = g_string_append (encoding, ptr);
156                                        g_free (ptr);
157                                       
158                                        encoding = g_string_append_c (encoding, '=');
159                                       
160                                        ptr = html_embedded_encode_string ((gchar *)g_list_nth (s->values, i)->data);
161                                        encoding = g_string_append (encoding, ptr);
162                                        g_free (ptr);
163                                }
164                        }
165                } else {
166                        gint item;
167
168                        ptr = html_embedded_encode_string (e->name);
169                        encoding = g_string_assign (encoding, ptr);
170                        g_free (ptr);
171                        encoding = g_string_append_c (encoding, '=');
172
173                        txt = e_utf8_gtk_entry_get_text (GTK_ENTRY(GTK_COMBO(e->widget)->entry));
174                        i = s->strings;
175                        item = 0;
176
177                        while (i) {
178
179                                if (strcmp(txt, (gchar *)i->data) == 0) {
180
181                                        ptr = html_embedded_encode_string ((gchar *)g_list_nth (s->values, item)->data);
182                                        encoding = g_string_append (encoding, ptr);
183                                        g_free (ptr);
184                                       
185                                        break;
186                                }
187                                i = i->next;
188                                item++;
189                        }
190
191                }
192        }
193        ptr = encoding->str;
194        g_string_free(encoding, FALSE);
195       
196        return ptr;
197}
198
199void
200html_select_type_init (void)
201{
202        html_select_class_init (&html_select_class, HTML_TYPE_SELECT, sizeof (HTMLSelect));
203}
204
205void
206html_select_class_init (HTMLSelectClass *klass,
207                        HTMLType type,
208                        guint object_size)
209{
210        HTMLEmbeddedClass *element_class;
211        HTMLObjectClass *object_class;
212
213        element_class = HTML_EMBEDDED_CLASS (klass);
214        object_class = HTML_OBJECT_CLASS (klass);
215
216        html_embedded_class_init (element_class, type, object_size);
217
218        /* HTMLEmbedded methods.   */
219        element_class->reset = reset;
220        element_class->encode = encode;
221
222        /* HTMLObject methods.   */
223        object_class->destroy = destroy;
224        object_class->copy = copy;
225        object_class->draw = draw;
226
227        parent_class = &html_embedded_class;
228}
229
230void
231html_select_init (HTMLSelect *select,
232                      HTMLSelectClass *klass,
233                      GtkWidget *parent,
234                      gchar *name,
235                      gint size,
236                      gboolean multi)
237{
238
239        HTMLEmbedded *element;
240        HTMLObject *object;
241        GtkWidget *widget;
242
243        element = HTML_EMBEDDED (select);
244        object = HTML_OBJECT (select);
245
246        html_embedded_init (element, HTML_EMBEDDED_CLASS (klass),
247                           parent, name, NULL);
248
249        if (size > 1 || multi) {
250                select->clist = gtk_clist_new (1);
251                gtk_clist_set_column_auto_resize (GTK_CLIST (select->clist), 0, TRUE);
252
253                if (multi)
254                        gtk_clist_set_selection_mode (GTK_CLIST (select->clist), GTK_SELECTION_MULTIPLE);
255
256                widget = gtk_scrolled_window_new (NULL, NULL);
257                gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (widget),
258                                                GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
259                gtk_container_add (GTK_CONTAINER (widget), select->clist);
260                gtk_widget_show(select->clist);
261
262                gtk_widget_set_usize (widget, 120, (GTK_CLIST(select->clist)->row_height + 1) * size + 5);
263
264        } else {
265
266                widget = gtk_combo_new ();
267                gtk_entry_set_editable (GTK_ENTRY(GTK_COMBO(widget)->entry), FALSE);
268                gtk_widget_set_usize ( GTK_WIDGET (widget), 120, -2);
269        }
270        html_embedded_set_widget (element, widget);
271
272        select->size = size;
273        select->multi = multi;
274        select->default_selected = 0;
275        select->values = NULL;
276        select->strings = NULL;
277        select->default_selection = NULL;
278        select->needs_update = TRUE;
279}
280
281HTMLObject *
282html_select_new (GtkWidget *parent,
283                     gchar *name,
284                     gint size,
285                     gboolean multi)
286{
287        HTMLSelect *ti;
288
289        ti = g_new0 (HTMLSelect, 1);
290        html_select_init (ti, &html_select_class,
291                              parent, name, size, multi);
292
293        return HTML_OBJECT (ti);
294}
295
296void html_select_add_option (HTMLSelect *select,
297                             gchar *value,
298                             gboolean selected)
299{
300        gchar *data[] = { "", NULL};
301        GtkWidget *w;
302
303        if(select->size > 1 || select->multi) {
304
305                w = select->clist;
306
307                gtk_clist_append (GTK_CLIST(w), data);
308                if(selected) {
309
310                        select->default_selected = GTK_CLIST(w)->rows - 1;
311                        gtk_clist_select_row (GTK_CLIST(w), select->default_selected, 0);
312
313                } else if (GTK_CLIST(w)->rows == 1) {
314
315                        gtk_clist_unselect_row (GTK_CLIST(w), 0, 0);
316                }
317        } else {
318                w = HTML_EMBEDDED (select)->widget;
319                select->strings = g_list_append (select->strings, g_strdup (""));
320
321                select->needs_update = TRUE;
322                if (selected || g_list_length (select->strings) == 1)
323                        select->default_selected = g_list_length (select->strings) - 1;
324        }
325
326        select->values = g_list_append (select->values, g_strdup (value));
327
328        if(select->multi)
329                select->default_selection = g_list_append (select->default_selection, GINT_TO_POINTER(selected));
330}
331
332static char *
333longest_string (HTMLSelect *s)
334{
335        GList *i = s->strings;
336        gint max = 0;
337        gchar *str = NULL;
338
339        while (i) {
340                if (strlen(i->data) > max) {
341                        max = strlen (i->data);
342                        str = i->data;
343                }
344                i = i->next;
345        }
346        return str;
347}
348
349void
350html_select_set_text (HTMLSelect *select, gchar *text)
351{
352        GtkWidget *w = GTK_WIDGET (HTML_EMBEDDED (select)->widget);
353        gint item;
354
355        if (select->size > 1 || select->multi) {
356                char *gtk_text;
357                item = GTK_CLIST(select->clist)->rows - 1;
358
359                gtk_text = e_utf8_to_gtk_string (select->clist, text);
360                gtk_clist_set_text (GTK_CLIST(select->clist), item, 0, gtk_text);
361                g_free (gtk_text);
362
363                HTML_OBJECT(select)->width = gtk_clist_optimal_column_width (GTK_CLIST (select->clist), 0) + 12;
364                /* Add width of scrollbar */
365                if ((item + 1) > select->size && GTK_SCROLLED_WINDOW(w)->vscrollbar) {
366                        GtkRequisition req;
367
368                        gtk_widget_size_request(GTK_SCROLLED_WINDOW(w)->vscrollbar, &req);
369                        HTML_OBJECT(select)->width += req.width + 8;
370                }
371
372                gtk_widget_set_usize ( w, HTML_OBJECT(select)->width, -2);
373        } else {
374                w = HTML_EMBEDDED (select)->widget;
375                item = g_list_length (select->strings) - 1;
376
377                if (select->strings) {
378                        char *longest;
379
380                        g_list_last (select->strings)->data = e_utf8_to_gtk_string (w, text);
381
382                        select->needs_update = TRUE;
383                        gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(w)->entry),
384                                           g_list_nth(select->strings, select->default_selected)->data);
385
386                        longest = longest_string(select);
387                        HTML_OBJECT(select)->width = (longest ? gdk_string_width(w->style->font, longest) : 0) + 30;
388                               
389                }
390                gtk_widget_set_usize (GTK_WIDGET (w), HTML_OBJECT (select)->width, -2);
391        }
392
393        if (item >= 0 && g_list_nth (select->values, item)->data == NULL)
394                g_list_nth (select->values, item)->data = g_strdup(text);
395}
396
397
Note: See TracBrowser for help on using the repository browser.