File indexing completed on 2024-12-22 04:17:31

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 "equationdialog.h"
0014 
0015 #include "dialogpage.h"
0016 #include "editmultiplewidget.h"
0017 
0018 #include "datacollection.h"
0019 #include "equation.h"
0020 #include "plotitem.h"
0021 #include "plotrenderitem.h"
0022 #include "curve.h"
0023 #include "document.h"
0024 #include "objectstore.h"
0025 #include "updatemanager.h"
0026 #include "updateserver.h"
0027 #include "dialogdefaults.h"
0028 #include "vector.h"
0029 
0030 #include <QPushButton>
0031 
0032 namespace Kst {
0033 
0034 QString EquationDialog::_lastXVectorName;
0035 
0036 EquationTab::EquationTab(QWidget *parent)
0037   : DataTab(parent) {
0038 
0039   setupUi(this);
0040 
0041   populateFunctionList();
0042 
0043   setTabTitle(tr("Equation"));
0044 
0045   _curvePlacement->setExistingPlots(Data::self()->plotList());
0046 
0047   _xVectors->setIsX(true);
0048 
0049   TextLabel1_11->setBuddy(_equation);
0050   _xVectorLabel->setBuddy(_xVectors->_vector);
0051   connect(_xVectors, SIGNAL(selectionChanged(QString)), this, SLOT(selectionChanged()));
0052   connect(_equation, SIGNAL(textChanged(QString)), this, SLOT(selectionChanged()));
0053 
0054   //connect(_xVectors, SIGNAL(contentChanged()), this, SLOT(updateVectorCombos()));
0055 
0056   connect(_xVectors, SIGNAL(selectionChanged(QString)), this, SIGNAL(modified()));
0057   connect(_equation, SIGNAL(textChanged(QString)), this, SIGNAL(modified()));
0058   connect(_doInterpolation, SIGNAL(clicked()), this, SIGNAL(modified()));
0059   connect(_curvePlacement->_noPlot, SIGNAL(toggled(bool)), _curveAppearance, SLOT(setDisabled(bool)));
0060   connect(UpdateServer::self(), SIGNAL(objectListsChanged()), this->_equation, SLOT(fillKstObjects()));
0061 
0062 }
0063 
0064 
0065 EquationTab::~EquationTab() {
0066 }
0067 
0068 
0069 void EquationTab::selectionChanged() {
0070   emit optionsChanged();
0071 }
0072 
0073 
0074 void EquationTab::equationUpdate(const QString& string) {
0075   QString cleanString = string;
0076   cleanString.remove('[').remove(']'); // HACK: '[' in descriptive names mess up parser.  Remove them.
0077   _equation->insert('[' + cleanString + ']');
0078 }
0079 
0080 
0081 void EquationTab::equationOperatorUpdate(const QString& string) {
0082   QString equation = _equation->text();
0083   equation += string;
0084   _equation->setText(equation); 
0085 }
0086 
0087 
0088 void EquationTab::populateFunctionList() {
0089   QList<QString> Operators;
0090   Operators.clear();
0091   Operators.push_back("+");
0092   Operators.push_back("-");
0093   Operators.push_back("*");
0094   Operators.push_back("/");
0095   Operators.push_back("%");
0096   Operators.push_back("^");
0097   Operators.push_back("&");
0098   Operators.push_back("|");
0099   Operators.push_back("&&");
0100   Operators.push_back("||");
0101   Operators.push_back("!");
0102   Operators.push_back("<");
0103   Operators.push_back("<=");
0104   Operators.push_back("==");
0105   Operators.push_back(">=");
0106   Operators.push_back(">");
0107   Operators.push_back("!=");
0108   Operators.push_back("STEP()");
0109   Operators.push_back("ABS()");
0110   Operators.push_back("SQRT()");
0111   Operators.push_back("CBRT()");
0112   Operators.push_back("SIN()");
0113   Operators.push_back("SIND()");
0114   Operators.push_back("COS()");
0115   Operators.push_back("COSD()");
0116   Operators.push_back("TAN()");
0117   Operators.push_back("TAND()");
0118   Operators.push_back("ASIN()");
0119   Operators.push_back("ASIND()");
0120   Operators.push_back("ACOS()");
0121   Operators.push_back("ACOSD()");
0122   Operators.push_back("ATAN()");
0123   Operators.push_back("ATAND()");
0124   Operators.push_back("ATAN2()");
0125   Operators.push_back("SEC()");
0126   Operators.push_back("SECD()");
0127   Operators.push_back("CSC()");
0128   Operators.push_back("CSCD()");
0129   Operators.push_back("COT()");
0130   Operators.push_back("COTD()");
0131   Operators.push_back("SINH()");
0132   Operators.push_back("COSH()");
0133   Operators.push_back("TANH()");
0134   Operators.push_back("EXP()");
0135   Operators.push_back("LN()");
0136   Operators.push_back("LOG()");
0137   Operators.push_back("PLUGIN()");
0138 
0139   QList<CompletionCase> data;
0140   data.push_back(CompletionCase(""));
0141   data.back().push_back(Category("Operators"));
0142   data.push_back(CompletionCase(""));
0143   data.back().push_back(Category("Functions"));
0144   for(int i=0;i<Operators.count();i++) {
0145       data[Operators.at(i).contains("()")?1:0][0]<<Operators.at(i);
0146   }
0147   for(int i=0;i<data[1][0].size();i++) {
0148       data[1][0][i].chop(1);
0149   }
0150   data.push_back(CompletionCase("\\["));    //block escaped brackets
0151   _equation->init(data);
0152 
0153 }
0154 
0155 
0156 VectorPtr EquationTab::xVector() const {
0157   return _xVectors->selectedVector();
0158 }
0159 
0160 
0161 bool EquationTab::xVectorDirty() const {
0162   return _xVectors->selectedVectorDirty();
0163 }
0164 
0165 
0166 void EquationTab::setXVector(VectorPtr vector) {
0167   _xVectors->setSelectedVector(vector);
0168 }
0169 
0170 
0171 QString EquationTab::equation() const {
0172   return _equation->text();
0173 }
0174 
0175 
0176 bool EquationTab::equationDirty() const {
0177   return (!_equation->text().isEmpty());
0178 }
0179 
0180 
0181 void EquationTab::setToLastX(Document *document, QString lastXVName) {
0182   QString x_name = lastXVName;
0183   VectorPtr xv = kst_cast<Vector>(document->objectStore()->retrieveObject(x_name, false));
0184 
0185   if (xv) {
0186     setXVector(xv);
0187   } else{
0188     _xVectors->setToLastX();
0189   }
0190 }
0191 
0192 
0193 void EquationTab::setEquation(const QString &equation) {
0194   _equation->setText(equation);
0195 }
0196 
0197 
0198 bool EquationTab::doInterpolation() const {
0199   return _doInterpolation->isChecked();
0200 }
0201 
0202 
0203 bool EquationTab::doInterpolationDirty() const {
0204   return _doInterpolation->checkState() != Qt::PartiallyChecked;
0205 }
0206 
0207 
0208 void EquationTab::setDoInterpolation(bool doInterpolation) {
0209   _doInterpolation->setChecked(doInterpolation);
0210 }
0211 
0212 
0213 CurveAppearance* EquationTab::curveAppearance() const {
0214   return _curveAppearance;
0215 }
0216 
0217 
0218 CurvePlacement* EquationTab::curvePlacement() const {
0219   return _curvePlacement;
0220 }
0221 
0222 
0223 void EquationTab::setObjectStore(ObjectStore *store) {
0224   _equation->setObjectStore(store);
0225   _xVectors->setObjectStore(store);
0226 }
0227 
0228 
0229 void EquationTab::hideCurveOptions() {
0230   _curvePlacement->setVisible(false);
0231   _curveAppearance->setVisible(false);
0232 }
0233 
0234 
0235 void EquationTab::clearTabValues() {
0236   _xVectors->clearSelection();
0237   _equation->clear();
0238   _doInterpolation->setCheckState(Qt::PartiallyChecked);
0239 }
0240 
0241 
0242 void EquationTab::updateVectorCombos() {
0243   _xVectors->fillVectors();
0244   _equation->fillKstObjects();
0245 }
0246 
0247 EquationDialog::EquationDialog(ObjectPtr dataObject, QWidget *parent)
0248   : DataDialog(dataObject, parent) {
0249 
0250   if (editMode() == Edit)
0251     setWindowTitle(tr("Edit Equation"));
0252   else
0253     setWindowTitle(tr("New Equation"));
0254 
0255   _equationTab = new EquationTab(this);
0256   addDataTab(_equationTab);
0257 
0258   _equationTab->setEquation("");
0259 
0260   if (editMode() == Edit) {
0261     configureTab(dataObject);
0262   } else {
0263     configureTab(0);
0264   }
0265 
0266   connect(_equationTab, SIGNAL(optionsChanged()), this, SLOT(updateButtons()));
0267   connect(this, SIGNAL(editMultipleMode()), this, SLOT(editMultipleMode()));
0268   connect(this, SIGNAL(editSingleMode()), this, SLOT(editSingleMode()));
0269 
0270   connect(_equationTab, SIGNAL(modified()), this, SLOT(modified()));
0271   updateButtons();
0272 
0273 }
0274 
0275 
0276 EquationDialog::~EquationDialog() {
0277 }
0278 
0279 
0280 // QString EquationDialog::tagString() const {
0281 //   return DataDialog::tagString();
0282 // }
0283 
0284 
0285 void EquationDialog::editMultipleMode() {
0286   _equationTab->clearTabValues();
0287 }
0288 
0289 
0290 void EquationDialog::editSingleMode() {
0291    configureTab(dataObject());
0292 }
0293 
0294 
0295 void EquationDialog::updateButtons() {
0296   _buttonBox->button(QDialogButtonBox::Ok)->setEnabled(dialogValid());
0297 }
0298 
0299 
0300 bool EquationDialog::dialogValid() const {
0301   bool valid = (_equationTab->xVectorSelected()) || (editMode() == EditMultiple);
0302   return (valid);
0303 }
0304 
0305 void EquationDialog::configureTab(ObjectPtr object) {
0306   if (!object) {
0307     _equationTab->curveAppearance()->loadWidgetDefaults();
0308     _equationTab->setToLastX(_document, _lastXVectorName);
0309   } else if (EquationPtr equation = kst_cast<Equation>(object)) {
0310     _equationTab->setXVector(equation->vXIn());
0311     _equationTab->setEquation(equation->equation());
0312     _equationTab->setDoInterpolation(equation->doInterp());
0313     _equationTab->hideCurveOptions();
0314     if (_editMultipleWidget) {
0315       EquationList objects = _document->objectStore()->getObjects<Equation>();
0316       _editMultipleWidget->clearObjects();
0317       foreach(EquationPtr object, objects) {
0318         _editMultipleWidget->addObject(object->Name(), object->descriptionTip());
0319       }
0320     }
0321   }
0322 }
0323 
0324 
0325 ObjectPtr EquationDialog::createNewDataObject() {
0326   Q_ASSERT(_document && _document->objectStore());
0327 
0328   EquationPtr equation = _document->objectStore()->createObject<Equation>();
0329   Q_ASSERT(equation);
0330 
0331   equation->setEquation(_equationTab->equation());
0332   equation->setExistingXVector(_equationTab->xVector(), _equationTab->doInterpolation());
0333   if (DataDialog::tagStringAuto()) {
0334      equation->setDescriptiveName(QString());
0335   } else {
0336      equation->setDescriptiveName(DataDialog::tagString());
0337   }
0338 
0339   equation->writeLock();
0340   equation->registerChange();
0341   equation->unlock();
0342 
0343   CurvePtr curve = _document->objectStore()->createObject<Curve>();
0344   Q_ASSERT(curve);
0345 
0346   curve->setXVector(equation->vX());
0347   curve->setYVector(equation->vY());
0348   curve->setColor(_equationTab->curveAppearance()->color());
0349   curve->setHeadColor(_equationTab->curveAppearance()->headColor());
0350   curve->setHasPoints(_equationTab->curveAppearance()->showPoints());
0351   curve->setHasLines(_equationTab->curveAppearance()->showLines());
0352   curve->setHasBars(_equationTab->curveAppearance()->showBars());
0353   curve->setHasHead(_equationTab->curveAppearance()->showHead());
0354   curve->setLineWidth(_equationTab->curveAppearance()->lineWidth());
0355   curve->setPointSize(_equationTab->curveAppearance()->pointSize());
0356   curve->setLineStyle(_equationTab->curveAppearance()->lineStyle());
0357   curve->setPointType(_equationTab->curveAppearance()->pointType());
0358   curve->setHeadType(_equationTab->curveAppearance()->headType());
0359   curve->setPointDensity(_equationTab->curveAppearance()->pointDensity());
0360   //curve->setBarStyle(_equationTab->curveAppearance()->barStyle());
0361 
0362   curve->writeLock();
0363   curve->registerChange();
0364   curve->unlock();
0365 
0366   _equationTab->curveAppearance()->setWidgetDefaults(true);
0367   _lastXVectorName =  equation->vXIn()->Name();
0368 
0369   if(editMode()==New) {
0370       PlotItem *plotItem = 0;
0371       switch (_equationTab->curvePlacement()->place()) {
0372       case CurvePlacement::NoPlot:
0373           break;
0374       case CurvePlacement::ExistingPlot:
0375       {
0376           plotItem = static_cast<PlotItem*>(_equationTab->curvePlacement()->existingPlot());
0377           break;
0378       }
0379       case CurvePlacement::NewPlotNewTab:
0380           _document->createView();
0381           // fall through to case NewPlot.
0382       case CurvePlacement::NewPlot:
0383       {
0384           CreatePlotForCurve *cmd = new CreatePlotForCurve();
0385           cmd->createItem();
0386 
0387           plotItem = static_cast<PlotItem*>(cmd->item());
0388           if (_equationTab->curvePlacement()->scaleFonts()) {
0389               plotItem->view()->resetPlotFontSizes(plotItem);
0390               plotItem->view()->configurePlotFontDefaults(plotItem); // copy plots already in window
0391           }
0392           break;
0393       }
0394       default:
0395           break;
0396       }
0397 
0398       if (_equationTab->curvePlacement()->place() != CurvePlacement::NoPlot) {
0399           PlotRenderItem *renderItem = plotItem->renderItem(PlotRenderItem::Cartesian);
0400           renderItem->addRelation(kst_cast<Relation>(curve));
0401           plotItem->update();
0402 
0403           if (_equationTab->curvePlacement()->place() != CurvePlacement::ExistingPlot) {
0404               plotItem->view()->appendToLayout(_equationTab->curvePlacement()->layout(), plotItem, _equationTab->curvePlacement()->gridColumns());
0405               if (_equationTab->curvePlacement()->layout() == CurvePlacement::Custom) {
0406                 plotItem->createCustomLayout(_equationTab->curvePlacement()->gridColumns());
0407               }
0408           }
0409       }
0410   }
0411 
0412   return ObjectPtr(equation.data());
0413 }
0414 
0415 
0416 ObjectPtr EquationDialog::editExistingDataObject() const {
0417   if (EquationPtr equation = kst_cast<Equation>(dataObject())) {
0418     if (editMode() == EditMultiple) {
0419       QStringList objects = _editMultipleWidget->selectedObjects();
0420       foreach (const QString &objectName, objects) {
0421         EquationPtr equation = kst_cast<Equation>(_document->objectStore()->retrieveObject(objectName));
0422         if (equation) {
0423           VectorPtr xVector = _equationTab->xVectorDirty() ? _equationTab->xVector() : equation->vXIn();
0424           const QString equationString = _equationTab->equationDirty() ? _equationTab->equation() : equation->equation();
0425           const bool doInterpolation = _equationTab->doInterpolationDirty() ?  _equationTab->doInterpolation() : equation->doInterp();
0426 
0427           equation->writeLock();
0428           equation->setEquation(equationString);
0429           equation->setExistingXVector(xVector, doInterpolation);
0430 
0431           equation->registerChange();
0432           equation->unlock();
0433         }
0434       }
0435       if (_equationTab->xVectorDirty()) {
0436         _lastXVectorName = _equationTab->xVector()->Name();
0437       }
0438     } else {
0439       equation->writeLock();
0440       equation->setEquation(_equationTab->equation());
0441       equation->setExistingXVector(_equationTab->xVector(), _equationTab->doInterpolation());
0442       if (DataDialog::tagStringAuto()) {
0443          equation->setDescriptiveName(QString());
0444       } else {
0445          equation->setDescriptiveName(DataDialog::tagString());
0446       }
0447       equation->registerChange();
0448       equation->unlock();
0449       _lastXVectorName = equation->vXIn()->Name();
0450     }
0451   }
0452 
0453   return dataObject();
0454 }
0455 
0456 }
0457 
0458 // vim: ts=2 sw=2 et