Compare commits

..

388 Commits

Author SHA1 Message Date
Christopher Snowhill ad9af1640c
Remove a saucy option
Nobody was likely to be using it, much less even know what it was.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-06-13 22:43:40 -07:00
Christopher Snowhill a1caefa014
Updated BASS and company
Also included missing BASS_MPC, which was still being imported
even though it wasn't actually included.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-06-12 17:27:56 -07:00
Christopher Snowhill 42b91c6f9d Update MASShortcut for Xcode 15
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-06-08 04:40:24 -07:00
Christopher Snowhill da2c2eb2a8 Touched by Xcode
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-06-08 04:30:25 -07:00
Christopher Snowhill 2dbe524f20
Organya: Fix deployment target for 10.13
Oops, it was somehow still set to 13.0, from when I created it.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-06-08 04:13:21 -07:00
Christopher Snowhill eb26ab8be4
Update projects and source in prep for Xcode 15
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-06-08 04:12:29 -07:00
Christopher Snowhill 8443464b54
About Dialog: Move logo to asset catalog
Also convert it to a supported HEIF format, making it much smaller.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-06-08 03:44:24 -07:00
Shoh Sewell f64ec07b43
Volume slider changes
Makes volume slider logarithmic when limited to 100% to allow easier changing of volume towards the bottom of the slider.
The tooltip remains as the slider location instead of the logarithmic value of the actual volume.
2023-06-08 03:40:04 -07:00
Christopher Snowhill 1cd3a3230c
File Tree: Reduce monitoring to limited changes
Only track new, removed, or renamed files. Tracking Xattr changes was
apparently causing the tracker dialog to crash on things like the user
changing file type associations, which either added or removed a per-
file association xattr, or when clicking Change All, removed this xattr
from all associated files tracked by Spotlight.

Fixes #361

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-06-04 01:37:31 -07:00
Christopher Snowhill 6c0db041e3
Playlist: Add a workaround for AppleStript URLs
AppleScript is apparently such a legacy system, that when it sends URLs
to your app to open, they're in the old Carbon format. So we need to
translate these to proper URL strings for the rest of the app to deal
with them at all.

The format of these URLs is as follows:

/method/::

Followed optionally by:

username/password@

Where the slash and password are optional.

Followed by:

hostname

Followed optionally by:

/portnumber

And finally, followed by:

:path:on:server:filename.ext

So, in hostname field, we must swap slashes to colons. And in the path
field, swap colons to slashes. What a bizarre world.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-06-01 21:34:16 -07:00
Christopher Snowhill 22cdf0aa4f
HTTP Input: Do not hang if transfer completes
If transfer completes quickly, do not hang waiting for it to achieve
reading state. Also add some comments indicating what we're doing.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-06-01 21:29:37 -07:00
Christopher Snowhill 10f22d137c
Metadata: Fixes metadata reading
metadataBlob may be null, so create dictionary in that case.

Fixes #360

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-06-01 15:15:52 -07:00
Christopher Snowhill 877660b4cc
Update feed updater script for R2
Update to use rclone with out of tree config to upload

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-06-01 00:14:48 -07:00
C.W. Betts fa373b9ff1
Move most image assets to Xcode assets.
AboutCog.jp2 isn't moved because Xcode/Xcode assets doesn't recognize jp2 files as images.

