diff --git a/src/kdefrontend/dockwidgets/HistogramDock.cpp b/src/kdefrontend/dockwidgets/HistogramDock.cpp index b53474eae..e868ba64a 100644 --- a/src/kdefrontend/dockwidgets/HistogramDock.cpp +++ b/src/kdefrontend/dockwidgets/HistogramDock.cpp @@ -1,1081 +1,1089 @@ /*************************************************************************** File : HistogramDock.cpp Project : LabPlot Description : widget for Histogram properties -------------------------------------------------------------------- Copyright : (C) 2016 Anu Mittal (anu22mittal@gmail.com) ***************************************************************************/ /*************************************************************************** * * * 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 "HistogramDock.h" #include "backend/worksheet/plots/cartesian/Histogram.h" #include "backend/worksheet/Worksheet.h" #include "backend/core/AspectTreeModel.h" #include "backend/core/column/Column.h" #include "backend/core/Project.h" #include "backend/core/datatypes/Double2StringFilter.h" #include "backend/core/datatypes/DateTime2StringFilter.h" #include "commonfrontend/widgets/TreeViewComboBox.h" #include "kdefrontend/TemplateHandler.h" #include "kdefrontend/GuiTools.h" #include #include #include #include +#include #include #include #include #include /*! \class HistogramDock \brief Provides a widget for editing the properties of the Histograms (2D-curves) 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 */ HistogramDock::HistogramDock(QWidget* parent) : QWidget(parent), cbXColumn(nullptr), m_curve(nullptr), m_aspectTreeModel(nullptr), m_initializing(false) { ui.setupUi(this); //Tab "Values" QGridLayout* gridLayout = qobject_cast(ui.tabValues->layout()); cbValuesColumn = new TreeViewComboBox(ui.tabValues); gridLayout->addWidget(cbValuesColumn, 2, 2, 1, 1); //Tab "Filling" ui.cbFillingColorStyle->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon); ui.bFillingOpen->setIcon( QIcon::fromTheme("document-open") ); QCompleter* completer = new QCompleter(this); completer->setModel(new QDirModel); ui.leFillingFileName->setCompleter(completer); //adjust layouts in the tabs for (int i=0; icount(); ++i){ QGridLayout* layout = dynamic_cast(ui.tabWidget->widget(i)->layout()); if (!layout) continue; layout->setContentsMargins(2,2,2,2); layout->setHorizontalSpacing(2); layout->setVerticalSpacing(2); } //Slots //Values connect( ui.cbValuesType, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesTypeChanged(int)) ); connect( cbValuesColumn, SIGNAL(currentModelIndexChanged(QModelIndex)), this, SLOT(valuesColumnChanged(QModelIndex)) ); connect( ui.cbValuesPosition, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesPositionChanged(int)) ); connect( ui.sbValuesDistance, SIGNAL(valueChanged(double)), this, SLOT(valuesDistanceChanged(double)) ); connect( ui.sbValuesRotation, SIGNAL(valueChanged(int)), this, SLOT(valuesRotationChanged(int)) ); connect( ui.sbValuesOpacity, SIGNAL(valueChanged(int)), this, SLOT(valuesOpacityChanged(int)) ); //TODO connect( ui.cbValuesFormat, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesColumnFormatChanged(int)) ); connect( ui.leValuesPrefix, SIGNAL(returnPressed()), this, SLOT(valuesPrefixChanged()) ); connect( ui.leValuesSuffix, SIGNAL(returnPressed()), this, SLOT(valuesSuffixChanged()) ); connect( ui.kfrValuesFont, SIGNAL(fontSelected(QFont)), this, SLOT(valuesFontChanged(QFont)) ); connect( ui.kcbValuesColor, SIGNAL(changed(QColor)), this, SLOT(valuesColorChanged(QColor)) ); //Filling connect( ui.cbFillingPosition, SIGNAL(currentIndexChanged(int)), this, SLOT(fillingPositionChanged(int)) ); connect( ui.cbFillingType, SIGNAL(currentIndexChanged(int)), this, SLOT(fillingTypeChanged(int)) ); connect( ui.cbFillingColorStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(fillingColorStyleChanged(int)) ); connect( ui.cbFillingImageStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(fillingImageStyleChanged(int)) ); connect( ui.cbFillingBrushStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(fillingBrushStyleChanged(int)) ); connect( ui.bFillingOpen, SIGNAL(clicked(bool)), this, SLOT(selectFile())); connect( ui.leFillingFileName, SIGNAL(returnPressed()), this, SLOT(fileNameChanged()) ); connect( ui.leFillingFileName, SIGNAL(textChanged(const QString&)), this, SLOT(fileNameChanged()) ); connect( ui.kcbFillingFirstColor, SIGNAL(changed(QColor)), this, SLOT(fillingFirstColorChanged(QColor)) ); connect( ui.kcbFillingSecondColor, SIGNAL(changed(QColor)), this, SLOT(fillingSecondColorChanged(QColor)) ); connect( ui.sbFillingOpacity, SIGNAL(valueChanged(int)), this, SLOT(fillingOpacityChanged(int)) ); //template handler TemplateHandler* templateHandler = new TemplateHandler(this, TemplateHandler::Histogram); ui.verticalLayout->addWidget(templateHandler); templateHandler->show(); connect(templateHandler, SIGNAL(loadConfigRequested(KConfig&)), this, SLOT(loadConfigFromTemplate(KConfig&))); connect(templateHandler, SIGNAL(saveConfigRequested(KConfig&)), this, SLOT(saveConfigAsTemplate(KConfig&))); connect(templateHandler, SIGNAL(info(QString)), this, SIGNAL(info(QString))); retranslateUi(); init(); } HistogramDock::~HistogramDock() { if (m_aspectTreeModel) delete m_aspectTreeModel; } //TODO: very similiar to ColumnDock void HistogramDock::updateValuesFormatWidgets(const AbstractColumn::ColumnMode columnMode) { ui.cbValuesFormat->clear(); switch (columnMode) { case AbstractColumn::Numeric: ui.cbValuesFormat->addItem(i18n("Decimal"), QVariant('f')); ui.cbValuesFormat->addItem(i18n("Scientific (e)"), QVariant('e')); ui.cbValuesFormat->addItem(i18n("Scientific (E)"), QVariant('E')); ui.cbValuesFormat->addItem(i18n("Automatic (e)"), QVariant('g')); ui.cbValuesFormat->addItem(i18n("Automatic (E)"), QVariant('G')); break; case AbstractColumn::Integer: break; case AbstractColumn::Text: ui.cbValuesFormat->addItem(i18n("Text"), QVariant()); break; case AbstractColumn::Month: ui.cbValuesFormat->addItem(i18n("Number without leading zero"), QVariant("M")); ui.cbValuesFormat->addItem(i18n("Number with leading zero"), QVariant("MM")); ui.cbValuesFormat->addItem(i18n("Abbreviated month name"), QVariant("MMM")); ui.cbValuesFormat->addItem(i18n("Full month name"), QVariant("MMMM")); break; case AbstractColumn::Day: ui.cbValuesFormat->addItem(i18n("Number without leading zero"), QVariant("d")); ui.cbValuesFormat->addItem(i18n("Number with leading zero"), QVariant("dd")); ui.cbValuesFormat->addItem(i18n("Abbreviated day name"), QVariant("ddd")); ui.cbValuesFormat->addItem(i18n("Full day name"), QVariant("dddd")); break; case AbstractColumn::DateTime: for (const auto& s: AbstractColumn::dateFormats()) ui.cbValuesFormat->addItem(s, QVariant(s)); for (const auto& s: AbstractColumn::timeFormats()) ui.cbValuesFormat->addItem(s, QVariant(s)); for (const auto& s1: AbstractColumn::dateFormats()) for (const auto& s2: AbstractColumn::timeFormats()) ui.cbValuesFormat->addItem(s1 + ' ' + s2, QVariant(s1 + ' ' + s2)); break; } ui.cbValuesFormat->setCurrentIndex(0); if (columnMode == AbstractColumn::Numeric) { ui.lValuesPrecision->show(); ui.sbValuesPrecision->show(); } else { ui.lValuesPrecision->hide(); ui.sbValuesPrecision->hide(); } if (columnMode == AbstractColumn::Text) { ui.lValuesFormatTop->hide(); ui.lValuesFormat->hide(); ui.cbValuesFormat->hide(); } else { ui.lValuesFormatTop->show(); ui.lValuesFormat->show(); ui.cbValuesFormat->show(); ui.cbValuesFormat->setCurrentIndex(0); } if (columnMode == AbstractColumn::DateTime) { ui.cbValuesFormat->setEditable(true); } else { ui.cbValuesFormat->setEditable(false); } } //TODO: very similiar to ColumnDock void HistogramDock::showValuesColumnFormat(const Column* column){ if (!column){ // no valid column is available // -> hide all the format properties widgets (equivalent to showing the properties of the column mode "Text") this->updateValuesFormatWidgets(AbstractColumn::Text); }else{ AbstractColumn::ColumnMode columnMode = column->columnMode(); //update the format widgets for the new column mode this->updateValuesFormatWidgets(columnMode); //show the actuall formating properties switch(columnMode) { case AbstractColumn::Numeric:{ Double2StringFilter * filter = static_cast(column->outputFilter()); ui.cbValuesFormat->setCurrentIndex(ui.cbValuesFormat->findData(filter->numericFormat())); ui.sbValuesPrecision->setValue(filter->numDigits()); break; } case AbstractColumn::Text: case AbstractColumn::Integer: break; case AbstractColumn::Month: case AbstractColumn::Day: case AbstractColumn::DateTime: { DateTime2StringFilter * filter = static_cast(column->outputFilter()); ui.cbValuesFormat->setCurrentIndex(ui.cbValuesFormat->findData(filter->format())); break; } } } } void HistogramDock::setModelIndexFromColumn(TreeViewComboBox* cb, const AbstractColumn* column) { if (column) cb->setCurrentModelIndex(m_aspectTreeModel->modelIndexOfAspect(column)); else cb->setCurrentModelIndex(QModelIndex()); } void HistogramDock::retranslateUi() { //TODO: // uiGeneralTab.lName->setText(i18n("Name")); // uiGeneralTab.lComment->setText(i18n("Comment")); // uiGeneralTab.chkVisible->setText(i18n("Visible")); // uiGeneralTab.lXColumn->setText(i18n("x-data")); // uiGeneralTab.lYColumn->setText(i18n("y-data")); //TODO updatePenStyles, updateBrushStyles for all comboboxes } // "General"-tab void HistogramDock::nameChanged() { if (m_initializing) return; m_curve->setName(uiGeneralTab.leName->text()); } void HistogramDock::commentChanged() { if (m_initializing) return; m_curve->setComment(uiGeneralTab.leComment->text()); } void HistogramDock::visibilityChanged(bool state){ if (m_initializing) return; for (auto* curve: m_curvesList) curve->setVisible(state); } void HistogramDock::valuesColorChanged(const QColor& color){ if (m_initializing) return; for (auto* curve: m_curvesList) curve->setValuesColor(color); } void HistogramDock::init(){ //Values ui.cbValuesType->addItem(i18n("no values")); ui.cbValuesType->addItem("y"); ui.cbValuesType->addItem(i18n("custom column")); ui.cbValuesPosition->addItem(i18n("above")); ui.cbValuesPosition->addItem(i18n("below")); ui.cbValuesPosition->addItem(i18n("left")); ui.cbValuesPosition->addItem(i18n("right")); //Filling ui.cbFillingPosition->clear(); ui.cbFillingPosition->addItem(i18n("none")); ui.cbFillingPosition->addItem(i18n("above")); ui.cbFillingPosition->addItem(i18n("below")); ui.cbFillingPosition->addItem(i18n("zero baseline")); ui.cbFillingPosition->addItem(i18n("left")); ui.cbFillingPosition->addItem(i18n("right")); ui.cbFillingType->clear(); ui.cbFillingType->addItem(i18n("color")); ui.cbFillingType->addItem(i18n("image")); ui.cbFillingType->addItem(i18n("pattern")); ui.cbFillingColorStyle->clear(); ui.cbFillingColorStyle->addItem(i18n("single color")); ui.cbFillingColorStyle->addItem(i18n("horizontal linear gradient")); ui.cbFillingColorStyle->addItem(i18n("vertical linear gradient")); ui.cbFillingColorStyle->addItem(i18n("diagonal linear gradient (start from top left)")); ui.cbFillingColorStyle->addItem(i18n("diagonal linear gradient (start from bottom left)")); ui.cbFillingColorStyle->addItem(i18n("radial gradient")); ui.cbFillingImageStyle->clear(); ui.cbFillingImageStyle->addItem(i18n("scaled and cropped")); ui.cbFillingImageStyle->addItem(i18n("scaled")); ui.cbFillingImageStyle->addItem(i18n("scaled, keep proportions")); ui.cbFillingImageStyle->addItem(i18n("centered")); ui.cbFillingImageStyle->addItem(i18n("tiled")); ui.cbFillingImageStyle->addItem(i18n("center tiled")); GuiTools::updateBrushStyles(ui.cbFillingBrushStyle, Qt::SolidPattern); } void HistogramDock::setModel() { QList list; list<<"Folder"<<"Workbook"<<"Datapicker"<<"DatapickerCurve"<<"Spreadsheet" <<"FileDataSource"<<"Column"<<"Worksheet"<<"CartesianPlot"<< "Histogram" <<"XYInterpolationCurve"<<"XYFitCurve"<<"XYFourierFilterCurve"; if (cbXColumn) { cbXColumn->setTopLevelClasses(list); } cbValuesColumn->setTopLevelClasses(list); list.clear(); list<<"Column"; m_aspectTreeModel->setSelectableAspects(list); if (cbXColumn) cbXColumn->setModel(m_aspectTreeModel); cbValuesColumn->setModel(m_aspectTreeModel); } void HistogramDock::setCurves(QList list){ m_initializing=true; m_curvesList=list; m_curve=list.first(); Q_ASSERT(m_curve); m_aspectTreeModel = new AspectTreeModel(m_curve->project()); setModel(); initGeneralTab(); initTabs(); m_initializing=false; } void HistogramDock::initGeneralTab(){ //if there are more then one curve in the list, disable the content in 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.lXColumn->setEnabled(true); cbXColumn->setEnabled(true); this->setModelIndexFromColumn(cbXColumn, m_curve->xColumn()); 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.lXColumn->setEnabled(false); cbXColumn->setEnabled(false); cbXColumn->setCurrentModelIndex(QModelIndex()); uiGeneralTab.leName->setText(""); uiGeneralTab.leComment->setText(""); } //show the properties of the first curve const Histogram::HistogramData& data = m_curve->histogramData(); uiGeneralTab.cbHistogramType->setCurrentIndex(data.type); uiGeneralTab.cbBins->setCurrentIndex(data.binsOption); uiGeneralTab.chkVisible->setChecked( m_curve->isVisible() ); connect(m_curve, SIGNAL(linePenChanged(QPen)), this, SLOT(curveLinePenChanged(QPen))); connect(m_curve, SIGNAL(visibilityChanged(bool)), this, SLOT(curveVisibilityChanged(bool))); uiGeneralTab.pbRecalculate->setEnabled(m_curve->isSourceDataChangedSinceLastPlot()); //Slots connect(m_curve, SIGNAL(aspectDescriptionChanged(const AbstractAspect*)), this, SLOT(curveDescriptionChanged(const AbstractAspect*))); connect(m_curve, SIGNAL(histogramDataChanged(Histogram::HistogramData)), this, SLOT(curveHistogramDataChanged(Histogram::HistogramData))); } //************************************************************* //**** SLOTs for changes triggered in HistogramDock ***** //************************************************************* void HistogramDock::recalculateClicked() { Histogram::HistogramData data; if( data.type != (Histogram::HistogramType)uiGeneralTab.cbHistogramType->currentIndex()) data.type = (Histogram::HistogramType)uiGeneralTab.cbHistogramType->currentIndex(); data.binsOption= (Histogram::BinsOption)uiGeneralTab.cbBins->currentIndex(); data.binValue = uiGeneralTab.sbBins->value(); // m_curve->retransform(); foreach(Histogram* curve, m_curvesList) dynamic_cast(curve)->setHistogramData(data); uiGeneralTab.pbRecalculate->setEnabled(false); } void HistogramDock::enableRecalculate() const { if (m_initializing) return; uiGeneralTab.pbRecalculate->setEnabled(true); } void HistogramDock::curveLinePenChanged(const QPen& pen) { m_initializing = true; uiGeneralTab.kcbLineColor->setColor( pen.color()); m_initializing = false; } //Values-Tab void HistogramDock::curveValuesTypeChanged(Histogram::ValuesType type) { m_initializing = true; ui.cbValuesType->setCurrentIndex((int) type); m_initializing = false; } void HistogramDock::curveValuesColumnChanged(const AbstractColumn* column) { m_initializing = true; this->setModelIndexFromColumn(cbValuesColumn, column); m_initializing = false; } void HistogramDock::curveValuesPositionChanged(Histogram::ValuesPosition position) { m_initializing = true; ui.cbValuesPosition->setCurrentIndex((int) position); m_initializing = false; } void HistogramDock::curveValuesDistanceChanged(qreal distance) { m_initializing = true; ui.sbValuesDistance->setValue( Worksheet::convertFromSceneUnits(distance, Worksheet::Point) ); m_initializing = false; } void HistogramDock::curveValuesRotationAngleChanged(qreal angle) { m_initializing = true; ui.sbValuesRotation->setValue(angle); m_initializing = false; } void HistogramDock::curveValuesOpacityChanged(qreal opacity) { m_initializing = true; ui.sbValuesOpacity->setValue( round(opacity*100.0) ); m_initializing = false; } void HistogramDock::curveValuesPrefixChanged(QString prefix) { m_initializing = true; ui.leValuesPrefix->setText(prefix); m_initializing = false; } void HistogramDock::curveValuesSuffixChanged(QString suffix) { m_initializing = true; ui.leValuesSuffix->setText(suffix); m_initializing = false; } void HistogramDock::curveValuesFontChanged(QFont font) { m_initializing = true; font.setPointSizeF( round(Worksheet::convertFromSceneUnits(font.pixelSize(), Worksheet::Point)) ); ui.kfrValuesFont->setFont(font); m_initializing = false; } void HistogramDock::curveValuesColorChanged(QColor color) { m_initializing = true; ui.kcbValuesColor->setColor(color); m_initializing = false; } /*! called when the type of the values (none, x, y, (x,y) etc.) was changed. */ void HistogramDock::valuesTypeChanged(int index) { Histogram::ValuesType valuesType = Histogram::ValuesType(index); if (valuesType == Histogram::NoValues){ //no values are to paint -> deactivate all the pertinent widgets ui.cbValuesPosition->setEnabled(false); ui.lValuesColumn->hide(); cbValuesColumn->hide(); ui.sbValuesDistance->setEnabled(false); ui.sbValuesRotation->setEnabled(false); ui.sbValuesOpacity->setEnabled(false); ui.cbValuesFormat->setEnabled(false); ui.cbValuesFormat->setEnabled(false); ui.sbValuesPrecision->setEnabled(false); ui.leValuesPrefix->setEnabled(false); ui.leValuesSuffix->setEnabled(false); ui.kfrValuesFont->setEnabled(false); ui.kcbValuesColor->setEnabled(false); } else { ui.cbValuesPosition->setEnabled(true); ui.sbValuesDistance->setEnabled(true); ui.sbValuesRotation->setEnabled(true); ui.sbValuesOpacity->setEnabled(true); ui.cbValuesFormat->setEnabled(true); ui.sbValuesPrecision->setEnabled(true); ui.leValuesPrefix->setEnabled(true); ui.leValuesSuffix->setEnabled(true); ui.kfrValuesFont->setEnabled(true); ui.kcbValuesColor->setEnabled(true); const Column* column; if (valuesType == Histogram::ValuesCustomColumn) { ui.lValuesColumn->show(); cbValuesColumn->show(); column= static_cast(cbValuesColumn->currentModelIndex().internalPointer()); } else { ui.lValuesColumn->hide(); cbValuesColumn->hide(); column = static_cast(m_curve->xColumn()); } this->showValuesColumnFormat(column); } if (m_initializing) return; for (auto* curve: m_curvesList) curve->setValuesType(valuesType); } /*! called when the custom column for the values was changed. */ void HistogramDock::valuesColumnChanged(const QModelIndex& index){ if (m_initializing) return; Column* column = static_cast(index.internalPointer()); this->showValuesColumnFormat(column); for (auto* curve: m_curvesList) { //TODO save also the format of the currently selected column for the values (precision etc.) curve->setValuesColumn(column); } } void HistogramDock::curveVisibilityChanged(bool on) { m_initializing = true; uiGeneralTab.chkVisible->setChecked(on); m_initializing = false; } void HistogramDock::valuesPositionChanged(int index){ if (m_initializing) return; foreach(Histogram* curve, m_curvesList) curve->setValuesPosition(Histogram::ValuesPosition(index)); } void HistogramDock::valuesDistanceChanged(double value){ if (m_initializing) return; for (auto* curve: m_curvesList) curve->setValuesDistance( Worksheet::convertToSceneUnits(value, Worksheet::Point) ); } void HistogramDock::valuesRotationChanged(int value){ if (m_initializing) return; for (auto* curve: m_curvesList) curve->setValuesRotationAngle(value); } void HistogramDock::valuesOpacityChanged(int value){ if (m_initializing) return; qreal opacity = (float)value/100.; for (auto* curve: m_curvesList) curve->setValuesOpacity(opacity); } void HistogramDock::valuesPrefixChanged(){ if (m_initializing) return; QString prefix = ui.leValuesPrefix->text(); for (auto* curve: m_curvesList) curve->setValuesPrefix(prefix); } void HistogramDock::valuesSuffixChanged(){ if (m_initializing) return; QString suffix = ui.leValuesSuffix->text(); for (auto* curve: m_curvesList) curve->setValuesSuffix(suffix); } void HistogramDock::valuesFontChanged(const QFont& font){ if (m_initializing) return; QFont valuesFont = font; valuesFont.setPixelSize( Worksheet::convertToSceneUnits(font.pointSizeF(), Worksheet::Point) ); for (auto* curve: m_curvesList) curve->setValuesFont(valuesFont); } //Filling void HistogramDock::curveFillingPositionChanged(Histogram::FillingPosition position) { m_initializing = true; ui.cbFillingPosition->setCurrentIndex((int)position); m_initializing = false; } void HistogramDock::curveFillingTypeChanged(PlotArea::BackgroundType type){ m_initializing = true; ui.cbFillingType->setCurrentIndex(type); m_initializing = false; } void HistogramDock::curveFillingColorStyleChanged(PlotArea::BackgroundColorStyle style){ m_initializing = true; ui.cbFillingColorStyle->setCurrentIndex(style); m_initializing = false; } void HistogramDock::curveFillingImageStyleChanged(PlotArea::BackgroundImageStyle style){ m_initializing = true; ui.cbFillingImageStyle->setCurrentIndex(style); m_initializing = false; } void HistogramDock::curveFillingBrushStyleChanged(Qt::BrushStyle style){ m_initializing = true; ui.cbFillingBrushStyle->setCurrentIndex(style); m_initializing = false; } void HistogramDock::curveFillingFirstColorChanged(QColor& color){ m_initializing = true; ui.kcbFillingFirstColor->setColor(color); m_initializing = false; } void HistogramDock::curveFillingSecondColorChanged(QColor& color){ m_initializing = true; ui.kcbFillingSecondColor->setColor(color); m_initializing = false; } void HistogramDock::curveFillingFileNameChanged(QString& filename){ m_initializing = true; ui.leFillingFileName->setText(filename); m_initializing = false; } void HistogramDock::curveFillingOpacityChanged(float opacity){ m_initializing = true; ui.sbFillingOpacity->setValue( round(opacity*100.0) ); m_initializing = false; } void HistogramDock::initTabs() { //if there are more then one curve in the list, disable the tab "general" if (m_curvesList.size()==1){ this->setModelIndexFromColumn(cbValuesColumn, m_curve->valuesColumn()); }else { cbValuesColumn->setCurrentModelIndex(QModelIndex()); } //show the properties of the first curve KConfig config("", KConfig::SimpleConfig); loadConfig(config); //Slots //Values-Tab connect(m_curve, SIGNAL(valuesTypeChanged(Histogram::ValuesType)), this, SLOT(curveValuesTypeChanged(Histogram::ValuesType))); connect(m_curve, SIGNAL(valuesColumnChanged(const AbstractColumn*)), this, SLOT(curveValuesColumnChanged(const AbstractColumn*))); connect(m_curve, SIGNAL(valuesPositionChanged(Histogram::ValuesPosition)), this, SLOT(curveValuesPositionChanged(Histogram::ValuesPosition))); connect(m_curve, SIGNAL(valuesDistanceChanged(qreal)), this, SLOT(curveValuesDistanceChanged(qreal))); connect(m_curve, SIGNAL(valuesOpacityChanged(qreal)), this, SLOT(curveValuesOpacityChanged(qreal))); connect(m_curve, SIGNAL(valuesRotationAngleChanged(qreal)), this, SLOT(curveValuesRotationAngleChanged(qreal))); connect(m_curve, SIGNAL(valuesPrefixChanged(QString)), this, SLOT(curveValuesPrefixChanged(QString))); connect(m_curve, SIGNAL(valuesSuffixChanged(QString)), this, SLOT(curveValuesSuffixChanged(QString))); connect(m_curve, SIGNAL(valuesFontChanged(QFont)), this, SLOT(curveValuesFontChanged(QFont))); connect(m_curve, SIGNAL(valuesColorChanged(QColor)), this, SLOT(curveValuesColorChanged(QColor))); //Filling-Tab connect( m_curve, SIGNAL(fillingPositionChanged(Histogram::FillingPosition)), this, SLOT(curveFillingPositionChanged(Histogram::FillingPosition)) ); connect( m_curve, SIGNAL(fillingTypeChanged(PlotArea::BackgroundType)), this, SLOT(curveFillingTypeChanged(PlotArea::BackgroundType)) ); connect( m_curve, SIGNAL(fillingColorStyleChanged(PlotArea::BackgroundColorStyle)), this, SLOT(curveFillingColorStyleChanged(PlotArea::BackgroundColorStyle)) ); connect( m_curve, SIGNAL(fillingImageStyleChanged(PlotArea::BackgroundImageStyle)), this, SLOT(curveFillingImageStyleChanged(PlotArea::BackgroundImageStyle)) ); connect( m_curve, SIGNAL(fillingBrushStyleChanged(Qt::BrushStyle)), this, SLOT(curveFillingBrushStyleChanged(Qt::BrushStyle)) ); connect( m_curve, SIGNAL(fillingFirstColorChanged(QColor&)), this, SLOT(curveFillingFirstColorChanged(QColor&)) ); connect( m_curve, SIGNAL(fillingSecondColorChanged(QColor&)), this, SLOT(curveFillingSecondColorChanged(QColor&)) ); connect( m_curve, SIGNAL(fillingFileNameChanged(QString&)), this, SLOT(curveFillingFileNameChanged(QString&)) ); connect( m_curve, SIGNAL(fillingOpacityChanged(float)), this, SLOT(curveFillingOpacityChanged(float)) ); } //Filling-tab void HistogramDock::fillingPositionChanged(int index){ Histogram::FillingPosition fillingPosition = Histogram::FillingPosition(index); bool b = (fillingPosition != Histogram::NoFilling); ui.cbFillingType->setEnabled(b); ui.cbFillingColorStyle->setEnabled(b); ui.cbFillingBrushStyle->setEnabled(b); ui.cbFillingImageStyle->setEnabled(b); ui.kcbFillingFirstColor->setEnabled(b); ui.kcbFillingSecondColor->setEnabled(b); ui.leFillingFileName->setEnabled(b); ui.bFillingOpen->setEnabled(b); ui.sbFillingOpacity->setEnabled(b); if (m_initializing) return; for (auto* curve: m_curvesList) curve->setFillingPosition(fillingPosition); } void HistogramDock::fillingTypeChanged(int index){ PlotArea::BackgroundType type = (PlotArea::BackgroundType)index; if (type == PlotArea::Color){ ui.lFillingColorStyle->show(); ui.cbFillingColorStyle->show(); ui.lFillingImageStyle->hide(); ui.cbFillingImageStyle->hide(); ui.lFillingBrushStyle->hide(); ui.cbFillingBrushStyle->hide(); ui.lFillingFileName->hide(); ui.leFillingFileName->hide(); ui.bFillingOpen->hide(); ui.lFillingFirstColor->show(); ui.kcbFillingFirstColor->show(); PlotArea::BackgroundColorStyle style = (PlotArea::BackgroundColorStyle) ui.cbFillingColorStyle->currentIndex(); if (style == PlotArea::SingleColor){ ui.lFillingFirstColor->setText(i18n("Color")); ui.lFillingSecondColor->hide(); ui.kcbFillingSecondColor->hide(); }else{ ui.lFillingFirstColor->setText(i18n("First Color")); ui.lFillingSecondColor->show(); ui.kcbFillingSecondColor->show(); } }else if(type == PlotArea::Image){ ui.lFillingColorStyle->hide(); ui.cbFillingColorStyle->hide(); ui.lFillingImageStyle->show(); ui.cbFillingImageStyle->show(); ui.lFillingBrushStyle->hide(); ui.cbFillingBrushStyle->hide(); ui.lFillingFileName->show(); ui.leFillingFileName->show(); ui.bFillingOpen->show(); ui.lFillingFirstColor->hide(); ui.kcbFillingFirstColor->hide(); ui.lFillingSecondColor->hide(); ui.kcbFillingSecondColor->hide(); }else if(type == PlotArea::Pattern) { ui.lFillingFirstColor->setText(i18n("Color")); ui.lFillingColorStyle->hide(); ui.cbFillingColorStyle->hide(); ui.lFillingImageStyle->hide(); ui.cbFillingImageStyle->hide(); ui.lFillingBrushStyle->show(); ui.cbFillingBrushStyle->show(); ui.lFillingFileName->hide(); ui.leFillingFileName->hide(); ui.bFillingOpen->hide(); ui.lFillingFirstColor->show(); ui.kcbFillingFirstColor->show(); ui.lFillingSecondColor->hide(); ui.kcbFillingSecondColor->hide(); } if (m_initializing) return; for (auto* curve: m_curvesList) curve->setFillingType(type); } void HistogramDock::fillingColorStyleChanged(int index){ PlotArea::BackgroundColorStyle style = (PlotArea::BackgroundColorStyle)index; if (style == PlotArea::SingleColor){ ui.lFillingFirstColor->setText(i18n("Color")); ui.lFillingSecondColor->hide(); ui.kcbFillingSecondColor->hide(); } else { ui.lFillingFirstColor->setText(i18n("First Color")); ui.lFillingSecondColor->show(); ui.kcbFillingSecondColor->show(); ui.lFillingBrushStyle->hide(); ui.cbFillingBrushStyle->hide(); } if (m_initializing) return; for (auto* curve: m_curvesList) curve->setFillingColorStyle(style); } void HistogramDock::fillingImageStyleChanged(int index){ if (m_initializing) return; PlotArea::BackgroundImageStyle style = (PlotArea::BackgroundImageStyle)index; for (auto* curve: m_curvesList) curve->setFillingImageStyle(style); } void HistogramDock::fillingBrushStyleChanged(int index){ if (m_initializing) return; Qt::BrushStyle style = (Qt::BrushStyle)index; for (auto* curve: m_curvesList) curve->setFillingBrushStyle(style); } void HistogramDock::fillingFirstColorChanged(const QColor& c){ if (m_initializing) return; for (auto* curve: m_curvesList) curve->setFillingFirstColor(c); } void HistogramDock::fillingSecondColorChanged(const QColor& c){ if (m_initializing) return; for (auto* curve: m_curvesList) curve->setFillingSecondColor(c); } /*! opens a file dialog and lets the user select the image file. */ void HistogramDock::selectFile() { KConfigGroup conf(KSharedConfig::openConfig(), "HistogramDock"); QString dir = conf.readEntry("LastImageDir", ""); - QString path = QFileDialog::getOpenFileName(this, i18n("Select the image file"), dir); + + QString formats; + foreach(const QByteArray& format, QImageReader::supportedImageFormats()) { + QString f = "*." + QString(format.constData()); + formats.isEmpty() ? formats+=f : formats+=' '+f; + } + + QString path = QFileDialog::getOpenFileName(this, i18n("Select the image file"), dir, i18n("Images (%1)", formats)); if (path.isEmpty()) return; //cancel was clicked in the file-dialog int pos = path.lastIndexOf(QDir::separator()); if (pos != -1) { QString newDir = path.left(pos); if (newDir!=dir) conf.writeEntry("LastImageDir", newDir); } ui.leFillingFileName->setText( path ); for (auto* curve: m_curvesList) curve->setFillingFileName(path); } void HistogramDock::fileNameChanged(){ if (m_initializing) return; QString fileName = ui.leFillingFileName->text(); for (auto* curve: m_curvesList) curve->setFillingFileName(fileName); } void HistogramDock::fillingOpacityChanged(int value){ if (m_initializing) return; qreal opacity = (float)value/100.; for (auto* curve: m_curvesList) curve->setFillingOpacity(opacity); } void HistogramDock::loadConfig(KConfig& config) { KConfigGroup group = config.group(QLatin1String("Histogram")); //General //we don't load/save the settings in the general-tab, since they are not style related. //It doesn't make sense to load/save them in the template. //This data is read in HistogramDock::setCurves(). //Values ui.cbValuesType->setCurrentIndex( group.readEntry("ValuesType", (int) m_curve->valuesType()) ); ui.cbValuesPosition->setCurrentIndex( group.readEntry("ValuesPosition", (int) m_curve->valuesPosition()) ); ui.sbValuesDistance->setValue( Worksheet::convertFromSceneUnits(group.readEntry("ValuesDistance", m_curve->valuesDistance()), Worksheet::Point) ); ui.sbValuesRotation->setValue( group.readEntry("ValuesRotation", m_curve->valuesRotationAngle()) ); ui.sbValuesOpacity->setValue( round(group.readEntry("ValuesOpacity",m_curve->valuesOpacity())*100.0) ); ui.leValuesPrefix->setText( group.readEntry("ValuesPrefix", m_curve->valuesPrefix()) ); ui.leValuesSuffix->setText( group.readEntry("ValuesSuffix", m_curve->valuesSuffix()) ); QFont valuesFont = m_curve->valuesFont(); valuesFont.setPointSizeF( round(Worksheet::convertFromSceneUnits(valuesFont.pixelSize(), Worksheet::Point)) ); ui.kfrValuesFont->setFont( group.readEntry("ValuesFont", valuesFont) ); ui.kcbValuesColor->setColor( group.readEntry("ValuesColor", m_curve->valuesColor()) ); //Filling ui.cbFillingPosition->setCurrentIndex( group.readEntry("FillingPosition", (int) m_curve->fillingPosition()) ); ui.cbFillingType->setCurrentIndex( group.readEntry("FillingType", (int) m_curve->fillingType()) ); ui.cbFillingColorStyle->setCurrentIndex( group.readEntry("FillingColorStyle", (int) m_curve->fillingColorStyle()) ); ui.cbFillingImageStyle->setCurrentIndex( group.readEntry("FillingImageStyle", (int) m_curve->fillingImageStyle()) ); ui.cbFillingBrushStyle->setCurrentIndex( group.readEntry("FillingBrushStyle", (int) m_curve->fillingBrushStyle()) ); ui.leFillingFileName->setText( group.readEntry("FillingFileName", m_curve->fillingFileName()) ); ui.kcbFillingFirstColor->setColor( group.readEntry("FillingFirstColor", m_curve->fillingFirstColor()) ); ui.kcbFillingSecondColor->setColor( group.readEntry("FillingSecondColor", m_curve->fillingSecondColor()) ); ui.sbFillingOpacity->setValue( round(group.readEntry("FillingOpacity", m_curve->fillingOpacity())*100.0) ); } void HistogramDock::setupGeneral() { QWidget* generalTab = new QWidget(ui.tabGeneral); uiGeneralTab.setupUi(generalTab); QHBoxLayout* layout = new QHBoxLayout(ui.tabGeneral); layout->setMargin(0); layout->addWidget(generalTab); // Tab "General" QGridLayout* gridLayout = qobject_cast(generalTab->layout()); cbXColumn = new TreeViewComboBox(generalTab); gridLayout->addWidget(cbXColumn, 2, 2, 1, 1); //show the properties of the first curve //bins option uiGeneralTab.cbBins->addItem(i18n("By Number")); uiGeneralTab.cbBins->addItem(i18n("By width")); uiGeneralTab.cbBins->addItem(i18n("Square-root rule")); uiGeneralTab.cbBins->addItem(i18n("Rice rule")); uiGeneralTab.cbBins->addItem(i18n("Sturgis rule")); //types options uiGeneralTab.cbHistogramType->addItem(i18n("Ordinary Histogram")); uiGeneralTab.cbHistogramType->addItem(i18n("Cumulative Histogram")); uiGeneralTab.cbHistogramType->addItem(i18n("AvgShifted Histogram")); uiGeneralTab.pbRecalculate->setIcon(QIcon::fromTheme("run-build")); //General connect( uiGeneralTab.leName, SIGNAL(returnPressed()), this, SLOT(nameChanged()) ); connect( uiGeneralTab.leComment, SIGNAL(returnPressed()), this, SLOT(commentChanged()) ); connect( uiGeneralTab.chkVisible, SIGNAL(clicked(bool)), this, SLOT(visibilityChanged(bool)) ); connect( uiGeneralTab.kcbLineColor, SIGNAL(changed(QColor)), this, SLOT(lineColorChanged(QColor)) ); connect( cbXColumn, SIGNAL(currentModelIndexChanged(QModelIndex)), this, SLOT(xColumnChanged(QModelIndex)) ); connect( uiGeneralTab.cbHistogramType, SIGNAL(currentIndexChanged(int)), this, SLOT(histogramTypeChanged(int)) ); connect( uiGeneralTab.cbBins, SIGNAL(currentIndexChanged(int)), this, SLOT(binsOptionChanged(int)) ); connect( uiGeneralTab.sbBins, SIGNAL(valueChanged(int)), this, SLOT(binValueChanged(int)) ); connect( uiGeneralTab.pbRecalculate, SIGNAL(clicked()), this, SLOT(recalculateClicked()) ); } void HistogramDock::histogramTypeChanged(int index) { Histogram::HistogramType histogramType = Histogram::HistogramType(index); m_curve->setHistrogramType(histogramType); enableRecalculate(); } void HistogramDock::binValueChanged(int value) { m_curve->setBinValue(value); enableRecalculate(); } void HistogramDock::binsOptionChanged(int index){ Histogram::BinsOption binsOption = Histogram::BinsOption(index); m_curve->setbinsOption(binsOption); enableRecalculate(); } void HistogramDock::lineColorChanged(const QColor& color){ if (m_initializing) return; QPen pen; for (auto* curve: m_curvesList) { pen = curve->linePen(); pen.setColor(color); curve->setLinePen(pen); } } void HistogramDock::xColumnChanged(const QModelIndex& index) { if (m_initializing) return; AbstractAspect* aspect = static_cast(index.internalPointer()); AbstractColumn* column = 0; if (aspect) { column = dynamic_cast(aspect); Q_ASSERT(column); } foreach(Histogram* curve, m_curvesList) { curve->setXColumn(column); } } void HistogramDock::loadConfigFromTemplate(KConfig& config) { //extract the name of the template from the file name QString name; int index = config.name().lastIndexOf(QDir::separator()); if (index!=-1) name = config.name().right(config.name().size() - index - 1); else name = config.name(); int size = m_curvesList.size(); if (size>1) m_curve->beginMacro(i18n("%1 xy-curves: template \"%2\" loaded", size, name)); else m_curve->beginMacro(i18n("%1: template \"%2\" loaded", m_curve->name(), name)); this->loadConfig(config); m_curve->endMacro(); } void HistogramDock::saveConfigAsTemplate(KConfig& config) { KConfigGroup group = config.group( "Histogram" ); //Values group.writeEntry("ValuesType", ui.cbValuesType->currentIndex()); group.writeEntry("ValuesPosition", ui.cbValuesPosition->currentIndex()); group.writeEntry("ValuesDistance", Worksheet::convertToSceneUnits(ui.sbValuesDistance->value(),Worksheet::Point)); group.writeEntry("ValuesRotation", ui.sbValuesRotation->value()); group.writeEntry("ValuesOpacity", ui.sbValuesOpacity->value()/100); group.writeEntry("ValuesPrefix", ui.leValuesPrefix->text()); group.writeEntry("ValuesSuffix", ui.leValuesSuffix->text()); group.writeEntry("ValuesFont", ui.kfrValuesFont->font()); group.writeEntry("ValuesColor", ui.kcbValuesColor->color()); //Filling group.writeEntry("FillingPosition", ui.cbFillingPosition->currentIndex()); group.writeEntry("FillingType", ui.cbFillingType->currentIndex()); group.writeEntry("FillingColorStyle", ui.cbFillingColorStyle->currentIndex()); group.writeEntry("FillingImageStyle", ui.cbFillingImageStyle->currentIndex()); group.writeEntry("FillingBrushStyle", ui.cbFillingBrushStyle->currentIndex()); group.writeEntry("FillingFileName", ui.leFillingFileName->text()); group.writeEntry("FillingFirstColor", ui.kcbFillingFirstColor->color()); group.writeEntry("FillingSecondColor", ui.kcbFillingSecondColor->color()); group.writeEntry("FillingOpacity", ui.sbFillingOpacity->value()/100.0); config.sync(); } //************************************************************* //*********** SLOTs for changes triggered in Histogram ********** //************************************************************* //General-Tab void HistogramDock::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 HistogramDock::curveHistogramDataChanged(const Histogram::HistogramData& data) { m_initializing = true; uiGeneralTab.cbHistogramType->setCurrentIndex(data.type); uiGeneralTab.cbBins->setCurrentIndex(data.binsOption); uiGeneralTab.sbBins->setValue(data.binValue); m_initializing = false; } diff --git a/src/kdefrontend/dockwidgets/XYCurveDock.cpp b/src/kdefrontend/dockwidgets/XYCurveDock.cpp index b310b9ce1..84579dc21 100644 --- a/src/kdefrontend/dockwidgets/XYCurveDock.cpp +++ b/src/kdefrontend/dockwidgets/XYCurveDock.cpp @@ -1,2226 +1,2234 @@ /*************************************************************************** File : XYCurveDock.cpp Project : LabPlot Description : widget for XYCurve properties -------------------------------------------------------------------- Copyright : (C) 2010-2015 Alexander Semke (alexander.semke@web.de) Copyright : (C) 2012-2017 Stefan Gerlach (stefan.gerlach@uni-konstanz.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 "XYCurveDock.h" #include "backend/worksheet/plots/cartesian/XYCurve.h" #include "backend/worksheet/Worksheet.h" #include "backend/core/AspectTreeModel.h" #include "backend/core/column/Column.h" #include "backend/core/Project.h" #include "backend/core/datatypes/Double2StringFilter.h" #include "backend/core/datatypes/DateTime2StringFilter.h" #include "commonfrontend/widgets/TreeViewComboBox.h" #include "kdefrontend/TemplateHandler.h" #include "kdefrontend/GuiTools.h" #include #include #include #include +#include #include #include #include #include /*! \class XYCurveDock \brief Provides a widget for editing the properties of the XYCurves (2D-curves) currently selected in the project explorer. If more than 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 */ XYCurveDock::XYCurveDock(QWidget* parent) : QWidget(parent), cbXColumn(nullptr), cbYColumn(nullptr), m_curve(nullptr), m_aspectTreeModel(nullptr) { ui.setupUi(this); //Tab "Values" QGridLayout* gridLayout = qobject_cast(ui.tabValues->layout()); cbValuesColumn = new TreeViewComboBox(ui.tabValues); gridLayout->addWidget(cbValuesColumn, 2, 2, 1, 1); //Tab "Filling" ui.cbFillingColorStyle->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon); ui.bFillingOpen->setIcon( QIcon::fromTheme("document-open") ); QCompleter* completer = new QCompleter(this); completer->setModel(new QDirModel); ui.leFillingFileName->setCompleter(completer); //Tab "Error bars" gridLayout = qobject_cast(ui.tabErrorBars->layout()); cbXErrorPlusColumn = new TreeViewComboBox(ui.tabErrorBars); gridLayout->addWidget(cbXErrorPlusColumn, 2, 2, 1, 1); cbXErrorMinusColumn = new TreeViewComboBox(ui.tabErrorBars); gridLayout->addWidget(cbXErrorMinusColumn, 3, 2, 1, 1); cbYErrorPlusColumn = new TreeViewComboBox(ui.tabErrorBars); gridLayout->addWidget(cbYErrorPlusColumn, 7, 2, 1, 1); cbYErrorMinusColumn = new TreeViewComboBox(ui.tabErrorBars); gridLayout->addWidget(cbYErrorMinusColumn, 8, 2, 1, 1); //adjust layouts in the tabs for (int i=0; icount(); ++i) { QGridLayout* layout = dynamic_cast(ui.tabWidget->widget(i)->layout()); if (!layout) continue; layout->setContentsMargins(2,2,2,2); layout->setHorizontalSpacing(2); layout->setVerticalSpacing(2); } //Slots //Lines connect( ui.cbLineType, SIGNAL(currentIndexChanged(int)), this, SLOT(lineTypeChanged(int)) ); connect( ui.sbLineInterpolationPointsCount, SIGNAL(valueChanged(int)), this, SLOT(lineInterpolationPointsCountChanged(int)) ); connect( ui.chkLineSkipGaps, SIGNAL(clicked(bool)), this, SLOT(lineSkipGapsChanged(bool)) ); connect( ui.cbLineStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(lineStyleChanged(int)) ); connect( ui.kcbLineColor, SIGNAL(changed(QColor)), this, SLOT(lineColorChanged(QColor)) ); connect( ui.sbLineWidth, SIGNAL(valueChanged(double)), this, SLOT(lineWidthChanged(double)) ); connect( ui.sbLineOpacity, SIGNAL(valueChanged(int)), this, SLOT(lineOpacityChanged(int)) ); connect( ui.cbDropLineType, SIGNAL(currentIndexChanged(int)), this, SLOT(dropLineTypeChanged(int)) ); connect( ui.cbDropLineStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(dropLineStyleChanged(int)) ); connect( ui.kcbDropLineColor, SIGNAL(changed(QColor)), this, SLOT(dropLineColorChanged(QColor)) ); connect( ui.sbDropLineWidth, SIGNAL(valueChanged(double)), this, SLOT(dropLineWidthChanged(double)) ); connect( ui.sbDropLineOpacity, SIGNAL(valueChanged(int)), this, SLOT(dropLineOpacityChanged(int)) ); //Symbol connect( ui.cbSymbolStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(symbolsStyleChanged(int)) ); connect( ui.sbSymbolSize, SIGNAL(valueChanged(double)), this, SLOT(symbolsSizeChanged(double)) ); connect( ui.sbSymbolRotation, SIGNAL(valueChanged(int)), this, SLOT(symbolsRotationChanged(int)) ); connect( ui.sbSymbolOpacity, SIGNAL(valueChanged(int)), this, SLOT(symbolsOpacityChanged(int)) ); connect( ui.cbSymbolFillingStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(symbolsFillingStyleChanged(int)) ); connect( ui.kcbSymbolFillingColor, SIGNAL(changed(QColor)), this, SLOT(symbolsFillingColorChanged(QColor)) ); connect( ui.cbSymbolBorderStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(symbolsBorderStyleChanged(int)) ); connect( ui.kcbSymbolBorderColor, SIGNAL(changed(QColor)), this, SLOT(symbolsBorderColorChanged(QColor)) ); connect( ui.sbSymbolBorderWidth, SIGNAL(valueChanged(double)), this, SLOT(symbolsBorderWidthChanged(double)) ); //Values connect( ui.cbValuesType, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesTypeChanged(int)) ); connect( cbValuesColumn, SIGNAL(currentModelIndexChanged(QModelIndex)), this, SLOT(valuesColumnChanged(QModelIndex)) ); connect( ui.cbValuesPosition, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesPositionChanged(int)) ); connect( ui.sbValuesDistance, SIGNAL(valueChanged(double)), this, SLOT(valuesDistanceChanged(double)) ); connect( ui.sbValuesRotation, SIGNAL(valueChanged(int)), this, SLOT(valuesRotationChanged(int)) ); connect( ui.sbValuesOpacity, SIGNAL(valueChanged(int)), this, SLOT(valuesOpacityChanged(int)) ); //TODO connect( ui.cbValuesFormat, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesColumnFormatChanged(int)) ); connect( ui.leValuesPrefix, SIGNAL(returnPressed()), this, SLOT(valuesPrefixChanged()) ); connect( ui.leValuesSuffix, SIGNAL(returnPressed()), this, SLOT(valuesSuffixChanged()) ); connect( ui.kfrValuesFont, SIGNAL(fontSelected(QFont)), this, SLOT(valuesFontChanged(QFont)) ); connect( ui.kcbValuesColor, SIGNAL(changed(QColor)), this, SLOT(valuesColorChanged(QColor)) ); //Filling connect( ui.cbFillingPosition, SIGNAL(currentIndexChanged(int)), this, SLOT(fillingPositionChanged(int)) ); connect( ui.cbFillingType, SIGNAL(currentIndexChanged(int)), this, SLOT(fillingTypeChanged(int)) ); connect( ui.cbFillingColorStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(fillingColorStyleChanged(int)) ); connect( ui.cbFillingImageStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(fillingImageStyleChanged(int)) ); connect( ui.cbFillingBrushStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(fillingBrushStyleChanged(int)) ); connect(ui.bFillingOpen, SIGNAL(clicked(bool)), this, SLOT(selectFile())); connect( ui.leFillingFileName, SIGNAL(returnPressed()), this, SLOT(fileNameChanged()) ); connect( ui.leFillingFileName, SIGNAL(textChanged(const QString&)), this, SLOT(fileNameChanged()) ); connect( ui.kcbFillingFirstColor, SIGNAL(changed(QColor)), this, SLOT(fillingFirstColorChanged(QColor)) ); connect( ui.kcbFillingSecondColor, SIGNAL(changed(QColor)), this, SLOT(fillingSecondColorChanged(QColor)) ); connect( ui.sbFillingOpacity, SIGNAL(valueChanged(int)), this, SLOT(fillingOpacityChanged(int)) ); //Error bars connect( ui.cbXErrorType, SIGNAL(currentIndexChanged(int)), this, SLOT(xErrorTypeChanged(int)) ); connect( cbXErrorPlusColumn, SIGNAL(currentModelIndexChanged(QModelIndex)), this, SLOT(xErrorPlusColumnChanged(QModelIndex)) ); connect( cbXErrorMinusColumn, SIGNAL(currentModelIndexChanged(QModelIndex)), this, SLOT(xErrorMinusColumnChanged(QModelIndex)) ); connect( ui.cbYErrorType, SIGNAL(currentIndexChanged(int)), this, SLOT(yErrorTypeChanged(int)) ); connect( cbYErrorPlusColumn, SIGNAL(currentModelIndexChanged(QModelIndex)), this, SLOT(yErrorPlusColumnChanged(QModelIndex)) ); connect( cbYErrorMinusColumn, SIGNAL(currentModelIndexChanged(QModelIndex)), this, SLOT(yErrorMinusColumnChanged(QModelIndex)) ); connect( ui.cbErrorBarsType, SIGNAL(currentIndexChanged(int)), this, SLOT(errorBarsTypeChanged(int)) ); connect( ui.sbErrorBarsCapSize, SIGNAL(valueChanged(double)), this, SLOT(errorBarsCapSizeChanged(double)) ); connect( ui.cbErrorBarsStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(errorBarsStyleChanged(int)) ); connect( ui.kcbErrorBarsColor, SIGNAL(changed(QColor)), this, SLOT(errorBarsColorChanged(QColor)) ); connect( ui.sbErrorBarsWidth, SIGNAL(valueChanged(double)), this, SLOT(errorBarsWidthChanged(double)) ); connect( ui.sbErrorBarsOpacity, SIGNAL(valueChanged(int)), this, SLOT(errorBarsOpacityChanged(int)) ); //template handler TemplateHandler* templateHandler = new TemplateHandler(this, TemplateHandler::XYCurve); ui.verticalLayout->addWidget(templateHandler); templateHandler->show(); connect(templateHandler, SIGNAL(loadConfigRequested(KConfig&)), this, SLOT(loadConfigFromTemplate(KConfig&))); connect(templateHandler, SIGNAL(saveConfigRequested(KConfig&)), this, SLOT(saveConfigAsTemplate(KConfig&))); connect(templateHandler, SIGNAL(info(QString)), this, SIGNAL(info(QString))); retranslateUi(); init(); } XYCurveDock::~XYCurveDock() { if (m_aspectTreeModel) delete m_aspectTreeModel; } void XYCurveDock::setupGeneral() { QWidget* generalTab = new QWidget(ui.tabGeneral); uiGeneralTab.setupUi(generalTab); QHBoxLayout* layout = new QHBoxLayout(ui.tabGeneral); layout->setMargin(0); layout->addWidget(generalTab); // Tab "General" QGridLayout* gridLayout = qobject_cast(generalTab->layout()); cbXColumn = new TreeViewComboBox(generalTab); gridLayout->addWidget(cbXColumn, 2, 2, 1, 1); cbYColumn = new TreeViewComboBox(generalTab); gridLayout->addWidget(cbYColumn, 3, 2, 1, 1); //General connect( uiGeneralTab.leName, SIGNAL(returnPressed()), this, SLOT(nameChanged()) ); connect( uiGeneralTab.leComment, SIGNAL(returnPressed()), this, SLOT(commentChanged()) ); connect( uiGeneralTab.chkVisible, SIGNAL(clicked(bool)), this, SLOT(visibilityChanged(bool)) ); connect( cbXColumn, SIGNAL(currentModelIndexChanged(QModelIndex)), this, SLOT(xColumnChanged(QModelIndex)) ); connect( cbYColumn, SIGNAL(currentModelIndexChanged(QModelIndex)), this, SLOT(yColumnChanged(QModelIndex)) ); } void XYCurveDock::init() { m_initializing = true; //Line ui.cbLineType->addItem(i18n("none")); ui.cbLineType->addItem(i18n("line")); ui.cbLineType->addItem(i18n("horiz. start")); ui.cbLineType->addItem(i18n("vert. start")); ui.cbLineType->addItem(i18n("horiz. midpoint")); ui.cbLineType->addItem(i18n("vert. midpoint")); ui.cbLineType->addItem(i18n("2-segments")); ui.cbLineType->addItem(i18n("3-segments")); ui.cbLineType->addItem(i18n("cubic spline (natural)")); ui.cbLineType->addItem(i18n("cubic spline (periodic)")); ui.cbLineType->addItem(i18n("Akima-spline (natural)")); ui.cbLineType->addItem(i18n("Akima-spline (periodic)")); QPainter pa; //TODO size of the icon depending on the actuall height of the combobox? int iconSize = 20; QPixmap pm(iconSize, iconSize); ui.cbLineType->setIconSize(QSize(iconSize, iconSize)); QPen pen(Qt::SolidPattern, 0); const QColor& color = (palette().color(QPalette::Base).lightness() < 128) ? Qt::white : Qt::black; pen.setColor(color); pa.setPen( pen ); //no line pm.fill(Qt::transparent); pa.begin( &pm ); pa.setPen(pen); pa.setRenderHint(QPainter::Antialiasing); pa.drawEllipse( 1,1,4,4); pa.drawEllipse( 15,15,4,4); pa.end(); ui.cbLineType->setItemIcon(0, pm); //line pm.fill(Qt::transparent); pa.begin( &pm ); pa.setPen(pen); pa.setRenderHint(QPainter::Antialiasing); pa.drawEllipse( 1,1,4,4); pa.drawEllipse( 15,15,4,4); pa.drawLine(3,3,17,17); pa.end(); ui.cbLineType->setItemIcon(1, pm); pm.fill(Qt::transparent); pa.begin( &pm ); pa.setPen(pen); pa.setRenderHint(QPainter::Antialiasing); pa.drawEllipse( 1,1,4,4); pa.drawEllipse( 15,15,4,4); pa.drawLine(3,3,17,3); pa.drawLine(17,3,17,17); pa.end(); ui.cbLineType->setItemIcon(2, pm); pm.fill(Qt::transparent); pa.begin( &pm ); pa.setPen(pen); pa.setRenderHint(QPainter::Antialiasing); pa.drawEllipse( 1,1,4,4); pa.drawEllipse( 15,15,4,4); pa.drawLine(3,3,3,17); pa.drawLine(3,17,17,17); pa.end(); ui.cbLineType->setItemIcon(3, pm); //horizontal midpoint pm.fill(Qt::transparent); pa.begin( &pm ); pa.setPen(pen); pa.setRenderHint(QPainter::Antialiasing); pa.drawEllipse( 1,1,4,4); pa.drawEllipse( 15,15,4,4); pa.drawLine(3,3,10,3); pa.drawLine(10,3,10,17); pa.drawLine(10,17,17,17); pa.end(); ui.cbLineType->setItemIcon(4, pm); //vertical midpoint pm.fill(Qt::transparent); pa.begin( &pm ); pa.setPen(pen); pa.setRenderHint(QPainter::Antialiasing); pa.drawEllipse( 1,1,4,4); pa.drawEllipse( 15,15,4,4); pa.drawLine(3,3,3,10); pa.drawLine(3,10,17,10); pa.drawLine(17,10,17,17); pa.end(); ui.cbLineType->setItemIcon(5, pm); //2-segments pm.fill(Qt::transparent); pa.begin( &pm ); pa.setPen(pen); pa.setRenderHint(QPainter::Antialiasing); pa.drawEllipse( 1,1,4,4); pa.drawEllipse( 8,8,4,4); pa.drawEllipse( 15,15,4,4); pa.drawLine(3,3,10,10); pa.end(); ui.cbLineType->setItemIcon(6, pm); //3-segments pm.fill(Qt::transparent); pa.begin( &pm ); pa.setPen(pen); pa.setRenderHint(QPainter::Antialiasing); pa.drawEllipse( 1,1,4,4); pa.drawEllipse( 8,8,4,4); pa.drawEllipse( 15,15,4,4); pa.drawLine(3,3,17,17); pa.end(); ui.cbLineType->setItemIcon(7, pm); //natural spline pm.fill(Qt::transparent); pa.begin( &pm ); pa.setPen(pen); pa.setRenderHint(QPainter::Antialiasing); pa.drawEllipse( 1,1,4,4); pa.drawEllipse( 15,15,4,4); pa.rotate(45); pa.drawArc(2*sqrt(2),-4,17*sqrt(2),20,30*16,120*16); pa.end(); ui.cbLineType->setItemIcon(8, pm); ui.cbLineType->setItemIcon(9, pm); ui.cbLineType->setItemIcon(10, pm); ui.cbLineType->setItemIcon(11, pm); GuiTools::updatePenStyles(ui.cbLineStyle, Qt::black); //Drop lines ui.cbDropLineType->addItem(i18n("no drop lines")); ui.cbDropLineType->addItem(i18n("drop lines, X")); ui.cbDropLineType->addItem(i18n("drop lines, Y")); ui.cbDropLineType->addItem(i18n("drop lines, XY")); ui.cbDropLineType->addItem(i18n("drop lines, X, zero baseline")); ui.cbDropLineType->addItem(i18n("drop lines, X, min baseline")); ui.cbDropLineType->addItem(i18n("drop lines, X, max baseline")); GuiTools::updatePenStyles(ui.cbDropLineStyle, Qt::black); //Symbols GuiTools::updatePenStyles(ui.cbSymbolBorderStyle, Qt::black); ui.cbSymbolStyle->setIconSize(QSize(iconSize, iconSize)); QTransform trafo; trafo.scale(15, 15); ui.cbSymbolStyle->addItem(i18n("none")); for (int i = 1; i < 19; ++i) { //TODO: use enum count Symbol::Style style = (Symbol::Style)i; pm.fill(Qt::transparent); pa.begin(&pm); pa.setPen(pen); pa.setRenderHint(QPainter::Antialiasing); pa.translate(iconSize/2,iconSize/2); pa.drawPath(trafo.map(Symbol::pathFromStyle(style))); pa.end(); ui.cbSymbolStyle->addItem(QIcon(pm), Symbol::nameFromStyle(style)); } GuiTools::updateBrushStyles(ui.cbSymbolFillingStyle, Qt::black); m_initializing = false; //Values ui.cbValuesType->addItem(i18n("no values")); ui.cbValuesType->addItem("x"); ui.cbValuesType->addItem("y"); ui.cbValuesType->addItem("x, y"); ui.cbValuesType->addItem("(x, y)"); ui.cbValuesType->addItem(i18n("custom column")); ui.cbValuesPosition->addItem(i18n("above")); ui.cbValuesPosition->addItem(i18n("below")); ui.cbValuesPosition->addItem(i18n("left")); ui.cbValuesPosition->addItem(i18n("right")); //Filling ui.cbFillingPosition->clear(); ui.cbFillingPosition->addItem(i18n("none")); ui.cbFillingPosition->addItem(i18n("above")); ui.cbFillingPosition->addItem(i18n("below")); ui.cbFillingPosition->addItem(i18n("zero baseline")); ui.cbFillingPosition->addItem(i18n("left")); ui.cbFillingPosition->addItem(i18n("right")); ui.cbFillingType->clear(); ui.cbFillingType->addItem(i18n("color")); ui.cbFillingType->addItem(i18n("image")); ui.cbFillingType->addItem(i18n("pattern")); ui.cbFillingColorStyle->clear(); ui.cbFillingColorStyle->addItem(i18n("single color")); ui.cbFillingColorStyle->addItem(i18n("horizontal gradient")); ui.cbFillingColorStyle->addItem(i18n("vertical gradient")); ui.cbFillingColorStyle->addItem(i18n("diag. gradient (from top left)")); ui.cbFillingColorStyle->addItem(i18n("diag. gradient (from bottom left)")); ui.cbFillingColorStyle->addItem(i18n("radial gradient")); ui.cbFillingImageStyle->clear(); ui.cbFillingImageStyle->addItem(i18n("scaled and cropped")); ui.cbFillingImageStyle->addItem(i18n("scaled")); ui.cbFillingImageStyle->addItem(i18n("scaled, keep proportions")); ui.cbFillingImageStyle->addItem(i18n("centered")); ui.cbFillingImageStyle->addItem(i18n("tiled")); ui.cbFillingImageStyle->addItem(i18n("center tiled")); GuiTools::updateBrushStyles(ui.cbFillingBrushStyle, Qt::SolidPattern); //Error-bars pm.fill(Qt::transparent); pa.begin( &pm ); pa.setRenderHint(QPainter::Antialiasing); pa.drawLine(3,10,17,10);//vert. line pa.drawLine(10,3,10,17);//hor. line pa.end(); ui.cbErrorBarsType->addItem(i18n("bars")); ui.cbErrorBarsType->setItemIcon(0, pm); pm.fill(Qt::transparent); pa.begin( &pm ); pa.setRenderHint(QPainter::Antialiasing); pa.setBrush(Qt::SolidPattern); pa.drawLine(3,10,17,10); //vert. line pa.drawLine(10,3,10,17); //hor. line pa.drawLine(7,3,13,3); //upper cap pa.drawLine(7,17,13,17); //bottom cap pa.drawLine(3,7,3,13); //left cap pa.drawLine(17,7,17,13); //right cap pa.end(); ui.cbErrorBarsType->addItem(i18n("bars with ends")); ui.cbErrorBarsType->setItemIcon(1, pm); ui.cbXErrorType->addItem(i18n("no")); ui.cbXErrorType->addItem(i18n("symmetric")); ui.cbXErrorType->addItem(i18n("asymmetric")); ui.cbYErrorType->addItem(i18n("no")); ui.cbYErrorType->addItem(i18n("symmetric")); ui.cbYErrorType->addItem(i18n("asymmetric")); GuiTools::updatePenStyles(ui.cbErrorBarsStyle, Qt::black); } void XYCurveDock::setModel() { QList list; list<<"Folder"<<"Workbook"<<"Datapicker"<<"DatapickerCurve"<<"Spreadsheet" <<"FileDataSource"<<"Column"<<"Worksheet"<<"CartesianPlot"<<"XYFitCurve"<<"CantorWorksheet"; if (cbXColumn) { cbXColumn->setTopLevelClasses(list); cbYColumn->setTopLevelClasses(list); } cbValuesColumn->setTopLevelClasses(list); cbXErrorMinusColumn->setTopLevelClasses(list); cbXErrorPlusColumn->setTopLevelClasses(list); cbYErrorMinusColumn->setTopLevelClasses(list); cbYErrorPlusColumn->setTopLevelClasses(list); list.clear(); list<<"Column"<<"XYCurve"; m_aspectTreeModel->setSelectableAspects(list); if (cbXColumn) { cbXColumn->setModel(m_aspectTreeModel); cbYColumn->setModel(m_aspectTreeModel); } cbValuesColumn->setModel(m_aspectTreeModel); cbXErrorMinusColumn->setModel(m_aspectTreeModel); cbXErrorPlusColumn->setModel(m_aspectTreeModel); cbYErrorMinusColumn->setModel(m_aspectTreeModel); cbYErrorPlusColumn->setModel(m_aspectTreeModel); } /*! sets the curves. The properties of the curves in the list \c list can be edited in this widget. */ void XYCurveDock::setCurves(QList list) { m_initializing=true; m_curvesList=list; m_curve=list.first(); Q_ASSERT(m_curve); m_aspectTreeModel = new AspectTreeModel(m_curve->project()); setModel(); initGeneralTab(); initTabs(); m_initializing=false; } void XYCurveDock::initGeneralTab() { //if there are more than one curve in the list, disable the content in 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.lXColumn->setEnabled(true); cbXColumn->setEnabled(true); uiGeneralTab.lYColumn->setEnabled(true); cbYColumn->setEnabled(true); this->setModelIndexFromAspect(cbXColumn, m_curve->xColumn()); this->setModelIndexFromAspect(cbYColumn, m_curve->yColumn()); 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.lXColumn->setEnabled(false); cbXColumn->setEnabled(false); uiGeneralTab.lYColumn->setEnabled(false); cbYColumn->setEnabled(false); cbXColumn->setCurrentModelIndex(QModelIndex()); cbYColumn->setCurrentModelIndex(QModelIndex()); uiGeneralTab.leName->setText(""); uiGeneralTab.leComment->setText(""); } //show the properties of the first curve uiGeneralTab.chkVisible->setChecked( m_curve->isVisible() ); //Slots connect(m_curve, SIGNAL(aspectDescriptionChanged(const AbstractAspect*)),this, SLOT(curveDescriptionChanged(const AbstractAspect*))); connect(m_curve, SIGNAL(xColumnChanged(const AbstractColumn*)), this, SLOT(curveXColumnChanged(const AbstractColumn*))); connect(m_curve, SIGNAL(yColumnChanged(const AbstractColumn*)), this, SLOT(curveYColumnChanged(const AbstractColumn*))); connect(m_curve, SIGNAL(visibilityChanged(bool)), this, SLOT(curveVisibilityChanged(bool))); } void XYCurveDock::initTabs() { //if there are more than one curve in the list, disable the tab "general" if (m_curvesList.size() == 1) { this->setModelIndexFromAspect(cbValuesColumn, m_curve->valuesColumn()); this->setModelIndexFromAspect(cbXErrorPlusColumn, m_curve->xErrorPlusColumn()); this->setModelIndexFromAspect(cbXErrorMinusColumn, m_curve->xErrorMinusColumn()); this->setModelIndexFromAspect(cbYErrorPlusColumn, m_curve->yErrorPlusColumn()); this->setModelIndexFromAspect(cbYErrorMinusColumn, m_curve->yErrorMinusColumn()); } else { cbValuesColumn->setCurrentModelIndex(QModelIndex()); cbXErrorPlusColumn->setCurrentModelIndex(QModelIndex()); cbXErrorMinusColumn->setCurrentModelIndex(QModelIndex()); cbYErrorPlusColumn->setCurrentModelIndex(QModelIndex()); cbYErrorMinusColumn->setCurrentModelIndex(QModelIndex()); } //show the properties of the first curve KConfig config("", KConfig::SimpleConfig); loadConfig(config); //Slots //Line-Tab connect(m_curve, SIGNAL(lineTypeChanged(XYCurve::LineType)), this, SLOT(curveLineTypeChanged(XYCurve::LineType))); connect(m_curve, SIGNAL(lineSkipGapsChanged(bool)), this, SLOT(curveLineSkipGapsChanged(bool))); connect(m_curve, SIGNAL(lineInterpolationPointsCountChanged(int)), this, SLOT(curveLineInterpolationPointsCountChanged(int))); connect(m_curve, SIGNAL(linePenChanged(QPen)), this, SLOT(curveLinePenChanged(QPen))); connect(m_curve, SIGNAL(lineOpacityChanged(qreal)), this, SLOT(curveLineOpacityChanged(qreal))); connect(m_curve, SIGNAL(dropLineTypeChanged(XYCurve::DropLineType)), this, SLOT(curveDropLineTypeChanged(XYCurve::DropLineType))); connect(m_curve, SIGNAL(dropLinePenChanged(QPen)), this, SLOT(curveDropLinePenChanged(QPen))); connect(m_curve, SIGNAL(dropLineOpacityChanged(qreal)), this, SLOT(curveDropLineOpacityChanged(qreal))); //Symbol-Tab connect(m_curve, SIGNAL(symbolsStyleChanged(Symbol::Style)), this, SLOT(curveSymbolsStyleChanged(Symbol::Style))); connect(m_curve, SIGNAL(symbolsSizeChanged(qreal)), this, SLOT(curveSymbolsSizeChanged(qreal))); connect(m_curve, SIGNAL(symbolsRotationAngleChanged(qreal)), this, SLOT(curveSymbolsRotationAngleChanged(qreal))); connect(m_curve, SIGNAL(symbolsOpacityChanged(qreal)), this, SLOT(curveSymbolsOpacityChanged(qreal))); connect(m_curve, SIGNAL(symbolsBrushChanged(QBrush)), this, SLOT(curveSymbolsBrushChanged(QBrush))); connect(m_curve, SIGNAL(symbolsPenChanged(QPen)), this, SLOT(curveSymbolsPenChanged(QPen))); //Values-Tab connect(m_curve, SIGNAL(valuesTypeChanged(XYCurve::ValuesType)), this, SLOT(curveValuesTypeChanged(XYCurve::ValuesType))); connect(m_curve, SIGNAL(valuesColumnChanged(const AbstractColumn*)), this, SLOT(curveValuesColumnChanged(const AbstractColumn*))); connect(m_curve, SIGNAL(valuesPositionChanged(XYCurve::ValuesPosition)), this, SLOT(curveValuesPositionChanged(XYCurve::ValuesPosition))); connect(m_curve, SIGNAL(valuesDistanceChanged(qreal)), this, SLOT(curveValuesDistanceChanged(qreal))); connect(m_curve, SIGNAL(valuesOpacityChanged(qreal)), this, SLOT(curveValuesOpacityChanged(qreal))); connect(m_curve, SIGNAL(valuesRotationAngleChanged(qreal)), this, SLOT(curveValuesRotationAngleChanged(qreal))); connect(m_curve, SIGNAL(valuesPrefixChanged(QString)), this, SLOT(curveValuesPrefixChanged(QString))); connect(m_curve, SIGNAL(valuesSuffixChanged(QString)), this, SLOT(curveValuesSuffixChanged(QString))); connect(m_curve, SIGNAL(valuesFontChanged(QFont)), this, SLOT(curveValuesFontChanged(QFont))); connect(m_curve, SIGNAL(valuesColorChanged(QColor)), this, SLOT(curveValuesColorChanged(QColor))); //Filling-Tab connect( m_curve, SIGNAL(fillingPositionChanged(XYCurve::FillingPosition)), this, SLOT(curveFillingPositionChanged(XYCurve::FillingPosition)) ); connect( m_curve, SIGNAL(fillingTypeChanged(PlotArea::BackgroundType)), this, SLOT(curveFillingTypeChanged(PlotArea::BackgroundType)) ); connect( m_curve, SIGNAL(fillingColorStyleChanged(PlotArea::BackgroundColorStyle)), this, SLOT(curveFillingColorStyleChanged(PlotArea::BackgroundColorStyle)) ); connect( m_curve, SIGNAL(fillingImageStyleChanged(PlotArea::BackgroundImageStyle)), this, SLOT(curveFillingImageStyleChanged(PlotArea::BackgroundImageStyle)) ); connect( m_curve, SIGNAL(fillingBrushStyleChanged(Qt::BrushStyle)), this, SLOT(curveFillingBrushStyleChanged(Qt::BrushStyle)) ); connect( m_curve, SIGNAL(fillingFirstColorChanged(QColor&)), this, SLOT(curveFillingFirstColorChanged(QColor&)) ); connect( m_curve, SIGNAL(fillingSecondColorChanged(QColor&)), this, SLOT(curveFillingSecondColorChanged(QColor&)) ); connect( m_curve, SIGNAL(fillingFileNameChanged(QString&)), this, SLOT(curveFillingFileNameChanged(QString&)) ); connect( m_curve, SIGNAL(fillingOpacityChanged(float)), this, SLOT(curveFillingOpacityChanged(float)) ); //"Error bars"-Tab connect(m_curve, SIGNAL(xErrorTypeChanged(XYCurve::ErrorType)), this, SLOT(curveXErrorTypeChanged(XYCurve::ErrorType))); connect(m_curve, SIGNAL(xErrorPlusColumnChanged(const AbstractColumn*)), this, SLOT(curveXErrorPlusColumnChanged(const AbstractColumn*))); connect(m_curve, SIGNAL(xErrorMinusColumnChanged(const AbstractColumn*)), this, SLOT(curveXErrorMinusColumnChanged(const AbstractColumn*))); connect(m_curve, SIGNAL(yErrorTypeChanged(XYCurve::ErrorType)), this, SLOT(curveYErrorTypeChanged(XYCurve::ErrorType))); connect(m_curve, SIGNAL(yErrorPlusColumnChanged(const AbstractColumn*)), this, SLOT(curveYErrorPlusColumnChanged(const AbstractColumn*))); connect(m_curve, SIGNAL(yErrorMinusColumnChanged(const AbstractColumn*)), this, SLOT(curveYErrorMinusColumnChanged(const AbstractColumn*))); connect(m_curve, SIGNAL(errorBarsCapSizeChanged(qreal)), this, SLOT(curveErrorBarsCapSizeChanged(qreal))); connect(m_curve, SIGNAL(errorBarsTypeChanged(XYCurve::ErrorBarsType)), this, SLOT(curveErrorBarsTypeChanged(XYCurve::ErrorBarsType))); connect(m_curve, SIGNAL(errorBarsPenChanged(QPen)), this, SLOT(curveErrorBarsPenChanged(QPen))); connect(m_curve, SIGNAL(errorBarsOpacityChanged(qreal)), this, SLOT(curveErrorBarsOpacityChanged(qreal))); } /*! depending on the currently selected values column type (column mode) updates the widgets for the values column format, shows/hides the allowed widgets, fills the corresponding combobox with the possible entries. Called when the values column was changed. synchronize this function with ColumnDock::updateFormat. */ void XYCurveDock::updateValuesFormatWidgets(const AbstractColumn::ColumnMode columnMode) { ui.cbValuesFormat->clear(); switch (columnMode) { case AbstractColumn::Numeric: ui.cbValuesFormat->addItem(i18n("Decimal"), QVariant('f')); ui.cbValuesFormat->addItem(i18n("Scientific (e)"), QVariant('e')); ui.cbValuesFormat->addItem(i18n("Scientific (E)"), QVariant('E')); ui.cbValuesFormat->addItem(i18n("Automatic (e)"), QVariant('g')); ui.cbValuesFormat->addItem(i18n("Automatic (E)"), QVariant('G')); break; case AbstractColumn::Integer: break; case AbstractColumn::Text: ui.cbValuesFormat->addItem(i18n("Text"), QVariant()); break; case AbstractColumn::Month: ui.cbValuesFormat->addItem(i18n("Number without leading zero"), QVariant("M")); ui.cbValuesFormat->addItem(i18n("Number with leading zero"), QVariant("MM")); ui.cbValuesFormat->addItem(i18n("Abbreviated month name"), QVariant("MMM")); ui.cbValuesFormat->addItem(i18n("Full month name"), QVariant("MMMM")); break; case AbstractColumn::Day: ui.cbValuesFormat->addItem(i18n("Number without leading zero"), QVariant("d")); ui.cbValuesFormat->addItem(i18n("Number with leading zero"), QVariant("dd")); ui.cbValuesFormat->addItem(i18n("Abbreviated day name"), QVariant("ddd")); ui.cbValuesFormat->addItem(i18n("Full day name"), QVariant("dddd")); break; case AbstractColumn::DateTime: { for (const auto& s: AbstractColumn::dateFormats()) ui.cbValuesFormat->addItem(s, QVariant(s)); for (const auto& s: AbstractColumn::timeFormats()) ui.cbValuesFormat->addItem(s, QVariant(s)); for (const auto& s1: AbstractColumn::dateFormats()) { for (const auto& s2: AbstractColumn::timeFormats()) ui.cbValuesFormat->addItem(s1 + ' ' + s2, QVariant(s1 + ' ' + s2)); } break; } } if (columnMode == AbstractColumn::Numeric) { ui.lValuesPrecision->show(); ui.sbValuesPrecision->show(); } else { ui.lValuesPrecision->hide(); ui.sbValuesPrecision->hide(); } if (columnMode == AbstractColumn::Text) { ui.lValuesFormatTop->hide(); ui.lValuesFormat->hide(); ui.cbValuesFormat->hide(); } else { ui.lValuesFormatTop->show(); ui.lValuesFormat->show(); ui.cbValuesFormat->show(); } if (columnMode == AbstractColumn::DateTime) { ui.cbValuesFormat->setCurrentItem("yyyy-MM-dd hh:mm:ss.zzz"); ui.cbValuesFormat->setEditable(true); } else { ui.cbValuesFormat->setCurrentIndex(0); ui.cbValuesFormat->setEditable(false); } } /*! shows the formating properties of the column \c column. Called, when a new column for the values was selected - either by changing the type of the values (none, x, y, etc.) or by selecting a new custom column for the values. */ void XYCurveDock::showValuesColumnFormat(const Column* column) { if (!column) { // no valid column is available // -> hide all the format properties widgets (equivalent to showing the properties of the column mode "Text") this->updateValuesFormatWidgets(AbstractColumn::Text); } else { AbstractColumn::ColumnMode columnMode = column->columnMode(); //update the format widgets for the new column mode this->updateValuesFormatWidgets(columnMode); //show the actuall formating properties switch (columnMode) { case AbstractColumn::Numeric: { Double2StringFilter* filter = static_cast(column->outputFilter()); ui.cbValuesFormat->setCurrentIndex(ui.cbValuesFormat->findData(filter->numericFormat())); ui.sbValuesPrecision->setValue(filter->numDigits()); break; } case AbstractColumn::Integer: case AbstractColumn::Text: break; case AbstractColumn::Month: case AbstractColumn::Day: case AbstractColumn::DateTime: { DateTime2StringFilter* filter = static_cast(column->outputFilter()); DEBUG(" column values format = " << filter->format().toStdString()); ui.cbValuesFormat->setCurrentIndex(ui.cbValuesFormat->findData(filter->format())); break; } } } } void XYCurveDock::setModelIndexFromAspect(TreeViewComboBox* cb, const AbstractAspect* aspect) { if (aspect) cb->setCurrentModelIndex(m_aspectTreeModel->modelIndexOfAspect(aspect)); else cb->setCurrentModelIndex(QModelIndex()); } //************************************************************* //********** SLOTs for changes triggered in XYCurveDock ******** //************************************************************* void XYCurveDock::retranslateUi() { //TODO: // uiGeneralTab.lName->setText(i18n("Name")); // uiGeneralTab.lComment->setText(i18n("Comment")); // uiGeneralTab.chkVisible->setText(i18n("Visible")); // uiGeneralTab.lXColumn->setText(i18n("x-data")); // uiGeneralTab.lYColumn->setText(i18n("y-data")); //TODO updatePenStyles, updateBrushStyles for all comboboxes } // "General"-tab void XYCurveDock::nameChanged() { if (m_initializing) return; m_curve->setName(uiGeneralTab.leName->text()); } void XYCurveDock::commentChanged() { if (m_initializing) return; m_curve->setComment(uiGeneralTab.leComment->text()); } void XYCurveDock::xColumnChanged(const QModelIndex& index) { if (m_initializing) return; AbstractAspect* aspect = static_cast(index.internalPointer()); AbstractColumn* column = 0; if (aspect) { column = dynamic_cast(aspect); Q_ASSERT(column); } foreach(XYCurve* curve, m_curvesList) curve->setXColumn(column); } void XYCurveDock::yColumnChanged(const QModelIndex& index) { if (m_initializing) return; AbstractAspect* aspect = static_cast(index.internalPointer()); AbstractColumn* column = 0; if (aspect) { column = dynamic_cast(aspect); Q_ASSERT(column); } foreach(XYCurve* curve, m_curvesList) curve->setYColumn(column); } void XYCurveDock::visibilityChanged(bool state) { if (m_initializing) return; foreach(XYCurve* curve, m_curvesList) curve->setVisible(state); } // "Line"-tab void XYCurveDock::lineTypeChanged(int index) { XYCurve::LineType lineType = XYCurve::LineType(index); if ( lineType == XYCurve::NoLine) { ui.chkLineSkipGaps->setEnabled(false); ui.cbLineStyle->setEnabled(false); ui.kcbLineColor->setEnabled(false); ui.sbLineWidth->setEnabled(false); ui.sbLineOpacity->setEnabled(false); ui.lLineInterpolationPointsCount->hide(); ui.sbLineInterpolationPointsCount->hide(); } else { ui.chkLineSkipGaps->setEnabled(true); ui.cbLineStyle->setEnabled(true); ui.kcbLineColor->setEnabled(true); ui.sbLineWidth->setEnabled(true); ui.sbLineOpacity->setEnabled(true); if (lineType == XYCurve::SplineCubicNatural || lineType == XYCurve::SplineCubicPeriodic || lineType == XYCurve::SplineAkimaNatural || lineType == XYCurve::SplineAkimaPeriodic) { ui.lLineInterpolationPointsCount->show(); ui.sbLineInterpolationPointsCount->show(); ui.lLineSkipGaps->hide(); ui.chkLineSkipGaps->hide(); } else { ui.lLineInterpolationPointsCount->hide(); ui.sbLineInterpolationPointsCount->hide(); ui.lLineSkipGaps->show(); ui.chkLineSkipGaps->show(); } } if (m_initializing) return; foreach(XYCurve* curve, m_curvesList) curve->setLineType(lineType); } void XYCurveDock::lineSkipGapsChanged(bool skip) { if (m_initializing) return; foreach(XYCurve* curve, m_curvesList) curve->setLineSkipGaps(skip); } void XYCurveDock::lineInterpolationPointsCountChanged(int count) { if (m_initializing) return; foreach(XYCurve* curve, m_curvesList) curve->setLineInterpolationPointsCount(count); } void XYCurveDock::lineStyleChanged(int index) { if (m_initializing) return; Qt::PenStyle penStyle=Qt::PenStyle(index); QPen pen; foreach(XYCurve* curve, m_curvesList) { pen=curve->linePen(); pen.setStyle(penStyle); curve->setLinePen(pen); } } void XYCurveDock::lineColorChanged(const QColor& color) { if (m_initializing) return; QPen pen; foreach(XYCurve* curve, m_curvesList) { pen=curve->linePen(); pen.setColor(color); curve->setLinePen(pen); } m_initializing = true; GuiTools::updatePenStyles(ui.cbLineStyle, color); m_initializing = false; } void XYCurveDock::lineWidthChanged(double value) { if (m_initializing) return; QPen pen; foreach(XYCurve* curve, m_curvesList) { pen=curve->linePen(); pen.setWidthF( Worksheet::convertToSceneUnits(value, Worksheet::Point) ); curve->setLinePen(pen); } } void XYCurveDock::lineOpacityChanged(int value) { if (m_initializing) return; qreal opacity = (float)value/100.; foreach(XYCurve* curve, m_curvesList) curve->setLineOpacity(opacity); } void XYCurveDock::dropLineTypeChanged(int index) { XYCurve::DropLineType dropLineType = XYCurve::DropLineType(index); if ( dropLineType == XYCurve::NoDropLine) { ui.cbDropLineStyle->setEnabled(false); ui.kcbDropLineColor->setEnabled(false); ui.sbDropLineWidth->setEnabled(false); ui.sbDropLineOpacity->setEnabled(false); } else { ui.cbDropLineStyle->setEnabled(true); ui.kcbDropLineColor->setEnabled(true); ui.sbDropLineWidth->setEnabled(true); ui.sbDropLineOpacity->setEnabled(true); } if (m_initializing) return; foreach(XYCurve* curve, m_curvesList) curve->setDropLineType(dropLineType); } void XYCurveDock::dropLineStyleChanged(int index) { if (m_initializing) return; Qt::PenStyle penStyle=Qt::PenStyle(index); QPen pen; foreach(XYCurve* curve, m_curvesList) { pen=curve->dropLinePen(); pen.setStyle(penStyle); curve->setDropLinePen(pen); } } void XYCurveDock::dropLineColorChanged(const QColor& color) { if (m_initializing) return; QPen pen; foreach(XYCurve* curve, m_curvesList) { pen=curve->dropLinePen(); pen.setColor(color); curve->setDropLinePen(pen); } m_initializing = true; GuiTools::updatePenStyles(ui.cbDropLineStyle, color); m_initializing = false; } void XYCurveDock::dropLineWidthChanged(double value) { if (m_initializing) return; QPen pen; foreach(XYCurve* curve, m_curvesList) { pen=curve->dropLinePen(); pen.setWidthF( Worksheet::convertToSceneUnits(value, Worksheet::Point) ); curve->setDropLinePen(pen); } } void XYCurveDock::dropLineOpacityChanged(int value) { if (m_initializing) return; qreal opacity = (float)value/100.; foreach(XYCurve* curve, m_curvesList) curve->setDropLineOpacity(opacity); } //"Symbol"-tab void XYCurveDock::symbolsStyleChanged(int index) { Symbol::Style style = Symbol::Style(index); if (style == Symbol::NoSymbols) { ui.sbSymbolSize->setEnabled(false); ui.sbSymbolRotation->setEnabled(false); ui.sbSymbolOpacity->setEnabled(false); ui.kcbSymbolFillingColor->setEnabled(false); ui.cbSymbolFillingStyle->setEnabled(false); ui.cbSymbolBorderStyle->setEnabled(false); ui.kcbSymbolBorderColor->setEnabled(false); ui.sbSymbolBorderWidth->setEnabled(false); } else { ui.sbSymbolSize->setEnabled(true); ui.sbSymbolRotation->setEnabled(true); ui.sbSymbolOpacity->setEnabled(true); //enable/disable the symbol filling options in the GUI depending on the currently selected symbol. if (style!=Symbol::Line && style!=Symbol::Cross) { ui.cbSymbolFillingStyle->setEnabled(true); bool noBrush = (Qt::BrushStyle(ui.cbSymbolFillingStyle->currentIndex()) == Qt::NoBrush); ui.kcbSymbolFillingColor->setEnabled(!noBrush); } else { ui.kcbSymbolFillingColor->setEnabled(false); ui.cbSymbolFillingStyle->setEnabled(false); } ui.cbSymbolBorderStyle->setEnabled(true); bool noLine = (Qt::PenStyle(ui.cbSymbolBorderStyle->currentIndex()) == Qt::NoPen); ui.kcbSymbolBorderColor->setEnabled(!noLine); ui.sbSymbolBorderWidth->setEnabled(!noLine); } if (m_initializing) return; foreach(XYCurve* curve, m_curvesList) curve->setSymbolsStyle(style); } void XYCurveDock::symbolsSizeChanged(double value) { if (m_initializing) return; foreach(XYCurve* curve, m_curvesList) curve->setSymbolsSize( Worksheet::convertToSceneUnits(value, Worksheet::Point) ); } void XYCurveDock::symbolsRotationChanged(int value) { if (m_initializing) return; foreach(XYCurve* curve, m_curvesList) curve->setSymbolsRotationAngle(value); } void XYCurveDock::symbolsOpacityChanged(int value) { if (m_initializing) return; qreal opacity = (float)value/100.; foreach(XYCurve* curve, m_curvesList) curve->setSymbolsOpacity(opacity); } void XYCurveDock::symbolsFillingStyleChanged(int index) { Qt::BrushStyle brushStyle = Qt::BrushStyle(index); ui.kcbSymbolFillingColor->setEnabled(!(brushStyle == Qt::NoBrush)); if (m_initializing) return; QBrush brush; foreach(XYCurve* curve, m_curvesList) { brush=curve->symbolsBrush(); brush.setStyle(brushStyle); curve->setSymbolsBrush(brush); } } void XYCurveDock::symbolsFillingColorChanged(const QColor& color) { if (m_initializing) return; QBrush brush; foreach(XYCurve* curve, m_curvesList) { brush=curve->symbolsBrush(); brush.setColor(color); curve->setSymbolsBrush(brush); } m_initializing = true; GuiTools::updateBrushStyles(ui.cbSymbolFillingStyle, color ); m_initializing = false; } void XYCurveDock::symbolsBorderStyleChanged(int index) { Qt::PenStyle penStyle=Qt::PenStyle(index); if ( penStyle == Qt::NoPen ) { ui.kcbSymbolBorderColor->setEnabled(false); ui.sbSymbolBorderWidth->setEnabled(false); } else { ui.kcbSymbolBorderColor->setEnabled(true); ui.sbSymbolBorderWidth->setEnabled(true); } if (m_initializing) return; QPen pen; foreach(XYCurve* curve, m_curvesList) { pen=curve->symbolsPen(); pen.setStyle(penStyle); curve->setSymbolsPen(pen); } } void XYCurveDock::symbolsBorderColorChanged(const QColor& color) { if (m_initializing) return; QPen pen; foreach(XYCurve* curve, m_curvesList) { pen=curve->symbolsPen(); pen.setColor(color); curve->setSymbolsPen(pen); } m_initializing = true; GuiTools::updatePenStyles(ui.cbSymbolBorderStyle, color); m_initializing = false; } void XYCurveDock::symbolsBorderWidthChanged(double value) { if (m_initializing) return; QPen pen; foreach(XYCurve* curve, m_curvesList) { pen=curve->symbolsPen(); pen.setWidthF( Worksheet::convertToSceneUnits(value, Worksheet::Point) ); curve->setSymbolsPen(pen); } } //Values-tab /*! called when the type of the values (none, x, y, (x,y) etc.) was changed. */ void XYCurveDock::valuesTypeChanged(int index) { XYCurve::ValuesType valuesType = XYCurve::ValuesType(index); if (valuesType == XYCurve::NoValues) { //no values are to paint -> deactivate all the pertinent widgets ui.cbValuesPosition->setEnabled(false); ui.lValuesColumn->hide(); cbValuesColumn->hide(); ui.sbValuesDistance->setEnabled(false); ui.sbValuesRotation->setEnabled(false); ui.sbValuesOpacity->setEnabled(false); ui.cbValuesFormat->setEnabled(false); ui.cbValuesFormat->setEnabled(false); ui.sbValuesPrecision->setEnabled(false); ui.leValuesPrefix->setEnabled(false); ui.leValuesSuffix->setEnabled(false); ui.kfrValuesFont->setEnabled(false); ui.kcbValuesColor->setEnabled(false); } else { ui.cbValuesPosition->setEnabled(true); ui.sbValuesDistance->setEnabled(true); ui.sbValuesRotation->setEnabled(true); ui.sbValuesOpacity->setEnabled(true); ui.cbValuesFormat->setEnabled(true); ui.sbValuesPrecision->setEnabled(true); ui.leValuesPrefix->setEnabled(true); ui.leValuesSuffix->setEnabled(true); ui.kfrValuesFont->setEnabled(true); ui.kcbValuesColor->setEnabled(true); const Column* column; if (valuesType == XYCurve::ValuesCustomColumn) { ui.lValuesColumn->show(); cbValuesColumn->show(); column= static_cast(cbValuesColumn->currentModelIndex().internalPointer()); } else { ui.lValuesColumn->hide(); cbValuesColumn->hide(); if (valuesType == XYCurve::ValuesY) column = static_cast(m_curve->yColumn()); else column = static_cast(m_curve->xColumn()); } this->showValuesColumnFormat(column); } if (m_initializing) return; foreach(XYCurve* curve, m_curvesList) curve->setValuesType(valuesType); } /*! called when the custom column for the values was changed. */ void XYCurveDock::valuesColumnChanged(const QModelIndex& index) { if (m_initializing) return; Column* column= static_cast(index.internalPointer()); this->showValuesColumnFormat(column); foreach(XYCurve* curve, m_curvesList) { //TODO save also the format of the currently selected column for the values (precision etc.) curve->setValuesColumn(column); } } void XYCurveDock::valuesPositionChanged(int index) { if (m_initializing) return; foreach(XYCurve* curve, m_curvesList) curve->setValuesPosition(XYCurve::ValuesPosition(index)); } void XYCurveDock::valuesDistanceChanged(double value) { if (m_initializing) return; foreach(XYCurve* curve, m_curvesList) curve->setValuesDistance( Worksheet::convertToSceneUnits(value, Worksheet::Point) ); } void XYCurveDock::valuesRotationChanged(int value) { if (m_initializing) return; foreach(XYCurve* curve, m_curvesList) curve->setValuesRotationAngle(value); } void XYCurveDock::valuesOpacityChanged(int value) { if (m_initializing) return; qreal opacity = (float)value/100.; foreach(XYCurve* curve, m_curvesList) curve->setValuesOpacity(opacity); } void XYCurveDock::valuesPrefixChanged() { if (m_initializing) return; QString prefix = ui.leValuesPrefix->text(); foreach(XYCurve* curve, m_curvesList) curve->setValuesPrefix(prefix); } void XYCurveDock::valuesSuffixChanged() { if (m_initializing) return; QString suffix = ui.leValuesSuffix->text(); foreach(XYCurve* curve, m_curvesList) curve->setValuesSuffix(suffix); } void XYCurveDock::valuesFontChanged(const QFont& font) { if (m_initializing) return; QFont valuesFont = font; valuesFont.setPixelSize( Worksheet::convertToSceneUnits(font.pointSizeF(), Worksheet::Point) ); foreach(XYCurve* curve, m_curvesList) curve->setValuesFont(valuesFont); } void XYCurveDock::valuesColorChanged(const QColor& color) { if (m_initializing) return; foreach(XYCurve* curve, m_curvesList) curve->setValuesColor(color); } //Filling-tab void XYCurveDock::fillingPositionChanged(int index) { XYCurve::FillingPosition fillingPosition = XYCurve::FillingPosition(index); bool b = (fillingPosition != XYCurve::NoFilling); ui.cbFillingType->setEnabled(b); ui.cbFillingColorStyle->setEnabled(b); ui.cbFillingBrushStyle->setEnabled(b); ui.cbFillingImageStyle->setEnabled(b); ui.kcbFillingFirstColor->setEnabled(b); ui.kcbFillingSecondColor->setEnabled(b); ui.leFillingFileName->setEnabled(b); ui.bFillingOpen->setEnabled(b); ui.sbFillingOpacity->setEnabled(b); if (m_initializing) return; foreach(XYCurve* curve, m_curvesList) curve->setFillingPosition(fillingPosition); } void XYCurveDock::fillingTypeChanged(int index) { PlotArea::BackgroundType type = (PlotArea::BackgroundType)index; if (type == PlotArea::Color) { ui.lFillingColorStyle->show(); ui.cbFillingColorStyle->show(); ui.lFillingImageStyle->hide(); ui.cbFillingImageStyle->hide(); ui.lFillingBrushStyle->hide(); ui.cbFillingBrushStyle->hide(); ui.lFillingFileName->hide(); ui.leFillingFileName->hide(); ui.bFillingOpen->hide(); ui.lFillingFirstColor->show(); ui.kcbFillingFirstColor->show(); PlotArea::BackgroundColorStyle style = (PlotArea::BackgroundColorStyle) ui.cbFillingColorStyle->currentIndex(); if (style == PlotArea::SingleColor) { ui.lFillingFirstColor->setText(i18n("Color")); ui.lFillingSecondColor->hide(); ui.kcbFillingSecondColor->hide(); } else { ui.lFillingFirstColor->setText(i18n("First color")); ui.lFillingSecondColor->show(); ui.kcbFillingSecondColor->show(); } } else if (type == PlotArea::Image) { ui.lFillingColorStyle->hide(); ui.cbFillingColorStyle->hide(); ui.lFillingImageStyle->show(); ui.cbFillingImageStyle->show(); ui.lFillingBrushStyle->hide(); ui.cbFillingBrushStyle->hide(); ui.lFillingFileName->show(); ui.leFillingFileName->show(); ui.bFillingOpen->show(); ui.lFillingFirstColor->hide(); ui.kcbFillingFirstColor->hide(); ui.lFillingSecondColor->hide(); ui.kcbFillingSecondColor->hide(); } else if (type == PlotArea::Pattern) { ui.lFillingFirstColor->setText(i18n("Color")); ui.lFillingColorStyle->hide(); ui.cbFillingColorStyle->hide(); ui.lFillingImageStyle->hide(); ui.cbFillingImageStyle->hide(); ui.lFillingBrushStyle->show(); ui.cbFillingBrushStyle->show(); ui.lFillingFileName->hide(); ui.leFillingFileName->hide(); ui.bFillingOpen->hide(); ui.lFillingFirstColor->show(); ui.kcbFillingFirstColor->show(); ui.lFillingSecondColor->hide(); ui.kcbFillingSecondColor->hide(); } if (m_initializing) return; foreach(XYCurve* curve, m_curvesList) curve->setFillingType(type); } void XYCurveDock::fillingColorStyleChanged(int index) { PlotArea::BackgroundColorStyle style = (PlotArea::BackgroundColorStyle)index; if (style == PlotArea::SingleColor) { ui.lFillingFirstColor->setText(i18n("Color")); ui.lFillingSecondColor->hide(); ui.kcbFillingSecondColor->hide(); } else { ui.lFillingFirstColor->setText(i18n("First color")); ui.lFillingSecondColor->show(); ui.kcbFillingSecondColor->show(); ui.lFillingBrushStyle->hide(); ui.cbFillingBrushStyle->hide(); } if (m_initializing) return; foreach(XYCurve* curve, m_curvesList) curve->setFillingColorStyle(style); } void XYCurveDock::fillingImageStyleChanged(int index) { if (m_initializing) return; PlotArea::BackgroundImageStyle style = (PlotArea::BackgroundImageStyle)index; foreach(XYCurve* curve, m_curvesList) curve->setFillingImageStyle(style); } void XYCurveDock::fillingBrushStyleChanged(int index) { if (m_initializing) return; Qt::BrushStyle style = (Qt::BrushStyle)index; foreach(XYCurve* curve, m_curvesList) curve->setFillingBrushStyle(style); } void XYCurveDock::fillingFirstColorChanged(const QColor& c) { if (m_initializing) return; foreach(XYCurve* curve, m_curvesList) curve->setFillingFirstColor(c); m_initializing = true; GuiTools::updateBrushStyles(ui.cbFillingBrushStyle, c); m_initializing = false; } void XYCurveDock::fillingSecondColorChanged(const QColor& c) { if (m_initializing) return; foreach(XYCurve* curve, m_curvesList) curve->setFillingSecondColor(c); } /*! opens a file dialog and lets the user select the image file. */ void XYCurveDock::selectFile() { KConfigGroup conf(KSharedConfig::openConfig(), "XYCurveDock"); QString dir = conf.readEntry("LastImageDir", ""); - QString path = QFileDialog::getOpenFileName(this, i18n("Select the image file"), dir); + + QString formats; + foreach(const QByteArray& format, QImageReader::supportedImageFormats()) { + QString f = "*." + QString(format.constData()); + formats.isEmpty() ? formats+=f : formats+=' '+f; + } + + QString path = QFileDialog::getOpenFileName(this, i18n("Select the image file"), dir, i18n("Images (%1)", formats)); if (path.isEmpty()) return; //cancel was clicked in the file-dialog int pos = path.lastIndexOf(QDir::separator()); if (pos!=-1) { QString newDir = path.left(pos); if (newDir!=dir) conf.writeEntry("LastImageDir", newDir); } ui.leFillingFileName->setText( path ); foreach(XYCurve* curve, m_curvesList) curve->setFillingFileName(path); } void XYCurveDock::fileNameChanged() { if (m_initializing) return; QString fileName = ui.leFillingFileName->text(); foreach(XYCurve* curve, m_curvesList) curve->setFillingFileName(fileName); } void XYCurveDock::fillingOpacityChanged(int value) { if (m_initializing) return; qreal opacity = (float)value/100.; foreach(XYCurve* curve, m_curvesList) curve->setFillingOpacity(opacity); } //"Error bars"-Tab void XYCurveDock::xErrorTypeChanged(int index) const { if (index == 0) { //no error ui.lXErrorDataPlus->setVisible(false); cbXErrorPlusColumn->setVisible(false); ui.lXErrorDataMinus->setVisible(false); cbXErrorMinusColumn->setVisible(false); } else if (index == 1) { //symmetric error ui.lXErrorDataPlus->setVisible(true); cbXErrorPlusColumn->setVisible(true); ui.lXErrorDataMinus->setVisible(false); cbXErrorMinusColumn->setVisible(false); ui.lXErrorDataPlus->setText(i18n("Data, +-")); } else if (index == 2) { //asymmetric error ui.lXErrorDataPlus->setVisible(true); cbXErrorPlusColumn->setVisible(true); ui.lXErrorDataMinus->setVisible(true); cbXErrorMinusColumn->setVisible(true); ui.lXErrorDataPlus->setText(i18n("Data, +")); } bool b = (index!=0 || ui.cbYErrorType->currentIndex()!=0); ui.lErrorFormat->setVisible(b); ui.lErrorBarsType->setVisible(b); ui.cbErrorBarsType->setVisible(b); ui.lErrorBarsStyle->setVisible(b); ui.cbErrorBarsStyle->setVisible(b); ui.lErrorBarsColor->setVisible(b); ui.kcbErrorBarsColor->setVisible(b); ui.lErrorBarsWidth->setVisible(b); ui.sbErrorBarsWidth->setVisible(b); ui.lErrorBarsOpacity->setVisible(b); ui.sbErrorBarsOpacity->setVisible(b); if (m_initializing) return; foreach(XYCurve* curve, m_curvesList) curve->setXErrorType(XYCurve::ErrorType(index)); } void XYCurveDock::xErrorPlusColumnChanged(const QModelIndex& index) const { Q_UNUSED(index); if (m_initializing) return; AbstractAspect* aspect = static_cast(index.internalPointer()); AbstractColumn* column = dynamic_cast(aspect); Q_ASSERT(column); foreach(XYCurve* curve, m_curvesList) curve->setXErrorPlusColumn(column); } void XYCurveDock::xErrorMinusColumnChanged(const QModelIndex& index) const { Q_UNUSED(index); if (m_initializing) return; AbstractAspect* aspect = static_cast(index.internalPointer()); AbstractColumn* column = dynamic_cast(aspect); Q_ASSERT(column); foreach(XYCurve* curve, m_curvesList) curve->setXErrorMinusColumn(column); } void XYCurveDock::yErrorTypeChanged(int index) const { if (index == 0) { //no error ui.lYErrorDataPlus->setVisible(false); cbYErrorPlusColumn->setVisible(false); ui.lYErrorDataMinus->setVisible(false); cbYErrorMinusColumn->setVisible(false); } else if (index == 1) { //symmetric error ui.lYErrorDataPlus->setVisible(true); cbYErrorPlusColumn->setVisible(true); ui.lYErrorDataMinus->setVisible(false); cbYErrorMinusColumn->setVisible(false); ui.lYErrorDataPlus->setText(i18n("Data, +-")); } else if (index == 2) { //asymmetric error ui.lYErrorDataPlus->setVisible(true); cbYErrorPlusColumn->setVisible(true); ui.lYErrorDataMinus->setVisible(true); cbYErrorMinusColumn->setVisible(true); ui.lYErrorDataPlus->setText(i18n("Data, +")); } bool b = (index!=0 || ui.cbXErrorType->currentIndex()!=0); ui.lErrorFormat->setVisible(b); ui.lErrorBarsType->setVisible(b); ui.cbErrorBarsType->setVisible(b); ui.lErrorBarsStyle->setVisible(b); ui.cbErrorBarsStyle->setVisible(b); ui.lErrorBarsColor->setVisible(b); ui.kcbErrorBarsColor->setVisible(b); ui.lErrorBarsWidth->setVisible(b); ui.sbErrorBarsWidth->setVisible(b); ui.lErrorBarsOpacity->setVisible(b); ui.sbErrorBarsOpacity->setVisible(b); if (m_initializing) return; foreach(XYCurve* curve, m_curvesList) curve->setYErrorType(XYCurve::ErrorType(index)); } void XYCurveDock::yErrorPlusColumnChanged(const QModelIndex& index) const { Q_UNUSED(index); if (m_initializing) return; AbstractAspect* aspect = static_cast(index.internalPointer()); AbstractColumn* column = dynamic_cast(aspect); Q_ASSERT(column); foreach(XYCurve* curve, m_curvesList) curve->setYErrorPlusColumn(column); } void XYCurveDock::yErrorMinusColumnChanged(const QModelIndex& index) const { Q_UNUSED(index); if (m_initializing) return; AbstractAspect* aspect = static_cast(index.internalPointer()); AbstractColumn* column = dynamic_cast(aspect); Q_ASSERT(column); foreach(XYCurve* curve, m_curvesList) curve->setYErrorMinusColumn(column); } void XYCurveDock::errorBarsTypeChanged(int index) const { XYCurve::ErrorBarsType type = XYCurve::ErrorBarsType(index); bool b = (type == XYCurve::ErrorBarsWithEnds); ui.lErrorBarsCapSize->setVisible(b); ui.sbErrorBarsCapSize->setVisible(b); if (m_initializing) return; foreach(XYCurve* curve, m_curvesList) curve->setErrorBarsType(type); } void XYCurveDock::errorBarsCapSizeChanged(double value) const { if (m_initializing) return; float size = Worksheet::convertToSceneUnits(value, Worksheet::Point); foreach(XYCurve* curve, m_curvesList) curve->setErrorBarsCapSize(size); } void XYCurveDock::errorBarsStyleChanged(int index) const { if (m_initializing) return; Qt::PenStyle penStyle=Qt::PenStyle(index); QPen pen; foreach(XYCurve* curve, m_curvesList) { pen=curve->errorBarsPen(); pen.setStyle(penStyle); curve->setErrorBarsPen(pen); } } void XYCurveDock::errorBarsColorChanged(const QColor& color) { if (m_initializing) return; QPen pen; foreach(XYCurve* curve, m_curvesList) { pen=curve->errorBarsPen(); pen.setColor(color); curve->setErrorBarsPen(pen); } m_initializing = true; GuiTools::updatePenStyles(ui.cbErrorBarsStyle, color); m_initializing = false; } void XYCurveDock::errorBarsWidthChanged(double value) const { if (m_initializing) return; QPen pen; foreach(XYCurve* curve, m_curvesList) { pen=curve->errorBarsPen(); pen.setWidthF( Worksheet::convertToSceneUnits(value, Worksheet::Point) ); curve->setErrorBarsPen(pen); } } void XYCurveDock::errorBarsOpacityChanged(int value) const { if (m_initializing) return; qreal opacity = (float)value/100.; foreach(XYCurve* curve, m_curvesList) curve->setErrorBarsOpacity(opacity); } //************************************************************* //*********** SLOTs for changes triggered in XYCurve ********** //************************************************************* //General-Tab void XYCurveDock::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 XYCurveDock::curveXColumnChanged(const AbstractColumn* column) { m_initializing = true; this->setModelIndexFromAspect(cbXColumn, column); m_initializing = false; } void XYCurveDock::curveYColumnChanged(const AbstractColumn* column) { m_initializing = true; this->setModelIndexFromAspect(cbYColumn, column); m_initializing = false; } void XYCurveDock::curveVisibilityChanged(bool on) { m_initializing = true; uiGeneralTab.chkVisible->setChecked(on); m_initializing = false; } //Line-Tab void XYCurveDock::curveLineTypeChanged(XYCurve::LineType type) { m_initializing = true; ui.cbLineType->setCurrentIndex( (int) type); m_initializing = false; } void XYCurveDock::curveLineSkipGapsChanged(bool skip) { m_initializing = true; ui.chkLineSkipGaps->setChecked(skip); m_initializing = false; } void XYCurveDock::curveLineInterpolationPointsCountChanged(int count) { m_initializing = true; ui.sbLineInterpolationPointsCount->setValue(count); m_initializing = false; } void XYCurveDock::curveLinePenChanged(const QPen& pen) { m_initializing = true; ui.cbLineStyle->setCurrentIndex( (int)pen.style()); ui.kcbLineColor->setColor( pen.color()); GuiTools::updatePenStyles(ui.cbLineStyle, pen.color()); ui.sbLineWidth->setValue( Worksheet::convertFromSceneUnits( pen.widthF(), Worksheet::Point) ); m_initializing = false; } void XYCurveDock::curveLineOpacityChanged(qreal opacity) { m_initializing = true; ui.sbLineOpacity->setValue( round(opacity*100.0) ); m_initializing = false; } void XYCurveDock::curveDropLineTypeChanged(XYCurve::DropLineType type) { m_initializing = true; ui.cbDropLineType->setCurrentIndex( (int)type ); m_initializing = false; } void XYCurveDock::curveDropLinePenChanged(const QPen& pen) { m_initializing = true; ui.cbDropLineStyle->setCurrentIndex( (int) pen.style()); ui.kcbDropLineColor->setColor( pen.color()); GuiTools::updatePenStyles(ui.cbDropLineStyle, pen.color()); ui.sbDropLineWidth->setValue( Worksheet::convertFromSceneUnits(pen.widthF(),Worksheet::Point) ); m_initializing = false; } void XYCurveDock::curveDropLineOpacityChanged(qreal opacity) { m_initializing = true; ui.sbDropLineOpacity->setValue( round(opacity*100.0) ); m_initializing = false; } //Symbol-Tab void XYCurveDock::curveSymbolsStyleChanged(Symbol::Style style) { m_initializing = true; ui.cbSymbolStyle->setCurrentIndex((int)style); m_initializing = false; } void XYCurveDock::curveSymbolsSizeChanged(qreal size) { m_initializing = true; ui.sbSymbolSize->setValue( Worksheet::convertFromSceneUnits(size, Worksheet::Point) ); m_initializing = false; } void XYCurveDock::curveSymbolsRotationAngleChanged(qreal angle) { m_initializing = true; ui.sbSymbolRotation->setValue(angle); m_initializing = false; } void XYCurveDock::curveSymbolsOpacityChanged(qreal opacity) { m_initializing = true; ui.sbSymbolOpacity->setValue( round(opacity*100.0) ); m_initializing = false; } void XYCurveDock::curveSymbolsBrushChanged(QBrush brush) { m_initializing = true; ui.cbSymbolFillingStyle->setCurrentIndex((int) brush.style()); ui.kcbSymbolFillingColor->setColor(brush.color()); GuiTools::updateBrushStyles(ui.cbSymbolFillingStyle, brush.color()); m_initializing = false; } void XYCurveDock::curveSymbolsPenChanged(const QPen& pen) { m_initializing = true; ui.cbSymbolBorderStyle->setCurrentIndex( (int) pen.style()); ui.kcbSymbolBorderColor->setColor( pen.color()); GuiTools::updatePenStyles(ui.cbSymbolBorderStyle, pen.color()); ui.sbSymbolBorderWidth->setValue( Worksheet::convertFromSceneUnits(pen.widthF(), Worksheet::Point)); m_initializing = false; } //Values-Tab void XYCurveDock::curveValuesTypeChanged(XYCurve::ValuesType type) { m_initializing = true; ui.cbValuesType->setCurrentIndex((int) type); m_initializing = false; } void XYCurveDock::curveValuesColumnChanged(const AbstractColumn* column) { m_initializing = true; this->setModelIndexFromAspect(cbValuesColumn, column); m_initializing = false; } void XYCurveDock::curveValuesPositionChanged(XYCurve::ValuesPosition position) { m_initializing = true; ui.cbValuesPosition->setCurrentIndex((int) position); m_initializing = false; } void XYCurveDock::curveValuesDistanceChanged(qreal distance) { m_initializing = true; ui.sbValuesDistance->setValue( Worksheet::convertFromSceneUnits(distance, Worksheet::Point) ); m_initializing = false; } void XYCurveDock::curveValuesRotationAngleChanged(qreal angle) { m_initializing = true; ui.sbValuesRotation->setValue(angle); m_initializing = false; } void XYCurveDock::curveValuesOpacityChanged(qreal opacity) { m_initializing = true; ui.sbValuesOpacity->setValue( round(opacity*100.0) ); m_initializing = false; } void XYCurveDock::curveValuesPrefixChanged(QString prefix) { m_initializing = true; ui.leValuesPrefix->setText(prefix); m_initializing = false; } void XYCurveDock::curveValuesSuffixChanged(QString suffix) { m_initializing = true; ui.leValuesSuffix->setText(suffix); m_initializing = false; } void XYCurveDock::curveValuesFontChanged(QFont font) { m_initializing = true; font.setPointSizeF( round(Worksheet::convertFromSceneUnits(font.pixelSize(), Worksheet::Point)) ); ui.kfrValuesFont->setFont(font); m_initializing = false; } void XYCurveDock::curveValuesColorChanged(QColor color) { m_initializing = true; ui.kcbValuesColor->setColor(color); m_initializing = false; } //Filling void XYCurveDock::curveFillingPositionChanged(XYCurve::FillingPosition position) { m_initializing = true; ui.cbFillingPosition->setCurrentIndex((int)position); m_initializing = false; } void XYCurveDock::curveFillingTypeChanged(PlotArea::BackgroundType type) { m_initializing = true; ui.cbFillingType->setCurrentIndex(type); m_initializing = false; } void XYCurveDock::curveFillingColorStyleChanged(PlotArea::BackgroundColorStyle style) { m_initializing = true; ui.cbFillingColorStyle->setCurrentIndex(style); m_initializing = false; } void XYCurveDock::curveFillingImageStyleChanged(PlotArea::BackgroundImageStyle style) { m_initializing = true; ui.cbFillingImageStyle->setCurrentIndex(style); m_initializing = false; } void XYCurveDock::curveFillingBrushStyleChanged(Qt::BrushStyle style) { m_initializing = true; ui.cbFillingBrushStyle->setCurrentIndex(style); m_initializing = false; } void XYCurveDock::curveFillingFirstColorChanged(QColor& color) { m_initializing = true; ui.kcbFillingFirstColor->setColor(color); GuiTools::updateBrushStyles(ui.cbFillingBrushStyle, color); m_initializing = false; } void XYCurveDock::curveFillingSecondColorChanged(QColor& color) { m_initializing = true; ui.kcbFillingSecondColor->setColor(color); m_initializing = false; } void XYCurveDock::curveFillingFileNameChanged(QString& filename) { m_initializing = true; ui.leFillingFileName->setText(filename); m_initializing = false; } void XYCurveDock::curveFillingOpacityChanged(float opacity) { m_initializing = true; ui.sbFillingOpacity->setValue( round(opacity*100.0) ); m_initializing = false; } //"Error bars"-Tab void XYCurveDock::curveXErrorTypeChanged(XYCurve::ErrorType type) { m_initializing = true; ui.cbXErrorType->setCurrentIndex((int) type); m_initializing = false; } void XYCurveDock::curveXErrorPlusColumnChanged(const AbstractColumn* column) { m_initializing = true; this->setModelIndexFromAspect(cbXErrorPlusColumn, column); m_initializing = false; } void XYCurveDock::curveXErrorMinusColumnChanged(const AbstractColumn* column) { m_initializing = true; this->setModelIndexFromAspect(cbXErrorMinusColumn, column); m_initializing = false; } void XYCurveDock::curveYErrorTypeChanged(XYCurve::ErrorType type) { m_initializing = true; ui.cbYErrorType->setCurrentIndex((int) type); m_initializing = false; } void XYCurveDock::curveYErrorPlusColumnChanged(const AbstractColumn* column) { m_initializing = true; this->setModelIndexFromAspect(cbYErrorPlusColumn, column); m_initializing = false; } void XYCurveDock::curveYErrorMinusColumnChanged(const AbstractColumn* column) { m_initializing = true; this->setModelIndexFromAspect(cbYErrorMinusColumn, column); m_initializing = false; } void XYCurveDock::curveErrorBarsCapSizeChanged(qreal size) { m_initializing = true; ui.sbErrorBarsCapSize->setValue( Worksheet::convertFromSceneUnits(size, Worksheet::Point) ); m_initializing = false; } void XYCurveDock::curveErrorBarsTypeChanged(XYCurve::ErrorBarsType type) { m_initializing = true; ui.cbErrorBarsType->setCurrentIndex( (int) type); m_initializing = false; } void XYCurveDock::curveErrorBarsPenChanged(QPen pen) { m_initializing = true; ui.cbErrorBarsStyle->setCurrentIndex( (int) pen.style()); ui.kcbErrorBarsColor->setColor( pen.color()); GuiTools::updatePenStyles(ui.cbErrorBarsStyle, pen.color()); ui.sbErrorBarsWidth->setValue( Worksheet::convertFromSceneUnits(pen.widthF(),Worksheet::Point) ); m_initializing = false; } void XYCurveDock::curveErrorBarsOpacityChanged(qreal opacity) { m_initializing = true; ui.sbErrorBarsOpacity->setValue( round(opacity*100.0) ); m_initializing = false; } //************************************************************* //************************* Settings ************************** //************************************************************* void XYCurveDock::load() { //General //This data is read in XYCurveDock::setCurves(). //Line ui.cbLineType->setCurrentIndex( (int) m_curve->lineType() ); ui.chkLineSkipGaps->setChecked( m_curve->lineSkipGaps() ); ui.sbLineInterpolationPointsCount->setValue( m_curve->lineInterpolationPointsCount() ); ui.cbLineStyle->setCurrentIndex( (int) m_curve->linePen().style() ); ui.kcbLineColor->setColor( m_curve->linePen().color() ); ui.sbLineWidth->setValue( Worksheet::convertFromSceneUnits(m_curve->linePen().widthF(), Worksheet::Point) ); ui.sbLineOpacity->setValue( round(m_curve->lineOpacity()*100.0) ); //Drop lines ui.cbDropLineType->setCurrentIndex( (int) m_curve->dropLineType() ); ui.cbDropLineStyle->setCurrentIndex( (int) m_curve->dropLinePen().style() ); ui.kcbDropLineColor->setColor( m_curve->dropLinePen().color() ); ui.sbDropLineWidth->setValue( Worksheet::convertFromSceneUnits(m_curve->dropLinePen().widthF(),Worksheet::Point) ); ui.sbDropLineOpacity->setValue( round(m_curve->dropLineOpacity()*100.0) ); //Symbols //TODO: character ui.cbSymbolStyle->setCurrentIndex( (int)m_curve->symbolsStyle() ); ui.sbSymbolSize->setValue( Worksheet::convertFromSceneUnits(m_curve->symbolsSize(), Worksheet::Point) ); ui.sbSymbolRotation->setValue( m_curve->symbolsRotationAngle() ); ui.sbSymbolOpacity->setValue( round(m_curve->symbolsOpacity()*100.0) ); ui.cbSymbolFillingStyle->setCurrentIndex( (int) m_curve->symbolsBrush().style() ); ui.kcbSymbolFillingColor->setColor( m_curve->symbolsBrush().color() ); ui.cbSymbolBorderStyle->setCurrentIndex( (int) m_curve->symbolsPen().style() ); ui.kcbSymbolBorderColor->setColor( m_curve->symbolsPen().color() ); ui.sbSymbolBorderWidth->setValue( Worksheet::convertFromSceneUnits(m_curve->symbolsPen().widthF(), Worksheet::Point) ); //Values ui.cbValuesType->setCurrentIndex( (int) m_curve->valuesType() ); ui.cbValuesPosition->setCurrentIndex( (int) m_curve->valuesPosition() ); ui.sbValuesDistance->setValue( Worksheet::convertFromSceneUnits(m_curve->valuesDistance(), Worksheet::Point) ); ui.sbValuesRotation->setValue( m_curve->valuesRotationAngle() ); ui.sbValuesOpacity->setValue( round(m_curve->valuesOpacity()*100.0) ); ui.leValuesPrefix->setText( m_curve->valuesPrefix() ); ui.leValuesSuffix->setText( m_curve->valuesSuffix() ); QFont valuesFont = m_curve->valuesFont(); valuesFont.setPointSizeF( round(Worksheet::convertFromSceneUnits(valuesFont.pixelSize(), Worksheet::Point)) ); ui.kfrValuesFont->setFont(valuesFont); ui.kcbValuesColor->setColor( m_curve->valuesColor() ); //Filling ui.cbFillingPosition->setCurrentIndex( (int) m_curve->fillingPosition() ); ui.cbFillingType->setCurrentIndex( (int)m_curve->fillingType() ); ui.cbFillingColorStyle->setCurrentIndex( (int) m_curve->fillingColorStyle() ); ui.cbFillingImageStyle->setCurrentIndex( (int) m_curve->fillingImageStyle() ); ui.cbFillingBrushStyle->setCurrentIndex( (int) m_curve->fillingBrushStyle() ); ui.leFillingFileName->setText( m_curve->fillingFileName() ); ui.kcbFillingFirstColor->setColor( m_curve->fillingFirstColor() ); ui.kcbFillingSecondColor->setColor( m_curve->fillingSecondColor() ); ui.sbFillingOpacity->setValue( round(m_curve->fillingOpacity()*100.0) ); //Error bars ui.cbXErrorType->setCurrentIndex( (int) m_curve->xErrorType() ); ui.cbYErrorType->setCurrentIndex( (int) m_curve->yErrorType() ); ui.cbErrorBarsType->setCurrentIndex( (int) m_curve->errorBarsType() ); ui.sbErrorBarsCapSize->setValue( Worksheet::convertFromSceneUnits(m_curve->errorBarsCapSize(), Worksheet::Point) ); ui.cbErrorBarsStyle->setCurrentIndex( (int) m_curve->errorBarsPen().style() ); ui.kcbErrorBarsColor->setColor( m_curve->errorBarsPen().color() ); ui.sbErrorBarsWidth->setValue( Worksheet::convertFromSceneUnits(m_curve->errorBarsPen().widthF(),Worksheet::Point) ); ui.sbErrorBarsOpacity->setValue( round(m_curve->errorBarsOpacity()*100.0) ); m_initializing=true; GuiTools::updatePenStyles(ui.cbLineStyle, ui.kcbLineColor->color()); GuiTools::updatePenStyles(ui.cbDropLineStyle, ui.kcbDropLineColor->color()); GuiTools::updateBrushStyles(ui.cbSymbolFillingStyle, ui.kcbSymbolFillingColor->color()); GuiTools::updatePenStyles(ui.cbSymbolBorderStyle, ui.kcbSymbolBorderColor->color()); GuiTools::updatePenStyles(ui.cbErrorBarsStyle, ui.kcbErrorBarsColor->color()); m_initializing=false; } void XYCurveDock::loadConfigFromTemplate(KConfig& config) { //extract the name of the template from the file name QString name; int index = config.name().lastIndexOf(QDir::separator()); if (index!=-1) name = config.name().right(config.name().size() - index - 1); else name = config.name(); int size = m_curvesList.size(); if (size>1) m_curve->beginMacro(i18n("%1 xy-curves: template \"%2\" loaded", size, name)); else m_curve->beginMacro(i18n("%1: template \"%2\" loaded", m_curve->name(), name)); this->loadConfig(config); m_curve->endMacro(); } void XYCurveDock::loadConfig(KConfig& config) { KConfigGroup group = config.group( "XYCurve" ); //General //we don't load/save the settings in the general-tab, since they are not style related. //It doesn't make sense to load/save them in the template. //This data is read in XYCurveDock::setCurves(). //Line ui.cbLineType->setCurrentIndex( group.readEntry("LineType", (int) m_curve->lineType()) ); ui.chkLineSkipGaps->setChecked( group.readEntry("LineSkipGaps", m_curve->lineSkipGaps()) ); ui.sbLineInterpolationPointsCount->setValue( group.readEntry("LineInterpolationPointsCount", m_curve->lineInterpolationPointsCount()) ); ui.cbLineStyle->setCurrentIndex( group.readEntry("LineStyle", (int) m_curve->linePen().style()) ); ui.kcbLineColor->setColor( group.readEntry("LineColor", m_curve->linePen().color()) ); ui.sbLineWidth->setValue( Worksheet::convertFromSceneUnits(group.readEntry("LineWidth", m_curve->linePen().widthF()), Worksheet::Point) ); ui.sbLineOpacity->setValue( round(group.readEntry("LineOpacity", m_curve->lineOpacity())*100.0) ); //Drop lines ui.cbDropLineType->setCurrentIndex( group.readEntry("DropLineType", (int) m_curve->dropLineType()) ); ui.cbDropLineStyle->setCurrentIndex( group.readEntry("DropLineStyle", (int) m_curve->dropLinePen().style()) ); ui.kcbDropLineColor->setColor( group.readEntry("DropLineColor", m_curve->dropLinePen().color()) ); ui.sbDropLineWidth->setValue( Worksheet::convertFromSceneUnits(group.readEntry("DropLineWidth", m_curve->dropLinePen().widthF()),Worksheet::Point) ); ui.sbDropLineOpacity->setValue( round(group.readEntry("DropLineOpacity", m_curve->dropLineOpacity())*100.0) ); //Symbols //TODO: character ui.cbSymbolStyle->setCurrentIndex( group.readEntry("SymbolStyle", (int)m_curve->symbolsStyle()) ); ui.sbSymbolSize->setValue( Worksheet::convertFromSceneUnits(group.readEntry("SymbolSize", m_curve->symbolsSize()), Worksheet::Point) ); ui.sbSymbolRotation->setValue( group.readEntry("SymbolRotation", m_curve->symbolsRotationAngle()) ); ui.sbSymbolOpacity->setValue( round(group.readEntry("SymbolOpacity", m_curve->symbolsOpacity())*100.0) ); ui.cbSymbolFillingStyle->setCurrentIndex( group.readEntry("SymbolFillingStyle", (int) m_curve->symbolsBrush().style()) ); ui.kcbSymbolFillingColor->setColor( group.readEntry("SymbolFillingColor", m_curve->symbolsBrush().color()) ); ui.cbSymbolBorderStyle->setCurrentIndex( group.readEntry("SymbolBorderStyle", (int) m_curve->symbolsPen().style()) ); ui.kcbSymbolBorderColor->setColor( group.readEntry("SymbolBorderColor", m_curve->symbolsPen().color()) ); ui.sbSymbolBorderWidth->setValue( Worksheet::convertFromSceneUnits(group.readEntry("SymbolBorderWidth",m_curve->symbolsPen().widthF()), Worksheet::Point) ); //Values ui.cbValuesType->setCurrentIndex( group.readEntry("ValuesType", (int) m_curve->valuesType()) ); ui.cbValuesPosition->setCurrentIndex( group.readEntry("ValuesPosition", (int) m_curve->valuesPosition()) ); ui.sbValuesDistance->setValue( Worksheet::convertFromSceneUnits(group.readEntry("ValuesDistance", m_curve->valuesDistance()), Worksheet::Point) ); ui.sbValuesRotation->setValue( group.readEntry("ValuesRotation", m_curve->valuesRotationAngle()) ); ui.sbValuesOpacity->setValue( round(group.readEntry("ValuesOpacity",m_curve->valuesOpacity())*100.0) ); ui.leValuesPrefix->setText( group.readEntry("ValuesPrefix", m_curve->valuesPrefix()) ); ui.leValuesSuffix->setText( group.readEntry("ValuesSuffix", m_curve->valuesSuffix()) ); QFont valuesFont = m_curve->valuesFont(); valuesFont.setPointSizeF( round(Worksheet::convertFromSceneUnits(valuesFont.pixelSize(), Worksheet::Point)) ); ui.kfrValuesFont->setFont( group.readEntry("ValuesFont", valuesFont) ); ui.kcbValuesColor->setColor( group.readEntry("ValuesColor", m_curve->valuesColor()) ); //Filling ui.cbFillingPosition->setCurrentIndex( group.readEntry("FillingPosition", (int) m_curve->fillingPosition()) ); ui.cbFillingType->setCurrentIndex( group.readEntry("FillingType", (int) m_curve->fillingType()) ); ui.cbFillingColorStyle->setCurrentIndex( group.readEntry("FillingColorStyle", (int) m_curve->fillingColorStyle()) ); ui.cbFillingImageStyle->setCurrentIndex( group.readEntry("FillingImageStyle", (int) m_curve->fillingImageStyle()) ); ui.cbFillingBrushStyle->setCurrentIndex( group.readEntry("FillingBrushStyle", (int) m_curve->fillingBrushStyle()) ); ui.leFillingFileName->setText( group.readEntry("FillingFileName", m_curve->fillingFileName()) ); ui.kcbFillingFirstColor->setColor( group.readEntry("FillingFirstColor", m_curve->fillingFirstColor()) ); ui.kcbFillingSecondColor->setColor( group.readEntry("FillingSecondColor", m_curve->fillingSecondColor()) ); ui.sbFillingOpacity->setValue( round(group.readEntry("FillingOpacity", m_curve->fillingOpacity())*100.0) ); //Error bars ui.cbXErrorType->setCurrentIndex( group.readEntry("XErrorType", (int) m_curve->xErrorType()) ); ui.cbYErrorType->setCurrentIndex( group.readEntry("YErrorType", (int) m_curve->yErrorType()) ); ui.cbErrorBarsType->setCurrentIndex( group.readEntry("ErrorBarsType", (int) m_curve->errorBarsType()) ); ui.sbErrorBarsCapSize->setValue( Worksheet::convertFromSceneUnits(group.readEntry("ErrorBarsCapSize", m_curve->errorBarsCapSize()), Worksheet::Point) ); ui.cbErrorBarsStyle->setCurrentIndex( group.readEntry("ErrorBarsStyle", (int) m_curve->errorBarsPen().style()) ); ui.kcbErrorBarsColor->setColor( group.readEntry("ErrorBarsColor", m_curve->errorBarsPen().color()) ); ui.sbErrorBarsWidth->setValue( Worksheet::convertFromSceneUnits(group.readEntry("ErrorBarsWidth", m_curve->errorBarsPen().widthF()),Worksheet::Point) ); ui.sbErrorBarsOpacity->setValue( round(group.readEntry("ErrorBarsOpacity", m_curve->errorBarsOpacity())*100.0) ); m_initializing=true; GuiTools::updatePenStyles(ui.cbLineStyle, ui.kcbLineColor->color()); GuiTools::updatePenStyles(ui.cbDropLineStyle, ui.kcbDropLineColor->color()); GuiTools::updateBrushStyles(ui.cbSymbolFillingStyle, ui.kcbSymbolFillingColor->color()); GuiTools::updatePenStyles(ui.cbSymbolBorderStyle, ui.kcbSymbolBorderColor->color()); GuiTools::updatePenStyles(ui.cbErrorBarsStyle, ui.kcbErrorBarsColor->color()); GuiTools::updateBrushStyles(ui.cbFillingBrushStyle, ui.kcbFillingFirstColor->color()); m_initializing=false; } void XYCurveDock::saveConfigAsTemplate(KConfig& config) { KConfigGroup group = config.group( "XYCurve" ); //General //we don't load/save the settings in the general-tab, since they are not style related. //It doesn't make sense to load/save them in the template. group.writeEntry("LineType", ui.cbLineType->currentIndex()); group.writeEntry("LineSkipGaps", ui.chkLineSkipGaps->isChecked()); group.writeEntry("LineInterpolationPointsCount", ui.sbLineInterpolationPointsCount->value() ); group.writeEntry("LineStyle", ui.cbLineStyle->currentIndex()); group.writeEntry("LineColor", ui.kcbLineColor->color()); group.writeEntry("LineWidth", Worksheet::convertToSceneUnits(ui.sbLineWidth->value(),Worksheet::Point) ); group.writeEntry("LineOpacity", ui.sbLineOpacity->value()/100 ); //Drop Line group.writeEntry("DropLineType", ui.cbDropLineType->currentIndex()); group.writeEntry("DropLineStyle", ui.cbDropLineStyle->currentIndex()); group.writeEntry("DropLineColor", ui.kcbDropLineColor->color()); group.writeEntry("DropLineWidth", Worksheet::convertToSceneUnits(ui.sbDropLineWidth->value(),Worksheet::Point) ); group.writeEntry("DropLineOpacity", ui.sbDropLineOpacity->value()/100 ); //Symbol (TODO: character) group.writeEntry("SymbolStyle", ui.cbSymbolStyle->currentText()); group.writeEntry("SymbolSize", Worksheet::convertToSceneUnits(ui.sbSymbolSize->value(),Worksheet::Point)); group.writeEntry("SymbolRotation", ui.sbSymbolRotation->value()); group.writeEntry("SymbolOpacity", ui.sbSymbolOpacity->value()/100 ); group.writeEntry("SymbolFillingStyle", ui.cbSymbolFillingStyle->currentIndex()); group.writeEntry("SymbolFillingColor", ui.kcbSymbolFillingColor->color()); group.writeEntry("SymbolBorderStyle", ui.cbSymbolBorderStyle->currentIndex()); group.writeEntry("SymbolBorderColor", ui.kcbSymbolBorderColor->color()); group.writeEntry("SymbolBorderWidth", Worksheet::convertToSceneUnits(ui.sbSymbolBorderWidth->value(),Worksheet::Point)); //Values group.writeEntry("ValuesType", ui.cbValuesType->currentIndex()); group.writeEntry("ValuesPosition", ui.cbValuesPosition->currentIndex()); group.writeEntry("ValuesDistance", Worksheet::convertToSceneUnits(ui.sbValuesDistance->value(),Worksheet::Point)); group.writeEntry("ValuesRotation", ui.sbValuesRotation->value()); group.writeEntry("ValuesOpacity", ui.sbValuesOpacity->value()/100); group.writeEntry("ValuesPrefix", ui.leValuesPrefix->text()); group.writeEntry("ValuesSuffix", ui.leValuesSuffix->text()); group.writeEntry("ValuesFont", ui.kfrValuesFont->font()); group.writeEntry("ValuesColor", ui.kcbValuesColor->color()); //Filling group.writeEntry("FillingPosition", ui.cbFillingPosition->currentIndex()); group.writeEntry("FillingType", ui.cbFillingType->currentIndex()); group.writeEntry("FillingColorStyle", ui.cbFillingColorStyle->currentIndex()); group.writeEntry("FillingImageStyle", ui.cbFillingImageStyle->currentIndex()); group.writeEntry("FillingBrushStyle", ui.cbFillingBrushStyle->currentIndex()); group.writeEntry("FillingFileName", ui.leFillingFileName->text()); group.writeEntry("FillingFirstColor", ui.kcbFillingFirstColor->color()); group.writeEntry("FillingSecondColor", ui.kcbFillingSecondColor->color()); group.writeEntry("FillingOpacity", ui.sbFillingOpacity->value()/100.0); //Error bars group.writeEntry("XErrorType", ui.cbXErrorType->currentIndex()); group.writeEntry("YErrorType", ui.cbYErrorType->currentIndex()); group.writeEntry("ErrorBarsType", ui.cbErrorBarsType->currentIndex()); group.writeEntry("ErrorBarsCapSize", Worksheet::convertToSceneUnits(ui.sbErrorBarsCapSize->value(),Worksheet::Point) ); group.writeEntry("ErrorBarsStyle", ui.cbErrorBarsStyle->currentIndex()); group.writeEntry("ErrorBarsColor", ui.kcbErrorBarsColor->color()); group.writeEntry("ErrorBarsWidth", Worksheet::convertToSceneUnits(ui.sbErrorBarsWidth->value(),Worksheet::Point) ); group.writeEntry("ErrorBarsOpacity", ui.sbErrorBarsOpacity->value()/100 ); config.sync(); } diff --git a/src/kdefrontend/widgets/FITSHeaderEditWidget.cpp b/src/kdefrontend/widgets/FITSHeaderEditWidget.cpp index 44e0d7eab..292faff78 100644 --- a/src/kdefrontend/widgets/FITSHeaderEditWidget.cpp +++ b/src/kdefrontend/widgets/FITSHeaderEditWidget.cpp @@ -1,629 +1,629 @@ /*************************************************************************** File : FITSHeaderEditWidget.cpp Project : LabPlot Description : Widget for listing/editing FITS header keywords -------------------------------------------------------------------- Copyright : (C) 2016-2017 by Fabian Kristof (fkristofszabolcs@gmail.com) ***************************************************************************/ /*************************************************************************** * * * 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 "FITSHeaderEditWidget.h" #include "ui_fitsheadereditwidget.h" #include "backend/datasources/filters/FITSFilter.h" #include "backend/lib/macros.h" #include "FITSHeaderEditNewKeywordDialog.h" #include "FITSHeaderEditAddUnitDialog.h" #include #include #include #include #include #include #include /*! \class FITSHeaderEditWidget * \brief Widget for listing/editing FITS header keywords * \since 2.4.0 * \ingroup kdefrontend/widgets */ FITSHeaderEditWidget::FITSHeaderEditWidget(QWidget* parent) : QWidget(parent), ui(new Ui::FITSHeaderEditWidget()), m_fitsFilter(new FITSFilter()), m_initializingTable(false) { ui->setupUi(this); initActions(); connectActions(); initContextMenus(); ui->bOpen->setIcon(QIcon::fromTheme("document-open")); ui->bAddKey->setIcon(QIcon::fromTheme("list-add")); ui->bAddKey->setEnabled(false); ui->bAddKey->setToolTip(i18n("Add new keyword")); ui->bRemoveKey->setIcon(QIcon::fromTheme("list-remove")); ui->bRemoveKey->setEnabled(false); ui->bRemoveKey->setToolTip(i18n("Remove selected keyword")); ui->bAddUnit->setIcon(QIcon::fromTheme("document-new")); ui->bAddUnit->setEnabled(false); ui->bAddUnit->setToolTip(i18n("Add unit to keyword")); ui->bClose->setIcon(QIcon::fromTheme("document-close")); ui->bClose->setEnabled(false); ui->bClose->setToolTip(i18n("Close file")); ui->twKeywordsTable->setColumnCount(3); ui->twExtensions->setSelectionMode(QAbstractItemView::SingleSelection); ui->twExtensions->headerItem()->setText(0, i18n("Content")); ui->twKeywordsTable->setHorizontalHeaderItem(0, new QTableWidgetItem(i18n("Key"))); ui->twKeywordsTable->setHorizontalHeaderItem(1, new QTableWidgetItem(i18n("Value"))); ui->twKeywordsTable->setHorizontalHeaderItem(2, new QTableWidgetItem(i18n("Comment"))); ui->twKeywordsTable->setAlternatingRowColors(true); ui->twKeywordsTable->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents); ui->twKeywordsTable->horizontalHeader()->setStretchLastSection(true); ui->twKeywordsTable->installEventFilter(this); ui->twExtensions->installEventFilter(this); setAttribute(Qt::WA_DeleteOnClose); connect(ui->bAddUnit, SIGNAL(clicked(bool)), m_action_addmodify_unit, SIGNAL(triggered(bool))); connect(ui->bClose, SIGNAL(clicked(bool)), this, SLOT(closeFile())); connect(ui->bOpen, SIGNAL(clicked()), this, SLOT(openFile())); connect(ui->bAddKey, SIGNAL(clicked()), this, SLOT(addKeyword())); connect(ui->bRemoveKey, SIGNAL(clicked()), this, SLOT(removeKeyword())); connect(ui->twKeywordsTable, SIGNAL(itemClicked(QTableWidgetItem*)), this, SLOT(enableButtonAddUnit())); connect(ui->twKeywordsTable, SIGNAL(itemChanged(QTableWidgetItem*)), this, SLOT(updateKeyword(QTableWidgetItem*))); connect(ui->twExtensions, SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, SLOT(fillTable(QTreeWidgetItem*,int))); connect(ui->twExtensions, SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, SLOT(enableButtonCloseFile(QTreeWidgetItem*,int))); } /*! * \brief Destructor */ FITSHeaderEditWidget::~FITSHeaderEditWidget() { delete m_fitsFilter; } /*! * \brief Fills the keywords tablewidget. * If the selected extension was not yet selected before, then the keywords are read from the file * and then the table is filled, otherwise the table is filled using the already existing keywords. */ void FITSHeaderEditWidget::fillTable() { m_initializingTable = true; if (!m_extensionDatas.contains(m_seletedExtension)) { m_extensionDatas[m_seletedExtension].keywords = m_fitsFilter->chduKeywords(m_seletedExtension); m_extensionDatas[m_seletedExtension].updates.updatedKeywords.reserve(m_extensionDatas[m_seletedExtension].keywords.size()); m_extensionDatas[m_seletedExtension].updates.updatedKeywords.resize(m_extensionDatas[m_seletedExtension].keywords.size()); m_fitsFilter->parseHeader(m_seletedExtension, ui->twKeywordsTable); } else { QList keywords = m_extensionDatas[m_seletedExtension].keywords; for (int i = 0; i < m_extensionDatas[m_seletedExtension].updates.updatedKeywords.size(); ++i) { FITSFilter::Keyword keyword = m_extensionDatas[m_seletedExtension].updates.updatedKeywords.at(i); if (!keyword.key.isEmpty()) keywords.operator [](i).key = keyword.key; if (!keyword.value.isEmpty()) keywords.operator [](i).value = keyword.value; if (!keyword.comment.isEmpty()) keywords.operator [](i).comment = keyword.comment; } for (const FITSFilter::Keyword& key : m_extensionDatas[m_seletedExtension].updates.newKeywords) keywords.append(key); m_fitsFilter->parseHeader(QString(), ui->twKeywordsTable, false, keywords); } m_initializingTable = false; } /*! * \brief Fills the tablewidget with the keywords of extension \a item * \param item the extension selected * \param col the column of the selected item */ void FITSHeaderEditWidget::fillTable(QTreeWidgetItem *item, int col) { WAIT_CURSOR; const QString& itemText = item->text(col); QString selectedExtension; int extType = 0; if (itemText.contains(QLatin1String("IMAGE #")) || itemText.contains(QLatin1String("ASCII_TBL #")) || itemText.contains(QLatin1String("BINARY_TBL #"))) extType = 1; else if (!itemText.compare(QLatin1String("Primary header"))) extType = 2; if (extType == 0) { if (item->parent() != 0) { if (item->parent()->parent() != 0) selectedExtension = item->parent()->parent()->text(0) + '[' + item->text(col) + ']'; } } else if (extType == 1) { if (item->parent() != 0) { if (item->parent()->parent() != 0) { bool ok; int hduNum = itemText.right(1).toInt(&ok); selectedExtension = item->parent()->parent()->text(0) + '[' + QString::number(hduNum-1) + ']'; } } } else { if (item->parent()->parent() != 0) selectedExtension = item->parent()->parent()->text(col); } if (!selectedExtension.isEmpty()) { if (!(m_seletedExtension == selectedExtension)) { m_seletedExtension = selectedExtension; fillTable(); } } RESET_CURSOR; } /*! * \brief Shows a dialog for opening a FITS file * If the returned file name is not empty (so a FITS file was selected) and it's not opened yet * then the file is parsed, so the treeview for the extensions is built and the table is filled. */ void FITSHeaderEditWidget::openFile() { KConfigGroup conf(KSharedConfig::openConfig(), "FITSHeaderEditWidget"); QString dir = conf.readEntry("LastDir", ""); QString fileName = QFileDialog::getOpenFileName(this, i18n("Open FITS file"), dir, - i18n("FITS files (*.fits)")); + i18n("FITS files (*.fits *.fit *.fts)")); if (fileName.isEmpty()) return; int pos = fileName.lastIndexOf(QDir::separator()); if (pos!=-1) { QString newDir = fileName.left(pos); if (newDir!=dir) conf.writeEntry("LastDir", newDir); } WAIT_CURSOR; QTreeWidgetItem* root = ui->twExtensions->invisibleRootItem(); const int childCount = root->childCount(); bool opened = false; for (int i = 0; i < childCount; ++i) { if(root->child(i)->text(0) == fileName) { opened = true; break; } } if (!opened) { for (QTreeWidgetItem* item : ui->twExtensions->selectedItems()) item->setSelected(false); m_fitsFilter->parseExtensions(fileName, ui->twExtensions); ui->twExtensions->resizeColumnToContents(0); if (ui->twExtensions->selectedItems().size() > 0) fillTable(ui->twExtensions->selectedItems().at(0), 0); ui->bAddKey->setEnabled(true); ui->bRemoveKey->setEnabled(true); ui->bAddUnit->setEnabled(true); ui->bClose->setEnabled(false); } else { KMessageBox::information(this, i18n("Cannot open file, file already opened."), i18n("File already opened")); } enableButtonAddUnit(); RESET_CURSOR; } /*! * \brief Triggered when clicking the Save button * Saves the modifications (new keywords, new keyword units, keyword modifications, * deleted keywords, deleted extensions) to the FITS files. * \return \c true if there was something saved, otherwise false */ bool FITSHeaderEditWidget::save() { bool saved = false; for (const QString& fileName : m_extensionDatas.keys()) { if (m_extensionDatas[fileName].updates.newKeywords.size() > 0) { m_fitsFilter->addNewKeyword(fileName,m_extensionDatas[fileName].updates.newKeywords); if (!saved) saved = true; } if (m_extensionDatas[fileName].updates.removedKeywords.size() > 0) { m_fitsFilter->deleteKeyword(fileName, m_extensionDatas[fileName].updates.removedKeywords); if (!saved) saved = true; } if (!saved) { for (const FITSFilter::Keyword& key : m_extensionDatas[fileName].updates.updatedKeywords) { if (!key.isEmpty()) { saved = true; break; } } } m_fitsFilter->updateKeywords(fileName, m_extensionDatas[fileName].keywords, m_extensionDatas[fileName].updates.updatedKeywords); m_fitsFilter->addKeywordUnit(fileName, m_extensionDatas[fileName].keywords); m_fitsFilter->addKeywordUnit(fileName, m_extensionDatas[fileName].updates.newKeywords); } if (m_removedExtensions.size() > 0) { m_fitsFilter->removeExtensions(m_removedExtensions); if (!saved) saved = true; } if (saved) { //to reset the window title emit changed(false); } return saved; } /*! * \brief Initializes the context menu's actions. */ void FITSHeaderEditWidget::initActions() { m_action_add_keyword = new QAction(QIcon::fromTheme("list-add"), i18n("Add new keyword"), this); m_action_remove_keyword = new QAction(QIcon::fromTheme("list-remove"), i18n("Remove keyword"), this); m_action_remove_extension = new QAction(i18n("Delete"), this); m_action_addmodify_unit = new QAction(i18n("Add unit"), this); } /*! * \brief Connects signals of the actions to the appropriate slots. */ void FITSHeaderEditWidget::connectActions() { connect(m_action_add_keyword, SIGNAL(triggered()), this, SLOT(addKeyword())); connect(m_action_remove_keyword, SIGNAL(triggered()), this, SLOT(removeKeyword())); connect(m_action_remove_extension, SIGNAL(triggered()), this, SLOT(removeExtension())); connect(m_action_addmodify_unit, SIGNAL(triggered()), this, SLOT(addModifyKeywordUnit())); } /*! * \brief Initializes the context menus. */ void FITSHeaderEditWidget::initContextMenus() { m_KeywordActionsMenu = new QMenu(this); m_KeywordActionsMenu->addAction(m_action_add_keyword); m_KeywordActionsMenu->addAction(m_action_remove_keyword); m_KeywordActionsMenu->addSeparator(); m_KeywordActionsMenu->addAction(m_action_addmodify_unit); m_ExtensionActionsMenu = new QMenu(this); m_ExtensionActionsMenu->addAction(m_action_remove_extension); } /*! * \brief Shows a FITSHeaderEditNewKeywordDialog and decides whether the new keyword provided in the dialog * can be added to the new keywords or not. Updates the tablewidget if it's needed. */ void FITSHeaderEditWidget::addKeyword() { FITSHeaderEditNewKeywordDialog* newKeywordDialog = new FITSHeaderEditNewKeywordDialog; m_initializingTable = true; if (newKeywordDialog->exec() == QDialog::Accepted) { FITSFilter::Keyword newKeyWord = newKeywordDialog->newKeyword(); QList currentKeywords = m_extensionDatas[m_seletedExtension].keywords; for(const FITSFilter::Keyword& keyword : currentKeywords) { if (keyword.operator==(newKeyWord)) { KMessageBox::information(this, i18n("Cannot add keyword, keyword already added"), i18n("Cannot add keyword")); return; } } for(const FITSFilter::Keyword& keyword : m_extensionDatas[m_seletedExtension].updates.newKeywords) { if (keyword.operator==(newKeyWord)) { KMessageBox::information(this, i18n("Cannot add keyword, keyword already added"), i18n("Cannot add keyword")); return; } } for(const QString& keyword : mandatoryKeywords()) { if (!keyword.compare(newKeyWord.key)) { KMessageBox::information(this, i18n("Cannot add mandatory keyword, they are already present"), i18n("Cannot add keyword")); return; } } /* - Column related keyword (TFIELDS, TTYPEn,TFORMn, etc.) in an image - SIMPLE, EXTEND, or BLOCKED keyword in any extension - BSCALE, BZERO, BUNIT, BLANK, DATAMAX, DATAMIN keywords in a table - Keyword name contains illegal character */ m_extensionDatas[m_seletedExtension].updates.newKeywords.append(newKeyWord); const int lastRow = ui->twKeywordsTable->rowCount(); ui->twKeywordsTable->setRowCount(lastRow + 1); QTableWidgetItem* newKeyWordItem = new QTableWidgetItem(newKeyWord.key); newKeyWordItem->setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled); ui->twKeywordsTable->setItem(lastRow, 0, newKeyWordItem); newKeyWordItem = new QTableWidgetItem(newKeyWord.value); newKeyWordItem->setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled); ui->twKeywordsTable->setItem(lastRow, 1, newKeyWordItem); newKeyWordItem = new QTableWidgetItem(newKeyWord.comment); newKeyWordItem->setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled); ui->twKeywordsTable->setItem(lastRow, 2, newKeyWordItem); emit changed(true); } m_initializingTable = false; delete newKeywordDialog; } /*! * \brief Shows a messagebox whether we want to remove the keyword or not. * Mandatory keywords cannot be deleted. */ void FITSHeaderEditWidget::removeKeyword() { const int row = ui->twKeywordsTable->currentRow(); if (row == -1) return; QString key = ui->twKeywordsTable->item(row, 0)->text(); const int rc = KMessageBox::questionYesNo(this, i18n("Are you sure you want to delete the keyword '%1'?").arg(key), i18n("Confirm deletion")); if (rc == KMessageBox::Yes) { bool remove = true; for(const QString& k : mandatoryKeywords()) { if (!k.compare(key)) { remove = false; break; } } if (remove) { FITSFilter::Keyword toRemove = FITSFilter::Keyword(key, ui->twKeywordsTable->item(row, 1)->text(), ui->twKeywordsTable->item(row, 2)->text()); ui->twKeywordsTable->removeRow(row); m_extensionDatas[m_seletedExtension].keywords.removeAt(row); m_extensionDatas[m_seletedExtension].updates.removedKeywords.append(toRemove); emit changed(true); } else KMessageBox::information(this, i18n("Cannot remove mandatory keyword."), i18n("Removing keyword")); } enableButtonAddUnit(); } /*! * \brief Trigggered when an item was updated by the user in the tablewidget * \param item the item which was updated */ void FITSHeaderEditWidget::updateKeyword(QTableWidgetItem *item) { if (!m_initializingTable) { const int row = item->row(); int idx; bool fromNewKeyword = false; if (row > m_extensionDatas[m_seletedExtension].keywords.size()-1) { idx = row - m_extensionDatas[m_seletedExtension].keywords.size(); fromNewKeyword = true; } else idx = row; if (item->column() == 0) { if (!fromNewKeyword) { m_extensionDatas[m_seletedExtension].updates.updatedKeywords.operator [](idx).key = item->text(); m_extensionDatas[m_seletedExtension].keywords.operator [](idx).updates.keyUpdated = true; } else { m_extensionDatas[m_seletedExtension].updates.newKeywords.operator [](idx).key = item->text(); m_extensionDatas[m_seletedExtension].updates.newKeywords.operator [](idx).updates.keyUpdated = true; } } else if (item->column() == 1) { if (!fromNewKeyword) { m_extensionDatas[m_seletedExtension].updates.updatedKeywords.operator [](idx).value = item->text(); m_extensionDatas[m_seletedExtension].keywords.operator [](idx).updates.valueUpdated = true; } else { m_extensionDatas[m_seletedExtension].updates.newKeywords.operator [](idx).value = item->text(); m_extensionDatas[m_seletedExtension].updates.newKeywords.operator [](idx).updates.valueUpdated = true; } } else { if (!fromNewKeyword) { m_extensionDatas[m_seletedExtension].updates.updatedKeywords.operator [](idx).comment = item->text(); m_extensionDatas[m_seletedExtension].keywords.operator [](idx).updates.commentUpdated = true; } else { m_extensionDatas[m_seletedExtension].updates.newKeywords.operator [](idx).comment = item->text(); m_extensionDatas[m_seletedExtension].updates.newKeywords.operator [](idx).updates.commentUpdated = true; } } emit changed(true); } } /*! * \brief Shows a FITSHeaderEditAddUnitDialog on the selected keyword (provides the keyword's unit to the * dialog if it had one) and if the dialog was accepted then the new keyword unit is set and the tablewidget * is updated (filled with the modifications). */ void FITSHeaderEditWidget::addModifyKeywordUnit() { FITSHeaderEditAddUnitDialog* addUnitDialog; const int selectedRow = ui->twKeywordsTable->currentRow(); int idx; bool fromNewKeyword = false; if (selectedRow > m_extensionDatas[m_seletedExtension].keywords.size()-1) { idx = selectedRow - m_extensionDatas[m_seletedExtension].keywords.size(); fromNewKeyword = true; } else idx = selectedRow; QString unit; if (fromNewKeyword) { if (!m_extensionDatas[m_seletedExtension].updates.newKeywords.at(idx).unit.isEmpty()) unit = m_extensionDatas[m_seletedExtension].updates.newKeywords.at(idx).unit; } else { if (!m_extensionDatas[m_seletedExtension].keywords.at(idx).unit.isEmpty()) unit = m_extensionDatas[m_seletedExtension].keywords.at(idx).unit; } addUnitDialog = new FITSHeaderEditAddUnitDialog(unit); if (addUnitDialog->exec() == QDialog::Accepted) { if (fromNewKeyword) { m_extensionDatas[m_seletedExtension].updates.newKeywords.operator [](idx).unit = addUnitDialog->unit(); if (!m_extensionDatas[m_seletedExtension].updates.newKeywords.at(idx).unit.isEmpty()) { m_extensionDatas[m_seletedExtension].updates.newKeywords.operator [](idx).updates.unitUpdated = true;; } } else { m_extensionDatas[m_seletedExtension].keywords.operator [](idx).unit = addUnitDialog->unit(); if (!m_extensionDatas[m_seletedExtension].keywords.at(idx).unit.isEmpty()) m_extensionDatas[m_seletedExtension].keywords.operator [](idx).updates.unitUpdated = true; } emit changed(true); fillTable(); } delete addUnitDialog; } /*! * \brief Removes the selected extension from the extensions treeview * If the last extension is removed from the tree, then the extension and the file will be removed too. */ void FITSHeaderEditWidget::removeExtension() { QTreeWidgetItem* current = ui->twExtensions->currentItem(); QTreeWidgetItem* newCurrent = ui->twExtensions->itemBelow(current); if (current->parent()) { if (current->parent()->childCount() < 2) delete current->parent(); else delete current; } const QStringList keys = m_extensionDatas.keys(); const int selectedidx = keys.indexOf(m_seletedExtension); if (selectedidx > 0) { const QString& ext = m_seletedExtension; m_extensionDatas.remove(ext); m_removedExtensions.append(ext); m_seletedExtension = keys.at(selectedidx-1); fillTable(); } ui->twExtensions->setCurrentItem(newCurrent); emit changed(true); } /*! * \brief Returns a list of mandatory keywords according to the currently selected extension. * If the currently selected extension is an image then it returns the mandatory keywords of an image, * otherwise the mandatory keywords of a table * \return a list of mandatory keywords */ QList FITSHeaderEditWidget::mandatoryKeywords() const { QList mandatoryKeywords; const QTreeWidgetItem* currentItem = ui->twExtensions->currentItem(); if (currentItem->parent()->text(0).compare(QLatin1String("Images"))) mandatoryKeywords = FITSFilter::mandatoryImageExtensionKeywords(); else mandatoryKeywords = FITSFilter::mandatoryTableExtensionKeywords(); return mandatoryKeywords; } /*! * \brief Manipulates the contextmenu event of the widget * \param watched the object on which the event occurred * \param event the event watched * \return */ bool FITSHeaderEditWidget::eventFilter(QObject* watched, QEvent* event) { if (event->type() == QEvent::ContextMenu) { QContextMenuEvent *cm_event = static_cast(event); const QPoint& global_pos = cm_event->globalPos(); if (watched == ui->twKeywordsTable) { if (ui->twExtensions->selectedItems().size() != 0) m_KeywordActionsMenu->exec(global_pos); } else if (watched == ui->twExtensions) { if (ui->twExtensions->selectedItems().size() != 0) { QTreeWidgetItem* current = ui->twExtensions->currentItem(); int col = ui->twExtensions->currentColumn(); if (current->parent()) { if ((current->text(col) != QLatin1String("Images")) && (current->text(col) != QLatin1String("Tables"))) m_ExtensionActionsMenu->exec(global_pos); } } } else return QWidget::eventFilter(watched, event); return true; } else return QWidget::eventFilter(watched, event); } void FITSHeaderEditWidget::closeFile() { if (ui->twExtensions->currentItem()) { QTreeWidgetItem* current = ui->twExtensions->currentItem(); int idxOfCurrentAsTopLevel = -1; for (int i = 0; i < ui->twExtensions->topLevelItemCount(); ++i) { if (current == ui->twExtensions->topLevelItem(i)) { idxOfCurrentAsTopLevel = i; break; } } QTreeWidgetItem* newCurrent = (QTreeWidgetItem*)0; if (idxOfCurrentAsTopLevel == 0) { if (ui->twExtensions->topLevelItemCount() == 1) { //last file closed, deactivate action buttons, clear keywords table ui->twKeywordsTable->setRowCount(0); ui->bClose->setEnabled(false); ui->bAddUnit->setEnabled(false); ui->bAddKey->setEnabled(false); ui->bRemoveKey->setEnabled(false); } else newCurrent = ui->twExtensions->topLevelItem(idxOfCurrentAsTopLevel + 1); } else newCurrent = ui->twExtensions->topLevelItem(idxOfCurrentAsTopLevel - 1); if (newCurrent) { m_seletedExtension = newCurrent->text(0); fillTable(); } for(const QString& key : m_extensionDatas.keys()) { if (key.startsWith(current->text(0))) m_extensionDatas.remove(key); } delete current; enableButtonAddUnit(); emit changed(true); } } void FITSHeaderEditWidget::enableButtonAddUnit() { if (ui->twKeywordsTable->currentItem() != nullptr) ui->bAddUnit->setEnabled(true); else ui->bAddUnit->setEnabled(false); } void FITSHeaderEditWidget::enableButtonCloseFile(QTreeWidgetItem* item,int col) { Q_UNUSED(col) ui->bClose->setEnabled(item->parent() ? false : true); } diff --git a/src/kdefrontend/worksheet/ExportWorksheetDialog.cpp b/src/kdefrontend/worksheet/ExportWorksheetDialog.cpp index e16116032..d26f97034 100644 --- a/src/kdefrontend/worksheet/ExportWorksheetDialog.cpp +++ b/src/kdefrontend/worksheet/ExportWorksheetDialog.cpp @@ -1,253 +1,271 @@ /*************************************************************************** File : ExportWorksheetDialog.cpp Project : LabPlot Description : export worksheet dialog -------------------------------------------------------------------- Copyright : (C) 2011-2016 by 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 "ExportWorksheetDialog.h" #include "ui_exportworksheetwidget.h" #include #include #include #include +#include #include #include #include #include #include /*! \class ExportWorksheetDialog \brief Dialog for exporting a worksheet to a file. \ingroup kdefrontend */ ExportWorksheetDialog::ExportWorksheetDialog(QWidget* parent) : QDialog(parent), - ui(new Ui::ExportWorksheetWidget()) { + ui(new Ui::ExportWorksheetWidget()), m_showOptions(true) { + ui->setupUi(this); QDialogButtonBox* btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); m_showOptionsButton = new QPushButton; connect(btnBox, SIGNAL(clicked(QAbstractButton*)), this, SLOT(slotButtonClicked(QAbstractButton*))); btnBox->addButton(m_showOptionsButton, QDialogButtonBox::ActionRole); ui->verticalLayout->addWidget(btnBox); m_okButton = btnBox->button(QDialogButtonBox::Ok); m_cancelButton = btnBox->button(QDialogButtonBox::Cancel); QCompleter* completer = new QCompleter(this); completer->setModel(new QDirModel); ui->leFileName->setCompleter(completer); ui->bOpen->setIcon(QIcon::fromTheme("document-open")); - ui->cbFormat->addItem(QIcon::fromTheme("application-pdf"), "Portable data format (PDF)"); + ui->cbFormat->addItem(QIcon::fromTheme("application-pdf"), "Portable Data Format (PDF)"); ui->cbFormat->addItem(QIcon::fromTheme("image-svg+xml"), "Scalable Vector Graphics (SVG)"); ui->cbFormat->insertSeparator(3); ui->cbFormat->addItem(QIcon::fromTheme("image-x-generic"), "Portable Network Graphics (PNG)"); ui->cbExportArea->addItem(i18n("Object's bounding box")); ui->cbExportArea->addItem(i18n("Current selection")); ui->cbExportArea->addItem(i18n("Complete worksheet")); ui->cbResolution->addItem(QString::number(QApplication::desktop()->physicalDpiX()) + " (" + i18n("desktop") + ')'); ui->cbResolution->addItem("100"); ui->cbResolution->addItem("150"); ui->cbResolution->addItem("200"); ui->cbResolution->addItem("300"); ui->cbResolution->addItem("600"); ui->cbResolution->setValidator(new QIntValidator(ui->cbResolution)); + ui->leFileName->setFocus(); + connect( ui->cbFormat, SIGNAL(currentIndexChanged(int)), SLOT(formatChanged(int)) ); connect( ui->bOpen, SIGNAL(clicked()), this, SLOT (selectFile()) ); connect( ui->leFileName, SIGNAL(textChanged(QString)), this, SLOT(fileNameChanged(QString)) ); connect(m_showOptionsButton,SIGNAL(clicked(bool)), this, SLOT(toggleOptions())); setWindowTitle(i18n("Export worksheet")); setWindowIcon(QIcon::fromTheme("document-export-database")); + QTimer::singleShot(0, this, &ExportWorksheetDialog::loadSettings); +} + +void ExportWorksheetDialog::loadSettings() { //restore saved setting KConfigGroup conf(KSharedConfig::openConfig(), "ExportWorksheetDialog"); + + KWindowConfig::restoreWindowSize(windowHandle(), conf); + ui->cbFormat->setCurrentIndex(conf.readEntry("Format", 0)); ui->cbExportArea->setCurrentIndex(conf.readEntry("Area", 0)); ui->chkExportBackground->setChecked(conf.readEntry("Background", true)); ui->cbResolution->setCurrentIndex(conf.readEntry("Resolution", 0)); - m_showOptions = conf.readEntry("ShowOptions", false); - ui->gbOptions->setVisible(m_showOptions); + m_showOptions = conf.readEntry("ShowOptions", true); m_showOptions ? m_showOptionsButton->setText(i18n("Hide Options")) : - m_showOptionsButton->setText(i18n("Show Options")); - - KWindowConfig::restoreWindowSize(windowHandle(), conf); + m_showOptionsButton->setText(i18n("Show Options")); + ui->gbOptions->setVisible(m_showOptions); } ExportWorksheetDialog::~ExportWorksheetDialog() { //save current settings KConfigGroup conf(KSharedConfig::openConfig(), "ExportWorksheetDialog"); conf.writeEntry("Format", ui->cbFormat->currentIndex()); conf.writeEntry("Area", ui->cbExportArea->currentIndex()); conf.writeEntry("Background", ui->chkExportBackground->isChecked()); conf.writeEntry("Resolution", ui->cbResolution->currentIndex()); conf.writeEntry("ShowOptions", m_showOptions); KWindowConfig::saveWindowSize(windowHandle(), conf); } void ExportWorksheetDialog::setFileName(const QString& name) { KConfigGroup conf(KSharedConfig::openConfig(), "ExportWorksheetDialog"); QString dir = conf.readEntry("LastDir", ""); if (dir.isEmpty()) dir = QDir::homePath(); ui->leFileName->setText(dir + QDir::separator() + name); this->formatChanged(ui->cbFormat->currentIndex()); } QString ExportWorksheetDialog::path() const { return ui->leFileName->text(); } WorksheetView::ExportFormat ExportWorksheetDialog::exportFormat() const { int index = ui->cbFormat->currentIndex(); //we have a separator in the format combobox at the 3th position -> skip it if (index > 2) index--; return WorksheetView::ExportFormat(index); } WorksheetView::ExportArea ExportWorksheetDialog::exportArea() const { return WorksheetView::ExportArea(ui->cbExportArea->currentIndex()); } bool ExportWorksheetDialog::exportBackground() const { return ui->chkExportBackground->isChecked(); } int ExportWorksheetDialog::exportResolution() const { if (ui->cbResolution->currentIndex() == 0) return QApplication::desktop()->physicalDpiX(); else return ui->cbResolution->currentText().toInt(); } void ExportWorksheetDialog::slotButtonClicked(QAbstractButton* button) { if (button == m_okButton) okClicked(); else if (button == m_cancelButton) { reject(); } } //SLOTS void ExportWorksheetDialog::okClicked() { if ( QFile::exists(ui->leFileName->text()) ) { int r = KMessageBox::questionYesNo(this, i18n("The file already exists. Do you really want to overwrite it?"), i18n("Export")); if (r == KMessageBox::No) return; } KConfigGroup conf(KSharedConfig::openConfig(), "ExportWorksheetDialog"); conf.writeEntry("Format", ui->cbFormat->currentIndex()); conf.writeEntry("Area", ui->cbExportArea->currentIndex()); conf.writeEntry("Resolution", ui->cbResolution->currentIndex()); QString path = ui->leFileName->text(); if (!path.isEmpty()) { QString dir = conf.readEntry("LastDir", ""); ui->leFileName->setText(path); int pos = path.lastIndexOf(QDir::separator()); if (pos!=-1) { QString newDir = path.left(pos); if (newDir!=dir) conf.writeEntry("LastDir", newDir); } } accept(); } /*! Shows/hides the GroupBox with export options in this dialog. */ void ExportWorksheetDialog::toggleOptions() { m_showOptions = !m_showOptions; ui->gbOptions->setVisible(m_showOptions); m_showOptions ? m_showOptionsButton->setText(i18n("Hide Options")) : m_showOptionsButton->setText(i18n("Show Options")); //resize the dialog resize(layout()->minimumSize()); layout()->activate(); resize( QSize(this->width(),0).expandedTo(minimumSize()) ); } /*! opens a file dialog and lets the user select the file. */ void ExportWorksheetDialog::selectFile() { KConfigGroup conf(KSharedConfig::openConfig(), "ExportWorksheetDialog"); const QString dir = conf.readEntry("LastDir", ""); - const QString path = QFileDialog::getOpenFileName(this, i18n("Export to file"), dir); + + QString format; + if (ui->cbFormat->currentIndex() == 0) + format = i18n("Portable Data Format (PDF) (*.pdf *.PDF)"); + else if (ui->cbFormat->currentIndex() == 1) + format = i18n("Scalable Vector Graphics (SVG) (*.svg *.SVG)"); + else + format = i18n("Portable Network Graphics (PNG) (*.png *.PNG)"); + + const QString path = QFileDialog::getOpenFileName(this, i18n("Export to file"), dir, format); if (!path.isEmpty()) { ui->leFileName->setText(path); int pos = path.lastIndexOf(QDir::separator()); if (pos!=-1) { const QString newDir = path.left(pos); if (newDir != dir) conf.writeEntry("LastDir", newDir); } } } /*! called when the output format was changed. Adjusts the extension for the specified file. */ void ExportWorksheetDialog::formatChanged(int index) { - //we have a separator in the format combobox at the 4th posiiton -> skip it - if (index > 3) + //we have a separator in the format combobox at the 3rd posiiton -> skip it + if (index > 2) index --; QStringList extensions; - extensions<<".pdf"<<".eps"<<".svg"<<".png"; + extensions << ".pdf" << ".svg" << ".png"; QString path = ui->leFileName->text(); int i = path.indexOf("."); if (i == -1) path = path + extensions.at(index); else path = path.left(i) + extensions.at(index); ui->leFileName->setText(path); // show resolution option for png format ui->lResolution->setVisible(index == 3); ui->cbResolution->setVisible(index == 3); } void ExportWorksheetDialog::fileNameChanged(const QString& name) { m_okButton->setEnabled(!name.simplified().isEmpty()); } diff --git a/src/kdefrontend/worksheet/ExportWorksheetDialog.h b/src/kdefrontend/worksheet/ExportWorksheetDialog.h index 5c94a2d9c..17bc0cb3c 100644 --- a/src/kdefrontend/worksheet/ExportWorksheetDialog.h +++ b/src/kdefrontend/worksheet/ExportWorksheetDialog.h @@ -1,72 +1,73 @@ /*************************************************************************** File : ExportWorksheetDialog.h Project : LabPlot Description : export worksheet dialog -------------------------------------------------------------------- Copyright : (C) 2011-2016 by 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 * * * ***************************************************************************/ #ifndef EXPORTWORKSHEETDIALOG_H #define EXPORTWORKSHEETDIALOG_H #include #include "commonfrontend/worksheet/WorksheetView.h" namespace Ui { class ExportWorksheetWidget; } class QPushButton; class QAbstractButton; class ExportWorksheetDialog : public QDialog { Q_OBJECT public: explicit ExportWorksheetDialog(QWidget*); virtual ~ExportWorksheetDialog(); QString path() const; void setFileName(const QString&); WorksheetView::ExportFormat exportFormat() const; WorksheetView::ExportArea exportArea() const; bool exportBackground() const; int exportResolution() const; private: Ui::ExportWorksheetWidget* ui; bool m_showOptions; QPushButton* m_showOptionsButton; QPushButton* m_okButton; QPushButton* m_cancelButton; private slots: void slotButtonClicked(QAbstractButton *); void okClicked(); void toggleOptions(); void selectFile(); void formatChanged(int); void fileNameChanged(const QString&); + void loadSettings(); }; #endif