patches from rob browning

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@842 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Linas Vepstas 1998-05-19 00:23:45 +00:00
parent 24059fd35f
commit 432b61f132
11 changed files with 2088 additions and 360 deletions

View File

@ -35,11 +35,11 @@ CFLAGS := -O2 -Wall -g -Wall -DCELL_WIDGETS=1 ${INCLPATH}
######################################################################
# See Makefile.common for information about these variables.
COMMON_SRCS := basiccell.c cellblock.c combocell.c \
COMMON_SRCS := basiccell.c cellblock.c \
datecell.c pricecell.c QuickFill.c quickfillcell.c \
recncell.c register.c table-allgui.c textcell.c
MOTIF_SRCS := table-motif.c
GNOME_SRCS := table-gtk.c
MOTIF_SRCS := table-motif.c combocell-motif.c
GNOME_SRCS := table-gtk.c combocell-gtk.c
######################################################################
all:

View File

@ -35,11 +35,11 @@ CFLAGS := @CFLAGS@ -DCELL_WIDGETS=1 ${INCLPATH}
######################################################################
# See Makefile.common for information about these variables.
COMMON_SRCS := basiccell.c cellblock.c combocell.c \
COMMON_SRCS := basiccell.c cellblock.c \
datecell.c pricecell.c QuickFill.c quickfillcell.c \
recncell.c register.c table-allgui.c textcell.c
MOTIF_SRCS := table-motif.c
GNOME_SRCS := table-gtk.c
MOTIF_SRCS := table-motif.c combocell-motif.c
GNOME_SRCS := table-gtk.c combocell-gtk.c
######################################################################
all:

View File

@ -0,0 +1,720 @@
/*
* FILE:
* combocell.c
*
* FUNCTION:
* implement motif portions of a pull-down combo widget
* embedded in a table cell.
*
* HISTORY:
* Copyright (c) 1998 Linas Vepstas
* Copyright (c) 1998 Rob Browning <rlb@cs.utexas.edu>
*/
/********************************************************************\
* 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 <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>
#include "table-allgui.h"
#include "table-gtk.h"
#include "combocell-gtk.h"
#include "combocell-gtkP.h"
/* Some GUI-private date that is inappropriate for
* the public interface. In this impelmentation,
* it holds gtk data that we need.
*/
#define SET(cell,str) { \
if ((cell)->value) free ((cell)->value); \
(cell)->value = strdup (str); \
(cell)->changed = 0xffffffff; \
}
typedef struct _PopBox {
GtkCombo *combobox;
GList *menustrings;
Table *table;
int currow;
int curcol;
} PopBox;
//static void selectCB (Widget w, XtPointer cd, XtPointer cb );
static void realizeCombo (BasicCell *bcell, void *w, int width);
static void moveCombo (BasicCell *bcell, int phys_row, int phys_col);
static void destroyCombo (BasicCell *bcell);
static void setComboValue (BasicCell *bcell, const char *value);
static const char * enterCombo (BasicCell *bcell, const char *value);
static const char * leaveCombo (BasicCell *bcell, const char *value);
/* =============================================== */
ComboCell *xaccMallocComboCell (void)
{
ComboCell * cell;
cell = (ComboCell *) malloc (sizeof (ComboCell));
xaccInitComboCell (cell);
return cell;
}
void xaccInitComboCell (ComboCell *cell)
{
xaccInitBasicCell ( &(cell->cell));
cell->cell.realize = realizeCombo;
cell->cell.set_value = setComboValue;
cell->cell.destroy = destroyCombo;
{
PopBox *box = (PopBox *) malloc (sizeof (PopBox));
box->table = NULL;
box->menustrings = NULL;
box->combobox = GTK_COMBO(gtk_combo_new());
gtk_widget_ref(GTK_WIDGET(box->combobox));
gtk_combo_set_value_in_list(box->combobox, 1, 0);
gtk_widget_show(GTK_WIDGET(box->combobox));
cell->cell.gui_private = box;
}
}
/* =============================================== */
static
void destroyCombo (BasicCell *bcell)
{
ComboCell *cell;
cell = (ComboCell *) bcell;
if (!(cell->cell.realize)) {
PopBox *box = (PopBox *) (cell->cell.gui_private);
gtk_container_remove(GTK_CONTAINER(box->table->entry_frame),
GTK_WIDGET(box->combobox));
gtk_container_add(GTK_CONTAINER(box->table->entry_frame),
GTK_WIDGET(box->table->entry_widget));
/* allow the widget to be shown again */
cell->cell.realize = realizeCombo;
cell->cell.move = NULL;
cell->cell.enter_cell = NULL;
cell->cell.leave_cell = NULL;
cell->cell.destroy = NULL;
}
}
/* =============================================== */
void xaccDestroyComboCell (ComboCell *cell)
{
PopBox *box = (PopBox *) (cell->cell.gui_private);
destroyCombo (&(cell->cell));
gtk_widget_destroy(GTK_WIDGET(box->combobox));
gtk_widget_unref(GTK_WIDGET(box->combobox));
g_list_foreach(box->menustrings, (GFunc) g_free, NULL);
g_list_free(box->menustrings);
free (box);
box = NULL;
cell->cell.gui_private = NULL;
cell->cell.realize = NULL;
cell->cell.set_value = NULL;
xaccDestroyBasicCell ( &(cell->cell));
}
/* =============================================== */
void
xaccAddComboCellMenuItem (ComboCell *cell, char * menustr)
{
PopBox *box = (PopBox *) cell->cell.gui_private;
GtkList *comboitems = GTK_LIST(box->combobox->list);
if (!cell) return;
if (!menustr) return;
box->menustrings = g_list_append(box->menustrings, g_strdup(menustr));
fprintf(stderr, "Adding item: %s\n", menustr);
gtk_combo_set_popdown_strings(box->combobox, box->menustrings);
}
/* =============================================== */
/* not only do we set the cell contents, but we
* make the gui reflect the right value too.
*/
void
xaccSetComboCellValue (ComboCell *cell, const char * str)
{
PopBox * box;
SET (&(cell->cell), str);
box = (PopBox *) (cell->cell.gui_private);
if(!str) str = "";
gtk_entry_set_text(GTK_ENTRY(box->combobox->entry), str);
}
/* =============================================== */
static void
setComboValue (BasicCell *_cell, const char *str)
{
ComboCell * cell = (ComboCell *) _cell;
xaccSetComboCellValue (cell, str);
}
/* =============================================== */
static
void realizeCombo (BasicCell *bcell, void *data, int pixel_width)
{
Table *table = (Table *) data;
ComboCell *cell = (ComboCell *) bcell;
PopBox *box = cell->cell.gui_private;
/* initialize gui-specific, private data */
box->table = table;
box->currow = -1;
box->curcol = -1;
/* to mark cell as realized, remove the realize method */
cell->cell.realize = NULL;
cell->cell.move = moveCombo;
cell->cell.enter_cell = enterCombo;
cell->cell.leave_cell = leaveCombo;
cell->cell.destroy = destroyCombo;
#if 0
/* add callbacks to detect a selection */
XtAddCallback (combobox, XmNselectionCallback, selectCB, (XtPointer)cell);
XtAddCallback (combobox, XmNunselectionCallback, selectCB, (XtPointer)cell);
#endif
}
/* =============================================== */
static
void moveCombo (BasicCell *bcell, int phys_row, int phys_col)
{
ComboCell *cell = (ComboCell *) bcell;
PopBox *box = cell->cell.gui_private;
box->currow = phys_row;
box->curcol = phys_col;
}
/* =============================================== */
static
const char * enterCombo (BasicCell *bcell, const char *value)
{
ComboCell *cell = (ComboCell *) bcell;
PopBox *box = (PopBox *) (cell->cell.gui_private);
int phys_row = box->currow;
int phys_col = box->curcol;
char *choice;
/* if the new position is valid, go to it,
* otherwise, unmanage the widget */
if ((0 <= phys_row) && (0 <= phys_col)) {
/* Get the current cell contents, and set the
* combobox menu selection to match the contents.
* We could use the value passed in, but things should
* be consitent, so we don't need it. */
choice = cell->cell.value;
if(!choice) choice = "";
if(GTK_WIDGET(box->table->entry_widget)->parent ==
box->table->entry_frame) {
gtk_container_remove(GTK_CONTAINER(box->table->entry_frame),
GTK_WIDGET(box->table->entry_widget));
}
gtk_container_add(GTK_CONTAINER(box->table->entry_frame),
GTK_WIDGET(box->combobox));
gtk_entry_set_text(GTK_ENTRY(box->combobox->entry), choice);
} else {
gtk_container_remove(GTK_CONTAINER(box->table->entry_frame),
GTK_WIDGET(box->combobox));
gtk_container_add(GTK_CONTAINER(box->table->entry_frame),
GTK_WIDGET(box->table->entry_widget));
}
return NULL;
}
/* =============================================== */
static
const char * leaveCombo (BasicCell *bcell, const char *value)
{
ComboCell *cell = (ComboCell *) bcell;
PopBox *box = (PopBox *) (cell->cell.gui_private);
gchar *text;
/* check for a valid mapping of the widget.
Note that if the combo box value is set to
a string that is not in the combo box menu
(for example, the empty string ""), then the
combobox will issue an XmCR_UNSELECT event.
This typically happens while loading the array.
We want to ignore these. */
if ((0 > box->currow) || (0 > box->curcol)) return NULL;
text = gtk_entry_get_text(GTK_ENTRY(box->combobox->entry));
/* be sure to set the string into the matrix widget as well,
so that we don't end up blanking out the cell when we
unmap the combobox widget */
gtk_clist_set_text(GTK_CLIST(box->table->table_widget),
box->currow - 1,
box->curcol,
text);
SET (&(cell->cell), text);
gtk_container_remove(GTK_CONTAINER(box->table->entry_frame),
GTK_WIDGET(box->combobox));
gtk_container_add(GTK_CONTAINER(box->table->entry_frame),
GTK_WIDGET(box->table->entry_widget));
return NULL;
}
/* =============================================== */
#if 0
static void selectCB (Widget w, XtPointer cd, XtPointer cb )
{
ComboCell *cell;
PopBox *box;
char * choice = 0x0;
XmComboBoxSelectionCallbackStruct *selection =
(XmComboBoxSelectionCallbackStruct *) cb;
cell = (ComboCell *) cd;
box = (PopBox *) (cell->cell.gui_private);
/* check for a valid mapping of the widget.
* Note that if the combo box value is set to
* a string that is not in the combo box menu
* (for example, the empty string ""), then the
* combobox will issue an XmCR_UNSELECT event.
* This typically happens while loading the array.
* We want to ignore these. */
if ((0 > box->currow) || (0 > box->curcol)) return;
/* check the reason, because the unslect callback
* doesn't even have a value field! */
if ( (XmCR_SINGLE_SELECT == selection->reason) ||
(XmCR_BROWSE_SELECT == selection->reason) ) {
choice = XmCvtXmStringToCT (selection->value);
if (!choice) choice = XtNewString (""); /* null if blank/unselect */
} else
if (XmCR_UNSELECT == selection->reason) {
choice = XtNewString ("");
} else {
return;
}
/* be sure to set the string into the matrix widget as well,
* so that we don't end up blanking out the cell when we
* unmap the combobox widget */
XbaeMatrixSetCell (box->parent, box->currow, box->curcol, choice);
SET (&(cell->cell), choice);
XtFree (choice);
/* a diffeent way of getting the user's selection ... */
/* text = XmComboBoxGetString (ab->combobox); */
}
#endif
/* =============== end of file =================== */
/*
* FILE:
* combocell.c
*
* FUNCTION:
* implement motif portions of a pull-down combo widget
* embedded in a table cell.
*
* HISTORY:
* Copyright (c) 1998 Linas Vepstas
* Copyright (c) 1998 Rob Browning <rlb@cs.utexas.edu>
*/
/********************************************************************\
* 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 <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>
#include "table-allgui.h"
#include "table-gtk.h"
#include "combocell-gtk.h"
#include "combocell-gtkP.h"
/* Some GUI-private date that is inappropriate for
* the public interface. In this impelmentation,
* it holds gtk data that we need.
*/
#define SET(cell,str) { \
if ((cell)->value) free ((cell)->value); \
(cell)->value = strdup (str); \
(cell)->changed = 0xffffffff; \
}
typedef struct _PopBox {
GtkCombo *combobox;
GList *menustrings;
Table *table;
int currow;
int curcol;
} PopBox;
//static void selectCB (Widget w, XtPointer cd, XtPointer cb );
static void realizeCombo (BasicCell *bcell, void *w, int width);
static void moveCombo (BasicCell *bcell, int phys_row, int phys_col);
static void destroyCombo (BasicCell *bcell);
static void setComboValue (BasicCell *bcell, const char *value);
static const char * enterCombo (BasicCell *bcell, const char *value);
static const char * leaveCombo (BasicCell *bcell, const char *value);
/* =============================================== */
ComboCell *xaccMallocComboCell (void)
{
ComboCell * cell;
cell = (ComboCell *) malloc (sizeof (ComboCell));
xaccInitComboCell (cell);
return cell;
}
void xaccInitComboCell (ComboCell *cell)
{
xaccInitBasicCell ( &(cell->cell));
cell->cell.realize = realizeCombo;
cell->cell.set_value = setComboValue;
cell->cell.destroy = destroyCombo;
{
PopBox *box = (PopBox *) malloc (sizeof (PopBox));
box->table = NULL;
box->menustrings = NULL;
box->combobox = GTK_COMBO(gtk_combo_new());
gtk_widget_ref(GTK_WIDGET(box->combobox));
gtk_combo_set_value_in_list(box->combobox, 1, 0);
gtk_widget_show(GTK_WIDGET(box->combobox));
cell->cell.gui_private = box;
}
}
/* =============================================== */
static
void destroyCombo (BasicCell *bcell)
{
ComboCell *cell;
cell = (ComboCell *) bcell;
if (!(cell->cell.realize)) {
PopBox *box = (PopBox *) (cell->cell.gui_private);
gtk_container_remove(GTK_CONTAINER(box->table->entry_frame),
GTK_WIDGET(box->combobox));
gtk_container_add(GTK_CONTAINER(box->table->entry_frame),
GTK_WIDGET(box->table->entry_widget));
/* allow the widget to be shown again */
cell->cell.realize = realizeCombo;
cell->cell.move = NULL;
cell->cell.enter_cell = NULL;
cell->cell.leave_cell = NULL;
cell->cell.destroy = NULL;
}
}
/* =============================================== */
void xaccDestroyComboCell (ComboCell *cell)
{
PopBox *box = (PopBox *) (cell->cell.gui_private);
destroyCombo (&(cell->cell));
gtk_widget_destroy(GTK_WIDGET(box->combobox));
gtk_widget_unref(GTK_WIDGET(box->combobox));
g_list_foreach(box->menustrings, (GFunc) g_free, NULL);
g_list_free(box->menustrings);
free (box);
box = NULL;
cell->cell.gui_private = NULL;
cell->cell.realize = NULL;
cell->cell.set_value = NULL;
xaccDestroyBasicCell ( &(cell->cell));
}
/* =============================================== */
void
xaccAddComboCellMenuItem (ComboCell *cell, char * menustr)
{
PopBox *box = (PopBox *) cell->cell.gui_private;
GtkList *comboitems = GTK_LIST(box->combobox->list);
if (!cell) return;
if (!menustr) return;
box->menustrings = g_list_append(box->menustrings, g_strdup(menustr));
fprintf(stderr, "Adding item: %s\n", menustr);
gtk_combo_set_popdown_strings(box->combobox, box->menustrings);
}
/* =============================================== */
/* not only do we set the cell contents, but we
* make the gui reflect the right value too.
*/
void
xaccSetComboCellValue (ComboCell *cell, const char * str)
{
PopBox * box;
SET (&(cell->cell), str);
box = (PopBox *) (cell->cell.gui_private);
if(!str) str = "";
gtk_entry_set_text(GTK_ENTRY(box->combobox->entry), str);
}
/* =============================================== */
static void
setComboValue (BasicCell *_cell, const char *str)
{
ComboCell * cell = (ComboCell *) _cell;
xaccSetComboCellValue (cell, str);
}
/* =============================================== */
static
void realizeCombo (BasicCell *bcell, void *data, int pixel_width)
{
Table *table = (Table *) data;
ComboCell *cell = (ComboCell *) bcell;
PopBox *box = cell->cell.gui_private;
/* initialize gui-specific, private data */
box->table = table;
box->currow = -1;
box->curcol = -1;
/* to mark cell as realized, remove the realize method */
cell->cell.realize = NULL;
cell->cell.move = moveCombo;
cell->cell.enter_cell = enterCombo;
cell->cell.leave_cell = leaveCombo;
cell->cell.destroy = destroyCombo;
#if 0
/* add callbacks to detect a selection */
XtAddCallback (combobox, XmNselectionCallback, selectCB, (XtPointer)cell);
XtAddCallback (combobox, XmNunselectionCallback, selectCB, (XtPointer)cell);
#endif
}
/* =============================================== */
static
void moveCombo (BasicCell *bcell, int phys_row, int phys_col)
{
ComboCell *cell = (ComboCell *) bcell;
PopBox *box = cell->cell.gui_private;
box->currow = phys_row;
box->curcol = phys_col;
}
/* =============================================== */
static
const char * enterCombo (BasicCell *bcell, const char *value)
{
ComboCell *cell = (ComboCell *) bcell;
PopBox *box = (PopBox *) (cell->cell.gui_private);
int phys_row = box->currow;
int phys_col = box->curcol;
char *choice;
/* if the new position is valid, go to it,
* otherwise, unmanage the widget */
if ((0 <= phys_row) && (0 <= phys_col)) {
/* Get the current cell contents, and set the
* combobox menu selection to match the contents.
* We could use the value passed in, but things should
* be consitent, so we don't need it. */
choice = cell->cell.value;
if(!choice) choice = "";
if(GTK_WIDGET(box->table->entry_widget)->parent ==
box->table->entry_frame) {
gtk_container_remove(GTK_CONTAINER(box->table->entry_frame),
GTK_WIDGET(box->table->entry_widget));
}
gtk_container_add(GTK_CONTAINER(box->table->entry_frame),
GTK_WIDGET(box->combobox));
gtk_entry_set_text(GTK_ENTRY(box->combobox->entry), choice);
} else {
gtk_container_remove(GTK_CONTAINER(box->table->entry_frame),
GTK_WIDGET(box->combobox));
gtk_container_add(GTK_CONTAINER(box->table->entry_frame),
GTK_WIDGET(box->table->entry_widget));
}
return NULL;
}
/* =============================================== */
static
const char * leaveCombo (BasicCell *bcell, const char *value)
{
ComboCell *cell = (ComboCell *) bcell;
PopBox *box = (PopBox *) (cell->cell.gui_private);
gchar *text;
/* check for a valid mapping of the widget.
Note that if the combo box value is set to
a string that is not in the combo box menu
(for example, the empty string ""), then the
combobox will issue an XmCR_UNSELECT event.
This typically happens while loading the array.
We want to ignore these. */
if ((0 > box->currow) || (0 > box->curcol)) return NULL;
text = gtk_entry_get_text(GTK_ENTRY(box->combobox->entry));
/* be sure to set the string into the matrix widget as well,
so that we don't end up blanking out the cell when we
unmap the combobox widget */
gtk_clist_set_text(GTK_CLIST(box->table->table_widget),
box->currow - 1,
box->curcol,
text);
SET (&(cell->cell), text);
gtk_container_remove(GTK_CONTAINER(box->table->entry_frame),
GTK_WIDGET(box->combobox));
gtk_container_add(GTK_CONTAINER(box->table->entry_frame),
GTK_WIDGET(box->table->entry_widget));
return NULL;
}
/* =============================================== */
#if 0
static void selectCB (Widget w, XtPointer cd, XtPointer cb )
{
ComboCell *cell;
PopBox *box;
char * choice = 0x0;
XmComboBoxSelectionCallbackStruct *selection =
(XmComboBoxSelectionCallbackStruct *) cb;
cell = (ComboCell *) cd;
box = (PopBox *) (cell->cell.gui_private);
/* check for a valid mapping of the widget.
* Note that if the combo box value is set to
* a string that is not in the combo box menu
* (for example, the empty string ""), then the
* combobox will issue an XmCR_UNSELECT event.
* This typically happens while loading the array.
* We want to ignore these. */
if ((0 > box->currow) || (0 > box->curcol)) return;
/* check the reason, because the unslect callback
* doesn't even have a value field! */
if ( (XmCR_SINGLE_SELECT == selection->reason) ||
(XmCR_BROWSE_SELECT == selection->reason) ) {
choice = XmCvtXmStringToCT (selection->value);
if (!choice) choice = XtNewString (""); /* null if blank/unselect */
} else
if (XmCR_UNSELECT == selection->reason) {
choice = XtNewString ("");
} else {
return;
}
/* be sure to set the string into the matrix widget as well,
* so that we don't end up blanking out the cell when we
* unmap the combobox widget */
XbaeMatrixSetCell (box->parent, box->currow, box->curcol, choice);
SET (&(cell->cell), choice);
XtFree (choice);
/* a diffeent way of getting the user's selection ... */
/* text = XmComboBoxGetString (ab->combobox); */
}
#endif
/* =============== end of file =================== */

View File

@ -0,0 +1,112 @@
/*
* FILE:
* combocell.h
*
* FUNCTION:
* The ComboCell object implements a cell handler with a
* "combination-box" pull-down menu in it.
*
* On output, the currently selected menu item is displayed.
* On input, the user can select from a list in the pull-down menu,
* or use the keyboard to slect a menu entry by typing the first
* few menu characters.
*
* METHODS:
* The xaccAddComboCellMenuItem() method can be used to add a menu
* item to the list.
*
*
* HISTORY:
* Created Jan 1998 Linas Vepstas
* Copyright (c) 1998 Linas Vepstas
*/
/********************************************************************\
* 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 __XACC_COMBO_CELL_H__
#define __XACC_COMBO_CELL_H__
#include "basiccell.h"
typedef struct _ComboCell ComboCell;
ComboCell * xaccMallocComboCell (void);
void xaccInitComboCell (ComboCell *);
void xaccDestroyComboCell (ComboCell *);
void xaccSetComboCellValue (ComboCell *, const char *);
void xaccAddComboCellMenuItem (ComboCell *, char * menustr);
#endif /* __XACC_COMBO_CELL_H__ */
/* --------------- end of file ---------------------- */
/*
* FILE:
* combocell.h
*
* FUNCTION:
* The ComboCell object implements a cell handler with a
* "combination-box" pull-down menu in it.
*
* On output, the currently selected menu item is displayed.
* On input, the user can select from a list in the pull-down menu,
* or use the keyboard to slect a menu entry by typing the first
* few menu characters.
*
* METHODS:
* The xaccAddComboCellMenuItem() method can be used to add a menu
* item to the list.
*
*
* HISTORY:
* Created Jan 1998 Linas Vepstas
* Copyright (c) 1998 Linas Vepstas
*/
/********************************************************************\
* 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 __XACC_COMBO_CELL_H__
#define __XACC_COMBO_CELL_H__
#include "basiccell.h"
typedef struct _ComboCell ComboCell;
ComboCell * xaccMallocComboCell (void);
void xaccInitComboCell (ComboCell *);
void xaccDestroyComboCell (ComboCell *);
void xaccSetComboCellValue (ComboCell *, const char *);
void xaccAddComboCellMenuItem (ComboCell *, char * menustr);
#endif /* __XACC_COMBO_CELL_H__ */
/* --------------- end of file ---------------------- */

View File

@ -0,0 +1,102 @@
/*
* FILE:
* combocell-gtkP.h
*
* FUNCTION:
* The ComboCell object implements a cell handler with a
* "combination-box" pull-down menu in it.
*
* On output, the currently selected menu item is displayed.
* On input, the user can select from a list in the pull-down menu,
* or use the keyboard to slect a menu entry by typing the first
* few menu characters.
*
* METHODS:
* The xaccAddComboCellMenuItem() method can be used to add a menu
* item to the list.
*
*
* HISTORY:
* Created Jan 1998 Linas Vepstas
* Copyright (c) 1998 Linas Vepstas
* Copyright (c) 1998 Rob Browning <rlb@cs.utexas.edu>
*/
/********************************************************************\
* 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 __XACC_COMBO_CELL_P_H__
#define __XACC_COMBO_CELL_P_H__
#include "basiccell.h"
struct _ComboCell {
BasicCell cell;
};
#endif /* __XACC_COMBO_CELL_P_H__ */
/* --------------- end of file ---------------------- */
/*
* FILE:
* combocell-gtkP.h
*
* FUNCTION:
* The ComboCell object implements a cell handler with a
* "combination-box" pull-down menu in it.
*
* On output, the currently selected menu item is displayed.
* On input, the user can select from a list in the pull-down menu,
* or use the keyboard to slect a menu entry by typing the first
* few menu characters.
*
* METHODS:
* The xaccAddComboCellMenuItem() method can be used to add a menu
* item to the list.
*
*
* HISTORY:
* Created Jan 1998 Linas Vepstas
* Copyright (c) 1998 Linas Vepstas
* Copyright (c) 1998 Rob Browning <rlb@cs.utexas.edu>
*/
/********************************************************************\
* 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 __XACC_COMBO_CELL_P_H__
#define __XACC_COMBO_CELL_P_H__
#include "basiccell.h"
struct _ComboCell {
BasicCell cell;
};
#endif /* __XACC_COMBO_CELL_P_H__ */
/* --------------- end of file ---------------------- */

View File

