From be94ab70f4377efecd980ce4f7ce2dbf418f5954 Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Sun, 14 Oct 2012 18:57:57 -0700 Subject: [PATCH] Extract cut/copy/delete lines logic from SubtitlesGrid --- aegisub/src/command/edit.cpp | 80 +++++++++++++++++++++++++++++++--- aegisub/src/frame_main.cpp | 2 +- aegisub/src/subs_grid.cpp | 84 +----------------------------------- aegisub/src/subs_grid.h | 15 +------ 4 files changed, 77 insertions(+), 104 deletions(-) diff --git a/aegisub/src/command/edit.cpp b/aegisub/src/command/edit.cpp index bbac439a4..35c816376 100644 --- a/aegisub/src/command/edit.cpp +++ b/aegisub/src/command/edit.cpp @@ -484,6 +484,71 @@ struct edit_find_replace : public Command { } }; +static void copy_lines(agi::Context *c) { + wxString data; + SubtitleSelection sel = c->selectionController->GetSelectedSet(); + for (entryIter it = c->ass->Line.begin(); it != c->ass->Line.end(); ++it) { + AssDialogue *diag = dynamic_cast(*it); + if (diag && sel.count(diag)) { + if (!data.empty()) + data += "\r\n"; + data += diag->GetEntryData(); + } + } + + if (wxTheClipboard->Open()) { + wxTheClipboard->SetData(new wxTextDataObject(data)); + wxTheClipboard->Close(); + } +} + +static void delete_lines(agi::Context *c, wxString const& commit_message) { + AssDialogue *active = c->selectionController->GetActiveLine(); + SubtitleSelection sel = c->selectionController->GetSelectedSet(); + + // Find a line near the active line not being deleted to make the new active line + AssDialogue *new_active = 0; + bool hit_active = false; + + for (entryIter it = c->ass->Line.begin(); it != c->ass->Line.end(); ++it) { + AssDialogue *diag = dynamic_cast(*it); + if (!diag) continue; + + if (diag == active) { + hit_active = true; + if (new_active) break; + } + + if (!sel.count(diag)) { + new_active = diag; + if (hit_active) break; + } + } + + // Delete selected lines + for (entryIter it = c->ass->Line.begin(); it != c->ass->Line.end(); ) { + if (sel.count(static_cast(*it))) { + delete *it; + c->ass->Line.erase(it++); + } + else + ++it; + } + + // If we didn't get a new active line then we just deleted all the dialogue + // lines, so make a new one + if (!new_active) { + new_active = new AssDialogue; + c->ass->InsertDialogue(new_active); + } + + c->ass->Commit(commit_message, AssFile::COMMIT_DIAG_ADDREM); + + sel.clear(); + sel.insert(new_active); + c->selectionController->SetSelectionAndActive(sel, new_active); +} + /// Copy subtitles. struct edit_line_copy : public validate_sel_nonempty { CMD_NAME("edit/line/copy") @@ -501,12 +566,12 @@ struct edit_line_copy : public validate_sel_nonempty { if (wxTextEntryBase *ctrl = dynamic_cast(c->parent->FindFocus())) ctrl->Copy(); - else - c->subsGrid->CopyLines(c->subsGrid->GetSelection()); + else { + copy_lines(c); + } } }; - /// Cut subtitles. struct edit_line_cut: public validate_sel_nonempty { CMD_NAME("edit/line/cut") @@ -517,12 +582,13 @@ struct edit_line_cut: public validate_sel_nonempty { void operator()(agi::Context *c) { if (wxTextEntryBase *ctrl = dynamic_cast(c->parent->FindFocus())) ctrl->Cut(); - else - c->subsGrid->CutLines(c->subsGrid->GetSelection()); + else { + copy_lines(c); + delete_lines(c, _("cut lines")); + } } }; - /// Delete currently selected lines. struct edit_line_delete : public validate_sel_nonempty { CMD_NAME("edit/line/delete") @@ -531,7 +597,7 @@ struct edit_line_delete : public validate_sel_nonempty { STR_HELP("Delete currently selected lines") void operator()(agi::Context *c) { - c->subsGrid->DeleteLines(c->subsGrid->GetSelection()); + delete_lines(c, _("delete lines")); } }; diff --git a/aegisub/src/frame_main.cpp b/aegisub/src/frame_main.cpp index 8c5569f5d..dae5ec74e 100644 --- a/aegisub/src/frame_main.cpp +++ b/aegisub/src/frame_main.cpp @@ -377,7 +377,7 @@ void FrameMain::InitContents() { wxPanel *Panel = new wxPanel(this,-1,wxDefaultPosition,wxDefaultSize,wxTAB_TRAVERSAL | wxCLIP_CHILDREN); StartupLog("Create subtitles grid"); - context->subsGrid = SubsGrid = new SubtitlesGrid(Panel,context.get(),wxSize(600,100),wxWANTS_CHARS | wxSUNKEN_BORDER,"Subs grid"); + context->subsGrid = SubsGrid = new SubtitlesGrid(Panel, context.get()); context->selectionController = context->subsGrid; Search.context = context.get(); diff --git a/aegisub/src/subs_grid.cpp b/aegisub/src/subs_grid.cpp index 08d865ee8..df9b305eb 100644 --- a/aegisub/src/subs_grid.cpp +++ b/aegisub/src/subs_grid.cpp @@ -56,8 +56,8 @@ #include "utils.h" #include "video_context.h" -SubtitlesGrid::SubtitlesGrid(wxWindow *parent, agi::Context *context, const wxSize& size, long style, const wxString& name) -: BaseGrid(parent,context,size,style,name) +SubtitlesGrid::SubtitlesGrid(wxWindow *parent, agi::Context *context) +: BaseGrid(parent, context, wxDefaultSize, wxWANTS_CHARS | wxSUNKEN_BORDER) { } @@ -161,86 +161,6 @@ void SubtitlesGrid::RecombineLines() { context->ass->Commit(_("combining"), AssFile::COMMIT_DIAG_ADDREM | AssFile::COMMIT_DIAG_FULL); } -/// @brief Insert a line -/// @param line -/// @param n -/// @param after -/// @param update -void SubtitlesGrid::InsertLine(AssDialogue *line,int n,bool after,bool update) { - AssDialogue *rel_line = GetDialogue(n); - entryIter pos = std::find(context->ass->Line.begin(), context->ass->Line.end(), rel_line); - if (after) ++pos; - - context->ass->Line.insert(pos,line); - - // Update - if (update) { - context->ass->Commit(_("line insertion"), AssFile::COMMIT_DIAG_ADDREM); - } - else { - UpdateMaps(); - } -} - -void SubtitlesGrid::CopyLines(wxArrayInt target) { - // Prepare text - wxString data; - AssDialogue *cur; - int nrows = target.Count(); - bool first = true; - for (int i=0;iGetEntryData(); - } - - // Send to clipboard - if (wxTheClipboard->Open()) { - wxTheClipboard->SetData(new wxTextDataObject(data)); - wxTheClipboard->Close(); - } -} - -void SubtitlesGrid::CutLines(wxArrayInt target) { - BeginBatch(); - CopyLines(target); - DeleteLines(target); - EndBatch(); -} - -void SubtitlesGrid::DeleteLines(wxArrayInt target, bool flagModified) { - entryIter before_first = std::find_if(context->ass->Line.begin(), context->ass->Line.end(), cast()); --before_first; - - int row = -1; - size_t deleted = 0; - for (entryIter cur = context->ass->Line.begin(); cur != context->ass->Line.end();) { - if (dynamic_cast(*cur) && ++row == target[deleted]) { - delete *cur; - cur = context->ass->Line.erase(cur); - ++deleted; - if (deleted == target.size()) break; - } - else { - ++cur; - } - } - - // Add default line if file was wiped - if ((size_t)GetRows() == deleted) { - AssDialogue *def = new AssDialogue; - ++before_first; - context->ass->Line.insert(before_first, def); - } - - if (flagModified) { - context->ass->Commit(_("delete"), AssFile::COMMIT_DIAG_ADDREM); - } - else { - UpdateMaps(); - } -} - void SubtitlesGrid::AdjoinLines(int n1,int n2,bool setStart) { if (n1 == n2) { if (setStart) { diff --git a/aegisub/src/subs_grid.h b/aegisub/src/subs_grid.h index 9ac9538d1..5945846b0 100644 --- a/aegisub/src/subs_grid.h +++ b/aegisub/src/subs_grid.h @@ -50,7 +50,7 @@ /// DOCME class SubtitlesGrid: public BaseGrid { public: - SubtitlesGrid(wxWindow *parent, agi::Context *context, const wxSize& size = wxDefaultSize, long style = wxWANTS_CHARS, const wxString& name = wxPanelNameStr); + SubtitlesGrid(wxWindow *parent, agi::Context *context); /// @brief Adjoins selected lines, setting each line's start time to the previous line's end time /// @param n1 First line to adjoin @@ -58,19 +58,6 @@ public: /// @param setStart Set the start times (rather than end times) void AdjoinLines(int first,int last,bool setStart); - void InsertLine(AssDialogue *line,int position,bool insertAfter,bool update=true); - /// @brief Delete selected lines - /// @param target Lines to delete - /// @param flagModified Commit the file afterwards - void DeleteLines(wxArrayInt lines, bool flagModified=true); - - /// @brief Copy to clipboard - /// @param target Lines to copy - void CopyLines(wxArrayInt lines); - /// @brief Cut to clipboard - /// @param target Lines to cut - void CutLines(wxArrayInt lines); - void RecombineLines(); /// Retrieve a list of selected lines in the actual ASS file (i.e. not as displayed in the grid but as represented in the file)