6d5f3ce99e80277181d02150c7492f22fcb3dba8
[mussa.git] / qui / SubanalysisWindow.cpp
1 #include "qui/SubanalysisWindow.hpp"
2 #include "qui/MussaWindow.hpp"
3
4 #include "mussa_exceptions.hpp"
5 #include "alg/mussa.hpp"
6
7 #include <QMessageBox>
8 #include <QVBoxLayout>
9 #include <QHBoxLayout>
10 #include <QGridLayout>
11
12 SubanalysisWindow::SubanalysisWindow(MussaRef m, QWidget *parent)
13   : QWidget(parent),
14     analysis(m),
15     window(0),
16     threshold(0),
17     table(0),
18     ok(0),
19     cancel(0)
20 {
21   QGridLayout *parameterLayout = new QGridLayout;
22
23   QLabel *thresholdLabel = new QLabel(tr("threshold (bp)"));
24   parameterLayout->addWidget(thresholdLabel, 0, 0);
25   threshold = new QSpinBox(this);
26   threshold->setValue(8);
27   parameterLayout->addWidget(threshold, 1, 0);
28   QLabel *windowLabel = new QLabel(tr("window (bp)"));
29   parameterLayout->addWidget(windowLabel, 0, 1);
30   window = new QSpinBox(this);
31   window->setValue(10);
32   parameterLayout->addWidget(window, 1, 1);
33
34   ok = new QPushButton(tr("&OK"), this);
35   ok->setEnabled( false );
36   connect(ok, SIGNAL(clicked()), this, SLOT(run()));
37
38   cancel = new QPushButton(tr("Cancel"), this);
39   connect(cancel, SIGNAL(clicked()), this, SLOT(abort()));
40
41   table = new QTableView(this);
42   table->setModel(&model);
43
44   // layout buttons
45   QHBoxLayout *buttonLayout = new QHBoxLayout;
46   buttonLayout->addWidget(ok);
47   buttonLayout->addWidget(cancel);
48
49   // layout verticle space
50   QVBoxLayout *verticalLayout = new QVBoxLayout;
51   verticalLayout->addLayout(parameterLayout);
52   verticalLayout->addWidget(table);
53   verticalLayout->addLayout(buttonLayout);
54   setLayout(verticalLayout);
55
56   // now that we're all setup lets get notices when we're updated
57   connect(&model, SIGNAL(rowsInserted(const QModelIndex&, int, int)), 
58           this, SLOT(modelUpdated(const QModelIndex&, int, int)));
59   connect(&model, SIGNAL(rowsRemoved(const QModelIndex&, int, int)), 
60           this, SLOT(modelUpdated(const QModelIndex&, int, int)));
61           
62   updateTitle();        
63 }
64
65 SequenceLocationModel& SubanalysisWindow::getModel()
66 {
67   return model;
68 }
69
70 void SubanalysisWindow::abort()
71 {
72   model.clear();
73   hide();
74 }
75
76 void SubanalysisWindow::run()
77 {
78   if (window == 0 or threshold == 0) {
79     throw std::runtime_error("SubanalysisWindow misconstructed");
80   }
81
82   if (model.size() == 0) {
83     throw std::runtime_error("It shouldn't be possible to call run with an "
84                              "empty model now.");
85   }
86
87   MussaRef m(new Mussa);
88   
89   for(SequenceLocationModel::iterator itor = model.begin();
90       itor != model.end();
91       ++itor)
92   {
93     // append_sequence from a const Sequence & will make a copy 
94     // for the shared pointer.
95     m->append_sequence(itor->getSelectedSequence());
96   }
97
98   try {
99     m->set_window(window->value());
100     m->set_threshold(threshold->value());
101     m->analyze();
102     MussaWindow *mw = new MussaWindow(m);
103     mw->show();
104     model.clear();
105     hide();
106   } catch(mussa_error e) {
107     QMessageBox::critical(this,
108                           "Mussa Subanalysis Error",
109                           QString(e.what()),
110                           QMessageBox::Ok, 0, 0);
111   }
112 }
113
114 void SubanalysisWindow::modelUpdated(const QModelIndex&, int, int )
115 {
116   // if the model is empty we shouldn't be able to click ok
117   if (ok) ok->setEnabled(not model.empty());
118 }
119
120 void SubanalysisWindow::updateTitle()
121 {
122   std::string title("Subanalysis: ");
123   if (analysis) {
124     title += analysis->get_title();
125   }
126   setWindowTitle(title.c_str());  
127 }