-
Notifications
You must be signed in to change notification settings - Fork 4
/
LHCalendarStream.m
146 lines (112 loc) · 3.94 KB
/
LHCalendarStream.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
//
// LHCalendarStream.m
// LastHistory
//
// Created by Frederik Seiffert on 10.12.09.
// Copyright 2009 Frederik Seiffert. All rights reserved.
//
#import "LHCalendarStream.h"
#import <CalendarStore/CalendarStore.h>
#import "LHCommonMacros.h"
#import "LHHistoryView.h"
#import "LHDocument.h"
#import "LHHistoryEntry.h"
#import "NSImage-Extras.h"
#import "NSColor-Extras.h"
#define EVENT_HEIGHT 5.0
#define EVENT_MARGIN 1.0
@implementation LHCalendarStream
+ (Class)nodeClass
{
return [CalEvent class];
}
- (id)initWithLayer:(id)layer
{
self = [super initWithLayer:layer];
if (self != nil) {
LHCalendarStream *object = layer;
_calendars = object->_calendars;
_calendarEvents = object->_calendarEvents;
}
return self;
}
- (void)setupLayer
{
self.anchorPoint = CGPointMake(0, 0);
self.bounds = CGRectMake(0, 0, self.superlayer.bounds.size.width, self.calendars.count * (EVENT_HEIGHT + EVENT_MARGIN));
}
- (void)generateNodes
{
[self removeAllSublayers];
// load calendar events
NSArray *calendarEvents = self.calendarEvents;
NSLog(@"Generating calendar nodes...");
NSUInteger processedCount = 0;
for (CalEvent *event in calendarEvents)
{
CALayer *layer = [CALayer layer];
[layer setValue:event forKey:LAYER_DATA_KEY];
layer.anchorPoint = CGPointMake(0, 0);
layer.backgroundColor = [event.calendar.color cgColor];
[self addSublayer:layer];
processedCount++;
}
[self layoutSublayers];
NSLog(@"Generated %u calendar nodes", processedCount);
}
- (void)layoutSublayers
{
if (self.superlayer.isHidden)
return;
for (CALayer *layer in self.sublayers)
{
CalEvent *event = [layer valueForKey:LAYER_DATA_KEY];
CGFloat startPoint = [self.view xPositionForDate:self.view.flipTimeline ? event.endDate : event.startDate];
CGFloat endPoint = [self.view xPositionForDate:self.view.flipTimeline ? event.startDate : event.endDate];
layer.bounds = CGRectMake(0, 0, endPoint - startPoint, EVENT_HEIGHT);
NSUInteger layerCalendarPosition = [self.calendars indexOfObject:event.calendar];
layer.position = CGPointMake(startPoint, layerCalendarPosition * (EVENT_HEIGHT + EVENT_MARGIN));
}
}
- (NSArray *)calendars
{
if (!_calendars)
_calendars = [[CalCalendarStore defaultCalendarStore].calendars filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"type == %@", CalCalendarTypeLocal]];
return _calendars;
}
- (NSArray *)calendarEvents
{
if (!_calendarEvents)
{
NSDate *startDate = self.view.document.firstHistoryEntry.timestamp;
NSDate *endDate = self.view.document.lastHistoryEntry.timestamp;
if (!startDate)
return nil;
LHLog(@"Fetching calendar events...");
// get all all-day events from local calendars
// we have to fetch them in batches, because eventsWithPredicate: only fetches 4 years at a time
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *fourYears = [NSDateComponents new];
fourYears.year = 4;
NSDateComponents *oneSecond = [NSDateComponents new];
fourYears.second = 1;
NSDate *batchStartDate = startDate;
NSDate *batchEndDate = nil;
NSArray *events = [NSArray array];
do {
batchEndDate = [calendar dateByAddingComponents:fourYears toDate:batchStartDate options:0];
if ([batchEndDate compare:endDate] == NSOrderedDescending)
batchEndDate = endDate;
NSPredicate *eventsPredicate = [CalCalendarStore eventPredicateWithStartDate:batchStartDate
endDate:batchEndDate
calendars:self.calendars];
NSArray *batchEvents = [[CalCalendarStore defaultCalendarStore] eventsWithPredicate:eventsPredicate];
batchEvents = [batchEvents filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"isAllDay == TRUE"]];
events = [events arrayByAddingObjectsFromArray:batchEvents];
batchStartDate = [calendar dateByAddingComponents:oneSecond toDate:batchEndDate options:0];
} while ([batchEndDate compare:endDate] == NSOrderedAscending);
_calendarEvents = events;
}
return _calendarEvents;
}
@end