Browse Source

Add saved state to history::State. Ask for user confirmation in patch::resetDialog() and patch::loadDialog() if patch is unsaved.

tags/v1.0.0
Andrew Belt 5 years ago
parent
commit
87cab493f3
4 changed files with 48 additions and 17 deletions
  1. +6
    -1
      include/history.hpp
  2. +17
    -0
      src/history.cpp
  3. +23
    -16
      src/patch.cpp
  4. +2
    -0
      src/window.cpp

+ 6
- 1
include/history.hpp View File

@@ -150,8 +150,11 @@ struct CableRemove : InverseAction<CableAdd> {


struct State { struct State {
std::vector<Action*> actions; std::vector<Action*> actions;
int actionIndex = 0;
int actionIndex;
/** Action index of saved patch state. */
int savedIndex;


State();
~State(); ~State();
void clear(); void clear();
void push(Action *action); void push(Action *action);
@@ -161,6 +164,8 @@ struct State {
bool canRedo(); bool canRedo();
std::string getUndoName(); std::string getUndoName();
std::string getRedoName(); std::string getRedoName();
void setSaved();
bool isSaved();
}; };






+ 17
- 0
src/history.cpp View File

@@ -163,6 +163,10 @@ void CableAdd::redo() {
} }




State::State() {
clear();
}

State::~State() { State::~State() {
clear(); clear();
} }
@@ -173,6 +177,7 @@ void State::clear() {
} }
actions.clear(); actions.clear();
actionIndex = 0; actionIndex = 0;
savedIndex = -1;
} }


void State::push(Action *action) { void State::push(Action *action) {
@@ -182,6 +187,10 @@ void State::push(Action *action) {
actions.resize(actionIndex); actions.resize(actionIndex);
actions.push_back(action); actions.push_back(action);
actionIndex++; actionIndex++;
// Unset the savedIndex if we just permanently overwrote the saved state
if (actionIndex == savedIndex) {
savedIndex = -1;
}
} }


void State::undo() { void State::undo() {
@@ -218,6 +227,14 @@ std::string State::getRedoName() {
return actions[actionIndex]->name; return actions[actionIndex]->name;
} }


void State::setSaved() {
savedIndex = actionIndex;
}

bool State::isSaved() {
return actionIndex == savedIndex;
}



} // namespace history } // namespace history
} // namespace rack } // namespace rack

+ 23
- 16
src/patch.cpp View File

@@ -66,9 +66,10 @@ void PatchManager::reset() {
} }


void PatchManager::resetDialog() { void PatchManager::resetDialog() {
if (osdialog_message(OSDIALOG_INFO, OSDIALOG_OK_CANCEL, "Clear patch and start over?")) {
reset();
}
if (!(APP->history->isSaved() || osdialog_message(OSDIALOG_INFO, OSDIALOG_OK_CANCEL, "The current patch is unsaved. Clear it and start a new patch?")))
return;

reset();
} }


void PatchManager::save(std::string path) { void PatchManager::save(std::string path) {
@@ -95,6 +96,7 @@ void PatchManager::save(std::string path) {
void PatchManager::saveDialog() { void PatchManager::saveDialog() {
if (!path.empty()) { if (!path.empty()) {
save(path); save(path);
APP->history->setSaved();
} }
else { else {
saveAsDialog(); saveAsDialog();
@@ -124,10 +126,9 @@ void PatchManager::saveAsDialog() {
return; return;
} }
DEFER({ DEFER({
free(pathC);
std::free(pathC);
}); });



std::string pathStr = pathC; std::string pathStr = pathC;
if (string::extension(pathStr).empty()) { if (string::extension(pathStr).empty()) {
pathStr += ".vcv"; pathStr += ".vcv";
@@ -135,12 +136,15 @@ void PatchManager::saveAsDialog() {


save(pathStr); save(pathStr);
path = pathStr; path = pathStr;
APP->history->setSaved();
} }


void PatchManager::saveTemplateDialog() { void PatchManager::saveTemplateDialog() {
if (osdialog_message(OSDIALOG_INFO, OSDIALOG_OK_CANCEL, "Overwrite template patch?")) {
save(asset::user("template.vcv"));
}
// Even if <user>/template.vcv doesn't exist, this message is still valid because it overrides the <system>/template.vcv patch.
if (!osdialog_message(OSDIALOG_INFO, OSDIALOG_OK_CANCEL, "Overwrite template patch?"))
return;

save(asset::user("template.vcv"));
} }


bool PatchManager::load(std::string path) { bool PatchManager::load(std::string path) {
@@ -174,6 +178,9 @@ bool PatchManager::load(std::string path) {
} }


void PatchManager::loadDialog() { void PatchManager::loadDialog() {
if (!(APP->history->isSaved() || osdialog_message(OSDIALOG_INFO, OSDIALOG_OK_CANCEL, "The current patch is unsaved. Clear it and open a new patch?")))
return;

std::string dir; std::string dir;
if (path.empty()) { if (path.empty()) {
dir = asset::user("patches"); dir = asset::user("patches");
@@ -194,26 +201,26 @@ void PatchManager::loadDialog() {
return; return;
} }
DEFER({ DEFER({
free(pathC);
std::free(pathC);
}); });


load(pathC); load(pathC);
path = pathC; path = pathC;
APP->history->setSaved();
} }


void PatchManager::revertDialog() { void PatchManager::revertDialog() {
if (path.empty()) if (path.empty())
return; return;
if (osdialog_message(OSDIALOG_INFO, OSDIALOG_OK_CANCEL, "Revert patch to the last saved state?")) {
load(path);
}

if (!(APP->history->isSaved() || osdialog_message(OSDIALOG_INFO, OSDIALOG_OK_CANCEL, "Revert patch to the last saved state?")))
return;

load(path);
APP->history->setSaved();
} }


void PatchManager::disconnectDialog() { void PatchManager::disconnectDialog() {
// Since we have undo history, no need for a warning.
// if (!osdialog_message(OSDIALOG_WARNING, OSDIALOG_OK_CANCEL, "Remove all patch cables?"))
// return;

APP->scene->rack->clearCablesAction(); APP->scene->rack->clearCablesAction();
} }




+ 2
- 0
src/window.cpp View File

@@ -325,6 +325,8 @@ void Window::run() {
windowTitle += app::APP_VERSION; windowTitle += app::APP_VERSION;
if (!APP->patch->path.empty()) { if (!APP->patch->path.empty()) {
windowTitle += " - "; windowTitle += " - ";
if (!APP->history->isSaved())
windowTitle += "*";
windowTitle += string::filename(APP->patch->path); windowTitle += string::filename(APP->patch->path);
} }
if (windowTitle != internal->lastWindowTitle) { if (windowTitle != internal->lastWindowTitle) {


Loading…
Cancel
Save