Isis 3 Programmer Reference
FilterGroup.cpp
1
7/* SPDX-License-Identifier: CC0-1.0 */
8
9#include "FilterGroup.h"
10
11#include <QButtonGroup>
12#include <QGroupBox>
13#include <QPushButton>
14#include <QHBoxLayout>
15#include <QIcon>
16#include <QLabel>
17#include <QRadioButton>
18#include <QString>
19#include <QVBoxLayout>
20
21#include "IException.h"
22#include "IString.h"
23#include "FileName.h"
24
25#include "AbstractFilterSelector.h"
26#include "ImageImageFilterSelector.h"
27#include "PointMeasureFilterSelector.h"
28#include "ImagePointFilterSelector.h"
29
30
31using std::nothrow;
32using std::swap;
33
34namespace Isis {
35 FilterGroup::FilterGroup(QString type) {
36 nullify();
37
38 m_filterType = new QString(type);
39
40 init();
41 addSelector();
42 }
43
44
45 FilterGroup::FilterGroup(const FilterGroup &other) {
46 nullify();
47
48 m_filterType = new QString(*other.m_filterType);
49
50 init();
51
52 foreach (AbstractFilterSelector * selector, *other.m_selectors) {
53 AbstractFilterSelector *newSelector = NULL;
54 if (*m_filterType == "Points and Measures") {
55 newSelector = new PointMeasureFilterSelector(
56 *((PointMeasureFilterSelector *) selector));
57 }
58 else {
59 if (*m_filterType == "Images and Points") {
60 newSelector = new ImagePointFilterSelector(
61 *((ImagePointFilterSelector *) selector));
62 }
63 else {
64 if (*m_filterType == "Connections") {
65 newSelector = new ImageImageFilterSelector(
66 *((ImageImageFilterSelector *) selector));
67 }
68 }
69 }
70
71 addSelector(newSelector);
72 }
73
74 m_buttonGroup->button(other.m_buttonGroup->checkedId())->click();
75 }
76
77
78 FilterGroup::~FilterGroup() {
79 if (m_buttonGroup) {
80 delete m_buttonGroup;
81 m_buttonGroup = NULL;
82 }
83
84 if (m_selectors) {
85 delete m_selectors;
86 m_selectors = NULL;
87 }
88
89 if (m_filterType) {
90 delete m_filterType;
91 m_filterType = NULL;
92 }
93 }
94
95
96 bool FilterGroup::hasFilter(bool (AbstractFilter::*meth)() const) const {
97 bool found = false;
98
99 for (int i = 0; !found && i < m_selectors->size(); i++)
100 if (meth)
101 found = m_selectors->at(i)->hasFilter(meth);
102 else
103 found = m_selectors->at(i)->hasFilter();
104
105 return found;
106 }
107
108
109 void FilterGroup::nullify() {
110 m_buttonGroup = NULL;
111 m_closeButton = NULL;
112 m_groupBoxLayout = NULL;
113 m_selectors = NULL;
114 }
115
116
117 void FilterGroup::init() {
118 m_selectors = new QList< AbstractFilterSelector * >;
119
120 QLabel *descriptionLabel = new QLabel("Combine filters using logic "
121 "type: ");
122 QFont descriptionFont("SansSerif", 11);
123 descriptionLabel->setFont(descriptionFont);
124 QFont logicTypeFont("SansSerif", 12, QFont::Bold);
125 QRadioButton *andButton = new QRadioButton("and");
126 andButton->setFont(logicTypeFont);
127 QRadioButton *orButton = new QRadioButton("or");
128 orButton->setFont(logicTypeFont);
129 m_buttonGroup = new QButtonGroup;
130 m_buttonGroup->addButton(andButton, 0);
131 m_buttonGroup->addButton(orButton, 1);
132 connect(m_buttonGroup, SIGNAL(buttonClicked(int)), this,
133 SLOT(changeFilterCombinationLogic(int)));
134
135 // FIXME: this should be controlled by QSettings
136 andButton->click();
137
138 QHBoxLayout *logicLayout = new QHBoxLayout;
139 QMargins margins = logicLayout->contentsMargins();
140 margins.setBottom(4);
141 logicLayout->setContentsMargins(margins);
142 logicLayout->addStretch();
143 logicLayout->addWidget(descriptionLabel);
144 logicLayout->addWidget(andButton);
145 logicLayout->addWidget(orButton);
146 logicLayout->addStretch();
147 m_logicWidget = new QWidget;
148 m_logicWidget->setLayout(logicLayout);
149
150 m_newSelectorButton = new QPushButton;
151 m_newSelectorButton->setIcon(QIcon(
152 FileName("$ISISROOT/appdata/images/icons/add.png").expanded()));
153 QString newSelectorTooltip = "Add new filter";
154 m_newSelectorButton->setToolTip(newSelectorTooltip);
155 m_newSelectorButton->setStatusTip(newSelectorTooltip);
156
157 connect(m_newSelectorButton, SIGNAL(clicked()), this, SLOT(addSelector()));
158 QHBoxLayout *newSelectorLayout = new QHBoxLayout;
159 newSelectorLayout->addWidget(m_newSelectorButton);
160 newSelectorLayout->addStretch();
161
162 m_groupBoxLayout = new QVBoxLayout;
163 m_groupBoxLayout->addWidget(m_logicWidget);
164 m_groupBoxLayout->addLayout(newSelectorLayout);
165 QGroupBox *groupBox = new QGroupBox;
166 groupBox->setLayout(m_groupBoxLayout);
167
168 QVBoxLayout *mainLayout = new QVBoxLayout;
169 margins = mainLayout->contentsMargins();
170 margins.setTop(2);
171 margins.setBottom(2);
172 mainLayout->setContentsMargins(margins);
173 mainLayout->addWidget(groupBox);
174
175 setLayout(mainLayout);
176 }
177
178
179 void FilterGroup::addSelector() {
180 AbstractFilterSelector *filterSelector = NULL;
181 if (*m_filterType == "Points and Measures")
182 filterSelector = new PointMeasureFilterSelector;
183 else if (*m_filterType == "Images and Points")
184 filterSelector = new ImagePointFilterSelector;
185 else if (*m_filterType == "Connections")
186 filterSelector = new ImageImageFilterSelector;
187
188 addSelector(filterSelector);
189 }
190
191
192 void FilterGroup::addSelector(AbstractFilterSelector *newSelector) {
193
194 if (newSelector) {
195 connect(newSelector, SIGNAL(close(AbstractFilterSelector *)),
196 this, SLOT(deleteSelector(AbstractFilterSelector *)));
197 connect(newSelector, SIGNAL(filterChanged()),
198 this, SIGNAL(filterChanged()));
199 connect(newSelector, SIGNAL(sizeChanged()),
200 this, SLOT(sendSizeChanged()));
201 m_groupBoxLayout->insertWidget(m_groupBoxLayout->count() - 1, newSelector);
202 m_selectors->append(newSelector);
203 m_selectors->size() > 1 ? m_logicWidget->show() : m_logicWidget->hide();
204 }
205
206 sendSizeChanged();
207 }
208
209
210 void FilterGroup::deleteSelector(AbstractFilterSelector *filterSelector) {
211 m_groupBoxLayout->removeWidget(filterSelector);
212 delete filterSelector;
213 m_selectors->removeOne(filterSelector);
214
215 int m_selectorsSize = m_selectors->size();
216 m_selectorsSize > 1 ? m_logicWidget->show() : m_logicWidget->hide();
217 if (!m_selectorsSize)
218 emit close(this);
219 else
220 emit filterChanged();
221 }
222
223
224 void FilterGroup::sendClose() {
225 emit close(this);
226 }
227
228
229 void FilterGroup::sendSizeChanged() {
230 emit sizeChanged(this);
231 }
232
233
234 void FilterGroup::changeFilterCombinationLogic(int button) {
235 m_andFiltersTogether = button == 0;
236 emit filterChanged();
237 }
238
239
240 bool FilterGroup::filtersAreAndedTogether() const {
241 return m_andFiltersTogether;
242 }
243
244
245 FilterGroup &FilterGroup::operator=(FilterGroup other) {
246
247 // create temporary list of new selectors
248 QList< AbstractFilterSelector * > newSelectors;
249 foreach (AbstractFilterSelector * selector, *other.m_selectors) {
250 AbstractFilterSelector *newSelector = NULL;
251 if (*m_filterType == "Points and Measures") {
252 newSelector = new(nothrow) PointMeasureFilterSelector(
253 *((PointMeasureFilterSelector *) selector));
254 }
255 else {
256 if (*m_filterType == "Images and Points") {
257 newSelector = new(nothrow) ImagePointFilterSelector(
258 *((ImagePointFilterSelector *) selector));
259 }
260 else {
261 if (*m_filterType == "Connections") {
262 newSelector = new(nothrow) ImageImageFilterSelector(
263 *((ImageImageFilterSelector *) selector));
264 }
265 }
266 }
267
268 if (newSelector) {
269 *newSelector = *selector;
270 newSelectors.append(newSelector);
271 }
272 }
273
274 // if all is ok, and it is safe to assign
275 if (newSelectors.size() == other.m_selectors->size()) {
276 foreach (AbstractFilterSelector * selector, *m_selectors) {
277 deleteSelector(selector);
278 }
279
280 foreach (AbstractFilterSelector * newSelector, newSelectors) {
281 addSelector(newSelector);
282 }
283
284 swap(*m_filterType, *other.m_filterType);
285 m_buttonGroup->button(other.m_buttonGroup->checkedId())->click();
286 }
287 else {
288 // clean up any temp groups
289 foreach (AbstractFilterSelector * newSelector, newSelectors) {
290 if (newSelector) {
291 delete newSelector;
292 newSelector = NULL;
293 }
294 }
295
296 IString msg = "Assignment of FilterGroup failed";
297 throw IException(IException::Programmer, msg, _FILEINFO_);
298 }
299
300 return *this;
301 }
302
303
304 QString FilterGroup::getDescription(
305 bool (AbstractFilter::*hasFilterMeth)() const,
306 QString(AbstractFilter::*descriptionMeth)() const) const {
307 QString description;
308
309 QList< AbstractFilterSelector * > selectorsWithFilters;
310 for (int i = 0; i < m_selectors->size(); i++)
311 if (m_selectors->at(i)->hasFilter(hasFilterMeth))
312 selectorsWithFilters.append(m_selectors->at(i));
313
314 int numFilters = selectorsWithFilters.size();
315
316 if (numFilters) {
317 QString logic = "<b> ";
318 if (m_andFiltersTogether)
319 logic += "and";
320 else
321 logic += "or";
322 logic += " </b>";
323
324 for (int i = 0; i < numFilters - 1; i++) {
325 description += selectorsWithFilters[i]->getDescription(descriptionMeth)
326 + logic;
327 }
328
329 description += selectorsWithFilters[numFilters - 1]->getDescription(
330 descriptionMeth);
331 }
332
333 return description;
334 }
335}
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16