Commit f1129f62c610106a0099c1421a64df6239b1449e
1 parent
5f6ac8ad
Started working on better csv gallery
Showing
1 changed file
with
146 additions
and
19 deletions
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; j<headers.size(); j++) | ||
| 97 | + if (headers[j].contains("_")) { | ||
| 98 | + const QStringList subKeys = headers[j].split("_"); | ||
| 99 | + if (subKeys.first() == header.key) { | ||
| 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,25 @@ class csvGallery : public FileGallery | @@ -64,6 +157,25 @@ 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 | + qDebug() << headers.keys(); | ||
| 163 | + | ||
| 164 | + foreach (const CSVHeader &header, headers) { | ||
| 165 | + qDebug() << header.key; | ||
| 166 | + if (header.indices.size() == 1) | ||
| 167 | + f.set(header.key, values[header.indices.first()]); | ||
| 168 | + else if (header.indices.size() == 2) // QPointF | ||
| 169 | + f.appendPoint(QPointF(values[header.indices[header.subKeys.indexOf("X")]].toFloat(), | ||
| 170 | + values[header.indices[header.subKeys.indexOf("Y")]].toFloat())); | ||
| 171 | + else if (header.indices.size() == 4) // QRectF | ||
| 172 | + f.appendRect(QRectF(values[header.indices[header.subKeys.indexOf("X")]].toFloat(), | ||
| 173 | + values[header.indices[header.subKeys.indexOf("Y")]].toFloat(), | ||
| 174 | + values[header.indices[header.subKeys.indexOf("Width")]].toFloat(), | ||
| 175 | + values[header.indices[header.subKeys.indexOf("Height")]].toFloat())); | ||
| 176 | + } | ||
| 177 | + } | ||
| 178 | + | ||
| 67 | TemplateList readBlock(bool *done) | 179 | TemplateList readBlock(bool *done) |
| 68 | { | 180 | { |
| 69 | readOpen(); | 181 | readOpen(); |
| @@ -79,22 +191,37 @@ class csvGallery : public FileGallery | @@ -79,22 +191,37 @@ class csvGallery : public FileGallery | ||
| 79 | QByteArray lineBytes = f.readLine(); | 191 | QByteArray lineBytes = f.readLine(); |
| 80 | QString line = QString::fromLocal8Bit(lineBytes).trimmed(); | 192 | QString line = QString::fromLocal8Bit(lineBytes).trimmed(); |
| 81 | QRegExp regexp("\\s*,\\s*"); | 193 | QRegExp regexp("\\s*,\\s*"); |
| 82 | - headers = line.split(regexp); | 194 | + headers = CSVHeaderList::fromHeaders(line.split(regexp).mid(1)); |
| 83 | } | 195 | } |
| 84 | 196 | ||
| 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; | 197 | + if (combineFiles) { |
| 198 | + *done = true; | ||
| 199 | + QMap<QString, File> combinedFiles; | ||
| 200 | + | ||
| 201 | + for (qint64 i = 0; i < !f.atEnd(); i++) { | ||
| 202 | + const QVariantList values = parseLine(f.readLine()); | ||
| 203 | + const QString name = values.first().toString(); | ||
| 204 | + File &in = combinedFiles[name]; | ||
| 205 | + in.name = name; | ||
| 206 | + setValuesFromHeaders(in, headers, values.mid(1)); | ||
| 207 | + } | ||
| 88 | 208 | ||
| 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); | 209 | + qDebug() << combinedFiles.values(); |
| 210 | + foreach (const File &in, combinedFiles.values()) | ||
| 211 | + templates.append(in); | ||
| 212 | + } else { | ||
| 213 | + for (qint64 i = 0; i < this->readBlockSize && !f.atEnd(); i++) { | ||
| 214 | + const QVariantList values = parseLine(f.readLine()); | ||
| 215 | + | ||
| 216 | + File in; | ||
| 217 | + in.name = values.first().toString(); | ||
| 218 | + setValuesFromHeaders(in, headers, values.mid(1)); | ||
| 219 | + in.set("progress", f.pos()); | ||
| 220 | + templates.append(in); | ||
| 221 | + } | ||
| 222 | + *done = f.atEnd(); | ||
| 96 | } | 223 | } |
| 97 | - *done = f.atEnd(); | 224 | + |
| 98 | return templates; | 225 | return templates; |
| 99 | } | 226 | } |
| 100 | 227 | ||
| @@ -104,10 +231,10 @@ class csvGallery : public FileGallery | @@ -104,10 +231,10 @@ class csvGallery : public FileGallery | ||
| 104 | writeOpen(); | 231 | writeOpen(); |
| 105 | if (headers.isEmpty()) { | 232 | if (headers.isEmpty()) { |
| 106 | foreach (const QString &key, t.file.localKeys()) | 233 | foreach (const QString &key, t.file.localKeys()) |
| 107 | - headers.append(key); | 234 | + headers.append(CSVHeader(key)); |
| 108 | 235 | ||
| 109 | headers.sort(); | 236 | headers.sort(); |
| 110 | - const QString header = QString(QStringList(QStringList("File") + headers).join(",") + "\n"); | 237 | + const QString header = QString(QStringList(QStringList("File") + headers.keys()).join(",") + "\n"); |
| 111 | f.write(header.toLocal8Bit()); | 238 | f.write(header.toLocal8Bit()); |
| 112 | } | 239 | } |
| 113 | f.write(QString(lineFromFile(t.file) + "\n").toLocal8Bit()); | 240 | f.write(QString(lineFromFile(t.file) + "\n").toLocal8Bit()); |
| @@ -119,7 +246,7 @@ class csvGallery : public FileGallery | @@ -119,7 +246,7 @@ class csvGallery : public FileGallery | ||
| 119 | { | 246 | { |
| 120 | QStringList words; | 247 | QStringList words; |
| 121 | words.append(file.name); | 248 | words.append(file.name); |
| 122 | - foreach (const QString &key, headers) { | 249 | + foreach (const QString &key, headers.keys()) { |
| 123 | QString value = QtUtils::toString(file.value(key)); | 250 | QString value = QtUtils::toString(file.value(key)); |
| 124 | if (value.contains(",")) | 251 | if (value.contains(",")) |
| 125 | value = '"' + value + '"'; | 252 | value = '"' + value + '"'; |