/***************************************************************************** # Copyright (C) 1994-2008 by David Gordon. # All rights reserved. # # This software is part of a beta-test version of the Consed/Autofinish # package. It should not be redistributed or # used for any commercial purpose, including commercially funded # sequencing, without written permission from the author and the # University of Washington. # # This software is provided ``AS IS'' and any express or implied # warranties, including, but not limited to, the implied warranties of # merchantability and fitness for a particular purpose, are disclaimed. # In no event shall the authors or the University of Washington be # liable for any direct, indirect, incidental, special, exemplary, or # consequential damages (including, but not limited to, procurement of # substitute goods or services; loss of use, data, or profits; or # business interruption) however caused and on any theory of liability, # whether in contract, strict liability, or tort (including negligence # or otherwise) arising in any way out of the use of this software, even # if advised of the possibility of such damage. # # Building Consed from source is error prone and not simple which is # why I provide executables. Due to time limitations I cannot # provide any assistance in building Consed. Even if you do not # modify the source, you may introduce errors due to using a # different version of the compiler, a different version of motif, # different versions of other libraries than I used, etc. For this # reason, if you discover Consed bugs, I can only offer help with # those bugs if you first reproduce those bugs with an executable # provided by me--not an executable you have built. # # Modifying Consed is also difficult. Although Consed is modular, # some modules are used by many other modules. Thus making a change # in one place can have unforeseen effects on many other features. # It may takes months for you to notice these other side-effects # which may not seen connected at all. It is not feasable for me to # provide help with modifying Consed sources because of the # potentially huge amount of time involved. # #*****************************************************************************/ #include #include #include using namespace std; #include #include #include #include #include "assert.h" #include "contigwin.h" #include "consed.h" #include "guicontigwin.h" #include "guiMultiContigNavigator.h" #include "handleWindowManagerDelete.h" #include "consedParameters.h" #include "hp_exception_kludge.h" #include "assemblyView.h" guiMultiContigNavigator :: guiMultiContigNavigator( const RWCString& soWindowTitle, const RWCString& soTextForFirstLine, const RWCString& soTextForSecondLine, const int nWidthInChars, const RWCString& soTitleOfSpecialPurposeButton, cbSpecialPurposeButton cbS, void* pClientDataForCbSpecialPurposeButton, Widget widTopLevelShellToBeConnectedTo, gotoList* pGotoList, ContigWin* pContigWin, const RWCString& soTextForThirdLine ) : pcbSpecialPurposeButton_( cbS ), pClientDataForSpecialPurposeButton_( pClientDataForCbSpecialPurposeButton ), pContigWin_( pContigWin ), pAssemblyView_( NULL ) { // activating prev/next buttons on all traces window if ( pContigWin_ ) pContigWin_->pGuiMultiContigNav_ = this; if ( ! pGotoList ) pGotoList_ = new gotoList( ); else pGotoList_ = pGotoList; int nArgs; Arg aArg[500]; // set private member indicating current selection // to be const value for no selection nCurrentSelection_ = navigatorNoSelection; // how many GotoItems in the list? int nNumGotoItems = pGotoList_->nGetNumGotoItems(); // allocate space for the array of XmStrings XmString* paXms; // pointer to array if (nNumGotoItems > 0 ) paXms = new XmString[nNumGotoItems]; else { paXms = NULL; } // populate the array of XmStrings for the listbox resource int n; for( n = 0; n < nNumGotoItems; n++) { paXms[n] = // get char* from GotoItem* from GotoList* XmStringCreateSimple((char*)(*pGotoList_)[n]->soGetFullDesc().data()); } // the list box title is from the GotoList's description XmString xmsListLabel = XmStringCreateSimple( (char*) soWindowTitle.data() ); XmString xmsSelectionLabel = XmStringCreateSimple("Go to"); bool bParentIsTopLevelWindow = false; if (widTopLevelShellToBeConnectedTo == NULL ) { bParentIsTopLevelWindow = true; widTopLevelShellToBeConnectedTo = GuiApp::pGetGuiApp()->widGetTopLevel(); } // figure out where to place the box on the screen // Place it right below the window that is calling this one. Dimension nHeight; Dimension nWidth; Position nY; Position nX; XtVaGetValues( widTopLevelShellToBeConnectedTo, XmNheight, &nHeight, XmNwidth, &nWidth, XmNy, &nY, XmNx, &nX, NULL ); if ( bParentIsTopLevelWindow ) { widPopupShell_ = XtVaCreatePopupShell( "consed", topLevelShellWidgetClass, widTopLevelShellToBeConnectedTo, XmNtitle, (char*) soWindowTitle.data(), XmNnoResize, False, XmNautoUnmanage, False, XmNtransient, False, XmNdeleteResponse, XmDO_NOTHING, NULL ); } else { widPopupShell_ = XtVaCreatePopupShell( "consed", topLevelShellWidgetClass, widTopLevelShellToBeConnectedTo, XmNtitle, (char*) soWindowTitle.data(), XmNnoResize, False, XmNautoUnmanage, False, XmNtransient, False, XmNdeleteResponse, XmDO_NOTHING, XmNy, nY + nHeight, XmNx, nX, NULL ); } handleWindowManagerDelete( widPopupShell_ ); // the immediate child of the application shell is a // main window Widget widMainWin = XtVaCreateManagedWidget("mainwin", xmMainWindowWidgetClass, widPopupShell_, XmNancestorSensitive, True, NULL ); // // create the form widget // nArgs = 0; XtSetArg(aArg[nArgs],XmNshadowThickness,0); nArgs++; XtSetArg(aArg[nArgs],XmNborderWidth,0); nArgs++; Widget widForm = XmCreateForm(widMainWin, "form", aArg, nArgs); XtManageChild(widForm); RWCString soTextToDisplay; short shRows; if ( soTextForThirdLine.bIsNull() ) { soTextToDisplay = soTextForFirstLine + "\n" + soTextForSecondLine; shRows = 2; } else { soTextToDisplay = soTextForFirstLine + "\n" + soTextForSecondLine + "\n" + soTextForThirdLine; shRows = 3; } nArgs = 0; XtSetArg(aArg[nArgs], XmNeditable, false); nArgs++; XtSetArg(aArg[nArgs], XmNcursorPositionVisible, false); nArgs++; XtSetArg(aArg[nArgs], XmNrows, shRows ); nArgs++; XtSetArg(aArg[nArgs], XmNtraversalOn, False); nArgs++; XtSetArg(aArg[nArgs], XmNvalue, (char*) soTextToDisplay.data()); nArgs++; XtSetArg(aArg[nArgs], XmNtopAttachment, XmATTACH_FORM); nArgs++; XtSetArg(aArg[nArgs], XmNtopOffset, 0); nArgs++; XtSetArg(aArg[nArgs], XmNleftAttachment, XmATTACH_FORM); nArgs++; XtSetArg(aArg[nArgs], XmNrightAttachment, XmATTACH_FORM); nArgs++; XtSetArg( aArg[nArgs], XmNeditMode, XmMULTI_LINE_EDIT ); ++nArgs; XtSetArg( aArg[nArgs], XmNcolumns, nWidthInChars ); ++nArgs; // removing this method of setting fontList to fix SuSe bug // that gives dagger characters // XtSetArg( aArg[nArgs], XmNfontList, GuiApp::pGetGuiApp()->xmfontListGet() ); ++nArgs; widFirstLineText_ = XmCreateText(widForm, "navtextfield", aArg, nArgs); XtManageChild(widFirstLineText_); const int nSpacingBetweenButtons = 1; int nButtonLocationLeft[6]; int nButtonLocationRight[6]; bool bAddMultiplePurposeButton = ( pcbSpecialPurposeButton_ ) ? true : false; int nNumberOfButtons = bAddMultiplePurposeButton ? 6 : 5; double dWidthOfAButton = ( 100 - nSpacingBetweenButtons * ( nNumberOfButtons + 1) ) / (double) nNumberOfButtons; for( int nButton = 0; nButton < nNumberOfButtons; ++nButton ) { nButtonLocationLeft[ nButton ] = nSpacingBetweenButtons * ( nButton + 1 ) + (int) (dWidthOfAButton * nButton ); nButtonLocationRight[ nButton ] = nSpacingBetweenButtons * ( nButton + 1 ) + (int) (dWidthOfAButton * ( nButton + 1 )); } // get the widget id's of the buttons (stored in appropriately // named members) widGoButton_ = XtVaCreateManagedWidget( "Go", xmPushButtonWidgetClass, widForm, XmNbottomAttachment, XmATTACH_FORM, XmNbottomOffset, 10, XmNtraversalOn, False, XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, nButtonLocationLeft[0], XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, nButtonLocationRight[0], NULL ); XtAddCallback(widGoButton_, XmNactivateCallback, (XtCallbackProc )guiMultiContigNavigatorXtButtonCb, this); widPrevButton_ = XtVaCreateManagedWidget( "Prev", xmPushButtonWidgetClass, widForm, XmNbottomAttachment, XmATTACH_FORM, XmNbottomOffset, 10, XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET, XmNtopWidget, widGoButton_, XmNtraversalOn, False, XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, nButtonLocationLeft[1], XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, nButtonLocationRight[1], NULL ); XtAddCallback(widPrevButton_, XmNactivateCallback, (XtCallbackProc )guiMultiContigNavigatorXtButtonCb, this); widNextButton_ = XtVaCreateManagedWidget( "Next", xmPushButtonWidgetClass, widForm, XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET, XmNtopWidget, widGoButton_, XmNbottomAttachment, XmATTACH_FORM, XmNbottomOffset, 10, XmNtraversalOn, False, XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, nButtonLocationLeft[2], XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, nButtonLocationRight[2], NULL ); XtAddCallback(widNextButton_, XmNactivateCallback, (XtCallbackProc )guiMultiContigNavigatorXtButtonCb, this); widSaveButton_ = XtVaCreateManagedWidget( "Save", xmPushButtonWidgetClass, widForm, XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET, XmNtopWidget, widGoButton_, XmNbottomAttachment, XmATTACH_FORM, XmNbottomOffset, 10, XmNtraversalOn, False, XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, nButtonLocationLeft[3], XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, nButtonLocationRight[3], NULL ); XtAddCallback(widSaveButton_, XmNactivateCallback, (XtCallbackProc )guiMultiContigNavigatorXtButtonCb, this); if ( bAddMultiplePurposeButton ) { widSpecialPurposeButton_ = XtVaCreateManagedWidget( (char*) soTitleOfSpecialPurposeButton.data(), xmPushButtonWidgetClass, widForm, XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET, XmNtopWidget, widGoButton_, XmNbottomAttachment, XmATTACH_FORM, XmNbottomOffset, 10, XmNtraversalOn, False, XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, nButtonLocationLeft[4], XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, nButtonLocationRight[4], NULL ); XtAddCallback(widSpecialPurposeButton_, XmNactivateCallback, (XtCallbackProc )guiMultiContigNavigatorXtButtonCb, this); } else widSpecialPurposeButton_ = NULL; int nLastButtonIndex = bAddMultiplePurposeButton ? 5 : 4; widDismissButton_ = XtVaCreateManagedWidget( "Dismiss", xmPushButtonWidgetClass, widForm, XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET, XmNtopWidget, widGoButton_, XmNbottomAttachment, XmATTACH_FORM, XmNbottomOffset, 10, XmNtraversalOn, False, XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, nButtonLocationLeft[ nLastButtonIndex ], XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, nButtonLocationRight[ nLastButtonIndex ], NULL ); XtAddCallback(widDismissButton_, XmNactivateCallback, (XtCallbackProc )guiMultiContigNavigatorXtButtonCb, this); nArgs = 0; XtSetArg(aArg[nArgs], XmNselectionPolicy, XmSINGLE_SELECT); nArgs++; XtSetArg(aArg[nArgs], XmNmustMatch, True); nArgs++; XtSetArg(aArg[nArgs], XmNlistItems, paXms); nArgs++; XtSetArg(aArg[nArgs], XmNlistItemCount, nNumGotoItems); nArgs++; XtSetArg(aArg[nArgs], XmNlistLabelString, xmsListLabel); nArgs++; // XtSetArg(aArg[nArgs], XmNselectionLabelString, xmsSelectionLabel); nArgs++; XtSetArg(aArg[nArgs], XmNdialogType, XmDIALOG_COMMAND); nArgs++; XtSetArg(aArg[nArgs], XmNtopAttachment, XmATTACH_WIDGET); nArgs++; XtSetArg(aArg[nArgs], XmNtopWidget, widFirstLineText_ ); nArgs++; XtSetArg(aArg[nArgs], XmNtopOffset, 0 ); nArgs++; XtSetArg(aArg[nArgs], XmNleftAttachment, XmATTACH_FORM); nArgs++; XtSetArg(aArg[nArgs], XmNrightAttachment, XmATTACH_FORM); nArgs++; XtSetArg(aArg[nArgs], XmNbottomAttachment, XmATTACH_WIDGET); nArgs++; XtSetArg(aArg[nArgs], XmNbottomWidget, widGoButton_); nArgs++; XtSetArg(aArg[nArgs], XmNbottomOffset, 10 ); nArgs++; XtSetArg(aArg[nArgs], XmNmarginWidth, 0 ); nArgs++; XtSetArg(aArg[nArgs], XmNmarginHeight, 0 ); nArgs++; XtSetArg( aArg[nArgs], XmNtextColumns, (short) nWidthInChars ); ++nArgs; widSelectionBox_ = XmCreateSelectionBox( widForm, "navigator", aArg, nArgs); XtManageChild( widSelectionBox_ ); // get the widget id for the text widget Widget widText = XmSelectionBoxGetChild(widSelectionBox_, XmDIALOG_TEXT); // make the text not editable, traversal off, etc. XtUnmanageChild( widText ); Widget widLabel = XmSelectionBoxGetChild(widSelectionBox_, XmDIALOG_SELECTION_LABEL); XtUnmanageChild( widLabel ); // get the widget id for the list widget widList_ = XmSelectionBoxGetChild(widSelectionBox_, XmDIALOG_LIST); // set traversal off for list, etc. nArgs = 0; XtSetArg(aArg[nArgs], XmNtraversalOn, False); nArgs++; // removing this method of setting fontList to fix SuSe bug // that gives dagger characters // XtSetArg( aArg[nArgs], XmNfontList, GuiApp::pGetGuiApp()->xmfontListGet() ); ++nArgs; // XtSetArg(aArg[nArgs], XmNlistSizePolicy, XmVARIABLE ); nArgs++; XtSetValues(widList_, aArg, nArgs); // This is so the user can double-click on an item on the list rather // than single clicking and clicking 'go' XtAddCallback(widList_, XmNdefaultActionCallback, (XtCallbackProc )guiMultiContigNavigatorXtButtonCb, this); XtManageChild(widSelectionBox_); // free the strings we used XmStringFree(xmsListLabel); XmStringFree(xmsSelectionLabel); for (n = 0; n < nNumGotoItems; n++) { XmStringFree(paXms[n]); } XtPopup( widPopupShell_, XtGrabNone ); } void guiMultiContigNavigatorXtButtonCb(Widget wid, XtPointer clientData, XmSelectionBoxCallbackStruct* cbs) { guiMultiContigNavigator* pNav = (guiMultiContigNavigator* )clientData; TRY_CATCH_WRAPPER( pNav->guiMultiContigNavigatorXtButtonCb2( wid ) ); } void guiMultiContigNavigator :: popDownAndDestroy() { delete this; } void guiMultiContigNavigator :: guiMultiContigNavigatorXtButtonCb2( Widget wid ) { // Dismiss button if (wid == widDismissButton_ ) { popDownAndDestroy(); return; } // in all cases except for dismiss, there must be some items in the list. // otherwise ignore the user. if ( pGotoList_->nGetNumGotoItems() == 0 ) { GuiApp::popupErrorMessage( "This command doesn't make sense with an empty list" ); return; } if (wid == widSaveButton_ ) { saveNavigatorList(); return; } int nCurIndex; int* pPositionList; int nNumberOfSelectedItems; if ( XmListGetSelectedPos( widList_, &pPositionList, &nNumberOfSelectedItems ) ) { if ( nNumberOfSelectedItems == 0 ) { nCurIndex = navigatorNoSelection; } else { assert( nNumberOfSelectedItems == 1 ); nCurIndex = pPositionList[0]; } XtFree( (char*) pPositionList ); } else nCurIndex = navigatorNoSelection; if ( wid == widSpecialPurposeButton_ ) { gotoItem* pGotoItem; if ( nCurIndex == navigatorNoSelection ) pGotoItem = NULL; else { // -1 since the Motif list is 1-based and the Rogue Wave list // is 0-based pGotoItem = (*pGotoList_)[ nCurIndex - 1]; } pcbSpecialPurposeButton_( pGotoItem, pClientDataForSpecialPurposeButton_ ); return; } int nGotoIndex; // where we want to go (may be different from currently // selected item if the user pushes next or prev if (wid == widGoButton_ || wid == widList_ ) { if ( ( wid == widGoButton_ ) && ( nCurIndex == navigatorNoSelection ) ) { GuiApp::popupErrorMessage( "First click on an item before clicking on Go" ); return; } nGotoIndex = nCurIndex; } else if (wid == widNextButton_ ) { // which one is "next"? if (nCurrentSelection_ == navigatorNoSelection ) { nGotoIndex = 1; // go to first one } else if (nCurrentSelection_ < nGetMaxIndex()) { nGotoIndex = nCurrentSelection_ + 1; } else { nGotoIndex = navigatorNoSelection; } } else if (wid == widPrevButton_ ) { // which one is "prev"? if ((nCurrentSelection_ == navigatorNoSelection ) || (nCurrentSelection_ == 1) ) { nGotoIndex = 1; // go to first one } else { nGotoIndex = nCurrentSelection_ - 1; } } else assert(false); if (nGotoIndex != navigatorNoSelection) { // highlight the position we are going to int nTopIndex; int nVisibleItems; XtVaGetValues( widList_, XmNtopItemPosition, &nTopIndex, XmNvisibleItemCount, &nVisibleItems, NULL ); // motif list's start at 1 int nIndexInMotifList = nGotoIndex; if ( nIndexInMotifList < nTopIndex ) XmListSetPos( widList_, nIndexInMotifList ); else if (nIndexInMotifList > nTopIndex + nVisibleItems - 1) XmListSetBottomPos( widList_, nIndexInMotifList ); XmListSelectPos( widList_, nIndexInMotifList, True ); // set the current selection member data // long winded debug version nCurrentSelection_ = nGotoIndex; // because nGotoIndex starts at 1 but gotoList starts at 0 gotoItem* pGotoItem = (*pGotoList_)[nGotoIndex - 1]; int nConsPos = pGotoItem->nGetStart(); Contig* pContig = pGotoItem->pGetContig(); // this can happen, for example, with hits against singletons if (!pContig ) return; // this fixes the following bug: if you bring up a contig, // and then you bring it up again, and then you bring up a nav window, // and you click 'next', it will scroll the first one--not the // one you brought up the nav window from. Now fixed (DG, 1/17/99 // in Iceland!) ContigWin* pContigWin = NULL; if (pGotoItem->pGetLocFrag() ) { if ( pContigWin_ ) { pContigWin = pContigWin_; // the moveCursorToConsPos doesn't scroll the aligned reads // window--it just moves the cursor. Thus we must first // scroll so this position is visible pContigWin->scrollToConsensusPosInCenter( nConsPos ); } else pContigWin = ConsEd::pGetConsEd()->pScrollExistingContigWinOrMakeNewContigWin( pContig, nConsPos ); pContigWin->moveCursorToFragPos( nConsPos, pGotoItem->pGetLocFrag() ); } else { if ( pContigWin_ ) { pContigWin = pContigWin_; pContigWin->scrollToConsensusPosInCenterAndSetCursorOnConsensus( nConsPos ); } else { pContigWin = ConsEd::pGetConsEd()->pScrollExistingContigWinOrMakeNewContigWinAndSetCursorOnConsensus( pContig, nConsPos ); } } // raise the window pContigWin->raiseWindow(); if ( consedParameters::pGetConsedParameters()->bNavigateAutomaticTracePopup_ ) { // check if this is on a read if ( pGotoItem->pGetLocFrag() ) { // if on a read, bring up the trace pContigWin->scrollExistingTracesOrPopupIfNecessary( pGotoItem->pGetLocFrag(), nConsPos ); } } if ( consedParameters::pGetConsedParameters()->bNavigateAutomaticAllTracesPopup_ ) { // check if this is on the consensus if ( ! (pGotoItem->pGetLocFrag() ) ) { // if on the consensus, bring up all traces pContigWin->showAllTracesByConsensusPosition( nConsPos ); } } } } void guiMultiContigNavigator :: saveNavigatorList() { RWCString soDirMask = "*.*"; RWCString soTryOutFileName = "list.txt"; FileName soUserOutFileName = GuiApp::popupFileSelector("Save list to file", soDirMask, soTryOutFileName); // if user cancelled or did not supply name, bail now if (soUserOutFileName.isNull()) { return; } bool bGoAhead = true; if (soUserOutFileName.bFileByThisNameExists()) { bGoAhead = GuiApp::popupDecisionMessage("File %s exists. Save anyway?", (const char*)soUserOutFileName); } if (! bGoAhead) return; try { saveNavigatorList2( soUserOutFileName ); } catch (SysRequestFailed srf) { GuiApp::popupErrorMessage(srf.szGetDesc()); } } void guiMultiContigNavigator :: saveNavigatorList2( const RWCString& soFilename ) { // open the output file ofstream ofsNavigatorListFile( soFilename, ios::out); if (! ofsNavigatorListFile) { // throw an exception with a detailed explanation ostringstream ost; ost << "Unable to open file " << soFilename << " for writing" << endl << ends; SysRequestFailed srf(ost.str().c_str()); // what the hell, show 'em the errno srf.includeErrnoDescription(); throw srf; } // how many gotoItems in the list? int nNumGotoItems = pGotoList_->nGetNumGotoItems(); for (int n = 0; n < nNumGotoItems; n++) { ofsNavigatorListFile << (*pGotoList_)[n]->soGetFullDesc() << endl; } ofsNavigatorListFile.close(); } void guiMultiContigNavigator :: appendToMultiContigNavigator( gotoItem* pGotoItemToAppend ) { pGotoList_->addToList( pGotoItemToAppend ); XmString xms = // get char* from gotoItem* from gotoList* XmStringCreateSimple((char*)( pGotoItemToAppend->soGetFullDesc().data())); int nOneBasedIndex = pGotoList_->nGetNumGotoItems(); XmListAddItem( widList_, xms, nOneBasedIndex ); } void guiMultiContigNavigator :: appendToList ( gotoItem* pGotoItemToAppend ) { pGotoList_->addToList( pGotoItemToAppend ); } void guiMultiContigNavigator :: displayList( const bool bSortByStartPosition ) { if ( bSortByStartPosition ) pGotoList_->sortByPosition(); XmString* pXmStrings; pXmStrings = (XmString*) XtMalloc( sizeof( XmString ) * pGotoList_->nGetNumGotoItems() ); int nGotoItem; for( nGotoItem = 0; nGotoItem < pGotoList_->nGetNumGotoItems(); ++nGotoItem ) { gotoItem* pGotoItem = pGotoList_->pGetGotoItem( nGotoItem ); pXmStrings[ nGotoItem ] = XmStringCreateSimple( (char*) pGotoItem->soGetFullDesc().data() ); } XtVaSetValues( widList_, XmNitems, pXmStrings, XmNitemCount, pGotoList_->nGetNumGotoItems(), NULL ); for( nGotoItem = 0; nGotoItem < pGotoList_->nGetNumGotoItems(); ++nGotoItem ) XmStringFree( pXmStrings[ nGotoItem ] ); XtFree( (char*) pXmStrings ); } void guiMultiContigNavigator :: gotoNextOrPreviousItem( const bool bNextNotPrevious ) { Widget wid = ( bNextNotPrevious ? widNextButton_ : widPrevButton_ ); guiMultiContigNavigatorXtButtonCb2( wid ); } guiMultiContigNavigator :: ~guiMultiContigNavigator() { if ( pContigWin_ ) { // allow the possibility that the same aligned reads window // has several different navigate windows up at once if ( pContigWin_->pGuiMultiContigNav_ == this ) pContigWin_->pGuiMultiContigNav_ = NULL; } else if ( pAssemblyView_ ) { pAssemblyView_->pGuiNav_ = NULL; } else { ConsEd::pGetConsEd()->aGuiMultiContigNavigator_.remove( this ); } // there is a memory leak here--the gotoList should be deallocated unmanage(); XtDestroyWidget( widPopupShell_ ); } void guiMultiContigNavigator :: raiseWindow() { XtMapWidget( widPopupShell_ ); XRaiseWindow( XtDisplay( widPopupShell_ ), XtWindow( widPopupShell_ ) ); } void guiMultiContigNavigator :: scrollDownToBottom() { int nVisibleItemCount; XtVaGetValues( widList_, XmNvisibleItemCount, &nVisibleItemCount, NULL ); if ( pGotoList_->nGetNumGotoItems() > nVisibleItemCount ) { XtVaSetValues( widList_, XmNtopItemPosition, pGotoList_->nGetNumGotoItems() - nVisibleItemCount + 1, NULL ); } }