Mercurial > hg > svgui
comparison widgets/CSVFormatDialog.cpp @ 560:e15afed2bfeb
* Start revamping the CSV import dialog so as to show a "purpose" for each column.
These are estimated from the file now, but changing them does not actually do
anything yet.
author | Chris Cannam |
---|---|
date | Fri, 16 Jul 2010 16:51:39 +0000 |
parents | 5bcfc5606528 |
children | aced8ec09bc8 |
comparison
equal
deleted
inserted
replaced
559:5bcfc5606528 | 560:e15afed2bfeb |
---|---|
23 #include <QTableWidget> | 23 #include <QTableWidget> |
24 #include <QComboBox> | 24 #include <QComboBox> |
25 #include <QLabel> | 25 #include <QLabel> |
26 #include <QDialogButtonBox> | 26 #include <QDialogButtonBox> |
27 | 27 |
28 | 28 #include <iostream> |
29 CSVFormatDialog::CSVFormatDialog(QWidget *parent, CSVFormat format, | 29 |
30 size_t defaultSampleRate) : | 30 CSVFormatDialog::CSVFormatDialog(QWidget *parent, CSVFormat format) : |
31 QDialog(parent), | 31 QDialog(parent), |
32 m_modelType(CSVFormat::OneDimensionalModel), | 32 m_format(format) |
33 m_timingType(CSVFormat::ExplicitTiming), | |
34 m_durationType(CSVFormat::Durations), | |
35 m_timeUnits(CSVFormat::TimeAudioFrames), | |
36 m_separator(""), | |
37 m_behaviour(QString::KeepEmptyParts) | |
38 { | 33 { |
39 setModal(true); | 34 setModal(true); |
40 setWindowTitle(tr("Select Data Format")); | 35 setWindowTitle(tr("Select Data Format")); |
41 | 36 |
42 m_modelType = format.getModelType(); | |
43 m_timingType = format.getTimingType(); | |
44 m_durationType = format.getDurationType(); | |
45 m_timeUnits = format.getTimeUnits(); | |
46 m_separator = format.getSeparator(); | |
47 m_sampleRate = format.getSampleRate(); | |
48 m_windowSize = format.getWindowSize(); | |
49 m_behaviour = format.getSplitBehaviour(); | |
50 m_example = format.getExample(); | |
51 m_maxExampleCols = format.getMaxExampleCols(); | |
52 | |
53 QGridLayout *layout = new QGridLayout; | 37 QGridLayout *layout = new QGridLayout; |
54 | 38 |
55 layout->addWidget(new QLabel(tr("<b>Select Data Format</b><p>Please select the correct data format for this file.")), | 39 int row = 0; |
56 0, 0, 1, 4); | 40 |
57 | 41 layout->addWidget(new QLabel(tr("Please select the correct data format for this file.")), |
58 layout->addWidget(new QLabel(tr("Each row specifies:")), 1, 0); | 42 row++, 0, 1, 4); |
43 | |
44 QFrame *exampleFrame = new QFrame; | |
45 exampleFrame->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); | |
46 exampleFrame->setLineWidth(2); | |
47 QGridLayout *exampleLayout = new QGridLayout; | |
48 exampleFrame->setLayout(exampleLayout); | |
49 | |
50 QPalette palette = exampleFrame->palette(); | |
51 palette.setColor(QPalette::Window, palette.color(QPalette::Base)); | |
52 exampleFrame->setPalette(palette); | |
53 | |
54 QFont fp; | |
55 fp.setFixedPitch(true); | |
56 fp.setStyleHint(QFont::TypeWriter); | |
57 fp.setFamily("Monospaced"); | |
58 | |
59 int columns = format.getColumnCount(); | |
60 QList<QStringList> example = m_format.getExample(); | |
61 | |
62 for (int i = 0; i < columns; ++i) { | |
63 | |
64 QComboBox *cpc = new QComboBox; | |
65 m_columnPurposeCombos.push_back(cpc); | |
66 exampleLayout->addWidget(cpc, 0, i); | |
67 | |
68 // NB must be in the same order as the CSVFormat::ColumnPurpose enum | |
69 cpc->addItem(tr("<ignore>")); // ColumnUnknown | |
70 cpc->addItem(tr("Time")); // ColumnStartTime | |
71 cpc->addItem(tr("End time")); // ColumnEndTime | |
72 cpc->addItem(tr("Duration")); // ColumnDuration | |
73 cpc->addItem(tr("Value")); // ColumnValue | |
74 cpc->addItem(tr("Label")); // ColumnLabel | |
75 cpc->setCurrentIndex(int(m_format.getColumnPurpose(i))); | |
76 connect(cpc, SIGNAL(activated(int)), this, SLOT(columnPurposeChanged(int))); | |
77 | |
78 if (i < m_format.getMaxExampleCols()) { | |
79 for (int j = 0; j < example.size() && j < 6; ++j) { | |
80 QLabel *label = new QLabel; | |
81 label->setTextFormat(Qt::PlainText); | |
82 label->setText(example[j][i]); | |
83 label->setFont(fp); | |
84 label->setPalette(palette); | |
85 exampleLayout->addWidget(label, j+1, i); | |
86 } | |
87 } | |
88 } | |
89 | |
90 layout->addWidget(exampleFrame, row, 0, 1, 4); | |
91 layout->setColumnStretch(3, 10); | |
92 layout->setRowStretch(row++, 10); | |
93 | |
94 layout->addWidget(new QLabel(tr("Each row describes:")), row, 0); | |
59 | 95 |
60 m_modelTypeCombo = new QComboBox; | 96 m_modelTypeCombo = new QComboBox; |
61 m_modelTypeCombo->addItem(tr("A point in time")); | 97 m_modelTypeCombo->addItem(tr("A point in time")); |
62 m_modelTypeCombo->addItem(tr("A value at a time")); | 98 m_modelTypeCombo->addItem(tr("A value at a time")); |
63 m_modelTypeCombo->addItem(tr("A value across a time range")); | 99 m_modelTypeCombo->addItem(tr("A value across a time range")); |
64 m_modelTypeCombo->addItem(tr("A set of values")); | 100 m_modelTypeCombo->addItem(tr("A set of values")); |
65 layout->addWidget(m_modelTypeCombo, 1, 1, 1, 2); | 101 layout->addWidget(m_modelTypeCombo, row++, 1, 1, 2); |
66 connect(m_modelTypeCombo, SIGNAL(activated(int)), | 102 connect(m_modelTypeCombo, SIGNAL(activated(int)), |
67 this, SLOT(modelTypeChanged(int))); | 103 this, SLOT(modelTypeChanged(int))); |
68 m_modelTypeCombo->setCurrentIndex(int(m_modelType)); | 104 m_modelTypeCombo->setCurrentIndex(int(m_format.getModelType())); |
69 | 105 |
70 layout->addWidget(new QLabel(tr("The first column contains:")), 2, 0); | 106 layout->addWidget(new QLabel(tr("Timing is specified:")), row, 0); |
71 | 107 |
72 m_timingTypeCombo = new QComboBox; | 108 m_timingTypeCombo = new QComboBox; |
73 m_timingTypeCombo->addItem(tr("Time, in seconds")); | 109 m_timingTypeCombo->addItem(tr("Explicitly, in seconds")); |
74 m_timingTypeCombo->addItem(tr("Time, in audio sample frames")); | 110 m_timingTypeCombo->addItem(tr("Explicitly, in audio sample frames")); |
75 m_timingTypeCombo->addItem(tr("Data (rows are consecutive in time)")); | 111 m_timingTypeCombo->addItem(tr("Implicitly: rows are equally spaced in time")); |
76 layout->addWidget(m_timingTypeCombo, 2, 1, 1, 2); | 112 layout->addWidget(m_timingTypeCombo, row++, 1, 1, 2); |
77 connect(m_timingTypeCombo, SIGNAL(activated(int)), | 113 connect(m_timingTypeCombo, SIGNAL(activated(int)), |
78 this, SLOT(timingTypeChanged(int))); | 114 this, SLOT(timingTypeChanged(int))); |
79 m_timingTypeCombo->setCurrentIndex(m_timingType == CSVFormat::ExplicitTiming ? | 115 m_timingTypeCombo->setCurrentIndex |
80 m_timeUnits == CSVFormat::TimeSeconds ? 0 : 1 : 2); | 116 (m_format.getTimingType() == CSVFormat::ExplicitTiming ? |
81 | 117 m_format.getTimeUnits() == CSVFormat::TimeSeconds ? 0 : 1 : 2); |
82 m_durationTypeLabel = new QLabel(tr("The second column contains:")); | |
83 layout->addWidget(m_durationTypeLabel, 3, 0); | |
84 | |
85 m_durationTypeCombo = new QComboBox; | |
86 m_durationTypeCombo->addItem(tr("Duration")); | |
87 m_durationTypeCombo->addItem(tr("End time")); | |
88 layout->addWidget(m_durationTypeCombo, 3, 1, 1, 2); | |
89 connect(m_durationTypeCombo, SIGNAL(activated(int)), | |
90 this, SLOT(durationTypeChanged(int))); | |
91 m_durationTypeCombo->setCurrentIndex(int(m_durationType)); | |
92 | 118 |
93 m_sampleRateLabel = new QLabel(tr("Audio sample rate (Hz):")); | 119 m_sampleRateLabel = new QLabel(tr("Audio sample rate (Hz):")); |
94 layout->addWidget(m_sampleRateLabel, 4, 0); | 120 layout->addWidget(m_sampleRateLabel, row, 0); |
95 | 121 |
96 size_t sampleRates[] = { | 122 size_t sampleRates[] = { |
97 8000, 11025, 12000, 22050, 24000, 32000, | 123 8000, 11025, 12000, 22050, 24000, 32000, |
98 44100, 48000, 88200, 96000, 176400, 192000 | 124 44100, 48000, 88200, 96000, 176400, 192000 |
99 }; | 125 }; |
100 | 126 |
101 m_sampleRateCombo = new QComboBox; | 127 m_sampleRateCombo = new QComboBox; |
102 m_sampleRate = defaultSampleRate; | |
103 for (size_t i = 0; i < sizeof(sampleRates) / sizeof(sampleRates[0]); ++i) { | 128 for (size_t i = 0; i < sizeof(sampleRates) / sizeof(sampleRates[0]); ++i) { |
104 m_sampleRateCombo->addItem(QString("%1").arg(sampleRates[i])); | 129 m_sampleRateCombo->addItem(QString("%1").arg(sampleRates[i])); |
105 if (sampleRates[i] == m_sampleRate) m_sampleRateCombo->setCurrentIndex(i); | 130 if (sampleRates[i] == m_format.getSampleRate()) { |
131 m_sampleRateCombo->setCurrentIndex(i); | |
132 } | |
106 } | 133 } |
107 m_sampleRateCombo->setEditable(true); | 134 m_sampleRateCombo->setEditable(true); |
108 | 135 |
109 layout->addWidget(m_sampleRateCombo, 4, 1); | 136 layout->addWidget(m_sampleRateCombo, row++, 1); |
110 connect(m_sampleRateCombo, SIGNAL(activated(QString)), | 137 connect(m_sampleRateCombo, SIGNAL(activated(QString)), |
111 this, SLOT(sampleRateChanged(QString))); | 138 this, SLOT(sampleRateChanged(QString))); |
112 connect(m_sampleRateCombo, SIGNAL(editTextChanged(QString)), | 139 connect(m_sampleRateCombo, SIGNAL(editTextChanged(QString)), |
113 this, SLOT(sampleRateChanged(QString))); | 140 this, SLOT(sampleRateChanged(QString))); |
114 | 141 |
115 m_windowSizeLabel = new QLabel(tr("Frame increment between rows:")); | 142 m_windowSizeLabel = new QLabel(tr("Frame increment between rows:")); |
116 layout->addWidget(m_windowSizeLabel, 5, 0); | 143 layout->addWidget(m_windowSizeLabel, row, 0); |
117 | 144 |
118 m_windowSizeCombo = new QComboBox; | 145 m_windowSizeCombo = new QComboBox; |
119 m_windowSize = 1024; | |
120 for (int i = 0; i <= 16; ++i) { | 146 for (int i = 0; i <= 16; ++i) { |
121 int value = 1 << i; | 147 int value = 1 << i; |
122 m_windowSizeCombo->addItem(QString("%1").arg(value)); | 148 m_windowSizeCombo->addItem(QString("%1").arg(value)); |
123 if (value == int(m_windowSize)) m_windowSizeCombo->setCurrentIndex(i); | 149 if (value == int(m_format.getWindowSize())) { |
150 m_windowSizeCombo->setCurrentIndex(i); | |
151 } | |
124 } | 152 } |
125 m_windowSizeCombo->setEditable(true); | 153 m_windowSizeCombo->setEditable(true); |
126 | 154 |
127 layout->addWidget(m_windowSizeCombo, 5, 1); | 155 layout->addWidget(m_windowSizeCombo, row++, 1); |
128 connect(m_windowSizeCombo, SIGNAL(activated(QString)), | 156 connect(m_windowSizeCombo, SIGNAL(activated(QString)), |
129 this, SLOT(windowSizeChanged(QString))); | 157 this, SLOT(windowSizeChanged(QString))); |
130 connect(m_windowSizeCombo, SIGNAL(editTextChanged(QString)), | 158 connect(m_windowSizeCombo, SIGNAL(editTextChanged(QString)), |
131 this, SLOT(windowSizeChanged(QString))); | 159 this, SLOT(windowSizeChanged(QString))); |
132 | 160 |
133 layout->addWidget(new QLabel(tr("\nExample data from file:")), 6, 0, 1, 4); | |
134 | |
135 m_exampleWidget = new QTableWidget | |
136 (std::min(10, m_example.size()), m_maxExampleCols); | |
137 | |
138 layout->addWidget(m_exampleWidget, 7, 0, 1, 4); | |
139 layout->setColumnStretch(3, 10); | |
140 layout->setRowStretch(6, 10); | |
141 | |
142 QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Ok | | 161 QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Ok | |
143 QDialogButtonBox::Cancel); | 162 QDialogButtonBox::Cancel); |
144 layout->addWidget(bb, 8, 0, 1, 4); | 163 layout->addWidget(bb, row++, 0, 1, 4); |
145 connect(bb, SIGNAL(accepted()), this, SLOT(accept())); | 164 connect(bb, SIGNAL(accepted()), this, SLOT(accept())); |
146 connect(bb, SIGNAL(rejected()), this, SLOT(reject())); | 165 connect(bb, SIGNAL(rejected()), this, SLOT(reject())); |
147 | 166 |
148 setLayout(layout); | 167 setLayout(layout); |
149 | 168 |
150 modelTypeChanged(m_modelTypeCombo->currentIndex()); | 169 modelTypeChanged(m_modelTypeCombo->currentIndex()); |
151 timingTypeChanged(m_timingTypeCombo->currentIndex()); | 170 timingTypeChanged(m_timingTypeCombo->currentIndex()); |
152 durationTypeChanged(m_durationTypeCombo->currentIndex()); | |
153 } | 171 } |
154 | 172 |
155 CSVFormatDialog::~CSVFormatDialog() | 173 CSVFormatDialog::~CSVFormatDialog() |
156 { | 174 { |
157 } | 175 } |
158 | 176 |
159 CSVFormat | 177 CSVFormat |
160 CSVFormatDialog::getFormat() const | 178 CSVFormatDialog::getFormat() const |
161 { | 179 { |
162 CSVFormat format; | 180 return m_format; |
163 format.setModelType(m_modelType); | |
164 format.setTimingType(m_timingType); | |
165 format.setDurationType(m_durationType); | |
166 format.setTimeUnits(m_timeUnits); | |
167 format.setSeparator(m_separator); | |
168 format.setSampleRate(m_sampleRate); | |
169 format.setWindowSize(m_windowSize); | |
170 format.setSplitBehaviour(m_behaviour); | |
171 return format; | |
172 } | |
173 | |
174 void | |
175 CSVFormatDialog::populateExample() | |
176 { | |
177 m_exampleWidget->setColumnCount | |
178 (m_timingType == CSVFormat::ExplicitTiming ? | |
179 m_maxExampleCols - 1 : m_maxExampleCols); | |
180 | |
181 m_exampleWidget->setHorizontalHeaderLabels(QStringList()); | |
182 | |
183 for (int i = 0; i < m_example.size(); ++i) { | |
184 for (int j = 0; j < m_example[i].size(); ++j) { | |
185 | |
186 QTableWidgetItem *item = new QTableWidgetItem(m_example[i][j]); | |
187 | |
188 if (j == 0) { | |
189 if (m_timingType == CSVFormat::ExplicitTiming) { | |
190 m_exampleWidget->setVerticalHeaderItem(i, item); | |
191 continue; | |
192 } else { | |
193 QTableWidgetItem *header = | |
194 new QTableWidgetItem(QString("%1").arg(i)); | |
195 header->setFlags(Qt::ItemIsEnabled); | |
196 m_exampleWidget->setVerticalHeaderItem(i, header); | |
197 } | |
198 } | |
199 int index = j; | |
200 if (m_timingType == CSVFormat::ExplicitTiming) --index; | |
201 item->setFlags(Qt::ItemIsEnabled); | |
202 m_exampleWidget->setItem(i, index, item); | |
203 } | |
204 } | |
205 } | 181 } |
206 | 182 |
207 void | 183 void |
208 CSVFormatDialog::modelTypeChanged(int type) | 184 CSVFormatDialog::modelTypeChanged(int type) |
209 { | 185 { |
210 m_modelType = (CSVFormat::ModelType)type; | 186 m_format.setModelType((CSVFormat::ModelType)type); |
211 | |
212 if (m_modelType == CSVFormat::TwoDimensionalModelWithDuration) { | |
213 m_durationTypeCombo->setEnabled(true); | |
214 m_durationTypeLabel->setEnabled(true); | |
215 } else { | |
216 m_durationTypeCombo->setEnabled(false); | |
217 m_durationTypeLabel->setEnabled(false); | |
218 } | |
219 } | 187 } |
220 | 188 |
221 void | 189 void |
222 CSVFormatDialog::timingTypeChanged(int type) | 190 CSVFormatDialog::timingTypeChanged(int type) |
223 { | 191 { |
224 switch (type) { | 192 switch (type) { |
225 | 193 |
226 case 0: | 194 case 0: |
227 m_timingType = CSVFormat::ExplicitTiming; | 195 m_format.setTimingType(CSVFormat::ExplicitTiming); |
228 m_timeUnits = CSVFormat::TimeSeconds; | 196 m_format.setTimeUnits(CSVFormat::TimeSeconds); |
229 m_sampleRateCombo->setEnabled(false); | 197 m_sampleRateCombo->setEnabled(false); |
230 m_sampleRateLabel->setEnabled(false); | 198 m_sampleRateLabel->setEnabled(false); |
231 m_windowSizeCombo->setEnabled(false); | 199 m_windowSizeCombo->setEnabled(false); |
232 m_windowSizeLabel->setEnabled(false); | 200 m_windowSizeLabel->setEnabled(false); |
233 break; | 201 break; |
234 | 202 |
235 case 1: | 203 case 1: |
236 m_timingType = CSVFormat::ExplicitTiming; | 204 m_format.setTimingType(CSVFormat::ExplicitTiming); |
237 m_timeUnits = CSVFormat::TimeAudioFrames; | 205 m_format.setTimeUnits(CSVFormat::TimeAudioFrames); |
238 m_sampleRateCombo->setEnabled(true); | 206 m_sampleRateCombo->setEnabled(true); |
239 m_sampleRateLabel->setEnabled(true); | 207 m_sampleRateLabel->setEnabled(true); |
240 m_windowSizeCombo->setEnabled(false); | 208 m_windowSizeCombo->setEnabled(false); |
241 m_windowSizeLabel->setEnabled(false); | 209 m_windowSizeLabel->setEnabled(false); |
242 break; | 210 break; |
243 | 211 |
244 case 2: | 212 case 2: |
245 m_timingType = CSVFormat::ImplicitTiming; | 213 m_format.setTimingType(CSVFormat::ImplicitTiming); |
246 m_timeUnits = CSVFormat::TimeWindows; | 214 m_format.setTimeUnits(CSVFormat::TimeWindows); |
247 m_sampleRateCombo->setEnabled(true); | 215 m_sampleRateCombo->setEnabled(true); |
248 m_sampleRateLabel->setEnabled(true); | 216 m_sampleRateLabel->setEnabled(true); |
249 m_windowSizeCombo->setEnabled(true); | 217 m_windowSizeCombo->setEnabled(true); |
250 m_windowSizeLabel->setEnabled(true); | 218 m_windowSizeLabel->setEnabled(true); |
251 break; | 219 break; |
252 } | 220 } |
253 | |
254 populateExample(); | |
255 } | |
256 | |
257 void | |
258 CSVFormatDialog::durationTypeChanged(int type) | |
259 { | |
260 m_durationType = (CSVFormat::DurationType)type; | |
261 } | 221 } |
262 | 222 |
263 void | 223 void |
264 CSVFormatDialog::sampleRateChanged(QString rateString) | 224 CSVFormatDialog::sampleRateChanged(QString rateString) |
265 { | 225 { |
266 bool ok = false; | 226 bool ok = false; |
267 int sampleRate = rateString.toInt(&ok); | 227 int sampleRate = rateString.toInt(&ok); |
268 if (ok) m_sampleRate = sampleRate; | 228 if (ok) m_format.setSampleRate(sampleRate); |
269 } | 229 } |
270 | 230 |
271 void | 231 void |
272 CSVFormatDialog::windowSizeChanged(QString sizeString) | 232 CSVFormatDialog::windowSizeChanged(QString sizeString) |
273 { | 233 { |
274 bool ok = false; | 234 bool ok = false; |
275 int size = sizeString.toInt(&ok); | 235 int size = sizeString.toInt(&ok); |
276 if (ok) m_windowSize = size; | 236 if (ok) m_format.setWindowSize(size); |
277 } | 237 } |
238 | |
239 void | |
240 CSVFormatDialog::columnPurposeChanged(int purpose) | |
241 { | |
242 QObject *o = sender(); | |
243 QComboBox *cb = qobject_cast<QComboBox *>(o); | |
244 if (!cb) return; | |
245 int changedCol = -1; | |
246 for (int i = 0; i < m_columnPurposeCombos.size(); ++i) { | |
247 if (cb == m_columnPurposeCombos[i]) { | |
248 changedCol = i; | |
249 break; | |
250 } | |
251 } | |
252 if (changedCol < 0) { | |
253 std::cerr << "Hm, some problem here -- column combo changed, but cannot locate column" << std::endl; | |
254 return; | |
255 } | |
256 | |
257 } | |
258 | |
259 |