mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2025-02-25 00:50:04 -05:00
Syntax style, spaces and pretty indentation
This commit is contained in:
parent
afdf02b4be
commit
a7e358c27d
@ -15,10 +15,12 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "CsvParser.h"
|
||||||
|
|
||||||
#include <QTextCodec>
|
#include <QTextCodec>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
#include "core/Tools.h"
|
#include "core/Tools.h"
|
||||||
#include "CsvParser.h"
|
|
||||||
|
|
||||||
CsvParser::CsvParser()
|
CsvParser::CsvParser()
|
||||||
: m_ch(0)
|
: m_ch(0)
|
||||||
@ -61,16 +63,14 @@ bool CsvParser::parse(QFile *device) {
|
|||||||
m_statusMsg += QObject::tr("NULL device\n");
|
m_statusMsg += QObject::tr("NULL device\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!readFile(device)) {
|
if (!readFile(device))
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
return parseFile();
|
return parseFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CsvParser::readFile(QFile *device) {
|
bool CsvParser::readFile(QFile *device) {
|
||||||
if (device->isOpen()) {
|
if (device->isOpen())
|
||||||
device->close();
|
device->close();
|
||||||
}
|
|
||||||
|
|
||||||
device->open(QIODevice::ReadOnly);
|
device->open(QIODevice::ReadOnly);
|
||||||
if (!Tools::readAllFromDevice(device, m_array)) {
|
if (!Tools::readAllFromDevice(device, m_array)) {
|
||||||
@ -78,14 +78,14 @@ bool CsvParser::readFile(QFile *device) {
|
|||||||
m_isFileLoaded = false;
|
m_isFileLoaded = false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
device->close();
|
device->close();
|
||||||
|
|
||||||
m_array.replace("\r\n", "\n");
|
m_array.replace("\r\n", "\n");
|
||||||
m_array.replace("\r", "\n");
|
m_array.replace("\r", "\n");
|
||||||
if (0 == m_array.size()) {
|
if (0 == m_array.size()) {
|
||||||
m_statusMsg += QObject::tr("File empty\n");
|
m_statusMsg += QObject::tr("File empty\n");
|
||||||
}
|
}
|
||||||
m_isFileLoaded = true;
|
m_isFileLoaded = true;
|
||||||
}
|
}
|
||||||
return m_isFileLoaded;
|
return m_isFileLoaded;
|
||||||
}
|
}
|
||||||
@ -117,11 +117,9 @@ void CsvParser::clear() {
|
|||||||
|
|
||||||
bool CsvParser::parseFile() {
|
bool CsvParser::parseFile() {
|
||||||
parseRecord();
|
parseRecord();
|
||||||
while (!m_isEof)
|
while (!m_isEof) {
|
||||||
{
|
if (!skipEndline())
|
||||||
if (!skipEndline()) {
|
|
||||||
appendStatusMsg(QObject::tr("malformed string"));
|
appendStatusMsg(QObject::tr("malformed string"));
|
||||||
}
|
|
||||||
m_currRow++;
|
m_currRow++;
|
||||||
m_currCol = 1;
|
m_currCol = 1;
|
||||||
parseRecord();
|
parseRecord();
|
||||||
@ -131,43 +129,36 @@ bool CsvParser::parseFile() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CsvParser::parseRecord() {
|
void CsvParser::parseRecord() {
|
||||||
csvrow row;
|
CsvRow row;
|
||||||
if (isComment()) {
|
if (isComment()) {
|
||||||
skipLine();
|
skipLine();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else {
|
do {
|
||||||
do {
|
parseField(row);
|
||||||
parseField(row);
|
getChar(m_ch);
|
||||||
getChar(m_ch);
|
} while (isSeparator(m_ch) && !m_isEof);
|
||||||
} while (isSeparator(m_ch) && !m_isEof);
|
|
||||||
|
|
||||||
if (!m_isEof) {
|
if (!m_isEof)
|
||||||
ungetChar();
|
ungetChar();
|
||||||
}
|
if (isEmptyRow(row)) {
|
||||||
if (isEmptyRow(row)) {
|
row.clear();
|
||||||
row.clear();
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_table.push_back(row);
|
|
||||||
if (m_maxCols < row.size()) {
|
|
||||||
m_maxCols = row.size();
|
|
||||||
}
|
|
||||||
m_currCol++;
|
|
||||||
}
|
}
|
||||||
|
m_table.push_back(row);
|
||||||
|
if (m_maxCols < row.size())
|
||||||
|
m_maxCols = row.size();
|
||||||
|
m_currCol++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CsvParser::parseField(csvrow& row) {
|
void CsvParser::parseField(CsvRow& row) {
|
||||||
QString field;
|
QString field;
|
||||||
peek(m_ch);
|
peek(m_ch);
|
||||||
if (!isTerminator(m_ch))
|
if (!isTerminator(m_ch)) {
|
||||||
{
|
if (isQualifier(m_ch))
|
||||||
if (isQualifier(m_ch)) {
|
|
||||||
parseQuoted(field);
|
parseQuoted(field);
|
||||||
}
|
else
|
||||||
else {
|
parseSimple(field);
|
||||||
parseSimple(field);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
row.push_back(field);
|
row.push_back(field);
|
||||||
}
|
}
|
||||||
@ -175,14 +166,12 @@ void CsvParser::parseField(csvrow& row) {
|
|||||||
void CsvParser::parseSimple(QString &s) {
|
void CsvParser::parseSimple(QString &s) {
|
||||||
QChar c;
|
QChar c;
|
||||||
getChar(c);
|
getChar(c);
|
||||||
while ((isText(c)) && (!m_isEof))
|
while ((isText(c)) && (!m_isEof)) {
|
||||||
{
|
|
||||||
s.append(c);
|
s.append(c);
|
||||||
getChar(c);
|
getChar(c);
|
||||||
}
|
}
|
||||||
if (!m_isEof) {
|
if (!m_isEof)
|
||||||
ungetChar();
|
ungetChar();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CsvParser::parseQuoted(QString &s) {
|
void CsvParser::parseQuoted(QString &s) {
|
||||||
@ -190,25 +179,21 @@ void CsvParser::parseQuoted(QString &s) {
|
|||||||
getChar(m_ch);
|
getChar(m_ch);
|
||||||
parseEscaped(s);
|
parseEscaped(s);
|
||||||
//getChar(m_ch);
|
//getChar(m_ch);
|
||||||
if (!isQualifier(m_ch)) {
|
if (!isQualifier(m_ch))
|
||||||
appendStatusMsg(QObject::tr("missing closing quote"));
|
appendStatusMsg(QObject::tr("missing closing quote"));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CsvParser::parseEscaped(QString &s) {
|
void CsvParser::parseEscaped(QString &s) {
|
||||||
parseEscapedText(s);
|
parseEscapedText(s);
|
||||||
while (processEscapeMark(s, m_ch)) {
|
while (processEscapeMark(s, m_ch))
|
||||||
parseEscapedText(s);
|
parseEscapedText(s);
|
||||||
}
|
if (!m_isEof)
|
||||||
if (!m_isEof) {
|
|
||||||
ungetChar();
|
ungetChar();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CsvParser::parseEscapedText(QString &s) {
|
void CsvParser::parseEscapedText(QString &s) {
|
||||||
getChar(m_ch);
|
getChar(m_ch);
|
||||||
while ((!isQualifier(m_ch)) && !m_isEof)
|
while ((!isQualifier(m_ch)) && !m_isEof) {
|
||||||
{
|
|
||||||
s.append(m_ch);
|
s.append(m_ch);
|
||||||
getChar(m_ch);
|
getChar(m_ch);
|
||||||
}
|
}
|
||||||
@ -218,30 +203,25 @@ bool CsvParser::processEscapeMark(QString &s, QChar c) {
|
|||||||
QChar buf;
|
QChar buf;
|
||||||
peek(buf);
|
peek(buf);
|
||||||
QChar c2;
|
QChar c2;
|
||||||
//escape-character syntax, e.g. \"
|
if (true == m_isBackslashSyntax) {
|
||||||
if (true == m_isBackslashSyntax)
|
//escape-character syntax, e.g. \"
|
||||||
{
|
|
||||||
if (c != '\\') {
|
if (c != '\\') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//consume (and append) second qualifier
|
//consume (and append) second qualifier
|
||||||
getChar(c2);
|
getChar(c2);
|
||||||
if (m_isEof){
|
if (m_isEof) {
|
||||||
c2='\\';
|
c2='\\';
|
||||||
s.append('\\');
|
s.append('\\');
|
||||||
return false;
|
return false;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
s.append(c2);
|
s.append(c2);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
//double quote syntax, e.g. ""
|
//double quote syntax, e.g. ""
|
||||||
else
|
if (!isQualifier(c))
|
||||||
{
|
|
||||||
if (!isQualifier(c)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
peek(c2);
|
peek(c2);
|
||||||
if (!m_isEof) { //not EOF, can read one char
|
if (!m_isEof) { //not EOF, can read one char
|
||||||
if (isQualifier(c2)) {
|
if (isQualifier(c2)) {
|
||||||
@ -255,13 +235,12 @@ bool CsvParser::processEscapeMark(QString &s, QChar c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CsvParser::fillColumns() {
|
void CsvParser::fillColumns() {
|
||||||
//fill the rows with lesser columns with empty fields
|
//fill shorter rows with empty placeholder columns
|
||||||
|
for (int i = 0; i < m_table.size(); ++i) {
|
||||||
for (int i=0; i<m_table.size(); ++i) {
|
|
||||||
int gap = m_maxCols-m_table.at(i).size();
|
int gap = m_maxCols-m_table.at(i).size();
|
||||||
if (gap > 0) {
|
if (gap > 0) {
|
||||||
csvrow r = m_table.at(i);
|
CsvRow r = m_table.at(i);
|
||||||
for (int j=0; j<gap; ++j) {
|
for (int j = 0; j < gap; ++j) {
|
||||||
r.append(QString(""));
|
r.append(QString(""));
|
||||||
}
|
}
|
||||||
m_table.replace(i, r);
|
m_table.replace(i, r);
|
||||||
@ -271,7 +250,7 @@ void CsvParser::fillColumns() {
|
|||||||
|
|
||||||
void CsvParser::skipLine() {
|
void CsvParser::skipLine() {
|
||||||
m_ts.readLine();
|
m_ts.readLine();
|
||||||
m_ts.seek(m_ts.pos()-1);
|
m_ts.seek(m_ts.pos() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CsvParser::skipEndline() {
|
bool CsvParser::skipEndline() {
|
||||||
@ -295,18 +274,15 @@ void CsvParser::ungetChar() {
|
|||||||
|
|
||||||
void CsvParser::peek(QChar& c) {
|
void CsvParser::peek(QChar& c) {
|
||||||
getChar(c);
|
getChar(c);
|
||||||
if (!m_isEof) {
|
if (!m_isEof)
|
||||||
ungetChar();
|
ungetChar();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CsvParser::isQualifier(const QChar c) const {
|
bool CsvParser::isQualifier(const QChar &c) const {
|
||||||
if (true == m_isBackslashSyntax && (c != m_qualifier)) {
|
if (true == m_isBackslashSyntax && (c != m_qualifier))
|
||||||
return (c == '\\');
|
return (c == '\\');
|
||||||
}
|
else
|
||||||
else {
|
return (c == m_qualifier);
|
||||||
return (c == m_qualifier);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CsvParser::isComment() {
|
bool CsvParser::isComment() {
|
||||||
@ -314,13 +290,11 @@ bool CsvParser::isComment() {
|
|||||||
QChar c2;
|
QChar c2;
|
||||||
qint64 pos = m_ts.pos();
|
qint64 pos = m_ts.pos();
|
||||||
|
|
||||||
do {
|
do getChar(c2);
|
||||||
getChar(c2);
|
while ((isSpace(c2) || isTab(c2)) && (!m_isEof));
|
||||||
} while ((isSpace(c2) || isTab(c2)) && (!m_isEof));
|
|
||||||
|
|
||||||
if (c2 == m_comment) {
|
if (c2 == m_comment)
|
||||||
result = true;
|
result = true;
|
||||||
}
|
|
||||||
m_ts.seek(pos);
|
m_ts.seek(pos);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -329,32 +303,31 @@ bool CsvParser::isText(QChar c) const {
|
|||||||
return !( (isCRLF(c)) || (isSeparator(c)) );
|
return !( (isCRLF(c)) || (isSeparator(c)) );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CsvParser::isEmptyRow(csvrow row) const {
|
bool CsvParser::isEmptyRow(CsvRow row) const {
|
||||||
csvrow::const_iterator it = row.constBegin();
|
CsvRow::const_iterator it = row.constBegin();
|
||||||
for (; it != row.constEnd(); ++it) {
|
for (; it != row.constEnd(); ++it)
|
||||||
if ( ((*it) != "\n") && ((*it) != "") )
|
if ( ((*it) != "\n") && ((*it) != "") )
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CsvParser::isCRLF(const QChar c) const {
|
bool CsvParser::isCRLF(const QChar &c) const {
|
||||||
return (c == '\n');
|
return (c == '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CsvParser::isSpace(const QChar c) const {
|
bool CsvParser::isSpace(const QChar &c) const {
|
||||||
return (c == 0x20);
|
return (c == 0x20);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CsvParser::isTab(const QChar c) const {
|
bool CsvParser::isTab(const QChar &c) const {
|
||||||
return (c == '\t');
|
return (c == '\t');
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CsvParser::isSeparator(const QChar c) const {
|
bool CsvParser::isSeparator(const QChar &c) const {
|
||||||
return (c == m_separator);
|
return (c == m_separator);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CsvParser::isTerminator(const QChar c) const {
|
bool CsvParser::isTerminator(const QChar &c) const {
|
||||||
return (isSeparator(c) || (c == '\n') || (c == '\r'));
|
return (isSeparator(c) || (c == '\n') || (c == '\r'));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -362,19 +335,19 @@ void CsvParser::setBackslashSyntax(bool set) {
|
|||||||
m_isBackslashSyntax = set;
|
m_isBackslashSyntax = set;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CsvParser::setComment(const QChar c) {
|
void CsvParser::setComment(const QChar &c) {
|
||||||
m_comment = c.unicode();
|
m_comment = c.unicode();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CsvParser::setCodec(const QString s) {
|
void CsvParser::setCodec(const QString &s) {
|
||||||
m_ts.setCodec(QTextCodec::codecForName(s.toLocal8Bit()));
|
m_ts.setCodec(QTextCodec::codecForName(s.toLocal8Bit()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CsvParser::setFieldSeparator(const QChar c) {
|
void CsvParser::setFieldSeparator(const QChar &c) {
|
||||||
m_separator = c.unicode();
|
m_separator = c.unicode();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CsvParser::setTextQualifier(const QChar c) {
|
void CsvParser::setTextQualifier(const QChar &c) {
|
||||||
m_qualifier = c.unicode();
|
m_qualifier = c.unicode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,11 +355,14 @@ int CsvParser::getFileSize() const {
|
|||||||
return m_csv.size();
|
return m_csv.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
const csvtable CsvParser::getCsvTable() const {
|
const CsvTable CsvParser::getCsvTable() const {
|
||||||
return m_table;
|
return m_table;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CsvParser::getStatus() const {
|
QString CsvParser::getStatus() const {
|
||||||
|
if (m_statusMsg.size() > 100)
|
||||||
|
return m_statusMsg.section('\n', 0, 4)
|
||||||
|
.append("\n[...]\n").append(QObject::tr("More messages, skipped!"));
|
||||||
return m_statusMsg;
|
return m_statusMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,8 +23,8 @@
|
|||||||
#include <QQueue>
|
#include <QQueue>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
|
|
||||||
typedef QStringList csvrow;
|
typedef QStringList CsvRow;
|
||||||
typedef QList<csvrow> csvtable;
|
typedef QList<CsvRow> CsvTable;
|
||||||
|
|
||||||
class CsvParser {
|
class CsvParser {
|
||||||
|
|
||||||
@ -36,19 +36,19 @@ public:
|
|||||||
bool isFileLoaded();
|
bool isFileLoaded();
|
||||||
//reparse the same buffer (device is not opened again)
|
//reparse the same buffer (device is not opened again)
|
||||||
bool reparse();
|
bool reparse();
|
||||||
void setCodec(const QString s);
|
void setCodec(const QString &s);
|
||||||
void setComment(const QChar c);
|
void setComment(const QChar &c);
|
||||||
void setFieldSeparator(const QChar c);
|
void setFieldSeparator(const QChar &c);
|
||||||
void setTextQualifier(const QChar c);
|
void setTextQualifier(const QChar &c);
|
||||||
void setBackslashSyntax(bool set);
|
void setBackslashSyntax(bool set);
|
||||||
int getFileSize() const;
|
int getFileSize() const;
|
||||||
int getCsvRows() const;
|
int getCsvRows() const;
|
||||||
int getCsvCols() const;
|
int getCsvCols() const;
|
||||||
QString getStatus() const;
|
QString getStatus() const;
|
||||||
const csvtable getCsvTable() const;
|
const CsvTable getCsvTable() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
csvtable m_table;
|
CsvTable m_table;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QByteArray m_array;
|
QByteArray m_array;
|
||||||
@ -72,22 +72,22 @@ private:
|
|||||||
void ungetChar();
|
void ungetChar();
|
||||||
void peek(QChar &c);
|
void peek(QChar &c);
|
||||||
void fillColumns();
|
void fillColumns();
|
||||||
bool isTerminator(const QChar c) const;
|
bool isTerminator(const QChar &c) const;
|
||||||
bool isSeparator(const QChar c) const;
|
bool isSeparator(const QChar &c) const;
|
||||||
bool isQualifier(const QChar c) const;
|
bool isQualifier(const QChar &c) const;
|
||||||
bool processEscapeMark(QString &s, QChar c);
|
bool processEscapeMark(QString &s, QChar c);
|
||||||
bool isText(QChar c) const;
|
bool isText(QChar c) const;
|
||||||
bool isComment();
|
bool isComment();
|
||||||
bool isCRLF(const QChar c) const;
|
bool isCRLF(const QChar &c) const;
|
||||||
bool isSpace(const QChar c) const;
|
bool isSpace(const QChar &c) const;
|
||||||
bool isTab(const QChar c) const;
|
bool isTab(const QChar &c) const;
|
||||||
bool isEmptyRow(csvrow row) const;
|
bool isEmptyRow(CsvRow row) const;
|
||||||
bool parseFile();
|
bool parseFile();
|
||||||
void parseRecord();
|
void parseRecord();
|
||||||
void parseField(csvrow& row);
|
void parseField(CsvRow &row);
|
||||||
void parseSimple(QString& s);
|
void parseSimple(QString &s);
|
||||||
void parseQuoted(QString& s);
|
void parseQuoted(QString &s);
|
||||||
void parseEscaped(QString& s);
|
void parseEscaped(QString &s);
|
||||||
void parseEscapedText(QString &s);
|
void parseEscapedText(QString &s);
|
||||||
bool readFile(QFile *device);
|
bool readFile(QFile *device);
|
||||||
void reset();
|
void reset();
|
||||||
|
@ -196,6 +196,9 @@ DatabaseWidget::Mode DatabaseWidget::currentMode() const
|
|||||||
if (currentWidget() == nullptr) {
|
if (currentWidget() == nullptr) {
|
||||||
return DatabaseWidget::None;
|
return DatabaseWidget::None;
|
||||||
}
|
}
|
||||||
|
else if (currentWidget() == m_csvImportWizard) {
|
||||||
|
return DatabaseWidget::ImportMode;
|
||||||
|
}
|
||||||
else if (currentWidget() == m_mainWidget) {
|
else if (currentWidget() == m_mainWidget) {
|
||||||
return DatabaseWidget::ViewMode;
|
return DatabaseWidget::ViewMode;
|
||||||
}
|
}
|
||||||
|
@ -61,6 +61,7 @@ public:
|
|||||||
enum Mode
|
enum Mode
|
||||||
{
|
{
|
||||||
None,
|
None,
|
||||||
|
ImportMode,
|
||||||
ViewMode,
|
ViewMode,
|
||||||
EditMode,
|
EditMode,
|
||||||
LockedMode
|
LockedMode
|
||||||
|
@ -425,6 +425,7 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DatabaseWidget::EditMode:
|
case DatabaseWidget::EditMode:
|
||||||
|
case DatabaseWidget::ImportMode:
|
||||||
case DatabaseWidget::LockedMode: {
|
case DatabaseWidget::LockedMode: {
|
||||||
const QList<QAction*> entryActions = m_ui->menuEntries->actions();
|
const QList<QAction*> entryActions = m_ui->menuEntries->actions();
|
||||||
for (QAction* action : entryActions) {
|
for (QAction* action : entryActions) {
|
||||||
|
@ -17,15 +17,17 @@
|
|||||||
|
|
||||||
#include "CsvImportWidget.h"
|
#include "CsvImportWidget.h"
|
||||||
#include "ui_CsvImportWidget.h"
|
#include "ui_CsvImportWidget.h"
|
||||||
#include "gui/MessageBox.h"
|
|
||||||
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
|
|
||||||
|
#include "gui/MessageBox.h"
|
||||||
|
#include "gui/MessageWidget.h"
|
||||||
|
|
||||||
//I wanted to make the CSV import GUI future-proof, so if one day you need entries
|
//I wanted to make the CSV import GUI future-proof, so if one day you need entries
|
||||||
//to have a new field, all you have to do is uncomment a row or two here, and the GUI will follow:
|
//to have a new field, all you have to do is uncomment a row or two here, and the GUI will follow:
|
||||||
//dynamic generation of comboBoxes, labels, placement and so on. Try it for immense fun!
|
//dynamic generation of comboBoxes, labels, placement and so on. Try it for immense fun!
|
||||||
const QStringList CsvImportWidget::m_columnheader = QStringList()
|
const QStringList CsvImportWidget::m_columnHeader = QStringList()
|
||||||
<< QObject::tr("Group")
|
<< QObject::tr("Group")
|
||||||
<< QObject::tr("Title")
|
<< QObject::tr("Title")
|
||||||
<< QObject::tr("Username")
|
<< QObject::tr("Username")
|
||||||
@ -46,10 +48,7 @@ CsvImportWidget::CsvImportWidget(QWidget *parent)
|
|||||||
{
|
{
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
|
|
||||||
QFont font = m_ui->labelHeadline->font();
|
m_ui->messageWidget->setHidden(true);
|
||||||
font.setBold(true);
|
|
||||||
font.setPointSize(font.pointSize() + 2);
|
|
||||||
m_ui->labelHeadline->setFont(font);
|
|
||||||
|
|
||||||
m_ui->comboBoxCodec->addItems(QStringList() <<"UTF-8" <<"Windows-1252" <<"UTF-16" <<"UTF-16LE");
|
m_ui->comboBoxCodec->addItems(QStringList() <<"UTF-8" <<"Windows-1252" <<"UTF-16" <<"UTF-16LE");
|
||||||
m_ui->comboBoxFieldSeparator->addItems(QStringList() <<"," <<";" <<"-" <<":" <<".");
|
m_ui->comboBoxFieldSeparator->addItems(QStringList() <<"," <<";" <<"-" <<":" <<".");
|
||||||
@ -59,10 +58,10 @@ CsvImportWidget::CsvImportWidget(QWidget *parent)
|
|||||||
m_ui->tableViewFields->setSelectionMode(QAbstractItemView::NoSelection);
|
m_ui->tableViewFields->setSelectionMode(QAbstractItemView::NoSelection);
|
||||||
m_ui->tableViewFields->setFocusPolicy(Qt::NoFocus);
|
m_ui->tableViewFields->setFocusPolicy(Qt::NoFocus);
|
||||||
|
|
||||||
for (int i=0; i<m_columnheader.count(); ++i) {
|
for (int i = 0; i < m_columnHeader.count(); ++i) {
|
||||||
QLabel* label = new QLabel(m_columnheader.at(i), this);
|
QLabel* label = new QLabel(m_columnHeader.at(i), this);
|
||||||
label->setFixedWidth(label->minimumSizeHint().width());
|
label->setFixedWidth(label->minimumSizeHint().width());
|
||||||
font = label->font();
|
QFont font = label->font();
|
||||||
font.setBold(false);
|
font.setBold(false);
|
||||||
label->setFont(font);
|
label->setFont(font);
|
||||||
|
|
||||||
@ -76,14 +75,14 @@ CsvImportWidget::CsvImportWidget(QWidget *parent)
|
|||||||
connect(combo, SIGNAL(currentIndexChanged(int)), m_comboMapper, SLOT(map()));
|
connect(combo, SIGNAL(currentIndexChanged(int)), m_comboMapper, SLOT(map()));
|
||||||
|
|
||||||
//layout labels and combo fields in column-first order
|
//layout labels and combo fields in column-first order
|
||||||
int combo_rows = 1+(m_columnheader.count()-1)/2;
|
int combo_rows = 1+(m_columnHeader.count()-1)/2;
|
||||||
int x=i%combo_rows;
|
int x = i%combo_rows;
|
||||||
int y= 2*(i/combo_rows);
|
int y = 2*(i/combo_rows);
|
||||||
m_ui->gridLayout_combos->addWidget(label, x, y);
|
m_ui->gridLayout_combos->addWidget(label, x, y);
|
||||||
m_ui->gridLayout_combos->addWidget(combo, x, y+1);
|
m_ui->gridLayout_combos->addWidget(combo, x, y+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_parserModel->setHeaderLabels(m_columnheader);
|
m_parserModel->setHeaderLabels(m_columnHeader);
|
||||||
m_ui->tableViewFields->setModel(m_parserModel);
|
m_ui->tableViewFields->setModel(m_parserModel);
|
||||||
|
|
||||||
connect(m_ui->spinBoxSkip, SIGNAL(valueChanged(int)), SLOT(skippedChanged(int)));
|
connect(m_ui->spinBoxSkip, SIGNAL(valueChanged(int)), SLOT(skippedChanged(int)));
|
||||||
@ -101,10 +100,9 @@ CsvImportWidget::CsvImportWidget(QWidget *parent)
|
|||||||
|
|
||||||
void CsvImportWidget::comboChanged(int comboId) {
|
void CsvImportWidget::comboChanged(int comboId) {
|
||||||
QComboBox* currentSender = qobject_cast<QComboBox*>(m_comboMapper->mapping(comboId));
|
QComboBox* currentSender = qobject_cast<QComboBox*>(m_comboMapper->mapping(comboId));
|
||||||
if (currentSender->currentIndex() != -1) {
|
if (currentSender->currentIndex() != -1)
|
||||||
//here is the line that actually updates the GUI table
|
//this line is the one that actually updates GUI table
|
||||||
m_parserModel->mapColumns(currentSender->currentIndex(), comboId);
|
m_parserModel->mapColumns(currentSender->currentIndex(), comboId);
|
||||||
}
|
|
||||||
updateTableview();
|
updateTableview();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,7 +125,7 @@ void CsvImportWidget::updateTableview() {
|
|||||||
m_ui->tableViewFields->resizeRowsToContents();
|
m_ui->tableViewFields->resizeRowsToContents();
|
||||||
m_ui->tableViewFields->resizeColumnsToContents();
|
m_ui->tableViewFields->resizeColumnsToContents();
|
||||||
|
|
||||||
for (int c=0; c<m_ui->tableViewFields->horizontalHeader()->count(); ++c) {
|
for (int c = 0; c < m_ui->tableViewFields->horizontalHeader()->count(); ++c) {
|
||||||
m_ui->tableViewFields->horizontalHeader()->setSectionResizeMode(
|
m_ui->tableViewFields->horizontalHeader()->setSectionResizeMode(
|
||||||
c, QHeaderView::Stretch);
|
c, QHeaderView::Stretch);
|
||||||
}
|
}
|
||||||
@ -137,12 +135,12 @@ void CsvImportWidget::updatePreview() {
|
|||||||
|
|
||||||
m_ui->labelSizeRowsCols->setText(m_parserModel->getFileInfo());
|
m_ui->labelSizeRowsCols->setText(m_parserModel->getFileInfo());
|
||||||
m_ui->spinBoxSkip->setValue(0);
|
m_ui->spinBoxSkip->setValue(0);
|
||||||
m_ui->spinBoxSkip->setMaximum(m_parserModel->rowCount()-1);
|
m_ui->spinBoxSkip->setMaximum(m_parserModel->rowCount() - 1);
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
QStringList list(tr("Not present in CSV file"));
|
QStringList list(tr("Not present in CSV file"));
|
||||||
|
|
||||||
for (i=1; i<m_parserModel->getCsvCols(); i++) {
|
for (i = 1; i < m_parserModel->getCsvCols(); i++) {
|
||||||
QString s = QString(tr("Column ")) + QString::number(i);
|
QString s = QString(tr("Column ")) + QString::number(i);
|
||||||
list << s;
|
list << s;
|
||||||
}
|
}
|
||||||
@ -150,12 +148,10 @@ void CsvImportWidget::updatePreview() {
|
|||||||
|
|
||||||
i=1;
|
i=1;
|
||||||
Q_FOREACH (QComboBox* b, m_combos) {
|
Q_FOREACH (QComboBox* b, m_combos) {
|
||||||
if (i < m_parserModel->getCsvCols()) {
|
if (i < m_parserModel->getCsvCols())
|
||||||
b->setCurrentIndex(i);
|
b->setCurrentIndex(i);
|
||||||
}
|
else
|
||||||
else {
|
|
||||||
b->setCurrentIndex(0);
|
b->setCurrentIndex(0);
|
||||||
}
|
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -166,7 +162,7 @@ void CsvImportWidget::load(const QString& filename, Database* const db) {
|
|||||||
m_ui->labelFilename->setText(filename);
|
m_ui->labelFilename->setText(filename);
|
||||||
Group* group = m_db->rootGroup();
|
Group* group = m_db->rootGroup();
|
||||||
group->setUuid(Uuid::random());
|
group->setUuid(Uuid::random());
|
||||||
group->setNotes(tr("Imported from CSV file\nOriginal data: ") + filename);
|
group->setNotes(tr("Imported from CSV file").append("\n").append(tr("Original data: ")) + filename);
|
||||||
|
|
||||||
parse();
|
parse();
|
||||||
}
|
}
|
||||||
@ -181,47 +177,48 @@ void CsvImportWidget::parse() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CsvImportWidget::showReport() {
|
void CsvImportWidget::showReport() {
|
||||||
MessageBox::warning(this, tr("Syntax error"), tr("While parsing file...\n")
|
// MessageBox::warning(this, tr("Syntax error"), tr("While parsing file...\n")
|
||||||
.append(m_parserModel->getStatus()), QMessageBox::Ok, QMessageBox::Ok);
|
// .append(m_parserModel->getStatus()), QMessageBox::Ok, QMessageBox::Ok);
|
||||||
|
m_ui->messageWidget->showMessage(tr("Syntax error while parsing file.").append("\n")
|
||||||
|
.append(m_parserModel->getStatus()), MessageWidget::Warning);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CsvImportWidget::writeDatabase() {
|
void CsvImportWidget::writeDatabase() {
|
||||||
|
|
||||||
checkGroupNames();
|
setRootGroup();
|
||||||
for (int r=0; r<m_parserModel->rowCount(); r++) {
|
for (int r = 0; r < m_parserModel->rowCount(); r++)
|
||||||
//use the validity of second column as a GO/NOGO hint for all others fields
|
//use the validity of second column as a GO/NOGO hint for all others fields
|
||||||
if (m_parserModel->data(m_parserModel->index(r, 1)).isValid()) {
|
if (m_parserModel->data(m_parserModel->index(r, 1)).isValid()) {
|
||||||
Entry* entry = new Entry();
|
Entry* entry = new Entry();
|
||||||
entry->setUuid(Uuid::random());
|
entry->setUuid(Uuid::random());
|
||||||
entry->setGroup(splitGroups(m_parserModel->data(m_parserModel->index(r, 0)).toString()));
|
entry->setGroup(splitGroups(m_parserModel->data(m_parserModel->index(r, 0)).toString()));
|
||||||
entry->setTitle( m_parserModel->data(m_parserModel->index(r, 1)).toString());
|
entry->setTitle(m_parserModel->data(m_parserModel->index(r, 1)).toString());
|
||||||
entry->setUsername( m_parserModel->data(m_parserModel->index(r, 2)).toString());
|
entry->setUsername(m_parserModel->data(m_parserModel->index(r, 2)).toString());
|
||||||
entry->setPassword( m_parserModel->data(m_parserModel->index(r, 3)).toString());
|
entry->setPassword(m_parserModel->data(m_parserModel->index(r, 3)).toString());
|
||||||
entry->setUrl( m_parserModel->data(m_parserModel->index(r, 4)).toString());
|
entry->setUrl(m_parserModel->data(m_parserModel->index(r, 4)).toString());
|
||||||
entry->setNotes( m_parserModel->data(m_parserModel->index(r, 5)).toString());
|
entry->setNotes(m_parserModel->data(m_parserModel->index(r, 5)).toString());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
QBuffer buffer;
|
QBuffer buffer;
|
||||||
buffer.open(QBuffer::ReadWrite);
|
buffer.open(QBuffer::ReadWrite);
|
||||||
|
|
||||||
KeePass2Writer writer;
|
KeePass2Writer writer;
|
||||||
writer.writeDatabase(&buffer, m_db);
|
writer.writeDatabase(&buffer, m_db);
|
||||||
if (writer.hasError()) {
|
if (writer.hasError())
|
||||||
MessageBox::warning(this, tr("Error"), tr("CSV import: writer has errors:\n")
|
MessageBox::warning(this, tr("Error"), tr("CSV import: writer has errors:\n")
|
||||||
.append((writer.errorString())), QMessageBox::Ok, QMessageBox::Ok);
|
.append((writer.errorString())), QMessageBox::Ok, QMessageBox::Ok);
|
||||||
}
|
|
||||||
Q_EMIT editFinished(true);
|
Q_EMIT editFinished(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CsvImportWidget::checkGroupNames() {
|
void CsvImportWidget::setRootGroup() {
|
||||||
QString groupLabel;
|
QString groupLabel;
|
||||||
QStringList groupList;
|
QStringList groupList;
|
||||||
bool is_root = false
|
bool is_root = false;
|
||||||
, is_empty = false
|
bool is_empty = false;
|
||||||
, is_label = false;
|
bool is_label = false;
|
||||||
for (int r=0; r<m_parserModel->rowCount(); r++) {
|
|
||||||
|
for (int r = 0; r < m_parserModel->rowCount(); r++) {
|
||||||
groupLabel = m_parserModel->data(m_parserModel->index(r, 0)).toString();
|
groupLabel = m_parserModel->data(m_parserModel->index(r, 0)).toString();
|
||||||
//check if group name is either "root", "" (empty) or some other label
|
//check if group name is either "root", "" (empty) or some other label
|
||||||
groupList = groupLabel.split("/", QString::SkipEmptyParts);
|
groupList = groupLabel.split("/", QString::SkipEmptyParts);
|
||||||
@ -234,18 +231,13 @@ void CsvImportWidget::checkGroupNames() {
|
|||||||
groupList.clear();
|
groupList.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((not is_label and (is_empty xor is_root))
|
if ((not is_label and (is_empty xor is_root)) or (is_label and not is_root))
|
||||||
or (is_label and not is_root)) {
|
|
||||||
m_db->rootGroup()->setName("Root");
|
m_db->rootGroup()->setName("Root");
|
||||||
}
|
else if ((is_empty and is_root) or (is_label and not is_empty and is_root))
|
||||||
else if ((is_empty and is_root)
|
|
||||||
or (is_label and not is_empty and is_root)) {
|
|
||||||
m_db->rootGroup()->setName("CSV IMPORTED");
|
m_db->rootGroup()->setName("CSV IMPORTED");
|
||||||
}
|
else
|
||||||
else {
|
|
||||||
//SHOULD NEVER GET HERE
|
//SHOULD NEVER GET HERE
|
||||||
m_db->rootGroup()->setName("ROOT_FALLBACK");
|
m_db->rootGroup()->setName("ROOT_FALLBACK");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Group *CsvImportWidget::splitGroups(QString label) {
|
Group *CsvImportWidget::splitGroups(QString label) {
|
||||||
@ -254,9 +246,8 @@ Group *CsvImportWidget::splitGroups(QString label) {
|
|||||||
QStringList groupList = label.split("/", QString::SkipEmptyParts);
|
QStringList groupList = label.split("/", QString::SkipEmptyParts);
|
||||||
|
|
||||||
//skip the creation of a subgroup of Root with the same name
|
//skip the creation of a subgroup of Root with the same name
|
||||||
if (m_db->rootGroup()->name() == "Root" && groupList.first() == "Root") {
|
if (m_db->rootGroup()->name() == "Root" && groupList.first() == "Root")
|
||||||
groupList.removeFirst();
|
groupList.removeFirst();
|
||||||
}
|
|
||||||
|
|
||||||
for (const QString& groupName : groupList) {
|
for (const QString& groupName : groupList) {
|
||||||
Group *children = hasChildren(current, groupName);
|
Group *children = hasChildren(current, groupName);
|
||||||
@ -265,8 +256,7 @@ Group *CsvImportWidget::splitGroups(QString label) {
|
|||||||
brandNew->setParent(current);
|
brandNew->setParent(current);
|
||||||
brandNew->setName(groupName);
|
brandNew->setName(groupName);
|
||||||
current = brandNew;
|
current = brandNew;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
Q_ASSERT(children != nullptr);
|
Q_ASSERT(children != nullptr);
|
||||||
current = children;
|
current = children;
|
||||||
}
|
}
|
||||||
@ -277,9 +267,8 @@ Group *CsvImportWidget::splitGroups(QString label) {
|
|||||||
Group* CsvImportWidget::hasChildren(Group* current, QString groupName) {
|
Group* CsvImportWidget::hasChildren(Group* current, QString groupName) {
|
||||||
//returns the group whose name is "groupName" and is child of "current" group
|
//returns the group whose name is "groupName" and is child of "current" group
|
||||||
for (Group * group : current->children()) {
|
for (Group * group : current->children()) {
|
||||||
if (group->name() == groupName) {
|
if (group->name() == groupName)
|
||||||
return group;
|
return group;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -26,10 +26,10 @@
|
|||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
#include <QStackedWidget>
|
#include <QStackedWidget>
|
||||||
|
|
||||||
|
#include "core/Metadata.h"
|
||||||
#include "format/KeePass2Writer.h"
|
#include "format/KeePass2Writer.h"
|
||||||
#include "gui/csvImport/CsvParserModel.h"
|
#include "gui/csvImport/CsvParserModel.h"
|
||||||
#include "keys/PasswordKey.h"
|
#include "keys/PasswordKey.h"
|
||||||
#include "core/Metadata.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
@ -42,7 +42,7 @@ class CsvImportWidget : public QWidget
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CsvImportWidget(QWidget *parent = nullptr);
|
explicit CsvImportWidget(QWidget *parent = nullptr);
|
||||||
virtual ~CsvImportWidget();
|
~CsvImportWidget();
|
||||||
void load(const QString& filename, Database* const db);
|
void load(const QString& filename, Database* const db);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
@ -54,7 +54,7 @@ private Q_SLOTS:
|
|||||||
void comboChanged(int comboId);
|
void comboChanged(int comboId);
|
||||||
void skippedChanged(int rows);
|
void skippedChanged(int rows);
|
||||||
void writeDatabase();
|
void writeDatabase();
|
||||||
void checkGroupNames();
|
void setRootGroup();
|
||||||
void reject();
|
void reject();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -67,7 +67,7 @@ private:
|
|||||||
Database *m_db;
|
Database *m_db;
|
||||||
|
|
||||||
KeePass2Writer m_writer;
|
KeePass2Writer m_writer;
|
||||||
static const QStringList m_columnheader;
|
static const QStringList m_columnHeader;
|
||||||
void configParser();
|
void configParser();
|
||||||
void updatePreview();
|
void updatePreview();
|
||||||
void updateTableview();
|
void updateTableview();
|
||||||
|
@ -14,7 +14,33 @@
|
|||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_4">
|
<layout class="QGridLayout" name="gridLayout_4">
|
||||||
<item row="2" column="0">
|
<item row="2" column="0" colspan="2">
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeType">
|
||||||
|
<enum>QSizePolicy::Fixed</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>758</width>
|
||||||
|
<height>24</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="0">
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
<property name="centerButtons">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0" colspan="2">
|
||||||
<widget class="QGroupBox" name="Encoding">
|
<widget class="QGroupBox" name="Encoding">
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
@ -377,17 +403,7 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="0">
|
<item row="4" column="0" colspan="2">
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
|
||||||
<property name="standardButtons">
|
|
||||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
|
||||||
</property>
|
|
||||||
<property name="centerButtons">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0">
|
|
||||||
<widget class="QGroupBox" name="groupBoxColumnAssociations">
|
<widget class="QGroupBox" name="groupBoxColumnAssociations">
|
||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
@ -409,50 +425,7 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="0">
|
<item row="5" column="0" colspan="2">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="labelHeadline">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Import CSV fields</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="labelFilename">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>filename</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="labelSizeRowsCols">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>size, rows, columns</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="0">
|
|
||||||
<widget class="QGroupBox" name="groupBoxPreview">
|
<widget class="QGroupBox" name="groupBoxPreview">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
||||||
@ -501,24 +474,69 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="0" column="0" rowspan="2">
|
||||||
<spacer name="verticalSpacer">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<property name="orientation">
|
<item>
|
||||||
<enum>Qt::Vertical</enum>
|
<widget class="MessageWidget" name="messageWidget" native="true"/>
|
||||||
</property>
|
</item>
|
||||||
<property name="sizeType">
|
<item>
|
||||||
<enum>QSizePolicy::Fixed</enum>
|
<widget class="QLabel" name="labelHeadline">
|
||||||
</property>
|
<property name="sizePolicy">
|
||||||
<property name="sizeHint" stdset="0">
|
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||||
<size>
|
<horstretch>0</horstretch>
|
||||||
<width>20</width>
|
<verstretch>0</verstretch>
|
||||||
<height>27</height>
|
</sizepolicy>
|
||||||
</size>
|
</property>
|
||||||
</property>
|
<property name="font">
|
||||||
</spacer>
|
<font>
|
||||||
|
<pointsize>11</pointsize>
|
||||||
|
<weight>75</weight>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Import CSV fields</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelFilename">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>filename</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelSizeRowsCols">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>size, rows, columns</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>MessageWidget</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>gui/MessageWidget.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
</ui>
|
</ui>
|
||||||
|
@ -16,8 +16,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "CsvImportWizard.h"
|
#include "CsvImportWizard.h"
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
|
||||||
#include "gui/MessageBox.h"
|
#include "gui/MessageBox.h"
|
||||||
|
|
||||||
|
|
||||||
@ -49,7 +51,7 @@ void CsvImportWizard::load(const QString& filename, Database* database)
|
|||||||
void CsvImportWizard::keyFinished(bool accepted)
|
void CsvImportWizard::keyFinished(bool accepted)
|
||||||
{
|
{
|
||||||
if (!accepted) {
|
if (!accepted) {
|
||||||
Q_EMIT(importFinished(false));
|
emit(importFinished(false));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,12 +63,12 @@ void CsvImportWizard::keyFinished(bool accepted)
|
|||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
MessageBox::critical(this, tr("Error"), tr("Unable to calculate master key"));
|
MessageBox::critical(this, tr("Error"), tr("Unable to calculate master key"));
|
||||||
Q_EMIT importFinished(false);
|
emit(importFinished(false));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CsvImportWizard::parseFinished(bool accepted)
|
void CsvImportWizard::parseFinished(bool accepted)
|
||||||
{
|
{
|
||||||
Q_EMIT(importFinished(accepted));
|
emit(importFinished(accepted));
|
||||||
}
|
}
|
||||||
|
@ -18,10 +18,11 @@
|
|||||||
#ifndef KEEPASSX_CSVIMPORTWIZARD_H
|
#ifndef KEEPASSX_CSVIMPORTWIZARD_H
|
||||||
#define KEEPASSX_CSVIMPORTWIZARD_H
|
#define KEEPASSX_CSVIMPORTWIZARD_H
|
||||||
|
|
||||||
|
#include "CsvImportWidget.h"
|
||||||
|
|
||||||
#include <QStackedWidget>
|
#include <QStackedWidget>
|
||||||
#include <QGridLayout>
|
#include <QGridLayout>
|
||||||
|
|
||||||
#include "CsvImportWidget.h"
|
|
||||||
#include "core/Database.h"
|
#include "core/Database.h"
|
||||||
#include "gui/ChangeMasterKeyWidget.h"
|
#include "gui/ChangeMasterKeyWidget.h"
|
||||||
#include "gui/DialogyWidget.h"
|
#include "gui/DialogyWidget.h"
|
||||||
@ -34,7 +35,7 @@ class CsvImportWizard : public DialogyWidget
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CsvImportWizard(QWidget *parent = nullptr);
|
explicit CsvImportWizard(QWidget *parent = nullptr);
|
||||||
virtual ~CsvImportWizard();
|
~CsvImportWizard();
|
||||||
void load(const QString& filename, Database *database);
|
void load(const QString& filename, Database *database);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
|
@ -42,39 +42,33 @@ bool CsvParserModel::parse() {
|
|||||||
m_columnMap.clear();
|
m_columnMap.clear();
|
||||||
if (CsvParser::isFileLoaded()) {
|
if (CsvParser::isFileLoaded()) {
|
||||||
r = CsvParser::reparse();
|
r = CsvParser::reparse();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
QFile csv(m_filename);
|
QFile csv(m_filename);
|
||||||
r = CsvParser::parse(&csv);
|
r = CsvParser::parse(&csv);
|
||||||
}
|
}
|
||||||
for (int i=0; i<columnCount(); i++) {
|
for (int i = 0; i < columnCount(); i++)
|
||||||
m_columnMap.insert(i,0);
|
m_columnMap.insert(i,0);
|
||||||
}
|
|
||||||
addEmptyColumn();
|
addEmptyColumn();
|
||||||
endResetModel();
|
endResetModel();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CsvParserModel::addEmptyColumn() {
|
void CsvParserModel::addEmptyColumn() {
|
||||||
for (int i=0; i<m_table.size(); ++i) {
|
for (int i = 0; i < m_table.size(); ++i) {
|
||||||
csvrow r = m_table.at(i);
|
CsvRow r = m_table.at(i);
|
||||||
r.prepend(QString(""));
|
r.prepend(QString(""));
|
||||||
m_table.replace(i, r);
|
m_table.replace(i, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CsvParserModel::mapColumns(int csvColumn, int dbColumn) {
|
void CsvParserModel::mapColumns(int csvColumn, int dbColumn) {
|
||||||
if ((csvColumn < 0) || (dbColumn < 0) ) {
|
if ((csvColumn < 0) || (dbColumn < 0))
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
if (csvColumn >= getCsvCols()) {
|
if (csvColumn >= getCsvCols())
|
||||||
m_columnMap[dbColumn] = 0; //map to the empty column
|
m_columnMap[dbColumn] = 0; //map to the empty column
|
||||||
}
|
else
|
||||||
else {
|
|
||||||
m_columnMap[dbColumn] = csvColumn;
|
m_columnMap[dbColumn] = csvColumn;
|
||||||
}
|
|
||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,8 +76,8 @@ void CsvParserModel::setSkippedRows(int skipped) {
|
|||||||
m_skipped = skipped;
|
m_skipped = skipped;
|
||||||
QModelIndex topLeft = createIndex(skipped,0);
|
QModelIndex topLeft = createIndex(skipped,0);
|
||||||
QModelIndex bottomRight = createIndex(m_skipped+rowCount(), columnCount());
|
QModelIndex bottomRight = createIndex(m_skipped+rowCount(), columnCount());
|
||||||
Q_EMIT dataChanged(topLeft, bottomRight);
|
emit dataChanged(topLeft, bottomRight);
|
||||||
Q_EMIT layoutChanged();
|
emit layoutChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CsvParserModel::setHeaderLabels(QStringList l) {
|
void CsvParserModel::setHeaderLabels(QStringList l) {
|
||||||
@ -91,45 +85,37 @@ void CsvParserModel::setHeaderLabels(QStringList l) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int CsvParserModel::rowCount(const QModelIndex &parent) const {
|
int CsvParserModel::rowCount(const QModelIndex &parent) const {
|
||||||
if (parent.isValid()) {
|
if (parent.isValid())
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
return getCsvRows();
|
return getCsvRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
int CsvParserModel::columnCount(const QModelIndex &parent) const {
|
int CsvParserModel::columnCount(const QModelIndex &parent) const {
|
||||||
if (parent.isValid()) {
|
if (parent.isValid())
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
return m_columnHeader.size();
|
return m_columnHeader.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant CsvParserModel::data(const QModelIndex &index, int role) const {
|
QVariant CsvParserModel::data(const QModelIndex &index, int role) const {
|
||||||
if ( (index.column() >= m_columnHeader.size())
|
if ((index.column() >= m_columnHeader.size())
|
||||||
|| (index.row()+m_skipped >= rowCount())
|
|| (index.row()+m_skipped >= rowCount())
|
||||||
|| !index.isValid() )
|
|| !index.isValid()) {
|
||||||
{
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
if (role == Qt::DisplayRole)
|
||||||
if (role == Qt::DisplayRole) {
|
|
||||||
return m_table.at(index.row()+m_skipped).at(m_columnMap[index.column()]);
|
return m_table.at(index.row()+m_skipped).at(m_columnMap[index.column()]);
|
||||||
}
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant CsvParserModel::headerData(int section, Qt::Orientation orientation, int role) const {
|
QVariant CsvParserModel::headerData(int section, Qt::Orientation orientation, int role) const {
|
||||||
if (role == Qt::DisplayRole) {
|
if (role == Qt::DisplayRole) {
|
||||||
if (orientation == Qt::Horizontal) {
|
if (orientation == Qt::Horizontal) {
|
||||||
if ( (section < 0) || (section >= m_columnHeader.size())) {
|
if ((section < 0) || (section >= m_columnHeader.size()))
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
|
||||||
return m_columnHeader.at(section);
|
return m_columnHeader.at(section);
|
||||||
}
|
} else if (orientation == Qt::Vertical) {
|
||||||
else if (orientation == Qt::Vertical) {
|
if (section+m_skipped >= rowCount())
|
||||||
if (section+m_skipped >= rowCount()) {
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
|
||||||
return QString::number(section+1);
|
return QString::number(section+1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,9 @@
|
|||||||
|
|
||||||
#include <QAbstractTableModel>
|
#include <QAbstractTableModel>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include "core/Group.h"
|
|
||||||
#include "core/CsvParser.h"
|
#include "core/CsvParser.h"
|
||||||
|
#include "core/Group.h"
|
||||||
|
|
||||||
class CsvParserModel : public QAbstractTableModel, public CsvParser
|
class CsvParserModel : public QAbstractTableModel, public CsvParser
|
||||||
{
|
{
|
||||||
@ -29,7 +30,7 @@ class CsvParserModel : public QAbstractTableModel, public CsvParser
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CsvParserModel(QObject *parent = nullptr);
|
explicit CsvParserModel(QObject *parent = nullptr);
|
||||||
virtual ~CsvParserModel();
|
~CsvParserModel();
|
||||||
void setFilename(const QString& filename);
|
void setFilename(const QString& filename);
|
||||||
QString getFileInfo();
|
QString getFileInfo();
|
||||||
bool parse();
|
bool parse();
|
||||||
@ -37,10 +38,10 @@ public:
|
|||||||
void setHeaderLabels(QStringList l);
|
void setHeaderLabels(QStringList l);
|
||||||
void mapColumns(int csvColumn, int dbColumn);
|
void mapColumns(int csvColumn, int dbColumn);
|
||||||
|
|
||||||
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
virtual int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const Q_DECL_OVERRIDE;
|
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void setSkippedRows(int skipped);
|
void setSkippedRows(int skipped);
|
||||||
|
@ -62,8 +62,8 @@ private Q_SLOTS:
|
|||||||
private:
|
private:
|
||||||
QFile file;
|
QFile file;
|
||||||
CsvParser* parser;
|
CsvParser* parser;
|
||||||
csvtable t;
|
CsvTable t;
|
||||||
void dumpRow(csvtable table, int row);
|
void dumpRow(CsvTable table, int row);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // KEEPASSX_TESTCSVPARSER_H
|
#endif // KEEPASSX_TESTCSVPARSER_H
|
||||||
|
Loading…
x
Reference in New Issue
Block a user