Subversion Repositories TruePreview

[/] [trunk/] [Source/] [TruePreviewMessageViewer.m] - Blame information for rev 51

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jhriggs
/*
2 42 jhriggs
 * Copyright (c) 2009-2011, Jim Riggs, Christian Serving, L.L.C.
3 14 jhriggs
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are
7
 * met:
8
 *     * Redistributions of source code must retain the above copyright
9
 *       notice, this list of conditions and the following disclaimer.
10
 *     * Redistributions in binary form must reproduce the above
11
 *       copyright notice, this list of conditions and the following
12
 *       disclaimer in the documentation and/or other materials provided
13
 *       with the distribution.
14
 *     * Neither the name of Christian Serving, L.L.C. nor the names of
15
 *       its contributors may be used to endorse or promote products
16
 *       derived from this software without specific prior written
17
 *       permission.
18
 *
19
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
 */
31
 
32
#import "TruePreviewMessageViewer.h"
33
 
34
@implementation TruePreviewMessageViewer
35
 
36
#pragma mark Class methods
37
 
38
+ (NSMutableDictionary*)truePreviewTimers {
39 51 jhriggs
  TRUEPREVIEW_LOG();
40
 
41 14 jhriggs
  static NSMutableDictionary* sTimers = nil;
42
 
43
  if (sTimers == nil) {
44
    sTimers = [[NSMutableDictionary alloc] initWithCapacity:1];
45
  }
46
 
47
  return sTimers;
48
}
49
 
50
#pragma mark Swizzled instance methods
51
 
52
- (void)truePreviewDealloc {
53 51 jhriggs
  TRUEPREVIEW_LOG();
54
 
55 14 jhriggs
  [self truePreviewReset];
56
  [[[self class] truePreviewTimers]
57 51 jhriggs
    removeObjectForKey:[NSNumber numberWithUnsignedLongLong:(unsigned long long)self]
58 14 jhriggs
  ];
59
  [self truePreviewDealloc];
60
}
61
 
62 23 jhriggs
- (void)truePreviewForwardAsAttachment:(id)inSender {
63 51 jhriggs
  TRUEPREVIEW_LOG(@"%@", inSender);
64
 
65 23 jhriggs
  id theMessage = [self currentDisplayedMessage];
66
 
67
  if ([theMessage isKindOfClass:NSClassFromString(@"LibraryMessage")]) {
68
    NSDictionary* theSettings = [theMessage truePreviewSettings];
69
 
70
    if ([[theSettings objectForKey:@"forward"] boolValue]) {
71
      [self truePreviewReset];
72 51 jhriggs
      [self truePreviewMarkMessagesAsViewed:[NSArray arrayWithObject:theMessage]];
73 23 jhriggs
    }
74
  }
75
 
76
  [self truePreviewForwardAsAttachment:inSender];
77
}
78
 
79
- (void)truePreviewForwardMessage:(id)inSender {
80 51 jhriggs
  TRUEPREVIEW_LOG(@"%@", inSender);
81
 
82 23 jhriggs
  id theMessage = [self currentDisplayedMessage];
83
 
84
  if ([theMessage isKindOfClass:NSClassFromString(@"LibraryMessage")]) {
85
    NSDictionary* theSettings = [theMessage truePreviewSettings];
86
 
87
    if ([[theSettings objectForKey:@"forward"] boolValue]) {
88
      [self truePreviewReset];
89 51 jhriggs
      [self truePreviewMarkMessagesAsViewed:[NSArray arrayWithObject:theMessage]];
90 23 jhriggs
    }
91
  }
92
 
93
  [self truePreviewForwardMessage:inSender];
94
}
95
 
96 14 jhriggs
- (void)truePreviewMarkAsRead:(id)inSender {
97 51 jhriggs
  TRUEPREVIEW_LOG(@"%@", inSender);
98
 
99 14 jhriggs
  [self truePreviewReset];
100
  [self truePreviewMarkAsRead:inSender];
101
}
102
 
