--- /dev/null
+/* HBAutoNamer.h $
+
+ This file is part of the HandBrake source code.
+ Homepage: <http://handbrake.fr/>.
+ It may be used under the terms of the GNU General Public License. */
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@class HBJob;
+
+@interface HBAutoNamer : NSObject
+
+- (instancetype)initWithJob:(HBJob *)job;
+
+- (void)updateFileExtension;
+- (void)updateFileName;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+/* HBAutoNamer.m $
+
+ This file is part of the HandBrake source code.
+ Homepage: <http://handbrake.fr/>.
+ It may be used under the terms of the GNU General Public License. */
+
+#import "HBAutoNamer.h"
+
+#import "HBJob.h"
+#import "HBUtilities.h"
+
+static void *HBAutoNamerPrefsContext = &HBAutoNamerPrefsContext;
+static void *HBAutoNamerContext = &HBAutoNamerContext;
+
+@interface HBAutoNamer ()
+
+@property (nonatomic) HBJob *job;
+@property (nonatomic) NSArray<NSString *> *format;
+
+@end
+
+@implementation HBAutoNamer
+
+- (instancetype)initWithJob:(HBJob *)job
+{
+ self = [super init];
+ if (self)
+ {
+ _job = job;
+ _format = [[NSUserDefaults standardUserDefaults] objectForKey:@"HBAutoNamingFormat"];
+ [self addFormatObservers];
+ [self addJobObservers];
+ [self addPrefsObservers];
+ }
+ return self;
+}
+
+- (void)dealloc
+{
+ [self removeFormatObservers];
+ [self removeJobObservers];
+ [self removePrefsObservers];
+}
+
+#pragma mark - KVO
+
+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
+{
+ if (context == HBAutoNamerContext)
+ {
+ [self updateFileName];
+ }
+ else if (context == HBAutoNamerPrefsContext)
+ {
+ [self removeJobObservers];
+ self.format = [[NSUserDefaults standardUserDefaults] objectForKey:@"HBAutoNamingFormat"];
+ [self addJobObservers];
+ [self updateFileName];
+ [self updateFileExtension];
+ }
+ else
+ {
+ [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
+ }
+}
+
+- (void)addPrefsObservers
+{
+ NSUserDefaultsController *ud = [NSUserDefaultsController sharedUserDefaultsController];
+ [ud addObserver:self forKeyPath:@"values.HBAutoNamingFormat" options:0 context:HBAutoNamerPrefsContext];
+ [ud addObserver:self forKeyPath:@"values.HBAutoNamingRemoveUnderscore" options:0 context:HBAutoNamerPrefsContext];
+ [ud addObserver:self forKeyPath:@"values.HBAutoNamingRemovePunctuation" options:0 context:HBAutoNamerPrefsContext];
+ [ud addObserver:self forKeyPath:@"values.HBAutoNamingTitleCase" options:0 context:HBAutoNamerPrefsContext];
+}
+
+- (void)removePrefsObservers
+{
+ NSUserDefaultsController *ud = [NSUserDefaultsController sharedUserDefaultsController];
+ [ud removeObserver:self forKeyPath:@"values.HBAutoNamingFormat" context:HBAutoNamerPrefsContext];
+ [ud removeObserver:self forKeyPath:@"values.HBAutoNamingRemoveUnderscore" context:HBAutoNamerPrefsContext];
+ [ud removeObserver:self forKeyPath:@"values.HBAutoNamingRemovePunctuation" context:HBAutoNamerPrefsContext];
+ [ud removeObserver:self forKeyPath:@"values.HBAutoNamingTitleCase" context:HBAutoNamerPrefsContext];
+
+}
+
+#pragma mark - File extension
+
+- (void)addFormatObservers
+{
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateFileExtension:) name:HBAudioEncoderChangedNotification object:self.job.audio];
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateFileExtension:) name:HBChaptersChangedNotification object:self.job];
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateFileExtension:) name:HBRangeChangedNotification object:self.job.range];
+}
+
+- (void)removeFormatObservers
+{
+ [[NSNotificationCenter defaultCenter] removeObserver:self name:HBAudioEncoderChangedNotification object:self.job.audio];
+ [[NSNotificationCenter defaultCenter] removeObserver:self name:HBChaptersChangedNotification object:self.job];
+ [[NSNotificationCenter defaultCenter] removeObserver:self name:HBRangeChangedNotification object:_job.range];
+}
+
+- (void)updateFileExtension:(NSNotification *)notification
+{
+ NSUndoManager *undo = self.job.undo;
+
+ if (self.job && !(undo.isUndoing || undo.isRedoing))
+ {
+ NSString *extension = [HBUtilities automaticExtForJob:self.job];
+ if (![extension isEqualTo:self.job.outputFileName.pathExtension])
+ {
+ self.job.outputFileName = [[self.job.outputFileName stringByDeletingPathExtension] stringByAppendingPathExtension:extension];
+ }
+ }
+}
+
+- (void)updateFileExtension
+{
+ [self updateFileExtension:nil];
+}
+
+#pragma mark - File name
+
+- (void)addJobObservers
+{
+ for (NSString *formatKey in self.format)
+ {
+ if ([formatKey isEqualToString:@"{Chapters}"])
+ {
+ [self.job addObserver:self forKeyPath:@"range.chapterStart" options:0 context:HBAutoNamerContext];
+ [self.job addObserver:self forKeyPath:@"range.chapterStop" options:0 context:HBAutoNamerContext];
+ }
+ else if ([formatKey isEqualToString:@"{Quality/Bitrate}"])
+ {
+ [self.job addObserver:self forKeyPath:@"video.qualityType" options:0 context:HBAutoNamerContext];
+ [self.job addObserver:self forKeyPath:@"video.avgBitrate" options:0 context:HBAutoNamerContext];
+ [self.job addObserver:self forKeyPath:@"video.quality" options:0 context:HBAutoNamerContext];
+ }
+ }
+}
+
+- (void)removeJobObservers
+{
+ for (NSString *formatKey in self.format)
+ {
+ if ([formatKey isEqualToString:@"{Chapters}"])
+ {
+ [self.job removeObserver:self forKeyPath:@"range.chapterStart" context:HBAutoNamerContext];
+ [self.job removeObserver:self forKeyPath:@"range.chapterStop" context:HBAutoNamerContext];
+ }
+ else if ([formatKey isEqualToString:@"{Quality/Bitrate}"])
+ {
+ [self.job removeObserver:self forKeyPath:@"video.qualityType" context:HBAutoNamerContext];
+ [self.job removeObserver:self forKeyPath:@"video.avgBitrate" context:HBAutoNamerContext];
+ [self.job removeObserver:self forKeyPath:@"video.quality" context:HBAutoNamerContext];
+ }
+ }
+}
+
+- (void)updateFileName
+{
+ NSUndoManager *undo = self.job.undo;
+
+ if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultAutoNaming"] && self.job && !(undo.isUndoing || undo.isRedoing))
+ {
+ // Generate a new file name
+ NSString *fileName = [HBUtilities automaticNameForJob:self.job];
+
+ // Swap the old one with the new one
+ self.job.outputFileName = [NSString stringWithFormat:@"%@.%@", fileName, self.job.outputFileName.pathExtension];
+ }
+}
+
+@end
#import "HBAddPresetController.h"
#import "HBRenamePresetController.h"
+#import "HBAutoNamer.h"
+
@import HandBrakeKit;
static void *HBControllerScanCoreContext = &HBControllerScanCoreContext;
@property (nonatomic, readwrite, strong) HBTitleSelectionController *titlesSelectionController;
/// The current job.
-@property (nonatomic, strong, nullable) HBJob *job;
+@property (nonatomic, nullable) HBJob *job;
+@property (nonatomic, nullable) HBAutoNamer *autoNamer;
/// The current selected preset.
@property (nonatomic, strong) HBPreset *currentPreset;
[[NSNotificationCenter defaultCenter] removeObserver:self name:HBPictureChangedNotification object:_job.picture];
[[NSNotificationCenter defaultCenter] removeObserver:self name:HBFiltersChangedNotification object:_job.filters];
[[NSNotificationCenter defaultCenter] removeObserver:self name:HBVideoChangedNotification object:_job.video];
- [[NSNotificationCenter defaultCenter] removeObserver:self name:HBAudioEncoderChangedNotification object:_job.audio];
- [[NSNotificationCenter defaultCenter] removeObserver:self name:HBChaptersChangedNotification object:_job];
- [[NSNotificationCenter defaultCenter] removeObserver:self name:HBRangeChangedNotification object:_job.range];
+ self.autoNamer = nil;
}
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(customSettingUsed) name:HBPictureChangedNotification object:_job.picture];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(customSettingUsed) name:HBFiltersChangedNotification object:_job.filters];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(customSettingUsed) name:HBVideoChangedNotification object:_job.video];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateFileExtension:) name:HBAudioEncoderChangedNotification object:_job.audio];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateFileExtension:) name:HBChaptersChangedNotification object:_job];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(chapterPopUpChanged:) name:HBRangeChangedNotification object:_job.range];
+ self.autoNamer = [[HBAutoNamer alloc] initWithJob:self.job];
}
}
self.job = job;
}
-- (void)chapterPopUpChanged:(NSNotification *)notification
-{
- // We're changing the chapter range - we may need to flip the m4v/mp4 extension
- if (self.job.container & 0x030000 /*HB_MUX_MASK_MP4*/)
- {
- [self updateFileExtension:notification];
- }
-
- // If Auto Naming is on it might need to be update if it includes the chapters range
- [self updateFileName];
-}
-
- (void)formatChanged:(NSNotification *)notification
{
- [self updateFileExtension:notification];
[self customSettingUsed];
}
-- (void)updateFileName
-{
- [self updateFileExtension:nil];
-
- if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultAutoNaming"] && self.job)
- {
- // Generate a new file name
- NSString *fileName = [HBUtilities automaticNameForJob:self.job];
-
- // Swap the old one with the new one
- self.job.outputFileName = [NSString stringWithFormat:@"%@.%@", fileName, self.job.outputFileName.pathExtension];
- }
-}
-
-- (void)updateFileExtension:(NSNotification *)notification
-{
- if (self.job)
- {
- NSString *extension = [HBUtilities automaticExtForJob:self.job];
- if (![extension isEqualTo:self.job.outputFileName.pathExtension])
- {
- self.job.outputFileName = [[self.job.outputFileName stringByDeletingPathExtension] stringByAppendingPathExtension:extension];
- }
- }
-}
-
/**
* Method to determine if we should change the UI
* To reflect whether or not a Preset is being used or if
self.job.presetName = [NSString stringWithFormat:@"%@ %@", self.job.presetName, NSLocalizedString(@"(Modified)", @"Main Window -> preset modified")];
}
self.edited = YES;
- [self updateFileName];
}
}
[self.job applyPreset:self.currentPreset];
// If Auto Naming is on, update the destination
- [self updateFileName];
+ [self.autoNamer updateFileName];
[self addJobObservers];
}
A94DC2DE20CADA2C00EAC8FD /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = A94DC2DC20CADA2C00EAC8FD /* MainWindow.xib */; };
A95121E61B5F7BE700FD773D /* NSArray+HBAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = A95121E51B5F7BE700FD773D /* NSArray+HBAdditions.m */; };
A955128B1A320B02001BFC6F /* libjansson.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A95512881A320A12001BFC6F /* libjansson.a */; };
+ A957EBCD218DBE5900007988 /* HBAutoNamer.m in Sources */ = {isa = PBXBuildFile; fileRef = A957EBCC218DBE5900007988 /* HBAutoNamer.m */; };
A95BC1E71CD2548A008D6A33 /* volHighTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = A95BC1E51CD2548A008D6A33 /* volHighTemplate.pdf */; };
A95BC1E81CD2548A008D6A33 /* volLowTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = A95BC1E61CD2548A008D6A33 /* volLowTemplate.pdf */; };
A9637D8A20F7A252001EAE7C /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = A9637D8820F7A252001EAE7C /* InfoPlist.strings */; };
A9E1468216BC2AD800C307BC /* PlayTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = A9E1467E16BC2AD800C307BC /* PlayTemplate.pdf */; };
A9E1468316BC2AD800C307BC /* PrevTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = A9E1467F16BC2AD800C307BC /* PrevTemplate.pdf */; };
A9E165521C523016003EF30E /* libavfilter.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A9E165511C523016003EF30E /* libavfilter.a */; };
+ A9E52CD8218DD52B00E17B86 /* ExceptionAlert.xib in Resources */ = {isa = PBXBuildFile; fileRef = A9E52CD6218DD52A00E17B86 /* ExceptionAlert.xib */; };
A9F217E61E2F934C00C10C6E /* container-migration.plist in Resources */ = {isa = PBXBuildFile; fileRef = A9F217E51E2F934C00C10C6E /* container-migration.plist */; };
A9F472891976B7F30009EC65 /* HBSubtitlesDefaultsController.m in Sources */ = {isa = PBXBuildFile; fileRef = A9F472871976B7F30009EC65 /* HBSubtitlesDefaultsController.m */; };
A9F7102619A475EC00F61301 /* HBDockTile.m in Sources */ = {isa = PBXBuildFile; fileRef = A9F7102519A475EC00F61301 /* HBDockTile.m */; };
A9537BF81A48AC9000141102 /* HBFilters+UIAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "HBFilters+UIAdditions.m"; sourceTree = "<group>"; };
A953FF3820CAD29300325A51 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/HBSummaryViewController.xib; sourceTree = "<group>"; };
A95512881A320A12001BFC6F /* libjansson.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libjansson.a; path = external/contrib/lib/libjansson.a; sourceTree = BUILT_PRODUCTS_DIR; };
+ A957EBCB218DBE5900007988 /* HBAutoNamer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HBAutoNamer.h; sourceTree = "<group>"; };
+ A957EBCC218DBE5900007988 /* HBAutoNamer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HBAutoNamer.m; sourceTree = "<group>"; };
A9597A281A49749D00007771 /* HBRange+UIAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "HBRange+UIAdditions.h"; sourceTree = "<group>"; };
A9597A291A49749D00007771 /* HBRange+UIAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "HBRange+UIAdditions.m"; sourceTree = "<group>"; };
A95BC1E51CD2548A008D6A33 /* volHighTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = volHighTemplate.pdf; sourceTree = "<group>"; };
A9E165511C523016003EF30E /* libavfilter.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libavfilter.a; path = external/contrib/lib/libavfilter.a; sourceTree = BUILT_PRODUCTS_DIR; };
A9E2FD241A21BC4A000E8D3F /* HBAddPresetController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HBAddPresetController.h; sourceTree = "<group>"; };
A9E2FD251A21BC4A000E8D3F /* HBAddPresetController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HBAddPresetController.m; sourceTree = "<group>"; };
+ A9E52CD7218DD52A00E17B86 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ExceptionAlert.xib; sourceTree = "<group>"; };
A9E66D6E1A67A2A8007B641D /* HBDistributedArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HBDistributedArray.h; path = ../HBDistributedArray.h; sourceTree = "<group>"; };
A9E66D6F1A67A2A8007B641D /* HBDistributedArray.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HBDistributedArray.m; path = ../HBDistributedArray.m; sourceTree = "<group>"; };
A9EA43661A2210C400785E95 /* HBQueueOutlineView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HBQueueOutlineView.h; sourceTree = "<group>"; };
273F208F14ADBE670021BE6D /* HBController.m */,
A94DC2DC20CADA2C00EAC8FD /* MainWindow.xib */,
A9B34D701976841800871B7D /* View Controllers */,
+ A957EBCB218DBE5900007988 /* HBAutoNamer.h */,
+ A957EBCC218DBE5900007988 /* HBAutoNamer.m */,
);
name = "Main Window";
sourceTree = "<group>";
A9706CB31AC1436F00BAEAA8 /* HBApplication.m */,
A9706CB51AC1437800BAEAA8 /* HBExceptionAlertController.h */,
A9706CB61AC1437800BAEAA8 /* HBExceptionAlertController.m */,
+ A9E52CD6218DD52A00E17B86 /* ExceptionAlert.xib */,
A95121E41B5F7BE700FD773D /* NSArray+HBAdditions.h */,
A95121E51B5F7BE700FD773D /* NSArray+HBAdditions.m */,
273F20BD14ADC09F0021BE6D /* main.mm */,
A9A96BDA20CAD64B00A39AFB /* PicturePreview.xib in Resources */,
A95BC1E71CD2548A008D6A33 /* volHighTemplate.pdf in Resources */,
A9A96BB620CAD5D600A39AFB /* HBTitleSelection.xib in Resources */,
+ A9E52CD8218DD52B00E17B86 /* ExceptionAlert.xib in Resources */,
A9A96B8820CAD2D100A39AFB /* HBPlayerHUDController.xib in Resources */,
3490BCB41614CF8D002A5AD7 /* HandBrake.icns in Resources */,
A9E1468016BC2AD800C307BC /* NextTemplate.pdf in Resources */,
A91AFD0C1A948827009BECED /* HBOutputFileWriter.m in Sources */,
A95121E61B5F7BE700FD773D /* NSArray+HBAdditions.m in Sources */,
A96664B51CCE48F700DA4A57 /* HBPictureHUDController.m in Sources */,
+ A957EBCD218DBE5900007988 /* HBAutoNamer.m in Sources */,
A92B148220CA9F7700146FD8 /* HBHUDView.m in Sources */,
A914BCB31BC441C700157917 /* HBPreviewView.m in Sources */,
273F20B714ADBE670021BE6D /* HBPreviewController.m in Sources */,
name = Localizable.strings;
sourceTree = "<group>";
};
+ A9E52CD6218DD52A00E17B86 /* ExceptionAlert.xib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ A9E52CD7218DD52A00E17B86 /* Base */,
+ );
+ name = ExceptionAlert.xib;
+ sourceTree = "<group>";
+ };
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */