1 /********************************************************************\ 2 * table-allgui.h -- 2D grid table object, embeds cells for i/o * 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 /** @addtogroup RegisterCore Register Core 23 * @{ 24 */ 25 /** @addtogroup Table Table 26 * @brief The "Table" is a displayed matrix. The table 27 * is a complex object; it is @b not merely a @ref Cellblock. The table provides 28 * all of the GUI infrastructure for displaying a row-column matrix of strings. 29 * 30 * The table provides one very important function for minimizing memory usage 31 * for large matrixes - the notion of a "Cursor". The cursor is a @ref Cellblock 32 * (an array of active cells) that is moved to the location that the user is 33 * currently editing. The cursor "virtualizes" @ref Cell functions; that is, it 34 * makes it seem to the user as if all cells in the table are active, when in 35 * fact the only cell that actually needs to be active is the one that the user 36 * is currently editing. 37 * 38 * The table design allows multiple cursors to be defined. When a user enters a 39 * cell, the appropriate cursor is positioned within the table. Cursors cannot 40 * overlap: any given cell can be mapped to at most one cursor. Multiple-cursor 41 * support allows tables to be designed that have a non-uniform layout. For 42 * example, the multiple-cursor support can be used to define a tree structure 43 * of headings and sub-headings, where the layout/format of the heading is 44 * different from the sub-headings. A financial example is a table which lists 45 * splits underneath their parent transaction. This is very different from a 46 * checkbook register, where all entries are uniform, and can be handled with a 47 * single repeated cursor. 48 * 49 * Users of the table must provide a TableView object which provides an API the 50 * table uses to obtain information about the data it is displaying such as 51 * strings, colors, etc. Thus, the table represents the non-GUI portion of the 52 * View object in the Model-View-Controller paradigm. 53 * @{ 54 */ 55 /** @file table-allgui.h 56 * @brief Declarations for the Table object 57 * @author Copyright (c) 1998,1999,2000 Linas Vepstas 58 * @author Copyright (c) 2000-2001 Dave Peticolas 59 * 60 * @details 61 * The Table object defines the structure and the GUI required 62 * to display a two-dimensional grid. It provides several 63 * important functions: 64 * - An array of virtual cells. These cells contain: 65 * - the cellblock handler for that virtual cell. 66 * - a user data pointer 67 * - Tab-traversing mechanism so that operator can tab in a 68 * predefined order between cells. 69 * 70 * This implements the gui-independent parts of the table 71 * infrastructure. Additional, GUI-dependent parts are implemented 72 * in table-gnome.c. 73 * 74 * The following concepts apply to the rows in a table: 75 * - a cursor is always the same size as the virt row its on, 76 * - there is only one cursor for a given virt row. 77 * - there is no overlap; a phys row can only belong to one virt row. 78 * 79 * Lets say there are three cursors T(rans), S(plit), and B(lank). 80 * Lets say that these are used to 'print' the following table layout: 81 * 82 @verbatim 83 virtual row 1 T 84 virtual row 2 S 85 virtual row 3 B 86 virtual row 4 T 87 virtual row 5 S 88 virtual row 6 S 89 virtual row 7 S 90 virtual row 8 S 91 virtual row 9 B 92 @endverbatim 93 * 94 * You can see there is only one cursor per virtual row. There is no overlap 95 * between cursors and virtual rows; the correspondence is one to one. Note 96 * that the three cursors T, S and B may consist of one, or more physical rows, 97 * e.g. B and S may be one line each, but T may be two lines. Thus, we 98 * have the following physical layout: 99 * 100 @verbatim 101 physical row 1 virtual row 1 T 102 physical row 2 virtual row 1 T 103 physical row 3 virtual row 2 S 104 physical row 4 virtual row 3 B 105 physical row 5 virtual row 4 T 106 physical row 6 virtual row 4 T 107 physical row 7 virtual row 5 S 108 physical row 8 virtual row 6 S 109 physical row 9 virtual row 7 S 110 physical row 10 virtual row 8 S 111 physical row 11 virtual row 9 B 112 @endverbatim 113 * 114 * This layout remains static until the next time that the table is 115 * re-'printed'. 116 */ 117 118 #ifndef TABLE_ALLGUI_H 119 #define TABLE_ALLGUI_H 120 121 #include <glib.h> 122 123 #include "basiccell.h" 124 #include "cellblock.h" 125 #include "gtable.h" 126 #include "register-common.h" 127 #include "table-control.h" 128 #include "table-layout.h" 129 #include "table-model.h" 130 131 /** holds information about each virtual cell. */ 132 typedef struct 133 { 134 CellBlock *cellblock; /** Array of physical cells */ 135 gpointer vcell_data; /** Used by higher-level code */ 136 137 /* flags */ 138 unsigned int visible : 1; /** visible in the GUI */ 139 unsigned int start_primary_color : 1; /** color usage flag */ 140 } VirtualCell; 141 142 typedef struct table Table; 143 144 typedef void (*TableCursorRefreshCB) (Table *table, 145 VirtualCellLocation vcell_loc, 146 gboolean do_scroll); 147 148 typedef void (*TableRedrawHelpCB) (Table *table); 149 typedef void (*TableDestroyCB) (Table *table); 150 151 typedef struct 152 { 153 TableCursorRefreshCB cursor_refresh; 154 155 TableRedrawHelpCB redraw_help; 156 TableDestroyCB destroy; 157 } TableGUIHandlers; 158 159 struct table 160 { 161 TableLayout *layout; 162 TableModel *model; 163 TableControl *control; 164 165 int num_virt_rows; 166 int num_virt_cols; 167 168 CellBlock *current_cursor; 169 170 VirtualLocation current_cursor_loc; 171 172 /* private data */ 173 174 /* The virtual cell table */ 175 GTable *virt_cells; 176 177 TableGUIHandlers gui_handlers; 178 gpointer ui_data; 179 }; 180 181 /** Color definitions used for table elements */ 182 typedef enum { 183 COLOR_UNDEFINED = 0, // 0 184 COLOR_HEADER, // 1 185 COLOR_PRIMARY, // 2 186 COLOR_PRIMARY_ACTIVE, // 3 187 COLOR_SECONDARY, // 4 188 COLOR_SECONDARY_ACTIVE, // 5 189 COLOR_SPLIT, // 6 190 COLOR_SPLIT_ACTIVE, // 7 191 COLOR_NEGATIVE = 16, // 16 192 } RegisterColor; 193 194 195 /** Set the default gui handlers used by new tables. */ 196 void gnc_table_set_default_gui_handlers (TableGUIHandlers *gui_handlers); 197 198 /* Functions to create and destroy Tables. */ 199 Table * gnc_table_new (TableLayout *layout, 200 TableModel *model, 201 TableControl *control); 202 void gnc_virtual_location_init (VirtualLocation *vloc); 203 204 void gnc_table_save_state (Table *table, const gchar *state_section); 205 void gnc_table_destroy (Table *table); 206 207 208 /* Functions to work with current cursor */ 209 int gnc_table_current_cursor_changed (Table *table, 210 gboolean include_conditional); 211 212 void gnc_table_clear_current_cursor_changes (Table *table); 213 214 void gnc_table_save_current_cursor (Table *table, CursorBuffer *buffer); 215 void gnc_table_restore_current_cursor (Table *table, 216 CursorBuffer *buffer); 217 218 const char * gnc_table_get_current_cell_name (Table *table); 219 220 gboolean gnc_table_get_current_cell_location (Table *table, 221 const char *cell_name, 222 VirtualLocation *virt_loc); 223 224 225 /** checks the given location and returns true if it is out of bounds of the 226 * table. */ 227 gboolean gnc_table_virtual_cell_out_of_bounds (Table *table, 228 VirtualCellLocation vcell_loc); 229 230 gboolean gnc_table_virtual_location_in_header (Table *table, 231 VirtualLocation virt_loc); 232 233 234 /** returns the virtual cell associated with a particular virtual location. If 235 * the location is out of bounds, NULL is * returned. */ 236 VirtualCell * gnc_table_get_virtual_cell (Table *table, 237 VirtualCellLocation vcell_loc); 238 239 const char * gnc_table_get_entry (Table *table, VirtualLocation virt_loc); 240 241 char * gnc_table_get_tooltip (Table *table, VirtualLocation virt_loc); 242 243 const char * gnc_table_get_label (Table *table, VirtualLocation virt_loc); 244 245 CellIOFlags gnc_table_get_io_flags (Table *table, VirtualLocation virt_loc); 246 247 guint32 gnc_table_get_color (Table *table, VirtualLocation virt_loc, 248 gboolean *hatching); 249 250 void gnc_table_get_borders (Table *table, VirtualLocation virt_loc, 251 PhysicalCellBorders *borders); 252 253 CellAlignment gnc_table_get_align (Table *table, VirtualLocation virt_loc); 254 255 gboolean gnc_table_is_popup (Table *table, VirtualLocation virt_loc); 256 257 char * gnc_table_get_help (Table *table); 258 259 BasicCell * gnc_table_get_cell (Table *table, VirtualLocation virt_loc); 260 261 const char * gnc_table_get_cell_name (Table *table, 262 VirtualLocation virt_loc); 263 const gchar * gnc_table_get_cell_type_name (Table *table, 264 VirtualLocation virt_loc); 265 gboolean gnc_table_get_cell_location (Table *table, 266 const char * cell_name, 267 VirtualCellLocation vcell_loc, 268 VirtualLocation *virt_loc); 269 270 void gnc_table_save_cells (Table *table, gpointer save_data); 271 272 273 /** Return the virtual cell of the header */ 274 VirtualCell * gnc_table_get_header_cell (Table *table); 275 276 /** The gnc_table_set_size() method will resize the table to the 277 * indicated dimensions. */ 278 void gnc_table_set_size (Table * table, int virt_rows, int virt_cols); 279 280 /** Indicate what handler should be used for a given virtual block */ 281 void gnc_table_set_vcell (Table *table, CellBlock *cursor, 282 gconstpointer vcell_data, 283 gboolean visible, 284 gboolean start_primary_color, 285 VirtualCellLocation vcell_loc); 286 287 /** Set the virtual cell data for a particular location. */ 288 void gnc_table_set_virt_cell_data (Table *table, 289 VirtualCellLocation vcell_loc, 290 gconstpointer vcell_data); 291 292 /** Set the visibility flag for a particular location. */ 293 void gnc_table_set_virt_cell_visible (Table *table, 294 VirtualCellLocation vcell_loc, 295 gboolean visible); 296 297 /** Set the cellblock handler for a virtual cell. */ 298 void gnc_table_set_virt_cell_cursor (Table *table, 299 VirtualCellLocation vcell_loc, 300 CellBlock *cursor); 301 302 /** will move the cursor (but not the cursor GUI) to the indicated 303 * location. This function is useful when loading the table from the cursor: 304 * data can be loaded into the cursor, then committed to the table, all 305 * without the annoying screen flashing associated with GUI redraw. */ 306 void gnc_table_move_cursor (Table *table, VirtualLocation virt_loc); 307 308 /** will move the cursor and its GUI to the indicated location. Through a series 309 * of callbacks, all GUI elements get repositioned. */ 310 void gnc_table_move_cursor_gui (Table *table, VirtualLocation virt_loc); 311 312 /** checks the location of the cursor with respect to a virtual location 313 * position, and if the resulting virtual location has changed, repositions 314 * the cursor and gui to the new position. Returns true if the cell cursor was 315 * repositioned. */ 316 gboolean gnc_table_verify_cursor_position (Table *table, 317 VirtualLocation virt_loc); 318 319 /** returns the virtual cell data associated with a cursor located at the given 320 * virtual coords, or NULL if the coords are out of bounds. */ 321 gpointer gnc_table_get_vcell_data (Table *table, 322 VirtualCellLocation vcell_loc); 323 324 /** Find a close valid cell. If exact_cell is true, cells that must 325 * be explicitly selected by the user (as opposed to just tabbing 326 * into), are considered valid cells. */ 327 gboolean gnc_table_find_close_valid_cell (Table *table, 328 VirtualLocation *virt_loc, 329 gboolean exact_cell); 330 331 /** UI-specific functions *******************************/ 332 333 /** Initialize the GUI from a table */ 334 void gnc_table_init_gui (Table *table); 335 336 void gnc_table_realize_gui (Table *table); 337 338 /** Refresh the current cursor gui */ 339 void gnc_table_refresh_current_cursor_gui (Table * table, 340 gboolean do_scroll); 341 342 /** Refresh the whole GUI from the table. */ 343 void gnc_table_refresh_gui (Table *table, gboolean do_scroll); 344 345 /** Try to show the whole range in the register. */ 346 void gnc_table_show_range (Table *table, 347 VirtualCellLocation start_loc, 348 VirtualCellLocation end_loc); 349 350 /** Refresh the cursor in the given location. If do_scroll is TRUE, 351 * scroll the register so the location is in view. */ 352 void gnc_table_refresh_cursor_gui (Table * table, 353 VirtualCellLocation vcell_loc, 354 gboolean do_scroll); 355 356 /* ==================================================== */ 357 358 void gnc_table_wrap_verify_cursor_position (Table *table, 359 VirtualLocation virt_loc); 360 361 gboolean gnc_table_virtual_loc_valid(Table *table, 362 VirtualLocation virt_loc, 363 gboolean exact_pointer); 364 365 gboolean gnc_table_move_tab (Table *table, 366 VirtualLocation *virt_loc, 367 gboolean move_right); 368 369 /** Moves away from virtual location @a virt_loc by @a phys_row_offset physical 370 * rows. Virtual cells that are not visible are skipped over. 371 * 372 * @param table The table 373 * 374 * @param virt_loc The virtual location to start from. If the move succeeds, 375 * it is updated with the new location. 376 * 377 * @param phys_row_offset The number of physical rows to move. A positive 378 * number moves down and a negative number moves up. 379 * 380 * @return TRUE if the location changed, FALSE otherwise 381 */ 382 gboolean gnc_table_move_vertical_position (Table *table, 383 VirtualLocation *virt_loc, 384 int phys_row_offset); 385 386 gboolean gnc_table_enter_update(Table *table, 387 VirtualLocation virt_loc, 388 int *cursor_position, 389 int *start_selection, 390 int *end_selection); 391 392 void gnc_table_leave_update(Table *table, VirtualLocation virt_loc); 393 394 gboolean gnc_table_confirm_change(Table *table, VirtualLocation virt_loc); 395 396 const char * gnc_table_modify_update(Table *table, 397 VirtualLocation virt_loc, 398 const char *change, 399 int change_len, 400 const char *newval, 401 int newval_len, 402 int *cursor_position, 403 int *start_selection, 404 int *end_selection, 405 gboolean *cancelled); 406 407 gboolean gnc_table_direct_update(Table *table, 408 VirtualLocation virt_loc, 409 char **newval_ptr, 410 int *cursor_position, 411 int *start_selection, 412 int *end_selection, 413 gpointer gui_data); 414 415 gboolean gnc_table_traverse_update(Table *table, 416 VirtualLocation virt_loc, 417 gncTableTraversalDir dir, 418 VirtualLocation *dest_loc); 419 420 #endif /* TABLE_ALLGUI_H */ 421 /** @} */ 422 /** @} */ 423