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