Make pasting lines not horribly slow and bad. Closes #1534.
This commit is contained in:
parent
7410e37e07
commit
610b2a9494
3 changed files with 92 additions and 104 deletions
|
@ -52,7 +52,9 @@
|
|||
#include "../ass_override.h"
|
||||
#include "../ass_style.h"
|
||||
#include "../dialog_colorpicker.h"
|
||||
#include "../dialog_paste_over.h"
|
||||
#include "../dialog_search_replace.h"
|
||||
#include "../main.h"
|
||||
#include "../include/aegisub/context.h"
|
||||
#include "../subs_edit_ctrl.h"
|
||||
#include "../subs_grid.h"
|
||||
|
@ -78,6 +80,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;
|
||||
SubtitleSelection 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);
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T get_value(AssDialogue const& line, int blockn, T initial, wxString const& tag, wxString alt = wxString()) {
|
||||
for (int i = blockn; i >= 0; i--) {
|
||||
|
@ -629,7 +719,7 @@ struct edit_line_paste : public Command {
|
|||
if (wxTextEntryBase *ctrl = dynamic_cast<wxTextEntryBase*>(c->parent->FindFocus()))
|
||||
ctrl->Paste();
|
||||
else
|
||||
c->subsGrid->PasteLines(c->subsGrid->GetFirstSelRow());
|
||||
paste_lines(c, false);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -652,7 +742,7 @@ struct edit_line_paste_over : public Command {
|
|||
}
|
||||
|
||||
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_file.h"
|
||||
#include "dialog_paste_over.h"
|
||||
#include "main.h"
|
||||
#include "utils.h"
|
||||
#include "video_context.h"
|
||||
|
@ -210,106 +209,6 @@ void SubtitlesGrid::CutLines(wxArrayInt target) {
|
|||
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) {
|
||||
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
|
||||
/// @param target Lines to cut
|
||||
void CutLines(wxArrayInt lines);
|
||||
void PasteLines(int pos,bool over=false);
|
||||
|
||||
void RecombineLines();
|
||||
|
||||
|
|
Loading…
Reference in a new issue