/trunk/Source
/* |
* Copyright (c) 2009, Jim Riggs, Christian Serving, L.L.C. |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions are |
* met: |
* * Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* * Redistributions in binary form must reproduce the above |
* copyright notice, this list of conditions and the following |
* disclaimer in the documentation and/or other materials provided |
* with the distribution. |
* * Neither the name of Christian Serving, L.L.C. nor the names of |
* its contributors may be used to endorse or promote products |
* derived from this software without specific prior written |
* permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
|
#import "TruePreviewMessageViewer.h" |
|
@implementation TruePreviewMessageViewer |
|
#pragma mark Class methods |
|
+ (NSMutableDictionary*)truePreviewTimers { |
static NSMutableDictionary* sTimers = nil; |
|
if (sTimers == nil) { |
sTimers = [[NSMutableDictionary alloc] initWithCapacity:1]; |
} |
|
return sTimers; |
} |
|
#pragma mark Swizzled instance methods |
|
- (void)truePreviewDealloc { |
[self truePreviewReset]; |
[[[self class] truePreviewTimers] |
removeObjectForKey:[NSNumber numberWithUnsignedLong:(unsigned long)self] |
]; |
[self truePreviewDealloc]; |
} |
|
- (void)truePreviewMarkAsRead:(id)inSender { |
[self truePreviewReset]; |
[self truePreviewMarkAsRead:inSender]; |
} |
|
- (void)truePreviewMarkAsUnread:(id)inSender { |
[self truePreviewReset]; |
[self truePreviewMarkAsUnread:inSender]; |
} |
|
- (void)truePreviewMessageWasDisplayedInTextView:(NSNotification*)inNotification { |
[self truePreviewMessageWasDisplayedInTextView:inNotification]; |
|
id theMessage = [[inNotification userInfo] objectForKey:@"MessageKey"]; |
|
if ([theMessage isKindOfClass:NSClassFromString(@"LibraryMessage")]) { |
NSDictionary* theSettings = [theMessage truePreviewSettings]; |
|
if ( |
([[theSettings objectForKey:@"delay"] floatValue] == TRUEPREVIEW_DELAY_IMMEDIATE) |
|| ( |
[[theSettings objectForKey:@"window"] boolValue] |
&& [self isKindOfClass:NSClassFromString(@"SingleMessageViewer")] |
) |
) { |
[self truePreviewReset]; |
[theMessage truePreviewMarkAsViewed]; |
|
return; |
} |
|
float theDelay = [[theSettings objectForKey:@"delay"] floatValue]; |
|
if (theDelay > TRUEPREVIEW_DELAY_IMMEDIATE) { |
[self truePreviewReset]; |
[self |
truePreviewSetTimer:[NSTimer |
scheduledTimerWithTimeInterval:theDelay |
target:self |
selector:@selector(truePreviewTimerFired:) |
userInfo:nil |
repeats:NO |
] |
]; |
} |
|
if ([[theSettings objectForKey:@"scroll"] boolValue]) { |
// listen for bounds change notification on the message's clip view |
[[NSNotificationCenter defaultCenter] |
addObserver:self |
selector:@selector(truePreviewBoundsDidChange:) |
name:NSViewBoundsDidChangeNotification |
object:[[[[object_getIvar(self, class_getInstanceVariable([self class], "_contentController")) currentDisplay] contentView] enclosingScrollView] contentView] |
]; |
} |
} |
} |
|
- (void)truePreviewMessageNoLongerDisplayedInTextView:(NSNotification*)inNotification { |
[self truePreviewMessageNoLongerDisplayedInTextView:inNotification]; |
[self truePreviewReset]; |
} |
|
#pragma mark Accessors |
|
- (NSTimer*)truePreviewTimer { |
return [[[self class] truePreviewTimers] |
objectForKey:[NSNumber numberWithUnsignedLong:(unsigned long)self] |
]; |
} |
|
- (void)truePreviewSetTimer:(NSTimer*)inTimer { |
[[[self class] truePreviewTimers] |
setObject:inTimer |
forKey:[NSNumber numberWithUnsignedLong:(unsigned long)self] |
]; |
} |
|
#pragma mark Instance methods |
|
- (void)truePreviewReset { |
NSTimer* theTimer = [self truePreviewTimer]; |
|
if ((theTimer != nil) && [theTimer isValid]) { |
[theTimer invalidate]; |
} |
|
// stop observing when changed |
[[NSNotificationCenter defaultCenter] |
removeObserver:self |
name:NSViewBoundsDidChangeNotification |
object:[[[[object_getIvar(self, class_getInstanceVariable([self class], "_contentController")) currentDisplay] contentView] enclosingScrollView] contentView] |
]; |
} |
|
- (void)truePreviewTimerFired:(NSTimer*)inTimer { |
[self truePreviewReset]; |
|
if ([[self currentDisplayedMessage] isKindOfClass:NSClassFromString(@"LibraryMessage")]) { |
[[self currentDisplayedMessage] truePreviewMarkAsViewed]; |
} |
} |
|
- (void)truePreviewBoundsDidChange:(NSNotification*)inNotification { |
// ignore the first time we get the notification; it may be an initial scroll |
// to the origin after changing messages |
static BOOL sIsFirstTime = YES; |
|
if (sIsFirstTime) { |
sIsFirstTime = NO; |
|
return; |
} |
|
sIsFirstTime = YES; |
|
[self truePreviewReset]; |
|
if ([[self currentDisplayedMessage] isKindOfClass:NSClassFromString(@"LibraryMessage")]) { |
[[self currentDisplayedMessage] truePreviewMarkAsViewed]; |
} |
} |
|
@end |
/* |
* Copyright (c) 2009, Jim Riggs, Christian Serving, L.L.C. |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions are |
* met: |
* * Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* * Redistributions in binary form must reproduce the above |
* copyright notice, this list of conditions and the following |
* disclaimer in the documentation and/or other materials provided |
* with the distribution. |
* * Neither the name of Christian Serving, L.L.C. nor the names of |
* its contributors may be used to endorse or promote products |
* derived from this software without specific prior written |
* permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
|
/*! |
* @header |
* Defines the <code>TruePreviewPreferenceValueTransformer</code> |
* <code>NSValueTransformer</code> subclasses. |
* @copyright Copyright (c) 2009 Jim Riggs, Christian Serving, L.L.C. All rights reserved. |
* @version \@(#) $Id: TruePreviewPreferencesModule.h 2 2009-06-27 07:02:45Z jhriggs $ |
* @updated $Date: 2009-06-27 02:02:45 -0500 (Sat, 27 Jun 2009) $ |
*/ |
|
/*! |
* @class |
* The <code>TruePreviewPreferenceValueTransformer</code> class is the subclass |
* of <code>NSValueTransformer</code> that selects the correct radio button in |
* the TruePreview preferences panel. |
* @version \@(#) $Id: TruePreviewPreferencesModule.h 2 2009-06-27 07:02:45Z jhriggs $ |
* @updated $Date: 2009-06-27 02:02:45 -0500 (Sat, 27 Jun 2009) $ |
*/ |
@interface TruePreviewPreferenceValueTransformer : NSValueTransformer { |
} |
|
#pragma mark NSValueTransformer class methods |
/*! @group NSValueTransformer class methods */ |
|
/*! |
* Returns the class of transformed values for this value transformer |
* (NSNumber). |
* @result |
* <code>[NSNumber class]</code>. |
*/ |
+ (Class)transformedValueClass; |
|
#pragma mark NSValueTransformer instance methods |
/*! @group NSValueTransformer instance methods */ |
|
/*! |
* Returns an <code>NSNumber</code> equivalent to the provided value if the |
* value is <code>TRUEPREVIEW_DELAY_IMMEDIATE</code>, |
* <code>TRUEPREVIEW_DELAY_DEFAULT</code>, |
* <code>TRUEPREVIEW_DELAY_NEVER</code>, or > 0 to |
* <code>TRUEPREVIEW_DELAY_MAX</code>; otherwise, |
* <code>TRUEPREVIEW_DELAY_DEFAULT</code> is returned. |
* @param inValue |
* The value being transformed. |
* @result |
* An <code>NSNumber</code> containing the transformed value. |
*/ |
- (id)transformedValue:(id)inValue; |
|
@end |
|
/*! |
* @class |
* The <code>TruePreviewPreferenceValueTransformerDelay</code> class is the |
* subclass of <code>NSValueTransformer</code> that provides a value appropriate |
* to display in controls in the TruePreview preferences panel. |
* @version \@(#) $Id: TruePreviewPreferencesModule.h 2 2009-06-27 07:02:45Z jhriggs $ |
* @updated $Date: 2009-06-27 02:02:45 -0500 (Sat, 27 Jun 2009) $ |
*/ |
@interface TruePreviewPreferenceValueTransformerDelay : NSValueTransformer { |
} |
|
#pragma mark NSValueTransformer class methods |
/*! @group NSValueTransformer class methods */ |
|
/*! |
* Returns the class of transformed values for this value transformer |
* (NSNumber). |
* @result |
* <code>[NSNumber class]</code>. |
*/ |
+ (Class)transformedValueClass; |
|
#pragma mark NSValueTransformer instance methods |
/*! @group NSValueTransformer instance methods */ |
|
/*! |
* Returns an <code>NSNumber</code> for displaying the delay in controls (i.e. |
* > 0 to <code>TRUEPREVIEW_DELAY_MAX</code> or <code>nil</code>). |
* @param inValue |
* The value being transformed. |
* @result |
* An <code>NSNumber</code> containing the transformed value. |
*/ |
- (id)transformedValue:(id)inValue; |
|
@end |
|
/*! |
* @class |
* The <code>TruePreviewPreferenceValueTransformerDelayEditIndicator</code> |
* class is the subclass of <code>NSValueTransformer</code> that indicates |
* whether or not delay controls should be enabled in the TruePreview |
* preferences panel. |
* @version \@(#) $Id: TruePreviewPreferencesModule.h 2 2009-06-27 07:02:45Z jhriggs $ |
* @updated $Date: 2009-06-27 02:02:45 -0500 (Sat, 27 Jun 2009) $ |
*/ |
@interface TruePreviewPreferenceValueTransformerDelayEditIndicator : NSValueTransformer { |
} |
|
#pragma mark NSValueTransformer class methods |
/*! @group NSValueTransformer class methods */ |
|
/*! |
* Returns the class of transformed values for this value transformer |
* (NSNumber). |
* @result |
* <code>[NSNumber class]</code>. |
*/ |
+ (Class)transformedValueClass; |
|
#pragma mark NSValueTransformer instance methods |
/*! @group NSValueTransformer instance methods */ |
|
/*! |
* Returns an <code>NSNumber</code> indicating whether or not delay controls |
* should be enabled (i.e. delay is > 0 to |
* <code>TRUEPREVIEW_DELAY_MAX</code>). |
* @param inValue |
* The value being transformed. |
* @result |
* An <code>NSNumber</code> containing the transformed value. |
*/ |
- (id)transformedValue:(id)inValue; |
|
@end |
TruePreviewMessageViewer category for
+ * MessageViewer.
+ * @copyright Copyright (c) 2009 Jim Riggs, Christian Serving, L.L.C. All rights reserved.
+ * @version \@(#) $Id: TruePreviewLibraryMessage.h 2 2009-06-27 07:02:45Z jhriggs $
+ * @updated $Date: 2009-06-27 02:02:45 -0500 (Sat, 27 Jun 2009) $
+ */
+
+#import "TruePreviewLibraryMessage.h"
+
+/*!
+ * @class
+ * Adds a method for overriding the "mark as viewed" behavior of
+ * MessageViewer.
+ * @version \@(#) $Id: TruePreviewLibraryMessage.h 2 2009-06-27 07:02:45Z jhriggs $
+ * @updated $Date: 2009-06-27 02:02:45 -0500 (Sat, 27 Jun 2009) $
+ */
+@interface TruePreviewMessageViewer : NSObject {
+}
+
+#pragma mark Class methods
+/*! @group Class methods */
+
+/*!
+ * Returns the timers for instances of this class.
+ * @result
+ * The NSMutableDictionary containing the NSTimer
+ * for each instance of this class. The key is an NSNumber
+ * (unsigned long) of the address of each instance.
+ */
++ (NSMutableDictionary*)truePreviewTimers;
+
+#pragma mark Swizzled instance methods
+/*! @group Swizzled instance methods */
+
+/*!
+ * Invalidates this instance's timer and stops observing scroll changes before
+ * deallocating.
+ */
+- (void)truePreviewDealloc;
+
+/*!
+ * Invalidates this instance's timer and stops observing scroll changes when a
+ * message is explicitly marked as read.
+ * @param inSender
+ * Unused.
+ */
+- (void)truePreviewMarkAsRead:(id)inSender;
+
+/*!
+ * Invalidates this instance's timer and stops observing scroll changes when a
+ * message is explicitly marked as unread.
+ * @param inSender
+ * Unused.
+ */
+- (void)truePreviewMarkAsUnread:(id)inSender;
+
+/*!
+ * Marks the displayed message as viewed, sets a timer to mark the displayed
+ * message as viewed, and/or adds a notification observer to mark the message as
+ * viewed when it is scrolled as appropriate.
+ * @param inNotification
+ * The NSNotification describing the event.
+ */
+- (void)truePreviewMessageWasDisplayedInTextView:(id)inNotification;
+
+/*!
+ * Invalidates this instance's timer and stops observing scroll changes.
+ * @param inNotification
+ * The NSNotification describing the event.
+ */
+- (void)truePreviewMessageNoLongerDisplayedInTextView:(NSNotification*)inNotification;
+
+#pragma mark Accessors
+/*! @group Accessors */
+
+/*!
+ * Returns the timer for this instance.
+ * @result
+ * The NSTimer for this instance.
+ */
+- (NSTimer*)truePreviewTimer;
+
+/*!
+ * Sets the timer for this instance.
+ * @param inTimer
+ * The NSTimer for this instance.
+ */
+- (void)truePreviewSetTimer:(NSTimer*)inTimer;
+
+#pragma mark Instance methods
+/*! @group Instance methods */
+
+/*!
+ * Invalidates this instance's timer and stops observing scroll changes.
+ */
+- (void)truePreviewReset;
+
+/*!
+ * Marks the currently-displayed message as read.
+ * @param inTimer
+ * Unused.
+ */
+- (void)truePreviewTimerFired:(NSTimer*)inTimer;
+
+/*!
+ * Marks the currently-displayed message as read.
+ * @param inNotification
+ * Unused.
+ */
+- (void)truePreviewBoundsDidChange:(NSNotification*)inNotification;
+
+@end