9#include "FilterWidget.h"
13#include <QButtonGroup>
19#include <QRadioButton>
23#include "IException.h"
27#include "FilterGroup.h"
35 FilterWidget::FilterWidget(QString type) {
38 m_filterType =
new QString(type);
46 FilterWidget::FilterWidget(
const FilterWidget &other) {
49 m_filterType =
new QString(*other.m_filterType);
53 foreach (FilterGroup * group, *other.m_filterGroups) {
54 addGroup(
new FilterGroup(*group));
57 m_buttonGroup->button(other.m_buttonGroup->checkedId())->click();
63 FilterWidget::~FilterWidget() {
70 delete m_filterGroups;
71 m_filterGroups = NULL;
81 bool FilterWidget::evaluate(
const QPair<QString, ControlNet *> *imageAndNet)
const {
82 return evaluate(imageAndNet, &AbstractFilter::canFilterImages);
86 bool FilterWidget::evaluate(
const ControlPoint *point)
const {
87 return evaluate(point, &AbstractFilter::canFilterPoints);
91 bool FilterWidget::evaluate(
const ControlMeasure *measure)
const {
92 return evaluate(measure, &AbstractFilter::canFilterMeasures);
96 bool FilterWidget::hasFilter(
bool (AbstractFilter::*meth)() const) const {
99 for (
int i = 0; !found && i < m_filterGroups->size(); i++)
100 found = m_filterGroups->at(i)->hasFilter(meth);
106 FilterWidget &FilterWidget::operator=(FilterWidget other) {
109 QList< FilterGroup * > newGroups;
110 foreach (FilterGroup * group, *other.m_filterGroups) {
111 FilterGroup *newGroup =
new(nothrow) FilterGroup(*other.m_filterType);
114 newGroups.append(newGroup);
119 if (newGroups.size() == other.m_filterGroups->size()) {
120 foreach (FilterGroup * group, *m_filterGroups) {
124 foreach (FilterGroup * newGroup, newGroups) {
128 swap(*m_filterType, *other.m_filterType);
129 m_buttonGroup->button(other.m_buttonGroup->checkedId())->click();
133 foreach (FilterGroup * newGroup, newGroups) {
140 IString msg =
"Assignment of FilterWidget failed";
141 throw IException(IException::Programmer, msg, _FILEINFO_);
148 void FilterWidget::nullify() {
149 m_addGroupButton = NULL;
150 m_buttonGroup = NULL;
151 m_imageDescription = NULL;
152 m_pointDescription = NULL;
153 m_measureDescription = NULL;
155 m_filterGroups = NULL;
160 void FilterWidget::init() {
161 m_filterGroups =
new QList< FilterGroup * >;
163 QString whatsThis =
"<html>Filters are organized into groups (bounded by a box)."
164 " Filters within a group will be combined using either AND or OR "
165 "logic. Furthermore, multiple groups are supported, and the logic "
166 "used to combine the various groups is also configurable.<br/><br/>"
167 "For example, let A, B, and C be filters. By creating two "
168 "groups, one with A and B and the other with C, it is possible to "
169 "build the expression \"(A and B) or C\".<br/><br/>"
170 "Each group has a green plus (+) button, which adds a new filter to "
171 "the group. There is also a green plus (+) button outside any group "
172 "for adding a new group.</html>";
175 QString title =
"Filter " + *m_filterType;
176 QLabel *titleLabel =
new QLabel(title);
177 titleLabel->setFont(QFont(
"SansSerif", 15, QFont::DemiBold));
179 QHBoxLayout *titleLayout =
new QHBoxLayout;
180 titleLayout->addStretch();
181 titleLayout->addWidget(titleLabel);
182 titleLayout->addStretch();
184 QLabel *logicTypeLabel =
new QLabel(
"Combine groups using logic type: ");
185 QFont logicTypeLabelFont(
"SansSerif", 12);
186 logicTypeLabel->setFont(logicTypeLabelFont);
188 QFont logicTypeFont(
"SansSerif", 12, QFont::Bold);
189 QRadioButton *andButton =
new QRadioButton(
"AND");
190 andButton->setFont(logicTypeFont);
191 QRadioButton *orButton =
new QRadioButton(
"OR");
192 orButton->setFont(logicTypeFont);
193 m_buttonGroup =
new QButtonGroup;
194 m_buttonGroup->addButton(andButton, 0);
195 m_buttonGroup->addButton(orButton, 1);
196 connect(m_buttonGroup, SIGNAL(buttonClicked(
int)),
this,
197 SLOT(changeGroupCombinationLogic(
int)));
202 QHBoxLayout *buttonLayout =
new QHBoxLayout;
203 buttonLayout->addStretch();
204 buttonLayout->addWidget(logicTypeLabel);
205 buttonLayout->addWidget(andButton);
206 buttonLayout->addWidget(orButton);
207 buttonLayout->addStretch();
209 m_logicWidget->setLayout(buttonLayout);
211 m_addGroupButton =
new QPushButton;
212 m_addGroupButton->setIcon(QIcon(FileName(
"$ISISROOT/appdata/images/icons/add.png").expanded()));
213 QString addGroupTooltip =
"Add new filter group";
214 m_addGroupButton->setToolTip(addGroupTooltip);
215 m_addGroupButton->setStatusTip(addGroupTooltip);
216 m_addGroupButton->setWhatsThis(whatsThis);
217 connect(m_addGroupButton, SIGNAL(clicked()),
this, SLOT(addGroup()));
218 QHBoxLayout *addGroupLayout =
new QHBoxLayout;
219 addGroupLayout->addWidget(m_addGroupButton);
220 addGroupLayout->addStretch();
222 QLabel *titleDummy =
new QLabel;
223 titleDummy->setFont(QFont(
"SansSerif", 6));
225 m_imageDescription =
new QLabel;
226 m_imageDescription->setWordWrap(
true);
227 m_imageDescription->setFont(QFont(
"SansSerif", 10));
229 m_pointDescription =
new QLabel;
230 m_pointDescription->setWordWrap(
true);
231 m_pointDescription->setFont(QFont(
"SansSerif", 10));
233 m_measureDescription =
new QLabel;
234 m_measureDescription->setWordWrap(
true);
235 m_measureDescription->setFont(QFont(
"SansSerif", 10));
237 QVBoxLayout *descriptionLayout =
new QVBoxLayout;
238 descriptionLayout->addWidget(titleDummy);
239 descriptionLayout->addWidget(m_imageDescription);
240 descriptionLayout->addWidget(m_pointDescription);
241 descriptionLayout->addWidget(m_measureDescription);
243 connect(
this, SIGNAL(filterChanged()),
244 this, SLOT(updateDescription()));
246 m_mainLayout =
new QVBoxLayout;
247 m_mainLayout->addLayout(titleLayout);
248 m_mainLayout->addLayout(descriptionLayout);
249 m_mainLayout->addWidget(m_logicWidget);
250 m_mainLayout->addLayout(addGroupLayout);
251 m_mainLayout->addStretch();
253 setLayout(m_mainLayout);
254 setWhatsThis(whatsThis);
258 void FilterWidget::updateDescription() {
259 updateDescription(m_imageDescription, &AbstractFilter::canFilterImages,
260 &AbstractFilter::getImageDescription,
"images");
261 updateDescription(m_pointDescription, &AbstractFilter::canFilterPoints,
262 &AbstractFilter::getPointDescription,
"points");
263 updateDescription(m_measureDescription, &AbstractFilter::canFilterMeasures,
264 &AbstractFilter::getMeasureDescription,
"measures");
268 void FilterWidget::updateDescription(QLabel *label,
269 bool (AbstractFilter::*hasFilterMeth)() const,
270 QString(AbstractFilter::*descriptionMeth)() const,
276 QList< FilterGroup * > groups;
277 for (
int i = 0; i < m_filterGroups->size(); i++)
278 if (m_filterGroups->at(i)->hasFilter(hasFilterMeth))
279 groups.append(m_filterGroups->at(i));
281 const int GROUP_SIZE = groups.size();
284 QString black =
"<font color=black>";
285 QString blue =
"<font color=darkBlue>";
286 QString red =
"<font color=darkRed>";
287 QString end =
"</font>";
289 QString text =
"Showing " + red + title + end + black +
" which " + end;
292 if (m_andGroupsTogether)
293 groupLogic +=
" AND ";
295 groupLogic +=
" OR ";
297 QString leftParen = black +
"<b>(</b>" + end;
298 QString rightParen = black +
"<b>)</b>" + end;
300 for (
int i = 0; i < GROUP_SIZE - 1; i++) {
303 text += blue + groups[i]->getDescription(
304 hasFilterMeth, descriptionMeth) + end;
306 text += rightParen + black +
"<b>" + groupLogic +
"</b>" + end;
311 text += blue + groups[GROUP_SIZE - 1]->getDescription(
312 hasFilterMeth, descriptionMeth) + end;
316 text += black +
"." + end;
318 label->setText(text);
324 void FilterWidget::maybeScroll(FilterGroup *group) {
326 if (m_filterGroups && m_filterGroups->size() &&
327 m_filterGroups->at(m_filterGroups->size() - 1) == group)
328 emit scrollToBottom();
332 void FilterWidget::addGroup() {
333 FilterGroup *newGroup =
new FilterGroup(*m_filterType);
338 void FilterWidget::addGroup(FilterGroup *newGroup) {
339 connect(newGroup, SIGNAL(close(FilterGroup *)),
340 this, SLOT(deleteGroup(FilterGroup *)));
341 connect(newGroup, SIGNAL(filterChanged()),
this, SIGNAL(filterChanged()));
342 connect(newGroup, SIGNAL(sizeChanged(FilterGroup *)),
343 this, SLOT(maybeScroll(FilterGroup *)));
344 m_mainLayout->insertWidget(m_mainLayout->count() - 2, newGroup);
345 m_filterGroups->append(newGroup);
346 m_filterGroups->size() > 1 ? m_logicWidget->show() : m_logicWidget->hide();
348 emit scrollToBottom();
349 emit filterChanged();
353 void FilterWidget::deleteGroup(FilterGroup *filterGroup) {
354 m_mainLayout->removeWidget(filterGroup);
356 m_filterGroups->removeOne(filterGroup);
357 m_filterGroups->size() > 1 ? m_logicWidget->show() : m_logicWidget->hide();
358 emit filterChanged();
362 void FilterWidget::changeGroupCombinationLogic(
int button) {
363 m_andGroupsTogether = button == 0;
364 emit filterChanged();
This is free and unencumbered software released into the public domain.