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.