Revision: 18366
http://bibdesk.svn.sourceforge.net/bibdesk/?rev=18366&view=rev
Author: hofman
Date: 2012-01-05 22:39:00 +0000 (Thu, 05 Jan 2012)
Log Message:
-----------
Show line numbers in rule view subclass in error editor
Modified Paths:
--------------
trunk/bibdesk/BDSKErrorEditor.m
trunk/bibdesk/Bibdesk.xcodeproj/project.pbxproj
Added Paths:
-----------
trunk/bibdesk/BDSKLineNumberView.h
trunk/bibdesk/BDSKLineNumberView.m
Modified: trunk/bibdesk/BDSKErrorEditor.m
===================================================================
--- trunk/bibdesk/BDSKErrorEditor.m 2012-01-05 07:36:04 UTC (rev 18365)
+++ trunk/bibdesk/BDSKErrorEditor.m 2012-01-05 22:39:00 UTC (rev 18366)
@@ -45,6 +45,7 @@
#import "BDSKAppController.h"
#import "BDSKStringEncodingManager.h"
#import "NSWindowController_BDSKExtensions.h"
+#import "BDSKLineNumberView.h"
static char BDSKErrorEditorObservationContext;
@@ -108,8 +109,15 @@
[syntaxHighlightCheckbox setState:NSOnState];
// faster layout if it's not antialiased, and fixed pitch makes
pretty-printed files look right
- [textView setFont:[NSFont userFixedPitchFontOfSize:10.0]];
-
+ [textView setFont:[NSFont userFixedPitchFontOfSize:0.0]];
+
+ NSScrollView *scrollView = [textView enclosingScrollView];
+ BDSKLineNumberView *lineNumberView = [[[BDSKLineNumberView alloc]
initWithScrollView:scrollView orientation:NSVerticalRuler] autorelease];
+ [lineNumberView setClientView:textView];
+ [scrollView setVerticalRulerView:lineNumberView];
+ [scrollView setHasVerticalRuler:YES];
+ [scrollView setRulersVisible:YES];
+
[self loadFile:self];
NSString *prefix = (isPasteDrag) ? NSLocalizedString(@"Paste/Drag Data",
@"Partial window title") : NSLocalizedString(@"Source Data", @"Partial window
title");
Added: trunk/bibdesk/BDSKLineNumberView.h
===================================================================
--- trunk/bibdesk/BDSKLineNumberView.h (rev 0)
+++ trunk/bibdesk/BDSKLineNumberView.h 2012-01-05 22:39:00 UTC (rev 18366)
@@ -0,0 +1,45 @@
+//
+// BDSKLineNumberView.h
+// Bibdesk
+//
+// Created by Christiaan Hofman on 1/5/12.
+/*
+ This software is Copyright (c) 2012
+ Christiaan Hofman. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of Christiaan Hofman nor the names of any
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+
+@interface BDSKLineNumberView : NSRulerView {
+ NSPointerArray *lineCharacterIndexes;
+}
+@end
Added: trunk/bibdesk/BDSKLineNumberView.m
===================================================================
--- trunk/bibdesk/BDSKLineNumberView.m (rev 0)
+++ trunk/bibdesk/BDSKLineNumberView.m 2012-01-05 22:39:00 UTC (rev 18366)
@@ -0,0 +1,186 @@
+//
+// BDSKLineNumberView.m
+// Bibdesk
+//
+// Created by Christiaan Hofman on 1/5/12.
+/*
+ This software is Copyright (c) 2012
+ Christiaan Hofman. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of Christiaan Hofman nor the names of any
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "BDSKLineNumberView.h"
+#import "NSInvocation_BDSKExtensions.h"
+
+#define DEFAULT_THICKNESS 22.0
+#define RULER_MARGIN 4.0
+
+@implementation BDSKLineNumberView
+
+static NSDictionary *lineNumberAttributes = nil;
+
++ (void)initialize {
+ BDSKINITIALIZE;
+ lineNumberAttributes = [[NSDictionary alloc] initWithObjectsAndKeys:
+ [NSFont labelFontOfSize:[NSFont
systemFontSizeForControlSize:NSMiniControlSize]], NSFontAttributeName,
+ [NSColor colorWithCalibratedWhite:0.33 alpha:1.0],
NSForegroundColorAttributeName,
+ nil];
+}
+
+- (void)dealloc {
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+ BDSKDESTROY(lineCharacterIndexes);
+ [super dealloc];
+}
+
+- (void)textDidChange:(NSNotification *)notification {
+ BDSKDESTROY(lineCharacterIndexes);
+ [self setNeedsDisplay:YES];
+}
+
+- (void)viewFrameDidChange:(NSNotification *)notification {
+ [self setNeedsDisplay:YES];
+}
+
+- (void)setClientView:(NSView *)aView {
+ id oldClientView = [self clientView];
+ NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
+
+ if ([oldClientView isKindOfClass:[NSTextView class]]) {
+ [nc removeObserver:self
name:NSTextStorageDidProcessEditingNotification object:[(NSTextView
*)oldClientView textStorage]];
+ [nc removeObserver:self name:NSViewFrameDidChangeNotification
object:oldClientView ];
+ }
+
+ [super setClientView:aView];
+
+ if ([aView isKindOfClass:[NSTextView class]]) {
+ [nc addObserver:self selector:@selector(textDidChange:)
name:NSTextStorageDidProcessEditingNotification object:[(NSTextView *)aView
textStorage]];
+ [nc addObserver:self selector:@selector(viewFrameDidChange:)
name:NSViewFrameDidChangeNotification object:aView];
+ }
+ BDSKDESTROY(lineCharacterIndexes);
+}
+
+static inline CGFloat ruleThicknessForLineCount(NSUInteger count) {
+ NSUInteger i = (NSUInteger)log10(count) + 1;
+ NSMutableString *string = [NSMutableString string];
+ while (i-- > 0) [string appendString:@"0"];
+ return ceilf(fmax(DEFAULT_THICKNESS, [string
sizeWithAttributes:lineNumberAttributes].width + RULER_MARGIN * 2));
+}
+
+static NSPointerArray *createLineCharacterIndexesForString(NSString *string) {
+ NSUInteger idx = 0, stringLength = [string length], lineEnd, contentsEnd;
+ NSPointerArray *lineCharacterIndexes = [[NSPointerArray alloc]
initWithOptions:NSPointerFunctionsOpaqueMemory |
NSPointerFunctionsIntegerPersonality];
+
+ do {
+ [lineCharacterIndexes addPointer:(void *)idx];
+ idx = NSMaxRange([string lineRangeForRange:NSMakeRange(idx, 0)]);
+ } while (idx < stringLength);
+
+ [string getLineStart:NULL end:&lineEnd contentsEnd:&contentsEnd
forRange:NSMakeRange((NSUInteger)[lineCharacterIndexes
pointerAtIndex:[lineCharacterIndexes count] - 1], 0)];
+ if (contentsEnd < lineEnd)
+ [lineCharacterIndexes addPointer:(void *)idx];
+
+ return lineCharacterIndexes;
+}
+
+- (NSPointerArray *)lineCharacterIndexes {
+ if (lineCharacterIndexes == nil) {
+ id view = [self clientView];
+
+ if ([view isKindOfClass:[NSTextView class]]) {
+ lineCharacterIndexes = createLineCharacterIndexesForString([view
string]);
+
+ CGFloat oldThickness = [self ruleThickness];
+ CGFloat newThickness =
ruleThicknessForLineCount([lineCharacterIndexes count]);
+ if (fabs(oldThickness - newThickness) >= 1.0) {
+ NSInvocation *invocation = [NSInvocation
invocationWithTarget:self selector:@selector(setRuleThickness:)];
+ [invocation setArgument:&newThickness atIndex:2];
+ [invocation performSelector:@selector(invoke) withObject:nil
afterDelay:0.0];
+ }
+ }
+ }
+ return lineCharacterIndexes;
+}
+
+- (NSUInteger)lineForCharacterIndex:(NSUInteger)anIndex {
+ NSPointerArray *lines = [self lineCharacterIndexes];
+ NSUInteger left = 0, right = [lines count], mid, lineStart;
+
+ while (right - left > 1) {
+ mid = (right + left) / 2;
+ lineStart = (NSUInteger)[lines pointerAtIndex:mid];
+ if (anIndex < lineStart)
+ right = mid;
+ else if (anIndex > lineStart)
+ left = mid;
+ else
+ return mid;
+ }
+ return left;
+}
+
+- (void)drawHashMarksAndLabelsInRect:(NSRect)aRect {
+ id view = [self clientView];
+ NSRect bounds = NSInsetRect([self bounds], RULER_MARGIN, 0.0);
+
+ if ([view isKindOfClass:[NSTextView class]]) {
+ NSLayoutManager *lm = [view layoutManager];
+ NSTextContainer *container = [view textContainer];
+ NSRect visibleRect = [[[self scrollView] contentView] bounds];
+ NSRange range = [lm characterRangeForGlyphRange:[lm
glyphRangeForBoundingRect:visibleRect inTextContainer:container]
actualGlyphRange:NULL];
+ NSRange nullRange = NSMakeRange(NSNotFound, 0);
+ NSString *label;
+ NSRectArray rects;
+ CGFloat offset = [view textContainerInset].height -
NSMinY(visibleRect);
+ NSSize labelSize;
+ NSPointerArray *lines = [self lineCharacterIndexes];
+ NSUInteger rectCount, i, line, count = [lines count];
+
+ // one extra for any newline at the end, which doesn't have a glyph
+ range.length++;
+
+ for (line = [self lineForCharacterIndex:range.location]; line < count;
line++) {
+ i = (NSUInteger)[lines pointerAtIndex:line];
+
+ if (NSLocationInRange(i, range)) {
+ rects = [lm rectArrayForCharacterRange:NSMakeRange(i, 0)
withinSelectedCharacterRange:nullRange inTextContainer:container
rectCount:&rectCount];
+ if (rectCount > 0) {
+ label = [NSString stringWithFormat:@"%lu", (unsigned
long)(line + 1)];
+ labelSize = [label
sizeWithAttributes:lineNumberAttributes];
+ [label drawInRect:NSMakeRect(NSMaxX(bounds) -
labelSize.width, offset + NSMidY(rects[0]) - 0.5 * labelSize.height,
NSWidth(bounds), NSHeight(rects[0])) withAttributes:lineNumberAttributes];
+ }
+ }
+ if (i > NSMaxRange(range))
+ break;
+ }
+ }
+}
+
+@end
Modified: trunk/bibdesk/Bibdesk.xcodeproj/project.pbxproj
===================================================================
--- trunk/bibdesk/Bibdesk.xcodeproj/project.pbxproj 2012-01-05 07:36:04 UTC
(rev 18365)
+++ trunk/bibdesk/Bibdesk.xcodeproj/project.pbxproj 2012-01-05 22:39:00 UTC
(rev 18366)
@@ -94,6 +94,7 @@
CE11B0060AE8FD53008C47AC /* scriptGroup.tiff in Resources */ =
{isa = PBXBuildFile; fileRef = CE11B0050AE8FD53008C47AC /* scriptGroup.tiff */;
};
CE129A180B44088900416D19 /* BDSKEntrezGroupServer.m in Sources
*/ = {isa = PBXBuildFile; fileRef = CE129A160B44088900416D19 /*
BDSKEntrezGroupServer.m */; };
CE12A1700B44AED200416D19 /* SearchGroupServers.plist in
Resources */ = {isa = PBXBuildFile; fileRef = CE12A16F0B44AED100416D19 /*
SearchGroupServers.plist */; };
+ CE15198214B62E47003AE698 /* BDSKLineNumberView.m in Sources */
= {isa = PBXBuildFile; fileRef = CE15198014B62E47003AE698 /*
BDSKLineNumberView.m */; };
CE15C0D80AA5B9A3002C555F /* BDSKErrorManager.m in Sources */ =
{isa = PBXBuildFile; fileRef = CE15C0D60AA5B9A3002C555F /* BDSKErrorManager.m
*/; };
CE15E6230FCC28B1009FCBF1 /* BibDocument_UI.m in Sources */ =
{isa = PBXBuildFile; fileRef = CE15E6210FCC28B1009FCBF1 /* BibDocument_UI.m */;
};
CE1782FC1158EFCB00B2EBDF /* BookmarkSheet.xib in Resources */ =
{isa = PBXBuildFile; fileRef = CE1782FB1158EFCB00B2EBDF /* BookmarkSheet.xib
*/; };
@@ -890,6 +891,8 @@
CE129A150B44088900416D19 /* BDSKEntrezGroupServer.h */ = {isa =
PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path =
BDSKEntrezGroupServer.h; sourceTree = "<group>"; };
CE129A160B44088900416D19 /* BDSKEntrezGroupServer.m */ = {isa =
PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc;
path = BDSKEntrezGroupServer.m; sourceTree = "<group>"; };
CE12A16F0B44AED100416D19 /* SearchGroupServers.plist */ = {isa
= PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path =
SearchGroupServers.plist; sourceTree = "<group>"; };
+ CE15197F14B62E47003AE698 /* BDSKLineNumberView.h */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path =
BDSKLineNumberView.h; sourceTree = "<group>"; };
+ CE15198014B62E47003AE698 /* BDSKLineNumberView.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path
= BDSKLineNumberView.m; sourceTree = "<group>"; };
CE15C0D50AA5B9A3002C555F /* BDSKErrorManager.h */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path =
BDSKErrorManager.h; sourceTree = "<group>"; };
CE15C0D60AA5B9A3002C555F /* BDSKErrorManager.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path
= BDSKErrorManager.m; sourceTree = "<group>"; };
CE15E6200FCC28B1009FCBF1 /* BibDocument_UI.h */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path =
BibDocument_UI.h; sourceTree = "<group>"; };
@@ -2067,6 +2070,7 @@
CE3B682909D1B0190017D339 /*
BDSKImagePopUpButtonCell.m */,
CE33D61A136AB8A700ACE924 /*
BDSKImportTextView.m */,
F92405010BC5856900672839 /*
BDSKLevelIndicatorCell.m */,
+ CE15198014B62E47003AE698 /*
BDSKLineNumberView.m */,
CEF536691192EFE400027C3C /*
BDSKNotesOutlineView.m */,
CE62E0BE0F4C4A5500BDF01E /* BDSKOutlineView.m
*/,
F941B7E908AA574200F04ECD /* BDSKOverlayWindow.m
*/,
@@ -2664,6 +2668,7 @@
CE24B35210C3E9E100818EDF /*
BDSKLastImportGroup.h */,
F92405000BC5856900672839 /*
BDSKLevelIndicatorCell.h */,
CE24B33210C3E13900818EDF /* BDSKLibraryGroup.h
*/,
+ CE15197F14B62E47003AE698 /*
BDSKLineNumberView.h */,
F911D7100CFE90050009C77B /* BDSKLinkedFile.h */,
F9201DFF0B72504C007E45BB /* BDSKMacro.h */,
CE3B5E7A09CEDE470017D339 /* BDSKMacroResolver.h
*/,
@@ -3789,6 +3794,7 @@
CE0CD73C1459812300488DE1 /*
NSAttributedString+Scripting.m in Sources */,
CEA498A21481183600AB81C5 /*
BDSKAddressTextField.m in Sources */,
CEA498A61481185100AB81C5 /*
BDSKAddressTextFieldCell.m in Sources */,
+ CE15198214B62E47003AE698 /*
BDSKLineNumberView.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Ridiculously easy VDI. With Citrix VDI-in-a-Box, you don't need a complex
infrastructure or vast IT resources to deliver seamless, secure access to
virtual desktops. With this all-in-one solution, easily deploy virtual
desktops for less than the cost of PCs and save 60% on VDI infrastructure
costs. Try it free! http://p.sf.net/sfu/Citrix-VDIinabox
_______________________________________________
Bibdesk-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bibdesk-commit