field.c File Reference


Detailed Description

Add and edit fields (columns) in the GtkSheet.

Author:
Copyright 2006-2007 Neil Williams <linux@codehelp.co.uk>

Copyright 1999 Robert Lissner, Jay MacDonald

Copyright 1999 Sam Phillips, Keith Wesolowski.

Definition in file field.c.

#include "config.h"
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include <gtkextra/gtksheet.h>
#include <monetary.h>
#include "types.h"
#include "dialog_initial.h"
#include "dim_list_menu.h"
#include "filein.h"
#include "main.h"

Go to the source code of this file.

Functions

static void cancel_clicked (GtkObject G_GNUC_UNUSED *object, gpointer G_GNUC_UNUSED entry)
static void done_clicked (GtkObject G_GNUC_UNUSED *object, gpointer data)
static void just_clicked (GtkObject G_GNUC_UNUSED *object, gpointer entry)
static void sm_formatting_changed (GtkObject G_GNUC_UNUSED *object, gpointer G_GNUC_UNUSED entry)
static void update_field_db (QlTabData *tab)
static void type_clicked (GtkObject G_GNUC_UNUSED *object, gpointer data)
static gchar * get_datestamp (const gchar *format)
static gchar * get_timestamp (const gchar *format)
static gchar * display_currency (gdouble number, QlCurrFormat qc)
 used for currency
static GtkWidget * sub_menus (QlTabData *tab)
 Assemble the style menus for numeric, date and time.
static void new_std_field (QlTabData *tab)
static void add_column_cb (gpointer G_GNUC_UNUSED field_index, gpointer field_ptr, gpointer user_data)
static void ok_clicked (GtkObject G_GNUC_UNUSED *object, gpointer data)
 Create new field in the sheet.
static void swap_columns (QlTabData *tab, gint tocol, gint from)
void build_field_db (QlTabData *tab)
 Builds dialogue box to edit field parameters.
void column_add (GtkAction G_GNUC_UNUSED *w, gpointer data)
void column_edit (GtkAction G_GNUC_UNUSED *w, gpointer data)
void del_column_cb (gpointer field_index, gpointer field_ptr, gpointer G_GNUC_UNUSED user_data)
void column_delete (GtkAction G_GNUC_UNUSED *w, gpointer data)
void column_left (GtkAction G_GNUC_UNUSED *w, gpointer data)
void column_right (GtkAction G_GNUC_UNUSED *w, gpointer data)
void new_file (GtkAction G_GNUC_UNUSED *w, gpointer data)

Variables

static QlFieldInfofield_db_start
static QlFieldInfofield_db_curr
static GtkWidget * done_button
static gboolean displaying
static GtkWidget * text_button
static GtkWidget * numeric_button
static GtkWidget * date_button
static GtkWidget * time_button
static GtkWidget * left_button
static GtkWidget * center_button
static GtkWidget * right_button
static GtkWidget * column_name_entry
static GtkWidget * decimal_places_entry
static GtkWidget * entry_dialogue
static G_GNUC_UNUSED gchar * num_formats []
 new locale sensitive number formatting


Function Documentation

void build_field_db ( QlTabData tab  ) 

Builds dialogue box to edit field parameters.

Parameters:
front->sel_range.col0 the field being edited
field_db_curr the information we want to display
field_db_start the settings at the time the dialog box was opened. Zero is possible

Definition at line 606 of file field.c.

00607 {
00608     GtkWidget *top_box;
00609     GtkWidget *hbox_name;
00610     GtkWidget *hbox_type;
00611     GtkWidget *hbox_just;
00612     GtkWidget *button_box;
00613     GtkWidget *ok_button;
00614     GtkWidget *cancel_button;
00615     GtkWidget *name_label;
00616 
00617     entry_dialogue = gtk_dialog_new ();
00618     gtk_window_set_modal (GTK_WINDOW (entry_dialogue), TRUE);
00619     gtk_window_set_position (GTK_WINDOW (entry_dialogue), GTK_WIN_POS_CENTER);
00620     gtk_window_set_resizable (GTK_WINDOW (entry_dialogue), TRUE);
00621     gtk_container_set_border_width (GTK_CONTAINER (entry_dialogue), 5);
00622     displaying = FALSE;
00623     field_db_start = field_db_curr;
00624     /* associate the tab context with the field dialogue. */
00625     g_object_set_data (G_OBJECT(entry_dialogue), QLTABID, tab);
00626     gtk_window_set_title (GTK_WINDOW (entry_dialogue),
00627         _("Edit Column Information"));
00628     top_box = GTK_DIALOG (entry_dialogue)->vbox;
00629     gtk_box_set_spacing (GTK_BOX (top_box), 10);
00630     button_box = GTK_DIALOG (entry_dialogue)->action_area;
00631 
00632     hbox_name = gtk_hbox_new (FALSE, 5);
00633     name_label = gtk_label_new (_("Column Name"));
00634     gtk_widget_show (name_label);
00635     gtk_box_pack_start (GTK_BOX (hbox_name), name_label, FALSE, FALSE, 0);
00636 
00637     column_name_entry = gtk_entry_new ();
00638     gtk_entry_set_max_length (GTK_ENTRY (column_name_entry), MAX_FIELD_NAME);
00639     gtk_box_pack_start (GTK_BOX (hbox_name), column_name_entry, TRUE, TRUE, 0);
00640     gtk_widget_show (column_name_entry);
00641     gtk_widget_show (hbox_name);
00642     gtk_box_pack_start (GTK_BOX (top_box), hbox_name, FALSE, FALSE, 0);
00643 
00644     /* Got the top box formatted, now go for type radio buttons */
00645     hbox_type = gtk_hbox_new (FALSE, 3);
00646     text_button = gtk_radio_button_new_with_label (NULL, _("Text"));
00647     g_signal_connect (GTK_OBJECT (text_button), "clicked",
00648         G_CALLBACK (type_clicked), GINT_TO_POINTER (FIELD_TYPE_TEXT));
00649     gtk_box_pack_start (GTK_BOX (hbox_type), text_button, TRUE,
00650         TRUE, 0);
00651     gtk_widget_show (text_button);
00652 
00653     numeric_button = gtk_radio_button_new_with_label
00654         (gtk_radio_button_get_group
00655         (GTK_RADIO_BUTTON (text_button)), _("Numeric"));
00656     g_signal_connect (GTK_OBJECT (numeric_button), "clicked",
00657         G_CALLBACK (type_clicked), GINT_TO_POINTER (FIELD_TYPE_NUMERIC));
00658     gtk_box_pack_start (GTK_BOX (hbox_type), numeric_button, TRUE,
00659         TRUE, 0);
00660     gtk_widget_show (numeric_button);
00661 
00662     date_button = gtk_radio_button_new_with_label
00663         (gtk_radio_button_get_group
00664         (GTK_RADIO_BUTTON (text_button)), _("Date"));
00665     g_signal_connect (GTK_OBJECT (date_button), "clicked",
00666         G_CALLBACK (type_clicked), GINT_TO_POINTER (FIELD_TYPE_DATE));
00667     gtk_box_pack_start (GTK_BOX (hbox_type), date_button, TRUE,
00668         TRUE, 0);
00669     gtk_widget_show (date_button);
00670 
00671     time_button = gtk_radio_button_new_with_label
00672         (gtk_radio_button_get_group
00673         (GTK_RADIO_BUTTON (text_button)), _("Time"));
00674     g_signal_connect (GTK_OBJECT (time_button), "clicked",
00675         G_CALLBACK (type_clicked), GINT_TO_POINTER (FIELD_TYPE_TIME));
00676     gtk_box_pack_start (GTK_BOX (hbox_type), time_button, TRUE,
00677         TRUE, 0);
00678     gtk_widget_show (time_button);
00679     gtk_widget_show (hbox_type);
00680     gtk_box_pack_start (GTK_BOX (top_box), hbox_type, FALSE, FALSE, 0);
00681 
00682     /* Now the justification radio buttons */
00683     hbox_just = gtk_hbox_new (FALSE, 3);
00684     left_button = gtk_radio_button_new_with_label (NULL, _("Left"));
00685     g_signal_connect (GTK_OBJECT (left_button), "clicked",
00686         G_CALLBACK (just_clicked), GINT_TO_POINTER (GTK_JUSTIFY_LEFT));
00687     gtk_box_pack_start (GTK_BOX (hbox_just), left_button, TRUE,
00688         TRUE, 0);
00689     gtk_widget_show (left_button);
00690 
00691     center_button = gtk_radio_button_new_with_label
00692         (gtk_radio_button_get_group
00693         (GTK_RADIO_BUTTON (left_button)), _("Center"));
00694     g_signal_connect (GTK_OBJECT (center_button), "clicked",
00695         G_CALLBACK (just_clicked), GINT_TO_POINTER (GTK_JUSTIFY_CENTER));
00696     gtk_box_pack_start (GTK_BOX (hbox_just), center_button, TRUE,
00697         TRUE, 0);
00698     gtk_widget_show (center_button);
00699 
00700     right_button = gtk_radio_button_new_with_label
00701         (gtk_radio_button_get_group
00702         (GTK_RADIO_BUTTON (left_button)), _("Right"));
00703     g_signal_connect (GTK_OBJECT (right_button), "clicked",
00704         G_CALLBACK (just_clicked), GINT_TO_POINTER (GTK_JUSTIFY_RIGHT));
00705     gtk_box_pack_start (GTK_BOX (hbox_just), right_button, TRUE,
00706         TRUE, 0);
00707     gtk_widget_show (right_button);
00708     gtk_widget_show (hbox_just);
00709     gtk_box_pack_start (GTK_BOX (top_box), hbox_just, FALSE, FALSE, 0);
00710 
00711     /* go get the display types buttons for numeric, date and time */
00712     gtk_box_pack_start (GTK_BOX (top_box), sub_menus (tab), FALSE, FALSE, 0);
00713 
00714     /* Now do OK, Done and Cancel buttons */
00715     ok_button = gtk_button_new_from_stock (GTK_STOCK_ADD);
00716     gtk_widget_show (ok_button);
00717     gtk_box_pack_start (GTK_BOX (button_box), ok_button, TRUE, TRUE, 0);
00718     g_signal_connect (GTK_OBJECT (ok_button), "clicked",
00719         G_CALLBACK (ok_clicked), tab);
00720 
00721     if (tab->view->dialog_mode == MODE_NEW)
00722     {
00723         done_button = gtk_button_new_from_stock (GTK_STOCK_APPLY);
00724         /* show is done later */
00725         gtk_box_pack_start (GTK_BOX (button_box),
00726             done_button, TRUE, TRUE, 0);
00727         g_signal_connect (GTK_OBJECT (done_button), "clicked",
00728             G_CALLBACK (done_clicked), tab);
00729     }
00730     cancel_button = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
00731     gtk_widget_show (cancel_button);
00732     gtk_box_pack_start (GTK_BOX (button_box),
00733         cancel_button, TRUE, TRUE, 0);
00734     g_signal_connect (GTK_OBJECT (cancel_button), "clicked",
00735         G_CALLBACK (cancel_clicked), tab);
00736     g_signal_connect (GTK_OBJECT (entry_dialogue),
00737         "delete_event", G_CALLBACK (cancel_clicked), tab);
00738     gtk_widget_show (entry_dialogue);
00739 }

void column_edit ( GtkAction G_GNUC_UNUSED *  w,
gpointer  data 
)

Todo:
simplify the notation further

Definition at line 757 of file field.c.

00758 {
00759     QlContext * qlc;
00760     QlTabData * tab;
00761     gint this_field, selected;
00762 
00764     qlc = ql_get_context (GTK_WIDGET(data));
00765     tab = ql_get_tabdata (qlc);
00766     CHECK_RANGE;
00767     CHECK_CHANGED(tab);
00768     if (tab->view->sel_type != SELECT_COLUMN)
00769         return;
00770     tab->view->dialog_mode = MODE_EDIT;
00771     selected = tab->view->sel_range.col0;
00772     this_field = tab->file->col_to_field[selected];
00773     field_db_curr = ql_get_fieldinfo (tab, this_field);
00774     build_field_db (tab);
00775     update_field_db (tab);
00776 }

static gchar* display_currency ( gdouble  number,
QlCurrFormat  qc 
) [static]

used for currency

Parameters:
number The amount of currency.
qc The QuickList currency format to use.

Definition at line 285 of file field.c.

00286 {
00287     gchar buf[MAX_DATE_BUFFER];
00288     gsize len;
00289     gchar * format;
00290 
00291     format = NULL;
00292     switch (qc)
00293     {
00294         /* "1,234.56" %! formatting style for formatting == 0 */
00295         case QL_NF_GRP :   { format = g_strdup("%!i"); break;  }
00296         /* "1234.56"  %^! */
00297         case QL_NF :       { format = g_strdup("%^!i"); break; }
00298         /* "$1,234.56"  default (%n) */
00299         case QL_NF_CURR :  { format = g_strdup("%n"); break;  }
00300         /* "1,234.56%" percentage numbers */
00301         case QL_NF_PERCENT : { format = g_strdup ("%!i%%"); break; }
00302         /* "1.234,56" used for files only */
00303         /* "1234,56" used for files only */
00304         /* "1.234,56%" used for files only */
00305         default : break;
00306     }
00307     if (!format)
00308         return NULL;
00309     buf[0] = '\1';
00310     len = strfmon (buf, MAX_DATE_BUFFER, format, number);
00311     g_free (format);
00312     if (len <= 0 && buf[0] != '\0')
00313         return NULL;
00314     return g_strdup (buf);
00315 }

static void new_std_field ( QlTabData tab  )  [static]

setup a new text field as a standard text field. User might change it as they edit it

Definition at line 384 of file field.c.

00385 {
00386     gtk_entry_set_text (GTK_ENTRY (column_name_entry), "");
00387     /* if last_field =2, then new is Field 4 */
00388     field_db_curr->name = g_strdup_printf (_("Column %u"),
00389         tab->file->last_field + 2);
00390     field_db_curr->sheet_column = tab->file->last_field + 1;
00391     field_db_curr->type = FIELD_TYPE_TEXT;
00392     field_db_curr->formatting = 0;
00393     field_db_curr->decimal_places = 0;
00394     field_db_curr->justification = GTK_JUSTIFY_LEFT;
00395     field_db_curr->width = 10;
00396 }

static void ok_clicked ( GtkObject G_GNUC_UNUSED *  object,
gpointer  data 
) [static]

Create new field in the sheet.

Called by build_field_db and therefore used by new and existing files. Remember that the sheet isn't open yet if this is a new file.

Bug:
need type-specific GList based formatting.

Definition at line 415 of file field.c.

00416 {
00417     gint fieldx;
00418     gint sheetx;
00419     gint rowx;
00420     const gchar *text;
00421     gchar *tmp;
00422     GtkSheetRange range;
00423     gdouble temp_double;
00424     gchar linebuf[48];
00425     QlTabData * tab;
00426 
00427     tab = (QlTabData*)data;
00428     g_return_if_fail (tab);
00429     text = gtk_entry_get_text (GTK_ENTRY (column_name_entry));
00430     tmp = g_strdup (text);
00431     if (check_entry (tab, tmp))
00432         return;
00433     g_free (tmp);
00434     field_db_curr->name = g_strdup(text);
00435 
00436     if (field_db_curr->type == FIELD_TYPE_NUMERIC)
00437     {
00438         field_db_curr->decimal_places = gtk_spin_button_get_value_as_int
00439             (GTK_SPIN_BUTTON(decimal_places_entry));
00440     }
00441 
00442     /* we have an existing file and we are adding a new field/column */
00443     if (tab->view->dialog_mode == MODE_ADD)
00444     {
00445         field_db_curr->sheet_column = sheetx = tab->view->sel_range.col0;
00446         ql_fieldinfo_foreach (tab, add_column_cb, GINT_TO_POINTER (sheetx));
00447 
00448         fieldx = ++tab->file->last_field;
00449         big_draw_start (tab);
00450         ql_add_fieldinfo (tab, field_db_curr);
00451 
00452         /* add column, add to sheet now */
00453         gtk_sheet_insert_columns (tab->view->sheet, sheetx, 1);
00454         gtk_sheet_set_column_width (tab->view->sheet, sheetx,
00455             field_db_curr->width * 8);
00456         gtk_sheet_column_button_add_label (tab->view->sheet,
00457             sheetx, field_db_curr->name);
00458         gtk_sheet_column_set_justification (tab->view->sheet,
00459             sheetx, field_db_curr->justification);
00460 
00461         reset_col_to_field (tab);
00462         big_draw_end (tab);
00463         front_is_changed (tab);
00464         return;
00465     }                           /* end of add field */
00466 
00467     /* we have an existing file and editing the fields. */
00468     else if (tab->view->dialog_mode == MODE_EDIT)
00469     {
00470         QlFieldInfo * field;
00471         sheetx = tab->view->sel_range.col0;
00472         field = ql_get_fieldinfo (tab, sheetx);
00473         field = field_db_curr;
00474         gtk_sheet_column_button_add_label (tab->view->sheet,
00475             sheetx, field_db_curr->name);
00476         big_draw_start (tab);
00477         if (field_db_curr->justification != field_db_start->justification)
00478         {
00479             gtk_sheet_column_set_justification (tab->view->sheet,
00480                 sheetx, field_db_curr->justification);
00481             range.row0 = 0;
00482             range.rowi = tab->file->last_row;
00483             range.col0 = range.coli = sheetx;
00484             gtk_sheet_range_set_justification (tab->view->sheet,
00485                 &range, field_db_curr->justification);
00486         }
00487 
00488         /* check if numeric format changed */
00489         if (field_db_curr->type == FIELD_TYPE_TEXT ||
00490             !tab->file->last_row)
00491         {
00492             big_draw_end (tab);
00493             front_is_changed (tab);
00494             return;
00495         }
00496         if (field_db_curr->type != FIELD_TYPE_TEXT &&
00497             (field_db_start->type != field_db_curr->type ||
00498                 field_db_start->formatting != field_db_curr->formatting ||
00499                 field_db_start->decimal_places !=
00500                 field_db_curr->decimal_places))
00501         {
00502 
00503             /* make sure the old formatting code is valid */
00505             if (field_db_start->type == FIELD_TYPE_TEXT)
00506                 field_db_start->formatting = field_db_curr->formatting; /* default */
00507             for (rowx = 0; rowx < tab->file->last_row; rowx++)
00508             {
00509                 text = gtk_sheet_cell_get_text (tab->view->sheet,
00510                     rowx, sheetx);
00511                 if (text)
00512                 {
00513                     temp_double = qls2d (text, field_db_curr->type,
00514                         field_db_start->formatting);
00515                     d2qls (linebuf, temp_double, field_db_curr->type,
00516                         field_db_curr->formatting,
00517                         field_db_curr->decimal_places);
00518                     gtk_sheet_set_cell_text (tab->view->sheet,
00519                         rowx, sheetx, linebuf);
00520                 }
00521             }
00522         }
00523         big_draw_end (tab);
00524         front_is_changed (tab);
00525         return;
00526     }
00527 
00528     /* we have a new file */
00529     fieldx = sheetx = ++tab->file->last_field;
00530     ql_add_fieldinfo (tab, field_db_curr);
00531     reset_col_to_field (tab);
00532     new_std_field (tab);
00533     field_db_start = field_db_curr;
00534     update_field_db (tab);
00535 }

static void update_field_db ( QlTabData tab  )  [static]

This function displays the field dialogue box.

Definition at line 136 of file field.c.

00137 {
00138     gchar linebuf[20];
00139     const gchar *text;
00140 
00141     displaying = TRUE;
00142 
00143     text = gtk_entry_get_text (GTK_ENTRY (column_name_entry));
00144     if (text && strlen (text) > 0)
00145         field_db_curr->name = g_strdup(text);
00146     gtk_entry_set_text (GTK_ENTRY (column_name_entry), field_db_curr->name);
00147     /* otherwise assume want to enter name */
00148     if (tab->view->dialog_mode != MODE_EDIT)
00149         gtk_editable_select_region (GTK_EDITABLE (column_name_entry), 0,
00150             strlen (field_db_curr->name));
00151     gtk_widget_hide (GTK_WIDGET (tab->view->sm_numeric_box));
00152     gtk_widget_hide (tab->view->dec_places_label);
00153     gtk_widget_hide (decimal_places_entry);
00154     gtk_widget_hide (GTK_WIDGET (tab->view->sm_date_box));
00155     gtk_widget_hide (GTK_WIDGET (tab->view->sm_time_box));
00156 
00157     switch (field_db_curr->type)
00158     {
00159         case FIELD_TYPE_TEXT:
00160         {
00161             gtk_toggle_button_set_active
00162                 (GTK_TOGGLE_BUTTON (text_button), TRUE);
00163             break;
00164         }
00165         case FIELD_TYPE_NUMERIC:
00166         {
00167             gtk_toggle_button_set_active
00168             (GTK_TOGGLE_BUTTON (numeric_button), TRUE);
00169             gtk_combo_box_set_active (tab->view->sm_numeric_box,
00170                 field_db_curr->formatting);
00171             if (field_db_curr->decimal_places >= 0 &&
00172                 field_db_curr->decimal_places < 10)
00173                 sprintf (linebuf, "%u", field_db_curr->decimal_places);
00174             else
00175                 strcpy (linebuf, "0");
00176 
00177             gtk_entry_set_text (GTK_ENTRY (decimal_places_entry), linebuf);
00178             gtk_widget_show (GTK_WIDGET (tab->view->sm_numeric_box));
00179             gtk_widget_show (tab->view->dec_places_label);
00180             gtk_widget_show (decimal_places_entry);
00181             break;
00182         }
00183         case FIELD_TYPE_DATE:
00184         {
00185             gtk_toggle_button_set_active
00186                 (GTK_TOGGLE_BUTTON (date_button), TRUE);
00187             gtk_combo_box_set_active (tab->view->sm_date_box,
00188                 field_db_curr->formatting);
00189             gtk_widget_show (GTK_WIDGET (tab->view->sm_date_box));
00190             break;
00191         }
00192         case FIELD_TYPE_TIME:
00193         {
00194             gtk_toggle_button_set_active
00195                 (GTK_TOGGLE_BUTTON (time_button), TRUE);
00196             gtk_combo_box_set_active (tab->view->sm_time_box,
00197                 field_db_curr->formatting);
00198             gtk_widget_show (GTK_WIDGET (tab->view->sm_time_box));
00199             break;
00200         }
00201     }
00202     switch (field_db_curr->justification)
00203     {
00204         case GTK_JUSTIFY_LEFT:
00205         {
00206             gtk_toggle_button_set_active
00207                 (GTK_TOGGLE_BUTTON (left_button), TRUE);
00208             break;
00209         }
00210         case GTK_JUSTIFY_CENTER:
00211         {
00212             gtk_toggle_button_set_active
00213                 (GTK_TOGGLE_BUTTON (center_button), TRUE);
00214             break;
00215         }
00216         case GTK_JUSTIFY_RIGHT:
00217         {
00218             gtk_toggle_button_set_active
00219                 (GTK_TOGGLE_BUTTON (right_button), TRUE);
00220             break;
00221         }
00222     }
00223     if (tab->view->dialog_mode == MODE_NEW && tab->file->last_field >= 0)
00224         gtk_widget_show (done_button);
00225 
00226     gtk_widget_grab_focus (GTK_WIDGET (column_name_entry));
00227     displaying = FALSE;
00228 }


Variable Documentation

gboolean displaying [static]

so we can ignore signals during display

Definition at line 49 of file field.c.

G_GNUC_UNUSED gchar* num_formats[] [static]

Initial value:

 {
    "1,234.56",     
    "1.234,56",     
    "1234.56",      
    "1234,56",      
    "$1,234.56",    
    "1,234.56%",    
    "1.234,56%",    
    NULL
}
new locale sensitive number formatting

Todo:
make locale sensitive
strfmon : ^ - omit grouping £1234567.89, default is £1,234,567.89 %( - bracket negative values (£12,345.99) + - use the locale equivalent of +/- -£12,345.99 ! - omit the currency symbol. 12,345.99 - - left formatted instead of right formatted. also have string width support and # for number of digits to the LEFT of the decimal. Use . for number of decimal places. Also i for international currencies, n for national. TEST!

Bug:
take care how these are read from existing files!
Include new specifiers for: %( (£12,345.99) ^( (£12345.99) %(! 12,345.99 i 12,345.99GBP i( (12,345.99)GBP ^i( (12345.99)GBP ^i 12,345.99GBP

Definition at line 87 of file field.c.


Generated on Mon Jan 28 22:02:10 2008 for quicklist by  doxygen 1.5.4