1 /***************************************************************************
2  *                                                                         *
3  *   copyright : (C) 2007 The University of Toronto                        *
4  *                   netterfield@astro.utoronto.ca                         *
5  *                                                                         *
6  *   This program is free software; you can redistribute it and/or modify  *
7  *   it under the terms of the GNU General Public License as published by  *
8  *   the Free Software Foundation; either version 2 of the License, or     *
9  *   (at your option) any later version.                                   *
10  *                                                                         *
11  ***************************************************************************/
12 
13 #include "datarange.h"
14 #include "dialogdefaults.h"
15 
16 namespace Kst {
17 
DataRange(QWidget * parent)18 DataRange::DataRange(QWidget *parent)
19   : QWidget(parent) {
20   setupUi(this);
21 
22   connect(_countFromEnd, SIGNAL(toggled(bool)), this, SLOT(countFromEndChanged()));
23   connect(_readToEnd, SIGNAL(toggled(bool)), this, SLOT(readToEndChanged()));
24   connect(_doSkip, SIGNAL(toggled(bool)), this, SLOT(doSkipChanged()));
25 
26   connect(_start, SIGNAL(textEdited(QString)), this, SLOT(startChanged()));
27   connect(_range, SIGNAL(textEdited(QString)), this, SLOT(rangeChanged()));
28   connect(_last, SIGNAL(textEdited(QString)), this, SLOT(lastChanged()));
29   connect(_skip, SIGNAL(valueChanged(int)), this, SIGNAL(modified()));
30   connect(_doFilter, SIGNAL(toggled(bool)), this, SIGNAL(modified()));
31   connect(_countFromEnd, SIGNAL(toggled(bool)), this, SIGNAL(modified()));
32   connect(_readToEnd, SIGNAL(toggled(bool)), this, SIGNAL(modified()));
33   connect(_doSkip, SIGNAL(toggled(bool)), this, SIGNAL(modified()));
34   connect(_startUnits, SIGNAL(currentIndexChanged(int)), this, SLOT(unitsChanged()));
35   connect(_rangeUnits, SIGNAL(currentIndexChanged(int)), this, SLOT(unitsChanged()));
36 
37   _controlField0 = Range;
38   _controlField1 = Start;
39 }
40 
41 
~DataRange()42 DataRange::~DataRange() {
43 }
44 
45 
clearValues()46 void DataRange::clearValues() {
47   _start->clear();
48   _range->clear();
49   _skip->clear();
50   _doFilter->setCheckState(Qt::PartiallyChecked);
51   _readToEnd->setCheckState(Qt::PartiallyChecked);
52   _doSkip->setCheckState(Qt::PartiallyChecked);
53 }
54 
55 
start() const56 qreal DataRange::start() const {
57   return _start->text().toDouble();
58 }
59 
60 
startDirty() const61 bool DataRange::startDirty() const {
62   return !_start->text().isEmpty();
63 }
64 
65 
setStart(qreal start,bool callUpdateFields)66 void DataRange::setStart(qreal start, bool callUpdateFields) {
67   _start->setText(QString::number(start, 'g', 12));
68   if (callUpdateFields) {
69     updateFields(None);
70   }
71 }
72 
last() const73 qreal DataRange::last() const {
74   return _last->text().toDouble();
75 }
76 
77 
lastDirty() const78 bool DataRange::lastDirty() const {
79   return !_last->text().isEmpty();
80 }
81 
82 
setLast(qreal last,bool callUpdateFields)83 void DataRange::setLast(qreal last, bool callUpdateFields) {
84   _last->setText(QString::number(last, 'g', 12));
85   if (callUpdateFields) {
86     updateFields(None);
87   }
88 }
89 
clearIndexList()90 void DataRange::clearIndexList() {
91   _startUnits->clear();
92   _rangeUnits->clear();
93 }
94 
95 
updateIndexList(const QStringList & indexFields)96 void DataRange::updateIndexList(const QStringList &indexFields) {
97   _startUnits->clear();
98   _startUnits->addItems(indexFields);
99   setStartUnits(_requestedStartUnits);
100   _rangeUnits->clear();
101   _rangeUnits->addItems(indexFields);
102   setRangeUnits(_requestedRangeUnits);
103 }
104 
105 
startUnits() const106 QString DataRange::startUnits() const {
107   return _startUnits->currentText();
108 }
109 
110 
startUnitsIndex() const111 int DataRange::startUnitsIndex() const {
112   return _startUnits->currentIndex();
113 }
114 
115 
setStartUnits(const QString & startUnits)116 void DataRange::setStartUnits(const QString &startUnits) {
117   _requestedStartUnits = startUnits;
118   int i = _startUnits->findText(startUnits);
119   if (i>=0) {
120     _startUnits->setCurrentIndex(i);
121   }
122 }
123 
range() const124 qreal DataRange::range() const {
125   return _range->text().toDouble();
126 }
127 
128 
rangeUnitsIndex() const129 int DataRange::rangeUnitsIndex()  const {
130   return _rangeUnits->currentIndex();
131 }
132 
133 
rangeDirty() const134 bool DataRange::rangeDirty() const {
135   return !_range->text().isEmpty();
136 }
137 
138 
setRange(qreal range,bool callUpdateFields)139 void DataRange::setRange(qreal range, bool callUpdateFields) {
140   _range->setText(QString::number(range));
141   if (callUpdateFields) {
142     updateFields(None);
143   }
144 }
145 
146 
rangeUnits() const147 QString DataRange::rangeUnits() const {
148   return _rangeUnits->currentText();
149 }
150 
151 
setRangeUnits(const QString & rangeUnits)152 void DataRange::setRangeUnits(const QString &rangeUnits) {
153   _requestedRangeUnits = rangeUnits;
154   int i = _rangeUnits->findText(rangeUnits);
155   if (i>=0) {
156     _rangeUnits->setCurrentIndex(i);
157   } else {
158     _rangeUnits->setCurrentIndex(0);
159   }
160 }
161 
162 
skip() const163 int DataRange::skip() const {
164   return _skip->value();
165 }
166 
167 
skipDirty() const168 bool DataRange::skipDirty() const {
169   return !_skip->text().isEmpty();
170 }
171 
172 
setSkip(int skip)173 void DataRange::setSkip(int skip) {
174   _skip->setValue(skip);
175 }
176 
177 
countFromEnd() const178 bool DataRange::countFromEnd() const {
179   return _countFromEnd->isChecked();
180 }
181 
182 
setCountFromEnd(bool countFromEnd)183 void DataRange::setCountFromEnd(bool countFromEnd) {
184   _countFromEnd->setChecked(countFromEnd);
185   updateFields(None);
186 }
187 
188 
countFromEndDirty() const189 bool DataRange::countFromEndDirty() const {
190   return _readToEnd->checkState() == Qt::PartiallyChecked;
191 }
192 
193 
readToEnd() const194 bool DataRange::readToEnd() const {
195   return _readToEnd->isChecked();
196 }
197 
198 
readToEndDirty() const199 bool DataRange::readToEndDirty() const {
200   return _readToEnd->checkState() == Qt::PartiallyChecked;
201 }
202 
203 
setReadToEnd(bool readToEnd)204 void DataRange::setReadToEnd(bool readToEnd) {
205   _readToEnd->setChecked(readToEnd);
206   updateFields(None);
207 }
208 
209 
doSkip() const210 bool DataRange::doSkip() const {
211   return _doSkip->isChecked();
212 }
213 
214 
doSkipDirty() const215 bool DataRange::doSkipDirty() const {
216   return _doSkip->checkState() == Qt::PartiallyChecked;
217 }
218 
219 
setDoSkip(bool doSkip)220 void DataRange::setDoSkip(bool doSkip) {
221   _doSkip->setChecked(doSkip);
222 }
223 
224 
doFilter() const225 bool DataRange::doFilter() const {
226   return _doFilter->isChecked();
227 }
228 
229 
doFilterDirty() const230 bool DataRange::doFilterDirty() const {
231   return _doFilter->checkState() == Qt::PartiallyChecked;
232 }
233 
234 
setDoFilter(bool doFilter)235 void DataRange::setDoFilter(bool doFilter) {
236   _doFilter->setChecked(doFilter);
237 }
238 
239 
countFromEndChanged()240 void DataRange::countFromEndChanged() {
241   if (countFromEnd()) {
242     setReadToEnd(false);
243   }
244 
245   updateFields(None);
246 
247 }
248 
249 
readToEndChanged()250 void DataRange::readToEndChanged() {
251   if (readToEnd()) {
252     setCountFromEnd(false);
253   }
254 
255   updateFields(None);
256 
257 }
258 
259 
unitsChanged()260 void DataRange::unitsChanged() {
261   updateFields(None);
262 }
263 
264 
doSkipChanged()265 void DataRange::doSkipChanged() {
266   _skip->setEnabled(doSkip());
267   _doFilter->setEnabled(doSkip());
268 }
269 
270 // control field logic:
271 // the last one changed, other than this one, should be the control field
272 // do we need a history?
273 // F0 R -> L
274 // F0 L -> R
275 // R L -> F0
276 // R F0 -> L
277 
startChanged()278 void DataRange::startChanged() {
279   updateFields(Start);
280   emit modified();
281 }
282 
283 
lastChanged()284 void DataRange::lastChanged() {
285   updateFields(Last);
286   emit modified();
287 }
288 
289 
rangeChanged()290 void DataRange::rangeChanged() {
291   updateFields(Range);
292   emit modified();
293 }
294 
295 
updateFields(ControlField cf)296 void DataRange::updateFields(ControlField cf) {
297 
298   bool enable_last = (_rangeUnits->currentIndex() == _startUnits->currentIndex());
299   enable_last &= !readToEnd();
300   enable_last &= !countFromEnd();
301 
302 
303   _last->setEnabled(enable_last);
304   _lastLabel->setEnabled(enable_last);
305 
306   _start->setEnabled(!countFromEnd());
307   _startLabel->setEnabled(!countFromEnd());
308   _startUnits->setEnabled(!countFromEnd());
309   _range->setEnabled(!readToEnd());
310   _rangeLabel->setEnabled(!readToEnd());
311   _rangeUnits->setEnabled(!readToEnd());
312 
313   if ((cf!=None) && (cf != _controlField1)) {
314     _controlField0 = _controlField1;
315     _controlField1 = cf;
316   }
317 
318   // don't do anything if it wouldn't make sense to.
319   if (readToEnd() || countFromEnd()) {
320     return;
321   }
322 
323   if (startUnits() != (rangeUnits())) {
324     return;
325   }
326 
327   if ((_controlField0 != Start) && (_controlField1 != Start)) {
328     _start->setText(QString::number(last() - range() + 1, 'g', 12));
329   } else if ((_controlField0 != Last) && (_controlField1 != Last)) {
330     _last->setText(QString::number(start() + range() - 1, 'g', 12));
331   } else if ((_controlField0 != Range) && (_controlField1 != Range)) {
332     _range->setText(QString::number(last() - start() + 1, 'g', 12));
333   }
334 }
335 
336 
setWidgetDefaults()337 void DataRange::setWidgetDefaults() {
338   //FIXME Do we need a V->readLock() here?
339   dialogDefaults().setValue("vector/range", range());
340   dialogDefaults().setValue("vector/start", start());
341   dialogDefaults().setValue("vector/countFromEnd", countFromEnd());
342   dialogDefaults().setValue("vector/readToEnd", readToEnd());
343   dialogDefaults().setValue("vector/skip", skip());
344   dialogDefaults().setValue("vector/doSkip", doSkip());
345   dialogDefaults().setValue("vector/doAve", doFilter());
346   dialogDefaults().setValue("vector/rangeUnits", rangeUnits());
347   dialogDefaults().setValue("vector/startUnits", rangeUnits());
348 }
349 
loadWidgetDefaults()350 void DataRange::loadWidgetDefaults() {
351   setRange(dialogDefaults().value("vector/range", 1).toInt());
352   setStart(dialogDefaults().value("vector/start", 0).toInt());
353   setCountFromEnd(dialogDefaults().value("vector/countFromEnd",false).toBool());
354   setReadToEnd(dialogDefaults().value("vector/readToEnd",true).toBool());
355   setSkip(dialogDefaults().value("vector/skip", 0).toInt());
356   setDoSkip(dialogDefaults().value("vector/doSkip", false).toBool());
357   setDoFilter(dialogDefaults().value("vector/doAve",false).toBool());
358   setRangeUnits(dialogDefaults().value("vector/rangeUnits",tr("frames")).toString());
359   setStartUnits(dialogDefaults().value("vector/startUnits",tr("frames")).toString());
360 }
361 
rangeIsValid()362 bool DataRange::rangeIsValid() {
363   if (readToEnd()) {
364     return true;
365   } else {
366     return (range()>1);
367   }
368 }
369 
370 }
371 
372 // vim: ts=2 sw=2 et
373