implement selection context menu
[mussa.git] / qui / seqbrowser / SequenceBrowser.cpp
1 #include <QApplication>
2 #include <QClipboard>
3 #include <QDir>
4 #include <QFileDialog>
5 #include <QMessageBox>
6 #include <QMouseEvent>
7 #include <QRubberBand>
8 #include <QRect>
9 #include <QString>
10 #include <iostream>
11 #include <set>
12
13 #include <math.h>
14
15 #include "qui/seqbrowser/SequenceBrowser.hpp"
16 #include "mussa_exceptions.hpp"
17
18 using namespace std;
19
20 SequenceBrowser::SequenceBrowser(QWidget *parent)
21   : QGLWidget(parent),
22     rubberBand(0),
23     popupMenu(this),
24     copySelectedSequenceAsFastaAction(tr("&Copy as Fasta"), this)
25
26   connect(&copySelectedSequenceAsFastaAction, SIGNAL(triggered()), 
27           this, SLOT(copySelectedSequenceAsFasta()));
28   popupMenu.addAction(&copySelectedSequenceAsFastaAction);
29 }
30
31 QSize SequenceBrowser::sizeHint() const
32 {
33   //return QSize((int)GlSeqBrowser::viewportHeight(), (int)GlSeqBrowser::viewportWidth());
34   return QSize(600, 400);
35 }
36
37 void SequenceBrowser::setViewportCenter(float x)
38 {
39   const float epsilon = 1e-10;
40   float center = GlSeqBrowser::viewportCenter();
41   float difference = fabsf(x - center);
42   float abs_x = fabsf(x);
43   center = fabsf(center);
44
45   // the difference < epsilon * val is one of the recommended tests
46   // for float equality.
47   // of course since we're looking for not equals, we need to toss a
48   // not at the beginning
49   if (not (difference < epsilon * abs_x or difference < epsilon * center))
50   {
51     GlSeqBrowser::setViewportCenter(x);
52     emit viewportChanged();
53     update();
54   }
55 }
56
57 void SequenceBrowser::setZoom(double new_zoom)
58 {
59   if (new_zoom != GlSeqBrowser::zoom()) {
60     GlSeqBrowser::setZoom(new_zoom);
61     emit viewportChanged();
62     update();
63   }
64 }
65
66 void SequenceBrowser::setClipPlane(int )
67 {
68 /*
69   if (clipZ != (double) newZ){
70     clipZ = (double) newZ;
71     update();
72   }
73 */
74 }
75
76 void SequenceBrowser::copySelectedSequenceAsFasta()
77 {
78   // get fasta data
79   std::string buffer;
80   copySelectedTracksAsFasta(buffer);
81
82   // get reference to clipboard
83   QClipboard *clipboard = QApplication::clipboard();
84   clipboard->setText(buffer.c_str());
85 }
86
87
88 void SequenceBrowser::clear()
89 {
90   GlSeqBrowser::clear();
91   emit tracksChanged();
92 }
93
94 void SequenceBrowser::displayContextMenu(const QPoint& point)
95 {
96   popupMenu.popup(point);
97 }
98
99 void SequenceBrowser::push_sequence(const Sequence &s)
100 {
101   GlSeqBrowser::push_sequence(s);
102   emit tracksChanged();
103 }
104
105 void SequenceBrowser::push_sequence(GlSequence &gs)
106 {
107   GlSeqBrowser::push_sequence(gs);
108   emit tracksChanged();
109 }
110
111 ////////////////////
112 // Rendering code
113 void SequenceBrowser::initializeGL()
114 {
115   GlSeqBrowser::initializeGL();
116 }
117
118 void SequenceBrowser::resizeGL(int width, int height)
119 {
120   GlSeqBrowser::resizeGL(width, height);
121   emit viewportChanged();
122 }
123
124 void SequenceBrowser::paintGL()
125 {
126   GlSeqBrowser::paintGL();
127 }
128
129 void SequenceBrowser::mousePressEvent( QMouseEvent *e)
130 {
131   switch(e->button()) {
132     case Qt::LeftButton:
133       startSelecting(e);
134       break;
135    case Qt::RightButton:
136       break;
137    default:
138       break;
139   }
140 }
141
142 void SequenceBrowser::mouseMoveEvent( QMouseEvent *e )
143 {
144   if (rubberBand and rubberBand->isVisible()) {
145     rubberBand->setGeometry(QRect(bandOrigin, e->pos()).normalized());
146   }
147 }
148
149 void SequenceBrowser::mouseReleaseEvent( QMouseEvent *e)
150 {
151   switch(e->button()) {
152     case Qt::LeftButton:
153       stopSelecting(e);
154       break;
155    case Qt::RightButton:
156       // ok so selectedMode and drawing mode should probably be combinded
157       // into a single state variable.
158       if (rubberBand and 
159           not rubberBand->isVisible() and
160           selectedCanvasRegion.contains(e->pos())) {
161         displayContextMenu(e->globalPos());
162       }
163       break;
164    default:
165       break;
166   }
167
168 }
169
170 void SequenceBrowser::startSelecting(QMouseEvent *e)
171 {
172   if (!rubberBand)
173     rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
174
175   if (not rubberBand->isVisible()) {
176     bandOrigin = e->pos();
177     rubberBand->setGeometry(QRect(bandOrigin, QSize()));
178     rubberBand->show();
179   }
180 }
181
182 void SequenceBrowser::stopSelecting(QMouseEvent *e)
183 {
184   if (rubberBand and rubberBand->isVisible()) {
185     rubberBand->hide();
186     selectedMode = false;
187     QRect r = QRect(bandOrigin, e->pos()).normalized();
188     bandOrigin = r.topLeft();
189   
190     selectRegion(r.top(), r.left(), r.bottom(), r.right());
191     selectedCanvasRegion = r;
192   }
193 }