#include <string.h>
#include "ui/gui/psppire-marshal.h"
+#include "ui/gui/pspp-sheet-selection.h"
+#include "ui/gui/pspp-widget-facade.h"
#define P_(STRING) STRING
#define GTK_PARAM_READABLE G_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB
PROP_RESIZABLE,
PROP_WIDTH,
PROP_SPACING,
- PROP_SIZING,
PROP_FIXED_WIDTH,
PROP_MIN_WIDTH,
PROP_MAX_WIDTH,
PROP_REORDERABLE,
PROP_SORT_INDICATOR,
PROP_SORT_ORDER,
- PROP_SORT_COLUMN_ID
+ PROP_SORT_COLUMN_ID,
+ PROP_QUICK_EDIT,
+ PROP_SELECTED,
+ PROP_SELECTABLE,
+ PROP_ROW_HEAD,
+ PROP_TABBABLE
};
enum
{
CLICKED,
+ QUERY_TOOLTIP,
+ POPUP_MENU,
+ BUTTON_PRESS_EVENT,
LAST_SIGNAL
};
/* Button handling code */
static void pspp_sheet_view_column_create_button (PsppSheetViewColumn *tree_column);
-static void pspp_sheet_view_column_update_button (PsppSheetViewColumn *tree_column);
+void pspp_sheet_view_column_update_button (PsppSheetViewColumn *tree_column);
/* Button signal handlers */
static gint pspp_sheet_view_column_button_event (GtkWidget *widget,
gpointer data);
static void pspp_sheet_view_column_button_clicked (GtkWidget *widget,
gpointer data);
+static void pspp_sheet_view_column_button_popup_menu (GtkWidget *widget,
+ gpointer data);
static gboolean pspp_sheet_view_column_mnemonic_activate (GtkWidget *widget,
gboolean group_cycling,
gpointer data);
+static gboolean on_pspp_sheet_view_column_button_clicked (PsppSheetViewColumn *);
+static gboolean on_pspp_sheet_view_column_button_press_event (PsppSheetViewColumn *,
+ GdkEventButton *);
/* Property handlers */
static void pspp_sheet_view_model_sort_column_changed (GtkTreeSortable *sortable,
object_class = (GObjectClass*) class;
- class->clicked = NULL;
+ class->clicked = on_pspp_sheet_view_column_button_clicked;
+ class->button_press_event = on_pspp_sheet_view_column_button_press_event;
object_class->finalize = pspp_sheet_view_column_finalize;
object_class->set_property = pspp_sheet_view_column_set_property;
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (PsppSheetViewColumnClass, clicked),
+ g_signal_accumulator_true_handled, NULL,
+ psppire_marshal_BOOLEAN__VOID,
+ G_TYPE_BOOLEAN, 0);
+
+ tree_column_signals[POPUP_MENU] =
+ g_signal_new ("popup-menu",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
+ tree_column_signals[QUERY_TOOLTIP] =
+ g_signal_new ("query-tooltip",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ g_signal_accumulator_true_handled, NULL,
+ psppire_marshal_BOOLEAN__OBJECT,
+ G_TYPE_BOOLEAN, 1,
+ GTK_TYPE_TOOLTIP);
+
+ tree_column_signals[BUTTON_PRESS_EVENT] =
+ g_signal_new ("button-press-event",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (PsppSheetViewColumnClass, button_press_event),
+ g_signal_accumulator_true_handled, NULL,
+ psppire_marshal_BOOLEAN__BOXED,
+ G_TYPE_BOOLEAN, 1,
+ GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
+
g_object_class_install_property (object_class,
PROP_VISIBLE,
g_param_spec_boolean ("visible",
G_MAXINT,
0,
GTK_PARAM_READWRITE));
- g_object_class_install_property (object_class,
- PROP_SIZING,
- g_param_spec_enum ("sizing",
- P_("Sizing"),
- P_("Resize mode of the column"),
- PSPP_TYPE_SHEET_VIEW_COLUMN_SIZING,
- PSPP_SHEET_VIEW_COLUMN_GROW_ONLY,
- GTK_PARAM_READWRITE));
g_object_class_install_property (object_class,
PROP_FIXED_WIDTH,
P_("Current fixed width of the column"),
1,
G_MAXINT,
- 1, /* not useful */
+ 100,
GTK_PARAM_READWRITE));
g_object_class_install_property (object_class,
G_MAXINT,
-1,
GTK_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
+ PROP_QUICK_EDIT,
+ g_param_spec_boolean ("quick-edit",
+ P_("Quick edit"),
+ P_("If true, editing starts upon the first click in the column. If false, the first click selects the column and a second click is needed to begin editing. This has no effect on cells that are not editable."),
+ TRUE,
+ GTK_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
+ PROP_SELECTED,
+ g_param_spec_boolean ("selected",
+ P_("Selected"),
+ P_("If true, this column is selected as part of a rectangular selection."),
+ FALSE,
+ GTK_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
+ PROP_SELECTABLE,
+ g_param_spec_boolean ("selectable",
+ P_("Selectable"),
+ P_("If true, this column may be selected as part of a rectangular selection."),
+ TRUE,
+ GTK_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
+ PROP_ROW_HEAD,
+ g_param_spec_boolean ("row-head",
+ P_("Row head"),
+ P_("If true, this column is a \"row head\", equivalent to a column head. If rectangular selection is enabled, then shift+click and control+click in the column select row ranges and toggle row selection, respectively. The column should ordinarily include a button cell; clicking on the button will select the row (and deselect all other rows)."),
+ FALSE,
+ GTK_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
+ PROP_TABBABLE,
+ g_param_spec_boolean ("tabbable",
+ P_("Tabbable"),
+ P_("If true, Tab and Shift+Tab visit this column. If false, Tab and Shift+Tab skip this column."),
+ TRUE,
+ GTK_PARAM_READWRITE));
}
static void
tree_column->min_width = -1;
tree_column->max_width = -1;
tree_column->resized_width = 0;
- tree_column->column_type = PSPP_SHEET_VIEW_COLUMN_GROW_ONLY;
tree_column->visible = TRUE;
tree_column->resizable = FALSE;
tree_column->expand = FALSE;
tree_column->clickable = FALSE;
tree_column->dirty = TRUE;
+ tree_column->selected = FALSE;
+ tree_column->selectable = TRUE;
+ tree_column->row_head = FALSE;
+ tree_column->tabbable = TRUE;
tree_column->sort_order = GTK_SORT_ASCENDING;
tree_column->show_sort_indicator = FALSE;
tree_column->property_changed_signal = 0;
tree_column->fixed_width = 1;
tree_column->use_resized_width = FALSE;
tree_column->title = g_strdup ("");
+ tree_column->quick_edit = TRUE;
+ tree_column->need_button = FALSE;
}
static void
g_value_get_boolean (value));
break;
- case PROP_SIZING:
- pspp_sheet_view_column_set_sizing (tree_column,
- g_value_get_enum (value));
- break;
-
case PROP_FIXED_WIDTH:
pspp_sheet_view_column_set_fixed_width (tree_column,
g_value_get_int (value));
pspp_sheet_view_column_set_sort_column_id (tree_column,
g_value_get_int (value));
break;
-
+
+ case PROP_QUICK_EDIT:
+ pspp_sheet_view_column_set_quick_edit (tree_column,
+ g_value_get_boolean (value));
+ break;
+
+ case PROP_SELECTED:
+ pspp_sheet_view_column_set_selected (tree_column,
+ g_value_get_boolean (value));
+ break;
+
+ case PROP_SELECTABLE:
+ pspp_sheet_view_column_set_selectable (tree_column,
+ g_value_get_boolean (value));
+ break;
+
+ case PROP_ROW_HEAD:
+ pspp_sheet_view_column_set_row_head (tree_column,
+ g_value_get_boolean (value));
+ break;
+
+ case PROP_TABBABLE:
+ pspp_sheet_view_column_set_tabbable (tree_column,
+ g_value_get_boolean (value));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
pspp_sheet_view_column_get_spacing (tree_column));
break;
- case PROP_SIZING:
- g_value_set_enum (value,
- pspp_sheet_view_column_get_sizing (tree_column));
- break;
-
case PROP_FIXED_WIDTH:
g_value_set_int (value,
pspp_sheet_view_column_get_fixed_width (tree_column));
g_value_set_int (value,
pspp_sheet_view_column_get_sort_column_id (tree_column));
break;
-
+
+ case PROP_QUICK_EDIT:
+ g_value_set_boolean (value,
+ pspp_sheet_view_column_get_quick_edit (tree_column));
+ break;
+
+ case PROP_SELECTED:
+ g_value_set_boolean (value,
+ pspp_sheet_view_column_get_selected (tree_column));
+ break;
+
+ case PROP_SELECTABLE:
+ g_value_set_boolean (value,
+ pspp_sheet_view_column_get_selectable (tree_column));
+ break;
+
+ case PROP_ROW_HEAD:
+ g_value_set_boolean (value,
+ pspp_sheet_view_column_get_row_head (tree_column));
+ break;
+
+ case PROP_TABBABLE:
+ g_value_set_boolean (value,
+ pspp_sheet_view_column_get_tabbable (tree_column));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
info->attributes = g_slist_prepend (info->attributes, g_strdup (attribute));
if (tree_column->tree_view)
- _pspp_sheet_view_column_cell_set_dirty (tree_column, TRUE);
+ _pspp_sheet_view_column_cell_set_dirty (tree_column);
}
static void
info->destroy = destroy;
if (column->tree_view)
- _pspp_sheet_view_column_cell_set_dirty (column, TRUE);
+ _pspp_sheet_view_column_cell_set_dirty (column);
}
static void
info->attributes = NULL;
if (tree_column->tree_view)
- _pspp_sheet_view_column_cell_set_dirty (tree_column, TRUE);
+ _pspp_sheet_view_column_cell_set_dirty (tree_column);
+}
+
+static gboolean
+on_query_tooltip (GtkWidget *widget,
+ gint x,
+ gint y,
+ gboolean keyboard_mode,
+ GtkTooltip *tooltip,
+ gpointer user_data)
+{
+ PsppSheetViewColumn *tree_column = user_data;
+ gboolean handled;
+
+ g_signal_emit (tree_column, tree_column_signals[QUERY_TOOLTIP], 0,
+ tooltip, &handled);
+ return handled;
+}
+
+static gboolean
+on_button_pressed (GtkWidget *widget, GdkEventButton *event,
+ gpointer user_data)
+{
+ PsppSheetViewColumn *tree_column = user_data;
+ gboolean handled;
+
+ /* XXX See "Implement GtkWidget::popup_menu" in GTK+ reference manual. */
+ g_signal_emit (tree_column, tree_column_signals[BUTTON_PRESS_EVENT],
+ 0, event, &handled);
+ return handled;
}
/* Helper functions
g_signal_connect (tree_column->button, "clicked",
G_CALLBACK (pspp_sheet_view_column_button_clicked),
tree_column);
+ g_signal_connect (tree_column->button, "popup-menu",
+ G_CALLBACK (pspp_sheet_view_column_button_popup_menu),
+ tree_column);
+ g_signal_connect (tree_column->button, "button-press-event",
+ G_CALLBACK (on_button_pressed), tree_column);
+
+ g_signal_connect (tree_column->button, "query-tooltip",
+ G_CALLBACK (on_query_tooltip), tree_column);
+ g_object_set (tree_column->button, "has-tooltip", TRUE, NULL);
tree_column->alignment = gtk_alignment_new (tree_column->xalign, 0.5, 0.0, 0.0);
pspp_sheet_view_column_update_button (tree_column);
}
-static void
+void
pspp_sheet_view_column_update_button (PsppSheetViewColumn *tree_column)
{
gint sort_column_id = -1;
GtkWidget *current_child;
GtkArrowType arrow_type = GTK_ARROW_NONE;
GtkTreeModel *model;
+ gboolean can_focus;
if (tree_column->tree_view)
model = pspp_sheet_view_get_model (PSPP_SHEET_VIEW (tree_column->tree_view));
model = NULL;
/* Create a button if necessary */
- if (tree_column->visible &&
+ if (tree_column->need_button &&
+ tree_column->visible &&
tree_column->button == NULL &&
tree_column->tree_view &&
gtk_widget_get_realized (tree_column->tree_view))
gdk_window_hide (tree_column->window);
}
}
-
- if (tree_column->reorderable || tree_column->clickable)
- {
- gtk_widget_set_can_focus (tree_column->button, TRUE);
- }
- else
+
+ can_focus = pspp_sheet_view_column_can_focus (tree_column);
+ gtk_widget_set_can_focus (tree_column->button, can_focus);
+ if (!can_focus && gtk_widget_has_focus (tree_column->button))
{
- gtk_widget_set_can_focus (tree_column->button, FALSE);
- if (gtk_widget_has_focus (tree_column->button))
- {
- GtkWidget *toplevel = gtk_widget_get_toplevel (tree_column->tree_view);
- if (gtk_widget_is_toplevel (toplevel))
- {
- gtk_window_set_focus (GTK_WINDOW (toplevel), NULL);
- }
- }
+ GtkWidget *toplevel = gtk_widget_get_toplevel (tree_column->tree_view);
+ if (gtk_widget_is_toplevel (toplevel))
+ {
+ gtk_window_set_focus (GTK_WINDOW (toplevel), NULL);
+ }
}
+
/* Queue a resize on the assumption that we always want to catch all changes
* and columns don't change all that often.
*/
{
switch (event->type)
{
- case GDK_BUTTON_PRESS:
- case GDK_2BUTTON_PRESS:
- case GDK_3BUTTON_PRESS:
case GDK_MOTION_NOTIFY:
case GDK_BUTTON_RELEASE:
case GDK_ENTER_NOTIFY:
return FALSE;
}
+static gboolean
+all_rows_selected (PsppSheetView *sheet_view)
+{
+ PsppSheetSelection *selection = sheet_view->priv->selection;
+ gint n_rows, n_selected_rows;
+
+ n_rows = sheet_view->priv->row_count;
+ n_selected_rows = pspp_sheet_selection_count_selected_rows (selection);
+
+ return n_rows > 0 && n_selected_rows >= n_rows;
+}
+
+static gboolean
+on_pspp_sheet_view_column_button_press_event (PsppSheetViewColumn *column,
+ GdkEventButton *event)
+{
+ PsppSheetView *sheet_view = PSPP_SHEET_VIEW (column->tree_view);
+ PsppSheetSelection *selection;
+ GSignalInvocationHint *hint;
+ guint modifiers;
+
+ /* We only want to run first, not last, but combining that with return type
+ `gboolean' makes GObject warn, so just ignore the run_last call. */
+ hint = g_signal_get_invocation_hint (column);
+ g_return_val_if_fail (hint != NULL, FALSE);
+ if (hint->run_type != G_SIGNAL_RUN_FIRST)
+ return FALSE;
+
+ g_return_val_if_fail (sheet_view != NULL, FALSE);
+
+ selection = sheet_view->priv->selection;
+ g_return_val_if_fail (selection != NULL, FALSE);
+
+ if (pspp_sheet_selection_get_mode (selection) != PSPP_SHEET_SELECTION_RECTANGLE)
+ return FALSE;
+
+ modifiers = event->state & gtk_accelerator_get_default_mod_mask ();
+ if (event->type == GDK_BUTTON_PRESS && event->button == 3)
+ {
+ if (pspp_sheet_selection_count_selected_columns (selection) <= 1
+ || !all_rows_selected (sheet_view))
+ {
+ pspp_sheet_selection_select_all (selection);
+ pspp_sheet_selection_unselect_all_columns (selection);
+ pspp_sheet_selection_select_column (selection, column);
+ sheet_view->priv->anchor_column = column;
+ }
+ return FALSE;
+ }
+ else if (event->type == GDK_BUTTON_PRESS && event->button == 1
+ && modifiers == GDK_CONTROL_MASK)
+ {
+ gboolean is_selected;
+
+ if (!all_rows_selected (sheet_view))
+ {
+ pspp_sheet_selection_select_all (selection);
+ pspp_sheet_selection_unselect_all_columns (selection);
+ }
+ sheet_view->priv->anchor_column = column;
+
+ is_selected = pspp_sheet_view_column_get_selected (column);
+ pspp_sheet_view_column_set_selected (column, !is_selected);
+
+ return TRUE;
+ }
+ else if (event->type == GDK_BUTTON_PRESS && event->button == 1
+ && modifiers == GDK_SHIFT_MASK)
+ {
+ if (!all_rows_selected (sheet_view))
+ {
+ pspp_sheet_selection_select_all (selection);
+ pspp_sheet_selection_unselect_all_columns (selection);
+ sheet_view->priv->anchor_column = column;
+ }
+ else if (sheet_view->priv->anchor_column == NULL)
+ sheet_view->priv->anchor_column = column;
+
+ pspp_sheet_selection_unselect_all_columns (selection);
+ pspp_sheet_selection_select_column_range (selection,
+ sheet_view->priv->anchor_column,
+ column);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+on_pspp_sheet_view_column_button_clicked (PsppSheetViewColumn *column)
+{
+ PsppSheetSelection *selection;
+ PsppSheetView *sheet_view;
+
+ sheet_view = PSPP_SHEET_VIEW (pspp_sheet_view_column_get_tree_view (column));
+ selection = pspp_sheet_view_get_selection (sheet_view);
+ if (pspp_sheet_selection_get_mode (selection) == PSPP_SHEET_SELECTION_RECTANGLE)
+ {
+ pspp_sheet_selection_select_all (selection);
+ if (pspp_sheet_view_column_get_row_head (column))
+ pspp_sheet_selection_select_all_columns (selection);
+ else
+ {
+ pspp_sheet_selection_unselect_all_columns (selection);
+ pspp_sheet_selection_select_column (selection, column);
+ }
+ sheet_view->priv->anchor_column = column;
+ return TRUE;
+ }
+ return FALSE;
+}
static void
pspp_sheet_view_column_button_clicked (GtkWidget *widget, gpointer data)
{
- g_signal_emit_by_name (data, "clicked");
+ PsppSheetViewColumn *column = data;
+ gboolean handled;
+
+ g_signal_emit (column, tree_column_signals[CLICKED], 0, &handled);
+}
+
+static void
+pspp_sheet_view_column_button_popup_menu (GtkWidget *widget, gpointer data)
+{
+ g_signal_emit_by_name (data, "popup-menu");
}
static gboolean
g_return_if_fail (PSPP_IS_SHEET_VIEW (tree_view));
g_return_if_fail (gtk_widget_get_realized (GTK_WIDGET (tree_view)));
g_return_if_fail (tree_view->priv->header_window != NULL);
+ if (!column->need_button || !column->button)
+ return;
+
g_return_if_fail (column->button != NULL);
gtk_widget_set_parent_window (column->button, tree_view->priv->header_window);
_pspp_sheet_view_column_unrealize_button (PsppSheetViewColumn *column)
{
g_return_if_fail (column != NULL);
- g_return_if_fail (column->window != NULL);
-
- gdk_window_set_user_data (column->window, NULL);
- gdk_window_destroy (column->window);
- column->window = NULL;
+ if (column->window != NULL)
+ {
+ gdk_window_set_user_data (column->window, NULL);
+ gdk_window_destroy (column->window);
+ column->window = NULL;
+ }
}
void
g_assert (column->tree_view == NULL);
column->tree_view = GTK_WIDGET (tree_view);
- pspp_sheet_view_column_create_button (column);
+ if (column->need_button)
+ pspp_sheet_view_column_create_button (column);
column->property_changed_signal =
g_signal_connect_swapped (tree_view,
tree_column->spacing = spacing;
if (tree_column->tree_view)
- _pspp_sheet_view_column_cell_set_dirty (tree_column, TRUE);
+ _pspp_sheet_view_column_cell_set_dirty (tree_column);
}
/**
tree_column->visible = visible;
if (tree_column->visible)
- _pspp_sheet_view_column_cell_set_dirty (tree_column, TRUE);
+ _pspp_sheet_view_column_cell_set_dirty (tree_column);
pspp_sheet_view_column_update_button (tree_column);
g_object_notify (G_OBJECT (tree_column), "visible");
* @resizable: %TRUE, if the column can be resized
*
* If @resizable is %TRUE, then the user can explicitly resize the column by
- * grabbing the outer edge of the column button. If resizable is %TRUE and
- * sizing mode of the column is #PSPP_SHEET_VIEW_COLUMN_AUTOSIZE, then the sizing
- * mode is changed to #PSPP_SHEET_VIEW_COLUMN_GROW_ONLY.
+ * grabbing the outer edge of the column button.
**/
void
pspp_sheet_view_column_set_resizable (PsppSheetViewColumn *tree_column,
tree_column->resizable = resizable;
- if (resizable && tree_column->column_type == PSPP_SHEET_VIEW_COLUMN_AUTOSIZE)
- pspp_sheet_view_column_set_sizing (tree_column, PSPP_SHEET_VIEW_COLUMN_GROW_ONLY);
-
pspp_sheet_view_column_update_button (tree_column);
g_object_notify (G_OBJECT (tree_column), "resizable");
}
-/**
- * pspp_sheet_view_column_set_sizing:
- * @tree_column: A #PsppSheetViewColumn.
- * @type: The #PsppSheetViewColumnSizing.
- *
- * Sets the growth behavior of @tree_column to @type.
- **/
-void
-pspp_sheet_view_column_set_sizing (PsppSheetViewColumn *tree_column,
- PsppSheetViewColumnSizing type)
-{
- g_return_if_fail (PSPP_IS_SHEET_VIEW_COLUMN (tree_column));
-
- if (type == tree_column->column_type)
- return;
-
- if (type == PSPP_SHEET_VIEW_COLUMN_AUTOSIZE)
- pspp_sheet_view_column_set_resizable (tree_column, FALSE);
-
-#if 0
- /* I was clearly on crack when I wrote this. I'm not sure what's supposed to
- * be below so I'll leave it until I figure it out.
- */
- if (tree_column->column_type == PSPP_SHEET_VIEW_COLUMN_AUTOSIZE &&
- tree_column->requested_width != -1)
- {
- pspp_sheet_view_column_set_sizing (tree_column, tree_column->requested_width);
- }
-#endif
- tree_column->column_type = type;
-
- pspp_sheet_view_column_update_button (tree_column);
-
- g_object_notify (G_OBJECT (tree_column), "sizing");
-}
-
-/**
- * pspp_sheet_view_column_get_sizing:
- * @tree_column: A #PsppSheetViewColumn.
- *
- * Returns the current type of @tree_column.
- *
- * Return value: The type of @tree_column.
- **/
-PsppSheetViewColumnSizing
-pspp_sheet_view_column_get_sizing (PsppSheetViewColumn *tree_column)
-{
- g_return_val_if_fail (PSPP_IS_SHEET_VIEW_COLUMN (tree_column), 0);
-
- return tree_column->column_type;
-}
-
/**
* pspp_sheet_view_column_get_width:
* @tree_column: A #PsppSheetViewColumn.
* @tree_column: A #PsppSheetViewColumn.
* @fixed_width: The size to set @tree_column to. Must be greater than 0.
*
- * Sets the size of the column in pixels. This is meaningful only if the sizing
- * type is #PSPP_SHEET_VIEW_COLUMN_FIXED. The size of the column is clamped to
+ * Sets the size of the column in pixels. The size of the column is clamped to
* the min/max width for the column. Please note that the min/max width of the
* column doesn't actually affect the "fixed_width" property of the widget, just
* the actual size when displayed.
tree_column->use_resized_width = FALSE;
if (tree_column->tree_view &&
- gtk_widget_get_realized (tree_column->tree_view) &&
- tree_column->column_type == PSPP_SHEET_VIEW_COLUMN_FIXED)
+ gtk_widget_get_realized (tree_column->tree_view))
{
gtk_widget_queue_resize (tree_column->tree_view);
}
}
g_object_notify (G_OBJECT (tree_column), "min-width");
g_object_thaw_notify (G_OBJECT (tree_column));
-
- if (tree_column->column_type == PSPP_SHEET_VIEW_COLUMN_AUTOSIZE)
- _pspp_sheet_view_column_autosize (PSPP_SHEET_VIEW (tree_column->tree_view),
- tree_column);
}
/**
}
g_object_notify (G_OBJECT (tree_column), "max-width");
g_object_thaw_notify (G_OBJECT (tree_column));
-
- if (tree_column->column_type == PSPP_SHEET_VIEW_COLUMN_AUTOSIZE)
- _pspp_sheet_view_column_autosize (PSPP_SHEET_VIEW (tree_column->tree_view),
- tree_column);
}
/**
* Return value: the title of the column. This string should not be
* modified or freed.
**/
-G_CONST_RETURN gchar *
+const gchar *
pspp_sheet_view_column_get_title (PsppSheetViewColumn *tree_column)
{
g_return_val_if_fail (PSPP_IS_SHEET_VIEW_COLUMN (tree_column), NULL);
{
g_return_if_fail (PSPP_IS_SHEET_VIEW_COLUMN (tree_column));
- expand = expand?TRUE:FALSE;
+ expand = !!expand;
if (tree_column->expand == expand)
return;
tree_column->expand = expand;
/* if (reorderable)
pspp_sheet_view_column_set_clickable (tree_column, TRUE);*/
- if (tree_column->reorderable == (reorderable?TRUE:FALSE))
+ reorderable = !!reorderable;
+ if (tree_column->reorderable == reorderable)
return;
- tree_column->reorderable = (reorderable?TRUE:FALSE);
+ tree_column->reorderable = reorderable;
pspp_sheet_view_column_update_button (tree_column);
g_object_notify (G_OBJECT (tree_column), "reorderable");
}
return tree_column->reorderable;
}
+/**
+ * pspp_sheet_view_column_set_quick_edit:
+ * @tree_column: A #PsppSheetViewColumn
+ * @quick_edit: If true, editing starts upon the first click in the column. If
+ * false, the first click selects the column and a second click is needed to
+ * begin editing. This has no effect on cells that are not editable.
+ **/
+void
+pspp_sheet_view_column_set_quick_edit (PsppSheetViewColumn *tree_column,
+ gboolean quick_edit)
+{
+ g_return_if_fail (PSPP_IS_SHEET_VIEW_COLUMN (tree_column));
+
+ quick_edit = !!quick_edit;
+ if (tree_column->quick_edit != quick_edit)
+ {
+ tree_column->quick_edit = quick_edit;
+ g_object_notify (G_OBJECT (tree_column), "quick-edit");
+ }
+}
+
+/**
+ * pspp_sheet_view_column_get_quick_edit:
+ * @tree_column: A #PsppSheetViewColumn
+ *
+ * Returns %TRUE if editing starts upon the first click in the column. Returns
+ * %FALSE, the first click selects the column and a second click is needed to
+ * begin editing. This is not meaningful for cells that are not editable.
+ *
+ * Return value: %TRUE if editing starts upon the first click.
+ **/
+gboolean
+pspp_sheet_view_column_get_quick_edit (PsppSheetViewColumn *tree_column)
+{
+ g_return_val_if_fail (PSPP_IS_SHEET_VIEW_COLUMN (tree_column), FALSE);
+
+ return tree_column->quick_edit;
+}
+
+
+/**
+ * pspp_sheet_view_column_set_selected:
+ * @tree_column: A #PsppSheetViewColumn
+ * @selected: If true, the column is selected as part of a rectangular
+ * selection.
+ **/
+void
+pspp_sheet_view_column_set_selected (PsppSheetViewColumn *tree_column,
+ gboolean selected)
+{
+ g_return_if_fail (PSPP_IS_SHEET_VIEW_COLUMN (tree_column));
+
+ selected = !!selected;
+ if (tree_column->selected != selected)
+ {
+ PsppSheetSelection *selection;
+ PsppSheetView *sheet_view;
+
+ if (tree_column->tree_view != NULL)
+ gtk_widget_queue_draw (GTK_WIDGET (tree_column->tree_view));
+ tree_column->selected = selected;
+ g_object_notify (G_OBJECT (tree_column), "selected");
+
+ sheet_view = PSPP_SHEET_VIEW (pspp_sheet_view_column_get_tree_view (
+ tree_column));
+ selection = pspp_sheet_view_get_selection (sheet_view);
+ _pspp_sheet_selection_emit_changed (selection);
+ }
+}
+
+/**
+ * pspp_sheet_view_column_get_selected:
+ * @tree_column: A #PsppSheetViewColumn
+ *
+ * Returns %TRUE if the column is selected as part of a rectangular
+ * selection.
+ *
+ * Return value: %TRUE if the column is selected as part of a rectangular
+ * selection.
+ **/
+gboolean
+pspp_sheet_view_column_get_selected (PsppSheetViewColumn *tree_column)
+{
+ g_return_val_if_fail (PSPP_IS_SHEET_VIEW_COLUMN (tree_column), FALSE);
+
+ return tree_column->selected;
+}
+
+/**
+ * pspp_sheet_view_column_set_selectable:
+ * @tree_column: A #PsppSheetViewColumn
+ * @selectable: If true, the column may be selected as part of a rectangular
+ * selection.
+ **/
+void
+pspp_sheet_view_column_set_selectable (PsppSheetViewColumn *tree_column,
+ gboolean selectable)
+{
+ g_return_if_fail (PSPP_IS_SHEET_VIEW_COLUMN (tree_column));
+
+ selectable = !!selectable;
+ if (tree_column->selectable != selectable)
+ {
+ if (tree_column->tree_view != NULL)
+ gtk_widget_queue_draw (GTK_WIDGET (tree_column->tree_view));
+ tree_column->selectable = selectable;
+ g_object_notify (G_OBJECT (tree_column), "selectable");
+ }
+}
+
+/**
+ * pspp_sheet_view_column_get_selectable:
+ * @tree_column: A #PsppSheetViewColumn
+ *
+ * Returns %TRUE if the column may be selected as part of a rectangular
+ * selection.
+ *
+ * Return value: %TRUE if the column may be selected as part of a rectangular
+ * selection.
+ **/
+gboolean
+pspp_sheet_view_column_get_selectable (PsppSheetViewColumn *tree_column)
+{
+ g_return_val_if_fail (PSPP_IS_SHEET_VIEW_COLUMN (tree_column), FALSE);
+
+ return tree_column->selectable;
+}
+
+
+/**
+ * pspp_sheet_view_column_set_row_head:
+ * @tree_column: A #PsppSheetViewColumn
+ * @row_head: If true, the column is a "row head", analogous to a column head.
+ * See the description of the row-head property for more information.
+ **/
+void
+pspp_sheet_view_column_set_row_head (PsppSheetViewColumn *tree_column,
+ gboolean row_head)
+{
+ g_return_if_fail (PSPP_IS_SHEET_VIEW_COLUMN (tree_column));
+
+ row_head = !!row_head;
+ if (tree_column->row_head != row_head)
+ {
+ tree_column->row_head = row_head;
+ g_object_notify (G_OBJECT (tree_column), "row_head");
+ }
+}
+
+/**
+ * pspp_sheet_view_column_get_row_head:
+ * @tree_column: A #PsppSheetViewColumn
+ *
+ * Returns %TRUE if the column is a row head.
+ *
+ * Return value: %TRUE if the column is a row head.
+ **/
+gboolean
+pspp_sheet_view_column_get_row_head (PsppSheetViewColumn *tree_column)
+{
+ g_return_val_if_fail (PSPP_IS_SHEET_VIEW_COLUMN (tree_column), FALSE);
+
+ return tree_column->row_head;
+}
+
+
+/**
+ * pspp_sheet_view_column_set_tabbable:
+ * @tree_column: A #PsppSheetViewColumn
+ * @tabbable: If true, the column is "tabbable", meaning that Tab and Shift+Tab
+ * in the sheet visit this column. If false, Tab and Shift+Tab skip this
+ * column.
+ **/
+void
+pspp_sheet_view_column_set_tabbable (PsppSheetViewColumn *tree_column,
+ gboolean tabbable)
+{
+ g_return_if_fail (PSPP_IS_SHEET_VIEW_COLUMN (tree_column));
+
+ tabbable = !!tabbable;
+ if (tree_column->tabbable != tabbable)
+ {
+ tree_column->tabbable = tabbable;
+ g_object_notify (G_OBJECT (tree_column), "tabbable");
+ }
+}
+
+/**
+ * pspp_sheet_view_column_get_tabbable:
+ * @tree_column: A #PsppSheetViewColumn
+ *
+ * Returns %TRUE if the column is tabbable.
+ *
+ * Return value: %TRUE if the column is tabbable.
+ **/
+gboolean
+pspp_sheet_view_column_get_tabbable (PsppSheetViewColumn *tree_column)
+{
+ g_return_val_if_fail (PSPP_IS_SHEET_VIEW_COLUMN (tree_column), FALSE);
+
+ return tree_column->tabbable;
+}
+
/**
* pspp_sheet_view_column_set_sort_column_id:
* @tree_column: A #PsppSheetViewColumn.
* @tree_model: The #GtkTreeModel to to get the cell renderers attributes from.
* @iter: The #GtkTreeIter to to get the cell renderer's attributes from.
- * @is_expander: %TRUE, if the row has children
- * @is_expanded: %TRUE, if the row has visible children
*
* Sets the cell renderer based on the @tree_model and @iter. That is, for
* every attribute mapping in @tree_column, it will get a value from the set
void
pspp_sheet_view_column_cell_set_cell_data (PsppSheetViewColumn *tree_column,
GtkTreeModel *tree_model,
- GtkTreeIter *iter,
- gboolean is_expander,
- gboolean is_expanded)
+ GtkTreeIter *iter)
{
GSList *list;
GValue value = { 0, };
g_object_freeze_notify (cell);
- if (info->cell->is_expander != is_expander)
- g_object_set (cell, "is-expander", is_expander, NULL);
-
- if (info->cell->is_expanded != is_expanded)
- g_object_set (cell, "is-expanded", is_expanded, NULL);
-
while (list && list->next)
{
gtk_tree_model_get_value (tree_model, iter,
}
void
-_pspp_sheet_view_column_cell_set_dirty (PsppSheetViewColumn *tree_column,
- gboolean install_handler)
+_pspp_sheet_view_column_cell_set_dirty (PsppSheetViewColumn *tree_column)
{
GList *list;
if (tree_column->tree_view &&
gtk_widget_get_realized (tree_column->tree_view))
{
- if (install_handler)
- _pspp_sheet_view_install_mark_rows_col_dirty (PSPP_SHEET_VIEW (tree_column->tree_view));
- else
- PSPP_SHEET_VIEW (tree_column->tree_view)->priv->mark_rows_col_dirty = TRUE;
+ _pspp_sheet_view_install_mark_rows_col_dirty (PSPP_SHEET_VIEW (tree_column->tree_view));
gtk_widget_queue_resize (tree_column->tree_view);
}
}
g_return_if_fail (PSPP_IS_SHEET_VIEW_COLUMN (tree_column));
if (tree_column->tree_view)
- _pspp_sheet_view_column_cell_set_dirty (tree_column, TRUE);
+ _pspp_sheet_view_column_cell_set_dirty (tree_column);
}
/**
iface->pack_start (GTK_CELL_LAYOUT (buildable), GTK_CELL_RENDERER (child), FALSE);
}
-GType
-pspp_sheet_view_column_sizing_get_type (void)
+void
+pspp_sheet_view_column_size_request (PsppSheetViewColumn *tree_column,
+ GtkRequisition *request)
{
- static GType etype = 0;
- if (G_UNLIKELY(etype == 0)) {
- static const GEnumValue values[] = {
- { PSPP_SHEET_VIEW_COLUMN_GROW_ONLY, "PSPP_SHEET_VIEW_COLUMN_GROW_ONLY", "grow-only" },
- { PSPP_SHEET_VIEW_COLUMN_AUTOSIZE, "PSPP_SHEET_VIEW_COLUMN_AUTOSIZE", "autosize" },
- { PSPP_SHEET_VIEW_COLUMN_FIXED, "PSPP_SHEET_VIEW_COLUMN_FIXED", "fixed" },
- { 0, NULL, NULL }
- };
- etype = g_enum_register_static (g_intern_static_string ("PsppSheetViewColumnSizing"), values);
+ GtkWidget *base = GTK_WIDGET (tree_column->tree_view);
+ GtkRequisition label_req;
+ GtkRequisition align_req;
+ GtkRequisition arrow_req;
+ GtkRequisition hbox_req;
+ GtkStyle **button_style;
+
+ if (tree_column->button)
+ {
+ gtk_widget_size_request (tree_column->button, request);
+ return;
+ }
+
+ facade_label_get_size_request (0, 0, base, tree_column->title, &label_req);
+ facade_alignment_get_size_request (0, 0, 0, 0, 0, &label_req, &align_req);
+ facade_arrow_get_size_request (0, 0, &arrow_req);
+
+ facade_hbox_get_base_size_request (0, 2, 2, &hbox_req);
+ facade_hbox_add_child_size_request (0, &arrow_req, 0, &hbox_req);
+ facade_hbox_add_child_size_request (0, &align_req, 0, &hbox_req);
+
+ button_style = &PSPP_SHEET_VIEW (tree_column->tree_view)->priv->button_style;
+ if (*button_style == NULL)
+ {
+ *button_style = facade_get_style (base, GTK_TYPE_BUTTON, 0);
+ g_object_ref (*button_style);
+ }
+ facade_button_get_size_request (0, base, *button_style, &hbox_req, request);
+}
+
+void
+pspp_sheet_view_column_size_allocate (PsppSheetViewColumn *tree_column,
+ GtkAllocation *allocation)
+{
+ tree_column->allocation = *allocation;
+ if (tree_column->button)
+ gtk_widget_size_allocate (tree_column->button, allocation);
+}
+
+gboolean
+pspp_sheet_view_column_can_focus (PsppSheetViewColumn *tree_column)
+{
+ return tree_column->reorderable || tree_column->clickable;
+}
+
+void
+pspp_sheet_view_column_set_need_button (PsppSheetViewColumn *tree_column,
+ gboolean need_button)
+{
+ if (tree_column->need_button != need_button)
+ {
+ tree_column->need_button = need_button;
+ pspp_sheet_view_column_update_button (tree_column);
+ _pspp_sheet_view_column_realize_button (tree_column);
}
- return etype;
}