diff --git a/src/belvuApp/belvu.cpp b/src/belvuApp/belvu.cpp index 7b23a1ae6f55e77eef29cac42deb106aedc9de09..bd5f4f5581b05a0896eb4ef4828499d306f802c1 100644 --- a/src/belvuApp/belvu.cpp +++ b/src/belvuApp/belvu.cpp @@ -2501,8 +2501,8 @@ BelvuContext* createBelvuContext() bc->fileName = NULL; bc->dirName = NULL; bc->organismLabel[0] = 'O'; - bc->organismLabel[0] = 'S'; - bc->organismLabel[0] = '\0'; + bc->organismLabel[1] = 'S'; + bc->organismLabel[2] = '\0'; bc->conservCount = NULL; bc->colorMap = NULL; @@ -4244,9 +4244,21 @@ static void parseMulAnnotationLine(BelvuContext *bc, const char *seqLine) ALN *aln = createEmptyAln(); aln->organism = valuep; /* Find organism string in permanent stack */ - g_array_append_val(bc->organismArr, aln); - g_array_sort(bc->organismArr, organism_order); + + /* Add to organisms array, if not already there */ + int org_idx = 0 ; + if (!alnArrayFind(bc->organismArr, aln, &org_idx, organism_order)) + { + g_array_append_val(bc->organismArr, aln); + g_array_sort(bc->organismArr, organism_order); + /* Set the max organism name length */ + int organismLen = strlen(aln->organism); + + if (organismLen > bc->maxOrganismLen) + bc->maxOrganismLen = organismLen ; + } + if (strchr(cp, '/') && strchr(cp, '-')) { str2aln(bc, namep, aln); @@ -4416,7 +4428,6 @@ static void readMul(BelvuContext *bc, FILE *pipe) /* Store all annotation lines in a list. Prepend the items because that * is more efficient, and then reverse the list at the end */ bc->annotationList = g_slist_prepend(bc->annotationList, g_strdup(line)); - parseMulAnnotationLine(bc, line); } else if (!strncmp(line, "#=GC ", 5) || !strncmp(line, "#=GR ", 5) || @@ -4451,6 +4462,14 @@ static void readMul(BelvuContext *bc, FILE *pipe) g_slist_free(alnList); alnList = NULL; + + /* Loop through all the annotation lines and parse them (must be done after adding alignment + * lines) */ + for (GSList *annItem = bc->annotationList; annItem; annItem = annItem->next) + { + char *line = (char*)(annItem->data) ; + parseMulAnnotationLine(bc, line); + } /* For debugging * / for (i = 0; i < nseq; i++) { diff --git a/src/belvuApp/belvuMain.cpp b/src/belvuApp/belvuMain.cpp index ab695a74ec9d3784c2f32fef4dcb45e9fe0993e7..e09d0931fbaf37f05ad1879d336bfb8027c09b81 100644 --- a/src/belvuApp/belvuMain.cpp +++ b/src/belvuApp/belvuMain.cpp @@ -355,7 +355,7 @@ static void showCompiledInfo() /* Convert swissprot name suffixes to organisms */ -static void suffix2organism(GArray *alignArr, GArray *organismArr) +static void suffix2organism(BelvuContext *bc, GArray *alignArr, GArray *organismArr) { int i = 0; char *cp = NULL; @@ -384,6 +384,12 @@ static void suffix2organism(GArray *alignArr, GArray *organismArr) g_array_append_val(organismArr, organism); g_array_sort(organismArr, organism_order); + + // Calculate the max organism name len + const int organismLen = strlen(alnp->organism) ; + + if (organismLen > bc->maxOrganismLen) + bc->maxOrganismLen = organismLen ; } else { @@ -550,6 +556,8 @@ int main(int argc, char **argv) * There are two handlers: the default one for all non-critical messages, which will just log * output to the console, and one for critical messages and errors, which will display a * pop-up message (the idea being that we don't bother the user unless it's something serious). + * Note that the latter needs to display a gtk dialog so can't be set up until after gtk_init + * has been called. * * All errors and warnings will be sent to stderr, as will info messages (g_message_info). * Program output destined for stdout should use g_message. @@ -570,8 +578,6 @@ int main(int argc, char **argv) msgData.statusBar = NULL; g_log_set_default_handler(defaultMessageHandler, &msgData); - g_log_set_handler(NULL, (GLogLevelFlags)(G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION), - popupMessageHandler, &msgData); /* Initialise up the context with default values */ @@ -585,8 +591,6 @@ int main(int argc, char **argv) setTreeScaleCorr(bc, bc->treeMethod); - char *OrganismLabel = g_strdup("OS"); - gboolean verbose = FALSE; gboolean init_rmPartial = FALSE; @@ -635,7 +639,7 @@ int main(int argc, char **argv) case 'L': markupColorCodesFile = g_strdup(optarg); break; case 'm': readMatchFile = g_strdup(optarg); break; case 'n': makeNRinit = atof(optarg); break; - case 'O': strncpy(OrganismLabel, optarg, 2); break; + case 'O': strncpy(bc->organismLabel, optarg, 2); break; case 'o': output_format = g_strdup(optarg); break; case 'P': init_rmPartial = TRUE; break; case 'Q': init_rmGappyColumns = atof(optarg); break; @@ -782,7 +786,7 @@ int main(int argc, char **argv) } if (bc->organismArr->len == 0) - suffix2organism(bc->alignArr, bc->organismArr); + suffix2organism(bc, bc->alignArr, bc->organismArr); setOrganismColors(bc->organismArr); @@ -965,6 +969,10 @@ int main(int argc, char **argv) /* We've finished all of the command-line-only options so now initialise the GTK GUI */ gtk_init(&argc, &argv); + /* After gtk_init is called, we can start using the popup message handler */ + g_log_set_handler(NULL, (GLogLevelFlags)(G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION), + popupMessageHandler, &msgData); + /* Update bits of the context that require the display to be initialised */ bc->removeSeqsCursor = gdk_cursor_new(GDK_PIRATE); bc->busyCursor = gdk_cursor_new(GDK_WATCH); @@ -1011,7 +1019,5 @@ int main(int argc, char **argv) gtk_main(); } - g_free(OrganismLabel) ; - return(EXIT_SUCCESS) ; } diff --git a/src/belvuApp/belvuWindow.cpp b/src/belvuApp/belvuWindow.cpp index 6c3b8985b58a2a97185678c0e2f3413907c01e71..d7c8017bc1f07cd03c06f0a188f00efa7371bbba 100644 --- a/src/belvuApp/belvuWindow.cpp +++ b/src/belvuApp/belvuWindow.cpp @@ -3463,8 +3463,9 @@ static void drawOrganisms(GtkWidget *widget, GdkDrawable *drawable, BelvuContext convertColorNumToGdkColor(alnp->color, FALSE, &color); gdk_gc_set_foreground(gc, &color); - drawText(widget, drawable, gc, x, y, alnp->organism, NULL, NULL); - + int text_width = 0; + drawText(widget, drawable, gc, x, y, alnp->organism, &text_width, NULL); + y += charHeight; } @@ -3543,9 +3544,17 @@ static void createOrganismWindow(BelvuContext *bc) /* Set layout size big enough to fit all organisms */ gdouble width = 0, height = 0; getFontCharSize(drawing, drawing->style->font_desc, &width, &height); - width *= (bc->maxNameLen + 1); + width *= (bc->maxOrganismLen + 1); height *= (bc->organismArr->len + 1); - gtk_layout_set_size(GTK_LAYOUT(drawing), width, height); + + /* The size is only approximate (especially the width), so add a sizeable buffer (e.g. double + * it). It's important the layout is not too small but doesn't matter if it's too big (because + * it will be in a scrollwin) */ + gtk_layout_set_size(GTK_LAYOUT(drawing), width * 2, height + 10); + + /* Add some padding in the main window for space around the layout etc. It doesn't matter too + * much if this is too small because the window is resizable */ + gtk_window_set_default_size(GTK_WINDOW(bc->orgsWindow), width * 2 + 20, height + 20) ; /* Set default background color */ GdkColor *bgColor = getGdkColor(BELCOLOR_BACKGROUND, bc->defaultColors, FALSE, FALSE); diff --git a/src/belvuApp/belvu_.hpp b/src/belvuApp/belvu_.hpp index 2e9b2b3e481c547882bf96c49328fc4ff74ad253..93e6bd4cfa67374d8b27de1651ff3f162a151135 100644 --- a/src/belvuApp/belvu_.hpp +++ b/src/belvuApp/belvu_.hpp @@ -351,6 +351,7 @@ typedef struct BelvuContextStruct int maxLen; /* number of columns in alignment */ int maxTreeWidth; int maxNameLen; /* Max string length of any sequence name */ + int maxOrganismLen; /* Max string length of any organism name */ int maxStartLen; /* Max string length of any sequence start */ int maxEndLen; /* Max string length of any sequence end */ int maxScoreen; /* Max string length of any sequence score */