1 /* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 #ifndef _GNM_DEPENDENT_H_
3 # define _GNM_DEPENDENT_H_
6 #include <goffice/goffice.h>
10 struct _GnmDependent
{
13 GnmExprTop
const *texpr
;
15 /* Double-linked list. */
16 GnmDependent
*next_dep
, *prev_dep
;
20 void (*eval
) (GnmDependent
*dep
);
21 void (*set_expr
) (GnmDependent
*dep
, GnmExprTop
const *new_texpr
);
22 GSList
* (*changed
) (GnmDependent
*dep
);
23 GnmCellPos
* (*pos
) (GnmDependent
const *dep
);
24 void (*debug_name
) (GnmDependent
const *dep
, GString
*target
);
28 DEPENDENT_NO_FLAG
= 0,
31 DEPENDENT_CELL
= 0x00000001, /* builtin type */
32 DEPENDENT_DYNAMIC_DEP
= 0x00000002, /* builtin type */
33 DEPENDENT_NAME
= 0x00000003, /* builtin pseudo type */
34 DEPENDENT_MANAGED
= 0x00000004, /* builtin type */
35 DEPENDENT_STYLE
= 0x00000005, /* builtin type */
36 DEPENDENT_TYPE_MASK
= 0x00000fff,
38 /* Linked into the workbook wide expression list */
39 DEPENDENT_IS_LINKED
= 0x00001000,
40 DEPENDENT_NEEDS_RECALC
= 0x00002000,
41 DEPENDENT_BEING_CALCULATED
= 0x00004000,
42 /* GnmDependent is in the midst of a cyclic calculation */
43 DEPENDENT_BEING_ITERATED
= 0x00008000,
45 DEPENDENT_GOES_INTERSHEET
= 0x00010000,
46 DEPENDENT_GOES_INTERBOOK
= 0x00020000,
47 DEPENDENT_USES_NAME
= 0x00040000,
48 DEPENDENT_HAS_3D
= 0x00080000,
49 DEPENDENT_HAS_DYNAMIC_DEPS
= 0x00200000,
50 DEPENDENT_IGNORE_ARGS
= 0x00400000,
51 DEPENDENT_LINK_FLAGS
= 0x007ff000,
53 /* An internal utility flag */
54 DEPENDENT_FLAGGED
= 0x01000000,
55 DEPENDENT_CAN_RELOCATE
= 0x02000000
58 #define dependent_type(dep) ((dep)->flags & DEPENDENT_TYPE_MASK)
59 #define dependent_is_cell(dep) (dependent_type (dep) == DEPENDENT_CELL)
60 #define dependent_needs_recalc(dep) ((dep)->flags & DEPENDENT_NEEDS_RECALC)
61 #define dependent_is_linked(dep) ((dep)->flags & DEPENDENT_IS_LINKED)
63 struct _GnmDepContainer
{
64 GnmDependent
*head
, *tail
;
66 /* Large ranges hashed on 'range' to accelerate duplicate culling. This
67 * is traversed by g_hash_table_foreach mostly.
70 GHashTable
**range_hash
;
71 GOMemChunk
*range_pool
;
73 /* Single ranges, this maps an GnmEvalPos * to a GSList of its
76 GHashTable
*single_hash
;
77 GOMemChunk
*single_pool
;
79 /* All of the ExprNames that refer to this container */
80 GHashTable
*referencing_names
;
83 GHashTable
*dynamic_deps
;
86 typedef void (*GnmDepFunc
) (GnmDependent
*dep
, gpointer user
);
88 guint32
dependent_type_register (GnmDependentClass
const *klass
);
89 void dependent_types_init (void);
90 void dependent_types_shutdown (void);
92 void dependent_set_expr (GnmDependent
*dep
, GnmExprTop
const *new_texpr
);
93 void dependent_set_sheet (GnmDependent
*dep
, Sheet
*sheet
);
94 void dependent_link (GnmDependent
*dep
);
95 void dependent_unlink (GnmDependent
*dep
);
96 void dependent_queue_recalc (GnmDependent
*dep
);
97 void dependent_add_dynamic_dep (GnmDependent
*dep
, GnmRangeRef
const *rr
);
99 gboolean
dependent_is_volatile (GnmDependent
*dep
);
101 gboolean
dependent_has_pos (GnmDependent
const *dep
);
102 GnmCellPos
const *dependent_pos (GnmDependent
const *dep
);
103 void dependent_move (GnmDependent
*dep
, int dx
, int dy
);
105 GOUndo
*dependents_relocate (GnmExprRelocateInfo
const *info
);
106 void dependents_link (GSList
*deps
);
108 void gnm_cell_eval (GnmCell
*cell
);
109 void cell_queue_recalc (GnmCell
*cell
);
110 void cell_foreach_dep (GnmCell
const *cell
, GnmDepFunc func
, gpointer user
);
112 void sheet_region_queue_recalc (Sheet
const *sheet
, GnmRange
const *range
);
113 void dependents_invalidate_sheet (Sheet
*sheet
, gboolean destroy
);
114 void dependents_workbook_destroy (Workbook
*wb
);
115 void dependents_revive_sheet (Sheet
*sheet
);
116 void workbook_queue_all_recalc (Workbook
*wb
);
117 void workbook_queue_volatile_recalc (Workbook
*wb
);
119 void gnm_dep_style_dependency (Sheet
*sheet
,
120 GnmExprTop
const *texpr
,
124 GnmDepContainer
*gnm_dep_container_new (Sheet
*sheet
);
125 void gnm_dep_container_dump (GnmDepContainer
const *deps
,
127 void dependents_dump (Workbook
*wb
);
128 void gnm_dep_container_sanity_check (GnmDepContainer
const *deps
);
129 void gnm_dep_container_resize (GnmDepContainer
*deps
, int rows
);
131 void dependent_managed_init (GnmDependent
*dep
, Sheet
*sheet
);
132 void dependent_managed_set_expr (GnmDependent
*dep
, GnmExprTop
const *texpr
);
133 void dependent_managed_set_sheet (GnmDependent
*dep
, Sheet
*sheet
);
135 #define DEPENDENT_CONTAINER_FOREACH_DEPENDENT(dc, dep, code) \
137 GnmDependent *dep = (dc)->head; \
139 GnmDependent *_next = dep->next_dep; \
145 #define DEPENDENT_MAKE_TYPE(t, set_expr_handler) \
147 t ## _get_dep_type (void) \
149 static guint32 type = 0; \
151 static GnmDependentClass klass; \
152 klass.eval = &t ## _eval; \
153 klass.set_expr = set_expr_handler; \
154 klass.changed = NULL; \
156 klass.debug_name = &t ## _debug_name; \
157 type = dependent_type_register (&klass); \
162 void dependent_debug_name (GnmDependent
const *dep
, GString
*target
);
166 #endif /* _GNM_DEPENDENT_H_ */