103
- (void)truePreviewMarkAsUnread:(id)inSender {
104 51 jhriggs
  TRUEPREVIEW_LOG(@"%@", inSender);
105
 
106 14 jhriggs
  [self truePreviewReset];
107
  [self truePreviewMarkAsUnread:inSender];
108
}
109
 
110 51 jhriggs
- (void)truePreviewMarkMessageAsViewed:(id)inMessage {
111
  TRUEPREVIEW_LOG(@"%@", inMessage);
112 23 jhriggs
 
113 51 jhriggs
  [self truePreviewCreateTimer:inMessage];
114 23 jhriggs
}
115
 
116 51 jhriggs
- (void)truePreviewMarkMessagesAsViewed:(NSArray*)inMessages  {
117
  TRUEPREVIEW_LOG(@"%@", inMessages);
118
 
119
  [self truePreviewCreateTimer:inMessages];
120
}
121
 
122 14 jhriggs
- (void)truePreviewMessageWasDisplayedInTextView:(NSNotification*)inNotification {
123 51 jhriggs
  TRUEPREVIEW_LOG(@"%@", inNotification);
124 14 jhriggs
 
125 51 jhriggs
  [self truePreviewMessageWasDisplayedInTextView:inNotification];  
126
  [self truePreviewReset];
127
/* TODO: IN PROGRESS
128 23 jhriggs
  // we receive notifications from all MessageContentControllers
129
  if ([inNotification object] != object_getIvar(self, class_getInstanceVariable([self class], "_contentController"))) {
130
    return;
131
  }
132
 
133 14 jhriggs
  id theMessage = [[inNotification userInfo] objectForKey:@"MessageKey"];
134
 
135
  if ([theMessage isKindOfClass:NSClassFromString(@"LibraryMessage")]) {
136
    NSDictionary* theSettings = [theMessage truePreviewSettings];
137
 
138
    if (
139
      ([[theSettings objectForKey:@"delay"] floatValue] == TRUEPREVIEW_DELAY_IMMEDIATE)
140
      || (
141
        [[theSettings objectForKey:@"window"] boolValue]
142
        && [self isKindOfClass:NSClassFromString(@"SingleMessageViewer")]
143
      )        
144
    ) {
145
      [self truePreviewReset];
146 51 jhriggs
      [self truePreviewMarkMessagesAsViewed:[NSArray arrayWithObject:theMessage]];
147 14 jhriggs
 
148
      return;
149
    }
150
 
151
    float theDelay = [[theSettings objectForKey:@"delay"] floatValue];
152
 
153
    if (theDelay > TRUEPREVIEW_DELAY_IMMEDIATE) {
154
      [self truePreviewReset];
155
      [self
156
        truePreviewSetTimer:[NSTimer
157
          scheduledTimerWithTimeInterval:theDelay
158
          target:self
159
          selector:@selector(truePreviewTimerFired:)
160
          userInfo:nil
161
          repeats:NO
162
        ]
163
      ];
164
    }
165
 
166 23 jhriggs
    if (
167
      ![self isKindOfClass:NSClassFromString(@"SingleMessageViewer")]
168
      && [[theSettings objectForKey:@"scroll"] boolValue]
169
    ) {
170 33 jhriggs
      // listen for selection change (mouse down) on message content view
171
      [[NSNotificationCenter defaultCenter]
172
        addObserver:self
173
        selector:@selector(truePreviewMessageClickedOrScrolled:)
174
        name:@"WebViewDidChangeSelectionNotification"
175
        object:[[object_getIvar(self, class_getInstanceVariable([self class], "_contentController")) currentDisplay] contentView]
176
      ];
177
 
178 14 jhriggs
      // listen for bounds change notification on the message's clip view
179
      [[NSNotificationCenter defaultCenter]
180 23 jhriggs
        addObserver:self
181 33 jhriggs
        selector:@selector(truePreviewMessageClickedOrScrolled:)
182 23 jhriggs
        name:NSViewBoundsDidChangeNotification
183
        object:[[[[object_getIvar(self, class_getInstanceVariable([self class], "_contentController")) currentDisplay] contentView] enclosingScrollView] contentView]
184
      ];
185 14 jhriggs
    }    
186
  }
187 51 jhriggs
*/
188 14 jhriggs
}
189
 