@ -30,11 +30,9 @@
#include <X11/keysym.h>
#ifdef MOTIF
#include <Xm/Xm.h>
#include <ComboBox.h>
#include <Xbae/Matrix.h>
#endif
#include "combocell.h"
@ -43,8 +41,6 @@
* it holds XtMotif data that we need.
*/
#ifdef MOTIF
typedef struct _PopBox {
Widget combobox;
Widget parent; /* the parent table widget */
@ -62,27 +58,12 @@ static void setComboValue (BasicCell *bcell, const char *value);
static const char * enterCombo (BasicCell *bcell, const char *value);
static const char * leaveCombo (BasicCell *bcell, const char *value);
#endif
#define SET(cell,str) { \
if ((cell)->value) free ((cell)->value); \
(cell)->value = strdup (str); \
(cell)->changed = 0xffffffff; \
}
#ifdef GNOME
typedef struct _PopBox {
int currow;
int curcol;
} PopBox;
void xaccDestroyComboCell (ComboCell *cell) { }
void xaccAddComboCellMenuItem (ComboCell *cell, char * menustr) {}
void xaccInitComboCell (ComboCell *cell) {}
#endif
/* =============================================== */
ComboCell *xaccMallocComboCell (void)
@ -93,8 +74,6 @@ ComboCell *xaccMallocComboCell (void)
return cell;
}
#ifndef GNOME
void xaccInitComboCell (ComboCell *cell)
{
xaccInitBasicCell ( &(cell->cell));
@ -207,8 +186,6 @@ xaccAddComboCellMenuItem (ComboCell *cell, char * menustr)
}
}
#endif
/* =============================================== */
/* not only do we set the cell contents, but we
* make the gui reflect the right value too.
@ -226,7 +203,6 @@ xaccSetComboCellValue (ComboCell *cell, const char * str)
* If so, then be sure to bail out now. */
if (!box) return;
#ifndef GNOME
if (str) {
if (0x0 != str[0]) {
XmString choosen;
@ -250,7 +226,6 @@ xaccSetComboCellValue (ComboCell *cell, const char * str)
XbaeMatrixSetCell (box->parent, box->currow, box->curcol, "");
}
}
#endif
}
/* =============================================== */
@ -262,8 +237,6 @@ setComboValue (BasicCell *_cell, const char *str)
xaccSetComboCellValue (cell, str);
}
#ifndef GNOME
/* =============================================== */
static
@ -547,6 +520,527 @@ static void dropDownCB (Widget w, XtPointer cd, XtPointer cb )
#endif /* USE_COMPLEX_TRAVERSAL_LOGIC */
}
#endif /* #ifndef GNOME */
/* =============== end of file =================== */
/*
* FILE:
* combocell.c
*
* FUNCTION:
* implement motif portions of a pull-down combo widget
* embedded in a table cell.
*
* HISTORY:
* Copyright (c) 1998 Linas Vepstas
*/
/********************************************************************\
* 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 <stdlib.h>
#include <string.h>
#include <X11/keysym.h>
#include <Xm/Xm.h>
#include <ComboBox.h>
#include <Xbae/Matrix.h>
#include "combocell.h"
/* Some GUI-private date that is inappropriate for
* the public interface. In this impelmentation,
* it holds XtMotif data that we need.
*/
typedef struct _PopBox {
Widget combobox;
Widget parent; /* the parent table widget */
int currow;
int curcol;
} PopBox;
static void selectCB (Widget w, XtPointer cd, XtPointer cb );
static void dropDownCB (Widget w, XtPointer cd, XtPointer cb );
static void realizeCombo (BasicCell *bcell, void *w, int width);
static void moveCombo (BasicCell *bcell, int phys_row, int phys_col);
static void destroyCombo (BasicCell *bcell);
static void setComboValue (BasicCell *bcell, const char *value);
static const char * enterCombo (BasicCell *bcell, const char *value);
static const char * leaveCombo (BasicCell *bcell, const char *value);
#define SET(cell,str) { \
if ((cell)->value) free ((cell)->value); \
(cell)->value = strdup (str); \
(cell)->changed = 0xffffffff; \
}
/* =============================================== */
ComboCell *xaccMallocComboCell (void)
{
ComboCell * cell;
cell = (ComboCell *) malloc (sizeof (ComboCell));
xaccInitComboCell (cell);
return cell;
}
void xaccInitComboCell (ComboCell *cell)
{
xaccInitBasicCell ( &(cell->cell));
cell->cell.realize = realizeCombo;
cell->cell.set_value = setComboValue;
cell->cell.destroy = destroyCombo;
cell->menuitems = (char **) malloc (sizeof (char *));
cell->menuitems[0] = NULL;
}
/* =============================================== */
static
void destroyCombo (BasicCell *bcell)
{
ComboCell *cell;
cell = (ComboCell *) bcell;
/* the realize callback will be null if the cell
* gui has been realized. Therefore, if its null,
* destroy the gui
*/
if (!(cell->cell.realize)) {
PopBox *box;
box = (PopBox *) (cell->cell.gui_private);
if (box) {
if (XtIsRealized(box->combobox)) {
moveCombo (bcell, -1, -1);
XtDestroyWidget (box->combobox);
}
free (box);
}
/* allow the widget to be created again */
cell->cell.gui_private = NULL;
cell->cell.realize = realizeCombo;
cell->cell.move = NULL;
cell->cell.enter_cell = NULL;
cell->cell.leave_cell = NULL;
cell->cell.destroy = NULL;
}
}
/* =============================================== */
void xaccDestroyComboCell (ComboCell *cell)
{
int n = 0;
char ** arr;
destroyCombo (&(cell->cell));
/* free malloced memory */
arr = cell->menuitems;
while (arr[n]) {
free (arr[n]);
n ++;
}
free (arr);
cell->menuitems = NULL;
cell->cell.realize = NULL;
cell->cell.set_value = NULL;
xaccDestroyBasicCell ( &(cell->cell));
}
/* =============================================== */
void
xaccAddComboCellMenuItem (ComboCell *cell, char * menustr)
{
int n = 0;
char ** oldarr;
if (!cell) return;
if (!menustr) return;
oldarr = cell->menuitems;
while (oldarr[n]) n ++;
cell->menuitems = (char **) malloc ((n+2) *sizeof (char *));
n = 0;
while (oldarr[n]) {
cell->menuitems[n] = oldarr[n];
n++;
}
cell->menuitems[n] = strdup (menustr);
cell->menuitems[n+1] = NULL;
free (oldarr);
/* if we are adding the menu item to a cell that
* is already realized, then alose add it to the
* widget directly.
*/
if (!cell->cell.realize) {
PopBox *box;
XmString str;
box = (PopBox *) cell->cell.gui_private;
str = XmStringCreateLtoR (menustr, XmSTRING_DEFAULT_CHARSET);
XmComboBoxAddItem (box->combobox, str, 0);
XmStringFree (str);
}
}
/* =============================================== */
/* not only do we set the cell contents, but we
* make the gui reflect the right value too.
*/
void
xaccSetComboCellValue (ComboCell *cell, const char * str)
{
PopBox * box;
SET (&(cell->cell), str);
box = (PopBox *) (cell->cell.gui_private);
/* we just might get called before the gui is initialized.
* If so, then be sure to bail out now. */
if (!box) return;
if (str) {
if (0x0 != str[0]) {
XmString choosen;
/* convert String to XmString ... arghhh */
choosen = XmCvtCTToXmString ((char *) str);
XmComboBoxSelectItem (box->combobox, choosen, False);
XmStringFree (choosen);
} else {
XmComboBoxClearItemSelection (box->combobox);
}
if ((0 < box->currow) && (0 < box->curcol)) {
/* be sure to set the string into the matrix widget as well,
* so that we don't end up blanking out the cell when we
* unmap the combobox widget */
XbaeMatrixSetCell (box->parent, box->currow, box->curcol, (char *) str);
}
} else {
XmComboBoxClearItemSelection (box->combobox);
if ((0 < box->currow) && (0 < box->curcol)) {
XbaeMatrixSetCell (box->parent, box->currow, box->curcol, "");
}
}
}
/* =============================================== */
static void
setComboValue (BasicCell *_cell, const char *str)
{
ComboCell * cell = (ComboCell *) _cell;
xaccSetComboCellValue (cell, str);
}
/* =============================================== */
static
void realizeCombo (BasicCell *bcell, void *w, int pixel_width)
{
ComboCell *cell;
PopBox *box;
Widget parent;
Widget combobox;
int width, drop_width;
parent = (Widget) w;
cell = (ComboCell *) bcell;
/* initialize gui-specific, private data */
box = (PopBox *) malloc (sizeof (PopBox));
box->parent = parent;
box->currow = -1;
box->curcol = -1;
cell->cell.gui_private = (void *) box;
/* to mark cell as realized, remove the realize method */
cell->cell.realize = NULL;
cell->cell.move = moveCombo;
cell->cell.enter_cell = enterCombo;
cell->cell.leave_cell = leaveCombo;
cell->cell.destroy = destroyCombo;
/* the combobox wants width in pixels, not in chars.
* It would be nice if ComboBox supported the XmNunits
* resource, but it doesn't. Also, while we are at it,
* increase the size of the drop-down box as well.
*/
width = pixel_width;
drop_width = (int) (1.3 * ((float) width));
if (15 > drop_width) drop_width = 15;
/* create the pop GUI */
combobox = XtVaCreateManagedWidget
("combocell", xmComboBoxWidgetClass, parent,
XmNshadowThickness, 0, /* don't draw a shadow,
* use bae shadows */
XmNeditable, False, /* user can only pick from list */
XmNsorted, False,
XmNshowLabel, False,
XmNmarginHeight, 0,
XmNmarginWidth, 0,
XmNselectionPolicy, XmSINGLE_SELECT,
XmNvalue, "",
XmNwidth, width,
XmNdropDownWidth, drop_width,
NULL);
box->combobox = combobox;
/* add callbacks to detect a selection */
XtAddCallback (combobox, XmNselectionCallback, selectCB, (XtPointer)cell);
XtAddCallback (combobox, XmNunselectionCallback, selectCB, (XtPointer)cell);
XtAddCallback (combobox, XmNdropDownCallback, dropDownCB, (XtPointer)box);
/* unmap the widget by moving it to an invlid location */
moveCombo (bcell, -1, -1);
/* add menu items */
if (cell->menuitems) {
char * menustr;
int i=0;
menustr = cell->menuitems[i];
while (menustr) {
XmString str;
str = XmStringCreateLtoR (menustr, XmSTRING_DEFAULT_CHARSET);
XmComboBoxAddItem (box->combobox, str, 0);
XmStringFree (str);
i++;
menustr = cell->menuitems[i];
}
}
}
/* =============================================== */
static
void moveCombo (BasicCell *bcell, int phys_row, int phys_col)
{
ComboCell *cell;
PopBox *box;
cell = (ComboCell *) bcell;
box = (PopBox *) (cell->cell.gui_private);
/* if the drop-down menu is showing, hide it now */
XmComboBoxHideList (box->combobox);
/* if there is an old widget, remove it */
if ((0 <= box->currow) && (0 <= box->curcol)) {
XbaeMatrixSetCellWidget (box->parent, box->currow, box->curcol, NULL);
}
box->currow = phys_row;
box->curcol = phys_col;
XtUnmanageChild (box->combobox);
}
/* =============================================== */
static
const char * enterCombo (BasicCell *bcell, const char *value)
{
int phys_row, phys_col;
String choice;
XmString choosen;
ComboCell *cell;
PopBox *box;
cell = (ComboCell *) bcell;
box = (PopBox *) (cell->cell.gui_private);
phys_row = box->currow;
phys_col = box->curcol;
/* if the new position is valid, go to it,
* otherwise, unmanage the widget */
if ((0 <= phys_row) && (0 <= phys_col)) {
/* Get the current cell contents, and set the
* combobox menu selection to match the contents.
* We could use the value passed in, but things should
* be consitent, so we don't need it. */
choice = cell->cell.value;
/* do a menu selection only if the cell ain't empty. */
if (choice) {
if (0x0 != choice[0]) {
/* convert String to XmString ... arghhh */
choosen = XmCvtCTToXmString (choice);
XmComboBoxSelectItem (box->combobox, choosen, False);
XmStringFree (choosen);
} else {
XmComboBoxClearItemSelection (box->combobox);
}
} else {
XmComboBoxClearItemSelection (box->combobox);
}
/* set the cell widget */
XbaeMatrixSetCellWidget (box->parent, phys_row, phys_col, box->combobox);
if (!XtIsManaged (box->combobox)) {
XtManageChild (box->combobox);
}
/* drop down the menu so that its ready to go. */
XmComboBoxShowList (box->combobox);
} else {
XtUnmanageChild (box->combobox);
}
return NULL;
}
/* =============================================== */
static
const char * leaveCombo (BasicCell *bcell, const char *value)
{
ComboCell *cell;
PopBox *box;
cell = (ComboCell *) bcell;
box = (PopBox *) (cell->cell.gui_private);
/* if the drop-down menu is showing, hide it now */
XmComboBoxHideList (box->combobox);
/* if there is an old widget, remove it */
if ((0 <= box->currow) && (0 <= box->curcol)) {
XbaeMatrixSetCellWidget (box->parent, box->currow, box->curcol, NULL);
}
XtUnmanageChild (box->combobox);
return NULL;
}
/* =============================================== */
static void selectCB (Widget w, XtPointer cd, XtPointer cb )
{
ComboCell *cell;
PopBox *box;
char * choice = 0x0;
XmComboBoxSelectionCallbackStruct *selection =
(XmComboBoxSelectionCallbackStruct *) cb;
cell = (ComboCell *) cd;
box = (PopBox *) (cell->cell.gui_private);
/* check for a valid mapping of the widget.
* Note that if the combo box value is set to
* a string that is not in the combo box menu
* (for example, the empty string ""), then the
* combobox will issue an XmCR_UNSELECT event.
* This typically happens while loading the array.
* We want to ignore these. */
if ((0 > box->currow) || (0 > box->curcol)) return;
/* check the reason, because the unslect callback
* doesn't even have a value field! */
if ( (XmCR_SINGLE_SELECT == selection->reason) ||
(XmCR_BROWSE_SELECT == selection->reason) ) {
choice = XmCvtXmStringToCT (selection->value);
if (!choice) choice = XtNewString (""); /* null if blank/unselect */
} else
if (XmCR_UNSELECT == selection->reason) {
choice = XtNewString ("");
} else {
return;
}
/* be sure to set the string into the matrix widget as well,
* so that we don't end up blanking out the cell when we
* unmap the combobox widget */
XbaeMatrixSetCell (box->parent, box->currow, box->curcol, choice);
SET (&(cell->cell), choice);
XtFree (choice);
/* a diffeent way of getting the user's selection ... */
/* text = XmComboBoxGetString (ab->combobox); */
}
/* =============================================== */
/*********************************************************\
* fix traversal by going back to the register window
* when the pull-down menu goes away. We do NOT want to
* go to the default next tab group, which is probably
* some button not in the register window.
\*********************************************************/
static void dropDownCB (Widget w, XtPointer cd, XtPointer cb )
{
PopBox *ab = (PopBox *) cd;
XmComboBoxDropDownCallbackStruct *ddcb =
(XmComboBoxDropDownCallbackStruct *) cb;
if (XmCR_HIDE_LIST == ddcb->reason) {
XmProcessTraversal(ab->parent, XmTRAVERSE_CURRENT);
}
#ifdef USE_COMPLEX_TRAVERSAL_LOGIC
/* continue traversal only under certain special curcumstances */
if (XmCR_HIDE_LIST == ddcb->reason) {
if (ddcb->event) {
/* don't leave if only a focus-out */
if (FocusOut == ddcb->event->type) {
XmProcessTraversal(ab->combobox, XmTRAVERSE_CURRENT);
} else
/* if user selected something, then go to next cell */
if (ButtonRelease == ddcb->event->type) {
XmProcessTraversal(ab->reg, XmTRAVERSE_CURRENT);
} else
/* if user hit the tab key, go to next cell */
if ((KeyPress == ddcb->event->type) || (KeyRelease == ddcb->event->type
)) {
KeySym sim;
XKeyEvent *kev = (XKeyEvent *) ddcb->event;
sim = XLookupKeysym (kev, 0);
if (XK_Tab == sim) { /* did the user hit the tab key ?? */
XmProcessTraversal(ab->reg, XmTRAVERSE_CURRENT);
}
}
}
}
#endif /* USE_COMPLEX_TRAVERSAL_LOGIC */
}
/* =============== end of file =================== */

View File

@ -57,3 +57,62 @@ void xaccAddComboCellMenuItem (ComboCell *, char * menustr);
#endif /* __XACC_COMBO_CELL_C__ */
/* --------------- end of file ---------------------- */
/*
* FILE:
* combocell.h
*
* FUNCTION:
* The ComboCell object implements a cell handler with a
* "combination-box" pull-down menu in it.
*
* On output, the currently selected menu item is displayed.
* On input, the user can select from a list in the pull-down menu,
* or use the keyboard to slect a menu entry by typing the first
* few menu characters.
*
* METHODS:
* The xaccAddComboCellMenuItem() method can be used to add a menu
* item to the list.
*
*
* HISTORY:
* Created Jan 1998 Linas Vepstas
* Copyright (c) 1998 Linas Vepstas
*/
/********************************************************************\
* 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 __XACC_COMBO_CELL_C__
#define __XACC_COMBO_CELL_C__
#include "basiccell.h"
typedef struct _ComboCell {
BasicCell cell;
char ** menuitems;
} ComboCell;
ComboCell * xaccMallocComboCell (void);
void xaccInitComboCell (ComboCell *);
void xaccDestroyComboCell (ComboCell *);
void xaccSetComboCellValue (ComboCell *, const char *);
void xaccAddComboCellMenuItem (ComboCell *, char * menustr);
#endif /* __XACC_COMBO_CELL_C__ */
/* --------------- end of file ---------------------- */

View File

@ -0,0 +1,103 @@
/* XPM */
static char * left_arrow_small_xpm[] = {
"13 14 86 1",
" c None",
". c #AC9B8E",
"+ c #8D5C3F",
"@ c #A26A47",
"# c #8F603E",
"$ c #432214",
"% c #8A4629",
"& c #9E5A39",
"* c #B6754F",
"= c #8A5D42",
"- c #974F31",
"; c #A85D3A",
"> c #AC603F",
", c #B36D48",
"' c #BA7A56",
") c #684937",
"! c #975135",
"~ c #B66C48",
"{ c #C57653",
"] c #C27552",
"^ c #C37650",
"/ c #CB805C",
"( c #C58664",
"_ c #8F5036",
": c #BE704D",
"< c #CE825B",
"[ c #D38560",
"} c #D58761",
"| c #D58862",
"1 c #D78A63",
"2 c #DE9471",
"3 c #C98F73",
"4 c #7F5846",
"5 c #9D6F58",
"6 c #C97B56",
"7 c #D88A65",
"8 c #DB8D67",
"9 c #E19069",
"0 c #E3946D",
"a c #EA9B75",
"b c #EBA47F",
"c c #E59A75",
"d c #AD6B4E",
"e c #7D4E3A",
"f c #E3B29A",
"g c #D68963",
"h c #E1916C",
"i c #E79870",
"j c #EA9E79",
"k c #F0A682",
"l c #E7A37F",
"m c #BD7656",
"n c #693924",
"o c #26170F",
"p c #040302",
"q c #000000",
"r c #E7B097",
"s c #E3936A",
"t c #ECA179",
"u c #EFA781",
"v c #EA9F7C",
"w c #C77E5E",
"x c #7E4833",
"y c #3C2118",
"z c #0B0604",
"A c #E9AC90",
"B c #EEA47F",
"C c #EBA27D",
"D c #BF7859",
"E c #844830",
"F c #402318",
"G c #130B07",
"H c #B09488",
"I c #EFA685",
"J c #CE8361",
"K c #87462F",
"L c #3C1F13",
"M c #0F0805",
"N c #E5BAA8",
"O c #9F5E43",
"P c #4F271B",
"Q c #170D09",
"R c #020100",
"S c #684A3D",
"T c #1B0F0A",
"U c #050302",
". ",
"+@# ",
"$%&*= ",
" -;>,') ",
" !~{]^/( ",
" _:<[}|1234 ",
" 567890abcde ",
" fghijklmnopq",
" rstuvwxyzqq ",
" ABCDEFGqq ",
"HIJKLMqq ",
"NOPQRq ",
"STUq ",
" q "};

View File

