From 64b9764b2e09e159319e9f79eb6a34204c92b199 Mon Sep 17 00:00:00 2001 From: Dzmitry Neviadomski Date: Wed, 27 Jan 2021 04:31:43 +0300 Subject: [PATCH 1/6] Inhibit ThirdParty libraries build errors. This helps as to actually see warnings of our code. --- .../xcschemes/CogAudio Framework.xcscheme | 2 +- Cog.xcodeproj/xcshareddata/xcschemes/Cog.xcscheme | 2 +- .../AdPlug/libAdPlug.xcodeproj/project.pbxproj | 2 ++ Frameworks/FLAC/flac.xcodeproj/project.pbxproj | 2 ++ .../xcshareddata/xcschemes/FLAC Framework.xcscheme | 2 +- .../xcshareddata/xcschemes/File_Extractor.xcscheme | 2 +- Frameworks/GME/GME.xcodeproj/project.pbxproj | 2 ++ .../xcshareddata/xcschemes/GME Framework.xcscheme | 2 +- .../xcshareddata/xcschemes/HighlyAdvanced.xcscheme | 2 +- .../HighlyExperimental.xcodeproj/project.pbxproj | 2 ++ .../xcschemes/HighlyExperimental.xcscheme | 2 +- .../HighlyQuixotic.xcodeproj/project.pbxproj | 2 ++ .../xcshareddata/xcschemes/HighlyQuixotic.xcscheme | 2 +- .../HighlyTheoretical.xcodeproj/project.pbxproj | 2 ++ .../xcschemes/HighlyTheoretical.xcscheme | 2 +- .../xcshareddata/xcschemes/HivelyPlayer.xcscheme | 2 +- Frameworks/MPCDec/MPCDec.xcodeproj/project.pbxproj | 2 ++ .../xcshareddata/xcschemes/mpcdec Framework.xcscheme | 2 +- Frameworks/Ogg/macosx/Ogg.xcodeproj/project.pbxproj | 2 ++ .../xcshareddata/xcschemes/Ogg.xcscheme | 2 +- .../xcshareddata/xcschemes/libogg (static).xcscheme | 2 +- .../OpenMPT/libOpenMPT.xcodeproj/project.pbxproj | 12 ++++-------- Frameworks/Opus/Opus.xcodeproj/project.pbxproj | 2 ++ .../xcshareddata/xcschemes/Opus.xcscheme | 2 +- .../xcshareddata/xcschemes/SSEQPlayer.xcscheme | 2 +- Frameworks/Shorten/Shorten.xcodeproj/project.pbxproj | 2 ++ .../xcschemes/Shorten Framework.xcscheme | 2 +- .../xcshareddata/xcschemes/Syntrax_c.xcscheme | 2 +- Frameworks/TagLib/TagLib.xcodeproj/project.pbxproj | 2 ++ .../xcshareddata/xcschemes/TagLib Framework.xcscheme | 2 +- .../Vorbis/macosx/Vorbis.xcodeproj/project.pbxproj | 2 ++ .../xcshareddata/xcschemes/Vorbis.xcscheme | 2 +- .../xcschemes/libvorbis (static).xcscheme | 2 +- .../xcschemes/libvorbisenc (static).xcscheme | 2 +- .../xcschemes/libvorbisfile (static).xcscheme | 2 +- Frameworks/WavPack/WavPack.xcodeproj/project.pbxproj | 2 ++ .../xcschemes/WavPack Framework.xcscheme | 2 +- Frameworks/g719/g719.xcodeproj/project.pbxproj | 2 ++ .../xcshareddata/xcschemes/g719.xcscheme | 2 +- .../lazyusf2/lazyusf2.xcodeproj/project.pbxproj | 2 ++ .../xcshareddata/xcschemes/lazyusf2.xcscheme | 2 +- .../libatrac9/libatrac9.xcodeproj/project.pbxproj | 2 ++ .../libbinio/libbinio.xcodeproj/project.pbxproj | 4 +++- .../libsidplay/sidplayfp.xcodeproj/project.pbxproj | 2 ++ .../xcshareddata/xcschemes/sidplayfp.xcscheme | 2 +- Frameworks/mGBA/mGBA.xcodeproj/project.pbxproj | 2 ++ .../xcshareddata/xcschemes/mGBA.xcscheme | 2 +- .../midi_processing.xcodeproj/project.pbxproj | 2 ++ .../xcshareddata/xcschemes/midi_processing.xcscheme | 2 +- Frameworks/mpg123/mpg123.xcodeproj/project.pbxproj | 4 +++- .../xcshareddata/xcschemes/mpg123.xcscheme | 2 +- Frameworks/psflib/psflib.xcodeproj/project.pbxproj | 2 ++ .../xcshareddata/xcschemes/psflib.xcscheme | 2 +- .../vgmstream/libvgmstream.xcodeproj/project.pbxproj | 8 +++++--- .../xcshareddata/xcschemes/vgmstream.xcscheme | 2 +- Frameworks/vio2sf/vio2sf.xcodeproj/project.pbxproj | 2 ++ .../xcshareddata/xcschemes/vio2sf.xcscheme | 2 +- .../xcshareddata/xcschemes/APL Plugin.xcscheme | 2 +- .../xcshareddata/xcschemes/ArchiveSource.xcscheme | 2 +- .../xcshareddata/xcschemes/CoreAudio Plugin.xcscheme | 2 +- Plugins/CueSheet/CueSheet.xcodeproj/project.pbxproj | 4 +++- .../xcshareddata/xcschemes/CueSheet.xcscheme | 2 +- .../xcshareddata/xcschemes/FFMPEG Plugin.xcscheme | 2 +- .../xcschemes/FileSource Plugin.xcscheme | 2 +- .../xcshareddata/xcschemes/Flac Plugin.xcscheme | 2 +- .../xcshareddata/xcschemes/GME Plugin.xcscheme | 2 +- .../xcschemes/HTTPSource Plugin.xcscheme | 2 +- .../xcshareddata/xcschemes/HighlyComplete.xcscheme | 2 +- .../xcshareddata/xcschemes/Hively.xcscheme | 2 +- .../xcshareddata/xcschemes/M3u.xcscheme | 2 +- .../xcshareddata/xcschemes/MIDI.xcscheme | 2 +- .../xcshareddata/xcschemes/Musepack Plugin.xcscheme | 2 +- .../xcshareddata/xcschemes/Opus.xcscheme | 2 +- .../xcshareddata/xcschemes/Pls.xcscheme | 2 +- .../xcshareddata/xcschemes/Shorten Plugin.xcscheme | 2 +- .../xcshareddata/xcschemes/SilenceDecoder.xcscheme | 2 +- .../xcshareddata/xcschemes/Syntrax.xcscheme | 2 +- .../xcshareddata/xcschemes/TagLib Plugin.xcscheme | 2 +- .../xcshareddata/xcschemes/Vorbis Plugin.xcscheme | 2 +- .../xcshareddata/xcschemes/WavPack Plugin.xcscheme | 2 +- .../xcshareddata/xcschemes/sidplay.xcscheme | 2 +- .../xcshareddata/xcschemes/vgmstream.xcscheme | 2 +- 82 files changed, 116 insertions(+), 70 deletions(-) diff --git a/Audio/CogAudio.xcodeproj/xcshareddata/xcschemes/CogAudio Framework.xcscheme b/Audio/CogAudio.xcodeproj/xcshareddata/xcschemes/CogAudio Framework.xcscheme index cb4f4a562..df25b15b9 100644 --- a/Audio/CogAudio.xcodeproj/xcshareddata/xcschemes/CogAudio Framework.xcscheme +++ b/Audio/CogAudio.xcodeproj/xcshareddata/xcschemes/CogAudio Framework.xcscheme @@ -1,6 +1,6 @@ Date: Wed, 27 Jan 2021 05:12:07 +0300 Subject: [PATCH 2/6] Fix some more warnings. --- Audio/Chain/Node.m | 1 + Audio/CogAudio_Prefix.pch | 1 + Plugins/AdPlug/AdPlug/AdPlugContainer.mm | 2 +- Plugins/AdPlug/AdPlug/AdPlugDecoder.mm | 2 +- Plugins/AdPlug/AdPlug/AdPlugMetadataReader.mm | 2 +- Plugins/AdPlug/AdPlug/fileprovider.mm | 2 +- Plugins/ArchiveSource/ArchiveSource/ArchiveContainer.m | 2 +- Plugins/ArchiveSource/ArchiveSource/ArchiveSource.m | 2 +- Plugins/FFMPEG/FFMPEGDecoder.m | 4 ---- Plugins/MIDI/MIDI.xcodeproj/project.pbxproj | 2 ++ Plugins/MIDI/MIDI/AUPlayerView.mm | 6 +++++- Plugins/OpenMPT/OpenMPT.xcodeproj/project.pbxproj | 4 ++-- Plugins/OpenMPT/OpenMPT/OMPTDecoder.mm | 2 +- Plugins/TagLib/TagLibMetadataReader.m | 2 +- Plugins/TagLib/TagLibMetadataWriter.m | 4 ++-- Plugins/vgmstream/vgmstream.xcodeproj/project.pbxproj | 2 ++ Plugins/vgmstream/vgmstream/VGMContainer.m | 2 +- Plugins/vgmstream/vgmstream/VGMDecoder.m | 2 +- Plugins/vgmstream/vgmstream/VGMInterface.m | 4 ++-- Plugins/vgmstream/vgmstream/VGMMetadataReader.m | 2 +- Plugins/vgmstream/vgmstream/VGMPropertiesReader.m | 2 +- 21 files changed, 29 insertions(+), 23 deletions(-) diff --git a/Audio/Chain/Node.m b/Audio/Chain/Node.m index 6474b5fb8..8e9453678 100644 --- a/Audio/Chain/Node.m +++ b/Audio/Chain/Node.m @@ -9,6 +9,7 @@ #import "Node.h" #import "Logging.h" +#import "BufferChain.h" @implementation Node diff --git a/Audio/CogAudio_Prefix.pch b/Audio/CogAudio_Prefix.pch index 142f8365e..da450dcd0 100644 --- a/Audio/CogAudio_Prefix.pch +++ b/Audio/CogAudio_Prefix.pch @@ -3,5 +3,6 @@ // #ifdef __OBJC__ + #import #import #endif diff --git a/Plugins/AdPlug/AdPlug/AdPlugContainer.mm b/Plugins/AdPlug/AdPlug/AdPlugContainer.mm index b719a5943..4e936f19e 100755 --- a/Plugins/AdPlug/AdPlug/AdPlugContainer.mm +++ b/Plugins/AdPlug/AdPlug/AdPlugContainer.mm @@ -51,7 +51,7 @@ Copl * p_emu = new CSilentopl; - std::string path = [[[url absoluteString] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding] UTF8String]; + std::string path = [[[url absoluteString] stringByRemovingPercentEncoding] UTF8String]; CPlayer * p_player = CAdPlug::factory(path, p_emu, CAdPlug::players, CProvider_cog( path, source )); if ( !p_player ) diff --git a/Plugins/AdPlug/AdPlug/AdPlugDecoder.mm b/Plugins/AdPlug/AdPlug/AdPlugDecoder.mm index c610b2032..2e7996d47 100755 --- a/Plugins/AdPlug/AdPlug/AdPlugDecoder.mm +++ b/Plugins/AdPlug/AdPlug/AdPlugDecoder.mm @@ -40,7 +40,7 @@ path = [path substringToIndex:fragmentRange.location]; } - std::string _path = [[path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding] UTF8String]; + std::string _path = [[path stringByRemovingPercentEncoding] UTF8String]; m_player = CAdPlug::factory(_path, m_emu, CAdPlug::players, CProvider_cog( _path, source )); if ( !m_player ) diff --git a/Plugins/AdPlug/AdPlug/AdPlugMetadataReader.mm b/Plugins/AdPlug/AdPlug/AdPlugMetadataReader.mm index 428ba6a16..5d06cd07d 100644 --- a/Plugins/AdPlug/AdPlug/AdPlugMetadataReader.mm +++ b/Plugins/AdPlug/AdPlug/AdPlugMetadataReader.mm @@ -52,7 +52,7 @@ path = [path substringToIndex:fragmentRange.location]; } - std::string _path = [[path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding] UTF8String]; + std::string _path = [[path stringByRemovingPercentEncoding] UTF8String]; CPlayer * p_player = CAdPlug::factory(_path, p_emu, CAdPlug::players, CProvider_cog( _path, source )); if ( !p_player ) diff --git a/Plugins/AdPlug/AdPlug/fileprovider.mm b/Plugins/AdPlug/AdPlug/fileprovider.mm index bfdb6176e..201c2103b 100644 --- a/Plugins/AdPlug/AdPlug/fileprovider.mm +++ b/Plugins/AdPlug/AdPlug/fileprovider.mm @@ -100,7 +100,7 @@ binistream * CProvider_cog::open(std::string filename) const fragmentString = [urlString substringFromIndex:fragmentRange.location]; urlString = [urlString substringToIndex:fragmentRange.location]; } - NSURL * url = [NSURL URLWithString:[[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] stringByAppendingString:fragmentString]]; + NSURL * url = [NSURL URLWithString:[[urlString stringByAddingPercentEncodingWithAllowedCharacters:NSCharacterSet.URLFragmentAllowedCharacterSet] stringByAppendingString:fragmentString]]; id audioSourceClass = NSClassFromString(@"AudioSource"); p_file = [audioSourceClass audioSourceForURL:url]; diff --git a/Plugins/ArchiveSource/ArchiveSource/ArchiveContainer.m b/Plugins/ArchiveSource/ArchiveSource/ArchiveContainer.m index 2aa5334f0..45226928f 100644 --- a/Plugins/ArchiveSource/ArchiveSource/ArchiveContainer.m +++ b/Plugins/ArchiveSource/ArchiveSource/ArchiveContainer.m @@ -62,7 +62,7 @@ static NSString * g_make_unpack_path(NSString * archive, NSString * file, NSStri while ( !fex_done(fex) ) { NSString *name = [NSString stringWithUTF8String:fex_name(fex)]; if ([[NSClassFromString(@"AudioPlayer") fileTypes] containsObject:[[name pathExtension] lowercaseString]]) - [files addObject:[NSURL URLWithString:[g_make_unpack_path([url path], name, @"fex") stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]]; + [files addObject:[NSURL URLWithString:[g_make_unpack_path([url path], name, @"fex") stringByAddingPercentEncodingWithAllowedCharacters:NSCharacterSet.URLPathAllowedCharacterSet]]]; fex_next(fex); } diff --git a/Plugins/ArchiveSource/ArchiveSource/ArchiveSource.m b/Plugins/ArchiveSource/ArchiveSource/ArchiveSource.m index 1d77b0558..87984b7ef 100644 --- a/Plugins/ArchiveSource/ArchiveSource/ArchiveSource.m +++ b/Plugins/ArchiveSource/ArchiveSource/ArchiveSource.m @@ -75,7 +75,7 @@ static BOOL g_parse_unpack_path(NSString * src, NSString ** archive, NSString ** { [self setURL:url]; - NSString * urlDecoded = [[url absoluteString] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + NSString * urlDecoded = [[url absoluteString] stringByRemovingPercentEncoding]; NSString * type; NSString * archive; diff --git a/Plugins/FFMPEG/FFMPEGDecoder.m b/Plugins/FFMPEG/FFMPEGDecoder.m index de0ae4d0e..96f43d813 100644 --- a/Plugins/FFMPEG/FFMPEGDecoder.m +++ b/Plugins/FFMPEG/FFMPEGDecoder.m @@ -80,8 +80,6 @@ int lockmgr_callback(void ** mutex, enum AVLockOp op) { av_log_set_flags(AV_LOG_SKIP_REPEATED); av_log_set_level(AV_LOG_ERROR); - av_register_all(); - av_lockmgr_register(lockmgr_callback); } } @@ -190,8 +188,6 @@ int lockmgr_callback(void ** mutex, enum AVLockOp op) ALog(@"Can't copy codec parameters to context, errcode = %d, error = %s", errcode, errDescr); return NO; } - - av_codec_set_pkt_timebase(codecCtx, stream->time_base); AVCodec * codec = avcodec_find_decoder(codecCtx->codec_id); if (!codec) { diff --git a/Plugins/MIDI/MIDI.xcodeproj/project.pbxproj b/Plugins/MIDI/MIDI.xcodeproj/project.pbxproj index 7f47ea1f9..9a99515e9 100644 --- a/Plugins/MIDI/MIDI.xcodeproj/project.pbxproj +++ b/Plugins/MIDI/MIDI.xcodeproj/project.pbxproj @@ -508,6 +508,7 @@ GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_INHIBIT_ALL_WARNINGS = YES; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; @@ -554,6 +555,7 @@ GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_INHIBIT_ALL_WARNINGS = YES; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; diff --git a/Plugins/MIDI/MIDI/AUPlayerView.mm b/Plugins/MIDI/MIDI/AUPlayerView.mm index f0de19816..8f5ce2558 100644 --- a/Plugins/MIDI/MIDI/AUPlayerView.mm +++ b/Plugins/MIDI/MIDI/AUPlayerView.mm @@ -30,7 +30,11 @@ AUPluginUI::AUPluginUI (AudioUnit & _au) } if (au_view) { - cocoa_window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, req_width, req_height) styleMask:(NSTitledWindowMask | NSClosableWindowMask) backing:NSBackingStoreBuffered defer:NO]; + cocoa_window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, req_width, req_height) + styleMask:(NSWindowStyleMaskTitled | + NSWindowStyleMaskClosable) + backing:NSBackingStoreBuffered + defer:NO]; [cocoa_window setAutodisplay:YES]; [cocoa_window setTitle:@"AU Plug-in"]; diff --git a/Plugins/OpenMPT/OpenMPT.xcodeproj/project.pbxproj b/Plugins/OpenMPT/OpenMPT.xcodeproj/project.pbxproj index 7b6cddc82..b59bcd8a8 100644 --- a/Plugins/OpenMPT/OpenMPT.xcodeproj/project.pbxproj +++ b/Plugins/OpenMPT/OpenMPT.xcodeproj/project.pbxproj @@ -248,7 +248,7 @@ CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = NO; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; @@ -305,7 +305,7 @@ CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = NO; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; diff --git a/Plugins/OpenMPT/OpenMPT/OMPTDecoder.mm b/Plugins/OpenMPT/OpenMPT/OMPTDecoder.mm index 69fcfdfe7..5bb9ee1ae 100755 --- a/Plugins/OpenMPT/OpenMPT/OMPTDecoder.mm +++ b/Plugins/OpenMPT/OpenMPT/OMPTDecoder.mm @@ -81,7 +81,7 @@ static void g_push_archive_extensions(std::vector & list) mod->set_render_param( openmpt::module::RENDER_STEREOSEPARATION_PERCENT, 100 ); mod->set_render_param( openmpt::module::RENDER_INTERPOLATIONFILTER_LENGTH, interp ); mod->set_render_param( openmpt::module::RENDER_VOLUMERAMPING_STRENGTH, -1 ); - mod->ctl_set( "render.resampler.emulate_amiga", "1" ); + mod->ctl_set_boolean("render.resampler.emulate_amiga", true); left.resize( 1024 ); right.resize( 1024 ); diff --git a/Plugins/TagLib/TagLibMetadataReader.m b/Plugins/TagLib/TagLibMetadataReader.m index f87bedd20..bf2e00b30 100644 --- a/Plugins/TagLib/TagLibMetadataReader.m +++ b/Plugins/TagLib/TagLibMetadataReader.m @@ -148,7 +148,7 @@ // Gather list of candidate image files NSArray *fileNames = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:nil]; - NSArray *imageFileNames = [fileNames pathsMatchingExtensions:[NSImage imageFileTypes]]; + NSArray *imageFileNames = [fileNames pathsMatchingExtensions:[NSImage imageTypes]]; for (NSString *fileName in imageFileNames) { if ([TagLibMetadataReader isCoverFile:fileName]) { diff --git a/Plugins/TagLib/TagLibMetadataWriter.m b/Plugins/TagLib/TagLibMetadataWriter.m index 40c6efbf9..ca85ff885 100644 --- a/Plugins/TagLib/TagLibMetadataWriter.m +++ b/Plugins/TagLib/TagLibMetadataWriter.m @@ -8,8 +8,8 @@ #import "TagLibMetadataWriter.h" -#import -#import +#import +#import #import "Logging.h" diff --git a/Plugins/vgmstream/vgmstream.xcodeproj/project.pbxproj b/Plugins/vgmstream/vgmstream.xcodeproj/project.pbxproj index add52ddfa..976043e63 100644 --- a/Plugins/vgmstream/vgmstream.xcodeproj/project.pbxproj +++ b/Plugins/vgmstream/vgmstream.xcodeproj/project.pbxproj @@ -332,6 +332,7 @@ GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_INHIBIT_ALL_WARNINGS = YES; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; @@ -393,6 +394,7 @@ ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_INHIBIT_ALL_WARNINGS = YES; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; diff --git a/Plugins/vgmstream/vgmstream/VGMContainer.m b/Plugins/vgmstream/vgmstream/VGMContainer.m index c7241e773..6f5abe7a7 100755 --- a/Plugins/vgmstream/vgmstream/VGMContainer.m +++ b/Plugins/vgmstream/vgmstream/VGMContainer.m @@ -36,7 +36,7 @@ return [NSMutableArray arrayWithObject:url]; } - NSString * path = [[url absoluteString] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + NSString * path = [[url absoluteString] stringByRemovingPercentEncoding]; VGMSTREAM * stream = init_vgmstream_from_cogfile([path UTF8String], 0); if (!stream) diff --git a/Plugins/vgmstream/vgmstream/VGMDecoder.m b/Plugins/vgmstream/vgmstream/VGMDecoder.m index 4e74530ef..4ee4972f7 100644 --- a/Plugins/vgmstream/vgmstream/VGMDecoder.m +++ b/Plugins/vgmstream/vgmstream/VGMDecoder.m @@ -194,7 +194,7 @@ NSLog(@"Opening %@ subsong %d", path, track_num); - stream = init_vgmstream_from_cogfile([[path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding] UTF8String], track_num); + stream = init_vgmstream_from_cogfile([[path stringByRemovingPercentEncoding] UTF8String], track_num); if ( !stream ) return NO; diff --git a/Plugins/vgmstream/vgmstream/VGMInterface.m b/Plugins/vgmstream/vgmstream/VGMInterface.m index a0fb90256..62cd6dbd4 100644 --- a/Plugins/vgmstream/vgmstream/VGMInterface.m +++ b/Plugins/vgmstream/vgmstream/VGMInterface.m @@ -82,7 +82,7 @@ static STREAMFILE *cogsf_create(id file, const char *path) { STREAMFILE *cogsf_create_from_path(const char *path) { NSString * urlString = [NSString stringWithUTF8String:path]; - NSURL * url = [NSURL URLWithString:[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; + NSURL * url = [NSURL URLWithString:[urlString stringByAddingPercentEncodingWithAllowedCharacters:NSCharacterSet.URLPathAllowedCharacterSet]]; return cogsf_create_from_url(url); } @@ -98,7 +98,7 @@ STREAMFILE *cogsf_create_from_url(NSURL * url) { if (![source seekable]) return 0; - return cogsf_create(source, [[[url absoluteString] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding] UTF8String]); + return cogsf_create(source, [[[url absoluteString] stringByRemovingPercentEncoding] UTF8String]); } VGMSTREAM *init_vgmstream_from_cogfile(const char *path, int subsong) { diff --git a/Plugins/vgmstream/vgmstream/VGMMetadataReader.m b/Plugins/vgmstream/vgmstream/VGMMetadataReader.m index d607b0176..4027a218c 100644 --- a/Plugins/vgmstream/vgmstream/VGMMetadataReader.m +++ b/Plugins/vgmstream/vgmstream/VGMMetadataReader.m @@ -42,7 +42,7 @@ path = [path substringToIndex:fragmentRange.location]; } - VGMSTREAM * stream = init_vgmstream_from_cogfile([[path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding] UTF8String], track_num); + VGMSTREAM * stream = init_vgmstream_from_cogfile([[path stringByRemovingPercentEncoding] UTF8String], track_num); if ( !stream ) return nil; diff --git a/Plugins/vgmstream/vgmstream/VGMPropertiesReader.m b/Plugins/vgmstream/vgmstream/VGMPropertiesReader.m index bf5fcb9f0..df91c84dc 100644 --- a/Plugins/vgmstream/vgmstream/VGMPropertiesReader.m +++ b/Plugins/vgmstream/vgmstream/VGMPropertiesReader.m @@ -44,7 +44,7 @@ path = [path substringToIndex:fragmentRange.location]; } - VGMSTREAM * stream = init_vgmstream_from_cogfile([[path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding] UTF8String], track_num); + VGMSTREAM * stream = init_vgmstream_from_cogfile([[path stringByRemovingPercentEncoding] UTF8String], track_num); if ( !stream ) return nil; From a0afe8513014a6870774dca50b4dcedf629ac443 Mon Sep 17 00:00:00 2001 From: Dzmitry Neviadomski Date: Wed, 27 Jan 2021 05:30:19 +0300 Subject: [PATCH 3/6] Fix deprecations with replacemnt and reindent touched files. --- Application/MediaKeysApplication.m | 12 +- FileTree/FileTreeOutlineView.m | 92 ++--- Playlist/PlaylistView.m | 454 +++++++++++------------ ThirdParty/ImageTextCell/ImageTextCell.m | 12 +- ThirdParty/OpenURLPanel/OpenURLPanel.m | 340 ++++++++--------- 5 files changed, 455 insertions(+), 455 deletions(-) diff --git a/Application/MediaKeysApplication.m b/Application/MediaKeysApplication.m index a62117c8c..57d0df88f 100644 --- a/Application/MediaKeysApplication.m +++ b/Application/MediaKeysApplication.m @@ -101,17 +101,17 @@ { BOOL shouldHandleMediaKeyEventLocally = ![SPMediaKeyTap usesGlobalMediaKeyTap]; - if(shouldHandleMediaKeyEventLocally && [event type] == NSSystemDefined && [event subtype] == 8 ) - { - [self mediaKeyTap:nil receivedMediaKeyEvent:event]; - } + if(shouldHandleMediaKeyEventLocally && [event type] == NSEventTypeSystemDefined && [event subtype] == 8 ) + { + [self mediaKeyTap:nil receivedMediaKeyEvent:event]; + } - [super sendEvent: event]; + [super sendEvent: event]; } -(void)mediaKeyTap:(SPMediaKeyTap*)keyTap receivedMediaKeyEvent:(NSEvent*)event; { - NSAssert([event type] == NSSystemDefined && [event subtype] == SPSystemDefinedEventMediaKeys, @"Unexpected NSEvent in mediaKeyTap:receivedMediaKeyEvent:"); + NSAssert([event type] == NSEventTypeSystemDefined && [event subtype] == SPSystemDefinedEventMediaKeys, @"Unexpected NSEvent in mediaKeyTap:receivedMediaKeyEvent:"); int keyCode = (([event data1] & 0xFFFF0000) >> 16); int keyFlags = ([event data1] & 0x0000FFFF); diff --git a/FileTree/FileTreeOutlineView.m b/FileTree/FileTreeOutlineView.m index 6a21949ab..286c27f0c 100644 --- a/FileTree/FileTreeOutlineView.m +++ b/FileTree/FileTreeOutlineView.m @@ -15,62 +15,62 @@ - (void)awakeFromNib { - [self setDoubleAction:@selector(addToPlaylistExternal:)]; - [self setTarget:[self delegate]]; + [self setDoubleAction:@selector(addToPlaylistExternal:)]; + [self setTarget:[self delegate]]; } - (void)keyDown:(NSEvent *)e { - unsigned int modifiers = [e modifierFlags] & (NSCommandKeyMask | NSShiftKeyMask | NSControlKeyMask | NSAlternateKeyMask); + unsigned int modifiers = [e modifierFlags] & (NSEventModifierFlagCommand | NSEventModifierFlagShift | NSEventModifierFlagControl | NSEventModifierFlagOption); NSString *characters = [e characters]; - unichar c; - - if ([characters length] == 1) - { - c = [characters characterAtIndex:0]; - - if (modifiers == 0 && (c == NSEnterCharacter || c == NSCarriageReturnCharacter)) - { - [(FileTreeController *)[self delegate] addToPlaylistExternal:self]; - - return; - } - else if (modifiers == 0 && c == ' ') - { - [(FileTreeController *)[self delegate] playPauseResume:self]; - return; - } - } - - [super keyDown:e]; - - return; + unichar c; + + if ([characters length] == 1) + { + c = [characters characterAtIndex:0]; + + if (modifiers == 0 && (c == NSEnterCharacter || c == NSCarriageReturnCharacter)) + { + [(FileTreeController *)[self delegate] addToPlaylistExternal:self]; + + return; + } + else if (modifiers == 0 && c == ' ') + { + [(FileTreeController *)[self delegate] playPauseResume:self]; + return; + } + } + + [super keyDown:e]; + + return; } // enables right-click selection for "Show in Finder" contextual menu -(NSMenu*)menuForEvent:(NSEvent*)event { - //Find which row is under the cursor - [[self window] makeFirstResponder:self]; - NSPoint menuPoint = [self convertPoint:[event locationInWindow] fromView:nil]; - NSInteger iRow = [self rowAtPoint:menuPoint]; - NSMenu* contextMenu = [self menu]; - - /* Update the file tree selection before showing menu - Preserves the selection if the row under the mouse is selected (to allow for - multiple items to be selected), otherwise selects the row under the mouse */ - BOOL currentRowIsSelected = [[self selectedRowIndexes] containsIndex:iRow]; - - if (iRow == -1) - { - [self deselectAll:self]; - } - else if (!currentRowIsSelected) - { - [self selectRowIndexes:[NSIndexSet indexSetWithIndex:iRow] byExtendingSelection:NO]; - } - - return contextMenu; + //Find which row is under the cursor + [[self window] makeFirstResponder:self]; + NSPoint menuPoint = [self convertPoint:[event locationInWindow] fromView:nil]; + NSInteger iRow = [self rowAtPoint:menuPoint]; + NSMenu* contextMenu = [self menu]; + + /* Update the file tree selection before showing menu + Preserves the selection if the row under the mouse is selected (to allow for + multiple items to be selected), otherwise selects the row under the mouse */ + BOOL currentRowIsSelected = [[self selectedRowIndexes] containsIndex:iRow]; + + if (iRow == -1) + { + [self deselectAll:self]; + } + else if (!currentRowIsSelected) + { + [self selectRowIndexes:[NSIndexSet indexSetWithIndex:iRow] byExtendingSelection:NO]; + } + + return contextMenu; } @end diff --git a/Playlist/PlaylistView.m b/Playlist/PlaylistView.m index 55a8b2a8d..baef28411 100644 --- a/Playlist/PlaylistView.m +++ b/Playlist/PlaylistView.m @@ -23,181 +23,181 @@ - (void)awakeFromNib { - [[self menu] setAutoenablesItems:NO]; - + [[self menu] setAutoenablesItems:NO]; + // Configure bindings to scale font size and row height - NSControlSize s = NSSmallControlSize; - NSFont *f = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:s]]; + NSControlSize s = NSControlSizeSmall; + NSFont *f = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:s]]; // NSFont *bf = [[NSFontManager sharedFontManager] convertFont:f toHaveTrait:NSBoldFontMask]; - - for (NSTableColumn *col in [self tableColumns]) { + + for (NSTableColumn *col in [self tableColumns]) { [[col dataCell] setControlSize:s]; [[col dataCell] setFont:f]; - } - - //Set up formatters - NSFormatter *secondsFormatter = [[SecondsFormatter alloc] init]; - [[[self tableColumnWithIdentifier:@"length"] dataCell] setFormatter:secondsFormatter]; - - NSFormatter *indexFormatter = [[IndexFormatter alloc] init]; - [[[self tableColumnWithIdentifier:@"index"] dataCell] setFormatter:indexFormatter]; - - NSFormatter *blankZeroFormatter = [[BlankZeroFormatter alloc] init]; - [[[self tableColumnWithIdentifier:@"track"] dataCell] setFormatter:blankZeroFormatter]; - [[[self tableColumnWithIdentifier:@"year"] dataCell] setFormatter:blankZeroFormatter]; - //end setting up formatters - - [self setVerticalMotionCanBeginDrag:YES]; - - //Set up header context menu - headerContextMenu = [[NSMenu alloc] initWithTitle:@"Playlist Header Context Menu"]; - - NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"identifier" ascending:YES]; - NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor]; - - int visibleTableColumns = 0; - int menuIndex = 0; - for (NSTableColumn *col in [[self tableColumns] sortedArrayUsingDescriptors: sortDescriptors]) - { - NSString *title; - if ([[col identifier] isEqualToString:@"status"]) - { - title = @"Status"; - } - else if ([[col identifier] isEqualToString:@"index"]) - { - title = @"Index"; - } - else - { - title = [[col headerCell] title]; - } - - NSMenuItem *contextMenuItem = [headerContextMenu insertItemWithTitle:title action:@selector(toggleColumn:) keyEquivalent:@"" atIndex:menuIndex]; - - [contextMenuItem setTarget:self]; - [contextMenuItem setRepresentedObject:col]; - [contextMenuItem setState:([col isHidden] ? NSOffState : NSOnState)]; - - visibleTableColumns += ![col isHidden]; - menuIndex++; - } - - if (visibleTableColumns == 0) { - for (NSTableColumn *col in [self tableColumns]) { - [col setHidden:NO]; - } - } - - [[self headerView] setMenu:headerContextMenu]; + } + + //Set up formatters + NSFormatter *secondsFormatter = [[SecondsFormatter alloc] init]; + [[[self tableColumnWithIdentifier:@"length"] dataCell] setFormatter:secondsFormatter]; + + NSFormatter *indexFormatter = [[IndexFormatter alloc] init]; + [[[self tableColumnWithIdentifier:@"index"] dataCell] setFormatter:indexFormatter]; + + NSFormatter *blankZeroFormatter = [[BlankZeroFormatter alloc] init]; + [[[self tableColumnWithIdentifier:@"track"] dataCell] setFormatter:blankZeroFormatter]; + [[[self tableColumnWithIdentifier:@"year"] dataCell] setFormatter:blankZeroFormatter]; + //end setting up formatters + + [self setVerticalMotionCanBeginDrag:YES]; + + //Set up header context menu + headerContextMenu = [[NSMenu alloc] initWithTitle:@"Playlist Header Context Menu"]; + + NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"identifier" ascending:YES]; + NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor]; + + int visibleTableColumns = 0; + int menuIndex = 0; + for (NSTableColumn *col in [[self tableColumns] sortedArrayUsingDescriptors: sortDescriptors]) + { + NSString *title; + if ([[col identifier] isEqualToString:@"status"]) + { + title = @"Status"; + } + else if ([[col identifier] isEqualToString:@"index"]) + { + title = @"Index"; + } + else + { + title = [[col headerCell] title]; + } + + NSMenuItem *contextMenuItem = [headerContextMenu insertItemWithTitle:title action:@selector(toggleColumn:) keyEquivalent:@"" atIndex:menuIndex]; + + [contextMenuItem setTarget:self]; + [contextMenuItem setRepresentedObject:col]; + [contextMenuItem setState:([col isHidden] ? NSOffState : NSOnState)]; + + visibleTableColumns += ![col isHidden]; + menuIndex++; + } + + if (visibleTableColumns == 0) { + for (NSTableColumn *col in [self tableColumns]) { + [col setHidden:NO]; + } + } + + [[self headerView] setMenu:headerContextMenu]; } - (IBAction)toggleColumn:(id)sender { - id tc = [sender representedObject]; - - if ([sender state] == NSOffState) - { - [sender setState:NSOnState]; - - [tc setHidden: NO]; - } - else - { - [sender setState:NSOffState]; - - [tc setHidden: YES]; - } + id tc = [sender representedObject]; + + if ([sender state] == NSOffState) + { + [sender setState:NSOnState]; + + [tc setHidden: NO]; + } + else + { + [sender setState:NSOffState]; + + [tc setHidden: YES]; + } } - (BOOL)acceptsFirstResponder { - return YES; + return YES; } - (BOOL)resignFirstResponder { - return YES; + return YES; } - (BOOL)acceptsFirstMouse:(NSEvent *)mouseDownEvent { - return NO; + return NO; } - (void)mouseDown:(NSEvent *)e { - [super mouseDown:e]; - - if ([e type] == NSLeftMouseDown && [e clickCount] == 2 && [[self selectedRowIndexes] count] == 1) - { - [playbackController play:self]; - } + [super mouseDown:e]; + + if ([e type] == NSEventTypeLeftMouseDown && [e clickCount] == 2 && [[self selectedRowIndexes] count] == 1) + { + [playbackController play:self]; + } } // enables right-click selection for "Show in Finder" contextual menu -(NSMenu*)menuForEvent:(NSEvent*)event { - //Find which row is under the cursor - [[self window] makeFirstResponder:self]; - NSPoint menuPoint = [self convertPoint:[event locationInWindow] fromView:nil]; - NSInteger iRow = [self rowAtPoint:menuPoint]; + //Find which row is under the cursor + [[self window] makeFirstResponder:self]; + NSPoint menuPoint = [self convertPoint:[event locationInWindow] fromView:nil]; + NSInteger iRow = [self rowAtPoint:menuPoint]; NSMenu* tableViewMenu = [self menu]; - - /* Update the table selection before showing menu - Preserves the selection if the row under the mouse is selected (to allow for - multiple items to be selected), otherwise selects the row under the mouse */ - BOOL currentRowIsSelected = [[self selectedRowIndexes] containsIndex:iRow]; - if (!currentRowIsSelected) { - if (iRow == -1) - { - [self deselectAll:self]; - } - else - { - [self selectRowIndexes:[NSIndexSet indexSetWithIndex:iRow] byExtendingSelection:NO]; - } - } - - if ([self numberOfSelectedRows] <=0) - { - //No rows are selected, so the table should be displayed with all items disabled - int i; - for (i=0;i<[tableViewMenu numberOfItems];i++) { - [[tableViewMenu itemAtIndex:i] setEnabled:NO]; - } - } - - return tableViewMenu; + + /* Update the table selection before showing menu + Preserves the selection if the row under the mouse is selected (to allow for + multiple items to be selected), otherwise selects the row under the mouse */ + BOOL currentRowIsSelected = [[self selectedRowIndexes] containsIndex:iRow]; + if (!currentRowIsSelected) { + if (iRow == -1) + { + [self deselectAll:self]; + } + else + { + [self selectRowIndexes:[NSIndexSet indexSetWithIndex:iRow] byExtendingSelection:NO]; + } + } + + if ([self numberOfSelectedRows] <=0) + { + //No rows are selected, so the table should be displayed with all items disabled + int i; + for (i=0;i<[tableViewMenu numberOfItems];i++) { + [[tableViewMenu itemAtIndex:i] setEnabled:NO]; + } + } + + return tableViewMenu; } - (void)keyDown:(NSEvent *)e { - unsigned int modifiers = [e modifierFlags] & (NSCommandKeyMask | NSShiftKeyMask | NSControlKeyMask | NSAlternateKeyMask); + unsigned int modifiers = [e modifierFlags] & (NSEventModifierFlagCommand | NSEventModifierFlagShift | NSEventModifierFlagControl | NSEventModifierFlagOption); NSString *characters = [e characters]; - unichar c; - - if ([characters length] != 1) - { - [super keyDown:e]; - - return; - } - - c = [characters characterAtIndex:0]; - if (modifiers == 0 && (c == NSDeleteCharacter || c == NSBackspaceCharacter || c == NSDeleteFunctionKey)) - { - [playlistController remove:self]; - } - else if (modifiers == 0 && c == ' ') - { - [playbackController playPauseResume:self]; - } - else if (modifiers == 0 && (c == NSEnterCharacter || c == NSCarriageReturnCharacter)) - { - [playbackController play:self]; - } + unichar c; + + if ([characters length] != 1) + { + [super keyDown:e]; + + return; + } + + c = [characters characterAtIndex:0]; + if (modifiers == 0 && (c == NSDeleteCharacter || c == NSBackspaceCharacter || c == NSDeleteFunctionKey)) + { + [playlistController remove:self]; + } + else if (modifiers == 0 && c == ' ') + { + [playbackController playPauseResume:self]; + } + else if (modifiers == 0 && (c == NSEnterCharacter || c == NSCarriageReturnCharacter)) + { + [playbackController play:self]; + } else if (modifiers == 0 && c == NSLeftArrowFunctionKey) { [playbackController eventSeekBackward:self]; @@ -206,31 +206,31 @@ { [playbackController eventSeekForward:self]; } - // Escape - else if (modifiers == 0 && c == 0x1b) - { - [playlistController clearFilterPredicate:self]; - } - else - { - [super keyDown:e]; - } + // Escape + else if (modifiers == 0 && c == 0x1b) + { + [playlistController clearFilterPredicate:self]; + } + else + { + [super keyDown:e]; + } } - (IBAction)scrollToCurrentEntry:(id)sender { - [self scrollRowToVisible:[[playlistController currentEntry] index]]; - [self selectRowIndexes:[NSIndexSet indexSetWithIndex:[[playlistController currentEntry] index]] byExtendingSelection:NO]; + [self scrollRowToVisible:[[playlistController currentEntry] index]]; + [self selectRowIndexes:[NSIndexSet indexSetWithIndex:[[playlistController currentEntry] index]] byExtendingSelection:NO]; } - (IBAction)undo:(id)sender { - [[playlistController undoManager] undo]; + [[playlistController undoManager] undo]; } - (IBAction)redo:(id)sender { - [[playlistController undoManager] redo]; + [[playlistController undoManager] redo]; } - (IBAction)copy:(id)sender @@ -257,7 +257,7 @@ [tracks setObject:track forKey:[NSString stringWithFormat:@"%lu", i]]; ++i; } - + NSMutableDictionary * itunesPlist = [NSMutableDictionary dictionaryWithObjectsAndKeys:tracks, @"Tracks", nil]; [pboard setPropertyList:itunesPlist forType:iTunesDropType]; @@ -279,69 +279,69 @@ [self copy:sender]; [playlistController removeObjectsAtArrangedObjectIndexes:[playlistController selectionIndexes]]; - + if ([playlistController shuffle] != ShuffleOff) [playlistController resetShuffleList]; } - (IBAction)paste:(id)sender { - // Determine the type of object that was dropped - NSArray *supportedTypes = [NSArray arrayWithObjects:CogUrlsPboardType, NSFilenamesPboardType, iTunesDropType, nil]; - NSPasteboard *pboard = [NSPasteboard generalPasteboard]; - NSString *bestType = [pboard availableTypeFromArray:supportedTypes]; + // Determine the type of object that was dropped + NSArray *supportedTypes = [NSArray arrayWithObjects:CogUrlsPboardType, NSFilenamesPboardType, iTunesDropType, nil]; + NSPasteboard *pboard = [NSPasteboard generalPasteboard]; + NSString *bestType = [pboard availableTypeFromArray:supportedTypes]; - NSMutableArray *acceptedURLs = [[NSMutableArray alloc] init]; - - // Get files from an file drawer drop - if ([bestType isEqualToString:CogUrlsPboardType]) { - NSArray *urls = [NSUnarchiver unarchiveObjectWithData:[pboard dataForType:CogUrlsPboardType]]; - DLog(@"URLS: %@", urls); - //[playlistLoader insertURLs: urls atIndex:row sort:YES]; - [acceptedURLs addObjectsFromArray:urls]; - } - - // Get files from a normal file drop (such as from Finder) - if ([bestType isEqualToString:NSFilenamesPboardType]) { - NSMutableArray *urls = [[NSMutableArray alloc] init]; + NSMutableArray *acceptedURLs = [[NSMutableArray alloc] init]; + + // Get files from an file drawer drop + if ([bestType isEqualToString:CogUrlsPboardType]) { + NSArray *urls = [NSUnarchiver unarchiveObjectWithData:[pboard dataForType:CogUrlsPboardType]]; + DLog(@"URLS: %@", urls); + //[playlistLoader insertURLs: urls atIndex:row sort:YES]; + [acceptedURLs addObjectsFromArray:urls]; + } + + // Get files from a normal file drop (such as from Finder) + if ([bestType isEqualToString:NSFilenamesPboardType]) { + NSMutableArray *urls = [[NSMutableArray alloc] init]; - for (NSString *file in [pboard propertyListForType:NSFilenamesPboardType]) - { - [urls addObject:[NSURL fileURLWithPath:file]]; - } - - //[playlistLoader insertURLs:urls atIndex:row sort:YES]; - [acceptedURLs addObjectsFromArray:urls]; - } - - // Get files from an iTunes drop - if ([bestType isEqualToString:iTunesDropType]) { - NSDictionary *iTunesDict = [pboard propertyListForType:iTunesDropType]; - NSDictionary *tracks = [iTunesDict valueForKey:@"Tracks"]; + for (NSString *file in [pboard propertyListForType:NSFilenamesPboardType]) + { + [urls addObject:[NSURL fileURLWithPath:file]]; + } - // Convert the iTunes URLs to URLs....MWAHAHAH! - NSMutableArray *urls = [[NSMutableArray alloc] init]; + //[playlistLoader insertURLs:urls atIndex:row sort:YES]; + [acceptedURLs addObjectsFromArray:urls]; + } + + // Get files from an iTunes drop + if ([bestType isEqualToString:iTunesDropType]) { + NSDictionary *iTunesDict = [pboard propertyListForType:iTunesDropType]; + NSDictionary *tracks = [iTunesDict valueForKey:@"Tracks"]; - for (NSDictionary *trackInfo in [tracks allValues]) { - [urls addObject:[NSURL URLWithString:[trackInfo valueForKey:@"Location"]]]; - } - - //[playlistLoader insertURLs:urls atIndex:row sort:YES]; - [acceptedURLs addObjectsFromArray:urls]; - } - - if ([acceptedURLs count]) - { + // Convert the iTunes URLs to URLs....MWAHAHAH! + NSMutableArray *urls = [[NSMutableArray alloc] init]; + + for (NSDictionary *trackInfo in [tracks allValues]) { + [urls addObject:[NSURL URLWithString:[trackInfo valueForKey:@"Location"]]]; + } + + //[playlistLoader insertURLs:urls atIndex:row sort:YES]; + [acceptedURLs addObjectsFromArray:urls]; + } + + if ([acceptedURLs count]) + { NSUInteger row = [[playlistController content] count]; [playlistController willInsertURLs:acceptedURLs origin:URLOriginInternal]; - - NSArray* entries = [playlistLoader insertURLs:acceptedURLs atIndex:(int)row sort:NO]; - [playlistLoader didInsertURLs:entries origin:URLOriginInternal]; - + + NSArray* entries = [playlistLoader insertURLs:acceptedURLs atIndex:(int)row sort:NO]; + [playlistLoader didInsertURLs:entries origin:URLOriginInternal]; + if ([playlistController shuffle] != ShuffleOff) [playlistController resetShuffleList]; - } + } } - (IBAction)delete:(id)sender @@ -352,22 +352,22 @@ -(BOOL)validateUserInterfaceItem:(id )anItem { - SEL action = [anItem action]; - - if (action == @selector(undo:)) - { - if ([[playlistController undoManager] canUndo]) - return YES; - else - return NO; - } - if (action == @selector(redo:)) - { - if ([[playlistController undoManager] canRedo]) - return YES; - else - return NO; - } + SEL action = [anItem action]; + + if (action == @selector(undo:)) + { + if ([[playlistController undoManager] canUndo]) + return YES; + else + return NO; + } + if (action == @selector(redo:)) + { + if ([[playlistController undoManager] canRedo]) + return YES; + else + return NO; + } if (action == @selector(cut:) || action == @selector(copy:) || action == @selector(delete:)) { if ([[playlistController selectionIndexes] count] == 0) @@ -378,7 +378,7 @@ if (action == @selector(paste:)) { NSPasteboard *pboard = [NSPasteboard generalPasteboard]; - + NSArray *supportedTypes = [NSArray arrayWithObjects:CogUrlsPboardType, NSFilenamesPboardType, iTunesDropType, nil]; NSString *bestType = [pboard availableTypeFromArray:supportedTypes]; @@ -388,20 +388,20 @@ else return NO; } - - if (action == @selector(scrollToCurrentEntry:) && (([playbackController playbackStatus] == kCogStatusStopped) || ([playbackController playbackStatus] == kCogStatusStopping))) - return NO; - - return [super validateUserInterfaceItem:anItem]; + + if (action == @selector(scrollToCurrentEntry:) && (([playbackController playbackStatus] == kCogStatusStopped) || ([playbackController playbackStatus] == kCogStatusStopping))) + return NO; + + return [super validateUserInterfaceItem:anItem]; } #if 0 - (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal { - if (isLocal) - return NSDragOperationNone; - else - return NSDragOperationCopy; + if (isLocal) + return NSDragOperationNone; + else + return NSDragOperationCopy; } #endif diff --git a/ThirdParty/ImageTextCell/ImageTextCell.m b/ThirdParty/ImageTextCell/ImageTextCell.m index d9e3a6044..0ec7213c7 100644 --- a/ThirdParty/ImageTextCell/ImageTextCell.m +++ b/ThirdParty/ImageTextCell/ImageTextCell.m @@ -47,8 +47,8 @@ - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView { if (image != nil) { - NSSize imageSize; - NSRect imageFrame; + NSSize imageSize; + NSRect imageFrame; imageSize = [image size]; NSDivideRect(cellFrame, &imageFrame, &cellFrame, 3 + imageSize.width, NSMinXEdge); @@ -58,10 +58,10 @@ } imageFrame.origin.x += 3; imageFrame.size = imageSize; - + imageFrame.origin.y += ceil((cellFrame.size.height - imageFrame.size.height) / 2); - - [image drawInRect:imageFrame fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0 respectFlipped:YES hints:nil]; + + [image drawInRect:imageFrame fromRect:NSZeroRect operation:NSCompositingOperationSourceOver fraction:1.0 respectFlipped:YES hints:nil]; } [super drawWithFrame:cellFrame inView:controlView]; } @@ -72,4 +72,4 @@ return cellSize; } -@end \ No newline at end of file +@end diff --git a/ThirdParty/OpenURLPanel/OpenURLPanel.m b/ThirdParty/OpenURLPanel/OpenURLPanel.m index 2f4921afe..f866580fa 100755 --- a/ThirdParty/OpenURLPanel/OpenURLPanel.m +++ b/ThirdParty/OpenURLPanel/OpenURLPanel.m @@ -1,54 +1,54 @@ /* - File: OpenURLPanel.m - - Originally introduced at WWDC 2004 at - Session 214, "Programming QuickTime with Cocoa." - Sample code is explained in detail in - "QTKit Programming Guide" documentation. - - - Copyright: © Copyright 2004, 2005 Apple Computer, Inc. - All rights reserved. - - Disclaimer: IMPORTANT: This Apple software is supplied to you by - Apple Computer, Inc. ("Apple") in consideration of your agreement to the - following terms, and your use, installation, modification or - redistribution of this Apple software constitutes acceptance of these - terms. If you do not agree with these terms, please do not use, - install, modify or redistribute this Apple software. - - In consideration of your agreement to abide by the following terms, and - subject to these terms, Apple grants you a personal, non-exclusive - license, under AppleÕs copyrights in this original Apple software (the - "Apple Software"), to use, reproduce, modify and redistribute the Apple - Software, with or without modifications, in source and/or binary forms; - provided that if you redistribute the Apple Software in its entirety and - without modifications, you must retain this notice and the following - text and disclaimers in all such redistributions of the Apple Software. - Neither the name, trademarks, service marks or logos of Apple Computer, - Inc. may be used to endorse or promote products derived from the Apple - Software without specific prior written permission from Apple. Except - as expressly stated in this notice, no other rights or licenses, express - or implied, are granted by Apple herein, including but not limited to - any patent rights that may be infringed by your derivative works or by - other works in which the Apple Software may be incorporated. - - The Apple Software is provided by Apple on an "AS IS" basis. APPLE - MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION - THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND - OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. - - IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL - OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, - MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED - AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), - STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - -*/ + File: OpenURLPanel.m + + Originally introduced at WWDC 2004 at + Session 214, "Programming QuickTime with Cocoa." + Sample code is explained in detail in + "QTKit Programming Guide" documentation. + + + Copyright: © Copyright 2004, 2005 Apple Computer, Inc. + All rights reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by + Apple Computer, Inc. ("Apple") in consideration of your agreement to the + following terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of these + terms. If you do not agree with these terms, please do not use, + install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under AppleÕs copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Computer, + Inc. may be used to endorse or promote products derived from the Apple + Software without specific prior written permission from Apple. Except + as expressly stated in this notice, no other rights or licenses, express + or implied, are granted by Apple herein, including but not limited to + any patent rights that may be infringed by your derivative works or by + other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + */ #import "OpenURLPanel.h" @@ -66,10 +66,10 @@ static OpenURLPanel *openURLPanel = nil; // class methods + (id)openURLPanel { - if (openURLPanel == nil) - openURLPanel = [[self alloc] init]; - - return openURLPanel; + if (openURLPanel == nil) + openURLPanel = [[self alloc] init]; + + return openURLPanel; } - (id)init @@ -78,84 +78,84 @@ static OpenURLPanel *openURLPanel = nil; { // init [self setURLArray:[NSMutableArray arrayWithCapacity:10]]; - + // listen for app termination notifications [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(writeURLs:) name:NSApplicationWillTerminateNotification object:NSApp]; } - - return self; + + return self; } - (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; - [self setURLArray:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [self setURLArray:nil]; } // getters - (NSString *)urlString { - NSString *urlString = nil; - - // get the url - urlString = [mUrlComboBox stringValue]; - - if (urlString == nil) - urlString = [mUrlComboBox objectValueOfSelectedItem]; - - if ([urlString length] == 0) - urlString = nil; - - return urlString; + NSString *urlString = nil; + + // get the url + urlString = [mUrlComboBox stringValue]; + + if (urlString == nil) + urlString = [mUrlComboBox objectValueOfSelectedItem]; + + if ([urlString length] == 0) + urlString = nil; + + return urlString; } - (NSURL *)url { - NSURL *url = nil; - NSString *urlString; - - // get the url - urlString = [self urlString]; - - if (urlString) - url = [NSURL URLWithString:urlString]; - - return url; + NSURL *url = nil; + NSString *urlString; + + // get the url + urlString = [self urlString]; + + if (urlString) + url = [NSURL URLWithString:urlString]; + + return url; } // setters - (void)setURLArray:(NSMutableArray *)urlLArray { - mUrlArray = urlLArray; + mUrlArray = urlLArray; } // delegates - (void)awakeFromNib { - NSArray *urls; - - // restore the previous urls - urls = [[NSUserDefaults standardUserDefaults] objectForKey:kUserDefaultURLsKey]; - [mUrlArray addObjectsFromArray:urls]; - - if (urls) - [mUrlComboBox addItemsWithObjectValues:urls]; + NSArray *urls; + + // restore the previous urls + urls = [[NSUserDefaults standardUserDefaults] objectForKey:kUserDefaultURLsKey]; + [mUrlArray addObjectsFromArray:urls]; + + if (urls) + [mUrlComboBox addItemsWithObjectValues:urls]; } // notifications - (void)writeURLs:(NSNotification *)notification { - NSUserDefaults *userDefaults; - - if ([mUrlArray count]) - { - // init - userDefaults = [NSUserDefaults standardUserDefaults]; - - // write out the urls - [userDefaults setObject:mUrlArray forKey:kUserDefaultURLsKey]; - [userDefaults synchronize]; - } + NSUserDefaults *userDefaults; + + if ([mUrlArray count]) + { + // init + userDefaults = [NSUserDefaults standardUserDefaults]; + + // write out the urls + [userDefaults setObject:mUrlArray forKey:kUserDefaultURLsKey]; + [userDefaults synchronize]; + } } // actions @@ -163,91 +163,91 @@ typedef id (*myIMP)(id, SEL, ...); - (IBAction)doOpenURL:(id)sender { - NSString *urlString; - NSURL *url; - BOOL informDelegate = YES; - myIMP callback; + NSString *urlString; + NSURL *url; + BOOL informDelegate = YES; + myIMP callback; + + if ([sender tag] == NSModalResponseOK) + { + // validate the URL + url = [self url]; + urlString = [self urlString]; + + if (url) + { + // save the url + if (![mUrlArray containsObject:urlString]) + { + // save the url + [mUrlArray addObject:urlString]; + + // add the url to the combo box + [mUrlComboBox addItemWithObjectValue:urlString]; + + // remove the oldest url if the maximum has been exceeded + if ([mUrlArray count] > kMaximumURLs) + { + [mUrlArray removeObjectAtIndex:0]; + [mUrlComboBox removeItemAtIndex:0]; + } + } + else + { + // move the url to the bottom of the list + [mUrlArray removeObject:urlString]; + [mUrlArray addObject:urlString]; + [mUrlComboBox removeItemWithObjectValue:urlString]; + [mUrlComboBox addItemWithObjectValue:urlString]; + } + } + else + { + if (mIsSheet) + NSRunAlertPanel(NSLocalizedString(@"InvalidURLShort", @""), NSLocalizedString(@"InvalidURLLong", @""), nil, nil, nil); + else + NSBeginAlertSheet(NSLocalizedString(@"InvalidURLShort", @""), nil, nil, nil, mPanel, nil, nil, nil, nil, NSLocalizedString(@"InvalidURLLong", @"")); - if ([sender tag] == NSOKButton) - { - // validate the URL - url = [self url]; - urlString = [self urlString]; - - if (url) - { - // save the url - if (![mUrlArray containsObject:urlString]) - { - // save the url - [mUrlArray addObject:urlString]; - - // add the url to the combo box - [mUrlComboBox addItemWithObjectValue:urlString]; - - // remove the oldest url if the maximum has been exceeded - if ([mUrlArray count] > kMaximumURLs) - { - [mUrlArray removeObjectAtIndex:0]; - [mUrlComboBox removeItemAtIndex:0]; - } - } - else - { - // move the url to the bottom of the list - [mUrlArray removeObject:urlString]; - [mUrlArray addObject:urlString]; - [mUrlComboBox removeItemWithObjectValue:urlString]; - [mUrlComboBox addItemWithObjectValue:urlString]; - } - } - else - { - if (mIsSheet) - NSRunAlertPanel(NSLocalizedString(@"InvalidURLShort", @""), NSLocalizedString(@"InvalidURLLong", @""), nil, nil, nil); - else - NSBeginAlertSheet(NSLocalizedString(@"InvalidURLShort", @""), nil, nil, nil, mPanel, nil, nil, nil, nil, NSLocalizedString(@"InvalidURLLong", @"")); - - informDelegate = NO; - } - } - - // inform the delegate - if (informDelegate && mDelegate && mDidEndSelector) - { - callback = (myIMP) [mDelegate methodForSelector:mDidEndSelector]; - callback(mDelegate, mDidEndSelector, self, [sender tag], mContextInfo); - - [self close]; - } + informDelegate = NO; + } + } + + // inform the delegate + if (informDelegate && mDelegate && mDidEndSelector) + { + callback = (myIMP) [mDelegate methodForSelector:mDidEndSelector]; + callback(mDelegate, mDidEndSelector, self, [sender tag], mContextInfo); + + [self close]; + } } // methods - (void)beginSheetWithWindow:(NSWindow *)window delegate:(id)delegate didEndSelector:(SEL)didEndSelector contextInfo:(void *)contextInfo { - // will this run as a sheet - mIsSheet = (window ? YES : NO); + // will this run as a sheet + mIsSheet = (window ? YES : NO); - // save the delegate, did end selector, and context info - mDelegate = delegate; - mDidEndSelector = (didEndSelector); - mContextInfo = contextInfo; + // save the delegate, did end selector, and context info + mDelegate = delegate; + mDidEndSelector = (didEndSelector); + mContextInfo = contextInfo; NSArray *objects; - // load the bundle (if necessary) - if (mPanel == nil) + // load the bundle (if necessary) + if (mPanel == nil) [[NSBundle mainBundle] loadNibNamed:@"OpenURLPanel" owner:self topLevelObjects:&objects]; - // start the sheet (or window) - [NSApp beginSheet:mPanel modalForWindow:window modalDelegate:nil didEndSelector:nil contextInfo:nil]; + // start the sheet (or window) + [NSApp beginSheet:mPanel modalForWindow:window modalDelegate:nil didEndSelector:nil contextInfo:nil]; } - (void)close { - // close it down - [NSApp endSheet:mPanel]; - [mPanel close]; + // close it down + [NSApp endSheet:mPanel]; + [mPanel close]; } @end From 832fa6dbd01d76aac5b518d8a9ceeaaac1eea64f Mon Sep 17 00:00:00 2001 From: Dzmitry Neviadomski Date: Wed, 27 Jan 2021 05:45:02 +0300 Subject: [PATCH 4/6] Even more deprecations fixes. --- Plugins/GME/GameMetadataReader.m | 6 +++--- Plugins/HighlyComplete/HighlyComplete/HCDecoder.mm | 6 +++--- Spotlight/SpotlightTransformers.m | 4 ++-- ThirdParty/OpenURLPanel/OpenURLPanel.m | 9 ++++++--- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/Plugins/GME/GameMetadataReader.m b/Plugins/GME/GameMetadataReader.m index 5c77c6752..810c9fecc 100644 --- a/Plugins/GME/GameMetadataReader.m +++ b/Plugins/GME/GameMetadataReader.m @@ -48,7 +48,7 @@ if (!type) { ALog(@"GME: No type!"); - return NO; + return nil; } Music_Emu* emu; @@ -56,7 +56,7 @@ if (!emu) { ALog(@"GME: No new emu!"); - return NO; + return nil; } [source seek:0 whence:SEEK_END]; @@ -68,7 +68,7 @@ if (error) { ALog(@"GME: ERROR Loding file!"); - return NO; + return nil; } NSURL *m3uurl = [url URLByDeletingPathExtension]; diff --git a/Plugins/HighlyComplete/HighlyComplete/HCDecoder.mm b/Plugins/HighlyComplete/HighlyComplete/HCDecoder.mm index 11494cd24..dc2d4d0de 100644 --- a/Plugins/HighlyComplete/HighlyComplete/HCDecoder.mm +++ b/Plugins/HighlyComplete/HighlyComplete/HCDecoder.mm @@ -112,7 +112,7 @@ void * source_fopen(const char * path) if ( ![[psf_file_container instance] try_hint:[NSString stringWithUTF8String:path] source:&source] ) { NSString * urlString = [NSString stringWithUTF8String:path]; - NSURL * url = [NSURL URLWithString:[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; + NSURL * url = [NSURL URLWithString:[urlString stringByAddingPercentEncodingWithAllowedCharacters:NSCharacterSet.URLPathAllowedCharacterSet]]; id audioSourceClass = NSClassFromString(@"AudioSource"); source = [audioSourceClass audioSourceForURL:url]; @@ -1271,7 +1271,7 @@ static int usf_info(void * context, const char * name, const char * value) info.trackPeak = 0; info.volume = 1; - currentUrl = [[[source url] absoluteString] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + currentUrl = [[[source url] absoluteString] stringByRemovingPercentEncoding]; [[psf_file_container instance] add_hint:currentUrl source:currentSource]; hintAdded = YES; @@ -1706,7 +1706,7 @@ static int usf_info(void * context, const char * name, const char * value) info.tag_length_ms = 0; info.tag_fade_ms = 0; - NSString * decodedUrl = [[url absoluteString] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + NSString * decodedUrl = [[url absoluteString] stringByRemovingPercentEncoding]; psf_load( [decodedUrl UTF8String], &source_callbacks, 0, 0, 0, psf_info_meta, &info, 0 ); diff --git a/Spotlight/SpotlightTransformers.m b/Spotlight/SpotlightTransformers.m index dc2eaf472..6839234c1 100644 --- a/Spotlight/SpotlightTransformers.m +++ b/Spotlight/SpotlightTransformers.m @@ -95,7 +95,7 @@ static SpotlightWindowController * searchController; if (value == nil) return nil; // If there's an NS/CFNumber hiding in here... - if([value respondsToSelector:@selector(stringValue:)]) + if([value respondsToSelector:@selector(stringValue)]) { return [value stringValue]; } @@ -103,4 +103,4 @@ static SpotlightWindowController * searchController; return value; } -@end \ No newline at end of file +@end diff --git a/ThirdParty/OpenURLPanel/OpenURLPanel.m b/ThirdParty/OpenURLPanel/OpenURLPanel.m index f866580fa..f425ab390 100755 --- a/ThirdParty/OpenURLPanel/OpenURLPanel.m +++ b/ThirdParty/OpenURLPanel/OpenURLPanel.m @@ -203,10 +203,13 @@ typedef id (*myIMP)(id, SEL, ...); } else { + NSAlert *alert = [[NSAlert alloc] init]; + alert.messageText = NSLocalizedString(@"InvalidURLShort", @""); + alert.informativeText = NSLocalizedString(@"InvalidURLLong", @""); if (mIsSheet) - NSRunAlertPanel(NSLocalizedString(@"InvalidURLShort", @""), NSLocalizedString(@"InvalidURLLong", @""), nil, nil, nil); + [alert runModal]; else - NSBeginAlertSheet(NSLocalizedString(@"InvalidURLShort", @""), nil, nil, nil, mPanel, nil, nil, nil, nil, NSLocalizedString(@"InvalidURLLong", @"")); + [alert beginSheetModalForWindow:mPanel completionHandler:nil]; informDelegate = NO; } @@ -240,7 +243,7 @@ typedef id (*myIMP)(id, SEL, ...); [[NSBundle mainBundle] loadNibNamed:@"OpenURLPanel" owner:self topLevelObjects:&objects]; // start the sheet (or window) - [NSApp beginSheet:mPanel modalForWindow:window modalDelegate:nil didEndSelector:nil contextInfo:nil]; + [window beginSheet:mPanel completionHandler:nil]; } - (void)close From 730276a7e7bc2d579d8784d2a3f216d98882ee1a Mon Sep 17 00:00:00 2001 From: Dzmitry Neviadomski Date: Thu, 28 Jan 2021 01:09:09 +0300 Subject: [PATCH 5/6] Modernize DNDArrayController. --- Playlist/DNDArrayController.h | 26 +++--- Playlist/DNDArrayController.m | 155 +++++++++++++++++----------------- Playlist/PlaylistController.m | 2 +- 3 files changed, 96 insertions(+), 87 deletions(-) diff --git a/Playlist/DNDArrayController.h b/Playlist/DNDArrayController.h index 7417f9ea4..e475dce36 100755 --- a/Playlist/DNDArrayController.h +++ b/Playlist/DNDArrayController.h @@ -1,22 +1,28 @@ #import -extern NSString *MovedRowsType; +extern NSString *CogPlaylistItemType; extern NSString *CogUrlsPboardType; extern NSString *iTunesDropType; -@interface DNDArrayController : NSArrayController -{ - IBOutlet NSTableView *tableView; -} +@interface DNDArrayController : NSArrayController + +@property IBOutlet NSTableView *tableView; // table view drag and drop support -- (BOOL)tableView:(NSTableView *)aTableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pboard; -- (NSDragOperation)tableView:(NSTableView*)tv validateDrop:(id )info proposedRow:(int)row proposedDropOperation:(NSTableViewDropOperation)op; -- (BOOL)tableView:(NSTableView*)tv acceptDrop:(id )info row:(int)row dropOperation:(NSTableViewDropOperation)op; - +- (id )tableView:(NSTableView *)tableView + pasteboardWriterForRow:(NSInteger)row; +- (NSDragOperation)tableView:(NSTableView *)tableView + validateDrop:(id )info + proposedRow:(int)row + proposedDropOperation:(NSTableViewDropOperation)dropOperation; +- (BOOL)tableView:(NSTableView *)tableView + acceptDrop:(id )info + row:(int)row + dropOperation:(NSTableViewDropOperation)dropOperation; // utility methods --(void)moveObjectsInArrangedObjectsFromIndexes:(NSIndexSet*)indexSet toIndex:(unsigned int)insertIndex; +-(void)moveObjectsInArrangedObjectsFromIndexes:(NSIndexSet *)indexSet + toIndex:(unsigned int)insertIndex; @end diff --git a/Playlist/DNDArrayController.m b/Playlist/DNDArrayController.m index 664177829..1e57aa543 100755 --- a/Playlist/DNDArrayController.m +++ b/Playlist/DNDArrayController.m @@ -5,7 +5,7 @@ @implementation DNDArrayController -NSString *MovedRowsType = @"MOVED_ROWS_TYPE"; +NSString *CogPlaylistItemType = @"org.cogx.cog.playlist-item"; NSString *CogUrlsPboardType = @"COG_URLS_TYPE"; // @"CorePasteboardFlavorType 0x6974756E" is the "itun" type representing an iTunes plist @@ -14,102 +14,105 @@ NSString *iTunesDropType = @"CorePasteboardFlavorType 0x6974756E"; - (void)awakeFromNib { // register for drag and drop - [tableView registerForDraggedTypes:[NSArray arrayWithObjects:MovedRowsType, CogUrlsPboardType, NSFilenamesPboardType, iTunesDropType, nil]]; + [self.tableView registerForDraggedTypes:@[CogPlaylistItemType, CogUrlsPboardType, + NSFilenamesPboardType, iTunesDropType]]; } -- (BOOL)tableView:(NSTableView *)aTableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pboard +- (id )tableView:(NSTableView *)tableView + pasteboardWriterForRow:(NSInteger)row { - DLog(@"INDEX SET ON DRAG: %@", rowIndexes); - - NSData *data = [NSArchiver archivedDataWithRootObject:rowIndexes]; - - [pboard declareTypes: [NSArray arrayWithObjects:MovedRowsType, nil] owner:self]; - [pboard setData:data forType: MovedRowsType]; + NSPasteboardItem *item = [[NSPasteboardItem alloc] init]; + [item setString:[@(row) stringValue] forType:CogPlaylistItemType]; + + return item; +} - return YES; +- (void)tableView:(NSTableView *)tableView + draggingSession:(NSDraggingSession *)session + willBeginAtPoint:(NSPoint)screenPoint + forRowIndexes:(NSIndexSet *)rowIndexes +{ + DLog(@"Drag session started with indexes: %@", rowIndexes); } -- (NSDragOperation)tableView:(NSTableView*)tv - validateDrop:(id )info - proposedRow:(int)row - proposedDropOperation:(NSTableViewDropOperation)op +- (NSDragOperation)tableView:(NSTableView*)tableView + validateDrop:(id )info + proposedRow:(int)row + proposedDropOperation:(NSTableViewDropOperation)dropOperation { - NSDragOperation dragOp = NSDragOperationCopy; - - if ([info draggingSource] == tv) - dragOp = NSDragOperationMove; - - DLog(@"VALIDATING DROP!"); + NSDragOperation dragOp = NSDragOperationCopy; + + if ([info draggingSource] == tableView) + dragOp = NSDragOperationMove; + + DLog(@"VALIDATING DROP!"); // we want to put the object at, not over, - // the current row (contrast NSTableViewDropOn) - [tv setDropRow:row dropOperation:NSTableViewDropAbove]; - + // the current row (contrast NSTableViewDropOn) + [tableView setDropRow:row dropOperation:NSTableViewDropAbove]; + return dragOp; } -- (BOOL)tableView:(NSTableView*)tv - acceptDrop:(id )info - row:(int)row - dropOperation:(NSTableViewDropOperation)op +- (BOOL)tableView:(NSTableView*)tableView + acceptDrop:(id )info + row:(int)row + dropOperation:(NSTableViewDropOperation)dropOperation { - if (row < 0) - { - row = 0; - } - + if (row < 0) { + row = 0; + } + + NSArray *items = info.draggingPasteboard.pasteboardItems; // if drag source is self, it's a move - if ([info draggingSource] == tableView) - { - NSIndexSet *indexSet = [NSUnarchiver unarchiveObjectWithData:[[info draggingPasteboard] dataForType:MovedRowsType]]; - if (indexSet) - { - DLog(@"INDEX SET ON DROP: %@", indexSet); - NSArray *selected = [[self arrangedObjects] objectsAtIndexes:indexSet]; - [self moveObjectsInArrangedObjectsFromIndexes:indexSet toIndex:row]; - - [self setSelectedObjects:selected]; - - DLog(@"ACCEPTING DROP!"); - return YES; - } - } - DLog(@"REJECTING DROP!"); - return NO; + if ([info draggingSource] == tableView || items == nil) { + NSMutableIndexSet *indexSet = [NSMutableIndexSet indexSet]; + for (NSPasteboardItem *item in items) { + [indexSet addIndex:[[item stringForType:CogPlaylistItemType] intValue]]; + } + if ([indexSet count] > 0) { + DLog(@"INDEX SET ON DROP: %@", indexSet); + NSArray *selected = [[self arrangedObjects] objectsAtIndexes:indexSet]; + [self moveObjectsInArrangedObjectsFromIndexes:indexSet toIndex:row]; + + [self setSelectedObjects:selected]; + + DLog(@"ACCEPTING DROP!"); + return YES; + } + } + DLog(@"REJECTING DROP!"); + return NO; } --(void) moveObjectsInArrangedObjectsFromIndexes:(NSIndexSet*)indexSet - toIndex:(unsigned int)insertIndex +-(void) moveObjectsInArrangedObjectsFromIndexes:(NSIndexSet *)indexSet + toIndex:(unsigned int)insertIndex { - - NSArray *objects = [self arrangedObjects]; - NSUInteger index = [indexSet lastIndex]; - - int aboveInsertIndexCount = 0; - id object; - int removeIndex; - - while (NSNotFound != index) - { - if (index >= insertIndex) { - removeIndex = (int)(index + aboveInsertIndexCount); - aboveInsertIndexCount += 1; - } - else - { - removeIndex = (int)index; - insertIndex -= 1; - } - - object = [objects objectAtIndex:removeIndex]; + NSArray *objects = [self arrangedObjects]; + NSUInteger index = [indexSet lastIndex]; - [self removeObjectAtArrangedObjectIndex:removeIndex]; - [self insertObject:object atArrangedObjectIndex:insertIndex]; - - index = [indexSet indexLessThanIndex:index]; + int aboveInsertIndexCount = 0; + id object; + int removeIndex; + + while (NSNotFound != index) { + if (index >= insertIndex) { + removeIndex = (int)(index + aboveInsertIndexCount); + aboveInsertIndexCount += 1; + } else { + removeIndex = (int)index; + insertIndex -= 1; + } + + object = [objects objectAtIndex:removeIndex]; + + [self removeObjectAtArrangedObjectIndex:removeIndex]; + [self insertObject:object atArrangedObjectIndex:insertIndex]; + + index = [indexSet indexLessThanIndex:index]; } } diff --git a/Playlist/PlaylistController.m b/Playlist/PlaylistController.m index ad860f37c..f99e5db2c 100644 --- a/Playlist/PlaylistController.m +++ b/Playlist/PlaylistController.m @@ -867,7 +867,7 @@ pe.current = YES; if (pe != nil) - [tableView scrollRowToVisible:pe.index]; + [self.tableView scrollRowToVisible:pe.index]; currentEntry = pe; } From c1da9a66e17a856c4273becfa696dbdc0d8f3253 Mon Sep 17 00:00:00 2001 From: Dzmitry Neviadomski Date: Sun, 31 Jan 2021 02:14:08 +0300 Subject: [PATCH 6/6] Modernize several classes. Use modern ObjC syntax. Use new Pasteboard APIs. Explicitly declare protocols. --- FileTree/FileTreeDataSource.h | 14 +- FileTree/FileTreeDataSource.m | 245 +++--- Playlist/DNDArrayController.h | 10 +- Playlist/DNDArrayController.m | 80 +- Playlist/PlaylistController.h | 70 +- Playlist/PlaylistController.m | 1497 +++++++++++++++------------------ Playlist/PlaylistView.h | 8 +- Playlist/PlaylistView.m | 417 +++++---- Playlist/XmlContainer.h | 4 +- Playlist/XmlContainer.m | 162 ++-- Window/RepeatTransformers.h | 4 +- Window/RepeatTransformers.m | 92 +- 12 files changed, 1210 insertions(+), 1393 deletions(-) diff --git a/FileTree/FileTreeDataSource.h b/FileTree/FileTreeDataSource.h index 5ea9597ac..7b281dcf4 100644 --- a/FileTree/FileTreeDataSource.h +++ b/FileTree/FileTreeDataSource.h @@ -11,16 +11,12 @@ @class PathNode; @class PathWatcher; -@interface FileTreeDataSource : NSObject { - PathNode *rootNode; - - IBOutlet NSPathControl *pathControl; - IBOutlet PathWatcher *watcher; - IBOutlet NSOutlineView *outlineView; -} +@interface FileTreeDataSource : NSObject + +@property(nonatomic, weak) IBOutlet NSOutlineView *outlineView; +@property(nonatomic, weak) IBOutlet NSPathControl *pathControl; +@property(nonatomic, weak) IBOutlet PathWatcher *watcher; -- (NSURL *)rootURL; -- (void)setRootURL:(NSURL *)rootURL; - (void)changeURL:(NSURL *)rootURL; - (void)reloadPathNode:(PathNode *)item; diff --git a/FileTree/FileTreeDataSource.m b/FileTree/FileTreeDataSource.m index 6c644c3b3..9bfb4e82a 100644 --- a/FileTree/FileTreeDataSource.m +++ b/FileTree/FileTreeDataSource.m @@ -8,176 +8,159 @@ #import "FileTreeDataSource.h" -#import "DNDArrayController.h" - #import "DirectoryNode.h" #import "PathWatcher.h" #import "Logging.h" -@implementation FileTreeDataSource - -+ (void)initialize -{ - NSMutableDictionary *userDefaultsValuesDict = [NSMutableDictionary dictionary]; - - [userDefaultsValuesDict setObject:[[NSURL fileURLWithPath:[@"~/Music" stringByExpandingTildeInPath]] absoluteString] forKey:@"fileTreeRootURL"]; - - [[NSUserDefaults standardUserDefaults] registerDefaults:userDefaultsValuesDict]; +NSURL *defaultMusicDirectory() { + return [[NSFileManager defaultManager] URLForDirectory:NSMusicDirectory + inDomain:NSUserDomainMask + appropriateForURL:nil + create:NO + error:nil]; } -- (void)awakeFromNib -{ - [[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.fileTreeRootURL" options:0 context:nil]; - - [self setRootURL: [NSURL URLWithString:[[[NSUserDefaultsController sharedUserDefaultsController] defaults] objectForKey:@"fileTreeRootURL"]]]; +@interface FileTreeDataSource() - [pathControl setTarget:self]; - [pathControl setAction:@selector(pathControlAction:)]; +@property NSURL *rootURL; + +@end + +@implementation FileTreeDataSource { + PathNode *rootNode; } -- (void) observeValueForKeyPath:(NSString *)keyPath - ofObject:(id)object - change:(NSDictionary *)change - context:(void *)context -{ - DLog(@"File tree root URL: %@\n", [[[NSUserDefaultsController sharedUserDefaultsController] defaults] objectForKey:@"fileTreeRootURL"]); - if ([keyPath isEqualToString:@"values.fileTreeRootURL"]) { - [self setRootURL:[NSURL URLWithString:[[[NSUserDefaultsController sharedUserDefaultsController] defaults] objectForKey:@"fileTreeRootURL"]]]; - } ++ (void)initialize { + NSString *path = [defaultMusicDirectory() absoluteString]; + NSDictionary *userDefaultsValuesDict = @{@"fileTreeRootURL": path}; + [[NSUserDefaults standardUserDefaults] registerDefaults:userDefaultsValuesDict]; } -- (void)changeURL:(NSURL *)url -{ - if (url != nil) - { - [[[NSUserDefaultsController sharedUserDefaultsController] defaults] setObject:[url absoluteString] forKey:@"fileTreeRootURL"]; - } +- (void)awakeFromNib { + [self.pathControl setTarget:self]; + [self.pathControl setAction:@selector(pathControlAction:)]; + [[NSUserDefaultsController sharedUserDefaultsController] addObserver:self + forKeyPath:@"values.fileTreeRootURL" + options:NSKeyValueObservingOptionNew | + NSKeyValueObservingOptionInitial + context:nil]; } -- (void)pathControlAction:(id)sender -{ - if ([pathControl clickedPathComponentCell] != nil && [[pathControl clickedPathComponentCell] URL] != nil) - { - [self changeURL:[[pathControl clickedPathComponentCell] URL]]; - } +- (void)observeValueForKeyPath:(NSString *)keyPath + ofObject:(id)object + change:(NSDictionary *)change + context:(void *)context { + if ([keyPath isEqualToString:@"values.fileTreeRootURL"]) { + NSString *url = + [[[NSUserDefaultsController sharedUserDefaultsController] defaults] objectForKey:@"fileTreeRootURL"]; + DLog(@"File tree root URL: %@\n", url); + self.rootURL = [NSURL URLWithString:url]; + } } -- (NSURL *)rootURL -{ - return [rootNode URL]; +- (void)changeURL:(NSURL *)url { + if (url != nil) { + [[[NSUserDefaultsController sharedUserDefaultsController] defaults] setObject:[url absoluteString] + forKey:@"fileTreeRootURL"]; + } } -- (void)setRootURL: (NSURL *)rootURL -{ - if (![[NSFileManager defaultManager] fileExistsAtPath:[rootURL path]]) - rootURL = [NSURL fileURLWithPath:[@"~/Music" stringByExpandingTildeInPath]]; - - rootNode = [[DirectoryNode alloc] initWithDataSource:self url:rootURL]; - - [watcher setPath:[rootURL path]]; - - [self reloadPathNode:rootNode]; +- (void)pathControlAction:(id)sender { + NSPathControlItem *item = [self.pathControl clickedPathItem]; + if (item != nil && item.URL != nil) { + [self changeURL:item.URL]; + } } -- (PathNode *)nodeForPath:(NSString *)path -{ - NSString *relativePath = [[path stringByReplacingOccurrencesOfString:[[[self rootURL] path] stringByAppendingString:@"/"] - withString:@"" - options:NSAnchoredSearch - range:NSMakeRange(0, [path length]) - ] stringByStandardizingPath]; - PathNode *node = rootNode; - DLog(@"Root | Relative | Path: %@ | %@ | %@",[[self rootURL] path], relativePath, path); - for (NSString *c in [relativePath pathComponents]) - { - DLog(@"COMPONENT: %@", c); - BOOL found = NO; - for (PathNode *subnode in [node subpaths]) { - if ([[[[subnode URL] path] lastPathComponent] isEqualToString:c]) { - node = subnode; - found = YES; - } - } - - if (!found) - { - DLog(@"Not found!"); - return nil; - } - } - - return node; +- (NSURL *)rootURL { + return [rootNode URL]; } -- (void)pathDidChange:(NSString *)path -{ - DLog(@"PATH DID CHANGE: %@", path); - //Need to find the corresponding node...and call [node reloadPath], then [self reloadPathNode:node] - PathNode *node = [self nodeForPath:path]; - DLog(@"NODE IS: %@", node); - [node updatePath]; - [self reloadPathNode:node]; +- (void)setRootURL:(NSURL *)rootURL { + if (![[NSFileManager defaultManager] fileExistsAtPath:[rootURL path]]) { + rootURL = defaultMusicDirectory(); + } + + rootNode = [[DirectoryNode alloc] initWithDataSource:self url:rootURL]; + + [self.watcher setPath:[rootURL path]]; + + [self reloadPathNode:rootNode]; } -- (int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item -{ - PathNode *n = (item == nil ? rootNode : item); +- (PathNode *)nodeForPath:(NSString *)path { + NSString *relativePath = [[path stringByReplacingOccurrencesOfString:[[[self rootURL] path] stringByAppendingString:@"/"] + withString:@"" + options:NSAnchoredSearch + range:NSMakeRange(0, [path length]) + ] stringByStandardizingPath]; + PathNode *node = rootNode; + DLog(@"Root | Relative | Path: %@ | %@ | %@", [[self rootURL] path], relativePath, path); + for (NSString *c in [relativePath pathComponents]) { + DLog(@"COMPONENT: %@", c); + BOOL found = NO; + for (PathNode *subnode in [node subpaths]) { + if ([[[[subnode URL] path] lastPathComponent] isEqualToString:c]) { + node = subnode; + found = YES; + } + } + + if (!found) { + DLog(@"Not found!"); + return nil; + } + } + + return node; +} + +- (void)pathDidChange:(NSString *)path { + DLog(@"PATH DID CHANGE: %@", path); + //Need to find the corresponding node...and call [node reloadPath], then [self reloadPathNode:node] + PathNode *node = [self nodeForPath:path]; + DLog(@"NODE IS: %@", node); + [node updatePath]; + [self reloadPathNode:node]; +} + +- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item { + PathNode *n = (item == nil ? rootNode : item); return (int) [[n subpaths] count]; } - -- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item -{ - PathNode *n = (item == nil ? rootNode : item); +- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item { + PathNode *n = (item == nil ? rootNode : item); - return ([n isLeaf] == NO); + return ![n isLeaf]; } -- (id)outlineView:(NSOutlineView *)outlineView child:(int)index ofItem:(id)item -{ - PathNode *n = (item == nil ? rootNode : item); +- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item { + PathNode *n = (item == nil ? rootNode : item); - return [[n subpaths] objectAtIndex:index]; + return [n subpaths][(NSUInteger) index]; } -- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item -{ - PathNode *n = (item == nil ? rootNode : item); +- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item { + PathNode *n = (item == nil ? rootNode : item); - return n; + return n; } -//Drag it drop it -- (BOOL)outlineView:(NSOutlineView *)outlineView writeItems:(NSArray*)items toPasteboard:(NSPasteboard*)pboard { - //Get selected paths - NSMutableArray *urls = [NSMutableArray arrayWithCapacity:[items count]]; - NSMutableArray *paths = [NSMutableArray arrayWithCapacity:[items count]]; - - for (id p in items) { - [urls addObject:[p URL]]; - [paths addObject:[[p URL] path]]; - } - DLog(@"Paths: %@", paths); - [pboard declareTypes:[NSArray arrayWithObjects:CogUrlsPboardType,nil] owner:nil]; //add it to pboard - [pboard setData:[NSArchiver archivedDataWithRootObject:urls] forType:CogUrlsPboardType]; - [pboard addTypes:[NSArray arrayWithObject:NSFilenamesPboardType] owner:self]; - [pboard setPropertyList:paths forType:NSFilenamesPboardType]; - - return YES; +- (id )outlineView:(NSOutlineView *)outlineView pasteboardWriterForItem:(id)item { + NSPasteboardItem *paste = [[NSPasteboardItem alloc] init]; + [paste setData:[[item URL] dataRepresentation] forType:NSPasteboardTypeFileURL]; + return paste; } -- (void)reloadPathNode:(PathNode *)item -{ - if (item == rootNode) - { - [outlineView reloadData]; - } - else - { - [outlineView reloadItem:item reloadChildren:YES]; - } +- (void)reloadPathNode:(PathNode *)item { + if (item == rootNode) { + [self.outlineView reloadData]; + } else { + [self.outlineView reloadItem:item reloadChildren:YES]; + } } @end diff --git a/Playlist/DNDArrayController.h b/Playlist/DNDArrayController.h index e475dce36..0194fae52 100755 --- a/Playlist/DNDArrayController.h +++ b/Playlist/DNDArrayController.h @@ -1,7 +1,7 @@ #import -extern NSString *CogPlaylistItemType; +extern NSString *CogDNDIndexType; extern NSString *CogUrlsPboardType; extern NSString *iTunesDropType; @@ -12,13 +12,17 @@ extern NSString *iTunesDropType; // table view drag and drop support - (id )tableView:(NSTableView *)tableView pasteboardWriterForRow:(NSInteger)row; +- (void)tableView:(NSTableView *)tableView + draggingSession:(NSDraggingSession *)session + willBeginAtPoint:(NSPoint)screenPoint + forRowIndexes:(NSIndexSet *)rowIndexes; - (NSDragOperation)tableView:(NSTableView *)tableView validateDrop:(id )info - proposedRow:(int)row + proposedRow:(NSInteger)row proposedDropOperation:(NSTableViewDropOperation)dropOperation; - (BOOL)tableView:(NSTableView *)tableView acceptDrop:(id )info - row:(int)row + row:(NSInteger)row dropOperation:(NSTableViewDropOperation)dropOperation; // utility methods diff --git a/Playlist/DNDArrayController.m b/Playlist/DNDArrayController.m index 1e57aa543..bda5ac7e1 100755 --- a/Playlist/DNDArrayController.m +++ b/Playlist/DNDArrayController.m @@ -3,45 +3,43 @@ #import "Logging.h" +NSString *CogDNDIndexType = @"org.cogx.cog.dnd-index"; +NSString *CogUrlsPboardType = @"org.cogx.cog.url"; +NSString *iTunesDropType = @"com.apple.tv.metadata"; + @implementation DNDArrayController -NSString *CogPlaylistItemType = @"org.cogx.cog.playlist-item"; -NSString *CogUrlsPboardType = @"COG_URLS_TYPE"; - -// @"CorePasteboardFlavorType 0x6974756E" is the "itun" type representing an iTunes plist -NSString *iTunesDropType = @"CorePasteboardFlavorType 0x6974756E"; - -- (void)awakeFromNib -{ +- (void)awakeFromNib { + [super awakeFromNib]; // register for drag and drop - [self.tableView registerForDraggedTypes:@[CogPlaylistItemType, CogUrlsPboardType, - NSFilenamesPboardType, iTunesDropType]]; + [self.tableView registerForDraggedTypes:@[CogDNDIndexType, + CogUrlsPboardType, + NSPasteboardTypeFileURL, + iTunesDropType]]; } - (id )tableView:(NSTableView *)tableView - pasteboardWriterForRow:(NSInteger)row -{ + pasteboardWriterForRow:(NSInteger)row { NSPasteboardItem *item = [[NSPasteboardItem alloc] init]; - [item setString:[@(row) stringValue] forType:CogPlaylistItemType]; - + [item setString:[@(row) stringValue] forType:CogDNDIndexType]; + return item; } + - (void)tableView:(NSTableView *)tableView - draggingSession:(NSDraggingSession *)session - willBeginAtPoint:(NSPoint)screenPoint - forRowIndexes:(NSIndexSet *)rowIndexes -{ + draggingSession:(NSDraggingSession *)session + willBeginAtPoint:(NSPoint)screenPoint + forRowIndexes:(NSIndexSet *)rowIndexes { DLog(@"Drag session started with indexes: %@", rowIndexes); } -- (NSDragOperation)tableView:(NSTableView*)tableView +- (NSDragOperation)tableView:(NSTableView *)tableView validateDrop:(id )info - proposedRow:(int)row - proposedDropOperation:(NSTableViewDropOperation)dropOperation -{ + proposedRow:(NSInteger)row + proposedDropOperation:(NSTableViewDropOperation)dropOperation { NSDragOperation dragOp = NSDragOperationCopy; if ([info draggingSource] == tableView) @@ -56,29 +54,28 @@ NSString *iTunesDropType = @"CorePasteboardFlavorType 0x6974756E"; } -- (BOOL)tableView:(NSTableView*)tableView +- (BOOL)tableView:(NSTableView *)tableView acceptDrop:(id )info - row:(int)row - dropOperation:(NSTableViewDropOperation)dropOperation -{ + row:(NSInteger)row + dropOperation:(NSTableViewDropOperation)dropOperation { if (row < 0) { row = 0; } - + NSArray *items = info.draggingPasteboard.pasteboardItems; // if drag source is self, it's a move if ([info draggingSource] == tableView || items == nil) { NSMutableIndexSet *indexSet = [NSMutableIndexSet indexSet]; for (NSPasteboardItem *item in items) { - [indexSet addIndex:[[item stringForType:CogPlaylistItemType] intValue]]; + [indexSet addIndex:(NSUInteger) [[item stringForType:CogDNDIndexType] intValue]]; } if ([indexSet count] > 0) { DLog(@"INDEX SET ON DROP: %@", indexSet); NSArray *selected = [[self arrangedObjects] objectsAtIndexes:indexSet]; - [self moveObjectsInArrangedObjectsFromIndexes:indexSet toIndex:row]; - + [self moveObjectsInArrangedObjectsFromIndexes:indexSet toIndex:(unsigned int) row]; + [self setSelectedObjects:selected]; - + DLog(@"ACCEPTING DROP!"); return YES; } @@ -88,26 +85,25 @@ NSString *iTunesDropType = @"CorePasteboardFlavorType 0x6974756E"; } --(void) moveObjectsInArrangedObjectsFromIndexes:(NSIndexSet *)indexSet - toIndex:(unsigned int)insertIndex -{ - NSArray *objects = [self arrangedObjects]; - NSUInteger index = [indexSet lastIndex]; +- (void)moveObjectsInArrangedObjectsFromIndexes:(NSIndexSet *)indexSet + toIndex:(unsigned int)insertIndex { + NSArray *objects = [self arrangedObjects]; + NSUInteger index = [indexSet lastIndex]; - int aboveInsertIndexCount = 0; - id object; - int removeIndex; + NSUInteger aboveInsertIndexCount = 0; + id object; + NSUInteger removeIndex; while (NSNotFound != index) { if (index >= insertIndex) { - removeIndex = (int)(index + aboveInsertIndexCount); + removeIndex = index + aboveInsertIndexCount; aboveInsertIndexCount += 1; } else { - removeIndex = (int)index; + removeIndex = index; insertIndex -= 1; } - object = [objects objectAtIndex:removeIndex]; + object = objects[removeIndex]; [self removeObjectAtArrangedObjectIndex:removeIndex]; [self insertObject:object atArrangedObjectIndex:insertIndex]; diff --git a/Playlist/PlaylistController.h b/Playlist/PlaylistController.h index f8054cf89..9852342a9 100644 --- a/Playlist/PlaylistController.h +++ b/Playlist/PlaylistController.h @@ -15,55 +15,48 @@ @class SpotlightWindowController; @class PlaybackController; -typedef enum { - RepeatNone = 0, - RepeatOne, - RepeatAlbum, - RepeatAll -} RepeatMode; +typedef NS_ENUM(NSInteger, RepeatMode) { + RepeatModeNoRepeat = 0, + RepeatModeRepeatOne, + RepeatModeRepeatAlbum, + RepeatModeRepeatAll +}; -static inline BOOL IsRepeatOneSet() -{ - return [[NSUserDefaults standardUserDefaults] integerForKey:@"repeat"] == RepeatOne; +static inline BOOL IsRepeatOneSet() { + return [[NSUserDefaults standardUserDefaults] integerForKey:@"repeat"] == RepeatModeRepeatOne; } -typedef enum { - ShuffleOff = 0, - ShuffleAlbums, - ShuffleAll -} ShuffleMode; - +typedef enum { ShuffleOff = 0, ShuffleAlbums, ShuffleAll } ShuffleMode; -typedef enum { - URLOriginInternal = 0, - URLOriginExternal, -} URLOrigin; +typedef NS_ENUM(NSInteger, URLOrigin) { + URLOriginInternal = 0, + URLOriginExternal +}; + +@interface PlaylistController : DNDArrayController { + IBOutlet PlaylistLoader *playlistLoader; + IBOutlet SpotlightWindowController *spotlightWindowController; + IBOutlet PlaybackController *playbackController; + + NSMutableArray *shuffleList; + NSMutableArray *queueList; + + NSString *totalTime; + + PlaylistEntry *currentEntry; -@interface PlaylistController : DNDArrayController { - IBOutlet PlaylistLoader *playlistLoader; - IBOutlet SpotlightWindowController *spotlightWindowController; - IBOutlet PlaybackController *playbackController; - - NSMutableArray *shuffleList; - NSMutableArray *queueList; - - NSString *totalTime; - - PlaylistEntry *currentEntry; - NSUndoManager *undoManager; } @property(nonatomic, retain) PlaylistEntry *currentEntry; @property(retain) NSString *totalTime; -//Private Methods +// Private Methods - (void)updateTotalTime; - (void)updatePlaylistIndexes; - (IBAction)stopAfterCurrent:(id)sender; - -//PUBLIC METHODS +// PUBLIC METHODS - (void)setShuffle:(ShuffleMode)s; - (ShuffleMode)shuffle; - (void)setRepeat:(RepeatMode)r; @@ -95,7 +88,7 @@ typedef enum { - (IBAction)searchByArtist:(id)sender; - (IBAction)searchByAlbum:(id)sender; -//FUN PLAYLIST MANAGEMENT STUFF! +// FUN PLAYLIST MANAGEMENT STUFF! - (BOOL)next; - (BOOL)prev; @@ -107,12 +100,15 @@ typedef enum { - (PlaylistEntry *)entryAtIndex:(int)i; // Event inlets: -- (void)willInsertURLs:(NSArray*)urls origin:(URLOrigin)origin; -- (void)didInsertURLs:(NSArray*)urls origin:(URLOrigin)origin; +- (void)willInsertURLs:(NSArray *)urls origin:(URLOrigin)origin; +- (void)didInsertURLs:(NSArray *)urls origin:(URLOrigin)origin; // queue methods - (IBAction)toggleQueued:(id)sender; - (IBAction)emptyQueueList:(id)sender; - (NSMutableArray *)queueList; +- (void)moveObjectsInArrangedObjectsFromIndexes:(NSIndexSet *)indexSet + toIndex:(unsigned int)insertIndex; + @end diff --git a/Playlist/PlaylistController.m b/Playlist/PlaylistController.m index f99e5db2c..15a3dfc3e 100644 --- a/Playlist/PlaylistController.m +++ b/Playlist/PlaylistController.m @@ -7,19 +7,18 @@ // #import "PlaylistController.h" +#import "PlaybackController.h" #import "PlaylistEntry.h" #import "PlaylistLoader.h" -#import "PlaybackController.h" -#import "Shuffle.h" -#import "SpotlightWindowController.h" #import "RepeatTransformers.h" +#import "Shuffle.h" #import "ShuffleTransformers.h" +#import "SpotlightWindowController.h" #import "StatusImageTransformer.h" #import "ToggleQueueTitleTransformer.h" #import "Logging.h" - #define UNDO_STACK_LIMIT 0 @implementation PlaylistController @@ -28,486 +27,446 @@ @synthesize totalTime; + (void)initialize { - NSValueTransformer *repeatNoneTransformer = [[RepeatModeTransformer alloc] initWithMode:RepeatNone]; - [NSValueTransformer setValueTransformer:repeatNoneTransformer - forName:@"RepeatNoneTransformer"]; + NSValueTransformer *repeatNoneTransformer = + [[RepeatModeTransformer alloc] initWithMode:RepeatModeNoRepeat]; + [NSValueTransformer setValueTransformer:repeatNoneTransformer forName:@"RepeatNoneTransformer"]; - NSValueTransformer *repeatOneTransformer = [[RepeatModeTransformer alloc] initWithMode:RepeatOne]; - [NSValueTransformer setValueTransformer:repeatOneTransformer - forName:@"RepeatOneTransformer"]; + NSValueTransformer *repeatOneTransformer = + [[RepeatModeTransformer alloc] initWithMode:RepeatModeRepeatOne]; + [NSValueTransformer setValueTransformer:repeatOneTransformer forName:@"RepeatOneTransformer"]; - NSValueTransformer *repeatAlbumTransformer = [[RepeatModeTransformer alloc] initWithMode:RepeatAlbum]; + NSValueTransformer *repeatAlbumTransformer = + [[RepeatModeTransformer alloc] initWithMode:RepeatModeRepeatAlbum]; [NSValueTransformer setValueTransformer:repeatAlbumTransformer forName:@"RepeatAlbumTransformer"]; - NSValueTransformer *repeatAllTransformer = [[RepeatModeTransformer alloc] initWithMode:RepeatAll]; - [NSValueTransformer setValueTransformer:repeatAllTransformer - forName:@"RepeatAllTransformer"]; + NSValueTransformer *repeatAllTransformer = + [[RepeatModeTransformer alloc] initWithMode:RepeatModeRepeatAll]; + [NSValueTransformer setValueTransformer:repeatAllTransformer forName:@"RepeatAllTransformer"]; - NSValueTransformer *repeatModeImageTransformer = [[RepeatModeImageTransformer alloc] init]; + NSValueTransformer *repeatModeImageTransformer = [[RepeatModeImageTransformer alloc] init]; [NSValueTransformer setValueTransformer:repeatModeImageTransformer forName:@"RepeatModeImageTransformer"]; - - NSValueTransformer *shuffleOffTransformer = [[ShuffleModeTransformer alloc] initWithMode:ShuffleOff]; - [NSValueTransformer setValueTransformer:shuffleOffTransformer - forName:@"ShuffleOffTransformer"]; - - NSValueTransformer *shuffleAlbumsTransformer = [[ShuffleModeTransformer alloc] initWithMode:ShuffleAlbums]; + NSValueTransformer *shuffleOffTransformer = + [[ShuffleModeTransformer alloc] initWithMode:ShuffleOff]; + [NSValueTransformer setValueTransformer:shuffleOffTransformer forName:@"ShuffleOffTransformer"]; + + NSValueTransformer *shuffleAlbumsTransformer = + [[ShuffleModeTransformer alloc] initWithMode:ShuffleAlbums]; [NSValueTransformer setValueTransformer:shuffleAlbumsTransformer forName:@"ShuffleAlbumsTransformer"]; - - NSValueTransformer *shuffleAllTransformer = [[ShuffleModeTransformer alloc] initWithMode:ShuffleAll]; - [NSValueTransformer setValueTransformer:shuffleAllTransformer - forName:@"ShuffleAllTransformer"]; - NSValueTransformer *shuffleImageTransformer = [[ShuffleImageTransformer alloc] init]; + NSValueTransformer *shuffleAllTransformer = + [[ShuffleModeTransformer alloc] initWithMode:ShuffleAll]; + [NSValueTransformer setValueTransformer:shuffleAllTransformer forName:@"ShuffleAllTransformer"]; + + NSValueTransformer *shuffleImageTransformer = [[ShuffleImageTransformer alloc] init]; [NSValueTransformer setValueTransformer:shuffleImageTransformer forName:@"ShuffleImageTransformer"]; - - - - NSValueTransformer *statusImageTransformer = [[StatusImageTransformer alloc] init]; + + NSValueTransformer *statusImageTransformer = [[StatusImageTransformer alloc] init]; [NSValueTransformer setValueTransformer:statusImageTransformer forName:@"StatusImageTransformer"]; - - NSValueTransformer *toggleQueueTitleTransformer = [[ToggleQueueTitleTransformer alloc] init]; + + NSValueTransformer *toggleQueueTitleTransformer = [[ToggleQueueTitleTransformer alloc] init]; [NSValueTransformer setValueTransformer:toggleQueueTitleTransformer forName:@"ToggleQueueTitleTransformer"]; } +- (void)initDefaults { + NSDictionary *defaultsDictionary = @{@"repeat": @(RepeatModeNoRepeat), @"shuffle": @(ShuffleOff)}; -- (void)initDefaults -{ - NSDictionary *defaultsDictionary = [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithInteger:RepeatNone], @"repeat", - [NSNumber numberWithInteger:ShuffleOff], @"shuffle", - nil]; - - [[NSUserDefaults standardUserDefaults] registerDefaults:defaultsDictionary]; + [[NSUserDefaults standardUserDefaults] registerDefaults:defaultsDictionary]; } +- (id)initWithCoder:(NSCoder *)decoder { + self = [super initWithCoder:decoder]; -- (id)initWithCoder:(NSCoder *)decoder -{ - self = [super initWithCoder:decoder]; - - if (self) - { - shuffleList = [[NSMutableArray alloc] init]; - queueList = [[NSMutableArray alloc] init]; + if (self) { + shuffleList = [[NSMutableArray alloc] init]; + queueList = [[NSMutableArray alloc] init]; undoManager = [[NSUndoManager alloc] init]; [undoManager setLevelsOfUndo:UNDO_STACK_LIMIT]; - [self initDefaults]; - } - - return self; -} - - -- (void)awakeFromNib -{ - [super awakeFromNib]; - - [self addObserver:self forKeyPath:@"arrangedObjects" options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) context:nil]; -} - -- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context -{ - if ([keyPath isEqualToString:@"arrangedObjects"]) - { - [self updatePlaylistIndexes]; - [self updateTotalTime]; - } -} - -- (void)updatePlaylistIndexes -{ - int i; - NSArray *arranged = [self arrangedObjects]; - for (i = 0; i < [arranged count]; i++) - { - PlaylistEntry *pe = [arranged objectAtIndex:i]; - if (pe.index != i) //Make sure we don't get into some kind of crazy observing loop... - pe.index = i; - } -} - -- (void)updateTotalTime -{ - double tt = 0; - ldiv_t hoursAndMinutes; - ldiv_t daysAndHours; - - for (PlaylistEntry *pe in [self arrangedObjects]) { - if (!isnan([pe.length doubleValue])) - tt += [pe.length doubleValue]; - } - - long sec = (long)(tt); - hoursAndMinutes = ldiv(sec/60, 60); - - if ( hoursAndMinutes.quot >= 24 ) - { - daysAndHours = ldiv(hoursAndMinutes.quot, 24); - [self setTotalTime:[NSString stringWithFormat:@"%ld days %ld hours %ld minutes %ld seconds", daysAndHours.quot, daysAndHours.rem, hoursAndMinutes.rem, sec%60]]; + [self initDefaults]; } - else - [self setTotalTime:[NSString stringWithFormat:@"%ld hours %ld minutes %ld seconds", hoursAndMinutes.quot, hoursAndMinutes.rem, sec%60]]; + + return self; } -- (void)tableView:(NSTableView *)tableView - didClickTableColumn:(NSTableColumn *)tableColumn -{ - if ([self shuffle] != ShuffleOff) - [self resetShuffleList]; +- (void)awakeFromNib { + [super awakeFromNib]; + + [self addObserver:self + forKeyPath:@"arrangedObjects" + options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) + context:nil]; } -- (NSString *)tableView:(NSTableView *)tv toolTipForCell:(NSCell *)cell rect:(NSRectPointer)rect tableColumn:(NSTableColumn *)tc row:(int)row mouseLocation:(NSPoint)mouseLocation -{ - DLog(@"GETTING STATUS FOR ROW: %i: %@!", row, [[[self arrangedObjects] objectAtIndex:row] statusMessage]); - return [[[self arrangedObjects] objectAtIndex:row] statusMessage]; +- (void)observeValueForKeyPath:(NSString *)keyPath + ofObject:(id)object + change:(NSDictionary *)change + context:(void *)context { + if ([keyPath isEqualToString:@"arrangedObjects"]) { + [self updatePlaylistIndexes]; + [self updateTotalTime]; + } } --(void)moveObjectsInArrangedObjectsFromIndexes:(NSIndexSet*)indexSet - toIndex:(unsigned int)insertIndex -{ - [super moveObjectsInArrangedObjectsFromIndexes:indexSet toIndex:insertIndex]; - - NSUInteger lowerIndex = insertIndex; - NSUInteger index = insertIndex; - - while (NSNotFound != lowerIndex) { - lowerIndex = [indexSet indexLessThanIndex:lowerIndex]; - - if (lowerIndex != NSNotFound) - index = lowerIndex; - } - - [playbackController playlistDidChange:self]; +- (void)updatePlaylistIndexes { + NSArray *arranged = [self arrangedObjects]; + NSUInteger n = [arranged count]; + for (NSUInteger i = 0; i < n; i++) { + PlaylistEntry *pe = arranged[i]; + if (pe.index != i) // Make sure we don't get into some kind of crazy observing loop... + pe.index = (int) i; + } } -- (BOOL)tableView:(NSTableView *)aTableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pboard -{ - [super tableView:aTableView writeRowsWithIndexes:rowIndexes toPasteboard:pboard]; +- (void)updateTotalTime { + double tt = 0; + ldiv_t hoursAndMinutes; + ldiv_t daysAndHours; - NSMutableArray *filenames = [NSMutableArray array]; - NSInteger row; - for (row = [rowIndexes firstIndex]; - row <= [rowIndexes lastIndex]; - row = [rowIndexes indexGreaterThanIndex:row]) - { - PlaylistEntry *song = [[self arrangedObjects] objectAtIndex:row]; - [filenames addObject:[[song path] stringByExpandingTildeInPath]]; - } + for (PlaylistEntry *pe in [self arrangedObjects]) { + if (!isnan([pe.length doubleValue])) tt += [pe.length doubleValue]; + } - [pboard addTypes:[NSArray arrayWithObject:NSFilenamesPboardType] owner:self]; - [pboard setPropertyList:filenames forType:NSFilenamesPboardType]; - - return YES; + long sec = (long) (tt); + hoursAndMinutes = ldiv(sec / 60, 60); + + if (hoursAndMinutes.quot >= 24) { + daysAndHours = ldiv(hoursAndMinutes.quot, 24); + [self setTotalTime:[NSString stringWithFormat:@"%ld days %ld hours %ld minutes %ld seconds", + daysAndHours.quot, daysAndHours.rem, + hoursAndMinutes.rem, sec % 60]]; + } else { + [self setTotalTime:[NSString stringWithFormat:@"%ld hours %ld minutes %ld seconds", + hoursAndMinutes.quot, hoursAndMinutes.rem, + sec % 60]]; + } } -- (BOOL)tableView:(NSTableView*)tv - acceptDrop:(id )info - row:(int)row - dropOperation:(NSTableViewDropOperation)op -{ - //Check if DNDArrayController handles it. - if ([super tableView:tv acceptDrop:info row:row dropOperation:op]) - return YES; - - if (row < 0) - row = 0; - - - // Determine the type of object that was dropped - NSArray *supportedTypes = [NSArray arrayWithObjects:CogUrlsPboardType, NSFilenamesPboardType, iTunesDropType, nil]; - NSPasteboard *pboard = [info draggingPasteboard]; - NSString *bestType = [pboard availableTypeFromArray:supportedTypes]; - - NSMutableArray *acceptedURLs = [[NSMutableArray alloc] init]; - - // Get files from an file drawer drop - if ([bestType isEqualToString:CogUrlsPboardType]) { - NSArray *urls = [NSUnarchiver unarchiveObjectWithData:[[info draggingPasteboard] dataForType:CogUrlsPboardType]]; - DLog(@"URLS: %@", urls); - //[playlistLoader insertURLs: urls atIndex:row sort:YES]; - [acceptedURLs addObjectsFromArray:urls]; - } - - // Get files from a normal file drop (such as from Finder) - if ([bestType isEqualToString:NSFilenamesPboardType]) { - NSMutableArray *urls = [[NSMutableArray alloc] init]; - - for (NSString *file in [[info draggingPasteboard] propertyListForType:NSFilenamesPboardType]) - { - [urls addObject:[NSURL fileURLWithPath:file]]; - } - - //[playlistLoader insertURLs:urls atIndex:row sort:YES]; - [acceptedURLs addObjectsFromArray:urls]; - } - - // Get files from an iTunes drop - if ([bestType isEqualToString:iTunesDropType]) { - NSDictionary *iTunesDict = [pboard propertyListForType:iTunesDropType]; - NSDictionary *tracks = [iTunesDict valueForKey:@"Tracks"]; - - // Convert the iTunes URLs to URLs....MWAHAHAH! - NSMutableArray *urls = [[NSMutableArray alloc] init]; - - for (NSDictionary *trackInfo in [tracks allValues]) { - [urls addObject:[NSURL URLWithString:[trackInfo valueForKey:@"Location"]]]; - } - - //[playlistLoader insertURLs:urls atIndex:row sort:YES]; - [acceptedURLs addObjectsFromArray:urls]; - } - - if ([acceptedURLs count]) - { - [self willInsertURLs:acceptedURLs origin:URLOriginInternal]; - - if (![[self content] count]) { - row = 0; - } - - NSArray* entries = [playlistLoader insertURLs:acceptedURLs atIndex:row sort:YES]; - [self didInsertURLs:entries origin:URLOriginInternal]; - } - - if ([self shuffle] != ShuffleOff) - [self resetShuffleList]; - - return YES; +- (void)tableView:(NSTableView *)tableView didClickTableColumn:(NSTableColumn *)tableColumn { + if ([self shuffle] != ShuffleOff) [self resetShuffleList]; } -- (NSUndoManager *)undoManager -{ - return undoManager; +- (NSString *)tableView:(NSTableView *)tv + toolTipForCell:(NSCell *)cell + rect:(NSRectPointer)rect + tableColumn:(NSTableColumn *)tc + row:(NSInteger)row + mouseLocation:(NSPoint)mouseLocation { + DLog(@"GETTING STATUS FOR ROW: %i: %@!", row, + [[[self arrangedObjects] objectAtIndex:row] statusMessage]); + return [[[self arrangedObjects] objectAtIndex:row] statusMessage]; } -- (NSIndexSet *)disarrangeIndexes:(NSIndexSet *)indexes -{ - if ([[self arrangedObjects] count] <= [indexes lastIndex]) - return indexes; - +- (void)moveObjectsInArrangedObjectsFromIndexes:(NSIndexSet *)indexSet + toIndex:(unsigned int)insertIndex { + [super moveObjectsInArrangedObjectsFromIndexes:indexSet toIndex:insertIndex]; + + [playbackController playlistDidChange:self]; +} + +- (id )tableView:(NSTableView *)tableView + pasteboardWriterForRow:(NSInteger)row { + NSPasteboardItem *item = (NSPasteboardItem *) [super tableView:tableView + pasteboardWriterForRow:row]; + if (!item) { + item = [[NSPasteboardItem alloc] init]; + } + + NSMutableArray *filenames = [NSMutableArray array]; + PlaylistEntry *song = [[self arrangedObjects] objectAtIndex:row]; + [filenames addObject:[[song path] stringByExpandingTildeInPath]]; + + [item setData:[song.URL dataRepresentation] forType:NSPasteboardTypeFileURL]; + + return item; +} + +- (BOOL)tableView:(NSTableView *)tv + acceptDrop:(id )info + row:(NSInteger)row + dropOperation:(NSTableViewDropOperation)op { + // Check if DNDArrayController handles it. + if ([super tableView:tv acceptDrop:info row:row dropOperation:op]) return YES; + + if (row < 0) row = 0; + + // Determine the type of object that was dropped + NSArray *supportedTypes = + @[CogUrlsPboardType, NSPasteboardTypeFileURL, iTunesDropType]; + NSPasteboard *pboard = [info draggingPasteboard]; + NSString *bestType = [pboard availableTypeFromArray:supportedTypes]; + + NSMutableArray *acceptedURLs = [[NSMutableArray alloc] init]; + + // Get files from an file drawer drop + if ([bestType isEqualToString:CogUrlsPboardType]) { + NSError *error; + NSData *data = [pboard dataForType:CogUrlsPboardType]; + NSArray *urls; + if (@available(macOS 11.0, *)) { + urls = [NSKeyedUnarchiver unarchivedArrayOfObjectsOfClass:[NSURL class] + fromData:data + error:&error]; + } else { + NSSet *allowed = [NSSet setWithArray:@[[NSArray class], [NSURL class]]]; + urls = [NSKeyedUnarchiver unarchivedObjectOfClasses:allowed fromData:data error:&error]; + } + if (!urls) { + DLog(@"%@", error); + } else { + DLog(@"URLS: %@", urls); + } + //[playlistLoader insertURLs: urls atIndex:row sort:YES]; + [acceptedURLs addObjectsFromArray:urls]; + } + + // Get files from a normal file drop (such as from Finder) + if ([bestType isEqualToString:NSPasteboardTypeFileURL]) { + NSMutableArray *urls = [[NSMutableArray alloc] init]; + + for (NSString *file in + [[info draggingPasteboard] propertyListForType:NSPasteboardTypeFileURL]) { + [urls addObject:[NSURL fileURLWithPath:file]]; + } + + //[playlistLoader insertURLs:urls atIndex:row sort:YES]; + [acceptedURLs addObjectsFromArray:urls]; + } + + // Get files from an iTunes drop + if ([bestType isEqualToString:iTunesDropType]) { + NSDictionary *iTunesDict = [pboard propertyListForType:iTunesDropType]; + NSDictionary *tracks = [iTunesDict valueForKey:@"Tracks"]; + + // Convert the iTunes URLs to URLs....MWAHAHAH! + NSMutableArray *urls = [[NSMutableArray alloc] init]; + + for (NSDictionary *trackInfo in [tracks allValues]) { + [urls addObject:[NSURL URLWithString:[trackInfo valueForKey:@"Location"]]]; + } + + //[playlistLoader insertURLs:urls atIndex:row sort:YES]; + [acceptedURLs addObjectsFromArray:urls]; + } + + if ([acceptedURLs count]) { + [self willInsertURLs:acceptedURLs origin:URLOriginInternal]; + + if (![[self content] count]) { + row = 0; + } + + NSArray *entries = [playlistLoader insertURLs:acceptedURLs atIndex:row sort:YES]; + [self didInsertURLs:entries origin:URLOriginInternal]; + } + + if ([self shuffle] != ShuffleOff) [self resetShuffleList]; + + return YES; +} + +- (NSUndoManager *)undoManager { + return undoManager; +} + +- (NSIndexSet *)disarrangeIndexes:(NSIndexSet *)indexes { + if ([[self arrangedObjects] count] <= [indexes lastIndex]) return indexes; + NSMutableIndexSet *disarrangedIndexes = [[NSMutableIndexSet alloc] init]; - + NSUInteger index = [indexes firstIndex]; - while (index != NSNotFound) - { - [disarrangedIndexes addIndex:[[self content] indexOfObject:[[self arrangedObjects] objectAtIndex:index]]]; + while (index != NSNotFound) { + [disarrangedIndexes + addIndex:[[self content] indexOfObject:[[self arrangedObjects] objectAtIndex:index]]]; index = [indexes indexGreaterThanIndex:index]; } - + return disarrangedIndexes; } -- (NSArray *)disarrangeObjects:(NSArray *)objects -{ +- (NSArray *)disarrangeObjects:(NSArray *)objects { NSMutableArray *disarrangedObjects = [[NSMutableArray alloc] init]; - - for (PlaylistEntry *pe in [self content]) - { - if ([objects containsObject:pe]) - [disarrangedObjects addObject:pe]; + + for (PlaylistEntry *pe in [self content]) { + if ([objects containsObject:pe]) [disarrangedObjects addObject:pe]; } - + return disarrangedObjects; } -- (NSIndexSet *)rearrangeIndexes:(NSIndexSet *)indexes -{ - if ([[self content] count] <= [indexes lastIndex]) - return indexes; - +- (NSIndexSet *)rearrangeIndexes:(NSIndexSet *)indexes { + if ([[self content] count] <= [indexes lastIndex]) return indexes; + NSMutableIndexSet *rearrangedIndexes = [[NSMutableIndexSet alloc] init]; - + NSUInteger index = [indexes firstIndex]; - while (index != NSNotFound) - { - [rearrangedIndexes addIndex:[[self arrangedObjects] indexOfObject:[[self content] objectAtIndex:index]]]; + while (index != NSNotFound) { + [rearrangedIndexes + addIndex:[[self arrangedObjects] indexOfObject:[[self content] objectAtIndex:index]]]; index = [indexes indexGreaterThanIndex:index]; } - + return rearrangedIndexes; } -- (void)insertObjects:(NSArray *)objects atIndexes:(NSIndexSet *)indexes -{ +- (void)insertObjects:(NSArray *)objects atIndexes:(NSIndexSet *)indexes { [self insertObjects:objects atArrangedObjectIndexes:indexes]; [self rearrangeObjects]; } -- (void)insertObjects:(NSArray *)objects atArrangedObjectIndexes:(NSIndexSet *)indexes -{ - [[[self undoManager] prepareWithInvocationTarget:self] removeObjectsAtIndexes:[self disarrangeIndexes:indexes]]; - NSString *actionName = [NSString stringWithFormat:@"Adding %lu entries", (unsigned long)[objects count]]; +- (void)insertObjects:(NSArray *)objects atArrangedObjectIndexes:(NSIndexSet *)indexes { + [[[self undoManager] prepareWithInvocationTarget:self] + removeObjectsAtIndexes:[self disarrangeIndexes:indexes]]; + NSString *actionName = + [NSString stringWithFormat:@"Adding %lu entries", (unsigned long) [objects count]]; [[self undoManager] setActionName:actionName]; [super insertObjects:objects atArrangedObjectIndexes:indexes]; - if ([self shuffle] != ShuffleOff) - [self resetShuffleList]; + if ([self shuffle] != ShuffleOff) [self resetShuffleList]; } -- (void)removeObjectsAtIndexes:(NSIndexSet *)indexes -{ +- (void)removeObjectsAtIndexes:(NSIndexSet *)indexes { [self removeObjectsAtArrangedObjectIndexes:[self rearrangeIndexes:indexes]]; } -- (void)removeObjectsAtArrangedObjectIndexes:(NSIndexSet *)indexes -{ +- (void)removeObjectsAtArrangedObjectIndexes:(NSIndexSet *)indexes { NSArray *objects = [[self arrangedObjects] objectsAtIndexes:indexes]; - [[[self undoManager] prepareWithInvocationTarget:self] insertObjects:[self disarrangeObjects:objects] atIndexes:[self disarrangeIndexes:indexes]]; - NSString *actionName = [NSString stringWithFormat:@"Removing %lu entries", (unsigned long)[indexes count]]; + [[[self undoManager] prepareWithInvocationTarget:self] + insertObjects:[self disarrangeObjects:objects] + atIndexes:[self disarrangeIndexes:indexes]]; + NSString *actionName = + [NSString stringWithFormat:@"Removing %lu entries", (unsigned long) [indexes count]]; [[self undoManager] setActionName:actionName]; - + DLog(@"Removing indexes: %@", indexes); DLog(@"Current index: %i", currentEntry.index); - + NSMutableIndexSet *unarrangedIndexes = [[NSMutableIndexSet alloc] init]; - for (PlaylistEntry *pe in objects) - { + for (PlaylistEntry *pe in objects) { [unarrangedIndexes addIndex:[pe index]]; } - - if (currentEntry.index >= 0 && [unarrangedIndexes containsIndex:currentEntry.index]) - { + + if (currentEntry.index >= 0 && [unarrangedIndexes containsIndex:currentEntry.index]) { currentEntry.index = -currentEntry.index - 1; DLog(@"Current removed: %i", currentEntry.index); } - - if (currentEntry.index < 0) //Need to update the negative index + + if (currentEntry.index < 0) // Need to update the negative index { int i = -currentEntry.index - 1; DLog(@"I is %i", i); int j; - for (j = i - 1; j >= 0; j--) - { + for (j = i - 1; j >= 0; j--) { if ([unarrangedIndexes containsIndex:j]) { DLog(@"Removing 1"); i--; } } currentEntry.index = -i - 1; - } - + [super removeObjectsAtArrangedObjectIndexes:indexes]; - if ([self shuffle] != ShuffleOff) - [self resetShuffleList]; + if ([self shuffle] != ShuffleOff) [self resetShuffleList]; [playbackController playlistDidChange:self]; } -- (void)setSortDescriptors:(NSArray *)sortDescriptors -{ - DLog(@"Current: %@, setting: %@", [self sortDescriptors], sortDescriptors); +- (void)setSortDescriptors:(NSArray *)sortDescriptors { + DLog(@"Current: %@, setting: %@", [self sortDescriptors], sortDescriptors); - //Cheap hack so the index column isn't sorted - if (([sortDescriptors count] != 0) && [[[sortDescriptors objectAtIndex:0] key] caseInsensitiveCompare:@"index"] == NSOrderedSame) - { - //Remove the sort descriptors - [super setSortDescriptors:[NSArray array]]; - [self rearrangeObjects]; - - return; - } + // Cheap hack so the index column isn't sorted + if (([sortDescriptors count] != 0) && [[sortDescriptors[0] key] + caseInsensitiveCompare:@"index"] == NSOrderedSame) { + // Remove the sort descriptors + [super setSortDescriptors:[NSArray array]]; + [self rearrangeObjects]; - [super setSortDescriptors:sortDescriptors]; - [self rearrangeObjects]; + return; + } - [playbackController playlistDidChange:self]; + [super setSortDescriptors:sortDescriptors]; + [self rearrangeObjects]; + + [playbackController playlistDidChange:self]; } - -- (IBAction)randomizeList:(id)sender -{ - [self setSortDescriptors:[NSArray array]]; + +- (IBAction)randomizeList:(id)sender { + [self setSortDescriptors:[NSArray array]]; NSArray *unrandomized = [self content]; [[[self undoManager] prepareWithInvocationTarget:self] unrandomizeList:unrandomized]; [self setContent:[Shuffle shuffleList:[self content]]]; - if ([self shuffle] != ShuffleOff) - [self resetShuffleList]; + if ([self shuffle] != ShuffleOff) [self resetShuffleList]; [[self undoManager] setActionName:@"Playlist Randomization"]; } -- (void)unrandomizeList:(NSArray *)entries -{ +- (void)unrandomizeList:(NSArray *)entries { [[[self undoManager] prepareWithInvocationTarget:self] randomizeList:self]; [self setContent:entries]; } -- (IBAction)toggleShuffle:(id)sender -{ - ShuffleMode shuffle = [self shuffle]; - - if (shuffle == ShuffleOff) { - [self setShuffle: ShuffleAlbums]; - } - else if (shuffle == ShuffleAlbums) { - [self setShuffle: ShuffleAll]; - } - else if (shuffle == ShuffleAll) { - [self setShuffle: ShuffleOff]; - } +- (IBAction)toggleShuffle:(id)sender { + ShuffleMode shuffle = [self shuffle]; + + if (shuffle == ShuffleOff) { + [self setShuffle:ShuffleAlbums]; + } else if (shuffle == ShuffleAlbums) { + [self setShuffle:ShuffleAll]; + } else if (shuffle == ShuffleAll) { + [self setShuffle:ShuffleOff]; + } } -- (IBAction)toggleRepeat:(id)sender -{ - RepeatMode repeat = [self repeat]; - - if (repeat == RepeatNone) { - [self setRepeat: RepeatOne]; - } - else if (repeat == RepeatOne) { - [self setRepeat: RepeatAlbum]; - } - else if (repeat == RepeatAlbum) { - [self setRepeat: RepeatAll]; - } - else if (repeat == RepeatAll) { - [self setRepeat: RepeatNone]; - } +- (IBAction)toggleRepeat:(id)sender { + RepeatMode repeat = [self repeat]; + + if (repeat == RepeatModeNoRepeat) { + [self setRepeat:RepeatModeRepeatOne]; + } else if (repeat == RepeatModeRepeatOne) { + [self setRepeat:RepeatModeRepeatAlbum]; + } else if (repeat == RepeatModeRepeatAlbum) { + [self setRepeat:RepeatModeRepeatAll]; + } else if (repeat == RepeatModeRepeatAll) { + [self setRepeat:RepeatModeNoRepeat]; + } } -- (PlaylistEntry *)entryAtIndex:(int)i -{ - RepeatMode repeat = [self repeat]; - - if (i < 0 || i >= [[self arrangedObjects] count] ) { - if ( repeat != RepeatAll ) - return nil; - - while ( i < 0 ) - i += [[self arrangedObjects] count]; - if ( i >= [[self arrangedObjects] count]) - i %= [[self arrangedObjects] count]; - } - - return [[self arrangedObjects] objectAtIndex:i]; +- (PlaylistEntry *)entryAtIndex:(int)i { + RepeatMode repeat = [self repeat]; + + if (i < 0 || i >= [[self arrangedObjects] count]) { + if (repeat != RepeatModeRepeatAll) return nil; + + while (i < 0) i += [[self arrangedObjects] count]; + if (i >= [[self arrangedObjects] count]) i %= [[self arrangedObjects] count]; + } + + return [[self arrangedObjects] objectAtIndex:i]; } - (void)remove:(id)sender { // It's a kind of magic. // Plain old NSArrayController's remove: isn't working properly for some reason. - // The method is definitely called but (overridden) removeObjectsAtArrangedObjectIndexes: isn't called - // and no entries are removed. - // Putting explicit call to removeObjectsAtArrangedObjectIndexes: here for now. + // The method is definitely called but (overridden) removeObjectsAtArrangedObjectIndexes: isn't + // called and no entries are removed. Putting explicit call to + // removeObjectsAtArrangedObjectIndexes: here for now. // TODO: figure it out NSIndexSet *selected = [self selectionIndexes]; - if ([selected count] > 0) - { + if ([selected count] > 0) { [self removeObjectsAtArrangedObjectIndexes:selected]; } } @@ -515,21 +474,18 @@ - (IBAction)removeDuplicates:(id)sender { NSMutableArray *originals = [[NSMutableArray alloc] init]; NSMutableArray *duplicates = [[NSMutableArray alloc] init]; - - for (PlaylistEntry *pe in [self content]) - { + + for (PlaylistEntry *pe in [self content]) { if ([originals containsObject:[pe URL]]) [duplicates addObject:pe]; else [originals addObject:[pe URL]]; } - - if ([duplicates count] > 0) - { - NSArray * arrangedContent = [self arrangedObjects]; - NSMutableIndexSet * duplicatesIndex = [[NSMutableIndexSet alloc] init]; - for (PlaylistEntry *pe in duplicates) - { + + if ([duplicates count] > 0) { + NSArray *arrangedContent = [self arrangedObjects]; + NSMutableIndexSet *duplicatesIndex = [[NSMutableIndexSet alloc] init]; + for (PlaylistEntry *pe in duplicates) { [duplicatesIndex addIndex:[arrangedContent indexOfObject:pe]]; } [self removeObjectsAtArrangedObjectIndexes:duplicatesIndex]; @@ -538,592 +494,509 @@ - (IBAction)removeDeadItems:(id)sender { NSMutableArray *deadItems = [[NSMutableArray alloc] init]; - - for (PlaylistEntry *pe in [self content]) - { + + for (PlaylistEntry *pe in [self content]) { NSURL *url = [pe URL]; if ([url isFileURL]) if (![[NSFileManager defaultManager] fileExistsAtPath:[url path]]) [deadItems addObject:pe]; } - - if ([deadItems count] > 0) - { - NSArray * arrangedContent = [self arrangedObjects]; - NSMutableIndexSet * deadItemsIndex = [[NSMutableIndexSet alloc] init]; - for (PlaylistEntry *pe in deadItems) - { + + if ([deadItems count] > 0) { + NSArray *arrangedContent = [self arrangedObjects]; + NSMutableIndexSet *deadItemsIndex = [[NSMutableIndexSet alloc] init]; + for (PlaylistEntry *pe in deadItems) { [deadItemsIndex addIndex:[arrangedContent indexOfObject:pe]]; } [self removeObjectsAtArrangedObjectIndexes:deadItemsIndex]; } } -- (PlaylistEntry *)shuffledEntryAtIndex:(int)i -{ - RepeatMode repeat = [self repeat]; - - while (i < 0) - { - if (repeat == RepeatAll) - { - [self addShuffledListToFront]; - //change i appropriately - i += [[self arrangedObjects] count]; - } - else - { - return nil; - } - } - while (i >= [shuffleList count]) - { - if (repeat == RepeatAll) - { - [self addShuffledListToBack]; - } - else - { - return nil; - } - } - - return [shuffleList objectAtIndex:i]; +- (PlaylistEntry *)shuffledEntryAtIndex:(int)i { + RepeatMode repeat = [self repeat]; + + while (i < 0) { + if (repeat == RepeatModeRepeatAll) { + [self addShuffledListToFront]; + // change i appropriately + i += [[self arrangedObjects] count]; + } else { + return nil; + } + } + while (i >= [shuffleList count]) { + if (repeat == RepeatModeRepeatAll) { + [self addShuffledListToBack]; + } else { + return nil; + } + } + + return shuffleList[i]; } -- (PlaylistEntry *)getNextEntry:(PlaylistEntry *)pe -{ +- (PlaylistEntry *)getNextEntry:(PlaylistEntry *)pe { return [self getNextEntry:pe ignoreRepeatOne:NO]; } -- (PlaylistEntry *)getNextEntry:(PlaylistEntry *)pe ignoreRepeatOne:(BOOL)ignoreRepeatOne -{ - if (!ignoreRepeatOne && [self repeat] == RepeatOne) - { +- (PlaylistEntry *)getNextEntry:(PlaylistEntry *)pe ignoreRepeatOne:(BOOL)ignoreRepeatOne { + if (!ignoreRepeatOne && [self repeat] == RepeatModeRepeatOne) { return pe; } - - if ([queueList count] > 0) - { - - pe = [queueList objectAtIndex:0]; - [queueList removeObjectAtIndex:0]; - pe.queued = NO; - [pe setQueuePosition:-1]; - - int i; - for (i = 0; i < [queueList count]; i++) - { - PlaylistEntry *queueItem = [queueList objectAtIndex:i]; - [queueItem setQueuePosition: i]; - } - - return pe; - } - - if ([self shuffle] != ShuffleOff) - { - return [self shuffledEntryAtIndex:(pe.shuffleIndex + 1)]; - } - else - { - int i; - if (pe.index < 0) //Was a current entry, now removed. - { - i = -pe.index - 1; - } - else - { - i = pe.index + 1; - } - - if ([self repeat] == RepeatAlbum) - { - PlaylistEntry *next = [self entryAtIndex:i]; - - if ((i > [[self arrangedObjects] count]-1) || ([[next album] caseInsensitiveCompare:[pe album]]) || ([next album] == nil)) - { - NSArray *filtered = [self filterPlaylistOnAlbum:[pe album]]; - if ([pe album] == nil) - i--; - else - i = [(PlaylistEntry *)[filtered objectAtIndex:0] index]; - } - - } - return [self entryAtIndex:i]; - } + if ([queueList count] > 0) { + pe = queueList[0]; + [queueList removeObjectAtIndex:0]; + pe.queued = NO; + [pe setQueuePosition:-1]; + + int i; + for (i = 0; i < [queueList count]; i++) { + PlaylistEntry *queueItem = queueList[i]; + [queueItem setQueuePosition:i]; + } + + return pe; + } + + if ([self shuffle] != ShuffleOff) { + return [self shuffledEntryAtIndex:(pe.shuffleIndex + 1)]; + } else { + int i; + if (pe.index < 0) // Was a current entry, now removed. + { + i = -pe.index - 1; + } else { + i = pe.index + 1; + } + + if ([self repeat] == RepeatModeRepeatAlbum) { + PlaylistEntry *next = [self entryAtIndex:i]; + + if ((i > [[self arrangedObjects] count] - 1) || + ([[next album] caseInsensitiveCompare:[pe album]]) || ([next album] == nil)) { + NSArray *filtered = [self filterPlaylistOnAlbum:[pe album]]; + if ([pe album] == nil) + i--; + else + i = [(PlaylistEntry *) filtered[0] index]; + } + } + + return [self entryAtIndex:i]; + } } -- (NSArray *)filterPlaylistOnAlbum:(NSString *)album -{ - NSPredicate *predicate; - if ([album length] > 0) - predicate = [NSPredicate predicateWithFormat:@"album like %@", - album]; - else - predicate = [NSPredicate predicateWithFormat:@"album == nil"]; - return [[self arrangedObjects] filteredArrayUsingPredicate:predicate]; +- (NSArray *)filterPlaylistOnAlbum:(NSString *)album { + NSPredicate *predicate; + if ([album length] > 0) + predicate = [NSPredicate predicateWithFormat:@"album like %@", album]; + else + predicate = [NSPredicate predicateWithFormat:@"album == nil"]; + return [[self arrangedObjects] filteredArrayUsingPredicate:predicate]; } -- (PlaylistEntry *)getPrevEntry:(PlaylistEntry *)pe -{ +- (PlaylistEntry *)getPrevEntry:(PlaylistEntry *)pe { return [self getPrevEntry:pe ignoreRepeatOne:NO]; } -- (PlaylistEntry *)getPrevEntry:(PlaylistEntry *)pe ignoreRepeatOne:(BOOL)ignoreRepeatOne -{ - if (!ignoreRepeatOne && [self repeat] == RepeatOne) - { - return pe; - } - - if ([self shuffle] != ShuffleOff) - { - return [self shuffledEntryAtIndex:(pe.shuffleIndex - 1)]; - } - else - { - int i; - if (pe.index < 0) //Was a current entry, now removed. - { - i = -pe.index - 2; - } - else - { - i = pe.index - 1; - } - - return [self entryAtIndex:i]; - } +- (PlaylistEntry *)getPrevEntry:(PlaylistEntry *)pe ignoreRepeatOne:(BOOL)ignoreRepeatOne { + if (!ignoreRepeatOne && [self repeat] == RepeatModeRepeatOne) { + return pe; + } + + if ([self shuffle] != ShuffleOff) { + return [self shuffledEntryAtIndex:(pe.shuffleIndex - 1)]; + } else { + int i; + if (pe.index < 0) // Was a current entry, now removed. + { + i = -pe.index - 2; + } else { + i = pe.index - 1; + } + + return [self entryAtIndex:i]; + } } -- (BOOL)next -{ - PlaylistEntry *pe; - - pe = [self getNextEntry:[self currentEntry] ignoreRepeatOne:YES]; - - if (pe == nil) - return NO; - - [self setCurrentEntry:pe]; - - return YES; +- (BOOL)next { + PlaylistEntry *pe; + + pe = [self getNextEntry:[self currentEntry] ignoreRepeatOne:YES]; + + if (pe == nil) return NO; + + [self setCurrentEntry:pe]; + + return YES; } -- (BOOL)prev -{ - PlaylistEntry *pe; - +- (BOOL)prev { + PlaylistEntry *pe; + pe = [self getPrevEntry:[self currentEntry] ignoreRepeatOne:YES]; - if (pe == nil) - return NO; - - [self setCurrentEntry:pe]; - - return YES; + if (pe == nil) return NO; + + [self setCurrentEntry:pe]; + + return YES; } -- (NSArray *)shuffleAlbums -{ - NSArray * newList = [self arrangedObjects]; - NSMutableArray * temp = [[NSMutableArray alloc] init]; - NSMutableArray * albums = [[NSMutableArray alloc] init]; - NSSortDescriptor * sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"track" ascending:YES]; - for (unsigned long i = 0, j = [newList count]; i < j; ++i) { - PlaylistEntry * pe = [newList objectAtIndex:i]; - NSString * album = [pe album]; - if (!album) - album = @""; - if ([albums containsObject:album]) continue; - [albums addObject:album]; - NSArray * albumContent = [self filterPlaylistOnAlbum:album]; - NSArray * sortedContent = [albumContent sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]]; - [temp addObject:[sortedContent objectAtIndex:0]]; - } - NSArray * tempList = [Shuffle shuffleList:temp]; - temp = [[NSMutableArray alloc] init]; - for (unsigned long i = 0, j = [tempList count]; i < j; ++i) { - PlaylistEntry * pe = [tempList objectAtIndex:i]; - NSString * album = [pe album]; - NSArray * albumContent = [self filterPlaylistOnAlbum:album]; - NSArray * sortedContent = [albumContent sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]]; - [temp addObjectsFromArray:sortedContent]; - } - return temp; +- (NSArray *)shuffleAlbums { + NSArray *newList = [self arrangedObjects]; + NSMutableArray *temp = [[NSMutableArray alloc] init]; + NSMutableArray *albums = [[NSMutableArray alloc] init]; + NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"track" + ascending:YES]; + for (unsigned long i = 0, j = [newList count]; i < j; ++i) { + PlaylistEntry *pe = newList[i]; + NSString *album = [pe album]; + if (!album) album = @""; + if ([albums containsObject:album]) continue; + [albums addObject:album]; + NSArray *albumContent = [self filterPlaylistOnAlbum:album]; + NSArray *sortedContent = + [albumContent sortedArrayUsingDescriptors:@[sortDescriptor]]; + [temp addObject:sortedContent[0]]; + } + NSArray *tempList = [Shuffle shuffleList:temp]; + temp = [[NSMutableArray alloc] init]; + for (unsigned long i = 0, j = [tempList count]; i < j; ++i) { + PlaylistEntry *pe = tempList[i]; + NSString *album = [pe album]; + NSArray *albumContent = [self filterPlaylistOnAlbum:album]; + NSArray *sortedContent = + [albumContent sortedArrayUsingDescriptors:@[sortDescriptor]]; + [temp addObjectsFromArray:sortedContent]; + } + return temp; } -- (void)addShuffledListToFront -{ - NSArray *newList; - NSIndexSet *indexSet; - - if ([self shuffle] == ShuffleAlbums) { - newList = [self shuffleAlbums]; - } - else { - newList = [Shuffle shuffleList:[self arrangedObjects]]; - } - - indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [newList count])]; - - [shuffleList insertObjects:newList atIndexes:indexSet]; - - int i; - for (i = 0; i < [shuffleList count]; i++) - { - [[shuffleList objectAtIndex:i] setShuffleIndex:i]; - } +- (void)addShuffledListToFront { + NSArray *newList; + NSIndexSet *indexSet; + + if ([self shuffle] == ShuffleAlbums) { + newList = [self shuffleAlbums]; + } else { + newList = [Shuffle shuffleList:[self arrangedObjects]]; + } + + indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [newList count])]; + + [shuffleList insertObjects:newList atIndexes:indexSet]; + + int i; + for (i = 0; i < [shuffleList count]; i++) { + [shuffleList[i] setShuffleIndex:i]; + } } -- (void)addShuffledListToBack -{ - NSArray *newList; - NSIndexSet *indexSet; - - if ([self shuffle] == ShuffleAlbums) { - newList = [self shuffleAlbums]; - } - else { - newList = [Shuffle shuffleList:[self arrangedObjects]]; - } - - indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange([shuffleList count], [newList count])]; - - [shuffleList insertObjects:newList atIndexes:indexSet]; - - unsigned long i; - for (i = ([shuffleList count] - [newList count]); i < [shuffleList count]; i++) - { - [[shuffleList objectAtIndex:i] setShuffleIndex:(int)i]; - } +- (void)addShuffledListToBack { + NSArray *newList; + NSIndexSet *indexSet; + + if ([self shuffle] == ShuffleAlbums) { + newList = [self shuffleAlbums]; + } else { + newList = [Shuffle shuffleList:[self arrangedObjects]]; + } + + indexSet = + [NSIndexSet indexSetWithIndexesInRange:NSMakeRange([shuffleList count], [newList count])]; + + [shuffleList insertObjects:newList atIndexes:indexSet]; + + unsigned long i; + for (i = ([shuffleList count] - [newList count]); i < [shuffleList count]; i++) { + [shuffleList[i] setShuffleIndex:(int) i]; + } } -- (void)resetShuffleList -{ - [shuffleList removeAllObjects]; +- (void)resetShuffleList { + [shuffleList removeAllObjects]; - [self addShuffledListToFront]; + [self addShuffledListToFront]; - if (currentEntry && currentEntry.index >= 0) - { + if (currentEntry && currentEntry.index >= 0) { if ([self shuffle] == ShuffleAlbums) { - NSString * currentAlbum = currentEntry.album; - if (!currentAlbum) - currentAlbum = @""; - - NSArray * wholeAlbum = [self filterPlaylistOnAlbum:currentAlbum]; - + NSString *currentAlbum = currentEntry.album; + if (!currentAlbum) currentAlbum = @""; + + NSArray *wholeAlbum = [self filterPlaylistOnAlbum:currentAlbum]; + // First prune the shuffle list of the currently playing album long i, j; for (i = 0; i < [shuffleList count];) { - if ([wholeAlbum containsObject:[shuffleList objectAtIndex:i]]) { + if ([wholeAlbum containsObject:shuffleList[i]]) { [shuffleList removeObjectAtIndex:i]; - } - else { + } else { ++i; } } - + // Then insert the playing album at the start - NSIndexSet * indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [wholeAlbum count])]; - + NSIndexSet *indexSet = + [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [wholeAlbum count])]; + [shuffleList insertObjects:wholeAlbum atIndexes:indexSet]; // Oops, gotta reset the shuffle indexes for (i = 0, j = [shuffleList count]; i < j; ++i) { - [[shuffleList objectAtIndex:i] setShuffleIndex:(int)i]; + [shuffleList[i] setShuffleIndex:(int) i]; } - } - else { + } else { [shuffleList insertObject:currentEntry atIndex:0]; [currentEntry setShuffleIndex:0]; - //Need to rejigger so the current entry is at the start now... + // Need to rejigger so the current entry is at the start now... long i, j; BOOL found = NO; - for (i = 1, j = [shuffleList count]; i < j && !found; i++) - { - if ([shuffleList objectAtIndex:i] == currentEntry) - { + for (i = 1, j = [shuffleList count]; i < j && !found; i++) { + if (shuffleList[i] == currentEntry) { found = YES; [shuffleList removeObjectAtIndex:i]; - } - else { - [[shuffleList objectAtIndex:i] setShuffleIndex: (int)i]; + } else { + [shuffleList[i] setShuffleIndex:(int) i]; } } } - } + } } -- (void)setCurrentEntry:(PlaylistEntry *)pe -{ - currentEntry.current = NO; - currentEntry.stopAfter = NO; - - pe.current = YES; - - if (pe != nil) - [self.tableView scrollRowToVisible:pe.index]; - - currentEntry = pe; +- (void)setCurrentEntry:(PlaylistEntry *)pe { + currentEntry.current = NO; + currentEntry.stopAfter = NO; + + pe.current = YES; + + if (pe != nil) [self.tableView scrollRowToVisible:pe.index]; + + currentEntry = pe; } -- (void)setShuffle:(ShuffleMode)s -{ - [[NSUserDefaults standardUserDefaults] setInteger:s forKey:@"shuffle"]; - if (s != ShuffleOff) - [self resetShuffleList]; - - [playbackController playlistDidChange:self]; -} -- (ShuffleMode)shuffle -{ - return (ShuffleMode) [[NSUserDefaults standardUserDefaults] integerForKey:@"shuffle"]; -} -- (void)setRepeat:(RepeatMode)r -{ - [[NSUserDefaults standardUserDefaults] setInteger:r forKey:@"repeat"]; - [playbackController playlistDidChange:self]; -} -- (RepeatMode)repeat -{ - return (RepeatMode) [[NSUserDefaults standardUserDefaults] integerForKey:@"repeat"]; +- (void)setShuffle:(ShuffleMode)s { + [[NSUserDefaults standardUserDefaults] setInteger:s forKey:@"shuffle"]; + if (s != ShuffleOff) [self resetShuffleList]; + + [playbackController playlistDidChange:self]; } -- (IBAction)clear:(id)sender -{ - [self setFilterPredicate:nil]; - - [self removeObjectsAtArrangedObjectIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [[self arrangedObjects] count])]]; +- (ShuffleMode)shuffle { + return (ShuffleMode) [[NSUserDefaults standardUserDefaults] integerForKey:@"shuffle"]; } -- (IBAction)clearFilterPredicate:(id)sender -{ - [self setFilterPredicate:nil]; +- (void)setRepeat:(RepeatMode)r { + [[NSUserDefaults standardUserDefaults] setInteger:r forKey:@"repeat"]; + [playbackController playlistDidChange:self]; } -- (void)setFilterPredicate:(NSPredicate *)filterPredicate -{ - [super setFilterPredicate:filterPredicate]; +- (RepeatMode)repeat { + return (RepeatMode) [[NSUserDefaults standardUserDefaults] integerForKey:@"repeat"]; } -- (IBAction)showEntryInFinder:(id)sender -{ - NSWorkspace* ws = [NSWorkspace sharedWorkspace]; - - NSURL *url = [[[self selectedObjects] objectAtIndex:0] URL]; - if ([url isFileURL]) - [ws selectFile:[url path] inFileViewerRootedAtPath:[url path]]; +- (IBAction)clear:(id)sender { + [self setFilterPredicate:nil]; + + [self + removeObjectsAtArrangedObjectIndexes: + [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [[self arrangedObjects] count])]]; } + +- (IBAction)clearFilterPredicate:(id)sender { + [self setFilterPredicate:nil]; +} + +- (void)setFilterPredicate:(NSPredicate *)filterPredicate { + [super setFilterPredicate:filterPredicate]; +} + +- (IBAction)showEntryInFinder:(id)sender { + NSWorkspace *ws = [NSWorkspace sharedWorkspace]; + + NSURL *url = [[self selectedObjects][0] URL]; + if ([url isFileURL]) [ws selectFile:[url path] inFileViewerRootedAtPath:[url path]]; +} + /* - (IBAction)showTagEditor:(id)sender { // call the editor & pass the url - if ([self selectionIndex] < 0) - return; - - NSURL *url = [[[self selectedObjects] objectAtIndex:0] URL]; - if ([url isFileURL]) - [TagEditorController openTagEditor:url sender:sender]; - + if ([self selectionIndex] < 0) + return; + + NSURL *url = [[[self selectedObjects] objectAtIndex:0] URL]; + if ([url isFileURL]) + [TagEditorController openTagEditor:url sender:sender]; + } */ -- (IBAction)searchByArtist:(id)sender; -{ +- (IBAction)searchByArtist:(id)sender; { PlaylistEntry *entry = [[self arrangedObjects] objectAtIndex:[self selectionIndex]]; [spotlightWindowController searchForArtist:[entry artist]]; } -- (IBAction)searchByAlbum:(id)sender; -{ + +- (IBAction)searchByAlbum:(id)sender; { PlaylistEntry *entry = [[self arrangedObjects] objectAtIndex:[self selectionIndex]]; [spotlightWindowController searchForAlbum:[entry album]]; } -- (NSMutableArray *)queueList -{ - return queueList; +- (NSMutableArray *)queueList { + return queueList; } -- (IBAction)emptyQueueList:(id)sender -{ - for (PlaylistEntry *queueItem in queueList) - { - queueItem.queued = NO; - [queueItem setQueuePosition:-1]; - } +- (IBAction)emptyQueueList:(id)sender { + for (PlaylistEntry *queueItem in queueList) { + queueItem.queued = NO; + [queueItem setQueuePosition:-1]; + } - [queueList removeAllObjects]; + [queueList removeAllObjects]; } +- (IBAction)toggleQueued:(id)sender { + for (PlaylistEntry *queueItem in [self selectedObjects]) { + if (queueItem.queued) { + queueItem.queued = NO; + queueItem.queuePosition = -1; -- (IBAction)toggleQueued:(id)sender -{ - for (PlaylistEntry *queueItem in [self selectedObjects]) - { - if (queueItem.queued) - { - queueItem.queued = NO; - queueItem.queuePosition = -1; + [queueList removeObject:queueItem]; + } else { + queueItem.queued = YES; + queueItem.queuePosition = (int) [queueList count]; - [queueList removeObject:queueItem]; - } - else - { - queueItem.queued = YES; - queueItem.queuePosition = (int) [queueList count]; - - [queueList addObject:queueItem]; - } - - DLog(@"TOGGLE QUEUED: %i", queueItem.queued); - } + [queueList addObject:queueItem]; + } - int i = 0; - for (PlaylistEntry *cur in queueList) - { - cur.queuePosition = i++; - } + DLog(@"TOGGLE QUEUED: %i", queueItem.queued); + } + + int i = 0; + for (PlaylistEntry *cur in queueList) { + cur.queuePosition = i++; + } } -- (IBAction)removeFromQueue:(id)sender -{ - for (PlaylistEntry *queueItem in [self selectedObjects]) - { +- (IBAction)removeFromQueue:(id)sender { + for (PlaylistEntry *queueItem in [self selectedObjects]) { queueItem.queued = NO; queueItem.queuePosition = -1; - + [queueList removeObject:queueItem]; } - + int i = 0; - for (PlaylistEntry *cur in queueList) - { + for (PlaylistEntry *cur in queueList) { cur.queuePosition = i++; } } -- (IBAction)addToQueue:(id)sender -{ - for (PlaylistEntry *queueItem in [self selectedObjects]) - { +- (IBAction)addToQueue:(id)sender { + for (PlaylistEntry *queueItem in [self selectedObjects]) { queueItem.queued = YES; queueItem.queuePosition = (int) [queueList count]; - + [queueList addObject:queueItem]; } - + int i = 0; - for (PlaylistEntry *cur in queueList) - { + for (PlaylistEntry *cur in queueList) { cur.queuePosition = i++; } } -- (IBAction)stopAfterCurrent:(id)sender -{ - currentEntry.stopAfter = !currentEntry.stopAfter; +- (IBAction)stopAfterCurrent:(id)sender { + currentEntry.stopAfter = !currentEntry.stopAfter; } --(BOOL)validateMenuItem:(NSMenuItem*)menuItem -{ - SEL action = [menuItem action]; - - if (action == @selector(removeFromQueue:)) - { - for (PlaylistEntry *q in [self selectedObjects]) - if (q.queuePosition >= 0) - return YES; +- (BOOL)validateMenuItem:(NSMenuItem *)menuItem { + SEL action = [menuItem action]; - return NO; - } + if (action == @selector(removeFromQueue:)) { + for (PlaylistEntry *q in [self selectedObjects]) + if (q.queuePosition >= 0) return YES; - if (action == @selector(emptyQueueList:) && ([queueList count] < 1)) - return NO; - - if (action == @selector(stopAfterCurrent:) && currentEntry.stopAfter) - return NO; - - // if nothing is selected, gray out these - if ([[self selectedObjects] count] < 1) - { - - if (action == @selector(remove:)) - return NO; - - if (action == @selector(addToQueue:)) - return NO; + return NO; + } - if (action == @selector(searchByArtist:)) - return NO; + if (action == @selector(emptyQueueList:) && ([queueList count] < 1)) return NO; - if (action == @selector(searchByAlbum:)) - return NO; - } - - return YES; + if (action == @selector(stopAfterCurrent:) && currentEntry.stopAfter) return NO; + + // if nothing is selected, gray out these + if ([[self selectedObjects] count] < 1) { + if (action == @selector(remove:)) return NO; + + if (action == @selector(addToQueue:)) return NO; + + if (action == @selector(searchByArtist:)) return NO; + + if (action == @selector(searchByAlbum:)) return NO; + } + + return YES; } // Event inlets: -- (void)willInsertURLs:(NSArray*)urls origin:(URLOrigin)origin -{ - if (![urls count]) - return; +- (void)willInsertURLs:(NSArray *)urls origin:(URLOrigin)origin { + if (![urls count]) return; - CGEventRef event = CGEventCreate(NULL /*default event source*/); - CGEventFlags mods = CGEventGetFlags(event); - CFRelease(event); - - BOOL modifierPressed = ((mods & kCGEventFlagMaskCommand)!=0)&((mods & kCGEventFlagMaskControl)!=0); - modifierPressed |= ((mods & kCGEventFlagMaskShift)!=0); + CGEventRef event = CGEventCreate(NULL /*default event source*/); + CGEventFlags mods = CGEventGetFlags(event); + CFRelease(event); - NSString *behavior = [[NSUserDefaults standardUserDefaults] valueForKey:@"openingFilesBehavior"]; - if (modifierPressed) { - behavior = [[NSUserDefaults standardUserDefaults] valueForKey:@"openingFilesAlteredBehavior"]; - } - - - BOOL shouldClear = modifierPressed; // By default, internal sources should not clear the playlist - if (origin == URLOriginExternal) { // For external insertions, we look at the preference - //possible settings are "clearAndPlay", "enqueue", "enqueueAndPlay" - shouldClear = [behavior isEqualToString:@"clearAndPlay"]; - } - - if (shouldClear) { - [self clear:self]; - } + BOOL modifierPressed = + ((mods & kCGEventFlagMaskCommand) != 0) & ((mods & kCGEventFlagMaskControl) != 0); + modifierPressed |= ((mods & kCGEventFlagMaskShift) != 0); + + NSString *behavior = + [[NSUserDefaults standardUserDefaults] valueForKey:@"openingFilesBehavior"]; + if (modifierPressed) { + behavior = + [[NSUserDefaults standardUserDefaults] valueForKey:@"openingFilesAlteredBehavior"]; + } + + BOOL shouldClear = + modifierPressed; // By default, internal sources should not clear the playlist + if (origin == URLOriginExternal) { // For external insertions, we look at the preference + // possible settings are "clearAndPlay", "enqueue", "enqueueAndPlay" + shouldClear = [behavior isEqualToString:@"clearAndPlay"]; + } + + if (shouldClear) { + [self clear:self]; + } } -- (void)didInsertURLs:(NSArray*)urls origin:(URLOrigin)origin -{ - if (![urls count]) - return; - - CGEventRef event = CGEventCreate(NULL); - CGEventFlags mods = CGEventGetFlags(event); - CFRelease(event); - - BOOL modifierPressed = ((mods & kCGEventFlagMaskCommand)!=0)&((mods & kCGEventFlagMaskControl)!=0); - modifierPressed |= ((mods & kCGEventFlagMaskShift)!=0); - - NSString *behavior = [[NSUserDefaults standardUserDefaults] valueForKey:@"openingFilesBehavior"]; - if (modifierPressed) { - behavior = [[NSUserDefaults standardUserDefaults] valueForKey:@"openingFilesAlteredBehavior"]; - } - - BOOL shouldPlay = modifierPressed; // The default is NO for internal insertions - if (origin == URLOriginExternal) { // For external insertions, we look at the preference - shouldPlay = [behavior isEqualToString:@"clearAndPlay"] || [behavior isEqualToString:@"enqueueAndPlay"];; - } +- (void)didInsertURLs:(NSArray *)urls origin:(URLOrigin)origin { + if (![urls count]) return; - //Auto start playback - if (shouldPlay && [[self content] count] > 0) { - [playbackController playEntry: [urls objectAtIndex:0]]; - } + CGEventRef event = CGEventCreate(NULL); + CGEventFlags mods = CGEventGetFlags(event); + CFRelease(event); + + BOOL modifierPressed = + ((mods & kCGEventFlagMaskCommand) != 0) & ((mods & kCGEventFlagMaskControl) != 0); + modifierPressed |= ((mods & kCGEventFlagMaskShift) != 0); + + NSString *behavior = + [[NSUserDefaults standardUserDefaults] valueForKey:@"openingFilesBehavior"]; + if (modifierPressed) { + behavior = + [[NSUserDefaults standardUserDefaults] valueForKey:@"openingFilesAlteredBehavior"]; + } + + BOOL shouldPlay = modifierPressed; // The default is NO for internal insertions + if (origin == URLOriginExternal) { // For external insertions, we look at the preference + shouldPlay = [behavior isEqualToString:@"clearAndPlay"] || + [behavior isEqualToString:@"enqueueAndPlay"];; + } + + // Auto start playback + if (shouldPlay && [[self content] count] > 0) { + [playbackController playEntry:urls[0]]; + } } - @end diff --git a/Playlist/PlaylistView.h b/Playlist/PlaylistView.h index 83e2ca41a..ed39842e1 100644 --- a/Playlist/PlaylistView.h +++ b/Playlist/PlaylistView.h @@ -13,11 +13,11 @@ #import "PlaylistLoader.h" @interface PlaylistView : NSTableView { - IBOutlet PlaybackController *playbackController; - IBOutlet PlaylistController *playlistController; + IBOutlet PlaybackController *playbackController; + IBOutlet PlaylistController *playlistController; IBOutlet PlaylistLoader *playlistLoader; - - NSMenu *headerContextMenu; + + NSMenu *headerContextMenu; } - (IBAction)toggleColumn:(id)sender; diff --git a/Playlist/PlaylistView.m b/Playlist/PlaylistView.m index baef28411..84daa8ecb 100644 --- a/Playlist/PlaylistView.m +++ b/Playlist/PlaylistView.m @@ -7,13 +7,11 @@ // #import "PlaylistView.h" -#import "PlaybackController.h" -#import "PlaylistController.h" -#import "IndexFormatter.h" -#import "SecondsFormatter.h" #import "BlankZeroFormatter.h" +#import "IndexFormatter.h" #import "PlaylistEntry.h" +#import "SecondsFormatter.h" #import "CogAudio/Status.h" @@ -21,377 +19,353 @@ @implementation PlaylistView -- (void)awakeFromNib -{ +- (void)awakeFromNib { [[self menu] setAutoenablesItems:NO]; - + // Configure bindings to scale font size and row height NSControlSize s = NSControlSizeSmall; NSFont *f = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:s]]; // NSFont *bf = [[NSFontManager sharedFontManager] convertFont:f toHaveTrait:NSBoldFontMask]; - + for (NSTableColumn *col in [self tableColumns]) { [[col dataCell] setControlSize:s]; [[col dataCell] setFont:f]; } - - //Set up formatters + + // Set up formatters NSFormatter *secondsFormatter = [[SecondsFormatter alloc] init]; [[[self tableColumnWithIdentifier:@"length"] dataCell] setFormatter:secondsFormatter]; - + NSFormatter *indexFormatter = [[IndexFormatter alloc] init]; [[[self tableColumnWithIdentifier:@"index"] dataCell] setFormatter:indexFormatter]; - + NSFormatter *blankZeroFormatter = [[BlankZeroFormatter alloc] init]; [[[self tableColumnWithIdentifier:@"track"] dataCell] setFormatter:blankZeroFormatter]; [[[self tableColumnWithIdentifier:@"year"] dataCell] setFormatter:blankZeroFormatter]; - //end setting up formatters - + // end setting up formatters + [self setVerticalMotionCanBeginDrag:YES]; - - //Set up header context menu + + // Set up header context menu headerContextMenu = [[NSMenu alloc] initWithTitle:@"Playlist Header Context Menu"]; - - NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"identifier" ascending:YES]; - NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor]; - + + NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"identifier" + ascending:YES]; + NSArray *sortDescriptors = @[sortDescriptor]; + int visibleTableColumns = 0; int menuIndex = 0; - for (NSTableColumn *col in [[self tableColumns] sortedArrayUsingDescriptors: sortDescriptors]) - { + for (NSTableColumn *col in [[self tableColumns] sortedArrayUsingDescriptors:sortDescriptors]) { NSString *title; - if ([[col identifier] isEqualToString:@"status"]) - { + if ([[col identifier] isEqualToString:@"status"]) { title = @"Status"; - } - else if ([[col identifier] isEqualToString:@"index"]) - { + } else if ([[col identifier] isEqualToString:@"index"]) { title = @"Index"; - } - else - { + } else { title = [[col headerCell] title]; } - - NSMenuItem *contextMenuItem = [headerContextMenu insertItemWithTitle:title action:@selector(toggleColumn:) keyEquivalent:@"" atIndex:menuIndex]; - + + NSMenuItem *contextMenuItem = + [headerContextMenu insertItemWithTitle:title + action:@selector(toggleColumn:) + keyEquivalent:@"" + atIndex:menuIndex]; + [contextMenuItem setTarget:self]; [contextMenuItem setRepresentedObject:col]; - [contextMenuItem setState:([col isHidden] ? NSOffState : NSOnState)]; - + [contextMenuItem setState:([col isHidden] ? NSControlStateValueOff : NSControlStateValueOn)]; + visibleTableColumns += ![col isHidden]; menuIndex++; } - + if (visibleTableColumns == 0) { for (NSTableColumn *col in [self tableColumns]) { [col setHidden:NO]; } } - + [[self headerView] setMenu:headerContextMenu]; } - -- (IBAction)toggleColumn:(id)sender -{ +- (IBAction)toggleColumn:(id)sender { id tc = [sender representedObject]; - - if ([sender state] == NSOffState) - { - [sender setState:NSOnState]; - - [tc setHidden: NO]; - } - else - { - [sender setState:NSOffState]; - - [tc setHidden: YES]; + + if ([sender state] == NSControlStateValueOff) { + [sender setState:NSControlStateValueOn]; + + [tc setHidden:NO]; + } else { + [sender setState:NSControlStateValueOff]; + + [tc setHidden:YES]; } } -- (BOOL)acceptsFirstResponder -{ +- (BOOL)acceptsFirstResponder { return YES; } -- (BOOL)resignFirstResponder -{ +- (BOOL)resignFirstResponder { return YES; } -- (BOOL)acceptsFirstMouse:(NSEvent *)mouseDownEvent -{ +- (BOOL)acceptsFirstMouse:(NSEvent *)mouseDownEvent { return NO; } -- (void)mouseDown:(NSEvent *)e -{ +- (void)mouseDown:(NSEvent *)e { [super mouseDown:e]; - - if ([e type] == NSEventTypeLeftMouseDown && [e clickCount] == 2 && [[self selectedRowIndexes] count] == 1) - { + + if ([e type] == NSEventTypeLeftMouseDown && [e clickCount] == 2 && + [[self selectedRowIndexes] count] == 1) { [playbackController play:self]; } } // enables right-click selection for "Show in Finder" contextual menu --(NSMenu*)menuForEvent:(NSEvent*)event -{ - //Find which row is under the cursor +- (NSMenu *)menuForEvent:(NSEvent *)event { + // Find which row is under the cursor [[self window] makeFirstResponder:self]; - NSPoint menuPoint = [self convertPoint:[event locationInWindow] fromView:nil]; + NSPoint menuPoint = [self convertPoint:[event locationInWindow] fromView:nil]; NSInteger iRow = [self rowAtPoint:menuPoint]; - NSMenu* tableViewMenu = [self menu]; - + NSMenu *tableViewMenu = [self menu]; + /* Update the table selection before showing menu Preserves the selection if the row under the mouse is selected (to allow for multiple items to be selected), otherwise selects the row under the mouse */ - BOOL currentRowIsSelected = [[self selectedRowIndexes] containsIndex:iRow]; + BOOL currentRowIsSelected = [[self selectedRowIndexes] containsIndex:(NSUInteger) iRow]; if (!currentRowIsSelected) { - if (iRow == -1) - { + if (iRow == -1) { [self deselectAll:self]; - } - else - { - [self selectRowIndexes:[NSIndexSet indexSetWithIndex:iRow] byExtendingSelection:NO]; + } else { + [self selectRowIndexes:[NSIndexSet indexSetWithIndex:(NSUInteger) iRow] byExtendingSelection:NO]; } } - - if ([self numberOfSelectedRows] <=0) - { - //No rows are selected, so the table should be displayed with all items disabled + + if ([self numberOfSelectedRows] <= 0) { + // No rows are selected, so the table should be displayed with all items disabled int i; - for (i=0;i<[tableViewMenu numberOfItems];i++) { + for (i = 0; i < [tableViewMenu numberOfItems]; i++) { [[tableViewMenu itemAtIndex:i] setEnabled:NO]; } } - + return tableViewMenu; } -- (void)keyDown:(NSEvent *)e -{ - unsigned int modifiers = [e modifierFlags] & (NSEventModifierFlagCommand | NSEventModifierFlagShift | NSEventModifierFlagControl | NSEventModifierFlagOption); - NSString *characters = [e characters]; - unichar c; - - if ([characters length] != 1) - { +- (void)keyDown:(NSEvent *)e { + unsigned int modifiers = + [e modifierFlags] & (NSEventModifierFlagCommand | NSEventModifierFlagShift | + NSEventModifierFlagControl | NSEventModifierFlagOption); + NSString *characters = [e characters]; + unichar c; + + if ([characters length] != 1) { [super keyDown:e]; - + return; } - + c = [characters characterAtIndex:0]; - if (modifiers == 0 && (c == NSDeleteCharacter || c == NSBackspaceCharacter || c == NSDeleteFunctionKey)) - { + if (modifiers == 0 && + (c == NSDeleteCharacter || c == NSBackspaceCharacter || c == NSDeleteFunctionKey)) { [playlistController remove:self]; - } - else if (modifiers == 0 && c == ' ') - { + } else if (modifiers == 0 && c == ' ') { [playbackController playPauseResume:self]; - } - else if (modifiers == 0 && (c == NSEnterCharacter || c == NSCarriageReturnCharacter)) - { + } else if (modifiers == 0 && (c == NSEnterCharacter || c == NSCarriageReturnCharacter)) { [playbackController play:self]; - } - else if (modifiers == 0 && c == NSLeftArrowFunctionKey) - { + } else if (modifiers == 0 && c == NSLeftArrowFunctionKey) { [playbackController eventSeekBackward:self]; - } - else if (modifiers == 0 && c == NSRightArrowFunctionKey) - { + } else if (modifiers == 0 && c == NSRightArrowFunctionKey) { [playbackController eventSeekForward:self]; } - // Escape - else if (modifiers == 0 && c == 0x1b) - { + // Escape + else if (modifiers == 0 && c == 0x1b) { [playlistController clearFilterPredicate:self]; - } - else - { + } else { [super keyDown:e]; } } -- (IBAction)scrollToCurrentEntry:(id)sender -{ +- (IBAction)scrollToCurrentEntry:(id)sender { [self scrollRowToVisible:[[playlistController currentEntry] index]]; - [self selectRowIndexes:[NSIndexSet indexSetWithIndex:[[playlistController currentEntry] index]] byExtendingSelection:NO]; + [self selectRowIndexes:[NSIndexSet indexSetWithIndex:(NSUInteger) [[playlistController currentEntry] index]] + byExtendingSelection:NO]; } -- (IBAction)undo:(id)sender -{ +- (IBAction)undo:(id)sender { [[playlistController undoManager] undo]; } -- (IBAction)redo:(id)sender -{ +- (IBAction)redo:(id)sender { [[playlistController undoManager] redo]; } -- (IBAction)copy:(id)sender -{ +- (IBAction)copy:(id)sender { NSPasteboard *pboard = [NSPasteboard generalPasteboard]; - [pboard clearContents]; - - NSMutableArray *selectedURLs = [[NSMutableArray alloc] init]; - - for (PlaylistEntry *pe in [[playlistController content] objectsAtIndexes:[playlistController selectionIndexes]]) - { + + NSArray *entries = + [[playlistController content] objectsAtIndexes:[playlistController selectionIndexes]]; + NSUInteger capacity = [entries count]; + NSMutableArray *selectedURLs = [NSMutableArray arrayWithCapacity:capacity]; + + for (PlaylistEntry *pe in entries) { [selectedURLs addObject:[pe URL]]; } - - [pboard setData:[NSArchiver archivedDataWithRootObject:selectedURLs] forType:CogUrlsPboardType]; - - NSMutableDictionary * tracks = [[NSMutableDictionary alloc] init]; - + + NSError *error; + NSData *data = [NSKeyedArchiver archivedDataWithRootObject:selectedURLs + requiringSecureCoding:YES + error:&error]; + if (!data) { + DLog(@"Error: %@", error); + } + [pboard setData:data forType:CogUrlsPboardType]; + + NSMutableDictionary *tracks = [NSMutableDictionary dictionaryWithCapacity:capacity]; + unsigned long i = 0; - for (NSURL *url in selectedURLs) - { - NSMutableDictionary * track = [NSMutableDictionary dictionaryWithObjectsAndKeys:[url absoluteString], @"Location", nil]; - [tracks setObject:track forKey:[NSString stringWithFormat:@"%lu", i]]; - ++i; + for (NSURL *url in selectedURLs) { + tracks[[NSString stringWithFormat:@"%lu", i++]] = @{@"Location": [url absoluteString]}; } - - NSMutableDictionary * itunesPlist = [NSMutableDictionary dictionaryWithObjectsAndKeys:tracks, @"Tracks", nil]; - + + NSDictionary *itunesPlist = @{@"Tracks": tracks}; + [pboard setPropertyList:itunesPlist forType:iTunesDropType]; - - NSMutableArray *filePaths = [[NSMutableArray alloc] init]; - - for (NSURL *url in selectedURLs) - { - if ([url isFileURL]) - [filePaths addObject:[url path]]; + + NSMutableArray *filePaths = [NSMutableArray array]; + + for (NSURL *url in selectedURLs) { + if ([url isFileURL]) { + [filePaths addObject:url]; + } + } + + if ([filePaths count]) { + [pboard writeObjects:filePaths]; } - - if ([filePaths count]) - [pboard setPropertyList:filePaths forType:NSFilenamesPboardType]; } -- (IBAction)cut:(id)sender -{ +- (IBAction)cut:(id)sender { [self copy:sender]; - + [playlistController removeObjectsAtArrangedObjectIndexes:[playlistController selectionIndexes]]; - - if ([playlistController shuffle] != ShuffleOff) - [playlistController resetShuffleList]; + + if ([playlistController shuffle] != ShuffleOff) [playlistController resetShuffleList]; } -- (IBAction)paste:(id)sender -{ +- (IBAction)paste:(id)sender { // Determine the type of object that was dropped - NSArray *supportedTypes = [NSArray arrayWithObjects:CogUrlsPboardType, NSFilenamesPboardType, iTunesDropType, nil]; + NSArray *supportedTypes = @[CogUrlsPboardType, NSPasteboardTypeFileURL, iTunesDropType]; NSPasteboard *pboard = [NSPasteboard generalPasteboard]; - NSString *bestType = [pboard availableTypeFromArray:supportedTypes]; - - NSMutableArray *acceptedURLs = [[NSMutableArray alloc] init]; - + NSPasteboardType bestType = [pboard availableTypeFromArray:supportedTypes]; + DLog(@"All types:"); + for (NSPasteboardType type in [pboard types]) { + DLog(@" Type: %@", type); + } + DLog(@"Supported types:"); + for (NSPasteboardType type in supportedTypes) { + DLog(@" Type: %@", type); + } + DLog(@"Best type: %@", bestType); + + NSMutableArray *acceptedURLs = [NSMutableArray array]; + // Get files from an file drawer drop if ([bestType isEqualToString:CogUrlsPboardType]) { - NSArray *urls = [NSUnarchiver unarchiveObjectWithData:[pboard dataForType:CogUrlsPboardType]]; - DLog(@"URLS: %@", urls); + NSError *error; + NSData *data = [pboard dataForType:CogUrlsPboardType]; + NSArray *urls; + if (@available(macOS 11.0, *)) { + urls = [NSKeyedUnarchiver unarchivedArrayOfObjectsOfClass:[NSURL class] + fromData:data + error:&error]; + } else { + NSSet *allowed = [NSSet setWithArray:@[[NSArray class], [NSURL class]]]; + urls = [NSKeyedUnarchiver unarchivedObjectOfClasses:allowed fromData:data error:&error]; + } + if (!urls) { + DLog(@"%@", error); + } else { + DLog(@"URLS: %@", urls); + } //[playlistLoader insertURLs: urls atIndex:row sort:YES]; [acceptedURLs addObjectsFromArray:urls]; } - + // Get files from a normal file drop (such as from Finder) - if ([bestType isEqualToString:NSFilenamesPboardType]) { + if ([bestType isEqualToString:NSPasteboardTypeFileURL]) { NSMutableArray *urls = [[NSMutableArray alloc] init]; - - for (NSString *file in [pboard propertyListForType:NSFilenamesPboardType]) - { + + for (NSString *file in [pboard propertyListForType:NSPasteboardTypeFileURL]) { [urls addObject:[NSURL fileURLWithPath:file]]; } - + //[playlistLoader insertURLs:urls atIndex:row sort:YES]; [acceptedURLs addObjectsFromArray:urls]; } - + // Get files from an iTunes drop if ([bestType isEqualToString:iTunesDropType]) { NSDictionary *iTunesDict = [pboard propertyListForType:iTunesDropType]; NSDictionary *tracks = [iTunesDict valueForKey:@"Tracks"]; - + // Convert the iTunes URLs to URLs....MWAHAHAH! NSMutableArray *urls = [[NSMutableArray alloc] init]; - + for (NSDictionary *trackInfo in [tracks allValues]) { [urls addObject:[NSURL URLWithString:[trackInfo valueForKey:@"Location"]]]; } - + //[playlistLoader insertURLs:urls atIndex:row sort:YES]; [acceptedURLs addObjectsFromArray:urls]; } - - if ([acceptedURLs count]) - { + + if ([acceptedURLs count]) { NSUInteger row = [[playlistController content] count]; - + [playlistController willInsertURLs:acceptedURLs origin:URLOriginInternal]; - - NSArray* entries = [playlistLoader insertURLs:acceptedURLs atIndex:(int)row sort:NO]; + + NSArray *entries = [playlistLoader insertURLs:acceptedURLs atIndex:(int) row sort:NO]; [playlistLoader didInsertURLs:entries origin:URLOriginInternal]; - - if ([playlistController shuffle] != ShuffleOff) - [playlistController resetShuffleList]; + + if ([playlistController shuffle] != ShuffleOff) [playlistController resetShuffleList]; } } -- (IBAction)delete:(id)sender -{ +- (IBAction)delete:(id)sender { [playlistController removeObjectsAtArrangedObjectIndexes:[playlistController selectionIndexes]]; } - --(BOOL)validateUserInterfaceItem:(id )anItem -{ +- (BOOL)validateUserInterfaceItem:(id )anItem { SEL action = [anItem action]; - - if (action == @selector(undo:)) - { - if ([[playlistController undoManager] canUndo]) - return YES; - else - return NO; + + if (action == @selector(undo:)) { + return [[playlistController undoManager] canUndo]; } - if (action == @selector(redo:)) - { - if ([[playlistController undoManager] canRedo]) - return YES; - else - return NO; + if (action == @selector(redo:)) { + return [[playlistController undoManager] canRedo]; } - if (action == @selector(cut:) || action == @selector(copy:) || action == @selector(delete:)) - { - if ([[playlistController selectionIndexes] count] == 0) - return NO; - else - return YES; + if (action == @selector(cut:) || action == @selector(copy:) || action == @selector(delete:)) { + return [[playlistController selectionIndexes] count] != 0; } - if (action == @selector(paste:)) - { + if (action == @selector(paste:)) { NSPasteboard *pboard = [NSPasteboard generalPasteboard]; - - NSArray *supportedTypes = [NSArray arrayWithObjects:CogUrlsPboardType, NSFilenamesPboardType, iTunesDropType, nil]; - + + NSArray *supportedTypes = @[CogUrlsPboardType, NSPasteboardTypeFileURL, iTunesDropType]; + NSString *bestType = [pboard availableTypeFromArray:supportedTypes]; - - if (bestType != nil) - return YES; - else - return NO; + + return bestType != nil; } - - if (action == @selector(scrollToCurrentEntry:) && (([playbackController playbackStatus] == kCogStatusStopped) || ([playbackController playbackStatus] == kCogStatusStopping))) + + if (action == @selector(scrollToCurrentEntry:) && + (([playbackController playbackStatus] == kCogStatusStopped) || + ([playbackController playbackStatus] == kCogStatusStopping))) return NO; - + return [super validateUserInterfaceItem:anItem]; } @@ -405,5 +379,4 @@ } #endif - @end diff --git a/Playlist/XmlContainer.h b/Playlist/XmlContainer.h index 9d1420294..0216dde0a 100644 --- a/Playlist/XmlContainer.h +++ b/Playlist/XmlContainer.h @@ -8,9 +8,7 @@ #import -@interface XmlContainer : NSObject { - -} +@interface XmlContainer : NSObject + (NSURL *)urlForPath:(NSString *)path relativeTo:(NSString *)baseFilename; diff --git a/Playlist/XmlContainer.m b/Playlist/XmlContainer.m index 4fcc2858d..a52b39c4d 100644 --- a/Playlist/XmlContainer.m +++ b/Playlist/XmlContainer.m @@ -8,101 +8,109 @@ #import "XmlContainer.h" -#import "PlaylistEntry.h" - #import "Logging.h" @implementation XmlContainer -+ (NSURL *)urlForPath:(NSString *)path relativeTo:(NSString *)baseFilename -{ - NSRange protocolRange = [path rangeOfString:@"://"]; - if (protocolRange.location != NSNotFound) - { - return [NSURL URLWithString:path]; - } ++ (NSURL *)urlForPath:(NSString *)path relativeTo:(NSString *)baseFilename { + NSRange protocolRange = [path rangeOfString:@"://"]; + if (protocolRange.location != NSNotFound) { + return [NSURL URLWithString:path]; + } - NSMutableString *unixPath = [path mutableCopy]; + NSMutableString *unixPath = [path mutableCopy]; - //Get the fragment - NSString *fragment = @""; - NSScanner *scanner = [NSScanner scannerWithString:unixPath]; - NSCharacterSet *characterSet = [NSCharacterSet characterSetWithCharactersInString:@"#1234567890"]; - while (![scanner isAtEnd]) { - NSString *possibleFragment; - [scanner scanUpToString:@"#" intoString:nil]; + //Get the fragment + NSString *fragment = @""; + NSScanner *scanner = [NSScanner scannerWithString:unixPath]; + NSCharacterSet *characterSet = [NSCharacterSet characterSetWithCharactersInString:@"#1234567890"]; + while (![scanner isAtEnd]) { + NSString *possibleFragment; + [scanner scanUpToString:@"#" intoString:nil]; - if ([scanner scanCharactersFromSet:characterSet intoString:&possibleFragment] && [scanner isAtEnd]) - { - fragment = possibleFragment; - [unixPath deleteCharactersInRange:NSMakeRange([scanner scanLocation] - [possibleFragment length], [possibleFragment length])]; - break; - } - } - DLog(@"Fragment: %@", fragment); + if ([scanner scanCharactersFromSet:characterSet intoString:&possibleFragment] && [scanner isAtEnd]) { + fragment = possibleFragment; + [unixPath deleteCharactersInRange:NSMakeRange([scanner scanLocation] - [possibleFragment length], [possibleFragment length])]; + break; + } + } + DLog(@"Fragment: %@", fragment); - if (![unixPath hasPrefix:@"/"]) { - //Only relative paths would have windows backslashes. - [unixPath replaceOccurrencesOfString:@"\\" withString:@"/" options:0 range:NSMakeRange(0, [unixPath length])]; - - NSString *basePath = [[[baseFilename stringByStandardizingPath] stringByDeletingLastPathComponent] stringByAppendingString:@"/"]; + if (![unixPath hasPrefix:@"/"]) { + //Only relative paths would have windows backslashes. + [unixPath replaceOccurrencesOfString:@"\\" withString:@"/" options:0 range:NSMakeRange(0, [unixPath length])]; - [unixPath insertString:basePath atIndex:0]; - } - - //Append the fragment - NSURL *url = [NSURL URLWithString:[[[NSURL fileURLWithPath:unixPath] absoluteString] stringByAppendingString: fragment]]; - return url; + NSString *basePath = [[[baseFilename stringByStandardizingPath] stringByDeletingLastPathComponent] stringByAppendingString:@"/"]; + + [unixPath insertString:basePath atIndex:0]; + } + + //Append the fragment + NSURL *url = [NSURL URLWithString:[[[NSURL fileURLWithPath:unixPath] absoluteString] stringByAppendingString:fragment]]; + return url; } -+ (NSDictionary *)entriesForContainerURL:(NSURL *)url -{ - if (![url isFileURL]) - return [NSDictionary dictionary]; ++ (NSDictionary *)entriesForContainerURL:(NSURL *)url { + if (![url isFileURL]) + return nil; - NSError *nserr; - - NSString *error; - - NSString *filename = [url path]; - - NSString * contents = [NSString stringWithContentsOfFile:filename encoding:NSUTF8StringEncoding error:&nserr]; - - NSData* plistData = [contents dataUsingEncoding:NSUTF8StringEncoding]; - - NSPropertyListFormat format; - id plist = [NSPropertyListSerialization propertyListFromData:plistData mutabilityOption:NSPropertyListImmutable format:&format errorDescription:&error]; - if(!plist){ - ALog(@"Error: %@",error); + NSError *error; + + NSString *filename = [url path]; + + NSString *contents = [NSString stringWithContentsOfFile:filename + encoding:NSUTF8StringEncoding + error:&error]; + if (!contents) { + ALog(@"Error: %@", error); return nil; } - + + NSData *plistData = [contents dataUsingEncoding:NSUTF8StringEncoding]; + + NSPropertyListFormat format; + id plist = [NSPropertyListSerialization propertyListWithData:plistData + options:NSPropertyListImmutable + format:&format + error:&error]; + if (!plist) { + ALog(@"Error: %@", error); + return nil; + } + BOOL isArray = [plist isKindOfClass:[NSArray class]]; BOOL isDict = [plist isKindOfClass:[NSDictionary class]]; - - if (!isDict && !isArray) return nil; - - NSArray * items = (isArray) ? (NSArray*)plist : [(NSDictionary *)plist objectForKey:@"items"]; - - NSDictionary *albumArt = (isArray) ? nil : [(NSDictionary *)plist objectForKey:@"albumArt"]; - NSArray *queueList = (isArray) ? [NSArray array] : [(NSDictionary *)plist objectForKey:@"queue"]; - - NSMutableArray *entries = [NSMutableArray array]; - - for (NSDictionary *entry in items) - { - NSMutableDictionary * preparedEntry = [NSMutableDictionary dictionaryWithDictionary:entry]; - - [preparedEntry setObject:[self urlForPath:[preparedEntry objectForKey:@"URL"] relativeTo:filename] forKey:@"URL"]; - - if (albumArt && [preparedEntry objectForKey:@"albumArt"]) - [preparedEntry setObject:[albumArt objectForKey:[preparedEntry objectForKey:@"albumArt"]] forKey:@"albumArt"]; - + if (!isDict && !isArray) return nil; + + NSArray *items; + NSDictionary *albumArt; + NSArray *queueList; + if (isArray) { + items = (NSArray *) plist; + albumArt = nil; + queueList = [NSArray array]; + } else { + NSDictionary *dict = (NSDictionary *) plist; + items = dict[@"items"]; + albumArt = dict[@"albumArt"]; + queueList = dict[@"queue"]; + } + + NSMutableArray *entries = [NSMutableArray array]; + + for (NSDictionary *entry in items) { + NSMutableDictionary *preparedEntry = [NSMutableDictionary dictionaryWithDictionary:entry]; + + preparedEntry[@"URL"] = [self urlForPath:preparedEntry[@"URL"] relativeTo:filename]; + + if (albumArt && preparedEntry[@"albumArt"]) + preparedEntry[@"albumArt"] = albumArt[preparedEntry[@"albumArt"]]; + [entries addObject:[NSDictionary dictionaryWithDictionary:preparedEntry]]; - } - - return [NSDictionary dictionaryWithObjectsAndKeys:entries, @"entries", queueList, @"queue", nil]; + } + + return @{@"entries": entries, @"queue": queueList}; } @end diff --git a/Window/RepeatTransformers.h b/Window/RepeatTransformers.h index 0cbf53662..f06a6b153 100644 --- a/Window/RepeatTransformers.h +++ b/Window/RepeatTransformers.h @@ -10,9 +10,7 @@ #import "PlaylistController.h" -@interface RepeatModeTransformer : NSValueTransformer { - RepeatMode repeatMode; -} +@interface RepeatModeTransformer : NSValueTransformer - (id)initWithMode:(RepeatMode) r; diff --git a/Window/RepeatTransformers.m b/Window/RepeatTransformers.m index d5ac8a8ac..f4eb9e8f5 100644 --- a/Window/RepeatTransformers.m +++ b/Window/RepeatTransformers.m @@ -7,55 +7,47 @@ // #import "RepeatTransformers.h" -#import "PlaylistController.h" #import "Logging.h" -@implementation RepeatModeTransformer +@implementation RepeatModeTransformer { + RepeatMode repeatMode; +} + (Class)transformedValueClass { return [NSNumber class]; } + (BOOL)allowsReverseTransformation { return YES; } -- (id)initWithMode:(RepeatMode) r -{ - self = [super init]; - if (self) - { - repeatMode = r; - } - - return self; +- (id)initWithMode:(RepeatMode)r { + self = [super init]; + if (self) { + repeatMode = r; + } + + return self; } // Convert from RepeatMode to BOOL - (id)transformedValue:(id)value { - DLog(@"Transforming value: %@", value); - - if (value == nil) return nil; - - RepeatMode mode = (RepeatMode) [value integerValue]; - - if (repeatMode == mode) { - return [NSNumber numberWithBool:YES]; - } - + DLog(@"Transforming value: %@", value); - return [NSNumber numberWithBool:NO]; + if (value == nil) return nil; + + RepeatMode mode = (RepeatMode) [value integerValue]; + + return @(repeatMode == mode); } - (id)reverseTransformedValue:(id)value { if (value == nil) return nil; - - BOOL enabled = [value boolValue]; - if (enabled) { - return [NSNumber numberWithInt:repeatMode]; - } - else if(repeatMode == RepeatNone) { - return [NSNumber numberWithInt:RepeatAll]; - } - else { - return [NSNumber numberWithInt:RepeatNone]; - } + + BOOL enabled = [value boolValue]; + if (enabled) { + return @(repeatMode); + } else if (repeatMode == RepeatModeNoRepeat) { + return @(RepeatModeRepeatAll); + } else { + return @(RepeatModeNoRepeat); + } } @end @@ -67,26 +59,26 @@ // Convert from string to RepeatMode - (id)transformedValue:(id)value { - DLog(@"Transforming value: %@", value); - + DLog(@"Transforming value: %@", value); + if (value == nil) return nil; - RepeatMode mode = (RepeatMode) [value integerValue]; - - if (mode == RepeatNone) { - return [NSImage imageNamed:@"repeatModeOffTemplate"]; - } - else if (mode == RepeatOne) { - return [NSImage imageNamed:@"repeatModeOneTemplate"]; - } - else if (mode == RepeatAlbum) { - return [NSImage imageNamed:@"repeatModeAlbumTemplate"]; - } - else if (mode == RepeatAll) { - return [NSImage imageNamed:@"repeatModeAllTemplate"]; - } + RepeatMode mode = (RepeatMode) [value integerValue]; - return nil; + if (mode == RepeatModeNoRepeat) { + return [NSImage imageNamed:@"repeatModeOffTemplate"]; + } + else if (mode == RepeatModeRepeatOne) { + return [NSImage imageNamed:@"repeatModeOneTemplate"]; + } + else if (mode == RepeatModeRepeatAlbum) { + return [NSImage imageNamed:@"repeatModeAlbumTemplate"]; + } + else if (mode == RepeatModeRepeatAll) { + return [NSImage imageNamed:@"repeatModeAllTemplate"]; + } + + return nil; } @end