From ba472864df01cb71ae5c1f2843d7c44406bf8ff0 Mon Sep 17 00:00:00 2001 From: Kim Wittenburg Date: Thu, 3 Mar 2016 23:08:26 +0100 Subject: [PATCH] Replaced much too complicated class based system with simple data structs. --- TagTunes/Album.swift | 148 ----- TagTunes/AlbumCollection.swift | 209 ------- TagTunes/SearchResult.swift | 65 --- TagTunes/Track.swift | 193 ------- TagTunes/TrackTableCellView.swift | 141 ----- TagTunes/de.lproj/Main.storyboard | 915 ------------------------------ 6 files changed, 1671 deletions(-) delete mode 100644 TagTunes/Album.swift delete mode 100644 TagTunes/AlbumCollection.swift delete mode 100644 TagTunes/SearchResult.swift delete mode 100644 TagTunes/Track.swift delete mode 100644 TagTunes/TrackTableCellView.swift delete mode 100644 TagTunes/de.lproj/Main.storyboard diff --git a/TagTunes/Album.swift b/TagTunes/Album.swift deleted file mode 100644 index ef8bdf5..0000000 --- a/TagTunes/Album.swift +++ /dev/null @@ -1,148 +0,0 @@ -// -// Album.swift -// Tag for iTunes -// -// Created by Kim Wittenburg on 29.05.15. -// Copyright (c) 2015 Kim Wittenburg. All rights reserved. -// - -import Cocoa - -/// Represents an album of the -/// [Search API](https://www.apple.com/itunes/affiliates/resources/documentation/itunes-store-web-service-search-api.html). -public class Album: iTunesType { - - // MARK: Properties - - public let id: iTunesId - - public let name: String - - public let censoredName: String - - public let viewURL: NSURL - - public let artwork: Artwork - - public let trackCount: Int - - public let releaseDate: NSDate - - public let genre: String - - public let artistName: String - - public private(set) var tracks = [Track]() - - // MARK: Initializers - - internal init(id: iTunesId, name: String, censoredName: String, viewURL: NSURL, artwork: Artwork, trackCount: Int, releaseDate: NSDate, genre: String, artistName: String) { - self.id = id - self.name = name - self.censoredName = censoredName - self.viewURL = viewURL - self.artwork = artwork - self.trackCount = trackCount - self.releaseDate = releaseDate - self.genre = genre - self.artistName = artistName - } - - public required init(data: [iTunesAPI.Field : AnyObject]) { - id = data[.CollectionId] as! UInt - name = data[.CollectionName] as! String - censoredName = data[.CollectionCensoredName] as! String - viewURL = NSURL(string: data[.CollectionViewUrl] as! String)! - - artwork = Artwork(data: data) - trackCount = data[.TrackCount] as! Int - releaseDate = iTunesAPI.sharedDateFormatter.dateFromString(data[.ReleaseDate] as! String)! - genre = data[.PrimaryGenreName] as! String - if let artistName = data[.CollectionArtistName] as? String { - self.artistName = artistName - } else { - artistName = data[.ArtistName] as! String - } - } - - public static var requiredFields: [iTunesAPI.Field] { - return [.CollectionId, .CollectionName, .CollectionCensoredName, .CollectionViewUrl, .TrackCount, .ReleaseDate, .PrimaryGenreName, .ArtistName] - } - - // MARK: Methods - - /// Adds a track to the album. - internal func addTrack(newTrack: Track) { - newTrack.album = self - var index = 0 - for track in tracks { - if newTrack.discNumber < track.discNumber { - break - } else if newTrack.discNumber == track.discNumber { - if newTrack.trackNumber <= track.trackNumber { - break - } - } - ++index - } - tracks.insert(newTrack, atIndex: index) - } - - /// Returns wether all tracks in the album have the same artist name as the - /// album itself. - public var hasSameArtistNameAsTracks: Bool { - for track in tracks { - if artistName != track.artistName { - return false - } - } - return true - } - - /// Saves the album to iTunes. - public func save() { - for track in tracks { - track.save() - } - } - - /// Saves the album's artwork to the directory specified in the user's - /// preferences (See `Preferences` for details). - public func saveArtwork() throws { - if let url = Preferences.sharedPreferences.artworkTarget { - try artwork.saveToURL(url, filename: name) - } - } - - /// Returns `true` if all tracks of the album are saved. - public var saved: Bool { - for track in tracks { - if !track.saved { - return false - } - } - return true - } - - -} - -extension Album: CustomStringConvertible { - - public var description: String { - return "\"\(name)\" (\(tracks.count) tracks)" - } - -} - -extension Album: Hashable { - - public var hashValue: Int { - return Int(id) - } - -} - -public func ==(lhs: Album, rhs: Album) -> Bool { - return lhs === rhs -} \ No newline at end of file diff --git a/TagTunes/AlbumCollection.swift b/TagTunes/AlbumCollection.swift deleted file mode 100644 index 8139070..0000000 --- a/TagTunes/AlbumCollection.swift +++ /dev/null @@ -1,209 +0,0 @@ -// -// AlbumCollection.swift -// TagTunes -// -// Created by Kim Wittenburg on 08.09.15. -// Copyright © 2015 Kim Wittenburg. All rights reserved. -// - -import Foundation - -/// Manages a collection of albums. Managing includes support for deferred -/// loading of an album's tracks as well as error support. -public class AlbumCollection: CollectionType { - - // MARK: Types - - private enum AlbumState { - - case Normal - - case Error(NSError) - - case Loading(NSURLSessionTask) - - } - - /// Notifications posted by an album collection. The `userInfo` of these - /// notifications contains all keys specified in `Keys`. - public struct Notifications { - - /// Posted when an album is added to a collection. This notification is - /// only posted if the album collection actually changed. - public static let albumAdded = "AlbumAddedNotificationName" - - /// Posted when an album is removed from a collection. This notification - /// is only posted if the album collection actually changed. - public static let albumRemoved = "AlbumRemovedNotificationName" - - /// Posted when the album collection started a network request for an - /// album's tracks. - /// - /// Note that the values for the keys `Album` and `AlbumIndex` for the - /// corresponding `AlbumFinishedLoading` notification may both be - /// different. - public static let albumStartedLoading = "AlbumStartedLoadingNotificationName" - - /// Posted when an album collection finished loading the tracks for an - /// album. Receiving this notification does not mean that the tracks were - /// actually loaded successfully. It just means that the networ - /// connection terminated. Use `errorForAlbum` to determine if an error - /// occured while the tracks have been loaded. - /// - /// - note: Since the actual `Album` instance in the album collection may - /// change during loading its tracks it is preferred that you use the - /// `AlbumIndexKey` of the notification to determine which album finished - /// loading its tracks. You can however use the `AlbumKey` as well to - /// access the `Album` instance that is currently present in the - /// collection at the respective index. - public static let albumFinishedLoading = "AlbumFinishedLoadingNotificationName" - - /// These constants are available as keys in the `userInfo` dictionary - /// for any notification an album collection may post. - public struct Keys { - - /// The `Album` instance affected by the notification. - public static let album = "AlbumKey" - - /// The index of the album affected by the notification. - public static let albumIndex = "AlbumIndexKey" - - } - - } - - // MARK: Properties - - /// Access the userlying array of albums. - public private(set) var albums = [Album]() - - private var albumStates = [Album: AlbumState]() - - /// The URL session used to load tracks for albums. - private let urlSession = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration(), delegate: nil, delegateQueue: NSOperationQueue.mainQueue()) - - // MARK: Collection Type - - public init() {} - - public var startIndex: Int { - return albums.startIndex - } - - public var endIndex: Int { - return albums.endIndex - } - - public subscript (position: Int) -> Album { - return albums[position] - } - - // MARK: Album Collection - - /// Adds the specified album, if not already present, and begins to load its - /// tracks. - /// - /// - parameters: - /// - album: The album to be added. - /// - flag: Specify `false` if the album collection should not begin to - /// load the album's tracks immediately. - public func addAlbum(album: Album, beginLoading flag: Bool = true) { - if !albums.contains(album) { - albums.append(album) - let userInfo: [NSObject: AnyObject] = [AlbumCollection.Notifications.Keys.album: album, AlbumCollection.Notifications.Keys.albumIndex: albums.count-1] - NSNotificationCenter.defaultCenter().postNotificationName(AlbumCollection.Notifications.albumAdded, object: self, userInfo: userInfo) - if flag { - beginLoadingTracksForAlbum(album) - } - } - } - - /// Removes the specified album from the collection if it is present. - public func removeAlbum(album: Album) { - if let index = albums.indexOf(album) { - removeAlbumAtIndex(index) - } - } - - /// Removes the album at the specified index from the collection. - /// - /// - requires: The specified index must be in the collection's range. - public func removeAlbumAtIndex(index: Int) { - let album = self[index] - setAlbumState(nil, forAlbum: album) - albums.removeAtIndex(index) - let userInfo: [NSObject: AnyObject] = [AlbumCollection.Notifications.Keys.album: album, AlbumCollection.Notifications.Keys.albumIndex: index] - NSNotificationCenter.defaultCenter().postNotificationName(AlbumCollection.Notifications.albumRemoved, object: self, userInfo: userInfo) - } - - /// Begins to load the tracks for the specified album. If there is already a - /// request for the specified album it is cancelled. When the tracks for the - /// specified album have been loaded or an error occured, a - /// `AlbumFinishedLoadingNotification` is posted. - public func beginLoadingTracksForAlbum(album: Album) { - guard let albumIndex = albums.indexOf(album) else { - return - } - let url = iTunesAPI.createAlbumLookupURLForId(album.id) - let task = urlSession.dataTaskWithURL(url) { (data, response, error) -> Void in - var newAlbumIndex = self.albums.indexOf(album)! - defer { - let userInfo: [NSObject: AnyObject] = [AlbumCollection.Notifications.Keys.album: self.albums[albumIndex], AlbumCollection.Notifications.Keys.albumIndex: albumIndex] - NSNotificationCenter.defaultCenter().postNotificationName(AlbumCollection.Notifications.albumFinishedLoading, object: self, userInfo: userInfo) - } - guard error == nil else { - if error!.code != NSUserCancelledError { - self.albumStates[album] = .Error(error!) - } - return - } - do { - let newAlbum = try iTunesAPI.parseAPIData(data!)[0] - self.albums.removeAtIndex(newAlbumIndex) - self.albums.insert(newAlbum, atIndex: newAlbumIndex) - self.setAlbumState(.Normal, forAlbum: album) - } catch let error as NSError { - self.setAlbumState(.Error(error), forAlbum: album) - } catch _ { - // Will never happen - } - } - setAlbumState(.Loading(task), forAlbum: album) - task.resume() - let userInfo: [NSObject: AnyObject] = [AlbumCollection.Notifications.Keys.album: album, AlbumCollection.Notifications.Keys.albumIndex: albumIndex] - NSNotificationCenter.defaultCenter().postNotificationName(AlbumCollection.Notifications.albumStartedLoading, object: self, userInfo: userInfo) - - } - - /// Cancels the request to load the tracks for the specified album and sets - /// the error for the album to a `NSUserCancelledError` in the - /// `NSCocoaErrorDomain`. - public func cancelLoadingTracksForAlbum(album: Album) { - let error = NSError(domain: NSCocoaErrorDomain, code: NSUserCancelledError, userInfo: nil) - setAlbumState(.Error(error), forAlbum: album) - } - - /// Sets the state for the specified album. If the previous state was - /// `Loading` the associated task is cancelled. - private func setAlbumState(state: AlbumState?, forAlbum album: Album) { - if case let .Some(.Loading(task)) = albumStates[album] { - task.cancel() - } - albumStates[album] = state - } - - public func isAlbumLoading(album: Album) -> Bool { - if case .Some(.Loading) = albumStates[album] { - return true - } - return false - } - - public func errorForAlbum(album: Album) -> NSError? { - if case let .Some(.Error(error)) = albumStates[album] { - return error - } - return nil - } - -} diff --git a/TagTunes/SearchResult.swift b/TagTunes/SearchResult.swift deleted file mode 100644 index c9e1d57..0000000 --- a/TagTunes/SearchResult.swift +++ /dev/null @@ -1,65 +0,0 @@ -// -// SearchResult.swift -// TagTunes -// -// Created by Kim Wittenburg on 31.08.15. -// Copyright © 2015 Kim Wittenburg. All rights reserved. -// - -import Cocoa - -/// Represents an `Album` returned fromm the -/// [Search API](https://www.apple.com/itunes/affiliates/resources/documentation/itunes-store-web-service-search-api.html). -public class SearchResult { - - public let id: iTunesId - - public let name: String - - public let censoredName: String - - public let viewURL: NSURL - - public let artwork: Artwork - - public let trackCount: Int - - public let releaseDate: NSDate - - public let genre: String - - public let artistName: String - - public init(representedAlbum: Album) { - id = representedAlbum.id - name = representedAlbum.name - censoredName = representedAlbum.censoredName - viewURL = representedAlbum.viewURL - artwork = representedAlbum.artwork - trackCount = representedAlbum.trackCount - releaseDate = representedAlbum.releaseDate - genre = representedAlbum.genre - artistName = representedAlbum.artistName - } - -} - -extension SearchResult: Hashable { - - public var hashValue: Int { - return Int(id) - } - -} - -extension Album { - - public convenience init(searchResult: SearchResult) { - self.init(id: searchResult.id, name: searchResult.name, censoredName: searchResult.censoredName, viewURL: searchResult.viewURL, artwork: searchResult.artwork, trackCount: searchResult.trackCount, releaseDate: searchResult.releaseDate, genre: searchResult.genre, artistName: searchResult.artistName) - } - -} - -public func ==(lhs: SearchResult, rhs: SearchResult) -> Bool { - return lhs.id == rhs.id -} \ No newline at end of file diff --git a/TagTunes/Track.swift b/TagTunes/Track.swift deleted file mode 100644 index 7d19802..0000000 --- a/TagTunes/Track.swift +++ /dev/null @@ -1,193 +0,0 @@ -// -// Track.swift -// Tag for iTunes -// -// Created by Kim Wittenburg on 30.05.15. -// Copyright (c) 2015 Kim Wittenburg. All rights reserved. -// - -import Cocoa - -/// Represents a track of the -/// [Search API](https://www.apple.com/itunes/affiliates/resources/documentation/itunes-store-web-service-search-api.html). -public class Track: iTunesType { - - // MARK: Types - - public enum Tag: String { - case Name = "name", Artist = "artist", Year = "year", TrackNumber = "trackNumber", TrackCount = "trackCount", DiscNumber = "discNumber", DiscCount = "discCount", Genre = "genre", AlbumName = "album", AlbumArtist = "albumArtist" - case SortName = "sortName", SortArtist = "sortArtist", SortAlbumName = "sortAlbum", SortAlbumArtist = "sortAlbumArtist", Composer = "composer", SortComposer = "sortComposer", Comment = "comment" - - /// Returns `true` for tags that are returned from the - /// [Search API](https://www.apple.com/itunes/affiliates/resources/documentation/itunes-store-web-service-search-api.html). - public var isReturnedBySearchAPI: Bool { - switch self { - case .Name, .Artist, .Year, .TrackNumber, .TrackCount, .DiscNumber, .DiscCount, .Genre, .AlbumName, .AlbumArtist: - return true - default: - return false - } - } - - public var clearable: Bool { - switch self { - case .Year, .TrackNumber, .TrackCount, .DiscNumber, .DiscCount: - return false - default: - return true - } - } - - /// Returns a string identifying the respective tag that can be displayed - /// to the user. - public var localizedName: String { - return NSLocalizedString("Tag: \(self.rawValue)", comment: "") - } - - /// Returns an array of all tags. - public static var allTags: [Tag] { - return [.Name, .Artist, .Year, .TrackNumber, .TrackCount, .DiscNumber, .DiscCount, .Genre, .AlbumName, .AlbumArtist, .SortName, .SortArtist, .SortAlbumName, .SortAlbumArtist, .Composer, .SortComposer, .Comment] - } - - } - - // MARK: Properties - - public let id: iTunesId - - public let name: String - - public let censoredName: String - - public let artistName: String - - public let releaseDate: NSDate - - public let trackNumber: Int - - public let trackCount: Int - - public let discNumber: Int - - public let discCount: Int - - public let genre: String - - public internal(set) weak var album: Album! - - /// These tracks will be changed, if `save()` is called. - public var associatedTracks = [iTunesTrack]() - - // MARK: Initializers - - public required init(data: [iTunesAPI.Field: AnyObject]) { - id = data[.TrackId] as! UInt - name = data[.TrackName] as! String - censoredName = data[.TrackCensoredName] as! String - artistName = data[.ArtistName] as! String - releaseDate = iTunesAPI.sharedDateFormatter.dateFromString(data[.ReleaseDate] as! String)! - trackNumber = data[.TrackNumber] as! Int - trackCount = data[.TrackCount] as! Int - discNumber = data[.DiscNumber] as! Int - discCount = data[.DiscCount] as! Int - genre = data[.PrimaryGenreName] as! String - } - - public static var requiredFields: [iTunesAPI.Field] { - return [.TrackId, .TrackName, .TrackCensoredName, .ArtistName, .ReleaseDate, .TrackNumber, .TrackCount, .DiscNumber, .DiscCount, .PrimaryGenreName] - } - - // MARK: Methods - - /// Saves the track. This means that its properties are applied to every - /// `iTunesTrack` in its `associatedTracks`. - /// - /// This method respects the user's preferences (See `Preferences` class). - public func save() { - saveToTracks(associatedTracks) - } - - /// Applies the receiver's properties to the specified tracks. - /// - /// This method respects the user's preferences (See `Preferences` class). - public func saveToTracks(tracks: [iTunesTrack]) { - for track in tracks { - saveToTrack(track) - } - } - - /// Applies the receiver's properties to the specified `track`. - /// - /// This method respects the user's preferences (See `Preferences` class). - public func saveToTrack(track: iTunesTrack) { - let components = NSCalendar.currentCalendar().components(.Year, fromDate: releaseDate) - let trackName = Preferences.sharedPreferences.useCensoredNames ? censoredName : name - saveTag(.Name, toTrack: track, value: trackName) - saveTag(.Artist, toTrack: track, value: artistName) - saveTag(.Year, toTrack: track, value: components.year) - saveTag(.TrackNumber, toTrack: track, value: trackNumber) - saveTag(.TrackCount, toTrack: track, value: trackCount) - saveTag(.DiscNumber, toTrack: track, value: discNumber) - saveTag(.DiscCount, toTrack: track, value: discCount) - saveTag(.Genre, toTrack: track, value: genre) - let albumName = Preferences.sharedPreferences.useCensoredNames ? album.censoredName : album.name - saveTag(.AlbumName, toTrack: track, value: albumName) - saveTag(.AlbumArtist, toTrack: track, value: album.artistName) - saveTag(.SortName, toTrack: track, value: nil) - saveTag(.SortArtist, toTrack: track, value: nil) - saveTag(.SortAlbumName, toTrack: track, value: nil) - saveTag(.SortAlbumArtist, toTrack: track, value: nil) - saveTag(.Composer, toTrack: track, value: nil) - saveTag(.SortComposer, toTrack: track, value: nil) - saveTag(.Comment, toTrack: track, value: nil) - - if Preferences.sharedPreferences.clearArtworks { - track.artworks().removeAllObjects() - } - } - - private func saveTag(tag: Tag, toTrack track: iTunesTrack, value: AnyObject?) { - switch Preferences.sharedPreferences.tagSavingBehaviors[tag]! { - case .Save: - track.setValue(value, forKey: tag.rawValue) - case .Clear: - track.setValue("", forKey: tag.rawValue) - case .Ignore: - break - } - } - - /// Returns `true` if all `associatedTrack`s contain the same values as the - /// `Track` instance. - public var saved: Bool { - let components = NSCalendar.currentCalendar().components(.Year, fromDate: releaseDate) - for track in associatedTracks { - let trackName = Preferences.sharedPreferences.useCensoredNames ? censoredName : name - let albumName = Preferences.sharedPreferences.useCensoredNames ? album.censoredName : album.name - let options = Preferences.sharedPreferences.caseSensitive ? [] : NSStringCompareOptions.CaseInsensitiveSearch - guard track.name.compare(trackName, options: options, range: nil, locale: nil) == .OrderedSame else { - return false - } - guard track.album.compare(albumName, options: options, range: nil, locale: nil) == .OrderedSame else { - return false - } - guard track.artist == artistName && track.year == components.year && track.trackNumber == trackNumber && track.trackCount == trackCount && track.discNumber == discNumber && track.discCount == discCount && track.genre == genre && track.albumArtist == album.artistName && track.composer == "" else { - return false - } - } - return true - } - -} - -extension Track: Hashable { - - public var hashValue: Int { - return Int(id) - } - -} - -public func ==(lhs: Track, rhs: Track) -> Bool { - return lhs.id == rhs.id -} diff --git a/TagTunes/TrackTableCellView.swift b/TagTunes/TrackTableCellView.swift deleted file mode 100644 index ecb1cce..0000000 --- a/TagTunes/TrackTableCellView.swift +++ /dev/null @@ -1,141 +0,0 @@ -// -// TrackTableCellView.swift -// Harmony -// -// Created by Kim Wittenburg on 21.01.15. -// Copyright (c) 2015 Das Code Kollektiv. All rights reserved. -// - -import Cocoa -import AppKitPlus - -/// A table cell view to display information for a `Track`. This class should -/// only be initialized from a nib or storyboard. -public class TrackTableCellView: AdvancedTableCellView { - - // MARK: Types - - private struct Images { - - /// Caches the tick image for track cells so that it does not need to be - /// reloaded every time a cell is configured. - static let tickImage = NSImage(named: "Tick")?.imageByMaskingWithColor(NSColor.clearColor()) - - /// Caches the gray tick image for track cells so that it does not need to be - /// reloaded every time a cell is configured. - static let grayTickImage = NSImage(named: "Tick")?.imageByMaskingWithColor(NSColor.lightGrayColor()) - - } - - // MARK: Properties - - /// An outlet do display the track number. This acts as a secondary label. - /// The text color is automatically adjusted based on the `backgroundStyle` - /// of the receiver. - /// - /// Intended to be used as accessory view - @IBOutlet public lazy var trackNumberTextField: NSTextField? = { - let trackNumberTextField = NSTextField() - trackNumberTextField.bordered = false - trackNumberTextField.drawsBackground = false - trackNumberTextField.selectable = false - trackNumberTextField.lineBreakMode = .ByTruncatingTail - trackNumberTextField.font = NSFont.systemFontOfSize(0) - trackNumberTextField.textColor = NSColor.secondaryLabelColor() - trackNumberTextField.translatesAutoresizingMaskIntoConstraints = false - return trackNumberTextField - }() - - /// Intended to be used as accessory view. - /// - /// This property replaces `imageView`. - @IBOutlet public lazy var savedImageView: NSImageView! = { - let secondaryImageView = NSImageView() - secondaryImageView.imageScaling = .ScaleProportionallyDown - secondaryImageView.translatesAutoresizingMaskIntoConstraints = false - return secondaryImageView - }() - - // MARK: Intitializers - - override public func setupView() { - leftAccessoryView = trackNumberTextField - super.setupView() - } - - // MARK: Overrides - - override public var backgroundStyle: NSBackgroundStyle { - get { - return super.backgroundStyle - } - set { - super.backgroundStyle = newValue - let trackNumberCell = self.trackNumberTextField?.cell as? NSTextFieldCell - trackNumberCell?.backgroundStyle = newValue - - switch newValue { - case .Light: - trackNumberTextField?.textColor = NSColor.secondaryLabelColor() - case .Dark: - trackNumberTextField?.textColor = NSColor.secondarySelectedControlColor() - default: - break - } - } - } - - override public var imageView: NSImageView? { - set { - savedImageView = newValue - } - get { - return savedImageView - } - } - - // MARK: Methods - - /// Sets up the receiver to display `track`. - public func setupForTrack(track: Track) { - style = track.album.hasSameArtistNameAsTracks ? .Simple : .CompactSubtitle - - textField?.stringValue = Preferences.sharedPreferences.useCensoredNames ? track.censoredName : track.name - if track.associatedTracks.isEmpty { - textField?.textColor = NSColor.disabledControlTextColor() - } else if track.associatedTracks.count > 1 || track.associatedTracks[0].name.compare(track.name, options: Preferences.sharedPreferences.caseSensitive ? [] : .CaseInsensitiveSearch, range: nil, locale: nil) != .OrderedSame { - textField?.textColor = NSColor.redColor() - } else { - textField?.textColor = NSColor.controlTextColor() - } - secondaryTextField?.stringValue = track.artistName - trackNumberTextField?.stringValue = "\(track.trackNumber)" - if track.associatedTracks.isEmpty { - imageView?.image = TrackTableCellView.Images.grayTickImage - } else { - imageView?.image = TrackTableCellView.Images.tickImage - } - if track.saved { - let aspectRatioConstraint = NSLayoutConstraint( - item: savedImageView, - attribute: .Width, - relatedBy: .Equal, - toItem: savedImageView, - attribute: .Height, - multiplier: 1, - constant: 0) - let widthConstraint = NSLayoutConstraint( - item: savedImageView, - attribute: .Width, - relatedBy: .Equal, - toItem: nil, - attribute: .Width, - multiplier: 1, - constant: 17) - setRightAccessoryView(savedImageView, withConstraints: [aspectRatioConstraint, widthConstraint]) - } else { - rightAccessoryView = nil - } - } - -} diff --git a/TagTunes/de.lproj/Main.storyboard b/TagTunes/de.lproj/Main.storyboard deleted file mode 100644 index a1d6a1b..0000000 --- a/TagTunes/de.lproj/Main.storyboard +++ /dev/null @@ -1,915 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -CA - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Wählen Sie einen Ordner… - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Diese Option betrifft nur Cover, die in TagTunes angezeigt werden. Beim Speichern wird immer die höchste Auflösung für Cover verwendet. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -