USGS

Isis 3.0 Application Source Code Reference

Home

AbstractFilter.cpp

Go to the documentation of this file.
00001 #include "IsisDebug.h"
00002 
00003 #include <iostream>
00004 #include <limits>
00005 
00006 #include "AbstractFilter.h"
00007 
00008 #include <QAction>
00009 #include <QAbstractButton>
00010 #include <QButtonGroup>
00011 #include <QCheckBox>
00012 #include <QFlags>
00013 #include <QHBoxLayout>
00014 #include <QLabel>
00015 #include <QMargins>
00016 #include <QMenu>
00017 #include <QMenuBar>
00018 #include <QRadioButton>
00019 #include <QSpinBox>
00020 #include <QString>
00021 #include <QVBoxLayout>
00022 #include <QWriteLocker>
00023 
00024 #include "ControlCubeGraphNode.h"
00025 #include "ControlMeasure.h"
00026 #include "ControlPoint.h"
00027 
00028 #include "AbstractFilterSelector.h"
00029 
00030 
00031 using std::cerr;
00032 
00033 
00034 
00035 namespace Isis
00036 {
00037   namespace CnetViz
00038   {
00039     AbstractFilter::AbstractFilter(FilterEffectivenessFlag effectiveness,
00040         int minimumForSuccess)
00041     {
00042       nullify();
00043 
00044       minForSuccess = minimumForSuccess;
00045 
00046       effectivenessFlags = new FilterEffectivenessFlag(effectiveness);
00047 
00048       smallFont = new QFont("SansSerif", 9);
00049 
00050       createWidget();
00051     }
00052 
00053 
00054     AbstractFilter::AbstractFilter(const AbstractFilter & other)
00055     {
00056       nullify();
00057 
00058       minForSuccess = other.minForSuccess;
00059 
00060       effectivenessFlags = new FilterEffectivenessFlag(*other.effectivenessFlags);
00061 
00062       smallFont = new QFont(*other.smallFont);
00063 
00064       createWidget();
00065 
00066       inclusiveExclusiveGroup->button(
00067         other.inclusiveExclusiveGroup->checkedId())->click();
00068     }
00069 
00070 
00071     AbstractFilter::~AbstractFilter()
00072     {
00073       delete effectivenessFlags;
00074       effectivenessFlags = NULL;
00075 
00076       delete inclusiveExclusiveGroup;
00077       inclusiveExclusiveGroup = NULL;
00078 
00079       delete smallFont;
00080       smallFont = NULL;
00081     }
00082 
00083 
00084     bool AbstractFilter::canFilterImages() const
00085     {
00086       return effectivenessFlags->testFlag(Images);
00087     }
00088 
00089 
00090     bool AbstractFilter::canFilterPoints() const
00091     {
00092       return effectivenessFlags->testFlag(Points);
00093     }
00094 
00095 
00096     bool AbstractFilter::canFilterMeasures() const
00097     {
00098       return effectivenessFlags->testFlag(Measures);
00099     }
00100 
00101 
00102     QString AbstractFilter::getImageDescription() const
00103     {
00104       return "have at least " + QString::number(getMinForSuccess()) + " ";
00105     }
00106 
00107 
00108     QString AbstractFilter::getPointDescription() const
00109     {
00110       return QString();
00111     }
00112 
00113 
00114     QString AbstractFilter::getMeasureDescription() const
00115     {
00116       return QString();
00117     }
00118 
00119 
00120     void AbstractFilter::nullify()
00121     {
00122       effectivenessGroup = NULL;
00123       inclusiveExclusiveGroup = NULL;
00124       inclusiveExclusiveLayout = NULL;
00125       mainLayout = NULL;
00126       minWidget = NULL;
00127       effectivenessFlags = NULL;
00128       smallFont = NULL;
00129     }
00130 
00131 
00132     void AbstractFilter::createWidget()
00133     {
00134       QRadioButton * inclusiveButton = new QRadioButton("Inclusive");
00135       inclusiveButton->setFont(*smallFont);
00136       QRadioButton * exclusiveButton = new QRadioButton("Exclusive");
00137       exclusiveButton->setFont(*smallFont);
00138 
00139       inclusiveExclusiveGroup = new QButtonGroup;
00140       connect(inclusiveExclusiveGroup, SIGNAL(buttonClicked(int)),
00141           this, SIGNAL(filterChanged()));
00142       inclusiveExclusiveGroup->addButton(inclusiveButton, 0);
00143       inclusiveExclusiveGroup->addButton(exclusiveButton, 1);
00144 
00145       inclusiveExclusiveLayout = new QHBoxLayout;
00146       QMargins margins = inclusiveExclusiveLayout->contentsMargins();
00147       margins.setTop(0);
00148       margins.setBottom(0);
00149       inclusiveExclusiveLayout->setContentsMargins(margins);
00150       inclusiveExclusiveLayout->addWidget(inclusiveButton);
00151       inclusiveExclusiveLayout->addWidget(exclusiveButton);
00152 
00153       QHBoxLayout * controlsLayout = new QHBoxLayout;
00154       margins = controlsLayout->contentsMargins();
00155       margins.setTop(0);
00156       margins.setBottom(0);
00157       controlsLayout->setContentsMargins(margins);
00158 
00159       controlsLayout->addLayout(inclusiveExclusiveLayout);
00160 
00161       effectivenessGroup = new QButtonGroup();
00162       effectivenessGroup->setExclusive(false);
00163 
00164       if (effectivenessFlags->testFlag(Images))
00165         effectivenessGroup->addButton(
00166             createEffectivenessCheckBox("&Images"), 0);
00167 
00168       if (effectivenessFlags->testFlag(Points))
00169         effectivenessGroup->addButton(
00170             createEffectivenessCheckBox("&Points"), 1);
00171 
00172       if (effectivenessFlags->testFlag(Measures))
00173         effectivenessGroup->addButton(
00174             createEffectivenessCheckBox("&Measures"), 2);
00175 
00176       QString firstGroupEntry;
00177       ASSERT(effectivenessGroup->buttons().size());
00178       if (effectivenessGroup->buttons().size())
00179       {
00180         firstGroupEntry = effectivenessGroup->buttons()[0]->text();
00181         firstGroupEntry.remove(0, 1);
00182       }
00183 
00184       QList<QAbstractButton *> buttons = effectivenessGroup->buttons();
00185       if (effectivenessGroup->buttons().size() >= 2)
00186       {
00187         QHBoxLayout * effectivenessLayout = new QHBoxLayout;
00188         QMargins effectivenessMargins = effectivenessLayout->contentsMargins();
00189         effectivenessMargins.setTop(0);
00190         effectivenessMargins.setBottom(0);
00191         effectivenessLayout->setContentsMargins(effectivenessMargins);
00192 
00193         for (int i = 0; i < buttons.size(); i++)
00194           effectivenessLayout->addWidget(buttons[i]);
00195 
00196         controlsLayout->addLayout(effectivenessLayout);
00197       }
00198       else
00199       {
00200         for (int i = 0; i < buttons.size(); i++)
00201           delete buttons[i];
00202         delete effectivenessGroup;
00203         effectivenessGroup = NULL;
00204       }
00205 
00206       if (minForSuccess != -1)
00207       {
00208         QLabel * label = new QLabel;
00209         label->setText(
00210             "<span>Min Count<br/>for " + firstGroupEntry + "</span>");
00211         label->setFont(QFont("SansSerif", 7));
00212         QSpinBox * spinBox = new QSpinBox;
00213         spinBox->setRange(1, std::numeric_limits< int >::max());
00214         spinBox->setValue(1);  // FIXME: QSettings should handle this
00215         connect(spinBox, SIGNAL(valueChanged(int)),
00216             this, SLOT(updateMinForSuccess(int)));
00217         QHBoxLayout * minLayout = new QHBoxLayout;
00218         margins = minLayout->contentsMargins();
00219         margins.setTop(0);
00220         margins.setBottom(0);
00221         minLayout->setContentsMargins(margins);
00222         minLayout->addWidget(label);
00223         minLayout->addWidget(spinBox);
00224         minWidget = new QWidget;
00225         minWidget->setLayout(minLayout);
00226 
00227         controlsLayout->addWidget(minWidget);
00228         controlsLayout->setAlignment(minWidget, Qt::AlignTop);
00229         minWidget->setVisible(true); // FIXME: QSettings should handle this
00230       }
00231 
00232       controlsLayout->addStretch();
00233 
00234       mainLayout = new QVBoxLayout;
00235       margins = mainLayout->contentsMargins();
00236       margins.setTop(0);
00237       margins.setBottom(0);
00238       mainLayout->setContentsMargins(margins);
00239       mainLayout->addLayout(controlsLayout);
00240 
00241 
00242       setLayout(mainLayout);
00243 
00244       // FIXME: QSettings should handle this
00245       inclusiveButton->click();
00246     }
00247 
00248 
00249     QCheckBox * AbstractFilter::createEffectivenessCheckBox(QString text)
00250     {
00251       QCheckBox * checkBox = new QCheckBox(text, this);
00252       checkBox->setChecked(true);
00253       checkBox->setFont(*smallFont);
00254       connect(checkBox, SIGNAL(toggled(bool)),
00255               this, SLOT(updateEffectiveness()));
00256       connect(checkBox, SIGNAL(toggled(bool)), this, SIGNAL(filterChanged()));
00257       return checkBox;
00258     }
00259 
00260 
00261     bool AbstractFilter::inclusive() const
00262     {
00263       return inclusiveExclusiveGroup->checkedId() == 0;
00264     }
00265 
00266 
00267     AbstractFilter::FilterEffectivenessFlag *
00268     AbstractFilter::getEffectivenessFlags() const
00269     {
00270       return effectivenessFlags;
00271     }
00272 
00273 
00274     QBoxLayout * AbstractFilter::getMainLayout() const
00275     {
00276       ASSERT(mainLayout);
00277 
00278       return mainLayout;
00279     }
00280 
00281 
00282     QBoxLayout * AbstractFilter::getInclusiveExclusiveLayout() const
00283     {
00284       ASSERT(inclusiveExclusiveLayout);
00285 
00286       return inclusiveExclusiveLayout;
00287     }
00288 
00289 
00290     bool AbstractFilter::evaluateFromCount(QList< ControlMeasure * > measures,
00291         bool usePoints) const
00292     {
00293       int passedCount = 0;
00294 
00295       foreach(ControlMeasure * measure, measures)
00296       {
00297         ASSERT(measure);
00298 
00299         if (usePoints)
00300         {
00301           ControlPoint * point = measure->Parent();
00302           ASSERT(point);
00303           if (point && evaluate(point))
00304             passedCount++;
00305         }
00306         else
00307         {
00308           if (measure && evaluate(measure))
00309             passedCount++;
00310         }
00311       }
00312 
00313       return passedCount >= getMinForSuccess();
00314     }
00315 
00316 
00317     bool AbstractFilter::evaluateImageFromPointFilter(
00318       const ControlCubeGraphNode * node) const
00319     {
00320       ASSERT(node);
00321 
00322       bool evaluation = true;
00323 
00324       if (canFilterImages())
00325         evaluation = evaluateFromCount(node->getMeasures(), true);
00326 
00327       return evaluation;
00328     }
00329 
00330 
00331     bool AbstractFilter::evaluateImageFromMeasureFilter(
00332       const ControlCubeGraphNode * node) const
00333     {
00334       ASSERT(node);
00335 
00336       bool evaluation = true;
00337 
00338       if (canFilterImages())
00339         evaluation = evaluateFromCount(node->getMeasures(), false);
00340 
00341       return evaluation;
00342     }
00343 
00344 
00345     bool AbstractFilter::evaluatePointFromMeasureFilter(
00346       const ControlPoint * point) const
00347     {
00348       ASSERT(point);
00349 
00350       bool evaluation = true;
00351 
00352       if (canFilterPoints())
00353         evaluation = evaluateFromCount(point->getMeasures(), false);
00354 
00355       return evaluation;
00356     }
00357 
00358 
00359     bool AbstractFilter::evaluate(const ControlPoint * point,
00360         bool (ControlPoint::*meth)() const) const
00361     {
00362       ASSERT(point);
00363 
00364       return !((point->*meth)() ^ inclusive());
00365     }
00366 
00367 
00368     bool AbstractFilter::evaluate(const ControlMeasure * measure,
00369         bool (ControlMeasure::*meth)() const) const
00370     {
00371       ASSERT(measure);
00372 
00373       return !((measure->*meth)() ^ inclusive());
00374     }
00375 
00376 
00377     void AbstractFilter::updateEffectiveness()
00378     {
00379       ASSERT(effectivenessGroup);
00380 
00381       if (effectivenessGroup)
00382       {
00383         FilterEffectivenessFlag newFlags;
00384 
00385         QList< QAbstractButton * > buttons = effectivenessGroup->buttons();
00386 
00387         if (minWidget)
00388           minWidget->setVisible(false);
00389 
00390         for (int i = 0; i < buttons.size(); i++)
00391         {
00392           if (buttons[i]->isChecked())
00393           {
00394             if (buttons[i]->text() == "&Images")
00395               newFlags |= Images;
00396             else
00397               if (buttons[i]->text() == "&Points")
00398                 newFlags |= Points;
00399               else
00400                 if (buttons[i]->text() == "&Measures")
00401                   newFlags |= Measures;
00402 
00403             if (i == 0 && minWidget)
00404               minWidget->setVisible(true);
00405           }
00406         }
00407 
00408         *effectivenessFlags = newFlags;
00409       }
00410     }
00411 
00412 
00413     void AbstractFilter::updateMinForSuccess(int newMin)
00414     {
00415       minForSuccess = newMin;
00416       emit filterChanged();
00417     }
00418   }
00419 }