Make the audio timing controller commit changes made

Originally committed to SVN as r4914.
This commit is contained in:
Thomas Goyne 2010-12-08 08:10:00 +00:00
parent e1e98d0ddd
commit a6a4132ab5
6 changed files with 95 additions and 63 deletions

View file

@ -62,11 +62,6 @@
#include "toggle_bitmap.h" #include "toggle_bitmap.h"
#include "tooltip_manager.h" #include "tooltip_manager.h"
// Stuff defines "min" and "max" as macros and breaks std::min and std::max in the process
#undef min
#undef max
enum AudioBoxControlIDs { enum AudioBoxControlIDs {
Audio_Scrollbar = 1600, Audio_Scrollbar = 1600,
Audio_Horizontal_Zoom, Audio_Horizontal_Zoom,
@ -108,7 +103,7 @@ enum AudioBoxControlIDs {
/// @brief Constructor /// @brief Constructor
/// @param parent /// @param parent
/// ///
AudioBox::AudioBox(wxWindow *parent, AudioController *_controller, SelectionController<AssDialogue> *selection_controller) AudioBox::AudioBox(wxWindow *parent, AudioController *_controller, SelectionController<AssDialogue> *selection_controller, AssFile *ass)
: wxPanel(parent,-1,wxDefaultPosition,wxDefaultSize,wxTAB_TRAVERSAL|wxBORDER_RAISED) : wxPanel(parent,-1,wxDefaultPosition,wxDefaultSize,wxTAB_TRAVERSAL|wxBORDER_RAISED)
, selection_controller(selection_controller) , selection_controller(selection_controller)
, controller(_controller) , controller(_controller)
@ -256,7 +251,7 @@ AudioBox::AudioBox(wxWindow *parent, AudioController *_controller, SelectionCont
SetKaraokeButtons(); // Decide which one to show or hide. SetKaraokeButtons(); // Decide which one to show or hide.
timing_controller_dialogue = CreateDialogueTimingController(controller, selection_controller); timing_controller_dialogue = CreateDialogueTimingController(controller, selection_controller, ass);
controller->SetTimingController(timing_controller_dialogue); controller->SetTimingController(timing_controller_dialogue);
} }
@ -490,8 +485,7 @@ void AudioBox::OnCommit(wxCommandEvent &event) {
LOG_D("audio/box") << "OnCommit"; LOG_D("audio/box") << "OnCommit";
audioDisplay->SetFocus(); audioDisplay->SetFocus();
LOG_D("audio/box") << "has set focus, now committing changes"; LOG_D("audio/box") << "has set focus, now committing changes";
/// @todo Commit changes and go to next line if appropriate controller->GetTimingController()->Commit();
//audioDisplay->CommitChanges(true);
LOG_D("audio/box") << "returning"; LOG_D("audio/box") << "returning";
} }

View file

@ -58,6 +58,7 @@
// Prototypes // Prototypes
class AudioController; class AudioController;
class AssDialogue; class AssDialogue;
class AssFile;
class AudioTimingController; class AudioTimingController;
class AudioDisplay; class AudioDisplay;
class AudioKaraoke; class AudioKaraoke;
@ -107,7 +108,7 @@ class AudioBox : public wxPanel {
/// Karaoke box sizer /// Karaoke box sizer
wxSizer *karaokeSizer; wxSizer *karaokeSizer;
/// Karaoke mode join syllabel button. /// Karaoke mode join syllable button.
wxButton *JoinButton; wxButton *JoinButton;
/// Karaoke mode split word button. /// Karaoke mode split word button.
@ -181,7 +182,7 @@ public:
/// DOCME /// DOCME
bool karaokeMode; bool karaokeMode;
AudioBox(wxWindow *parent, AudioController *controller, SelectionController<AssDialogue> *selection_controller); AudioBox(wxWindow *parent, AudioController *controller, SelectionController<AssDialogue> *selection_controller, AssFile *ass);
~AudioBox(); ~AudioBox();
void SetKaraokeButtons(); void SetKaraokeButtons();

View file

@ -457,7 +457,7 @@ public:
class AudioMarkerInteractionObject : public AudioDisplayInteractionObject { class AudioMarkerInteractionObject : public AudioDisplayInteractionObject {
// Object-pair being intracted with // Object-pair being interacted with
AudioMarker *marker; AudioMarker *marker;
AudioTimingController *timing_controller; AudioTimingController *timing_controller;
// Audio display drag is happening on // Audio display drag is happening on

View file

@ -36,6 +36,7 @@
class AssDialogue; class AssDialogue;
class AssFile;
class AudioController; class AudioController;
#include <libaegisub/signals.h> #include <libaegisub/signals.h>
@ -144,5 +145,6 @@ public:
/// @brief Create a standard dialogue audio timing controller /// @brief Create a standard dialogue audio timing controller
/// @param audio_controller The audio controller to own the timing controller /// @param audio_controller The audio controller to own the timing controller
/// @param selection_controller The selection controller to manage the set of lines being timed /// @param selection_controller The selection controller to manage the set of lines being timed
AudioTimingController *CreateDialogueTimingController(AudioController *audio_controller, SelectionController<AssDialogue> *selection_controller); /// @param ass The file being timed
AudioTimingController *CreateDialogueTimingController(AudioController *audio_controller, SelectionController<AssDialogue> *selection_controller, AssFile *ass);

View file

@ -39,8 +39,10 @@
#include <wx/pen.h> #include <wx/pen.h>
#endif #endif
#include "ass_time.h"
#include "ass_dialogue.h" #include "ass_dialogue.h"
#include "ass_file.h"
#include "ass_time.h"
#include "main.h"
#include "selection_controller.h" #include "selection_controller.h"
#include "audio_controller.h" #include "audio_controller.h"
#include "audio_timing.h" #include "audio_timing.h"
@ -78,7 +80,7 @@ public:
/// @brief Move the marker to a new position /// @brief Move the marker to a new position
/// @param new_position The position to move the marker to, in audio samples /// @param new_position The position to move the marker to, in audio samples
/// ///
/// If the marker moves to the opposite side of the ohter marker in the pair, /// If the marker moves to the opposite side of the other marker in the pair,
/// the styles of the two markers will be changed to match the new start/end /// the styles of the two markers will be changed to match the new start/end
/// relationship of them. /// relationship of them.
void SetPosition(int64_t new_position); void SetPosition(int64_t new_position);
@ -94,8 +96,8 @@ public:
/// @param marker1 The first marker in the pair to make /// @param marker1 The first marker in the pair to make
/// @param marker2 The second marker in the pair to make /// @param marker2 The second marker in the pair to make
/// ///
/// This checks that the markers aren't already part of a pair, and then sets their /// This checks that the markers aren't already part of a pair, and then
/// "other" field. Positions and styles aren't affected. /// sets their "other" field. Positions and styles aren't affected.
static void InitPair(AudioMarkerDialogueTiming *marker1, AudioMarkerDialogueTiming *marker2); static void InitPair(AudioMarkerDialogueTiming *marker1, AudioMarkerDialogueTiming *marker2);
}; };
@ -118,8 +120,13 @@ class AudioTimingControllerDialogue : public AudioTimingController, private Sele
AudioMarkerDialogueTiming markers[2]; AudioMarkerDialogueTiming markers[2];
/// Has the timing been modified by the user? /// Has the timing been modified by the user?
/// If auto commit is enabled this will only be true very briefly following
/// changes
bool timing_modified; bool timing_modified;
/// Commit id for coalescing purposes when in auto commit mode
int commit_id;
/// Get the leftmost of the markers /// Get the leftmost of the markers
AudioMarkerDialogueTiming *GetLeftMarker(); AudioMarkerDialogueTiming *GetLeftMarker();
const AudioMarkerDialogueTiming *GetLeftMarker() const; const AudioMarkerDialogueTiming *GetLeftMarker() const;
@ -133,14 +140,31 @@ class AudioTimingControllerDialogue : public AudioTimingController, private Sele
/// Update the audio controller's selection /// Update the audio controller's selection
void UpdateSelection(); void UpdateSelection();
/// @brief Set the position of a marker and announce the change to the world
/// @param marker Marker to move
/// @param sample New position of the marker
void SetMarker(AudioMarkerDialogueTiming *marker, int64_t sample);
/// Autocommit option
const agi::OptionValue *auto_commit;
/// Selection controller managing the set of lines currently being timed /// Selection controller managing the set of lines currently being timed
SelectionController<AssDialogue> *selection_controller; SelectionController<AssDialogue> *selection_controller;
private: agi::signal::Connection commit_slot;
/// @todo Dealing with the AssFile directly is probably not the best way to
/// handle committing, but anything better probably needs to wait for
/// the subtitle container work
AssFile *ass;
// SubtitleSelectionListener interface // SubtitleSelectionListener interface
virtual void OnActiveLineChanged(AssDialogue *new_line); virtual void OnActiveLineChanged(AssDialogue *new_line);
virtual void OnSelectedSetChanged(const Selection &lines_added, const Selection &lines_removed); virtual void OnSelectedSetChanged(const Selection &lines_added, const Selection &lines_removed);
// AssFile events
void OnFileChanged(int type);
public: public:
// AudioMarkerProvider interface // AudioMarkerProvider interface
virtual void GetMarkers(const SampleRange &range, AudioMarkerVector &out_markers) const; virtual void GetMarkers(const SampleRange &range, AudioMarkerVector &out_markers) const;
@ -163,21 +187,18 @@ public:
// Specific interface // Specific interface
/// @brief Constructor /// @brief Constructor
AudioTimingControllerDialogue(AudioController *audio_controller, SelectionController<AssDialogue> *selection_controller); AudioTimingControllerDialogue(AudioController *audio_controller, SelectionController<AssDialogue> *selection_controller, AssFile *ass);
virtual ~AudioTimingControllerDialogue(); virtual ~AudioTimingControllerDialogue();
}; };
AudioTimingController *CreateDialogueTimingController(AudioController *audio_controller, SelectionController<AssDialogue> *selection_controller) AudioTimingController *CreateDialogueTimingController(AudioController *audio_controller, SelectionController<AssDialogue> *selection_controller, AssFile *ass)
{ {
return new AudioTimingControllerDialogue(audio_controller, selection_controller); return new AudioTimingControllerDialogue(audio_controller, selection_controller, ass);
} }
// AudioMarkerDialogueTiming // AudioMarkerDialogueTiming
void AudioMarkerDialogueTiming::SetPosition(int64_t new_position) void AudioMarkerDialogueTiming::SetPosition(int64_t new_position)
{ {
position = new_position; position = new_position;
@ -228,8 +249,11 @@ void AudioMarkerDialogueTiming::InitPair(AudioMarkerDialogueTiming *marker1, Aud
// AudioTimingControllerDialogue // AudioTimingControllerDialogue
AudioTimingControllerDialogue::AudioTimingControllerDialogue(AudioController *audio_controller, SelectionController<AssDialogue> *selection_controller) AudioTimingControllerDialogue::AudioTimingControllerDialogue(AudioController *audio_controller, SelectionController<AssDialogue> *selection_controller, AssFile *ass)
: timing_modified(false) : timing_modified(false)
, commit_id(-1)
, ass(ass)
, auto_commit(OPT_GET("Audio/Auto/Commit"))
, audio_controller(audio_controller) , audio_controller(audio_controller)
, selection_controller(selection_controller) , selection_controller(selection_controller)
{ {
@ -238,6 +262,7 @@ AudioTimingControllerDialogue::AudioTimingControllerDialogue(AudioController *au
AudioMarkerDialogueTiming::InitPair(&markers[0], &markers[1]); AudioMarkerDialogueTiming::InitPair(&markers[0], &markers[1]);
selection_controller->AddSelectionListener(this); selection_controller->AddSelectionListener(this);
commit_slot = ass->AddCommitListener(&AudioTimingControllerDialogue::OnFileChanged, this);
} }
@ -278,21 +303,21 @@ void AudioTimingControllerDialogue::GetMarkers(const SampleRange &range, AudioMa
out_markers.push_back(&markers[1]); out_markers.push_back(&markers[1]);
} }
void AudioTimingControllerDialogue::OnActiveLineChanged(AssDialogue *new_line) void AudioTimingControllerDialogue::OnActiveLineChanged(AssDialogue *new_line)
{ {
/// @todo Need to change policy to default commit at some point Revert();
Revert(); // revert will read and reset the selection/markers
} }
void AudioTimingControllerDialogue::OnSelectedSetChanged(const Selection &lines_added, const Selection &lines_removed) void AudioTimingControllerDialogue::OnSelectedSetChanged(const Selection &lines_added, const Selection &lines_removed)
{ {
/// @todo Create new passive markers, perhaps /// @todo Create new passive markers, perhaps
} }
void AudioTimingControllerDialogue::OnFileChanged(int type) {
if (type == AssFile::COMMIT_UNDO || type == AssFile::COMMIT_FULL) return;
Revert();
}
wxString AudioTimingControllerDialogue::GetWarningMessage() const wxString AudioTimingControllerDialogue::GetWarningMessage() const
@ -342,13 +367,14 @@ void AudioTimingControllerDialogue::Prev()
void AudioTimingControllerDialogue::Commit() void AudioTimingControllerDialogue::Commit()
{ {
/// @todo Make these depend on actual configuration
const bool next_line_on_commit = true;
const int default_duration = 5000; // milliseconds
int new_start_ms = audio_controller->MillisecondsFromSamples(GetLeftMarker()->GetPosition()); int new_start_ms = audio_controller->MillisecondsFromSamples(GetLeftMarker()->GetPosition());
int new_end_ms = audio_controller->MillisecondsFromSamples(GetRightMarker()->GetPosition()); int new_end_ms = audio_controller->MillisecondsFromSamples(GetRightMarker()->GetPosition());
// If auto committing is enabled, timing_modified will be true iif it is an
// auto commit, as there is never pending changes to commit when the button
// is clicked
bool user_triggered = !(timing_modified && auto_commit->GetBool());
// Store back new times // Store back new times
if (timing_modified) if (timing_modified)
{ {
@ -359,16 +385,33 @@ void AudioTimingControllerDialogue::Commit()
(*sub)->Start.SetMS(new_start_ms); (*sub)->Start.SetMS(new_start_ms);
(*sub)->End.SetMS(new_end_ms); (*sub)->End.SetMS(new_end_ms);
} }
/// @todo Set an undo point
commit_slot.Block();
if (user_triggered)
{
ass->Commit(_("timing"), AssFile::COMMIT_TIMES);
commit_id = -1; // never coalesce with a manually triggered commit
}
else
commit_id = ass->Commit(_("timing"), AssFile::COMMIT_TIMES, commit_id);
commit_slot.Unblock();
timing_modified = false; timing_modified = false;
} }
// Assume that the next line might be zero-timed and should thus get a default timing if (user_triggered && OPT_GET("Audio/Next Line on Commit")->GetBool())
if (next_line_on_commit)
{ {
markers[0].SetPosition(audio_controller->SamplesFromMilliseconds(new_end_ms)); /// @todo Old audio display created a new line if there was no next,
markers[1].SetPosition(audio_controller->SamplesFromMilliseconds(new_end_ms + default_duration)); /// like the edit box, so maybe add a way to do that which both
UpdateSelection(); /// this and the edit box can use
Next();
if (selection_controller->GetActiveLine()->End.GetMS() == 0) {
const int default_duration = OPT_GET("Timing/Default Duration")->GetInt();
markers[0].SetPosition(audio_controller->SamplesFromMilliseconds(new_end_ms));
markers[1].SetPosition(audio_controller->SamplesFromMilliseconds(new_end_ms + default_duration));
timing_modified = true;
UpdateSelection();
}
} }
} }
@ -376,8 +419,7 @@ void AudioTimingControllerDialogue::Commit()
void AudioTimingControllerDialogue::Revert() void AudioTimingControllerDialogue::Revert()
{ {
AssDialogue *line = selection_controller->GetActiveLine(); if (AssDialogue *line = selection_controller->GetActiveLine())
if (line)
{ {
AssTime new_start = line->Start; AssTime new_start = line->Start;
AssTime new_end = line->End; AssTime new_end = line->End;
@ -418,10 +460,7 @@ AudioMarker * AudioTimingControllerDialogue::OnLeftClick(int64_t sample, int sen
{ {
// Clicked near the left marker: // Clicked near the left marker:
// Insta-move it and start dragging it // Insta-move it and start dragging it
left->SetPosition(sample); SetMarker(left, sample);
AnnounceMarkerMoved(left);
timing_modified = true;
UpdateSelection();
return left; return left;
} }
@ -435,10 +474,7 @@ AudioMarker * AudioTimingControllerDialogue::OnLeftClick(int64_t sample, int sen
// Clicked far from either marker: // Clicked far from either marker:
// Insta-set the left marker to the clicked position and return the right as the dragged one, // Insta-set the left marker to the clicked position and return the right as the dragged one,
// such that if the user does start dragging, he will create a new selection from scratch // such that if the user does start dragging, he will create a new selection from scratch
left->SetPosition(sample); SetMarker(left, sample);
AnnounceMarkerMoved(left);
timing_modified = true;
UpdateSelection();
return right; return right;
} }
@ -447,11 +483,7 @@ AudioMarker * AudioTimingControllerDialogue::OnLeftClick(int64_t sample, int sen
AudioMarker * AudioTimingControllerDialogue::OnRightClick(int64_t sample, int sensitivity) AudioMarker * AudioTimingControllerDialogue::OnRightClick(int64_t sample, int sensitivity)
{ {
AudioMarkerDialogueTiming *right = GetRightMarker(); AudioMarkerDialogueTiming *right = GetRightMarker();
SetMarker(right, sample);
right->SetPosition(sample);
AnnounceMarkerMoved(right);
timing_modified = true;
UpdateSelection();
return right; return right;
} }
@ -461,11 +493,7 @@ void AudioTimingControllerDialogue::OnMarkerDrag(AudioMarker *marker, int64_t ne
{ {
assert(marker == &markers[0] || marker == &markers[1]); assert(marker == &markers[0] || marker == &markers[1]);
static_cast<AudioMarkerDialogueTiming*>(marker)->SetPosition(new_position); SetMarker(static_cast<AudioMarkerDialogueTiming*>(marker), new_position);
AnnounceMarkerMoved(marker);
timing_modified = true;
UpdateSelection();
} }
@ -475,4 +503,11 @@ void AudioTimingControllerDialogue::UpdateSelection()
AnnounceUpdatedPrimaryRange(); AnnounceUpdatedPrimaryRange();
} }
void AudioTimingControllerDialogue::SetMarker(AudioMarkerDialogueTiming *marker, int64_t sample)
{
marker->SetPosition(sample);
AnnounceMarkerMoved(marker);
timing_modified = true;
if (auto_commit->GetBool()) Commit();
UpdateSelection();
}

View file

@ -591,7 +591,7 @@ void FrameMain::InitContents() {
// Audio area // Audio area
StartupLog(_T("Create audio box")); StartupLog(_T("Create audio box"));
audioBox = new AudioBox(audioSash, audioController, SubsGrid); audioBox = new AudioBox(audioSash, audioController, SubsGrid, ass);
audioBox->frameMain = this; audioBox->frameMain = this;
audioSashSizer->Add(audioBox, 1, wxEXPAND); audioSashSizer->Add(audioBox, 1, wxEXPAND);
audioSash->SetSizer(audioSashSizer); audioSash->SetSizer(audioSashSizer);