Initial implementation of the split editbox

This commit is contained in:
Thomas Goyne 2012-10-11 16:46:53 -07:00
parent 8162ebea24
commit 0e7df15170
10 changed files with 187 additions and 7 deletions

View File

@ -187,6 +187,7 @@
<ClInclude Include="$(SrcDir)include\aegisub\subtitles_provider.h" />
<ClInclude Include="$(SrcDir)include\aegisub\toolbar.h" />
<ClInclude Include="$(SrcDir)include\aegisub\video_provider.h" />
<ClInclude Include="$(SrcDir)initial_line_state.h" />
<ClInclude Include="$(SrcDir)kana_table.h" />
<ClInclude Include="$(SrcDir)main.h" />
<ClInclude Include="$(SrcDir)mkv_wrap.h" />
@ -450,6 +451,7 @@
<ClCompile Include="$(SrcDir)command\keyframe.cpp" />
<ClCompile Include="$(SrcDir)dialog_autosave.cpp" />
<ClCompile Include="$(SrcDir)search_replace_engine.cpp" />
<ClCompile Include="$(SrcDir)initial_line_state.cpp" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="$(SrcDir)res.rc" />

View File

@ -678,18 +678,18 @@
<ClInclude Include="$(SrcDir)dialog_autosave.h">
<Filter>Features\Autosave</Filter>
</ClInclude>
<ClInclude Include="$(SrcDir)include\aegisub\hotkey.h" />
<ClInclude Include="$(SrcDir)ass_info.h">
<Filter>ASS</Filter>
</ClInclude>
<ClInclude Include="$(SrcDir)include\aegisub\hotkey.h" />
<ClInclude Include="$(SrcDir)options.h">
<Filter>Preferences</Filter>
</ClInclude>
<ClInclude Include="$(SrcDir)include\aegisub\hotkey.h" />
<ClInclude Include="$(SrcDir)search_replace_engine.h">
<Filter>Features\Search-replace</Filter>
</ClInclude>
<ClInclude Include="$(SrcDir)initial_line_state.h">
<Filter>Utilities</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="$(SrcDir)ass_dialogue.cpp">
@ -1238,6 +1238,9 @@
<ClCompile Include="$(SrcDir)search_replace_engine.cpp">
<Filter>Features\Search-replace</Filter>
</ClCompile>
<ClCompile Include="$(SrcDir)initial_line_state.cpp">
<Filter>Utilities</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="$(SrcDir)res.rc">

View File

@ -204,6 +204,7 @@ SRC += \
help_button.cpp \
hotkey.cpp \
hotkey_data_view_model.cpp \
initial_line_state.cpp \
kana_table.cpp \
main.cpp \
menu.cpp \

View File

@ -53,6 +53,7 @@
#include "../dialog_paste_over.h"
#include "../dialog_search_replace.h"
#include "../include/aegisub/context.h"
#include "../initial_line_state.h"
#include "../options.h"
#include "../search_replace_engine.h"
#include "../subs_edit_ctrl.h"
@ -918,6 +919,48 @@ struct edit_undo : public Command {
}
};
struct edit_revert : public Command {
CMD_NAME("edit/revert")
STR_DISP("Revert")
STR_MENU("Revert")
STR_HELP("Revert the active line to its initial state")
void operator()(agi::Context *c) {
AssDialogue *line = c->selectionController->GetActiveLine();
line->Text = c->initialLineState->GetInitialText();
c->ass->Commit(_("revert line"), AssFile::COMMIT_DIAG_TEXT, -1, line);
}
};
struct edit_clear : public Command {
CMD_NAME("edit/clear")
STR_DISP("Clear")
STR_MENU("Clear")
STR_HELP("Clear the current line's text")
void operator()(agi::Context *c) {
AssDialogue *line = c->selectionController->GetActiveLine();
line->Text = "";
c->ass->Commit(_("clear line"), AssFile::COMMIT_DIAG_TEXT, -1, line);
}
};
struct edit_insert_original : public Command {
CMD_NAME("edit/insert_original")
STR_DISP("Insert Original")
STR_MENU("Insert Original")
STR_HELP("Insert the original line text at the cursor")
void operator()(agi::Context *c) {
AssDialogue *line = c->selectionController->GetActiveLine();
int sel_start = c->textSelectionController->GetSelectionStart();
int sel_end = c->textSelectionController->GetSelectionEnd();
line->Text = line->Text.Left(sel_start) + c->initialLineState->GetInitialText() + line->Text.Mid(sel_end);
c->ass->Commit(_("insert original"), AssFile::COMMIT_DIAG_TEXT, -1, line);
}
};
}
/// @}
@ -949,5 +992,8 @@ namespace cmd {
reg(new edit_style_strikeout);
reg(new edit_redo);
reg(new edit_undo);
reg(new edit_revert);
reg(new edit_insert_original);
reg(new edit_clear);
}
}

