USGS

Isis 3.0 Object Programmers' Reference

Home

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