comparison main/MainWindow.cpp @ 90:51ea003f8f99

* Add large chunks of context help in the optional status bar * Add an extra overlay mode in which even the centre frame is disabled * Fixes to FTP retrieval
author Chris Cannam
date Fri, 19 Jan 2007 13:13:14 +0000
parents 51be0daa1386
children 7005d8a9f0e0
comparison
equal deleted inserted replaced
89:a4e79db79282 90:51ea003f8f99
36 #include "widgets/PropertyStack.h" 36 #include "widgets/PropertyStack.h"
37 #include "widgets/AudioDial.h" 37 #include "widgets/AudioDial.h"
38 #include "widgets/LayerTree.h" 38 #include "widgets/LayerTree.h"
39 #include "widgets/ListInputDialog.h" 39 #include "widgets/ListInputDialog.h"
40 #include "widgets/SubdividingMenu.h" 40 #include "widgets/SubdividingMenu.h"
41 #include "widgets/NotifyingPushButton.h"
41 #include "audioio/AudioCallbackPlaySource.h" 42 #include "audioio/AudioCallbackPlaySource.h"
42 #include "audioio/AudioCallbackPlayTarget.h" 43 #include "audioio/AudioCallbackPlayTarget.h"
43 #include "audioio/AudioTargetFactory.h" 44 #include "audioio/AudioTargetFactory.h"
44 #include "audioio/PlaySpeedRangeMapper.h" 45 #include "audioio/PlaySpeedRangeMapper.h"
45 #include "data/fileio/AudioFileReaderFactory.h" 46 #include "data/fileio/AudioFileReaderFactory.h"
62 #include "vamp-sdk/PluginBase.h" 63 #include "vamp-sdk/PluginBase.h"
63 #include "plugin/api/ladspa.h" 64 #include "plugin/api/ladspa.h"
64 #include "plugin/api/dssi.h" 65 #include "plugin/api/dssi.h"
65 66
66 #include <QApplication> 67 #include <QApplication>
67 #include <QPushButton>
68 #include <QMessageBox> 68 #include <QMessageBox>
69 #include <QGridLayout> 69 #include <QGridLayout>
70 #include <QLabel> 70 #include <QLabel>
71 #include <QAction> 71 #include <QAction>
72 #include <QMenuBar> 72 #include <QMenuBar>
153 this, SLOT(currentLayerChanged(Pane *, Layer *))); 153 this, SLOT(currentLayerChanged(Pane *, Layer *)));
154 connect(m_paneStack, SIGNAL(rightButtonMenuRequested(Pane *, QPoint)), 154 connect(m_paneStack, SIGNAL(rightButtonMenuRequested(Pane *, QPoint)),
155 this, SLOT(rightButtonMenuRequested(Pane *, QPoint))); 155 this, SLOT(rightButtonMenuRequested(Pane *, QPoint)));
156 connect(m_paneStack, SIGNAL(propertyStacksResized()), 156 connect(m_paneStack, SIGNAL(propertyStacksResized()),
157 this, SLOT(propertyStacksResized())); 157 this, SLOT(propertyStacksResized()));
158 connect(m_paneStack, SIGNAL(contextHelpChanged(const QString &)),
159 statusBar(), SLOT(showMessage(const QString &)));
158 160
159 m_overview = new Overview(frame); 161 m_overview = new Overview(frame);
160 m_overview->setViewManager(m_viewManager); 162 m_overview->setViewManager(m_viewManager);
161 m_overview->setFixedHeight(40); 163 m_overview->setFixedHeight(40);
164 connect(m_overview, SIGNAL(contextHelpChanged(const QString &)),
165 statusBar(), SLOT(showMessage(const QString &)));
162 166
163 m_panLayer = new WaveformLayer; 167 m_panLayer = new WaveformLayer;
164 m_panLayer->setChannelMode(WaveformLayer::MergeChannels); 168 m_panLayer->setChannelMode(WaveformLayer::MergeChannels);
165 // m_panLayer->setScale(WaveformLayer::MeterScale); 169 // m_panLayer->setScale(WaveformLayer::MeterScale);
166 // m_panLayer->setAutoNormalize(true); 170 // m_panLayer->setAutoNormalize(true);
174 this, SLOT(sampleRateMismatch(size_t, size_t, bool))); 178 this, SLOT(sampleRateMismatch(size_t, size_t, bool)));
175 connect(m_playSource, SIGNAL(audioOverloadPluginDisabled()), 179 connect(m_playSource, SIGNAL(audioOverloadPluginDisabled()),
176 this, SLOT(audioOverloadPluginDisabled())); 180 this, SLOT(audioOverloadPluginDisabled()));
177 181
178 m_fader = new Fader(frame, false); 182 m_fader = new Fader(frame, false);
183 connect(m_fader, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredWidget()));
184 connect(m_fader, SIGNAL(mouseLeft()), this, SLOT(mouseLeftWidget()));
179 185
180 m_playSpeed = new AudioDial(frame); 186 m_playSpeed = new AudioDial(frame);
181 m_playSpeed->setMinimum(0); 187 m_playSpeed->setMinimum(0);
182 m_playSpeed->setMaximum(200); 188 m_playSpeed->setMaximum(200);
183 m_playSpeed->setValue(100); 189 m_playSpeed->setValue(100);
189 m_playSpeed->setDefaultValue(100); 195 m_playSpeed->setDefaultValue(100);
190 m_playSpeed->setRangeMapper(new PlaySpeedRangeMapper(0, 200)); 196 m_playSpeed->setRangeMapper(new PlaySpeedRangeMapper(0, 200));
191 m_playSpeed->setShowToolTip(true); 197 m_playSpeed->setShowToolTip(true);
192 connect(m_playSpeed, SIGNAL(valueChanged(int)), 198 connect(m_playSpeed, SIGNAL(valueChanged(int)),
193 this, SLOT(playSpeedChanged(int))); 199 this, SLOT(playSpeedChanged(int)));
194 200 connect(m_playSpeed, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredWidget()));
195 m_playSharpen = new QPushButton(frame); 201 connect(m_playSpeed, SIGNAL(mouseLeft()), this, SLOT(mouseLeftWidget()));
202
203 m_playSharpen = new NotifyingPushButton(frame);
196 m_playSharpen->setToolTip(tr("Sharpen percussive transients")); 204 m_playSharpen->setToolTip(tr("Sharpen percussive transients"));
197 m_playSharpen->setFixedSize(20, 20); 205 m_playSharpen->setFixedSize(20, 20);
198 // m_playSharpen->setFlat(true); 206 // m_playSharpen->setFlat(true);
199 m_playSharpen->setEnabled(false); 207 m_playSharpen->setEnabled(false);
200 m_playSharpen->setCheckable(true); 208 m_playSharpen->setCheckable(true);
201 m_playSharpen->setChecked(false); 209 m_playSharpen->setChecked(false);
202 m_playSharpen->setIcon(QIcon(":icons/sharpen.png")); 210 m_playSharpen->setIcon(QIcon(":icons/sharpen.png"));
203 connect(m_playSharpen, SIGNAL(clicked()), this, SLOT(playSharpenToggled())); 211 connect(m_playSharpen, SIGNAL(clicked()), this, SLOT(playSharpenToggled()));
204 212 connect(m_playSharpen, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredWidget()));
205 m_playMono = new QPushButton(frame); 213 connect(m_playSharpen, SIGNAL(mouseLeft()), this, SLOT(mouseLeftWidget()));
214
215 m_playMono = new NotifyingPushButton(frame);
206 m_playMono->setToolTip(tr("Run time stretcher in mono only")); 216 m_playMono->setToolTip(tr("Run time stretcher in mono only"));
207 m_playMono->setFixedSize(20, 20); 217 m_playMono->setFixedSize(20, 20);
208 // m_playMono->setFlat(true); 218 // m_playMono->setFlat(true);
209 m_playMono->setEnabled(false); 219 m_playMono->setEnabled(false);
210 m_playMono->setCheckable(true); 220 m_playMono->setCheckable(true);
211 m_playMono->setChecked(false); 221 m_playMono->setChecked(false);
212 m_playMono->setIcon(QIcon(":icons/mono.png")); 222 m_playMono->setIcon(QIcon(":icons/mono.png"));
213 connect(m_playMono, SIGNAL(clicked()), this, SLOT(playMonoToggled())); 223 connect(m_playMono, SIGNAL(clicked()), this, SLOT(playMonoToggled()));
224 connect(m_playMono, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredWidget()));
225 connect(m_playMono, SIGNAL(mouseLeft()), this, SLOT(mouseLeftWidget()));
214 226
215 QSettings settings; 227 QSettings settings;
216 settings.beginGroup("MainWindow"); 228 settings.beginGroup("MainWindow");
217 m_playSharpen->setChecked(settings.value("playsharpen", true).toBool()); 229 m_playSharpen->setChecked(settings.value("playsharpen", true).toBool());
218 m_playMono->setChecked(settings.value("playmono", false).toBool()); 230 m_playMono->setChecked(settings.value("playmono", false).toBool());
245 } 257 }
246 258
247 setupMenus(); 259 setupMenus();
248 setupToolbars(); 260 setupToolbars();
249 261
250 // statusBar()->addWidget(m_descriptionLabel); 262 statusBar();
251 263
252 newSession(); 264 newSession();
253 } 265 }
254 266
255 MainWindow::~MainWindow() 267 MainWindow::~MainWindow()
362 374
363 QIcon icon(":icons/filenew.png"); 375 QIcon icon(":icons/filenew.png");
364 icon.addFile(":icons/filenew-22.png"); 376 icon.addFile(":icons/filenew-22.png");
365 QAction *action = new QAction(icon, tr("&New Session"), this); 377 QAction *action = new QAction(icon, tr("&New Session"), this);
366 action->setShortcut(tr("Ctrl+N")); 378 action->setShortcut(tr("Ctrl+N"));
367 action->setStatusTip(tr("Clear the current Sonic Visualiser session and start a new one")); 379 action->setStatusTip(tr("Abandon the current Sonic Visualiser session and start a new one"));
368 connect(action, SIGNAL(triggered()), this, SLOT(newSession())); 380 connect(action, SIGNAL(triggered()), this, SLOT(newSession()));
369 menu->addAction(action); 381 menu->addAction(action);
370 toolbar->addAction(action); 382 toolbar->addAction(action);
371 383
372 icon = QIcon(":icons/fileopen.png"); 384 icon = QIcon(":icons/fileopen.png");
470 482
471 menu->addSeparator(); 483 menu->addSeparator();
472 action = new QAction(QIcon(":/icons/exit.png"), 484 action = new QAction(QIcon(":/icons/exit.png"),
473 tr("&Quit"), this); 485 tr("&Quit"), this);
474 action->setShortcut(tr("Ctrl+Q")); 486 action->setShortcut(tr("Ctrl+Q"));
487 action->setStatusTip(tr("Exit Sonic Visualiser"));
475 connect(action, SIGNAL(triggered()), this, SLOT(close())); 488 connect(action, SIGNAL(triggered()), this, SLOT(close()));
476 menu->addAction(action); 489 menu->addAction(action);
477 } 490 }
478 491
479 void 492 void
487 menu->addSeparator(); 500 menu->addSeparator();
488 501
489 QAction *action = new QAction(QIcon(":/icons/editcut.png"), 502 QAction *action = new QAction(QIcon(":/icons/editcut.png"),
490 tr("Cu&t"), this); 503 tr("Cu&t"), this);
491 action->setShortcut(tr("Ctrl+X")); 504 action->setShortcut(tr("Ctrl+X"));
505 action->setStatusTip(tr("Cut the selection from the current layer to the clipboard"));
492 connect(action, SIGNAL(triggered()), this, SLOT(cut())); 506 connect(action, SIGNAL(triggered()), this, SLOT(cut()));
493 connect(this, SIGNAL(canEditSelection(bool)), action, SLOT(setEnabled(bool))); 507 connect(this, SIGNAL(canEditSelection(bool)), action, SLOT(setEnabled(bool)));
494 menu->addAction(action); 508 menu->addAction(action);
495 m_rightButtonMenu->addAction(action); 509 m_rightButtonMenu->addAction(action);
496 510
497 action = new QAction(QIcon(":/icons/editcopy.png"), 511 action = new QAction(QIcon(":/icons/editcopy.png"),
498 tr("&Copy"), this); 512 tr("&Copy"), this);
499 action->setShortcut(tr("Ctrl+C")); 513 action->setShortcut(tr("Ctrl+C"));
514 action->setStatusTip(tr("Copy the selection from the current layer to the clipboard"));
500 connect(action, SIGNAL(triggered()), this, SLOT(copy())); 515 connect(action, SIGNAL(triggered()), this, SLOT(copy()));
501 connect(this, SIGNAL(canEditSelection(bool)), action, SLOT(setEnabled(bool))); 516 connect(this, SIGNAL(canEditSelection(bool)), action, SLOT(setEnabled(bool)));
502 menu->addAction(action); 517 menu->addAction(action);
503 m_rightButtonMenu->addAction(action); 518 m_rightButtonMenu->addAction(action);
504 519
505 action = new QAction(QIcon(":/icons/editpaste.png"), 520 action = new QAction(QIcon(":/icons/editpaste.png"),
506 tr("&Paste"), this); 521 tr("&Paste"), this);
507 action->setShortcut(tr("Ctrl+V")); 522 action->setShortcut(tr("Ctrl+V"));
523 action->setStatusTip(tr("Paste from the clipboard to the current layer"));
508 connect(action, SIGNAL(triggered()), this, SLOT(paste())); 524 connect(action, SIGNAL(triggered()), this, SLOT(paste()));
509 connect(this, SIGNAL(canPaste(bool)), action, SLOT(setEnabled(bool))); 525 connect(this, SIGNAL(canPaste(bool)), action, SLOT(setEnabled(bool)));
510 menu->addAction(action); 526 menu->addAction(action);
511 m_rightButtonMenu->addAction(action); 527 m_rightButtonMenu->addAction(action);
512 528
513 action = new QAction(tr("&Delete Selected Items"), this); 529 action = new QAction(tr("&Delete Selected Items"), this);
514 action->setShortcut(tr("Del")); 530 action->setShortcut(tr("Del"));
531 action->setStatusTip(tr("Delete the selection from the current layer"));
515 connect(action, SIGNAL(triggered()), this, SLOT(deleteSelected())); 532 connect(action, SIGNAL(triggered()), this, SLOT(deleteSelected()));
516 connect(this, SIGNAL(canEditSelection(bool)), action, SLOT(setEnabled(bool))); 533 connect(this, SIGNAL(canEditSelection(bool)), action, SLOT(setEnabled(bool)));
517 menu->addAction(action); 534 menu->addAction(action);
518 m_rightButtonMenu->addAction(action); 535 m_rightButtonMenu->addAction(action);
519 536
520 menu->addSeparator(); 537 menu->addSeparator();
521 m_rightButtonMenu->addSeparator(); 538 m_rightButtonMenu->addSeparator();
522 539
523 action = new QAction(tr("Select &All"), this); 540 action = new QAction(tr("Select &All"), this);
524 action->setShortcut(tr("Ctrl+A")); 541 action->setShortcut(tr("Ctrl+A"));
542 action->setStatusTip(tr("Select the whole duration of the current session"));
525 connect(action, SIGNAL(triggered()), this, SLOT(selectAll())); 543 connect(action, SIGNAL(triggered()), this, SLOT(selectAll()));
526 connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool))); 544 connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool)));
527 menu->addAction(action); 545 menu->addAction(action);
528 m_rightButtonMenu->addAction(action); 546 m_rightButtonMenu->addAction(action);
529 547
530 action = new QAction(tr("Select &Visible Range"), this); 548 action = new QAction(tr("Select &Visible Range"), this);
531 action->setShortcut(tr("Ctrl+Shift+A")); 549 action->setShortcut(tr("Ctrl+Shift+A"));
550 action->setStatusTip(tr("Select the time range corresponding to the current window width"));
532 connect(action, SIGNAL(triggered()), this, SLOT(selectVisible())); 551 connect(action, SIGNAL(triggered()), this, SLOT(selectVisible()));
533 connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool))); 552 connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool)));
534 menu->addAction(action); 553 menu->addAction(action);
535 554
536 action = new QAction(tr("Select to &Start"), this); 555 action = new QAction(tr("Select to &Start"), this);
537 action->setShortcut(tr("Shift+Left")); 556 action->setShortcut(tr("Shift+Left"));
557 action->setStatusTip(tr("Select from the start of the session to the current playback position"));
538 connect(action, SIGNAL(triggered()), this, SLOT(selectToStart())); 558 connect(action, SIGNAL(triggered()), this, SLOT(selectToStart()));
539 connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool))); 559 connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool)));
540 menu->addAction(action); 560 menu->addAction(action);
541 561
542 action = new QAction(tr("Select to &End"), this); 562 action = new QAction(tr("Select to &End"), this);
543 action->setShortcut(tr("Shift+Right")); 563 action->setShortcut(tr("Shift+Right"));
564 action->setStatusTip(tr("Select from the current playback position to the end of the session"));
544 connect(action, SIGNAL(triggered()), this, SLOT(selectToEnd())); 565 connect(action, SIGNAL(triggered()), this, SLOT(selectToEnd()));
545 connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool))); 566 connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool)));
546 menu->addAction(action); 567 menu->addAction(action);
547 568
548 action = new QAction(tr("C&lear Selection"), this); 569 action = new QAction(tr("C&lear Selection"), this);
549 action->setShortcut(tr("Esc")); 570 action->setShortcut(tr("Esc"));
571 action->setStatusTip(tr("Clear the selection"));
550 connect(action, SIGNAL(triggered()), this, SLOT(clearSelection())); 572 connect(action, SIGNAL(triggered()), this, SLOT(clearSelection()));
551 connect(this, SIGNAL(canClearSelection(bool)), action, SLOT(setEnabled(bool))); 573 connect(this, SIGNAL(canClearSelection(bool)), action, SLOT(setEnabled(bool)));
552 menu->addAction(action); 574 menu->addAction(action);
553 m_rightButtonMenu->addAction(action); 575 m_rightButtonMenu->addAction(action);
554 576
555 menu->addSeparator(); 577 menu->addSeparator();
556 578
557 action = new QAction(tr("&Insert Instant at Playback Position"), this); 579 action = new QAction(tr("&Insert Instant at Playback Position"), this);
558 action->setShortcut(tr("Enter")); 580 action->setShortcut(tr("Enter"));
581 action->setStatusTip(tr("Insert a new time instant at the current playback position, in a new layer if necessary"));
559 connect(action, SIGNAL(triggered()), this, SLOT(insertInstant())); 582 connect(action, SIGNAL(triggered()), this, SLOT(insertInstant()));
560 connect(this, SIGNAL(canInsertInstant(bool)), action, SLOT(setEnabled(bool))); 583 connect(this, SIGNAL(canInsertInstant(bool)), action, SLOT(setEnabled(bool)));
561 menu->addAction(action); 584 menu->addAction(action);
562 585
563 action = new QAction(tr("Insert Instants at Selection &Boundaries"), this); 586 action = new QAction(tr("Insert Instants at Selection &Boundaries"), this);
564 action->setShortcut(tr("Shift+Enter")); 587 action->setShortcut(tr("Shift+Enter"));
588 action->setStatusTip(tr("Insert new time instants at the start and end of the current selection, in a new layer if necessary"));
565 connect(action, SIGNAL(triggered()), this, SLOT(insertInstantsAtBoundaries())); 589 connect(action, SIGNAL(triggered()), this, SLOT(insertInstantsAtBoundaries()));
566 connect(this, SIGNAL(canInsertInstantsAtBoundaries(bool)), action, SLOT(setEnabled(bool))); 590 connect(this, SIGNAL(canInsertInstantsAtBoundaries(bool)), action, SLOT(setEnabled(bool)));
567 menu->addAction(action); 591 menu->addAction(action);
568 592
569 // Laptop shortcut (no keypad Enter key) 593 // Laptop shortcut (no keypad Enter key)
574 void 598 void
575 MainWindow::setupViewMenu() 599 MainWindow::setupViewMenu()
576 { 600 {
577 if (m_mainMenusCreated) return; 601 if (m_mainMenusCreated) return;
578 602
603 QAction *action = 0;
604
579 QMenu *menu = menuBar()->addMenu(tr("&View")); 605 QMenu *menu = menuBar()->addMenu(tr("&View"));
580
581 QActionGroup *overlayGroup = new QActionGroup(this);
582
583 QAction *action = new QAction(tr("&No Text Overlays"), this);
584 action->setShortcut(tr("0"));
585 action->setStatusTip(tr("Show no texts for frame times, layer names etc"));
586 connect(action, SIGNAL(triggered()), this, SLOT(showNoOverlays()));
587 action->setCheckable(true);
588 action->setChecked(false);
589 overlayGroup->addAction(action);
590 menu->addAction(action);
591
592 action = new QAction(tr("Basic &Text Overlays"), this);
593 action->setShortcut(tr("9"));
594 action->setStatusTip(tr("Show texts for frame times etc, but not layer names etc"));
595 connect(action, SIGNAL(triggered()), this, SLOT(showBasicOverlays()));
596 action->setCheckable(true);
597 action->setChecked(true);
598 overlayGroup->addAction(action);
599 menu->addAction(action);
600
601 action = new QAction(tr("&All Text Overlays"), this);
602 action->setShortcut(tr("8"));
603 action->setStatusTip(tr("Show texts for frame times, layer names etc"));
604 connect(action, SIGNAL(triggered()), this, SLOT(showAllTextOverlays()));
605 action->setCheckable(true);
606 action->setChecked(false);
607 overlayGroup->addAction(action);
608 menu->addAction(action);
609
610 menu->addSeparator();
611
612 action = new QAction(tr("Scroll &Left"), this); 606 action = new QAction(tr("Scroll &Left"), this);
613 action->setShortcut(tr("Left")); 607 action->setShortcut(tr("Left"));
614 action->setStatusTip(tr("Scroll the current pane to the left")); 608 action->setStatusTip(tr("Scroll the current pane to the left"));
615 connect(action, SIGNAL(triggered()), this, SLOT(scrollLeft())); 609 connect(action, SIGNAL(triggered()), this, SLOT(scrollLeft()));
616 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool))); 610 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool)));
621 action->setStatusTip(tr("Scroll the current pane to the right")); 615 action->setStatusTip(tr("Scroll the current pane to the right"));
622 connect(action, SIGNAL(triggered()), this, SLOT(scrollRight())); 616 connect(action, SIGNAL(triggered()), this, SLOT(scrollRight()));
623 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool))); 617 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool)));
624 menu->addAction(action); 618 menu->addAction(action);
625 619
626 action = new QAction(tr("Jump Left"), this); 620 action = new QAction(tr("&Jump Left"), this);
627 action->setShortcut(tr("Ctrl+Left")); 621 action->setShortcut(tr("Ctrl+Left"));
628 action->setStatusTip(tr("Scroll the current pane a big step to the left")); 622 action->setStatusTip(tr("Scroll the current pane a big step to the left"));
629 connect(action, SIGNAL(triggered()), this, SLOT(jumpLeft())); 623 connect(action, SIGNAL(triggered()), this, SLOT(jumpLeft()));
630 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool))); 624 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool)));
631 menu->addAction(action); 625 menu->addAction(action);
632 626
633 action = new QAction(tr("Jump Right"), this); 627 action = new QAction(tr("J&ump Right"), this);
634 action->setShortcut(tr("Ctrl+Right")); 628 action->setShortcut(tr("Ctrl+Right"));
635 action->setStatusTip(tr("Scroll the current pane a big step to the right")); 629 action->setStatusTip(tr("Scroll the current pane a big step to the right"));
636 connect(action, SIGNAL(triggered()), this, SLOT(jumpRight())); 630 connect(action, SIGNAL(triggered()), this, SLOT(jumpRight()));
637 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool))); 631 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool)));
638 menu->addAction(action); 632 menu->addAction(action);
654 connect(action, SIGNAL(triggered()), this, SLOT(zoomOut())); 648 connect(action, SIGNAL(triggered()), this, SLOT(zoomOut()));
655 connect(this, SIGNAL(canZoom(bool)), action, SLOT(setEnabled(bool))); 649 connect(this, SIGNAL(canZoom(bool)), action, SLOT(setEnabled(bool)));
656 menu->addAction(action); 650 menu->addAction(action);
657 651
658 action = new QAction(tr("Restore &Default Zoom"), this); 652 action = new QAction(tr("Restore &Default Zoom"), this);
653 action->setStatusTip(tr("Restore the zoom level to the default"));
659 connect(action, SIGNAL(triggered()), this, SLOT(zoomDefault())); 654 connect(action, SIGNAL(triggered()), this, SLOT(zoomDefault()));
660 connect(this, SIGNAL(canZoom(bool)), action, SLOT(setEnabled(bool))); 655 connect(this, SIGNAL(canZoom(bool)), action, SLOT(setEnabled(bool)));
661 menu->addAction(action); 656 menu->addAction(action);
662 657
663 action = new QAction(tr("Zoom to &Fit"), this); 658 action = new QAction(tr("Zoom to &Fit"), this);
664 action->setStatusTip(tr("Zoom to show the whole file")); 659 action->setStatusTip(tr("Zoom to show the whole file"));
665 connect(action, SIGNAL(triggered()), this, SLOT(zoomToFit())); 660 connect(action, SIGNAL(triggered()), this, SLOT(zoomToFit()));
666 connect(this, SIGNAL(canZoom(bool)), action, SLOT(setEnabled(bool))); 661 connect(this, SIGNAL(canZoom(bool)), action, SLOT(setEnabled(bool)));
662 menu->addAction(action);
663
664 menu->addSeparator();
665
666 QActionGroup *overlayGroup = new QActionGroup(this);
667
668 action = new QAction(tr("Show &No Overlays"), this);
669 action->setShortcut(tr("0"));
670 action->setStatusTip(tr("Hide centre indicator, frame times, layer names and scale"));
671 connect(action, SIGNAL(triggered()), this, SLOT(showNoOverlays()));
672 action->setCheckable(true);
673 action->setChecked(false);
674 overlayGroup->addAction(action);
675 menu->addAction(action);
676
677 action = new QAction(tr("Show &Minimal Overlays"), this);
678 action->setShortcut(tr("9"));
679 action->setStatusTip(tr("Show centre indicator only"));
680 connect(action, SIGNAL(triggered()), this, SLOT(showMinimalOverlays()));
681 action->setCheckable(true);
682 action->setChecked(false);
683 overlayGroup->addAction(action);
684 menu->addAction(action);
685
686 action = new QAction(tr("Show &Standard Overlays"), this);
687 action->setShortcut(tr("8"));
688 action->setStatusTip(tr("Show centre indicator, frame times and scale"));
689 connect(action, SIGNAL(triggered()), this, SLOT(showStandardOverlays()));
690 action->setCheckable(true);
691 action->setChecked(true);
692 overlayGroup->addAction(action);
693 menu->addAction(action);
694
695 action = new QAction(tr("Show &All Overlays"), this);
696 action->setShortcut(tr("7"));
697 action->setStatusTip(tr("Show all texts and scale"));
698 connect(action, SIGNAL(triggered()), this, SLOT(showAllOverlays()));
699 action->setCheckable(true);
700 action->setChecked(false);
701 overlayGroup->addAction(action);
667 menu->addAction(action); 702 menu->addAction(action);
668 703
669 menu->addSeparator(); 704 menu->addSeparator();
670 705
671 action = new QAction(tr("Show &Zoom Wheels"), this); 706 action = new QAction(tr("Show &Zoom Wheels"), this);
682 connect(action, SIGNAL(triggered()), this, SLOT(togglePropertyBoxes())); 717 connect(action, SIGNAL(triggered()), this, SLOT(togglePropertyBoxes()));
683 action->setCheckable(true); 718 action->setCheckable(true);
684 action->setChecked(true); 719 action->setChecked(true);
685 menu->addAction(action); 720 menu->addAction(action);
686 721
722 action = new QAction(tr("Show Status &Bar"), this);
723 action->setStatusTip(tr("Show context help information in the status bar at the bottom of the window"));
724 connect(action, SIGNAL(triggered()), this, SLOT(toggleStatusBar()));
725 action->setCheckable(true);
726 action->setChecked(true);
727 menu->addAction(action);
728
729 QSettings settings;
730 settings.beginGroup("MainWindow");
731 bool sb = settings.value("showstatusbar", true).toBool();
732 if (!sb) {
733 action->setChecked(false);
734 statusBar()->hide();
735 }
736 settings.endGroup();
737
687 /*!!! This one doesn't work properly yet 738 /*!!! This one doesn't work properly yet
739
740 menu->addSeparator();
741
742 action = new QAction(tr("Show La&yer Hierarchy"), this);
743 action->setShortcut(tr("Alt+L"));
744 action->setStatusTip(tr("Open a window displaying the hierarchy of panes and layers in this session"));
745 connect(action, SIGNAL(triggered()), this, SLOT(showLayerTree()));
746 menu->addAction(action);
688 */ 747 */
689 menu->addSeparator();
690
691 action = new QAction(tr("Show &Layer Hierarchy"), this);
692 action->setShortcut(tr("Alt+L"));
693 connect(action, SIGNAL(triggered()), this, SLOT(showLayerTree()));
694 menu->addAction(action);
695 /* */
696 } 748 }
697 749
698 void 750 void
699 MainWindow::setupPaneAndLayerMenus() 751 MainWindow::setupPaneAndLayerMenus()
700 { 752 {
809 case LayerFactory::Spectrogram: 861 case LayerFactory::Spectrogram:
810 icon = QIcon(":/icons/spectrogram.png"); 862 icon = QIcon(":/icons/spectrogram.png");
811 mainText = tr("Add &Spectrogram"); 863 mainText = tr("Add &Spectrogram");
812 if (menuType == 0) { 864 if (menuType == 0) {
813 shortcutText = tr("Alt+S"); 865 shortcutText = tr("Alt+S");
814 tipText = tr("Add a new pane showing a dB spectrogram"); 866 tipText = tr("Add a new pane showing a spectrogram");
815 } else { 867 } else {
816 tipText = tr("Add a new layer showing a dB spectrogram"); 868 tipText = tr("Add a new layer showing a spectrogram");
817 } 869 }
818 break; 870 break;
819 871
820 case LayerFactory::MelodicRangeSpectrogram: 872 case LayerFactory::MelodicRangeSpectrogram:
821 icon = QIcon(":/icons/spectrogram.png"); 873 icon = QIcon(":/icons/spectrogram.png");
822 mainText = tr("Add &Melodic Range Spectrogram"); 874 mainText = tr("Add &Melodic Range Spectrogram");
823 if (menuType == 0) { 875 if (menuType == 0) {
824 shortcutText = tr("Alt+M"); 876 shortcutText = tr("Alt+M");
825 tipText = tr("Add a new pane showing a spectrogram set up for a pitch overview"); 877 tipText = tr("Add a new pane showing a spectrogram set up for an overview of note pitches");
826 } else { 878 } else {
827 tipText = tr("Add a new layer showing a spectrogram set up for a pitch overview"); 879 tipText = tr("Add a new layer showing a spectrogram set up for an overview of note pitches");
828 } 880 }
829 break; 881 break;
830 882
831 case LayerFactory::PeakFrequencySpectrogram: 883 case LayerFactory::PeakFrequencySpectrogram:
832 icon = QIcon(":/icons/spectrogram.png"); 884 icon = QIcon(":/icons/spectrogram.png");
975 1027
976 menu->addSeparator(); 1028 menu->addSeparator();
977 1029
978 action = new QAction(QIcon(":/icons/editdelete.png"), tr("&Delete Pane"), this); 1030 action = new QAction(QIcon(":/icons/editdelete.png"), tr("&Delete Pane"), this);
979 action->setShortcut(tr("Alt+D")); 1031 action->setShortcut(tr("Alt+D"));
980 action->setStatusTip(tr("Delete the currently selected pane")); 1032 action->setStatusTip(tr("Delete the currently active pane"));
981 connect(action, SIGNAL(triggered()), this, SLOT(deleteCurrentPane())); 1033 connect(action, SIGNAL(triggered()), this, SLOT(deleteCurrentPane()));
982 connect(this, SIGNAL(canDeleteCurrentPane(bool)), action, SLOT(setEnabled(bool))); 1034 connect(this, SIGNAL(canDeleteCurrentPane(bool)), action, SLOT(setEnabled(bool)));
983 menu->addAction(action); 1035 menu->addAction(action);
984 1036
985 menu = m_layerMenu; 1037 menu = m_layerMenu;
1152 connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); 1204 connect(action, SIGNAL(triggered()), this, SLOT(addLayer()));
1153 m_transformActions[action] = transforms[i].name; 1205 m_transformActions[action] = transforms[i].name;
1154 m_transformActionsReverse[transforms[i].name] = action; 1206 m_transformActionsReverse[transforms[i].name] = action;
1155 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); 1207 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool)));
1156 1208
1209 QString tip;
1210 if (output == "") {
1211 tip = tr("Transform with \"%1\" plugin (from %3)")
1212 .arg(pluginName).arg(maker);
1213 } else {
1214 tip = tr("Transform with \"%1\" output of \"%2\" plugin (from %3)")
1215 .arg(output).arg(pluginName).arg(maker);
1216 }
1217 action->setStatusTip(tip);
1218
1157 if (categoryMenus[type].find(category) == categoryMenus[type].end()) { 1219 if (categoryMenus[type].find(category) == categoryMenus[type].end()) {
1158 std::cerr << "WARNING: MainWindow::setupMenus: Internal error: " 1220 std::cerr << "WARNING: MainWindow::setupMenus: Internal error: "
1159 << "No category menu for transform \"" 1221 << "No category menu for transform \""
1160 << description.toStdString() << "\" (category = \"" 1222 << description.toStdString() << "\" (category = \""
1161 << category.toStdString() << "\")" << std::endl; 1223 << category.toStdString() << "\")" << std::endl;
1174 1236
1175 action = new QAction(tr("%1...").arg(output == "" ? pluginName : output), this); 1237 action = new QAction(tr("%1...").arg(output == "" ? pluginName : output), this);
1176 connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); 1238 connect(action, SIGNAL(triggered()), this, SLOT(addLayer()));
1177 m_transformActions[action] = transforms[i].name; 1239 m_transformActions[action] = transforms[i].name;
1178 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); 1240 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool)));
1241 action->setStatusTip(tip);
1179 1242
1180 // cerr << "Transform: \"" << name.toStdString() << "\": plugin name \"" << pluginName.toStdString() << "\"" << endl; 1243 // cerr << "Transform: \"" << name.toStdString() << "\": plugin name \"" << pluginName.toStdString() << "\"" << endl;
1181 1244
1182 if (pluginNameMenus[type].find(pluginName) == 1245 if (pluginNameMenus[type].find(pluginName) ==
1183 pluginNameMenus[type].end()) { 1246 pluginNameMenus[type].end()) {
1390 action = toolbar->addAction(QIcon(":/icons/navigate.png"), 1453 action = toolbar->addAction(QIcon(":/icons/navigate.png"),
1391 tr("Navigate")); 1454 tr("Navigate"));
1392 action->setCheckable(true); 1455 action->setCheckable(true);
1393 action->setChecked(true); 1456 action->setChecked(true);
1394 action->setShortcut(tr("1")); 1457 action->setShortcut(tr("1"));
1458 action->setStatusTip(tr("Navigate"));
1395 connect(action, SIGNAL(triggered()), this, SLOT(toolNavigateSelected())); 1459 connect(action, SIGNAL(triggered()), this, SLOT(toolNavigateSelected()));
1396 group->addAction(action); 1460 group->addAction(action);
1397 m_toolActions[ViewManager::NavigateMode] = action; 1461 m_toolActions[ViewManager::NavigateMode] = action;
1398 1462
1399 action = toolbar->addAction(QIcon(":/icons/select.png"), 1463 action = toolbar->addAction(QIcon(":/icons/select.png"),
1400 tr("Select")); 1464 tr("Select"));
1401 action->setCheckable(true); 1465 action->setCheckable(true);
1402 action->setShortcut(tr("2")); 1466 action->setShortcut(tr("2"));
1467 action->setStatusTip(tr("Select ranges"));
1403 connect(action, SIGNAL(triggered()), this, SLOT(toolSelectSelected())); 1468 connect(action, SIGNAL(triggered()), this, SLOT(toolSelectSelected()));
1404 group->addAction(action); 1469 group->addAction(action);
1405 m_toolActions[ViewManager::SelectMode] = action; 1470 m_toolActions[ViewManager::SelectMode] = action;
1406 1471
1407 action = toolbar->addAction(QIcon(":/icons/move.png"), 1472 action = toolbar->addAction(QIcon(":/icons/move.png"),
1408 tr("Edit")); 1473 tr("Edit"));
1409 action->setCheckable(true); 1474 action->setCheckable(true);
1410 action->setShortcut(tr("3")); 1475 action->setShortcut(tr("3"));
1476 action->setStatusTip(tr("Edit items in layer"));
1411 connect(action, SIGNAL(triggered()), this, SLOT(toolEditSelected())); 1477 connect(action, SIGNAL(triggered()), this, SLOT(toolEditSelected()));
1412 connect(this, SIGNAL(canEditLayer(bool)), action, SLOT(setEnabled(bool))); 1478 connect(this, SIGNAL(canEditLayer(bool)), action, SLOT(setEnabled(bool)));
1413 group->addAction(action); 1479 group->addAction(action);
1414 m_toolActions[ViewManager::EditMode] = action; 1480 m_toolActions[ViewManager::EditMode] = action;
1415 1481
1416 action = toolbar->addAction(QIcon(":/icons/draw.png"), 1482 action = toolbar->addAction(QIcon(":/icons/draw.png"),
1417 tr("Draw")); 1483 tr("Draw"));
1418 action->setCheckable(true); 1484 action->setCheckable(true);
1419 action->setShortcut(tr("4")); 1485 action->setShortcut(tr("4"));
1486 action->setStatusTip(tr("Draw new items in layer"));
1420 connect(action, SIGNAL(triggered()), this, SLOT(toolDrawSelected())); 1487 connect(action, SIGNAL(triggered()), this, SLOT(toolDrawSelected()));
1421 connect(this, SIGNAL(canEditLayer(bool)), action, SLOT(setEnabled(bool))); 1488 connect(this, SIGNAL(canEditLayer(bool)), action, SLOT(setEnabled(bool)));
1422 group->addAction(action); 1489 group->addAction(action);
1423 m_toolActions[ViewManager::DrawMode] = action; 1490 m_toolActions[ViewManager::DrawMode] = action;
1424 1491
2292 closeSession(); 2359 closeSession();
2293 createDocument(); 2360 createDocument();
2294 2361
2295 Pane *pane = m_paneStack->addPane(); 2362 Pane *pane = m_paneStack->addPane();
2296 2363
2364 connect(pane, SIGNAL(contextHelpChanged(const QString &)),
2365 statusBar(), SLOT(showMessage(const QString &)));
2366
2297 if (!m_timeRulerLayer) { 2367 if (!m_timeRulerLayer) {
2298 m_timeRulerLayer = m_document->createMainModelLayer 2368 m_timeRulerLayer = m_document->createMainModelLayer
2299 (LayerFactory::TimeRuler); 2369 (LayerFactory::TimeRuler);
2300 } 2370 }
2301 2371
2893 { 2963 {
2894 m_viewManager->setOverlayMode(ViewManager::NoOverlays); 2964 m_viewManager->setOverlayMode(ViewManager::NoOverlays);
2895 } 2965 }
2896 2966
2897 void 2967 void
2898 MainWindow::showBasicOverlays() 2968 MainWindow::showMinimalOverlays()
2899 { 2969 {
2900 m_viewManager->setOverlayMode(ViewManager::BasicOverlays); 2970 m_viewManager->setOverlayMode(ViewManager::MinimalOverlays);
2901 } 2971 }
2902 2972
2903 void 2973 void
2904 MainWindow::showAllTextOverlays() 2974 MainWindow::showStandardOverlays()
2975 {
2976 m_viewManager->setOverlayMode(ViewManager::StandardOverlays);
2977 }
2978
2979 void
2980 MainWindow::showAllOverlays()
2905 { 2981 {
2906 m_viewManager->setOverlayMode(ViewManager::AllOverlays); 2982 m_viewManager->setOverlayMode(ViewManager::AllOverlays);
2907 } 2983 }
2908 2984
2909 void 2985 void
2927 m_paneStack->setLayoutStyle(PaneStack::SinglePropertyStackLayout); 3003 m_paneStack->setLayoutStyle(PaneStack::SinglePropertyStackLayout);
2928 } 3004 }
2929 } else { 3005 } else {
2930 m_paneStack->setLayoutStyle(PaneStack::NoPropertyStacks); 3006 m_paneStack->setLayoutStyle(PaneStack::NoPropertyStacks);
2931 } 3007 }
3008 }
3009
3010 void
3011 MainWindow::toggleStatusBar()
3012 {
3013 QSettings settings;
3014 settings.beginGroup("MainWindow");
3015 bool sb = settings.value("showstatusbar", true).toBool();
3016
3017 if (sb) {
3018 statusBar()->hide();
3019 } else {
3020 statusBar()->show();
3021 }
3022
3023 settings.setValue("showstatusbar", !sb);
3024
3025 settings.endGroup();
2932 } 3026 }
2933 3027
2934 void 3028 void
2935 MainWindow::preferenceChanged(PropertyContainer::PropertyName name) 3029 MainWindow::preferenceChanged(PropertyContainer::PropertyName name)
2936 { 3030 {
3142 MainWindow::AddPaneCommand::execute() 3236 MainWindow::AddPaneCommand::execute()
3143 { 3237 {
3144 if (!m_pane) { 3238 if (!m_pane) {
3145 m_prevCurrentPane = m_mw->m_paneStack->getCurrentPane(); 3239 m_prevCurrentPane = m_mw->m_paneStack->getCurrentPane();
3146 m_pane = m_mw->m_paneStack->addPane(); 3240 m_pane = m_mw->m_paneStack->addPane();
3241
3242 connect(m_pane, SIGNAL(contextHelpChanged(const QString &)),
3243 m_mw->statusBar(), SLOT(showMessage(const QString &)));
3147 } else { 3244 } else {
3148 m_mw->m_paneStack->showPane(m_pane); 3245 m_mw->m_paneStack->showPane(m_pane);
3149 } 3246 }
3150 3247
3151 m_mw->m_paneStack->setCurrentPane(m_pane); 3248 m_mw->m_paneStack->setCurrentPane(m_pane);
3889 m_playSpeed->setMappedValue(value); 3986 m_playSpeed->setMappedValue(value);
3890 } else if (property == "overlays") { 3987 } else if (property == "overlays") {
3891 if (value < 0.5) { 3988 if (value < 0.5) {
3892 m_viewManager->setOverlayMode(ViewManager::NoOverlays); 3989 m_viewManager->setOverlayMode(ViewManager::NoOverlays);
3893 } else if (value < 1.5) { 3990 } else if (value < 1.5) {
3894 m_viewManager->setOverlayMode(ViewManager::BasicOverlays); 3991 m_viewManager->setOverlayMode(ViewManager::MinimalOverlays);
3992 } else if (value < 2.5) {
3993 m_viewManager->setOverlayMode(ViewManager::StandardOverlays);
3895 } else { 3994 } else {
3896 m_viewManager->setOverlayMode(ViewManager::AllOverlays); 3995 m_viewManager->setOverlayMode(ViewManager::AllOverlays);
3897 } 3996 }
3898 } else if (property == "zoomwheels") { 3997 } else if (property == "zoomwheels") {
3899 m_viewManager->setZoomWheelsEnabled(value > 0.5); 3998 m_viewManager->setZoomWheelsEnabled(value > 0.5);
4110 4209
4111 m_preferencesDialog->show(); 4210 m_preferencesDialog->show();
4112 } 4211 }
4113 4212
4114 void 4213 void
4214 MainWindow::mouseEnteredWidget()
4215 {
4216 QWidget *w = dynamic_cast<QWidget *>(sender());
4217 if (!w) return;
4218
4219 if (w == m_fader) {
4220 statusBar()->showMessage(tr("Adjust the master playback level"));
4221 } else if (w == m_playSpeed) {
4222 statusBar()->showMessage(tr("Adjust the master playback speed"));
4223 } else if (w == m_playSharpen && w->isEnabled()) {
4224 statusBar()->showMessage(tr("Toggle transient sharpening for playback time scaling"));
4225 } else if (w == m_playMono && w->isEnabled()) {
4226 statusBar()->showMessage(tr("Toggle mono mode for playback time scaling"));
4227 }
4228 }
4229
4230 void
4231 MainWindow::mouseLeftWidget()
4232 {
4233 statusBar()->showMessage("");
4234 }
4235
4236 void
4115 MainWindow::website() 4237 MainWindow::website()
4116 { 4238 {
4117 openHelpUrl(tr("http://www.sonicvisualiser.org/")); 4239 openHelpUrl(tr("http://www.sonicvisualiser.org/"));
4118 } 4240 }
4119 4241
4185 #endif 4307 #endif
4186 4308
4187 QString aboutText; 4309 QString aboutText;
4188 4310
4189 aboutText += tr("<h3>About Sonic Visualiser</h3>"); 4311 aboutText += tr("<h3>About Sonic Visualiser</h3>");
4190 aboutText += tr("<p>Sonic Visualiser is a program for viewing and exploring audio data for semantic music analysis and annotation.</p>"); 4312 aboutText += tr("<p>Sonic Visualiser is a program for viewing and exploring audio data for<br>semantic music analysis and annotation.</p>");
4191 aboutText += tr("<p>%1 : %2 build</p>") 4313 aboutText += tr("<p>%1 : %2 build</p>")
4192 .arg(version) 4314 .arg(version)
4193 .arg(debug ? tr("Debug") : tr("Release")); 4315 .arg(debug ? tr("Debug") : tr("Release"));
4194 4316
4195 #ifdef BUILD_STATIC 4317 #ifdef BUILD_STATIC
4231 #endif 4353 #endif
4232 aboutText += "</p>"; 4354 aboutText += "</p>";
4233 #endif 4355 #endif
4234 4356
4235 aboutText += 4357 aboutText +=
4236 "<p>Sonic Visualiser Copyright &copy; 2005 - 2006 Chris Cannam and<br>" 4358 "<p>Sonic Visualiser Copyright &copy; 2005 - 2007 Chris Cannam and<br>"
4237 "Centre for Digital Music, Queen Mary, University of London.</p>" 4359 "Queen Mary, University of London.</p>"
4238 "<p>This program is free software; you can redistribute it and/or<br>" 4360 "<p>This program is free software; you can redistribute it and/or<br>"
4239 "modify it under the terms of the GNU General Public License as<br>" 4361 "modify it under the terms of the GNU General Public License as<br>"
4240 "published by the Free Software Foundation; either version 2 of the<br>" 4362 "published by the Free Software Foundation; either version 2 of the<br>"
4241 "License, or (at your option) any later version.<br>See the file " 4363 "License, or (at your option) any later version.<br>See the file "
4242 "COPYING included with this distribution for more information.</p>"; 4364 "COPYING included with this distribution for more information.</p>";