Allow changing the name for a sequence in the sequence browser.
[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
84   // connect the text change signals to each other
85   vector<SequenceDescription *> left = left_sidebar.descriptions;
86   vector<SequenceDescription *> right = right_sidebar.descriptions;
87   for(size_t i = 0; i != sequences.size() and i != right.size(); ++i)
88   {
89     connect(left[i], SIGNAL(nameChanged(const QString &)),
90             right[i], SLOT(setName(const QString &)));
91     connect(right[i], SIGNAL(nameChanged(const QString &)),
92             left[i], SLOT(setName(const QString &)));
93   }
94
95   updatePosition();
96 }
97
98 void SequenceBrowserWidget::setSequences(
99   std::vector<boost::shared_ptr<GlSequence> >& sequences
100 )
101 {
102   SequenceBrowser& browser = scrollable_browser.browser();
103   clear();
104   for(vector<boost::shared_ptr<GlSequence> >::iterator seq_i = sequences.begin();
105       seq_i != sequences.end();
106       ++seq_i)
107   {
108     browser.push_sequence(*seq_i);
109   }
110   left_sidebar.setSequences(sequences);
111   right_sidebar.setSequences(sequences);
112   updatePosition();
113 }
114
115 const vector<boost::shared_ptr<GlSequence> >& SequenceBrowserWidget::sequences() const
116 {
117   return scrollable_browser.browser().sequences();
118 }
119
120 void SequenceBrowserWidget::clear_links()
121 {
122   scrollable_browser.browser().clear_links();
123 }
124
125 void SequenceBrowserWidget::link(const std::vector<int>& path, 
126                                  const std::vector<bool>& isRC, 
127                                  int length)
128 {
129   scrollable_browser.browser().link(path, isRC, length);
130   scrollable_browser.browser().update();
131 }
132
133 const std::set<int> SequenceBrowserWidget::selectedPaths() const
134 {
135   return scrollable_browser.browser().selectedPaths();
136 }
137
138 void SequenceBrowserWidget::centerOnPath(const vector<int>& paths)
139 {
140   scrollable_browser.browser().centerOnPath(paths);
141   updatePosition();
142 }
143
144 /* This could theoretically be pushed down to some set 
145  * of signals and slots connecting SequenceDescriptions and 
146  * some signal emitted by the browser's viewportChanged code
147  * but evertime I tried to figure it out, I got confused about 
148  * how the descriptions in one of the sidebars was supposed to know
149  * if it was mapping the rightbase or the leftbase.
150  * And so though this could be better the typical use cases 
151  * can just talk to the SequenceBrowserWidget for rendering
152  * or mussa output
153  */
154 void SequenceBrowserWidget::updatePosition()
155 {
156   const SequenceBrowser& browser = scrollable_browser.browser();
157   const vector<boost::shared_ptr<GlSequence> > &sequences = browser.sequences();
158   vector<SequenceDescription *> left = left_sidebar.descriptions;
159   vector<SequenceDescription *> right = right_sidebar.descriptions;
160   for(size_t i = 0; i != sequences.size() and i != right.size(); ++i)
161   {
162     left[i]->setPosition(sequences[i]->leftbase(browser.viewportLeft()));
163     right[i]->setPosition(sequences[i]->rightbase(browser.viewportRight()));
164   }
165   scrollable_browser.browser().update();
166   scrollable_browser.updateScrollBar();
167 }
168
169 void SequenceBrowserWidget::promptSaveBrowserPixmap()
170 {
171   QSize size;
172   size = scrollable_browser.browser().size();
173   //Image Save Dialog
174   ImageSaveDialog imageSaveDialog(&scrollable_browser.browser(), this);
175   imageSaveDialog.setSize(size.width(), size.height());
176   imageSaveDialog.exec();
177 }
178
179 double SequenceBrowserWidget::zoom()
180 {
181   return scrollable_browser.browser().zoom();
182 }
183
184 double SequenceBrowserWidget::zoomOut()
185 {
186   double zoom_level = scrollable_browser.browser().zoomOut();
187   scrollable_browser.updateScrollBar();
188   return zoom_level;
189 }
190
191 double SequenceBrowserWidget::zoomToSequence()
192 {
193   double zoom_level = scrollable_browser.browser().zoomToSequence();
194   scrollable_browser.updateScrollBar();
195   return zoom_level;
196 }
197
198 void SequenceBrowserWidget::setZoom(double z)
199 {
200   scrollable_browser.browser().setZoom(z);
201 }
202
203 void SequenceBrowserWidget::update()
204 {
205   QWidget::update();
206   scrollable_browser.browser().update();
207 }