# Conflicts:
#	Cog.xcodeproj/project.pbxproj
2023-06-01 00:13:50 -07:00
Shoh Sewell 55cb51c330
Adds decimal digits to volume slider tooltip (#356)
* Adds decimal digits to volume slider tooltip

Modifies the volume slider tooltip so that:
-If the volume slider falls below 10%, the volume tooltip will display one decimal digit of precision (e.g. 3.4%).
-Else if the volume slider falls below 1%, display one decimal digit of precision (e.g. 0.34%).
-Otherwise display the volume slider tooltip as normal.

This helps show changes in volume between 0% and 10% where a change in volume isn't shown in the UI but is heard (especially when the "Limit volume control to 100%" option is unchecked in the "Output" Preferences submenu.

* Update VolumeSlider.m

Fix variable declaration

---------

Co-authored-by: Christopher Snowhill <chris@kode54.net>
2023-06-01 00:11:16 -07:00
Christopher Snowhill db338f929a
Playlist: Fix merging dynamic metadata dictionary
Merge the existing metadata entry dictionary with new values, because
sometimes, the caller may pass us a dictionary with some fields missing.

Fixes stream metadata for many HTTP streams.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-05-31 22:35:06 -07:00
Christopher Snowhill 13254f25b1
HTTP: Support a stream title hack
Support a stream title hack employed by some iHeartRadio streams

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-05-31 22:33:50 -07:00
Christopher Snowhill 1115e9651d
HTTP: Support much larger metadata blocks
Support icy metaint data blocks up to 4KiB in size

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-05-31 22:33:15 -07:00
Christopher Snowhill 836147b94b
Updated VGMStream to r1843-0-gb158e812
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-05-31 22:31:44 -07:00
Christopher Snowhill b47d2154b4
FFmpeg: Fix AAC streaming
Fix AAC streaming by adding the correct audio/aac MIME type.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-05-31 21:26:11 -07:00
Christopher Snowhill 9e54885b97
Touched by Xcode
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-05-04 18:23:39 -07:00
Christopher Snowhill 11ffdcb1c1
Updated Turkish translation to near completion
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-05-04 18:23:35 -07:00
Christopher Snowhill 4d106c40ce
Updated VGMStream to r1831-27-ge6883cbd
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-05-04 18:23:31 -07:00
Christopher Snowhill 9d3089462e
Updated libOpenMPT to version 0.7
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-05-04 18:23:25 -07:00
Christopher Snowhill 3e2286683a
Translation: Added Turkish language support
This translation is mostly complete.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-23 22:44:24 -08:00
Christopher Snowhill c1e5aa21fc
Translation: Updated Spanish translation
Added the new Lyrics window strings.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-23 22:42:39 -08:00
Christopher Snowhill 549f426e65
Main Menu: Add new Lyrics item to strings tables
Add item to strings tables for translations of the menu item. English is
already done as the base language, awaiting Spanish at least, will await
Polish and Russian when the respective translators get to it.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-23 18:25:33 -08:00
Christopher Snowhill c68b4b9585
Lyrics Window: Added localization templates
Awaiting localizations of the window name in currently supported
languages.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-23 18:19:05 -08:00
Christopher Snowhill 0b82160512
Lyrics Window: Touched by Xcode
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-23 18:19:01 -08:00
Christopher Snowhill ed38e4f8d0
Info Window: Reorder header imports
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-23 17:46:22 -08:00
Christopher Snowhill 799299df3a
Lyrics: Implement Lyrics window display and hotkey
Implement Lyrics window display into main app as a popup window panel,
with a main menu hotkey.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-23 17:45:59 -08:00
Christopher Snowhill 57a0ea6e87
Tags: Implement unsynced lyrics in Vorbis plugin
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-23 17:45:05 -08:00
Christopher Snowhill de974548de
Tags: Implement unsynced lyrics in Opus plugin
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-23 17:44:45 -08:00
Christopher Snowhill b0c718003b
Tags: Implement unsynced lyrics in Flac plugin
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-23 17:44:19 -08:00
Christopher Snowhill 593d7d155a
Tags: Implement unsynced lyrics in FFmpeg plugin
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-23 17:44:01 -08:00
Christopher Snowhill 190d6959fd
Tags: Implement unsynced lyrics into TagLib plugin
Implement unsynced lyrics reading into TagLib frontend plugin.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-23 17:41:50 -08:00
Christopher Snowhill 790eb5508b
TagLib: Implement unsynced lyrics tag support
Implement unsynced lyrics tag reading and writing into TagLib.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-23 17:41:12 -08:00
Christopher Snowhill c34d869b99
Tags: Added unsynced lyrics tag interface
Added an unsynced lyrics tag interface to the PlaylistEntry class

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-23 17:39:52 -08:00
Christopher Snowhill 5743652879
Update copyright year in various places
Update these things a bit for the next release.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-05 16:46:56 -08:00
Christopher Snowhill 4131d4eae4
Updated VGMStream to r1810-97-g408cada5
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-04 23:46:16 -08:00
Christopher Snowhill 9bfbeaadb5
Updated libOpenMPT to version 0.6.8
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-04 22:13:01 -08:00
Christopher Snowhill 26242673d1
Repair SceneKit project definition
Repair the SceneKit container definition in the Xcode project file, so
that the Visualization scene gets copied properly on project build.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-04 22:12:31 -08:00
Christopher Snowhill 57c2adf946
Replaced r8brain with libsoxr
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-04 22:10:22 -08:00
Christopher Snowhill 01c38c9440
Playback Controller: Fixed title bar updating
This change had several components. For one, the delay of the dispatch
was increased from 5 milliseconds to 50 milliseconds. Two, the post to
the notification center was included in the delayed dispatch, so that
retains the PlaylistEntry object. Finally, the playlistController's
currentEntry object is reassigned from the input PlaylistEntry object,
which facilitates all watchers which are observing that variable for
updates. This final step also retains self for the callback, which
should be fine, since it's a quick dispatch with a short delay.

Fixes #335

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-12-09 22:35:01 -08:00
Christopher Snowhill 72ee38ad14
Audio Player: Only wait for unstopped input
Input thread now signals when it has stopped and is about to return, in
case the input thread returns before the BufferChain dealloc function
would be waiting for it to terminate. Somehow, even though the Semaphore
is being signaled at this point, the BufferChain still ends up waiting
the default of 2.5 seconds for the signal that apparently never comes,
delaying file stoppage. This prevents the wait action entirely. Must
have been some sort of race condition.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-12-09 21:18:56 -08:00
Christopher Snowhill 6daa0de425
Audio Player: Add new method of signaling stop
This new method should cause all stops to default to immediate stoppage,
and only stops that occur after an end of track signal should indicate
to play out the entire buffer.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-12-09 21:18:47 -08:00
Christopher Snowhill 1b9f460538
Playback Controller: Remove "stopping" status use
This should not really be necessary for proper player operation any
longer, and can safely be removed.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-12-09 21:18:07 -08:00
Christopher Snowhill 1de501a64a
Sandbox: Rework several blocking actions
Several actions have been reworked to be non-blocking, as their
operation should still occur in the main thread, but should not block
the thread they are called from, as they are not required to continue
processing there.

End of secure access has also been made non-blocking, as it is usually
only called when an input is done accessing a given file or folder, so
it should be important to return quickly, as the input is likely about
to terminate, and other things are waiting for it to return.

Also remove a nested block call for the storage access, as it is within
an existing serializing block, so it shouldn't need to be nested.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-12-09 21:18:03 -08:00
Christopher Snowhill 4b37ffebee
Update script: Purge cache of manifest files
Purge the manifest files from the Bunny CDN cache before starting
the update of the site.
2022-12-05 23:16:50 -08:00
Christopher Snowhill 5e0a3308c0
Decoders: Implemented Organya decoder
Based on the C++11 code by Joel Yliluoma / bisqwit, which in turn is
based on information from NX-Engine. I have also taken the liberty of
bundling the required wavetable bank and PixTone drums. Contrary to the
documentation provided with the code, my version of dou_1006.zip, as
downloaded over a decade ago, had the wavetable bank at offset 635,816
bytes into the file, not 1,115,748 bytes. Possibly a difference of
having applied the translation patch? My copy is the original version,
so I had to use a real resource parser to locate the waveforms.

The player will obey the configured sample rate, loop count, and fade
time for synthesizers, and also obey Repeat One to play indefinitely.
The code should be quite robust to minor abuses, though I can't imagine
how well it would hold up to random bad files, other than playing
outright garbage.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-12-04 03:09:52 -08:00
Christopher Snowhill 85283b99a1
Sandbox: Fixed another outstanding sync bug
Releasing sandbox access was incorrectly synchronizing on the object,
but still running code in the calling thread. It has been updated to
match the rest of the interface, which serializes all access through the
main thread only. This should prevent the sandbox from carrying stale
handles to already-released objects.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-12-03 22:13:54 -08:00
Christopher Snowhill 63bd6b29d7
Resampler: Update r8brain-free-src to v6.2
This should improve performance significantly for downsampling.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-12-03 22:13:48 -08:00
Christopher Snowhill fadeec1827
Fix SceneKit visualization
Must always remember to have xcode-select set to Xcode.app and not
the Command Line Tools when archiving the app myself, as otherwise
Xcode will fail to package the SceneKit objects into the resulting
bundle.
2022-11-30 01:10:39 -08:00
Christopher Snowhill 9c67eb78fc
Sandbox Broker: Fixed a potential reference crash
The code which looked up Sandbox handles for a given path had a bug
where it would re-add the handle to the in-memory cache storage even if
it already had just retrieved the current handle from the cache. I hope
this will fix the crashes which have been plaguing people adding a lot
of files to the playlist all at once from a single folder.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-11-29 00:49:27 -08:00
Christopher Snowhill d8f0a19524
Updated VGMStream to r1800-25-g599326a3
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-11-29 00:47:14 -08:00
Christopher Snowhill 5cd5fe1c5e
Dependencies: Update libVGM release and debug
Update from 0e34925..fd7da37, with the following changes:

- C140: simplify update loop, add unbanked mode
  - It resembles MAME's code more closely now.

- OKIM6258: make more tolerant against late writes

- enforce "discrete YM3438" mode for YM3438 VGMs

- Update emu2413 to v1.5.9

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-11-29 00:27:44 -08:00
Christopher Snowhill 0c5c905af3
Update Script: Change feed upload to Bunny CDN
Change upload script to use curl to upload to Bunny. The access
key is stored in the system keychain, with confirmation on access.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-11-06 23:58:59 -08:00
Christopher Snowhill 364f13338d
Vorbis Plugin: Remove unnecessary shell script
Remove shell script that was modifying the import path of a framework,
as we are no longer using libvorbis like that.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-11-06 00:49:50 -07:00
Christopher Snowhill c627a9fc58
Add display name and category to project
Add display name and category fields to project. Thanks, Apple, for
adding those to Xcode all of a sudden.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-11-05 00:47:53 -07:00
Christopher Snowhill c40b25b571
Info plist: Add newly required keys
For some reason, Xcode isn't adding these now. No idea what Apple
has done to cause this.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-11-05 00:42:12 -07:00
Christopher Snowhill 66e1d67b32
Sandbox Broker: Fix hang with synchronization
Synchronize with dispatches to the main thread instead of using
synchronization primitives. This prevents the main thread from
hanging another thread as a result of other threads entering the
sync block, then dispatching a callback to the main thread, which
also tries to lock on the sync block.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-11-04 21:12:06 -07:00
Christopher Snowhill 3663140064 Core Data Store: Handle concurrency properly
All concurrency from other threads should pass through the viewContext's
performBlock or performBlockAndWait functions, and no other way. So now,
all access to Core Data is either happening on the main thread, or by
using these code blocks, all of which will wait for their access to
proceed.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-30 16:54:33 -07:00
Christopher Snowhill 31ddbbec29 MIDI Plugin: Fix Secret Sauce memory leaks
Needed some autoreleasepools in there.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-28 00:16:11 -07:00
Christopher Snowhill 7fb894d721 Touched by Xcode
Xcode updated the Preferences xib.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-28 00:15:37 -07:00
Christopher Snowhill 504ddcf82b Sparkle: Update API a bit
This updates the API interface calls a bit, and borrows about 20 lines
of code from WireShark.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-28 00:02:20 -07:00
Christopher Snowhill 02a7fe84cb MIDI Plugin: Add a little Secret Sauce
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-27 23:06:02 -07:00
Christopher Snowhill b88bee3f4a Amend MIDI Audio Unit player a bit
This should fix some potential initialization errors it may have had
before, but this doesn't fix the broken Sound Canvas VA plugin. Roland
says it's supposed to be broken on macOS 12+ and/or Apple silicon
anyway, so I guess there's no dodging that.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-21 16:37:01 -07:00
Christopher Snowhill 0d7fd92c82 Always create new ContentViewController for volume
This is needed to re-parent the VolumeSlider window, as there is only a
single VolumeSlider, but two different VolumeButtons and their
respective NSPopover windows. So, always recreate the view on open,
which doesn't appear to have a noticeable impact on performance.

Fixes #331

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-20 21:28:02 -07:00
Christopher Snowhill bc66220b36 Fix Spectrum View in toolbar customizer
It was referencing the old SpectrumView class, when it should have been
referencing the safe SpectrumViewCG class, which will software render a
single frame of spectrum data when the customizing dialog is opened.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-20 21:26:06 -07:00
Christopher Snowhill b1f97f3399 Updated FFmpeg to n5.2-dev-1305-g3bd0bf76fb
Among other things, fixes CVE-2022-2566.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-17 03:55:39 -07:00
Christopher Snowhill e7aec3547d Ignore unnamed audio devices on enumeration
This was crashing trying to assign a nil CFStringRef from mystery audio
devices to the NSString passed to the enumerate block function, which
was predictably crashing. Ignore such devices instead.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-16 15:23:06 -07:00
Christopher Snowhill a9dc4b564c Handle external artwork with .heic extension
External artwork already supported the HEIC format, just not the correct
filename extension for the format.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-16 15:00:28 -07:00
Christopher Snowhill e25cfbf22c Fix a crash with embedded cue sheet handling
Tag reading can read cue sheets as either a single NSString, or an
NSArray of NSStrings, so handle either case.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-16 15:00:24 -07:00
Christopher Snowhill 695a03d9e8 Updated Sparkle framework to version 2.3.0
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-16 00:18:57 -07:00
Christopher Snowhill 066ee806dc Only process visualizations when visible
Stop visualization processing when the host window is completely
occluded, thus reducing background CPU usage levels significantly

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-15 23:19:22 -07:00
Kevin López 2f90baf4bf Merge pull request #329 from gitter-badger/gitter-badge
Add a Gitter chat badge to README.md
2022-10-13 17:17:02 -07:00
The Gitter Badger 2ead57412b Add Gitter badge 2022-10-13 17:16:07 -07:00
Christopher Snowhill 309bd3bfef Update associated file type extensions
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-11 23:17:43 -07:00
Christopher Snowhill 323bc8f0df Formatting fixes
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-11 23:00:08 -07:00
Christopher Snowhill ce723fd44e Better locking behavior for playlist storage
This should fix up potential locking issues with maintaining a copy of
the results set while certain other background actions may happen, such
as the player updating play counts while playing.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-11 22:59:46 -07:00
Christopher Snowhill bc7331cf8c Updated libraries and libraries debug set
Updated:
- libFLAC from 1.3.3-235-g772efde6 to 1.4.1
- libvgm from 001ca75 to 0e34925
- libid3tag from 0.16.1 with patch to 0.16.2

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-11 22:52:41 -07:00
Christopher Snowhill fc372ef8b4 Updated libOpenMPT to version 0.6.6
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-11 22:47:02 -07:00
Christopher Snowhill 55882c0380 Updated VGMStream to r1776-97-g845961bb
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-11 22:45:07 -07:00
Christopher Snowhill 37065adf8a Updated VGMStream to r1776-46-gc0c2c3c7
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-09-06 21:56:51 -07:00
Christopher Snowhill 514374019b Update translations
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-08-21 16:49:56 -07:00
Christopher Snowhill 3a42f8896b Updated VGMStream to r1776-16-g7e4f5dc6
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-08-21 16:17:51 -07:00
Christopher Snowhill fadb3e9ee2 Updated libOpenMPT to version 0.6.5 final
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-08-21 15:56:54 -07:00
Christopher Snowhill d7418c3b33 [Cog Audio] Rename Semaphore.h to CogSemaphore.h
This magically fixes the stupid header maps that were pulling the system
semaphore.h into Swift projects, when they shouldn't have been doing
that in the first place. This is the same reason that the FLAC library
has its assert.h renamed to FLAC_assert.h.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-08-05 22:18:30 -07:00
Christopher Snowhill 41a04760eb [Cog Audio] Make the Swift Vis Controller work
And this is the actual meat of getting it to work properly, the changes
the Swift code needed to actually be fully functional.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-08-05 21:38:13 -07:00
Christopher Snowhill aed52840ca [Cog Audio] Add a Swift bridging header
This makes the Swift version of the Visualization Controller usable.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-08-05 21:36:39 -07:00
Christopher Snowhill 7e267f06cb [Cog Audio] Change a couple of imports
These imports needed to be changed so that Swift bridging didn't import
the system's semaphore.h instead of CogAudio's Semaphore.h, which is a
completely different thing.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-08-05 21:35:50 -07:00
Christopher Snowhill e5aa4287d1 First module converted to swift, but broken 2022-08-05 17:39:19 -07:00
Christopher Snowhill 06b4fc3ccc [GME Input] Correct old comment in the code
There has been an API in GME to detect tracks ending for quite some time
now, and this just adds a little bit to the existing comment, which
previously noted that there was no way to detect if a track had ended,
which may have been true several major versions of GME long past.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-08-04 18:02:49 -07:00
Christopher Snowhill 5019c6b4f6 [GME Input] Fix decoder output sample count
The output has been assigning twice as many samples as it was supposed
to ever since commit 8d851e5bda, which
ended up generating the correct 1024 samples (2048 per GME parameter),
but assigned 2048 to the AudioChunk, which resulted in over-reading the
audio buffer, and thankfully not crashing, but instead causing an awful
sound distortion effect as random memory contents were played as PCM
audio.

Fixes #320

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-08-04 18:01:09 -07:00
Christopher Snowhill 93e3dd7aa6 [CUE Sheet Container] Allow other containers
Allow .mp3 and such to fall back to the FFmpeg container handler, in
case there are chapters in a renamed file.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-08-03 21:20:42 -07:00
Christopher Snowhill f9c7e85e72 [MAD Decoder] Do not close source ourselves
The input isn't supposed to close its own sources, as it did not open
them itself, and they should be cleaned up automatically when they are
released to zero reference count.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-08-03 21:19:51 -07:00
Christopher Snowhill fbe232f791 [MAD Decoder] Drop RIFF files to the next input
Let the FFmpeg decoder handle RIFF files, if they happen to be named
.mp3 and not something like .wav.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-08-03 21:19:02 -07:00
Christopher Snowhill ea3d38bcae [Update Script] Add new JSON generator
Source is included here:

https://github.com/losnoco/sparkle-to-JSON
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-08-03 21:18:09 -07:00
Christopher Snowhill 49f88ae37f Fix update script
This fixes the update URL and parameter handling. Seems there
was an extraneous newline returned by the security command.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-31 23:38:07 -07:00
Christopher Snowhill c2a880fa52 [AdPlug Input] Fixed seeking
Looks like I never tested this, meh.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-31 22:52:03 -07:00
Christopher Snowhill 700cb962a3 Update update_feed.rb with new parameter
New parameter for update title for the site generator.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-31 21:50:05 -07:00
Christopher Snowhill 9560edf53d Updated AdPlug with a crash fix for RAD2
Fixed RAD2 files referencing instruments not present in the
file, which caused the player to reference uninitialized memory
and usually crash.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-31 21:47:58 -07:00
Christopher Snowhill f54b6c2c9a Updated libbinio
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-31 21:47:25 -07:00
Christopher Snowhill 3f7b375bfb [Playlist Menu] Disable actions on empty selection
These actions should not be invoked when there is no selection.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-29 01:42:45 -07:00
Christopher Snowhill af453816a0 [Playlist Queue] Save queue state change to disk
Save queue state changes to disk, rather than leaving it for later.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-29 01:41:49 -07:00
Christopher Snowhill daa0c3fc61 [Playlist Queue] Hopefully prevent a crash state
This removal was causing crashes for some people. It should not get this
way, however.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-29 01:41:10 -07:00
Christopher Snowhill 660cb1bab1 [SID Input] Add static initializer for residfp
The SID builder needs a static initializer, otherwise multiple instances
created simultaneously, such as during populating info on adding a lot
of tracks, will race and crash the player.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-27 21:38:22 -07:00
Christopher Snowhill 4ec2146549 [File Tree] Only free Smart Folder query if used
Only free the query if it was successfully allocated.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-27 06:35:59 -07:00
Christopher Snowhill 7cb22cfeb0 [File Tree] Ask Sandbox for access to Smart Folder
Ask for access to Smart Folder dictionary file, to read its query.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-27 06:35:55 -07:00
Christopher Snowhill 86dfe8b518 [Playlist View] Prevent assigning nil textField
Prevent somehow assigning nil textField contents, as well as the
tooltip text.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-25 19:55:45 -07:00
Christopher Snowhill b04be78f20 [Playlist Loader] Extend deduplication to CUEs
CUEs will now deduplicate playlist entries based on their dependencies,
and prevent loading redundant tracks if you add an entire directory, or
use the option to add a directory when adding single files from it.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-25 19:35:36 -07:00
Christopher Snowhill 177f055910 [Sandbox] Add Sandbox grants to places missing it
The subdirectory parser, the CUEsheet reader, and the legacy XML
playlist reader were missing grants for Sandbox access.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-25 19:35:32 -07:00
Christopher Snowhill 9f84a8bff5 Spanish translation of new option.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-24 23:23:02 -07:00
Christopher Snowhill 37cc0b4d30 Clarified folder add message to correct button
Clarified the button name to "Open", which is what the button actually
says, not "OK". Also used double quotes around the other button name.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-24 23:22:48 -07:00
Christopher Snowhill 8809c0d257 [Sandbox Paths] Automatically clean up old paths
Clean up redundant paths automatically, and on startup. Also refresh the
preferences dialog path list every time it is opened.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-24 23:15:10 -07:00
Christopher Snowhill 8bc94e9a48 [Playlist Loader] Deduplicate loaded items
Deduplicate loaded tracks, to prevent duplicate items when adding a
folder that happens to contain playlists or CUE sheets referencing the
very same files.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-24 23:15:06 -07:00
Christopher Snowhill 14eb923529 [Playlist Loader] Add option to load more files
Add option to load every file in a folder when opening just one or more
files in that folder.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-24 23:15:02 -07:00
Christopher Snowhill 4e24c5b829 [Playlist View] Change truncation behavior a bit
Change the truncation behavior to only truncate if the length exceeds
1024 code points.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-24 19:41:34 -07:00
Christopher Snowhill 360464ceec [Playlist View] Add Sample Rate and BPS fields
Add Sample Rate and Bits Per Sample columns, hidden by default.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-24 19:41:30 -07:00
Christopher Snowhill 9d2d29d0f4 [Sandbox Dialog] Fix removing newly added paths
Newly added paths weren't adding all of the necessary data to the list
storage to make it possible to remove them without restarting the
player. Oops.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-24 19:41:24 -07:00
Christopher Snowhill c612994cb2 Move most large stack using buffers to the heap
This should solve most potential future stack overflows.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-24 18:41:50 -07:00
Christopher Snowhill e330c64f43 Enable warnings to track stack overuse
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-24 18:41:45 -07:00
Christopher Snowhill e796e23afd [Sandbox Notification] Add Spanish translation
Add the Spanish translation of the new dialog.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-23 18:38:54 -07:00
Christopher Snowhill e2d228bbc0 [Sandbox Notice] Change single to double quotes
Change the quotes.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-23 18:38:29 -07:00
Christopher Snowhill f62a897f7d [Libraries] Fixed OpusFile debug library
It was linking to the wrong filename for libogg.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-23 18:37:40 -07:00
Christopher Snowhill 85a18f9a3e Updated VGMStream to r1745-79-g449bb5e0
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-23 18:36:45 -07:00
Christopher Snowhill 1c04d5e664 [File Permissions] Add warning dialog
Added a warning dialog to notify the user of the purpose of the add
folder dialog that will pop up after it. Otherwise, they may get the
idea that the dialog is a glitch and should be cancelled.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-23 18:04:32 -07:00
Christopher Snowhill 35dd0d38b3 [Playlist Loader] Only ask permission for local
Only ask permission for container folders if the container has local
files, and not for purely remote files, such as stream playlists.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-23 18:04:24 -07:00
Christopher Snowhill 9c4d9ebb2e [Playlist Insert] Add a further bodge fix
I wish people would stop adding files to the playlist while there's a
search filter in place.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-21 04:16:08 -07:00
Christopher Snowhill e14c630034 [FFmpeg Input] Buffer up to 5ms each read call
Buffer up to 5 milliseconds of audio, or at minimum 1024 samples, each
call. Also pre-allocate the buffer, rather than using a stack buffer.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-21 04:03:40 -07:00
Christopher Snowhill 28d5849505 [FFmpeg Input] Do not subtract first block length
This is an unnecessary step, and results in the offset being off by the
duration of the first pre-read block. This is incorrect.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-21 04:03:36 -07:00
Christopher Snowhill 81d31dbe58 [Inputs] Severely reduce metadata update intervals
The Vorbis, Opus, MAD MPEG, and especially the FFmpeg inputs needed to
have their metadata update intervals severely reduced, to reduce CPU
usage, especially on files with lots of tags. Interval reduced to only
once per second.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-21 04:03:33 -07:00
Christopher Snowhill 41e87e3830 [Chunk List Converter] Fix repeated initialization
Oops, this compare blunder resulted in DSD decimation breaking every
1024 samples or so, owing to block sizes, and caused ticking sounds as a
result. It would also cause HDCD decoding to break completely.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-19 23:05:59 -07:00
Christopher Snowhill 716170dcad [Chunk List Converter] Minor changes
Neither of these two changes is really important, but they do simplify
things, and the division on that one function makes the non-decimating
DSD support actually functional, as the caller expects a specific number
of samples, and that was otherwise octupling the input sample count.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-19 23:05:55 -07:00
Christopher Snowhill 533c36a745 [Audio Output] Eliminated another stack buffer
Another large stack buffer was at play here. Consolidated it into an
existing buffer that can perform double duty here, since neither place
it's used conflicts with each other.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-19 23:05:50 -07:00
Christopher Snowhill 4c4f479fb6 Add a lock around access to output PTS variable
This locking should help, but I don't know why visualization jumps
around now.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-19 07:31:20 -07:00
Christopher Snowhill b3d10bdd4d Reconfigure default toolbar layout
Now things are a little more understandable.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-19 07:31:15 -07:00
Christopher Snowhill 2a8aba1cf2 [FLAC Decoder] Fix reading CUESHEET tags
It already supported reading the CUESHEET metadata block, but I managed
to break reading and processing CUESHEET Vorbis comments, which broke
CUE tagging, as well as files that didn't have both tags.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-19 04:53:59 -07:00
Christopher Snowhill 8bd37943aa [Playlist Pasteboard] Rewrite row pasteboard
Playlist View pasteboard copier function should only be generating URLs,
and it should verify that the entry has a valid URL to begin with.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-16 06:07:53 -07:00
Christopher Snowhill 7bf1bd85b8 [Repeat Album] Add a safety test to repeat list
In case the current track isn't part of an album, or is otherwise not
matching any albums in the playlist. Though the Album filter predicate
wasn't working for a while due to changes.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-16 06:00:09 -07:00
Christopher Snowhill 6fe7883ed2 Update all localizations
This includes the base English strings, Spanish, Polish, and Russian.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-16 05:46:05 -07:00
Christopher Snowhill b5f6e0ec20 [Audio Output] Remove renderer from synchronizer
Remove the renderer from the synchronizer on stop, before releasing the
objects, if possible.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-15 22:56:46 -07:00
Christopher Snowhill 3f212f0cfb [Audio Output] Only unregister listener if used
Only unregister the listener if it actually has been registered, and
clear the handle upon doing so.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-15 22:56:38 -07:00
Christopher Snowhill 804e7652a8 [MAD Decoder] Don't crash on bad files
The local and seekable file scanner could crash on bad MPEG files if
they failed to decode any frames and broke due to either end of file or
other unrecoverable errors, due to a division by zero error attempting
to calculate the file bitrate. Now correctly return error state if this
occurs, bailing early.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-15 22:56:30 -07:00
Christopher Snowhill 051b86cbaf [Core Data] Add access locking
Apparently we need this to prevent Core Data from stomping on itself
when another thread accesses it.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-15 07:00:29 -07:00
Christopher Snowhill faa546bc49 [Playlist Storage] Properly force migration
Old version users needed this, but it wasn't performed correctly.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-15 06:12:57 -07:00
Christopher Snowhill a5e6988af6 [Dependencies] Fix libogg version number
Apparently, the autotools package uses a different versioning scheme
than the CMake build. Also rebuilt and re-versioned libvorbis and
libvorbisfile.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-15 06:11:59 -07:00
Christopher Snowhill 97707e9b8f [libid3tag] Updated to avoid crash bug
Already updated to 0.16.1, but this fixes a crash bug in 0.16.1.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-15 05:10:58 -07:00
Christopher Snowhill 647c754311 [Audio Output] Greatly improve sample rate changes
Sample rate changes will now occur on exact sample boundaries, like they
are supposed to. Also, FreeSurround accounts for its output latency.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-15 03:34:10 -07:00
Christopher Snowhill 96acc738e3 Fix the Spotlight search panel
It was previously crashing horribly on adding search results. This makes
it actually functional, and renders it using a view-based table instead.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-15 03:02:41 -07:00
Christopher Snowhill 838c0d08e8 Significantly reduce stack memory usage
Oops, there were a lot of large local buffers in use here.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 17:28:46 -07:00
Christopher Snowhill 193af27e7e Remove obsolete helpbook document
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 16:11:20 -07:00
LennyLip b62d2237f8 ru FreeSurround pref string 2022-07-14 16:08:43 -07:00
Christopher Snowhill 64fc906f40 Widen the Updates setting dialog
Oops, forgot to deal with this.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 16:05:33 -07:00
Christopher Snowhill af64f93e99 [Audio Output] Make toggling DSPs safe
The DSPs should not be deinitialized from another thread, possibly while
they are currently processing.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 03:35:48 -07:00
Christopher Snowhill c708e30d8c [FreeSurround] Add configuration option to enable
It now needs translation of the new string.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 03:35:43 -07:00
Christopher Snowhill b95cb59a61 [Audio Processing] Increase thread stack size
Apparently, all these new changes with FreeSurround have pushed the
default 512KB thread stack size to the limit. And I'm not even using
stack variables, really, except for maybe the autoreleasepools.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 03:35:38 -07:00
Christopher Snowhill 1a0ab6723a [FreeSurround] Actually make it work
Apparently, the LFE channel is not being initialized at all if bass
redirection isn't enabled, and even if it is, it's uninitialized for a
great portion of the spectrum. Clear it all on every iteration.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 03:35:32 -07:00
Christopher Snowhill 08e76bc9f3 [Audio Output / Debugging] Fix sample logging
Fix the sample logging function that is optionally compiled into debug
versions.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 03:35:27 -07:00
Christopher Snowhill 4044646280 [Audio Processing] Update for new API
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 03:35:21 -07:00
Christopher Snowhill 7cb0054d77 [FreeSurround] Change another variable to const
This should be const anyway, as it's not written to.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 03:35:15 -07:00
Christopher Snowhill 8034054d72 [FreeSurround] Further improvements
Still not working, though.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 03:35:09 -07:00
Christopher Snowhill f05bf71320 [FreeSurround] Fix surround block size
The output implementation has a block size of 4096, so the class
implementation should also use that.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 03:34:48 -07:00
Christopher Snowhill ad9b0df8ed [FreeSurround] The rest of the implementation
This is the code that actually needs to be added to make it process
audio. This insertion makes the whole app crash when processing audio at
all. Weirdly, simply reverting these two files makes the audio code work
again. I can't explain it.

Also, commenting out CMAudioFormatDescriptionCreate makes it work, too.
There's something weird going on with that function.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 03:34:41 -07:00
Christopher Snowhill eb9d642192 [FreeSurround] Experimental implementation code
This is a working implementation of FreeSurround, but I can't get it to
work in the Cog code base, as the whole project crashes head over heels
if this code is inserted into the output chain.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 03:34:36 -07:00
Christopher Snowhill 34884d825a [Audio Processing] Move float32 converter
Move the Float32 converter to a different location, for any future plans
to support decoding audio files to common data for any other purpose.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 01:46:54 -07:00
Christopher Snowhill 1713e0df7c [FLAC Decoder] Change maximum buffer size
This should be more correct, especially considering that the library can
handle 32 bit files now.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 01:46:47 -07:00
Christopher Snowhill 273cdef6b9 [libFLAC] Remove debug overlay
There's a bug in the debug version of the library which does not occur
in the release build.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 01:46:37 -07:00
Christopher Snowhill 68d323545b [FLAC Decoder] Correctly handle zero length frames
Apparently, the decoder is capable of returning zero length frames
without having hit the end of the stream.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 01:46:28 -07:00
Christopher Snowhill c4e975319a Updated the help document a bit
Oops, it's been a while since I've touched this.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-13 04:56:45 -07:00
Christopher Snowhill 2c0c77dee2 [Translations] Tweaked the Preferences dialog
Now the Preferences panels are 110 points wider, and most things are
shifted around in ways to make the current set of translations fit into
the dialogs.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-13 04:37:40 -07:00
Christopher Snowhill 9fdefbf88a [Polish translation] Fixed total time formatter
Please do not translate the token names, they are used by the code to
look up which value to insert into the string.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-13 03:52:10 -07:00
Christopher Snowhill 32dcc5725b [Polish Translation] Fix the MainMenu strings file
The MainMenu.strings file had several mistyped quotation marks, and
several strings outside of quotation marks or comments, breaking the
menu translation entirely. This makes the translation actually work.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-13 03:52:01 -07:00
Christopher Snowhill 0518f99aaf [Polish translation] Activate localized strings
Template was missing from the project declaration. Oops.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-13 03:51:53 -07:00
Christopher Snowhill 6a5fa23807 XIB touched by Xcode
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-13 03:51:47 -07:00
Christopher Snowhill 29dfe593f1 [Ogg Vorbis/Opus] Fix tag clobber on play
Fixed the tags being overwritten by an "update" on non-streaming files.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-13 00:14:17 -07:00
Christopher Snowhill 8c4f9a7123 [Ogg Vorbis/Opus] Fix picture metadata handling
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-13 00:14:11 -07:00
Christopher Snowhill 5238965534 [Playlist Insert] Add a special case for filtered
Insertions which occur when the playlist is filtered can try to add past
the end of the playlist. Let's try to dodge that.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-13 00:14:06 -07:00
Christopher Snowhill 8c0abf5fab Update several of the dependencies
- Updated libFLAC to the latest Git commit, post 1.3.4.
- Updated libid3tag to 0.16.1.
- Updated libopus to the latest Git commit.
- Updated my FFmpeg libfdk-aac patch. Previously was overwriting
  memory when it was supposed to be skipping samples.

Also added debug versions of several of the libraries, and changed
the library extractor script to unpack the debug libraries over the
release set to add the particular matching debug versions when
building a debug build.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-13 00:13:07 -07:00
LennyLip 40cc36d8df Russian translation: new strings (#310)
* Update MainMenu.strings

* Update Preferences.strings
2022-07-11 19:59:51 -07:00
Christopher Snowhill 9462e9fb70 [MAD Decoder] Fix streamed MP3s not working
Due to a change designed to stop playback when the end of the file is
reached, which should not be checked for unseekable files, which are
web streams that only stop when the connection drops, or when the user
stops playback manually.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-11 19:50:27 -07:00
Christopher Snowhill 7adaeb4dd0 [HTTP Reader] Fix reading small static files
The reader was previously returning a failure state on open if the read
completed and fit entirely into the read buffer, which broke most remote
M3U or PLS playlists.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-11 19:50:21 -07:00
Christopher Snowhill 824675ae59 [Sandbox Broker] Only pop suggester for local URLs
Only pop up the path suggester and check on local file URLs, not remote
URLs, which shouldn't be checked, since they don't require sandbox
permission grants or bookmarks.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-11 19:50:16 -07:00
Christopher Snowhill 7a3d571492 Update About Window logo
The previous version was from an old render. Also apply some minor
tweaks to the scene.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-11 19:50:12 -07:00
Christopher Snowhill 25b90f300f [Shuffle] Fix Shuffle Album mode
Oops, I should have remembered that the data structure changes would
break this search predicate. Now apply the search predicate to the
playlist representation, which allows searching against the data blocks
using the PlaylistEntry property implementation.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-11 19:50:07 -07:00
Kevin López a217bbec1e Update README.md
Third's the charm.
2022-07-11 19:50:02 -07:00
Kevin López 8cf84e5b90 Update README.md 2022-07-11 19:49:55 -07:00
Kevin López fc6d454432 Update README.md 2022-07-11 19:49:50 -07:00
Kevin López ff16c583a0 Added Lokalise logo and instructions. 2022-07-11 19:49:45 -07:00
Christopher Snowhill a92b857161 Add missing strings to new translations
Still in need of translation from their respective authors.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-11 15:26:11 -07:00
LennyLip 1ed85a1c84 Russian lang fixes 2022-07-11 15:21:41 -07:00
LennyLip 2ecf110632 Russian translation 2022-07-11 15:21:35 -07:00
Christopher Snowhill 1ad6c78d83 Fix missing Polish declarations in project
There were still missing things.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-11 15:03:35 -07:00
Christopher Snowhill 6134cc47fe Activate Polish translation
The declarations for the translation were missing from the project files
so that it wasn't being used. Also added the missing strings to the
files that were already added to the translation.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-11 14:41:15 -07:00
Christopher Snowhill 33e1086842 [Visualization Controller] Minor guard check
Guard check in case visualization controller is called before any data
is posted to it.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-11 14:41:09 -07:00
Christopher Snowhill e6908ac945 [Headphone Filter] Minor changes
Change a variable type, to avoid a warning.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-11 14:41:02 -07:00
Christopher Snowhill 833e298d3d [Audio Converter] Minor change for format changes
This should also seal up any potential hole for problems if there's an
audio format change and no audio buffered.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-10 16:36:43 -07:00
Christopher Snowhill ac9e404b23 [Audio API] Repair the damage to the input chain
The input chain could hang up indefinitely, and MAD decoder didn't
indicate end of file properly.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-10 16:24:08 -07:00
pax 36040582ce first(really basic) open url panel translation. 2022-07-10 15:41:42 -07:00
pax 5e09d8f4ef translated equalizer strings, as well as the spotlight thing. 2022-07-10 15:41:34 -07:00
Christopher Snowhill 8d851e5bda [Input API] Change input readAudio method
readAudio now returns an AudioChunk object directly, and all inputs have
been changed to accomodate this. Also, input and converter processing
have been altered to better work with this.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-10 15:22:04 -07:00
Christopher Snowhill c43ebba424 [Downmixer] Only downmix to stereo if not stereo
When downmixing to mono, only downmix to stereo first if the source is
not already stereo.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-10 15:21:57 -07:00
Christopher Snowhill c32d14a048 [Project Files] Change most to enable modules
Most projects needed to be changed to enable C or Objective C modules.
Hopefully, this improves debugging.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-10 15:21:48 -07:00
Christopher Snowhill cbc1c85a71 [Cuesheet Input] Don't repeatedly open file
The input file has already been opened for decoding by an earlier step
in the testing process, reuse the decoder from that. Spares a decoder
open cycle on all embedded cuesheet supporting formats.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-10 15:21:42 -07:00
Christopher Snowhill f150065194 [HRTF] Force filtering of odd channel formats
Apparently, Apple's Spatial Audio processor doesn't really support weird
configurations like this. So we need to filter them down to stereo.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-09 18:42:03 -07:00
Christopher Snowhill 1c6db85555 [HRTF] Reverse Z axis of speakers above listener
Apparently, positive elevation is above, negative is below.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-09 18:41:07 -07:00
Christopher Snowhill 54238d29e4 Update some strings from Polish translation
Update missing strings, including one which was translated already in
the comments.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-09 16:24:39 -07:00
Kevin López 02f488c7bf [Spanish Translation] New strings
Signed-off-by: Kevin López Brante <kevin@kddlb.cl>
2022-07-09 16:24:26 -07:00
Kevin López c735c8f387 [Translation] Privacy policy URL can now be loaded from strings files
Signed-off-by: Kevin López Brante <kevin@kddlb.cl>
2022-07-09 16:24:16 -07:00
Christopher Snowhill 2251650b6e Add two missing strings from the Sparkle branch
Oops, those were missing.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-09 16:24:05 -07:00
Kevin López 079301025c [Spanish Translation] Updated string for new HRTF filter. 2022-07-09 16:23:54 -07:00
Christopher Snowhill f1381b11fd Implemented all new HRTF filter
This filter replaces the old one, and uses OpenAL Soft presets. Since
there aren't that many of those, I've left off configuration for now,
except to turn it on or off.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-09 16:23:43 -07:00
pax b0ec50e96e The Polish translation is mostly ready. 2022-07-09 16:00:12 -07:00
pax 7c3500a925 *added Polish translation, not fully ready, but there ya go. 2022-07-09 16:00:04 -07:00
Christopher Snowhill 413ec69ee4 Truncate text in playlist to a reasonable length
1024 characters aught to be enough for any playlist view.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-08 16:36:11 -07:00
Christopher Snowhill ef0dd921ab Remove the meta string cache
It wasn't helping anyway.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-08 16:36:01 -07:00
Kevin López 375eae4be2 [Spanish Translation] Added strings for new Info Inspector fields 2022-07-08 16:35:52 -07:00
Christopher Snowhill 1d3bc8045c Ditch the data compression
It just wasn't working out.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-08 16:35:44 -07:00
Christopher Snowhill 8ee4a04f3b Experimental tag support redesign
This redesign completely changes how tags are stored in memory. Now all
arbitrary tag names are supported, where possible. Some extra work will
be needed to support arbitrary tags with TagLib, such as replacing it
with a different library.

Translation pending for a couple of strings.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-08 16:35:34 -07:00
Christopher Snowhill 44e1fc5c49 [Playlist] Increase default font size to Regular
Regular control size ends up being 13 points, rather than the previous
default of Small control size, which ended up being 11 points.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-07 17:56:25 -07:00
Christopher Snowhill 7d8c2c53a0 Updated VGMStream to r1745-58-g828c6b09
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-07 16:44:15 -07:00
Christopher Snowhill 3a16a53bd1 [Path Suggester] Only process local file URLs
Playlist entries for non-file URLs should be ignored.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-07 16:38:23 -07:00
Christopher Snowhill 812da2e331 [Table Views] Add a safety check to cell creation
Cell creation may create some other type of view, somehow. No idea how.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-07 16:37:42 -07:00
Christopher Snowhill 3d1be2ca0d [File Tree] Significantly improve the watcher
- Switch to fine grained folder and file watching responses
- Navigate the PathNode tree using a fast dictionary of path components
- Quickly refresh the file tree by locating parent nodes to refresh

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-06 22:41:38 -07:00
Christopher Snowhill a0621b2537 [File Association] Correctly play files on open
When opening files from external association, such as opening files, or
opening folders with Cog, correctly obey the configured clear and play
or enqueue and play actions, by playing the new additions.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-06 17:04:02 -07:00
Christopher Snowhill 38beb9e930 [Playlist Loader] Fix Clear and Play action
Clear and Play was broken by the previous update. This fixes it.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-06 16:04:17 -07:00
Christopher Snowhill 0732b176fd [CI Scripts] Update to use `command -v`
Instead of `which`.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-06 14:44:05 -07:00
Christopher Snowhill 7e516f8cfe [Playlist Loader] Load files in the background
Load new playlist entries in the background, asynchronously.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-06 14:28:34 -07:00
Christopher Snowhill 36d8fa5ba5 Attempt for one last time to fix Xcode Cloud
This should hammer fix it. That'll show them for forcing a shallow
commit on me.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-06 04:38:54 -07:00
Christopher Snowhill 6984ce326c Attempt to fix Xcode Cloud again
This time, run the git fetch tags and genversion in the pre
xcodebuild script.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-06 04:23:15 -07:00
Christopher Snowhill 4956569206 Fix Xcode Cloud CI script to fetch tags
The script needs to fetch repository tags to function properly.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-06 04:13:30 -07:00
Christopher Snowhill 0c6e69015f Change Crashlytics symbol upload script
Script should not fail an otherwise successful build.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-06 03:37:52 -07:00
Christopher Snowhill adc159eb05 [Playback] Prevent erroneous file from repeating
Prevent Repeat Single from locking up the player on an unplayable file.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-06 02:20:20 -07:00
Christopher Snowhill 8f4fb4a44c [Sandbox Broker] Greatly speed up path resolving
The fragment remover need not detect whether the given path is a folder
or a file, as it is only removing hash marked fragments, not actually
removing the entire filename if it's only a file and not a folder like
the old versions used to. This greatly speeds up access, especially on
network shares.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-06 00:04:28 -07:00
Christopher Snowhill 9bf5bbba80 [Path Config] Allow multiple selection
This more easily allows removing multiple paths at once.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-06 00:03:07 -07:00
Christopher Snowhill aa7eb52231 [Path Config] Remove exact items by token id
Should use the exact token object to remove them, rather than doing a
path comparison.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-06 00:02:34 -07:00
Christopher Snowhill 1fb636ffd2 [Path Config] Properly prune the database
When cleaning up the path list, actually remove the pruned entries from
the Core Data storage, so they don't end up resolving to broken
bookmarks in the player, breaking playback on migrated configurations.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-05 23:47:47 -07:00
Christopher Snowhill 933b06d5dd [Path Config] Properly report broken bookmarks
Broken bookmarks weren't reporting as isStale, but rather, were failing
to resolve at all, and without this change, they were impossible to
detect in a migrated configuration.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-05 23:47:41 -07:00
Christopher Snowhill fceee35896 [Album Art] macOS Ventura natively supports AVIF
Disable the compiled in AVIF support there, as the OS supports it
natively. Keep the libraries for older OSes.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-05 23:47:34 -07:00
Christopher Snowhill 3958af0670 [FFmpeg Decoder] Further improve Matroska tags
Matroska defaults the date field to "date_recorded".

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-05 18:15:34 -07:00
Christopher Snowhill de72631ea5 [FFmpeg Decoder] Better handle Matroska tags
Matroska files use the "TITLE" field for the album when there are
chapters. Also, Matroska container uses shorter gain field names for
album and track gain, differentiating them by either being global or
specific to each chapter.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-05 17:41:18 -07:00
Christopher Snowhill a474b469fa [FFmpeg Decoder] Enable Metroska and WebM videos
Enable playback of video file extensions. Like other video formats
handled by the FFmpeg decoder, video streams are dropped in decode and
only the first audio stream is played.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-05 14:26:04 -07:00
Kevin López ebe301a9b8 [Spanish Translation] Updated strings in Appearance preferences
Signed-off-by: Kevin López Brante <kevin@kddlb.cl>
2022-07-05 13:54:57 -07:00
Christopher Snowhill aba75e2184 [FLAC Decoder] Safety decoding for tag reader
Use tag string encoding guessing for tag decoding, just in case there
are invalid files with non-standard encoded strings inside the tags, or
if there are streams with such tags. We don't want any crashes.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-05 13:54:45 -07:00
Christopher Snowhill c3ca29db0d [Spectrum] Enable switching style at runtime
It is now possible to switch the display style at runtime, while the
views are open.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-05 13:54:35 -07:00
Christopher Snowhill b0d1533b43 Interface builder touched by Xcode
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-05 13:54:24 -07:00
Christopher Snowhill c4790af7c0 Reformat spaces to tabs
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-05 13:54:17 -07:00
Dzmitry Neviadomski 81c98736fa Add preference to choose between SceneKit and DDB spectrum. 2022-07-05 13:54:10 -07:00
Christopher Snowhill cd45941a93 Greatly improve tag reading performance
Improve tag reading performance for Ogg, Opus, FLAC, TTA, and TAK, by
eliminating TagLib from the equation in those cases and just using the
respective file inputs to do the tag reading, which is apparently a lot
faster anyway.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-05 00:55:21 -07:00
Christopher Snowhill a1ea668a41 [Audio Player] Eliminate an avenue of lockups
Prevent the player from locking up in certain circumstances, by not
locking chainQueue the entire time this function is processing.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-05 00:53:55 -07:00
Christopher Snowhill e37d1d15b1 Remove unnecessary files from build and copy steps
Remove a single .inc include from CogAudio build phase, as it's included
but not compiled as Pascal like Xcode thinks. Also remove a bunch of
files from being copied into the resulting .framework and .bundle files
during link stage, as we don't need to distribute that stuff.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-04 23:58:58 -07:00
Christopher Snowhill 511f1a1937 [Playlist Loader] Revert background loader
This reverts most of 802a86a3d8, since it
didn't work anyway.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-04 18:08:45 -07:00
Christopher Snowhill 92bce537d1 [Playlist Loader] Fix background queue post action
Post action now returns the files.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-04 17:50:29 -07:00
Christopher Snowhill aeee143de2 [Equalizer] Fix support for arbitrary channels
The deinterleaved format was being specified incorrectly. Now it asks
for the correct format, which is deinterleaved, and the bytes per frame
or packet sizes are relative to a single channel's buffer, not all
buffers. Oops, that could have been more clear in the documentation.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-03 22:39:43 -07:00
Christopher Snowhill 9e66838b9b [Equalizer] Remove unnecessary code
This code is obsolete, remove it.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-03 22:37:52 -07:00
Christopher Snowhill 740613b95a [Sandbox] Ask for permission for container folders
Ask for permission to access the folders containing container files,
such as .CUE sheets, or .M3U or .PLS playlists.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-03 22:37:11 -07:00
Christopher Snowhill 969bf4f502 [M3U Playlist] Reformulate safety checks
Apparently someone managed to crash this with their playlists. No idea
how. Added more safety checks.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-03 14:32:58 -07:00
Christopher Snowhill 6a46389310 [Tag Reading] Moved external cover art reader
Moved external cover art reader to a place where it can be used for any
format, even formats unsupported by Metadata Reader interfaces.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-02 14:59:19 -07:00
Christopher Snowhill e41f4e8556 Update Info.plist.template
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-02 04:38:59 -07:00
Christopher Snowhill 4450f13a8e [Plugin Loader] Unregister loader callback
This callback should be unregistered when plugin loading completes,
otherwise we could end up processing bundles loaded by external stuff,
like Audio Units loading for MIDI playback.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-02 04:38:51 -07:00
Christopher Snowhill 310a6d44f9 [FFmpeg Input] Add .m4b and .m4r extensions
Add support for more file name extensions, so we don't fall back on
Core Audio Input for these files.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-02 04:38:43 -07:00
Christopher Snowhill e9f580cfbc [FFmpeg Input] Implement SoundCheck tag support
Implement support for the Sound Check tag format.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-02 04:38:35 -07:00
Christopher Snowhill bf1afd1923 [TagLib] Disable MP4 tag reader, as it can crash
This MP4 tag reader is buggy. Disable it in favor of FFmpeg decoder's
metadata reader.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-02 04:38:29 -07:00
Christopher Snowhill fce21785c2 [MIDI Input] No longer crash when seeking to the end
When seeking to the end of a file, no longer crash due to out
of range std::vector access, because it was using at() with an
offset of the array size. Instead, offset from the begin()
iterator return value, which allows offsetting to end().

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-02 04:38:23 -07:00
Kevin López baec7ed72d [Spanish Translation] Added new strings for synthesis settings
Signed-off-by: Kevin López Brante <kevin@kddlb.cl>
2022-07-02 01:27:06 -07:00
Christopher Snowhill 5d7a9798fe [Synthesizers] Implement default overrides
Default time, fade, loop count, and sample rate may now be overridden.

Synchronized preferences strings tables. Spanish translation of new
options pending, new releases won't be pushed until they're complete.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-02 01:27:01 -07:00
Christopher Snowhill 33a24d4d3e [Translation] Widen the Path Suggester column
Widen the enable column, for the Spanish description of the column
header.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-01 14:30:37 -07:00
Christopher Snowhill 18a8baf93b [Translation] Fix translation of Path Suggester
Also fix the fact that the XIB wasn't embedding the XIB/NIB in the app
as a result of the translation move.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-01 14:29:54 -07:00
Christopher Snowhill 01ef37c565 [Audio Output] Fix equalizer support
Equalizer was copying the output of the equalizer repeatedly to the
first output channel, instead of copying each channel correctly. This
had the effect of making the equalizer output adjusted audio to only the
left channel in stereo output, and possibly render the stream sounding
weird.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-01 14:11:27 -07:00
Christopher Snowhill a4f2664ca4 [Plugin Controller] Add Cue sheet safety check
If somehow a plugin doesn't load, skip cuesheet should skip it anyway,
as we don't want any recursive loops.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-01 13:38:49 -07:00
Christopher Snowhill d9f111d735 [Audio Output] Remove unnecessary variables
These variables weren't being used anyway, so remove them.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-01 12:43:25 -07:00
Kevin López b701fa712e [Translation] The Big Translation Commit
- Plugs the Total duration text to macOS's localization technology
- Adds a proper Spanish translation
- Adapts certain dialogs to make them more suitable for translation

Signed-off-by: Kevin López Brante <kevin@kddlb.cl>
2022-07-01 12:43:18 -07:00
Christopher Snowhill 1b0e765d38 [libOpenMPT] Remove unnecessary compile option
ENABLE_ASM isn't even used anywhere in the library any more.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-01 01:02:17 -07:00
Christopher Snowhill 59bf8c6cf9 Move all dialog XIBs for translation
Make it easier to translate the relevant dialogs now.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-01 00:39:37 -07:00
Christopher Snowhill d4b440d6a5 Updated credits file with Patron preference
Oops, missed that Patreon message, because Patreon did not email me.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-01 00:17:01 -07:00
Christopher Snowhill 9e02492dc2 Update Credits.html in Spanish placeholder
Spanish translation really needs doing some time soon, maybe.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-01 00:12:56 -07:00
Christopher Snowhill da1973bcd9 Build libOpenMPT from source once again
Bundle libOpenMPT as a dynamic framework, which should be safe once
again, now that there is only one version to bundle. Also, now it is
using the versions of libvorbisfile and libmpg123 that are bundled with
the player, instead of compiling minimp3 and stbvorbis.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-30 22:56:52 -07:00
Christopher Snowhill 8b8fbad6d9 Updated libOpenMPT to version 0.6.5-pre.1+r17609
This allows us to eliminate the requirement to continue bundling version
0.5.x of libOpenMPT for compatibility with macOS 10.13 through 10.14.x.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-30 21:28:44 -07:00
Christopher Snowhill 099588b7bd Restore the File Tree, now with a chooser button
Revert "Remove the file tree, as Sandbox does not permit"

This reverts commit 35400e1320.

This also changes how the File Tree choosing works.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-30 16:59:35 -07:00
Christopher Snowhill 73c4360b1d [Info Inspector] Improve formatting of sample rate
Sample rate now has a locale independent formatting, and no longer uses
scientific notation for large numbers.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-30 00:28:30 -07:00
Christopher Snowhill da21cd7341 [Play Counts] Fix reporting play counts
Play counts are guaranteed to be reported on the correct track now.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-29 23:28:11 -07:00
Christopher Snowhill 27478e5df2 Update libVGM and BASSMIDI, SF3 support
BASSMIDI now includes SF3 support, as well as several other changes.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-29 23:27:28 -07:00
Christopher Snowhill d739e68e8e [Sandbox] Synchronize write accesses to storage
Synchronize writing to the bookmark storage to the main thread.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-29 19:41:03 -07:00
Christopher Snowhill 4ce180fb2a [Sandbox] Fix URL fragment removal function
This should be deleting from the #, including the #.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-29 19:39:47 -07:00
Christopher Snowhill 3c0ccd9d46 [Context Menu] Hook up Reset Play Counts item
Actually hook up the Reset Play Counts menu item so it actually does
something instead of just sitting there looking pretty.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-29 12:42:12 -07:00
Christopher Snowhill b24b9744c1 [Sandbox Config] Correctly test paths for files
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-29 12:11:01 -07:00
Christopher Snowhill 61778b7165 [Sandbox] Remove startup folder consent prompt
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-29 12:03:18 -07:00
Christopher Snowhill 7d26150c26 [Sandbox] Support bookmarking individual files
Individually added files, directly opened by the user, may now store
bookmarks in settings.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-29 12:00:25 -07:00
Christopher Snowhill 35400e1320 Remove the file tree, as Sandbox does not permit
The Sandbox does not permit such controls to exist.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-29 12:00:12 -07:00
Kevin López 3d94978f82 [Info Inspector] Made fields selectable, and fixed blending issue with
album art

Signed-off-by: Kevin López Brante <kevin@kddlb.cl>
2022-06-29 11:57:32 -07:00
Kevin López fe7c424843 [About Window] Fixed appearance for systems without Dark Mode
Signed-off-by: Kevin López Brante <kevin@kddlb.cl>
2022-06-29 11:57:26 -07:00
Christopher Snowhill 1a4c140708 [Sandbox] Handle file tree path config better
Handle the configuration better, by adding the path to the grants list
if it is newly configured.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-29 00:31:54 -07:00
Christopher Snowhill 29c070a616 [Sandbox] Automatically save folder bookmarks
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-28 23:15:08 -07:00
Christopher Snowhill 8b7418857d [Sandbox] Reduce entitlements granted by default
Since App Store approval decided these suddenly matter.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-28 23:14:53 -07:00
Christopher Snowhill a35459719d [Sandbox] Show grant dialog on launch if empty
If there are no configured paths, show the grant page on every startup.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-28 23:14:21 -07:00
Christopher Snowhill 802a86a3d8 [Playlist Loading] Process messages while loading
Process main queue messages by handling the loading in a background
queue, and sync it to the main thread periodically, while pausing to
wait for the results. This allows the file open dialog to return
immediately, and display loading progress on the status bar.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-28 20:28:10 -07:00
Christopher Snowhill f8d2837c4e [Playlist View] Change ratings column to variable
The ratings column needs to be made variable width, for variable font
sizes. If anyone knows how to force the width to fit the current text,
I'm open to suggestions.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-28 20:27:57 -07:00
Christopher Snowhill 112366c850 [Crash Handling] Enable exceptions for debugging
Debug builds should have exceptions enabled, rather than crashing.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-28 20:27:43 -07:00
Christopher Snowhill a1a8607a84 [About Dialog] Add needed WebKit framework
This is needed for macOS older than 11.0? 10.15? to open the About
dialog without crashing.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-28 04:26:55 -07:00
Christopher Snowhill 690153f561 [Play Info] Implement track rating system
The track ratings are stored in the same stats table as the play counts.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-28 01:55:30 -07:00
Christopher Snowhill b33e3ff6b3 [Audio Output] Restart correct track
When restarting playback on the current track, restart the correct
track, in case restarting near the end of it.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-27 22:03:02 -07:00
Christopher Snowhill bedfac4e33 [Play Counts] Add option to (mass) reset counts
Add option to reset counts for all selected tracks on the playlist.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-27 21:50:14 -07:00
Christopher Snowhill 66102a6cda [Play Counts] Commit play count edits to storage
Was calling commitEditing rather than commitPersistentStore, whoops.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-27 21:49:32 -07:00
Christopher Snowhill b36ebfe740 Resource templates touched by Xcode
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-27 21:48:43 -07:00
Christopher Snowhill 2ed78a0639 [Play Counts] Track play counts of correct track
Track play counts for the correct track, even on short tracks. Also
correctly track the play count of the last played item in the play queue
which stops with bufferChain set to nil, so the previous iteration was
not tracking it.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-27 21:46:36 -07:00
Christopher Snowhill ae019409c5 [File Tree] Pop permission grant on setting root
Setting the root path should now pop up a permission grant dialog.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-27 16:17:19 -07:00
Christopher Snowhill 66262c2a71 [Sandbox Broker] Synchronize full access operation
Full access should be synchronized, otherwise rapid access to the same
path from different threads will cause crashes.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-27 01:00:11 -07:00
Christopher Snowhill f567750d56 [Metadata Cache] Actually run cleanup thread
Previously, the cleanup thread was not being run. Also, only reset the
metadata deduplication store when the cache is first emptied.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-27 00:58:56 -07:00
Christopher Snowhill 2a99bb076f [Audio Output] Change converter back to Obj-C
Change converter source file back from Objective-C++ to Objective-C.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-27 00:34:19 -07:00
Christopher Snowhill dd65665990 [Sandbox Broker] Bypass entitled paths
Include entitlement granted user folders in the permission check, so
that if the file or folder is nested under one of them, it allocates a
static permission object, rather than querying the list of configured
paths every time. This also prevents the player from popping open the
path grant / suggester dialog every time a default path is in the file
set listed, which should provide some relief to most users.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 23:52:38 -07:00
Christopher Snowhill c477fbf553 Attempt to fix Xcode Cloud CI
Try to generate the Info.plist before xcodebuild runs.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 22:59:31 -07:00
Christopher Snowhill 03b3b43cfe Update versioning setup
Versioning now happens before building Cog itself, and goes
into the Info.plist in the project directory. The original
file became a template file which is altered any time a
build occurs.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 22:08:42 -07:00
Christopher Snowhill 9d8e278a57 Update debug.yml
Switch to building on macos-12
2022-06-26 22:07:12 -07:00
Christopher Snowhill ed9e352543 Add Package.resolved back to repo
Guess we can't use Github actions now, because this file breaks those.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 20:25:41 -07:00
Christopher Snowhill 16fdc1de6a Add CI scripts for Xcode Cloud
Add a post clone script for Xcode Cloud

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 20:22:54 -07:00
Christopher Snowhill fc37e96099 Automatically unpack libraries before building
This required adding the included script in every project that links to
one of the bundled libraries. The script is designed to sleep for a
while if another thread is already extracting the libraries. The script
uses a temporary file as an extraction step lock, so other instances
sleep, and then detect the libraries.updated file, which is created
before the lock is removed.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 20:11:52 -07:00
Christopher Snowhill 03a2c0c16e Updated VGMStream to r1745-47-gfa55119d
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 15:11:23 -07:00
Christopher Snowhill 206a3e42e7 [Equalizer] Prevent crash on stop
Wait for the equalizer to be shut down properly by the main thread
before destroying it. Otherwise, the main thread could crash on stop,
due to accessing the equalizer handle while it's being torn down in the
output thread.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 14:47:34 -07:00
Christopher Snowhill 6f6b5d6986 [Visualization System] Change API a bit
Now the API makes both PCM and FFT data optional, and will do nothing if
neither are requested. Also, it now supports a latency offset in seconds
with floating point precision. The two built-in visualizations currently
request zero larency. Increasing the latency asks for even older samples
while specifying a negative count requests samples from the "future"
relative to what the listener is hearing.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 05:39:24 -07:00
Christopher Snowhill 038b0b8067 [Play Events] Don't bug on end of playlist
Don't bug out on end of playlist, when didBeginStream will receive a nil
track pointer, which should result in unsetting the current track in the
player, and not send a DidBegin notification to everything, including
the visualization views' event handlers.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 05:28:43 -07:00
Christopher Snowhill a57827f4da [Play Counts] Fix counts for tracks with subsongs
Fix counts for tracks with subsongs from piling all the counts onto the
first subsong seen, by using the URL fragment in the filename check and
storage.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 04:37:41 -07:00
Christopher Snowhill 39be3ab962 [Audio Output] Fix for previous commit
This fixes the problem caused by the following commit:

050aaaf852

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 03:57:19 -07:00
Christopher Snowhill 17df6cde4f Fix compilation
Oops, that last suggester change broke compilation.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 03:08:20 -07:00
Christopher Snowhill 2945de085d [Sandbox] Don't try to grant access to container
Do not try to grant access to the app's container folder when searching
for paths to add.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 02:58:25 -07:00
Christopher Snowhill c2ef7d0e61 [Sandbox] Compare to the actual user paths
Remove the sandbox reference, because the user will add folders outside
the sandbox, and we have entitlements to access these folders.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 02:56:44 -07:00
Christopher Snowhill 96a7255779 [Sandbox] Suggest URLs that are contained in CUEs
Cuesheets can now expose which URLs they contain, which may help with
sandbox path configuration. That is, if the CUE sheets are already
readable.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 02:54:19 -07:00
Christopher Snowhill 050aaaf852 [Visualization] Resample more audio if present
If upsampling the audio by a significant factor, it may be necessary to
process more than one buffer at a time, rather than lose input.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 01:09:55 -07:00
Christopher Snowhill 5f52a4be81 [Audio Output] Better handle latency oddities
The visualization buffer now holds up to 45 seconds of loop, and the
latency measurement code now caps this at 30 seconds, and restarts the
output if latency exceeds 30 seconds, such as if a sound output is
reset.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 01:09:01 -07:00
Christopher Snowhill 5f2335b796 [Audio Output] Play last track and stop correctly
Play last track up until it actually ends, and stop on command.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-25 06:42:56 -07:00
Christopher Snowhill d33475953e [FFmpeg Decoder] Don't post redundant meta event
Don't post a metadata event on open, because inputs will relay it to the
player as an early notification bubble, which is unwanted.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-25 06:05:03 -07:00
Christopher Snowhill 7a56447271 [Audio Output] Fix serious memory leakage
For one thing, the example code I followed was Swift and handled auto
releasing handles in the background, while Objective-C requires manual
handle reference management.

For two, there was no autoreleasepool around the block handling the
input audio chunks, which need to be released as they are pulled out and
disposed of. This also contributed to memory leakage.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-25 06:00:11 -07:00
Christopher Snowhill b86ec3340f [fdkaac] Update libfdk-aac to 2.0.2 with patches
Update fdk-aac library in dependencies package.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-25 05:13:22 -07:00
Christopher Snowhill 36c82a61e7 [Audio Output] Fix serious deadlock issue
There was a serious deadlock issue. Now it is fixed. Whew.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-25 05:12:43 -07:00
Christopher Snowhill ab13b66755 [InputNode] Syntax code fix
This code was misformatted.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-25 05:10:33 -07:00
Christopher Snowhill 86de03a1ab [Play Count Info] Tabulate first seen info later
Tabulate first seen information when loading the metadata, rather than
when first adding the tracks to the playlist. This should fix first seen
information when metadata is available, as the information will be
useless without track titles.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-25 02:40:05 -07:00
Christopher Snowhill 0f923e6072 [Cuesheet] Greatly improve loading performance
Cuesheets were invoking a seek operation on open, rather than on first
playback, and this has a heavy toll on FFmpeg audio formats, apparently.
Defer the initial seek to the first readAudio call, and do not invoke it
if a seek was already called on that input session.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-25 02:38:17 -07:00
Christopher Snowhill cb2ce5675a [FFmpeg] Fix chapter handling and seeking
Fix chapter startup, and chapter seeking.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-25 02:36:14 -07:00
Christopher Snowhill 1f56e5ef5a [FFmpeg] Seek including skip samples
This is essential for chapters, as otherwise, we would be skipping an
awful lot of samples every chapter, or every seek within a chapter.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-25 01:43:36 -07:00
Christopher Snowhill 2663b5007d [FFmpeg] Support files with chapters
Support file chapters, including metadata reading for each chapter.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-25 01:35:07 -07:00
Christopher Snowhill 72572c9c7f [FFmpeg] Deduce the length from the container
Determine the length of the file from the container, rather than the
individual audio stream. The former is more likely to be set than the
latter is.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-25 00:05:57 -07:00
Christopher Snowhill 3de7a34eb8 [FFmpeg] Update FFmpeg library and decoder plugin
Update based on newest changes from upstream.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 23:51:12 -07:00
Christopher Snowhill 86d8f04966 [Audio Output] Correctly configure WAVE layouts
Correctly configure AVFoundation with the channel layouts supported by
WAVEFORMATEXTENSIBLE speaker position flags, which includes varied
formats supported by FFmpeg and Core Audio inputs.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 23:29:32 -07:00
Christopher Snowhill b55955ef1c [Audio Output] Correctly delay layout updates
Channel layout updates should be delayed when resampling, just like
sample format changes are.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 23:29:18 -07:00
Christopher Snowhill 8e1175bbd4 [FFmpeg] Update minimum platform for x86_64
Update minimum platform version to macOS 10.13.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 22:33:50 -07:00
Christopher Snowhill 62e2880b49 [FFmpeg] Enable TrueHD decoder and demuxer
Oops, somehow I didn't enable TrueHD support.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 22:22:29 -07:00
Christopher Snowhill 1ac3e5cd22 [FFmpeg] Update libfdk-aac fixed point patch
Update this patch to the latest FFmpeg master source, and update to use
fmtconvert instead of a naive for loop.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 22:18:25 -07:00
Christopher Snowhill d2eb4af3d5 [Audio Output] Stop immediately, and fix deadlocks
Stop output when requested, except on natural completion of the last
track in the play queue. Also fix deadlocks with stopping and
restarting.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 19:15:20 -07:00
Christopher Snowhill 50b7390181 [Vorbis / Opus] Do not assume text encoding
Stream metadata encoding may not be UTF-8, even though the Vorbis
Comment specification clearly calls for this.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 19:15:15 -07:00
Christopher Snowhill abf80c19ac Move static and dynamic libaries to archive
Please remember to unpack the archive before building, and
if it is updated by a future version.
2022-06-24 17:04:57 -07:00
Christopher Snowhill b21a02fe1b [Sandbox] Change preference dialog descriptions
Make the descriptions more apt to what they do.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 17:04:52 -07:00
Christopher Snowhill dd35639174 [OpenMPT / OpenMPT Legacy] Fix include paths
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 17:04:48 -07:00
Christopher Snowhill 43433c244e [mpg123] Fix include paths 2022-06-24 17:04:44 -07:00
Christopher Snowhill 870a5afed7 [Sandbox Broker] Fix deadlock and crash
The crash was because we weren't copying the results array before
iterating over it, and the deadlock was because this was forced to go
through the main thread, rather than going through its calling thread,
which could lock up if the main thread was busy working with the Sandbox
Broker object.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 17:04:39 -07:00
Christopher Snowhill b9ef5853d6 [Metadata] Commit first seen date for whole batch
Commit only once the entire batch is loaded and processed. Also commit
using the correct function.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 17:04:35 -07:00
Christopher Snowhill 1a9c73d166 [OpenMPT / vgmstream] Made libraries pre-built
Made the OpenMPT / legacy OpenMPT and mpg123 libraries pre-built.
Changed the OpenMPT and vgmstream plugins to import the libraries as
they are now. Made mpg123 embedded and imported by the main binary,
since it's now shared by two plugins.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 17:04:30 -07:00
Christopher Snowhill ec393d186a [Sandbox Broker] Copy results array
Hopefully this heads off a crash elsewhere.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 17:04:16 -07:00
Christopher Snowhill dfb773e9cb [Audio Output] Properly handle end of playlist
Handle audio on the end of the playlist, flushing playback until all
output stops.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 03:46:01 -07:00
Christopher Snowhill 438b142558 [Audio Output] Synchronize access, report latency
Report resampler latency properly, and synchronize access to the
resampler objects.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 03:45:16 -07:00
Christopher Snowhill 26a63e85b7 [Visualization] Resample all visualizer audio
Visualizer audio is now resampled to 44100 Hz, for consistency across
the system.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 03:43:50 -07:00
Christopher Snowhill ccbeaf16dc [Audio Output] Resample unsupported sample rates
These rates are too high for Apple's output routines, for some reason.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 02:46:23 -07:00
Christopher Snowhill cc5de69e9f [Core Data Store] Fix startup playlist pruning
The playlist was being pruned of entries marked for deletion, but they
were not being pruned from the set that was then added to the player.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 00:34:30 -07:00
Christopher Snowhill 80adb85b36 [Path Suggester] Automatically pop where required
The Path Suggester will now automatically open when new files are added
to the playlist and a given path is not in the sandbox settings. It will
also pop for both the File Tree and MIDI SoundFont path configuration
settings being changed.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 00:29:50 -07:00
Christopher Snowhill f3f3d436ba [Sandbox Broker] Synchronize storage access
Synchronize storage access to main thread only, to prevent enumeration
from hitting a case of the main thread writing to the storage.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-23 23:35:26 -07:00
Kevin López be6453e048 [Sandbox] Fixed path suggester window
Added a title to the window, make the table view resize properly, and
remove the font size inheritance from the main window.

Signed-off-by: Kevin López Brante <kevin@kddlb.cl>
2022-06-23 23:26:16 -07:00
Christopher Snowhill 8af32e8d2e Replace Core Audio output with Core Media runtime
The output now uses AVSampleBufferAudioRenderer to play all formats, and
uses that to resample. It also supports Spatial Audio on macOS 12.0 or
newer. Note that there are some outstanding bugs with Spatial Audio
support. Namely that it appears to be limited to only 192 kHz at mono or
stereo, or 352800 Hz at surround configurations. This breaks DSD64
playback at stereo formats, as well as possibly other things. This is
entirely an Apple bug. I have reported it to Apple with reference code
FB10441301 for reference, in case anyone else wants to complain that it
isn't fixed.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-23 23:22:41 -07:00
Christopher Snowhill 5b6dacd29c Cog now requires macOS 10.13 as a minimum version
All optional fallback code for older versions has also been removed, and
everything now assumes 10.13.0 or newer. Some cases are still included
for point releases, such as 10.13.2.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-22 22:54:32 -07:00
Christopher Snowhill ff44bc4d34 Updated VGMStream to r1745-37-g776c4d8c
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-22 19:33:32 -07:00
Christopher Snowhill 62824a94bd Serialize persistent store update to main thread
This needs to be called on the main thread, as something may or may not
be enumerating over the data while this thread decides to call it.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-22 19:11:32 -07:00
Christopher Snowhill 903bc9cba5 [Playlist Info Loader] Do not clear if loading
Do not clear the progress indicator if a loading task is already running
in the background, but instead return without doing anything.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-22 19:05:27 -07:00
Christopher Snowhill f274a8ef73 Sync version number with main branch 2022-06-22 16:28:08 -07:00
Kevin López 0317f2a649 [About Window] Fix
Pull request #281 by @nevack.
2022-06-22 16:11:59 -07:00
Kevin López b484a0be44 [About Window] Reorganized credits and added @nevack and myself in them
Signed-off-by: Kevin López Brante <kevin@kddlb.cl>
2022-06-22 16:11:38 -07:00
Dzmitry Neviadomski 36a9411b14 Fix runtime warnings in Window/AboutWindowController.xib
Fix typo in File Owner class name and remove absent outlet.
2022-06-22 16:11:24 -07:00
Kevin López 64fefce18d Merge pull request #280 from losnoco/nevack/about-window
AboutWindow adjustments
2022-06-22 16:07:16 -07:00
Dzmitry Neviadomski 3a6e41cabd AboutWindow adjustments
Allow opening links in default browser
Close window on Esc
Add rounded corners
2022-06-22 16:06:26 -07:00
Christopher Snowhill 632ba36f13 Changed updater script to handle new version strings
New version strings are in a different place, and Sparkle will no longer
be including the Git hash in the CFBundleVersion query, so we must get
it from the ZIP filename.
2022-06-22 01:18:43 -07:00
Christopher Snowhill 271b9b34d0 One last attempt to fix CI
This should fix building. I don't know how I missed those.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-21 23:51:05 -07:00
Christopher Snowhill 8d031f394b Assign blank development team in project files
Hopefully this blank assignment will spare these files from being
touched by Xcode again in the future, when the variable in question is
imported from a developer supplied configuration file.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-21 23:27:53 -07:00
Christopher Snowhill f2c6ae39c3 Remove developer supplied configuration file
This file should not be referenced directly by projects, otherwise it
will be expected to exist, even in CI.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-21 23:26:51 -07:00
Christopher Snowhill bb95270747 [Volume Control] Only initialize view once
Only initialize viewController once, the first time the volume control
is opened. Re-initializing it can cause an error assigning it as first
responder to the volume slider popover view.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-21 22:52:05 -07:00
Christopher Snowhill aa36e3ce10 Completely overhaul code signing practices
Redesign the code signing from the ground up. Now all bundles and their
embedded frameworks import the Shared.xcconfig file and enable its
settings, so they may be signed with Apple Development instead of sign
to run locally. This apparently isn't necessary for frameworks which are
embedded in the main app bundle directly, only for the bundles and their
frameworks.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-21 22:42:33 -07:00
Christopher Snowhill da8a4dffdf Remove deep forced code signing option
This option should no longer be needed for anything.
2022-06-21 19:40:15 -07:00
Kevin López a4692b80a4 [Main Menu] Added Privacy Policy link in App Menu
Signed-off-by: Kevin López Brante <kevin@kddlb.cl>
2022-06-21 19:31:06 -07:00
Kevin López de5cce8351 [About Dialog] Switched to WebView for credits
Signed-off-by: Kevin López Brante <kevin@kddlb.cl>
2022-06-21 19:30:58 -07:00
Christopher Snowhill 05da7450da [Crashlytics] Require asking user consent
Require asking user consent for data transmission on first launch, or
otherwise disable sending crash reports by default.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-21 19:16:23 -07:00
Christopher Snowhill 2b8156e86c [Info Plist] Auto format XML escapes
Automatically format any XML escapes of file type association names.
Adjust Info.plist to account for this change.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-21 19:14:00 -07:00
Christopher Snowhill d59b5335e9 Revert "Removed Sparkle"
This reverts commit b54ee58ec3.
2022-06-21 18:00:30 -07:00
Christopher Snowhill bc9e7b5d67 Revert "Remove stray entitlement from Sparkle"
This reverts commit 5ea6c9dde7.
2022-06-21 18:00:09 -07:00
203 changed files with 7757 additions and 13 deletions

View File

@ -66,6 +66,11 @@
- (IBAction)delEntries:(id)sender; - (IBAction)delEntries:(id)sender;
- (IBAction)savePlaylist:(id)sender; - (IBAction)savePlaylist:(id)sender;
- (IBAction)openLiberapayPage:(id)sender;
- (IBAction)openPaypalPage:(id)sender;
- (IBAction)openKofiPage:(id)sender;
- (IBAction)openPatreonPage:(id)sender;
- (IBAction)privacyPolicy:(id)sender; - (IBAction)privacyPolicy:(id)sender;
- (IBAction)feedback:(id)sender; - (IBAction)feedback:(id)sender;
@ -102,6 +107,8 @@
- (void)showPathSuggester; - (void)showPathSuggester;
+ (void)globalShowPathSuggester; + (void)globalShowPathSuggester;
- (IBAction)checkForUpdates:(id)sender;
@property NSWindow *mainWindow; @property NSWindow *mainWindow;
@property NSWindow *miniWindow; @property NSWindow *miniWindow;

View File

@ -28,6 +28,8 @@
#import "Shortcuts.h" #import "Shortcuts.h"
#import <MASShortcut/Shortcut.h> #import <MASShortcut/Shortcut.h>
#import <Sparkle/Sparkle.h>
#import "PreferencesController.h" #import "PreferencesController.h"
@import Firebase; @import Firebase;
@ -38,6 +40,22 @@ BOOL kAppControllerShuttingDown = NO;
static AppController *kAppController = nil; static AppController *kAppController = nil;
@interface SparkleBridge : NSObject
+ (SPUStandardUpdaterController *)sharedStandardUpdaterController;
@end
@implementation SparkleBridge
+ (SPUStandardUpdaterController *)sharedStandardUpdaterController {
static SPUStandardUpdaterController *sharedStandardUpdaterController_ = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedStandardUpdaterController_ = [[SPUStandardUpdaterController alloc] initWithUpdaterDelegate: nil userDriverDelegate: nil];
});
return sharedStandardUpdaterController_;
}
@end
@implementation AppController { @implementation AppController {
BOOL _isFullToolbarStyle; BOOL _isFullToolbarStyle;
} }
@ -165,9 +183,15 @@ static AppController *kAppController = nil;
#endif #endif
[FIRApp configure]; [FIRApp configure];
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.crashlyticsConsented" options:(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew) context:kAppControllerContext]; [[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.crashlyticsConsented" options:(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew) context:kAppControllerContext];
#ifdef DEBUG
// Prevent updates automatically in debug builds
[[[SparkleBridge sharedStandardUpdaterController] updater] setAutomaticallyChecksForUpdates:NO];
#endif
[[[SparkleBridge sharedStandardUpdaterController] updater] setUpdateCheckInterval:3600];
[[totalTimeField cell] setBackgroundStyle:NSBackgroundStyleRaised]; [[totalTimeField cell] setBackgroundStyle:NSBackgroundStyleRaised];
[self.infoButton setToolTip:NSLocalizedString(@"InfoButtonTooltip", @"")]; [self.infoButton setToolTip:NSLocalizedString(@"InfoButtonTooltip", @"")];
@ -538,6 +562,22 @@ static AppController *kAppController = nil;
[theApplication replyToOpenOrPrint:NSApplicationDelegateReplySuccess]; [theApplication replyToOpenOrPrint:NSApplicationDelegateReplySuccess];
} }
- (IBAction)openLiberapayPage:(id)sender {
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://liberapay.com/kode54"]];
}
- (IBAction)openPaypalPage:(id)sender {
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://www.paypal.com/paypalme/kode54"]];
}
- (IBAction)openKofiPage:(id)sender {
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://ko-fi.com/kode54"]];
}
- (IBAction)openPatreonPage:(id)sender {
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://www.patreon.com/kode54"]];
}
- (IBAction)privacyPolicy:(id)sender { - (IBAction)privacyPolicy:(id)sender {
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:NSLocalizedString(@"PrivacyPolicyURL", @"Privacy policy URL from Iubenda.")]]; [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:NSLocalizedString(@"PrivacyPolicyURL", @"Privacy policy URL from Iubenda.")]];
} }
@ -783,4 +823,8 @@ static AppController *kAppController = nil;
[kAppController showPathSuggester]; [kAppController showPathSuggester];
} }
- (IBAction)checkForUpdates:(id)sender {
[[SparkleBridge sharedStandardUpdaterController] checkForUpdates:[[NSApplication sharedApplication] delegate]];
}
@end @end

View File

@ -1380,6 +1380,11 @@
<action selector="showWindow:" target="Hd4-Wy-Rfl" id="xfd-8T-SL4"/> <action selector="showWindow:" target="Hd4-Wy-Rfl" id="xfd-8T-SL4"/>
</connections> </connections>
</menuItem> </menuItem>
<menuItem title="Check for Updates..." id="302">
<connections>
<action selector="checkForUpdates:" target="226" id="jEY-i9-qwZ"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="1100"> <menuItem isSeparatorItem="YES" id="1100">
<modifierMask key="keyEquivalentModifierMask" command="YES"/> <modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem> </menuItem>
@ -1390,6 +1395,45 @@
</connections> </connections>
</menuItem> </menuItem>
<menuItem isSeparatorItem="YES" id="0ig-xg-gkg"/> <menuItem isSeparatorItem="YES" id="0ig-xg-gkg"/>
<menuItem title="Donate" id="751">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Donate" id="kue-p2-G0Y">
<items>
<menuItem title="LiberaPay" id="nyW-nI-abw">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="openLiberapayPage:" target="226" id="pS6-Hj-tIm"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="Mbf-yW-WGC"/>
<menuItem title="One time" enabled="NO" id="wLp-NA-5u2">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title="PayPal" id="xcs-tx-Viz">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="openPaypalPage:" target="226" id="oxr-P1-35O"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="txC-Jd-Gez"/>
<menuItem title="Recurring" enabled="NO" id="iRb-7e-iMC">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title="Ko-fi" id="CVM-rp-UJe">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="openKofiPage:" target="226" id="gax-6q-SuW"/>
</connections>
</menuItem>
<menuItem title="Patreon" id="NXj-oA-q3F">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="openPatreonPage:" target="226" id="LFz-4J-b6o"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Send Feedback..." id="303"> <menuItem title="Send Feedback..." id="303">
<connections> <connections>
<action selector="feedback:" target="226" id="GSH-G5-qM1"/> <action selector="feedback:" target="226" id="GSH-G5-qM1"/>

View File

@ -2,6 +2,11 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>com.apple.security.temporary-exception.mach-lookup.global-name</key>
<array>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)-spks</string>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)-spki</string>
</array>
<key>com.apple.security.app-sandbox</key> <key>com.apple.security.app-sandbox</key>
<true/> <true/>
<key>com.apple.security.cs.allow-jit</key> <key>com.apple.security.cs.allow-jit</key>

View File

@ -145,6 +145,8 @@
837DC931285B3F790005C58A /* DataModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 837DC92F285B3F790005C58A /* DataModel.xcdatamodeld */; }; 837DC931285B3F790005C58A /* DataModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 837DC92F285B3F790005C58A /* DataModel.xcdatamodeld */; };
8381A09227C5F72F00A1C530 /* SHA256Digest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8381A09127C5F72F00A1C530 /* SHA256Digest.m */; }; 8381A09227C5F72F00A1C530 /* SHA256Digest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8381A09127C5F72F00A1C530 /* SHA256Digest.m */; };
8384914018083E4E00E7332D /* filetype.icns in Resources */ = {isa = PBXBuildFile; fileRef = 8384913D18083E4E00E7332D /* filetype.icns */; }; 8384914018083E4E00E7332D /* filetype.icns in Resources */ = {isa = PBXBuildFile; fileRef = 8384913D18083E4E00E7332D /* filetype.icns */; };
838F851E256B4E5E00C3E614 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 838F851D256B4E5E00C3E614 /* Sparkle.framework */; };
838F851F256B4E8B00C3E614 /* Sparkle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 838F851D256B4E5E00C3E614 /* Sparkle.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
83922FBA286B1AA900A0B039 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83922FB6286B1AA900A0B039 /* WebKit.framework */; }; 83922FBA286B1AA900A0B039 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83922FB6286B1AA900A0B039 /* WebKit.framework */; };
839614A2286ED97200D3EEDB /* AboutWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 839614A0286ED97200D3EEDB /* AboutWindowController.xib */; }; 839614A2286ED97200D3EEDB /* AboutWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 839614A0286ED97200D3EEDB /* AboutWindowController.xib */; };
839614AD286EDA5C00D3EEDB /* SpectrumWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 839614AB286EDA5C00D3EEDB /* SpectrumWindow.xib */; }; 839614AD286EDA5C00D3EEDB /* SpectrumWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 839614AB286EDA5C00D3EEDB /* SpectrumWindow.xib */; };
@ -724,6 +726,7 @@
83B72E3B279045B7006007A3 /* libfdk-aac.2.dylib in CopyFiles */, 83B72E3B279045B7006007A3 /* libfdk-aac.2.dylib in CopyFiles */,
8305963C277F013200EBFAAE /* File_Extractor.framework in CopyFiles */, 8305963C277F013200EBFAAE /* File_Extractor.framework in CopyFiles */,
ED69CBCA25BE32E80090B90D /* MASShortcut.framework in CopyFiles */, ED69CBCA25BE32E80090B90D /* MASShortcut.framework in CopyFiles */,
838F851F256B4E8B00C3E614 /* Sparkle.framework in CopyFiles */,
17F561400C3BD4F30019975C /* CogAudio.framework in CopyFiles */, 17F561400C3BD4F30019975C /* CogAudio.framework in CopyFiles */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -998,6 +1001,7 @@
838EE8B729A8600900CD0580 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Localizable.strings; sourceTree = "<group>"; }; 838EE8B729A8600900CD0580 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Localizable.strings; sourceTree = "<group>"; };
838EE8B829A8600900CD0580 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = tr; path = tr.lproj/Credits.html; sourceTree = "<group>"; }; 838EE8B829A8600900CD0580 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = tr; path = tr.lproj/Credits.html; sourceTree = "<group>"; };
838F84FF25687C5C00C3E614 /* Cog-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Cog-Bridging-Header.h"; sourceTree = "<group>"; }; 838F84FF25687C5C00C3E614 /* Cog-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Cog-Bridging-Header.h"; sourceTree = "<group>"; };
838F851D256B4E5E00C3E614 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sparkle.framework; path = ThirdParty/Frameworks/Sparkle.framework; sourceTree = "<group>"; };
83922FB6286B1AA900A0B039 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; 83922FB6286B1AA900A0B039 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; };
839614A1286ED97200D3EEDB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/AboutWindowController.xib; sourceTree = "<group>"; }; 839614A1286ED97200D3EEDB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/AboutWindowController.xib; sourceTree = "<group>"; };
839614A4286ED98600D3EEDB /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/AboutWindowController.strings; sourceTree = "<group>"; }; 839614A4286ED98600D3EEDB /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/AboutWindowController.strings; sourceTree = "<group>"; };
@ -1109,6 +1113,7 @@
83978E26285C596F0076ED21 /* FirebaseAnalytics in Frameworks */, 83978E26285C596F0076ED21 /* FirebaseAnalytics in Frameworks */,
17BB5CF90B8A86350009ACB1 /* AudioUnit.framework in Frameworks */, 17BB5CF90B8A86350009ACB1 /* AudioUnit.framework in Frameworks */,
17BB5CFA0B8A86350009ACB1 /* CoreAudio.framework in Frameworks */, 17BB5CFA0B8A86350009ACB1 /* CoreAudio.framework in Frameworks */,
838F851E256B4E5E00C3E614 /* Sparkle.framework in Frameworks */,
17BB5CFB0B8A86350009ACB1 /* CoreAudioKit.framework in Frameworks */, 17BB5CFB0B8A86350009ACB1 /* CoreAudioKit.framework in Frameworks */,
83978E16285C58190076ED21 /* FirebaseCrashlytics in Frameworks */, 83978E16285C58190076ED21 /* FirebaseCrashlytics in Frameworks */,
17BB5EA60B8A87850009ACB1 /* IOKit.framework in Frameworks */, 17BB5EA60B8A87850009ACB1 /* IOKit.framework in Frameworks */,
@ -1153,6 +1158,7 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
ED69CBB825BE328C0090B90D /* MASShortcut.xcodeproj */, ED69CBB825BE328C0090B90D /* MASShortcut.xcodeproj */,
838F851D256B4E5E00C3E614 /* Sparkle.framework */,
17F5612A0C3BD4DC0019975C /* CogAudio.xcodeproj */, 17F5612A0C3BD4DC0019975C /* CogAudio.xcodeproj */,
1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */, 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */,
); );

0
Plugins/Organya/fx96.pxt Executable file → Normal file
View File

0
Plugins/Organya/fx97.pxt Executable file → Normal file
View File

0
Plugins/Organya/fx98.pxt Executable file → Normal file
View File

0
Plugins/Organya/fx99.pxt Executable file → Normal file
View File

0
Plugins/Organya/fx9a.pxt Executable file → Normal file
View File

0
Plugins/Organya/fx9b.pxt Executable file → Normal file
View File

0
Plugins/Organya/wavetable.dat Executable file → Normal file
View File

View File

@ -16,6 +16,7 @@
<outlet property="notificationsView" destination="U4w-jw-ca5" id="wVJ-GH-A21"/> <outlet property="notificationsView" destination="U4w-jw-ca5" id="wVJ-GH-A21"/>
<outlet property="outputPane" destination="57" id="75"/> <outlet property="outputPane" destination="57" id="75"/>
<outlet property="playlistView" destination="231" id="244"/> <outlet property="playlistView" destination="231" id="244"/>
<outlet property="updatesView" destination="50" id="99"/>
</connections> </connections>
</customObject> </customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/> <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
@ -210,6 +211,24 @@
</subviews> </subviews>
<point key="canvasLocation" x="-151" y="-34"/> <point key="canvasLocation" x="-151" y="-34"/>
</customView> </customView>
<customView id="50" userLabel="UpdatesView">
<rect key="frame" x="0.0" y="0.0" width="640" height="56"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="51">
<rect key="frame" x="18" y="19" width="602" height="18"/>
<autoresizingMask key="autoresizingMask"/>
<buttonCell key="cell" type="check" title="Automatically check for updates on startup" bezelStyle="regularSquare" imagePosition="left" alignment="left" inset="2" id="207">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<binding destination="52" name="value" keyPath="values.SUCheckAtStartup" id="53"/>
</connections>
</button>
</subviews>
<point key="canvasLocation" x="-151" y="145"/>
</customView>
<userDefaultsController representsSharedInstance="YES" id="52" userLabel="Shared Defaults"/> <userDefaultsController representsSharedInstance="YES" id="52" userLabel="Shared Defaults"/>
<customObject id="57" userLabel="OutputPane" customClass="OutputPane"> <customObject id="57" userLabel="OutputPane" customClass="OutputPane">
<connections> <connections>

View File

@ -22,6 +22,7 @@
IBOutlet GeneralPane *generalPane; IBOutlet GeneralPane *generalPane;
IBOutlet NSView *playlistView; IBOutlet NSView *playlistView;
IBOutlet NSView *updatesView;
IBOutlet NSView *notificationsView; IBOutlet NSView *notificationsView;
IBOutlet NSView *appearanceView; IBOutlet NSView *appearanceView;
@ -33,6 +34,7 @@
- (MIDIPane *)midiPane; - (MIDIPane *)midiPane;
- (GeneralPane *)generalPane; - (GeneralPane *)generalPane;
- (GeneralPreferencePane *)updatesPane;
- (GeneralPreferencePane *)playlistPane; - (GeneralPreferencePane *)playlistPane;
- (GeneralPreferencePane *)notificationsPane; - (GeneralPreferencePane *)notificationsPane;
- (GeneralPreferencePane *)appearancePane; - (GeneralPreferencePane *)appearancePane;

View File

@ -35,6 +35,7 @@
return @[[plugin playlistPane], return @[[plugin playlistPane],
[plugin hotKeyPane], [plugin hotKeyPane],
[plugin updatesPane],
[plugin outputPane], [plugin outputPane],
[plugin generalPane], [plugin generalPane],
[plugin notificationsPane], [plugin notificationsPane],
@ -58,6 +59,13 @@
return generalPane; return generalPane;
} }
- (GeneralPreferencePane *)updatesPane {
return [GeneralPreferencePane preferencePaneWithView:updatesView
title:NSLocalizedPrefString(@"Updates")
systemIconName:@"arrow.triangle.2.circlepath.circle.fill"
orOldIconNamed:@"updates"];
}
- (GeneralPreferencePane *)playlistPane { - (GeneralPreferencePane *)playlistPane {
return [GeneralPreferencePane preferencePaneWithView:playlistView return [GeneralPreferencePane preferencePaneWithView:playlistView
title:NSLocalizedPrefString(@"Playlist") title:NSLocalizedPrefString(@"Playlist")

View File

@ -31,17 +31,6 @@ play with Cog. It is not necessary to add either your default Music folder,
your default Downloads folder, or your default Movies folder. your default Downloads folder, or your default Movies folder.
ADDENDUM - 2022-06-22
This branch is the App Store version. The only real difference between it and
the sparkle branch is that two commits which removed the Sparkle framework
were reverted in that branch. This branch contains an update to the README
and an extra empty commmit so that the version numbers sync up between the
two.
The App Store page for Cog is [here](https://apps.apple.com/us/app/cog-kode54/id1630499622), when it finally goes live.
ADDENDUM - 2013-09-30 ADDENDUM - 2013-09-30
I have forked this player to continue maintaining it for others to use, as its I have forked this player to continue maintaining it for others to use, as its

View File

@ -0,0 +1 @@
Versions/Current/Autoupdate

View File

@ -0,0 +1 @@
Versions/Current/Headers

View File

@ -0,0 +1 @@
Versions/Current/Modules

View File

@ -0,0 +1 @@
Versions/Current/PrivateHeaders

View File

@ -0,0 +1 @@
Versions/Current/Resources

View File

@ -0,0 +1 @@
Versions/Current/Sparkle

View File

@ -0,0 +1 @@
Versions/Current/Updater.app

Binary file not shown.

View File

@ -0,0 +1,52 @@
//
// SPUDownloadData.h
// Sparkle
//
// Created by Mayur Pawashe on 8/10/16.
// Copyright © 2016 Sparkle Project. All rights reserved.
//
#import <Foundation/Foundation.h>
#ifdef BUILDING_SPARKLE_DOWNLOADER_SERVICE
// Ignore incorrect warning
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wquoted-include-in-framework-header"
#import "SUExport.h"
#pragma clang diagnostic pop
#else
#import <Sparkle/SUExport.h>
#endif
NS_ASSUME_NONNULL_BEGIN
/**
* A class for containing downloaded data along with some information about it.
*/
SU_EXPORT @interface SPUDownloadData : NSObject <NSSecureCoding>
/**
* The raw data that was downloaded.
*/
@property (nonatomic, readonly) NSData *data;
/**
* The URL that was fetched from.
*
* This may be different from the URL in the request if there were redirects involved.
*/
@property (nonatomic, readonly, copy) NSURL *URL;
/**
* The IANA charset encoding name if available. Eg: "utf-8"
*/
@property (nonatomic, readonly, nullable, copy) NSString *textEncodingName;
/**
* The MIME type if available. Eg: "text/plain"
*/
@property (nonatomic, readonly, nullable, copy) NSString *MIMEType;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,112 @@
//
// SPUStandardUpdaterController.h
// Sparkle
//
// Created by Mayur Pawashe on 2/28/16.
// Copyright © 2016 Sparkle Project. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <Sparkle/SUExport.h>
NS_ASSUME_NONNULL_BEGIN
@class SPUUpdater;
@class SPUStandardUserDriver;
@class NSMenuItem;
@protocol SPUUserDriver, SPUUpdaterDelegate, SPUStandardUserDriverDelegate;
/**
A controller class that instantiates a `SPUUpdater` and allows binding UI to its updater settings.
This class can be instantiated in a nib or created programatically using `-initWithUpdaterDelegate:userDriverDelegate:` or `-initWithStartingUpdater:updaterDelegate:userDriverDelegate:`.
The controller's updater targets the application's main bundle and uses Sparkle's standard user interface.
Typically, this class is used by sticking it as a custom NSObject subclass in an Interface Builder nib (probably in MainMenu) but it works well programatically too.
The controller creates an `SPUUpdater` instance using a `SPUStandardUserDriver` and allows hooking up the check for updates action and handling menu item validation.
It also allows hooking up the updater's and user driver's delegates.
If you need more control over what bundle you want to update, or you want to provide a custom user interface (via `SPUUserDriver`), please use `SPUUpdater` directly instead.
*/
SU_EXPORT @interface SPUStandardUpdaterController : NSObject
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-interface-ivars"
/**
* Interface builder outlet for the updater's delegate.
*/
IBOutlet __weak id<SPUUpdaterDelegate> updaterDelegate;
/**
* Interface builder outlet for the user driver's delegate.
*/
IBOutlet __weak id<SPUStandardUserDriverDelegate> userDriverDelegate;
#pragma clang diagnostic pop
}
/**
Accessible property for the updater. Some properties on the updater can be binded via KVO
When instantiated from a nib, don't perform update checks before the application has finished launching in a MainMenu nib (i.e applicationDidFinishLaunching:) or before the corresponding window/view controller has been loaded (i.e, windowDidLoad or viewDidLoad). The updater is not guaranteed to be started yet before these points.
*/
@property (nonatomic, readonly) SPUUpdater *updater;
/**
Accessible property for the updater's user driver.
*/
@property (nonatomic, readonly) SPUStandardUserDriver *userDriver;
/**
Create a new `SPUStandardUpdaterController` from a nib.
You cannot call this initializer directly. You must instantiate a `SPUStandardUpdaterController` inside of a nib (typically the MainMenu nib) to use it.
To create a `SPUStandardUpdaterController` programatically, use `-initWithUpdaterDelegate:userDriverDelegate:` or `-initWithStartingUpdater:updaterDelegate:userDriverDelegate:` instead.
*/
- (instancetype)init NS_UNAVAILABLE;
/**
Create a new `SPUStandardUpdaterController` programmatically.
The updater is started automatically. See `-startUpdater` for more information.
*/
- (instancetype)initWithUpdaterDelegate:(nullable id<SPUUpdaterDelegate>)updaterDelegate userDriverDelegate:(nullable id<SPUStandardUserDriverDelegate>)userDriverDelegate;
/**
Create a new `SPUStandardUpdaterController` programmatically allowing you to specify whether or not to start the updater immediately.
You can specify whether or not you want to start the updater immediately.
If you do not start the updater, you must invoke `-startUpdater` at a later time to start it.
*/
- (instancetype)initWithStartingUpdater:(BOOL)startUpdater updaterDelegate:(nullable id<SPUUpdaterDelegate>)updaterDelegate userDriverDelegate:(nullable id<SPUStandardUserDriverDelegate>)userDriverDelegate;
/**
Starts the updater if it has not already been started.
You should only call this method yourself if you opted out of starting the updater on initialization.
Hence, do not call this yourself if you are instantiating this controller from a nib.
This invokes `-[SPUUpdater startUpdater:]`. If the application is misconfigured with Sparkle, an error is logged and an alert is shown to the user (after a few seconds) to contact the developer.
If you want more control over this behavior, you can create your own `SPUUpdater` instead of using `SPUStandardUpdaterController`.
*/
- (void)startUpdater;
/**
Explicitly checks for updates and displays a progress dialog while doing so.
This method is meant for a main menu item.
Connect any NSMenuItem to this action in Interface Builder or programmatically,
and Sparkle will check for updates and report back its findings verbosely when it is invoked.
When the target/action of the menu item is set to this controller and this method,
this controller also handles enabling/disabling the menu item by checking
`-[SPUUpdater canCheckForUpdates]`
This action checks updates by invoking `-[SPUUpdater checkForUpdates]`
*/
- (IBAction)checkForUpdates:(nullable id)sender;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,37 @@
//
// SPUStandardUserDriver.h
// Sparkle
//
// Created by Mayur Pawashe on 2/14/16.
// Copyright © 2016 Sparkle Project. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <Sparkle/SPUUserDriver.h>
#import <Sparkle/SUExport.h>
NS_ASSUME_NONNULL_BEGIN
@protocol SPUStandardUserDriverDelegate;
/**
Sparkle's standard built-in user driver for updater interactions
*/
SU_EXPORT @interface SPUStandardUserDriver : NSObject <SPUUserDriver>
/**
Initializes a Sparkle's standard user driver for user update interactions
@param hostBundle The target bundle of the host that is being updated.
@param delegate The optional delegate to this user driver.
*/
- (instancetype)initWithHostBundle:(NSBundle *)hostBundle delegate:(nullable id<SPUStandardUserDriverDelegate>)delegate;
/**
Use initWithHostBundle:delegate: instead.
*/
- (instancetype)init NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,172 @@
//
// SPUStandardUserDriverDelegate.h
// Sparkle
//
// Created by Mayur Pawashe on 3/3/16.
// Copyright © 2016 Sparkle Project. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <Sparkle/SUExport.h>
NS_ASSUME_NONNULL_BEGIN
@protocol SUVersionDisplay;
@class SUAppcastItem;
@class SPUUserUpdateState;
/**
A protocol for Sparkle's standard user driver's delegate
This includes methods related to UI interactions
*/
SU_EXPORT @protocol SPUStandardUserDriverDelegate <NSObject>
@optional
/**
Called before showing a modal alert window,
to give the opportunity to hide attached windows that may get in the way.
*/
- (void)standardUserDriverWillShowModalAlert;
/**
Called after showing a modal alert window,
to give the opportunity to hide attached windows that may get in the way.
*/
- (void)standardUserDriverDidShowModalAlert;
/**
Returns an object that formats version numbers for display to the user.
If you don't implement this method or return @c nil, the standard version formatter will be used.
*/
- (_Nullable id <SUVersionDisplay>)standardUserDriverRequestsVersionDisplayer;
/**
Handles showing the full release notes to the user.
When a user checks for new updates and no new update is found, Sparkle will offer to show the application's version history to the user
by providing a "Version History" button in the no new update available alert.
If this delegate method is not implemented, Sparkle will instead offer to open the
`fullReleaseNotesLink` (or `releaseNotesLink` if the former is unavailable) from the appcast's latest `item` in the user's web browser.
If this delegate method is implemented, Sparkle will instead ask the delegate to show the full release notes to the user.
A delegate may want to implement this method if they want to show in-app or offline release notes.
@param item The appcast item corresponding to the latest version available.
*/
- (void)standardUserDriverShowVersionHistoryForAppcastItem:(SUAppcastItem *)item;
/**
Specifies whether or not the download, extraction, and installing status windows allows to be minimized.
By default, the status window showing the current status of the update (download, extraction, ready to install) is allowed to be minimized
for regular application bundle updates.
@return @c YES if the status window is allowed to be minimized (default behavior), otherwise @c NO.
*/
- (BOOL)standardUserDriverAllowsMinimizableStatusWindow;
/**
Declares whether or not gentle scheduled update reminders are supported.
The delegate may implement scheduled update reminders that are presented in a gentle manner by implementing one or both of:
`-standardUserDriverWillHandleShowingUpdate:forUpdate:state:` and `-standardUserDriverShouldHandleShowingScheduledUpdate:andInImmediateFocus:`
Visit https://sparkle-project.org/documentation/gentle-reminders for more information and examples.
@return @c YES if gentle scheduled update reminders are implemented by standard user driver delegate, otherwise @c NO (default).
*/
@property (nonatomic, readonly) BOOL supportsGentleScheduledUpdateReminders;
/**
Specifies if the standard user driver should handle showing a new scheduled update, or if its delegate should handle showing the update instead.
If you implement this method and return @c NO the delegate is then responsible for showing the update,
which must be implemented and done in `-standardUserDriverWillHandleShowingUpdate:forUpdate:state:`
The motivation for the delegate being responsible for showing updates is to override Sparkle's default behavior
and add gentle reminders for new updates.
Returning @c YES is the default behavior and allows the standard user driver to handle showing the update.
If the standard user driver handles showing the update, `immediateFocus` reflects whether or not it will show the update in immediate and utmost focus.
The standard user driver may choose to show the update in immediate and utmost focus when the app was launched recently
or the system has been idle for some time.
If `immediateFocus` is @c NO the standard user driver may want to defer showing the update until the user comes back to the app.
For background running applications, when `immediateFocus` is @c NO the standard user driver will always want to show
the update alert immediately, but behind other running applications or behind the app's own windows if it's currently active.
There should be no side effects made when implementing this method so you should just return @c YES or @c NO
You will also want to implement `-standardUserDriverWillHandleShowingUpdate:forUpdate:state:` for adding additional update reminders.
This method is not called for user-initiated update checks. The standard user driver always handles those.
Visit https://sparkle-project.org/documentation/gentle-reminders for more information and examples.
@param update The update the standard user driver should show.
@param immediateFocus If @c immediateFocus is @c YES, then the standard user driver proposes to show the update in immediate and utmost focus. See discussion for more details.
@return @c YES if the standard user should handle showing the scheduled update (default behavior), otherwise @c NO if the delegate handles showing it.
*/
- (BOOL)standardUserDriverShouldHandleShowingScheduledUpdate:(SUAppcastItem *)update andInImmediateFocus:(BOOL)immediateFocus;
/**
Called before an update will be shown to the user.
If the standard user driver handles showing the update, `handleShowingUpdate` will be `YES`.
Please see `-standardUserDriverShouldHandleShowingScheduledUpdate:andInImmediateFocus:` for how the standard user driver
may handle showing scheduled updates when `handleShowingUpdate` is `YES` and `state.userInitiated` is `NO`.
If the delegate declared it handles showing the update by returning @c NO in `-standardUserDriverShouldHandleShowingScheduledUpdate:andInImmediateFocus:`
then the delegate should handle showing update reminders in this method, or at some later point.
In this case, `handleShowingUpdate` will be @c NO.
To bring the update alert in focus, you may call `-[SPUStandardUpdaterController checkForUpdates:]` or `-[SPUUpdater checkForUpdates]`.
You may want to show additional UI indicators in your application that will show this update in focus
and want to dismiss additional UI indicators in `-standardUserDriverWillFinishUpdateSession` or `-standardUserDriverDidReceiveUserAttentionForUpdate:`
If `state.userInitiated` is @c YES then the standard user driver always handles showing the new update and `handleShowingUpdate` will be @c YES.
In this case, it may still be useful for the delegate to intercept this method right before a new update will be shown.
This method is not called when bringing an update that has already been presented back in focus.
Visit https://sparkle-project.org/documentation/gentle-reminders for more information and examples.
@param handleShowingUpdate @c YES if the standard user driver handles showing the update, otherwise @c NO if the delegate handles showing the update.
@param update The update that will be shown.
@param state The user state of the update which includes if the update check was initiated by the user.
*/
- (void)standardUserDriverWillHandleShowingUpdate:(BOOL)handleShowingUpdate forUpdate:(SUAppcastItem *)update state:(SPUUserUpdateState *)state;
/**
Called when a new update first receives attention from the user.
This occurs either when the user first brings the update alert in utmost focus or when the user makes a choice to install an update or dismiss/skip it.
This may be useful to intercept for dismissing custom attention-based UI indicators (e.g, user notifications) introduced when implementing
`-standardUserDriverWillHandleShowingUpdate:forUpdate:state:`
For custom UI indicators that need to still be on screen after the user has started to install an update, please see `-standardUserDriverWillFinishUpdateSession`.
@param update The new update that the user gave attention to.
*/
- (void)standardUserDriverDidReceiveUserAttentionForUpdate:(SUAppcastItem *)update;
/**
Called before the standard user driver session will finish its current update session.
This may occur after the user has dismissed / skipped a new update or after an update error has occurred.
For updaters updating external/other bundles, this may also be called after an update has been successfully installed.
This may be useful to intercept for dismissing custom UI indicators introduced when implementing
`-standardUserDriverWillHandleShowingUpdate:forUpdate:state:`
For UI indicators that need to be dismissed when the user has given attention to a new update alert,
please see `-standardUserDriverDidReceiveUserAttentionForUpdate:`
*/
- (void)standardUserDriverWillFinishUpdateSession;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,33 @@
//
// SPUUpdateCheck.h
// SPUUpdateCheck
//
// Created by Mayur Pawashe on 8/28/21.
// Copyright © 2021 Sparkle Project. All rights reserved.
//
#ifndef SPUUpdateCheck_h
#define SPUUpdateCheck_h
/**
Describes the type of update check being performed.
Each update check corresponds to an update check method on `SPUUpdater`.
*/
typedef NS_ENUM(NSInteger, SPUUpdateCheck)
{
/**
The user-initiated update check corresponding to `-[SPUUpdater checkForUpdates]`.
*/
SPUUpdateCheckUpdates = 0,
/**
The background scheduled update check corresponding to `-[SPUUpdater checkForUpdatesInBackground]`.
*/
SPUUpdateCheckUpdatesInBackground = 1,
/**
The informational probe update check corresponding to `-[SPUUpdater checkForUpdateInformation]`.
*/
SPUUpdateCheckUpdateInformation = 2
};
#endif /* SPUUpdateCheck_h */

View File

@ -0,0 +1,33 @@
//
// SPUUpdatePermissionRequest.h
// Sparkle
//
// Created by Mayur Pawashe on 8/14/16.
// Copyright © 2016 Sparkle Project. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <Sparkle/SUExport.h>
NS_ASSUME_NONNULL_BEGIN
/**
This class represents information needed to make a permission request for checking updates.
*/
SU_EXPORT @interface SPUUpdatePermissionRequest : NSObject<NSSecureCoding>
/**
Initializes a new update permission request instance.
@param systemProfile The system profile information.
*/
- (instancetype)initWithSystemProfile:(NSArray<NSDictionary<NSString *, NSString *> *> *)systemProfile;
/**
A read-only property for the user's system profile.
*/
@property (nonatomic, readonly) NSArray<NSDictionary<NSString *, NSString *> *> *systemProfile;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,312 @@
//
// SPUUpdater.h
// Sparkle
//
// Created by Andy Matuschak on 1/4/06.
// Copyright 2006 Andy Matuschak. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <Sparkle/SUExport.h>
#import <Sparkle/SPUUserDriver.h>
NS_ASSUME_NONNULL_BEGIN
@class SUAppcastItem, SUAppcast;
@protocol SPUUpdaterDelegate;
/**
The main API in Sparkle for controlling the update mechanism.
This class is used to configure the update parameters as well as manually and automatically schedule and control checks for updates.
For convenience, you can create a standard or nib instantiable updater by using `SPUStandardUpdaterController`.
Prefer to set initial properties in your bundle's Info.plist as described in [Customizing Sparkle](https://sparkle-project.org/documentation/customization/).
Otherwise only if you need dynamic behavior for user settings should you set properties on the updater such as:
- `automaticallyChecksForUpdates`
- `updateCheckInterval`
- `automaticallyDownloadsUpdates`
- `feedURL`
Please view the documentation on each of these properties for more detail if you are to configure them dynamically.
*/
SU_EXPORT @interface SPUUpdater : NSObject
/**
Initializes a new `SPUUpdater` instance
This creates an updater, but to start it and schedule update checks `-startUpdater:` needs to be invoked first.
Related: See `SPUStandardUpdaterController` which wraps a `SPUUpdater` instance and is suitable for instantiating inside of nib files.
@param hostBundle The bundle that should be targetted for updating.
@param applicationBundle The application bundle that should be waited for termination and relaunched (unless overridden). Usually this can be the same as hostBundle. This may differ when updating a plug-in or other non-application bundle.
@param userDriver The user driver that Sparkle uses for user update interaction.
@param delegate The delegate for `SPUUpdater`.
*/
- (instancetype)initWithHostBundle:(NSBundle *)hostBundle applicationBundle:(NSBundle *)applicationBundle userDriver:(id <SPUUserDriver>)userDriver delegate:(nullable id<SPUUpdaterDelegate>)delegate;
/**
Use `-initWithHostBundle:applicationBundle:userDriver:delegate:` or `SPUStandardUpdaterController` standard adapter instead.
If you want to drop an updater into a nib, use `SPUStandardUpdaterController`.
*/
- (instancetype)init NS_UNAVAILABLE;
/**
Starts the updater.
This method first checks if Sparkle is configured properly. A valid feed URL should be set before this method is invoked.
If the configuration is valid, an update cycle is started in the next main runloop cycle.
During this cycle, a permission prompt may be brought up (if needed) for checking if the user wants automatic update checking.
Otherwise if automatic update checks are enabled, a scheduled update alert may be brought up if enough time has elapsed since the last check.
See `automaticallyChecksForUpdates` for more information.
After starting the updater and before the next runloop cycle, one of `-checkForUpdates`, `-checkForUpdatesInBackground`, or `-checkForUpdateInformation` can be invoked.
This may be useful if you want to check for updates immediately or without showing a potential permission prompt.
If the updater cannot be started (i.e, due to a configuration issue in the application), you may want to fall back appropriately.
For example, the standard updater controller (`SPUStandardUpdaterController`) alerts the user that the app is misconfigured and to contact the developer.
This must be called on the main thread.
@param error The error that is populated if this method fails. Pass NULL if not interested in the error information.
@return YES if the updater started otherwise NO with a populated error
*/
- (BOOL)startUpdater:(NSError * __autoreleasing *)error;
/**
Checks for updates, and displays progress while doing so if needed.
This is meant for users initiating a new update check or checking the current update progress.
If an update hasn't started, the user may be shown that a new check for updates is occurring.
If an update has already been downloaded or begun installing from a previous session, the user may be presented to install that update.
If the user is already being presented with an update, that update will be shown to the user in active focus.
This will find updates that the user has previously opted into skipping.
See `canCheckForUpdates` property which can determine when this method may be invoked.
*/
- (void)checkForUpdates;
/**
Checks for updates, but does not show any UI unless an update is found.
You usually do not need to call this method directly. If `automaticallyChecksForUpdates` is @c YES,
Sparkle calls this method automatically according to its update schedule using the `updateCheckInterval`
and the `lastUpdateCheckDate`. Therefore, you should typically only consider calling this method directly if you
opt out of automatic update checks.
This is meant for programmatically initating a check for updates in the background without the user initiating it.
This check will not show UI if no new updates are found.
If a new update is found, the updater's user driver may handle showing it at an appropriate (but not necessarily immediate) time.
If you want control over when and how a new update is shown, please see https://sparkle-project.org/documentation/gentle-reminders/
Note if automated updating is turned on, either a new update may be downloaded in the background to be installed silently,
or an already downloaded update may be shown.
This will not find updates that the user has opted into skipping.
This method does not do anything if there is a `sessionInProgress`.
*/
- (void)checkForUpdatesInBackground;
/**
Begins a "probing" check for updates which will not actually offer to
update to that version.
However, the delegate methods
`-[SPUUpdaterDelegate updater:didFindValidUpdate:]` and
`-[SPUUpdaterDelegate updaterDidNotFindUpdate:]` will be called,
so you can use that information in your UI.
`-[SPUUpdaterDelegate updater:didFinishUpdateCycleForUpdateCheck:error:]` will be called when
this probing check is completed.
Updates that have been skipped by the user will not be found.
This method does not do anything if there is a `sessionInProgress`.
*/
- (void)checkForUpdateInformation;
/**
A property indicating whether or not updates can be checked by the user.
An update check can be made by the user when an update session isn't in progress, or when an update or its progress is being shown to the user.
A user cannot check for updates when data (such as the feed or an update) is still being downloaded automatically in the background.
This property is suitable to use for menu item validation for seeing if `-checkForUpdates` can be invoked.
This property is also KVO-compliant.
Note this property does not reflect whether or not an update session is in progress. Please see `sessionInProgress` property instead.
*/
@property (nonatomic, readonly) BOOL canCheckForUpdates;
/**
A property indicating whether or not an update session is in progress.
An update session is in progress when the appcast is being downloaded, an update is being downloaded,
an update is being shown, update permission is being requested, or the installer is being started.
An active session is when Sparkle's fired scheduler is running.
Note an update session may not be running even though Sparkle's installer (ran as a separate process) may be running,
or even though the update has been downloaded but the installation has been deferred. In both of these cases, a new update session
may be activated with the update resumed at a later point (automatically or manually).
See also:
- `canCheckForUpdates` property which is more suited for menu item validation and deciding if the user can initiate update checks.
- `-[SPUUpdaterDelegate updater:didFinishUpdateCycleForUpdateCheck:error:]` which lets the updater delegate know when an update cycle and session finishes.
*/
@property (nonatomic, readonly) BOOL sessionInProgress;
/**
A property indicating whether or not to check for updates automatically.
By default, Sparkle asks users on second launch for permission if they want automatic update checks enabled
and sets this property based on their response. If `SUEnableAutomaticChecks` is set in the Info.plist,
this permission request is not performed however.
Setting this property will persist in the host bundle's user defaults.
Hence developers shouldn't maintain an additional user default for this property.
Only set this property if the user wants to change the default via a user settings option.
Do not always set it on launch unless you want to ignore the user's preference.
For testing environments, you can disable update checks by passing `-SUEnableAutomaticChecks NO`
to your app's command line arguments instead of setting this property.
The update schedule cycle will be reset in a short delay after the property's new value is set.
This is to allow reverting this property without kicking off a schedule change immediately
*/
@property (nonatomic) BOOL automaticallyChecksForUpdates;
/**
A property indicating the current automatic update check interval in seconds.
Prefer to set SUScheduledCheckInterval directly in your Info.plist for setting the initial value.
Setting this property will persist in the host bundle's user defaults.
Hence developers shouldn't maintain an additional user default for this property.
Only set this property if the user wants to change the default via a user settings option.
Do not always set it on launch unless you want to ignore the user's preference.
The update schedule cycle will be reset in a short delay after the property's new value is set.
This is to allow reverting this property without kicking off a schedule change immediately
*/
@property (nonatomic) NSTimeInterval updateCheckInterval;
/**
A property indicating whether or not updates can be automatically downloaded in the background.
By default, updates are not automatically downloaded.
Note that the developer can disallow automatic downloading of updates from being enabled (via `SUAllowsAutomaticUpdates` Info.plist key).
In this case, this property will return NO regardless of how this property is set.
Prefer to set SUAutomaticallyUpdate directly in your Info.plist for setting the initial value.
Setting this property will persist in the host bundle's user defaults.
Hence developers shouldn't maintain an additional user default for this property.
Only set this property if the user wants to change the default via a user settings option.
Do not always set it on launch unless you want to ignore the user's preference.
*/
@property (nonatomic) BOOL automaticallyDownloadsUpdates;
/**
The URL of the appcast used to download update information.
If the updater's delegate implements `-[SPUUpdaterDelegate feedURLStringForUpdater:]`, this will return that feed URL.
Otherwise if the feed URL has been set before, the feed URL returned will be retrieved from the host bundle's user defaults.
Otherwise the feed URL in the host bundle's Info.plist will be returned.
If no feed URL can be retrieved, returns nil.
For setting a primary feed URL, please set the `SUFeedURL` property in your Info.plist.
For setting an alternative feed URL, please prefer `-[SPUUpdaterDelegate feedURLStringForUpdater:]` over `-setFeedURL:`
This property must be called on the main thread; calls from background threads will return nil.
*/
@property (nonatomic, readonly, nullable) NSURL *feedURL;
/**
Set the URL of the appcast used to download update information. Using this method is discouraged.
Setting this property will persist in the host bundle's user defaults.
To avoid this, you should consider implementing
`-[SPUUpdaterDelegate feedURLStringForUpdater:]` instead of using this method.
Passing nil will remove any feed URL that has been set in the host bundle's user defaults.
If you do not need to alternate between multiple feeds, set the SUFeedURL in your Info.plist instead of invoking this method.
For beta updates, you may consider migrating to `-[SPUUpdaterDelegate allowedChannelsForUpdater:]` in the future.
This method must be called on the main thread; calls from background threads will have no effect.
*/
- (void)setFeedURL:(nullable NSURL *)feedURL;
/**
The host bundle that is being updated.
*/
@property (nonatomic, readonly) NSBundle *hostBundle;
/**
The user agent used when checking for updates.
By default the user agent string returned is in the format:
$(BundleDisplayName)/$(BundleDisplayVersion) Sparkle/$(SparkleDisplayVersion)
BundleDisplayVersion is derived from the main application's Info.plist's CFBundleShortVersionString.
Note if Sparkle is being used to update another application, the bundle information retrieved is from the main application performing the updating.
This default implementation can be overrided.
*/
@property (nonatomic, copy) NSString *userAgentString;
/**
The HTTP headers used when checking for updates, downloading release notes, and downloading updates.
The keys of this dictionary are HTTP header fields and values are corresponding values.
*/
@property (nonatomic, copy, nullable) NSDictionary<NSString *, NSString *> *httpHeaders;
/**
A property indicating whether or not the user's system profile information is sent when checking for updates.
Setting this property will persist in the host bundle's user defaults.
*/
@property (nonatomic) BOOL sendsSystemProfile;
/**
The date of the last update check or nil if no check has been performed yet.
For testing purposes, the last update check is stored in the `SULastCheckTime` key in the host bundle's user defaults.
For example, `defaults delete my-bundle-id SULastCheckTime` can be invoked to clear the last update check time and test
if update checks are automatically scheduled.
*/
@property (nonatomic, readonly, copy, nullable) NSDate *lastUpdateCheckDate;
/**
Appropriately schedules or cancels the update checking timer according to the settings for the time interval and automatic checks.
If you change the `updateCheckInterval` or `automaticallyChecksForUpdates` properties, the update cycle will be reset automatically after a short delay.
The update cycle is also started automatically after the updater is started. In all these cases, this method should not be called directly.
This call does not change the date of the next check, but only the internal timer.
*/
- (void)resetUpdateCycle;
/**
The system profile information that is sent when checking for updates.
*/
@property (nonatomic, readonly, copy) NSArray<NSDictionary<NSString *, NSString *> *> *systemProfileArray;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,465 @@
//
// SPUUpdaterDelegate.h
// Sparkle
//
// Created by Mayur Pawashe on 8/12/16.
// Copyright © 2016 Sparkle Project. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <Sparkle/SUExport.h>
#import <Sparkle/SPUUpdateCheck.h>
#import <Sparkle/SPUUserUpdateState.h>
@protocol SUVersionComparison;
@class SPUUpdater, SUAppcast, SUAppcastItem, SPUUserUpdateState;
NS_ASSUME_NONNULL_BEGIN
// -----------------------------------------------------------------------------
// SUUpdater Notifications for events that might be interesting to more than just the delegate
// The updater will be the notification object
// -----------------------------------------------------------------------------
SU_EXPORT extern NSString *const SUUpdaterDidFinishLoadingAppCastNotification;
SU_EXPORT extern NSString *const SUUpdaterDidFindValidUpdateNotification;
SU_EXPORT extern NSString *const SUUpdaterDidNotFindUpdateNotification;
SU_EXPORT extern NSString *const SUUpdaterWillRestartNotification;
#define SUUpdaterWillRelaunchApplicationNotification SUUpdaterWillRestartNotification;
#define SUUpdaterWillInstallUpdateNotification SUUpdaterWillRestartNotification;
// Key for the SUAppcastItem object in the SUUpdaterDidFindValidUpdateNotification userInfo
SU_EXPORT extern NSString *const SUUpdaterAppcastItemNotificationKey;
// Key for the SUAppcast object in the SUUpdaterDidFinishLoadingAppCastNotification userInfo
SU_EXPORT extern NSString *const SUUpdaterAppcastNotificationKey;
// -----------------------------------------------------------------------------
// System Profile Keys
// -----------------------------------------------------------------------------
SU_EXPORT extern NSString *const SUSystemProfilerApplicationNameKey;
SU_EXPORT extern NSString *const SUSystemProfilerApplicationVersionKey;
SU_EXPORT extern NSString *const SUSystemProfilerCPU64bitKey;
SU_EXPORT extern NSString *const SUSystemProfilerCPUCountKey;
SU_EXPORT extern NSString *const SUSystemProfilerCPUFrequencyKey;
SU_EXPORT extern NSString *const SUSystemProfilerCPUTypeKey;
SU_EXPORT extern NSString *const SUSystemProfilerCPUSubtypeKey;
SU_EXPORT extern NSString *const SUSystemProfilerHardwareModelKey;
SU_EXPORT extern NSString *const SUSystemProfilerMemoryKey;
SU_EXPORT extern NSString *const SUSystemProfilerOperatingSystemVersionKey;
SU_EXPORT extern NSString *const SUSystemProfilerPreferredLanguageKey;
// -----------------------------------------------------------------------------
// SPUUpdater Delegate:
// -----------------------------------------------------------------------------
/**
Provides delegation methods to control the behavior of an `SPUUpdater` object.
*/
@protocol SPUUpdaterDelegate <NSObject>
@optional
/**
Returns whether to allow Sparkle to check for updates.
For example, this may be used to prevent Sparkle from interrupting a setup assistant.
Alternatively, you may want to consider starting the updater after eg: the setup assistant finishes.
Note in Swift, this method returns Void and is marked with the throws keyword. If this method
doesn't throw an error, the updater may perform an update check. Otherwise if an error is thrown (we recommend using an NSError),
then the updater may not perform an update check.
@param updater The updater instance.
@param updateCheck The type of update check that will be performed if the updater is allowed to check for updates.
@param error The populated error object if the updater may not perform a new update check. The @c NSLocalizedDescriptionKey user info key should be populated indicating a description of the error.
@return @c YES if the updater is allowed to check for updates, otherwise @c NO
*/
- (BOOL)updater:(SPUUpdater *)updater mayPerformUpdateCheck:(SPUUpdateCheck)updateCheck error:(NSError * __autoreleasing *)error;
/**
Returns the set of Sparkle channels the updater is allowed to find new updates from.
An appcast item can specify a channel the update is posted to. Without specifying a channel, the appcast item is posted to the default channel.
For instance:
```
<item>
<sparkle:version>2.0 Beta 1</sparkle:version>
<sparkle:channel>beta</sparkle:channel>
</item>
```
This example posts an update to the @c beta channel, so only updaters that are allowed to use the @c beta channel can find this update.
If the @c <sparkle:channel> element is not present, the update item is posted to the default channel and can be found by any updater.
You can pick any name you'd like for the channel. The valid characters for channel names are letters, numbers, dashes, underscores, and periods.
Note to use this feature, all app versions that your users may update from in your feed must use a version of Sparkle that supports this feature.
This feature was added in Sparkle 2.
@return The set of channel names the updater is allowed to find new updates in. An empty set is the default behavior,
which means the updater will only look for updates in the default channel.
*/
- (NSSet<NSString *> *)allowedChannelsForUpdater:(SPUUpdater *)updater;
/**
Returns a custom appcast URL used for checking for new updates.
Override this to dynamically specify the feed URL.
@param updater The updater instance.
@return An appcast feed URL to check for new updates in, or @c nil for the default behavior and if you don't want to be delegated this task.
*/
- (nullable NSString *)feedURLStringForUpdater:(SPUUpdater *)updater;
/**
Returns additional parameters to append to the appcast URL's query string.
This is potentially based on whether or not Sparkle will also be sending along the system profile.
@param updater The updater instance.
@param sendingProfile Whether the system profile will also be sent.
@return An array of dictionaries with keys: `key`, `value`, `displayKey`, `displayValue`, the latter two being specifically for display to the user.
*/
- (NSArray<NSDictionary<NSString *, NSString *> *> *)feedParametersForUpdater:(SPUUpdater *)updater sendingSystemProfile:(BOOL)sendingProfile;
/**
Returns whether Sparkle should prompt the user about checking for new updates automatically.
Use this to override the default behavior.
@param updater The updater instance.
@return @c YES if the updater should prompt for permission to check for new updates automatically, otherwise @c NO
*/
- (BOOL)updaterShouldPromptForPermissionToCheckForUpdates:(SPUUpdater *)updater;
/**
Returns an allowed list of system profile keys to be appended to the appcast URL's query string.
By default all keys will be included. This method allows overriding which keys should only be allowed.
@param updater The updater instance.
@return An array of system profile keys to include in the appcast URL's query string. Elements must be one of the `SUSystemProfiler*Key` constants. Return @c nil for the default behavior and if you don't want to be delegated this task.
*/
- (nullable NSArray<NSString *> *)allowedSystemProfileKeysForUpdater:(SPUUpdater *)updater;
/**
Called after Sparkle has downloaded the appcast from the remote server.
Implement this if you want to do some special handling with the appcast once it finishes loading.
@param updater The updater instance.
@param appcast The appcast that was downloaded from the remote server.
*/
- (void)updater:(SPUUpdater *)updater didFinishLoadingAppcast:(SUAppcast *)appcast;
/**
Called when a new valid update is found by the update driver.
@param updater The updater instance.
@param item The appcast item corresponding to the update that is proposed to be installed.
*/
- (void)updater:(SPUUpdater *)updater didFindValidUpdate:(SUAppcastItem *)item;
/**
Called when a valid new update is not found.
There are various reasons a new update is unavailable and can't be installed.
The userInfo dictionary on the error is populated with three keys:
- `SPULatestAppcastItemFoundKey`: if available, this may provide the latest `SUAppcastItem` that was found. This will be @c nil if it's unavailable.
- `SPUNoUpdateFoundReasonKey`: This will provide the `SPUNoUpdateFoundReason`.
For example the reason could be because the latest version in the feed requires a newer OS version or could be because the user is already on the latest version.
- `SPUNoUpdateFoundUserInitiatedKey`: A boolean that indicates if a new update was not found when the user intitiated an update check manually.
@param updater The updater instance.
@param error An error containing information on why a new valid update was not found
*/
- (void)updaterDidNotFindUpdate:(SPUUpdater *)updater error:(NSError *)error;
/**
Called when a valid new update is not found.
If more information is needed on why an update was not found, use `-[SPUUpdaterDelegate updaterDidNotFindUpdate:error:]` instead.
@param updater The updater instance.
*/
- (void)updaterDidNotFindUpdate:(SPUUpdater *)updater;
/**
Returns the item in the appcast corresponding to the update that should be installed.
Please consider using or migrating to other supported features before adopting this method.
Specifically:
- If you want to filter out certain tagged updates (like beta updates), consider `-[SPUUpdaterDelegate allowedChannelsForUpdater:]` instead.
- If you want to treat certain updates as informational-only, consider supplying @c <sparkle:informationalUpdate> with a set of affected versions users are updating from.
If you're using special logic or extensions in your appcast, implement this to use your own logic for finding a valid update, if any, in the given appcast.
Do not base your logic by filtering out items with a minimum or maximum OS version or minimum autoupdate version
because Sparkle already has logic for determining whether or not those items should be filtered out.
Also do not return a non-top level item from the appcast such as a delta item. Delta items will be ignored.
Sparkle picks the delta item from your selection if the appropriate one is available.
This method will not be invoked with an appcast that has zero items. Pick the best item from the appcast.
If an item is available that has the same version as the application or bundle to update, do not pick an item that is worse than that version.
This method may be called multiple times for different selections and filters. This method should be efficient.
Return `+[SUAppcastItem emptyAppcastItem]` if no appcast item is valid.
Return @c nil if you don't want to be delegated this task and want to let Sparkle handle picking the best valid update.
@param appcast The appcast that was downloaded from the remote server.
@param updater The updater instance.
@return The best valid appcast item.
*/
- (nullable SUAppcastItem *)bestValidUpdateInAppcast:(SUAppcast *)appcast forUpdater:(SPUUpdater *)updater;
/**
Returns whether or not the updater should proceed with the new chosen update from the appcast.
By default, the updater will always proceed with the best selected update found in an appcast. Override this to override this behavior.
If you return @c NO and populate the @c error, the user is not shown this @c updateItem nor is the update downloaded or installed.
Note in Swift, this method returns Void and is marked with the throws keyword. If this method doesn't throw an error, the updater will proceed with the update.
Otherwise if an error is thrown (we recommend using an NSError), then the will not proceed with the update.
@param updater The updater instance.
@param updateItem The selected update item to proceed with.
@param updateCheck The type of update check that would be performed if proceeded.
@param error An error object that must be populated by the delegate if the updater should not proceed with the update. The @c NSLocalizedDescriptionKey user info key should be populated indicating a description of the error.
@return @c YES if the updater should proceed with @c updateItem, otherwise @c NO if the updater should not proceed with the update with an @c error populated.
*/
- (BOOL)updater:(SPUUpdater *)updater shouldProceedWithUpdate:(SUAppcastItem *)updateItem updateCheck:(SPUUpdateCheck)updateCheck error:(NSError * __autoreleasing *)error;
/**
Called when a user makes a choice to install, dismiss, or skip an update.
If the @c choice is `SPUUserUpdateChoiceDismiss` and @c state.stage is `SPUUserUpdateStageDownloaded` the downloaded update is kept
around until the next time Sparkle reminds the user of the update.
If the @c choice is `SPUUserUpdateChoiceDismiss` and @c state.stage is `SPUUserUpdateStageInstalling` the update is still set to install on application termination.
If the @c choice is `SPUUserUpdateChoiceSkip` the user will not be reminded in the future for this update unless they initiate an update check themselves.
If @c updateItem.isInformationOnlyUpdate is @c YES the @c choice cannot be `SPUUserUpdateChoiceInstall`.
@param updater The updater instance.
@param choice The choice (install, dismiss, or skip) the user made for this @c updateItem
@param updateItem The appcast item corresponding to the update that the user made a choice on.
@param state The current state for the update which includes if the update has already been downloaded or already installing.
*/
- (void)updater:(SPUUpdater *)updater userDidMakeChoice:(SPUUserUpdateChoice)choice forUpdate:(SUAppcastItem *)updateItem state:(SPUUserUpdateState *)state;
/**
Returns whether the release notes (if available) should be downloaded after an update is found and shown.
This is specifically for the @c <releaseNotesLink> element in the appcast item.
@param updater The updater instance.
@param updateItem The update item to download and show release notes from.
@return @c YES to download and show the release notes if available, otherwise @c NO. The default behavior is @c YES.
*/
- (BOOL)updater:(SPUUpdater *)updater shouldDownloadReleaseNotesForUpdate:(SUAppcastItem *)updateItem;
/**
Called immediately before downloading the specified update.
@param updater The updater instance.
@param item The appcast item corresponding to the update that is proposed to be downloaded.
@param request The mutable URL request that will be used to download the update.
*/
- (void)updater:(SPUUpdater *)updater willDownloadUpdate:(SUAppcastItem *)item withRequest:(NSMutableURLRequest *)request;
/**
Called immediately after succesfull download of the specified update.
@param updater The SUUpdater instance.
@param item The appcast item corresponding to the update that has been downloaded.
*/
- (void)updater:(SPUUpdater *)updater didDownloadUpdate:(SUAppcastItem *)item;
/**
Called after the specified update failed to download.
@param updater The updater instance.
@param item The appcast item corresponding to the update that failed to download.
@param error The error generated by the failed download.
*/
- (void)updater:(SPUUpdater *)updater failedToDownloadUpdate:(SUAppcastItem *)item error:(NSError *)error;
/**
Called when the user cancels an update while it is being downloaded.
@param updater The updater instance.
*/
- (void)userDidCancelDownload:(SPUUpdater *)updater;
/**
Called immediately before extracting the specified downloaded update.
@param updater The SUUpdater instance.
@param item The appcast item corresponding to the update that is proposed to be extracted.
*/
- (void)updater:(SPUUpdater *)updater willExtractUpdate:(SUAppcastItem *)item;
/**
Called immediately after extracting the specified downloaded update.
@param updater The SUUpdater instance.
@param item The appcast item corresponding to the update that has been extracted.
*/
- (void)updater:(SPUUpdater *)updater didExtractUpdate:(SUAppcastItem *)item;
/**
Called immediately before installing the specified update.
@param updater The updater instance.
@param item The appcast item corresponding to the update that is proposed to be installed.
*/
- (void)updater:(SPUUpdater *)updater willInstallUpdate:(SUAppcastItem *)item;
/**
Returns whether the relaunch should be delayed in order to perform other tasks.
This is not called if the user didn't relaunch on the previous update,
in that case it will immediately restart.
This may also not be called if the application is not going to relaunch after it terminates.
@param updater The updater instance.
@param item The appcast item corresponding to the update that is proposed to be installed.
@param installHandler The install handler that must be completed before continuing with the relaunch.
@return @c YES to delay the relaunch until @c installHandler is invoked.
*/
- (BOOL)updater:(SPUUpdater *)updater shouldPostponeRelaunchForUpdate:(SUAppcastItem *)item untilInvokingBlock:(void (^)(void))installHandler;
/**
Returns whether the application should be relaunched at all.
Some apps **cannot** be relaunched under certain circumstances.
This method can be used to explicitly prevent a relaunch.
@param updater The updater instance.
@return @c YES if the updater should be relaunched, otherwise @c NO if it shouldn't.
*/
- (BOOL)updaterShouldRelaunchApplication:(SPUUpdater *)updater;
/**
Called immediately before relaunching.
@param updater The updater instance.
*/
- (void)updaterWillRelaunchApplication:(SPUUpdater *)updater;
/**
Returns an object that compares version numbers to determine their arithmetic relation to each other.
This method allows you to provide a custom version comparator.
If you don't implement this method or return @c nil,
the standard version comparator will be used.
Note that the standard version comparator may be used during installation for preventing a downgrade,
even if you provide a custom comparator here.
@param updater The updater instance.
@return The custom version comparator or @c nil if you don't want to be delegated this task.
*/
- (nullable id<SUVersionComparison>)versionComparatorForUpdater:(SPUUpdater *)updater;
/**
Called when a background update will be scheduled after a delay.
Automatic update checks need to be enabled for this to trigger.
@param delay The delay in seconds until the next scheduled update will occur. This is an approximation and may vary due to system state.
@param updater The updater instance.
*/
- (void)updater:(SPUUpdater *)updater willScheduleUpdateCheckAfterDelay:(NSTimeInterval)delay;
/**
Called when no update checks will be scheduled in the future.
This may later change if automatic update checks become enabled.
@param updater The updater instance.
*/
- (void)updaterWillNotScheduleUpdateCheck:(SPUUpdater *)updater;
/**
Returns the decryption password (if any) which is used to extract the update archive DMG.
Return @c nil if no password should be used.
@param updater The updater instance.
@return The password used for decrypting the archive, or @c nil if no password should be used.
*/
- (nullable NSString *)decryptionPasswordForUpdater:(SPUUpdater *)updater;
/**
Called when an update is scheduled to be silently installed on quit after downloading the update automatically.
If the updater is given responsibility, it can later remind the user an update is available if they have not terminated the application for a long time.
Also if the updater is given responsibility and the update item is marked critical, the new update will be presented to the user immediately after.
Even if the @c immediateInstallHandler is not invoked, the installer will attempt to install the update on termination.
@param updater The updater instance.
@param item The appcast item corresponding to the update that is proposed to be installed.
@param immediateInstallHandler The install handler for the delegate to immediately install the update. No UI interaction will be shown and the application will be relaunched after installation. This handler can only be used if @c YES is returned and the delegate handles installing the update. For Sparkle 2.3 onwards, this handler can be invoked multiple times in case the application cancels the termination request.
@return @c YES if the delegate will handle installing the update or @c NO if the updater should be given responsibility.
*/
- (BOOL)updater:(SPUUpdater *)updater willInstallUpdateOnQuit:(SUAppcastItem *)item immediateInstallationBlock:(void (^)(void))immediateInstallHandler;
/**
Called after the update driver aborts due to an error.
The update driver runs when checking for updates. This delegate method is called an error occurs during this process.
Some special possible values of `error.code` are:
- `SUNoUpdateError`: No new update was found.
- `SUInstallationCanceledError`: The user canceled installing the update when requested for authorization.
@param updater The updater instance.
@param error The error that caused the update driver to abort.
*/
- (void)updater:(SPUUpdater *)updater didAbortWithError:(NSError *)error;
/**
Called after the update driver finishes.
The update driver runs when checking for updates. This delegate method is called when that check is finished.
An update may be scheduled to be installed during the update cycle, or no updates may be found, or an available update may be dismissed or skipped (which is the same as no error).
If the @c error is @c nil, no error has occurred.
Some special possible values of `error.code` are:
- `SUNoUpdateError`: No new update was found.
- `SUInstallationCanceledError`: The user canceled installing the update when requested for authorization.
@param updater The updater instance.
@param updateCheck The type of update check was performed.
@param error The error that caused the update driver to abort. This is @c nil if the update driver finished normally and there is no error.
*/
- (void)updater:(SPUUpdater *)updater didFinishUpdateCycleForUpdateCheck:(SPUUpdateCheck)updateCheck error:(nullable NSError *)error;
/* Deprecated methods */
- (BOOL)updaterMayCheckForUpdates:(SPUUpdater *)updater __deprecated_msg("Please use -[SPUUpdaterDelegate updater:mayPerformUpdateCheck:error:] instead.");
- (void)updater:(SPUUpdater *)updater userDidSkipThisVersion:(SUAppcastItem *)item __deprecated_msg("Please use -[SPUUpdaterDelegate updater:userDidMakeChoice:forUpdate:state:] instead.");
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,60 @@
//
// SPUUpdaterSettings.h
// Sparkle
//
// Created by Mayur Pawashe on 3/27/16.
// Copyright © 2016 Sparkle Project. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <Sparkle/SUExport.h>
NS_ASSUME_NONNULL_BEGIN
/**
This class can be used for reading certain updater settings.
It retrieves the settings by first looking into the host's user defaults.
If the setting is not found in there, then the host's Info.plist file is looked at.
*/
SU_EXPORT @interface SPUUpdaterSettings : NSObject
- (instancetype)initWithHostBundle:(NSBundle *)hostBundle;
/**
* Indicates whether or not automatic update checks are enabled.
*/
@property (readonly, nonatomic) BOOL automaticallyChecksForUpdates;
/**
* The regular update check interval.
*/
@property (readonly, nonatomic) NSTimeInterval updateCheckInterval;
/**
* Indicates whether or not automatically downloading updates is allowed to be turned on by the user.
* If this value is nil, the developer has not explicitly specified this option.
*/
@property (readonly, nonatomic, nullable) NSNumber *allowsAutomaticUpdatesOption;
/**
* Indicates whether or not automatically downloading updates is allowed to be turned on by the user.
*/
@property (readonly, nonatomic) BOOL allowsAutomaticUpdates;
/**
* Indicates whether or not automatically downloading updates is enabled by the user or developer.
*
* Note this does not indicate whether or not automatic downloading of updates is allowable.
* See `-allowsAutomaticUpdates` property for that.
*/
@property (readonly, nonatomic) BOOL automaticallyDownloadsUpdates;
/**
* Indicates whether or not anonymous system profile information is sent when checking for updates.
*/
@property (readonly, nonatomic) BOOL sendsSystemProfile;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,287 @@
//
// SPUUserDriver.h
// Sparkle
//
// Created by Mayur Pawashe on 2/14/16.
// Copyright © 2016 Sparkle Project. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <Sparkle/SPUUserUpdateState.h>
#import <Sparkle/SUExport.h>
NS_ASSUME_NONNULL_BEGIN
@class SPUUpdatePermissionRequest, SUUpdatePermissionResponse, SUAppcastItem, SPUDownloadData;
/**
The API in Sparkle for controlling the user interaction.
This protocol is used for implementing a user interface for the Sparkle updater. Sparkle's internal drivers tell
an object that implements this protocol what actions to take and show to the user.
Every method in this protocol can be assumed to be called from the main thread.
*/
SU_EXPORT @protocol SPUUserDriver <NSObject>
/**
* Show an updater permission request to the user
*
* Ask the user for their permission regarding update checks.
* This is typically only called once per app installation.
*
* @param request The update permission request.
* @param reply A reply with a update permission response.
*/
- (void)showUpdatePermissionRequest:(SPUUpdatePermissionRequest *)request reply:(void (^)(SUUpdatePermissionResponse *))reply;
/**
* Show the user initating an update check
*
* Respond to the user initiating an update check. Sparkle uses this to show the user a window with an indeterminate progress bar.
*
* @param cancellation Invoke this cancellation block to cancel the update check before the update check is completed.
*/
- (void)showUserInitiatedUpdateCheckWithCancellation:(void (^)(void))cancellation;
/**
* Show the user a new update is found.
*
* Let the user know a new update is found and ask them what they want to do.
* Before this point, `-showUserInitiatedUpdateCheckWithCancellation:` may be called.
*
* The potential `stage`s on the updater @c state are:
*
* `SPUUpdateStateNotDownloaded` - Update has not been downloaded yet.
*
* `SPUUpdateStateDownloaded` - Update has already been downloaded but not started installing yet.
*
* `SPUUpdateStateInstalling` - Update has been downloaded and already started installing.
*
* The `userIntiated` property on the @c state indicates if the update was initiated by the user or if it was automatically scheduled in the background.
*
* Additionally, these properties on the @c appcastItem are of importance:
*
* @c appcastItem.informationOnlyUpdate indicates if the update is only informational and should not be downloaded. You can direct the user to the infoURL property of the appcastItem in their web browser. Sometimes information only updates are used as a fallback in case a bad update is shipped, so you'll want to support this case.
*
* @c appcastItem.majorUpgrade indicates if the update is a major or paid upgrade.
*
* @c appcastItem.criticalUpdate indicates if the update is a critical update.
*
* A reply of `SPUUserUpdateChoiceInstall` begins or resumes downloading or installing the update.
* If the state.stage is `SPUUserUpdateStateInstalling`, this may send a quit event to the application and relaunch it immediately (in this state, this behaves as a fast "install and Relaunch").
* Do not use this reply if @c appcastItem.informationOnlyUpdate is YES.
*
* A reply of `SPUUserUpdateChoiceDismiss` dismisses the update for the time being. The user may be reminded of the update at a later point.
* If the state.stage is `SPUUserUpdateStateDownloaded`, the downloaded update is kept after dismissing until the next time an update is shown to the user.
* If the state.stage is `SPUUserUpdateStateInstalling`, the installing update is also preserved after dismissing. In this state however, the update will also still be installed after the application is terminated.
*
* A reply of `SPUUserUpdateChoiceSkip` skips this particular version and won't notify the user again, unless they initiate an update check themselves.
* If @c appcastItem.majorUpgrade is YES, the major update and any future minor updates to that major release are skipped, unless a future minor update specifies a `<sparkle:ignoreSkippedUpgradesBelowVersion>` requirement.
* If the state.stage is `SPUUpdateStateInstalling`, the installation is also canceled when the update is skipped.
*
* @param appcastItem The Appcast Item containing information that reflects the new update.
* @param state The current state of the user update. See above discussion for notable properties.
* @param reply The reply which indicates if the update should be installed, dismissed, or skipped. See above discussion for more details.
*/
- (void)showUpdateFoundWithAppcastItem:(SUAppcastItem *)appcastItem state:(SPUUserUpdateState *)state reply:(void (^)(SPUUserUpdateChoice))reply;
/**
* Show the user the release notes for the new update
*
* Display the release notes to the user. This will be called after showing the new update.
* This is only applicable if the release notes are linked from the appcast, and are not directly embedded inside of the appcast file.
* That is, this may be invoked if the releaseNotesURL from the appcast item is non-nil.
*
* @param downloadData The data for the release notes that was downloaded from the new update's appcast.
*/
- (void)showUpdateReleaseNotesWithDownloadData:(SPUDownloadData *)downloadData;
/**
* Show the user that the new update's release notes could not be downloaded
*
* This will be called after showing the new update.
* This is only applicable if the release notes are linked from the appcast, and are not directly embedded inside of the appcast file.
* That is, this may be invoked if the releaseNotesURL from the appcast item is non-nil.
*
* @param error The error associated with why the new update's release notes could not be downloaded.
*/
- (void)showUpdateReleaseNotesFailedToDownloadWithError:(NSError *)error;
/**
* Show the user a new update was not found
*
* Let the user know a new update was not found after they tried initiating an update check.
* Before this point, `-showUserInitiatedUpdateCheckWithCancellation:` may be called.
*
* There are various reasons a new update is unavailable and can't be installed.
* The @c error object is populated with recovery and suggestion strings suitable to be shown in an alert.
*
* The @c userInfo dictionary on the @c error is also populated with two keys:
*
* `SPULatestAppcastItemFoundKey`: if available, this may provide the latest SUAppcastItem that was found.
*
* `SPUNoUpdateFoundReasonKey`: if available, this will provide the `SUNoUpdateFoundReason`. For example the reason could be because
* the latest version in the feed requires a newer OS version or could be because the user is already on the latest version.
*
* @param error The error associated with why a new update was not found. See above discussion for more details.
* @param acknowledgement Acknowledge to the updater that no update found error was shown.
*/
- (void)showUpdateNotFoundWithError:(NSError *)error acknowledgement:(void (^)(void))acknowledgement;
/**
* Show the user an update error occurred
*
* Let the user know that the updater failed with an error. This will not be invoked without the user having been
* aware that an update was in progress.
*
* Before this point, any of the non-error user driver methods may have been invoked.
*
* @param error The error associated with what update error occurred.
* @param acknowledgement Acknowledge to the updater that the error was shown.
*/
- (void)showUpdaterError:(NSError *)error acknowledgement:(void (^)(void))acknowledgement;
/**
* Show the user that downloading the new update initiated
*
* Let the user know that downloading the new update started.
*
* @param cancellation Invoke this cancellation block to cancel the download at any point before `-showDownloadDidStartExtractingUpdate` is invoked.
*/
- (void)showDownloadInitiatedWithCancellation:(void (^)(void))cancellation;
/**
* Show the user the content length of the new update that will be downloaded
*
* @param expectedContentLength The expected content length of the new update being downloaded.
* An implementor should be able to handle if this value is invalid (more or less than actual content length downloaded).
* Additionally, this method may be called more than once for the same download in rare scenarios.
*/
- (void)showDownloadDidReceiveExpectedContentLength:(uint64_t)expectedContentLength;
/**
* Show the user that the update download received more data
*
* This may be an appropriate time to advance a visible progress indicator of the download
* @param length The length of the data that was just downloaded
*/
- (void)showDownloadDidReceiveDataOfLength:(uint64_t)length;
/**
* Show the user that the update finished downloading and started extracting
*
* Sparkle uses this to show an indeterminate progress bar.
*
* Note that an update can resume at this point after having been downloaded before,
* so this may be called without any of the download callbacks being invoked prior.
*/
- (void)showDownloadDidStartExtractingUpdate;
/**
* Show the user that the update is extracting with progress
*
* Let the user know how far along the update extraction is.
*
* Before this point, `-showDownloadDidStartExtractingUpdate` is called.
*
* @param progress The progress of the extraction from a 0.0 to 1.0 scale
*/
- (void)showExtractionReceivedProgress:(double)progress;
/**
* Show the user that the update is ready to install & relaunch
*
* Let the user know that the update is ready to install and relaunch, and ask them whether they want to proceed.
* Note if the target application has already terminated, this method may not be invoked.
*
* A reply of `SPUUserUpdateChoiceInstall` installs the update the new update immediately. The application is relaunched only if it is still running by the time this reply is invoked. If the application terminates on its own, Sparkle will attempt to automatically install the update.
*
* A reply of `SPUUserUpdateChoiceDismiss` dismisses the update installation for the time being. Note the update may still be installed automatically after the application terminates.
*
* A reply of `SPUUserUpdateChoiceSkip` cancels the current update that has begun installing and dismisses the update. In this circumstance, the update is canceled but this update version is not skipped in the future.
*
* Before this point, `-showExtractionReceivedProgress:` or `-showUpdateFoundWithAppcastItem:state:reply:` may be called.
*
* @param reply The reply which indicates if the update should be installed, dismissed, or skipped. See above discussion for more details.
*/
- (void)showReadyToInstallAndRelaunch:(void (^)(SPUUserUpdateChoice))reply;
/**
* Show the user that the update is installing
*
* Let the user know that the update is currently installing.
*
* Before this point, `-showReadyToInstallAndRelaunch:` or `-showUpdateFoundWithAppcastItem:state:reply:` will be called.
*
* @param applicationTerminated Indicates if the application has been terminated already.
* If the application hasn't been terminated, a quit event is sent to the running application before installing the update.
* If the application or user delays or cancels termination, there may be an indefinite period of time before the application fully quits.
* It is up to the implementor whether or not to decide to continue showing installation progress in this case.
*
* @param retryTerminatingApplication This handler gives a chance for the application to re-try sending a quit event to the running application before installing the update.
* The application may cancel or delay termination. This handler gives the user driver another chance to allow the user to try terminating the application again.
* If the application does not delay or cancel application termination, there is no need to invoke this handler. This handler may be invoked multiple times.
* Note this handler should not be invoked if @c applicationTerminated is already @c YES
*/
- (void)showInstallingUpdateWithApplicationTerminated:(BOOL)applicationTerminated retryTerminatingApplication:(void (^)(void))retryTerminatingApplication;
/**
* Show the user that the update installation finished
*
* Let the user know that the update finished installing.
*
* This will only be invoked if the updater process is still alive, which is typically not the case if
* the updater's lifetime is tied to the application it is updating. This implementation must not try to reference
* the old bundle prior to the installation, which will no longer be around.
*
* Before this point, `-showInstallingUpdateWithApplicationTerminated:retryTerminatingApplication:` will be called.
*
* @param relaunched Indicates if the update was relaunched.
* @param acknowledgement Acknowledge to the updater that the finished installation was shown.
*/
- (void)showUpdateInstalledAndRelaunched:(BOOL)relaunched acknowledgement:(void (^)(void))acknowledgement;
/**
* Show the user the current presented update or its progress in utmost focus
*
* The user wishes to check for updates while the user is being shown update progress.
* Bring whatever is on screen to frontmost focus (permission request, update information, downloading or extraction status, choice to install update, etc).
*/
- (void)showUpdateInFocus;
/**
* Dismiss the current update installation
*
* Stop and tear down everything.
* Dismiss all update windows, alerts, progress, etc from the user.
* Basically, stop everything that could have been started. Sparkle may invoke this when aborting or finishing an update.
*/
- (void)dismissUpdateInstallation;
/*
* Below are deprecated methods that have been replaced by better alternatives.
* The deprecated methods will be used if the alternatives have not been implemented yet.
* In the future support for using these deprecated methods may be removed however.
*/
@optional
// Clients should move to non-deprecated methods
// Deprecated methods are only (temporarily) kept around for compatibility reasons
- (void)showUpdateNotFoundWithAcknowledgement:(void (^)(void))acknowledgement __deprecated_msg("Implement -showUpdateNotFoundWithError:acknowledgement: instead");
- (void)showUpdateInstallationDidFinishWithAcknowledgement:(void (^)(void))acknowledgement __deprecated_msg("Implement -showUpdateInstalledAndRelaunched:acknowledgement: instead");
- (void)dismissUserInitiatedUpdateCheck __deprecated_msg("Transition to new UI appropriately when a new update is shown, when no update is found, or when an update error occurs.");
- (void)showInstallingUpdate __deprecated_msg("Implement -showInstallingUpdateWithApplicationTerminated:retryTerminatingApplication: instead.");
- (void)showSendingTerminationSignal __deprecated_msg("Implement -showInstallingUpdateWithApplicationTerminated:retryTerminatingApplication: instead.");
- (void)showInstallingUpdateWithApplicationTerminated:(BOOL)applicationTerminated __deprecated_msg("Implement -showInstallingUpdateWithApplicationTerminated:retryTerminatingApplication: instead.");;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,77 @@
//
// SPUUserUpdateState.h
// Sparkle
//
// Created by Mayur Pawashe on 2/29/16.
// Copyright © 2016 Sparkle Project. All rights reserved.
//
#ifndef SPUUserUpdateState_h
#define SPUUserUpdateState_h
#import <Foundation/Foundation.h>
#import <Sparkle/SUExport.h>
NS_ASSUME_NONNULL_BEGIN
/**
A choice made by the user when prompted with a new update.
*/
typedef NS_ENUM(NSInteger, SPUUserUpdateChoice) {
/**
Dismisses the update and skips being notified of it in the future.
*/
SPUUserUpdateChoiceSkip,
/**
Downloads (if needed) and installs the update.
*/
SPUUserUpdateChoiceInstall,
/**
Dismisses the update until Sparkle reminds the user of it at a later time.
*/
SPUUserUpdateChoiceDismiss,
};
/**
Describes the current stage an update is undergoing.
*/
typedef NS_ENUM(NSInteger, SPUUserUpdateStage) {
/**
The update has not been downloaded.
*/
SPUUserUpdateStageNotDownloaded,
/**
The update has already been downloaded but not begun installing.
*/
SPUUserUpdateStageDownloaded,
/**
The update has already been downloaded and began installing in the background.
*/
SPUUserUpdateStageInstalling
};
/**
This represents the user's current update state.
*/
SU_EXPORT @interface SPUUserUpdateState : NSObject
- (instancetype)init NS_UNAVAILABLE;
/**
The current update stage.
This stage indicates if data has been already downloaded or not, or if an update is currently being installed.
*/
@property (nonatomic, readonly) SPUUserUpdateStage stage;
/**
Indicates whether or not the update check was initiated by the user.
*/
@property (nonatomic, readonly) BOOL userInitiated;
@end
NS_ASSUME_NONNULL_END
#endif /* SPUUserUpdateState_h */

View File

@ -0,0 +1,37 @@
//
// SUAppcast.h
// Sparkle
//
// Created by Andy Matuschak on 3/12/06.
// Copyright 2006 Andy Matuschak. All rights reserved.
//
#ifndef SUAPPCAST_H
#define SUAPPCAST_H
#import <Foundation/Foundation.h>
#import <Sparkle/SUExport.h>
NS_ASSUME_NONNULL_BEGIN
@class SUAppcastItem;
/**
The appcast representing a collection of `SUAppcastItem` items in the feed.
*/
SU_EXPORT @interface SUAppcast : NSObject
- (instancetype)init NS_UNAVAILABLE;
/**
The collection of update items.
These `SUAppcastItem` items are in the same order as specified in the appcast XML feed and are thus not sorted by version.
*/
@property (readonly, copy) NSArray<SUAppcastItem *> *items;
@end
NS_ASSUME_NONNULL_END
#endif

View File

@ -0,0 +1,391 @@
//
// SUAppcastItem.h
// Sparkle
//
// Created by Andy Matuschak on 3/12/06.
// Copyright 2006 Andy Matuschak. All rights reserved.
//
#ifndef SUAPPCASTITEM_H
#define SUAPPCASTITEM_H
#import <Foundation/Foundation.h>
#ifdef BUILDING_SPARKLE_TESTS
// Ignore incorrect warning
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wquoted-include-in-framework-header"
#import "SUExport.h"
#pragma clang diagnostic pop
#else
#import <Sparkle/SUExport.h>
#endif
NS_ASSUME_NONNULL_BEGIN
/**
The appcast item describing an update in the application's appcast feed.
An appcast item represents a single update item in the `SUAppcast` contained within the @c <item> element.
Every appcast item must have a `versionString`, and either a `fileURL` or an `infoURL`.
All the remaining properties describing an update to the application are optional.
Extended documentation and examples on using appcast item features are available at:
https://sparkle-project.org/documentation/publishing/
*/
SU_EXPORT @interface SUAppcastItem : NSObject<NSSecureCoding>
/**
The version of the update item.
Sparkle uses this property to compare update items and determine the best available update item in the `SUAppcast`.
This corresponds to the application update's @c CFBundleVersion
This is extracted from the @c <sparkle:version> element, or the @c sparkle:version attribute from the @c <enclosure> element.
*/
@property (copy, readonly) NSString *versionString;
/**
The human-readable display version of the update item if provided.
This is the version string shown to the user when they are notified of a new update.
This corresponds to the application update's @c CFBundleShortVersionString
This is extracted from the @c <sparkle:shortVersionString> element, or the @c sparkle:shortVersionString attribute from the @c <enclosure> element.
If no short version string is available, this falls back to the update's `versionString`.
*/
@property (copy, readonly) NSString *displayVersionString;
/**
The file URL to the update item if provided.
This download contains the actual update Sparkle will attempt to install.
In cases where a download cannot be provided, an `infoURL` must be provided instead.
A file URL should have an accompanying `contentLength` provided.
This is extracted from the @c url attribute in the @c <enclosure> element.
*/
@property (readonly, nullable) NSURL *fileURL;
/**
The content length of the download in bytes.
This property is used as a fallback when the server doesn't report the content length of the download.
In that case, it is used to report progress of the downloading update to the user.
A warning is outputted if this property is not equal the server's expected content length (if provided).
This is extracted from the @c length attribute in the @c <enclosure> element.
It should be specified if a `fileURL` is provided.
*/
@property (nonatomic, readonly) uint64_t contentLength;
/**
The info URL to the update item if provided.
This informational link is used to direct the user to learn more about an update they cannot download/install directly from within the application.
The link should point to the product's web page.
The informational link will be used if `informationOnlyUpdate` is @c YES
This is extracted from the @c <link> element.
*/
@property (readonly, nullable) NSURL *infoURL;
/**
Indicates whether or not the update item is only informational and has no download.
If `infoURL` is not present, this is @c NO
If `fileURL` is not present, this is @c YES
Otherwise this is determined based on the contents extracted from the @c <sparkle:informationalUpdate> element.
*/
@property (getter=isInformationOnlyUpdate, readonly) BOOL informationOnlyUpdate;
/**
The title of the appcast item if provided.
This is extracted from the @c <title> element.
*/
@property (copy, readonly, nullable) NSString *title;
/**
The date string of the appcast item if provided.
The `date` property is constructed from this property and expects this string to comply with the following date format:
`E, dd MMM yyyy HH:mm:ss Z`
This is extracted from the @c <pubDate> element.
*/
@property (copy, readonly, nullable) NSString *dateString;
/**
The date constructed from the `dateString` property if provided.
Sparkle by itself only uses this property for phased group rollouts specified via `phasedRolloutInterval`, but clients may query this property too.
This date is constructed using the @c en_US locale.
*/
@property (copy, readonly, nullable) NSDate *date;
/**
The release notes URL of the appcast item if provided.
This external link points to an HTML file that Sparkle downloads and renders to show the user a new or old update item's changelog.
An alternative to using an external release notes link is providing an embedded `itemDescription`.
This is extracted from the @c <sparkle:releaseNotesLink> element.
*/
@property (readonly, nullable) NSURL *releaseNotesURL;
/**
The description of the appcast item if provided.
A description may be provided for inline/embedded release notes for new updates using @c <![CDATA[...]]>
This is an alternative to providing a `releaseNotesURL`.
This is extracted from the @c <description> element.
*/
@property (copy, readonly, nullable) NSString *itemDescription;
/**
The full release notes URL of the appcast item if provided.
The link should point to the product's full changelog.
Sparkle's standard user interface offers to show these full release notes when a user checks for a new update and no new update is available.
This is extracted from the @c <sparkle:fullReleaseNotesLink> element.
*/
@property (readonly, nullable) NSURL *fullReleaseNotesURL;
/**
The required minimum system operating version string for this update if provided.
This version string should contain three period-separated components.
Example: @c 10.13.0
Use `minimumOperatingSystemVersionIsOK` property to test if the current running system passes this requirement.
This is extracted from the @c <sparkle:minimumSystemVersion> element.
*/
@property (copy, readonly, nullable) NSString *minimumSystemVersion;
/**
Indicates whether or not the current running system passes the `minimumSystemVersion` requirement.
*/
@property (nonatomic, readonly) BOOL minimumOperatingSystemVersionIsOK;
/**
The required maximum system operating version string for this update if provided.
A maximum system operating version requirement should only be made in unusual scenarios.
This version string should contain three period-separated components.
Example: @c 10.14.0
Use `maximumOperatingSystemVersionIsOK` property to test if the current running system passes this requirement.
This is extracted from the @c <sparkle:maximumSystemVersion> element.
*/
@property (copy, readonly, nullable) NSString *maximumSystemVersion;
/**
Indicates whether or not the current running system passes the `maximumSystemVersion` requirement.
*/
@property (nonatomic, readonly) BOOL maximumOperatingSystemVersionIsOK;
/**
The channel the update item is on if provided.
An update item may specify a custom channel name (such as @c beta) that can only be found by updaters that filter for that channel.
If no channel is provided, the update item is assumed to be on the default channel.
This is extracted from the @c <sparkle:channel> element.
Old applications must be using Sparkle 2 or later to interpret the channel element and to ignore unmatched channels.
*/
@property (nonatomic, readonly, nullable) NSString *channel;
/**
The installation type of the update at `fileURL`
This may be:
- @c application - indicates this is a regular application update.
- @c package - indicates this is a guided package installer update.
- @c interactive-package - indicates this is an interactive package installer update (deprecated; use "package" instead)
This is extracted from the @c sparkle:installationType attribute in the @c <enclosure> element.
If no installation type is provided in the enclosure, the installation type is inferred from the `fileURL` file extension instead.
If the file extension is @c pkg or @c mpkg, the installation type is @c package otherwise it is @c application
Hence, the installation type in the enclosure element only needs to be specified for package based updates distributed inside of a @c zip or other archive format.
Old applications must be using Sparkle 1.26 or later to support downloading bare package updates (`pkg` or `mpkg`) that are not additionally archived inside of a @c zip or other archive format.
*/
@property (nonatomic, copy, readonly) NSString *installationType;
/**
The phased rollout interval of the update item in seconds if provided.
This is the interval between when different groups of users are notified of a new update.
For this property to be used by Sparkle, the published `date` on the update item must be present as well.
After each interval after the update item's `date`, a new group of users become eligible for being notified of the new update.
This is extracted from the @c <sparkle:phasedRolloutInterval> element.
Old applications must be using Sparkle 1.25 or later to support phased rollout intervals, otherwise they may assume updates are immediately available.
*/
@property (copy, readonly, nullable) NSNumber* phasedRolloutInterval;
/**
The minimum bundle version string this update requires for automatically downloading and installing updates if provided.
If an application's bundle version meets this version requirement, it can install the new update item in the background automatically.
Otherwise if the requirement is not met, the user is always prompted to install the update. In this case, the update is assumed to be a `majorUpgrade`.
If the update is a `majorUpgrade` and the update is skipped by the user, other future update alerts with the same `minimumAutoupdateVersion` will also be skipped automatically unless an update specifies `ignoreSkippedUpgradesBelowVersion`.
This version string corresponds to the application's @c CFBundleVersion
This is extracted from the @c <sparkle:minimumAutoupdateVersion> element.
*/
@property (copy, readonly, nullable) NSString *minimumAutoupdateVersion;
/**
Indicates whether or not the update item is a major upgrade.
An update is a major upgrade if the application's bundle version doesn't meet the `minimumAutoupdateVersion` requirement.
*/
@property (getter=isMajorUpgrade, readonly) BOOL majorUpgrade;
/**
Previously skipped upgrades by the user will be ignored if they skipped an update whose version precedes this version.
This can only be applied if the update is a `majorUpgrade`.
This version string corresponds to the application's @c CFBundleVersion
This is extracted from the @c <sparkle:ignoreSkippedUpgradesBelowVersion> element.
Old applications must be using Sparkle 2.1 or later, otherwise this property will be ignored.
*/
@property (nonatomic, readonly, nullable) NSString *ignoreSkippedUpgradesBelowVersion;
/**
Indicates whether or not the update item is critical.
Critical updates are shown to the user more promptly. Sparkle's standard user interface also does not allow them to be skipped.
This is determined and extracted from a top-level @c <sparkle:criticalUpdate> element or a @c sparkle:criticalUpdate element inside of a @c sparkle:tags element.
Old applications must be using Sparkle 2 or later to support the top-level @c <sparkle:criticalUpdate> element.
*/
@property (getter=isCriticalUpdate, readonly) BOOL criticalUpdate;
/**
Specifies the operating system the download update is available for if provided.
If this property is not provided, then the supported operating system is assumed to be macOS.
Known potential values for this string are @c macos and @c windows
Sparkle on Mac ignores update items that are for other operating systems.
This is only useful for sharing appcasts between Sparkle on Mac and Sparkle on other operating systems.
Use `macOsUpdate` property to test if this update item is for macOS.
This is extracted from the @c sparkle:os attribute in the @c <enclosure> element.
*/
@property (copy, readonly, nullable) NSString *osString;
/**
Indicates whether or not this update item is for macOS.
This is determined from the `osString` property.
*/
@property (getter=isMacOsUpdate, readonly) BOOL macOsUpdate;
/**
The delta updates for this update item.
Sparkle uses these to download and apply a smaller update based on the version the user is updating from.
The key is based on the @c sparkle:version of the update.
The value is an update item that will have `deltaUpdate` be @c YES
Clients typically should not need to examine the contents of the delta updates.
This is extracted from the @c <sparkle:deltas> element.
*/
@property (copy, readonly, nullable) NSDictionary<NSString *, SUAppcastItem *> *deltaUpdates;
/**
The expected size of the Sparkle executable file before applying this delta update.
This attribute is used to test if the delta item can still be applied. If Sparkle's executable file has changed (e.g. from having an architecture stripped),
then the delta item cannot be applied.
This is extracted from the @c sparkle:deltaFromSparkleExecutableSize attribute from the @c <enclosure> element of a @c sparkle:deltas item.
This attribute is optional for delta update items.
*/
@property (nonatomic, readonly, nullable) NSNumber *deltaFromSparkleExecutableSize;
/**
An expected set of Sparkle's locales present on disk before applying this delta update.
This attribute is used to test if the delta item can still be applied. If Sparkle's list of locales present on disk (.lproj directories) do not contain any items from this set,
(e.g. from having localization files stripped) then the delta item cannot be applied. This set does not need to be a complete list of locales. Sparkle may even decide
to not process all them. 1-10 should be a decent amount.
This is extracted from the @c sparkle:deltaFromSparkleLocales attribute from the @c <enclosure> element of a @c sparkle:deltas item.
The locales extracted from this attribute are delimited by a comma (e.g. "en,ca,fr,hr,hu"). This attribute is optional for delta update items.
*/
@property (nonatomic, readonly, nullable) NSSet<NSString *> *deltaFromSparkleLocales;
/**
Indicates whether or not the update item is a delta update.
An update item is a delta update if it is in the `deltaUpdates` of another update item.
*/
@property (getter=isDeltaUpdate, readonly) BOOL deltaUpdate;
/**
The dictionary representing the entire appcast item.
This is useful for querying custom extensions or elements from the appcast item.
*/
@property (readonly, copy) NSDictionary *propertiesDictionary;
- (instancetype)init NS_UNAVAILABLE;
/**
An empty appcast item.
This may be used as a potential return value in `-[SPUUpdaterDelegate bestValidUpdateInAppcast:forUpdater:]`
*/
+ (instancetype)emptyAppcastItem;
// Deprecated initializers
- (nullable instancetype)initWithDictionary:(NSDictionary *)dict __deprecated_msg("Properties that depend on the system or application version are not supported when used with this initializer. The designated initializer is available in SUAppcastItem+Private.h. Please first explore other APIs or contact us to describe your use case.");
- (nullable instancetype)initWithDictionary:(NSDictionary *)dict failureReason:(NSString * _Nullable __autoreleasing *_Nullable)error __deprecated_msg("Properties that depend on the system or application version are not supported when used with this initializer. The designated initializer is available in SUAppcastItem+Private.h. Please first explore other APIs or contact us to describe your use case.");
- (nullable instancetype)initWithDictionary:(NSDictionary *)dict relativeToURL:(NSURL * _Nullable)appcastURL failureReason:(NSString * _Nullable __autoreleasing *_Nullable)error __deprecated_msg("Properties that depend on the system or application version are not supported when used with this initializer. The designated initializer is available in SUAppcastItem+Private.h. Please first explore other APIs or contact us to describe your use case.");
@end
NS_ASSUME_NONNULL_END
#endif

View File

@ -0,0 +1,106 @@
//
// SUErrors.h
// Sparkle
//
// Created by C.W. Betts on 10/13/14.
// Copyright (c) 2014 Sparkle Project. All rights reserved.
//
#ifndef SUERRORS_H
#define SUERRORS_H
#import <Foundation/Foundation.h>
#if defined(BUILDING_SPARKLE_TOOL) || defined(BUILDING_SPARKLE_TESTS)
// Ignore incorrect warning
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wquoted-include-in-framework-header"
#import "SUExport.h"
#pragma clang diagnostic pop
#else
#import <Sparkle/SUExport.h>
#endif
/**
* Error domain used by Sparkle
*/
SU_EXPORT extern NSString *const SUSparkleErrorDomain;
typedef NS_ENUM(OSStatus, SUError) {
// Configuration phase errors
SUNoPublicDSAFoundError = 0001,
SUInsufficientSigningError = 0002,
SUInsecureFeedURLError = 0003,
SUInvalidFeedURLError = 0004,
SUInvalidUpdaterError = 0005,
SUInvalidHostBundleIdentifierError = 0006,
SUInvalidHostVersionError = 0007,
// Appcast phase errors.
SUAppcastParseError = 1000,
SUNoUpdateError = 1001,
SUAppcastError = 1002,
SURunningFromDiskImageError = 1003,
SUResumeAppcastError = 1004,
SURunningTranslocated = 1005,
SUWebKitTerminationError = 1006,
// Download phase errors.
SUTemporaryDirectoryError = 2000,
SUDownloadError = 2001,
// Extraction phase errors.
SUUnarchivingError = 3000,
SUSignatureError = 3001,
SUValidationError = 3002,
// Installation phase errors.
SUFileCopyFailure = 4000,
SUAuthenticationFailure = 4001,
SUMissingUpdateError = 4002,
SUMissingInstallerToolError = 4003,
SURelaunchError = 4004,
SUInstallationError = 4005,
SUDowngradeError = 4006,
SUInstallationCanceledError = 4007,
SUInstallationAuthorizeLaterError = 4008,
SUNotValidUpdateError = 4009,
SUAgentInvalidationError = 4010,
SUInstallationRootInteractiveError = 4011,
SUInstallationWriteNoPermissionError = 4012,
// API misuse errors.
SUIncorrectAPIUsageError = 5000
};
/**
The reason why a new update is not available.
*/
typedef NS_ENUM(OSStatus, SPUNoUpdateFoundReason) {
/**
A new update is unavailable for an unknown reason.
*/
SPUNoUpdateFoundReasonUnknown,
/**
A new update is unavailable because the user is on the latest known version in the appcast feed.
*/
SPUNoUpdateFoundReasonOnLatestVersion,
/**
A new update is unavailable because the user is on a version newer than the latest known version in the appcast feed.
*/
SPUNoUpdateFoundReasonOnNewerThanLatestVersion,
/**
A new update is unavailable because the user's operating system version is too old for the update.
*/
SPUNoUpdateFoundReasonSystemIsTooOld,
/**
A new update is unavailable because the user's operating system version is too new for the update.
*/
SPUNoUpdateFoundReasonSystemIsTooNew
};
SU_EXPORT extern NSString *const SPUNoUpdateFoundReasonKey;
SU_EXPORT extern NSString *const SPULatestAppcastItemFoundKey;
SU_EXPORT extern NSString *const SPUNoUpdateFoundUserInitiatedKey;
#endif

View File

@ -0,0 +1,18 @@
//
// SUExport.h
// Sparkle
//
// Created by Jake Petroules on 2014-08-23.
// Copyright (c) 2014 Sparkle Project. All rights reserved.
//
#ifndef SUEXPORT_H
#define SUEXPORT_H
#ifdef BUILDING_SPARKLE
#define SU_EXPORT __attribute__((visibility("default")))
#else
#define SU_EXPORT
#endif
#endif

View File

@ -0,0 +1,63 @@
//
// SUStandardVersionComparator.h
// Sparkle
//
// Created by Andy Matuschak on 12/21/07.
// Copyright 2007 Andy Matuschak. All rights reserved.
//
#ifndef SUSTANDARDVERSIONCOMPARATOR_H
#define SUSTANDARDVERSIONCOMPARATOR_H
#import <Foundation/Foundation.h>
#ifdef BUILDING_SPARKLE_TOOL
// Ignore incorrect warning
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wquoted-include-in-framework-header"
#import "SUExport.h"
#import "SUVersionComparisonProtocol.h"
#pragma clang diagnostic pop
#else
#import <Sparkle/SUExport.h>
#import <Sparkle/SUVersionComparisonProtocol.h>
#endif
NS_ASSUME_NONNULL_BEGIN
/**
Sparkle's default version comparator.
This comparator is adapted from MacPAD, by Kevin Ballard.
It's "dumb" in that it does essentially string comparison,
in components split by character type.
*/
SU_EXPORT @interface SUStandardVersionComparator : NSObject <SUVersionComparison>
/**
Initializes a new instance of the standard version comparator.
*/
- (instancetype)init;
/**
A singleton instance of the comparator.
*/
@property (nonatomic, class, readonly) SUStandardVersionComparator *defaultComparator;
/**
Compares two version strings through textual analysis.
These version strings should be in the format of x, x.y, or x.y.z where each component is a number.
For example, valid version strings include "1.5.3", "500", or "4000.1"
These versions that are compared correspond to the @c CFBundleVersion values of the updates.
@param versionA The first version string to compare.
@param versionB The second version string to compare.
@return A comparison result between @c versionA and @c versionB
*/
- (NSComparisonResult)compareVersion:(NSString *)versionA toVersion:(NSString *)versionB;
@end
NS_ASSUME_NONNULL_END
#endif

View File

@ -0,0 +1,40 @@
//
// SUUpdatePermissionResponse.h
// Sparkle
//
// Created by Mayur Pawashe on 2/8/16.
// Copyright © 2016 Sparkle Project. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <Sparkle/SUExport.h>
/**
This class represents a response for permission to check updates.
*/
SU_EXPORT @interface SUUpdatePermissionResponse : NSObject<NSSecureCoding>
/**
Initializes a new update permission response instance.
@param automaticUpdateChecks Flag for whether to allow automatic update checks.
@param sendSystemProfile Flag for if system profile information should be sent to the server hosting the appcast.
*/
- (instancetype)initWithAutomaticUpdateChecks:(BOOL)automaticUpdateChecks sendSystemProfile:(BOOL)sendSystemProfile;
/*
Use -initWithAutomaticUpdateChecks:sendSystemProfile: instead.
*/
- (instancetype)init NS_UNAVAILABLE;
/**
A read-only property indicating whether automatic update checks are allowed or not.
*/
@property (nonatomic, readonly) BOOL automaticUpdateChecks;
/**
A read-only property indicating if system profile should be sent or not.
*/
@property (nonatomic, readonly) BOOL sendSystemProfile;
@end

View File

@ -0,0 +1,200 @@
//
// SUUpdater.h
// Sparkle
//
// Created by Andy Matuschak on 1/4/06.
// Copyright 2006 Andy Matuschak. All rights reserved.
//
#ifndef SUUPDATER_H
#define SUUPDATER_H
#import <Foundation/Foundation.h>
#import <Sparkle/SUExport.h>
#import <Sparkle/SUVersionComparisonProtocol.h>
#import <Sparkle/SUVersionDisplayProtocol.h>
#import <Sparkle/SUUpdaterDelegate.h>
@class SUAppcastItem, SUAppcast, NSMenuItem;
@protocol SUUpdaterDelegate;
/**
The legacy API in Sparkle for controlling the update mechanism.
This class is now deprecated and acts as a thin wrapper around `SPUUpdater` and `SPUStandardUserDriver`.
If you are migrating to Sparkle 2, use `SPUStandardUpdaterController` instead, or `SPUUpdater` if you need more control.
*/
__deprecated_msg("Deprecated in Sparkle 2. Use SPUStandardUpdaterController instead, or SPUUpdater if you need more control.")
SU_EXPORT @interface SUUpdater : NSObject
@property (unsafe_unretained, nonatomic) IBOutlet id<SUUpdaterDelegate> delegate;
/*!
The shared updater for the main bundle.
This is equivalent to passing [NSBundle mainBundle] to SUUpdater::updaterForBundle:
*/
+ (SUUpdater *)sharedUpdater;
/*!
The shared updater for a specified bundle.
If an updater has already been initialized for the provided bundle, that shared instance will be returned.
*/
+ (SUUpdater *)updaterForBundle:(NSBundle *)bundle;
/*!
Designated initializer for SUUpdater.
If an updater has already been initialized for the provided bundle, that shared instance will be returned.
*/
- (instancetype)initForBundle:(NSBundle *)bundle;
/*!
Explicitly checks for updates and displays a progress dialog while doing so.
This method is meant for a main menu item.
Connect any menu item to this action in Interface Builder,
and Sparkle will check for updates and report back its findings verbosely
when it is invoked.
This will find updates that the user has opted into skipping.
*/
- (IBAction)checkForUpdates:(id)sender;
/*!
The menu item validation used for the -checkForUpdates: action
*/
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem;
/*!
Checks for updates, but does not display any UI unless an update is found.
This is meant for programmatically initating a check for updates. That is,
it will display no UI unless it actually finds an update, in which case it
proceeds as usual.
If automatic downloading of updates it turned on and allowed, however,
this will invoke that behavior, and if an update is found, it will be downloaded
in the background silently and will be prepped for installation.
This will not find updates that the user has opted into skipping.
*/
- (void)checkForUpdatesInBackground;
/*!
A property indicating whether or not to check for updates automatically.
Setting this property will persist in the host bundle's user defaults.
The update schedule cycle will be reset in a short delay after the property's new value is set.
This is to allow reverting this property without kicking off a schedule change immediately
*/
@property (nonatomic) BOOL automaticallyChecksForUpdates;
/*!
A property indicating whether or not updates can be automatically downloaded in the background.
Note that automatic downloading of updates can be disallowed by the developer.
In this case, -automaticallyDownloadsUpdates will return NO regardless of how this property is set.
Setting this property will persist in the host bundle's user defaults.
*/
@property (nonatomic) BOOL automaticallyDownloadsUpdates;
/*!
A property indicating the current automatic update check interval.
Setting this property will persist in the host bundle's user defaults.
The update schedule cycle will be reset in a short delay after the property's new value is set.
This is to allow reverting this property without kicking off a schedule change immediately
*/
@property (nonatomic) NSTimeInterval updateCheckInterval;
/*!
Begins a "probing" check for updates which will not actually offer to
update to that version.
However, the delegate methods
SUUpdaterDelegate::updater:didFindValidUpdate: and
SUUpdaterDelegate::updaterDidNotFindUpdate: will be called,
so you can use that information in your UI.
Updates that have been skipped by the user will not be found.
*/
- (void)checkForUpdateInformation;
/*!
The URL of the appcast used to download update information.
Setting this property will persist in the host bundle's user defaults.
If you don't want persistence, you may want to consider instead implementing
SUUpdaterDelegate::feedURLStringForUpdater: or SUUpdaterDelegate::feedParametersForUpdater:sendingSystemProfile:
This property must be called on the main thread.
*/
@property (nonatomic, copy) NSURL *feedURL;
/*!
The host bundle that is being updated.
*/
@property (readonly, nonatomic) NSBundle *hostBundle;
/*!
The bundle this class (SUUpdater) is loaded into.
*/
@property (nonatomic, readonly) NSBundle *sparkleBundle;
/*!
The user agent used when checking for and downloading updates.
The default implementation can be overrided.
*/
@property (nonatomic, copy) NSString *userAgentString;
/*!
The HTTP headers used when checking for and downloading updates.
The keys of this dictionary are HTTP header fields (NSString) and values are corresponding values (NSString)
*/
@property (copy) NSDictionary<NSString *, NSString *> *httpHeaders;
/*!
A property indicating whether or not the user's system profile information is sent when checking for updates.
Setting this property will persist in the host bundle's user defaults.
*/
@property (nonatomic) BOOL sendsSystemProfile;
/*!
A property indicating the decryption password used for extracting updates shipped as Apple Disk Images (dmg)
*/
@property (nonatomic, copy) NSString *decryptionPassword;
/*!
Returns the date of last update check.
\returns \c nil if no check has been performed.
*/
@property (nonatomic, readonly, copy) NSDate *lastUpdateCheckDate;
/*!
Appropriately schedules or cancels the update checking timer according to
the preferences for time interval and automatic checks.
This call does not change the date of the next check,
but only the internal NSTimer.
*/
- (void)resetUpdateCycle;
/*!
A property indicating whether or not an update is in progress.
Note this property is not indicative of whether or not user initiated updates can be performed.
Use SUUpdater::validateMenuItem: for that instead.
*/
@property (nonatomic, readonly) BOOL updateInProgress;
@end
#endif

View File

@ -0,0 +1,354 @@
//
// SUUpdaterDelegate.h
// Sparkle
//
// Created by Mayur Pawashe on 3/12/16.
// Copyright © 2016 Sparkle Project. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <Sparkle/SUExport.h>
@protocol SUVersionComparison, SUVersionDisplay;
@class SUUpdater, SUAppcast, SUAppcastItem;
NS_ASSUME_NONNULL_BEGIN
// -----------------------------------------------------------------------------
// SUUpdater Notifications for events that might be interesting to more than just the delegate
// The updater will be the notification object
// -----------------------------------------------------------------------------
SU_EXPORT extern NSString *const SUUpdaterDidFinishLoadingAppCastNotification;
SU_EXPORT extern NSString *const SUUpdaterDidFindValidUpdateNotification;
SU_EXPORT extern NSString *const SUUpdaterDidNotFindUpdateNotification;
SU_EXPORT extern NSString *const SUUpdaterWillRestartNotification;
#define SUUpdaterWillRelaunchApplicationNotification SUUpdaterWillRestartNotification;
#define SUUpdaterWillInstallUpdateNotification SUUpdaterWillRestartNotification;
// Key for the SUAppcastItem object in the SUUpdaterDidFindValidUpdateNotification userInfo
SU_EXPORT extern NSString *const SUUpdaterAppcastItemNotificationKey;
// Key for the SUAppcast object in the SUUpdaterDidFinishLoadingAppCastNotification userInfo
SU_EXPORT extern NSString *const SUUpdaterAppcastNotificationKey;
// -----------------------------------------------------------------------------
// SUUpdater Delegate:
// -----------------------------------------------------------------------------
/*!
Provides methods to control the behavior of an SUUpdater object.
*/
__deprecated_msg("Deprecated in Sparkle 2. See SPUUpdaterDelegate instead")
@protocol SUUpdaterDelegate <NSObject>
@optional
/*!
Returns whether to allow Sparkle to pop up.
For example, this may be used to prevent Sparkle from interrupting a setup assistant.
\param updater The SUUpdater instance.
*/
- (BOOL)updaterMayCheckForUpdates:(SUUpdater *)updater;
/*!
Returns additional parameters to append to the appcast URL's query string.
This is potentially based on whether or not Sparkle will also be sending along the system profile.
\param updater The SUUpdater instance.
\param sendingProfile Whether the system profile will also be sent.
\return An array of dictionaries with keys: "key", "value", "displayKey", "displayValue", the latter two being specifically for display to the user.
*/
- (NSArray<NSDictionary<NSString *, NSString *> *> *)feedParametersForUpdater:(SUUpdater *)updater sendingSystemProfile:(BOOL)sendingProfile;
/*!
Returns a custom appcast URL.
Override this to dynamically specify the entire URL.
An alternative may be to use SUUpdaterDelegate::feedParametersForUpdater:sendingSystemProfile:
and let the server handle what kind of feed to provide.
\param updater The SUUpdater instance.
*/
- (nullable NSString *)feedURLStringForUpdater:(SUUpdater *)updater;
/*!
Returns whether Sparkle should prompt the user about automatic update checks.
Use this to override the default behavior.
\param updater The SUUpdater instance.
*/
- (BOOL)updaterShouldPromptForPermissionToCheckForUpdates:(SUUpdater *)updater;
/*!
Called after Sparkle has downloaded the appcast from the remote server.
Implement this if you want to do some special handling with the appcast once it finishes loading.
\param updater The SUUpdater instance.
\param appcast The appcast that was downloaded from the remote server.
*/
- (void)updater:(SUUpdater *)updater didFinishLoadingAppcast:(SUAppcast *)appcast;
/*!
Returns the item in the appcast corresponding to the update that should be installed.
If you're using special logic or extensions in your appcast,
implement this to use your own logic for finding a valid update, if any,
in the given appcast.
\param appcast The appcast that was downloaded from the remote server.
\param updater The SUUpdater instance.
*/
- (nullable SUAppcastItem *)bestValidUpdateInAppcast:(SUAppcast *)appcast forUpdater:(SUUpdater *)updater;
/*!
Called when a valid update is found by the update driver.
\param updater The SUUpdater instance.
\param item The appcast item corresponding to the update that is proposed to be installed.
*/
- (void)updater:(SUUpdater *)updater didFindValidUpdate:(SUAppcastItem *)item;
/*!
Called when a valid update is not found.
\param updater The SUUpdater instance.
*/
- (void)updaterDidNotFindUpdate:(SUUpdater *)updater;
/*!
Called just before the scheduled update driver prompts the user to install an update.
\param updater The SUUpdater instance.
\return YES to allow the update prompt to be shown (the default behavior), or NO to suppress it.
*/
- (BOOL)updaterShouldShowUpdateAlertForScheduledUpdate:(SUUpdater *)updater forItem:(SUAppcastItem *)item;
/*!
Called after the user dismisses the update alert.
\param updater The SUUpdater instance.
\param permanently YES if the alert will not appear again for this update; NO if it may reappear.
*/
- (void)updater:(SUUpdater *)updater didDismissUpdateAlertPermanently:(BOOL)permanently forItem:(SUAppcastItem *)item;
/*!
Called immediately before downloading the specified update.
\param updater The SUUpdater instance.
\param item The appcast item corresponding to the update that is proposed to be downloaded.
\param request The mutable URL request that will be used to download the update.
*/
- (void)updater:(SUUpdater *)updater willDownloadUpdate:(SUAppcastItem *)item withRequest:(NSMutableURLRequest *)request;
/*!
Called immediately after succesfull download of the specified update.
\param updater The SUUpdater instance.
\param item The appcast item corresponding to the update that has been downloaded.
*/
- (void)updater:(SUUpdater *)updater didDownloadUpdate:(SUAppcastItem *)item;
/*!
Called after the specified update failed to download.
\param updater The SUUpdater instance.
\param item The appcast item corresponding to the update that failed to download.
\param error The error generated by the failed download.
*/
- (void)updater:(SUUpdater *)updater failedToDownloadUpdate:(SUAppcastItem *)item error:(NSError *)error;
/*!
Called when the user clicks the cancel button while and update is being downloaded.
\param updater The SUUpdater instance.
*/
- (void)userDidCancelDownload:(SUUpdater *)updater;
/*!
Called immediately before extracting the specified downloaded update.
\param updater The SUUpdater instance.
\param item The appcast item corresponding to the update that is proposed to be extracted.
*/
- (void)updater:(SUUpdater *)updater willExtractUpdate:(SUAppcastItem *)item;
/*!
Called immediately after extracting the specified downloaded update.
\param updater The SUUpdater instance.
\param item The appcast item corresponding to the update that has been extracted.
*/
- (void)updater:(SUUpdater *)updater didExtractUpdate:(SUAppcastItem *)item;
/*!
Called immediately before installing the specified update.
\param updater The SUUpdater instance.
\param item The appcast item corresponding to the update that is proposed to be installed.
*/
- (void)updater:(SUUpdater *)updater willInstallUpdate:(SUAppcastItem *)item;
/*!
Called when an update is skipped by the user.
\param updater The updater instance.
\param item The appcast item corresponding to the update that the user skipped.
*/
- (void)updater:(SUUpdater *)updater userDidSkipThisVersion:(SUAppcastItem *)item;
/*!
Returns whether the relaunch should be delayed in order to perform other tasks.
This is not called if the user didn't relaunch on the previous update,
in that case it will immediately restart.
This may also not be called if the application is not going to relaunch after it terminates.
\param updater The SUUpdater instance.
\param item The appcast item corresponding to the update that is proposed to be installed.
\param invocation The invocation that must be completed with `[invocation invoke]` before continuing with the relaunch.
\return \c YES to delay the relaunch until \p invocation is invoked.
*/
- (BOOL)updater:(SUUpdater *)updater shouldPostponeRelaunchForUpdate:(SUAppcastItem *)item untilInvoking:(NSInvocation *)invocation;
/*!
Returns whether the relaunch should be delayed in order to perform other tasks.
This is not called if the user didn't relaunch on the previous update,
in that case it will immediately restart.
This method acts as a simpler alternative to SUUpdaterDelegate::updater:shouldPostponeRelaunchForUpdate:untilInvoking: avoiding usage of NSInvocation, which is not available in Swift environments.
\param updater The SUUpdater instance.
\param item The appcast item corresponding to the update that is proposed to be installed.
\return \c YES to delay the relaunch.
*/
- (BOOL)updater:(SUUpdater *)updater shouldPostponeRelaunchForUpdate:(SUAppcastItem *)item;
/*!
Returns whether the application should be relaunched at all.
Some apps \b cannot be relaunched under certain circumstances.
This method can be used to explicitly prevent a relaunch.
\param updater The SUUpdater instance.
*/
- (BOOL)updaterShouldRelaunchApplication:(SUUpdater *)updater;
/*!
Called immediately before relaunching.
\param updater The SUUpdater instance.
*/
- (void)updaterWillRelaunchApplication:(SUUpdater *)updater;
/*!
Called immediately after relaunching. SUUpdater delegate must be set before applicationDidFinishLaunching: to catch this event.
\param updater The SUUpdater instance.
*/
- (void)updaterDidRelaunchApplication:(SUUpdater *)updater;
/*!
Returns an object that compares version numbers to determine their arithmetic relation to each other.
This method allows you to provide a custom version comparator.
If you don't implement this method or return \c nil,
the standard version comparator will be used. Note that the
standard version comparator may be used during installation for preventing
a downgrade, even if you provide a custom comparator here.
\sa SUStandardVersionComparator
\param updater The SUUpdater instance.
*/
- (nullable id<SUVersionComparison>)versionComparatorForUpdater:(SUUpdater *)updater;
/*!
Returns an object that formats version numbers for display to the user.
If you don't implement this method or return \c nil, the standard version formatter will be used.
\sa SUUpdateAlert
\param updater The SUUpdater instance.
*/
- (nullable id <SUVersionDisplay>)versionDisplayerForUpdater:(SUUpdater *)updater;
/*!
Returns the path to the application which is used to relaunch after the update is installed.
The installer also waits for the termination of the application at this path.
The default is the path of the host bundle.
\param updater The SUUpdater instance.
*/
- (nullable NSString *)pathToRelaunchForUpdater:(SUUpdater *)updater;
/*!
Called before an updater shows a modal alert window,
to give the host the opportunity to hide attached windows that may get in the way.
\param updater The SUUpdater instance.
*/
- (void)updaterWillShowModalAlert:(SUUpdater *)updater;
/*!
Called after an updater shows a modal alert window,
to give the host the opportunity to hide attached windows that may get in the way.
\param updater The SUUpdater instance.
*/
- (void)updaterDidShowModalAlert:(SUUpdater *)updater;
/*!
Called when an update is scheduled to be silently installed on quit.
This is after an update has been automatically downloaded in the background.
(i.e. SUUpdater::automaticallyDownloadsUpdates is YES)
\param updater The SUUpdater instance.
\param item The appcast item corresponding to the update that is proposed to be installed.
\param invocation Can be used to trigger an immediate silent install and relaunch.
*/
- (void)updater:(SUUpdater *)updater willInstallUpdateOnQuit:(SUAppcastItem *)item immediateInstallationInvocation:(NSInvocation *)invocation;
/*!
Called when an update is scheduled to be silently installed on quit.
This is after an update has been automatically downloaded in the background.
(i.e. SUUpdater::automaticallyDownloadsUpdates is YES)
This method acts as a more modern alternative to SUUpdaterDelegate::updater:willInstallUpdateOnQuit:immediateInstallationInvocation: using a block instead of NSInvocation, which is not available in Swift environments.
\param updater The SUUpdater instance.
\param item The appcast item corresponding to the update that is proposed to be installed.
\param installationBlock Can be used to trigger an immediate silent install and relaunch.
*/
- (void)updater:(SUUpdater *)updater willInstallUpdateOnQuit:(SUAppcastItem *)item immediateInstallationBlock:(void (^)(void))installationBlock;
/*!
Calls after an update that was scheduled to be silently installed on quit has been canceled.
\param updater The SUUpdater instance.
\param item The appcast item corresponding to the update that was proposed to be installed.
\deprecated This method is no longer invoked. The installer will try to its best ability to install the update.
*/
- (void)updater:(SUUpdater *)updater didCancelInstallUpdateOnQuit:(SUAppcastItem *)item __deprecated;
/*!
Called after an update is aborted due to an error.
\param updater The SUUpdater instance.
\param error The error that caused the abort
*/
- (void)updater:(SUUpdater *)updater didAbortWithError:(NSError *)error;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,42 @@
//
// SUVersionComparisonProtocol.h
// Sparkle
//
// Created by Andy Matuschak on 12/21/07.
// Copyright 2007 Andy Matuschak. All rights reserved.
//
#ifndef SUVERSIONCOMPARISONPROTOCOL_H
#define SUVERSIONCOMPARISONPROTOCOL_H
#import <Foundation/Foundation.h>
#ifdef BUILDING_SPARKLE_TOOL
// Ignore incorrect warning
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wquoted-include-in-framework-header"
#import "SUExport.h"
#pragma clang diagnostic pop
#else
#import <Sparkle/SUExport.h>
#endif
NS_ASSUME_NONNULL_BEGIN
/**
Provides version comparison facilities for Sparkle.
*/
@protocol SUVersionComparison
/**
An abstract method to compare two version strings.
Should return NSOrderedAscending if b > a, NSOrderedDescending if b < a,
and NSOrderedSame if they are equivalent.
*/
- (NSComparisonResult)compareVersion:(NSString *)versionA toVersion:(NSString *)versionB; // *** MAY BE CALLED ON NON-MAIN THREAD!
@end
NS_ASSUME_NONNULL_END
#endif

View File

@ -0,0 +1,25 @@
//
// SUVersionDisplayProtocol.h
// EyeTV
//
// Created by Uli Kusterer on 08.12.09.
// Copyright 2009 Elgato Systems GmbH. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <Sparkle/SUExport.h>
/**
Applies special display formatting to version numbers.
*/
SU_EXPORT @protocol SUVersionDisplay
/**
Formats two version strings.
Both versions are provided so that important distinguishing information
can be displayed while also leaving out unnecessary/confusing parts.
*/
- (void)formatVersion:(NSString *_Nonnull*_Nonnull)inOutVersionA andVersion:(NSString *_Nonnull*_Nonnull)inOutVersionB;
@end

View File

@ -0,0 +1,39 @@
//
// Sparkle.h
// Sparkle
//
// Created by Andy Matuschak on 3/16/06. (Modified by CDHW on 23/12/07)
// Copyright 2006 Andy Matuschak. All rights reserved.
//
#ifndef SPARKLE_H
#define SPARKLE_H
// This list should include the shared headers. It doesn't matter if some of them aren't shared (unless
// there are name-space collisions) so we can list all of them to start with:
#import <Sparkle/SUExport.h>
#import <Sparkle/SUAppcast.h>
#import <Sparkle/SUAppcastItem.h>
#import <Sparkle/SUStandardVersionComparator.h>
#import <Sparkle/SPUUpdater.h>
#import <Sparkle/SPUUpdaterDelegate.h>
#import <Sparkle/SPUUpdaterSettings.h>
#import <Sparkle/SUVersionComparisonProtocol.h>
#import <Sparkle/SUVersionDisplayProtocol.h>
#import <Sparkle/SUErrors.h>
#import <Sparkle/SPUUpdatePermissionRequest.h>
#import <Sparkle/SUUpdatePermissionResponse.h>
#import <Sparkle/SPUUserDriver.h>
#import <Sparkle/SPUDownloadData.h>
// UI bits
#import <Sparkle/SPUStandardUpdaterController.h>
#import <Sparkle/SPUStandardUserDriver.h>
#import <Sparkle/SPUStandardUserDriverDelegate.h>
// Deprecated bits
#import <Sparkle/SUUpdater.h>
#import <Sparkle/SUUpdaterDelegate.h>
#endif

View File

@ -0,0 +1,6 @@
framework module Sparkle {
umbrella header "Sparkle.h"
export *
module * { export * }
}

View File

@ -0,0 +1,30 @@
//
// SPUAppcastItemStateResolver.h
// Sparkle
//
// Created by Mayur Pawashe on 5/31/21.
// Copyright © 2021 Sparkle Project. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <Sparkle/SUExport.h>
NS_ASSUME_NONNULL_BEGIN
@class SUStandardVersionComparator, SPUAppcastItemState;
@protocol SUVersionComparison;
/**
Private exposed class used to resolve Appcast Item properties that rely on external factors such as a host.
This resolver is used for constructing appcast items.
*/
SU_EXPORT @interface SPUAppcastItemStateResolver : NSObject
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithHostVersion:(NSString *)hostVersion applicationVersionComparator:(id<SUVersionComparison>)applicationVersionComparator standardVersionComparator:(SUStandardVersionComparator *)standardVersionComparator;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,22 @@
//
// SPUGentleUserDriverReminders.h
// Sparkle
//
// Copyright © 2022 Sparkle Project. All rights reserved.
//
#ifndef SPUGentleUserDriverReminders_h
#define SPUGentleUserDriverReminders_h
/**
A private protocol for user drivers implementing gentle scheduled reminders
*/
@protocol SPUGentleUserDriverReminders
- (void)logGentleScheduledUpdateReminderWarningIfNeeded;
- (void)resetTimeSinceOpportuneUpdateNotice;
@end
#endif /* SPUGentleUserDriverReminders_h */

View File

@ -0,0 +1,19 @@
//
// SPUInstallationType.h
// Sparkle
//
// Created by Mayur Pawashe on 7/24/16.
// Copyright © 2016 Sparkle Project. All rights reserved.
//
#ifndef SPUInstallationType_h
#define SPUInstallationType_h
#define SPUInstallationTypeApplication @"application" // the default installation type for ordinary application updates
#define SPUInstallationTypeGuidedPackage @"package" // the preferred installation type for package installations
#define SPUInstallationTypeInteractivePackage @"interactive-package" // the deprecated installation type; use guided package instead
#define SPUInstallationTypesArray (@[SPUInstallationTypeApplication, SPUInstallationTypeGuidedPackage, SPUInstallationTypeInteractivePackage])
#define SPUValidInstallationType(x) ((x != nil) && [SPUInstallationTypesArray containsObject:(NSString * _Nonnull)x])
#endif /* SPUInstallationType_h */

View File

@ -0,0 +1,31 @@
//
// SPUStandardUserDriver+Private.h
// Sparkle
//
// Copyright © 2022 Sparkle Project. All rights reserved.
//
#ifndef SPUStandardUserDriver_Private_h
#define SPUStandardUserDriver_Private_h
#import <Sparkle/SPUStandardUserDriver.h>
#import <Sparkle/SUExport.h>
@class NSWindowController;
NS_ASSUME_NONNULL_BEGIN
SU_EXPORT @interface SPUStandardUserDriver (Private)
/**
Private API for accessing the active update alert's window controller.
This is the window controller that shows the update's release notes and install choices.
This can be accessed in -[SPUStandardUserDriverDelegate standardUserDriverWillHandleShowingUpdate:forUpdate:state:]
*/
@property (nonatomic, readonly, nullable) NSWindowController *activeUpdateAlert;
@end
NS_ASSUME_NONNULL_END
#endif /* SPUStandardUserDriver_Private_h */

View File

@ -0,0 +1,20 @@
//
// SPUUserAgent+Private.h
// Sparkle
//
// Created by Mayur Pawashe on 11/12/21.
// Copyright © 2021 Sparkle Project. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <Sparkle/SUExport.h>
NS_ASSUME_NONNULL_BEGIN
@class SUHost;
SU_EXPORT NSString *SPUMakeUserAgentWithHost(SUHost *responsibleHost, NSString * _Nullable displayNameSuffix);
SU_EXPORT NSString *SPUMakeUserAgentWithBundle(NSBundle *responsibleBundle, NSString * _Nullable displayNameSuffix);
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,39 @@
//
// SUAppcastItem+Private.h
// Sparkle
//
// Created by Mayur Pawashe on 4/30/21.
// Copyright © 2021 Sparkle Project. All rights reserved.
//
#ifndef SUAppcastItem_Private_h
#define SUAppcastItem_Private_h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
// Available in SPUAppcastItemStateResolver.h (a private exposed header)
@class SPUAppcastItemStateResolver;
@class SUSignatures;
@interface SUAppcastItem (Private) <NSSecureCoding>
/**
Initializes with data from a dictionary provided by the RSS class and state resolver
This initializer method is intended to be marked "private" and discouraged from public usage.
This method is available however. Talk to us to describe your use case and if you need to construct appcast items yourself.
*/
- (nullable instancetype)initWithDictionary:(NSDictionary *)dict relativeToURL:(NSURL * _Nullable)appcastURL stateResolver:(SPUAppcastItemStateResolver *)stateResolver failureReason:(NSString * _Nullable __autoreleasing *_Nullable)error;
/**
The DSA and EdDSA signatures along with their statuses.
*/
@property (readonly, nullable) SUSignatures *signatures;
@end
NS_ASSUME_NONNULL_END
#endif /* SUAppcastItem_Private_h */

View File

@ -0,0 +1,29 @@
//
// SUInstallerLauncher+Private.h
// SUInstallerLauncher+Private
//
// Created by Mayur Pawashe on 8/21/21.
// Copyright © 2021 Sparkle Project. All rights reserved.
//
#ifndef SUInstallerLauncher_Private_h
#define SUInstallerLauncher_Private_h
#import <Sparkle/SUExport.h>
// Chances are clients will need this too
#import <Sparkle/SPUInstallationType.h>
@class NSString;
/**
Private API for determining if the system needs authorization access to update a bundle path
This API is not supported when used directly from a Sandboxed applications and will always return @c YES in that case.
@param bundlePath The bundle path to test if authorization is needed when performing an update that replaces this bundle.
@return @c YES if Sparkle thinks authorization is needed to update the @c bundlePath, otherwise @c NO.
*/
SU_EXPORT BOOL SPUSystemNeedsAuthorizationAccessForBundlePath(NSString *bundlePath);
#endif /* SUInstallerLauncher_Private_h */

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildMachineOSBuild</key>
<string>21G115</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>Sparkle</string>
<key>CFBundleIdentifier</key>
<string>org.sparkle-project.Sparkle</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>Sparkle</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>2.3.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>CFBundleVersion</key>
<string>2021</string>
<key>DTCompiler</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>DTPlatformBuild</key>
<string>13F100</string>
<key>DTPlatformName</key>
<string>macosx</string>
<key>DTPlatformVersion</key>
<string>12.3</string>
<key>DTSDKBuild</key>
<string>21E226</string>
<key>DTSDKName</key>
<string>macosx12.3</string>
<key>DTXcode</key>
<string>1341</string>
<key>DTXcodeBuild</key>
<string>13F100</string>
<key>LSMinimumSystemVersion</key>
<string>10.13</string>
</dict>
</plist>

View File

@ -0,0 +1,13 @@
@media (prefers-color-scheme: dark) {
html {
color-scheme: dark;
color: white;
background: transparent;
}
:link {
color: #419CFF;
}
:link:active {
color: #FF1919;
}
}

Binary file not shown.

View File

@ -0,0 +1,17 @@
/* Class = "NSWindow"; title = "Software Update"; ObjectID = "5"; */
"5.title" = "محدث البرنامج";
/* Class = "NSTextFieldCell"; title = "Release Notes:"; ObjectID = "170"; */
"170.title" = "معلومات عن الإصدار:";
/* Class = "NSButtonCell"; title = "Remind Me Later"; ObjectID = "171"; */
"171.title" = "تذكيري لاحقًا";
/* Class = "NSButtonCell"; title = "Skip This Version"; ObjectID = "172"; */
"172.title" = "تخطي هذا الإصدار";
/* Class = "NSButtonCell"; title = "Install Update"; ObjectID = "173"; */
"173.title" = "تثبيت التحديث";
/* Class = "NSButtonCell"; title = "Automatically download and install updates in the future"; ObjectID = "175"; */
"175.title" = "تنزيل التحديثات وتثبيتها تلقائيًا في المستقبل";

View File

@ -0,0 +1,20 @@
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "43"; */
"43.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "45"; */
"45.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:"; ObjectID = "183"; */
"183.title" = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:";
/* Class = "NSButtonCell"; title = "Dont Check"; ObjectID = "cCJ-V0-aTi"; */
"cCJ-V0-aTi.title" = "عدم التحقق";
/* Class = "NSTextFieldCell"; title = "Check for updates automatically?"; ObjectID = "gmh-T4-BO0"; */
"gmh-T4-BO0.title" = "هل تريد أن يتم التحقق من وجود تحديثات تلقائيًا؟";
/* Class = "NSButtonCell"; title = "Include anonymous system profile"; ObjectID = "gz7-LM-gNf"; */
"gz7-LM-gNf.title" = "تضمين تقرير عن النظام دون ذكر معلومات عن المستخدم";
/* Class = "NSButtonCell"; title = "Check Automatically"; ObjectID = "OhZ-1K-DmA"; */
"OhZ-1K-DmA.title" = "التحقق تلقائيًا";

View File

@ -0,0 +1,17 @@
/* Class = "NSWindow"; title = "Software Update"; ObjectID = "5"; */
"5.title" = "Actualització del programari";
/* Class = "NSTextFieldCell"; title = "Release Notes:"; ObjectID = "170"; */
"170.title" = "Notes d'aquesta versió:";
/* Class = "NSButtonCell"; title = "Remind Me Later"; ObjectID = "171"; */
"171.title" = "Recorda-m'ho més tard";
/* Class = "NSButtonCell"; title = "Skip This Version"; ObjectID = "172"; */
"172.title" = "Omet aquesta versió";
/* Class = "NSButtonCell"; title = "Install Update"; ObjectID = "173"; */
"173.title" = "Instal·la l'actualització";
/* Class = "NSButtonCell"; title = "Automatically download and install updates in the future"; ObjectID = "175"; */
"175.title" = "Descarrega i instal·la les actualitzacions automàticament en el futur";

View File

@ -0,0 +1,17 @@
/* Class = "NSWindow"; title = "Software Update"; ObjectID = "5"; */
"5.title" = "Aktualizace aplikace";
/* Class = "NSTextFieldCell"; title = "Release Notes:"; ObjectID = "170"; */
"170.title" = "Poznámky k vydání:";
/* Class = "NSButtonCell"; title = "Remind Me Later"; ObjectID = "171"; */
"171.title" = "Připomenout později";
/* Class = "NSButtonCell"; title = "Skip This Version"; ObjectID = "172"; */
"172.title" = "Přeskočit tuto verzi";
/* Class = "NSButtonCell"; title = "Install Update"; ObjectID = "173"; */
"173.title" = "Instalovat aktualizaci";
/* Class = "NSButtonCell"; title = "Automatically download and install updates in the future"; ObjectID = "175"; */
"175.title" = "V budoucnu stahovat a instalovat aktualizace automaticky";

View File

@ -0,0 +1,20 @@
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "43"; */
"43.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "45"; */
"45.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:"; ObjectID = "183"; */
"183.title" = "Informace z anonymního systémového profilu pomáhají vývojářům lépe plánovat budoucí vývoj aplikace.\nBudete-li mít nějaký dotaz, obraťte se na nás.\n\nToto jsou informace, které budou odeslány:";
/* Class = "NSButtonCell"; title = "Dont Check"; ObjectID = "cCJ-V0-aTi"; */
"cCJ-V0-aTi.title" = "Nevyhledávat";
/* Class = "NSTextFieldCell"; title = "Check for updates automatically?"; ObjectID = "gmh-T4-BO0"; */
"gmh-T4-BO0.title" = "Vyhledávat aktualizace automaticky?";
/* Class = "NSButtonCell"; title = "Include anonymous system profile"; ObjectID = "gz7-LM-gNf"; */
"gz7-LM-gNf.title" = "Odeslat anonymní systémový profil";
/* Class = "NSButtonCell"; title = "Check Automatically"; ObjectID = "OhZ-1K-DmA"; */
"OhZ-1K-DmA.title" = "Automaticky vyhledávat";

View File

@ -0,0 +1,17 @@
/* Class = "NSWindow"; title = "Software Update"; ObjectID = "5"; */
"5.title" = "Software Update";
/* Class = "NSTextFieldCell"; title = "Release Notes:"; ObjectID = "170"; */
"170.title" = "Om denne udgivelse:";
/* Class = "NSButtonCell"; title = "Remind Me Later"; ObjectID = "171"; */
"171.title" = "Påmind mig senere";
/* Class = "NSButtonCell"; title = "Skip This Version"; ObjectID = "172"; */
"172.title" = "Spring over";
/* Class = "NSButtonCell"; title = "Install Update"; ObjectID = "173"; */
"173.title" = "Installer";
/* Class = "NSButtonCell"; title = "Automatically download and install updates in the future"; ObjectID = "175"; */
"175.title" = "Hent og installer opdateringer automatisk i fremtiden";

View File

@ -0,0 +1,20 @@
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "43"; */
"43.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "45"; */
"45.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:"; ObjectID = "183"; */
"183.title" = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:";
/* Class = "NSButtonCell"; title = "Dont Check"; ObjectID = "cCJ-V0-aTi"; */
"cCJ-V0-aTi.title" = "Søg ikke";
/* Class = "NSTextFieldCell"; title = "Check for updates automatically?"; ObjectID = "gmh-T4-BO0"; */
"gmh-T4-BO0.title" = "Søg efter opdateringer automatisk?";
/* Class = "NSButtonCell"; title = "Include anonymous system profile"; ObjectID = "gz7-LM-gNf"; */
"gz7-LM-gNf.title" = "Vedhæft anonym systemprofil";
/* Class = "NSButtonCell"; title = "Check Automatically"; ObjectID = "OhZ-1K-DmA"; */
"OhZ-1K-DmA.title" = "Søg automatisk";

View File

@ -0,0 +1,17 @@
/* Class = "NSWindow"; title = "Software Update"; ObjectID = "5"; */
"5.title" = "Softwareupdate";
/* Class = "NSTextFieldCell"; title = "Release Notes:"; ObjectID = "170"; */
"170.title" = "Versionshinweise:";
/* Class = "NSButtonCell"; title = "Remind Me Later"; ObjectID = "171"; */
"171.title" = "Später erinnern";
/* Class = "NSButtonCell"; title = "Skip This Version"; ObjectID = "172"; */
"172.title" = "Diese Version überspringen";
/* Class = "NSButtonCell"; title = "Install Update"; ObjectID = "173"; */
"173.title" = "Installieren";
/* Class = "NSButtonCell"; title = "Automatically download and install updates in the future"; ObjectID = "175"; */
"175.title" = "Updates in Zukunft automatisch laden und installieren";

View File

@ -0,0 +1,20 @@
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "43"; */
"43.title" = "";
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "45"; */
"45.title" = "";
/* Class = "NSTextFieldCell"; title = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:"; ObjectID = "183"; */
"183.title" = "Das anonymisierte Systemprofil unterstützt uns bei der zukünftigen Entwicklung. Bitte kontaktiere uns, wenn du Fragen hierzu hast.\n\nDiese Informationen würden an uns gesendet werden:";
/* Class = "NSButtonCell"; title = "Dont Check"; ObjectID = "cCJ-V0-aTi"; */
"cCJ-V0-aTi.title" = "Nicht suchen";
/* Class = "NSTextFieldCell"; title = "Check for updates automatically?"; ObjectID = "gmh-T4-BO0"; */
"gmh-T4-BO0.title" = "Automatisch nach Updates suchen?";
/* Class = "NSButtonCell"; title = "Include anonymous system profile"; ObjectID = "gz7-LM-gNf"; */
"gz7-LM-gNf.title" = "Anonymisiertes Systemprofil übertragen";
/* Class = "NSButtonCell"; title = "Check Automatically"; ObjectID = "OhZ-1K-DmA"; */
"OhZ-1K-DmA.title" = "Automatisch suchen";

View File

@ -0,0 +1,17 @@
/* Class = "NSWindow"; title = "Software Update"; ObjectID = "5"; */
"5.title" = "Ενημέρωση προγράμματος";
/* Class = "NSTextFieldCell"; title = "Release Notes:"; ObjectID = "170"; */
"170.title" = "Σημειώσεις Έκδοσης:";
/* Class = "NSButtonCell"; title = "Remind Me Later"; ObjectID = "171"; */
"171.title" = "Υπενθύμιση Αργότερα";
/* Class = "NSButtonCell"; title = "Skip This Version"; ObjectID = "172"; */
"172.title" = "Παράλειψη Έκδοσης";
/* Class = "NSButtonCell"; title = "Install Update"; ObjectID = "173"; */
"173.title" = "Εγκατάσταση Ενημέρωσης";
/* Class = "NSButtonCell"; title = "Automatically download and install updates in the future"; ObjectID = "175"; */
"175.title" = "Αυτόματη λήψη και εγκατάσταση ενημερώσεων στο μέλλον";

View File

@ -0,0 +1,20 @@
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "43"; */
"43.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "45"; */
"45.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:"; ObjectID = "183"; */
"183.title" = "Οι ανώνυμες πληροφορίες του προφίλ του συστήματός σας, μας βοηθούν στο σχεδιασμό της μελλοντικής ανάπτυξης του προγράμματος. Παρακαλώ επικοινωνήστε μαζί μας άν έχετε ερωτήσεις.\n\nΑυτές είναι οι πληροφορίες που θα σταλούν σε εμάς:";
/* Class = "NSButtonCell"; title = "Dont Check"; ObjectID = "cCJ-V0-aTi"; */
"cCJ-V0-aTi.title" = "Κανένας έλεγχος";
/* Class = "NSTextFieldCell"; title = "Check for updates automatically?"; ObjectID = "gmh-T4-BO0"; */
"gmh-T4-BO0.title" = "Αυτόματος έλεγχος για ενημερώσεις;";
/* Class = "NSButtonCell"; title = "Include anonymous system profile"; ObjectID = "gz7-LM-gNf"; */
"gz7-LM-gNf.title" = "Συμπερίληψη του ανώνυμου προφίλ του συστήματός σας";
/* Class = "NSButtonCell"; title = "Check Automatically"; ObjectID = "OhZ-1K-DmA"; */
"OhZ-1K-DmA.title" = "Αυτόματος Ελεγχος";

View File

@ -0,0 +1,18 @@
/* Class = "NSWindow"; title = "Software Update"; ObjectID = "5"; */
"5.title" = "Software Update";
/* Class = "NSTextFieldCell"; title = "Release Notes:"; ObjectID = "170"; */
"170.title" = "Release Notes:";
/* Class = "NSButtonCell"; title = "Remind Me Later"; ObjectID = "171"; */
"171.title" = "Remind Me Later";
/* Class = "NSButtonCell"; title = "Skip This Version"; ObjectID = "172"; */
"172.title" = "Skip This Version";
/* Class = "NSButtonCell"; title = "Install Update"; ObjectID = "173"; */
"173.title" = "Install Update";
/* Class = "NSButtonCell"; title = "Automatically download and install updates in the future"; ObjectID = "175"; */
"175.title" = "Automatically download and install updates in the future";

View File

@ -0,0 +1,24 @@
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "43"; */
"43.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "45"; */
"45.title" = "Text Cell";
/* Class = "NSButtonCell"; title = "Check Automatically"; ObjectID = "176"; */
"OhZ-1K-DmA.title" = "Check Automatically";
/* Class = "NSButtonCell"; title = "Dont Check"; ObjectID = "177"; */
"cCJ-V0-aTi.title" = "Dont Check";
/* Class = "NSTextFieldCell"; title = "Check for updates automatically?"; ObjectID = "178"; */
"gmh-T4-BO0.title" = "Check for updates automatically?";
/* Class = "NSTextFieldCell"; title = "DO NOT LOCALIZE"; ObjectID = "179"; */
"179.title" = "DO NOT LOCALIZE";
/* Class = "NSButtonCell"; title = "Include anonymous system profile"; ObjectID = "180"; */
"gz7-LM-gNf.title" = "Include anonymous system profile";
/* Class = "NSTextFieldCell"; title = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:"; ObjectID = "183"; */
"183.title" = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:";

View File

@ -0,0 +1,17 @@
/* Class = "NSWindow"; title = "Software Update"; ObjectID = "5"; */
"5.title" = "Actualización de software";
/* Class = "NSTextFieldCell"; title = "Release Notes:"; ObjectID = "170"; */
"170.title" = "Notas de la versión:";
/* Class = "NSButtonCell"; title = "Remind Me Later"; ObjectID = "171"; */
"171.title" = "Recordármelo";
/* Class = "NSButtonCell"; title = "Skip This Version"; ObjectID = "172"; */
"172.title" = "No instalar esta versión";
/* Class = "NSButtonCell"; title = "Install Update"; ObjectID = "173"; */
"173.title" = "Instalar actualización";
/* Class = "NSButtonCell"; title = "Automatically download and install updates in the future"; ObjectID = "175"; */
"175.title" = "Descargar e instalar actualizaciones automáticamente";

View File

@ -0,0 +1,20 @@
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "43"; */
"43.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "45"; */
"45.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:"; ObjectID = "183"; */
"183.title" = "La información de perfil de sistema anónimo se usa para ayudarnos a planear el trabajo de desarrollo futuro. Por favor, póngase en contacto con nosotros si tiene preguntas sobre esto.\n\nEsta es la información que nos enviaría:";
/* Class = "NSButtonCell"; title = "Dont Check"; ObjectID = "cCJ-V0-aTi"; */
"cCJ-V0-aTi.title" = "No comprobar";
/* Class = "NSTextFieldCell"; title = "Check for updates automatically?"; ObjectID = "gmh-T4-BO0"; */
"gmh-T4-BO0.title" = "¿Comprobar si hay actualizaciones automáticamente?";
/* Class = "NSButtonCell"; title = "Include anonymous system profile"; ObjectID = "gz7-LM-gNf"; */
"gz7-LM-gNf.title" = "Incluir perfil de sistema anónimo";
/* Class = "NSButtonCell"; title = "Check Automatically"; ObjectID = "OhZ-1K-DmA"; */
"OhZ-1K-DmA.title" = "Comprobar automáticamente";

View File

@ -0,0 +1,17 @@
/* Class = "NSWindow"; title = "Software Update"; ObjectID = "5"; */
"5.title" = "Ohjelmiston pävitys";
/* Class = "NSTextFieldCell"; title = "Release Notes:"; ObjectID = "170"; */
"170.title" = "Tietoa päivityksestä:";
/* Class = "NSButtonCell"; title = "Remind Me Later"; ObjectID = "171"; */
"171.title" = "Muistuta myöhemmin";
/* Class = "NSButtonCell"; title = "Skip This Version"; ObjectID = "172"; */
"172.title" = "Ohita tämä versio";
/* Class = "NSButtonCell"; title = "Install Update"; ObjectID = "173"; */
"173.title" = "Asenna päivitys";
/* Class = "NSButtonCell"; title = "Automatically download and install updates in the future"; ObjectID = "175"; */
"175.title" = "Hae ja asenna päivitykset jatkossa automaattisesti";

View File

@ -0,0 +1,20 @@
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "43"; */
"43.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "45"; */
"45.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:"; ObjectID = "183"; */
"183.title" = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:";
/* Class = "NSButtonCell"; title = "Dont Check"; ObjectID = "cCJ-V0-aTi"; */
"cCJ-V0-aTi.title" = "Älä tarkista";
/* Class = "NSTextFieldCell"; title = "Check for updates automatically?"; ObjectID = "gmh-T4-BO0"; */
"gmh-T4-BO0.title" = "Tarkista päivityksiä käynnistyksen yhteydessä?";
/* Class = "NSButtonCell"; title = "Include anonymous system profile"; ObjectID = "gz7-LM-gNf"; */
"gz7-LM-gNf.title" = "Sisällytä nimetön järjestelmäprofiili";
/* Class = "NSButtonCell"; title = "Check Automatically"; ObjectID = "OhZ-1K-DmA"; */
"OhZ-1K-DmA.title" = "Tarkista automaattisesti";

View File

@ -0,0 +1,17 @@
/* Class = "NSWindow"; title = "Software Update"; ObjectID = "5"; */
"5.title" = "Mise à jour logiciel";
/* Class = "NSTextFieldCell"; title = "Release Notes:"; ObjectID = "170"; */
"170.title" = "Notes de version :";
/* Class = "NSButtonCell"; title = "Remind Me Later"; ObjectID = "171"; */
"171.title" = "Pas maintenant";
/* Class = "NSButtonCell"; title = "Skip This Version"; ObjectID = "172"; */
"172.title" = "Ignorer cette version";
/* Class = "NSButtonCell"; title = "Install Update"; ObjectID = "173"; */
"173.title" = "Installer";
/* Class = "NSButtonCell"; title = "Automatically download and install updates in the future"; ObjectID = "175"; */
"175.title" = "Télécharger et installer automatiquement les mises à jour";

View File

@ -0,0 +1,20 @@
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "43"; */
"43.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "45"; */
"45.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:"; ObjectID = "183"; */
"183.title" = "Les informations anonymes de profil système nous aident à planifier les futurs développements. Contactez-nous pour toute question à ce sujet.\n\nCi-dessous figurent les informations qui seront transmises :";
/* Class = "NSButtonCell"; title = "Dont Check"; ObjectID = "cCJ-V0-aTi"; */
"cCJ-V0-aTi.title" = "Ne pas vérifier";
/* Class = "NSTextFieldCell"; title = "Check for updates automatically?"; ObjectID = "gmh-T4-BO0"; */
"gmh-T4-BO0.title" = "Rechercher automatiquement les mises à jour ?";
/* Class = "NSButtonCell"; title = "Include anonymous system profile"; ObjectID = "gz7-LM-gNf"; */
"gz7-LM-gNf.title" = "Avec transmission anonyme de mon profil système";
/* Class = "NSButtonCell"; title = "Check Automatically"; ObjectID = "OhZ-1K-DmA"; */
"OhZ-1K-DmA.title" = "Vérifier automatiquement";

View File

@ -0,0 +1,17 @@
/* Class = "NSWindow"; title = "Software Update"; ObjectID = "5"; */
"5.title" = "עדכון תכנה";
/* Class = "NSTextFieldCell"; title = "Release Notes:"; ObjectID = "170"; */
"170.title" = "פרטי גרסה:";
/* Class = "NSButtonCell"; title = "Remind Me Later"; ObjectID = "171"; */
"171.title" = "הזכר לי מאוחר יותר";
/* Class = "NSButtonCell"; title = "Skip This Version"; ObjectID = "172"; */
"172.title" = "דלג על גרסה זו";
/* Class = "NSButtonCell"; title = "Install Update"; ObjectID = "173"; */
"173.title" = "התקן עדכון";
/* Class = "NSButtonCell"; title = "Automatically download and install updates in the future"; ObjectID = "175"; */
"175.title" = "הורד והתקן עדכונים אוטומטית גם בעתיד";

View File

@ -0,0 +1,17 @@
/* Class = "NSWindow"; title = "Software Update"; ObjectID = "5"; */
"5.title" = "Aktualiziranje softvera";
/* Class = "NSTextFieldCell"; title = "Release Notes:"; ObjectID = "170"; */
"170.title" = "Napomene uz izdanje:";
/* Class = "NSButtonCell"; title = "Remind Me Later"; ObjectID = "171"; */
"171.title" = "Podsjeti me kasnije";
/* Class = "NSButtonCell"; title = "Skip This Version"; ObjectID = "172"; */
"172.title" = "Zanemari ovu verziju";
/* Class = "NSButtonCell"; title = "Install Update"; ObjectID = "173"; */
"173.title" = "Instaliraj nadogradnju";
/* Class = "NSButtonCell"; title = "Automatically download and install updates in the future"; ObjectID = "175"; */
"175.title" = "Ubuduće preuzmi i instaliraj nadogradnje automatski";

View File

@ -0,0 +1,20 @@
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "43"; */
"43.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "45"; */
"45.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:"; ObjectID = "183"; */
"183.title" = "Anonimizirani podaci profila susatava pomažu nam planirati budući razvoj. Kontaktiraj nas, ako imaš pitanja o tome.\n\nŠalju se sljedeći podaci:";
/* Class = "NSButtonCell"; title = "Dont Check"; ObjectID = "cCJ-V0-aTi"; */
"cCJ-V0-aTi.title" = "Nemoj provjeravati";
/* Class = "NSTextFieldCell"; title = "Check for updates automatically?"; ObjectID = "gmh-T4-BO0"; */
"gmh-T4-BO0.title" = "Automatski provjeriti nadogradnje?";
/* Class = "NSButtonCell"; title = "Include anonymous system profile"; ObjectID = "gz7-LM-gNf"; */
"gz7-LM-gNf.title" = "Uključi anonimizirane podatke o profilu sustava";
/* Class = "NSButtonCell"; title = "Check Automatically"; ObjectID = "OhZ-1K-DmA"; */
"OhZ-1K-DmA.title" = "Provjeri automatski";

View File

@ -0,0 +1,17 @@
/* Class = "NSWindow"; title = "Software Update"; ObjectID = "5"; */
"5.title" = "Szoftverfrissítés";
/* Class = "NSTextFieldCell"; title = "Release Notes:"; ObjectID = "170"; */
"170.title" = "Változások az előző verzióhoz képest:";
/* Class = "NSButtonCell"; title = "Remind Me Later"; ObjectID = "171"; */
"171.title" = "Emlékeztessen később";
/* Class = "NSButtonCell"; title = "Skip This Version"; ObjectID = "172"; */
"172.title" = "Verzió kihagyása";
/* Class = "NSButtonCell"; title = "Install Update"; ObjectID = "173"; */
"173.title" = "Telepítés";
/* Class = "NSButtonCell"; title = "Automatically download and install updates in the future"; ObjectID = "175"; */
"175.title" = "A jövőben automatikusan töltse le és telepítse a frissítéseket";

View File

@ -0,0 +1,20 @@
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "43"; */
"43.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "45"; */
"45.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:"; ObjectID = "183"; */
"183.title" = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:";
/* Class = "NSButtonCell"; title = "Dont Check"; ObjectID = "cCJ-V0-aTi"; */
"cCJ-V0-aTi.title" = "Manuális keresés";
/* Class = "NSTextFieldCell"; title = "Check for updates automatically?"; ObjectID = "gmh-T4-BO0"; */
"gmh-T4-BO0.title" = "Keresse automatikusan a frissítéseket?";
/* Class = "NSButtonCell"; title = "Include anonymous system profile"; ObjectID = "gz7-LM-gNf"; */
"gz7-LM-gNf.title" = "Anonim rendszerinformáció küldése";
/* Class = "NSButtonCell"; title = "Check Automatically"; ObjectID = "OhZ-1K-DmA"; */
"OhZ-1K-DmA.title" = "Automatikus keresés";

View File

@ -0,0 +1,17 @@
/* Class = "NSWindow"; title = "Software Update"; ObjectID = "5"; */
"5.title" = "Hugbúnaðaruppfærsla";
/* Class = "NSTextFieldCell"; title = "Release Notes:"; ObjectID = "170"; */
"170.title" = "Útgáfupunktar:";
/* Class = "NSButtonCell"; title = "Remind Me Later"; ObjectID = "171"; */
"171.title" = "Áminntu mig síðar";
/* Class = "NSButtonCell"; title = "Skip This Version"; ObjectID = "172"; */
"172.title" = "Sleppa þessari útgáfu";
/* Class = "NSButtonCell"; title = "Install Update"; ObjectID = "173"; */
"173.title" = "Innsetja";
/* Class = "NSButtonCell"; title = "Automatically download and install updates in the future"; ObjectID = "175"; */
"175.title" = "Sækja og innsetja uppfærslur sjálfkrafa framvegis";

View File

@ -0,0 +1,20 @@
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "43"; */
"43.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "45"; */
"45.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:"; ObjectID = "183"; */
"183.title" = "Upplýsingar úr nafnlausum kerfisskýrslum eru notaðar til að hjálpa okkur við framtíðarþróun hugbúnaðarins. Ekki hika við að hafa samband ef spurningar vakna um þetta.\n\nÞetta eru upplýsingarnar sem yrðu sendar:";
/* Class = "NSButtonCell"; title = "Dont Check"; ObjectID = "cCJ-V0-aTi"; */
"cCJ-V0-aTi.title" = "Ekki kanna";
/* Class = "NSTextFieldCell"; title = "Check for updates automatically?"; ObjectID = "gmh-T4-BO0"; */
"gmh-T4-BO0.title" = "Athuga sjálfkrafa með uppfærslur?";
/* Class = "NSButtonCell"; title = "Include anonymous system profile"; ObjectID = "gz7-LM-gNf"; */
"gz7-LM-gNf.title" = "Innifela nafnlausa kerfisskýrslu";
/* Class = "NSButtonCell"; title = "Check Automatically"; ObjectID = "OhZ-1K-DmA"; */
"OhZ-1K-DmA.title" = "Kanna sjálfkrafa";

Some files were not shown because too many files have changed in this diff Show More