diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cbf23b109..20bfcc556 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,404 +1,407 @@ find_package(SharedMimeInfo REQUIRED) set(KDE_FRONTEND true) set(KDEFRONTEND_DIR kdefrontend) set(BACKEND_DIR backend) set(COMMONFRONTEND_DIR commonfrontend) set(CANTOR_DIR cantor) set(TOOLS_DIR tools) set(CMAKE_AUTOMOC ON) set(SRC_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR} PARENT_SCOPE) set(GUI_SOURCES ${KDEFRONTEND_DIR}/GuiObserver.cpp ${KDEFRONTEND_DIR}/GuiTools.cpp ${KDEFRONTEND_DIR}/HistoryDialog.cpp ${KDEFRONTEND_DIR}/MainWin.cpp ${KDEFRONTEND_DIR}/SettingsDialog.cpp ${KDEFRONTEND_DIR}/SettingsGeneralPage.cpp ${KDEFRONTEND_DIR}/SettingsWorksheetPage.cpp ${KDEFRONTEND_DIR}/SettingsPage.h ${KDEFRONTEND_DIR}/TemplateHandler.cpp ${KDEFRONTEND_DIR}/ThemeHandler.cpp ${KDEFRONTEND_DIR}/datasources/AsciiOptionsWidget.cpp ${KDEFRONTEND_DIR}/datasources/BinaryOptionsWidget.cpp ${KDEFRONTEND_DIR}/datasources/DatabaseManagerDialog.cpp ${KDEFRONTEND_DIR}/datasources/DatabaseManagerWidget.cpp ${KDEFRONTEND_DIR}/datasources/HDF5OptionsWidget.cpp ${KDEFRONTEND_DIR}/datasources/FileInfoDialog.cpp ${KDEFRONTEND_DIR}/datasources/ImageOptionsWidget.cpp ${KDEFRONTEND_DIR}/datasources/ImportDialog.cpp ${KDEFRONTEND_DIR}/datasources/ImportFileWidget.cpp ${KDEFRONTEND_DIR}/datasources/ImportFileDialog.cpp ${KDEFRONTEND_DIR}/datasources/ImportProjectDialog.cpp ${KDEFRONTEND_DIR}/datasources/ImportSQLDatabaseDialog.cpp ${KDEFRONTEND_DIR}/datasources/ImportSQLDatabaseWidget.cpp ${KDEFRONTEND_DIR}/datasources/NetCDFOptionsWidget.cpp ${KDEFRONTEND_DIR}/datasources/ROOTOptionsWidget.cpp ${KDEFRONTEND_DIR}/datasources/FITSOptionsWidget.cpp ${KDEFRONTEND_DIR}/datasources/JsonOptionsWidget.cpp ${KDEFRONTEND_DIR}/dockwidgets/AxisDock.cpp ${KDEFRONTEND_DIR}/dockwidgets/NoteDock.cpp ${KDEFRONTEND_DIR}/dockwidgets/CartesianPlotDock.cpp ${KDEFRONTEND_DIR}/dockwidgets/CartesianPlotLegendDock.cpp ${KDEFRONTEND_DIR}/dockwidgets/HistogramDock.cpp ${KDEFRONTEND_DIR}/dockwidgets/BarChartPlotDock.cpp ${KDEFRONTEND_DIR}/dockwidgets/CustomPointDock.cpp ${KDEFRONTEND_DIR}/dockwidgets/ColumnDock.cpp ${KDEFRONTEND_DIR}/dockwidgets/LiveDataDock.cpp ${KDEFRONTEND_DIR}/dockwidgets/MatrixDock.cpp ${KDEFRONTEND_DIR}/dockwidgets/ProjectDock.cpp ${KDEFRONTEND_DIR}/dockwidgets/SpreadsheetDock.cpp ${KDEFRONTEND_DIR}/dockwidgets/XYCurveDock.cpp ${KDEFRONTEND_DIR}/dockwidgets/XYEquationCurveDock.cpp ${KDEFRONTEND_DIR}/dockwidgets/XYDataReductionCurveDock.cpp ${KDEFRONTEND_DIR}/dockwidgets/XYDifferentiationCurveDock.cpp ${KDEFRONTEND_DIR}/dockwidgets/XYIntegrationCurveDock.cpp ${KDEFRONTEND_DIR}/dockwidgets/XYInterpolationCurveDock.cpp ${KDEFRONTEND_DIR}/dockwidgets/XYSmoothCurveDock.cpp ${KDEFRONTEND_DIR}/dockwidgets/XYFitCurveDock.cpp ${KDEFRONTEND_DIR}/dockwidgets/XYFourierFilterCurveDock.cpp ${KDEFRONTEND_DIR}/dockwidgets/XYFourierTransformCurveDock.cpp + ${KDEFRONTEND_DIR}/dockwidgets/XYConvolutionCurveDock.cpp ${KDEFRONTEND_DIR}/dockwidgets/WorksheetDock.cpp ${KDEFRONTEND_DIR}/matrix/MatrixFunctionDialog.cpp ${KDEFRONTEND_DIR}/spreadsheet/PlotDataDialog.cpp ${KDEFRONTEND_DIR}/spreadsheet/EquidistantValuesDialog.cpp ${KDEFRONTEND_DIR}/spreadsheet/ExportSpreadsheetDialog.cpp ${KDEFRONTEND_DIR}/spreadsheet/DropValuesDialog.cpp ${KDEFRONTEND_DIR}/spreadsheet/FunctionValuesDialog.cpp ${KDEFRONTEND_DIR}/spreadsheet/RandomValuesDialog.cpp ${KDEFRONTEND_DIR}/spreadsheet/SortDialog.cpp ${KDEFRONTEND_DIR}/spreadsheet/StatisticsDialog.cpp ${KDEFRONTEND_DIR}/worksheet/ExportWorksheetDialog.cpp ${KDEFRONTEND_DIR}/worksheet/GridDialog.cpp ${KDEFRONTEND_DIR}/worksheet/DynamicPresenterWidget.cpp ${KDEFRONTEND_DIR}/worksheet/PresenterWidget.cpp ${KDEFRONTEND_DIR}/worksheet/SlidingPanel.cpp ${KDEFRONTEND_DIR}/widgets/ConstantsWidget.cpp ${KDEFRONTEND_DIR}/widgets/ThemesComboBox.cpp ${KDEFRONTEND_DIR}/widgets/ThemesWidget.cpp ${KDEFRONTEND_DIR}/widgets/ExpressionTextEdit.cpp ${KDEFRONTEND_DIR}/widgets/FitOptionsWidget.cpp ${KDEFRONTEND_DIR}/widgets/FitParametersWidget.cpp ${KDEFRONTEND_DIR}/widgets/FunctionsWidget.cpp ${KDEFRONTEND_DIR}/widgets/LabelWidget.cpp ${KDEFRONTEND_DIR}/widgets/DatapickerImageWidget.cpp ${KDEFRONTEND_DIR}/widgets/DatapickerCurveWidget.cpp ${KDEFRONTEND_DIR}/widgets/FITSHeaderEditWidget.cpp ${KDEFRONTEND_DIR}/widgets/FITSHeaderEditNewKeywordDialog.cpp ${KDEFRONTEND_DIR}/widgets/FITSHeaderEditAddUnitDialog.cpp ${KDEFRONTEND_DIR}/widgets/FITSHeaderEditDialog.cpp ${KDEFRONTEND_DIR}/widgets/ResizableTextEdit.cpp ) set(UI_SOURCES ${KDEFRONTEND_DIR}/ui/constantswidget.ui ${KDEFRONTEND_DIR}/ui/functionswidget.ui ${KDEFRONTEND_DIR}/ui/fitoptionswidget.ui ${KDEFRONTEND_DIR}/ui/fitparameterswidget.ui ${KDEFRONTEND_DIR}/ui/labelwidget.ui ${KDEFRONTEND_DIR}/ui/settingsgeneralpage.ui ${KDEFRONTEND_DIR}/ui/settingsworksheetpage.ui ${KDEFRONTEND_DIR}/ui/settingsprintingpage.ui ${KDEFRONTEND_DIR}/ui/datasources/asciioptionswidget.ui ${KDEFRONTEND_DIR}/ui/datasources/binaryoptionswidget.ui ${KDEFRONTEND_DIR}/ui/datasources/databasemanagerwidget.ui ${KDEFRONTEND_DIR}/ui/datasources/hdf5optionswidget.ui ${KDEFRONTEND_DIR}/ui/datasources/imageoptionswidget.ui ${KDEFRONTEND_DIR}/ui/datasources/importfilewidget.ui ${KDEFRONTEND_DIR}/ui/datasources/importprojectwidget.ui ${KDEFRONTEND_DIR}/ui/datasources/importsqldatabasewidget.ui ${KDEFRONTEND_DIR}/ui/datasources/netcdfoptionswidget.ui ${KDEFRONTEND_DIR}/ui/datasources/rootoptionswidget.ui ${KDEFRONTEND_DIR}/ui/datasources/fitsoptionswidget.ui ${KDEFRONTEND_DIR}/ui/datasources/jsonoptionswidget.ui ${KDEFRONTEND_DIR}/ui/dockwidgets/axisdock.ui ${KDEFRONTEND_DIR}/ui/dockwidgets/cartesianplotdock.ui ${KDEFRONTEND_DIR}/ui/dockwidgets/cartesianplotlegenddock.ui ${KDEFRONTEND_DIR}/ui/dockwidgets/histogramdock.ui ${KDEFRONTEND_DIR}/ui/dockwidgets/barchartplotdock.ui ${KDEFRONTEND_DIR}/ui/dockwidgets/columndock.ui ${KDEFRONTEND_DIR}/ui/dockwidgets/custompointdock.ui ${KDEFRONTEND_DIR}/ui/dockwidgets/livedatadock.ui ${KDEFRONTEND_DIR}/ui/dockwidgets/notedock.ui ${KDEFRONTEND_DIR}/ui/dockwidgets/matrixdock.ui ${KDEFRONTEND_DIR}/ui/dockwidgets/projectdock.ui ${KDEFRONTEND_DIR}/ui/dockwidgets/spreadsheetdock.ui ${KDEFRONTEND_DIR}/ui/dockwidgets/xycurvedock.ui ${KDEFRONTEND_DIR}/ui/dockwidgets/xycurvedockgeneraltab.ui ${KDEFRONTEND_DIR}/ui/dockwidgets/xydatareductioncurvedockgeneraltab.ui ${KDEFRONTEND_DIR}/ui/dockwidgets/xydifferentiationcurvedockgeneraltab.ui ${KDEFRONTEND_DIR}/ui/dockwidgets/xyintegrationcurvedockgeneraltab.ui ${KDEFRONTEND_DIR}/ui/dockwidgets/xyinterpolationcurvedockgeneraltab.ui ${KDEFRONTEND_DIR}/ui/dockwidgets/xysmoothcurvedockgeneraltab.ui ${KDEFRONTEND_DIR}/ui/dockwidgets/xyfitcurvedockgeneraltab.ui ${KDEFRONTEND_DIR}/ui/dockwidgets/xyfourierfiltercurvedockgeneraltab.ui ${KDEFRONTEND_DIR}/ui/dockwidgets/xyfouriertransformcurvedockgeneraltab.ui + ${KDEFRONTEND_DIR}/ui/dockwidgets/xyconvolutioncurvedockgeneraltab.ui ${KDEFRONTEND_DIR}/ui/dockwidgets/xyequationcurvedockgeneraltab.ui ${KDEFRONTEND_DIR}/ui/dockwidgets/worksheetdock.ui ${KDEFRONTEND_DIR}/ui/matrix/matrixfunctionwidget.ui ${KDEFRONTEND_DIR}/ui/spreadsheet/plotdatawidget.ui ${KDEFRONTEND_DIR}/ui/spreadsheet/equidistantvalueswidget.ui ${KDEFRONTEND_DIR}/ui/spreadsheet/exportspreadsheetwidget.ui ${KDEFRONTEND_DIR}/ui/spreadsheet/dropvalueswidget.ui ${KDEFRONTEND_DIR}/ui/spreadsheet/functionvalueswidget.ui ${KDEFRONTEND_DIR}/ui/spreadsheet/randomvalueswidget.ui ${KDEFRONTEND_DIR}/ui/spreadsheet/sortdialogwidget.ui ${KDEFRONTEND_DIR}/ui/worksheet/exportworksheetwidget.ui ${KDEFRONTEND_DIR}/ui/datapickerimagewidget.ui ${KDEFRONTEND_DIR}/ui/datapickercurvewidget.ui ${KDEFRONTEND_DIR}/ui/fitsheadereditwidget.ui ${KDEFRONTEND_DIR}/ui/fitsheadereditnewkeywordwidget.ui ${KDEFRONTEND_DIR}/ui/fitsheadereditaddunitwidget.ui ) set(BACKEND_SOURCES ${BACKEND_DIR}/core/Folder.cpp ${BACKEND_DIR}/core/AbstractAspect.cpp ${BACKEND_DIR}/core/AbstractColumn.cpp ${BACKEND_DIR}/core/AbstractColumnPrivate.cpp ${BACKEND_DIR}/core/abstractcolumncommands.cpp ${BACKEND_DIR}/core/AbstractFilter.cpp ${BACKEND_DIR}/core/AbstractSimpleFilter.cpp ${BACKEND_DIR}/core/column/Column.cpp ${BACKEND_DIR}/core/column/ColumnPrivate.cpp ${BACKEND_DIR}/core/column/ColumnStringIO.cpp ${BACKEND_DIR}/core/column/columncommands.cpp ${BACKEND_DIR}/core/AbstractScriptingEngine.cpp ${BACKEND_DIR}/core/AbstractScript.cpp ${BACKEND_DIR}/core/ScriptingEngineManager.cpp ${BACKEND_DIR}/core/Project.cpp ${BACKEND_DIR}/core/AbstractPart.cpp ${BACKEND_DIR}/core/Workbook.cpp ${BACKEND_DIR}/core/AspectTreeModel.cpp ${BACKEND_DIR}/core/datatypes/SimpleCopyThroughFilter.h ${BACKEND_DIR}/core/datatypes/Double2DateTimeFilter.h ${BACKEND_DIR}/core/datatypes/Double2DayOfWeekFilter.h ${BACKEND_DIR}/core/datatypes/Double2IntegerFilter.h ${BACKEND_DIR}/core/datatypes/Double2MonthFilter.h ${BACKEND_DIR}/core/datatypes/Double2StringFilter.cpp ${BACKEND_DIR}/core/datatypes/Integer2DateTimeFilter.h ${BACKEND_DIR}/core/datatypes/Integer2DayOfWeekFilter.h ${BACKEND_DIR}/core/datatypes/Integer2DoubleFilter.h ${BACKEND_DIR}/core/datatypes/Integer2MonthFilter.h ${BACKEND_DIR}/core/datatypes/Integer2StringFilter.h ${BACKEND_DIR}/core/datatypes/String2DayOfWeekFilter.h ${BACKEND_DIR}/core/datatypes/String2DoubleFilter.h ${BACKEND_DIR}/core/datatypes/String2IntegerFilter.h ${BACKEND_DIR}/core/datatypes/String2MonthFilter.h ${BACKEND_DIR}/core/datatypes/String2DateTimeFilter.cpp ${BACKEND_DIR}/core/datatypes/DateTime2DoubleFilter.h ${BACKEND_DIR}/core/datatypes/DateTime2IntegerFilter.h ${BACKEND_DIR}/core/datatypes/DateTime2StringFilter.cpp ${BACKEND_DIR}/core/datatypes/Month2DoubleFilter.h ${BACKEND_DIR}/core/datatypes/Month2IntegerFilter.h ${BACKEND_DIR}/core/datatypes/DayOfWeek2DoubleFilter.h ${BACKEND_DIR}/core/datatypes/DayOfWeek2IntegerFilter.h ${BACKEND_DIR}/core/plugin/PluginLoader.cpp ${BACKEND_DIR}/core/plugin/PluginManager.cpp ${BACKEND_DIR}/datasources/AbstractDataSource.cpp ${BACKEND_DIR}/datasources/LiveDataSource.cpp ${BACKEND_DIR}/datasources/filters/AbstractFileFilter.cpp ${BACKEND_DIR}/datasources/filters/AsciiFilter.cpp ${BACKEND_DIR}/datasources/filters/BinaryFilter.cpp ${BACKEND_DIR}/datasources/filters/HDF5Filter.cpp ${BACKEND_DIR}/datasources/filters/ImageFilter.cpp ${BACKEND_DIR}/datasources/filters/JsonFilter.cpp ${BACKEND_DIR}/datasources/filters/NetCDFFilter.cpp ${BACKEND_DIR}/datasources/filters/NgspiceRawAsciiFilter.cpp ${BACKEND_DIR}/datasources/filters/NgspiceRawBinaryFilter.cpp ${BACKEND_DIR}/datasources/filters/FITSFilter.cpp ${BACKEND_DIR}/datasources/filters/QJsonModel.cpp ${BACKEND_DIR}/datasources/filters/ROOTFilter.cpp ${BACKEND_DIR}/datasources/projects/ProjectParser.cpp ${BACKEND_DIR}/datasources/projects/LabPlotProjectParser.cpp ${BACKEND_DIR}/datasources/projects/OriginProjectParser.cpp ${BACKEND_DIR}/gsl/ExpressionParser.cpp ${BACKEND_DIR}/matrix/Matrix.cpp ${BACKEND_DIR}/matrix/matrixcommands.cpp ${BACKEND_DIR}/matrix/MatrixModel.cpp ${BACKEND_DIR}/spreadsheet/Spreadsheet.cpp ${BACKEND_DIR}/spreadsheet/SpreadsheetModel.cpp ${BACKEND_DIR}/lib/XmlStreamReader.cpp ${BACKEND_DIR}/note/Note.cpp ${BACKEND_DIR}/worksheet/WorksheetElement.cpp ${BACKEND_DIR}/worksheet/TextLabel.cpp ${BACKEND_DIR}/worksheet/Worksheet.cpp ${BACKEND_DIR}/worksheet/WorksheetElementContainer.cpp ${BACKEND_DIR}/worksheet/WorksheetElementGroup.cpp ${BACKEND_DIR}/worksheet/plots/AbstractPlot.cpp ${BACKEND_DIR}/worksheet/plots/AbstractCoordinateSystem.cpp ${BACKEND_DIR}/worksheet/plots/PlotArea.cpp ${BACKEND_DIR}/worksheet/plots/cartesian/Axis.cpp ${BACKEND_DIR}/worksheet/plots/cartesian/CartesianCoordinateSystem.cpp ${BACKEND_DIR}/worksheet/plots/cartesian/CartesianPlot.cpp ${BACKEND_DIR}/worksheet/plots/cartesian/CartesianPlotLegend.cpp ${BACKEND_DIR}/worksheet/plots/cartesian/Histogram.cpp ${BACKEND_DIR}/worksheet/plots/cartesian/BarChartPlot.cpp ${BACKEND_DIR}/worksheet/plots/cartesian/CustomPoint.cpp ${BACKEND_DIR}/worksheet/plots/cartesian/Symbol.cpp ${BACKEND_DIR}/worksheet/plots/cartesian/XYAnalysisCurve.cpp ${BACKEND_DIR}/worksheet/plots/cartesian/XYCurve.cpp ${BACKEND_DIR}/worksheet/plots/cartesian/XYEquationCurve.cpp ${BACKEND_DIR}/worksheet/plots/cartesian/XYDataReductionCurve.cpp ${BACKEND_DIR}/worksheet/plots/cartesian/XYDifferentiationCurve.cpp ${BACKEND_DIR}/worksheet/plots/cartesian/XYIntegrationCurve.cpp ${BACKEND_DIR}/worksheet/plots/cartesian/XYInterpolationCurve.cpp ${BACKEND_DIR}/worksheet/plots/cartesian/XYSmoothCurve.cpp ${BACKEND_DIR}/worksheet/plots/cartesian/XYFitCurve.cpp ${BACKEND_DIR}/worksheet/plots/cartesian/XYFourierFilterCurve.cpp ${BACKEND_DIR}/worksheet/plots/cartesian/XYFourierTransformCurve.cpp + ${BACKEND_DIR}/worksheet/plots/cartesian/XYConvolutionCurve.cpp ${BACKEND_DIR}/lib/SignallingUndoCommand.cpp ${BACKEND_DIR}/datapicker/DatapickerPoint.cpp ${BACKEND_DIR}/datapicker/DatapickerImage.cpp ${BACKEND_DIR}/datapicker/Datapicker.cpp ${BACKEND_DIR}/datapicker/Transform.cpp ${BACKEND_DIR}/datapicker/ImageEditor.cpp ${BACKEND_DIR}/datapicker/Segment.cpp ${BACKEND_DIR}/datapicker/Segments.cpp ${BACKEND_DIR}/datapicker/DatapickerCurve.cpp ) set(NSL_SOURCES ${BACKEND_DIR}/nsl/nsl_dft.c ${BACKEND_DIR}/nsl/nsl_diff.c ${BACKEND_DIR}/nsl/nsl_filter.c ${BACKEND_DIR}/nsl/nsl_fit.c ${BACKEND_DIR}/nsl/nsl_geom.c ${BACKEND_DIR}/nsl/nsl_geom_linesim.c ${BACKEND_DIR}/nsl/nsl_int.c ${BACKEND_DIR}/nsl/nsl_interp.c ${BACKEND_DIR}/nsl/nsl_math.c ${BACKEND_DIR}/nsl/nsl_sf_basic.c ${BACKEND_DIR}/nsl/nsl_sf_kernel.c ${BACKEND_DIR}/nsl/nsl_sf_poly.c ${BACKEND_DIR}/nsl/nsl_sf_stats.c ${BACKEND_DIR}/nsl/nsl_sf_window.c ${BACKEND_DIR}/nsl/nsl_smooth.c ${BACKEND_DIR}/nsl/nsl_sort.c ${BACKEND_DIR}/nsl/nsl_stats.c ) IF (NOT MSVC_FOUND) IF (NOT LIBCERF_FOUND) list(APPEND NSL_SOURCES ${BACKEND_DIR}/nsl/Faddeeva.c ) ENDIF () ENDIF () set(COMMONFRONTEND_SOURCES ${COMMONFRONTEND_DIR}/matrix/MatrixView.cpp ${COMMONFRONTEND_DIR}/note/NoteView.cpp ${COMMONFRONTEND_DIR}/spreadsheet/SpreadsheetCommentsHeaderModel.cpp ${COMMONFRONTEND_DIR}/spreadsheet/SpreadsheetHeaderView.cpp ${COMMONFRONTEND_DIR}/spreadsheet/SpreadsheetItemDelegate.cpp ${COMMONFRONTEND_DIR}/spreadsheet/SpreadsheetView.cpp ${COMMONFRONTEND_DIR}/workbook/WorkbookView.cpp ${COMMONFRONTEND_DIR}/worksheet/WorksheetView.cpp ${COMMONFRONTEND_DIR}/ProjectExplorer.cpp ${COMMONFRONTEND_DIR}/core/PartMdiView.cpp ${COMMONFRONTEND_DIR}/widgets/TreeViewComboBox.cpp ${COMMONFRONTEND_DIR}/widgets/qxtspanslider.cpp ${COMMONFRONTEND_DIR}/datapicker/DatapickerView.cpp ${COMMONFRONTEND_DIR}/datapicker/DatapickerImageView.cpp ) IF (${CANTOR_LIBS_FOUND}) set(CANTOR_SOURCES ${KDEFRONTEND_DIR}/dockwidgets/CantorWorksheetDock.cpp ${BACKEND_DIR}/cantorWorksheet/VariableParser.cpp ${BACKEND_DIR}/cantorWorksheet/CantorWorksheet.cpp ${COMMONFRONTEND_DIR}/cantorWorksheet/CantorWorksheetView.cpp ) set(CANTOR_UI_SOURCES ${KDEFRONTEND_DIR}/ui/dockwidgets/cantorworksheetdock.ui) set(UI_SOURCES ${UI_SOURCES} ${CANTOR_UI_SOURCES}) ELSE () set(CANTOR_SOURCES "") ENDIF () set(TOOLS_SOURCES ${TOOLS_DIR}/EquationHighlighter.cpp ${TOOLS_DIR}/ImageTools.cpp ${TOOLS_DIR}/TeXRenderer.cpp ) bison_target(GslParser ${BACKEND_DIR}/gsl/parser.y ${CMAKE_CURRENT_BINARY_DIR}/gsl_parser.c ) set(GENERATED_SOURCES ${BISON_GslParser_OUTPUTS} ) ############################################################################## INCLUDE_DIRECTORIES( . ${BACKEND_DIR}/gsl ${GSL_INCLUDE_DIR} ) set( LABPLOT_SRCS ${GUI_SOURCES} ) ki18n_wrap_ui( LABPLOT_SRCS ${UI_SOURCES} ) # TODO: build without: add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0) # static library add_library( labplot2lib STATIC ${LABPLOT_SRCS} ${BACKEND_SOURCES} ${NSL_SOURCES} ${CANTOR_SOURCES} ${DATASOURCES_SOURCES} ${COMMONFRONTEND_SOURCES} ${TOOLS_SOURCES} ${GENERATED_SOURCES} ${QTMOC_HDRS} ) # set_property(TARGET ${objlib} PROPERTY POSITION_INDEPENDENT_CODE 1) target_link_libraries( labplot2lib KF5::Archive KF5::Completion KF5::ConfigCore KF5::I18n KF5::IconThemes KF5::TextWidgets KF5::XmlGui Qt5::Svg Qt5::Core Qt5::Network Qt5::PrintSupport Qt5::Sql ${GSL_LIBRARIES} ${GSL_CBLAS_LIBRARIES} ) IF (Qt5SerialPort_FOUND) target_link_libraries( labplot2lib Qt5::SerialPort ) ENDIF () IF (KF5SyntaxHighlighting_FOUND) target_link_libraries( labplot2lib KF5::SyntaxHighlighting ) ENDIF () #TODO: KF5::NewStuff IF (CANTOR_LIBS_FOUND) target_link_libraries( labplot2lib ${CANTOR_LIBS} KF5::Service KF5::Parts) ENDIF () IF (HDF5_FOUND) target_link_libraries( labplot2lib ${HDF5_LIBRARIES} ) ENDIF () IF (FFTW_FOUND) target_link_libraries( labplot2lib ${FFTW_LIBRARIES} ) ENDIF () IF (NETCDF_FOUND) target_link_libraries( labplot2lib ${NETCDF_LIBRARY} ) ENDIF () IF (CFITSIO_FOUND) target_link_libraries( labplot2lib ${CFITSIO_LIBRARY} ) ENDIF () IF (LIBCERF_FOUND) target_link_libraries( labplot2lib ${LIBCERF_LIBRARY} ) ENDIF () IF (ZLIB_FOUND AND LZ4_FOUND) target_link_libraries( labplot2lib ${ZLIB_LIBRARY} ${LZ4_LIBRARY} ) ENDIF () IF (ENABLE_LIBORIGIN) target_link_libraries( labplot2lib liborigin-static ) ENDIF () # icons for the executable on Windows and Mac OS X set(LABPLOT_ICONS ${CMAKE_CURRENT_SOURCE_DIR}/../icons/16-apps-labplot2.png ${CMAKE_CURRENT_SOURCE_DIR}/../icons/32-apps-labplot2.png ${CMAKE_CURRENT_SOURCE_DIR}/../icons/48-apps-labplot2.png ${CMAKE_CURRENT_SOURCE_DIR}/../icons/64-apps-labplot2.png ${CMAKE_CURRENT_SOURCE_DIR}/../icons/128-apps-labplot2.png ${CMAKE_CURRENT_SOURCE_DIR}/../icons/256-apps-labplot2.png ${CMAKE_CURRENT_SOURCE_DIR}/../icons/512-apps-labplot2.png ) # main executable set(LABPLOT_SOURCE ${KDEFRONTEND_DIR}/LabPlot.cpp) ecm_add_app_icon(LABPLOT_SOURCE ICONS ${LABPLOT_ICONS}) add_executable( labplot2 ${LABPLOT_SOURCE} ) target_link_libraries( labplot2 labplot2lib ) ############## installation ################################ install( TARGETS labplot2 DESTINATION ${INSTALL_TARGETS_DEFAULT_ARGS} ) install( FILES ${KDEFRONTEND_DIR}/labplot2ui.rc DESTINATION ${KXMLGUI_INSTALL_DIR}/${PROJECT_NAME} ) install( FILES ${KDEFRONTEND_DIR}/splash.png ${KDEFRONTEND_DIR}/labplot2.ico DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME} ) install( PROGRAMS org.kde.labplot2.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} ) install( FILES labplot2.xml DESTINATION ${XDG_MIME_INSTALL_DIR} ) install( FILES labplot2_themes.knsrc DESTINATION ${CONFIG_INSTALL_DIR} ) update_xdg_mimetypes( ${XDG_MIME_INSTALL_DIR} ) diff --git a/src/backend/worksheet/plots/cartesian/XYConvolutionCurve.cpp b/src/backend/worksheet/plots/cartesian/XYConvolutionCurve.cpp new file mode 100644 index 000000000..433c4e1e0 --- /dev/null +++ b/src/backend/worksheet/plots/cartesian/XYConvolutionCurve.cpp @@ -0,0 +1,335 @@ +/*************************************************************************** + File : XYConvolutionCurve.cpp + Project : LabPlot + Description : A xy-curve defined by a convolution + -------------------------------------------------------------------- + Copyright : (C) 2018 Stefan Gerlach (stefan.gerlach@uni.kn) + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, * + * Boston, MA 02110-1301 USA * + * * + ***************************************************************************/ + +/*! + \class XYConvolutionCurve + \brief A xy-curve defined by a convolution + + \ingroup worksheet +*/ + +#include "XYConvolutionCurve.h" +#include "XYConvolutionCurvePrivate.h" +#include "backend/core/column/Column.h" +#include "backend/lib/commandtemplates.h" +#include "backend/lib/macros.h" + +#include +#include +#include +#include + +XYConvolutionCurve::XYConvolutionCurve(const QString& name) + : XYAnalysisCurve(name, new XYConvolutionCurvePrivate(this)) { +} + +XYConvolutionCurve::XYConvolutionCurve(const QString& name, XYConvolutionCurvePrivate* dd) + : XYAnalysisCurve(name, dd) { +} + +XYConvolutionCurve::~XYConvolutionCurve() { + //no need to delete the d-pointer here - it inherits from QGraphicsItem + //and is deleted during the cleanup in QGraphicsScene +} + +void XYConvolutionCurve::recalculate() { + Q_D(XYConvolutionCurve); + d->recalculate(); +} + +/*! + Returns an icon to be used in the project explorer. +*/ +QIcon XYConvolutionCurve::icon() const { + return QIcon::fromTheme("labplot-xy-convolution-curve"); +} + +//############################################################################## +//########################## getter methods ################################## +//############################################################################## +BASIC_SHARED_D_READER_IMPL(XYConvolutionCurve, XYConvolutionCurve::ConvolutionData, convolutionData, convolutionData) + +const XYConvolutionCurve::ConvolutionResult& XYConvolutionCurve::convolutionResult() const { + Q_D(const XYConvolutionCurve); + return d->convolutionResult; +} + +//############################################################################## +//################# setter methods and undo commands ########################## +//############################################################################## +STD_SETTER_CMD_IMPL_F_S(XYConvolutionCurve, SetConvolutionData, XYConvolutionCurve::ConvolutionData, convolutionData, recalculate); +void XYConvolutionCurve::setConvolutionData(const XYConvolutionCurve::ConvolutionData& convolutionData) { + Q_D(XYConvolutionCurve); + exec(new XYConvolutionCurveSetConvolutionDataCmd(d, convolutionData, ki18n("%1: set options and perform the convolution"))); +} + +//############################################################################## +//######################### Private implementation ############################# +//############################################################################## +XYConvolutionCurvePrivate::XYConvolutionCurvePrivate(XYConvolutionCurve* owner) : XYAnalysisCurvePrivate(owner), + q(owner) { + +} + +XYConvolutionCurvePrivate::~XYConvolutionCurvePrivate() { + //no need to delete xColumn and yColumn, they are deleted + //when the parent aspect is removed +} + +void XYConvolutionCurvePrivate::recalculate() { + QElapsedTimer timer; + timer.start(); + + //create convolution result columns if not available yet, clear them otherwise + if (!xColumn) { + xColumn = new Column("x", AbstractColumn::Numeric); + yColumn = new Column("y", AbstractColumn::Numeric); + xVector = static_cast* >(xColumn->data()); + yVector = static_cast* >(yColumn->data()); + + xColumn->setHidden(true); + q->addChild(xColumn); + yColumn->setHidden(true); + q->addChild(yColumn); + + q->setUndoAware(false); + q->setXColumn(xColumn); + q->setYColumn(yColumn); + q->setUndoAware(true); + } else { + xVector->clear(); + yVector->clear(); + } + + // clear the previous result + convolutionResult = XYConvolutionCurve::ConvolutionResult(); + + //determine the data source columns + const AbstractColumn* tmpXDataColumn = 0; + const AbstractColumn* tmpYDataColumn = 0; + if (dataSourceType == XYAnalysisCurve::DataSourceSpreadsheet) { + //spreadsheet columns as data source + tmpXDataColumn = xDataColumn; + tmpYDataColumn = yDataColumn; + } else { + //curve columns as data source + tmpXDataColumn = dataSourceCurve->xColumn(); + tmpYDataColumn = dataSourceCurve->yColumn(); + } + + if (!tmpXDataColumn || !tmpYDataColumn) { + emit q->dataChanged(); + sourceDataChangedSinceLastRecalc = false; + return; + } + + //check column sizes + if (tmpXDataColumn->rowCount() != tmpYDataColumn->rowCount()) { + convolutionResult.available = true; + convolutionResult.valid = false; + convolutionResult.status = i18n("Number of x and y data points must be equal."); + emit q->dataChanged(); + sourceDataChangedSinceLastRecalc = false; + return; + } + + //copy all valid data point for the convolution to temporary vectors + QVector xdataVector; + QVector ydataVector; + + double xmin; + double xmax; + if (convolutionData.autoRange) { + xmin = tmpXDataColumn->minimum(); + xmax = tmpXDataColumn->maximum(); + } else { + xmin = convolutionData.xRange.first(); + xmax = convolutionData.xRange.last(); + } + + for (int row = 0; row < tmpXDataColumn->rowCount(); ++row) { + //only copy those data where _all_ values (for x and y, if given) are valid + if (!std::isnan(tmpXDataColumn->valueAt(row)) && !std::isnan(tmpYDataColumn->valueAt(row)) + && !tmpXDataColumn->isMasked(row) && !tmpYDataColumn->isMasked(row)) { + + // only when inside given range + if (tmpXDataColumn->valueAt(row) >= xmin && tmpXDataColumn->valueAt(row) <= xmax) { + xdataVector.append(tmpXDataColumn->valueAt(row)); + ydataVector.append(tmpYDataColumn->valueAt(row)); + } + } + } + + const size_t n = (size_t)xdataVector.size(); // number of data points to integrate + if (n < 2) { + convolutionResult.available = true; + convolutionResult.valid = false; + convolutionResult.status = i18n("Not enough data points available."); + emit q->dataChanged(); + sourceDataChangedSinceLastRecalc = false; + return; + } + + double* xdata = xdataVector.data(); + double* ydata = ydataVector.data(); + + // convolution settings + const bool absolute = convolutionData.absolute; + + DEBUG("absolute area:"<resize((int)np); + yVector->resize((int)np); + memcpy(xVector->data(), xdata, np * sizeof(double)); + memcpy(yVector->data(), ydata, np * sizeof(double)); +/////////////////////////////////////////////////////////// + + //write the result + convolutionResult.available = true; + convolutionResult.valid = true; + convolutionResult.status = QString::number(status); + convolutionResult.elapsedTime = timer.elapsed(); + convolutionResult.value = ydata[np-1]; + + //redraw the curve + emit q->dataChanged(); + sourceDataChangedSinceLastRecalc = false; +} + +//############################################################################## +//################## Serialization/Deserialization ########################### +//############################################################################## +//! Save as XML +void XYConvolutionCurve::save(QXmlStreamWriter* writer) const{ + Q_D(const XYConvolutionCurve); + + writer->writeStartElement("xyConvolutionCurve"); + + //write the base class + XYAnalysisCurve::save(writer); + + //write xy-convolution-curve specific information + // convolution data + writer->writeStartElement("convolutionData"); + writer->writeAttribute( "autoRange", QString::number(d->convolutionData.autoRange) ); + writer->writeAttribute( "xRangeMin", QString::number(d->convolutionData.xRange.first()) ); + writer->writeAttribute( "xRangeMax", QString::number(d->convolutionData.xRange.last()) ); + writer->writeAttribute( "absolute", QString::number(d->convolutionData.absolute) ); + writer->writeEndElement();// convolutionData + + // convolution results (generated columns) + writer->writeStartElement("convolutionResult"); + writer->writeAttribute( "available", QString::number(d->convolutionResult.available) ); + writer->writeAttribute( "valid", QString::number(d->convolutionResult.valid) ); + writer->writeAttribute( "status", d->convolutionResult.status ); + writer->writeAttribute( "time", QString::number(d->convolutionResult.elapsedTime) ); + writer->writeAttribute( "value", QString::number(d->convolutionResult.value) ); + + //save calculated columns if available + if (d->xColumn) { + d->xColumn->save(writer); + d->yColumn->save(writer); + } + writer->writeEndElement(); //"convolutionResult" + + writer->writeEndElement(); //"xyConvolutionCurve" +} + +//! Load from XML +bool XYConvolutionCurve::load(XmlStreamReader* reader, bool preview) { + Q_D(XYConvolutionCurve); + + KLocalizedString attributeWarning = ki18n("Attribute '%1' missing or empty, default value is used"); + QXmlStreamAttributes attribs; + QString str; + + while (!reader->atEnd()) { + reader->readNext(); + if (reader->isEndElement() && reader->name() == "xyConvolutionCurve") + break; + + if (!reader->isStartElement()) + continue; + + if (reader->name() == "xyAnalysisCurve") { + if ( !XYAnalysisCurve::load(reader, preview) ) + return false; + } else if (!preview && reader->name() == "convolutionData") { + attribs = reader->attributes(); + READ_INT_VALUE("autoRange", convolutionData.autoRange, bool); + READ_DOUBLE_VALUE("xRangeMin", convolutionData.xRange.first()); + READ_DOUBLE_VALUE("xRangeMax", convolutionData.xRange.last()); + READ_INT_VALUE("absolute", convolutionData.absolute, bool); + } else if (!preview && reader->name() == "convolutionResult") { + attribs = reader->attributes(); + READ_INT_VALUE("available", convolutionResult.available, int); + READ_INT_VALUE("valid", convolutionResult.valid, int); + READ_STRING_VALUE("status", convolutionResult.status); + READ_INT_VALUE("time", convolutionResult.elapsedTime, int); + READ_DOUBLE_VALUE("value", convolutionResult.value); + } else if (!preview && reader->name() == "column") { + Column* column = new Column("", AbstractColumn::Numeric); + if (!column->load(reader, preview)) { + delete column; + return false; + } + if (column->name()=="x") + d->xColumn = column; + else if (column->name()=="y") + d->yColumn = column; + } + } + + if (preview) + return true; + + // wait for data to be read before using the pointers + QThreadPool::globalInstance()->waitForDone(); + + if (d->xColumn && d->yColumn) { + d->xColumn->setHidden(true); + addChild(d->xColumn); + + d->yColumn->setHidden(true); + addChild(d->yColumn); + + d->xVector = static_cast* >(d->xColumn->data()); + d->yVector = static_cast* >(d->yColumn->data()); + + setUndoAware(false); + XYCurve::d_ptr->xColumn = d->xColumn; + XYCurve::d_ptr->yColumn = d->yColumn; + setUndoAware(true); + } + + return true; +} diff --git a/src/backend/worksheet/plots/cartesian/XYConvolutionCurve.h b/src/backend/worksheet/plots/cartesian/XYConvolutionCurve.h new file mode 100644 index 000000000..2c91cd508 --- /dev/null +++ b/src/backend/worksheet/plots/cartesian/XYConvolutionCurve.h @@ -0,0 +1,80 @@ +/*************************************************************************** + File : XYConvolutionCurve.h + Project : LabPlot + Description : A xy-curve defined by a convolution + -------------------------------------------------------------------- + Copyright : (C) 2018 Stefan Gerlach (stefan.gerlach@uni.kn) + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, * + * Boston, MA 02110-1301 USA * + * * + ***************************************************************************/ + +#ifndef XYCONVOLUTIONCURVE_H +#define XYCONVOLUTIONCURVE_H + +#include "backend/worksheet/plots/cartesian/XYAnalysisCurve.h" + +class XYConvolutionCurvePrivate; +class XYConvolutionCurve : public XYAnalysisCurve { +Q_OBJECT + +public: + struct ConvolutionData { + ConvolutionData() : absolute(false), autoRange(true), xRange(2) {}; + + //TODO: check options + bool absolute; // absolute area? + bool autoRange; // use all data? + QVector xRange; // x range for convolution + }; + struct ConvolutionResult { + ConvolutionResult() : available(false), valid(false), elapsedTime(0), value(0) {}; + + bool available; + bool valid; + QString status; + qint64 elapsedTime; + double value; // final result of convolution + }; + + explicit XYConvolutionCurve(const QString& name); + ~XYConvolutionCurve() override; + + void recalculate() override; + QIcon icon() const override; + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; + + CLASS_D_ACCESSOR_DECL(ConvolutionData, convolutionData, ConvolutionData) + const ConvolutionResult& convolutionResult() const; + + typedef XYConvolutionCurvePrivate Private; + +protected: + XYConvolutionCurve(const QString& name, XYConvolutionCurvePrivate* dd); + +private: + Q_DECLARE_PRIVATE(XYConvolutionCurve) + +signals: + void convolutionDataChanged(const XYConvolutionCurve::ConvolutionData&); +}; + +#endif diff --git a/src/backend/worksheet/plots/cartesian/XYConvolutionCurvePrivate.h b/src/backend/worksheet/plots/cartesian/XYConvolutionCurvePrivate.h new file mode 100644 index 000000000..1ea8d5ffd --- /dev/null +++ b/src/backend/worksheet/plots/cartesian/XYConvolutionCurvePrivate.h @@ -0,0 +1,51 @@ +/*************************************************************************** + File : XYConvolutionCurvePrivate.h + Project : LabPlot + Description : Private members of XYConvolutionCurve + -------------------------------------------------------------------- + Copyright : (C) 2018 Stefan Gerlach (stefan.gerlach@uni.kn) + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, * + * Boston, MA 02110-1301 USA * + * * + ***************************************************************************/ + +#ifndef XYCONVOLUTIONCURVEPRIVATE_H +#define XYCONVOLUTIONCURVEPRIVATE_H + +#include "backend/worksheet/plots/cartesian/XYAnalysisCurvePrivate.h" +#include "backend/worksheet/plots/cartesian/XYConvolutionCurve.h" + +class XYConvolutionCurve; +class Column; + +class XYConvolutionCurvePrivate : public XYAnalysisCurvePrivate { +public: + explicit XYConvolutionCurvePrivate(XYConvolutionCurve*); + ~XYConvolutionCurvePrivate() override; + + void recalculate(); + + XYConvolutionCurve::ConvolutionData convolutionData; + XYConvolutionCurve::ConvolutionResult convolutionResult; + + XYConvolutionCurve* const q; +}; + +#endif diff --git a/src/kdefrontend/dockwidgets/XYConvolutionCurveDock.cpp b/src/kdefrontend/dockwidgets/XYConvolutionCurveDock.cpp new file mode 100644 index 000000000..3cb5f5877 --- /dev/null +++ b/src/kdefrontend/dockwidgets/XYConvolutionCurveDock.cpp @@ -0,0 +1,477 @@ +/*************************************************************************** + File : XYConvolutionCurveDock.cpp + Project : LabPlot + -------------------------------------------------------------------- + Copyright : (C) 2018 Stefan Gerlach (stefan.gerlach@uni.kn) + Description : widget for editing properties of convolution curves + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, * + * Boston, MA 02110-1301 USA * + * * + ***************************************************************************/ + +#include "XYConvolutionCurveDock.h" +#include "backend/core/AspectTreeModel.h" +#include "backend/core/Project.h" +#include "backend/worksheet/plots/cartesian/XYConvolutionCurve.h" +#include "commonfrontend/widgets/TreeViewComboBox.h" + +#include +#include +#include + +extern "C" { +#include "backend/nsl/nsl_int.h" +} + +/*! + \class XYConvolutionCurveDock + \brief Provides a widget for editing the properties of the XYConvolutionCurves + (2D-curves defined by a convolution) currently selected in + the project explorer. + + If more then one curves are set, the properties of the first column are shown. + The changes of the properties are applied to all curves. + The exclusions are the name, the comment and the datasets (columns) of + the curves - these properties can only be changed if there is only one single curve. + + \ingroup kdefrontend +*/ + +XYConvolutionCurveDock::XYConvolutionCurveDock(QWidget* parent) : XYCurveDock(parent), + cbDataSourceCurve(nullptr), + cbXDataColumn(nullptr), + cbYDataColumn(nullptr), + m_convolutionCurve(nullptr) { + + //hide the line connection type + ui.cbLineType->setDisabled(true); + + //remove the tab "Error bars" + ui.tabWidget->removeTab(5); +} + +/*! + * // Tab "General" + */ +void XYConvolutionCurveDock::setupGeneral() { + QWidget* generalTab = new QWidget(ui.tabGeneral); + uiGeneralTab.setupUi(generalTab); + + QGridLayout* gridLayout = dynamic_cast(generalTab->layout()); + if (gridLayout) { + gridLayout->setContentsMargins(2,2,2,2); + gridLayout->setHorizontalSpacing(2); + gridLayout->setVerticalSpacing(2); + } + + uiGeneralTab.cbDataSourceType->addItem(i18n("Spreadsheet")); + uiGeneralTab.cbDataSourceType->addItem(i18n("XY-Curve")); + + cbDataSourceCurve = new TreeViewComboBox(generalTab); + gridLayout->addWidget(cbDataSourceCurve, 5, 2, 1, 3); + cbXDataColumn = new TreeViewComboBox(generalTab); + gridLayout->addWidget(cbXDataColumn, 6, 2, 1, 3); + cbYDataColumn = new TreeViewComboBox(generalTab); + gridLayout->addWidget(cbYDataColumn, 7, 2, 1, 3); + + uiGeneralTab.sbMin->setRange(-std::numeric_limits::max(), std::numeric_limits::max()); + uiGeneralTab.sbMax->setRange(-std::numeric_limits::max(), std::numeric_limits::max()); + + uiGeneralTab.pbRecalculate->setIcon(QIcon::fromTheme("run-build")); + + QHBoxLayout* layout = new QHBoxLayout(ui.tabGeneral); + layout->setMargin(0); + layout->addWidget(generalTab); + + //Slots + connect( uiGeneralTab.leName, &QLineEdit::textChanged, this, &XYConvolutionCurveDock::nameChanged ); + connect( uiGeneralTab.leComment, &QLineEdit::textChanged, this, &XYConvolutionCurveDock::commentChanged ); + connect( uiGeneralTab.chkVisible, SIGNAL(clicked(bool)), this, SLOT(visibilityChanged(bool)) ); + connect( uiGeneralTab.cbDataSourceType, SIGNAL(currentIndexChanged(int)), this, SLOT(dataSourceTypeChanged(int)) ); + connect( uiGeneralTab.cbAutoRange, SIGNAL(clicked(bool)), this, SLOT(autoRangeChanged()) ); + connect( uiGeneralTab.sbMin, SIGNAL(valueChanged(double)), this, SLOT(xRangeMinChanged()) ); + connect( uiGeneralTab.sbMax, SIGNAL(valueChanged(double)), this, SLOT(xRangeMaxChanged()) ); + connect( uiGeneralTab.cbAbsolute, SIGNAL(clicked(bool)), this, SLOT(absoluteChanged()) ); + connect( uiGeneralTab.pbRecalculate, SIGNAL(clicked()), this, SLOT(recalculateClicked()) ); + + connect( cbDataSourceCurve, SIGNAL(currentModelIndexChanged(QModelIndex)), this, SLOT(dataSourceCurveChanged(QModelIndex)) ); + connect( cbXDataColumn, SIGNAL(currentModelIndexChanged(QModelIndex)), this, SLOT(xDataColumnChanged(QModelIndex)) ); + connect( cbYDataColumn, SIGNAL(currentModelIndexChanged(QModelIndex)), this, SLOT(yDataColumnChanged(QModelIndex)) ); +} + +void XYConvolutionCurveDock::initGeneralTab() { + //if there are more then one curve in the list, disable the tab "general" + if (m_curvesList.size()==1) { + uiGeneralTab.lName->setEnabled(true); + uiGeneralTab.leName->setEnabled(true); + uiGeneralTab.lComment->setEnabled(true); + uiGeneralTab.leComment->setEnabled(true); + + uiGeneralTab.leName->setText(m_curve->name()); + uiGeneralTab.leComment->setText(m_curve->comment()); + }else { + uiGeneralTab.lName->setEnabled(false); + uiGeneralTab.leName->setEnabled(false); + uiGeneralTab.lComment->setEnabled(false); + uiGeneralTab.leComment->setEnabled(false); + + uiGeneralTab.leName->setText(""); + uiGeneralTab.leComment->setText(""); + } + + //show the properties of the first curve + m_convolutionCurve = dynamic_cast(m_curve); + + uiGeneralTab.cbDataSourceType->setCurrentIndex(m_convolutionCurve->dataSourceType()); + this->dataSourceTypeChanged(uiGeneralTab.cbDataSourceType->currentIndex()); + XYCurveDock::setModelIndexFromAspect(cbDataSourceCurve, m_convolutionCurve->dataSourceCurve()); + XYCurveDock::setModelIndexFromAspect(cbXDataColumn, m_convolutionCurve->xDataColumn()); + XYCurveDock::setModelIndexFromAspect(cbYDataColumn, m_convolutionCurve->yDataColumn()); + uiGeneralTab.cbAutoRange->setChecked(m_convolutionData.autoRange); + uiGeneralTab.sbMin->setValue(m_convolutionData.xRange.first()); + uiGeneralTab.sbMax->setValue(m_convolutionData.xRange.last()); + this->autoRangeChanged(); + // update list of selectable types + xDataColumnChanged(cbXDataColumn->currentModelIndex()); + + uiGeneralTab.cbAbsolute->setChecked(m_convolutionData.absolute); + this->absoluteChanged(); + + this->showConvolutionResult(); + + uiGeneralTab.chkVisible->setChecked( m_curve->isVisible() ); + + //Slots + connect(m_convolutionCurve, SIGNAL(aspectDescriptionChanged(const AbstractAspect*)), this, SLOT(curveDescriptionChanged(const AbstractAspect*))); + connect(m_convolutionCurve, SIGNAL(dataSourceTypeChanged(XYAnalysisCurve::DataSourceType)), this, SLOT(curveDataSourceTypeChanged(XYAnalysisCurve::DataSourceType))); + connect(m_convolutionCurve, SIGNAL(dataSourceCurveChanged(const XYCurve*)), this, SLOT(curveDataSourceCurveChanged(const XYCurve*))); + connect(m_convolutionCurve, SIGNAL(xDataColumnChanged(const AbstractColumn*)), this, SLOT(curveXDataColumnChanged(const AbstractColumn*))); + connect(m_convolutionCurve, SIGNAL(yDataColumnChanged(const AbstractColumn*)), this, SLOT(curveYDataColumnChanged(const AbstractColumn*))); + connect(m_convolutionCurve, SIGNAL(convolutionDataChanged(XYConvolutionCurve::ConvolutionData)), this, SLOT(curveConvolutionDataChanged(XYConvolutionCurve::ConvolutionData))); + connect(m_convolutionCurve, SIGNAL(sourceDataChanged()), this, SLOT(enableRecalculate())); +} + +void XYConvolutionCurveDock::setModel() { + QList list; + list<<"Folder"<<"Datapicker"<<"Worksheet"<<"CartesianPlot"<<"XYCurve"; + cbDataSourceCurve->setTopLevelClasses(list); + + QList hiddenAspects; + for (auto* curve : m_curvesList) + hiddenAspects << curve; + cbDataSourceCurve->setHiddenAspects(hiddenAspects); + + list.clear(); + list<<"Folder"<<"Workbook"<<"Datapicker"<<"DatapickerCurve"<<"Spreadsheet" + <<"FileDataSource"<<"Column"<<"Worksheet"<<"CartesianPlot"<<"XYFitCurve"; + cbXDataColumn->setTopLevelClasses(list); + cbYDataColumn->setTopLevelClasses(list); + + cbDataSourceCurve->setModel(m_aspectTreeModel); + cbXDataColumn->setModel(m_aspectTreeModel); + cbYDataColumn->setModel(m_aspectTreeModel); + + XYCurveDock::setModel(); +} + +/*! + sets the curves. The properties of the curves in the list \c list can be edited in this widget. +*/ +void XYConvolutionCurveDock::setCurves(QList list) { + m_initializing=true; + m_curvesList=list; + m_curve=list.first(); + m_convolutionCurve = dynamic_cast(m_curve); + m_aspectTreeModel = new AspectTreeModel(m_curve->project()); + this->setModel(); + m_convolutionData = m_convolutionCurve->convolutionData(); + initGeneralTab(); + initTabs(); + m_initializing=false; + + //hide the "skip gaps" option after the curves were set + ui.lLineSkipGaps->hide(); + ui.chkLineSkipGaps->hide(); +} + +//************************************************************* +//**** SLOTs for changes triggered in XYFitCurveDock ***** +//************************************************************* +void XYConvolutionCurveDock::nameChanged() { + if (m_initializing) + return; + + m_curve->setName(uiGeneralTab.leName->text()); +} + +void XYConvolutionCurveDock::commentChanged() { + if (m_initializing) + return; + + m_curve->setComment(uiGeneralTab.leComment->text()); +} + +void XYConvolutionCurveDock::dataSourceTypeChanged(int index) { + XYAnalysisCurve::DataSourceType type = (XYAnalysisCurve::DataSourceType)index; + if (type == XYAnalysisCurve::DataSourceSpreadsheet) { + uiGeneralTab.lDataSourceCurve->hide(); + cbDataSourceCurve->hide(); + uiGeneralTab.lXColumn->show(); + cbXDataColumn->show(); + uiGeneralTab.lYColumn->show(); + cbYDataColumn->show(); + } else { + uiGeneralTab.lDataSourceCurve->show(); + cbDataSourceCurve->show(); + uiGeneralTab.lXColumn->hide(); + cbXDataColumn->hide(); + uiGeneralTab.lYColumn->hide(); + cbYDataColumn->hide(); + } + + if (m_initializing) + return; + + for (auto* curve : m_curvesList) + dynamic_cast(curve)->setDataSourceType(type); +} + +void XYConvolutionCurveDock::dataSourceCurveChanged(const QModelIndex& index) { + AbstractAspect* aspect = static_cast(index.internalPointer()); + XYCurve* dataSourceCurve = dynamic_cast(aspect); + + // disable convolution orders and accuracies that need more data points + this->updateSettings(dataSourceCurve->xColumn()); + + if (m_initializing) + return; + + for (auto* curve : m_curvesList) + dynamic_cast(curve)->setDataSourceCurve(dataSourceCurve); +} + +void XYConvolutionCurveDock::xDataColumnChanged(const QModelIndex& index) { + if (m_initializing) + return; + + AbstractAspect* aspect = static_cast(index.internalPointer()); + AbstractColumn* column = dynamic_cast(aspect); + + for (auto* curve : m_curvesList) + dynamic_cast(curve)->setXDataColumn(column); + + if (column != nullptr) { + if (uiGeneralTab.cbAutoRange->isChecked()) { + uiGeneralTab.sbMin->setValue(column->minimum()); + uiGeneralTab.sbMax->setValue(column->maximum()); + } + + // disable convolution methods that need more data points + this->updateSettings(column); + } +} + +/*! + * disable deriv orders and accuracies that need more data points + */ +void XYConvolutionCurveDock::updateSettings(const AbstractColumn* column) { + if (!column) + return; + + //TODO +// size_t n=0; +// for (int row=0; row < column->rowCount(); row++) +// if (!std::isnan(column->valueAt(row)) && !column->isMasked(row)) +// n++; +} +void XYConvolutionCurveDock::yDataColumnChanged(const QModelIndex& index) { + if (m_initializing) + return; + + AbstractAspect* aspect = static_cast(index.internalPointer()); + AbstractColumn* column = dynamic_cast(aspect); + + for (auto* curve : m_curvesList) + dynamic_cast(curve)->setYDataColumn(column); +} + +void XYConvolutionCurveDock::autoRangeChanged() { + bool autoRange = uiGeneralTab.cbAutoRange->isChecked(); + m_convolutionData.autoRange = autoRange; + + if (autoRange) { + uiGeneralTab.lMin->setEnabled(false); + uiGeneralTab.sbMin->setEnabled(false); + uiGeneralTab.lMax->setEnabled(false); + uiGeneralTab.sbMax->setEnabled(false); + + const AbstractColumn* xDataColumn = 0; + if (m_convolutionCurve->dataSourceType() == XYAnalysisCurve::DataSourceSpreadsheet) + xDataColumn = m_convolutionCurve->xDataColumn(); + else { + if (m_convolutionCurve->dataSourceCurve()) + xDataColumn = m_convolutionCurve->dataSourceCurve()->xColumn(); + } + + if (xDataColumn) { + uiGeneralTab.sbMin->setValue(xDataColumn->minimum()); + uiGeneralTab.sbMax->setValue(xDataColumn->maximum()); + } + } else { + uiGeneralTab.lMin->setEnabled(true); + uiGeneralTab.sbMin->setEnabled(true); + uiGeneralTab.lMax->setEnabled(true); + uiGeneralTab.sbMax->setEnabled(true); + } + +} +void XYConvolutionCurveDock::xRangeMinChanged() { + double xMin = uiGeneralTab.sbMin->value(); + + m_convolutionData.xRange.first() = xMin; + uiGeneralTab.pbRecalculate->setEnabled(true); +} + +void XYConvolutionCurveDock::xRangeMaxChanged() { + double xMax = uiGeneralTab.sbMax->value(); + + m_convolutionData.xRange.last() = xMax; + uiGeneralTab.pbRecalculate->setEnabled(true); +} + +void XYConvolutionCurveDock::absoluteChanged() { + bool absolute = uiGeneralTab.cbAbsolute->isChecked(); + m_convolutionData.absolute = absolute; + + uiGeneralTab.pbRecalculate->setEnabled(true); +} + +void XYConvolutionCurveDock::recalculateClicked() { + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + + for (auto* curve : m_curvesList) + dynamic_cast(curve)->setConvolutionData(m_convolutionData); + + uiGeneralTab.pbRecalculate->setEnabled(false); + emit info(i18n("Convolution status: %1", m_convolutionCurve->convolutionResult().status)); + QApplication::restoreOverrideCursor(); +} + +void XYConvolutionCurveDock::enableRecalculate() const { + if (m_initializing) + return; + + //no convolution possible without the x- and y-data + bool hasSourceData = false; + if (m_convolutionCurve->dataSourceType() == XYAnalysisCurve::DataSourceSpreadsheet) { + AbstractAspect* aspectX = static_cast(cbXDataColumn->currentModelIndex().internalPointer()); + AbstractAspect* aspectY = static_cast(cbYDataColumn->currentModelIndex().internalPointer()); + hasSourceData = (aspectX!=0 && aspectY!=0); + } else { + hasSourceData = (m_convolutionCurve->dataSourceCurve() != NULL); + } + + uiGeneralTab.pbRecalculate->setEnabled(hasSourceData); +} + +/*! + * show the result and details of the convolution + */ +void XYConvolutionCurveDock::showConvolutionResult() { + const XYConvolutionCurve::ConvolutionResult& convolutionResult = m_convolutionCurve->convolutionResult(); + if (!convolutionResult.available) { + uiGeneralTab.teResult->clear(); + return; + } + + QString str = i18n("status: %1", convolutionResult.status) + "
"; + + if (!convolutionResult.valid) { + uiGeneralTab.teResult->setText(str); + return; //result is not valid, there was an error which is shown in the status-string, nothing to show more. + } + + if (convolutionResult.elapsedTime>1000) + str += i18n("calculation time: %1 s", QString::number(convolutionResult.elapsedTime/1000)) + "
"; + else + str += i18n("calculation time: %1 ms", QString::number(convolutionResult.elapsedTime)) + "
"; + + str += i18n("value: %1", QString::number(convolutionResult.value)) + "
"; + str += "

