Mercurial > hg > svgui
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 |