[gnome-db]"New Database" Druid And Other Issues



(Beware! Lenghty and boring e-mail! You've been warned!)

Hi guys,

Noting the lack of an easy to use "New Database" interface, and
following Rodrigo's "New Datasource Druid", I was planning a similar
druid intended to the creation of databases by average users.

But then I noticed that Rodrigo is also doing something similar
thing (frontend/gnomedb-fe-wizard.c) in a different fashion.

I started implementing it as a Gtk widget (once more, following
the new datasource druid model), and confess that I questioned
its usefulness inside libgnomedb but still feel that the library is
the best place. So, I'd just like to hear from others what they think
about this.

I'm also sending the GnomeDbDesignerDbDruid widget code so that
you guys can take a look and be very harsh on my poor code.
I hope it's going to useful. The skeleton of the things 
I was trying to implement are already in place, but the real
functionality
is not. I'll just give a quick explanation of what I thought would be
cool:

- Database creation through a druid (obviously!)
- Three starting points (sources to get the basic database structure): 
    1. GDA Datasource
    2. Database Repository
    3. Existing XML Database File
The second item deserver some explanation, I guess. I was thinking
that it would be cool if we had some sort of collection of database
structures for the most varied purposes. A user would them simply
pick the structure closest model to his/her needs.

One important point here, in my opnion would be some sort of i18n
support.
and some more meta-data.
I have though about this, looked around and came up with a sample
(possibly broken, certainly incomplete but understandable) file
(attached).

This more "cheesy" xml structure could also be transformed (via
the mechanisms available in libxlst) in .glade files, using the
<shordescription> as label for data entry widgets, <longdescriptions>
for hints or statusbar, and have it all localized. Rapid Application
Development for Gnome!!! Way cooler than Kylix IMHO.

So, this is really intended to be discussed. I might be way off my head
in some points, but I believe the overall design makes sense, doesn't
it?

I also want to apologize for coming up with ideas and then failing
to turn them into reality (or sometimes lacking the skills to do them).
But this is just to prove that I want to see this project kicking ass.
I assure you I'm trying to improve myself where I lack skills or
knowledge. Just bear with me for the moment, and I guarantee\
I might be helpfull at the end.

Cheers.
/* GNOME DB library
 * Copyright (C) 2001 Cleber Rodrigues
 *
 * This 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.
 *
 * This 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 this 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.
 */

#include "gnome-db-designer-db-druid.h"
#include "gnome-db-util.h"
#include <gdk_imlib.h>
#include <libgnome/gnome-i18n.h>
#include <libgnomeui/gnome-druid-page-start.h>
#include <libgnomeui/gnome-druid-page-standard.h>
#include <libgnomeui/gnome-druid-page-finish.h>

struct _GnomeDbDesignerDbDruidPrivate {
  GdaXmlDatabase *xmldb;
  GnomeDruidPageStart *start_page;
  GnomeDruidPageStandard *select_source_page;
  GnomeDruidPageStandard *select_from_datasource_page;
  GnomeDruidPageStandard *select_from_repository_page;
  GnomeDruidPageStandard *select_from_xmldb_page;  
  GnomeDruidPageFinish *finish_page;

  /* radio buttons that go into the select_source_page */
  GtkWidget *select_from_datasource_radio;
  GtkWidget *select_from_repository_radio;
  GtkWidget *select_from_xmldb_radio;
};

enum {
  FINISH,
  LAST_SIGNAL
};

static gint config_druid_signals[LAST_SIGNAL] = { 0, };


/*
 * Private Functions
 */
static GtkWidget* 
datasource_combo_new (void)
{
  GtkWidget *combo;
  GList *datasource_list;

  combo = gtk_combo_new ();  
  datasource_list = gda_list_datasources ();
  if (datasource_list) {
    gtk_combo_set_popdown_strings (GTK_COMBO(combo),
				   datasource_list);
  }
  gda_dsn_free_list(datasource_list);

  return combo;
}

/*
 * Callbacks
 */
static void
cancel_druid_cb (GnomeDruid *gnome_druid, gpointer user_data)
{
  GnomeDbDesignerDbDruid *druid = (GnomeDbDesignerDbDruid *) user_data;

  g_return_if_fail(GNOME_DB_IS_DESIGNER_DB_DRUID(druid));

  /* free allocated XML document */
  if (druid->priv->xmldb) {
     gda_xml_database_free(druid->priv->xmldb);
     druid->priv->xmldb = NULL;
     }

  gtk_signal_emit(GTK_OBJECT(druid),
		  config_druid_signals[FINISH],
		  TRUE);
}

static gint
select_source_next_cb (GnomeDruid *gnome_druid, gpointer user_data)
{
  GnomeDbDesignerDbDruid *druid = (GnomeDbDesignerDbDruid *) user_data;

  g_return_if_fail (GNOME_DB_IS_DESIGNER_DB_DRUID(druid));
  g_return_if_fail (GNOME_IS_DRUID_PAGE (druid->priv->select_from_datasource_page));

  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(druid->priv->select_from_datasource_radio))) {
    /* go to select_from_datasource_page */
    gnome_druid_set_page (GNOME_DRUID (druid),
			  GNOME_DRUID_PAGE (druid->priv->select_from_datasource_page));
  }
  else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(druid->priv->select_from_repository_radio))) {
    /* go to select_from_repository_page */
    gnome_druid_set_page (GNOME_DRUID (druid),
			  GNOME_DRUID_PAGE (druid->priv->select_from_repository_page));
  }
  else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(druid->priv->select_from_xmldb_radio))) {
    /* go to select_from_xmldb_page */
    gnome_druid_set_page (GNOME_DRUID (druid),
			  GNOME_DRUID_PAGE (druid->priv->select_from_xmldb_page));
  }
  return TRUE;
}

/* We dont need a select_from_datasource_back_cb(), because
 * the default handler will do just what we want it to do */

static gint
select_from_repository_back_cb (GnomeDruid *gnome_druid, gpointer user_data)
{
  GnomeDbDesignerDbDruid *druid = (GnomeDbDesignerDbDruid *) user_data;
  
  g_return_if_fail (GNOME_DB_IS_DESIGNER_DB_DRUID(druid));
  g_return_if_fail (GNOME_IS_DRUID_PAGE (druid->priv->select_from_datasource_page));

  gnome_druid_set_page (GNOME_DRUID (druid),
			GNOME_DRUID_PAGE (druid->priv->select_source_page));

  return TRUE;
}

static gint
select_from_xmldb_back_cb (GnomeDruid *gnome_druid, gpointer user_data)
{
  GnomeDbDesignerDbDruid *druid = (GnomeDbDesignerDbDruid *) user_data;
  
  g_return_if_fail (GNOME_DB_IS_DESIGNER_DB_DRUID(druid));
  g_return_if_fail (GNOME_IS_DRUID_PAGE (druid->priv->select_from_datasource_page));

  gnome_druid_set_page (GNOME_DRUID (druid),
			GNOME_DRUID_PAGE (druid->priv->select_source_page));

  return TRUE;
}

/*
 * GnomeDbDsnConfigDruid interface
 */
static void
gnome_db_designer_db_druid_class_init (GnomeDbDesignerDbDruidClass *klass)
{
  GtkObjectClass *object_class = (GtkObjectClass *) klass;

  config_druid_signals[FINISH] =
    gtk_signal_new("finish",
		   GTK_RUN_LAST,
		   object_class->type,
		   GTK_SIGNAL_OFFSET(GnomeDbDesignerDbDruidClass, finish),
		   gtk_marshal_NONE__INT,
		   GTK_TYPE_NONE,
		   1, 
		   GTK_TYPE_INT);
  gtk_object_class_add_signals(object_class, config_druid_signals, LAST_SIGNAL);
	
  klass->finish = NULL;
}

static void
gnome_db_designer_db_druid_destroy (GtkObject *object, gpointer user_data)
{
  GnomeDbDesignerDbDruid *druid = (GnomeDbDesignerDbDruid *) object;
  
  g_return_if_fail(GNOME_DB_IS_DESIGNER_DB_DRUID(druid));
}

