Work on ASSA set/get pos - thx Leon :)

This commit is contained in:
niksedk 2021-06-22 11:12:48 +02:00
parent c4fce564d7
commit 49dc8c9053
17 changed files with 908 additions and 77 deletions

View File

@ -4,6 +4,8 @@
* NEW:
* Keep ASSA override tags (no html for italic/font etc.)
* ASSA override tag helper (shortcut + custom templates)
* ASSA set/get position
* ASSA plugin support
* Shortcuts for video contrast/brightness (mpv only)
* Waveform "Right-click + Ctrl" will toggle select of a subtitle
* Waveform "Right-click + Shift" will select a range of subtitles
@ -27,6 +29,7 @@
* Installer: Use ngen64 on 64-bit - thx XhmikosR
* Keep selected line (nearest) after "Remove text for HI" - thx Atlantis
* Improve FPC compatibility + PAC refactor - thx ngaullier
* Improve auto br / French regarding "space-punctuation" - thx Norbert
* FIXED:
* Fix MergeLinesShorterThan saving/loading - thx uckthis/OmrSi
* Fix load/save some ASSA storage style settings - thx Andrebavila

View File

@ -2024,6 +2024,7 @@ can edit in same subtitle file (collaboration)</Information>
<RemoveBlankLinesWhenOpening>Remove blank lines when opening a subtitle</RemoveBlankLinesWhenOpening>
<RemoveBlankLines>Remove blank lines</RemoveBlankLines>
<ApplyAssaOverrideTags>Apply ASSA override tags to selection</ApplyAssaOverrideTags>
<SetAssaPosition>Set/get ASSA position</SetAssaPosition>
<ShowLineBreaksAs>Show line breaks in list view as</ShowLineBreaksAs>
<SaveAsFileNameFrom>"Save as..." uses file name from</SaveAsFileNameFrom>
<MainListViewDoubleClickAction>Double-clicking line in main window list view will</MainListViewDoubleClickAction>

View File

@ -328,6 +328,7 @@ namespace Nikse.SubtitleEdit.Core.Common
public string ColumnPasteColumn { get; set; }
public string ColumnPasteOverwriteMode { get; set; }
public string AssaAttachmentFontTextPreview { get; set; }
public string AssaSetPositionTarget { get; set; }
public string VisualSyncStartSize { get; set; }
public ToolsSettings()
@ -2042,6 +2043,7 @@ $HorzAlign = Center
public string MainListViewGoToNextError { get; set; }
public string MainListViewRemoveBlankLines { get; set; }
public string ApplyAssaOverrideTags { get; set; }
public string SetAssaPosition { get; set; }
public string MainListViewRemoveTimeCodes { get; set; }
public string MainTextBoxSplitAtCursor { get; set; }
public string MainTextBoxSplitAtCursorAndVideoPos { get; set; }
@ -5080,6 +5082,12 @@ $HorzAlign = Center
settings.Tools.AssaAttachmentFontTextPreview = subNode.InnerText;
}
subNode = node.SelectSingleNode("AssaSetPositionTarget");
if (subNode != null)
{
settings.Tools.AssaSetPositionTarget = subNode.InnerText;
}
subNode = node.SelectSingleNode("VisualSyncStartSize");
if (subNode != null)
{
@ -7554,7 +7562,13 @@ $HorzAlign = Center
if (subNode != null)
{
shortcuts.ApplyAssaOverrideTags = subNode.InnerText;
}
}
subNode = node.SelectSingleNode("SetAssaPosition");
if (subNode != null)
{
shortcuts.SetAssaPosition = subNode.InnerText;
}
subNode = node.SelectSingleNode("MainListViewRemoveTimeCodes");
if (subNode != null)
@ -8697,6 +8711,7 @@ $HorzAlign = Center
textWriter.WriteElementString("ColumnPasteColumn", settings.Tools.ColumnPasteColumn);
textWriter.WriteElementString("ColumnPasteOverwriteMode", settings.Tools.ColumnPasteOverwriteMode);
textWriter.WriteElementString("AssaAttachmentFontTextPreview", settings.Tools.AssaAttachmentFontTextPreview);
textWriter.WriteElementString("AssaSetPositionTarget", settings.Tools.AssaSetPositionTarget);
textWriter.WriteElementString("VisualSyncStartSize", settings.Tools.VisualSyncStartSize);
if (settings.Tools.FindHistory != null && settings.Tools.FindHistory.Count > 0)
@ -9198,6 +9213,7 @@ $HorzAlign = Center
textWriter.WriteElementString("MainListViewGoToNextError", shortcuts.MainListViewGoToNextError);
textWriter.WriteElementString("MainListViewRemoveBlankLines", shortcuts.MainListViewRemoveBlankLines);
textWriter.WriteElementString("ApplyAssaOverrideTags", shortcuts.ApplyAssaOverrideTags);
textWriter.WriteElementString("SetAssaPosition", shortcuts.SetAssaPosition);
textWriter.WriteElementString("MainListViewRemoveTimeCodes", shortcuts.MainListViewRemoveTimeCodes);
textWriter.WriteElementString("MainEditFixRTLViaUnicodeChars", shortcuts.MainEditFixRTLViaUnicodeChars);
textWriter.WriteElementString("MainEditRemoveRTLUnicodeChars", shortcuts.MainEditRemoveRTLUnicodeChars);

View File

@ -699,7 +699,7 @@ Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text"
}
}
public static string GetTag(string tagName, string section, string header)
public static string GetTagFromHeader(string tagName, string section, string header)
{
var sectionOn = false;
foreach (var line in header.SplitToLines())

View File

@ -1,5 +1,4 @@
using Nikse.SubtitleEdit.Core;
using Nikse.SubtitleEdit.Core.Common;
using Nikse.SubtitleEdit.Core.Common;
using Nikse.SubtitleEdit.Logic;
using System;
using System.Collections.Generic;
@ -102,9 +101,9 @@ namespace Nikse.SubtitleEdit.Controls
public Paragraph Paragraph { get; set; }
}
private List<SyntaxColorLineParamter> _syntaxColorList = new List<SyntaxColorLineParamter>();
private object _syntaxColorListLock = new object();
private Timer _syntaxColorLineTimer = null;
private readonly List<SyntaxColorLineParamter> _syntaxColorList = new List<SyntaxColorLineParamter>();
private static readonly object SyntaxColorListLock = new object();
private readonly Timer _syntaxColorLineTimer;
public int FirstVisibleIndex { get; set; } = -1;
@ -1292,12 +1291,13 @@ namespace Nikse.SubtitleEdit.Controls
private void SyntaxColorLineTimerTick(object sender, EventArgs e)
{
var hashSet = new HashSet<int>();
lock (_syntaxColorListLock)
lock (SyntaxColorListLock)
{
_syntaxColorLineTimer.Stop();
for (int i = _syntaxColorList.Count - 1; i >= 0; i--)
{
SyntaxColorLineParamter item = _syntaxColorList[i];
var item = _syntaxColorList[i];
if (!hashSet.Contains(item.Index))
{
if (IsValidIndex(item.Index))
@ -1307,6 +1307,7 @@ namespace Nikse.SubtitleEdit.Controls
hashSet.Add(item.Index);
}
}
_syntaxColorList.Clear();
}
}
@ -1320,10 +1321,10 @@ namespace Nikse.SubtitleEdit.Controls
return;
}
lock (_syntaxColorListLock)
lock (SyntaxColorListLock)
{
_syntaxColorList.Add(new SyntaxColorLineParamter { Index = i, Paragraphs = paragraphs, Paragraph = paragraph });
_syntaxColorLineTimer.Stop();
_syntaxColorList.Add(new SyntaxColorLineParamter { Index = i, Paragraphs = paragraphs, Paragraph = paragraph });
_syntaxColorLineTimer.Start();
}
}

235
src/ui/Forms/Assa/SetPosition.Designer.cs generated Normal file
View File

@ -0,0 +1,235 @@

namespace Nikse.SubtitleEdit.Forms.Assa
{
sealed partial class SetPosition
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.radioButtonClipboard = new System.Windows.Forms.RadioButton();
this.radioButtonSelectedLines = new System.Windows.Forms.RadioButton();
this.groupBoxPreview = new System.Windows.Forms.GroupBox();
this.pictureBoxPreview = new System.Windows.Forms.PictureBox();
this.buttonOK = new System.Windows.Forms.Button();
this.buttonCancel = new System.Windows.Forms.Button();
this.timer1 = new System.Windows.Forms.Timer(this.components);
this.labelInfo = new System.Windows.Forms.Label();
this.labelCurrentPosition = new System.Windows.Forms.Label();
this.labelStyleAlignment = new System.Windows.Forms.Label();
this.labelVideoResolution = new System.Windows.Forms.Label();
this.labelCurrentTextPosition = new System.Windows.Forms.Label();
this.groupBox1.SuspendLayout();
this.groupBoxPreview.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pictureBoxPreview)).BeginInit();
this.SuspendLayout();
//
// groupBox1
//
this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.groupBox1.Controls.Add(this.radioButtonClipboard);
this.groupBox1.Controls.Add(this.radioButtonSelectedLines);
this.groupBox1.Location = new System.Drawing.Point(715, 12);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(246, 75);
this.groupBox1.TabIndex = 1;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Apply to";
//
// radioButtonClipboard
//
this.radioButtonClipboard.AutoSize = true;
this.radioButtonClipboard.Location = new System.Drawing.Point(7, 44);
this.radioButtonClipboard.Name = "radioButtonClipboard";
this.radioButtonClipboard.Size = new System.Drawing.Size(69, 17);
this.radioButtonClipboard.TabIndex = 1;
this.radioButtonClipboard.TabStop = true;
this.radioButtonClipboard.Text = "Clipboard";
this.radioButtonClipboard.UseVisualStyleBackColor = true;
//
// radioButtonSelectedLines
//
this.radioButtonSelectedLines.AutoSize = true;
this.radioButtonSelectedLines.Location = new System.Drawing.Point(7, 20);
this.radioButtonSelectedLines.Name = "radioButtonSelectedLines";
this.radioButtonSelectedLines.Size = new System.Drawing.Size(102, 17);
this.radioButtonSelectedLines.TabIndex = 0;
this.radioButtonSelectedLines.TabStop = true;
this.radioButtonSelectedLines.Text = "Selected lines: x";
this.radioButtonSelectedLines.UseVisualStyleBackColor = true;
//
// groupBoxPreview
//
this.groupBoxPreview.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.groupBoxPreview.Controls.Add(this.pictureBoxPreview);
this.groupBoxPreview.Location = new System.Drawing.Point(12, 105);
this.groupBoxPreview.Name = "groupBoxPreview";
this.groupBoxPreview.Size = new System.Drawing.Size(949, 589);
this.groupBoxPreview.TabIndex = 2;
this.groupBoxPreview.TabStop = false;
this.groupBoxPreview.Text = "Preview";
//
// pictureBoxPreview
//
this.pictureBoxPreview.Dock = System.Windows.Forms.DockStyle.Fill;
this.pictureBoxPreview.Location = new System.Drawing.Point(3, 16);
this.pictureBoxPreview.Name = "pictureBoxPreview";
this.pictureBoxPreview.Size = new System.Drawing.Size(943, 570);
this.pictureBoxPreview.TabIndex = 0;
this.pictureBoxPreview.TabStop = false;
this.pictureBoxPreview.Click += new System.EventHandler(this.pictureBoxPreview_Click);
this.pictureBoxPreview.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pictureBoxPreview_MouseMove);
//
// buttonOK
//
this.buttonOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.buttonOK.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.buttonOK.Location = new System.Drawing.Point(805, 699);
this.buttonOK.Name = "buttonOK";
this.buttonOK.Size = new System.Drawing.Size(75, 23);
this.buttonOK.TabIndex = 4;
this.buttonOK.Text = "&OK";
this.buttonOK.UseVisualStyleBackColor = true;
this.buttonOK.Click += new System.EventHandler(this.buttonOK_Click);
//
// buttonCancel
//
this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.buttonCancel.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.buttonCancel.Location = new System.Drawing.Point(886, 699);
this.buttonCancel.Name = "buttonCancel";
this.buttonCancel.Size = new System.Drawing.Size(75, 23);
this.buttonCancel.TabIndex = 5;
this.buttonCancel.Text = "C&ancel";
this.buttonCancel.UseVisualStyleBackColor = true;
this.buttonCancel.Click += new System.EventHandler(this.buttonCancel_Click);
//
// timer1
//
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
//
// labelInfo
//
this.labelInfo.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.labelInfo.AutoSize = true;
this.labelInfo.Location = new System.Drawing.Point(12, 704);
this.labelInfo.Name = "labelInfo";
this.labelInfo.Size = new System.Drawing.Size(205, 13);
this.labelInfo.TabIndex = 6;
this.labelInfo.Text = "Click on video to toggle set/move position";
//
// labelCurrentPosition
//
this.labelCurrentPosition.AutoSize = true;
this.labelCurrentPosition.Location = new System.Drawing.Point(12, 54);
this.labelCurrentPosition.Name = "labelCurrentPosition";
this.labelCurrentPosition.Size = new System.Drawing.Size(117, 13);
this.labelCurrentPosition.TabIndex = 7;
this.labelCurrentPosition.Text = "Current mouse position:";
//
// labelStyleAlignment
//
this.labelStyleAlignment.AutoSize = true;
this.labelStyleAlignment.Location = new System.Drawing.Point(12, 32);
this.labelStyleAlignment.Name = "labelStyleAlignment";
this.labelStyleAlignment.Size = new System.Drawing.Size(81, 13);
this.labelStyleAlignment.TabIndex = 8;
this.labelStyleAlignment.Text = "Style alignment:";
//
// labelVideoResolution
//
this.labelVideoResolution.AutoSize = true;
this.labelVideoResolution.Location = new System.Drawing.Point(12, 11);
this.labelVideoResolution.Name = "labelVideoResolution";
this.labelVideoResolution.Size = new System.Drawing.Size(85, 13);
this.labelVideoResolution.TabIndex = 9;
this.labelVideoResolution.Text = "Video resolution:";
//
// labelCurrentTextPosition
//
this.labelCurrentTextPosition.AutoSize = true;
this.labelCurrentTextPosition.Location = new System.Drawing.Point(12, 75);
this.labelCurrentTextPosition.Name = "labelCurrentTextPosition";
this.labelCurrentTextPosition.Size = new System.Drawing.Size(103, 13);
this.labelCurrentTextPosition.TabIndex = 10;
this.labelCurrentTextPosition.Text = "Current text position:";
//
// SetPosition
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(973, 734);
this.Controls.Add(this.labelCurrentTextPosition);
this.Controls.Add(this.labelVideoResolution);
this.Controls.Add(this.labelStyleAlignment);
this.Controls.Add(this.labelCurrentPosition);
this.Controls.Add(this.labelInfo);
this.Controls.Add(this.buttonOK);
this.Controls.Add(this.buttonCancel);
this.Controls.Add(this.groupBoxPreview);
this.Controls.Add(this.groupBox1);
this.KeyPreview = true;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.MinimumSize = new System.Drawing.Size(720, 545);
this.Name = "SetPosition";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Set position";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.ApplyCustomStyles_FormClosing);
this.Shown += new System.EventHandler(this.SetPosition_Shown);
this.ResizeEnd += new System.EventHandler(this.SetPosition_ResizeEnd);
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.ApplyCustomStyles_KeyDown);
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.groupBoxPreview.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.pictureBoxPreview)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.GroupBox groupBoxPreview;
private System.Windows.Forms.Button buttonOK;
private System.Windows.Forms.Button buttonCancel;
private System.Windows.Forms.RadioButton radioButtonClipboard;
private System.Windows.Forms.RadioButton radioButtonSelectedLines;
private System.Windows.Forms.PictureBox pictureBoxPreview;
private System.Windows.Forms.Timer timer1;
private System.Windows.Forms.Label labelInfo;
private System.Windows.Forms.Label labelCurrentPosition;
private System.Windows.Forms.Label labelStyleAlignment;
private System.Windows.Forms.Label labelVideoResolution;
private System.Windows.Forms.Label labelCurrentTextPosition;
}
}

View File

@ -0,0 +1,364 @@
using Nikse.SubtitleEdit.Core.Common;
using Nikse.SubtitleEdit.Core.SubtitleFormats;
using Nikse.SubtitleEdit.Logic;
using Nikse.SubtitleEdit.Logic.VideoPlayers;
using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace Nikse.SubtitleEdit.Forms.Assa
{
public sealed partial class SetPosition : Form
{
public Subtitle UpdatedSubtitle { get; private set; }
private readonly Subtitle _subtitle;
private readonly Subtitle _subtitleWithNewHeader;
private readonly int[] _selectedIndices;
private LibMpvDynamic _mpv;
private string _mpvTextFileName;
private bool _closing;
private bool _videoLoaded;
private int _x = -1;
private int _y = -1;
private int _tempX;
private int _tempY;
private bool _updatePos = true;
private readonly string _videoFileName;
private readonly VideoInfo _videoInfo;
private bool _positionChanged;
public SetPosition(Subtitle subtitle, int[] selectedIndices, string videoFileName, VideoInfo videoInfo)
{
UiUtil.PreInitialize(this);
InitializeComponent();
UiUtil.FixFonts(this);
_subtitle = subtitle;
_videoFileName = videoFileName;
_videoInfo = videoInfo;
_subtitleWithNewHeader = new Subtitle(_subtitle, false);
_selectedIndices = selectedIndices;
radioButtonSelectedLines.Checked = true;
Text = LanguageSettings.Current.AssaSetPosition.SetPosition;
radioButtonSelectedLines.Text = string.Format(LanguageSettings.Current.AssaOverrideTags.SelectedLinesX, _selectedIndices.Length);
radioButtonClipboard.Text = LanguageSettings.Current.AssaSetPosition.Clipboard;
labelInfo.Text = LanguageSettings.Current.AssaSetPosition.SetPosInfo;
groupBoxPreview.Text = LanguageSettings.Current.General.Preview;
buttonOK.Text = LanguageSettings.Current.General.Ok;
buttonCancel.Text = LanguageSettings.Current.General.Cancel;
UiUtil.FixLargeFonts(this, buttonOK);
if (_videoInfo == null)
{
_videoInfo = UiUtil.GetVideoInfo(_videoFileName);
}
labelVideoResolution.Text = string.Format(LanguageSettings.Current.AssaSetPosition.VideoResolutionX, $"{_videoInfo.Width}x{_videoInfo.Height}");
SetPosition_ResizeEnd(null, null);
if (Configuration.Settings.Tools.AssaSetPositionTarget == "Clipboard")
{
radioButtonClipboard.Checked = true;
}
else
{
radioButtonSelectedLines.Checked = true;
}
}
private void ApplyCustomStyles_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Escape)
{
DialogResult = DialogResult.Cancel;
}
else if (e.KeyCode == Keys.Enter)
{
buttonOK_Click(null, null);
}
else if (e.KeyData == UiUtil.HelpKeys)
{
UiUtil.OpenUrl("https://www.nikse.dk/SubtitleEdit/AssaOverrideTags#pos");
e.SuppressKeyPress = true;
}
}
private void buttonOK_Click(object sender, EventArgs e)
{
_subtitle.Header = _subtitleWithNewHeader.Header;
if (_positionChanged)
{
ApplyOverrideTags(_subtitle);
}
DialogResult = DialogResult.OK;
}
private void ApplyOverrideTags(Subtitle subtitle)
{
var styleToApply = $"{{\\pos({_x},{_y})}}";
if (radioButtonClipboard.Checked)
{
Clipboard.SetText(styleToApply);
return;
}
Configuration.Settings.SubtitleSettings.AssaOverrideTagHistory = Configuration.Settings.SubtitleSettings.AssaOverrideTagHistory
.Where(p => p != styleToApply)
.ToList();
Configuration.Settings.SubtitleSettings.AssaOverrideTagHistory.Insert(0, styleToApply);
if (Configuration.Settings.SubtitleSettings.AssaOverrideTagHistory.Count > 25)
{
Configuration.Settings.SubtitleSettings.AssaOverrideTagHistory.RemoveAt(Configuration.Settings.SubtitleSettings.AssaOverrideTagHistory.Count - 1);
}
UpdatedSubtitle = new Subtitle(subtitle, false);
var indices = GetIndices(subtitle);
for (int i = 0; i < UpdatedSubtitle.Paragraphs.Count; i++)
{
if (!indices.Contains(i))
{
continue;
}
var p = UpdatedSubtitle.Paragraphs[i];
// remove old position tags
p.Text = Regex.Replace(p.Text, @"{\\pos(.*)}", string.Empty);
p.Text = Regex.Replace(p.Text, @"\\pos(.*)", string.Empty);
if (p.Text.StartsWith("{\\", StringComparison.Ordinal) && styleToApply.EndsWith('}'))
{
p.Text = styleToApply.TrimEnd('}') + p.Text.Remove(0, 1);
}
else
{
p.Text = styleToApply + p.Text;
}
}
}
private int[] GetIndices(Subtitle subtitle)
{
return _selectedIndices;
}
private void buttonCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
}
private bool GeneratePreviewViaMpv()
{
var fileName = _videoFileName; // Path.Combine(Configuration.DataDirectory, "preview.mp4");
if (!File.Exists(fileName))
{
var isFfmpegAvailable = !Configuration.IsRunningOnWindows || !string.IsNullOrEmpty(Configuration.Settings.General.FFmpegLocation) && File.Exists(Configuration.Settings.General.FFmpegLocation);
if (!isFfmpegAvailable)
{
return false;
}
using (var p = GetFFmpegProcess(fileName))
{
p.Start();
p.WaitForExit();
}
}
if (!LibMpvDynamic.IsInstalled)
{
return false;
}
if (_mpv == null)
{
_mpv = new LibMpvDynamic();
_mpv.Initialize(pictureBoxPreview, fileName, VideoLoaded, null);
}
else
{
VideoLoaded(null, null);
}
return true;
}
public static Process GetFFmpegProcess(string outputFileName)
{
var ffmpegLocation = Configuration.Settings.General.FFmpegLocation;
if (!Configuration.IsRunningOnWindows && (string.IsNullOrEmpty(ffmpegLocation) || !File.Exists(ffmpegLocation)))
{
ffmpegLocation = "ffmpeg";
}
return new Process
{
StartInfo =
{
FileName = ffmpegLocation,
Arguments = $"-t 1 -f lavfi -i color=c=blue:s=720x480 -c:v libx264 -tune stillimage -pix_fmt yuv420p \"{outputFileName}\"",
UseShellExecute = false,
CreateNoWindow = true
}
};
}
private void VideoLoaded(object sender, EventArgs e)
{
var format = new AdvancedSubStationAlpha();
var subtitle = new Subtitle();
var indices = GetIndices(subtitle);
var styleToApply = $"{{\\pos({_x},{_y})}}";
var p = indices.Length > 0 ?
new Paragraph(_subtitleWithNewHeader.Paragraphs[indices[0]]) :
new Paragraph(Configuration.Settings.General.PreviewAssaText, 0, 1000);
// remove old position tags
p.Text = Regex.Replace(p.Text, @"{\\pos(.*)}", string.Empty);
p.Text = Regex.Replace(p.Text, @"\\pos(.*)", string.Empty);
// remove fade tags
p.Text = Regex.Replace(p.Text, @"{\\fad(.*)}", string.Empty);
p.Text = Regex.Replace(p.Text, @"\\fade(.*)", string.Empty);
p.Text = styleToApply + p.Text;
subtitle.Paragraphs.Add(p);
subtitle.Header = _subtitleWithNewHeader.Header ?? AdvancedSubStationAlpha.DefaultHeader;
var text = subtitle.ToText(format);
_mpvTextFileName = FileUtil.GetTempFileName(format.Extension);
File.WriteAllText(_mpvTextFileName, text);
_mpv.LoadSubtitle(_mpvTextFileName);
if (!_videoLoaded)
{
Application.DoEvents();
_mpv.Pause();
_mpv.CurrentPosition = p.StartTime.TotalSeconds + 0.05;
Application.DoEvents();
_videoLoaded = true;
timer1.Start();
}
}
private void ApplyCustomStyles_FormClosing(object sender, FormClosingEventArgs e)
{
_closing = true;
Application.DoEvents();
Configuration.Settings.Tools.AssaSetPositionTarget = radioButtonClipboard.Checked ? "Clipboard" : "SelectedLines";
_mpv?.Dispose();
}
private void timer1_Tick(object sender, EventArgs e)
{
if (_mpv == null || _closing)
{
return;
}
if (_updatePos && (_x != _tempX || _y != _tempY))
{
_x = _tempX;
_y = _tempY;
VideoLoaded(null, null);
}
}
private void SetPosition_Shown(object sender, EventArgs e)
{
ShowStyleAlignment();
ShowCurrentPosition();
var playResX = AdvancedSubStationAlpha.GetTagFromHeader("PlayResX", "[Script Info]", _subtitleWithNewHeader.Header);
var playResY = AdvancedSubStationAlpha.GetTagFromHeader("PlayResY", "[Script Info]", _subtitleWithNewHeader.Header);
if (string.IsNullOrEmpty(playResX) || string.IsNullOrEmpty(playResY))
{
var dialogResult = MessageBox.Show("PlayResX/PlayResY are not set - set the resolution now?", "Subtitle Edit", MessageBoxButtons.YesNoCancel);
if (dialogResult == DialogResult.OK || dialogResult == DialogResult.Yes)
{
_subtitleWithNewHeader.Header = AdvancedSubStationAlpha.AddTagToHeader("PlayResX", "PlayResX: " + _videoInfo.Width.ToString(CultureInfo.InvariantCulture), "[Script Info]", _subtitleWithNewHeader.Header);
_subtitleWithNewHeader.Header = AdvancedSubStationAlpha.AddTagToHeader("PlayResY", "PlayResY: " + _videoInfo.Height.ToString(CultureInfo.InvariantCulture), "[Script Info]", _subtitleWithNewHeader.Header);
}
}
GeneratePreviewViaMpv();
}
private void ShowCurrentPosition()
{
var indices = GetIndices(_subtitle);
if (indices.Length == 0)
{
return;
}
var p = _subtitleWithNewHeader.Paragraphs[indices[0]];
var match = Regex.Match(p.Text, @"\\pos(.*)");
if (match.Success)
{
var arr = match.Value.Split('(', ')', ',');
if (arr.Length > 2)
{
if (int.TryParse(arr[1], out var x) && int.TryParse(arr[2], out var y))
{
_x = x;
_y = y;
_updatePos = false;
labelCurrentTextPosition.Text = string.Format(LanguageSettings.Current.AssaSetPosition.CurrentTextPositionX, $"{_x},{_y}");
}
}
}
}
private void ShowStyleAlignment()
{
var indices = GetIndices(_subtitle);
if (indices.Length == 0)
{
labelStyleAlignment.Text = string.Format(LanguageSettings.Current.AssaSetPosition.StyleAlignmentX, "{\\an2}");
return;
}
var p = _subtitleWithNewHeader.Paragraphs[indices[0]];
var style = AdvancedSubStationAlpha.GetSsaStyle(p.Extra, _subtitleWithNewHeader.Header);
labelStyleAlignment.Text = string.Format(LanguageSettings.Current.AssaSetPosition.StyleAlignmentX, "{\\an" + style.Alignment + "} (" + p.Extra + ")");
}
private void pictureBoxPreview_Click(object sender, EventArgs e)
{
_x = _tempX;
_y = _tempY;
labelCurrentTextPosition.Text = string.Format(LanguageSettings.Current.AssaSetPosition.CurrentTextPositionX, $"{_x},{_y}");
_updatePos = !_updatePos;
VideoLoaded(null, null);
_positionChanged = true;
}
private void pictureBoxPreview_MouseMove(object sender, MouseEventArgs e)
{
var xAspectRatio = (double)_videoInfo.Width / pictureBoxPreview.Width;
_tempX = (int)Math.Round(e.Location.X * xAspectRatio);
var yAspectRatio = (double)_videoInfo.Height / pictureBoxPreview.Height;
_tempY = (int)Math.Round(e.Location.Y * yAspectRatio);
labelCurrentPosition.Text = string.Format(LanguageSettings.Current.AssaSetPosition.CurrentMousePositionX, $"{_tempX},{_tempY}");
}
private void SetPosition_ResizeEnd(object sender, EventArgs e)
{
var aspectRatio = (double)_videoInfo.Width / _videoInfo.Height;
var newWidth = pictureBoxPreview.Height * aspectRatio;
Width += (int)(newWidth - pictureBoxPreview.Width);
}
}
}

