~ubuntu-branches/ubuntu/quantal/gnumeric/quantal

« back to all changes in this revision

Viewing changes to src/position.c

  • Committer: Bazaar Package Importer
  • Author(s): Gauvain Pocentek
  • Date: 2009-06-07 11:10:47 UTC
  • mfrom: (1.1.19 upstream) (2.1.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090607111047-l3rtbzfjxvmi1kx0
Tags: 1.9.8-1ubuntu1
* Merge from debian unstable, remaining changes:
  - Promoted gnumeric-doc to Recommends in gnumeric package for help to be
    installed automatically
  - gnumeric-gtk is a transitional package
  - gnumeric conflicts with gnumeric-gtk << 1.8.3-3ubuntu1
  - call initltool-update in po*
  - remove psiconv support (psiconv is in universe):
    o debian/control: remove B-D on libpsiconv-dev
    o debian/rules: don't pass --with-psiconv to ./configure

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
 *         coordinates.
5
5
 *
6
6
 * Copyright (C) 2000-2005 Jody Goldberg (jody@gnome.org)
 
7
 * Copyright (C) 2006-2009 Morten Welinder (terra@gnome.org)
7
8
 *
8
9
 * This program is free software; you can redistribute it and/or
9
10
 * modify it under the terms of the GNU General Public License as
30
31
#include "cell.h"
31
32
#include "value.h"
32
33
#include "ranges.h"
 
34
#include "workbook.h"
33
35
 
34
36
 
35
37
GnmEvalPos *
125
127
}
126
128
 
127
129
GnmEvalPos *
128
 
eval_pos_init_sheet (GnmEvalPos *ep, Sheet *sheet)
 
130
eval_pos_init_sheet (GnmEvalPos *ep, Sheet const *sheet)
129
131
{
130
132
        g_return_val_if_fail (ep != NULL, NULL);
131
133
        g_return_val_if_fail (IS_SHEET (sheet), NULL);
132
134
 
133
135
        ep->eval.col = ep->eval.row = 0;
134
 
        ep->sheet = sheet;
 
136
        ep->sheet = (Sheet *)sheet;
135
137
        ep->dep   = NULL;
136
138
        ep->array = NULL;
137
139
 
151
153
 * ParsePosition.
152
154
 */
153
155
GnmParsePos *
154
 
parse_pos_init (GnmParsePos *pp, Workbook *wb, Sheet *sheet, int col, int row)
 
156
parse_pos_init (GnmParsePos *pp, Workbook *wb, Sheet const *sheet,
 
157
                int col, int row)
155
158
{
156
159
        /* Global */
157
160
        if (wb == NULL && sheet == NULL)
159
162
 
160
163
        g_return_val_if_fail (pp != NULL, NULL);
161
164
 
162
 
        pp->sheet = sheet;
 
165
        pp->sheet = (Sheet *)sheet;
163
166
        pp->wb = sheet ? sheet->workbook : wb;
164
167
        pp->eval.col = col;
165
168
        pp->eval.row = row;
217
220
}
218
221
 
219
222
GnmParsePos *
220
 
parse_pos_init_sheet (GnmParsePos *pp, Sheet *sheet)
 
223
parse_pos_init_sheet (GnmParsePos *pp, Sheet const *sheet)
221
224
{
222
225
        g_return_val_if_fail (pp != NULL, NULL);
223
226
        g_return_val_if_fail (IS_SHEET (sheet), NULL);
250
253
guint
251
254
gnm_cellref_hash (GnmCellRef const *cr)
252
255
{
253
 
        guint h = ((cr->row << 8) ^ cr->col) * 4;
254
 
        if (cr->col_relative) h |= 1;
255
 
        if (cr->row_relative) h |= 2;
 
256
        guint h = cr->row;
 
257
        h = (h << 16) | (h >> 16);
 
258
        h ^= (cr->col << 2);
 
259
        if (cr->col_relative) h ^= 1;
 
260
        if (cr->row_relative) h ^= 2;
256
261
        return h;
257
262
}
258
263
 
263
268
        g_return_val_if_fail (ep != NULL, 0);
264
269
 
265
270
        if (ref->col_relative) {
266
 
                int res = (ep->eval.col + ref->col) % gnm_sheet_get_max_cols (ref->sheet);
 
271
                Sheet const *sheet = eval_sheet (ref->sheet, ep->sheet);
 
272
                int res = (ep->eval.col + ref->col) % gnm_sheet_get_max_cols (sheet);
267
273
                if (res < 0)
268
 
                        return res + gnm_sheet_get_max_cols (ref->sheet);
 
274
                        return res + gnm_sheet_get_max_cols (sheet);
269
275
                return res;
270
276
        }
271
277
        return ref->col;
278
284
        g_return_val_if_fail (ep != NULL, 0);
279
285
 
280
286
        if (ref->row_relative) {
281
 
                int res = (ep->eval.row + ref->row) % gnm_sheet_get_max_rows (ref->sheet);
 
287
                Sheet const *sheet = eval_sheet (ref->sheet, ep->sheet);
 
288
                int res = (ep->eval.row + ref->row) % gnm_sheet_get_max_rows (sheet);
282
289
                if (res < 0)
283
 
                        return res + gnm_sheet_get_max_rows (ref->sheet);
 
290
                        return res + gnm_sheet_get_max_rows (sheet);
284
291
                return res;
285
292
        }
286
293
        return ref->row;
287
294
}
288
295
 
289
296
void
290
 
gnm_cellpos_init_cellref (GnmCellPos *res,
291
 
                          GnmCellRef const *cell_ref, GnmCellPos const *pos)
 
297
gnm_cellpos_init_cellref_ss (GnmCellPos *res, GnmCellRef const *cell_ref,
 
298
                             GnmCellPos const *pos, GnmSheetSize const *ss)
292
299
{
293
300
        g_return_if_fail (cell_ref != NULL);
294
301
        g_return_if_fail (res != NULL);
295
302
 
296
303
        if (cell_ref->col_relative) {
297
 
                res->col = (cell_ref->col + pos->col) % gnm_sheet_get_max_cols (cell_ref->sheet);
298
 
                if (res->col < 0)
299
 
                        res->col += gnm_sheet_get_max_cols (cell_ref->sheet);
 
304
                int col = cell_ref->col + pos->col;
 
305
                int max = ss->max_cols;
 
306
                if (col < 0)
 
307
                        col += max;
 
308
                else if (col >= max)
 
309
                        col -= max;
 
310
                res->col = col;
300
311
        } else
301
312
                res->col = cell_ref->col;
302
313
 
303
314
        if (cell_ref->row_relative) {
304
 
                res->row = (cell_ref->row + pos->row) % gnm_sheet_get_max_rows (cell_ref->sheet);
305
 
                if (res->row < 0)
306
 
                        res->row += gnm_sheet_get_max_rows (cell_ref->sheet);
 
315
                int row = cell_ref->row + pos->row;
 
316
                int max = ss->max_rows;
 
317
                if (row < 0)
 
318
                        row += max;
 
319
                else if (row >= max)
 
320
                        row -= max;
 
321
                res->row = row;
307
322
        } else
308
323
                res->row = cell_ref->row;
309
324
}
310
325
 
311
326
void
 
327
gnm_cellpos_init_cellref (GnmCellPos *res, GnmCellRef const *cell_ref,
 
328
                          GnmCellPos const *pos, Sheet const *base_sheet)
 
329
{
 
330
        Sheet const *sheet = eval_sheet (cell_ref->sheet, base_sheet);
 
331
        gnm_cellpos_init_cellref_ss (res, cell_ref, pos,
 
332
                                     gnm_sheet_get_size (sheet));
 
333
}
 
334
 
 
335
void
312
336
gnm_cellref_make_abs (GnmCellRef *dest, GnmCellRef const *src, GnmEvalPos const *ep)
313
337
{
 
338
        GnmCellPos pos;
 
339
 
314
340
        g_return_if_fail (dest != NULL);
315
341
        g_return_if_fail (src != NULL);
316
342
        g_return_if_fail (ep != NULL);
317
343
 
318
 
        *dest = *src;
319
 
        if (src->col_relative) {
320
 
                dest->col = (dest->col + ep->eval.col) % gnm_sheet_get_max_cols (dest->sheet);
321
 
                if (dest->col < 0)
322
 
                        dest->col += gnm_sheet_get_max_cols (dest->sheet);
323
 
        }
324
 
 
325
 
        if (src->row_relative) {
326
 
                dest->row = (dest->row + ep->eval.row) % gnm_sheet_get_max_rows (dest->sheet);
327
 
                if (dest->row < 0)
328
 
                        dest->row += gnm_sheet_get_max_rows (dest->sheet);
329
 
        }
330
 
 
331
 
        dest->row_relative = dest->col_relative = FALSE;
 
344
        gnm_cellpos_init_cellref (&pos, src, &ep->eval, ep->sheet);
 
345
 
 
346
        dest->sheet = src->sheet;
 
347
        dest->col = pos.col;
 
348
        dest->row = pos.row;
 
349
        dest->col_relative = FALSE;
 
350
        dest->row_relative = FALSE;
332
351
}
333
352
 
334
353
void
365
384
guint
366
385
gnm_rangeref_hash (GnmRangeRef const *rr)
367
386
{
368
 
        return gnm_cellref_hash (&rr->a) << 16 | gnm_cellref_hash (&rr->b);
 
387
        guint h = gnm_cellref_hash (&rr->a);
 
388
        h = (h << 16) | (h >> 16);
 
389
        h ^= gnm_cellref_hash (&rr->b);
 
390
        return h;
369
391
}
370
392
 
371
393
GnmRangeRef *
385
407
 *     by converting to absolute coords and handling inversions.
386
408
 */
387
409
void
 
410
gnm_rangeref_normalize_pp (GnmRangeRef const *ref, GnmParsePos const *pp,
 
411
                           Sheet **start_sheet, Sheet **end_sheet,
 
412
                           GnmRange *dest)
 
413
{
 
414
        GnmSheetSize const *ss;
 
415
 
 
416
        g_return_if_fail (ref != NULL);
 
417
        g_return_if_fail (pp != NULL);
 
418
 
 
419
        *start_sheet = eval_sheet (ref->a.sheet, pp->sheet);
 
420
        *end_sheet   = eval_sheet (ref->b.sheet, *start_sheet);
 
421
 
 
422
        ss = gnm_sheet_get_size2 (*start_sheet, pp->wb);
 
423
        gnm_cellpos_init_cellref_ss (&dest->start, &ref->a, &pp->eval, ss);
 
424
 
 
425
        ss = *end_sheet
 
426
                ? gnm_sheet_get_size (*end_sheet)
 
427
                : ss;
 
428
        gnm_cellpos_init_cellref_ss (&dest->end, &ref->b, &pp->eval, ss);
 
429
 
 
430
        range_normalize (dest);
 
431
}
 
432
 
 
433
void
388
434
gnm_rangeref_normalize (GnmRangeRef const *ref, GnmEvalPos const *ep,
389
435
                        Sheet **start_sheet, Sheet **end_sheet, GnmRange *dest)
390
436
{
391
 
        g_return_if_fail (ref != NULL);
392
 
        g_return_if_fail (ep != NULL);
393
 
 
394
 
        gnm_cellpos_init_cellref (&dest->start, &ref->a, &ep->eval);
395
 
        gnm_cellpos_init_cellref (&dest->end, &ref->b, &ep->eval);
396
 
        range_normalize (dest);
397
 
 
398
 
        *start_sheet = eval_sheet (ref->a.sheet, ep->sheet);
399
 
        *end_sheet   = eval_sheet (ref->b.sheet, *start_sheet);
 
437
        GnmParsePos pp;
 
438
 
 
439
        parse_pos_init_evalpos (&pp, ep);
 
440
        gnm_rangeref_normalize_pp (ref, &pp, start_sheet, end_sheet, dest);
400
441
}
401
442
 
402
443
guint
403
444
gnm_cellpos_hash (GnmCellPos const *key)
404
445
{
405
 
        return (key->row << 8) | key->col;
 
446
        guint h = key->row;
 
447
        h = (h << 16) | (h >> 16);
 
448
        h ^= key->col;
 
449
        return h;
406
450
}
407
451
 
408
452
gint