1 /**
2 * UGENE - Integrated Bioinformatics Tools.
3 * Copyright (C) 2008-2021 UniPro <ugene@unipro.ru>
4 * http://ugene.net
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 * MA 02110-1301, USA.
20 */
21
22 #include <limits.h>
23
24 #include <QLineEdit>
25 #include <QMessageBox>
26 #include <QPushButton>
27
28 #include "WindowStepSelectorWidget.h"
29
30 namespace U2 {
31
32 //////////////////////////////////////////////////////////////////////////
33 // WindowStepSelectorWidget
34
WindowStepSelectorWidget(QWidget * p,const U2Region & winRange,int win,int step)35 WindowStepSelectorWidget::WindowStepSelectorWidget(QWidget *p, const U2Region &winRange, int win, int step)
36 : QWidget(p) {
37 assert(win >= step);
38
39 windowEdit = new QSpinBox(this);
40 windowEdit->setRange(winRange.startPos, winRange.endPos());
41 windowEdit->setValue(win);
42 windowEdit->setAlignment(Qt::AlignLeft);
43 windowEdit->setObjectName("windowEdit");
44
45 stepsPerWindowEdit = new QSpinBox(this);
46 stepsPerWindowEdit->setRange(1, winRange.endPos());
47 stepsPerWindowEdit->setValue(win / step);
48 stepsPerWindowEdit->setAlignment(Qt::AlignLeft);
49 stepsPerWindowEdit->setObjectName("stepsPerWindowEdit");
50
51 formLayout = new QFormLayout(this);
52 formLayout->setMargin(0);
53 formLayout->addRow(tr("Window"), windowEdit);
54 formLayout->addRow(tr("Steps per window"), stepsPerWindowEdit);
55 setLayout(formLayout);
56 }
57
getWindow() const58 int WindowStepSelectorWidget::getWindow() const {
59 assert(validate().isEmpty());
60 return windowEdit->value();
61 }
62
getStep() const63 int WindowStepSelectorWidget::getStep() const {
64 assert(validate().isEmpty());
65 return windowEdit->value() / stepsPerWindowEdit->value();
66 }
67
validate() const68 QString WindowStepSelectorWidget::validate() const {
69 int win = windowEdit->value();
70 int stepsPerWindow = stepsPerWindowEdit->value();
71 if (win % stepsPerWindow != 0) {
72 stepsPerWindowEdit->setFocus(Qt::NoFocusReason);
73 return tr("Illegal step value");
74 }
75 int step = win / stepsPerWindow;
76 if (step > win) {
77 stepsPerWindowEdit->setFocus(Qt::NoFocusReason);
78 return tr("Invalid step value");
79 }
80 return QString();
81 }
82 //////////////////////////////////////////////////////////////////////////
83 ///
84
85 class MinMaxDoubleSpinBox : public QDoubleSpinBox {
86 public:
getLineEdit() const87 QLineEdit *getLineEdit() const {
88 return lineEdit();
89 }
90 };
91
MinMaxSelectorWidget(QWidget * p,double min,double max,bool enabled)92 MinMaxSelectorWidget::MinMaxSelectorWidget(QWidget *p, double min, double max, bool enabled) {
93 Q_UNUSED(p);
94
95 minmaxGroup = new QGroupBox(QString(tr("Cutoff for minimum and maximum values")), this);
96 minmaxGroup->setCheckable(true);
97 minmaxGroup->setChecked(enabled);
98 minmaxGroup->setObjectName("minmaxGroup");
99
100 // for range use min max of type
101 minBox = new MinMaxDoubleSpinBox;
102 minBox->setRange(INT_MIN, INT_MAX);
103 minBox->setValue(min);
104 minBox->setDecimals(2);
105 minBox->setAlignment(Qt::AlignLeft);
106 minBox->setObjectName("minBox");
107
108 maxBox = new MinMaxDoubleSpinBox;
109 maxBox->setRange(INT_MIN, INT_MAX);
110 maxBox->setValue(max);
111 maxBox->setDecimals(2);
112 maxBox->setAlignment(Qt::AlignLeft);
113 maxBox->setObjectName("maxBox");
114
115 normalPalette = maxBox->palette();
116
117 QFormLayout *l = new QFormLayout;
118 l->setSizeConstraint(QLayout::SetMinAndMaxSize);
119 l->addRow(tr("Minimum"), minBox);
120 l->addRow(tr("Maximum"), maxBox);
121 minmaxGroup->setLayout(l);
122
123 QVBoxLayout *mainLayout = new QVBoxLayout;
124 mainLayout->setSizeConstraint(QLayout::SetFixedSize);
125 mainLayout->setMargin(0);
126 mainLayout->addWidget(minmaxGroup);
127 setLayout(mainLayout);
128
129 connect(minBox, SIGNAL(valueChanged(const QString &)), SLOT(sl_valueChanged(const QString &)));
130 connect(maxBox, SIGNAL(valueChanged(const QString &)), SLOT(sl_valueChanged(const QString &)));
131 }
132
getMin() const133 double MinMaxSelectorWidget::getMin() const {
134 assert(validate().isEmpty());
135 return minBox->value();
136 }
137
getMax() const138 double MinMaxSelectorWidget::getMax() const {
139 assert(validate().isEmpty());
140 return maxBox->value();
141 }
142
getState() const143 bool MinMaxSelectorWidget::getState() const {
144 assert(validate().isEmpty());
145 return minmaxGroup->isChecked();
146 }
147
sl_valueChanged(const QString &)148 void MinMaxSelectorWidget::sl_valueChanged(const QString &) {
149 double min = minBox->value();
150 double max = maxBox->value();
151 QPalette p = normalPalette;
152 if (min >= max) {
153 p.setColor(QPalette::Base, QColor(255, 200, 200));
154 }
155 ((MinMaxDoubleSpinBox *)minBox)->getLineEdit()->setPalette(p);
156 ((MinMaxDoubleSpinBox *)maxBox)->getLineEdit()->setPalette(p);
157 }
158
validate() const159 QString MinMaxSelectorWidget::validate() const {
160 if (!minmaxGroup->isChecked())
161 return QString();
162 double min = minBox->value();
163 double max = maxBox->value();
164 if (min >= max) {
165 minBox->setFocus(Qt::NoFocusReason);
166 return tr("Invalid cutoff range");
167 }
168 return QString();
169 }
170
171 //////////////////////////////////////////////////////////////////////////
172 /// Dialog
173
WindowStepSelectorDialog(QWidget * p,const U2Region & winRange,int win,int step,double min,double max,bool e)174 WindowStepSelectorDialog::WindowStepSelectorDialog(QWidget *p, const U2Region &winRange, int win, int step, double min, double max, bool e)
175 : QDialog(p) {
176 wss = new WindowStepSelectorWidget(this, winRange, win, step);
177 mms = new MinMaxSelectorWidget(this, min, max, e);
178 QVBoxLayout *l = new QVBoxLayout();
179 QHBoxLayout *buttonsLayout = new QHBoxLayout();
180 buttonsLayout->addStretch(10);
181 QPushButton *cancelButton = new QPushButton(tr("Cancel"), this);
182 QPushButton *okButton = new QPushButton(tr("OK"), this);
183 buttonsLayout->addWidget(okButton);
184 buttonsLayout->addWidget(cancelButton);
185
186 l->addWidget(wss);
187 l->addWidget(mms);
188 l->addLayout(buttonsLayout);
189
190 setLayout(l);
191 setWindowTitle(tr("Graph Settings"));
192 setWindowIcon(QIcon(":core/images/graphs.png"));
193
194 setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
195 setMinimumWidth(400);
196
197 connect(cancelButton, SIGNAL(clicked(bool)), SLOT(sl_onCancelClicked(bool)));
198 connect(okButton, SIGNAL(clicked(bool)), SLOT(sl_onOkClicked(bool)));
199
200 okButton->setDefault(true);
201 }
202
sl_onCancelClicked(bool v)203 void WindowStepSelectorDialog::sl_onCancelClicked(bool v) {
204 Q_UNUSED(v);
205 reject();
206 }
207
sl_onOkClicked(bool v)208 void WindowStepSelectorDialog::sl_onOkClicked(bool v) {
209 Q_UNUSED(v);
210 QString err = wss->validate();
211 QString mmerr = mms->validate();
212 if (err.isEmpty() && mmerr.isEmpty()) {
213 accept();
214 return;
215 }
216 QMessageBox::critical(this, tr("Error!"), err.append(' ').append(mmerr));
217 }
218
219 } // namespace U2
220