diff --git a/Classes/HOPopoverViewController.h b/Classes/HOPopoverViewController.h new file mode 100644 index 0000000..a69ab07 --- /dev/null +++ b/Classes/HOPopoverViewController.h @@ -0,0 +1,15 @@ +// +// HOStringSense by Dirk Holtwick 2012, holtwick.it +// Based on OMColorSense by by Ole Zorn, 2012 +// Licensed under BSD style license +// + +#import + +@interface HOPopoverViewController : NSViewController { + NSTextField *_textField; +} + +@property (weak, nonatomic) id delegate; + +@end diff --git a/Classes/HOPopoverViewController.m b/Classes/HOPopoverViewController.m new file mode 100644 index 0000000..747095e --- /dev/null +++ b/Classes/HOPopoverViewController.m @@ -0,0 +1,54 @@ +// +// HOStringSense by Dirk Holtwick 2012, holtwick.it +// Based on OMColorSense by by Ole Zorn, 2012 +// Licensed under BSD style license +// + +#import "HOPopoverViewController.h" + +@implementation HOPopoverViewController + +- (NSView *)view { + if(!_textField) { + _textField = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 200, 200)]; + _textField.focusRingType = NSFocusRingTypeNone; + _textField.bordered = NO; + _textField.backgroundColor = [NSColor colorWithCalibratedWhite:0.974 alpha:1.000]; + _textField.textColor = [NSColor colorWithCalibratedWhite:0.107 alpha:1.000]; + _textField.delegate = self; + } + return _textField; +} + +- (void)dealloc { + _delegate = nil; +} + +- (void)controlTextDidChange:(NSNotification *)obj { + // NSLog(@"Test: %@", [_textField stringValue]); + if([_delegate respondsToSelector:@selector(stringDidChange:)]) { + [_delegate performSelector:@selector(stringDidChange:) withObject:nil]; + } +} + +- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector { + // NSLog(@"Textview Command: %@", NSStringFromSelector(commandSelector)); + if(commandSelector == @selector(cancelOperation:)) { + if([_delegate respondsToSelector:@selector(dismissPopover)]) { + [_delegate performSelector:@selector(dismissPopover)]; + } + return YES; + } + + if (commandSelector == @selector(insertNewline:)) { + // new line action: + // always insert a line-break character and don’t cause the receiver + // to end editing + [textView insertNewlineIgnoringFieldEditor:self]; + return YES; + } + + return NO; +} + +@end diff --git a/Classes/HOStringFrameView.h b/Classes/HOStringFrameView.h new file mode 100644 index 0000000..d60b447 --- /dev/null +++ b/Classes/HOStringFrameView.h @@ -0,0 +1,13 @@ +// +// HOStringSense by Dirk Holtwick 2012, holtwick.it +// Based on OMColorSense by by Ole Zorn, 2012 +// Licensed under BSD style license +// + +#import + +@interface HOStringFrameView : NSView + +@property (nonatomic, strong) NSColor *color; + +@end diff --git a/Classes/HOStringFrameView.m b/Classes/HOStringFrameView.m new file mode 100644 index 0000000..1921450 --- /dev/null +++ b/Classes/HOStringFrameView.m @@ -0,0 +1,25 @@ +// +// HOStringSense by Dirk Holtwick 2012, holtwick.it +// Based on OMColorSense by by Ole Zorn, 2012 +// Licensed under BSD style license +// + +#import "HOStringFrameView.h" + +@implementation HOStringFrameView + +- (void)drawRect:(NSRect)dirtyRect { + [self.color setStroke]; + NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:NSInsetRect(self.bounds, 0.5, 0.5) xRadius:3.0 yRadius:3.0]; + [path stroke]; +} + +- (void)setColor:(NSColor *)color { + if (color != _color) { + _color = color; + [self setNeedsDisplay:YES]; + } +} + + +@end diff --git a/Classes/HOStringHelper.h b/Classes/HOStringHelper.h new file mode 100644 index 0000000..a4dafaa --- /dev/null +++ b/Classes/HOStringHelper.h @@ -0,0 +1,32 @@ +// +// HOStringSense by Dirk Holtwick 2012, holtwick.it +// Based on OMColorSense by by Ole Zorn, 2012 +// Licensed under BSD style license +// + +#import +#import + +@class HOStringFrameView, HOStringInfoButton, HOPopoverViewController; + +@interface HOStringHelper : NSObject { + HOPopoverViewController *_stringPopoverViewController; + NSPopover *_stringPopover; + NSRegularExpression *_stringRegex; +} + +@property (nonatomic, strong) HOStringInfoButton *stringButton; +@property (nonatomic, strong) HOStringFrameView *stringFrameView; +@property (nonatomic, strong) NSTextView *textView; +@property (nonatomic, assign) NSRange selectedStringRange; +@property (nonatomic, copy) NSString *selectedStringContent; + +- (void)dismissPopover; +- (void)activateColorHighlighting; +- (void)deactivateColorHighlighting; +- (NSString *)stringInText:(NSString *)text selectedRange:(NSRange)selectedRange matchedRange:(NSRangePointer)matchedRange; + +- (NSString *)escapeString:(NSString *)string; +- (NSString *)unescapeString:(NSString *)string; + +@end diff --git a/Classes/HOStringHelper.m b/Classes/HOStringHelper.m new file mode 100755 index 0000000..dcffce8 --- /dev/null +++ b/Classes/HOStringHelper.m @@ -0,0 +1,389 @@ +// +// HOStringSense by Dirk Holtwick 2012, holtwick.it +// Based on OMColorSense by by Ole Zorn, 2012 +// Licensed under BSD style license +// + +#import "HOStringHelper.h" +#import "HOStringInfoButton.h" +#import "HOStringFrameView.h" +#import "HOPopoverViewController.h" + +#define kHOStringHelperHighlightingDisabled @"HOStringHelperHighlightingDisabled" + +#define NSNullRange NSMakeRange(NSNotFound, 0) + +@implementation HOStringHelper + +#pragma mark - String Helper + +- (NSString *)escapeString:(NSString *)string { + NSMutableString *result = [NSMutableString string]; + @try { + NSUInteger length = [string length]; + for (NSUInteger i = 0; i < length; i++) { + unichar uc = [string characterAtIndex:i]; + switch (uc) { + case '\"': [result appendString:@"\\\""]; break; + case '\'': [result appendString:@"\\\'"]; break; + case '\\': [result appendString:@"\\\\"]; break; + case '\t': [result appendString:@"\\t"]; break; + case '\n': [result appendString:@"\\n"]; break; + case '\r': [result appendString:@"\\r"]; break; + case '\b': [result appendString:@"\\b"]; break; + case '\f': [result appendString:@"\\f"]; break; + default: { + if (uc < 0x20) { + [result appendFormat:@"\\u%04x", uc]; + } + else { + [result appendFormat:@"%C", uc]; + } + } break; + } + } + // } + } + @catch (NSException *exception) { + NSLog(@"Error while converting string: %@", exception); + } + return (NSString *)result; +} + +#define nextUC ++i; if(i>=length) { break; }; uc = [string characterAtIndex:i]; +- (NSString *)unescapeString:(NSString *)string { + // NSScanner *scanner = [[NSScanner alloc] initWithString:string]; + NSMutableString *result = [NSMutableString string]; + NSUInteger length = [string length]; + for (NSUInteger i = 0; i < length; i++) { + unichar uc = [string characterAtIndex:i]; + if(uc == '\\') { + nextUC; + switch (uc) { + case '\"': [result appendString:@"\""]; break; + case '\'': [result appendString:@"\'"]; break; + case '\\': [result appendString:@"\\"]; break; + case 't': [result appendString:@"\t"]; break; + case 'n': [result appendString:@"\n"]; break; + case 'r': [result appendString:@"\r"]; break; + case 'b': [result appendString:@"\b"]; break; + case 'f': [result appendString:@"\f"]; break; + case 'u': { + unichar hex[5]; hex[4] = 0; + nextUC; hex[0] = uc; + nextUC; hex[1] = uc; + nextUC; hex[2] = uc; + nextUC; hex[3] = uc; + + } break; + default: { + CFStringAppendCharacters((CFMutableStringRef)result, &uc, 1); + } break; + } + } + else { + CFStringAppendCharacters((CFMutableStringRef)result, &uc, 1); + } + } + return result; +} + +//- (NSString *)unescapeString:(NSString *)string { +// @try { +// NSError *error = nil; +// NSString *s = [NSString stringWithFormat:@"\"%@\"", string]; +// NSString *result = [NSJSONSerialization JSONObjectWithData:[s dataUsingEncoding:NSUTF8StringEncoding] +// options:NSJSONReadingAllowFragments +// error:&error]; +// if(!result) { +// NSLog(@"Error while unescaping: %@", error); +// return nil; +// } +// return result; +// } +// @catch (NSException *exception) { ; } +// return nil; +//} + +#pragma mark - Plugin Initialization + ++ (void)pluginDidLoad:(NSBundle *)plugin { + static id sharedPlugin = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedPlugin = [[self alloc] init]; + }); +} + +- (id)init { + if (self = [super init]) { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidFinishLaunching:) name:NSApplicationDidFinishLaunchingNotification object:nil]; + _selectedStringRange = NSMakeRange(NSNotFound, 0); + _stringRegex = [NSRegularExpression regularExpressionWithPattern:@"\"((\\\\\"|.)*?)\"" + options:0 + error:NULL]; + } + return self; +} + +- (void)applicationDidFinishLaunching:(NSNotification *)notification { + NSMenuItem *editMenuItem = [[NSApp mainMenu] itemWithTitle:@"Edit"]; + if (editMenuItem) { + [[editMenuItem submenu] addItem:[NSMenuItem separatorItem]]; + + { + NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:@"Enable Strings Popover" action:@selector(toggleColorHighlightingEnabled:) keyEquivalent:@""]; + [item setTarget:self]; + [[editMenuItem submenu] addItem:item]; + } + + { + NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:@"Show Strings Popover" action:@selector(showPopover:) keyEquivalent:@""]; + [item setTarget:self]; + [[editMenuItem submenu] addItem:item]; + } + + // NSMenuItem *insertColorMenuItem = [[[NSMenuItem alloc] initWithTitle:@"Insert Color..." action:@selector(insertColor:) keyEquivalent:@""] autorelease]; + // [insertColorMenuItem setTarget:self]; + // [[editMenuItem submenu] addItem:insertColorMenuItem]; + } + + BOOL highlightingEnabled = ![[NSUserDefaults standardUserDefaults] boolForKey:kHOStringHelperHighlightingDisabled]; + if (highlightingEnabled) { + [self activateColorHighlighting]; + } +} + +#pragma mark - Preferences + +- (BOOL)validateMenuItem:(NSMenuItem *)menuItem { + if ([menuItem action] == @selector(showPopover:)) { + return ![_stringPopover isShown]; + } + else if ([menuItem action] == @selector(toggleColorHighlightingEnabled:)) { + BOOL enabled = [[NSUserDefaults standardUserDefaults] boolForKey:kHOStringHelperHighlightingDisabled]; + [menuItem setState:enabled ? NSOffState : NSOnState]; + return YES; + } + return YES; +} + +- (void)toggleColorHighlightingEnabled:(id)sender { + BOOL enabled = [[NSUserDefaults standardUserDefaults] boolForKey:kHOStringHelperHighlightingDisabled]; + [[NSUserDefaults standardUserDefaults] setBool:!enabled forKey:kHOStringHelperHighlightingDisabled]; + if (enabled) { + [self activateColorHighlighting]; + } else { + [self deactivateColorHighlighting]; + } +} + +- (void)activateColorHighlighting { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(selectionDidChange:) name:NSTextViewDidChangeSelectionNotification object:nil]; + if (!self.textView) { + NSResponder *firstResponder = [[NSApp keyWindow] firstResponder]; + if ([firstResponder isKindOfClass:NSClassFromString(@"DVTSourceTextView")] && [firstResponder isKindOfClass:[NSTextView class]]) { + self.textView = (NSTextView *)firstResponder; + } + } + if (self.textView) { + NSNotification *notification = [NSNotification notificationWithName:NSTextViewDidChangeSelectionNotification object:self.textView]; + [self selectionDidChange:notification]; + + } +} + +- (void)deactivateColorHighlighting { + [[NSNotificationCenter defaultCenter] removeObserver:self name:NSTextViewDidChangeSelectionNotification object:nil]; + [self dismissPopover]; + self.textView = nil; +} + +#pragma mark - Text Selection Handling + +- (void)selectionDidChange:(NSNotification *)notification { + // NSLog(@"%s", __PRETTY_FUNCTION__); + if ([[notification object] isKindOfClass:NSClassFromString(@"DVTSourceTextView")] && [[notification object] isKindOfClass:[NSTextView class]]) { + self.textView = (NSTextView *)[notification object]; + BOOL disabled = [[NSUserDefaults standardUserDefaults] boolForKey:kHOStringHelperHighlightingDisabled]; + if (disabled) { + return; + } + NSArray *selectedRanges = [self.textView selectedRanges]; + if (selectedRanges.count >= 1) { + NSRange selectedRange = [[selectedRanges objectAtIndex:0] rangeValue]; + NSString *text = self.textView.textStorage.string; + NSRange lineRange = [text lineRangeForRange:selectedRange]; + NSRange selectedRangeInLine = NSMakeRange(selectedRange.location - lineRange.location, selectedRange.length); + NSString *line = [text substringWithRange:lineRange]; + NSRange stringRange = NSNullRange; + + self.selectedStringContent = [self stringInText:line selectedRange:selectedRangeInLine matchedRange:&stringRange]; + if (_selectedStringContent && [_selectedStringContent length] >= 2) { + + // String's content + NSInteger oldLocation = _selectedStringRange.location; + self.selectedStringContent = [_selectedStringContent substringWithRange:NSMakeRange(1, _selectedStringContent.length - 2)]; + self.selectedStringRange = NSMakeRange(stringRange.location + lineRange.location, stringRange.length); + if(oldLocation != _selectedStringRange.location) { + [self dismissPopover]; + } + + // Color calculations based ion Xcode theme + NSColor *backgroundColor = [self.textView.backgroundColor colorUsingColorSpace:[NSColorSpace genericRGBColorSpace]]; + CGFloat r = 1.0; CGFloat g = 1.0; CGFloat b = 1.0; + [backgroundColor getRed:&r green:&g blue:&b alpha:NULL]; + CGFloat backgroundLuminance = (r + g + b) / 3.0; + NSColor *strokeColor = (backgroundLuminance > 0.5) ? [NSColor colorWithCalibratedWhite:0.5 alpha:1] : [NSColor colorWithCalibratedWhite:1.000 alpha:1]; + + // Button's label + NSString * aString = [NSString stringWithFormat:@"%d", (int)[[self unescapeString:_selectedStringContent] length]]; + NSMutableDictionary * aAttributes = [NSMutableDictionary dictionary]; + NSMutableParagraphStyle * aStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; + aStyle.alignment = NSCenterTextAlignment; + [aAttributes setValue:(backgroundLuminance > 0.5) ? [NSColor whiteColor] : [NSColor blackColor] + forKey:NSForegroundColorAttributeName]; + [aAttributes setValue:[NSFont boldSystemFontOfSize:11] forKey:NSFontAttributeName]; + [aAttributes setValue:aStyle forKey:NSParagraphStyleAttributeName]; + NSAttributedString * aAttributedString = [[NSAttributedString alloc] initWithString:aString attributes:aAttributes]; + self.stringButton.attributedTitle = aAttributedString; + self.stringButton.strokeColor = strokeColor; + + // Place button + NSRect selectionRectOnScreen = [self.textView firstRectForCharacterRange:self.selectedStringRange]; + NSRect selectionRectInWindow = [self.textView.window convertRectFromScreen:selectionRectOnScreen]; + NSRect selectionRectInView = [self.textView convertRect:selectionRectInWindow fromView:nil]; + + CGFloat Width = [aAttributedString size].width + 14; + NSRect buttonRect = NSMakeRect(NSMinX(selectionRectInView), NSMinY(selectionRectInView) - selectionRectInView.size.height - 2, Width, selectionRectInView.size.height); + self.stringButton.frame = NSIntegralRect(buttonRect); + + + [self.textView addSubview:self.stringButton]; + + // Draw the frame around the string + self.stringFrameView.frame = NSInsetRect(NSIntegralRect(selectionRectInView), -1, -1); + self.stringFrameView.color = strokeColor; + [self.textView addSubview:self.stringFrameView]; + + return; + } + } + [self removeSelection]; + } +} + +- (void)dismissPopover { + // NSLog(@"%s", __PRETTY_FUNCTION__); + if(_stringPopover) { + [_stringPopover close]; + } +} + +- (void)removeSelection { + // NSLog(@"%s", __PRETTY_FUNCTION__); + [self dismissPopover]; + [self.stringButton removeFromSuperview]; + [self.stringFrameView removeFromSuperview]; + self.selectedStringRange = NSNullRange; + self.selectedStringContent = nil; +} + +- (void)stringDidChange:(id)sender { + // NSLog(@"%s", __PRETTY_FUNCTION__); + if (self.selectedStringRange.location == NSNotFound) { + return; + } + NSTextField *textfield = (id)_stringPopoverViewController.view; + NSString *result = textfield.stringValue; + if(result) { + result = [self escapeString:result]; + if(![result isEqualToString:_selectedStringContent]) { + [self.textView.undoManager beginUndoGrouping]; + [self.textView insertText:[NSString stringWithFormat:@"%@", result] + replacementRange:self.selectedStringRange]; + [self.textView.undoManager endUndoGrouping]; + } + } +} + +//- (void)popoverWillClose:(NSNotification *)notification { +// NSLog(@"%s", __PRETTY_FUNCTION__); +// // [self stringDidChange:nil]; +//} + +- (void)showPopover:(id)sender { + // NSLog(@"%s", __PRETTY_FUNCTION__); + if(_selectedStringRange.location == NSNotFound) { + return; + } + [self dismissPopover]; + if(!_stringPopoverViewController) { + _stringPopoverViewController = [[HOPopoverViewController alloc] init]; + _stringPopoverViewController.delegate = self; + } + NSTextField *textfield = (id)_stringPopoverViewController.view; + textfield.stringValue = [self unescapeString:_selectedStringContent]; + textfield.font = self.textView.font; + NSSize size = NSMakeSize(self.textView.bounds.size.width * 0.50, 120); + if(!_stringPopover) { + _stringPopover = [[NSPopover alloc] init]; + } + _stringPopover.contentViewController = _stringPopoverViewController; + _stringPopover.contentSize = size; + _stringPopover.delegate = self; + [_stringPopover showRelativeToRect:self.stringButton.bounds + ofView:self.stringButton + preferredEdge:NSMinYEdge]; +} + +#pragma mark - View Initialization + +- (HOStringInfoButton *)stringButton { + if (!_stringButton) { + _stringButton = [[HOStringInfoButton alloc] initWithFrame:NSMakeRect(0, 0, 100, 30)]; + [_stringButton setTarget:self]; + [_stringButton setAction:@selector(showPopover:)]; + } + return _stringButton; +} + +- (HOStringFrameView *)stringFrameView { + if (!_stringFrameView) { + _stringFrameView = [[HOStringFrameView alloc] initWithFrame:NSZeroRect]; + } + return _stringFrameView; +} + +#pragma mark - Color String Parsing + +- (NSString *)stringInText:(NSString *)text selectedRange:(NSRange)selectedRange matchedRange:(NSRangePointer)matchedRange { + __block NSString *foundStringContent = nil; + __block NSRange foundColorRange = NSMakeRange(NSNotFound, 0); + [_stringRegex enumerateMatchesInString:text options:0 range:NSMakeRange(0, text.length) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) { + NSRange colorRange = [result range]; + if (selectedRange.location >= colorRange.location + 1 && NSMaxRange(selectedRange) <= NSMaxRange(colorRange) - 1) { + foundStringContent = [text substringWithRange:[result rangeAtIndex:0]]; + colorRange.location++; + colorRange.length -= 2; + foundColorRange = colorRange; + *stop = YES; + } + }]; + if (foundStringContent) { + if (matchedRange != NULL) { + *matchedRange = foundColorRange; + } + return foundStringContent; + } + return nil; +} + +#pragma mark - + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [self dismissPopover]; +} + +@end diff --git a/Classes/HOStringInfoButton.h b/Classes/HOStringInfoButton.h new file mode 100644 index 0000000..74ad469 --- /dev/null +++ b/Classes/HOStringInfoButton.h @@ -0,0 +1,13 @@ +// +// HOStringSense by Dirk Holtwick 2012, holtwick.it +// Based on OMColorSense by by Ole Zorn, 2012 +// Licensed under BSD style license +// + +#import + +@interface HOStringInfoButton : NSButton + +@property (copy, nonatomic) NSColor *strokeColor; + +@end diff --git a/Classes/HOStringInfoButton.m b/Classes/HOStringInfoButton.m new file mode 100644 index 0000000..7cc0ea6 --- /dev/null +++ b/Classes/HOStringInfoButton.m @@ -0,0 +1,44 @@ +// +// HOStringSense by Dirk Holtwick 2012, holtwick.it +// Based on OMColorSense by by Ole Zorn, 2012 +// Licensed under BSD style license +// + +#import "HOStringInfoButton.h" + +@implementation HOStringInfoButton + +- (id)initWithFrame:(NSRect)frameRect { + if(self = [super initWithFrame:frameRect]) { + self.font = [NSFont boldSystemFontOfSize:11.]; + self.bordered = NO; + } + return self; +} + +- (void)drawRect:(NSRect)dirtyRect { + [NSGraphicsContext saveGraphicsState]; + NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:NSMakeRect(0, 0, self.bounds.size.width, self.bounds.size.height ) xRadius:3.0 yRadius:3.0]; + [path addClip]; + if (self.strokeColor) { + [self.strokeColor set]; + } + else { + [[NSColor colorWithCalibratedWhite:0.500 alpha:0.500] setFill]; + } + [path fill]; + [super drawRect:dirtyRect]; + + // [self drawWellInside:self.bounds]; + [NSGraphicsContext restoreGraphicsState]; +} + +- (void)setStrokeColor:(NSColor *)strokeColor { + if (strokeColor != _strokeColor) { + _strokeColor = strokeColor; + [self setNeedsDisplay:YES]; + } +} + + +@end diff --git a/Classes/OMColorFrameView.h b/Classes/OMColorFrameView.h deleted file mode 100644 index ddceb72..0000000 --- a/Classes/OMColorFrameView.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// OMColorFrameView.h -// OMColorHelper -// -// Created by Ole Zorn on 09/07/12. -// -// - -#import - -@interface OMColorFrameView : NSView { - - NSColor *_color; -} - -@property (nonatomic, retain) NSColor *color; - -@end diff --git a/Classes/OMColorFrameView.m b/Classes/OMColorFrameView.m deleted file mode 100644 index db14d0c..0000000 --- a/Classes/OMColorFrameView.m +++ /dev/null @@ -1,36 +0,0 @@ -// -// OMColorFrameView.m -// OMColorHelper -// -// Created by Ole Zorn on 09/07/12. -// -// - -#import "OMColorFrameView.h" - -@implementation OMColorFrameView - -@synthesize color=_color; - -- (void)drawRect:(NSRect)dirtyRect -{ - [self.color setStroke]; - [NSBezierPath strokeRect:NSInsetRect(self.bounds, 0.5, 0.5)]; -} - -- (void)setColor:(NSColor *)color -{ - if (color != _color) { - [_color release]; - _color = [color retain]; - [self setNeedsDisplay:YES]; - } -} - -- (void)dealloc -{ - [_color release]; - [super dealloc]; -} - -@end diff --git a/Classes/OMColorHelper.h b/Classes/OMColorHelper.h deleted file mode 100644 index 43beb84..0000000 --- a/Classes/OMColorHelper.h +++ /dev/null @@ -1,64 +0,0 @@ -// -// OMColorHelper.h -// OMColorHelper -// -// Created by Ole Zorn on 09/07/12. -// -// - -#import -#import - -typedef enum OMColorType { - OMColorTypeNone = 0, - - OMColorTypeUIRGBA, //[UIColor colorWithRed:1.0 green:0.0 blue:0.0 alpha:1.0] - OMColorTypeUIRGBAInit, //[[UIColor alloc] initWithRed:1.0 green:0.0 blue:0.0 alpha:1.0] - OMColorTypeUIWhite, //[UIColor colorWithWhite:0.5 alpha:1.0] - OMColorTypeUIWhiteInit, //[[UIColor alloc] initWithWhite:0.5 alpha:1.0] - OMColorTypeUIConstant, //[UIColor redColor] - - OMColorTypeNSRGBACalibrated, //[NSColor colorWithCalibratedRed:1.0 green:0.0 blue:0.0 alpha:1.0] - OMColorTypeNSRGBADevice, //[NSColor colorWithDeviceRed:1.0 green:0.0 blue:0.0 alpha:1.0] - OMColorTypeNSWhiteCalibrated, //[NSColor colorWithCalibratedWhite:0.5 alpha:1.0] - OMColorTypeNSWhiteDevice, //[NSColor colorWithDeviceWhite:0.5 alpha:1.0] - OMColorTypeNSConstant, //[NSColor redColor] - -} OMColorType; - -BOOL OMColorTypeIsNSColor(OMColorType colorType) { return colorType >= OMColorTypeNSRGBACalibrated; } - -//TODO: Maybe support HSB and CMYK color types... - -@class OMColorFrameView, OMPlainColorWell; - -@interface OMColorHelper : NSObject { - - OMPlainColorWell *_colorWell; - OMColorFrameView *_colorFrameView; - NSRange _selectedColorRange; - OMColorType _selectedColorType; - NSTextView *_textView; - NSDictionary *_constantColorsByName; - - NSRegularExpression *_rgbaUIColorRegex; - NSRegularExpression *_rgbaNSColorRegex; - NSRegularExpression *_whiteNSColorRegex; - NSRegularExpression *_whiteUIColorRegex; - NSRegularExpression *_constantColorRegex; -} - -@property (nonatomic, retain) OMPlainColorWell *colorWell; -@property (nonatomic, retain) OMColorFrameView *colorFrameView; -@property (nonatomic, retain) NSTextView *textView; -@property (nonatomic, assign) NSRange selectedColorRange; -@property (nonatomic, assign) OMColorType selectedColorType; - -- (void)dismissColorWell; -- (void)activateColorHighlighting; -- (void)deactivateColorHighlighting; -- (NSColor *)colorInText:(NSString *)text selectedRange:(NSRange)selectedRange type:(OMColorType *)type matchedRange:(NSRangePointer)matchedRange; -- (NSString *)colorStringForColor:(NSColor *)color withType:(OMColorType)colorType; -- (double)dividedValue:(double)value withDivisorRange:(NSRange)divisorRange inString:(NSString *)text; - -@end diff --git a/Classes/OMColorHelper.m b/Classes/OMColorHelper.m deleted file mode 100755 index 713ed68..0000000 --- a/Classes/OMColorHelper.m +++ /dev/null @@ -1,517 +0,0 @@ -// -// OMColorHelper.m -// OMColorHelper -// -// Created by Ole Zorn on 09/07/12. -// -// - -#import "OMColorHelper.h" -#import "OMPlainColorWell.h" -#import "OMColorFrameView.h" - -#define kOMColorHelperHighlightingDisabled @"OMColorHelperHighlightingDisabled" -#define kOMColorHelperInsertionMode @"OMColorHelperInsertionMode" - -@implementation OMColorHelper - -@synthesize colorWell=_colorWell, colorFrameView=_colorFrameView, textView=_textView, selectedColorRange=_selectedColorRange, selectedColorType=_selectedColorType; - -#pragma mark - Plugin Initialization - -+ (void)pluginDidLoad:(NSBundle *)plugin -{ - static id sharedPlugin = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - sharedPlugin = [[self alloc] init]; - }); -} - -- (id)init -{ - if (self = [super init]) { - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidFinishLaunching:) name:NSApplicationDidFinishLaunchingNotification object:nil]; - _selectedColorRange = NSMakeRange(NSNotFound, 0); - _constantColorsByName = [[NSDictionary alloc] initWithObjectsAndKeys: - [[NSColor blackColor] colorUsingColorSpace:[NSColorSpace genericRGBColorSpace]], @"black", - [NSColor darkGrayColor], @"darkGray", - [NSColor lightGrayColor], @"lightGray", - [[NSColor whiteColor] colorUsingColorSpace:[NSColorSpace genericRGBColorSpace]], @"white", - [NSColor grayColor], @"gray", - [NSColor redColor], @"red", - [NSColor greenColor], @"green", - [NSColor blueColor], @"blue", - [NSColor cyanColor], @"cyan", - [NSColor yellowColor], @"yellow", - [NSColor magentaColor], @"magenta", - [NSColor orangeColor], @"orange", - [NSColor purpleColor], @"purple", - [NSColor brownColor], @"brown", - [[NSColor clearColor] colorUsingColorSpace:[NSColorSpace genericRGBColorSpace]], @"clear", nil]; - - _rgbaUIColorRegex = [[NSRegularExpression regularExpressionWithPattern:@"(\\[\\s*UIColor\\s+colorWith|\\[\\s*\\[\\s*UIColor\\s+alloc\\]\\s*initWith)Red:\\s*([0-9]*\\.?[0-9]*f?)\\s*(\\/\\s*[0-9]*\\.?[0-9]*f?)?\\s+green:\\s*([0-9]*\\.?[0-9]*f?)\\s*(\\/\\s*[0-9]*\\.?[0-9]*f?)?\\s+blue:\\s*([0-9]*\\.?[0-9]*f?)\\s*(\\/\\s*[0-9]*\\.?[0-9]*f?)?\\s*alpha:\\s*([0-9]*\\.?[0-9]*f?)\\s*(\\/\\s*[0-9]*\\.?[0-9]*f?)?\\s*\\]" options:0 error:NULL] retain]; - _whiteUIColorRegex = [[NSRegularExpression regularExpressionWithPattern:@"(\\[\\s*UIColor\\s+colorWith|\\[\\s*\\[\\s*UIColor\\s+alloc\\]\\s*initWith)White:\\s*([0-9]*\\.?[0-9]*f?)\\s*(\\/\\s*[0-9]*\\.?[0-9]*f?)?\\s+alpha:\\s*([0-9]*\\.?[0-9]*f?)\\s*(\\/\\s*[0-9]*\\.?[0-9]*f?)?\\s*\\]" options:0 error:NULL] retain]; - _rgbaNSColorRegex = [[NSRegularExpression regularExpressionWithPattern:@"\\[\\s*NSColor\\s+colorWith(Calibrated|Device)Red:\\s*([0-9]*\\.?[0-9]*f?)\\s*(\\/\\s*[0-9]*\\.?[0-9]*f?)?\\s+green:\\s*([0-9]*\\.?[0-9]*f?)\\s*(\\/\\s*[0-9]*\\.?[0-9]*f?)?\\s+blue:\\s*([0-9]*\\.?[0-9]*f?)\\s*(\\/\\s*[0-9]*\\.?[0-9]*f?)?\\s+alpha:\\s*([0-9]*\\.?[0-9]*f?)\\s*(\\/\\s*[0-9]*\\.?[0-9]*f?)?\\s*\\]" options:0 error:NULL] retain]; - _whiteNSColorRegex = [[NSRegularExpression regularExpressionWithPattern:@"\\[\\s*NSColor\\s+colorWith(Calibrated|Device)White:\\s*([0-9]*\\.?[0-9]*f?)\\s*(\\/\\s*[0-9]*\\.?[0-9]*f?)?\\s+alpha:\\s*([0-9]*\\.?[0-9]*f?)\\s*(\\/\\s*[0-9]*\\.?[0-9]*f?)?\\s*\\]" options:0 error:NULL] retain]; - _constantColorRegex = [[NSRegularExpression regularExpressionWithPattern:@"\\[\\s*(UI|NS)Color\\s+(black|darkGray|lightGray|white|gray|red|green|blue|cyan|yellow|magenta|orange|purple|brown|clear)Color\\s*\\]" options:0 error:NULL] retain]; - } - return self; -} - -- (void)applicationDidFinishLaunching:(NSNotification *)notification -{ - NSMenuItem *editMenuItem = [[NSApp mainMenu] itemWithTitle:@"Edit"]; - if (editMenuItem) { - [[editMenuItem submenu] addItem:[NSMenuItem separatorItem]]; - - NSMenuItem *toggleColorHighlightingMenuItem = [[[NSMenuItem alloc] initWithTitle:@"Show Colors Under Caret" action:@selector(toggleColorHighlightingEnabled:) keyEquivalent:@""] autorelease]; - [toggleColorHighlightingMenuItem setTarget:self]; - [[editMenuItem submenu] addItem:toggleColorHighlightingMenuItem]; - - NSMenuItem *colorInsertionModeItem = [[[NSMenuItem alloc] initWithTitle:@"Color Insertion Mode" action:nil keyEquivalent:@""] autorelease]; - NSMenuItem *colorInsertionModeNSItem = [[[NSMenuItem alloc] initWithTitle:@"NSColor" action:@selector(selectNSColorInsertionMode:) keyEquivalent:@""] autorelease]; - [colorInsertionModeNSItem setTarget:self]; - NSMenuItem *colorInsertionModeUIItem = [[[NSMenuItem alloc] initWithTitle:@"UIColor" action:@selector(selectUIColorInsertionMode:) keyEquivalent:@""] autorelease]; - [colorInsertionModeUIItem setTarget:self]; - - NSMenu *colorInsertionModeMenu = [[[NSMenu alloc] initWithTitle:@"Color Insertion Mode"] autorelease]; - [colorInsertionModeItem setSubmenu:colorInsertionModeMenu]; - [[colorInsertionModeItem submenu] addItem:colorInsertionModeUIItem]; - [[colorInsertionModeItem submenu] addItem:colorInsertionModeNSItem]; - [[editMenuItem submenu] addItem:colorInsertionModeItem]; - - NSMenuItem *insertColorMenuItem = [[[NSMenuItem alloc] initWithTitle:@"Insert Color..." action:@selector(insertColor:) keyEquivalent:@""] autorelease]; - [insertColorMenuItem setTarget:self]; - [[editMenuItem submenu] addItem:insertColorMenuItem]; - } - - BOOL highlightingEnabled = ![[NSUserDefaults standardUserDefaults] boolForKey:kOMColorHelperHighlightingDisabled]; - if (highlightingEnabled) { - [self activateColorHighlighting]; - } -} - -#pragma mark - Preferences - -- (BOOL)validateMenuItem:(NSMenuItem *)menuItem -{ - if ([menuItem action] == @selector(insertColor:)) { - NSResponder *firstResponder = [[NSApp keyWindow] firstResponder]; - return ([firstResponder isKindOfClass:NSClassFromString(@"DVTSourceTextView")] && [firstResponder isKindOfClass:[NSTextView class]]); - } else if ([menuItem action] == @selector(toggleColorHighlightingEnabled:)) { - BOOL enabled = [[NSUserDefaults standardUserDefaults] boolForKey:kOMColorHelperHighlightingDisabled]; - [menuItem setState:enabled ? NSOffState : NSOnState]; - return YES; - } else if ([menuItem action] == @selector(selectNSColorInsertionMode:)) { - [menuItem setState:[[NSUserDefaults standardUserDefaults] integerForKey:kOMColorHelperInsertionMode] == 1 ? NSOnState : NSOffState]; - } else if ([menuItem action] == @selector(selectUIColorInsertionMode:)) { - [menuItem setState:[[NSUserDefaults standardUserDefaults] integerForKey:kOMColorHelperInsertionMode] == 0 ? NSOnState : NSOffState]; - } - return YES; -} - -- (void)selectNSColorInsertionMode:(id)sender -{ - [[NSUserDefaults standardUserDefaults] setInteger:1 forKey:kOMColorHelperInsertionMode]; -} - -- (void)selectUIColorInsertionMode:(id)sender -{ - [[NSUserDefaults standardUserDefaults] setInteger:0 forKey:kOMColorHelperInsertionMode]; -} - -- (void)toggleColorHighlightingEnabled:(id)sender -{ - BOOL enabled = [[NSUserDefaults standardUserDefaults] boolForKey:kOMColorHelperHighlightingDisabled]; - [[NSUserDefaults standardUserDefaults] setBool:!enabled forKey:kOMColorHelperHighlightingDisabled]; - if (enabled) { - [self activateColorHighlighting]; - } else { - [self deactivateColorHighlighting]; - } -} - -- (void)activateColorHighlighting -{ - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(selectionDidChange:) name:NSTextViewDidChangeSelectionNotification object:nil]; - if (!self.textView) { - NSResponder *firstResponder = [[NSApp keyWindow] firstResponder]; - if ([firstResponder isKindOfClass:NSClassFromString(@"DVTSourceTextView")] && [firstResponder isKindOfClass:[NSTextView class]]) { - self.textView = (NSTextView *)firstResponder; - } - } - if (self.textView) { - NSNotification *notification = [NSNotification notificationWithName:NSTextViewDidChangeSelectionNotification object:self.textView]; - [self selectionDidChange:notification]; - - } -} - -- (void)deactivateColorHighlighting -{ - [[NSNotificationCenter defaultCenter] removeObserver:self name:NSTextViewDidChangeSelectionNotification object:nil]; - [self dismissColorWell]; - //self.textView = nil; -} - -#pragma mark - Color Insertion - -- (void)insertColor:(id)sender -{ - if (!self.textView) { - NSResponder *firstResponder = [[NSApp keyWindow] firstResponder]; - if ([firstResponder isKindOfClass:NSClassFromString(@"DVTSourceTextView")] && [firstResponder isKindOfClass:[NSTextView class]]) { - self.textView = (NSTextView *)firstResponder; - } else { - NSBeep(); - return; - } - } - if ([[NSUserDefaults standardUserDefaults] boolForKey:kOMColorHelperHighlightingDisabled]) { - //Inserting a color implicitly activates color highlighting: - [[NSUserDefaults standardUserDefaults] setBool:NO forKey:kOMColorHelperHighlightingDisabled]; - [self activateColorHighlighting]; - } - [self.textView.undoManager beginUndoGrouping]; - NSInteger insertionMode = [[NSUserDefaults standardUserDefaults] integerForKey:kOMColorHelperInsertionMode]; - if (insertionMode == 0) { - [self.textView insertText:@"[UIColor colorWithRed:1.0 green:0.0 blue:0.0 alpha:1.0]" replacementRange:self.textView.selectedRange]; - } else { - [self.textView insertText:@"[NSColor colorWithCalibratedRed:1.0 green:0.0 blue:0.0 alpha:1.0]" replacementRange:self.textView.selectedRange]; - } - [self.textView.undoManager endUndoGrouping]; - [self performSelector:@selector(activateColorWell) withObject:nil afterDelay:0.0]; -} - -- (void)activateColorWell -{ - [self.colorWell activate:YES]; -} - -#pragma mark - Text Selection Handling - -- (void)selectionDidChange:(NSNotification *)notification -{ - if ([[notification object] isKindOfClass:NSClassFromString(@"DVTSourceTextView")] && [[notification object] isKindOfClass:[NSTextView class]]) { - self.textView = (NSTextView *)[notification object]; - - BOOL disabled = [[NSUserDefaults standardUserDefaults] boolForKey:kOMColorHelperHighlightingDisabled]; - if (disabled) return; - - NSArray *selectedRanges = [self.textView selectedRanges]; - if (selectedRanges.count >= 1) { - NSRange selectedRange = [[selectedRanges objectAtIndex:0] rangeValue]; - NSString *text = self.textView.textStorage.string; - NSRange lineRange = [text lineRangeForRange:selectedRange]; - NSRange selectedRangeInLine = NSMakeRange(selectedRange.location - lineRange.location, selectedRange.length); - NSString *line = [text substringWithRange:lineRange]; - - NSRange colorRange = NSMakeRange(NSNotFound, 0); - OMColorType colorType = OMColorTypeNone; - NSColor *matchedColor = [self colorInText:line selectedRange:selectedRangeInLine type:&colorType matchedRange:&colorRange]; - - if (matchedColor) { - NSColor *backgroundColor = [self.textView.backgroundColor colorUsingColorSpace:[NSColorSpace genericRGBColorSpace]]; - CGFloat r = 1.0; CGFloat g = 1.0; CGFloat b = 1.0; - [backgroundColor getRed:&r green:&g blue:&b alpha:NULL]; - CGFloat backgroundLuminance = (r + g + b) / 3.0; - - NSColor *strokeColor = (backgroundLuminance > 0.5) ? [NSColor colorWithCalibratedWhite:0.2 alpha:1.0] : [NSColor whiteColor]; - - self.selectedColorType = colorType; - self.colorWell.color = matchedColor; - self.colorWell.strokeColor = strokeColor; - - self.selectedColorRange = NSMakeRange(colorRange.location + lineRange.location, colorRange.length); - NSRect selectionRectOnScreen = [self.textView firstRectForCharacterRange:self.selectedColorRange]; - NSRect selectionRectInWindow = [self.textView.window convertRectFromScreen:selectionRectOnScreen]; - NSRect selectionRectInView = [self.textView convertRect:selectionRectInWindow fromView:nil]; - NSRect colorWellRect = NSMakeRect(NSMaxX(selectionRectInView) - 49, NSMinY(selectionRectInView) - selectionRectInView.size.height - 2, 50, selectionRectInView.size.height + 2); - self.colorWell.frame = NSIntegralRect(colorWellRect); - [self.textView addSubview:self.colorWell]; - self.colorFrameView.frame = NSInsetRect(NSIntegralRect(selectionRectInView), -1, -1); - - self.colorFrameView.color = strokeColor; - - [self.textView addSubview:self.colorFrameView]; - } else { - [self dismissColorWell]; - } - } else { - [self dismissColorWell]; - } - } -} - -- (void)dismissColorWell -{ - if (self.colorWell.isActive) { - [self.colorWell deactivate]; - [[NSColorPanel sharedColorPanel] orderOut:nil]; - } - [self.colorWell removeFromSuperview]; - [self.colorFrameView removeFromSuperview]; - self.selectedColorRange = NSMakeRange(NSNotFound, 0); - self.selectedColorType = OMColorTypeNone; -} - -- (void)colorDidChange:(id)sender -{ - if (self.selectedColorRange.location == NSNotFound) { - return; - } - NSString *colorString = [self colorStringForColor:self.colorWell.color withType:self.selectedColorType]; - if (colorString) { - [self.textView.undoManager beginUndoGrouping]; - [self.textView insertText:colorString replacementRange:self.selectedColorRange]; - [self.textView.undoManager endUndoGrouping]; - } -} - -#pragma mark - View Initialization - -- (OMPlainColorWell *)colorWell -{ - if (!_colorWell) { - _colorWell = [[OMPlainColorWell alloc] initWithFrame:NSMakeRect(0, 0, 50, 30)]; - [_colorWell setTarget:self]; - [_colorWell setAction:@selector(colorDidChange:)]; - } - return _colorWell; -} - -- (OMColorFrameView *)colorFrameView -{ - if (!_colorFrameView) { - _colorFrameView = [[OMColorFrameView alloc] initWithFrame:NSZeroRect]; - } - return _colorFrameView; -} - -#pragma mark - Color String Parsing - -- (NSColor *)colorInText:(NSString *)text selectedRange:(NSRange)selectedRange type:(OMColorType *)type matchedRange:(NSRangePointer)matchedRange -{ - __block NSColor *foundColor = nil; - __block NSRange foundColorRange = NSMakeRange(NSNotFound, 0); - __block OMColorType foundColorType = OMColorTypeNone; - - [_rgbaUIColorRegex enumerateMatchesInString:text options:0 range:NSMakeRange(0, text.length) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) { - NSRange colorRange = [result range]; - if (selectedRange.location >= colorRange.location && NSMaxRange(selectedRange) <= NSMaxRange(colorRange)) { - NSString *typeIndicator = [text substringWithRange:[result rangeAtIndex:1]]; - if ([typeIndicator rangeOfString:@"init"].location != NSNotFound) { - foundColorType = OMColorTypeUIRGBAInit; - } else { - foundColorType = OMColorTypeUIRGBA; - } - - // [UIColor colorWithRed:128 / 255.0 green:10 / 255 blue:123/255 alpha:128 /255] - - double red = [[text substringWithRange:[result rangeAtIndex:2]] doubleValue]; - red = [self dividedValue:red withDivisorRange:[result rangeAtIndex:3] inString:text]; - - double green = [[text substringWithRange:[result rangeAtIndex:4]] doubleValue]; - green = [self dividedValue:green withDivisorRange:[result rangeAtIndex:5] inString:text]; - - double blue = [[text substringWithRange:[result rangeAtIndex:6]] doubleValue]; - blue = [self dividedValue:blue withDivisorRange:[result rangeAtIndex:7] inString:text]; - - double alpha = [[text substringWithRange:[result rangeAtIndex:8]] doubleValue]; - alpha = [self dividedValue:alpha withDivisorRange:[result rangeAtIndex:9] inString:text]; - - foundColor = [NSColor colorWithCalibratedRed:red green:green blue:blue alpha:alpha]; - foundColorRange = colorRange; - *stop = YES; - } - }]; - - if (!foundColor) { - [_whiteUIColorRegex enumerateMatchesInString:text options:0 range:NSMakeRange(0, text.length) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) { - NSRange colorRange = [result range]; - if (selectedRange.location >= colorRange.location && NSMaxRange(selectedRange) <= NSMaxRange(colorRange)) { - NSString *typeIndicator = [text substringWithRange:[result rangeAtIndex:1]]; - if ([typeIndicator rangeOfString:@"init"].location != NSNotFound) { - foundColorType = OMColorTypeUIWhiteInit; - } else { - foundColorType = OMColorTypeUIWhite; - } - double white = [[text substringWithRange:[result rangeAtIndex:2]] doubleValue]; - white = [self dividedValue:white withDivisorRange:[result rangeAtIndex:3] inString:text]; - - double alpha = [[text substringWithRange:[result rangeAtIndex:4]] doubleValue]; - alpha = [self dividedValue:alpha withDivisorRange:[result rangeAtIndex:5] inString:text]; - - foundColor = [NSColor colorWithCalibratedWhite:white alpha:alpha]; - foundColorRange = colorRange; - *stop = YES; - } - }]; - } - - if (!foundColor) { - [_constantColorRegex enumerateMatchesInString:text options:0 range:NSMakeRange(0, text.length) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) { - NSRange colorRange = [result range]; - if (selectedRange.location >= colorRange.location && NSMaxRange(selectedRange) <= NSMaxRange(colorRange)) { - NSString *NS_UI = [text substringWithRange:[result rangeAtIndex:1]]; - NSString *colorName = [text substringWithRange:[result rangeAtIndex:2]]; - foundColor = [_constantColorsByName objectForKey:colorName]; - foundColorRange = colorRange; - if ([NS_UI isEqualToString:@"UI"]) { - foundColorType = OMColorTypeUIConstant; - } else { - foundColorType = OMColorTypeNSConstant; - } - *stop = YES; - } - }]; - } - - if (!foundColor) { - [_rgbaNSColorRegex enumerateMatchesInString:text options:0 range:NSMakeRange(0, text.length) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) { - NSRange colorRange = [result range]; - if (selectedRange.location >= colorRange.location && NSMaxRange(selectedRange) <= NSMaxRange(colorRange)) { - NSString *deviceOrCalibrated = [text substringWithRange:[result rangeAtIndex:1]]; - if ([deviceOrCalibrated isEqualToString:@"Device"]) { - foundColorType = OMColorTypeNSRGBADevice; - } else { - foundColorType = OMColorTypeNSRGBACalibrated; - } - double red = [[text substringWithRange:[result rangeAtIndex:2]] doubleValue]; - red = [self dividedValue:red withDivisorRange:[result rangeAtIndex:3] inString:text]; - - double green = [[text substringWithRange:[result rangeAtIndex:4]] doubleValue]; - green = [self dividedValue:green withDivisorRange:[result rangeAtIndex:5] inString:text]; - - double blue = [[text substringWithRange:[result rangeAtIndex:6]] doubleValue]; - blue = [self dividedValue:blue withDivisorRange:[result rangeAtIndex:7] inString:text]; - - double alpha = [[text substringWithRange:[result rangeAtIndex:8]] doubleValue]; - alpha = [self dividedValue:alpha withDivisorRange:[result rangeAtIndex:9] inString:text]; - - if (foundColorType == OMColorTypeNSRGBACalibrated) { - foundColor = [NSColor colorWithCalibratedRed:red green:green blue:blue alpha:alpha]; - } else { - foundColor = [NSColor colorWithDeviceRed:red green:green blue:blue alpha:alpha]; - } - foundColorRange = colorRange; - *stop = YES; - } - }]; - } - - if (!foundColor) { - [_whiteNSColorRegex enumerateMatchesInString:text options:0 range:NSMakeRange(0, text.length) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) { - NSRange colorRange = [result range]; - if (selectedRange.location >= colorRange.location && NSMaxRange(selectedRange) <= NSMaxRange(colorRange)) { - NSString *deviceOrCalibrated = [text substringWithRange:[result rangeAtIndex:1]]; - double white = [[text substringWithRange:[result rangeAtIndex:2]] doubleValue]; - white = [self dividedValue:white withDivisorRange:[result rangeAtIndex:3] inString:text]; - - double alpha = [[text substringWithRange:[result rangeAtIndex:4]] doubleValue]; - alpha = [self dividedValue:alpha withDivisorRange:[result rangeAtIndex:5] inString:text]; - - if ([deviceOrCalibrated isEqualToString:@"Device"]) { - foundColor = [NSColor colorWithDeviceWhite:white alpha:alpha]; - foundColorType = OMColorTypeNSWhiteDevice; - } else { - foundColor = [NSColor colorWithCalibratedWhite:white alpha:alpha]; - foundColorType = OMColorTypeNSWhiteCalibrated; - } - foundColorRange = colorRange; - *stop = YES; - } - }]; - } - - if (foundColor) { - if (matchedRange != NULL) { - *matchedRange = foundColorRange; - } - if (type != NULL) { - *type = foundColorType; - } - return foundColor; - } - - return nil; -} - -- (double)dividedValue:(double)value withDivisorRange:(NSRange)divisorRange inString:(NSString *)text -{ - if (divisorRange.location != NSNotFound) { - double divisor = [[[text substringWithRange:divisorRange] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"/ "]] doubleValue]; - if (divisor != 0) { - value /= divisor; - } - } - return value; -} - -- (NSString *)colorStringForColor:(NSColor *)color withType:(OMColorType)colorType -{ - NSString *colorString = nil; - CGFloat red = -1.0; CGFloat green = -1.0; CGFloat blue = -1.0; CGFloat alpha = -1.0; - color = [color colorUsingColorSpace:[NSColorSpace genericRGBColorSpace]]; - [color getRed:&red green:&green blue:&blue alpha:&alpha]; - - if (red >= 0) { - for (NSString *colorName in _constantColorsByName) { - NSColor *constantColor = [_constantColorsByName objectForKey:colorName]; - if ([constantColor isEqual:color]) { - if (OMColorTypeIsNSColor(colorType)) { - colorString = [NSString stringWithFormat:@"[NSColor %@Color]", colorName]; - } else { - colorString = [NSString stringWithFormat:@"[UIColor %@Color]", colorName]; - } - break; - } - } - if (!colorString) { - if (fabs(red - green) < 0.001 && fabs(green - blue) < 0.001) { - if (colorType == OMColorTypeUIRGBA || colorType == OMColorTypeUIWhite || colorType == OMColorTypeUIConstant) { - colorString = [NSString stringWithFormat:@"[UIColor colorWithWhite:%.3f alpha:%.3f]", red, alpha]; - } else if (colorType == OMColorTypeUIRGBAInit || colorType == OMColorTypeUIWhiteInit) { - colorString = [NSString stringWithFormat:@"[[UIColor alloc] initWithWhite:%.3f alpha:%.3f]", red, alpha]; - } - else if (colorType == OMColorTypeNSConstant || colorType == OMColorTypeNSRGBACalibrated || colorType == OMColorTypeNSWhiteCalibrated) { - colorString = [NSString stringWithFormat:@"[NSColor colorWithCalibratedWhite:%.3f alpha:%.3f]", red, alpha]; - } else if (colorType == OMColorTypeNSRGBADevice || colorType == OMColorTypeNSWhiteDevice) { - colorString = [NSString stringWithFormat:@"[NSColor colorWithDeviceWhite:%.3f alpha:%.3f]", red, alpha]; - } - } else { - if (colorType == OMColorTypeUIRGBA || colorType == OMColorTypeUIWhite || colorType == OMColorTypeUIConstant) { - colorString = [NSString stringWithFormat:@"[UIColor colorWithRed:%.3f green:%.3f blue:%.3f alpha:%.3f]", red, green, blue, alpha]; - } else if (colorType == OMColorTypeUIRGBAInit || colorType == OMColorTypeUIWhiteInit) { - colorString = [NSString stringWithFormat:@"[[UIColor alloc] initWithRed:%.3f green:%.3f blue:%.3f alpha:%.3f]", red, green, blue, alpha]; - } - else if (colorType == OMColorTypeNSConstant || colorType == OMColorTypeNSRGBACalibrated || colorType == OMColorTypeNSWhiteCalibrated) { - colorString = [NSString stringWithFormat:@"[NSColor colorWithCalibratedRed:%.3f green:%.3f blue:%.3f alpha:%.3f]", red, green, blue, alpha]; - } else if (colorType == OMColorTypeNSRGBADevice || colorType == OMColorTypeNSWhiteDevice) { - colorString = [NSString stringWithFormat:@"[NSColor colorWithDeviceRed:%.3f green:%.3f blue:%.3f alpha:%.3f]", red, green, blue, alpha]; - } - } - } - } - return colorString; -} - -#pragma mark - - -- (void)dealloc -{ - [[NSNotificationCenter defaultCenter] removeObserver:self]; - [_colorWell release]; - [_colorFrameView release]; - [_textView release]; - [_constantColorsByName release]; - [_rgbaUIColorRegex release]; - [_whiteUIColorRegex release]; - [_constantColorsByName release]; - [_whiteNSColorRegex release]; - [_rgbaNSColorRegex release]; - [super dealloc]; -} - -@end diff --git a/Classes/OMPlainColorWell.h b/Classes/OMPlainColorWell.h deleted file mode 100644 index 888177a..0000000 --- a/Classes/OMPlainColorWell.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// OMPlainColorWell.h -// OMColorHelper -// -// Created by Ole Zorn on 09/07/12. -// -// - -#import - -@interface OMPlainColorWell : NSColorWell { - - NSColor *_strokeColor; -} - -@property (nonatomic, retain) NSColor *strokeColor; - -@end diff --git a/Classes/OMPlainColorWell.m b/Classes/OMPlainColorWell.m deleted file mode 100644 index 765b9f2..0000000 --- a/Classes/OMPlainColorWell.m +++ /dev/null @@ -1,51 +0,0 @@ -// -// OMPlainColorWell.m -// OMColorHelper -// -// Created by Ole Zorn on 09/07/12. -// -// - -#import "OMPlainColorWell.h" - -@implementation OMPlainColorWell - -@synthesize strokeColor=_strokeColor; - -- (void)drawRect:(NSRect)dirtyRect -{ - [NSGraphicsContext saveGraphicsState]; - NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:NSMakeRect(0, -5, self.bounds.size.width, self.bounds.size.height + 5) xRadius:5.0 yRadius:5.0]; - [path addClip]; - [self drawWellInside:self.bounds]; - [NSGraphicsContext restoreGraphicsState]; - - if (self.strokeColor) { - NSBezierPath *strokePath = [NSBezierPath bezierPathWithRoundedRect:NSInsetRect(NSMakeRect(0, -5, self.bounds.size.width, self.bounds.size.height + 5), 0.5, 0.5) xRadius:5.0 yRadius:5.0]; - [self.strokeColor setStroke]; - [strokePath stroke]; - } -} - -- (void)deactivate -{ - [super deactivate]; - [[NSColorPanel sharedColorPanel] orderOut:nil]; -} - -- (void)setStrokeColor:(NSColor *)strokeColor -{ - if (strokeColor != _strokeColor) { - [_strokeColor release]; - _strokeColor = [strokeColor retain]; - [self setNeedsDisplay:YES]; - } -} - -- (void)dealloc -{ - [_strokeColor release]; - [super dealloc]; -} - -@end diff --git a/OMColorSense.xcodeproj/project.pbxproj b/HOStringSense.xcodeproj/project.pbxproj similarity index 55% rename from OMColorSense.xcodeproj/project.pbxproj rename to HOStringSense.xcodeproj/project.pbxproj index 2843686..ec22071 100755 --- a/OMColorSense.xcodeproj/project.pbxproj +++ b/HOStringSense.xcodeproj/project.pbxproj @@ -7,24 +7,40 @@ objects = { /* Begin PBXBuildFile section */ + 43BA8625167490550002C238 /* HOPopoverViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 43BA8624167490550002C238 /* HOPopoverViewController.m */; }; 7F2EB89C145057F200E97A87 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F2EB899145057EA00E97A87 /* AppKit.framework */; }; - 7F6EE2BF15FA6F3B00BA114A /* OMColorFrameView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F6EE2BE15FA6F3B00BA114A /* OMColorFrameView.m */; }; - 7FDADE3A15FA6CA400A847E3 /* OMPlainColorWell.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FDADE3915FA6CA400A847E3 /* OMPlainColorWell.m */; }; + 7F6EE2BF15FA6F3B00BA114A /* HOStringFrameView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F6EE2BE15FA6F3B00BA114A /* HOStringFrameView.m */; }; + 7FDADE3A15FA6CA400A847E3 /* HOStringInfoButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FDADE3915FA6CA400A847E3 /* HOStringInfoButton.m */; }; DA1B5D020E64686800921439 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 089C1672FE841209C02AAC07 /* Foundation.framework */; }; - DA37E2DC0E6291C8001BDFEF /* OMColorHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = DA37E2DB0E6291C8001BDFEF /* OMColorHelper.m */; }; + DA37E2DC0E6291C8001BDFEF /* HOStringHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = DA37E2DB0E6291C8001BDFEF /* HOStringHelper.m */; }; /* End PBXBuildFile section */ +/* Begin PBXBuildRule section */ + 4302EDD316748CAD001E6539 /* PBXBuildRule */ = { + isa = PBXBuildRule; + compilerSpec = com.apple.compilers.proxy.script; + fileType = file.xib; + isEditable = 1; + outputFiles = ( + ); + script = "# ibtool\n"; + }; +/* End PBXBuildRule section */ + /* Begin PBXFileReference section */ 089C1672FE841209C02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; - 7F2B355F15FA59D000DB3249 /* OMColorHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OMColorHelper.h; sourceTree = ""; }; + 43BA8623167490550002C238 /* HOPopoverViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HOPopoverViewController.h; sourceTree = ""; }; + 43BA8624167490550002C238 /* HOPopoverViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HOPopoverViewController.m; sourceTree = ""; }; + 43ED5411167509CC00AE1269 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = text; path = README.md; sourceTree = ""; }; + 7F2B355F15FA59D000DB3249 /* HOStringHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HOStringHelper.h; sourceTree = ""; }; 7F2EB899145057EA00E97A87 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; - 7F6EE2BD15FA6F3B00BA114A /* OMColorFrameView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OMColorFrameView.h; sourceTree = ""; }; - 7F6EE2BE15FA6F3B00BA114A /* OMColorFrameView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OMColorFrameView.m; sourceTree = ""; }; - 7FDADE3815FA6CA400A847E3 /* OMPlainColorWell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OMPlainColorWell.h; sourceTree = ""; }; - 7FDADE3915FA6CA400A847E3 /* OMPlainColorWell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OMPlainColorWell.m; sourceTree = ""; }; - 8D5B49B6048680CD000E48DA /* OMColorSense.xcplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OMColorSense.xcplugin; sourceTree = BUILT_PRODUCTS_DIR; }; + 7F6EE2BD15FA6F3B00BA114A /* HOStringFrameView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HOStringFrameView.h; sourceTree = ""; }; + 7F6EE2BE15FA6F3B00BA114A /* HOStringFrameView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HOStringFrameView.m; sourceTree = ""; }; + 7FDADE3815FA6CA400A847E3 /* HOStringInfoButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HOStringInfoButton.h; sourceTree = ""; }; + 7FDADE3915FA6CA400A847E3 /* HOStringInfoButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HOStringInfoButton.m; sourceTree = ""; }; + 8D5B49B6048680CD000E48DA /* HOStringSense.xcplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HOStringSense.xcplugin; sourceTree = BUILT_PRODUCTS_DIR; }; 8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - DA37E2DB0E6291C8001BDFEF /* OMColorHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OMColorHelper.m; sourceTree = ""; }; + DA37E2DB0E6291C8001BDFEF /* HOStringHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HOStringHelper.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -43,11 +59,13 @@ 089C166AFE841209C02AAC07 /* QuietXcode */ = { isa = PBXGroup; children = ( + 43ED5411167509CC00AE1269 /* README.md */, 7F411B0C15FABAC6002F77B6 /* Classes */, 089C167CFE841241C02AAC07 /* Resources */, 089C1671FE841209C02AAC07 /* Frameworks and Libraries */, 19C28FB8FE9D52D311CA2CBB /* Products */, ); + indentWidth = 4; name = QuietXcode; sourceTree = ""; }; @@ -71,7 +89,7 @@ 19C28FB8FE9D52D311CA2CBB /* Products */ = { isa = PBXGroup; children = ( - 8D5B49B6048680CD000E48DA /* OMColorSense.xcplugin */, + 8D5B49B6048680CD000E48DA /* HOStringSense.xcplugin */, ); name = Products; sourceTree = ""; @@ -79,12 +97,14 @@ 7F411B0C15FABAC6002F77B6 /* Classes */ = { isa = PBXGroup; children = ( - 7F2B355F15FA59D000DB3249 /* OMColorHelper.h */, - DA37E2DB0E6291C8001BDFEF /* OMColorHelper.m */, - 7F6EE2BD15FA6F3B00BA114A /* OMColorFrameView.h */, - 7F6EE2BE15FA6F3B00BA114A /* OMColorFrameView.m */, - 7FDADE3815FA6CA400A847E3 /* OMPlainColorWell.h */, - 7FDADE3915FA6CA400A847E3 /* OMPlainColorWell.m */, + 7F2B355F15FA59D000DB3249 /* HOStringHelper.h */, + DA37E2DB0E6291C8001BDFEF /* HOStringHelper.m */, + 7F6EE2BD15FA6F3B00BA114A /* HOStringFrameView.h */, + 7F6EE2BE15FA6F3B00BA114A /* HOStringFrameView.m */, + 7FDADE3815FA6CA400A847E3 /* HOStringInfoButton.h */, + 7FDADE3915FA6CA400A847E3 /* HOStringInfoButton.m */, + 43BA8623167490550002C238 /* HOPopoverViewController.h */, + 43BA8624167490550002C238 /* HOPopoverViewController.m */, ); path = Classes; sourceTree = ""; @@ -92,21 +112,23 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 8D5B49AC048680CD000E48DA /* OMColorSense */ = { + 8D5B49AC048680CD000E48DA /* HOStringSense */ = { isa = PBXNativeTarget; - buildConfigurationList = 1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "OMColorSense" */; + buildConfigurationList = 1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "HOStringSense" */; buildPhases = ( 8D5B49B1048680CD000E48DA /* Sources */, + 4302EDD516748D08001E6539 /* Resources */, 8D5B49B3048680CD000E48DA /* Frameworks */, ); buildRules = ( + 4302EDD316748CAD001E6539 /* PBXBuildRule */, ); dependencies = ( ); - name = OMColorSense; + name = HOStringSense; productInstallPath = "$(HOME)/Library/Bundles"; productName = QuietXcode; - productReference = 8D5B49B6048680CD000E48DA /* OMColorSense.xcplugin */; + productReference = 8D5B49B6048680CD000E48DA /* HOStringSense.xcplugin */; productType = "com.apple.product-type.bundle"; }; /* End PBXNativeTarget section */ @@ -115,9 +137,10 @@ 089C1669FE841209C02AAC07 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0440; + LastTestingUpgradeCheck = 0710; + LastUpgradeCheck = 0730; }; - buildConfigurationList = 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "OMColorSense" */; + buildConfigurationList = 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "HOStringSense" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 1; @@ -126,24 +149,36 @@ Japanese, French, German, + en, ); mainGroup = 089C166AFE841209C02AAC07 /* QuietXcode */; projectDirPath = ""; projectRoot = ""; targets = ( - 8D5B49AC048680CD000E48DA /* OMColorSense */, + 8D5B49AC048680CD000E48DA /* HOStringSense */, ); }; /* End PBXProject section */ +/* Begin PBXResourcesBuildPhase section */ + 4302EDD516748D08001E6539 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ 8D5B49B1048680CD000E48DA /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DA37E2DC0E6291C8001BDFEF /* OMColorHelper.m in Sources */, - 7FDADE3A15FA6CA400A847E3 /* OMPlainColorWell.m in Sources */, - 7F6EE2BF15FA6F3B00BA114A /* OMColorFrameView.m in Sources */, + DA37E2DC0E6291C8001BDFEF /* HOStringHelper.m in Sources */, + 7FDADE3A15FA6CA400A847E3 /* HOStringInfoButton.m in Sources */, + 7F6EE2BF15FA6F3B00BA114A /* HOStringFrameView.m in Sources */, + 43BA8625167490550002C238 /* HOPopoverViewController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -154,19 +189,20 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ENABLE_OBJC_ARC = YES; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; DEPLOYMENT_LOCATION = YES; DEPLOYMENT_POSTPROCESSING = YES; DSTROOT = "$(HOME)"; GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_OBJC_GC = supported; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "/Library/Application Support/Developer/Shared/Xcode/Plug-ins"; LD_RUNPATH_SEARCH_PATHS = /Developer; - PRODUCT_NAME = OMColorSense; + PRODUCT_BUNDLE_IDENTIFIER = "it.holtwick.${PRODUCT_NAME:identifier}"; + PRODUCT_NAME = HOStringSense; STRIP_INSTALLED_PRODUCT = NO; WRAPPER_EXTENSION = xcplugin; }; @@ -175,14 +211,15 @@ 1DEB913F08733D840010E9CD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; CURRENT_PROJECT_VERSION = 1.0.1; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = c99; GCC_OPTIMIZATION_LEVEL = 0; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; INSTALL_PATH = "$(HOME)/Library/Application Support/Developer/Shared/Xcode/Plug-ins"; MACOSX_DEPLOYMENT_TARGET = 10.7; + ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; }; name = Debug; @@ -190,7 +227,7 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "OMColorSense" */ = { + 1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "HOStringSense" */ = { isa = XCConfigurationList; buildConfigurations = ( 1DEB913B08733D840010E9CD /* Debug */, @@ -198,7 +235,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; - 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "OMColorSense" */ = { + 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "HOStringSense" */ = { isa = XCConfigurationList; buildConfigurations = ( 1DEB913F08733D840010E9CD /* Debug */, diff --git a/HOStringSense.xcodeproj/project.xcworkspace/xcshareddata/HOStringSense.xccheckout b/HOStringSense.xcodeproj/project.xcworkspace/xcshareddata/HOStringSense.xccheckout new file mode 100644 index 0000000..04fef74 --- /dev/null +++ b/HOStringSense.xcodeproj/project.xcworkspace/xcshareddata/HOStringSense.xccheckout @@ -0,0 +1,41 @@ + + + + + IDESourceControlProjectFavoriteDictionaryKey + + IDESourceControlProjectIdentifier + E822DE2D-8AFB-45D6-B909-ED96F189E2AE + IDESourceControlProjectName + project + IDESourceControlProjectOriginsDictionary + + F05946858516928A212830FAEE4FD23BEA3A31AB + github.com:holtwick/HOStringSense-for-Xcode.git + + IDESourceControlProjectPath + HOStringSense.xcodeproj/project.xcworkspace + IDESourceControlProjectRelativeInstallPathDictionary + + F05946858516928A212830FAEE4FD23BEA3A31AB + ../.. + + IDESourceControlProjectURL + github.com:holtwick/HOStringSense-for-Xcode.git + IDESourceControlProjectVersion + 111 + IDESourceControlProjectWCCIdentifier + F05946858516928A212830FAEE4FD23BEA3A31AB + IDESourceControlProjectWCConfigurations + + + IDESourceControlRepositoryExtensionIdentifierKey + public.vcs.git + IDESourceControlWCCIdentifierKey + F05946858516928A212830FAEE4FD23BEA3A31AB + IDESourceControlWCCName + HOStringSense-for-Xcode + + + + diff --git a/Info.plist b/Info.plist index 1bfa565..dc5d763 100755 --- a/Info.plist +++ b/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - com.omz-software.${PRODUCT_NAME:identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -18,13 +18,32 @@ ${CURRENT_PROJECT_VERSION} CFBundleVersion ${CURRENT_PROJECT_VERSION} + DVTPlugInCompatibilityUUIDs + + ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C + AD68E85B-441B-4301-B564-A45E4919A6AD + A2E4D43F-41F4-4FB9-BB94-7177011C9AED + 640F884E-CE55-4B40-87C0-8869546CAB7A + 63FC1C47-140D-42B0-BB4D-A10B2D225574 + 37B30044-3B14-46BA-ABAA-F01000C27B63 + C4A681B0-4A26-480E-93EC-1218098B9AA0 + A16FF353-8441-459E-A50C-B071F53F51B7 + 9F75337B-21B4-4ADC-B558-F9CADF7073A7 + E969541F-E6F9-4D25-8158-72DC3545A6C6 + AABB7188-E14E-4433-AD3B-5CD791EAD9A3 + 7FDF5C7A-131F-4ABB-9EDC-8C5F8F0B8A90 + 0420B86A-AA43-4792-9ED0-6FE0F2B16A13 + CC0D0F4F-05B3-431A-8F33-F84AFCB2C651 + 7265231C-39B4-402C-89E1-16167C4CC990 + F41BD31E-2683-44B8-AE7F-5F09E919790E + NSPrincipalClass - OMColorHelper + HOStringHelper + XC4Compatible + XCGCReady XCPluginHasUI - XC4Compatible - diff --git a/README.md b/README.md index aabd8c0..9c4b24a 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,36 @@ -# ColorSense for Xcode +# String Editing Plugin for Xcode -## Overview +Perfect for editing regular expressions, multi line texts, inline HTML and many more use cases. Also provides quick feedback on string length. -ColorSense is an Xcode plugin that makes working with `UIColor` (and `NSColor`) more visual. +![Screenshot](https://github.com/holtwick/HOStringSense-for-Xcode/raw/master/StringDemoAnimation.gif "Demo") -There are [many](http://www.colorchooserapp.com) [tools](http://iconfactory.com/software/xscope) that allow you to insert a `UIColor`/`NSColor` from a color picker or by picking a color from the screen. But once you've inserted it, it can be hard to remember which color you're actually looking at in your code because you basically just have a series of numbers. - -This is where ColorSense comes in: When you put the caret on one of your colors, it automatically shows the actual color as an overlay, and you can even adjust it on-the-fly with the standard Mac OS X color picker. +## Installation -The plugin also adds some items to the _Edit_ menu to insert colors and to disable color highlighting temporarily. These menu items have no keyboard shortcuts by default, but you can set them via the system's keyboard preferences (Xcode's own preferences won't show them). +There are two ways: -**[Watch Demo Video (YouTube)](http://www.youtube.com/watch?v=eblRfDQM0Go)** +1. Build the Xcode project and restart Xcode. The plugin will automatically be installed in `~/Library/Application Support/Developer/Shared/Xcode/Plug-ins`. First remove the plugin from there (and restart Xcode). -I'm [@olemoritz](http://twitter.com/olemoritz) on Twitter. + If you get a "Permission Denied" error while building, please see [this issue](https://github.com/omz/ColorSense-for-Xcode/issues/1). - -Flattr this +1. Use [**Alcatraz**, the package manager for Xcode](http://alcatraz.io/) (Attention, you'll need to have MacOS 10.9 installed!) -## Installation +## Keyboard Shortcut -Simply build the Xcode project and restart Xcode. The plugin will automatically be installed in `~/Library/Application Support/Developer/Shared/Xcode/Plug-ins`. To uninstall, just remove the plugin from there (and restart Xcode). +With a little trick you can enable keyboard shortcut for showing the popover. Open `System Preferences` app, then section `Keyboard` and add a custom application shortcut for Xcode as in the following image: -If you get a "Permission Denied" error while building, please see [this issue](https://github.com/omz/ColorSense-for-Xcode/issues/1). +![Screenshot](https://github.com/holtwick/HOStringSense-for-Xcode/raw/master/Shortcut.png "Keyboard Shortcur") -This is tested on OS X 10.8 with Xcode 4.4.1 and 4.5. +## Author -## Limitations +I'm a Mac and iOS developer, follow me on Twitter [@holtwick](https://twitter.com/holtwick) -* It only works for constant colors, something like `[UIColor colorWithWhite:foo * bar + 1 alpha:baz]` won't work. +## Credits -* Only RGB (`colorWithRed:green:blue:alpha:`), grayscale (`colorWithWhite:alpha:`), and named colors (`redColor`...) are supported at the moment (no HSB or CMYK). +This work is derived from the awesome [Color Sense](https://github.com/omz/ColorSense-for-Xcode) plugin of Ole Zorn. Thanks Ole! ## License - Copyright (c) 2012, Ole Zorn + Copyright (c) 2012-2015, Dirk Holtwick All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/Shortcut.png b/Shortcut.png new file mode 100644 index 0000000..1cb5f42 Binary files /dev/null and b/Shortcut.png differ diff --git a/StringDemoAnimation.gif b/StringDemoAnimation.gif new file mode 100644 index 0000000..895343b Binary files /dev/null and b/StringDemoAnimation.gif differ