Logo Search packages:      
Sourcecode: gaby version File versions  Download package

shared.c

/*
   Loads'o stuff waiting for a better place to be put in

   Gaby Databases Builder
   Copyright (C) 1998  Ron Bessems
   Copyright (C) 2000  Frederic Peters

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

 */





#include "main.h"
#include "localelist.h"
#include "icons/ja.xpm"
#include "icons/nee2.xpm"
#include "icons/cancel.xpm"

#include "icons/builder.xpm"

struct bla
  {
    GtkWidget *entry;
    GtkWidget *dialoog;
    // GtkWidget *wid;
    gpointer wid;
    void (*function) (gchar *, gpointer data);
  };

struct bla2
  {
    GtkWidget *name;
    GtkWidget *locale;
    GtkWidget *dialoog;
    // GtkWidget *wid;
    gpointer wid;
    void (*function) (doublestring * ds, gpointer );
  };

/* The created string has to be freed manually */
void
ok_add_table_dialog (GtkWidget * widget, struct bla *z)
{
  gchar *text;
  gchar *text2;

  text = gtk_entry_get_text (GTK_ENTRY (z->entry));
  text2 = g_malloc (strlen (text) + 1);
  strcpy (text2, text);
  z->function (text2, z->wid);
  gtk_widget_destroy (z->dialoog);
  return;
}


/* The created string has to be freed manually */
void
ok_locale_dialog (GtkWidget * widget, struct bla2 *z)
{
  gchar *text;
  gchar *text2;
  gchar *text3;
  doublestring *ds;

  ds = g_malloc (sizeof (doublestring));

  text = gtk_entry_get_text (GTK_ENTRY (z->name));
  text2 = g_malloc (strlen (text) + 1);
  strcpy (text2, text);

  text = gtk_entry_get_text (GTK_ENTRY (z->locale));
  text3 = g_malloc (strlen (text) + 1);
  strcpy (text3, text);

  ds->name = text2;
  ds->locale = text3;
  z->function (ds, z->wid);
  gtk_widget_destroy (z->dialoog);
  return;
}




static gboolean
delete_event (GtkWidget * widget, GdkEvent * event, gpointer data)
{
  return FALSE;
}

static void
destroy (GtkWidget * widget, struct bla *z)
{
  g_free (z);
}


void
popup_dialog (void (*function) (gchar *, gpointer data), gchar * caption,
            gchar * text, gchar * defaultt, gpointer wid)
{
  GtkWidget *window;
  GtkWidget *hbox;
  GtkWidget *hbox2;
  GtkWidget *label;
  GtkWidget *vbox;
  GtkWidget *entry;
  GtkWidget *button;
  GtkWidget *frame;
  GtkWidget *lab;
  gint key;
  struct bla *z;

  window = gtk_window_new (GTK_WINDOW_DIALOG);
  gtk_window_set_title (GTK_WINDOW (window), caption);

  /* WM DELETE */
  gtk_signal_connect (GTK_OBJECT (window), "delete_event",
                  GTK_SIGNAL_FUNC (delete_event), NULL);
  /* Destroy */
  gtk_signal_connect (GTK_OBJECT (window), "destroy",
                  GTK_SIGNAL_FUNC (destroy), NULL);

  gtk_container_set_border_width (GTK_CONTAINER (window), 2);


  frame = gtk_frame_new (NULL);
  // gtk_frame_set_label(GTK_FRAME(frame),"");
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
  gtk_container_add (GTK_CONTAINER (window), frame);
  gtk_widget_show (frame);


  hbox2 = gtk_hbox_new (FALSE, 10);
  gtk_container_set_border_width (GTK_CONTAINER (hbox2), 10);
  gtk_container_add (GTK_CONTAINER (frame), hbox2);


  vbox = gtk_vbox_new (TRUE, 5);
  gtk_box_pack_start (GTK_BOX (hbox2), vbox, TRUE, TRUE, 0);
  gtk_widget_show (vbox);

  label = gtk_label_new (text);
  gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
  gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
  gtk_widget_show (label);
  hbox = gtk_hbox_new (FALSE, 5);
  gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
  entry = gtk_entry_new ();
  if (defaultt != NULL)
    gtk_entry_set_text (GTK_ENTRY (entry), defaultt);
  // ton=gtk_button_new_with_label(_("Ok"));



  vbox = gtk_vbox_new (FALSE, 5);
  gtk_box_pack_start (GTK_BOX (hbox2), vbox, FALSE, TRUE, 0);
  gtk_widget_show (vbox);


  button = gtk_button_new ();
  lab = xpm_label_box (ja_xpm, _ ("Ok"), 1, &key);
  gtk_widget_show (lab);
  gtk_container_add (GTK_CONTAINER (button), lab);



  z = g_malloc (sizeof (struct bla));

  z->entry = entry;
  z->dialoog = window;
  z->function = function;
  z->wid = wid;
  gtk_signal_connect (GTK_OBJECT (button), "clicked",
                  GTK_SIGNAL_FUNC (ok_add_table_dialog), z);

  gtk_signal_connect (GTK_OBJECT (entry), "activate",
                  GTK_SIGNAL_FUNC (ok_add_table_dialog), z);



  gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
  gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
  gtk_widget_show (button);
  gtk_widget_show (entry);
  gtk_widget_show (hbox);
  gtk_widget_show (hbox2);
  gtk_widget_grab_focus (entry);
  gtk_widget_show (vbox);
  gtk_widget_show (window);
}


