Add to git.
[monolith.git] / widgets / ml_user_directory.c
1 /* Monolith user directory widget.
2  * - by Richard W.M. Jones <rich@annexia.org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the Free
16  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  *
18  * $Id: ml_user_directory.c,v 1.2 2003/02/22 15:34:33 rich Exp $
19  */
20
21 #include "config.h"
22
23 #include <stdio.h>
24 #include <stdlib.h>
25
26 #ifdef HAVE_STRING_H
27 #include <string.h>
28 #endif
29
30 #include <pool.h>
31 #include <pstring.h>
32 #include <pre.h>
33 #include <pthr_iolib.h>
34
35 #include "monolith.h"
36 #include "ml_widget.h"
37 #include "ml_button.h"
38 #include "ml_window.h"
39 #include "ml_form.h"
40 #include "ml_form_select.h"
41 #include "ml_form_submit.h"
42 #include "ml_table_layout.h"
43 #include "ml_user_directory.h"
44
45 static void repaint (void *, ml_session, const char *, io_handle);
46
47 struct ml_widget_operations user_directory_ops =
48   {
49     repaint: repaint
50   };
51
52 struct ml_user_directory
53 {
54   struct ml_widget_operations *ops;
55   pool pool;                    /* Pool for allocations. */
56   ml_session session;           /* Current session. */
57   const char *conninfo;         /* Database connection. */
58   ml_form form;                 /* Form (can be NULL). */
59   int userid;                   /* Currently selected userid (0 = none). */
60   ml_widget top;                /* This is our top-level widget. */
61   ml_form_select select;        /* Selection widget. */
62   vector users;                 /* List of all users (vector of int). */
63 };
64
65 static void make_select (pool, ml_session, const char *,
66                          ml_form, int userid,
67                          ml_form_select *select_rtn,
68                          vector *users_rtn);
69
70 ml_user_directory
71 new_ml_user_directory (pool pool, ml_session session, const char *conninfo,
72                        ml_form form, int userid)
73 {
74   ml_user_directory w = pmalloc (pool, sizeof *w);
75
76   w->ops = &user_directory_ops;
77   w->pool = pool;
78   w->session = session;
79   w->conninfo = conninfo;
80   w->userid = userid;
81
82   /* Create the table widget. */
83   if (form)                     /* We are in an existing form. */
84     {
85       w->form = form;
86       make_select (pool, session, conninfo, form, userid,
87                    &w->select, &w->users);
88       w->top = w->select;
89     }
90   else                          /* We are a standalone widget. */
91     {
92       ml_table_layout tbl;
93       ml_form_submit submit;
94
95       w->form = new_ml_form (w->pool);
96       tbl = new_ml_table_layout (pool, 1, 2);
97       make_select (pool, session, conninfo, w->form, userid,
98                    &w->select, &w->users);
99       ml_table_layout_pack (tbl, w->select, 0, 0);
100       submit = new_ml_form_submit (pool, w->form, "Go");
101       ml_table_layout_pack (tbl, submit, 0, 1);
102       ml_form_pack (w->form, tbl);
103
104       w->top = w->form;
105     }
106
107   return w;
108 }
109
110 static void
111 make_select (pool pool, ml_session session, const char *conninfo,
112              ml_form form, int selected_userid,
113              ml_form_select *select, vector *users)
114 {
115   db_handle dbh;
116   st_handle sth;
117   int userid;
118   const char *email, *given_name, *family_name;
119
120   *select = new_ml_form_select (pool, form);
121   *users = new_vector (pool, int);
122
123   dbh = get_db_handle (conninfo, DBI_THROW_ERRORS);
124
125   /* Pull out the list of users, and details. */
126   sth = st_prepare_cached
127     (dbh,
128      "select p.userid, u.email, u.given_name, u.family_name "
129      "from ml_userdir_prefs p, ml_users u "
130      "order by u.given_name, u.family_name, u.email");
131   st_execute (sth);
132
133   st_bind (sth, 0, userid, DBI_INT);
134   st_bind (sth, 1, email, DBI_STRING);
135   st_bind (sth, 2, given_name, DBI_STRING);
136   st_bind (sth, 3, family_name, DBI_STRING);
137
138   while (st_fetch (sth))
139     {
140       vector_push_back (*users, userid);
141       ml_form_select_push_back
142         (*select,
143          psprintf (pool, "%s %s <%s>", given_name, family_name, email));
144
145       if (userid == selected_userid)
146         ml_form_select_set_selection (*select,
147                                       ml_form_select_size (*select) - 1);
148     }
149
150   put_db_handle (dbh);
151 }
152
153 static void
154 repaint (void *vw, ml_session session, const char *windowid, io_handle io)
155 {
156   ml_user_directory w = (ml_user_directory) vw;
157
158   ml_widget_repaint (w->top, session, windowid, io);
159 }