Git commit b71e8d46cc8ddfb7c25c57ce6b6dfcc181f250c0 by Alexander Semke. Committed on 12/12/2014 at 20:36. Pushed by asemke into branch 'master'.
Implemented spreadsheet export. M +2 -1 ChangeLog M +11 -1 doc/index.docbook M +2 -0 src/CMakeLists.txt M +35 -1 src/commonfrontend/spreadsheet/SpreadsheetView.cpp M +1 -0 src/commonfrontend/spreadsheet/SpreadsheetView.h M +17 -1 src/kdefrontend/MainWin.cpp A +204 -0 src/kdefrontend/spreadsheet/ExportSpreadsheetDialog.cpp [License: GPL (v2+)] A +59 -0 src/kdefrontend/spreadsheet/ExportSpreadsheetDialog.h [License: GPL (v2+)] A +128 -0 src/kdefrontend/ui/spreadsheet/exportspreadsheetwidget.ui http://commits.kde.org/labplot/b71e8d46cc8ddfb7c25c57ce6b6dfcc181f250c0 diff --git a/ChangeLog b/ChangeLog index 7bf3f44..61510e7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -13,6 +13,7 @@ New features: * Fill columns with uniform and non-uniform random numbers, several distributions are available. * Fill columns with function values * Allow custom resolutions for PNG-export + * Export of the spreadsheet to a text file. Bug fixes: * Don't crash when trying to create a plot in case no rc-file was installed. @@ -47,4 +48,4 @@ Brief summary of features and capabilities of LabPlot2 implemented in the first * legend for xy-plots * a lot of properties of the worksheet elements can be edited in a very easy way in the corresponding dock widgets * plots on the worksheet can be put into a horizontal, vertical or grid layouts - * export of worksheet (entire worksheet or current seleciton) to pdf, eps, png and svg \ No newline at end of file + * export of worksheet (entire worksheet or current seleciton) to pdf, eps, png and svg diff --git a/doc/index.docbook b/doc/index.docbook index 58d61ca..8e64501 100644 --- a/doc/index.docbook +++ b/doc/index.docbook @@ -223,7 +223,7 @@ Masked data is not plotted and is also excluded from data analysis functions lik <para> Any spreadsheet function can be reached via the context menu (&RMB; click). You can cut, copy and paste between spreadsheets, generate, normalize and sort data and finally make plots out of your data. -Of course you can also export the data in the spreadsheet. +Of course you can also <link linkend="exportdialog">export</link> the data in the spreadsheet to an external file. </para> <screenshot><mediaobject><imageobject> @@ -637,6 +637,16 @@ files. You can also specify the type of the data, the filter, the separating cha </para> </sect1> +<!-- TODO: + Describe the export of worksheet and spreadsheet. +--> +<sect1 id="exportdialog"> +<title>Export Dialog</title> +<para> + +</para> +</sect1> + </chapter> <!-- TODO: diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7b14de4..200c53d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -32,6 +32,7 @@ set(GUI_SOURCES ${KDEFRONTEND_DIR}/dockwidgets/XYEquationCurveDock.cpp ${KDEFRONTEND_DIR}/dockwidgets/WorksheetDock.cpp ${KDEFRONTEND_DIR}/spreadsheet/EquidistantValuesDialog.cpp + ${KDEFRONTEND_DIR}/spreadsheet/ExportSpreadsheetDialog.cpp ${KDEFRONTEND_DIR}/spreadsheet/FunctionValuesDialog.cpp ${KDEFRONTEND_DIR}/spreadsheet/RandomValuesDialog.cpp ${KDEFRONTEND_DIR}/spreadsheet/SortDialog.cpp @@ -68,6 +69,7 @@ set(UI_SOURCES ${KDEFRONTEND_DIR}/ui/dockwidgets/xyequationcurvedockgeneraltab.ui ${KDEFRONTEND_DIR}/ui/dockwidgets/worksheetdock.ui ${KDEFRONTEND_DIR}/ui/spreadsheet/equidistantvalueswidget.ui + ${KDEFRONTEND_DIR}/ui/spreadsheet/exportspreadsheetwidget.ui ${KDEFRONTEND_DIR}/ui/spreadsheet/functionvalueswidget.ui ${KDEFRONTEND_DIR}/ui/spreadsheet/randomvalueswidget.ui ${KDEFRONTEND_DIR}/ui/worksheet/exportworksheetwidget.ui diff --git a/src/commonfrontend/spreadsheet/SpreadsheetView.cpp b/src/commonfrontend/spreadsheet/SpreadsheetView.cpp index f641d0b..67c9da8 100644 --- a/src/commonfrontend/spreadsheet/SpreadsheetView.cpp +++ b/src/commonfrontend/spreadsheet/SpreadsheetView.cpp @@ -55,7 +55,8 @@ #include <QPainter> #include <QPrinter> #include <QToolBar> -#include <QInputDialog> +#include <QTextStream> +#include <QDebug> #ifdef ACTIVATE_SCIDAVIS_SPECIFIC_CODE #include "spreadsheetview_qactions.h" @@ -1631,3 +1632,36 @@ void SpreadsheetView::print(QPrinter* printer) const{ } } } + +void SpreadsheetView::exportToFile(const QString& path, const bool exportHeader, const QString& separator) const { + QFile file(path); + if (!file.open(QFile::WriteOnly | QFile::Truncate)) + return; + + QTextStream out(&file); + const int cols = m_spreadsheet->columnCount(); + + QString sep = separator; + sep = sep.replace(QString("TAB"), QString("\t"), Qt::CaseInsensitive); + sep = sep.replace(QString("SPACE"), QString(" "), Qt::CaseInsensitive); + + //export header (column names) + if (exportHeader) { + for (int j=0; j<cols; ++j) { + out << m_spreadsheet->column(j)->name(); + if (j!=cols-1) + out<<sep; + } + out << '\n'; + } + + //export values + for (int i=0; i<m_spreadsheet->rowCount(); ++i) { + for (int j=0; j<cols; ++j) { + out << m_spreadsheet->column(j)->asStringColumn()->textAt(i); + if (j!=cols-1) + out<<sep; + } + out << '\n'; + } +} diff --git a/src/commonfrontend/spreadsheet/SpreadsheetView.h b/src/commonfrontend/spreadsheet/SpreadsheetView.h index d032f2c..f82c292 100644 --- a/src/commonfrontend/spreadsheet/SpreadsheetView.h +++ b/src/commonfrontend/spreadsheet/SpreadsheetView.h @@ -74,6 +74,7 @@ class SpreadsheetView : public QWidget{ void setCellSelected(int row, int col, bool select = true); void setCellsSelected(int first_row, int first_col, int last_row, int last_col, bool select = true); void getCurrentCell(int * row, int * col); + void exportToFile(const QString&, const bool, const QString&) const; private: void init(); diff --git a/src/kdefrontend/MainWin.cpp b/src/kdefrontend/MainWin.cpp index 2cfabc9..a4e9b3c 100644 --- a/src/kdefrontend/MainWin.cpp +++ b/src/kdefrontend/MainWin.cpp @@ -45,6 +45,7 @@ #include "commonfrontend/worksheet/WorksheetView.h" #include "kdefrontend/worksheet/ExportWorksheetDialog.h" +#include "kdefrontend/spreadsheet/ExportSpreadsheetDialog.h" #include "kdefrontend/datasources/ImportFileDialog.h" #include "kdefrontend/dockwidgets/ProjectDock.h" #include "kdefrontend/HistoryDialog.h" @@ -1290,7 +1291,22 @@ void MainWin::exportDialog(){ RESET_CURSOR; } }else{//Spreadsheet - //TODO + Spreadsheet* s = this->activeSpreadsheet(); + if (!s) + return; + + ExportSpreadsheetDialog* dlg = new ExportSpreadsheetDialog(this); + dlg->setFileName(s->name()); + if (dlg->exec()==QDialog::Accepted){ + QString path = dlg->path(); + const bool exportHeader = dlg->exportHeader(); + QString separator = dlg->separator(); + + SpreadsheetView* view = qobject_cast<SpreadsheetView*>(s->view()); + WAIT_CURSOR; + view->exportToFile(path, exportHeader, separator); + RESET_CURSOR; + } } } diff --git a/src/kdefrontend/spreadsheet/ExportSpreadsheetDialog.cpp b/src/kdefrontend/spreadsheet/ExportSpreadsheetDialog.cpp new file mode 100644 index 0000000..030cad7 --- /dev/null +++ b/src/kdefrontend/spreadsheet/ExportSpreadsheetDialog.cpp @@ -0,0 +1,204 @@ +/*************************************************************************** + File : ExportSpreadsheetDialog.cpp + Project : LabPlot + Description : export spreadsheet dialog + -------------------------------------------------------------------- + Copyright : (C) 2014 by Alexander Semke (alexander.semke at 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 "ExportSpreadsheetDialog.h" + +#include <QFileDialog> +#include <KUrlCompletion> +#include <KMessageBox> +#include <KPushButton> +#include <QStringList> + +/*! + \class ExportSpreadsheetDialog + \brief Dialog for exporting a spreadsheet to a file. + + \ingroup kdefrontend +*/ + +ExportSpreadsheetDialog::ExportSpreadsheetDialog(QWidget* parent) : KDialog(parent) { + mainWidget = new QWidget(this); + ui.setupUi(mainWidget); + ui.gbOptions->hide(); + + KUrlCompletion *comp = new KUrlCompletion(); + ui.kleFileName->setCompletionObject(comp); + + ui.cbFormat->addItem("ASCII"); + ui.cbFormat->addItem("Binary"); + //TODO: implement later + ui.lFormat->hide(); + ui.cbFormat->hide(); + + ui.cbSeparator->addItem("TAB"); + ui.cbSeparator->addItem("SPACE"); + ui.cbSeparator->addItem(","); + ui.cbSeparator->addItem(";"); + ui.cbSeparator->addItem(":"); + ui.cbSeparator->addItem(",TAB"); + ui.cbSeparator->addItem(";TAB"); + ui.cbSeparator->addItem(":TAB"); + ui.cbSeparator->addItem(",SPACE"); + ui.cbSeparator->addItem(";SPACE"); + ui.cbSeparator->addItem(":SPACE"); + + ui.bOpen->setIcon( KIcon("document-open") ); + + setMainWidget( mainWidget ); + + setButtons( KDialog::Ok | KDialog::User1 | KDialog::Cancel ); + setButtonText(KDialog::User1,i18n("Options >>")); + + connect( ui.bOpen, SIGNAL(clicked()), this, SLOT (selectFile()) ); + connect( ui.kleFileName, SIGNAL(textChanged(QString)), this, SLOT(fileNameChanged(QString)) ); + connect(this,SIGNAL(user1Clicked()), this, SLOT(toggleOptions())); + + setCaption(i18n("Export spreadsheet")); + setWindowIcon(KIcon("document-export-database")); + + KConfigGroup conf(KSharedConfig::openConfig(), "ExportSpreadsheetDialog"); + ui.cbFormat->setCurrentIndex(conf.readEntry("Format", 0)); +// ui.chkExportHeader->setChecked(conf.readEntry("Header", "").toInt()); + ui.chkExportHeader->setChecked(conf.readEntry("Header", true)); + ui.cbSeparator->setCurrentItem(conf.readEntry("Separator", "")); + + resize( QSize(500,0).expandedTo(minimumSize()) ); +} + +void ExportSpreadsheetDialog::setFileName(const QString& name){ + KConfigGroup conf(KSharedConfig::openConfig(), "ExportSpreadsheetDialog"); + QString dir = conf.readEntry("LastDir", ""); + if (dir.isEmpty()) dir = QDir::homePath(); + ui.kleFileName->setText(dir + QDir::separator() + name); + this->formatChanged(ui.cbFormat->currentIndex()); +} + +QString ExportSpreadsheetDialog::path() const{ + return ui.kleFileName->text(); +} + +bool ExportSpreadsheetDialog::exportHeader() const { + return ui.chkExportHeader->isChecked(); +} + +const QString& ExportSpreadsheetDialog::separator() const { + return ui.cbSeparator->currentText(); +} + +void ExportSpreadsheetDialog::slotButtonClicked(int button) { + if (button == KDialog::Ok) + okClicked(); + else + KDialog::slotButtonClicked(button); +} + +//SLOTS +void ExportSpreadsheetDialog::okClicked(){ + if ( QFile::exists(ui.kleFileName->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(), "ExportSpreadsheetDialog"); + conf.writeEntry("Format", ui.cbFormat->currentIndex()); + conf.writeEntry("Header", ui.chkExportHeader->isChecked()); + conf.writeEntry("Separator", ui.cbSeparator->currentText()); + + QString path = ui.kleFileName->text(); + if (!path.isEmpty()) { + QString dir = conf.readEntry("LastDir", ""); + ui.kleFileName->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 ExportSpreadsheetDialog::toggleOptions(){ + if (ui.gbOptions->isVisible()){ + ui.gbOptions->hide(); + setButtonText(KDialog::User1,i18n("Options >>")); + }else{ + ui.gbOptions->show(); + setButtonText(KDialog::User1,i18n("Options <<")); + } + + //resize the dialog + mainWidget->resize(layout()->minimumSize()); + layout()->activate(); + resize( QSize(this->width(),0).expandedTo(minimumSize()) ); +} + +/*! + opens a file dialog and lets the user select the file. +*/ +void ExportSpreadsheetDialog::selectFile() { + KConfigGroup conf(KSharedConfig::openConfig(), "ExportSpreadsheetDialog"); + QString dir = conf.readEntry("LastDir", ""); + QString path = QFileDialog::getOpenFileName(this, i18n("Export to file"), dir); + if (!path.isEmpty()) { + ui.kleFileName->setText(path); + + int pos = path.lastIndexOf(QDir::separator()); + if (pos!=-1) { + 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 ExportSpreadsheetDialog::formatChanged(int index){ + QStringList extensions; + extensions<<".txt"<<".bin"; + QString path = ui.kleFileName->text(); + int i = path.indexOf("."); + if (i==-1) + path = path + extensions.at(index); + else + path=path.left(i) + extensions.at(index); + + ui.kleFileName->setText(path); +} + +void ExportSpreadsheetDialog::fileNameChanged(const QString& name) { + enableButtonOk( !name.simplified().isEmpty() ); +} diff --git a/src/kdefrontend/spreadsheet/ExportSpreadsheetDialog.h b/src/kdefrontend/spreadsheet/ExportSpreadsheetDialog.h new file mode 100644 index 0000000..2552e64 --- /dev/null +++ b/src/kdefrontend/spreadsheet/ExportSpreadsheetDialog.h @@ -0,0 +1,59 @@ +/*************************************************************************** + File : ExportSpreadsheetDialog.h + Project : LabPlot + Description : export spreadsheet dialog + -------------------------------------------------------------------- + Copyright : (C) 2014 by Alexander Semke (alexander.semke at 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 EXPORTSPREADSHEETDIALOG_H +#define EXPORTSPREADSHEETDIALOG_H + +#include <KDialog> +#include "ui_exportspreadsheetwidget.h" +#include "commonfrontend/spreadsheet/SpreadsheetView.h" + +class ExportSpreadsheetDialog: public KDialog{ + Q_OBJECT + + public: + explicit ExportSpreadsheetDialog(QWidget*); + QString path() const; + void setFileName(const QString&); + bool exportHeader() const; + const QString& separator() const; + + private: + QWidget* mainWidget; + Ui::ExportSpreadsheetWidget ui; + + private slots: + void slotButtonClicked(int); + void okClicked(); + void toggleOptions(); + void selectFile(); + void formatChanged(int); + void fileNameChanged(const QString&); +}; + +#endif diff --git a/src/kdefrontend/ui/spreadsheet/exportspreadsheetwidget.ui b/src/kdefrontend/ui/spreadsheet/exportspreadsheetwidget.ui new file mode 100644 index 0000000..94709ac --- /dev/null +++ b/src/kdefrontend/ui/spreadsheet/exportspreadsheetwidget.ui @@ -0,0 +1,128 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>ExportSpreadsheetWidget</class> + <widget class="QWidget" name="ExportSpreadsheetWidget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>370</width> + <height>201</height> + </rect> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QGroupBox" name="gbExport"> + <property name="title"> + <string>Export</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="lFormat"> + <property name="text"> + <string>Format</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="KComboBox" name="cbFormat"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="lFileName"> + <property name="text"> + <string>File name</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="KLineEdit" name="kleFileName"> + <property name="toolTip"> + <string>Specify the name of the file to import.</string> + </property> + <property name="showClearButton" stdset="0"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QPushButton" name="bOpen"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string> Select the file to import</string> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="gbOptions"> + <property name="title"> + <string>Options</string> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="0"> + <widget class="QLabel" name="lExportHeader"> + <property name="toolTip"> + <string>Check this option if the worksheet background should be exported.</string> + </property> + <property name="text"> + <string>Export header</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QCheckBox" name="chkExportHeader"> + <property name="toolTip"> + <string>Check this option if the worksheet background should be exported.</string> + </property> + <property name="text"> + <string/> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="lSeparator"> + <property name="text"> + <string>Separating character</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="KComboBox" name="cbSeparator"> + <property name="editable"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>KComboBox</class> + <extends>QComboBox</extends> + <header>kcombobox.h</header> + </customwidget> + <customwidget> + <class>KLineEdit</class> + <extends>QLineEdit</extends> + <header>klineedit.h</header> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui>