ViewManager.cpp

Go to the documentation of this file.
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
00002 
00003 /*
00004     Sonic Visualiser
00005     An audio file viewer and annotation editor.
00006     Centre for Digital Music, Queen Mary, University of London.
00007     This file copyright 2006 Chris Cannam and QMUL.
00008     
00009     This program is free software; you can redistribute it and/or
00010     modify it under the terms of the GNU General Public License as
00011     published by the Free Software Foundation; either version 2 of the
00012     License, or (at your option) any later version.  See the file
00013     COPYING included with this distribution for more information.
00014 */
00015 
00016 #include "ViewManager.h"
00017 #include "base/AudioPlaySource.h"
00018 #include "data/model/Model.h"
00019 #include "base/CommandHistory.h"
00020 #include "View.h"
00021 
00022 #include <QSettings>
00023 #include <QApplication>
00024 
00025 #include <iostream>
00026 
00027 //#define DEBUG_VIEW_MANAGER 1
00028 
00029 ViewManager::ViewManager() :
00030     m_playSource(0),
00031     m_globalCentreFrame(0),
00032     m_globalZoom(1024),
00033     m_playbackFrame(0),
00034     m_playbackModel(0),
00035     m_mainModelSampleRate(0),
00036     m_lastLeft(0), 
00037     m_lastRight(0),
00038     m_inProgressExclusive(true),
00039     m_toolMode(NavigateMode),
00040     m_playLoopMode(false),
00041     m_playSelectionMode(false),
00042     m_playSoloMode(false),
00043     m_alignMode(false),
00044     m_overlayMode(StandardOverlays),
00045     m_zoomWheelsEnabled(true),
00046     m_illuminateLocalFeatures(true),
00047     m_showWorkTitle(false),
00048     m_lightPalette(QApplication::palette()),
00049     m_darkPalette(QApplication::palette())
00050 {
00051     QSettings settings;
00052     settings.beginGroup("MainWindow");
00053     m_overlayMode = OverlayMode
00054         (settings.value("overlay-mode", int(m_overlayMode)).toInt());
00055     m_zoomWheelsEnabled =
00056         settings.value("zoom-wheels-enabled", m_zoomWheelsEnabled).toBool();
00057     settings.endGroup();
00058 
00059     if (getGlobalDarkBackground()) {
00060 /*
00061         std::cerr << "dark palette:" << std::endl;
00062         std::cerr << "window = " << QApplication::palette().color(QPalette::Window).name().toStdString() << std::endl;
00063         std::cerr << "windowtext = " << QApplication::palette().color(QPalette::WindowText).name().toStdString() << std::endl;
00064         std::cerr << "base = " << QApplication::palette().color(QPalette::Base).name().toStdString() << std::endl;
00065         std::cerr << "alternatebase = " << QApplication::palette().color(QPalette::AlternateBase).name().toStdString() << std::endl;
00066         std::cerr << "text = " << QApplication::palette().color(QPalette::Text).name().toStdString() << std::endl;
00067         std::cerr << "button = " << QApplication::palette().color(QPalette::Button).name().toStdString() << std::endl;
00068         std::cerr << "buttontext = " << QApplication::palette().color(QPalette::ButtonText).name().toStdString() << std::endl;
00069         std::cerr << "brighttext = " << QApplication::palette().color(QPalette::BrightText).name().toStdString() << std::endl;
00070         std::cerr << "light = " << QApplication::palette().color(QPalette::Light).name().toStdString() << std::endl;
00071         std::cerr << "dark = " << QApplication::palette().color(QPalette::Dark).name().toStdString() << std::endl;
00072         std::cerr << "mid = " << QApplication::palette().color(QPalette::Mid).name().toStdString() << std::endl;
00073 */
00074         m_lightPalette = QPalette(QColor("#000000"),  // WindowText
00075                                   QColor("#dddfe4"),  // Button
00076                                   QColor("#ffffff"),  // Light
00077                                   QColor("#555555"),  // Dark
00078                                   QColor("#c7c7c7"),  // Mid
00079                                   QColor("#000000"),  // Text
00080                                   QColor("#ffffff"),  // BrightText
00081                                   QColor("#ffffff"),  // Base
00082                                   QColor("#efefef")); // Window
00083                                   
00084 
00085     } else {
00086 /*
00087         std::cerr << "light palette:" << std::endl;
00088         std::cerr << "window = " << QApplication::palette().color(QPalette::Window).name().toStdString() << std::endl;
00089         std::cerr << "windowtext = " << QApplication::palette().color(QPalette::WindowText).name().toStdString() << std::endl;
00090         std::cerr << "base = " << QApplication::palette().color(QPalette::Base).name().toStdString() << std::endl;
00091         std::cerr << "alternatebase = " << QApplication::palette().color(QPalette::AlternateBase).name().toStdString() << std::endl;
00092         std::cerr << "text = " << QApplication::palette().color(QPalette::Text).name().toStdString() << std::endl;
00093         std::cerr << "button = " << QApplication::palette().color(QPalette::Button).name().toStdString() << std::endl;
00094         std::cerr << "buttontext = " << QApplication::palette().color(QPalette::ButtonText).name().toStdString() << std::endl;
00095         std::cerr << "brighttext = " << QApplication::palette().color(QPalette::BrightText).name().toStdString() << std::endl;
00096         std::cerr << "light = " << QApplication::palette().color(QPalette::Light).name().toStdString() << std::endl;
00097         std::cerr << "dark = " << QApplication::palette().color(QPalette::Dark).name().toStdString() << std::endl;
00098         std::cerr << "mid = " << QApplication::palette().color(QPalette::Mid).name().toStdString() << std::endl;
00099 */
00100         m_darkPalette = QPalette(QColor("#ffffff"),  // WindowText
00101                                  QColor("#3e3e3e"),  // Button
00102                                  QColor("#808080"),  // Light
00103                                  QColor("#1e1e1e"),  // Dark
00104                                  QColor("#404040"),  // Mid
00105                                  QColor("#ffffff"),  // Text
00106                                  QColor("#ffffff"),  // BrightText
00107                                  QColor("#000000"),  // Base
00108                                  QColor("#202020")); // Window
00109     }
00110 }
00111 
00112 ViewManager::~ViewManager()
00113 {
00114 }
00115 
00116 unsigned long
00117 ViewManager::getGlobalCentreFrame() const
00118 {
00119 #ifdef DEBUG_VIEW_MANAGER
00120     std::cout << "ViewManager::getGlobalCentreFrame: returning " << m_globalCentreFrame << std::endl;
00121 #endif
00122     return m_globalCentreFrame;
00123 }
00124 
00125 void
00126 ViewManager::setGlobalCentreFrame(unsigned long f)
00127 {
00128 #ifdef DEBUG_VIEW_MANAGER
00129     std::cout << "ViewManager::setGlobalCentreFrame to " << f << std::endl;
00130 #endif
00131     m_globalCentreFrame = f;
00132     emit globalCentreFrameChanged(f);
00133 }
00134 
00135 unsigned long
00136 ViewManager::getGlobalZoom() const
00137 {
00138 #ifdef DEBUG_VIEW_MANAGER
00139     std::cout << "ViewManager::getGlobalZoom: returning " << m_globalZoom << std::endl;
00140 #endif
00141     return m_globalZoom;
00142 }
00143 
00144 unsigned long
00145 ViewManager::getPlaybackFrame() const
00146 {
00147     if (m_playSource && m_playSource->isPlaying()) {
00148         m_playbackFrame = m_playSource->getCurrentPlayingFrame();
00149     }
00150     return m_playbackFrame;
00151 }
00152 
00153 void
00154 ViewManager::setPlaybackFrame(unsigned long f)
00155 {
00156     if (m_playbackFrame != f) {
00157         m_playbackFrame = f;
00158         emit playbackFrameChanged(f);
00159         if (m_playSource && m_playSource->isPlaying()) {
00160             m_playSource->play(f);
00161         }
00162     }
00163 }
00164 
00165 Model *
00166 ViewManager::getPlaybackModel() const
00167 {
00168     return m_playbackModel;
00169 }
00170 
00171 void
00172 ViewManager::setPlaybackModel(Model *model)
00173 {
00174     m_playbackModel = model;
00175 }
00176 
00177 size_t
00178 ViewManager::alignPlaybackFrameToReference(size_t frame) const
00179 {
00180     if (!m_playbackModel) return frame;
00181     else return m_playbackModel->alignToReference(frame);
00182 }
00183 
00184 size_t
00185 ViewManager::alignReferenceToPlaybackFrame(size_t frame) const
00186 {
00187     if (!m_playbackModel) return frame;
00188     else return m_playbackModel->alignFromReference(frame);
00189 }
00190 
00191 bool
00192 ViewManager::haveInProgressSelection() const
00193 {
00194     return !m_inProgressSelection.isEmpty();
00195 }
00196 
00197 const Selection &
00198 ViewManager::getInProgressSelection(bool &exclusive) const
00199 {
00200     exclusive = m_inProgressExclusive;
00201     return m_inProgressSelection;
00202 }
00203 
00204 void
00205 ViewManager::setInProgressSelection(const Selection &selection, bool exclusive)
00206 {
00207     m_inProgressExclusive = exclusive;
00208     m_inProgressSelection = selection;
00209     if (exclusive) clearSelections();
00210     emit inProgressSelectionChanged();
00211 }
00212 
00213 void
00214 ViewManager::clearInProgressSelection()
00215 {
00216     m_inProgressSelection = Selection();
00217     emit inProgressSelectionChanged();
00218 }
00219 
00220 const MultiSelection &
00221 ViewManager::getSelection() const
00222 {
00223     return m_selections;
00224 }
00225 
00226 const MultiSelection::SelectionList &
00227 ViewManager::getSelections() const
00228 {
00229     return m_selections.getSelections();
00230 }
00231 
00232 void
00233 ViewManager::setSelection(const Selection &selection)
00234 {
00235     MultiSelection ms(m_selections);
00236     ms.setSelection(selection);
00237     setSelections(ms);
00238 }
00239 
00240 void
00241 ViewManager::addSelection(const Selection &selection)
00242 {
00243     MultiSelection ms(m_selections);
00244     ms.addSelection(selection);
00245     setSelections(ms);
00246 }
00247 
00248 void
00249 ViewManager::removeSelection(const Selection &selection)
00250 {
00251     MultiSelection ms(m_selections);
00252     ms.removeSelection(selection);
00253     setSelections(ms);
00254 }
00255 
00256 void
00257 ViewManager::clearSelections()
00258 {
00259     MultiSelection ms(m_selections);
00260     ms.clearSelections();
00261     setSelections(ms);
00262 }
00263 
00264 void
00265 ViewManager::setSelections(const MultiSelection &ms)
00266 {
00267     if (m_selections.getSelections() == ms.getSelections()) return;
00268     SetSelectionCommand *command = new SetSelectionCommand(this, ms);
00269     CommandHistory::getInstance()->addCommand(command);
00270 }
00271 
00272 size_t
00273 ViewManager::constrainFrameToSelection(size_t frame) const
00274 {
00275     MultiSelection::SelectionList sl = getSelections();
00276     if (sl.empty()) return frame;
00277 
00278     for (MultiSelection::SelectionList::const_iterator i = sl.begin();
00279          i != sl.end(); ++i) {
00280 
00281         if (frame < i->getEndFrame()) {
00282             if (frame < i->getStartFrame()) {
00283                 return i->getStartFrame();
00284             } else {
00285                 return frame;
00286             }
00287         }
00288     }
00289 
00290     return sl.begin()->getStartFrame();
00291 }
00292 
00293 void
00294 ViewManager::signalSelectionChange()
00295 {
00296     emit selectionChanged();
00297 }
00298 
00299 ViewManager::SetSelectionCommand::SetSelectionCommand(ViewManager *vm,
00300                                                       const MultiSelection &ms) :
00301     m_vm(vm),
00302     m_oldSelection(vm->m_selections),
00303     m_newSelection(ms)
00304 {
00305 }
00306 
00307 ViewManager::SetSelectionCommand::~SetSelectionCommand() { }
00308 
00309 void
00310 ViewManager::SetSelectionCommand::execute()
00311 {
00312     m_vm->m_selections = m_newSelection;
00313     m_vm->signalSelectionChange();
00314 }
00315 
00316 void
00317 ViewManager::SetSelectionCommand::unexecute()
00318 {
00319     m_vm->m_selections = m_oldSelection;
00320     m_vm->signalSelectionChange();
00321 }
00322 
00323 QString
00324 ViewManager::SetSelectionCommand::getName() const
00325 {
00326     if (m_newSelection.getSelections().empty()) return tr("Clear Selection");
00327     else return tr("Select");
00328 }
00329 
00330 Selection
00331 ViewManager::getContainingSelection(size_t frame, bool defaultToFollowing) const
00332 {
00333     return m_selections.getContainingSelection(frame, defaultToFollowing);
00334 }
00335 
00336 void
00337 ViewManager::setToolMode(ToolMode mode)
00338 {
00339     m_toolMode = mode;
00340 
00341     emit toolModeChanged();
00342 }
00343 
00344 void
00345 ViewManager::setPlayLoopMode(bool mode)
00346 {
00347     if (m_playLoopMode != mode) {
00348 
00349         m_playLoopMode = mode;
00350 
00351         emit playLoopModeChanged();
00352         emit playLoopModeChanged(mode);
00353     }
00354 }
00355 
00356 void
00357 ViewManager::setPlaySelectionMode(bool mode)
00358 {
00359     if (m_playSelectionMode != mode) {
00360 
00361         m_playSelectionMode = mode;
00362 
00363         emit playSelectionModeChanged();
00364         emit playSelectionModeChanged(mode);
00365     }
00366 }
00367 
00368 void
00369 ViewManager::setPlaySoloMode(bool mode)
00370 {
00371     if (m_playSoloMode != mode) {
00372 
00373         m_playSoloMode = mode;
00374 
00375         emit playSoloModeChanged();
00376         emit playSoloModeChanged(mode);
00377     }
00378 }
00379 
00380 void
00381 ViewManager::setAlignMode(bool mode)
00382 {
00383     if (m_alignMode != mode) {
00384 
00385         m_alignMode = mode;
00386 
00387         emit alignModeChanged();
00388         emit alignModeChanged(mode);
00389     }
00390 }
00391 
00392 size_t 
00393 ViewManager::getPlaybackSampleRate() const
00394 {
00395     if (m_playSource) {
00396         return m_playSource->getSourceSampleRate();
00397     }
00398     return 0;
00399 }
00400 
00401 size_t
00402 ViewManager::getOutputSampleRate() const
00403 {
00404     if (m_playSource) {
00405         return m_playSource->getTargetSampleRate();
00406     }
00407     return 0;
00408 }
00409 
00410 void
00411 ViewManager::setAudioPlaySource(AudioPlaySource *source)
00412 {
00413     if (!m_playSource) {
00414         QTimer::singleShot(100, this, SLOT(checkPlayStatus()));
00415     }
00416     m_playSource = source;
00417 }
00418 
00419 void
00420 ViewManager::playStatusChanged(bool /* playing */)
00421 {
00422     checkPlayStatus();
00423 }
00424 
00425 void
00426 ViewManager::checkPlayStatus()
00427 {
00428     if (m_playSource && m_playSource->isPlaying()) {
00429 
00430         float left = 0, right = 0;
00431         if (m_playSource->getOutputLevels(left, right)) {
00432             if (left != m_lastLeft || right != m_lastRight) {
00433                 emit outputLevelsChanged(left, right);
00434                 m_lastLeft = left;
00435                 m_lastRight = right;
00436             }
00437         }
00438 
00439         m_playbackFrame = m_playSource->getCurrentPlayingFrame();
00440 
00441 #ifdef DEBUG_VIEW_MANAGER
00442         std::cout << "ViewManager::checkPlayStatus: Playing, frame " << m_playbackFrame << ", levels " << m_lastLeft << "," << m_lastRight << std::endl;
00443 #endif
00444 
00445         emit playbackFrameChanged(m_playbackFrame);
00446 
00447         QTimer::singleShot(20, this, SLOT(checkPlayStatus()));
00448 
00449     } else {
00450 
00451         QTimer::singleShot(100, this, SLOT(checkPlayStatus()));
00452         
00453         if (m_lastLeft != 0.0 || m_lastRight != 0.0) {
00454             emit outputLevelsChanged(0.0, 0.0);
00455             m_lastLeft = 0.0;
00456             m_lastRight = 0.0;
00457         }
00458 
00459 #ifdef DEBUG_VIEW_MANAGER
00460 //      std::cout << "ViewManager::checkPlayStatus: Not playing" << std::endl;
00461 #endif
00462     }
00463 }
00464 
00465 bool
00466 ViewManager::isPlaying() const
00467 {
00468     return m_playSource && m_playSource->isPlaying();
00469 }
00470 
00471 void
00472 ViewManager::viewCentreFrameChanged(unsigned long f, bool locked,
00473                                     PlaybackFollowMode mode)
00474 {
00475     View *v = dynamic_cast<View *>(sender());
00476 
00477     if (locked) {
00478         m_globalCentreFrame = f;
00479         emit globalCentreFrameChanged(f);
00480     } else {
00481         if (v) emit viewCentreFrameChanged(v, f);
00482     }
00483 
00484     if (mode == PlaybackIgnore) {
00485         return;
00486     }
00487 
00488     seek(f);
00489 }
00490 
00491 void
00492 ViewManager::seek(unsigned long f)
00493 {
00494 #ifdef DEBUG_VIEW_MANAGER 
00495     std::cout << "ViewManager::seek(" << f << ")" << std::endl;
00496 #endif
00497 
00498     if (m_playSource && m_playSource->isPlaying()) {
00499         unsigned long playFrame = m_playSource->getCurrentPlayingFrame();
00500         unsigned long diff = std::max(f, playFrame) - std::min(f, playFrame);
00501         if (diff > 20000) {
00502             m_playbackFrame = f;
00503             m_playSource->play(f);
00504 #ifdef DEBUG_VIEW_MANAGER 
00505             std::cout << "ViewManager::considerSeek: reseeking from " << playFrame << " to " << f << std::endl;
00506 #endif
00507             emit playbackFrameChanged(f);
00508         }
00509     } else {
00510         if (m_playbackFrame != f) {
00511             m_playbackFrame = f;
00512             emit playbackFrameChanged(f);
00513         }
00514     }
00515 }
00516 
00517 void
00518 ViewManager::viewZoomLevelChanged(unsigned long z, bool locked)
00519 {
00520     View *v = dynamic_cast<View *>(sender());
00521 
00522     if (!v) {
00523         std::cerr << "ViewManager::viewZoomLevelChanged: WARNING: sender is not a view" << std::endl;
00524         return;
00525     }
00526 
00528     
00529     if (locked) {
00530         m_globalZoom = z;
00531     }
00532 
00533 #ifdef DEBUG_VIEW_MANAGER 
00534     std::cout << "ViewManager::viewZoomLevelChanged(" << v << ", " << z << ", " << locked << ")" << std::endl;
00535 #endif
00536 
00537     emit viewZoomLevelChanged(v, z, locked);
00538 }
00539 
00540 void
00541 ViewManager::setOverlayMode(OverlayMode mode)
00542 {
00543     if (m_overlayMode != mode) {
00544         m_overlayMode = mode;
00545         emit overlayModeChanged();
00546     }
00547 
00548     QSettings settings;
00549     settings.beginGroup("MainWindow");
00550     settings.setValue("overlay-mode", int(m_overlayMode));
00551     settings.endGroup();
00552 }
00553 
00554 void
00555 ViewManager::setZoomWheelsEnabled(bool enabled)
00556 {
00557     if (m_zoomWheelsEnabled != enabled) {
00558         m_zoomWheelsEnabled = enabled;
00559         emit zoomWheelsEnabledChanged();
00560     }
00561 
00562     QSettings settings;
00563     settings.beginGroup("MainWindow");
00564     settings.setValue("zoom-wheels-enabled", m_zoomWheelsEnabled);
00565     settings.endGroup();
00566 }
00567 
00568 void
00569 ViewManager::setGlobalDarkBackground(bool dark)
00570 {
00571     // also save the current palette, in case the user has changed it
00572     // since construction
00573     if (getGlobalDarkBackground()) {
00574         m_darkPalette = QApplication::palette();
00575     } else {
00576         m_lightPalette = QApplication::palette();
00577     }
00578 
00579     if (dark) {
00580         QApplication::setPalette(m_darkPalette);
00581     } else {
00582         QApplication::setPalette(m_lightPalette);
00583     }
00584 }
00585 
00586 bool
00587 ViewManager::getGlobalDarkBackground() const
00588 {
00589     bool dark = false;
00590     QColor windowBg = QApplication::palette().color(QPalette::Window);
00591     if (windowBg.red() + windowBg.green() + windowBg.blue() < 384) {
00592         dark = true;
00593     }
00594     return dark;
00595 }
00596 

Generated on Wed Feb 20 15:45:30 2008 for SonicVisualiser by  doxygen 1.5.1