Skip to content

Commit 7e9ffbe

Browse files
committed
Refactor preview and description handling
1 parent 7a357b2 commit 7e9ffbe

2 files changed

Lines changed: 120 additions & 78 deletions

File tree

PasteIntoFile/ClipboardContents.cs

Lines changed: 87 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,57 @@ public TKey KeyOf(TValue value) {
4949
}
5050
}
5151

52+
/// <summary>
53+
/// Class holding the preview of the clipboard contents, and the preview type as an enum
54+
/// </summary>
55+
public class PreviewHolder {
56+
public Image Image = null;
57+
public string Text = null;
58+
public string Html = null;
59+
public string Rtf = null;
60+
public string[] List = null;
61+
62+
/// <summary>
63+
/// A friendly description of the contents
64+
/// </summary>
65+
public string Description = Resources.str_preview;
66+
67+
private PreviewHolder(string description) {
68+
Description = description ?? Resources.str_preview;
69+
}
70+
public static PreviewHolder ForImage(Image image, string description = null) {
71+
if (description == null)
72+
description = string.Format(Resources.str_preview_image, image.Width, image.Height);
73+
var p = new PreviewHolder(description);
74+
p.Image = image;
75+
return p;
76+
}
77+
public static PreviewHolder ForText(string text, string description = null) {
78+
if (description == null)
79+
description = string.Format(Resources.str_preview_text, text.Length, text.Split('\n').Length);
80+
var p = new PreviewHolder(description);
81+
p.Text = text;
82+
return p;
83+
}
84+
public static PreviewHolder ForHtml(string html, string description) {
85+
var p = new PreviewHolder(description);
86+
p.Html = html;
87+
return p;
88+
}
89+
public static PreviewHolder ForRtf(string rtf, string description = null) {
90+
if (description == null)
91+
description = Resources.str_preview_rtf;
92+
var p = new PreviewHolder(description);
93+
p.Rtf = rtf;
94+
return p;
95+
}
96+
public static PreviewHolder ForList(string[] list, string description) {
97+
var p = new PreviewHolder(description);
98+
p.List = list;
99+
return p;
100+
}
101+
}
102+
52103

53104
/// <summary>
54105
/// This is the base class to hold clipboard contents, metadata, and perform actions with it
@@ -62,9 +113,11 @@ public abstract class BaseContent {
62113
public abstract string[] Extensions { get; }
63114

64115
/// <summary>
65-
/// A friendly description of the contents
116+
/// The preview of the contents
66117
/// </summary>
67-
public abstract string Description { get; }
118+
/// <param name="extension">File extension determining the format</param>
119+
/// <returns></returns>
120+
public abstract PreviewHolder Preview(string extension);
68121

69122
/// <summary>
70123
/// The actual data content
@@ -113,12 +166,6 @@ public static string NormalizeExtension(string extension) {
113166
/// Holds image contents
114167
/// </summary>
115168
public abstract class ImageLikeContent : BaseContent {
116-
/// <summary>
117-
/// Convert the image to the format used for saving it, so it can be used for a preview
118-
/// </summary>
119-
/// <param name="extension">File extension determining the format</param>
120-
/// <returns>Image in target format or null if no suitable format is found</returns>
121-
public abstract Image ImagePreview(string extension);
122169
}
123170

124171

@@ -129,12 +176,11 @@ public ImageContent(Image image) {
129176
}
130177
public Image Image => Data as Image;
131178
public override string[] Extensions => EXTENSIONS;
132-
public override string Description => string.Format(Resources.str_preview_image, Image.Width, Image.Height);
133179

134180
public override void SaveAs(string path, string extension, bool append = false) {
135181
if (append)
136182
throw new AppendNotSupportedException();
137-
Image image = ImagePreview(extension);
183+
Image image = Preview(extension).Image;
138184
if (image == null)
139185
throw new FormatException(string.Format(Resources.str_error_cliboard_format_missmatch, extension));
140186

@@ -174,19 +220,19 @@ public override void SaveAs(string path, string extension, bool append = false)
174220
/// </summary>
175221
/// <param name="extension">File extension determining the format</param>
176222
/// <returns>Image in target format or null if no suitable format is found</returns>
177-
public override Image ImagePreview(string extension) {
223+
public override PreviewHolder Preview(string extension) {
178224
extension = NormalizeExtension(extension);
179225
// Special formats with intermediate conversion types
180226
switch (extension) {
181227
case "pdf": extension = "png"; break;
182-
case "ico": return ImageAsIcon.ToBitmap();
228+
case "ico": return PreviewHolder.ForImage(ImageAsIcon.ToBitmap());
183229
}
184230
// Find suitable codec and convert image
185231
foreach (var encoder in ImageCodecInfo.GetImageEncoders()) {
186232
if (encoder.FilenameExtension.ToLower().Contains(extension)) {
187233
var stream = new MemoryStream();
188234
Image.Save(stream, encoder, null);
189-
return Image.FromStream(stream);
235+
return PreviewHolder.ForImage(Image.FromStream(stream));
190236
}
191237
}
192238
// TODO: Support conversion to EMF, WMF
@@ -255,7 +301,6 @@ public VectorImageContent(Metafile metafile) {
255301
}
256302
public Metafile Metafile => Data as Metafile;
257303
public override string[] Extensions => EXTENSIONS;
258-
public override string Description => string.Format(Resources.str_preview_image_vector, Metafile.Width, Metafile.Height, Math.Round(Metafile.HorizontalResolution / 2 + Metafile.VerticalResolution / 2));
259304

260305
public override void SaveAs(string path, string extension, bool append = false) {
261306
if (append)
@@ -283,13 +328,14 @@ public override void SaveAs(string path, string extension, bool append = false)
283328
/// </summary>
284329
/// <param name="extension">File extension determining the format</param>
285330
/// <returns>Image in target format or null if no suitable format is found</returns>
286-
public override Image ImagePreview(string extension) {
331+
public override PreviewHolder Preview(string extension) {
287332
switch (NormalizeExtension(extension)) {
288333
case "emf":
289-
return Metafile;
334+
var description = string.Format(Resources.str_preview_image_vector, Metafile.Width, Metafile.Height, Math.Round(Metafile.HorizontalResolution / 2 + Metafile.VerticalResolution / 2));
335+
return PreviewHolder.ForImage(Metafile, description);
290336

291337
default: // fallback to save as raster image
292-
return new ImageContent(Metafile).ImagePreview(extension);
338+
return new ImageContent(Metafile).Preview(extension);
293339
}
294340
}
295341
public override void AddTo(IDataObject data) {
@@ -315,7 +361,11 @@ public TextLikeContent(string[] formats, string[] extensions, string text) {
315361

316362
public static readonly Encoding DefaultEncoding = new UTF8Encoding(false); // omit unnecessary BOM bytes
317363

318-
public override string Description => Resources.str_preview;
364+
public virtual string Description => null;
365+
366+
public override PreviewHolder Preview(string extension) {
367+
return PreviewHolder.ForText(TextFor(extension), Description);
368+
}
319369

320370
public override void AddTo(IDataObject data) {
321371
AddTo(data, Text);
@@ -334,7 +384,7 @@ protected void AddTo(IDataObject data, string text, Encoding encoding = null) {
334384
}
335385

336386
public override void SaveAs(string path, string extension, bool append = false) {
337-
Save(path, TextPreview(extension), append);
387+
Save(path, TextFor(extension), append);
338388
}
339389

340390
protected static void Save(string path, string text, bool append = false, Encoding encoding = null) {
@@ -350,7 +400,7 @@ public static string EnsureNewline(string text) {
350400
/// Return a string used for preview
351401
/// </summary>
352402
/// <returns></returns>
353-
public virtual string TextPreview(string extension) {
403+
public virtual string TextFor(string extension) {
354404
return Text;
355405
}
356406
}
@@ -362,8 +412,6 @@ public class TextContent : TextLikeContent {
362412

363413
public TextContent(string text) : base(FORMATS, EXTENSIONS, text) { }
364414

365-
public override string Description => string.Format(Resources.str_preview_text, Text.Length, Text.Split('\n').Length);
366-
367415
}
368416

369417
public class RtfContent : TextLikeContent {
@@ -413,14 +461,16 @@ public string Xml {
413461
}
414462
}
415463

416-
public override string Description => Resources.str_preview_svg;
464+
public override PreviewHolder Preview(string extension) {
465+
return PreviewHolder.ForHtml(Xml, Resources.str_preview_svg);
466+
}
417467

418468
public override void SaveAs(string path, string extension, bool append = false) {
419469
if (append) throw new AppendNotSupportedException();
420470
base.SaveAs(path, extension, append);
421471
}
422472

423-
public override string TextPreview(string extension) {
473+
public override string TextFor(string extension) {
424474
return Xml;
425475
}
426476
}
@@ -432,7 +482,10 @@ public class HtmlContent : TextLikeContent {
432482

433483
public HtmlContent(string text) : base(FORMATS, EXTENSIONS, text) { }
434484

435-
public override string Description => Resources.str_preview_html;
485+
public override PreviewHolder Preview(string extension) {
486+
return PreviewHolder.ForHtml(Text, Resources.str_preview_html);
487+
}
488+
436489
public override void SaveAs(string path, string extension, bool append = false) {
437490
var html = Text;
438491
if (!append && !html.StartsWith("<!DOCTYPE html>"))
@@ -464,6 +517,7 @@ public class CsvContent : TextLikeContent {
464517
public static readonly string[] EXTENSIONS = { "csv", "tsv", "tab", "md" };
465518

466519
public CsvContent(string text) : base(FORMATS, EXTENSIONS, text) { }
520+
467521
public override string Description => Resources.str_preview_csv;
468522

469523
/// <summary>
@@ -515,12 +569,12 @@ private string AsMarkdown() {
515569
return header + markdown;
516570
}
517571

518-
public override string TextPreview(string extension) {
572+
public override string TextFor(string extension) {
519573
switch (NormalizeExtension(extension)) {
520574
case "md":
521575
return AsMarkdown();
522576
default:
523-
return base.TextPreview(extension);
577+
return base.TextFor(extension);
524578
}
525579
}
526580

@@ -580,7 +634,6 @@ public List<string> FileList {
580634
public string FileListString => string.Join("\n", FileList);
581635

582636
public override string[] Extensions => new[] { "zip", "m3u", "files", "txt" };
583-
public override string Description => string.Format(Resources.str_preview_files, Files.Count);
584637
public override void SaveAs(string path, string extension, bool append = false) {
585638
switch (NormalizeExtension(extension)) {
586639
case "zip":
@@ -609,12 +662,13 @@ public override void SaveAs(string path, string extension, bool append = false)
609662
/// <param name="extension">File extension determining the format</param>
610663
/// <returns>Preview as text string</returns>
611664
///
612-
public string TextPreview(string extension) {
665+
public override PreviewHolder Preview(string extension) {
666+
var description = string.Format(Resources.str_preview_files, Files.Count);
613667
switch (NormalizeExtension(extension)) {
614668
case "zip":
615-
return null;
669+
return PreviewHolder.ForList(FileList.ToArray(), description);
616670
default:
617-
return FileListString;
671+
return PreviewHolder.ForText(FileListString, description);
618672
}
619673
}
620674

@@ -849,8 +903,8 @@ public static ClipboardContents FromClipboard() {
849903
// print a list of all contens in the container to the console
850904
foreach (var content in container.Contents) {
851905
Console.WriteLine("> " + content.GetType());
852-
if (content is TextLikeContent textContent) {
853-
var preview = textContent.TextPreview(content.DefaultExtension).Replace('\r', ' ').Replace('\n', ' ').Trim();
906+
if (content.Preview(content.DefaultExtension).Text is string preview) {
907+
preview = preview.Replace('\r', ' ').Replace('\n', ' ').Trim();
854908
Console.WriteLine(" " + preview.Substring(0, preview.Length > 100 ? 100 : preview.Length));
855909
}
856910
}

PasteIntoFile/Dialog.cs

Lines changed: 33 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -322,63 +322,51 @@ private void updateContentPreview() {
322322
return;
323323
}
324324

325-
box.Text = content.Description;
326-
327-
if (content is ImageLikeContent imageContent) {
328-
var img = imageContent.ImagePreview(ext);
329-
if (img != null) {
330-
imagePreview.Image = img;
331-
332-
// Checkerboard background in case image is transparent
333-
Bitmap bg = new Bitmap(img.Width, img.Height, PixelFormat.Format32bppArgb);
334-
Graphics g = Graphics.FromImage(bg);
335-
Brush brush = new SolidBrush(Color.LightGray);
336-
float d = Math.Max(10, Math.Max(bg.Width, bg.Height) / 50f);
337-
for (int x = 0; x < bg.Width / d; x++) {
338-
for (int y = 0; y < bg.Height / d; y += 2) {
339-
g.FillRectangle(brush, x * d, d * (y + x % 2), d, d);
340-
}
325+
var preview = content.Preview(ext);
326+
box.Text = preview.Description;
327+
328+
if (preview.Image is Image img) {
329+
imagePreview.Image = img;
330+
331+
// Checkerboard background in case image is transparent
332+
Bitmap bg = new Bitmap(img.Width, img.Height, PixelFormat.Format32bppArgb);
333+
Graphics g = Graphics.FromImage(bg);
334+
Brush brush = new SolidBrush(Color.LightGray);
335+
float d = Math.Max(10, Math.Max(bg.Width, bg.Height) / 50f);
336+
for (int x = 0; x < bg.Width / d; x++) {
337+
for (int y = 0; y < bg.Height / d; y += 2) {
338+
g.FillRectangle(brush, x * d, d * (y + x % 2), d, d);
341339
}
342-
imagePreview.BackgroundImage = bg;
343-
344-
imagePreview.Show();
345-
} else {
346-
// conversion failed
347-
box.Text = String.Format(Resources.str_error_cliboard_format_missmatch, comExt.Text);
348340
}
341+
imagePreview.BackgroundImage = bg;
342+
imagePreview.Show();
349343

350-
} else if (content is HtmlContent htmlContent) {
351-
htmlPreview.DocumentText = htmlContent.Text;
352-
htmlPreview.Show();
344+
} else if (preview.Text is string text) {
345+
textPreview.Text = text;
346+
textPreview.Show();
353347

354-
} else if (content is SvgContent svgContent) {
355-
htmlPreview.DocumentText = svgContent.Xml;
348+
} else if (preview.Html is string html) {
349+
htmlPreview.DocumentText = html;
356350
htmlPreview.Show();
357351

358-
} else if (content is TextLikeContent textLikeContent) {
359-
if (content.Extensions.FirstOrDefault() == "rtf")
360-
textPreview.Rtf = textLikeContent.TextPreview(ext);
361-
else
362-
textPreview.Text = textLikeContent.TextPreview(ext);
352+
} else if (preview.Rtf is string rtf) {
353+
textPreview.Rtf = rtf;
363354
textPreview.Show();
364355

365-
} else if (content is FilesContent filesContent) {
366-
if (filesContent.TextPreview(ext) is string preview) {
367-
textPreview.Text = preview;
368-
textPreview.Show();
369-
} else {
370-
treePreview.BeginUpdate();
371-
treePreview.Nodes.Clear();
372-
foreach (var file in filesContent.FileList) {
373-
treePreview.Nodes.Add(file);
374-
}
375-
treePreview.EndUpdate();
376-
treePreview.Show();
356+
} else if (preview.List is string[] list) {
357+
treePreview.BeginUpdate();
358+
treePreview.Nodes.Clear();
359+
foreach (var entry in list) {
360+
treePreview.Nodes.Add(entry);
377361
}
362+
treePreview.EndUpdate();
363+
treePreview.Show();
378364

365+
} else {
366+
// conversion failed
367+
box.Text = String.Format(Resources.str_error_cliboard_format_missmatch, comExt.Text);
379368
}
380369

381-
382370
}
383371

384372

0 commit comments

Comments
 (0)