]> granicus.if.org Git - handbrake/commitdiff
MacGui: show better error message to the user if a preset fails to import
authorDamiano Galassi <damiog@gmail.com>
Sat, 10 Oct 2015 10:19:22 +0000 (12:19 +0200)
committerDamiano Galassi <damiog@gmail.com>
Sat, 10 Oct 2015 19:50:26 +0000 (21:50 +0200)
macosx/HBPreset.h
macosx/HBPreset.m
macosx/HBPresetsManager.m
macosx/HBPresetsViewController.m

index 1c5375edb57f08d3740b09ff533f285eb94642ac..bf5b51e8b8d317b9ed2662552c28c37dbe0b39b5 100644 (file)
@@ -35,7 +35,7 @@ typedef NS_ENUM(NSUInteger, HBPresetFormat) {
  *  @return An initialized preset—which might be different than the original receiver—that contains the preset at URL,
  *  or nil if there is an error or if the contents of the resource are not and HandBrake preset.
  */
-- (nullable instancetype)initWithContentsOfURL:(NSURL *)url;
+- (nullable instancetype)initWithContentsOfURL:(NSURL *)url error:(NSError **)outError;
 
 /**
  *  Writes a property list or json representation of the contents of the preset to a given URL.
index 8b3d5c6bab54ead9e268ba1e7b3165922eafe9ea..58fe6a36d8f51cca16b448284b6019a2227213c6 100644 (file)
 {
     NSParameterAssert(dict);
 
+    NSString *name = dict[@"PresetName"] ? dict[@"PresetName"] : @"Unnamed preset";
+    BOOL builtIn = [dict[@"Type"] boolValue] ? NO : YES;
+    BOOL defaultPreset = [dict[@"Default"] boolValue];
+
     if ([dict[@"Folder"] boolValue])
     {
-        self = [self initWithFolderName:dict[@"PresetName"] builtIn:![dict[@"Type"] boolValue]];
+        self = [self initWithFolderName:name builtIn:builtIn];
 
         for (NSDictionary *childDict in [dict[@"ChildrenArray"] reverseObjectEnumerator])
         {
     }
     else
     {
-        self = [self initWithName:dict[@"PresetName"]
+        self = [self initWithName:name
                           content:dict
-                          builtIn:![dict[@"Type"] boolValue]];
-        self.isDefault = [dict[@"Default"] boolValue];
+                          builtIn:builtIn];
+        self.isDefault = defaultPreset;
     }
 
     return self;
 }
 
-- (nullable instancetype)initWithContentsOfURL:(NSURL *)url
+- (nullable instancetype)initWithContentsOfURL:(NSURL *)url error:(NSError **)outError
 {
+    NSParameterAssert(url);
+
     NSArray *presetsArray;
-    NSString *presetsJson;
+    NSString *presetsString;
 
+    // Read a json file or the old plists format
     if ([url.pathExtension isEqualToString:@"json"])
     {
         NSData *data = [[NSData alloc] initWithContentsOfURL:url];
-        presetsJson = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
+        presetsString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
     }
     else
     {
         NSArray *array = [[NSArray alloc] initWithContentsOfURL:url];
         if ([NSJSONSerialization isValidJSONObject:array])
         {
-            presetsJson = [NSJSONSerialization HB_StringWithJSONObject:array options:0 error:NULL];
+            presetsString = [NSJSONSerialization HB_StringWithJSONObject:array options:0 error:NULL];
         }
     }
 
     // Run the json through the libhb import function
     // to avoid importing unknowns keys.
-    if (presetsJson.length) {
+    if (presetsString.length)
+    {
         char *importedJson;
-        int   result;
-
-        result = hb_presets_import_json(presetsJson.UTF8String, &importedJson);
+        hb_presets_import_json(presetsString.UTF8String, &importedJson);
 
         if (importedJson)
         {
             id importedPresets = [NSJSONSerialization HB_JSONObjectWithUTF8String:importedJson options:0 error:NULL];
+            free(importedJson);
 
             if ([importedPresets isKindOfClass:[NSDictionary class]])
             {
-                presetsArray = importedPresets[@"PresetList"];
+                int hb_major, hb_minor, hb_micro;
+                int major;
+
+                hb_presets_current_version(&hb_major, &hb_minor, &hb_micro);
+                major = [importedPresets[@"VersionMajor"] intValue];
+
+                if (major <= hb_major)
+                {
+                    presetsArray = importedPresets[@"PresetList"];
+                }
+                else
+                {
+                    // Change in major indicates non-backward compatible preset changes.
+                    if (outError)
+                    {
+                        *outError = [self newerPresetErrorForUrl:url];
+                    }
+                    return nil;
+                }
             }
             else if ([importedPresets isKindOfClass:[NSArray class]])
             {
                 presetsArray = importedPresets;
             }
         }
-
-        free(importedJson);
     }
 
+    // Convert the array to a HBPreset tree.
     if (presetsArray.count)
     {
         self = [self initWithFolderName:@"Imported Presets" builtIn:NO];
         }
         return self;
     }
+    else if (outError)
+    {
+        *outError = [self invalidPresetErrorForUrl:url];
+    }
 
     return nil;
 }
 
+- (NSError *)invalidPresetErrorForUrl:(NSURL *)url
+{
+    NSString *description = [NSString stringWithFormat:NSLocalizedString(@"The preset \"%@\" could not be imported.", nil),
+                             url.lastPathComponent];
+    NSString *reason = NSLocalizedString(@"The selected preset is invalid.", nil);
+
+    return [NSError errorWithDomain:@"HBPresetDomain" code:1 userInfo:@{NSLocalizedDescriptionKey: description,
+                                                                        NSLocalizedRecoverySuggestionErrorKey: reason}];
+
+}
+
+- (NSError *)newerPresetErrorForUrl:(NSURL *)url
+{
+    NSString *description = [NSString stringWithFormat:NSLocalizedString(@"The preset \"%@\" could not be imported.", nil),
+                             url.lastPathComponent];
+    NSString *reason = NSLocalizedString(@"The selected preset was created with a newer version of HandBrake.", nil);
+
+    return [NSError errorWithDomain:@"HBPresetDomain" code:2 userInfo:@{NSLocalizedDescriptionKey: description,
+                                                                        NSLocalizedRecoverySuggestionErrorKey: reason}];
+    
+}
+
 - (NSDictionary *)dictionary
 {
     NSMutableDictionary *output = [[NSMutableDictionary alloc] init];
index a98269298378c28c3a655b925d0d9a84251e390a..f1970904402e17ee54868044a367358c807c5710 100644 (file)
@@ -70,7 +70,8 @@ NSString *HBPresetsChangedNotification = @"HBPresetsChangedNotification";
  */
 - (void)loadOldPresetsFromURL:(NSURL *)url
 {
-    HBPreset *oldPresets = [[HBPreset alloc] initWithContentsOfURL:url];
+    NSError *error;
+    HBPreset *oldPresets = [[HBPreset alloc] initWithContentsOfURL:url error:&error];
 
     for (HBPreset *preset in oldPresets.children)
     {
index d58cb67157d6b7e0e8e1a2241d57fdf555fd3c6d..fd8bc96774a8fe721b72aab5cd8897fb094c27a8 100644 (file)
 
          for (NSURL *url in panel.URLs)
          {
-             HBPreset *import = [[HBPreset alloc] initWithContentsOfURL:url];
+             NSError *error;
+             HBPreset *import = [[HBPreset alloc] initWithContentsOfURL:url error:&error];
+
+             if (import == nil)
+             {
+                 [self presentError:error];
+             }
+
              for (HBPreset *child in import.children)
              {
                  [self.presets addPreset:child];