From 3a0aed2a3493f91cb473aaed410ce81106efcc46 Mon Sep 17 00:00:00 2001
From: mh17 <mh17>
Date: Thu, 22 Apr 2010 14:31:52 +0000
Subject: [PATCH] fixed DNA not there bug where ACEDB is second server running

---
 src/include/ZMap/zmapFeature.h     |   3 +-
 src/include/ZMap/zmapView.h        |  13 +-
 src/zmapConfig/zmapConfigLoader.c  |   7 +-
 src/zmapControl/zmapControl.c      | 119 ++++++++----
 src/zmapFeature/zmapFeature.c      | 300 +++++------------------------
 src/zmapFeature/zmapFeatureDNA.c   |  94 +++++++--
 src/zmapServer/pipe/pipeServer.c   |  15 +-
 src/zmapView/zmapView.c            |  76 ++++++--
 src/zmapWindow/zmapWindowFeature.c | 285 ++++++++++++++-------------
 9 files changed, 440 insertions(+), 472 deletions(-)

diff --git a/src/include/ZMap/zmapFeature.h b/src/include/ZMap/zmapFeature.h
index 168609dc0..dbf2fef9e 100755
--- a/src/include/ZMap/zmapFeature.h
+++ b/src/include/ZMap/zmapFeature.h
@@ -27,7 +27,7 @@
  * HISTORY:
  * Last edited: Mar  3 13:40 2010 (edgrif)
  * Created: Fri Jun 11 08:37:19 2004 (edgrif)
- * CVS info:   $Id: zmapFeature.h,v 1.173 2010-03-19 08:56:41 mh17 Exp $
+ * CVS info:   $Id: zmapFeature.h,v 1.174 2010-04-22 14:31:52 mh17 Exp $
  *-------------------------------------------------------------------
  */
 #ifndef ZMAP_FEATURE_H
@@ -875,6 +875,7 @@ ZMapFeatureTypeStyle zMapFeatureContextFindStyle(ZMapFeatureContext context, cha
 
 void zMapFeatureContextDestroy(ZMapFeatureContext context, gboolean free_data) ;
 
+gboolean zMapFeatureContextGetDNAStatus(ZMapFeatureContext context);
 
 /* THOSE IN FEATURECONTEXT.C */
 
diff --git a/src/include/ZMap/zmapView.h b/src/include/ZMap/zmapView.h
index 55f53ea64..4fc9901a7 100755
--- a/src/include/ZMap/zmapView.h
+++ b/src/include/ZMap/zmapView.h
@@ -31,7 +31,7 @@
  * HISTORY:
  * Last edited: Jun 12 14:36 2009 (edgrif)
  * Created: Thu May 13 14:59:14 2004 (edgrif)
- * CVS info:   $Id: zmapView.h,v 1.57 2010-03-19 08:56:41 mh17 Exp $
+ * CVS info:   $Id: zmapView.h,v 1.58 2010-04-22 14:31:52 mh17 Exp $
  *-------------------------------------------------------------------
  */
 #ifndef ZMAPVIEW_H
@@ -84,6 +84,17 @@ typedef struct
 
 
 
+// tried to put these into ConnectionData but as ever there's scope issues
+typedef struct
+{
+  char *err_msg;        // from the server mainly
+  GList *feature_sets ;
+  gboolean status;      // load sucessful?
+  unsigned long xwid ;  // X Window id for the xremote widg. */
+
+} LoadFeaturesDataStruct, *LoadFeaturesData ;
+
+
 /* Holds a sequence to be fetched, in the end this will include aligns/blocks etc. */
 typedef struct
 {
diff --git a/src/zmapConfig/zmapConfigLoader.c b/src/zmapConfig/zmapConfigLoader.c
index 4578bccc6..ec8bdcc63 100644
--- a/src/zmapConfig/zmapConfigLoader.c
+++ b/src/zmapConfig/zmapConfigLoader.c
@@ -31,7 +31,7 @@
  * HISTORY:
  * Last edited: Mar  2 14:47 2010 (edgrif)
  * Created: Thu Sep 25 14:12:05 2008 (rds)
- * CVS info:   $Id: zmapConfigLoader.c,v 1.15 2010-04-20 12:00:37 mh17 Exp $
+ * CVS info:   $Id: zmapConfigLoader.c,v 1.16 2010-04-22 14:31:52 mh17 Exp $
  *-------------------------------------------------------------------
  */
 
@@ -654,7 +654,10 @@ gboolean zMapConfigIniGetStylesFromFile(char *styles_list, char *styles_file, GD
                   if(shape_param)
                     {
                       GQuark q = (GQuark) enum_value; // ie the name of the shape
-                      ZMapStyleGlyphShape shape = g_hash_table_lookup(shapes,GINT_TO_POINTER(q));
+                      ZMapStyleGlyphShape shape = NULL;
+
+                      if(shapes)
+                         shape = g_hash_table_lookup(shapes,GINT_TO_POINTER(q));
 
                       if(shape)
                         {
diff --git a/src/zmapControl/zmapControl.c b/src/zmapControl/zmapControl.c
index 697f145a9..d38b0b646 100755
--- a/src/zmapControl/zmapControl.c
+++ b/src/zmapControl/zmapControl.c
@@ -6,12 +6,12 @@
  * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
@@ -28,7 +28,7 @@
  * HISTORY:
  * Last edited: Feb  1 15:12 2010 (edgrif)
  * Created: Thu Jul 24 16:06:44 2003 (edgrif)
- * CVS info:   $Id: zmapControl.c,v 1.98 2010-03-04 15:09:51 mh17 Exp $
+ * CVS info:   $Id: zmapControl.c,v 1.99 2010-04-22 14:31:52 mh17 Exp $
  *-------------------------------------------------------------------
  */
 
@@ -71,14 +71,14 @@ static ZMapCallbacks zmap_cbs_G = NULL ;
 
 /* Holds callbacks we set in the level below us to be called back on. */
 ZMapViewCallbacksStruct view_cbs_G = {
-  enterCB, 
+  enterCB,
   leaveCB,
-  dataLoadCB, 
-  controlFocusCB, 
-  controlSelectCB, 
+  dataLoadCB,
+  controlFocusCB,
+  controlSelectCB,
   controlSplitToPatternCB,
-  controlVisibilityChangeCB, 
-  viewStateChangeCB, 
+  controlVisibilityChangeCB,
+  viewStateChangeCB,
   viewKilledCB
 } ;
 
@@ -95,7 +95,7 @@ ZMapViewCallbacksStruct view_cbs_G = {
 /* This routine must be called just once before any other zmaps routine, it is a fatal error
  * if the caller calls this routine more than once. The caller must supply all of the callback
  * routines.
- * 
+ *
  * Note that since this routine is called once per application we do not bother freeing it
  * via some kind of zmaps terminate routine. */
 void zMapInit(ZMapCallbacks callbacks)
@@ -145,7 +145,7 @@ gboolean zMapRaise(ZMap zmap)
   /* Presents a window to the user. This may mean raising the window
    * in the stacking order, deiconifying it, moving it to the current
    * desktop, and/or giving it the keyboard focus, possibly dependent
-   * on the user's platform, window manager, and preferences. 
+   * on the user's platform, window manager, and preferences.
    */
   gtk_window_present(GTK_WINDOW(zmap->toplevel));
 
@@ -183,7 +183,7 @@ gboolean zmapConnectViewConfig(ZMap zmap, ZMapView view, char *config)
   result = zMapViewConnect(view, config) ;
 
   zmapControlWindowSetGUIState(zmap) ;
-  
+
   return result ;
 }
 
@@ -198,7 +198,7 @@ gboolean zMapConnectView(ZMap zmap, ZMapView view)
 
   if ((result = zMapViewConnect(view, NULL)))
     zmapControlWindowSetGUIState(zmap) ;
-  
+
   return result ;
 }
 
@@ -236,15 +236,15 @@ gboolean zMapDeleteView(ZMap zmap, ZMapView view)
 
 
 /* Reset an existing ZMap, this call will:
- * 
+ *
  *    - Completely reset a ZMap window to blank with no sequences displayed and no
  *      threads attached or anything.
  *    - Frees all ZMap window data
  *    - Kills all existings server threads etc.
- * 
+ *
  * After this call the ZMap will be ready for the user to specify a new sequence to be
  * loaded.
- * 
+ *
  *  */
 gboolean zMapReset(ZMap zmap)
 {
@@ -319,7 +319,7 @@ gboolean zMapDestroy(ZMap zmap)
 
 /*
  * These functions are internal to zmapControl.
- * 
+ *
  */
 
 
@@ -416,7 +416,7 @@ void zmapControlSetGUIVisChange(ZMap zmap, ZMapWindowVisibilityChange vis_change
 
 /* Called when the user kills the toplevel window of the ZMap either by clicking the "quit"
  * button or by using the window manager frame menu to kill the window.
- * 
+ *
  * Really this function just signals the zmap to be killed. */
 void zmapControlSignalKill(ZMap zmap)
 {
@@ -435,7 +435,7 @@ void zmapControlSignalKill(ZMap zmap)
 void zmapControlDoKill(ZMap zmap)
 {
   g_return_if_fail((zmap->state != ZMAP_DYING)) ;
- 
+
 
   /* set our state to DYING....so we don't respond to anything anymore.... */
   /* Must set this as this will prevent any further interaction with the ZMap as
@@ -468,7 +468,7 @@ void zmapControlLoadCB(ZMap zmap)
       ZMapView curr_view ;
 
       /* for now we are just doing the current view but this will need to change to allow a kind
-       * of global load of all views if there is no current selected view, or perhaps be an error 
+       * of global load of all views if there is no current selected view, or perhaps be an error
        * if no view is selected....perhaps there should always be a selected view. */
       zMapAssert(zmap->focus_viewwindow) ;
 
@@ -502,7 +502,7 @@ void zmapControlResetCB(ZMap zmap)
       view_state = zMapViewGetStatus(curr_view) ;
 
       /* for now we are just doing the current view but this will need to change to allow a kind
-       * of global load of all views if there is no current selected view, or perhaps be an error 
+       * of global load of all views if there is no current selected view, or perhaps be an error
        * if no view is selected....perhaps there should always be a selected view. */
       zMapViewReset(curr_view) ;
 
@@ -567,8 +567,8 @@ static ZMap createZMap(void *app_data)
 
   /* Use default hashing functions, but THINK ABOUT THIS, MAY NEED TO ATTACH DESTROY FUNCTIONS. */
   zmap->viewwindow_2_parent = g_hash_table_new(NULL, NULL) ;
-  
-  
+
+
   zmap->view2infopanel = g_hash_table_new_full(NULL, NULL, NULL, infoPanelLabelsHashCB);
 
   return zmap ;
@@ -595,15 +595,62 @@ static void destroyZMap(ZMap zmap)
 
 
 
+
 /* Called when a view has loaded data. */
+/*
+ * mh17: this appear to be only for the GUI
+ * but we need to tell x-remote about this and also to give some data about what data got loaded
+ * as view_data is NULL in all existing calls I'll specify the following:
+ * - if view_data == NULL then update GUI stuff
+ * - else send a message to x-remote
+  */
 static void dataLoadCB(ZMapView view, void *app_data, void *view_data)
 {
   ZMap zmap = (ZMap)app_data ;
 
-  /* Update title etc. */
-  updateControl(zmap, view) ;
+  if(!view_data)
+  {
+      /* Update title etc. */
+      updateControl(zmap, view) ;
 
-  zmapControlWindowSetGUIState(zmap) ;
+      zmapControlWindowSetGUIState(zmap) ;
+  }
+  else if(zmap->xremote_client)
+  {
+    LoadFeaturesData lfd = (LoadFeaturesData ) view_data;
+    char *request ;
+    char *response = NULL;
+    GList *features;
+    char * featurelist = NULL;
+    char *f;
+
+    for(features = lfd->feature_sets;features;features = features->next)
+      {
+        f = (char *) g_quark_to_string(GPOINTER_TO_UINT(features->data));
+        if(!featurelist)
+            featurelist = g_strdup(f);
+        else
+            featurelist = g_strjoin(";",featurelist,f,NULL);
+      }
+
+    request = g_strdup_printf(
+            "<zmap> <request action=\"features_loaded\">"
+            " <client xwid=\"0x%lx\" />"
+            " <featureset names=\"%s\" />"
+            " <status value=\"%d\" message=\"%s\" />"
+            "</request></zmap>",
+            lfd->xwid, featurelist,(int) lfd->status,lfd->err_msg ? lfd->err_msg : "OK") ;
+
+    if (zMapXRemoteSendRemoteCommand(zmap->xremote_client, request, &response) != ZMAPXREMOTE_SENDCOMMAND_SUCCEED)
+      {
+        response = response ? response : zMapXRemoteGetResponse(zmap->xremote_client);
+        zMapLogWarning("Notify of view closing failed: \"%s\"", response) ;
+      }
+
+    g_free(request);
+    g_free(featurelist);
+
+  }
 
   return ;
 }
@@ -612,7 +659,7 @@ static void dataLoadCB(ZMapView view, void *app_data, void *view_data)
 
 /* This routine gets called when someone clicks in one of the zmap windows....it
  * handles general focus handling of windows etc.
- */ 
+ */
 static void controlFocusCB(ZMapViewWindow view_window, void *app_data, void *view_data_unused)
 {
   ZMap zmap = (ZMap)app_data ;
@@ -628,7 +675,7 @@ static void controlFocusCB(ZMapViewWindow view_window, void *app_data, void *vie
 
   /* Step through each of the navigators and get their size and
    * maximise the current view_window->view navigator */
-  
+
   do
     {
       ZMapView view_item = (ZMapView)(list_item->data);
@@ -685,10 +732,10 @@ static void controlSelectCB(ZMapViewWindow view_window, void *app_data, void *vi
                                                                   vselect->xml_handler.xml_events,
                                                                   vselect->xml_handler.start_handlers,
                                                                   vselect->xml_handler.end_handlers,
-                                                                  vselect->xml_handler.handler_data);        
+                                                                  vselect->xml_handler.handler_data);
     }
 #endif
-  
+
   return ;
 }
 
@@ -721,7 +768,7 @@ static void controlSplitToPatternCB(ZMapViewWindow view_window, void *app_data,
           {
             GList *tmp_list = split->touched_window_list;
             int i = 2;          /* Go through loop twice */
-            
+
             /* First time sets to the last list member, second time if there is another, the one before that. */
             for(tmp_list = g_list_last(tmp_list); i > 0 && tmp_list; i--)
               {
@@ -757,7 +804,7 @@ static void controlSplitToPatternCB(ZMapViewWindow view_window, void *app_data,
           split->touched_window_list = g_list_append(split->touched_window_list, new_view_window);
         }
     }
-  
+
   zmapControlWindowSetGUIState(zmap) ;
 
   /* leave this to the last minute */
@@ -828,10 +875,10 @@ static void viewStateChangeCB(ZMapView view, void *app_data, void *view_data)
  *
  * 2) The View may have died because it has detected an error and is now signalling us
  *    to say it has died.
- * 
+ *
  * NOTE we have made a policy decision to kill the whole zmap when the last view
  * goes away.
- * 
+ *
  *  */
 static void viewKilledCB(ZMapView view, void *app_data, void *view_data)
 {
@@ -842,7 +889,7 @@ static void viewKilledCB(ZMapView view, void *app_data, void *view_data)
 
   if (!zmap->view_list)
     {
-      
+
       if (zmap->state != ZMAP_DYING)
 	{
 	  zMapLogCritical("ZMap \"%s\": the last view has died but zmap is not in ZMAP_DYING state.,"
@@ -1029,7 +1076,7 @@ static void removeView(ZMap zmap, ZMapView view, unsigned long xwid)
   else
     {
       g_hash_table_remove(zmap->view2infopanel, view);
-      
+
       zmap->view_list = g_list_remove(zmap->view_list, view) ;
 
       if (zmap->xremote_client)
diff --git a/src/zmapFeature/zmapFeature.c b/src/zmapFeature/zmapFeature.c
index 1b43343f5..062aaff33 100755
--- a/src/zmapFeature/zmapFeature.c
+++ b/src/zmapFeature/zmapFeature.c
@@ -29,7 +29,7 @@
  * HISTORY:
  * Last edited: Dec 14 11:20 2009 (edgrif)
  * Created: Fri Jul 16 13:05:58 2004 (edgrif)
- * CVS info:   $Id: zmapFeature.c,v 1.127 2010-04-15 11:19:03 mh17 Exp $
+ * CVS info:   $Id: zmapFeature.c,v 1.128 2010-04-22 14:31:53 mh17 Exp $
  *-------------------------------------------------------------------
  */
 
@@ -2295,13 +2295,41 @@ static ZMapFeatureContextExecuteStatus mergePreCB(GQuark key,
 	    if(new)
 	      (*diff_path_ptr)->parent = *view_path_parent_ptr;
 
-
-	    if (feature_any->struct_type == ZMAPFEATURE_STRUCT_BLOCK &&
+#if MH17_OLD_CODE
+          if (feature_any->struct_type == ZMAPFEATURE_STRUCT_BLOCK &&
+            (*view_path_ptr)->unique_id == feature_any->unique_id)
+            {
+              ((ZMapFeatureBlock)(*view_path_ptr))->features_start =
+                              ((ZMapFeatureBlock)(feature_any))->features_start;
+              ((ZMapFeatureBlock)(*view_path_ptr))->features_end   =
+                              ((ZMapFeatureBlock)(feature_any))->features_end;
+            }
+#else
+// debugging reveals that features start and end are 1.0 in the new data and semsible in the old
+// maybe 1,0 gets reprocessed into start,end?? so let's leave it as it used to run
+// BUT: this code should only run if not a new block 'cos if it's new then we've just
+// assinged the pointer
+// thsi is a block which may hold a sequence, the dna featureset is another struct
+	    if (!new && feature_any->struct_type == ZMAPFEATURE_STRUCT_BLOCK &&
 		(*view_path_ptr)->unique_id == feature_any->unique_id)
 	      {
-		((ZMapFeatureBlock)(*view_path_ptr))->features_start = ((ZMapFeatureBlock)(feature_any))->features_start;
-		((ZMapFeatureBlock)(*view_path_ptr))->features_end   = ((ZMapFeatureBlock)(feature_any))->features_end;
-	      }
+               ZMapFeatureBlock vptr = (ZMapFeatureBlock)(*view_path_ptr);
+               ZMapFeatureBlock feat = (ZMapFeatureBlock) feature_any;
+
+	  	   vptr->features_start = feat->features_start;
+		   vptr->features_end   = feat->features_end;
+
+              // mh17: DNA did not get merged from a non first source
+              // by analogy with the above we need to copy the sequence too, in fact any Block only data
+              // sequence contains a pointer to a (long) string - can we just copy it?
+              // seems to work without double frees...
+              if(!vptr->sequence.sequence)      // let's keep the first one, should be the same
+              {
+                memcpy(&vptr->block_to_sequence,&feat->block_to_sequence,sizeof(ZMapAlignBlockStruct));
+                memcpy(&vptr->sequence,&feat->sequence,sizeof(ZMapSequenceStruct));
+	        }
+            }
+#endif
 	  }
 
 	/* general code stop */
@@ -2346,257 +2374,29 @@ static ZMapFeatureContextExecuteStatus mergePreCB(GQuark key,
       break;
 
 
-#ifdef GENERALISING
-    case ZMAPFEATURE_STRUCT_ALIGN:
-      {
-	ZMapFeatureAlignment feature_align = (ZMapFeatureAlignment)feature_any ;
-	ZMapFeatureContext server_context = (ZMapFeatureContext)(feature_any->parent) ;
-	gboolean is_master_align = FALSE;
-#ifdef MESSES_UP_HASH
-	/* Always remove from the server context */
-	result = zMapFeatureAnyRemoveFeature((ZMapFeatureAny)server_context, feature_any) ;
-	zMapAssert(result) ;
-#endif /* MESSES_UP_HASH */
-	if(server_context->master_align == feature_align)
-	  {
-	    is_master_align = TRUE;
-	    server_context->master_align = NULL;
-	  }
-
-	feature_any->parent = NULL;
-	status = ZMAP_CONTEXT_EXEC_STATUS_OK_DELETE;
-	/* If there are no children then we don't add it, we don't keep empty aligns etc. */
-	if (feature_any->children)
-	  {
-	    ZMapFeatureAny diff_align ;
-	    children = TRUE ;
-
-	    /* If its not in the current context then add it, otherwise copy it so we can add
-	     * features further down the tree. */
-	    if (!(merge_data->current_view_align
-		  = (ZMapFeatureAlignment)zMapFeatureAnyGetFeatureByID((ZMapFeatureAny)(merge_data->view_context),
-								       feature_any->unique_id)))
-	      {
-
-		/* If its new we can simply copy a pointer over to the diff context
-		 * and stop recursing.... */
-		zMapFeatureContextAddAlignment(merge_data->view_context, feature_align, FALSE);
-		merge_data->current_view_align = feature_align ;
-
-		merge_data->new_features = new = TRUE ;
-
-		diff_align = (ZMapFeatureAny)feature_align ;
-
-                /* but we need to reset parent pointer....*/
-		diff_align->parent = (ZMapFeatureAny)(merge_data->view_context) ;
-
-		status = ZMAP_CONTEXT_EXEC_STATUS_DONT_DESCEND ;
-	      }
-	    else
-	      {
-		/* If the feature is there we need to copy it and then recurse down until
-		 * we get to the individual feature level. */
-		diff_align = zmapFeatureAnyCopy((ZMapFeatureAny)feature_align, NULL) ;
-		featureAnyAddToDestroyList(merge_data->diff_context, diff_align) ;
-	      }
-
-	    /* Add align to diff context, n.b. we do _not_ set a destroy function. */
-	    featureAnyAddFeature((ZMapFeatureAny)(merge_data->diff_context), (ZMapFeatureAny)diff_align) ;
-	    merge_data->current_diff_align = (ZMapFeatureAlignment)diff_align ;
-
-	    if (new)
-	      diff_align->parent = (ZMapFeatureAny)(merge_data->view_context) ;
-
-	    if (is_master_align)
-	      {
-		merge_data->diff_context->master_align = (ZMapFeatureAlignment)diff_align ;
-	      }
-	  }
-
-	break;
-      }
-
-    case ZMAPFEATURE_STRUCT_BLOCK:
-      {
-	ZMapFeatureBlock feature_block = (ZMapFeatureBlock)feature_any ;
-	ZMapFeatureAlignment server_align = (ZMapFeatureAlignment)(feature_any->parent) ;
-#ifdef MESSES_UP_HASH
-	/* remove from server align */
-	result = zMapFeatureAnyRemoveFeature((ZMapFeatureAny)server_align, feature_any) ;
-	zMapAssert(result) ;
-#endif
-	feature_any->parent = NULL;
-	status = ZMAP_CONTEXT_EXEC_STATUS_OK_DELETE;
-
-	/* If there are no children then we don't add it, we don't keep empty aligns etc. */
-	if (feature_any->children)
-	  {
-	    ZMapFeatureAny diff_block ;
-
-	    children = TRUE ;
-
-	    /* If its not in the current context then add it. */
-	    if (!(merge_data->current_view_block
-		  = (ZMapFeatureBlock)zMapFeatureAnyGetFeatureByID((ZMapFeatureAny)(merge_data->current_view_align),
-								   feature_any->unique_id)))
-	      {
-		/* add to the full context align */
-		zMapFeatureAlignmentAddBlock(merge_data->current_view_align, feature_block);
-		merge_data->current_view_block = feature_block ;
-
-		merge_data->new_features = new = TRUE ;
-
-		/* If its new we can simply copy a pointer over to the diff context
-		 * and stop recursing.... */
-		diff_block = (ZMapFeatureAny)feature_block ;
-
-		/* but we need to reset parent pointer....*/
-		diff_block->parent = (ZMapFeatureAny)(merge_data->current_view_align) ;
-
-		status = ZMAP_CONTEXT_EXEC_STATUS_DONT_DESCEND ;
-
-	      }
-	    else
-	      {
-		/* Add to diff align. */
-		diff_block = zmapFeatureAnyCopy((ZMapFeatureAny)feature_block, NULL) ;
-		featureAnyAddToDestroyList(merge_data->diff_context, (ZMapFeatureAny)diff_block) ;
-	      }
-
-	    featureAnyAddFeature((ZMapFeatureAny)(merge_data->current_diff_align), diff_block) ;
-	    merge_data->current_diff_block = (ZMapFeatureBlock)diff_block ;
-
-	    if (new)
-	      diff_block->parent = (ZMapFeatureAny)(merge_data->current_view_align) ;
-
-	  }
-
-	break;
-      }
-
-    case ZMAPFEATURE_STRUCT_FEATURESET:
-      {
-	ZMapFeatureSet feature_set = (ZMapFeatureSet)feature_any ;
-	ZMapFeatureBlock server_block = (ZMapFeatureBlock)(feature_any->parent);
-#ifdef MESSES_UP_HASH
-	/* remove from server align */
-	result = zMapFeatureAnyRemoveFeature((ZMapFeatureAny)server_block, feature_any) ;
-	zMapAssert(result) ;
-#endif
-	feature_any->parent = NULL;
-	status = ZMAP_CONTEXT_EXEC_STATUS_OK_DELETE;
-	/* If there are no children then we don't add it, we don't keep empty aligns etc. */
-	if (feature_any->children)
-	  {
-	    ZMapFeatureAny diff_set ;
-
-	    children = TRUE ;
-
-	    if (!(merge_data->current_view_set
-		  = (ZMapFeatureSet)zMapFeatureAnyGetFeatureByID((ZMapFeatureAny)(merge_data->current_view_block),
-								 feature_any->unique_id)))
-	      {
-		/* add to the full context block */
-		zMapFeatureBlockAddFeatureSet(merge_data->current_view_block, (ZMapFeatureSet)feature_set);
-		merge_data->current_view_set = feature_set;
-
-		merge_data->new_features = new = TRUE ;
-
-		/* If its new we can simply copy a pointer over to the diff context
-		 * and stop recursing.... */
-		diff_set = (ZMapFeatureAny)feature_set ;
-
-		/* but we need to reset parent pointer....*/
-		diff_set->parent = (ZMapFeatureAny)(merge_data->current_view_block) ;
-
-		status = ZMAP_CONTEXT_EXEC_STATUS_DONT_DESCEND ;
-
-	      }
-	    else
-	      {
-		diff_set = zmapFeatureAnyCopy((ZMapFeatureAny)feature_set, NULL) ;
-		((ZMapFeatureSet)diff_set)->style = feature_set->style ;
-
-		featureAnyAddToDestroyList(merge_data->diff_context, (ZMapFeatureAny)diff_set) ;
-	      }
-
-	    featureAnyAddFeature((ZMapFeatureAny)(merge_data->current_diff_block), diff_set) ;
-	    merge_data->current_diff_set = (ZMapFeatureSet)diff_set ;
-
-	    if (new)
-	      diff_set->parent = (ZMapFeatureAny)(merge_data->current_view_block) ;
-
-	  }
-
-	break;
-      }
-
-    case ZMAPFEATURE_STRUCT_FEATURE:
-      {
-	ZMapFeature feature = (ZMapFeature)(feature_any) ;
-	ZMapFeatureSet server_set = (ZMapFeatureSet)(feature_any->parent) ;
-	ZMapFeatureAny diff_feature ;
-#ifdef MESSES_UP_HASH
-	/* remove from the server set */
-	result = zMapFeatureAnyRemoveFeature((ZMapFeatureAny)server_set, feature_any) ;
-	zMapAssert(result) ;
-#endif
-	feature_any->parent = NULL;
-	status = ZMAP_CONTEXT_EXEC_STATUS_OK_DELETE;
-
-	/* Note that features do not have children _ever_ so we are only concerned with copying
-	 * pointers if we find new features. */
-
-	/* If its not in the current context then add it. */
-	if (!(zMapFeatureAnyGetFeatureByID((ZMapFeatureAny)(merge_data->current_view_set),
-					   feature_any->unique_id)))
-	  {
-	    merge_data->new_features = new = TRUE ;
-
-	    /* If its new we can simply copy a pointer over to the diff context
-	     * and stop recursing.... */
-	    diff_feature = (ZMapFeatureAny)feature ;
-
-
-#ifdef ED_G_NEVER_INCLUDE_THIS_CODE
-	    /* I don't think we need to do this because features do not have children. */
-
-	    featureAnyAddToRemoveList(merge_data->diff_context, diff_feature) ;
-	    status = ZMAP_CONTEXT_EXEC_STATUS_DONT_DESCEND ;
-#endif /* ED_G_NEVER_INCLUDE_THIS_CODE */
-
-	    /* We need to reset parent pointer....and the style pointer....
-	     * order is critical here since featureany call resets parent... */
-	    featureAnyAddFeature((ZMapFeatureAny)merge_data->current_diff_set, diff_feature) ;
-
-	    /* add to the full context set */
-	    featureAnyAddFeature((ZMapFeatureAny)(merge_data->current_view_set), diff_feature);
-
-
-	    if (merge_debug_G)
-	      zMapLogWarning("feature(%p)->parent = %p. current_view_set = %p",
-			     feature, feature->parent, merge_data->current_view_set);
-	  }
-
-	break;
-      }
-#endif /* GENERALISING */
-
     default:
       {
-	zMapAssertNotReached() ;
-	break;
+      zMapAssertNotReached() ;
+      break;
       }
     }
 
-
   if (merge_debug_G)
     zMapLogWarning("%s (%p) '%s' is %s and has %s",
-		   zMapFeatureStructType2Str(feature_any->struct_type),
-		   feature_any,
-		   g_quark_to_string(feature_any->unique_id),
-		   (new == TRUE ? "new" : "old"),
-		   (children ? "children and was added" : "no children and was not added"));
+               zMapFeatureStructType2Str(feature_any->struct_type),
+               feature_any,
+               g_quark_to_string(feature_any->unique_id),
+               (new == TRUE ? "new" : "old"),
+               (children ? "children and was added" : "no children and was not added"));
+#if 0
+    printf("%s (%p) '%s' is %s and has %s\n",
+               zMapFeatureStructType2Str(feature_any->struct_type),
+               feature_any,
+               g_quark_to_string(feature_any->unique_id),
+               (new == TRUE ? "new" : "old"),
+               (children ? "children and was added" : "no children and was not added"));
+#endif
+
 
   return status;
 }
diff --git a/src/zmapFeature/zmapFeatureDNA.c b/src/zmapFeature/zmapFeatureDNA.c
index 34a8a3901..385d59d6d 100755
--- a/src/zmapFeature/zmapFeatureDNA.c
+++ b/src/zmapFeature/zmapFeatureDNA.c
@@ -6,12 +6,12 @@
  * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
@@ -23,13 +23,13 @@
  * 	Ed Griffiths (Sanger Institute, UK) edgrif@sanger.ac.uk,
  *      Roy Storey (Sanger Institute, UK) rds@sanger.ac.uk
  *
- * Description: 
+ * Description:
  *
  * Exported functions: See XXXXXXXXXXXXX.h
  * HISTORY:
  * Last edited: Jul 15 09:04 2009 (rds)
  * Created: Tue Apr  7 10:32:21 2009 (rds)
- * CVS info:   $Id: zmapFeatureDNA.c,v 1.5 2010-03-04 15:10:23 mh17 Exp $
+ * CVS info:   $Id: zmapFeatureDNA.c,v 1.6 2010-04-22 14:31:53 mh17 Exp $
  *-------------------------------------------------------------------
  */
 
@@ -48,7 +48,7 @@ gboolean zMapFeatureBlockDNA(ZMapFeatureBlock block,
 
   zMapAssert( block ) ;
 
-  if(block->sequence.sequence && 
+  if(block->sequence.sequence &&
      block->sequence.type != ZMAPSEQUENCE_NONE &&
      block->sequence.type == ZMAPSEQUENCE_DNA  &&
      (context = (ZMapFeatureContext)zMapFeatureGetParentGroup((ZMapFeatureAny)block,
@@ -89,7 +89,7 @@ GQuark zMapFeatureDNAFeatureID(ZMapFeatureBlock block)
       dna_id = zMapFeatureCreateID(ZMAPSTYLE_MODE_RAW_SEQUENCE,
 				   dna_name, ZMAPSTRAND_FORWARD,
 				   block->block_to_sequence.q1,
-				   block->block_to_sequence.q2, 
+				   block->block_to_sequence.q2,
 				   0, 0);
       g_free(dna_name);
     }
@@ -105,7 +105,7 @@ gboolean zMapFeatureDNACreateFeatureSet(ZMapFeatureBlock block, ZMapFeatureSet *
   GQuark dna_set_id = 0;
 
   dna_set_id = zMapFeatureSetCreateID(ZMAP_FIXED_STYLE_DNA_NAME);
-  
+
   if(!(dna_feature_set = zMapFeatureBlockGetSetByID(block, dna_set_id)))
     {
       GQuark original_id = 0;
@@ -140,9 +140,9 @@ void zMapFeatureDNAAddSequenceData(ZMapFeature dna_feature, char *dna_str, int s
   return ;
 }
 
-ZMapFeature zMapFeatureDNACreateFeature(ZMapFeatureBlock     block, 
+ZMapFeature zMapFeatureDNACreateFeature(ZMapFeatureBlock     block,
 					ZMapFeatureTypeStyle style,
-					char *dna_str, 
+					char *dna_str,
 					int   sequence_length)
 {
   ZMapFeatureSet dna_feature_set = NULL;
@@ -162,7 +162,7 @@ ZMapFeature zMapFeatureDNACreateFeature(ZMapFeatureBlock     block,
       char *feature_name, *sequence, *ontology;
       GQuark dna_id;
       int block_start, block_end;
-      
+
       block_start = block->block_to_sequence.q1 ;
       block_end   = block->block_to_sequence.q2 ;
 
@@ -205,13 +205,83 @@ ZMapFeature zMapFeatureDNACreateFeature(ZMapFeatureBlock     block,
 	  block->sequence.sequence = dna_feature->feature.sequence.sequence;
 	  block->sequence.type     = dna_feature->feature.sequence.type;
 	  block->sequence.length   = dna_feature->feature.sequence.length;
-	  
+
 	}
 
       if(feature_name)
 	g_free(feature_name);
     }
-  
+
 
   return dna_feature;
 }
+
+
+
+typedef struct
+{
+  gboolean exists;
+}BlockHasDNAStruct, *BlockHasDNA;
+
+/* Function to check whether any of the blocks has dna */
+static ZMapFeatureContextExecuteStatus oneBlockHasDNA(GQuark key,
+                                                      gpointer data,
+                                                      gpointer user_data,
+                                                      char **error_out)
+{
+  ZMapFeatureAny feature_any = (ZMapFeatureAny)data;
+  ZMapFeatureBlock     feature_block = NULL;
+  ZMapFeatureStructType feature_type = ZMAPFEATURE_STRUCT_INVALID;
+
+  BlockHasDNA dna = (BlockHasDNA)user_data;
+
+  feature_type = feature_any->struct_type;
+
+  switch(feature_type)
+    {
+    case ZMAPFEATURE_STRUCT_BLOCK:
+      feature_block = (ZMapFeatureBlock)feature_any;
+      if(!dna->exists)
+        dna->exists = (gboolean)(feature_block->sequence.length ? TRUE : FALSE);
+      break;
+    case ZMAPFEATURE_STRUCT_CONTEXT:
+    case ZMAPFEATURE_STRUCT_FEATURESET:
+    case ZMAPFEATURE_STRUCT_FEATURE:
+    case ZMAPFEATURE_STRUCT_ALIGN:
+      break;
+    case ZMAPFEATURE_STRUCT_INVALID:
+    default:
+      zMapAssertNotReached();
+      break;
+
+    }
+
+  return ZMAP_CONTEXT_EXEC_STATUS_OK;
+}
+
+
+gboolean zMapFeatureContextGetDNAStatus(ZMapFeatureContext context)
+{
+  gboolean drawable = FALSE;
+  BlockHasDNAStruct dna = {0};
+
+  /* We just need one of the blocks to have DNA.
+   * This enables us to turn on this button as we
+   * can't have half sensitivity.  Any block which
+   * doesn't have DNA creates a warning for the user
+   * to complain about.
+   */
+
+  if(context)
+    {
+      zMapFeatureContextExecute((ZMapFeatureAny)context,
+                                ZMAPFEATURE_STRUCT_BLOCK,
+                                oneBlockHasDNA,
+                                &dna);
+
+      drawable = dna.exists;
+    }
+
+  return drawable;
+}
+
diff --git a/src/zmapServer/pipe/pipeServer.c b/src/zmapServer/pipe/pipeServer.c
index a9de40641..22b636629 100755
--- a/src/zmapServer/pipe/pipeServer.c
+++ b/src/zmapServer/pipe/pipeServer.c
@@ -34,7 +34,7 @@
  * HISTORY:
  * Last edited: Jan 14 10:10 2010 (edgrif)
  * Created: 2009-11-26 12:02:40 (mh17)
- * CVS info:   $Id: pipeServer.c,v 1.21 2010-03-19 14:20:54 mh17 Exp $
+ * CVS info:   $Id: pipeServer.c,v 1.22 2010-04-22 14:31:53 mh17 Exp $
  *-------------------------------------------------------------------
  */
 
@@ -385,7 +385,7 @@ static ZMapServerResponseType openConnection(void *server_in, gboolean sequence_
               pipeGetSequence(server);
             }
 	  }
-	  else
+	if(!retval || result != ZMAP_SERVERRESPONSE_OK)
 	  {
 	    setLastErrorMsg(server, &gff_pipe_err) ;
 	    result = ZMAP_SERVERRESPONSE_REQFAIL ;
@@ -958,14 +958,19 @@ static void addMapping(ZMapFeatureContext feature_context, ZMapGFFHeader header)
 static void setLastErrorMsg(PipeServer server, GError **gff_pipe_err_inout)
 {
   GError *gff_pipe_err ;
+  char *msg = "failed";
 
-  zMapAssert(server && gff_pipe_err_inout && *gff_pipe_err_inout) ;
+  zMapAssert(server && gff_pipe_err_inout);
 
   gff_pipe_err = *gff_pipe_err_inout ;
+  if(gff_pipe_err)
+    {
+      msg = gff_pipe_err->message;
+      g_error_free(gff_pipe_err) ;
+    }
+  setErrMsg(server, g_strdup_printf("%s %s", server->script_path, msg)) ;
 
-  setErrMsg(server, g_strdup_printf("%s %s", server->script_path, gff_pipe_err->message)) ;
 
-  g_error_free(gff_pipe_err) ;
 
   *gff_pipe_err_inout = NULL ;
 
diff --git a/src/zmapView/zmapView.c b/src/zmapView/zmapView.c
index 507d15d78..35accb874 100755
--- a/src/zmapView/zmapView.c
+++ b/src/zmapView/zmapView.c
@@ -29,7 +29,7 @@
  * HISTORY:
  * Last edited: Apr  7 15:59 2010 (edgrif)
  * Created: Thu May 13 15:28:26 2004 (edgrif)
- * CVS info:   $Id: zmapView.c,v 1.194 2010-04-19 11:00:39 mh17 Exp $
+ * CVS info:   $Id: zmapView.c,v 1.195 2010-04-22 14:31:53 mh17 Exp $
  *-------------------------------------------------------------------
  */
 
@@ -50,7 +50,6 @@
 
 #include <zmapView_P.h>
 
-
 typedef struct
 {
   /* Processing options. */
@@ -65,18 +64,18 @@ typedef struct
   char *database_title ;
   char *database_path ;
 
-
-
+  char *err_msg;        // from the server mainly
 
   GList *feature_sets ;
 
   GList *required_styles ;
   gboolean server_styles_have_mode ;
+  gboolean status;      // load sucessful?
 
-  GHashTable *featureset_2_stylelist ;			    /* Mapping of each feature_set to all
-							       the styles it requires. */
+  GHashTable *featureset_2_stylelist ;                    /* Mapping of each feature_set to all
+                                                 the styles it requires. */
 
-  GData *curr_styles ;					    /* Styles for this context. */
+  GData *curr_styles ;                              /* Styles for this context. */
   ZMapFeatureContext curr_context ;
 
   ZMapServerReqType display_after ;
@@ -437,8 +436,6 @@ gboolean zMapViewConnect(ZMapView zmap_view, char *config_str)
 
 	  free_this_list = settings_list ;
 
-//	  current_server = (ZMapConfigSource)settings_list->data ;
-
 
 
 	  /* Current error handling policy is to connect to servers that we can and
@@ -470,7 +467,6 @@ gboolean zMapViewConnect(ZMapView zmap_view, char *config_str)
 	      else if (!(current_server->featuresets))
 		{
 		  /* featuresets are absolutely required, go on to next stanza if there aren't
-
 		   * any. */
 		  zMapWarning("Server \"%s\": no featuresets specified in configuration file so cannot connect.",
 			      current_server->url) ;
@@ -487,7 +483,7 @@ gboolean zMapViewConnect(ZMapView zmap_view, char *config_str)
 
 	      else if (!checkSequenceToServerMatch(zmap_view->sequence_2_server, &tmp_seq))
 		{
-		  /* If certain sequences must only be fetched from certain servers zmap_viewthen make sure
+		  /* If certain sequences must only be fetched from certain servers then make sure
 		   * we only make those connections. */
 		  zMapLogMessage("server %s no sequence: ignored",current_server->url);
 		  continue ;
@@ -1340,7 +1336,7 @@ static GHashTable *zmapViewGetFeatureSourceHash(GList *sources)
  * retrieved the features are added via a gtk event. */
  /* mh17:
   * unlike zmapViewConnect() we request one feature set at a time from the relevant server
-  * we scan the config file and create a hash table linking feature set
+  * we scan the config file and create a hash table linking feature set to source
   */
 void zmapViewLoadFeatures(ZMapView view, ZMapFeatureBlock block_orig, GList *req_sources,
 			  int features_start, int features_end)
@@ -1905,10 +1901,11 @@ static void stopStateConnectionChecking(ZMapView zmap_view)
  *  */
 static gboolean checkStateConnections(ZMapView zmap_view)
 {
-  gboolean call_again = TRUE ;		/* Normally we want to called continuously. */
+  gboolean call_again = TRUE ;	      /* Normally we want to be called continuously. */
   gboolean state_change = TRUE ;          /* Has view state changed ?. */
-  gboolean reqs_finished = FALSE;
-  int has_step_list = 0;                 // any requests still active?
+  gboolean reqs_finished = FALSE;         // at least one thread just finished
+  int thread_status = 0;                  // current thread: -ve for fail 0 for pending  +ve for ok
+  int has_step_list = 0;                  // any requests still active?
 
   if (zmap_view->connection_list)
     {
@@ -1924,9 +1921,12 @@ static gboolean checkStateConnections(ZMapView zmap_view)
 	  void *data = NULL ;
 	  char *err_msg = NULL ;
 	  gboolean thread_has_died = FALSE ;
+        ConnectionData cd;
+        LoadFeaturesDataStruct lfd;
 
 	  view_con = list_item->data ;
 	  thread = view_con->thread ;
+        cd = (ConnectionData) view_con->request_data;
 
 	  /* NOTE HOW THE FACT THAT WE KNOW NOTHING ABOUT WHERE THIS DATA CAME FROM
 	   * MEANS THAT WE SHOULD BE PASSING A HEADER WITH THE DATA SO WE CAN SAY WHERE
@@ -1935,6 +1935,15 @@ static gboolean checkStateConnections(ZMapView zmap_view)
 
 	  data = NULL ;
 	  err_msg = NULL ;
+        thread_status = 0;
+
+        // need to copy this info in case of thread death which clears it up
+
+        if(cd)
+          {
+            lfd.feature_sets = cd->feature_sets;
+            lfd.xwid = zmap_view->xwid;
+          }
 
 	  if (!(zMapThreadGetReplyWithData(thread, &reply, &data, &err_msg)))
 	    {
@@ -2103,8 +2112,9 @@ static gboolean checkStateConnections(ZMapView zmap_view)
 
 	      if(view_con->step_list)
 		reqs_finished = TRUE;
+            thread_status = -1;
 
-	      destroyConnection(zmap_view,view_con) ;
+	      destroyConnection(zmap_view,view_con) ;  //NB frees up what cd points to  (view_com->request_data)
 
 	    }
 
@@ -2123,11 +2133,26 @@ static gboolean checkStateConnections(ZMapView zmap_view)
 		{
                   zmapViewStepListDestroy(view_con) ;
                   reqs_finished = TRUE;
-		  //printf("step list %s finished\n",view_con->url);
-		  //zMapLogWarning("step list %s finished\n",view_con->url);
+                  thread_status = 1;
+		      //printf("step list %s finished\n",view_con->url);
+		      //zMapLogWarning("step list %s finished\n",view_con->url);
 		}
 	    }
 
+        if(thread_status)     // tell otterlace
+          {
+            if(cd)      // ie was valid at the start of the loop
+            {
+              if(thread_status < 0 && !err_msg)
+                err_msg = "Failed";
+
+              lfd.status = thread_status > 0 ? TRUE : FALSE;
+              lfd.err_msg = err_msg;
+
+             (*(view_cbs_G->load_data))(zmap_view, zmap_view->app_data,&lfd);
+            }
+          }
+
 	  if (err_msg)
 	    g_free(err_msg) ;
 	}
@@ -2474,8 +2499,9 @@ static gboolean processDataRequests(ZMapViewConnection view_con, ZMapServerReqAn
 
 	break ;
       }
-    case ZMAP_SERVERREQ_GETSEQUENCE:
-      // never appears??
+//    case ZMAP_SERVERREQ_GETSEQUENCE:
+      // never appears?? - see commandCB() and processGetSeqRequests() in this file
+
     case ZMAP_SERVERREQ_TERMINATE:
       {
       break ;
@@ -2673,6 +2699,10 @@ static ZMapViewConnection createConnection(ZMapView zmap_view,
 
       connect_data->featureset_2_stylelist = zMap_g_hashlist_create() ;
 
+      // we need to save this to tell otterlace when we've finished
+      // it also gets given to threads: when can we free it?
+      connect_data->feature_sets = req_featuresets;
+
       view_con->request_data = connect_data ;
 
 
@@ -2960,6 +2990,8 @@ static gboolean justMergeContext(ZMapView view, ZMapFeatureContext *context_inou
 
   new_features = *context_inout ;
 
+//  printf("just Merge new = %s\n",zMapFeatureContextGetDNAStatus(new_features) ? "yes" : "non");
+
   zMapPrintTimer(NULL, "Merge Context starting...") ;
 
   if (view->revcomped_features)
@@ -2972,6 +3004,10 @@ static gboolean justMergeContext(ZMapView view, ZMapFeatureContext *context_inou
     }
 
   merge = zMapFeatureContextMerge(&(view->features), &new_features, &diff_context) ;
+
+//  printf("just Merge view = %s\n",zMapFeatureContextGetDNAStatus(view->features) ? "yes" : "non");
+//  printf("just Merge diff = %s\n",zMapFeatureContextGetDNAStatus(diff_context) ? "yes" : "non");
+
 #ifdef MH17_NEVER
       {
             GError *err = NULL;
diff --git a/src/zmapWindow/zmapWindowFeature.c b/src/zmapWindow/zmapWindowFeature.c
index 2abcd02e9..911822386 100755
--- a/src/zmapWindow/zmapWindowFeature.c
+++ b/src/zmapWindow/zmapWindowFeature.c
@@ -6,12 +6,12 @@
  * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
@@ -30,7 +30,7 @@
  * HISTORY:
  * Last edited: Apr 15 09:29 2010 (edgrif)
  * Created: Mon Jan  9 10:25:40 2006 (edgrif)
- * CVS info:   $Id: zmapWindowFeature.c,v 1.179 2010-04-19 14:29:06 edgrif Exp $
+ * CVS info:   $Id: zmapWindowFeature.c,v 1.180 2010-04-22 14:31:53 mh17 Exp $
  *-------------------------------------------------------------------
  */
 
@@ -85,7 +85,7 @@ typedef struct
 }PFetchDataStruct, *PFetchData;
 
 
-typedef struct 
+typedef struct
 {
   ZMapWindow window;
   FooCanvasGroup *column;
@@ -151,8 +151,8 @@ static void pfetchEntry(ZMapWindow window, char *sequence_name) ;
 static void handle_dialog_close(GtkWidget *dialog, gpointer user_data);
 
 
-static ZMapFeatureContextExecuteStatus oneBlockHasDNA(GQuark key, 
-                                                      gpointer data, 
+static ZMapFeatureContextExecuteStatus oneBlockHasDNA(GQuark key,
+                                                      gpointer data,
                                                       gpointer user_data,
                                                       char **error_out);
 
@@ -163,30 +163,30 @@ static gboolean factoryTopItemCreated(FooCanvasItem *top_item,
                                       ZMapFeatureSet set,
                                       ZMapFeature feature,
                                       gpointer handler_data);
-static gboolean factoryFeatureSizeReq(ZMapFeature feature, 
-                                      double *limits_array, 
-                                      double *points_array_inout, 
+static gboolean factoryFeatureSizeReq(ZMapFeature feature,
+                                      double *limits_array,
+                                      double *points_array_inout,
                                       gpointer handler_data);
 
 static gboolean sequenceSelectionCB(FooCanvasItem *item, int start, int end, gpointer user_data) ;
 
 
 /* NOTE that we make some assumptions in this code including:
- * 
+ *
  * - the caller has found the correct context, alignment, block and set
  *   to put the feature in. Probably we will have to write some helper
  *   helper functions to do this if they have not already been written.
  *   There will need to map stuff like  "block spec" -> ZMapFeatureBlock etc.
- * 
- * 
+ *
+ *
  *  */
 
-/* 
+/*
  * NOTE TO ROY: I've written the functions so that when you get the xml from James, you can
- * get the align/block/set information and then 
+ * get the align/block/set information and then
  * use the hash calls to get the foocanvasgroup that is the column you want to add/modify the feature
  * in. The you can just call these routines with the group and the feature.
- * 
+ *
  * This way if there are errors in the xml and you can't find the right align/block/set then
  * you can easily report back to lace what the error was....
  *  */
@@ -210,7 +210,7 @@ GData *zMapWindowFeatureAllStyles(ZMapWindow window)
 
 
 /* Add a new feature to the feature_set given by the set canvas item.
- * 
+ *
  * Returns the new canvas feature item or NULL if there is some problem, e.g. the feature already
  * exists in the feature_set.
  *  */
@@ -263,7 +263,7 @@ FooCanvasItem *zMapWindowFeatureSetAdd(ZMapWindow window,
 
   feature_block = zmapWindowContainerGetFeatureBlock(ZMAP_CONTAINER_GROUP( block_group ));
   zMapAssert(feature_block);
-  
+
   context = (ZMapFeatureContext)(zMapFeatureGetParentGroup((ZMapFeatureAny)feature_block, ZMAPFEATURE_STRUCT_CONTEXT));
   zMapAssert(context);
 
@@ -297,16 +297,16 @@ FooCanvasItem *zMapWindowFeatureSetAdd(ZMapWindow window,
 
       /* Create the columns */
       zmapWindowCreateSetColumns(window,
-                                 forward_features, 
+                                 forward_features,
                                  reverse_features,
-                                 feature_block, 
+                                 feature_block,
                                  feature_set,
 				 window->read_only_styles,
-                                 ZMAPFRAME_NONE, 
-                                 &new_forward_set, 
-                                 &new_reverse_set, 
+                                 ZMAPFRAME_NONE,
+                                 &new_forward_set,
+                                 &new_reverse_set,
 				 NULL);
-      
+
       zmapWindowColOrderColumns(window);
 
     }
@@ -319,12 +319,12 @@ FooCanvasItem *zMapWindowFeatureSetAdd(ZMapWindow window,
 
 /* THERE IS A PROBLEM HERE IN THAT WE REMOVE THE EXISTING FOOCANVAS ITEM FOR THE FEATURE
  * AND DRAW A NEW ONE, THIS WILL INVALIDATE ANY CODE THAT IS CACHING THE ITEM.
- * 
+ *
  * THE FIX IS FOR ALL OUR CODE TO USE THE HASH TO GET TO FEATURE ITEMS AND NOT CACHE THEM....*/
 
 /* Replace an existing feature in the feature context, this is the only way to modify
  * a feature currently.
- * 
+ *
  * Returns FALSE if the feature does not exist. */
 FooCanvasItem *zMapWindowFeatureReplace(ZMapWindow zmap_window,
 					FooCanvasItem *curr_feature_item,
@@ -363,7 +363,7 @@ FooCanvasItem *zMapWindowFeatureReplace(ZMapWindow zmap_window,
 
 
 /* Remove an existing feature from the displayed feature context.
- * 
+ *
  * Returns FALSE if the feature does not exist. */
 gboolean zMapWindowFeatureRemove(ZMapWindow zmap_window, FooCanvasItem *feature_item, gboolean destroy_feature)
 {
@@ -382,13 +382,13 @@ gboolean zMapWindowFeatureRemove(ZMapWindow zmap_window, FooCanvasItem *feature_
   /* Need to delete the feature from the feature set and from the hash and destroy the
    * canvas item....NOTE this is very order dependent. */
 
-  /* I'm still not sure this is all correct.  
-   * canvasItemDestroyCB has a FToIRemove! 
+  /* I'm still not sure this is all correct.
+   * canvasItemDestroyCB has a FToIRemove!
    */
 
   /* Firstly remove from the FToI hash... */
   if (zmapWindowFToIRemoveFeature(zmap_window->context_to_item,
-				  container_set->strand, 
+				  container_set->strand,
 				  container_set->frame, feature))
     {
       /* check the feature is in featureset. */
@@ -398,7 +398,7 @@ gboolean zMapWindowFeatureRemove(ZMapWindow zmap_window, FooCanvasItem *feature_
           /* remove the item from the focus items list. */
           zmapWindowFocusRemoveFocusItem(zmap_window->focus, feature_item);
 
-          if(zmapWindowMarkIsSet(zmap_window->mark) && 
+          if(zmapWindowMarkIsSet(zmap_window->mark) &&
              feature_item == zmapWindowMarkGetItem(zmap_window->mark) &&
              zmapWindowMarkGetWorldRange(zmap_window->mark, &x1, &y1, &x2, &y2))
             {
@@ -440,23 +440,23 @@ ZMapFrame zmapWindowFeatureFrame(ZMapFeature feature)
 }
 
 /* Encapulates the rules about which strand a feature will be drawn on.
- * 
+ *
  * For ZMap this amounts to:
  *                            strand specific     not strand specific
  *       features strand
- * 
+ *
  *       ZMAPSTRAND_NONE            +                     +
  *       ZMAPSTRAND_FORWARD         +                     +
  *       ZMAPSTRAND_REVERSE         -                     +
- * 
+ *
  * Some features (e.g. repeats) are derived from alignments that match to the
  * forward or reverse strand and hence the feature can be said to have strand
  * in the alignment sense but for the actual feature (the repeat) the strand
  * is irrelevant.
- * 
+ *
  * Points to a data problem really, if features are not strand specific then
  * their strand should be ZMAPSTRAND_NONE !
- * 
+ *
  *  */
 ZMapStrand zmapWindowFeatureStrand(ZMapWindow window, ZMapFeature feature)
 {
@@ -468,7 +468,7 @@ ZMapStrand zmapWindowFeatureStrand(ZMapWindow window, ZMapFeature feature)
   g_return_val_if_fail(style != NULL, strand);
 
   if ((!(zMapStyleIsStrandSpecific(style))) ||
-      ((feature->strand == ZMAPSTRAND_FORWARD) || 
+      ((feature->strand == ZMAPSTRAND_FORWARD) ||
        (feature->strand == ZMAPSTRAND_NONE)))
     strand = ZMAPSTRAND_FORWARD ;
   else
@@ -495,7 +495,7 @@ void zmapWindowFeatureFactoryInit(ZMapWindow window)
 
 
 /* Called to draw each individual feature. */
-FooCanvasItem *zmapWindowFeatureDraw(ZMapWindow      window, 
+FooCanvasItem *zmapWindowFeatureDraw(ZMapWindow      window,
 				     ZMapFeatureTypeStyle style,
 				     FooCanvasGroup *set_group,
 				     ZMapFeature     feature)
@@ -519,22 +519,22 @@ FooCanvasItem *zmapWindowFeatureDraw(ZMapWindow      window,
 
 
   /* These should be parameters, rather than continually fetch them, caller will almost certainly know these! */
-  set       = (ZMapFeatureSet)zMapFeatureGetParentGroup((ZMapFeatureAny)feature, 
+  set       = (ZMapFeatureSet)zMapFeatureGetParentGroup((ZMapFeatureAny)feature,
 							ZMAPFEATURE_STRUCT_FEATURESET) ;
-  block     = (ZMapFeatureBlock)zMapFeatureGetParentGroup((ZMapFeatureAny)set, 
+  block     = (ZMapFeatureBlock)zMapFeatureGetParentGroup((ZMapFeatureAny)set,
 							  ZMAPFEATURE_STRUCT_BLOCK) ;
-  alignment = (ZMapFeatureAlignment)zMapFeatureGetParentGroup((ZMapFeatureAny)block, 
+  alignment = (ZMapFeatureAlignment)zMapFeatureGetParentGroup((ZMapFeatureAny)block,
 							      ZMAPFEATURE_STRUCT_ALIGN) ;
-  context   = (ZMapFeatureContext)zMapFeatureGetParentGroup((ZMapFeatureAny)alignment, 
+  context   = (ZMapFeatureContext)zMapFeatureGetParentGroup((ZMapFeatureAny)alignment,
 							    ZMAPFEATURE_STRUCT_CONTEXT) ;
-  
+
   new_feature = zmapWindowFToIFactoryRunSingle(window->item_factory,
 					       NULL,
-                                               set_group, 
-                                               context, 
-                                               alignment, 
-                                               block, 
-                                               set, 
+                                               set_group,
+                                               context,
+                                               alignment,
+                                               block,
+                                               set,
                                                feature);
   return new_feature;
 }
@@ -626,12 +626,7 @@ gboolean zMapWindowGetDNAStatus(ZMapWindow window)
   if(window->feature_context &&
      zMapFindStyle(window->read_only_styles, zMapStyleCreateID(ZMAP_FIXED_STYLE_DNA_NAME)))
     {
-      zMapFeatureContextExecute((ZMapFeatureAny)(window->feature_context), 
-                                ZMAPFEATURE_STRUCT_BLOCK, 
-                                oneBlockHasDNA, 
-                                &dna);
-
-      drawable = dna.exists;
+      drawable = zMapFeatureContextGetDNAStatus(window->feature_context);
     }
 
   return drawable;
@@ -678,13 +673,13 @@ char *zmapWindowFeatureTranscriptFASTA(ZMapFeature feature, gboolean spliced, gb
 
 
   if((feature->type == ZMAPSTYLE_MODE_TRANSCRIPT)
-     && ((context = (ZMapFeatureContext)zMapFeatureGetParentGroup((ZMapFeatureAny)feature, 
+     && ((context = (ZMapFeatureContext)zMapFeatureGetParentGroup((ZMapFeatureAny)feature,
 								  ZMAPFEATURE_STRUCT_CONTEXT))))
     {
       ZMapPeptide peptide;
       char *dna, *seq_name = NULL, *gene_name = NULL;
       int pep_length, start_incr = 0;
-      
+
       seq_name  = (char *)g_quark_to_string(context->original_id);
       gene_name = (char *)g_quark_to_string(feature->original_id);
 
@@ -693,15 +688,15 @@ char *zmapWindowFeatureTranscriptFASTA(ZMapFeature feature, gboolean spliced, gb
 	  /* Adjust for when its known that the start exon is incomplete.... */
 	  if (feature->feature.transcript.flags.start_not_found)
 	    start_incr = feature->feature.transcript.start_phase - 1 ; /* Phase values are 1 <= phase <= 3 */
-      
+
 	  peptide = zMapPeptideCreate(seq_name, gene_name, (dna + start_incr), NULL, TRUE) ;
-      
+
 	  /* Note that we do not include the "Stop" in the peptide length, is this the norm ? */
 	  pep_length = zMapPeptideLength(peptide) ;
 	  if (zMapPeptideHasStopCodon(peptide))
 	    pep_length-- ;
-      
-	  peptide_fasta = zMapFASTAString(ZMAPFASTA_SEQTYPE_AA, 
+
+	  peptide_fasta = zMapFASTAString(ZMAPFASTA_SEQTYPE_AA,
 					  seq_name, "Protein",
 					  gene_name, pep_length,
 					  zMapPeptideSequence(peptide));
@@ -716,7 +711,7 @@ char *zmapWindowFeatureTranscriptFASTA(ZMapFeature feature, gboolean spliced, gb
 
 
 
-/* 
+/*
  *                       Internal functions.
  */
 
@@ -728,7 +723,7 @@ static gboolean canvasItemDestroyCB(FooCanvasItem *feature_item, gpointer data)
 
   /* Check to see if there is an entry in long items for this feature.... */
   zmapWindowLongItemRemove(window->long_items, feature_item) ;  /* Ignore boolean result. */
-  
+
   zmapWindowFocusRemoveFocusItem(window->focus, feature_item);
 
   return event_handled ;
@@ -737,8 +732,8 @@ static gboolean canvasItemDestroyCB(FooCanvasItem *feature_item, gpointer data)
 
 
 
-static void featureCopySelectedItem(ZMapFeature feature_in, 
-                                    ZMapFeature feature_out, 
+static void featureCopySelectedItem(ZMapFeature feature_in,
+                                    ZMapFeature feature_out,
                                     FooCanvasItem *selected)
 {
   ZMapFeatureSubPartSpan item_feature_data;
@@ -759,13 +754,13 @@ static void featureCopySelectedItem(ZMapFeature feature_in,
           /* copy the selected intron/exon */
           span.x1 = item_feature_data->start;
           span.x2 = item_feature_data->end;
-          if(item_feature_data->subpart == ZMAPFEATURE_SUBPART_EXON || 
+          if(item_feature_data->subpart == ZMAPFEATURE_SUBPART_EXON ||
              item_feature_data->subpart == ZMAPFEATURE_SUBPART_EXON_CDS)
             zMapFeatureAddTranscriptExonIntron(feature_out, &span, NULL);
           else
             zMapFeatureAddTranscriptExonIntron(feature_out, NULL, &span);
         }
-      else if (feature_out->type == ZMAPSTYLE_MODE_ALIGNMENT && 
+      else if (feature_out->type == ZMAPSTYLE_MODE_ALIGNMENT &&
 	       item_feature_data->subpart == ZMAPFEATURE_SUBPART_MATCH)
         {
           feature_out->feature.homol.align = NULL;
@@ -827,8 +822,8 @@ static gboolean canvasItemEventCB(FooCanvasItem *item, GdkEvent *event, gpointer
 	     * press generated by clicks but catch the button2 press (see below). */
 	    if (but_event->time - last_but_press > 250)
 	      {
-                GdkModifierType shift_mask = GDK_SHIFT_MASK, 
-                  control_mask             = GDK_CONTROL_MASK, 
+                GdkModifierType shift_mask = GDK_SHIFT_MASK,
+                  control_mask             = GDK_CONTROL_MASK,
                   shift_control_mask       = GDK_SHIFT_MASK | GDK_CONTROL_MASK,
                   unwanted_masks           = GDK_LOCK_MASK | GDK_MOD2_MASK | GDK_MOD3_MASK | GDK_MOD4_MASK | GDK_MOD5_MASK,
                   locks_mask;
@@ -939,7 +934,7 @@ static gboolean canvasItemEventCB(FooCanvasItem *item, GdkEvent *event, gpointer
 		    /* Pass information about the object clicked on back to the application. */
 		    zMapWindowUpdateInfoPanel(window, feature, sub_item, highlight_item, NULL,
 					      replace_highlight, highlight_same_names) ;
-		    
+
 		    if (but_event->button == 3)
 		      {
 			/* Pop up an item menu. */
@@ -1008,8 +1003,8 @@ void zmapMakeItemMenu(GdkEventButton *button_event, ZMapWindow window, FooCanvas
   zMapAssert(feature);
 
   column_group  = zmapWindowContainerCanvasItemGetContainer(item) ;
-    
-  style = zmapWindowContainerFeatureSetStyleFromID((ZMapWindowContainerFeatureSet)column_group, 
+
+  style = zmapWindowContainerFeatureSetStyleFromID((ZMapWindowContainerFeatureSet)column_group,
 						   feature->style_id);
 
 
@@ -1037,7 +1032,7 @@ void zmapMakeItemMenu(GdkEventButton *button_event, ZMapWindow window, FooCanvas
 
   if (feature->type == ZMAPSTYLE_MODE_TRANSCRIPT && feature->strand == ZMAPSTRAND_FORWARD)
     menu_sets = g_list_append(menu_sets, makeMenuShowTranslation(NULL, NULL, menu_data));
-    
+
   if (feature->url)
     menu_sets = g_list_append(menu_sets, makeMenuURL(NULL, NULL, menu_data)) ;
 
@@ -1125,7 +1120,7 @@ static void itemMenuCB(int menu_item_id, gpointer callback_data)
 	ZMapStrand set_strand ;
 	ZMapFrame set_frame ;
 	gboolean result ;
-	
+
 	result = zmapWindowItemGetStrandFrame(menu_data->item, &set_strand, &set_frame) ;
 	zMapAssert(result) ;
 
@@ -1137,9 +1132,9 @@ static void itemMenuCB(int menu_item_id, gpointer callback_data)
 						    zMapFeatureStrand2Str(set_strand),
 						    zMapFeatureFrame2Str(set_frame));
 
-	zmapWindowListWindow(menu_data->window, 
+	zmapWindowListWindow(menu_data->window,
 			     menu_data->item,
-			     (char *)g_quark_to_string(feature->parent->original_id), 
+			     (char *)g_quark_to_string(feature->parent->original_id),
 			     NULL, NULL,
 			     (ZMapWindowListSearchHashFunc)zmapWindowFToISetSearchPerform, search_data,
 			     (GDestroyNotify)zmapWindowFToISetSearchDestroy, zoom_to_item) ;
@@ -1158,9 +1153,9 @@ static void itemMenuCB(int menu_item_id, gpointer callback_data)
 	search_data = zmapWindowFToISetSearchCreate(zmapWindowFToIFindSameNameItems, feature,
 						    0, 0, 0, 0, zMapFeatureStrand2Str(set_strand),
 						    zMapFeatureFrame2Str(set_frame));
-	zmapWindowListWindow(menu_data->window, 
+	zmapWindowListWindow(menu_data->window,
 			     menu_data->item,
-			     (char *)g_quark_to_string(feature->parent->original_id), 
+			     (char *)g_quark_to_string(feature->parent->original_id),
 			     NULL, NULL,
 			     (ZMapWindowListSearchHashFunc)zmapWindowFToISetSearchPerform, search_data,
 			     (GDestroyNotify)zmapWindowFToISetSearchDestroy, zoom_to_item) ;
@@ -1177,7 +1172,7 @@ static void itemMenuCB(int menu_item_id, gpointer callback_data)
 
       break ;
     case ITEM_MENU_SEARCH:
-      zmapWindowCreateSearchWindow(menu_data->window, 
+      zmapWindowCreateSearchWindow(menu_data->window,
 				   NULL, NULL,
 				   menu_data->item) ;
 
@@ -1211,7 +1206,7 @@ static void itemMenuCB(int menu_item_id, gpointer callback_data)
       }
     case ITEM_MENU_SHOW_TRANSLATION:
       {
-	zmapWindowItemShowTranslation(menu_data->window, 
+	zmapWindowItemShowTranslation(menu_data->window,
 				      menu_data->item);
       }
       break;
@@ -1332,7 +1327,7 @@ static ZMapGUIMenuItem makeMenuURL(int *start_index_inout,
 
 
 #ifdef ED_G_NEVER_INCLUDE_THIS_CODE
-static void textSelectCB(int menu_item_id, gpointer callback_data) 
+static void textSelectCB(int menu_item_id, gpointer callback_data)
 {
 #ifdef RDS_BREAKING_STUFF
   ItemMenuCBData menu_data = (ItemMenuCBData)callback_data ;
@@ -1419,7 +1414,7 @@ static void pfetchEntry(ZMapWindow window, char *sequence_name)
   PFetchHandle    pfetch = NULL;
   PFetchUserPrefsStruct prefs = {NULL};
   gboolean  debug_pfetch = FALSE;
-  
+
   if((zmapWindowGetPFetchUserPrefs(&prefs)) &&
      (prefs.location   != NULL))
     {
@@ -1427,20 +1422,20 @@ static void pfetchEntry(ZMapWindow window, char *sequence_name)
 
       if(prefs.mode && strncmp(prefs.mode, "pipe", 4) == 0)
 	pfetch_type = PFETCH_TYPE_PIPE_HANDLE;
-	
+
       pfetch_data->pfetch = pfetch = PFetchHandleNew(pfetch_type);
-      
+
       if((pfetch_data->title = g_strdup_printf(PFETCH_TITLE_FORMAT, sequence_name)))
 	{
 	  pfetch_data->dialog = zMapGUIShowTextFull(pfetch_data->title, "pfetching...\n",
 						    FALSE, &(pfetch_data->text_buffer));
-	  
-	  pfetch_data->widget_destroy_handler_id = 
-	    g_signal_connect(G_OBJECT(pfetch_data->dialog), "destroy", 
-			     G_CALLBACK(handle_dialog_close), pfetch_data); 
+
+	  pfetch_data->widget_destroy_handler_id =
+	    g_signal_connect(G_OBJECT(pfetch_data->dialog), "destroy",
+			     G_CALLBACK(handle_dialog_close), pfetch_data);
 	}
 
-      PFetchHandleSettings(pfetch, 
+      PFetchHandleSettings(pfetch,
 			   "debug",       debug_pfetch,
 			   "full",        prefs.full_record,
 			   "pfetch",      prefs.location,
@@ -1448,20 +1443,20 @@ static void pfetchEntry(ZMapWindow window, char *sequence_name)
 			   NULL);
 
       if(PFETCH_IS_HTTP_HANDLE(pfetch))
-	PFetchHandleSettings(pfetch, 
+	PFetchHandleSettings(pfetch,
 			     "port",       prefs.port,
 			     "cookie-jar", prefs.cookie_jar,
 			     NULL);
-      
+
       g_free(prefs.location);
       g_free(prefs.cookie_jar);
-      
+
       g_signal_connect(G_OBJECT(pfetch), "reader", G_CALLBACK(pfetch_reader_func), pfetch_data);
 
       g_signal_connect(G_OBJECT(pfetch), "error",  G_CALLBACK(pfetch_reader_func), pfetch_data);
-      
+
       g_signal_connect(G_OBJECT(pfetch), "closed", G_CALLBACK(pfetch_closed_func), pfetch_data);
-      
+
       if(PFetchHandleFetch(pfetch, sequence_name) == PFETCH_STATUS_FAILED)
 	zMapWarning("Error fetching sequence '%s'", sequence_name);
     }
@@ -1490,9 +1485,9 @@ static void handle_dialog_close(GtkWidget *dialog, gpointer user_data)
 #ifdef ED_G_NEVER_INCLUDE_THIS_CODE
 /* We may wish to make this public some time but as the rest of the long item calls for features
  * are in this file then there is no need for it to be exposed.
- * 
+ *
  * Deals with removing all the items contained in a compound object from the longitem list.
- * 
+ *
  *  */
 static void removeFeatureLongItems(ZMapWindowLongItems long_items, FooCanvasItem *feature_item)
 {
@@ -1539,8 +1534,8 @@ static void removeLongItemCB(gpointer data, gpointer user_data)
 
 
 /* Function to check whether any of the blocks has dna */
-static ZMapFeatureContextExecuteStatus oneBlockHasDNA(GQuark key, 
-                                                      gpointer data, 
+static ZMapFeatureContextExecuteStatus oneBlockHasDNA(GQuark key,
+                                                      gpointer data,
                                                       gpointer user_data,
                                                       char **error_out)
 {
@@ -1549,7 +1544,7 @@ static ZMapFeatureContextExecuteStatus oneBlockHasDNA(GQuark key,
   ZMapFeatureStructType feature_type = ZMAPFEATURE_STRUCT_INVALID;
 
   BlockHasDNA dna = (BlockHasDNA)user_data;
-  
+
   feature_type = feature_any->struct_type;
 
   switch(feature_type)
@@ -1611,24 +1606,24 @@ static double getWidthFromScore(ZMapFeatureTypeStyle style, double score)
 
   if (score <= style->min_score)
     tmp = 0 ;
-  else if (score >= style->max_score) 
+  else if (score >= style->max_score)
     tmp = style->width ;
-  else 
+  else
     tmp = fac * (score - style->min_score) ;
 
   width = tmp ;
 
 #ifdef ED_G_NEVER_INCLUDE_THIS_CODE
-      if (seg->data.f <= bc->meth->minScore) 
+      if (seg->data.f <= bc->meth->minScore)
 	x = 0 ;
-      else if (seg->data.f >= bc->meth->maxScore) 
+      else if (seg->data.f >= bc->meth->maxScore)
 	x = bc->width ;
-      else 
+      else
 	x = fac * (seg->data.f - bc->meth->minScore) ;
 
       box = graphBoxStart() ;
 
-      if (x > origin + 0.5 || x < origin - 0.5) 
+      if (x > origin + 0.5 || x < origin - 0.5)
 	graphLine (bc->offset+origin, y, bc->offset+x, y) ;
       else if (x > origin)
 	graphLine (bc->offset+origin-0.5, y, bc->offset+x, y) ;
@@ -1696,7 +1691,7 @@ static void showSplices (FeatureMap look, SegType type, BoxCol *bc, float origin
   float fac;
 
   fac = bc->width / (bc->meth->maxScore - bc->meth->minScore);
-  
+
   for (i = 0 ; i < arrayMax(look->segs) ; ++i)
     { seg = arrp(look->segs, i, SEG) ;
       if (seg->x1 > look->max
@@ -1705,14 +1700,14 @@ static void showSplices (FeatureMap look, SegType type, BoxCol *bc, float origin
 	  || seg->type != type)
 	continue ;
       y = MAP2GRAPH(look->map, seg->x2) ;
-      if (seg->data.f <= bc->meth->minScore) 
+      if (seg->data.f <= bc->meth->minScore)
 	x = 0 ;
-      else if (seg->data.f >= bc->meth->maxScore) 
+      else if (seg->data.f >= bc->meth->maxScore)
 	x = bc->width ;
-      else 
+      else
 	x = fac * (seg->data.f - bc->meth->minScore) ;
       box = graphBoxStart() ;
-      if (x > origin + 0.5 || x < origin - 0.5) 
+      if (x > origin + 0.5 || x < origin - 0.5)
 	graphLine (bc->offset+origin, y, bc->offset+x, y) ;
       else if (x > origin)
 	graphLine (bc->offset+origin-0.5, y, bc->offset+x, y) ;
@@ -1783,21 +1778,21 @@ static gboolean sequenceSelectionCB(FooCanvasItem *item, int start, int end, gpo
     {
       ZMapFrame frame;
       int window_origin;
-      
+
       frame = zMapFeatureFrame(feature) ;
-      
+
       start = origin_index ;
       end = current_index ;
-      
+
       /* Do some monkeying to get the dna coords */
       origin_index-- ;
       origin_index *= 3 ;
       origin_index += frame ;
       current_index = origin_index + ((end - start + 1) * 3) - 1;
-      
+
       dna_start = origin_index ;
       dna_end = current_index ;
-      
+
       /* zmapWindowCoordToDisplay() doesn't work for protein coord space,
        * whether this is useful though.... */
       if (window->origin == window->min_coord)
@@ -1810,32 +1805,32 @@ static gboolean sequenceSelectionCB(FooCanvasItem *item, int start, int end, gpo
 	  /* CHECK THIS OUT! TEST THE + 4 is required */
 	  window_origin = (window->origin + 4 ) / 3;
 	}
-      
+
       start = start - (window_origin - 1);
       end   = end   - (window_origin - 1);
-      
+
       coords_text = "Protein Coords: ";
-      
+
       select.feature_desc.sub_feature_start  = g_strdup_printf("%s%d", coords_text, start);
       select.feature_desc.sub_feature_end    = g_strdup_printf("%d", end);
       select.feature_desc.sub_feature_length = g_strdup_printf("%d", end - start + 1);
-      
+
       coords_text = "DNA Coords: ";			    /* reset */
     }
 
- 
+
   display_start = zmapWindowCoordToDisplay(window, origin_index);
   display_end   = zmapWindowCoordToDisplay(window, current_index);
-  
+
   select.feature_desc.feature_start  = g_strdup_printf("%s%d", coords_text, display_start);
   select.feature_desc.feature_end    = g_strdup_printf("%d", display_end);
   select.feature_desc.feature_length = g_strdup_printf("%d", current_index - origin_index + 1);
   select.feature_desc.feature_name   = (char *)g_quark_to_string(feature->original_id);
-  
-  
+
+
   /* update the info panel */
   (*(window->caller_cbs->select))(window, window->app_data, (void *)&select) ;
-  
+
 
   /* Update the highlighting, note that for peptides we highlight the
    * corresponding dna sequence as well as the peptide. */
@@ -1844,32 +1839,32 @@ static gboolean sequenceSelectionCB(FooCanvasItem *item, int start, int end, gpo
       g_free(select.feature_desc.sub_feature_start);
       g_free(select.feature_desc.sub_feature_end);
       g_free(select.feature_desc.sub_feature_length);
-      
+
       zmapWindowItemHighlightDNARegion(window, item, origin_index, current_index);
     }
   else
     {
       zmapWindowItemHighlightRegionTranslations(window, item, origin_index, current_index);
     }
-  
+
   g_free(select.feature_desc.feature_start);
   g_free(select.feature_desc.feature_end);
   g_free(select.feature_desc.feature_length);
-  
-  
+
+
   /* We wait until here to do this so we are only setting the
    * clipboard text once. i.e. for this window. And so that we have
    * updated the focus object correctly. */
   if (feature->type == ZMAPSTYLE_MODE_RAW_SEQUENCE)
     {
       char *dna_string, *seq_name;
-      
+
       dna_string = zMapFeatureGetDNA((ZMapFeatureAny)feature, start, end, FALSE);
-      
+
       seq_name = g_strdup_printf("%d-%d", display_start, display_end);
-      
-      select.secondary_text = zMapFASTAString(ZMAPFASTA_SEQTYPE_DNA, 
-					      seq_name, "DNA", NULL, 
+
+      select.secondary_text = zMapFASTAString(ZMAPFASTA_SEQTYPE_DNA,
+					      seq_name, "DNA", NULL,
 					      end - start + 1,
 					      dna_string);
       g_free(seq_name);
@@ -1886,8 +1881,8 @@ static gboolean sequenceSelectionCB(FooCanvasItem *item, int start, int end, gpo
       dna_string  = zMapFeatureGetDNA((ZMapFeatureAny)feature, dna_start, dna_end, FALSE) ;
       seq_name    = g_strdup_printf("%d-%d (%d-%d)", start, end, dna_start, dna_end) ;
       translation = zMapPeptideCreate(seq_name, NULL, dna_string, NULL, TRUE) ;
-      select.secondary_text = zMapFASTAString(ZMAPFASTA_SEQTYPE_AA, 
-					      seq_name, "Protein", NULL, 
+      select.secondary_text = zMapFASTAString(ZMAPFASTA_SEQTYPE_AA,
+					      seq_name, "Protein", NULL,
 					      zMapPeptideLength(translation),
 					      zMapPeptideSequence(translation)) ;
       g_free(seq_name);
@@ -1927,18 +1922,18 @@ static gboolean factoryTopItemCreated(FooCanvasItem *top_item,
       break;
     }
 
-  /* ummmmm....I don't like this....suggests that all is not fully implemented in the new 
+  /* ummmmm....I don't like this....suggests that all is not fully implemented in the new
    * feature item stuff..... */
   if (ZMAP_IS_WINDOW_SEQUENCE_FEATURE(top_item))
-    g_signal_connect(G_OBJECT(top_item), "sequence-selected", 
+    g_signal_connect(G_OBJECT(top_item), "sequence-selected",
 		     G_CALLBACK(sequenceSelectionCB), handler_data) ;
 
   return TRUE ;
 }
 
-static gboolean factoryFeatureSizeReq(ZMapFeature feature, 
-                                      double *limits_array, 
-                                      double *points_array_inout, 
+static gboolean factoryFeatureSizeReq(ZMapFeature feature,
+                                      double *limits_array,
+                                      double *points_array_inout,
                                       gpointer handler_data)
 {
   gboolean outside = FALSE;
@@ -1959,11 +1954,11 @@ static gboolean factoryFeatureSizeReq(ZMapFeature feature,
     {
       ZMapWindow window = (ZMapWindow)handler_data;
       double x1, x2;
-      
+
       points_array_inout[1] = points_array_inout[3] = x1 = x2 = 0.0;
       /* Get scrolled region (clamped to sequence coords)  */
       zmapWindowGetScrollRegion(window,
-                                 &x1, &(points_array_inout[1]), 
+                                 &x1, &(points_array_inout[1]),
                                  &x2, &(points_array_inout[3]));
     }
   else
@@ -1978,12 +1973,12 @@ static gboolean factoryFeatureSizeReq(ZMapFeature feature,
       start_end_crossing |= ((x2_in > block_end)   << 2);
       start_end_crossing |= ((x1_in > block_end)   << 3);
       start_end_crossing |= ((x2_in < block_start) << 4);
-      
+
       /* Now check whether we cross! */
-      if(start_end_crossing & 8 || 
+      if(start_end_crossing & 8 ||
          start_end_crossing & 16) /* everything is out of range don't display! */
-        outside = TRUE;        
-      
+        outside = TRUE;
+
       if(start_end_crossing & 2)
         points_array_inout[1] = block_start;
       if(start_end_crossing & 4)
@@ -2011,7 +2006,7 @@ FooCanvasItem *addNewCanvasItem(ZMapWindow window, FooCanvasGroup *feature_group
 
   container_features = FOO_CANVAS_GROUP(zmapWindowContainerGetFeatures((ZMapWindowContainerGroup)feature_group));
   column_is_empty = !(container_features->item_list);
-            
+
   /* This function will add the new feature to the hash. */
   new_feature = zmapWindowFeatureDraw(window, style, FOO_CANVAS_GROUP(feature_group), feature) ;
 
-- 
GitLab