Extract cut/copy/delete lines logic from SubtitlesGrid

This commit is contained in:
Thomas Goyne 2012-10-14 18:57:57 -07:00
parent 8aeb611745
commit be94ab70f4
4 changed files with 77 additions and 104 deletions

View file

@ -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<AssDialogue*>(*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<AssDialogue*>(*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<AssDialogue*>(*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<wxTextEntryBase*>(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<wxTextEntryBase*>(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"));
}
};

View file

@ -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();

View file

@ -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;i<nrows;i++) {
if (!first) data += "\r\n";
first = false;
cur = GetDialogue(target[i]);
data += cur->GetEntryData();
}
// 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<AssDialogue*>()); --before_first;
int row = -1;
size_t deleted = 0;
for (entryIter cur = context->ass->Line.begin(); cur != context->ass->Line.end();) {
if (dynamic_cast<AssDialogue*>(*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) {

View file

@ -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)