1 #ifndef _GNM_SHEET_H_
2 # define _GNM_SHEET_H_
3 
4 #include <gnumeric.h>
5 #include <colrow.h>
6 #include <position.h>
7 #include <pango/pango.h>
8 #include <goffice/goffice.h>
9 #include <libgnumeric.h>
10 #include <style-border.h>
11 
12 G_BEGIN_DECLS
13 
14 GNM_VAR_DECL Sheet *invalid_sheet;
15 
16 GType gnm_sheet_size_get_type (void);
17 
18 struct _ColRowCollection {
19 	int         max_used;
20 	ColRowInfo  default_style;
21 	GPtrArray * info;
22 	int	    max_outline_level;
23 };
24 
25 typedef struct _SheetPrivate SheetPrivate;
26 GType gnm_sheet_type_get_type (void);
27 #define GNM_SHEET_TYPE_TYPE (gnm_sheet_type_get_type ())
28 
29 GType gnm_sheet_visibility_get_type (void);
30 #define GNM_SHEET_VISIBILITY_TYPE (gnm_sheet_visibility_get_type ())
31 
32 struct _Sheet {
33 	GObject	base;
34 
35 	int         index_in_wb;
36 	Workbook    *workbook;
37 	gboolean    being_invalidated;
38 	gboolean    being_constructed;
39 	gboolean    being_destructed;
40 
41 	GOUndoGroup *revive;
42 
43 	GPtrArray   *sheet_views;
44 
45 	char        *name_quoted;
46 	char        *name_unquoted;
47 	char        *name_unquoted_collate_key;
48 	char	    *name_case_insensitive;
49 
50 	GnmSheetStyleData *style_data; /* See sheet-style.c */
51 
52 	GnmSheetConditionsData *conditions; // See sheet-conditions.c
53 
54 	ColRowCollection cols, rows;
55 
56 	GHashTable  *cell_hash;	/* The cells in hashed format */
57 
58 	GnmNamedExprCollection *names;
59 
60 	/* This should eventually be moved to the views.  */
61 	double      last_zoom_factor_used;
62 	GnmRenderedValueCollection *rendered_values;
63 
64 	GSList      *sheet_objects;	/* List of objects in this sheet */
65 	GnmCellPos   max_object_extent;
66 
67 	/* Sheet level preferences */
68 	GnmConventions *convs;
69 	gboolean    display_formulas;
70 	gboolean    hide_zero;
71 	gboolean    hide_grid;
72 	gboolean    hide_col_header;
73 	gboolean    hide_row_header;
74 	gboolean    is_protected;
75 	struct {
76 		gboolean edit_objects;		/* TODO */
77 		gboolean edit_scenarios;	/* TODO */
78 		gboolean cell_formatting;	/* TODO */
79 		gboolean column_formatting;	/* TODO */
80 		gboolean row_formatting;	/* TODO */
81 		gboolean insert_columns;	/* TODO */
82 		gboolean insert_rows;		/* TODO */
83 		gboolean insert_hyperlinks;	/* TODO */
84 		gboolean delete_columns;	/* TODO */
85 		gboolean delete_rows;		/* TODO */
86 		gboolean select_locked_cells;	/* Partial : TODO range selection */
87 		gboolean sort_ranges;		/* TODO */
88 		gboolean edit_auto_filters;	/* TODO */
89 		gboolean edit_pivottable;	/* TODO */
90 		gboolean select_unlocked_cells;	/* Partial : TODO range selection */
91 	} protected_allow;
92 
93 	GnmSheetVisibility visibility;
94 
95 	gboolean    display_outlines;
96 	gboolean    outline_symbols_below;
97 	gboolean    outline_symbols_right;
98 	gboolean    text_is_rtl;
99 
100 	gboolean    has_filtered_rows;
101 
102         GnmSolverParameters *solver_parameters;
103 	GList            *scenarios;
104 	GHashTable       *sort_setups;
105 
106 	gint simulation_round;
107 
108 	GnmDepContainer *deps;
109 
110 	GArray *pending_redraw;
111 	guint pending_redraw_src;
112 
113 	GSList		 *slicers;
114 	GSList		 *filters;
115 	GSList		 *list_merged;
116 	GHashTable	 *hash_merged;
117 	SheetPrivate     *priv;
118 	GnmPrintInformation *print_info;
119 	GnmColor	 *tab_color;
120 	GnmColor	 *tab_text_color;
121 	GnmSheetType	  sheet_type;
122 
123 	GnmSheetSize size;
124 
125 	/* tile related data */
126 	int tile_top_level;
127 };
128 
129 #define GNM_SHEET_TYPE	(gnm_sheet_get_type ())
130 #define SHEET(obj)     (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNM_SHEET_TYPE, Sheet))
131 #define IS_SHEET(o)    (G_TYPE_CHECK_INSTANCE_TYPE ((o), GNM_SHEET_TYPE))
132 #define GNM_SHEET_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GNM_SHEET_TYPE, GnmSheetClass))
133 GType     gnm_sheet_get_type	 (void);
134 
135 Sheet    *sheet_new		 (Workbook *wb, char const *name, int columns, int rows);
136 Sheet    *sheet_new_with_type	 (Workbook *wb, char const *name,
137 				  GnmSheetType type, int columns, int rows);
138 Sheet    *sheet_dup		 (Sheet const *source_sheet);
139 void      sheet_destroy_contents (Sheet *sheet);
140 
141 gboolean  gnm_sheet_valid_size   (int cols, int rows);
142 void      gnm_sheet_suggest_size (int *cols, int *rows);
143 
144 GOUndo   *gnm_sheet_resize       (Sheet *sheet, int cols, int rows,
145 				  GOCmdContext *cc, gboolean *perr);
146 
147 GnmSheetSize const *gnm_sheet_get_size (Sheet const *sheet);
148 GnmSheetSize const *gnm_sheet_get_size2 (Sheet const *sheet,
149 					 Workbook const *wb);
150 #define gnm_sheet_get_max_rows(sheet) (gnm_sheet_get_size(sheet)->max_rows)
151 #define gnm_sheet_get_max_cols(sheet) (gnm_sheet_get_size(sheet)->max_cols)
152 #define gnm_sheet_get_last_col(sheet) (gnm_sheet_get_max_cols(sheet) - 1)
153 #define gnm_sheet_get_last_row(sheet) (gnm_sheet_get_max_rows(sheet) - 1)
154 
155 /* GnmCell management */
156 GnmCell  *sheet_cell_get	 (Sheet const *sheet, int col, int row);
157 GnmCell  *sheet_cell_fetch	 (Sheet *sheet, int col, int row);
158 GnmCell  *sheet_cell_create	 (Sheet *sheet, int col, int row);
159 void      sheet_cell_remove	 (Sheet *sheet, GnmCell *cell,
160 				  gboolean redraw, gboolean queue_recalc);
161 /* TODO TODO TODO
162  * Merge with sheet_cell_foreach
163  *
164  **/
165 struct _GnmCellIter {
166 	GnmCell	    *cell;
167 	GnmParsePos  pp;
168 	ColRowInfo  *ci, *ri;
169 };
170 GnmValue *sheet_foreach_cell_in_region (Sheet *sheet, CellIterFlags flags,
171 				       int start_col, int start_row,
172 				       int end_col, int end_row,
173 				       CellIterFunc callback,
174 				       gpointer     closure);
175 GnmValue *sheet_foreach_cell_in_range (Sheet *sheet, CellIterFlags flags,
176 				       GnmRange const *r,
177 				       CellIterFunc callback,
178 				       gpointer     closure);
179 void	    sheet_cell_foreach	 (Sheet const *sheet,
180 				  GHFunc callback, gpointer data);
181 unsigned    sheet_cells_count	 (Sheet const *sheet);
182 GPtrArray  *sheet_cell_positions (Sheet *sheet, gboolean comments);
183 
184 GPtrArray  *sheet_cells          (Sheet *sheet, const GnmRange *r);
185 
186 void        sheet_recompute_spans_for_col     (Sheet *sheet, int col);
187 void        sheet_range_unrender (Sheet *sheet, GnmRange const *r);
188 
189 gboolean    sheet_is_region_empty	      (Sheet *sheet, GnmRange const *r);
190 gboolean    sheet_is_cell_empty		      (Sheet *sheet, int col, int row);
191 
192 gboolean    sheet_col_is_hidden		   (Sheet const *sheet, int col);
193 gboolean    sheet_row_is_hidden		   (Sheet const *sheet, int row);
194 
195 GnmComment *sheet_get_comment		   (Sheet const *sheet,
196 					    GnmCellPos const *pos);
197 
198 int	    sheet_find_boundary_horizontal (Sheet *sheet, int col, int move_row,
199 					    int base_row, int count,
200 					    gboolean jump_to_boundaries);
201 int	    sheet_find_boundary_vertical   (Sheet *sheet, int move_col, int row,
202 					    int base_col, int count,
203 					    gboolean jump_to_boundaries);
204 
205 ColRowInfo const *sheet_colrow_get_default (Sheet const *sheet,
206 					    gboolean is_cols);
207 
208 void        sheet_colrow_optimize          (Sheet *sheet);
209 
210 /* Returns a pointer to a ColRowInfo: existing or NULL */
211 ColRowInfo *sheet_col_get                 (Sheet const *sheet, int col);
212 ColRowInfo *sheet_row_get                 (Sheet const *sheet, int row);
213 ColRowInfo *sheet_colrow_get              (Sheet const *sheet,
214 					   int colrow, gboolean is_cols);
215 /* Returns a pointer to a ColRowInfo: existing or freshly created */
216 ColRowInfo *sheet_col_fetch               (Sheet *sheet, int col);
217 ColRowInfo *sheet_row_fetch               (Sheet *sheet, int row);
218 ColRowInfo *sheet_colrow_fetch            (Sheet *sheet,
219 					   int colrow, gboolean is_cols);
220 /* Returns a pointer to a ColRowInfo: existing or default */
221 ColRowInfo const *sheet_col_get_info	  (Sheet const *sheet, int col);
222 ColRowInfo const *sheet_row_get_info	  (Sheet const *sheet, int row);
223 ColRowInfo const *sheet_colrow_get_info	  (Sheet const *sheet,
224 					   int colrow, gboolean is_cols);
225 
226 gboolean          sheet_colrow_foreach	   (Sheet const *sheet,
227 					    gboolean is_cols,
228 					    int first, int last,
229 					    ColRowHandler callback,
230 					    gpointer user_data);
231 
232 /*
233  * Definitions of row/col size terminology :
234  *
235  * _pixels == measurments are in screen pixels.
236  * _pts == measurments are in 'points' and should be the same size on all displays
237  *         (printers and monitors).
238  *
239  * distance == pixels from the leading edge of the 'from' col/row
240  *             to the leading edge of the 'to' col/row
241  *             INCLUDING all internal margins.
242  *             INCLUDING the leading grid line
243  *             EXCLUDING the trailing grid line.
244  *
245  * _default == The size of all cols/rows that do not have explicit sizes.
246  */
247 /* Col width */
248 double  sheet_col_get_distance_pts	  (Sheet const *sheet, int from_col, int to_col);
249 int     sheet_col_get_distance_pixels     (Sheet const *sheet, int from_col, int to_col);
250 void    sheet_col_set_size_pts		  (Sheet *sheet, int col, double width_pts,
251 					   gboolean set_by_user);
252 void    sheet_col_set_size_pixels	  (Sheet *sheet, int col, int width_pixels,
253 					   gboolean set_by_user);
254 double  sheet_col_get_default_size_pts	  (Sheet const *sheet);
255 int     sheet_col_get_default_size_pixels (Sheet const *sheet);
256 void    sheet_col_set_default_size_pts	  (Sheet *sheet, double width_pts);
257 void    sheet_col_set_default_size_pixels (Sheet *sheet, int width_pixels);
258 
259 /* Row height */
260 double  sheet_row_get_distance_pts	  (Sheet const *sheet, int from_row, int to_row);
261 int     sheet_row_get_distance_pixels     (Sheet const *sheet, int from, int to);
262 void    sheet_row_set_size_pts		  (Sheet *sheet, int row, double height_pts,
263 					   gboolean set_by_user);
264 void    sheet_row_set_size_pixels	  (Sheet *sheet, int row, int height_pixels,
265 					   gboolean set_by_user);
266 double  sheet_row_get_default_size_pts	  (Sheet const *sheet);
267 int     sheet_row_get_default_size_pixels (Sheet const *sheet);
268 void    sheet_row_set_default_size_pts	  (Sheet *sheet, double height_pts);
269 void    sheet_row_set_default_size_pixels (Sheet *sheet, int height_pixels);
270 
271 /* Find minimum pixel size to display contents (including margins and far grid line) */
272 int     sheet_col_size_fit_pixels    (Sheet *sheet, int col,
273 				      int srow, int erow,
274 				      gboolean ignore_strings);
275 int     sheet_row_size_fit_pixels    (Sheet *sheet, int row,
276 				      int scol, int ecol,
277 				      gboolean ignore_strings);
278 
279 gboolean sheet_colrow_can_group	     (Sheet *sheet, GnmRange const *r,
280 				      gboolean is_cols);
281 gboolean sheet_colrow_group_ungroup  (Sheet *sheet, GnmRange const *r,
282 				      gboolean is_cols, gboolean inc);
283 void     sheet_colrow_gutter	     (Sheet *sheet,
284 				      gboolean is_cols, int max_outline);
285 
286 gboolean sheet_range_splits_array    (Sheet const *sheet,
287 				      GnmRange const *r, GnmRange const *ignore,
288 				      GOCmdContext *cc, char const *cmd);
289 gboolean sheet_range_splits_region   (Sheet const *sheet,
290 				      GnmRange const *r, GnmRange const *ignore,
291 				      GOCmdContext *cc, char const *cmd);
292 gboolean sheet_ranges_split_region   (Sheet const *sheet, GSList const *ranges,
293 				      GOCmdContext *cc, char const *cmd);
294 gboolean sheet_range_contains_merges_or_arrays (Sheet const *sheet,
295 						GnmRange const *r,
296 						GOCmdContext *cc,
297 						char const *cmd,
298 						gboolean merges,
299 						gboolean arrays);
300 void	 sheet_range_bounding_box    (Sheet const *sheet, GnmRange *r);
301 gboolean sheet_range_trim	     (Sheet const *sheet, GnmRange *r,
302 				      gboolean cols, gboolean rows);
303 gboolean sheet_range_has_heading     (Sheet const *sheet, GnmRange const *src,
304 				      gboolean top, gboolean ignore_styles);
305 
306 
307 void gnm_sheet_foreach_name (Sheet const *sheet, GHFunc func, gpointer data);
308 
309 void gnm_sheet_set_solver_params (Sheet *sheet, GnmSolverParameters *param);
310 
311 GnmScenario *gnm_sheet_scenario_new (Sheet *sheet, const char *name);
312 GnmScenario *gnm_sheet_scenario_find (Sheet *sheet, const char *name);
313 void gnm_sheet_scenario_add (Sheet *sheet, GnmScenario *sc);
314 void gnm_sheet_scenario_remove (Sheet *sheet, GnmScenario *sc);
315 
316 GHashTable *gnm_sheet_get_sort_setups (Sheet *sheet);
317 void gnm_sheet_add_sort_setup (Sheet *sheet, char *key, gpointer setup);
318 gconstpointer gnm_sheet_find_sort_setup (Sheet *sheet, char const *key);
319 
320 /* Redraw */
321 #define sheet_is_visible(_sheet) ((_sheet)->visibility == GNM_SHEET_VISIBILITY_VISIBLE)
322 void     sheet_redraw_all       (Sheet const *sheet, gboolean header);
323 void     sheet_redraw_range     (Sheet const *sheet, GnmRange const *range);
324 void     sheet_queue_redraw_range (Sheet *sheet, GnmRange const *range);
325 void     sheet_redraw_region    (Sheet const *sheet,
326 				 int start_col, int start_row,
327 				 int end_col,   int end_row);
328 
329 void	 sheet_flag_status_update_cell	(GnmCell const *cell);
330 void	 sheet_flag_status_update_range	(Sheet const *sheet, GnmRange const *range);
331 void     sheet_flag_style_update_range	(Sheet const *sheet, GnmRange const *range);
332 void	 sheet_flag_recompute_spans	(Sheet const *sheet);
333 void	 sheet_update_only_grid		(Sheet const *sheet);
334 void     sheet_update                   (Sheet const *sheet);
335 void	 sheet_scrollbar_config		(Sheet const *sheet);
336 
337 void     sheet_mark_dirty	(Sheet *sheet);
338 GnmRange    sheet_get_extent	(Sheet const *sheet,
339 				 gboolean spans_and_merges_extend,
340 				 gboolean include_hidden);
341 GnmRange    sheet_get_cells_extent (Sheet const *sheet);
342 GnmRange    sheet_get_printarea	(Sheet const *sheet,
343 				 gboolean include_styles,
344 				 gboolean ignore_printarea);
345 GnmRange    *sheet_get_nominal_printarea (Sheet const *sheet);
346 
347 /*
348  * Utilities to set cell contents, queueing recalcs,
349  * redraws and rendering as required.  Does NOT check for
350  * division of arrays.
351  */
352 void	     sheet_cell_set_expr    (GnmCell *cell, GnmExprTop const *texpr);
353 void	     sheet_cell_set_value   (GnmCell *cell, GnmValue *v);
354 void	     sheet_cell_set_text    (GnmCell *cell, char const *str,
355 				     PangoAttrList *markup);
356 GnmValue const *sheet_cell_get_value(Sheet *sheet, int col, int row);
357 void	     sheet_range_set_text   (GnmParsePos const *pos,
358 				     GnmRange const *r, char const *str);
359 GOUndo *     sheet_range_set_text_undo (GnmSheetRange *sr,
360 					char const *text);
361 GOUndo *     sheet_range_set_expr_undo (GnmSheetRange *sr,
362 					GnmExprTop const  *texpr);
363 GOUndo *     sheet_range_set_markup_undo (GnmSheetRange *sr,
364 					  PangoAttrList *markup);
365 void	     sheet_apply_style	    (Sheet  *sheet, GnmRange const *range, GnmStyle *style);
366 GOUndo *     sheet_apply_style_undo (GnmSheetRange *sr,
367 				     GnmStyle      *style);
368 void	     sheet_apply_border	    (Sheet  *sheet, GnmRange const *range,
369 				     GnmBorder *borders[GNM_STYLE_BORDER_EDGE_MAX]);
370 void	     sheet_queue_respan     (Sheet const *sheet, int start_row, int end_row);
371 void         sheet_cell_queue_respan (GnmCell *cell);
372 void	     sheet_range_calc_spans (Sheet *sheet, GnmRange const *r, GnmSpanCalcFlags flags);
373 
374 void	     sheet_set_outline_direction (Sheet *sheet, gboolean is_cols);
375 gboolean     sheet_selection_is_allowed (Sheet const *sheet, GnmCellPos const *pos);
376 
377 GnmConventions const *sheet_get_conventions (Sheet const *sheet);
378 
379 gboolean  sheet_insert_cols (Sheet *sheet, int col, int count,
380 			     GOUndo **pundo, GOCmdContext *cc);
381 gboolean  sheet_delete_cols (Sheet *sheet, int col, int count,
382 			     GOUndo **pundo, GOCmdContext *cc);
383 gboolean  sheet_insert_rows (Sheet *sheet, int row, int count,
384 			     GOUndo **pundo, GOCmdContext *cc);
385 gboolean  sheet_delete_rows (Sheet *sheet, int row, int count,
386 			     GOUndo **pundo, GOCmdContext *cc);
387 void      sheet_move_range   (GnmExprRelocateInfo const *rinfo,
388 			      GOUndo **pundo, GOCmdContext *cc);
389 
390 typedef enum {
391 	CLEAR_VALUES	   = 0x01,
392 	CLEAR_FORMATS	   = 0x02,
393 	CLEAR_COMMENTS	   = 0x04,
394 	CLEAR_NOCHECKARRAY = 0x08,
395 	CLEAR_NORESPAN	   = 0x10,
396 	CLEAR_RECALC_DEPS  = 0x20,
397 	CLEAR_MERGES	   = 0x40,
398 	CLEAR_OBJECTS	   = 0x80,
399 	CLEAR_FILTERED_ONLY = 0x100
400 } SheetClearFlags;
401 
402 void  sheet_clear_region (Sheet *sheet,
403 			  int start_col, int start_row,
404 			  int end_col, int end_row,
405 			  SheetClearFlags clear_flags, GOCmdContext *cc);
406 
407 GOUndo *sheet_clear_region_undo (GnmSheetRange *sr,
408 				 int clear_flags);
409 
410 SheetView *sheet_get_view (Sheet const *sheet, WorkbookView const *wbv);
411 
412 GODateConventions const *sheet_date_conv (Sheet const *sheet);
413 
414 // Introspection support
415 void sheet_cell_set_value_gi (Sheet *sheet, int col, int row, GnmValue *v);
416 void sheet_cell_set_text_gi  (Sheet *sheet, int col, int row, char const *str);
417 void sheet_apply_style_gi (Sheet *sheet, GnmRange const *range, GnmStyle *style);
418 
419 
420 #define SHEET_FOREACH_VIEW(sheet, view, code)					\
421 do {										\
422 	int InD;								\
423 	GPtrArray *views = (sheet)->sheet_views;				\
424 	if (views != NULL) /* Reverse is important during destruction */	\
425 		for (InD = views->len; InD-- > 0; ) {				\
426 			SheetView *view = g_ptr_array_index (views, InD);	\
427 			code							\
428 		}								\
429 } while (0)
430 
431 #define SHEET_FOREACH_CONTROL(sheet, view, control, code)		\
432 	SHEET_FOREACH_VIEW((sheet), view,				\
433 		SHEET_VIEW_FOREACH_CONTROL(view, control, code);)
434 
435 /*
436  * Walk the dependents.  WARNING: Note, that it is only valid to muck with
437  * the current dependency in the code.
438  */
439 #define SHEET_FOREACH_DEPENDENT(sheet, dep, code)					\
440   do {											\
441 	/* Maybe external deps here.  */						\
442 											\
443 	if ((sheet)->deps) {								\
444 		DEPENDENT_CONTAINER_FOREACH_DEPENDENT ((sheet)->deps, dep, code);	\
445 	}										\
446   } while (0)
447 
448 G_END_DECLS
449 
450 #endif /* _GNM_SHEET_H_ */
451