Subversion Repositories Scribus

Rev

Rev 19104 | Rev 20810 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4430 cbradney 1
/*
2
For general Scribus (>=1.3.2) copyright and licensing information please refer
3
to the COPYING file provided with the program. Following this notice may exist
4
a copyright and/or license notice that predates the release of Scribus 1.3.2
5
for which a new license (GPL+exception) is in place.
6
*/
375 Franz 7
#include "csvim.h"
13805 jghali 8
#include "gtwriter.h"
9
#include "gtparagraphstyle.h"
10
#include "gtframestyle.h"
2986 craig 11
#include "scribusstructs.h"
15117 cbradney 12
#include "util.h"
375 Franz 13
 
14
QString FileFormatName()
15
{
16
    return QObject::tr("Comma Separated Value Files");
17
}
18
 
19
QStringList FileExtensions()
20
{
21
    return QStringList("csv");
22
}
23
 
2501 fschmid 24
void GetText(QString filename, QString encoding, bool /* textOnly */, gtWriter *writer)
375 Franz 25
{
26
        CsvDialog* csvdia = new CsvDialog();
27
        if (csvdia->exec())
28
        {
29
                CsvIm *cim = new CsvIm(filename, encoding, writer, csvdia->getFDelim(), csvdia->getVDelim(),
30
                               csvdia->hasHeader(), csvdia->useVDelim());
31
                cim->write();
32
                delete cim;
33
        }
34
        delete csvdia;
35
}
36
 
37
/******* Class CsvIm **************************************************************/
38
 
39
CsvIm::CsvIm(const QString& fname, const QString& enc, gtWriter *w,
40
             const QString& fdelim, const QString& vdelim, bool header, bool usevdelim)
41
{
42
        fieldDelimiter = fdelim;
43
        valueDelimiter = vdelim;
44
        hasHeader = header;
380 Franz 45
        useVDelim = usevdelim;
375 Franz 46
        filename = fname;
47
        encoding = enc;
48
        writer = w;
49
        header = "";
50
        data = "";
51
        rowNumber = 0;
52
        colIndex = 0;
53
        colCount = 0;
54
        setupPStyles();
55
        loadFile();
56
        setupTabulators();
57
}
58
 
59
void CsvIm::setupPStyles()
60
{
61
        pstyleData = new gtParagraphStyle(*(writer->getDefaultStyle()));
62
        pstyleData->setName(writer->getFrameName() + "-" + QObject::tr("CSV_data"));
63
        if (hasHeader)
64
        {
65
                pstyleHeader = new gtParagraphStyle(*pstyleData);
66
                pstyleHeader->setName(writer->getFrameName() + "-" + QObject::tr("CSV_header"));
67
                pstyleHeader->setSpaceBelow(7.0);
68
                int size = pstyleData->getFont()->getSize();
69
                size += 10;
70
                pstyleHeader->getFont()->setSize(size);
71
                pstyleHeader->getFont()->setWeight(BOLD);
72
        }
73
        else
74
                pstyleHeader = NULL;
75
}
76
 
77
void CsvIm::setFieldDelimiter(const QString& fdelim)
78
{
79
        fieldDelimiter = fdelim;
80
}
81
 
82
void CsvIm::setValueDelimiter(const QString& vdelim)
83
{
84
        valueDelimiter = vdelim;
85
}
86
 
87
void CsvIm::write()
88
{
89
        writer->append(header, pstyleHeader);
90
        writer->append(data, pstyleData);
91
}
92
 
93
void CsvIm::loadFile()
94
{
95
        QString text = "";
15117 cbradney 96
        /*
375 Franz 97
        QFile f(filename);
98
        QFileInfo fi(f);
99
        if (!fi.exists())
100
                return;
10599 fschmid 101
        QByteArray bb(f.size(), ' ');
8501 cbradney 102
        if (f.open(QIODevice::ReadOnly))
375 Franz 103
        {
10599 fschmid 104
                f.read(bb.data(), f.size());
375 Franz 105
                f.close();
8546 cbradney 106
                for (int posi = 0; posi < bb.size(); ++posi)
3041 fschmid 107
                        text += QChar(bb[posi]);
375 Franz 108
        }
109
        text = toUnicode(text);
15117 cbradney 110
        */
111
        QByteArray rawText;
112
        if (loadRawText(filename, rawText))
113
                text = toUnicode(rawText);
114
 
10603 fschmid 115
        QStringList lines = text.split("\n", QString::SkipEmptyParts);
15117 cbradney 116
        uint i=0;
375 Franz 117
        if (hasHeader)
118
        {
119
                colIndex = 0;
120
                parseLine(lines[0], true);
121
                header += "\n";
122
                colCount = colIndex;
123
                i = 1;
124
                ++rowNumber;
125
        }
8546 cbradney 126
        for (int i2 = i; i2 < lines.size(); ++i2)
375 Franz 127
        {
128
                colIndex = 0;
379 Franz 129
                parseLine(lines[i2], false);
375 Franz 130
                data += "\n";
131
                ++rowNumber;
132
                if (colCount < colIndex)
133
                        colCount = colIndex;
134
        }
19368 craig 135
        if (data.startsWith("\t"))
136
                data.remove(0,1);
137
        data.replace("\n\t","\n");
375 Franz 138
}
139
 
