From 437afc5bcb3eddfeb235c76d788708a8da01b5f3 Mon Sep 17 00:00:00 2001 From: Manuel Brotz Date: Tue, 16 Apr 2024 10:29:40 +0200 Subject: [PATCH 01/10] modernized the layout and appearance to more closely match the Finder --- LICENSE.txt | 32 +- README.txt | 11 +- qlZipInfo.xcodeproj/project.pbxproj | 9 +- qlZipInfo/GeneratePreviewForURL.h | 67 ++-- qlZipInfo/GeneratePreviewForURL.m | 475 +++++++++++++++------------- qlZipInfo/Info.plist | 4 +- 6 files changed, 341 insertions(+), 257 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index d305b61..769e8ad 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,7 +1,7 @@ qlZipInfo Licenses ------------------ -Portions Copyright (c) 2015-2022 Sriranga Veeraraghavan . +Portions Copyright (c) 2015-2024 Sriranga Veeraraghavan . All rights reserved. For those portions Copyright (c) Sriranga Veeraraghavan, the following license @@ -165,3 +165,33 @@ lzma: 7-Zip , which has a modified version of the public domain SHA-256 code found from Crypto++ . The SHA-256 code in Crypto++ was written by Kevin Springle and Wei Dai. + +SVG icons from icons8.com: + + Contribution by Manuel Brotz, https://github.com/mbrotz/qlZipInfo + + I asked for and received permission from icons8 to use their icons in this + project. Please note that these icons were purchased using a subscription + to icons8 and you are not allowed to use them in your own projects whithout + purchasing them from icons8 yourself! + + This question was posted to the questions section at + https://icons8.com/pricing on 04/09/2024. + + Manuel Brotz 04/09/2024 + + Hi. I paid for one month and downloaded 6 icons in svg format. I now + cancelled my subscription. Am i allowed to use these 6 icons in an open + source project, where the svg source would be accessible in a public + source code repository on github? I can include the a link to icon8. + + Alex 04/10/2024 + + You can use the downloaded icons in your open-source project. However, you + must inform your users that they're not allowed to use our icons as is in + their own projects. + + Manuel Brotz 04/11/2024 + + That is great! Thank you so much! I will add a disclaimer and a link to + icons8 in the source code and the readme! diff --git a/README.txt b/README.txt index 35552be..601e295 100644 --- a/README.txt +++ b/README.txt @@ -1,12 +1,12 @@ README ------ -qlZipInfo v1.2.6 +qlZipInfo v1.3 Homepage: https://github.com/srirangav/qlZipInfo - + Overview: qlZipInfo is a QuickLook generator for zip, jar, tar, @@ -22,7 +22,7 @@ Overview: Information for each file in an archive is displayed in the following format: - Icon | Filename | Size | Date Modified + Icon | Filename | Size | Permissions | Date Modified A folder icon is shown for folders / directories, a file icon is shown for regular files, and a lock icon is shown @@ -88,6 +88,11 @@ Known Issues: History: + v1.3 - modernized the generated preview to more closely + match the Finder + - added modern svg icons from icons8.com (see LICENSE.txt) + - added a column to show file permissions + - increased the size of the preview window v1.2.6 - update to Google Toolbox for Mac v.4.0.0 and libarchive 3.7.2; add support for some ipsw files diff --git a/qlZipInfo.xcodeproj/project.pbxproj b/qlZipInfo.xcodeproj/project.pbxproj index a00b831..342452d 100644 --- a/qlZipInfo.xcodeproj/project.pbxproj +++ b/qlZipInfo.xcodeproj/project.pbxproj @@ -613,7 +613,6 @@ TargetAttributes = { 26CA45D21B8461BA00B08F29 = { CreatedOnToolsVersion = 6.4; - DevelopmentTeam = CLN8R9E6QM; ProvisioningStyle = Automatic; }; }; @@ -854,11 +853,11 @@ COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; DEAD_CODE_STRIPPING = YES; - DEVELOPMENT_TEAM = CLN8R9E6QM; + DEVELOPMENT_TEAM = 4YD6U8PZLA; INFOPLIST_FILE = qlZipInfo/Info.plist; INSTALL_PATH = /Library/QuickLook; MACOSX_DEPLOYMENT_TARGET = 10.13; - MARKETING_VERSION = 1.2.6; + MARKETING_VERSION = 1.3.0; PRODUCT_BUNDLE_IDENTIFIER = "org.calalum.ranga.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -874,11 +873,11 @@ COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; DEAD_CODE_STRIPPING = YES; - DEVELOPMENT_TEAM = CLN8R9E6QM; + DEVELOPMENT_TEAM = 4YD6U8PZLA; INFOPLIST_FILE = qlZipInfo/Info.plist; INSTALL_PATH = /Library/QuickLook; MACOSX_DEPLOYMENT_TARGET = 10.13; - MARKETING_VERSION = 1.2.6; + MARKETING_VERSION = 1.3.0; PRODUCT_BUNDLE_IDENTIFIER = "org.calalum.ranga.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/qlZipInfo/GeneratePreviewForURL.h b/qlZipInfo/GeneratePreviewForURL.h index ea923ca..c924f77 100644 --- a/qlZipInfo/GeneratePreviewForURL.h +++ b/qlZipInfo/GeneratePreviewForURL.h @@ -6,8 +6,12 @@ v. 0.1.0 (07/22/2021) - initial release v. 0.2.0 (11/13/2021) - add binhex support v. 0.3.0 (08/01/2022) - add stuffit support - - Copyright (c) 2015-2022 Sriranga R. Veeraraghavan + v. 0.4.0 (04/16/2024) - Added svg icons from icons8.com. (see LICENSE.txt) + - Changed colors to more closely match the Finder. + - Contribution by Manuel Brotz + https://github.com/mbrotz/qlZipInfo + + Copyright (c) 2015-2024 Sriranga R. Veeraraghavan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -70,45 +74,53 @@ enum static const NSString *gTableHeaderName = @"Name"; static const NSString *gTableHeaderSize = @"Size"; +static const NSString *gTableHeaderMode = @"Mode"; static const NSString *gTableHeaderDate = @"Modified"; static const NSString *gTableHeaderType = @"Type"; static const NSString *gTableHeaderCreator = @"Creator"; /* darkmode styles */ -static const NSString *gDarkModeBackground = @"#232323"; -static const NSString *gDarkModeForeground = @"lightgrey"; -static const NSString *gDarkModeTableRowEvenBackgroundColor - = @"#313131"; -static const NSString *gDarkModeTableRowEvenForegroundColor - = @"white"; +static const NSString *gDarkModeBackground = @"#231D2D"; +static const NSString *gDarkModeForeground = @"#aba8ad"; +static const NSString *gDarkModeFolderColor + = @"#51C5F8"; +static const NSString *gDarkModeTableRowEvenBackground + = @"#2F2A39"; +static const NSString *gDarkModeTableRowEvenForeground + = @"#aba8ad"; static const NSString *gDarkModeTableBorderColor - = @"#232323"; + = @"#231D2D"; static const NSString *gDarkModeTableHeaderBorderColor - = @"#555555"; + = @"#403B47"; /* light mode styles */ static const NSString *gLightModeBackground = @"white"; -static const NSString *gLightModeForeground = @"black"; -static const NSString *gLightModeTableRowEvenBackgroundColor - = @"#F5F5F5"; -static const NSString *gLightModeTableRowEvenForegroundColor - = @"black"; +static const NSString *gLightModeForeground = @"#6e6b6d"; +static const NSString *gLightModeFolderColor + = @"#76D0FB"; +static const NSString *gLightModeTableRowEvenBackground + = @"#F4F5F5"; +static const NSString *gLightModeTableRowEvenForeground + = @"#6e6b6d"; static const NSString *gLightModeTableBorderColor = @"white"; static const NSString *gLightModeTableHeaderBorderColor - = @"#E7E7E7"; + = @"#DDDDDD"; + +/* SVG icons from icons8.com, see LICENSE.txt for more information. */ + +static const NSString *gFolderIcon = @""; +static const NSString *gFileIcon = @""; +static const NSString *gFileEncyrptedIcon = @""; +static const NSString *gFileLinkIcon = @""; +static const NSString *gFileSpecialIcon = @""; +static const NSString *gFileUnknownIcon = @""; -/* icons */ +/* Unicode icons */ -static const NSString *gFolderIcon = @"📁"; -static const NSString *gFileIcon = @"📄"; -static const NSString *gFileEncyrptedIcon = @"🔒"; -static const NSString *gFileLinkIcon = @"📑"; -static const NSString *gFileSpecialIcon = @"⚙"; -static const NSString *gFileUnknownIcon = @"❓"; -static const NSString *gFileAppIcon = @"✍"; -static const NSString *gFilePkgIcon = @"📦"; +static const NSString *gFileAppIcon = @"E✍"; +static const NSString *gFilePkgIcon = @"F📦"; /* unknown file name */ @@ -116,9 +128,9 @@ static const char *gFileNameUnavilable = "[Unavailable]"; static const NSString *gFileNameUnavilableStr = @"[Unavailable]"; -/* default font style - sans serif */ +/* default font style of the Finder is Lucida Grande. */ -static const NSString *gFontFace = @"sans-serif"; +static const NSString *gFontFace = @"Lucida Grande"; /* filesize abbreviations */ @@ -171,6 +183,7 @@ static int getFileSizeSpec(off_t fileSizeInBytes, fileSizeSpec_t *fileSpec); static float getCompression(off_t uncompressedSize, off_t compressedSize); +static void getPermissions(mode_t mode, char *buf); static bool formatOutputHeader(NSMutableString *qlHtml); static bool startOutputBody(NSMutableString *qlHtml); static bool endOutputBody(NSMutableString *qlHtml); diff --git a/qlZipInfo/GeneratePreviewForURL.m b/qlZipInfo/GeneratePreviewForURL.m index 8e11336..a4b85ae 100644 --- a/qlZipInfo/GeneratePreviewForURL.m +++ b/qlZipInfo/GeneratePreviewForURL.m @@ -30,8 +30,22 @@ v. 0.2.5 (10/26/2021) - add support for uu encoded archives and rpms v. 0.3.0 (11/13/2021) - add support for binhex archives v. 0.4.0 (08/01/2022) - add support for stuffit archives - - Copyright (c) 2015-2022 Sriranga R. Veeraraghavan + + v. 0.5.0 (04/16/2024) - modernized the appearance of the generated + preview, imitating the Finder more closely. + - Changed the calculation of compression ratio + to indicate an increase in filesize as a + negative percentage. + - Added a column showing a files permissions. + - Increased the read buffer for libarchive from + 10KB to 1MB to increase performance. + - Switched to using library provided functions + to activate all filters and formats supported + by libarchive. + - Contribution by Manuel Brotz + https://github.com/mbrotz/qlZipInfo + + Copyright (c) 2015-2024 Sriranga R. Veeraraghavan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -103,10 +117,15 @@ OSStatus GeneratePreviewForURL(void *thisInterface, off_t totalSize = 0; off_t totalCompressedSize = 0; off_t fileCompressedSize = 0; - bool isFolder = FALSE; + bool isFolder = false; bool isGZFile = false; + bool isLink = false; + bool isSpecial = false; + bool isEncrypted = false; + mode_t mode; + char permissions[10]; fileSizeSpec_t fileSizeSpecInZip; - + if (url == NULL) { fprintf(stderr, "qlZipInfo: ERROR: url is null\n"); @@ -207,32 +226,14 @@ file path using CFStringGetCString() b/c the file path a = archive_read_new(); - /* enable filters */ - - archive_read_support_filter_compress(a); - archive_read_support_filter_gzip(a); - archive_read_support_filter_bzip2(a); - archive_read_support_filter_xz(a); - archive_read_support_filter_uu(a); - archive_read_support_filter_rpm(a); - - /* enable archive formats */ - - archive_read_support_format_cpio(a); - archive_read_support_format_tar(a); - archive_read_support_format_zip(a); - archive_read_support_format_xar(a); - archive_read_support_format_iso9660(a); - archive_read_support_format_rar(a); - archive_read_support_format_rar5(a); - archive_read_support_format_lha(a); - archive_read_support_format_ar(a); - archive_read_support_format_7zip(a); - archive_read_support_format_cab(a); + /* enable formats/filters */ + + archive_read_support_format_all(a); + archive_read_support_filter_all(a); /* open the archive for reading */ - r = archive_read_open_filename(a, zipFileNameStr, 10240); + r = archive_read_open_filename(a, zipFileNameStr, 1048576); // blocksize 1048576 = 1MB /* return an error if the file couldn't be opened */ @@ -310,29 +311,18 @@ file path using CFStringGetCString() b/c the file path based on: http://www.w3.org/TR/html4/struct/tables.html */ - [qlHtml appendFormat: @"\n", - (gColPadding/2)]; - [qlHtml appendFormat: @"\n", - (gColFileType + gColPadding)]; - [qlHtml appendFormat: @"\n", - (gColFileName + gColPadding)]; - [qlHtml appendFormat: @"\n", - (gColFileSize + gColPadding)]; - [qlHtml appendFormat: @"\n", - (gColFileCompress + gColPadding)]; - [qlHtml appendFormat: @"\n", - (gColFileModDate + gColPadding)]; - [qlHtml appendFormat: @"\n", - (gColFileModTime + gColPadding)]; + [qlHtml appendString: @"
\n"]; /* add the table header */ - - [qlHtml appendString: @""]; - [qlHtml appendFormat: @"", + [qlHtml appendString: @""]; + [qlHtml appendString: @""]; + [qlHtml appendFormat: @"", gTableHeaderName]; - [qlHtml appendFormat: @"", + [qlHtml appendFormat: @"", gTableHeaderSize]; - [qlHtml appendFormat: @"", + [qlHtml appendFormat: @"", + gTableHeaderMode]; + [qlHtml appendFormat: @"", gTableHeaderDate]; [qlHtml appendString: @"\n"]; @@ -368,7 +358,8 @@ file path using CFStringGetCString() b/c the file path /* stop listing files if the user canceled the preview */ - if (QLPreviewRequestIsCancelled(preview)) { + if (QLPreviewRequestIsCancelled(preview)) + { break; } @@ -382,17 +373,16 @@ file path using CFStringGetCString() b/c the file path { fileNameInZip = gFileNameUnavilable; } - - if (isGZFile == true) - { - isFolder = FALSE; - } - else + + if (isGZFile == false) { - isFolder = - (archive_entry_filetype(entry) == AE_IFDIR ? TRUE : FALSE); + int fileType = archive_entry_filetype(entry); + isFolder = (fileType == AE_IFDIR ? TRUE : FALSE); + isLink = (fileType == AE_IFLNK ? TRUE : FALSE); + isSpecial = (fileType == AE_IFREG ? FALSE : TRUE); + isEncrypted = (archive_entry_is_encrypted(entry) ? TRUE : FALSE); } - + /* start the table row for this entry */ [qlHtml appendFormat: @""]; @@ -411,26 +401,25 @@ file path using CFStringGetCString() b/c the file path if (isGZFile != true) { - if (isFolder == TRUE) + if (isFolder) { qlEntryIcon = (NSString *)gFolderIcon; } - else if (archive_entry_is_encrypted(entry)) - { - qlEntryIcon = (NSString *)gFileEncyrptedIcon; - } - else if (archive_entry_filetype(entry) == AE_IFLNK) + else if (isLink) { qlEntryIcon = (NSString *)gFileLinkIcon; } - else if (archive_entry_filetype(entry) != AE_IFREG) + else if (isSpecial) { qlEntryIcon = (NSString *)gFileSpecialIcon; } + else if (isEncrypted) + { + qlEntryIcon = (NSString *)gFileEncyrptedIcon; + } } - [qlHtml appendFormat: @"", - qlEntryIcon]; + [qlHtml appendFormat: @"", qlEntryIcon]; /* output the filename with HTML escaping */ @@ -441,22 +430,32 @@ file path using CFStringGetCString() b/c the file path { fileNameInZipEscaped = (NSString *)gFileNameUnavilableStr; } + + /* + insert zero width white space characters to improve word breaking behavior + based on: https://stackoverflow.com/questions/15841109/optional-line-breaking-html-entity-that-is-always-invisible + */ + fileNameInZipEscaped = [fileNameInZipEscaped stringByReplacingOccurrencesOfString:@"/" withString:@"/​"]; - [qlHtml appendString: @"", - fileNameInZipEscaped]; - + NSString* nameClass = @"file"; + if (isFolder) + { + nameClass = @"folder"; + } else if (isLink) + { + nameClass = @"link"; + } + [qlHtml appendFormat: @"", nameClass, fileNameInZipEscaped]; + /* - if the entry is a folder, don't print out its size, + if the entry is a folder or a symbolic link, don't print out its size, which is always 0 */ - - if (isFolder == TRUE) { + if (isFolder || isLink) + { [qlHtml appendString: - @""]; + @""]; } else { - if (isGZFile == true) { fileCompressedSize = getGZExpandedFileSize(zipFileNameStr); @@ -478,16 +477,18 @@ file path using CFStringGetCString() b/c the file path /* print out the file's size in B, K, M, G, or T */ [qlHtml appendFormat: - @"", + @"", fileSizeSpecInZip.size, fileSizeSpecInZip.spec]; - - [qlHtml appendString: - @""]; - - //[qlHtml appendString: @""]; } + /* output the files permissions */ + + mode = archive_entry_perm(entry); + getPermissions(mode, permissions); + + [qlHtml appendFormat: @"", permissions]; + /* print out the modified date and time for the file in the local format. based on: https://stackoverflow.com/questions/9676435/how-do-i-format-the-current-date-for-the-users-locale @@ -497,10 +498,12 @@ file path using CFStringGetCString() b/c the file path /* init the date string (if needed) and clear it */ - if (fileDateStringInZip == nil) { + if (fileDateStringInZip == nil) + { fileDateStringInZip = [[NSMutableString alloc] initWithString: @""]; - } else { + } else + { [fileDateStringInZip setString: @""]; } @@ -509,14 +512,16 @@ file path using CFStringGetCString() b/c the file path date, as stored in the zip file */ - if (fileDateFormatterInZip == nil) { + if (fileDateFormatterInZip == nil) + { fileDateFormatterInZip = [[NSDateFormatter alloc] init]; [fileDateFormatterInZip setDateFormat: @"MM-dd-yy HH:mm"]; } /* initialize the date formatter for the local date format */ - if (fileLocalDateFormatterInZip == nil) { + if (fileLocalDateFormatterInZip == nil) + { fileLocalDateFormatterInZip = [[NSDateFormatter alloc] init]; } @@ -533,7 +538,8 @@ file path using CFStringGetCString() b/c the file path use a default format */ - if (fileDateInZip != nil) { + if (fileDateInZip != nil) + { /* Make sure the days and months are zero prefixed. @@ -550,18 +556,19 @@ file path using CFStringGetCString() b/c the file path setLocalizedDateFormatFromTemplate: @"MM-dd-yyyy"]; [qlHtml appendFormat: - @"", + @"", + @" %@", [fileLocalDateFormatterInZip stringFromDate: fileDateInZip]]; - } else { + } else + { [qlHtml appendFormat: - @""]; + @""]; } /* close the row */ @@ -594,16 +601,18 @@ file path using CFStringGetCString() b/c the file path [# files] [expanded size / compressed size] [% compression] */ - [qlHtml appendString: @"\n\n"]; + [qlHtml appendString: @"\n\n"]; /* print out the total number of files in the zip file */ fileCount = archive_file_count(a); [qlHtml appendString: - @""]; + [qlHtml appendString: + @"\n", + [qlHtml appendFormat: @"%lu item%s", fileCount, (fileCount > 1 ? "s" : "")]; @@ -618,9 +627,7 @@ file path using CFStringGetCString() b/c the file path /* print out the zip file's total size in B, K, M, G, or T */ - [qlHtml appendString: - @""]; - [qlHtml appendString: - @"\n"]; - /* close the summary row */ [qlHtml appendString:@"\n"]; /* close the table body */ - [qlHtml appendString: @"\n"]; + [qlHtml appendString: @"\n"]; /* close the table */ [qlHtml appendString: @"
%@
 %@%@%@%@%@%@
%@%@
%@
%@
--
 %-.1f %-1s%-.1f %-1s %s%@%@", [fileLocalDateFormatterInZip stringFromDate: fileDateInZip]]; [fileLocalDateFormatterInZip setLocalizedDateFormatFromTemplate: @"HH:mm"]; [qlHtml appendFormat: - @"%@  
"]; + @" "]; - [qlHtml appendFormat: @"%lu item%s"]; - [qlHtml appendFormat: @"%-.1f %-1s", + [qlHtml appendFormat: @" | %-.1f %-1s", fileSizeSpecInZip.size, fileSizeSpecInZip.spec]; @@ -639,7 +646,7 @@ file path using CFStringGetCString() b/c the file path getFileSizeSpec(totalCompressedSize, &fileSizeSpecInZip); - [qlHtml appendFormat: @" / %-.1f %-1s", + [qlHtml appendFormat: @" | %-.1f %-1s", fileSizeSpecInZip.size, fileSizeSpecInZip.spec]; } @@ -649,28 +656,24 @@ file path using CFStringGetCString() b/c the file path if (totalSize > 0 && totalCompressedSize > 0) { - [qlHtml appendFormat: @" (%3.0f%%)", - getCompression(totalSize, - totalCompressedSize)]; + [qlHtml appendFormat: @" | %.0f%%", + getCompression(totalSize, totalCompressedSize)]; } [qlHtml appendString: @"
 
\n"]; - + /* close the html */ endOutputBody(qlHtml); @@ -832,14 +835,14 @@ file path using CFStringGetCString() b/c the file path /* add the table header */ - [qlHtml appendString: @""]; - [qlHtml appendFormat: @"%@", + [qlHtml appendString: @""]; + [qlHtml appendFormat: @"%@", gTableHeaderName]; - [qlHtml appendFormat: @"%@", + [qlHtml appendFormat: @"%@", gTableHeaderSize]; - [qlHtml appendFormat: @"%@", + [qlHtml appendFormat: @"%@", gTableHeaderType]; - [qlHtml appendFormat: @"%@", + [qlHtml appendFormat: @"%@", gTableHeaderCreator]; [qlHtml appendString: @"\n"]; @@ -1099,10 +1102,10 @@ file path using CFStringGetCString() b/c the file path /* add the table header */ - [qlHtml appendString: @""]; - [qlHtml appendFormat: @"%@", + [qlHtml appendString: @""]; + [qlHtml appendFormat: @"%@", gTableHeaderName]; - [qlHtml appendFormat: @"%@", + [qlHtml appendFormat: @"%@", gTableHeaderSize]; [qlHtml appendFormat: @"%@", gTableHeaderDate]; @@ -1444,130 +1447,149 @@ static bool formatOutputHeader(NSMutableString *qlHtml) [qlHtml appendString: @"@media (prefers-color-scheme: dark) { "]; - /* set darkmode background and foreground colors */ + /* set darkmode background and foreground colors */ - [qlHtml appendFormat: - @"body { background-color: %@; color: %@; }\n", - gDarkModeBackground, - gDarkModeForeground]; + [qlHtml appendFormat: + @"body { background-color: %@; color: %@; }\n", + gDarkModeBackground, + gDarkModeForeground]; - /* - put a border around the table only, but make it the same color - as the background to better match the BigSur finder - based on: https://stackoverflow.com/questions/10131729/removing-border-from-table-cell + /* + put a border around the table only, but make it the same color + as the background to better match the BigSur finder + based on: https://stackoverflow.com/questions/10131729/removing-border-from-table-cell + */ + + [qlHtml appendFormat: + @"table { border: %dpx solid %@; }\n", + gBorder, + gDarkModeTableBorderColor]; + + [qlHtml appendFormat: + @"th { border-bottom: %dpx solid %@; background-color: %@ }\n", + gBorder, + gDarkModeTableHeaderBorderColor, + gDarkModeBackground]; + + /* colors for the even rows */ + + [qlHtml appendFormat: + @"tr:nth-child(even) { background-color: %@ ; color: %@; }\n", + gDarkModeTableRowEvenBackground, + gDarkModeTableRowEvenForeground]; + + /* top border for table cells in the summary row */ + + [qlHtml appendFormat: + @"td.footer { border-top: %dpx solid %@; }\n", + gBorder, + gDarkModeTableHeaderBorderColor]; + + /* icon colors */ + [qlHtml appendFormat: @"svg > g { fill: %@; }\n", gDarkModeForeground]; + [qlHtml appendFormat: @"svg > g.folder-icon { fill: %@; }\n", gDarkModeFolderColor]; + + /* close darkmode styles */ - set y-direction overflow to auto to support a fixed header - based on: - https://www.w3docs.com/snippets/html/how-to-create-a-table-with-a-fixed-header-and-scrollable-body.html - https://stackoverflow.com/questions/50361698/border-style-do-not-work-with-sticky-position-element - */ + [qlHtml appendString: @"}\n"]; + + /* light mode styles */ - [qlHtml appendFormat: @"table { width: 100%%; border: %dpx solid %@; ", - gBorder, - gDarkModeTableBorderColor]; - [qlHtml appendString: @"table-layout: fixed; overflow-y: auto;"]; [qlHtml appendString: - @"border-collapse: separate; border-spacing: 0; }\n"]; + @"@media (prefers-color-scheme: light) { "]; - /* set the darkmode colors for the even rows of the table */ + /* light mode background and foreground colors */ - [qlHtml appendFormat: - @"tr:nth-child(even) { background-color: %@ ; color: %@; }\n", - gDarkModeTableRowEvenBackgroundColor, - gDarkModeTableRowEvenForegroundColor]; + [qlHtml appendFormat: + @"body { background-color: %@; color: %@; }\n", + gLightModeBackground, + gLightModeForeground]; - /* - add a bottom border for the header row items only, to better - match the BigSur finder, and make the header fixed. - based on: - https://www.w3docs.com/snippets/html/how-to-create-a-table-with-a-fixed-header-and-scrollable-body.html - */ + /* + put a border around the table only, but make it the same color + as the background to better match the BigSur finder + based on: https://stackoverflow.com/questions/10131729/removing-border-from-table-cell + */ + + [qlHtml appendFormat: + @"table { border: %dpx solid %@; }\n", + gBorder, + gLightModeTableBorderColor]; - [qlHtml appendFormat: - @"th { border-bottom: %dpx solid %@; ", - gBorder, - gDarkModeTableHeaderBorderColor]; - [qlHtml appendString: @" position: sticky; position: -webkit-sticky; "]; - [qlHtml appendFormat: @"top: 0; z-index: 3; background-color: %@ ;}\n", - gDarkModeBackground]; + [qlHtml appendFormat: + @"th { border-bottom: %dpx solid %@; background-color: %@ }\n", + gBorder, + gLightModeTableHeaderBorderColor, + gLightModeBackground]; - /* disable internal borders for table cells */ + /* colors for the even rows */ - [qlHtml appendString: @"td { border: none; z-index: 1; }\n"]; + [qlHtml appendFormat: + @"tr:nth-child(even) { background-color: %@ ; color: %@; }\n", + gLightModeTableRowEvenBackground, + gLightModeTableRowEvenForeground]; - /* top border for table cells in the summary row */ + /* top border for table cells in the summary row */ - [qlHtml appendFormat: - @"td.border-top { border-top: %dpx solid %@; }\n", - gBorder, - gDarkModeTableHeaderBorderColor]; - - /* close darkmode styles */ + [qlHtml appendFormat: + @"td.footer { border-top: %dpx solid %@; }\n", + gBorder, + gLightModeTableHeaderBorderColor]; - [qlHtml appendString: @"}\n"]; + /* icon colors */ + [qlHtml appendFormat: @"svg > g { fill: %@; }\n", gLightModeForeground]; + [qlHtml appendFormat: @"svg > g.folder-icon { fill: %@; }\n", gLightModeFolderColor]; - /* light mode styles */ + /* close light mode styles */ - [qlHtml appendString: - @"@media (prefers-color-scheme: light) { "]; - - /* light mode background and foreground colors */ - - [qlHtml appendFormat: - @"body { background-color: %@; color: %@; }\n", - gLightModeBackground, - gLightModeForeground]; + [qlHtml appendString: @"}\n"]; /* - put a border around the table only - based on: https://stackoverflow.com/questions/10131729/removing-border-from-table-cell + make the header fixed. + based on: + https://www.w3docs.com/snippets/html/how-to-create-a-table-with-a-fixed-header-and-scrollable-body.html */ + [qlHtml appendString: @"th { position: sticky; position: -webkit-sticky; top: 0; z-index: 3; }\n"]; - [qlHtml appendFormat: @"table { width: 100%%; border: %dpx solid %@; ", - gBorder, - gLightModeTableBorderColor]; + /* + set y-direction overflow to auto to support a fixed header + based on: + https://www.w3docs.com/snippets/html/how-to-create-a-table-with-a-fixed-header-and-scrollable-body.html + https://stackoverflow.com/questions/50361698/border-style-do-not-work-with-sticky-position-element + */ + [qlHtml appendString: @"table {"]; + [qlHtml appendString: @"width: 100%;"]; [qlHtml appendString: @"table-layout: fixed; overflow-y: auto;"]; - [qlHtml appendString: - @"border-collapse: separate; border-spacing: 0; }\n"]; - - /* make the header sticky */ - - [qlHtml appendFormat: @"th { border-bottom: %dpx solid %@; ", - gBorder, - gLightModeTableHeaderBorderColor]; - [qlHtml appendString: @" position: sticky; position: -webkit-sticky; "]; - [qlHtml appendFormat: @"top: 0; z-index: 3; background-color: %@ ;}\n", - gLightModeBackground]; - - /* colors for the even rows */ + [qlHtml appendString: @"border-collapse: separate; border-spacing: 0;"]; + [qlHtml appendString: @"}\n"]; - [qlHtml appendFormat: - @"tr:nth-child(even) { background-color: %@ ; color: %@; }\n", - gLightModeTableRowEvenBackgroundColor, - gLightModeTableRowEvenForegroundColor]; + /* font settings */ + + [qlHtml appendString: @"body, td, th { font-family: \"Lucida Grande\"; font-size: 11px; }\n"]; /* no internal borders */ [qlHtml appendString: @"td { border: none; z-index: 1; }\n"]; - /* top border for table cells in the summary row */ - - [qlHtml appendFormat: - @"td.border-top { border-top: %dpx solid %@; }\n", - gBorder, - gLightModeTableHeaderBorderColor]; - - /* close light mode styles */ - - [qlHtml appendString: @"}\n"]; - /* style for preventing wrapping in table cells, based on: https://stackoverflow.com/questions/300220/how-to-prevent-text-in-a-table-cell-from-wrapping */ [qlHtml appendString: @".nowrap { white-space: nowrap; }\n"]; - + + [qlHtml appendFormat: @".icon { width: %dpx; height: %dpx; }\n", gIconWidth, gIconHeight]; + + [qlHtml appendString: @".name { word-wrap: break-word; text-align: left; width: 70%; }\n"]; + [qlHtml appendString: @".file { }\n"]; + [qlHtml appendString: @".folder { }\n"]; + [qlHtml appendString: @".link { font-style: italic; }\n"]; + [qlHtml appendString: @".size { white-space: nowrap; text-align: right; width: 10%; }\n"]; + [qlHtml appendString: @".mode { white-space: nowrap; text-align: right; width: 65px; }\n"]; + [qlHtml appendString: @".date { white-space: nowrap; text-align: right; width: 110px; }\n"]; + + [qlHtml appendString: @"td.footer { white-space: nowrap; text-align: left; }\n"]; + /* close the style sheet */ [qlHtml appendString: @"\n"]; @@ -1588,8 +1610,7 @@ static bool startOutputBody(NSMutableString *qlHtml) } [qlHtml appendFormat: @"\n"]; - [qlHtml appendFormat: @"\n", gFontFace]; - + return true; } @@ -1599,7 +1620,7 @@ static bool endOutputBody(NSMutableString *qlHtml) return false; } - [qlHtml appendString: @"\n\n\n"]; + [qlHtml appendString: @"\n\n"]; return true; } @@ -1722,22 +1743,38 @@ static int getFileSizeSpec(off_t fileSizeInBytes, static float getCompression(off_t uncompressedSize, off_t compressedSize) { - Float64 compression = 0.0; - - if (uncompressedSize > 0) + if (compressedSize < 0 || uncompressedSize < 0) { - compression = uncompressedSize / (Float64)(compressedSize); - if (compression >= 1.0) + return 0.0; + } + if (compressedSize < uncompressedSize) + { + Float64 ratio = compressedSize / (Float64)(uncompressedSize); + return 100.0 * (1.0 - ratio); + } else if (compressedSize > uncompressedSize) + { + Float64 ratio = compressedSize / (Float64)(uncompressedSize); + Float64 bloat = -100.0 * (ratio - 1.0); + if (bloat < 1.0) { - compression = 1.0 / compression; + return 0.0; } - compression = 100.0 * (1.0 - compression); + return bloat; } + return 0.0; +} - if (compression <= 0 || compression >= 99.9) - { - compression = 0.0; - } +/* + convert permission bits to string + based on: https://jameshfisher.com/2017/02/24/what-is-mode_t/ + */ - return compression; +// buf must have at least 10 bytes +static void getPermissions(mode_t mode, char *buf) +{ + const char chars[] = "rwxrwxrwx"; + for (size_t i = 0; i < 9; i++) { + buf[i] = (mode & (1 << (8-i))) ? chars[i] : '-'; + } + buf[9] = '\0'; } diff --git a/qlZipInfo/Info.plist b/qlZipInfo/Info.plist index b918784..67c60b9 100644 --- a/qlZipInfo/Info.plist +++ b/qlZipInfo/Info.plist @@ -82,9 +82,9 @@ QLNeedsToBeRunInMainThread QLPreviewHeight - 320 + 800 QLPreviewWidth - 640 + 1000 QLSupportsConcurrentRequests QLThumbnailMinimumSize From aedfdc82e658754f0e082fb0e3a67259d524a700 Mon Sep 17 00:00:00 2001 From: Manuel Brotz Date: Tue, 16 Apr 2024 10:59:56 +0200 Subject: [PATCH 02/10] updated copyright info --- qlZipInfo/Info.plist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qlZipInfo/Info.plist b/qlZipInfo/Info.plist index 67c60b9..d28fb1b 100644 --- a/qlZipInfo/Info.plist +++ b/qlZipInfo/Info.plist @@ -78,7 +78,7 @@ CFPlugInUnloadFunction NSHumanReadableCopyright - Portions Copyright © 2015-2022 Sriranga Veeraraghavan. All rights reserved. + Portions Copyright © 2015-2024 Sriranga Veeraraghavan. All rights reserved. QLNeedsToBeRunInMainThread QLPreviewHeight From 4b07f0ad72e74982cbcede4da547ecf085e12bda Mon Sep 17 00:00:00 2001 From: Manuel Brotz Date: Tue, 16 Apr 2024 11:01:31 +0200 Subject: [PATCH 03/10] enabled support for universal binary --- qlZipInfo.xcodeproj/project.pbxproj | 1 + 1 file changed, 1 insertion(+) diff --git a/qlZipInfo.xcodeproj/project.pbxproj b/qlZipInfo.xcodeproj/project.pbxproj index 342452d..9c59878 100644 --- a/qlZipInfo.xcodeproj/project.pbxproj +++ b/qlZipInfo.xcodeproj/project.pbxproj @@ -858,6 +858,7 @@ INSTALL_PATH = /Library/QuickLook; MACOSX_DEPLOYMENT_TARGET = 10.13; MARKETING_VERSION = 1.3.0; + ONLY_ACTIVE_ARCH = NO; PRODUCT_BUNDLE_IDENTIFIER = "org.calalum.ranga.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; From 7953780eccf8f49298bfd4fa0b9612e6fa0aeb35 Mon Sep 17 00:00:00 2001 From: Manuel Brotz Date: Tue, 16 Apr 2024 11:10:26 +0200 Subject: [PATCH 04/10] bumped version to 1.3 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ae3c3af..d616970 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ PROJNAME = qlZipInfo PROJEXT = qlgenerator -PROJVERS = 1.2.6 +PROJVERS = 1.3 BUNDLEID = "org.calalum.ranga.$(PROJNAME)" # extra files to include in the package From af0deaee4252dff7c77e5dba8e4d287bdb802125 Mon Sep 17 00:00:00 2001 From: Manuel Brotz Date: Fri, 3 May 2024 09:15:00 +0200 Subject: [PATCH 05/10] Reset development team id. --- qlZipInfo.xcodeproj/project.pbxproj | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/qlZipInfo.xcodeproj/project.pbxproj b/qlZipInfo.xcodeproj/project.pbxproj index 9c59878..210130f 100644 --- a/qlZipInfo.xcodeproj/project.pbxproj +++ b/qlZipInfo.xcodeproj/project.pbxproj @@ -613,6 +613,7 @@ TargetAttributes = { 26CA45D21B8461BA00B08F29 = { CreatedOnToolsVersion = 6.4; + DevelopmentTeam = CLN8R9E6QM; ProvisioningStyle = Automatic; }; }; @@ -853,7 +854,7 @@ COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; DEAD_CODE_STRIPPING = YES; - DEVELOPMENT_TEAM = 4YD6U8PZLA; + DEVELOPMENT_TEAM = CLN8R9E6QM; INFOPLIST_FILE = qlZipInfo/Info.plist; INSTALL_PATH = /Library/QuickLook; MACOSX_DEPLOYMENT_TARGET = 10.13; @@ -874,7 +875,7 @@ COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; DEAD_CODE_STRIPPING = YES; - DEVELOPMENT_TEAM = 4YD6U8PZLA; + DEVELOPMENT_TEAM = CLN8R9E6QM; INFOPLIST_FILE = qlZipInfo/Info.plist; INSTALL_PATH = /Library/QuickLook; MACOSX_DEPLOYMENT_TARGET = 10.13; From 376a98c064ac9ed825c6117d3a5a70529d0ab6f6 Mon Sep 17 00:00:00 2001 From: Manuel Brotz Date: Tue, 16 Apr 2024 10:29:40 +0200 Subject: [PATCH 06/10] modernized the layout and appearance to more closely match the Finder --- LICENSE.txt | 32 +- README.txt | 12 +- qlZipInfo.xcodeproj/project.pbxproj | 10 +- qlZipInfo/GeneratePreviewForURL.h | 67 ++-- qlZipInfo/GeneratePreviewForURL.m | 475 +++++++++++++++------------- qlZipInfo/Info.plist | 4 +- 6 files changed, 341 insertions(+), 259 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index d305b61..769e8ad 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,7 +1,7 @@ qlZipInfo Licenses ------------------ -Portions Copyright (c) 2015-2022 Sriranga Veeraraghavan . +Portions Copyright (c) 2015-2024 Sriranga Veeraraghavan . All rights reserved. For those portions Copyright (c) Sriranga Veeraraghavan, the following license @@ -165,3 +165,33 @@ lzma: 7-Zip , which has a modified version of the public domain SHA-256 code found from Crypto++ . The SHA-256 code in Crypto++ was written by Kevin Springle and Wei Dai. + +SVG icons from icons8.com: + + Contribution by Manuel Brotz, https://github.com/mbrotz/qlZipInfo + + I asked for and received permission from icons8 to use their icons in this + project. Please note that these icons were purchased using a subscription + to icons8 and you are not allowed to use them in your own projects whithout + purchasing them from icons8 yourself! + + This question was posted to the questions section at + https://icons8.com/pricing on 04/09/2024. + + Manuel Brotz 04/09/2024 + + Hi. I paid for one month and downloaded 6 icons in svg format. I now + cancelled my subscription. Am i allowed to use these 6 icons in an open + source project, where the svg source would be accessible in a public + source code repository on github? I can include the a link to icon8. + + Alex 04/10/2024 + + You can use the downloaded icons in your open-source project. However, you + must inform your users that they're not allowed to use our icons as is in + their own projects. + + Manuel Brotz 04/11/2024 + + That is great! Thank you so much! I will add a disclaimer and a link to + icons8 in the source code and the readme! diff --git a/README.txt b/README.txt index 45bf43f..601e295 100644 --- a/README.txt +++ b/README.txt @@ -1,12 +1,12 @@ README ------ -qlZipInfo v1.2.7 +qlZipInfo v1.3 Homepage: https://github.com/srirangav/qlZipInfo - + Overview: qlZipInfo is a QuickLook generator for zip, jar, tar, @@ -22,7 +22,7 @@ Overview: Information for each file in an archive is displayed in the following format: - Icon | Filename | Size | Date Modified + Icon | Filename | Size | Permissions | Date Modified A folder icon is shown for folders / directories, a file icon is shown for regular files, and a lock icon is shown @@ -88,7 +88,11 @@ Known Issues: History: - v1.2.7 - update to libarchive 3.7.4 + v1.3 - modernized the generated preview to more closely + match the Finder + - added modern svg icons from icons8.com (see LICENSE.txt) + - added a column to show file permissions + - increased the size of the preview window v1.2.6 - update to Google Toolbox for Mac v.4.0.0 and libarchive 3.7.2; add support for some ipsw files diff --git a/qlZipInfo.xcodeproj/project.pbxproj b/qlZipInfo.xcodeproj/project.pbxproj index 7d641aa..342452d 100644 --- a/qlZipInfo.xcodeproj/project.pbxproj +++ b/qlZipInfo.xcodeproj/project.pbxproj @@ -613,7 +613,6 @@ TargetAttributes = { 26CA45D21B8461BA00B08F29 = { CreatedOnToolsVersion = 6.4; - DevelopmentTeam = CLN8R9E6QM; ProvisioningStyle = Automatic; }; }; @@ -854,11 +853,11 @@ COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; DEAD_CODE_STRIPPING = YES; - DEVELOPMENT_TEAM = CLN8R9E6QM; + DEVELOPMENT_TEAM = 4YD6U8PZLA; INFOPLIST_FILE = qlZipInfo/Info.plist; INSTALL_PATH = /Library/QuickLook; MACOSX_DEPLOYMENT_TARGET = 10.13; - MARKETING_VERSION = 1.2.7; + MARKETING_VERSION = 1.3.0; PRODUCT_BUNDLE_IDENTIFIER = "org.calalum.ranga.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -874,12 +873,11 @@ COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; DEAD_CODE_STRIPPING = YES; - DEVELOPMENT_TEAM = CLN8R9E6QM; + DEVELOPMENT_TEAM = 4YD6U8PZLA; INFOPLIST_FILE = qlZipInfo/Info.plist; INSTALL_PATH = /Library/QuickLook; MACOSX_DEPLOYMENT_TARGET = 10.13; - MARKETING_VERSION = 1.2.7; - ONLY_ACTIVE_ARCH = NO; + MARKETING_VERSION = 1.3.0; PRODUCT_BUNDLE_IDENTIFIER = "org.calalum.ranga.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/qlZipInfo/GeneratePreviewForURL.h b/qlZipInfo/GeneratePreviewForURL.h index ea923ca..c924f77 100644 --- a/qlZipInfo/GeneratePreviewForURL.h +++ b/qlZipInfo/GeneratePreviewForURL.h @@ -6,8 +6,12 @@ v. 0.1.0 (07/22/2021) - initial release v. 0.2.0 (11/13/2021) - add binhex support v. 0.3.0 (08/01/2022) - add stuffit support - - Copyright (c) 2015-2022 Sriranga R. Veeraraghavan + v. 0.4.0 (04/16/2024) - Added svg icons from icons8.com. (see LICENSE.txt) + - Changed colors to more closely match the Finder. + - Contribution by Manuel Brotz + https://github.com/mbrotz/qlZipInfo + + Copyright (c) 2015-2024 Sriranga R. Veeraraghavan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -70,45 +74,53 @@ enum static const NSString *gTableHeaderName = @"Name"; static const NSString *gTableHeaderSize = @"Size"; +static const NSString *gTableHeaderMode = @"Mode"; static const NSString *gTableHeaderDate = @"Modified"; static const NSString *gTableHeaderType = @"Type"; static const NSString *gTableHeaderCreator = @"Creator"; /* darkmode styles */ -static const NSString *gDarkModeBackground = @"#232323"; -static const NSString *gDarkModeForeground = @"lightgrey"; -static const NSString *gDarkModeTableRowEvenBackgroundColor - = @"#313131"; -static const NSString *gDarkModeTableRowEvenForegroundColor - = @"white"; +static const NSString *gDarkModeBackground = @"#231D2D"; +static const NSString *gDarkModeForeground = @"#aba8ad"; +static const NSString *gDarkModeFolderColor + = @"#51C5F8"; +static const NSString *gDarkModeTableRowEvenBackground + = @"#2F2A39"; +static const NSString *gDarkModeTableRowEvenForeground + = @"#aba8ad"; static const NSString *gDarkModeTableBorderColor - = @"#232323"; + = @"#231D2D"; static const NSString *gDarkModeTableHeaderBorderColor - = @"#555555"; + = @"#403B47"; /* light mode styles */ static const NSString *gLightModeBackground = @"white"; -static const NSString *gLightModeForeground = @"black"; -static const NSString *gLightModeTableRowEvenBackgroundColor - = @"#F5F5F5"; -static const NSString *gLightModeTableRowEvenForegroundColor - = @"black"; +static const NSString *gLightModeForeground = @"#6e6b6d"; +static const NSString *gLightModeFolderColor + = @"#76D0FB"; +static const NSString *gLightModeTableRowEvenBackground + = @"#F4F5F5"; +static const NSString *gLightModeTableRowEvenForeground + = @"#6e6b6d"; static const NSString *gLightModeTableBorderColor = @"white"; static const NSString *gLightModeTableHeaderBorderColor - = @"#E7E7E7"; + = @"#DDDDDD"; + +/* SVG icons from icons8.com, see LICENSE.txt for more information. */ + +static const NSString *gFolderIcon = @""; +static const NSString *gFileIcon = @""; +static const NSString *gFileEncyrptedIcon = @""; +static const NSString *gFileLinkIcon = @""; +static const NSString *gFileSpecialIcon = @""; +static const NSString *gFileUnknownIcon = @""; -/* icons */ +/* Unicode icons */ -static const NSString *gFolderIcon = @"📁"; -static const NSString *gFileIcon = @"📄"; -static const NSString *gFileEncyrptedIcon = @"🔒"; -static const NSString *gFileLinkIcon = @"📑"; -static const NSString *gFileSpecialIcon = @"⚙"; -static const NSString *gFileUnknownIcon = @"❓"; -static const NSString *gFileAppIcon = @"✍"; -static const NSString *gFilePkgIcon = @"📦"; +static const NSString *gFileAppIcon = @"E✍"; +static const NSString *gFilePkgIcon = @"F📦"; /* unknown file name */ @@ -116,9 +128,9 @@ static const char *gFileNameUnavilable = "[Unavailable]"; static const NSString *gFileNameUnavilableStr = @"[Unavailable]"; -/* default font style - sans serif */ +/* default font style of the Finder is Lucida Grande. */ -static const NSString *gFontFace = @"sans-serif"; +static const NSString *gFontFace = @"Lucida Grande"; /* filesize abbreviations */ @@ -171,6 +183,7 @@ static int getFileSizeSpec(off_t fileSizeInBytes, fileSizeSpec_t *fileSpec); static float getCompression(off_t uncompressedSize, off_t compressedSize); +static void getPermissions(mode_t mode, char *buf); static bool formatOutputHeader(NSMutableString *qlHtml); static bool startOutputBody(NSMutableString *qlHtml); static bool endOutputBody(NSMutableString *qlHtml); diff --git a/qlZipInfo/GeneratePreviewForURL.m b/qlZipInfo/GeneratePreviewForURL.m index 8e11336..a4b85ae 100644 --- a/qlZipInfo/GeneratePreviewForURL.m +++ b/qlZipInfo/GeneratePreviewForURL.m @@ -30,8 +30,22 @@ v. 0.2.5 (10/26/2021) - add support for uu encoded archives and rpms v. 0.3.0 (11/13/2021) - add support for binhex archives v. 0.4.0 (08/01/2022) - add support for stuffit archives - - Copyright (c) 2015-2022 Sriranga R. Veeraraghavan + + v. 0.5.0 (04/16/2024) - modernized the appearance of the generated + preview, imitating the Finder more closely. + - Changed the calculation of compression ratio + to indicate an increase in filesize as a + negative percentage. + - Added a column showing a files permissions. + - Increased the read buffer for libarchive from + 10KB to 1MB to increase performance. + - Switched to using library provided functions + to activate all filters and formats supported + by libarchive. + - Contribution by Manuel Brotz + https://github.com/mbrotz/qlZipInfo + + Copyright (c) 2015-2024 Sriranga R. Veeraraghavan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -103,10 +117,15 @@ OSStatus GeneratePreviewForURL(void *thisInterface, off_t totalSize = 0; off_t totalCompressedSize = 0; off_t fileCompressedSize = 0; - bool isFolder = FALSE; + bool isFolder = false; bool isGZFile = false; + bool isLink = false; + bool isSpecial = false; + bool isEncrypted = false; + mode_t mode; + char permissions[10]; fileSizeSpec_t fileSizeSpecInZip; - + if (url == NULL) { fprintf(stderr, "qlZipInfo: ERROR: url is null\n"); @@ -207,32 +226,14 @@ file path using CFStringGetCString() b/c the file path a = archive_read_new(); - /* enable filters */ - - archive_read_support_filter_compress(a); - archive_read_support_filter_gzip(a); - archive_read_support_filter_bzip2(a); - archive_read_support_filter_xz(a); - archive_read_support_filter_uu(a); - archive_read_support_filter_rpm(a); - - /* enable archive formats */ - - archive_read_support_format_cpio(a); - archive_read_support_format_tar(a); - archive_read_support_format_zip(a); - archive_read_support_format_xar(a); - archive_read_support_format_iso9660(a); - archive_read_support_format_rar(a); - archive_read_support_format_rar5(a); - archive_read_support_format_lha(a); - archive_read_support_format_ar(a); - archive_read_support_format_7zip(a); - archive_read_support_format_cab(a); + /* enable formats/filters */ + + archive_read_support_format_all(a); + archive_read_support_filter_all(a); /* open the archive for reading */ - r = archive_read_open_filename(a, zipFileNameStr, 10240); + r = archive_read_open_filename(a, zipFileNameStr, 1048576); // blocksize 1048576 = 1MB /* return an error if the file couldn't be opened */ @@ -310,29 +311,18 @@ file path using CFStringGetCString() b/c the file path based on: http://www.w3.org/TR/html4/struct/tables.html */ - [qlHtml appendFormat: @"\n", - (gColPadding/2)]; - [qlHtml appendFormat: @"\n", - (gColFileType + gColPadding)]; - [qlHtml appendFormat: @"\n", - (gColFileName + gColPadding)]; - [qlHtml appendFormat: @"\n", - (gColFileSize + gColPadding)]; - [qlHtml appendFormat: @"\n", - (gColFileCompress + gColPadding)]; - [qlHtml appendFormat: @"\n", - (gColFileModDate + gColPadding)]; - [qlHtml appendFormat: @"\n", - (gColFileModTime + gColPadding)]; + [qlHtml appendString: @"
\n"]; /* add the table header */ - - [qlHtml appendString: @""]; - [qlHtml appendFormat: @"", + [qlHtml appendString: @""]; + [qlHtml appendString: @""]; + [qlHtml appendFormat: @"", gTableHeaderName]; - [qlHtml appendFormat: @"", + [qlHtml appendFormat: @"", gTableHeaderSize]; - [qlHtml appendFormat: @"", + [qlHtml appendFormat: @"", + gTableHeaderMode]; + [qlHtml appendFormat: @"", gTableHeaderDate]; [qlHtml appendString: @"\n"]; @@ -368,7 +358,8 @@ file path using CFStringGetCString() b/c the file path /* stop listing files if the user canceled the preview */ - if (QLPreviewRequestIsCancelled(preview)) { + if (QLPreviewRequestIsCancelled(preview)) + { break; } @@ -382,17 +373,16 @@ file path using CFStringGetCString() b/c the file path { fileNameInZip = gFileNameUnavilable; } - - if (isGZFile == true) - { - isFolder = FALSE; - } - else + + if (isGZFile == false) { - isFolder = - (archive_entry_filetype(entry) == AE_IFDIR ? TRUE : FALSE); + int fileType = archive_entry_filetype(entry); + isFolder = (fileType == AE_IFDIR ? TRUE : FALSE); + isLink = (fileType == AE_IFLNK ? TRUE : FALSE); + isSpecial = (fileType == AE_IFREG ? FALSE : TRUE); + isEncrypted = (archive_entry_is_encrypted(entry) ? TRUE : FALSE); } - + /* start the table row for this entry */ [qlHtml appendFormat: @""]; @@ -411,26 +401,25 @@ file path using CFStringGetCString() b/c the file path if (isGZFile != true) { - if (isFolder == TRUE) + if (isFolder) { qlEntryIcon = (NSString *)gFolderIcon; } - else if (archive_entry_is_encrypted(entry)) - { - qlEntryIcon = (NSString *)gFileEncyrptedIcon; - } - else if (archive_entry_filetype(entry) == AE_IFLNK) + else if (isLink) { qlEntryIcon = (NSString *)gFileLinkIcon; } - else if (archive_entry_filetype(entry) != AE_IFREG) + else if (isSpecial) { qlEntryIcon = (NSString *)gFileSpecialIcon; } + else if (isEncrypted) + { + qlEntryIcon = (NSString *)gFileEncyrptedIcon; + } } - [qlHtml appendFormat: @"", - qlEntryIcon]; + [qlHtml appendFormat: @"", qlEntryIcon]; /* output the filename with HTML escaping */ @@ -441,22 +430,32 @@ file path using CFStringGetCString() b/c the file path { fileNameInZipEscaped = (NSString *)gFileNameUnavilableStr; } + + /* + insert zero width white space characters to improve word breaking behavior + based on: https://stackoverflow.com/questions/15841109/optional-line-breaking-html-entity-that-is-always-invisible + */ + fileNameInZipEscaped = [fileNameInZipEscaped stringByReplacingOccurrencesOfString:@"/" withString:@"/​"]; - [qlHtml appendString: @"", - fileNameInZipEscaped]; - + NSString* nameClass = @"file"; + if (isFolder) + { + nameClass = @"folder"; + } else if (isLink) + { + nameClass = @"link"; + } + [qlHtml appendFormat: @"", nameClass, fileNameInZipEscaped]; + /* - if the entry is a folder, don't print out its size, + if the entry is a folder or a symbolic link, don't print out its size, which is always 0 */ - - if (isFolder == TRUE) { + if (isFolder || isLink) + { [qlHtml appendString: - @""]; + @""]; } else { - if (isGZFile == true) { fileCompressedSize = getGZExpandedFileSize(zipFileNameStr); @@ -478,16 +477,18 @@ file path using CFStringGetCString() b/c the file path /* print out the file's size in B, K, M, G, or T */ [qlHtml appendFormat: - @"", + @"", fileSizeSpecInZip.size, fileSizeSpecInZip.spec]; - - [qlHtml appendString: - @""]; - - //[qlHtml appendString: @""]; } + /* output the files permissions */ + + mode = archive_entry_perm(entry); + getPermissions(mode, permissions); + + [qlHtml appendFormat: @"", permissions]; + /* print out the modified date and time for the file in the local format. based on: https://stackoverflow.com/questions/9676435/how-do-i-format-the-current-date-for-the-users-locale @@ -497,10 +498,12 @@ file path using CFStringGetCString() b/c the file path /* init the date string (if needed) and clear it */ - if (fileDateStringInZip == nil) { + if (fileDateStringInZip == nil) + { fileDateStringInZip = [[NSMutableString alloc] initWithString: @""]; - } else { + } else + { [fileDateStringInZip setString: @""]; } @@ -509,14 +512,16 @@ file path using CFStringGetCString() b/c the file path date, as stored in the zip file */ - if (fileDateFormatterInZip == nil) { + if (fileDateFormatterInZip == nil) + { fileDateFormatterInZip = [[NSDateFormatter alloc] init]; [fileDateFormatterInZip setDateFormat: @"MM-dd-yy HH:mm"]; } /* initialize the date formatter for the local date format */ - if (fileLocalDateFormatterInZip == nil) { + if (fileLocalDateFormatterInZip == nil) + { fileLocalDateFormatterInZip = [[NSDateFormatter alloc] init]; } @@ -533,7 +538,8 @@ file path using CFStringGetCString() b/c the file path use a default format */ - if (fileDateInZip != nil) { + if (fileDateInZip != nil) + { /* Make sure the days and months are zero prefixed. @@ -550,18 +556,19 @@ file path using CFStringGetCString() b/c the file path setLocalizedDateFormatFromTemplate: @"MM-dd-yyyy"]; [qlHtml appendFormat: - @"", + @"", + @" %@", [fileLocalDateFormatterInZip stringFromDate: fileDateInZip]]; - } else { + } else + { [qlHtml appendFormat: - @""]; + @""]; } /* close the row */ @@ -594,16 +601,18 @@ file path using CFStringGetCString() b/c the file path [# files] [expanded size / compressed size] [% compression] */ - [qlHtml appendString: @"\n\n"]; + [qlHtml appendString: @"\n\n"]; /* print out the total number of files in the zip file */ fileCount = archive_file_count(a); [qlHtml appendString: - @""]; + [qlHtml appendString: + @"\n", + [qlHtml appendFormat: @"%lu item%s", fileCount, (fileCount > 1 ? "s" : "")]; @@ -618,9 +627,7 @@ file path using CFStringGetCString() b/c the file path /* print out the zip file's total size in B, K, M, G, or T */ - [qlHtml appendString: - @""]; - [qlHtml appendString: - @"\n"]; - /* close the summary row */ [qlHtml appendString:@"\n"]; /* close the table body */ - [qlHtml appendString: @"\n"]; + [qlHtml appendString: @"\n"]; /* close the table */ [qlHtml appendString: @"
%@
 %@%@%@%@%@%@
%@%@
%@
%@
--
 %-.1f %-1s%-.1f %-1s %s%@%@", [fileLocalDateFormatterInZip stringFromDate: fileDateInZip]]; [fileLocalDateFormatterInZip setLocalizedDateFormatFromTemplate: @"HH:mm"]; [qlHtml appendFormat: - @"%@  
"]; + @" "]; - [qlHtml appendFormat: @"%lu item%s"]; - [qlHtml appendFormat: @"%-.1f %-1s", + [qlHtml appendFormat: @" | %-.1f %-1s", fileSizeSpecInZip.size, fileSizeSpecInZip.spec]; @@ -639,7 +646,7 @@ file path using CFStringGetCString() b/c the file path getFileSizeSpec(totalCompressedSize, &fileSizeSpecInZip); - [qlHtml appendFormat: @" / %-.1f %-1s", + [qlHtml appendFormat: @" | %-.1f %-1s", fileSizeSpecInZip.size, fileSizeSpecInZip.spec]; } @@ -649,28 +656,24 @@ file path using CFStringGetCString() b/c the file path if (totalSize > 0 && totalCompressedSize > 0) { - [qlHtml appendFormat: @" (%3.0f%%)", - getCompression(totalSize, - totalCompressedSize)]; + [qlHtml appendFormat: @" | %.0f%%", + getCompression(totalSize, totalCompressedSize)]; } [qlHtml appendString: @"
 
\n"]; - + /* close the html */ endOutputBody(qlHtml); @@ -832,14 +835,14 @@ file path using CFStringGetCString() b/c the file path /* add the table header */ - [qlHtml appendString: @""]; - [qlHtml appendFormat: @"%@", + [qlHtml appendString: @""]; + [qlHtml appendFormat: @"%@", gTableHeaderName]; - [qlHtml appendFormat: @"%@", + [qlHtml appendFormat: @"%@", gTableHeaderSize]; - [qlHtml appendFormat: @"%@", + [qlHtml appendFormat: @"%@", gTableHeaderType]; - [qlHtml appendFormat: @"%@", + [qlHtml appendFormat: @"%@", gTableHeaderCreator]; [qlHtml appendString: @"\n"]; @@ -1099,10 +1102,10 @@ file path using CFStringGetCString() b/c the file path /* add the table header */ - [qlHtml appendString: @""]; - [qlHtml appendFormat: @"%@", + [qlHtml appendString: @""]; + [qlHtml appendFormat: @"%@", gTableHeaderName]; - [qlHtml appendFormat: @"%@", + [qlHtml appendFormat: @"%@", gTableHeaderSize]; [qlHtml appendFormat: @"%@", gTableHeaderDate]; @@ -1444,130 +1447,149 @@ static bool formatOutputHeader(NSMutableString *qlHtml) [qlHtml appendString: @"@media (prefers-color-scheme: dark) { "]; - /* set darkmode background and foreground colors */ + /* set darkmode background and foreground colors */ - [qlHtml appendFormat: - @"body { background-color: %@; color: %@; }\n", - gDarkModeBackground, - gDarkModeForeground]; + [qlHtml appendFormat: + @"body { background-color: %@; color: %@; }\n", + gDarkModeBackground, + gDarkModeForeground]; - /* - put a border around the table only, but make it the same color - as the background to better match the BigSur finder - based on: https://stackoverflow.com/questions/10131729/removing-border-from-table-cell + /* + put a border around the table only, but make it the same color + as the background to better match the BigSur finder + based on: https://stackoverflow.com/questions/10131729/removing-border-from-table-cell + */ + + [qlHtml appendFormat: + @"table { border: %dpx solid %@; }\n", + gBorder, + gDarkModeTableBorderColor]; + + [qlHtml appendFormat: + @"th { border-bottom: %dpx solid %@; background-color: %@ }\n", + gBorder, + gDarkModeTableHeaderBorderColor, + gDarkModeBackground]; + + /* colors for the even rows */ + + [qlHtml appendFormat: + @"tr:nth-child(even) { background-color: %@ ; color: %@; }\n", + gDarkModeTableRowEvenBackground, + gDarkModeTableRowEvenForeground]; + + /* top border for table cells in the summary row */ + + [qlHtml appendFormat: + @"td.footer { border-top: %dpx solid %@; }\n", + gBorder, + gDarkModeTableHeaderBorderColor]; + + /* icon colors */ + [qlHtml appendFormat: @"svg > g { fill: %@; }\n", gDarkModeForeground]; + [qlHtml appendFormat: @"svg > g.folder-icon { fill: %@; }\n", gDarkModeFolderColor]; + + /* close darkmode styles */ - set y-direction overflow to auto to support a fixed header - based on: - https://www.w3docs.com/snippets/html/how-to-create-a-table-with-a-fixed-header-and-scrollable-body.html - https://stackoverflow.com/questions/50361698/border-style-do-not-work-with-sticky-position-element - */ + [qlHtml appendString: @"}\n"]; + + /* light mode styles */ - [qlHtml appendFormat: @"table { width: 100%%; border: %dpx solid %@; ", - gBorder, - gDarkModeTableBorderColor]; - [qlHtml appendString: @"table-layout: fixed; overflow-y: auto;"]; [qlHtml appendString: - @"border-collapse: separate; border-spacing: 0; }\n"]; + @"@media (prefers-color-scheme: light) { "]; - /* set the darkmode colors for the even rows of the table */ + /* light mode background and foreground colors */ - [qlHtml appendFormat: - @"tr:nth-child(even) { background-color: %@ ; color: %@; }\n", - gDarkModeTableRowEvenBackgroundColor, - gDarkModeTableRowEvenForegroundColor]; + [qlHtml appendFormat: + @"body { background-color: %@; color: %@; }\n", + gLightModeBackground, + gLightModeForeground]; - /* - add a bottom border for the header row items only, to better - match the BigSur finder, and make the header fixed. - based on: - https://www.w3docs.com/snippets/html/how-to-create-a-table-with-a-fixed-header-and-scrollable-body.html - */ + /* + put a border around the table only, but make it the same color + as the background to better match the BigSur finder + based on: https://stackoverflow.com/questions/10131729/removing-border-from-table-cell + */ + + [qlHtml appendFormat: + @"table { border: %dpx solid %@; }\n", + gBorder, + gLightModeTableBorderColor]; - [qlHtml appendFormat: - @"th { border-bottom: %dpx solid %@; ", - gBorder, - gDarkModeTableHeaderBorderColor]; - [qlHtml appendString: @" position: sticky; position: -webkit-sticky; "]; - [qlHtml appendFormat: @"top: 0; z-index: 3; background-color: %@ ;}\n", - gDarkModeBackground]; + [qlHtml appendFormat: + @"th { border-bottom: %dpx solid %@; background-color: %@ }\n", + gBorder, + gLightModeTableHeaderBorderColor, + gLightModeBackground]; - /* disable internal borders for table cells */ + /* colors for the even rows */ - [qlHtml appendString: @"td { border: none; z-index: 1; }\n"]; + [qlHtml appendFormat: + @"tr:nth-child(even) { background-color: %@ ; color: %@; }\n", + gLightModeTableRowEvenBackground, + gLightModeTableRowEvenForeground]; - /* top border for table cells in the summary row */ + /* top border for table cells in the summary row */ - [qlHtml appendFormat: - @"td.border-top { border-top: %dpx solid %@; }\n", - gBorder, - gDarkModeTableHeaderBorderColor]; - - /* close darkmode styles */ + [qlHtml appendFormat: + @"td.footer { border-top: %dpx solid %@; }\n", + gBorder, + gLightModeTableHeaderBorderColor]; - [qlHtml appendString: @"}\n"]; + /* icon colors */ + [qlHtml appendFormat: @"svg > g { fill: %@; }\n", gLightModeForeground]; + [qlHtml appendFormat: @"svg > g.folder-icon { fill: %@; }\n", gLightModeFolderColor]; - /* light mode styles */ + /* close light mode styles */ - [qlHtml appendString: - @"@media (prefers-color-scheme: light) { "]; - - /* light mode background and foreground colors */ - - [qlHtml appendFormat: - @"body { background-color: %@; color: %@; }\n", - gLightModeBackground, - gLightModeForeground]; + [qlHtml appendString: @"}\n"]; /* - put a border around the table only - based on: https://stackoverflow.com/questions/10131729/removing-border-from-table-cell + make the header fixed. + based on: + https://www.w3docs.com/snippets/html/how-to-create-a-table-with-a-fixed-header-and-scrollable-body.html */ + [qlHtml appendString: @"th { position: sticky; position: -webkit-sticky; top: 0; z-index: 3; }\n"]; - [qlHtml appendFormat: @"table { width: 100%%; border: %dpx solid %@; ", - gBorder, - gLightModeTableBorderColor]; + /* + set y-direction overflow to auto to support a fixed header + based on: + https://www.w3docs.com/snippets/html/how-to-create-a-table-with-a-fixed-header-and-scrollable-body.html + https://stackoverflow.com/questions/50361698/border-style-do-not-work-with-sticky-position-element + */ + [qlHtml appendString: @"table {"]; + [qlHtml appendString: @"width: 100%;"]; [qlHtml appendString: @"table-layout: fixed; overflow-y: auto;"]; - [qlHtml appendString: - @"border-collapse: separate; border-spacing: 0; }\n"]; - - /* make the header sticky */ - - [qlHtml appendFormat: @"th { border-bottom: %dpx solid %@; ", - gBorder, - gLightModeTableHeaderBorderColor]; - [qlHtml appendString: @" position: sticky; position: -webkit-sticky; "]; - [qlHtml appendFormat: @"top: 0; z-index: 3; background-color: %@ ;}\n", - gLightModeBackground]; - - /* colors for the even rows */ + [qlHtml appendString: @"border-collapse: separate; border-spacing: 0;"]; + [qlHtml appendString: @"}\n"]; - [qlHtml appendFormat: - @"tr:nth-child(even) { background-color: %@ ; color: %@; }\n", - gLightModeTableRowEvenBackgroundColor, - gLightModeTableRowEvenForegroundColor]; + /* font settings */ + + [qlHtml appendString: @"body, td, th { font-family: \"Lucida Grande\"; font-size: 11px; }\n"]; /* no internal borders */ [qlHtml appendString: @"td { border: none; z-index: 1; }\n"]; - /* top border for table cells in the summary row */ - - [qlHtml appendFormat: - @"td.border-top { border-top: %dpx solid %@; }\n", - gBorder, - gLightModeTableHeaderBorderColor]; - - /* close light mode styles */ - - [qlHtml appendString: @"}\n"]; - /* style for preventing wrapping in table cells, based on: https://stackoverflow.com/questions/300220/how-to-prevent-text-in-a-table-cell-from-wrapping */ [qlHtml appendString: @".nowrap { white-space: nowrap; }\n"]; - + + [qlHtml appendFormat: @".icon { width: %dpx; height: %dpx; }\n", gIconWidth, gIconHeight]; + + [qlHtml appendString: @".name { word-wrap: break-word; text-align: left; width: 70%; }\n"]; + [qlHtml appendString: @".file { }\n"]; + [qlHtml appendString: @".folder { }\n"]; + [qlHtml appendString: @".link { font-style: italic; }\n"]; + [qlHtml appendString: @".size { white-space: nowrap; text-align: right; width: 10%; }\n"]; + [qlHtml appendString: @".mode { white-space: nowrap; text-align: right; width: 65px; }\n"]; + [qlHtml appendString: @".date { white-space: nowrap; text-align: right; width: 110px; }\n"]; + + [qlHtml appendString: @"td.footer { white-space: nowrap; text-align: left; }\n"]; + /* close the style sheet */ [qlHtml appendString: @"\n"]; @@ -1588,8 +1610,7 @@ static bool startOutputBody(NSMutableString *qlHtml) } [qlHtml appendFormat: @"\n"]; - [qlHtml appendFormat: @"\n", gFontFace]; - + return true; } @@ -1599,7 +1620,7 @@ static bool endOutputBody(NSMutableString *qlHtml) return false; } - [qlHtml appendString: @"\n\n\n"]; + [qlHtml appendString: @"\n\n"]; return true; } @@ -1722,22 +1743,38 @@ static int getFileSizeSpec(off_t fileSizeInBytes, static float getCompression(off_t uncompressedSize, off_t compressedSize) { - Float64 compression = 0.0; - - if (uncompressedSize > 0) + if (compressedSize < 0 || uncompressedSize < 0) { - compression = uncompressedSize / (Float64)(compressedSize); - if (compression >= 1.0) + return 0.0; + } + if (compressedSize < uncompressedSize) + { + Float64 ratio = compressedSize / (Float64)(uncompressedSize); + return 100.0 * (1.0 - ratio); + } else if (compressedSize > uncompressedSize) + { + Float64 ratio = compressedSize / (Float64)(uncompressedSize); + Float64 bloat = -100.0 * (ratio - 1.0); + if (bloat < 1.0) { - compression = 1.0 / compression; + return 0.0; } - compression = 100.0 * (1.0 - compression); + return bloat; } + return 0.0; +} - if (compression <= 0 || compression >= 99.9) - { - compression = 0.0; - } +/* + convert permission bits to string + based on: https://jameshfisher.com/2017/02/24/what-is-mode_t/ + */ - return compression; +// buf must have at least 10 bytes +static void getPermissions(mode_t mode, char *buf) +{ + const char chars[] = "rwxrwxrwx"; + for (size_t i = 0; i < 9; i++) { + buf[i] = (mode & (1 << (8-i))) ? chars[i] : '-'; + } + buf[9] = '\0'; } diff --git a/qlZipInfo/Info.plist b/qlZipInfo/Info.plist index b918784..67c60b9 100644 --- a/qlZipInfo/Info.plist +++ b/qlZipInfo/Info.plist @@ -82,9 +82,9 @@ QLNeedsToBeRunInMainThread QLPreviewHeight - 320 + 800 QLPreviewWidth - 640 + 1000 QLSupportsConcurrentRequests QLThumbnailMinimumSize From fd9fafff390cc44a63c8b0aecdc31db7fd2f2068 Mon Sep 17 00:00:00 2001 From: Manuel Brotz Date: Tue, 16 Apr 2024 10:59:56 +0200 Subject: [PATCH 07/10] updated copyright info --- qlZipInfo/Info.plist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qlZipInfo/Info.plist b/qlZipInfo/Info.plist index 67c60b9..d28fb1b 100644 --- a/qlZipInfo/Info.plist +++ b/qlZipInfo/Info.plist @@ -78,7 +78,7 @@ CFPlugInUnloadFunction NSHumanReadableCopyright - Portions Copyright © 2015-2022 Sriranga Veeraraghavan. All rights reserved. + Portions Copyright © 2015-2024 Sriranga Veeraraghavan. All rights reserved. QLNeedsToBeRunInMainThread QLPreviewHeight From 30135e7e842cea3c4380ae6e4b8a97417f172002 Mon Sep 17 00:00:00 2001 From: Manuel Brotz Date: Tue, 16 Apr 2024 11:01:31 +0200 Subject: [PATCH 08/10] enabled support for universal binary --- qlZipInfo.xcodeproj/project.pbxproj | 1 + 1 file changed, 1 insertion(+) diff --git a/qlZipInfo.xcodeproj/project.pbxproj b/qlZipInfo.xcodeproj/project.pbxproj index 342452d..9c59878 100644 --- a/qlZipInfo.xcodeproj/project.pbxproj +++ b/qlZipInfo.xcodeproj/project.pbxproj @@ -858,6 +858,7 @@ INSTALL_PATH = /Library/QuickLook; MACOSX_DEPLOYMENT_TARGET = 10.13; MARKETING_VERSION = 1.3.0; + ONLY_ACTIVE_ARCH = NO; PRODUCT_BUNDLE_IDENTIFIER = "org.calalum.ranga.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; From 559400d485abd82085caadee0796e211fd7da96b Mon Sep 17 00:00:00 2001 From: Manuel Brotz Date: Tue, 16 Apr 2024 11:10:26 +0200 Subject: [PATCH 09/10] bumped version to 1.3 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c08c475..d616970 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ PROJNAME = qlZipInfo PROJEXT = qlgenerator -PROJVERS = 1.2.7 +PROJVERS = 1.3 BUNDLEID = "org.calalum.ranga.$(PROJNAME)" # extra files to include in the package From 8e37b6ba621100ff676be1669aa7d6645f9ecff2 Mon Sep 17 00:00:00 2001 From: Manuel Brotz Date: Fri, 3 May 2024 09:15:00 +0200 Subject: [PATCH 10/10] Reset development team id. --- qlZipInfo.xcodeproj/project.pbxproj | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/qlZipInfo.xcodeproj/project.pbxproj b/qlZipInfo.xcodeproj/project.pbxproj index 9c59878..210130f 100644 --- a/qlZipInfo.xcodeproj/project.pbxproj +++ b/qlZipInfo.xcodeproj/project.pbxproj @@ -613,6 +613,7 @@ TargetAttributes = { 26CA45D21B8461BA00B08F29 = { CreatedOnToolsVersion = 6.4; + DevelopmentTeam = CLN8R9E6QM; ProvisioningStyle = Automatic; }; }; @@ -853,7 +854,7 @@ COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; DEAD_CODE_STRIPPING = YES; - DEVELOPMENT_TEAM = 4YD6U8PZLA; + DEVELOPMENT_TEAM = CLN8R9E6QM; INFOPLIST_FILE = qlZipInfo/Info.plist; INSTALL_PATH = /Library/QuickLook; MACOSX_DEPLOYMENT_TARGET = 10.13; @@ -874,7 +875,7 @@ COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; DEAD_CODE_STRIPPING = YES; - DEVELOPMENT_TEAM = 4YD6U8PZLA; + DEVELOPMENT_TEAM = CLN8R9E6QM; INFOPLIST_FILE = qlZipInfo/Info.plist; INSTALL_PATH = /Library/QuickLook; MACOSX_DEPLOYMENT_TARGET = 10.13;