summaryrefslogtreecommitdiff
path: root/src/dictionary/DicCsvWriter.cpp
blob: f2a5e2eff9f9658a0940a31a31e09e954508c733 (plain)
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
#include "DicCsvWriter.h"
#include "Dictionary.h"
#include "DicRecord.h"
#include "Field.h"

#include <QTextStream>

DicCsvWriter::DicCsvWriter( const Dictionary* aDict ):
    m_dict( aDict )
    {
    }

DicCsvWriter::DicCsvWriter( const QList<DicRecord*> aEntries ):
    m_dict( NULL ), m_entries( aEntries )
    {
    }

QString DicCsvWriter::toCsvString( const CsvExportData& aExportData )
    {
    m_params = aExportData;
    if( m_params.quoteAllFields )
        m_fieldSepRegExp = QRegExp(".");  // Any character
    else
        m_fieldSepRegExp = QRegExp( m_params.fieldSeparators );   // Exact string of separators

    QChar delimiter = m_params.textDelimiter;
    QString outStr;
    QTextStream outStream( &outStr );

    // Generate list of selected fields
    m_selectedFieldNames.clear();
    if( !m_dict )   // from entries
        {
        foreach(DicRecord* entry, m_entries )
            foreach( QString fieldName, entry->getFields().keys() )
                if( !m_selectedFieldNames.contains( fieldName ) )
                    m_selectedFieldNames << fieldName;
        }
    else    // from dictionary
        {
        if( !m_params.usedCols.isEmpty() )
            foreach( int col, m_params.usedCols )
                m_selectedFieldNames << m_dict->field(col)->name();
        else    // All fields
            foreach( Field* field, m_dict->fields() )
                m_selectedFieldNames << field->name();

        }
    
    // Write column names
    if( m_params.writeColumnNames )
        {
        QStringList escapedNames;
        foreach( QString name, m_selectedFieldNames )
            {
            if( !delimiter.isNull() && name.contains( m_fieldSepRegExp ) )
                name = delimiter + name + delimiter;
            escapedNames << name;
            }
        QString header = QString( m_params.commentChar ) + " ";
        header += escapedNames.join( m_params.fieldSeparators );
        outStream << header << endl;
        }

    // For dictionary, copy entries into the local list.
    if( m_dict )
        m_entries = m_dict->getRecords();

    // Write entries
    bool lastLineWasEmpty = false;
    for( int i = 0; i < m_entries.size(); i++ )
        {
        QString curLine = dicEntryToString( m_entries.value( i ) );
        if( !(lastLineWasEmpty && curLine.isEmpty()) )   // Don't print several empty lines in a row
            outStream << curLine << endl;
        lastLineWasEmpty = curLine.isEmpty();
        }
    return outStr;
    }

QString DicCsvWriter::dicEntryToString(const DicRecord* aEntry ) const
    {
    if( !aEntry )
        return QString();

    QStringList fieldValues;    // Convert the fields map into string list. If needed, delimit text ("" or ').
    QChar delimiter = m_params.textDelimiter;
    foreach( QString key, m_selectedFieldNames )
        {
        QString value = aEntry->getFieldValue( key );
        /* If the field has embedded field separator or text delimiter (quote),
         * it must be quoted. */
        if( !delimiter.isNull() && ( value.contains( m_fieldSepRegExp ) || value.contains(delimiter) ) )
            {
            if( value.contains(delimiter) ) // Embedded text delimiter (")
                value.replace( delimiter, QString(delimiter) + delimiter ); // Escape it with double delimiter ("")
            value = delimiter + value + delimiter;
            }
        fieldValues << value;
        }
    // Remove all last empty fields
    while( !fieldValues.isEmpty() && fieldValues.last().isEmpty() )
        fieldValues.removeLast();
    QString res = fieldValues.join( m_params.fieldSeparators );

    /* FUTURE FEATURE: if( iIsCommented )
            csv.insert( 0, m_params.iCommentChar );  // Insert the comment character */
    return res;
    }