@ -37,16 +37,18 @@
#define __XACC_REGISTER_H__
#include "basiccell.h"
#include "combocell.h"
#include "datecell.h"
#include "quickfillcell.h"
#include "pricecell.h"
#ifdef MOTIF
#include "combocell-motif.h"
#include "table-motif.h"
#endif
#ifdef GNOME
#include "combocell-gtk.h"
#include "combocell-gtkP.h"
#include "table-gtk.h"
#endif
@ -91,7 +93,7 @@ struct _BasicRegister {
/* the table itself that implements the underlying GUI. */
Table * table;
/* the cursors that define thecurrently edited row */
/* the cursors that define the currently edited row */
CellBlock * cursor;
CellBlock * header;

View File

@ -27,9 +27,18 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
\********************************************************************/
/*
TODO:
Everywhere I use row + 1, it should be row + num_header_rows
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <gtk/gtk.h>
#include "cellblock.h"
@ -37,10 +46,6 @@
#include "table-gtk.h"
#if 0
static void enterCB (GtkWidget * mw, gpointer cd, gpointer cb);
static void leaveCB (GtkWidget * mw, gpointer cd, gpointer cb);
static void modifyCB (GtkWidget * mw, gpointer cd, gpointer cb);
static void traverseCB (GtkWidget * mw, gpointer cd, gpointer cb);
/* The XrmQuarks are used to figure out the direction of
* traversal from cell to cell */
@ -66,7 +71,14 @@ xaccMallocTable (void)
void
xaccInitTable (Table * table)
{
table->table_widget = 0;
table->table_widget = NULL;
table->entry_frame = NULL;
table->entry_widget = NULL;
table->current_col = -1; /* coords ignoring header lines */
table->current_row = -1;
table->prev_entry_text = NULL;
table->next_tab_group = 0;
table->num_phys_rows = -1;
@ -102,7 +114,14 @@ xaccDestroyTable (Table * table)
xaccFreeTableEntries (table);
/* Let GTK know we're finished with this */
gtk_widget_unref(table->table_widget);
if(table->table_widget) gtk_widget_unref(table->table_widget);
if(table->entry_frame) gtk_widget_unref(table->entry_frame);
if(table->entry_widget) gtk_widget_unref(table->entry_widget);
table->table_widget = NULL;
table->entry_frame = NULL;
table->entry_widget = NULL;
g_free(table->prev_entry_text); table->prev_entry_text = NULL;
/* intialize vars to null value so that any access is voided. */
xaccInitTable (table);
@ -140,107 +159,40 @@ xaccNextTabGroup (Table *table, GtkWidget * w)
table->next_tab_group = w;
}
#if 0
/* ==================================================== */
/* this routine calls the individual cell callbacks */
/* hack alert -- assumes that header is first cell */
static void
cellCB (GtkWidget *mw, gpointer cd, gpointer cb)
static int
verify_cell_interaction_OK(Table *table, const int row, const int col)
{
Table *table;
XbaeMatrixDefaultActionCallbackStruct *cbs;
int row, col;
int rel_row, rel_col;
CellBlock *arr, *header;
int invalid = 0;
table = (Table *) cd;
arr = table->current_cursor;
cbs = (XbaeMatrixDefaultActionCallbackStruct *) cb;
row = cbs->row;
col = cbs->column;
/* can't edit outside of the physical space */
invalid = (0 > row) || (0 > col) ;
invalid = invalid || (row >= table->num_phys_rows);
invalid = invalid || (col >= table->num_phys_cols);
/* header rows cannot be modified */
header = table->handlers[0][0];
invalid = invalid || (row < header->numRows);
/* compute the cell location */
rel_row = table->locators[row][col]->phys_row_offset;
rel_col = table->locators[row][col]->phys_col_offset;
/* check for a cell handler, but only if cell adress is valid */
if (arr && !invalid) {
if (! (arr->cells[rel_row][rel_col])) {
invalid = TRUE;
} else {
/* if cell is marked as output-only,
* then don't call callbacks */
if (0 == (arr->cells[rel_row][rel_col])->input_output) {
invalid = TRUE;
}
}
} else {
/* This was cellCB in a previous (Motif) life. We don't do nearly
the checking that the Xbae code did because we presume that the
row/column has to be valid if the user could have clicked on it.
That's reasonable given the way that CList works. For one thing,
header rows are handled separately. */
const CellBlock *arr = table->current_cursor;
int rel_row, rel_col;
int invalid = 0;
/* compute the cell location */
rel_row = table->locators[row][col]->phys_row_offset;
rel_col = table->locators[row][col]->phys_col_offset;
/* check for a cell handler, but only if cell adress is valid */
/* GTK may not need all these checks, but they don't hurt */
if (arr && !invalid) {
if (! (arr->cells[rel_row][rel_col])) {
invalid = TRUE;
}
} else {
/* if cell is marked as output-only,
* then don't call callbacks */
if (0 == (arr->cells[rel_row][rel_col])->input_output) {
invalid = TRUE;
}
}
} else {
invalid = TRUE;
}
/* oops the callback failed for some reason ...
* reject the enter/edit/leave and return */
if (invalid) {
switch (cbs->reason) {
case XbaeEnterCellReason: {
XbaeMatrixEnterCellCallbackStruct *ecbs;
ecbs = (XbaeMatrixEnterCellCallbackStruct *) cbs;
ecbs->doit = False;
ecbs->map = False;
break;
}
case XbaeModifyVerifyReason: {
XbaeMatrixModifyVerifyCallbackStruct *mvcbs;
mvcbs = (XbaeMatrixModifyVerifyCallbackStruct *) cbs;
mvcbs->verify->doit = False;
break;
}
case XbaeLeaveCellReason: {
XbaeMatrixLeaveCellCallbackStruct *lcbs;
lcbs = (XbaeMatrixLeaveCellCallbackStruct *) cbs;
/* must set doit to true in order to be able to leave the cell */
lcbs->doit = True;
break;
}
default:
break;
}
return;
}
/* if we got to here, then there is a cell handler for
* this cell. Dispatch for processing. */
switch (cbs->reason) {
case XbaeEnterCellReason: {
xaccVerifyCursorPosition (table, row, col);
enterCB (mw, cd, cb);
break;
}
case XbaeModifyVerifyReason: {
modifyCB (mw, cd, cb);
break;
}
case XbaeLeaveCellReason: {
leaveCB (mw, cd, cb);
break;
}
default:
break;
}
return(!invalid);
}
/* ==================================================== */
@ -248,217 +200,285 @@ cellCB (GtkWidget *mw, gpointer cd, gpointer cb)
* been performed. */
static void
enterCB (GtkWidget * mw, gpointer cd, gpointer cb)
cell_entered(Table *table, const int row, const int col)
{
Table *table;
CellBlock *arr;
XbaeMatrixEnterCellCallbackStruct *cbs;
int row, col;
int rel_row, rel_col;
const char * (*enter) (BasicCell *, const char *);
CellBlock *arr;
int rel_row, rel_col;
const char * (*enter) (BasicCell *, const char *);
gchar *text;
GtkCList *cl = GTK_CLIST(table->table_widget);
fprintf(stderr, "cell_entered: %d %d\n", row - 1, col);
gtk_clist_get_text(cl, row - 1, col, &text);
text = g_strdup(text); /* This is OK and required b/c GTK kills the
old pointer before using the one you
give it. */
{
GtkWidget *w = GTK_WIDGET(cl);
GdkColor *background = &w->style->bg[GTK_STATE_NORMAL];
GdkBitmap *mask;
GdkPixmap *pm = gdk_pixmap_create_from_xpm(w->window, &mask, background,
"/home/rlb/xacc/src/register/"
"left_arrow_small.xpm");
gtk_clist_set_pixtext(cl, row - 1, col, text, 2, pm, mask);
gdk_pixmap_unref(pm);
gdk_bitmap_unref(mask);
}
gtk_frame_set_label(GTK_FRAME(table->entry_frame),
cl->column[col].title);
table = (Table *) cd;
/* Have to block and unblock here because we don't want a callback
for this "edit" */
{
const guint handler_id =
(guint) gtk_object_get_user_data(GTK_OBJECT(table->entry_widget));
gtk_signal_handler_block(GTK_OBJECT(table->entry_widget), handler_id);
gtk_entry_set_text(GTK_ENTRY(table->entry_widget), text);
gtk_signal_handler_unblock(GTK_OBJECT(table->entry_widget), handler_id);
}
g_free(table->prev_entry_text);
table->prev_entry_text = text;
fprintf(stderr,
" current_cursor->phys: %d %d\n"
" current_cursor->virt: %d %d\n"
" text: %s\n",
table->current_cursor_phys_row,
table->current_cursor_phys_col,
table->current_cursor_virt_row,
table->current_cursor_virt_col,
text);
xaccVerifyCursorPosition (table, row, col);
arr = table->current_cursor;
cbs = (XbaeMatrixEnterCellCallbackStruct *) cb;
/* compute the cell location */
row = cbs->row;
col = cbs->column;
rel_row = table->locators[row][col]->phys_row_offset;
rel_col = table->locators[row][col]->phys_col_offset;
printf ("enter %d %d \n", row, col);
/* since we are here, there must be a cell handler.
* therefore, we accept entry into the cell by default,
*/
cbs->doit = True;
cbs->map = True;
/* OK, if there is a callback for this cell, call it */
enter = arr->cells[rel_row][rel_col]->enter_cell;
if (enter) {
const char *val;
char *retval;
val = table->entries[row][col];
retval = (char *) enter (arr->cells[rel_row][rel_col], val);
if (NULL == retval) retval = (char *) val;
if (val != retval) {
if (table->entries[row][col]) free (table->entries[row][col]);
table->entries[row][col] = retval;
(arr->cells[rel_row][rel_col])->changed = 0xffffffff;
XbaeMatrixSetCell (mw, row, col, retval);
XbaeMatrixRefreshCell (mw, row, col);
/* don't map a text widget */
cbs->map = False;
cbs->doit = False;
}
const char *val;
char *retval;
val = table->entries[row][col];
retval = (char *) enter (arr->cells[rel_row][rel_col], val);
if (NULL == retval) retval = (char *) val;
if (val != retval) {
if (table->entries[row][col]) free (table->entries[row][col]);
table->entries[row][col] = retval;
(arr->cells[rel_row][rel_col])->changed = 0xffffffff;
/* ??? Should this be setting the entry or the clist cell? */
gtk_entry_set_text(GTK_ENTRY(table->entry_widget), retval);
}
}
/* record this position as the cell that will be
* traversed out of if a traverse even happens */
table->prev_phys_traverse_row = row;
table->prev_phys_traverse_col = col;
}
static void
compute_string_single_change(const gchar *a, const gchar *b, gchar **result) {
/* Compute the change from a to b assuming that the changed region
is contiguous. This is only a guess, the solution is
ambiguous. */
const gint a_len = strlen(a);
const gint b_len = strlen(b);
const gchar *afptr = a, *bfptr = b;
const gchar *arptr = a + a_len;
const gchar *brptr = b + b_len;
while(*afptr && *bfptr && (*afptr == *bfptr)) {
afptr++;
bfptr++;
}
while((arptr != afptr) && (brptr != bfptr) && (*arptr == *brptr)) {
arptr--;
brptr--;
}
if(a_len == b_len) brptr++;
if(bfptr == brptr) {
/* deletion or nothing */
*result = NULL;
return;
} else {
const gint length = (brptr - bfptr);
*result = (char *) g_malloc(length * sizeof(char) + 1);
strncpy(*result, bfptr, length);
(*result)[length] = '\0';
return;
}
}
/* ==================================================== */
/* this routine calls the individual cell callbacks */
static void
modifyCB (GtkWidget * mw, gpointer cd, gpointer cb)
cell_modified(Table *table, const int row, const int col)
{
Table *table;
CellBlock *arr;
XbaeMatrixModifyVerifyCallbackStruct *cbs;
int row, col;
int rel_row, rel_col;
const char * (*mv) (BasicCell *,
const char *,
const char *,
const char *);
const char *oldval, *change;
char *newval;
const char *retval;
int len;
table = (Table *) cd;
arr = table->current_cursor;
cbs = (XbaeMatrixModifyVerifyCallbackStruct *) cb;
CellBlock *arr;
GtkEntry *entry = GTK_ENTRY(table->entry_widget);
int rel_row, rel_col;
const char * (*mv) (BasicCell *,
const char *,
const char *,
const char *);
const char *oldval, *newval, *retval, *final_text;
gchar *change = NULL;
/* compute the cell location */
row = cbs->row;
col = cbs->column;
rel_row = table->locators[row][col]->phys_row_offset;
rel_col = table->locators[row][col]->phys_col_offset;
arr = table->current_cursor;
/* compute the cell location */
rel_row = table->locators[row][col]->phys_row_offset;
rel_col = table->locators[row][col]->phys_col_offset;
/* accept edits by default, unless the cell handler rejects them */
/* cbs->verify->doit = True; */
oldval = table->prev_entry_text;
newval = strdup(gtk_entry_get_text(entry));
final_text = newval;
if(oldval) compute_string_single_change(oldval, newval, &change);
/* accept edits by default, unless the cell handler rejects them */
cbs->verify->doit = True;
fprintf(stderr, " CHANGES: (%s -> %s) <=> [%s]\n",
oldval, newval, change);
if(strcmp(newval, oldval) == 0) {
g_free((gchar *) change);
return;
}
oldval = cbs->prev_text;
change = cbs->verify->text->ptr;
/* OK, if there is a callback for this cell, call it */
mv = arr->cells[rel_row][rel_col]->modify_verify;
/* first, compute the newval string */
len = 1;
if (oldval) len += strlen (oldval);
if (change) len += strlen (change);
newval = (char *) malloc (len);
/* text may be inserted, or deleted, or replaced ... */
newval[0] = 0;
strncat (newval, oldval, cbs->verify->startPos);
if (change) strcat (newval, change);
strcat (newval, &oldval[(cbs->verify->endPos)]);
/* OK, if there is a callback for this cell, call it */
mv = arr->cells[rel_row][rel_col]->modify_verify;
if (mv) {
retval = (*mv) (arr->cells[rel_row][rel_col], oldval, change, newval);
/* if the callback returned a non-null value, allow the edit */
if (retval) {
/* update data. bounds check done earlier */
free (table->entries[row][col]);
table->entries[row][col] = (char *) retval;
(arr->cells[rel_row][rel_col])->changed = 0xffffffff;
/* if the callback modified the display string,
* update the display cell as well */
if (retval != newval) {
XbaeMatrixSetCell (mw, row, col, (char *) retval);
XbaeMatrixRefreshCell (mw, row, col);
XbaeMatrixSetCursorPosition (mw, (cbs->verify->endPos) +1);
/* the default update has already been overridden,
* so don't allow Xbae to update */
cbs->verify->doit = False;
/* avoid wasting memory */
free (newval);
}
} else {
/* NULL return value means the edit was rejected */
cbs->verify->doit = False;
/* avoid wasting memory */
free(newval);
}
} else {
if (mv) {
retval = (*mv) (arr->cells[rel_row][rel_col], oldval, change, newval);
/* if the callback returned a non-null value, allow the edit */
if (retval) {
/* update data. bounds check done earlier */
free (table->entries[row][col]);
table->entries[row][col] = newval;
table->entries[row][col] = (char *) retval;
(arr->cells[rel_row][rel_col])->changed = 0xffffffff;
}
/* if the callback modified the display string,
* update the display cell as well */
if (retval != newval) {
{
/* Don't want a signal for this change */
const guint id =
(guint) gtk_object_get_user_data(GTK_OBJECT(table->entry_widget));
gtk_signal_handler_block(GTK_OBJECT(table->entry_widget), id);
gtk_entry_set_text(entry, retval);
gtk_signal_handler_unblock(GTK_OBJECT(table->entry_widget), id);
}
final_text = retval;
/*XbaeMatrixSetCursorPosition (mw, (cbs->verify->endPos) +1);*/
free((char *) newval);
}
} else {
free((char *) newval);
}
} else {
/* update data. bounds check done earlier */
free (table->entries[row][col]);
table->entries[row][col] = strdup(newval);
(arr->cells[rel_row][rel_col])->changed = 0xffffffff;
}
g_free(table->prev_entry_text);
table->prev_entry_text = g_strdup(final_text);
g_free((gchar *) change);
}
/* ==================================================== */
static void
leaveCB (GtkWidget * mw, gpointer cd, gpointer cb)
cell_left(Table *table, const int row, const int col)
{
Table *table;
CellBlock *arr;
XbaeMatrixLeaveCellCallbackStruct *cbs;
int row, col;
int rel_row, rel_col;
const char * (*leave) (BasicCell *, const char *);
char * newval;
CellBlock *arr;
int rel_row, rel_col;
const char * (*leave) (BasicCell *, const char *);
char * newval;
const char *val;
gchar *text;
GdkBitmap *mask;
GtkCList *cl = GTK_CLIST(table->table_widget);
table = (Table *) cd;
arr = table->current_cursor;
cbs = (XbaeMatrixLeaveCellCallbackStruct *) cb;
fprintf(stderr, "cell_left: %d %d\n", row - 1, col);
/* compute the cell location */
row = cbs->row;
col = cbs->column;
rel_row = table->locators[row][col]->phys_row_offset;
rel_col = table->locators[row][col]->phys_col_offset;
if(gtk_clist_get_pixtext(cl, row - 1, col, &text, NULL, NULL, &mask)) {
/* we need to get rid of the pixmap -- this will only fail on the
first click when there was no previous cell (but we default to
0 0) */
text = g_strdup(text); /* This is OK and required b/c we're about to
kill this pointer via set_text. */
gtk_clist_set_text(cl, row - 1, col, text);
g_free(text);
}
arr = table->current_cursor;
/* compute the cell location */
rel_row = table->locators[row][col]->phys_row_offset;
rel_col = table->locators[row][col]->phys_col_offset;
printf ("leave %d %d \n", row, col);
val = gtk_entry_get_text(GTK_ENTRY(table->entry_widget));
/* OK, if there is a callback for this cell, call it */
leave = arr->cells[rel_row][rel_col]->leave_cell;
if (leave) {
const char *retval;
retval = leave (arr->cells[rel_row][rel_col], val);
newval = (char *) retval;
if (NULL == retval) newval = strdup (val);
if (val == retval) newval = strdup (val);
/* if the leave() routine declared a new string, lets use it */
if ( retval && (retval != val)) {
gtk_clist_set_text(cl, row - 1, col, (gchar *) retval);
}
} else {
newval = strdup(val);
}
/* by default, accept whatever the final proposed edit is */
cbs->doit = True;
/* OK, if there is a callback for this cell, call it */
leave = arr->cells[rel_row][rel_col]->leave_cell;
if (leave) {
const char *val, *retval;
val = cbs->value;
retval = leave (arr->cells[rel_row][rel_col], val);
newval = (char *) retval;
if (NULL == retval) newval = strdup (val);
if (val == retval) newval = strdup (val);
/* if the leave() routine declared a new string, lets use it */
if ( retval && (retval != val)) {
cbs->value = strdup (retval);
}
} else {
newval = strdup (cbs->value);
}
/* save whatever was returned; but lets check for
* changes to avoid roiling the cells too much */
if (table->entries[row][col]) {
if (strcmp (table->entries[row][col], newval)) {
free (table->entries[row][col]);
table->entries[row][col] = newval;
(arr->cells[rel_row][rel_col])->changed = 0xffffffff;
} else {
/* leave() allocated memory, which we will not be using ... */
free (newval);
}
} else {
/* Commit the change to the clist when we leave the cell */
gtk_clist_set_text(GTK_CLIST(table->table_widget), row - 1, col, newval);
/* save whatever was returned; but lets check for
* changes to avoid roiling the cells too much */
if (table->entries[row][col]) {
if (strcmp (table->entries[row][col], newval)) {
free (table->entries[row][col]);
table->entries[row][col] = newval;
(arr->cells[rel_row][rel_col])->changed = 0xffffffff;
}
} else {
/* leave() allocated memory, which we will not be using ... */
free(newval);
}
} else {
table->entries[row][col] = newval;
(arr->cells[rel_row][rel_col])->changed = 0xffffffff;
}
}
#if 0
/* ==================================================== */
@ -538,6 +558,58 @@ traverseCB (GtkWidget * mw, gpointer cd, gpointer cb)
#endif
static int counter;
static void
table_edit_entry_cb(GtkEntry *entry, gpointer user_data) {
Table *table = (Table *) user_data;
const int row = table->current_row;
const int col = table->current_col;
fprintf(stderr, "table_edit_entry_cb:\n");
fprintf(stderr, " curpos: %d selstart %d selend %d has_select: %d\n",
GTK_EDITABLE(entry)->current_pos,
GTK_EDITABLE(entry)->selection_start_pos,
GTK_EDITABLE(entry)->selection_end_pos,
GTK_EDITABLE(entry)->has_selection
);
if(!verify_cell_interaction_OK(table, row + 1, col)) return;
{
const int xxx = counter++;
printf(" cm: in %d\n", xxx);
cell_modified(table, row + 1, col);
printf(" cm: out %d\n", xxx);
}
}
static void
table_select_row_cb(GtkCList *cl, gint row, gint column, GdkEventButton *e,
gpointer user_data) {
Table *table = (Table *) user_data;
fprintf(stderr, "table_select_row_cb: %d %d\n", row, column);
//gtk_clist_unselect_row(cl, row, column);
if(!verify_cell_interaction_OK(table, row + 1, column)) return;
if(table->current_col != -1) {
cell_left(table, table->current_row + 1, table->current_col);
}
table->current_col = column;
table->current_row = row;
{
const int xxx = counter++;
printf(" ce: in %d\n", xxx);
cell_entered(table, row + 1, column);
printf(" ce: out %d\n", xxx);
}
}
/* ==================================================== */
GtkWidget *
@ -546,12 +618,18 @@ xaccCreateTable (Table *table, GtkWidget * parent)
CellBlock *curs;
unsigned char * alignments;
short * widths;
GtkWidget * reg;
int num_header_rows = 0;
int i;
if (!table) return 0;
if(table->table_widget != NULL) {
fprintf(stderr,
"Error: detected internal corruption in xaccCreateTable, "
"aborting\n");
return 0;
}
#if 0
/* if quarks have not yet been initialized for this
* application, initialize them now. */
@ -583,47 +661,94 @@ xaccCreateTable (Table *table, GtkWidget * parent)
num_header_rows = 1;
}
if(num_header_rows == 0) {
reg = gtk_clist_new(table->num_phys_cols);
} else {
reg = gtk_clist_new_with_titles(table->num_phys_cols, table->entries[0]);
gtk_clist_freeze(GTK_CLIST(reg));
for(i = 0; i < table->num_phys_cols; i++) {
{
/* TODO: Handle unrefs in destructor */
/* Widths are in units of characters, not pixels, so we have
this hack. It should be fixed later... */
gtk_clist_set_column_width(GTK_CLIST(reg), i, widths[i] * 5);
GtkWidget *vbox;
GtkWidget * reg;
/* We don't ref this vbox because we never use it in our code again */
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(parent), vbox);
if(num_header_rows == 0) {
reg = gtk_clist_new(table->num_phys_cols);
gtk_widget_ref(reg);
} else {
reg = gtk_clist_new_with_titles(table->num_phys_cols,
table->entries[0]);
gtk_widget_ref(reg);
gtk_clist_freeze(GTK_CLIST(reg));
for(i = 0; i < table->num_phys_cols; i++) {
/* Widths are in units of characters, not pixels, so we have
this hack. It should be fixed later... */
gtk_clist_set_column_width(GTK_CLIST(reg), i, widths[i] * 5);
}
gtk_clist_thaw(GTK_CLIST(reg));
}
gtk_clist_freeze(GTK_CLIST(reg));
for(i = num_header_rows; i < table->num_phys_rows; i++) {
gtk_clist_append(GTK_CLIST(reg), table->entries[i]);
}
gtk_clist_set_selection_mode(GTK_CLIST(reg), GTK_SELECTION_BROWSE);
gtk_clist_thaw(GTK_CLIST(reg));
/* size?
alignments?
grid type?
shadow type?
*/
gtk_signal_connect (GTK_OBJECT (reg), "select_row",
GTK_SIGNAL_FUNC (table_select_row_cb),
(gpointer) table);
// unselect is mostly useless for us since it doesn't get called when
// you click on a different cell in the same row.
//gtk_signal_connect (GTK_OBJECT (reg), "unselect_row",
// GTK_SIGNAL_FUNC (table_unselect_row_cb),
// (gpointer) table);
gtk_box_pack_start(GTK_BOX(vbox), reg, TRUE, TRUE, 0);
gtk_widget_show(reg);
table->table_widget = reg;
{
GtkWidget *entry_frame = NULL;
GtkWidget *entry_widget = NULL;
entry_frame = gtk_frame_new("<none>");
gtk_widget_ref(entry_frame);
entry_widget = gtk_entry_new();
gtk_widget_ref(entry_widget);
gtk_container_add(GTK_CONTAINER(entry_frame), entry_widget);
gtk_box_pack_start(GTK_BOX(vbox), entry_frame, FALSE, FALSE, 0);
{
const guint handler_id =
gtk_signal_connect (GTK_OBJECT(entry_widget), "changed",
GTK_SIGNAL_FUNC(table_edit_entry_cb),
(gpointer) table);
gtk_object_set_user_data(GTK_OBJECT(entry_widget),
(gpointer) handler_id);
}
gtk_widget_show(entry_widget);
gtk_widget_show(entry_frame);
gtk_widget_show(vbox);
table->entry_frame = entry_frame;
table->entry_widget = entry_widget;
}
}
gtk_clist_freeze(GTK_CLIST(reg));
for(i = num_header_rows; i < table->num_phys_rows; i++) {
gtk_clist_append(GTK_CLIST(reg), table->entries[i]);
}
gtk_clist_thaw(GTK_CLIST(reg));
/* size?
alignments?
grid type?
shadow type?
*/
gtk_container_add(GTK_CONTAINER(parent), reg);
gtk_widget_show(reg);
#if 0
/* add callbacks that handle cell editing */
XtAddCallback (reg, XmNenterCellCallback, cellCB, (gpointer)table);
XtAddCallback (reg, XmNleaveCellCallback, cellCB, (gpointer)table);
XtAddCallback (reg, XmNmodifyVerifyCallback, cellCB, (gpointer)table);
XtAddCallback (reg, XmNtraverseCellCallback, traverseCB, (gpointer)table);
#endif
table->table_widget = reg;
#if 0
/* ??? What does xt_realize do? */
/* if any of the cells have GUI specific components that need
* initialization, initialize them now. */
@ -636,21 +761,20 @@ xaccCreateTable (Table *table, GtkWidget * parent)
BasicCell *cell;
cell = curs->cells[i][j];
if (cell) {
void (*xt_realize) (BasicCell *,
void *gui,
int pixel_width);
void (*xt_realize) (BasicCell *, void *gui, int pixel_width);
xt_realize = cell->realize;
if (xt_realize) {
int pixel_width;
pixel_width = XbaeMatrixGetColumnPixelWidth (reg, j);
xt_realize (cell, ((void *) reg), pixel_width);
/* cl->column[col].width */
/*pixel_width = XbaeMatrixGetColumnPixelWidth (reg, j);*/
xt_realize (cell, ((void *) table), 0);
/*xt_realize (cell, ((void *) reg), pixel_width);*/
}
}
}
}
}
#endif
return (reg);
return (table->table_widget);
}
/* ==================================================== */
@ -672,7 +796,7 @@ xaccRefreshTableGUI (Table * table)
reg = table->table_widget;
printf (" refresh numphysrows=%d numphyscols=%d \n",
table->num_phys_rows,table->num_phys_cols);
table->num_phys_rows, table->num_phys_cols);
for (i = num_header_rows; i < table->num_phys_rows; i++) {
printf ("cell %d act:%s descr: %s \n",
@ -682,13 +806,15 @@ xaccRefreshTableGUI (Table * table)
gtk_clist_freeze(GTK_CLIST(reg));
while(GTK_CLIST(reg)->rows < table->num_phys_rows) {
while(GTK_CLIST(reg)->rows < (table->num_phys_rows - num_header_rows)) {
gtk_clist_append(GTK_CLIST(reg), NULL);
}
for(i = num_header_rows; i < table->num_phys_rows; i++) {
for(i = num_header_rows; i < table->num_phys_rows; i++)
{
for(j = 0; j < table->num_phys_cols; j++) {
gtk_clist_set_text(GTK_CLIST(reg), i, j, table->entries[i][j]);
gtk_clist_set_text(GTK_CLIST(reg), i - num_header_rows, j,
table->entries[i][j]);
}
}
gtk_clist_thaw(GTK_CLIST(reg));
@ -700,8 +826,8 @@ xaccRefreshTableGUI (Table * table)
Local Variables:
tab-width: 2
indent-tabs-mode: nil
mode: c-mode
mode: c
c-indentation-style: gnu
eval: (c-set-offset 'block-open '-)
eval: (c-set-offset 'substatement-open 0)
End:
*/

View File

@ -119,6 +119,16 @@ struct _Table {
/* protected data -- vital for the implementation,
* but not something we want to generally expose */
GtkWidget *table_widget; /* the CList */
GtkWidget *entry_frame; /* the editing widget frame */
GtkWidget *entry_widget; /* the current cell editing widget */
/* Current editing cell */
int current_col;
int current_row;
/* snapshot of entry text -- used to detect changes in callback */
char *prev_entry_text;
GtkWidget *next_tab_group; /* where to traverse in the end */
};