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;
GLuint path_index = 0;
GLuint pair_key_0 = 0;
GLuint pair_key_1 = 0;
+ TrackRegion track;
selected_paths.clear();
selected_tracks.clear();
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 << " ";
glFlush();
glPopMatrix();
hits = glRenderMode(GL_RENDER);
- processSelection(hits, selectBuf, select_buf_size);
+ processSelection(hits, selectBuf, select_buf_size, selectedRegion);
}
float GlSeqBrowser::border() 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()) {
//! zoom in to a reasonable sequence view
double zoomToSequence();
//! set the current zoom level in (base pairs / pix )
- /*! its a double as zoom levels of [0.01, 1.0] make nice sequence views
- */
+ //! its a double as zoom levels of [0.01, 1.0] make nice sequence views
void setZoom(double zoom_level);
//! returns the current zoom level as basepairs per pixel
double zoom() const;
+ //! center the provided path in the current viewport
+ void centerOnPath(const std::vector<int>&);
void setColorMapper(AnnotationColors& cm);
AnnotationColors& colorMapper();
void link(const std::vector<int>& path, const std::vector<bool>& isRC, int length);
//! returns the index of pathids based on order added by link
const std::set<int>& selectedPaths() const;
- //! center the provided path in the current viewport
- void centerOnPath(const std::vector<int>&);
-
+ //! define our function for formating sequence copy
+ typedef std::string format_track(const Sequence& s, int left, int right);
+ //! copy sequence from selected track using formating function
+ void copySelectedTracks(std::string& copy_buffer, format_track func);
+ //! copy sequence from selected tracks as plain sequences
+ void copySelectedTracksAsString(std::string& copy_buffer);
+ //! copy sequence from selected tracks as FASTA sequences
+ void copySelectedTracksAsFasta(std::string& copy_buffer);
+
+
//! Provide a logical name for a type discriminator for our glName stack
enum FeatureType { MussaTrack, MussaSegment };
typedef std::map<segment_key, Segment> pair_segment_map;
typedef std::vector<pair_segment_map> path_segment_map_vector;
path_segment_map_vector path_segments;
+
+ struct TrackRegion
+ {
+ GLuint track_id;
+ int left;
+ int right;
+
+ TrackRegion():track_id(0), left(0), right(0) {};
+ TrackRegion(const TrackRegion& o)
+ : track_id(o.track_id), left(o.left), right(o.right) {}
+ TrackRegion(GLuint id, int l, int r)
+ : track_id(id), left(l), right(r) {}
+ void set(GLuint id, int l, int r) { track_id = id; left=l; right=r; };
+ };
+
private:
//! recalculate the viewable world
/*! depending on the size of our canvas, our zoom level and
void update_layout();
//! convert opengl selections into the list of paths we should highlight
- void processSelection(GLuint hits, GLuint buffer[], GLuint bufsize);
+ void processSelection(GLuint hits,
+ GLuint buffer[],
+ GLuint bufsize,
+ const rect<float>& r);
//! master scene drawing function
/*! draw is broken out for the opengl selection code
int pathid;
protected:
- //! where to draw our box
+ //! where to draw our box (world coordinates)
rect<float> selectedRegion;
//! true if we have a selection
bool selectedMode;
//! indicate which paths are selected
std::set<int> selected_paths;
//! which track is selected (it only makes sense to have one track selected).
- std::set<int> selected_tracks;
-
+ std::list<TrackRegion> selected_tracks;
+ typedef std::list<TrackRegion>::iterator selected_track_iterator;
};
#endif
std::string
-Sequence::subseq(int start, int end) const
+Sequence::subseq(int start, int count) const
{
- return sequence.substr(start, end);
+ return sequence.substr(start, count);
}
void set_seq(const std::string& a_seq);
const std::string& get_seq() const;
const char *c_seq() const;
- std::string subseq(int start, int end) const;
+ std::string subseq(int start, int count) const;
std::string rev_comp() const;
// string-like functions
Sequence s;
s.load_fasta(seq_path);
BOOST_CHECK_EQUAL(s.subseq(0, 5), "GGATC"); // first few chars of fasta file
+ BOOST_CHECK_EQUAL(s.subseq(2, 3), "ATC");
BOOST_CHECK_EQUAL(s.get_header(), "gi|180579|gb|M21487.1|HUMCKMM1 Human "
"muscle creatine kinase gene (CKMM), "
"5' flank");
threshold(),
progress_dialog(0),
aboutAction(0),
+ copySelectedSequenceAsFastaAction(0),
closeAction(0),
createNewAnalysisAction(0),
createSubAnalysisAction(0),
if (progress_dialog != 0) delete progress_dialog;
if (aboutAction != 0) delete aboutAction;
+ if (copySelectedSequenceAsFastaAction != 0)
+ delete copySelectedSequenceAsFastaAction;
if (closeAction != 0) delete closeAction;
if (createNewAnalysisAction != 0) delete createNewAnalysisAction;
if (createSubAnalysisAction != 0) delete createSubAnalysisAction;
connect(aboutAction, SIGNAL(triggered()), this, SLOT(about()));
aboutAction->setIcon(QIcon(":/icons/info.png"));
+ // copy sequence
+ copySelectedSequenceAsFastaAction = new QAction(tr("&Copy As Fasta"), this);
+ connect(copySelectedSequenceAsFastaAction, SIGNAL(triggered()),
+ &browser, SLOT(copySelectedSequenceAsFasta()));
+
// add exit
closeAction = new QAction(tr("&Close"), this);
closeAction->setStatusTip(tr("Close this window"));
newMenu->addSeparator();
newMenu->addAction(closeAction);
+ newMenu = menuBar()->addMenu(tr("&Edit"));
+ newMenu->addAction(copySelectedSequenceAsFastaAction);
+
newMenu = menuBar()->addMenu(tr("&View"));
newMenu->addAction(editMotifsAction);
newMenu->addAction(viewMussaAlignmentAction);
QProgressDialog *progress_dialog;
QAction *aboutAction;
+ QAction *copySelectedSequenceAsFastaAction;
QAction *closeAction;
QAction *createNewAnalysisAction;
QAction *createSubAnalysisAction;
return scrollable_browser.browser().sequences();
}
+void SequenceBrowserWidget::copySelectedSequenceAsFasta()
+{
+ std::string buffer;
+ scrollable_browser.browser().copySelectedTracksAsFasta(buffer);
+}
+
void SequenceBrowserWidget::clear_links()
{
scrollable_browser.browser().clear_links();
void centerOnPath(const std::vector<int>& paths);
public slots:
+ //! copy selected sequence
+ void copySelectedSequenceAsFasta();
+
//! set the zoom level of our browser
void setZoom(double);
//! zoom to fit the whole scene on the screen