Add an optional Validate method to commands

Originally committed to SVN as r5459.
This commit is contained in:
Thomas Goyne 2011-07-15 04:05:22 +00:00
parent d405b061df
commit f098e2fac8
14 changed files with 252 additions and 144 deletions

View File

@ -461,28 +461,14 @@ int BaseGrid::GetLastSelRow() const {
/// @brief Gets all selected rows /// @brief Gets all selected rows
/// @param[out] cont Is the selection contiguous, i.e. free from holes
/// @return Array with indices of selected lines /// @return Array with indices of selected lines
/// ///
wxArrayInt BaseGrid::GetSelection(bool *cont) const { wxArrayInt BaseGrid::GetSelection() const {
int last = -1; wxArrayInt res(selection.size());
bool continuous = true;
std::set<int> sel_row_indices;
for (Selection::const_iterator it = selection.begin(); it != selection.end(); ++it) { for (Selection::const_iterator it = selection.begin(); it != selection.end(); ++it) {
sel_row_indices.insert(GetDialogueIndex(*it)); res.push_back(GetDialogueIndex(*it));
} }
std::sort(res.begin(), res.end());
// Iterating the int set yields a sorted list
wxArrayInt res;
for (std::set<int>::iterator it = sel_row_indices.begin(); it != sel_row_indices.end(); ++it) {
res.Add(*it);
if (last != -1 && *it != last+1) continuous = false;
last = *it;
}
if (cont) *cont = continuous;
return res; return res;
} }

View File

@ -158,7 +158,7 @@ public:
int GetFirstSelRow() const; int GetFirstSelRow() const;
int GetLastSelRow() const; int GetLastSelRow() const;
void SelectVisible(); void SelectVisible();
wxArrayInt GetSelection(bool *continuous=NULL) const; wxArrayInt GetSelection() const;
void ClearMaps(); void ClearMaps();
/// @brief Update the row <-> AssDialogue mappings /// @brief Update the row <-> AssDialogue mappings

View File

@ -85,6 +85,10 @@ struct app_display_audio_subs : public Command {
void operator()(agi::Context *c) { void operator()(agi::Context *c) {
wxGetApp().frame->SetDisplayMode(0,1); wxGetApp().frame->SetDisplayMode(0,1);
} }
bool Validate(const agi::Context *c) {
return c->audioController->IsAudioOpen();
}
}; };
@ -98,6 +102,10 @@ struct app_display_full : public Command {
void operator()(agi::Context *c) { void operator()(agi::Context *c) {
wxGetApp().frame->SetDisplayMode(1,1); wxGetApp().frame->SetDisplayMode(1,1);
} }
bool Validate(const agi::Context *c) {
return c->audioController->IsAudioOpen() && c->videoController->IsLoaded() && !c->detachedVideo;
}
}; };
@ -124,6 +132,10 @@ struct app_display_video_subs : public Command {
void operator()(agi::Context *c) { void operator()(agi::Context *c) {
wxGetApp().frame->SetDisplayMode(1,0); wxGetApp().frame->SetDisplayMode(1,0);
} }
bool Validate(const agi::Context *c) {
return c->videoController->IsLoaded() && !c->detachedVideo;
}
}; };

View File

@ -49,18 +49,25 @@
#include "../audio_timing.h" #include "../audio_timing.h"
#include "../compat.h" #include "../compat.h"
#include "../include/aegisub/context.h" #include "../include/aegisub/context.h"
#include "../selection_controller.h"
#include "../main.h" #include "../main.h"
#include "../selection_controller.h"
typedef SelectionController<AssDialogue>::Selection Selection; #include "../video_context.h"
namespace { namespace {
typedef SelectionController<AssDialogue>::Selection Selection;
using cmd::Command; using cmd::Command;
struct validate_audio_open : public Command {
bool Validate(const agi::Context *c) {
return c->audioController->IsAudioOpen();
}
};
/// @defgroup cmd-audio Audio commands. /// @defgroup cmd-audio Audio commands.
/// @{ /// @{
/// Closes the currently open audio file. /// Closes the currently open audio file.
struct audio_close : public Command { struct audio_close : public validate_audio_open {
CMD_NAME("audio/close") CMD_NAME("audio/close")
STR_MENU("&Close Audio") STR_MENU("&Close Audio")
STR_DISP("Close Audio") STR_DISP("Close Audio")
@ -126,6 +133,10 @@ struct audio_open_video : public Command {
STR_DISP("Open Audio from Video") STR_DISP("Open Audio from Video")
STR_HELP("Opens the audio from the current video file.") STR_HELP("Opens the audio from the current video file.")
bool Validate(const agi::Context *c) {
return c->videoController->IsLoaded();
}
void operator()(agi::Context *c) { void operator()(agi::Context *c) {
c->audioController->OpenAudio(_T("audio-video:cache")); c->audioController->OpenAudio(_T("audio-video:cache"));
} }
@ -176,11 +187,12 @@ struct audio_save_clip : public Command {
}; };
/// Play the current audio selection /// Play the current audio selection
struct audio_play_selection : public Command { struct audio_play_selection : public validate_audio_open {
CMD_NAME("audio/play/selection") CMD_NAME("audio/play/selection")
STR_MENU("Play audio selection") STR_MENU("Play audio selection")
STR_DISP("Play audio selection") STR_DISP("Play audio selection")
STR_HELP("Play selection") STR_HELP("Play selection")
void operator()(agi::Context *c) { void operator()(agi::Context *c) {
c->audioController->PlayPrimaryRange(); c->audioController->PlayPrimaryRange();
} }
@ -192,17 +204,23 @@ struct audio_stop : public Command {
STR_MENU("Stop playing") STR_MENU("Stop playing")
STR_DISP("Stop playing") STR_DISP("Stop playing")
STR_HELP("Stop") STR_HELP("Stop")
bool Validate(const agi::Context *c) {
return c->audioController->IsPlaying();
}
void operator()(agi::Context *c) { void operator()(agi::Context *c) {
c->audioController->Stop(); c->audioController->Stop();
} }
}; };
/// Play 500 ms before the selected audio range /// Play 500 ms before the selected audio range
struct audio_play_before : public Command { struct audio_play_before : public validate_audio_open {
CMD_NAME("audio/play/selection/before") CMD_NAME("audio/play/selection/before")
STR_MENU("Play 500 ms before selection") STR_MENU("Play 500 ms before selection")
STR_DISP("Play 500 ms before selection") STR_DISP("Play 500 ms before selection")
STR_HELP("Play 500 ms before selection") STR_HELP("Play 500 ms before selection")
void operator()(agi::Context *c) { void operator()(agi::Context *c) {
SampleRange times(c->audioController->GetPrimaryPlaybackRange()); SampleRange times(c->audioController->GetPrimaryPlaybackRange());
c->audioController->PlayRange(SampleRange( c->audioController->PlayRange(SampleRange(
@ -212,11 +230,12 @@ struct audio_play_before : public Command {
}; };
/// Play 500 ms after the selected audio range /// Play 500 ms after the selected audio range
struct audio_play_after : public Command { struct audio_play_after : public validate_audio_open {
CMD_NAME("audio/play/selection/after") CMD_NAME("audio/play/selection/after")
STR_MENU("Play 500 ms after selection") STR_MENU("Play 500 ms after selection")
STR_DISP("Play 500 ms after selection") STR_DISP("Play 500 ms after selection")
STR_HELP("Play 500 ms after selection") STR_HELP("Play 500 ms after selection")
void operator()(agi::Context *c) { void operator()(agi::Context *c) {
SampleRange times(c->audioController->GetPrimaryPlaybackRange()); SampleRange times(c->audioController->GetPrimaryPlaybackRange());
c->audioController->PlayRange(SampleRange( c->audioController->PlayRange(SampleRange(
@ -226,11 +245,12 @@ struct audio_play_after : public Command {
}; };
/// Play from the beginning of the audio range to the end of the file /// Play from the beginning of the audio range to the end of the file
struct audio_play_end : public Command { struct audio_play_end : public validate_audio_open {
CMD_NAME("audio/play/selection/end") CMD_NAME("audio/play/selection/end")
STR_MENU("Play last 500 ms of selection") STR_MENU("Play last 500 ms of selection")
STR_DISP("Play last 500 ms of selection") STR_DISP("Play last 500 ms of selection")
STR_HELP("Play last 500 ms of selection") STR_HELP("Play last 500 ms of selection")
void operator()(agi::Context *c) { void operator()(agi::Context *c) {
SampleRange times(c->audioController->GetPrimaryPlaybackRange()); SampleRange times(c->audioController->GetPrimaryPlaybackRange());
c->audioController->PlayRange(SampleRange( c->audioController->PlayRange(SampleRange(
@ -242,11 +262,12 @@ struct audio_play_end : public Command {
}; };
/// Play the first 500 ms of the audio range /// Play the first 500 ms of the audio range
struct audio_play_begin : public Command { struct audio_play_begin : public validate_audio_open {
CMD_NAME("audio/play/selection/begin") CMD_NAME("audio/play/selection/begin")
STR_MENU("Play first 500 ms of selection") STR_MENU("Play first 500 ms of selection")
STR_DISP("Play first 500 ms of selection") STR_DISP("Play first 500 ms of selection")
STR_HELP("Play first 500 ms of selection") STR_HELP("Play first 500 ms of selection")
void operator()(agi::Context *c) { void operator()(agi::Context *c) {
SampleRange times(c->audioController->GetPrimaryPlaybackRange()); SampleRange times(c->audioController->GetPrimaryPlaybackRange());
c->audioController->PlayRange(SampleRange( c->audioController->PlayRange(SampleRange(
@ -258,11 +279,12 @@ struct audio_play_begin : public Command {
}; };
/// Play the last 500 ms of the audio range /// Play the last 500 ms of the audio range
struct audio_play_to_end : public Command { struct audio_play_to_end : public validate_audio_open {
CMD_NAME("audio/play/to_end") CMD_NAME("audio/play/to_end")
STR_MENU("Play from selection start to end of file") STR_MENU("Play from selection start to end of file")
STR_DISP("Play from selection start to end of file") STR_DISP("Play from selection start to end of file")
STR_HELP("Play from selection start to end of file") STR_HELP("Play from selection start to end of file")
void operator()(agi::Context *c) { void operator()(agi::Context *c) {
c->audioController->PlayToEnd(c->audioController->GetPrimaryPlaybackRange().begin()); c->audioController->PlayToEnd(c->audioController->GetPrimaryPlaybackRange().begin());
} }
@ -275,6 +297,7 @@ struct audio_commit : public Command {
STR_MENU("Commit") STR_MENU("Commit")
STR_DISP("Commit") STR_DISP("Commit")
STR_HELP("Commit") STR_HELP("Commit")
void operator()(agi::Context *c) { void operator()(agi::Context *c) {
c->audioController->GetTimingController()->Commit(); c->audioController->GetTimingController()->Commit();
} }
@ -286,6 +309,7 @@ struct audio_go_to : public Command {
STR_MENU("Go to selection") STR_MENU("Go to selection")
STR_DISP("Go to selection") STR_DISP("Go to selection")
STR_HELP("Go to selection") STR_HELP("Go to selection")
void operator()(agi::Context *c) { void operator()(agi::Context *c) {
//if (c->audioController->GetTimingController()) //if (c->audioController->GetTimingController())
//audioDisplay->ScrollSampleRangeInView(c->audioController->GetTimingController()->GetIdealVisibleSampleRange()); //audioDisplay->ScrollSampleRangeInView(c->audioController->GetTimingController()->GetIdealVisibleSampleRange());
@ -302,6 +326,7 @@ struct audio_autoscroll : public Command {
STR_MENU("Auto scrolls audio display to selected line") STR_MENU("Auto scrolls audio display to selected line")
STR_DISP("Auto scrolls audio display to selected line") STR_DISP("Auto scrolls audio display to selected line")
STR_HELP("Auto scrolls audio display to selected line") STR_HELP("Auto scrolls audio display to selected line")
void operator()(agi::Context *c) { void operator()(agi::Context *c) {
toggle("Audio/Auto/Scroll"); toggle("Audio/Auto/Scroll");
} }
@ -313,6 +338,7 @@ struct audio_autocommit : public Command {
STR_MENU("Automatically commit all changes") STR_MENU("Automatically commit all changes")
STR_DISP("Automatically commit all changes") STR_DISP("Automatically commit all changes")
STR_HELP("Automatically commit all changes") STR_HELP("Automatically commit all changes")
void operator()(agi::Context *c) { void operator()(agi::Context *c) {
toggle("Audio/Auto/Commit"); toggle("Audio/Auto/Commit");
} }
@ -324,6 +350,7 @@ struct audio_autonext : public Command {
STR_MENU("Auto goes to next line on commit") STR_MENU("Auto goes to next line on commit")
STR_DISP("Auto goes to next line on commit") STR_DISP("Auto goes to next line on commit")
STR_HELP("Auto goes to next line on commit") STR_HELP("Auto goes to next line on commit")
void operator()(agi::Context *c) { void operator()(agi::Context *c) {
toggle("Audio/Next Line on Commit"); toggle("Audio/Next Line on Commit");
} }
@ -335,6 +362,7 @@ struct audio_vertical_link : public Command {
STR_MENU("Link vertical zoom and volume sliders") STR_MENU("Link vertical zoom and volume sliders")
STR_DISP("Link vertical zoom and volume sliders") STR_DISP("Link vertical zoom and volume sliders")
STR_HELP("Link vertical zoom and volume sliders") STR_HELP("Link vertical zoom and volume sliders")
void operator()(agi::Context *c) { void operator()(agi::Context *c) {
toggle("Audio/Link"); toggle("Audio/Link");
} }
@ -353,8 +381,10 @@ namespace cmd {
reg(new audio_commit); reg(new audio_commit);
reg(new audio_go_to); reg(new audio_go_to);
reg(new audio_open); reg(new audio_open);
#if _DEBUG
reg(new audio_open_blank); reg(new audio_open_blank);
reg(new audio_open_noise); reg(new audio_open_noise);
#endif
reg(new audio_open_video); reg(new audio_open_video);
reg(new audio_play_after); reg(new audio_play_after);
reg(new audio_play_before); reg(new audio_play_before);

View File

@ -66,6 +66,17 @@ namespace cmd {
/// Command function /// Command function
virtual void operator()(agi::Context *c)=0; virtual void operator()(agi::Context *c)=0;
/// Check whether or not it makes sense to call this command at this time
/// @param c Project context
///
/// This function should be very fast, as it is called whenever a menu
/// containing this command is opened and is called periodically for
/// any commands used in a toolbar
///
/// Note that it is still legal to call commands when this returns
/// false. In this situation, commands should do nothing.
virtual bool Validate(const agi::Context *c) { return true; }
/// Destructor /// Destructor
virtual ~Command() { }; virtual ~Command() { };
}; };

View File

@ -58,8 +58,20 @@ namespace {
/// @defgroup cmd-edit Editing commands. /// @defgroup cmd-edit Editing commands.
/// @{ /// @{
struct validate_sel_nonempty : public Command {
bool Validate(const agi::Context *c) {
return c->selectionController->GetSelectedSet().size() > 0;
}
};
struct validate_sel_multiple : public Command {
bool Validate(const agi::Context *c) {
return c->selectionController->GetSelectedSet().size() > 1;
}
};
/// Copy subtitles. /// Copy subtitles.
struct edit_line_copy : public Command { struct edit_line_copy : public validate_sel_nonempty {
CMD_NAME("edit/line/copy") CMD_NAME("edit/line/copy")
STR_MENU("Copy Lines") STR_MENU("Copy Lines")
STR_DISP("Copy Lines") STR_DISP("Copy Lines")
@ -76,7 +88,7 @@ struct edit_line_copy : public Command {
/// Cut subtitles. /// Cut subtitles.
struct edit_line_cut: public Command { struct edit_line_cut: public validate_sel_nonempty {
CMD_NAME("edit/line/cut") CMD_NAME("edit/line/cut")
STR_MENU("Cut Lines") STR_MENU("Cut Lines")
STR_DISP("Cut Lines") STR_DISP("Cut Lines")
@ -93,7 +105,7 @@ struct edit_line_cut: public Command {
/// Delete currently selected lines. /// Delete currently selected lines.
struct edit_line_delete : public Command { struct edit_line_delete : public validate_sel_nonempty {
CMD_NAME("edit/line/delete") CMD_NAME("edit/line/delete")
STR_MENU("Delete Lines") STR_MENU("Delete Lines")
STR_DISP("Delete Lines") STR_DISP("Delete Lines")
@ -106,7 +118,7 @@ struct edit_line_delete : public Command {
/// Duplicate the selected lines. /// Duplicate the selected lines.
struct edit_line_duplicate : public Command { struct edit_line_duplicate : public validate_sel_nonempty {
CMD_NAME("edit/line/duplicate") CMD_NAME("edit/line/duplicate")
STR_MENU("&Duplicate Lines") STR_MENU("&Duplicate Lines")
STR_DISP("Duplicate Lines") STR_DISP("Duplicate Lines")
@ -126,6 +138,10 @@ struct edit_line_duplicate_shift : public Command {
STR_DISP("Duplicate and Shift by 1 Frame") STR_DISP("Duplicate and Shift by 1 Frame")
STR_HELP("Duplicate lines and shift by one frame.") STR_HELP("Duplicate lines and shift by one frame.")
bool Validate(const agi::Context *c) {
return !c->selectionController->GetSelectedSet().empty() && c->videoController->IsLoaded();
}
void operator()(agi::Context *c) { void operator()(agi::Context *c) {
wxArrayInt sels = c->subsGrid->GetSelection(); wxArrayInt sels = c->subsGrid->GetSelection();
c->subsGrid->DuplicateLines(sels.front(), sels.back(), true); c->subsGrid->DuplicateLines(sels.front(), sels.back(), true);
@ -174,7 +190,7 @@ static void combine_concat(AssDialogue *first, AssDialogue *second) {
static void combine_drop(AssDialogue *, AssDialogue *) { } static void combine_drop(AssDialogue *, AssDialogue *) { }
/// Joins selected lines in a single one, as karaoke. /// Joins selected lines in a single one, as karaoke.
struct edit_line_join_as_karaoke : public Command { struct edit_line_join_as_karaoke : public validate_sel_multiple {
CMD_NAME("edit/line/join/as_karaoke") CMD_NAME("edit/line/join/as_karaoke")
STR_MENU("As &Karaoke") STR_MENU("As &Karaoke")
STR_DISP("As Karaoke") STR_DISP("As Karaoke")
@ -187,7 +203,7 @@ struct edit_line_join_as_karaoke : public Command {
/// Joins selected lines in a single one, concatenating text together. /// Joins selected lines in a single one, concatenating text together.
struct edit_line_join_concatenate : public Command { struct edit_line_join_concatenate : public validate_sel_multiple {
CMD_NAME("edit/line/join/concatenate") CMD_NAME("edit/line/join/concatenate")
STR_MENU("&Concatenate") STR_MENU("&Concatenate")
STR_DISP("Concatenate") STR_DISP("Concatenate")
@ -200,7 +216,7 @@ struct edit_line_join_concatenate : public Command {
/// Joins selected lines in a single one, keeping text of first and discarding remaining. /// Joins selected lines in a single one, keeping text of first and discarding remaining.
struct edit_line_join_keep_first : public Command { struct edit_line_join_keep_first : public validate_sel_multiple {
CMD_NAME("edit/line/join/keep_first") CMD_NAME("edit/line/join/keep_first")
STR_MENU("Keep &First") STR_MENU("Keep &First")
STR_DISP("Keep First") STR_DISP("Keep First")
@ -219,6 +235,15 @@ struct edit_line_paste : public Command {
STR_DISP("Paste Lines") STR_DISP("Paste Lines")
STR_HELP("Paste subtitles.") STR_HELP("Paste subtitles.")
bool Validate(const agi::Context *c) {
if (wxTheClipboard->Open()) {
bool can_paste = wxTheClipboard->IsSupported(wxDF_TEXT);
wxTheClipboard->Close();
return can_paste;
}
return false;
}
void operator()(agi::Context *c) { void operator()(agi::Context *c) {
if (c->parent->FindFocus() == c->editBox->TextEdit) { if (c->parent->FindFocus() == c->editBox->TextEdit) {
c->editBox->TextEdit->Paste(); c->editBox->TextEdit->Paste();
@ -236,6 +261,15 @@ struct edit_line_paste_over : public Command {
STR_DISP("Paste Lines Over") STR_DISP("Paste Lines Over")
STR_HELP("Paste subtitles over others.") STR_HELP("Paste subtitles over others.")
bool Validate(const agi::Context *c) {
if (wxTheClipboard->Open()) {
bool can_paste = wxTheClipboard->IsSupported(wxDF_TEXT);
wxTheClipboard->Close();
return can_paste && c->selectionController->GetSelectedSet().size();
}
return false;
}
void operator()(agi::Context *c) { void operator()(agi::Context *c) {
c->subsGrid->PasteLines(c->subsGrid->GetFirstSelRow(),true); c->subsGrid->PasteLines(c->subsGrid->GetFirstSelRow(),true);
} }
@ -243,7 +277,7 @@ struct edit_line_paste_over : public Command {
/// Recombine subtitles when they have been split and merged. /// Recombine subtitles when they have been split and merged.
struct edit_line_recombine : public Command { struct edit_line_recombine : public validate_sel_multiple {
CMD_NAME("edit/line/recombine") CMD_NAME("edit/line/recombine")
STR_MENU("Recombine Lines") STR_MENU("Recombine Lines")
STR_DISP("Recombine Lines") STR_DISP("Recombine Lines")
@ -256,7 +290,7 @@ struct edit_line_recombine : public Command {
/// Uses karaoke timing to split line into multiple smaller lines. /// Uses karaoke timing to split line into multiple smaller lines.
struct edit_line_split_by_karaoke : public Command { struct edit_line_split_by_karaoke : public validate_sel_nonempty {
CMD_NAME("edit/line/split/by_karaoke") CMD_NAME("edit/line/split/by_karaoke")
STR_MENU("Split Lines (by karaoke)") STR_MENU("Split Lines (by karaoke)")
STR_DISP("Split Lines (by karaoke)") STR_DISP("Split Lines (by karaoke)")
@ -284,6 +318,10 @@ struct edit_line_swap : public Command {
STR_DISP("Swap Lines") STR_DISP("Swap Lines")
STR_HELP("Swaps the two selected lines.") STR_HELP("Swaps the two selected lines.")
bool Validate(const agi::Context *c) {
return c->selectionController->GetSelectedSet().size() == 2;
}
void operator()(agi::Context *c) { void operator()(agi::Context *c) {
SelectionController<AssDialogue>::Selection sel = c->selectionController->GetSelectedSet(); SelectionController<AssDialogue>::Selection sel = c->selectionController->GetSelectedSet();
if (sel.size() == 2) { if (sel.size() == 2) {
@ -305,6 +343,10 @@ struct edit_redo : public Command {
STR_DISP("Redo") STR_DISP("Redo")
STR_HELP("Redoes last action.") STR_HELP("Redoes last action.")
bool Validate(const agi::Context *c) {
return !c->ass->IsRedoStackEmpty();
}
void operator()(agi::Context *c) { void operator()(agi::Context *c) {
c->videoController->Stop(); c->videoController->Stop();
c->ass->Redo(); c->ass->Redo();
@ -333,6 +375,10 @@ struct edit_undo : public Command {
STR_DISP("Undo") STR_DISP("Undo")
STR_HELP("Undoes last action.") STR_HELP("Undoes last action.")
bool Validate(const agi::Context *c) {
return !c->ass->IsUndoStackEmpty();
}
void operator()(agi::Context *c) { void operator()(agi::Context *c) {
c->videoController->Stop(); c->videoController->Stop();
c->ass->Undo(); c->ass->Undo();

View File

@ -167,10 +167,14 @@ struct grid_swap_up : public Command {
STR_DISP("Move line up") STR_DISP("Move line up")
STR_HELP("Move the selected line up one row") STR_HELP("Move the selected line up one row")
bool Validate(agi::Context *c) {
return c->selectionController->GetActiveLine() != 0;
}
void operator()(agi::Context *c) { void operator()(agi::Context *c) {
if (AssDialogue *line = c->selectionController->GetActiveLine()) { if (AssDialogue *line = c->selectionController->GetActiveLine()) {
if (move_one(c->ass->Line.rbegin(), c->ass->Line.rend(), line)) if (move_one(c->ass->Line.rbegin(), c->ass->Line.rend(), line))
/// todo Maybe add COMMIT_ORDER, as the grid is the only thing /// @todo Maybe add COMMIT_ORDER, as the grid is the only thing
/// that needs to care about this /// that needs to care about this
/// Probably not worth it /// Probably not worth it
c->ass->Commit(_("swap lines"), AssFile::COMMIT_FULL); c->ass->Commit(_("swap lines"), AssFile::COMMIT_FULL);
@ -185,6 +189,10 @@ struct grid_swap_down : public Command {
STR_DISP("Move line down") STR_DISP("Move line down")
STR_HELP("Move the selected line down one row") STR_HELP("Move the selected line down one row")
bool Validate(agi::Context *c) {
return c->selectionController->GetActiveLine() != 0;
}
void operator()(agi::Context *c) { void operator()(agi::Context *c) {
if (AssDialogue *line = c->selectionController->GetActiveLine()) { if (AssDialogue *line = c->selectionController->GetActiveLine()) {
if (move_one(c->ass->Line.begin(), c->ass->Line.end(), line)) if (move_one(c->ass->Line.begin(), c->ass->Line.end(), line))

View File

@ -62,6 +62,10 @@ struct keyframe_close : public Command {
STR_DISP("Close Keyframes") STR_DISP("Close Keyframes")
STR_HELP("Closes the currently open keyframes list.") STR_HELP("Closes the currently open keyframes list.")
bool Validate(const agi::Context *c) {
return c->videoController->OverKeyFramesLoaded();
}
void operator()(agi::Context *c) { void operator()(agi::Context *c) {
c->videoController->CloseKeyframes(); c->videoController->CloseKeyframes();
} }
@ -99,6 +103,10 @@ struct keyframe_save : public Command {
STR_DISP("Save Keyframes") STR_DISP("Save Keyframes")
STR_HELP("Saves the current keyframe list.") STR_HELP("Saves the current keyframe list.")
bool Validate(const agi::Context *c) {
return c->videoController->KeyFramesLoaded();
}
void operator()(agi::Context *c) { void operator()(agi::Context *c) {
wxString path = lagi_wxString(OPT_GET("Path/Last/Keyframes")->GetString()); wxString path = lagi_wxString(OPT_GET("Path/Last/Keyframes")->GetString());
wxString filename = wxFileSelector(_T("Select the Keyframes file to open"),path,_T(""),_T("*.key.txt"),_T("Text files (*.txt)|*.txt"),wxFD_OVERWRITE_PROMPT | wxFD_SAVE); wxString filename = wxFileSelector(_T("Select the Keyframes file to open"),path,_T(""),_T("*.key.txt"),_T("Text files (*.txt)|*.txt"),wxFD_OVERWRITE_PROMPT | wxFD_SAVE);

View File

@ -67,6 +67,18 @@ namespace {
/// @defgroup cmd-subtitle Subtitle commands. /// @defgroup cmd-subtitle Subtitle commands.
/// @{ /// @{
struct validate_nonempty_selection : public Command {
bool Validate(const agi::Context *c) {
return !c->selectionController->GetSelectedSet().empty();
}
};
struct validate_nonempty_selection_video_loaded : public Command {
bool Validate(const agi::Context *c) {
return c->videoController->IsLoaded() && !c->selectionController->GetSelectedSet().empty();
}
};
/// Open the attachment list. /// Open the attachment list.
struct subtitle_attachment : public Command { struct subtitle_attachment : public Command {
CMD_NAME("subtitle/attachment") CMD_NAME("subtitle/attachment")
@ -127,7 +139,7 @@ static void insert_subtitle_at_video(agi::Context *c, bool after) {
} }
/// Inserts a line after current. /// Inserts a line after current.
struct subtitle_insert_after : public Command { struct subtitle_insert_after : public validate_nonempty_selection {
CMD_NAME("subtitle/insert/after") CMD_NAME("subtitle/insert/after")
STR_MENU("&After Current") STR_MENU("&After Current")
STR_DISP("After Current") STR_DISP("After Current")
@ -161,7 +173,7 @@ struct subtitle_insert_after : public Command {
}; };
/// Inserts a line after current, starting at video time. /// Inserts a line after current, starting at video time.
struct subtitle_insert_after_videotime : public Command { struct subtitle_insert_after_videotime : public validate_nonempty_selection_video_loaded {
CMD_NAME("subtitle/insert/after/videotime") CMD_NAME("subtitle/insert/after/videotime")
STR_MENU("After Current, at Video Time") STR_MENU("After Current, at Video Time")
STR_DISP("After Current, at Video Time") STR_DISP("After Current, at Video Time")
@ -174,7 +186,7 @@ struct subtitle_insert_after_videotime : public Command {
/// Inserts a line before current. /// Inserts a line before current.
struct subtitle_insert_before : public Command { struct subtitle_insert_before : public validate_nonempty_selection {
CMD_NAME("subtitle/insert/before") CMD_NAME("subtitle/insert/before")
STR_MENU("&Before Current") STR_MENU("&Before Current")
STR_DISP("Before Current") STR_DISP("Before Current")
@ -211,7 +223,7 @@ struct subtitle_insert_before : public Command {
/// Inserts a line before current, starting at video time. /// Inserts a line before current, starting at video time.
struct subtitle_insert_before_videotime : public Command { struct subtitle_insert_before_videotime : public validate_nonempty_selection_video_loaded {
CMD_NAME("subtitle/insert/before/videotime") CMD_NAME("subtitle/insert/before/videotime")
STR_MENU("Before Current, at Video Time") STR_MENU("Before Current, at Video Time")
STR_DISP("Before Current, at Video Time") STR_DISP("Before Current, at Video Time")
@ -286,6 +298,10 @@ struct subtitle_open_video : public Command {
void operator()(agi::Context *c) { void operator()(agi::Context *c) {
wxGetApp().frame->LoadSubtitles(c->videoController->videoName, "binary"); wxGetApp().frame->LoadSubtitles(c->videoController->videoName, "binary");
} }
bool Validate(const agi::Context *c) {
return c->videoController->IsLoaded() && c->videoController->HasSubtitles();
}
}; };
@ -377,6 +393,10 @@ struct subtitle_select_visible : public Command {
c->videoController->Stop(); c->videoController->Stop();
c->subsGrid->SelectVisible(); c->subsGrid->SelectVisible();
} }
bool Validate(agi::Context *c) {
return c->videoController->IsLoaded();
}
}; };

View File

@ -57,11 +57,38 @@
namespace { namespace {
using cmd::Command; using cmd::Command;
struct validate_video_loaded : public Command {
bool Validate(const agi::Context *c) {
return c->videoController->IsLoaded();
}
};
struct validate_adjoinable : public Command {
bool Validate(const agi::Context *c) {
SelectionController<AssDialogue>::Selection sel = c->selectionController->GetSelectedSet();
if (sel.size() < 2) return false;
bool found = false;
for (entryIter it = c->ass->Line.begin(); it != c->ass->Line.end(); ++it) {
AssDialogue *diag = dynamic_cast<AssDialogue*>(*it);
if (!diag) continue;
if (sel.count(diag)) {
found = true;
}
else if (found) {
return false;
}
}
return true;
}
};
/// @defgroup cmd-time Time manipulation commands. /// @defgroup cmd-time Time manipulation commands.
/// @{ /// @{
/// Changes times of subs so end times begin on next's start time. /// Changes times of subs so end times begin on next's start time.
struct time_continuous_end : public Command { struct time_continuous_end : public validate_adjoinable {
CMD_NAME("time/continuous/end") CMD_NAME("time/continuous/end")
STR_MENU("Change &End") STR_MENU("Change &End")
STR_DISP("Change End") STR_DISP("Change End")
@ -75,7 +102,7 @@ struct time_continuous_end : public Command {
/// Changes times of subs so start times begin on previous's end time. /// Changes times of subs so start times begin on previous's end time.
struct time_continuous_start : public Command { struct time_continuous_start : public validate_adjoinable {
CMD_NAME("time/continuous/start") CMD_NAME("time/continuous/start")
STR_MENU("Change &Start") STR_MENU("Change &Start")
STR_DISP("Change Start") STR_DISP("Change Start")
@ -90,7 +117,7 @@ struct time_continuous_start : public Command {
/// Shift selection so first selected line starts at current frame. /// Shift selection so first selected line starts at current frame.
struct time_frame_current : public Command { struct time_frame_current : public validate_video_loaded {
CMD_NAME("time/frame/current") CMD_NAME("time/frame/current")
STR_MENU("Shift to Current Frame") STR_MENU("Shift to Current Frame")
STR_DISP("Shift to Current Frame") STR_DISP("Shift to Current Frame")
@ -139,7 +166,7 @@ struct time_shift : public Command {
/// Set end of selected subtitles to current video frame. /// Set end of selected subtitles to current video frame.
struct time_snap_end_video : public Command { struct time_snap_end_video : public validate_video_loaded {
CMD_NAME("time/snap/end_video") CMD_NAME("time/snap/end_video")
STR_MENU("Snap End to Video") STR_MENU("Snap End to Video")
STR_DISP("Snap End to Video") STR_DISP("Snap End to Video")
@ -152,7 +179,7 @@ struct time_snap_end_video : public Command {
/// Shift selected subtitles so first selected starts at this frame. /// Shift selected subtitles so first selected starts at this frame.
struct time_snap_frame : public Command { struct time_snap_frame : public validate_video_loaded {
CMD_NAME("time/snap/frame") CMD_NAME("time/snap/frame")
STR_MENU("Shift Subtitles to Frame") STR_MENU("Shift Subtitles to Frame")
STR_DISP("Shift Subtitles to Frame") STR_DISP("Shift Subtitles to Frame")
@ -181,7 +208,7 @@ struct time_snap_frame : public Command {
/// Set start and end of subtitles to the keyframes around current video frame. /// Set start and end of subtitles to the keyframes around current video frame.
struct time_snap_scene : public Command { struct time_snap_scene : public validate_video_loaded {
CMD_NAME("time/snap/scene") CMD_NAME("time/snap/scene")
STR_MENU("Snap to Scene") STR_MENU("Snap to Scene")
STR_DISP("Snap to Scene") STR_DISP("Snap to Scene")
@ -262,7 +289,7 @@ struct time_add_lead_out : public Command {
/// Set start of selected subtitles to current video frame. /// Set start of selected subtitles to current video frame.
struct time_snap_start_video : public Command { struct time_snap_start_video : public validate_video_loaded {
CMD_NAME("time/snap/start_video") CMD_NAME("time/snap/start_video")
STR_MENU("Snap Start to Video") STR_MENU("Snap Start to Video")
STR_DISP("Snap Start to Video") STR_DISP("Snap Start to Video")

View File

@ -62,6 +62,10 @@ struct timecode_close : public Command {
STR_DISP("Close Timecodes File") STR_DISP("Close Timecodes File")
STR_HELP("Closes the currently open timecodes file.") STR_HELP("Closes the currently open timecodes file.")
bool Validate(const agi::Context *c) {
return c->videoController->OverTimecodesLoaded();
}
void operator()(agi::Context *c) { void operator()(agi::Context *c) {
c->videoController->CloseTimecodes(); c->videoController->CloseTimecodes();
} }
@ -94,6 +98,10 @@ struct timecode_save : public Command {
STR_DISP("Save Timecodes File") STR_DISP("Save Timecodes File")
STR_HELP("Saves a VFR timecodes v2 file.") STR_HELP("Saves a VFR timecodes v2 file.")
bool Validate(const agi::Context *c) {
return c->videoController->TimecodesLoaded();
}
void operator()(agi::Context *c) { void operator()(agi::Context *c) {
wxString path = lagi_wxString(OPT_GET("Path/Last/Timecodes")->GetString()); wxString path = lagi_wxString(OPT_GET("Path/Last/Timecodes")->GetString());
wxString str = wxString(_("All Supported Types")) + _T("(*.txt)|*.txt|") + _("All Files") + _T(" (*.*)|*.*"); wxString str = wxString(_("All Supported Types")) + _T("(*.txt)|*.txt|") + _("All Files") + _T(" (*.*)|*.*");

View File

@ -63,9 +63,20 @@ namespace {
/// @defgroup cmd-video Video commands. /// @defgroup cmd-video Video commands.
/// @{ /// @{
struct validator_video_loaded : public Command {
bool Validate(const agi::Context *c) {
return c->videoController->IsLoaded();
}
};
struct validator_video_attached : public Command {
bool Validate(const agi::Context *c) {
return c->videoController->IsLoaded() && !c->detachedVideo;
}
};
/// Forces video to 2.35 aspect ratio. /// Forces video to 2.35 aspect ratio.
struct video_aspect_cinematic : public Command { struct video_aspect_cinematic : public validator_video_attached {
CMD_NAME("video/aspect/cinematic") CMD_NAME("video/aspect/cinematic")
STR_MENU("&Cinematic (2.35)") STR_MENU("&Cinematic (2.35)")
STR_DISP("Cinematic (235)") STR_DISP("Cinematic (235)")
@ -78,9 +89,8 @@ struct video_aspect_cinematic : public Command {
} }
}; };
/// Forces video to a custom aspect ratio. /// Forces video to a custom aspect ratio.
struct video_aspect_custom : public Command { struct video_aspect_custom : public validator_video_attached {
CMD_NAME("video/aspect/custom") CMD_NAME("video/aspect/custom")
STR_MENU("Custom..") STR_MENU("Custom..")
STR_DISP("Custom") STR_DISP("Custom")
@ -134,10 +144,8 @@ struct video_aspect_custom : public Command {
} }
}; };
/// Leave video on original aspect ratio. /// Leave video on original aspect ratio.
struct video_aspect_default : public Command { struct video_aspect_default : public validator_video_attached {
CMD_NAME("video/aspect/default") CMD_NAME("video/aspect/default")
STR_MENU("&Default") STR_MENU("&Default")
STR_DISP("Default") STR_DISP("Default")
@ -150,10 +158,8 @@ struct video_aspect_default : public Command {
} }
}; };
/// Forces video to 4:3 aspect ratio. /// Forces video to 4:3 aspect ratio.
struct video_aspect_full : public Command { struct video_aspect_full : public validator_video_attached {
CMD_NAME("video/aspect/full") CMD_NAME("video/aspect/full")
STR_MENU("&Fullscreen (4:3)") STR_MENU("&Fullscreen (4:3)")
STR_DISP("Fullscreen (4:3)") STR_DISP("Fullscreen (4:3)")
@ -166,9 +172,8 @@ struct video_aspect_full : public Command {
} }
}; };
/// Forces video to 16:9 aspect ratio. /// Forces video to 16:9 aspect ratio.
struct video_aspect_wide : public Command { struct video_aspect_wide : public validator_video_attached {
CMD_NAME("video/aspect/wide") CMD_NAME("video/aspect/wide")
STR_MENU("&Widescreen (16:9)") STR_MENU("&Widescreen (16:9)")
STR_DISP("Widescreen (16:9)") STR_DISP("Widescreen (16:9)")
@ -181,9 +186,8 @@ struct video_aspect_wide : public Command {
} }
}; };
/// Closes the currently open video file. /// Closes the currently open video file.
struct video_close : public Command { struct video_close : public validator_video_loaded {
CMD_NAME("video/close") CMD_NAME("video/close")
STR_MENU("&Close Video") STR_MENU("&Close Video")
STR_DISP("Close Video") STR_DISP("Close Video")
@ -194,10 +198,8 @@ struct video_close : public Command {
} }
}; };
/// Detach video, displaying it in a separate Window. /// Detach video, displaying it in a separate Window.
struct video_detach : public Command { struct video_detach : public validator_video_loaded {
CMD_NAME("video/detach") CMD_NAME("video/detach")
STR_MENU("Detach Video") STR_MENU("Detach Video")
STR_DISP("Detach Video") STR_DISP("Detach Video")
@ -208,9 +210,8 @@ struct video_detach : public Command {
} }
}; };
/// Shows video details. /// Shows video details.
struct video_details : public Command { struct video_details : public validator_video_loaded {
CMD_NAME("video/details") CMD_NAME("video/details")
STR_MENU("Show Video Details..") STR_MENU("Show Video Details..")
STR_DISP("Show Video Details") STR_DISP("Show Video Details")
@ -222,9 +223,8 @@ struct video_details : public Command {
} }
}; };
/// ///
struct video_focus_seek : public Command { struct video_focus_seek : public validator_video_loaded {
CMD_NAME("video/focus_seek") CMD_NAME("video/focus_seek")
STR_MENU("XXX: no idea") STR_MENU("XXX: no idea")
STR_DISP("XXX: no idea") STR_DISP("XXX: no idea")
@ -242,9 +242,8 @@ struct video_focus_seek : public Command {
} }
}; };
/// Seek to the next frame. /// Seek to the next frame.
struct video_frame_next : public Command { struct video_frame_next : public validator_video_loaded {
CMD_NAME("video/frame/next") CMD_NAME("video/frame/next")
STR_MENU("Next Frame") STR_MENU("Next Frame")
STR_DISP("Next Frame") STR_DISP("Next Frame")
@ -256,7 +255,7 @@ struct video_frame_next : public Command {
}; };
/// Seek to the next subtitle boundary. /// Seek to the next subtitle boundary.
struct video_frame_next_boundary : public Command { struct video_frame_next_boundary : public validator_video_loaded {
CMD_NAME("video/frame/next/boundary") CMD_NAME("video/frame/next/boundary")
STR_MENU("Next Boundary") STR_MENU("Next Boundary")
STR_DISP("Next Boundary") STR_DISP("Next Boundary")
@ -286,7 +285,7 @@ struct video_frame_next_boundary : public Command {
}; };
/// Seek to the next keyframe. /// Seek to the next keyframe.
struct video_frame_next_keyframe : public Command { struct video_frame_next_keyframe : public validator_video_loaded {
CMD_NAME("video/frame/next/keyframe") CMD_NAME("video/frame/next/keyframe")
STR_MENU("Next Keyframe") STR_MENU("Next Keyframe")
STR_DISP("Next Keyframe") STR_DISP("Next Keyframe")
@ -302,7 +301,7 @@ struct video_frame_next_keyframe : public Command {
}; };
/// Fast jump forward /// Fast jump forward
struct video_frame_next_large : public Command { struct video_frame_next_large : public validator_video_loaded {
CMD_NAME("video/frame/next/large") CMD_NAME("video/frame/next/large")
STR_MENU("Fast jump forward") STR_MENU("Fast jump forward")
STR_DISP("Fast jump forward") STR_DISP("Fast jump forward")
@ -316,7 +315,7 @@ struct video_frame_next_large : public Command {
}; };
/// Seek to the previous frame. /// Seek to the previous frame.
struct video_frame_prev : public Command { struct video_frame_prev : public validator_video_loaded {
CMD_NAME("video/frame/prev") CMD_NAME("video/frame/prev")
STR_MENU("Previous Frame") STR_MENU("Previous Frame")
STR_DISP("Previous Frame") STR_DISP("Previous Frame")
@ -328,7 +327,7 @@ struct video_frame_prev : public Command {
}; };
/// Seek to the previous subtitle boundary. /// Seek to the previous subtitle boundary.
struct video_frame_prev_boundary : public Command { struct video_frame_prev_boundary : public validator_video_loaded {
CMD_NAME("video/frame/prev/boundary") CMD_NAME("video/frame/prev/boundary")
STR_MENU("Previous Boundary") STR_MENU("Previous Boundary")
STR_DISP("Previous Boundary") STR_DISP("Previous Boundary")
@ -358,7 +357,7 @@ struct video_frame_prev_boundary : public Command {
}; };
/// Seek to the previous keyframe. /// Seek to the previous keyframe.
struct video_frame_prev_keyframe : public Command { struct video_frame_prev_keyframe : public validator_video_loaded {
CMD_NAME("video/frame/prev/keyframe") CMD_NAME("video/frame/prev/keyframe")
STR_MENU("Previous Keyframe") STR_MENU("Previous Keyframe")
STR_DISP("Previous Keyframe") STR_DISP("Previous Keyframe")
@ -377,7 +376,7 @@ struct video_frame_prev_keyframe : public Command {
}; };
/// Fast jump backwards /// Fast jump backwards
struct video_frame_prev_large : public Command { struct video_frame_prev_large : public validator_video_loaded {
CMD_NAME("video/frame/prev/large") CMD_NAME("video/frame/prev/large")
STR_MENU("Fast jump backwards") STR_MENU("Fast jump backwards")
STR_DISP("Fast jump backwards") STR_DISP("Fast jump backwards")
@ -391,7 +390,7 @@ struct video_frame_prev_large : public Command {
}; };
/// Jump to frame or time. /// Jump to frame or time.
struct video_jump : public Command { struct video_jump : public validator_video_loaded {
CMD_NAME("video/jump") CMD_NAME("video/jump")
STR_MENU("&Jump to..") STR_MENU("&Jump to..")
STR_DISP("Jump to") STR_DISP("Jump to")
@ -406,9 +405,8 @@ struct video_jump : public Command {
} }
}; };
/// Jumps the video to the end frame of current subtitle. /// Jumps the video to the end frame of current subtitle.
struct video_jump_end : public Command { struct video_jump_end : public validator_video_loaded {
CMD_NAME("video/jump/end") CMD_NAME("video/jump/end")
STR_MENU("Jump Video to End") STR_MENU("Jump Video to End")
STR_DISP("Jump Video to End") STR_DISP("Jump Video to End")
@ -419,9 +417,8 @@ struct video_jump_end : public Command {
} }
}; };
/// Jumps the video to the start frame of current subtitle. /// Jumps the video to the start frame of current subtitle.
struct video_jump_start : public Command { struct video_jump_start : public validator_video_loaded {
CMD_NAME("video/jump/start") CMD_NAME("video/jump/start")
STR_MENU("Jump Video to Start") STR_MENU("Jump Video to Start")
STR_DISP("Jump Video to Start") STR_DISP("Jump Video to Start")
@ -432,7 +429,6 @@ struct video_jump_start : public Command {
} }
}; };
/// Opens a video file. /// Opens a video file.
struct video_open : public Command { struct video_open : public Command {
CMD_NAME("video/open") CMD_NAME("video/open")
@ -452,7 +448,6 @@ struct video_open : public Command {
} }
}; };
/// Opens a video clip with solid colour. /// Opens a video clip with solid colour.
struct video_open_dummy : public Command { struct video_open_dummy : public Command {
CMD_NAME("video/open/dummy") CMD_NAME("video/open/dummy")
@ -481,7 +476,7 @@ struct video_opt_autoscroll : public Command {
}; };
/// Play video. /// Play video.
struct video_play : public Command { struct video_play : public validator_video_loaded {
CMD_NAME("video/play") CMD_NAME("video/play")
STR_MENU("Play") STR_MENU("Play")
STR_DISP("Play") STR_DISP("Play")
@ -493,7 +488,7 @@ struct video_play : public Command {
}; };
/// Play video for the active line. /// Play video for the active line.
struct video_play_line : public Command { struct video_play_line : public validator_video_loaded {
CMD_NAME("video/play/line") CMD_NAME("video/play/line")
STR_MENU("Play line") STR_MENU("Play line")
STR_DISP("Play line") STR_DISP("Play line")
@ -505,7 +500,7 @@ struct video_play_line : public Command {
}; };
/// Show a mask over the video. /// Show a mask over the video.
struct video_show_overscan : public Command { struct video_show_overscan : public validator_video_loaded {
CMD_NAME("video/show_overscan") CMD_NAME("video/show_overscan")
STR_MENU("Show Overscan Mask") STR_MENU("Show Overscan Mask")
STR_DISP("Show Overscan Mask") STR_DISP("Show Overscan Mask")
@ -517,9 +512,8 @@ struct video_show_overscan : public Command {
} }
}; };
/// Set zoom to 100%. /// Set zoom to 100%.
class video_zoom_100: public Command { class video_zoom_100: public validator_video_attached {
public: public:
CMD_NAME("video/zoom/100") CMD_NAME("video/zoom/100")
STR_MENU("&100%") STR_MENU("&100%")
@ -533,7 +527,7 @@ public:
}; };
/// Stop video playback /// Stop video playback
class video_stop: public Command { class video_stop: public validator_video_loaded {
public: public:
CMD_NAME("video/stop") CMD_NAME("video/stop")
STR_MENU("Stop video") STR_MENU("Stop video")
@ -546,7 +540,7 @@ public:
}; };
/// Set zoom to 200%. /// Set zoom to 200%.
class video_zoom_200: public Command { class video_zoom_200: public validator_video_attached {
public: public:
CMD_NAME("video/zoom/200") CMD_NAME("video/zoom/200")
STR_MENU("&200%") STR_MENU("&200%")
@ -559,9 +553,8 @@ public:
} }
}; };
/// Set zoom to 50%. /// Set zoom to 50%.
class video_zoom_50: public Command { class video_zoom_50: public validator_video_attached {
public: public:
CMD_NAME("video/zoom/50") CMD_NAME("video/zoom/50")
STR_MENU("&50%") STR_MENU("&50%")
@ -574,9 +567,8 @@ public:
} }
}; };
/// Zoom video in. /// Zoom video in.
struct video_zoom_in : public Command { struct video_zoom_in : public validator_video_attached {
CMD_NAME("video/zoom/in") CMD_NAME("video/zoom/in")
STR_MENU("Zoom In") STR_MENU("Zoom In")
STR_DISP("Zoom In") STR_DISP("Zoom In")
@ -587,9 +579,8 @@ struct video_zoom_in : public Command {
} }
}; };
/// Zoom video out. /// Zoom video out.
struct video_zoom_out : public Command { struct video_zoom_out : public validator_video_attached {
CMD_NAME("video/zoom/out") CMD_NAME("video/zoom/out")
STR_MENU("Zoom Out") STR_MENU("Zoom Out")
STR_DISP("Zoom Out") STR_DISP("Zoom Out")

View File

@ -764,15 +764,6 @@ void FrameMain::OnMenuOpen (wxMenuEvent &event) {
// View menu // View menu
else if (curMenu == menu::menu->GetMenu("main/view")) { else if (curMenu == menu::menu->GetMenu("main/view")) {
// Flags
bool aud = context->audioController->IsAudioOpen();
bool vid = context->videoController->IsLoaded() && !context->detachedVideo;
// Set states
MenuBar->Enable(cmd::id("app/display/audio_subs"),aud);
MenuBar->Enable(cmd::id("app/display/video_subs"),vid);
MenuBar->Enable(cmd::id("app/display/full"),aud && vid);
// Select option // Select option
if (!showVideo && !showAudio) MenuBar->Check(cmd::id("app/display/subs"),true); if (!showVideo && !showAudio) MenuBar->Check(cmd::id("app/display/subs"),true);
else if (showVideo && !showAudio) MenuBar->Check(cmd::id("app/display/video_subs"),true); else if (showVideo && !showAudio) MenuBar->Check(cmd::id("app/display/video_subs"),true);
@ -783,37 +774,14 @@ void FrameMain::OnMenuOpen (wxMenuEvent &event) {
if (sub_grid == 1) MenuBar->Check(cmd::id("grid/tags/show"), true); if (sub_grid == 1) MenuBar->Check(cmd::id("grid/tags/show"), true);
if (sub_grid == 2) MenuBar->Check(cmd::id("grid/tags/simplify"), true); if (sub_grid == 2) MenuBar->Check(cmd::id("grid/tags/simplify"), true);
if (sub_grid == 3) MenuBar->Check(cmd::id("grid/tags/hide"), true); if (sub_grid == 3) MenuBar->Check(cmd::id("grid/tags/hide"), true);
} }
// Video menu // Video menu
else if (curMenu == menu::menu->GetMenu("main/video")) { else if (curMenu == menu::menu->GetMenu("main/video")) {
bool state = context->videoController->IsLoaded();
bool attached = state && !context->detachedVideo;
// Set states // Set states
MenuBar->Enable(cmd::id("video/jump"),state);
MenuBar->Enable(cmd::id("video/jump/start"),state);
MenuBar->Enable(cmd::id("video/jump/end"),state);
MenuBar->Enable(cmd::id("main/video/set zoom"), attached);
MenuBar->Enable(cmd::id("video/zoom/50"),attached);
MenuBar->Enable(cmd::id("video/zoom/100"),attached);
MenuBar->Enable(cmd::id("video/zoom/200"),attached);
MenuBar->Enable(cmd::id("video/close"),state);
MenuBar->Enable(cmd::id("main/video/override ar"),attached);
MenuBar->Enable(cmd::id("video/aspect/default"),attached);
MenuBar->Enable(cmd::id("video/aspect/full"),attached);
MenuBar->Enable(cmd::id("video/aspect/wide"),attached);
MenuBar->Enable(cmd::id("video/aspect/cinematic"),attached);
MenuBar->Enable(cmd::id("video/aspect/custom"),attached);
MenuBar->Enable(cmd::id("video/detach"),state);
MenuBar->Enable(cmd::id("timecode/save"),context->videoController->TimecodesLoaded()); MenuBar->Enable(cmd::id("timecode/save"),context->videoController->TimecodesLoaded());
MenuBar->Enable(cmd::id("timecode/close"),context->videoController->OverTimecodesLoaded()); MenuBar->Enable(cmd::id("timecode/close"),context->videoController->OverTimecodesLoaded());
MenuBar->Enable(cmd::id("keyframe/close"),context->videoController->OverKeyFramesLoaded()); MenuBar->Enable(cmd::id("keyframe/close"),context->videoController->OverKeyFramesLoaded());
MenuBar->Enable(cmd::id("keyframe/save"),context->videoController->KeyFramesLoaded()); MenuBar->Enable(cmd::id("keyframe/save"),context->videoController->KeyFramesLoaded());
MenuBar->Enable(cmd::id("video/details"),state);
MenuBar->Enable(cmd::id("video/show_overscan"),state);
// Set AR radio // Set AR radio
int arType = context->videoController->GetAspectRatioType(); int arType = context->videoController->GetAspectRatioType();
@ -861,13 +829,7 @@ void FrameMain::OnMenuOpen (wxMenuEvent &event) {
// Entries // Entries
state = count > 0; state = count > 0;
MenuBar->Enable(cmd::id("subtitle/insert/before"),state);
MenuBar->Enable(cmd::id("subtitle/insert/after"),state);
MenuBar->Enable(cmd::id("edit/line/split/by_karaoke"),state);
MenuBar->Enable(cmd::id("edit/line/delete"),state);
state2 = count > 0 && context->videoController->IsLoaded(); state2 = count > 0 && context->videoController->IsLoaded();
MenuBar->Enable(cmd::id("subtitle/insert/before/videotime"),state2);
MenuBar->Enable(cmd::id("subtitle/insert/after/videotime"),state2);
MenuBar->Enable(cmd::id("main/subtitle/insert lines"),state); MenuBar->Enable(cmd::id("main/subtitle/insert lines"),state);
state = count > 0 && continuous; state = count > 0 && continuous;
MenuBar->Enable(cmd::id("edit/line/duplicate"),state); MenuBar->Enable(cmd::id("edit/line/duplicate"),state);

View File

@ -188,11 +188,10 @@ void SubtitlesGrid::OnPopupMenu(bool alternate) {
// Duplicate selection // Duplicate selection
append_command(menu, "edit/line/duplicate", state); append_command(menu, "edit/line/duplicate", state);
append_command(menu, "edit/line/duplicate/shift", state); append_command(menu, "edit/line/duplicate/shift", state);
append_command(menu, "edit/line/join/as_karaoke", state);
// Swaps selection // Swaps selection
state = (sels == 2); state = (sels == 2);
//append_command(menu, "MENU_SWAP", state); append_command(menu, "edit/line/swap", state);
// Join selection // Join selection
state = (sels >= 2 && continuous); state = (sels >= 2 && continuous);