+ if (row != -1 && column != -1)
+ {
+ if (sheet->state != GTK_SHEET_NORMAL)
+ {
+ sheet->state = GTK_SHEET_NORMAL;
+ gtk_sheet_real_unselect_range (sheet, NULL);
+ }
+ else
+ {
+ if (!gtk_sheet_deactivate_cell (sheet))
+ {
+ *veto = FALSE;
+ return;
+ }
+ }
+
+ if (gtk_sheet_autoscroll (sheet))
+ gtk_sheet_move_query (sheet, row, column);
+ sheet->active_cell.row = row;
+ sheet->active_cell.col = column;
+ sheet->selection_cell.row = row;
+ sheet->selection_cell.col = column;
+ sheet->range.row0 = row;
+ sheet->range.col0 = column;
+ sheet->range.rowi = row;
+ sheet->range.coli = column;
+ sheet->state = GTK_SHEET_NORMAL;
+ GTK_SHEET_SET_FLAGS (sheet, GTK_SHEET_IN_SELECTION);
+ gtk_sheet_draw_active_cell (sheet);
+ return;
+ }
+
+ g_assert_not_reached ();
+ gtk_sheet_activate_cell (sheet, sheet->active_cell.row,
+ sheet->active_cell.col);
+}
+
+static gint
+gtk_sheet_button_release (GtkWidget * widget,
+ GdkEventButton * event)
+{
+ GtkSheet *sheet;
+ gint x,y;
+
+ sheet = GTK_SHEET (widget);
+
+ /* release on resize windows */
+ if (GTK_SHEET_IN_XDRAG (sheet))
+ {
+ GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_XDRAG);
+ GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_SELECTION);
+ gtk_widget_get_pointer (widget, &x, NULL);
+ gdk_pointer_ungrab (event->time);
+ draw_xor_vline (sheet);
+
+ gtk_sheet_set_column_width (sheet, sheet->drag_cell.col,
+ new_column_width (sheet, sheet->drag_cell.col, &x));
+ sheet->old_hadjustment = -1.;
+ gtk_signal_emit_by_name (GTK_OBJECT (sheet->hadjustment), "value_changed");
+ return TRUE;
+ }
+
+ if (GTK_SHEET_IN_YDRAG (sheet))
+ {
+ GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_YDRAG);
+ GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_SELECTION);
+ gtk_widget_get_pointer (widget, NULL, &y);
+ gdk_pointer_ungrab (event->time);
+ draw_xor_hline (sheet);
+
+ gtk_sheet_set_row_height (sheet, sheet->drag_cell.row, new_row_height (sheet, sheet->drag_cell.row, &y));
+ sheet->old_vadjustment = -1.;
+ gtk_signal_emit_by_name (GTK_OBJECT (sheet->vadjustment), "value_changed");
+ return TRUE;
+ }
+
+
+ if (GTK_SHEET_IN_DRAG (sheet))
+ {
+ GtkSheetRange old_range;
+ draw_xor_rectangle (sheet, sheet->drag_range);
+ GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_DRAG);
+ gdk_pointer_ungrab (event->time);
+
+ gtk_sheet_real_unselect_range (sheet, NULL);
+
+ sheet->active_cell.row = sheet->active_cell.row +
+ (sheet->drag_range.row0 - sheet->range.row0);
+ sheet->active_cell.col = sheet->active_cell.col +
+ (sheet->drag_range.col0 - sheet->range.col0);
+ sheet->selection_cell.row = sheet->selection_cell.row +
+ (sheet->drag_range.row0 - sheet->range.row0);
+ sheet->selection_cell.col = sheet->selection_cell.col +
+ (sheet->drag_range.col0 - sheet->range.col0);
+ old_range = sheet->range;
+ sheet->range = sheet->drag_range;
+ sheet->drag_range = old_range;
+ gtk_signal_emit (GTK_OBJECT (sheet),sheet_signals[MOVE_RANGE],
+ &sheet->drag_range, &sheet->range);
+ gtk_sheet_select_range (sheet, &sheet->range);
+ }
+
+ if (GTK_SHEET_IN_RESIZE (sheet))
+ {
+ GtkSheetRange old_range;
+ draw_xor_rectangle (sheet, sheet->drag_range);
+ GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_RESIZE);
+ gdk_pointer_ungrab (event->time);
+
+ gtk_sheet_real_unselect_range (sheet, NULL);
+
+ sheet->active_cell.row = sheet->active_cell.row +
+ (sheet->drag_range.row0 - sheet->range.row0);
+ sheet->active_cell.col = sheet->active_cell.col +
+ (sheet->drag_range.col0 - sheet->range.col0);
+ if (sheet->drag_range.row0 < sheet->range.row0)
+ sheet->selection_cell.row = sheet->drag_range.row0;
+ if (sheet->drag_range.rowi >= sheet->range.rowi)
+ sheet->selection_cell.row = sheet->drag_range.rowi;
+ if (sheet->drag_range.col0 < sheet->range.col0)
+ sheet->selection_cell.col = sheet->drag_range.col0;
+ if (sheet->drag_range.coli >= sheet->range.coli)
+ sheet->selection_cell.col = sheet->drag_range.coli;
+ old_range = sheet->range;
+ sheet->range = sheet->drag_range;
+ sheet->drag_range = old_range;
+
+ if (sheet->state == GTK_STATE_NORMAL) sheet->state = GTK_SHEET_RANGE_SELECTED;
+ gtk_signal_emit (GTK_OBJECT (sheet),sheet_signals[RESIZE_RANGE],
+ &sheet->drag_range, &sheet->range);
+ gtk_sheet_select_range (sheet, &sheet->range);
+ }
+
+ if (sheet->state == GTK_SHEET_NORMAL && GTK_SHEET_IN_SELECTION (sheet))
+ {
+ GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_SELECTION);
+ gdk_pointer_ungrab (event->time);
+ gtk_sheet_activate_cell (sheet, sheet->active_cell.row,
+ sheet->active_cell.col);
+ }
+
+ if (GTK_SHEET_IN_SELECTION)
+ gdk_pointer_ungrab (event->time);
+ gtk_grab_remove (GTK_WIDGET (sheet));
+
+ GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_SELECTION);
+
+ return TRUE;
+}
+
+/* Shamelessly lifted from gtktooltips */
+static gboolean
+gtk_sheet_subtitle_paint_window (GtkWidget *tip_window)
+{
+ GtkRequisition req;
+
+ gtk_widget_size_request (tip_window, &req);
+ gtk_paint_flat_box (tip_window->style, tip_window->window,
+ GTK_STATE_NORMAL, GTK_SHADOW_OUT,
+ NULL, GTK_WIDGET(tip_window), "tooltip",
+ 0, 0, req.width, req.height);
+
+ return FALSE;
+}
+
+static GtkSheetHoverTitle *
+create_hover_window (void)
+{
+ GtkSheetHoverTitle *hw = malloc (sizeof (*hw));
+
+ hw->window = gtk_window_new (GTK_WINDOW_POPUP);
+
+#if GTK_CHECK_VERSION (2, 9, 0)
+ gtk_window_set_type_hint (GTK_WINDOW (hw->window),
+ GDK_WINDOW_TYPE_HINT_TOOLTIP);
+#endif
+
+ gtk_widget_set_app_paintable (hw->window, TRUE);
+ gtk_window_set_resizable (GTK_WINDOW (hw->window), FALSE);
+ gtk_widget_set_name (hw->window, "gtk-tooltips");
+ gtk_container_set_border_width (GTK_CONTAINER (hw->window), 4);
+
+ g_signal_connect (hw->window,
+ "expose_event",
+ G_CALLBACK (gtk_sheet_subtitle_paint_window),
+ NULL);
+
+ hw->label = gtk_label_new (NULL);
+
+
+ gtk_label_set_line_wrap (GTK_LABEL (hw->label), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (hw->label), 0.5, 0.5);
+
+ gtk_container_add (GTK_CONTAINER (hw->window), hw->label);
+
+ gtk_widget_show (hw->label);
+
+ g_signal_connect (hw->window,
+ "destroy",
+ G_CALLBACK (gtk_widget_destroyed),
+ &hw->window);
+
+ return hw;
+}
+
+#define HOVER_WINDOW_Y_OFFSET 2
+
+static void
+show_subtitle (GtkSheet *sheet, gint row, gint column, const gchar *subtitle)
+{
+ gint x, y;
+ gint px, py;
+ gint width;
+
+ if ( ! subtitle )
+ return;
+
+ if ( ! sheet->hover_window)
+ {
+ sheet->hover_window = create_hover_window ();
+ gtk_widget_add_events (GTK_WIDGET (sheet), GDK_LEAVE_NOTIFY_MASK);
+
+ g_signal_connect_swapped (sheet, "leave-notify-event",
+ G_CALLBACK (gtk_widget_hide),
+ sheet->hover_window->window);
+ }
+
+ gtk_label_set_text (GTK_LABEL (sheet->hover_window->label),
+ subtitle);
+
+
+ sheet->hover_window->row = row;
+ sheet->hover_window->column = column;
+
+ gdk_window_get_origin (GTK_WIDGET (sheet)->window, &x, &y);
+
+ gtk_widget_get_pointer (GTK_WIDGET (sheet), &px, &py);
+
+ gtk_widget_show (sheet->hover_window->window);
+
+ width = GTK_WIDGET (sheet->hover_window->label)->allocation.width;
+
+ if (row == -1 )
+ {
+ x += px;
+ x -= width / 2;
+ y += sheet->column_title_area.y;
+ y += sheet->column_title_area.height;
+ y += HOVER_WINDOW_Y_OFFSET;
+ }