* You can also set many attributes as: border, foreground and background color,
* text justification, and more.
*
- * The testgtksheet program shows how easy is to create a spreadsheet -like GUI
+ * The testgtksheet program shows how easy is to create a spreadsheet-like GUI
* using this widget.
*/
#include <config.h>
#define CELL_SPACING 1
#define DRAG_WIDTH 6
-#define TIMEOUT_SCROLL 20
#define TIMEOUT_FLASH 200
#define TIME_INTERVAL 8
#define COLUMN_MIN_WIDTH 10
gint row, gint column);
/* Clipped Range */
-static gint gtk_sheet_scroll (gpointer data);
static gint gtk_sheet_flash (gpointer data);
/* Drawing Routines */
static void gtk_sheet_cell_draw_default (GtkSheet *sheet,
gint row, gint column);
-/* draw cell border */
-static void gtk_sheet_cell_draw_border (GtkSheet *sheet,
- gint row, gint column,
- gint mask);
-
/* draw cell contents */
static void gtk_sheet_cell_draw_label (GtkSheet *sheet,
gint row, gint column);
/* Selection */
-static gint gtk_sheet_move_query (GtkSheet *sheet,
+static gboolean gtk_sheet_move_query (GtkSheet *sheet,
gint row, gint column);
static void gtk_sheet_real_select_range (GtkSheet * sheet,
const GtkSheetRange * range);
sheet_range_type =
g_boxed_type_register_static ("GtkSheetRange",
(GBoxedCopyFunc) gtk_sheet_range_copy,
- (GBoxedFreeFunc)gtk_sheet_range_free);
+ (GBoxedFreeFunc) gtk_sheet_range_free);
}
return sheet_range_type;
sheet->children = NULL;
sheet->flags = 0;
- sheet->selection_mode = GTK_SELECTION_BROWSE;
+ sheet->selection_mode = GTK_SELECTION_NONE;
sheet->freeze_count = 0;
sheet->state = GTK_SHEET_NORMAL;
if (sheet->state == GTK_STATE_NORMAL)
if (sheet->sheet_entry && GTK_WIDGET_MAPPED (sheet->sheet_entry))
{
- gtk_sheet_activate_cell (sheet, sheet->active_cell.row, sheet->active_cell.col);
+ gtk_sheet_activate_cell (sheet, sheet->active_cell.row,
+ sheet->active_cell.col);
}
}
if (height < DEFAULT_ROW_HEIGHT (GTK_WIDGET (sheet))) return;
sheet->column_title_area.height = height;
- sheet->view.row0 = ROW_FROM_YPIXEL (sheet, sheet->column_title_area.height + 1);
+ sheet->view.row0 = ROW_FROM_YPIXEL (sheet,
+ sheet->column_title_area.height + 1);
sheet->view.rowi = ROW_FROM_YPIXEL (sheet, sheet->sheet_window_height - 1);
adjust_scrollbars (sheet);
return sheet->row_titles_visible;
}
-
-
void
-gtk_sheet_moveto (GtkSheet * sheet,
+gtk_sheet_moveto (GtkSheet *sheet,
gint row,
gint column,
gfloat row_align,
width = sheet->sheet_window_width;
/* adjust vertical scrollbar */
-
if (row >= 0 && row_align >= 0.)
{
y = ROW_TOP_YPIXEL (sheet, row) - sheet->voffset
- - (gint) ( row_align*height + (1. - row_align) * yyy_row_height (sheet, row));
+ - (gint) ( row_align*height + (1. - row_align)
+ * yyy_row_height (sheet, row));
/* This forces the sheet to scroll when you don't see the entire cell */
min_row = row;
if (!GTK_SHEET_IN_CLIP (sheet)) return;
GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_CLIP);
+
gtk_timeout_remove (sheet->clip_timer);
gtk_sheet_range_draw (sheet, &sheet->clip_range);
clip_area.width = sheet->sheet_window_width;
clip_area.height = sheet->sheet_window_height;
- if (x < 0)
+ if (x < 0)
{
width += x + 1;
x =- 1;
}
if (width > clip_area.width) width = clip_area.width + 10;
- if (y < 0)
+ if (y < 0)
{
height += y + 1;
y =- 1;
GDK_THREADS_LEAVE ();
return TRUE;
-
}
static void
height = ROW_TOP_YPIXEL (sheet,sheet->clip_range.rowi)- y+
yyy_row_height (sheet, sheet->clip_range.rowi)- 1;
- if (x < 0)
+ if (x < 0)
{
width += x + 1;
x =- 1;
}
if (width > clip_area.width) width = clip_area.width + 10;
- if (y < 0)
+ if (y < 0)
{
height += y + 1;
y =- 1;
void
gtk_sheet_get_visible_range (GtkSheet *sheet, GtkSheetRange *range)
{
-
g_return_if_fail (sheet != NULL);
g_return_if_fail (GTK_IS_SHEET (sheet)) ;
g_return_if_fail (range != NULL);
range->col0 = MIN_VISIBLE_COLUMN (sheet);
range->rowi = MAX_VISIBLE_ROW (sheet);
range->coli = MAX_VISIBLE_COLUMN (sheet);
-
}
GtkAdjustment *
sheet->button = NULL;
}
- if (sheet->timer)
- {
- gtk_timeout_remove (sheet->timer);
- sheet->timer = 0;
- }
-
if (sheet->clip_timer)
{
gtk_timeout_remove (sheet->clip_timer);
}
}
-static void
-gtk_sheet_cell_draw_border (GtkSheet *sheet, gint row, gint col, gint mask)
-{
- GtkWidget *widget;
- GdkGC *fg_gc, *bg_gc;
- GtkSheetCellAttr attributes;
- GdkRectangle area;
- guint width;
-
- g_return_if_fail (sheet != NULL);
-
- /* bail now if we arn't drawable yet */
- if (!GTK_WIDGET_DRAWABLE (sheet)) return;
-
- if (row < 0 || row >= yyy_row_count (sheet)) return;
- if (col < 0 || col >= xxx_column_count (sheet)) return;
- if (!xxx_column_is_visible (sheet, col)) return;
- if (!yyy_row_is_visible (sheet, row)) return;
-
- widget = GTK_WIDGET (sheet);
-
- gtk_sheet_get_attributes (sheet, row, col, &attributes);
-
- /* select GC for background rectangle */
- gdk_gc_set_foreground (sheet->fg_gc, &attributes.border.color);
- gdk_gc_set_foreground (sheet->bg_gc, &attributes.background);
-
- fg_gc = sheet->fg_gc;
- bg_gc = sheet->bg_gc;
-
- area.x = COLUMN_LEFT_XPIXEL (sheet,col);
- area.y = ROW_TOP_YPIXEL (sheet,row);
- area.width = xxx_column_width (sheet, col);
- area.height = yyy_row_height (sheet, row);
-
- width = attributes.border.width;
- gdk_gc_set_line_attributes (sheet->fg_gc, attributes.border.width,
- attributes.border.line_style,
- attributes.border.cap_style,
- attributes.border.join_style);
- if (width > 0)
- {
-
- if (attributes.border.mask & GTK_SHEET_LEFT_BORDER & mask)
- gdk_draw_line (sheet->pixmap, sheet->fg_gc,
- area.x, area.y - width / 2,
- area.x, area.y + area.height + width / 2+1);
-
- if (attributes.border.mask & GTK_SHEET_RIGHT_BORDER & mask)
- gdk_draw_line (sheet->pixmap, sheet->fg_gc,
- area.x + area.width, area.y - width / 2,
- area.x + area.width,
- area.y + area.height + width / 2+1);
-
- if (attributes.border.mask & GTK_SHEET_TOP_BORDER & mask)
- gdk_draw_line (sheet->pixmap, sheet->fg_gc,
- area.x - width / 2,area.y,
- area.x + area.width + width / 2+1,
- area.y);
-
- if (attributes.border.mask & GTK_SHEET_BOTTOM_BORDER & mask)
- gdk_draw_line (sheet->pixmap, sheet->fg_gc,
- area.x - width / 2, area.y + area.height,
- area.x + area.width + width / 2+1,
- area.y + area.height);
- }
-
-}
-
-
static void
gtk_sheet_cell_draw_label (GtkSheet *sheet, gint row, gint col)
{
}
-
-
static void
gtk_sheet_range_draw (GtkSheet *sheet, const GtkSheetRange *range)
{
GTK_WIDGET (sheet)->style->white_gc,
TRUE,
0,0,
- sheet->sheet_window_width,sheet->sheet_window_height);
-
+ sheet->sheet_window_width,
+ sheet->sheet_window_height);
}
else
{
for (j = drawing_range.col0; j <= drawing_range.coli; j++)
{
gtk_sheet_cell_draw_default (sheet, i, j);
+ gtk_sheet_cell_draw_label (sheet, i, j);
}
- for (i = drawing_range.row0; i <= drawing_range.rowi; i++)
- for (j = drawing_range.col0; j <= drawing_range.coli; j++)
- {
- gtk_sheet_cell_draw_border (sheet, i - 1, j, GTK_SHEET_BOTTOM_BORDER);
- gtk_sheet_cell_draw_border (sheet, i + 1, j, GTK_SHEET_TOP_BORDER);
- gtk_sheet_cell_draw_border (sheet, i, j - 1, GTK_SHEET_RIGHT_BORDER);
- gtk_sheet_cell_draw_border (sheet, i, j + 1, GTK_SHEET_LEFT_BORDER);
- gtk_sheet_cell_draw_border (sheet, i, j, 15);
- }
-
- for (i = drawing_range.row0; i <= drawing_range.rowi; i++)
- for (j = drawing_range.col0; j <= drawing_range.coli; j++)
- gtk_sheet_cell_draw_label (sheet, i, j);
-
- for (i = drawing_range.row0; i <= drawing_range.rowi; i++)
- for (j= xxx_column_left_column (sheet, drawing_range.col0);
- j < drawing_range.col0; j++)
- gtk_sheet_cell_draw_label (sheet, i, j);
-
- for (i = drawing_range.row0; i <= drawing_range.rowi; i++)
- for (j = drawing_range.coli + 1;
- j <= xxx_column_right_column (sheet, drawing_range.coli);
- j++)
- gtk_sheet_cell_draw_label (sheet, i, j);
-
gtk_sheet_draw_backing_pixmap (sheet, drawing_range);
if (sheet->state != GTK_SHEET_NORMAL &&
sheet->active_cell.col >= drawing_range.col0 &&
sheet->active_cell.col <= drawing_range.coli)
gtk_sheet_show_active_cell (sheet);
-
}
static void
}
gboolean
-gtk_sheet_get_pixel_info (GtkSheet * sheet,
+gtk_sheet_get_pixel_info (GtkSheet *sheet,
gint x,
gint y,
- gint * row,
- gint * column)
+ gint *row,
+ gint *column)
{
- gint trow, tcol;
+ gint trow = -1;
+ gint tcol = -1;
g_return_val_if_fail (sheet != NULL, 0);
g_return_val_if_fail (GTK_IS_SHEET (sheet), 0);
/* bounds checking, return false if the user clicked
- on a blank area */
+ on a blank area */
trow = ROW_FROM_YPIXEL (sheet, y);
if (trow >= yyy_row_count (sheet))
return FALSE;
sheet->selection_cell.col = col;
GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_SELECTION);
+
gtk_sheet_show_active_cell (sheet);
+
g_signal_connect (G_OBJECT (gtk_sheet_get_entry (sheet)),
"changed",
G_CALLBACK (gtk_sheet_entry_changed),
gtk_sheet_size_allocate_entry (sheet);
gtk_widget_map (sheet->sheet_entry);
- gtk_sheet_draw_active_cell (sheet);
gtk_widget_grab_focus (GTK_WIDGET (sheet_entry));
GtkWidget *widget;
GdkRectangle area;
gint i;
- gint x,y,width,height;
+ gint x, y, width, height;
widget = GTK_WIDGET (sheet);
x = COLUMN_LEFT_XPIXEL (sheet,new_range.col0);
y = ROW_TOP_YPIXEL (sheet,new_range.row0);
- width = COLUMN_LEFT_XPIXEL (sheet,new_range.coli)- x+
+ width = COLUMN_LEFT_XPIXEL (sheet, new_range.coli) - x +
xxx_column_width (sheet, new_range.coli);
- height = ROW_TOP_YPIXEL (sheet,new_range.rowi)- y+
+ height = ROW_TOP_YPIXEL (sheet, new_range.rowi) - y +
yyy_row_height (sheet, new_range.rowi);
area.x = COLUMN_LEFT_XPIXEL (sheet, MIN_VISIBLE_COLUMN (sheet));
area.width = sheet->sheet_window_width;
area.height = sheet->sheet_window_height;
- if (x < 0)
+ if (x < 0)
{
width = width + x;
x = 0;
}
if (width > area.width) width = area.width + 10;
- if (y < 0)
+ if (y < 0)
{
height = height + y;
y = 0;
gdk_draw_rectangle (sheet->sheet_window,
sheet->xor_gc,
FALSE,
- x + i,y + i,
- width - 2 * i,height - 2 * i);
+ x + i,
+ y + i,
+ width - 2 * i,
+ height - 2 * i);
gdk_gc_set_clip_rectangle (sheet->xor_gc, NULL);
- gtk_sheet_draw_corners (sheet, new_range);
+ gtk_sheet_draw_corners (sheet, new_range);
}
static void
g_return_val_if_fail (GTK_IS_SHEET (widget), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
+
sheet = GTK_SHEET (widget);
if (GTK_WIDGET_DRAWABLE (widget))
}
-static gint
+static gboolean
gtk_sheet_button_press (GtkWidget * widget,
GdkEventButton * event)
{
GDK_BUTTON_RELEASE_MASK,
NULL, NULL, event->time);
gtk_grab_add (GTK_WIDGET (sheet));
- sheet->timer = gtk_timeout_add (TIMEOUT_SCROLL, gtk_sheet_scroll, sheet);
+
+ /* This seems to be a kludge to work around a problem where the sheet
+ scrolls to another position. The timeout scrolls it back to its
+ original posn. JMD 3 July 2007
+ */
gtk_widget_grab_focus (GTK_WIDGET (sheet));
if (sheet->selection_mode != GTK_SELECTION_SINGLE &&
+ sheet->selection_mode != GTK_SELECTION_NONE &&
sheet->cursor_drag->type == GDK_SIZING &&
!GTK_SHEET_IN_SELECTION (sheet) && !GTK_SHEET_IN_RESIZE (sheet))
{
- if (sheet->state == GTK_STATE_NORMAL)
+ if (sheet->state == GTK_STATE_NORMAL)
{
row = sheet->active_cell.row;
column = sheet->active_cell.col;
&& sheet->active_cell.col >= 0
)
{
- if (sheet->state == GTK_STATE_NORMAL)
+ if (sheet->state == GTK_STATE_NORMAL)
{
row = sheet->active_cell.row;
column = sheet->active_cell.col;
{
gtk_widget_get_pointer (widget, &x, &y);
column = COLUMN_FROM_XPIXEL (sheet, x);
+
if (xxx_column_is_sensitive (sheet, column))
{
gtk_sheet_click_cell (sheet, - 1, column, &veto);
gtk_grab_add (GTK_WIDGET (sheet));
- sheet->timer = gtk_timeout_add (TIMEOUT_SCROLL, gtk_sheet_scroll, sheet);
gtk_widget_grab_focus (GTK_WIDGET (sheet));
GTK_SHEET_SET_FLAGS (sheet, GTK_SHEET_IN_SELECTION);
}
{
gtk_sheet_click_cell (sheet, row, - 1, &veto);
gtk_grab_add (GTK_WIDGET (sheet));
- sheet->timer = gtk_timeout_add (TIMEOUT_SCROLL, gtk_sheet_scroll, sheet);
gtk_widget_grab_focus (GTK_WIDGET (sheet));
GTK_SHEET_SET_FLAGS (sheet, GTK_SHEET_IN_SELECTION);
}
return TRUE;
}
+#if 0
static gint
gtk_sheet_scroll (gpointer data)
{
GDK_THREADS_LEAVE ();
return TRUE;
-
}
+#endif
static void
gtk_sheet_click_cell (GtkSheet *sheet, gint row, gint column, gboolean *veto)
if (GTK_SHEET_IN_SELECTION)
gdk_pointer_ungrab (event->time);
- if (sheet->timer)
- gtk_timeout_remove (sheet->timer);
gtk_grab_remove (GTK_WIDGET (sheet));
GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_SELECTION);
new_cursor = GDK_SIZING;
if ( event->window == sheet->sheet_window &&
+ sheet->selection_mode != GTK_SELECTION_NONE &&
!GTK_SHEET_IN_DRAG (sheet) &&
(POSSIBLE_RESIZE (sheet, x, y, &row, &column) ||
GTK_SHEET_IN_RESIZE (sheet)) &&
gdk_window_set_cursor (sheet->sheet_window,sheet->cursor_drag);
}
+
gdk_window_get_pointer (widget->window, &x, &y, &mods);
if (! (mods & GDK_BUTTON1_MASK)) return FALSE;
return TRUE;
}
-static gint
+static gboolean
gtk_sheet_move_query (GtkSheet *sheet, gint row, gint column)
{
gint row_move, column_move;
height = sheet->sheet_window_height;
width = sheet->sheet_window_width;
- if (row >= MAX_VISIBLE_ROW (sheet) && sheet->state!=GTK_SHEET_COLUMN_SELECTED)
+ if (row >= MAX_VISIBLE_ROW (sheet) && sheet->state!=GTK_SHEET_COLUMN_SELECTED)
{
row_align = 1.;
new_row = MIN (yyy_row_count (sheet), row + 1);
row_align = -1.;
}
}
- if (row < MIN_VISIBLE_ROW (sheet) && sheet->state!=GTK_SHEET_COLUMN_SELECTED)
+ if (row < MIN_VISIBLE_ROW (sheet) && sheet->state!=GTK_SHEET_COLUMN_SELECTED)
{
row_align= 0.;
row_move = TRUE;
}
- if (column >= MAX_VISIBLE_COLUMN (sheet) && sheet->state!=GTK_SHEET_ROW_SELECTED)
+ if (column >= MAX_VISIBLE_COLUMN (sheet) && sheet->state!=GTK_SHEET_ROW_SELECTED)
{
col_align = 1.;
new_col = MIN (xxx_column_count (sheet) - 1, column + 1);
col_align = -1.;
}
}
- if (column < MIN_VISIBLE_COLUMN (sheet) && sheet->state!=GTK_SHEET_ROW_SELECTED)
+ if (column < MIN_VISIBLE_COLUMN (sheet) && sheet->state!=GTK_SHEET_ROW_SELECTED)
{
col_align = 0.;
column_move = TRUE;
row = MIN_VISIBLE_ROW (sheet);
while (! xxx_column_is_visible (sheet, col) && col < xxx_column_count (sheet) - 1) col++;
if (strlen (gtk_entry_get_text (GTK_ENTRY (gtk_sheet_get_entry (sheet)))) == 0
- || force_move)
+ || force_move)
{
gtk_sheet_click_cell (sheet, row, col, &veto);
}
extend_selection = FALSE;
break;
default:
- if (in_selection)
+ if (in_selection)
{
GTK_SHEET_SET_FLAGS (sheet, GTK_SHEET_IN_SELECTION);
if (extend_selection) return TRUE;
while (children)
{
- if (GTK_IS_TABLE (parent))
+ if (GTK_IS_TABLE (parent))
{
table_child = children->data;
entry = table_child->widget;
if (!sheet->row_titles_visible) clip_area.x = 0;
if (!sheet->column_titles_visible) clip_area.y = 0;
- if (area.x < 0)
+ if (area.x < 0)
{
area.width = area.width + area.x;
area.x = 0;
}
if (area.width > clip_area.width) area.width = clip_area.width + 10;
- if (area.y < 0)
+ if (area.y < 0)
{
area.height = area.height + area.y;
area.y = 0;