17 std::unique_ptr<UndoAction> definitions,
20 std::string description)
21 : resource_(std::move(resource)),
22 before_(plan.resource_before),
23 after_(plan.resource_after),
24 palettes_(plan.palette_changes),
25 definitions_(std::move(definitions)),
27 refresh_(std::move(refresh)),
28 description_(std::move(description)) {}
40 absl::Status
Apply(
bool forward) {
42 return absl::FailedPreconditionError(
43 "Import rollback failed; reload the document");
44 if (forward == applied_)
45 return absl::FailedPreconditionError(
46 "Import action is already in that state");
47 const auto& expected = forward ? before_ : after_;
48 const auto& desired = forward ? after_ : before_;
50 if (current != expected) {
51 return absl::FailedPreconditionError(
52 "Graphics resource changed since import planning");
54 auto changes = palettes_;
56 for (
auto& change : changes)
57 std::swap(change.original_color, change.new_color);
59 bool participated =
false;
60 bool resource_applied =
false;
61 bool definitions_applied =
false;
62 std::string rollback_errors;
63 auto record_rollback = [&](
const absl::Status& status,
const char* phase) {
65 absl::StrAppend(&rollback_errors,
"; ", phase,
": ", status.message());
69 auto rollback = [&](
const absl::Status& failure) -> absl::Status {
70 if (definitions_applied) {
71 record_rollback(forward ? definitions_->Undo() : definitions_->Redo(),
72 "definition rollback");
75 record_rollback(resource_.replace(expected),
"resource rollback");
76 return rollback_errors.empty() ? failure
77 : absl::InternalError(absl::StrCat(
78 failure.message(), rollback_errors));
80 const auto status = gfx::PaletteManager::Get().ApplyExternalChanges(
81 owner_, changes, [&]() -> absl::Status {
83 if (expected != desired) {
84 const auto replaced = resource_.replace(desired);
86 return rollback(replaced);
87 resource_applied =
true;
89 const auto source_refreshed = refresh_();
90 if (!source_refreshed.ok())
91 return rollback(source_refreshed);
94 forward ? definitions_->Redo() : definitions_->Undo();
96 return rollback(defined);
97 definitions_applied =
true;
99 const auto view_refreshed = refresh_();
100 if (!view_refreshed.ok())
101 return rollback(view_refreshed);
102 return absl::OkStatus();
108 const auto restored = refresh_();
109 if (!restored.ok()) {
111 return absl::InternalError(
112 absl::StrCat(status.message(),
113 "; restored-view refresh: ", restored.message()));
119 return absl::OkStatus();