static void restore_cursor (ETreeSelectionModel *etsm, ETreeModel *etm) { clear_selection (etsm); etsm->priv->cursor_path = NULL; if (etsm->priv->cursor_save_id) { etsm->priv->cursor_path = e_tree_model_get_node_by_id ( etm, etsm->priv->cursor_save_id); if (etsm->priv->cursor_path != NULL && etsm->priv->cursor_col == -1) etsm->priv->cursor_col = 0; select_single_path (etsm, etsm->priv->cursor_path); } e_selection_model_selection_changed (E_SELECTION_MODEL (etsm)); if (etsm->priv->cursor_path) { gint cursor_row = get_cursor_row (etsm); e_selection_model_cursor_changed ( E_SELECTION_MODEL (etsm), cursor_row, etsm->priv->cursor_col); } else { e_selection_model_cursor_changed ( E_SELECTION_MODEL (etsm), -1, -1); e_selection_model_cursor_activated ( E_SELECTION_MODEL (etsm), -1, -1); } free_id (etsm); }
static void tree_selection_model_select_all (ESelectionModel *selection) { ETreeSelectionModel *etsm = E_TREE_SELECTION_MODEL (selection); ETreePath root; root = e_tree_model_get_root (etsm->priv->model); if (root == NULL) return; clear_selection (etsm); /* We want to select ALL rows regardless of expanded state. * ETreeTableAdapter pretends that collapsed rows don't exist, * so instead we need to iterate over the ETreeModel directly. */ e_tree_model_node_traverse ( etsm->priv->model, root, tree_selection_model_traverse_cb, selection); if (etsm->priv->cursor_path == NULL) etsm->priv->cursor_path = e_tree_table_adapter_node_at_row ( etsm->priv->etta, 0); e_selection_model_selection_changed (E_SELECTION_MODEL (etsm)); e_selection_model_cursor_changed ( E_SELECTION_MODEL (etsm), get_cursor_row (etsm), etsm->priv->cursor_col); }
static void tree_selection_model_clear (ESelectionModel *selection) { ETreeSelectionModel *etsm = E_TREE_SELECTION_MODEL (selection); clear_selection (etsm); etsm->priv->cursor_path = NULL; e_selection_model_selection_changed (E_SELECTION_MODEL (etsm)); e_selection_model_cursor_changed (E_SELECTION_MODEL (etsm), -1, -1); }
static inline void e_reflow_update_selection_row (EReflow *reflow, int row) { if (reflow->items[row]) { g_object_set(reflow->items[row], "selected", e_selection_model_is_row_selected(E_SELECTION_MODEL(reflow->selection), row), NULL); } else if (e_selection_model_is_row_selected (E_SELECTION_MODEL (reflow->selection), row)) { reflow->items[row] = e_reflow_model_incarnate (reflow->model, row, GNOME_CANVAS_GROUP (reflow)); g_object_set (reflow->items[row], "selected", e_selection_model_is_row_selected(E_SELECTION_MODEL(reflow->selection), row), "width", (double) reflow->column_width, NULL); } }
static void tree_selection_model_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { ESelectionModel *esm = E_SELECTION_MODEL (object); ETreeSelectionModel *etsm = E_TREE_SELECTION_MODEL (object); switch (property_id) { case PROP_CURSOR_ROW: e_selection_model_do_something ( esm, g_value_get_int (value), etsm->priv->cursor_col, 0); break; case PROP_CURSOR_COL: e_selection_model_do_something ( esm, get_cursor_row (etsm), g_value_get_int (value), 0); break; case PROP_MODEL: drop_model (etsm); add_model (etsm, E_TREE_MODEL (g_value_get_object (value))); break; case PROP_ETTA: etsm->priv->etta = E_TREE_TABLE_ADAPTER (g_value_get_object (value)); break; } }
static void model_pre_change (ETableModel *etm, ETableSelectionModel *etsm) { free_hash (etsm); if (etsm->model && e_table_model_has_save_id (etsm->model)) { gint cursor_row; etsm->hash = g_hash_table_new_full ( g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) NULL); e_selection_model_foreach (E_SELECTION_MODEL (etsm), save_to_hash, etsm); g_object_get (etsm, "cursor_row", &cursor_row, NULL); g_free (etsm->cursor_id); if (cursor_row != -1) etsm->cursor_id = e_table_model_get_save_id (etm, cursor_row); else etsm->cursor_id = NULL; } }
static void esm_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { ESelectionModel *esm = E_SELECTION_MODEL (object); switch (property_id) { case PROP_SORTER: drop_sorter (esm); add_sorter ( esm, g_value_get_object (value) ? E_SORTER (g_value_get_object (value)) : NULL); break; case PROP_SELECTION_MODE: esm->mode = g_value_get_int (value); if (esm->mode == GTK_SELECTION_SINGLE) { gint cursor_row = e_selection_model_cursor_row (esm); gint cursor_col = e_selection_model_cursor_col (esm); e_selection_model_do_something (esm, cursor_row, cursor_col, 0); } break; case PROP_CURSOR_MODE: esm->cursor_mode = g_value_get_int (value); break; } }
static void tree_selection_model_select_single_row (ESelectionModel *selection, gint row) { ETreeSelectionModel *etsm = E_TREE_SELECTION_MODEL (selection); ETreePath path; gint rows[5], *rowp = NULL, size; path = e_tree_table_adapter_node_at_row (etsm->priv->etta, row); g_return_if_fail (path != NULL); /* we really only care about the size=1 case (cursor changed), * but this doesn't cost much */ size = g_hash_table_size (etsm->priv->paths); if (size > 0 && size <= 5) { rowp = rows; tree_selection_model_foreach (selection, etsm_get_rows, &rowp); } select_single_path (etsm, path); if (size > 5) { e_selection_model_selection_changed (E_SELECTION_MODEL (etsm)); } else { if (rowp) { gint *p = rows; while (p < rowp) e_selection_model_selection_row_changed ( (ESelectionModel *) etsm, *p++); } e_selection_model_selection_row_changed ( (ESelectionModel *) etsm, row); } }
static void set_initial_selection (ETableClickToAdd *etcta) { e_selection_model_do_something ( E_SELECTION_MODEL (etcta->selection), 0, e_table_header_prioritized_column (etcta->eth), 0); }
static void e_reflow_init (EReflow *reflow) { reflow->model = NULL; reflow->items = NULL; reflow->heights = NULL; reflow->count = 0; reflow->columns = NULL; reflow->column_count = 0; reflow->empty_text = NULL; reflow->empty_message = NULL; reflow->minimum_width = 10; reflow->width = 10; reflow->height = 10; reflow->column_width = 150; reflow->column_drag = FALSE; reflow->need_height_update = FALSE; reflow->need_column_resize = FALSE; reflow->need_reflow_columns = FALSE; reflow->maybe_did_something = FALSE; reflow->maybe_in_drag = FALSE; reflow->default_cursor_shown = TRUE; reflow->arrow_cursor = NULL; reflow->default_cursor = NULL; reflow->cursor_row = -1; reflow->incarnate_idle_id = 0; reflow->do_adjustment_idle_id = 0; reflow->set_scroll_adjustments_id = 0; reflow->selection = E_SELECTION_MODEL (e_selection_model_simple_new()); reflow->sorter = e_sorter_array_new (er_compare, reflow); g_object_set (reflow->selection, "sorter", reflow->sorter, NULL); reflow->selection_changed_id = g_signal_connect(reflow->selection, "selection_changed", G_CALLBACK (selection_changed), reflow); reflow->selection_row_changed_id = g_signal_connect(reflow->selection, "selection_row_changed", G_CALLBACK (selection_row_changed), reflow); reflow->cursor_changed_id = g_signal_connect(reflow->selection, "cursor_changed", G_CALLBACK (cursor_changed), reflow); e_canvas_item_set_reflow_callback(GNOME_CANVAS_ITEM(reflow), e_reflow_reflow); }
static void model_changed (ETableModel *etm, ETableSelectionModel *etsm) { e_selection_model_clear (E_SELECTION_MODEL (etsm)); if (!etsm->model_changed_idle_id && etm && e_table_model_has_save_id (etm)) { etsm->model_changed_idle_id = g_idle_add_full (G_PRIORITY_HIGH, (GSourceFunc) model_changed_idle, etsm, NULL); } }
static void tree_selection_model_move_selection_end (ESelectionModel *selection, gint row) { ETreeSelectionModel *etsm = E_TREE_SELECTION_MODEL (selection); g_return_if_fail (etsm->priv->cursor_path); etsm_real_move_selection_end (etsm, row); e_selection_model_selection_changed (E_SELECTION_MODEL (selection)); }
static void esm_dispose (GObject *object) { ESelectionModel *esm; esm = E_SELECTION_MODEL (object); drop_sorter(esm); if (G_OBJECT_CLASS (e_selection_model_parent_class)->dispose) (* G_OBJECT_CLASS (e_selection_model_parent_class)->dispose) (object); }
static void esm_dispose (GObject *object) { ESelectionModel *esm; esm = E_SELECTION_MODEL (object); drop_sorter (esm); /* Chain up to parent's dispose() method. */ G_OBJECT_CLASS (e_selection_model_parent_class)->dispose (object); }
static void finish_editing (ETableClickToAdd *etcta) { if (etcta->row) { ETableModel *one; e_table_item_leave_edit (E_TABLE_ITEM (etcta->row)); e_table_one_commit (E_TABLE_ONE (etcta->one)); etcta_drop_one (etcta); g_object_run_dispose (G_OBJECT (etcta->row)); etcta->row = NULL; if (etcta->text) { g_object_run_dispose (G_OBJECT (etcta->text)); etcta->text = NULL; } if (etcta->rect) { g_object_run_dispose (G_OBJECT (etcta->rect)); etcta->rect = NULL; } one = e_table_one_new (etcta->model); etcta_add_one (etcta, one); g_object_unref (one); e_selection_model_clear (E_SELECTION_MODEL (etcta->selection)); etcta->row = gnome_canvas_item_new ( GNOME_CANVAS_GROUP (etcta), e_table_item_get_type (), "ETableHeader", etcta->eth, "ETableModel", etcta->one, "minimum_width", etcta->width, "horizontal_draw_grid", TRUE, "vertical_draw_grid", TRUE, "selection_model", etcta->selection, "cursor_mode", E_CURSOR_SPREADSHEET, NULL); g_signal_connect ( etcta->row, "key_press", G_CALLBACK (item_key_press), etcta); e_signal_connect_notify ( etcta->row, "notify::is-editing", G_CALLBACK (table_click_to_add_row_is_editing_changed_cb), etcta); set_initial_selection (etcta); g_object_notify (G_OBJECT (etcta), "is-editing"); } }
static void incarnate (EReflow *reflow) { int column_width; int first_column; int last_column; int first_cell; int last_cell; int i; GtkAdjustment *adjustment = gtk_layout_get_hadjustment (GTK_LAYOUT (GNOME_CANVAS_ITEM (reflow)->canvas)); column_width = reflow->column_width; first_column = adjustment->value - 1 + E_REFLOW_BORDER_WIDTH; first_column /= column_width + E_REFLOW_FULL_GUTTER; last_column = adjustment->value + adjustment->page_size + 1 - E_REFLOW_BORDER_WIDTH - E_REFLOW_DIVIDER_WIDTH; last_column /= column_width + E_REFLOW_FULL_GUTTER; last_column ++; if (first_column >= 0 && first_column < reflow->column_count) first_cell = reflow->columns[first_column]; else first_cell = 0; if (last_column >= 0 && last_column < reflow->column_count) last_cell = reflow->columns[last_column]; else last_cell = reflow->count; for (i = first_cell; i < last_cell; i++) { int unsorted = e_sorter_sorted_to_model (E_SORTER (reflow->sorter), i); if (reflow->items[unsorted] == NULL) { if (reflow->model) { reflow->items[unsorted] = e_reflow_model_incarnate (reflow->model, unsorted, GNOME_CANVAS_GROUP (reflow)); g_object_set (reflow->items[unsorted], "selected", e_selection_model_is_row_selected(E_SELECTION_MODEL(reflow->selection), unsorted), "width", (double) reflow->column_width, NULL); } } } reflow->incarnate_idle_id = 0; }
static void esm_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { ESelectionModel *esm = E_SELECTION_MODEL (object); switch (prop_id){ case PROP_SORTER: g_value_set_object (value, esm->sorter); break; case PROP_SELECTION_MODE: g_value_set_int (value, esm->mode); break; case PROP_CURSOR_MODE: g_value_set_int (value, esm->cursor_mode); break; } }
static gint model_changed_idle (ETableSelectionModel *etsm) { ETableModel *etm = etsm->model; e_selection_model_clear (E_SELECTION_MODEL (etsm)); if (etsm->cursor_id && etm && e_table_model_has_save_id (etm)) { gint row_count = e_table_model_row_count (etm); gint cursor_row = -1; gint cursor_col = -1; gint i; e_selection_model_array_confirm_row_count (E_SELECTION_MODEL_ARRAY (etsm)); for (i = 0; i < row_count; i++) { gchar *save_id = e_table_model_get_save_id (etm, i); if (g_hash_table_lookup (etsm->hash, save_id)) e_selection_model_change_one_row (E_SELECTION_MODEL (etsm), i, TRUE); if (etsm->cursor_id && !strcmp (etsm->cursor_id, save_id)) { cursor_row = i; cursor_col = e_selection_model_cursor_col (E_SELECTION_MODEL (etsm)); if (cursor_col == -1) { if (etsm->eth) { cursor_col = e_table_header_prioritized_column (etsm->eth); } else cursor_col = 0; } e_selection_model_change_cursor (E_SELECTION_MODEL (etsm), cursor_row, cursor_col); g_free (etsm->cursor_id); etsm->cursor_id = NULL; } g_free (save_id); } free_hash (etsm); e_selection_model_cursor_changed (E_SELECTION_MODEL (etsm), cursor_row, cursor_col); e_selection_model_selection_changed (E_SELECTION_MODEL (etsm)); } etsm->model_changed_idle_id = 0; return FALSE; }
static void etgl_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { ETableGroup *etg = E_TABLE_GROUP (object); ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (object); switch (property_id) { case PROP_FROZEN: etg->frozen = g_value_get_boolean (value); break; case PROP_MINIMUM_WIDTH: case PROP_WIDTH: etgl->minimum_width = g_value_get_double (value); if (etgl->item) { gnome_canvas_item_set ( GNOME_CANVAS_ITEM (etgl->item), "minimum_width", etgl->minimum_width, NULL); } break; case PROP_LENGTH_THRESHOLD: etgl->length_threshold = g_value_get_int (value); if (etgl->item) { gnome_canvas_item_set ( GNOME_CANVAS_ITEM (etgl->item), "length_threshold", etgl->length_threshold, NULL); } break; case PROP_SELECTION_MODEL: if (etgl->selection_model) g_object_unref (etgl->selection_model); etgl->selection_model = E_SELECTION_MODEL (g_value_get_object (value)); if (etgl->selection_model) { g_object_ref (etgl->selection_model); } if (etgl->item) { gnome_canvas_item_set ( GNOME_CANVAS_ITEM (etgl->item), "selection_model", etgl->selection_model, NULL); } break; case PROP_UNIFORM_ROW_HEIGHT: etgl->uniform_row_height = g_value_get_boolean (value); if (etgl->item) { gnome_canvas_item_set ( GNOME_CANVAS_ITEM (etgl->item), "uniform_row_height", etgl->uniform_row_height, NULL); } break; case PROP_TABLE_ALTERNATING_ROW_COLORS: etgl->alternating_row_colors = g_value_get_boolean (value); if (etgl->item) { gnome_canvas_item_set ( GNOME_CANVAS_ITEM (etgl->item), "alternating_row_colors", etgl->alternating_row_colors, NULL); } break; case PROP_TABLE_HORIZONTAL_DRAW_GRID: etgl->horizontal_draw_grid = g_value_get_boolean (value); if (etgl->item) { gnome_canvas_item_set ( GNOME_CANVAS_ITEM (etgl->item), "horizontal_draw_grid", etgl->horizontal_draw_grid, NULL); } break; case PROP_TABLE_VERTICAL_DRAW_GRID: etgl->vertical_draw_grid = g_value_get_boolean (value); if (etgl->item) { gnome_canvas_item_set ( GNOME_CANVAS_ITEM (etgl->item), "vertical_draw_grid", etgl->vertical_draw_grid, NULL); } break; case PROP_TABLE_DRAW_FOCUS: etgl->draw_focus = g_value_get_boolean (value); if (etgl->item) { gnome_canvas_item_set ( GNOME_CANVAS_ITEM (etgl->item), "drawfocus", etgl->draw_focus, NULL); } break; case PROP_CURSOR_MODE: etgl->cursor_mode = g_value_get_int (value); if (etgl->item) { gnome_canvas_item_set ( GNOME_CANVAS_ITEM (etgl->item), "cursor_mode", etgl->cursor_mode, NULL); } break; default: break; } }
/* Handles the events on the ETableClickToAdd, particularly * it creates the ETableItem and passes in some events. */ static gint etcta_event (GnomeCanvasItem *item, GdkEvent *e) { ETableClickToAdd *etcta = E_TABLE_CLICK_TO_ADD (item); switch (e->type) { case GDK_FOCUS_CHANGE: if (!e->focus_change.in) return TRUE; /* coverity[fallthrough] */ case GDK_BUTTON_PRESS: if (etcta->text) { g_object_run_dispose (G_OBJECT (etcta->text)); etcta->text = NULL; } if (etcta->rect) { g_object_run_dispose (G_OBJECT (etcta->rect)); etcta->rect = NULL; } if (!etcta->row) { ETableModel *one; one = e_table_one_new (etcta->model); etcta_add_one (etcta, one); g_object_unref (one); e_selection_model_clear (E_SELECTION_MODEL (etcta->selection)); etcta->row = gnome_canvas_item_new ( GNOME_CANVAS_GROUP (item), e_table_item_get_type (), "ETableHeader", etcta->eth, "ETableModel", etcta->one, "minimum_width", etcta->width, "horizontal_draw_grid", TRUE, "vertical_draw_grid", TRUE, "selection_model", etcta->selection, "cursor_mode", E_CURSOR_SPREADSHEET, NULL); g_signal_connect ( etcta->row, "key_press", G_CALLBACK (item_key_press), etcta); e_signal_connect_notify ( etcta->row, "notify::is-editing", G_CALLBACK (table_click_to_add_row_is_editing_changed_cb), etcta); e_canvas_item_grab_focus (GNOME_CANVAS_ITEM (etcta->row), TRUE); set_initial_selection (etcta); g_object_notify (G_OBJECT (etcta), "is-editing"); } break; case GDK_KEY_PRESS: switch (e->key.keyval) { case GDK_KEY_Tab: case GDK_KEY_KP_Tab: case GDK_KEY_ISO_Left_Tab: finish_editing (etcta); break; default: return FALSE; case GDK_KEY_Escape: if (etcta->row) { e_table_item_leave_edit (E_TABLE_ITEM (etcta->row)); etcta_drop_one (etcta); g_object_run_dispose (G_OBJECT (etcta->row)); etcta->row = NULL; create_rect_and_text (etcta); e_canvas_item_move_absolute (etcta->text, 3, 3); } break; } break; default: return FALSE; } return TRUE; }
static void etgc_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { ETableGroup *etg = E_TABLE_GROUP (object); ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (object); GList *list; switch (prop_id) { case PROP_FROZEN: if (g_value_get_boolean (value)) etg->frozen = TRUE; else { etg->frozen = FALSE; etgc_thaw (etg); } break; case PROP_MINIMUM_WIDTH: case PROP_WIDTH: etgc->minimum_width = g_value_get_double (value); for (list = etgc->children; list; list = g_list_next (list)) { ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *)list->data; g_object_set (child_node->child, "minimum_width", etgc->minimum_width - GROUP_INDENT, NULL); } break; case PROP_LENGTH_THRESHOLD: etgc->length_threshold = g_value_get_int (value); for (list = etgc->children; list; list = g_list_next (list)) { ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *)list->data; g_object_set (child_node->child, "length_threshold", etgc->length_threshold, NULL); } break; case PROP_UNIFORM_ROW_HEIGHT: etgc->uniform_row_height = g_value_get_boolean (value); for (list = etgc->children; list; list = g_list_next (list)) { ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *)list->data; g_object_set (child_node->child, "uniform_row_height", etgc->uniform_row_height, NULL); } break; case PROP_SELECTION_MODEL: if (etgc->selection_model) g_object_unref (etgc->selection_model); etgc->selection_model = E_SELECTION_MODEL(g_value_get_object (value)); if (etgc->selection_model) g_object_ref (etgc->selection_model); for (list = etgc->children; list; list = g_list_next (list)) { ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *)list->data; g_object_set (child_node->child, "selection_model", etgc->selection_model, NULL); } break; case PROP_TABLE_ALTERNATING_ROW_COLORS: etgc->alternating_row_colors = g_value_get_boolean (value); for (list = etgc->children; list; list = g_list_next (list)) { ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *)list->data; g_object_set (child_node->child, "alternating_row_colors", etgc->alternating_row_colors, NULL); } break; case PROP_TABLE_HORIZONTAL_DRAW_GRID: etgc->horizontal_draw_grid = g_value_get_boolean (value); for (list = etgc->children; list; list = g_list_next (list)) { ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *)list->data; g_object_set (child_node->child, "horizontal_draw_grid", etgc->horizontal_draw_grid, NULL); } break; case PROP_TABLE_VERTICAL_DRAW_GRID: etgc->vertical_draw_grid = g_value_get_boolean (value); for (list = etgc->children; list; list = g_list_next (list)) { ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *)list->data; g_object_set (child_node->child, "vertical_draw_grid", etgc->vertical_draw_grid, NULL); } break; case PROP_TABLE_DRAW_FOCUS: etgc->draw_focus = g_value_get_boolean (value); for (list = etgc->children; list; list = g_list_next (list)) { ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *)list->data; g_object_set (child_node->child, "drawfocus", etgc->draw_focus, NULL); } break; case PROP_CURSOR_MODE: etgc->cursor_mode = g_value_get_int (value); for (list = etgc->children; list; list = g_list_next (list)) { ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *)list->data; g_object_set (child_node->child, "cursor_mode", etgc->cursor_mode, NULL); } break; default: break; } }