11 #include "FilterWidget.h"
15 #include <QButtonGroup>
16 #include <QHBoxLayout>
20 #include <QPushButton>
21 #include <QRadioButton>
23 #include <QVBoxLayout>
25 #include "IException.h"
29 #include "FilterGroup.h"
37 FilterWidget::FilterWidget(QString type) {
40 m_filterType =
new QString(type);
48 FilterWidget::FilterWidget(
const FilterWidget &other) {
51 m_filterType =
new QString(*other.m_filterType);
55 foreach (FilterGroup * group, *other.m_filterGroups) {
56 addGroup(
new FilterGroup(*group));
59 m_buttonGroup->button(other.m_buttonGroup->checkedId())->click();
65 FilterWidget::~FilterWidget() {
72 delete m_filterGroups;
73 m_filterGroups = NULL;
84 return evaluate(imageAndNet, &AbstractFilter::canFilterImages);
88 bool FilterWidget::evaluate(
const ControlPoint *point)
const {
89 return evaluate(point, &AbstractFilter::canFilterPoints);
93 bool FilterWidget::evaluate(
const ControlMeasure *measure)
const {
94 return evaluate(measure, &AbstractFilter::canFilterMeasures);
98 bool FilterWidget::hasFilter(
bool (AbstractFilter::*meth)()
const)
const {
101 for (
int i = 0; !found && i < m_filterGroups->size(); i++)
102 found = m_filterGroups->at(i)->hasFilter(meth);
108 FilterWidget &FilterWidget::operator=(FilterWidget other) {
109 ASSERT(m_filterType);
110 ASSERT(m_filterGroups);
111 ASSERT(m_buttonGroup);
115 foreach (FilterGroup * group, *other.m_filterGroups) {
116 FilterGroup *newGroup =
new(nothrow) FilterGroup(*other.m_filterType);
119 newGroups.append(newGroup);
124 if (newGroups.size() == other.m_filterGroups->size()) {
125 foreach (FilterGroup * group, *m_filterGroups) {
129 foreach (FilterGroup * newGroup, newGroups) {
133 swap(*m_filterType, *other.m_filterType);
134 m_buttonGroup->button(other.m_buttonGroup->checkedId())->click();
138 foreach (FilterGroup * newGroup, newGroups) {
145 IString msg =
"Assignment of FilterWidget failed";
153 void FilterWidget::nullify() {
154 m_addGroupButton = NULL;
155 m_buttonGroup = NULL;
156 m_imageDescription = NULL;
157 m_pointDescription = NULL;
158 m_measureDescription = NULL;
160 m_filterGroups = NULL;
165 void FilterWidget::init() {
168 QString whatsThis =
"<html>Filters are organized into groups (bounded by a box)."
169 " Filters within a group will be combined using either AND or OR "
170 "logic. Furthermore, multiple groups are supported, and the logic "
171 "used to combine the various groups is also configurable.<br/><br/>"
172 "For example, let A, B, and C be filters. By creating two "
173 "groups, one with A and B and the other with C, it is possible to "
174 "build the expression \"(A and B) or C\".<br/><br/>"
175 "Each group has a green plus (+) button, which adds a new filter to "
176 "the group. There is also a green plus (+) button outside any group "
177 "for adding a new group.</html>";
179 ASSERT(m_filterType);
181 QString title =
"Filter " + *m_filterType;
182 QLabel *titleLabel =
new QLabel(title);
183 titleLabel->setFont(QFont(
"SansSerif", 15, QFont::DemiBold));
185 QHBoxLayout *titleLayout =
new QHBoxLayout;
186 titleLayout->addStretch();
187 titleLayout->addWidget(titleLabel);
188 titleLayout->addStretch();
190 QLabel *logicTypeLabel =
new QLabel(
"Combine groups using logic type: ");
191 QFont logicTypeLabelFont(
"SansSerif", 12);
192 logicTypeLabel->setFont(logicTypeLabelFont);
194 QFont logicTypeFont(
"SansSerif", 12, QFont::Bold);
195 QRadioButton *andButton =
new QRadioButton(
"AND");
196 andButton->setFont(logicTypeFont);
197 QRadioButton *orButton =
new QRadioButton(
"OR");
198 orButton->setFont(logicTypeFont);
199 m_buttonGroup =
new QButtonGroup;
200 m_buttonGroup->addButton(andButton, 0);
201 m_buttonGroup->addButton(orButton, 1);
202 connect(m_buttonGroup, SIGNAL(buttonClicked(
int)),
this,
203 SLOT(changeGroupCombinationLogic(
int)));
208 QHBoxLayout *buttonLayout =
new QHBoxLayout;
209 buttonLayout->addStretch();
210 buttonLayout->addWidget(logicTypeLabel);
211 buttonLayout->addWidget(andButton);
212 buttonLayout->addWidget(orButton);
213 buttonLayout->addStretch();
215 m_logicWidget->setLayout(buttonLayout);
217 m_addGroupButton =
new QPushButton;
218 m_addGroupButton->setIcon(QIcon(FileName(
"$ISISROOT/appdata/images/icons/add.png").expanded()));
219 QString addGroupTooltip =
"Add new filter group";
220 m_addGroupButton->setToolTip(addGroupTooltip);
221 m_addGroupButton->setStatusTip(addGroupTooltip);
222 m_addGroupButton->setWhatsThis(whatsThis);
223 connect(m_addGroupButton, SIGNAL(clicked()),
this, SLOT(addGroup()));
224 QHBoxLayout *addGroupLayout =
new QHBoxLayout;
225 addGroupLayout->addWidget(m_addGroupButton);
226 addGroupLayout->addStretch();
228 QLabel *titleDummy =
new QLabel;
229 titleDummy->setFont(QFont(
"SansSerif", 6));
231 m_imageDescription =
new QLabel;
232 m_imageDescription->setWordWrap(
true);
233 m_imageDescription->setFont(QFont(
"SansSerif", 10));
235 m_pointDescription =
new QLabel;
236 m_pointDescription->setWordWrap(
true);
237 m_pointDescription->setFont(QFont(
"SansSerif", 10));
239 m_measureDescription =
new QLabel;
240 m_measureDescription->setWordWrap(
true);
241 m_measureDescription->setFont(QFont(
"SansSerif", 10));
243 QVBoxLayout *descriptionLayout =
new QVBoxLayout;
244 descriptionLayout->addWidget(titleDummy);
245 descriptionLayout->addWidget(m_imageDescription);
246 descriptionLayout->addWidget(m_pointDescription);
247 descriptionLayout->addWidget(m_measureDescription);
249 connect(
this, SIGNAL(filterChanged()),
250 this, SLOT(updateDescription()));
252 m_mainLayout =
new QVBoxLayout;
253 m_mainLayout->addLayout(titleLayout);
254 m_mainLayout->addLayout(descriptionLayout);
255 m_mainLayout->addWidget(m_logicWidget);
256 m_mainLayout->addLayout(addGroupLayout);
257 m_mainLayout->addStretch();
259 setLayout(m_mainLayout);
260 setWhatsThis(whatsThis);
264 void FilterWidget::updateDescription() {
265 updateDescription(m_imageDescription, &AbstractFilter::canFilterImages,
266 &AbstractFilter::getImageDescription,
"images");
267 updateDescription(m_pointDescription, &AbstractFilter::canFilterPoints,
268 &AbstractFilter::getPointDescription,
"points");
269 updateDescription(m_measureDescription, &AbstractFilter::canFilterMeasures,
270 &AbstractFilter::getMeasureDescription,
"measures");
274 void FilterWidget::updateDescription(QLabel *label,
275 bool (AbstractFilter::*hasFilterMeth)()
const,
276 QString(AbstractFilter::*descriptionMeth)()
const,
284 for (
int i = 0; i < m_filterGroups->size(); i++)
285 if (m_filterGroups->at(i)->hasFilter(hasFilterMeth))
286 groups.append(m_filterGroups->at(i));
288 const int GROUP_SIZE = groups.size();
291 QString black =
"<font color=black>";
292 QString blue =
"<font color=darkBlue>";
293 QString red =
"<font color=darkRed>";
294 QString end =
"</font>";
296 QString text =
"Showing " + red + title + end + black +
" which " + end;
299 if (m_andGroupsTogether)
300 groupLogic +=
" AND ";
302 groupLogic +=
" OR ";
304 QString leftParen = black +
"<b>(</b>" + end;
305 QString rightParen = black +
"<b>)</b>" + end;
307 for (
int i = 0; i < GROUP_SIZE - 1; i++) {
310 text += blue + groups[i]->getDescription(
311 hasFilterMeth, descriptionMeth) + end;
313 text += rightParen + black +
"<b>" + groupLogic +
"</b>" + end;
318 text += blue + groups[GROUP_SIZE - 1]->getDescription(
319 hasFilterMeth, descriptionMeth) + end;
323 text += black +
"." + end;
325 label->setText(text);
331 void FilterWidget::maybeScroll(FilterGroup *group) {
332 ASSERT(m_filterGroups);
333 ASSERT(m_filterGroups->size());
335 if (m_filterGroups && m_filterGroups->size() &&
336 m_filterGroups->at(m_filterGroups->size() - 1) == group)
337 emit scrollToBottom();
341 void FilterWidget::addGroup() {
342 FilterGroup *newGroup =
new FilterGroup(*m_filterType);
347 void FilterWidget::addGroup(FilterGroup *newGroup) {
348 connect(newGroup, SIGNAL(close(FilterGroup *)),
349 this, SLOT(deleteGroup(FilterGroup *)));
350 connect(newGroup, SIGNAL(filterChanged()),
this, SIGNAL(filterChanged()));
351 connect(newGroup, SIGNAL(sizeChanged(FilterGroup *)),
352 this, SLOT(maybeScroll(FilterGroup *)));
353 m_mainLayout->insertWidget(m_mainLayout->count() - 2, newGroup);
354 m_filterGroups->append(newGroup);
355 m_filterGroups->size() > 1 ? m_logicWidget->show() : m_logicWidget->hide();
357 emit scrollToBottom();
358 emit filterChanged();
362 void FilterWidget::deleteGroup(FilterGroup *filterGroup) {
363 m_mainLayout->removeWidget(filterGroup);
365 m_filterGroups->removeOne(filterGroup);
366 m_filterGroups->size() > 1 ? m_logicWidget->show() : m_logicWidget->hide();
367 emit filterChanged();
371 void FilterWidget::changeGroupCombinationLogic(
int button) {
372 m_andGroupsTogether = button == 0;
373 emit filterChanged();