|
Isis 3.0 Application Source Code Reference |
Home |
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 }