190 23 jhriggs
- (void)truePreviewReplyAllMessage:(id)inSender {
191 51 jhriggs
  TRUEPREVIEW_LOG(@"%@", inSender);
192
 
193 23 jhriggs
  id theMessage = [self currentDisplayedMessage];
194
 
195
  if ([theMessage isKindOfClass:NSClassFromString(@"LibraryMessage")]) {
196
    NSDictionary* theSettings = [theMessage truePreviewSettings];
197
 
198
    if ([[theSettings objectForKey:@"reply"] boolValue]) {
199
      [self truePreviewReset];
200 51 jhriggs
      [self truePreviewMarkMessagesAsViewed:[NSArray arrayWithObject:theMessage]];
201 23 jhriggs
    }
202
  }
203
 
204
  [self truePreviewReplyAllMessage:inSender];
205 14 jhriggs
}
206
 
207 23 jhriggs
- (void)truePreviewReplyMessage:(id)inSender {
208 51 jhriggs
  TRUEPREVIEW_LOG(@"%@", inSender);
209
 
210 23 jhriggs
  id theMessage = [self currentDisplayedMessage];
211
 
212
  if ([theMessage isKindOfClass:NSClassFromString(@"LibraryMessage")]) {
213
    NSDictionary* theSettings = [theMessage truePreviewSettings];
214
 
215
    if ([[theSettings objectForKey:@"reply"] boolValue]) {
216
      [self truePreviewReset];
217 51 jhriggs
      [self truePreviewMarkMessagesAsViewed:[NSArray arrayWithObject:theMessage]];
218 23 jhriggs
    }
219
  }
220
 
221
  [self truePreviewReplyMessage:inSender];
222
}
223
 
224 51 jhriggs
- (void)truePreviewSelectedMessagesDidChangeInMessageList {
225
  TRUEPREVIEW_LOG();
226
 
227
  [self truePreviewReset];
228
  [self truePreviewSelectedMessagesDidChangeInMessageList];
229
}
230
 
231 14 jhriggs
#pragma mark Accessors
232
 
233
- (NSTimer*)truePreviewTimer {
234 51 jhriggs
  TRUEPREVIEW_LOG();
235
 
236 14 jhriggs
  return [[[self class] truePreviewTimers]
237 51 jhriggs
    objectForKey:[NSNumber numberWithUnsignedLongLong:(unsigned long long)self]
238 14 jhriggs
  ];
239
}
240
 
241
- (void)truePreviewSetTimer:(NSTimer*)inTimer {
242 51 jhriggs
  TRUEPREVIEW_LOG(@"%@ (userInfo: %@)", inTimer, [inTimer userInfo]);
243
 
244 14 jhriggs
  [[[self class] truePreviewTimers]
245
    setObject:inTimer
246 51 jhriggs
    forKey:[NSNumber numberWithUnsignedLongLong:(unsigned long long)self]
247 14 jhriggs
  ];
248
}
249
 
250
#pragma mark Instance methods
251
 
252 51 jhriggs
- (void)truePreviewCreateTimer:(id)inMessages {
253
  TRUEPREVIEW_LOG(@"%@", inMessages);
254
 
255
  if (![inMessages isKindOfClass:[NSArray class]]) {
256
    inMessages = [NSArray arrayWithObject:inMessages];
257
  }
258
  else {
259
    inMessages = [[inMessages copy] autorelease];
260
  }
261
 
262
  id theMessage = [inMessages objectAtIndex:0];
263
 
264
  if (
265
    ![theMessage isKindOfClass:NSClassFromString(@"LibraryMessage")]
266
    || ![[self currentDisplayedMessage] isKindOfClass:NSClassFromString(@"LibraryMessage")]
267
  ) {
268
    return;
269
  }
270
 
271
  NSDictionary* theSettings = [theMessage truePreviewSettings];
272
 
273
  if (
274
    ([[theSettings objectForKey:@"delay"] floatValue] == TRUEPREVIEW_DELAY_IMMEDIATE)
275
    || (
276
      [[theSettings objectForKey:@"window"] boolValue]
277
      && [self isKindOfClass:NSClassFromString(@"SingleMessageViewer")]
278
    )        
279
  ) {
280
    [self truePreviewReset];
281
    [self truePreviewMarkMessagesAsViewed:inMessages];
282
 
283
    return;
284
  }
285
 
286
  float theDelay = [[theSettings objectForKey:@"delay"] floatValue];
287
 
288
  if (theDelay > TRUEPREVIEW_DELAY_IMMEDIATE) {
289
    [self truePreviewReset];
290
    [self
291
      truePreviewSetTimer:[NSTimer
292
        scheduledTimerWithTimeInterval:theDelay
293
        target:self
294
        selector:@selector(truePreviewTimerFired:)
295
        userInfo:inMessages
296
        repeats:NO
297
      ]
298
    ];
299
  }
300
}
301
 
302 14 jhriggs
- (void)truePreviewReset {
303 51 jhriggs
  TRUEPREVIEW_LOG();
304
 
305 14 jhriggs
  NSTimer* theTimer = [self truePreviewTimer];
306
 
307
  if ((theTimer != nil) && [theTimer isValid]) {
308
    [theTimer invalidate];
309
  }
310
 
311
  // stop observing when changed
312
  [[NSNotificationCenter defaultCenter]
313
    removeObserver:self
314 33 jhriggs
    name:@"WebViewDidChangeSelectionNotification"
315
    object:[[object_getIvar(self, class_getInstanceVariable([self class], "_contentController")) currentDisplay] contentView]
316
  ];
317
  [[NSNotificationCenter defaultCenter]
318
    removeObserver:self
319 14 jhriggs
    name:NSViewBoundsDidChangeNotification
320
    object:[[[[object_getIvar(self, class_getInstanceVariable([self class], "_contentController")) currentDisplay] contentView] enclosingScrollView] contentView]
321
  ];
322
}
323
 
324
- (void)truePreviewTimerFired:(NSTimer*)inTimer {
325 51 jhriggs
  TRUEPREVIEW_LOG(@"%@ (userInfo: %@)", inTimer, [inTimer userInfo]);
326
 
327
  id theMessages = [inTimer userInfo];
328
 
329 14 jhriggs
  [self truePreviewReset];
330 51 jhriggs
  [self truePreviewMarkMessagesAsViewed:theMessages];
331 14 jhriggs
}
332
 
333 33 jhriggs
- (void)truePreviewMessageClickedOrScrolled:(NSNotification*)inNotification {
334 51 jhriggs
  TRUEPREVIEW_LOG(@"%@", inNotification);
335
 
336 14 jhriggs
  // ignore the first time we get the notification; it may be an initial scroll
337
  // to the origin after changing messages
338
  static BOOL sIsFirstTime = YES;
339
 
340 33 jhriggs
  if ([NSViewBoundsDidChangeNotification isEqualToString:[inNotification name]] && sIsFirstTime) {
341 14 jhriggs
    sIsFirstTime = NO;
342
 
343
    return;
344
  }
345
 
346
  sIsFirstTime = YES;
347
 
348
  [self truePreviewReset];
349
 
350
  if ([[self currentDisplayedMessage] isKindOfClass:NSClassFromString(@"LibraryMessage")]) {
351
    [[self currentDisplayedMessage] truePreviewMarkAsViewed];
352
  }
353
}
354
 
355
@end