Skip to content

Commit

Permalink
- Added Sparkle Framework to enable automatic updates. Closes Issue #21.
Browse files Browse the repository at this point in the history
- Organized Preferences window to multi-tab interface. Added preferences related to automatic update checking.
- Bumped version number to 1.2.0.
- Updated About TodoTxtMac text.
- Updated README.md to add FAQs and for other small changes.
  • Loading branch information
mjdescy committed Jun 25, 2014
1 parent 829c491 commit e2830e3
Show file tree
Hide file tree
Showing 108 changed files with 2,855 additions and 285 deletions.
39 changes: 36 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ From a design perspective the goal is to be the fastest, simplest, and cleanest
- Full compliance with the todo.txt format spec.
- Fully keyboard-driven, with one-key bindings for commonly-used commands.
- Multiple selection in the task list.
- Support for due dates, which are formatted "due:YYYY-MM-DD".
- Shortcuts to toggle completion, change priority, set due dates, and delete all selected tasks.
- Archive completed tasks (to done.txt), either on command or automatically.
- Preserves Windows or Unix line endings in the todo.txt file for cross-platform compatability.
- Automatic update checking.

## Adding/removing tasks

Expand Down Expand Up @@ -120,10 +122,38 @@ From a design perspective the goal is to be the fastest, simplest, and cleanest
- 9: apply quick filter 9
- 0: remove applied filter

## Caveats/Features Not Planned
# Features Not Planned

- This application is not meant for direct reordering of tasks in the todo.txt file.
- This application does not retain blank lines in the todo.txt file.
- This application does not support line breaks, long-form notes, attachments, or other features not part of the todo.txt format specification.

# Frequently Asked Questions (FAQ)

## Is there a preference to re-open my todo.txt file on launch?

No, there is no preference, but the application will do this automatically under normal circumstances. The default behavior of TodoTxtMac is to reopen whatever todo.txt files were open when you last quit the app. To enjoy this behavior, do not close your todo.txt file's window prior to quitting the app. This behavior is dependent on

If the TodoTxtMac is not reopening your files, or keeping a list of them in the "File > Open Recent" menu, then you should check the following preferences under System Preferences > General:

1. "Close windows when quitting an application" must be unchecked.
2. "Recent items" must not be "None".

## Is this application Dropbox-enabled?

No. Unlike the official Todo.txt iOS application, this application does not call Dropbox's API. You can sync your file outside of TodoTxtMac via Dropbox or other services.

## TodoTxtMac says my todo.txt file cannot be autosaved. The file has been changed by another application.

Your todo.txt file can get modified outside of TodoTxtMac, especially if you are syncing the file via Dropbox or a similar service. TodoTxtMac uses Cocoa's default document object model to handle the file interactions. This means that the application will warn you of file changes that came from outside the application when you try to make changes to the file, not at the moment the file was changed. To avoid file conflicts, try the following strategies:

1. Reload your TodoTxtMac file manually (press `.`) before making changes to it, if you believe the file was updated (by Dropbox for example) recently.
2. Close TodoTxtMac when not using it for extended periods.
3. When presented with the option to "Save Anyway" or "Revert" changes, always revert changes. You will have to re-do your last action in TodoTxtMac, but you will not lose the changes that originated outside the application.

## Will this project be ported from Objective C to Swift?

At this time, there are no plans to move from Objective C to Swift.

# License

Expand Down Expand Up @@ -152,13 +182,16 @@ The project uses [git-flow] to implement Vincent Driessen's [branching model]. A

Thanks to Gina Tripani who created the [Todo.txt][] format and the community of developers who created the command line tools and iOS/Android apps.

Thanks to Ben Hughes whose Windows application [todotxt.net] formed the basis of this application's design and feature set. Todotxt.net is a fantastic program and did not have an analog on the Mac. After starting my application, I contributed some patches to todotxt.net and am happy to be a contributor on such a great project.
Thanks to Ben Hughes whose Windows application [todotxt.net][] formed the basis of this application's design and feature set. Todotxt.net is a fantastic program and did not have an analog on the Mac. After starting my application, I contributed some patches to todotxt.net and am happy to be a contributor on such a great project.

Thanks to Josh Wright <@BendyTree> for his [RegExCategories][] library.

Thanks to kuba for the image used as the icon. Image Credit: [OK Icon][] from [Vector.me][] (by kuba)
Thanks to kuba for the image used as the icon. Image Credit: [OK Icon][] from [Vector.me][] (by kuba).

Thanks to Andy Matuschak and the other contributors for the [Sparkle framework].

[Todo.txt]: http://www.todotxt.com
[RegExCategories]: https://github.com/bendytree/Objective-C-RegEx-Categories
[OK Icon]: http://vector.me/browse/329308/ok_icon
[Vector.me]: http://vector.me/
[Sparkle framework]: http://sparkle.andymatuschak.org/
1 change: 1 addition & 0 deletions Sparkle.framework/Headers
1 change: 1 addition & 0 deletions Sparkle.framework/Resources
1 change: 1 addition & 0 deletions Sparkle.framework/Sparkle
33 changes: 33 additions & 0 deletions Sparkle.framework/Versions/A/Headers/SUAppcast.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// SUAppcast.h
// Sparkle
//
// Created by Andy Matuschak on 3/12/06.
// Copyright 2006 Andy Matuschak. All rights reserved.
//

#ifndef SUAPPCAST_H
#define SUAPPCAST_H

@class SUAppcastItem;
@interface SUAppcast : NSObject {
NSArray *items;
NSString *userAgentString;
id delegate;
NSMutableData *incrementalData;
}

- (void)fetchAppcastFromURL:(NSURL *)url;
- (void)setDelegate:delegate;
- (void)setUserAgentString:(NSString *)userAgentString;

- (NSArray *)items;

@end

@interface NSObject (SUAppcastDelegate)
- (void)appcastDidFinishLoading:(SUAppcast *)appcast;
- (void)appcast:(SUAppcast *)appcast failedToLoadWithError:(NSError *)error;
@end

#endif
47 changes: 47 additions & 0 deletions Sparkle.framework/Versions/A/Headers/SUAppcastItem.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//
// SUAppcastItem.h
// Sparkle
//
// Created by Andy Matuschak on 3/12/06.
// Copyright 2006 Andy Matuschak. All rights reserved.
//

#ifndef SUAPPCASTITEM_H
#define SUAPPCASTITEM_H

@interface SUAppcastItem : NSObject {
NSString *title;
NSDate *date;
NSString *itemDescription;

NSURL *releaseNotesURL;

NSString *DSASignature;
NSString *minimumSystemVersion;

NSURL *fileURL;
NSString *versionString;
NSString *displayVersionString;

NSDictionary *propertiesDictionary;
}

// Initializes with data from a dictionary provided by the RSS class.
- initWithDictionary:(NSDictionary *)dict;

- (NSString *)title;
- (NSString *)versionString;
- (NSString *)displayVersionString;
- (NSDate *)date;
- (NSString *)itemDescription;
- (NSURL *)releaseNotesURL;
- (NSURL *)fileURL;
- (NSString *)DSASignature;
- (NSString *)minimumSystemVersion;

// Returns the dictionary provided in initWithDictionary; this might be useful later for extensions.
- (NSDictionary *)propertiesDictionary;

@end

#endif
118 changes: 118 additions & 0 deletions Sparkle.framework/Versions/A/Headers/SUUpdater.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
//
// 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 <Sparkle/SUVersionComparisonProtocol.h>

@class SUUpdateDriver, SUAppcastItem, SUHost, SUAppcast;
@interface SUUpdater : NSObject {
NSTimer *checkTimer;
SUUpdateDriver *driver;

SUHost *host;
IBOutlet id delegate;
}

+ (SUUpdater *)sharedUpdater;
+ (SUUpdater *)updaterForBundle:(NSBundle *)bundle;
- (NSBundle *)hostBundle;

- (void)setDelegate:(id)delegate;
- delegate;

- (void)setAutomaticallyChecksForUpdates:(BOOL)automaticallyChecks;
- (BOOL)automaticallyChecksForUpdates;

- (void)setUpdateCheckInterval:(NSTimeInterval)interval;
- (NSTimeInterval)updateCheckInterval;

- (void)setFeedURL:(NSURL *)feedURL;
- (NSURL *)feedURL;

- (void)setSendsSystemProfile:(BOOL)sendsSystemProfile;
- (BOOL)sendsSystemProfile;

- (void)setAutomaticallyDownloadsUpdates:(BOOL)automaticallyDownloadsUpdates;
- (BOOL)automaticallyDownloadsUpdates;

// This IBAction is meant for a main menu item. Hook up any menu item to this action,
// and Sparkle will check for updates and report back its findings verbosely.
- (IBAction)checkForUpdates:sender;

// This kicks off an update meant to be programmatically initiated. That is, it will display no UI unless it actually finds an update,
// in which case it proceeds as usual. If the fully automated updating is turned on, however, this will invoke that behavior, and if an
// update is found, it will be downloaded and prepped for installation.
- (void)checkForUpdatesInBackground;

// Date of last update check. Returns null if no check has been performed.
- (NSDate*)lastUpdateCheckDate;

// This begins a "probing" check for updates which will not actually offer to update to that version. The delegate methods, though,
// (up to updater:didFindValidUpdate: and updaterDidNotFindUpdate:), are called, so you can use that information in your UI.
- (void)checkForUpdateInformation;

// Call this to appropriately schedule or cancel 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;

- (BOOL)updateInProgress;
@end

@interface NSObject (SUUpdaterDelegateInformalProtocol)
// This method allows you to add extra parameters to the appcast URL, potentially based on whether or not Sparkle will also be sending along the system profile. This method should return an array of dictionaries with keys: "key", "value", "displayKey", "displayValue", the latter two being specifically for display to the user.
- (NSArray *)feedParametersForUpdater:(SUUpdater *)updater sendingSystemProfile:(BOOL)sendingProfile;

// Use this to override the default behavior for Sparkle prompting the user about automatic update checks.
- (BOOL)updaterShouldPromptForPermissionToCheckForUpdates:(SUUpdater *)bundle;

// Implement this if you want to do some special handling with the appcast once it finishes loading.
- (void)updater:(SUUpdater *)updater didFinishLoadingAppcast:(SUAppcast *)appcast;

// 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.
- (SUAppcastItem *)bestValidUpdateInAppcast:(SUAppcast *)appcast forUpdater:(SUUpdater *)bundle;

// Sent when a valid update is found by the update driver.
- (void)updater:(SUUpdater *)updater didFindValidUpdate:(SUAppcastItem *)update;

// Sent when a valid update is not found.
- (void)updaterDidNotFindUpdate:(SUUpdater *)update;

// Sent immediately before installing the specified update.
- (void)updater:(SUUpdater *)updater willInstallUpdate:(SUAppcastItem *)update;

// Return YES to delay the relaunch until you do some processing; invoke the given NSInvocation to continue.
- (BOOL)updater:(SUUpdater *)updater shouldPostponeRelaunchForUpdate:(SUAppcastItem *)update untilInvoking:(NSInvocation *)invocation;

// Called immediately before relaunching.
- (void)updaterWillRelaunchApplication:(SUUpdater *)updater;

// This method allows you to provide a custom version comparator.
// If you don't implement this method or return nil, the standard version comparator will be used.
- (id <SUVersionComparison>)versionComparatorForUpdater:(SUUpdater *)updater;

// Returns the path which is used to relaunch the client after the update is installed. By default, the path of the host bundle.
- (NSString *)pathToRelaunchForUpdater:(SUUpdater *)updater;

@end

// Define some minimum intervals to avoid DOS-like checking attacks. These are in seconds.
#ifdef DEBUG
#define SU_MIN_CHECK_INTERVAL 60
#else
#define SU_MIN_CHECK_INTERVAL 60*60
#endif

#ifdef DEBUG
#define SU_DEFAULT_CHECK_INTERVAL 60
#else
#define SU_DEFAULT_CHECK_INTERVAL 60*60*24
#endif

#endif
27 changes: 27 additions & 0 deletions Sparkle.framework/Versions/A/Headers/SUVersionComparisonProtocol.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//
// SUVersionComparisonProtocol.h
// Sparkle
//
// Created by Andy Matuschak on 12/21/07.
// Copyright 2007 Andy Matuschak. All rights reserved.
//

#ifndef SUVERSIONCOMPARISONPROTOCOL_H
#define SUVERSIONCOMPARISONPROTOCOL_H

/*!
@protocol
@abstract Implement this protocol to provide version comparison facilities for Sparkle.
*/
@protocol SUVersionComparison

/*!
@method
@abstract An abstract method to compare two version strings.
@discussion Should return NSOrderedAscending if b > a, NSOrderedDescending if b < a, and NSOrderedSame if they are equivalent.
*/
- (NSComparisonResult)compareVersion:(NSString *)versionA toVersion:(NSString *)versionB;

@end

#endif
21 changes: 21 additions & 0 deletions Sparkle.framework/Versions/A/Headers/Sparkle.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// 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/SUUpdater.h>

#import <Sparkle/SUAppcast.h>
#import <Sparkle/SUAppcastItem.h>
#import <Sparkle/SUVersionComparisonProtocol.h>

#endif
24 changes: 24 additions & 0 deletions Sparkle.framework/Versions/A/Resources/Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?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>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>Sparkle</string>
<key>CFBundleIdentifier</key>
<string>org.andymatuschak.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>1.5 Beta 6</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>313</string>
</dict>
</plist>
7 changes: 7 additions & 0 deletions Sparkle.framework/Versions/A/Resources/License.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Copyright (c) 2006 Andy Matuschak

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Loading

0 comments on commit e2830e3

Please sign in to comment.