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