Actually copy our selected sequence to the clipboard
[mussa.git] / qui / seqbrowser / SequenceBrowserWidget.cpp
1 #include <iostream>
2
3 #include <QApplication>
4 #include <QClipboard>
5 #include <QLabel>
6 #include <QScrollBar>
7 #include <QSpacerItem>
8 #include <QSplitter>
9 #include <QVBoxLayout>
10 #include <QWidget>
11
12 #include "qui/seqbrowser/SequenceBrowserWidget.hpp"
13 #include "qui/seqbrowser/SequenceBrowser.hpp"
14 #include "qui/seqbrowser/ScrollableSequenceBrowser.hpp"
15 #include "qui/seqbrowser/SequenceDescription.hpp"
16 #include "qui/ImageSaveDialog.hpp"
17
18 #include "alg/glsequence.hpp"
19
20 #include <math.h>
21 using namespace std;
22
23 SequenceBrowserWidget::SequenceBrowserWidget(QWidget *parent)
24   : QWidget(parent),
25     scrollable_browser(parent)
26 {
27   QHBoxLayout *hlayout = new QHBoxLayout;
28   hlayout->addWidget(&left_sidebar, 0);
29   hlayout->addWidget(&scrollable_browser, 1);
30   hlayout->addWidget(&right_sidebar, 0);
31   setLayout(hlayout);
32
33   // update position values when something in the SequenceBrowser changes
34   connect(&scrollable_browser.browser(), SIGNAL(viewportChanged()),
35           this, SLOT(updatePosition()));
36 }
37
38 void SequenceBrowserWidget::clear()
39 {
40   converted_sequences.clear();
41   scrollable_browser.browser().clear();
42   left_sidebar.clear();
43   right_sidebar.clear();
44 }
45
46 void SequenceBrowserWidget::setSequences(const std::vector<Sequence>& sequences,
47                                             AnnotationColors& cm)
48 {
49   SequenceBrowser& browser = scrollable_browser.browser();
50   clear();
51   for(vector<Sequence>::const_iterator seq_i = sequences.begin();
52       seq_i != sequences.end();
53       ++seq_i)
54   {
55     GlSequence *gs= new GlSequence(*seq_i, cm);
56     converted_sequences.push_back(*gs);
57     browser.push_sequence(*gs);
58   }
59   left_sidebar.setSequences(converted_sequences);
60   right_sidebar.setSequences(converted_sequences);
61   updatePosition();
62 }
63
64 void SequenceBrowserWidget::setSequences(std::vector<GlSequence>& sequences)
65 {
66   SequenceBrowser& browser = scrollable_browser.browser();
67   clear();
68   for(vector<GlSequence>::iterator seq_i = sequences.begin();
69       seq_i != sequences.end();
70       ++seq_i)
71   {
72     browser.push_sequence(*seq_i);
73   }
74   left_sidebar.setSequences(sequences);
75   right_sidebar.setSequences(sequences);
76   updatePosition();
77 }
78
79 const vector<GlSequence>& SequenceBrowserWidget::sequences() const
80 {
81   return scrollable_browser.browser().sequences();
82 }
83
84 void SequenceBrowserWidget::copySelectedSequenceAsFasta()
85 {
86   // get fasta data
87   std::string buffer;
88   scrollable_browser.browser().copySelectedTracksAsFasta(buffer);
89
90   // get reference to clipboard
91   QClipboard *clipboard = QApplication::clipboard();
92   clipboard->setText(buffer.c_str());
93 }
94
95 void SequenceBrowserWidget::clear_links()
96 {
97   scrollable_browser.browser().clear_links();
98 }
99
100 void SequenceBrowserWidget::link(const std::vector<int>& path, 
101                                  const std::vector<bool>& isRC, 
102                                  int length)
103 {
104   scrollable_browser.browser().link(path, isRC, length);
105   scrollable_browser.browser().update();
106 }
107
108 const std::set<int> SequenceBrowserWidget::selectedPaths() const
109 {
110   return scrollable_browser.browser().selectedPaths();
111 }
112
113 void SequenceBrowserWidget::centerOnPath(const vector<int>& paths)
114 {
115   scrollable_browser.browser().centerOnPath(paths);
116   updatePosition();
117 }
118
119 /* This could theoretically be pushed down to some set 
120  * of signals and slots connecting SequenceDescriptions and 
121  * some signal emitted by the browser's viewportChanged code
122  * but evertime I tried to figure it out, I got confused about 
123  * how the descriptions in one of the sidebars was supposed to know
124  * if it was mapping the rightbase or the leftbase.
125  * And so though this could be better the typical use cases 
126  * can just talk to the SequenceBrowserWidget for rendering
127  * or mussa output
128  */
129 void SequenceBrowserWidget::updatePosition()
130 {
131   const SequenceBrowser& browser = scrollable_browser.browser();
132   const vector<GlSequence> &sequences = browser.sequences();
133   vector<SequenceDescription *> left = left_sidebar.descriptions;
134   vector<SequenceDescription *> right = right_sidebar.descriptions;
135   for(size_t i = 0; i != sequences.size() and i != right.size(); ++i)
136   {
137     left[i]->setPosition(sequences[i].leftbase(browser.viewportLeft()));
138     right[i]->setPosition(sequences[i].rightbase(browser.viewportRight()));
139   }
140   scrollable_browser.browser().update();
141   scrollable_browser.updateScrollBar();
142 }
143
144 void SequenceBrowserWidget::promptSaveBrowserPixmap()
145 {
146   QSize size;
147   size = scrollable_browser.browser().size();
148   //Image Save Dialog
149   ImageSaveDialog imageSaveDialog(&scrollable_browser.browser(), this);
150   imageSaveDialog.setSize(size.width(), size.height());
151   imageSaveDialog.exec();
152 }
153
154 double SequenceBrowserWidget::zoom()
155 {
156   return scrollable_browser.browser().zoom();
157 }
158
159 double SequenceBrowserWidget::zoomOut()
160 {
161   double zoom_level = scrollable_browser.browser().zoomOut();
162   scrollable_browser.updateScrollBar();
163   return zoom_level;
164 }
165
166 double SequenceBrowserWidget::zoomToSequence()
167 {
168   double zoom_level = scrollable_browser.browser().zoomToSequence();
169   scrollable_browser.updateScrollBar();
170   return zoom_level;
171 }
172
173 void SequenceBrowserWidget::setZoom(double z)
174 {
175   scrollable_browser.browser().setZoom(z);
176 }
177
178 void SequenceBrowserWidget::update()
179 {
180   QWidget::update();
181   scrollable_browser.browser().update();
182 }