View File

@ -61,6 +61,7 @@
#include "dialog_manager.h"
#include "dialog_version_check.h"
#include "help_button.h"
#include "initial_line_state.h"
#include "libresrc/libresrc.h"
#include "main.h"
#include "options.h"
@ -377,6 +378,7 @@ void FrameMain::InitContents() {
context->subsGrid = SubsGrid = new SubtitlesGrid(Panel, context.get());
context->selectionController = context->subsGrid;
context->search = new SearchReplaceEngine(context.get());
context->initialLineState = new InitialLineState(context.get());
StartupLog("Create video box");
videoBox = new VideoBox(Panel, false, context.get());

View File

@ -5,6 +5,7 @@ class AssDialogue;
class AudioKaraoke;
class DialogManager;
class SearchReplaceEngine;
class InitialLineState;
template<class T> class SelectionController;
class SubsTextEditCtrl;
class SubtitlesGrid;
@ -20,6 +21,7 @@ struct Context {
// Models
AssFile *ass;
Automation4::ScriptManager *local_scripts;
InitialLineState *initialLineState;
// Controllers
AudioController *audioController;

View File

@ -0,0 +1,36 @@
// Copyright (c) 2012, Thomas Goyne <plorkyeran@aegisub.org>
//
// Permission to use, copy, modify, and distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "config.h"
#include "initial_line_state.h"
#include "ass_dialogue.h"
#include "include/aegisub/context.h"
#include "selection_controller.h"
InitialLineState::InitialLineState(agi::Context *c)
: active_line_connection(c->selectionController->AddActiveLineListener(&InitialLineState::OnActiveLineChanged, this))
{
OnActiveLineChanged(c->selectionController->GetActiveLine());
}
void InitialLineState::OnActiveLineChanged(AssDialogue *new_line) {
if (new_line)
initial_text = new_line->Text;
else
initial_text.clear();
InitialStateChanged(initial_text);
}

View File

@ -0,0 +1,36 @@
// Copyright (c) 2012, Thomas Goyne <plorkyeran@aegisub.org>
//
// Permission to use, copy, modify, and distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#ifndef AGI_PRE
#include <wx/string.h>
#endif
#include <libaegisub/signal.h>
namespace agi { struct Context; }
class AssDialogue;
class InitialLineState {
agi::signal::Connection active_line_connection;
wxString initial_text;
agi::signal::Signal<wxString const&> InitialStateChanged;
void OnActiveLineChanged(AssDialogue *new_line);
public:
InitialLineState(agi::Context *c);
wxString GetInitialText() const { return initial_text; }
DEFINE_SIGNAL_ADDERS(InitialStateChanged, AddChangeListener);
};

View File

@ -55,6 +55,7 @@
#include "compat.h"
#include "include/aegisub/context.h"
#include "include/aegisub/hotkey.h"
#include "initial_line_state.h"
#include "libresrc/libresrc.h"
#include "options.h"
#include "placeholder_ctrl.h"
@ -166,17 +167,33 @@ SubsEditBox::SubsEditBox(wxWindow *parent, agi::Context *context)
by_frame = MakeRadio(_("F&rame"), false, _("Time by frame number"));
by_frame->Enable(false);
// Text editor
edit_ctrl = new SubsTextEditCtrl(this, wxSize(300,50), wxBORDER_SUNKEN, c);
edit_ctrl->Bind(wxEVT_CHAR_HOOK, &SubsEditBox::OnKeyDown, this);
Bind(wxEVT_CHAR_HOOK, &SubsEditBox::OnKeyDown, this);
split_box = new wxCheckBox(this,-1,_("Split"));
split_box->Bind(wxEVT_COMMAND_CHECKBOX_CLICKED, &SubsEditBox::OnSplit, this);
middle_right_sizer->Add(split_box, wxSizerFlags().Center().Left());
// Main sizer
wxSizer *main_sizer = new wxBoxSizer(wxVERTICAL);
main_sizer->Add(top_sizer,0,wxEXPAND | wxALL,3);
main_sizer->Add(middle_left_sizer,0,wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM,3);
main_sizer->Add(middle_right_sizer,0,wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM,3);
// Text editor
edit_ctrl = new SubsTextEditCtrl(this, wxSize(300,50), wxBORDER_SUNKEN, c);
edit_ctrl->Bind(wxEVT_CHAR_HOOK, &SubsEditBox::OnKeyDown, this);
secondary_editor = new wxTextCtrl(this, -1, "", wxDefaultPosition, wxSize(300,50), wxBORDER_SUNKEN | wxTE_MULTILINE);
secondary_editor->Enable(false);
main_sizer->Add(secondary_editor,1,wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM,3);
main_sizer->Add(edit_ctrl,1,wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM,3);
main_sizer->Hide(secondary_editor);
bottom_sizer = new wxBoxSizer(wxHORIZONTAL);
bottom_sizer->Add(MakeBottomButton("edit/revert"));
bottom_sizer->Add(MakeBottomButton("edit/clear"));
bottom_sizer->Add(MakeBottomButton("edit/insert_original"));
main_sizer->Add(bottom_sizer);
main_sizer->Hide(bottom_sizer);
SetSizerAndFit(main_sizer);
@ -187,6 +204,7 @@ SubsEditBox::SubsEditBox(wxWindow *parent, agi::Context *context)
Bind(wxEVT_COMMAND_SPINCTRL_UPDATED, &SubsEditBox::OnLayerEnter, this, layer->GetId());
Bind(wxEVT_COMMAND_CHECKBOX_CLICKED, &SubsEditBox::OnCommentChange, this, comment_box->GetId());
Bind(wxEVT_CHAR_HOOK, &SubsEditBox::OnKeyDown, this);
Bind(wxEVT_SIZE, &SubsEditBox::OnSize, this);
Bind(wxEVT_TIMER, [=](wxTimerEvent&) { commit_id = -1; });
@ -197,6 +215,7 @@ SubsEditBox::SubsEditBox(wxWindow *parent, agi::Context *context)
connections.push_back(context->videoController->AddTimecodesListener(&SubsEditBox::UpdateFrameTiming, this));
connections.push_back(context->selectionController->AddActiveLineListener(&SubsEditBox::OnActiveLineChanged, this));
connections.push_back(context->selectionController->AddSelectionListener(&SubsEditBox::OnSelectedSetChanged, this));
connections.push_back(context->initialLineState->AddChangeListener(&SubsEditBox::OnLineInitialTextChanged, this));
textSelectionController.reset(new ScintillaTextSelectionController(edit_ctrl));
context->textSelectionController = textSelectionController.get();
@ -239,6 +258,15 @@ void SubsEditBox::MakeButton(const char *cmd_name) {
btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, std::bind(&SubsEditBox::CallCommand, this, cmd_name));
}
wxButton *SubsEditBox::MakeBottomButton(const char *cmd_name) {
cmd::Command *command = cmd::get(cmd_name);
wxButton *btn = new wxButton(this, -1, command->StrDisplay(c));
ToolTipManager::Bind(btn, command->StrHelp(), "Subtitle Edit Box", cmd_name);
btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, std::bind(&SubsEditBox::CallCommand, this, cmd_name));
return btn;
}
wxComboBox *SubsEditBox::MakeComboBox(wxString const& initial_text, int style, void (SubsEditBox::*handler)(wxCommandEvent&), wxString const& tooltip) {
wxString styles[] = { "Default" };
wxComboBox *ctrl = new wxComboBox(this, -1, initial_text, wxDefaultPosition, wxSize(110,-1), 1, styles, style | wxTE_PROCESS_ENTER);
@ -356,6 +384,11 @@ void SubsEditBox::OnSelectedSetChanged(const SubtitleSelection &, const Subtitle
initial_times.clear();
}
void SubsEditBox::OnLineInitialTextChanged(wxString const& new_text) {
if (split_box->IsChecked())
secondary_editor->SetValue(new_text);
}
void SubsEditBox::UpdateFrameTiming(agi::vfr::Framerate const& fps) {
if (fps.IsLoaded()) {
by_frame->Enable(true);
@ -491,6 +524,19 @@ void SubsEditBox::SetControlsState(bool state) {
}
}
void SubsEditBox::OnSplit(wxCommandEvent&) {
Freeze();
GetSizer()->Show(secondary_editor, split_box->IsChecked());
GetSizer()->Show(bottom_sizer, split_box->IsChecked());
Fit();
SetMinSize(GetSize());
GetParent()->GetSizer()->Layout();
Thaw();
if (split_box->IsChecked())
secondary_editor->SetValue(c->initialLineState->GetInitialText());
}
void SubsEditBox::OnStyleChange(wxCommandEvent &) {
SetSelectedRows(&AssDialogue::Style, boost::flyweight<wxString>(style_box->GetValue()), _("style change"), AssFile::COMMIT_DIAG_META);
}

View File

@ -104,10 +104,12 @@ class SubsEditBox : public wxPanel {
wxRadioButton *by_time;
wxRadioButton *by_frame;
wxTextCtrl *char_count;
wxCheckBox *split_box;
wxSizer *top_sizer;
wxSizer *middle_right_sizer;
wxSizer *middle_left_sizer;
wxSizer *bottom_sizer;
void SetControlsState(bool state);
/// @brief Update times of selected lines
@ -138,6 +140,7 @@ class SubsEditBox : public wxPanel {
wxTextCtrl *MakeMarginCtrl(wxString const& tooltip, int margin, wxString const& commit_msg);
TimeEdit *MakeTimeCtrl(wxString const& tooltip, TimeField field);
void MakeButton(const char *cmd_name);
wxButton *MakeBottomButton(const char *cmd_name);
wxComboBox *MakeComboBox(wxString const& initial_text, int style, void (SubsEditBox::*handler)(wxCommandEvent&), wxString const& tooltip);
wxRadioButton *MakeRadio(wxString const& text, bool start, wxString const& tooltip);
@ -146,6 +149,7 @@ class SubsEditBox : public wxPanel {
void OnActiveLineChanged(AssDialogue *new_line);
void OnSelectedSetChanged(const SubtitleSelection &, const SubtitleSelection &);
void OnLineInitialTextChanged(wxString const& new_text);
void OnFrameTimeRadio(wxCommandEvent &event);
void OnStyleChange(wxCommandEvent &event);
@ -154,6 +158,7 @@ class SubsEditBox : public wxPanel {
void OnCommentChange(wxCommandEvent &);
void OnEffectChange(wxCommandEvent &);
void OnSize(wxSizeEvent &event);
void OnSplit(wxCommandEvent&);
void SetPlaceholderCtrl(wxControl *ctrl, wxString const& value);
@ -191,6 +196,7 @@ class SubsEditBox : public wxPanel {
void CallCommand(const char *cmd_name);
SubsTextEditCtrl *edit_ctrl;
wxTextCtrl *secondary_editor;
agi::scoped_ptr<TextSelectionController> textSelectionController;
public: