1 #include <QApplication>
16 #include "qui/seqbrowser/SequenceBrowser.hpp"
17 #include "mussa_exceptions.hpp"
21 SequenceBrowser::SequenceBrowser(QWidget *parent)
25 copySelectedSequenceAsFastaAction(0),
26 copySelectedSequenceAsStringAction(0),
27 editSequencePropertiesAction(0),
28 clearSelectionAction(0)
30 popupMenu = new QMenu(this);
31 copySelectedSequenceAsFastaAction = new QAction(tr("&Copy as Fasta"), this);
32 connect(copySelectedSequenceAsFastaAction, SIGNAL(triggered()),
33 this, SLOT(copySelectedSequenceAsFasta()));
34 popupMenu->addAction(copySelectedSequenceAsFastaAction);
36 copySelectedSequenceAsStringAction = new QAction(tr("&Copy Sequence"), this);
37 copySelectedSequenceAsStringAction->setShortcut(Qt::CTRL | Qt::Key_C);
38 connect(copySelectedSequenceAsStringAction, SIGNAL(triggered()),
39 this, SLOT(copySelectedSequenceAsString()));
40 popupMenu->addAction(copySelectedSequenceAsStringAction);
42 // connect edit properties action
43 editSequencePropertiesAction = new QAction(tr("Sequence &Properties"), this);
44 connect(editSequencePropertiesAction, SIGNAL(triggered()),
45 this, SLOT(editSequenceProperties()));
47 clearSelectionAction = new QAction(tr("Clear Selection"), this);
48 clearSelectionAction->setShortcut(Qt::Key_Escape);
49 connect(clearSelectionAction, SIGNAL(triggered()),
50 this, SLOT(clearSelection()));
51 this->addAction(clearSelectionAction);
55 SequenceBrowser::SequenceBrowser(const SequenceBrowser& sb, QWidget *parent)
58 rubberBand(sb.rubberBand),
59 popupMenu(sb.popupMenu),
60 copySelectedSequenceAsFastaAction(sb.copySelectedSequenceAsFastaAction),
61 copySelectedSequenceAsStringAction(sb.copySelectedSequenceAsStringAction),
62 editSequencePropertiesAction(sb.editSequencePropertiesAction),
63 clearSelectionAction(sb.clearSelectionAction)
65 resize(sb.width(), sb.height());
70 QMenu *SequenceBrowser::getPopupMenu()
75 QAction *SequenceBrowser::getCopySelectedSequenceAsFastaAction()
77 return copySelectedSequenceAsFastaAction;
80 QAction *SequenceBrowser::getCopySelectedSequenceAsStringAction()
82 return copySelectedSequenceAsStringAction;
85 QAction *SequenceBrowser::getEditSequencePropertiesAction()
87 return editSequencePropertiesAction;
90 QSize SequenceBrowser::sizeHint() const
92 return QSize(viewportPixelWidth(), viewportPixelHeight());
95 void SequenceBrowser::setViewportCenter(float x)
97 const float epsilon = 1e-10;
98 float center = GlSeqBrowser::viewportCenter();
99 float difference = fabsf(x - center);
100 float abs_x = fabsf(x);
101 center = fabsf(center);
103 // the difference < epsilon * val is one of the recommended tests
104 // for float equality.
105 // of course since we're looking for not equals, we need to toss a
106 // not at the beginning
107 if (not (difference < epsilon * abs_x or difference < epsilon * center))
109 GlSeqBrowser::setViewportCenter(x);
110 emit viewportChanged();
115 void SequenceBrowser::setZoom(double new_zoom)
117 if (new_zoom != GlSeqBrowser::zoom()) {
118 GlSeqBrowser::setZoom(new_zoom);
119 emit viewportChanged();
124 void SequenceBrowser::setClipPlane(int )
127 if (clipZ != (double) newZ){
128 clipZ = (double) newZ;
134 void SequenceBrowser::copySelectedSequenceAsFasta()
138 size_t base_pairs_copied = copySelectedTracksAsFasta(buffer);
140 // get reference to clipboard
141 QClipboard *clipboard = QApplication::clipboard();
142 clipboard->setText(buffer.c_str());
143 emit basepairsCopied(base_pairs_copied);
146 void SequenceBrowser::copySelectedSequenceAsString()
150 size_t base_pairs_copied = copySelectedTracksAsString(buffer);
152 // get reference to clipboard
153 QClipboard *clipboard = QApplication::clipboard();
154 clipboard->setText(buffer.c_str());
155 emit basepairsCopied(base_pairs_copied);
158 void SequenceBrowser::clear()
160 GlSeqBrowser::clear();
161 emit tracksChanged();
164 void SequenceBrowser::displayContextMenu(const QPoint& point)
166 popupMenu->popup(point);
169 void SequenceBrowser::editSequenceProperties()
171 // if there's a previous window, disconnect its signal
173 disconnect(properties.get(), SIGNAL(propertiesChanged()),
174 this, SLOT(updateGL()));
176 PropertiesWindowRef new_properties(new PropertiesWindow(track_container));
177 properties = new_properties;
178 connect(properties.get(), SIGNAL(propertiesChanged()),
179 this, SLOT(updateGL()));
183 void SequenceBrowser::push_sequence(boost::shared_ptr<Sequence> s)
185 GlSeqBrowser::push_sequence(s);
186 emit tracksChanged();
189 void SequenceBrowser::push_sequence(boost::shared_ptr<GlSequence> gs)
191 GlSeqBrowser::push_sequence(gs);
192 emit tracksChanged();
197 void SequenceBrowser::initializeGL()
199 GlSeqBrowser::initializeGL();
202 void SequenceBrowser::resizeGL(int width, int height)
204 GlSeqBrowser::resizeGL(width, height);
205 emit viewportChanged();
208 void SequenceBrowser::paintGL()
210 GlSeqBrowser::paintGL();
213 void SequenceBrowser::mousePressEvent( QMouseEvent *e)
215 switch(e->button()) {
226 void SequenceBrowser::mouseMoveEvent( QMouseEvent *e )
228 if (rubberBand and rubberBand->isVisible()) {
229 rubberBand->setGeometry(QRect(bandOrigin, e->pos()).normalized());
236 void SequenceBrowser::mouseReleaseEvent( QMouseEvent *e)
238 switch(e->button()) {
242 case Qt::RightButton:
243 // ok so selectedMode and drawing mode should probably be combinded
244 // into a single state variable.
246 not rubberBand->isVisible() and
247 selectedCanvasRegion.contains(e->pos())) {
248 displayContextMenu(e->globalPos());
259 void SequenceBrowser::startSelecting(QMouseEvent *e)
262 rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
264 if (not rubberBand->isVisible()) {
265 bandOrigin = e->pos();
266 rubberBand->setGeometry(QRect(bandOrigin, QSize()));
271 void SequenceBrowser::stopSelecting(QMouseEvent *e)
273 if (rubberBand and rubberBand->isVisible()) {
275 selectedMode = false;
276 QRect r = QRect(bandOrigin, e->pos()).normalized();
277 bandOrigin = r.topLeft();
279 selectRegion(r.top(), r.left(), r.bottom(), r.right());
280 selectedCanvasRegion = r;
284 void SequenceBrowser::wheelEvent(QWheelEvent *e)
287 double cur_zoom = GlSeqBrowser::zoom();
289 // Normalize so one 15 degree turn of the mouse wheel
290 // is equal to 1 step.
291 int num_degrees = e->delta() / 8;
292 int num_steps = num_degrees / 15;
297 // Invert number of steps because code was written
298 // thinking that adding a positve num_steps was zooming
299 // in, but because it's bp/pixel, it's actually zooming out.
300 // To get mouse wheel to zoom in, when pushing the wheel
301 // forward, I can use the existing code, by making num_steps
303 num_steps = num_steps * (-1);
305 if (cur_zoom + num_steps >= 1.0)
307 emit mouseWheelZoom(cur_zoom + num_steps);
309 else if (cur_zoom > 1.0 && cur_zoom + num_steps < 1.0)
311 emit mouseWheelZoom(1.0);
313 else if (cur_zoom <= 0.1)
315 emit mouseWheelZoom(cur_zoom + ((double)num_steps*0.01));
317 else if (cur_zoom <= 1.0 && cur_zoom + ((double)num_steps*0.1) >= 0.1)
319 emit mouseWheelZoom(cur_zoom + ((double)num_steps*0.1));
321 else if (cur_zoom <= 1.0 && cur_zoom + ((double)num_steps*0.1) < 0.1)
323 emit mouseWheelZoom(0.1);
331 // Invert number of steps because code was written
332 // thinking that adding a positve num_steps was zooming
333 // in, but because it's bp/pixel, it's actually zooming out.
334 // To get mouse wheel to zoom out, when pulling the wheel
335 // backwards, I can use the existing code, by making num_steps
337 num_steps = num_steps * (-1);
341 emit mouseWheelZoom(cur_zoom+num_steps);
343 else if (cur_zoom < 1.0 && cur_zoom >= 0.1)
345 emit mouseWheelZoom(cur_zoom + ((double)num_steps*0.1));
347 else if (cur_zoom < 0.1)
349 emit mouseWheelZoom(cur_zoom + ((double)num_steps*0.01));
354 //cout << "Mouse wheel delta: " << num_degrees << "; " << num_steps << "\n";
357 void SequenceBrowser::clearSelection()
359 GlSeqBrowser::clearSelection();
360 if (rubberBand and rubberBand->isVisible()) {