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