1 /********************************************************************\
2 * cellblock.c -- group of cells that act as cursor within 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 /*
24 * FILE:
25 * cellblock.c
26 *
27 * FUNCTION:
28 * implements a rectangular array of cells. See the header file for
29 * additional documentation.
30 *
31 * HISTORY:
32 * Copyright (c) 1998 Linas Vepstas
33 * Copyright (c) 2000-2001 Dave Peticolas <dave@krondo.com>
34 */
35
36 #include <config.h>
37
38 #include "cellblock.h"
39
40 static void gnc_cellblock_init (CellBlock *cellblock, int rows, int cols);
41
42
43 CellBlock *
gnc_cellblock_new(int rows,int cols,const char * cursor_name)44 gnc_cellblock_new (int rows, int cols, const char *cursor_name)
45 {
46 CellBlock *cellblock;
47
48 g_return_val_if_fail (rows > 0, NULL);
49 g_return_val_if_fail (cols > 0, NULL);
50 g_return_val_if_fail (cursor_name != NULL, NULL);
51
52 cellblock = g_new0 (CellBlock, 1);
53
54 gnc_cellblock_init (cellblock, rows, cols);
55
56 cellblock->cursor_name = g_strdup (cursor_name);
57
58 return cellblock;
59 }
60
61 static void
gnc_cellblock_init(CellBlock * cellblock,int rows,int cols)62 gnc_cellblock_init (CellBlock *cellblock, int rows, int cols)
63 {
64 /* record new size */
65 cellblock->num_rows = rows;
66 cellblock->num_cols = cols;
67
68 cellblock->start_col = cols;
69 cellblock->stop_col = -1;
70
71 /* malloc new cell table */
72 cellblock->cells = g_ptr_array_new ();
73
74 g_ptr_array_set_size (cellblock->cells, rows * cols);
75 }
76
77 void
gnc_cellblock_destroy(CellBlock * cellblock)78 gnc_cellblock_destroy (CellBlock *cellblock)
79 {
80 if (!cellblock) return;
81
82 g_ptr_array_free (cellblock->cells, FALSE);
83 cellblock->cells = NULL;
84
85 g_free (cellblock->cursor_name);
86 cellblock->cursor_name = NULL;
87
88 g_free (cellblock);
89 }
90
91 void
gnc_cellblock_set_cell(CellBlock * cellblock,int row,int col,BasicCell * cell)92 gnc_cellblock_set_cell (CellBlock *cellblock,
93 int row, int col,
94 BasicCell *cell)
95 {
96 if (cellblock == NULL)
97 return;
98
99 if (row < 0 || row >= cellblock->num_rows)
100 return;
101
102 if (col < 0 || col >= cellblock->num_cols)
103 return;
104
105 cellblock->cells->pdata[(row * cellblock->num_cols) + col] = cell;
106 }
107
108 BasicCell *
gnc_cellblock_get_cell(CellBlock * cellblock,int row,int col)109 gnc_cellblock_get_cell (CellBlock *cellblock, int row, int col)
110 {
111 if (cellblock == NULL)
112 return NULL;
113
114 if (row < 0 || row >= cellblock->num_rows)
115 return NULL;
116
117 if (col < 0 || col >= cellblock->num_cols)
118 return NULL;
119
120 return cellblock->cells->pdata[(row * cellblock->num_cols) + col];
121 }
122
123 BasicCell *
gnc_cellblock_get_cell_by_name(CellBlock * cellblock,const char * cell_name,int * row,int * col)124 gnc_cellblock_get_cell_by_name(CellBlock *cellblock,
125 const char *cell_name,
126 int *row, int *col)
127 {
128 int r, c, num_rows, num_cols;
129
130 if (cellblock == NULL)
131 return NULL;
132
133 if (cell_name == NULL)
134 return NULL;
135
136 num_rows = cellblock->num_rows;
137 num_cols = cellblock->num_cols;
138 for (r = 0; r < num_rows; r++)
139 for (c = 0; c < num_cols; c++)
140 {
141 BasicCell *cell = cellblock->cells->pdata[(r * num_cols) + c];
142 if (!cell) continue;
143 if (gnc_cell_name_equal(cell->cell_name, cell_name))
144 {
145 if (row)
146 *row = r;
147 if (col)
148 *col = c;
149 return cell;
150 }
151 }
152
153 return NULL;
154 }
155
156 int
gnc_cellblock_changed(CellBlock * cursor,gboolean include_conditional)157 gnc_cellblock_changed (CellBlock *cursor, gboolean include_conditional)
158 {
159 int changed = 0;
160 int r, c;
161
162 if (!cursor)
163 return FALSE;
164
165 for (r = 0; r < cursor->num_rows; r++)
166 for (c = 0; c < cursor->num_cols; c++)
167 {
168 BasicCell *cell;
169
170 cell = gnc_cellblock_get_cell (cursor, r, c);
171 if (cell == NULL)
172 continue;
173
174 if (gnc_basic_cell_get_changed (cell))
175 {
176 changed++;
177 continue;
178 }
179
180 if (include_conditional &&
181 gnc_basic_cell_get_conditionally_changed (cell))
182 changed++;
183 }
184
185 return changed;
186 }
187
188 void
gnc_cellblock_clear_changes(CellBlock * cursor)189 gnc_cellblock_clear_changes (CellBlock *cursor)
190 {
191 int r, c;
192
193 if (!cursor)
194 return;
195
196 for (r = 0; r < cursor->num_rows; r++)
197 for (c = 0; c < cursor->num_cols; c++)
198 {
199 BasicCell *cell;
200
201 cell = gnc_cellblock_get_cell (cursor, r, c);
202 if (cell == NULL)
203 continue;
204
205 gnc_basic_cell_set_changed (cell, FALSE);
206 gnc_basic_cell_set_conditionally_changed (cell, FALSE);
207 }
208 }
209