File indexing completed on 2025-06-29 04:09:19
0001 /*************************************************************************** 0002 * * 0003 * copyright : (C) 2007 The University of Toronto * 0004 * netterfield@astro.utoronto.ca * 0005 * * 0006 * This program is free software; you can redistribute it and/or modify * 0007 * it under the terms of the GNU General Public License as published by * 0008 * the Free Software Foundation; either version 2 of the License, or * 0009 * (at your option) any later version. * 0010 * * 0011 ***************************************************************************/ 0012 0013 #include "histogramdialog.h" 0014 0015 #include "dialogpage.h" 0016 #include "editmultiplewidget.h" 0017 0018 #include "histogram.h" 0019 0020 #include "view.h" 0021 #include "plotitem.h" 0022 #include "tabwidget.h" 0023 #include "mainwindow.h" 0024 #include "application.h" 0025 #include "plotrenderitem.h" 0026 #include "curve.h" 0027 #include "document.h" 0028 #include "objectstore.h" 0029 0030 #include "datacollection.h" 0031 #include "dialogdefaults.h" 0032 #include "updatemanager.h" 0033 0034 using namespace std; 0035 0036 namespace Kst { 0037 0038 HistogramTab::HistogramTab(QWidget *parent) 0039 : DataTab(parent), _normalizationDirty(false) { 0040 0041 setupUi(this); 0042 setTabTitle(tr("Histogram")); 0043 0044 connect(AutoBin, SIGNAL(clicked()), this, SLOT(generateAutoBin())); 0045 connect(_realTimeAutoBin, SIGNAL(clicked()), this, SLOT(updateButtons())); 0046 connect(_vector, SIGNAL(selectionChanged(QString)), this, SLOT(selectionChanged())); 0047 0048 connect(_vector, SIGNAL(selectionChanged(QString)), this, SIGNAL(modified())); 0049 connect(_min, SIGNAL(textChanged(QString)), this, SIGNAL(modified())); 0050 connect(_max, SIGNAL(textChanged(QString)), this, SIGNAL(modified())); 0051 connect(_numberOfBins, SIGNAL(valueChanged(int)), this, SIGNAL(modified())); 0052 connect(_realTimeAutoBin, SIGNAL(clicked()), this, SIGNAL(modified())); 0053 connect(_normalizationIsNumber, SIGNAL(clicked()), this, SIGNAL(modified())); 0054 connect(_normalizationIsFraction, SIGNAL(clicked()), this, SIGNAL(modified())); 0055 connect(_normalizationIsPercent, SIGNAL(clicked()), this, SIGNAL(modified())); 0056 connect(_normalizationMaximumOne, SIGNAL(clicked()), this, SIGNAL(modified())); 0057 connect(_normalizationIsNumber, SIGNAL(clicked()), this, SLOT(normalizationChanged())); 0058 connect(_normalizationIsFraction, SIGNAL(clicked()), this, SLOT(normalizationChanged())); 0059 connect(_normalizationIsPercent, SIGNAL(clicked()), this, SLOT(normalizationChanged())); 0060 connect(_normalizationMaximumOne, SIGNAL(clicked()), this, SLOT(normalizationChanged())); 0061 connect(_curvePlacement->_noPlot, SIGNAL(toggled(bool)), _curveAppearance, SLOT(setDisabled(bool))); 0062 0063 _vectorLabel->setBuddy(_vector->_vector); 0064 0065 _curvePlacement->setExistingPlots(Data::self()->plotList()); 0066 0067 _curveAppearance->loadWidgetDefaults(); 0068 0069 _curveAppearance->setShowLines(false); 0070 _curveAppearance->setShowPoints(false); 0071 _curveAppearance->setShowHead(false); 0072 _curveAppearance->setShowBars(true); 0073 _curveAppearance->setPointDensity(0); 0074 _curveAppearance->setColor(dialogDefaults().value("plot/strokeBrushColor",QColor(Qt::black)).value<QColor>()); 0075 0076 } 0077 0078 0079 HistogramTab::~HistogramTab() { 0080 } 0081 0082 0083 void HistogramTab::normalizationChanged() { 0084 _normalizationDirty = true; 0085 } 0086 0087 0088 void HistogramTab::resetNormalizationDirty() { 0089 _normalizationDirty = false; 0090 } 0091 0092 0093 void HistogramTab::selectionChanged() { 0094 emit vectorChanged(); 0095 } 0096 0097 0098 void HistogramTab::generateAutoBin() { 0099 0100 VectorPtr selectedVector = vector(); 0101 0102 if (selectedVector) { 0103 selectedVector->readLock(); // Hmm should we really lock here? AutoBin should I think 0104 int n; 0105 double max, min; 0106 Histogram::AutoBin(selectedVector, &n, &max, &min); 0107 selectedVector->unlock(); 0108 0109 _numberOfBins->setValue(n); 0110 _min->setText(QString::number(min)); 0111 _max->setText(QString::number(max)); 0112 } 0113 } 0114 0115 0116 void HistogramTab::updateButtons() { 0117 if (_realTimeAutoBin->isChecked()) { 0118 generateAutoBin(); 0119 } 0120 0121 _min->setEnabled(!_realTimeAutoBin->isChecked()); 0122 _max->setEnabled(!_realTimeAutoBin->isChecked()); 0123 _numberOfBins->setEnabled(!_realTimeAutoBin->isChecked()); 0124 AutoBin->setEnabled(!_realTimeAutoBin->isChecked()); 0125 } 0126 0127 0128 VectorPtr HistogramTab::vector() const { 0129 return _vector->selectedVector(); 0130 } 0131 0132 0133 bool HistogramTab::vectorDirty() const { 0134 return _vector->selectedVectorDirty(); 0135 } 0136 0137 0138 void HistogramTab::setVector(const VectorPtr vector) { 0139 _vector->setSelectedVector(vector); 0140 } 0141 0142 0143 double HistogramTab::min() const { 0144 return _min->text().toDouble(); 0145 } 0146 0147 0148 bool HistogramTab::minDirty() const { 0149 return !_min->text().isEmpty(); 0150 } 0151 0152 0153 void HistogramTab::setMin(const double min) { 0154 _min->setText(QString::number(min)); 0155 } 0156 0157 0158 double HistogramTab::max() const { 0159 return _max->text().toDouble(); 0160 } 0161 0162 0163 bool HistogramTab::maxDirty() const { 0164 return !_max->text().isEmpty(); 0165 } 0166 0167 0168 void HistogramTab::setMax(const double max) { 0169 _max->setText(QString::number(max)); 0170 } 0171 0172 0173 int HistogramTab::bins() const { 0174 return _numberOfBins->text().toInt(); 0175 } 0176 0177 0178 bool HistogramTab::binsDirty() const { 0179 return !_numberOfBins->text().isEmpty(); 0180 } 0181 0182 0183 void HistogramTab::setBins(const int bins) { 0184 _numberOfBins->setValue(bins); 0185 } 0186 0187 0188 bool HistogramTab::realTimeAutoBin() const { 0189 return _realTimeAutoBin->isChecked(); 0190 } 0191 0192 0193 bool HistogramTab::realTimeAutoBinDirty() const { 0194 return _realTimeAutoBin->checkState() != Qt::PartiallyChecked; 0195 } 0196 0197 0198 void HistogramTab::setRealTimeAutoBin(const bool autoBin) { 0199 _realTimeAutoBin->setChecked(autoBin); 0200 } 0201 0202 0203 Histogram::NormalizationType HistogramTab::normalizationType() const { 0204 Histogram::NormalizationType normalization = Histogram::Number; 0205 0206 if (_normalizationIsFraction->isChecked()) { 0207 normalization = Histogram::Fraction; 0208 } else if (_normalizationIsPercent->isChecked()) { 0209 normalization = Histogram::Percent; 0210 } else if (_normalizationMaximumOne->isChecked()) { 0211 normalization = Histogram::MaximumOne; 0212 } 0213 return normalization; 0214 } 0215 0216 0217 bool HistogramTab::normalizationTypeDirty() const { 0218 return _normalizationDirty; 0219 } 0220 0221 0222 void HistogramTab::setNormalizationType(const Histogram::NormalizationType normalizationType) { 0223 switch (normalizationType) { 0224 case Histogram::Fraction: 0225 _normalizationIsFraction->setChecked(true); 0226 break; 0227 case Histogram::MaximumOne: 0228 _normalizationMaximumOne->setChecked(true); 0229 break; 0230 case Histogram::Number: 0231 _normalizationIsNumber->setChecked(true); 0232 break; 0233 case Histogram::Percent: 0234 _normalizationIsPercent->setChecked(true); 0235 break; 0236 } 0237 resetNormalizationDirty(); 0238 } 0239 0240 0241 0242 CurveAppearance* HistogramTab::curveAppearance() const { 0243 return _curveAppearance; 0244 } 0245 0246 0247 CurvePlacement* HistogramTab::curvePlacement() const { 0248 return _curvePlacement; 0249 } 0250 0251 0252 void HistogramTab::setObjectStore(ObjectStore *store) { 0253 _vector->setObjectStore(store); 0254 } 0255 0256 0257 void HistogramTab::hideCurveOptions() { 0258 _curvePlacement->setVisible(false); 0259 _curveAppearance->setVisible(false); 0260 } 0261 0262 0263 void HistogramTab::clearTabValues() { 0264 _vector->clearSelection(); 0265 _min->clear(); 0266 _max->clear(); 0267 _numberOfBins->clear(); 0268 _realTimeAutoBin->setCheckState(Qt::PartiallyChecked); 0269 _normalizationIsNumber->setChecked(true); 0270 resetNormalizationDirty(); 0271 } 0272 0273 0274 HistogramDialog::HistogramDialog(ObjectPtr dataObject, QWidget *parent) 0275 : DataDialog(dataObject, parent) { 0276 0277 if (editMode() == Edit) 0278 setWindowTitle(tr("Edit Histogram")); 0279 else 0280 setWindowTitle(tr("New Histogram")); 0281 0282 _histogramTab = new HistogramTab(this); 0283 addDataTab(_histogramTab); 0284 0285 if (editMode() == Edit) { 0286 configureTab(dataObject); 0287 } else { 0288 configureTab(0); 0289 } 0290 0291 connect(_histogramTab, SIGNAL(vectorChanged()), this, SLOT(updateButtons())); 0292 connect(this, SIGNAL(editMultipleMode()), this, SLOT(editMultipleMode())); 0293 connect(this, SIGNAL(editSingleMode()), this, SLOT(editSingleMode())); 0294 0295 connect(_histogramTab, SIGNAL(modified()), this, SLOT(modified())); 0296 updateButtons(); 0297 } 0298 0299 0300 HistogramDialog::~HistogramDialog() { 0301 } 0302 0303 0304 // QString HistogramDialog::tagString() const { 0305 // return DataDialog::tagString(); 0306 // } 0307 0308 0309 void HistogramDialog::editMultipleMode() { 0310 _histogramTab->clearTabValues(); 0311 } 0312 0313 0314 void HistogramDialog::editSingleMode() { 0315 configureTab(dataObject()); 0316 } 0317 0318 0319 void HistogramDialog::configureTab(ObjectPtr object) { 0320 if (!object) { 0321 _histogramTab->setRealTimeAutoBin(dialogDefaults().value("histogram/realTimeAutoBin", false).toBool()); 0322 _histogramTab->setNormalizationType(Histogram::NormalizationType(dialogDefaults().value("histogram/normalizationType",Histogram::Number).toInt())); 0323 } else if (HistogramPtr histogram = kst_cast<Histogram>(object)) { 0324 _histogramTab->setVector(histogram->vector()); 0325 _histogramTab->setMin(histogram->xMin()); 0326 _histogramTab->setMax(histogram->xMax()); 0327 _histogramTab->setBins(histogram->numberOfBins()); 0328 _histogramTab->setRealTimeAutoBin(histogram->realTimeAutoBin()); 0329 _histogramTab->setNormalizationType(histogram->normalizationType()); 0330 _histogramTab->hideCurveOptions(); 0331 if (_editMultipleWidget) { 0332 HistogramList objects = _document->objectStore()->getObjects<Histogram>(); 0333 _editMultipleWidget->clearObjects(); 0334 foreach(HistogramPtr object, objects) { 0335 _editMultipleWidget->addObject(object->Name(), object->descriptionTip()); 0336 } 0337 } 0338 } 0339 } 0340 0341 0342 void HistogramDialog::updateButtons() { 0343 _buttonBox->button(QDialogButtonBox::Ok)->setEnabled(dialogValid()); 0344 } 0345 0346 0347 bool HistogramDialog::dialogValid() const { 0348 return _histogramTab->vectorSelected() || (editMode() == EditMultiple); 0349 } 0350 0351 0352 void HistogramDialog::setVector(VectorPtr vector) { 0353 _histogramTab->setVector(vector); 0354 } 0355 0356 0357 ObjectPtr HistogramDialog::createNewDataObject() { 0358 Q_ASSERT(_document && _document->objectStore()); 0359 0360 HistogramPtr histogram = _document->objectStore()->createObject<Histogram>(); 0361 0362 histogram->change(_histogramTab->vector(), _histogramTab->min(), _histogramTab->max(), 0363 _histogramTab->bins(), _histogramTab->normalizationType(), 0364 _histogramTab->realTimeAutoBin()); 0365 0366 if (DataDialog::tagStringAuto()) { 0367 histogram->setDescriptiveName(QString()); 0368 } else { 0369 histogram->setDescriptiveName(DataDialog::tagString()); 0370 } 0371 0372 histogram->writeLock(); 0373 histogram->registerChange(); 0374 histogram->unlock(); 0375 0376 setHistogramDefaults(histogram); 0377 0378 CurvePtr curve = _document->objectStore()->createObject<Curve>(); 0379 0380 curve->setXVector(histogram->vX()); 0381 curve->setYVector(histogram->vY()); 0382 curve->setColor(_histogramTab->curveAppearance()->color()); 0383 curve->setHeadColor(_histogramTab->curveAppearance()->headColor()); 0384 curve->setBarFillColor(_histogramTab->curveAppearance()->barFillColor()); 0385 curve->setHasPoints(_histogramTab->curveAppearance()->showPoints()); 0386 curve->setHasLines(_histogramTab->curveAppearance()->showLines()); 0387 curve->setHasBars(_histogramTab->curveAppearance()->showBars()); 0388 curve->setHasHead(_histogramTab->curveAppearance()->showHead()); 0389 curve->setLineWidth(_histogramTab->curveAppearance()->lineWidth()); 0390 curve->setPointSize(_histogramTab->curveAppearance()->pointSize()); 0391 curve->setLineStyle(_histogramTab->curveAppearance()->lineStyle()); 0392 curve->setPointType(_histogramTab->curveAppearance()->pointType()); 0393 curve->setHeadType(_histogramTab->curveAppearance()->headType()); 0394 curve->setPointDensity(_histogramTab->curveAppearance()->pointDensity()); 0395 0396 curve->writeLock(); 0397 curve->registerChange(); 0398 curve->unlock(); 0399 0400 if(editMode()==New) { 0401 PlotItem *plotItem = 0; 0402 switch (_histogramTab->curvePlacement()->place()) { 0403 case CurvePlacement::NoPlot: 0404 break; 0405 case CurvePlacement::ExistingPlot: 0406 { 0407 plotItem = static_cast<PlotItem*>(_histogramTab->curvePlacement()->existingPlot()); 0408 break; 0409 } 0410 case CurvePlacement::NewPlotNewTab: 0411 _document->createView(); 0412 // fall through to case NewPlot. 0413 case CurvePlacement::NewPlot: 0414 { 0415 CreatePlotForCurve *cmd = new CreatePlotForCurve(); 0416 cmd->createItem(); 0417 0418 plotItem = static_cast<PlotItem*>(cmd->item()); 0419 if (_histogramTab->curvePlacement()->scaleFonts()) { 0420 plotItem->view()->resetPlotFontSizes(plotItem); 0421 plotItem->view()->configurePlotFontDefaults(plotItem); // copy plots already in window 0422 } 0423 break; 0424 } 0425 default: 0426 break; 0427 } 0428 0429 if (_histogramTab->curvePlacement()->place() != CurvePlacement::NoPlot) { 0430 PlotRenderItem *renderItem = plotItem->renderItem(PlotRenderItem::Cartesian); 0431 renderItem->addRelation(kst_cast<Relation>(curve)); 0432 plotItem->update(); 0433 0434 if (_histogramTab->curvePlacement()->place() != CurvePlacement::ExistingPlot) { 0435 plotItem->view()->appendToLayout(_histogramTab->curvePlacement()->layout(), plotItem, _histogramTab->curvePlacement()->gridColumns()); 0436 if (_histogramTab->curvePlacement()->layout() == CurvePlacement::Custom) { 0437 plotItem->createCustomLayout(_histogramTab->curvePlacement()->gridColumns()); 0438 } 0439 } 0440 } 0441 } 0442 0443 return ObjectPtr(histogram.data()); 0444 } 0445 0446 0447 ObjectPtr HistogramDialog::editExistingDataObject() const { 0448 if (HistogramPtr histogram = kst_cast<Histogram>(dataObject())) { 0449 if (editMode() == EditMultiple) { 0450 QStringList objects = _editMultipleWidget->selectedObjects(); 0451 foreach (const QString &objectName, objects) { 0452 HistogramPtr histogram = kst_cast<Histogram>(_document->objectStore()->retrieveObject(objectName)); 0453 if (histogram) { 0454 VectorPtr vector = _histogramTab->vectorDirty() ? _histogramTab->vector() : histogram->vector(); 0455 const double min = _histogramTab->minDirty() ? _histogramTab->min() : histogram->xMin(); 0456 const double max = _histogramTab->maxDirty() ? _histogramTab->max() : histogram->xMax(); 0457 const int bins = _histogramTab->binsDirty() ? _histogramTab->bins() : histogram->numberOfBins(); 0458 Histogram::NormalizationType normalizationType = _histogramTab->normalizationTypeDirty() ? _histogramTab->normalizationType() : histogram->normalizationType(); 0459 const bool realTimeAutoBin = _histogramTab->realTimeAutoBinDirty() ? _histogramTab->realTimeAutoBin() : histogram->realTimeAutoBin(); 0460 0461 histogram->writeLock(); 0462 histogram->setVector(vector); 0463 histogram->setXRange(min, max); 0464 histogram->setNumberOfBins(bins); 0465 histogram->setNormalizationType(normalizationType); 0466 histogram->setRealTimeAutoBin(realTimeAutoBin); 0467 0468 histogram->unlock(); 0469 0470 histogram->registerChange(); 0471 } 0472 } 0473 } else { 0474 histogram->writeLock(); 0475 histogram->setVector(_histogramTab->vector()); 0476 histogram->setXRange(_histogramTab->min(), _histogramTab->max()); 0477 histogram->setNumberOfBins(_histogramTab->bins()); 0478 histogram->setNormalizationType(_histogramTab->normalizationType()); 0479 histogram->setRealTimeAutoBin(_histogramTab->realTimeAutoBin()); 0480 if (DataDialog::tagStringAuto()) { 0481 histogram->setDescriptiveName(QString()); 0482 } else { 0483 histogram->setDescriptiveName(DataDialog::tagString()); 0484 } 0485 0486 histogram->unlock(); 0487 0488 histogram->registerChange(); 0489 setHistogramDefaults(histogram); 0490 } 0491 } 0492 return dataObject(); 0493 } 0494 0495 } 0496 0497 // vim: ts=2 sw=2 et