2006-01-16 22:02:54 +01:00
|
|
|
// Copyright (c) 2005, Rodrigo Braz Monteiro
|
|
|
|
// All rights reserved.
|
|
|
|
//
|
|
|
|
// Redistribution and use in source and binary forms, with or without
|
|
|
|
// modification, are permitted provided that the following conditions are met:
|
|
|
|
//
|
|
|
|
// * Redistributions of source code must retain the above copyright notice,
|
|
|
|
// this list of conditions and the following disclaimer.
|
|
|
|
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
|
|
// this list of conditions and the following disclaimer in the documentation
|
|
|
|
// and/or other materials provided with the distribution.
|
|
|
|
// * Neither the name of the Aegisub Group nor the names of its contributors
|
|
|
|
// may be used to endorse or promote products derived from this software
|
|
|
|
// without specific prior written permission.
|
|
|
|
//
|
|
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
|
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
|
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
// POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
//
|
2009-07-29 07:43:02 +02:00
|
|
|
// Aegisub Project http://www.aegisub.org/
|
|
|
|
|
|
|
|
/// @file dialog_style_editor.cpp
|
|
|
|
/// @brief Style Editor dialogue box
|
|
|
|
/// @ingroup style_editor
|
|
|
|
///
|
2006-01-16 22:02:54 +01:00
|
|
|
|
2009-01-04 07:31:48 +01:00
|
|
|
#include "config.h"
|
|
|
|
|
2011-10-10 21:30:11 +02:00
|
|
|
#include <algorithm>
|
2011-10-10 19:28:59 +02:00
|
|
|
|
2011-10-10 21:30:11 +02:00
|
|
|
#include <wx/bmpbuttn.h>
|
2007-05-21 05:59:46 +02:00
|
|
|
#include <wx/fontenum.h>
|
2012-12-02 00:57:02 +01:00
|
|
|
#include <wx/msgdlg.h>
|
|
|
|
#include <wx/sizer.h>
|
|
|
|
#include <wx/stattext.h>
|
2009-09-10 15:06:40 +02:00
|
|
|
|
2006-12-17 21:16:22 +01:00
|
|
|
#include "ass_dialogue.h"
|
2006-01-16 22:02:54 +01:00
|
|
|
#include "ass_file.h"
|
2009-09-10 15:06:40 +02:00
|
|
|
#include "ass_style.h"
|
2007-07-27 08:14:38 +02:00
|
|
|
#include "ass_style_storage.h"
|
2011-10-10 19:28:48 +02:00
|
|
|
#include "colour_button.h"
|
2010-05-21 03:13:36 +02:00
|
|
|
#include "compat.h"
|
2009-09-10 15:06:40 +02:00
|
|
|
#include "dialog_style_editor.h"
|
2008-01-13 22:27:06 +01:00
|
|
|
#include "help_button.h"
|
2011-10-10 19:28:48 +02:00
|
|
|
#include "include/aegisub/context.h"
|
|
|
|
#include "include/aegisub/subtitles_provider.h"
|
2009-07-24 02:08:25 +02:00
|
|
|
#include "libresrc/libresrc.h"
|
2010-05-21 03:13:36 +02:00
|
|
|
#include "main.h"
|
2011-10-10 19:28:48 +02:00
|
|
|
#include "persist_location.h"
|
2010-12-08 04:36:10 +01:00
|
|
|
#include "selection_controller.h"
|
2009-09-10 15:06:40 +02:00
|
|
|
#include "subs_grid.h"
|
|
|
|
#include "subs_preview.h"
|
|
|
|
#include "utils.h"
|
|
|
|
#include "validators.h"
|
2007-04-17 01:41:06 +02:00
|
|
|
|
2012-11-05 17:20:58 +01:00
|
|
|
#include <libaegisub/of_type_adaptor.h>
|
|
|
|
|
2012-03-07 23:40:26 +01:00
|
|
|
/// Style rename helper that walks a file searching for a style and optionally
|
|
|
|
/// updating references to it
|
|
|
|
class StyleRenamer {
|
|
|
|
agi::Context *c;
|
|
|
|
bool found_any;
|
|
|
|
bool do_replace;
|
|
|
|
wxString source_name;
|
|
|
|
wxString new_name;
|
|
|
|
|
|
|
|
/// Process a single override parameter to check if it's \r with this style name
|
2012-12-30 00:53:56 +01:00
|
|
|
static void ProcessTag(std::string const& tag, AssOverrideParameter* param, void *userData) {
|
2012-03-07 23:40:26 +01:00
|
|
|
StyleRenamer *self = static_cast<StyleRenamer*>(userData);
|
2012-12-30 00:53:56 +01:00
|
|
|
if (tag == "\\r" && param->GetType() == VARDATA_TEXT && to_wx(param->Get<std::string>()) == self->source_name) {
|
2012-03-07 23:40:26 +01:00
|
|
|
if (self->do_replace)
|
2012-12-30 00:53:56 +01:00
|
|
|
param->Set(from_wx(self->new_name));
|
2012-03-07 23:40:26 +01:00
|
|
|
else
|
|
|
|
self->found_any = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Walk(bool replace) {
|
|
|
|
found_any = false;
|
|
|
|
do_replace = replace;
|
|
|
|
|
2012-11-05 17:20:58 +01:00
|
|
|
for (auto diag : c->ass->Line | agi::of_type<AssDialogue>()) {
|
2012-03-07 23:40:26 +01:00
|
|
|
if (diag->Style == source_name) {
|
|
|
|
if (replace)
|
|
|
|
diag->Style = new_name;
|
|
|
|
else
|
|
|
|
found_any = true;
|
|
|
|
}
|
|
|
|
|
2012-12-02 19:24:49 +01:00
|
|
|
boost::ptr_vector<AssDialogueBlock> blocks(diag->ParseTags());
|
|
|
|
for (auto block : blocks | agi::of_type<AssDialogueBlockOverride>())
|
|
|
|
block->ProcessParameters(&StyleRenamer::ProcessTag, this);
|
2012-03-07 23:40:26 +01:00
|
|
|
if (replace)
|
2012-12-02 19:24:49 +01:00
|
|
|
diag->UpdateText(blocks);
|
2012-03-07 23:40:26 +01:00
|
|
|
|
|
|
|
if (found_any) return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
StyleRenamer(agi::Context *c, wxString const& source_name, wxString const& new_name)
|
|
|
|
: c(c)
|
|
|
|
, found_any(false)
|
|
|
|
, do_replace(false)
|
|
|
|
, source_name(source_name)
|
|
|
|
, new_name(new_name)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Check if there are any uses of the original style name in the file
|
|
|
|
bool NeedsReplace() {
|
|
|
|
Walk(false);
|
|
|
|
return found_any;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Replace all uses of the original style name with the new one
|
|
|
|
void Replace() {
|
|
|
|
Walk(true);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2011-10-10 19:28:59 +02:00
|
|
|
static void add_with_label(wxSizer *sizer, wxWindow *parent, wxString const& label, wxWindow *ctrl) {
|
|
|
|
sizer->Add(new wxStaticText(parent, -1, label), wxSizerFlags().Center().Right().Border(wxLEFT | wxRIGHT));
|
|
|
|
sizer->Add(ctrl, wxSizerFlags(1).Left().Expand());
|
|
|
|
}
|
|
|
|
|
|
|
|
static wxSpinCtrl *spin_ctrl(wxWindow *parent, float value, int max_value) {
|
|
|
|
return new wxSpinCtrl(parent, -1, AegiFloatToString(value), wxDefaultPosition, wxSize(60, -1), wxSP_ARROW_KEYS, 0, max_value, value);
|
|
|
|
}
|
2007-04-17 01:41:06 +02:00
|
|
|
|
2011-10-10 19:28:59 +02:00
|
|
|
static wxTextCtrl *num_text_ctrl(wxWindow *parent, double value, wxSize size = wxSize(70, 20)) {
|
2011-12-22 22:23:07 +01:00
|
|
|
return new wxTextCtrl(parent, -1, "", wxDefaultPosition, size, 0, NumValidator(value));
|
2011-10-10 19:28:59 +02:00
|
|
|
}
|
|
|
|
|
2012-03-07 23:40:15 +01:00
|
|
|
DialogStyleEditor::DialogStyleEditor(wxWindow *parent, AssStyle *style, agi::Context *c, AssStyleStorage *store, wxString const& new_name)
|
|
|
|
: wxDialog (parent, -1, _("Style Editor"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
|
2011-01-16 08:17:36 +01:00
|
|
|
, c(c)
|
2011-10-18 00:00:58 +02:00
|
|
|
, is_new(false)
|
2011-10-10 19:29:09 +02:00
|
|
|
, style(style)
|
2011-01-16 08:17:36 +01:00
|
|
|
, store(store)
|
2006-01-16 22:02:54 +01:00
|
|
|
{
|
2012-03-07 23:40:15 +01:00
|
|
|
if (new_name.size()) {
|
2011-10-18 00:00:58 +02:00
|
|
|
is_new = true;
|
|
|
|
style = this->style = new AssStyle(*style);
|
2012-03-07 23:40:15 +01:00
|
|
|
style->name = new_name;
|
2011-10-18 00:00:58 +02:00
|
|
|
}
|
|
|
|
else if (!style) {
|
|
|
|
is_new = true;
|
|
|
|
style = this->style = new AssStyle;
|
|
|
|
}
|
|
|
|
|
|
|
|
work.reset(new AssStyle(*style));
|
|
|
|
|
2012-04-03 22:40:24 +02:00
|
|
|
SetIcon(GETICON(style_toolbutton_16));
|
2007-07-05 01:09:40 +02:00
|
|
|
|
2007-04-17 00:13:09 +02:00
|
|
|
// Prepare control values
|
2011-01-20 06:57:30 +01:00
|
|
|
wxString EncodingValue = AegiIntegerToString(style->encoding);
|
2011-10-10 19:28:59 +02:00
|
|
|
wxString alignValues[9] = { "7", "8", "9", "4", "5", "6", "1", "2", "3" };
|
2007-05-21 05:59:46 +02:00
|
|
|
wxArrayString fontList = wxFontEnumerator::GetFacenames();
|
|
|
|
fontList.Sort();
|
2006-01-16 22:02:54 +01:00
|
|
|
|
2007-04-17 00:13:09 +02:00
|
|
|
// Encoding options
|
|
|
|
wxArrayString encodingStrings;
|
|
|
|
AssStyle::GetEncodings(encodingStrings);
|
2012-03-25 06:05:06 +02:00
|
|
|
|
2007-09-24 19:04:13 +02:00
|
|
|
// Create sizers
|
2012-01-08 02:05:25 +01:00
|
|
|
wxSizer *NameSizer = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Style Name"));
|
2007-09-24 19:04:13 +02:00
|
|
|
wxSizer *FontSizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Font"));
|
2011-10-10 19:28:59 +02:00
|
|
|
wxSizer *ColorsSizer = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Colors"));
|
|
|
|
wxSizer *MarginSizer = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Margins"));
|
|
|
|
wxSizer *OutlineBox = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Outline"));
|
|
|
|
wxSizer *MiscBox = new wxStaticBoxSizer(wxVERTICAL, this, _("Miscellaneous"));
|
|
|
|
wxSizer *PreviewBox = new wxStaticBoxSizer(wxVERTICAL, this, _("Preview"));
|
2007-04-17 00:13:09 +02:00
|
|
|
|
|
|
|
// Create controls
|
2011-10-10 19:28:59 +02:00
|
|
|
StyleName = new wxTextCtrl(this, -1, style->name);
|
|
|
|
FontName = new wxComboBox(this, -1, style->font, wxDefaultPosition, wxSize(150, -1), 0, 0, wxCB_DROPDOWN);
|
|
|
|
FontSize = num_text_ctrl(this, style->fontsize, wxSize(50, -1));
|
2011-11-18 19:49:09 +01:00
|
|
|
BoxBold = new wxCheckBox(this, -1, _("&Bold"));
|
|
|
|
BoxItalic = new wxCheckBox(this, -1, _("&Italic"));
|
|
|
|
BoxUnderline = new wxCheckBox(this, -1, _("&Underline"));
|
|
|
|
BoxStrikeout = new wxCheckBox(this, -1, _("&Strikeout"));
|
2012-10-26 16:09:14 +02:00
|
|
|
colorButton[0] = new ColourButton(this, -1, wxSize(55, 16), style->primary);
|
|
|
|
colorButton[1] = new ColourButton(this, -1, wxSize(55, 16), style->secondary);
|
|
|
|
colorButton[2] = new ColourButton(this, -1, wxSize(55, 16), style->outline);
|
|
|
|
colorButton[3] = new ColourButton(this, -1, wxSize(55, 16), style->shadow);
|
2011-10-10 19:28:59 +02:00
|
|
|
colorAlpha[0] = spin_ctrl(this, style->primary.a, 255);
|
|
|
|
colorAlpha[1] = spin_ctrl(this, style->secondary.a, 255);
|
|
|
|
colorAlpha[2] = spin_ctrl(this, style->outline.a, 255);
|
|
|
|
colorAlpha[3] = spin_ctrl(this, style->shadow.a, 255);
|
|
|
|
for (int i = 0; i < 3; i++)
|
|
|
|
margin[i] = spin_ctrl(this, style->Margin[i], 9999);
|
|
|
|
Alignment = new wxRadioBox(this, -1, _("Alignment"), wxDefaultPosition, wxDefaultSize, 9, alignValues, 3, wxRA_SPECIFY_COLS);
|
|
|
|
Outline = num_text_ctrl(this, style->outline_w, wxSize(50, -1));
|
|
|
|
Shadow = num_text_ctrl(this, style->shadow_w, wxSize(50, -1));
|
2011-11-18 19:49:09 +01:00
|
|
|
OutlineType = new wxCheckBox(this, -1, _("&Opaque box"));
|
2011-10-10 19:28:59 +02:00
|
|
|
ScaleX = num_text_ctrl(this, style->scalex);
|
|
|
|
ScaleY = num_text_ctrl(this, style->scaley);
|
|
|
|
Angle = num_text_ctrl(this, style->angle);
|
|
|
|
Spacing = num_text_ctrl(this, style->spacing);
|
|
|
|
Encoding = new wxComboBox(this, -1, "", wxDefaultPosition, wxDefaultSize, encodingStrings, wxCB_READONLY);
|
2007-04-17 00:13:09 +02:00
|
|
|
|
|
|
|
// Set control tooltips
|
2012-02-07 02:22:32 +01:00
|
|
|
StyleName->SetToolTip(_("Style name"));
|
|
|
|
FontName->SetToolTip(_("Font face"));
|
|
|
|
FontSize->SetToolTip(_("Font size"));
|
|
|
|
colorButton[0]->SetToolTip(_("Choose primary color"));
|
|
|
|
colorButton[1]->SetToolTip(_("Choose secondary color"));
|
|
|
|
colorButton[2]->SetToolTip(_("Choose outline color"));
|
|
|
|
colorButton[3]->SetToolTip(_("Choose shadow color"));
|
|
|
|
for (int i=0;i<4;i++) colorAlpha[i]->SetToolTip(_("Set opacity, from 0 (opaque) to 255 (transparent)"));
|
|
|
|
margin[0]->SetToolTip(_("Distance from left edge, in pixels"));
|
|
|
|
margin[1]->SetToolTip(_("Distance from right edge, in pixels"));
|
|
|
|
margin[2]->SetToolTip(_("Distance from top/bottom edge, in pixels"));
|
|
|
|
OutlineType->SetToolTip(_("When selected, display an opaque box behind the subtitles instead of an outline around the text"));
|
|
|
|
Outline->SetToolTip(_("Outline width, in pixels"));
|
|
|
|
Shadow->SetToolTip(_("Shadow distance, in pixels"));
|
|
|
|
ScaleX->SetToolTip(_("Scale X, in percentage"));
|
|
|
|
ScaleY->SetToolTip(_("Scale Y, in percentage"));
|
|
|
|
Angle->SetToolTip(_("Angle to rotate in Z axis, in degrees"));
|
|
|
|
Encoding->SetToolTip(_("Encoding, only useful in unicode if the font doesn't have the proper unicode mapping"));
|
|
|
|
Spacing->SetToolTip(_("Character spacing, in pixels"));
|
|
|
|
Alignment->SetToolTip(_("Alignment in screen, in numpad style"));
|
2007-04-17 00:13:09 +02:00
|
|
|
|
|
|
|
// Set up controls
|
2006-01-16 22:02:54 +01:00
|
|
|
BoxBold->SetValue(style->bold);
|
|
|
|
BoxItalic->SetValue(style->italic);
|
|
|
|
BoxUnderline->SetValue(style->underline);
|
|
|
|
BoxStrikeout->SetValue(style->strikeout);
|
2007-04-17 00:13:09 +02:00
|
|
|
OutlineType->SetValue(style->borderstyle == 3);
|
|
|
|
Alignment->SetSelection(AlignToControl(style->alignment));
|
2007-06-06 23:42:32 +02:00
|
|
|
// Fill font face list box
|
|
|
|
FontName->Freeze();
|
2012-04-17 01:54:53 +02:00
|
|
|
FontName->Append(fontList);
|
2008-07-16 14:10:00 +02:00
|
|
|
FontName->SetValue(style->font);
|
2007-06-06 23:42:32 +02:00
|
|
|
FontName->Thaw();
|
2007-04-17 00:13:09 +02:00
|
|
|
|
|
|
|
// Set encoding value
|
|
|
|
bool found = false;
|
|
|
|
for (size_t i=0;i<encodingStrings.Count();i++) {
|
2007-06-06 23:42:32 +02:00
|
|
|
if (encodingStrings[i].StartsWith(EncodingValue)) {
|
2007-04-17 00:13:09 +02:00
|
|
|
Encoding->Select(i);
|
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!found) Encoding->Select(0);
|
|
|
|
|
|
|
|
// Style name sizer
|
2011-10-10 19:28:59 +02:00
|
|
|
NameSizer->Add(StyleName, 1, wxALL, 0);
|
2007-04-17 00:13:09 +02:00
|
|
|
|
|
|
|
// Font sizer
|
|
|
|
wxSizer *FontSizerTop = new wxBoxSizer(wxHORIZONTAL);
|
|
|
|
wxSizer *FontSizerBottom = new wxBoxSizer(wxHORIZONTAL);
|
2011-10-10 19:28:59 +02:00
|
|
|
FontSizerTop->Add(FontName, 1, wxALL, 0);
|
|
|
|
FontSizerTop->Add(FontSize, 0, wxLEFT, 5);
|
2006-01-16 22:02:54 +01:00
|
|
|
FontSizerBottom->AddStretchSpacer(1);
|
2011-10-10 19:28:59 +02:00
|
|
|
FontSizerBottom->Add(BoxBold, 0, 0, 0);
|
|
|
|
FontSizerBottom->Add(BoxItalic, 0, wxLEFT, 5);
|
|
|
|
FontSizerBottom->Add(BoxUnderline, 0, wxLEFT, 5);
|
|
|
|
FontSizerBottom->Add(BoxStrikeout, 0, wxLEFT, 5);
|
2006-01-16 22:02:54 +01:00
|
|
|
FontSizerBottom->AddStretchSpacer(1);
|
2011-10-10 19:28:59 +02:00
|
|
|
FontSizer->Add(FontSizerTop, 1, wxALL | wxEXPAND, 0);
|
|
|
|
FontSizer->Add(FontSizerBottom, 1, wxTOP | wxEXPAND, 5);
|
2006-01-16 22:02:54 +01:00
|
|
|
|
2007-04-17 00:13:09 +02:00
|
|
|
// Colors sizer
|
2007-05-21 07:38:28 +02:00
|
|
|
wxSizer *ColorSizer[4];
|
|
|
|
wxString colorLabels[] = { _("Primary"), _("Secondary"), _("Outline"), _("Shadow") };
|
2006-01-16 22:02:54 +01:00
|
|
|
ColorsSizer->AddStretchSpacer(1);
|
2007-05-21 07:38:28 +02:00
|
|
|
for (int i=0;i<4;i++) {
|
|
|
|
ColorSizer[i] = new wxBoxSizer(wxVERTICAL);
|
2011-10-10 19:28:59 +02:00
|
|
|
ColorSizer[i]->Add(new wxStaticText(this, -1, colorLabels[i]), 0, wxBOTTOM | wxALIGN_CENTER, 5);
|
|
|
|
ColorSizer[i]->Add(colorButton[i], 0, wxBOTTOM | wxALIGN_CENTER, 5);
|
|
|
|
ColorSizer[i]->Add(colorAlpha[i], 0, wxALIGN_CENTER, 0);
|
|
|
|
ColorsSizer->Add(ColorSizer[i], 0, wxLEFT, i?5:0);
|
2007-05-21 07:38:28 +02:00
|
|
|
}
|
2006-01-16 22:02:54 +01:00
|
|
|
ColorsSizer->AddStretchSpacer(1);
|
|
|
|
|
|
|
|
// Margins
|
2007-05-21 08:03:09 +02:00
|
|
|
wxString marginLabels[] = { _("Left"), _("Right"), _("Vert") };
|
2006-01-16 22:02:54 +01:00
|
|
|
MarginSizer->AddStretchSpacer(1);
|
2007-05-21 08:03:09 +02:00
|
|
|
wxSizer *marginSubSizer[3];
|
|
|
|
for (int i=0;i<3;i++) {
|
|
|
|
marginSubSizer[i] = new wxBoxSizer(wxVERTICAL);
|
|
|
|
marginSubSizer[i]->AddStretchSpacer(1);
|
2011-10-10 19:28:59 +02:00
|
|
|
marginSubSizer[i]->Add(new wxStaticText(this, -1, marginLabels[i]), 0, wxCENTER, 0);
|
|
|
|
marginSubSizer[i]->Add(margin[i], 0, wxTOP | wxCENTER, 5);
|
2007-05-21 08:03:09 +02:00
|
|
|
marginSubSizer[i]->AddStretchSpacer(1);
|
2011-10-10 19:28:59 +02:00
|
|
|
MarginSizer->Add(marginSubSizer[i], 0, wxEXPAND | wxLEFT, i?5:0);
|
2007-05-21 08:03:09 +02:00
|
|
|
}
|
2006-01-16 22:02:54 +01:00
|
|
|
MarginSizer->AddStretchSpacer(1);
|
|
|
|
|
|
|
|
// Margins+Alignment
|
|
|
|
wxSizer *MarginAlign = new wxBoxSizer(wxHORIZONTAL);
|
2011-10-10 19:28:59 +02:00
|
|
|
MarginAlign->Add(MarginSizer, 1, wxLEFT | wxEXPAND, 0);
|
|
|
|
MarginAlign->Add(Alignment, 0, wxLEFT | wxEXPAND, 5);
|
2006-01-16 22:02:54 +01:00
|
|
|
|
|
|
|
// Outline
|
2011-10-10 19:28:59 +02:00
|
|
|
add_with_label(OutlineBox, this, _("Outline:"), Outline);
|
|
|
|
add_with_label(OutlineBox, this, _("Shadow:"), Shadow);
|
|
|
|
OutlineBox->Add(OutlineType, 0, wxLEFT | wxALIGN_CENTER, 5);
|
2006-01-16 22:02:54 +01:00
|
|
|
|
|
|
|
// Misc
|
2011-10-10 19:28:59 +02:00
|
|
|
wxFlexGridSizer *MiscBoxTop = new wxFlexGridSizer(2, 4, 5, 5);
|
|
|
|
add_with_label(MiscBoxTop, this, _("Scale X%:"), ScaleX);
|
|
|
|
add_with_label(MiscBoxTop, this, _("Scale Y%:"), ScaleY);
|
|
|
|
add_with_label(MiscBoxTop, this, _("Rotation:"), Angle);
|
|
|
|
add_with_label(MiscBoxTop, this, _("Spacing:"), Spacing);
|
|
|
|
|
2006-01-16 22:02:54 +01:00
|
|
|
wxSizer *MiscBoxBottom = new wxBoxSizer(wxHORIZONTAL);
|
2011-10-10 19:28:59 +02:00
|
|
|
add_with_label(MiscBoxBottom, this, _("Encoding:"), Encoding);
|
|
|
|
|
|
|
|
MiscBox->Add(MiscBoxTop, wxSizerFlags().Expand().Center());
|
|
|
|
MiscBox->Add(MiscBoxBottom, wxSizerFlags().Expand().Center().Border(wxTOP));
|
2006-01-16 22:02:54 +01:00
|
|
|
|
2007-04-16 17:08:09 +02:00
|
|
|
// Preview
|
2012-11-13 17:51:01 +01:00
|
|
|
SubsPreview = nullptr;
|
|
|
|
PreviewText = nullptr;
|
2011-10-10 19:29:17 +02:00
|
|
|
ColourButton *previewButton = 0;
|
2010-08-02 08:31:38 +02:00
|
|
|
if (!SubtitlesProviderFactory::GetClasses().empty()) {
|
2012-12-23 00:18:38 +01:00
|
|
|
PreviewText = new wxTextCtrl(this, -1, to_wx(OPT_GET("Tool/Style Editor/Preview Text")->GetString()));
|
2012-10-26 16:09:14 +02:00
|
|
|
previewButton = new ColourButton(this, -1, wxSize(45, 16), OPT_GET("Colour/Style Editor/Background/Preview")->GetColor());
|
|
|
|
SubsPreview = new SubtitlesPreview(this, wxSize(100, 60), wxSUNKEN_BORDER, OPT_GET("Colour/Style Editor/Background/Preview")->GetColor());
|
2012-03-25 06:05:06 +02:00
|
|
|
|
2012-02-07 02:22:32 +01:00
|
|
|
SubsPreview->SetToolTip(_("Preview of current style"));
|
2010-06-11 04:25:34 +02:00
|
|
|
SubsPreview->SetStyle(*style);
|
2007-06-03 06:54:38 +02:00
|
|
|
SubsPreview->SetText(PreviewText->GetValue());
|
2012-02-07 02:22:32 +01:00
|
|
|
PreviewText->SetToolTip(_("Text to be used for the preview"));
|
2012-04-03 19:38:50 +02:00
|
|
|
previewButton->SetToolTip(_("Color of preview background"));
|
2007-06-03 06:54:38 +02:00
|
|
|
|
|
|
|
wxSizer *PreviewBottomSizer = new wxBoxSizer(wxHORIZONTAL);
|
2011-10-10 19:28:59 +02:00
|
|
|
PreviewBottomSizer->Add(PreviewText, 1, wxEXPAND | wxRIGHT, 5);
|
|
|
|
PreviewBottomSizer->Add(previewButton, 0, wxEXPAND, 0);
|
|
|
|
PreviewBox->Add(SubsPreview, 1, wxEXPAND | wxBOTTOM, 5);
|
|
|
|
PreviewBox->Add(PreviewBottomSizer, 0, wxEXPAND | wxBOTTOM, 0);
|
2007-06-03 06:54:38 +02:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
wxStaticText *NoSP = new wxStaticText(this, -1, _("No subtitle providers available. Cannot preview subs."));
|
|
|
|
PreviewBox->AddStretchSpacer();
|
2011-10-10 19:28:59 +02:00
|
|
|
PreviewBox->Add(NoSP, 1, wxEXPAND|wxLEFT|wxRIGHT, 8);
|
2007-06-03 06:54:38 +02:00
|
|
|
PreviewBox->AddStretchSpacer();
|
|
|
|
}
|
|
|
|
|
2006-01-16 22:02:54 +01:00
|
|
|
// Buttons
|
2011-10-10 19:28:59 +02:00
|
|
|
wxStdDialogButtonSizer *ButtonSizer = CreateStdDialogButtonSizer(wxOK | wxCANCEL | wxAPPLY | wxHELP);
|
2007-06-03 06:54:38 +02:00
|
|
|
|
2007-04-16 06:26:42 +02:00
|
|
|
// Left side sizer
|
|
|
|
wxSizer *LeftSizer = new wxBoxSizer(wxVERTICAL);
|
2011-10-10 19:28:59 +02:00
|
|
|
LeftSizer->Add(NameSizer, 0, wxBOTTOM | wxEXPAND, 5);
|
|
|
|
LeftSizer->Add(FontSizer, 0, wxBOTTOM | wxEXPAND, 5);
|
|
|
|
LeftSizer->Add(ColorsSizer, 0, wxBOTTOM | wxEXPAND, 5);
|
|
|
|
LeftSizer->Add(MarginAlign, 0, wxBOTTOM | wxEXPAND, 0);
|
2007-04-16 06:26:42 +02:00
|
|
|
|
|
|
|
// Right side sizer
|
|
|
|
wxSizer *RightSizer = new wxBoxSizer(wxVERTICAL);
|
2011-10-10 19:28:59 +02:00
|
|
|
RightSizer->Add(OutlineBox, wxSizerFlags().Expand().Border(wxBOTTOM));
|
|
|
|
RightSizer->Add(MiscBox, wxSizerFlags().Expand().Border(wxBOTTOM));
|
|
|
|
RightSizer->Add(PreviewBox, wxSizerFlags(1).Expand());
|
2007-04-16 06:26:42 +02:00
|
|
|
|
|
|
|
// Controls Sizer
|
|
|
|
wxSizer *ControlSizer = new wxBoxSizer(wxHORIZONTAL);
|
2011-10-10 19:28:59 +02:00
|
|
|
ControlSizer->Add(LeftSizer, 0, wxEXPAND, 0);
|
|
|
|
ControlSizer->Add(RightSizer, 1, wxLEFT | wxEXPAND, 5);
|
2007-04-16 06:26:42 +02:00
|
|
|
|
2006-01-16 22:02:54 +01:00
|
|
|
// General Layout
|
2011-10-10 19:29:17 +02:00
|
|
|
wxSizer *MainSizer = new wxBoxSizer(wxVERTICAL);
|
2011-10-10 19:28:59 +02:00
|
|
|
MainSizer->Add(ControlSizer, 1, wxALL | wxALIGN_CENTER | wxEXPAND, 5);
|
|
|
|
MainSizer->Add(ButtonSizer, 0, wxBOTTOM | wxEXPAND, 5);
|
2006-01-16 22:02:54 +01:00
|
|
|
|
2011-10-10 19:28:59 +02:00
|
|
|
SetSizerAndFit(MainSizer);
|
2011-10-10 19:28:48 +02:00
|
|
|
|
2012-05-01 04:50:09 +02:00
|
|
|
// Force the style name text field to scroll based on its final size, rather
|
|
|
|
// than its initial size
|
|
|
|
StyleName->SetInsertionPoint(0);
|
|
|
|
StyleName->SetInsertionPoint(-1);
|
|
|
|
|
2012-05-03 00:42:37 +02:00
|
|
|
persist.reset(new PersistLocation(this, "Tool/Style Editor", true));
|
2011-10-10 19:28:59 +02:00
|
|
|
|
|
|
|
Bind(wxEVT_CHILD_FOCUS, &DialogStyleEditor::OnChildFocus, this);
|
2012-03-25 06:05:06 +02:00
|
|
|
|
2011-10-10 19:28:59 +02:00
|
|
|
if (PreviewText) {
|
|
|
|
Bind(wxEVT_COMMAND_CHECKBOX_CLICKED, &DialogStyleEditor::OnCommandPreviewUpdate, this);
|
|
|
|
Bind(wxEVT_COMMAND_COMBOBOX_SELECTED, &DialogStyleEditor::OnCommandPreviewUpdate, this);
|
|
|
|
Bind(wxEVT_COMMAND_SPINCTRL_UPDATED, &DialogStyleEditor::OnCommandPreviewUpdate, this);
|
|
|
|
|
|
|
|
previewButton->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &DialogStyleEditor::OnPreviewColourChange, this);
|
|
|
|
FontName->Bind(wxEVT_COMMAND_TEXT_ENTER, &DialogStyleEditor::OnCommandPreviewUpdate, this);
|
|
|
|
PreviewText->Bind(wxEVT_COMMAND_TEXT_UPDATED, &DialogStyleEditor::OnPreviewTextChange, this);
|
|
|
|
}
|
|
|
|
|
2012-09-25 01:35:27 +02:00
|
|
|
Bind(wxEVT_COMMAND_BUTTON_CLICKED, std::bind(&DialogStyleEditor::Apply, this, true, true), wxID_OK);
|
|
|
|
Bind(wxEVT_COMMAND_BUTTON_CLICKED, std::bind(&DialogStyleEditor::Apply, this, true, false), wxID_APPLY);
|
|
|
|
Bind(wxEVT_COMMAND_BUTTON_CLICKED, std::bind(&DialogStyleEditor::Apply, this, false, true), wxID_CANCEL);
|
|
|
|
Bind(wxEVT_COMMAND_BUTTON_CLICKED, std::bind(&HelpButton::OpenPage, "Style Editor"), wxID_HELP);
|
2011-10-10 19:28:59 +02:00
|
|
|
|
|
|
|
for (int i = 0; i < 4; ++i)
|
2012-09-25 03:15:20 +02:00
|
|
|
colorButton[i]->Bind(wxEVT_COMMAND_BUTTON_CLICKED, std::bind(&DialogStyleEditor::OnSetColor, this, i + 1, std::placeholders::_1));
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
|
|
|
|
2011-10-18 00:00:58 +02:00
|
|
|
DialogStyleEditor::~DialogStyleEditor() {
|
|
|
|
if (is_new)
|
|
|
|
delete style;
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
|
|
|
|
2012-03-07 23:40:15 +01:00
|
|
|
wxString DialogStyleEditor::GetStyleName() const {
|
|
|
|
return style->name;
|
|
|
|
}
|
|
|
|
|
2011-10-18 00:00:58 +02:00
|
|
|
void DialogStyleEditor::Apply(bool apply, bool close) {
|
2006-01-16 22:02:54 +01:00
|
|
|
if (apply) {
|
2006-12-17 21:16:22 +01:00
|
|
|
wxString newStyleName = StyleName->GetValue();
|
2006-12-17 21:30:59 +01:00
|
|
|
|
2007-07-27 08:14:38 +02:00
|
|
|
// Get list of existing styles
|
2011-10-18 00:00:58 +02:00
|
|
|
wxArrayString styles = store ? store->GetNames() : c->ass->GetStyles();
|
2007-07-27 08:14:38 +02:00
|
|
|
|
2006-12-17 21:30:59 +01:00
|
|
|
// Check if style name is unique
|
2012-11-04 04:53:03 +01:00
|
|
|
for (auto const& style_name : styles) {
|
|
|
|
if (newStyleName.CmpNoCase(style_name) == 0) {
|
|
|
|
if ((store && store->GetStyle(style_name) != style) || (!store && c->ass->GetStyle(style_name) != style)) {
|
2012-03-29 01:59:19 +02:00
|
|
|
wxMessageBox("There is already a style with this name. Please choose another name.", "Style name conflict.", wxOK | wxICON_ERROR | wxCENTER);
|
2007-04-08 02:21:56 +02:00
|
|
|
return;
|
2006-12-17 21:30:59 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Style name change
|
2011-09-15 07:16:32 +02:00
|
|
|
bool did_rename = false;
|
2007-03-18 02:20:25 +01:00
|
|
|
if (work->name != newStyleName) {
|
2012-02-07 21:42:44 +01:00
|
|
|
if (!store && !is_new) {
|
2012-03-07 23:40:26 +01:00
|
|
|
StyleRenamer renamer(c, work->name, newStyleName);
|
|
|
|
if (renamer.NeedsReplace()) {
|
|
|
|
// See if user wants to update style name through script
|
|
|
|
int answer = wxMessageBox(
|
|
|
|
_("Do you want to change all instances of this style in the script to this new name?"),
|
|
|
|
_("Update script?"),
|
|
|
|
wxYES_NO | wxCANCEL);
|
|
|
|
|
|
|
|
if (answer == wxCANCEL) return;
|
|
|
|
|
|
|
|
if (answer == wxYES) {
|
|
|
|
did_rename = true;
|
|
|
|
renamer.Replace();
|
2007-03-18 02:20:25 +01:00
|
|
|
}
|
2006-12-17 21:16:22 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
work->name = newStyleName;
|
|
|
|
}
|
|
|
|
|
2007-04-17 01:41:06 +02:00
|
|
|
UpdateWorkStyle();
|
2006-04-20 01:47:41 +02:00
|
|
|
|
2006-01-16 22:02:54 +01:00
|
|
|
*style = *work;
|
|
|
|
style->UpdateData();
|
2011-10-18 00:00:58 +02:00
|
|
|
if (is_new) {
|
|
|
|
if (store)
|
2012-03-08 05:17:29 +01:00
|
|
|
store->push_back(style);
|
2011-10-18 00:00:58 +02:00
|
|
|
else
|
2012-11-22 17:14:34 +01:00
|
|
|
c->ass->InsertLine(style);
|
2011-10-18 00:00:58 +02:00
|
|
|
is_new = false;
|
|
|
|
}
|
|
|
|
if (!store)
|
2011-09-15 07:16:32 +02:00
|
|
|
c->ass->Commit(_("style change"), AssFile::COMMIT_STYLES | (did_rename ? AssFile::COMMIT_DIAG_FULL : 0));
|
2007-04-16 06:26:42 +02:00
|
|
|
|
|
|
|
// Update preview
|
2011-10-10 19:28:59 +02:00
|
|
|
if (!close && SubsPreview) SubsPreview->SetStyle(*style);
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
|
|
|
|
2011-10-10 19:28:59 +02:00
|
|
|
if (close) {
|
|
|
|
EndModal(apply);
|
|
|
|
if (PreviewText)
|
2012-12-23 00:18:38 +01:00
|
|
|
OPT_SET("Tool/Style Editor/Preview Text")->SetString(from_wx(PreviewText->GetValue()));
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-25 06:05:06 +02:00
|
|
|
/// @brief Update work style
|
2007-04-17 01:41:06 +02:00
|
|
|
void DialogStyleEditor::UpdateWorkStyle() {
|
|
|
|
work->font = FontName->GetValue();
|
|
|
|
FontSize->GetValue().ToDouble(&(work->fontsize));
|
|
|
|
|
|
|
|
ScaleX->GetValue().ToDouble(&(work->scalex));
|
|
|
|
ScaleY->GetValue().ToDouble(&(work->scaley));
|
|
|
|
|
|
|
|
long templ = 0;
|
2011-10-10 19:28:59 +02:00
|
|
|
Encoding->GetValue().BeforeFirst('-').ToLong(&templ);
|
2007-04-17 01:41:06 +02:00
|
|
|
work->encoding = templ;
|
|
|
|
|
|
|
|
Angle->GetValue().ToDouble(&(work->angle));
|
|
|
|
Spacing->GetValue().ToDouble(&(work->spacing));
|
|
|
|
|
2011-10-10 19:28:59 +02:00
|
|
|
work->borderstyle = OutlineType->IsChecked() ? 3 : 1;
|
2007-04-17 01:41:06 +02:00
|
|
|
|
|
|
|
Shadow->GetValue().ToDouble(&(work->shadow_w));
|
|
|
|
Outline->GetValue().ToDouble(&(work->outline_w));
|
|
|
|
|
|
|
|
work->alignment = ControlToAlign(Alignment->GetSelection());
|
|
|
|
|
2012-10-10 16:04:44 +02:00
|
|
|
for (size_t i = 0; i < 3; ++i)
|
2011-10-10 19:28:59 +02:00
|
|
|
work->Margin[i] = margin[i]->GetValue();
|
2007-04-17 01:41:06 +02:00
|
|
|
|
2007-05-21 07:38:28 +02:00
|
|
|
work->primary.a = colorAlpha[0]->GetValue();
|
|
|
|
work->secondary.a = colorAlpha[1]->GetValue();
|
|
|
|
work->outline.a = colorAlpha[2]->GetValue();
|
|
|
|
work->shadow.a = colorAlpha[3]->GetValue();
|
2007-04-17 01:41:06 +02:00
|
|
|
|
|
|
|
work->bold = BoxBold->IsChecked();
|
|
|
|
work->italic = BoxItalic->IsChecked();
|
|
|
|
work->underline = BoxUnderline->IsChecked();
|
|
|
|
work->strikeout = BoxStrikeout->IsChecked();
|
|
|
|
}
|
|
|
|
|
2012-03-25 06:05:06 +02:00
|
|
|
/// @brief Sets color for one of the four color buttons
|
2011-10-10 19:28:59 +02:00
|
|
|
/// @param n Colour to set
|
2012-10-26 16:09:14 +02:00
|
|
|
void DialogStyleEditor::OnSetColor(int n, wxCommandEvent& evt) {
|
2011-10-10 19:29:17 +02:00
|
|
|
ColourButton *btn = static_cast<ColourButton*>(evt.GetClientData());
|
|
|
|
if (!btn) {
|
|
|
|
evt.Skip();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2006-01-16 22:02:54 +01:00
|
|
|
switch (n) {
|
2012-10-26 16:09:14 +02:00
|
|
|
case 1: work->primary = btn->GetColor(); break;
|
|
|
|
case 2: work->secondary = btn->GetColor(); break;
|
|
|
|
case 3: work->outline = btn->GetColor(); break;
|
|
|
|
case 4: work->shadow = btn->GetColor(); break;
|
2011-10-10 19:28:59 +02:00
|
|
|
default: throw agi::InternalError("attempted setting colour id outside range", 0);
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
2011-10-10 19:29:17 +02:00
|
|
|
if (SubsPreview)
|
|
|
|
SubsPreview->SetStyle(*work);
|
2007-04-17 01:41:06 +02:00
|
|
|
}
|
|
|
|
|
2012-10-26 16:09:14 +02:00
|
|
|
void DialogStyleEditor::OnChildFocus(wxChildFocusEvent &event) {
|
2007-04-17 01:41:06 +02:00
|
|
|
UpdateWorkStyle();
|
2011-10-10 19:28:59 +02:00
|
|
|
if (SubsPreview)
|
|
|
|
SubsPreview->SetStyle(*work);
|
2007-04-17 01:41:06 +02:00
|
|
|
event.Skip();
|
|
|
|
}
|
|
|
|
|
|
|
|
void DialogStyleEditor::OnPreviewTextChange (wxCommandEvent &event) {
|
2011-10-10 19:28:59 +02:00
|
|
|
SubsPreview->SetText(PreviewText->GetValue());
|
|
|
|
event.Skip();
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
|
|
|
|
2012-03-25 06:05:06 +02:00
|
|
|
/// @brief Change colour of preview's background
|
2011-10-10 19:29:17 +02:00
|
|
|
void DialogStyleEditor::OnPreviewColourChange (wxCommandEvent &evt) {
|
|
|
|
ColourButton *btn = static_cast<ColourButton*>(evt.GetClientData());
|
|
|
|
if (!btn)
|
|
|
|
evt.Skip();
|
|
|
|
else {
|
2012-10-26 16:09:14 +02:00
|
|
|
SubsPreview->SetColour(btn->GetColor());
|
|
|
|
OPT_SET("Colour/Style Editor/Background/Preview")->SetColor(btn->GetColor());
|
2011-10-10 19:29:17 +02:00
|
|
|
}
|
2007-05-21 06:53:14 +02:00
|
|
|
}
|
|
|
|
|
2012-03-25 06:05:06 +02:00
|
|
|
/// @brief Command event to update preview
|
2007-04-17 01:59:38 +02:00
|
|
|
void DialogStyleEditor::OnCommandPreviewUpdate (wxCommandEvent &event) {
|
2007-05-22 07:53:08 +02:00
|
|
|
if (!IsShownOnScreen()) return;
|
2007-04-17 01:59:38 +02:00
|
|
|
UpdateWorkStyle();
|
2011-10-10 19:28:59 +02:00
|
|
|
SubsPreview->SetStyle(*work);
|
2007-04-17 01:59:38 +02:00
|
|
|
event.Skip();
|
|
|
|
}
|
|
|
|
|
2012-03-25 06:05:06 +02:00
|
|
|
/// @brief Converts control value to alignment
|
2006-01-16 22:02:54 +01:00
|
|
|
int DialogStyleEditor::ControlToAlign (int n) {
|
|
|
|
switch (n) {
|
|
|
|
case 0: return 7;
|
|
|
|
case 1: return 8;
|
|
|
|
case 2: return 9;
|
|
|
|
case 3: return 4;
|
|
|
|
case 4: return 5;
|
|
|
|
case 5: return 6;
|
|
|
|
case 6: return 1;
|
|
|
|
case 7: return 2;
|
|
|
|
case 8: return 3;
|
|
|
|
default: return 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-25 06:05:06 +02:00
|
|
|
/// @brief Converts alignment value to control
|
2006-01-16 22:02:54 +01:00
|
|
|
int DialogStyleEditor::AlignToControl (int n) {
|
|
|
|
switch (n) {
|
|
|
|
case 7: return 0;
|
|
|
|
case 8: return 1;
|
|
|
|
case 9: return 2;
|
|
|
|
case 4: return 3;
|
|
|
|
case 5: return 4;
|
|
|
|
case 6: return 5;
|
|
|
|
case 1: return 6;
|
|
|
|
case 2: return 7;
|
|
|
|
case 3: return 8;
|
|
|
|
default: return 7;
|
|
|
|
}
|
|
|
|
}
|