1 /********************************************************************\
2  * basiccell.h -- base class for editable cell in a table           *
3  *                                                                  *
4  * This program is free software; you can redistribute it and/or    *
5  * modify it under the terms of the GNU General Public License as   *
6  * published by the Free Software Foundation; either version 2 of   *
7  * the License, or (at your option) any later version.              *
8  *                                                                  *
9  * This program 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    *
12  * GNU General Public License for more details.                     *
13  *                                                                  *
14  * You should have received a copy of the GNU General Public License*
15  * along with this program; if not, contact:                        *
16  *                                                                  *
17  * Free Software Foundation           Voice:  +1-617-542-5942       *
18  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
19  * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
20  *                                                                  *
21 \********************************************************************/
22 
23 /** @addtogroup RegisterCore Register Core
24  * @{
25  * @addtogroup Cell Cell
26  * @brief A "Cell" is an active object which is designed to read a specific kind
27  * of user input. A Cell object has callbacks that are called when the
28  * user enters the cell (e.g. by mouse-clicking on a cell in a table, or
29  * tabbing into it), when the user attempts to modify text in the cell
30  * (e.g. by typing in it), and when the user leaves the cell (e.g. by
31  * mouse-clicking elsewhere, or tabbing away).
32  *
33  * Special-purpose cells can be created by "inheriting" from the basic
34  * cell object. Thus, there are special-purpose cells for handling dates,
35  * pull-down menus, text fields with auto-completion from a list of
36  * alternatives, monetary amounts, etc.
37  *
38  * Cells implementations may or may not contain GUI code. Cells which
39  * require only that text be displayed are completely "GUI-independent",
40  * that is, they depend on the underlying table to display the text. Cells
41  * which require additional GUI elements (such as pull-down menus) must
42  * implement the proper GUI handling on their own (using, e.g., GTK).
43  * @{
44  * @file basiccell.h
45  * @struct basic_cell
46  * @brief The BasicCell class provides an abstract base class
47  * defining the handling of the editing of a cell of a table.
48  * Classes that provide the actual handling for different
49  * cell types should inherit from this class.
50  *
51  * The BasicCell class encapsulates a single string value
52  * which can be set & read by the programmer, and edited
53  * by the "user".  In the text below, the "user" is the
54  * person controlling the mouse and keyboard.  Thus, when
55  * the user makes a move, it means that they have somehow
56  * interacted with the cell, by clicking with mouse or by
57  * typing at the keyboard.  This class provides three
58  * callbacks which allow the programmer to understand what
59  * the user is doing.
60  *
61  * The programmer can create a custom GUI for editing the
62  * contents of the cell. There are three callbacks to allow
63  * a custom GUI to be created, destroyed and moved about.
64  *
65  * Since this class is implemented in C not C++, there is
66  * a "minor" problem with inheritance.  To emulate the
67  * overloading of a virtual "SetValues" method, there is
68  * a set_value() callback, which will be called whenever
69  * the xaccSetBasicCellValue() subroutine is called.
70  *
71  * VIRTUAL/OVERLOADED METHODS:
72  * The set_value() callback will be called whenever the
73  * xaccSetBasicCellValue() method is called.  Derived
74  * classes should provide a callback here if they need
75  * to understand special cell formats.
76  *
77  * USER CALLBACKS:
78  * The enter_cell() callback is called when the user first
79  *    makes a move to enter a cell.  This might be by clicking
80  *    on the cell with the mouse, by tabbing to it, using the
81  *    arrow keys, or otherwise "selecting" it as the current
82  *    cell to edit.
83  *
84  *    The callback may change the value of the cell. The callback
85  *    should return true if the cell should allow direct editing
86  *    by the user, FALSE otherwise.
87  *
88  *    The callback is also passed pointers to the cursor position
89  *    and the start and end of the highlited region. If the callback
90  *    returns NULL, it may also change these values and the GUI will
91  *    update appropriately.
92  *
93  * The leave_cell() callback is called when the user exits
94  *    a cell.  This can be by tabbing or arrow-keying away
95  *    from it, or by using the mouse to specify a different
96  *    cell, etc. The callback may change the value of the cell.
97  *
98  * The modify_verify() callback is called when a user makes a
99  *    change to a cell.  It is called after every keystroke,
100  *    (actually, after every X11 "input-method" type input,
101  *    so that ctrl-alt-etc modifier keys are pre-processed in
102  *    the usual X11 fashion).
103  *
104  *    The arguments passed in are :
105  *    "add", the string the user is attempting to add
106  *           (will be null if text is being deleted).
107  *    "new", the string that would result is user's changes
108  *           are accepted.
109  *    "cursor_position", the position of the editing cursor
110  *                       in the text. This may be modified by
111  *                       the callback, in which case the GUI
112  *                       will reflect the change. Set to -1
113  *                       to make the cursor go to the end of
114  *                       the text.
115  *    "start_selection", the starting character of the highlited
116  *                       selection.
117  *    "end_selection",   the index immediately after the last
118  *                       character in the selection. Set both
119  *                       start and end to 0 for no selection.
120  *                       Set the end to -1 to make the selection
121  *                       go to the end of the text.
122  *
123  * The direct_update() callback is called to pass raw gui data
124  *    to the cell. The exact format of the data is determined
125  *    by the gui. The callback should return TRUE if the event
126  *    was handled, i.e., there is no need to call the modify
127  *    update. If the value needs to be changed, the cell should
128  *    go ahead and change it.
129  *
130  *
131  * GUI CALLBACKS:
132  * The cell may have some specific GUI elements which need
133  * to be initialized/positioned/etc.  There are three GUI
134  * callbacks that allow the programmer to perform GUI-specific
135  * initialization & changes.
136  *
137  * The gui_realize() callback will be called when GUI-specific
138  *    initialization needs to be done. For Gnome, the second
139  *    argument will be cast to the parent widget.
140  *
141  * The gui_destroy() callback will be called when the GUI associated
142  *    with the cell needs to be destroyed.
143  *
144  * The gui_move() callback will be called when the GUI element needs
145  *    to be positioned to a new location within the table grid.
146  *    The second argument is the virtual location the GUI
147  *    element should be moved to.
148  *
149  * The gui_private member may be used by the derived class to
150  *    store any additional GUI-specific data.
151  */
152 /* HISTORY:
153  * Copyright (c) 1998 Linas Vepstas
154  * Copyright (c) 2000 Dave Peticolas <dave@krondo.com>
155  */
156 
157 #ifndef BASIC_CELL_H
158 #define BASIC_CELL_H
159 
160 #include <gdk/gdk.h>
161 #include <glib.h>
162 #include <gtk/gtk.h>
163 
164 #include "gnc-ui-util.h"
165 
166 typedef struct basic_cell BasicCell;
167 
168 typedef BasicCell * (*CellCreateFunc) (void);
169 
170 typedef void (*CellSetValueFunc) (BasicCell *cell,
171                                   const char * new_value);
172 
173 typedef gboolean (*CellEnterFunc) (BasicCell *cell,
174                                    int *cursor_position,
175                                    int *start_selection,
176                                    int *end_selection);
177 
178 typedef void (*CellModifyVerifyFunc) (BasicCell *cell,
179                                       const char *add_str,
180                                       int add_str_len,
181                                       const char *new_value,
182                                       int new_value_len,
183                                       int *cursor_position,
184                                       int *start_selection,
185                                       int *end_selection);
186 
187 typedef gboolean (*CellDirectUpdateFunc) (BasicCell *cell,
188         int *cursor_position,
189         int *start_selection,
190         int *end_selection,
191         gpointer gui_data);
192 
193 typedef void (*CellLeaveFunc) (BasicCell *cell);
194 
195 typedef void (*CellRealizeFunc) (BasicCell *cell, gpointer gui_handle);
196 
197 typedef void (*CellMoveFunc) (BasicCell *cell);
198 
199 typedef void (*CellDestroyFunc) (BasicCell *cell);
200 
201 typedef enum
202 {
203     CELL_ALIGN_RIGHT,
204     CELL_ALIGN_CENTER,
205     CELL_ALIGN_LEFT
206 } CellAlignment;
207 
208 struct basic_cell
209 {
210     char * cell_name;
211     gchar *cell_type_name;
212     char * value;                  /** current value */
213     guint value_chars;           /** number of characters in value */
214 
215     gboolean changed;               /** true if value modified */
216     gboolean conditionally_changed; /** true if value modified conditionally */
217 
218     /* "virtual", overloaded methods */
219     CellSetValueFunc set_value;
220     CellDestroyFunc  destroy;
221 
222     /* cell-editing callbacks */
223     CellEnterFunc        enter_cell;
224     CellModifyVerifyFunc modify_verify;
225     CellDirectUpdateFunc direct_update;
226     CellLeaveFunc        leave_cell;
227 
228     /* private, GUI-specific callbacks */
229     CellRealizeFunc gui_realize;
230     CellMoveFunc    gui_move;
231     CellDestroyFunc gui_destroy;
232 
233     /* GUI information */
234     char *sample_text;       /** sample text for sizing purposes */
235     CellAlignment alignment; /** horizontal alignment in column */
236     gboolean expandable;     /** can fill with extra space */
237     gboolean span;           /** can span multiple columns */
238     gboolean is_popup;       /** is a popup widget */
239 
240     gpointer gui_private;    /** general hook for gui-private data */
241 };
242 
243 
244 gboolean     gnc_cell_name_equal (const char * cell_name_1,
245                                   const char * cell_name_2);
246 
247 BasicCell *  gnc_basic_cell_new (void);
248 void         gnc_basic_cell_init (BasicCell *bcell);
249 void         gnc_basic_cell_destroy (BasicCell *bcell);
250 
251 void         gnc_basic_cell_set_name (BasicCell *cell, const char *name);
252 gboolean     gnc_basic_cell_has_name (BasicCell *cell, const char *name);
253 void         gnc_basic_cell_set_type_name (BasicCell *cell, const gchar *type_name);
254 gboolean     gnc_basic_cell_has_type_name (BasicCell *cell, const gchar *type_name);
255 
256 
257 
258 void         gnc_basic_cell_set_sample_text (BasicCell *cell,
259         const char *sample_text);
260 void         gnc_basic_cell_set_alignment (BasicCell *cell,
261         CellAlignment alignment);
262 void         gnc_basic_cell_set_expandable (BasicCell *cell,
263         gboolean expandable);
264 void         gnc_basic_cell_set_span (BasicCell *cell,
265                                       gboolean span);
266 
267 const char * gnc_basic_cell_get_value (BasicCell *cell);
268 void         gnc_basic_cell_set_value (BasicCell *bcell, const char *value);
269 
270 gboolean     gnc_basic_cell_get_changed (BasicCell *cell);
271 gboolean     gnc_basic_cell_get_conditionally_changed (BasicCell *cell);
272 
273 void         gnc_basic_cell_set_changed (BasicCell *cell, gboolean changed);
274 void         gnc_basic_cell_set_conditionally_changed (BasicCell *cell,
275         gboolean changed);
276 
277 /* for sub-class use only */
278 void         gnc_basic_cell_set_value_internal (BasicCell *bcell,
279         const char *value);
280 
281 char * gnc_basic_cell_validate (BasicCell *bcell,
282                                 GNCPrintAmountInfo print_info,
283                                 const char *change,
284                                 const char *newval,
285                                 const char *toks,
286                                 gint *cursor_position);
287 
288 /** @} @} */
289 #endif /* BASIC_CELL_H */
290