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

gEDA-dev: [PATCH] gattrib: reorganize file opening code



Hi,

Here is the first patch in my patch series meant
to simplify/improve/fix gattrib. This patch is 
moderately intrusive and hasn't had extensive testing.
As such, I would not consider it to be merged
without testing it a bit more (it appears to work
fine for me though). So please give it a try and
report any issues. 

Hopefully the patch should resolve (or help resolve) 
couple of gattrib related bugs in the tracker.

One thing I'm not sure about is the behaviour
when the user has already opened several pages
and then the File->Open is invoked to open another
schematic (project?). I would much rather see 
this as a request to close the current project,
destroy all the data (SHEET_DATA etc.) and reinitialize
everything with the new project. (See my comments
to the s_toplevel_menubar_file_open function.)
Stuart, what do you think?

-- 
Ivan Stankovic, ivan.stankovic@xxxxxx

"Protect your digital freedom and privacy, eliminate DRM, 
learn more at http://www.defectivebydesign.org/what_is_drm";
Subject: [PATCH] gattrib: reorganize file opening code

This patch reorganizes the file opening code
and related code paths in gattrib. Besides
simplifying the code, the patch also improves
error reporting.
---
 gattrib/include/globals.h   |    6 -
 gattrib/include/prototype.h |   10 +--
 gattrib/src/gattrib.c       |  216 +++++-------------------------------------
 gattrib/src/globals.c       |    3 -
 gattrib/src/s_toplevel.c    |   87 +++++++++---------
 gattrib/src/x_dialog.c      |   73 +++++++--------
 gattrib/src/x_fileselect.c  |  180 ++++++++++++++---------------------
 gattrib/src/x_gtksheet.c    |    3 +-
 gattrib/src/x_window.c      |  104 +++++----------------
 9 files changed, 200 insertions(+), 482 deletions(-)

diff --git a/gattrib/include/globals.h b/gattrib/include/globals.h
index c035c7f..e7561d2 100644
--- a/gattrib/include/globals.h
+++ b/gattrib/include/globals.h
@@ -69,12 +69,6 @@
 TOPLEVEL *pr_current;
 
 /*------------------------------------------------------------------
- * first_page -- this will eventually get folded into the TOPLEVEL
- * struct.
- *------------------------------------------------------------------*/
-int first_page;  /* set to zero after first page is read in. */
-
-/*------------------------------------------------------------------
  * (SHEET_DATA *sheet_head) -- my own data structure which I made
  * a global because it was easier to deal with when handing
  * callbacks.  It is defined in structs.h
diff --git a/gattrib/include/prototype.h b/gattrib/include/prototype.h
index 4fc48b7..378a5ab 100644
--- a/gattrib/include/prototype.h
+++ b/gattrib/include/prototype.h
@@ -6,9 +6,6 @@
 /* ---------------- gattrib.c ---------------- */
 void gattrib_really_quit(void);
 gint gattrib_quit(gint return_code);
-void gattrib_main(void *closure, int argc, char *argv[]);
-int main(int argc, char *argv[]);
-
 
 /* -------------- parsecmd.c ----------------- */
 void usage(char *cmd);   
@@ -212,9 +209,7 @@ void x_dialog_unsaved_data_abort_callback(GtkWidget *buttonyes,
 
 void x_dialog_unimplemented_feature();
 
-void x_dialog_exit_announcement(gchar *string, gint return_code);
-void x_dialog_exit_announcement_close_callback(GtkWidget *buttonok, 
-				   gpointer return_code);
+void x_dialog_fatal_error(gchar *string, gint return_code);
 
 int x_dialog_about_keypress_callback(GtkWidget * widget, GdkEventKey * event,
 				     GtkWidget * window);
@@ -289,8 +284,9 @@ void do_show_column_titles(GtkWidget *widget);
 
 
 /* ------------- x_fileselect.c ------------- */
-void x_fileselect_open (void);
+GSList *x_fileselect_open (void);
 void x_fileselect_save (void);
+gboolean x_fileselect_load_files (GSList *filenames);
 
 /* ------------- x_window.c ------------- */
 void x_window_init();
diff --git a/gattrib/src/gattrib.c b/gattrib/src/gattrib.c
index 9d295d0..6e98838 100644
--- a/gattrib/src/gattrib.c
+++ b/gattrib/src/gattrib.c
@@ -84,7 +84,6 @@ void gattrib_really_quit(void)
   }
 }
 
-
 /*------------------------------------------------------------------*/
 /*! \brief gattrib_quit -- wrap up and quit fcn. 
  *
@@ -106,7 +105,6 @@ gint gattrib_quit(gint return_code)
   exit(return_code);
 }
 
-
 /*------------------------------------------------------------------*/
 /*! \brief gattrib_main -- main gattrib fcn. 
  *
@@ -119,12 +117,9 @@ void gattrib_main(void *closure, int argc, char *argv[])
   /* SHEET_DATA *sheet_head is a global */
   /* GtkWidget *main_window is a global */
 
-  int i;
-  int return_code;  /* used when invoking s_toplevel_read_page */
   int argv_index;
-  char *cwd;
-  PAGE *p_local;
-  char *logfile;
+  gchar *cwd;
+  gchar *logfile;
 
 #ifdef HAVE_GTHREAD
   /* Gattrib isn't threaded, but some of GTK's file chooser
@@ -140,17 +135,18 @@ void gattrib_main(void *closure, int argc, char *argv[])
   /* Note that argv_index holds index to first non-flag command line option 
    * (that is, to the first file name) */
   argv_index = parse_commandline(argc, argv);
