mirror of https://github.com/odrling/Aegisub
Merge branch 'folding' into feature
This commit is contained in:
commit
7bc18fec26
|
@ -242,7 +242,7 @@ uint32_t AssFile::AddExtradata(std::string const& key, std::string const& value)
|
||||||
return data.id;
|
return data.id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Extradata.push_back(ExtradataEntry{next_extradata_id, key, value});
|
Extradata.push_back(ExtradataEntry{next_extradata_id, 0, key, value});
|
||||||
return next_extradata_id++; // return old value, then post-increment
|
return next_extradata_id++; // return old value, then post-increment
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,10 +340,16 @@ void AssFile::CleanExtradata() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (ExtradataEntry &e : Extradata) {
|
||||||
|
if (ids_used.count(e.id))
|
||||||
|
e.expiration_counter = 0;
|
||||||
|
else
|
||||||
|
e.expiration_counter++;
|
||||||
|
}
|
||||||
if (ids_used.size() != Extradata.size()) {
|
if (ids_used.size() != Extradata.size()) {
|
||||||
// Erase all no-longer-used extradata entries
|
// Erase all no-longer-used extradata entries
|
||||||
Extradata.erase(std::remove_if(begin(Extradata), end(Extradata), [&](ExtradataEntry const& e) {
|
Extradata.erase(std::remove_if(begin(Extradata), end(Extradata), [&](ExtradataEntry const& e) {
|
||||||
return !ids_used.count(e.id);
|
return e.expiration_counter >= 10;
|
||||||
}), end(Extradata));
|
}), end(Extradata));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,17 +50,11 @@ using EntryList = typename boost::intrusive::make_list<T, boost::intrusive::cons
|
||||||
|
|
||||||
struct ExtradataEntry {
|
struct ExtradataEntry {
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
|
int expiration_counter;
|
||||||
std::string key;
|
std::string key;
|
||||||
std::string value;
|
std::string value;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Both start and end are inclusive
|
|
||||||
struct LineFold {
|
|
||||||
int start;
|
|
||||||
int end;
|
|
||||||
bool collapsed;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct AssFileCommit {
|
struct AssFileCommit {
|
||||||
wxString const& message;
|
wxString const& message;
|
||||||
int *commit_id;
|
int *commit_id;
|
||||||
|
|
|
@ -219,7 +219,7 @@ void AssParser::ParseExtradataLine(std::string const &data) {
|
||||||
|
|
||||||
// ensure next_extradata_id is always at least 1 more than the largest existing id
|
// ensure next_extradata_id is always at least 1 more than the largest existing id
|
||||||
target->next_extradata_id = std::max(id+1, target->next_extradata_id);
|
target->next_extradata_id = std::max(id+1, target->next_extradata_id);
|
||||||
target->Extradata.push_back(ExtradataEntry{id, std::move(key), std::move(value)});
|
target->Extradata.push_back(ExtradataEntry{id, 0, std::move(key), std::move(value)});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,16 +79,13 @@ void FoldController::AddFold(AssDialogue& start, AssDialogue& end, bool collapse
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FoldController::DoForAllFolds(bool action(AssDialogue& line)) {
|
void FoldController::DoForAllFolds(std::function<void(AssDialogue&)> action) {
|
||||||
for (AssDialogue& line : context->ass->Events) {
|
for (AssDialogue& line : context->ass->Events) {
|
||||||
if (line.Fold.valid) {
|
if (line.Fold.valid) {
|
||||||
bool result = action(line);
|
action(line);
|
||||||
UpdateLineExtradata(line);
|
UpdateLineExtradata(line);
|
||||||
if (result)
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FoldController::FixFoldsPreCommit(int type, const AssDialogue *single_line) {
|
void FoldController::FixFoldsPreCommit(int type, const AssDialogue *single_line) {
|
||||||
|
@ -98,24 +95,22 @@ void FoldController::FixFoldsPreCommit(int type, const AssDialogue *single_line)
|
||||||
}
|
}
|
||||||
|
|
||||||
// For each line in lines, applies action() to the opening delimiter of the innermost fold containing this line.
|
// For each line in lines, applies action() to the opening delimiter of the innermost fold containing this line.
|
||||||
// Returns true as soon as any action() call returned true.
|
|
||||||
//
|
//
|
||||||
// In general, this can leave the folds in an inconsistent state, so unless action() is read-only this should always
|
// In general, this can leave the folds in an inconsistent state, so unless action() is read-only this should always
|
||||||
// be followed by a commit.
|
// be followed by a commit.
|
||||||
bool FoldController::DoForFoldsAt(std::vector<AssDialogue *> const& lines, bool action(AssDialogue& line)) {
|
void FoldController::DoForFoldsAt(std::vector<AssDialogue *> const& lines, std::function<void(AssDialogue&)> action) {
|
||||||
|
std::map<int, bool> visited;
|
||||||
for (AssDialogue *line : lines) {
|
for (AssDialogue *line : lines) {
|
||||||
if (line->Fold.parent != nullptr && !(line->Fold.valid && !line->Fold.side)) {
|
if (line->Fold.parent != nullptr && !(line->Fold.valid && !line->Fold.side)) {
|
||||||
line = line->Fold.parent;
|
line = line->Fold.parent;
|
||||||
}
|
}
|
||||||
if (!line->Fold.visited) {
|
if (visited.count(line->Row))
|
||||||
bool result = action(*line);
|
continue;
|
||||||
UpdateLineExtradata(*line);
|
|
||||||
if (result)
|
action(*line);
|
||||||
return true;
|
UpdateLineExtradata(*line);
|
||||||
}
|
visited[line->Row] = true;
|
||||||
line->Fold.visited = true;
|
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FoldController::UpdateFoldInfo() {
|
void FoldController::UpdateFoldInfo() {
|
||||||
|
@ -263,7 +258,6 @@ void FoldController::LinkFolds() {
|
||||||
line->Fold.parent = foldStack.empty() ? nullptr : foldStack.back();
|
line->Fold.parent = foldStack.empty() ? nullptr : foldStack.back();
|
||||||
line->Fold.nextVisible = nullptr;
|
line->Fold.nextVisible = nullptr;
|
||||||
line->Fold.visible = highestFolded > (int) foldStack.size();
|
line->Fold.visible = highestFolded > (int) foldStack.size();
|
||||||
line->Fold.visited = false;
|
|
||||||
line->Fold.visibleRow = visibleRow;
|
line->Fold.visibleRow = visibleRow;
|
||||||
|
|
||||||
if (line->Fold.visible) {
|
if (line->Fold.visible) {
|
||||||
|
@ -299,56 +293,78 @@ int FoldController::GetMaxDepth() {
|
||||||
return maxdepth;
|
return maxdepth;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FoldController::ActionHasFold(AssDialogue& line) { return line.Fold.valid; }
|
|
||||||
|
|
||||||
bool FoldController::ActionClearFold(AssDialogue& line) { line.Fold.extraExists = false; line.Fold.valid = false; return false; }
|
|
||||||
|
|
||||||
bool FoldController::ActionOpenFold(AssDialogue& line) { line.Fold.collapsed = false; return false; }
|
|
||||||
|
|
||||||
bool FoldController::ActionCloseFold(AssDialogue& line) { line.Fold.collapsed = true; return false; }
|
|
||||||
|
|
||||||
bool FoldController::ActionToggleFold(AssDialogue& line) { line.Fold.collapsed = !line.Fold.collapsed; return false; }
|
|
||||||
|
|
||||||
|
|
||||||
void FoldController::ClearAllFolds() {
|
void FoldController::ClearAllFolds() {
|
||||||
FoldController::DoForAllFolds(FoldController::ActionClearFold);
|
DoForAllFolds([&](AssDialogue &line) {
|
||||||
|
line.Fold.extraExists = false; line.Fold.valid = false;
|
||||||
|
});
|
||||||
context->ass->Commit(_("clear all folds"), AssFile::COMMIT_FOLD);
|
context->ass->Commit(_("clear all folds"), AssFile::COMMIT_FOLD);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FoldController::OpenAllFolds() {
|
void FoldController::OpenAllFolds() {
|
||||||
FoldController::DoForAllFolds(FoldController::ActionOpenFold);
|
DoForAllFolds([&](AssDialogue &line) {
|
||||||
|
line.Fold.collapsed = false;
|
||||||
|
});
|
||||||
context->ass->Commit(_("open all folds"), AssFile::COMMIT_FOLD);
|
context->ass->Commit(_("open all folds"), AssFile::COMMIT_FOLD);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FoldController::CloseAllFolds() {
|
void FoldController::CloseAllFolds() {
|
||||||
FoldController::DoForAllFolds(FoldController::ActionCloseFold);
|
DoForAllFolds([&](AssDialogue &line) {
|
||||||
|
line.Fold.collapsed = true;
|
||||||
|
});
|
||||||
context->ass->Commit(_("close all folds"), AssFile::COMMIT_FOLD);
|
context->ass->Commit(_("close all folds"), AssFile::COMMIT_FOLD);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FoldController::HasFolds() {
|
bool FoldController::HasFolds() {
|
||||||
return FoldController::DoForAllFolds(FoldController::ActionHasFold);
|
bool hasfold = false;
|
||||||
|
DoForAllFolds([&](AssDialogue &line) {
|
||||||
|
hasfold = hasfold || line.Fold.valid;
|
||||||
|
});
|
||||||
|
return hasfold;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FoldController::ClearFoldsAt(std::vector<AssDialogue *> const& lines) {
|
void FoldController::ClearFoldsAt(std::vector<AssDialogue *> const& lines) {
|
||||||
FoldController::DoForFoldsAt(lines, FoldController::ActionClearFold);
|
DoForFoldsAt(lines, [&](AssDialogue &line) {
|
||||||
|
line.Fold.extraExists = false; line.Fold.valid = false;
|
||||||
|
if (line.Fold.counterpart) {
|
||||||
|
line.Fold.counterpart->Fold.extraExists = false;
|
||||||
|
line.Fold.counterpart->Fold.valid = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
context->ass->Commit(_("clear folds"), AssFile::COMMIT_FOLD);
|
context->ass->Commit(_("clear folds"), AssFile::COMMIT_FOLD);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FoldController::OpenFoldsAt(std::vector<AssDialogue *> const& lines) {
|
void FoldController::OpenFoldsAt(std::vector<AssDialogue *> const& lines) {
|
||||||
FoldController::DoForFoldsAt(lines, FoldController::ActionOpenFold);
|
DoForFoldsAt(lines, [&](AssDialogue &line) {
|
||||||
|
line.Fold.collapsed = false;
|
||||||
|
if (line.Fold.counterpart)
|
||||||
|
line.Fold.counterpart->Fold.collapsed = line.Fold.collapsed;
|
||||||
|
});
|
||||||
context->ass->Commit(_("open folds"), AssFile::COMMIT_FOLD);
|
context->ass->Commit(_("open folds"), AssFile::COMMIT_FOLD);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FoldController::CloseFoldsAt(std::vector<AssDialogue *> const& lines) {
|
void FoldController::CloseFoldsAt(std::vector<AssDialogue *> const& lines) {
|
||||||
FoldController::DoForFoldsAt(lines, FoldController::ActionCloseFold);
|
DoForFoldsAt(lines, [&](AssDialogue &line) {
|
||||||
|
line.Fold.collapsed = true;
|
||||||
|
if (line.Fold.counterpart)
|
||||||
|
line.Fold.counterpart->Fold.collapsed = line.Fold.collapsed;
|
||||||
|
});
|
||||||
context->ass->Commit(_("close folds"), AssFile::COMMIT_FOLD);
|
context->ass->Commit(_("close folds"), AssFile::COMMIT_FOLD);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FoldController::ToggleFoldsAt(std::vector<AssDialogue *> const& lines) {
|
void FoldController::ToggleFoldsAt(std::vector<AssDialogue *> const& lines) {
|
||||||
FoldController::DoForFoldsAt(lines, FoldController::ActionToggleFold);
|
DoForFoldsAt(lines, [&](AssDialogue &line) {
|
||||||
|
line.Fold.collapsed = !line.Fold.collapsed;
|
||||||
|
if (line.Fold.counterpart)
|
||||||
|
line.Fold.counterpart->Fold.collapsed = line.Fold.collapsed;
|
||||||
|
});
|
||||||
context->ass->Commit(_("toggle folds"), AssFile::COMMIT_FOLD);
|
context->ass->Commit(_("toggle folds"), AssFile::COMMIT_FOLD);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FoldController::AreFoldsAt(std::vector<AssDialogue *> const& lines) {
|
bool FoldController::AreFoldsAt(std::vector<AssDialogue *> const& lines) {
|
||||||
return FoldController::DoForFoldsAt(lines, FoldController::ActionHasFold);
|
bool hasfold = false;
|
||||||
|
DoForFoldsAt(lines, [&](AssDialogue &line) {
|
||||||
|
hasfold = hasfold || line.Fold.valid;
|
||||||
|
});
|
||||||
|
return hasfold;
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,9 +56,6 @@ class FoldInfo {
|
||||||
/// False if a fold is started here, true otherwise.
|
/// False if a fold is started here, true otherwise.
|
||||||
bool side = false;
|
bool side = false;
|
||||||
|
|
||||||
|
|
||||||
// Used in DoForFoldsAt to ensure each line is visited only once
|
|
||||||
bool visited = false;
|
|
||||||
/// Whether the line is currently visible
|
/// Whether the line is currently visible
|
||||||
bool visible = true;
|
bool visible = true;
|
||||||
|
|
||||||
|
@ -106,24 +103,12 @@ class FoldController {
|
||||||
|
|
||||||
void RawAddFold(AssDialogue& start, AssDialogue& end, bool collapsed);
|
void RawAddFold(AssDialogue& start, AssDialogue& end, bool collapsed);
|
||||||
|
|
||||||
bool DoForFoldsAt(std::vector<AssDialogue *> const& lines, bool action(AssDialogue& line));
|
void DoForFoldsAt(std::vector<AssDialogue *> const& lines, std::function<void(AssDialogue&)> action);
|
||||||
|
|
||||||
bool DoForAllFolds(bool action(AssDialogue& line));
|
void DoForAllFolds(std::function<void(AssDialogue&)> action);
|
||||||
|
|
||||||
void FixFoldsPreCommit(int type, const AssDialogue *single_line);
|
void FixFoldsPreCommit(int type, const AssDialogue *single_line);
|
||||||
|
|
||||||
// These are used for the DoForAllFolds action and should not be used as ordinary getters/setters
|
|
||||||
|
|
||||||
static bool ActionHasFold(AssDialogue& line);
|
|
||||||
|
|
||||||
static bool ActionClearFold(AssDialogue& line);
|
|
||||||
|
|
||||||
static bool ActionOpenFold(AssDialogue& line);
|
|
||||||
|
|
||||||
static bool ActionCloseFold(AssDialogue& line);
|
|
||||||
|
|
||||||
static bool ActionToggleFold(AssDialogue& line);
|
|
||||||
|
|
||||||
/// Updates the line's extradata entry from the values in FoldInfo. Used after actions like toggling folds.
|
/// Updates the line's extradata entry from the values in FoldInfo. Used after actions like toggling folds.
|
||||||
void UpdateLineExtradata(AssDialogue& line);
|
void UpdateLineExtradata(AssDialogue& line);
|
||||||
|
|
||||||
|
|
|
@ -150,9 +150,7 @@ struct GridColumnFolds final : GridColumn {
|
||||||
bool OnMouseEvent(AssDialogue *d, agi::Context *c, wxMouseEvent &event) const override {
|
bool OnMouseEvent(AssDialogue *d, agi::Context *c, wxMouseEvent &event) const override {
|
||||||
if ((event.LeftDown() || event.LeftDClick()) && !event.ShiftDown() && !event.CmdDown() && !event.AltDown()) {
|
if ((event.LeftDown() || event.LeftDClick()) && !event.ShiftDown() && !event.CmdDown() && !event.AltDown()) {
|
||||||
if (d->Fold.hasFold() && !d->Fold.isEnd()) {
|
if (d->Fold.hasFold() && !d->Fold.isEnd()) {
|
||||||
std::vector<AssDialogue *> lines;
|
c->foldController->ToggleFoldsAt({d});
|
||||||
lines.push_back(d);
|
|
||||||
c->foldController->ToggleFoldsAt(lines);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue