# HG changeset patch # User Chris Cannam # Date 1205417163 0 # Node ID 0bcb449d15f43092be5e1033329d6f29021ba425 # Parent e1a9e478b7f2ce792014d848b38a73658357ca3f * Fix #1628781 changes to layer visibility and mute should use a command * Also use a command for changes to layer playback pan, gain, plugin settings * Refactor PlayParameterRepository to remove dependency on audioio from base * Fix failure to save play parameters for main model in session file diff -r e1a9e478b7f2 -r 0bcb449d15f4 widgets/CommandHistory.cpp --- a/widgets/CommandHistory.cpp Wed Mar 12 17:42:56 2008 +0000 +++ b/widgets/CommandHistory.cpp Thu Mar 13 14:06:03 2008 +0000 @@ -35,6 +35,8 @@ #include +//#define DEBUG_COMMAND_HISTORY 1 + CommandHistory *CommandHistory::m_instance = 0; CommandHistory::CommandHistory() : @@ -95,7 +97,9 @@ void CommandHistory::clear() { -// std::cerr << "CommandHistory::clear()" << std::endl; +#ifdef DEBUG_COMMAND_HISTORY + std::cerr << "CommandHistory::clear()" << std::endl; +#endif closeBundle(); m_savedAt = -1; clearStack(m_undoStack); @@ -147,10 +151,14 @@ closeBundle(); } -// std::cerr << "CommandHistory::addCommand: " << command->getName().toLocal8Bit().data() << " at " << command << std::endl; +#ifdef DEBUG_COMMAND_HISTORY + std::cerr << "CommandHistory::addCommand: " << command->getName().toLocal8Bit().data() << " at " << command << std::endl; + if (!m_redoStack.empty()) { + std::cerr << "CommandHistory::clearing redo stack" << std::endl; + } +#endif // We can't redo after adding a command -// std::cerr << "CommandHistory::clearing redo stack" << std::endl; clearStack(m_redoStack); // can we reach savedAt? @@ -176,6 +184,11 @@ { if (m_currentBundle) { if (!command || (command->getName() != m_currentBundleName)) { +#ifdef DEBUG_COMMAND_HISTORY + std::cerr << "CommandHistory::addToBundle: " + << command->getName().toStdString() + << ": closing current bundle" << std::endl; +#endif closeBundle(); } } @@ -183,6 +196,13 @@ if (!command) return; if (!m_currentBundle) { + +#ifdef DEBUG_COMMAND_HISTORY + std::cerr << "CommandHistory::addToBundle: " + << command->getName().toStdString() + << ": creating new bundle" << std::endl; +#endif + // need to addCommand before setting m_currentBundle, as addCommand // with bundle false will reset m_currentBundle to 0 MacroCommand *mc = new MacroCommand(command->getName()); @@ -191,9 +211,22 @@ m_currentBundleName = command->getName(); } +#ifdef DEBUG_COMMAND_HISTORY + std::cerr << "CommandHistory::addToBundle: " + << command->getName().toStdString() + << ": adding to bundle" << std::endl; +#endif + if (execute) command->execute(); m_currentBundle->addCommand(command); + // Emit even if we aren't executing the command, because + // someone must have executed it for this to make any sense + emit commandExecuted(); + emit commandExecuted(command); + + updateActions(); + delete m_bundleTimer; m_bundleTimer = new QTimer(this); connect(m_bundleTimer, SIGNAL(timeout()), this, SLOT(bundleTimerTimeout())); @@ -203,6 +236,10 @@ void CommandHistory::closeBundle() { +#ifdef DEBUG_COMMAND_HISTORY + std::cerr << "CommandHistory::closeBundle" << std::endl; +#endif + m_currentBundle = 0; m_currentBundleName = ""; } @@ -210,13 +247,19 @@ void CommandHistory::bundleTimerTimeout() { +#ifdef DEBUG_COMMAND_HISTORY + std::cerr << "CommandHistory::bundleTimerTimeout: bundle is " << m_currentBundle << std::endl; +#endif + closeBundle(); } void CommandHistory::addToCompound(Command *command, bool execute) { -// std::cerr << "CommandHistory::addToCompound: " << command->getName().toLocal8Bit().data() << std::endl; +#ifdef DEBUG_COMMAND_HISTORY + std::cerr << "CommandHistory::addToCompound: " << command->getName().toLocal8Bit().data() << std::endl; +#endif if (!m_currentCompound) { std::cerr << "CommandHistory::addToCompound: ERROR: no compound operation in progress!" << std::endl; return; @@ -278,6 +321,10 @@ { if (m_undoStack.empty()) return; +#ifdef DEBUG_COMMAND_HISTORY + std::cerr << "CommandHistory::undo()" << std::endl; +#endif + closeBundle(); Command *command = m_undoStack.top(); @@ -299,6 +346,10 @@ { if (m_redoStack.empty()) return; +#ifdef DEBUG_COMMAND_HISTORY + std::cerr << "CommandHistory::redo()" << std::endl; +#endif + closeBundle(); Command *command = m_redoStack.top(); @@ -374,8 +425,10 @@ CommandStack tempStack; for (i = 0; i < limit; ++i) { -// Command *command = stack.top(); -// std::cerr << "CommandHistory::clipStack: Saving recent command: " << command->getName().toLocal8Bit().data() << " at " << command << std::endl; +#ifdef DEBUG_COMMAND_HISTORY + Command *command = stack.top(); + std::cerr << "CommandHistory::clipStack: Saving recent command: " << command->getName().toLocal8Bit().data() << " at " << command << std::endl; +#endif tempStack.push(stack.top()); stack.pop(); } @@ -395,7 +448,9 @@ while (!stack.empty()) { Command *command = stack.top(); // Not safe to call getName() on a command about to be deleted -// std::cerr << "CommandHistory::clearStack: About to delete command " << command << std::endl; +#ifdef DEBUG_COMMAND_HISTORY + std::cerr << "CommandHistory::clearStack: About to delete command " << command << std::endl; +#endif delete command; stack.pop(); } diff -r e1a9e478b7f2 -r 0bcb449d15f4 widgets/PropertyBox.cpp --- a/widgets/PropertyBox.cpp Wed Mar 12 17:42:56 2008 +0000 +++ b/widgets/PropertyBox.cpp Thu Mar 13 14:06:03 2008 +0000 @@ -18,6 +18,7 @@ #include "base/PropertyContainer.h" #include "base/PlayParameters.h" +#include "base/PlayParameterRepository.h" #include "layer/Layer.h" #include "layer/ColourDatabase.h" #include "base/UnitDatabase.h" @@ -176,13 +177,13 @@ m_playButton->setState(!params->isPlayMuted()); layout->addWidget(m_playButton); connect(m_playButton, SIGNAL(stateChanged(bool)), - params, SLOT(setPlayAudible(bool))); + this, SLOT(playAudibleButtonChanged(bool))); connect(m_playButton, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredWidget())); connect(m_playButton, SIGNAL(mouseLeft()), this, SLOT(mouseLeftWidget())); connect(params, SIGNAL(playAudibleChanged(bool)), - m_playButton, SLOT(setState(bool))); + this, SLOT(playAudibleChanged(bool))); layout->setAlignment(m_playButton, Qt::AlignVCenter); layout->insertStretch(-1, 10); @@ -214,14 +215,13 @@ this, SLOT(playGainDialChanged(int))); connect(params, SIGNAL(playGainChanged(float)), this, SLOT(playGainChanged(float))); - connect(this, SIGNAL(changePlayGain(float)), - params, SLOT(setPlayGain(float))); connect(this, SIGNAL(changePlayGainDial(int)), gainDial, SLOT(setValue(int))); connect(gainDial, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredWidget())); connect(gainDial, SIGNAL(mouseLeft()), this, SLOT(mouseLeftWidget())); + playGainChanged(params->getPlayGain()); layout->setAlignment(gainDial, Qt::AlignVCenter); AudioDial *panDial = new AudioDial; @@ -241,14 +241,13 @@ this, SLOT(playPanDialChanged(int))); connect(params, SIGNAL(playPanChanged(float)), this, SLOT(playPanChanged(float))); - connect(this, SIGNAL(changePlayPan(float)), - params, SLOT(setPlayPan(float))); connect(this, SIGNAL(changePlayPanDial(int)), panDial, SLOT(setValue(int))); connect(panDial, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredWidget())); connect(panDial, SIGNAL(mouseLeft()), this, SLOT(mouseLeftWidget())); + playPanChanged(params->getPlayPan()); layout->setAlignment(panDial, Qt::AlignVCenter); } else { @@ -656,6 +655,26 @@ db->setUseDarkBackground(index, dialog.isDarkBackgroundChecked()); } } + +void +PropertyBox::playAudibleChanged(bool audible) +{ + m_playButton->setState(audible); +} + +void +PropertyBox::playAudibleButtonChanged(bool audible) +{ + PlayParameters *params = m_container->getPlayParameters(); + if (!params) return; + + if (params->isPlayAudible() != audible) { + PlayParameterRepository::EditCommand *command = + new PlayParameterRepository::EditCommand(params); + command->setPlayAudible(audible); + CommandHistory::getInstance()->addCommand(command, true, true); + } +} void PropertyBox::playGainChanged(float gain) @@ -670,8 +689,19 @@ PropertyBox::playGainDialChanged(int dialValue) { QObject *obj = sender(); + + PlayParameters *params = m_container->getPlayParameters(); + if (!params) return; + float gain = pow(10, float(dialValue) / 20.0); - emit changePlayGain(gain); + + if (params->getPlayGain() != gain) { + PlayParameterRepository::EditCommand *command = + new PlayParameterRepository::EditCommand(params); + command->setPlayGain(gain); + CommandHistory::getInstance()->addCommand(command, true, true); + } + updateContextHelp(obj); } @@ -688,10 +718,21 @@ PropertyBox::playPanDialChanged(int dialValue) { QObject *obj = sender(); + + PlayParameters *params = m_container->getPlayParameters(); + if (!params) return; + float pan = float(dialValue) / 50.0; if (pan < -1.0) pan = -1.0; if (pan > 1.0) pan = 1.0; - emit changePlayPan(pan); + + if (params->getPlayPan() != pan) { + PlayParameterRepository::EditCommand *command = + new PlayParameterRepository::EditCommand(params); + command->setPlayPan(pan); + CommandHistory::getInstance()->addCommand(command, true, true); + } + updateContextHelp(obj); } @@ -705,6 +746,9 @@ QString pluginId = params->getPlayPluginId(); QString configurationXml = params->getPlayPluginConfiguration(); + + PlayParameterRepository::EditCommand *command = + new PlayParameterRepository::EditCommand(params); RealTimePluginFactory *factory = RealTimePluginFactory::instanceFor(pluginId); @@ -721,8 +765,11 @@ this, SLOT(pluginConfigurationChanged(QString))); if (dialog->exec() == QDialog::Accepted) { - params->setPlayPluginConfiguration(PluginXml(instance).toXmlString()); + QString newConfiguration = PluginXml(instance).toXmlString(); + command->setPlayPluginConfiguration(newConfiguration); + CommandHistory::getInstance()->addCommand(command, true); } else { + delete command; // restore in case we mucked about with the configuration // as a consequence of signals from the dialog params->setPlayPluginConfiguration(configurationXml); diff -r e1a9e478b7f2 -r 0bcb449d15f4 widgets/PropertyBox.h --- a/widgets/PropertyBox.h Wed Mar 12 17:42:56 2008 +0000 +++ b/widgets/PropertyBox.h Thu Mar 13 14:06:03 2008 +0000 @@ -39,9 +39,7 @@ PropertyContainer *getContainer() { return m_container; } signals: - void changePlayGain(float); void changePlayGainDial(int); - void changePlayPan(float); void changePlayPanDial(int); void showLayer(bool); void contextHelpChanged(const QString &); @@ -56,6 +54,8 @@ void propertyControllerChanged(int); void propertyControllerChanged(bool); + void playAudibleChanged(bool); + void playAudibleButtonChanged(bool); void playGainChanged(float); void playGainDialChanged(int); void playPanChanged(float); diff -r e1a9e478b7f2 -r 0bcb449d15f4 widgets/PropertyStack.cpp --- a/widgets/PropertyStack.cpp Wed Mar 12 17:42:56 2008 +0000 +++ b/widgets/PropertyStack.cpp Thu Mar 13 14:06:03 2008 +0000 @@ -21,6 +21,8 @@ #include "layer/LayerFactory.h" #include "widgets/NotifyingTabBar.h" #include "widgets/IconLoader.h" +#include "base/Command.h" +#include "widgets/CommandHistory.h" #include #include @@ -198,6 +200,26 @@ repopulate(); } +class ShowLayerCommand : public QObject, public Command +{ +public: + ShowLayerCommand(View *view, Layer *layer, bool show) : + m_view(view), m_layer(layer), m_show(show) { } + void execute() { + m_layer->showLayer(m_view, m_show); + } + void unexecute() { + m_layer->showLayer(m_view, !m_show); + } + QString getName() const { + return tr("Change Layer Visibility"); + } +protected: + View *m_view; + Layer *m_layer; + bool m_show; +}; + void PropertyStack::showLayer(bool show) { @@ -207,7 +229,8 @@ if (obj == m_boxes[i]) { Layer *layer = dynamic_cast(m_boxes[i]->getContainer()); if (layer) { - layer->showLayer(m_client, show); + CommandHistory::getInstance()->addCommand + (new ShowLayerCommand(m_client, layer, show)); return; } }