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