summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRamiro Estrugo <ramiro@src.gnome.org>2000-04-26 15:24:53 +0000
committerRamiro Estrugo <ramiro@src.gnome.org>2000-04-26 15:24:53 +0000
commitbfb251fc7a7688cf645ceb1fd197907fc418199a (patch)
tree8eb8a50b83e443ed667d672b4cb0305790836518
parentb96e440f143aaa2f191af483e3350346f01a7a08 (diff)
downloadnautilus-bfb251fc7a7688cf645ceb1fd197907fc418199a.tar.gz
Add a caption table widget which i will later use for a password prompt
* nautilus-widgets/nautilus-caption-table.c, nautilus-widgets/nautilus-caption-table.h, test-nautilus-widgets.c: Add a caption table widget which i will later use for a password prompt dialog.
-rw-r--r--ChangeLog7
-rw-r--r--libnautilus-extensions/nautilus-caption-table.c400
-rw-r--r--libnautilus-extensions/nautilus-caption-table.h89
-rw-r--r--libnautilus-extensions/test-nautilus-widgets.c87
-rw-r--r--libnautilus-private/nautilus-caption-table.c400
-rw-r--r--libnautilus-private/nautilus-caption-table.h89
-rw-r--r--libnautilus-private/test-nautilus-widgets.c87
-rw-r--r--nautilus-widgets/Makefile.am2
-rw-r--r--nautilus-widgets/nautilus-caption-table.c400
-rw-r--r--nautilus-widgets/nautilus-caption-table.h89
-rw-r--r--nautilus-widgets/test-nautilus-widgets.c87
11 files changed, 1704 insertions, 33 deletions
diff --git a/ChangeLog b/ChangeLog
index 72b580278..60bfd0155 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2000-04-26 Ramiro Estrugo <ramiro@eazel.com>
+
+ * nautilus-widgets/nautilus-caption-table.c,
+ nautilus-widgets/nautilus-caption-table.h,
+ test-nautilus-widgets.c: Add a caption table widget which i will
+ later use for a password prompt dialog.
+
2000-04-26 Pavel Cisler <pavel@eazel.com>
* librsvg/test-rsvg.c:
diff --git a/libnautilus-extensions/nautilus-caption-table.c b/libnautilus-extensions/nautilus-caption-table.c
new file mode 100644
index 000000000..1eb8affa2
--- /dev/null
+++ b/libnautilus-extensions/nautilus-caption-table.c
@@ -0,0 +1,400 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+
+/* nautilus-caption-table.c - An easy way to do tables of aligned captions.
+
+ Copyright (C) 1999, 2000 Eazel, Inc.
+
+ The Gnome Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Authors: Ramiro Estrugo <ramiro@eazel.com>
+*/
+
+#include "nautilus-caption-table.h"
+
+#include <gtk/gtkentry.h>
+#include <gtk/gtksignal.h>
+#include <gtk/gtklabel.h>
+#include <libnautilus-extensions/nautilus-gtk-macros.h>
+
+struct _NautilusCaptionTableDetail
+{
+ GtkWidget **labels;
+ GtkWidget **entries;
+ guint num_rows;
+ guint size;
+};
+
+enum
+{
+ ACTIVATE,
+ LAST_SIGNAL
+};
+
+/* NautilusCaptionTableClass methods */
+static void nautilus_caption_table_initialize_class (NautilusCaptionTableClass *klass);
+static void nautilus_caption_table_initialize (NautilusCaptionTable *caption_table);
+
+/* GtkObjectClass methods */
+static void caption_table_destroy (GtkObject *object);
+
+/* Private methods */
+static void caption_table_resize (NautilusCaptionTable *caption_table,
+ guint num_rows);
+static GtkWidget* caption_table_find_next_sensitive_entry (NautilusCaptionTable *caption_table,
+ guint index);
+static int caption_table_index_of_entry (NautilusCaptionTable *caption_table,
+ GtkWidget *entry);
+
+/* Entry callbacks */
+static void entry_activate (GtkWidget *widget,
+ gpointer data);
+
+/* Boilerplate stuff */
+NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusCaptionTable,
+ nautilus_caption_table,
+ GTK_TYPE_TABLE)
+
+static int caption_table_signals[LAST_SIGNAL] = { 0 };
+
+static void
+nautilus_caption_table_initialize_class (NautilusCaptionTableClass *klass)
+{
+ GtkObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+
+ object_class = GTK_OBJECT_CLASS (klass);
+ widget_class = GTK_WIDGET_CLASS (klass);
+
+ parent_class = gtk_type_class (GTK_TYPE_TABLE);
+
+ caption_table_signals[ACTIVATE] =
+ gtk_signal_new ("activate",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (NautilusCaptionTableClass, activate),
+ gtk_marshal_NONE__INT,
+ GTK_TYPE_NONE, 1, GTK_TYPE_INT);
+
+ gtk_object_class_add_signals (object_class, caption_table_signals, LAST_SIGNAL);
+
+ /* GtkObjectClass */
+ object_class->destroy = caption_table_destroy;
+}
+
+#define CAPTION_TABLE_DEFAULT_ROWS 1
+
+static void
+nautilus_caption_table_initialize (NautilusCaptionTable * caption_table)
+{
+ GtkTable *table = GTK_TABLE (caption_table);
+
+ caption_table->detail = g_new (NautilusCaptionTableDetail, 1);
+
+ caption_table->detail->num_rows = 0;
+
+ caption_table->detail->size = 0;
+
+ caption_table->detail->labels = NULL;
+ caption_table->detail->entries = NULL;
+
+ table->homogeneous = FALSE;
+}
+
+/* GtkObjectClass methods */
+static void
+caption_table_destroy (GtkObject *object)
+{
+ NautilusCaptionTable *caption_table;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (NAUTILUS_IS_CAPTION_TABLE (object));
+
+ caption_table = NAUTILUS_CAPTION_TABLE (object);
+
+ if (caption_table->detail->labels)
+ g_free(caption_table->detail->labels);
+
+ if (caption_table->detail->entries)
+ g_free(caption_table->detail->entries);
+
+ g_free (caption_table->detail);
+
+ if (GTK_OBJECT_CLASS (parent_class)->destroy)
+ (*GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+/* FIXME: This should be public for the widget to be useful */
+static void
+caption_table_resize (NautilusCaptionTable *caption_table,
+ guint num_rows)
+{
+ GtkTable* table = NULL;
+
+ g_return_if_fail (caption_table != NULL);
+ g_return_if_fail (NAUTILUS_IS_CAPTION_TABLE (caption_table));
+
+ /* Make sure the num_rows have changed */
+ if (caption_table->detail->num_rows == num_rows)
+ return;
+
+ caption_table->detail->num_rows = num_rows;
+
+ /* Resize the GtkTable */
+ table = GTK_TABLE (caption_table);
+ gtk_table_resize(table, caption_table->detail->num_rows, 2);
+
+ /* Create more label/entry pairs if needed */
+ if (caption_table->detail->num_rows > caption_table->detail->size)
+ {
+ guint i;
+ guint old_size = caption_table->detail->size;
+ guint new_size = caption_table->detail->num_rows;
+ guint realloc_size = sizeof(GtkWidget *) * new_size;
+
+ /* FIXME: Use a GList for this */
+ caption_table->detail->labels = (GtkWidget**) g_realloc (caption_table->detail->labels,
+ realloc_size);
+
+ caption_table->detail->entries = (GtkWidget**) g_realloc (caption_table->detail->entries,
+ realloc_size);
+
+ for (i = old_size; i < new_size; i++)
+ {
+ caption_table->detail->labels[i] = gtk_label_new("");
+ caption_table->detail->entries[i] = gtk_entry_new();
+
+ gtk_signal_connect(GTK_OBJECT (caption_table->detail->entries[i]),
+ "activate",
+ GTK_SIGNAL_FUNC(entry_activate),
+ (gpointer) caption_table);
+
+ gtk_misc_set_alignment(GTK_MISC(caption_table->detail->labels[i]), 1.0, 0.5);
+
+ /* Column 1 */
+ gtk_table_attach(table,
+ caption_table->detail->labels[i], /* child */
+ 0, /* left_attatch */
+ 1, /* right_attatch */
+ i, /* top_attatch */
+ i + 1, /* bottom_attatch */
+ GTK_FILL, /* xoptions */
+ (GTK_FILL|GTK_EXPAND), /* yoptions */
+ 0, /* xpadding */
+ 0); /* ypadding */
+
+ /* Column 2 */
+ gtk_table_attach(table,
+ caption_table->detail->entries[i], /* child */
+ 1, /* left_attatch */
+ 2, /* right_attatch */
+ i, /* top_attatch */
+ i + 1, /* bottom_attatch */
+ (GTK_FILL|GTK_EXPAND), /* xoptions */
+ (GTK_FILL|GTK_EXPAND), /* yoptions */
+ 0, /* xpadding */
+ 0); /* ypadding */
+ }
+
+ caption_table->detail->size = new_size;
+ }
+
+ /* Show only the needed caption widgets */
+ if (caption_table->detail->size > 0)
+ {
+ guint i;
+
+ for(i = 0; i < caption_table->detail->size; i++)
+ {
+ if (i < caption_table->detail->num_rows)
+ {
+ gtk_widget_show (caption_table->detail->labels[i]);
+ gtk_widget_show (caption_table->detail->entries[i]);
+ }
+ else
+ {
+ gtk_widget_hide (caption_table->detail->labels[i]);
+ gtk_widget_hide (caption_table->detail->entries[i]);
+ }
+ }
+ }
+
+ /* Set inter row spacing */
+ if (caption_table->detail->num_rows > 1)
+ {
+ guint i;
+
+ for(i = 0; i < (caption_table->detail->num_rows - 1); i++)
+ gtk_table_set_row_spacing (GTK_TABLE (table), i, 10);
+ }
+}
+
+static int
+caption_table_index_of_entry (NautilusCaptionTable *caption_table,
+ GtkWidget* entry)
+{
+ guint i;
+
+ g_return_val_if_fail (caption_table != NULL, -1);
+ g_return_val_if_fail (NAUTILUS_IS_CAPTION_TABLE (caption_table), -1);
+
+ for(i = 0; i < caption_table->detail->num_rows; i++)
+ if (caption_table->detail->entries[i] == entry)
+ return i;
+
+ return -1;
+}
+
+static GtkWidget*
+caption_table_find_next_sensitive_entry (NautilusCaptionTable *caption_table,
+ guint index)
+{
+ guint i;
+
+ g_return_val_if_fail (caption_table != NULL, NULL);
+ g_return_val_if_fail (NAUTILUS_IS_CAPTION_TABLE (caption_table), NULL);
+
+ for(i = index; i < caption_table->detail->num_rows; i++)
+ if (GTK_WIDGET_SENSITIVE (caption_table->detail->entries[i]))
+ return caption_table->detail->entries[i];
+
+ return NULL;
+}
+
+static void
+entry_activate (GtkWidget *widget, gpointer data)
+{
+ NautilusCaptionTable *caption_table = NAUTILUS_CAPTION_TABLE (data);
+ int index;
+
+ g_return_if_fail (caption_table != NULL);
+ g_return_if_fail (NAUTILUS_IS_CAPTION_TABLE (caption_table));
+
+ index = caption_table_index_of_entry (caption_table, widget);
+
+ /* Check for an invalid index */
+ if (index == -1)
+ return;
+
+ /* Check for the last index */
+ if (index < caption_table->detail->num_rows)
+ {
+ /* Look for the next sensitive entry */
+ GtkWidget* sensitive_entry =
+ caption_table_find_next_sensitive_entry (caption_table, index + 1);
+
+ /* Make the next sensitive entry take focus */
+ if (sensitive_entry)
+ gtk_widget_grab_focus (sensitive_entry);
+ }
+
+ /* Emit the activate signal */
+ gtk_signal_emit (GTK_OBJECT (caption_table),
+ caption_table_signals[ACTIVATE],
+ index);
+}
+
+/* Public methods */
+GtkWidget*
+nautilus_caption_table_new (guint num_rows)
+{
+ GtkWidget *widget = GTK_WIDGET (gtk_type_new (nautilus_caption_table_get_type()));
+
+ if (num_rows == 0)
+ num_rows = 1;
+
+ caption_table_resize (NAUTILUS_CAPTION_TABLE(widget), num_rows);
+
+ gtk_table_set_col_spacing (GTK_TABLE (widget), 0, 10);
+
+ return widget;
+}
+
+void
+nautilus_caption_table_set_row_info (NautilusCaptionTable *caption_table,
+ guint row,
+ const char* label_text,
+ const char* entry_text,
+ gboolean entry_visibility,
+ gboolean entry_readonly)
+{
+ g_return_if_fail (caption_table != NULL);
+ g_return_if_fail (NAUTILUS_IS_CAPTION_TABLE (caption_table));
+ g_return_if_fail (row < caption_table->detail->num_rows);
+
+ gtk_label_set_text (GTK_LABEL (caption_table->detail->labels[row]), label_text);
+
+ gtk_entry_set_text (GTK_ENTRY (caption_table->detail->entries[row]), entry_text);
+ gtk_entry_set_visibility (GTK_ENTRY (caption_table->detail->entries[row]), entry_visibility);
+ gtk_widget_set_sensitive (caption_table->detail->entries[row], !entry_readonly);
+}
+
+void
+nautilus_caption_table_set_entry_text (NautilusCaptionTable *caption_table,
+ guint row,
+ const char* entry_text)
+{
+ g_return_if_fail (caption_table != NULL);
+ g_return_if_fail (NAUTILUS_IS_CAPTION_TABLE (caption_table));
+ g_return_if_fail (row < caption_table->detail->num_rows);
+
+ gtk_entry_set_text (GTK_ENTRY (caption_table->detail->entries[row]), entry_text);
+}
+
+void
+nautilus_caption_table_set_entry_readonly (NautilusCaptionTable *caption_table,
+ guint row,
+ gboolean readonly)
+{
+ g_return_if_fail (caption_table != NULL);
+ g_return_if_fail (NAUTILUS_IS_CAPTION_TABLE (caption_table));
+ g_return_if_fail (row < caption_table->detail->num_rows);
+
+ gtk_widget_set_sensitive (caption_table->detail->entries[row], !readonly);
+}
+
+void
+nautilus_caption_table_entry_grab_focus (NautilusCaptionTable *caption_table, guint row)
+{
+ g_return_if_fail (caption_table != NULL);
+ g_return_if_fail (NAUTILUS_IS_CAPTION_TABLE (caption_table));
+ g_return_if_fail (row < caption_table->detail->num_rows);
+
+ if (GTK_WIDGET_SENSITIVE (caption_table->detail->entries[row]))
+ gtk_widget_grab_focus (caption_table->detail->entries[row]);
+}
+
+char*
+nautilus_caption_table_get_entry_text (NautilusCaptionTable *caption_table, guint row)
+{
+ char *text;
+
+ g_return_val_if_fail (caption_table != NULL, NULL);
+ g_return_val_if_fail (NAUTILUS_IS_CAPTION_TABLE (caption_table), NULL);
+ g_return_val_if_fail (row < caption_table->detail->num_rows, NULL);
+
+ text = gtk_entry_get_text (GTK_ENTRY (caption_table->detail->entries[row]));
+
+ return g_strdup (text);
+}
+
+guint
+nautilus_caption_table_get_num_rows (NautilusCaptionTable *caption_table)
+{
+ g_return_val_if_fail (caption_table != NULL, 0);
+ g_return_val_if_fail (NAUTILUS_IS_CAPTION_TABLE (caption_table), 0);
+
+ return caption_table->detail->num_rows;
+}
diff --git a/libnautilus-extensions/nautilus-caption-table.h b/libnautilus-extensions/nautilus-caption-table.h
new file mode 100644
index 000000000..bc8235e12
--- /dev/null
+++ b/libnautilus-extensions/nautilus-caption-table.h
@@ -0,0 +1,89 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+
+/* nautilus-caption-table.h - An easy way to do tables of aligned captions.
+
+ Copyright (C) 1999, 2000 Eazel, Inc.
+
+ The Gnome Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Authors: Ramiro Estrugo <ramiro@eazel.com>
+*/
+
+#ifndef NAUTILUS_CAPTION_TABLE_H
+#define NAUTILUS_CAPTION_TABLE_H
+
+#include <gtk/gtktable.h>
+#include <gnome.h>
+
+/*
+ * NautilusCaptionTable is a GtkTable sublass that allows you to painlessly
+ * create tables of nicely aligned captions.
+ */
+
+BEGIN_GNOME_DECLS
+
+#define NAUTILUS_TYPE_CAPTION_TABLE (nautilus_caption_table_get_type ())
+#define NAUTILUS_CAPTION_TABLE(obj) (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_CAPTION_TABLE, NautilusCaptionTable))
+#define NAUTILUS_CAPTION_TABLE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_CAPTION_TABLE, NautilusCaptionTableClass))
+#define NAUTILUS_IS_CAPTION_TABLE(obj) (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_CAPTION_TABLE))
+#define NAUTILUS_IS_CAPTION_TABLE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_CAPTION_TABLE))
+
+
+typedef struct _NautilusCaptionTable NautilusCaptionTable;
+typedef struct _NautilusCaptionTableClass NautilusCaptionTableClass;
+typedef struct _NautilusCaptionTableDetail NautilusCaptionTableDetail;
+
+struct _NautilusCaptionTable
+{
+ GtkTable table;
+
+ NautilusCaptionTableDetail *detail;
+};
+
+struct _NautilusCaptionTableClass
+{
+ GtkTableClass parent_class;
+
+ void (*activate) (GtkWidget *caption_table, int active_entry);
+};
+
+
+GtkType nautilus_caption_table_get_type (void);
+GtkWidget* nautilus_caption_table_new (guint num_rows);
+void nautilus_caption_table_set_row_info (NautilusCaptionTable *caption_table,
+ guint row,
+ const char *label_text,
+ const char *entry_text,
+ gboolean entry_visibility,
+ gboolean entry_readonly);
+void nautilus_caption_table_set_entry_text (NautilusCaptionTable *caption_table,
+ guint row,
+ const char *entry_text);
+void nautilus_caption_table_set_entry_readonly (NautilusCaptionTable *caption_table,
+ guint row,
+ gboolean readonly);
+void nautilus_caption_table_entry_grab_focus (NautilusCaptionTable *caption_table,
+ guint row);
+char* nautilus_caption_table_get_entry_text (NautilusCaptionTable *caption_table,
+ guint row);
+guint nautilus_caption_table_get_num_rows (NautilusCaptionTable *caption_table);
+
+
+BEGIN_GNOME_DECLS
+
+#endif /* NAUTILUS_CAPTION_TABLE_H */
+
+
diff --git a/libnautilus-extensions/test-nautilus-widgets.c b/libnautilus-extensions/test-nautilus-widgets.c
index daee9e31c..a18f61c37 100644
--- a/libnautilus-extensions/test-nautilus-widgets.c
+++ b/libnautilus-extensions/test-nautilus-widgets.c
@@ -1,5 +1,6 @@
#include <nautilus-widgets/nautilus-radio-button-group.h>
+#include <nautilus-widgets/nautilus-caption-table.h>
#include <nautilus-widgets/nautilus-preferences-group.h>
#include <nautilus-widgets/nautilus-preferences-item.h>
#include <nautilus-widgets/nautilus-preferences.h>
@@ -7,14 +8,19 @@
#include <gtk/gtk.h>
#include <stdio.h>
-static void test_radio_group (void);
-static void test_preferences_group (void);
-static void test_preferences_item (void);
-static void test_radio_changed_signal (GtkWidget *button_group,
- gpointer user_data);
-static void register_global_preferences (void);
-GtkWidget * create_enum_item (const char *preference_name);
-GtkWidget * create_bool_item (const char *preference_name);
+static void test_radio_group (void);
+static void test_caption_table (void);
+static void test_preferences_group (void);
+static void test_preferences_item (void);
+static void test_radio_changed_callback (GtkWidget *button_group,
+ gpointer user_data);
+static void test_caption_table_activate_callback (GtkWidget *button_group,
+ gint active_index,
+ gpointer user_data);
+static void register_global_preferences (void);
+GtkWidget * create_enum_item (const char *preference_name);
+GtkWidget * create_bool_item (const char *preference_name);
+
enum
{
@@ -35,6 +41,7 @@ main (int argc, char * argv[])
register_global_preferences ();
test_radio_group ();
+ test_caption_table ();
test_preferences_group ();
test_preferences_item ();
@@ -60,7 +67,7 @@ test_radio_group (void)
gtk_signal_connect (GTK_OBJECT (buttons),
"changed",
- GTK_SIGNAL_FUNC (test_radio_changed_signal),
+ GTK_SIGNAL_FUNC (test_radio_changed_callback),
(gpointer) NULL);
gtk_container_add (GTK_CONTAINER (window), buttons);
@@ -71,6 +78,56 @@ test_radio_group (void)
}
static void
+test_caption_table (void)
+{
+ GtkWidget * window;
+ GtkWidget * table;
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+ table = nautilus_caption_table_new (4);
+
+ nautilus_caption_table_set_row_info (NAUTILUS_CAPTION_TABLE (table),
+ 0,
+ "Something",
+ "Text",
+ TRUE,
+ FALSE);
+
+ nautilus_caption_table_set_row_info (NAUTILUS_CAPTION_TABLE (table),
+ 1,
+ "ReadOnly",
+ "Cant Change Me",
+ TRUE,
+ TRUE);
+
+ nautilus_caption_table_set_row_info (NAUTILUS_CAPTION_TABLE (table),
+ 2,
+ "Password",
+ "sekret",
+ FALSE,
+ FALSE);
+
+ nautilus_caption_table_set_row_info (NAUTILUS_CAPTION_TABLE (table),
+ 3,
+ "This is a very long label",
+ "Text",
+ TRUE,
+ FALSE);
+
+ gtk_signal_connect (GTK_OBJECT (table),
+ "activate",
+ GTK_SIGNAL_FUNC (test_caption_table_activate_callback),
+ (gpointer) NULL);
+
+ gtk_container_add (GTK_CONTAINER (window), table);
+
+ gtk_widget_show (table);
+
+ gtk_widget_show (window);
+}
+
+static void
test_preferences_item (void)
{
GtkWidget * window;
@@ -109,13 +166,21 @@ test_preferences_group (void)
}
static void
-test_radio_changed_signal (GtkWidget *buttons, gpointer user_data)
+test_radio_changed_callback (GtkWidget *buttons, gpointer user_data)
{
gint i;
i = nautilus_radio_button_group_get_active_index (NAUTILUS_RADIO_BUTTON_GROUP (buttons));
- printf ("test_radio_changed_signal (%d)\n", i);
+ g_print ("test_radio_changed_callback (%d)\n", i);
+}
+
+static void
+test_caption_table_activate_callback (GtkWidget *button_group,
+ gint active_index,
+ gpointer user_data)
+{
+ g_print ("test_caption_table_activate_callback (active_index=%d)\n", active_index);
}
GtkWidget *
diff --git a/libnautilus-private/nautilus-caption-table.c b/libnautilus-private/nautilus-caption-table.c
new file mode 100644
index 000000000..1eb8affa2
--- /dev/null
+++ b/libnautilus-private/nautilus-caption-table.c
@@ -0,0 +1,400 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+
+/* nautilus-caption-table.c - An easy way to do tables of aligned captions.
+
+ Copyright (C) 1999, 2000 Eazel, Inc.
+
+ The Gnome Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Authors: Ramiro Estrugo <ramiro@eazel.com>
+*/
+
+#include "nautilus-caption-table.h"
+
+#include <gtk/gtkentry.h>
+#include <gtk/gtksignal.h>
+#include <gtk/gtklabel.h>
+#include <libnautilus-extensions/nautilus-gtk-macros.h>
+
+struct _NautilusCaptionTableDetail
+{
+ GtkWidget **labels;
+ GtkWidget **entries;
+ guint num_rows;
+ guint size;
+};
+
+enum
+{
+ ACTIVATE,
+ LAST_SIGNAL
+};
+
+/* NautilusCaptionTableClass methods */
+static void nautilus_caption_table_initialize_class (NautilusCaptionTableClass *klass);
+static void nautilus_caption_table_initialize (NautilusCaptionTable *caption_table);
+
+/* GtkObjectClass methods */
+static void caption_table_destroy (GtkObject *object);
+
+/* Private methods */
+static void caption_table_resize (NautilusCaptionTable *caption_table,
+ guint num_rows);
+static GtkWidget* caption_table_find_next_sensitive_entry (NautilusCaptionTable *caption_table,
+ guint index);
+static int caption_table_index_of_entry (NautilusCaptionTable *caption_table,
+ GtkWidget *entry);
+
+/* Entry callbacks */
+static void entry_activate (GtkWidget *widget,
+ gpointer data);
+
+/* Boilerplate stuff */
+NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusCaptionTable,
+ nautilus_caption_table,
+ GTK_TYPE_TABLE)
+
+static int caption_table_signals[LAST_SIGNAL] = { 0 };
+
+static void
+nautilus_caption_table_initialize_class (NautilusCaptionTableClass *klass)
+{
+ GtkObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+
+ object_class = GTK_OBJECT_CLASS (klass);
+ widget_class = GTK_WIDGET_CLASS (klass);
+
+ parent_class = gtk_type_class (GTK_TYPE_TABLE);
+
+ caption_table_signals[ACTIVATE] =
+ gtk_signal_new ("activate",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (NautilusCaptionTableClass, activate),
+ gtk_marshal_NONE__INT,
+ GTK_TYPE_NONE, 1, GTK_TYPE_INT);
+
+ gtk_object_class_add_signals (object_class, caption_table_signals, LAST_SIGNAL);
+
+ /* GtkObjectClass */
+ object_class->destroy = caption_table_destroy;
+}
+
+#define CAPTION_TABLE_DEFAULT_ROWS 1
+
+static void
+nautilus_caption_table_initialize (NautilusCaptionTable * caption_table)
+{
+ GtkTable *table = GTK_TABLE (caption_table);
+
+ caption_table->detail = g_new (NautilusCaptionTableDetail, 1);
+
+ caption_table->detail->num_rows = 0;
+
+ caption_table->detail->size = 0;
+
+ caption_table->detail->labels = NULL;
+ caption_table->detail->entries = NULL;
+
+ table->homogeneous = FALSE;
+}
+
+/* GtkObjectClass methods */
+static void
+caption_table_destroy (GtkObject *object)
+{
+ NautilusCaptionTable *caption_table;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (NAUTILUS_IS_CAPTION_TABLE (object));
+
+ caption_table = NAUTILUS_CAPTION_TABLE (object);
+
+ if (caption_table->detail->labels)
+ g_free(caption_table->detail->labels);
+
+ if (caption_table->detail->entries)
+ g_free(caption_table->detail->entries);
+
+ g_free (caption_table->detail);
+
+ if (GTK_OBJECT_CLASS (parent_class)->destroy)
+ (*GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+/* FIXME: This should be public for the widget to be useful */
+static void
+caption_table_resize (NautilusCaptionTable *caption_table,
+ guint num_rows)
+{
+ GtkTable* table = NULL;
+
+ g_return_if_fail (caption_table != NULL);
+ g_return_if_fail (NAUTILUS_IS_CAPTION_TABLE (caption_table));
+
+ /* Make sure the num_rows have changed */
+ if (caption_table->detail->num_rows == num_rows)
+ return;
+
+ caption_table->detail->num_rows = num_rows;
+
+ /* Resize the GtkTable */
+ table = GTK_TABLE (caption_table);
+ gtk_table_resize(table, caption_table->detail->num_rows, 2);
+
+ /* Create more label/entry pairs if needed */
+ if (caption_table->detail->num_rows > caption_table->detail->size)
+ {
+ guint i;
+ guint old_size = caption_table->detail->size;
+ guint new_size = caption_table->detail->num_rows;
+ guint realloc_size = sizeof(GtkWidget *) * new_size;
+
+ /* FIXME: Use a GList for this */
+ caption_table->detail->labels = (GtkWidget**) g_realloc (caption_table->detail->labels,
+ realloc_size);
+
+ caption_table->detail->entries = (GtkWidget**) g_realloc (caption_table->detail->entries,
+ realloc_size);
+
+ for (i = old_size; i < new_size; i++)
+ {
+ caption_table->detail->labels[i] = gtk_label_new("");
+ caption_table->detail->entries[i] = gtk_entry_new();
+
+ gtk_signal_connect(GTK_OBJECT (caption_table->detail->entries[i]),
+ "activate",
+ GTK_SIGNAL_FUNC(entry_activate),
+ (gpointer) caption_table);
+
+ gtk_misc_set_alignment(GTK_MISC(caption_table->detail->labels[i]), 1.0, 0.5);
+
+ /* Column 1 */
+ gtk_table_attach(table,
+ caption_table->detail->labels[i], /* child */
+ 0, /* left_attatch */
+ 1, /* right_attatch */
+ i, /* top_attatch */
+ i + 1, /* bottom_attatch */
+ GTK_FILL, /* xoptions */
+ (GTK_FILL|GTK_EXPAND), /* yoptions */
+ 0, /* xpadding */
+ 0); /* ypadding */
+
+ /* Column 2 */
+ gtk_table_attach(table,
+ caption_table->detail->entries[i], /* child */
+ 1, /* left_attatch */
+ 2, /* right_attatch */
+ i, /* top_attatch */
+ i + 1, /* bottom_attatch */
+ (GTK_FILL|GTK_EXPAND), /* xoptions */
+ (GTK_FILL|GTK_EXPAND), /* yoptions */
+ 0, /* xpadding */
+ 0); /* ypadding */
+ }
+
+ caption_table->detail->size = new_size;
+ }
+
+ /* Show only the needed caption widgets */
+ if (caption_table->detail->size > 0)
+ {
+ guint i;
+
+ for(i = 0; i < caption_table->detail->size; i++)
+ {
+ if (i < caption_table->detail->num_rows)
+ {
+ gtk_widget_show (caption_table->detail->labels[i]);
+ gtk_widget_show (caption_table->detail->entries[i]);
+ }
+ else
+ {
+ gtk_widget_hide (caption_table->detail->labels[i]);
+ gtk_widget_hide (caption_table->detail->entries[i]);
+ }
+ }
+ }
+
+ /* Set inter row spacing */
+ if (caption_table->detail->num_rows > 1)
+ {
+ guint i;
+
+ for(i = 0; i < (caption_table->detail->num_rows - 1); i++)
+ gtk_table_set_row_spacing (GTK_TABLE (table), i, 10);
+ }
+}
+
+static int
+caption_table_index_of_entry (NautilusCaptionTable *caption_table,
+ GtkWidget* entry)
+{
+ guint i;
+
+ g_return_val_if_fail (caption_table != NULL, -1);
+ g_return_val_if_fail (NAUTILUS_IS_CAPTION_TABLE (caption_table), -1);
+
+ for(i = 0; i < caption_table->detail->num_rows; i++)
+ if (caption_table->detail->entries[i] == entry)
+ return i;
+
+ return -1;
+}
+
+static GtkWidget*
+caption_table_find_next_sensitive_entry (NautilusCaptionTable *caption_table,
+ guint index)
+{
+ guint i;
+
+ g_return_val_if_fail (caption_table != NULL, NULL);
+ g_return_val_if_fail (NAUTILUS_IS_CAPTION_TABLE (caption_table), NULL);
+
+ for(i = index; i < caption_table->detail->num_rows; i++)
+ if (GTK_WIDGET_SENSITIVE (caption_table->detail->entries[i]))
+ return caption_table->detail->entries[i];
+
+ return NULL;
+}
+
+static void
+entry_activate (GtkWidget *widget, gpointer data)
+{
+ NautilusCaptionTable *caption_table = NAUTILUS_CAPTION_TABLE (data);
+ int index;
+
+ g_return_if_fail (caption_table != NULL);
+ g_return_if_fail (NAUTILUS_IS_CAPTION_TABLE (caption_table));
+
+ index = caption_table_index_of_entry (caption_table, widget);
+
+ /* Check for an invalid index */
+ if (index == -1)
+ return;
+
+ /* Check for the last index */
+ if (index < caption_table->detail->num_rows)
+ {
+ /* Look for the next sensitive entry */
+ GtkWidget* sensitive_entry =
+ caption_table_find_next_sensitive_entry (caption_table, index + 1);
+
+ /* Make the next sensitive entry take focus */
+ if (sensitive_entry)
+ gtk_widget_grab_focus (sensitive_entry);
+ }
+
+ /* Emit the activate signal */
+ gtk_signal_emit (GTK_OBJECT (caption_table),
+ caption_table_signals[ACTIVATE],
+ index);
+}
+
+/* Public methods */
+GtkWidget*
+nautilus_caption_table_new (guint num_rows)
+{
+ GtkWidget *widget = GTK_WIDGET (gtk_type_new (nautilus_caption_table_get_type()));
+
+ if (num_rows == 0)
+ num_rows = 1;
+
+ caption_table_resize (NAUTILUS_CAPTION_TABLE(widget), num_rows);
+
+ gtk_table_set_col_spacing (GTK_TABLE (widget), 0, 10);
+
+ return widget;
+}
+
+void
+nautilus_caption_table_set_row_info (NautilusCaptionTable *caption_table,
+ guint row,
+ const char* label_text,
+ const char* entry_text,
+ gboolean entry_visibility,
+ gboolean entry_readonly)
+{
+ g_return_if_fail (caption_table != NULL);
+ g_return_if_fail (NAUTILUS_IS_CAPTION_TABLE (caption_table));
+ g_return_if_fail (row < caption_table->detail->num_rows);
+
+ gtk_label_set_text (GTK_LABEL (caption_table->detail->labels[row]), label_text);
+
+ gtk_entry_set_text (GTK_ENTRY (caption_table->detail->entries[row]), entry_text);
+ gtk_entry_set_visibility (GTK_ENTRY (caption_table->detail->entries[row]), entry_visibility);
+ gtk_widget_set_sensitive (caption_table->detail->entries[row], !entry_readonly);
+}
+
+void
+nautilus_caption_table_set_entry_text (NautilusCaptionTable *caption_table,
+ guint row,
+ const char* entry_text)
+{
+ g_return_if_fail (caption_table != NULL);
+ g_return_if_fail (NAUTILUS_IS_CAPTION_TABLE (caption_table));
+ g_return_if_fail (row < caption_table->detail->num_rows);
+
+ gtk_entry_set_text (GTK_ENTRY (caption_table->detail->entries[row]), entry_text);
+}
+
+void
+nautilus_caption_table_set_entry_readonly (NautilusCaptionTable *caption_table,
+ guint row,
+ gboolean readonly)
+{
+ g_return_if_fail (caption_table != NULL);
+ g_return_if_fail (NAUTILUS_IS_CAPTION_TABLE (caption_table));
+ g_return_if_fail (row < caption_table->detail->num_rows);
+
+ gtk_widget_set_sensitive (caption_table->detail->entries[row], !readonly);
+}
+
+void
+nautilus_caption_table_entry_grab_focus (NautilusCaptionTable *caption_table, guint row)
+{
+ g_return_if_fail (caption_table != NULL);
+ g_return_if_fail (NAUTILUS_IS_CAPTION_TABLE (caption_table));
+ g_return_if_fail (row < caption_table->detail->num_rows);
+
+ if (GTK_WIDGET_SENSITIVE (caption_table->detail->entries[row]))
+ gtk_widget_grab_focus (caption_table->detail->entries[row]);
+}
+
+char*
+nautilus_caption_table_get_entry_text (NautilusCaptionTable *caption_table, guint row)
+{
+ char *text;
+
+ g_return_val_if_fail (caption_table != NULL, NULL);
+ g_return_val_if_fail (NAUTILUS_IS_CAPTION_TABLE (caption_table), NULL);
+ g_return_val_if_fail (row < caption_table->detail->num_rows, NULL);
+
+ text = gtk_entry_get_text (GTK_ENTRY (caption_table->detail->entries[row]));
+
+ return g_strdup (text);
+}
+
+guint
+nautilus_caption_table_get_num_rows (NautilusCaptionTable *caption_table)
+{
+ g_return_val_if_fail (caption_table != NULL, 0);
+ g_return_val_if_fail (NAUTILUS_IS_CAPTION_TABLE (caption_table), 0);
+
+ return caption_table->detail->num_rows;
+}
diff --git a/libnautilus-private/nautilus-caption-table.h b/libnautilus-private/nautilus-caption-table.h
new file mode 100644
index 000000000..bc8235e12
--- /dev/null
+++ b/libnautilus-private/nautilus-caption-table.h
@@ -0,0 +1,89 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+
+/* nautilus-caption-table.h - An easy way to do tables of aligned captions.
+
+ Copyright (C) 1999, 2000 Eazel, Inc.
+
+ The Gnome Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Authors: Ramiro Estrugo <ramiro@eazel.com>
+*/
+
+#ifndef NAUTILUS_CAPTION_TABLE_H
+#define NAUTILUS_CAPTION_TABLE_H
+
+#include <gtk/gtktable.h>
+#include <gnome.h>
+
+/*
+ * NautilusCaptionTable is a GtkTable sublass that allows you to painlessly
+ * create tables of nicely aligned captions.
+ */
+
+BEGIN_GNOME_DECLS
+
+#define NAUTILUS_TYPE_CAPTION_TABLE (nautilus_caption_table_get_type ())
+#define NAUTILUS_CAPTION_TABLE(obj) (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_CAPTION_TABLE, NautilusCaptionTable))
+#define NAUTILUS_CAPTION_TABLE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_CAPTION_TABLE, NautilusCaptionTableClass))
+#define NAUTILUS_IS_CAPTION_TABLE(obj) (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_CAPTION_TABLE))
+#define NAUTILUS_IS_CAPTION_TABLE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_CAPTION_TABLE))
+
+
+typedef struct _NautilusCaptionTable NautilusCaptionTable;
+typedef struct _NautilusCaptionTableClass NautilusCaptionTableClass;
+typedef struct _NautilusCaptionTableDetail NautilusCaptionTableDetail;
+
+struct _NautilusCaptionTable
+{
+ GtkTable table;
+
+ NautilusCaptionTableDetail *detail;
+};
+
+struct _NautilusCaptionTableClass
+{
+ GtkTableClass parent_class;
+
+ void (*activate) (GtkWidget *caption_table, int active_entry);
+};
+
+
+GtkType nautilus_caption_table_get_type (void);
+GtkWidget* nautilus_caption_table_new (guint num_rows);
+void nautilus_caption_table_set_row_info (NautilusCaptionTable *caption_table,
+ guint row,
+ const char *label_text,
+ const char *entry_text,
+ gboolean entry_visibility,
+ gboolean entry_readonly);
+void nautilus_caption_table_set_entry_text (NautilusCaptionTable *caption_table,
+ guint row,
+ const char *entry_text);
+void nautilus_caption_table_set_entry_readonly (NautilusCaptionTable *caption_table,
+ guint row,
+ gboolean readonly);
+void nautilus_caption_table_entry_grab_focus (NautilusCaptionTable *caption_table,
+ guint row);
+char* nautilus_caption_table_get_entry_text (NautilusCaptionTable *caption_table,
+ guint row);
+guint nautilus_caption_table_get_num_rows (NautilusCaptionTable *caption_table);
+
+
+BEGIN_GNOME_DECLS
+
+#endif /* NAUTILUS_CAPTION_TABLE_H */
+
+
diff --git a/libnautilus-private/test-nautilus-widgets.c b/libnautilus-private/test-nautilus-widgets.c
index daee9e31c..a18f61c37 100644
--- a/libnautilus-private/test-nautilus-widgets.c
+++ b/libnautilus-private/test-nautilus-widgets.c
@@ -1,5 +1,6 @@
#include <nautilus-widgets/nautilus-radio-button-group.h>
+#include <nautilus-widgets/nautilus-caption-table.h>
#include <nautilus-widgets/nautilus-preferences-group.h>
#include <nautilus-widgets/nautilus-preferences-item.h>
#include <nautilus-widgets/nautilus-preferences.h>
@@ -7,14 +8,19 @@
#include <gtk/gtk.h>
#include <stdio.h>
-static void test_radio_group (void);
-static void test_preferences_group (void);
-static void test_preferences_item (void);
-static void test_radio_changed_signal (GtkWidget *button_group,
- gpointer user_data);
-static void register_global_preferences (void);
-GtkWidget * create_enum_item (const char *preference_name);
-GtkWidget * create_bool_item (const char *preference_name);
+static void test_radio_group (void);
+static void test_caption_table (void);
+static void test_preferences_group (void);
+static void test_preferences_item (void);
+static void test_radio_changed_callback (GtkWidget *button_group,
+ gpointer user_data);
+static void test_caption_table_activate_callback (GtkWidget *button_group,
+ gint active_index,
+ gpointer user_data);
+static void register_global_preferences (void);
+GtkWidget * create_enum_item (const char *preference_name);
+GtkWidget * create_bool_item (const char *preference_name);
+
enum
{
@@ -35,6 +41,7 @@ main (int argc, char * argv[])
register_global_preferences ();
test_radio_group ();
+ test_caption_table ();
test_preferences_group ();
test_preferences_item ();
@@ -60,7 +67,7 @@ test_radio_group (void)
gtk_signal_connect (GTK_OBJECT (buttons),
"changed",
- GTK_SIGNAL_FUNC (test_radio_changed_signal),
+ GTK_SIGNAL_FUNC (test_radio_changed_callback),
(gpointer) NULL);
gtk_container_add (GTK_CONTAINER (window), buttons);
@@ -71,6 +78,56 @@ test_radio_group (void)
}
static void
+test_caption_table (void)
+{
+ GtkWidget * window;
+ GtkWidget * table;
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+ table = nautilus_caption_table_new (4);
+
+ nautilus_caption_table_set_row_info (NAUTILUS_CAPTION_TABLE (table),
+ 0,
+ "Something",
+ "Text",
+ TRUE,
+ FALSE);
+
+ nautilus_caption_table_set_row_info (NAUTILUS_CAPTION_TABLE (table),
+ 1,
+ "ReadOnly",
+ "Cant Change Me",
+ TRUE,
+ TRUE);
+
+ nautilus_caption_table_set_row_info (NAUTILUS_CAPTION_TABLE (table),
+ 2,
+ "Password",
+ "sekret",
+ FALSE,
+ FALSE);
+
+ nautilus_caption_table_set_row_info (NAUTILUS_CAPTION_TABLE (table),
+ 3,
+ "This is a very long label",
+ "Text",
+ TRUE,
+ FALSE);
+
+ gtk_signal_connect (GTK_OBJECT (table),
+ "activate",
+ GTK_SIGNAL_FUNC (test_caption_table_activate_callback),
+ (gpointer) NULL);
+
+ gtk_container_add (GTK_CONTAINER (window), table);
+
+ gtk_widget_show (table);
+
+ gtk_widget_show (window);
+}
+
+static void
test_preferences_item (void)
{
GtkWidget * window;
@@ -109,13 +166,21 @@ test_preferences_group (void)
}
static void
-test_radio_changed_signal (GtkWidget *buttons, gpointer user_data)
+test_radio_changed_callback (GtkWidget *buttons, gpointer user_data)
{
gint i;
i = nautilus_radio_button_group_get_active_index (NAUTILUS_RADIO_BUTTON_GROUP (buttons));
- printf ("test_radio_changed_signal (%d)\n", i);
+ g_print ("test_radio_changed_callback (%d)\n", i);
+}
+
+static void
+test_caption_table_activate_callback (GtkWidget *button_group,
+ gint active_index,
+ gpointer user_data)
+{
+ g_print ("test_caption_table_activate_callback (active_index=%d)\n", active_index);
}
GtkWidget *
diff --git a/nautilus-widgets/Makefile.am b/nautilus-widgets/Makefile.am
index 9145098c4..a94b116aa 100644
--- a/nautilus-widgets/Makefile.am
+++ b/nautilus-widgets/Makefile.am
@@ -24,6 +24,7 @@ libnautilus_widgets_la_LDFLAGS=\
libnautilus_widgetsincludedir=$(includedir)/nautilus-widgets
libnautilus_widgetsinclude_HEADERS =\
+ nautilus-caption-table.h \
nautilus-preference.h \
nautilus-preferences-box.h \
nautilus-preferences-dialog.h \
@@ -35,6 +36,7 @@ libnautilus_widgetsinclude_HEADERS =\
$(NULL)
libnautilus_widgets_la_SOURCES =\
+ nautilus-caption-table.c \
nautilus-preference.c \
nautilus-preferences-box.c \
nautilus-preferences-dialog.c \
diff --git a/nautilus-widgets/nautilus-caption-table.c b/nautilus-widgets/nautilus-caption-table.c
new file mode 100644
index 000000000..1eb8affa2
--- /dev/null
+++ b/nautilus-widgets/nautilus-caption-table.c
@@ -0,0 +1,400 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+
+/* nautilus-caption-table.c - An easy way to do tables of aligned captions.
+
+ Copyright (C) 1999, 2000 Eazel, Inc.
+
+ The Gnome Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Authors: Ramiro Estrugo <ramiro@eazel.com>
+*/
+
+#include "nautilus-caption-table.h"
+
+#include <gtk/gtkentry.h>
+#include <gtk/gtksignal.h>
+#include <gtk/gtklabel.h>
+#include <libnautilus-extensions/nautilus-gtk-macros.h>
+
+struct _NautilusCaptionTableDetail
+{
+ GtkWidget **labels;
+ GtkWidget **entries;
+ guint num_rows;
+ guint size;
+};
+
+enum
+{
+ ACTIVATE,
+ LAST_SIGNAL
+};
+
+/* NautilusCaptionTableClass methods */
+static void nautilus_caption_table_initialize_class (NautilusCaptionTableClass *klass);
+static void nautilus_caption_table_initialize (NautilusCaptionTable *caption_table);
+
+/* GtkObjectClass methods */
+static void caption_table_destroy (GtkObject *object);
+
+/* Private methods */
+static void caption_table_resize (NautilusCaptionTable *caption_table,
+ guint num_rows);
+static GtkWidget* caption_table_find_next_sensitive_entry (NautilusCaptionTable *caption_table,
+ guint index);
+static int caption_table_index_of_entry (NautilusCaptionTable *caption_table,
+ GtkWidget *entry);
+
+/* Entry callbacks */
+static void entry_activate (GtkWidget *widget,
+ gpointer data);
+
+/* Boilerplate stuff */
+NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusCaptionTable,
+ nautilus_caption_table,
+ GTK_TYPE_TABLE)
+
+static int caption_table_signals[LAST_SIGNAL] = { 0 };
+
+static void
+nautilus_caption_table_initialize_class (NautilusCaptionTableClass *klass)
+{
+ GtkObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+
+ object_class = GTK_OBJECT_CLASS (klass);
+ widget_class = GTK_WIDGET_CLASS (klass);
+
+ parent_class = gtk_type_class (GTK_TYPE_TABLE);
+
+ caption_table_signals[ACTIVATE] =
+ gtk_signal_new ("activate",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (NautilusCaptionTableClass, activate),
+ gtk_marshal_NONE__INT,
+ GTK_TYPE_NONE, 1, GTK_TYPE_INT);
+
+ gtk_object_class_add_signals (object_class, caption_table_signals, LAST_SIGNAL);
+
+ /* GtkObjectClass */
+ object_class->destroy = caption_table_destroy;
+}
+
+#define CAPTION_TABLE_DEFAULT_ROWS 1
+
+static void
+nautilus_caption_table_initialize (NautilusCaptionTable * caption_table)
+{
+ GtkTable *table = GTK_TABLE (caption_table);
+
+ caption_table->detail = g_new (NautilusCaptionTableDetail, 1);
+
+ caption_table->detail->num_rows = 0;
+
+ caption_table->detail->size = 0;
+
+ caption_table->detail->labels = NULL;
+ caption_table->detail->entries = NULL;
+
+ table->homogeneous = FALSE;
+}
+
+/* GtkObjectClass methods */
+static void
+caption_table_destroy (GtkObject *object)
+{
+ NautilusCaptionTable *caption_table;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (NAUTILUS_IS_CAPTION_TABLE (object));
+
+ caption_table = NAUTILUS_CAPTION_TABLE (object);
+
+ if (caption_table->detail->labels)
+ g_free(caption_table->detail->labels);
+
+ if (caption_table->detail->entries)
+ g_free(caption_table->detail->entries);
+
+ g_free (caption_table->detail);
+
+ if (GTK_OBJECT_CLASS (parent_class)->destroy)
+ (*GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+/* FIXME: This should be public for the widget to be useful */
+static void
+caption_table_resize (NautilusCaptionTable *caption_table,
+ guint num_rows)
+{
+ GtkTable* table = NULL;
+
+ g_return_if_fail (caption_table != NULL);
+ g_return_if_fail (NAUTILUS_IS_CAPTION_TABLE (caption_table));
+
+ /* Make sure the num_rows have changed */
+ if (caption_table->detail->num_rows == num_rows)
+ return;
+
+ caption_table->detail->num_rows = num_rows;
+
+ /* Resize the GtkTable */
+ table = GTK_TABLE (caption_table);
+ gtk_table_resize(table, caption_table->detail->num_rows, 2);
+
+ /* Create more label/entry pairs if needed */
+ if (caption_table->detail->num_rows > caption_table->detail->size)
+ {
+ guint i;
+ guint old_size = caption_table->detail->size;
+ guint new_size = caption_table->detail->num_rows;
+ guint realloc_size = sizeof(GtkWidget *) * new_size;
+
+ /* FIXME: Use a GList for this */
+ caption_table->detail->labels = (GtkWidget**) g_realloc (caption_table->detail->labels,
+ realloc_size);
+
+ caption_table->detail->entries = (GtkWidget**) g_realloc (caption_table->detail->entries,
+ realloc_size);
+
+ for (i = old_size; i < new_size; i++)
+ {
+ caption_table->detail->labels[i] = gtk_label_new("");
+ caption_table->detail->entries[i] = gtk_entry_new();
+
+ gtk_signal_connect(GTK_OBJECT (caption_table->detail->entries[i]),
+ "activate",
+ GTK_SIGNAL_FUNC(entry_activate),
+ (gpointer) caption_table);
+
+ gtk_misc_set_alignment(GTK_MISC(caption_table->detail->labels[i]), 1.0, 0.5);
+
+ /* Column 1 */
+ gtk_table_attach(table,
+ caption_table->detail->labels[i], /* child */
+ 0, /* left_attatch */
+ 1, /* right_attatch */
+ i, /* top_attatch */
+ i + 1, /* bottom_attatch */
+ GTK_FILL, /* xoptions */
+ (GTK_FILL|GTK_EXPAND), /* yoptions */
+ 0, /* xpadding */
+ 0); /* ypadding */
+
+ /* Column 2 */
+ gtk_table_attach(table,
+ caption_table->detail->entries[i], /* child */
+ 1, /* left_attatch */
+ 2, /* right_attatch */
+ i, /* top_attatch */
+ i + 1, /* bottom_attatch */
+ (GTK_FILL|GTK_EXPAND), /* xoptions */
+ (GTK_FILL|GTK_EXPAND), /* yoptions */
+ 0, /* xpadding */
+ 0); /* ypadding */
+ }
+
+ caption_table->detail->size = new_size;
+ }
+
+ /* Show only the needed caption widgets */
+ if (caption_table->detail->size > 0)
+ {
+ guint i;
+
+ for(i = 0; i < caption_table->detail->size; i++)
+ {
+ if (i < caption_table->detail->num_rows)
+ {
+ gtk_widget_show (caption_table->detail->labels[i]);
+ gtk_widget_show (caption_table->detail->entries[i]);
+ }
+ else
+ {
+ gtk_widget_hide (caption_table->detail->labels[i]);
+ gtk_widget_hide (caption_table->detail->entries[i]);
+ }
+ }
+ }
+
+ /* Set inter row spacing */
+ if (caption_table->detail->num_rows > 1)
+ {
+ guint i;
+
+ for(i = 0; i < (caption_table->detail->num_rows - 1); i++)
+ gtk_table_set_row_spacing (GTK_TABLE (table), i, 10);
+ }
+}
+
+static int
+caption_table_index_of_entry (NautilusCaptionTable *caption_table,
+ GtkWidget* entry)
+{
+ guint i;
+
+ g_return_val_if_fail (caption_table != NULL, -1);
+ g_return_val_if_fail (NAUTILUS_IS_CAPTION_TABLE (caption_table), -1);
+
+ for(i = 0; i < caption_table->detail->num_rows; i++)
+ if (caption_table->detail->entries[i] == entry)
+ return i;
+
+ return -1;
+}
+
+static GtkWidget*
+caption_table_find_next_sensitive_entry (NautilusCaptionTable *caption_table,
+ guint index)
+{
+ guint i;
+
+ g_return_val_if_fail (caption_table != NULL, NULL);
+ g_return_val_if_fail (NAUTILUS_IS_CAPTION_TABLE (caption_table), NULL);
+
+ for(i = index; i < caption_table->detail->num_rows; i++)
+ if (GTK_WIDGET_SENSITIVE (caption_table->detail->entries[i]))
+ return caption_table->detail->entries[i];
+
+ return NULL;
+}
+
+static void
+entry_activate (GtkWidget *widget, gpointer data)
+{
+ NautilusCaptionTable *caption_table = NAUTILUS_CAPTION_TABLE (data);
+ int index;
+
+ g_return_if_fail (caption_table != NULL);
+ g_return_if_fail (NAUTILUS_IS_CAPTION_TABLE (caption_table));
+
+ index = caption_table_index_of_entry (caption_table, widget);
+
+ /* Check for an invalid index */
+ if (index == -1)
+ return;
+
+ /* Check for the last index */
+ if (index < caption_table->detail->num_rows)
+ {
+ /* Look for the next sensitive entry */
+ GtkWidget* sensitive_entry =
+ caption_table_find_next_sensitive_entry (caption_table, index + 1);
+
+ /* Make the next sensitive entry take focus */
+ if (sensitive_entry)
+ gtk_widget_grab_focus (sensitive_entry);
+ }
+
+ /* Emit the activate signal */
+ gtk_signal_emit (GTK_OBJECT (caption_table),
+ caption_table_signals[ACTIVATE],
+ index);
+}
+
+/* Public methods */
+GtkWidget*
+nautilus_caption_table_new (guint num_rows)
+{
+ GtkWidget *widget = GTK_WIDGET (gtk_type_new (nautilus_caption_table_get_type()));
+
+ if (num_rows == 0)
+ num_rows = 1;
+
+ caption_table_resize (NAUTILUS_CAPTION_TABLE(widget), num_rows);
+
+ gtk_table_set_col_spacing (GTK_TABLE (widget), 0, 10);
+
+ return widget;
+}
+
+void
+nautilus_caption_table_set_row_info (NautilusCaptionTable *caption_table,
+ guint row,
+ const char* label_text,
+ const char* entry_text,
+ gboolean entry_visibility,
+ gboolean entry_readonly)
+{
+ g_return_if_fail (caption_table != NULL);
+ g_return_if_fail (NAUTILUS_IS_CAPTION_TABLE (caption_table));
+ g_return_if_fail (row < caption_table->detail->num_rows);
+
+ gtk_label_set_text (GTK_LABEL (caption_table->detail->labels[row]), label_text);
+
+ gtk_entry_set_text (GTK_ENTRY (caption_table->detail->entries[row]), entry_text);
+ gtk_entry_set_visibility (GTK_ENTRY (caption_table->detail->entries[row]), entry_visibility);
+ gtk_widget_set_sensitive (caption_table->detail->entries[row], !entry_readonly);
+}
+
+void
+nautilus_caption_table_set_entry_text (NautilusCaptionTable *caption_table,
+ guint row,
+ const char* entry_text)
+{
+ g_return_if_fail (caption_table != NULL);
+ g_return_if_fail (NAUTILUS_IS_CAPTION_TABLE (caption_table));
+ g_return_if_fail (row < caption_table->detail->num_rows);
+
+ gtk_entry_set_text (GTK_ENTRY (caption_table->detail->entries[row]), entry_text);
+}
+
+void
+nautilus_caption_table_set_entry_readonly (NautilusCaptionTable *caption_table,
+ guint row,
+ gboolean readonly)
+{
+ g_return_if_fail (caption_table != NULL);
+ g_return_if_fail (NAUTILUS_IS_CAPTION_TABLE (caption_table));
+ g_return_if_fail (row < caption_table->detail->num_rows);
+
+ gtk_widget_set_sensitive (caption_table->detail->entries[row], !readonly);
+}
+
+void
+nautilus_caption_table_entry_grab_focus (NautilusCaptionTable *caption_table, guint row)
+{
+ g_return_if_fail (caption_table != NULL);
+ g_return_if_fail (NAUTILUS_IS_CAPTION_TABLE (caption_table));
+ g_return_if_fail (row < caption_table->detail->num_rows);
+
+ if (GTK_WIDGET_SENSITIVE (caption_table->detail->entries[row]))
+ gtk_widget_grab_focus (caption_table->detail->entries[row]);
+}
+
+char*
+nautilus_caption_table_get_entry_text (NautilusCaptionTable *caption_table, guint row)
+{
+ char *text;
+
+ g_return_val_if_fail (caption_table != NULL, NULL);
+ g_return_val_if_fail (NAUTILUS_IS_CAPTION_TABLE (caption_table), NULL);
+ g_return_val_if_fail (row < caption_table->detail->num_rows, NULL);
+
+ text = gtk_entry_get_text (GTK_ENTRY (caption_table->detail->entries[row]));
+
+ return g_strdup (text);
+}
+
+guint
+nautilus_caption_table_get_num_rows (NautilusCaptionTable *caption_table)
+{
+ g_return_val_if_fail (caption_table != NULL, 0);
+ g_return_val_if_fail (NAUTILUS_IS_CAPTION_TABLE (caption_table), 0);
+
+ return caption_table->detail->num_rows;
+}
diff --git a/nautilus-widgets/nautilus-caption-table.h b/nautilus-widgets/nautilus-caption-table.h
new file mode 100644
index 000000000..bc8235e12
--- /dev/null
+++ b/nautilus-widgets/nautilus-caption-table.h
@@ -0,0 +1,89 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+
+/* nautilus-caption-table.h - An easy way to do tables of aligned captions.
+
+ Copyright (C) 1999, 2000 Eazel, Inc.
+
+ The Gnome Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Authors: Ramiro Estrugo <ramiro@eazel.com>
+*/
+
+#ifndef NAUTILUS_CAPTION_TABLE_H
+#define NAUTILUS_CAPTION_TABLE_H
+
+#include <gtk/gtktable.h>
+#include <gnome.h>
+
+/*
+ * NautilusCaptionTable is a GtkTable sublass that allows you to painlessly
+ * create tables of nicely aligned captions.
+ */
+
+BEGIN_GNOME_DECLS
+
+#define NAUTILUS_TYPE_CAPTION_TABLE (nautilus_caption_table_get_type ())
+#define NAUTILUS_CAPTION_TABLE(obj) (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_CAPTION_TABLE, NautilusCaptionTable))
+#define NAUTILUS_CAPTION_TABLE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_CAPTION_TABLE, NautilusCaptionTableClass))
+#define NAUTILUS_IS_CAPTION_TABLE(obj) (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_CAPTION_TABLE))
+#define NAUTILUS_IS_CAPTION_TABLE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_CAPTION_TABLE))
+
+
+typedef struct _NautilusCaptionTable NautilusCaptionTable;
+typedef struct _NautilusCaptionTableClass NautilusCaptionTableClass;
+typedef struct _NautilusCaptionTableDetail NautilusCaptionTableDetail;
+
+struct _NautilusCaptionTable
+{
+ GtkTable table;
+
+ NautilusCaptionTableDetail *detail;
+};
+
+struct _NautilusCaptionTableClass
+{
+ GtkTableClass parent_class;
+
+ void (*activate) (GtkWidget *caption_table, int active_entry);
+};
+
+
+GtkType nautilus_caption_table_get_type (void);
+GtkWidget* nautilus_caption_table_new (guint num_rows);
+void nautilus_caption_table_set_row_info (NautilusCaptionTable *caption_table,
+ guint row,
+ const char *label_text,
+ const char *entry_text,
+ gboolean entry_visibility,
+ gboolean entry_readonly);
+void nautilus_caption_table_set_entry_text (NautilusCaptionTable *caption_table,
+ guint row,
+ const char *entry_text);
+void nautilus_caption_table_set_entry_readonly (NautilusCaptionTable *caption_table,
+ guint row,
+ gboolean readonly);
+void nautilus_caption_table_entry_grab_focus (NautilusCaptionTable *caption_table,
+ guint row);
+char* nautilus_caption_table_get_entry_text (NautilusCaptionTable *caption_table,
+ guint row);
+guint nautilus_caption_table_get_num_rows (NautilusCaptionTable *caption_table);
+
+
+BEGIN_GNOME_DECLS
+
+#endif /* NAUTILUS_CAPTION_TABLE_H */
+
+
diff --git a/nautilus-widgets/test-nautilus-widgets.c b/nautilus-widgets/test-nautilus-widgets.c
index daee9e31c..a18f61c37 100644
--- a/nautilus-widgets/test-nautilus-widgets.c
+++ b/nautilus-widgets/test-nautilus-widgets.c
@@ -1,5 +1,6 @@
#include <nautilus-widgets/nautilus-radio-button-group.h>
+#include <nautilus-widgets/nautilus-caption-table.h>
#include <nautilus-widgets/nautilus-preferences-group.h>
#include <nautilus-widgets/nautilus-preferences-item.h>
#include <nautilus-widgets/nautilus-preferences.h>
@@ -7,14 +8,19 @@
#include <gtk/gtk.h>
#include <stdio.h>
-static void test_radio_group (void);
-static void test_preferences_group (void);
-static void test_preferences_item (void);
-static void test_radio_changed_signal (GtkWidget *button_group,
- gpointer user_data);
-static void register_global_preferences (void);
-GtkWidget * create_enum_item (const char *preference_name);
-GtkWidget * create_bool_item (const char *preference_name);
+static void test_radio_group (void);
+static void test_caption_table (void);
+static void test_preferences_group (void);
+static void test_preferences_item (void);
+static void test_radio_changed_callback (GtkWidget *button_group,
+ gpointer user_data);
+static void test_caption_table_activate_callback (GtkWidget *button_group,
+ gint active_index,
+ gpointer user_data);
+static void register_global_preferences (void);
+GtkWidget * create_enum_item (const char *preference_name);
+GtkWidget * create_bool_item (const char *preference_name);
+
enum
{
@@ -35,6 +41,7 @@ main (int argc, char * argv[])
register_global_preferences ();
test_radio_group ();
+ test_caption_table ();
test_preferences_group ();
test_preferences_item ();
@@ -60,7 +67,7 @@ test_radio_group (void)
gtk_signal_connect (GTK_OBJECT (buttons),
"changed",
- GTK_SIGNAL_FUNC (test_radio_changed_signal),
+ GTK_SIGNAL_FUNC (test_radio_changed_callback),
(gpointer) NULL);
gtk_container_add (GTK_CONTAINER (window), buttons);
@@ -71,6 +78,56 @@ test_radio_group (void)
}
static void
+test_caption_table (void)
+{
+ GtkWidget * window;
+ GtkWidget * table;
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+ table = nautilus_caption_table_new (4);
+
+ nautilus_caption_table_set_row_info (NAUTILUS_CAPTION_TABLE (table),
+ 0,
+ "Something",
+ "Text",
+ TRUE,
+ FALSE);
+
+ nautilus_caption_table_set_row_info (NAUTILUS_CAPTION_TABLE (table),
+ 1,
+ "ReadOnly",
+ "Cant Change Me",
+ TRUE,
+ TRUE);
+
+ nautilus_caption_table_set_row_info (NAUTILUS_CAPTION_TABLE (table),
+ 2,
+ "Password",
+ "sekret",
+ FALSE,
+ FALSE);
+
+ nautilus_caption_table_set_row_info (NAUTILUS_CAPTION_TABLE (table),
+ 3,
+ "This is a very long label",
+ "Text",
+ TRUE,
+ FALSE);
+
+ gtk_signal_connect (GTK_OBJECT (table),
+ "activate",
+ GTK_SIGNAL_FUNC (test_caption_table_activate_callback),
+ (gpointer) NULL);
+
+ gtk_container_add (GTK_CONTAINER (window), table);
+
+ gtk_widget_show (table);
+
+ gtk_widget_show (window);
+}
+
+static void
test_preferences_item (void)
{
GtkWidget * window;
@@ -109,13 +166,21 @@ test_preferences_group (void)
}
static void
-test_radio_changed_signal (GtkWidget *buttons, gpointer user_data)
+test_radio_changed_callback (GtkWidget *buttons, gpointer user_data)
{
gint i;
i = nautilus_radio_button_group_get_active_index (NAUTILUS_RADIO_BUTTON_GROUP (buttons));
- printf ("test_radio_changed_signal (%d)\n", i);
+ g_print ("test_radio_changed_callback (%d)\n", i);
+}
+
+static void
+test_caption_table_activate_callback (GtkWidget *button_group,
+ gint active_index,
+ gpointer user_data)
+{
+ g_print ("test_caption_table_activate_callback (active_index=%d)\n", active_index);
}
GtkWidget *