labplot  2.8.2
About: LabPlot is an application for plotting and analysis of 2D and 3D functions and data. It is a complete rewrite of LabPlot1 and lacks in the first release a lot of features available in the predecessor. On the other hand, the GUI and the usability is more superior.
  Fossies Dox: labplot-2.8.2.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

XYEquationCurveDock.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  File : XYEquationCurveDock.cpp
3  Project : LabPlot
4  --------------------------------------------------------------------
5  Copyright : (C) 2014-2021 Alexander Semke (alexander.semke@web.de)
6  Description : widget for editing properties of equation curves
7 
8  ***************************************************************************/
9 
10 /***************************************************************************
11  * *
12  * This program is free software; you can redistribute it and/or modify *
13  * it under the terms of the GNU General Public License as published by *
14  * the Free Software Foundation; either version 2 of the License, or *
15  * (at your option) any later version. *
16  * *
17  * This program is distributed in the hope that it will be useful, *
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
20  * GNU General Public License for more details. *
21  * *
22  * You should have received a copy of the GNU General Public License *
23  * along with this program; if not, write to the Free Software *
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
25  * Boston, MA 02110-1301 USA *
26  * *
27  ***************************************************************************/
28 
29 #include "XYEquationCurveDock.h"
31 #include "backend/core/Project.h"
36 
37 #include <QCompleter>
38 #include <QKeyEvent>
39 #include <QMenu>
40 #include <QWidgetAction>
41 
42 #include <KLocalizedString>
43 
44 /*!
45  \class XYEquationCurveDock
46  \brief Provides a widget for editing the properties of the XYEquationCurves
47  (2D-curves defined by a mathematical equation) currently selected in
48  the project explorer.
49 
50  If more then one curves are set, the properties of the first column are shown.
51  The changes of the properties are applied to all curves.
52  The exclusions are the name, the comment and the datasets (columns) of
53  the curves - these properties can only be changed if there is only one single curve.
54 
55  \ingroup kdefrontend
56 */
57 
59  //remove the tab "Error bars"
60  ui.tabWidget->removeTab(5);
61 }
62 
63 /*!
64  * // Tab "General"
65  */
67  QWidget* generalTab = new QWidget(ui.tabGeneral);
68  uiGeneralTab.setupUi(generalTab);
69  m_leName = uiGeneralTab.leName;
70  m_leComment = uiGeneralTab.leComment;
71 
72  auto* gridLayout = dynamic_cast<QGridLayout*>(generalTab->layout());
73  if (gridLayout) {
74  gridLayout->setContentsMargins(2, 2, 2, 2);
75  gridLayout->setHorizontalSpacing(2);
76  gridLayout->setVerticalSpacing(2);
77  }
78 
79  auto* layout = new QHBoxLayout(ui.tabGeneral);
80  layout->setMargin(0);
81  layout->addWidget(generalTab);
82 
83  uiGeneralTab.tbConstants1->setIcon( QIcon::fromTheme("labplot-format-text-symbol") );
84  uiGeneralTab.tbFunctions1->setIcon( QIcon::fromTheme("preferences-desktop-font") );
85 
86  uiGeneralTab.tbConstants2->setIcon( QIcon::fromTheme("labplot-format-text-symbol") );
87  uiGeneralTab.tbFunctions2->setIcon( QIcon::fromTheme("preferences-desktop-font") );
88 
89  uiGeneralTab.cbType->addItem(i18n("Cartesian"));
90  uiGeneralTab.cbType->addItem(i18n("Polar"));
91  uiGeneralTab.cbType->addItem(i18n("Parametric"));
92 // uiGeneralTab.cbType->addItem(i18n("Implicit"));
93 
94  uiGeneralTab.pbRecalculate->setIcon(QIcon::fromTheme("run-build"));
95 
96  uiGeneralTab.teEquation2->setExpressionType(XYEquationCurve::EquationType::Parametric);
97 
98 // uiGeneralTab.teEquation1->setMaximumHeight(uiGeneralTab.leName->sizeHint().height()*2);
99 // uiGeneralTab.teEquation2->setMaximumHeight(uiGeneralTab.leName->sizeHint().height()*2);
100  uiGeneralTab.teMin->setMaximumHeight(uiGeneralTab.leName->sizeHint().height());
101  uiGeneralTab.teMax->setMaximumHeight(uiGeneralTab.leName->sizeHint().height());
102 
103  //Slots
104  connect(uiGeneralTab.leName, &QLineEdit::textChanged, this, &XYEquationCurveDock::nameChanged);
105  connect(uiGeneralTab.leComment, &QLineEdit::textChanged, this, &XYEquationCurveDock::commentChanged);
106  connect(uiGeneralTab.chkVisible, &QCheckBox::clicked, this, &XYEquationCurveDock::visibilityChanged);
107 
108  connect(uiGeneralTab.cbType, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &XYEquationCurveDock::typeChanged);
111  connect(uiGeneralTab.tbConstants1, &QToolButton::clicked, this, &XYEquationCurveDock::showConstants);
112  connect(uiGeneralTab.tbFunctions1, &QToolButton::clicked, this, &XYEquationCurveDock::showFunctions);
113  connect(uiGeneralTab.tbConstants2, &QToolButton::clicked, this, &XYEquationCurveDock::showConstants);
114  connect(uiGeneralTab.tbFunctions2, &QToolButton::clicked, this, &XYEquationCurveDock::showFunctions);
117  connect(uiGeneralTab.sbCount, QOverload<int>::of(&QSpinBox::valueChanged), this, &XYEquationCurveDock::enableRecalculate);
118  connect(uiGeneralTab.pbRecalculate, &QPushButton::clicked, this, &XYEquationCurveDock::recalculateClicked);
119 }
120 
121 /*!
122  sets the curves. The properties of the curves in the list \c list can be edited in this widget.
123 */
125  m_initializing = true;
126  m_curvesList = list;
127  m_curve = list.first();
128  m_aspect = list.first();
129  m_equationCurve = dynamic_cast<XYEquationCurve*>(m_curve);
130  Q_ASSERT(m_equationCurve);
133  initGeneralTab();
134  initTabs();
135  uiGeneralTab.pbRecalculate->setEnabled(false);
136  m_initializing = false;
137 }
138 
140  //if there are more then one curve in the list, disable the tab "general"
141  if (m_curvesList.size() == 1) {
142  uiGeneralTab.lName->setEnabled(true);
143  uiGeneralTab.leName->setEnabled(true);
144  uiGeneralTab.lComment->setEnabled(true);
145  uiGeneralTab.leComment->setEnabled(true);
146 
147  uiGeneralTab.leName->setText(m_curve->name());
148  uiGeneralTab.leComment->setText(m_curve->comment());
149  } else {
150  uiGeneralTab.lName->setEnabled(false);
151  uiGeneralTab.leName->setEnabled(false);
152  uiGeneralTab.lComment->setEnabled(false);
153  uiGeneralTab.leComment->setEnabled(false);
154 
155  uiGeneralTab.leName->setText(QString());
156  uiGeneralTab.leComment->setText(QString());
157  }
158 
159  //show the properties of the first curve
160  const auto* equationCurve = dynamic_cast<const XYEquationCurve*>(m_curve);
161  Q_ASSERT(equationCurve);
162  const XYEquationCurve::EquationData& data = equationCurve->equationData();
163  uiGeneralTab.cbType->setCurrentIndex(static_cast<int>(data.type));
164  this->typeChanged(static_cast<int>(data.type));
165  uiGeneralTab.teEquation1->setText(data.expression1);
166  uiGeneralTab.teEquation2->setText(data.expression2);
167  uiGeneralTab.teMin->setText(data.min);
168  uiGeneralTab.teMax->setText(data.max);
169  uiGeneralTab.sbCount->setValue(data.count);
170 
171  uiGeneralTab.chkVisible->setChecked( m_curve->isVisible() );
172 
173  //Slots
178 }
179 
180 //*************************************************************
181 //**** SLOTs for changes triggered in XYEquationCurveDock *****
182 //*************************************************************
184  const auto type{XYEquationCurve::EquationType(index)};
186  uiGeneralTab.lEquation1->setText("y=f(x)");
187  uiGeneralTab.lEquation2->hide();
188  uiGeneralTab.teEquation2->hide();
189  uiGeneralTab.tbFunctions2->hide();
190  uiGeneralTab.tbConstants2->hide();
191  uiGeneralTab.lMin->show();
192  uiGeneralTab.lMax->show();
193  uiGeneralTab.teMin->show();
194  uiGeneralTab.teMax->show();
195  uiGeneralTab.lMin->setText(i18n("x, min"));
196  uiGeneralTab.lMax->setText(i18n("x, max"));
198  uiGeneralTab.lEquation1->setText(QString::fromUtf8("r(φ)"));
199  uiGeneralTab.lEquation2->hide();
200  uiGeneralTab.teEquation2->hide();
201  uiGeneralTab.tbFunctions2->hide();
202  uiGeneralTab.tbConstants2->hide();
203  uiGeneralTab.lMin->show();
204  uiGeneralTab.lMax->show();
205  uiGeneralTab.teMin->show();
206  uiGeneralTab.teMax->show();
207  uiGeneralTab.lMin->setText(i18n("φ, min"));
208  uiGeneralTab.lMax->setText(i18n("φ, max"));
210  uiGeneralTab.lEquation1->setText("x=f(t)");
211  uiGeneralTab.lEquation2->setText("y=f(t)");
212  uiGeneralTab.lEquation2->show();
213  uiGeneralTab.teEquation2->show();
214  uiGeneralTab.tbFunctions2->show();
215  uiGeneralTab.tbConstants2->show();
216  uiGeneralTab.lMin->show();
217  uiGeneralTab.lMax->show();
218  uiGeneralTab.teMin->show();
219  uiGeneralTab.teMax->show();
220  uiGeneralTab.lMin->setText(i18n("t, min"));
221  uiGeneralTab.lMax->setText(i18n("t, max"));
223  uiGeneralTab.lEquation1->setText("f(x,y)");
224  uiGeneralTab.lEquation2->hide();
225  uiGeneralTab.teEquation2->hide();
226  uiGeneralTab.tbFunctions2->hide();
227  uiGeneralTab.tbConstants2->hide();
228  uiGeneralTab.lMin->hide();
229  uiGeneralTab.lMax->hide();
230  uiGeneralTab.teMin->hide();
231  uiGeneralTab.teMax->hide();
232  }
233 
234  uiGeneralTab.teEquation1->setExpressionType(type);
235  this->enableRecalculate();
236 }
237 
240  data.type = (XYEquationCurve::EquationType)uiGeneralTab.cbType->currentIndex();
241  data.expression1 = uiGeneralTab.teEquation1->document()->toPlainText();
242  data.expression2 = uiGeneralTab.teEquation2->document()->toPlainText();
243  data.min = uiGeneralTab.teMin->document()->toPlainText();
244  data.max = uiGeneralTab.teMax->document()->toPlainText();
245  data.count = uiGeneralTab.sbCount->value();
246 
247  for (auto* curve : m_curvesList)
248  static_cast<XYEquationCurve*>(curve)->setEquationData(data);
249 
250  uiGeneralTab.pbRecalculate->setEnabled(false);
251 }
252 
254  QMenu menu;
255  ConstantsWidget constants(&menu);
256 
257  if (QObject::sender() == uiGeneralTab.tbConstants1)
259  else
261 
262  connect(&constants, &ConstantsWidget::constantSelected, &menu, &QMenu::close);
263  connect(&constants, &ConstantsWidget::canceled, &menu, &QMenu::close);
264 
265  auto* widgetAction = new QWidgetAction(this);
266  widgetAction->setDefaultWidget(&constants);
267  menu.addAction(widgetAction);
268 
269  if (QObject::sender() == uiGeneralTab.tbConstants1) {
270  QPoint pos(-menu.sizeHint().width()+uiGeneralTab.tbConstants1->width(),-menu.sizeHint().height());
271  menu.exec(uiGeneralTab.tbConstants1->mapToGlobal(pos));
272  } else {
273  QPoint pos(-menu.sizeHint().width()+uiGeneralTab.tbConstants2->width(),-menu.sizeHint().height());
274  menu.exec(uiGeneralTab.tbConstants2->mapToGlobal(pos));
275  }
276 }
277 
279  QMenu menu;
280  FunctionsWidget functions(&menu);
281  if (QObject::sender() == uiGeneralTab.tbFunctions1)
283  else
285 
286  connect(&functions, &FunctionsWidget::functionSelected, &menu, &QMenu::close);
287  connect(&functions, &FunctionsWidget::canceled, &menu, &QMenu::close);
288 
289  auto* widgetAction = new QWidgetAction(this);
290  widgetAction->setDefaultWidget(&functions);
291  menu.addAction(widgetAction);
292 
293  if (QObject::sender() == uiGeneralTab.tbFunctions1) {
294  QPoint pos(-menu.sizeHint().width()+uiGeneralTab.tbFunctions1->width(),-menu.sizeHint().height());
295  menu.exec(uiGeneralTab.tbFunctions1->mapToGlobal(pos));
296  } else {
297  QPoint pos(-menu.sizeHint().width()+uiGeneralTab.tbFunctions2->width(),-menu.sizeHint().height());
298  menu.exec(uiGeneralTab.tbFunctions2->mapToGlobal(pos));
299  }
300 }
301 
302 void XYEquationCurveDock::insertFunction1(const QString& functionName) {
303  const auto type{XYEquationCurve::EquationType(uiGeneralTab.cbType->currentIndex())};
304 
305  uiGeneralTab.teEquation1->insertPlainText(functionName + ExpressionParser::functionArgumentString(functionName, type));
306 }
307 
308 void XYEquationCurveDock::insertConstant1(const QString& constantsName) {
309  uiGeneralTab.teEquation1->insertPlainText(constantsName);
310 }
311 
312 void XYEquationCurveDock::insertFunction2(const QString& functionName) {
313  uiGeneralTab.teEquation1->insertPlainText(functionName + ExpressionParser::functionArgumentString(functionName, XYEquationCurve::EquationType::Parametric));
314 }
315 
316 void XYEquationCurveDock::insertConstant2(const QString& constantsName) {
317  uiGeneralTab.teEquation2->insertPlainText(constantsName);
318 }
319 
321  if (m_initializing)
322  return;
323 
324  //check whether the formular expressions are correct
325  bool valid = false;
326  const auto type = XYEquationCurve::EquationType(uiGeneralTab.cbType->currentIndex());
328  valid = uiGeneralTab.teEquation1->isValid();
329  else
330  valid = (uiGeneralTab.teEquation1->isValid() && uiGeneralTab.teEquation2->isValid());
331 
332  valid = (valid && uiGeneralTab.teMin->isValid() && uiGeneralTab.teMax->isValid());
333  uiGeneralTab.pbRecalculate->setEnabled(valid);
334 }
335 
336 //*************************************************************
337 //*********** SLOTs for changes triggered in XYCurve **********
338 //*************************************************************
339 //General-Tab
341  if (m_curve != aspect)
342  return;
343 
344  const Lock lock(m_initializing);
345  if (aspect->name() != uiGeneralTab.leName->text())
346  uiGeneralTab.leName->setText(aspect->name());
347  else if (aspect->comment() != uiGeneralTab.leComment->text())
348  uiGeneralTab.leComment->setText(aspect->comment());
349 }
350 
352  const Lock lock(m_initializing);
353  uiGeneralTab.cbType->setCurrentIndex(static_cast<int>(data.type));
354  uiGeneralTab.teEquation1->setText(data.expression1);
355  uiGeneralTab.teEquation2->setText(data.expression2);
356  uiGeneralTab.teMin->setText(data.min);
357  uiGeneralTab.teMax->setText(data.max);
358  uiGeneralTab.sbCount->setValue(data.count);
359 }
Base class of all persistent objects in a Project.
void aspectDescriptionChanged(const AbstractAspect *)
Emitted after the name, comment or caption spec have changed.
QString name() const
QString comment() const
virtual Project * project()
Return the Project this Aspect belongs to, or 0 if it is currently not part of one.
Represents a tree of AbstractAspect objects as a Qt item model.
QLineEdit * m_leName
Definition: BaseDock.h:68
QLineEdit * m_leComment
Definition: BaseDock.h:69
void commentChanged()
Definition: BaseDock.cpp:61
AbstractAspect * m_aspect
Definition: BaseDock.h:70
bool m_initializing
Definition: BaseDock.h:67
void nameChanged()
Definition: BaseDock.cpp:47
Widget for selecting supported mathematical and physical constants that can be used in expressions in...
void constantSelected(const QString &)
static QString functionArgumentString(const QString &functionName, const XYEquationCurve::EquationType)
Widget for selecting supported mathematical functions that can be used in expressions in ExpressionTe...
void functionSelected(const QString &)
Provides a widget for editing the properties of the XYCurves (2D-curves) currently selected in the pr...
Definition: XYCurveDock.h:46
void initTabs()
XYCurve * m_curve
Definition: XYCurveDock.h:82
AspectTreeModel * m_aspectTreeModel
Definition: XYCurveDock.h:83
virtual void setModel()
QList< XYCurve * > m_curvesList
Definition: XYCurveDock.h:81
Ui::XYCurveDock ui
Definition: XYCurveDock.h:80
void visibilityChanged(bool)
bool isVisible() const override
Return whether the element is (at least) partially visible.
Definition: XYCurve.cpp:216
void setCurves(QList< XYCurve * >)
void curveEquationDataChanged(const XYEquationCurve::EquationData &)
void insertFunction2(const QString &)
void insertFunction1(const QString &)
void insertConstant1(const QString &)
void curveDescriptionChanged(const AbstractAspect *)
void setupGeneral() override
XYEquationCurve * m_equationCurve
void insertConstant2(const QString &)
Ui::XYEquationCurveDockGeneralTab uiGeneralTab
void initGeneralTab() override
XYEquationCurveDock(QWidget *parent)
A xy-curve defined by a mathematical equation.
void equationDataChanged(const XYEquationCurve::EquationData &)
#define i18n(m)
Definition: nsl_common.h:38
Definition: BaseDock.h:40