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