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