Mercurial > hg > sonic-visualiser
comparison main/MainWindow.cpp @ 66:cf27fc7feb7a
* Add Pane menu entries for generating spectrogram etc from non-main models
* Some restructuring of MainWindow menu setup code
author | Chris Cannam |
---|---|
date | Fri, 20 Oct 2006 16:47:13 +0000 |
parents | 77c083741589 |
children | 0229bec2d2dc |
comparison
equal
deleted
inserted
replaced
65:77c083741589 | 66:cf27fc7feb7a |
---|---|
175 m_playSpeed->setValue(100); | 175 m_playSpeed->setValue(100); |
176 m_playSpeed->setFixedWidth(24); | 176 m_playSpeed->setFixedWidth(24); |
177 m_playSpeed->setFixedHeight(24); | 177 m_playSpeed->setFixedHeight(24); |
178 m_playSpeed->setNotchesVisible(true); | 178 m_playSpeed->setNotchesVisible(true); |
179 m_playSpeed->setPageStep(10); | 179 m_playSpeed->setPageStep(10); |
180 //!!! m_playSpeed->setToolTip(tr("Playback speed: +0%")); | |
181 m_playSpeed->setObjectName(tr("Playback Speedup")); | 180 m_playSpeed->setObjectName(tr("Playback Speedup")); |
182 m_playSpeed->setDefaultValue(100); | 181 m_playSpeed->setDefaultValue(100); |
183 m_playSpeed->setRangeMapper(new PlaySpeedRangeMapper(0, 200)); | 182 m_playSpeed->setRangeMapper(new PlaySpeedRangeMapper(0, 200)); |
184 m_playSpeed->setShowToolTip(true); | 183 m_playSpeed->setShowToolTip(true); |
185 connect(m_playSpeed, SIGNAL(valueChanged(int)), | 184 connect(m_playSpeed, SIGNAL(valueChanged(int)), |
248 } | 247 } |
249 | 248 |
250 void | 249 void |
251 MainWindow::setupMenus() | 250 MainWindow::setupMenus() |
252 { | 251 { |
253 QAction *action = 0; | |
254 QMenu *menu = 0; | |
255 QToolBar *toolbar = 0; | |
256 | |
257 if (!m_mainMenusCreated) { | 252 if (!m_mainMenusCreated) { |
258 m_rightButtonMenu = new QMenu(); | 253 m_rightButtonMenu = new QMenu(); |
259 } | 254 } |
260 | 255 |
261 if (m_rightButtonLayerMenu) { | 256 if (m_rightButtonLayerMenu) { |
271 m_rightButtonTransformsMenu = m_rightButtonMenu->addMenu(tr("&Transform")); | 266 m_rightButtonTransformsMenu = m_rightButtonMenu->addMenu(tr("&Transform")); |
272 m_rightButtonMenu->addSeparator(); | 267 m_rightButtonMenu->addSeparator(); |
273 } | 268 } |
274 | 269 |
275 if (!m_mainMenusCreated) { | 270 if (!m_mainMenusCreated) { |
276 | |
277 CommandHistory::getInstance()->registerMenu(m_rightButtonMenu); | 271 CommandHistory::getInstance()->registerMenu(m_rightButtonMenu); |
278 m_rightButtonMenu->addSeparator(); | 272 m_rightButtonMenu->addSeparator(); |
279 | 273 } |
280 menu = menuBar()->addMenu(tr("&File")); | 274 |
281 toolbar = addToolBar(tr("File Toolbar")); | 275 setupFileMenu(); |
282 | 276 setupEditMenu(); |
283 QIcon icon(":icons/filenew.png"); | 277 setupViewMenu(); |
284 icon.addFile(":icons/filenew-22.png"); | 278 setupPaneAndLayerMenus(); |
285 action = new QAction(icon, tr("&New Session"), this); | 279 setupTransformsMenu(); |
286 action->setShortcut(tr("Ctrl+N")); | 280 setupHelpMenu(); |
287 action->setStatusTip(tr("Clear the current Sonic Visualiser session and start a new one")); | 281 |
288 connect(action, SIGNAL(triggered()), this, SLOT(newSession())); | 282 m_mainMenusCreated = true; |
289 menu->addAction(action); | 283 } |
290 toolbar->addAction(action); | 284 |
285 void | |
286 MainWindow::setupFileMenu() | |
287 { | |
288 if (m_mainMenusCreated) return; | |
289 | |
290 QMenu *menu = menuBar()->addMenu(tr("&File")); | |
291 QToolBar *toolbar = addToolBar(tr("File Toolbar")); | |
292 | |
293 QIcon icon(":icons/filenew.png"); | |
294 icon.addFile(":icons/filenew-22.png"); | |
295 QAction *action = new QAction(icon, tr("&New Session"), this); | |
296 action->setShortcut(tr("Ctrl+N")); | |
297 action->setStatusTip(tr("Clear the current Sonic Visualiser session and start a new one")); | |
298 connect(action, SIGNAL(triggered()), this, SLOT(newSession())); | |
299 menu->addAction(action); | |
300 toolbar->addAction(action); | |
291 | 301 |
292 icon = QIcon(":icons/fileopen.png"); | 302 icon = QIcon(":icons/fileopen.png"); |
293 icon.addFile(":icons/fileopen-22.png"); | 303 icon.addFile(":icons/fileopen-22.png"); |
294 | 304 |
295 action = new QAction(icon, tr("&Open Session..."), this); | 305 action = new QAction(icon, tr("&Open Session..."), this); |
296 action->setShortcut(tr("Ctrl+O")); | 306 action->setShortcut(tr("Ctrl+O")); |
297 action->setStatusTip(tr("Open a previously saved Sonic Visualiser session file")); | 307 action->setStatusTip(tr("Open a previously saved Sonic Visualiser session file")); |
298 connect(action, SIGNAL(triggered()), this, SLOT(openSession())); | 308 connect(action, SIGNAL(triggered()), this, SLOT(openSession())); |
299 menu->addAction(action); | 309 menu->addAction(action); |
300 | 310 |
301 action = new QAction(icon, tr("&Open..."), this); | 311 action = new QAction(icon, tr("&Open..."), this); |
302 action->setStatusTip(tr("Open a session file, audio file, or layer")); | 312 action->setStatusTip(tr("Open a session file, audio file, or layer")); |
303 connect(action, SIGNAL(triggered()), this, SLOT(openSomething())); | 313 connect(action, SIGNAL(triggered()), this, SLOT(openSomething())); |
304 toolbar->addAction(action); | 314 toolbar->addAction(action); |
305 | 315 |
306 icon = QIcon(":icons/filesave.png"); | 316 icon = QIcon(":icons/filesave.png"); |
307 icon.addFile(":icons/filesave-22.png"); | 317 icon.addFile(":icons/filesave-22.png"); |
308 action = new QAction(icon, tr("&Save Session"), this); | 318 action = new QAction(icon, tr("&Save Session"), this); |
309 action->setShortcut(tr("Ctrl+S")); | 319 action->setShortcut(tr("Ctrl+S")); |
310 action->setStatusTip(tr("Save the current session into a Sonic Visualiser session file")); | 320 action->setStatusTip(tr("Save the current session into a Sonic Visualiser session file")); |
311 connect(action, SIGNAL(triggered()), this, SLOT(saveSession())); | 321 connect(action, SIGNAL(triggered()), this, SLOT(saveSession())); |
312 connect(this, SIGNAL(canSave(bool)), action, SLOT(setEnabled(bool))); | 322 connect(this, SIGNAL(canSave(bool)), action, SLOT(setEnabled(bool))); |
313 menu->addAction(action); | 323 menu->addAction(action); |
314 toolbar->addAction(action); | 324 toolbar->addAction(action); |
315 | 325 |
316 icon = QIcon(":icons/filesaveas.png"); | 326 icon = QIcon(":icons/filesaveas.png"); |
317 icon.addFile(":icons/filesaveas-22.png"); | 327 icon.addFile(":icons/filesaveas-22.png"); |
318 action = new QAction(icon, tr("Save Session &As..."), this); | 328 action = new QAction(icon, tr("Save Session &As..."), this); |
319 action->setStatusTip(tr("Save the current session into a new Sonic Visualiser session file")); | 329 action->setStatusTip(tr("Save the current session into a new Sonic Visualiser session file")); |
320 connect(action, SIGNAL(triggered()), this, SLOT(saveSessionAs())); | 330 connect(action, SIGNAL(triggered()), this, SLOT(saveSessionAs())); |
321 menu->addAction(action); | 331 menu->addAction(action); |
322 toolbar->addAction(action); | 332 toolbar->addAction(action); |
323 | 333 |
324 menu->addSeparator(); | 334 menu->addSeparator(); |
325 | 335 |
326 action = new QAction(tr("&Import Audio File..."), this); | 336 action = new QAction(tr("&Import Audio File..."), this); |
327 action->setShortcut(tr("Ctrl+I")); | 337 action->setShortcut(tr("Ctrl+I")); |
328 action->setStatusTip(tr("Import an existing audio file")); | 338 action->setStatusTip(tr("Import an existing audio file")); |
329 connect(action, SIGNAL(triggered()), this, SLOT(importAudio())); | 339 connect(action, SIGNAL(triggered()), this, SLOT(importAudio())); |
330 menu->addAction(action); | 340 menu->addAction(action); |
331 | 341 |
332 action = new QAction(tr("Import Secondary Audio File..."), this); | 342 action = new QAction(tr("Import Secondary Audio File..."), this); |
333 action->setShortcut(tr("Ctrl+Shift+I")); | 343 action->setShortcut(tr("Ctrl+Shift+I")); |
334 action->setStatusTip(tr("Import an extra audio file as a separate layer")); | 344 action->setStatusTip(tr("Import an extra audio file as a separate layer")); |
335 connect(action, SIGNAL(triggered()), this, SLOT(importMoreAudio())); | 345 connect(action, SIGNAL(triggered()), this, SLOT(importMoreAudio())); |
336 connect(this, SIGNAL(canImportMoreAudio(bool)), action, SLOT(setEnabled(bool))); | 346 connect(this, SIGNAL(canImportMoreAudio(bool)), action, SLOT(setEnabled(bool))); |
337 menu->addAction(action); | 347 menu->addAction(action); |
338 | 348 |
339 action = new QAction(tr("&Export Audio File..."), this); | 349 action = new QAction(tr("&Export Audio File..."), this); |
340 action->setStatusTip(tr("Export selection as an audio file")); | 350 action->setStatusTip(tr("Export selection as an audio file")); |
341 connect(action, SIGNAL(triggered()), this, SLOT(exportAudio())); | 351 connect(action, SIGNAL(triggered()), this, SLOT(exportAudio())); |
342 connect(this, SIGNAL(canExportAudio(bool)), action, SLOT(setEnabled(bool))); | 352 connect(this, SIGNAL(canExportAudio(bool)), action, SLOT(setEnabled(bool))); |
343 menu->addAction(action); | 353 menu->addAction(action); |
344 | 354 |
345 menu->addSeparator(); | 355 menu->addSeparator(); |
346 | 356 |
347 action = new QAction(tr("Import Annotation &Layer..."), this); | 357 action = new QAction(tr("Import Annotation &Layer..."), this); |
348 action->setShortcut(tr("Ctrl+L")); | 358 action->setShortcut(tr("Ctrl+L")); |
349 action->setStatusTip(tr("Import layer data from an existing file")); | 359 action->setStatusTip(tr("Import layer data from an existing file")); |
350 connect(action, SIGNAL(triggered()), this, SLOT(importLayer())); | 360 connect(action, SIGNAL(triggered()), this, SLOT(importLayer())); |
351 connect(this, SIGNAL(canImportLayer(bool)), action, SLOT(setEnabled(bool))); | 361 connect(this, SIGNAL(canImportLayer(bool)), action, SLOT(setEnabled(bool))); |
352 menu->addAction(action); | 362 menu->addAction(action); |
353 | 363 |
354 action = new QAction(tr("Export Annotation Layer..."), this); | 364 action = new QAction(tr("Export Annotation Layer..."), this); |
355 action->setStatusTip(tr("Export layer data to a file")); | 365 action->setStatusTip(tr("Export layer data to a file")); |
356 connect(action, SIGNAL(triggered()), this, SLOT(exportLayer())); | 366 connect(action, SIGNAL(triggered()), this, SLOT(exportLayer())); |
357 connect(this, SIGNAL(canExportLayer(bool)), action, SLOT(setEnabled(bool))); | 367 connect(this, SIGNAL(canExportLayer(bool)), action, SLOT(setEnabled(bool))); |
358 menu->addAction(action); | 368 menu->addAction(action); |
359 | 369 |
360 menu->addSeparator(); | 370 menu->addSeparator(); |
361 m_recentFilesMenu = menu->addMenu(tr("&Recent Files")); | 371 m_recentFilesMenu = menu->addMenu(tr("&Recent Files")); |
362 setupRecentFilesMenu(); | 372 setupRecentFilesMenu(); |
363 connect(&m_recentFiles, SIGNAL(recentChanged()), | 373 connect(&m_recentFiles, SIGNAL(recentChanged()), |
364 this, SLOT(setupRecentFilesMenu())); | 374 this, SLOT(setupRecentFilesMenu())); |
365 | 375 |
366 menu->addSeparator(); | 376 menu->addSeparator(); |
367 action = new QAction(tr("&Preferences..."), this); | 377 action = new QAction(tr("&Preferences..."), this); |
368 action->setStatusTip(tr("Adjust the application preferences")); | 378 action->setStatusTip(tr("Adjust the application preferences")); |
369 connect(action, SIGNAL(triggered()), this, SLOT(preferences())); | 379 connect(action, SIGNAL(triggered()), this, SLOT(preferences())); |
370 menu->addAction(action); | 380 menu->addAction(action); |
371 | 381 |
372 /*!!! | 382 /*!!! |
373 menu->addSeparator(); | 383 menu->addSeparator(); |
374 | 384 |
375 action = new QAction(tr("Play / Pause"), this); | 385 action = new QAction(tr("Play / Pause"), this); |
376 action->setShortcut(tr("Space")); | 386 action->setShortcut(tr("Space")); |
377 action->setStatusTip(tr("Start or stop playback from the current position")); | 387 action->setStatusTip(tr("Start or stop playback from the current position")); |
378 connect(action, SIGNAL(triggered()), this, SLOT(play())); | 388 connect(action, SIGNAL(triggered()), this, SLOT(play())); |
379 menu->addAction(action); | 389 menu->addAction(action); |
380 */ | 390 */ |
381 | 391 |
382 menu->addSeparator(); | 392 menu->addSeparator(); |
383 action = new QAction(QIcon(":/icons/exit.png"), | 393 action = new QAction(QIcon(":/icons/exit.png"), |
384 tr("&Quit"), this); | 394 tr("&Quit"), this); |
385 action->setShortcut(tr("Ctrl+Q")); | 395 action->setShortcut(tr("Ctrl+Q")); |
386 connect(action, SIGNAL(triggered()), this, SLOT(close())); | 396 connect(action, SIGNAL(triggered()), this, SLOT(close())); |
387 menu->addAction(action); | 397 menu->addAction(action); |
388 | 398 } |
389 menu = menuBar()->addMenu(tr("&Edit")); | 399 |
390 CommandHistory::getInstance()->registerMenu(menu); | 400 void |
391 | 401 MainWindow::setupEditMenu() |
392 menu->addSeparator(); | 402 { |
393 | 403 if (m_mainMenusCreated) return; |
394 action = new QAction(QIcon(":/icons/editcut.png"), | 404 |
395 tr("Cu&t"), this); | 405 QMenu *menu = menuBar()->addMenu(tr("&Edit")); |
396 action->setShortcut(tr("Ctrl+X")); | 406 CommandHistory::getInstance()->registerMenu(menu); |
397 connect(action, SIGNAL(triggered()), this, SLOT(cut())); | 407 |
398 connect(this, SIGNAL(canEditSelection(bool)), action, SLOT(setEnabled(bool))); | 408 menu->addSeparator(); |
399 menu->addAction(action); | 409 |
400 m_rightButtonMenu->addAction(action); | 410 QAction *action = new QAction(QIcon(":/icons/editcut.png"), |
401 | 411 tr("Cu&t"), this); |
402 action = new QAction(QIcon(":/icons/editcopy.png"), | 412 action->setShortcut(tr("Ctrl+X")); |
403 tr("&Copy"), this); | 413 connect(action, SIGNAL(triggered()), this, SLOT(cut())); |
404 action->setShortcut(tr("Ctrl+C")); | 414 connect(this, SIGNAL(canEditSelection(bool)), action, SLOT(setEnabled(bool))); |
405 connect(action, SIGNAL(triggered()), this, SLOT(copy())); | 415 menu->addAction(action); |
406 connect(this, SIGNAL(canEditSelection(bool)), action, SLOT(setEnabled(bool))); | 416 m_rightButtonMenu->addAction(action); |
407 menu->addAction(action); | 417 |
408 m_rightButtonMenu->addAction(action); | 418 action = new QAction(QIcon(":/icons/editcopy.png"), |
409 | 419 tr("&Copy"), this); |
410 action = new QAction(QIcon(":/icons/editpaste.png"), | 420 action->setShortcut(tr("Ctrl+C")); |
411 tr("&Paste"), this); | 421 connect(action, SIGNAL(triggered()), this, SLOT(copy())); |
412 action->setShortcut(tr("Ctrl+V")); | 422 connect(this, SIGNAL(canEditSelection(bool)), action, SLOT(setEnabled(bool))); |
413 connect(action, SIGNAL(triggered()), this, SLOT(paste())); | 423 menu->addAction(action); |
414 connect(this, SIGNAL(canPaste(bool)), action, SLOT(setEnabled(bool))); | 424 m_rightButtonMenu->addAction(action); |
415 menu->addAction(action); | 425 |
416 m_rightButtonMenu->addAction(action); | 426 action = new QAction(QIcon(":/icons/editpaste.png"), |
417 | 427 tr("&Paste"), this); |
418 action = new QAction(tr("&Delete Selected Items"), this); | 428 action->setShortcut(tr("Ctrl+V")); |
419 action->setShortcut(tr("Del")); | 429 connect(action, SIGNAL(triggered()), this, SLOT(paste())); |
420 connect(action, SIGNAL(triggered()), this, SLOT(deleteSelected())); | 430 connect(this, SIGNAL(canPaste(bool)), action, SLOT(setEnabled(bool))); |
421 connect(this, SIGNAL(canEditSelection(bool)), action, SLOT(setEnabled(bool))); | 431 menu->addAction(action); |
422 menu->addAction(action); | 432 m_rightButtonMenu->addAction(action); |
423 m_rightButtonMenu->addAction(action); | 433 |
424 | 434 action = new QAction(tr("&Delete Selected Items"), this); |
425 menu->addSeparator(); | 435 action->setShortcut(tr("Del")); |
426 m_rightButtonMenu->addSeparator(); | 436 connect(action, SIGNAL(triggered()), this, SLOT(deleteSelected())); |
437 connect(this, SIGNAL(canEditSelection(bool)), action, SLOT(setEnabled(bool))); | |
438 menu->addAction(action); | |
439 m_rightButtonMenu->addAction(action); | |
440 | |
441 menu->addSeparator(); | |
442 m_rightButtonMenu->addSeparator(); | |
427 | 443 |
428 action = new QAction(tr("Select &All"), this); | 444 action = new QAction(tr("Select &All"), this); |
429 action->setShortcut(tr("Ctrl+A")); | 445 action->setShortcut(tr("Ctrl+A")); |
430 connect(action, SIGNAL(triggered()), this, SLOT(selectAll())); | 446 connect(action, SIGNAL(triggered()), this, SLOT(selectAll())); |
431 connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool))); | 447 connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool))); |
432 menu->addAction(action); | 448 menu->addAction(action); |
433 m_rightButtonMenu->addAction(action); | 449 m_rightButtonMenu->addAction(action); |
434 | 450 |
435 action = new QAction(tr("Select &Visible Range"), this); | 451 action = new QAction(tr("Select &Visible Range"), this); |
436 action->setShortcut(tr("Ctrl+Shift+A")); | 452 action->setShortcut(tr("Ctrl+Shift+A")); |
437 connect(action, SIGNAL(triggered()), this, SLOT(selectVisible())); | 453 connect(action, SIGNAL(triggered()), this, SLOT(selectVisible())); |
438 connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool))); | 454 connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool))); |
439 menu->addAction(action); | 455 menu->addAction(action); |
440 | 456 |
441 action = new QAction(tr("Select to &Start"), this); | 457 action = new QAction(tr("Select to &Start"), this); |
442 action->setShortcut(tr("Shift+Left")); | 458 action->setShortcut(tr("Shift+Left")); |
443 connect(action, SIGNAL(triggered()), this, SLOT(selectToStart())); | 459 connect(action, SIGNAL(triggered()), this, SLOT(selectToStart())); |
444 connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool))); | 460 connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool))); |
445 menu->addAction(action); | 461 menu->addAction(action); |
446 | 462 |
447 action = new QAction(tr("Select to &End"), this); | 463 action = new QAction(tr("Select to &End"), this); |
448 action->setShortcut(tr("Shift+Right")); | 464 action->setShortcut(tr("Shift+Right")); |
449 connect(action, SIGNAL(triggered()), this, SLOT(selectToEnd())); | 465 connect(action, SIGNAL(triggered()), this, SLOT(selectToEnd())); |
450 connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool))); | 466 connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool))); |
451 menu->addAction(action); | 467 menu->addAction(action); |
452 | 468 |
453 action = new QAction(tr("C&lear Selection"), this); | 469 action = new QAction(tr("C&lear Selection"), this); |
454 action->setShortcut(tr("Esc")); | 470 action->setShortcut(tr("Esc")); |
455 connect(action, SIGNAL(triggered()), this, SLOT(clearSelection())); | 471 connect(action, SIGNAL(triggered()), this, SLOT(clearSelection())); |
456 connect(this, SIGNAL(canClearSelection(bool)), action, SLOT(setEnabled(bool))); | 472 connect(this, SIGNAL(canClearSelection(bool)), action, SLOT(setEnabled(bool))); |
457 menu->addAction(action); | 473 menu->addAction(action); |
458 m_rightButtonMenu->addAction(action); | 474 m_rightButtonMenu->addAction(action); |
459 | 475 |
460 menu->addSeparator(); | 476 menu->addSeparator(); |
461 | 477 |
462 action = new QAction(tr("&Insert Instant at Playback Position"), this); | 478 action = new QAction(tr("&Insert Instant at Playback Position"), this); |
463 action->setShortcut(tr("Enter")); | 479 action->setShortcut(tr("Enter")); |
464 connect(action, SIGNAL(triggered()), this, SLOT(insertInstant())); | 480 connect(action, SIGNAL(triggered()), this, SLOT(insertInstant())); |
465 connect(this, SIGNAL(canInsertInstant(bool)), action, SLOT(setEnabled(bool))); | 481 connect(this, SIGNAL(canInsertInstant(bool)), action, SLOT(setEnabled(bool))); |
466 menu->addAction(action); | 482 menu->addAction(action); |
467 | 483 |
468 // Laptop shortcut (no keypad Enter key) | 484 // Laptop shortcut (no keypad Enter key) |
469 connect(new QShortcut(tr(";"), this), SIGNAL(activated()), | 485 connect(new QShortcut(tr(";"), this), SIGNAL(activated()), |
470 this, SLOT(insertInstant())); | 486 this, SLOT(insertInstant())); |
471 | 487 } |
472 menu = menuBar()->addMenu(tr("&View")); | 488 |
473 | 489 void |
474 QActionGroup *overlayGroup = new QActionGroup(this); | 490 MainWindow::setupViewMenu() |
491 { | |
492 if (m_mainMenusCreated) return; | |
493 | |
494 QMenu *menu = menuBar()->addMenu(tr("&View")); | |
495 | |
496 QActionGroup *overlayGroup = new QActionGroup(this); | |
475 | 497 |
476 action = new QAction(tr("&No Text Overlays"), this); | 498 QAction *action = new QAction(tr("&No Text Overlays"), this); |
477 action->setShortcut(tr("0")); | 499 action->setShortcut(tr("0")); |
478 action->setStatusTip(tr("Show no texts for frame times, layer names etc")); | 500 action->setStatusTip(tr("Show no texts for frame times, layer names etc")); |
479 connect(action, SIGNAL(triggered()), this, SLOT(showNoOverlays())); | 501 connect(action, SIGNAL(triggered()), this, SLOT(showNoOverlays())); |
480 action->setCheckable(true); | 502 action->setCheckable(true); |
481 action->setChecked(false); | 503 action->setChecked(false); |
482 overlayGroup->addAction(action); | 504 overlayGroup->addAction(action); |
483 menu->addAction(action); | 505 menu->addAction(action); |
484 | 506 |
485 action = new QAction(tr("Basic &Text Overlays"), this); | 507 action = new QAction(tr("Basic &Text Overlays"), this); |
486 action->setShortcut(tr("9")); | 508 action->setShortcut(tr("9")); |
487 action->setStatusTip(tr("Show texts for frame times etc, but not layer names etc")); | 509 action->setStatusTip(tr("Show texts for frame times etc, but not layer names etc")); |
488 connect(action, SIGNAL(triggered()), this, SLOT(showBasicOverlays())); | 510 connect(action, SIGNAL(triggered()), this, SLOT(showBasicOverlays())); |
489 action->setCheckable(true); | 511 action->setCheckable(true); |
490 action->setChecked(true); | 512 action->setChecked(true); |
491 overlayGroup->addAction(action); | 513 overlayGroup->addAction(action); |
492 menu->addAction(action); | 514 menu->addAction(action); |
493 | 515 |
494 action = new QAction(tr("&All Text Overlays"), this); | 516 action = new QAction(tr("&All Text Overlays"), this); |
495 action->setShortcut(tr("8")); | 517 action->setShortcut(tr("8")); |
496 action->setStatusTip(tr("Show texts for frame times, layer names etc")); | 518 action->setStatusTip(tr("Show texts for frame times, layer names etc")); |
497 connect(action, SIGNAL(triggered()), this, SLOT(showAllTextOverlays())); | 519 connect(action, SIGNAL(triggered()), this, SLOT(showAllTextOverlays())); |
498 action->setCheckable(true); | 520 action->setCheckable(true); |
499 action->setChecked(false); | 521 action->setChecked(false); |
500 overlayGroup->addAction(action); | 522 overlayGroup->addAction(action); |
501 menu->addAction(action); | 523 menu->addAction(action); |
502 | 524 |
503 menu->addSeparator(); | 525 menu->addSeparator(); |
504 | 526 |
505 action = new QAction(tr("Scroll &Left"), this); | 527 action = new QAction(tr("Scroll &Left"), this); |
506 action->setShortcut(tr("Left")); | 528 action->setShortcut(tr("Left")); |
507 action->setStatusTip(tr("Scroll the current pane to the left")); | 529 action->setStatusTip(tr("Scroll the current pane to the left")); |
508 connect(action, SIGNAL(triggered()), this, SLOT(scrollLeft())); | 530 connect(action, SIGNAL(triggered()), this, SLOT(scrollLeft())); |
509 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool))); | 531 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool))); |
510 menu->addAction(action); | 532 menu->addAction(action); |
511 | 533 |
512 action = new QAction(tr("Scroll &Right"), this); | 534 action = new QAction(tr("Scroll &Right"), this); |
513 action->setShortcut(tr("Right")); | 535 action->setShortcut(tr("Right")); |
514 action->setStatusTip(tr("Scroll the current pane to the right")); | 536 action->setStatusTip(tr("Scroll the current pane to the right")); |
515 connect(action, SIGNAL(triggered()), this, SLOT(scrollRight())); | 537 connect(action, SIGNAL(triggered()), this, SLOT(scrollRight())); |
516 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool))); | 538 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool))); |
517 menu->addAction(action); | 539 menu->addAction(action); |
518 | 540 |
519 action = new QAction(tr("Jump Left"), this); | 541 action = new QAction(tr("Jump Left"), this); |
520 action->setShortcut(tr("Ctrl+Left")); | 542 action->setShortcut(tr("Ctrl+Left")); |
521 action->setStatusTip(tr("Scroll the current pane a big step to the left")); | 543 action->setStatusTip(tr("Scroll the current pane a big step to the left")); |
522 connect(action, SIGNAL(triggered()), this, SLOT(jumpLeft())); | 544 connect(action, SIGNAL(triggered()), this, SLOT(jumpLeft())); |
523 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool))); | 545 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool))); |
524 menu->addAction(action); | 546 menu->addAction(action); |
525 | 547 |
526 action = new QAction(tr("Jump Right"), this); | 548 action = new QAction(tr("Jump Right"), this); |
527 action->setShortcut(tr("Ctrl+Right")); | 549 action->setShortcut(tr("Ctrl+Right")); |
528 action->setStatusTip(tr("Scroll the current pane a big step to the right")); | 550 action->setStatusTip(tr("Scroll the current pane a big step to the right")); |
529 connect(action, SIGNAL(triggered()), this, SLOT(jumpRight())); | 551 connect(action, SIGNAL(triggered()), this, SLOT(jumpRight())); |
530 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool))); | 552 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool))); |
531 menu->addAction(action); | 553 menu->addAction(action); |
532 | 554 |
533 menu->addSeparator(); | 555 menu->addSeparator(); |
534 | 556 |
535 action = new QAction(QIcon(":/icons/zoom-in.png"), | 557 action = new QAction(QIcon(":/icons/zoom-in.png"), |
536 tr("Zoom &In"), this); | 558 tr("Zoom &In"), this); |
537 action->setShortcut(tr("Up")); | 559 action->setShortcut(tr("Up")); |
538 action->setStatusTip(tr("Increase the zoom level")); | 560 action->setStatusTip(tr("Increase the zoom level")); |
539 connect(action, SIGNAL(triggered()), this, SLOT(zoomIn())); | 561 connect(action, SIGNAL(triggered()), this, SLOT(zoomIn())); |
540 connect(this, SIGNAL(canZoom(bool)), action, SLOT(setEnabled(bool))); | 562 connect(this, SIGNAL(canZoom(bool)), action, SLOT(setEnabled(bool))); |
541 menu->addAction(action); | 563 menu->addAction(action); |
542 | 564 |
543 action = new QAction(QIcon(":/icons/zoom-out.png"), | 565 action = new QAction(QIcon(":/icons/zoom-out.png"), |
544 tr("Zoom &Out"), this); | 566 tr("Zoom &Out"), this); |
545 action->setShortcut(tr("Down")); | 567 action->setShortcut(tr("Down")); |
546 action->setStatusTip(tr("Decrease the zoom level")); | 568 action->setStatusTip(tr("Decrease the zoom level")); |
547 connect(action, SIGNAL(triggered()), this, SLOT(zoomOut())); | 569 connect(action, SIGNAL(triggered()), this, SLOT(zoomOut())); |
548 connect(this, SIGNAL(canZoom(bool)), action, SLOT(setEnabled(bool))); | 570 connect(this, SIGNAL(canZoom(bool)), action, SLOT(setEnabled(bool))); |
549 menu->addAction(action); | 571 menu->addAction(action); |
550 | 572 |
551 action = new QAction(tr("Restore &Default Zoom"), this); | 573 action = new QAction(tr("Restore &Default Zoom"), this); |
552 connect(action, SIGNAL(triggered()), this, SLOT(zoomDefault())); | 574 connect(action, SIGNAL(triggered()), this, SLOT(zoomDefault())); |
553 connect(this, SIGNAL(canZoom(bool)), action, SLOT(setEnabled(bool))); | 575 connect(this, SIGNAL(canZoom(bool)), action, SLOT(setEnabled(bool))); |
554 menu->addAction(action); | 576 menu->addAction(action); |
555 | 577 |
556 action = new QAction(tr("Zoom to &Fit"), this); | 578 action = new QAction(tr("Zoom to &Fit"), this); |
557 action->setStatusTip(tr("Zoom to show the whole file")); | 579 action->setStatusTip(tr("Zoom to show the whole file")); |
558 connect(action, SIGNAL(triggered()), this, SLOT(zoomToFit())); | 580 connect(action, SIGNAL(triggered()), this, SLOT(zoomToFit())); |
559 connect(this, SIGNAL(canZoom(bool)), action, SLOT(setEnabled(bool))); | 581 connect(this, SIGNAL(canZoom(bool)), action, SLOT(setEnabled(bool))); |
560 menu->addAction(action); | 582 menu->addAction(action); |
561 | 583 |
562 action = new QAction(tr("Show &Zoom Wheels"), this); | 584 action = new QAction(tr("Show &Zoom Wheels"), this); |
563 action->setShortcut(tr("Z")); | 585 action->setShortcut(tr("Z")); |
564 action->setStatusTip(tr("Show thumbwheels for zooming horizontally and vertically")); | 586 action->setStatusTip(tr("Show thumbwheels for zooming horizontally and vertically")); |
565 connect(action, SIGNAL(triggered()), this, SLOT(toggleZoomWheels())); | 587 connect(action, SIGNAL(triggered()), this, SLOT(toggleZoomWheels())); |
566 action->setCheckable(true); | 588 action->setCheckable(true); |
567 action->setChecked(m_viewManager->getZoomWheelsEnabled()); | 589 action->setChecked(m_viewManager->getZoomWheelsEnabled()); |
568 menu->addAction(action); | 590 menu->addAction(action); |
569 | 591 |
570 /*!!! This one doesn't work properly yet | 592 /*!!! This one doesn't work properly yet |
571 */ | 593 */ |
572 menu->addSeparator(); | 594 menu->addSeparator(); |
573 | 595 |
574 action = new QAction(tr("Show &Layer Hierarchy"), this); | 596 action = new QAction(tr("Show &Layer Hierarchy"), this); |
575 action->setShortcut(tr("Alt+L")); | 597 action->setShortcut(tr("Alt+L")); |
576 connect(action, SIGNAL(triggered()), this, SLOT(showLayerTree())); | 598 connect(action, SIGNAL(triggered()), this, SLOT(showLayerTree())); |
577 menu->addAction(action); | 599 menu->addAction(action); |
578 /* */ | 600 /* */ |
579 } | 601 } |
580 | 602 |
603 void | |
604 MainWindow::setupPaneAndLayerMenus() | |
605 { | |
581 if (m_paneMenu) { | 606 if (m_paneMenu) { |
582 m_paneActions.clear(); | 607 m_paneActions.clear(); |
583 m_paneMenu->clear(); | 608 m_paneMenu->clear(); |
584 } else { | 609 } else { |
585 m_paneMenu = menuBar()->addMenu(tr("&Pane")); | 610 m_paneMenu = menuBar()->addMenu(tr("&Pane")); |
590 m_layerMenu->clear(); | 615 m_layerMenu->clear(); |
591 } else { | 616 } else { |
592 m_layerMenu = menuBar()->addMenu(tr("&Layer")); | 617 m_layerMenu = menuBar()->addMenu(tr("&Layer")); |
593 } | 618 } |
594 | 619 |
620 QMenu *menu = m_paneMenu; | |
621 | |
622 QAction *action = new QAction(QIcon(":/icons/pane.png"), tr("Add &New Pane"), this); | |
623 action->setShortcut(tr("Alt+N")); | |
624 action->setStatusTip(tr("Add a new pane containing only a time ruler")); | |
625 connect(action, SIGNAL(triggered()), this, SLOT(addPane())); | |
626 connect(this, SIGNAL(canAddPane(bool)), action, SLOT(setEnabled(bool))); | |
627 m_paneActions[action] = PaneConfiguration(LayerFactory::TimeRuler); | |
628 menu->addAction(action); | |
629 | |
630 menu->addSeparator(); | |
631 | |
632 menu = m_layerMenu; | |
633 | |
634 // menu->addSeparator(); | |
635 | |
636 LayerFactory::LayerTypeSet emptyLayerTypes = | |
637 LayerFactory::getInstance()->getValidEmptyLayerTypes(); | |
638 | |
639 for (LayerFactory::LayerTypeSet::iterator i = emptyLayerTypes.begin(); | |
640 i != emptyLayerTypes.end(); ++i) { | |
641 | |
642 QIcon icon; | |
643 QString mainText, tipText, channelText; | |
644 LayerFactory::LayerType type = *i; | |
645 QString name = LayerFactory::getInstance()->getLayerPresentationName(type); | |
646 | |
647 icon = QIcon(QString(":/icons/%1.png") | |
648 .arg(LayerFactory::getInstance()->getLayerIconName(type))); | |
649 | |
650 mainText = tr("Add New %1 Layer").arg(name); | |
651 tipText = tr("Add a new empty layer of type %1").arg(name); | |
652 | |
653 action = new QAction(icon, mainText, this); | |
654 action->setStatusTip(tipText); | |
655 | |
656 if (type == LayerFactory::Text) { | |
657 action->setShortcut(tr("Alt+T")); | |
658 } | |
659 | |
660 connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); | |
661 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); | |
662 m_layerActions[action] = type; | |
663 menu->addAction(action); | |
664 m_rightButtonLayerMenu->addAction(action); | |
665 } | |
666 | |
667 m_rightButtonLayerMenu->addSeparator(); | |
668 menu->addSeparator(); | |
669 | |
670 LayerFactory::LayerType backgroundTypes[] = { | |
671 LayerFactory::Waveform, | |
672 LayerFactory::Spectrogram, | |
673 LayerFactory::MelodicRangeSpectrogram, | |
674 LayerFactory::PeakFrequencySpectrogram, | |
675 LayerFactory::Spectrum | |
676 }; | |
677 | |
678 std::vector<Model *> models; | |
679 if (m_document) models = m_document->getTransformInputModels(); //!!! not well named for this! | |
680 bool plural = (models.size() > 1); | |
681 if (models.empty()) { | |
682 if (m_document) { | |
683 models.push_back(m_document->getMainModel()); // probably 0 | |
684 } else { | |
685 models.push_back(0); | |
686 } | |
687 } | |
688 | |
689 for (unsigned int i = 0; | |
690 i < sizeof(backgroundTypes)/sizeof(backgroundTypes[0]); ++i) { | |
691 | |
692 for (int menuType = 0; menuType <= 1; ++menuType) { // pane, layer | |
693 | |
694 if (menuType == 0) menu = m_paneMenu; | |
695 else menu = m_layerMenu; | |
696 | |
697 QMenu *submenu = 0; | |
698 | |
699 QIcon icon; | |
700 QString mainText, shortcutText, tipText, channelText; | |
701 LayerFactory::LayerType type = backgroundTypes[i]; | |
702 bool mono = true; | |
703 | |
704 switch (type) { | |
705 | |
706 case LayerFactory::Waveform: | |
707 icon = QIcon(":/icons/waveform.png"); | |
708 mainText = tr("Add &Waveform"); | |
709 if (menuType == 0) { | |
710 shortcutText = tr("Alt+W"); | |
711 tipText = tr("Add a new pane showing a waveform view"); | |
712 } else { | |
713 tipText = tr("Add a new layer showing a waveform view"); | |
714 } | |
715 mono = false; | |
716 break; | |
717 | |
718 case LayerFactory::Spectrogram: | |
719 mainText = tr("Add &Spectrogram"); | |
720 if (menuType == 0) { | |
721 shortcutText = tr("Alt+S"); | |
722 tipText = tr("Add a new pane showing a dB spectrogram"); | |
723 } else { | |
724 tipText = tr("Add a new layer showing a dB spectrogram"); | |
725 } | |
726 break; | |
727 | |
728 case LayerFactory::MelodicRangeSpectrogram: | |
729 mainText = tr("Add &Melodic Range Spectrogram"); | |
730 if (menuType == 0) { | |
731 shortcutText = tr("Alt+M"); | |
732 tipText = tr("Add a new pane showing a spectrogram set up for a pitch overview"); | |
733 } else { | |
734 tipText = tr("Add a new layer showing a spectrogram set up for a pitch overview"); | |
735 } | |
736 break; | |
737 | |
738 case LayerFactory::PeakFrequencySpectrogram: | |
739 mainText = tr("Add &Peak Frequency Spectrogram"); | |
740 if (menuType == 0) { | |
741 shortcutText = tr("Alt+P"); | |
742 tipText = tr("Add a new pane showing a spectrogram set up for tracking frequencies"); | |
743 } else { | |
744 tipText = tr("Add a new layer showing a spectrogram set up for tracking frequencies"); | |
745 } | |
746 break; | |
747 | |
748 case LayerFactory::Spectrum: | |
749 mainText = tr("Add Spectr&um"); | |
750 if (menuType == 0) { | |
751 shortcutText = tr("Alt+U"); | |
752 tipText = tr("Add a new pane showing a frequency spectrum"); | |
753 } else { | |
754 tipText = tr("Add a new layer showing a frequency spectrum"); | |
755 } | |
756 break; | |
757 | |
758 default: break; | |
759 } | |
760 | |
761 std::vector<Model *> candidateModels; | |
762 if (menuType == 0) { | |
763 candidateModels = models; | |
764 } else { | |
765 candidateModels.push_back(0); | |
766 } | |
767 | |
768 for (std::vector<Model *>::iterator mi = | |
769 candidateModels.begin(); | |
770 mi != candidateModels.end(); ++mi) { | |
771 | |
772 Model *model = *mi; | |
773 | |
774 int channels = 0; | |
775 if (model) { | |
776 DenseTimeValueModel *dtvm = | |
777 dynamic_cast<DenseTimeValueModel *>(model); | |
778 if (dtvm) channels = dtvm->getChannelCount(); | |
779 } | |
780 if (channels < 1 && getMainModel()) { | |
781 channels = getMainModel()->getChannelCount(); | |
782 } | |
783 if (channels < 1) channels = 1; | |
784 | |
785 for (int c = 0; c <= channels; ++c) { | |
786 | |
787 if (c == 1 && channels == 1) continue; | |
788 bool isDefault = (c == 0); | |
789 bool isOnly = (isDefault && (channels == 1)); | |
790 | |
791 if (menuType == 1) { | |
792 if (isDefault) isOnly = true; | |
793 else continue; | |
794 } | |
795 | |
796 if (isOnly && (!plural || menuType == 1)) { | |
797 | |
798 action = new QAction(icon, mainText, this); | |
799 action->setShortcut(shortcutText); | |
800 action->setStatusTip(tipText); | |
801 if (menuType == 0) { | |
802 connect(action, SIGNAL(triggered()), | |
803 this, SLOT(addPane())); | |
804 connect(this, SIGNAL(canAddPane(bool)), | |
805 action, SLOT(setEnabled(bool))); | |
806 m_paneActions[action] = PaneConfiguration(type); | |
807 } else { | |
808 connect(action, SIGNAL(triggered()), | |
809 this, SLOT(addLayer())); | |
810 connect(this, SIGNAL(canAddLayer(bool)), | |
811 action, SLOT(setEnabled(bool))); | |
812 m_layerActions[action] = type; | |
813 } | |
814 menu->addAction(action); | |
815 | |
816 } else { | |
817 | |
818 if (!submenu) { | |
819 submenu = menu->addMenu(mainText); | |
820 } | |
821 | |
822 QString actionText; | |
823 if (c == 0) { | |
824 if (mono) { | |
825 actionText = tr("&All Channels Mixed"); | |
826 } else { | |
827 actionText = tr("&All Channels"); | |
828 } | |
829 } else { | |
830 actionText = tr("Channel &%1").arg(c); | |
831 } | |
832 | |
833 if (model) { | |
834 actionText = tr("%1: %2") | |
835 .arg(model->objectName()) | |
836 .arg(actionText); | |
837 } | |
838 | |
839 action = new QAction(icon, actionText, this); | |
840 if (isDefault) action->setShortcut(shortcutText); | |
841 action->setStatusTip(tipText); | |
842 | |
843 if (menuType == 0) { | |
844 connect(action, SIGNAL(triggered()), | |
845 this, SLOT(addPane())); | |
846 connect(this, SIGNAL(canAddPane(bool)), | |
847 action, SLOT(setEnabled(bool))); | |
848 m_paneActions[action] = | |
849 PaneConfiguration(type, model, c - 1); | |
850 } else { | |
851 connect(action, SIGNAL(triggered()), | |
852 this, SLOT(addLayer())); | |
853 connect(this, SIGNAL(canAddLayer(bool)), | |
854 action, SLOT(setEnabled(bool))); | |
855 m_layerActions[action] = type; | |
856 } | |
857 | |
858 submenu->addAction(action); | |
859 } | |
860 } | |
861 } | |
862 } | |
863 } | |
864 | |
865 menu = m_paneMenu; | |
866 | |
867 menu->addSeparator(); | |
868 | |
869 action = new QAction(QIcon(":/icons/editdelete.png"), tr("&Delete Pane"), this); | |
870 action->setShortcut(tr("Alt+D")); | |
871 action->setStatusTip(tr("Delete the currently selected pane")); | |
872 connect(action, SIGNAL(triggered()), this, SLOT(deleteCurrentPane())); | |
873 connect(this, SIGNAL(canDeleteCurrentPane(bool)), action, SLOT(setEnabled(bool))); | |
874 menu->addAction(action); | |
875 | |
876 menu = m_layerMenu; | |
877 | |
878 action = new QAction(QIcon(":/icons/timeruler.png"), tr("Add &Time Ruler"), this); | |
879 action->setStatusTip(tr("Add a new layer showing a time ruler")); | |
880 connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); | |
881 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); | |
882 m_layerActions[action] = LayerFactory::TimeRuler; | |
883 menu->addAction(action); | |
884 | |
885 menu->addSeparator(); | |
886 | |
887 m_existingLayersMenu = menu->addMenu(tr("Add &Existing Layer")); | |
888 m_rightButtonLayerMenu->addMenu(m_existingLayersMenu); | |
889 setupExistingLayersMenu(); | |
890 | |
891 m_rightButtonLayerMenu->addSeparator(); | |
892 menu->addSeparator(); | |
893 | |
894 action = new QAction(tr("&Rename Layer..."), this); | |
895 action->setShortcut(tr("Alt+R")); | |
896 action->setStatusTip(tr("Rename the currently active layer")); | |
897 connect(action, SIGNAL(triggered()), this, SLOT(renameCurrentLayer())); | |
898 connect(this, SIGNAL(canRenameLayer(bool)), action, SLOT(setEnabled(bool))); | |
899 menu->addAction(action); | |
900 m_rightButtonLayerMenu->addAction(action); | |
901 | |
902 action = new QAction(QIcon(":/icons/editdelete.png"), tr("&Delete Layer"), this); | |
903 action->setShortcut(tr("Alt+Shift+D")); | |
904 action->setStatusTip(tr("Delete the currently active layer")); | |
905 connect(action, SIGNAL(triggered()), this, SLOT(deleteCurrentLayer())); | |
906 connect(this, SIGNAL(canDeleteCurrentLayer(bool)), action, SLOT(setEnabled(bool))); | |
907 menu->addAction(action); | |
908 m_rightButtonLayerMenu->addAction(action); | |
909 } | |
910 | |
911 void | |
912 MainWindow::setupTransformsMenu() | |
913 { | |
595 if (m_transformsMenu) { | 914 if (m_transformsMenu) { |
596 m_transformActions.clear(); | 915 m_transformActions.clear(); |
597 m_transformActionsReverse.clear(); | 916 m_transformActionsReverse.clear(); |
598 m_transformsMenu->clear(); | 917 m_transformsMenu->clear(); |
599 } else { | 918 } else { |
716 maker.replace(QRegExp(tr(" [\\(<].*$")), ""); | 1035 maker.replace(QRegExp(tr(" [\\(<].*$")), ""); |
717 | 1036 |
718 QString pluginName = description.section(": ", 0, 0); | 1037 QString pluginName = description.section(": ", 0, 0); |
719 QString output = description.section(": ", 1); | 1038 QString output = description.section(": ", 1); |
720 | 1039 |
721 action = new QAction(tr("%1...").arg(description), this); | 1040 QAction *action = new QAction(tr("%1...").arg(description), this); |
722 connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); | 1041 connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); |
723 m_transformActions[action] = transforms[i].name; | 1042 m_transformActions[action] = transforms[i].name; |
724 m_transformActionsReverse[transforms[i].name] = action; | 1043 m_transformActionsReverse[transforms[i].name] = action; |
725 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); | 1044 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); |
726 | 1045 |
775 i != pendingMenus.end(); ++i) { | 1094 i != pendingMenus.end(); ++i) { |
776 (*i)->entriesAdded(); | 1095 (*i)->entriesAdded(); |
777 } | 1096 } |
778 | 1097 |
779 setupRecentTransformsMenu(); | 1098 setupRecentTransformsMenu(); |
780 | 1099 } |
781 menu = m_paneMenu; | 1100 |
782 | 1101 void |
783 action = new QAction(QIcon(":/icons/pane.png"), tr("Add &New Pane"), this); | 1102 MainWindow::setupHelpMenu() |
784 action->setShortcut(tr("Alt+N")); | 1103 { |
785 action->setStatusTip(tr("Add a new pane containing only a time ruler")); | 1104 if (m_mainMenusCreated) return; |
786 connect(action, SIGNAL(triggered()), this, SLOT(addPane())); | 1105 |
787 connect(this, SIGNAL(canAddPane(bool)), action, SLOT(setEnabled(bool))); | 1106 QMenu *menu = menuBar()->addMenu(tr("&Help")); |
788 m_paneActions[action] = PaneConfiguration(LayerFactory::TimeRuler); | |
789 menu->addAction(action); | |
790 | |
791 menu->addSeparator(); | |
792 | |
793 menu = m_layerMenu; | |
794 | |
795 // menu->addSeparator(); | |
796 | |
797 LayerFactory::LayerTypeSet emptyLayerTypes = | |
798 LayerFactory::getInstance()->getValidEmptyLayerTypes(); | |
799 | |
800 for (LayerFactory::LayerTypeSet::iterator i = emptyLayerTypes.begin(); | |
801 i != emptyLayerTypes.end(); ++i) { | |
802 | |
803 QIcon icon; | |
804 QString mainText, tipText, channelText; | |
805 LayerFactory::LayerType type = *i; | |
806 QString name = LayerFactory::getInstance()->getLayerPresentationName(type); | |
807 | |
808 icon = QIcon(QString(":/icons/%1.png") | |
809 .arg(LayerFactory::getInstance()->getLayerIconName(type))); | |
810 | |
811 mainText = tr("Add New %1 Layer").arg(name); | |
812 tipText = tr("Add a new empty layer of type %1").arg(name); | |
813 | |
814 action = new QAction(icon, mainText, this); | |
815 action->setStatusTip(tipText); | |
816 | |
817 if (type == LayerFactory::Text) { | |
818 action->setShortcut(tr("Alt+T")); | |
819 } | |
820 | |
821 connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); | |
822 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); | |
823 m_layerActions[action] = type; | |
824 menu->addAction(action); | |
825 m_rightButtonLayerMenu->addAction(action); | |
826 } | |
827 | 1107 |
828 m_rightButtonLayerMenu->addSeparator(); | 1108 QAction *action = new QAction(tr("&Help Reference"), this); |
829 menu->addSeparator(); | 1109 action->setStatusTip(tr("Open the Sonic Visualiser reference manual")); |
830 | 1110 connect(action, SIGNAL(triggered()), this, SLOT(help())); |
831 int channels = 1; | 1111 menu->addAction(action); |
832 if (getMainModel()) channels = getMainModel()->getChannelCount(); | 1112 |
833 | 1113 action = new QAction(tr("Sonic Visualiser on the &Web"), this); |
834 if (channels < 1) channels = 1; | 1114 action->setStatusTip(tr("Open the Sonic Visualiser website")); |
835 | 1115 connect(action, SIGNAL(triggered()), this, SLOT(website())); |
836 LayerFactory::LayerType backgroundTypes[] = { | 1116 menu->addAction(action); |
837 LayerFactory::Waveform, | 1117 |
838 LayerFactory::Spectrogram, | 1118 action = new QAction(tr("&About Sonic Visualiser"), this); |
839 LayerFactory::MelodicRangeSpectrogram, | 1119 action->setStatusTip(tr("Show information about Sonic Visualiser")); |
840 LayerFactory::PeakFrequencySpectrogram, | 1120 connect(action, SIGNAL(triggered()), this, SLOT(about())); |
841 LayerFactory::Spectrum | 1121 menu->addAction(action); |
842 }; | |
843 | |
844 for (unsigned int i = 0; | |
845 i < sizeof(backgroundTypes)/sizeof(backgroundTypes[0]); ++i) { | |
846 | |
847 for (int menuType = 0; menuType <= 1; ++menuType) { // pane, layer | |
848 | |
849 if (menuType == 0) menu = m_paneMenu; | |
850 else menu = m_layerMenu; | |
851 | |
852 QMenu *submenu = 0; | |
853 | |
854 for (int c = 0; c <= channels; ++c) { | |
855 | |
856 if (c == 1 && channels == 1) continue; | |
857 bool isDefault = (c == 0); | |
858 bool isOnly = (isDefault && (channels == 1)); | |
859 | |
860 if (menuType == 1) { | |
861 if (isDefault) isOnly = true; | |
862 else continue; | |
863 } | |
864 | |
865 QIcon icon; | |
866 QString mainText, shortcutText, tipText, channelText; | |
867 LayerFactory::LayerType type = backgroundTypes[i]; | |
868 bool mono = true; | |
869 | |
870 switch (type) { | |
871 | |
872 case LayerFactory::Waveform: | |
873 icon = QIcon(":/icons/waveform.png"); | |
874 mainText = tr("Add &Waveform"); | |
875 if (menuType == 0) { | |
876 shortcutText = tr("Alt+W"); | |
877 tipText = tr("Add a new pane showing a waveform view"); | |
878 } else { | |
879 tipText = tr("Add a new layer showing a waveform view"); | |
880 } | |
881 mono = false; | |
882 break; | |
883 | |
884 case LayerFactory::Spectrogram: | |
885 mainText = tr("Add &Spectrogram"); | |
886 if (menuType == 0) { | |
887 shortcutText = tr("Alt+S"); | |
888 tipText = tr("Add a new pane showing a dB spectrogram"); | |
889 } else { | |
890 tipText = tr("Add a new layer showing a dB spectrogram"); | |
891 } | |
892 break; | |
893 | |
894 case LayerFactory::MelodicRangeSpectrogram: | |
895 mainText = tr("Add &Melodic Range Spectrogram"); | |
896 if (menuType == 0) { | |
897 shortcutText = tr("Alt+M"); | |
898 tipText = tr("Add a new pane showing a spectrogram set up for a pitch overview"); | |
899 } else { | |
900 tipText = tr("Add a new layer showing a spectrogram set up for a pitch overview"); | |
901 } | |
902 break; | |
903 | |
904 case LayerFactory::PeakFrequencySpectrogram: | |
905 mainText = tr("Add &Peak Frequency Spectrogram"); | |
906 if (menuType == 0) { | |
907 shortcutText = tr("Alt+P"); | |
908 tipText = tr("Add a new pane showing a spectrogram set up for tracking frequencies"); | |
909 } else { | |
910 tipText = tr("Add a new layer showing a spectrogram set up for tracking frequencies"); | |
911 } | |
912 break; | |
913 | |
914 case LayerFactory::Spectrum: | |
915 mainText = tr("Add Spectr&um"); | |
916 if (menuType == 0) { | |
917 shortcutText = tr("Alt+U"); | |
918 tipText = tr("Add a new pane showing a frequency spectrum"); | |
919 } else { | |
920 tipText = tr("Add a new layer showing a frequency spectrum"); | |
921 } | |
922 break; | |
923 | |
924 default: break; | |
925 } | |
926 | |
927 if (isOnly) { | |
928 | |
929 action = new QAction(icon, mainText, this); | |
930 action->setShortcut(shortcutText); | |
931 action->setStatusTip(tipText); | |
932 if (menuType == 0) { | |
933 connect(action, SIGNAL(triggered()), this, SLOT(addPane())); | |
934 connect(this, SIGNAL(canAddPane(bool)), action, SLOT(setEnabled(bool))); | |
935 m_paneActions[action] = PaneConfiguration(type); | |
936 } else { | |
937 connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); | |
938 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); | |
939 m_layerActions[action] = type; | |
940 } | |
941 menu->addAction(action); | |
942 | |
943 } else { | |
944 | |
945 QString actionText; | |
946 if (c == 0) | |
947 if (mono) actionText = tr("&All Channels Mixed"); | |
948 else actionText = tr("&All Channels"); | |
949 else actionText = tr("Channel &%1").arg(c); | |
950 | |
951 if (!submenu) { | |
952 submenu = menu->addMenu(mainText); | |
953 } | |
954 | |
955 action = new QAction(icon, actionText, this); | |
956 if (isDefault) action->setShortcut(shortcutText); | |
957 action->setStatusTip(tipText); | |
958 if (menuType == 0) { | |
959 connect(action, SIGNAL(triggered()), this, SLOT(addPane())); | |
960 connect(this, SIGNAL(canAddPane(bool)), action, SLOT(setEnabled(bool))); | |
961 m_paneActions[action] = PaneConfiguration(type, c - 1); | |
962 } else { | |
963 connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); | |
964 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); | |
965 m_layerActions[action] = type; | |
966 } | |
967 submenu->addAction(action); | |
968 } | |
969 } | |
970 } | |
971 } | |
972 | |
973 menu = m_paneMenu; | |
974 | |
975 menu->addSeparator(); | |
976 | |
977 action = new QAction(QIcon(":/icons/editdelete.png"), tr("&Delete Pane"), this); | |
978 action->setShortcut(tr("Alt+D")); | |
979 action->setStatusTip(tr("Delete the currently selected pane")); | |
980 connect(action, SIGNAL(triggered()), this, SLOT(deleteCurrentPane())); | |
981 connect(this, SIGNAL(canDeleteCurrentPane(bool)), action, SLOT(setEnabled(bool))); | |
982 menu->addAction(action); | |
983 | |
984 menu = m_layerMenu; | |
985 | |
986 action = new QAction(QIcon(":/icons/timeruler.png"), tr("Add &Time Ruler"), this); | |
987 action->setStatusTip(tr("Add a new layer showing a time ruler")); | |
988 connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); | |
989 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); | |
990 m_layerActions[action] = LayerFactory::TimeRuler; | |
991 menu->addAction(action); | |
992 | |
993 menu->addSeparator(); | |
994 | |
995 m_existingLayersMenu = menu->addMenu(tr("Add &Existing Layer")); | |
996 m_rightButtonLayerMenu->addMenu(m_existingLayersMenu); | |
997 setupExistingLayersMenu(); | |
998 | |
999 m_rightButtonLayerMenu->addSeparator(); | |
1000 menu->addSeparator(); | |
1001 | |
1002 action = new QAction(tr("&Rename Layer..."), this); | |
1003 action->setShortcut(tr("Alt+R")); | |
1004 action->setStatusTip(tr("Rename the currently active layer")); | |
1005 connect(action, SIGNAL(triggered()), this, SLOT(renameCurrentLayer())); | |
1006 connect(this, SIGNAL(canRenameLayer(bool)), action, SLOT(setEnabled(bool))); | |
1007 menu->addAction(action); | |
1008 m_rightButtonLayerMenu->addAction(action); | |
1009 | |
1010 action = new QAction(QIcon(":/icons/editdelete.png"), tr("&Delete Layer"), this); | |
1011 action->setShortcut(tr("Alt+Shift+D")); | |
1012 action->setStatusTip(tr("Delete the currently active layer")); | |
1013 connect(action, SIGNAL(triggered()), this, SLOT(deleteCurrentLayer())); | |
1014 connect(this, SIGNAL(canDeleteCurrentLayer(bool)), action, SLOT(setEnabled(bool))); | |
1015 menu->addAction(action); | |
1016 m_rightButtonLayerMenu->addAction(action); | |
1017 | |
1018 if (!m_mainMenusCreated) { | |
1019 | |
1020 menu = menuBar()->addMenu(tr("&Help")); | |
1021 | |
1022 action = new QAction(tr("&Help Reference"), this); | |
1023 action->setStatusTip(tr("Open the Sonic Visualiser reference manual")); | |
1024 connect(action, SIGNAL(triggered()), this, SLOT(help())); | |
1025 menu->addAction(action); | |
1026 | |
1027 action = new QAction(tr("Sonic Visualiser on the &Web"), this); | |
1028 action->setStatusTip(tr("Open the Sonic Visualiser website")); | |
1029 connect(action, SIGNAL(triggered()), this, SLOT(website())); | |
1030 menu->addAction(action); | |
1031 | |
1032 action = new QAction(tr("&About Sonic Visualiser"), this); | |
1033 action->setStatusTip(tr("Show information about Sonic Visualiser")); | |
1034 connect(action, SIGNAL(triggered()), this, SLOT(about())); | |
1035 menu->addAction(action); | |
1036 /* | |
1037 action = new QAction(tr("About &Qt"), this); | |
1038 action->setStatusTip(tr("Show information about Qt")); | |
1039 connect(action, SIGNAL(triggered()), | |
1040 QApplication::getInstance(), SLOT(aboutQt())); | |
1041 menu->addAction(action); | |
1042 */ | |
1043 } | |
1044 | |
1045 m_mainMenusCreated = true; | |
1046 } | 1122 } |
1047 | 1123 |
1048 void | 1124 void |
1049 MainWindow::setupRecentFilesMenu() | 1125 MainWindow::setupRecentFilesMenu() |
1050 { | 1126 { |
2794 | 2870 |
2795 m_document->addLayerToView(pane, m_timeRulerLayer); | 2871 m_document->addLayerToView(pane, m_timeRulerLayer); |
2796 } | 2872 } |
2797 | 2873 |
2798 Layer *newLayer = m_document->createLayer(i->second.layer); | 2874 Layer *newLayer = m_document->createLayer(i->second.layer); |
2799 m_document->setModel(newLayer, m_document->getMainModel()); | 2875 |
2876 Model *suggestedModel = i->second.sourceModel; | |
2877 Model *model = 0; | |
2878 | |
2879 if (suggestedModel) { | |
2880 | |
2881 // check its validity | |
2882 std::vector<Model *> inputModels = m_document->getTransformInputModels(); | |
2883 for (size_t j = 0; j < inputModels.size(); ++j) { | |
2884 if (inputModels[j] == suggestedModel) { | |
2885 model = suggestedModel; | |
2886 break; | |
2887 } | |
2888 } | |
2889 | |
2890 if (!model) { | |
2891 std::cerr << "WARNING: Model " << (void *)suggestedModel | |
2892 << " appears in pane action map, but is not reported " | |
2893 << "by document as a valid transform source" << std::endl; | |
2894 } | |
2895 } | |
2896 | |
2897 if (!model) model = m_document->getMainModel(); | |
2898 | |
2899 m_document->setModel(newLayer, model); | |
2900 | |
2800 m_document->setChannel(newLayer, i->second.channel); | 2901 m_document->setChannel(newLayer, i->second.channel); |
2801 m_document->addLayerToView(pane, newLayer); | 2902 m_document->addLayerToView(pane, newLayer); |
2802 | 2903 |
2803 m_paneStack->setCurrentPane(pane); | 2904 m_paneStack->setCurrentPane(pane); |
2804 | 2905 |
2972 // supposed to be configurable, because we need to let the user | 3073 // supposed to be configurable, because we need to let the user |
2973 // change the execution context (block size etc). | 3074 // change the execution context (block size etc). |
2974 | 3075 |
2975 PluginTransform::ExecutionContext context(channel); | 3076 PluginTransform::ExecutionContext context(channel); |
2976 | 3077 |
2977 std::vector<Model *> candidateInputModels; | 3078 std::vector<Model *> candidateInputModels = |
2978 candidateInputModels.push_back(m_document->getMainModel()); | 3079 m_document->getTransformInputModels(); |
2979 | |
2980 //!!! rationalise this (via document method for example) | |
2981 for (int i = 0; i < m_paneStack->getPaneCount(); ++i) { | |
2982 Pane *ip = m_paneStack->getPane(i); | |
2983 if (!ip) continue; | |
2984 for (int j = 0; j < ip->getLayerCount(); ++j) { | |
2985 Layer *jl = ip->getLayer(j); | |
2986 if (jl) { | |
2987 Model *model = jl->getModel(); | |
2988 DenseTimeValueModel *dtvm = dynamic_cast<DenseTimeValueModel *> | |
2989 (model); | |
2990 if (dtvm) { | |
2991 int k; | |
2992 for (k = 0; k < candidateInputModels.size(); ++k) { | |
2993 if (candidateInputModels[k] == dtvm) break; | |
2994 } | |
2995 if (k == candidateInputModels.size()) { | |
2996 candidateInputModels.push_back(dtvm); | |
2997 } | |
2998 } | |
2999 } | |
3000 } | |
3001 } | |
3002 | 3080 |
3003 Model *inputModel = factory->getConfigurationForTransform(transform, | 3081 Model *inputModel = factory->getConfigurationForTransform(transform, |
3004 candidateInputModels, | 3082 candidateInputModels, |
3005 context, | 3083 context, |
3006 configurationXml, | 3084 configurationXml, |
3234 void | 3312 void |
3235 MainWindow::modelAdded(Model *model) | 3313 MainWindow::modelAdded(Model *model) |
3236 { | 3314 { |
3237 // std::cerr << "MainWindow::modelAdded(" << model << ")" << std::endl; | 3315 // std::cerr << "MainWindow::modelAdded(" << model << ")" << std::endl; |
3238 m_playSource->addModel(model); | 3316 m_playSource->addModel(model); |
3317 if (dynamic_cast<DenseTimeValueModel *>(model)) { | |
3318 setupPaneAndLayerMenus(); | |
3319 } | |
3239 } | 3320 } |
3240 | 3321 |
3241 void | 3322 void |
3242 MainWindow::mainModelChanged(WaveFileModel *model) | 3323 MainWindow::mainModelChanged(WaveFileModel *model) |
3243 { | 3324 { |