diff --git a/src/Forms/Main.Designer.cs b/src/Forms/Main.Designer.cs
index 1a42c3814..107366156 100644
--- a/src/Forms/Main.Designer.cs
+++ b/src/Forms/Main.Designer.cs
@@ -90,11 +90,14 @@
this.toolStripMenuItemExportPngXml = new System.Windows.Forms.ToolStripMenuItem();
this.bluraySupToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItemExportCapMakerPlus = new System.Windows.Forms.ToolStripMenuItem();
+ this.toolStripMenuItemExportCaptionInc = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItemCavena890 = new System.Windows.Forms.ToolStripMenuItem();
+ this.toolStripMenuItemExportCheetahCap = new System.Windows.Forms.ToolStripMenuItem();
this.eBUSTLToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItemImagePerFrame = new System.Windows.Forms.ToolStripMenuItem();
this.pACScreenElectronicsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.plainTextToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.toolStripMenuItemExportUltech130 = new System.Windows.Forms.ToolStripMenuItem();
this.plainTextWithoutLineBreaksToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.vobSubsubidxToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator10 = new System.Windows.Forms.ToolStripSeparator();
@@ -951,11 +954,14 @@
this.toolStripMenuItemExportPngXml,
this.bluraySupToolStripMenuItem,
this.toolStripMenuItemExportCapMakerPlus,
+ this.toolStripMenuItemExportCaptionInc,
this.toolStripMenuItemCavena890,
+ this.toolStripMenuItemExportCheetahCap,
this.eBUSTLToolStripMenuItem,
this.toolStripMenuItemImagePerFrame,
this.pACScreenElectronicsToolStripMenuItem,
this.plainTextToolStripMenuItem,
+ this.toolStripMenuItemExportUltech130,
this.plainTextWithoutLineBreaksToolStripMenuItem,
this.vobSubsubidxToolStripMenuItem});
this.toolStripMenuItemExport.Name = "toolStripMenuItemExport";
@@ -990,6 +996,13 @@
this.toolStripMenuItemExportCapMakerPlus.Text = "CapMaker Plus...";
this.toolStripMenuItemExportCapMakerPlus.Click += new System.EventHandler(this.toolStripMenuItemExportCapMakerPlus_Click);
//
+ // toolStripMenuItemExportCaptionInc
+ //
+ this.toolStripMenuItemExportCaptionInc.Name = "toolStripMenuItemExportCaptionInc";
+ this.toolStripMenuItemExportCaptionInc.Size = new System.Drawing.Size(258, 22);
+ this.toolStripMenuItemExportCaptionInc.Text = "Captions Inc...";
+ this.toolStripMenuItemExportCaptionInc.Click += new System.EventHandler(this.toolStripMenuItemExportCaptionInc_Click);
+ //
// toolStripMenuItemCavena890
//
this.toolStripMenuItemCavena890.Name = "toolStripMenuItemCavena890";
@@ -997,6 +1010,13 @@
this.toolStripMenuItemCavena890.Text = "Cavena 890...";
this.toolStripMenuItemCavena890.Click += new System.EventHandler(this.ToolStripMenuItemCavena890Click);
//
+ // toolStripMenuItemExportCheetahCap
+ //
+ this.toolStripMenuItemExportCheetahCap.Name = "toolStripMenuItemExportCheetahCap";
+ this.toolStripMenuItemExportCheetahCap.Size = new System.Drawing.Size(258, 22);
+ this.toolStripMenuItemExportCheetahCap.Text = "Cheetah CAP...";
+ this.toolStripMenuItemExportCheetahCap.Click += new System.EventHandler(this.toolStripMenuItemExportCheetahCap_Click);
+ //
// eBUSTLToolStripMenuItem
//
this.eBUSTLToolStripMenuItem.Name = "eBUSTLToolStripMenuItem";
@@ -1026,6 +1046,13 @@
this.plainTextToolStripMenuItem.Text = "Plain text...";
this.plainTextToolStripMenuItem.Click += new System.EventHandler(this.PlainTextToolStripMenuItemClick);
//
+ // toolStripMenuItemExportUltech130
+ //
+ this.toolStripMenuItemExportUltech130.Name = "toolStripMenuItemExportUltech130";
+ this.toolStripMenuItemExportUltech130.Size = new System.Drawing.Size(258, 22);
+ this.toolStripMenuItemExportUltech130.Text = "Ultech caption...";
+ this.toolStripMenuItemExportUltech130.Click += new System.EventHandler(this.toolStripMenuItemExportUltech130_Click);
+ //
// plainTextWithoutLineBreaksToolStripMenuItem
//
this.plainTextWithoutLineBreaksToolStripMenuItem.Name = "plainTextWithoutLineBreaksToolStripMenuItem";
@@ -1755,7 +1782,7 @@
this.fixCommonErrorsInSelectedLinesToolStripMenuItem,
this.changeCasingForSelectedLinesToolStripMenuItem});
this.contextMenuStripListview.Name = "contextMenuStripListview";
- this.contextMenuStripListview.Size = new System.Drawing.Size(285, 782);
+ this.contextMenuStripListview.Size = new System.Drawing.Size(285, 760);
this.contextMenuStripListview.Opening += new System.ComponentModel.CancelEventHandler(this.ContextMenuStripListviewOpening);
//
// setStylesForSelectedLinesToolStripMenuItem
@@ -3014,7 +3041,7 @@
this.showOnlyWaveformToolStripMenuItem,
this.showOnlySpectrogramToolStripMenuItem});
this.contextMenuStripWaveForm.Name = "contextMenuStripWaveForm";
- this.contextMenuStripWaveForm.Size = new System.Drawing.Size(253, 236);
+ this.contextMenuStripWaveForm.Size = new System.Drawing.Size(253, 214);
this.contextMenuStripWaveForm.Opening += new System.ComponentModel.CancelEventHandler(this.ContextMenuStripWaveFormOpening);
//
// addParagraphHereToolStripMenuItem
@@ -4162,6 +4189,9 @@
private System.Windows.Forms.ToolStripMenuItem joinSubtitlesToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItemReverseRightToLeftStartEnd;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItemExportCapMakerPlus;
+ private System.Windows.Forms.ToolStripMenuItem toolStripMenuItemExportCheetahCap;
+ private System.Windows.Forms.ToolStripMenuItem toolStripMenuItemExportCaptionInc;
+ private System.Windows.Forms.ToolStripMenuItem toolStripMenuItemExportUltech130;
}
}
diff --git a/src/Forms/Main.cs b/src/Forms/Main.cs
index 37584de7c..45a5e3802 100644
--- a/src/Forms/Main.cs
+++ b/src/Forms/Main.cs
@@ -1843,6 +1843,35 @@ namespace Nikse.SubtitleEdit.Forms
}
}
+ if (format == null)
+ {
+ var captionsInc = new CaptionsInc();
+ if (captionsInc.IsMine(null, fileName))
+ {
+ captionsInc.LoadSubtitle(_subtitle, null, fileName);
+ _oldSubtitleFormat = captionsInc;
+ SetFormatToSubRip();
+ SetEncoding(Configuration.Settings.General.DefaultEncoding);
+ encoding = GetCurrentEncoding();
+ justConverted = true;
+ format = GetCurrentSubtitleFormat();
+ }
+ }
+
+ if (format == null)
+ {
+ var ultech130 = new Ultech130();
+ if (ultech130.IsMine(null, fileName))
+ {
+ ultech130.LoadSubtitle(_subtitle, null, fileName);
+ _oldSubtitleFormat = ultech130;
+ SetFormatToSubRip();
+ SetEncoding(Configuration.Settings.General.DefaultEncoding);
+ encoding = GetCurrentEncoding();
+ justConverted = true;
+ format = GetCurrentSubtitleFormat();
+ }
+ }
if (format == null)
{
@@ -12247,7 +12276,16 @@ namespace Nikse.SubtitleEdit.Forms
private void InsertLineToolStripMenuItemClick(object sender, EventArgs e)
{
- InsertBefore();
+ if (_subtitle == null || _subtitle.Paragraphs.Count == 0)
+ {
+ InsertBefore();
+ }
+ else
+ {
+ SubtitleListview1.SelectIndexAndEnsureVisible(_subtitle.Paragraphs.Count - 1);
+ InsertAfter();
+ SubtitleListview1.SelectIndexAndEnsureVisible(_subtitle.Paragraphs.Count - 1);
+ }
}
private void CloseVideoToolStripMenuItemClick(object sender, EventArgs e)
@@ -13842,5 +13880,104 @@ namespace Nikse.SubtitleEdit.Forms
}
}
+ private void toolStripMenuItemExportCheetahCap_Click(object sender, EventArgs e)
+ {
+ var cheetahCaption = new CheetahCaption();
+ saveFileDialog1.Filter = cheetahCaption.Name + "|*" + cheetahCaption.Extension;
+ saveFileDialog1.Title = _language.SaveSubtitleAs;
+ saveFileDialog1.DefaultExt = "*" + cheetahCaption.Extension;
+ saveFileDialog1.AddExtension = true;
+
+ if (!string.IsNullOrEmpty(_videoFileName))
+ saveFileDialog1.FileName = Path.GetFileNameWithoutExtension(_videoFileName);
+ else
+ saveFileDialog1.FileName = Path.GetFileNameWithoutExtension(_fileName);
+
+ if (!string.IsNullOrEmpty(openFileDialog1.InitialDirectory))
+ saveFileDialog1.InitialDirectory = openFileDialog1.InitialDirectory;
+
+ DialogResult result = saveFileDialog1.ShowDialog(this);
+ if (result == DialogResult.OK)
+ {
+ openFileDialog1.InitialDirectory = saveFileDialog1.InitialDirectory;
+ string fileName = saveFileDialog1.FileName;
+ string ext = Path.GetExtension(fileName).ToLower();
+ bool extOk = ext == cheetahCaption.Extension.ToLower();
+ if (!extOk)
+ {
+ if (fileName.EndsWith("."))
+ fileName = fileName.Substring(0, fileName.Length - 1);
+ fileName += cheetahCaption.Extension;
+ }
+ cheetahCaption.Save(fileName, _subtitle);
+ }
+ }
+
+ private void toolStripMenuItemExportCaptionInc_Click(object sender, EventArgs e)
+ {
+ var captionInc = new CaptionsInc();
+ saveFileDialog1.Filter = captionInc.Name + "|*" + captionInc.Extension;
+ saveFileDialog1.Title = _language.SaveSubtitleAs;
+ saveFileDialog1.DefaultExt = "*" + captionInc.Extension;
+ saveFileDialog1.AddExtension = true;
+
+ if (!string.IsNullOrEmpty(_videoFileName))
+ saveFileDialog1.FileName = Path.GetFileNameWithoutExtension(_videoFileName);
+ else
+ saveFileDialog1.FileName = Path.GetFileNameWithoutExtension(_fileName);
+
+ if (!string.IsNullOrEmpty(openFileDialog1.InitialDirectory))
+ saveFileDialog1.InitialDirectory = openFileDialog1.InitialDirectory;
+
+ DialogResult result = saveFileDialog1.ShowDialog(this);
+ if (result == DialogResult.OK)
+ {
+ openFileDialog1.InitialDirectory = saveFileDialog1.InitialDirectory;
+ string fileName = saveFileDialog1.FileName;
+ string ext = Path.GetExtension(fileName).ToLower();
+ bool extOk = ext == captionInc.Extension.ToLower();
+ if (!extOk)
+ {
+ if (fileName.EndsWith("."))
+ fileName = fileName.Substring(0, fileName.Length - 1);
+ fileName += captionInc.Extension;
+ }
+ captionInc.Save(fileName, _subtitle);
+ }
+ }
+
+ private void toolStripMenuItemExportUltech130_Click(object sender, EventArgs e)
+ {
+ var ultech130 = new Ultech130();
+ saveFileDialog1.Filter = ultech130.Name + "|*" + ultech130.Extension;
+ saveFileDialog1.Title = _language.SaveSubtitleAs;
+ saveFileDialog1.DefaultExt = "*" + ultech130.Extension;
+ saveFileDialog1.AddExtension = true;
+
+ if (!string.IsNullOrEmpty(_videoFileName))
+ saveFileDialog1.FileName = Path.GetFileNameWithoutExtension(_videoFileName);
+ else
+ saveFileDialog1.FileName = Path.GetFileNameWithoutExtension(_fileName);
+
+ if (!string.IsNullOrEmpty(openFileDialog1.InitialDirectory))
+ saveFileDialog1.InitialDirectory = openFileDialog1.InitialDirectory;
+
+ DialogResult result = saveFileDialog1.ShowDialog(this);
+ if (result == DialogResult.OK)
+ {
+ openFileDialog1.InitialDirectory = saveFileDialog1.InitialDirectory;
+ string fileName = saveFileDialog1.FileName;
+ string ext = Path.GetExtension(fileName).ToLower();
+ bool extOk = ext == ultech130.Extension.ToLower();
+ if (!extOk)
+ {
+ if (fileName.EndsWith("."))
+ fileName = fileName.Substring(0, fileName.Length - 1);
+ fileName += ultech130.Extension;
+ }
+ ultech130.Save(fileName, _subtitle);
+ }
+ }
+
}
}
\ No newline at end of file
diff --git a/src/Forms/Main.resx b/src/Forms/Main.resx
index cceb35c0e..4836f3b2d 100644
--- a/src/Forms/Main.resx
+++ b/src/Forms/Main.resx
@@ -574,6 +574,9 @@
208, 56
+
+ 208, 56
+
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
@@ -681,7 +684,7 @@
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAD2
- CAAAAk1TRnQBSQFMAgEBAgEAAZgBEgGYARIBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
+ CAAAAk1TRnQBSQFMAgEBAgEAAcgBEgHIARIBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
AwABQAMAARADAAEBAQABCAYAAQQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA
AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5
AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA
diff --git a/src/Forms/Settings.Designer.cs b/src/Forms/Settings.Designer.cs
index 1552b647a..f620e56c9 100644
--- a/src/Forms/Settings.Designer.cs
+++ b/src/Forms/Settings.Designer.cs
@@ -2293,7 +2293,7 @@
"Down",
"End",
"Escape",
- "Ins",
+ "Insert",
"Left",
"Pause",
"Return",
diff --git a/src/Logic/Settings.cs b/src/Logic/Settings.cs
index facf7c4bb..6d3e7cfa3 100644
--- a/src/Logic/Settings.cs
+++ b/src/Logic/Settings.cs
@@ -589,8 +589,8 @@ namespace Nikse.SubtitleEdit.Logic
MainAdjustSetEnd = string.Empty;
MainAdjustSelected100MsForward = string.Empty;
MainAdjustSelected100MsBack = string.Empty;
- MainInsertAfter = "Alt+Ins";
- MainInsertBefore = "Control+Shift+Ins";
+ MainInsertAfter = "Alt+Insert";
+ MainInsertBefore = "Control+Shift+Insert";
MainMergeDialogue = string.Empty;
WaveformVerticalZoom = string.Empty;
WaveformPlaySelection = string.Empty;
diff --git a/src/Logic/SubtitleFormats/CapMakerPlus.cs b/src/Logic/SubtitleFormats/CapMakerPlus.cs
index d1605efb0..d585e262b 100644
--- a/src/Logic/SubtitleFormats/CapMakerPlus.cs
+++ b/src/Logic/SubtitleFormats/CapMakerPlus.cs
@@ -61,27 +61,55 @@ namespace Nikse.SubtitleEdit.Logic.SubtitleFormats
buffer = new byte[] { // styles 00 00 80 BF 00 00 00 C0 02 00 01 00
0,
0,
- 0x80,
+ 0x80, //horizontal align, 0x80BF= center, 0x0000=left, 0x00c0=right
0xBF,
0,
0,
0,
- 0xC0, // horizontal pos: C0=bottom, 0=top
- 2,
+ 0xC0, // vertical pos: C0=bottom, 0=top
+ 2, //justification, 1=left, 2=center
0,
1, //1=normal font, 3=italic
0 };
- if (p.Text.StartsWith("{\\a6}"))
+ string text = p.Text;
+ if (text.StartsWith("{\\a6}"))
{
- p.Text = p.Text.Remove(0, 5);
+ text = p.Text.Remove(0, 5);
buffer[7] = 0; // align top
}
- if (p.Text.StartsWith("") && p.Text.EndsWith(""))
+ else if (text.StartsWith("{\\a1}"))
+ {
+ text = p.Text.Remove(0, 5);
+ buffer[2] = 0; // align left
+ buffer[3] = 0; // align left
+ }
+ else if (text.StartsWith("{\\a3}"))
+ {
+ text = p.Text.Remove(0, 5);
+ buffer[2] = 0; // align right
+ buffer[3] = 0xc0; // align right
+ }
+ else if (text.StartsWith("{\\a5}"))
+ {
+ text = p.Text.Remove(0, 5);
+ buffer[7] = 0; // align top
+ buffer[2] = 0; // align left
+ buffer[3] = 0; // align left
+ }
+ else if (text.StartsWith("{\\a7}"))
+ {
+ text = p.Text.Remove(0, 5);
+ buffer[7] = 0; // align top
+ buffer[2] = 0; // align right
+ buffer[3] = 0xc0; // align right
+ }
+
+ if (text.StartsWith("") && text.EndsWith(""))
buffer[10] = 3;
fs.Write(buffer, 0, buffer.Length);
- string text = Utilities.RemoveHtmlTags(p.Text);
+ text = Utilities.RemoveHtmlTags(text);
if (text.Length > 118)
text = text.Substring(0, 118);
fs.WriteByte((byte)(text.Length));
diff --git a/src/Logic/SubtitleFormats/CaptionsInc.cs b/src/Logic/SubtitleFormats/CaptionsInc.cs
index 6b183002f..e852bd632 100644
--- a/src/Logic/SubtitleFormats/CaptionsInc.cs
+++ b/src/Logic/SubtitleFormats/CaptionsInc.cs
@@ -139,10 +139,11 @@ namespace Nikse.SubtitleEdit.Logic.SubtitleFormats
bool textEnd = false;
while (!startFound && !textEnd && i < buffer.Length - 20)
{
+ bool skip = false;
if (buffer[i] == 0x0d)
i++;
else if (buffer[i] == 0x0a)
- ;
+ skip = true;
else if (buffer[i] == 0x14 && buffer[i + 1] == 0x2c) // text end
textEnd = true;
else if (buffer[i] <= 0x20) // text start
@@ -150,7 +151,8 @@ namespace Nikse.SubtitleEdit.Logic.SubtitleFormats
else
startFound = true;
- i++;
+ if (!skip)
+ i++;
}
i++;
diff --git a/src/Logic/SubtitleFormats/CheetahCaption.cs b/src/Logic/SubtitleFormats/CheetahCaption.cs
index 444d8322f..8e671a788 100644
--- a/src/Logic/SubtitleFormats/CheetahCaption.cs
+++ b/src/Logic/SubtitleFormats/CheetahCaption.cs
@@ -35,7 +35,12 @@ namespace Nikse.SubtitleEdit.Logic.SubtitleFormats
byte[] buffer = new byte[] { 0xEA, 0x22, 1, 0 }; // header
fs.Write(buffer, 0, buffer.Length);
- buffer = new byte[] { 5, 0, 9, 0xA8, 0xAF, 0x4F }; // sizes
+ int numberOfLines = subtitle.Paragraphs.Count;
+ fs.WriteByte((byte)(numberOfLines % 256)); // paragraphs - low byte
+ fs.WriteByte((byte)(numberOfLines / 256)); // paragraphs - high byte
+
+
+ buffer = new byte[] { 9, 0xA8, 0xAF, 0x4F }; // ?
fs.Write(buffer, 0, buffer.Length);
for (int i = 0; i < 118; i++)
@@ -45,19 +50,71 @@ namespace Nikse.SubtitleEdit.Logic.SubtitleFormats
foreach (Paragraph p in subtitle.Paragraphs)
{
string text = p.Text.Replace(Environment.NewLine, "\0\0\0\0");
- int length = text.Length + 16;
+
+ //styles + ?
+ buffer = new byte[] {
+ 0x12,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3, // justification, 1=left, 2=right, 3=center
+ 0xF, //horizontal position, 1=top, F=bottom
+ 0x10 //horizontal position, 3=left, 0x10=center, 0x19=right
+ };
+
+ //Normal : 12 01 00 00 00 00 03 0F 10
+ //Right-top : 12 01 00 00 00 00 03 01 1C
+ //Top : 12 01 00 00 00 00 03 01 10
+ //Left-top : 12 01 00 00 00 00 03 01 05
+ //Left : 12 01 00 00 00 00 03 0F 0A
+ //Right : 12 01 00 00 00 00 03 0F 1E
+ //Left : 12 03 00 00 00 00 03 0F 07
+
+ if (text.StartsWith("{\\a6}"))
+ {
+ text = p.Text.Remove(0, 5);
+ buffer[7] = 1; // align top
+ }
+ else if (text.StartsWith("{\\a1}"))
+ {
+ text = p.Text.Remove(0, 5);
+ buffer[8] = 0x0A; // align left
+ }
+ else if (text.StartsWith("{\\a3}"))
+ {
+ text = p.Text.Remove(0, 5);
+ buffer[8] = 0x1E; // align right
+ }
+ else if (text.StartsWith("{\\a5}"))
+ {
+ text = p.Text.Remove(0, 5);
+ buffer[7] = 1; // align top
+ buffer[8] = 05; // align left
+ }
+ else if (text.StartsWith("{\\a7}"))
+ {
+ text = p.Text.Remove(0, 5);
+ buffer[7] = 1; // align top
+ buffer[8] = 0xc; // align right
+ }
+
+ int length = text.Length + 20;
long end = fs.Position + length;
fs.WriteByte((byte)(length));
- fs.WriteByte(0x42); // ?
+ fs.WriteByte(0x62); // ?
+
+ WriteTime(fs, p.StartTime);
+ WriteTime(fs, p.EndTime);
- WriteTime(fs, p.StartTime);
- buffer = new byte[] { 0x12, 1,0,0,0,0,1,0x0F,1 }; // sizes ?
fs.Write(buffer, 0, buffer.Length);
buffer = Encoding.ASCII.GetBytes(text);
fs.Write(buffer, 0, buffer.Length); // Text starter på index 19 (0 baseret)
+ fs.WriteByte(0);
while (end > fs.Position)
fs.WriteByte(0);
diff --git a/src/Logic/SubtitleFormats/FinalCutProTextXml.cs b/src/Logic/SubtitleFormats/FinalCutProTextXml.cs
index 88ead64aa..1e34eb1f8 100644
--- a/src/Logic/SubtitleFormats/FinalCutProTextXml.cs
+++ b/src/Logic/SubtitleFormats/FinalCutProTextXml.cs
@@ -4,12 +4,11 @@ using System.IO;
using System.Text;
using System.Xml;
+// - Mom, when you were my age
what did you want to do?
namespace Nikse.SubtitleEdit.Logic.SubtitleFormats
{
class FinalCutProTestXml : SubtitleFormat
{
- public double FrameRate { get; set; }
-
public override string Extension
{
get { return ".xml"; }
@@ -37,486 +36,463 @@ namespace Nikse.SubtitleEdit.Logic.SubtitleFormats
return subtitle.Paragraphs.Count > 0;
}
- private string IsNtsc()
+ public string GetFrameRateAsString()
{
- if (FrameRate >= 29.976 && FrameRate <= 30.0)
- return "TRUE";
+ if (Configuration.Settings.General.CurrentFrameRate < 24)
+ return "24"; // ntsc 23.976
+ if (Configuration.Settings.General.CurrentFrameRate < 25)
+ return "24";
+ if (Configuration.Settings.General.CurrentFrameRate < 29)
+ return "25";
+ if (Configuration.Settings.General.CurrentFrameRate < 29)
+ return "25";
+ if (Configuration.Settings.General.CurrentFrameRate < 30)
+ return "30"; // ntsc 29.97
+ if (Configuration.Settings.General.CurrentFrameRate < 40)
+ return "30";
+ if (Configuration.Settings.General.CurrentFrameRate < 40)
+ return "30";
+ if (Configuration.Settings.General.CurrentFrameRate < 60)
+ return "60"; // ntsc 59.94
+ return "60";
+ }
+
+ public string GetNtsc()
+ {
+ if (Configuration.Settings.General.CurrentFrameRate < 24)
+ return "TRUE"; // ntsc 23.976
+ if (Configuration.Settings.General.CurrentFrameRate < 25)
+ return "FALSE";
+ if (Configuration.Settings.General.CurrentFrameRate < 29)
+ return "FALSE";
+ if (Configuration.Settings.General.CurrentFrameRate < 29)
+ return "FALSE";
+ if (Configuration.Settings.General.CurrentFrameRate < 30)
+ return "TRUE"; // ntsc 29.97
+ if (Configuration.Settings.General.CurrentFrameRate < 40)
+ return "FALSE";
+ if (Configuration.Settings.General.CurrentFrameRate < 40)
+ return "FALSE";
+ if (Configuration.Settings.General.CurrentFrameRate < 60)
+ return "TRUE"; // ntsc 59.94
return "FALSE";
}
public override string ToText(Subtitle subtitle, string title)
{
- if (Configuration.Settings.General.CurrentFrameRate > 26)
- FrameRate = 30;
- else
- FrameRate = 25;
string xmlStructure =
"" + Environment.NewLine +
- "" + Environment.NewLine +
- "" + Environment.NewLine +
- " " + Environment.NewLine +
- " Subtitles" + Environment.NewLine +
- " " + Environment.NewLine +
- " " + Environment.NewLine +
- " " + Environment.NewLine +
- " " + Environment.NewLine +
- "";
+ "" + Environment.NewLine +
+ "" + Environment.NewLine +
+ @" 5B3B0C07-9A9D-42AA-872C-C953923F97D8
+ add
+ LOF_master til dialogliste
+ 73574
+
+ " + GetNtsc() + @"
+ " + GetFrameRateAsString() + @"
+
+
+
+ " + GetNtsc() + @"
+ " + GetFrameRateAsString() + @"
+
+ 00:00:00:00
+ 0
+
+ NDF
+
+ 0
+ 73575
+
+
+
+
+";
+
string xmlTrackStructure =
- "" + Environment.NewLine +
- " Text" + Environment.NewLine +
- " " + Environment.NewLine +
- " " + IsNtsc() + "" + Environment.NewLine +
- " " + string.Format("{0:0.##}", FrameRate) + "" + Environment.NewLine +
- " " + Environment.NewLine +
- " " + Environment.NewLine + // start frame?
- " " + Environment.NewLine + // end frame?
- " TRUE" + Environment.NewLine +
- " FALSE" + Environment.NewLine +
- " black" + Environment.NewLine +
- " " + Environment.NewLine +
- " Text" + Environment.NewLine +
-// " Text" + Environment.NewLine +
- " Text" + Environment.NewLine +
- " generator" + Environment.NewLine +
- " video" + Environment.NewLine +
- " " + Environment.NewLine +
- " str" + Environment.NewLine +
- " Text" + Environment.NewLine +
- " " + Environment.NewLine + // TEXT GOES HERE
- " " + Environment.NewLine +
- " " + Environment.NewLine +
- "";
-
-// string xmlTrackStructure2 =
-// @"
-// edit 'B subtitle
-// 3000
-//
-// FALSE
-// 25
-//
-// 1375
-// 1383
-// 0
-// 8
-// TRUE
-// TRUE
-// black
-//
-//
-//
-//
-//
-//
-//
-// FALSE
-//
-//
-//
-//
-//
-//
-//
-//
-//
-//
-//
-//
-//
-//
-//
-//
-// edit 'B subtitle
-// edit 'B subtitle
-// Text
-// generator
-// video
-//
-// part1
-// Text Settings
-// 0
-//
-//
-// str
-// Text
-//
-//
-//
-// fontname
-// Font
-// Arial Narrow
-//
-//
-// fontstyle
-// Style
-// 1
-// 4
-//
-//
-// Plain
-// 1
-//
-//
-// Bold
-// 2
-//
-//
-// Italic
-// 3
-//
-//
-// Bold/Italic
-// 4
-//
-//
-// 1
-//
-//
-// fontalign
-// Alignment
-// 1
-// 3
-//
-//
-// Left
-// 1
-//
-//
-// Center
-// 2
-//
-//
-// Right
-// 3
-//
-//
-// 2
-//
-//
-// fontsize
-// Size
-// 20
-// 80
-// 28
-//
-//
-// origin
-// Origin
-//
-// 0
-// 0.3056
-//
-//
-//
-// aspect
-// Aspect
-// 0
-// 2
-// 1
-//
-//
-// textopacity
-// Text Opacity
-// 0
-// 100
-// 100
-//
-//
-// textcolor
-// Text Color
-//
-// 255
-// 255
-// 255
-// 255
-//
-//
-//
-// fonttrack
-// Tracking
-// 0
-// 10
-// 1
-//
-//
-// leading
-// Leading
-// -40
-// 40
-// -13
-//
-//
-// autokern
-// Auto Kerning
-// TRUE
-//
-//
-// part2
-// Outline Settings
-// 0
-//
-//
-// linewidth
-// Width
-// 0
-// 50
-// 8
-//
-//
-// linesoft
-// Soft
-// 0
-// 100
-// 38
-//
-//
-// linecolor
-// Color
-//
-// 255
-// 0
-// 0
-// 0
-//
-//
-//
-// part3
-// Shadow Settings
-// 0
-//
-//
-// shadowoffsetx
-// Offset X
-// -20
-// 20
-// 3
-//
-//
-// shadowoffsety
-// Offset y
-// -20
-// 20
-// 3
-//
-//
-// shadowopacity
-// Opacity
-// 0
-// 100
-// 75
-//
-//
-// shadowsoft
-// Softness
-// 0
-// 100
-// 2
-//
-//
-// shadowcolor
-// Color
-//
-// 255
-// 0
-// 0
-// 0
-//
-//
-//
-//
-// video
-//
-// ";
-
- string xmlTrackStructure3a =
-@"
- Text
- 3600
-
- TRUE
- " + string.Format("{0:0.##}", FrameRate) + @"
-
- 1650
- 1784
- 0
- 134
- TRUE
- FALSE
- black
-
- Text
- Text
- Text
- generator
- video
-
- str
- Text
- If you look at the Lindy Hop
you'll see a couple just moving
-
-
- fontname
- Font
- Futura
-
-
- fontsize
- Size
- 0
- 1000
- 36
-
- fontstyle
- Style
- 1
- 4
-
-
+ @"
+ Outline Text
+ 3000
+
+ " + GetNtsc() + @"
+ " + GetFrameRateAsString() + @"
+
+ 1380
+ 1474
+ 8228
+ 8322
+ TRUE
+ FALSE
+ black
+ Outline Text1
+
+
+
+
+ FALSE
+
+
+
+
+
+
+
+
+
+
+
+ Outline Text
+ Outline Text
+ Text
+ generator
+ video
+
+ part1
+ Text Settings
+
+
+
+ str
+ Text
+ [TEXT]
+
+
+ font
+ Font
+ Lucida Grande
+
+
+ style
+ Style
+ 1
+ 4
+
+
Plain
1
-
-
+
+
Bold
2
-
-
+
+
Italic
3
-
-
+
+
Bold/Italic
4
-
-
- 3
-
-
- fontalign
- Alignment
- 1
- 3
-
-
+
+
+ [FONTSTYLE]
+
+
+ align
+ Alignment
+ 1
+ 3
+
+
Left
1
-
-
+
+
Center
2
-
-
+
+
Right
3
-
-
- 2
-
-
- fontcolor
- Font Color
-
- 255
- 255
- 255
- 255
-
-
-
- origin
- Origin
-
- 0
- 0.34375
-
-
-
-
- video
-
-";
+
+
+ 2
+
+
+ size
+ Size
+ 0
+ 200
+ 18
+
+
+ track
+ Tracking
+ 0
+ 100
+ 1
+
+
+ lead
+ Leading
+ -100
+ 100
+ 0
+
+
+ aspect
+ Aspect
+ 0
+ 4
+ 1
+
+
+ linewidth
+ Line Width
+ 0
+ 200
+ 20
+
+
+ linesoft
+ Line Softness
+ 0
+ 100
+ 5
+
+
+ textopacity
+ Text Opacity
+ 0
+ 100
+ 100
+
+
+ center
+ Center
+
+ 0.00833333
+ 0.390741
+
+
+
+ textcolor
+ Text Color
+
+ 255
+ 255
+ 255
+ 255
+
+
+
+ supertext
+ Text Graphic
+
+
+ linecolor
+ Line Color
+
+ 255
+ 0
+ 0
+ 0
+
+
+
+ superline
+ Line Graphic
+
+
+ part2
+ Background Settings
+
+
+
+ xscale
+ Horizontal Size
+ 0
+ 200
+ 0
+
+
+ yscale
+ Vertical Size
+ 0
+ 200
+ 0
+
+
+ xoffset
+ Horizontal Offset
+ -100
+ 100
+ 0
+
+
+ yoffset
+ Vertical Offset
+ -100
+ 100
+ 0
+
+
+ backsoft
+ Back Soft
+ 0
+ 100
+ 0
+
+
+ backopacity
+ Back Opacity
+ 0
+ 100
+ 50
+
+
+ backcolor
+ Back Color
+
+ 255
+ 255
+ 255
+ 255
+
+
+
+ superback
+ Back Graphic
+
+
+ crop
+ Crop
+ FALSE
+
+
+ autokern
+ Auto Kerning
+ TRUE
+
+
+
+ video
+
+
+ 8F00E937-5C83-4A2F-9827-AE0612006D05
+
+ ";
-string xmlTrackStructure3b =
-@"
- 135
- 219
-
- Text
- Text
- Text
- generator
- video
-
- str
- Text
-
-
-
-";
-
- XmlDocument xml = new XmlDocument();
+ var xml = new XmlDocument();
xml.LoadXml(xmlStructure);
+ xml.DocumentElement.SelectSingleNode("sequence/name").InnerText = title;
+ if (subtitle.Header != null && subtitle.Header.StartsWith("") && subtitle.Header.EndsWith(""))
+ xml.DocumentElement.SelectSingleNode("sequence/uuid").InnerText = subtitle.Header.Replace("", string.Empty).Replace("", string.Empty).Trim();
+ else
+ xml.DocumentElement.SelectSingleNode("sequence/uuid").InnerText = Guid.NewGuid().ToString().ToUpper();
- XmlNode videoNode = xml.DocumentElement.SelectSingleNode("sequence/media/video");
+ XmlNode trackNode = xml.DocumentElement.SelectSingleNode("sequence/media/video/track");
+ string newLine = "_____@___";
int number = 1;
foreach (Paragraph p in subtitle.Paragraphs)
{
- XmlNode track = xml.CreateElement("track");
- if (number == 1)
- track.InnerXml = xmlTrackStructure3a;
- else
- track.InnerXml = xmlTrackStructure3b;
+ XmlNode generatorItem = xml.CreateElement("generatoritem");
+ string fontStyle = "1"; //1==plain
+ string s = Utilities.RemoveHtmlFontTag(p.Text).Trim();
+ if (s.StartsWith("") && s.EndsWith(""))
+ fontStyle = "3"; //3==italic
+ generatorItem.InnerXml = xmlTrackStructure.Replace("[NUMBER]", number.ToString()).Replace("[FONTSTYLE]", fontStyle);
double frameRate = Configuration.Settings.General.CurrentFrameRate;
- XmlNode start = track.SelectSingleNode("generatoritem/start");
- start.InnerText = ((int)Math.Round(p.StartTime.TotalSeconds*frameRate)).ToString();
+ XmlNode start = generatorItem.SelectSingleNode("generatoritem/start");
+ start.InnerText = ((int)Math.Round(p.StartTime.TotalSeconds * frameRate)).ToString();
- XmlNode end = track.SelectSingleNode("generatoritem/end");
+ XmlNode end = generatorItem.SelectSingleNode("generatoritem/end");
end.InnerText = ((int)Math.Round(p.EndTime.TotalSeconds * frameRate)).ToString();
- XmlNode text = track.SelectSingleNode("generatoritem/effect/parameter[parameterid='str']/value");
+ XmlNode text = generatorItem.SelectSingleNode("generatoritem/effect/parameter[parameterid='str']/value");
text.InnerText = Utilities.RemoveHtmlTags(p.Text);
+ text.InnerXml = text.InnerXml.Replace(Environment.NewLine, newLine);
- XmlNode effect = track.SelectSingleNode("generatoritem/effect");
- if (effect != null && effect.Attributes["id"] != null)
- effect.Attributes["id"].InnerText = "Subtitle" + number.ToString();
-
- videoNode.AppendChild(track);
+ trackNode.AppendChild(generatorItem.SelectSingleNode("generatoritem"));
number++;
}
- MemoryStream ms = new MemoryStream();
- XmlTextWriter writer = new XmlTextWriter(ms, Encoding.UTF8);
- writer.Formatting = Formatting.Indented;
+ var ms = new MemoryStream();
+ var writer = new XmlTextWriter(ms, Encoding.UTF8) { Formatting = Formatting.Indented };
xml.Save(writer);
string xmlAsText = Encoding.UTF8.GetString(ms.ToArray()).Trim();
xmlAsText = xmlAsText.Replace("xmeml[]", "xmeml");
+ xmlAsText = xmlAsText.Replace(newLine, "
");
return xmlAsText;
}
public override void LoadSubtitle(Subtitle subtitle, List lines, string fileName)
{
_errorCount = 0;
- FrameRate = Configuration.Settings.General.CurrentFrameRate;
+ var frameRate = Configuration.Settings.General.CurrentFrameRate;
- StringBuilder sb = new StringBuilder();
+ var sb = new StringBuilder();
lines.ForEach(line => sb.AppendLine(line));
- XmlDocument xml = new XmlDocument();
+ var xml = new XmlDocument();
try
{
xml.LoadXml(sb.ToString());
+ if (xml.DocumentElement.SelectSingleNode("sequence/uuid") != null)
+ subtitle.Header = "" + xml.DocumentElement.SelectSingleNode("sequence/uuid").InnerText + "";
+
if (xml.DocumentElement.SelectSingleNode("sequence/rate") != null && xml.DocumentElement.SelectSingleNode("sequence/rate/timebase") != null)
{
try
{
- FrameRate = double.Parse(xml.DocumentElement.SelectSingleNode("sequence/rate/timebase").InnerText);
+ frameRate = double.Parse(xml.DocumentElement.SelectSingleNode("sequence/rate/timebase").InnerText);
}
catch
{
- FrameRate = Configuration.Settings.General.CurrentFrameRate;
+ frameRate = Configuration.Settings.General.CurrentFrameRate;
}
}
@@ -531,7 +507,7 @@ string xmlTrackStructure3b =
{
XmlNode timebase = rate.SelectSingleNode("timebase");
if (timebase != null)
- FrameRate = double.Parse(timebase.InnerText);
+ frameRate = double.Parse(timebase.InnerText);
}
double startFrame = 0;
@@ -551,9 +527,38 @@ string xmlTrackStructure3b =
if (valueNode != null)
text += valueNode.InnerText;
}
+
+ bool italic = false;
+ foreach (XmlNode parameterNode in generatorItemNode.SelectNodes("effect/parameter[parameterid='style']"))
+ {
+ XmlNode valueNode = parameterNode.SelectSingleNode("value");
+ var valueEntries = parameterNode.SelectNodes("valuelist/valueentry");
+ if (valueNode != null)
+ {
+ int no;
+ if (int.TryParse(valueNode.InnerText, out no))
+ {
+ no--;
+ if (no < valueEntries.Count)
+ {
+ var styleNameNode = valueEntries[no].SelectSingleNode("name");
+ if (styleNameNode != null)
+ {
+ string styleName = styleNameNode.InnerText;
+ italic = styleName.ToLower().Trim() == "italic";
+ }
+ }
+ }
+ }
+ }
+
if (text.Length > 0)
{
- subtitle.Paragraphs.Add(new Paragraph(text, Convert.ToDouble((startFrame / FrameRate) *1000), Convert.ToDouble((endFrame / FrameRate) * 1000)));
+ if (!text.Contains(Environment.NewLine))
+ text = text.Replace("\r", Environment.NewLine);
+ if (italic)
+ text = "" + text + "";
+ subtitle.Paragraphs.Add(new Paragraph(text, Convert.ToDouble((startFrame / frameRate) * 1000), Convert.ToDouble((endFrame / frameRate) * 1000)));
}
}
}
@@ -569,7 +574,7 @@ string xmlTrackStructure3b =
_errorCount = 1;
return;
}
-
+ Configuration.Settings.General.CurrentFrameRate = frameRate;
}
}
diff --git a/src/Logic/SubtitleFormats/FinalCutProXml.cs b/src/Logic/SubtitleFormats/FinalCutProXml.cs
index fcf2e92c3..54dd2d313 100644
--- a/src/Logic/SubtitleFormats/FinalCutProXml.cs
+++ b/src/Logic/SubtitleFormats/FinalCutProXml.cs
@@ -177,21 +177,6 @@ namespace Nikse.SubtitleEdit.Logic.SubtitleFormats
FALSE
black
Outline Text1
-
-
-
-
- FALSE
-
-
-
-
-
-
-
-
-
-
Outline Text
Outline Text
@@ -340,10 +325,6 @@ namespace Nikse.SubtitleEdit.Logic.SubtitleFormats
0
-
- superline
- Line Graphic
-
part2
Background Settings
@@ -377,20 +358,6 @@ namespace Nikse.SubtitleEdit.Logic.SubtitleFormats
100
0
-
- backsoft
- Back Soft
- 0
- 100
- 0
-
-
- backopacity
- Back Opacity
- 0
- 100
- 50
-
backcolor
Back Color
@@ -419,9 +386,6 @@ namespace Nikse.SubtitleEdit.Logic.SubtitleFormats
video
-
- 8F00E937-5C83-4A2F-9827-AE0612006D05
-
";
var xml = new XmlDocument();
diff --git a/src/Logic/SubtitleFormats/Ultech130.cs b/src/Logic/SubtitleFormats/Ultech130.cs
new file mode 100644
index 000000000..81274fc80
--- /dev/null
+++ b/src/Logic/SubtitleFormats/Ultech130.cs
@@ -0,0 +1,285 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+
+namespace Nikse.SubtitleEdit.Logic.SubtitleFormats
+{
+ class Ultech130 : SubtitleFormat
+ {
+
+ private const string UltechId = "ULTECH\01.30";
+
+ public override string Extension
+ {
+ get { return ".ult"; }
+ }
+
+ public override string Name
+ {
+ get { return "Ultech 1.30 Caption"; }
+ }
+
+ public override bool HasLineNumber
+ {
+ get { return false; }
+ }
+
+ public override bool IsTimeBased
+ {
+ get { return true; }
+ }
+
+ public void Save(string fileName, Subtitle subtitle)
+ {
+ var fs = new FileStream(fileName, FileMode.Create, FileAccess.Write);
+
+ byte[] buffer = buffer = Encoding.ASCII.GetBytes(UltechId);
+ fs.Write(buffer, 0, buffer.Length);
+
+ buffer = new byte[] { 0, 0, 2, 0x1D, 0 }; // ?
+ fs.Write(buffer, 0, buffer.Length);
+
+ int numberOfLines = subtitle.Paragraphs.Count;
+ fs.WriteByte((byte)(numberOfLines % 256)); // paragraphs - low byte
+ fs.WriteByte((byte)(numberOfLines / 256)); // paragraphs - high byte
+
+ buffer = new byte[] { 0, 0, 0, 0, 0x1, 0, 0xF, 0x15, 0, 0, 0, 0, 0, 0, 0, 0x1, 0, 0xE, 0x15, 0, 0, 0, 0, 0, 0, 0, 0x1, 0, 0xD, 0x15, 0, 0, 0, 0, 0, 0, 0, 0x1, 0, 0xC, 0x15, 0, 0, 0, 0, 0, 0, 0, 0x1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // ?
+ fs.Write(buffer, 0, buffer.Length);
+
+ buffer = buffer = Encoding.ASCII.GetBytes("Subtitle Edit");
+ fs.Write(buffer, 0, buffer.Length);
+
+ while (fs.Length < 512)
+ fs.WriteByte(0);
+
+ // paragraphs
+ foreach (Paragraph p in subtitle.Paragraphs)
+ {
+ // convert line breaks
+ var sb = new StringBuilder();
+ var line = new StringBuilder();
+ int skipCount = 0;
+ int numberOfNewLines = Utilities.CountTagInText(p.Text, Environment.NewLine);
+ bool italic = p.Text.StartsWith("") && p.Text.EndsWith("");
+ string text = Utilities.RemoveHtmlTags(p.Text);
+ if (italic)
+ {
+ sb.Append(Convert.ToChar(0x11).ToString());
+ sb.Append(Convert.ToChar(0x2E).ToString());
+ }
+ int y = 0x74 - (numberOfNewLines * 0x20);
+ for (int j=0; j 0)
+ sb.Append(line);
+ line = new StringBuilder();
+ skipCount = Environment.NewLine.Length - 1;
+ sb.Append(Convert.ToChar(0x14).ToString());
+ sb.Append(Convert.ToChar((byte)(y)).ToString());
+ if (italic)
+ {
+ sb.Append(Convert.ToChar(0x11).ToString());
+ sb.Append(Convert.ToChar(0x2E).ToString());
+ }
+ }
+ else if (skipCount == 0)
+ {
+ line.Append(text.Substring(j, 1));
+ }
+ else
+ {
+ skipCount--;
+ }
+ }
+ if (line.Length > 0)
+ sb.Append(line);
+ text = sb.ToString();
+
+
+ // codes?
+ buffer = new byte[] {
+ 0x14,
+ 0x20,
+ 0x14,
+ 0x2E,
+ 0x14,
+ (byte)(0x74 - (numberOfNewLines * 0x20)),
+ 0x17,
+ 0x21,
+ };
+
+ //if (text.StartsWith("{\\a6}"))
+ //{
+ // text = p.Text.Remove(0, 5);
+ // buffer[7] = 1; // align top
+ //}
+ //else if (text.StartsWith("{\\a1}"))
+ //{
+ // text = p.Text.Remove(0, 5);
+ // buffer[8] = 0x0A; // align left
+ //}
+ //else if (text.StartsWith("{\\a3}"))
+ //{
+ // text = p.Text.Remove(0, 5);
+ // buffer[8] = 0x1E; // align right
+ //}
+ //else if (text.StartsWith("{\\a5}"))
+ //{
+ // text = p.Text.Remove(0, 5);
+ // buffer[7] = 1; // align top
+ // buffer[8] = 05; // align left
+ //}
+ //else if (text.StartsWith("{\\a7}"))
+ //{
+ // text = p.Text.Remove(0, 5);
+ // buffer[7] = 1; // align top
+ // buffer[8] = 0xc; // align right
+ //}
+
+ fs.WriteByte(0xF1); //ID of start record
+
+ // length
+ int length = text.Length + 15;
+ fs.WriteByte((byte)(length));
+ fs.WriteByte(0);
+
+ // start time
+ WriteTime(fs, p.StartTime);
+ fs.Write(buffer, 0, buffer.Length);
+
+ // text
+ buffer = Encoding.ASCII.GetBytes(text);
+ fs.Write(buffer, 0, buffer.Length); // Text starter på index 19 (0 baseret)
+ fs.WriteByte(0x14);
+ fs.WriteByte(0x2F);
+ fs.WriteByte(0);
+
+ // end time
+ fs.WriteByte(0xF1); // id of start record
+ fs.WriteByte(7); // length of end time
+ fs.WriteByte(0);
+ WriteTime(fs, p.EndTime);
+ fs.WriteByte(0x14);
+ fs.WriteByte(0x2c);
+ fs.WriteByte(0);
+ }
+
+ buffer = new byte[] { 0xF1, 0x0B, 0x00, 0x00, 0x00, 0x1B, 0x18, 0x14, 0x20, 0x14, 0x2E, 0x14, 0x2F, 0x00 }; // footer
+ fs.Write(buffer, 0, buffer.Length);
+
+ fs.Close();
+ }
+
+ private void WriteTime(FileStream fs, TimeCode timeCode)
+ {
+ fs.WriteByte((byte)timeCode.Hours);
+ fs.WriteByte((byte)timeCode.Minutes);
+ fs.WriteByte((byte)timeCode.Seconds);
+ fs.WriteByte((byte)MillisecondsToFrames(timeCode.Milliseconds));
+ }
+
+ public override bool IsMine(List lines, string fileName)
+ {
+ if (!string.IsNullOrEmpty(fileName) && File.Exists(fileName))
+ {
+ var fi = new FileInfo(fileName);
+ if (fi.Length >= 200 && fi.Length < 1024000) // not too small or too big
+ {
+ if (fileName.ToLower().EndsWith(".ult") || fileName.ToLower().EndsWith(".uld")) // drop frame is often named uld, and ult for non-drop
+ {
+ byte[] buffer = File.ReadAllBytes(fileName);
+ string id = Encoding.ASCII.GetString(buffer, 0, UltechId.Length);
+ return id == UltechId;
+ }
+ }
+ }
+ return false;
+ }
+
+ public override string ToText(Subtitle subtitle, string title)
+ {
+ return "Not supported!";
+ }
+
+ private TimeCode DecodeTimeStamp(byte[] buffer, int index)
+ {
+ return new TimeCode(buffer[index], buffer[index + 1], buffer[index + 2], FramesToMilliseconds(buffer[index + 3]));
+ }
+
+ public override void LoadSubtitle(Subtitle subtitle, List lines, string fileName)
+ {
+ subtitle.Paragraphs.Clear();
+ subtitle.Header = null;
+ byte[] buffer = File.ReadAllBytes(fileName);
+
+ int i = 512;
+ Paragraph last = null;
+ while (i < buffer.Length - 25)
+ {
+ var p = new Paragraph();
+ int length = buffer[i+1];
+
+ p.StartTime = DecodeTimeStamp(buffer, i + 3);
+ if (last != null && last.EndTime.TotalMilliseconds == 0)
+ last.EndTime.TotalMilliseconds = p.StartTime.TotalMilliseconds-1;
+
+ if (length > 22)
+ {
+ int start = i + 7;
+ var sb = new StringBuilder();
+ int skipCount = 0;
+ for (int k = start; k < length + i; k++)
+ {
+ byte b = buffer[k];
+ if (skipCount > 0)
+ {
+ skipCount--;
+ }
+ else if (b < 0x1F)
+ {
+ skipCount = 1;
+ if (sb.Length > 0)
+ sb.AppendLine();
+ }
+ else if (b == 0x80)
+ {
+ break;
+ }
+ else
+ {
+ sb.Append(Convert.ToChar(b).ToString());
+ }
+ }
+
+ p.Text = sb.ToString();
+ p.Text = p.Text.Replace(Environment.NewLine + Environment.NewLine, Environment.NewLine);
+ p.Text = p.Text.Replace(Environment.NewLine + Environment.NewLine, Environment.NewLine);
+ p.Text = p.Text.Replace(Environment.NewLine + Environment.NewLine, Environment.NewLine);
+
+ subtitle.Paragraphs.Add(p);
+ }
+ else if (last != null)
+ {
+ last.EndTime.TotalMilliseconds = p.StartTime.TotalMilliseconds;
+ }
+ last = p;
+
+ i += length + 3;
+ }
+ if (last != null)
+ {
+ if (last.EndTime.TotalMilliseconds == 0)
+ last.EndTime.TotalMilliseconds = last.StartTime.TotalMilliseconds + 2500;
+ if (last != null && last.Duration.TotalMilliseconds > Configuration.Settings.General.SubtitleMaximumDisplayMilliseconds)
+ last.EndTime.TotalMilliseconds = last.StartTime.TotalMilliseconds + Utilities.GetDisplayMillisecondsFromText(last.Text);
+ }
+
+ subtitle.Renumber(1);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/src/Logic/Utilities.cs b/src/Logic/Utilities.cs
index a316c8577..d53108c92 100644
--- a/src/Logic/Utilities.cs
+++ b/src/Logic/Utilities.cs
@@ -1318,29 +1318,33 @@ namespace Nikse.SubtitleEdit.Logic
}
}
+ private static void AddExtension(StringBuilder sb, string extension)
+ {
+ if (!sb.ToString().Contains("*" + extension + ";"))
+ sb.Append("*" + extension + ";");
+ }
+
public static string GetOpenDialogFilter()
{
StringBuilder sb = new StringBuilder();
sb.Append(Configuration.Settings.Language.General.SubtitleFiles + "|");
foreach (SubtitleFormat s in SubtitleFormat.AllSubtitleFormats)
{
- if (!sb.ToString().Contains("*" + s.Extension + ";"))
- sb.Append("*" + s.Extension + ";");
+ AddExtension(sb, s.Extension);
foreach (string ext in s.AlternateExtensions)
- {
- if (!sb.ToString().Contains("*" + ext + ";"))
- sb.Append("*" + ext + ";");
- }
+ AddExtension(sb, ext);
}
- sb.Append("*" + new Pac().Extension + ";");
- sb.Append("*" + new Cavena890().Extension + ";");
- sb.Append("*" + new Spt().Extension + ";");
- sb.Append("*" + new Wsb().Extension + ";");
- sb.Append("*" + new CheetahCaption().Extension + ";");
- sb.Append("*" + new CaptionsInc().Extension + ";");
- sb.Append("*" + new SonicScenaristBitmaps().Extension + ";");
- sb.Append("*.mks;"); // matroska subtitlefiles (normally contain subtitles)
- sb.Append("*.sup;"); // blu-ray sup
+ AddExtension(sb, new Pac().Extension);
+ AddExtension(sb, new Cavena890().Extension);
+ AddExtension(sb, new Spt().Extension);
+ AddExtension(sb, new Wsb().Extension);
+ AddExtension(sb, new CheetahCaption().Extension);
+ AddExtension(sb, new CaptionsInc().Extension);
+ AddExtension(sb, new Ultech130().Extension);
+ AddExtension(sb, ".uld"); // Ultech drop frame
+ AddExtension(sb, new SonicScenaristBitmaps().Extension);
+ AddExtension(sb, ".mks");
+ AddExtension(sb, ".sup");
if (!string.IsNullOrEmpty(Configuration.Settings.General.OpenSubtitleExtraExtensions))
{
diff --git a/src/SubtitleEdit.csproj b/src/SubtitleEdit.csproj
index 5e484b01c..975306f4e 100644
--- a/src/SubtitleEdit.csproj
+++ b/src/SubtitleEdit.csproj
@@ -660,6 +660,7 @@
+