GList *
get_locale_list (GList * list)
{
  int x;
  x = 0;
  while (localestr[x] != NULL)
    {
      list = g_list_append (list, localestr[x]);
      x++;
    }
  return list;
}


void
popup_locale_dialog (void (*function) (doublestring *, gpointer),
                 gchar * caption, gchar * text,
                 gchar * deftext,
                 gchar * defloc,
                 gpointer wid)
{
  GtkWidget *window;
  GtkWidget *hbox2;
  GtkWidget *label;
  GtkWidget *vbox;
  GtkWidget *entry;
  GtkWidget *combo;
  GtkWidget *button;
  GtkWidget *frame;
  GtkWidget *lab;
  int key;
  struct bla2 *z;
  GList *localelist;

  window = gtk_window_new (GTK_WINDOW_DIALOG);
  gtk_window_set_title (GTK_WINDOW (window), caption);

  /* WM DELETE */
  gtk_signal_connect (GTK_OBJECT (window), "delete_event",
                  GTK_SIGNAL_FUNC (delete_event), NULL);
  /* Destroy */
  gtk_signal_connect (GTK_OBJECT (window), "destroy",
                  GTK_SIGNAL_FUNC (destroy), NULL);

  gtk_container_set_border_width (GTK_CONTAINER (window), 2);


  frame = gtk_frame_new (NULL);
  // gtk_frame_set_label(GTK_FRAME(frame),"");
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
  gtk_container_add (GTK_CONTAINER (window), frame);
  gtk_widget_show (frame);

  hbox2 = gtk_hbox_new (FALSE, 10);
  gtk_widget_show (hbox2);
  gtk_container_add (GTK_CONTAINER (frame), hbox2);
  gtk_container_set_border_width (GTK_CONTAINER (hbox2), 5);

  vbox = gtk_vbox_new (FALSE, 3);
  gtk_widget_show (vbox);
  gtk_box_pack_start (GTK_BOX (hbox2), vbox, TRUE, TRUE, 0);

  label = gtk_label_new (text);
  gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
  gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
  gtk_widget_show (label);
  entry = gtk_entry_new ();
  if (deftext != NULL)
    gtk_entry_set_text (GTK_ENTRY (entry), deftext);

  combo = gtk_combo_new ();
  localelist = NULL;
  localelist = get_locale_list (localelist);
  gtk_combo_set_popdown_strings (GTK_COMBO (combo), localelist);
  if (defloc != NULL)
    gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (combo)->entry), defloc);


  button = gtk_button_new ();
  lab = xpm_label_box (ja_xpm, _ ("Ok"), 1, &key);
  gtk_widget_show (lab);
  gtk_container_add (GTK_CONTAINER (button), lab);



  z = g_malloc (sizeof (struct bla2));

  z->name = entry;
  z->locale = GTK_COMBO (combo)->entry;
  z->dialoog = window;
  z->function = function;
  z->wid = wid;
  gtk_signal_connect (GTK_OBJECT (button), "clicked",
                  GTK_SIGNAL_FUNC (ok_locale_dialog), z);

  gtk_box_pack_start (GTK_BOX (vbox), entry, TRUE, TRUE, 0);

  label = gtk_label_new (_ ("Locale code"));
  gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
  gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
  gtk_widget_show (label);

  gtk_box_pack_start (GTK_BOX (vbox), combo, TRUE, TRUE, 0);

  vbox = gtk_vbox_new (FALSE, 5);
  gtk_widget_show (vbox);
  gtk_box_pack_start (GTK_BOX (hbox2), vbox, TRUE, TRUE, 0);

  gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
  gtk_widget_show (button);
  gtk_widget_show (entry);
  gtk_widget_show (combo);
  gtk_widget_show (vbox);
  gtk_widget_grab_focus (entry);
  gtk_widget_show (window);
}




GtkWidget *
xpm_label_box (char **xpme, gchar * label_text, gint order, gint * key)
{
  GtkWidget *box1;
  GtkWidget *label;
  GtkWidget *pixmapwid;
  GdkPixmap *pixmap;
  GdkBitmap *mask;
  GtkStyle *style;

  /* create box for xpm and label */
  box1 = gtk_hbox_new (FALSE, 0);
  gtk_container_border_width (GTK_CONTAINER (box1), 2);

  /* get style of button.. I assume it's to get the background color.
   * if someone knows the real reason, please enlighten me. */
  style = gtk_widget_get_style (Window);

  /* now on to the xpm stuff.. load xpm */
  pixmap = gdk_pixmap_create_from_xpm_d (Window->window, &mask,
                               &style->bg[GTK_STATE_NORMAL],
                               (gchar **) xpme);
  pixmapwid = gtk_pixmap_new (pixmap, mask);
  label = NULL;
  /* create label for button */
  if (label_text != NULL)
    {
      label = gtk_label_new ("");
      if (key != NULL)
      *key = gtk_label_parse_uline (GTK_LABEL (label), label_text);
      else
      gtk_label_set_text (GTK_LABEL (label), label_text);
    }

  /* pack the pixmap and label into the box */
  if (order == 1)
    {
      gtk_box_pack_start (GTK_BOX (box1),
                    pixmapwid, FALSE, FALSE, 3);
      if (label_text != NULL)
      gtk_box_pack_end (GTK_BOX (box1), label, FALSE, FALSE, 3);
    }
  if (order == 2)
    {
      gtk_box_pack_end (GTK_BOX (box1),
                  pixmapwid, FALSE, TRUE, 3);
      if (label_text != NULL)
      gtk_box_pack_start (GTK_BOX (box1), label, TRUE, TRUE, 3);
    }
  if (order == 3)
    {
      gtk_box_pack_start (GTK_BOX (box1),
                    pixmapwid, TRUE, TRUE, 3);
      if (label_text != NULL)
      gtk_box_pack_end (GTK_BOX (box1), label, TRUE, TRUE, 3);
    }

  gtk_widget_show (pixmapwid);

  if (label_text != NULL)
    gtk_widget_show (label);

  return (box1);



}

GtkWidget *
scroll_new (GtkWidget * clist)
{
  GtkWidget *scroll;
  scroll = gtk_scrolled_window_new (NULL, NULL);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
                          GTK_POLICY_NEVER,
                          GTK_POLICY_AUTOMATIC);
  gtk_container_add (GTK_CONTAINER (scroll), clist);
  gtk_widget_show (scroll);
  return scroll;
}


/* Cut's off all white space from string begin and end */
void
trim (char *str)
{
  int pos;
  int count;
  int len;

  if (str == NULL)
    return;

  len = strlen (str);
  pos = -1;

  /* Find the first character that isn't a whitespace */
  for (count = 0; count <= len; count++)
    {
      if (isspace ((int)(str[count])) == 0 && pos == -1)
      pos = count;
    }
 
  if (pos == -1 ) pos =0;
  len = strlen (str+pos);

  /* copy hole string forward */
  for (count = 0; count <= len ; count ++)
    {
      str[count]=str[count+pos];
    }

  pos = -1;

  /* Find last char */
  for (count = len - 1; count >= 0; count--)
    {
      if (isspace ((int)(str[count])) == 0 && pos == -1)
      pos = count;
    }

  /* Set that to 0 */
  if (pos != -1)
    str[pos+1]=0;

}



/* table = 10 allow space in name */
gint
check_name (gchar * name, int table)
{
  gchar *a;
  a = NULL;
  if (strlen (name) == 0 && table != 10)
    {
      error_dialog (_ ("Cannot use an empty string"), _ ("Oops"));
      return -1;
    }
  a = strchr (name, ':');
  if (a != NULL )
    {
      error_dialog (_ ("Cannot use a : in the name string"), _ ("Oops"));
      return -2;
    }
  a = strchr (name, '=');
  if (a != NULL)
    {
      error_dialog (_ ("Cannot use a = in the name string"), _ ("Oops"));
      return -3;
    }
  a = strchr (name, '_');
  if (a != NULL)
    {
      error_dialog (_ ("Cannot use a _ in the name string"), _ ("Oops"));
      return -4;
    }

  return 0;
}


static gint
close_dialog (GtkWidget * widget, GdkEvent * event, gpointer data)
{
  return (TRUE);
}


static gint
ok_dialog (GtkWidget * widget, GtkWidget * window)
{
  gtk_grab_remove (window);
  gtk_widget_destroy (window);
  return 0;
}


void
error_dialog (gchar * tekst, gchar * caption)
{
  GtkWidget *box;
  GtkWidget *hbox;
  GtkWidget *button;
  GtkWidget *exit_win;
  GtkWidget *frame;
  GtkWidget *b;

  exit_win = gtk_window_new (GTK_WINDOW_DIALOG);
  gtk_window_set_policy (GTK_WINDOW (exit_win), FALSE, FALSE, FALSE);
  gtk_signal_connect (GTK_OBJECT (exit_win), "delete_event",
                  GTK_SIGNAL_FUNC (close_dialog), exit_win);

  gtk_container_set_border_width (GTK_CONTAINER (exit_win), 3);
  frame = gtk_frame_new (NULL);
  gtk_container_add (GTK_CONTAINER (exit_win), frame);
  gtk_widget_show (frame);

  gtk_window_set_title (GTK_WINDOW (exit_win), caption);
  box = gtk_vbox_new (0, 10);

  gtk_container_add (GTK_CONTAINER (frame), box);
  gtk_container_set_border_width (GTK_CONTAINER (box), 4);

  hbox = xpm_label_box (builder_xpm, tekst, 1, NULL);
  gtk_box_pack_start (GTK_BOX (box), hbox, 0, 0, 0);

  gtk_widget_show (hbox);


  hbox = gtk_hbox_new (1, 10);
  gtk_box_pack_start (GTK_BOX (box), hbox, 1, 1, 0);


  button = gtk_button_new_with_label (_ ("Ok"));
  b = button;

  gtk_box_pack_start (GTK_BOX (hbox), button, 0, 0, 0);
  gtk_signal_connect (GTK_OBJECT (button), "clicked",
                  GTK_SIGNAL_FUNC (ok_dialog), exit_win);
  gtk_widget_set_usize (button, 100, 30);
  gtk_widget_show (button);


  gtk_widget_show (hbox);
  gtk_widget_show (box);

  gtk_widget_show (exit_win);
  gtk_widget_grab_focus (b);
  gtk_grab_add (exit_win);


}
/* This probably could be 1 function */
static void
yes_dialog (GtkWidget * wid, void (*func) (gpointer data))
{
  gpointer data;
  data = gtk_object_get_user_data (GTK_OBJECT (wid));
  func (data);
}

