mirror of https://github.com/odrling/Aegisub
Extract cut/copy/delete lines logic from SubtitlesGrid
This commit is contained in:
parent
8aeb611745
commit
be94ab70f4
|
@ -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.
|
/// Copy subtitles.
|
||||||
struct edit_line_copy : public validate_sel_nonempty {
|
struct edit_line_copy : public validate_sel_nonempty {
|
||||||
CMD_NAME("edit/line/copy")
|
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()))
|
if (wxTextEntryBase *ctrl = dynamic_cast<wxTextEntryBase*>(c->parent->FindFocus()))
|
||||||
ctrl->Copy();
|
ctrl->Copy();
|
||||||
else
|
else {
|
||||||
c->subsGrid->CopyLines(c->subsGrid->GetSelection());
|
copy_lines(c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/// Cut subtitles.
|
/// Cut subtitles.
|
||||||
struct edit_line_cut: public validate_sel_nonempty {
|
struct edit_line_cut: public validate_sel_nonempty {
|
||||||
CMD_NAME("edit/line/cut")
|
CMD_NAME("edit/line/cut")
|
||||||
|
@ -517,12 +582,13 @@ struct edit_line_cut: public validate_sel_nonempty {
|
||||||
void operator()(agi::Context *c) {
|
void operator()(agi::Context *c) {
|
||||||
if (wxTextEntryBase *ctrl = dynamic_cast<wxTextEntryBase*>(c->parent->FindFocus()))
|
if (wxTextEntryBase *ctrl = dynamic_cast<wxTextEntryBase*>(c->parent->FindFocus()))
|
||||||
ctrl->Cut();
|
ctrl->Cut();
|
||||||
else
|
else {
|
||||||
c->subsGrid->CutLines(c->subsGrid->GetSelection());
|
copy_lines(c);
|
||||||
|
delete_lines(c, _("cut lines"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/// Delete currently selected lines.
|
/// Delete currently selected lines.
|
||||||
struct edit_line_delete : public validate_sel_nonempty {
|
struct edit_line_delete : public validate_sel_nonempty {
|
||||||
CMD_NAME("edit/line/delete")
|
CMD_NAME("edit/line/delete")
|
||||||
|
@ -531,7 +597,7 @@ struct edit_line_delete : public validate_sel_nonempty {
|
||||||
STR_HELP("Delete currently selected lines")
|
STR_HELP("Delete currently selected lines")
|
||||||
|
|
||||||
void operator()(agi::Context *c) {
|
void operator()(agi::Context *c) {
|
||||||
c->subsGrid->DeleteLines(c->subsGrid->GetSelection());
|
delete_lines(c, _("delete lines"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -377,7 +377,7 @@ void FrameMain::InitContents() {
|
||||||
wxPanel *Panel = new wxPanel(this,-1,wxDefaultPosition,wxDefaultSize,wxTAB_TRAVERSAL | wxCLIP_CHILDREN);
|
wxPanel *Panel = new wxPanel(this,-1,wxDefaultPosition,wxDefaultSize,wxTAB_TRAVERSAL | wxCLIP_CHILDREN);
|
||||||
|
|
||||||
StartupLog("Create subtitles grid");
|
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;
|
context->selectionController = context->subsGrid;
|
||||||
Search.context = context.get();
|
Search.context = context.get();
|
||||||
|
|
||||||
|
|
|
@ -56,8 +56,8 @@
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "video_context.h"
|
#include "video_context.h"
|
||||||
|
|
||||||
SubtitlesGrid::SubtitlesGrid(wxWindow *parent, agi::Context *context, const wxSize& size, long style, const wxString& name)
|
SubtitlesGrid::SubtitlesGrid(wxWindow *parent, agi::Context *context)
|
||||||
: BaseGrid(parent,context,size,style,name)
|
: 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);
|
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) {
|
void SubtitlesGrid::AdjoinLines(int n1,int n2,bool setStart) {
|
||||||
if (n1 == n2) {
|
if (n1 == n2) {
|
||||||
if (setStart) {
|
if (setStart) {
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
/// DOCME
|
/// DOCME
|
||||||
class SubtitlesGrid: public BaseGrid {
|
class SubtitlesGrid: public BaseGrid {
|
||||||
public:
|
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
|
/// @brief Adjoins selected lines, setting each line's start time to the previous line's end time
|
||||||
/// @param n1 First line to adjoin
|
/// @param n1 First line to adjoin
|
||||||
|
@ -58,19 +58,6 @@ public:
|
||||||
/// @param setStart Set the start times (rather than end times)
|
/// @param setStart Set the start times (rather than end times)
|
||||||
void AdjoinLines(int first,int last,bool setStart);
|
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();
|
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)
|
/// 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)
|
||||||
|
|
Loading…
Reference in New Issue