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 | 16 | |
| 17 | 17 | #include <openbr/plugins/openbr_internal.h> |
| 18 | 18 | #include <openbr/core/qtutils.h> |
| 19 | +#include <openbr/core/common.h> | |
| 19 | 20 | |
| 20 | 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 | 115 | * \ingroup galleries |
| 25 | 116 | * \brief Treats each line as a file. |
| ... | ... | @@ -35,10 +126,12 @@ class csvGallery : public FileGallery |
| 35 | 126 | Q_OBJECT |
| 36 | 127 | Q_PROPERTY(bool inPlace READ get_inPlace WRITE set_inPlace RESET reset_inPlace STORED false) |
| 37 | 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 | 132 | FileList files; |
| 40 | - QStringList headers; | |
| 41 | - | |
| 133 | + CSVHeaderList headers; | |
| 134 | + | |
| 42 | 135 | ~csvGallery() |
| 43 | 136 | { |
| 44 | 137 | f.close(); |
| ... | ... | @@ -53,9 +146,9 @@ class csvGallery : public FileGallery |
| 53 | 146 | lines.reserve(files.size()+1); |
| 54 | 147 | |
| 55 | 148 | // Make header |
| 56 | - headers = samples.values(); | |
| 149 | + headers = CSVHeaderList(samples.values()); | |
| 57 | 150 | headers.sort(); |
| 58 | - lines.append(QStringList(QStringList("File") + headers).join(",")); | |
| 151 | + lines.append(QStringList(QStringList("File") + headers.keys()).join(",")); | |
| 59 | 152 | |
| 60 | 153 | // Make table |
| 61 | 154 | foreach (const File &file, files) |
| ... | ... | @@ -64,6 +157,25 @@ class csvGallery : public FileGallery |
| 64 | 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 | 179 | TemplateList readBlock(bool *done) |
| 68 | 180 | { |
| 69 | 181 | readOpen(); |
| ... | ... | @@ -79,22 +191,37 @@ class csvGallery : public FileGallery |
| 79 | 191 | QByteArray lineBytes = f.readLine(); |
| 80 | 192 | QString line = QString::fromLocal8Bit(lineBytes).trimmed(); |
| 81 | 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 | 225 | return templates; |
| 99 | 226 | } |
| 100 | 227 | |
| ... | ... | @@ -104,10 +231,10 @@ class csvGallery : public FileGallery |
| 104 | 231 | writeOpen(); |
| 105 | 232 | if (headers.isEmpty()) { |
| 106 | 233 | foreach (const QString &key, t.file.localKeys()) |
| 107 | - headers.append(key); | |
| 234 | + headers.append(CSVHeader(key)); | |
| 108 | 235 | |
| 109 | 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 | 238 | f.write(header.toLocal8Bit()); |
| 112 | 239 | } |
| 113 | 240 | f.write(QString(lineFromFile(t.file) + "\n").toLocal8Bit()); |
| ... | ... | @@ -119,7 +246,7 @@ class csvGallery : public FileGallery |
| 119 | 246 | { |
| 120 | 247 | QStringList words; |
| 121 | 248 | words.append(file.name); |
| 122 | - foreach (const QString &key, headers) { | |
| 249 | + foreach (const QString &key, headers.keys()) { | |
| 123 | 250 | QString value = QtUtils::toString(file.value(key)); |
| 124 | 251 | if (value.contains(",")) |
| 125 | 252 | value = '"' + value + '"'; | ... | ... |