Warning, file /education/khipu/src/plotseditor.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /************************************************************************************* 0002 * Copyright (C) 2010-2014 by Percy Camilo T. Aucahuasi <percy.camilo.ta@gmail.com> * 0003 * * 0004 * This program is free software; you can redistribute it and/or * 0005 * modify it under the terms of the GNU General Public License * 0006 * as published by the Free Software Foundation; either version 2 * 0007 * of the License, or (at your option) any later version. * 0008 * * 0009 * This program is distributed in the hope that it will be useful, * 0010 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0012 * GNU General Public License for more details. * 0013 * * 0014 * You should have received a copy of the GNU General Public License * 0015 * along with this program; if not, write to the Free Software * 0016 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 0017 *************************************************************************************/ 0018 0019 #include "plotseditor.h" 0020 #include "ui_plotseditor.h" 0021 0022 //Analitza includes 0023 #include <analitza/analyzer.h> 0024 #include <analitza/expression.h> 0025 #include <analitza/variables.h> 0026 #include <analitza/value.h> 0027 #include <analitzagui/expressionedit.h> 0028 #include <analitzagui/algebrahighlighter.h> 0029 #include <analitzagui/variablesmodel.h> 0030 #include <analitzaplot/functiongraph.h> 0031 #include <analitzaplot/planecurve.h> 0032 #include <analitzaplot/plotsmodel.h> 0033 #include <analitzaplot/spacecurve.h> 0034 #include <analitzaplot/surface.h> 0035 #include <analitzaplot/plotsfactory.h> 0036 0037 //Qt includes 0038 #include <QStringListModel> 0039 #include <QPushButton> 0040 #include <qstyleditemdelegate.h> 0041 #include <QPainter> 0042 0043 //KDE includes 0044 #include <KRandom> 0045 0046 #include <cmath> 0047 0048 //local includes 0049 #include "datastore.h" 0050 #include "spacesmodel.h" 0051 #include "spaceplotsproxymodel.h" 0052 #include "spaceitem.h" 0053 0054 using namespace Analitza; 0055 0056 PlotsEditor::PlotsEditor(QWidget * parent) 0057 : QDockWidget(parent), isEditing(false), plotnumber(1) 0058 { 0059 m_widget = new Ui::PlotsEditorWidget; 0060 m_widget->setupUi(this); 0061 setObjectName("adasdds"); 0062 0063 // random coloring of the plots 0064 m_widget->plotColor->setColor(randomFunctionColor()); 0065 0066 m_widget->focusPlot->setToolTip(i18n("check/uncheck to show/hide the Axes")); 0067 m_widget->focusPlot->setChecked(true); 0068 0069 m_widget->editPlot->setToolTip(i18n("Click to edit the plot")); 0070 m_widget->removePlot->setToolTip(i18n("Click to remove the plot")); 0071 0072 // no bounding by default 0073 m_widget->intervals->setChecked(false); 0074 0075 connect(m_widget->fnameForGraphs, SIGNAL(currentIndexChanged(QString)), SLOT(setCurrentFunctionGraphs(QString))); 0076 0077 m_widget->farrow->setText("="); 0078 m_widget->garrow->setText("="); 0079 m_widget->harrow->setText("="); 0080 0081 connect(m_widget->builderDialogBox->button(QDialogButtonBox::Cancel), SIGNAL(pressed()), SLOT(showList())); 0082 connect(m_widget->editorDialogBox->button(QDialogButtonBox::Cancel), SIGNAL(pressed()), SLOT(cancelEditor())); 0083 connect(m_widget->editorDialogBox->button(QDialogButtonBox::Ok), SIGNAL(pressed()), SLOT(savePlot())); 0084 0085 m_widget->builder->mapConnection(PlotsBuilder::CartesianGraphCurve, this, SLOT(buildCartesianGraphCurve())); 0086 m_widget->builder->mapConnection(PlotsBuilder::CartesianImplicitCurve, this, SLOT(buildCartesianImplicitCurve())); 0087 m_widget->builder->mapConnection(PlotsBuilder::CartesianParametricCurve2D, this, SLOT(buildCartesianParametricCurve2D())); 0088 m_widget->builder->mapConnection(PlotsBuilder::PolarGraphCurve, this, SLOT(buildPolarGraphCurve())); 0089 m_widget->builder->mapConnection(PlotsBuilder::CartesianParametricCurve3D, this, SLOT(buildCartesianParametricCurve3D())); 0090 m_widget->builder->mapConnection(PlotsBuilder::CartesianGraphSurface, this, SLOT(buildCartesianGraphSurface())); 0091 m_widget->builder->mapConnection(PlotsBuilder::CartesianImplicitSurface, this, SLOT(buildCartesianImplicitSurface())); 0092 m_widget->builder->mapConnection(PlotsBuilder::CartesianParametricSurface, this, SLOT(buildCartesianParametricSurface())); 0093 m_widget->builder->mapConnection(PlotsBuilder::CylindricalGraphSurface, this, SLOT(buildCylindricalGraphSurface())); 0094 m_widget->builder->mapConnection(PlotsBuilder::SphericalGraphSurface, this, SLOT(buildSphericalGraphSurface())); 0095 0096 connect(m_widget->addPlots, SIGNAL(pressed()), SLOT(addPlots())); 0097 connect(m_widget->editPlot, SIGNAL(pressed()), SLOT(editPlot())); 0098 connect(m_widget->plotsView, SIGNAL(doubleClicked(QModelIndex)), SLOT(editPlot())); 0099 connect(m_widget->removePlot, SIGNAL(pressed()), SLOT(removePlot())); 0100 connect(m_widget->focusPlot,SIGNAL(stateChanged(int)),SLOT(showAxis(int))); 0101 connect(m_widget->plotnamecheck,SIGNAL(toggled(bool)),SLOT(plotnamecheckClicked(bool))); 0102 0103 this->installEventFilter(this); 0104 m_widget->f->installEventFilter(this); 0105 plotnamecheckClicked(false); 0106 } 0107 0108 bool PlotsEditor::eventFilter(QObject*, QEvent *event) 0109 { 0110 if(event->type() == QEvent::KeyPress) 0111 { 0112 QKeyEvent *key = static_cast<QKeyEvent *>(event); 0113 if(key->key() == Qt::Key_Enter || key->key() == Qt::Key_Return) 0114 { 0115 savePlot(); 0116 m_widget->plotnamecheck->setChecked(false); 0117 } 0118 } 0119 return false; 0120 } 0121 0122 PlotsEditor::~PlotsEditor() 0123 { 0124 delete m_widget; 0125 } 0126 0127 void PlotsEditor::setDocument(DataStore* doc) 0128 { 0129 m_document = doc; 0130 m_widget->plotsView->setModel(m_document->currentPlots()); 0131 m_widget->plotsView->setSelectionModel(m_document->currentSelectionModel()); 0132 } 0133 0134 void PlotsEditor::setCurrentSpace(int spaceidx) 0135 { 0136 switch (m_document->spacesModel()->space(spaceidx)->dimension()) 0137 { 0138 case Dim2D: 0139 { 0140 m_widget->builder->setupTypes(PlotsBuilder::CartesianGraphCurve | 0141 PlotsBuilder::CartesianImplicitCurve | PlotsBuilder::CartesianParametricCurve2D | 0142 PlotsBuilder::PolarGraphCurve); 0143 m_widget->styleWidget->hide(); 0144 break; 0145 } 0146 case Dim3D: 0147 { 0148 m_widget->builder->setupTypes(PlotsBuilder::CartesianParametricCurve3D | PlotsBuilder::CartesianGraphSurface | 0149 PlotsBuilder::CartesianImplicitSurface | PlotsBuilder::CartesianParametricSurface | PlotsBuilder::CylindricalGraphSurface | 0150 PlotsBuilder::SphericalGraphSurface); 0151 m_widget->styleWidget->show(); 0152 break; 0153 } 0154 default: 0155 break; 0156 } 0157 } 0158 0159 void PlotsEditor::reset(bool clearBuilder) 0160 { 0161 //clear widgets 0162 m_widget->plotName->clear(); 0163 m_widget->plotnamecheck->setChecked(false); 0164 m_widget->plotColor->setColor(randomFunctionColor()); 0165 0166 m_widget->f->clear(); 0167 m_widget->g->clear(); 0168 m_widget->h->clear(); 0169 m_widget->minx->clear(); 0170 m_widget->maxx->clear(); 0171 m_widget->miny->clear(); 0172 m_widget->maxy->clear(); 0173 m_widget->minz->clear(); 0174 m_widget->maxz->clear(); 0175 0176 //reset widgets 0177 m_widget->widgets->setCurrentIndex(0); 0178 0179 if (clearBuilder) 0180 m_widget->builder->hideAllTypes(); 0181 0182 //focus 0183 m_widget->plotName->setFocus(); 0184 } 0185 0186 void PlotsEditor::showList() 0187 { 0188 m_widget->widgets->setCurrentIndex(0); 0189 } 0190 0191 void PlotsEditor::showTypes() 0192 { 0193 m_widget->widgets->setCurrentIndex(1); 0194 } 0195 0196 void PlotsEditor::showEditor() 0197 { 0198 /// clear actions 0199 m_widget->widgets->setCurrentIndex(2); 0200 0201 /// force right focus 0202 // while editing the plot , it is very likely that user needs to change the expression. 0203 m_widget->f->setFocus(); 0204 } 0205 0206 void PlotsEditor::cancelEditor() 0207 { 0208 if (isEditing) 0209 { 0210 showList(); 0211 isEditing = false; 0212 return; 0213 } 0214 if (m_cancelIsGoHome) 0215 { 0216 emit goHome(); 0217 m_document->removeCurrentSpace(); 0218 } 0219 else 0220 showTypes(); 0221 } 0222 0223 void PlotsEditor::showAxis(int state) 0224 { 0225 if (state==0) { 0226 if(m_document->spacesModel()->space(m_document->currentSpace())->dimension()==Dim2D) 0227 emit updateGridcolor(QColor(255,255,255)); // Axis willnot be visible when the color will be white. 0228 else 0229 emit updateGridcolor(QColor(Qt::black)); // Axis willnot be visible when the color will be black. 0230 } 0231 else if (state==2) { 0232 if(m_document->spacesModel()->space(m_document->currentSpace())->dimension()==Dim2D) 0233 emit updateGridcolor(QColor(230,230,230)); // Axis will be visible when the color will be grey. 0234 else 0235 emit updateGridcolor(QColor(Qt::darkGray)); // Axis will be visible when the color will be darkGrey. 0236 } 0237 } 0238 0239 void PlotsEditor::addPlots() 0240 { 0241 m_cancelIsGoHome = false; 0242 showTypes(); 0243 } 0244 0245 void PlotsEditor::editPlot(const QModelIndex &) 0246 { 0247 // comes when double clicked on the items in the list shown with checkbox.! 0248 isEditing = true; 0249 0250 reset(); 0251 0252 // while editing the plot , it is very likely that user needs to change the expression. 0253 m_widget->f->setFocus(); 0254 0255 if (m_widget->plotsView->selectionModel()->hasSelection()) // may be the plotsview is different .!!! 0256 { 0257 QModelIndex index = m_widget->plotsView->selectionModel()->currentIndex(); 0258 PlotItem* item = index.data(PlotsModel::PlotRole).value<PlotItem*>(); 0259 0260 m_widget->plotColor->setColor(item->color()); 0261 m_widget->plotName->setText(item->name()); 0262 0263 if (dynamic_cast<PlaneCurve*>(item)) 0264 { 0265 PlaneCurve *curve = dynamic_cast<PlaneCurve*>(item); 0266 0267 if (Expression(curve->display()).isEquation()) // implicit 0268 { 0269 m_widget->f->setExpression(Expression(curve->display())); 0270 buildCartesianImplicitCurve(); 0271 0272 if (curve->hasIntervals()) 0273 { 0274 QPair<Analitza::Expression, Analitza::Expression> interval = curve->interval(curve->parameters().at(1), false); 0275 0276 m_widget->miny->setExpression(interval.first); 0277 m_widget->maxy->setExpression(interval.second); 0278 } 0279 } 0280 else if (curve->expression().lambdaBody().isVector()) //vectorvalued 0281 { 0282 m_widget->f->setExpression(curve->expression().lambdaBody().elementAt(0)); 0283 m_widget->g->setExpression(curve->expression().lambdaBody().elementAt(1)); 0284 0285 buildCartesianParametricCurve2D(); 0286 } 0287 else //graph 0288 { 0289 m_widget->f->setExpression(curve->expression().lambdaBody()); 0290 0291 if (curve->parameters().first() == "q") 0292 { 0293 buildPolarGraphCurve(); 0294 } 0295 else 0296 { 0297 buildCartesianGraphCurve(); 0298 0299 if (curve->parameters().first() == "x") 0300 { 0301 m_currentVars = QStringList() << "x"; 0302 m_widget->fnameForGraphs->hide(); 0303 setupFuncName(1, "y", QStringList() << "x"); 0304 setupVarName(1, "x"); 0305 m_widget->fname->show(); 0306 } 0307 else if (curve->parameters().first() == "y") 0308 { 0309 m_currentVars = QStringList() << "y"; 0310 m_widget->fnameForGraphs->hide(); 0311 setupFuncName(1, "x", QStringList() << "y"); 0312 setupVarName(1, "y"); 0313 m_widget->fname->show(); 0314 } 0315 } 0316 } 0317 0318 if (curve->hasIntervals()) 0319 { 0320 QPair<Analitza::Expression, Analitza::Expression> interval = curve->interval(curve->parameters().first(), false); 0321 0322 m_widget->minx->setExpression(interval.first); 0323 m_widget->maxx->setExpression(interval.second); 0324 } 0325 } 0326 else if (dynamic_cast<SpaceCurve*>(item)) 0327 { 0328 SpaceCurve *curve = dynamic_cast<SpaceCurve*>(item); 0329 0330 m_widget->f->setExpression(curve->expression().lambdaBody().elementAt(0)); 0331 m_widget->g->setExpression(curve->expression().lambdaBody().elementAt(1)); 0332 m_widget->h->setExpression(curve->expression().lambdaBody().elementAt(2)); 0333 0334 buildCartesianParametricCurve3D(); 0335 0336 0337 if (curve->hasIntervals()) 0338 { 0339 QPair<Analitza::Expression, Analitza::Expression> interval = curve->interval(curve->parameters().first(), false); 0340 0341 m_widget->minx->setExpression(interval.first); 0342 m_widget->maxx->setExpression(interval.second); 0343 } 0344 } 0345 else if (dynamic_cast<Surface*>(item)) 0346 { 0347 Surface *surface = dynamic_cast<Surface*>(item); 0348 0349 if (Expression(surface->display()).isEquation()) // implicit 0350 { 0351 m_widget->f->setExpression(Expression(surface->display())); 0352 0353 buildCartesianImplicitSurface(); 0354 0355 if (surface->hasIntervals()) 0356 { 0357 QPair<Analitza::Expression, Analitza::Expression> interval = surface->interval(surface->parameters().at(2), false); 0358 0359 m_widget->minz->setExpression(interval.first); 0360 m_widget->maxz->setExpression(interval.second); 0361 } 0362 } 0363 else if (surface->expression().lambdaBody().isVector()) //vectorvalued 0364 { 0365 m_widget->f->setExpression(surface->expression().lambdaBody().elementAt(0)); 0366 m_widget->g->setExpression(surface->expression().lambdaBody().elementAt(1)); 0367 m_widget->h->setExpression(surface->expression().lambdaBody().elementAt(2)); 0368 0369 buildCartesianParametricSurface(); 0370 } 0371 else //graph 0372 { 0373 m_widget->f->setExpression(surface->expression().lambdaBody()); 0374 0375 if (surface->parameters() == QStringList() << "r" << "p") 0376 buildCylindricalGraphSurface(); 0377 else if (surface->parameters() == QStringList() << "t" << "p") 0378 buildSphericalGraphSurface(); 0379 else 0380 { 0381 buildCartesianGraphSurface(); 0382 0383 if (surface->parameters() == QStringList() << "x" << "y") 0384 { 0385 m_currentVars = QStringList() << "x" << "y"; 0386 m_widget->fnameForGraphs->hide(); 0387 setupFuncName(1, "z", QStringList() << "x" << "y"); 0388 setupVarName(1, "x"); 0389 setupVarName(2, "y"); 0390 m_widget->fname->show(); 0391 } 0392 else if (surface->parameters() == QStringList() << "x" << "z") 0393 { 0394 m_currentVars = QStringList() << "x" << "z"; 0395 m_widget->fnameForGraphs->hide(); 0396 setupFuncName(1, "y", QStringList() << "x" << "z"); 0397 setupVarName(1, "x"); 0398 setupVarName(2, "z"); 0399 m_widget->fname->show(); 0400 } 0401 else if (surface->parameters() == QStringList() << "y" << "z") 0402 { 0403 m_currentVars = QStringList() << "y" << "z"; 0404 m_widget->fnameForGraphs->hide(); 0405 setupFuncName(1, "x", QStringList() << "y" << "z"); 0406 setupVarName(1, "y"); 0407 setupVarName(2, "z"); 0408 m_widget->fname->show(); 0409 } 0410 } 0411 } 0412 0413 if (surface->hasIntervals()) 0414 { 0415 QPair<Analitza::Expression, Analitza::Expression> interval = surface->interval(surface->parameters().first(), false); 0416 0417 m_widget->minx->setExpression(interval.first); 0418 m_widget->maxx->setExpression(interval.second); 0419 0420 interval = surface->interval(surface->parameters().at(1), false); 0421 0422 m_widget->miny->setExpression(interval.first); 0423 m_widget->maxy->setExpression(interval.second); 0424 } 0425 } 0426 } 0427 } 0428 0429 void PlotsEditor::buildCartesianGraphCurve(bool cancelIsGoHome) 0430 { 0431 if (!isEditing) 0432 reset(); 0433 0434 m_cancelIsGoHome = cancelIsGoHome; 0435 0436 m_currentType = PlotsBuilder::CartesianGraphCurve; 0437 0438 m_widget->plotIcon->setPixmap(QIcon::fromTheme("newfunction").pixmap(16, 16)); 0439 0440 setupExpressionType(QStringList() << "x" << "y", QStringList() << "x"); 0441 0442 m_widget->minx->setExpression(Analitza::Expression(Analitza::Cn(-5))); 0443 m_widget->maxx->setExpression(Analitza::Expression(Analitza::Cn(5))); 0444 } 0445 0446 void PlotsEditor::buildCartesianImplicitCurve(bool cancelIsGoHome) 0447 { 0448 if (!isEditing) 0449 reset(); 0450 0451 m_cancelIsGoHome = cancelIsGoHome; 0452 0453 m_currentType = PlotsBuilder::CartesianImplicitCurve; 0454 0455 m_widget->plotIcon->setPixmap(QIcon::fromTheme("newimplicit").pixmap(16, 16)); 0456 0457 setupExpressionType(QStringList(), QStringList() << "x" << "y", true); 0458 0459 m_widget->minx->setExpression(Analitza::Expression(Analitza::Cn(-5))); 0460 m_widget->maxx->setExpression(Analitza::Expression(Analitza::Cn(5))); 0461 0462 m_widget->miny->setExpression(Analitza::Expression(Analitza::Cn(-5))); 0463 m_widget->maxy->setExpression(Analitza::Expression(Analitza::Cn(5))); 0464 } 0465 0466 void PlotsEditor::buildCartesianParametricCurve2D(bool cancelIsGoHome) 0467 { 0468 if (!isEditing) 0469 reset(); 0470 0471 m_cancelIsGoHome = cancelIsGoHome; 0472 0473 m_currentType = PlotsBuilder::CartesianParametricCurve2D; 0474 0475 m_widget->plotIcon->setPixmap(QIcon::fromTheme("newparametric").pixmap(16, 16)); 0476 0477 setupExpressionType(QStringList() << "x" << "y", QStringList() << "t", false, true); 0478 0479 m_widget->minx->setExpression(Analitza::Expression("-pi")); 0480 m_widget->maxx->setExpression(Analitza::Expression("pi")); 0481 } 0482 0483 void PlotsEditor::buildPolarGraphCurve(bool cancelIsGoHome) 0484 { 0485 if (!isEditing) 0486 reset(); 0487 0488 m_cancelIsGoHome = cancelIsGoHome; 0489 0490 m_currentType = PlotsBuilder::PolarGraphCurve; 0491 0492 m_widget->plotIcon->setPixmap(QIcon::fromTheme("draw-spiral").pixmap(16, 16)); 0493 0494 setupExpressionType(QStringList()<<"q", QStringList() << "q"); 0495 0496 m_widget->minx->setExpression(Analitza::Expression(Analitza::Cn(0))); 0497 m_widget->maxx->setExpression(Analitza::Expression("2*pi")); 0498 } 0499 0500 //3D 0501 void PlotsEditor::buildCartesianParametricCurve3D(bool cancelIsGoHome) 0502 { 0503 if (!isEditing) 0504 reset(); 0505 0506 m_cancelIsGoHome = cancelIsGoHome; 0507 0508 m_currentType = PlotsBuilder::CartesianParametricCurve3D; 0509 0510 m_widget->plotIcon->setPixmap(QIcon::fromTheme("newparametric3d").pixmap(16, 16)); 0511 0512 setupExpressionType(QStringList() << "x" << "y" << "z", QStringList() << "t", false, true); 0513 0514 m_widget->minx->setExpression(Analitza::Expression("-pi")); 0515 m_widget->maxx->setExpression(Analitza::Expression("pi")); 0516 } 0517 0518 void PlotsEditor::buildCartesianGraphSurface(bool cancelIsGoHome) 0519 { 0520 if (!isEditing) 0521 reset(); 0522 0523 m_cancelIsGoHome = cancelIsGoHome; 0524 0525 m_currentType = PlotsBuilder::CartesianGraphSurface; 0526 0527 m_widget->plotIcon->setPixmap(QIcon::fromTheme("newfunction3d").pixmap(16, 16)); 0528 0529 setupExpressionType(QStringList() << "x,y" << "x,z" << "y,z", QStringList() << "x" << "y"); 0530 0531 m_widget->minx->setExpression(Analitza::Expression(Analitza::Cn(-5))); 0532 m_widget->maxx->setExpression(Analitza::Expression(Analitza::Cn(5))); 0533 0534 m_widget->miny->setExpression(Analitza::Expression(Analitza::Cn(-5))); 0535 m_widget->maxy->setExpression(Analitza::Expression(Analitza::Cn(5))); 0536 } 0537 0538 void PlotsEditor::buildCartesianImplicitSurface(bool cancelIsGoHome) 0539 { 0540 if (!isEditing) 0541 reset(); 0542 0543 m_cancelIsGoHome = cancelIsGoHome; 0544 0545 m_currentType = PlotsBuilder::CartesianImplicitSurface; 0546 0547 m_widget->plotIcon->setPixmap(QIcon::fromTheme("draw-square-inverted-corners").pixmap(16, 16)); 0548 0549 setupExpressionType(QStringList(), QStringList() << "x" << "y" << "z", true); 0550 0551 m_widget->minx->setExpression(Analitza::Expression(Analitza::Cn(-5))); 0552 m_widget->maxx->setExpression(Analitza::Expression(Analitza::Cn(5))); 0553 0554 m_widget->miny->setExpression(Analitza::Expression(Analitza::Cn(-5))); 0555 m_widget->maxy->setExpression(Analitza::Expression(Analitza::Cn(5))); 0556 0557 m_widget->minz->setExpression(Analitza::Expression(Analitza::Cn(-5))); 0558 m_widget->maxz->setExpression(Analitza::Expression(Analitza::Cn(5))); 0559 } 0560 0561 void PlotsEditor::buildCartesianParametricSurface(bool cancelIsGoHome) 0562 { 0563 if (!isEditing) 0564 reset(); 0565 0566 m_cancelIsGoHome = cancelIsGoHome; 0567 0568 m_currentType = PlotsBuilder::CartesianParametricSurface; 0569 0570 m_widget->plotIcon->setPixmap(QIcon::fromTheme("draw-donut").pixmap(16, 16)); 0571 0572 setupExpressionType(QStringList() << "x" << "y" << "z", QStringList() << "u" << "v", false, true); 0573 0574 m_widget->minx->setExpression(Analitza::Expression(Analitza::Cn(-5))); 0575 m_widget->maxx->setExpression(Analitza::Expression(Analitza::Cn(5))); 0576 0577 m_widget->miny->setExpression(Analitza::Expression(Analitza::Cn(-5))); 0578 m_widget->maxy->setExpression(Analitza::Expression(Analitza::Cn(5))); 0579 } 0580 0581 void PlotsEditor::buildCylindricalGraphSurface(bool cancelIsGoHome) 0582 { 0583 if (!isEditing) 0584 reset(); 0585 0586 m_cancelIsGoHome = cancelIsGoHome; 0587 0588 m_currentType = PlotsBuilder::CylindricalGraphSurface; 0589 0590 m_widget->plotIcon->setPixmap(QIcon::fromTheme("newcylindrical").pixmap(16, 16)); 0591 0592 setupExpressionType(QStringList() << "r,p", QStringList() << "r" << "p"); 0593 0594 m_widget->minx->setExpression(Analitza::Expression(Analitza::Cn(0))); 0595 m_widget->maxx->setExpression(Analitza::Expression(Analitza::Cn(5))); 0596 0597 m_widget->miny->setExpression(Analitza::Expression(Analitza::Cn(0))); 0598 m_widget->maxy->setExpression(Analitza::Expression("2*pi")); 0599 } 0600 0601 void PlotsEditor::buildSphericalGraphSurface(bool cancelIsGoHome) 0602 { 0603 if (!isEditing) 0604 reset(); 0605 0606 m_cancelIsGoHome = cancelIsGoHome; 0607 0608 m_currentType = PlotsBuilder::SphericalGraphSurface; 0609 0610 m_widget->plotIcon->setPixmap(QIcon::fromTheme("newspherical").pixmap(16, 16)); 0611 0612 setupExpressionType(QStringList() << "t,p", QStringList() << "t" << "p"); 0613 0614 m_widget->minx->setExpression(Analitza::Expression(Analitza::Cn(0))); 0615 m_widget->maxx->setExpression(Analitza::Expression("2*pi")); 0616 0617 m_widget->miny->setExpression(Analitza::Expression(Analitza::Cn(0))); 0618 m_widget->maxy->setExpression(Analitza::Expression("pi")); 0619 } 0620 0621 void PlotsEditor::savePlot() 0622 { 0623 QStringList errors; 0624 0625 QString name = m_widget->plotName->text(); 0626 0627 if (name.isEmpty()) 0628 name = 'f'+QString::number(m_document->currentPlots()->rowCount()+1); 0629 0630 switch (m_currentType) 0631 { 0632 case PlotsBuilder::CartesianGraphCurve: 0633 case PlotsBuilder::PolarGraphCurve: 0634 { 0635 PlotBuilder req = PlotsFactory::self()->requestPlot(Analitza::Expression(QString(m_currentVars.first()+"->"+m_widget->f->expression().toString())), Dim2D); 0636 if (req.canDraw()) 0637 { 0638 FunctionGraph *item =nullptr; 0639 0640 if (isEditing) 0641 { 0642 //remove that first and then add the new one 0643 m_document->unmapPlot(m_widget->plotsView->selectionModel()->currentIndex()); 0644 } 0645 0646 item = req.create(m_widget->plotColor->color(), m_widget->plotName->text()); 0647 if (m_widget->intervals->isChecked()) 0648 { 0649 item->setInterval(item->parameters().first(), m_widget->minx->expression(), m_widget->maxx->expression()); 0650 } 0651 else 0652 item->clearIntervals(); 0653 0654 m_document->plotsModel()->addPlot(item); 0655 mapDataChanged(); 0656 } 0657 else 0658 errors = req.errors(); 0659 0660 break; 0661 } 0662 case PlotsBuilder::CartesianGraphSurface: 0663 case PlotsBuilder::CylindricalGraphSurface: 0664 case PlotsBuilder::SphericalGraphSurface: 0665 { 0666 PlotBuilder req = PlotsFactory::self()->requestPlot(m_widget->f->expression(), Dim3D); 0667 qDebug() << "------------" << m_widget->f->text() << m_widget->f->expression().toString() << req.errors(); 0668 0669 if (req.canDraw()) 0670 { 0671 FunctionGraph *item = nullptr; 0672 0673 if (isEditing) { 0674 m_document->unmapPlot(m_widget->plotsView->selectionModel()->currentIndex()); 0675 0676 } 0677 0678 item = req.create(m_widget->plotColor->color(), m_widget->plotName->text()); 0679 0680 if (m_widget->intervals->isChecked()) 0681 { 0682 item->setInterval(item->parameters().at(0), m_widget->minx->expression(), m_widget->maxx->expression()); 0683 item->setInterval(item->parameters().at(1), m_widget->miny->expression(), m_widget->maxy->expression()); 0684 } 0685 else 0686 item->clearIntervals(); 0687 0688 m_document->plotsModel()->addPlot(item); 0689 mapDataChanged(); 0690 } 0691 else 0692 errors = req.errors(); 0693 0694 break; 0695 } 0696 0697 case PlotsBuilder::CartesianImplicitCurve: 0698 { 0699 PlotBuilder req = PlotsFactory::self()->requestPlot(m_widget->f->expression(), Dim2D); 0700 0701 if (req.canDraw() && m_widget->f->expression().isEquation()) 0702 { 0703 FunctionGraph *item = nullptr; 0704 0705 if (isEditing) 0706 { 0707 m_document->unmapPlot(m_widget->plotsView->selectionModel()->currentIndex()); 0708 } 0709 0710 item = req.create(m_widget->plotColor->color(), m_widget->plotName->text()); 0711 0712 if (m_widget->intervals->isChecked()) 0713 { 0714 item->setInterval(item->parameters().at(0), m_widget->minx->expression(), m_widget->maxx->expression()); 0715 item->setInterval(item->parameters().at(1), m_widget->miny->expression(), m_widget->maxy->expression()); 0716 } 0717 else 0718 item->clearIntervals(); 0719 0720 m_document->plotsModel()->addPlot(item); 0721 0722 mapDataChanged(); 0723 } 0724 else 0725 errors = req.errors(); 0726 0727 break; 0728 } 0729 0730 case PlotsBuilder::CartesianImplicitSurface: 0731 { 0732 PlotBuilder req = PlotsFactory::self()->requestPlot(m_widget->f->expression(), Dim3D); 0733 0734 if (req.canDraw() && m_widget->f->expression().isEquation()) 0735 { 0736 FunctionGraph *item = nullptr; 0737 0738 if (isEditing) 0739 { 0740 m_document->unmapPlot(m_widget->plotsView->selectionModel()->currentIndex()); 0741 } 0742 0743 item = req.create(m_widget->plotColor->color(), m_widget->plotName->text()); 0744 0745 if (m_widget->intervals->isChecked()) 0746 { 0747 item->setInterval(item->parameters().at(0), m_widget->minx->expression(), m_widget->maxx->expression()); 0748 item->setInterval(item->parameters().at(1), m_widget->miny->expression(), m_widget->maxy->expression()); 0749 item->setInterval(item->parameters().at(2), m_widget->minz->expression(), m_widget->maxz->expression()); 0750 } 0751 else 0752 item->clearIntervals(); 0753 0754 m_document->plotsModel()->addPlot(item); 0755 mapDataChanged(); 0756 } 0757 else 0758 errors = req.errors(); 0759 0760 break; 0761 } 0762 0763 case PlotsBuilder::CartesianParametricCurve2D: 0764 { 0765 PlotBuilder req = PlotsFactory::self()->requestPlot(Analitza::Expression(QString(m_currentVars.first()+"->vector{"+m_widget->f->expression().toString()+", "+ 0766 m_widget->g->expression().toString()+"}")), Dim2D); 0767 0768 if (req.canDraw()) 0769 { 0770 FunctionGraph *item = nullptr; 0771 0772 if (isEditing) 0773 { 0774 m_document->unmapPlot(m_widget->plotsView->selectionModel()->currentIndex()); 0775 } 0776 0777 item = req.create(m_widget->plotColor->color(), m_widget->plotName->text()); 0778 0779 if (m_widget->intervals->isChecked()) 0780 item->setInterval(item->parameters().first(), m_widget->minx->expression(), m_widget->maxx->expression()); 0781 else 0782 item->clearIntervals(); 0783 0784 m_document->plotsModel()->addPlot(item); 0785 mapDataChanged(); 0786 } 0787 else 0788 errors = req.errors(); 0789 0790 break; 0791 } 0792 0793 case PlotsBuilder::CartesianParametricCurve3D: 0794 { 0795 PlotBuilder req = PlotsFactory::self()->requestPlot(Analitza::Expression(QString(m_currentVars.first()+"->vector{"+m_widget->f->expression().toString()+", "+m_widget->g->expression().toString()+", "+m_widget->h->expression().toString()+'}')), Dim3D); 0796 0797 if (req.canDraw()) 0798 { 0799 FunctionGraph *item = nullptr; 0800 0801 if (isEditing) { 0802 m_document->unmapPlot(m_widget->plotsView->selectionModel()->currentIndex()); 0803 } 0804 item = req.create(m_widget->plotColor->color(), m_widget->plotName->text()); 0805 0806 if (m_widget->intervals->isChecked()) { 0807 item->setInterval(item->parameters().first(), m_widget->minx->expression(), m_widget->maxx->expression()); 0808 } 0809 else 0810 item->clearIntervals(); 0811 0812 0813 m_document->plotsModel()->addPlot(item); 0814 mapDataChanged(); 0815 } 0816 else 0817 errors = req.errors(); 0818 0819 break; 0820 } 0821 0822 case PlotsBuilder::CartesianParametricSurface: 0823 { 0824 PlotBuilder req = PlotsFactory::self()->requestPlot(Analitza::Expression(QString("("+m_currentVars.join(",")+")->vector{"+m_widget->f->expression().toString()+", "+m_widget->g->expression().toString()+", "+m_widget->h->expression().toString()+'}')), Dim3D); 0825 0826 if (req.canDraw()) 0827 { 0828 FunctionGraph *item = nullptr; 0829 if (isEditing) { 0830 m_document->unmapPlot(m_widget->plotsView->selectionModel()->currentIndex()); 0831 } 0832 item = req.create(m_widget->plotColor->color(), m_widget->plotName->text()); 0833 0834 if (m_widget->intervals->isChecked()) 0835 { 0836 item->setInterval(item->parameters().at(0), m_widget->minx->expression(), m_widget->maxx->expression()); 0837 item->setInterval(item->parameters().at(1), m_widget->miny->expression(), m_widget->maxy->expression()); 0838 } 0839 else 0840 item->clearIntervals(); 0841 0842 m_document->plotsModel()->addPlot(item); 0843 mapDataChanged(); 0844 } 0845 else 0846 errors = req.errors(); 0847 0848 break; 0849 } 0850 0851 default: 0852 break; 0853 } 0854 0855 if (errors.isEmpty()) 0856 { 0857 isEditing = false; 0858 reset(); 0859 showList(); 0860 } 0861 else 0862 { 0863 emit sendStatus(errors.last(), 2000); //2 secs for the user 0864 } 0865 } 0866 0867 void PlotsEditor::removePlot() 0868 { 0869 if (m_widget->plotsView->selectionModel()->hasSelection()) 0870 m_document->unmapPlot(m_widget->plotsView->selectionModel()->currentIndex()); 0871 emit mapDataChanged(); 0872 } 0873 0874 void PlotsEditor::setCurrentFunctionGraphs(const QString& txt) 0875 { 0876 m_currentFunctionGraphs = txt.split(','); 0877 m_currentVars = m_currentFunctionGraphs; 0878 for (int var = 1; var <=m_currentFunctionGraphs.size(); ++var) 0879 setupVarName(var, m_currentFunctionGraphs[var-1]); 0880 } 0881 0882 void PlotsEditor::setupVarName(int var, const QString &vvalue) 0883 { 0884 switch (var) 0885 { 0886 case 1: 0887 { 0888 m_widget->x->setText("< "+vvalue+" <"); 0889 break; 0890 } 0891 case 2: 0892 { 0893 m_widget->yinterval->show(); 0894 m_widget->y->setText("< "+vvalue+" <"); 0895 break; 0896 } 0897 case 3: 0898 { 0899 m_widget->zinterval->show(); 0900 m_widget->z->setText("< "+vvalue+" <"); 0901 break; 0902 } 0903 } 0904 } 0905 0906 void PlotsEditor::setupFuncName(int var, const QString& vvalue, const QStringList& vars, bool withparenthesis) 0907 { 0908 QString mmlhelper = vvalue; 0909 0910 if (withparenthesis) 0911 mmlhelper.append("("); 0912 0913 foreach(const QString &v, vars) 0914 { 0915 mmlhelper.append(v); 0916 0917 if (v != vars.last()) 0918 mmlhelper.append(","); 0919 } 0920 0921 if (withparenthesis) 0922 mmlhelper.append(")"); 0923 0924 switch (var) 0925 { 0926 case 1: 0927 { 0928 m_widget->fname->setText(mmlhelper); 0929 m_widget->gexpression->hide(); 0930 m_widget->hexpression->hide(); 0931 break; 0932 } 0933 case 2: 0934 { 0935 m_widget->gname->setText(mmlhelper); 0936 m_widget->gexpression->show(); 0937 m_widget->hexpression->hide(); 0938 break; 0939 } 0940 case 3: 0941 { 0942 m_widget->hname->setText(mmlhelper); 0943 m_widget->hexpression->show(); 0944 break; 0945 } 0946 } 0947 } 0948 0949 void PlotsEditor::setupExpressionType(const QStringList &fvalues, const QStringList &vvalues, bool isimplicit, bool isvectorValued) 0950 { 0951 //this vars track current type of plot (see saveslot) 0952 m_currentVars = vvalues; 0953 m_currentIsImplicit = isimplicit; 0954 m_currentIsVectorValued = isvectorValued; 0955 m_currentVectorSize = isvectorValued?fvalues.size():-1; 0956 0957 m_widget->farrow->show(); 0958 0959 if (!isimplicit && !isvectorValued) 0960 { 0961 m_widget->fnameForGraphs->show(); 0962 m_widget->fname->hide(); 0963 m_widget->fnameForGraphs->clear(); 0964 m_widget->fnameForGraphs->addItems(fvalues); 0965 } 0966 else 0967 { 0968 m_widget->fnameForGraphs->hide(); 0969 m_widget->fname->show(); 0970 } 0971 0972 if (!isvectorValued || !isimplicit) 0973 { 0974 m_widget->gexpression->hide(); 0975 m_widget->hexpression->hide(); 0976 0977 m_widget->yinterval->hide(); 0978 m_widget->zinterval->hide(); 0979 } 0980 0981 if (isimplicit) 0982 { 0983 m_widget->fnameForGraphs->hide(); 0984 m_widget->fname->hide(); 0985 m_widget->farrow->hide(); 0986 } 0987 0988 for (int var = 1; var <=vvalues.size(); ++var) 0989 setupVarName(var, vvalues[var-1]); 0990 0991 if (isvectorValued) 0992 { 0993 m_widget->fnameForGraphs->hide(); 0994 0995 m_widget->farrow->setText("="); 0996 0997 for (int func = 1; func <= fvalues.size(); ++func) 0998 { 0999 setupFuncName(func, fvalues[func-1], vvalues); 1000 } 1001 } 1002 else 1003 { 1004 if (!isimplicit) 1005 { 1006 m_widget->farrow->setText("="); 1007 } 1008 } 1009 1010 showEditor(); 1011 } 1012 1013 void PlotsEditor::plotnamecheckClicked(bool state) 1014 { 1015 if(state==true) { 1016 m_widget->plotIcon->show(); 1017 m_widget->plotName->show(); 1018 if(m_widget->plotName->text().isEmpty()) { 1019 m_widget->plotName->setText(i18n("plot %1",plotnumber)); 1020 plotnumber++; 1021 } 1022 } else { 1023 m_widget->plotIcon->hide(); 1024 m_widget->plotName->hide(); 1025 } 1026 }