diff --git a/src/backend/spreadsheet/SpreadsheetModel.cpp b/src/backend/spreadsheet/SpreadsheetModel.cpp index a41a5754f..31ffe95dc 100644 --- a/src/backend/spreadsheet/SpreadsheetModel.cpp +++ b/src/backend/spreadsheet/SpreadsheetModel.cpp @@ -1,467 +1,467 @@ /*************************************************************************** File : SpreadsheetModel.cpp Project : LabPlot Description : Model for the access to a Spreadsheet -------------------------------------------------------------------- Copyright : (C) 2007 Tilman Benkert (thzs@gmx.net) Copyright : (C) 2009 Knut Franke (knut.franke@gmx.de) Copyright : (C) 2013-2017 Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 "backend/spreadsheet/Spreadsheet.h" #include "backend/spreadsheet/SpreadsheetModel.h" #include "backend/core/datatypes/Double2StringFilter.h" #include #include #include #include /*! \class SpreadsheetModel \brief Model for the access to a Spreadsheet This is a model in the sense of Qt4 model/view framework which is used to access a Spreadsheet object from any of Qt4s view classes, typically a QTableView. Its main purposes are translating Spreadsheet signals into QAbstractItemModel signals and translating calls to the QAbstractItemModel read/write API into calls in the public API of Spreadsheet. In many cases a pointer to the addressed column is obtained by calling Spreadsheet::column() and the manipulation is done using the public API of column. \ingroup backend */ SpreadsheetModel::SpreadsheetModel(Spreadsheet* spreadsheet) : QAbstractItemModel(0), m_spreadsheet(spreadsheet), m_formula_mode(false) { updateVerticalHeader(); updateHorizontalHeader(); connect(m_spreadsheet, &Spreadsheet::aspectAboutToBeAdded, this, &SpreadsheetModel::handleAspectAboutToBeAdded); connect(m_spreadsheet, &Spreadsheet::aspectAdded, this, &SpreadsheetModel::handleAspectAdded); connect(m_spreadsheet, &Spreadsheet::aspectAboutToBeRemoved, this, &SpreadsheetModel::handleAspectAboutToBeRemoved); connect(m_spreadsheet, &Spreadsheet::aspectRemoved, this, &SpreadsheetModel::handleAspectRemoved); connect(m_spreadsheet, &Spreadsheet::aspectDescriptionChanged, this, &SpreadsheetModel::handleDescriptionChange); for (int i = 0; i < spreadsheet->columnCount(); ++i) { beginInsertColumns(QModelIndex(), i, i); handleAspectAdded(spreadsheet->column(i)); } } Qt::ItemFlags SpreadsheetModel::flags(const QModelIndex& index) const { if (index.isValid()) return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable; else return Qt::ItemIsEnabled; } QVariant SpreadsheetModel::data(const QModelIndex& index, int role) const { if( !index.isValid() ) return QVariant(); const int row = index.row(); const int col = index.column(); Column* col_ptr = m_spreadsheet->column(col); if(!col_ptr) return QVariant(); switch(role) { case Qt::ToolTipRole: if(col_ptr->isValid(row)) { if(col_ptr->isMasked(row)) return QVariant(i18n("%1, masked (ignored in all operations)", col_ptr->asStringColumn()->textAt(row))); else return QVariant(col_ptr->asStringColumn()->textAt(row)); } else { if(col_ptr->isMasked(row)) return QVariant(i18n("invalid cell, masked (ignored in all operations)")); else return QVariant(i18n("invalid cell (ignored in all operations)")); } case Qt::EditRole: if(col_ptr->isValid(row)) return QVariant(col_ptr->asStringColumn()->textAt(row)); //m_formula_mode is not used at the moment //if(m_formula_mode) // return QVariant(col_ptr->formula(row)); break; case Qt::DisplayRole: if(!col_ptr->isValid(row)) return QVariant("-"); //m_formula_mode is not used at the moment //if(m_formula_mode) // return QVariant(col_ptr->formula(row)); return QVariant(col_ptr->asStringColumn()->textAt(row)); case Qt::ForegroundRole: if(!col_ptr->isValid(index.row())) return QVariant(QBrush(Qt::red)); break; case MaskingRole: return QVariant(col_ptr->isMasked(row)); case FormulaRole: return QVariant(col_ptr->formula(row)); // case Qt::DecorationRole: // if(m_formula_mode) // return QIcon(QPixmap(":/equals.png")); //TODO } return QVariant(); } QVariant SpreadsheetModel::headerData(int section, Qt::Orientation orientation, int role) const { if ( (orientation == Qt::Horizontal && section > m_spreadsheet->columnCount()-1) || (orientation == Qt::Vertical && section > m_spreadsheet->rowCount()-1) ) return QVariant(); switch(orientation) { case Qt::Horizontal: switch(role) { case Qt::DisplayRole: case Qt::ToolTipRole: case Qt::EditRole: return m_horizontal_header_data.at(section); case Qt::DecorationRole: return m_spreadsheet->child(section)->icon(); case SpreadsheetModel::CommentRole: return m_spreadsheet->child(section)->comment(); } break; case Qt::Vertical: switch(role) { case Qt::DisplayRole: case Qt::ToolTipRole: return m_vertical_header_data.at(section); } } return QVariant(); } int SpreadsheetModel::rowCount(const QModelIndex& parent) const { Q_UNUSED(parent) return m_spreadsheet->rowCount(); } int SpreadsheetModel::columnCount(const QModelIndex& parent) const { Q_UNUSED(parent) return m_spreadsheet->columnCount(); } bool SpreadsheetModel::setData(const QModelIndex& index, const QVariant& value, int role) { if (!index.isValid()) return false; int row = index.row(); Column* column = m_spreadsheet->column(index.column()); //don't do anything if no new value was provided if (column->columnMode() == AbstractColumn::Numeric) { bool ok; QLocale locale; double new_value = locale.toDouble(value.toString(), &ok); if (ok) { if (column->valueAt(row) == new_value ) return false; } else { //an empty (non-numeric value) was provided if (std::isnan(column->valueAt(row))) return false; } } else { if (column->asStringColumn()->textAt(row) == value.toString()) return false; } switch(role) { case Qt::EditRole: { // remark: the validity of the cell is determined by the input filter if (m_formula_mode) column->setFormula(row, value.toString()); else column->asStringColumn()->setTextAt(row, value.toString()); return true; } case MaskingRole: { m_spreadsheet->column(index.column())->setMasked(row, value.toBool()); return true; } case FormulaRole: { m_spreadsheet->column(index.column())->setFormula(row, value.toString()); return true; } } return false; } QModelIndex SpreadsheetModel::index(int row, int column, const QModelIndex& parent) const { Q_UNUSED(parent) return createIndex(row, column); } QModelIndex SpreadsheetModel::parent(const QModelIndex& child) const { Q_UNUSED(child) return QModelIndex(); } bool SpreadsheetModel::hasChildren(const QModelIndex& parent) const { Q_UNUSED(parent) return false; } void SpreadsheetModel::handleAspectAboutToBeAdded(const AbstractAspect* parent, const AbstractAspect* before, const AbstractAspect* new_child) { const Column* col = qobject_cast(new_child); if (!col || parent != static_cast(m_spreadsheet)) return; //TODO: breaks undo/redo Q_UNUSED(before); // int index = before ? m_spreadsheet->indexOfChild(before) : 0; //beginInsertColumns(QModelIndex(), index, index); } void SpreadsheetModel::handleAspectAdded(const AbstractAspect * aspect) { const Column* col = qobject_cast(aspect); if (!col || aspect->parentAspect() != static_cast(m_spreadsheet)) return; updateVerticalHeader(); updateHorizontalHeader(); connect(col, &Column::plotDesignationChanged, this, &SpreadsheetModel::handlePlotDesignationChange); connect(col, &Column::modeChanged, this, &SpreadsheetModel::handleDataChange); connect(col, &Column::dataChanged, this, &SpreadsheetModel::handleDataChange); connect(col, &Column::modeChanged, this, &SpreadsheetModel::handleModeChange); connect(col, &Column::rowsInserted, this, &SpreadsheetModel::handleRowsInserted); connect(col, &Column::rowsRemoved, this, &SpreadsheetModel::handleRowsRemoved); connect(col, &Column::maskingChanged, this, &SpreadsheetModel::handleDataChange); connect(col->outputFilter(), &AbstractSimpleFilter::digitsChanged, this, &SpreadsheetModel::handleDigitsChange); beginResetModel(); //TODO: breaks undo/redo //endInsertColumns(); endResetModel(); m_spreadsheet->emitColumnCountChanged(); } void SpreadsheetModel::handleAspectAboutToBeRemoved(const AbstractAspect* aspect) { const Column* col = qobject_cast(aspect); if (!col || aspect->parentAspect() != static_cast(m_spreadsheet)) return; beginResetModel(); disconnect(col, 0, this, 0); } void SpreadsheetModel::handleAspectRemoved(const AbstractAspect* parent, const AbstractAspect* before, const AbstractAspect* child) { Q_UNUSED(before) const Column* col = qobject_cast(child); if (!col || parent != static_cast(m_spreadsheet)) return; updateVerticalHeader(); updateHorizontalHeader(); endResetModel(); m_spreadsheet->emitColumnCountChanged(); } void SpreadsheetModel::handleDescriptionChange(const AbstractAspect* aspect) { const Column* col = qobject_cast(aspect); if (!col || aspect->parentAspect() != static_cast(m_spreadsheet)) return; updateHorizontalHeader(); int index = m_spreadsheet->indexOfChild(col); emit headerDataChanged(Qt::Horizontal, index, index); } void SpreadsheetModel::handleModeChange(const AbstractColumn* col) { updateHorizontalHeader(); int index = m_spreadsheet->indexOfChild(col); emit headerDataChanged(Qt::Horizontal, index, index); handleDataChange(col); //output filter was changed after the mode change, update the signal-slot connection disconnect(0, SIGNAL(digitsChanged()), this, SLOT(handledigitsChange())); connect(dynamic_cast(col)->outputFilter(), SIGNAL(digitsChanged()), this, SLOT(handleDigitsChange())); } void SpreadsheetModel::handleDigitsChange() { const Double2StringFilter* filter = dynamic_cast(QObject::sender()); if (!filter) return; const AbstractColumn* col = filter->output(0); handleDataChange(col); } void SpreadsheetModel::handlePlotDesignationChange(const AbstractColumn* col) { updateHorizontalHeader(); int index = m_spreadsheet->indexOfChild(col); emit headerDataChanged(Qt::Horizontal, index, m_spreadsheet->columnCount()-1); } void SpreadsheetModel::handleDataChange(const AbstractColumn* col) { int i = m_spreadsheet->indexOfChild(col); emit dataChanged(index(0, i), index(col->rowCount()-1, i)); } void SpreadsheetModel::handleRowsInserted(const AbstractColumn* col, int before, int count) { Q_UNUSED(before) Q_UNUSED(count) updateVerticalHeader(); int i = m_spreadsheet->indexOfChild(col); emit dataChanged(index(0, i), index(col->rowCount()-1, i)); m_spreadsheet->emitRowCountChanged(); } void SpreadsheetModel::handleRowsRemoved(const AbstractColumn* col, int first, int count) { Q_UNUSED(first) Q_UNUSED(count) updateVerticalHeader(); int i = m_spreadsheet->indexOfChild(col); emit dataChanged(index(0, i), index(col->rowCount()-1, i)); m_spreadsheet->emitRowCountChanged(); } void SpreadsheetModel::updateVerticalHeader() { int old_rows = m_vertical_header_data.size(); int new_rows = m_spreadsheet->rowCount(); if (new_rows > old_rows) { beginInsertRows(QModelIndex(), old_rows, new_rows-1); for(int i=old_rows+1; i<=new_rows; i++) m_vertical_header_data << i; endInsertRows(); } else if (new_rows < old_rows) { beginRemoveRows(QModelIndex(), new_rows, old_rows-1); while (m_vertical_header_data.size() > new_rows) m_vertical_header_data.removeLast(); endRemoveRows(); } } void SpreadsheetModel::updateHorizontalHeader() { int column_count = m_spreadsheet->childCount(); while(m_horizontal_header_data.size() < column_count) m_horizontal_header_data << QString(); while(m_horizontal_header_data.size() > column_count) m_horizontal_header_data.removeLast(); for (int i = 0; i < column_count; i++) { Column* col = m_spreadsheet->child(i); QString type; switch(col->columnMode()) { case AbstractColumn::Numeric: type = QLatin1String(" {") + i18n("Numeric") + QLatin1Char('}'); break; case AbstractColumn::Integer: type = QLatin1String(" {") + i18n("Integer") + QLatin1Char('}'); break; case AbstractColumn::Text: type = QLatin1String(" {") + i18n("Text") + QLatin1Char('}'); break; case AbstractColumn::Month: - type = QLatin1String(" {") + i18n("Month names") + QLatin1Char('}'); + type = QLatin1String(" {") + i18n("Month Names") + QLatin1Char('}'); break; case AbstractColumn::Day: - type = QLatin1String(" {") + i18n("Day names") + QLatin1Char('}'); + type = QLatin1String(" {") + i18n("Day Names") + QLatin1Char('}'); break; case AbstractColumn::DateTime: - type = QLatin1String(" {") + i18n("Date and time") + QLatin1Char('}'); + type = QLatin1String(" {") + i18n("Date and Time") + QLatin1Char('}'); break; } QString designation; switch(col->plotDesignation()) { case AbstractColumn::NoDesignation: break; case AbstractColumn::X: designation = QLatin1String(" [X]"); break; case AbstractColumn::Y: designation = QLatin1String(" [Y]"); break; case AbstractColumn::Z: designation = QLatin1String(" [Z]"); break; case AbstractColumn::XError: designation = QLatin1String(" [") + i18n("X-error") + QLatin1Char(']'); break; case AbstractColumn::XErrorPlus: designation = QLatin1String(" [") + i18n("X-error +") + QLatin1Char(']'); break; case AbstractColumn::XErrorMinus: designation = QLatin1String(" [") + i18n("X-error -") + QLatin1Char(']'); break; case AbstractColumn::YError: designation = QLatin1String(" [") + i18n("Y-error") + QLatin1Char(']'); break; case AbstractColumn::YErrorPlus: designation = QLatin1String(" [") + i18n("Y-error +") + QLatin1Char(']'); break; case AbstractColumn::YErrorMinus: designation = QLatin1String(" [") + i18n("Y-error -") + QLatin1Char(']'); break; } m_horizontal_header_data.replace(i, col->name() + type + designation); } } Column* SpreadsheetModel::column(int index) { return m_spreadsheet->column(index); } void SpreadsheetModel::activateFormulaMode(bool on) { if (m_formula_mode == on) return; m_formula_mode = on; int rows = m_spreadsheet->rowCount(); int cols = m_spreadsheet->columnCount(); if (rows > 0 && cols > 0) emit dataChanged(index(0,0), index(rows-1,cols-1)); } bool SpreadsheetModel::formulaModeActive() const { return m_formula_mode; } diff --git a/src/kdefrontend/dockwidgets/XYDataReductionCurveDock.cpp b/src/kdefrontend/dockwidgets/XYDataReductionCurveDock.cpp index dff647f1d..10853fe2f 100644 --- a/src/kdefrontend/dockwidgets/XYDataReductionCurveDock.cpp +++ b/src/kdefrontend/dockwidgets/XYDataReductionCurveDock.cpp @@ -1,698 +1,698 @@ /*************************************************************************** File : XYDataReductionCurveDock.cpp Project : LabPlot -------------------------------------------------------------------- Copyright : (C) 2016 Stefan Gerlach (stefan.gerlach@uni.kn) Copyright : (C) 2017 Alexander Semke (alexander.semke@web.de) Description : widget for editing properties of data reduction 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 "XYDataReductionCurveDock.h" #include "backend/core/AspectTreeModel.h" #include "backend/core/Project.h" #include "backend/worksheet/plots/cartesian/XYDataReductionCurve.h" #include "commonfrontend/widgets/TreeViewComboBox.h" #include #include #include #include #include /*! \class XYDataReductionCurveDock \brief Provides a widget for editing the properties of the XYDataReductionCurves (2D-curves defined by an data reduction) 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 */ XYDataReductionCurveDock::XYDataReductionCurveDock(QWidget* parent, QStatusBar* sb) : XYCurveDock(parent), statusBar(sb), cbDataSourceCurve(nullptr), cbXDataColumn(nullptr), cbYDataColumn(nullptr), m_dataReductionCurve(nullptr) { //hide the line connection type ui.cbLineType->setDisabled(true); //remove the tab "Error bars" ui.tabWidget->removeTab(5); } /*! * // Tab "General" */ void XYDataReductionCurveDock::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); for (int i=0; i < NSL_GEOM_LINESIM_TYPE_COUNT; ++i) uiGeneralTab.cbType->addItem(i18n(nsl_geom_linesim_type_name[i])); uiGeneralTab.cbType->setItemData(nsl_geom_linesim_type_visvalingam_whyatt, i18n("This method is much slower than any other"), Qt::ToolTipRole); uiGeneralTab.sbMin->setRange(-std::numeric_limits::max(), std::numeric_limits::max()); uiGeneralTab.sbMax->setRange(-std::numeric_limits::max(), std::numeric_limits::max()); uiGeneralTab.sbTolerance->setRange(0.0, std::numeric_limits::max()); uiGeneralTab.sbTolerance2->setRange(0.0, 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, &XYDataReductionCurveDock::nameChanged ); connect( uiGeneralTab.leComment, &QLineEdit::textChanged, this, &XYDataReductionCurveDock::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.cbType, SIGNAL(currentIndexChanged(int)), this, SLOT(typeChanged()) ); connect( uiGeneralTab.chkAuto, SIGNAL(clicked(bool)), this, SLOT(autoToleranceChanged()) ); connect( uiGeneralTab.sbTolerance, SIGNAL(valueChanged(double)), this, SLOT(toleranceChanged()) ); connect( uiGeneralTab.chkAuto2, SIGNAL(clicked(bool)), this, SLOT(autoTolerance2Changed()) ); connect( uiGeneralTab.sbTolerance2, SIGNAL(valueChanged(double)), this, SLOT(tolerance2Changed()) ); 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 XYDataReductionCurveDock::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_dataReductionCurve = dynamic_cast(m_curve); uiGeneralTab.cbDataSourceType->setCurrentIndex(m_dataReductionCurve->dataSourceType()); this->dataSourceTypeChanged(uiGeneralTab.cbDataSourceType->currentIndex()); XYCurveDock::setModelIndexFromAspect(cbDataSourceCurve, m_dataReductionCurve->dataSourceCurve()); XYCurveDock::setModelIndexFromAspect(cbXDataColumn, m_dataReductionCurve->xDataColumn()); XYCurveDock::setModelIndexFromAspect(cbYDataColumn, m_dataReductionCurve->yDataColumn()); uiGeneralTab.cbAutoRange->setChecked(m_dataReductionData.autoRange); uiGeneralTab.sbMin->setValue(m_dataReductionData.xRange.first()); uiGeneralTab.sbMax->setValue(m_dataReductionData.xRange.last()); this->autoRangeChanged(); // update list of selectable types xDataColumnChanged(cbXDataColumn->currentModelIndex()); uiGeneralTab.cbType->setCurrentIndex(m_dataReductionData.type); this->typeChanged(); uiGeneralTab.chkAuto->setChecked(m_dataReductionData.autoTolerance); this->autoToleranceChanged(); uiGeneralTab.sbTolerance->setValue(m_dataReductionData.tolerance); this->toleranceChanged(); uiGeneralTab.chkAuto2->setChecked(m_dataReductionData.autoTolerance2); this->autoTolerance2Changed(); uiGeneralTab.sbTolerance2->setValue(m_dataReductionData.tolerance2); this->tolerance2Changed(); this->showDataReductionResult(); //enable the "recalculate"-button if the source data was changed since the last dataReduction uiGeneralTab.pbRecalculate->setEnabled(m_dataReductionCurve->isSourceDataChangedSinceLastRecalc()); uiGeneralTab.chkVisible->setChecked( m_curve->isVisible() ); //Slots connect(m_dataReductionCurve, SIGNAL(aspectDescriptionChanged(const AbstractAspect*)), this, SLOT(curveDescriptionChanged(const AbstractAspect*))); connect(m_dataReductionCurve, SIGNAL(dataSourceTypeChanged(XYAnalysisCurve::DataSourceType)), this, SLOT(curveDataSourceTypeChanged(XYAnalysisCurve::DataSourceType))); connect(m_dataReductionCurve, SIGNAL(dataSourceCurveChanged(const XYCurve*)), this, SLOT(curveDataSourceCurveChanged(const XYCurve*))); connect(m_dataReductionCurve, SIGNAL(xDataColumnChanged(const AbstractColumn*)), this, SLOT(curveXDataColumnChanged(const AbstractColumn*))); connect(m_dataReductionCurve, SIGNAL(yDataColumnChanged(const AbstractColumn*)), this, SLOT(curveYDataColumnChanged(const AbstractColumn*))); connect(m_dataReductionCurve, SIGNAL(dataReductionDataChanged(XYDataReductionCurve::DataReductionData)), this, SLOT(curveDataReductionDataChanged(XYDataReductionCurve::DataReductionData))); connect(m_dataReductionCurve, SIGNAL(sourceDataChanged()), this, SLOT(enableRecalculate())); } void XYDataReductionCurveDock::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 XYDataReductionCurveDock::setCurves(QList list) { m_initializing=true; m_curvesList=list; m_curve=list.first(); m_dataReductionCurve = dynamic_cast(m_curve); m_aspectTreeModel = new AspectTreeModel(m_curve->project()); this->setModel(); m_dataReductionData = m_dataReductionCurve->dataReductionData(); 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 XYDataReductionCurveDock::nameChanged() { if (m_initializing) return; m_curve->setName(uiGeneralTab.leName->text()); } void XYDataReductionCurveDock::commentChanged() { if (m_initializing) return; m_curve->setComment(uiGeneralTab.leComment->text()); } void XYDataReductionCurveDock::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 XYDataReductionCurveDock::dataSourceCurveChanged(const QModelIndex& index) { AbstractAspect* aspect = static_cast(index.internalPointer()); XYCurve* dataSourceCurve = dynamic_cast(aspect); // // disable deriv 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 XYDataReductionCurveDock::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); //TODO: this->updateSettings(column); ? if (column != 0 && uiGeneralTab.cbAutoRange->isChecked()) { uiGeneralTab.sbMin->setValue(column->minimum()); uiGeneralTab.sbMax->setValue(column->maximum()); } updateTolerance(); updateTolerance2(); } void XYDataReductionCurveDock::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); updateTolerance(); updateTolerance2(); } void XYDataReductionCurveDock::updateTolerance() { const AbstractColumn* xDataColumn = nullptr; const AbstractColumn* yDataColumn = nullptr; if (m_dataReductionCurve->dataSourceType() == XYAnalysisCurve::DataSourceSpreadsheet) { xDataColumn = m_dataReductionCurve->xDataColumn(); yDataColumn = m_dataReductionCurve->yDataColumn(); } else { if (m_dataReductionCurve->dataSourceCurve()) { xDataColumn = m_dataReductionCurve->dataSourceCurve()->xColumn(); yDataColumn = m_dataReductionCurve->dataSourceCurve()->yColumn(); } } if(xDataColumn == nullptr || yDataColumn == nullptr) return; //copy all valid data points for calculating tolerance to temporary vectors QVector xdataVector; QVector ydataVector; const double xmin = m_dataReductionData.xRange.first(); const double xmax = m_dataReductionData.xRange.last(); for (int row=0; rowrowCount(); ++row) { //only copy those data where _all_ values (for x and y, if given) are valid if (!std::isnan(xDataColumn->valueAt(row)) && !std::isnan(yDataColumn->valueAt(row)) && !xDataColumn->isMasked(row) && !yDataColumn->isMasked(row)) { // only when inside given range if (xDataColumn->valueAt(row) >= xmin && xDataColumn->valueAt(row) <= xmax) { xdataVector.append(xDataColumn->valueAt(row)); ydataVector.append(yDataColumn->valueAt(row)); } } } if(xdataVector.size() > 1) uiGeneralTab.cbType->setEnabled(true); else { uiGeneralTab.cbType->setEnabled(false); return; } DEBUG("automatic tolerance:"); DEBUG("clip_diag_perpoint =" << nsl_geom_linesim_clip_diag_perpoint(xdataVector.data(), ydataVector.data(), (size_t)xdataVector.size())); DEBUG("clip_area_perpoint =" << nsl_geom_linesim_clip_area_perpoint(xdataVector.data(), ydataVector.data(), (size_t)xdataVector.size())); DEBUG("avg_dist_perpoint =" << nsl_geom_linesim_avg_dist_perpoint(xdataVector.data(), ydataVector.data(), (size_t)xdataVector.size())); nsl_geom_linesim_type type = (nsl_geom_linesim_type)uiGeneralTab.cbType->currentIndex(); if (type == nsl_geom_linesim_type_raddist || type == nsl_geom_linesim_type_opheim) m_dataReductionData.tolerance = 10. * nsl_geom_linesim_clip_diag_perpoint(xdataVector.data(), ydataVector.data(), (size_t)xdataVector.size()); else if (type == nsl_geom_linesim_type_visvalingam_whyatt) m_dataReductionData.tolerance = 0.1 * nsl_geom_linesim_clip_area_perpoint(xdataVector.data(), ydataVector.data(), (size_t)xdataVector.size()); else if (type == nsl_geom_linesim_type_douglas_peucker_variant) m_dataReductionData.tolerance = xdataVector.size()/10.; // reduction to 10% else m_dataReductionData.tolerance = 2.*nsl_geom_linesim_avg_dist_perpoint(xdataVector.data(), ydataVector.data(), xdataVector.size()); //m_dataReductionData.tolerance = nsl_geom_linesim_clip_diag_perpoint(xdataVector.data(), ydataVector.data(), xdataVector.size()); uiGeneralTab.sbTolerance->setValue(m_dataReductionData.tolerance); } void XYDataReductionCurveDock::updateTolerance2() { nsl_geom_linesim_type type = (nsl_geom_linesim_type)uiGeneralTab.cbType->currentIndex(); if (type == nsl_geom_linesim_type_perpdist) uiGeneralTab.sbTolerance2->setValue(10); else if (type == nsl_geom_linesim_type_opheim) uiGeneralTab.sbTolerance2->setValue(5*uiGeneralTab.sbTolerance->value()); else if (type == nsl_geom_linesim_type_lang) uiGeneralTab.sbTolerance2->setValue(10); } void XYDataReductionCurveDock::autoRangeChanged() { bool autoRange = uiGeneralTab.cbAutoRange->isChecked(); m_dataReductionData.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_dataReductionCurve->dataSourceType() == XYAnalysisCurve::DataSourceSpreadsheet) xDataColumn = m_dataReductionCurve->xDataColumn(); else { if (m_dataReductionCurve->dataSourceCurve()) xDataColumn = m_dataReductionCurve->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 XYDataReductionCurveDock::xRangeMinChanged() { double xMin = uiGeneralTab.sbMin->value(); m_dataReductionData.xRange.first() = xMin; uiGeneralTab.pbRecalculate->setEnabled(true); } void XYDataReductionCurveDock::xRangeMaxChanged() { double xMax = uiGeneralTab.sbMax->value(); m_dataReductionData.xRange.last() = xMax; uiGeneralTab.pbRecalculate->setEnabled(true); } void XYDataReductionCurveDock::typeChanged() { nsl_geom_linesim_type type = (nsl_geom_linesim_type)uiGeneralTab.cbType->currentIndex(); m_dataReductionData.type = type; switch (type) { case nsl_geom_linesim_type_douglas_peucker: case nsl_geom_linesim_type_raddist: case nsl_geom_linesim_type_interp: case nsl_geom_linesim_type_reumann_witkam: - uiGeneralTab.lOption->setText(i18n("Tolerance (distance)")); + uiGeneralTab.lOption->setText(i18n("Tolerance (distance):")); uiGeneralTab.sbTolerance->setDecimals(6); uiGeneralTab.sbTolerance->setMinimum(0); uiGeneralTab.sbTolerance->setSingleStep(0.01); uiGeneralTab.lOption2->hide(); uiGeneralTab.chkAuto2->hide(); uiGeneralTab.sbTolerance2->hide(); if (uiGeneralTab.chkAuto->isChecked()) updateTolerance(); break; case nsl_geom_linesim_type_douglas_peucker_variant: - uiGeneralTab.lOption->setText(i18n("Number of points")); + uiGeneralTab.lOption->setText(i18n("Number of points:")); uiGeneralTab.sbTolerance->setDecimals(0); uiGeneralTab.sbTolerance->setMinimum(2); uiGeneralTab.sbTolerance->setSingleStep(1); uiGeneralTab.lOption2->hide(); uiGeneralTab.chkAuto2->hide(); uiGeneralTab.sbTolerance2->hide(); if (uiGeneralTab.chkAuto->isChecked()) updateTolerance(); break; case nsl_geom_linesim_type_nthpoint: - uiGeneralTab.lOption->setText(i18n("Step size")); + uiGeneralTab.lOption->setText(i18n("Step size:")); uiGeneralTab.sbTolerance->setValue(10); uiGeneralTab.sbTolerance->setDecimals(0); uiGeneralTab.sbTolerance->setMinimum(1); uiGeneralTab.sbTolerance->setSingleStep(1); uiGeneralTab.lOption2->hide(); uiGeneralTab.chkAuto2->hide(); uiGeneralTab.sbTolerance2->hide(); break; case nsl_geom_linesim_type_perpdist: // repeat option - uiGeneralTab.lOption->setText(i18n("Tolerance (distance)")); + uiGeneralTab.lOption->setText(i18n("Tolerance (distance):")); uiGeneralTab.sbTolerance->setDecimals(6); uiGeneralTab.sbTolerance->setMinimum(0); uiGeneralTab.sbTolerance->setSingleStep(0.01); uiGeneralTab.sbTolerance2->show(); uiGeneralTab.lOption2->show(); uiGeneralTab.chkAuto2->show(); - uiGeneralTab.lOption2->setText(i18n("Repeats")); + uiGeneralTab.lOption2->setText(i18n("Repeats:")); uiGeneralTab.sbTolerance2->setDecimals(0); uiGeneralTab.sbTolerance2->setMinimum(1); uiGeneralTab.sbTolerance2->setSingleStep(1); if (uiGeneralTab.chkAuto->isChecked()) updateTolerance(); if (uiGeneralTab.chkAuto2->isChecked()) updateTolerance2(); break; case nsl_geom_linesim_type_visvalingam_whyatt: - uiGeneralTab.lOption->setText(i18n("Tolerance (area)")); + uiGeneralTab.lOption->setText(i18n("Tolerance (area):")); uiGeneralTab.sbTolerance->setDecimals(6); uiGeneralTab.sbTolerance->setMinimum(0); uiGeneralTab.sbTolerance->setSingleStep(0.01); uiGeneralTab.lOption2->hide(); uiGeneralTab.chkAuto2->hide(); uiGeneralTab.sbTolerance2->hide(); if (uiGeneralTab.chkAuto->isChecked()) updateTolerance(); break; case nsl_geom_linesim_type_opheim: // min/max tol options - uiGeneralTab.lOption->setText(i18n(" Min. Tolerance")); + uiGeneralTab.lOption->setText(i18n("Minumum tolerance:")); uiGeneralTab.sbTolerance->setDecimals(6); uiGeneralTab.sbTolerance->setMinimum(0); uiGeneralTab.sbTolerance->setSingleStep(0.01); - uiGeneralTab.lOption2->setText(i18n("Max. Tolerance")); + uiGeneralTab.lOption2->setText(i18n("Maximum tolerance:")); uiGeneralTab.lOption2->show(); uiGeneralTab.chkAuto2->show(); uiGeneralTab.sbTolerance2->show(); uiGeneralTab.sbTolerance2->setDecimals(6); uiGeneralTab.sbTolerance2->setMinimum(0); uiGeneralTab.sbTolerance2->setSingleStep(0.01); if (uiGeneralTab.chkAuto->isChecked()) updateTolerance(); if (uiGeneralTab.chkAuto2->isChecked()) updateTolerance2(); break; case nsl_geom_linesim_type_lang: // distance/region - uiGeneralTab.lOption->setText(i18n("Tolerance (distance)")); + uiGeneralTab.lOption->setText(i18n("Tolerance (distance):")); uiGeneralTab.sbTolerance->setDecimals(6); uiGeneralTab.sbTolerance->setMinimum(0); uiGeneralTab.sbTolerance->setSingleStep(0.01); - uiGeneralTab.lOption2->setText(i18n("Search region")); + uiGeneralTab.lOption2->setText(i18n("Search region:")); uiGeneralTab.lOption2->show(); uiGeneralTab.chkAuto2->show(); uiGeneralTab.sbTolerance2->show(); uiGeneralTab.sbTolerance2->setDecimals(0); uiGeneralTab.sbTolerance2->setMinimum(1); uiGeneralTab.sbTolerance2->setSingleStep(1); if (uiGeneralTab.chkAuto->isChecked()) updateTolerance(); if (uiGeneralTab.chkAuto2->isChecked()) updateTolerance2(); break; } uiGeneralTab.pbRecalculate->setEnabled(true); } void XYDataReductionCurveDock::autoToleranceChanged() { bool autoTolerance = (bool)uiGeneralTab.chkAuto->isChecked(); m_dataReductionData.autoTolerance = autoTolerance; if (autoTolerance) { uiGeneralTab.sbTolerance->setEnabled(false); updateTolerance(); } else uiGeneralTab.sbTolerance->setEnabled(true); } void XYDataReductionCurveDock::toleranceChanged() { m_dataReductionData.tolerance = uiGeneralTab.sbTolerance->value(); uiGeneralTab.pbRecalculate->setEnabled(true); } void XYDataReductionCurveDock::autoTolerance2Changed() { bool autoTolerance2 = (bool)uiGeneralTab.chkAuto2->isChecked(); m_dataReductionData.autoTolerance2 = autoTolerance2; if (autoTolerance2) { uiGeneralTab.sbTolerance2->setEnabled(false); updateTolerance2(); } else uiGeneralTab.sbTolerance2->setEnabled(true); } void XYDataReductionCurveDock::tolerance2Changed() { m_dataReductionData.tolerance2 = uiGeneralTab.sbTolerance2->value(); uiGeneralTab.pbRecalculate->setEnabled(true); } void XYDataReductionCurveDock::recalculateClicked() { //show a progress bar in the status bar QProgressBar* progressBar = new QProgressBar(); progressBar->setMinimum(0); progressBar->setMaximum(100); connect(m_curve, SIGNAL(completed(int)), progressBar, SLOT(setValue(int))); statusBar->clearMessage(); statusBar->addWidget(progressBar, 1); QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); for (auto* curve : m_curvesList) dynamic_cast(curve)->setDataReductionData(m_dataReductionData); QApplication::restoreOverrideCursor(); statusBar->removeWidget(progressBar); uiGeneralTab.pbRecalculate->setEnabled(false); emit info(i18n("Data reduction status: %1", m_dataReductionCurve->dataReductionResult().status)); } void XYDataReductionCurveDock::enableRecalculate() const { if (m_initializing) return; //no dataReductioning possible without the x- and y-data bool hasSourceData = false; if (m_dataReductionCurve->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_dataReductionCurve->dataSourceCurve() != NULL); } uiGeneralTab.pbRecalculate->setEnabled(hasSourceData); } /*! * show the result and details of the dataReduction */ void XYDataReductionCurveDock::showDataReductionResult() { const XYDataReductionCurve::DataReductionResult& dataReductionResult = m_dataReductionCurve->dataReductionResult(); if (!dataReductionResult.available) { uiGeneralTab.teResult->clear(); return; } QString str = i18n("status: %1", dataReductionResult.status) + "
"; if (!dataReductionResult.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 (dataReductionResult.elapsedTime>1000) str += i18n("calculation time: %1 s", QString::number(dataReductionResult.elapsedTime/1000)) + "
"; else str += i18n("calculation time: %1 ms", QString::number(dataReductionResult.elapsedTime)) + "
"; str += "
"; str += i18n("number of points: %1", QString::number(dataReductionResult.npoints)) + "
"; str += i18n("positional squared error: %1", QString::number(dataReductionResult.posError)) + "
"; str += i18n("area error: %1", QString::number(dataReductionResult.areaError)) + "
"; uiGeneralTab.teResult->setText(str); } //************************************************************* //*********** SLOTs for changes triggered in XYCurve ********** //************************************************************* //General-Tab void XYDataReductionCurveDock::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 XYDataReductionCurveDock::curveDataSourceTypeChanged(XYAnalysisCurve::DataSourceType type) { m_initializing = true; uiGeneralTab.cbDataSourceType->setCurrentIndex(type); m_initializing = false; } void XYDataReductionCurveDock::curveDataSourceCurveChanged(const XYCurve* curve) { m_initializing = true; XYCurveDock::setModelIndexFromAspect(cbDataSourceCurve, curve); m_initializing = false; } void XYDataReductionCurveDock::curveXDataColumnChanged(const AbstractColumn* column) { m_initializing = true; XYCurveDock::setModelIndexFromAspect(cbXDataColumn, column); m_initializing = false; } void XYDataReductionCurveDock::curveYDataColumnChanged(const AbstractColumn* column) { m_initializing = true; XYCurveDock::setModelIndexFromAspect(cbYDataColumn, column); m_initializing = false; } void XYDataReductionCurveDock::curveDataReductionDataChanged(const XYDataReductionCurve::DataReductionData& dataReductionData) { m_initializing = true; m_dataReductionData = dataReductionData; //uiGeneralTab.cbType->setCurrentIndex(m_dataReductionData.type); //this->typeChanged(); this->showDataReductionResult(); m_initializing = false; } void XYDataReductionCurveDock::dataChanged() { this->enableRecalculate(); } diff --git a/src/kdefrontend/ui/fitoptionswidget.ui b/src/kdefrontend/ui/fitoptionswidget.ui index a409071ba..3fa350ecc 100644 --- a/src/kdefrontend/ui/fitoptionswidget.ui +++ b/src/kdefrontend/ui/fitoptionswidget.ui @@ -1,188 +1,188 @@ FitOptionsWidget 0 0 298 413 Qt::Horizontal 129 20 Apply Cancel 6 6 Tolerance: false Robust fit: Max. iterations: .. - <html><head/><body><p>This option can be used to turn on and off the usage of given data errors when fitting.</p></body></html> + This option can be used to turn on and off the usage of given data errors when fitting. Use given data errors true .. 6 6 Auto fit range true - <html><head/><body><p>If selected, the resulting fit parameter are set as new start values. </p></body></html> + If selected, the resulting fit parameter are set as new start values. Use results as new start values true Evaluated points: - <html><head/><body><p>If selected, the fit function is evaluated for the full range of data points and not only for the given x-range.</p></body></html> + If selected, the fit function is evaluated for the full range of data points and not only for the given x-range. Auto evaluation range true diff --git a/src/kdefrontend/worksheet/GridDialog.cpp b/src/kdefrontend/worksheet/GridDialog.cpp index 9a8ae7e7b..3d999e169 100644 --- a/src/kdefrontend/worksheet/GridDialog.cpp +++ b/src/kdefrontend/worksheet/GridDialog.cpp @@ -1,118 +1,118 @@ /*************************************************************************** File : GridDialog.cpp Project : LabPlot -------------------------------------------------------------------- Copyright : (C) 2011-2017 by Alexander Semke Email (use @ for *) : alexander.semke@web.de Description : dialog for editing the grid properties for the worksheet view ***************************************************************************/ /*************************************************************************** * * * 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 "GridDialog.h" #include #include #include #include #include #include #include //TODO: //1. improve the layout and move the UI-part to a ui-file //2. restore the dialog size //3. restore the currently active grid settings /** * @brief Provides a dialog for editing the grid properties for the worksheet view * \ingroup kdefrontend */ GridDialog::GridDialog(QWidget* parent) : QDialog(parent){ setWindowTitle(i18nc("@title:window", "Custom Grid")); QWidget* widget = new QWidget; QGridLayout* layout = new QGridLayout(widget); QLabel* label = new QLabel(i18n("Style:"), widget); layout->addWidget(label, 0, 0); cbStyle = new QComboBox(this); cbStyle->addItem(i18n("Lines")); cbStyle->addItem(i18n("Dots")); cbStyle->setCurrentIndex(0); layout->addWidget(cbStyle, 0, 1); label = new QLabel(i18n("Horizontal spacing:"), widget); layout->addWidget(label, 1, 0); sbHorizontalSpacing = new QSpinBox(widget); sbHorizontalSpacing->setRange(1,100); sbHorizontalSpacing->setValue(10); layout->addWidget(sbHorizontalSpacing, 1, 1); label = new QLabel(i18n("Vertical spacing:"), widget); layout->addWidget(label, 2, 0); sbVerticalSpacing = new QSpinBox(widget); sbVerticalSpacing->setRange(1,100); sbVerticalSpacing->setValue(10); layout->addWidget(sbVerticalSpacing, 2, 1); label = new QLabel(i18n("Color:"), widget); layout->addWidget(label, 3, 0); kcbColor = new KColorButton(widget); kcbColor->setColor(Qt::gray); layout->addWidget(kcbColor , 3, 1); label = new QLabel(i18n("Opacity:"), widget); layout->addWidget(label, 4, 0); sbOpacity = new QSpinBox(widget); sbOpacity->setRange(1,100); sbOpacity->setValue(100); layout->addWidget(sbOpacity, 4, 1); - label = new QLabel(i18n("%"), widget); + label = new QLabel(i18n(" %"), widget); layout->addWidget(label, 4, 2); QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); QVBoxLayout* vlayout = new QVBoxLayout(this); vlayout->addWidget(widget); vlayout->addWidget(buttonBox); connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); } void GridDialog::save(WorksheetView::GridSettings& settings){ if (cbStyle->currentIndex() == 0) settings.style = WorksheetView::LineGrid; else settings.style = WorksheetView::DotGrid; settings.horizontalSpacing = sbHorizontalSpacing->value(); settings.verticalSpacing = sbVerticalSpacing->value(); settings.color = kcbColor->color(); settings.opacity = (float)sbOpacity->value()/100; }