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