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