3 This file is part of the HandBrake source code.
4 Homepage: <http://handbrake.fr/>.
5 It may be used under the terms of the GNU General Public License. */
10 #import "NSJSONSerialization+HBAdditions.h"
12 @implementation HBPreset
19 _name = @"New Preset";
20 _presetDescription = @"";
26 - (instancetype)initWithName:(NSString *)title content:(NSDictionary *)content builtIn:(BOOL)builtIn;
33 _content = [content copy];
34 if ([content[@"PresetDescription"] isKindOfClass:[NSString class]])
36 _presetDescription = [content[@"PresetDescription"] copy];
42 - (instancetype)initWithFolderName:(NSString *)title builtIn:(BOOL)builtIn;
54 - (instancetype)initWithDictionary:(NSDictionary *)dict
56 NSParameterAssert(dict);
58 if ([dict[@"Folder"] boolValue])
60 self = [self initWithFolderName:dict[@"PresetName"] builtIn:![dict[@"Type"] boolValue]];
62 for (NSDictionary *childDict in [dict[@"ChildrenArray"] reverseObjectEnumerator])
64 HBPreset *childPreset = [[HBPreset alloc] initWithDictionary:childDict];
65 [self insertObject:childPreset inChildrenAtIndex:0];
70 self = [self initWithName:dict[@"PresetName"]
72 builtIn:![dict[@"Type"] boolValue]];
73 self.isDefault = [dict[@"Default"] boolValue];
79 - (nullable instancetype)initWithContentsOfURL:(NSURL *)url
81 NSArray *presetsArray;
82 NSString *presetsJson;
84 if ([url.pathExtension isEqualToString:@"json"])
86 NSData *data = [[NSData alloc] initWithContentsOfURL:url];
87 presetsJson = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
91 NSArray *array = [[NSArray alloc] initWithContentsOfURL:url];
92 if ([NSJSONSerialization isValidJSONObject:array])
94 presetsJson = [NSJSONSerialization HB_StringWithJSONObject:array options:0 error:NULL];
98 // Run the json through the libhb import function
99 // to avoid importing unknowns keys.
100 if (presetsJson.length) {
101 char *importedJson = hb_presets_import_json(presetsJson.UTF8String);
105 id importedPresets = [NSJSONSerialization HB_JSONObjectWithUTF8String:importedJson options:0 error:NULL];
107 if ([importedPresets isKindOfClass:[NSDictionary class]])
109 presetsArray = importedPresets[@"PresetList"];
111 else if ([importedPresets isKindOfClass:[NSArray class]])
113 presetsArray = importedPresets;
120 if (presetsArray.count)
122 self = [self initWithFolderName:@"Imported Presets" builtIn:NO];
126 for (NSDictionary *dict in presetsArray)
128 HBPreset *preset = [[HBPreset alloc] initWithDictionary:dict];
129 [self.children addObject:preset];
138 - (NSDictionary *)dictionary
140 NSMutableDictionary *output = [[NSMutableDictionary alloc] init];
141 [output addEntriesFromDictionary:self.content];
143 output[@"PresetName"] = self.name;
144 output[@"PresetDescription"] = self.presetDescription;
145 output[@"Folder"] = [NSNumber numberWithBool:!self.isLeaf];
146 output[@"Type"] = @(!self.isBuiltIn);
147 output[@"Default"] = @(self.isDefault);
151 NSMutableArray *childArray = [[NSMutableArray alloc] init];
152 for (HBPreset *child in self.children)
154 [childArray addObject:[child dictionary]];
157 output[@"ChildrenArray"] = childArray;
163 - (BOOL)writeToURL:(NSURL *)url atomically:(BOOL)atomically format:(HBPresetFormat)format removeRoot:(BOOL)removeRoot;
170 presetList = self.dictionary[@"ChildrenArray"];
174 presetList = @[self.dictionary];
177 int major, minor, micro;
178 hb_presets_current_version(&major, &minor, µ);
180 NSDictionary *dict = @{ @"PresetList": presetList,
181 @"VersionMajor": @(major),
182 @"VersionMicro": @(minor),
183 @"VersionMinor": @(micro) };
185 if (format == HBPresetFormatPlist)
187 success = [dict writeToURL:url atomically:atomically];
191 NSData *jsonPreset = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:NULL];
192 success = [jsonPreset writeToURL:url atomically:atomically];
198 - (id)copyWithZone:(NSZone *)zone
200 HBPreset *node = [super copyWithZone:zone];
201 node->_name = [self.name copy];
202 node->_content = [self.content copy];
203 node->_presetDescription = [self.presetDescription copy];
210 return self.name.hash + self.isBuiltIn + self.isLeaf;
215 // Run the libhb clean function
216 NSString *presetJson = [NSJSONSerialization HB_StringWithJSONObject:self.dictionary options:0 error:NULL];
218 if (presetJson.length)
220 char *cleanedJson = hb_presets_clean_json(presetJson.UTF8String);
221 NSDictionary *cleanedDict = [NSJSONSerialization HB_JSONObjectWithUTF8String:cleanedJson options:0 error:NULL];
224 if ([cleanedDict isKindOfClass:[NSDictionary class]])
226 self.content = cleanedDict;
231 - (void)setName:(NSString *)name
234 [self.delegate nodeDidChange:self];
237 - (void)setIsDefault:(BOOL)isDefault
239 _isDefault = isDefault;
240 [self.delegate nodeDidChange:self];
245 - (BOOL)validateName:(id *)ioValue error:(NSError * __autoreleasing *)outError
247 // Return an error is the name is empty
248 if (![*ioValue length])
252 *outError = [[NSError alloc] initWithDomain:@"HBErrorDomain"
254 userInfo:@{NSLocalizedDescriptionKey:@"The preset title cannot be empty.",
255 NSLocalizedRecoverySuggestionErrorKey:@"Please enter a title."}];