mirror of
https://github.com/CloverHackyColor/CloverBootloader.git
synced 2024-11-27 12:15:19 +01:00
c8969630f3
Introduced a real Property List Editor. Fixed Theme manager engine. Other minor fixes
300 lines
12 KiB
Swift
300 lines
12 KiB
Swift
/*
|
|
* vector sigma (https://github.com/vectorsigma72)
|
|
* Copyright 2020 vector sigma All Rights Reserved.
|
|
*
|
|
* The source code contained or described herein and all documents related
|
|
* to the source code ("Material") are owned by vector sigma.
|
|
* Title to the Material remains with vector sigma or its suppliers and licensors.
|
|
* The Material is proprietary of vector sigma and is protected by worldwide copyright.
|
|
* No part of the Material may be used, copied, reproduced, modified, published,
|
|
* uploaded, posted, transmitted, distributed, or disclosed in any way without
|
|
* vector sigma's prior express written permission.
|
|
*
|
|
* No license under any patent, copyright, trade secret or other intellectual
|
|
* property right is granted to or conferred upon you by disclosure or delivery
|
|
* of the Materials, either expressly, by implication, inducement, estoppel or
|
|
* otherwise. Any license under such intellectual property rights must be
|
|
* express and approved by vector sigma in writing.
|
|
*
|
|
* Unless otherwise agreed by vector sigma in writing, you may not remove or alter
|
|
* this notice or any other notice embedded in Materials by vector sigma in any way.
|
|
*
|
|
* The license is granted for the CloverBootloader project (i.e. https://github.com/CloverHackyColor/CloverBootloader)
|
|
* and all the users as long as the Material is used only within the
|
|
* source code and for the exclusive use of CloverBootloader, which must
|
|
* be free from any type of payment or commercial service for the license to be valid.
|
|
*/
|
|
|
|
import Cocoa
|
|
|
|
@available(OSX 10.11, *)
|
|
extension PlistEditorVC {
|
|
@objc func boolPopUpPressed(sender: PEPopUpButton) {
|
|
let originalValue : Bool = sender.node!.tagdata!.value as! Bool
|
|
let actualValue = (sender.title == localizedYes) ? true : false
|
|
|
|
if originalValue != actualValue {
|
|
self.outline.undo_SetBoolValue(node: sender.node!,
|
|
sender: sender,
|
|
originalValue: originalValue,
|
|
actualValue: actualValue)
|
|
}
|
|
}
|
|
|
|
@objc func typePopUpPressed(sender: PEPopUpButton) {
|
|
let originalType = sender.node!.tagdata!.type
|
|
let actualType = sender.selectedItem?.representedObject as! PlistTag
|
|
if originalType != actualType {
|
|
let newTree : TagData? = sender.node?.tagdata?.copy() as? TagData
|
|
|
|
newTree?.type = actualType
|
|
/*
|
|
switching between contenitors types (Array/Dictionary) can save some memory
|
|
since we need don't need to backup the childrens.
|
|
Reloading the view it's enough to show children correctly
|
|
*/
|
|
|
|
switch originalType {
|
|
case .Dictionary:
|
|
if actualType == .Array {
|
|
var oldKeys : PEArray = PEArray()
|
|
var newKeys : PEArray = PEArray()
|
|
|
|
var index : Int = 0
|
|
for n in sender.node!.mutableChildren {
|
|
let ex : PENode = n as! PENode
|
|
oldKeys.append(ex.tagdata!.key)
|
|
newKeys.append("\(localizedItem) \(index)")
|
|
index+=1
|
|
}
|
|
|
|
self.outline.undo_ChangeContenitor(node: sender.node!,
|
|
sender: sender,
|
|
originalType: gPlistTagStr(tag: originalType),
|
|
actualType: gPlistTagStr(tag: actualType),
|
|
oldKeys: oldKeys,
|
|
newKeys: newKeys)
|
|
} else {
|
|
if actualType == .String {
|
|
newTree?.value = ""
|
|
} else if actualType == .Number {
|
|
newTree?.value = 0
|
|
} else if actualType == .Bool {
|
|
newTree?.value = false
|
|
} else if actualType == .Data {
|
|
newTree?.value = Data()
|
|
} else if actualType == .Date {
|
|
newTree?.value = Date()
|
|
}
|
|
self.outline.undo_ChangeType(node: sender.node!,
|
|
newData: newTree!,
|
|
oldData: sender.node!.tagdata!,
|
|
newChilds: nil,
|
|
oldChilds: sender.node!.children,
|
|
sender: sender)
|
|
}
|
|
break
|
|
case .Array:
|
|
if actualType == .Dictionary {
|
|
var oldKeys : PEArray = PEArray()
|
|
var newKeys : PEArray = PEArray()
|
|
|
|
var index : Int = 0
|
|
for n in sender.node!.mutableChildren {
|
|
let _ : PENode = n as! PENode
|
|
oldKeys.append("\(localizedItem) \(index)")
|
|
if index == 0 {
|
|
newKeys.append(localizedNewItem)
|
|
} else {
|
|
newKeys.append("\(localizedNewItem) - \(index)")
|
|
}
|
|
|
|
index+=1
|
|
}
|
|
self.outline.undo_ChangeContenitor(node: sender.node!,
|
|
sender: sender,
|
|
originalType: gPlistTagStr(tag: originalType),
|
|
actualType: gPlistTagStr(tag: actualType),
|
|
oldKeys: oldKeys,
|
|
newKeys: newKeys)
|
|
} else {
|
|
if actualType == .String {
|
|
newTree?.value = ""
|
|
} else if actualType == .Number {
|
|
newTree?.value = 0
|
|
} else if actualType == .Bool {
|
|
newTree?.value = false
|
|
} else if actualType == .Data {
|
|
newTree?.value = Data()
|
|
} else if actualType == .Date {
|
|
newTree?.value = Date()
|
|
}
|
|
|
|
self.outline.undo_ChangeType(node: sender.node!,
|
|
newData: newTree!,
|
|
oldData: sender.node!.tagdata!,
|
|
newChilds: nil,
|
|
oldChilds: sender.node!.children,
|
|
sender: sender)
|
|
}
|
|
break
|
|
case .String:
|
|
let oldString = sender.node?.tagdata?.value as! String
|
|
if actualType == .Number {
|
|
let nv = localizedNumberFormatter().number(from: oldString) ?? 0
|
|
newTree?.value = nv
|
|
} else if actualType == .Bool {
|
|
// check if old string is compatible with a bool value
|
|
var bv : Bool = false
|
|
let localized = localizedYes
|
|
let firstChar = localized[localized.startIndex]
|
|
if oldString.hasPrefix(String(firstChar).lowercased())
|
|
|| oldString.hasPrefix(String(firstChar).uppercased()) {
|
|
bv = true
|
|
}
|
|
newTree?.value = bv
|
|
} else if actualType == .Data {
|
|
// da migliorare (se la stringa era un hex valido usare quella!!)
|
|
// check if old string is compatible with bytes
|
|
var dv : Data? = nil
|
|
|
|
if isHexStringValid(string: oldString) == "HexSuccess" {
|
|
dv = oldString.hexadecimal()
|
|
}
|
|
|
|
if (dv == nil) {
|
|
dv = oldString.data(using: String.Encoding.utf8)
|
|
}
|
|
|
|
if (dv == nil) {
|
|
dv = Data()
|
|
}
|
|
newTree?.value = dv!
|
|
} else if actualType == .Date {
|
|
// check if old string is compatible with date
|
|
var dv : Date? = nil
|
|
dv = localizedStringToDateS(oldString) // first try with "S" version that can be nil
|
|
|
|
if (dv == nil) {
|
|
dv = funcyDateFromUser(oldString) // secondly try to detect it (NSDataDetector + NSTextCheckingResult)
|
|
}
|
|
if (dv == nil) {
|
|
dv = Date() // no way, init a new one..
|
|
}
|
|
newTree?.value = dv!
|
|
} else if actualType == .Dictionary {
|
|
newTree?.value = nil
|
|
} else if actualType == .Array {
|
|
newTree?.value = nil
|
|
}
|
|
self.outline.undo_ChangeType(node: sender.node!,
|
|
newData: newTree!,
|
|
oldData: sender.node!.tagdata!,
|
|
newChilds: nil,
|
|
oldChilds: sender.node!.children,
|
|
sender: sender)
|
|
break
|
|
case .Bool:
|
|
if actualType == .String {
|
|
var ns : String = "0"
|
|
if (sender.node?.tagdata?.value as! NSNumber).boolValue {
|
|
ns = "1"
|
|
}
|
|
newTree?.value = ns
|
|
} else if actualType == .Number {
|
|
var nn : Int = 0
|
|
if (sender.node?.tagdata?.value as! NSNumber).boolValue {
|
|
nn = 1
|
|
}
|
|
newTree?.value = nn
|
|
} else if actualType == .Data {
|
|
newTree?.value = Data()
|
|
} else if actualType == .Date {
|
|
newTree?.value = Date()
|
|
} else if actualType == .Dictionary {
|
|
newTree?.value = nil
|
|
} else if actualType == .Array {
|
|
newTree?.value = nil
|
|
}
|
|
self.outline.undo_ChangeType(node: sender.node!,
|
|
newData: newTree!,
|
|
oldData: sender.node!.tagdata!,
|
|
newChilds: nil,
|
|
oldChilds: sender.node!.children,
|
|
sender: sender)
|
|
break
|
|
case .Number:
|
|
if actualType == .String {
|
|
let str = localizedNumberFormatter().string(from: sender.node!.tagdata!.value as! NSNumber)
|
|
newTree?.value = str ?? ""
|
|
} else if actualType == .Bool {
|
|
var nb : Bool = false
|
|
if (sender.node?.tagdata?.value as! NSNumber).boolValue {
|
|
nb = true
|
|
}
|
|
newTree?.value = nb
|
|
} else if actualType == .Data {
|
|
newTree?.value = Data()
|
|
} else if actualType == .Date {
|
|
newTree?.value = Date()
|
|
} else if actualType == .Dictionary {
|
|
newTree?.value = nil
|
|
} else if actualType == .Array {
|
|
newTree?.value = nil
|
|
}
|
|
self.outline.undo_ChangeType(node: sender.node!,
|
|
newData: newTree!,
|
|
oldData: sender.node!.tagdata!,
|
|
newChilds: nil,
|
|
oldChilds: sender.node!.children,
|
|
sender: sender)
|
|
break
|
|
case .Data:
|
|
if actualType == .String {
|
|
newTree?.value = "\(sender.node!.tagdata!.value!)"
|
|
} else if actualType == .Bool {
|
|
newTree?.value = false
|
|
} else if actualType == .Number {
|
|
newTree?.value = 0
|
|
} else if actualType == .Date {
|
|
newTree?.value = Date()
|
|
} else if actualType == .Dictionary {
|
|
newTree?.value = nil
|
|
} else if actualType == .Array {
|
|
newTree?.value = nil
|
|
}
|
|
self.outline.undo_ChangeType(node: sender.node!,
|
|
newData: newTree!,
|
|
oldData: sender.node!.tagdata!,
|
|
newChilds: nil,
|
|
oldChilds: sender.node!.children,
|
|
sender: sender)
|
|
break
|
|
case .Date:
|
|
if actualType == .String {
|
|
let dateStr = localizedDateToString(sender.node!.tagdata!.value as! Date)
|
|
newTree?.value = dateStr
|
|
} else if actualType == .Bool {
|
|
newTree?.value = false
|
|
} else if actualType == .Number {
|
|
newTree?.value = 0
|
|
} else if actualType == .Data {
|
|
newTree?.value = Data()
|
|
} else if actualType == .Dictionary {
|
|
newTree?.value = nil
|
|
} else if actualType == .Array {
|
|
newTree?.value = nil
|
|
}
|
|
self.outline.undo_ChangeType(node: sender.node!,
|
|
newData: newTree!,
|
|
oldData: sender.node!.tagdata!,
|
|
newChilds: nil,
|
|
oldChilds: sender.node!.children,
|
|
sender: sender)
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|