CSVExportDialog.cpp
Go to the documentation of this file.
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2 
3 /*
4  Sonic Visualiser
5  An audio file viewer and annotation editor.
6  Centre for Digital Music, Queen Mary, University of London.
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2 of the
11  License, or (at your option) any later version. See the file
12  COPYING included with this distribution for more information.
13 */
14 
15 #include "CSVExportDialog.h"
16 
17 #include "view/ViewManager.h"
18 
19 #include <QVBoxLayout>
20 #include <QGridLayout>
21 #include <QGroupBox>
22 #include <QLabel>
23 #include <QDialogButtonBox>
24 #include <QRadioButton>
25 #include <QButtonGroup>
26 #include <QCheckBox>
27 #include <QComboBox>
28 
29 #include <vector>
30 
31 using namespace std;
32 
34 
36  QDialog(parent),
37  m_config(config)
38 {
39  setWindowTitle(tr("Export Layer"));
40 
41  QString intro = tr("Exporting layer \"%1\" to %2 file.")
42  .arg(config.layerName)
43  .arg(config.fileExtension.toUpper());
44 
45  QVBoxLayout *vbox = new QVBoxLayout;
46 
47  QLabel *label = new QLabel(intro);
48  label->setWordWrap(true);
49  vbox->addWidget(label);
50 
51  int space = ViewManager::scalePixelSize(2);
52 
53  vbox->addSpacing(space);
54 
55  QGroupBox *rowColGroup = new QGroupBox(tr("Row and column options:"));
56  QGridLayout *rowColLayout = new QGridLayout;
57  rowColGroup->setLayout(rowColLayout);
58 
59  vector<pair<QString, QChar>> separators {
60  { tr("Comma"), ',' },
61  { tr("Tab"), '\t' },
62  { tr("Space"), ' ' },
63  { tr("Pipe"), '|' },
64  { tr("Slash"), '/' },
65  { tr("Colon"), ':' }
66  };
67 
68  QChar defaultSeparator = ',';
69  if (m_config.fileExtension != "csv") {
70  defaultSeparator = '\t';
71  }
72 
73  rowColLayout->addWidget(new QLabel(tr("Column separator:")));
74  m_separatorCombo = new QComboBox;
75  for (auto p: separators) {
76  if (p.second == '\t' || p.second == ' ') {
77  m_separatorCombo->addItem(p.first, p.second);
78  } else {
79  m_separatorCombo->addItem(tr("%1 '%2'").arg(p.first).arg(p.second),
80  p.second);
81  }
82  if (p.second == defaultSeparator) {
83  m_separatorCombo->setCurrentIndex(m_separatorCombo->count()-1);
84  }
85  }
86  m_separatorCombo->setEditable(false);
87  rowColLayout->addWidget(m_separatorCombo, 0, 1);
88  rowColLayout->setColumnStretch(2, 10);
89 
90  m_header = new QCheckBox
91  (tr("Include a header row before the data rows"));
92  m_timestamps = new QCheckBox
93  (tr("Include a timestamp column before the data columns"));
94  rowColLayout->addWidget(m_header, 1, 0, 1, 3);
95  rowColLayout->addWidget(m_timestamps, 2, 0, 1, 3);
96 
97  if (!m_config.isDense) {
98  m_timestamps->setChecked(true);
99  m_timestamps->setEnabled(false);
100  }
101 
102  vbox->addWidget(rowColGroup);
103 
104  vbox->addSpacing(space);
105 
106  QGroupBox *framesGroup = new QGroupBox
107  (tr("Timing format:"));
108 
109  m_seconds = new QRadioButton
110  (tr("Write times in seconds"));
111  m_frames = new QRadioButton
112  (tr("Write times in audio sample frames"));
113  m_seconds->setChecked(true);
114 
115  QVBoxLayout *framesLayout = new QVBoxLayout;
116  framesLayout->addWidget(m_seconds);
117  framesLayout->addWidget(m_frames);
118  framesGroup->setLayout(framesLayout);
119  vbox->addWidget(framesGroup);
120 
121  vbox->addSpacing(space);
122 
123  if (m_config.isDense) {
124  m_seconds->setEnabled(false);
125  m_frames->setEnabled(false);
126  }
127 
128  QGroupBox *rangeGroup = new QGroupBox
129  (tr("Range to export:"));
130 
131  QButtonGroup *selectionGroup = new QButtonGroup(rangeGroup);
132  QButtonGroup *viewGroup = new QButtonGroup(rangeGroup);
133 
134  m_selectionOnly = new QRadioButton
135  (tr("Export only the current selection"));
136  QRadioButton *fullDuration = new QRadioButton
137  (tr("Export the full duration of the layer"));
138 
139  selectionGroup->addButton(m_selectionOnly);
140  selectionGroup->addButton(fullDuration);
141 
142  if (m_config.haveSelection) {
143  m_selectionOnly->setChecked(true);
144  } else {
145  m_selectionOnly->setEnabled(false);
146  fullDuration->setEnabled(false);
147  fullDuration->setChecked(true);
148  }
149 
150  QVBoxLayout *rangeLayout = new QVBoxLayout;
151  rangeLayout->addWidget(m_selectionOnly);
152  rangeLayout->addWidget(fullDuration);
153 
155 
156  m_viewOnly = new QRadioButton
157  (tr("Export only the height of the visible view"));
158  QRadioButton *fullHeight = new QRadioButton
159  (tr("Export the full height of the layer"));
160 
161  viewGroup->addButton(m_viewOnly);
162  viewGroup->addButton(fullHeight);
163 
164  m_viewOnly->setChecked(true);
165 
166  rangeLayout->addSpacing(space);
167 
168  rangeLayout->addWidget(m_viewOnly);
169  rangeLayout->addWidget(fullHeight);
170 
171  } else {
172  m_viewOnly = nullptr;
173  }
174 
175  rangeGroup->setLayout(rangeLayout);
176  vbox->addWidget(rangeGroup);
177 
178  vbox->addSpacing(space);
179 
180  QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Ok |
181  QDialogButtonBox::Cancel);
182  vbox->addWidget(bb);
183  connect(bb, SIGNAL(accepted()), this, SLOT(accept()));
184  connect(bb, SIGNAL(rejected()), this, SLOT(reject()));
185 
186  connect(m_timestamps, SIGNAL(toggled(bool)),
187  this, SLOT(timestampsToggled(bool)));
188 
189  setLayout(vbox);
190 }
191 
192 void
194 {
195  m_seconds->setEnabled(on);
196  m_frames->setEnabled(on);
197 }
198 
199 QString
201 {
202  return m_separatorCombo->currentData().toChar();
203 }
204 
205 bool
207 {
208  return m_header && m_header->isChecked();
209 }
210 
211 bool
213 {
214  return m_timestamps && m_timestamps->isChecked();
215 }
216 
217 bool
219 {
220  return shouldIncludeTimestamps() && m_frames && m_frames->isChecked();
221 }
222 
223 bool
225 {
226  return m_viewOnly && m_viewOnly->isChecked();
227 }
228 
229 bool
231 {
232  return m_selectionOnly && m_selectionOnly->isChecked();
233 }
234 
bool shouldIncludeHeader() const
Return true if we should include a header row at the top of the exported file.
QRadioButton * m_selectionOnly
bool shouldConstrainToSelection() const
Return true if we should export the selected time range(s) only.
static int scalePixelSize(int pixels)
Take a "design pixel" size and scale it for the actual display.
bool shouldConstrainToViewHeight() const
Return true if we should constrain the vertical range to the visible area only.
bool haveView
True if we have a view that provides a vertical scale range, so we may want to offer a choice between...
bool shouldIncludeTimestamps() const
Return true if we should write a timestamp column.
Configuration m_config
bool shouldWriteTimeInFrames() const
Return true if we should use sample frames rather than seconds for the timestamp column (and duration...
QCheckBox * m_header
QString getDelimiter() const
Return the column delimiter to use in the exported file.
bool haveSelection
True if there is a selection current that the user may want to constrain export to.
QCheckBox * m_timestamps
QRadioButton * m_seconds
QString fileExtension
Extension of file being exported into.
void timestampsToggled(bool)
bool isDense
True if the model is a dense type for which timestamps are not written by default.
QRadioButton * m_frames
QComboBox * m_separatorCombo
QString layerName
Presentation name of the layer being exported.
QRadioButton * m_viewOnly
CSVExportDialog(Configuration config, QWidget *parent)
!! todo: remember & re-apply last set of options chosen for this layer type