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
/// @param[out] cont Is the selection contiguous, i.e. free from holes
/// @return Array with indices of selected lines
///
wxArrayInt BaseGrid::GetSelection(bool *cont) const {
int last = -1;
bool continuous = true;
std::set<int> sel_row_indices;
wxArrayInt BaseGrid::GetSelection() const {
wxArrayInt res(selection.size());
for (Selection::const_iterator it = selection.begin(); it != selection.end(); ++it) {
sel_row_indices.insert(GetDialogueIndex(*it));
res.push_back(GetDialogueIndex(*it));
}
// 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;
std::sort(res.begin(), res.end());
return res;
}

View File

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

View File

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

View File

@ -66,6 +66,17 @@ namespace cmd {
/// Command function
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
virtual ~Command() { };
};

View File

@ -58,8 +58,20 @@ namespace {
/// @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.
struct edit_line_copy : public Command {
struct edit_line_copy : public validate_sel_nonempty {
CMD_NAME("edit/line/copy")
STR_MENU("Copy Lines")
STR_DISP("Copy Lines")
@ -76,7 +88,7 @@ struct edit_line_copy : public Command {
/// Cut subtitles.
struct edit_line_cut: public Command {
struct edit_line_cut: public validate_sel_nonempty {
CMD_NAME("edit/line/cut")
STR_MENU("Cut Lines")
STR_DISP("Cut Lines")
@ -93,7 +105,7 @@ struct edit_line_cut: public Command {
/// Delete currently selected lines.
struct edit_line_delete : public Command {
struct edit_line_delete : public validate_sel_nonempty {
CMD_NAME("edit/line/delete")
STR_MENU("Delete Lines")
STR_DISP("Delete Lines")
@ -106,7 +118,7 @@ struct edit_line_delete : public Command {
/// Duplicate the selected lines.
struct edit_line_duplicate : public Command {
struct edit_line_duplicate : public validate_sel_nonempty {
CMD_NAME("edit/line/duplicate")
STR_MENU("&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_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) {
wxArrayInt sels = c->subsGrid->GetSelection();
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 *) { }
/// 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")
STR_MENU("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.
struct edit_line_join_concatenate : public Command {
struct edit_line_join_concatenate : public validate_sel_multiple {
CMD_NAME("edit/line/join/concatenate")
STR_MENU("&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.
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")
STR_MENU("Keep &First")
STR_DISP("Keep First")
@ -219,6 +235,15 @@ struct edit_line_paste : public Command {
STR_DISP("Paste Lines")
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) {
if (c->parent->FindFocus() == c->editBox->TextEdit) {
c->editBox->TextEdit->Paste();
@ -236,6 +261,15 @@ struct edit_line_paste_over : public Command {
STR_DISP("Paste Lines Over")
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) {
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.
struct edit_line_recombine : public Command {
struct edit_line_recombine : public validate_sel_multiple {
CMD_NAME("edit/line/recombine")
STR_MENU("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.
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")
STR_MENU("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_HELP("Swaps the two selected lines.")
bool Validate(const agi::Context *c) {
return c->selectionController->GetSelectedSet().size() == 2;
}
void operator()(agi::Context *c) {
SelectionController<AssDialogue>::Selection sel = c->selectionController->GetSelectedSet();
if (sel.size() == 2) {
@ -305,6 +343,10 @@ struct edit_redo : public Command {
STR_DISP("Redo")
STR_HELP("Redoes last action.")
bool Validate(const agi::Context *c) {
return !c->ass->IsRedoStackEmpty();
}
void operator()(agi::Context *c) {
c->videoController->Stop();
c->ass->Redo();
@ -333,6 +375,10 @@ struct edit_undo : public Command {
STR_DISP("Undo")
STR_HELP("Undoes last action.")
bool Validate(const agi::Context *c) {
return !c->ass->IsUndoStackEmpty();
}
void operator()(agi::Context *c) {
c->videoController->Stop();
c->ass->Undo();

View File

@ -167,12 +167,16 @@ struct grid_swap_up : public Command {
STR_DISP("Move line up")
STR_HELP("Move the selected line up one row")
bool Validate(agi::Context *c) {
return c->selectionController->GetActiveLine() != 0;
}
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
/// @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);
}
}
@ -185,6 +189,10 @@ struct grid_swap_down : public Command {
STR_DISP("Move line down")
STR_HELP("Move the selected line down one row")
bool Validate(agi::Context *c) {
return c->selectionController->GetActiveLine() != 0;
}
void operator()(agi::Context *c) {
if (AssDialogue *line = c->selectionController->GetActiveLine()) {
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_HELP("Closes the currently open keyframes list.")
bool Validate(const agi::Context *c) {
return c->videoController->OverKeyFramesLoaded();
}
void operator()(agi::Context *c) {
c->videoController->CloseKeyframes();
}
@ -99,6 +103,10 @@ struct keyframe_save : public Command {
STR_DISP("Save Keyframes")
STR_HELP("Saves the current keyframe list.")
bool Validate(const agi::Context *c) {
return c->videoController->KeyFramesLoaded();
}
void operator()(agi::Context *c) {
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);

View File

@ -67,6 +67,18 @@ namespace {
/// @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.
struct subtitle_attachment : public Command {
CMD_NAME("subtitle/attachment")
@ -127,7 +139,7 @@ static void insert_subtitle_at_video(agi::Context *c, bool after) {
}
/// Inserts a line after current.
struct subtitle_insert_after : public Command {
struct subtitle_insert_after : public validate_nonempty_selection {
CMD_NAME("subtitle/insert/after")
STR_MENU("&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.
struct subtitle_insert_after_videotime : public Command {
struct subtitle_insert_after_videotime : public validate_nonempty_selection_video_loaded {
CMD_NAME("subtitle/insert/after/videotime")
STR_MENU("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.
struct subtitle_insert_before : public Command {
struct subtitle_insert_before : public validate_nonempty_selection {
CMD_NAME("subtitle/insert/before")
STR_MENU("&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.
struct subtitle_insert_before_videotime : public Command {
struct subtitle_insert_before_videotime : public validate_nonempty_selection_video_loaded {
CMD_NAME("subtitle/insert/before/videotime")
STR_MENU("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) {
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->subsGrid->SelectVisible();
}
bool Validate(agi::Context *c) {
return c->videoController->IsLoaded();
}
};

View File

@ -57,11 +57,38 @@
namespace {
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.
/// @{
/// 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")
STR_MENU("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.
struct time_continuous_start : public Command {
struct time_continuous_start : public validate_adjoinable {
CMD_NAME("time/continuous/start")
STR_MENU("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.
struct time_frame_current : public Command {
struct time_frame_current : public validate_video_loaded {
CMD_NAME("time/frame/current")
STR_MENU("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.
struct time_snap_end_video : public Command {
struct time_snap_end_video : public validate_video_loaded {
CMD_NAME("time/snap/end_video")
STR_MENU("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.
struct time_snap_frame : public Command {
struct time_snap_frame : public validate_video_loaded {
CMD_NAME("time/snap/frame")
STR_MENU("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.
struct time_snap_scene : public Command {
struct time_snap_scene : public validate_video_loaded {
CMD_NAME("time/snap/scene")
STR_MENU("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.
struct time_snap_start_video : public Command {
struct time_snap_start_video : public validate_video_loaded {
CMD_NAME("time/snap/start_video")
STR_MENU("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_HELP("Closes the currently open timecodes file.")
bool Validate(const agi::Context *c) {
return c->videoController->OverTimecodesLoaded();
}
void operator()(agi::Context *c) {
c->videoController->CloseTimecodes();
}
@ -94,6 +98,10 @@ struct timecode_save : public Command {
STR_DISP("Save Timecodes File")
STR_HELP("Saves a VFR timecodes v2 file.")
bool Validate(const agi::Context *c) {
return c->videoController->TimecodesLoaded();
}
void operator()(agi::Context *c) {
wxString path = lagi_wxString(OPT_GET("Path/Last/Timecodes")->GetString());
wxString str = wxString(_("All Supported Types")) + _T("(*.txt)|*.txt|") + _("All Files") + _T(" (*.*)|*.*");

View File

@ -63,24 +63,34 @@ namespace {
/// @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.
struct video_aspect_cinematic : public Command {
struct video_aspect_cinematic : public validator_video_attached {
CMD_NAME("video/aspect/cinematic")
STR_MENU("&Cinematic (2.35)")
STR_DISP("Cinematic (235)")
STR_HELP("Forces video to 2.35 aspect ratio.")
void operator()(agi::Context *c) {
c->videoController->Stop();
c->videoController->SetAspectRatio(3);
wxGetApp().frame->SetDisplayMode(1,-1);
c->videoController->Stop();
c->videoController->SetAspectRatio(3);
wxGetApp().frame->SetDisplayMode(1,-1);
}
};
/// 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")
STR_MENU("Custom..")
STR_DISP("Custom")
@ -134,10 +144,8 @@ struct video_aspect_custom : public Command {
}
};
/// 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")
STR_MENU("&Default")
STR_DISP("Default")
@ -150,10 +158,8 @@ struct video_aspect_default : public Command {
}
};
/// 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")
STR_MENU("&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.
struct video_aspect_wide : public Command {
struct video_aspect_wide : public validator_video_attached {
CMD_NAME("video/aspect/wide")
STR_MENU("&Widescreen (16:9)")
STR_DISP("Widescreen (16:9)")
@ -181,9 +186,8 @@ struct video_aspect_wide : public Command {
}
};
/// Closes the currently open video file.
struct video_close : public Command {
struct video_close : public validator_video_loaded {
CMD_NAME("video/close")
STR_MENU("&Close Video")
STR_DISP("Close Video")
@ -194,10 +198,8 @@ struct video_close : public Command {
}
};
/// Detach video, displaying it in a separate Window.
struct video_detach : public Command {
struct video_detach : public validator_video_loaded {
CMD_NAME("video/detach")
STR_MENU("Detach Video")
STR_DISP("Detach Video")
@ -208,9 +210,8 @@ struct video_detach : public Command {
}
};
/// Shows video details.
struct video_details : public Command {
struct video_details : public validator_video_loaded {
CMD_NAME("video/details")
STR_MENU("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")
STR_MENU("XXX: no idea")
STR_DISP("XXX: no idea")
@ -242,9 +242,8 @@ struct video_focus_seek : public Command {
}
};
/// Seek to the next frame.
struct video_frame_next : public Command {
struct video_frame_next : public validator_video_loaded {
CMD_NAME("video/frame/next")
STR_MENU("Next Frame")
STR_DISP("Next Frame")
@ -256,7 +255,7 @@ struct video_frame_next : public Command {
};
/// 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")
STR_MENU("Next Boundary")
STR_DISP("Next Boundary")
@ -286,7 +285,7 @@ struct video_frame_next_boundary : public Command {
};
/// 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")
STR_MENU("Next Keyframe")
STR_DISP("Next Keyframe")
@ -302,7 +301,7 @@ struct video_frame_next_keyframe : public Command {
};
/// 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")
STR_MENU("Fast jump forward")
STR_DISP("Fast jump forward")
@ -316,7 +315,7 @@ struct video_frame_next_large : public Command {
};
/// Seek to the previous frame.
struct video_frame_prev : public Command {
struct video_frame_prev : public validator_video_loaded {
CMD_NAME("video/frame/prev")
STR_MENU("Previous Frame")
STR_DISP("Previous Frame")
@ -328,7 +327,7 @@ struct video_frame_prev : public Command {
};
/// 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")
STR_MENU("Previous Boundary")
STR_DISP("Previous Boundary")
@ -358,7 +357,7 @@ struct video_frame_prev_boundary : public Command {
};
/// 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")
STR_MENU("Previous Keyframe")
STR_DISP("Previous Keyframe")
@ -377,7 +376,7 @@ struct video_frame_prev_keyframe : public Command {
};
/// 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")
STR_MENU("Fast jump backwards")
STR_DISP("Fast jump backwards")
@ -391,7 +390,7 @@ struct video_frame_prev_large : public Command {
};
/// Jump to frame or time.
struct video_jump : public Command {
struct video_jump : public validator_video_loaded {
CMD_NAME("video/jump")
STR_MENU("&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.
struct video_jump_end : public Command {
struct video_jump_end : public validator_video_loaded {
CMD_NAME("video/jump/end")
STR_MENU("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.
struct video_jump_start : public Command {
struct video_jump_start : public validator_video_loaded {
CMD_NAME("video/jump/start")
STR_MENU("Jump Video to Start")
STR_DISP("Jump Video to Start")
@ -432,7 +429,6 @@ struct video_jump_start : public Command {
}
};
/// Opens a video file.
struct video_open : public Command {
CMD_NAME("video/open")
@ -452,7 +448,6 @@ struct video_open : public Command {
}
};
/// Opens a video clip with solid colour.
struct video_open_dummy : public Command {
CMD_NAME("video/open/dummy")
@ -481,7 +476,7 @@ struct video_opt_autoscroll : public Command {
};
/// Play video.
struct video_play : public Command {
struct video_play : public validator_video_loaded {
CMD_NAME("video/play")
STR_MENU("Play")
STR_DISP("Play")
@ -493,7 +488,7 @@ struct video_play : public Command {
};
/// 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")
STR_MENU("Play line")
STR_DISP("Play line")
@ -505,7 +500,7 @@ struct video_play_line : public Command {
};
/// 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")
STR_MENU("Show Overscan Mask")
STR_DISP("Show Overscan Mask")
@ -517,9 +512,8 @@ struct video_show_overscan : public Command {
}
};
/// Set zoom to 100%.
class video_zoom_100: public Command {
class video_zoom_100: public validator_video_attached {
public:
CMD_NAME("video/zoom/100")
STR_MENU("&100%")
@ -533,7 +527,7 @@ public:
};
/// Stop video playback
class video_stop: public Command {
class video_stop: public validator_video_loaded {
public:
CMD_NAME("video/stop")
STR_MENU("Stop video")
@ -546,7 +540,7 @@ public:
};
/// Set zoom to 200%.
class video_zoom_200: public Command {
class video_zoom_200: public validator_video_attached {
public:
CMD_NAME("video/zoom/200")
STR_MENU("&200%")
@ -559,9 +553,8 @@ public:
}
};
/// Set zoom to 50%.
class video_zoom_50: public Command {
class video_zoom_50: public validator_video_attached {
public:
CMD_NAME("video/zoom/50")
STR_MENU("&50%")
@ -574,9 +567,8 @@ public:
}
};
/// Zoom video in.
struct video_zoom_in : public Command {
struct video_zoom_in : public validator_video_attached {
CMD_NAME("video/zoom/in")
STR_MENU("Zoom In")
STR_DISP("Zoom In")
@ -587,9 +579,8 @@ struct video_zoom_in : public Command {
}
};
/// Zoom video out.
struct video_zoom_out : public Command {
struct video_zoom_out : public validator_video_attached {
CMD_NAME("video/zoom/out")
STR_MENU("Zoom Out")
STR_DISP("Zoom Out")

View File

@ -764,15 +764,6 @@ void FrameMain::OnMenuOpen (wxMenuEvent &event) {
// View menu
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
if (!showVideo && !showAudio) MenuBar->Check(cmd::id("app/display/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 == 2) MenuBar->Check(cmd::id("grid/tags/simplify"), true);
if (sub_grid == 3) MenuBar->Check(cmd::id("grid/tags/hide"), true);
}
// Video menu
else if (curMenu == menu::menu->GetMenu("main/video")) {
bool state = context->videoController->IsLoaded();
bool attached = state && !context->detachedVideo;
// 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/close"),context->videoController->OverTimecodesLoaded());
MenuBar->Enable(cmd::id("keyframe/close"),context->videoController->OverKeyFramesLoaded());
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
int arType = context->videoController->GetAspectRatioType();
@ -861,13 +829,7 @@ void FrameMain::OnMenuOpen (wxMenuEvent &event) {
// Entries
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();
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);
state = count > 0 && continuous;
MenuBar->Enable(cmd::id("edit/line/duplicate"),state);

View File

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