forked from sqlitebrowser/sqlitebrowser
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathExportCsvDialog.cpp
152 lines (137 loc) · 5.67 KB
/
ExportCsvDialog.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#include "ExportCsvDialog.h"
#include "ui_ExportCsvDialog.h"
#include "sqlitedb.h"
#include "PreferencesDialog.h"
#include "sqlitetablemodel.h"
#include <QFile>
#include <QTextStream>
#include <QMessageBox>
#include <QFileDialog>
#include <sqlite3.h>
ExportCsvDialog::ExportCsvDialog(DBBrowserDB* db, QWidget* parent, const QString& query, const QString& selection)
: QDialog(parent),
ui(new Ui::ExportCsvDialog),
pdb(db),
m_sQuery(query)
{
// Create UI
ui->setupUi(this);
showCustomCharEdits();
// If a SQL query was specified hide the table combo box. If not fill it with tables to export
if(query.isEmpty())
{
// Get list of tables to export
objectMap objects = pdb->getBrowsableObjects();
for(objectMap::ConstIterator i=objects.begin();i!=objects.end();++i)
ui->comboTable->addItem(QIcon(QString(":icons/%1").arg(i.value().gettype())), i.value().getname());
// Sort list of tables and select the table specified in the selection parameter or alternatively the first one
ui->comboTable->model()->sort(0);
if(selection.isEmpty())
ui->comboTable->setCurrentIndex(0);
else
ui->comboTable->setCurrentIndex(ui->comboTable->findText(selection));
} else {
// Hide table combo box
ui->labelTable->setVisible(false);
ui->comboTable->setVisible(false);
}
}
ExportCsvDialog::~ExportCsvDialog()
{
delete ui;
}
void ExportCsvDialog::accept()
{
// Get filename
QString fileName = QFileDialog::getSaveFileName(
this,
tr("Choose a filename to export data"),
PreferencesDialog::getSettingsValue("db", "defaultlocation").toString(),
tr("Text files(*.csv *.txt)"));
// Only if the user hasn't clicked the cancel button
if(fileName.size() > 0)
{
if(m_sQuery.isEmpty())
{
m_sQuery = QString("SELECT * from `%1`;").arg(ui->comboTable->currentText());
}
// Prepare the quote and separating characters
QString quoteChar = ui->comboQuoteCharacter->currentIndex() == ui->comboQuoteCharacter->count()-1
? ui->editCustomQuote->text() : ui->comboQuoteCharacter->currentText();
QString quotequoteChar = quoteChar + quoteChar;
QString sepChar;
if(ui->comboFieldSeparator->currentIndex() == ui->comboFieldSeparator->count()-1)
{
sepChar = ui->editCustomSeparator->text();
} else {
sepChar = ui->comboFieldSeparator->currentText();
if(sepChar == tr("Tab")) sepChar = "\t";
}
QString newlineChar = "\r\n";
// Open file
QFile file(fileName);
if(file.open(QIODevice::WriteOnly))
{
// Open text stream to the file
QTextStream stream(&file);
QByteArray utf8Query = m_sQuery.toUtf8();
sqlite3_stmt *stmt;
int status = sqlite3_prepare_v2(pdb->_db, utf8Query.data(), utf8Query.size(), &stmt, NULL);
if(SQLITE_OK == status)
{
if(ui->checkHeader->isChecked())
{
int columns = sqlite3_column_count(stmt);
for (int i = 0; i < columns; ++i)
{
QString content = QString::fromUtf8(sqlite3_column_name(stmt, i));
if(content.contains(quoteChar) || content.contains(newlineChar))
stream << quoteChar << content.replace(quoteChar, quotequoteChar) << quoteChar;
else
stream << content;
if(i != columns - 1)
stream << sepChar;
}
stream << newlineChar;
}
QApplication::setOverrideCursor(Qt::WaitCursor);
int columns = sqlite3_column_count(stmt);
size_t counter = 0;
while(sqlite3_step(stmt) == SQLITE_ROW)
{
for (int i = 0; i < columns; ++i)
{
QString content = QString::fromUtf8(
(const char*)sqlite3_column_blob(stmt, i),
sqlite3_column_bytes(stmt, i));
if(content.contains(quoteChar) || content.contains("\r\n") || content.contains('\n'))
stream << quoteChar << content.replace(quoteChar, quotequoteChar) << quoteChar;
else
stream << content;
if(i != columns - 1)
stream << sepChar;
}
stream << newlineChar;
if(counter % 1000 == 0)
qApp->processEvents();
counter++;
}
}
sqlite3_finalize(stmt);
QApplication::restoreOverrideCursor();
qApp->processEvents();
// Done writing the file
file.close();
QMessageBox::information(this, QApplication::applicationName(), tr("Export completed."));
QDialog::accept();
} else {
QMessageBox::warning(this, QApplication::applicationName(), tr("Could not open output file."));
}
}
}
void ExportCsvDialog::showCustomCharEdits()
{
// Show/hide custom quote/separator input fields
ui->editCustomQuote->setVisible(ui->comboQuoteCharacter->currentIndex() == ui->comboQuoteCharacter->count()-1);
ui->editCustomSeparator->setVisible(ui->comboFieldSeparator->currentIndex() == ui->comboFieldSeparator->count()-1);
}