View File

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="timer1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

View File

@ -181,10 +181,10 @@ namespace Nikse.SubtitleEdit.Forms
{
if (format.Name == AdvancedSubStationAlpha.NameOfFormat && header != null)
{
var oldPlayResX = AdvancedSubStationAlpha.GetTag("PlayResX", "[Script Info]", header);
var oldPlayResY = AdvancedSubStationAlpha.GetTag("PlayResY", "[Script Info]", header);
var newPlayResX = AdvancedSubStationAlpha.GetTag("PlayResX", "[Script Info]", sub.Header);
var newPlayResY = AdvancedSubStationAlpha.GetTag("PlayResY", "[Script Info]", sub.Header);
var oldPlayResX = AdvancedSubStationAlpha.GetTagFromHeader("PlayResX", "[Script Info]", header);
var oldPlayResY = AdvancedSubStationAlpha.GetTagFromHeader("PlayResY", "[Script Info]", header);
var newPlayResX = AdvancedSubStationAlpha.GetTagFromHeader("PlayResX", "[Script Info]", sub.Header);
var newPlayResY = AdvancedSubStationAlpha.GetTagFromHeader("PlayResY", "[Script Info]", sub.Header);
var stylesInHeader = AdvancedSubStationAlpha.GetStylesFromHeader(header);
var styles = new List<SsaStyle>();

View File

@ -273,6 +273,7 @@ namespace Nikse.SubtitleEdit.Forms
this.setActorForSelectedLinesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItemAssaOverrideTags = new System.Windows.Forms.ToolStripMenuItem();
this.applyCustomStylesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.setPositionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItemAssStyles = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparatorAssa = new System.Windows.Forms.ToolStripSeparator();
this.toolStripMenuItemSetRegion = new System.Windows.Forms.ToolStripMenuItem();
@ -2583,7 +2584,8 @@ namespace Nikse.SubtitleEdit.Forms
// toolStripMenuItemAssaOverrideTags
//
this.toolStripMenuItemAssaOverrideTags.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.applyCustomStylesToolStripMenuItem});
this.applyCustomStylesToolStripMenuItem,
this.setPositionToolStripMenuItem});
this.toolStripMenuItemAssaOverrideTags.Name = "toolStripMenuItemAssaOverrideTags";
this.toolStripMenuItemAssaOverrideTags.Size = new System.Drawing.Size(284, 22);
this.toolStripMenuItemAssaOverrideTags.Text = "Set override tags";
@ -2595,6 +2597,13 @@ namespace Nikse.SubtitleEdit.Forms
this.applyCustomStylesToolStripMenuItem.Text = "Apply custom tags...";
this.applyCustomStylesToolStripMenuItem.Click += new System.EventHandler(this.applyCustomStylesToolStripMenuItem_Click);
//
// setPositionToolStripMenuItem
//
this.setPositionToolStripMenuItem.Name = "setPositionToolStripMenuItem";
this.setPositionToolStripMenuItem.Size = new System.Drawing.Size(182, 22);
this.setPositionToolStripMenuItem.Text = "Set position...";
this.setPositionToolStripMenuItem.Click += new System.EventHandler(this.setPositionToolStripMenuItem_Click);
//
// toolStripMenuItemAssStyles
//
this.toolStripMenuItemAssStyles.Name = "toolStripMenuItemAssStyles";
@ -5998,5 +6007,6 @@ namespace Nikse.SubtitleEdit.Forms
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItemInsertBefore;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItemInsertSubtitle;
private System.Windows.Forms.ToolStripMenuItem applyCustomStylesToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem setPositionToolStripMenuItem;
}
}

View File

@ -1283,6 +1283,24 @@ namespace Nikse.SubtitleEdit.Forms
MovePrevNext(e, beforeParagraph, index);
SubtitleListview1.SyntaxColorLineBackground(_subtitle.Paragraphs, index, paragraph);
if (e.MouseDownParagraphType == AudioVisualizer.MouseDownParagraphType.End)
{
var next = _subtitle.GetParagraphOrDefault(index + 1);
if (next != null)
{
SubtitleListview1.SyntaxColorLineBackground(_subtitle.Paragraphs, index + 1, next);
}
}
if (e.MouseDownParagraphType == AudioVisualizer.MouseDownParagraphType.Start)
{
var prev = _subtitle.GetParagraphOrDefault(index - 1);
if (prev != null)
{
SubtitleListview1.SyntaxColorLineBackground(_subtitle.Paragraphs, index - 1, prev);
}
}
if (_subtitleOriginal != null)
{
@ -22610,6 +22628,7 @@ namespace Nikse.SubtitleEdit.Forms
toolStripMenuItemReverseRightToLeftStartEnd.ShortcutKeys = UiUtil.GetKeys(Configuration.Settings.Shortcuts.MainEditReverseStartAndEndingForRTL);
translateToolStripMenuItem.ShortcutKeys = UiUtil.GetKeys(Configuration.Settings.Shortcuts.MainAutoTranslate);
applyCustomStylesToolStripMenuItem.ShortcutKeys = UiUtil.GetKeys(Configuration.Settings.Shortcuts.ApplyAssaOverrideTags);
setPositionToolStripMenuItem.ShortcutKeys = UiUtil.GetKeys(Configuration.Settings.Shortcuts.SetAssaPosition);
audioVisualizer.InsertAtVideoPositionShortcut = UiUtil.GetKeys(Configuration.Settings.Shortcuts.MainWaveformInsertAtCurrentPosition);
audioVisualizer.Move100MsLeft = UiUtil.GetKeys(Configuration.Settings.Shortcuts.Waveform100MsLeft);
@ -31191,5 +31210,26 @@ namespace Nikse.SubtitleEdit.Forms
RestoreSubtitleListviewIndices();
}
}
private void setPositionToolStripMenuItem_Click(object sender, EventArgs e)
{
using (var form = new SetPosition(_subtitle, SubtitleListview1.GetSelectedIndices(), VideoFileName, _videoInfo))
{
if (form.ShowDialog(this) != DialogResult.OK)
{
return;
}
MakeHistoryForUndo(string.Format(_language.BeforeX, "Set position"));
if (form.UpdatedSubtitle != null)
{
SaveSubtitleListviewIndices();
_subtitle.Paragraphs.Clear();
_subtitle.Paragraphs.AddRange(form.UpdatedSubtitle.Paragraphs);
SubtitleListview1.Fill(_subtitle, _subtitleOriginal);
RestoreSubtitleListviewIndices();
}
}
}
}
}

View File

@ -464,75 +464,75 @@
<data name="toolStripButtonAssStyleManager.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAOgSURBVFhH7VddSBVBFN5+LC2oUKwMvTO7W2qSVEQQBEkQ
kRQEvVQIUQSieK87u1IIEbeniB56CIQKpKcy7y5aQgT1oPZWhBFFRBSVu/dGSfTQHxG5nVNHXWe07vXn
rQ8+LrvnmzkfZ2bPzNX+Yyq4v2f3Gd8W3VGmbdEeatockswePMYqk2vLh30rEaYdMZ5C7CTZ7ME1Yxc8
k4cD+/YqBgLHukWy2UFX5aqiKyb/ggZurl+nGGh3xHCmpaWK5DMPz2QnMPkIn9QdVExkHHGJ5DOLVFXV
gmsmz0QN3NmyWTGQdo5+zSQSxTRs5pAy+aFocuQ1s/RdYFuPZRNQhZM0bObg6XxANuCa7BRsvMOygcCy
3j5PJBbS0OkD1n67nBz47aqur8BEmFAxYTcfoeHTR8pgPRMYaKewFkDJZQPQmB5ReHro0PVySPYzmjxp
8uFOXa8miYabDjefbCIQYgdJpg7X4G3R5EhY+9sUHgVU4ZJiwLFuUnhq6CwtLfQM/lkxYLBakowCGxA2
oqiBdtuCZ6eSJLnDM1irmpw/nezQwVYcNYCEylygcG64uGlTnqvzQDYArCeJAjyMZAPPHPElaG0qIkn2
SOmxOjm5y9gQLEsBSRRgZQJbKI0JKnOCJNnDNfkD2cBlxn50mPzj39hbU/NdNdCUeZJMLqCp/w2P821y
8mzZtcYMXzc1jjOA9G3rEE3/b6R03j3R5Nny3u5dioG0ZQ3Q9H9H1+oyE8o/rvHkyhtVFaEvmhUTvp3Y
Tmkmh6uz88qksdh76AcPc+Hjg/sD2UDabu6hNBOjm7FlcOf7JBtwdX0PSbLGoG1Xy40JNujPwHHKSaIC
nB+Tk3tm2bOkps0lSU7whbgdNYD0LauNwuMB7uZDsjeKAZ01kiRnZFqsWtnAi4aGz1CdQpKMAY7cA0py
g3/oKSlZRJKcEYbhHN8RT2UT8K6VJGOA6/Y92QD0/dMUnjIyLaJeNhA48SCsr88jCa59bKuc3Csu/n69
omwVSaLAg2gyKoByF7yKx4dkE4OOqCPJ7813HO58va4R60sZsf5Og929qrOzEFoMXALENVsOLAGWAmNA
BuT0i8/4HuOoQ/1SII7Pf9kct3073g9nQh/clHqRcJk9BzEFuNuxNHjgjCReAcTJdSB+QvjHA29DG4Ab
6Ref8T3GDWAZcCUQT0GcB/cRngU5fU0jZcVB84BoDCdB4o03P0J8RmIMdfOBOA454dL8gab9Ah96TS1q
FTkBAAAAAElFTkSuQmCC
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAOhSURBVFhH7VdJaBRBFG2XuIKKIWokmaru1hiDoiKCIBgC
IoYEBC8qAVGEoGQmXd1BCYiMJxEPHgTBBfFklukm0UAQ4iHRmyIRUSSI4tI9IxrEg0YJYtr/9Uc7VVlm
stx88Bi6/6v6j1/Vv2q0/5gMHlZXnfNt0R5l2hbXQ02bRZKZg8dYaXJ9yZBvJcK0I0ZSiN0kmzm4Zuyy
Z/Kwd99exUDgWHdINjNoK12df9PkA2igc9MGxcA1RwxlGhrKSD798Ex2CpMP81nNQcVExhFXST69SJWV
zWsxeSZq4O72bYqBtHP0WyaRKKBh04eUyQ9FkyNbzKIPgW09lU1AFU7TsOmDp/Ne2YBrsjOw8Q7LBgLL
ev8ikZhPQ6cOWPsKOTnwe5Our8REmFAxYdcfoeFTR8pgHaMYuE5hLYCSywagMT2h8NTQrOslkOxnNHnS
5EOtur6RJBpuOtx8solAiF0kmTxcg1+KJkfC2ndR+C+gClcVA47VSeHJobWoaLln8K+KAYNVkuQvsAFh
I4oauGZb8OyUkiR3eAZrVJPz52MdOtiKowaQUJnLFM4NV7ZuzXN1HsgGgLUkUYCHkWygzxEDQWNdPkmy
R0qP1cjJXcb6YVkWkkQBViawhdKYoDKnSJI9XJM/kg3cYOxHs8k/j8fu8vJB1UBd5lkyOY+mnhge5zvl
5Nmyba0Zvqk7PsIA0retQzT9xEjpvH20ybPlg6o9ioG0ZfXS9OOjbU2xCeUf0Xhy5e2ydaEv6hUTvp2o
oDRjw9XZRWXSWOwj9IPHufDpwf2BbCBt13dQmtHRztgyuPN9kQ24ul5NkqzxzrY3yo0JNujPwHFKSKIC
nJ+Qk3tmcV9S02aTJCf4QnRFDSB9y7pE4ZEAd3Mh2VvFgM6OkyRnZBqsStnAy2PHvkJ1lpPkH+DIPaAk
N/injsLCRSTJGWEYzvId8Vw2Ae8aSfIPcN1+IBuAvn+WwpNGpkHUygYCJx6EtbV5JMG1j+2Qk3sFBYO3
1hWvJkkUeBCNRQVQ7oWv4/F+2cQ7R9SQ5PfmOwl3vm7XiPWkjNi9VoPdb9LZeQgtBi4B4pqtABYCi4Ax
IANy+sVnfI9x1KF+KRDHL3hVH7d9O34PzoQeuCl1I+EyewFiCnC3Y2nwwBlOvBKIk+tA/ITwjwfehjYD
t9AvPuN7jBvAYuAqIJ6COA/uIzwLcvqahsuKg+YA0RhOgsQb74II8RmJMdTNBeI45KhL8wea9gvZg00l
kkBKxwAAAABJRU5ErkJggg==
</value>
</data>
<data name="toolStripButtonAssProperties.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAQcSURBVFhH1VddTFNnGC6OqJtZYjSZGpWetiZEFxOzbEa2
GUAzE02MXnlhTJDEZcaknEPNxgWTZkuWceFmFhkGB8NfRFqBCApBwID8aORHa0UobaE9PS3QC7lY4oWO
b+9zeiCkO/3L6Y1P8uQ77/t93/s+33+rey/BGMuQQqGSx6Nj7ifPX0xJUugn8n2gVGtDKBTivD5/w8sJ
z8OYdHmf1rb0sEt3Otnl5m5W1dTFxibdo6ptFXqmxcZwOJytpIkNUZL+tlY3s5JKW1xeuNXOSOwF4s+V
9k7VNst57nIjgwglTWxQoya1ANEsv97KRFFsFoPBut9JjFqbaGImlDSxkawA8JcrLezXa62qdWpMSYDt
wSBr6xtOCxErZQHlNLLzN++nhYiVsgDs8vqOgbQQsVIWMOx0jc/Ozu5KBxErZQFDL12jikszEOv9FUBn
fcvMzEw1sRYMBoPnFr8TkdoeQgxNAijQUVy38JX91cTIlkvYiQgRiKFJAI3iixGHK9w76HzdR6SgQyhh
JyL1/RExNAlIBzQJwDNLR+lrenTyFHLLvvOo7kur1bpC7hwDmgRgI7X1j7Cr93pZXXsfczqd71DCBjsf
P2MQgbZ93+Q/kCwCq7EIC/7i4p3wAZoE0CgPN3Y/YRdtHayqsUvehChhgy29T9nc3NzeJoNhp3WbYcHz
3bcMIkSLUC0HJGgSIEnSR5T0BAk5SSMtIHsvStgg1R2nZVppN3E1RNa/Y8c7CJB4/k3o7NlPEEOTgGRQ
ZzBsoORvIODup9tLScBriAgU82Wod457Bkqr7jCXx3df7hAP0QJotLsmPN4uqAdpT9SgHHdPd1PdV2hj
N3JlSG43bZpvzs7+WBKE32QBPB9ymc2rqE+uGAjcoBnbjfZxobIHTmKt4Vt+EeGZpW+hVq9fbTNtnoEA
m5E7L/fheW6qoOBtZBaKCuFLGioCdr8Y9wzDHhqbHCXbjtLxyj1C3/sajPpCJCchb+0cp5eDECh5gyzA
wj9jOl2G4k6MVPYAAttNWc8hoN60ZZaWomKRXTl7OiAgIsKyX+mSGKkIsBmz9kfWXp0ThQWyAL/Atyhd
EiMlASauFYmonCLeiubgwQPtEPAwN/ffwPd84v8EwJIA56SXNtnRKB6hdefQ7jbHZVtN3IIi4JjcOQrM
as30WQRfZCn4PxV3fCwKqKCdj2c4mo8cznkSsYaSVkamequPRpipdP8fKPkPEOA+ffofup7XKe7Y8AcC
f9S19y/d9dHsdzjCDWfObKw3cq/q9XqxmttaQt3WE3HrbSRuUkrY60vzc/Reocg9bTb7pwXzKfLFPxF0
rWbSVOfQKJdevEXSr6O8np4eJPiQuJaIRDh6WF88Pp8RP1dK2PCjfgMR7dEPs5X8sUwSCBiLcaDT/QcQ
Avic8b5wSQAAAABJRU5ErkJggg==
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAQZSURBVFhH1VdbaBNZGI5aVt1lYVHwwlYzSYSiIoioWHel
VXHBBdEnH0SoBUUR4kwj2odqwwpiH7wgupVq3a661trEttiqpbaV1tYq9qIx1jZN0iaTSdrmQR8WfFB7
/L/JtJQ4uTF58YOPM/9/zvn/79wT3XcJxtgMKRQqfN7X737x+s2wJIX+It8spVobQqEQ5/X5q98Oep7E
pMv7sqK+jV2518yu1rWystoW1j/k7lNtq9AzItaEw+EsJU1siJL0j7W8jhWW2uLywp1GRmIvEE+V2ptV
20znyas1DCKUNLFBjWrVAkSz5FYDE0WxTgwGK8+TGLU20cRMKGliI1kB4Ol/69mZmw2qdWpMSYDtcRd7
1NGTFiJWygJKaGRnbz9MCxErZQHY5VVNz9JCxEpZQI/TNTA2NrY6HUSslAV0v3X1KS7NQKzvVwCd9czR
0dFyYgUYDAZPTn4nIrX9EzE0CaBAu3Ddwld8rZaRLZewExEiEEOTABrFul6HK9ze5XzfQaSg3ShhJyL1
PYEYmgSkA5oE4Jmlo/Q7PTq5Crlp37lUt9Fqtc6UO8eAJgHYSI86e9mNB+2ssrGDOZ3Ozyhhg83PXzGI
QNuObZsfSxaBXbMIE/6CglXwAZoE0Ch31LS+YJdsTayspkXehChhg/XtL9n4+PimWoNhlXWZYcJz8ACD
CNEilMsBCZoESJL0IyXdS0L20UjzyN6EEjZIdXtomX6wm7jrRNa5YsVnCJB4/mPo6NEFiKFJQDKoNBgW
UvKPEHB/5fIiEvAeIgIFfDHqnQOeZ0Vl95jL43sod4iHaAE02tWDHm8L1IO0J66jHHCPtFLdb2hjN3LF
SG43Lf5Ql5X1syQI52QBPB9ymc2zqU+OGAj8RzO2Hu3jQmUP7MNawzf9IsIzS99ChV4/x2b6dRQCbEbu
rNyH57nhvLxPkVk4kg9f0lARsP7NgKcHdnf/UB/ZdpSOd+5e+t5SbdTnIzkJ+WTnOL0chEDJq2UBFv4V
0+lmKO7ESGUPILDdtPQ1BFSZMsdoKS5PsiV7QxMERERYtipdEiMVATbj0q2RtVfnYH6eLMAv8PVKl8RI
SYCJa0AiKoeJd6LZtf2PRgh4kpPzJXCMT/yfAJgS4Bzy0ibbFcWdtO4c2t3luCyriZtQBOyWO0eBWa0Z
PovgiywF/7fijo9JAZdp5+MZjuZTh/MDifiJkpZGpnqJj0aYoXT/BpT8OAS4Dx36n67neYo7NvyBwMXK
xs6puz6anQ5HuPrw4UVVRu5dlV4vlnNLCqnbfCJuvUXExUoJe37R5my9VzjiHjGb/SOCeT/54p8IulYz
aKqzaZRTL94k6ddRbltbGxLMJf5CRCIcPawvHp81xLVKCRt+1C8koj36YbaSP5ZJAgFjMQ50uq8Bjvia
/ugqywAAAABJRU5ErkJggg==
</value>
</data>
<data name="toolStripButtonAssAttachments.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
</value>
</data>
<data name="toolStripButtonNetflixQualityCheck.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
@ -775,7 +775,7 @@
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAD2
CAAAAk1TRnQBSQFMAgEBAgEAAWQBKgFkASoBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
CAAAAk1TRnQBSQFMAgEBAgEAAXQBKgF0ASoBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
AwABQAMAARADAAEBAQABCAYAAQQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA
AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5
AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA

View File

@ -1260,7 +1260,8 @@ namespace Nikse.SubtitleEdit.Forms.Options
AddNode(generalNode, language.ToggleMode, nameof(Configuration.Settings.Shortcuts.GeneralToggleMode));
AddNode(generalNode, language.TogglePreviewOnVideo, nameof(Configuration.Settings.Shortcuts.GeneralTogglePreviewOnVideo));
AddNode(generalNode, language.RemoveBlankLines, nameof(Configuration.Settings.Shortcuts.MainListViewRemoveBlankLines));
AddNode(generalNode, language.ApplyAssaOverrideTags, nameof(Configuration.Settings.Shortcuts.ApplyAssaOverrideTags));
AddNode(generalNode, language.ApplyAssaOverrideTags, nameof(Configuration.Settings.Shortcuts.ApplyAssaOverrideTags), true);
AddNode(generalNode, language.SetAssaPosition, nameof(Configuration.Settings.Shortcuts.SetAssaPosition), true);
AddNode(generalNode, language.Help, nameof(Configuration.Settings.Shortcuts.GeneralHelp), true);
_shortcuts.Nodes.Add(generalNode);

View File

@ -20,6 +20,7 @@ namespace Nikse.SubtitleEdit.Logic
public LanguageStructure.ApplyDurationLimits ApplyDurationLimits;
public LanguageStructure.AssaAttachments AssaAttachments;
public LanguageStructure.AssaOverrideTags AssaOverrideTags;
public LanguageStructure.AssaSetPosition AssaSetPosition;
public LanguageStructure.AudioToText AudioToText;
public LanguageStructure.AutoBreakUnbreakLines AutoBreakUnbreakLines;
public LanguageStructure.BatchConvert BatchConvert;
@ -330,6 +331,17 @@ namespace Nikse.SubtitleEdit.Logic
TagsToApply = "Tags to apply",
};
AssaSetPosition = new LanguageStructure.AssaSetPosition
{
SetPosition = "Set/get position",
VideoResolutionX = "Video reslution: {0}",
StyleAlignmentX = "Style alignment: {0}",
CurrentMousePositionX = "Mouse position: {0}",
CurrentTextPositionX = "Text position: {0}",
SetPosInfo = "Click on video to toggle set/move position",
Clipboard = "Clipboard",
};
AudioToText = new LanguageStructure.AudioToText
{
Title = "Audio to text",
@ -2340,6 +2352,7 @@ can edit in same subtitle file (collaboration)",
RemoveBlankLinesWhenOpening = "Remove blank lines when opening a subtitle",
RemoveBlankLines = "Remove blank lines",
ApplyAssaOverrideTags = "Apply ASSA override tags to selection",
SetAssaPosition = "Set/get ASSA position",
ShowLineBreaksAs = "Show line breaks in list view as",
SaveAsFileNameFrom = "\"Save as...\" uses file name from",
MainListViewDoubleClickAction = "Double-clicking line in main window list view will",

View File

@ -5476,6 +5476,9 @@ namespace Nikse.SubtitleEdit.Logic
case "Settings/ApplyAssaOverrideTags":
language.Settings.ApplyAssaOverrideTags = reader.Value;
break;
case "Settings/SetAssaPosition":
language.Settings.SetAssaPosition = reader.Value;
break;
case "Settings/ShowLineBreaksAs":
language.Settings.ShowLineBreaksAs = reader.Value;
break;

View File

@ -196,6 +196,17 @@
public string AdvancedSelection { get; set; }
}
public class AssaSetPosition
{
public string SetPosition { get; set; }
public string VideoResolutionX { get; set; }
public string StyleAlignmentX { get; set; }
public string CurrentMousePositionX { get; set; }
public string CurrentTextPositionX { get; set; }
public string SetPosInfo { get; set; }
public string Clipboard { get; set; }
}
public class AudioToText
{
public string Title { get; set; }
@ -2195,6 +2206,7 @@
public string RemoveBlankLinesWhenOpening { get; set; }
public string RemoveBlankLines { get; set; }
public string ApplyAssaOverrideTags { get; set; }
public string SetAssaPosition { get; set; }
public string ShowLineBreaksAs { get; set; }
public string SaveAsFileNameFrom { get; set; }
public string MainListViewDoubleClickAction { get; set; }

View File

@ -121,6 +121,12 @@
<Compile Include="Forms\Assa\AdvancedSelectionHelper.Designer.cs">
<DependentUpon>AdvancedSelectionHelper.cs</DependentUpon>
</Compile>
<Compile Include="Forms\Assa\SetPosition.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Forms\Assa\SetPosition.Designer.cs">
<DependentUpon>SetPosition.cs</DependentUpon>
</Compile>
<Compile Include="Forms\Assa\ApplyCustomStyles.cs">
<SubType>Form</SubType>
</Compile>
@ -1261,6 +1267,9 @@
<EmbeddedResource Include="Forms\Assa\AdvancedSelectionHelper.resx">
<DependentUpon>AdvancedSelectionHelper.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\Assa\SetPosition.resx">
<DependentUpon>SetPosition.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\Assa\ApplyCustomStyles.resx">
<DependentUpon>ApplyCustomStyles.cs</DependentUpon>
</EmbeddedResource>