Skip to content

Commit

Permalink
Merge branch 'release/1.5.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
mjdescy committed Mar 3, 2015
2 parents aca634d + 864d212 commit 0352c91
Show file tree
Hide file tree
Showing 47 changed files with 4,364 additions and 921 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ From a design perspective the goal is to be the fastest, simplest, and cleanest
- Bold priorities in task list.
- Colors completed tasks in light gray and applies strikethrough.
- Colors overdue tasks in purple and tasks due today in red. Both these colors are user customizable.
- User-customizable colors for projects, contexts, due dates, threshold dates, and arbitrary tags in task list.
- User-customizable colors for projects, contexts, due dates, threshold dates, creation dates, and arbitrary tags in task list.

## Mac-specific user interface features

Expand All @@ -77,6 +77,7 @@ From a design perspective the goal is to be the fastest, simplest, and cleanest
- U or Enter: update task
- P: postpone task by X (user-entered) days
- S: set due date
- Option+S: set threshold date
- I: set priority to user-entered value (A-Z)
- T: append text to end of selected tasks
- R: prepend text to beginning of selected tasks (after priority and creation date if they exist)
Expand Down Expand Up @@ -114,7 +115,7 @@ From a design perspective the goal is to be the fastest, simplest, and cleanest

## Filtering the task list

- Command+F: find (moves focus to the search field)
- Command+F: find within displayed tasks (moves focus to the search field)
- F: define quick filters
- 1: apply quick filter 1
- 2: apply quick filter 2
Expand Down Expand Up @@ -164,7 +165,7 @@ Your todo.txt file can get modified outside of TodoTxtMac, especially if you are

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

At this time, there are no plans to move from Objective C to Swift.
When Apple officially deprecates Objective C, the plan is to migrate this project to Swift.

# License

Expand Down
147 changes: 133 additions & 14 deletions TodoTxtMac.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion TodoTxtMac/Base.lproj/TTMDocument.xib
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
<connections>
<binding destination="z03-iY-Esn" name="predicate" keyPath="filterPredicate" id="BCD-jx-NVb">
<binding destination="-2" name="predicate" keyPath="self.searchFieldPredicate" id="GIK-On-p5m">
<dictionary key="options">
<string key="NSDisplayName">predicate</string>
<string key="NSPredicateFormat">rawText contains[cd] $value</string>
Expand Down
67 changes: 67 additions & 0 deletions TodoTxtMac/NSMutableAttributableString+ColorRegExMatches.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/**
* @author Michael Descy
* @copyright 2014-2015 Michael Descy
* @discussion Dual-licensed under the GNU General Public License and the MIT License
*
*
*
* @license GNU General Public License http://www.gnu.org/licenses/gpl.html
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*
*
* @license The MIT License (MIT)
*
* 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.
*/

#import <Foundation/Foundation.h>

@interface NSMutableAttributedString (ColorRegExMatches)

/*!
* @method applyColor:toRegexPatternMatches:
* @abstract Adds foreground color attributes to a mutable attributed string based for all regular
* epxression matches.
* @param color Color to apply
* @param regExPattern Regular expression pattern to apply colors to matches
*/
- (void)applyColor:(NSColor*)color toRegexPatternMatches:(NSString*)regExPattern;

/*!
* @method applyColorToFullStringRange:
* @abstract Adds foreground color attributes to the entire mutable attributed string.
* @param color Color to apply
*/
- (void)applyColorToFullStringRange:(NSColor*)color;

@end
67 changes: 67 additions & 0 deletions TodoTxtMac/NSMutableAttributableString+ColorRegExMatches.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/**
* @author Michael Descy
* @copyright 2014-2015 Michael Descy
* @discussion Dual-licensed under the GNU General Public License and the MIT License
*
*
*
* @license GNU General Public License http://www.gnu.org/licenses/gpl.html
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*
*
* @license The MIT License (MIT)
*
* 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.
*/

#import "NSMutableAttributableString+ColorRegExMatches.h"
#import "RegExCategories.h"

@implementation NSMutableAttributedString (ColorRegExMatches)

- (void)applyColor:(NSColor*)color toRegexPatternMatches:(NSString*)regExPattern {
NSArray *matches = [self.string matchesWithDetails:RX(regExPattern)];
for (RxMatch *match in matches) {
[self addAttribute:NSForegroundColorAttributeName
value:color
range:match.range];
}
}

- (void)applyColorToFullStringRange:(NSColor*)color {
[self addAttribute:NSForegroundColorAttributeName
value:color
range:NSMakeRange(0, [self.string length])];
}

@end
2 changes: 2 additions & 0 deletions TodoTxtMac/TTMAppController.m
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,15 @@
@NO, @"useCustomColorForTags",
@NO, @"useCustomColorForDueDates",
@NO, @"useCustomColorForThresholdDates",
@NO, @"useCustomColorForCreationDates",
[NSArchiver archivedDataWithRootObject:[NSColor redColor]], @"dueTodayColor",
[NSArchiver archivedDataWithRootObject:[NSColor purpleColor]], @"overdueColor",
[NSArchiver archivedDataWithRootObject:[NSColor darkGrayColor]], @"projectColor",
[NSArchiver archivedDataWithRootObject:[NSColor darkGrayColor]], @"contextColor",
[NSArchiver archivedDataWithRootObject:[NSColor darkGrayColor]], @"tagColor",
[NSArchiver archivedDataWithRootObject:[NSColor darkGrayColor]], @"dueDateColor",
[NSArchiver archivedDataWithRootObject:[NSColor darkGrayColor]], @"thresholdDateColor",
[NSArchiver archivedDataWithRootObject:[NSColor darkGrayColor]], @"creationDateColor",
@NO, @"escapeKeyCancelsAllTextChanges",
@NO, @"openDefaultTodoFileOnStartup",
@"", @"defaultTodoFilePath",
Expand Down
12 changes: 2 additions & 10 deletions TodoTxtMac/TTMDateUtility.m
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ + (NSDate*)convertStringToDate:(NSString*)dateString {
// Convert dateString to NSDate.
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"GMT"]];
return [dateFormatter dateFromString:dateTimeString];
}

Expand All @@ -70,8 +69,7 @@ + (NSString*)convertDateToString:(NSDate*)date {
}
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"GMT"]];
return [dateFormatter stringFromDate:date];
return [dateFormatter stringFromDate:date];
}

+ (NSDate*)today {
Expand All @@ -94,13 +92,8 @@ + (NSDate*)dateWithoutTime:(NSDate*)date {
return nil;
}
NSDateComponents *comps = [[NSCalendar currentCalendar]
components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit|
NSHourCalendarUnit|NSMinuteCalendarUnit|NSSecondCalendarUnit
components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit
fromDate:date];
[comps setHour:00];
[comps setMinute:00];
[comps setSecond:00];
[comps setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];

return [[NSCalendar currentCalendar] dateFromComponents:comps];
}
Expand Down Expand Up @@ -182,7 +175,6 @@ + (NSDate*)relativeDateFromWeekdayName:(NSString*)weekdayName
}

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"GMT"]];
[dateFormatter setLocale:[NSLocale currentLocale]];
[dateFormatter setDateFormat:dateFormat];

Expand Down
9 changes: 9 additions & 0 deletions TodoTxtMac/TTMDocument.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ typedef void (^TaskChangeBlock)(id, NSUInteger, BOOL*);
// Window controls
@property (nonatomic, retain) IBOutlet NSTextField *textField;
@property (nonatomic, retain) IBOutlet NSSearchField *searchField;
@property (nonatomic, retain) IBOutlet NSPredicate *searchFieldPredicate;
@property (nonatomic, retain) IBOutlet TTMTableView *tableView;
@property (nonatomic, retain) IBOutlet TTMTableViewDelegate *tableViewDelegate;
@property (nonatomic, retain) IBOutlet NSArrayController *arrayController;
Expand Down Expand Up @@ -377,6 +378,14 @@ typedef void (^TaskChangeBlock)(id, NSUInteger, BOOL*);

#pragma mark - Filter Methods

/*!
* @method combineFilterPresetPredicate:withSearchFilterPredicate
* @abstract Combines the filter preset predicate applied to the task list with the search field
* predicate in an "AND" fashion.
*/
- (NSPredicate*)combineFilterPresetPredicate:(NSPredicate*)filterPresetPredicate
withSearchFilterPredicate:(NSPredicate*)searchFilterPredicate;

