gnumeric r16970 - in trunk: . src src/widgets
- From: mortenw svn gnome org
- To: svn-commits-list gnome org
- Subject: gnumeric r16970 - in trunk: . src src/widgets
- Date: Sun, 23 Nov 2008 15:21:01 +0000 (UTC)
Author: mortenw
Date: Sun Nov 23 15:21:00 2008
New Revision: 16970
URL: http://svn.gnome.org/viewvc/gnumeric?rev=16970&view=rev
Log:
2008-11-23 Morten Welinder <terra gnome org>
* src/wbc-gtk.c (wbcg_sheet_add): Add a SHEET_CONTROL_KEY for the
labels too.
(get_scg): New function to retrieve and scg for a tab label or
sheet table widget. Simplify drag handling code using this.
(wbcg_sheet_remove_all): Make sure disconnection happens for sheet
signals, even when we shut down the wbcg.
(wbcg_set_direction): Split from cb_direction_change. Change
direct callers of cb_direction_change to use wbcg_set_direction.
(wbcg_sheet_add): Don't init scg->label here.
(wbcg_set_end_mode): Translate "END".
(wbcg_get_n_scg): New function.
* src/sheet-control-gui.c (sheet_control_gui_new): Keep a ref for
->table and ->label. Init ->label here.
(scg_finalize): Unref here.
* src/wbc-gtk-impl.h (struct _WBCGtk): Add a paned for sheet tabs
and the progress bar. Split notebook into ->snotebook (for the
sheet tables) and ->bnotebook for the tabs. Make the latter a
GnmNotebook. All users changed accordingly.
Added:
trunk/src/widgets/gnm-notebook.c
trunk/src/widgets/gnm-notebook.h
Modified:
trunk/ChangeLog
trunk/NEWS
trunk/src/gnm-pane.c
trunk/src/gui-file.c
trunk/src/sheet-control-gui.c
trunk/src/wbc-gtk-edit.c
trunk/src/wbc-gtk-impl.h
trunk/src/wbc-gtk.c
trunk/src/wbc-gtk.h
trunk/src/widgets/ChangeLog
trunk/src/widgets/Makefile.am
Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS (original)
+++ trunk/NEWS Sun Nov 23 15:21:00 2008
@@ -34,6 +34,8 @@
* Fix GROWTH/TREND crash. [#559363]
* Make non-gnome the default. [#558840]
* Disallow deleting last visible sheet. [#557153]
+ * Merge the sheet tabs into the status bar. [#561733]
+ * Fix potential crashes in multi-view mode.
--------------------------------------------------------------------------
Gnumeric 1.9.3
Modified: trunk/src/gnm-pane.c
==============================================================================
--- trunk/src/gnm-pane.c (original)
+++ trunk/src/gnm-pane.c Sun Nov 23 15:21:00 2008
@@ -279,7 +279,7 @@
case GDK_KP_Page_Up:
case GDK_Page_Up:
if ((event->state & GDK_CONTROL_MASK) != 0)
- gtk_notebook_prev_page (wbcg->notebook);
+ gnm_notebook_prev_page (wbcg->bnotebook);
else if ((event->state & GDK_MOD1_MASK) == 0) {
delayed_movement = TRUE;
scg_queue_movement (scg, movefn,
@@ -296,7 +296,7 @@
case GDK_KP_Page_Down:
case GDK_Page_Down:
if ((event->state & GDK_CONTROL_MASK) != 0)
- gtk_notebook_next_page (wbcg->notebook);
+ gnm_notebook_next_page (wbcg->bnotebook);
else if ((event->state & GDK_MOD1_MASK) == 0) {
delayed_movement = TRUE;
scg_queue_movement (scg, movefn,
Modified: trunk/src/gui-file.c
==============================================================================
--- trunk/src/gui-file.c (original)
+++ trunk/src/gui-file.c Sun Nov 23 15:21:00 2008
@@ -528,7 +528,7 @@
}
if (wbcg2) {
- GtkWidget *nb = GTK_WIDGET (wbcg2->notebook);
+ GtkWidget *nb = GTK_WIDGET (wbcg2->notebook_area);
wb_view_preferred_size (wb_view,
nb->allocation.width,
nb->allocation.height);
@@ -565,7 +565,7 @@
wbcg_find_for_workbook (wb, wbcg, NULL, NULL);
if (wbcg2) {
- GtkWidget *nb = GTK_WIDGET (wbcg2->notebook);
+ GtkWidget *nb = GTK_WIDGET (wbcg2->notebook_area);
wb_view_preferred_size (wb_view,
nb->allocation.width,
nb->allocation.height);
Modified: trunk/src/sheet-control-gui.c
==============================================================================
--- trunk/src/sheet-control-gui.c (original)
+++ trunk/src/sheet-control-gui.c Sun Nov 23 15:21:00 2008
@@ -53,11 +53,13 @@
#include "ranges.h"
#include "xml-sax.h"
#include "xml-io.h"
+#include "style-color.h"
#include "gnm-pane-impl.h"
#include "item-bar.h"
#include "item-cursor.h"
#include "widgets/gnumeric-expr-entry.h"
+#include "widgets/widget-editable-label.h"
#include <goffice/utils/go-file.h>
#include <goffice/utils/go-glib-extras.h>
@@ -654,7 +656,10 @@
SheetControl *sc = (SheetControl *) scg;
int i;
- scg->table = NULL;
+ if (scg->table) {
+ g_object_unref (scg->table);
+ scg->table = NULL;
+ }
scg_mode_edit (scg); /* finish any object edits */
scg_unant (sc); /* Make sure that everything is unanted */
@@ -1458,6 +1463,7 @@
G_CALLBACK (cb_hscrollbar_adjust_bounds), sheet);
scg->table = GTK_TABLE (gtk_table_new (4, 4, FALSE));
+ g_object_ref (scg->table);
gtk_table_attach (scg->table, GTK_WIDGET (scg->inner_table),
0, 1, 0, 1,
GTK_EXPAND | GTK_FILL | GTK_SHRINK,
@@ -1511,6 +1517,12 @@
"signal::notify::display-outlines-right", cb_scg_redraw_resize, scg,
NULL);
+ scg->label = editable_label_new
+ (sheet->name_unquoted,
+ sheet->tab_color ? &sheet->tab_color->gdk_color : NULL,
+ sheet->tab_text_color ? &sheet->tab_text_color->gdk_color : NULL);
+ g_object_ref (scg->label);
+
return scg;
}
@@ -1560,7 +1572,13 @@
if (scg->table) {
gtk_object_destroy (GTK_OBJECT (scg->table));
- scg->table =NULL;
+ g_object_unref (scg->table);
+ scg->table = NULL;
+ }
+
+ if (scg->label) {
+ g_object_unref (scg->label);
+ scg->label = NULL;
}
if (scg->wbcg != NULL)
@@ -3589,4 +3607,3 @@
cmd_reorganize_sheets (wbc, old_state, sheet);
}
}
-
Modified: trunk/src/wbc-gtk-edit.c
==============================================================================
--- trunk/src/wbc-gtk-edit.c (original)
+++ trunk/src/wbc-gtk-edit.c Sun Nov 23 15:21:00 2008
@@ -998,7 +998,7 @@
wbcg_insert_object_clear (wbcg);
wbcg->new_object = so;
- npages = gtk_notebook_get_n_pages (wbcg->notebook);
+ npages = wbcg_get_n_scg (wbcg);
for (i = 0; i < npages; i++)
if (NULL != (scg = wbcg_get_nth_scg (wbcg, i))) {
scg_object_unselect (scg, NULL);
@@ -1030,7 +1030,7 @@
g_object_unref (G_OBJECT (wbcg->new_object));
wbcg->new_object = NULL;
- npages = gtk_notebook_get_n_pages (wbcg->notebook);
+ npages = wbcg_get_n_scg (wbcg);
for (i = 0; i < npages; i++)
if (NULL != (scg = wbcg_get_nth_scg (wbcg, i)))
scg_cursor_visible (scg, TRUE);
Modified: trunk/src/wbc-gtk-impl.h
==============================================================================
--- trunk/src/wbc-gtk-impl.h (original)
+++ trunk/src/wbc-gtk-impl.h Sun Nov 23 15:21:00 2008
@@ -7,10 +7,10 @@
#include "workbook-control-priv.h"
#include "style.h"
#include "widgets/gnumeric-expr-entry.h"
+#include "widgets/gnm-notebook.h"
#include <goffice/app/file.h>
-#include <gtk/gtknotebook.h>
-#include <gtk/gtkuimanager.h>
+#include <gtk/gtk.h>
#include <goffice/gtk/go-action-combo-stack.h>
#include <goffice/gtk/go-action-combo-color.h>
#include <goffice/gtk/go-action-combo-text.h>
@@ -28,7 +28,19 @@
#ifdef GNM_USE_HILDON
HildonProgram *hildon_prog;
#endif
- GtkNotebook *notebook;
+
+ /* The area that contains the sheet and the sheet tabs. */
+ GtkWidget *notebook_area;
+
+ /* The notebook that contains the sheets. */
+ GtkNotebook *snotebook;
+
+ /* The notebook that contains the sheet tabs. */
+ GnmNotebook *bnotebook;
+
+ /* The GtkPaned that contains the sheet tabs and the status area. */
+ GtkPaned *tabs_paned;
+
GtkWidget *progress_bar;
struct {
@@ -84,6 +96,7 @@
GOFileSaver *current_saver;
+ SheetControlGUI *active_scg;
gulong sig_view_changed;
gulong sig_auto_expr_text;
gulong sig_sheet_order, sig_notify_uri, sig_notify_dirty;
Modified: trunk/src/wbc-gtk.c
==============================================================================
--- trunk/src/wbc-gtk.c (original)
+++ trunk/src/wbc-gtk.c Sun Nov 23 15:21:00 2008
@@ -77,7 +77,9 @@
#include <hildon-widgets/hildon-program.h>
#endif
-#define SHEET_CONTROL_KEY "SheetControl"
+#define SHEET_CONTROL_KEY "SheetControl"
+#define PANED_SIGNAL_KEY "SIGNAL_PANED_REPARTITION"
+
enum {
WBG_GTK_PROP_0,
@@ -106,23 +108,6 @@
/****************************************************************************/
-static int
-gnm_notebook_get_n_visible (GtkNotebook *nb)
-{
- int count = 0;
- GList *l, *children = gtk_container_get_children (GTK_CONTAINER (nb));
-
- for (l = children; l; l = l->next) {
- GtkWidget *child = l->data;
- if (GTK_WIDGET_VISIBLE (child))
- count++;
- }
-
- g_list_free (children);
-
- return count;
-}
-
static void
wbc_gtk_set_action_sensitivity (WBCGtk const *wbcg,
char const *action, gboolean sensitive)
@@ -187,7 +172,7 @@
SheetControlGUI *scg;
int i, npages;
- if (sheet == NULL || wbcg->notebook == NULL)
+ if (sheet == NULL || wbcg->snotebook == NULL)
return NULL;
g_return_val_if_fail (IS_SHEET (sheet), NULL);
@@ -201,7 +186,7 @@
* index_in_wb is probably not accurate because we are in the
* middle of removing or adding a sheet.
*/
- npages = gtk_notebook_get_n_pages (wbcg->notebook);
+ npages = wbcg_get_n_scg (wbcg);
for (i = 0; i < npages; i++) {
scg = wbcg_get_nth_scg (wbcg, i);
if (NULL != scg && scg_sheet (scg) == sheet)
@@ -337,12 +322,13 @@
gtk_widget_set_sensitive (wbcg->cancel_button, enable_edit_ok_cancel);
gtk_widget_set_sensitive (wbcg->func_button, enable_actions);
- if (wbcg->notebook) {
- int i;
- for (i = 0; i < gtk_notebook_get_n_pages (wbcg->notebook); i++) {
- GtkWidget *page = gtk_notebook_get_nth_page (wbcg->notebook, i);
- GtkWidget *label = gtk_notebook_get_tab_label (wbcg->notebook, page);
- editable_label_set_editable (EDITABLE_LABEL (label), enable_actions);
+ if (wbcg->snotebook) {
+ int i, N = wbcg_get_n_scg (wbcg);
+ for (i = 0; i < N; i++) {
+ GtkWidget *label =
+ gnm_notebook_get_nth_label (wbcg->bnotebook, i);
+ editable_label_set_editable (EDITABLE_LABEL (label),
+ enable_actions);
}
}
@@ -371,6 +357,21 @@
return reject;
}
+static void
+signal_paned_repartition (GtkPaned *paned)
+{
+ g_object_set_data (G_OBJECT (paned),
+ PANED_SIGNAL_KEY, GINT_TO_POINTER(1));
+ gtk_widget_queue_resize (GTK_WIDGET (paned));
+}
+
+static void
+cb_sheet_label_edit_happened (EditableLabel *el, G_GNUC_UNUSED GParamSpec *pspec,
+ WBCGtk *wbcg)
+{
+ signal_paned_repartition (wbcg->tabs_paned);
+}
+
void
wbcg_insert_sheet (GtkWidget *unused, WBCGtk *wbcg)
{
@@ -433,7 +434,7 @@
unsigned int i;
GtkWidget *item, *menu = gtk_menu_new ();
- gboolean has_multiple = gnm_notebook_get_n_visible (scg->wbcg->notebook) > 1;
+ gboolean has_multiple = gnm_notebook_get_n_visible (scg->wbcg->bnotebook) > 1;
for (i = 0; i < G_N_ELEMENTS (sheet_label_context_actions); i++){
char const *text = sheet_label_context_actions[i].text;
@@ -467,18 +468,17 @@
cb_sheet_label_button_press (GtkWidget *widget, GdkEventButton *event,
SheetControlGUI *scg)
{
- GtkNotebook *notebook;
+ WBCGtk *wbcg = scg->wbcg;
gint page_number;
- GtkWidget *table = GTK_WIDGET (scg->table);
+
if (event->type != GDK_BUTTON_PRESS)
return FALSE;
- notebook = GTK_NOTEBOOK (table->parent);
- page_number = gtk_notebook_page_num (notebook, table);
+ page_number = gtk_notebook_page_num (wbcg->snotebook,
+ GTK_WIDGET (scg->table));
+ gnm_notebook_set_current_page (wbcg->bnotebook, page_number);
- gtk_notebook_set_current_page (notebook, page_number);
-
- if (event->button == 1 || NULL != scg->wbcg->rangesel)
+ if (event->button == 1 || NULL != wbcg->rangesel)
return TRUE;
if (event->button == 3 &&
@@ -491,41 +491,37 @@
return FALSE;
}
-static gint
-gnm_notebook_page_num_by_label (GtkNotebook *notebook, GtkWidget *label)
+static SheetControlGUI *
+get_scg (const GtkWidget *w)
{
- guint i;
- GtkWidget *page, *l;
+ return g_object_get_data (G_OBJECT (w), SHEET_CONTROL_KEY);
+}
- g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), -1);
- g_return_val_if_fail (GTK_IS_WIDGET (label), -1);
+static GList *
+get_all_scgs (WBCGtk *wbcg)
+{
+ int i, n = gtk_notebook_get_n_pages (wbcg->snotebook);
+ GList *l = NULL;
- for (i = g_list_length (notebook->children); i-- > 0 ; ) {
- page = gtk_notebook_get_nth_page (notebook, i);
- l = gtk_notebook_get_tab_label (notebook, page);
- if (label == l)
- return i;
- }
+ for (i = 0; i < n; i++) {
+ GtkWidget *w = gtk_notebook_get_nth_page (wbcg->snotebook, i);
+ SheetControlGUI *scg = get_scg (w);
+ l = g_list_prepend (l, scg);
+ }
- return -1;
+ return g_list_reverse (l);
}
static void
cb_sheet_label_drag_data_get (GtkWidget *widget, GdkDragContext *context,
GtkSelectionData *selection_data,
- guint info, guint time,
- WBCGtk *wbcg)
+ guint info, guint time)
{
- SheetControlGUI *scg;
- gint n_source;
-
- g_return_if_fail (IS_WBC_GTK (wbcg));
-
- n_source = gnm_notebook_page_num_by_label (wbcg->notebook, widget);
- scg = wbcg_get_nth_scg (wbcg, n_source);
+ SheetControlGUI *scg = get_scg (widget);
+ g_return_if_fail (IS_SHEET_CONTROL_GUI (scg));
gtk_selection_data_set (selection_data, selection_data->target,
- 8, (void *) scg, sizeof (scg));
+ 8, (void *) scg, sizeof (scg));
}
static void
@@ -534,7 +530,8 @@
WBCGtk *wbcg)
{
GtkWidget *w_source;
- gint p_src;
+ SheetControlGUI *scg_src, *scg_dst;
+ Sheet *s_src, *s_dst;
g_return_if_fail (IS_WBC_GTK (wbcg));
g_return_if_fail (GTK_IS_WIDGET (widget));
@@ -545,26 +542,26 @@
return;
}
- p_src = gnm_notebook_page_num_by_label (wbcg->notebook, w_source);
-
- /*
- * Is this a sheet of our workbook? If yes, we just reorder
- * the sheets.
- */
- if (p_src >= 0) {
- Workbook *wb = wb_control_get_workbook (WORKBOOK_CONTROL (wbcg));
- Sheet *s_src = workbook_sheet_by_index (wb, p_src);
- int p_dst = gnm_notebook_page_num_by_label (wbcg->notebook,
- widget);
- Sheet *s_dst = workbook_sheet_by_index (wb, p_dst);
-
- if (s_src && s_dst && s_src != s_dst) {
- WorkbookSheetState *old_state = workbook_sheet_state_new (wb);
- workbook_sheet_move (s_src, p_dst - p_src);
- cmd_reorganize_sheets (WORKBOOK_CONTROL (wbcg),
- old_state,
- s_src);
- }
+ scg_src = get_scg (w_source);
+ g_return_if_fail (scg_src != NULL);
+ s_src = scg_sheet (scg_src);
+
+ scg_dst = get_scg (widget);
+ g_return_if_fail (scg_dst != NULL);
+ s_dst = scg_sheet (scg_dst);
+
+ if (s_src == s_dst) {
+ /* Nothing */
+ } else if (s_src->workbook == s_dst->workbook) {
+ /* Move within workbook */
+ Workbook *wb = s_src->workbook;
+ int p_src = s_src->index_in_wb;
+ int p_dst = s_dst->index_in_wb;
+ WorkbookSheetState *old_state = workbook_sheet_state_new (wb);
+ workbook_sheet_move (s_src, p_dst - p_src);
+ cmd_reorganize_sheets (WORKBOOK_CONTROL (wbcg),
+ old_state,
+ s_src);
} else {
g_return_if_fail (IS_SHEET_CONTROL_GUI (data->data));
@@ -638,25 +635,26 @@
static gboolean
cb_sheet_label_drag_motion (GtkWidget *widget, GdkDragContext *context,
- gint x, gint y, guint time, WBCGtk *wbcg)
+ gint x, gint y, guint time, WBCGtk *wbcg)
{
+ SheetControlGUI *scg_src, *scg_dst;
GtkWidget *w_source, *arrow, *window;
- gint n_source, n_dest, root_x, root_y, pos_x, pos_y;
+ gint root_x, root_y, pos_x, pos_y;
g_return_val_if_fail (IS_WBC_GTK (wbcg), FALSE);
g_return_val_if_fail (IS_WBC_GTK (wbcg), FALSE);
/* Make sure we are really hovering over another label. */
w_source = gtk_drag_get_source_widget (context);
- n_source = -1;
- if (w_source)
- n_source = gnm_notebook_page_num_by_label (wbcg->notebook,
- w_source);
- else
+ if (!w_source)
return FALSE;
- n_dest = gnm_notebook_page_num_by_label (wbcg->notebook, widget);
+
arrow = g_object_get_data (G_OBJECT (w_source), "arrow");
- if (n_source == n_dest) {
+
+ scg_src = get_scg (w_source);
+ scg_dst = get_scg (widget);
+
+ if (scg_src == scg_dst) {
gtk_widget_hide (arrow);
return (FALSE);
}
@@ -666,7 +664,7 @@
gtk_window_get_position (GTK_WINDOW (window), &root_x, &root_y);
pos_x = root_x + widget->allocation.x;
pos_y = root_y + widget->allocation.y;
- if (n_source < n_dest)
+ if (w_source->allocation.x < widget->allocation.x)
pos_x += widget->allocation.width;
gtk_window_move (GTK_WINDOW (arrow), pos_x, pos_y);
gtk_widget_show (arrow);
@@ -685,21 +683,26 @@
}
static void
+wbcg_set_direction (SheetControlGUI const *scg)
+{
+ GtkWidget *w = (GtkWidget *)scg->wbcg->snotebook;
+ gboolean text_is_rtl = scg_sheet (scg)->text_is_rtl;
+ GtkTextDirection dir = text_is_rtl
+ ? GTK_TEXT_DIR_RTL
+ : GTK_TEXT_DIR_LTR;
+
+ if (dir != gtk_widget_get_direction (w))
+ set_dir (w, &dir);
+ g_object_set (scg->hs, "inverted", text_is_rtl, NULL);
+}
+
+static void
cb_direction_change (G_GNUC_UNUSED Sheet *null_sheet,
G_GNUC_UNUSED GParamSpec *null_pspec,
SheetControlGUI const *scg)
{
- if (scg == wbcg_cur_scg (scg->wbcg)) {
- GtkWidget *w = (GtkWidget *)scg->wbcg->notebook;
- gboolean text_is_rtl = scg_sheet (scg)->text_is_rtl;
- GtkTextDirection dir = text_is_rtl
- ? GTK_TEXT_DIR_RTL
- : GTK_TEXT_DIR_LTR;
-
- if (dir != gtk_widget_get_direction (w))
- set_dir (w, &dir);
- g_object_set (scg->hs, "inverted", text_is_rtl, NULL);
- }
+ if (scg && scg == wbcg_cur_scg (scg->wbcg))
+ wbcg_set_direction (scg);
}
static void
@@ -747,7 +750,8 @@
}
static void
-cb_notebook_switch_page (GtkNotebook *notebook, GtkNotebookPage *page,
+cb_notebook_switch_page (G_GNUC_UNUSED GtkNotebook *notebook_,
+ G_GNUC_UNUSED GtkNotebookPage *page_,
guint page_num, WBCGtk *wbcg)
{
Sheet *sheet;
@@ -756,7 +760,7 @@
g_return_if_fail (IS_WBC_GTK (wbcg));
/* Ignore events during destruction */
- if (wbcg->notebook == NULL)
+ if (wbcg->snotebook == NULL)
return;
/* While initializing adding the sheets will trigger page changes, but
@@ -769,8 +773,14 @@
if (NULL != wbcg->rangesel)
scg_rangesel_stop (wbcg->rangesel, TRUE);
+ /*
+ * Make snotebook follow bnotebook. This should be the only place
+ * that changes pages for snotebook.
+ */
+ gtk_notebook_set_current_page (wbcg->snotebook, page_num);
+
new_scg = wbcg_get_nth_scg (wbcg, page_num);
- cb_direction_change (NULL, NULL, new_scg);
+ wbcg_set_direction (new_scg);
if (wbcg_is_editing (wbcg) && wbcg_rangesel_possible (wbcg)) {
/*
@@ -791,21 +801,25 @@
* then prompt the user and don't switch the notebook page.
*/
if (wbcg_is_editing (wbcg)) {
- guint prev = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (notebook), "previous_page"));
+ guint prev = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (wbcg->snotebook),
+ "previous_page"));
if (prev == page_num)
return;
if (!wbcg_edit_finish (wbcg, WBC_EDIT_ACCEPT, NULL))
- gtk_notebook_set_current_page (notebook, prev);
+ gnm_notebook_set_current_page (wbcg->bnotebook,
+ prev);
else
/* Looks silly, but is really neccesarry */
- gtk_notebook_set_current_page (notebook, page_num);
+ gnm_notebook_set_current_page (wbcg->bnotebook,
+ page_num);
+
return;
}
- g_object_set_data (G_OBJECT (notebook), "previous_page",
- GINT_TO_POINTER (gtk_notebook_get_current_page (notebook)));
+ g_object_set_data (G_OBJECT (wbcg->snotebook), "previous_page",
+ GINT_TO_POINTER (gtk_notebook_get_current_page (wbcg->snotebook)));
/* if we are not selecting a range for an expression update */
sheet = wbcg_focus_cur_scg (wbcg);
@@ -818,26 +832,139 @@
}
}
+/*
+ * We want the pane managed differently that GtkHPaned does by default.
+ * When in automatic mode, we want at most 1/3 of the space to be
+ * allocated to the tabs. We don't want empty space on the tabs side
+ * at all.
+ *
+ * We is quite difficult to trick the GtkPaned into doing. Basically,
+ * we need to size_request the tabs notebook in non-scrollable mode
+ * and only make it scrollable if we don't have room. Further, we
+ * need to make the notebook non-shrinkable when (and only when) the
+ * paned has a set position.
+ */
static void
-workbook_setup_sheets (WBCGtk *wbcg)
+cb_paned_size_allocate (GtkHPaned *hpaned,
+ GtkAllocation *allocation)
{
- wbcg->notebook = g_object_new (GTK_TYPE_NOTEBOOK,
- "tab-pos", GTK_POS_BOTTOM,
- "tab-hborder", 0,
- "tab-vborder", 0,
- NULL);
- g_signal_connect_after (G_OBJECT (wbcg->notebook),
+ GtkPaned *paned = (GtkPaned *)hpaned;
+ GtkWidget *widget = (GtkWidget *)paned;
+ GtkRequisition child1_requisition;
+ gint handle_size;
+ gint p1, p2, h1, h2, w1, w2, w;
+ gint border_width = GTK_CONTAINER (paned)->border_width;
+ gboolean position_set;
+ GtkWidget *child1 = paned->child1;
+ GtkWidget *child2 = paned->child2;
+
+ if (child1 == NULL || !GTK_WIDGET_VISIBLE (child1) ||
+ child2 == NULL || !GTK_WIDGET_VISIBLE (child2))
+ goto chain;
+
+ g_object_get (G_OBJECT (paned), "position-set", &position_set, NULL);
+ if (position_set) {
+ g_object_set (G_OBJECT (child1), "scrollable", TRUE, NULL);
+ gtk_container_child_set (GTK_CONTAINER (paned),
+ child1, "shrink", FALSE,
+ NULL);
+ p1 = -1;
+ p2 = -1;
+ goto set_sizes;
+ }
+
+ if (!g_object_get_data (G_OBJECT (paned), PANED_SIGNAL_KEY))
+ goto chain;
+
+ widget->allocation = *allocation;
+
+ gtk_container_child_set (GTK_CONTAINER (paned),
+ child1, "shrink", TRUE,
+ NULL);
+
+ g_object_set (G_OBJECT (child1), "scrollable", FALSE, NULL);
+ gtk_widget_size_request (child1, &child1_requisition);
+
+ gtk_widget_style_get (widget, "handle-size", &handle_size, NULL);
+ w = widget->allocation.width - handle_size - 2 * border_width;
+ p1 = MIN (w / 3, child1->requisition.width);
+ p2 = w - p1;
+
+ if (p1 < child1->requisition.width) {
+ /*
+ * We don't have room so make the notebook scrollable.
+ * We will then not set the size again.
+ */
+ g_object_set (G_OBJECT (child1), "scrollable", TRUE, NULL);
+ }
+
+ set_sizes:
+ gtk_widget_get_size_request (child1, &w1, &h1);
+ if (p1 != w1)
+ gtk_widget_set_size_request (child1, p1, h1);
+
+ gtk_widget_get_size_request (child2, &w2, &h2);
+ if (p2 != w2)
+ gtk_widget_set_size_request (child2, p2, h2);
+
+ g_object_set_data (G_OBJECT (paned), PANED_SIGNAL_KEY, NULL);
+
+ chain:
+ GTK_WIDGET_GET_CLASS(paned)->size_allocate (widget, allocation);
+}
+
+static gboolean
+cb_paned_button_press (GtkWidget *widget, GdkEventButton *event)
+{
+ GtkPaned *paned = (GtkPaned *)widget;
+ if (event->type == GDK_2BUTTON_PRESS && event->button == 1) {
+ /* Cancel the drag that the first click started. */
+ GTK_WIDGET_GET_CLASS(paned)->button_release_event
+ (widget, event);
+ /* Then turn off set position that was set. */
+ gtk_paned_set_position (paned, -1);
+ signal_paned_repartition (paned);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+static void
+wbc_gtk_create_notebook_area (WBCGtk *wbcg)
+{
+ wbcg->notebook_area = gtk_vbox_new (FALSE, 0);
+
+ wbcg->snotebook = g_object_new (GTK_TYPE_NOTEBOOK,
+ "show-tabs", FALSE,
+ "show-border", FALSE,
+ NULL);
+ gtk_widget_show (GTK_WIDGET (wbcg->snotebook));
+ gtk_box_pack_start (GTK_BOX (wbcg->notebook_area),
+ GTK_WIDGET (wbcg->snotebook),
+ TRUE, TRUE, 0);
+
+ wbcg->bnotebook = g_object_new (GNM_NOTEBOOK_TYPE,
+ "tab-pos", GTK_POS_BOTTOM,
+ "show-border", FALSE,
+ "tab-hborder", 0,
+ "tab-vborder", 0,
+ NULL);
+ g_signal_connect_after (G_OBJECT (wbcg->bnotebook),
"switch_page",
G_CALLBACK (cb_notebook_switch_page), wbcg);
+ gtk_paned_pack1 (wbcg->tabs_paned, GTK_WIDGET (wbcg->bnotebook), FALSE, TRUE);
- gtk_table_attach (GTK_TABLE (wbcg->table), GTK_WIDGET (wbcg->notebook),
+ gtk_widget_show_all (GTK_WIDGET (wbcg->tabs_paned));
+ gtk_widget_show (GTK_WIDGET (wbcg->notebook_area));
+ gtk_table_attach (GTK_TABLE (wbcg->table),
+ wbcg->notebook_area,
0, 1, 1, 2,
GTK_FILL | GTK_EXPAND | GTK_SHRINK,
GTK_FILL | GTK_EXPAND | GTK_SHRINK,
0, 0);
- gtk_widget_show (GTK_WIDGET (wbcg->notebook));
-
#ifdef GNM_USE_HILDON
gtk_notebook_set_show_border (wbcg->notebook, FALSE);
gtk_notebook_set_show_tabs (wbcg->notebook, FALSE);
@@ -874,18 +1001,16 @@
}
#endif
-
static void
wbcg_menu_state_sheet_count (WBCGtk *wbcg)
{
- int const sheet_count = gnm_notebook_get_n_visible (wbcg->notebook);
+ int const sheet_count = gnm_notebook_get_n_visible (wbcg->bnotebook);
/* Should we enable commands requiring multiple sheets */
gboolean const multi_sheet = (sheet_count > 1);
- /* Scrollable if there are more than 3 tabs */
- gtk_notebook_set_scrollable (wbcg->notebook, sheet_count > 3);
-
wbc_gtk_set_action_sensitivity (wbcg, "SheetRemove", multi_sheet);
+
+ signal_paned_repartition (wbcg->tabs_paned);
}
static void
@@ -893,11 +1018,16 @@
G_GNUC_UNUSED GParamSpec *pspec,
EditableLabel *el)
{
+ SheetControlGUI *scg = get_scg (GTK_WIDGET (el));
+ g_return_if_fail (IS_SHEET_CONTROL_GUI (scg));
+
/* We're lazy and just set all relevant attributes. */
editable_label_set_text (el, sheet->name_unquoted);
editable_label_set_color (el,
sheet->tab_color ? &sheet->tab_color->gdk_color : NULL,
sheet->tab_text_color ? &sheet->tab_text_color->gdk_color : NULL);
+
+ signal_paned_repartition (scg->wbcg->tabs_paned);
}
static void
@@ -912,32 +1042,53 @@
static void
cb_sheet_visibility_change (Sheet *sheet,
G_GNUC_UNUSED GParamSpec *pspec,
- WBCGtk *wbcg)
+ SheetControlGUI *scg)
{
- GtkWidget *w = gtk_notebook_get_nth_page (wbcg->notebook, sheet->index_in_wb);
- if (sheet_is_visible (sheet))
- gtk_widget_show (w);
- else
- gtk_widget_hide (w);
+ g_return_if_fail (IS_SHEET_CONTROL_GUI (scg));
- wbcg_menu_state_sheet_count (wbcg);
+ g_object_set (GTK_WIDGET (scg->label),
+ "visible", sheet_is_visible (sheet),
+ NULL);
+ wbcg_menu_state_sheet_count (scg->wbcg);
}
static void
-disconnect_sheet_signals (WBCGtk *wbcg, Sheet *sheet, gboolean focus_signals_only)
+disconnect_sheet_focus_signals (WBCGtk *wbcg)
{
- SheetControlGUI *scg = wbcg_get_scg (wbcg, sheet);
+ SheetControlGUI *scg = wbcg->active_scg;
+ Sheet *sheet;
- if (scg) {
- g_signal_handlers_disconnect_by_func (sheet, cb_toggle_menu_item_changed, wbcg);
- g_signal_handlers_disconnect_by_func (sheet, cb_direction_change, scg);
- g_signal_handlers_disconnect_by_func (sheet, cb_zoom_change, wbcg);
-
- if (!focus_signals_only) {
- g_signal_handlers_disconnect_by_func (sheet, cb_sheet_tab_change, scg->label);
- g_signal_handlers_disconnect_by_func (sheet, cb_sheet_visibility_change, wbcg);
- }
- }
+ if (!scg)
+ return;
+
+ sheet = scg_sheet (scg);
+
+#if 0
+ g_printerr ("Disconnecting focus for %s with scg=%p\n", sheet->name_unquoted, scg);
+#endif
+
+ g_signal_handlers_disconnect_by_func (sheet, cb_toggle_menu_item_changed, wbcg);
+ g_signal_handlers_disconnect_by_func (sheet, cb_direction_change, scg);
+ g_signal_handlers_disconnect_by_func (sheet, cb_zoom_change, wbcg);
+
+ wbcg->active_scg = NULL;
+}
+
+static void
+disconnect_sheet_signals (SheetControlGUI *scg)
+{
+ WBCGtk *wbcg = scg->wbcg;
+ Sheet *sheet = scg_sheet (scg);
+
+ if (scg == wbcg->active_scg)
+ disconnect_sheet_focus_signals (wbcg);
+
+#if 0
+ g_printerr ("Disconnecting all for %s with scg=%p\n", sheet->name_unquoted, scg);
+#endif
+
+ g_signal_handlers_disconnect_by_func (sheet, cb_sheet_tab_change, scg->label);
+ g_signal_handlers_disconnect_by_func (sheet, cb_sheet_visibility_change, scg);
}
static void
@@ -954,22 +1105,17 @@
g_return_if_fail (wbcg != NULL);
- if (wbcg->notebook == NULL)
- workbook_setup_sheets (wbcg);
-
scg = sheet_control_gui_new (sv, wbcg);
+
g_object_set_data (G_OBJECT (scg->table), SHEET_CONTROL_KEY, scg);
- /*
- * NB. this is so we can use editable_label_set_text since
- * gtk_notebook_set_tab_label kills our widget & replaces with a label.
- */
- scg->label = editable_label_new (sheet->name_unquoted,
- sheet->tab_color ? &sheet->tab_color->gdk_color : NULL,
- sheet->tab_text_color ? &sheet->tab_text_color->gdk_color : NULL);
+ g_object_set_data (G_OBJECT (scg->label), SHEET_CONTROL_KEY, scg);
g_signal_connect_after (G_OBJECT (scg->label),
"edit_finished",
G_CALLBACK (cb_sheet_label_edit_finished), wbcg);
+ g_signal_connect (G_OBJECT (scg->label),
+ "notify::text",
+ G_CALLBACK (cb_sheet_label_edit_happened), wbcg);
/* do not preempt the editable label handler */
g_signal_connect_after (G_OBJECT (scg->label),
@@ -987,7 +1133,7 @@
"signal::drag_begin", G_CALLBACK (cb_sheet_label_drag_begin), wbcg,
"signal::drag_end", G_CALLBACK (cb_sheet_label_drag_end), wbcg,
"signal::drag_leave", G_CALLBACK (cb_sheet_label_drag_leave), wbcg,
- "signal::drag_data_get", G_CALLBACK (cb_sheet_label_drag_data_get), wbcg,
+ "signal::drag_data_get", G_CALLBACK (cb_sheet_label_drag_data_get), NULL,
"signal::drag_data_received", G_CALLBACK (cb_sheet_label_drag_data_received), wbcg,
"signal::drag_motion", G_CALLBACK (cb_sheet_label_drag_motion), wbcg,
NULL);
@@ -997,16 +1143,24 @@
if (!visible)
gtk_widget_hide (GTK_WIDGET (scg->table));
g_object_connect (G_OBJECT (sheet),
- "signal::notify::visibility", cb_sheet_visibility_change, wbcg,
+ "signal::notify::visibility", cb_sheet_visibility_change, scg,
"signal::notify::name", cb_sheet_tab_change, scg->label,
"signal::notify::tab-foreground", cb_sheet_tab_change, scg->label,
"signal::notify::tab-background", cb_sheet_tab_change, scg->label,
NULL);
if (wbcg_ui_update_begin (wbcg)) {
- gtk_notebook_insert_page (wbcg->notebook,
- GTK_WIDGET (scg->table), scg->label,
- sheet->index_in_wb);
+ /*
+ * Just let wbcg_sheet_order_changed deal with where to put
+ * it.
+ */
+ int pos = -1;
+ gtk_notebook_insert_page (wbcg->snotebook,
+ GTK_WIDGET (scg->table), NULL,
+ pos);
+ gnm_notebook_insert_tab (wbcg->bnotebook,
+ GTK_WIDGET (scg->label),
+ pos);
wbcg_menu_state_sheet_count (wbcg);
wbcg_ui_update_end (wbcg);
}
@@ -1014,7 +1168,7 @@
scg_adjust_preferences (scg);
if (sheet == wb_control_cur_sheet (wbc)) {
scg_take_focus (scg);
- cb_direction_change (NULL, NULL, scg);
+ wbcg_set_direction (scg);
cb_zoom_change (sheet, NULL, wbcg);
cb_toggle_menu_item_changed (sheet, NULL, wbcg);
}
@@ -1024,13 +1178,16 @@
wbcg_sheet_remove (WorkbookControl *wbc, Sheet *sheet)
{
WBCGtk *wbcg = (WBCGtk *)wbc;
+ SheetControlGUI *scg = wbcg_get_scg (wbcg, sheet);
/* During destruction we may have already removed the notebook */
- if (wbcg->notebook == NULL)
+ if (scg == NULL)
return;
- disconnect_sheet_signals (wbcg, sheet, FALSE);
- gtk_notebook_remove_page (wbcg->notebook, sheet->index_in_wb);
+ disconnect_sheet_signals (scg);
+
+ gtk_widget_destroy (GTK_WIDGET (scg->label));
+ gtk_widget_destroy (GTK_WIDGET (scg->table));
wbcg_menu_state_sheet_count (wbcg);
}
@@ -1041,17 +1198,24 @@
WBCGtk *wbcg = (WBCGtk *)wbc;
SheetControlGUI *scg = wbcg_get_scg (wbcg, sheet);
- if (sheet)
- gtk_notebook_set_current_page (wbcg->notebook,
- sheet->index_in_wb);
+ if (scg) {
+ int n = gtk_notebook_page_num (wbcg->snotebook,
+ GTK_WIDGET (scg->table));
+ gnm_notebook_set_current_page (wbcg->bnotebook, n);
+ }
+
if (wbcg->rangesel == NULL)
gnm_expr_entry_set_scg (wbcg->edit_line.entry, scg);
- disconnect_sheet_signals (wbcg, wbcg_cur_sheet (wbcg), TRUE);
+ disconnect_sheet_focus_signals (wbcg);
if (sheet) {
wbcg_update_menu_feedback (wbcg, sheet);
- cb_direction_change (NULL, NULL, scg);
+ wbcg_set_direction (scg);
+
+#if 0
+ g_printerr ("Connecting for %s with scg=%p\n", sheet->name_unquoted, scg);
+#endif
g_object_connect
(G_OBJECT (sheet),
@@ -1066,29 +1230,39 @@
"signal::notify::text-is-rtl", cb_direction_change, scg,
"signal::notify::zoom-factor", cb_zoom_change, wbcg,
NULL);
+
+ wbcg->active_scg = scg;
}
}
+static gint
+by_sheet_index (gconstpointer a, gconstpointer b)
+{
+ SheetControlGUI *scga = (SheetControlGUI *)a;
+ SheetControlGUI *scgb = (SheetControlGUI *)b;
+ return scg_sheet (scga)->index_in_wb - scg_sheet (scgb)->index_in_wb;
+}
+
static void
wbcg_sheet_order_changed (WBCGtk *wbcg)
{
- GtkNotebook *nb = wbcg->notebook;
- int i, n = gtk_notebook_get_n_pages (nb);
- SheetControlGUI **scgs = g_new (SheetControlGUI *, n);
-
- /* Collect the scgs first as we are moving pages. */
- for (i = 0 ; i < n; i++)
- scgs[i] = wbcg_get_nth_scg (wbcg, i);
-
- for (i = 0 ; i < n; i++) {
- SheetControlGUI *scg = scgs[i];
- Sheet *sheet = scg_sheet (scg);
- gtk_notebook_reorder_child (nb,
+ GList *l, *scgs = get_all_scgs (wbcg);
+ int i;
+
+ /* Reorder all tabs so they end up in index_in_wb order. */
+ scgs = g_list_sort (scgs, by_sheet_index);
+
+ for (i = 0, l = scgs; l; l = l->next, i++) {
+ SheetControlGUI *scg = l->data;
+ gtk_notebook_reorder_child (wbcg->snotebook,
GTK_WIDGET (scg->table),
- sheet->index_in_wb);
+ i);
+ gnm_notebook_move_tab (wbcg->bnotebook,
+ GTK_WIDGET (scg->label),
+ i);
}
- g_free (scgs);
+ g_list_free (scgs);
}
static void
@@ -1111,20 +1285,23 @@
{
WBCGtk *wbcg = (WBCGtk *)wbc;
- if (wbcg->notebook != NULL) {
- GtkWidget *tmp = GTK_WIDGET (wbcg->notebook);
- Workbook *wb = wb_control_get_workbook (wbc);
- int i;
+ if (wbcg->snotebook != NULL) {
+ GtkWidget *tmp = GTK_WIDGET (wbcg->snotebook);
+ GList *l, *all = get_all_scgs (wbcg);
/* Clear notebook to disable updates as focus changes for pages
* during destruction */
- wbcg->notebook = NULL;
+ wbcg->snotebook = NULL;
/* Be sure we are no longer editing */
wbcg_edit_finish (wbcg, WBC_EDIT_REJECT, NULL);
- for (i = workbook_sheet_count (wb) - 1; i >= 0; i--)
- disconnect_sheet_signals (wbcg, workbook_sheet_by_index (wb, i), FALSE);
+ for (l = all; l; l = l->next) {
+ SheetControlGUI *scg = l->data;
+ disconnect_sheet_signals (scg);
+ }
+
+ g_list_free (all);
gtk_widget_destroy (tmp);
}
@@ -1645,7 +1822,7 @@
* the current book. Which leads to a slew of errors for keystrokes
* until focus is corrected.
*/
- if (wbcg->notebook) {
+ if (wbcg->snotebook) {
wbcg_focus_cur_scg (wbcg);
wbcg_update_menu_feedback (wbcg,
wb_control_cur_sheet (WORKBOOK_CONTROL (wbcg)));
@@ -1711,10 +1888,10 @@
{
g_return_if_fail (IS_WBC_GTK (wbcg));
- if ((!wbcg->last_key_was_end) != (!flag)) {
- wbcg_set_status_text (wbcg,
- (wbcg->last_key_was_end = flag)
- ? "END" : "");
+ if (!wbcg->last_key_was_end != !flag) {
+ const char *txt = flag ? _("END") : "";
+ wbcg_set_status_text (wbcg, txt);
+ wbcg->last_key_was_end = flag;
}
}
@@ -1735,8 +1912,8 @@
static void
cb_update_item_bar_font (GtkWidget *w)
{
- SheetControl *sc = g_object_get_data (G_OBJECT (w), SHEET_CONTROL_KEY);
- sc_resize (sc, TRUE);
+ SheetControlGUI *scg = get_scg (w);
+ sc_resize ((SheetControl *)scg, TRUE);
}
static void
@@ -1746,7 +1923,7 @@
if (wbcg->font_desc)
pango_font_description_free (wbcg->font_desc);
wbcg->font_desc = settings_get_font_desc (settings);
- gtk_container_foreach (GTK_CONTAINER (wbcg->notebook),
+ gtk_container_foreach (GTK_CONTAINER (wbcg->snotebook),
(GtkCallback)cb_update_item_bar_font, NULL);
}
@@ -1782,7 +1959,7 @@
wbcg->preferred_geometry)) {
g_free (wbcg->preferred_geometry);
wbcg->preferred_geometry = NULL;
- } else if (wbcg->notebook != NULL &&
+ } else if (wbcg->snotebook != NULL &&
wbv != NULL &&
(wbv->preferred_width > 0 || wbv->preferred_height > 0)) {
/* Set grid size to preferred width */
@@ -1792,7 +1969,7 @@
pwidth = pwidth > 0 ? pwidth : -1;
pheight = pheight > 0 ? pheight : -1;
- gtk_widget_set_size_request (GTK_WIDGET (wbcg->notebook),
+ gtk_widget_set_size_request (GTK_WIDGET (wbcg->notebook_area),
pwidth, pheight);
gtk_widget_size_request (GTK_WIDGET (wbcg->toplevel),
&requisition);
@@ -1822,8 +1999,9 @@
gtk_window_set_default_size (wbcg_toplevel (wbcg), sx * fx, sy * fy);
}
- if (NULL != (scg = wbcg_cur_scg (wbcg)))
- cb_direction_change (NULL, NULL, scg);
+ scg = wbcg_cur_scg (wbcg);
+ if (scg)
+ wbcg_set_direction (scg);
gtk_widget_show (GTK_WIDGET (wbcg_toplevel (wbcg)));
@@ -1838,20 +2016,34 @@
wbcg_get_label_for_position (WBCGtk *wbcg, GtkWidget *source,
gint x)
{
- GtkWidget *label = NULL, *page;
guint n, i;
+ GtkWidget *last_visible = NULL;
g_return_val_if_fail (IS_WBC_GTK (wbcg), NULL);
- n = g_list_length (wbcg->notebook->children);
+ n = wbcg_get_n_scg (wbcg);
for (i = 0; i < n; i++) {
- page = gtk_notebook_get_nth_page (wbcg->notebook, i);
- label = gtk_notebook_get_tab_label (wbcg->notebook, page);
- if (label->allocation.x + label->allocation.width >= x)
- break;
+ GtkWidget *label = gnm_notebook_get_nth_label (wbcg->bnotebook, i);
+ int x0, x1;
+
+ if (!GTK_WIDGET_VISIBLE (label))
+ continue;
+
+ x0 = label->allocation.x;
+ x1 = x0 + label->allocation.width;
+
+ if (x <= x1) {
+ /*
+ * We are left of this label's right edge. Use it
+ * even if we are far left of the label.
+ */
+ return label;
+ }
+
+ last_visible = label;
}
- return (label);
+ return last_visible;
}
static gboolean
@@ -1872,7 +2064,8 @@
* drag motion over a label.
*/
GtkWidget *label = wbcg_get_label_for_position (wbcg, source_widget, x);
- return cb_sheet_label_drag_motion (label, context, x, y, time, wbcg);
+ return cb_sheet_label_drag_motion (label, context, x, y,
+ time, wbcg);
} else if (wbcg_is_local_drag (wbcg, source_widget))
gnm_pane_object_autoscroll (GNM_PANE (source_widget),
context, x, y, time);
@@ -1914,8 +2107,7 @@
GtkWidget *label = wbcg_get_label_for_position (wbcg,
gtk_drag_get_source_widget (context), x);
cb_sheet_label_drag_data_received (label, context, x, y,
- selection_data, info, time, wbcg);
-
+ selection_data, info, time, wbcg);
} else {
GtkWidget *source_widget = gtk_drag_get_source_widget (context);
if (wbcg_is_local_drag (wbcg, source_widget))
@@ -1928,7 +2120,7 @@
}
static void
-wbcg_create_edit_area (WBCGtk *wbcg)
+wbc_gtk_create_edit_area (WBCGtk *wbcg)
{
GtkToolItem *item;
GtkEntry *entry;
@@ -3771,14 +3963,25 @@
gtk_widget_ensure_style (tmp);
gtk_widget_set_size_request (tmp, go_pango_measure_string (
gtk_widget_get_pango_context (GTK_WIDGET (wbcg->toplevel)),
- tmp->style->font_desc, "W") * 15, -1);
+ tmp->style->font_desc, "W") * 5, -1);
+
+ wbcg->tabs_paned = GTK_PANED (gtk_hpaned_new ());
+ gtk_paned_pack2 (wbcg->tabs_paned, wbcg->progress_bar, FALSE, TRUE);
+ g_signal_connect (G_OBJECT (wbcg->tabs_paned),
+ "size-allocate", G_CALLBACK (cb_paned_size_allocate),
+ NULL);
+ g_signal_connect (G_OBJECT (wbcg->tabs_paned),
+ "button-press-event", G_CALLBACK (cb_paned_button_press),
+ NULL);
wbcg->status_area = gtk_hbox_new (FALSE, 2);
- gtk_box_pack_end (GTK_BOX (wbcg->status_area), wbcg->status_text, FALSE, TRUE, 0);
- gtk_box_pack_end (GTK_BOX (wbcg->status_area), frame, FALSE, TRUE, 0);
- gtk_box_pack_end (GTK_BOX (wbcg->status_area), wbcg->progress_bar, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (wbcg->status_area),
+ GTK_WIDGET (wbcg->tabs_paned),
+ TRUE, TRUE, 0);
+ gtk_box_pack_end (GTK_BOX (wbcg->status_area), wbcg->status_text, FALSE, FALSE, 0);
+ gtk_box_pack_end (GTK_BOX (wbcg->status_area), frame, FALSE, FALSE, 0);
gtk_box_pack_end (GTK_BOX (wbcg->everything),
- wbcg->status_area, FALSE, TRUE, 0);
+ wbcg->status_area, FALSE, TRUE, 0);
gtk_widget_show_all (wbcg->status_area);
g_hash_table_insert (wbcg->visibility_widgets,
@@ -4003,9 +4206,9 @@
wbcg_autosave_cancel (wbcg);
- if (wbcg->notebook != NULL)
+ if (wbcg->bnotebook != NULL)
g_signal_handlers_disconnect_by_func (
- G_OBJECT (wbcg->notebook),
+ G_OBJECT (wbcg->bnotebook),
G_CALLBACK (cb_notebook_switch_page), wbcg);
g_signal_handlers_disconnect_by_func (
G_OBJECT (wbcg->toplevel),
@@ -4378,7 +4581,9 @@
#endif
wbcg->table = gtk_table_new (0, 0, 0);
- wbcg->notebook = NULL;
+ wbcg->bnotebook = NULL;
+ wbcg->snotebook = NULL;
+ wbcg->notebook_area = NULL;
wbcg->updating_ui = FALSE;
wbcg->rangesel = NULL;
wbcg->font_desc = NULL;
@@ -4567,7 +4772,7 @@
wbcg->preferred_geometry = g_strdup (optional_geometry);
- wbcg_create_edit_area (wbcg);
+ wbc_gtk_create_edit_area (wbcg);
wbc_gtk_create_status_area (wbcg);
wbc_gtk_reload_recent_file_menu (wbcg);
@@ -4585,6 +4790,9 @@
cb_zoom_change (sheet, NULL, wbcg);
}
+ wbc_gtk_create_notebook_area (wbcg);
+ signal_paned_repartition (wbcg->tabs_paned);
+
wbcg_view_changed (wbcg, NULL, NULL);
if (optional_screen)
@@ -4593,7 +4801,7 @@
/* Postpone showing the GUI, so that we may resize it freely. */
g_idle_add ((GSourceFunc) show_gui, wbcg);
- wb_control_init_state ((WorkbookControl *)wbcg);
+ wb_control_init_state (wbc);
return wbcg;
}
@@ -4628,6 +4836,12 @@
go_gtk_window_set_transient (wbcg_toplevel (wbcg), window);
}
+int
+wbcg_get_n_scg (WBCGtk const *wbcg)
+{
+ return gtk_notebook_get_n_pages (wbcg->snotebook);
+}
+
/**
* wbcg_get_nth_scg
* @wbcg : #WBCGtk
@@ -4644,9 +4858,9 @@
g_return_val_if_fail (IS_WBC_GTK (wbcg), NULL);
- if (NULL != wbcg->notebook &&
- NULL != (w = gtk_notebook_get_nth_page (wbcg->notebook, i)) &&
- NULL != (scg = g_object_get_data (G_OBJECT (w), SHEET_CONTROL_KEY)) &&
+ if (NULL != wbcg->snotebook &&
+ NULL != (w = gtk_notebook_get_nth_page (wbcg->snotebook, i)) &&
+ NULL != (scg = get_scg (w)) &&
NULL != scg->table &&
NULL != scg_sheet (scg) &&
NULL != scg_view (scg))
@@ -4673,11 +4887,11 @@
g_return_val_if_fail (IS_WBC_GTK (wbcg), NULL);
- if (wbcg->notebook == NULL)
+ if (wbcg->snotebook == NULL)
return NULL;
scg = wbcg_get_nth_scg (wbcg,
- gtk_notebook_get_current_page (wbcg->notebook));
+ gtk_notebook_get_current_page (wbcg->snotebook));
g_return_val_if_fail (scg != NULL, NULL);
@@ -4705,8 +4919,9 @@
if (!wbcg->font_desc) {
GtkSettings *settings = wbcg_get_gtk_settings (wbcg);
wbcg->font_desc = settings_get_font_desc (settings);
- g_signal_connect (settings, "notify::gtk-font-name",
- G_CALLBACK (cb_desktop_font_changed), wbcg);
+ g_signal_connect_object (settings, "notify::gtk-font-name",
+ G_CALLBACK (cb_desktop_font_changed),
+ wbcg, 0);
}
return wbcg->font_desc;
}
Modified: trunk/src/wbc-gtk.h
==============================================================================
--- trunk/src/wbc-gtk.h (original)
+++ trunk/src/wbc-gtk.h Sun Nov 23 15:21:00 2008
@@ -29,6 +29,7 @@
SheetControlGUI *wbcg_cur_scg (WBCGtk *wbcg);
Sheet *wbcg_cur_sheet (WBCGtk *wbcg);
Sheet *wbcg_focus_cur_scg (WBCGtk *wbcg);
+int wbcg_get_n_scg (WBCGtk const *wbcg);
gboolean wbcg_ui_update_begin (WBCGtk *wbcg);
void wbcg_ui_update_end (WBCGtk *wbcg);
Modified: trunk/src/widgets/Makefile.am
==============================================================================
--- trunk/src/widgets/Makefile.am (original)
+++ trunk/src/widgets/Makefile.am Sun Nov 23 15:21:00 2008
@@ -13,6 +13,8 @@
gnm-dao.h \
gnm-format-sel.c \
gnm-format-sel.h \
+ gnm-notebook.c \
+ gnm-notebook.h \
widget-editable-label.c \
widget-editable-label.h \
widget-font-selector.c \
Added: trunk/src/widgets/gnm-notebook.c
==============================================================================
--- (empty file)
+++ trunk/src/widgets/gnm-notebook.c Sun Nov 23 15:21:00 2008
@@ -0,0 +1,250 @@
+/**
+ * gnm-notebook.h: Implements a button-only notebook.
+ *
+ * Copyright (c) 2008 Morten Welinder <terra gnome org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ **/
+
+#include <gnumeric-config.h>
+#include "gnm-notebook.h"
+#include <gsf/gsf-impl-utils.h>
+
+struct _GnmNotebook {
+ GtkNotebook parent;
+
+ /*
+ * This is the number of pixels from a regular notebook that
+ * we are not drawing. It is caused by the empty widgets
+ * that we have to use.
+ */
+ int dummy_height;
+};
+
+typedef struct {
+ GtkNotebookClass parent_class;
+} GnmNotebookClass;
+
+static GtkNotebookClass *gnm_notebook_parent_class;
+
+#define DUMMY_KEY "GNM-NOTEBOOK-DUMMY-WIDGET"
+
+static void
+gnm_notebook_size_request (GtkWidget *widget,
+ GtkRequisition *requisition)
+{
+ ((GtkWidgetClass *)gnm_notebook_parent_class)->size_request
+ (widget, requisition);
+ widget->requisition.height -= widget->style->ythickness;
+}
+
+static void
+gnm_notebook_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ int i, h = 0;
+ GnmNotebook *gnb = (GnmNotebook *)widget;
+ GtkAllocation alc = *allocation;
+
+ for (i = 0; TRUE; i++) {
+ GtkWidget *page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (widget), i);
+ if (!page)
+ break;
+ if (!GTK_WIDGET_VISIBLE (page))
+ continue;
+ h = MAX (h, page->allocation.height);
+ }
+ h += widget->style->ythickness;
+
+ gnb->dummy_height = h;
+
+ alc.y -= h;
+ ((GtkWidgetClass *)gnm_notebook_parent_class)->size_allocate
+ (widget, &alc);
+}
+
+#if 0
+static void
+dump_region (GdkRegion *reg)
+{
+ GdkRectangle *rects;
+ gint i, n;
+
+ gdk_region_get_rectangles (reg, &rects, &n);
+ g_printerr ("Region has %d rectangles.\n", n);
+ for (i = 0; i < n; i++)
+ g_printerr (" region %d : (%d,%d) at %dx%d\n",
+ i,
+ rects[i].x, rects[i].y,
+ rects[i].width, rects[i].height);
+}
+#endif
+
+static gint
+gnm_notebook_expose (GtkWidget *widget,
+ GdkEventExpose *event)
+{
+ GnmNotebook *gnb = (GnmNotebook *)widget;
+ GdkEvent *ev = gdk_event_copy ((GdkEvent *)event);
+ GdkEventExpose *eve = (GdkEventExpose *)ev;
+ GtkAllocation alc = widget->allocation;
+ int res = FALSE;
+
+ alc.y += gnb->dummy_height;
+ alc.height -= gnb->dummy_height;
+ if (gdk_rectangle_intersect (&alc, &eve->area, &eve->area)) {
+ GdkRegion *reg = gdk_region_rectangle (&eve->area);
+ gdk_region_intersect (reg, eve->region);
+ gdk_region_destroy (eve->region);
+ eve->region = reg;
+
+ res = ((GtkWidgetClass *)gnm_notebook_parent_class)->expose_event (widget, eve);
+ }
+
+ gdk_event_free (ev);
+
+ return res;
+}
+
+static void
+gnm_notebook_class_init (GtkObjectClass *klass)
+{
+ GtkWidgetClass *widget_class = (GtkWidgetClass *)klass;
+
+ gnm_notebook_parent_class = g_type_class_peek (GTK_TYPE_NOTEBOOK);
+ widget_class->size_request = gnm_notebook_size_request;
+ widget_class->size_allocate = gnm_notebook_size_allocate;
+ widget_class->expose_event = gnm_notebook_expose;
+
+ gtk_rc_parse_string ("style \"gnm-notebook-default-style\" {\n"
+ " ythickness = 0\n"
+ "}\n"
+ "class \"GnmNotebook\" style \"gnm-notebook-default-style\"\n"
+ );
+}
+
+static void
+gnm_notebook_init (G_GNUC_UNUSED GnmNotebook *notebook)
+{
+}
+
+GSF_CLASS (GnmNotebook, gnm_notebook,
+ gnm_notebook_class_init, gnm_notebook_init, GTK_TYPE_NOTEBOOK)
+
+int
+gnm_notebook_get_n_visible (GnmNotebook *nb)
+{
+ int count = 0;
+ GList *l, *children = gtk_container_get_children (GTK_CONTAINER (nb));
+
+ for (l = children; l; l = l->next) {
+ GtkWidget *child = l->data;
+ if (GTK_WIDGET_VISIBLE (child))
+ count++;
+ }
+
+ g_list_free (children);
+
+ return count;
+}
+
+GtkWidget *
+gnm_notebook_get_nth_label (GnmNotebook *nb, int n)
+{
+ GtkWidget *page;
+
+ g_return_val_if_fail (IS_GNM_NOTEBOOK (nb), NULL);
+
+ page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (nb), n);
+ if (!page)
+ return NULL;
+
+ return gtk_notebook_get_tab_label (GTK_NOTEBOOK (nb), page);
+}
+
+static void
+cb_label_destroyed (G_GNUC_UNUSED GtkWidget *label, GtkWidget *dummy)
+{
+ gtk_widget_destroy (dummy);
+}
+
+static void
+cb_label_visibility (GtkWidget *label,
+ G_GNUC_UNUSED GParamSpec *pspec,
+ GtkWidget *dummy)
+{
+ g_object_set (GTK_OBJECT (dummy),
+ "visible", GTK_WIDGET_VISIBLE (label),
+ NULL);
+}
+
+void
+gnm_notebook_insert_tab (GnmNotebook *nb, GtkWidget *label, int pos)
+{
+ GtkWidget *dummy_page = gtk_hbox_new (FALSE, 0);
+ gtk_widget_set_size_request (dummy_page, 1, 1);
+ gtk_widget_show (dummy_page);
+ g_object_set_data (G_OBJECT (label), DUMMY_KEY, dummy_page);
+
+ g_signal_connect_object (G_OBJECT (label), "destroy",
+ G_CALLBACK (cb_label_destroyed), dummy_page,
+ 0);
+ g_signal_connect_object (G_OBJECT (label), "notify::visible",
+ G_CALLBACK (cb_label_visibility), dummy_page,
+ 0);
+
+ gtk_notebook_insert_page (GTK_NOTEBOOK (nb), dummy_page, label, pos);
+}
+
+void
+gnm_notebook_move_tab (GnmNotebook *nb, GtkWidget *label, int newpos)
+{
+ GtkWidget *child = g_object_get_data (G_OBJECT (label), DUMMY_KEY);
+ gtk_notebook_reorder_child (GTK_NOTEBOOK (nb), child, newpos);
+}
+
+void
+gnm_notebook_set_tab_visible (GnmNotebook *nb, int page, gboolean viz)
+{
+ GtkWidget *dummy;
+ g_return_if_fail (IS_GNM_NOTEBOOK (nb));
+
+ dummy = gtk_notebook_get_nth_page (GTK_NOTEBOOK (nb), page);
+ if (!dummy)
+ return;
+
+ if (viz)
+ gtk_widget_show (dummy);
+ else
+ gtk_widget_hide (dummy);
+}
+
+void
+gnm_notebook_set_current_page (GnmNotebook *nb, int page)
+{
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (nb), page);
+}
+
+void
+gnm_notebook_prev_page (GnmNotebook *nb)
+{
+ gtk_notebook_prev_page (GTK_NOTEBOOK (nb));
+}
+
+void
+gnm_notebook_next_page (GnmNotebook *nb)
+{
+ gtk_notebook_next_page (GTK_NOTEBOOK (nb));
+}
Added: trunk/src/widgets/gnm-notebook.h
==============================================================================
--- (empty file)
+++ trunk/src/widgets/gnm-notebook.h Sun Nov 23 15:21:00 2008
@@ -0,0 +1,44 @@
+/**
+ * gnm-notebook.h: Implements a button-only notebook.
+ *
+ * Copyright (c) 2008 Morten Welinder <terra gnome org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ **/
+
+#ifndef __GNM_NOTEBOOK_H__
+#define __GNM_NOTEBOOK_H__
+
+#include <gtk/gtk.h>
+
+#define GNM_NOTEBOOK_TYPE (gnm_notebook_get_type ())
+#define GNM_NOTEBOOK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNM_NOTEBOOK_TYPE, GnmNotebook))
+#define IS_GNM_NOTEBOOK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNM_NOTEBOOK_TYPE))
+
+typedef struct _GnmNotebook GnmNotebook;
+
+GType gnm_notebook_get_type (void);
+
+int gnm_notebook_get_n_visible (GnmNotebook *nb);
+GtkWidget * gnm_notebook_get_nth_label (GnmNotebook *nb, int n);
+void gnm_notebook_insert_tab (GnmNotebook *nb, GtkWidget *label,
+ int pos);
+void gnm_notebook_move_tab (GnmNotebook *nb, GtkWidget *label, int newpos);
+void gnm_notebook_set_tab_visible (GnmNotebook *nb, int page, gboolean viz);
+void gnm_notebook_set_current_page (GnmNotebook *nb, int page);
+void gnm_notebook_prev_page (GnmNotebook *nb);
+void gnm_notebook_next_page (GnmNotebook *nb);
+
+#endif /*__GNM_NOTEBOOK_H__*/
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]