| Chris@127 | 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */ | 
| Chris@127 | 2 | 
| Chris@127 | 3 /* | 
| Chris@127 | 4     Sonic Visualiser | 
| Chris@127 | 5     An audio file viewer and annotation editor. | 
| Chris@127 | 6     Centre for Digital Music, Queen Mary, University of London. | 
| Chris@182 | 7     This file copyright 2006 Chris Cannam and QMUL. | 
| Chris@127 | 8 | 
| Chris@127 | 9     This program is free software; you can redistribute it and/or | 
| Chris@127 | 10     modify it under the terms of the GNU General Public License as | 
| Chris@127 | 11     published by the Free Software Foundation; either version 2 of the | 
| Chris@127 | 12     License, or (at your option) any later version.  See the file | 
| Chris@127 | 13     COPYING included with this distribution for more information. | 
| Chris@127 | 14 */ | 
| Chris@127 | 15 | 
| Chris@127 | 16 #include "ViewManager.h" | 
| Chris@128 | 17 #include "base/AudioPlaySource.h" | 
| Chris@128 | 18 #include "data/model/Model.h" | 
| Chris@128 | 19 #include "base/CommandHistory.h" | 
| Chris@211 | 20 #include "View.h" | 
| Chris@127 | 21 | 
| Chris@133 | 22 #include <QSettings> | 
| Chris@292 | 23 #include <QApplication> | 
| Chris@133 | 24 | 
| Chris@127 | 25 #include <iostream> | 
| Chris@127 | 26 | 
| Chris@363 | 27 //#define DEBUG_VIEW_MANAGER 1 | 
| Chris@127 | 28 | 
| Chris@127 | 29 ViewManager::ViewManager() : | 
| Chris@127 | 30     m_playSource(0), | 
| Chris@127 | 31     m_globalCentreFrame(0), | 
| Chris@127 | 32     m_globalZoom(1024), | 
| Chris@127 | 33     m_playbackFrame(0), | 
| Chris@301 | 34     m_playbackModel(0), | 
| Chris@127 | 35     m_mainModelSampleRate(0), | 
| Chris@127 | 36     m_lastLeft(0), | 
| Chris@127 | 37     m_lastRight(0), | 
| Chris@127 | 38     m_inProgressExclusive(true), | 
| Chris@127 | 39     m_toolMode(NavigateMode), | 
| Chris@127 | 40     m_playLoopMode(false), | 
| Chris@127 | 41     m_playSelectionMode(false), | 
| Chris@301 | 42     m_playSoloMode(false), | 
| Chris@314 | 43     m_alignMode(false), | 
| Chris@189 | 44     m_overlayMode(StandardOverlays), | 
| Chris@292 | 45     m_zoomWheelsEnabled(true), | 
| Chris@326 | 46     m_illuminateLocalFeatures(true), | 
| Chris@326 | 47     m_showWorkTitle(false), | 
| Chris@292 | 48     m_lightPalette(QApplication::palette()), | 
| Chris@292 | 49     m_darkPalette(QApplication::palette()) | 
| Chris@127 | 50 { | 
| Chris@133 | 51     QSettings settings; | 
| Chris@133 | 52     settings.beginGroup("MainWindow"); | 
| Chris@133 | 53     m_overlayMode = OverlayMode | 
| Chris@133 | 54         (settings.value("overlay-mode", int(m_overlayMode)).toInt()); | 
| Chris@133 | 55     m_zoomWheelsEnabled = | 
| Chris@133 | 56         settings.value("zoom-wheels-enabled", m_zoomWheelsEnabled).toBool(); | 
| Chris@133 | 57     settings.endGroup(); | 
| Chris@292 | 58 | 
| Chris@292 | 59     if (getGlobalDarkBackground()) { | 
| Chris@343 | 60 /* | 
| Chris@293 | 61         std::cerr << "dark palette:" << std::endl; | 
| Chris@293 | 62         std::cerr << "window = " << QApplication::palette().color(QPalette::Window).name().toStdString() << std::endl; | 
| Chris@293 | 63         std::cerr << "windowtext = " << QApplication::palette().color(QPalette::WindowText).name().toStdString() << std::endl; | 
| Chris@293 | 64         std::cerr << "base = " << QApplication::palette().color(QPalette::Base).name().toStdString() << std::endl; | 
| Chris@293 | 65         std::cerr << "alternatebase = " << QApplication::palette().color(QPalette::AlternateBase).name().toStdString() << std::endl; | 
| Chris@293 | 66         std::cerr << "text = " << QApplication::palette().color(QPalette::Text).name().toStdString() << std::endl; | 
| Chris@293 | 67         std::cerr << "button = " << QApplication::palette().color(QPalette::Button).name().toStdString() << std::endl; | 
| Chris@293 | 68         std::cerr << "buttontext = " << QApplication::palette().color(QPalette::ButtonText).name().toStdString() << std::endl; | 
| Chris@293 | 69         std::cerr << "brighttext = " << QApplication::palette().color(QPalette::BrightText).name().toStdString() << std::endl; | 
| Chris@293 | 70         std::cerr << "light = " << QApplication::palette().color(QPalette::Light).name().toStdString() << std::endl; | 
| Chris@293 | 71         std::cerr << "dark = " << QApplication::palette().color(QPalette::Dark).name().toStdString() << std::endl; | 
| Chris@293 | 72         std::cerr << "mid = " << QApplication::palette().color(QPalette::Mid).name().toStdString() << std::endl; | 
| Chris@343 | 73 */ | 
| Chris@293 | 74         m_lightPalette = QPalette(QColor("#000000"),  // WindowText | 
| Chris@293 | 75                                   QColor("#dddfe4"),  // Button | 
| Chris@293 | 76                                   QColor("#ffffff"),  // Light | 
| Chris@293 | 77                                   QColor("#555555"),  // Dark | 
| Chris@293 | 78                                   QColor("#c7c7c7"),  // Mid | 
| Chris@293 | 79                                   QColor("#000000"),  // Text | 
| Chris@293 | 80                                   QColor("#ffffff"),  // BrightText | 
| Chris@293 | 81                                   QColor("#ffffff"),  // Base | 
| Chris@293 | 82                                   QColor("#efefef")); // Window | 
| Chris@293 | 83 | 
| Chris@293 | 84 | 
| Chris@292 | 85     } else { | 
| Chris@343 | 86 /* | 
| Chris@293 | 87         std::cerr << "light palette:" << std::endl; | 
| Chris@293 | 88         std::cerr << "window = " << QApplication::palette().color(QPalette::Window).name().toStdString() << std::endl; | 
| Chris@293 | 89         std::cerr << "windowtext = " << QApplication::palette().color(QPalette::WindowText).name().toStdString() << std::endl; | 
| Chris@293 | 90         std::cerr << "base = " << QApplication::palette().color(QPalette::Base).name().toStdString() << std::endl; | 
| Chris@293 | 91         std::cerr << "alternatebase = " << QApplication::palette().color(QPalette::AlternateBase).name().toStdString() << std::endl; | 
| Chris@293 | 92         std::cerr << "text = " << QApplication::palette().color(QPalette::Text).name().toStdString() << std::endl; | 
| Chris@293 | 93         std::cerr << "button = " << QApplication::palette().color(QPalette::Button).name().toStdString() << std::endl; | 
| Chris@293 | 94         std::cerr << "buttontext = " << QApplication::palette().color(QPalette::ButtonText).name().toStdString() << std::endl; | 
| Chris@293 | 95         std::cerr << "brighttext = " << QApplication::palette().color(QPalette::BrightText).name().toStdString() << std::endl; | 
| Chris@293 | 96         std::cerr << "light = " << QApplication::palette().color(QPalette::Light).name().toStdString() << std::endl; | 
| Chris@293 | 97         std::cerr << "dark = " << QApplication::palette().color(QPalette::Dark).name().toStdString() << std::endl; | 
| Chris@293 | 98         std::cerr << "mid = " << QApplication::palette().color(QPalette::Mid).name().toStdString() << std::endl; | 
| Chris@343 | 99 */ | 
| Chris@293 | 100         m_darkPalette = QPalette(QColor("#ffffff"),  // WindowText | 
| Chris@293 | 101                                  QColor("#3e3e3e"),  // Button | 
| Chris@293 | 102                                  QColor("#808080"),  // Light | 
| Chris@293 | 103                                  QColor("#1e1e1e"),  // Dark | 
| Chris@293 | 104                                  QColor("#404040"),  // Mid | 
| Chris@293 | 105                                  QColor("#ffffff"),  // Text | 
| Chris@293 | 106                                  QColor("#ffffff"),  // BrightText | 
| Chris@293 | 107                                  QColor("#000000"),  // Base | 
| Chris@293 | 108                                  QColor("#202020")); // Window | 
| Chris@292 | 109     } | 
| Chris@127 | 110 } | 
| Chris@127 | 111 | 
| Chris@127 | 112 ViewManager::~ViewManager() | 
| Chris@127 | 113 { | 
| Chris@127 | 114 } | 
| Chris@127 | 115 | 
| Chris@127 | 116 unsigned long | 
| Chris@127 | 117 ViewManager::getGlobalCentreFrame() const | 
| Chris@127 | 118 { | 
| Chris@127 | 119 #ifdef DEBUG_VIEW_MANAGER | 
| Chris@127 | 120     std::cout << "ViewManager::getGlobalCentreFrame: returning " << m_globalCentreFrame << std::endl; | 
| Chris@127 | 121 #endif | 
| Chris@127 | 122     return m_globalCentreFrame; | 
| Chris@127 | 123 } | 
| Chris@127 | 124 | 
| Chris@180 | 125 void | 
| Chris@180 | 126 ViewManager::setGlobalCentreFrame(unsigned long f) | 
| Chris@180 | 127 { | 
| Chris@180 | 128 #ifdef DEBUG_VIEW_MANAGER | 
| Chris@180 | 129     std::cout << "ViewManager::setGlobalCentreFrame to " << f << std::endl; | 
| Chris@180 | 130 #endif | 
| Chris@180 | 131     m_globalCentreFrame = f; | 
| Chris@211 | 132     emit globalCentreFrameChanged(f); | 
| Chris@180 | 133 } | 
| Chris@180 | 134 | 
| Chris@127 | 135 unsigned long | 
| Chris@127 | 136 ViewManager::getGlobalZoom() const | 
| Chris@127 | 137 { | 
| Chris@127 | 138 #ifdef DEBUG_VIEW_MANAGER | 
| Chris@127 | 139     std::cout << "ViewManager::getGlobalZoom: returning " << m_globalZoom << std::endl; | 
| Chris@127 | 140 #endif | 
| Chris@127 | 141     return m_globalZoom; | 
| Chris@127 | 142 } | 
| Chris@127 | 143 | 
| Chris@127 | 144 unsigned long | 
| Chris@127 | 145 ViewManager::getPlaybackFrame() const | 
| Chris@127 | 146 { | 
| Chris@127 | 147     if (m_playSource && m_playSource->isPlaying()) { | 
| Chris@127 | 148 	m_playbackFrame = m_playSource->getCurrentPlayingFrame(); | 
| Chris@127 | 149     } | 
| Chris@127 | 150     return m_playbackFrame; | 
| Chris@127 | 151 } | 
| Chris@127 | 152 | 
| Chris@127 | 153 void | 
| Chris@127 | 154 ViewManager::setPlaybackFrame(unsigned long f) | 
| Chris@127 | 155 { | 
| Chris@127 | 156     if (m_playbackFrame != f) { | 
| Chris@127 | 157 	m_playbackFrame = f; | 
| Chris@127 | 158 	emit playbackFrameChanged(f); | 
| Chris@127 | 159 	if (m_playSource && m_playSource->isPlaying()) { | 
| Chris@127 | 160 	    m_playSource->play(f); | 
| Chris@127 | 161 	} | 
| Chris@127 | 162     } | 
| Chris@127 | 163 } | 
| Chris@127 | 164 | 
| Chris@301 | 165 Model * | 
| Chris@301 | 166 ViewManager::getPlaybackModel() const | 
| Chris@301 | 167 { | 
| Chris@301 | 168     return m_playbackModel; | 
| Chris@301 | 169 } | 
| Chris@301 | 170 | 
| Chris@301 | 171 void | 
| Chris@301 | 172 ViewManager::setPlaybackModel(Model *model) | 
| Chris@301 | 173 { | 
| Chris@301 | 174     m_playbackModel = model; | 
| Chris@301 | 175 } | 
| Chris@301 | 176 | 
| Chris@333 | 177 size_t | 
| Chris@333 | 178 ViewManager::alignPlaybackFrameToReference(size_t frame) const | 
| Chris@333 | 179 { | 
| Chris@333 | 180     if (!m_playbackModel) return frame; | 
| Chris@333 | 181     else return m_playbackModel->alignToReference(frame); | 
| Chris@333 | 182 } | 
| Chris@333 | 183 | 
| Chris@333 | 184 size_t | 
| Chris@333 | 185 ViewManager::alignReferenceToPlaybackFrame(size_t frame) const | 
| Chris@333 | 186 { | 
| Chris@333 | 187     if (!m_playbackModel) return frame; | 
| Chris@333 | 188     else return m_playbackModel->alignFromReference(frame); | 
| Chris@333 | 189 } | 
| Chris@333 | 190 | 
| Chris@127 | 191 bool | 
| Chris@127 | 192 ViewManager::haveInProgressSelection() const | 
| Chris@127 | 193 { | 
| Chris@127 | 194     return !m_inProgressSelection.isEmpty(); | 
| Chris@127 | 195 } | 
| Chris@127 | 196 | 
| Chris@127 | 197 const Selection & | 
| Chris@127 | 198 ViewManager::getInProgressSelection(bool &exclusive) const | 
| Chris@127 | 199 { | 
| Chris@127 | 200     exclusive = m_inProgressExclusive; | 
| Chris@127 | 201     return m_inProgressSelection; | 
| Chris@127 | 202 } | 
| Chris@127 | 203 | 
| Chris@127 | 204 void | 
| Chris@127 | 205 ViewManager::setInProgressSelection(const Selection &selection, bool exclusive) | 
| Chris@127 | 206 { | 
| Chris@127 | 207     m_inProgressExclusive = exclusive; | 
| Chris@127 | 208     m_inProgressSelection = selection; | 
| Chris@127 | 209     if (exclusive) clearSelections(); | 
| Chris@127 | 210     emit inProgressSelectionChanged(); | 
| Chris@127 | 211 } | 
| Chris@127 | 212 | 
| Chris@127 | 213 void | 
| Chris@127 | 214 ViewManager::clearInProgressSelection() | 
| Chris@127 | 215 { | 
| Chris@127 | 216     m_inProgressSelection = Selection(); | 
| Chris@127 | 217     emit inProgressSelectionChanged(); | 
| Chris@127 | 218 } | 
| Chris@127 | 219 | 
| Chris@127 | 220 const MultiSelection & | 
| Chris@127 | 221 ViewManager::getSelection() const | 
| Chris@127 | 222 { | 
| Chris@127 | 223     return m_selections; | 
| Chris@127 | 224 } | 
| Chris@127 | 225 | 
| Chris@127 | 226 const MultiSelection::SelectionList & | 
| Chris@127 | 227 ViewManager::getSelections() const | 
| Chris@127 | 228 { | 
| Chris@127 | 229     return m_selections.getSelections(); | 
| Chris@127 | 230 } | 
| Chris@127 | 231 | 
| Chris@127 | 232 void | 
| Chris@127 | 233 ViewManager::setSelection(const Selection &selection) | 
| Chris@127 | 234 { | 
| Chris@127 | 235     MultiSelection ms(m_selections); | 
| Chris@127 | 236     ms.setSelection(selection); | 
| Chris@127 | 237     setSelections(ms); | 
| Chris@127 | 238 } | 
| Chris@127 | 239 | 
| Chris@127 | 240 void | 
| Chris@127 | 241 ViewManager::addSelection(const Selection &selection) | 
| Chris@127 | 242 { | 
| Chris@127 | 243     MultiSelection ms(m_selections); | 
| Chris@127 | 244     ms.addSelection(selection); | 
| Chris@127 | 245     setSelections(ms); | 
| Chris@127 | 246 } | 
| Chris@127 | 247 | 
| Chris@127 | 248 void | 
| Chris@127 | 249 ViewManager::removeSelection(const Selection &selection) | 
| Chris@127 | 250 { | 
| Chris@127 | 251     MultiSelection ms(m_selections); | 
| Chris@127 | 252     ms.removeSelection(selection); | 
| Chris@127 | 253     setSelections(ms); | 
| Chris@127 | 254 } | 
| Chris@127 | 255 | 
| Chris@127 | 256 void | 
| Chris@127 | 257 ViewManager::clearSelections() | 
| Chris@127 | 258 { | 
| Chris@127 | 259     MultiSelection ms(m_selections); | 
| Chris@127 | 260     ms.clearSelections(); | 
| Chris@127 | 261     setSelections(ms); | 
| Chris@127 | 262 } | 
| Chris@127 | 263 | 
| Chris@127 | 264 void | 
| Chris@127 | 265 ViewManager::setSelections(const MultiSelection &ms) | 
| Chris@127 | 266 { | 
| Chris@127 | 267     if (m_selections.getSelections() == ms.getSelections()) return; | 
| Chris@127 | 268     SetSelectionCommand *command = new SetSelectionCommand(this, ms); | 
| Chris@127 | 269     CommandHistory::getInstance()->addCommand(command); | 
| Chris@127 | 270 } | 
| Chris@127 | 271 | 
| Chris@271 | 272 size_t | 
| Chris@271 | 273 ViewManager::constrainFrameToSelection(size_t frame) const | 
| Chris@271 | 274 { | 
| Chris@271 | 275     MultiSelection::SelectionList sl = getSelections(); | 
| Chris@271 | 276     if (sl.empty()) return frame; | 
| Chris@271 | 277 | 
| Chris@271 | 278     size_t selectionStartFrame = sl.begin()->getStartFrame(); | 
| Chris@271 | 279     if (frame < selectionStartFrame) { | 
| Chris@271 | 280         frame = selectionStartFrame; | 
| Chris@271 | 281         return frame; | 
| Chris@271 | 282     } | 
| Chris@271 | 283 | 
| Chris@271 | 284     MultiSelection::SelectionList::iterator i = sl.end(); | 
| Chris@271 | 285     --i; | 
| Chris@271 | 286     size_t selectionEndFrame = i->getEndFrame(); | 
| Chris@271 | 287     if (frame > selectionEndFrame) frame = selectionEndFrame; | 
| Chris@271 | 288 | 
| Chris@271 | 289     return frame; | 
| Chris@271 | 290 } | 
| Chris@271 | 291 | 
| Chris@127 | 292 void | 
| Chris@127 | 293 ViewManager::signalSelectionChange() | 
| Chris@127 | 294 { | 
| Chris@127 | 295     emit selectionChanged(); | 
| Chris@127 | 296 } | 
| Chris@127 | 297 | 
| Chris@127 | 298 ViewManager::SetSelectionCommand::SetSelectionCommand(ViewManager *vm, | 
| Chris@127 | 299 						      const MultiSelection &ms) : | 
| Chris@127 | 300     m_vm(vm), | 
| Chris@127 | 301     m_oldSelection(vm->m_selections), | 
| Chris@127 | 302     m_newSelection(ms) | 
| Chris@127 | 303 { | 
| Chris@127 | 304 } | 
| Chris@127 | 305 | 
| Chris@127 | 306 ViewManager::SetSelectionCommand::~SetSelectionCommand() { } | 
| Chris@127 | 307 | 
| Chris@127 | 308 void | 
| Chris@127 | 309 ViewManager::SetSelectionCommand::execute() | 
| Chris@127 | 310 { | 
| Chris@127 | 311     m_vm->m_selections = m_newSelection; | 
| Chris@127 | 312     m_vm->signalSelectionChange(); | 
| Chris@127 | 313 } | 
| Chris@127 | 314 | 
| Chris@127 | 315 void | 
| Chris@127 | 316 ViewManager::SetSelectionCommand::unexecute() | 
| Chris@127 | 317 { | 
| Chris@127 | 318     m_vm->m_selections = m_oldSelection; | 
| Chris@127 | 319     m_vm->signalSelectionChange(); | 
| Chris@127 | 320 } | 
| Chris@127 | 321 | 
| Chris@127 | 322 QString | 
| Chris@127 | 323 ViewManager::SetSelectionCommand::getName() const | 
| Chris@127 | 324 { | 
| Chris@127 | 325     if (m_newSelection.getSelections().empty()) return tr("Clear Selection"); | 
| Chris@127 | 326     else return tr("Select"); | 
| Chris@127 | 327 } | 
| Chris@127 | 328 | 
| Chris@127 | 329 Selection | 
| Chris@127 | 330 ViewManager::getContainingSelection(size_t frame, bool defaultToFollowing) const | 
| Chris@127 | 331 { | 
| Chris@127 | 332     return m_selections.getContainingSelection(frame, defaultToFollowing); | 
| Chris@127 | 333 } | 
| Chris@127 | 334 | 
| Chris@127 | 335 void | 
| Chris@127 | 336 ViewManager::setToolMode(ToolMode mode) | 
| Chris@127 | 337 { | 
| Chris@127 | 338     m_toolMode = mode; | 
| Chris@127 | 339 | 
| Chris@127 | 340     emit toolModeChanged(); | 
| Chris@127 | 341 } | 
| Chris@127 | 342 | 
| Chris@127 | 343 void | 
| Chris@127 | 344 ViewManager::setPlayLoopMode(bool mode) | 
| Chris@127 | 345 { | 
| Chris@177 | 346     if (m_playLoopMode != mode) { | 
| Chris@127 | 347 | 
| Chris@177 | 348         m_playLoopMode = mode; | 
| Chris@177 | 349 | 
| Chris@177 | 350         emit playLoopModeChanged(); | 
| Chris@177 | 351         emit playLoopModeChanged(mode); | 
| Chris@177 | 352     } | 
| Chris@127 | 353 } | 
| Chris@127 | 354 | 
| Chris@127 | 355 void | 
| Chris@127 | 356 ViewManager::setPlaySelectionMode(bool mode) | 
| Chris@127 | 357 { | 
| Chris@177 | 358     if (m_playSelectionMode != mode) { | 
| Chris@127 | 359 | 
| Chris@177 | 360         m_playSelectionMode = mode; | 
| Chris@177 | 361 | 
| Chris@177 | 362         emit playSelectionModeChanged(); | 
| Chris@177 | 363         emit playSelectionModeChanged(mode); | 
| Chris@177 | 364     } | 
| Chris@127 | 365 } | 
| Chris@127 | 366 | 
| Chris@301 | 367 void | 
| Chris@301 | 368 ViewManager::setPlaySoloMode(bool mode) | 
| Chris@301 | 369 { | 
| Chris@301 | 370     if (m_playSoloMode != mode) { | 
| Chris@301 | 371 | 
| Chris@301 | 372         m_playSoloMode = mode; | 
| Chris@301 | 373 | 
| Chris@301 | 374         emit playSoloModeChanged(); | 
| Chris@301 | 375         emit playSoloModeChanged(mode); | 
| Chris@301 | 376     } | 
| Chris@301 | 377 } | 
| Chris@301 | 378 | 
| Chris@314 | 379 void | 
| Chris@314 | 380 ViewManager::setAlignMode(bool mode) | 
| Chris@314 | 381 { | 
| Chris@314 | 382     if (m_alignMode != mode) { | 
| Chris@314 | 383 | 
| Chris@314 | 384         m_alignMode = mode; | 
| Chris@314 | 385 | 
| Chris@314 | 386         emit alignModeChanged(); | 
| Chris@314 | 387         emit alignModeChanged(mode); | 
| Chris@314 | 388     } | 
| Chris@314 | 389 } | 
| Chris@314 | 390 | 
| Chris@224 | 391 size_t | 
| Chris@224 | 392 ViewManager::getPlaybackSampleRate() const | 
| Chris@224 | 393 { | 
| Chris@224 | 394     if (m_playSource) { | 
| Chris@224 | 395         return m_playSource->getSourceSampleRate(); | 
| Chris@224 | 396     } | 
| Chris@224 | 397     return 0; | 
| Chris@224 | 398 } | 
| Chris@224 | 399 | 
| Chris@127 | 400 size_t | 
| Chris@224 | 401 ViewManager::getOutputSampleRate() const | 
| Chris@127 | 402 { | 
| Chris@127 | 403     if (m_playSource) { | 
| Chris@127 | 404 	return m_playSource->getTargetSampleRate(); | 
| Chris@127 | 405     } | 
| Chris@127 | 406     return 0; | 
| Chris@127 | 407 } | 
| Chris@127 | 408 | 
| Chris@127 | 409 void | 
| Chris@127 | 410 ViewManager::setAudioPlaySource(AudioPlaySource *source) | 
| Chris@127 | 411 { | 
| Chris@127 | 412     if (!m_playSource) { | 
| Chris@127 | 413 	QTimer::singleShot(100, this, SLOT(checkPlayStatus())); | 
| Chris@127 | 414     } | 
| Chris@127 | 415     m_playSource = source; | 
| Chris@127 | 416 } | 
| Chris@127 | 417 | 
| Chris@127 | 418 void | 
| Chris@248 | 419 ViewManager::playStatusChanged(bool /* playing */) | 
| Chris@127 | 420 { | 
| Chris@127 | 421     checkPlayStatus(); | 
| Chris@127 | 422 } | 
| Chris@127 | 423 | 
| Chris@127 | 424 void | 
| Chris@127 | 425 ViewManager::checkPlayStatus() | 
| Chris@127 | 426 { | 
| Chris@127 | 427     if (m_playSource && m_playSource->isPlaying()) { | 
| Chris@127 | 428 | 
| Chris@127 | 429 	float left = 0, right = 0; | 
| Chris@127 | 430 	if (m_playSource->getOutputLevels(left, right)) { | 
| Chris@127 | 431 	    if (left != m_lastLeft || right != m_lastRight) { | 
| Chris@127 | 432 		emit outputLevelsChanged(left, right); | 
| Chris@127 | 433 		m_lastLeft = left; | 
| Chris@127 | 434 		m_lastRight = right; | 
| Chris@127 | 435 	    } | 
| Chris@127 | 436 	} | 
| Chris@127 | 437 | 
| Chris@127 | 438 	m_playbackFrame = m_playSource->getCurrentPlayingFrame(); | 
| Chris@127 | 439 | 
| Chris@127 | 440 #ifdef DEBUG_VIEW_MANAGER | 
| Chris@127 | 441 	std::cout << "ViewManager::checkPlayStatus: Playing, frame " << m_playbackFrame << ", levels " << m_lastLeft << "," << m_lastRight << std::endl; | 
| Chris@127 | 442 #endif | 
| Chris@127 | 443 | 
| Chris@127 | 444 	emit playbackFrameChanged(m_playbackFrame); | 
| Chris@127 | 445 | 
| Chris@127 | 446 	QTimer::singleShot(20, this, SLOT(checkPlayStatus())); | 
| Chris@127 | 447 | 
| Chris@127 | 448     } else { | 
| Chris@127 | 449 | 
| Chris@127 | 450 	QTimer::singleShot(100, this, SLOT(checkPlayStatus())); | 
| Chris@127 | 451 | 
| Chris@127 | 452 	if (m_lastLeft != 0.0 || m_lastRight != 0.0) { | 
| Chris@127 | 453 	    emit outputLevelsChanged(0.0, 0.0); | 
| Chris@127 | 454 	    m_lastLeft = 0.0; | 
| Chris@127 | 455 	    m_lastRight = 0.0; | 
| Chris@127 | 456 	} | 
| Chris@127 | 457 | 
| Chris@127 | 458 #ifdef DEBUG_VIEW_MANAGER | 
| Chris@127 | 459 //	std::cout << "ViewManager::checkPlayStatus: Not playing" << std::endl; | 
| Chris@127 | 460 #endif | 
| Chris@127 | 461     } | 
| Chris@127 | 462 } | 
| Chris@127 | 463 | 
| Chris@127 | 464 bool | 
| Chris@127 | 465 ViewManager::isPlaying() const | 
| Chris@127 | 466 { | 
| Chris@127 | 467     return m_playSource && m_playSource->isPlaying(); | 
| Chris@127 | 468 } | 
| Chris@127 | 469 | 
| Chris@127 | 470 void | 
| Chris@211 | 471 ViewManager::viewCentreFrameChanged(unsigned long f, bool locked, | 
| Chris@211 | 472                                     PlaybackFollowMode mode) | 
| Chris@127 | 473 { | 
| Chris@211 | 474     View *v = dynamic_cast<View *>(sender()); | 
| Chris@211 | 475 | 
| Chris@127 | 476     if (locked) { | 
| Chris@211 | 477         m_globalCentreFrame = f; | 
| Chris@211 | 478         emit globalCentreFrameChanged(f); | 
| Chris@211 | 479     } else { | 
| Chris@211 | 480         if (v) emit viewCentreFrameChanged(v, f); | 
| Chris@127 | 481     } | 
| Chris@127 | 482 | 
| Chris@211 | 483     if (mode == PlaybackIgnore) { | 
| Chris@211 | 484         return; | 
| Chris@211 | 485     } | 
| Chris@211 | 486 | 
| Chris@211 | 487     seek(f); | 
| Chris@211 | 488 } | 
| Chris@211 | 489 | 
| Chris@211 | 490 void | 
| Chris@211 | 491 ViewManager::seek(unsigned long f) | 
| Chris@211 | 492 { | 
| Chris@127 | 493 #ifdef DEBUG_VIEW_MANAGER | 
| Chris@211 | 494     std::cout << "ViewManager::seek(" << f << ")" << std::endl; | 
| Chris@127 | 495 #endif | 
| Chris@127 | 496 | 
| Chris@127 | 497     if (m_playSource && m_playSource->isPlaying()) { | 
| Chris@127 | 498 	unsigned long playFrame = m_playSource->getCurrentPlayingFrame(); | 
| Chris@127 | 499 	unsigned long diff = std::max(f, playFrame) - std::min(f, playFrame); | 
| Chris@127 | 500 	if (diff > 20000) { | 
| Chris@127 | 501 	    m_playbackFrame = f; | 
| Chris@127 | 502 	    m_playSource->play(f); | 
| Chris@127 | 503 #ifdef DEBUG_VIEW_MANAGER | 
| Chris@127 | 504 	    std::cout << "ViewManager::considerSeek: reseeking from " << playFrame << " to " << f << std::endl; | 
| Chris@127 | 505 #endif | 
| Chris@211 | 506             emit playbackFrameChanged(f); | 
| Chris@127 | 507 	} | 
| Chris@127 | 508     } else { | 
| Chris@211 | 509         if (m_playbackFrame != f) { | 
| Chris@211 | 510             m_playbackFrame = f; | 
| Chris@211 | 511             emit playbackFrameChanged(f); | 
| Chris@211 | 512         } | 
| Chris@127 | 513     } | 
| Chris@127 | 514 } | 
| Chris@127 | 515 | 
| Chris@127 | 516 void | 
| Chris@222 | 517 ViewManager::viewZoomLevelChanged(unsigned long z, bool locked) | 
| Chris@127 | 518 { | 
| Chris@222 | 519     View *v = dynamic_cast<View *>(sender()); | 
| Chris@222 | 520 | 
| Chris@222 | 521     if (!v) { | 
| Chris@222 | 522         std::cerr << "ViewManager::viewZoomLevelChanged: WARNING: sender is not a view" << std::endl; | 
| Chris@222 | 523         return; | 
| Chris@222 | 524     } | 
| Chris@222 | 525 | 
| Chris@222 | 526 //!!!    emit zoomLevelChanged(); | 
| Chris@133 | 527 | 
| Chris@127 | 528     if (locked) { | 
| Chris@127 | 529 	m_globalZoom = z; | 
| Chris@127 | 530     } | 
| Chris@127 | 531 | 
| Chris@127 | 532 #ifdef DEBUG_VIEW_MANAGER | 
| Chris@222 | 533     std::cout << "ViewManager::viewZoomLevelChanged(" << v << ", " << z << ", " << locked << ")" << std::endl; | 
| Chris@127 | 534 #endif | 
| Chris@222 | 535 | 
| Chris@222 | 536     emit viewZoomLevelChanged(v, z, locked); | 
| Chris@127 | 537 } | 
| Chris@127 | 538 | 
| Chris@127 | 539 void | 
| Chris@127 | 540 ViewManager::setOverlayMode(OverlayMode mode) | 
| Chris@127 | 541 { | 
| Chris@127 | 542     if (m_overlayMode != mode) { | 
| Chris@127 | 543         m_overlayMode = mode; | 
| Chris@127 | 544         emit overlayModeChanged(); | 
| Chris@127 | 545     } | 
| Chris@133 | 546 | 
| Chris@133 | 547     QSettings settings; | 
| Chris@133 | 548     settings.beginGroup("MainWindow"); | 
| Chris@133 | 549     settings.setValue("overlay-mode", int(m_overlayMode)); | 
| Chris@133 | 550     settings.endGroup(); | 
| Chris@127 | 551 } | 
| Chris@127 | 552 | 
| Chris@133 | 553 void | 
| Chris@133 | 554 ViewManager::setZoomWheelsEnabled(bool enabled) | 
| Chris@133 | 555 { | 
| Chris@133 | 556     if (m_zoomWheelsEnabled != enabled) { | 
| Chris@133 | 557         m_zoomWheelsEnabled = enabled; | 
| Chris@133 | 558         emit zoomWheelsEnabledChanged(); | 
| Chris@133 | 559     } | 
| Chris@127 | 560 | 
| Chris@133 | 561     QSettings settings; | 
| Chris@133 | 562     settings.beginGroup("MainWindow"); | 
| Chris@133 | 563     settings.setValue("zoom-wheels-enabled", m_zoomWheelsEnabled); | 
| Chris@133 | 564     settings.endGroup(); | 
| Chris@133 | 565 } | 
| Chris@133 | 566 | 
| Chris@292 | 567 void | 
| Chris@292 | 568 ViewManager::setGlobalDarkBackground(bool dark) | 
| Chris@292 | 569 { | 
| Chris@292 | 570     // also save the current palette, in case the user has changed it | 
| Chris@292 | 571     // since construction | 
| Chris@292 | 572     if (getGlobalDarkBackground()) { | 
| Chris@292 | 573         m_darkPalette = QApplication::palette(); | 
| Chris@292 | 574     } else { | 
| Chris@292 | 575         m_lightPalette = QApplication::palette(); | 
| Chris@292 | 576     } | 
| Chris@292 | 577 | 
| Chris@292 | 578     if (dark) { | 
| Chris@292 | 579         QApplication::setPalette(m_darkPalette); | 
| Chris@292 | 580     } else { | 
| Chris@292 | 581         QApplication::setPalette(m_lightPalette); | 
| Chris@292 | 582     } | 
| Chris@292 | 583 } | 
| Chris@292 | 584 | 
| Chris@292 | 585 bool | 
| Chris@292 | 586 ViewManager::getGlobalDarkBackground() const | 
| Chris@292 | 587 { | 
| Chris@292 | 588     bool dark = false; | 
| Chris@292 | 589     QColor windowBg = QApplication::palette().color(QPalette::Window); | 
| Chris@292 | 590     if (windowBg.red() + windowBg.green() + windowBg.blue() < 384) { | 
| Chris@292 | 591         dark = true; | 
| Chris@292 | 592     } | 
| Chris@292 | 593     return dark; | 
| Chris@292 | 594 } | 
| Chris@292 | 595 |