[gnumeric] Deps: implement style dependents -- not hooked up yet.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] Deps: implement style dependents -- not hooked up yet.
- Date: Thu, 7 Feb 2013 14:13:39 +0000 (UTC)
commit 0acb4c9e12521fb20b13c128bca96e3cf97fec89
Author: Morten Welinder <terra gnome org>
Date: Thu Feb 7 09:11:46 2013 -0500
Deps: implement style dependents -- not hooked up yet.
This contains the basics for style dependents, i.e., dependents for
conditional formatting to trigger rerendering and redrawing of cells.
This isn't actually hooked up yet.
ChangeLog | 10 +++++
src/dependent.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++
src/dependent.h | 5 ++
src/gnm-style-impl.h | 2 +
src/mstyle.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++
src/mstyle.h | 5 ++
6 files changed, 223 insertions(+), 0 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 742f13d..9f5aa35 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2013-02-07 Morten Welinder <terra gnome org>
+
+ * src/dependent.c (GnmStyleDependent): New type of dependent.
+ When triggered, the cells in which it resised will be rerendered
+ and redrawn.
+
+ * src/mstyle.c (gnm_style_link_dependents)
+ (gnm_style_unlink_dependents): New functions to manage style
+ dependents due to conditional formatting.
+
2013-02-06 Morten Welinder <terra gnome org>
* src/sheet-style.c (vector_apply_pstyle): Turn loop structure
diff --git a/src/dependent.c b/src/dependent.c
index a64dae9..65bc7fa 100644
--- a/src/dependent.c
+++ b/src/dependent.c
@@ -283,6 +283,22 @@ static const GnmDependentClass managed_dep_class = {
managed_dep_debug_name,
};
+static GSList *style_dep_changed (GnmDependent *dep);
+static GnmCellPos const *style_dep_pos (GnmDependent const *dep);
+static void style_dep_debug_name (GnmDependent const *dep, GString *target);
+static const GnmDependentClass style_dep_class = {
+ dummy_dep_eval,
+ NULL,
+ style_dep_changed,
+ style_dep_pos,
+ style_dep_debug_name,
+};
+typedef struct {
+ GnmDependent base;
+ GnmCellPos pos;
+} GnmStyleDependent;
+
+
static GPtrArray *dep_classes = NULL;
void
@@ -297,6 +313,7 @@ dependent_types_init (void)
g_ptr_array_add (dep_classes, (gpointer)&dynamic_dep_class);
g_ptr_array_add (dep_classes, (gpointer)&name_dep_class);
g_ptr_array_add (dep_classes, (gpointer)&managed_dep_class);
+ g_ptr_array_add (dep_classes, (gpointer)&style_dep_class);
#if USE_POOLS
micro_few_pool =
@@ -1152,6 +1169,39 @@ workbook_unlink_3d_dep (GnmDependent *dep)
g_hash_table_remove (wb->sheet_order_dependents, dep);
}
+GSList *
+gnm_dep_style_dependency (Sheet *sheet,
+ GnmExprTop const *texpr,
+ GnmRange const *r)
+{
+ int row, col;
+ GSList *res = NULL;
+
+ /*
+ * FIXME: Maybe do better for an expression that is just an
+ * absolute ref.
+ */
+
+ for (row = r->start.row; row <= r->end.row; row++) {
+ for (col = r->start.col; col <= r->end.col; col++) {
+ GnmStyleDependent *sd = g_new0 (GnmStyleDependent, 1);
+ GnmDependent *dep = &sd->base;
+
+ dep->sheet = sheet;
+ dep->flags = DEPENDENT_STYLE;
+ dep->texpr = NULL;
+ sd->pos.col = col;
+ sd->pos.row = row;
+
+ dependent_set_expr (dep, texpr);
+ dependent_link (dep);
+ res = g_slist_prepend (res, dep);
+ }
+ }
+
+ return res;
+}
+
/*****************************************************************************/
static void
@@ -1272,6 +1322,55 @@ managed_dep_debug_name (GnmDependent const *dep, GString *target)
/*****************************************************************************/
+static gboolean
+debug_style_deps (void)
+{
+ static int debug = -1;
+ if (debug < 0)
+ debug = gnm_debug_flag ("style-deps");
+ return debug;
+}
+
+static GSList *
+style_dep_changed (GnmDependent *dep)
+{
+ GnmCellPos const *pos = dependent_pos (dep);
+ GnmCell *cell;
+ Sheet *sheet = dep->sheet;
+
+ if (debug_style_deps ())
+ g_printerr ("StyleDep %p at %s changed\n",
+ dep, cellpos_as_string (pos));
+
+ /*
+ * If the cell exists, unrender it so format changes can take
+ * effect.
+ */
+ cell = sheet_cell_get (sheet, pos->col, pos->row);
+ if (cell)
+ gnm_cell_unrender (cell);
+
+ sheet_redraw_region (sheet,
+ pos->col, pos->row,
+ pos->col, pos->row);
+
+ return NULL;
+}
+
+static GnmCellPos const *
+style_dep_pos (GnmDependent const *dep)
+{
+ return &((GnmStyleDependent*)dep)->pos;
+}
+
+static void
+style_dep_debug_name (GnmDependent const *dep, GString *target)
+{
+ g_string_append_printf (target, "StyleDep%p", (void *)dep);
+}
+
+/*****************************************************************************/
+
static void
name_dep_debug_name (GnmDependent const *dep, GString *target)
{
diff --git a/src/dependent.h b/src/dependent.h
index aa150ff..82d2dbb 100644
--- a/src/dependent.h
+++ b/src/dependent.h
@@ -32,6 +32,7 @@ typedef enum {
DEPENDENT_DYNAMIC_DEP = 0x00000002, /* builtin type */
DEPENDENT_NAME = 0x00000003, /* builtin pseudo type */
DEPENDENT_MANAGED = 0x00000004, /* builtin type */
+ DEPENDENT_STYLE = 0x00000005, /* builtin type */
DEPENDENT_TYPE_MASK = 0x00000fff,
/* Linked into the workbook wide expression list */
@@ -110,6 +111,10 @@ void dependents_workbook_destroy (Workbook *wb);
void dependents_revive_sheet (Sheet *sheet);
void workbook_queue_all_recalc (Workbook *wb);
+GSList *gnm_dep_style_dependency (Sheet *sheet,
+ GnmExprTop const *texpr,
+ GnmRange const *r);
+
GnmDepContainer *gnm_dep_container_new (Sheet *sheet);
void gnm_dep_container_dump (GnmDepContainer const *deps,
Sheet *sheet);
diff --git a/src/gnm-style-impl.h b/src/gnm-style-impl.h
index 1d3af77..7e58cb0 100644
--- a/src/gnm-style-impl.h
+++ b/src/gnm-style-impl.h
@@ -64,6 +64,8 @@ struct _GnmStyle {
GnmInputMsg *input_msg;
GnmStyleConditions *conditions;
GPtrArray *cond_styles;
+
+ GSList *deps;
};
#define elem_changed(style, elem) do { (style)->changed |= (1u << (elem)); } while(0)
diff --git a/src/mstyle.c b/src/mstyle.c
index a134f9d..cd6fa3f 100644
--- a/src/mstyle.c
+++ b/src/mstyle.c
@@ -16,7 +16,10 @@
#include "sheet-style.h"
#include "style-conditions.h"
#include "application.h"
+#include "parse-util.h"
+#include "expr.h"
#include "gutils.h"
+#include "ranges.h"
#include "gnumeric-conf.h"
#include <goffice/goffice.h>
@@ -733,6 +736,9 @@ gnm_style_unref (GnmStyle const *style)
gnm_style_clear_pango (unconst);
gnm_style_clear_font (unconst);
+ if (style->deps)
+ g_warning ("Leftover style deps!");
+
CHUNK_FREE (gnm_style_pool, unconst);
}
}
@@ -1748,6 +1754,102 @@ gnm_style_get_conditions (GnmStyle const *style)
return style->conditions;
}
+static gboolean
+debug_style_deps (void)
+{
+ static int debug = -1;
+ if (debug < 0)
+ debug = gnm_debug_flag ("style-deps");
+ return debug;
+}
+
+void
+gnm_style_link_dependents (GnmStyle *style, GnmRange const *r)
+{
+ GnmStyleConditions *sc;
+ Sheet *sheet;
+ GSList *deps;
+
+ g_return_if_fail (style != NULL);
+ g_return_if_fail (r != NULL);
+
+ sheet = style->linked_sheet;
+ deps = style->deps;
+
+ /*
+ * Conditional formatting.
+ *
+ * We need to trigger a reformatting of the cell if a cell referenced
+ * by the condition changes.
+ */
+ sc = elem_is_set (style, MSTYLE_CONDITIONS)
+ ? gnm_style_get_conditions (style)
+ : NULL;
+ if (sc) {
+ GPtrArray const *conds = gnm_style_conditions_details (sc);
+ guint ui;
+ if (debug_style_deps ())
+ g_printerr ("Linking %s for %p\n",
+ range_as_string (r), style);
+ for (ui = 0; ui < conds->len; ui++) {
+ GnmStyleCond const *c = g_ptr_array_index (conds, ui);
+ guint ei;
+
+ for (ei = 0; ei < 2; ei++) {
+ GnmExprTop const *texpr =
+ gnm_style_cond_get_expr (c, ei);
+ if (!texpr)
+ continue;
+ deps = g_slist_concat
+ (deps,
+ gnm_dep_style_dependency
+ (sheet, texpr, r));
+ }
+ }
+ }
+
+ /*
+ * Validations.
+ *
+ * We can probably ignore those. If a dependent cell changes such
+ * that a validation condition is no longer satisfied, it is
+ * grandfathered in a valid.
+ */
+
+ /* The style owns the deps. */
+ style->deps = deps;
+}
+
+void
+gnm_style_unlink_dependents (GnmStyle *style, GnmRange const *r)
+{
+ GSList *keep = NULL, *l, *next;
+
+ g_return_if_fail (style != NULL);
+ g_return_if_fail (r != NULL);
+
+ for (l = style->deps; l; l = next) {
+ GnmDependent *dep = l->data;
+ GnmCellPos const *pos = dependent_pos (dep);
+ next = l->next;
+
+ if (range_contains (r, pos->col, pos->row)) {
+ if (debug_style_deps ())
+ g_printerr ("Unlinking %s for %p\n",
+ cellpos_as_string (pos), style);
+ dependent_set_expr (dep, NULL);
+ g_free (dep);
+ g_slist_free_1 (l);
+ } else {
+ l->next = keep;
+ keep = l;
+ }
+ }
+
+ style->deps = keep;
+}
+
+
gboolean
gnm_style_visible_in_blank (GnmStyle const *style)
{
diff --git a/src/mstyle.h b/src/mstyle.h
index db1de9e..3a73eb2 100644
--- a/src/mstyle.h
+++ b/src/mstyle.h
@@ -158,6 +158,11 @@ GnmInputMsg *gnm_style_get_input_msg (GnmStyle const *style);
void gnm_style_set_conditions (GnmStyle *style, GnmStyleConditions *sc);
GnmStyleConditions *gnm_style_get_conditions (GnmStyle const *style);
+void gnm_style_link_dependents (GnmStyle *style,
+ GnmRange const *r);
+void gnm_style_unlink_dependents (GnmStyle *style,
+ GnmRange const *r);
+
gboolean gnm_style_visible_in_blank (GnmStyle const *style);
PangoAttrList *gnm_style_generate_attrs_full (GnmStyle const *style);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]