diff --git a/src/Mod/Spreadsheet/App/Sheet.cpp b/src/Mod/Spreadsheet/App/Sheet.cpp index a0a1f6916d..3442e5a9b7 100644 --- a/src/Mod/Spreadsheet/App/Sheet.cpp +++ b/src/Mod/Spreadsheet/App/Sheet.cpp @@ -127,6 +127,46 @@ void Sheet::clearAll() observers.clear(); } +//validate import/export parameters +bool Sheet::getCharsFromPrefs(char &delim, char "e, char &escape, std::string &errMsg){ + bool isValid = true; + ParameterGrp::handle group = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Spreadsheet"); + QString delimiter = QString::fromStdString(group->GetASCII("ImportExportDelimiter","tab")); + QString quoteChar = QString::fromStdString(group->GetASCII("ImportExportQuoteCharacter","\"")); + QString escapeChar = QString::fromStdString(group->GetASCII("ImportExportEscapeCharacter","\\")); + + delim = delimiter.size() == 1 ? delimiter[0].toLatin1() : '\0'; + if (delimiter.compare(QLatin1String("tab"), Qt::CaseInsensitive) == 0 || delimiter.compare(QLatin1String("\\t"),Qt::CaseInsensitive) == 0){ + delim = '\t'; + } else if (delimiter.compare(QLatin1String("comma"), Qt::CaseInsensitive) == 0){ + delim = ','; + } else if (delimiter.compare(QLatin1String("semicolon"), Qt::CaseInsensitive) == 0){ + delim = ';'; + } + if(delim != '\0' && quoteChar.size() == 1 && escapeChar.size() == 1){ + quote = quoteChar[0].toLatin1(); + escape = escapeChar[0].toLatin1(); + } else { + isValid = false; + std::string importExport = errMsg; + std::stringstream errStream; + errStream << "Invalid spreadsheet Import/Export parameter.\n"; + if (delim == '\0') { + errStream << "Unrecognized delimiter: " << delimiter.toStdString() << " (recognized tokens: \\t, tab, semicolon, comma, or any single character)\n"; + } + if (quoteChar.size() != 1){ + errStream << "Invalid quote character: " << quoteChar.toStdString() << " (quote character must be one single character)\n"; + } + if (escapeChar.size() != 1){ + errStream << "Invalid escape character: " << escapeChar.toStdString() << " (escape character must be one single character)\n"; + } + errStream << importExport << " not done.\n"; + errMsg = errStream.str(); + } + return isValid; +} + + /** * Import a file into the spreadsheet object. * diff --git a/src/Mod/Spreadsheet/App/Sheet.h b/src/Mod/Spreadsheet/App/Sheet.h index 15b0327249..7b60256885 100644 --- a/src/Mod/Spreadsheet/App/Sheet.h +++ b/src/Mod/Spreadsheet/App/Sheet.h @@ -86,6 +86,8 @@ public: bool importFromFile(const std::string & filename, char delimiter = '\t', char quoteChar = '\0', char escapeChar = '\\'); + bool getCharsFromPrefs(char &delimiter, char "e, char &escape, std::string &errMsg); + bool exportToFile(const std::string & filename, char delimiter = '\t', char quoteChar = '\0', char escapeChar = '\\') const; bool mergeCells(const App::Range &range); diff --git a/src/Mod/Spreadsheet/Gui/AppSpreadsheetGui.cpp b/src/Mod/Spreadsheet/Gui/AppSpreadsheetGui.cpp index a8f0736864..8b276dbf5e 100644 --- a/src/Mod/Spreadsheet/Gui/AppSpreadsheetGui.cpp +++ b/src/Mod/Spreadsheet/Gui/AppSpreadsheetGui.cpp @@ -41,8 +41,10 @@ #include #include #include +#include #include #include +#include "DlgSettingsImp.h" #include "Workbench.h" #include "ViewProviderSpreadsheet.h" #include "SpreadsheetView.h" @@ -119,6 +121,9 @@ PyMOD_INIT_FUNC(SpreadsheetGui) SpreadsheetGui::Workbench::init(); SpreadsheetGui::SheetView::init(); + // register preference page + new Gui::PrefPageProducer ("Spreadsheet"); + // add resources and reloads the translators loadSpreadsheetResource(); diff --git a/src/Mod/Spreadsheet/Gui/CMakeLists.txt b/src/Mod/Spreadsheet/Gui/CMakeLists.txt index cfaf5cba91..fbfde0a87d 100644 --- a/src/Mod/Spreadsheet/Gui/CMakeLists.txt +++ b/src/Mod/Spreadsheet/Gui/CMakeLists.txt @@ -64,6 +64,9 @@ SET(SpreadsheetGui_SRCS ${SpreadsheetGui_XML_SRCS} AppSpreadsheetGui.cpp Command.cpp + DlgSettings.ui + DlgSettingsImp.cpp + DlgSettingsImp.h LineEdit.h LineEdit.cpp ViewProviderSpreadsheet.cpp @@ -93,6 +96,26 @@ SET(SpreadsheetGuiIcon_SVG Resources/icons/SpreadsheetWorkbench.svg ) +set(SpreadsheetGui_MOC_HDRS + DlgSettingsImp.h +) + +SOURCE_GROUP("Moc" FILES ${SpreadsheetGui_MOC_SRCS}) + +SET(Resource_SRCS + ${Resource_SRCS} + Resources/Spreadsheet.qrc +) + +set(SpreadsheetGui_UIC_SRCS + DlgSettings.ui +) + + +if (BUILD_QT5) + qt5_wrap_ui(SpreadsheetGui_UIC_HDRS ${SpreadsheetGui_UIC_SRCS}) +endif() + add_library(SpreadsheetGui SHARED ${SpreadsheetGui_SRCS} ${SpreadsheetGuiIcon_SVG}) target_link_libraries(SpreadsheetGui ${SpreadsheetGui_LIBS}) diff --git a/src/Mod/Spreadsheet/Gui/Command.cpp b/src/Mod/Spreadsheet/Gui/Command.cpp index 87d5cf4346..5e141262e9 100644 --- a/src/Mod/Spreadsheet/Gui/Command.cpp +++ b/src/Mod/Spreadsheet/Gui/Command.cpp @@ -197,9 +197,19 @@ void CmdSpreadsheetImport::activated(int iMsg) if (!fileName.isEmpty()) { std::string FeatName = getUniqueObjectName("Spreadsheet"); Sheet * sheet = freecad_dynamic_cast(App::GetApplication().getActiveDocument()->addObject("Spreadsheet::Sheet", FeatName.c_str())); + if (sheet){ + char delim, quote, escape; + std::string errMsg = "Import"; + bool isValid = sheet->getCharsFromPrefs(delim, quote, escape, errMsg); - sheet->importFromFile(Base::Tools::toStdString(fileName), '\t', '"', '\\'); - sheet->execute(); + if (isValid){ + sheet->importFromFile(fileName.toStdString(), delim, quote, escape); + sheet->execute(); + } else { + Base::Console().Error(errMsg.c_str()); + return; + } + } } } @@ -240,8 +250,20 @@ void CmdSpreadsheetExport::activated(int iMsg) QString(), formatList, &selectedFilter); - if (!fileName.isEmpty()) - sheet->exportToFile(Base::Tools::toStdString(fileName), '\t', '"', '\\'); + if (!fileName.isEmpty()){ + if (sheet){ + char delim, quote, escape; + std::string errMsg = "Export"; + bool isValid = sheet->getCharsFromPrefs(delim, quote, escape, errMsg); + + if (isValid){ + sheet->exportToFile(fileName.toStdString(), delim, quote, escape); + } else { + Base::Console().Error(errMsg.c_str()); + return; + } + } + } } } } diff --git a/src/Mod/Spreadsheet/Gui/DlgSettings.ui b/src/Mod/Spreadsheet/Gui/DlgSettings.ui new file mode 100644 index 0000000000..8d140c0b2c --- /dev/null +++ b/src/Mod/Spreadsheet/Gui/DlgSettings.ui @@ -0,0 +1,189 @@ + + + SpreadsheetGui::DlgSettings + + + + 0 + 0 + 555 + 413 + + + + Spreadsheet + + + + + 10 + 10 + 531 + 161 + + + + Import/Export Settings + + + + + 156 + 70 + 142 + 25 + + + + <html><head/><body><p>Character used to delimit strings, typically is single quote (') or double quote (&quot;). Must be a single character.</p></body></html> + + + + + + " + + + ImportExportQuoteCharacter + + + Mod/Spreadsheet + + + + + + 13 + 33 + 137 + 17 + + + + + 0 + 0 + + + + Delimiter Character: + + + + + + 156 + 113 + 142 + 25 + + + + <html><head/><body><p>Escape character, typically the backslash (\), used to indicate special unprintable characters, e.g. \t = tab. Must be a single character.</p></body></html> + + + \ + + + ImportExportEscapeCharacter + + + Mod/Spreadsheet + + + + + + 13 + 113 + 124 + 17 + + + + + 0 + 0 + + + + Escape Character: + + + + + + 156 + 33 + 142 + 25 + + + + <html><head/><body><p>Character to use as field delimiter. Default is tab, but also commonly used are commas (,) and semicolons (;). Select from the list or enter your own in the field. Must be a single character or the words <span style=" font-style:italic;">tab</span>, <span style=" font-style:italic;">comma</span>, or <span style=" font-style:italic;">semicolon</span>.</p></body></html> + + + true + + + tab + + + ImportExportDelimiter + + + Mod/Spreadsheet + + + + tab + + + + + ; + + + + + , + + + + + + + 13 + 70 + 117 + 17 + + + + + 0 + 0 + + + + Quote Character: + + + + + + + + Gui::PrefLineEdit + QLineEdit +
Gui/PrefWidgets.h
+
+ + Gui::PrefComboBox + QComboBox +
Gui/PrefWidgets.h
+
+
+ + +
diff --git a/src/Mod/Spreadsheet/Gui/DlgSettingsImp.cpp b/src/Mod/Spreadsheet/Gui/DlgSettingsImp.cpp new file mode 100644 index 0000000000..8311835c98 --- /dev/null +++ b/src/Mod/Spreadsheet/Gui/DlgSettingsImp.cpp @@ -0,0 +1,111 @@ +/*************************************************************************** + * Copyright (c) 2002 Jürgen Riegel * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library 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 Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" +#ifndef _PreComp_ +# include +#endif + +#include "DlgSettingsImp.h" +#include "ui_DlgSettings.h" +#include +#include +#include + +using namespace SpreadsheetGui; + +/* TRANSLATOR SpreadsheetGui::DlgSettingsImp */ + +DlgSettingsImp::DlgSettingsImp( QWidget* parent ) + : PreferencePage( parent ) + , ui(new Ui_DlgSettings) +{ + ui->setupUi(this); + +} + +/** + * Destroys the object and frees any allocated resources + */ +DlgSettingsImp::~DlgSettingsImp() +{ + // no need to delete child widgets, Qt does it all for us +} + +void DlgSettingsImp::saveSettings() +{ + + /** use whatever the user has entered here + * we'll check for validity during import/export + */ + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Spreadsheet"); + QString delimiter = ui->delimiterComboBox->currentText(); + hGrp->SetASCII("ImportExportDelimiter", delimiter.toStdString().c_str()); + ui->quoteCharLineEdit->onSave(); + ui->escapeCharLineEdit->onSave(); +} + +void DlgSettingsImp::loadSettings() +{ + /** items "tab", ";", and "," have already been added to the combo box in the .ui file + * we'll recognize a few tokens: comma, semicolon, tab, and \t + */ + + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Spreadsheet"); + QString delimiter = QString::fromStdString(hGrp->GetASCII("ImportExportDelimiter", "tab")); + int idx = ui->delimiterComboBox->findText(delimiter, Qt::MatchFixedString); + if(idx != -1){ + ui->delimiterComboBox->setCurrentIndex(idx); + } else if(delimiter.compare(QLatin1String("\\t"), Qt::CaseInsensitive) == 0){ + idx = ui->delimiterComboBox->findText(QLatin1String("tab"), Qt::MatchFixedString); + ui->delimiterComboBox->setCurrentIndex(idx); + } else if(delimiter.compare(QLatin1String("semicolon"), Qt::CaseInsensitive) == 0){ + idx = ui->delimiterComboBox->findText(QLatin1String(";"), Qt::MatchFixedString); + ui->delimiterComboBox->setCurrentIndex(idx); + } else if(delimiter.compare(QLatin1String("comma"), Qt::CaseInsensitive) == 0){ + idx = ui->delimiterComboBox->findText(QLatin1String(","), Qt::MatchFixedString); + ui->delimiterComboBox->setCurrentIndex(idx); + } else { + ui->delimiterComboBox->addItem(delimiter); + idx = ui->delimiterComboBox->findText(delimiter, Qt::MatchFixedString); + ui->delimiterComboBox->setCurrentIndex(idx); + } + + ui->quoteCharLineEdit->onRestore(); + ui->escapeCharLineEdit->onRestore(); +} + +/** + * Sets the strings of the subwidgets using the current language. + */ +void DlgSettingsImp::changeEvent(QEvent *e) +{ + if (e->type() == QEvent::LanguageChange) { + ui->retranslateUi(this); + } + else { + QWidget::changeEvent(e); + } +} + +#include "moc_DlgSettingsImp.cpp" diff --git a/src/Mod/Spreadsheet/Gui/DlgSettingsImp.h b/src/Mod/Spreadsheet/Gui/DlgSettingsImp.h new file mode 100644 index 0000000000..66f395696d --- /dev/null +++ b/src/Mod/Spreadsheet/Gui/DlgSettingsImp.h @@ -0,0 +1,57 @@ +/*************************************************************************** + * Copyright (c) 2021 Mark Ganson * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library 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 Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#ifndef SPREADSHEETGUI_DLGSETTINGSIMP_H +#define SPREADSHEETGUI_DLGSETTINGSIMP_H + +#include +#include + +namespace SpreadsheetGui { +class Ui_DlgSettings; + +/** + * The DlgSettingsImp class implements a preference page to change settings + * for the Spreadsheet workbench. + * /author TheMarkster, based on work by Jürgen Riegel + */ +class DlgSettingsImp : public Gui::Dialog::PreferencePage +{ + Q_OBJECT + +public: + DlgSettingsImp( QWidget* parent = 0 ); + ~DlgSettingsImp(); + +protected: + void saveSettings(); + void loadSettings(); + void changeEvent(QEvent *e); + +private: + std::unique_ptr ui; +}; + +} // namespace SpreadsheetGui + +#endif // SPREADSHEETGUI_DLGSETTINGSIMP_H diff --git a/src/Mod/Spreadsheet/Gui/Resources/Spreadsheet.qrc b/src/Mod/Spreadsheet/Gui/Resources/Spreadsheet.qrc index 01ec7eaf4f..9d6a72b8d1 100644 --- a/src/Mod/Spreadsheet/Gui/Resources/Spreadsheet.qrc +++ b/src/Mod/Spreadsheet/Gui/Resources/Spreadsheet.qrc @@ -1,5 +1,6 @@ + icons/preferences-spreadsheet.svg icons/Spreadsheet.svg icons/SpreadsheetController.svg icons/SpreadsheetImport.svg diff --git a/src/Mod/Spreadsheet/Gui/Resources/icons/preferences-spreadsheet.svg b/src/Mod/Spreadsheet/Gui/Resources/icons/preferences-spreadsheet.svg new file mode 100644 index 0000000000..f15eab6536 --- /dev/null +++ b/src/Mod/Spreadsheet/Gui/Resources/icons/preferences-spreadsheet.svg @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + [Eivind Kvedalen] + + + Spreadsheet + 2013-09-29 + http://www.freecadweb.org/wiki/index.php?title=Artwork + + + FreeCAD + + + FreeCAD/src/Mod/Spreadsheet/Gui/Resources/icons/Spreadsheet.svg + + + FreeCAD LGPL2+ + + + https://www.gnu.org/copyleft/lesser.html + + + [agryson] Alexander Gryson + + + + + + + + + + + + + +