Chris@127: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@127: Chris@127: /* Chris@127: Sonic Visualiser Chris@127: An audio file viewer and annotation editor. Chris@127: Centre for Digital Music, Queen Mary, University of London. Chris@182: This file copyright 2006 Chris Cannam and QMUL. Chris@127: Chris@127: This program is free software; you can redistribute it and/or Chris@127: modify it under the terms of the GNU General Public License as Chris@127: published by the Free Software Foundation; either version 2 of the Chris@127: License, or (at your option) any later version. See the file Chris@127: COPYING included with this distribution for more information. Chris@127: */ Chris@127: Chris@127: #include "ViewManager.h" Chris@128: #include "base/AudioPlaySource.h" Chris@128: #include "data/model/Model.h" Chris@128: #include "base/CommandHistory.h" Chris@211: #include "View.h" Chris@127: Chris@133: #include Chris@133: Chris@127: #include Chris@127: Chris@180: //#define DEBUG_VIEW_MANAGER 1 Chris@127: Chris@127: ViewManager::ViewManager() : Chris@127: m_playSource(0), Chris@127: m_globalCentreFrame(0), Chris@127: m_globalZoom(1024), Chris@127: m_playbackFrame(0), Chris@127: m_mainModelSampleRate(0), Chris@127: m_lastLeft(0), Chris@127: m_lastRight(0), Chris@127: m_inProgressExclusive(true), Chris@127: m_toolMode(NavigateMode), Chris@127: m_playLoopMode(false), Chris@127: m_playSelectionMode(false), Chris@189: m_overlayMode(StandardOverlays), Chris@133: m_zoomWheelsEnabled(true) Chris@127: { Chris@133: QSettings settings; Chris@133: settings.beginGroup("MainWindow"); Chris@133: m_overlayMode = OverlayMode Chris@133: (settings.value("overlay-mode", int(m_overlayMode)).toInt()); Chris@133: m_zoomWheelsEnabled = Chris@133: settings.value("zoom-wheels-enabled", m_zoomWheelsEnabled).toBool(); Chris@133: settings.endGroup(); Chris@222: /*!!! Chris@127: connect(this, Chris@127: SIGNAL(zoomLevelChanged(void *, unsigned long, bool)), Chris@127: SLOT(considerZoomChange(void *, unsigned long, bool))); Chris@222: */ Chris@127: } Chris@127: Chris@127: ViewManager::~ViewManager() Chris@127: { Chris@127: } Chris@127: Chris@127: unsigned long Chris@127: ViewManager::getGlobalCentreFrame() const Chris@127: { Chris@127: #ifdef DEBUG_VIEW_MANAGER Chris@127: std::cout << "ViewManager::getGlobalCentreFrame: returning " << m_globalCentreFrame << std::endl; Chris@127: #endif Chris@127: return m_globalCentreFrame; Chris@127: } Chris@127: Chris@180: void Chris@180: ViewManager::setGlobalCentreFrame(unsigned long f) Chris@180: { Chris@180: #ifdef DEBUG_VIEW_MANAGER Chris@180: std::cout << "ViewManager::setGlobalCentreFrame to " << f << std::endl; Chris@180: #endif Chris@180: m_globalCentreFrame = f; Chris@211: emit globalCentreFrameChanged(f); Chris@180: } Chris@180: Chris@127: unsigned long Chris@127: ViewManager::getGlobalZoom() const Chris@127: { Chris@127: #ifdef DEBUG_VIEW_MANAGER Chris@127: std::cout << "ViewManager::getGlobalZoom: returning " << m_globalZoom << std::endl; Chris@127: #endif Chris@127: return m_globalZoom; Chris@127: } Chris@127: Chris@127: unsigned long Chris@127: ViewManager::getPlaybackFrame() const Chris@127: { Chris@127: if (m_playSource && m_playSource->isPlaying()) { Chris@127: m_playbackFrame = m_playSource->getCurrentPlayingFrame(); Chris@127: } Chris@127: return m_playbackFrame; Chris@127: } Chris@127: Chris@127: void Chris@127: ViewManager::setPlaybackFrame(unsigned long f) Chris@127: { Chris@127: if (m_playbackFrame != f) { Chris@127: m_playbackFrame = f; Chris@127: emit playbackFrameChanged(f); Chris@127: if (m_playSource && m_playSource->isPlaying()) { Chris@127: m_playSource->play(f); Chris@127: } Chris@127: } Chris@127: } Chris@127: Chris@127: bool Chris@127: ViewManager::haveInProgressSelection() const Chris@127: { Chris@127: return !m_inProgressSelection.isEmpty(); Chris@127: } Chris@127: Chris@127: const Selection & Chris@127: ViewManager::getInProgressSelection(bool &exclusive) const Chris@127: { Chris@127: exclusive = m_inProgressExclusive; Chris@127: return m_inProgressSelection; Chris@127: } Chris@127: Chris@127: void Chris@127: ViewManager::setInProgressSelection(const Selection &selection, bool exclusive) Chris@127: { Chris@127: m_inProgressExclusive = exclusive; Chris@127: m_inProgressSelection = selection; Chris@127: if (exclusive) clearSelections(); Chris@127: emit inProgressSelectionChanged(); Chris@127: } Chris@127: Chris@127: void Chris@127: ViewManager::clearInProgressSelection() Chris@127: { Chris@127: m_inProgressSelection = Selection(); Chris@127: emit inProgressSelectionChanged(); Chris@127: } Chris@127: Chris@127: const MultiSelection & Chris@127: ViewManager::getSelection() const Chris@127: { Chris@127: return m_selections; Chris@127: } Chris@127: Chris@127: const MultiSelection::SelectionList & Chris@127: ViewManager::getSelections() const Chris@127: { Chris@127: return m_selections.getSelections(); Chris@127: } Chris@127: Chris@127: void Chris@127: ViewManager::setSelection(const Selection &selection) Chris@127: { Chris@127: MultiSelection ms(m_selections); Chris@127: ms.setSelection(selection); Chris@127: setSelections(ms); Chris@127: } Chris@127: Chris@127: void Chris@127: ViewManager::addSelection(const Selection &selection) Chris@127: { Chris@127: MultiSelection ms(m_selections); Chris@127: ms.addSelection(selection); Chris@127: setSelections(ms); Chris@127: } Chris@127: Chris@127: void Chris@127: ViewManager::removeSelection(const Selection &selection) Chris@127: { Chris@127: MultiSelection ms(m_selections); Chris@127: ms.removeSelection(selection); Chris@127: setSelections(ms); Chris@127: } Chris@127: Chris@127: void Chris@127: ViewManager::clearSelections() Chris@127: { Chris@127: MultiSelection ms(m_selections); Chris@127: ms.clearSelections(); Chris@127: setSelections(ms); Chris@127: } Chris@127: Chris@127: void Chris@127: ViewManager::setSelections(const MultiSelection &ms) Chris@127: { Chris@127: if (m_selections.getSelections() == ms.getSelections()) return; Chris@127: SetSelectionCommand *command = new SetSelectionCommand(this, ms); Chris@127: CommandHistory::getInstance()->addCommand(command); Chris@127: } Chris@127: Chris@127: void Chris@127: ViewManager::signalSelectionChange() Chris@127: { Chris@127: emit selectionChanged(); Chris@127: } Chris@127: Chris@127: ViewManager::SetSelectionCommand::SetSelectionCommand(ViewManager *vm, Chris@127: const MultiSelection &ms) : Chris@127: m_vm(vm), Chris@127: m_oldSelection(vm->m_selections), Chris@127: m_newSelection(ms) Chris@127: { Chris@127: } Chris@127: Chris@127: ViewManager::SetSelectionCommand::~SetSelectionCommand() { } Chris@127: Chris@127: void Chris@127: ViewManager::SetSelectionCommand::execute() Chris@127: { Chris@127: m_vm->m_selections = m_newSelection; Chris@127: m_vm->signalSelectionChange(); Chris@127: } Chris@127: Chris@127: void Chris@127: ViewManager::SetSelectionCommand::unexecute() Chris@127: { Chris@127: m_vm->m_selections = m_oldSelection; Chris@127: m_vm->signalSelectionChange(); Chris@127: } Chris@127: Chris@127: QString Chris@127: ViewManager::SetSelectionCommand::getName() const Chris@127: { Chris@127: if (m_newSelection.getSelections().empty()) return tr("Clear Selection"); Chris@127: else return tr("Select"); Chris@127: } Chris@127: Chris@127: Selection Chris@127: ViewManager::getContainingSelection(size_t frame, bool defaultToFollowing) const Chris@127: { Chris@127: return m_selections.getContainingSelection(frame, defaultToFollowing); Chris@127: } Chris@127: Chris@127: void Chris@127: ViewManager::setToolMode(ToolMode mode) Chris@127: { Chris@127: m_toolMode = mode; Chris@127: Chris@127: emit toolModeChanged(); Chris@127: } Chris@127: Chris@127: void Chris@127: ViewManager::setPlayLoopMode(bool mode) Chris@127: { Chris@177: if (m_playLoopMode != mode) { Chris@127: Chris@177: m_playLoopMode = mode; Chris@177: Chris@177: emit playLoopModeChanged(); Chris@177: emit playLoopModeChanged(mode); Chris@177: } Chris@127: } Chris@127: Chris@127: void Chris@127: ViewManager::setPlaySelectionMode(bool mode) Chris@127: { Chris@177: if (m_playSelectionMode != mode) { Chris@127: Chris@177: m_playSelectionMode = mode; Chris@177: Chris@177: emit playSelectionModeChanged(); Chris@177: emit playSelectionModeChanged(mode); Chris@177: } Chris@127: } Chris@127: Chris@224: size_t Chris@224: ViewManager::getPlaybackSampleRate() const Chris@224: { Chris@224: if (m_playSource) { Chris@224: return m_playSource->getSourceSampleRate(); Chris@224: } Chris@224: return 0; Chris@224: } Chris@224: Chris@127: size_t Chris@224: ViewManager::getOutputSampleRate() const Chris@127: { Chris@127: if (m_playSource) { Chris@127: return m_playSource->getTargetSampleRate(); Chris@127: } Chris@127: return 0; Chris@127: } Chris@127: Chris@127: void Chris@127: ViewManager::setAudioPlaySource(AudioPlaySource *source) Chris@127: { Chris@127: if (!m_playSource) { Chris@127: QTimer::singleShot(100, this, SLOT(checkPlayStatus())); Chris@127: } Chris@127: m_playSource = source; Chris@127: } Chris@127: Chris@127: void Chris@127: ViewManager::playStatusChanged(bool playing) Chris@127: { Chris@127: checkPlayStatus(); Chris@127: } Chris@127: Chris@127: void Chris@127: ViewManager::checkPlayStatus() Chris@127: { Chris@127: if (m_playSource && m_playSource->isPlaying()) { Chris@127: Chris@127: float left = 0, right = 0; Chris@127: if (m_playSource->getOutputLevels(left, right)) { Chris@127: if (left != m_lastLeft || right != m_lastRight) { Chris@127: emit outputLevelsChanged(left, right); Chris@127: m_lastLeft = left; Chris@127: m_lastRight = right; Chris@127: } Chris@127: } Chris@127: Chris@127: m_playbackFrame = m_playSource->getCurrentPlayingFrame(); Chris@127: Chris@127: #ifdef DEBUG_VIEW_MANAGER Chris@127: std::cout << "ViewManager::checkPlayStatus: Playing, frame " << m_playbackFrame << ", levels " << m_lastLeft << "," << m_lastRight << std::endl; Chris@127: #endif Chris@127: Chris@127: emit playbackFrameChanged(m_playbackFrame); Chris@127: Chris@127: QTimer::singleShot(20, this, SLOT(checkPlayStatus())); Chris@127: Chris@127: } else { Chris@127: Chris@127: QTimer::singleShot(100, this, SLOT(checkPlayStatus())); Chris@127: Chris@127: if (m_lastLeft != 0.0 || m_lastRight != 0.0) { Chris@127: emit outputLevelsChanged(0.0, 0.0); Chris@127: m_lastLeft = 0.0; Chris@127: m_lastRight = 0.0; Chris@127: } Chris@127: Chris@127: #ifdef DEBUG_VIEW_MANAGER Chris@127: // std::cout << "ViewManager::checkPlayStatus: Not playing" << std::endl; Chris@127: #endif Chris@127: } Chris@127: } Chris@127: Chris@127: bool Chris@127: ViewManager::isPlaying() const Chris@127: { Chris@127: return m_playSource && m_playSource->isPlaying(); Chris@127: } Chris@127: Chris@127: void Chris@211: ViewManager::viewCentreFrameChanged(unsigned long f, bool locked, Chris@211: PlaybackFollowMode mode) Chris@127: { Chris@211: View *v = dynamic_cast(sender()); Chris@211: Chris@127: if (locked) { Chris@211: m_globalCentreFrame = f; Chris@211: emit globalCentreFrameChanged(f); Chris@211: } else { Chris@211: if (v) emit viewCentreFrameChanged(v, f); Chris@127: } Chris@127: Chris@211: if (mode == PlaybackIgnore) { Chris@211: return; Chris@211: } Chris@211: Chris@211: seek(f); Chris@211: } Chris@211: Chris@211: void Chris@211: ViewManager::seek(unsigned long f) Chris@211: { Chris@127: #ifdef DEBUG_VIEW_MANAGER Chris@211: std::cout << "ViewManager::seek(" << f << ")" << std::endl; Chris@127: #endif Chris@127: Chris@127: if (m_playSource && m_playSource->isPlaying()) { Chris@127: unsigned long playFrame = m_playSource->getCurrentPlayingFrame(); Chris@127: unsigned long diff = std::max(f, playFrame) - std::min(f, playFrame); Chris@127: if (diff > 20000) { Chris@127: m_playbackFrame = f; Chris@127: m_playSource->play(f); Chris@127: #ifdef DEBUG_VIEW_MANAGER Chris@127: std::cout << "ViewManager::considerSeek: reseeking from " << playFrame << " to " << f << std::endl; Chris@127: #endif Chris@211: emit playbackFrameChanged(f); Chris@127: } Chris@127: } else { Chris@211: if (m_playbackFrame != f) { Chris@211: m_playbackFrame = f; Chris@211: emit playbackFrameChanged(f); Chris@211: } Chris@127: } Chris@127: } Chris@127: Chris@127: void Chris@222: ViewManager::viewZoomLevelChanged(unsigned long z, bool locked) Chris@127: { Chris@222: View *v = dynamic_cast(sender()); Chris@222: Chris@222: if (!v) { Chris@222: std::cerr << "ViewManager::viewZoomLevelChanged: WARNING: sender is not a view" << std::endl; Chris@222: return; Chris@222: } Chris@222: Chris@222: //!!! emit zoomLevelChanged(); Chris@133: Chris@127: if (locked) { Chris@127: m_globalZoom = z; Chris@127: } Chris@127: Chris@127: #ifdef DEBUG_VIEW_MANAGER Chris@222: std::cout << "ViewManager::viewZoomLevelChanged(" << v << ", " << z << ", " << locked << ")" << std::endl; Chris@127: #endif Chris@222: Chris@222: emit viewZoomLevelChanged(v, z, locked); Chris@127: } Chris@127: Chris@127: void Chris@127: ViewManager::setOverlayMode(OverlayMode mode) Chris@127: { Chris@127: if (m_overlayMode != mode) { Chris@127: m_overlayMode = mode; Chris@127: emit overlayModeChanged(); Chris@127: } Chris@133: Chris@133: QSettings settings; Chris@133: settings.beginGroup("MainWindow"); Chris@133: settings.setValue("overlay-mode", int(m_overlayMode)); Chris@133: settings.endGroup(); Chris@127: } Chris@127: Chris@133: void Chris@133: ViewManager::setZoomWheelsEnabled(bool enabled) Chris@133: { Chris@133: if (m_zoomWheelsEnabled != enabled) { Chris@133: m_zoomWheelsEnabled = enabled; Chris@133: emit zoomWheelsEnabledChanged(); Chris@133: } Chris@127: Chris@133: QSettings settings; Chris@133: settings.beginGroup("MainWindow"); Chris@133: settings.setValue("zoom-wheels-enabled", m_zoomWheelsEnabled); Chris@133: settings.endGroup(); Chris@133: } Chris@133: