Subversion Repositories TruePreview

Compare Revisions

Ignore whitespace Rev 13 → Rev 14

/trunk/Source/TruePreviewPreferenceValueTransformer.h New file
0,0 → 1,156
/*
* 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 &gt; 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.
* &gt; 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 &gt; 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
TruePreviewPreferenceValueTransformer.h Property changes : Added: svn:mime-type ## -0,0 +1 ## +text/x-c \ No newline at end of property Index: TruePreviewPreferenceValueTransformer.m =================================================================== --- TruePreviewPreferenceValueTransformer.m (revision 0) +++ TruePreviewPreferenceValueTransformer.m (revision 14) @@ -0,0 +1,103 @@ +/* + * 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 "TruePreviewPreferenceValueTransformer.h" + +@implementation TruePreviewPreferenceValueTransformer + +#pragma mark NSValueTransformer class methods + ++ (Class)transformedValueClass { + return [NSNumber class]; +} + +#pragma mark NSValueTransformer instance methods + +- (id)transformedValue:(id)inValue { + float theValue = [inValue floatValue]; + + if ((theValue > 0) && (theValue <= TRUEPREVIEW_DELAY_MAX)) { + return [NSNumber numberWithInt:1]; + } + else if ( + (theValue == TRUEPREVIEW_DELAY_IMMEDIATE) + || (theValue == TRUEPREVIEW_DELAY_DEFAULT) + || (theValue == TRUEPREVIEW_DELAY_NEVER) + ) { + return [NSNumber numberWithInt:theValue]; + } + else { + return [NSNumber numberWithInt:TRUEPREVIEW_DELAY_DEFAULT]; + } +} + +@end + +@implementation TruePreviewPreferenceValueTransformerDelay + +#pragma mark NSValueTransformer class methods + ++ (Class)transformedValueClass { + return [NSNumber class]; +} + +#pragma mark NSValueTransformer instance methods + +- (id)transformedValue:(id)inValue { + float theValue = [inValue floatValue]; + + if ((theValue <= 0) || (theValue > TRUEPREVIEW_DELAY_MAX)) { + return nil; + } + else { + return [NSNumber numberWithFloat:theValue]; + } +} + +@end + +@implementation TruePreviewPreferenceValueTransformerDelayEditIndicator + +#pragma mark NSValueTransformer class methods + ++ (Class)transformedValueClass { + return [NSNumber class]; +} + +#pragma mark NSValueTransformer instance methods + +- (id)transformedValue:(id)inValue { + float theValue = [inValue floatValue]; + + return [NSNumber numberWithInt:((theValue > 0) && (theValue <= TRUEPREVIEW_DELAY_MAX))]; +} + +@end Index: TruePreviewMessageViewer.h =================================================================== --- TruePreviewMessageViewer.h (revision 0) +++ TruePreviewMessageViewer.h (revision 14) @@ -0,0 +1,145 @@ +/* + * 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 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
TruePreviewMessageViewer.h Property changes : Added: svn:mime-type ## -0,0 +1 ## +text/x-c \ No newline at end of property Index: TruePreviewMessageViewer.m =================================================================== --- TruePreviewMessageViewer.m (revision 0) +++ TruePreviewMessageViewer.m (revision 14) @@ -0,0 +1,181 @@ +/* + * 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