From 0d33ab74be4f0dd5a712f09f50a335ef8e19f767 Mon Sep 17 00:00:00 2001 From: Diane Trout Date: Wed, 23 Aug 2006 01:40:40 +0000 Subject: [PATCH] Allow changing the name for a sequence in the sequence browser. Doing this required being much more thorough about always using boost::shared_ptr<>s for GlSequences and Sequences. When you initalize a shared pointer from something that wasn't specially allocated for it using new, bad things happen. This is more of me learning that if one has a temptation to store a reference don't. Instead use a shared_ptr or similar. --- alg/glseqbrowser.cpp | 92 +++++++++++-------- alg/glseqbrowser.hpp | 10 +- alg/glsequence.cpp | 4 +- alg/glsequence.hpp | 2 +- alg/test/test_glseqbrowser.cpp | 8 +- alg/test/test_glsequence.cpp | 6 +- py/glsequence.cpp | 3 +- qui/MussaWindow.cpp | 28 ------ qui/MussaWindow.hpp | 1 - qui/SubanalysisWindow.cpp | 2 + qui/seqbrowser/SequenceBrowser.cpp | 4 +- qui/seqbrowser/SequenceBrowser.hpp | 6 +- qui/seqbrowser/SequenceBrowserSidebar.cpp | 11 ++- qui/seqbrowser/SequenceBrowserSidebar.hpp | 4 +- qui/seqbrowser/SequenceBrowserWidget.cpp | 32 +++++-- qui/seqbrowser/SequenceBrowserWidget.hpp | 6 +- qui/seqbrowser/SequenceDescription.cpp | 107 ++++++++++++++++------ qui/seqbrowser/SequenceDescription.hpp | 29 ++++-- qui/test/CMakeLists.txt | 1 + qui/test/TestSequenceBrowser.cpp | 9 +- qui/test/TestSequenceDescription.cpp | 49 ++++++++++ 21 files changed, 270 insertions(+), 144 deletions(-) create mode 100644 qui/test/TestSequenceDescription.cpp diff --git a/alg/glseqbrowser.cpp b/alg/glseqbrowser.cpp index 470c7c4..254b845 100644 --- a/alg/glseqbrowser.cpp +++ b/alg/glseqbrowser.cpp @@ -117,8 +117,8 @@ void GlSeqBrowser::processSelection(GLuint hits, GLuint buffer[], GLuint bufsize { objid = *ptr++; ++consumed_names; - int left = track_container[objid].leftbase(r.left); - int right = track_container[objid].rightbase(r.right); + int left = track_container[objid]->leftbase(r.left); + int right = track_container[objid]->rightbase(r.right); // the static_cast should be ok, since basepairs line up on // integral values //TrackRegion track(objid, left, right); @@ -193,12 +193,12 @@ float GlSeqBrowser::left() const { return cur_ortho.left; } else { - vector::const_iterator track_i = track_container.begin(); - left = track_i->x(); + vector >::const_iterator track_i = track_container.begin(); + left = (*track_i)->x(); for( ; track_i != track_container.end(); ++track_i) { - if (track_i->x() < left) { - left = track_i->x(); + if ((*track_i)->x() < left) { + left = (*track_i)->x(); } } return left-border_width; @@ -211,11 +211,11 @@ float GlSeqBrowser::right() const if (track_container.size() == 0) { return cur_ortho.right; } else { - vector::const_iterator track_i = track_container.begin(); - right = track_i->right(); + vector >::const_iterator track_i = track_container.begin(); + right = (*track_i)->right(); for( ; track_i != track_container.end(); ++track_i) { - if (track_i->right() > right) - right = track_i->right(); + if ((*track_i)->right() > right) + right = (*track_i)->right(); } return right+border_width; } @@ -321,11 +321,17 @@ void GlSeqBrowser::push_sequence(const Sequence& s) void GlSeqBrowser::push_sequence(boost::shared_ptr s) { - GlSequence gs(s, color_mapper); + boost::shared_ptr gs(new GlSequence(s, color_mapper)); push_sequence(gs); } void GlSeqBrowser::push_sequence(GlSequence gs) +{ + boost::shared_ptr new_gs(new GlSequence(gs)); + push_sequence(new_gs); +} + +void GlSeqBrowser::push_sequence(boost::shared_ptr gs) { clear_links(); track_container.push_back(gs); @@ -334,7 +340,7 @@ void GlSeqBrowser::push_sequence(GlSequence gs) path_segments.push_back(pair_segment_map()); } -const std::vector& GlSeqBrowser::sequences() const +const std::vector >& GlSeqBrowser::sequences() const { return track_container; } @@ -376,10 +382,10 @@ GlSeqBrowser::link(const vector& path, const vector& rc, int ) pair_segment_map::iterator found_segment = path_segments[track_i].find(p); if (found_segment == path_segments[track_i].end()) { // not already found - float y1 = track_container[track_i].y(); - y1 -= track_container[track_i].height()/2; - float y2 = track_container[track_i+1].y(); - y2 += track_container[track_i+1].height()/2; + float y1 = track_container[track_i]->y(); + y1 -= track_container[track_i]->height()/2; + float y2 = track_container[track_i+1]->y(); + y2 += track_container[track_i+1]->height()/2; bool rcFlag = (prev_rc or *rc_i) and !(prev_rc and *rc_i); Segment s(prev_x, y1, *path_i, y2, rcFlag); @@ -428,7 +434,9 @@ list GlSeqBrowser::selectedTracks() const //! copy sequence from selected track using formating function template void GlSeqBrowser::copySelectedTracks(std::list& result, - Item (*formatter)(const Sequence& s, int left, int right)) + Item (*formatter)(boost::shared_ptr s, + int left, + int right)) { result.clear(); @@ -443,7 +451,7 @@ void GlSeqBrowser::copySelectedTracks(std::list& result, << endl; } else { // we should be safe - const Sequence& seq = track_container[track_index].sequence(); + boost::shared_ptr seq = track_container[track_index]->sequence(); result.push_back(formatter(seq, track_i->left, track_i->right)); } } @@ -454,13 +462,15 @@ void GlSeqBrowser::copySelectedTracksAsFasta(std::string& copy_buffer) { std::list result; struct AsFasta { - static string formatter(const Sequence& seq, int left, int right) + static string formatter(boost::shared_ptr seq, + int left, + int right) { stringstream s; - s << ">" << seq.get_fasta_header() + s << ">" << seq->get_fasta_header() << "|" << "subregion=" << left << "-" << right+1 << std::endl - << seq.subseq(left, right-left+1) << std::endl; + << seq->subseq(left, right-left+1) << std::endl; return s.str(); } }; @@ -478,9 +488,11 @@ void GlSeqBrowser::copySelectedTracksAsFasta(std::string& copy_buffer) void GlSeqBrowser::copySelectedTracksAsSequences(std::list& result) { struct AsSequence { - static Sequence formatter(const Sequence& seq, int left, int right) + static Sequence formatter(boost::shared_ptr seq, + int left, + int right) { - return seq.subseq(left, right-left+1); + return seq->subseq(left, right-left+1); } }; copySelectedTracks(result, AsSequence::formatter); @@ -490,7 +502,9 @@ void GlSeqBrowser::copySelectedTracksAsSeqLocation( std::list& result) { struct AsSeqLocation { - static SequenceLocation formatter(const Sequence& seq, int left, int right) + static SequenceLocation formatter(boost::shared_ptr seq, + int left, + int right) { return SequenceLocation(seq, left, right); } @@ -503,10 +517,12 @@ void GlSeqBrowser::copySelectedTracksAsString(std::string& copy_buffer) { std::list result; struct AsString { - static string formatter(const Sequence& seq, int left, int right) + static string formatter(boost::shared_ptr seq, + int left, + int right) { stringstream s; - s << seq.subseq(left, right-left+1) << std::endl; + s << seq->subseq(left, right-left+1) << std::endl; return s.str(); } }; @@ -531,7 +547,7 @@ void GlSeqBrowser::centerOnPath(const vector& paths) for(size_t track_i = 0; track_i != track_container.size(); ++track_i) { // -15 = shift more to the left - track_container[track_i].setX((viewport_center-15) - paths[track_i]); + track_container[track_i]->setX((viewport_center-15) - paths[track_i]); } } @@ -548,7 +564,7 @@ void GlSeqBrowser::update_viewport(float center, double new_zoom) void GlSeqBrowser::update_layout() { - typedef std::vector::iterator glseq_itor_type; + typedef std::vector >::iterator glseq_itor_type; float available_height = (float)cur_ortho.top - 2 * (float)border_width; float max_base_pairs = 0; size_t track_count = track_container.size(); @@ -561,17 +577,17 @@ void GlSeqBrowser::update_layout() seq_i != track_container.end(); ++seq_i, y-=track_spacing) { - seq_i->setX(0); - seq_i->setY(y); - if (seq_i->size() > max_base_pairs) - max_base_pairs = seq_i->size(); + (*seq_i)->setX(0); + (*seq_i)->setY(y); + if ((*seq_i)->size() > max_base_pairs) + max_base_pairs = (*seq_i)->size(); } } else if (track_count == 1) { // center the single track glseq_itor_type seq_i = track_container.begin(); - seq_i->setX(0); - seq_i->setY(viewport_size.x /2); - max_base_pairs = seq_i->size(); + (*seq_i)->setX(0); + (*seq_i)->setY(viewport_size.x /2); + max_base_pairs = (*seq_i)->size(); } else { // nothing to do as we're empty return; @@ -616,7 +632,7 @@ void GlSeqBrowser::draw_tracks() const for(size_t track_i = 0; track_i != track_container.size(); ++track_i) { glPushName(track_i); - track_container[track_i].draw(cur_ortho.left, cur_ortho.right); + track_container[track_i]->draw(cur_ortho.left, cur_ortho.right); glPopName(); } } @@ -675,8 +691,8 @@ void GlSeqBrowser::draw_segments() const // save the multipart name for our segment glPushName(path_index); glPushName(key.first); glPushName(key.second); glBegin(GL_LINES); - float seq_start_x = track_container[path_index].x(); - float seq_end_x = track_container[path_index+1].x(); + float seq_start_x = track_container[path_index]->x(); + float seq_end_x = track_container[path_index+1]->x(); glVertex3f(s.start.x + seq_start_x, s.start.y, -1); glVertex3f(s.end.x + seq_end_x , s.end.y, -1); glEnd(); diff --git a/alg/glseqbrowser.hpp b/alg/glseqbrowser.hpp index b5be3a6..ba33704 100644 --- a/alg/glseqbrowser.hpp +++ b/alg/glseqbrowser.hpp @@ -75,8 +75,10 @@ public: void push_sequence(boost::shared_ptr s); //! add a glsequence to the back of our track container void push_sequence(GlSequence s); + //! add a glsequence to the back of our track container + void push_sequence(boost::shared_ptr gs); //! return our track container - const std::vector& sequences() const; + const std::vector >& sequences() const; //! clear all the line segments between all the sequences void clear_links(); @@ -96,7 +98,9 @@ public: //! copy sequence from selected track using formating function template void copySelectedTracks(std::list& result, - Item (*format_track)(const Sequence& s, int left, int right)); + Item (*format_track)(boost::shared_ptr s, + int left, + int right)); //! copy sequence from selected tracks as FASTA sequences void copySelectedTracksAsFasta(std::string& copy_buffer); //! copy sequence from selected tracks as a list of sequences @@ -193,7 +197,7 @@ private: double zoom_level; boost::shared_ptr color_mapper; //! container of all the GlSequences loaded into our scene - std::vector track_container; + std::vector > track_container; //! counter for each path added to us via connect int pathid; diff --git a/alg/glsequence.cpp b/alg/glsequence.cpp index de262d4..60e14e9 100644 --- a/alg/glsequence.cpp +++ b/alg/glsequence.cpp @@ -46,9 +46,9 @@ GlSequence &GlSequence::operator=(const GlSequence & s) return *this; } -const Sequence& GlSequence::sequence() const +boost::shared_ptr GlSequence::sequence() { - return *seq; + return seq; } void GlSequence::setX(GLfloat value) diff --git a/alg/glsequence.hpp b/alg/glsequence.hpp index 31e282e..ab96239 100644 --- a/alg/glsequence.hpp +++ b/alg/glsequence.hpp @@ -30,7 +30,7 @@ public: */ void draw(GLfloat left, GLfloat right) const; - const Sequence& sequence() const; + boost::shared_ptr sequence(); //! set our starting x (horizontal) coordinate void setX(GLfloat); //! get our starting x (horizontal) coordinate diff --git a/alg/test/test_glseqbrowser.cpp b/alg/test/test_glseqbrowser.cpp index ad183f0..9e23d28 100644 --- a/alg/test/test_glseqbrowser.cpp +++ b/alg/test/test_glseqbrowser.cpp @@ -80,11 +80,11 @@ BOOST_AUTO_TEST_CASE( glseqbrowser_center ) BOOST_CHECK_EQUAL( gt.right(), s0.size() + gt.border()-11 ); // aparently we end up with a different glsequence in the seqbrowser - BOOST_CHECK( glseq1.x() != gt.sequences()[1].x() ); + BOOST_CHECK( glseq1.x() != gt.sequences()[1]->x() ); - BOOST_CHECK_EQUAL( gt.sequences()[0].x(), (gt.viewportCenter()-15)-path[0] ); - BOOST_CHECK_EQUAL( gt.sequences()[1].x(), (gt.viewportCenter()-15)-path[1] ); - BOOST_CHECK_EQUAL( gt.sequences()[2].x(), (gt.viewportCenter()-15)-path[2] ); + BOOST_CHECK_EQUAL( gt.sequences()[0]->x(), (gt.viewportCenter()-15)-path[0] ); + BOOST_CHECK_EQUAL( gt.sequences()[1]->x(), (gt.viewportCenter()-15)-path[1] ); + BOOST_CHECK_EQUAL( gt.sequences()[2]->x(), (gt.viewportCenter()-15)-path[2] ); } BOOST_AUTO_TEST_CASE( setSelectedPaths ) diff --git a/alg/test/test_glsequence.cpp b/alg/test/test_glsequence.cpp index b0aa6ad..f0bf301 100644 --- a/alg/test/test_glsequence.cpp +++ b/alg/test/test_glsequence.cpp @@ -20,15 +20,15 @@ BOOST_AUTO_TEST_CASE ( glsequence_operator_assignment ) boost::shared_ptr seq1(new Sequence(s1)); GlSequence glseq0(seq0, cm); - BOOST_CHECK (glseq0.sequence() == s0); + BOOST_CHECK (*glseq0.sequence() == s0); GlSequence glseq1(seq1, cm); GlSequence glseq_copy0(glseq0); BOOST_CHECK(glseq_copy0.sequence() == glseq0.sequence()); - BOOST_CHECK( &(glseq_copy0.sequence()) == &(glseq0.sequence())); + BOOST_CHECK( glseq_copy0.sequence() == glseq0.sequence()); glseq0 = glseq1; - BOOST_CHECK( glseq0.sequence() == s1 ); + BOOST_CHECK( *glseq0.sequence() == s1 ); } BOOST_AUTO_TEST_CASE( glsequence_color ) diff --git a/py/glsequence.cpp b/py/glsequence.cpp index ea456eb..c901494 100644 --- a/py/glsequence.cpp +++ b/py/glsequence.cpp @@ -15,8 +15,7 @@ void export_glsequence() >()) .def(init()) .def("draw", &GlSequence::draw) - .def("sequence", &GlSequence::sequence, - return_internal_reference<>()) + .def("sequence", &GlSequence::sequence ) .add_property("x", &GlSequence::x, &GlSequence::setX) .add_property("y", &GlSequence::y, &GlSequence::setY) .add_property("size", &GlSequence::size) diff --git a/qui/MussaWindow.cpp b/qui/MussaWindow.cpp index 1587e47..6759567 100644 --- a/qui/MussaWindow.cpp +++ b/qui/MussaWindow.cpp @@ -92,34 +92,6 @@ MussaWindow::MussaWindow(Mussa *analysis_, QWidget *parent) : updateAnalysis(); } -MussaWindow::~MussaWindow() -{ - if (analysis != 0) delete analysis; - aligned_windows.clear(); - if (motif_editor != 0) delete motif_editor; - if (progress_dialog != 0) delete progress_dialog; - - if (aboutAction != 0) delete aboutAction; - if (closeAction != 0) delete closeAction; - if (createNewAnalysisAction != 0) delete createNewAnalysisAction; - if (createSubAnalysisAction != 0) delete createSubAnalysisAction; - if (editMotifsAction != 0) delete editMotifsAction; - if (loadMotifListAction != 0) delete loadMotifListAction; - if (loadMupaAction != 0) delete loadMupaAction; - if (loadSavedAnalysisAction != 0) delete loadSavedAnalysisAction; - if (mussaManualAssistantAction != 0) delete mussaManualAssistantAction; - if (newMussaWindowAction != 0) delete newMussaWindowAction; - if (saveBrowserPixmapAction != 0) delete saveBrowserPixmapAction; - if (saveMotifListAction != 0) delete saveMotifListAction; - if (showMussaViewToolbarAction != 0) delete showMussaViewToolbarAction; - if (toggleMotifsAction != 0) delete toggleMotifsAction; - if (whatsThisAction != 0) delete whatsThisAction; - if (viewMussaAlignmentAction != 0) delete viewMussaAlignmentAction; - - if (manualAssistant != 0) delete manualAssistant; - -} - void MussaWindow::setAnalysis(Mussa *new_analysis) { if (new_analysis != 0) { diff --git a/qui/MussaWindow.hpp b/qui/MussaWindow.hpp index 0e15a55..30900c8 100644 --- a/qui/MussaWindow.hpp +++ b/qui/MussaWindow.hpp @@ -31,7 +31,6 @@ class MussaWindow : public QMainWindow public: MussaWindow(Mussa* analysis=0, QWidget *parent=0); - ~MussaWindow(); //! reset any attached window void clear(); diff --git a/qui/SubanalysisWindow.cpp b/qui/SubanalysisWindow.cpp index 5ac41ac..5fdafcd 100644 --- a/qui/SubanalysisWindow.cpp +++ b/qui/SubanalysisWindow.cpp @@ -86,6 +86,8 @@ void SubanalysisWindow::run() itor != model.end(); ++itor) { + // append_sequence from a const Sequence & will make a copy + // for the shared pointer. m->append_sequence(itor->getSelectedSequence()); } diff --git a/qui/seqbrowser/SequenceBrowser.cpp b/qui/seqbrowser/SequenceBrowser.cpp index 116d58c..3d31f7f 100644 --- a/qui/seqbrowser/SequenceBrowser.cpp +++ b/qui/seqbrowser/SequenceBrowser.cpp @@ -108,13 +108,13 @@ void SequenceBrowser::displayContextMenu(const QPoint& point) popupMenu.popup(point); } -void SequenceBrowser::push_sequence(const Sequence &s) +void SequenceBrowser::push_sequence(boost::shared_ptr s) { GlSeqBrowser::push_sequence(s); emit tracksChanged(); } -void SequenceBrowser::push_sequence(GlSequence &gs) +void SequenceBrowser::push_sequence(boost::shared_ptr gs) { GlSeqBrowser::push_sequence(gs); emit tracksChanged(); diff --git a/qui/seqbrowser/SequenceBrowser.hpp b/qui/seqbrowser/SequenceBrowser.hpp index 43e817c..7ada612 100644 --- a/qui/seqbrowser/SequenceBrowser.hpp +++ b/qui/seqbrowser/SequenceBrowser.hpp @@ -10,6 +10,8 @@ #include #include +#include + #include "alg/mussa.hpp" #include "alg/glsequence.hpp" #include "alg/glseqbrowser.hpp" @@ -28,8 +30,8 @@ public: QSize sizeHint() const; void clear(); - void push_sequence(const Sequence &s); - void push_sequence(GlSequence &); + void push_sequence(boost::shared_ptr s); + void push_sequence(boost::shared_ptr); //! return the popup menu for the glcanvas (reference stored internally) QMenu &getPopupMenu(); diff --git a/qui/seqbrowser/SequenceBrowserSidebar.cpp b/qui/seqbrowser/SequenceBrowserSidebar.cpp index f63a500..b695f24 100644 --- a/qui/seqbrowser/SequenceBrowserSidebar.cpp +++ b/qui/seqbrowser/SequenceBrowserSidebar.cpp @@ -20,16 +20,18 @@ void SequenceBrowserSidebar::clear() descriptions.clear(); } -void SequenceBrowserSidebar::setSequences(vector& sequences) +void SequenceBrowserSidebar::setSequences( + vector > sequences +) { + typedef vector > vector_shared_glsequences; clear(); - for (vector::const_iterator track_i = sequences.begin(); + for (vector_shared_glsequences::iterator track_i = sequences.begin(); track_i != sequences.end(); ++track_i) { SequenceDescription *desc = new SequenceDescription(this); - desc->setName(track_i->sequence().get_species()); - desc->setLength(track_i->sequence().length()); + desc->setGlSequence(*track_i); descriptions.push_back(desc); layout.addWidget(desc); if ((track_i+1) != sequences.end()) { @@ -38,3 +40,4 @@ void SequenceBrowserSidebar::setSequences(vector& sequences) } setLayout(&layout); } + diff --git a/qui/seqbrowser/SequenceBrowserSidebar.hpp b/qui/seqbrowser/SequenceBrowserSidebar.hpp index 48bc78e..4c599de 100644 --- a/qui/seqbrowser/SequenceBrowserSidebar.hpp +++ b/qui/seqbrowser/SequenceBrowserSidebar.hpp @@ -3,6 +3,8 @@ #include +#include + #include #include #include "qui/seqbrowser/SequenceBrowser.hpp" @@ -21,7 +23,7 @@ public: //! clear our list of descriptions void clear(); - void setSequences(std::vector& ); + void setSequences(std::vector > ); std::vector descriptions; public slots: diff --git a/qui/seqbrowser/SequenceBrowserWidget.cpp b/qui/seqbrowser/SequenceBrowserWidget.cpp index 0f396f2..ef3db33 100644 --- a/qui/seqbrowser/SequenceBrowserWidget.cpp +++ b/qui/seqbrowser/SequenceBrowserWidget.cpp @@ -65,7 +65,7 @@ void SequenceBrowserWidget::copySelectedTracksAsSeqLocation( } void SequenceBrowserWidget::setSequences( - const std::vector< boost::shared_ptr >& sequences, + const std::vector >& sequences, boost::shared_ptr cm) { SequenceBrowser& browser = scrollable_browser.browser(); @@ -75,19 +75,33 @@ void SequenceBrowserWidget::setSequences( ++seq_i) { boost::shared_ptr gs(new GlSequence(*seq_i, cm)); - converted_sequences.push_back(*gs); - browser.push_sequence(*gs); + converted_sequences.push_back(gs); + browser.push_sequence(gs); } left_sidebar.setSequences(converted_sequences); right_sidebar.setSequences(converted_sequences); + + // connect the text change signals to each other + vector left = left_sidebar.descriptions; + vector right = right_sidebar.descriptions; + for(size_t i = 0; i != sequences.size() and i != right.size(); ++i) + { + connect(left[i], SIGNAL(nameChanged(const QString &)), + right[i], SLOT(setName(const QString &))); + connect(right[i], SIGNAL(nameChanged(const QString &)), + left[i], SLOT(setName(const QString &))); + } + updatePosition(); } -void SequenceBrowserWidget::setSequences(std::vector& sequences) +void SequenceBrowserWidget::setSequences( + std::vector >& sequences +) { SequenceBrowser& browser = scrollable_browser.browser(); clear(); - for(vector::iterator seq_i = sequences.begin(); + for(vector >::iterator seq_i = sequences.begin(); seq_i != sequences.end(); ++seq_i) { @@ -98,7 +112,7 @@ void SequenceBrowserWidget::setSequences(std::vector& sequences) updatePosition(); } -const vector& SequenceBrowserWidget::sequences() const +const vector >& SequenceBrowserWidget::sequences() const { return scrollable_browser.browser().sequences(); } @@ -140,13 +154,13 @@ void SequenceBrowserWidget::centerOnPath(const vector& paths) void SequenceBrowserWidget::updatePosition() { const SequenceBrowser& browser = scrollable_browser.browser(); - const vector &sequences = browser.sequences(); + const vector > &sequences = browser.sequences(); vector left = left_sidebar.descriptions; vector right = right_sidebar.descriptions; for(size_t i = 0; i != sequences.size() and i != right.size(); ++i) { - left[i]->setPosition(sequences[i].leftbase(browser.viewportLeft())); - right[i]->setPosition(sequences[i].rightbase(browser.viewportRight())); + left[i]->setPosition(sequences[i]->leftbase(browser.viewportLeft())); + right[i]->setPosition(sequences[i]->rightbase(browser.viewportRight())); } scrollable_browser.browser().update(); scrollable_browser.updateScrollBar(); diff --git a/qui/seqbrowser/SequenceBrowserWidget.hpp b/qui/seqbrowser/SequenceBrowserWidget.hpp index 6c82f58..332fa1b 100644 --- a/qui/seqbrowser/SequenceBrowserWidget.hpp +++ b/qui/seqbrowser/SequenceBrowserWidget.hpp @@ -42,8 +42,8 @@ public: void setSequences( const std::vector< boost::shared_ptr >& sequences, boost::shared_ptr cm); - void setSequences(std::vector& sequences); - const std::vector& sequences() const; + void setSequences(std::vector >& sequences); + const std::vector >& sequences() const; //! reset just the links we're displaying void clear_links(); @@ -78,6 +78,6 @@ private: //! sequences created by a setSequences(vector) call /*! I need to save them so i can free them to avoid a memory leak */ - std::vector converted_sequences; + std::vector > converted_sequences; }; #endif diff --git a/qui/seqbrowser/SequenceDescription.cpp b/qui/seqbrowser/SequenceDescription.cpp index d01ae5f..80dfa8f 100644 --- a/qui/seqbrowser/SequenceDescription.cpp +++ b/qui/seqbrowser/SequenceDescription.cpp @@ -1,5 +1,4 @@ #include - #include "qui/seqbrowser/SequenceDescription.hpp" using namespace std; @@ -12,15 +11,12 @@ SequenceDescription::SequenceDescription(QWidget *parent) createWidget(); } -SequenceDescription::SequenceDescription(string name, int length, - QWidget *parent) - : QFrame(parent), - pos(-1) // set pos to an invalid value so the setPos function will call - // setText +SequenceDescription::SequenceDescription( + boost::shared_ptr glseq, + QWidget *parent +) : QFrame(parent) { - setName(name); - setLength(length); - createWidget(); + setGlSequence(glseq); } void SequenceDescription::createWidget() @@ -31,38 +27,84 @@ void SequenceDescription::createWidget() layout->addWidget(&name_label); layout->addWidget(&length_label); layout->addWidget(&position_label); + name_label.setMaximumWidth(length_label.fontMetrics().width("01234567")); setLayout(layout); + + connect(&name_label, SIGNAL(textChanged(const QString& )), + this, SLOT(setName(const QString& ))); +} + +void SequenceDescription::setGlSequence( + boost::shared_ptr glseq ) +{ + if (glseq != glsequence_) { + glsequence_ = glseq; + setName(glsequence_->sequence()->get_species()); + setLength(glsequence_->sequence()->length()); + emit glsequenceChanged(glsequence_); + } +} + +boost::shared_ptr SequenceDescription::glsequence() +{ + return glsequence_; } void SequenceDescription::setName(std::string name) { - if (name != name_label.text().toStdString()) { - name_label.setText(name.c_str()); - emit nameChanged(name); + setName(QString(name.c_str())); +} + +void SequenceDescription::setName(const QString& name_) +{ + std::string std_name_ = name_.toStdString(); + + if (std_name_ != glsequence_->sequence()->get_species()) { + glsequence_->sequence()->set_species(std_name_); + emit nameChanged(name_); + } + + // no need to setText again if its because of user editing + if (name_ != name_label.text()) { + name_label.setText(name_); } } -void SequenceDescription::setLength(int length_) +std::string SequenceDescription::name() const +{ + if (glsequence_) + return glsequence_->sequence()->get_species(); + else + return string(""); +} + +void SequenceDescription::setLength(int length) { QString s; - float short_length = length_; - if (length_ != length) { - if (short_length > 1000000) { - short_length /= 1000000; - s.setNum(short_length, 'f', 2); - s += "mb"; - } if (short_length > 1000) { - short_length /= 1000; - s.setNum(short_length, 'f', 2); - s += "kb"; - } else { - s.setNum(short_length); - s += "b"; - } - length_label.setText(s); - length = length_; - emit lengthChanged(length); + float short_length = length; + if (short_length > 1000000) { + short_length /= 1000000; + s.setNum(short_length, 'f', 2); + s += "mb"; + } if (short_length > 1000) { + short_length /= 1000; + s.setNum(short_length, 'f', 2); + s += "kb"; + } else { + s.setNum(short_length); + s += "b"; } + length_label.setText(s); +} + +int SequenceDescription::length() const +{ + return 0; + + if (glsequence_) + return glsequence_->sequence()->size(); + else + return 0; } void SequenceDescription::setPosition(int pos_) @@ -74,3 +116,8 @@ void SequenceDescription::setPosition(int pos_) emit positionChanged(pos); } } + +int SequenceDescription::position() const +{ + return pos; +} diff --git a/qui/seqbrowser/SequenceDescription.hpp b/qui/seqbrowser/SequenceDescription.hpp index ff449ee..929a999 100644 --- a/qui/seqbrowser/SequenceDescription.hpp +++ b/qui/seqbrowser/SequenceDescription.hpp @@ -1,38 +1,53 @@ #ifndef _SEQUENCE_DESCRIPTION_H #define _SEQUENCE_DESCRIPTION_H +#include + #include #include #include +#include #include +#include "alg/glsequence.hpp" + class SequenceDescription : public QFrame { Q_OBJECT public: SequenceDescription(QWidget *parent=0); - SequenceDescription(std::string name, int length, QWidget *parent=0); + SequenceDescription(boost::shared_ptr, QWidget *); + void setName(std::string name); + + boost::shared_ptr glsequence(); + std::string name() const; + int length() const; + int position() const; public slots: - void setName(std::string name); - void setLength(int length); + //! Display the passed GlSequence information + void setGlSequence(boost::shared_ptr); + //! set the name for our sequence + void setName(const QString& name); void setPosition(int pos); signals: - void nameChanged(std::string name); - void lengthChanged(float length); + void glsequenceChanged(boost::shared_ptr); + void nameChanged(const QString& name); void positionChanged(int pos); private: - QLabel name_label; + QLineEdit name_label; QLabel length_label; QLabel position_label; - int length; + boost::shared_ptr glsequence_; int pos; void createWidget(); + //! format the length and set the QLabel + void setLength(int length); }; #endif diff --git a/qui/test/CMakeLists.txt b/qui/test/CMakeLists.txt index feff58e..7e279f2 100644 --- a/qui/test/CMakeLists.txt +++ b/qui/test/CMakeLists.txt @@ -40,4 +40,5 @@ ENDMACRO(MAKE_UNITTEST) MAKE_UNITTEST(TestSequenceLocationModel) MAKE_UNITTEST(TestSequenceBrowser) +MAKE_UNITTEST(TestSequenceDescription) MAKE_UNITTEST(TestColorSharing) diff --git a/qui/test/TestSequenceBrowser.cpp b/qui/test/TestSequenceBrowser.cpp index 6925615..eb09d6a 100644 --- a/qui/test/TestSequenceBrowser.cpp +++ b/qui/test/TestSequenceBrowser.cpp @@ -9,6 +9,7 @@ #include #include +#include using namespace boost::assign; @@ -19,8 +20,8 @@ class TestSequenceBrowser : public QObject private slots: void testSimplePushSequence() { - Sequence seq1("AAGGCCTT"); - Sequence seq2("GGCCTTAA"); + boost::shared_ptr seq1(new Sequence("AAGGCCTT")); + boost::shared_ptr seq2(new Sequence("GGCCTTAA")); SequenceBrowser browser; QVERIFY(browser.sequences().size() == 0); @@ -32,8 +33,8 @@ private slots: } void testSelect() { - Sequence seq1("AAGGCCTT"); - Sequence seq2("GGCCTTAA"); + boost::shared_ptr seq1(new Sequence("AAGGCCTT")); + boost::shared_ptr seq2(new Sequence("GGCCTTAA")); SequenceBrowser browser; browser.push_sequence(seq1); diff --git a/qui/test/TestSequenceDescription.cpp b/qui/test/TestSequenceDescription.cpp new file mode 100644 index 0000000..81be6dc --- /dev/null +++ b/qui/test/TestSequenceDescription.cpp @@ -0,0 +1,49 @@ +#include +#include + +#include "alg/sequence.hpp" +#include "alg/glsequence.hpp" +#include "alg/annotation_colors.hpp" +#include "qui/seqbrowser/SequenceDescription.hpp" + +#include +#include +#include + +class TestSequenceDescription : public QObject +{ + Q_OBJECT + +private slots: + void testSimple() { + boost::shared_ptr seq1(new Sequence("AAGGCCTT")); + seq1->set_species("foo"); + boost::shared_ptr cm(new AnnotationColors); + boost::shared_ptr glseq1(new GlSequence(seq1, cm)); + + SequenceDescription sd(glseq1, 0); + QVERIFY(sd.glsequence() == glseq1); + QVERIFY(sd.glsequence()->sequence()->get_species() == seq1->get_species()); + sd.setName(std::string("bar")); + QVERIFY(sd.glsequence()->sequence()->get_species() == seq1->get_species()); + QVERIFY(seq1->get_species() == "bar"); + } + void testDeletedPointer() { + SequenceDescription sd; + + { + boost::shared_ptr seq1(new Sequence("AAGGCCTT")); + Sequence m("AAGG"); + seq1->find_motif(m); + seq1->set_species("foo"); + boost::shared_ptr cm(new AnnotationColors); + boost::shared_ptr glseq1(new GlSequence(seq1, cm)); + sd.setGlSequence(glseq1); + } + + QVERIFY(sd.name() == "foo"); + } +}; + +QTEST_MAIN(TestSequenceDescription) +#include "moc_TestSequenceDescription.cxx" -- 2.30.2