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 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 }