Clover.app: added LAbyOne's theme repository + themeout of date theme detection

HelmoHass themes repository (by LAbyOne) can be selected directly in the UI.
Now the theme manager knows when a theme is out dated and show a dedicate icon when this happens. Now Clover.app can encode the git sha1 ... always with out git.
Searching themes in the relative fields is now even more easy by tipying the name partially in case insensitive mode.
builme now close the Terminal window when exit is selected (thanks to LAbyOne).
Fixed a bug in the theme manager engine switching between repositories.
This commit is contained in:
vectorsigma72 2020-04-09 05:31:05 +02:00
parent ea3058f867
commit a4c90606d1
10 changed files with 379 additions and 172 deletions

View File

@ -22,6 +22,7 @@
9542ABC02373783400DC03E6 /* boot1-install in Copy tools */ = {isa = PBXBuildFile; fileRef = 9542ABBD2373780C00DC03E6 /* boot1-install */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
9542ABC22373786700DC03E6 /* CloverV2 in Copy CloverV2 */ = {isa = PBXBuildFile; fileRef = 9542ABC12373786700DC03E6 /* CloverV2 */; };
9546AE1B23806299007155A6 /* CloverLogOut in Copy tools */ = {isa = PBXBuildFile; fileRef = 95524B88238051F4005F6425 /* CloverLogOut */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
954B0385243EB0AB001E719A /* update.png in Resources */ = {isa = PBXBuildFile; fileRef = 954B0384243EB0AB001E719A /* update.png */; };
954BBE99238196EE0032425F /* Locale.swift in Sources */ = {isa = PBXBuildFile; fileRef = 954BBE98238196EE0032425F /* Locale.swift */; };
954DECD523899F5F006A9876 /* Bootmanager.png in Resources */ = {isa = PBXBuildFile; fileRef = 954DECD423899F5F006A9876 /* Bootmanager.png */; };
954FCFD92391818300C9273C /* NSWindowFix.m in Sources */ = {isa = PBXBuildFile; fileRef = 954FCFD82391818300C9273C /* NSWindowFix.m */; };
@ -240,6 +241,7 @@
953BC20223720C0A0039755D /* FixedWidthViews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FixedWidthViews.swift; sourceTree = "<group>"; };
9542ABB82373780C00DC03E6 /* boot1-inst.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "boot1-inst.xcodeproj"; path = "../CloverPackage/utils/boot1-install/boot1-inst.xcodeproj"; sourceTree = "<group>"; };
9542ABC12373786700DC03E6 /* CloverV2 */ = {isa = PBXFileReference; lastKnownFileType = folder; name = CloverV2; path = ../CloverPackage/CloverV2; sourceTree = "<group>"; };
954B0384243EB0AB001E719A /* update.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = update.png; sourceTree = "<group>"; };
954BBE98238196EE0032425F /* Locale.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Locale.swift; sourceTree = "<group>"; };
954C3DF0237DF0250059C698 /* ServiceManagement.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ServiceManagement.framework; path = System/Library/Frameworks/ServiceManagement.framework; sourceTree = SDKROOT; };
954DECD423899F5F006A9876 /* Bootmanager.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Bootmanager.png; sourceTree = "<group>"; };
@ -570,6 +572,7 @@
9534B79A242CDC52003F323E /* Find.png */,
9534B799242CDC52003F323E /* Replace.png */,
955BEE1A23C7171000425AB0 /* check.png */,
954B0384243EB0AB001E719A /* update.png */,
);
path = images;
sourceTree = "<group>";
@ -861,6 +864,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
954B0385243EB0AB001E719A /* update.png in Resources */,
9534B79B242CDC53003F323E /* Replace.png in Resources */,
9571A22A241C2E7F000D6645 /* PlistEditor.storyboard in Resources */,
9556CAF5238DF75600082671 /* InstallerOutline.xib in Resources */,

View File

@ -80,7 +80,7 @@
<rect key="frame" x="14" y="186" width="311" height="14"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" title="Check update:" id="fMZ-r2-dlm">
<font key="font" metaFont="label" size="11"/>
<font key="font" metaFont="menu" size="11"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -89,7 +89,7 @@
<rect key="frame" x="14" y="91" width="311" height="14"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" title="Label" id="v3d-HG-AeW">
<font key="font" metaFont="label" size="11"/>
<font key="font" metaFont="menu" size="11"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -195,7 +195,7 @@
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="Read daemon log" bezelStyle="rounded" alignment="center" controlSize="small" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="UZY-ie-enb">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="label" size="11"/>
<font key="font" metaFont="menu" size="11"/>
</buttonCell>
<connections>
<action selector="readDaemonLog:" target="tSJ-3G-dnL" id="Mo0-RL-dK0"/>
@ -206,7 +206,7 @@
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="Read bdmesg" bezelStyle="rounded" alignment="center" controlSize="small" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="bhg-iF-USh">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="label" size="11"/>
<font key="font" metaFont="menu" size="11"/>
</buttonCell>
<connections>
<action selector="readbdmesg:" target="tSJ-3G-dnL" id="eFP-wf-VyP"/>
@ -216,7 +216,7 @@
<rect key="frame" x="61" y="9" width="224" height="15"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" alignment="center" title="Label" id="goU-fD-Ng6">
<font key="font" metaFont="label" size="11"/>
<font key="font" metaFont="menu" size="11"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -284,7 +284,7 @@
<rect key="frame" x="30" y="20" width="294" height="14"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" controlSize="small" lineBreakMode="truncatingHead" selectable="YES" allowsUndo="NO" focusRingType="none" title="N/A" id="EX6-6q-G8U">
<font key="font" metaFont="label" size="11"/>
<font key="font" metaFont="menu" size="11"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -298,7 +298,7 @@
<rect key="frame" x="30" y="56" width="294" height="14"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" selectable="YES" allowsUndo="NO" title="N/A" id="EFW-lW-i6c">
<font key="font" metaFont="label" size="11"/>
<font key="font" metaFont="menu" size="11"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -324,7 +324,7 @@
<rect key="frame" x="30" y="79" width="294" height="14"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" selectable="YES" focusRingType="none" title="N/A" id="PZZ-nm-ERe">
<font key="font" metaFont="label" size="11"/>
<font key="font" metaFont="menu" size="11"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -342,7 +342,7 @@
<rect key="frame" x="30" y="39" width="294" height="14"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" selectable="YES" focusRingType="none" title="N/A" id="oPZ-3Y-89o">
<font key="font" metaFont="label" size="11"/>
<font key="font" metaFont="menu" size="11"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -360,7 +360,7 @@
<rect key="frame" x="30" y="0.0" width="294" height="14"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" selectable="YES" focusRingType="none" title="N/A" id="okN-IH-2al">
<font key="font" metaFont="label" size="11"/>
<font key="font" metaFont="menu" size="11"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -386,7 +386,7 @@
<rect key="frame" x="30" y="79" width="294" height="14"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" selectable="YES" focusRingType="none" title="N/A" id="HZg-rD-gZv">
<font key="font" metaFont="label" size="11"/>
<font key="font" metaFont="menu" size="11"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -413,7 +413,7 @@
<rect key="frame" x="30" y="39" width="294" height="14"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" selectable="YES" focusRingType="none" title="Label" id="J7N-7a-sdN">
<font key="font" metaFont="label" size="11"/>
<font key="font" metaFont="menu" size="11"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -422,7 +422,7 @@
<rect key="frame" x="30" y="0.0" width="294" height="14"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" selectable="YES" focusRingType="none" title="Label" id="0dT-GZ-Ytt">
<font key="font" metaFont="label" size="11"/>
<font key="font" metaFont="menu" size="11"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -474,7 +474,7 @@
<rect key="frame" x="256" y="497" width="69" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<segmentedCell key="cell" controlSize="small" borderStyle="border" alignment="left" style="rounded" trackingMode="momentary" id="3O5-bI-89P">
<font key="font" metaFont="label" size="11"/>
<font key="font" metaFont="menu" size="11"/>
<segments>
<segment image="NSLeftFacingTriangleTemplate" width="31"/>
<segment image="NSRightFacingTriangleTemplate" width="31" tag="1"/>
@ -490,7 +490,7 @@
<font key="font" metaFont="system"/>
<tabViewItems>
<tabViewItem identifier="Mount" id="F4n-I1-4Gq">
<view key="view" id="E05-QZ-1bf">
<view key="view" ambiguous="YES" id="E05-QZ-1bf">
<rect key="frame" x="0.0" y="0.0" width="342" height="113"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
@ -569,24 +569,66 @@
</textFieldCell>
</textField>
<comboBox verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="MMH-mb-fPM">
<rect key="frame" x="23" y="65" width="302" height="25"/>
<rect key="frame" x="23" y="67" width="302" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<comboBoxCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" placeholderString="NVRAM" drawsBackground="YES" completes="NO" numberOfVisibleItems="5" id="kdy-IM-YSv">
<comboBoxCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" placeholderString="NVRAM" drawsBackground="YES" completes="NO" usesDataSource="YES" numberOfVisibleItems="5" id="kdy-IM-YSv">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
<objectValues>
<string>Item 1</string>
<string>Item 2</string>
<string>Item 3</string>
</objectValues>
</comboBoxCell>
<connections>
<outlet property="dataSource" destination="tSJ-3G-dnL" id="edh-mp-ILZ"/>
<outlet property="delegate" destination="tSJ-3G-dnL" id="kY4-3y-8Vx"/>
</connections>
</comboBox>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6VD-VJ-phW">
<rect key="frame" x="21" y="48" width="75" height="14"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" title="GitHub user" id="Bi4-5Q-YMR">
<font key="font" metaFont="menu" size="11"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="QbU-PE-PmE">
<rect key="frame" x="21" y="28" width="75" height="14"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" title="GitHub repo" id="dE6-xG-swG">
<font key="font" metaFont="menu" size="11"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2Va-F7-vYB">
<rect key="frame" x="102" y="26" width="220" height="18"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="dmw-9Z-gN5">
<font key="font" metaFont="menu" size="11"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<outlet property="delegate" destination="tSJ-3G-dnL" id="tWZ-Mw-jdD"/>
</connections>
</textField>
<comboBox verticalHuggingPriority="750" fixedFrame="YES" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="81R-f3-rAr">
<rect key="frame" x="102" y="43" width="223" height="22"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<comboBoxCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" numberOfVisibleItems="2" id="JjI-1A-wBD">
<font key="font" metaFont="menu" size="11"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<objectValues>
<string>CloverHackyColor</string>
<string>HelmoHass</string>
</objectValues>
</comboBoxCell>
<connections>
<outlet property="delegate" destination="tSJ-3G-dnL" id="dOk-qJ-DYi"/>
</connections>
</comboBox>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="AzG-cL-pFW">
<rect key="frame" x="17" y="33" width="311" height="32"/>
<rect key="frame" x="17" y="-7" width="311" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="Manager" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="I4v-1L-brN">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
@ -596,48 +638,6 @@
<action selector="openThemeManager:" target="tSJ-3G-dnL" id="PE4-2e-cP2"/>
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6VD-VJ-phW">
<rect key="frame" x="21" y="20" width="75" height="14"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" title="GitHub user" id="Bi4-5Q-YMR">
<font key="font" metaFont="label" size="11"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="QbU-PE-PmE">
<rect key="frame" x="21" y="2" width="75" height="14"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" title="GitHub repo" id="dE6-xG-swG">
<font key="font" metaFont="label" size="11"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2Va-F7-vYB">
<rect key="frame" x="102" y="1" width="220" height="16"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" controlSize="mini" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" id="dmw-9Z-gN5">
<font key="font" metaFont="label" size="9"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<outlet property="delegate" destination="tSJ-3G-dnL" id="tWZ-Mw-jdD"/>
</connections>
</textField>
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="rfY-Ds-j3c">
<rect key="frame" x="102" y="19" width="220" height="16"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" controlSize="mini" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" id="glm-s6-df6">
<font key="font" metaFont="label" size="9"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<outlet property="delegate" destination="tSJ-3G-dnL" id="IJL-eP-tCC"/>
</connections>
</textField>
</subviews>
</view>
</tabViewItem>
@ -676,7 +676,7 @@
<rect key="frame" x="18" y="94" width="306" height="14"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" alignment="right" title="Startup Sound" id="Vif-FP-OaO">
<font key="font" metaFont="label" size="11"/>
<font key="font" metaFont="menu" size="11"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -699,7 +699,7 @@
<rect key="frame" x="18" y="25" width="306" height="14"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" title="Volume level:" id="ebr-lB-pTD">
<font key="font" metaFont="label" size="11"/>
<font key="font" metaFont="menu" size="11"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -708,7 +708,7 @@
<rect key="frame" x="18" y="79" width="241" height="14"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" title="Device:" id="sIi-by-bNC">
<font key="font" metaFont="label" size="11"/>
<font key="font" metaFont="menu" size="11"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -727,7 +727,7 @@
</tabViewItem>
<tabViewItem identifier="clover-genconfig" id="kc7-iD-ZPw">
<nil key="label"/>
<view key="view" ambiguous="YES" id="Lp8-6t-ak1">
<view key="view" id="Lp8-6t-ak1">
<rect key="frame" x="0.0" y="0.0" width="342" height="113"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
@ -898,7 +898,7 @@
<outlet property="tabViewInfo" destination="PGs-4a-XRc" id="ghG-r0-tYY"/>
<outlet property="themeBox" destination="MMH-mb-fPM" id="2nx-c0-WqX"/>
<outlet property="themeRepoField" destination="2Va-F7-vYB" id="o15-c9-jRd"/>
<outlet property="themeUserField" destination="rfY-Ds-j3c" id="RNj-Rn-fsb"/>
<outlet property="themeUserCBox" destination="81R-f3-rAr" id="i8d-tx-SIs"/>
<outlet property="timeIntervalPopUp" destination="1qf-uO-CvA" id="774-SY-GdB"/>
<outlet property="unInstallDaemonButton" destination="MWn-i4-CYn" id="r2Y-WW-wd9"/>
<outlet property="unmountButton" destination="Zc5-Dl-jIh" id="5wb-ye-REX"/>

View File

@ -7,6 +7,7 @@
//
import Cocoa
import CommonCrypto
extension String {
/// Create `Data` from hexadecimal string representation
@ -253,6 +254,15 @@ extension Data {
.joined(separator: "")
}
var sha1: String {
var h = [UInt8](repeating: 0, count: Int(CC_SHA1_DIGEST_LENGTH))
self.withUnsafeBytes {
_ = CC_SHA1($0.baseAddress, CC_LONG(self.count), &h)
}
return Data(h).hexadecimal()
}
func castToCPointer<T>() -> T {
let mem = UnsafeMutablePointer<T>.allocate(capacity: 1)
_ = self.copyBytes(to: UnsafeMutableBufferPointer(start: mem, count: 1))

View File

@ -37,7 +37,7 @@ final class SoundSlider : NSSlider {
}
final class SettingsViewController:
NSViewController, NSTextFieldDelegate, NSComboBoxDelegate, URLSessionDownloadDelegate {
NSViewController, NSTextFieldDelegate, NSComboBoxDelegate, NSComboBoxDataSource, URLSessionDownloadDelegate {
// MARK: Variables
@IBOutlet var tabViewInfo : LITabView!
// tab 0
@ -66,7 +66,7 @@ final class SettingsViewController:
// tab 1
@IBOutlet var themeBox : NSComboBox!
@IBOutlet var openThemeButton : NSButton!
@IBOutlet var themeUserField : NSTextField!
@IBOutlet var themeUserCBox : NSComboBox!
@IBOutlet var themeRepoField : NSTextField!
// tab 2
@IBOutlet var soundDevicePopUp : NSPopUpButton!
@ -145,15 +145,18 @@ final class SettingsViewController:
AppSD.themeUser = UDs.string(forKey: kThemeUserKey) ?? kDefaultThemeUser
AppSD.themeRepo = UDs.string(forKey: kThemeRepoKey) ?? kDefaultThemeRepo
self.themeUserField.stringValue = AppSD.themeUser
self.themeUserCBox.stringValue = AppSD.themeUser
self.themeRepoField.stringValue = AppSD.themeRepo
if #available(OSX 10.10, *) {
self.themeUserField.placeholderString = kDefaultThemeUser
self.themeUserCBox.placeholderString = kDefaultThemeUser
self.themeRepoField.placeholderString = kDefaultThemeRepo
}
self.themeBox.removeAllItems()
self.themeUserCBox.removeAllItems()
self.themeUserCBox.completes = true
self.themeUserCBox.addItems(withObjectValues: ["CloverHackyColor", "HelmoHass"])
let themeManagerIndexDir = NSHomeDirectory().addPath("Library/Application Support/CloverApp/Themeindex/\(AppSD.themeUser)_\(AppSD.themeRepo)")
let tm = ThemeManager(user: AppSD.themeUser,
@ -162,18 +165,22 @@ final class SettingsViewController:
indexDir: themeManagerIndexDir,
delegate: nil)
let indexedThemes = tm.getIndexedThemes()
self.themeBox.addItems(withObjectValues: indexedThemes)
let indexedThemes = tm.getIndexedThemesForAllRepositories()
AppSD.themes = indexedThemes.sorted()
if indexedThemes.contains("embedded") {
self.themeBox.addItem(withObjectValue: "embedded")
if !AppSD.themes.contains("embedded") {
AppSD.themes.append("embedded")
}
if indexedThemes.contains("random") {
self.themeBox.addItem(withObjectValue: "random")
if !AppSD.themes.contains("random") {
AppSD.themes.append("random")
}
self.themeBox.delegate = self
self.themeBox.dataSource = self
self.themeBox.usesDataSource = true
self.themeBox.completes = true
self.themeBox.reloadData()
self.soundVolumeSlider.field = self.soundVolumeField
self.soundVolumeField.stringValue = kNotAvailable.locale
@ -636,41 +643,65 @@ final class SettingsViewController:
}
}
func numberOfItems(in comboBox: NSComboBox) -> Int {
return AppSD.themes.count
}
func comboBox(_ comboBox: NSComboBox, indexOfItemWithStringValue string: String) -> Int {
return AppSD.themes.firstIndex(of: string) ?? -1
}
func comboBox(_ comboBox: NSComboBox, objectValueForItemAt index: Int) -> Any? {
return AppSD.themes[index]
}
func comboBox(_ comboBox: NSComboBox, completedString string: String) -> String? {
for theme in AppSD.themes {
if theme.lowercased().hasPrefix(string.lowercased()) {
return theme
}
}
return nil
}
func comboBoxSelectionDidChange(_ notification: Notification) {
if (notification.object as? NSComboBox) == self.themeBox {
self.themeBoxSelected(self.themeBox)
let themeName = self.themeBox.itemObjectValue(at: self.themeBox.indexOfSelectedItem) as! String
self.set(theme: themeName, sender: self.themeBox)
} else if (notification.object as? NSComboBox) == self.themeUserCBox {
let val = self.themeUserCBox.itemObjectValue(at: self.themeUserCBox.indexOfSelectedItem) as! String
UDs.set(val, forKey: kThemeUserKey)
UDs.synchronize()
AppSD.themeUser = val
}
}
func controlTextDidEndEditing(_ obj: Notification) {
if (obj.object as? NSComboBox) == self.themeBox {
self.themeBoxSelected(self.themeBox)
let themeName = self.themeBox.stringValue
self.set(theme: themeName, sender: self.themeBox)
return
}
var updateThemeRepo = false
if let field = obj.object as? NSTextField {
if field == self.themeUserField {
if field.stringValue.count > 0 {
UDs.set(field.stringValue, forKey: kThemeUserKey)
if let cbox = obj.object as? NSComboBox {
if cbox == self.themeUserCBox {
if cbox.stringValue.count > 0 {
UDs.set(cbox.stringValue, forKey: kThemeUserKey)
} else {
UDs.set(kDefaultThemeUser, forKey: kThemeUserKey)
}
updateThemeRepo = true
} else if field == self.themeRepoField {
AppSD.themeUser = UDs.string(forKey: kThemeUserKey) ?? kDefaultThemeUser
}
} else if let field = obj.object as? NSTextField {
if field == self.themeRepoField {
if field.stringValue.count > 0 {
UDs.set(field.stringValue, forKey: kThemeRepoKey)
} else {
UDs.set(kDefaultThemeRepo, forKey: kThemeRepoKey)
}
updateThemeRepo = true
UDs.synchronize()
AppSD.themeRepo = UDs.string(forKey: kThemeRepoKey) ?? kDefaultThemeRepo
}
}
if updateThemeRepo {
AppSD.themeUser = UDs.string(forKey: kThemeUserKey) ?? kDefaultThemeUser
AppSD.themeRepo = UDs.string(forKey: kThemeRepoKey) ?? kDefaultThemeRepo
}
}
@IBAction func generateConfig(_ sender: NSButton!) {
@ -933,19 +964,22 @@ final class SettingsViewController:
// MARK: NVRAM editing
func themeBoxSelected(_ sender: NSComboBox!) {
//sender.window?.makeFirstResponder(nil)
let themeName = sender.itemObjectValue(at: sender.indexOfSelectedItem) as! String
self.set(theme: themeName, sender: sender)
}
private func set(theme name: String, sender: NSComboBox) {
let key = "Clover.Theme"
let theme = sender.stringValue
var nvramValue : String = ""
if let data = getNVRAM()?.object(forKey: key) as? Data {
nvramValue = String(decoding: data, as: UTF8.self)
}
if nvramValue != theme {
if theme.count == 0 {
if nvramValue != name {
if name.count == 0 {
deleteNVRAM(key: key.nvramString)
} else {
setNVRAM(key: key, stringValue: theme.nvramString)
setNVRAM(key: key, stringValue: name.nvramString)
}
} else {
return

View File

@ -7,6 +7,7 @@
//
import Cocoa
import CommonCrypto
let kThemeUserKey = "themeUser"
let kThemeRepoKey = "themeRepo"
@ -31,11 +32,11 @@ final class ThemeManager: NSObject, URLSessionDataDelegate {
private let errorDomain : String = "org.slice.Clover.ThemeManager.Error"
var statusError : Error? = nil
var delegate : ThemeManagerVC?
private var user : String
private var repo : String
var user : String
var repo : String
var basePath : String
private var urlBaseStr : String
private var themeManagerIndexDir : String
var themeManagerIndexDir : String
private var gitInitCount : Int32 = 0
@ -58,6 +59,31 @@ final class ThemeManager: NSObject, URLSessionDataDelegate {
}
}
public func getIndexedThemesForAllRepositories() -> [String] {
self.statusError = nil
var themes = [String]()
let tip = NSHomeDirectory().addPath("Library/Application Support/CloverApp/Themeindex")
if let repos = try? fm.contentsOfDirectory(atPath: tip) {
for repo in repos {
let repoThemesDir = tip.addPath(repo).addPath("Themes")
let repoShaFilePath = tip.addPath(repo).addPath("sha")
if fm.fileExists(atPath: repoShaFilePath) && fm.fileExists(atPath: repoThemesDir) {
if let files : [String] = try? fm.contentsOfDirectory(atPath: repoThemesDir) {
for f in files {
let theme : String = f.deletingFileExtension
let ext : String = f.fileExtension
if ext == "plist" && !themes.contains(theme) {
themes.append(theme)
}
}
}
}
}
}
return themes.sorted()
}
public func getIndexedThemes() -> [String] {
self.statusError = nil
var themes = [String]()
@ -367,18 +393,34 @@ final class ThemeManager: NSObject, URLSessionDataDelegate {
completion(false)
break
}
if let path = obj["path"] as? String {
if path.componentsPath.count == 1 && type != "tree" {
// skip every things is not a directory in the root of the repository (like README.md)
continue
}
if !path.hasPrefix(".") && type == "blob" { // .gitignore, .DS_Store
guard let fileSha = obj["sha"] as? String else {
let errStr = "GI16, Error: 'sha' key not found for \(path)."
let se : Error = NSError(domain: self.errorDomain,
code: 2016,
userInfo: [NSLocalizedDescriptionKey: errStr])
self.statusError = se
completion(false)
break
}
// skip every hidden files like .gitignore, .DS_Store, etc.
if !path.hasPrefix(".") && type == "blob" {
let themeName : String = path.components(separatedBy: "/")[0]
let plistPath : String = "\(self.themeManagerIndexDir)/\(sha)/\(themeName).plist"
let theme : NSMutableArray = NSMutableArray(contentsOfFile: plistPath) ?? NSMutableArray()
if !theme.contains(path) {
theme.add(path)
let theme : NSMutableDictionary = NSMutableDictionary(contentsOfFile: plistPath) ?? NSMutableDictionary()
if !(theme.allKeys as! [String]).contains(path) {
theme.setObject(fileSha, forKey: path as NSString)
}
if !theme.write(toFile: plistPath, atomically: false) {
let errStr = "GI10, Error: can't write \(plistPath)"
let se : Error = NSError(domain: self.errorDomain,
@ -499,8 +541,8 @@ final class ThemeManager: NSObject, URLSessionDataDelegate {
}
let plistPath : String = "\(themeManagerIndexDir)/Themes/\(theme).plist"
if let files : [String] = NSArray(contentsOfFile: plistPath) as? [String] {
let themePlist = NSDictionary(contentsOfFile: plistPath)
if let files : [String] = themePlist?.allKeys as? [String] {
// ---------------------------------------
let fc : Int = files.count
if fc > 0 {
@ -509,7 +551,7 @@ final class ThemeManager: NSObject, URLSessionDataDelegate {
for i in 0..<fc {
let file : String = files[i]
// build the url
let furl : String = "\(GitProtocol.https.rawValue)://raw.githubusercontent.com/CloverHackyColor/CloverThemes/master/\(file)"
let furl : String = "\(GitProtocol.https.rawValue)://raw.githubusercontent.com/\(self.user)/\(self.repo)/master/\(file)"
if down == .thumbnail {
if file != theme.addPath("screenshot.png")
@ -589,7 +631,7 @@ final class ThemeManager: NSObject, URLSessionDataDelegate {
}
}
public func signTheme(at path: String) {
public func signTheme(at path: String) { // unused function
if let sha : String = self.getSha() {
let fileURL : URL = URL(fileURLWithPath: path)
let data : Data? = sha.data(using: .utf8)
@ -617,10 +659,81 @@ final class ThemeManager: NSObject, URLSessionDataDelegate {
}
}
/// Check if a theme exist (in the current repository
public func exist(theme: String) -> Bool {
return fm.fileExists(atPath: "\(self.themeManagerIndexDir)/Themes/\(theme).plist")
}
/// Check if a theme at the given path is up to date in the current repository. True if doesn't exists.
public func isThemeUpToDate(at path : String) -> Bool {
let theme = path.lastPath
if !self.exist(theme: theme) {
// if theme doesn't exist in the repository is up to date since is not part of it!
return true
}
let plistPath = "\(self.themeManagerIndexDir)/Themes/\(theme).plist"
guard var plist = NSMutableDictionary(contentsOfFile: plistPath) as? [String : String] else {
// We cannot load our generated file? :-(
print("Error: Theme Manager can't load \(plistPath)")
return true
}
let enumerator = fm.enumerator(atPath: path)
while let file = enumerator?.nextObject() as? String {
let fp = path.addPath(file)
var isDir : ObjCBool = false
fm.fileExists(atPath: fp, isDirectory: &isDir)
// don't check hidden files, like .DS_Store ;-)
if !file.lastPath.hasPrefix(".") {
/*
Check only files.
If extra directories exists inside the user theme it's not our business...
*/
if !isDir.boolValue {
// ..it is if a file doesn't exist
let key = theme.addPath(file)
if let githubSha = plist[key] {
// ok compare the sha1
if let fileData = try? Data(contentsOf: URL(fileURLWithPath: fp)) {
var gitdata = Data()
let encoding : String.Encoding = .utf8
gitdata.append("blob ".data(using: encoding)!)
gitdata.append("\(fileData.count)".data(using: encoding)!)
gitdata.append(0x00)
gitdata.append(fileData)
let gitsha1 = gitdata.sha1
if gitsha1 != githubSha {
// sha doesn't match, this is a different file
return false
}
} else {
print("Error: Theme Manager can't load \(fp)")
return false
}
plist[key] = nil // no longer needed
} else {
// file doesn't exist in the theme at repository
return false
}
}
}
}
/*
if We are here is because sha1 has been compared successfully
for each file on the installed theme.
If plist var no longer contains keys, it also means that all
the files are existing on the installed theme.
Otherwise fail!
*/
return plist.keys.count == 0
}
public func optimizeTheme(at path: String, completion: @escaping (Error?) -> ()) {
DispatchQueue.global(priority: .background).async(execute: { () -> Void in

View File

@ -37,12 +37,12 @@
<tableColumns>
<tableColumn identifier="column1" width="147" minWidth="40" maxWidth="1000" id="SqG-sb-peF">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border">
<font key="font" metaFont="label" size="11"/>
<font key="font" metaFont="controlContent" size="11"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Text Cell" id="XIw-Cc-NAw">
<font key="font" metaFont="label" size="13"/>
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -56,7 +56,7 @@
<rect key="frame" x="0.0" y="0.0" width="147" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="zkl-n1-vr4">
<font key="font" metaFont="label" size="13"/>
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -86,7 +86,7 @@
<rect key="frame" x="162" y="74" width="579" height="14"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" controlSize="small" lineBreakMode="truncatingTail" title="Description:" id="VVK-qM-R76">
<font key="font" metaFont="label" size="11"/>
<font key="font" metaFont="controlContent" size="11"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -98,7 +98,7 @@
<rect key="frame" x="162" y="51" width="579" height="15"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" controlSize="small" lineBreakMode="truncatingTail" title="Author:" id="nVY-gj-ELR">
<font key="font" metaFont="label" size="11"/>
<font key="font" metaFont="controlContent" size="11"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -107,17 +107,12 @@
</connections>
</textField>
<comboBox focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1Be-Yl-lqT">
<rect key="frame" x="164" y="97" width="201" height="25"/>
<rect key="frame" x="199" y="97" width="206" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<comboBoxCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" focusRingType="none" placeholderString="Theme" drawsBackground="YES" completes="NO" numberOfVisibleItems="5" id="ZdF-kp-eIO">
<font key="font" metaFont="label" size="13"/>
<comboBoxCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" focusRingType="none" placeholderString="Theme" drawsBackground="YES" usesDataSource="YES" numberOfVisibleItems="5" id="ZdF-kp-eIO">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
<objectValues>
<string>Item 1</string>
<string>Item 2</string>
<string>Item 3</string>
</objectValues>
</comboBoxCell>
<connections>
<action selector="nameBoxSelected:" target="ClZ-60-myJ" id="rPH-oQ-4RO"/>
@ -129,7 +124,7 @@
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="Install" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="hSu-fW-idj">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="label" size="13"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="InstallPressed:" target="ClZ-60-myJ" id="Phd-pp-aYa"/>
@ -140,7 +135,7 @@
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="cP4-wD-4Ph" id="MEO-zC-Iak">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="label" size="13"/>
<font key="font" metaFont="system"/>
<menu key="menu" id="fEx-Zt-ngB">
<items>
<menuItem title="Item 1" state="on" id="cP4-wD-4Ph"/>
@ -165,11 +160,11 @@
</webPreferences>
</webView>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="qNn-1b-hdX">
<rect key="frame" x="396" y="102" width="345" height="18"/>
<rect key="frame" x="420" y="102" width="321" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="check" title="Show installed" bezelStyle="regularSquare" imagePosition="left" inset="2" id="PPl-2s-7pe">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="label" size="13"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="showInstalledThemes:" target="ClZ-60-myJ" id="mYF-2e-FAu"/>
@ -180,7 +175,7 @@
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="Uninstall" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Nxb-Kj-kDi">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="label" size="13"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="unInstallPressed:" target="ClZ-60-myJ" id="tVl-6l-eul"/>
@ -191,12 +186,23 @@
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="Optimize" bezelStyle="rounded" alignment="center" borderStyle="border" inset="2" id="Sop-mp-zDW">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="label" size="13"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="optimizeThemePressed:" target="ClZ-60-myJ" id="eFv-na-WZg"/>
</connections>
</button>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="x6y-uP-1AE">
<rect key="frame" x="158" y="94" width="39" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" bezelStyle="rounded" image="NSRefreshFreestandingTemplate" imagePosition="only" alignment="center" borderStyle="border" imageScaling="axesIndependently" inset="2" id="bOt-6K-Swp">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="refreshIndexedThemesPressed:" target="ClZ-60-myJ" id="iRd-Gj-qZR"/>
</connections>
</button>
</subviews>
</view>
<connections>
@ -226,4 +232,7 @@
</connections>
</viewController>
</objects>
<resources>
<image name="NSRefreshFreestandingTemplate" width="14" height="14"/>
</resources>
</document>

View File

@ -21,9 +21,14 @@ final class GradientView : NSView {
}
final class ThemeManagerVC: NSViewController,
NSTableViewDelegate, NSTableViewDataSource, WebFrameLoadDelegate, WebUIDelegate {
NSTableViewDelegate,
NSTableViewDataSource,
WebFrameLoadDelegate,
WebUIDelegate,
NSComboBoxDelegate,
NSComboBoxDataSource {
var targetVolume : String? = nil
var themes : [String] = [String]()
var manager : ThemeManager?
@IBOutlet var installedThemesCheckBox : NSButton!
@ -62,19 +67,10 @@ NSTableViewDelegate, NSTableViewDataSource, WebFrameLoadDelegate, WebUIDelegate
}
self.loaded = true
/*
let winImagePath = "/Library/Desktop Pictures/Ink Cloud.jpg"
if fm.fileExists(atPath: winImagePath) {
let winImage = NSImage(byReferencingFile: winImagePath)
let winImageSize = NSMakeSize(self.view.frame.width, self.view.frame.height)
winImage?.size = winImageSize
self.view.window?.backgroundColor = NSColor.init(patternImage: winImage!)
}*/
self.view.window?.title = self.view.window!.title.locale
let settingVC = AppSD.settingsWC?.contentViewController as? SettingsViewController
settingVC?.themeUserField.isEnabled = false
settingVC?.themeUserCBox.isEnabled = false
settingVC?.themeRepoField.isEnabled = false
self.webView.drawsBackground = false
self.webView.uiDelegate = self
@ -82,17 +78,17 @@ NSTableViewDelegate, NSTableViewDataSource, WebFrameLoadDelegate, WebUIDelegate
self.webView.frameLoadDelegate = self
self.webView.mainFrame.frameView.allowsScrolling = false
localize(view: self.view)
AppSD.isInstallerOpen = true
settingVC?.disksPopUp.isEnabled = false
settingVC?.updateCloverButton.isEnabled = false
settingVC?.unmountButton.isEnabled = false
AppSD.themes.removeAll()
self.nameBox.completes = true
self.nameBox.delegate = self
self.nameBox.dataSource = self
self.nameBox.usesDataSource = true
self.nameBox.removeAllItems()
self.sidebar.delegate = self
self.sidebar.dataSource = self
self.sidebar.backgroundColor = NSColor.clear
@ -119,8 +115,14 @@ NSTableViewDelegate, NSTableViewDataSource, WebFrameLoadDelegate, WebUIDelegate
}
}
self.reloadThemes()
}
func reloadThemes() {
self.themes.removeAll()
self.sidebar.reloadData()
self.showIndexing()
//return
let themeManagerIndexDir = NSHomeDirectory().addPath("Library/Application Support/CloverApp/Themeindex/\(AppSD.themeUser)_\(AppSD.themeRepo)")
self.manager = ThemeManager(user: AppSD.themeUser,
@ -128,7 +130,6 @@ NSTableViewDelegate, NSTableViewDataSource, WebFrameLoadDelegate, WebUIDelegate
basePath: themeManagerIndexDir,
indexDir: themeManagerIndexDir,
delegate: self)
/*
1) immediately load indexed themes (if any).
Fast if thumbnails already exists.
@ -142,7 +143,7 @@ NSTableViewDelegate, NSTableViewDataSource, WebFrameLoadDelegate, WebUIDelegate
2) download thumbnails.
Slower if thumbnails didn't exist or themes never indexed.
*/
self.manager?.getThemes { (t) in
let sorted = t.sorted()
for t in sorted {
@ -157,16 +158,48 @@ NSTableViewDelegate, NSTableViewDataSource, WebFrameLoadDelegate, WebUIDelegate
if showInstalled {
return AppSD.installedThemes
}
return AppSD.themes
return self.themes
}
func numberOfItems(in comboBox: NSComboBox) -> Int {
return self.dataSource().count
}
func comboBox(_ comboBox: NSComboBox, indexOfItemWithStringValue string: String) -> Int {
return self.dataSource().firstIndex(of: string) ?? -1
}
func comboBox(_ comboBox: NSComboBox, objectValueForItemAt index: Int) -> Any? {
return self.dataSource()[index]
}
func comboBox(_ comboBox: NSComboBox, completedString string: String) -> String? {
for theme in dataSource() {
if theme.lowercased().hasPrefix(string.lowercased()) {
return theme
}
}
return nil
}
@IBAction func refreshIndexedThemesPressed(_ sender: NSButton!) {
if let repoDir = self.manager?.themeManagerIndexDir {
// delete old index
if fm.fileExists(atPath: repoDir) {
try? fm.removeItem(atPath: repoDir)
}
// re index the repository
self.reloadThemes()
} else {
NSSound.beep()
}
}
@IBAction func showInstalledThemes(_ sender: NSButton!) {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
let copy = self.manager!.getIndexedThemes().sorted() // in cases of low downloads
self.nameBox.removeAllItems()
self.sidebar.noteNumberOfRowsChanged()
AppSD.installedThemes.removeAll()
AppSD.themes.removeAll()
self.themes.removeAll()
if sender.state == .on {
if (self.targetVolume != nil && fm.fileExists(atPath: self.targetVolume!)) {
@ -196,15 +229,13 @@ NSTableViewDelegate, NSTableViewDataSource, WebFrameLoadDelegate, WebUIDelegate
} catch { }
}
AppSD.installedThemes = installed.sorted()
self.nameBox.addItems(withObjectValues: installed.sorted())
if installed.count == 0 {
self.showNoThemes()
}
}
self.showInstalled = true
} else {
AppSD.themes = copy
self.nameBox.addItems(withObjectValues: copy.sorted())
self.themes = copy
self.showInstalled = false
if copy.count == 0 {
self.showNoThemes()
@ -491,18 +522,15 @@ NSTableViewDelegate, NSTableViewDataSource, WebFrameLoadDelegate, WebUIDelegate
}
func addRow(for theme: String) {
let index = AppSD.themes.count
AppSD.themes.append(theme)
//if self.installedThemesCheckBox.state == .off {
self.sidebar.beginUpdates()
self.sidebar.insertRows(at: IndexSet(integer: index), withAnimation: .slideUp)
self.sidebar.endUpdates()
//}
self.nameBox.addItem(withObjectValue: theme)
let index = self.themes.count
self.themes.append(theme)
self.sidebar.beginUpdates()
self.sidebar.insertRows(at: IndexSet(integer: index), withAnimation: .slideUp)
self.sidebar.endUpdates()
}
func add(theme: String) {
if AppSD.themes.contains(theme) {
if self.themes.contains(theme) {
return
}
if let sha = self.manager?.getSha() {
@ -562,8 +590,10 @@ NSTableViewDelegate, NSTableViewDataSource, WebFrameLoadDelegate, WebUIDelegate
self.optimizeButton.isEnabled = false
self.optimizeButton.state = .off
let sr = self.sidebar.selectedRow
if sr >= 0 {
if let v = self.sidebar.view(atColumn: 0, row: sr, makeIfNecessary: false) as? ThemeView {
self.installButton.title = v.isUpToDate ? "Install".locale : "Update".locale
if v.isInstalled {
self.unistallButton.animator().isHidden = false
self.unistallButton.isEnabled = true
@ -638,6 +668,8 @@ NSTableViewDelegate, NSTableViewDataSource, WebFrameLoadDelegate, WebUIDelegate
v.load()
}
}
} else {
self.installButton.title = "Install".locale
}
}
@ -805,7 +837,7 @@ final class ThemeManagerWC: NSWindowController, NSWindowDelegate {
settingVC?.updateCloverButton.isEnabled = true
settingVC?.searchESPDisks()
AppSD.isInstallerOpen = false
settingVC?.themeUserField.isEnabled = true
settingVC?.themeUserCBox.isEnabled = true
settingVC?.themeRepoField.isEnabled = true
self.window = nil
self.close()

View File

@ -17,6 +17,7 @@ class ThemeView: NSView, WebFrameLoadDelegate, WebUIDelegate {
var info : String?
var row : Int
var isInstalled = false
var isUpToDate = true
public let webView: WebView = {
let wv = WebView(frame: NSMakeRect(0, 0, 147, 82))
@ -111,8 +112,10 @@ class ThemeView: NSView, WebFrameLoadDelegate, WebUIDelegate {
}
func setInstalledStatus() {
var installPath = ""
if let vol = self.manager.delegate?.targetVolume {
self.isInstalled = fm.fileExists(atPath: vol.addPath("EFI/CLOVER/themes").addPath(self.name))
installPath = vol.addPath("EFI/CLOVER/themes").addPath(self.name)
self.isInstalled = fm.fileExists(atPath: installPath)
if (self.imagePath == nil) {
if fm.fileExists(atPath: vol.addPath("EFI/CLOVER/themes").addPath(self.name).addPath("theme.svg")) {
self.imagePath = vol.addPath("EFI/CLOVER/themes").addPath(self.name).addPath("theme.svg")
@ -126,7 +129,8 @@ class ThemeView: NSView, WebFrameLoadDelegate, WebUIDelegate {
if let path = self.imagePath {
if self.isInstalled {
let icon = Bundle.main.path(forResource: "check", ofType: "png")
self.isUpToDate = self.manager.isThemeUpToDate(at: installPath)
let icon = Bundle.main.path(forResource: self.isUpToDate ? "check" : "update", ofType: "png")
self.webView.mainFrame.loadHTMLString("""
<html>
<body>
@ -138,6 +142,7 @@ class ThemeView: NSView, WebFrameLoadDelegate, WebUIDelegate {
</html>
""", baseURL: Bundle.main.bundleURL)
} else {
self.isUpToDate = true
self.webView.mainFrame.loadHTMLString("""
<html>
<body>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -351,7 +351,7 @@ do
break
;;
"quit")
exit 0
osascript -e 'tell application "Terminal" to close first window' & exit
;;
*)
echo "invalid option $REPLY"