Isis 3 Programmer Reference
AbstractFilter.cpp
1 #include "IsisDebug.h"
2 
3 #include <iostream>
4 #include <limits>
5 
6 #include "AbstractFilter.h"
7 
8 #include <QAction>
9 #include <QAbstractButton>
10 #include <QButtonGroup>
11 #include <QCheckBox>
12 #include <QFlags>
13 #include <QHBoxLayout>
14 #include <QLabel>
15 #include <QMargins>
16 #include <QMenu>
17 #include <QMenuBar>
18 #include <QPair>
19 #include <QRadioButton>
20 #include <QSpinBox>
21 #include <QString>
22 #include <QVBoxLayout>
23 #include <QWriteLocker>
24 
25 #include "ControlMeasure.h"
26 #include "ControlNet.h"
27 #include "ControlPoint.h"
28 
29 #include "AbstractFilterSelector.h"
30 
31 
32 namespace Isis {
33  AbstractFilter::AbstractFilter(FilterEffectivenessFlag effectiveness,
34  int minimumForSuccess) {
35  nullify();
36 
37  m_minForSuccess = minimumForSuccess;
38 
39  m_effectivenessFlags = new FilterEffectivenessFlag(effectiveness);
40 
41  m_smallFont = new QFont("SansSerif", 9);
42 
43  createWidget();
44  }
45 
46 
47  AbstractFilter::AbstractFilter(const AbstractFilter &other) {
48  nullify();
49 
50  m_minForSuccess = other.m_minForSuccess;
51 
52  m_effectivenessFlags = new FilterEffectivenessFlag(*other.m_effectivenessFlags);
53 
54  m_smallFont = new QFont(*other.m_smallFont);
55 
56  createWidget();
57 
58  m_inclusiveExclusiveGroup->button(
59  other.m_inclusiveExclusiveGroup->checkedId())->click();
60  }
61 
62 
63  AbstractFilter::~AbstractFilter() {
64  delete m_effectivenessFlags;
65  m_effectivenessFlags = NULL;
66 
67  delete m_inclusiveExclusiveGroup;
68  m_inclusiveExclusiveGroup = NULL;
69 
70  delete m_smallFont;
71  m_smallFont = NULL;
72  }
73 
74 
75  bool AbstractFilter::canFilterImages() const {
76  return m_effectivenessFlags->testFlag(Images);
77  }
78 
79 
80  bool AbstractFilter::canFilterPoints() const {
81  return m_effectivenessFlags->testFlag(Points);
82  }
83 
84 
85  bool AbstractFilter::canFilterMeasures() const {
86  return m_effectivenessFlags->testFlag(Measures);
87  }
88 
89 
90  QString AbstractFilter::getImageDescription() const {
91  return "have at least " + QString::number(getMinForSuccess()) + " ";
92  }
93 
94 
95  QString AbstractFilter::getPointDescription() const {
96  return QString();
97  }
98 
99 
100  QString AbstractFilter::getMeasureDescription() const {
101  return QString();
102  }
103 
104 
105  void AbstractFilter::nullify() {
106  m_effectivenessGroup = NULL;
107  m_inclusiveExclusiveGroup = NULL;
108  m_inclusiveExclusiveLayout = NULL;
109  m_mainLayout = NULL;
110  m_minWidget = NULL;
111  m_effectivenessFlags = NULL;
112  m_smallFont = NULL;
113  }
114 
115 
116  void AbstractFilter::createWidget() {
117  QRadioButton *inclusiveButton = new QRadioButton("Inclusive");
118  inclusiveButton->setFont(*m_smallFont);
119  QRadioButton *exclusiveButton = new QRadioButton("Exclusive");
120  exclusiveButton->setFont(*m_smallFont);
121 
122  m_inclusiveExclusiveGroup = new QButtonGroup;
123  connect(m_inclusiveExclusiveGroup, SIGNAL(buttonClicked(int)),
124  this, SIGNAL(filterChanged()));
125  m_inclusiveExclusiveGroup->addButton(inclusiveButton, 0);
126  m_inclusiveExclusiveGroup->addButton(exclusiveButton, 1);
127 
128  m_inclusiveExclusiveLayout = new QHBoxLayout;
129  QMargins margins = m_inclusiveExclusiveLayout->contentsMargins();
130  margins.setTop(0);
131  margins.setBottom(0);
132  m_inclusiveExclusiveLayout->setContentsMargins(margins);
133  m_inclusiveExclusiveLayout->addWidget(inclusiveButton);
134  m_inclusiveExclusiveLayout->addWidget(exclusiveButton);
135 
136  QHBoxLayout *controlsLayout = new QHBoxLayout;
137  margins = controlsLayout->contentsMargins();
138  margins.setTop(0);
139  margins.setBottom(0);
140  controlsLayout->setContentsMargins(margins);
141 
142  controlsLayout->addLayout(m_inclusiveExclusiveLayout);
143 
144  m_effectivenessGroup = new QButtonGroup();
145  m_effectivenessGroup->setExclusive(false);
146 
147  if (m_effectivenessFlags->testFlag(Images))
148  m_effectivenessGroup->addButton(
149  createEffectivenessCheckBox("&Images"), 0);
150 
151  if (m_effectivenessFlags->testFlag(Points))
152  m_effectivenessGroup->addButton(
153  createEffectivenessCheckBox("&Points"), 1);
154 
155  if (m_effectivenessFlags->testFlag(Measures))
156  m_effectivenessGroup->addButton(
157  createEffectivenessCheckBox("&Measures"), 2);
158 
159  QString firstGroupEntry;
160  ASSERT(m_effectivenessGroup->buttons().size());
161  if (m_effectivenessGroup->buttons().size()) {
162  firstGroupEntry = m_effectivenessGroup->buttons()[0]->text();
163  firstGroupEntry.remove(0, 1);
164  }
165 
166  QList<QAbstractButton *> buttons = m_effectivenessGroup->buttons();
167  if (m_effectivenessGroup->buttons().size() >= 2) {
168  QHBoxLayout *effectivenessLayout = new QHBoxLayout;
169  QMargins effectivenessMargins = effectivenessLayout->contentsMargins();
170  effectivenessMargins.setTop(0);
171  effectivenessMargins.setBottom(0);
172  effectivenessLayout->setContentsMargins(effectivenessMargins);
173 
174  for (int i = 0; i < buttons.size(); i++)
175  effectivenessLayout->addWidget(buttons[i]);
176 
177  controlsLayout->addLayout(effectivenessLayout);
178  }
179  else {
180  for (int i = 0; i < buttons.size(); i++)
181  delete buttons[i];
182  delete m_effectivenessGroup;
183  m_effectivenessGroup = NULL;
184  }
185 
186  if (m_minForSuccess != -1) {
187  QLabel *label = new QLabel;
188  label->setText(
189  "<span>Min Count<br/>for " + firstGroupEntry + "</span>");
190  label->setFont(QFont("SansSerif", 7));
191  QSpinBox *spinBox = new QSpinBox;
192  spinBox->setRange(1, std::numeric_limits< int >::max());
193  spinBox->setValue(1); // FIXME: QSettings should handle this
194  connect(spinBox, SIGNAL(valueChanged(int)),
195  this, SLOT(updateMinForSuccess(int)));
196  QHBoxLayout *minLayout = new QHBoxLayout;
197  margins = minLayout->contentsMargins();
198  margins.setTop(0);
199  margins.setBottom(0);
200  minLayout->setContentsMargins(margins);
201  minLayout->addWidget(label);
202  minLayout->addWidget(spinBox);
203  m_minWidget = new QWidget;
204  m_minWidget->setLayout(minLayout);
205 
206  controlsLayout->addWidget(m_minWidget);
207  controlsLayout->setAlignment(m_minWidget, Qt::AlignTop);
208  m_minWidget->setVisible(true); // FIXME: QSettings should handle this
209  }
210 
211  controlsLayout->addStretch();
212 
213  m_mainLayout = new QVBoxLayout;
214  margins = m_mainLayout->contentsMargins();
215  margins.setTop(0);
216  margins.setBottom(0);
217  m_mainLayout->setContentsMargins(margins);
218  m_mainLayout->addLayout(controlsLayout);
219 
220 
221  setLayout(m_mainLayout);
222 
223  // FIXME: QSettings should handle this
224  inclusiveButton->click();
225  }
226 
227 
228  QCheckBox *AbstractFilter::createEffectivenessCheckBox(QString text) {
229  QCheckBox *checkBox = new QCheckBox(text, this);
230  checkBox->setChecked(true);
231  checkBox->setFont(*m_smallFont);
232  connect(checkBox, SIGNAL(toggled(bool)),
233  this, SLOT(updateEffectiveness()));
234  connect(checkBox, SIGNAL(toggled(bool)), this, SIGNAL(filterChanged()));
235  return checkBox;
236  }
237 
238 
239  bool AbstractFilter::inclusive() const {
240  return m_inclusiveExclusiveGroup->checkedId() == 0;
241  }
242 
243 
244  AbstractFilter::FilterEffectivenessFlag *
245  AbstractFilter::getEffectivenessFlags() const {
246  return m_effectivenessFlags;
247  }
248 
249 
250  QBoxLayout *AbstractFilter::getMainLayout() const {
251  ASSERT(m_mainLayout);
252 
253  return m_mainLayout;
254  }
255 
256 
257  QBoxLayout *AbstractFilter::getInclusiveExclusiveLayout() const {
258  ASSERT(m_inclusiveExclusiveLayout);
259 
260  return m_inclusiveExclusiveLayout;
261  }
262 
263 
264  bool AbstractFilter::evaluateFromCount(QList< ControlMeasure * > measures,
265  bool usePoints) const {
266  int passedCount = 0;
267 
268  foreach (ControlMeasure * measure, measures) {
269  ASSERT(measure);
270 
271  if (usePoints) {
272  ControlPoint *point = measure->Parent();
273  ASSERT(point);
274  if (point && evaluate(point))
275  passedCount++;
276  }
277  else {
278  if (measure && evaluate(measure))
279  passedCount++;
280  }
281  }
282 
283  return passedCount >= getMinForSuccess();
284  }
285 
286 
287  bool AbstractFilter::evaluateImageFromPointFilter(
288  const QPair<QString, ControlNet *> *imageAndNet) const {
289  bool evaluation = true;
290 
291  if (canFilterImages()) {
292  evaluation = evaluateFromCount(imageAndNet->second->GetMeasuresInCube(imageAndNet->first),
293  true);
294  }
295 
296  return evaluation;
297  }
298 
299 
300  bool AbstractFilter::evaluateImageFromMeasureFilter(
301  const QPair<QString, ControlNet *> *imageAndNet) const {
302  bool evaluation = true;
303 
304  if (canFilterImages()) {
305  evaluation = evaluateFromCount(imageAndNet->second->GetMeasuresInCube(imageAndNet->first),
306  false);
307  }
308 
309  return evaluation;
310  }
311 
312 
313  bool AbstractFilter::evaluatePointFromMeasureFilter(
314  const ControlPoint *point) const {
315  ASSERT(point);
316 
317  bool evaluation = true;
318 
319  if (canFilterPoints())
320  evaluation = evaluateFromCount(point->getMeasures(), false);
321 
322  return evaluation;
323  }
324 
325 
326  bool AbstractFilter::evaluate(const ControlPoint *point,
327  bool (ControlPoint::*meth)() const) const {
328  ASSERT(point);
329 
330  return !((point->*meth)() ^ inclusive());
331  }
332 
333 
334  bool AbstractFilter::evaluate(const ControlMeasure *measure,
335  bool (ControlMeasure::*meth)() const) const {
336  ASSERT(measure);
337 
338  return !((measure->*meth)() ^ inclusive());
339  }
340 
341 
342  void AbstractFilter::updateEffectiveness() {
343  ASSERT(m_effectivenessGroup);
344 
345  if (m_effectivenessGroup) {
346  FilterEffectivenessFlag newFlags;
347 
348  QList< QAbstractButton * > buttons = m_effectivenessGroup->buttons();
349 
350  if (m_minWidget)
351  m_minWidget->setVisible(false);
352 
353  for (int i = 0; i < buttons.size(); i++) {
354  if (buttons[i]->isChecked()) {
355  if (buttons[i]->text() == "&Images")
356  newFlags |= Images;
357  else if (buttons[i]->text() == "&Points")
358  newFlags |= Points;
359  else if (buttons[i]->text() == "&Measures")
360  newFlags |= Measures;
361 
362  if (i == 0 && m_minWidget)
363  m_minWidget->setVisible(true);
364  }
365  }
366 
367  *m_effectivenessFlags = newFlags;
368  }
369  }
370 
371 
372  void AbstractFilter::updateMinForSuccess(int newMin) {
373  m_minForSuccess = newMin;
374  emit filterChanged();
375  }
376 }
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31