140
void CsvIm::parseLine(const QString& line, bool isHeader)
141
{
10517 cbradney 142
        if ((line.indexOf(valueDelimiter) < 0) || (!useVDelim))
375 Franz 143
        {
10603 fschmid 144
                QStringList l = line.split(fieldDelimiter, QString::SkipEmptyParts);
8546 cbradney 145
                for (int i = 0; i < l.size(); ++i)
375 Franz 146
                {
147
                        ++colIndex;
10394 cbradney 148
                        QString tmp = l[i].trimmed();
375 Franz 149
                        if (isHeader)
150
                                header += "\t" + tmp;
151
                        else
152
                                data += "\t" + tmp;
153
                }
813 tsoots 154
                return; // line done
375 Franz 155
        }
19104 jghali 156
 
10517 cbradney 157
        int vdIndexStart = line.indexOf(valueDelimiter);
158
        int vdIndexEnd   = line.indexOf(valueDelimiter, vdIndexStart + 1);
813 tsoots 159
        if (vdIndexEnd < 0)
375 Franz 160
        {
161
                if (isHeader)
813 tsoots 162
                        header += "\t" + line;
375 Franz 163
                else
813 tsoots 164
                        data += "\t" + line;
19368 craig 165
                return; // error in line, no closing valuedelimiter could be found
375 Franz 166
        }
19104 jghali 167
 
10517 cbradney 168
        int fdIndex = line.indexOf(fieldDelimiter, vdIndexEnd + 1);
813 tsoots 169
        QString tmpCol = "";
19104 jghali 170
 
813 tsoots 171
        if (fdIndex < 0)
375 Franz 172
        {
813 tsoots 173
                if (vdIndexEnd < 0)
375 Franz 174
                {
405 Franz 175
                        if (isHeader)
813 tsoots 176
                                header += "\t" + line;
405 Franz 177
                        else
813 tsoots 178
                                data += "\t" + line;
405 Franz 179
                }
813 tsoots 180
                else
375 Franz 181
                {
813 tsoots 182
                        tmpCol = line.mid(vdIndexStart + 1, (vdIndexEnd - 1) - vdIndexStart);
375 Franz 183
                        if (isHeader)
813 tsoots 184
                                header += "\t" + tmpCol;
375 Franz 185
                        else
813 tsoots 186
                                data += "\t" + tmpCol;
375 Franz 187
                }
813 tsoots 188
                ++colIndex;
189
                return; // no more field delimiters left
375 Franz 190
        }
19104 jghali 191
 
813 tsoots 192
        if (fdIndex < vdIndexStart)
375 Franz 193
        {
813 tsoots 194
                tmpCol = line.mid(0, fdIndex);
375 Franz 195
                if (isHeader)
813 tsoots 196
                        header += "\t" + tmpCol;
375 Franz 197
                else
813 tsoots 198
                        data += "\t" + tmpCol;
375 Franz 199
                ++colIndex;
813 tsoots 200
                parseLine(line.mid(fdIndex + 1, line.length() - (fdIndex + 1)), isHeader);
375 Franz 201
        }
813 tsoots 202
        else if (fdIndex > vdIndexEnd)
203
        {
204
                tmpCol = line.mid(vdIndexStart + 1, (vdIndexEnd - 1) - vdIndexStart);
205
                if (isHeader)
206
                        header += "\t" + tmpCol;
207
                else
208
                        data += "\t" + tmpCol;
209
                ++colIndex;
210
                parseLine(line.mid(vdIndexEnd + 1, line.length() - (vdIndexEnd + 1)), isHeader);
211
        }
375 Franz 212
}
213
 
813 tsoots 214
 
375 Franz 215
void CsvIm::setupTabulators()
216
{
217
        double frameWidth = writer->getFrameWidth();
218
        double addition = frameWidth / (colCount + 1);
219
        double curValue = addition / 2;
379 Franz 220
        for (int i = 0; i < colCount; ++i)
375 Franz 221
        {
222
                pstyleData->setTabValue(curValue);
223
                if (pstyleHeader)
224
                        pstyleHeader->setTabValue(curValue, CENTER_T);
225
                curValue += addition;
226
        }
227
}
15117 cbradney 228
/*
375 Franz 229
QString CsvIm::toUnicode(const QString& text)
230
{
231
        QTextCodec *codec;
2877 cbradney 232
        if (encoding.isEmpty())
375 Franz 233
                codec = QTextCodec::codecForLocale();
234
        else
10599 fschmid 235
                codec = QTextCodec::codecForName(encoding.toLocal8Bit());
236
        QString dec = codec->toUnicode(text.toLocal8Bit());
375 Franz 237
        return dec;
238
}
15117 cbradney 239
*/
240
QString CsvIm::toUnicode(const QByteArray& rawText)
241
{
242
        QTextCodec *codec;
243
        if (encoding.isEmpty())
244
                codec = QTextCodec::codecForLocale();
245
        else
246
                codec = QTextCodec::codecForName(encoding.toLocal8Bit());
247
        QString unistr = codec->toUnicode(rawText);
248
        return unistr;
249
}
375 Franz 250
 
251
CsvIm::~CsvIm()
252
{
253
        delete pstyleData;
254
        delete pstyleHeader;
255
}