diff --git a/Medianno.xcodeproj/project.pbxproj b/Medianno.xcodeproj/project.pbxproj index 00f2eff..df34d0a 100644 --- a/Medianno.xcodeproj/project.pbxproj +++ b/Medianno.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -26,6 +26,7 @@ 950BB7A713F467A400D8E669 /* MAAddMedia.xib in Resources */ = {isa = PBXBuildFile; fileRef = 950BB7A513F467A400D8E669 /* MAAddMedia.xib */; }; 950BB7AA13F46BAF00D8E669 /* MAAddMediaSheet.mm in Sources */ = {isa = PBXBuildFile; fileRef = 950BB7A913F46BAF00D8E669 /* MAAddMediaSheet.mm */; }; 950BB7AD13F46ECF00D8E669 /* MAAppController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 950BB7AC13F46ECF00D8E669 /* MAAppController.mm */; }; + 951152732A2C06AA00A56C6C /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 951152722A2C06AA00A56C6C /* CoreMedia.framework */; }; 9556F185140426EB00B81D2E /* MAToolbarButton.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9556F184140426EB00B81D2E /* MAToolbarButton.mm */; }; 958AAE3414052FC600365087 /* DateHypotheses.plist in Resources */ = {isa = PBXBuildFile; fileRef = 958AAE3314052FC600365087 /* DateHypotheses.plist */; }; 95BCFA2113F76A04000F650F /* app.icns in Resources */ = {isa = PBXBuildFile; fileRef = 95BCFA1F13F76A04000F650F /* app.icns */; }; @@ -81,6 +82,7 @@ 950BB7A913F46BAF00D8E669 /* MAAddMediaSheet.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MAAddMediaSheet.mm; sourceTree = ""; }; 950BB7AB13F46ECF00D8E669 /* MAAppController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MAAppController.h; sourceTree = ""; }; 950BB7AC13F46ECF00D8E669 /* MAAppController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MAAppController.mm; sourceTree = ""; }; + 951152722A2C06AA00A56C6C /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; }; 9556F183140426EB00B81D2E /* MAToolbarButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MAToolbarButton.h; sourceTree = ""; }; 9556F184140426EB00B81D2E /* MAToolbarButton.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MAToolbarButton.mm; sourceTree = ""; }; 958AAE3314052FC600365087 /* DateHypotheses.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = DateHypotheses.plist; path = Medianno/Resources/DateHypotheses.plist; sourceTree = ""; }; @@ -118,6 +120,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 951152732A2C06AA00A56C6C /* CoreMedia.framework in Frameworks */, 950737F31D5FAA1600737CDE /* AVKit.framework in Frameworks */, 950737F11D5FAA0F00737CDE /* AVFoundation.framework in Frameworks */, 950BB68F13F1F29D00D8E669 /* CoreData.framework in Frameworks */, @@ -148,6 +151,7 @@ 950BB66913F1F26200D8E669 /* Frameworks */ = { isa = PBXGroup; children = ( + 951152722A2C06AA00A56C6C /* CoreMedia.framework */, 950737F21D5FAA1600737CDE /* AVKit.framework */, 950737F01D5FAA0F00737CDE /* AVFoundation.framework */, 950BB68D13F1F29D00D8E669 /* CoreData.framework */, @@ -286,15 +290,17 @@ 950BB65D13F1F26200D8E669 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0800; + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 1500; ORGANIZATIONNAME = "Matthias Neeracher"; }; buildConfigurationList = 950BB66013F1F26200D8E669 /* Build configuration list for PBXProject "Medianno" */; compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, + Base, ); mainGroup = 950BB65B13F1F26200D8E669; productRefGroup = 950BB66713F1F26200D8E669 /* Products */; @@ -438,18 +444,32 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "c++14"; CLANG_CXX_LIBRARY = "libc++"; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; @@ -478,18 +498,32 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "c++14"; CLANG_CXX_LIBRARY = "libc++"; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_NO_COMMON_BLOCKS = YES; @@ -510,10 +544,11 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; - GCC_ENABLE_OBJC_GC = unsupported; + DEAD_CODE_STRIPPING = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "Medianno/Medianno-Prefix.pch"; INFOPLIST_FILE = "Medianno/Medianno-Info.plist"; + MACOSX_DEPLOYMENT_TARGET = 12.4; PRODUCT_BUNDLE_IDENTIFIER = "org.aereperennius.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; @@ -525,10 +560,11 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; - GCC_ENABLE_OBJC_GC = unsupported; + DEAD_CODE_STRIPPING = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "Medianno/Medianno-Prefix.pch"; INFOPLIST_FILE = "Medianno/Medianno-Info.plist"; + MACOSX_DEPLOYMENT_TARGET = 12.4; PRODUCT_BUNDLE_IDENTIFIER = "org.aereperennius.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; diff --git a/Medianno/MAColorForURL.mm b/Medianno/MAColorForURL.mm index f224102..b6d9822 100644 --- a/Medianno/MAColorForURL.mm +++ b/Medianno/MAColorForURL.mm @@ -24,7 +24,7 @@ - (id)transformedValue:(id)value { NSURL * mediaURL = [NSURL URLWithString:value]; - if ([[AVAsset assetWithURL:mediaURL] isPlayable]) + if ([AVAsset assetWithURL:mediaURL]) return [NSColor blackColor]; else return [NSColor redColor]; diff --git a/Medianno/MADocWindow.h b/Medianno/MADocWindow.h index 5a264d3..c078258 100644 --- a/Medianno/MADocWindow.h +++ b/Medianno/MADocWindow.h @@ -24,12 +24,13 @@ IBOutlet NSView * textExportAccessoryView; AVPlayer * currentMovie; NSString * currentMovieTitle; + id currentMovieTimeObserver; } @property BOOL exportAnnotations; @property BOOL exportTags; @property (nonatomic,retain)NSString * searchString; -@property (readonly) NSNumber * currentMovieTime; +@property double currentMovieTime; - (IBAction)addMediaFiles:(id)sender; - (IBAction)importText:(id)sender; diff --git a/Medianno/MADocWindow.mm b/Medianno/MADocWindow.mm index 3abb6d9..131f071 100644 --- a/Medianno/MADocWindow.mm +++ b/Medianno/MADocWindow.mm @@ -90,10 +90,17 @@ static const char * kMADocWindowObserver = "MADocWindowObserver"; // Current movie changed // [self willChangeValueForKey:@"currentMovie"]; + if (currentMovieTimeObserver) { + [currentMovie removeTimeObserver:currentMovieTimeObserver]; + currentMovieTimeObserver = nil; + } if (MAMedia * currentMedia = [self currentMedia]) { NSURL * mediaURL = [NSURL URLWithString:[currentMedia media]]; currentMovie = [AVPlayer playerWithURL:mediaURL]; currentMovieTitle = [currentMedia name]; + currentMovieTimeObserver = [currentMovie addPeriodicTimeObserverForInterval:CMTimeMake(1, 1) queue:nil usingBlock:^(CMTime time) { + self.currentMovieTime = (double)time.value/time.timescale; + }]; } else { currentMovie = nil; currentMovieTitle = @""; @@ -114,27 +121,15 @@ static const char * kMADocWindowObserver = "MADocWindowObserver"; return nil; } -+ (NSSet *)keyPathsForValuesAffectingCurrentMovieTime -{ - return [NSSet setWithObject:@"currentMovie.currentTime"]; -} - -- (NSNumber *)currentMovieTime -{ - CMTime time = [currentMovie currentTime]; - - return [NSNumber numberWithDouble:(double)time.value/time.timescale]; -} - - (IBAction)addMediaFiles:(id)sender { NSOpenPanel * openPanel = [NSOpenPanel openPanel]; - [openPanel setAllowedFileTypes:[AVMovie movieTypes]]; + [openPanel setAllowedFileTypes:[AVURLAsset audiovisualTypes]]; [openPanel setAllowsMultipleSelection:YES]; [openPanel setCanChooseDirectories:YES]; [openPanel beginSheetModalForWindow:[self window] completionHandler:^(NSInteger result) { [openPanel orderOut:self]; - if (result == NSFileHandlingPanelOKButton) + if (result == NSModalResponseOK) [self addMedia:[openPanel URLs]]; }]; } @@ -167,7 +162,7 @@ static const char * kMADocWindowObserver = "MADocWindowObserver"; NSNumber * isDirectory; [url getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:nil]; if ([isDirectory boolValue]) { - [self addMediaTypes:[AVMovie movieTypes] inDirectory:url toList:expandedURLs]; + [self addMediaTypes:[AVURLAsset audiovisualTypes] inDirectory:url toList:expandedURLs]; continue; } } @@ -264,10 +259,11 @@ static const char * kMADocWindowObserver = "MADocWindowObserver"; - (IBAction)toggleMediaPlay:(id)sender { - if ([currentMovie rate] > 0.0f) + if ([currentMovie rate] > 0.0f) { [currentMovie pause]; - else + } else { [currentMovie play]; + } } - (BOOL)validateUserInterfaceItem:(id )item diff --git a/Medianno/MAShortenQTTime.mm b/Medianno/MAShortenQTTime.mm index 10a77d4..581d48a 100644 --- a/Medianno/MAShortenQTTime.mm +++ b/Medianno/MAShortenQTTime.mm @@ -61,7 +61,14 @@ CFTimeInterval MATimeFromString(NSString * timeStr) - (id)transformedValue:(id)value { - NSUInteger seconds = [value unsignedIntegerValue]; + NSUInteger seconds; + if (!value) { + seconds = 0; + } else if ([value isKindOfClass:[NSNumber class]]) { + seconds = [value unsignedIntegerValue]; + } else { + seconds = MATimeFromString(value); + } if (NSUInteger minutes = seconds/60) { seconds %= 60; if (NSUInteger hours = minutes/60) { diff --git a/Medianno/en.lproj/MADocument.xib b/Medianno/en.lproj/MADocument.xib index 0d67ce8..264bef4 100644 --- a/Medianno/en.lproj/MADocument.xib +++ b/Medianno/en.lproj/MADocument.xib @@ -1,10 +1,10 @@ - + - - - + + + @@ -20,37 +20,36 @@ - + - + - + - + - + - + - - + + - + - @@ -69,9 +68,8 @@ - + - @@ -87,7 +85,6 @@ - @@ -113,40 +110,40 @@ - - + - - + + - - + + - + - - + + @@ -154,7 +151,6 @@ - @@ -166,11 +162,11 @@ - + - - + + @@ -201,9 +197,8 @@ - + - @@ -215,10 +210,10 @@ - + - + @@ -244,9 +239,8 @@ - + - @@ -258,11 +252,11 @@ - + - - + + @@ -297,21 +291,21 @@ - - -