diff --git a/NSTextFieldHyperlinks/AppDelegate.h b/NSTextFieldHyperlinks/AppDelegate.h index 28d38b8..2b9b233 100644 --- a/NSTextFieldHyperlinks/AppDelegate.h +++ b/NSTextFieldHyperlinks/AppDelegate.h @@ -33,5 +33,6 @@ @property (assign) IBOutlet NSWindow *window; @property (weak) IBOutlet HyperlinkTextField *hyperlinkTextField; - +@property (weak) IBOutlet HyperlinkTextField *hyperlinkTextField2; +@property (weak) IBOutlet HyperlinkTextField *hyperlinkTextField3; @end diff --git a/NSTextFieldHyperlinks/AppDelegate.m b/NSTextFieldHyperlinks/AppDelegate.m index 46aa4f9..39082c9 100644 --- a/NSTextFieldHyperlinks/AppDelegate.m +++ b/NSTextFieldHyperlinks/AppDelegate.m @@ -37,17 +37,21 @@ - (void)applicationDidFinishLaunching:(NSNotification *)aNotification // Create hyperlink NSString *linkName = @"blog"; NSURL *url = [NSURL URLWithString:@"http://toomasvahter.wordpress.com"]; - NSMutableAttributedString *hyperlinkString = [[NSMutableAttributedString alloc] initWithString:linkName]; - [hyperlinkString beginEditing]; - [hyperlinkString addAttribute:NSLinkAttributeName value:url range:NSMakeRange(0, [hyperlinkString length])]; - [hyperlinkString addAttribute:NSForegroundColorAttributeName value:[NSColor blueColor] range:NSMakeRange(0, [hyperlinkString length])]; - [hyperlinkString endEditing]; + NSAttributedString *hyperlinkString = [self.hyperlinkTextField hyperlink:linkName toURL:url]; [resultString appendAttributedString:hyperlinkString]; NSString *plainString = @". Some pretty interesting posts."; [resultString appendAttributedString:[[NSAttributedString alloc] initWithString:plainString]]; [self.hyperlinkTextField setAttributedStringValue:resultString]; + + // Update existing textfield substring with hyperlink + self.hyperlinkTextField2.linkColor = [NSColor redColor]; + [self.hyperlinkTextField2 updateSubstring:@"blog" withHyperLinkToURL:url]; + + // Replace existing textfield content key with hyperlink + self.hyperlinkTextField3.linkColor = [NSColor greenColor]; + [self.hyperlinkTextField3 replaceSubstring:@"$key" withHyperLink:@"blog" toURL:url]; } @end diff --git a/NSTextFieldHyperlinks/HyperlinkTextField.h b/NSTextFieldHyperlinks/HyperlinkTextField.h index 2cd5e24..73b9131 100644 --- a/NSTextFieldHyperlinks/HyperlinkTextField.h +++ b/NSTextFieldHyperlinks/HyperlinkTextField.h @@ -27,5 +27,91 @@ #import +// link option keys +extern NSString * HTLinkOption; +extern NSString * HTUrlOption; +extern NSString * HTColorOption; + @interface HyperlinkTextField : NSTextField + +@property (strong) NSCursor *cursor; + +/*! + + Explicity enable and disable hyperlinks. + + */ +@property (assign) BOOL hyperlinksEnabled; + +/*! + + Link color + + */ +@property (strong) NSColor *linkColor; + +/*! + + Update control attributed string with link options to define hyperlink. + + */ +- (void)updateAttributedStringValueWithLinkOptions:(NSArray *>*)options; + +/*! + + Set control string with link options to define hyperlink. + + */ +- (void)setStringValue:(NSString *)stringValue linkOptions:(NSArray *>*)options; + +/*! + + Set control string with attributes and link options to define hyperlink. + + */ +- (void)setStringValue:(NSString *)stringValue attributes:(NSDictionary *)attributes linkOptions:(NSArray *>*)options; + +/*! + + Update control substring with hyperlink to given URL + + */ +- (void)updateSubstring:(NSString *)linktext withHyperLinkToURL:(NSURL *)linkURL; + +/*! + + Update control substring with hyperlink to given URL + + */ +- (void)replaceSubstring:(NSString *)linkKey withHyperLink:(NSString *)linktext toURL:(NSURL *)linkURL; + +/*! + + Make hyperlink attributed string to given URL + + */ +- (NSAttributedString *)hyperlink:(NSString *)linktext toURL:(NSURL *)linkURL; + +@end + +@interface NSString (HyperTextField) +- (NSAttributedString *)htf_hyperlinkToURL:(NSURL *)linkURL; +- (NSAttributedString *)htf_hyperlinkToURL:(NSURL *)linkURL linkColor:(NSColor *)linkColor; +- (NSAttributedString *)htf_hyperlinkToURL:(NSURL *)linkURL linkColor:(NSColor *)linkColor font:(NSFont *)font; +- (NSAttributedString *)htf_hyperlinkWithAttributes:(NSDictionary *)attributes linkOptions:(NSArray *>*)options; @end + +@interface NSAttributedString (HyperTextField) + +- (NSAttributedString *)htf_replaceSubstringWithHyperLink:(NSString *)linktext toURL:(NSURL *)linkURL; + +- (NSAttributedString *)htf_replaceSubstringWithHyperLink:(NSString *)linktext + toURL:(NSURL *)linkURL + linkColor:(NSColor *)linkColor; + +- (NSAttributedString *)htf_replaceSubstring:(NSString *)linkKey + withHyperLink:(NSString *)linktext + toURL:(NSURL *)linkURL + linkColor:(NSColor *)linkColor; +@end + diff --git a/NSTextFieldHyperlinks/HyperlinkTextField.m b/NSTextFieldHyperlinks/HyperlinkTextField.m index 424a7d6..8678a35 100644 --- a/NSTextFieldHyperlinks/HyperlinkTextField.m +++ b/NSTextFieldHyperlinks/HyperlinkTextField.m @@ -25,8 +25,14 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +NSString * HTLinkOption = @"link"; +NSString * HTUrlOption = @"url"; +NSString * HTColorOption = @"color"; + #import "HyperlinkTextField.h" +static BOOL m_useNativeHyperlinkImplementation = YES; + @interface HyperlinkTextField () @property (nonatomic, readonly) NSArray *hyperlinkInfos; @property (nonatomic, readonly) NSTextView *textView; @@ -40,17 +46,49 @@ - (void)_resetHyperlinkCursorRects; @implementation HyperlinkTextField +/* + + The non native implementation attempts to improve on the native implementation. + + The main failing of the default implementation is that it uses the selection cursor (the hand cursor appears if the field is selected). + + The non native implementation works tolerably well in some cases but can fail to compute the correct link cursor rect for longer strings. + + TODO: in order to improve on the non native performance we could display -textView in a popup window and look for layout issues. I tried various + methods of overriding the current cursor but none were flicker free. + + on 10.12 the default link style is enforced + http://stackoverflow.com/questions/39926951/color-attribute-is-ignored-in-nsattributedstring-with-nslinkattributename + + A proper solution involves using an NSTextView subclass as oppposed to NSTextField. + + */ ++ (void)setUseNativeHyperlinkImplementation:(BOOL)value +{ + m_useNativeHyperlinkImplementation = value; +} + ++ (BOOL)useNativeHyperlinkImplementation +{ + return m_useNativeHyperlinkImplementation; +} + - (void)_hyperlinkTextFieldInit { [self setEditable:NO]; - [self setSelectable:NO]; -} + _linkColor = [NSColor blueColor]; + _cursor = [NSCursor arrowCursor]; + if (m_useNativeHyperlinkImplementation) { + // An NSTextView based implementation might give a better result but would require a good deal of refactoring. + // see https://developer.apple.com/library/content/qa/qa1487/_index.html + self.hyperlinksEnabled = YES; + } +} - (id)initWithFrame:(NSRect)frame { - if ((self = [super initWithFrame:frame])) - { + if ((self = [super initWithFrame:frame])) { [self _hyperlinkTextFieldInit]; } @@ -60,26 +98,38 @@ - (id)initWithFrame:(NSRect)frame - (id)initWithCoder:(NSCoder *)coder { - if ((self = [super initWithCoder:coder])) - { + if ((self = [super initWithCoder:coder])) { [self _hyperlinkTextFieldInit]; } return self; } - - (void)resetCursorRects { [super resetCursorRects]; - [self _resetHyperlinkCursorRects]; + if (!m_useNativeHyperlinkImplementation) { + [self _resetHyperlinkCursorRects]; + } + else { + [self addCursorRect:self.bounds cursor:self.cursor]; + } } +- (void)addCursorRect:(NSRect)rect cursor:(NSCursor *)object +{ + if (!m_useNativeHyperlinkImplementation) { + [super addCursorRect:rect cursor:object]; + } + else { + [super addCursorRect:rect cursor:self.cursor]; + } +} - (void)_resetHyperlinkCursorRects { - for (NSDictionary *info in self.hyperlinkInfos) - { + for (NSDictionary *info in self.hyperlinkInfos) { + // TODO: use tracking areas instead [self addCursorRect:[[info objectForKey:kHyperlinkInfoRectKey] rectValue] cursor:[NSCursor pointingHandCursor]]; } } @@ -97,6 +147,7 @@ - (NSArray *)hyperlinkInfos { if (value) { + [textView.layoutManager ensureLayoutForTextContainer:textView.textContainer]; NSUInteger rectCount = 0; NSRectArray rectArray = [textView.layoutManager rectArrayForCharacterRange:range withinSelectedCharacterRange:range inTextContainer:textView.textContainer rectCount:&rectCount]; for (NSUInteger i = 0; i < rectCount; i++) @@ -109,15 +160,15 @@ - (NSArray *)hyperlinkInfos return [hyperlinkInfos count] ? hyperlinkInfos : nil; } - - (NSTextView *)textView { // Font used for displaying and frame calculations must match NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithAttributedString:self.attributedStringValue]; NSFont *font = [attributedString attribute:NSFontAttributeName atIndex:0 effectiveRange:NULL]; - if (!font) + if (!font) { [attributedString addAttribute:NSFontAttributeName value:self.font range:NSMakeRange(0, [attributedString length])]; + } NSRect textViewFrame = [self.cell titleRectForBounds:self.bounds]; NSTextView *textView = [[NSTextView alloc] initWithFrame:textViewFrame]; @@ -126,12 +177,105 @@ - (NSTextView *)textView return textView; } +- (void)setStringValue:(NSString *)stringValue +{ + NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:stringValue attributes:@{NSFontAttributeName : self.font}]; + + [super setAttributedStringValue:attrString]; +} + + +- (void)setAttributedStringValue:(NSAttributedString *)attributedString +{ + NSFont *font = nil; + + if (attributedString.length > 0) { + font = [attributedString attribute:NSFontAttributeName atIndex:0 effectiveRange:NULL]; + } + + if (!font) { + NSMutableAttributedString *s = [attributedString mutableCopy]; + [s addAttribute:NSFontAttributeName value:self.font range:NSMakeRange(0, [attributedString length])]; + attributedString = s; + } + [super setAttributedStringValue:attributedString]; + + // enforcing the field init here seems to be necessary in some cases. + [self _hyperlinkTextFieldInit]; +} + +- (void)setStringValue:(NSString *)stringValue linkOptions:(NSArray *>*)options +{ + NSDictionary *attributes = @{NSFontAttributeName : self.font}; + [self setStringValue:stringValue attributes:attributes linkOptions:options]; +} + +- (void)setStringValue:(NSString *)stringValue attributes:(NSDictionary *)attributes linkOptions:(NSArray *>*)options +{ + NSAttributedString *hyperlinkText = [stringValue htf_hyperlinkWithAttributes:attributes linkOptions:options]; + self.attributedStringValue = hyperlinkText; +} + +- (void)setObjectValue:(id)objectValue +{ + // when binding and using the native implementation the text rendering changes if the text is clicked and + // the attributed text does not have a font attribute defined. hence we enforce this. + if ([objectValue isKindOfClass:[NSString class]]) { + objectValue = [[NSAttributedString alloc] initWithString:objectValue attributes:@{NSFontAttributeName : self.font}]; + } + else if ([objectValue isKindOfClass:[NSAttributedString class]]) { + NSAttributedString *attrString = objectValue; + if (attrString.length > 0) { + NSFont *existingFont = [attrString attribute:NSFontAttributeName atIndex:0 effectiveRange:NULL]; + + if (!existingFont) { + NSMutableAttributedString *s = [attrString mutableCopy]; + [s addAttribute:NSFontAttributeName value:self.font range:NSMakeRange(0, [attrString length])]; + objectValue = s; + } + } + } + + [super setObjectValue:objectValue]; +} + +- (void)setSelectable:(BOOL)selectable +{ + [super setSelectable:selectable]; +} + +- (void)setHyperlinksEnabled:(BOOL)enabled +{ + self.allowsEditingTextAttributes = enabled; + self.selectable = enabled; +} + +- (BOOL)hyperlinksEnabled +{ + return self.allowsEditingTextAttributes && self.selectable; +} #pragma mark - #pragma mark Mouse Events +- (void)mouseMoved:(NSEvent *)theEvent { + if (m_useNativeHyperlinkImplementation) { + // this is not a great solution as there is some cursor flickering but it is perhaps better than using the default I beam + if ([NSCursor currentSystemCursor] != self.cursor) { + [self.cursor set]; + } + return; + } + [super mouseMoved:theEvent]; +} + - (void)mouseUp:(NSEvent *)theEvent { + if (m_useNativeHyperlinkImplementation) { + [super mouseUp:theEvent]; + return; + } + NSTextView *textView = self.textView; NSPoint localPoint = [self convertPoint:[theEvent locationInWindow] fromView:nil]; NSUInteger index = [textView.layoutManager characterIndexForPoint:localPoint inTextContainer:textView.textContainer fractionOfDistanceBetweenInsertionPoints:NULL]; @@ -150,4 +294,164 @@ - (void)mouseUp:(NSEvent *)theEvent } } +#pragma mark - +#pragma mark Substring value updating + +- (void)updateSubstring:(NSString *)linktext withHyperLinkToURL:(NSURL *)linkURL +{ + [self replaceSubstring:linktext withHyperLink:linktext toURL:linkURL]; +} + +- (void)replaceSubstring:(NSString *)linkKey withHyperLink:(NSString *)linktext toURL:(NSURL *)linkURL +{ + // get substring + NSString *sourceString = self.stringValue; + NSRange linkrange = [sourceString rangeOfString:linkKey]; + if (linkrange.location == NSNotFound) { + return; + } + + NSFont *font = self.font; + + // get attributed string + NSAttributedString *attrString = nil; + if (!self.attributedStringValue) { + attrString = [[NSAttributedString alloc] initWithString:sourceString attributes:@{NSFontAttributeName : font}]; + } + else { + attrString = self.attributedStringValue; + } + + attrString = [attrString htf_replaceSubstring:linkKey withHyperLink:linktext toURL:linkURL linkColor:self.linkColor]; + + // update the control attributed string value + [self setAttributedStringValue:attrString]; +} + +- (void)updateAttributedStringValueWithLinkOptions:(NSArray *>*)options +{ + NSAttributedString *hyperlinkText = self.attributedStringValue; + for (NSDictionary *option in options) { + hyperlinkText = [hyperlinkText htf_replaceSubstringWithHyperLink:option[HTLinkOption] + toURL:option[HTUrlOption] + linkColor:option[HTColorOption]]; + } + self.attributedStringValue = hyperlinkText; +} + +#pragma mark - +#pragma mark Link building + +- (NSAttributedString *)hyperlink:(NSString *)linktext toURL:(NSURL *)linkURL +{ + NSAttributedString *hyperlinkString = [linktext htf_hyperlinkToURL:linkURL linkColor:self.linkColor]; + + return hyperlinkString; +} + +@end + + +@implementation NSString (HyperTextField) + +- (NSAttributedString *)htf_hyperlinkToURL:(NSURL *)linkURL +{ + return [self htf_hyperlinkToURL:linkURL linkColor:[NSColor blueColor]]; +} + +- (NSAttributedString *)htf_hyperlinkToURL:(NSURL *)linkURL linkColor:(NSColor *)linkColor +{ + return [self htf_hyperlinkToURL:linkURL linkColor:linkColor font:nil]; +} + +- (NSAttributedString *)htf_hyperlinkToURL:(NSURL *)linkURL linkColor:(NSColor *)linkColor font:(NSFont *)font +{ + // contract + NSAssert([linkURL isKindOfClass:[NSURL class]], @"invalid class"); + + if (!font) { + font = [NSFont controlContentFontOfSize:[NSFont systemFontSize]]; + } + + NSMutableAttributedString *hyperlinkString = [[NSMutableAttributedString alloc] initWithString:self]; + [hyperlinkString beginEditing]; + [hyperlinkString addAttribute:NSLinkAttributeName value:linkURL range:NSMakeRange(0, [hyperlinkString length])]; + + // in some cases we see tootltips, which may be okay. + // however if are using links for internal app navigation via a custom scheme then it's not so desirable. + // using an empty tooltip seems to banish the tool tip. + [hyperlinkString addAttribute:NSToolTipAttributeName value:@"" range:NSMakeRange(0, [hyperlinkString length])]; + + // can no longer change the link style + // see https://stackoverflow.com/questions/39926951/color-attribute-is-ignored-in-nsattributedstring-with-nslinkattributename + if (linkColor) { + [hyperlinkString addAttribute:NSForegroundColorAttributeName value:linkColor range:NSMakeRange(0, [hyperlinkString length])]; + } + [hyperlinkString addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleNone) range:NSMakeRange(0, [hyperlinkString length])]; + [hyperlinkString addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, [hyperlinkString length])]; + [hyperlinkString endEditing]; + + return hyperlinkString; +} + +- (NSAttributedString *)htf_hyperlinkWithAttributes:(NSDictionary *)attributes linkOptions:(NSArray *>*)options +{ + NSAttributedString *hyperlinkText = [[NSAttributedString alloc] initWithString:self attributes:attributes]; + for (NSDictionary *option in options) { + hyperlinkText = [hyperlinkText htf_replaceSubstringWithHyperLink:option[HTLinkOption] + toURL:option[HTUrlOption] + linkColor:option[HTColorOption]]; + } + return hyperlinkText; +} + +@end + +@implementation NSAttributedString (HyperTextField) + +- (NSAttributedString *)htf_replaceSubstringWithHyperLink:(NSString *)linktext toURL:(NSURL *)linkURL +{ + return [self htf_replaceSubstring:linktext withHyperLink:linktext toURL:linkURL linkColor:[NSColor blueColor]]; +} + +- (NSAttributedString *)htf_replaceSubstringWithHyperLink:(NSString *)linktext + toURL:(NSURL *)linkURL + linkColor:(NSColor *)linkColor +{ + return [self htf_replaceSubstring:linktext withHyperLink:linktext toURL:linkURL linkColor:linkColor]; +} + +- (NSAttributedString *)htf_replaceSubstring:(NSString *)linkKey + withHyperLink:(NSString *)linktext + toURL:(NSURL *)linkURL + linkColor:(NSColor *)linkColor +{ + // get substring + NSString *sourceString = self.string; + if (!linkKey || linkKey.length == 0 ) linkKey = sourceString; + if (!linktext || linktext.length == 0 ) linktext = sourceString; + NSRange linkrange = [sourceString rangeOfString:linkKey]; + if (linkrange.location == NSNotFound) { + return self; + } + CGFloat linkEndLocation = linkrange.location + linkrange.length; + + NSFont *font = nil; + id attr = [self attribute:NSFontAttributeName atIndex:linkrange.location effectiveRange:nil]; + if ([attr isKindOfClass:NSFont.class]) font = attr; + + // build the hyper link + NSAttributedString *hyperlinkString = [linktext htf_hyperlinkToURL:linkURL linkColor:linkColor font:font]; + + // get link prefix and suffix strings + NSAttributedString *linkPrefix = [self attributedSubstringFromRange:NSMakeRange(0, linkrange.location)]; + NSAttributedString *linkSuffix = [self attributedSubstringFromRange:NSMakeRange(linkEndLocation, sourceString.length - linkEndLocation)]; + + // build new attributed string containing the hyperlink + NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithAttributedString:linkPrefix]; + [attrString appendAttributedString:hyperlinkString]; + [attrString appendAttributedString:linkSuffix]; + + return attrString; +} @end diff --git a/NSTextFieldHyperlinks/en.lproj/MainMenu.xib b/NSTextFieldHyperlinks/en.lproj/MainMenu.xib index 76073c3..08d6efb 100644 --- a/NSTextFieldHyperlinks/en.lproj/MainMenu.xib +++ b/NSTextFieldHyperlinks/en.lproj/MainMenu.xib @@ -1,3384 +1,711 @@ - - - - 1080 - 12C3006 - 2844 - 1187.34 - 625.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 2844 - - - IBNSLayoutConstraint - NSCustomObject - NSMenu - NSMenuItem - NSTextField - NSTextFieldCell - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - NSApplication - - - FirstResponder - - - NSApplication - - - AMainMenu - - - - NSTextFieldHyperlinks - - 1048576 - 2147483647 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - submenuAction: - - NSTextFieldHyperlinks - - - - About NSTextFieldHyperlinks - - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Preferences… - , - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Services - - 1048576 - 2147483647 - - - submenuAction: - - Services - - _NSServicesMenu - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Hide NSTextFieldHyperlinks - h - 1048576 - 2147483647 - - - - - - Hide Others - h - 1572864 - 2147483647 - - - - - - Show All - - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Quit NSTextFieldHyperlinks - q - 1048576 - 2147483647 - - - - - _NSAppleMenu - - - - - File - - 1048576 - 2147483647 - - - submenuAction: - - File - - - - New - n - 1048576 - 2147483647 - - - - - - Open… - o - 1048576 - 2147483647 - - - - - - Open Recent - - 1048576 - 2147483647 - - - submenuAction: - - Open Recent - - - - Clear Menu - - 1048576 - 2147483647 - - - - - _NSRecentDocumentsMenu - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Close - w - 1048576 - 2147483647 - - - - - - Save… - s - 1048576 - 2147483647 - - - - - - Revert to Saved - - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Page Setup... - P - 1179648 - 2147483647 - - - - - - - Print… - p - 1048576 - 2147483647 - - - - - - - - - Edit - - 1048576 - 2147483647 - - - submenuAction: - - Edit - - - - Undo - z - 1048576 - 2147483647 - - - - - - Redo - Z - 1179648 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Cut - x - 1048576 - 2147483647 - - - - - - Copy - c - 1048576 - 2147483647 - - - - - - Paste - v - 1048576 - 2147483647 - - - - - - Paste and Match Style - V - 1572864 - 2147483647 - - - - - - Delete - - 1048576 - 2147483647 - - - - - - Select All - a - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Find - - 1048576 - 2147483647 - - - submenuAction: - - Find - - - - Find… - f - 1048576 - 2147483647 - - - 1 - - - - Find and Replace… - f - 1572864 - 2147483647 - - - 12 - - - - Find Next - g - 1048576 - 2147483647 - - - 2 - - - - Find Previous - G - 1179648 - 2147483647 - - - 3 - - - - Use Selection for Find - e - 1048576 - 2147483647 - - - 7 - - - - Jump to Selection - j - 1048576 - 2147483647 - - - - - - - - - Spelling and Grammar - - 1048576 - 2147483647 - - - submenuAction: - - Spelling and Grammar - - - - Show Spelling and Grammar - : - 1048576 - 2147483647 - - - - - - Check Document Now - ; - 1048576 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Check Spelling While Typing - - 1048576 - 2147483647 - - - - - - Check Grammar With Spelling - - 1048576 - 2147483647 - - - - - - Correct Spelling Automatically - - 2147483647 - - - - - - - - - Substitutions - - 1048576 - 2147483647 - - - submenuAction: - - Substitutions - - - - Show Substitutions - - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Smart Copy/Paste - f - 1048576 - 2147483647 - - - 1 - - - - Smart Quotes - g - 1048576 - 2147483647 - - - 2 - - - - Smart Dashes - - 2147483647 - - - - - - Smart Links - G - 1179648 - 2147483647 - - - 3 - - - - Text Replacement - - 2147483647 - - - - - - - - - Transformations - - 2147483647 - - - submenuAction: - - Transformations - - - - Make Upper Case - - 2147483647 - - - - - - Make Lower Case - - 2147483647 - - - - - - Capitalize - - 2147483647 - - - - - - - - - Speech - - 1048576 - 2147483647 - - - submenuAction: - - Speech - - - - Start Speaking - - 1048576 - 2147483647 - - - - - - Stop Speaking - - 1048576 - 2147483647 - - - - - - - - - - - - Format - - 2147483647 - - - submenuAction: - - Format - - - - Font - - 2147483647 - - - submenuAction: - - Font - - - - Show Fonts - t - 1048576 - 2147483647 - - - - - - Bold - b - 1048576 - 2147483647 - - - 2 - - - - Italic - i - 1048576 - 2147483647 - - - 1 - - - - Underline - u - 1048576 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Bigger - + - 1048576 - 2147483647 - - - 3 - - - - Smaller - - - 1048576 - 2147483647 - - - 4 - - - - YES - YES - - - 2147483647 - - - - - - Kern - - 2147483647 - - - submenuAction: - - Kern - - - - Use Default - - 2147483647 - - - - - - Use None - - 2147483647 - - - - - - Tighten - - 2147483647 - - - - - - Loosen - - 2147483647 - - - - - - - - - Ligatures - - 2147483647 - - - submenuAction: - - Ligatures - - - - Use Default - - 2147483647 - - - - - - Use None - - 2147483647 - - - - - - Use All - - 2147483647 - - - - - - - - - Baseline - - 2147483647 - - - submenuAction: - - Baseline - - - - Use Default - - 2147483647 - - - - - - Superscript - - 2147483647 - - - - - - Subscript - - 2147483647 - - - - - - Raise - - 2147483647 - - - - - - Lower - - 2147483647 - - - - - - - - - YES - YES - - - 2147483647 - - - - - - Show Colors - C - 1048576 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Copy Style - c - 1572864 - 2147483647 - - - - - - Paste Style - v - 1572864 - 2147483647 - - - - - _NSFontMenu - - - - - Text - - 2147483647 - - - submenuAction: - - Text - - - - Align Left - { - 1048576 - 2147483647 - - - - - - Center - | - 1048576 - 2147483647 - - - - - - Justify - - 2147483647 - - - - - - Align Right - } - 1048576 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Writing Direction - - 2147483647 - - - submenuAction: - - Writing Direction - - - - YES - Paragraph - - 2147483647 - - - - - - CURlZmF1bHQ - - 2147483647 - - - - - - CUxlZnQgdG8gUmlnaHQ - - 2147483647 - - - - - - CVJpZ2h0IHRvIExlZnQ - - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - YES - Selection - - 2147483647 - - - - - - CURlZmF1bHQ - - 2147483647 - - - - - - CUxlZnQgdG8gUmlnaHQ - - 2147483647 - - - - - - CVJpZ2h0IHRvIExlZnQ - - 2147483647 - - - - - - - - - YES - YES - - - 2147483647 - - - - - - Show Ruler - - 2147483647 - - - - - - Copy Ruler - c - 1310720 - 2147483647 - - - - - - Paste Ruler - v - 1310720 - 2147483647 - - - - - - - - - - - - View - - 1048576 - 2147483647 - - - submenuAction: - - View - - - - Show Toolbar - t - 1572864 - 2147483647 - - - - - - Customize Toolbar… - - 1048576 - 2147483647 - - - - - - - - - Window - - 1048576 - 2147483647 - - - submenuAction: - - Window - - - - Minimize - m - 1048576 - 2147483647 - - - - - - Zoom - - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Bring All to Front - - 1048576 - 2147483647 - - - - - _NSWindowsMenu - - - - - Help - - 2147483647 - - - submenuAction: - - Help - - - - NSTextFieldHyperlinks Help - ? - 1048576 - 2147483647 - - - - - _NSHelpMenu - - - - _NSMainMenu - - - 15 - 2 - {{335, 390}, {244, 57}} - 1954021376 - NSTextFieldHyperlinks - NSWindow - - - - - 256 - - - - 258 - {{17, 20}, {210, 17}} - - - _NS:1535 - YES - - 67108928 - 272632064 - Label - - LucidaGrande - 13 - 1044 - - _NS:1535 - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - {244, 57} - - - - - {{0, 0}, {1440, 878}} - {10000000000000, 10000000000000} - YES - - - AppDelegate - - - NSFontManager - - - - - - - terminate: - - - - 449 - - - - orderFrontStandardAboutPanel: - - - - 142 - - - - delegate - - - - 495 - - - - performMiniaturize: - - - - 37 - - - - arrangeInFront: - - - - 39 - - - - print: - - - - 86 - - - - runPageLayout: - - - - 87 - - - - clearRecentDocuments: - - - - 127 - - - - performClose: - - - - 193 - - - - toggleContinuousSpellChecking: - - - - 222 - - - - undo: - - - - 223 - - - - copy: - - - - 224 - - - - checkSpelling: - - - - 225 - - - - paste: - - - - 226 - - - - stopSpeaking: - - - - 227 - - - - cut: - - - - 228 - - - - showGuessPanel: - - - - 230 - - - - redo: - - - - 231 - - - - selectAll: - - - - 232 - - - - startSpeaking: - - - - 233 - - - - delete: - - - - 235 - - - - performZoom: - - - - 240 - - - - performFindPanelAction: - - - - 241 - - - - centerSelectionInVisibleArea: - - - - 245 - - - - toggleGrammarChecking: - - - - 347 - - - - toggleSmartInsertDelete: - - - - 355 - - - - toggleAutomaticQuoteSubstitution: - - - - 356 - - - - toggleAutomaticLinkDetection: - - - - 357 - - - - saveDocument: - - - - 362 - - - - revertDocumentToSaved: - - - - 364 - - - - runToolbarCustomizationPalette: - - - - 365 - - - - toggleToolbarShown: - - - - 366 - - - - hide: - - - - 367 - - - - hideOtherApplications: - - - - 368 - - - - unhideAllApplications: - - - - 370 - - - - newDocument: - - - - 373 - - - - openDocument: - - - - 374 - - - - raiseBaseline: - - - - 426 - - - - lowerBaseline: - - - - 427 - - - - copyFont: - - - - 428 - - - - subscript: - - - - 429 - - - - superscript: - - - - 430 - - - - tightenKerning: - - - - 431 - - - - underline: - - - - 432 - - - - orderFrontColorPanel: - - - - 433 - - - - useAllLigatures: - - - - 434 - - - - loosenKerning: - - - - 435 - - - - pasteFont: - - - - 436 - - - - unscript: - - - - 437 - - - - useStandardKerning: - - - - 438 - - - - useStandardLigatures: - - - - 439 - - - - turnOffLigatures: - - - - 440 - - - - turnOffKerning: - - - - 441 - - - - toggleAutomaticSpellingCorrection: - - - - 456 - - - - orderFrontSubstitutionsPanel: - - - - 458 - - - - toggleAutomaticDashSubstitution: - - - - 461 - - - - toggleAutomaticTextReplacement: - - - - 463 - - - - uppercaseWord: - - - - 464 - - - - capitalizeWord: - - - - 467 - - - - lowercaseWord: - - - - 468 - - - - pasteAsPlainText: - - - - 486 - - - - performFindPanelAction: - - - - 487 - - - - performFindPanelAction: - - - - 488 - - - - performFindPanelAction: - - - - 489 - - - - showHelp: - - - - 493 - - - - alignCenter: - - - - 518 - - - - pasteRuler: - - - - 519 - - - - toggleRuler: - - - - 520 - - - - alignRight: - - - - 521 - - - - copyRuler: - - - - 522 - - - - alignJustified: - - - - 523 - - - - alignLeft: - - - - 524 - - - - makeBaseWritingDirectionNatural: - - - - 525 - - - - makeBaseWritingDirectionLeftToRight: - - - - 526 - - - - makeBaseWritingDirectionRightToLeft: - - - - 527 - - - - makeTextWritingDirectionNatural: - - - - 528 - - - - makeTextWritingDirectionLeftToRight: - - - - 529 - - - - makeTextWritingDirectionRightToLeft: - - - - 530 - - - - performFindPanelAction: - - - - 535 - - - - addFontTrait: - - - - 421 - - - - addFontTrait: - - - - 422 - - - - modifyFont: - - - - 423 - - - - orderFrontFontPanel: - - - - 424 - - - - modifyFont: - - - - 425 - - - - window - - - - 532 - - - - hyperlinkTextField - - - - 541 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - -3 - - - Application - - - 29 - - - - - - - - - - - - - - 19 - - - - - - - - 56 - - - - - - - - 217 - - - - - - - - 83 - - - - - - - - 81 - - - - - - - - - - - - - - - - - 75 - - - - - 78 - - - - - 72 - - - - - 82 - - - - - 124 - - - - - - - - 77 - - - - - 73 - - - - - 79 - - - - - 112 - - - - - 74 - - - - - 125 - - - - - - - - 126 - - - - - 205 - - - - - - - - - - - - - - - - - - - - - - 202 - - - - - 198 - - - - - 207 - - - - - 214 - - - - - 199 - - - - - 203 - - - - - 197 - - - - - 206 - - - - - 215 - - - - - 218 - - - - - - - - 216 - - - - - - - - 200 - - - - - - - - - - - - - 219 - - - - - 201 - - - - - 204 - - - - - 220 - - - - - - - - - - - - - 213 - - - - - 210 - - - - - 221 - - - - - 208 - - - - - 209 - - - - - 57 - - - - - - - - - - - - - - - - - - 58 - - - - - 134 - - - - - 150 - - - - - 136 - - - - - 144 - - - - - 129 - - - - - 143 - - - - - 236 - - - - - 131 - - - - - - - - 149 - - - - - 145 - - - - - 130 - - - - - 24 - - - - - - - - - - - 92 - - - - - 5 - - - - - 239 - - - - - 23 - - - - - 295 - - - - - - - - 296 - - - - - - - - - 297 - - - - - 298 - - - - - 211 - - - - - - - - 212 - - - - - - - - - 195 - - - - - 196 - - - - - 346 - - - - - 348 - - - - - - - - 349 - - - - - - - - - - - - - - 350 - - - - - 351 - - - - - 354 - - - - - 371 - - - - - - - - 372 - - - - - - 4 - 0 - - 4 - 1 - - 20 - - 1000 - - 9 - 40 - 3 - - - - 6 - 0 - - 6 - 1 - - 20 - - 1000 - - 8 - 29 - 3 - - - - 5 - 0 - - 5 - 1 - - 20 - - 1000 - - 8 - 29 - 3 - - - - 3 - 0 - - 3 - 1 - - 20 - - 1000 - - 9 - 40 - 3 - - - - - - 375 - - - - - - - - 376 - - - - - - - - - 377 - - - - - - - - 388 - - - - - - - - - - - - - - - - - - - - - - - 389 - - - - - 390 - - - - - 391 - - - - - 392 - - - - - 393 - - - - - 394 - - - - - 395 - - - - - 396 - - - - - 397 - - - - - - - - 398 - - - - - - - - 399 - - - - - - - - 400 - - - - - 401 - - - - - 402 - - - - - 403 - - - - - 404 - - - - - 405 - - - - - - - - - - - - 406 - - - - - 407 - - - - - 408 - - - - - 409 - - - - - 410 - - - - - 411 - - - - - - - - - - 412 - - - - - 413 - - - - - 414 - - - - - 415 - - - - - - - - - - - 416 - - - - - 417 - - - - - 418 - - - - - 419 - - - - - 420 - - - - - 450 - - - - - - - - 451 - - - - - - - - - - 452 - - - - - 453 - - - - - 454 - - - - - 457 - - - - - 459 - - - - - 460 - - - - - 462 - - - - - 465 - - - - - 466 - - - - - 485 - - - - - 490 - - - - - - - - 491 - - - - - - - - 492 - - - - - 494 - - - - - 496 - - - - - - - - 497 - - - - - - - - - - - - - - - - - 498 - - - - - 499 - - - - - 500 - - - - - 501 - - - - - 502 - - - - - 503 - - - - - - - - 504 - - - - - 505 - - - - - 506 - - - - - 507 - - - - - 508 - - - - - - - - - - - - - - - - 509 - - - - - 510 - - - - - 511 - - - - - 512 - - - - - 513 - - - - - 514 - - - - - 515 - - - - - 516 - - - - - 517 - - - - - 534 - - - - - 536 - - - - - - - - 537 - - - - - 545 - - - - - 546 - - - - - 547 - - - - - 548 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{380, 496}, {480, 360}} - - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - HyperlinkTextField - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 548 - - - - - AppDelegate - NSObject - - HyperlinkTextField - NSWindow - - - - hyperlinkTextField - HyperlinkTextField - - - window - NSWindow - - - - IBProjectSource - ./Classes/AppDelegate.h - - - - HyperlinkTextField - NSTextField - - IBProjectSource - ./Classes/HyperlinkTextField.h - - - - NSLayoutConstraint - NSObject - - IBProjectSource - ./Classes/NSLayoutConstraint.h - - - - - 0 - IBCocoaFramework - YES - 3 - - {11, 11} - {10, 3} - - YES - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Default + + + + + + + Left to Right + + + + + + + Right to Left + + + + + + + + + + + Default + + + + + + + Left to Right + + + + + + + Right to Left + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +