diff --git a/bigpicture.c b/bigpicture.c index a14b5e11fcf7afd81be26ee5c966896354f8285b..fe6b997a127d7c95418afb58a41e4a4f0d6ff4c3 100644 --- a/bigpicture.c +++ b/bigpicture.c @@ -994,8 +994,9 @@ gdouble bigPictureGetIdPerCell(GtkWidget *bigPicture) return properties->idPerCell; } -void bigPictureSetIdPerCell(GtkWidget *bigPicture, const gdouble idPerCell) +gboolean bigPictureSetIdPerCell(GtkWidget *bigPicture, const gdouble idPerCell) { + gboolean result = FALSE; BigPictureProperties *properties = bigPictureGetProperties(bigPicture); if (idPerCell < GRID_SCALE_MIN_ID_PER_CELL) @@ -1006,7 +1007,10 @@ void bigPictureSetIdPerCell(GtkWidget *bigPicture, const gdouble idPerCell) { properties->idPerCell = idPerCell; updateOnPercentIdChanged(bigPicture); + result = TRUE; } + + return result; } int bigPictureGetNumVCells(GtkWidget *bigPicture) @@ -1021,8 +1025,9 @@ DoubleRange* bigPictureGetPercentIdRange(GtkWidget *bigPicture) return &properties->percentIdRange; } -void bigPictureSetMaxPercentId(GtkWidget *bigPicture, const gdouble newValue) +gboolean bigPictureSetMaxPercentId(GtkWidget *bigPicture, const gdouble newValue) { + gboolean result = FALSE; BigPictureProperties *properties = bigPictureGetProperties(bigPicture); if (newValue < GRID_SCALE_MIN) @@ -1041,11 +1046,15 @@ void bigPictureSetMaxPercentId(GtkWidget *bigPicture, const gdouble newValue) { properties->percentIdRange.max = newValue; updateOnPercentIdChanged(bigPicture); + result = TRUE; } + + return result; } -void bigPictureSetMinPercentId(GtkWidget *bigPicture, const gdouble newValue) +gboolean bigPictureSetMinPercentId(GtkWidget *bigPicture, const gdouble newValue) { + gboolean result = FALSE; BigPictureProperties *properties = bigPictureGetProperties(bigPicture); if (newValue < GRID_SCALE_MIN) @@ -1064,7 +1073,10 @@ void bigPictureSetMinPercentId(GtkWidget *bigPicture, const gdouble newValue) { properties->percentIdRange.min = newValue; updateOnPercentIdChanged(bigPicture); + result = TRUE; } + + return result; } /*********************************************************** diff --git a/bigpicture.h b/bigpicture.h index d3a1ed24a1e625dc918b0cc9c087bd7c32513183..f3ffea1b7dfe8a68279c198a0688264b0b210477 100644 --- a/bigpicture.h +++ b/bigpicture.h @@ -87,9 +87,9 @@ DoubleRange* bigPictureGetPercentIdRange(GtkWidget *bigPicture); int bigPictureGetNumVCells(GtkWidget *bigPicture); BlxViewContext* bigPictureGetContext(GtkWidget *bigPicture); -void bigPictureSetIdPerCell(GtkWidget *bigPicture, const gdouble idPerCell); -void bigPictureSetMaxPercentId(GtkWidget *bigPicture, const gdouble newValue); -void bigPictureSetMinPercentId(GtkWidget *bigPicture, const gdouble newValue); +gboolean bigPictureSetIdPerCell(GtkWidget *bigPicture, const gdouble idPerCell); +gboolean bigPictureSetMaxPercentId(GtkWidget *bigPicture, const gdouble newValue); +gboolean bigPictureSetMinPercentId(GtkWidget *bigPicture, const gdouble newValue); void bigPictureSetPreviewBoxCentre(GtkWidget *bigPicture, int previewBoxCentre); void calculateGridHeaderBorders(GtkWidget *header); diff --git a/blxFetch.c b/blxFetch.c index be266e9cc748d9bb7bcdf9fbdafa0eeb6c280924..3c158b3c885dc8638f1f9b0e19f1665428ae2131 100644 --- a/blxFetch.c +++ b/blxFetch.c @@ -38,7 +38,7 @@ * HISTORY: * Last edited: Aug 21 17:34 2009 (edgrif) * Created: Tue Jun 17 16:20:26 2008 (edgrif) - * CVS info: $Id: blxFetch.c,v 1.36 2010-08-26 11:11:20 gb10 Exp $ + * CVS info: $Id: blxFetch.c,v 1.37 2010-09-03 11:15:38 gb10 Exp $ *------------------------------------------------------------------- */ @@ -1867,7 +1867,7 @@ void setupFetchMode(PfetchParams *pfetch, char **fetchMode, const char **net_id, /* Callback called when the sort order has been changed in the drop-down box */ -static void onFetchModeChanged(GtkWidget *widget, const gint responseId, gpointer data) +static gboolean onFetchModeChanged(GtkWidget *widget, const gint responseId, gpointer data) { BlxViewContext *bc = (BlxViewContext*)data; GtkComboBox *combo = GTK_COMBO_BOX(widget); @@ -1899,6 +1899,8 @@ static void onFetchModeChanged(GtkWidget *widget, const gint responseId, gpointe } } } + + return TRUE; } diff --git a/blxdotter.c b/blxdotter.c index 1da2249afd43fbc037f297b7dfaa5cc5287dc75e..41e36664b7fa2ea9c73cac3172fbece9b2590ef3 100644 --- a/blxdotter.c +++ b/blxdotter.c @@ -49,7 +49,7 @@ typedef enum { /* Local function declarations */ -static gboolean getDotterRange(GtkWidget *blxWindow, const char *dotterSSeq, const gboolean callOnSelf, int *dotterStart, int *dotterEnd, int *dotterZoom, GError **error); +static gboolean getDotterRange(GtkWidget *blxWindow, const char *dotterSSeq, const gboolean callOnSelf, const gboolean autoDotter, int *dotterStart, int *dotterEnd, int *dotterZoom, GError **error); static gboolean smartDotterRange(GtkWidget *blxWindow, const char *dotterSSeq, int *dotter_start_out, int *dotter_end_out, GError **error); static gboolean smartDotterRangeSelf(GtkWidget *blxWindow, int *dotter_start_out, int *dotter_end_out, GError **error); static char* fetchSeqRaw(const char *seqname, const char *fetchMode); @@ -65,42 +65,71 @@ static gboolean callDotterSelf(GtkWidget *blxWindow, GError **error); /* Callback to be called when the user clicks OK or Apply on the dotter * dialog. It sets the dotter mode according to the toggle state of the * "auto" button. */ -static void onSaveDotterMode(GtkWidget *button, const gint responseId, gpointer data) +static gboolean onSaveDotterMode(GtkWidget *button, const gint responseId, gpointer data) { GtkWidget *blxWindow = GTK_WIDGET(data); BlxViewContext *blxContext = blxWindowGetContext(blxWindow); blxContext->autoDotter = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)); + return TRUE; } /* Callback to be called when the user clicks OK or Apply on the dotter * dialog. It saves the start parameter that was entered (if manual dotter * params are being used). */ -static void onSaveDotterStart(GtkWidget *entry, const gint responseId, gpointer data) +static gboolean onSaveDotterStart(GtkWidget *entry, const gint responseId, gpointer data) { + gboolean result = TRUE; + GtkWidget *blxWindow = GTK_WIDGET(data); - BlxViewContext *blxContext = blxWindowGetContext(blxWindow); + BlxViewContext *bc = blxWindowGetContext(blxWindow); /* Only save the parameter if we are using manual parameters */ - if (!blxContext->autoDotter) + if (!bc->autoDotter) { - blxContext->dotterStart = atoi(gtk_entry_get_text(GTK_ENTRY(entry))); + const int newVal = atoi(gtk_entry_get_text(GTK_ENTRY(entry))); + + if (valueWithinRange(newVal, &bc->refSeqRange)) + { + bc->dotterStart = newVal; + } + else + { + result = FALSE; + g_critical("Start value %d is outside reference sequence range %d -> %d. Value not saved.\n", newVal, bc->refSeqRange.min, bc->refSeqRange.max); + } } + + return result; } -static void onSaveDotterEnd(GtkWidget *entry, const gint responseId, gpointer data) +static gboolean onSaveDotterEnd(GtkWidget *entry, const gint responseId, gpointer data) { + gboolean result = TRUE; + GtkWidget *blxWindow = GTK_WIDGET(data); - BlxViewContext *blxContext = blxWindowGetContext(blxWindow); + BlxViewContext *bc = blxWindowGetContext(blxWindow); /* Only save the parameter if we are using manual parameters */ - if (!blxContext->autoDotter) + if (!bc->autoDotter) { - blxContext->dotterEnd = atoi(gtk_entry_get_text(GTK_ENTRY(entry))); + const int newVal = atoi(gtk_entry_get_text(GTK_ENTRY(entry))); + + if (valueWithinRange(newVal, &bc->refSeqRange)) + { + bc->dotterEnd = newVal; + } + else + { + result = FALSE; + g_critical("End value %d is outside reference sequence range %d -> %d. Value not saved.\n", newVal, bc->refSeqRange.min, bc->refSeqRange.max); + } } + + return result; } -static void onSaveDotterZoom(GtkWidget *entry, const gint responseId, gpointer data) +static gboolean onSaveDotterZoom(GtkWidget *entry, const gint responseId, gpointer data) { GtkWidget *blxWindow = GTK_WIDGET(data); BlxViewContext *blxContext = blxWindowGetContext(blxWindow); @@ -110,6 +139,8 @@ static void onSaveDotterZoom(GtkWidget *entry, const gint responseId, gpointer d { blxContext->dotterZoom = atoi(gtk_entry_get_text(GTK_ENTRY(entry))); } + + return TRUE; } @@ -187,7 +218,9 @@ static void onSelfButtonToggled(GtkWidget *button, gpointer data) /* Recalculate auto start/end */ int autoStart = UNSET_INT, autoEnd = UNSET_INT; - getDotterRange(dialogData->blxWindow, getDotterSSeq(dialogData->blxWindow, NULL), dialogData->callOnSelf, &autoStart, &autoEnd, NULL, NULL); + const gboolean autoDotter = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialogData->autoButton)); + + getDotterRange(dialogData->blxWindow, getDotterSSeq(dialogData->blxWindow, NULL), dialogData->callOnSelf, autoDotter, &autoStart, &autoEnd, NULL, NULL); if (autoStart == UNSET_INT) autoStart = bc->displayRev ? bc->refSeqRange.max : bc->refSeqRange.min; @@ -229,8 +262,23 @@ static void onResponseDotterDialog(GtkDialog *dialog, gint responseId, gpointer switch (responseId) { case GTK_RESPONSE_ACCEPT: - widgetCallAllCallbacks(GTK_WIDGET(dialog), GINT_TO_POINTER(responseId)); - destroy = dialogData->callOnSelf ? callDotterSelf(dialogData->blxWindow, &error) : callDotter(dialogData->blxWindow, dialogData->hspsOnly, &error); + /* Only continue to call dotter if saving the values is successful */ + if (widgetCallAllCallbacks(GTK_WIDGET(dialog), GINT_TO_POINTER(responseId))) + { + if (dialogData->callOnSelf) + { + destroy = callDotterSelf(dialogData->blxWindow, &error); + } + else + { + destroy = callDotter(dialogData->blxWindow, dialogData->hspsOnly, &error); + } + } + else + { + destroy = FALSE; /* there was an error, so leave the dialog open */ + } + break; case GTK_RESPONSE_APPLY: @@ -274,7 +322,7 @@ static void onRadioButtonToggled(GtkWidget *button, gpointer data) { /* Recalculate auto start/end in case user has selected a different sequence */ int autoStart = UNSET_INT, autoEnd = UNSET_INT; - getDotterRange(dialogData->blxWindow, getDotterSSeq(dialogData->blxWindow, NULL), dialogData->callOnSelf, &autoStart, &autoEnd, NULL, NULL); + getDotterRange(dialogData->blxWindow, getDotterSSeq(dialogData->blxWindow, NULL), dialogData->callOnSelf, TRUE, &autoStart, &autoEnd, NULL, NULL); if (autoStart == UNSET_INT) autoStart = bc->displayRev ? bc->refSeqRange.max : bc->refSeqRange.min; @@ -484,8 +532,8 @@ void showDotterDialog(GtkWidget *blxWindow, const gboolean bringToFront) * is still open: the auto range does not update automatically for the new sequence. To * mitigate this, connect the 'clicked' signal as well as the toggle signal, so that they can * click on the 'auto' toggle button and have it refresh, even if that button is already selected.*/ - g_signal_connect(G_OBJECT(autoButton), "toggled", G_CALLBACK(onRadioButtonToggled), dialogData); - g_signal_connect(G_OBJECT(manualButton), "toggled", G_CALLBACK(onRadioButtonToggled), dialogData); +// g_signal_connect(G_OBJECT(autoButton), "toggled", G_CALLBACK(onRadioButtonToggled), dialogData); +// g_signal_connect(G_OBJECT(manualButton), "toggled", G_CALLBACK(onRadioButtonToggled), dialogData); g_signal_connect(G_OBJECT(autoButton), "clicked", G_CALLBACK(onRadioButtonToggled), dialogData); g_signal_connect(G_OBJECT(manualButton), "clicked", G_CALLBACK(onRadioButtonToggled), dialogData); @@ -543,11 +591,12 @@ char getDotterMode(const BlxBlastMode blastMode) } -/* Get the start/end coords. If the autoDotter flag is set, calculate coords +/* Get the start/end coords. If the passed autoDotter flag is true, calculate coords * automatically - otherwise use the stored manual coords */ static gboolean getDotterRange(GtkWidget *blxWindow, const char *dotterSSeq, const gboolean callOnSelf, + const gboolean autoDotter, int *dotterStart, int *dotterEnd, int *dotterZoom, @@ -558,7 +607,7 @@ static gboolean getDotterRange(GtkWidget *blxWindow, gboolean success = TRUE; BlxViewContext *bc = blxWindowGetContext(blxWindow); - if (!bc->autoDotter) + if (!autoDotter) { /* Use manual coords */ if (dotterStart) *dotterStart = bc->dotterStart; @@ -1016,7 +1065,7 @@ gboolean callDotter(GtkWidget *blxWindow, const gboolean hspsOnly, GError **erro /* Get the coords */ int dotterStart = UNSET_INT, dotterEnd = UNSET_INT, dotterZoom = 0; - if (!getDotterRange(blxWindow, dotterSSeq, FALSE, &dotterStart, &dotterEnd, &dotterZoom, &tmpError)) + if (!getDotterRange(blxWindow, dotterSSeq, FALSE, bc->autoDotter, &dotterStart, &dotterEnd, &dotterZoom, &tmpError)) { g_propagate_error(error, tmpError); return FALSE; @@ -1103,7 +1152,7 @@ static gboolean callDotterSelf(GtkWidget *blxWindow, GError **error) int dotterZoom = 0; GError *tmpError = NULL; - if (!getDotterRange(blxWindow, NULL, TRUE, &dotterStart, &dotterEnd, &dotterZoom, &tmpError)) + if (!getDotterRange(blxWindow, NULL, TRUE, bc->autoDotter, &dotterStart, &dotterEnd, &dotterZoom, &tmpError)) { g_propagate_error(error, tmpError); return FALSE; diff --git a/blxview.c b/blxview.c index c8e3c35f8de64511a4c7b91560bcaf473ae98306..5b49c09c09bda854afa141c1ba03ef4af262a87e 100644 --- a/blxview.c +++ b/blxview.c @@ -88,7 +88,7 @@ 01-10-05 Added getsseqsPfetch to fetch all missing sseqs in one go via socket connection to pfetch [RD] * Created: Thu Feb 20 10:27:39 1993 (esr) - * CVS info: $Id: blxview.c,v 1.64 2010-08-31 11:42:05 gb10 Exp $ + * CVS info: $Id: blxview.c,v 1.65 2010-09-03 11:15:38 gb10 Exp $ *------------------------------------------------------------------- */ @@ -167,8 +167,8 @@ static char* blxMessageGetDisplayText(const BlxMessage *msg, const gbo static void addMessagesToBuffer(GSList *messageList, GtkTextBuffer *textBuffer, GtkTextTag *normalTag, GtkTextTag *highlightTag); static gboolean getUseScrolledMessages(); static void setUseScrolledMessages(const gboolean newValue); -static void onSetUseScrolledMessages(GtkWidget *button, const gint responseId, gpointer data); -static void onSetUsePopupMessages(GtkWidget *button, const gint responseId, gpointer data); +static gboolean onSetUseScrolledMessages(GtkWidget *button, const gint responseId, gpointer data); +static gboolean onSetUsePopupMessages(GtkWidget *button, const gint responseId, gpointer data); static char* getDialogIcon(GLogLevelFlags log_level); static void printMessageToStatusbar(const gchar *message, gpointer data); @@ -2140,18 +2140,20 @@ static void setUseScrolledMessages(const gboolean newValue) /* Called when user requests to view messages as a list */ -static void onSetUseScrolledMessages(GtkWidget *button, const gint responseId, gpointer data) +static gboolean onSetUseScrolledMessages(GtkWidget *button, const gint responseId, gpointer data) { const gboolean useScrolledMessages = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)); setUseScrolledMessages(useScrolledMessages); + return TRUE; } /* Called when user requests to view messages as popups */ -static void onSetUsePopupMessages(GtkWidget *button, const gint responseId, gpointer data) +static gboolean onSetUsePopupMessages(GtkWidget *button, const gint responseId, gpointer data) { const gboolean usePopupMessages = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)); setUseScrolledMessages(!usePopupMessages); + return TRUE; } diff --git a/blxwindow.c b/blxwindow.c index dcaa02f17791b6513c1967530d7d5f3342a6c148..c47f15536fcaab7e26e80e0926b7d5cf15b24ee0 100755 --- a/blxwindow.c +++ b/blxwindow.c @@ -1294,8 +1294,10 @@ static GList* findSeqsFromList(GtkWidget *blxWindow, const char *inputText, cons /* Callback called when requested to find sequences from a sequence name. Selects * the sequences and scrolls to the start of the first match in the selection */ -static void onFindSeqsFromName(GtkWidget *button, const gint responseId, gpointer data) +static gboolean onFindSeqsFromName(GtkWidget *button, const gint responseId, gpointer data) { + gboolean result = TRUE; + const char *inputText = NULL; if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) @@ -1309,7 +1311,11 @@ static void onFindSeqsFromName(GtkWidget *button, const gint responseId, gpointe GError *error = NULL; GList *seqList = findSeqsFromName(blxWindow, inputText, FALSE, &error); - reportAndClearIfError(&error, G_LOG_LEVEL_CRITICAL); + if (error) + { + reportAndClearIfError(&error, G_LOG_LEVEL_CRITICAL); + result = FALSE; + } if (seqList) { @@ -1331,13 +1337,17 @@ static void onFindSeqsFromName(GtkWidget *button, const gint responseId, gpointe firstMatch(blxWindowGetDetailView(blxWindow), seqList); } } + + return result; } /* Callback called when requested to find sequences from a given list. Selects * the sequences ands scrolls to the start of the first match in the selection. */ -static void onFindSeqsFromList(GtkWidget *button, const gint responseId, gpointer data) +static gboolean onFindSeqsFromList(GtkWidget *button, const gint responseId, gpointer data) { + gboolean result = TRUE; + const char *inputText = NULL; if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) @@ -1351,7 +1361,11 @@ static void onFindSeqsFromList(GtkWidget *button, const gint responseId, gpointe GError *error = NULL; GList *seqList = findSeqsFromList(blxWindow, inputText, FALSE, &error); - reportAndClearIfError(&error, G_LOG_LEVEL_CRITICAL); + if (error) + { + reportAndClearIfError(&error, G_LOG_LEVEL_CRITICAL); + result = FALSE; + } if (seqList) { @@ -1370,6 +1384,8 @@ static void onFindSeqsFromList(GtkWidget *button, const gint responseId, gpointe firstMatch(blxWindowGetDetailView(blxWindow), seqList); } } + + return result; } @@ -1526,8 +1542,10 @@ static int getSearchStartCoord(GtkWidget *blxWindow, const gboolean startBeginni /* Callback called when requested to search for a DNA string. If found, sets the currently- * selected base index to the coord where the matching string starts. The text entry for the * search string is passed as the callback data. */ -static void onFindDnaString(GtkWidget *button, const gint responseId, gpointer data) +static gboolean onFindDnaString(GtkWidget *button, const gint responseId, gpointer data) { + gboolean result = TRUE; + /* Get the search string from the text entry. If the toggle button is not active, call * blxWindowFindDnaString with a NULL search string to "cancel" any previous searches * so that "findAgain" will not attempt to perform a DNA search). */ @@ -1540,6 +1558,7 @@ static void onFindDnaString(GtkWidget *button, const gint responseId, gpointer d if (!searchStr || strlen(searchStr) < 1) { g_critical("DNA search failed. The search string was empty.\n"); + result = FALSE; } } @@ -1570,9 +1589,12 @@ static void onFindDnaString(GtkWidget *button, const gint responseId, gpointer d if (error) { + result = FALSE; prefixError(error, "DNA search failed. "); reportAndClearIfError(&error, G_LOG_LEVEL_CRITICAL); } + + return result; } @@ -1852,8 +1874,10 @@ static SequenceGroup* createSequenceGroup(GtkWidget *blxWindow, GList *seqList, /* This function sets the sequence-group-name text based on the given text entry widget */ -static void onGroupNameChanged(GtkWidget *widget, const gint responseId, gpointer data) +static gboolean onGroupNameChanged(GtkWidget *widget, const gint responseId, gpointer data) { + gboolean result = TRUE; + GtkEntry *entry = GTK_ENTRY(widget); SequenceGroup *group = (SequenceGroup*)data; @@ -1863,6 +1887,7 @@ static void onGroupNameChanged(GtkWidget *widget, const gint responseId, gpointe { g_critical("Invalid group name '%s' entered; reverting to previous group name '%s'.", newName, group->groupName); gtk_entry_set_text(entry, group->groupName); + result = FALSE; } else { @@ -1871,13 +1896,17 @@ static void onGroupNameChanged(GtkWidget *widget, const gint responseId, gpointe group->groupName = g_strdup(newName); } + + return result; } /* This function is called when the sequence-group-order text entry widget's * value has changed. It sets the new order number in the group. */ -static void onGroupOrderChanged(GtkWidget *widget, const gint responseId, gpointer data) +static gboolean onGroupOrderChanged(GtkWidget *widget, const gint responseId, gpointer data) { + gboolean result = TRUE; + GtkEntry *entry = GTK_ENTRY(widget); SequenceGroup *group = (SequenceGroup*)data; @@ -1889,6 +1918,7 @@ static void onGroupOrderChanged(GtkWidget *widget, const gint responseId, gpoint char *orderStr = convertIntToString(group->order); gtk_entry_set_text(entry, orderStr); g_free(orderStr); + result = FALSE; } else { @@ -1899,13 +1929,17 @@ static void onGroupOrderChanged(GtkWidget *widget, const gint responseId, gpoint blxWindowGroupsChanged(blxWindow); } + + return result; } /* This callback is called when the dialog settings are applied. It sets the hidden * status of the passed groupo based on the toggle button's state */ -static void onGroupHiddenToggled(GtkWidget *button, const gint responseId, gpointer data) +static gboolean onGroupHiddenToggled(GtkWidget *button, const gint responseId, gpointer data) { + gboolean result = TRUE; + SequenceGroup *group = (SequenceGroup*)data; group->hidden = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)); @@ -1914,13 +1948,17 @@ static void onGroupHiddenToggled(GtkWidget *button, const gint responseId, gpoin GtkWidget *blxWindow = GTK_WIDGET(gtk_window_get_transient_for(GTK_WINDOW(dialog))); blxWindowGroupsChanged(blxWindow); + + return result; } /* This callback is called when the toggle button for a group's "highlighted" flag is toggled. * It updates the group's highlighted flag according to the button's new status. */ -static void onGroupHighlightedToggled(GtkWidget *button, const gint responseId, gpointer data) +static gboolean onGroupHighlightedToggled(GtkWidget *button, const gint responseId, gpointer data) { + gboolean result = TRUE; + SequenceGroup *group = (SequenceGroup*)data; group->highlighted = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)); @@ -1931,12 +1969,16 @@ static void onGroupHighlightedToggled(GtkWidget *button, const gint responseId, GtkWidget *blxWindow = GTK_WIDGET(gtk_window_get_transient_for(GTK_WINDOW(dialog))); blxWindowRedrawAll(blxWindow); + + return result; } /* Called when the user has changed the color of a group in the 'edit groups' dialog */ -static void onGroupColorChanged(GtkWidget *button, const gint responseId, gpointer data) -{ +static gboolean onGroupColorChanged(GtkWidget *button, const gint responseId, gpointer data) +{ + gboolean result = TRUE; + SequenceGroup *group = (SequenceGroup*)data; gtk_color_button_get_color(GTK_COLOR_BUTTON(button), &group->highlightColor); gdk_colormap_alloc_color(gdk_colormap_get_system(), &group->highlightColor, TRUE, TRUE); @@ -1945,6 +1987,8 @@ static void onGroupColorChanged(GtkWidget *button, const gint responseId, gpoint GtkWindow *dialogWindow = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(button))); GtkWidget *blxWindow = GTK_WIDGET(gtk_window_get_transient_for(dialogWindow)); blxWindowRedrawAll(blxWindow); + + return result; } @@ -2072,8 +2116,10 @@ static void getSequencesThatMatch(gpointer listDataItem, gpointer data) /* If the given radio button is enabled, add a group based on the curently- * selected sequences. */ -static void addGroupFromSelection(GtkWidget *button, const gint responseId, gpointer data) +static gboolean addGroupFromSelection(GtkWidget *button, const gint responseId, gpointer data) { + gboolean result = TRUE; + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) { GtkWindow *dialogWindow = GTK_WINDOW(gtk_widget_get_toplevel(button)); @@ -2088,19 +2134,24 @@ static void addGroupFromSelection(GtkWidget *button, const gint responseId, gpoi } else { + result = FALSE; g_critical("Warning: cannot create group; no sequences are currently selected"); } } + + return result; } /* If the given radio button is enabled, add a group based on the search text * in the given text entry. */ -static void addGroupFromName(GtkWidget *button, const gint responseId, gpointer data) +static gboolean addGroupFromName(GtkWidget *button, const gint responseId, gpointer data) { + gboolean result = TRUE; + if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) { - return; + return result; } GtkWindow *dialogWindow = GTK_WINDOW(gtk_widget_get_toplevel(button)); @@ -2111,7 +2162,11 @@ static void addGroupFromName(GtkWidget *button, const gint responseId, gpointer GError *error = NULL; GList *seqList = findSeqsFromName(blxWindow, inputText, FALSE, &error); - reportAndClearIfError(&error, G_LOG_LEVEL_CRITICAL); + if (error) + { + reportAndClearIfError(&error, G_LOG_LEVEL_CRITICAL); + result = FALSE; + } if (seqList) { @@ -2120,6 +2175,8 @@ static void addGroupFromName(GtkWidget *button, const gint responseId, gpointer createSequenceGroup(blxWindow, seqList, FALSE, NULL); } + + return result; } @@ -2160,7 +2217,6 @@ static GList* getSeqStructsFromText(GtkWidget *blxWindow, const char *inputText) { g_list_free(seqList); seqList = NULL; - g_critical("No valid sequence names in buffer '%s'\n", inputText); } return seqList; @@ -2250,11 +2306,13 @@ static void toggleMatchSet(GtkWidget *blxWindow) /* If the given radio button is enabled, add a group based on the list of sequences * in the given text entry. */ -static void addGroupFromList(GtkWidget *button, const gint responseId, gpointer data) +static gboolean addGroupFromList(GtkWidget *button, const gint responseId, gpointer data) { + gboolean result = TRUE; + if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) { - return; + return result; } GtkWindow *dialogWindow = GTK_WINDOW(gtk_widget_get_toplevel(button)); @@ -2266,7 +2324,11 @@ static void addGroupFromList(GtkWidget *button, const gint responseId, gpointer GError *error = NULL; GList *seqList = findSeqsFromList(blxWindow, inputText, FALSE, &error); - reportAndClearIfError(&error, G_LOG_LEVEL_CRITICAL); + if (error) + { + reportAndClearIfError(&error, G_LOG_LEVEL_CRITICAL); + result = FALSE; + } if (seqList) { @@ -2275,6 +2337,8 @@ static void addGroupFromList(GtkWidget *button, const gint responseId, gpointer createSequenceGroup(blxWindow, seqList, FALSE, NULL); } + + return result; } @@ -2491,8 +2555,7 @@ void onResponseGroupsDialog(GtkDialog *dialog, gint responseId, gpointer data) switch (responseId) { case GTK_RESPONSE_ACCEPT: - widgetCallAllCallbacks(page, GINT_TO_POINTER(responseId)); - destroy = TRUE; + destroy = widgetCallAllCallbacks(page, GINT_TO_POINTER(responseId)); refresh = FALSE; break; @@ -2767,8 +2830,10 @@ static void createCheckButton(GtkBox *box, /* Callback to be called when the user has entered a new column size */ -static void onColumnSizeChanged(GtkWidget *widget, const gint responseId, gpointer data) +static gboolean onColumnSizeChanged(GtkWidget *widget, const gint responseId, gpointer data) { + gboolean result = TRUE; + GtkEntry *entry = GTK_ENTRY(widget); DetailViewColumnInfo *columnInfo = (DetailViewColumnInfo*)data; @@ -2785,6 +2850,8 @@ static void onColumnSizeChanged(GtkWidget *widget, const gint responseId, gpoint callFuncOnAllDetailViewTrees(detailView, resizeTreeColumns, NULL); resizeDetailViewHeaders(detailView); } + + return result; } @@ -2937,31 +3004,31 @@ static void createColumnSizeButtons(GtkWidget *parent, GtkWidget *detailView) /* Callback to be called when the user has entered a new percent-ID per cell */ -static void onIdPerCellChanged(GtkWidget *widget, const gint responseId, gpointer data) +static gboolean onIdPerCellChanged(GtkWidget *widget, const gint responseId, gpointer data) { GtkWidget *bigPicture = GTK_WIDGET(data); const char *text = gtk_entry_get_text(GTK_ENTRY(widget)); const gdouble newValue = g_strtod(text, NULL); - bigPictureSetIdPerCell(bigPicture, newValue); + return bigPictureSetIdPerCell(bigPicture, newValue); } /* Callback to be called when the user has entered a new maximum percent-ID to display */ -static void onMaxPercentIdChanged(GtkWidget *widget, const gint responseId, gpointer data) +static gboolean onMaxPercentIdChanged(GtkWidget *widget, const gint responseId, gpointer data) { GtkWidget *bigPicture = GTK_WIDGET(data); const char *text = gtk_entry_get_text(GTK_ENTRY(widget)); const gdouble newValue = g_strtod(text, NULL); - bigPictureSetMaxPercentId(bigPicture, newValue); + return bigPictureSetMaxPercentId(bigPicture, newValue); } /* Callback to be called when the user has entered a new minimum percent-ID to display */ -static void onMinPercentIdChanged(GtkWidget *widget, const gint responseId, gpointer data) +static gboolean onMinPercentIdChanged(GtkWidget *widget, const gint responseId, gpointer data) { GtkWidget *bigPicture = GTK_WIDGET(data); const char *text = gtk_entry_get_text(GTK_ENTRY(widget)); const gdouble newValue = g_strtod(text, NULL); - bigPictureSetMinPercentId(bigPicture, newValue); + return bigPictureSetMinPercentId(bigPicture, newValue); } @@ -3043,7 +3110,7 @@ static void createGridSettingsButtons(GtkWidget *parent, GtkWidget *bigPicture) /* Callback called when user has changed a blixem color */ -static void onChangeBlxColor(GtkWidget *button, const gint responseId, gpointer data) +static gboolean onChangeBlxColor(GtkWidget *button, const gint responseId, gpointer data) { GdkColor *color = (GdkColor*)data; @@ -3055,11 +3122,13 @@ static void onChangeBlxColor(GtkWidget *button, const gint responseId, gpointer GtkWindow *dialogWindow = GTK_WINDOW(gtk_widget_get_toplevel(button)); GtkWidget *blxWindow = GTK_WIDGET(gtk_window_get_transient_for(dialogWindow)); blxWindowRedrawAll(blxWindow); + + return TRUE; } /* Callback called when user has changed the blixem background color */ -static void onChangeBackgroundColor(GtkWidget *button, const gint responseId, gpointer data) +static gboolean onChangeBackgroundColor(GtkWidget *button, const gint responseId, gpointer data) { GdkColor *color = (GdkColor*)data; @@ -3071,6 +3140,8 @@ static void onChangeBackgroundColor(GtkWidget *button, const gint responseId, gp GtkWindow *dialogWindow = GTK_WINDOW(gtk_widget_get_toplevel(button)); GtkWidget *blxWindow = GTK_WIDGET(gtk_window_get_transient_for(dialogWindow)); onUpdateBackgroundColor(blxWindow); + + return TRUE; } @@ -3182,13 +3253,15 @@ static void onLimitUnalignedBasesToggled(GtkWidget *button, gpointer data) /* Callback called when the user has changed the number of additional bases to show when the * 'show unaligned bases' option is enabled. */ -static void onSetNumUnalignedBases(GtkWidget *entry, const gint responseId, gpointer data) +static gboolean onSetNumUnalignedBases(GtkWidget *entry, const gint responseId, gpointer data) { const char *numStr = gtk_entry_get_text(GTK_ENTRY(entry)); int numBases = convertStringToInt(numStr); GtkWidget *detailView = GTK_WIDGET(data); detailViewSetNumUnalignedBases(detailView, numBases); + + return TRUE; } diff --git a/utilities.c b/utilities.c index 806ffa72753bc5f4737c8c91ac57292ca7149878..8f0dbd4a18b5b9edaf69e21b247c7eeb0bdeca0f 100644 --- a/utilities.c +++ b/utilities.c @@ -1811,32 +1811,54 @@ void widgetSetCallbackData(GtkWidget *widget, BlxResponseCallback func, gpointer } } -/* Get the CallbackData struct for this widget, if it has one, and call it. */ -static void widgetCallCallback(GtkWidget *widget, const gint responseId) +/* Get the CallbackData struct for this widget, if it has one, and call it. Returns false if + * there was an error */ +static gboolean widgetCallCallback(GtkWidget *widget, const gint responseId) { + gboolean result = TRUE; CallbackData *callbackData = widgetGetCallbackData(widget); if (callbackData && callbackData->func) { - callbackData->func(widget, responseId, callbackData->data); + result = callbackData->func(widget, responseId, callbackData->data); } + + return result; } /* Call the stored CallbackData callbacks (if any exist) for this widget and - * all of its children. The response ID is passed as the user data */ -void widgetCallAllCallbacks(GtkWidget *widget, gpointer data) + * all of its children. The response ID is passed as the user data. Returns false if + * any callback returns an error. */ +gboolean widgetCallAllCallbacks(GtkWidget *widget, gpointer data) { + gboolean result = TRUE; + if (widget && GTK_IS_WIDGET(widget)) { gint responseId = GPOINTER_TO_INT(data); - widgetCallCallback(widget, responseId); + if (!widgetCallCallback(widget, responseId)) + { + result = FALSE; + } if (GTK_IS_CONTAINER(widget)) { - gtk_container_foreach(GTK_CONTAINER(widget), widgetCallAllCallbacks, data); + GList *childItem = gtk_container_get_children(GTK_CONTAINER(widget)); + + for ( ; childItem; childItem = childItem->next) + { + GtkWidget *child = GTK_WIDGET(childItem->data); + + if (!widgetCallAllCallbacks(child, data)) + { + result = FALSE; + } + } } } + + return result; } @@ -1850,8 +1872,8 @@ void onResponseDialog(GtkDialog *dialog, gint responseId, gpointer data) switch (responseId) { case GTK_RESPONSE_ACCEPT: - widgetCallAllCallbacks(GTK_WIDGET(dialog), GINT_TO_POINTER(responseId)); - destroy = TRUE; + /* Destroy if successful */ + destroy = widgetCallAllCallbacks(GTK_WIDGET(dialog), GINT_TO_POINTER(responseId)); break; case GTK_RESPONSE_APPLY: diff --git a/utilities.h b/utilities.h index 02471c055fcb33a87828c00d2bcf55237a2f8c05..5dd044b95452bca1f7eebb10e357d956734b22af 100644 --- a/utilities.h +++ b/utilities.h @@ -87,8 +87,8 @@ #define BLX_BURLYWOOD "#deb887" #define BLX_TAN "#d2b48c" -/* Function pointer for callback functions used by widgets on dialog boxes */ -typedef void (*BlxResponseCallback)(GtkWidget *widget, const gint responseId, gpointer data); +/* Function pointer for callback functions used by widgets on dialog boxes. */ +typedef gboolean (*BlxResponseCallback)(GtkWidget *widget, const gint responseId, gpointer data); /* This struct holds generic callback information. It can be stored as a widget * property and called on the widget on request (e.g. by a dialog when it applies changes). */ @@ -263,7 +263,7 @@ GtkWidget* createScrollableTextView(const char *messageText, GtkTextView **textViewOut); void widgetSetCallbackData(GtkWidget *widget, BlxResponseCallback callbackFunc, gpointer callbackData); -void widgetCallAllCallbacks(GtkWidget *widget, gpointer data); +gboolean widgetCallAllCallbacks(GtkWidget *widget, gpointer data); void onResponseDialog(GtkDialog *dialog, gint responseId, gpointer data); void onCloseDialog(GtkDialog *dialog, gpointer data); void dialogClearContentArea(GtkDialog *dialog);