/*!
* @method filterTaskListUsingTagforPreset:
* @abstract Sets the filter on the task list to a numbered preset, based on the sender's tag.
Expand Down
46 changes: 38 additions & 8 deletions TodoTxtMac/TTMDocument.m
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,10 @@ @implementation TTMDocument
[(TTMTask*)task removePriority];
};
TaskChangeBlock _increaseDueDateByOneDay = ^(id task, NSUInteger idx, BOOL *stop) {
[(TTMTask*)task postponeTask:1];
[(TTMTask*)task incrementDueDate:1];
};
TaskChangeBlock _decreaseDueDateByOneDay = ^(id task, NSUInteger idx, BOOL *stop) {
[(TTMTask*)task postponeTask:-1];
[(TTMTask*)task decrementDueDate:1];
};
TaskChangeBlock _removeDueDate = ^(id task, NSUInteger idx, BOOL *stop) {
[(TTMTask*)task removeDueDate];
Expand All @@ -88,10 +88,10 @@ @implementation TTMDocument
[(TTMTask*)task removeThresholdDate];
};
TaskChangeBlock _increaseThresholdDateByOneDay = ^(id task, NSUInteger idx, BOOL *stop) {
[(TTMTask*)task incrementThresholdDay:1];
[(TTMTask*)task incrementThresholdDate:1];
};
TaskChangeBlock _decreaseThresholdDateByOneDay = ^(id task, NSUInteger idx, BOOL *stop) {
[(TTMTask*)task decrementThresholdDay:1];
[(TTMTask*)task decrementThresholdDate:1];
};

#pragma mark - init Methods
Expand Down Expand Up @@ -132,6 +132,9 @@ - (void)awakeFromNib {

// Observe array controller selection to update "selected tasks" count in status bar
[self.arrayController addObserver:self forKeyPath:@"selection" options:NSKeyValueObservingOptionNew context:nil];

// Observe self to update search field filter
[self addObserver:self forKeyPath:@"searchFieldPredicate" options:NSKeyValueObservingOptionNew context:nil];
}

- (NSString *)windowNibName {
Expand Down Expand Up @@ -385,6 +388,7 @@ - (void)addNewTasksFromPasteBoard:(NSPasteboard*)pasteboard {
componentsSeparatedByCharactersInSet:
[NSCharacterSet newlineCharacterSet]];
[self addTasksFromArray:rawTextStrings removeAllTasksFirst:NO];
[self reapplyActiveFilterPredicate];
[self refreshTaskListWithSave:YES];
}

Expand Down Expand Up @@ -807,6 +811,26 @@ - (IBAction)sortTaskListUsingTagforPreset:(id)sender {

#pragma mark - Filter Methods

- (NSPredicate*)combineFilterPresetPredicate:(NSPredicate*)filterPresetPredicate
withSearchFilterPredicate:(NSPredicate*)searchFilterPredicate {
if (searchFilterPredicate == nil && filterPresetPredicate == nil) {
return nil;
}

if (searchFilterPredicate == nil && filterPresetPredicate != nil) {
return filterPresetPredicate;
}

if (searchFilterPredicate != nil && filterPresetPredicate == nil) {
return searchFilterPredicate;
}

// if (searchFilterPredicate != nil && filterPresetPredicate != nil)
NSCompoundPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:
@[filterPresetPredicate, searchFilterPredicate]];
return predicate;
}

- (IBAction)filterTaskListUsingTagforPreset:(id)sender {
[self changeActiveFilterPredicateToPreset:[sender tag]];
}
Expand All @@ -816,12 +840,14 @@ - (void)removeTaskListFilter {
}

- (void)reapplyActiveFilterPredicate {
self.activeFilterPredicate = [TTMFilterPredicates activeFilterPredicate];
[self changeActiveFilterPredicateToPreset:self.activeFilterPredicateNumber];
}

- (void)changeActiveFilterPredicateToPreset:(NSUInteger)presetNumber {
self.activeFilterPredicate = [TTMFilterPredicates
getFilterPredicateFromPresetNumber:presetNumber];
NSPredicate *filterPresetPredicate = [TTMFilterPredicates
getFilterPredicateFromPresetNumber:presetNumber];
self.activeFilterPredicate = [self combineFilterPresetPredicate:filterPresetPredicate
withSearchFilterPredicate:self.searchFieldPredicate];
[TTMFilterPredicates setActiveFilterPredicate:self.activeFilterPredicate];
[TTMFilterPredicates setActiveFilterPredicatePresetNumber:presetNumber];
self.activeFilterPredicateNumber = presetNumber;
Expand Down Expand Up @@ -925,7 +951,7 @@ - (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
}
}
// Check active filter menu item.
if ([menuItem.parentItem tag] == FILTERMENUTAG) {
if ([menuItem.parentItem tag] == FILTERMENUTAG) {
if (menuItem.tag == self.activeFilterPredicateNumber) {
[menuItem setState:NSOnState];
} else {
Expand Down Expand Up @@ -1003,6 +1029,10 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N
if ([keyPath isEqualToString:@"selection"]) {
[self updateStatusBarText];
}

if ([keyPath isEqualToString:@"searchFieldPredicate"]) {
[self reapplyActiveFilterPredicate];
}
}

- (void)updateStatusBarText {
Expand Down
Loading

0 comments on commit 0352c91

Please sign in to comment.