-  cwd = g_strdup(getcwd(NULL, 1024));
   
   /* ----------  create log file right away ---------- */
   /* ----------  even if logging is enabled ---------- */
+  cwd = g_get_current_dir();
   logfile = g_build_path (G_DIR_SEPARATOR_S,
                           cwd,
                           "gattrib.log",
                           NULL);
   s_log_init (logfile);
   g_free (logfile);
-  
+  g_free (cwd);
+
   s_log_message
     ("gEDA/gattrib version %s%s.%s\n", PREPEND_VERSION_STRING, 
      DOTTED_VERSION, DATE_VERSION);
@@ -174,7 +170,6 @@ void gattrib_main(void *closure, int argc, char *argv[])
     fprintf(stderr,
 	    "conditions; please see the COPYING file for more details.\n\n");
   }
-  
 
   /* ------  register guile (scheme) functions.  Necessary to parse RC file.  ------ */
   g_register_funcs();
@@ -185,198 +180,43 @@ void gattrib_main(void *closure, int argc, char *argv[])
   /* ----- Read in RC files.   ----- */
   g_rc_parse(pr_current, "gattribrc", rc_filename);
 
-  /*
-  i_vars_set(pr_current);
-  */
-
   i_window_vars_set(pr_current);   /* The window vars are used in gschem,
                                       but we need to set them here because
                                       graphical information is used
                                       when introducing new attributes. */
 
-#if DEBUG
-  printf("In gattrib_main -- we have just created and init'ed a new pr_current\n");
-#endif  
-
-
-
-  /* --------  Initialize main_window.  -------- */
-#if DEBUG
-  printf("In gattrib_main -- calling gtk_init. . . ..\n");
-#endif  
   gtk_init(&argc, &argv);
 
   x_window_init();  
-#if DEBUG
-  printf("In gattrib_main -- we have just initialized the main_window.\n");
-#endif  
- 
   
   /* ---------- Initialize SHEET_DATA data structure ---------- */
   sheet_head = s_sheet_data_new();   /* sheet_head was declared in globals.h */
 
-
-  /* ----- Now loop on the files specified on the cmd line & read them in ---- */
-  /* argv[0] = name of this prog (gattrib).  argv_index holds the 
-   * position of the first filename  */
-  i = argv_index;
-  while(argv[i] != NULL) {
-
-    gchar *temp_filename;
-    gchar *filename;
-#ifdef __MINGW32__
-    if (argv[i][1] == ':' && (argv[i][2] == G_DIR_SEPARATOR ||
-                              argv[i][2] == OTHER_PATH_SEPARATER_CHAR))
-#else
-    if (argv[i][0] == G_DIR_SEPARATOR)
-#endif
-    {
-      /* Path is already absolute so no need to do any concat of cwd */
-      temp_filename = g_strdup(argv[i]);
-    } else {
-      temp_filename = g_build_path (G_DIR_SEPARATOR_S, cwd, argv[i], NULL);
-    }
-
-    filename = f_normalize_filename(temp_filename);
-    g_free(temp_filename);
-
-    s_log_message("Loading file [%s]\n", filename);
-    if (!quiet_mode) {
-      printf ("Loading file [%s]\n", filename);
-    }
-
-    s_page_goto (pr_current,
-		 s_page_new (pr_current, filename));
-    
-    return_code = 0;
-    if (first_page == 1) {
-      return_code |= s_toplevel_read_page(filename);
-      first_page = 0;
-    } else {
-      return_code |= s_toplevel_read_page(filename);
-    }
-    
-    /* Now add all items found to the master lists */
-    s_sheet_data_add_master_comp_list_items(pr_current->page_current->object_head); 
-    s_sheet_data_add_master_comp_attrib_list_items(pr_current->page_current->object_head); 
-    
-#if 0
-    /* Note that this must be changed.  We need to input the entire project
-     * before doing anything with the nets because we need to first
-     * determine where they are all connected!   */
-    s_sheet_data_add_master_net_list_items(pr_current->page_current->object_head);    
-    s_sheet_data_add_master_net_attrib_list_items(pr_current->page_current->object_head); 
-#endif
-
-    s_sheet_data_add_master_pin_list_items(pr_current->page_current->object_head); 
-    s_sheet_data_add_master_pin_attrib_list_items(pr_current->page_current->object_head); 
-
-    i++;
-    g_free(filename);
-  }  /* while(argv[i])  */
-  g_free(cwd); /* cwd is allocated with g_strdup so, g_free is correct */
-
-
-  /* ---------- Now complete read-in of project  ---------- */
-  if ( first_page != 1 ) { 
-
-
-    /* ---------- Sort the master lists  ---------- */
-    s_string_list_sort_master_comp_list();
-    s_string_list_sort_master_comp_attrib_list();
-
-#if 0
-    /* Note that this must be changed.  We need to input the entire project
-     * before doing anything with the nets because we need to first
-     * determine where they are all connected!   */
-    s_string_list_sort_master_net_list();
-    s_string_list_sort_master_net_attrib_list();
-#endif
-
-    s_string_list_sort_master_pin_list();
-    s_string_list_sort_master_pin_attrib_list();
-
-    /* ---------- Create and load the tables  ---------- */
-    sheet_head->component_table = s_table_new(sheet_head->comp_count, sheet_head->comp_attrib_count);
-    sheet_head->net_table = s_table_new(sheet_head->net_count, sheet_head->net_attrib_count);
-    sheet_head->pin_table = s_table_new(sheet_head->pin_count, sheet_head->pin_attrib_count);
-    
-    p_local = pr_current->page_head; /* must iterate over all pages in design */
-    while (p_local != NULL) {
-      if (p_local->pid != -1) {   /* only traverse pages which are toplevel */
-	if (p_local->object_head && p_local->page_control == 0) {
-	  s_table_add_toplevel_comp_items_to_comp_table(p_local->object_head);    /* adds all components from page to comp_table */
-
-#if 0
-	  /* Note that this must be changed.  We need to input the entire project
-	   * before doing anything with the nets because we need to first
-	   * determine where they are all connected!   */
-	  s_table_add_toplevel_net_items_to_net_table(p_local->object_head);     /* adds all nets from page to net_table */
-#endif
-
-	  s_table_add_toplevel_pin_items_to_pin_table(p_local->object_head);    /* adds all pins from page to pin_table */
-
-	}
-      }
-      p_local = p_local->next;  /* iterate to next schematic page */
-    }
-#if DEBUG
-    printf("In gattrib_main -- we have just returned from adding to the tables.\n");
-#endif  
-
-
-#if DEBUG
-    /*  -----  Make debug printout of entire object list  -----  */
-    printf("In gattrib_main -- we have just read in the project and filled out pr_current\n");
-    printf("----------------------------  Object list -----------------------------\n");
-    s_page_print_all(pr_current);
-    printf("-----------------------------------------------------------------------\n");
-#endif
-
-    
-    /* -------------- Next, update windows --------------- */
-    x_window_add_items();    /* This updates the top level stuff,
-			      * and then calls another fcn to update
-			      * the GtkSheet itself.  */
-#if DEBUG
-    printf("In gattrib_main -- we have just returned from x_window_add_items.\n");
-#endif  
-    
-  }  /* if (first_page != 1) */
-  else {
-    /* no filename found on command line, therefore we are still on the first page */
-#if DEBUG
-    printf("In gattrib_main -- no files specified on command line.  Throw up filedialog.\n");
-#endif
-    x_fileselect_open ();
-
-    gtk_widget_show( GTK_WIDGET(notebook) );
-    gtk_widget_show( GTK_WIDGET(window) );
-
-    while( gtk_events_pending () ) {
-#ifdef DEBUG
-      printf("In gattrib_main, trying to flush gtk event queue before running gtk_main. . . . \n");
-#endif
-      gtk_main_iteration();  /* force window exposure by running event handler once */
-    }
-    
+  GSList *file_list = NULL;
+  if(argv[argv_index] == NULL) {
+     /* No files specified on the command line, pop up the File open dialog. */
+     file_list = x_fileselect_open();
+     if(file_list == NULL)
+        exit(0);
+  } else {
+     /* Construct the list of filenames from the command line.
+      * argv_index holds the position of the first filename  */
+     while(argv[argv_index] != NULL) {
+        file_list = g_slist_append(file_list, f_normalize_filename(argv[argv_index]));
+        argv_index++;
+     }
   }
 
-  /* ---------- Now verify correctness of read-in design.  ---------- */
-  s_toplevel_verify_design(pr_current);
-
+  /* Load the files */
+  if(x_fileselect_load_files(file_list) == FALSE) {
+     /* just exit the program */
+     exit(1);
+  }
+  
+  g_slist_foreach(file_list, (GFunc)g_free, NULL);
+  g_slist_free(file_list);
 
-  /* ---------- Now enter main event loop for spreadsheet.  ---------- */
-  gtk_widget_show( GTK_WIDGET(window) );  /*  One final show for good measure  */
-  gtk_main_iteration();  /* force window exposure by running event handler once */
   gtk_main();
-
-
-  /* ---------- Spreadsheet has been killed; we are quitting.  ---------- */
-#ifdef DEBUG
-  printf("In gattrib_main, we have exited gtk_main. \n");
-#endif  
-
   exit(0);
 }
 
@@ -391,7 +231,6 @@ void gattrib_main(void *closure, int argc, char *argv[])
  *------------------------------------------------------------------*/
 int main(int argc, char *argv[])
 {
-
   /* This is i18n stuff */
 #if ENABLE_NLS
   setlocale(LC_ALL, "");
@@ -407,8 +246,5 @@ int main(int argc, char *argv[])
   
   scm_boot_guile( argc, argv, gattrib_main, NULL);
 
-#ifdef DEBUG
-  printf("Now exiting main . . . Bye!\n");
-#endif
   exit(0);   /* This is not real exit point.  Real exit is in gattrib_quit. */
 }
diff --git a/gattrib/src/globals.c b/gattrib/src/globals.c
index ece96de..84e6abc 100644
--- a/gattrib/src/globals.c
+++ b/gattrib/src/globals.c
@@ -64,9 +64,6 @@ void (*x_log_update_func)() = NULL;
 void (*variable_set_func)() = i_vars_set;
 int (*load_newer_backup_func)() = NULL;
 
-/* gattrib specific variables */
-int first_page = 1;
-
 /* command line arguments */
 int verbose_mode=FALSE;
 int quiet_mode=FALSE;
diff --git a/gattrib/src/s_toplevel.c b/gattrib/src/s_toplevel.c
index 0e03f71..07aa160 100644
--- a/gattrib/src/s_toplevel.c
+++ b/gattrib/src/s_toplevel.c
@@ -48,10 +48,12 @@
 /* ===================  Public Functions  ====================== */
 
 
-/*------------------------------------------------------------------
- * This fcn reads in a page & calls f_open, which fills out the 
- * pr_current structure.  
- *------------------------------------------------------------------*/
+/*! \brief Reads in a page & calls f_open, which fills out the
+ *         pr_current structure.
+ *
+ *  \param [in] filename file to be opened
+ *  \returns 1 on success, 0 on failure
+ */
 int s_toplevel_read_page(char *filename)
 {
   int file_return_code;
@@ -61,50 +63,43 @@ int s_toplevel_read_page(char *filename)
   
   /* read in and fill out pr_current using f_open and its callees */
   file_return_code = f_open(pr_current, filename);
-  if (!file_return_code) {     /* 1 = success reading in page */
-                               /* 0 = failure reading in page */
-    fprintf(stderr, "Couldn't load schematic [%s]\n", filename);
-  }
   return file_return_code;
 }
 
 
-/*------------------------------------------------------------------
- * This fcn loops through all components in the design looking for
- * components which are placeholders.  Placeholders are inserted into
- * the object list when no symbol file is found.  If this fcn finds 
- * a placeholder, it warns the user.  
- *------------------------------------------------------------------*/
+/*! \brief This function loops through all components in the
+ *         design looking for components which are placeholders.
+ *
+ *  Placeholders are inserted into the object list when
+ *  no symbol file is found.  If this function finds a
+ *  placeholder, it warns the user.
+ *
+ *  \param [in] pr_current a toplevel object
+ */
 void s_toplevel_verify_design(TOPLEVEL *pr_current)
 {
   OBJECT *o_current;
   PAGE *p_current;
   int missing_sym_flag = 0;
 
-#ifdef DEBUG
-   printf("In s_toplevel_verify_design, about to check that all components have sym files.\n");
-#endif
-   
-   p_current = pr_current->page_head; /* must iterate over all pages in design */
-   while (p_current != NULL) {
-     if (p_current->pid != -1) {  /* skip over page_head which has pid = -1. */
-       o_current = p_current->object_head;
-       while (o_current != NULL) { 
-	 /* --- look for object, and verify that it has a symbol file attached. ---- */
-	 if (o_current->type == OBJ_PLACEHOLDER) {  
-	   missing_sym_flag = 1;  /* flag to signal that problem exists.  */
-	 }
-	 o_current = o_current->next;
-       }
-     }  /* if (p_current->pid != -1) */
-     p_current = p_current->next;
-   }
-
-   if (missing_sym_flag) {
-     x_dialog_missing_sym();  /* dialog gives user option to quit */
-   }
-
-   return;
+  p_current = pr_current->page_head; /* must iterate over all pages in design */
+  while (p_current != NULL) {
+    if (p_current->pid != -1) {  /* skip over page_head which has pid = -1. */
+      o_current = p_current->object_head;
+      while (o_current != NULL) {
+        /* --- look for object, and verify that it has a symbol file attached. ---- */
+        if (o_current->type == OBJ_PLACEHOLDER) {
+          missing_sym_flag = 1;  /* flag to signal that problem exists.  */
+        }
+        o_current = o_current->next;
+      }
+    }  /* if (p_current->pid != -1) */
+    p_current = p_current->next;
+  }
+
+  if (missing_sym_flag) {
+    x_dialog_missing_sym();  /* dialog gives user option to quit */
+  }
 }
 
 
@@ -175,15 +170,21 @@ s_toplevel_gtksheet_to_toplevel()
  * open.  Then it figures out if there is already an existing
  * project, and call the appropriate version of s_toplevel_read 
  * depending upon that.
+ * TODO: this should really be done in two stages:
+ * 1. close the current project and reinitialize structures
+ * 2. load the new project
  *------------------------------------------------------------------*/
 void s_toplevel_menubar_file_open(TOPLEVEL *pr_current)
 {
-#ifdef DEBUG
-  printf("In s_toplevel_menubar_file_open, about to create fileselect box\n");
-#endif
+  GSList *file_list;
 
-  x_fileselect_open ();
-  return;
+  file_list = x_fileselect_open();
+  
+  /* Load the files, don't check if it went OK */
+  x_fileselect_load_files(file_list);
+  
+  g_slist_foreach(file_list, (GFunc)g_free, NULL);
+  g_slist_free(file_list);
 }
 
 
diff --git a/gattrib/src/x_dialog.c b/gattrib/src/x_dialog.c
index 204e27e..02833ef 100644
--- a/gattrib/src/x_dialog.c
+++ b/gattrib/src/x_dialog.c
@@ -180,40 +180,32 @@ void x_dialog_delattrib_confirm()
   gtk_widget_destroy(dialog);
 }
 
-/* ========================================================= *
- * Missing symbol file dialog boxes.                         *
- * ========================================================= */
-
-/* --------------------------------------------------------- *
- * This is the "missing symbol file found on object" dialog.
- * It offers the user the chance to close the project without
- * saving because he read a schematic with a missing symbol file.
- * --------------------------------------------------------- */
+/*! \brief This is the "missing symbol file found on object" dialog.
+ *
+ *  It offers the user the chance to close the project without
+ *  saving because he read a schematic with a missing symbol file.
+ */
 void x_dialog_missing_sym()
 {
-  GtkWidget *label;
   GtkWidget *dialog;
-  const char *string = "Warning!  One or more components have been found with missing symbol files!\n\n"
-    "This probably happened because gattrib couldn't find your component libraries,\n"
-    "perhaps because your gafrc or gattribrc files are misconfigured.\n"
+  const char *string = "One or more components have been found with missing symbol files!\n\n"
+    "This probably happened because gattrib couldn't find your component libraries, "
+    "perhaps because your gafrc or gattribrc files are misconfigured.\n\n"
     "Chose \"Quit\" to leave gattrib and fix the problem, or\n"
     "\"Forward\" to continue working with gattrib.\n";
 
-#ifdef DEBUG
-  printf("In x_dialog_missing_sym, creating windows.\n");
-#endif
-
   /* Create the dialog */
-  dialog = gtk_dialog_new_with_buttons("Missing symbol file found for component!", NULL,
-      GTK_DIALOG_MODAL,
-      GTK_STOCK_QUIT, GTK_RESPONSE_REJECT,
-      GTK_STOCK_GO_FORWARD, GTK_RESPONSE_ACCEPT,
-      NULL);
-  
-  label = gtk_label_new(string);
-  gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label, FALSE, FALSE, 0);
-  gtk_widget_show(label);
+  dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL,
+                                  GTK_MESSAGE_WARNING,
+                                  GTK_BUTTONS_NONE,
+                                  string);
+
+  gtk_dialog_add_buttons(GTK_DIALOG(dialog), 
+                  GTK_STOCK_QUIT, GTK_RESPONSE_REJECT,
+                  GTK_STOCK_GO_FORWARD, GTK_RESPONSE_ACCEPT,
+                  NULL);
 
+  gtk_window_set_title(GTK_WINDOW(dialog), "Missing symbol file found for component!");
   gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_REJECT);
 
   switch(gtk_dialog_run(GTK_DIALOG(dialog))) {
@@ -223,7 +215,7 @@ void x_dialog_missing_sym()
 
     default:
       /* Terminate */
-      gattrib_quit(0);
+      exit(0);
       break;
   }
 
@@ -303,32 +295,31 @@ void x_dialog_unimplemented_feature()
   gtk_widget_destroy(dialog);
 }
 
-
-
-/* ========================================================= *
- * Exit announcment callback
- * ========================================================= */
-
-/* --------------------------------------------------------- *
- * This fcn accepts a string and displays it.  It presents
- * only an "OK" button to close the box and exit gattrib.
- * --------------------------------------------------------- */
-void x_dialog_exit_announcement(gchar *string, gint return_code)
+/*! \brief This function displays a dialog with the error string and
+ *         terminates the program.
+ *
+ *  \param [in] string the error string
+ *  \param [in] return_code the exit code
+ *  \return this function never returns
+ */
+void x_dialog_fatal_error(gchar *string, gint return_code)
 {
   GtkWidget *dialog;
+  
+  fprintf(stderr, "%s\n", string);
 
   /* Create the dialog */
   dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL,
-                                  GTK_MESSAGE_WARNING,
+                                  GTK_MESSAGE_ERROR,
                                   GTK_BUTTONS_OK,
                                   string);
 
-  gtk_window_set_title(GTK_WINDOW(dialog), "Attention!");
+  gtk_window_set_title(GTK_WINDOW(dialog), "Fatal error");
 
   gtk_dialog_run(GTK_DIALOG(dialog));
   gtk_widget_destroy(dialog);
   
-  gattrib_quit( GPOINTER_TO_INT(return_code) );
+  exit(GPOINTER_TO_INT(return_code));
 }
 
 /* ========================================================= *
diff --git a/gattrib/src/x_fileselect.c b/gattrib/src/x_fileselect.c
index 05dd4c0..f4e0d3f 100644
--- a/gattrib/src/x_fileselect.c
+++ b/gattrib/src/x_fileselect.c
@@ -159,50 +159,40 @@ x_fileselect_setup_filechooser_filters (GtkFileChooser *filechooser)
 
 }
 
-/*------------------------------------------------------------------
+/*! \brief Open all files specified in the list. The caller
+ *         is responsible for freeing the strings and the list
+ *         itself.
  *
- *------------------------------------------------------------------*/
-static void
-x_fileselect_open_files (GSList *filenames)
+ *  \par Function Description
+ *  The function updates the user interface. At the end of the function, 
+ *  the toplevel's current page is set to the page of the last loaded page.
+ *
+ *  \param [in] filenames list of files to be opened
+ *  \returns FALSE if any of the files could not be opened, TRUE otherwise
+ */
+gboolean
+x_fileselect_load_files (GSList *filenames)
 {
   PAGE *p_local;
-  int return_code = 0;
-  int old_num_rows, old_num_cols;  /* There is a better way . . . */
-
   GSList *filename;
 
-#ifdef DEBUG
-  printf("We have just entered x_fileselect_open_file.\n");
-#endif
-
-  old_num_rows = sheet_head->comp_count;
-  old_num_cols = sheet_head->comp_attrib_count;
-
   /* iterate over selected files */
   for (filename = filenames;
        filename != NULL;
        filename = g_slist_next (filename)) {
     gchar *string = (gchar*)filename->data;
     
-#if DEBUG
-    printf("In x_fileselect_open_file, opening string = %s\n", string);
-#endif
-    
     if (!quiet_mode) {
       s_log_message("Loading file [%s]\n", string);
     }
-    
+
     s_page_goto (pr_current, s_page_new (pr_current, string));
-      
-    return_code = 0;
-    if (first_page == 1) {
-      return_code |= s_toplevel_read_page(string);
-      first_page = 0;
-    } else {
-      return_code |= s_toplevel_read_page(string);
+
+    if(s_toplevel_read_page(string) == 0) {
+       fprintf(stderr, "Couldn't load schematic [%s]\n", string);
+       return FALSE;
     }
-    g_free(string);
-      
+
     /* Now add all items found to the master lists */
     s_sheet_data_add_master_comp_list_items(pr_current->page_current->object_head); 
     s_sheet_data_add_master_comp_attrib_list_items(pr_current->page_current->object_head); 
@@ -216,90 +206,74 @@ x_fileselect_open_files (GSList *filenames)
     
     s_sheet_data_add_master_pin_list_items(pr_current->page_current->object_head);    
     s_sheet_data_add_master_pin_attrib_list_items(pr_current->page_current->object_head); 
-    
-    
   }  	/* end of loop over files     */
   
-  /* Now update rest of project if we had at least one new file */
-  if (return_code) {
-    /* ---------- Sort the master lists  ---------- */
-    s_string_list_sort_master_comp_list();
-    s_string_list_sort_master_comp_attrib_list();
+
+  /* ---------- Sort the master lists  ---------- */
+  s_string_list_sort_master_comp_list();
+  s_string_list_sort_master_comp_attrib_list();
+
 #if 0
-    /* Note that this must be changed.  We need to input the entire project
-     * before doing anything with the nets because we need to first
-     * determine where they are all connected!   */
-    s_string_list_sort_master_net_list();
-    s_string_list_sort_master_net_attrib_list();
+  /* Note that this must be changed.  We need to input the entire project
+   * before doing anything with the nets because we need to first
+   * determine where they are all connected!   */
+  s_string_list_sort_master_net_list();
+  s_string_list_sort_master_net_attrib_list();
 #endif
-    
-    s_string_list_sort_master_pin_list();
-    s_string_list_sort_master_pin_attrib_list();
-    
-    
-    /* ---------- Now create and load the tables  ---------- */
-    sheet_head->component_table = s_table_new(sheet_head->comp_count, sheet_head->comp_attrib_count);
-    sheet_head->net_table = s_table_new(sheet_head->net_count, sheet_head->net_attrib_count);
-    sheet_head->pin_table = s_table_new(sheet_head->pin_count, sheet_head->pin_attrib_count);
-    
-    
-    p_local = pr_current->page_head; /* must iterate over all pages in design */
-    while (p_local != NULL) {
-      if (p_local->pid != -1) {   /* only traverse pages which are toplevel */
+
+  s_string_list_sort_master_pin_list();
+  s_string_list_sort_master_pin_attrib_list();
+
+  /* ---------- Create and load the tables  ---------- */
+  sheet_head->component_table = s_table_new(sheet_head->comp_count, sheet_head->comp_attrib_count);
+  sheet_head->net_table = s_table_new(sheet_head->net_count, sheet_head->net_attrib_count);
+  sheet_head->pin_table = s_table_new(sheet_head->pin_count, sheet_head->pin_attrib_count);
+
+  p_local = pr_current->page_head; /* must iterate over all pages in design */
+  while (p_local != NULL) {
+     if (p_local->pid != -1) {   /* only traverse pages which are toplevel */
         if (p_local->object_head && p_local->page_control == 0) {
-          s_table_add_toplevel_comp_items_to_comp_table(p_local->object_head);    /* adds all objects from page */
+           /* adds all components from page to comp_table */
+           s_table_add_toplevel_comp_items_to_comp_table(p_local->object_head);    
 #if 0
-          /* Note that this must be changed.  We need to input the entire project
-           * before doing anything with the nets because we need to first
-           * determine where they are all connected!   */
-          s_table_add_toplevel_net_items_to_net_table(p_local->object_head);     /* adds all objects from page */
+           /* Note that this must be changed.  We need to input the entire project
+            * before doing anything with the nets because we need to first
+            * determine where they are all connected!   */
+
+           /* adds all nets from page to net_table */
+           s_table_add_toplevel_net_items_to_net_table(p_local->object_head);
 #endif
-          
-          s_table_add_toplevel_pin_items_to_pin_table(p_local->object_head);     /* adds all objects from page */
-          
+
+           /* adds all pins from page to pin_table */
+           s_table_add_toplevel_pin_items_to_pin_table(p_local->object_head);
         }
-      }
-      p_local = p_local->next;  /* iterate to next schematic page */
-    }   /* while(p_local != NULL) */
-    
-#if DEBUG
-    printf("In x_fileselect_open_file -- we have just added more files to the project.\n");
-#endif  
-    
-    /* -------------- update windows --------------- */
-    x_window_add_items();    /* This updates the top level stuff,
-                              * and then calls another fcn to update
-                              * the GtkSheet itself.  */
-    
-#ifdef DEBUG
-    printf("In x_fileselect_open_file -- we have just returned from x_window_add_items.\n");
-#endif
-  } else {
-    fprintf(stderr, "Couldn't open any file!.\n");
+     }
+     p_local = p_local->next;  /* iterate to next schematic page */
   }
 
-  /* try showing all windows now */
-  gtk_widget_show( GTK_WIDGET(notebook));
-  gtk_widget_show( GTK_WIDGET(window));
-  
+  /* -------------- update windows --------------- */
+  x_window_add_items();    /* This updates the top level stuff,
+                            * and then calls another fcn to update
+                            * the GtkSheet itself.  */
+
+
   /* ---------- Now verify correctness of entire design.  ---------- */
   s_toplevel_verify_design(pr_current);  /* pr_current is a global */
-  
+
+  return TRUE;
 }
 
-/*------------------------------------------------------------------
- *  This function opens a file chooser dialog and wait for the user to
- *  select at least one file to load as toplevel's new pages.
- *
- *  The function updates the user interface.
+/*! \brief This function opens a file chooser dialog and waits for the user
+ *         to select at least one file to load as toplevel's new pages.
  *
- *  At the end of the function, the toplevel's current page is set to
- *  the page of the last loaded page.
- *------------------------------------------------------------------*/
-void
+ *  \returns list of files to be opened, or NULL if the user cancelled
+ *           the dialog
+ */
+GSList *
 x_fileselect_open (void)
 {
   GtkWidget *dialog;
+  GSList *filenames = NULL;
 
   dialog = gtk_file_chooser_dialog_new ("Open...",
                                         GTK_WINDOW(window),
@@ -323,22 +297,12 @@ x_fileselect_open (void)
   /* add file filters to dialog */
   x_fileselect_setup_filechooser_filters (GTK_FILE_CHOOSER (dialog));
   gtk_widget_show (dialog);
-  if (gtk_dialog_run ((GtkDialog*)dialog) == GTK_RESPONSE_ACCEPT) {
-    GSList *filenames =
-      gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER (dialog));
-
-    /* open each file */
-    x_fileselect_open_files (filenames);
 
-    if (filenames != NULL) {
-      /* free the list of filenames */
-      g_slist_foreach (filenames, (GFunc)g_free, NULL);
-      g_slist_free (filenames);
-    }
-    
-  }
-  gtk_widget_destroy (dialog);
+  if(gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
+     filenames = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER (dialog));
   
+  gtk_widget_destroy (dialog);
+  return filenames;
 }
 
 /*------------------------------------------------------------------
diff --git a/gattrib/src/x_gtksheet.c b/gattrib/src/x_gtksheet.c
index ea6d6da..b1d7b79 100644
--- a/gattrib/src/x_gtksheet.c
+++ b/gattrib/src/x_gtksheet.c
@@ -92,8 +92,7 @@ x_gtksheet_init()
     fflush(stdout);
     printf("In x_gtksheet_init, no components in comp sheet.\n");
 #endif
-    x_dialog_exit_announcement("No components found in design.  Please check your schematic and try again!\n", -1);
-    gtk_main();  /* Run gtk loop here since the next thing we do is quit. */ 
+    x_dialog_fatal_error("No components found in design.  Please check your schematic and try again!\n", 1);
   }
   
 
diff --git a/gattrib/src/x_window.c b/gattrib/src/x_window.c
index c30202b..b09ba0d 100644
--- a/gattrib/src/x_window.c
+++ b/gattrib/src/x_window.c
@@ -216,17 +216,19 @@ x_window_create_menu(GtkWidget **menubar)
 }
 
 
-/*------------------------------------------------------------------
- * x_window_add_items -- this fcn updates the top level window
- * after a new page is read in.  It does the following:
+/*! \brief This function updates the top level window
+ *         after a new page is read in.  
+ *
+ *  \par Function Description
+ *  It does the following:
  * 
- * 2.  Create a new gtksheet having the current dimensions.
- * 3.  Call x_gktsheet_add_row_labels(comp_count, master_*_list_head)
- * 4.  Call x_gktsheet_add_col_labels(comp_attrib_count, master_*_attrib_list_head)
- * 5.  Call x_gktsheet_add_row_labels(net_count, master_*_list_head)
- * 6.  Call x_gktsheet_add_col_labels(net_attrib_count, master_*_attrib_list_head)
- * 7.  loop on i, j -- call x_gtksheet_add_entry(i, j, attrib_value)
- * 8.  Call gtk_widget_show(window) to show new window.
+ *  2.  Create a new gtksheet having the current dimensions.
+ *  3.  Call x_gktsheet_add_row_labels(comp_count, master_*_list_head)
+ *  4.  Call x_gktsheet_add_col_labels(comp_attrib_count, master_*_attrib_list_head)
+ *  5.  Call x_gktsheet_add_row_labels(net_count, master_*_list_head)
+ *  6.  Call x_gktsheet_add_col_labels(net_attrib_count, master_*_attrib_list_head)
+ *  7.  loop on i, j -- call x_gtksheet_add_entry(i, j, attrib_value)
+ *  8.  Call gtk_widget_show(window) to show new window.
  *------------------------------------------------------------------*/
 void
 x_window_add_items()
@@ -236,59 +238,30 @@ x_window_add_items()
   gchar *text, *error_string;
   gint visibility, show_name_value;
   
-#ifdef DEBUG
-  fflush(stderr);
-  fflush(stdout);
-  printf("Entered x_window_add_items . . . . . ..\n");
-#endif
-
   /* Do these sanity check to prevent later segfaults */
   if (sheet_head->comp_count == 0) {
-    error_string = g_strdup("\n\nNo components found in entire design!  ");
-    error_string = g_strconcat(error_string, 
-                            "Do you have refdeses on your components?  \n", NULL);
-    error_string = g_strconcat(error_string, 
-			    "Exiting. . . .\n", NULL);
-    fprintf(stderr, "%s", error_string);
-    x_dialog_exit_announcement(error_string, -1);
-    g_free(error_string);
-    gtk_main();
+    error_string = "No components found in entire design!\n"
+            "Do you have refdeses on your components?";
+    x_dialog_fatal_error(error_string, 1);
   }
 
   if (sheet_head->comp_attrib_count == 0) {
-    error_string = g_strdup("\n\nNo configurable component attributes found in entire design!  ");
-    error_string = g_strconcat(error_string, 
-                            "Please attach at least some attributes before running gattrib.\n", NULL);
-    error_string = g_strconcat(error_string, "Exiting. . . .\n", NULL);
-    fprintf(stderr, "%s", error_string);
-    x_dialog_exit_announcement(error_string, -2);
-    g_free(error_string);
-    gtk_main();
+    error_string = "No configurable component attributes found in entire design!\n"
+            "Please attach at least some attributes before running gattrib.";
+    x_dialog_fatal_error(error_string, 2);
   }
 
-
   if (sheet_head->pin_count == 0) {
-    error_string = g_strdup("\n\nNo pins found on any components!  ");
-    error_string = g_strconcat(error_string, "Please check your design.\n", NULL);
-    error_string = g_strconcat(error_string, "Exiting. . . .\n", NULL);
-    fprintf(stderr, "%s", error_string);
-    x_dialog_exit_announcement(error_string, -3);
-    g_free(error_string);
-    gtk_main();
+    error_string = "No pins found on any components!\n"
+            "Please check your design.";
+    x_dialog_fatal_error(error_string, 3);
   }
 
 
   /*  initialize the gtksheet. */
-#ifdef DEBUG
-  printf("In x_window_add_items, about to call x_gtksheet_init.\n");
-#endif
   x_gtksheet_init();  /* this creates a new gtksheet having dimensions specified
 		       * in sheet_head->comp_count, etc. . .  */
 
-
-#ifdef DEBUG
-  printf("In x_window_add_items, now load up the row and column labels.\n");
-#endif
   if (sheet_head->comp_count > 0 ) {
     x_gtksheet_add_row_labels(GTK_SHEET(sheets[0]), 
 			      sheet_head->comp_count, sheet_head->master_comp_list_head);
@@ -296,7 +269,6 @@ x_window_add_items()
 			      sheet_head->comp_attrib_count, sheet_head->master_comp_attrib_list_head);
   }
 
-
   /* This is not ready.  I need to implement net attributes */
   if (sheet_head->net_count > 0 ) {
     x_gtksheet_add_row_labels(GTK_SHEET(sheets[1]), 
@@ -316,10 +288,6 @@ x_window_add_items()
 			      sheet_head->pin_attrib_count, sheet_head->master_pin_attrib_list_head);
   }
   
-
-#ifdef DEBUG
-  printf("In x_window_add_items, now put comp attrib values in the comp sheet.\n");
-#endif
   /* ------ Comp sheet: put values in the individual cells ------- */
   num_rows = sheet_head->comp_count;
   num_cols = sheet_head->comp_attrib_count;
@@ -335,14 +303,7 @@ x_window_add_items()
       }
     }
   }
-  /* Do I really need these shows here? */
-  gtk_widget_show( GTK_WIDGET(sheets[0]) );
-  gtk_widget_show( GTK_WIDGET(scrolled_windows[0]) );
-
 
-#ifdef DEBUG
-  printf("In x_window_add_items, now put net attrib values in the net sheet.\n");
-#endif
   /* ------ Net sheet: put values in the individual cells ------- */
   num_rows = sheet_head->net_count;
   num_cols = sheet_head->net_attrib_count;
@@ -358,16 +319,7 @@ x_window_add_items()
       }
     }
   }
-  /* Do I really need these shows here? */
-  if (sheet_head->net_count > 0) {
-    gtk_widget_show( GTK_WIDGET(sheets[1]) );
-    gtk_widget_show( GTK_WIDGET(scrolled_windows[1]) );
-  }
-
 
-#ifdef DEBUG
-  printf("In x_window_add_items, now put pin attrib values in the pin sheet.\n");
-#endif
   /* ------ Pin sheet: put pin attribs in the individual cells ------- */
   num_rows = sheet_head->pin_count;
   num_cols = sheet_head->pin_attrib_count;
@@ -382,19 +334,7 @@ x_window_add_items()
       }
     }
   }
-  /* Do I really need these shows here? */
-  if (sheet_head->pin_count > 0) {
-    gtk_widget_show( GTK_WIDGET(sheets[2]) );
-    gtk_widget_show( GTK_WIDGET(scrolled_windows[2]) );
-  }
-
-  gtk_widget_show( GTK_WIDGET(notebook) );
-  /*  gtk_widget_show( GTK_WIDGET(main_vbox) ); */
-  gtk_widget_show( GTK_WIDGET(window) );
-
-  return;
 
+  gtk_widget_show_all( GTK_WIDGET(window) );
 }
-/* ======================  Private functions  ======================== */
-
 
-- 
1.5.2.2


_______________________________________________
geda-dev mailing list
geda-dev@xxxxxxxxxxxxxx
http://www.seul.org/cgi-bin/mailman/listinfo/geda-dev