From 77fb811736396b160d9bde9ccf3c36f60c678624 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Minisini?= Date: Fri, 23 Dec 2022 13:47:28 +0100 Subject: [PATCH] FileView: Add preview of text files and PDF files. [GB.FORM] * NEW: FileView: Add preview of text files and PDF files. --- comp/src/gb.form/.icon.png | Bin 5356 -> 5355 bytes comp/src/gb.form/.project | 2 +- comp/src/gb.form/.src/File/CTaskPreview.class | 129 +++++++++++++++++- comp/src/gb.form/.src/File/FileView.class | 23 +++- 4 files changed, 144 insertions(+), 10 deletions(-) diff --git a/comp/src/gb.form/.icon.png b/comp/src/gb.form/.icon.png index 47885d02a1fcbcef1b0499d5074bcabb4bf69130..686e221559351440491f260aed08918150f72bfa 100644 GIT binary patch delta 4329 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 t;LMj|ta7+4MgoJwNGkxJ5j6R+0Hcwhhk delta 4383 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 diff --git a/comp/src/gb.form/.project b/comp/src/gb.form/.project index e6aeedbd2..70afd23a5 100644 --- a/comp/src/gb.form/.project +++ b/comp/src/gb.form/.project @@ -1,6 +1,6 @@ # Gambas Project File 3.0 Title=More controls for graphical components -Startup=FTestFileView +Startup=FTestFileChooser Icon=.hidden/icon.png Version=3.17.90 VersionFile=1 diff --git a/comp/src/gb.form/.src/File/CTaskPreview.class b/comp/src/gb.form/.src/File/CTaskPreview.class index bec0cea93..d786b364e 100644 --- a/comp/src/gb.form/.src/File/CTaskPreview.class +++ b/comp/src/gb.form/.src/File/CTaskPreview.class @@ -3,10 +3,12 @@ Inherits Task Class Hash +Class PdfDocument + +Public Preview As String[] Private $sDir As String Private $iSize As Integer -Private $aPreview As String[] Private $iMaxFileSize As Integer Private $sCache As String @@ -16,12 +18,44 @@ Public Sub _new(sDir As String, iSize As Integer, iMaxFileSize As Integer, aPrev $iSize = iSize $iMaxFileSize = iMaxFileSize If $iMaxFileSize = 0 Then $iMaxFileSize = 4194304 - $aPreview = aPreview + Preview = aPreview $sCache = sTempDir &/ "gb.form/thumbnails" Main.MkDir($sCache) End +Private Sub IsTextFile(sPath As String) As Boolean + + Dim hFile As File + Dim sStr As String + Dim sCar As String + Dim iCode As Integer + Dim sTest As String + + Try hFile = Open sPath + If Error Then Return + + sStr = Read #hFile, -256 + + While sStr + sCar = String.Left(sStr) + sStr = Mid$(sStr, Len(sCar) + 1) + If Not sCar Then Break + If Len(sCar) = 1 Then + iCode = Asc(sCar) + If iCode = &HFE Then Return False + If iCode = &HFF Then Return False + If iCode < 32 And If iCode <> 10 And If iCode <> 13 And If iCode <> 9 Then Return False + Else If sStr Then + Try sTest = Conv(sCar, "UTF-8", "UCS-4LE") + If Error Then Return False + Endif + Wend + + Return True + +End + Private Sub PrintIcon(hImage As Image, sThumb As String) Dim hIcon As Image @@ -53,6 +87,85 @@ Private Sub PrintIcon(hImage As Image, sThumb As String) End +Private Sub PrintTextFile(sPath As String, sThumb As String) + + Dim hImage As Image + Dim hFile As File + Dim sLine As String + Dim X, Y As Integer + Dim fSize As Float + + If $iSize <= 16 Then Return + + hImage = New Image($iSize, $iSize, Color.TextBackground) + + hFile = Open sPath + + Paint.Begin(hImage) + + fSize = Min($iSize / 16, Desktop.Scale) + + X = CInt(fSize) + 1 + Y = X + + Paint.Save + Paint.ClipRect = Rect(X, Y, hImage.W - X * 2, hImage.H - Y * 2) + + If fSize >= 4 Then + + Paint.Font.Size = fSize + + While Not Eof(hFile) + Line Input #hFile, sLine + Paint.DrawText(sLine, X, Y + Paint.Font.Ascent) + Y += Paint.Font.Height + If Y > hImage.H Then Break + Wend + + Else + + hFile = Open sPath + While Not Eof(hFile) + Line Input #hFile, sLine + Paint.FillRect(X, Y, String.Len(sLine), 1, Color.LightForeground) + Y += 2 + If Y > hImage.H Then Break + Wend + + Endif + + Paint.Restore + + Paint.Rectangle(0.5, 0.5, hImage.W - 1, hImage.H - 1) + Paint.Background = Color.LightForeground + Paint.Stroke + Paint.End + + Paint.End + + Close hFile + + Try hImage.Save(sThumb) + +End + +Private Sub PrintPdfFile(sPath As String, sThumb As String) + + Dim hPdf As PdfDocument + Dim hPage As Image + + Try Component.Load("gb.poppler") + If Error Then Return + + Try hPdf = New PdfDocument(sPath) + If Error Then Return + If hPdf.Count = 0 Then Return + + hPage = hPdf[0].Render() + PrintIcon(hPage, sThumb) + +End + Private Sub GetThumbnailPath(sPath As String) As String Try Return $sCache &/ Hash.Sha256(File.Load(sPath)) & "." & CStr($iSize) & ".png" @@ -70,7 +183,7 @@ Public Sub Main() Application.Priority += 10 - For Each sFile In $aPreview + For Each sFile In Preview sPath = $sDir &/ sFile sExt = LCase(File.Ext(sFile)) @@ -108,8 +221,16 @@ Public Sub Main() Paint.End PrintIcon(hImage, sThumb) - + Endif + + Else If sExt = "pdf" Then + + Try PrintPdfFile(sPath, sThumb) + + Else If IsTextFile(sPath) Then + + Try PrintTextFile(sPath, sThumb) Endif diff --git a/comp/src/gb.form/.src/File/FileView.class b/comp/src/gb.form/.src/File/FileView.class index 99466f53c..fe7ba9d35 100644 --- a/comp/src/gb.form/.src/File/FileView.class +++ b/comp/src/gb.form/.src/File/FileView.class @@ -126,6 +126,7 @@ Private $hHighlightPicture As Picture Private $hBorder As Panel Private $hProgress As ProgressBar Private $bRefreshPreview As Boolean +Private $sLastPreview As String Static Public Sub _init() @@ -438,7 +439,7 @@ Private Sub RefreshView() Dim SY As Integer Dim sKey As String Dim aPreview As New String[] - Dim sExt As String + 'Dim sExt As String Dim bVoid As Boolean Dim iSort As Integer Dim bSortAscent As Boolean @@ -635,9 +636,9 @@ Catch ADD_PREVIEW: If Not $bShowPreview Then Return - sExt = LCase(File.Ext(sFile)) - If Not sExt Then Return - If $cExt[sExt] <> "image" Then Return + 'sExt = LCase(File.Ext(sFile)) + 'If Not sExt Then Return + 'If $cExt[sExt] <> "image" Then Return aPreview.Add(sFile) Return @@ -647,6 +648,7 @@ Private Sub StopPreview() If $hPreview Then $hPreview.Stop $hProgress.Hide + $sLastPreview = "" End @@ -688,13 +690,24 @@ Public Sub TaskPreview_Read(Data As String) Inc $iPreviewCount $hProgress.Value = $iPreviewCount / $iPreviewMax + $sLastPreview = sPath + Next End Public Sub TaskPreview_Kill() - If $hPreview = Last Then $hPreview = Null + Dim iPos As Integer + + If $hPreview = Last Then + If $sLastPreview Then + iPos = $hPreview.Preview.Find($sLastPreview) + Error "gb.form: preview failed: "; $hPreview.Preview[iPos + 1] + Endif + $hPreview = Null + StopPreview + Endif End