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