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@1210: #include "base/AudioRecordTarget.h" Chris@502: #include "base/RealTime.h" Chris@128: #include "data/model/Model.h" Chris@376: #include "widgets/CommandHistory.h" Chris@211: #include "View.h" Chris@503: #include "Overview.h" Chris@127: Chris@1577: #include "system/System.h" Chris@1577: Chris@133: #include Chris@292: #include Chris@1575: #include Chris@133: Chris@127: #include Chris@127: Chris@643: //#define DEBUG_VIEW_MANAGER 1 Chris@127: Chris@127: ViewManager::ViewManager() : Chris@1408: m_playSource(nullptr), Chris@1408: m_recordTarget(nullptr), Chris@127: m_globalCentreFrame(0), Chris@1327: m_globalZoom(ZoomLevel::FramesPerPixel, 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@301: m_playSoloMode(false), Chris@314: m_alignMode(false), Chris@741: m_overlayMode(StandardOverlays), Chris@292: m_zoomWheelsEnabled(true), Chris@1468: m_opportunisticEditingEnabled(true), Chris@607: m_showCentreLine(true), Chris@326: m_illuminateLocalFeatures(true), Chris@326: m_showWorkTitle(false), matthiasm@822: m_showDuration(true), Chris@292: m_lightPalette(QApplication::palette()), Chris@292: m_darkPalette(QApplication::palette()) 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@607: Chris@607: if (m_overlayMode != NoOverlays && Chris@741: m_overlayMode != StandardOverlays && Chris@607: m_overlayMode != AllOverlays) { Chris@741: m_overlayMode = StandardOverlays; Chris@607: } Chris@607: Chris@133: m_zoomWheelsEnabled = Chris@133: settings.value("zoom-wheels-enabled", m_zoomWheelsEnabled).toBool(); Chris@607: m_showCentreLine = Chris@607: settings.value("show-centre-line", m_showCentreLine).toBool(); Chris@133: settings.endGroup(); Chris@292: Chris@292: if (getGlobalDarkBackground()) { Chris@1573: // i.e. widgets are already dark; create a light palette in Chris@1573: // case we are asked to switch to it, but don't create a dark Chris@1573: // one because it will be assigned from the actual application Chris@1573: // palette if we switch Chris@1573: Chris@293: m_lightPalette = QPalette(QColor("#000000"), // WindowText Chris@293: QColor("#dddfe4"), // Button Chris@293: QColor("#ffffff"), // Light Chris@293: QColor("#555555"), // Dark Chris@293: QColor("#c7c7c7"), // Mid Chris@293: QColor("#000000"), // Text Chris@293: QColor("#ffffff"), // BrightText Chris@293: QColor("#ffffff"), // Base Chris@293: QColor("#efefef")); // Window Chris@1577: Chris@1577: m_lightPalette.setColor(QPalette::Highlight, Qt::darkBlue); Chris@1577: if (!OSReportsDarkThemeActive()) { Chris@1577: int r, g, b; Chris@1616: if (OSQueryAccentColour(&r, &g, &b)) { Chris@1577: m_lightPalette.setColor(QPalette::Highlight, QColor(r, g, b)); Chris@1577: } Chris@1577: } Chris@293: Chris@292: } else { Chris@1573: // i.e. widgets are currently light; create a dark palette in Chris@1573: // case we are asked to switch to it, but don't create a light Chris@1573: // one because it will be assigned from the actual application Chris@1573: // palette if we switch Chris@1573: Chris@1573: m_darkPalette = QPalette(QColor("#f0f0f0"), // WindowText Chris@293: QColor("#3e3e3e"), // Button Chris@293: QColor("#808080"), // Light Chris@293: QColor("#1e1e1e"), // Dark Chris@293: QColor("#404040"), // Mid Chris@1573: QColor("#f0f0f0"), // Text Chris@293: QColor("#ffffff"), // BrightText Chris@293: QColor("#000000"), // Base Chris@293: QColor("#202020")); // Window Chris@1573: Chris@1576: m_darkPalette.setColor(QPalette::Highlight, QColor(25, 130, 220)); Chris@1577: if (OSReportsDarkThemeActive()) { Chris@1577: int r, g, b; Chris@1616: if (OSQueryAccentColour(&r, &g, &b)) { Chris@1577: m_darkPalette.setColor(QPalette::Highlight, QColor(r, g, b)); Chris@1577: } Chris@1577: } Chris@1577: Chris@1576: m_darkPalette.setColor(QPalette::Link, QColor(50, 175, 255)); Chris@1576: m_darkPalette.setColor(QPalette::LinkVisited, QColor(50, 175, 255)); Chris@1576: Chris@1573: m_darkPalette.setColor(QPalette::Disabled, QPalette::WindowText, Chris@1573: QColor("#808080")); Chris@1573: m_darkPalette.setColor(QPalette::Disabled, QPalette::Text, Chris@1573: QColor("#808080")); Chris@1573: m_darkPalette.setColor(QPalette::Disabled, QPalette::Shadow, Chris@1573: QColor("#000000")); Chris@292: } Chris@127: } Chris@127: Chris@127: ViewManager::~ViewManager() Chris@127: { Chris@127: } Chris@127: Chris@902: sv_frame_t Chris@127: ViewManager::getGlobalCentreFrame() const Chris@127: { Chris@127: #ifdef DEBUG_VIEW_MANAGER Chris@682: cerr << "ViewManager::getGlobalCentreFrame: returning " << m_globalCentreFrame << endl; Chris@127: #endif Chris@127: return m_globalCentreFrame; Chris@127: } Chris@127: Chris@180: void Chris@902: ViewManager::setGlobalCentreFrame(sv_frame_t f) Chris@180: { Chris@180: #ifdef DEBUG_VIEW_MANAGER Chris@682: cerr << "ViewManager::setGlobalCentreFrame to " << f << endl; Chris@180: #endif Chris@180: m_globalCentreFrame = f; Chris@211: emit globalCentreFrameChanged(f); Chris@180: } Chris@180: Chris@1327: ZoomLevel Chris@127: ViewManager::getGlobalZoom() const Chris@127: { Chris@127: #ifdef DEBUG_VIEW_MANAGER Chris@682: cerr << "ViewManager::getGlobalZoom: returning " << m_globalZoom << endl; Chris@127: #endif Chris@127: return m_globalZoom; Chris@127: } Chris@127: Chris@902: sv_frame_t Chris@127: ViewManager::getPlaybackFrame() const Chris@127: { Chris@1210: if (isRecording()) { Chris@1210: m_playbackFrame = m_recordTarget->getRecordDuration(); Chris@1210: #ifdef DEBUG_VIEW_MANAGER Chris@1210: cout << "ViewManager::getPlaybackFrame(recording) -> " << m_playbackFrame << endl; Chris@1210: #endif Chris@1210: } else if (isPlaying()) { Chris@1266: m_playbackFrame = m_playSource->getCurrentPlayingFrame(); Chris@1185: #ifdef DEBUG_VIEW_MANAGER Chris@1185: cout << "ViewManager::getPlaybackFrame(playing) -> " << m_playbackFrame << endl; Chris@1185: #endif Chris@1185: } else { Chris@1185: #ifdef DEBUG_VIEW_MANAGER Chris@1185: cout << "ViewManager::getPlaybackFrame(not playing) -> " << m_playbackFrame << endl; Chris@1185: #endif Chris@127: } Chris@127: return m_playbackFrame; Chris@127: } Chris@127: Chris@127: void Chris@902: ViewManager::setPlaybackFrame(sv_frame_t f) Chris@127: { Chris@1185: #ifdef DEBUG_VIEW_MANAGER Chris@1185: cerr << "ViewManager::setPlaybackFrame(" << f << ")" << endl; Chris@1185: #endif Chris@968: if (f < 0) f = 0; Chris@127: if (m_playbackFrame != f) { Chris@1266: m_playbackFrame = f; Chris@1266: emit playbackFrameChanged(f); Chris@1266: if (isPlaying()) { Chris@1266: m_playSource->play(f); Chris@1266: } Chris@127: } Chris@127: } Chris@127: Chris@1479: ModelId Chris@301: ViewManager::getPlaybackModel() const Chris@301: { Chris@301: return m_playbackModel; Chris@301: } Chris@301: Chris@301: void Chris@1479: ViewManager::setPlaybackModel(ModelId model) Chris@301: { Chris@301: m_playbackModel = model; Chris@301: } Chris@301: Chris@902: sv_frame_t Chris@902: ViewManager::alignPlaybackFrameToReference(sv_frame_t frame) const Chris@333: { Chris@830: #ifdef DEBUG_VIEW_MANAGER Chris@830: cerr << "ViewManager::alignPlaybackFrameToReference(" << frame << "): playback model is " << m_playbackModel << endl; Chris@830: #endif Chris@1479: if (m_playbackModel.isNone() || !m_alignMode) { Chris@830: return frame; Chris@830: } else { Chris@1479: auto playbackModel = ModelById::get(m_playbackModel); Chris@1479: if (!playbackModel) { Chris@1479: return frame; Chris@1479: } Chris@1479: sv_frame_t f = playbackModel->alignToReference(frame); Chris@830: #ifdef DEBUG_VIEW_MANAGER Chris@830: cerr << "aligned frame = " << f << endl; Chris@830: #endif Chris@830: return f; Chris@830: } Chris@333: } Chris@333: Chris@902: sv_frame_t Chris@902: ViewManager::alignReferenceToPlaybackFrame(sv_frame_t frame) const Chris@333: { Chris@830: #ifdef DEBUG_VIEW_MANAGER Chris@830: cerr << "ViewManager::alignReferenceToPlaybackFrame(" << frame << "): playback model is " << m_playbackModel << endl; Chris@830: #endif Chris@1479: if (m_playbackModel.isNone() || !m_alignMode) { Chris@830: return frame; Chris@830: } else { Chris@1479: auto playbackModel = ModelById::get(m_playbackModel); Chris@1479: if (!playbackModel) { Chris@1479: return frame; Chris@1479: } Chris@1479: sv_frame_t f = playbackModel->alignFromReference(frame); Chris@830: #ifdef DEBUG_VIEW_MANAGER Chris@830: cerr << "aligned frame = " << f << endl; Chris@830: #endif Chris@830: return f; Chris@830: } Chris@333: } Chris@333: 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@762: ViewManager::addSelectionQuietly(const Selection &selection) Chris@762: { Chris@762: MultiSelection ms(m_selections); Chris@762: ms.addSelection(selection); Chris@762: setSelections(ms, true); Chris@762: } Chris@762: Chris@762: 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@762: ViewManager::setSelections(const MultiSelection &ms, bool quietly) 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@762: if (!quietly) { Chris@762: emit selectionChangedByUser(); Chris@762: } Chris@127: } Chris@127: Chris@902: sv_frame_t Chris@902: ViewManager::constrainFrameToSelection(sv_frame_t frame) const Chris@271: { Chris@271: MultiSelection::SelectionList sl = getSelections(); Chris@271: if (sl.empty()) return frame; Chris@271: Chris@368: for (MultiSelection::SelectionList::const_iterator i = sl.begin(); Chris@368: i != sl.end(); ++i) { Chris@368: Chris@368: if (frame < i->getEndFrame()) { Chris@368: if (frame < i->getStartFrame()) { Chris@368: return i->getStartFrame(); Chris@368: } else { Chris@368: return frame; Chris@368: } Chris@368: } Chris@271: } Chris@271: Chris@368: return sl.begin()->getStartFrame(); Chris@271: } Chris@271: 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@1266: 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@502: if (m_newSelection.getSelections().size() > 1) return tr("Select Multiple Regions"); Chris@502: else return tr("Select Region"); Chris@127: } Chris@127: Chris@127: Selection Chris@902: ViewManager::getContainingSelection(sv_frame_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@502: Chris@502: switch (mode) { Chris@502: case NavigateMode: emit activity(tr("Enter Navigate mode")); break; Chris@502: case SelectMode: emit activity(tr("Enter Select mode")); break; Chris@502: case EditMode: emit activity(tr("Enter Edit mode")); break; Chris@502: case DrawMode: emit activity(tr("Enter Draw mode")); break; Chris@502: case EraseMode: emit activity(tr("Enter Erase mode")); break; Chris@502: case MeasureMode: emit activity(tr("Enter Measure mode")); break; gyorgyf@645: case NoteEditMode: emit activity(tr("Enter NoteEdit mode")); break; // GF: NoteEditMode activity (I'm not yet certain why we need to emit this.) Chris@502: }; Chris@127: } Chris@127: Chris@711: ViewManager::ToolMode Chris@711: ViewManager::getToolModeFor(const View *v) const Chris@711: { Chris@711: if (m_toolModeOverrides.find(v) == m_toolModeOverrides.end()) { Chris@711: return getToolMode(); Chris@711: } else { Chris@711: return m_toolModeOverrides.find(v)->second; Chris@711: } Chris@711: } Chris@711: Chris@711: void Chris@711: ViewManager::setToolModeFor(const View *v, ToolMode mode) Chris@711: { Chris@711: m_toolModeOverrides[v] = mode; Chris@711: } Chris@711: Chris@711: void Chris@711: ViewManager::clearToolModeOverrides() Chris@711: { Chris@711: m_toolModeOverrides.clear(); Chris@711: } Chris@711: 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@502: Chris@502: if (mode) emit activity(tr("Switch on Loop mode")); Chris@502: else emit activity(tr("Switch off Loop 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@502: Chris@502: if (mode) emit activity(tr("Switch on Play Selection mode")); Chris@502: else emit activity(tr("Switch off Play Selection mode")); Chris@177: } Chris@127: } Chris@127: Chris@301: void Chris@301: ViewManager::setPlaySoloMode(bool mode) Chris@301: { Chris@301: if (m_playSoloMode != mode) { Chris@301: Chris@301: m_playSoloMode = mode; Chris@301: Chris@301: emit playSoloModeChanged(); Chris@301: emit playSoloModeChanged(mode); Chris@502: Chris@502: if (mode) emit activity(tr("Switch on Play Solo mode")); Chris@502: else emit activity(tr("Switch off Play Solo mode")); Chris@301: } Chris@301: } Chris@301: Chris@314: void Chris@314: ViewManager::setAlignMode(bool mode) Chris@314: { Chris@314: if (m_alignMode != mode) { Chris@314: Chris@314: m_alignMode = mode; Chris@314: Chris@314: emit alignModeChanged(); Chris@314: emit alignModeChanged(mode); Chris@502: Chris@502: if (mode) emit activity(tr("Switch on Alignment mode")); Chris@502: else emit activity(tr("Switch off Alignment mode")); Chris@314: } Chris@314: } Chris@314: Chris@902: sv_samplerate_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@902: sv_samplerate_t Chris@1181: ViewManager::getDeviceSampleRate() const Chris@127: { Chris@127: if (m_playSource) { Chris@1266: return m_playSource->getDeviceSampleRate(); 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@1266: QTimer::singleShot(100, this, SLOT(checkPlayStatus())); Chris@127: } Chris@127: m_playSource = source; Chris@127: } Chris@127: Chris@127: void Chris@1210: ViewManager::setAudioRecordTarget(AudioRecordTarget *target) Chris@1210: { Chris@1210: if (!m_recordTarget) { Chris@1266: QTimer::singleShot(100, this, SLOT(checkPlayStatus())); Chris@1210: } Chris@1210: m_recordTarget = target; Chris@1210: } Chris@1210: Chris@1210: void Chris@248: ViewManager::playStatusChanged(bool /* playing */) Chris@127: { Chris@689: #ifdef DEBUG_VIEW_MANAGER Chris@689: cerr << "ViewManager::playStatusChanged" << endl; Chris@689: #endif Chris@127: checkPlayStatus(); Chris@127: } Chris@127: Chris@127: void Chris@1210: ViewManager::recordStatusChanged(bool /* recording */) Chris@1210: { Chris@1210: #ifdef DEBUG_VIEW_MANAGER Chris@1210: cerr << "ViewManager::recordStatusChanged" << endl; Chris@1210: #endif Chris@1210: checkPlayStatus(); Chris@1210: } Chris@1210: Chris@1210: void Chris@127: ViewManager::checkPlayStatus() Chris@127: { Chris@1210: if (isRecording()) { Chris@1210: Chris@1266: float left = 0, right = 0; Chris@1266: if (m_recordTarget->getInputLevels(left, right)) { Chris@1266: if (left != m_lastLeft || right != m_lastRight) { Chris@1266: emit monitoringLevelsChanged(left, right); Chris@1266: m_lastLeft = left; Chris@1266: m_lastRight = right; Chris@1266: } Chris@1266: } Chris@1210: Chris@1266: m_playbackFrame = m_recordTarget->getRecordDuration(); Chris@1210: Chris@1210: #ifdef DEBUG_VIEW_MANAGER Chris@1266: cerr << "ViewManager::checkPlayStatus: Recording, frame " << m_playbackFrame << ", levels " << m_lastLeft << "," << m_lastRight << endl; Chris@1210: #endif Chris@1210: Chris@1266: emit playbackFrameChanged(m_playbackFrame); Chris@1210: Chris@1266: QTimer::singleShot(500, this, SLOT(checkPlayStatus())); Chris@1210: Chris@1210: } else if (isPlaying()) { Chris@127: Chris@1266: float left = 0, right = 0; Chris@1266: if (m_playSource->getOutputLevels(left, right)) { Chris@1266: if (left != m_lastLeft || right != m_lastRight) { Chris@1266: emit monitoringLevelsChanged(left, right); Chris@1266: m_lastLeft = left; Chris@1266: m_lastRight = right; Chris@1266: } Chris@1266: } Chris@127: Chris@1266: m_playbackFrame = m_playSource->getCurrentPlayingFrame(); Chris@127: Chris@127: #ifdef DEBUG_VIEW_MANAGER Chris@1266: cerr << "ViewManager::checkPlayStatus: Playing, frame " << m_playbackFrame << ", levels " << m_lastLeft << "," << m_lastRight << endl; Chris@127: #endif Chris@127: Chris@1266: emit playbackFrameChanged(m_playbackFrame); Chris@127: Chris@1266: QTimer::singleShot(20, this, SLOT(checkPlayStatus())); Chris@127: Chris@127: } else { Chris@127: Chris@1266: if (m_lastLeft != 0.0 || m_lastRight != 0.0) { Chris@1266: emit monitoringLevelsChanged(0.0, 0.0); Chris@1266: m_lastLeft = 0.0; Chris@1266: m_lastRight = 0.0; Chris@1266: } Chris@127: Chris@127: #ifdef DEBUG_VIEW_MANAGER Chris@1266: cerr << "ViewManager::checkPlayStatus: Not playing or recording" << 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@1210: bool Chris@1210: ViewManager::isRecording() const Chris@1210: { Chris@1210: return m_recordTarget && m_recordTarget->isRecording(); Chris@1210: } Chris@1210: Chris@127: void Chris@902: ViewManager::viewCentreFrameChanged(sv_frame_t f, bool locked, Chris@211: PlaybackFollowMode mode) Chris@127: { Chris@211: View *v = dynamic_cast(sender()); Chris@211: Chris@398: #ifdef DEBUG_VIEW_MANAGER Chris@682: cerr << "ViewManager::viewCentreFrameChanged(" << f << ", " << locked << ", " << mode << "), view is " << v << endl; Chris@398: #endif Chris@394: 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@815: if (!dynamic_cast(v) || (mode != PlaybackIgnore)) { Chris@527: if (m_mainModelSampleRate != 0) { Chris@527: emit activity(tr("Scroll to %1") Chris@527: .arg(RealTime::frame2RealTime Chris@527: (f, m_mainModelSampleRate).toText().c_str())); Chris@527: } Chris@503: } Chris@502: Chris@815: if (mode == PlaybackScrollPageWithCentre || Chris@815: mode == PlaybackScrollContinuous) { Chris@815: seek(f); Chris@211: } Chris@211: } Chris@211: Chris@211: void Chris@902: ViewManager::seek(sv_frame_t f) Chris@211: { Chris@127: #ifdef DEBUG_VIEW_MANAGER Chris@682: cerr << "ViewManager::seek(" << f << ")" << endl; Chris@127: #endif Chris@127: Chris@1210: if (isRecording()) { Chris@1210: // ignore Chris@1210: #ifdef DEBUG_VIEW_MANAGER Chris@1210: cerr << "ViewManager::seek: Ignoring during recording" << endl; Chris@1210: #endif Chris@1210: return; Chris@1210: } Chris@1210: Chris@1210: if (isPlaying()) { Chris@1266: sv_frame_t playFrame = m_playSource->getCurrentPlayingFrame(); Chris@1266: sv_frame_t diff = std::max(f, playFrame) - std::min(f, playFrame); Chris@1266: if (diff > 20000) { Chris@1266: m_playbackFrame = f; Chris@1266: m_playSource->play(f); Chris@127: #ifdef DEBUG_VIEW_MANAGER Chris@1266: cerr << "ViewManager::seek: reseeking from " << playFrame << " to " << f << endl; Chris@127: #endif Chris@211: emit playbackFrameChanged(f); Chris@1266: } 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@1327: ViewManager::viewZoomLevelChanged(ZoomLevel z, bool locked) Chris@127: { Chris@222: View *v = dynamic_cast(sender()); Chris@222: Chris@222: if (!v) { Chris@587: SVDEBUG << "ViewManager::viewZoomLevelChanged: WARNING: sender is not a view" << endl; Chris@222: return; Chris@222: } Chris@222: Chris@222: //!!! emit zoomLevelChanged(); Chris@133: Chris@127: if (locked) { Chris@1266: m_globalZoom = z; Chris@127: } Chris@127: Chris@127: #ifdef DEBUG_VIEW_MANAGER Chris@682: cerr << "ViewManager::viewZoomLevelChanged(" << v << ", " << z << ", " << locked << ")" << endl; Chris@127: #endif Chris@222: Chris@222: emit viewZoomLevelChanged(v, z, locked); Chris@503: Chris@503: if (!dynamic_cast(v)) { Chris@1327: if (z.zone == ZoomLevel::FramesPerPixel) { Chris@1327: emit activity(tr("Zoom to %n sample(s) per pixel", "", z.level)); Chris@1327: } else { Chris@1327: emit activity(tr("Zoom to %n pixels per sample", "", z.level)); Chris@1327: } Chris@503: } 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@502: emit activity(tr("Change overlay level")); 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@502: if (enabled) emit activity("Show zoom wheels"); Chris@502: else emit activity("Hide zoom wheels"); 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: Chris@292: void Chris@1468: ViewManager::setOpportunisticEditingEnabled(bool enabled) Chris@1468: { Chris@1468: if (m_opportunisticEditingEnabled != enabled) { Chris@1468: m_opportunisticEditingEnabled = enabled; Chris@1468: emit opportunisticEditingEnabledChanged(); Chris@1468: } Chris@1468: } Chris@1468: Chris@1468: void Chris@607: ViewManager::setShowCentreLine(bool show) Chris@607: { Chris@607: if (m_showCentreLine != show) { Chris@607: m_showCentreLine = show; Chris@607: emit showCentreLineChanged(); Chris@607: if (show) emit activity("Show centre line"); Chris@607: else emit activity("Hide centre line"); Chris@607: } Chris@607: Chris@607: QSettings settings; Chris@607: settings.beginGroup("MainWindow"); Chris@607: settings.setValue("show-centre-line", int(m_showCentreLine)); Chris@607: settings.endGroup(); Chris@607: } Chris@607: Chris@607: void Chris@292: ViewManager::setGlobalDarkBackground(bool dark) Chris@292: { Chris@292: // also save the current palette, in case the user has changed it Chris@292: // since construction Chris@292: if (getGlobalDarkBackground()) { Chris@292: m_darkPalette = QApplication::palette(); Chris@292: } else { Chris@292: m_lightPalette = QApplication::palette(); Chris@292: } Chris@292: Chris@1574: #ifdef Q_OS_MAC Chris@1574: return; Chris@1574: #endif Chris@1574: Chris@292: if (dark) { Chris@1574: Chris@1574: #ifdef Q_OS_WIN32 Chris@1575: // The Windows Vista style doesn't use the palette for many of Chris@1575: // its controls. They can be styled with stylesheets, but that Chris@1575: // takes a lot of fiddly and fragile custom bits. Easier and Chris@1575: // more reliable to switch to a non-Vista style which does use Chris@1575: // the palette. Chris@1574: Chris@1575: QStyle *plainWindowsStyle = QStyleFactory::create("windows"); Chris@1575: if (!plainWindowsStyle) { Chris@1575: SVCERR << "Failed to load plain Windows style" << endl; Chris@1575: } else { Chris@1575: qApp->setStyle(plainWindowsStyle); Chris@1574: } Chris@1574: #endif Chris@1574: Chris@292: QApplication::setPalette(m_darkPalette); Chris@1574: Chris@292: } else { Chris@1574: Chris@1574: #ifdef Q_OS_WIN32 Chris@1575: // Switch back to Vista style Chris@1575: Chris@1575: QStyle *fancyWindowsStyle = QStyleFactory::create("windowsvista"); Chris@1575: if (!fancyWindowsStyle) { Chris@1575: SVCERR << "Failed to load fancy Windows style" << endl; Chris@1575: } else { Chris@1575: qApp->setStyle(fancyWindowsStyle); Chris@1575: } Chris@1574: #endif Chris@1574: Chris@292: QApplication::setPalette(m_lightPalette); Chris@292: } Chris@292: } Chris@292: Chris@292: bool Chris@292: ViewManager::getGlobalDarkBackground() const Chris@292: { Chris@292: bool dark = false; Chris@292: QColor windowBg = QApplication::palette().color(QPalette::Window); Chris@292: if (windowBg.red() + windowBg.green() + windowBg.blue() < 384) { Chris@292: dark = true; Chris@292: } Chris@292: return dark; Chris@292: } Chris@292: Chris@894: int Chris@894: ViewManager::scalePixelSize(int pixels) Chris@894: { Chris@908: static double ratio = 0.0; Chris@908: if (ratio == 0.0) { Chris@908: double baseEm; Chris@894: #ifdef Q_OS_MAC Chris@908: baseEm = 17.0; Chris@894: #else Chris@908: baseEm = 15.0; Chris@894: #endif Chris@908: double em = QFontMetrics(QFont()).height(); Chris@894: ratio = em / baseEm; Chris@1224: Chris@1224: SVDEBUG << "ViewManager::scalePixelSize: ratio is " << ratio Chris@1224: << " (em = " << em << ")" << endl; Chris@894: } Chris@894: Chris@894: int scaled = int(pixels * ratio + 0.5); Chris@1273: // SVDEBUG << "scaledSize: " << pixels << " -> " << scaled << " at ratio " << ratio << endl; Chris@894: if (pixels != 0 && scaled == 0) scaled = 1; Chris@894: return scaled; Chris@894: } Chris@946: