comparison widgets/CSVFormatDialog.cpp @ 561:aced8ec09bc8

* Complete the overhaul of CSV file import; now you can pick the purpose for each column in the file, and SV should do the rest. The most significant practical improvement here is that we can now handle files in which time and duration do not necessarily appear in known columns.
author Chris Cannam
date Mon, 19 Jul 2010 17:08:56 +0000
parents e15afed2bfeb
children e2211947cbfd
comparison
equal deleted inserted replaced
560:e15afed2bfeb 561:aced8ec09bc8
13 COPYING included with this distribution for more information. 13 COPYING included with this distribution for more information.
14 */ 14 */
15 15
16 #include "CSVFormatDialog.h" 16 #include "CSVFormatDialog.h"
17 17
18 #include "layer/LayerFactory.h"
19
18 #include <QFrame> 20 #include <QFrame>
19 #include <QGridLayout> 21 #include <QGridLayout>
20 #include <QPushButton> 22 #include <QPushButton>
21 #include <QHBoxLayout> 23 #include <QHBoxLayout>
22 #include <QVBoxLayout> 24 #include <QVBoxLayout>
43 45
44 QFrame *exampleFrame = new QFrame; 46 QFrame *exampleFrame = new QFrame;
45 exampleFrame->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); 47 exampleFrame->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
46 exampleFrame->setLineWidth(2); 48 exampleFrame->setLineWidth(2);
47 QGridLayout *exampleLayout = new QGridLayout; 49 QGridLayout *exampleLayout = new QGridLayout;
50 exampleLayout->setSpacing(4);
48 exampleFrame->setLayout(exampleLayout); 51 exampleFrame->setLayout(exampleLayout);
49 52
50 QPalette palette = exampleFrame->palette(); 53 QPalette palette = exampleFrame->palette();
51 palette.setColor(QPalette::Window, palette.color(QPalette::Base)); 54 palette.setColor(QPalette::Window, palette.color(QPalette::Base));
52 exampleFrame->setPalette(palette); 55 exampleFrame->setPalette(palette);
53 56
54 QFont fp; 57 QFont fp;
55 fp.setFixedPitch(true); 58 fp.setPointSize(fp.pointSize() * 0.9);
56 fp.setStyleHint(QFont::TypeWriter); 59 // fp.setFixedPitch(true);
57 fp.setFamily("Monospaced"); 60 // fp.setStyleHint(QFont::TypeWriter);
61 // fp.setFamily("Monospaced");
58 62
59 int columns = format.getColumnCount(); 63 int columns = format.getColumnCount();
60 QList<QStringList> example = m_format.getExample(); 64 QList<QStringList> example = m_format.getExample();
61 65
62 for (int i = 0; i < columns; ++i) { 66 for (int i = 0; i < columns; ++i) {
80 QLabel *label = new QLabel; 84 QLabel *label = new QLabel;
81 label->setTextFormat(Qt::PlainText); 85 label->setTextFormat(Qt::PlainText);
82 label->setText(example[j][i]); 86 label->setText(example[j][i]);
83 label->setFont(fp); 87 label->setFont(fp);
84 label->setPalette(palette); 88 label->setPalette(palette);
89 label->setIndent(8);
85 exampleLayout->addWidget(label, j+1, i); 90 exampleLayout->addWidget(label, j+1, i);
86 } 91 }
87 } 92 }
88 } 93 }
89 94
90 layout->addWidget(exampleFrame, row, 0, 1, 4); 95 layout->addWidget(exampleFrame, row, 0, 1, 4);
91 layout->setColumnStretch(3, 10); 96 layout->setColumnStretch(3, 10);
92 layout->setRowStretch(row++, 10); 97 layout->setRowStretch(row++, 10);
93
94 layout->addWidget(new QLabel(tr("Each row describes:")), row, 0);
95
96 m_modelTypeCombo = new QComboBox;
97 m_modelTypeCombo->addItem(tr("A point in time"));
98 m_modelTypeCombo->addItem(tr("A value at a time"));
99 m_modelTypeCombo->addItem(tr("A value across a time range"));
100 m_modelTypeCombo->addItem(tr("A set of values"));
101 layout->addWidget(m_modelTypeCombo, row++, 1, 1, 2);
102 connect(m_modelTypeCombo, SIGNAL(activated(int)),
103 this, SLOT(modelTypeChanged(int)));
104 m_modelTypeCombo->setCurrentIndex(int(m_format.getModelType()));
105 98
106 layout->addWidget(new QLabel(tr("Timing is specified:")), row, 0); 99 layout->addWidget(new QLabel(tr("Timing is specified:")), row, 0);
107 100
108 m_timingTypeCombo = new QComboBox; 101 m_timingTypeCombo = new QComboBox;
109 m_timingTypeCombo->addItem(tr("Explicitly, in seconds")); 102 m_timingTypeCombo->addItem(tr("Explicitly, in seconds"));
156 connect(m_windowSizeCombo, SIGNAL(activated(QString)), 149 connect(m_windowSizeCombo, SIGNAL(activated(QString)),
157 this, SLOT(windowSizeChanged(QString))); 150 this, SLOT(windowSizeChanged(QString)));
158 connect(m_windowSizeCombo, SIGNAL(editTextChanged(QString)), 151 connect(m_windowSizeCombo, SIGNAL(editTextChanged(QString)),
159 this, SLOT(windowSizeChanged(QString))); 152 this, SLOT(windowSizeChanged(QString)));
160 153
154 m_modelLabel = new QLabel;
155 QFont f(m_modelLabel->font());
156 f.setItalic(true);
157 m_modelLabel->setFont(f);
158 layout->addWidget(m_modelLabel, row++, 0, 1, 4);
159
161 QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Ok | 160 QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Ok |
162 QDialogButtonBox::Cancel); 161 QDialogButtonBox::Cancel);
163 layout->addWidget(bb, row++, 0, 1, 4); 162 layout->addWidget(bb, row++, 0, 1, 4);
164 connect(bb, SIGNAL(accepted()), this, SLOT(accept())); 163 connect(bb, SIGNAL(accepted()), this, SLOT(accept()));
165 connect(bb, SIGNAL(rejected()), this, SLOT(reject())); 164 connect(bb, SIGNAL(rejected()), this, SLOT(reject()));
166 165
167 setLayout(layout); 166 setLayout(layout);
168 167
169 modelTypeChanged(m_modelTypeCombo->currentIndex());
170 timingTypeChanged(m_timingTypeCombo->currentIndex()); 168 timingTypeChanged(m_timingTypeCombo->currentIndex());
169 updateModelLabel();
171 } 170 }
172 171
173 CSVFormatDialog::~CSVFormatDialog() 172 CSVFormatDialog::~CSVFormatDialog()
174 { 173 {
175 } 174 }
179 { 178 {
180 return m_format; 179 return m_format;
181 } 180 }
182 181
183 void 182 void
184 CSVFormatDialog::modelTypeChanged(int type) 183 CSVFormatDialog::updateModelLabel()
185 { 184 {
186 m_format.setModelType((CSVFormat::ModelType)type); 185 LayerFactory *f = LayerFactory::getInstance();
186
187 QString s;
188 switch (m_format.getModelType()) {
189 case CSVFormat::OneDimensionalModel:
190 s = f->getLayerPresentationName(LayerFactory::TimeInstants);
191 break;
192 case CSVFormat::TwoDimensionalModel:
193 s = f->getLayerPresentationName(LayerFactory::TimeValues);
194 break;
195 case CSVFormat::TwoDimensionalModelWithDuration:
196 s = f->getLayerPresentationName(LayerFactory::Regions);
197 break;
198 case CSVFormat::ThreeDimensionalModel:
199 s = f->getLayerPresentationName(LayerFactory::Colour3DPlot);
200 break;
201 }
202
203 m_modelLabel->setText("\n" + QString("Data will be displayed in a %1 layer.").arg(s));
187 } 204 }
188 205
189 void 206 void
190 CSVFormatDialog::timingTypeChanged(int type) 207 CSVFormatDialog::timingTypeChanged(int type)
191 { 208 {
235 int size = sizeString.toInt(&ok); 252 int size = sizeString.toInt(&ok);
236 if (ok) m_format.setWindowSize(size); 253 if (ok) m_format.setWindowSize(size);
237 } 254 }
238 255
239 void 256 void
240 CSVFormatDialog::columnPurposeChanged(int purpose) 257 CSVFormatDialog::columnPurposeChanged(int p)
241 { 258 {
242 QObject *o = sender(); 259 QObject *o = sender();
260
243 QComboBox *cb = qobject_cast<QComboBox *>(o); 261 QComboBox *cb = qobject_cast<QComboBox *>(o);
244 if (!cb) return; 262 if (!cb) return;
245 int changedCol = -1; 263
264 CSVFormat::ColumnPurpose purpose = (CSVFormat::ColumnPurpose)p;
265
266 bool haveStartTime = false;
267 bool haveDuration = false;
268 int valueCount = 0;
269
246 for (int i = 0; i < m_columnPurposeCombos.size(); ++i) { 270 for (int i = 0; i < m_columnPurposeCombos.size(); ++i) {
247 if (cb == m_columnPurposeCombos[i]) { 271
248 changedCol = i; 272 CSVFormat::ColumnPurpose cp = m_format.getColumnPurpose(i);
249 break; 273
250 } 274 bool thisChanged = (cb == m_columnPurposeCombos[i]);
251 } 275
252 if (changedCol < 0) { 276 if (thisChanged) {
253 std::cerr << "Hm, some problem here -- column combo changed, but cannot locate column" << std::endl; 277
254 return; 278 cp = purpose;
255 } 279
256 280 } else {
257 } 281
258 282 // We can only have one ColumnStartTime column, and only
259 283 // one of either ColumnDuration or ColumnEndTime
284
285 if (purpose == CSVFormat::ColumnStartTime) {
286 if (cp == purpose) {
287 cp = CSVFormat::ColumnValue;
288 }
289 } else if (purpose == CSVFormat::ColumnDuration ||
290 purpose == CSVFormat::ColumnEndTime) {
291 if (cp == CSVFormat::ColumnDuration ||
292 cp == CSVFormat::ColumnEndTime) {
293 cp = CSVFormat::ColumnValue;
294 }
295 }
296
297 // And we can only have one label
298 if (purpose == CSVFormat::ColumnLabel) {
299 if (cp == purpose) {
300 cp = CSVFormat::ColumnUnknown;
301 }
302 }
303 }
304
305 if (cp == CSVFormat::ColumnStartTime) {
306 haveStartTime = true;
307 }
308 if (cp == CSVFormat::ColumnEndTime ||
309 cp == CSVFormat::ColumnDuration) {
310 haveDuration = true;
311 }
312 if (cp == CSVFormat::ColumnValue) {
313 ++valueCount;
314 }
315
316 m_columnPurposeCombos[i]->setCurrentIndex(int(cp));
317 m_format.setColumnPurpose(i, cp);
318 }
319
320 if (!haveStartTime) {
321 m_timingTypeCombo->setCurrentIndex(2);
322 timingTypeChanged(2);
323 }
324
325 if (haveStartTime && haveDuration) {
326 m_format.setModelType(CSVFormat::TwoDimensionalModelWithDuration);
327 } else {
328 if (valueCount > 1) {
329 m_format.setModelType(CSVFormat::ThreeDimensionalModel);
330 } else if (valueCount > 0) {
331 m_format.setModelType(CSVFormat::TwoDimensionalModel);
332 } else {
333 m_format.setModelType(CSVFormat::OneDimensionalModel);
334 }
335 }
336
337 updateModelLabel();
338 }
339
340