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