diff --git a/QuickLook.Plugin/QuickLook.Plugin.CsvViewer/Plugin.MoreMenu.cs b/QuickLook.Plugin/QuickLook.Plugin.CsvViewer/Plugin.MoreMenu.cs new file mode 100644 index 0000000..379e19b --- /dev/null +++ b/QuickLook.Plugin/QuickLook.Plugin.CsvViewer/Plugin.MoreMenu.cs @@ -0,0 +1,43 @@ +// Copyright © 2017-2026 QL-Win Contributors +// +// This file is part of QuickLook program. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using QuickLook.Common.Commands; +using QuickLook.Common.Controls; +using QuickLook.Common.Helpers; +using QuickLook.Common.Plugin; +using QuickLook.Common.Plugin.MoreMenu; +using System.Collections.Generic; +using System.IO; + +namespace QuickLook.Plugin.CsvViewer; + +public sealed partial class Plugin : IViewer, IMoreMenu +{ + public IEnumerable MenuItems => GetMenuItems(); + + public IEnumerable GetMenuItems() + { + string translationFile = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "Translations.config"); + + yield return new MoreMenuItem() + { + Icon = FontSymbols.Code, + Header = TranslationHelper.Get("MW_ReopenAsTextPreview", translationFile), + Command = new RelayCommand(() => PluginHelper.InvokePluginPreview("QuickLook.Plugin.TextViewer", _currentPath)), + }; + } +} diff --git a/QuickLook.Plugin/QuickLook.Plugin.CsvViewer/Plugin.cs b/QuickLook.Plugin/QuickLook.Plugin.CsvViewer/Plugin.cs index 152ca29..75aa51b 100644 --- a/QuickLook.Plugin/QuickLook.Plugin.CsvViewer/Plugin.cs +++ b/QuickLook.Plugin/QuickLook.Plugin.CsvViewer/Plugin.cs @@ -16,15 +16,17 @@ // along with this program. If not, see . using QuickLook.Common.Plugin; +using QuickLook.Common.Plugin.MoreMenu; using System; using System.IO; using System.Windows; namespace QuickLook.Plugin.CsvViewer; -public sealed class Plugin : IViewer +public sealed partial class Plugin : IViewer, IMoreMenu { private CsvViewerPanel _panel; + private string _currentPath; public int Priority => 0; @@ -49,6 +51,8 @@ public sealed class Plugin : IViewer public void View(string path, ContextObject context) { + _currentPath = path; + _panel = new CsvViewerPanel(); context.ViewerContent = _panel; diff --git a/QuickLook.Plugin/QuickLook.Plugin.CsvViewer/QuickLook.Plugin.CsvViewer.csproj b/QuickLook.Plugin/QuickLook.Plugin.CsvViewer/QuickLook.Plugin.CsvViewer.csproj index 8b8c53e..fa49e7d 100644 --- a/QuickLook.Plugin/QuickLook.Plugin.CsvViewer/QuickLook.Plugin.CsvViewer.csproj +++ b/QuickLook.Plugin/QuickLook.Plugin.CsvViewer/QuickLook.Plugin.CsvViewer.csproj @@ -83,6 +83,12 @@ + + + PreserveNewest + + + Properties\GitVersion.cs diff --git a/QuickLook.Plugin/QuickLook.Plugin.CsvViewer/Translations.config b/QuickLook.Plugin/QuickLook.Plugin.CsvViewer/Translations.config new file mode 100644 index 0000000..4be7791 --- /dev/null +++ b/QuickLook.Plugin/QuickLook.Plugin.CsvViewer/Translations.config @@ -0,0 +1,91 @@ + + + + + إعادة فتح كمعاينة نص + + + Torna a obrir com a previsualització de text + + + Als Text-Vorschau erneut öffnen + + + Reopen as text preview + + + Reabrir como vista previa de texto + + + Rouvrir en aperçu texte + + + Riapri come anteprima testo + + + テキストとして再度開く + + + 텍스트 미리보기로 다시 열기 + + + Åpne på nytt som tekst-forhåndsvisning + + + Opnieuw openen als tekst-voorbeeld + + + Otwórz ponownie jako podgląd tekstu + + + Reabrir como visualização de texto + + + Reabrir como pré-visualização de texto + + + Redeschideți ca previzualizare text + + + Переоткрыть как предварительный просмотр текста + + + Metin önizlemesi olarak yeniden aç + + + Перевідкрити як попередній перегляд тексту + + + Mở lại dưới dạng xem trước văn bản + + + 重新作为文本预览打开 + + + 重新作為文本預覽開啟 + + + पुनः टेक्स्ट पूर्वावलोकन म्हणून उघडा + + + टेक्स्ट पूर्वावलोकन के रूप में फिर से खोलें + + + פתח מחדש כתצוגת טקסט + + + Újranyitás szöveg előnézetként + + + Buka ulang sebagai pratinjau teks + + + Znova otvoriť ako náhľad textu + + + Επανανοίξτε ως προεπισκόπηση κειμένου + + + Öppna på nytt som textförhandsgranskning + + diff --git a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Plugin.MoreMenu.cs b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Plugin.MoreMenu.cs index 358349f..5eee342 100644 --- a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Plugin.MoreMenu.cs +++ b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Plugin.MoreMenu.cs @@ -19,6 +19,7 @@ using QuickLook.Common.Commands; using QuickLook.Common.Controls; using QuickLook.Common.Helpers; using QuickLook.Common.Plugin.MoreMenu; +using System; using System.Collections.Generic; using System.IO; using System.Reflection; @@ -30,14 +31,16 @@ public sealed partial class Plugin public IEnumerable GetMenuItems() { string translationFile = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Translations.config"); - string extension = ""; + string extension = string.Empty; + try { + // Get the file extension in lowercase for comparison extension = Path.GetExtension(_currentPath).ToLower(); - } catch (System.Exception) - { } - + catch (Exception) + { + } var reopen = extension switch { @@ -58,6 +61,14 @@ public sealed partial class Plugin Header = TranslationHelper.Get("MW_ReopenAsImagePreview", translationFile), Command = new RelayCommand(() => PluginHelper.InvokePluginPreview("QuickLook.Plugin.ImageViewer", _currentPath)), }, + + // CSV, TSV, PSV <=> CSV viewer + ".csv" or ".tsv" or ".psv" => new MoreMenuItem() + { + Icon = FontSymbols.Code, + Header = TranslationHelper.Get("MW_ReopenAsCsvPreview", translationFile), + Command = new RelayCommand(() => PluginHelper.InvokePluginPreview("QuickLook.Plugin.CsvViewer", _currentPath)), + }, _ => null, }; diff --git a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Dark/CSVHighlightingDefinition.cs b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Dark/CSVHighlightingDefinition.cs new file mode 100644 index 0000000..1f9e903 --- /dev/null +++ b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Dark/CSVHighlightingDefinition.cs @@ -0,0 +1,94 @@ +using ICSharpCode.AvalonEdit.Document; +using ICSharpCode.AvalonEdit.Rendering; +using System.Windows.Media; + +namespace QuickLook.Plugin.TextViewer.Themes.HighlightingDefinitions.Dark; + +/// +/// Rainbow CSV Highlighting Definition +/// +public class CSVHighlightingDefinition : DarkHighlightingDefinition +{ + public override string Name => "CSV"; + + public override string Extension => ".csv"; + + public override DocumentColorizingTransformer[] LineTransformers { get; } = [new RainbowTransformer(',')]; + + public class RainbowTransformer(char sep) : DocumentColorizingTransformer + { + private readonly char _sep = sep; + + private readonly Brush[] _brushes = + [ + Colors.OrangeRed.ToBrush(), + Colors.CornflowerBlue.ToBrush(), + Colors.LimeGreen.ToBrush(), + Colors.MediumVioletRed.ToBrush(), + Colors.Peru.ToBrush(), + Colors.CadetBlue.ToBrush(), + Colors.Khaki.ToBrush(), + Colors.MediumSlateBlue.ToBrush(), + ]; + + protected override void ColorizeLine(DocumentLine line) + { + var text = CurrentContext.Document.GetText(line); + if (string.IsNullOrEmpty(text)) + return; + + int offset = line.Offset; + int i = 0; + int col = 0; + int len = text.Length; + + while (i < len) + { + int contentStart = i; + int contentEnd = i; + + if (text[i] == '"') + { + contentStart = i + 1; + i++; + while (i < len) + { + if (text[i] == '"') + { + if (i + 1 < len && text[i + 1] == '"') + { + i += 2; + continue; + } + else + { + contentEnd = i; + i++; + break; + } + } + i++; + } + while (i < len && text[i] != _sep) i++; + } + else + { + contentStart = i; + while (i < len && text[i] != _sep) i++; + contentEnd = i; + } + + if (contentEnd > contentStart) + { + int a = offset + contentStart; + int b = offset + contentEnd; + var brush = _brushes[col % _brushes.Length]; + ChangeLinePart(a, b, el => el.TextRunProperties.SetForegroundBrush(brush)); + } + + if (i < len && text[i] == _sep) i++; + col++; + } + } + } +} diff --git a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Dark/PSVHighlightingDefinition.cs b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Dark/PSVHighlightingDefinition.cs new file mode 100644 index 0000000..88b71d5 --- /dev/null +++ b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Dark/PSVHighlightingDefinition.cs @@ -0,0 +1,15 @@ +using ICSharpCode.AvalonEdit.Rendering; + +namespace QuickLook.Plugin.TextViewer.Themes.HighlightingDefinitions.Dark; + +/// +/// Rainbow PSV Highlighting Definition +/// +public class PSVHighlightingDefinition : DarkHighlightingDefinition +{ + public override string Name => "PSV"; + + public override string Extension => ".psv"; + + public override DocumentColorizingTransformer[] LineTransformers { get; } = [new CSVHighlightingDefinition.RainbowTransformer('|')]; +} diff --git a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Dark/TSVHighlightingDefinition.cs b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Dark/TSVHighlightingDefinition.cs new file mode 100644 index 0000000..a645c91 --- /dev/null +++ b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Dark/TSVHighlightingDefinition.cs @@ -0,0 +1,15 @@ +using ICSharpCode.AvalonEdit.Rendering; + +namespace QuickLook.Plugin.TextViewer.Themes.HighlightingDefinitions.Dark; + +/// +/// Rainbow TSV Highlighting Definition +/// +public class TSVHighlightingDefinition : DarkHighlightingDefinition +{ + public override string Name => "TSV"; + + public override string Extension => ".tsv"; + + public override DocumentColorizingTransformer[] LineTransformers { get; } = [new CSVHighlightingDefinition.RainbowTransformer('\t')]; +} diff --git a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Light/CSVHighlightingDefinition.cs b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Light/CSVHighlightingDefinition.cs new file mode 100644 index 0000000..e91b960 --- /dev/null +++ b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Light/CSVHighlightingDefinition.cs @@ -0,0 +1,102 @@ +using ICSharpCode.AvalonEdit.Document; +using ICSharpCode.AvalonEdit.Rendering; +using System.Windows.Media; + +namespace QuickLook.Plugin.TextViewer.Themes.HighlightingDefinitions.Light; + +/// +/// Rainbow CSV Highlighting Definition +/// +public class CSVHighlightingDefinition : LightHighlightingDefinition +{ + public override string Name => "CSV"; + + public override string Extension => ".csv"; + + public override DocumentColorizingTransformer[] LineTransformers { get; } = [new RainbowTransformer(',')]; + + public class RainbowTransformer(char sep) : DocumentColorizingTransformer + { + private readonly char _sep = sep; + + private readonly Brush[] _brushes = + [ + Colors.DarkRed.ToBrush(), + Colors.DarkBlue.ToBrush(), + Colors.DarkGreen.ToBrush(), + Colors.DarkMagenta.ToBrush(), + Colors.SaddleBrown.ToBrush(), + Colors.Teal.ToBrush(), + Colors.Olive.ToBrush(), + Colors.SlateBlue.ToBrush(), + ]; + + protected override void ColorizeLine(DocumentLine line) + { + var text = CurrentContext.Document.GetText(line); + if (string.IsNullOrEmpty(text)) + return; + + int offset = line.Offset; + int i = 0; + int col = 0; + int len = text.Length; + + while (i < len) + { + int fieldStart = i; + int contentStart = i; + int contentEnd = i; + + if (text[i] == '"') + { + // quoted field + contentStart = i + 1; + i++; + while (i < len) + { + if (text[i] == '"') + { + if (i + 1 < len && text[i + 1] == '"') + { + // escaped quote + i += 2; + continue; + } + else + { + // end quote + contentEnd = i; + i++; + break; + } + } + i++; + } + // skip to separator + while (i < len && text[i] != _sep) i++; + } + else + { + // unquoted + contentStart = i; + while (i < len && text[i] != _sep) i++; + contentEnd = i; + } + + // color content [contentStart, contentEnd) + if (contentEnd > contentStart) + { + int a = offset + contentStart; + int b = offset + contentEnd; + var brush = _brushes[col % _brushes.Length]; + ChangeLinePart(a, b, el => el.TextRunProperties.SetForegroundBrush(brush)); + } + + // advance past separator + if (i < len && text[i] == _sep) i++; + col++; + } + } + } +} diff --git a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Light/PSVHighlightingDefinition.cs b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Light/PSVHighlightingDefinition.cs new file mode 100644 index 0000000..1d0f270 --- /dev/null +++ b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Light/PSVHighlightingDefinition.cs @@ -0,0 +1,15 @@ +using ICSharpCode.AvalonEdit.Rendering; + +namespace QuickLook.Plugin.TextViewer.Themes.HighlightingDefinitions.Light; + +/// +/// Rainbow PSV Highlighting Definition +/// +public class PSVHighlightingDefinition : LightHighlightingDefinition +{ + public override string Name => "PSV"; + + public override string Extension => ".psv"; + + public override DocumentColorizingTransformer[] LineTransformers { get; } = [new CSVHighlightingDefinition.RainbowTransformer('|')]; +} diff --git a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Light/TSVHighlightingDefinition.cs b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Light/TSVHighlightingDefinition.cs new file mode 100644 index 0000000..6f7ed97 --- /dev/null +++ b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Light/TSVHighlightingDefinition.cs @@ -0,0 +1,15 @@ +using ICSharpCode.AvalonEdit.Rendering; + +namespace QuickLook.Plugin.TextViewer.Themes.HighlightingDefinitions.Light; + +/// +/// Rainbow TSV Highlighting Definition +/// +public class TSVHighlightingDefinition : LightHighlightingDefinition +{ + public override string Name => "TSV"; + + public override string Extension => ".tsv"; + + public override DocumentColorizingTransformer[] LineTransformers { get; } = [new CSVHighlightingDefinition.RainbowTransformer('\t')]; +} diff --git a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Translations.config b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Translations.config index 52a95a7..71bbc18 100644 --- a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Translations.config +++ b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Translations.config @@ -7,6 +7,7 @@ حدد الكل إعادة فتح كمعاينة HTML إعادة فتح كمعاينة صورة + إعادة فتح كمعاينة CSV Consolas @@ -14,6 +15,7 @@ Selecciona-ho tot Torna a obrir com a previsualització HTML Torna a obrir com a previsualització d'imatge + Torna a obrir com a previsualització CSV Consolas @@ -21,6 +23,7 @@ Alles markieren Als HTML-Vorschau erneut öffnen Als Bildvorschau erneut öffnen + Als CSV-Vorschau erneut öffnen Consolas @@ -28,6 +31,7 @@ Select All Reopen as HTML preview Reopen as image preview + Reopen as CSV preview Consolas @@ -35,6 +39,7 @@ Seleccionar Todo Reabrir como vista previa HTML Reabrir como vista previa de imagen + Reabrir como vista previa CSV Consolas @@ -42,6 +47,7 @@ Tout sélectionner Rouvrir en aperçu HTML Rouvrir en aperçu d'image + Rouvrir en aperçu CSV Consolas @@ -49,6 +55,7 @@ Seleziona tutto Riapri come anteprima HTML Riapri come anteprima immagine + Riapri come anteprima CSV Consolas,Meiryo UI,MS UI Gothic,MS Gothic @@ -56,6 +63,7 @@ すべて選択 HTML プレビューとして再度開く 画像プレビューとして再度開く + CSV プレビューとして再度開く Consolas,Malgun Gothic,Gulim @@ -63,6 +71,7 @@ 모두 선택 HTML 미리보기로 다시 열기 이미지 미리보기로 다시 열기 + CSV 미리보기로 다시 열기 Consolas @@ -70,6 +79,7 @@ Merk alt Åpne på nytt som HTML-forhåndsvisning Åpne på nytt som bilde-forhåndsvisning + Åpne på nytt som CSV-forhåndsvisning Consolas @@ -77,6 +87,7 @@ Alles selecteren Opnieuw openen als HTML-voorbeeld Opnieuw openen als afbeelding-voorbeeld + Opnieuw openen als CSV-voorbeeld Consolas @@ -84,6 +95,7 @@ Zaznacz wszystko Otwórz ponownie jako podgląd HTML Otwórz ponownie jako podgląd obrazu + Otwórz ponownie jako podgląd CSV Consolas @@ -91,6 +103,7 @@ Selecionar tudo Reabrir como visualização HTML Reabrir como visualização de imagem + Reabrir como visualização CSV Consolas @@ -98,6 +111,7 @@ Selecionar tudo Reabrir como pré-visualização HTML Reabrir como pré-visualização de imagem + Reabrir como pré-visualização CSV Consolas @@ -105,6 +119,7 @@ Selectați tot Redeschideți ca previzualizare HTML Redeschideți ca previzualizare imagine + Redeschideți ca previzualizare CSV Consolas @@ -112,6 +127,7 @@ Выделить всё Переоткрыть как предварительный просмотр HTML Переоткрыть как предварительный просмотр изображения + Переоткрыть как предварительный просмотр CSV Consolas @@ -119,6 +135,7 @@ Tümünü seç HTML önizlemesi olarak yeniden aç Resim önizlemesi olarak yeniden aç + CSV önizlemesi olarak yeniden aç Consolas @@ -126,6 +143,7 @@ Виділити Все Перевідкрити як попередній перегляд HTML Перевідкрити як попередній перегляд зображення + Перевідкрити як попередній перегляд CSV Consolas @@ -133,6 +151,7 @@ Chọn tất cả Mở lại dưới dạng xem trước HTML Mở lại dưới dạng xem trước hình ảnh + Mở lại dưới dạng xem trước CSV Consolas,Microsoft Yahei UI,Microsoft Yahei,SimSun @@ -140,6 +159,7 @@ 全选 重新作为 HTML 预览打开 重新作为图像预览打开 + 重新作为 CSV 预览打开 Consolas,Microsoft JhengHei UI,Microsoft JhengHei,MingLiU