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