static void
gnome_db_designer_db_druid_init (GnomeDbDesignerDbDruid *druid)
{
	GdkImlibImage *logo = NULL;
	gchar *pathname;
	GtkWidget *table;
	GtkWidget *label;
	GtkWidget *datasource_combo;

	GList *datasource_list;
	GList *node;

	/* allocate private structure */
	druid->priv = g_new0(GnomeDbDesignerDbDruidPrivate, 1);

	pathname = gnome_pixmap_file("gnome-db.png");
	if (pathname) {
		logo = gdk_imlib_load_image(pathname);
		g_free((gpointer) pathname);
	}

	/* create the start_page */
	druid->priv->start_page = gnome_druid_page_start_new();
	gnome_druid_page_start_set_logo(GNOME_DRUID_PAGE_START(druid->priv->start_page), logo);
	gnome_druid_page_start_set_title(GNOME_DRUID_PAGE_START(druid->priv->start_page),
					 _("Creating A New Database..."));
	gnome_druid_page_start_set_text(GNOME_DRUID_PAGE_START(druid->priv->start_page),
					_("This wizard will guide you through the process of\n"
					  "creating a new data base for your GNOME-DB\n"
					  "installation. Just follow the steps!"));
	gtk_widget_show_all(GTK_WIDGET(druid->priv->start_page));


	/* create the select_source_page */
	druid->priv->select_source_page = gnome_druid_page_standard_new_with_vals(_("Choose Source"),
									     logo);
	table = gnome_db_new_table_widget(5, 2, FALSE);
	gtk_box_pack_start(GTK_BOX(GNOME_DRUID_PAGE_STANDARD(druid->priv->select_source_page)->vbox), table, 1, 1, 0);

	label = gnome_db_new_label_widget(_("Gnome-DB can help you create your ideal Database.\n"
					    "To do so, you can choose from the following starting points:"));

	gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5);
	gtk_table_attach(GTK_TABLE(table), label, 0, 2, 0, 1,
			 GTK_FILL | GTK_EXPAND | GTK_SHRINK,
			 GTK_FILL | GTK_EXPAND | GTK_SHRINK,
			 3, 3);
	
	druid->priv->select_from_datasource_radio = gnome_db_new_radio_button_widget (_("GDA Datasource"), NULL);
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(druid->priv->select_from_datasource_radio), TRUE);
	gtk_table_attach(GTK_TABLE(table), druid->priv->select_from_datasource_radio, 0, 2, 2, 3,
			 GTK_FILL | GTK_EXPAND | GTK_SHRINK,
			 GTK_FILL | GTK_EXPAND | GTK_SHRINK,
			 3, 3);

	druid->priv->select_from_repository_radio = gnome_db_new_radio_button_widget (_("Database Models From Repository"), druid->priv->select_from_datasource_radio);
	gtk_table_attach(GTK_TABLE(table), druid->priv->select_from_repository_radio, 0, 2, 3, 4,
			 GTK_FILL | GTK_EXPAND | GTK_SHRINK,
			 GTK_FILL | GTK_EXPAND | GTK_SHRINK,
			 3, 3);

	druid->priv->select_from_xmldb_radio = gnome_db_new_radio_button_widget (_("Existing GDA XML Database File"), druid->priv->select_from_datasource_radio);
	gtk_table_attach(GTK_TABLE(table), druid->priv->select_from_xmldb_radio, 0, 2, 4, 5,
			 GTK_FILL | GTK_EXPAND | GTK_SHRINK,
			 GTK_FILL | GTK_EXPAND | GTK_SHRINK,
			 3, 3);
	
	gtk_widget_show_all(GTK_WIDGET(druid->priv->select_source_page ));

	/* create the select_from_datasource_page */
	druid->priv->select_from_datasource_page = gnome_druid_page_standard_new_with_vals(_("Getting Structure From GDA Datasource"),
											   logo);
	table = gnome_db_new_table_widget(5, 2, FALSE);
	gtk_box_pack_start(GTK_BOX(GNOME_DRUID_PAGE_STANDARD(druid->priv->select_from_datasource_page)->vbox), table, 1, 1, 0);
	/* datasource_combo = datasource_combo_new;
	gtk_table_attach(GTK_TABLE(table), datasource_combo, 0, 2, 3, 4,
			 GTK_FILL | GTK_EXPAND | GTK_SHRINK,
			 GTK_FILL | GTK_EXPAND | GTK_SHRINK,
			 3, 3); */

	gtk_widget_show_all(GTK_WIDGET(druid->priv->select_from_datasource_page));

	/* create the select_from_repository_page */
	druid->priv->select_from_repository_page = gnome_druid_page_standard_new_with_vals(_("Getting Structure From Database Repository"),
											   logo);
	gtk_widget_show_all(GTK_WIDGET(druid->priv->select_from_repository_page));

	/* create the select_from_xml_page */
	druid->priv->select_from_xmldb_page = gnome_druid_page_standard_new_with_vals(_("Getting Structure From GDA XML Database"),
										      logo);
	gtk_widget_show_all(GTK_WIDGET(druid->priv->select_from_xmldb_page));

	/* create the finish page */
	druid->priv->finish_page = gnome_druid_page_finish_new();
	gnome_druid_page_finish_set_logo(GNOME_DRUID_PAGE_FINISH(druid->priv->finish_page), logo);
	gnome_druid_page_finish_set_title(GNOME_DRUID_PAGE_FINISH(druid->priv->finish_page),
									  _("All information retrieved"));
	gnome_druid_page_finish_set_text(GNOME_DRUID_PAGE_FINISH(druid->priv->finish_page),
					 _("All information needed to create a new database \n"
					   "has been retrieved. Now, press 'Finish' to close \n"
					   "this dialog. To open your newly created database, \n"
					   "DO WHAT ???"));
	
	gtk_widget_show_all(GTK_WIDGET(druid->priv->finish_page));

	/* append all pages to the druid */
	gnome_druid_append_page(GNOME_DRUID(druid), GNOME_DRUID_PAGE(druid->priv->start_page));
	gnome_druid_append_page(GNOME_DRUID(druid), GNOME_DRUID_PAGE(druid->priv->select_source_page));
	gnome_druid_append_page(GNOME_DRUID(druid), GNOME_DRUID_PAGE(druid->priv->select_from_datasource_page));
	gnome_druid_append_page(GNOME_DRUID(druid), GNOME_DRUID_PAGE(druid->priv->select_from_repository_page));
	gnome_druid_append_page(GNOME_DRUID(druid), GNOME_DRUID_PAGE(druid->priv->select_from_xmldb_page));
	gnome_druid_append_page(GNOME_DRUID(druid), GNOME_DRUID_PAGE(druid->priv->finish_page));
	gnome_druid_set_page(GNOME_DRUID(druid), GNOME_DRUID_PAGE(druid->priv->start_page));

	/* connect to signals */
	gtk_signal_connect(GTK_OBJECT(druid),
			   "cancel",
			   GTK_SIGNAL_FUNC(cancel_druid_cb),
			   druid);
	gtk_signal_connect(GTK_OBJECT(druid),
			   "destroy",
			   GTK_SIGNAL_FUNC(gnome_db_designer_db_druid_destroy),
			   NULL);

	/* signals emmited by page change */
	gtk_signal_connect(GTK_OBJECT(druid->priv->select_source_page),
			   "next",
			   GTK_SIGNAL_FUNC(select_source_next_cb),
			   (gpointer) druid);
	gtk_signal_connect(GTK_OBJECT(druid->priv->select_from_repository_page),
			   "back",
			   GTK_SIGNAL_FUNC(select_from_repository_back_cb),
			   (gpointer) druid);
	gtk_signal_connect(GTK_OBJECT(druid->priv->select_from_xmldb_page),
			   "back",
			   GTK_SIGNAL_FUNC(select_from_xmldb_back_cb),
			   (gpointer) druid);
}

/**
 * gnome_db_designer_db_druid_get_type
 *
 * The usual _get_type() function required by the Gtk+ type system.
 * Returns an unique identifier for this class of widget.
 */
GtkType
gnome_db_designer_db_druid_get_type (void)
{
  static GtkType type = 0;

  if (!type) {
    GtkTypeInfo info = {
      "GnomeDbDesignerDbDruid",
      sizeof(GnomeDbDesignerDbDruid),
      sizeof(GnomeDbDesignerDbDruidClass),
      (GtkClassInitFunc) gnome_db_designer_db_druid_class_init,
      (GtkObjectInitFunc) gnome_db_designer_db_druid_init,
      (GtkArgSetFunc) NULL,
      (GtkArgGetFunc) NULL
    };
    type = gtk_type_unique(gnome_druid_get_type(), &info);
  }
  return type;
}

/**
 * gnome_db_designer_db_druid_new
 *
 * Creates a new instance of a #GnomeDbDesignerDbDruid
 */
GtkWidget *
gnome_db_designer_db_druid_new (void)
{
  GnomeDbDesignerDbDruid *druid;

  druid = GNOME_DB_DESIGNER_DB_DRUID(gtk_type_new(GNOME_DB_TYPE_DESIGNER_DB_DRUID));
  return GTK_WIDGET(druid);
}

/**
 * gnome_db_designer_db_get_db
 * @druid: a #GnomeDbDesignerDruid widget
 *
 * Returns an Returns the GDA data source resulted from the interaction between the
 * #GnomeDbDsnConfigDruid widget and the user
 */
GdaXmlDatabase *
gnome_db_designer_db_get_db (GnomeDbDesignerDbDruid *druid)
{
  g_return_val_if_fail(GNOME_DB_IS_DESIGNER_DB_DRUID(druid), NULL);
  g_return_val_if_fail(GDA_IS_XML_FILE(druid->priv->xmldb), NULL);

  return druid->priv->xmldb;
}
/* GNOME DB library
 * Copyright (C) 2001 Cleber Rodrigues
 *
 * This 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.
 *
 * This 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 this 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.
 */

#ifndef __gnome_db_designer_db_druid_h__
#define __gnome_db_designer_db_druid_h__ 1

#include <libgnome/gnome-defs.h>
#include <libgnomeui/gnome-druid.h>
#include <gda-xml-database.h>

#define GNOME_DB_TYPE_DESIGNER_DB_DRUID            (gnome_db_designer_db_druid_get_type())
#define GNOME_DB_DESIGNER_DB_DRUID(obj)            GTK_CHECK_CAST(obj, GNOME_DB_TYPE_DESIGNER_DB_DRUID, GnomeDbDesignerDbDruid)
#define GNOME_DB_DESIGNER_DB_DRUID_CLASS(klass)    GTK_CHECK_CLASS_CAST(klass, GNOME_DB_TYPE_DESIGNER_DB_DRUID, GnomeDbDesignerDbDruidClass)
#define GNOME_DB_IS_DESIGNER_DB_DRUID(obj)         GTK_CHECK_TYPE(obj, GNOME_DB_TYPE_DESIGNER_DB_DRUID)
#define GNOME_DB_IS_DESIGNER_DB_DRUID_CLASS(klass) (GTK_CHECK_CLASS_TYPE((klass), GNOME_DB_TYPE_DESIGNER_DB_DRUID))

typedef struct _GnomeDbDesignerDbDruidPrivate GnomeDbDesignerDbDruidPrivate;
typedef struct _GnomeDbDesignerDbDruid        GnomeDbDesignerDbDruid;
typedef struct _GnomeDbDesignerDbDruidClass   GnomeDbDesignerDbDruidClass;

struct _GnomeDbDesignerDbDruid {
	GnomeDruid                    druid;
	GnomeDbDesignerDbDruidPrivate *priv;
};

struct _GnomeDbDesignerDbDruidClass {
	GnomeDruidClass parent_class;

	void (*finish)(GnomeDbDesignerDbDruid *druid, gboolean error);
};

GtkType    gnome_db_designer_db_druid_get_type (void);

GtkWidget *gnome_db_designer_db_druid_new      (void);

GdaXmlDatabase *gnome_db_designer_db_druid_get_db  (GnomeDbDesignerDbDruid *druid);

#endif
<?xml version="1.0"?>
  <database name=contacts>
    <shortdescription>
      <i18n>
	en = "Contacts"
	pt_BR = "Contatos"
      </i18n>
    </shortdescription>
    <table name="person">
      <shortdescription>
	<i18n>
	  en = "Person"
	  pt_BR = "Pessoa"
	</i18n>
      </shortdescription>
      <field name="name" size="64" scale="0" gdatype="GDA_TypeVarchar">
	<shortdescription>
	  <i18n>
	    en = "First Name"
	    pt_BR = "Primeiro Nome"
	  </i18n>
	</shortdescription>
      </field>
      <field name="phone" size="12" scale="0" gdatype="GDA_TypeDecimal">
	<shortdescription>
	  <i18n>
	    en = "Telephone Number"
	    pt_BR = "Numero Telefonico"
	  </i18n>
	</shortdescription>
      </field>
    </table>
  </database>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]