forked from mia/Aegisub
Make pasting lines not horribly slow and bad. Closes #1534.
This commit is contained in:
parent
6e90d9498d
commit
dcbf644820
3 changed files with 92 additions and 104 deletions
|
@ -49,7 +49,9 @@
|
||||||
#include "../ass_dialogue.h"
|
#include "../ass_dialogue.h"
|
||||||
#include "../ass_file.h"
|
#include "../ass_file.h"
|
||||||
#include "../ass_karaoke.h"
|
#include "../ass_karaoke.h"
|
||||||
|
#include "../dialog_paste_over.h"
|
||||||
#include "../dialog_search_replace.h"
|
#include "../dialog_search_replace.h"
|
||||||
|
#include "../main.h"
|
||||||
#include "../include/aegisub/context.h"
|
#include "../include/aegisub/context.h"
|
||||||
#include "../subs_edit_ctrl.h"
|
#include "../subs_edit_ctrl.h"
|
||||||
#include "../subs_grid.h"
|
#include "../subs_grid.h"
|
||||||
|
@ -74,6 +76,94 @@ struct validate_sel_multiple : public Command {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void paste_lines(agi::Context *c, bool paste_over) {
|
||||||
|
wxString data;
|
||||||
|
if (wxTheClipboard->Open()) {
|
||||||
|
if (wxTheClipboard->IsSupported(wxDF_TEXT)) {
|
||||||
|
wxTextDataObject rawdata;
|
||||||
|
wxTheClipboard->GetData(rawdata);
|
||||||
|
data = rawdata.GetText();
|
||||||
|
}
|
||||||
|
wxTheClipboard->Close();
|
||||||
|
}
|
||||||
|
if (!data) return;
|
||||||
|
|
||||||
|
AssDialogue *rel_line = c->selectionController->GetActiveLine();
|
||||||
|
entryIter pos = find(c->ass->Line.begin(), c->ass->Line.end(), rel_line);
|
||||||
|
|
||||||
|
AssDialogue *first = 0;
|
||||||
|
std::set<AssDialogue *> newsel;
|
||||||
|
|
||||||
|
std::vector<bool> pasteOverOptions;
|
||||||
|
wxStringTokenizer token (data,"\r\n",wxTOKEN_STRTOK);
|
||||||
|
while (token.HasMoreTokens()) {
|
||||||
|
// Convert data into an AssDialogue
|
||||||
|
wxString curdata = token.GetNextToken();
|
||||||
|
curdata.Trim(true);
|
||||||
|
curdata.Trim(false);
|
||||||
|
AssDialogue *curdiag;
|
||||||
|
try {
|
||||||
|
// Try to interpret the line as an ASS line
|
||||||
|
curdiag = new AssDialogue(curdata);
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
// Line didn't parse correctly, assume it's plain text that
|
||||||
|
// should be pasted in the Text field only
|
||||||
|
curdiag = new AssDialogue();
|
||||||
|
curdiag->Text = curdata;
|
||||||
|
// Make sure pasted plain-text lines always are blank-timed
|
||||||
|
curdiag->Start = 0;
|
||||||
|
curdiag->End = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!first)
|
||||||
|
first = curdiag;
|
||||||
|
|
||||||
|
if (!paste_over) {
|
||||||
|
newsel.insert(curdiag);
|
||||||
|
c->ass->Line.insert(pos, curdiag);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Get list of options to paste over, if not asked yet
|
||||||
|
if (pasteOverOptions.empty()) {
|
||||||
|
DialogPasteOver diag(c->parent);
|
||||||
|
if (diag.ShowModal()) {
|
||||||
|
delete curdiag;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pasteOverOptions = OPT_GET("Tool/Paste Lines Over/Fields")->GetListBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
AssDialogue *line = static_cast<AssDialogue *>(*pos);
|
||||||
|
if (pasteOverOptions[0]) line->Layer = curdiag->Layer;
|
||||||
|
if (pasteOverOptions[1]) line->Start = curdiag->Start;
|
||||||
|
if (pasteOverOptions[2]) line->End = curdiag->End;
|
||||||
|
if (pasteOverOptions[3]) line->Style = curdiag->Style;
|
||||||
|
if (pasteOverOptions[4]) line->Actor = curdiag->Actor;
|
||||||
|
if (pasteOverOptions[5]) line->Margin[0] = curdiag->Margin[0];
|
||||||
|
if (pasteOverOptions[6]) line->Margin[1] = curdiag->Margin[1];
|
||||||
|
if (pasteOverOptions[7]) line->Margin[2] = curdiag->Margin[2];
|
||||||
|
if (pasteOverOptions[8]) line->Effect = curdiag->Effect;
|
||||||
|
if (pasteOverOptions[9]) line->Text = curdiag->Text;
|
||||||
|
|
||||||
|
delete curdiag;
|
||||||
|
|
||||||
|
do {
|
||||||
|
++pos;
|
||||||
|
} while (pos != c->ass->Line.end() && !dynamic_cast<AssDialogue*>(*pos));
|
||||||
|
if (pos == c->ass->Line.end())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (first) {
|
||||||
|
c->ass->Commit(_("paste"), paste_over ? AssFile::COMMIT_DIAG_FULL : AssFile::COMMIT_DIAG_ADDREM);
|
||||||
|
|
||||||
|
if (!paste_over)
|
||||||
|
c->selectionController->SetSelectionAndActive(newsel, first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Find and replace words in subtitles.
|
/// Find and replace words in subtitles.
|
||||||
struct edit_find_replace : public Command {
|
struct edit_find_replace : public Command {
|
||||||
CMD_NAME("edit/find_replace")
|
CMD_NAME("edit/find_replace")
|
||||||
|
@ -322,7 +412,7 @@ struct edit_line_paste : public Command {
|
||||||
if (wxTextEntryBase *ctrl = dynamic_cast<wxTextEntryBase*>(c->parent->FindFocus()))
|
if (wxTextEntryBase *ctrl = dynamic_cast<wxTextEntryBase*>(c->parent->FindFocus()))
|
||||||
ctrl->Paste();
|
ctrl->Paste();
|
||||||
else
|
else
|
||||||
c->subsGrid->PasteLines(c->subsGrid->GetFirstSelRow());
|
paste_lines(c, false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -345,7 +435,7 @@ struct edit_line_paste_over : public Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(agi::Context *c) {
|
void operator()(agi::Context *c) {
|
||||||
c->subsGrid->PasteLines(c->subsGrid->GetFirstSelRow(),true);
|
paste_lines(c, true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,6 @@
|
||||||
|
|
||||||
#include "ass_dialogue.h"
|
#include "ass_dialogue.h"
|
||||||
#include "ass_file.h"
|
#include "ass_file.h"
|
||||||
#include "dialog_paste_over.h"
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "video_context.h"
|
#include "video_context.h"
|
||||||
|
@ -210,106 +209,6 @@ void SubtitlesGrid::CutLines(wxArrayInt target) {
|
||||||
EndBatch();
|
EndBatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Paste lines from clipboard
|
|
||||||
/// @param n
|
|
||||||
/// @param pasteOver
|
|
||||||
void SubtitlesGrid::PasteLines(int n,bool pasteOver) {
|
|
||||||
BeginBatch();
|
|
||||||
|
|
||||||
// Prepare text
|
|
||||||
wxString data;
|
|
||||||
|
|
||||||
// Read from clipboard
|
|
||||||
if (wxTheClipboard->Open()) {
|
|
||||||
if (wxTheClipboard->IsSupported(wxDF_TEXT)) {
|
|
||||||
wxTextDataObject rawdata;
|
|
||||||
wxTheClipboard->GetData(rawdata);
|
|
||||||
data = rawdata.GetText();
|
|
||||||
}
|
|
||||||
wxTheClipboard->Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if it actually got anything
|
|
||||||
if (!data.empty()) {
|
|
||||||
// Insert data
|
|
||||||
int inserted = 0;
|
|
||||||
std::vector<bool> pasteOverOptions;
|
|
||||||
wxStringTokenizer token (data,"\r\n",wxTOKEN_STRTOK);
|
|
||||||
while (token.HasMoreTokens()) {
|
|
||||||
// Convert data into an AssDialogue
|
|
||||||
wxString curdata = token.GetNextToken();
|
|
||||||
curdata.Trim(true);
|
|
||||||
curdata.Trim(false);
|
|
||||||
AssDialogue *curdiag;
|
|
||||||
try {
|
|
||||||
// Try to interpret the line as an ASS line
|
|
||||||
curdiag = new AssDialogue(curdata);
|
|
||||||
}
|
|
||||||
catch (...) {
|
|
||||||
// Line didn't parse correctly, assume it's plain text that
|
|
||||||
// should be pasted in the Text field only
|
|
||||||
curdiag = new AssDialogue();
|
|
||||||
curdiag->Text = curdata;
|
|
||||||
// Make sure pasted plain-text lines always are blank-timed
|
|
||||||
curdiag->Start = 0;
|
|
||||||
curdiag->End = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Paste over
|
|
||||||
if (pasteOver) {
|
|
||||||
if (n+inserted < GetRows()) {
|
|
||||||
// Get list of options to paste over, if not asked yet
|
|
||||||
if (pasteOverOptions.empty()) {
|
|
||||||
DialogPasteOver diag(context->parent);
|
|
||||||
if (diag.ShowModal()) {
|
|
||||||
delete curdiag;
|
|
||||||
EndBatch();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pasteOverOptions = OPT_GET("Tool/Paste Lines Over/Fields")->GetListBool();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Paste over
|
|
||||||
AssDialogue *target = GetDialogue(n+inserted);
|
|
||||||
if (pasteOverOptions[0]) target->Layer = curdiag->Layer;
|
|
||||||
if (pasteOverOptions[1]) target->Start = curdiag->Start;
|
|
||||||
if (pasteOverOptions[2]) target->End = curdiag->End;
|
|
||||||
if (pasteOverOptions[3]) target->Style = curdiag->Style;
|
|
||||||
if (pasteOverOptions[4]) target->Actor = curdiag->Actor;
|
|
||||||
if (pasteOverOptions[5]) target->Margin[0] = curdiag->Margin[0];
|
|
||||||
if (pasteOverOptions[6]) target->Margin[1] = curdiag->Margin[1];
|
|
||||||
if (pasteOverOptions[7]) target->Margin[2] = curdiag->Margin[2];
|
|
||||||
if (pasteOverOptions[8]) target->Effect = curdiag->Effect;
|
|
||||||
if (pasteOverOptions[9]) target->Text = curdiag->Text;
|
|
||||||
}
|
|
||||||
delete curdiag;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Paste normally
|
|
||||||
else InsertLine(curdiag,n+inserted,false,false);
|
|
||||||
|
|
||||||
// Increment insertion
|
|
||||||
inserted++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update data post-insertion
|
|
||||||
if (inserted > 0) {
|
|
||||||
context->ass->Commit(_("paste"), pasteOver ? AssFile::COMMIT_DIAG_FULL : AssFile::COMMIT_DIAG_ADDREM);
|
|
||||||
|
|
||||||
// Set selection
|
|
||||||
if (!pasteOver) {
|
|
||||||
Selection newsel;
|
|
||||||
for (int i=n;i<n+inserted;i++) {
|
|
||||||
newsel.insert(GetDialogue(i));
|
|
||||||
}
|
|
||||||
SetSelectedSet(newsel);
|
|
||||||
SetActiveLine(GetDialogue(GetFirstSelRow()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EndBatch();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SubtitlesGrid::DeleteLines(wxArrayInt target, bool flagModified) {
|
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;
|
entryIter before_first = std::find_if(context->ass->Line.begin(), context->ass->Line.end(), cast<AssDialogue*>()); --before_first;
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,6 @@ public:
|
||||||
/// @brief Cut to clipboard
|
/// @brief Cut to clipboard
|
||||||
/// @param target Lines to cut
|
/// @param target Lines to cut
|
||||||
void CutLines(wxArrayInt lines);
|
void CutLines(wxArrayInt lines);
|
||||||
void PasteLines(int pos,bool over=false);
|
|
||||||
|
|
||||||
void RecombineLines();
|
void RecombineLines();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue