+void GlSeqBrowser::appendSelectedTrack(GLuint track, int start, int stop)
+{
+ selected_tracks.push_back(TrackRegion(track, start, stop));
+}
+
+list<TrackRegion> GlSeqBrowser::selectedTracks() const
+{
+ return selected_tracks;
+}
+
+//! copy sequence from selected track using formating function
+template<class Item>
+size_t GlSeqBrowser::copySelectedTracks(std::list<Item>& result,
+ Item (*formatter)(boost::shared_ptr<Sequence> s,
+ int left,
+ int right))
+{
+ size_t base_pairs_copied = 0;
+ result.clear();
+
+ for(selected_track_iterator track_i = selected_tracks.begin();
+ track_i != selected_tracks.end();
+ ++track_i)
+ {
+ int track_index = track_i->track_id;
+ if (track_index >= track_container.size()) {
+ // should this be an exception instead?
+ clog << "track " << track_index << " > " << track_container.size()
+ << endl;
+ } else {
+ // we should be safe
+ boost::shared_ptr<Sequence> seq = track_container[track_index]->sequence();
+ result.push_back(formatter(seq, track_i->left, track_i->right));
+ base_pairs_copied += max(track_i->right-track_i->left, 0);
+ }
+ }
+ return base_pairs_copied;
+}
+
+//! copy sequence from selected tracks as FASTA sequences
+size_t GlSeqBrowser::copySelectedTracksAsFasta(std::string& copy_buffer)
+{
+ std::list<std::string> result;
+ struct AsFasta {
+ static string formatter(boost::shared_ptr<Sequence> seq,
+ int left,
+ int right)
+ {
+ stringstream s;
+ s << ">" << seq->get_fasta_header()
+ << "|" << "subregion=" << left << "-" << right+1
+ << std::endl
+ << seq->subseq(left, right-left+1) << std::endl;
+ return s.str();
+ }
+ };
+ size_t base_pairs_copied = copySelectedTracks(result, AsFasta::formatter);
+ // I wish there was some way to use for_each and bind here
+ for (list<string>::iterator result_i = result.begin();
+ result_i != result.end();
+ ++result_i)
+ {
+ copy_buffer.append(*result_i);
+ }
+ return base_pairs_copied;
+}
+
+//! copy sequence from selected tracks as new sequences
+size_t GlSeqBrowser::copySelectedTracksAsSequences(std::list<Sequence>& result)
+{
+ struct AsSequence {
+ static Sequence formatter(boost::shared_ptr<Sequence> seq,
+ int left,
+ int right)
+ {
+ return seq->subseq(left, right-left+1);
+ }
+ };
+ return copySelectedTracks(result, AsSequence::formatter);
+}
+
+size_t GlSeqBrowser::copySelectedTracksAsSeqLocation(
+ std::list<SequenceLocation>& result)
+{
+ struct AsSeqLocation {
+ static SequenceLocation formatter(boost::shared_ptr<Sequence> seq,
+ int left,
+ int right)
+ {
+ return SequenceLocation(seq, left, right);
+ }
+ };
+ return copySelectedTracks(result, AsSeqLocation::formatter);
+}
+
+//! copy sequence from selected tracks as plain sequences
+size_t GlSeqBrowser::copySelectedTracksAsString(std::string& copy_buffer)
+{
+ std::list<string> result;
+ struct AsString {
+ static string formatter(boost::shared_ptr<Sequence> seq,
+ int left,
+ int right)
+ {
+ stringstream s;
+ s << seq->subseq(left, right-left+1);
+ return s.str();
+ }
+ };
+
+ size_t base_pairs_copied = copySelectedTracks(result, AsString::formatter);
+ // I wish there was some way to use for_each and bind here
+ for (list<string>::iterator result_i = result.begin();
+ result_i != result.end();
+ ++result_i)
+ {
+ copy_buffer.append(*result_i);
+ }
+ return base_pairs_copied;
+}
+