Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
// Copyright (c) 2005-2010, Niels Martin Hansen
|
|
|
|
// Copyright (c) 2005-2010, Rodrigo Braz Monteiro
|
|
|
|
// Copyright (c) 2010, Amar Takhar
|
|
|
|
// All rights reserved.
|
|
|
|
//
|
|
|
|
// Redistribution and use in source and binary forms, with or without
|
|
|
|
// modification, are permitted provided that the following conditions are met:
|
|
|
|
//
|
|
|
|
// * Redistributions of source code must retain the above copyright notice,
|
|
|
|
// this list of conditions and the following disclaimer.
|
|
|
|
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
|
|
// this list of conditions and the following disclaimer in the documentation
|
|
|
|
// and/or other materials provided with the distribution.
|
|
|
|
// * Neither the name of the Aegisub Group nor the names of its contributors
|
|
|
|
// may be used to endorse or promote products derived from this software
|
|
|
|
// without specific prior written permission.
|
|
|
|
//
|
|
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
|
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
|
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
// POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
//
|
|
|
|
// Aegisub Project http://www.aegisub.org/
|
|
|
|
|
|
|
|
/// @file edit.cpp
|
|
|
|
/// @brief edit/ commands.
|
|
|
|
/// @ingroup command
|
|
|
|
///
|
|
|
|
|
2011-01-05 19:40:37 +01:00
|
|
|
#include "../config.h"
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
|
|
|
|
#include "command.h"
|
|
|
|
|
2011-01-18 07:01:29 +01:00
|
|
|
#include "../ass_dialogue.h"
|
2011-01-05 19:40:37 +01:00
|
|
|
#include "../ass_file.h"
|
2011-09-28 21:44:07 +02:00
|
|
|
#include "../ass_karaoke.h"
|
2012-10-09 04:07:54 +02:00
|
|
|
#include "../ass_style.h"
|
2012-12-30 00:53:56 +01:00
|
|
|
#include "../compat.h"
|
2012-10-09 04:07:54 +02:00
|
|
|
#include "../dialog_colorpicker.h"
|
2012-10-14 06:21:43 +02:00
|
|
|
#include "../dialog_paste_over.h"
|
2011-01-05 19:40:37 +01:00
|
|
|
#include "../dialog_search_replace.h"
|
|
|
|
#include "../include/aegisub/context.h"
|
2012-10-12 01:46:53 +02:00
|
|
|
#include "../initial_line_state.h"
|
2013-01-07 02:50:09 +01:00
|
|
|
#include "../options.h"
|
2013-01-11 18:35:39 +01:00
|
|
|
#include "../search_replace_engine.h"
|
2013-01-26 02:57:46 +01:00
|
|
|
#include "../subs_controller.h"
|
2011-01-05 19:40:37 +01:00
|
|
|
#include "../subs_edit_ctrl.h"
|
|
|
|
#include "../subs_grid.h"
|
2012-10-09 04:07:54 +02:00
|
|
|
#include "../text_selection_controller.h"
|
2012-10-25 17:13:13 +02:00
|
|
|
#include "../utils.h"
|
2011-01-05 19:40:37 +01:00
|
|
|
#include "../video_context.h"
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
|
2013-01-04 16:01:50 +01:00
|
|
|
#include <libaegisub/of_type_adaptor.h>
|
2013-06-08 06:19:40 +02:00
|
|
|
#include <libaegisub/util.h>
|
2013-01-04 16:01:50 +01:00
|
|
|
|
|
|
|
#include <algorithm>
|
2012-12-07 17:06:03 +01:00
|
|
|
#include <boost/algorithm/string/join.hpp>
|
2013-01-04 16:01:50 +01:00
|
|
|
#include <boost/algorithm/string/predicate.hpp>
|
|
|
|
#include <boost/algorithm/string/trim.hpp>
|
2013-01-10 15:54:41 +01:00
|
|
|
#include <boost/format.hpp>
|
2012-11-03 05:24:11 +01:00
|
|
|
#include <boost/range/adaptor/filtered.hpp>
|
2012-11-05 17:20:58 +01:00
|
|
|
#include <boost/range/adaptor/reversed.hpp>
|
2012-12-02 19:24:49 +01:00
|
|
|
#include <boost/range/adaptor/sliced.hpp>
|
2012-11-03 05:24:11 +01:00
|
|
|
#include <boost/range/adaptor/transformed.hpp>
|
2013-01-04 16:01:50 +01:00
|
|
|
#include <boost/tokenizer.hpp>
|
2012-11-05 17:20:58 +01:00
|
|
|
|
2013-01-04 16:01:50 +01:00
|
|
|
#include <wx/clipbrd.h>
|
|
|
|
#include <wx/fontdlg.h>
|
2012-11-05 17:20:58 +01:00
|
|
|
|
2011-07-15 06:05:01 +02:00
|
|
|
namespace {
|
2012-12-02 19:24:49 +01:00
|
|
|
using namespace boost::adaptors;
|
2011-07-15 06:05:01 +02:00
|
|
|
using cmd::Command;
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
/// @defgroup cmd-edit Editing commands.
|
|
|
|
/// @{
|
|
|
|
|
2011-07-15 06:05:22 +02:00
|
|
|
struct validate_sel_nonempty : public Command {
|
2011-07-15 06:05:56 +02:00
|
|
|
CMD_TYPE(COMMAND_VALIDATE)
|
2011-07-15 06:05:22 +02:00
|
|
|
bool Validate(const agi::Context *c) {
|
|
|
|
return c->selectionController->GetSelectedSet().size() > 0;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct validate_sel_multiple : public Command {
|
2011-07-15 06:05:56 +02:00
|
|
|
CMD_TYPE(COMMAND_VALIDATE)
|
2011-07-15 06:05:22 +02:00
|
|
|
bool Validate(const agi::Context *c) {
|
|
|
|
return c->selectionController->GetSelectedSet().size() > 1;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2013-01-14 01:55:39 +01:00
|
|
|
template<typename Paster>
|
|
|
|
void paste_lines(agi::Context *c, bool paste_over, Paster&& paste_line) {
|
2013-01-04 16:01:50 +01:00
|
|
|
std::string data = GetClipboard();
|
|
|
|
if (data.empty()) return;
|
2012-10-14 06:21:43 +02:00
|
|
|
|
2013-01-14 01:55:39 +01:00
|
|
|
AssDialogue *first = nullptr;
|
2012-10-14 06:21:43 +02:00
|
|
|
SubtitleSelection newsel;
|
|
|
|
|
2013-01-04 16:01:50 +01:00
|
|
|
boost::char_separator<char> sep("\r\n");
|
|
|
|
for (auto curdata : boost::tokenizer<boost::char_separator<char>>(data, sep)) {
|
|
|
|
boost::trim(curdata);
|
2012-10-14 06:21:43 +02:00
|
|
|
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
|
2013-01-14 01:55:39 +01:00
|
|
|
curdiag = new AssDialogue;
|
2013-01-17 23:04:50 +01:00
|
|
|
curdiag->End = 0;
|
2012-10-14 06:21:43 +02:00
|
|
|
curdiag->Text = curdata;
|
|
|
|
}
|
|
|
|
|
2013-01-14 01:55:39 +01:00
|
|
|
AssDialogue *inserted = paste_line(curdiag);
|
|
|
|
if (!inserted)
|
|
|
|
break;
|
2012-10-14 06:21:43 +02:00
|
|
|
|
2013-01-14 01:55:39 +01:00
|
|
|
newsel.insert(inserted);
|
|
|
|
if (!first)
|
|
|
|
first = inserted;
|
2012-10-14 06:21:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (first) {
|
|
|
|
c->ass->Commit(_("paste"), paste_over ? AssFile::COMMIT_DIAG_FULL : AssFile::COMMIT_DIAG_ADDREM);
|
|
|
|
|
|
|
|
if (!paste_over)
|
|
|
|
c->selectionController->SetSelectionAndActive(newsel, first);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-14 01:55:39 +01:00
|
|
|
AssDialogue *paste_over(wxWindow *parent, std::vector<bool>& pasteOverOptions, AssDialogue *new_line, AssDialogue *old_line) {
|
|
|
|
if (pasteOverOptions.empty()) {
|
|
|
|
if (DialogPasteOver(parent).ShowModal()) return nullptr;
|
|
|
|
pasteOverOptions = OPT_GET("Tool/Paste Lines Over/Fields")->GetListBool();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pasteOverOptions[0]) old_line->Layer = new_line->Layer;
|
|
|
|
if (pasteOverOptions[1]) old_line->Start = new_line->Start;
|
|
|
|
if (pasteOverOptions[2]) old_line->End = new_line->End;
|
|
|
|
if (pasteOverOptions[3]) old_line->Style = new_line->Style;
|
|
|
|
if (pasteOverOptions[4]) old_line->Actor = new_line->Actor;
|
|
|
|
if (pasteOverOptions[5]) old_line->Margin[0] = new_line->Margin[0];
|
|
|
|
if (pasteOverOptions[6]) old_line->Margin[1] = new_line->Margin[1];
|
|
|
|
if (pasteOverOptions[7]) old_line->Margin[2] = new_line->Margin[2];
|
|
|
|
if (pasteOverOptions[8]) old_line->Effect = new_line->Effect;
|
|
|
|
if (pasteOverOptions[9]) old_line->Text = new_line->Text;
|
|
|
|
|
|
|
|
return old_line;
|
|
|
|
}
|
|
|
|
|
2013-04-30 05:24:33 +02:00
|
|
|
template<typename T>
|
2012-12-30 00:53:56 +01:00
|
|
|
T get_value(boost::ptr_vector<AssDialogueBlock> const& blocks, int blockn, T initial, std::string const& tag_name, std::string alt = "") {
|
2012-12-02 19:24:49 +01:00
|
|
|
for (auto ovr : blocks | sliced(0, blockn + 1) | reversed | agi::of_type<AssDialogueBlockOverride>()) {
|
2012-12-11 00:32:36 +01:00
|
|
|
for (auto const& tag : ovr->Tags | reversed) {
|
|
|
|
if (tag.Name == tag_name || tag.Name == alt)
|
2013-04-30 05:24:33 +02:00
|
|
|
return tag.Params[0].template Get<T>(initial);
|
2012-10-09 04:07:54 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return initial;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Get the block index in the text of the position
|
2013-01-04 16:01:50 +01:00
|
|
|
int block_at_pos(std::string const& text, int pos) {
|
2012-10-09 04:07:54 +02:00
|
|
|
int n = 0;
|
|
|
|
int max = text.size() - 1;
|
|
|
|
for (int i = 0; i <= pos && i <= max; ++i) {
|
|
|
|
if (i > 0 && text[i] == '{')
|
|
|
|
n++;
|
|
|
|
if (text[i] == '}' && i != max && i != pos && i != pos -1 && (i+1 == max || text[i+1] != '{'))
|
|
|
|
n++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
2012-12-30 00:53:56 +01:00
|
|
|
void set_tag(AssDialogue *line, boost::ptr_vector<AssDialogueBlock> &blocks, std::string const& tag, std::string const& value, int &sel_start, int &sel_end, bool at_end = false) {
|
2012-12-02 19:24:49 +01:00
|
|
|
if (blocks.empty())
|
|
|
|
blocks = line->ParseTags();
|
2012-10-09 04:07:54 +02:00
|
|
|
|
|
|
|
int start = at_end ? sel_end : sel_start;
|
|
|
|
int blockn = block_at_pos(line->Text, start);
|
|
|
|
|
|
|
|
AssDialogueBlockPlain *plain = 0;
|
|
|
|
AssDialogueBlockOverride *ovr = 0;
|
|
|
|
while (blockn >= 0) {
|
2012-12-02 19:24:49 +01:00
|
|
|
AssDialogueBlock *block = &blocks[blockn];
|
2012-10-09 04:07:54 +02:00
|
|
|
if (dynamic_cast<AssDialogueBlockDrawing*>(block))
|
|
|
|
--blockn;
|
2012-12-30 18:04:43 +01:00
|
|
|
else if (dynamic_cast<AssDialogueBlockComment*>(block)) {
|
2012-10-09 04:07:54 +02:00
|
|
|
// Cursor is in a comment block, so try the previous block instead
|
2012-12-30 18:04:43 +01:00
|
|
|
--blockn;
|
|
|
|
start = line->Text.get().rfind('{', start);
|
2012-10-09 04:07:54 +02:00
|
|
|
}
|
2012-12-30 18:04:43 +01:00
|
|
|
else if ((plain = dynamic_cast<AssDialogueBlockPlain*>(block)))
|
|
|
|
break;
|
2012-10-09 04:07:54 +02:00
|
|
|
else {
|
|
|
|
ovr = dynamic_cast<AssDialogueBlockOverride*>(block);
|
|
|
|
assert(ovr);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we didn't hit a suitable block for inserting the override just put
|
|
|
|
// it at the beginning of the line
|
|
|
|
if (blockn < 0)
|
|
|
|
start = 0;
|
|
|
|
|
2012-12-30 00:53:56 +01:00
|
|
|
std::string insert(tag + value);
|
2012-10-09 04:07:54 +02:00
|
|
|
int shift = insert.size();
|
|
|
|
if (plain || blockn < 0) {
|
2013-01-04 16:01:50 +01:00
|
|
|
line->Text = line->Text.get().substr(0, start) + "{" + insert + "}" + line->Text.get().substr(start);
|
2012-10-09 04:07:54 +02:00
|
|
|
shift += 2;
|
2012-12-02 19:24:49 +01:00
|
|
|
blocks = line->ParseTags();
|
2012-10-09 04:07:54 +02:00
|
|
|
}
|
2012-12-02 19:24:49 +01:00
|
|
|
else if (ovr) {
|
2012-12-30 00:53:56 +01:00
|
|
|
std::string alt;
|
2012-10-09 04:07:54 +02:00
|
|
|
if (tag == "\\c") alt = "\\1c";
|
|
|
|
// Remove old of same
|
|
|
|
bool found = false;
|
|
|
|
for (size_t i = 0; i < ovr->Tags.size(); i++) {
|
2012-12-30 00:53:56 +01:00
|
|
|
std::string const& name = ovr->Tags[i].Name;
|
2012-10-09 04:07:54 +02:00
|
|
|
if (tag == name || alt == name) {
|
2012-12-30 00:53:56 +01:00
|
|
|
shift -= ((std::string)ovr->Tags[i]).size();
|
2012-10-09 04:07:54 +02:00
|
|
|
if (found) {
|
|
|
|
ovr->Tags.erase(ovr->Tags.begin() + i);
|
|
|
|
i--;
|
|
|
|
}
|
|
|
|
else {
|
2012-12-11 00:32:36 +01:00
|
|
|
ovr->Tags[i].Params[0].Set(value);
|
2012-10-09 04:07:54 +02:00
|
|
|
found = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!found)
|
|
|
|
ovr->AddTag(insert);
|
|
|
|
|
2012-12-02 19:24:49 +01:00
|
|
|
line->UpdateText(blocks);
|
2012-10-09 04:07:54 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
assert(false);
|
|
|
|
|
2012-10-15 05:35:08 +02:00
|
|
|
if (!at_end) {
|
|
|
|
sel_start += shift;
|
|
|
|
sel_end += shift;
|
|
|
|
}
|
2012-10-09 04:07:54 +02:00
|
|
|
}
|
|
|
|
|
2012-10-15 05:35:08 +02:00
|
|
|
void commit_text(agi::Context const * const c, wxString const& desc, int sel_start = -1, int sel_end = -1, int *commit_id = 0) {
|
2012-10-09 04:07:54 +02:00
|
|
|
SubtitleSelection const& sel = c->selectionController->GetSelectedSet();
|
2013-01-04 16:01:50 +01:00
|
|
|
std::string text = c->selectionController->GetActiveLine()->Text;
|
2012-12-02 19:24:49 +01:00
|
|
|
for_each(sel.begin(), sel.end(), [&](AssDialogue *d) { d->Text = text; });
|
|
|
|
|
2012-10-09 04:07:54 +02:00
|
|
|
int new_commit_id = c->ass->Commit(desc, AssFile::COMMIT_DIAG_TEXT, commit_id ? *commit_id : -1, sel.size() == 1 ? *sel.begin() : 0);
|
|
|
|
if (commit_id)
|
|
|
|
*commit_id = new_commit_id;
|
2012-10-15 05:35:08 +02:00
|
|
|
if (sel_start >= 0 && sel_end >= 0)
|
|
|
|
c->textSelectionController->SetSelection(sel_start, sel_end);
|
2012-10-09 04:07:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void toggle_override_tag(const agi::Context *c, bool (AssStyle::*field), const char *tag, wxString const& undo_msg) {
|
|
|
|
AssDialogue *const line = c->selectionController->GetActiveLine();
|
2013-01-04 16:01:50 +01:00
|
|
|
AssStyle const* const style = c->ass->GetStyle(line->Style);
|
2012-10-09 04:07:54 +02:00
|
|
|
bool state = style ? style->*field : AssStyle().*field;
|
|
|
|
|
2012-12-02 19:24:49 +01:00
|
|
|
boost::ptr_vector<AssDialogueBlock> blocks(line->ParseTags());
|
2012-10-09 04:07:54 +02:00
|
|
|
int sel_start = c->textSelectionController->GetSelectionStart();
|
|
|
|
int sel_end = c->textSelectionController->GetSelectionEnd();
|
|
|
|
int blockn = block_at_pos(line->Text, sel_start);
|
|
|
|
|
2012-12-02 19:24:49 +01:00
|
|
|
state = get_value(blocks, blockn, state, tag);
|
2012-10-09 04:07:54 +02:00
|
|
|
|
2012-12-02 19:24:49 +01:00
|
|
|
set_tag(line, blocks, tag, state ? "0" : "1", sel_start, sel_end);
|
2012-10-09 04:07:54 +02:00
|
|
|
if (sel_start != sel_end)
|
2012-12-02 19:24:49 +01:00
|
|
|
set_tag(line, blocks, tag, state ? "1" : "0", sel_start, sel_end, true);
|
2012-10-09 04:07:54 +02:00
|
|
|
|
2012-10-15 05:35:08 +02:00
|
|
|
commit_text(c, undo_msg, sel_start, sel_end);
|
2012-10-09 04:07:54 +02:00
|
|
|
}
|
|
|
|
|
2013-01-10 15:54:41 +01:00
|
|
|
void show_color_picker(const agi::Context *c, agi::Color (AssStyle::*field), const char *tag, const char *alt, const char *alpha) {
|
2012-10-09 04:07:54 +02:00
|
|
|
AssDialogue *const line = c->selectionController->GetActiveLine();
|
2013-01-04 16:01:50 +01:00
|
|
|
AssStyle const* const style = c->ass->GetStyle(line->Style);
|
2012-10-26 16:09:14 +02:00
|
|
|
agi::Color color = (style ? style->*field : AssStyle().*field);
|
2012-10-09 04:07:54 +02:00
|
|
|
|
2012-12-02 19:24:49 +01:00
|
|
|
boost::ptr_vector<AssDialogueBlock> blocks(line->ParseTags());
|
2012-10-09 04:07:54 +02:00
|
|
|
int sel_start = c->textSelectionController->GetSelectionStart();
|
|
|
|
int sel_end = c->textSelectionController->GetSelectionEnd();
|
|
|
|
int blockn = block_at_pos(line->Text, sel_start);
|
2012-12-02 19:24:49 +01:00
|
|
|
int initial_sel_start = sel_start, initial_sel_end = sel_end;
|
2012-10-09 04:07:54 +02:00
|
|
|
|
2013-01-14 05:33:49 +01:00
|
|
|
int a = get_value(blocks, blockn, (int)color.a, alpha, "\\alpha");
|
2012-12-02 19:24:49 +01:00
|
|
|
color = get_value(blocks, blockn, color, tag, alt);
|
2013-01-14 05:33:49 +01:00
|
|
|
color.a = a;
|
2012-10-09 04:07:54 +02:00
|
|
|
int commit_id = -1;
|
2013-01-13 20:19:13 +01:00
|
|
|
bool ok = GetColorFromUser(c->parent, color, true, [&](agi::Color new_color) {
|
2012-12-02 19:24:49 +01:00
|
|
|
set_tag(line, blocks, tag, new_color.GetAssOverrideFormatted(), sel_start, sel_end);
|
2013-01-13 20:24:45 +01:00
|
|
|
if (new_color.a != color.a) {
|
|
|
|
set_tag(line, blocks, alpha, str(boost::format("&H%02X&") % (int)new_color.a), sel_start, sel_end);
|
|
|
|
color.a = new_color.a;
|
|
|
|
}
|
2012-12-02 19:24:49 +01:00
|
|
|
commit_text(c, _("set color"), sel_start, sel_end, &commit_id);
|
|
|
|
});
|
2012-10-15 05:35:08 +02:00
|
|
|
commit_text(c, _("set color"), -1, -1, &commit_id);
|
2012-10-09 04:07:54 +02:00
|
|
|
|
2012-10-26 16:09:14 +02:00
|
|
|
if (!ok) {
|
2013-01-26 02:57:46 +01:00
|
|
|
c->subsController->Undo();
|
2012-12-02 19:24:49 +01:00
|
|
|
c->textSelectionController->SetSelection(initial_sel_start, initial_sel_end);
|
2012-10-09 04:07:54 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct edit_color_primary : public Command {
|
|
|
|
CMD_NAME("edit/color/primary")
|
|
|
|
STR_MENU("Primary Color...")
|
|
|
|
STR_DISP("Primary Color")
|
2013-03-31 17:07:18 +02:00
|
|
|
STR_HELP("Set the primary fill color (\\c) at the cursor position")
|
2012-10-09 04:07:54 +02:00
|
|
|
|
|
|
|
void operator()(agi::Context *c) {
|
2013-01-10 15:54:41 +01:00
|
|
|
show_color_picker(c, &AssStyle::primary, "\\c", "\\1c", "\\1a");
|
2012-10-09 04:07:54 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct edit_color_secondary : public Command {
|
|
|
|
CMD_NAME("edit/color/secondary")
|
|
|
|
STR_MENU("Secondary Color...")
|
|
|
|
STR_DISP("Secondary Color")
|
2013-03-31 17:07:18 +02:00
|
|
|
STR_HELP("Set the secondary (karaoke) fill color (\\2c) at the cursor position")
|
2012-10-09 04:07:54 +02:00
|
|
|
|
|
|
|
void operator()(agi::Context *c) {
|
2013-01-10 15:54:41 +01:00
|
|
|
show_color_picker(c, &AssStyle::secondary, "\\2c", "", "\\2a");
|
2012-10-09 04:07:54 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct edit_color_outline : public Command {
|
|
|
|
CMD_NAME("edit/color/outline")
|
|
|
|
STR_MENU("Outline Color...")
|
|
|
|
STR_DISP("Outline Color")
|
2013-03-31 17:07:18 +02:00
|
|
|
STR_HELP("Set the outline color (\\3c) at the cursor position")
|
2012-10-09 04:07:54 +02:00
|
|
|
|
|
|
|
void operator()(agi::Context *c) {
|
2013-01-10 15:54:41 +01:00
|
|
|
show_color_picker(c, &AssStyle::outline, "\\3c", "", "\\3a");
|
2012-10-09 04:07:54 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct edit_color_shadow : public Command {
|
|
|
|
CMD_NAME("edit/color/shadow")
|
|
|
|
STR_MENU("Shadow Color...")
|
|
|
|
STR_DISP("Shadow Color")
|
2013-03-31 17:07:18 +02:00
|
|
|
STR_HELP("Set the shadow color (\\4c) at the cursor position")
|
2012-10-09 04:07:54 +02:00
|
|
|
|
|
|
|
void operator()(agi::Context *c) {
|
2013-01-10 15:54:41 +01:00
|
|
|
show_color_picker(c, &AssStyle::shadow, "\\4c", "", "\\4a");
|
2012-10-09 04:07:54 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct edit_style_bold : public Command {
|
|
|
|
CMD_NAME("edit/style/bold")
|
2013-03-31 17:07:18 +02:00
|
|
|
STR_MENU("Toggle Bold")
|
|
|
|
STR_DISP("Toggle Bold")
|
|
|
|
STR_HELP("Toggle bold (\\b) for the current selection or at the current cursor position")
|
2012-10-09 04:07:54 +02:00
|
|
|
|
|
|
|
void operator()(agi::Context *c) {
|
|
|
|
toggle_override_tag(c, &AssStyle::bold, "\\b", _("toggle bold"));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct edit_style_italic : public Command {
|
|
|
|
CMD_NAME("edit/style/italic")
|
2013-03-31 17:07:18 +02:00
|
|
|
STR_MENU("Toggle Italics")
|
|
|
|
STR_DISP("Toggle Italics")
|
|
|
|
STR_HELP("Toggle italics (\\i) for the current selection or at the current cursor position")
|
2012-10-09 04:07:54 +02:00
|
|
|
|
|
|
|
void operator()(agi::Context *c) {
|
|
|
|
toggle_override_tag(c, &AssStyle::italic, "\\i", _("toggle italic"));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct edit_style_underline : public Command {
|
|
|
|
CMD_NAME("edit/style/underline")
|
2013-03-31 17:07:18 +02:00
|
|
|
STR_MENU("Toggle Underline")
|
|
|
|
STR_DISP("Toggle Underline")
|
|
|
|
STR_HELP("Toggle underline (\\u) for the current selection or at the current cursor position")
|
2012-10-09 04:07:54 +02:00
|
|
|
|
|
|
|
void operator()(agi::Context *c) {
|
|
|
|
toggle_override_tag(c, &AssStyle::underline, "\\u", _("toggle underline"));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct edit_style_strikeout : public Command {
|
|
|
|
CMD_NAME("edit/style/strikeout")
|
2013-03-31 17:07:18 +02:00
|
|
|
STR_MENU("Toggle Strikeout")
|
|
|
|
STR_DISP("Toggle Strikeout")
|
|
|
|
STR_HELP("Toggle strikeout (\\s) for the current selection or at the current cursor position")
|
2012-10-09 04:07:54 +02:00
|
|
|
|
|
|
|
void operator()(agi::Context *c) {
|
|
|
|
toggle_override_tag(c, &AssStyle::strikeout, "\\s", _("toggle strikeout"));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct edit_font : public Command {
|
|
|
|
CMD_NAME("edit/font")
|
|
|
|
STR_MENU("Font Face...")
|
|
|
|
STR_DISP("Font Face")
|
2013-03-31 17:07:18 +02:00
|
|
|
STR_HELP("Select a font face and size")
|
2012-10-09 04:07:54 +02:00
|
|
|
|
|
|
|
void operator()(agi::Context *c) {
|
|
|
|
AssDialogue *const line = c->selectionController->GetActiveLine();
|
2012-12-02 19:24:49 +01:00
|
|
|
boost::ptr_vector<AssDialogueBlock> blocks(line->ParseTags());
|
2012-10-09 04:07:54 +02:00
|
|
|
const int blockn = block_at_pos(line->Text, c->textSelectionController->GetInsertionPoint());
|
|
|
|
|
2013-01-04 16:01:50 +01:00
|
|
|
const AssStyle *style = c->ass->GetStyle(line->Style);
|
2012-10-09 04:07:54 +02:00
|
|
|
const AssStyle default_style;
|
|
|
|
if (!style)
|
|
|
|
style = &default_style;
|
|
|
|
|
2012-10-15 05:35:08 +02:00
|
|
|
int sel_start = c->textSelectionController->GetSelectionStart();
|
|
|
|
int sel_end = c->textSelectionController->GetSelectionEnd();
|
|
|
|
|
2012-10-09 04:07:54 +02:00
|
|
|
const wxFont startfont(
|
2012-12-02 19:24:49 +01:00
|
|
|
get_value(blocks, blockn, (int)style->fontsize, "\\fs"),
|
2012-10-09 04:07:54 +02:00
|
|
|
wxFONTFAMILY_DEFAULT,
|
2012-12-02 19:24:49 +01:00
|
|
|
get_value(blocks, blockn, style->italic, "\\i") ? wxFONTSTYLE_ITALIC : wxFONTSTYLE_NORMAL,
|
|
|
|
get_value(blocks, blockn, style->bold, "\\b") ? wxFONTWEIGHT_BOLD : wxFONTWEIGHT_NORMAL,
|
|
|
|
get_value(blocks, blockn, style->underline, "\\u"),
|
2013-01-04 16:01:50 +01:00
|
|
|
to_wx(get_value(blocks, blockn, style->font, "\\fn")));
|
2012-10-09 04:07:54 +02:00
|
|
|
|
|
|
|
const wxFont font = wxGetFontFromUser(c->parent, startfont);
|
2012-12-02 19:24:49 +01:00
|
|
|
if (!font.Ok() || font == startfont) return;
|
2012-10-09 04:07:54 +02:00
|
|
|
|
|
|
|
if (font.GetFaceName() != startfont.GetFaceName())
|
2012-12-30 00:53:56 +01:00
|
|
|
set_tag(line, blocks, "\\fn", from_wx(font.GetFaceName()), sel_start, sel_end);
|
2012-10-09 04:07:54 +02:00
|
|
|
if (font.GetPointSize() != startfont.GetPointSize())
|
2012-12-30 00:53:56 +01:00
|
|
|
set_tag(line, blocks, "\\fs", std::to_string(font.GetPointSize()), sel_start, sel_end);
|
2012-10-09 04:07:54 +02:00
|
|
|
if (font.GetWeight() != startfont.GetWeight())
|
2012-12-30 00:53:56 +01:00
|
|
|
set_tag(line, blocks, "\\b", std::to_string(font.GetWeight() == wxFONTWEIGHT_BOLD), sel_start, sel_end);
|
2012-10-09 04:07:54 +02:00
|
|
|
if (font.GetStyle() != startfont.GetStyle())
|
2012-12-30 00:53:56 +01:00
|
|
|
set_tag(line, blocks, "\\i", std::to_string(font.GetStyle() == wxFONTSTYLE_ITALIC), sel_start, sel_end);
|
2012-10-09 04:07:54 +02:00
|
|
|
if (font.GetUnderlined() != startfont.GetUnderlined())
|
2012-12-30 00:53:56 +01:00
|
|
|
set_tag(line, blocks, "\\i", std::to_string(font.GetUnderlined()), sel_start, sel_end);
|
2012-10-09 04:07:54 +02:00
|
|
|
|
2012-10-15 05:35:08 +02:00
|
|
|
commit_text(c, _("set font"), sel_start, sel_end);
|
2012-10-09 04:07:54 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2011-10-01 01:51:41 +02:00
|
|
|
/// Find and replace words in subtitles.
|
|
|
|
struct edit_find_replace : public Command {
|
|
|
|
CMD_NAME("edit/find_replace")
|
2012-10-09 04:07:54 +02:00
|
|
|
STR_MENU("Find and R&eplace...")
|
|
|
|
STR_DISP("Find and Replace")
|
|
|
|
STR_HELP("Find and replace words in subtitles")
|
2011-10-01 01:51:41 +02:00
|
|
|
|
2012-10-09 04:07:54 +02:00
|
|
|
void operator()(agi::Context *c) {
|
|
|
|
c->videoController->Stop();
|
2013-01-11 18:35:39 +01:00
|
|
|
DialogSearchReplace::Show(c, true);
|
2011-10-01 01:51:41 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2013-01-04 16:01:50 +01:00
|
|
|
static std::string get_entry_data(AssDialogue *d) { return d->GetEntryData(); }
|
2012-10-15 03:57:57 +02:00
|
|
|
static void copy_lines(agi::Context *c) {
|
|
|
|
SubtitleSelection sel = c->selectionController->GetSelectedSet();
|
2012-12-07 17:06:03 +01:00
|
|
|
SetClipboard(join(c->ass->Line
|
|
|
|
| agi::of_type<AssDialogue>()
|
|
|
|
| filtered([&](AssDialogue *d) { return sel.count(d); })
|
|
|
|
| transformed(get_entry_data),
|
2013-01-04 16:01:50 +01:00
|
|
|
"\r\n"));
|
2012-10-15 03:57:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void delete_lines(agi::Context *c, wxString const& commit_message) {
|
|
|
|
SubtitleSelection sel = c->selectionController->GetSelectedSet();
|
|
|
|
|
|
|
|
// Find a line near the active line not being deleted to make the new active line
|
2013-04-16 02:01:36 +02:00
|
|
|
AssDialogue *pre_sel = nullptr;
|
|
|
|
AssDialogue *post_sel = nullptr;
|
|
|
|
bool hit_selection = false;
|
2012-10-15 03:57:57 +02:00
|
|
|
|
2012-11-05 17:20:58 +01:00
|
|
|
for (auto diag : c->ass->Line | agi::of_type<AssDialogue>()) {
|
2013-04-16 02:01:36 +02:00
|
|
|
if (sel.count(diag))
|
|
|
|
hit_selection = true;
|
|
|
|
else if (hit_selection && !post_sel) {
|
|
|
|
post_sel = diag;
|
|
|
|
break;
|
2012-10-15 03:57:57 +02:00
|
|
|
}
|
2013-04-16 02:01:36 +02:00
|
|
|
else
|
|
|
|
pre_sel = diag;
|
2012-10-15 03:57:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Delete selected lines
|
2012-11-28 17:17:59 +01:00
|
|
|
c->ass->Line.remove_and_dispose_if([&sel](AssEntry const& e) {
|
|
|
|
return sel.count(const_cast<AssDialogue *>(static_cast<const AssDialogue*>(&e)));
|
|
|
|
}, [](AssEntry *e) { delete e; });
|
2012-10-15 03:57:57 +02:00
|
|
|
|
2013-04-16 02:01:36 +02:00
|
|
|
AssDialogue *new_active = post_sel;
|
|
|
|
if (!new_active)
|
|
|
|
new_active = pre_sel;
|
2012-10-15 03:57:57 +02:00
|
|
|
// 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;
|
2012-11-22 17:14:34 +01:00
|
|
|
c->ass->InsertLine(new_active);
|
2012-10-15 03:57:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
c->ass->Commit(commit_message, AssFile::COMMIT_DIAG_ADDREM);
|
|
|
|
|
|
|
|
sel.clear();
|
|
|
|
sel.insert(new_active);
|
|
|
|
c->selectionController->SetSelectionAndActive(sel, new_active);
|
|
|
|
}
|
|
|
|
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
/// Copy subtitles.
|
2011-07-15 06:05:22 +02:00
|
|
|
struct edit_line_copy : public validate_sel_nonempty {
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
CMD_NAME("edit/line/copy")
|
2011-11-18 06:00:20 +01:00
|
|
|
STR_MENU("&Copy Lines")
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
STR_DISP("Copy Lines")
|
2012-02-01 19:47:26 +01:00
|
|
|
STR_HELP("Copy subtitles")
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
|
|
|
|
void operator()(agi::Context *c) {
|
2012-03-13 00:34:25 +01:00
|
|
|
// Ideally we'd let the control's keydown handler run and only deal
|
|
|
|
// with the events not processed by it, but that doesn't seem to be
|
|
|
|
// possible with how wx implements key event handling - the native
|
|
|
|
// platform processing is evoked only if the wx event is unprocessed,
|
|
|
|
// and there's no way to do something if the native platform code leaves
|
|
|
|
// it unprocessed
|
|
|
|
|
|
|
|
if (wxTextEntryBase *ctrl = dynamic_cast<wxTextEntryBase*>(c->parent->FindFocus()))
|
|
|
|
ctrl->Copy();
|
2012-10-15 03:57:57 +02:00
|
|
|
else {
|
|
|
|
copy_lines(c);
|
|
|
|
}
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Cut subtitles.
|
2011-07-15 06:05:22 +02:00
|
|
|
struct edit_line_cut: public validate_sel_nonempty {
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
CMD_NAME("edit/line/cut")
|
2011-11-18 06:00:20 +01:00
|
|
|
STR_MENU("Cu&t Lines")
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
STR_DISP("Cut Lines")
|
2012-02-01 19:47:26 +01:00
|
|
|
STR_HELP("Cut subtitles")
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
|
|
|
|
void operator()(agi::Context *c) {
|
2012-03-13 00:34:25 +01:00
|
|
|
if (wxTextEntryBase *ctrl = dynamic_cast<wxTextEntryBase*>(c->parent->FindFocus()))
|
|
|
|
ctrl->Cut();
|
2012-10-15 03:57:57 +02:00
|
|
|
else {
|
|
|
|
copy_lines(c);
|
|
|
|
delete_lines(c, _("cut lines"));
|
|
|
|
}
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Delete currently selected lines.
|
2011-07-15 06:05:22 +02:00
|
|
|
struct edit_line_delete : public validate_sel_nonempty {
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
CMD_NAME("edit/line/delete")
|
2011-11-18 06:00:20 +01:00
|
|
|
STR_MENU("De&lete Lines")
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
STR_DISP("Delete Lines")
|
2012-02-01 19:47:26 +01:00
|
|
|
STR_HELP("Delete currently selected lines")
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
|
|
|
|
void operator()(agi::Context *c) {
|
2012-10-15 03:57:57 +02:00
|
|
|
delete_lines(c, _("delete lines"));
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2012-10-12 19:16:39 +02:00
|
|
|
struct in_selection : public std::unary_function<AssEntry, bool> {
|
2012-02-15 23:14:10 +01:00
|
|
|
SubtitleSelectionController::Selection const& sel;
|
|
|
|
in_selection(SubtitleSelectionController::Selection const& sel) : sel(sel) { }
|
2012-10-12 19:16:39 +02:00
|
|
|
bool operator()(AssEntry const& e) const {
|
|
|
|
const AssDialogue *d = dynamic_cast<const AssDialogue*>(&e);
|
|
|
|
return d && sel.count(const_cast<AssDialogue *>(d));
|
2012-02-15 23:14:10 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2013-06-07 03:57:14 +02:00
|
|
|
template<typename Func>
|
|
|
|
static void duplicate_lines(agi::Context *c, Func&& shift) {
|
2012-02-15 23:14:10 +01:00
|
|
|
in_selection sel(c->selectionController->GetSelectedSet());
|
|
|
|
SubtitleSelectionController::Selection new_sel;
|
|
|
|
AssDialogue *new_active = 0;
|
|
|
|
|
2012-10-12 19:16:39 +02:00
|
|
|
entryIter start = c->ass->Line.begin();
|
|
|
|
entryIter end = c->ass->Line.end();
|
2012-02-15 23:14:10 +01:00
|
|
|
while (start != end) {
|
|
|
|
// Find the first line in the selection
|
|
|
|
start = find_if(start, end, sel);
|
|
|
|
if (start == end) break;
|
|
|
|
|
|
|
|
// And the last line in this contiguous selection
|
2012-11-13 14:52:24 +01:00
|
|
|
entryIter insert_pos = find_if_not(start, end, sel);
|
2012-11-29 05:36:03 +01:00
|
|
|
entryIter last = std::prev(insert_pos);
|
2012-02-15 23:14:10 +01:00
|
|
|
|
|
|
|
// Duplicate each of the selected lines, inserting them in a block
|
|
|
|
// after the selected block
|
|
|
|
do {
|
2012-11-03 05:06:37 +01:00
|
|
|
AssDialogue *new_diag = new AssDialogue(*static_cast<AssDialogue*>(&*start));
|
2012-02-15 23:14:10 +01:00
|
|
|
|
2012-10-12 19:16:39 +02:00
|
|
|
c->ass->Line.insert(insert_pos, *new_diag);
|
2012-02-15 23:14:10 +01:00
|
|
|
new_sel.insert(new_diag);
|
|
|
|
if (!new_active)
|
|
|
|
new_active = new_diag;
|
2013-06-07 03:57:14 +02:00
|
|
|
shift(new_diag);
|
2012-02-15 23:14:10 +01:00
|
|
|
} while (start++ != last);
|
|
|
|
|
|
|
|
// Skip over the lines we just made
|
|
|
|
start = insert_pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (new_sel.empty()) return;
|
|
|
|
|
|
|
|
c->ass->Commit(_("duplicate lines"), AssFile::COMMIT_DIAG_ADDREM);
|
|
|
|
|
2012-05-05 04:11:09 +02:00
|
|
|
c->selectionController->SetSelectionAndActive(new_sel, new_active);
|
2012-02-15 23:14:10 +01:00
|
|
|
}
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
|
|
|
|
/// Duplicate the selected lines.
|
2011-07-15 06:05:22 +02:00
|
|
|
struct edit_line_duplicate : public validate_sel_nonempty {
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
CMD_NAME("edit/line/duplicate")
|
|
|
|
STR_MENU("&Duplicate Lines")
|
|
|
|
STR_DISP("Duplicate Lines")
|
2012-02-01 19:47:26 +01:00
|
|
|
STR_HELP("Duplicate the selected lines")
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
|
|
|
|
void operator()(agi::Context *c) {
|
2013-06-07 03:57:14 +02:00
|
|
|
duplicate_lines(c, [](AssDialogue *){});
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Duplicate lines and shift by one frame.
|
2011-01-16 08:15:32 +01:00
|
|
|
struct edit_line_duplicate_shift : public Command {
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
CMD_NAME("edit/line/duplicate/shift")
|
2011-11-18 06:00:20 +01:00
|
|
|
STR_MENU("D&uplicate and Shift by 1 Frame")
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
STR_DISP("Duplicate and Shift by 1 Frame")
|
2013-06-07 03:57:14 +02:00
|
|
|
STR_HELP("Duplicate lines and shift them to the frame after the original end frame")
|
|
|
|
CMD_TYPE(COMMAND_VALIDATE)
|
|
|
|
|
|
|
|
bool Validate(const agi::Context *c) {
|
|
|
|
return !c->selectionController->GetSelectedSet().empty() && c->videoController->IsLoaded();
|
|
|
|
}
|
|
|
|
|
|
|
|
void operator()(agi::Context *c) {
|
|
|
|
duplicate_lines(c, [=](AssDialogue *new_diag) {
|
|
|
|
int pos = c->videoController->FrameAtTime(new_diag->End, agi::vfr::END) + 1;
|
|
|
|
new_diag->Start = c->videoController->TimeAtFrame(pos, agi::vfr::START);
|
|
|
|
new_diag->End = c->videoController->TimeAtFrame(pos, agi::vfr::END);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct edit_line_duplicate_shift_back : public Command {
|
|
|
|
CMD_NAME("edit/line/duplicate/shift_back")
|
|
|
|
STR_MENU("Du&plicate and Shift by 1 Frame Backwards")
|
|
|
|
STR_DISP("Duplicate and Shift by 1 Frame Backwards")
|
|
|
|
STR_HELP("Duplicate selected lines and shift them to the frame before the original start frame")
|
2011-07-15 06:05:56 +02:00
|
|
|
CMD_TYPE(COMMAND_VALIDATE)
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
|
2011-07-15 06:05:22 +02:00
|
|
|
bool Validate(const agi::Context *c) {
|
|
|
|
return !c->selectionController->GetSelectedSet().empty() && c->videoController->IsLoaded();
|
|
|
|
}
|
|
|
|
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
void operator()(agi::Context *c) {
|
2013-06-07 03:57:14 +02:00
|
|
|
duplicate_lines(c, [=](AssDialogue *new_diag) {
|
|
|
|
int pos = c->videoController->FrameAtTime(new_diag->Start, agi::vfr::START) - 1;
|
|
|
|
new_diag->Start = c->videoController->TimeAtFrame(pos, agi::vfr::START);
|
|
|
|
new_diag->End = c->videoController->TimeAtFrame(pos, agi::vfr::END);
|
|
|
|
});
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2011-07-15 06:04:48 +02:00
|
|
|
static void combine_lines(agi::Context *c, void (*combiner)(AssDialogue *, AssDialogue *), wxString const& message) {
|
2012-10-05 05:22:54 +02:00
|
|
|
SubtitleSelection sel = c->selectionController->GetSelectedSet();
|
2011-07-15 06:04:48 +02:00
|
|
|
|
|
|
|
AssDialogue *first = 0;
|
2012-10-12 19:16:39 +02:00
|
|
|
for (entryIter it = c->ass->Line.begin(); it != c->ass->Line.end(); ) {
|
|
|
|
AssDialogue *diag = dynamic_cast<AssDialogue*>(&*it++);
|
|
|
|
if (!diag || !sel.count(diag))
|
2011-07-15 06:04:48 +02:00
|
|
|
continue;
|
|
|
|
if (!first) {
|
|
|
|
first = diag;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
combiner(first, diag);
|
2012-05-01 04:49:53 +02:00
|
|
|
first->End = std::max(first->End, diag->End);
|
2011-07-15 06:04:48 +02:00
|
|
|
delete diag;
|
|
|
|
}
|
|
|
|
|
|
|
|
sel.clear();
|
|
|
|
sel.insert(first);
|
2012-05-05 04:11:09 +02:00
|
|
|
c->selectionController->SetSelectionAndActive(sel, first);
|
2011-09-15 07:16:32 +02:00
|
|
|
c->ass->Commit(message, AssFile::COMMIT_DIAG_ADDREM | AssFile::COMMIT_DIAG_FULL);
|
2011-07-15 06:04:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void combine_karaoke(AssDialogue *first, AssDialogue *second) {
|
2013-01-04 16:01:50 +01:00
|
|
|
first->Text = first->Text.get() + "{\\k" + std::to_string((second->Start - first->End) / 10) + "}" + second->Text.get();
|
2011-07-15 06:04:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void combine_concat(AssDialogue *first, AssDialogue *second) {
|
2013-01-04 16:01:50 +01:00
|
|
|
first->Text = first->Text.get() + " " + second->Text.get();
|
2011-07-15 06:04:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void combine_drop(AssDialogue *, AssDialogue *) { }
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
|
|
|
|
/// Joins selected lines in a single one, as karaoke.
|
2011-07-15 06:05:22 +02:00
|
|
|
struct edit_line_join_as_karaoke : public validate_sel_multiple {
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
CMD_NAME("edit/line/join/as_karaoke")
|
|
|
|
STR_MENU("As &Karaoke")
|
|
|
|
STR_DISP("As Karaoke")
|
2012-02-01 19:47:26 +01:00
|
|
|
STR_HELP("Joins selected lines in a single one, as karaoke")
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
|
|
|
|
void operator()(agi::Context *c) {
|
2011-07-15 06:04:48 +02:00
|
|
|
combine_lines(c, combine_karaoke, _("join as karaoke"));
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/// Joins selected lines in a single one, concatenating text together.
|
2011-07-15 06:05:22 +02:00
|
|
|
struct edit_line_join_concatenate : public validate_sel_multiple {
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
CMD_NAME("edit/line/join/concatenate")
|
|
|
|
STR_MENU("&Concatenate")
|
|
|
|
STR_DISP("Concatenate")
|
2012-02-01 19:47:26 +01:00
|
|
|
STR_HELP("Joins selected lines in a single one, concatenating text together")
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
|
|
|
|
void operator()(agi::Context *c) {
|
2011-07-15 06:04:48 +02:00
|
|
|
combine_lines(c, combine_concat, _("join lines"));
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/// Joins selected lines in a single one, keeping text of first and discarding remaining.
|
2011-07-15 06:05:22 +02:00
|
|
|
struct edit_line_join_keep_first : public validate_sel_multiple {
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
CMD_NAME("edit/line/join/keep_first")
|
|
|
|
STR_MENU("Keep &First")
|
|
|
|
STR_DISP("Keep First")
|
2012-02-01 19:47:26 +01:00
|
|
|
STR_HELP("Joins selected lines in a single one, keeping text of first and discarding remaining")
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
|
|
|
|
void operator()(agi::Context *c) {
|
2011-07-15 06:04:48 +02:00
|
|
|
combine_lines(c, combine_drop, _("join lines"));
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Paste subtitles.
|
2011-01-16 08:15:32 +01:00
|
|
|
struct edit_line_paste : public Command {
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
CMD_NAME("edit/line/paste")
|
2011-11-18 06:00:20 +01:00
|
|
|
STR_MENU("&Paste Lines")
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
STR_DISP("Paste Lines")
|
2012-02-01 19:47:26 +01:00
|
|
|
STR_HELP("Paste subtitles")
|
2011-07-15 06:05:56 +02:00
|
|
|
CMD_TYPE(COMMAND_VALIDATE)
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
|
2011-12-22 22:09:31 +01:00
|
|
|
bool Validate(const agi::Context *) {
|
2012-10-25 17:13:13 +02:00
|
|
|
bool can_paste = false;
|
2011-07-15 06:05:22 +02:00
|
|
|
if (wxTheClipboard->Open()) {
|
2012-10-25 17:13:13 +02:00
|
|
|
can_paste = wxTheClipboard->IsSupported(wxDF_TEXT);
|
2011-07-15 06:05:22 +02:00
|
|
|
wxTheClipboard->Close();
|
|
|
|
}
|
2012-10-25 17:13:13 +02:00
|
|
|
return can_paste;
|
2011-07-15 06:05:22 +02:00
|
|
|
}
|
|
|
|
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
void operator()(agi::Context *c) {
|
2012-03-13 00:34:25 +01:00
|
|
|
if (wxTextEntryBase *ctrl = dynamic_cast<wxTextEntryBase*>(c->parent->FindFocus()))
|
|
|
|
ctrl->Paste();
|
2013-01-14 01:55:39 +01:00
|
|
|
else {
|
|
|
|
auto pos = c->ass->Line.iterator_to(*c->selectionController->GetActiveLine());
|
|
|
|
paste_lines(c, false, [=](AssDialogue *new_line) -> AssDialogue * {
|
|
|
|
c->ass->Line.insert(pos, *new_line);
|
|
|
|
return new_line;
|
|
|
|
});
|
|
|
|
}
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Paste subtitles over others.
|
2011-01-16 08:15:32 +01:00
|
|
|
struct edit_line_paste_over : public Command {
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
CMD_NAME("edit/line/paste/over")
|
2011-11-18 06:00:20 +01:00
|
|
|
STR_MENU("Paste Lines &Over...")
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
STR_DISP("Paste Lines Over")
|
2012-02-01 19:47:26 +01:00
|
|
|
STR_HELP("Paste subtitles over others")
|
2011-07-15 06:05:56 +02:00
|
|
|
CMD_TYPE(COMMAND_VALIDATE)
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
|
2011-07-15 06:05:22 +02:00
|
|
|
bool Validate(const agi::Context *c) {
|
2012-10-25 17:13:13 +02:00
|
|
|
bool can_paste = !c->selectionController->GetSelectedSet().empty();
|
|
|
|
if (can_paste && wxTheClipboard->Open()) {
|
|
|
|
can_paste = wxTheClipboard->IsSupported(wxDF_TEXT);
|
2011-07-15 06:05:22 +02:00
|
|
|
wxTheClipboard->Close();
|
|
|
|
}
|
2012-10-25 17:13:13 +02:00
|
|
|
return can_paste;
|
2011-07-15 06:05:22 +02:00
|
|
|
}
|
|
|
|
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
void operator()(agi::Context *c) {
|
2013-01-14 01:55:39 +01:00
|
|
|
auto const& sel = c->selectionController->GetSelectedSet();
|
|
|
|
std::vector<bool> pasteOverOptions;
|
|
|
|
|
|
|
|
// Only one line selected, so paste over downwards from the active line
|
|
|
|
if (sel.size() < 2) {
|
|
|
|
auto pos = c->ass->Line.iterator_to(*c->selectionController->GetActiveLine());
|
|
|
|
|
|
|
|
paste_lines(c, true, [&](AssDialogue *new_line) -> AssDialogue * {
|
|
|
|
std::unique_ptr<AssDialogue> deleter(new_line);
|
|
|
|
if (pos == c->ass->Line.end()) return nullptr;
|
|
|
|
|
|
|
|
AssDialogue *ret = paste_over(c->parent, pasteOverOptions, new_line, static_cast<AssDialogue*>(&*pos));
|
|
|
|
if (ret)
|
|
|
|
pos = find_if(next(pos), c->ass->Line.end(), cast<AssDialogue*>());
|
|
|
|
return ret;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Multiple lines selected, so paste over the selection
|
|
|
|
|
|
|
|
// Sort the selection by grid order
|
|
|
|
std::vector<AssDialogue*> sorted_selection;
|
|
|
|
sorted_selection.reserve(sel.size());
|
|
|
|
for (auto& line : c->ass->Line) {
|
|
|
|
if (sel.count(static_cast<AssDialogue*>(&line)))
|
|
|
|
sorted_selection.push_back(static_cast<AssDialogue*>(&line));
|
|
|
|
}
|
|
|
|
|
|
|
|
auto pos = begin(sorted_selection);
|
|
|
|
paste_lines(c, true, [&](AssDialogue *new_line) -> AssDialogue * {
|
|
|
|
std::unique_ptr<AssDialogue> deleter(new_line);
|
|
|
|
if (pos == end(sorted_selection)) return nullptr;
|
|
|
|
|
|
|
|
AssDialogue *ret = paste_over(c->parent, pasteOverOptions, new_line, *pos);
|
|
|
|
if (ret) ++pos;
|
|
|
|
return ret;
|
|
|
|
});
|
|
|
|
}
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Recombine subtitles when they have been split and merged.
|
2011-07-15 06:05:22 +02:00
|
|
|
struct edit_line_recombine : public validate_sel_multiple {
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
CMD_NAME("edit/line/recombine")
|
2012-01-27 20:22:57 +01:00
|
|
|
STR_MENU("Recom&bine Lines")
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
STR_DISP("Recombine Lines")
|
2012-02-01 19:47:26 +01:00
|
|
|
STR_HELP("Recombine subtitles when they have been split and merged")
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
|
|
|
|
void operator()(agi::Context *c) {
|
2011-01-16 08:17:46 +01:00
|
|
|
c->subsGrid->RecombineLines();
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/// Uses karaoke timing to split line into multiple smaller lines.
|
2011-07-15 06:05:22 +02:00
|
|
|
struct edit_line_split_by_karaoke : public validate_sel_nonempty {
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
CMD_NAME("edit/line/split/by_karaoke")
|
|
|
|
STR_MENU("Split Lines (by karaoke)")
|
|
|
|
STR_DISP("Split Lines (by karaoke)")
|
2012-02-01 19:47:26 +01:00
|
|
|
STR_HELP("Uses karaoke timing to split line into multiple smaller lines")
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
|
|
|
|
void operator()(agi::Context *c) {
|
2011-09-28 21:44:07 +02:00
|
|
|
AssKaraoke::SplitLines(c->selectionController->GetSelectedSet(), c);
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2012-10-30 20:32:47 +01:00
|
|
|
void split_lines(agi::Context *c, bool estimate) {
|
|
|
|
int pos = c->textSelectionController->GetSelectionStart();
|
|
|
|
|
|
|
|
AssDialogue *n1 = c->selectionController->GetActiveLine();
|
|
|
|
AssDialogue *n2 = new AssDialogue(*n1);
|
|
|
|
c->ass->Line.insert(++c->ass->Line.iterator_to(*n1), *n2);
|
|
|
|
|
2013-01-04 16:01:50 +01:00
|
|
|
std::string orig = n1->Text;
|
|
|
|
n1->Text = boost::trim_right_copy(orig.substr(0, pos));
|
|
|
|
n2->Text = boost::trim_left_copy(orig.substr(pos));
|
2012-10-30 20:32:47 +01:00
|
|
|
|
|
|
|
if (estimate && orig.size()) {
|
|
|
|
double splitPos = double(pos) / orig.size();
|
|
|
|
n2->Start = n1->End = (int)((n1->End - n1->Start) * splitPos) + n1->Start;
|
|
|
|
}
|
|
|
|
|
|
|
|
c->ass->Commit(_("split"), AssFile::COMMIT_DIAG_ADDREM | (estimate ? AssFile::COMMIT_DIAG_FULL : AssFile::COMMIT_DIAG_TEXT));
|
|
|
|
}
|
|
|
|
|
|
|
|
struct edit_line_split_estimate : public validate_sel_nonempty {
|
|
|
|
CMD_NAME("edit/line/split/estimate")
|
|
|
|
STR_MENU("Split at cursor (estimate times)")
|
|
|
|
STR_DISP("Split at cursor (estimate times)")
|
|
|
|
STR_HELP("Split the current line at the cursor, dividing the original line's duration between the new ones")
|
|
|
|
|
|
|
|
void operator()(agi::Context *c) {
|
|
|
|
split_lines(c, true);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct edit_line_split_preserve : public validate_sel_nonempty {
|
|
|
|
CMD_NAME("edit/line/split/preserve")
|
|
|
|
STR_MENU("Split at cursor (preserve times)")
|
|
|
|
STR_DISP("Split at cursor (preserve times)")
|
|
|
|
STR_HELP("Split the current line at the cursor, setting both lines to the original line's times")
|
|
|
|
|
|
|
|
void operator()(agi::Context *c) {
|
|
|
|
split_lines(c, false);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
/// Redoes last action.
|
2011-01-16 08:15:32 +01:00
|
|
|
struct edit_redo : public Command {
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
CMD_NAME("edit/redo")
|
2012-02-01 19:47:26 +01:00
|
|
|
STR_HELP("Redoes last action")
|
2011-07-15 06:05:56 +02:00
|
|
|
CMD_TYPE(COMMAND_VALIDATE | COMMAND_DYNAMIC_NAME)
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
|
2011-08-27 08:29:36 +02:00
|
|
|
wxString StrMenu(const agi::Context *c) const {
|
2013-01-26 02:57:46 +01:00
|
|
|
return c->subsController->IsRedoStackEmpty() ?
|
2011-11-17 03:19:10 +01:00
|
|
|
_("Nothing to &redo") :
|
2013-01-26 02:57:46 +01:00
|
|
|
wxString::Format(_("&Redo %s"), c->subsController->GetRedoDescription());
|
2011-08-27 08:29:36 +02:00
|
|
|
}
|
|
|
|
wxString StrDisplay(const agi::Context *c) const {
|
2013-01-26 02:57:46 +01:00
|
|
|
return c->subsController->IsRedoStackEmpty() ?
|
2011-11-17 03:19:10 +01:00
|
|
|
_("Nothing to redo") :
|
2013-01-26 02:57:46 +01:00
|
|
|
wxString::Format(_("Redo %s"), c->subsController->GetRedoDescription());
|
2011-08-27 08:29:36 +02:00
|
|
|
}
|
|
|
|
|
2011-07-15 06:05:22 +02:00
|
|
|
bool Validate(const agi::Context *c) {
|
2013-01-26 02:57:46 +01:00
|
|
|
return !c->subsController->IsRedoStackEmpty();
|
2011-07-15 06:05:22 +02:00
|
|
|
}
|
|
|
|
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
void operator()(agi::Context *c) {
|
2013-01-26 02:57:46 +01:00
|
|
|
c->subsController->Redo();
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Undoes last action.
|
2011-01-16 08:15:32 +01:00
|
|
|
struct edit_undo : public Command {
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
CMD_NAME("edit/undo")
|
2012-02-01 19:47:26 +01:00
|
|
|
STR_HELP("Undoes last action")
|
2011-07-15 06:05:56 +02:00
|
|
|
CMD_TYPE(COMMAND_VALIDATE | COMMAND_DYNAMIC_NAME)
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
|
2011-08-27 08:29:36 +02:00
|
|
|
wxString StrMenu(const agi::Context *c) const {
|
2013-01-26 02:57:46 +01:00
|
|
|
return c->subsController->IsUndoStackEmpty() ?
|
2011-11-17 03:19:10 +01:00
|
|
|
_("Nothing to &undo") :
|
2013-01-26 02:57:46 +01:00
|
|
|
wxString::Format(_("&Undo %s"), c->subsController->GetUndoDescription());
|
2011-08-27 08:29:36 +02:00
|
|
|
}
|
|
|
|
wxString StrDisplay(const agi::Context *c) const {
|
2013-01-26 02:57:46 +01:00
|
|
|
return c->subsController->IsUndoStackEmpty() ?
|
2011-11-17 03:19:10 +01:00
|
|
|
_("Nothing to undo") :
|
2013-01-26 02:57:46 +01:00
|
|
|
wxString::Format(_("Undo %s"), c->subsController->GetUndoDescription());
|
2011-08-27 08:29:36 +02:00
|
|
|
}
|
|
|
|
|
2011-07-15 06:05:22 +02:00
|
|
|
bool Validate(const agi::Context *c) {
|
2013-01-26 02:57:46 +01:00
|
|
|
return !c->subsController->IsUndoStackEmpty();
|
2011-07-15 06:05:22 +02:00
|
|
|
}
|
|
|
|
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
void operator()(agi::Context *c) {
|
2013-01-26 02:57:46 +01:00
|
|
|
c->subsController->Undo();
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2012-10-12 01:46:53 +02:00
|
|
|
struct edit_revert : public Command {
|
|
|
|
CMD_NAME("edit/revert")
|
|
|
|
STR_DISP("Revert")
|
|
|
|
STR_MENU("Revert")
|
2013-03-31 17:07:18 +02:00
|
|
|
STR_HELP("Revert the active line to its initial state (shown in the upper editor)")
|
2012-10-12 01:46:53 +02:00
|
|
|
|
|
|
|
void operator()(agi::Context *c) {
|
|
|
|
AssDialogue *line = c->selectionController->GetActiveLine();
|
|
|
|
line->Text = c->initialLineState->GetInitialText();
|
|
|
|
c->ass->Commit(_("revert line"), AssFile::COMMIT_DIAG_TEXT, -1, line);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct edit_clear : public Command {
|
|
|
|
CMD_NAME("edit/clear")
|
|
|
|
STR_DISP("Clear")
|
|
|
|
STR_MENU("Clear")
|
|
|
|
STR_HELP("Clear the current line's text")
|
|
|
|
|
|
|
|
void operator()(agi::Context *c) {
|
|
|
|
AssDialogue *line = c->selectionController->GetActiveLine();
|
|
|
|
line->Text = "";
|
|
|
|
c->ass->Commit(_("clear line"), AssFile::COMMIT_DIAG_TEXT, -1, line);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2013-01-04 16:01:50 +01:00
|
|
|
std::string get_text(AssDialogueBlock &d) { return d.GetText(); }
|
2012-11-03 05:24:11 +01:00
|
|
|
struct edit_clear_text : public Command {
|
|
|
|
CMD_NAME("edit/clear/text")
|
|
|
|
STR_DISP("Clear Text")
|
|
|
|
STR_MENU("Clear Text")
|
|
|
|
STR_HELP("Clear the current line's text, leaving override tags")
|
|
|
|
|
|
|
|
void operator()(agi::Context *c) {
|
|
|
|
AssDialogue *line = c->selectionController->GetActiveLine();
|
|
|
|
boost::ptr_vector<AssDialogueBlock> blocks(line->ParseTags());
|
|
|
|
line->Text = join(blocks
|
|
|
|
| filtered([](AssDialogueBlock const& b) { return b.GetType() != BLOCK_PLAIN; })
|
|
|
|
| transformed(get_text),
|
2013-01-04 16:01:50 +01:00
|
|
|
"");
|
2012-11-03 05:24:11 +01:00
|
|
|
c->ass->Commit(_("clear line"), AssFile::COMMIT_DIAG_TEXT, -1, line);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2012-10-12 01:46:53 +02:00
|
|
|
struct edit_insert_original : public Command {
|
|
|
|
CMD_NAME("edit/insert_original")
|
|
|
|
STR_DISP("Insert Original")
|
|
|
|
STR_MENU("Insert Original")
|
|
|
|
STR_HELP("Insert the original line text at the cursor")
|
|
|
|
|
|
|
|
void operator()(agi::Context *c) {
|
|
|
|
AssDialogue *line = c->selectionController->GetActiveLine();
|
|
|
|
int sel_start = c->textSelectionController->GetSelectionStart();
|
|
|
|
int sel_end = c->textSelectionController->GetSelectionEnd();
|
|
|
|
|
2013-01-04 16:01:50 +01:00
|
|
|
line->Text = line->Text.get().substr(0, sel_start) + c->initialLineState->GetInitialText() + line->Text.get().substr(sel_end);
|
2012-10-12 01:46:53 +02:00
|
|
|
c->ass->Commit(_("insert original"), AssFile::COMMIT_DIAG_TEXT, -1, line);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2011-07-15 06:05:01 +02:00
|
|
|
}
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
/// @}
|
|
|
|
|
2011-07-15 06:05:01 +02:00
|
|
|
namespace cmd {
|
|
|
|
void init_edit() {
|
2013-06-08 06:19:40 +02:00
|
|
|
reg(agi::util::make_unique<edit_color_primary>());
|
|
|
|
reg(agi::util::make_unique<edit_color_secondary>());
|
|
|
|
reg(agi::util::make_unique<edit_color_outline>());
|
|
|
|
reg(agi::util::make_unique<edit_color_shadow>());
|
|
|
|
reg(agi::util::make_unique<edit_font>());
|
|
|
|
reg(agi::util::make_unique<edit_find_replace>());
|
|
|
|
reg(agi::util::make_unique<edit_line_copy>());
|
|
|
|
reg(agi::util::make_unique<edit_line_cut>());
|
|
|
|
reg(agi::util::make_unique<edit_line_delete>());
|
|
|
|
reg(agi::util::make_unique<edit_line_duplicate>());
|
|
|
|
reg(agi::util::make_unique<edit_line_duplicate_shift>());
|
|
|
|
reg(agi::util::make_unique<edit_line_duplicate_shift_back>());
|
|
|
|
reg(agi::util::make_unique<edit_line_join_as_karaoke>());
|
|
|
|
reg(agi::util::make_unique<edit_line_join_concatenate>());
|
|
|
|
reg(agi::util::make_unique<edit_line_join_keep_first>());
|
|
|
|
reg(agi::util::make_unique<edit_line_paste>());
|
|
|
|
reg(agi::util::make_unique<edit_line_paste_over>());
|
|
|
|
reg(agi::util::make_unique<edit_line_recombine>());
|
|
|
|
reg(agi::util::make_unique<edit_line_split_by_karaoke>());
|
|
|
|
reg(agi::util::make_unique<edit_line_split_estimate>());
|
|
|
|
reg(agi::util::make_unique<edit_line_split_preserve>());
|
|
|
|
reg(agi::util::make_unique<edit_style_bold>());
|
|
|
|
reg(agi::util::make_unique<edit_style_italic>());
|
|
|
|
reg(agi::util::make_unique<edit_style_underline>());
|
|
|
|
reg(agi::util::make_unique<edit_style_strikeout>());
|
|
|
|
reg(agi::util::make_unique<edit_redo>());
|
|
|
|
reg(agi::util::make_unique<edit_undo>());
|
|
|
|
reg(agi::util::make_unique<edit_revert>());
|
|
|
|
reg(agi::util::make_unique<edit_insert_original>());
|
|
|
|
reg(agi::util::make_unique<edit_clear>());
|
|
|
|
reg(agi::util::make_unique<edit_clear_text>());
|
2011-07-15 06:05:01 +02:00
|
|
|
}
|
Merge the dynamic menu, hotkey and toolbar branch to trunk. This doesn't include Windows support as vs2008 was being a major pain. This involves revisions r4921:4950, r4961:5002, r5005:5006, r5008:5056, r5062:5065, r5072, r5081:5082, r5087, r5096:5110, r5124:5125. Updates #1258.
Originally committed to SVN as r5126.
2011-01-05 14:00:46 +01:00
|
|
|
}
|