diff --git a/aegisub/src/base_grid.cpp b/aegisub/src/base_grid.cpp index ca264ddd7..62f3cc8bf 100644 --- a/aegisub/src/base_grid.cpp +++ b/aegisub/src/base_grid.cpp @@ -1129,14 +1129,12 @@ bool BaseGrid::IsDisplayed(const AssDialogue *line) const { /// @return /// void BaseGrid::OnKeyDown(wxKeyEvent &event) { - // Get size int w,h; GetClientSize(&w,&h); hotkey::check("Subtitle Grid", event.GetKeyCode(), event.GetUnicodeKey(), event.GetModifiers()); event.StopPropagation(); - // Get scan code int key = event.GetKeyCode(); #ifdef __APPLE__ @@ -1147,25 +1145,6 @@ void BaseGrid::OnKeyDown(wxKeyEvent &event) { bool alt = event.m_altDown; bool shift = event.m_shiftDown; - // Left/right, forward to seek bar if video is loaded - if (key == WXK_LEFT || key == WXK_RIGHT) { - if (context->videoController->IsLoaded()) { - /// todo: is this nessesary, or can left/right just be in the Subtitle Grid category? - hotkey::check("Video", event.GetKeyCode(), event.GetUnicodeKey(), event.GetModifiers()); - } - else { - event.Skip(); - } - return; - } - - // Select all - if (key == 'A' && ctrl && !alt && !shift) { - Selection sel; - std::copy(index_line_map.begin(), index_line_map.end(), std::inserter(sel, sel.end())); - SetSelectedSet(sel); - } - // Up/down int dir = 0; int step = 1; @@ -1240,15 +1219,9 @@ void BaseGrid::OnKeyDown(wxKeyEvent &event) { return; } } - - // Other events, send to audio display - /// @todo Reinstate this, or make a better solution, when audio is getting stabler again - /* - if (context->audio->loaded) { - context->audio->GetEventHandler()->ProcessEvent(event); + else { + hotkey::check("Audio", event.GetKeyCode(), event.GetUnicodeKey(), event.GetModifiers()); } - */ - else event.Skip(); } diff --git a/aegisub/src/command/edit.cpp b/aegisub/src/command/edit.cpp index 074f01327..13790a62f 100644 --- a/aegisub/src/command/edit.cpp +++ b/aegisub/src/command/edit.cpp @@ -246,8 +246,11 @@ struct edit_line_swap : public Command { STR_HELP("Swaps the two selected lines.") void operator()(agi::Context *c) { - wxArrayInt sels = c->subsGrid->GetSelection(); - c->subsGrid->SwapLines(sels.front(), sels.back()); + SelectionController::Selection sel = c->selectionController->GetSelectedSet(); + if (sel.size() == 2) { + using std::swap; + swap(*sel.begin(), *sel.rbegin()); + } } }; diff --git a/aegisub/src/command/grid.cpp b/aegisub/src/command/grid.cpp index fe76a152e..1241993b5 100644 --- a/aegisub/src/command/grid.cpp +++ b/aegisub/src/command/grid.cpp @@ -43,17 +43,19 @@ #include "command.h" +#include "../ass_dialogue.h" +#include "../ass_file.h" #include "../include/aegisub/context.h" #include "../subs_grid.h" #include "../main.h" #include "../frame_main.h" +#include "../utils.h" + namespace cmd { /// @defgroup cmd-grid Subtitle grid commands. /// @{ - - /// Move to the next subtitle line. struct grid_line_next : public Command { CMD_NAME("grid/line/next") @@ -144,17 +146,69 @@ struct grid_tags_simplify : public Command { } }; +template +static bool move_one(T begin, T end, U value) { + T it = find(begin, end, value); + assert(it != end); + + T prev = it; + ++prev; + prev = find_if(prev, end, cast()); + + if (prev != end) { + using std::swap; + swap(*it, *prev); + return true; + } + return false; +} + +/// Swap the active line with the dialogue line above it +struct grid_swap_up : public Command { + CMD_NAME("grid/swap/up") + STR_MENU("Move line up") + STR_DISP("Move line up") + STR_HELP("Move the selected line up one row") + + void operator()(agi::Context *c) { + if (AssDialogue *line = c->selectionController->GetActiveLine()) { + if (move_one(c->ass->Line.rbegin(), c->ass->Line.rend(), line)) + /// todo Maybe add COMMIT_ORDER, as the grid is the only thing + /// that needs to care about this + /// Probably not worth it + c->ass->Commit(_("swap lines"), AssFile::COMMIT_FULL); + } + } +}; + +/// Swap the active line with the dialogue line below it +struct grid_swap_down : public Command { + CMD_NAME("grid/swap/down") + STR_MENU("Move line down") + STR_DISP("Move line down") + STR_HELP("Move the selected line down one row") + + void operator()(agi::Context *c) { + if (AssDialogue *line = c->selectionController->GetActiveLine()) { + if (move_one(c->ass->Line.begin(), c->ass->Line.end(), line)) + c->ass->Commit(_("swap lines"), AssFile::COMMIT_FULL); + } + } +}; + /// @} /// Init grid/ commands. void init_grid(CommandManager *cm) { - cm->reg(new grid_line_next()); - cm->reg(new grid_line_prev()); - cm->reg(new grid_tag_cycle_hiding()); - cm->reg(new grid_tags_hide()); - cm->reg(new grid_tags_show()); - cm->reg(new grid_tags_simplify()); + cm->reg(new grid_line_next); + cm->reg(new grid_line_prev); + cm->reg(new grid_swap_down); + cm->reg(new grid_swap_up); + cm->reg(new grid_tag_cycle_hiding); + cm->reg(new grid_tags_hide); + cm->reg(new grid_tags_show); + cm->reg(new grid_tags_simplify); } } // namespace cmd diff --git a/aegisub/src/command/subtitle.cpp b/aegisub/src/command/subtitle.cpp index 147ea57ab..82c8b5d16 100644 --- a/aegisub/src/command/subtitle.cpp +++ b/aegisub/src/command/subtitle.cpp @@ -60,6 +60,7 @@ #include "../main.h" #include "../subs_grid.h" #include "../video_context.h" +#include "../utils.h" namespace cmd { @@ -329,9 +330,24 @@ struct subtitle_save_as : public Command { } }; +/// Selects all dialogue lines +struct subtitle_select_all : public Command { + CMD_NAME("subtitle/select/all") + STR_MENU("Select All") + STR_DISP("Select All") + STR_HELP("Selects all dialogue lines.") + + void operator()(agi::Context *c) { + SelectionController::Selection sel; + transform(c->ass->Line.begin(), c->ass->Line.end(), + inserter(sel, sel.begin()), cast()); + sel.erase(0); + c->selectionController->SetSelectedSet(sel); + } +}; /// Selects all lines that are currently visible on video frame. -struct subtitle_select_visiblek : public Command { +struct subtitle_select_visible : public Command { CMD_NAME("subtitle/select/visible") STR_MENU("Select Visible") STR_DISP("Select Visible") @@ -374,23 +390,24 @@ struct subtitle_tags_show : public Command { /// Init subtitle/ commands. void init_subtitle(CommandManager *cm) { - cm->reg(new subtitle_attachment()); - cm->reg(new subtitle_find()); - cm->reg(new subtitle_find_next()); - cm->reg(new subtitle_insert_after()); - cm->reg(new subtitle_insert_after_videotime()); - cm->reg(new subtitle_insert_before()); - cm->reg(new subtitle_insert_before_videotime()); - cm->reg(new subtitle_new()); - cm->reg(new subtitle_open()); - cm->reg(new subtitle_open_charset()); - cm->reg(new subtitle_open_video()); - cm->reg(new subtitle_properties()); - cm->reg(new subtitle_save()); - cm->reg(new subtitle_save_as()); - cm->reg(new subtitle_select_visiblek()); - cm->reg(new subtitle_spellcheck()); - cm->reg(new subtitle_tags_show()); + cm->reg(new subtitle_attachment); + cm->reg(new subtitle_find); + cm->reg(new subtitle_find_next); + cm->reg(new subtitle_insert_after); + cm->reg(new subtitle_insert_after_videotime); + cm->reg(new subtitle_insert_before); + cm->reg(new subtitle_insert_before_videotime); + cm->reg(new subtitle_new); + cm->reg(new subtitle_open); + cm->reg(new subtitle_open_charset); + cm->reg(new subtitle_open_video); + cm->reg(new subtitle_properties); + cm->reg(new subtitle_save); + cm->reg(new subtitle_save_as); + cm->reg(new subtitle_select_all); + cm->reg(new subtitle_select_visible); + cm->reg(new subtitle_spellcheck); + cm->reg(new subtitle_tags_show); } diff --git a/aegisub/src/libresrc/default_hotkey.json b/aegisub/src/libresrc/default_hotkey.json index 834cb62b2..31fd3d0a6 100644 --- a/aegisub/src/libresrc/default_hotkey.json +++ b/aegisub/src/libresrc/default_hotkey.json @@ -95,14 +95,14 @@ "enable" : true } ], - "edit/copy" : [ + "edit/line/copy" : [ { "modifiers" : [ "Ctrl" ], "key" : "C", "enable" : true } ], - "edit/cut" : [ + "edit/line/cut" : [ { "modifiers" : [ "Ctrl" ], "key" : "X", @@ -130,14 +130,14 @@ "enable" : true } ], - "edit/paste" : [ + "edit/line/paste" : [ { "modifiers" : [ "Ctrl" ], "key" : "V", "enable" : true } ], - "edit/paste/over" : [ + "edit/line/paste/over" : [ { "modifiers" : [ "Ctrl", "Shift" ], "key" : "V", @@ -572,6 +572,30 @@ ] }, + "Subtitle Grid" : { + "subtitle/select/all" : [ + { + "modifiers" : [ "Ctrl" ], + "key" : "A", + "enable" : true + } + ], + "video/frame/next" : [ + { + "modifiers" : [], + "key" : "Right", + "enable" : true + } + ], + "video/frame/prev" : [ + { + "modifiers" : [], + "key" : "Left", + "enable" : true + } + ] + }, + "Styling Assistant" : { "audio play" : [ { diff --git a/aegisub/src/subs_grid.cpp b/aegisub/src/subs_grid.cpp index 889442c8c..089af1dce 100644 --- a/aegisub/src/subs_grid.cpp +++ b/aegisub/src/subs_grid.cpp @@ -69,7 +69,6 @@ #include "video_context.h" BEGIN_EVENT_TABLE(SubtitlesGrid, BaseGrid) - EVT_KEY_DOWN(SubtitlesGrid::OnKeyDown) EVT_MENU_RANGE(MENU_SHOW_COL,MENU_SHOW_COL+15,SubtitlesGrid::OnShowColMenu) END_EVENT_TABLE() @@ -247,102 +246,6 @@ void SubtitlesGrid::OnShowColMenu(wxCommandEvent &event) { Refresh(false); } -/// @brief Process keyboard events -/// @param event -void SubtitlesGrid::OnKeyDown(wxKeyEvent &event) { - - hotkey::check("Subtitle Grid", event.GetKeyCode(), event.GetUnicodeKey(), event.GetModifiers()); - event.StopPropagation(); - -//H Fix below. -/* - // Get key -#ifdef __APPLE__ - Hotkeys.SetPressed(event.GetKeyCode(),event.m_metaDown,event.m_altDown,event.m_shiftDown); -#else - Hotkeys.SetPressed(event.GetKeyCode(),event.m_controlDown,event.m_altDown,event.m_shiftDown); -#endif - - // Get selection - bool continuous = false; - wxArrayInt sels = GetSelection(&continuous); - int n_found = sels.Count(); - int n = 0; - int n2 = 0; - int nrows = GetRows(); - if (n_found > 0) { - n = sels[0]; - n2 = sels[n_found-1]; - } - - if (n_found == 1) { - // Move down - if (Hotkeys.IsPressed(_T("Grid move row down"))) { - if (n < nrows-1) { - SwapLines(n,n+1); - SelectRow(n+1); - //editBox->SetToLine(n+1); - } - return; - } - - // Move up - if (Hotkeys.IsPressed(_T("Grid move row up"))) { - if (n > 0) { - SwapLines(n-1,n); - SelectRow(n-1); - //editBox->SetToLine(n-1); - } - return; - } - } - - if (n_found >= 1) { - // Copy - if (Hotkeys.IsPressed(_T("Copy"))) { - CopyLines(GetSelection()); - return; - } - - // Cut - if (Hotkeys.IsPressed(_T("Cut"))) { - CutLines(GetSelection()); - return; - } - - // Paste - if (Hotkeys.IsPressed(_T("Paste"))) { - PasteLines(GetFirstSelRow()); - return; - } - - // Delete - if (Hotkeys.IsPressed(_T("Grid delete rows"))) { - DeleteLines(GetSelection()); - return; - } - - if (continuous) { - // Duplicate - if (Hotkeys.IsPressed(_T("Grid duplicate rows"))) { - DuplicateLines(n,n2,false); - return; - } - - // Duplicate and shift - if (context->videoController->TimecodesLoaded()) { - if (Hotkeys.IsPressed(_T("Grid duplicate and shift one frame"))) { - DuplicateLines(n,n2,true); - return; - } - } - } - } - - event.Skip(); -*/ -} - static void trim_text(AssDialogue *diag) { static wxRegEx start(L"^( |\\t|\\\\[nNh])+"); static wxRegEx end(L"( |\\t|\\\\[nNh])+$"); @@ -437,19 +340,6 @@ void SubtitlesGrid::RecombineLines() { SetActiveLine(activeLine); } -/// @brief Swaps two lines -/// @param n1 -/// @param n2 -void SubtitlesGrid::SwapLines(int n1,int n2) { - AssDialogue *dlg1 = GetDialogue(n1); - AssDialogue *dlg2 = GetDialogue(n2); - if (n1 == 0 || n2 == 0) return; - - std::swap(*dlg1, *dlg2); - - context->ass->Commit(_("swap lines")); -} - /// @brief Insert a line /// @param line /// @param n diff --git a/aegisub/src/subs_grid.h b/aegisub/src/subs_grid.h index 1c1afb643..96158e356 100644 --- a/aegisub/src/subs_grid.h +++ b/aegisub/src/subs_grid.h @@ -66,7 +66,6 @@ class SubtitlesGrid: public BaseGrid { void OnPopupMenu(bool alternate=false); void OnCommand(wxCommandEvent& event); - void OnKeyDown(wxKeyEvent &event); void OnShowColMenu(wxCommandEvent &event); @@ -117,7 +116,6 @@ public: /// @param nextFrame Set the new lines to start and end on the next frame void DuplicateLines(int first,int last,bool nextFrame=false); - void SwapLines(int line1,int line2); /// @brief Shift line by time /// @param n Line to shift /// @param len ms to shift by