Fixed typos
[gnumeric.git] / plugins / excel / ms-container.c
blobd0a212bb21e187f35e2ceae9f147627097231e1c
1 /* vim: set sw=8: */
3 /**
4 * ms-container.c: A meta container to handle object import for charts,
5 * workbooks and sheets.
7 * Author:
8 * Jody Goldberg (jody@gnome.org)
10 * (C) 2000-2005 Jody Goldberg
11 **/
13 #include <gnumeric-config.h>
14 #include <gnumeric.h>
15 #include "ms-container.h"
16 #include "ms-escher.h"
17 #include "ms-obj.h"
18 #include "ms-excel-util.h"
20 #include <expr-name.h>
21 #include <value.h>
23 #include <gsf/gsf-utils.h>
25 void
26 ms_container_init (MSContainer *container, MSContainerClass const *vtbl,
27 MSContainer *parent, GnmXLImporter *importer)
29 container->vtbl = vtbl;
30 container->importer = importer;
31 container->free_blips = TRUE;
32 container->blips = NULL;
33 container->obj_queue = NULL;
34 container->parent = parent;
36 container->v7.externsheets = NULL;
37 container->v7.externnames = NULL;
40 void
41 ms_container_finalize (MSContainer *container)
43 int i;
45 g_return_if_fail (container != NULL);
47 if (container->free_blips && container->blips != NULL) {
48 for (i = container->blips->len; i-- > 0 ; ) {
49 MSEscherBlip *blip = g_ptr_array_index (container->blips, i);
50 if (blip != NULL)
51 ms_escher_blip_free (blip);
54 g_ptr_array_free (container->blips, TRUE);
55 container->blips = NULL;
58 if (container->obj_queue != NULL) {
59 GSList *ptr;
60 for (ptr = container->obj_queue; ptr != NULL; ptr = ptr->next)
61 ms_obj_delete (ptr->data);
63 g_slist_free (container->obj_queue);
64 container->obj_queue = NULL;
67 if (container->v7.externsheets != NULL) {
68 g_ptr_array_free (container->v7.externsheets, TRUE);
69 container->v7.externsheets = NULL;
71 if (container->v7.externnames != NULL) {
72 for (i = container->v7.externnames->len; i-- > 0 ; )
73 if (g_ptr_array_index (container->v7.externnames, i) != NULL) {
74 GnmNamedExpr *nexpr = g_ptr_array_index (container->v7.externnames, i);
75 if (nexpr != NULL) {
76 /* NAME placeholders need removal, EXTERNNAME placeholders
77 * will no be active */
78 if (expr_name_is_active (nexpr) &&
79 expr_name_is_placeholder (nexpr) &&
80 /* FIXME: Why do we need this? */
81 nexpr->ref_count == 2)
82 expr_name_remove (nexpr);
83 expr_name_unref (nexpr);
86 g_ptr_array_free (container->v7.externnames, TRUE);
87 container->v7.externnames = NULL;
91 void
92 ms_container_add_blip (MSContainer *container, MSEscherBlip *blip)
94 if (container->blips == NULL)
95 container->blips = g_ptr_array_new ();
96 g_ptr_array_add (container->blips, blip);
99 MSEscherBlip *
100 ms_container_get_blip (MSContainer *container, int blip_id)
102 g_return_val_if_fail (container != NULL, NULL);
103 g_return_val_if_fail (blip_id >= 0, NULL);
105 if (container->parent != NULL &&
106 (container->blips == NULL || container->blips->len == 0))
107 return ms_container_get_blip (container->parent, blip_id);
109 g_return_val_if_fail (container->blips != NULL, NULL);
110 g_return_val_if_fail (blip_id < (int)container->blips->len, NULL);
112 return g_ptr_array_index (container->blips, blip_id);
115 void
116 ms_container_set_blips (MSContainer *container, GPtrArray *blips)
118 g_return_if_fail (container != NULL);
119 g_return_if_fail (container->blips == NULL || container->blips == blips);
121 container->blips = blips;
122 container->free_blips = FALSE;
125 void
126 ms_container_add_obj (MSContainer *container, MSObj *obj)
128 #if 0
129 g_warning ("registered obj %d\n", obj->id);
130 #endif
131 container->obj_queue = g_slist_prepend (container->obj_queue, obj);
134 MSObj *
135 ms_container_get_obj (MSContainer *c, int obj_id)
137 GSList *ptr;
139 for (ptr = c->obj_queue ; ptr != NULL ; ptr = ptr->next) {
140 MSObj *obj = ptr->data;
141 if (obj != NULL && obj->id == obj_id)
142 return obj;
144 g_warning ("did not find %d\n", obj_id);
145 return NULL;
149 * ms_container_realize_objs:
150 * @container:
152 * This realizes the objects after the zoom factor has been
153 * loaded.
155 void
156 ms_container_realize_objs (MSContainer *container)
158 GSList *ptr;
160 g_return_if_fail (container != NULL);
161 g_return_if_fail (container->vtbl != NULL);
162 g_return_if_fail (container->vtbl->realize_obj != NULL);
164 for (ptr = container->obj_queue; ptr != NULL; ptr = ptr->next) {
165 MSObj *obj = ptr->data;
166 if (obj->gnum_obj != NULL)
167 (void) (*container->vtbl->realize_obj) (container, obj);
172 * ms_container_parse_expr:
174 * @c: The container
175 * @data: the encoded expression
176 * @length: the size of the encoded expression
178 * Attempts to parse the encoded expression in the context of the container.
180 GnmExprTop const *
181 ms_container_parse_expr (MSContainer *c, guint8 const *data, int length)
183 g_return_val_if_fail (c != NULL, NULL);
184 g_return_val_if_fail (c->vtbl != NULL, NULL);
185 g_return_val_if_fail (c->vtbl->parse_expr != NULL, NULL);
186 if (length == 0)
187 return NULL;
188 return (*c->vtbl->parse_expr) (c, data, length);
192 * ms_container_sheet:
194 * @c: The container
196 * DEPRECATED !
197 * This will become dependent_container when that abstraction is added
198 * in the code. We will need it to support tabs with standalone charts.
199 * DEPRECATED !
201 Sheet *
202 ms_container_sheet (MSContainer const *c)
204 g_return_val_if_fail (c != NULL, NULL);
205 g_return_val_if_fail (c->vtbl != NULL, NULL);
206 if (c->vtbl->sheet == NULL)
207 return NULL;
208 return (*c->vtbl->sheet) (c);
211 GOFormat *
212 ms_container_get_fmt (MSContainer const *c, unsigned indx)
214 for ( ; TRUE ; c = c->parent) {
215 g_return_val_if_fail (c != NULL, NULL);
216 g_return_val_if_fail (c->vtbl != NULL, NULL);
217 if (c->vtbl->get_fmt != NULL)
218 break;
220 return (*c->vtbl->get_fmt) (c, indx);
224 * ms_container_get_markup :
225 * @c: #MSContainer
226 * @indx:
228 * Return a #PangoAttrList the caller should not modify or free the list.
230 PangoAttrList *
231 ms_container_get_markup (MSContainer const *c, unsigned indx)
233 for ( ; TRUE ; c = c->parent) {
234 g_return_val_if_fail (c != NULL, NULL);
235 g_return_val_if_fail (c->vtbl != NULL, NULL);
236 if (c->vtbl->get_markup != NULL)
237 break;
239 return (*c->vtbl->get_markup) (c, indx);
242 typedef struct {
243 unsigned first, last;
244 PangoAttrList *accum;
245 } TXORun;
247 static gboolean
248 append_txorun (PangoAttribute *src, TXORun *run)
250 PangoAttribute *dst = pango_attribute_copy (src);
251 dst->start_index = run->first; /* inclusive */
252 dst->end_index = run->last; /* exclusive */
253 pango_attr_list_change (run->accum, dst);
254 return FALSE;
257 PangoAttrList *
258 ms_container_read_markup (MSContainer const *c,
259 guint8 const *data, size_t txo_len,
260 char const *str)
262 TXORun txo_run;
263 size_t str_len;
265 XL_CHECK_CONDITION_VAL (txo_len >= 16,
266 pango_attr_list_new ()); /* min two records */
268 str_len = g_utf8_strlen (str, -1);
270 txo_run.last = G_MAXINT;
271 txo_run.accum = NULL;
272 for (txo_len -= 16 ; (gssize)txo_len >= 0 ; txo_len -= 8) {
273 guint16 o = GSF_LE_GET_GUINT16 (data + txo_len);
274 guint16 idx = GSF_LE_GET_GUINT16 (data + txo_len + 2);
276 XL_CHECK_CONDITION_VAL (o <= str_len, txo_run.accum);
277 txo_run.first = g_utf8_offset_to_pointer (str, o) - str;
278 XL_CHECK_CONDITION_VAL (txo_run.first < txo_run.last, txo_run.accum);
280 if (idx != 0) {
281 if (!txo_run.accum)
282 txo_run.accum = pango_attr_list_new ();
283 pango_attr_list_filter
284 (ms_container_get_markup (c, idx),
285 (PangoAttrFilterFunc) append_txorun,
286 &txo_run);
288 txo_run.last = txo_run.first;
290 return txo_run.accum;