/***************************************************************************** # 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 "tag.h" #include "soGetDateTime.h" #include "soGetDate.h" #include "assert.h" #include "numutil.h" // #include "tagTypes.h" #include "guiPopupTagInfo.h" #include "guiapp.h" #include "contig.h" #include "consed.h" #include #include #include #include #include #include #include #include "search_for_string.h" #include "hp_exception_kludge.h" #include "searchMethods.h" #include "rwcregexp.h" #include "userDefinedTagField.h" #include "tagTypes.h" #include "guiGetUserDefinedTagInfo.h" tag :: tag( LocatedFragment* pLocFrag, // only used // if this is a read tag Contig* pContig, // only used if this is // is a consensus tag const RWCString& soType, const int nConsPosStart, const int nConsPosEnd, const bool bWriteToPhdFileNotAceFile, const RWCString& soComment, const RWCString& soSource, const RWCString& soDate, const bool bNoTrans ) : pLocFrag_( pLocFrag ), pContig_( pContig ), soType_( soType ), bCoordinatesAreUnpaddedRead_( false ), nPaddedConsPosStart_( nConsPosStart ), nPaddedConsPosEnd_( nConsPosEnd ), bWriteToPhdFileNotAceFile_( bWriteToPhdFileNotAceFile ), soComment_( soComment ), soSource_( soSource ), soDate_( soDate ), bNoTrans_( bNoTrans ), pGuiPopupTagInfo_( NULL ), lID_( nUndefinedTagID ), pArrayOfUserDefinedTagFields_( NULL ) { if ( pLocFrag_ ) { pContig_ = pLocFrag_->pGetContig(); bReadTagNotConsensusTag_ = true; } else bReadTagNotConsensusTag_ = false; if (soDate_ == soEmptyString ) { if ( bReadTagNotConsensusTag_ ) soDate_ = soGetDateTime( nSlashes ); else soDate_ = soGetDateTime( nNoSlashes ); } // assert( tagTypes::pGetConsensusTagType()->bIsAValidTagType( soType ) ); tagType* pTagType = tagTypes::pGetTagTypes()->pGetTagType( soType ); if ( pTagType->bIsAUserDefinedTagType() ) { pUserDefinedTagType_ = (userDefinedTagType*) pTagType; } else pUserDefinedTagType_ = NULL; } bool tag :: bTagIsOnScreen( const int nConsPosMin, const int nConsPosMax, int& nVisibleConsPosMin, int& nVisibleConsPosMax ) { return( bIntersect( nPaddedConsPosStart_, nPaddedConsPosEnd_, nConsPosMin, nConsPosMax, nVisibleConsPosMin, nVisibleConsPosMax ) ); } void tag :: popupTagInfoForOneTag( const int nNumberOfTagsAlreadyPoppedUp, void* pGuiContigWinOrGuiTeditor, const bool bIsGuiContigWin ) { if ( ! pGuiPopupTagInfo_ ) { pGuiPopupTagInfo_ = new guiPopupTagInfo( pGuiContigWinOrGuiTeditor, bIsGuiContigWin, nNumberOfTagsAlreadyPoppedUp, this ); } else { pGuiPopupTagInfo_->raiseWindow(); } } void tag :: writeTagToEditHistoryFile() { if (bReadTagNotConsensusTag_ ) ConsEd :: pGetAssembly()->writeEditToEditHistoryFile( "addReadTag %s %s %s %s %d %d %s", (char*) soType_.data(), (char*) soSource_.data(), (char*) pContig_->soGetName().data(), (char*) pLocFrag_->soGetFragmentName().data(), nPaddedConsPosStart_, nPaddedConsPosEnd_, (char*) soDate_.data() ); else ConsEd :: pGetAssembly()->writeEditToEditHistoryFile( "addConsensusTag %s %s %s %d %d %s", (char*) soType_.data(), (char*) soSource_.data(), (char*) pContig_->soGetName().data(), nPaddedConsPosStart_, nPaddedConsPosEnd_, (char*) soDate_.data() ); if ( !soComment_.isNull() ) { ConsEd::pGetAssembly()->writeEditToEditHistoryFile( "BEGIN_COMMENT" ); RWCString soTemp = soComment_.stripWhitespace( RWCString::TRAILING ); ConsEd::pGetAssembly()->writeEditToEditHistoryFile( soTemp.data() ); ConsEd::pGetAssembly()->writeEditToEditHistoryFile( "END_COMMENT" ); } if ( !soMiscData_.isNull() ) { ConsEd::pGetAssembly()->writeEditToEditHistoryFile( "BEGIN_MISC" ); RWCString soTemp = soMiscData_.stripWhitespace( RWCString::TRAILING ); ConsEd::pGetAssembly()->writeEditToEditHistoryFile( soTemp.data() ); ConsEd::pGetAssembly()->writeEditToEditHistoryFile( "END_MISC" ); } } void tag :: writeDeleteTagToEditHistoryFile() { if ( bReadTagNotConsensusTag_ ) ConsEd::pGetAssembly()->writeEditToEditHistoryFile( "deleteReadTag %s %s %s %s %d %d %s", (char*) soType_.data(), (char*) soSource_.data(), (char*) pContig_->soGetName().data(), (char*) pLocFrag_->soGetName().data(), nPaddedConsPosStart_, nPaddedConsPosEnd_, (char*) soDate_.data() ); else ConsEd::pGetAssembly()->writeEditToEditHistoryFile( "deleteConsensusTag %s %s %s %d %d %s", (char*) soType_.data(), (char*) soSource_.data(), (char*) pContig_->soGetName().data(), nPaddedConsPosStart_, nPaddedConsPosEnd_, (char*) soDate_.data() ); if ( !soComment_.isNull() ) { ConsEd::pGetAssembly()->writeEditToEditHistoryFile( "BEGIN_COMMENT" ); RWCString soTemp = soComment_.stripWhitespace( RWCString::TRAILING ); ConsEd::pGetAssembly()->writeEditToEditHistoryFile( soTemp.data() ); ConsEd::pGetAssembly()->writeEditToEditHistoryFile( "END_COMMENT" ); } if ( !soMiscData_.isNull() ) { ConsEd::pGetAssembly()->writeEditToEditHistoryFile( "BEGIN_MISC" ); RWCString soTemp = soMiscData_.stripWhitespace( RWCString::TRAILING ); ConsEd::pGetAssembly()->writeEditToEditHistoryFile( soTemp.data() ); ConsEd::pGetAssembly()->writeEditToEditHistoryFile( "END_MISC" ); } } bool tag :: bCheckTag( const int nPerhapsStartTagUnpaddedConsPos, const int nPerhapsEndTagUnpaddedConsPos ) { if (! (nPerhapsStartTagUnpaddedConsPos <= nPerhapsEndTagUnpaddedConsPos ) ) { GuiApp::popupErrorMessage( "Please help me out by making the start position <= end position" ); return( false ); } int nTagLeftMostAllowedConsPos; int nTagRightMostAllowedConsPos; if ( bReadTagNotConsensusTag_ ) { nTagLeftMostAllowedConsPos = pLocFrag_->nGetAlignStart(); nTagRightMostAllowedConsPos = pLocFrag_->nGetAlignEnd(); } else { nTagLeftMostAllowedConsPos = pContig_->nGetStartConsensusIndex(); nTagRightMostAllowedConsPos = pContig_->nGetEndConsensusIndex(); } int nTagLeftMostAllowedUnpadded = pContig_->nUnpaddedIndex( nTagLeftMostAllowedConsPos ); int nTagRightMostAllowedUnpadded = pContig_->nUnpaddedIndex( nTagRightMostAllowedConsPos ); if ( ! ( ( nTagLeftMostAllowedUnpadded <= nPerhapsStartTagUnpaddedConsPos ) && ( nPerhapsEndTagUnpaddedConsPos <= nTagRightMostAllowedUnpadded ) )) { char szError[200]; sprintf( szError, "Tag's Start and End Consensus Positions must be between %d and %d ", nTagLeftMostAllowedUnpadded, nTagRightMostAllowedUnpadded ); GuiApp::popupErrorMessage( szError ); return( false ); } int nOriginalStartTagUnpaddedConsPos = pContig_->nUnpaddedIndex( nPaddedConsPosStart_ ); int nOriginalEndTagUnpaddedConsPos = pContig_->nUnpaddedIndex( nPaddedConsPosEnd_ ); if ( ( nPerhapsStartTagUnpaddedConsPos != nOriginalStartTagUnpaddedConsPos ) || ( nPerhapsEndTagUnpaddedConsPos != nOriginalEndTagUnpaddedConsPos ) ) { if ( soType_ == "edit" ) { GuiApp::popupErrorMessage( "you can't delete or modify edit tags" ); return( false ); } } return( true ); } void tag :: changeTag( const int nPerhapsStartTagUnpaddedConsPos, const int nPerhapsEndTagUnpaddedConsPos ) { bool bSomethingChanged = false; int nOriginalStartTagUnpaddedConsPos = pContig_->nUnpaddedIndex( nPaddedConsPosStart_ ); int nOriginalEndTagUnpaddedConsPos = pContig_->nUnpaddedIndex( nPaddedConsPosEnd_ ); if ( ( nPerhapsStartTagUnpaddedConsPos != nOriginalStartTagUnpaddedConsPos ) || ( nPerhapsEndTagUnpaddedConsPos != nOriginalEndTagUnpaddedConsPos ) ) { bSomethingChanged = true; } if (bSomethingChanged ) { nPaddedConsPosStart_ = pContig_->nPaddedIndex( nPerhapsStartTagUnpaddedConsPos ); nPaddedConsPosEnd_ = pContig_->nPaddedIndex( nPerhapsEndTagUnpaddedConsPos ); if ( bReadTagNotConsensusTag_ ) pLocFrag_->setChanged(); else pContig_->setChanged(); } } void tag :: changeTagComment( const RWCString& soComment ) { if ( soComment != soComment_ ) { soComment_ = soComment; if ( bReadTagNotConsensusTag_ ) pLocFrag_->setChanged(); else pContig_->setChanged(); } } void tag :: writeTagToPHDFile( ofstream& ofsPHD ) { // should only be writing to PHD files if you are a read tag assert( pLocFrag_ ); ofsPHD << "BEGIN_TAG" << endl; ofsPHD << "TYPE: " << soType_ << endl; ofsPHD << "SOURCE: " << soSource_ << endl; int nUnpaddedStart = pLocFrag_->nOrientedUnpaddedFragPosFromConsPos( nPaddedConsPosStart_ ); int nUnpaddedEnd = pLocFrag_->nOrientedUnpaddedFragPosFromConsPos( nPaddedConsPosEnd_ ); char szTemp[200]; sprintf( szTemp, "%d %d", nUnpaddedStart, nUnpaddedEnd ); ofsPHD << "UNPADDED_READ_POS: " << szTemp << endl; ofsPHD << "DATE: " << soDate_ << endl; if ( lID_ != nUndefinedTagID ) { ofsPHD << "ID: " << RWCString( lID_ ) << endl; } soComment_ = soComment_.stripWhitespace( RWCString::TRAILING ); if ( !soComment_.isNull() ) { ofsPHD << "BEGIN_COMMENT" << endl; ofsPHD << soComment_ << endl; // note that trailing cr's are stripped off of the comment on // input so we need to add the endl after the comment ofsPHD << "END_COMMENT" << endl; } writeToPHDFileAnythingSpecialForThisTagType( ofsPHD ); ofsPHD << "END_TAG" << endl; ofsPHD << endl; } void tag :: writeToPHDFileAnythingSpecialForThisTagType( ofstream& ofsPHD ) { if ( pUserDefinedTagType_ ) { writeUserDefinedTagTypeFields( ofsPHD ); } else { if ( !soMiscData_.isNull() ) { ofsPHD << soMiscData_; if ( soMiscData_.cGetLastChar() != '\n' ) ofsPHD << endl; } } } void tag :: adjustTagPosition(const int nAdjustToRightOfThisConsPos, const int nAmountToAdjust ) { if ( nAdjustToRightOfThisConsPos <= nPaddedConsPosStart_ ) nPaddedConsPosStart_ += nAmountToAdjust; if ( nAdjustToRightOfThisConsPos <= nPaddedConsPosEnd_ ) nPaddedConsPosEnd_ += nAmountToAdjust; } static RWCString soPointsRight = "\ngap->\n"; static RWCString soPointsLeft = "\n<-gap\n"; void tag :: complementSelf( ) { pContig_->complementEndPoints( nPaddedConsPosStart_, nPaddedConsPosEnd_ ); if ( soType_ == "cloneEnd" ) { if ( soMiscData_ == "->" ) soMiscData_ = "<-"; else soMiscData_ = "->"; } else if ( soType_ == "contigEndPair" ) { bool bPointsRight; int nIndex = soMiscData_.index( soPointsRight ); if ( nIndex != RW_NPOS ) bPointsRight = true; else { nIndex = soMiscData_.index( soPointsLeft ); assert( nIndex != RW_NPOS ); bPointsRight = false; } RWCString& soNewString = ( bPointsRight ? soPointsLeft : soPointsRight ); // replace the old string with the new string soMiscData_.replace( nIndex, soNewString ); } } void tag :: writeTagToAceFile( ofstream& ofsAceFile ) { if ( bReadTagNotConsensusTag_ ) { ofsAceFile << "RT{" << endl << pLocFrag_->soGetName() << " " << soType_ << " " << soSource_ << " " << pLocFrag_->nGetFragIndexFromConsPos( nPaddedConsPosStart_ ) << " " << pLocFrag_->nGetFragIndexFromConsPos( nPaddedConsPosEnd_ ) << " " << soDate_ << endl; } else { ofsAceFile << "CT{" << endl; ofsAceFile << pContig_->soGetName() << " " << soType_ << " " << soSource_ << " " << nPaddedConsPosStart_ << " " << nPaddedConsPosEnd_ << " " << soDate_; if ( bNoTrans_ ) { ofsAceFile << " NoTrans"; } ofsAceFile << endl; } // this is polymorphic--may call a function not in the tag class this->writeToAceFileAnythingSpecialForThisTagType( ofsAceFile ); // write tag id, if there is one if ( lID_ != nUndefinedTagID ) { ofsAceFile << "ID: " << lID_ << endl; } // write comment at end of tag soComment_ = soComment_.stripWhitespace( RWCString::TRAILING ); if ( !soComment_.isNull() ) { ofsAceFile << "COMMENT{" << endl; ofsAceFile << soComment_ << endl; ofsAceFile << "C}" << endl; } // the end on the tag! ofsAceFile << "}" << endl << endl; } void tag :: writeToAceFileAnythingSpecialForThisTagType( ofstream& ofsAceFile ) { if ( soMiscData_.length() > 0 ) { ofsAceFile << soMiscData_; if ( soMiscData_[ soMiscData_.length() - 1 ] != '\n' ) ofsAceFile << endl; } if ( pUserDefinedTagType_ ) writeUserDefinedTagTypeFields( ofsAceFile ); } void tag :: writeUserDefinedTagTypeFields( ofstream& ofsAceFile ) { if ( !pArrayOfUserDefinedTagFields_ ) return; // I think this would indicate a programming error for( int nField = 0; nField < pArrayOfUserDefinedTagFields_->length(); ++nField ) { userDefinedTagField* pUserDefinedTagField = (*pArrayOfUserDefinedTagFields_)[ nField ]; pUserDefinedTagField->writeThyselfToAceFile( ofsAceFile ); } } void tag :: guiDisplayExtraInformation( Widget widForm, Widget widAbove, Widget widBelow, bool& bExtraStuffDisplayed, Widget& widBottomOfExtraStuff ) { if ( pArrayOfUserDefinedTagFields_ ) { displayUserDefinedTagFields( widForm, widAbove, widBelow, widBottomOfExtraStuff ); bExtraStuffDisplayed = true; } else if ( soType_ == "matchElsewhereHighQual" || soType_ == "matchElsewhereLowQual" ) { Widget widSearchForStringButton = XtVaCreateManagedWidget( "search for string", xmPushButtonWidgetClass, widForm, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, widAbove, XmNtopOffset, 10, // XmNbottomAttachment, XmATTACH_WIDGET, // XmNbottomWidget, widBelow, XmNbottomOffset, 10, XmNtraversalOn, False, NULL ); XtAddCallback( widSearchForStringButton, XmNactivateCallback, (XtCallbackProc) cbMatchElsewhereTagSearchForString, this ); Dimension nTotalWidth; XtVaGetValues( widForm, XmNwidth, &nTotalWidth, NULL ); Dimension nButtonWidth; XtVaGetValues( widSearchForStringButton, XmNwidth, &nButtonWidth, NULL ); int nLeftPosition = ( nTotalWidth - nButtonWidth ) / 2; XtVaSetValues( widSearchForStringButton, XmNx, (Dimension) nLeftPosition, NULL ); widBottomOfExtraStuff = widSearchForStringButton; bExtraStuffDisplayed = true; } else { bExtraStuffDisplayed = false; } } void cbMatchElsewhereTagSearchForString( Widget wid, XtPointer pClientData, XtPointer pCallData ) { TRY_CATCH_WRAPPER( tag* pTag = (tag*) pClientData; pTag->matchElsewhereTagSearchForString(); ); } void tag :: matchElsewhereTagSearchForString() { RWCString soQueryBases = pLocFrag_->soGetPartOfReadUpperOrLower( nPaddedConsPosStart_, nPaddedConsPosEnd_ ); // remove all pads for( int n = soQueryBases.length() - 1; n >= 0; --n ) { if ( soQueryBases[n] == '*' ) soQueryBases.remove( n, 1 ); } // guess at the singlets filename FileName filSingletsFile = ConsEd::pGetAssembly()->soGetAceFileName(); // chop off everything starting with .fasta.screen. RWCRegexp regFasta( "\\.fasta\\.screen\\..*$" ); filSingletsFile( regFasta ) = ""; filSingletsFile += ".fasta.screen.singlets"; popupOutputWindowAndDoSearch( soQueryBases, nExact, // search method ignored false, // search reads, not contigs 0, // per cent mismatch ignored filSingletsFile ); } RWCString tag :: soGetExtraInformationForNavigator(const int nMaxLength ) { RWCString soExtraInfo; if ( !soComment_.isNull() ) { if ( soComment_.length() <= nMaxLength ) soExtraInfo = soComment_; else { if ( nMaxLength < 4 ) return( "" ); else return( soComment_( 0, nMaxLength - 3 ) + "..." ); } } if ( !soMiscData_.isNull() ) { soExtraInfo += soMiscData_; } if ( soExtraInfo.length() <= nMaxLength ) return( soExtraInfo ); else { if ( nMaxLength < 4 ) return( "" ); else return( soExtraInfo( 0, nMaxLength - 3 ) + "..." ); } } Contig* tag :: pGetContig() { if ( bReadTagNotConsensusTag_ ) { return( pLocFrag_->pContig_ ); } else { return( pContig_ ); } } void tag :: displayUserDefinedTagFields( Widget widForm, Widget widAbove2, Widget widBelow, Widget& widBottomOfExtraStuff ) { Widget widAbove = widAbove2; for( int nUserDefinedTagField = 0; nUserDefinedTagField < pArrayOfUserDefinedTagFields_->length(); ++nUserDefinedTagField ) { userDefinedTagField* pUserDefinedTagField = (*pArrayOfUserDefinedTagFields_)[ nUserDefinedTagField ]; RWCString soLabel = pUserDefinedTagField->pUserDefinedTagFieldType_->soFieldName_; if ( pUserDefinedTagField->eWhatType() == userDefinedTagFieldType::eInteger || pUserDefinedTagField->eWhatType() == userDefinedTagFieldType::eFloating ) { Widget widLabel = XtVaCreateManagedWidget( soLabel.data(), xmLabelWidgetClass, widForm, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, 40, NULL ); RWCString soValue; if ( pUserDefinedTagField->eWhatType() == userDefinedTagFieldType::eInteger ) soValue = RWCString( ((userDefinedIntegerTagField*)pUserDefinedTagField)->l_ ); else if ( pUserDefinedTagField->eWhatType() == userDefinedTagFieldType::eFloating ) { soValue = RWCString( ( (userDefinedFloatingTagField*)pUserDefinedTagField)->d_ ); } else assert( false ); Widget widValue = XtVaCreateManagedWidget( "value", xmTextFieldWidgetClass, widForm, XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, 45, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, widAbove, XmNvalue, soValue.data(), NULL ); XtVaSetValues( widLabel, XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET, XmNtopWidget, widValue, XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET, XmNbottomWidget, widValue, NULL ); widAbove = widValue; } else if ( pUserDefinedTagField->eWhatType() == userDefinedTagFieldType::eString ) { RWCString soValue = ((userDefinedStringTagField*) pUserDefinedTagField )->so_; // we need to determine whether this field has 1 line or more than // one line. If there is a '\n' anywhere in the string, then there // is more than one line. if ( strchr( soValue.data(), '\n' ) == NULL ) { // only one line--set up the widgets the same way // as for eFloating and eInteger Widget widLabel = XtVaCreateManagedWidget( soLabel.data(), xmLabelWidgetClass, widForm, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, 40, NULL ); Widget widValue = XtVaCreateManagedWidget( "text", xmTextFieldWidgetClass, widForm, XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, 45, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, widAbove, XmNvalue, soValue.data(), NULL ); XtVaSetValues( widLabel, XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET, XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET, XmNtopWidget, widValue, XmNbottomWidget, widValue, NULL ); widAbove = widValue; } else { // more than one line. Mimic the way that comments are // done in the guiPopupTagInfo. Widget widLabel = XtVaCreateManagedWidget( soLabel.data(), xmLabelWidgetClass, widForm, XmNleftAttachment, XmATTACH_FORM, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, widAbove, NULL ); int nArgs = 0; Arg aArg[ 30 ]; XtSetArg( aArg[nArgs], XmNtopAttachment, XmATTACH_WIDGET ); ++nArgs; XtSetArg( aArg[nArgs], XmNtopWidget, widLabel ); ++nArgs; XtSetArg( aArg[nArgs], XmNleftAttachment, XmATTACH_FORM ); ++nArgs; XtSetArg( aArg[nArgs], XmNrightAttachment, XmATTACH_FORM ); ++nArgs; XtSetArg( aArg[nArgs], XmNrows, 3 ); ++nArgs; XtSetArg( aArg[nArgs], XmNvalue, soValue.data() ); ++nArgs; XtSetArg( aArg[nArgs], XmNeditMode, XmMULTI_LINE_EDIT ); ++nArgs; XtSetArg( aArg[nArgs], XmNeditable, True ); ++nArgs; XtSetArg( aArg[nArgs], XmNcursorPositionVisible, True ); ++nArgs; Widget widValue = XmCreateScrolledText( widForm, "multilinetext", aArg, nArgs ); XtManageChild( widValue ); widAbove = widValue; } } // else if ( pUserDefinedTagField->eWhatType() == else if ( pUserDefinedTagField->eWhatType() == userDefinedTagFieldType::ePointer ) { userDefinedPointerTagField* pUserDefinedPointerTagField = (userDefinedPointerTagField*) pUserDefinedTagField; Widget widType = XtVaCreateManagedWidget( "type", xmTextFieldWidgetClass, widForm, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, widAbove, XmNvalue, pUserDefinedPointerTagField->pTag_->soType_.data(), NULL ); Widget widLabel1 = XtVaCreateManagedWidget( "pointer to tag of type ", xmLabelWidgetClass, widForm, XmNleftAttachment, XmATTACH_FORM, XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET, XmNtopWidget, widType, XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET, XmNbottomWidget, widType, NULL ); const int nSpaceBetweenWidgets = 10; Dimension dimWidth; XtVaGetValues( widLabel1, XmNwidth, &dimWidth, NULL ); XtVaSetValues( widType, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, dimWidth + nSpaceBetweenWidgets, NULL ); RWCString soLocation = pUserDefinedPointerTagField->pTag_->pGetContig()->soGetName(); soLocation += " "; soLocation += RWCString( (long) pUserDefinedPointerTagField->pTag_->nGetUnpaddedStart() ); soLocation += "-"; soLocation += RWCString( (long) pUserDefinedPointerTagField->pTag_->nGetUnpaddedEnd() ); if ( pUserDefinedPointerTagField->pTag_->bReadTagNotConsensusTag_ ) { soLocation += " on read "; soLocation += pUserDefinedPointerTagField->pTag_->pLocFrag_->soGetName(); } else { soLocation += " on consensus"; } Widget widLocation = XtVaCreateManagedWidget( "location", xmTextFieldWidgetClass, widForm, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, widType, XmNvalue, soLocation.data(), XmNcolumns, 40, NULL ); const int nOffsetOfLabel2 = 30; Widget widLabel2 = XtVaCreateManagedWidget( "at location ", xmLabelWidgetClass, widForm, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, nOffsetOfLabel2, XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET, XmNtopWidget, widLocation, XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET, XmNbottomWidget, widLocation, NULL ); XtVaGetValues( widLabel2, XmNwidth, &dimWidth, NULL ); XtVaSetValues( widLocation, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, nOffsetOfLabel2 + dimWidth + nSpaceBetweenWidgets, NULL ); widAbove = widLocation; } } // for( int nUserDefinedTagField = 0; nUserDefinedTagField < widBottomOfExtraStuff = widAbove; } bool tag :: bTagHasExtraInformation() { // find the corresponding tagType if ( pUserDefinedTagType_ ) { if ( pUserDefinedTagType_->aUserDefinedTagFieldType_.length() > 0 ) return true; else return false; } else return false; } void tag :: askUserForExtraTagInformation( bool& bUserPushedCancel ) { // layout will be OK and Cancel at the bottom // There will be a scrolling window above this with all of // the entry fields in it. if ( !pUserDefinedTagType_ ) { bUserPushedCancel = false; return; } guiGetUserDefinedTagInfo* pGuiGetUserDefinedTagInfo = new guiGetUserDefinedTagInfo( this ); pGuiGetUserDefinedTagInfo->popupBox( bUserPushedCancel ); // let the widget delete itself. // delete pGuiGetUserDefinedTagInfo; } void tag :: clearUserDefinedFields() { if ( pArrayOfUserDefinedTagFields_ ) pArrayOfUserDefinedTagFields_->clear(); } int tag :: nGetUnpaddedStart() { return( pGetContig()->nUnpaddedIndex( nPaddedConsPosStart_ ) ); } int tag :: nGetUnpaddedEnd() { return( pGetContig()->nUnpaddedIndex( nPaddedConsPosEnd_ ) ); } void tag :: dealWithPointerFields( RWCString& soErrorMessage ) { if ( !pArrayOfUserDefinedTagFields_ ) return; for( int nTagField = 0; nTagField < pArrayOfUserDefinedTagFields_->length(); ++nTagField ) { userDefinedTagField* pUserDefinedTagField = (*pArrayOfUserDefinedTagFields_)[ nTagField ]; if ( pUserDefinedTagField->eWhatType() == userDefinedTagFieldType::ePointer ) { ((userDefinedPointerTagField*)pUserDefinedTagField)->resolvePointer( this, soErrorMessage ); } } } RWCString tag :: soGetBasicInformation() { RWCString soTagInfo = soType_ + " " + pContig_->soGetName() + RWCString( (long) pContig_->nUnpaddedIndex( nPaddedConsPosStart_ ) ) + "-" + RWCString( (long) pContig_->nUnpaddedIndex( nPaddedConsPosEnd_ ) ) + " "; if (bReadTagNotConsensusTag_ ) { soTagInfo += "on read "; soTagInfo += pLocFrag_->soGetName(); } else { soTagInfo += "on consensus"; } soTagInfo += " source: "; soTagInfo += soSource_; soTagInfo += " date: "; soTagInfo += soDate_; return( soTagInfo ); } gotoItem* tag :: pGetGotoItemForThisTag() { int nConsPosStart = nPaddedConsPosStart_; int nConsPosEnd = nPaddedConsPosEnd_; int nUnpaddedConsPosStart = pContig_->nUnpaddedIndex( nConsPosStart ); int nUnpaddedConsPosEnd = pContig_->nUnpaddedIndex( nConsPosEnd ); const int nMaxLengthForDescription = 50; RWCString soDescription = soGetExtraInformationForNavigator( nMaxLengthForDescription ); gotoItem* pGotoItem = new gotoItem( pContig_, pLocFrag_, nConsPosStart, nConsPosEnd, nUnpaddedConsPosStart, nUnpaddedConsPosEnd, soDescription ); return pGotoItem; }