static void
no_dialog (GtkWidget * wid, void (*func) (gpointer data))
{
  gpointer data;
  data = gtk_object_get_user_data (GTK_OBJECT (wid));
  func (data);

}

static void
cancel_dialog (GtkWidget * wid, void (*func) (gpointer data))
{
  gpointer data;
  data = gtk_object_get_user_data (GTK_OBJECT (wid));
  func (data);
}

static void
del_dialog (GtkWidget * wid, GtkWidget * win)
{
  gtk_widget_destroy (win);
}


static gint
question_delete (GtkWidget * w, gpointer data)
{
  return (FALSE);
}

static void
question_destroy (GtkWidget * w, gpointer data)
{
}

void
dialog (char *tekst, char *caption, int options,
      void (*yes) (gpointer data),
      void (*no) (gpointer data),
      void (*cancel) (gpointer data), gpointer data)
{
  GtkWidget *box;
  GtkWidget *hbox;
  GtkWidget *sp;
  GtkWidget *window;
  GtkWidget *ja;
  GtkWidget *nee;
  GtkWidget *annuleren;
  GtkWidget *frame;

  window = gtk_window_new (GTK_WINDOW_DIALOG);
  gtk_window_set_policy (GTK_WINDOW (window), FALSE, FALSE, FALSE);
  gtk_signal_connect (GTK_OBJECT (window), "delete_event",
                  GTK_SIGNAL_FUNC (question_delete), NULL);

  gtk_signal_connect (GTK_OBJECT (window), "destroy",
                  GTK_SIGNAL_FUNC (question_destroy), NULL);

  gtk_container_border_width (GTK_CONTAINER (window), 2);
  
  frame = gtk_frame_new(NULL);
  gtk_frame_set_shadow_type(GTK_FRAME(frame),GTK_SHADOW_ETCHED_IN);
  gtk_container_add(GTK_CONTAINER(window),frame);
  gtk_widget_show(frame);


  gtk_window_set_title (GTK_WINDOW (window), caption);
  box = gtk_vbox_new (0, 10);
  gtk_container_border_width (GTK_CONTAINER (box), 5);
  gtk_container_add (GTK_CONTAINER (frame), box);

  hbox = xpm_label_box (builder_xpm, tekst, 1, NULL);
  gtk_box_pack_start (GTK_BOX (box), hbox, 0, 0, 0);

  gtk_widget_show (hbox);


  hbox = gtk_hbox_new (1, 10);
  gtk_box_pack_start (GTK_BOX (box), hbox, 1, 1, 0);

  ja = gtk_button_new ();
  sp = xpm_label_box (ja_xpm, _ ("Yes"), 1, NULL);
  gtk_widget_show (sp);
  gtk_widget_set_usize (ja, 100, 30);
  gtk_container_add (GTK_CONTAINER (ja), sp);
  gtk_box_pack_start (GTK_BOX (hbox), ja, 1, 1, 0);
  // gtk_widget_install_accelerator(ja,accelt,"clicked",'j',GDK_CONTROL_MASK);
  gtk_widget_show (ja);

  gtk_object_set_user_data (GTK_OBJECT (ja), data);
  gtk_signal_connect (GTK_OBJECT (ja), "clicked",
                  GTK_SIGNAL_FUNC (yes_dialog), yes);
  gtk_signal_connect (GTK_OBJECT (ja), "clicked",
                  GTK_SIGNAL_FUNC (del_dialog), window);



  nee = gtk_button_new ();
  sp = xpm_label_box (nee2_xpm, _ ("No"), 1, NULL);
  gtk_widget_show (sp);
  gtk_widget_set_usize (nee, 100, 30);
  gtk_container_add (GTK_CONTAINER (nee), sp);
  // gtk_widget_install_accelerator(nee,accelt,"clicked",'n',GDK_CONTROL_MASK);
  gtk_box_pack_start (GTK_BOX (hbox), nee, 1, 1, 0);
  gtk_widget_show (nee);
  gtk_object_set_user_data (GTK_OBJECT (nee), data);
  gtk_signal_connect (GTK_OBJECT (nee), "clicked",
                  GTK_SIGNAL_FUNC (no_dialog), no);
  gtk_signal_connect (GTK_OBJECT (nee), "clicked",
                  GTK_SIGNAL_FUNC (del_dialog), window);




  annuleren = gtk_button_new ();
  sp = xpm_label_box (cancel_xpm, _ ("Cancel"), 1, NULL);
  gtk_widget_show (sp);
  gtk_widget_set_usize (annuleren, 100, 30);
  gtk_container_add (GTK_CONTAINER (annuleren), sp);
  // gtk_widget_install_accelerator(annuleren,accelt,"clicked",'n',GDK_CONTROL_MASK);
  gtk_box_pack_start (GTK_BOX (hbox), annuleren, 1, 1, 0);
  gtk_widget_show (annuleren);
  gtk_object_set_user_data (GTK_OBJECT (annuleren), data);
  gtk_signal_connect (GTK_OBJECT (annuleren), "clicked",
                  GTK_SIGNAL_FUNC (cancel_dialog), cancel);
  gtk_signal_connect (GTK_OBJECT (annuleren), "clicked",
                  GTK_SIGNAL_FUNC (del_dialog), window);


  gtk_widget_show (hbox);
  gtk_widget_show (box);

  gtk_widget_show (window);

  gtk_widget_show (annuleren);
  gtk_widget_grab_focus (ja);
  gtk_grab_add (window);

}





gboolean
is_table_uniq(gchar *name, GList *tables)
{
  GList *loop;
  table *tab;

  loop = g_list_first(tables);
  while (loop != NULL)
  {
    tab = loop->data;
    if (strcasecmp(tab->name,name)==0)
    {
      return FALSE;
    }
    loop = loop->next;
  }
  return TRUE; 
}

gboolean
is_subtable_uniq(gchar *name, GList *subtables)
{
  GList *loop;
  subtable *stab;

  loop = g_list_first(subtables);
  while (loop != NULL)
  {
    stab = loop->data;
    if (strcasecmp(stab->name,name)==0)
    {
      return FALSE;
    }
    loop = loop->next;
  }
  return TRUE; 
}


gboolean
is_field_uniq(gchar *name, GList *fields)
{
  GList *loop;
  field *fld;

  loop = g_list_first(fields);
  while (loop != NULL)
  {
    fld = loop->data;
    if (strcasecmp(fld->name,name)==0)
    {
      return FALSE;
    }
    loop = loop->next;
  }
  return TRUE; 
}

gboolean
is_subfield_uniq(gchar *name, GList *subfields)
{
  GList *loop;
  subfield *sfld;

  loop = g_list_first(subfields);
  while (loop != NULL)
  {
    sfld = loop->data;
    if (strcasecmp(sfld->name,name)==0)
    {
      return FALSE;
    }
    loop = loop->next;
  }
  return TRUE; 
}


char* get_untranslated_string(char *string, doublestring *table)
{
      int i=0;
      
      printf("Looking for %s\n", string);
      while ( table[i].name ) {
            printf("strcmp'ing with %s\n", table[i].locale);
            if ( strcmp(table[i].locale, string) == 0 )
                  return table[i].name;
            printf("   -> failed\n");
            i++;
      }

      return NULL;
}

char* get_translated_string(char *string, doublestring *table)
{
      int i=0;
      
      while ( table[i].name ) {
            if ( strcmp(table[i].name, string) == 0 )
                  return _(table[i].locale);
            i++;
      }

      return NULL;
}


Generated by  Doxygen 1.6.0   Back to index