Commit 579362d55fb1f1442efb009697e55d95c125f705
Merge branch 'csv'
Showing
5 changed files
with
194 additions
and
72 deletions
openbr/core/evalutils.cpp
| @@ -263,7 +263,7 @@ QStringList EvalUtils::computeDetectionResults(const QList<ResolvedDetection> &d | @@ -263,7 +263,7 @@ QStringList EvalUtils::computeDetectionResults(const QList<ResolvedDetection> &d | ||
| 263 | debug << QString("|") << QString::number(FAR, 'f', 4).leftJustified(10, ' '); | 263 | debug << QString("|") << QString::number(FAR, 'f', 4).leftJustified(10, ' '); |
| 264 | debug << QString("|") << QString::number(TP / totalTrueDetections, 'f', 4).leftJustified(10, ' '); | 264 | debug << QString("|") << QString::number(TP / totalTrueDetections, 'f', 4).leftJustified(10, ' '); |
| 265 | debug << QString("|") << QString::number(detection.confidence, 'f', 4).leftJustified(10, ' '); | 265 | debug << QString("|") << QString::number(detection.confidence, 'f', 4).leftJustified(10, ' '); |
| 266 | - debug << QString("|") << QString::number(poseMatch / TP, 'f', 4).leftJustified(10, ' '); | 266 | + debug << QString("|") << QString::number(TP ? poseMatch / TP : 0., 'f', 4).leftJustified(10, ' '); |
| 267 | debug << QString("|") << endl; | 267 | debug << QString("|") << endl; |
| 268 | break; | 268 | break; |
| 269 | } | 269 | } |
openbr/core/qtutils.cpp
| @@ -172,12 +172,20 @@ QString find(const QString &file, const QString &alt) | @@ -172,12 +172,20 @@ QString find(const QString &file, const QString &alt) | ||
| 172 | return ""; | 172 | return ""; |
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | -bool toBool(const QString &string) | 175 | +bool toBool(const QString &string, bool *ok) |
| 176 | { | 176 | { |
| 177 | - bool ok; | ||
| 178 | - bool result = (string.toFloat(&ok) != 0.f); | ||
| 179 | - if (ok) return result; | ||
| 180 | - else return (string != "FALSE") && (string != "false") && (string != "F") && (string != "f"); | 177 | + bool floatOk; |
| 178 | + bool result = (string.toFloat(&floatOk) != 0.f); | ||
| 179 | + if (floatOk) { | ||
| 180 | + if (ok) *ok = true; | ||
| 181 | + return result; | ||
| 182 | + } else { | ||
| 183 | + if (ok) *ok = (string.compare("false", Qt::CaseInsensitive) == 0 || | ||
| 184 | + string.compare("true", Qt::CaseInsensitive) == 0 || | ||
| 185 | + string.compare("f", Qt::CaseInsensitive) == 0 || | ||
| 186 | + string.compare("t", Qt::CaseInsensitive) == 0); | ||
| 187 | + return (string.compare("false", Qt::CaseInsensitive) != 0 && string.compare("f", Qt::CaseInsensitive) != 0); | ||
| 188 | + } | ||
| 181 | } | 189 | } |
| 182 | 190 | ||
| 183 | int toInt(const QString &string) | 191 | int toInt(const QString &string) |
| @@ -245,10 +253,10 @@ QStringList parse(QString args, char split, bool *ok) | @@ -245,10 +253,10 @@ QStringList parse(QString args, char split, bool *ok) | ||
| 245 | QStack<QChar> subexpressions; | 253 | QStack<QChar> subexpressions; |
| 246 | for (int i=0; i<args.size(); i++) { | 254 | for (int i=0; i<args.size(); i++) { |
| 247 | if (inQuote) { | 255 | if (inQuote) { |
| 248 | - if (args[i] == '\'') | 256 | + if (args[i] == '\'' || args[i] == '\"') |
| 249 | inQuote = false; | 257 | inQuote = false; |
| 250 | } else { | 258 | } else { |
| 251 | - if (args[i] == '\'') { | 259 | + if (args[i] == '\'' || args[i] == '\"') { |
| 252 | inQuote = true; | 260 | inQuote = true; |
| 253 | } else if ((args[i] == '(') || (args[i] == '[') || (args[i] == '<') || (args[i] == '{')) { | 261 | } else if ((args[i] == '(') || (args[i] == '[') || (args[i] == '<') || (args[i] == '{')) { |
| 254 | subexpressions.push(args[i]); | 262 | subexpressions.push(args[i]); |
| @@ -277,7 +285,10 @@ QStringList parse(QString args, char split, bool *ok) | @@ -277,7 +285,10 @@ QStringList parse(QString args, char split, bool *ok) | ||
| 277 | return words; | 285 | return words; |
| 278 | } | 286 | } |
| 279 | } else if (subexpressions.isEmpty() && (args[i] == split)) { | 287 | } else if (subexpressions.isEmpty() && (args[i] == split)) { |
| 280 | - words.append(args.mid(start, i-start).trimmed()); | 288 | + QString word = args.mid(start, i-start).trimmed(); |
| 289 | + if (word.contains('\'') || word.contains('\"')) | ||
| 290 | + word = word.mid(1, word.size()-2); | ||
| 291 | + words.append(word); | ||
| 281 | start = i+1; | 292 | start = i+1; |
| 282 | } | 293 | } |
| 283 | } | 294 | } |
| @@ -512,6 +523,13 @@ QVariantMap fromJsonObject(const QJsonObject &object) | @@ -512,6 +523,13 @@ QVariantMap fromJsonObject(const QJsonObject &object) | ||
| 512 | 523 | ||
| 513 | QVariant fromString(const QString &value) | 524 | QVariant fromString(const QString &value) |
| 514 | { | 525 | { |
| 526 | + if (value.startsWith('[') && value.endsWith(']')) { | ||
| 527 | + QVariantList variants; | ||
| 528 | + foreach (const QString &value, QtUtils::parse(value.mid(1, value.size()-2))) | ||
| 529 | + variants.append(fromString(value)); | ||
| 530 | + return variants; | ||
| 531 | + } | ||
| 532 | + | ||
| 515 | bool ok = false; | 533 | bool ok = false; |
| 516 | const QPointF point = QtUtils::toPoint(value, &ok); | 534 | const QPointF point = QtUtils::toPoint(value, &ok); |
| 517 | if (ok) return point; | 535 | if (ok) return point; |
| @@ -523,6 +541,8 @@ QVariant fromString(const QString &value) | @@ -523,6 +541,8 @@ QVariant fromString(const QString &value) | ||
| 523 | if (ok) return i; | 541 | if (ok) return i; |
| 524 | const float f = value.toFloat(&ok); | 542 | const float f = value.toFloat(&ok); |
| 525 | if (ok) return f; | 543 | if (ok) return f; |
| 544 | + const bool b = QtUtils::toBool(value, &ok); | ||
| 545 | + if (ok) return b; | ||
| 526 | return value; | 546 | return value; |
| 527 | } | 547 | } |
| 528 | 548 |
openbr/core/qtutils.h
| @@ -56,7 +56,7 @@ namespace QtUtils | @@ -56,7 +56,7 @@ namespace QtUtils | ||
| 56 | QString getAbsolutePath(const QString &filename); | 56 | QString getAbsolutePath(const QString &filename); |
| 57 | 57 | ||
| 58 | /**** String Utilities ****/ | 58 | /**** String Utilities ****/ |
| 59 | - bool toBool(const QString &string); | 59 | + bool toBool(const QString &string, bool *ok = NULL); |
| 60 | int toInt(const QString &string); | 60 | int toInt(const QString &string); |
| 61 | float toFloat(const QString &string); | 61 | float toFloat(const QString &string); |
| 62 | QList<float> toFloats(const QStringList &strings); | 62 | QList<float> toFloats(const QStringList &strings); |
openbr/openbr_plugin.cpp
| @@ -156,30 +156,12 @@ QVariant File::value(const QString &key) const | @@ -156,30 +156,12 @@ QVariant File::value(const QString &key) const | ||
| 156 | 156 | ||
| 157 | QVariant File::parse(const QString &value) | 157 | QVariant File::parse(const QString &value) |
| 158 | { | 158 | { |
| 159 | - bool ok = false; | ||
| 160 | - const QPointF point = QtUtils::toPoint(value, &ok); | ||
| 161 | - if (ok) return point; | ||
| 162 | - const QRectF rect = QtUtils::toRect(value, &ok); | ||
| 163 | - if (ok) return rect; | ||
| 164 | - const cv::RotatedRect rotatedRect = OpenCVUtils::rotateRectFromString(value, &ok); | ||
| 165 | - if (ok) return QVariant::fromValue(rotatedRect); | ||
| 166 | - const int i = value.toInt(&ok); | ||
| 167 | - if (ok) return i; | ||
| 168 | - const float f = value.toFloat(&ok); | ||
| 169 | - if (ok) return f; | ||
| 170 | - return value; | 159 | + return QtUtils::fromString(value); |
| 171 | } | 160 | } |
| 172 | 161 | ||
| 173 | void File::set(const QString &key, const QString &value) | 162 | void File::set(const QString &key, const QString &value) |
| 174 | { | 163 | { |
| 175 | - if (value.startsWith('[') && value.endsWith(']')) { | ||
| 176 | - QVariantList variants; | ||
| 177 | - foreach (const QString &value, QtUtils::parse(value.mid(1, value.size()-2))) | ||
| 178 | - variants.append(parse(value)); | ||
| 179 | - set(key, variants); | ||
| 180 | - } else { | ||
| 181 | - set(key, QVariant(parse(value))); | ||
| 182 | - } | 164 | + set(key, QtUtils::fromString(value)); |
| 183 | } | 165 | } |
| 184 | 166 | ||
| 185 | bool File::getBool(const QString &key, bool defaultValue) const | 167 | bool File::getBool(const QString &key, bool defaultValue) const |
openbr/plugins/gallery/csv.cpp
| @@ -16,10 +16,101 @@ | @@ -16,10 +16,101 @@ | ||
| 16 | 16 | ||
| 17 | #include <openbr/plugins/openbr_internal.h> | 17 | #include <openbr/plugins/openbr_internal.h> |
| 18 | #include <openbr/core/qtutils.h> | 18 | #include <openbr/core/qtutils.h> |
| 19 | +#include <openbr/core/common.h> | ||
| 19 | 20 | ||
| 20 | namespace br | 21 | namespace br |
| 21 | { | 22 | { |
| 22 | 23 | ||
| 24 | +struct CSVHeader | ||
| 25 | +{ | ||
| 26 | + QList<int> indices; | ||
| 27 | + | ||
| 28 | + CSVHeader() | ||
| 29 | + {} | ||
| 30 | + | ||
| 31 | + CSVHeader(const QString &key) | ||
| 32 | + : key(key) | ||
| 33 | + {} | ||
| 34 | + | ||
| 35 | + QString key; | ||
| 36 | + QStringList subKeys; | ||
| 37 | +}; | ||
| 38 | + | ||
| 39 | +class CSVHeaderList : public QList<CSVHeader> | ||
| 40 | +{ | ||
| 41 | +public: | ||
| 42 | + CSVHeaderList() | ||
| 43 | + {} | ||
| 44 | + | ||
| 45 | + CSVHeaderList(const QList<CSVHeader> &headers) | ||
| 46 | + { | ||
| 47 | + foreach (const CSVHeader &header, headers) | ||
| 48 | + append(header); | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + CSVHeaderList(const QStringList &keys) | ||
| 52 | + { | ||
| 53 | + foreach (const QString &key, keys) | ||
| 54 | + append(CSVHeader(key)); | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | + void sort() | ||
| 58 | + { | ||
| 59 | + typedef QPair<QString, int> IndexPair; | ||
| 60 | + QList<IndexPair> sortedKeys = Common::Sort(keys()); | ||
| 61 | + | ||
| 62 | + CSVHeaderList sortedList; | ||
| 63 | + foreach (const IndexPair sortedKey, sortedKeys) | ||
| 64 | + sortedList.append((*this)[sortedKey.second]); | ||
| 65 | + *this = sortedList; | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + QStringList keys() const | ||
| 69 | + { | ||
| 70 | + QStringList keys; | ||
| 71 | + for (int i=0; i<this->size(); i++) | ||
| 72 | + keys.append((*this)[i].key); | ||
| 73 | + return keys; | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + static CSVHeaderList fromHeaders(const QStringList &headers) | ||
| 77 | + { | ||
| 78 | + CSVHeaderList csvHeaders; | ||
| 79 | + QStringList processedKeys; | ||
| 80 | + | ||
| 81 | + for (int i=0; i<headers.size(); i++) { | ||
| 82 | + CSVHeader header; | ||
| 83 | + if (headers[i].contains("_")) { | ||
| 84 | + const QStringList subKeys = headers[i].split("_"); | ||
| 85 | + header.key = subKeys.first(); | ||
| 86 | + | ||
| 87 | + if (processedKeys.contains(header.key)) | ||
| 88 | + continue; | ||
| 89 | + else | ||
| 90 | + processedKeys.append(header.key); | ||
| 91 | + | ||
| 92 | + header.subKeys.append(subKeys.last()); | ||
| 93 | + header.indices.append(i); | ||
| 94 | + | ||
| 95 | + // Look for other subheaders with the same key | ||
| 96 | + for (int j=i+1; j<headers.size(); j++) | ||
| 97 | + if (headers[j].contains("_")) { | ||
| 98 | + const QStringList subKeys = headers[j].split("_"); | ||
| 99 | + if (subKeys.first() == header.key && !header.subKeys.contains(subKeys.last()) /* Check for ill-formed csvs */) { | ||
| 100 | + header.indices.append(j); | ||
| 101 | + header.subKeys.append(subKeys.last()); | ||
| 102 | + } | ||
| 103 | + } | ||
| 104 | + } else { | ||
| 105 | + header.key = headers[i]; | ||
| 106 | + header.indices.append(i); | ||
| 107 | + } | ||
| 108 | + csvHeaders.append(header); | ||
| 109 | + } | ||
| 110 | + return csvHeaders; | ||
| 111 | + } | ||
| 112 | +}; | ||
| 113 | + | ||
| 23 | /*! | 114 | /*! |
| 24 | * \ingroup galleries | 115 | * \ingroup galleries |
| 25 | * \brief Treats each line as a file. | 116 | * \brief Treats each line as a file. |
| @@ -35,10 +126,12 @@ class csvGallery : public FileGallery | @@ -35,10 +126,12 @@ class csvGallery : public FileGallery | ||
| 35 | Q_OBJECT | 126 | Q_OBJECT |
| 36 | Q_PROPERTY(bool inPlace READ get_inPlace WRITE set_inPlace RESET reset_inPlace STORED false) | 127 | Q_PROPERTY(bool inPlace READ get_inPlace WRITE set_inPlace RESET reset_inPlace STORED false) |
| 37 | BR_PROPERTY(bool, inPlace, false) | 128 | BR_PROPERTY(bool, inPlace, false) |
| 129 | + Q_PROPERTY(bool combineFiles READ get_combineFiles WRITE set_combineFiles RESET reset_combineFiles STORED false) | ||
| 130 | + BR_PROPERTY(bool, combineFiles, false) | ||
| 38 | 131 | ||
| 39 | FileList files; | 132 | FileList files; |
| 40 | - QStringList headers; | ||
| 41 | - | 133 | + CSVHeaderList headers; |
| 134 | + | ||
| 42 | ~csvGallery() | 135 | ~csvGallery() |
| 43 | { | 136 | { |
| 44 | f.close(); | 137 | f.close(); |
| @@ -53,9 +146,9 @@ class csvGallery : public FileGallery | @@ -53,9 +146,9 @@ class csvGallery : public FileGallery | ||
| 53 | lines.reserve(files.size()+1); | 146 | lines.reserve(files.size()+1); |
| 54 | 147 | ||
| 55 | // Make header | 148 | // Make header |
| 56 | - headers = samples.values(); | 149 | + headers = CSVHeaderList(samples.values()); |
| 57 | headers.sort(); | 150 | headers.sort(); |
| 58 | - lines.append(QStringList(QStringList("File") + headers).join(",")); | 151 | + lines.append(QStringList(QStringList("File") + headers.keys()).join(",")); |
| 59 | 152 | ||
| 60 | // Make table | 153 | // Make table |
| 61 | foreach (const File &file, files) | 154 | foreach (const File &file, files) |
| @@ -64,6 +157,37 @@ class csvGallery : public FileGallery | @@ -64,6 +157,37 @@ class csvGallery : public FileGallery | ||
| 64 | QtUtils::writeFile(file, lines); | 157 | QtUtils::writeFile(file, lines); |
| 65 | } | 158 | } |
| 66 | 159 | ||
| 160 | + void setValuesFromHeaders(File &f, const CSVHeaderList &headers, const QVariantList &values) | ||
| 161 | + { | ||
| 162 | + foreach (const CSVHeader &header, headers) { | ||
| 163 | + if (header.indices.size() == 1) { | ||
| 164 | + if (header.key == "Rects") | ||
| 165 | + foreach(const QVariant &rect, values[header.indices.first()].toList()) | ||
| 166 | + f.appendRect(rect.toRectF()); | ||
| 167 | + else if (header.key == "Points") | ||
| 168 | + foreach(const QVariant &point, values[header.indices.first()].toList()) | ||
| 169 | + f.appendPoint(point.toPointF()); | ||
| 170 | + else { | ||
| 171 | + const QVariant value = values[header.indices.first()]; | ||
| 172 | + if (!value.canConvert<QString>() || !value.toString().isEmpty()) | ||
| 173 | + f.set(header.key, values[header.indices.first()]); | ||
| 174 | + } | ||
| 175 | + } else if (header.indices.size() == 2) { // QPointF | ||
| 176 | + const QPointF point(values[header.indices[header.subKeys.indexOf("X")]].toFloat(), | ||
| 177 | + values[header.indices[header.subKeys.indexOf("Y")]].toFloat()); | ||
| 178 | + f.set(header.key, point); | ||
| 179 | + f.appendPoint(point); | ||
| 180 | + } else if (header.indices.size() == 4) { // QRectF | ||
| 181 | + const QRectF rect(values[header.indices[header.subKeys.indexOf("X")]].toFloat(), | ||
| 182 | + values[header.indices[header.subKeys.indexOf("Y")]].toFloat(), | ||
| 183 | + values[header.indices[header.subKeys.indexOf("Width")]].toFloat(), | ||
| 184 | + values[header.indices[header.subKeys.indexOf("Height")]].toFloat()); | ||
| 185 | + f.set(header.key, rect); | ||
| 186 | + f.appendRect(rect); | ||
| 187 | + } | ||
| 188 | + } | ||
| 189 | + } | ||
| 190 | + | ||
| 67 | TemplateList readBlock(bool *done) | 191 | TemplateList readBlock(bool *done) |
| 68 | { | 192 | { |
| 69 | readOpen(); | 193 | readOpen(); |
| @@ -79,22 +203,41 @@ class csvGallery : public FileGallery | @@ -79,22 +203,41 @@ class csvGallery : public FileGallery | ||
| 79 | QByteArray lineBytes = f.readLine(); | 203 | QByteArray lineBytes = f.readLine(); |
| 80 | QString line = QString::fromLocal8Bit(lineBytes).trimmed(); | 204 | QString line = QString::fromLocal8Bit(lineBytes).trimmed(); |
| 81 | QRegExp regexp("\\s*,\\s*"); | 205 | QRegExp regexp("\\s*,\\s*"); |
| 82 | - headers = line.split(regexp); | 206 | + headers = CSVHeaderList::fromHeaders(line.split(regexp).mid(1)); |
| 83 | } | 207 | } |
| 84 | 208 | ||
| 85 | - for (qint64 i = 0; i < this->readBlockSize && !f.atEnd(); i++) { | ||
| 86 | - const QVariantList values = parseLine(f.readLine()); | ||
| 87 | - if (values.size() != headers.size()) continue; | 209 | + if (combineFiles) { |
| 210 | + *done = true; | ||
| 211 | + QMap<QString, File> combinedFiles; | ||
| 212 | + | ||
| 213 | + while (!f.atEnd()) { | ||
| 214 | + QVariantList values; | ||
| 215 | + foreach (const QString &value, QtUtils::parse(f.readLine(), ',')) | ||
| 216 | + values.append(QtUtils::fromString(value)); | ||
| 88 | 217 | ||
| 89 | - File in; | ||
| 90 | - for (int j=0; j<values.size(); j++) { | ||
| 91 | - if (j == 0) in.name = values[j].toString(); | ||
| 92 | - else in.set(headers[j], values[j].toString()); | ||
| 93 | - } | ||
| 94 | - in.set("progress", f.pos()); | ||
| 95 | - templates.append(in); | 218 | + const QString name = values.first().toString(); |
| 219 | + File &in = combinedFiles[name]; | ||
| 220 | + in.name = name; | ||
| 221 | + setValuesFromHeaders(in, headers, values.mid(1)); | ||
| 222 | + } | ||
| 223 | + | ||
| 224 | + foreach (const File &in, combinedFiles.values()) | ||
| 225 | + templates.append(in); | ||
| 226 | + } else { | ||
| 227 | + for (qint64 i = 0; i < this->readBlockSize && !f.atEnd(); i++) { | ||
| 228 | + QVariantList values; | ||
| 229 | + foreach (const QString &value, QtUtils::parse(f.readLine(), ',')) | ||
| 230 | + values.append(QtUtils::fromString(value)); | ||
| 231 | + | ||
| 232 | + File in; | ||
| 233 | + in.name = values.first().toString(); | ||
| 234 | + setValuesFromHeaders(in, headers, values.mid(1)); | ||
| 235 | + in.set("progress", f.pos()); | ||
| 236 | + templates.append(in); | ||
| 237 | + } | ||
| 238 | + *done = f.atEnd(); | ||
| 96 | } | 239 | } |
| 97 | - *done = f.atEnd(); | 240 | + |
| 98 | return templates; | 241 | return templates; |
| 99 | } | 242 | } |
| 100 | 243 | ||
| @@ -104,10 +247,10 @@ class csvGallery : public FileGallery | @@ -104,10 +247,10 @@ class csvGallery : public FileGallery | ||
| 104 | writeOpen(); | 247 | writeOpen(); |
| 105 | if (headers.isEmpty()) { | 248 | if (headers.isEmpty()) { |
| 106 | foreach (const QString &key, t.file.localKeys()) | 249 | foreach (const QString &key, t.file.localKeys()) |
| 107 | - headers.append(key); | 250 | + headers.append(CSVHeader(key)); |
| 108 | 251 | ||
| 109 | headers.sort(); | 252 | headers.sort(); |
| 110 | - const QString header = QString(QStringList(QStringList("File") + headers).join(",") + "\n"); | 253 | + const QString header = QString(QStringList(QStringList("File") + headers.keys()).join(",") + "\n"); |
| 111 | f.write(header.toLocal8Bit()); | 254 | f.write(header.toLocal8Bit()); |
| 112 | } | 255 | } |
| 113 | f.write(QString(lineFromFile(t.file) + "\n").toLocal8Bit()); | 256 | f.write(QString(lineFromFile(t.file) + "\n").toLocal8Bit()); |
| @@ -119,7 +262,7 @@ class csvGallery : public FileGallery | @@ -119,7 +262,7 @@ class csvGallery : public FileGallery | ||
| 119 | { | 262 | { |
| 120 | QStringList words; | 263 | QStringList words; |
| 121 | words.append(file.name); | 264 | words.append(file.name); |
| 122 | - foreach (const QString &key, headers) { | 265 | + foreach (const QString &key, headers.keys()) { |
| 123 | QString value = QtUtils::toString(file.value(key)); | 266 | QString value = QtUtils::toString(file.value(key)); |
| 124 | if (value.contains(",")) | 267 | if (value.contains(",")) |
| 125 | value = '"' + value + '"'; | 268 | value = '"' + value + '"'; |
| @@ -127,29 +270,6 @@ class csvGallery : public FileGallery | @@ -127,29 +270,6 @@ class csvGallery : public FileGallery | ||
| 127 | } | 270 | } |
| 128 | return words.join(","); | 271 | return words.join(","); |
| 129 | } | 272 | } |
| 130 | - | ||
| 131 | - static QVariantList parseLine(const QByteArray bytes) | ||
| 132 | - { | ||
| 133 | - bool inQuote(false); | ||
| 134 | - QVariantList values; | ||
| 135 | - QString value = QString(); | ||
| 136 | - const QString line = QString::fromLocal8Bit(bytes).trimmed(); | ||
| 137 | - for (int i=0; i<line.size(); i++) { | ||
| 138 | - const QChar c = line[i]; | ||
| 139 | - if (c == '"') { | ||
| 140 | - inQuote = !inQuote; | ||
| 141 | - continue; | ||
| 142 | - } else if (c == ',' && !inQuote) { | ||
| 143 | - values.append(QVariant(value)); | ||
| 144 | - value = QString(); | ||
| 145 | - } else | ||
| 146 | - value.append(c); | ||
| 147 | - } | ||
| 148 | - if (!value.isEmpty()) | ||
| 149 | - values.append(QVariant(value)); | ||
| 150 | - | ||
| 151 | - return values; | ||
| 152 | - } | ||
| 153 | }; | 273 | }; |
| 154 | 274 | ||
| 155 | BR_REGISTER(Gallery, csvGallery) | 275 | BR_REGISTER(Gallery, csvGallery) |