partial implementation of sequence track copy
[mussa.git] / alg / glseqbrowser.cpp
index f8a7b8c694834905c28ca9e4f634d4429f4581d1..560662b0188e1fb3b1a790e538626e1debd64da4 100644 (file)
@@ -62,7 +62,7 @@ void GlSeqBrowser::paintGL() const
   glFlush();
 }
 
-void GlSeqBrowser::processSelection(GLuint hits, GLuint buffer[], GLuint bufsize)
+void GlSeqBrowser::processSelection(GLuint hits, GLuint buffer[], GLuint bufsize, const rect<float>& r)
 {
   GLuint *ptr;
   GLuint names;
@@ -74,6 +74,7 @@ void GlSeqBrowser::processSelection(GLuint hits, GLuint buffer[], GLuint bufsize
   GLuint path_index = 0;
   GLuint pair_key_0 = 0;
   GLuint pair_key_1 = 0;
+  TrackRegion track;
 
   selected_paths.clear();
   selected_tracks.clear();
@@ -114,7 +115,14 @@ void GlSeqBrowser::processSelection(GLuint hits, GLuint buffer[], GLuint bufsize
           break;
         case MussaTrack:
           objid = *ptr++; ++consumed_names;
-          selected_tracks.insert(objid);
+
+          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); 
+          track.set(objid, left, right);
+          selected_tracks.push_back(track);
         break;
         default:
           cout << "unknown type " << objtype << " ";
@@ -168,7 +176,7 @@ void GlSeqBrowser::selectRegion(int top, int left, int bottom, int right)
   glFlush();
   glPopMatrix();
   hits = glRenderMode(GL_RENDER);
-  processSelection(hits, selectBuf, select_buf_size);
+  processSelection(hits, selectBuf, select_buf_size, selectedRegion);
 }
 
 float GlSeqBrowser::border() const
@@ -377,6 +385,60 @@ const set<int>& GlSeqBrowser::selectedPaths() const
   return selected_paths;
 }
 
+//! copy sequence from selected track using formating function
+void GlSeqBrowser::copySelectedTracks(std::string& copy_buffer, 
+                                      format_track formatter)
+{
+  copy_buffer.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
+      const Sequence& seq = track_container[track_index].sequence();
+      copy_buffer += formatter(seq, track_i->left, track_i->right);
+    }
+  }
+  cout << "copy" << endl << copy_buffer << endl;
+}
+
+//! copy sequence from selected tracks as plain sequences
+void GlSeqBrowser::copySelectedTracksAsString(std::string& copy_buffer)
+{
+  struct AsString {
+    static string formatter(const Sequence& seq, int left, int right)
+    {
+      stringstream s;
+      s << seq.subseq(left, right-left+1) << std::endl;
+      return s.str();
+    }
+  };
+
+  copySelectedTracks(copy_buffer, AsString::formatter);
+}
+
+//! copy sequence from selected tracks as FASTA sequences
+void GlSeqBrowser::copySelectedTracksAsFasta(std::string& copy_buffer)
+{
+  struct AsFasta {
+    static string formatter(const Sequence& seq, int left, int right)
+    {
+      stringstream s;
+      s << ">" << seq.get_header() << std::endl
+        << seq.subseq(left, right-left+1) << std::endl;
+      return s.str();
+    }
+  };
+  copySelectedTracks(copy_buffer, AsFasta::formatter);
+}
+
 void GlSeqBrowser::centerOnPath(const vector<int>& paths)
 {
   if (paths.size() != track_container.size()) {