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 "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 {
Audio_Scrollbar = 1600,
Audio_Horizontal_Zoom,
@ -108,7 +103,7 @@ enum AudioBoxControlIDs {
/// @brief Constructor
/// @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)
, selection_controller(selection_controller)
, controller(_controller)
@ -256,7 +251,7 @@ AudioBox::AudioBox(wxWindow *parent, AudioController *_controller, SelectionCont
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);
}
@ -490,8 +485,7 @@ void AudioBox::OnCommit(wxCommandEvent &event) {
LOG_D("audio/box") << "OnCommit";
audioDisplay->SetFocus();
LOG_D("audio/box") << "has set focus, now committing changes";
/// @todo Commit changes and go to next line if appropriate
//audioDisplay->CommitChanges(true);
controller->GetTimingController()->Commit();
LOG_D("audio/box") << "returning";
}

View File

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

View File

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

View File

@ -36,6 +36,7 @@
class AssDialogue;
class AssFile;
class AudioController;
#include <libaegisub/signals.h>
@ -144,5 +145,6 @@ public:
/// @brief Create a standard dialogue audio 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
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>
#endif
#include "ass_time.h"
#include "ass_dialogue.h"
#include "ass_file.h"
#include "ass_time.h"
#include "main.h"
#include "selection_controller.h"
#include "audio_controller.h"
#include "audio_timing.h"
@ -78,7 +80,7 @@ public:
/// @brief Move the marker to a new position
/// @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
/// relationship of them.
void SetPosition(int64_t new_position);
@ -94,8 +96,8 @@ public:
/// @param marker1 The first 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
/// "other" field. Positions and styles aren't affected.
/// This checks that the markers aren't already part of a pair, and then
/// sets their "other" field. Positions and styles aren't affected.
static void InitPair(AudioMarkerDialogueTiming *marker1, AudioMarkerDialogueTiming *marker2);
};
@ -118,8 +120,13 @@ class AudioTimingControllerDialogue : public AudioTimingController, private Sele
AudioMarkerDialogueTiming markers[2];
/// 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;
/// Commit id for coalescing purposes when in auto commit mode
int commit_id;
/// Get the leftmost of the markers
AudioMarkerDialogueTiming *GetLeftMarker();
const AudioMarkerDialogueTiming *GetLeftMarker() const;
@ -133,14 +140,31 @@ class AudioTimingControllerDialogue : public AudioTimingController, private Sele
/// Update the audio controller's selection
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
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
virtual void OnActiveLineChanged(AssDialogue *new_line);
virtual void OnSelectedSetChanged(const Selection &lines_added, const Selection &lines_removed);
// AssFile events
void OnFileChanged(int type);
public:
// AudioMarkerProvider interface
virtual void GetMarkers(const SampleRange &range, AudioMarkerVector &out_markers) const;
@ -163,21 +187,18 @@ public:
// Specific interface
/// @brief Constructor
AudioTimingControllerDialogue(AudioController *audio_controller, SelectionController<AssDialogue> *selection_controller);
AudioTimingControllerDialogue(AudioController *audio_controller, SelectionController<AssDialogue> *selection_controller, AssFile *ass);
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
void AudioMarkerDialogueTiming::SetPosition(int64_t new_position)
{
position = new_position;
@ -228,8 +249,11 @@ void AudioMarkerDialogueTiming::InitPair(AudioMarkerDialogueTiming *marker1, Aud
// AudioTimingControllerDialogue
AudioTimingControllerDialogue::AudioTimingControllerDialogue(AudioController *audio_controller, SelectionController<AssDialogue> *selection_controller)
AudioTimingControllerDialogue::AudioTimingControllerDialogue(AudioController *audio_controller, SelectionController<AssDialogue> *selection_controller, AssFile *ass)
: timing_modified(false)
, commit_id(-1)
, ass(ass)
, auto_commit(OPT_GET("Audio/Auto/Commit"))
, audio_controller(audio_controller)
, selection_controller(selection_controller)
{
@ -238,6 +262,7 @@ AudioTimingControllerDialogue::AudioTimingControllerDialogue(AudioController *au
AudioMarkerDialogueTiming::InitPair(&markers[0], &markers[1]);
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]);
}
void AudioTimingControllerDialogue::OnActiveLineChanged(AssDialogue *new_line)
{
/// @todo Need to change policy to default commit at some point
Revert(); // revert will read and reset the selection/markers
Revert();
}
void AudioTimingControllerDialogue::OnSelectedSetChanged(const Selection &lines_added, const Selection &lines_removed)
{
/// @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
@ -342,13 +367,14 @@ void AudioTimingControllerDialogue::Prev()
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_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
if (timing_modified)
{
@ -359,16 +385,33 @@ void AudioTimingControllerDialogue::Commit()
(*sub)->Start.SetMS(new_start_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;
}
// Assume that the next line might be zero-timed and should thus get a default timing
if (next_line_on_commit)
if (user_triggered && OPT_GET("Audio/Next Line on Commit")->GetBool())
{
markers[0].SetPosition(audio_controller->SamplesFromMilliseconds(new_end_ms));
markers[1].SetPosition(audio_controller->SamplesFromMilliseconds(new_end_ms + default_duration));
UpdateSelection();
/// @todo Old audio display created a new line if there was no next,
/// like the edit box, so maybe add a way to do that which both
/// 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()
{
AssDialogue *line = selection_controller->GetActiveLine();
if (line)
if (AssDialogue *line = selection_controller->GetActiveLine())
{
AssTime new_start = line->Start;
AssTime new_end = line->End;
@ -418,10 +460,7 @@ AudioMarker * AudioTimingControllerDialogue::OnLeftClick(int64_t sample, int sen
{
// Clicked near the left marker:
// Insta-move it and start dragging it
left->SetPosition(sample);
AnnounceMarkerMoved(left);
timing_modified = true;
UpdateSelection();
SetMarker(left, sample);
return left;
}
@ -435,10 +474,7 @@ AudioMarker * AudioTimingControllerDialogue::OnLeftClick(int64_t sample, int sen
// Clicked far from either marker:
// 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
left->SetPosition(sample);
AnnounceMarkerMoved(left);
timing_modified = true;
UpdateSelection();
SetMarker(left, sample);
return right;
}
@ -447,11 +483,7 @@ AudioMarker * AudioTimingControllerDialogue::OnLeftClick(int64_t sample, int sen
AudioMarker * AudioTimingControllerDialogue::OnRightClick(int64_t sample, int sensitivity)
{
AudioMarkerDialogueTiming *right = GetRightMarker();
right->SetPosition(sample);
AnnounceMarkerMoved(right);
timing_modified = true;
UpdateSelection();
SetMarker(right, sample);
return right;
}
@ -461,11 +493,7 @@ void AudioTimingControllerDialogue::OnMarkerDrag(AudioMarker *marker, int64_t ne
{
assert(marker == &markers[0] || marker == &markers[1]);
static_cast<AudioMarkerDialogueTiming*>(marker)->SetPosition(new_position);
AnnounceMarkerMoved(marker);
timing_modified = true;
UpdateSelection();
SetMarker(static_cast<AudioMarkerDialogueTiming*>(marker), new_position);
}
@ -475,4 +503,11 @@ void AudioTimingControllerDialogue::UpdateSelection()
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
StartupLog(_T("Create audio box"));
audioBox = new AudioBox(audioSash, audioController, SubsGrid);
audioBox = new AudioBox(audioSash, audioController, SubsGrid, ass);
audioBox->frameMain = this;
audioSashSizer->Add(audioBox, 1, wxEXPAND);
audioSash->SetSizer(audioSashSizer);