aboutsummaryrefslogtreecommitdiffstats
path: root/Plugins/CsvImport
diff options
context:
space:
mode:
authorLibravatarUnit 193 <unit193@ubuntu.com>2014-12-06 17:33:25 -0500
committerLibravatarUnit 193 <unit193@ubuntu.com>2014-12-06 17:33:25 -0500
commit7167ce41b61d2ba2cdb526777a4233eb84a3b66a (patch)
treea35c14143716e1f2c98f808c81f89426045a946f /Plugins/CsvImport
Imported Upstream version 2.99.6upstream/2.99.6
Diffstat (limited to 'Plugins/CsvImport')
-rw-r--r--Plugins/CsvImport/CsvImport.pro28
-rw-r--r--Plugins/CsvImport/CsvImportOptions.ui103
-rw-r--r--Plugins/CsvImport/csvimport.cpp206
-rw-r--r--Plugins/CsvImport/csvimport.h55
-rw-r--r--Plugins/CsvImport/csvimport.json7
-rw-r--r--Plugins/CsvImport/csvimport.qrc5
-rw-r--r--Plugins/CsvImport/csvimport_global.h12
7 files changed, 416 insertions, 0 deletions
diff --git a/Plugins/CsvImport/CsvImport.pro b/Plugins/CsvImport/CsvImport.pro
new file mode 100644
index 0000000..dfdb15b
--- /dev/null
+++ b/Plugins/CsvImport/CsvImport.pro
@@ -0,0 +1,28 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2014-05-17T20:38:58
+#
+#-------------------------------------------------
+
+include($$PWD/../../SQLiteStudio3/plugins.pri)
+
+QT -= gui
+
+TARGET = CsvImport
+TEMPLATE = lib
+
+DEFINES += CSVIMPORT_LIBRARY
+
+SOURCES += csvimport.cpp
+
+HEADERS += csvimport.h\
+ csvimport_global.h
+
+FORMS += \
+ CsvImportOptions.ui
+
+OTHER_FILES += \
+ csvimport.json
+
+RESOURCES += \
+ csvimport.qrc
diff --git a/Plugins/CsvImport/CsvImportOptions.ui b/Plugins/CsvImport/CsvImportOptions.ui
new file mode 100644
index 0000000..5a1c6ab
--- /dev/null
+++ b/Plugins/CsvImport/CsvImportOptions.ui
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>csvImportOptions</class>
+ <widget class="QWidget" name="csvImportOptions">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>333</width>
+ <height>90</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="1" column="1">
+ <widget class="QComboBox" name="separatorCombo">
+ <property name="cfg" stdset="0">
+ <string>CsvImport.Separator</string>
+ </property>
+ <item>
+ <property name="text">
+ <string>, (comma)</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>; (semicolon)</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>\t (tab)</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string> (whitespace)</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Custom:</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="0" column="0" colspan="3">
+ <widget class="QCheckBox" name="firstRowAsColumnsCheck">
+ <property name="cfg" stdset="0">
+ <string>CsvImport.FirstRowAsColumns</string>
+ </property>
+ <property name="text">
+ <string>First row represents column names</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="separatorLabel">
+ <property name="text">
+ <string>Field separator:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QLineEdit" name="separatorEdit">
+ <property name="maximumSize">
+ <size>
+ <width>30</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="cfg" stdset="0">
+ <string>CsvImport.CustomSeparator</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QCheckBox" name="nullCheck">
+ <property name="cfg" stdset="0">
+ <string>CsvImport.NullValues</string>
+ </property>
+ <property name="text">
+ <string>NULL values:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" colspan="2">
+ <widget class="QLineEdit" name="nullEdit">
+ <property name="toolTip">
+ <string>If your CSV data contains null values, define how are they represented in the CSV.</string>
+ </property>
+ <property name="cfg" stdset="0">
+ <string>CsvImport.NullValueString</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Plugins/CsvImport/csvimport.cpp b/Plugins/CsvImport/csvimport.cpp
new file mode 100644
index 0000000..cec81df
--- /dev/null
+++ b/Plugins/CsvImport/csvimport.cpp
@@ -0,0 +1,206 @@
+#include "csvimport.h"
+#include "services/importmanager.h"
+#include "sqlitestudio.h"
+#include "services/notifymanager.h"
+#include <QVariant>
+#include <QFile>
+#include <QTextStream>
+
+CsvImport::CsvImport()
+{
+}
+
+QString CsvImport::getDataSourceTypeName() const
+{
+ return "CSV";
+}
+
+ImportManager::StandardConfigFlags CsvImport::standardOptionsToEnable() const
+{
+ return ImportManager::CODEC|ImportManager::FILE_NAME;
+}
+
+bool CsvImport::beforeImport(const ImportManager::StandardImportConfig& config)
+{
+ defineCsvFormat();
+
+ file = new QFile(config.inputFileName);
+ if (!file->open(QFile::ReadOnly) || !file->isReadable())
+ {
+ notifyError(tr("Cannot read file %1").arg(config.inputFileName));
+ safe_delete(file);
+ return false;
+ }
+
+ stream = new QTextStream(file);
+ stream->setCodec(config.codec.toLatin1().data());
+
+ if (!extractColumns())
+ {
+ safe_delete(stream);
+ safe_delete(file);
+ return false;
+ }
+
+ return true;
+}
+
+void CsvImport::afterImport()
+{
+ safe_delete(stream);
+ safe_delete(file);
+}
+
+bool CsvImport::extractColumns()
+{
+ QString line = stream->readLine();
+ while (line.trimmed().isEmpty() && !stream->atEnd())
+ line = stream->readLine();
+
+ if (line.trimmed().isEmpty())
+ {
+ notifyError(tr("Could not find any data in the file %1.").arg(file->fileName()));
+ return false;
+ }
+
+ QStringList deserialized = CsvSerializer::deserialize(line.trimmed(), csvFormat).first();
+ if (cfg.CsvImport.FirstRowAsColumns.get())
+ {
+ columnNames = deserialized;
+ }
+ else
+ {
+ static const QString colTmp = QStringLiteral("column%1");
+ columnNames.clear();
+ for (int i = 1, total = deserialized.size(); i <= total; ++i)
+ columnNames << colTmp.arg(i);
+
+ stream->seek(0);
+ }
+
+ return true;
+}
+
+void CsvImport::defineCsvFormat()
+{
+ csvFormat = CsvFormat();
+ csvFormat.rowSeparator = '\n';
+
+ switch (cfg.CsvImport.Separator.get())
+ {
+ case 0:
+ csvFormat.columnSeparator = ',';
+ break;
+ case 1:
+ csvFormat.columnSeparator = ';';
+ break;
+ case 2:
+ csvFormat.columnSeparator = '\t';
+ break;
+ case 3:
+ csvFormat.columnSeparator = ' ';
+ break;
+ default:
+ csvFormat.columnSeparator = cfg.CsvImport.CustomSeparator.get();
+ break;
+ }
+}
+
+QList<ImportPlugin::ColumnDefinition> CsvImport::getColumns() const
+{
+ QList<ImportPlugin::ColumnDefinition> columnList;
+ for (const QString& colName : columnNames)
+ columnList << ImportPlugin::ColumnDefinition(colName, QString());
+
+ return columnList;
+}
+
+QList<QVariant> CsvImport::next()
+{
+ QString line = stream->readLine();
+ if (line.isNull())
+ return QList<QVariant>();
+
+ QList<QVariant> values;
+ QList<QStringList> deserialized = CsvSerializer::deserialize(line, csvFormat);
+ if (deserialized.size() > 0)
+ {
+ if (cfg.CsvImport.NullValues.get())
+ {
+ QString nullVal = cfg.CsvImport.NullValueString.get();
+ for (const QString& val : deserialized.first())
+ {
+ if (val == nullVal)
+ values << QVariant(QVariant::String);
+ else
+ values << val;
+ }
+ }
+ else
+ {
+ for (const QString& val : deserialized.first())
+ values << val;
+ }
+ }
+
+ return values;
+}
+
+CfgMain* CsvImport::getConfig()
+{
+ return &cfg;
+}
+
+QString CsvImport::getImportConfigFormName() const
+{
+ return "csvImportOptions";
+}
+
+bool CsvImport::validateOptions()
+{
+ bool isValid = true;
+ if (cfg.CsvImport.Separator.get() >= 4)
+ {
+ IMPORT_MANAGER->updateVisibilityAndEnabled(cfg.CsvImport.CustomSeparator, true, true);
+
+ bool valid = !cfg.CsvImport.CustomSeparator.get().isEmpty();
+ IMPORT_MANAGER->handleValidationFromPlugin(valid, cfg.CsvImport.CustomSeparator, tr("Enter the custom separator character."));
+ isValid &= valid;
+ }
+ else
+ {
+ IMPORT_MANAGER->updateVisibilityAndEnabled(cfg.CsvImport.CustomSeparator, true, false);
+ IMPORT_MANAGER->handleValidationFromPlugin(true, cfg.CsvImport.CustomSeparator);
+ }
+
+ if (cfg.CsvImport.NullValues.get())
+ {
+ IMPORT_MANAGER->updateVisibilityAndEnabled(cfg.CsvImport.NullValueString, true, true);
+
+ bool valid = !cfg.CsvImport.NullValueString.get().isEmpty();
+ IMPORT_MANAGER->handleValidationFromPlugin(valid, cfg.CsvImport.NullValueString, tr("Enter the value that will be interpreted as a NULL."));
+ isValid &= valid;
+ }
+ else
+ {
+ IMPORT_MANAGER->updateVisibilityAndEnabled(cfg.CsvImport.NullValueString, true, false);
+ IMPORT_MANAGER->handleValidationFromPlugin(true, cfg.CsvImport.NullValueString);
+ }
+ return isValid;
+}
+
+QString CsvImport::getFileFilter() const
+{
+ return tr("CSV files (*.csv);;Text files (*.txt);;All files (*)");
+}
+
+bool CsvImport::init()
+{
+ Q_INIT_RESOURCE(csvimport);
+ return GenericPlugin::init();
+}
+
+void CsvImport::deinit()
+{
+ Q_CLEANUP_RESOURCE(csvimport);
+}
diff --git a/Plugins/CsvImport/csvimport.h b/Plugins/CsvImport/csvimport.h
new file mode 100644
index 0000000..cec803c
--- /dev/null
+++ b/Plugins/CsvImport/csvimport.h
@@ -0,0 +1,55 @@
+#ifndef CSVIMPORT_H
+#define CSVIMPORT_H
+
+#include "csvimport_global.h"
+#include "plugins/importplugin.h"
+#include "plugins/genericplugin.h"
+#include "config_builder.h"
+#include "csvserializer.h"
+
+CFG_CATEGORIES(CsvImportConfig,
+ CFG_CATEGORY(CsvImport,
+ CFG_ENTRY(bool, FirstRowAsColumns, false)
+ CFG_ENTRY(int, Separator, 0)
+ CFG_ENTRY(QString, CustomSeparator, QString())
+ CFG_ENTRY(bool, NullValues, false)
+ CFG_ENTRY(QString, NullValueString, QString())
+ )
+)
+
+class QFile;
+class QTextStream;
+
+class CSVIMPORTSHARED_EXPORT CsvImport : public GenericPlugin, public ImportPlugin
+{
+ Q_OBJECT
+ SQLITESTUDIO_PLUGIN("csvimport.json")
+
+ public:
+ CsvImport();
+
+ QString getDataSourceTypeName() const;
+ ImportManager::StandardConfigFlags standardOptionsToEnable() const;
+ bool beforeImport(const ImportManager::StandardImportConfig& config);
+ void afterImport();
+ QList<ColumnDefinition> getColumns() const;
+ QList<QVariant> next();
+ CfgMain* getConfig();
+ QString getImportConfigFormName() const;
+ bool validateOptions();
+ QString getFileFilter() const;
+ bool init();
+ void deinit();
+
+ private:
+ bool extractColumns();
+ void defineCsvFormat();
+
+ QFile* file = nullptr;
+ QTextStream* stream = nullptr;
+ QStringList columnNames;
+ CsvFormat csvFormat;
+ CFG_LOCAL(CsvImportConfig, cfg)
+};
+
+#endif // CSVIMPORT_H
diff --git a/Plugins/CsvImport/csvimport.json b/Plugins/CsvImport/csvimport.json
new file mode 100644
index 0000000..016c539
--- /dev/null
+++ b/Plugins/CsvImport/csvimport.json
@@ -0,0 +1,7 @@
+{
+ "type": "ImportPlugin",
+ "title": "CSV import",
+ "description": "CSV format support for importing data",
+ "version": 10000,
+ "author": "SalSoft"
+}
diff --git a/Plugins/CsvImport/csvimport.qrc b/Plugins/CsvImport/csvimport.qrc
new file mode 100644
index 0000000..a071122
--- /dev/null
+++ b/Plugins/CsvImport/csvimport.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/forms">
+ <file>CsvImportOptions.ui</file>
+ </qresource>
+</RCC>
diff --git a/Plugins/CsvImport/csvimport_global.h b/Plugins/CsvImport/csvimport_global.h
new file mode 100644
index 0000000..cee5321
--- /dev/null
+++ b/Plugins/CsvImport/csvimport_global.h
@@ -0,0 +1,12 @@
+#ifndef CSVIMPORT_GLOBAL_H
+#define CSVIMPORT_GLOBAL_H
+
+#include <QtCore/qglobal.h>
+
+#if defined(CSVIMPORT_LIBRARY)
+# define CSVIMPORTSHARED_EXPORT Q_DECL_EXPORT
+#else
+# define CSVIMPORTSHARED_EXPORT Q_DECL_IMPORT
+#endif
+
+#endif // CSVIMPORT_GLOBAL_H