annotate widgets/ItemEditDialog.cpp @ 1551:e79731086b0f

Fixes to NoteLayer, particularly to calculation of vertical scale when model unit is not Hz. To avoid inconsistency we now behave as if the unit is always Hz from the point of view of the external API and display, converting at the point where we obtain values from the events themselves. Also various fixes to editing.
author Chris Cannam
date Thu, 21 Nov 2019 14:02:57 +0000
parents c5d2de8f7647
children
rev   line source
Chris@70 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@70 2
Chris@70 3 /*
Chris@70 4 Sonic Visualiser
Chris@70 5 An audio file viewer and annotation editor.
Chris@70 6 Centre for Digital Music, Queen Mary, University of London.
Chris@70 7 This file copyright 2006 Chris Cannam.
Chris@70 8
Chris@70 9 This program is free software; you can redistribute it and/or
Chris@70 10 modify it under the terms of the GNU General Public License as
Chris@70 11 published by the Free Software Foundation; either version 2 of the
Chris@70 12 License, or (at your option) any later version. See the file
Chris@70 13 COPYING included with this distribution for more information.
Chris@70 14 */
Chris@70 15
Chris@70 16 #include "ItemEditDialog.h"
Chris@70 17
Chris@70 18 #include <QLineEdit>
Chris@70 19 #include <QDoubleSpinBox>
Chris@73 20 #include <QSpinBox>
Chris@70 21 #include <QGridLayout>
Chris@70 22 #include <QHBoxLayout>
Chris@70 23 #include <QLabel>
Chris@70 24 #include <QPushButton>
Chris@73 25 #include <QGroupBox>
Chris@282 26 #include <QDialogButtonBox>
Chris@70 27
Chris@73 28 #include <float.h> // for FLT_MIN/MAX
Chris@70 29
Chris@73 30
Chris@1515 31 ItemEditDialog::LabelOptions::LabelOptions() :
Chris@1515 32 valueLabel(tr("Value")),
Chris@1515 33 levelLabel(tr("Level"))
Chris@1515 34 {
Chris@1515 35 }
Chris@1515 36
Chris@904 37 ItemEditDialog::ItemEditDialog(sv_samplerate_t sampleRate, int options,
Chris@1515 38 QString scaleUnits, QWidget *parent) :
Chris@1515 39 ItemEditDialog(sampleRate, options,
Chris@1515 40 [] (QString units) {
Chris@1517 41 ItemEditDialog::LabelOptions labelOptions;
Chris@1517 42 labelOptions.valueUnits = units;
Chris@1517 43 return labelOptions;
Chris@1515 44 }(scaleUnits),
Chris@1515 45 parent) {};
Chris@1515 46
Chris@1515 47 ItemEditDialog::ItemEditDialog(sv_samplerate_t sampleRate, int options,
Chris@1515 48 LabelOptions labelOptions, QWidget *parent) :
Chris@70 49 QDialog(parent),
Chris@70 50 m_sampleRate(sampleRate),
Chris@857 51 m_defaultFrame(0),
Chris@857 52 m_defaultDuration(0),
Chris@857 53 m_defaultValue(0),
Chris@1515 54 m_defaultLevel(0),
Chris@1408 55 m_frameTimeSpinBox(nullptr),
Chris@1408 56 m_realTimeSecsSpinBox(nullptr),
Chris@1408 57 m_realTimeUSecsSpinBox(nullptr),
Chris@1408 58 m_frameDurationSpinBox(nullptr),
Chris@1408 59 m_realDurationSecsSpinBox(nullptr),
Chris@1408 60 m_realDurationUSecsSpinBox(nullptr),
Chris@1408 61 m_valueSpinBox(nullptr),
Chris@1515 62 m_levelSpinBox(nullptr),
Chris@1408 63 m_textField(nullptr)
Chris@70 64 {
Chris@70 65 QGridLayout *grid = new QGridLayout;
Chris@70 66 setLayout(grid);
Chris@70 67
Chris@1408 68 QGroupBox *timeBox = nullptr;
Chris@1408 69 QGroupBox *valueBox = nullptr;
Chris@1408 70 QGridLayout *subgrid = nullptr;
Chris@70 71
Chris@73 72 int row = 0, subrow = 0;
Chris@70 73
Chris@807 74 int singleStep = RealTime::frame2RealTime(2, sampleRate).usec() - 1;
Chris@70 75
Chris@73 76 if ((options & ShowTime) || (options & ShowDuration)) {
Chris@70 77
Chris@73 78 timeBox = new QGroupBox;
Chris@73 79 timeBox->setTitle(tr("Timing"));
Chris@73 80 grid->addWidget(timeBox, row, 0);
Chris@70 81
Chris@73 82 subgrid = new QGridLayout;
Chris@73 83 timeBox->setLayout(subgrid);
Chris@70 84
Chris@70 85 ++row;
Chris@70 86 }
Chris@70 87
Chris@73 88 if (options & ShowTime) {
Chris@73 89
Chris@73 90 subgrid->addWidget(new QLabel(tr("Time:")), subrow, 0);
Chris@73 91
Chris@73 92 m_frameTimeSpinBox = new QSpinBox;
Chris@73 93 m_frameTimeSpinBox->setMaximum(INT_MAX);
Chris@73 94 m_frameTimeSpinBox->setSuffix(tr(" frames"));
Chris@73 95 subgrid->addWidget(m_frameTimeSpinBox, subrow, 1, 1, 2);
Chris@73 96 connect(m_frameTimeSpinBox, SIGNAL(valueChanged(int)),
Chris@938 97 this, SLOT(frameTimeChanged(int)));
Chris@73 98
Chris@73 99 ++subrow;
Chris@73 100
Chris@73 101 m_realTimeSecsSpinBox = new QSpinBox;
Chris@73 102 m_realTimeSecsSpinBox->setMaximum(999999);
Chris@73 103 m_realTimeSecsSpinBox->setSuffix(tr(" sec"));
Chris@73 104 subgrid->addWidget(m_realTimeSecsSpinBox, subrow, 1);
Chris@73 105 connect(m_realTimeSecsSpinBox, SIGNAL(valueChanged(int)),
Chris@73 106 this, SLOT(realTimeSecsChanged(int)));
Chris@73 107
Chris@73 108 m_realTimeUSecsSpinBox = new QSpinBox;
Chris@73 109 m_realTimeUSecsSpinBox->setMaximum(999999);
Chris@73 110 m_realTimeUSecsSpinBox->setSuffix(tr(" usec"));
Chris@73 111 m_realTimeUSecsSpinBox->setSingleStep(singleStep);
Chris@73 112 subgrid->addWidget(m_realTimeUSecsSpinBox, subrow, 2);
Chris@73 113 connect(m_realTimeUSecsSpinBox, SIGNAL(valueChanged(int)),
Chris@73 114 this, SLOT(realTimeUSecsChanged(int)));
Chris@73 115
Chris@73 116 ++subrow;
Chris@73 117 }
Chris@73 118
Chris@70 119 if (options & ShowDuration) {
Chris@70 120
Chris@73 121 subgrid->addWidget(new QLabel(tr("Duration:")), subrow, 0);
Chris@70 122
Chris@73 123 m_frameDurationSpinBox = new QSpinBox;
Chris@73 124 m_frameDurationSpinBox->setMaximum(INT_MAX);
Chris@73 125 m_frameDurationSpinBox->setSuffix(tr(" frames"));
Chris@73 126 subgrid->addWidget(m_frameDurationSpinBox, subrow, 1, 1, 2);
Chris@73 127 connect(m_frameDurationSpinBox, SIGNAL(valueChanged(int)),
Chris@938 128 this, SLOT(frameDurationChanged(int)));
Chris@70 129
Chris@73 130 ++subrow;
Chris@70 131
Chris@73 132 m_realDurationSecsSpinBox = new QSpinBox;
Chris@73 133 m_realDurationSecsSpinBox->setMaximum(999999);
Chris@73 134 m_realDurationSecsSpinBox->setSuffix(tr(" sec"));
Chris@73 135 subgrid->addWidget(m_realDurationSecsSpinBox, subrow, 1);
Chris@73 136 connect(m_realDurationSecsSpinBox, SIGNAL(valueChanged(int)),
Chris@73 137 this, SLOT(realDurationSecsChanged(int)));
Chris@70 138
Chris@73 139 m_realDurationUSecsSpinBox = new QSpinBox;
Chris@73 140 m_realDurationUSecsSpinBox->setMaximum(999999);
Chris@73 141 m_realDurationUSecsSpinBox->setSuffix(tr(" usec"));
Chris@73 142 m_realDurationUSecsSpinBox->setSingleStep(singleStep);
Chris@101 143 subgrid->addWidget(m_realDurationUSecsSpinBox, subrow, 2);
Chris@73 144 connect(m_realDurationUSecsSpinBox, SIGNAL(valueChanged(int)),
Chris@73 145 this, SLOT(realDurationUSecsChanged(int)));
Chris@70 146
Chris@73 147 ++subrow;
Chris@73 148 }
Chris@70 149
Chris@1515 150 if ((options & ShowValue) ||
Chris@1515 151 (options & ShowLevel) ||
Chris@1515 152 (options & ShowText)) {
Chris@70 153
Chris@73 154 valueBox = new QGroupBox;
Chris@73 155 valueBox->setTitle(tr("Properties"));
Chris@73 156 grid->addWidget(valueBox, row, 0);
Chris@73 157
Chris@73 158 subgrid = new QGridLayout;
Chris@73 159 valueBox->setLayout(subgrid);
Chris@70 160
Chris@70 161 ++row;
Chris@70 162 }
Chris@70 163
Chris@73 164 subrow = 0;
Chris@73 165
Chris@70 166 if (options & ShowValue) {
Chris@70 167
Chris@1515 168 subgrid->addWidget(new QLabel(tr("%1:").arg(labelOptions.valueLabel)),
Chris@1515 169 subrow, 0);
Chris@70 170
Chris@73 171 m_valueSpinBox = new QDoubleSpinBox;
Chris@1515 172 m_valueSpinBox->setSuffix(QString(" %1").arg(labelOptions.valueUnits));
Chris@73 173 m_valueSpinBox->setDecimals(10);
Chris@685 174 m_valueSpinBox->setMinimum(-1e10);
Chris@685 175 m_valueSpinBox->setMaximum(1e10);
Chris@73 176 connect(m_valueSpinBox, SIGNAL(valueChanged(double)),
Chris@70 177 this, SLOT(valueChanged(double)));
Chris@73 178 subgrid->addWidget(m_valueSpinBox, subrow, 1);
Chris@70 179
Chris@73 180 ++subrow;
Chris@70 181 }
Chris@70 182
Chris@1515 183 if (options & ShowLevel) {
Chris@1515 184
Chris@1515 185 subgrid->addWidget(new QLabel(tr("%1:").arg(labelOptions.levelLabel)),
Chris@1515 186 subrow, 0);
Chris@1515 187
Chris@1515 188 m_levelSpinBox = new QDoubleSpinBox;
Chris@1515 189 m_levelSpinBox->setSuffix(QString(" %1").arg(labelOptions.levelUnits));
Chris@1515 190 m_levelSpinBox->setDecimals(10);
Chris@1515 191 m_levelSpinBox->setMinimum(-1e10);
Chris@1515 192 m_levelSpinBox->setMaximum(1e10);
Chris@1515 193 connect(m_levelSpinBox, SIGNAL(levelChanged(double)),
Chris@1515 194 this, SLOT(levelChanged(double)));
Chris@1515 195 subgrid->addWidget(m_levelSpinBox, subrow, 1);
Chris@1515 196
Chris@1515 197 ++subrow;
Chris@1515 198 }
Chris@1515 199
Chris@70 200 if (options & ShowText) {
Chris@70 201
Chris@73 202 subgrid->addWidget(new QLabel(tr("Text:")), subrow, 0);
Chris@70 203
Chris@73 204 m_textField = new QLineEdit;
Chris@73 205 connect(m_textField, SIGNAL(textChanged(QString)),
Chris@70 206 this, SLOT(textChanged(QString)));
Chris@73 207 subgrid->addWidget(m_textField, subrow, 1);
Chris@70 208
Chris@73 209 ++subrow;
Chris@73 210 }
Chris@73 211
Chris@73 212 if (options & ShowText) {
Chris@73 213 m_textField->setFocus(Qt::OtherFocusReason);
Chris@73 214 } else if (options & ShowValue) {
Chris@73 215 m_valueSpinBox->setFocus(Qt::OtherFocusReason);
Chris@1515 216 } else if (options & ShowLevel) {
Chris@1515 217 m_levelSpinBox->setFocus(Qt::OtherFocusReason);
Chris@70 218 }
Chris@282 219
Chris@282 220 QDialogButtonBox *bb = new QDialogButtonBox(Qt::Horizontal);
Chris@282 221 grid->addWidget(bb, row, 0, 1, 2);
Chris@70 222
Chris@70 223 QPushButton *ok = new QPushButton(tr("OK"));
Chris@73 224 m_resetButton = new QPushButton(tr("Reset"));
Chris@70 225 QPushButton *cancel = new QPushButton(tr("Cancel"));
Chris@282 226 bb->addButton(ok, QDialogButtonBox::AcceptRole);
Chris@282 227 bb->addButton(m_resetButton, QDialogButtonBox::ResetRole);
Chris@282 228 bb->addButton(cancel, QDialogButtonBox::RejectRole);
Chris@70 229 connect(ok, SIGNAL(clicked()), this, SLOT(accept()));
Chris@73 230 connect(m_resetButton, SIGNAL(clicked()), this, SLOT(reset()));
Chris@70 231 connect(cancel, SIGNAL(clicked()), this, SLOT(reject()));
Chris@73 232 m_resetButton->setEnabled(false);
Chris@70 233 }
Chris@70 234
Chris@70 235 void
Chris@904 236 ItemEditDialog::setFrameTime(sv_frame_t frame)
Chris@70 237 {
Chris@73 238 if (!m_frameTimeSpinBox) return;
Chris@73 239
Chris@73 240 RealTime rt(RealTime::frame2RealTime(frame, m_sampleRate));
Chris@73 241 m_realTimeSecsSpinBox->setValue(rt.sec);
Chris@73 242 m_realTimeUSecsSpinBox->setValue(rt.usec());
Chris@908 243 m_frameTimeSpinBox->setValue(int(frame));
Chris@73 244 m_defaultFrame = frame;
Chris@73 245 m_resetButton->setEnabled(false);
Chris@70 246 }
Chris@70 247
Chris@904 248 sv_frame_t
Chris@70 249 ItemEditDialog::getFrameTime() const
Chris@70 250 {
Chris@73 251 return m_frameTimeSpinBox->value();
Chris@70 252 }
Chris@70 253
Chris@70 254 void
Chris@70 255 ItemEditDialog::setRealTime(RealTime rt)
Chris@70 256 {
Chris@73 257 setFrameTime(RealTime::realTime2Frame(rt, m_sampleRate));
Chris@70 258 }
Chris@70 259
Chris@70 260 RealTime
Chris@70 261 ItemEditDialog::getRealTime() const
Chris@70 262 {
Chris@73 263 return RealTime::frame2RealTime(getFrameTime(), m_sampleRate);
Chris@70 264 }
Chris@70 265
Chris@70 266 void
Chris@904 267 ItemEditDialog::setFrameDuration(sv_frame_t duration)
Chris@70 268 {
Chris@73 269 if (!m_frameDurationSpinBox) return;
Chris@73 270
Chris@73 271 RealTime rt(RealTime::frame2RealTime(duration, m_sampleRate));
Chris@73 272 m_realDurationSecsSpinBox->setValue(rt.sec);
Chris@73 273 m_realDurationUSecsSpinBox->setValue(rt.usec());
Chris@908 274 m_frameDurationSpinBox->setValue(int(duration));
Chris@73 275 m_defaultDuration = duration;
Chris@73 276 m_resetButton->setEnabled(false);
Chris@70 277 }
Chris@70 278
Chris@904 279 sv_frame_t
Chris@70 280 ItemEditDialog::getFrameDuration() const
Chris@70 281 {
Chris@73 282 return m_frameDurationSpinBox->value();
Chris@70 283 }
Chris@70 284
Chris@70 285 void
Chris@70 286 ItemEditDialog::setRealDuration(RealTime rt)
Chris@70 287 {
Chris@73 288 setFrameDuration(RealTime::realTime2Frame(rt, m_sampleRate));
Chris@70 289 }
Chris@70 290
Chris@70 291 RealTime
Chris@70 292 ItemEditDialog::getRealDuration() const
Chris@70 293 {
Chris@73 294 return RealTime::frame2RealTime(getFrameDuration(), m_sampleRate);
Chris@70 295 }
Chris@70 296
Chris@70 297 void
Chris@70 298 ItemEditDialog::setValue(float v)
Chris@70 299 {
Chris@73 300 if (!m_valueSpinBox) return;
Chris@73 301
Chris@73 302 m_valueSpinBox->setValue(v);
Chris@73 303 m_defaultValue = v;
Chris@73 304 m_resetButton->setEnabled(false);
Chris@70 305 }
Chris@70 306
Chris@70 307 float
Chris@70 308 ItemEditDialog::getValue() const
Chris@70 309 {
Chris@908 310 return float(m_valueSpinBox->value());
Chris@70 311 }
Chris@70 312
Chris@70 313 void
Chris@1515 314 ItemEditDialog::setLevel(float v)
Chris@1515 315 {
Chris@1515 316 if (!m_levelSpinBox) return;
Chris@1515 317
Chris@1515 318 m_levelSpinBox->setValue(v);
Chris@1515 319 m_defaultLevel = v;
Chris@1515 320 m_resetButton->setEnabled(false);
Chris@1515 321 }
Chris@1515 322
Chris@1515 323 float
Chris@1515 324 ItemEditDialog::getLevel() const
Chris@1515 325 {
Chris@1515 326 return float(m_levelSpinBox->value());
Chris@1515 327 }
Chris@1515 328
Chris@1515 329 void
Chris@70 330 ItemEditDialog::setText(QString text)
Chris@70 331 {
Chris@73 332 if (!m_textField) return;
Chris@73 333
Chris@73 334 m_textField->setText(text);
Chris@73 335 m_defaultText = text;
Chris@73 336 m_resetButton->setEnabled(false);
Chris@70 337 }
Chris@70 338
Chris@70 339 QString
Chris@70 340 ItemEditDialog::getText() const
Chris@70 341 {
Chris@73 342 return m_textField->text();
Chris@70 343 }
Chris@70 344
Chris@70 345 void
Chris@938 346 ItemEditDialog::frameTimeChanged(int i)
Chris@70 347 {
Chris@73 348 m_realTimeSecsSpinBox->blockSignals(true);
Chris@73 349 m_realTimeUSecsSpinBox->blockSignals(true);
Chris@73 350
Chris@73 351 RealTime rt(RealTime::frame2RealTime(i, m_sampleRate));
Chris@73 352 m_realTimeSecsSpinBox->setValue(rt.sec);
Chris@73 353 m_realTimeUSecsSpinBox->setValue(rt.usec());
Chris@73 354
Chris@73 355 m_realTimeSecsSpinBox->blockSignals(false);
Chris@73 356 m_realTimeUSecsSpinBox->blockSignals(false);
Chris@73 357 m_resetButton->setEnabled(true);
Chris@70 358 }
Chris@70 359
Chris@70 360 void
Chris@73 361 ItemEditDialog::realTimeSecsChanged(int i)
Chris@70 362 {
Chris@70 363 RealTime rt = getRealTime();
Chris@73 364 rt.sec = i;
Chris@904 365 sv_frame_t frame = RealTime::realTime2Frame(rt, m_sampleRate);
Chris@908 366 m_frameTimeSpinBox->setValue(int(frame));
Chris@73 367 m_resetButton->setEnabled(true);
Chris@70 368 }
Chris@70 369
Chris@70 370 void
Chris@73 371 ItemEditDialog::realTimeUSecsChanged(int i)
Chris@70 372 {
Chris@70 373 RealTime rt = getRealTime();
Chris@73 374 rt.nsec = i * 1000;
Chris@904 375 sv_frame_t frame = RealTime::realTime2Frame(rt, m_sampleRate);
Chris@908 376 m_frameTimeSpinBox->setValue(int(frame));
Chris@73 377 m_resetButton->setEnabled(true);
Chris@70 378 }
Chris@70 379
Chris@70 380 void
Chris@938 381 ItemEditDialog::frameDurationChanged(int i)
Chris@70 382 {
Chris@73 383 m_realDurationSecsSpinBox->blockSignals(true);
Chris@73 384 m_realDurationUSecsSpinBox->blockSignals(true);
Chris@73 385
Chris@73 386 RealTime rt(RealTime::frame2RealTime(i, m_sampleRate));
Chris@73 387 m_realDurationSecsSpinBox->setValue(rt.sec);
Chris@73 388 m_realDurationUSecsSpinBox->setValue(rt.usec());
Chris@73 389
Chris@73 390 m_realDurationSecsSpinBox->blockSignals(false);
Chris@73 391 m_realDurationUSecsSpinBox->blockSignals(false);
Chris@73 392 m_resetButton->setEnabled(true);
Chris@70 393 }
Chris@70 394
Chris@70 395 void
Chris@73 396 ItemEditDialog::realDurationSecsChanged(int i)
Chris@70 397 {
Chris@70 398 RealTime rt = getRealDuration();
Chris@73 399 rt.sec = i;
Chris@904 400 sv_frame_t frame = RealTime::realTime2Frame(rt, m_sampleRate);
Chris@908 401 m_frameDurationSpinBox->setValue(int(frame));
Chris@73 402 m_resetButton->setEnabled(true);
Chris@70 403 }
Chris@70 404
Chris@70 405 void
Chris@73 406 ItemEditDialog::realDurationUSecsChanged(int i)
Chris@70 407 {
Chris@70 408 RealTime rt = getRealDuration();
Chris@73 409 rt.nsec = i * 1000;
Chris@904 410 sv_frame_t frame = RealTime::realTime2Frame(rt, m_sampleRate);
Chris@908 411 m_frameDurationSpinBox->setValue(int(frame));
Chris@73 412 m_resetButton->setEnabled(true);
Chris@70 413 }
Chris@70 414
Chris@70 415 void
Chris@73 416 ItemEditDialog::valueChanged(double)
Chris@70 417 {
Chris@73 418 m_resetButton->setEnabled(true);
Chris@70 419 }
Chris@70 420
Chris@70 421 void
Chris@1515 422 ItemEditDialog::levelChanged(double)
Chris@1515 423 {
Chris@1515 424 m_resetButton->setEnabled(true);
Chris@1515 425 }
Chris@1515 426
Chris@1515 427 void
Chris@73 428 ItemEditDialog::textChanged(QString)
Chris@70 429 {
Chris@73 430 m_resetButton->setEnabled(true);
Chris@70 431 }
Chris@70 432
Chris@73 433 void
Chris@73 434 ItemEditDialog::reset()
Chris@73 435 {
Chris@73 436 setFrameTime(m_defaultFrame);
Chris@73 437 setFrameDuration(m_defaultDuration);
Chris@73 438 setValue(m_defaultValue);
Chris@1515 439 setLevel(m_defaultLevel);
Chris@73 440 setText(m_defaultText);
Chris@73 441 m_resetButton->setEnabled(false);
Chris@73 442 }
Chris@73 443