"; + + uiGeneralTab.teResult->setText(str); + + //enable the "recalculate"-button if the source data was changed since the last convolution + uiGeneralTab.pbRecalculate->setEnabled(m_convolutionCurve->isSourceDataChangedSinceLastRecalc()); +} + +//************************************************************* +//*********** SLOTs for changes triggered in XYCurve ********** +//************************************************************* +//General-Tab +void XYConvolutionCurveDock::curveDescriptionChanged(const AbstractAspect* aspect) { + if (m_curve != aspect) + return; + + m_initializing = true; + if (aspect->name() != uiGeneralTab.leName->text()) + uiGeneralTab.leName->setText(aspect->name()); + else if (aspect->comment() != uiGeneralTab.leComment->text()) + uiGeneralTab.leComment->setText(aspect->comment()); + m_initializing = false; +} + +void XYConvolutionCurveDock::curveDataSourceTypeChanged(XYAnalysisCurve::DataSourceType type) { + m_initializing = true; + uiGeneralTab.cbDataSourceType->setCurrentIndex(type); + m_initializing = false; +} + +void XYConvolutionCurveDock::curveDataSourceCurveChanged(const XYCurve* curve) { + m_initializing = true; + XYCurveDock::setModelIndexFromAspect(cbDataSourceCurve, curve); + m_initializing = false; +} + +void XYConvolutionCurveDock::curveXDataColumnChanged(const AbstractColumn* column) { + m_initializing = true; + XYCurveDock::setModelIndexFromAspect(cbXDataColumn, column); + m_initializing = false; +} + +void XYConvolutionCurveDock::curveYDataColumnChanged(const AbstractColumn* column) { + m_initializing = true; + XYCurveDock::setModelIndexFromAspect(cbYDataColumn, column); + m_initializing = false; +} + +void XYConvolutionCurveDock::curveConvolutionDataChanged(const XYConvolutionCurve::ConvolutionData& convolutionData) { + m_initializing = true; + m_convolutionData = convolutionData; + uiGeneralTab.cbAbsolute->setChecked(m_convolutionData.absolute); + this->absoluteChanged(); + + this->showConvolutionResult(); + m_initializing = false; +} + +void XYConvolutionCurveDock::dataChanged() { + this->enableRecalculate(); +} diff --git a/src/kdefrontend/dockwidgets/XYConvolutionCurveDock.h b/src/kdefrontend/dockwidgets/XYConvolutionCurveDock.h new file mode 100644 index 000000000..e1e69beaa --- /dev/null +++ b/src/kdefrontend/dockwidgets/XYConvolutionCurveDock.h @@ -0,0 +1,90 @@ +/*************************************************************************** + File : XYConvolutionCurveDock.h + Project : LabPlot + -------------------------------------------------------------------- + Copyright : (C) 2018 Stefan Gerlach (stefan.gerlach@uni.kn) + Description : widget for editing properties of convolution curves + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, * + * Boston, MA 02110-1301 USA * + * * + ***************************************************************************/ + +#ifndef XYCONVOLUTIONCURVEDOCK_H +#define XYCONVOLUTIONCURVEDOCK_H + +#include "kdefrontend/dockwidgets/XYCurveDock.h" +#include "backend/worksheet/plots/cartesian/XYConvolutionCurve.h" +#include "ui_xyconvolutioncurvedockgeneraltab.h" + +class TreeViewComboBox; + +class XYConvolutionCurveDock: public XYCurveDock { + Q_OBJECT + +public: + explicit XYConvolutionCurveDock(QWidget*); + void setCurves(QList); + virtual void setupGeneral(); + +private: + virtual void initGeneralTab(); + void showConvolutionResult(); + void updateSettings(const AbstractColumn*); + + Ui::XYConvolutionCurveDockGeneralTab uiGeneralTab; + TreeViewComboBox* cbDataSourceCurve; + TreeViewComboBox* cbXDataColumn; + TreeViewComboBox* cbYDataColumn; + + XYConvolutionCurve* m_convolutionCurve; + XYConvolutionCurve::ConvolutionData m_convolutionData; + +protected: + virtual void setModel(); + +private slots: + //SLOTs for changes triggered in XYConvolutionCurveDock + //general tab + void nameChanged(); + void commentChanged(); + void dataSourceTypeChanged(int); + void dataSourceCurveChanged(const QModelIndex&); + void xDataColumnChanged(const QModelIndex&); + void yDataColumnChanged(const QModelIndex&); + void autoRangeChanged(); + void xRangeMinChanged(); + void xRangeMaxChanged(); + void absoluteChanged(); + + void recalculateClicked(); + void enableRecalculate() const; + + //SLOTs for changes triggered in XYCurve + //General-Tab + void curveDescriptionChanged(const AbstractAspect*); + void curveDataSourceTypeChanged(XYAnalysisCurve::DataSourceType); + void curveDataSourceCurveChanged(const XYCurve*); + void curveXDataColumnChanged(const AbstractColumn*); + void curveYDataColumnChanged(const AbstractColumn*); + void curveConvolutionDataChanged(const XYConvolutionCurve::ConvolutionData&); + void dataChanged(); +}; + +#endif diff --git a/src/kdefrontend/ui/dockwidgets/xyconvolutioncurvedockgeneraltab.ui b/src/kdefrontend/ui/dockwidgets/xyconvolutioncurvedockgeneraltab.ui new file mode 100644 index 000000000..38d0a8e03 --- /dev/null +++ b/src/kdefrontend/ui/dockwidgets/xyconvolutioncurvedockgeneraltab.ui @@ -0,0 +1,364 @@ + + + XYConvolutionCurveDockGeneralTab + + + + 0 + 0 + 625 + 1374 + + + + + + + + 75 + true + + + + Convolution + + + + + + + Method: + + + + + + + + + false + + + + 0 + 0 + + + + + 50 + 0 + + + + Maximum: + + + + + + + false + + + 6 + + + + + + + + + Recalculate + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 24 + 10 + + + + + + + + Visible + + + + + + + Qt::Horizontal + + + + 266 + 20 + + + + + + + + true + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 13 + 23 + + + + + + + + + + + Auto + + + true + + + + + + + + + false + + + + 0 + 0 + + + + + 50 + 0 + + + + Minimum: + + + + + + + false + + + + 0 + 0 + + + + 6 + + + + + + + + + + + + x-Data: + + + + + + + + 0 + 0 + + + + Name: + + + + + + + Source: + + + + + + + Comment: + + + + + + + Curve: + + + + + + + y-Data: + + + + + + + x-Range: + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 18 + + + + + + + + + 75 + true + + + + Data + + + + + + + + + + Absolute area + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 18 + + + + + + + + + + + + + + + + 75 + true + + + + Results: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 10 + + + + + + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + + + + + +