Revision: 3781
http://skim-app.svn.sourceforge.net/skim-app/?rev=3781&view=rev
Author: hofman
Date: 2008-04-21 16:41:33 -0700 (Mon, 21 Apr 2008)
Log Message:
-----------
Move PDFDidplayView overrides to separate file. Add experimental code to make
annotations accessible for assistive devices. Should probably be disabled for
the next release.
Modified Paths:
--------------
trunk/PDFAnnotation_SKExtensions.h
trunk/PDFAnnotation_SKExtensions.m
trunk/SKPDFView.h
trunk/SKPDFView.m
trunk/Skim.xcodeproj/project.pbxproj
Added Paths:
-----------
trunk/PDFDisplayView_SKExtensions.h
trunk/PDFDisplayView_SKExtensions.m
Modified: trunk/PDFAnnotation_SKExtensions.h
===================================================================
--- trunk/PDFAnnotation_SKExtensions.h 2008-04-20 23:54:10 UTC (rev 3780)
+++ trunk/PDFAnnotation_SKExtensions.h 2008-04-21 23:41:33 UTC (rev 3781)
@@ -140,4 +140,13 @@
- (unsigned long)scriptingEndLineStyle;
- (id)selectionSpecifier;
+- (id)accessibilityRoleAttribute;
+- (id)accessibilityRoleDescriptionAttribute;
+- (id)accessibilityTitleAttribute;
+- (id)accessibilityValueAttribute;
+- (id)accessibilitySelectedTextAttribute;
+- (id)accessibilitySelectedTextRangeAttribute;
+- (id)accessibilityNumberOfCharactersAttribute;
+- (id)accessibilityVisibleCharacterRangeAttribute;
+
@end
Modified: trunk/PDFAnnotation_SKExtensions.m
===================================================================
--- trunk/PDFAnnotation_SKExtensions.m 2008-04-20 23:54:10 UTC (rev 3780)
+++ trunk/PDFAnnotation_SKExtensions.m 2008-04-21 23:41:33 UTC (rev 3781)
@@ -534,6 +534,40 @@
return [NSNull null];
}
+#pragma mark Accessibility
+
+- (id)accessibilityRoleAttribute {
+ return NSAccessibilityStaticTextRole;
+}
+
+- (id)accessibilityRoleDescriptionAttribute {
+ return NSAccessibilityRoleDescription([self accessibilityRoleAttribute],
nil);
+}
+
+- (id)accessibilityTitleAttribute {
+ return [[self type] typeName];
+}
+
+- (id)accessibilityValueAttribute {
+ return [self contents];
+}
+
+- (id)accessibilitySelectedTextAttribute {
+ return @"";
+}
+
+- (id)accessibilitySelectedTextRangeAttribute {
+ return [NSValue valueWithRange:NSMakeRange(0, 0)];
+}
+
+- (id)accessibilityNumberOfCharactersAttribute {
+ return [NSNumber numberWithUnsignedInt:[[self accessibilityValueAttribute]
length]];
+}
+
+- (id)accessibilityVisibleCharacterRangeAttribute {
+ return [NSValue valueWithRange:NSMakeRange(0, [[self
accessibilityValueAttribute] length])];
+}
+
@end
#pragma mark -
@@ -556,4 +590,40 @@
originalToolTip = OBReplaceMethodImplementationWithSelector(self,
@selector(toolTip), @selector(replacementToolTip));
}
+- (id)accessibilityRoleAttribute {
+ return NSAccessibilityLinkRole;
+}
+
+- (id)accessibilityRoleDescriptionAttribute {
+ return NSAccessibilityRoleDescription([self accessibilityRoleAttribute],
nil);
+}
+
+- (id)accessibilityTitleAttribute {
+ NSString *title = nil;
+ if (originalToolTip != NULL)
+ title = originalToolTip(self, _cmd);
+ if (title == nil)
+ title = [self contents];
+ return title;
+}
+
+- (id)accessibilityValueAttribute {
+ return [[[self page] selectionForRect:NSInsetRect([self bounds], -3.0,
-3.0)] string];
+}
+- (id)accessibilitySelectedTextAttribute {
+ return nil;
+}
+
+- (id)accessibilitySelectedTextRangeAttribute {
+ return nil;
+}
+
+- (id)accessibilityNumberOfCharactersAttribute {
+ return nil;
+}
+
+- (id)accessibilityVisibleCharacterRangeAttribute {
+ return nil;
+}
+
@end
Added: trunk/PDFDisplayView_SKExtensions.h
===================================================================
--- trunk/PDFDisplayView_SKExtensions.h (rev 0)
+++ trunk/PDFDisplayView_SKExtensions.h 2008-04-21 23:41:33 UTC (rev 3781)
@@ -0,0 +1,48 @@
+//
+// PDFDisplayView_SKExtensions.h
+// Skim
+//
+// Created by Christiaan Hofman on 4/22/08.
+/*
+ This software is Copyright (c) 2008
+ 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>
+#import <Quartz/Quartz.h>
+
+
[EMAIL PROTECTED] PDFDisplayView : NSView
+- (void)passwordEntered:(id)sender;
[EMAIL PROTECTED]
+
[EMAIL PROTECTED] PDFDisplayView (SKExtensions)
[EMAIL PROTECTED]
Added: trunk/PDFDisplayView_SKExtensions.m
===================================================================
--- trunk/PDFDisplayView_SKExtensions.m (rev 0)
+++ trunk/PDFDisplayView_SKExtensions.m 2008-04-21 23:41:33 UTC (rev 3781)
@@ -0,0 +1,423 @@
+//
+// PDFDisplayView_SKExtensions.m
+// Skim
+//
+// Created by Christiaan Hofman on 4/22/08.
+/*
+ This software is Copyright (c) 2008
+ 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 "PDFDisplayView_SKExtensions.h"
+#import "SKPDFView.h"
+#import "PDFAnnotation_SKExtensions.h"
+#import "SKPDFDocument.h"
+#import "SKStringConstants.h"
+#import "OBUtilities.h"
+
+
[EMAIL PROTECTED] SKAccessibilityPDFDisplayViewElement : NSObject {
+ id parent;
+}
+- (id)initWithParent:(id)aParent;
[EMAIL PROTECTED]
+
+#pragma mark -
+
[EMAIL PROTECTED] SKAccessibilityPDFAnnotationElement : NSObject {
+ PDFAnnotation *annotation;
+ SKPDFView *pdfView;
+ id parent;
+}
+- (id)initWithAnnotation:(PDFAnnotation *)anAnnotation pdfView:(SKPDFView
*)aPdfView parent:(id)aParent;
[EMAIL PROTECTED]
+
+#pragma mark -
+
+static IMP originalAccessibilityAttributeNames = NULL;
+static IMP originalAccessibilityAttributeValue = NULL;
+static IMP originalAccessibilityHitTest = NULL;
+static IMP originalAccessibilityFocusedUIElement = NULL;
+
[EMAIL PROTECTED] PDFDisplayView (SKExtensions)
+
+static IMP originalPasswordEntered = NULL;
+
+- (void)replacementPasswordEntered:(id)sender {
+ SKPDFDocument *document = [[[self window] windowController] document];
+ originalPasswordEntered(self, _cmd, sender);
+ if ([document respondsToSelector:@selector(savePasswordInKeychain:)])
+ [document savePasswordInKeychain:[sender stringValue]];
+}
+
+#pragma mark Accessibility
+
+- (SKPDFView *)skpdfView {
+ id pdfView = nil;
+ @try { pdfView = [self valueForKey:@"pdfView"]; }
+ @catch (id exception) {}
+ return [pdfView isKindOfClass:[SKPDFView class]] ? pdfView : nil;
+}
+
+- (NSArray *)replacementAccessibilityAttributeNames {
+ if ([self skpdfView])
+ return [originalAccessibilityAttributeNames(self, _cmd)
arrayByAddingObjectsFromArray:[NSArray
arrayWithObjects:NSAccessibilityChildrenAttribute,
NSAccessibilityVisibleChildrenAttribute, nil]];
+ else
+ return originalAccessibilityAttributeNames(self, _cmd);
+}
+
+- (id)replacementAccessibilityAttributeValue:(NSString *)attribute {
+ SKPDFView *pdfView = [self skpdfView];
+ if (pdfView == nil) {
+ return originalAccessibilityAttributeValue(self, _cmd, attribute);
+ } else if ([attribute isEqualToString:NSAccessibilityRoleAttribute]) {
+ return NSAccessibilityGroupRole;
+ } else if ([attribute
isEqualToString:NSAccessibilityRoleDescriptionAttribute]) {
+ return NSAccessibilityRoleDescription(NSAccessibilityGroupRole, nil);
+ } else if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
+ NSMutableArray *children = [NSMutableArray array];
+ [children
addObjectsFromArray:originalAccessibilityAttributeValue(self, _cmd, attribute)];
+ if (pdfView) {
+ [children addObject:[[[SKAccessibilityPDFDisplayViewElement alloc]
initWithParent:self] autorelease]];
+ PDFDocument *pdfDoc = [pdfView document];
+ unsigned int i, iMax = [pdfDoc pageCount];
+ for (i = 0; i < iMax; i++) {
+ PDFPage *page = [pdfDoc pageAtIndex:i];
+ NSEnumerator *annotationEnum = [[page annotations]
objectEnumerator];
+ PDFAnnotation *annotation;
+ while (annotation = [annotationEnum nextObject]) {
+ if ([[annotation type] isEqualToString:SKLinkString] ||
[annotation isNoteAnnotation])
+ [children
addObject:[[[SKAccessibilityPDFAnnotationElement alloc]
initWithAnnotation:annotation pdfView:pdfView parent:self] autorelease]];
+ }
+ }
+ }
+ return NSAccessibilityUnignoredChildren(children);
+ } else if ([attribute
isEqualToString:NSAccessibilityVisibleChildrenAttribute]) {
+ NSMutableArray *children = [NSMutableArray array];
+ [children
addObjectsFromArray:originalAccessibilityAttributeValue(self, _cmd, attribute)];
+ SKPDFView *pdfView = [self skpdfView];
+ if (pdfView) {
+ [children addObject:[[[SKAccessibilityPDFDisplayViewElement alloc]
initWithParent:self] autorelease]];
+ PDFDocument *pdfDoc = [pdfView document];
+ NSRect visibleRect = [pdfView visibleContentRect];
+ NSRange range = [pdfView visiblePageIndexRange];
+ unsigned int i;
+ for (i = range.location; i < NSMaxRange(range); i++) {
+ PDFPage *page = [pdfDoc pageAtIndex:i];
+ NSEnumerator *annotationEnum = [[page annotations]
objectEnumerator];
+ PDFAnnotation *annotation;
+ while (annotation = [annotationEnum nextObject]) {
+ if ([[annotation type] isEqualToString:SKLinkString] ||
[annotation isNoteAnnotation] &&
+ NSIntersectsRect([pdfView convertRect:[annotation
bounds] fromPage:[annotation page]], visibleRect))
+ [children
addObject:[[[SKAccessibilityPDFAnnotationElement alloc]
initWithAnnotation:annotation pdfView:pdfView parent:self] autorelease]];
+ }
+ }
+ }
+ return NSAccessibilityUnignoredChildren(children);
+ } else if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) {
+ NSNumber *focused = originalAccessibilityAttributeValue(self, _cmd,
attribute);
+ SKPDFView *pdfView = [self skpdfView];
+ if (pdfView)
+ return [NSNumber numberWithBool:[pdfView activeAnnotation] == nil
&& [focused boolValue]];
+ else
+ return focused;
+ } else {
+ return originalAccessibilityAttributeValue(self, _cmd, attribute);
+ }
+}
+
+- (id)replacementAccessibilityHitTest:(NSPoint)point {
+ SKPDFView *pdfView = [self skpdfView];
+ if (pdfView) {
+ NSPoint localPoint = [pdfView convertPoint:[[pdfView window]
convertScreenToBase:point] fromView:nil];
+ PDFPage *page = [pdfView pageForPoint:localPoint nearest:NO];
+ if (page) {
+ PDFAnnotation *annotation = [page annotationAtPoint:[pdfView
convertPoint:localPoint toPage:page]];
+ if ([[annotation type] isEqualToString:SKLinkString] ||
[annotation isNoteAnnotation]) {
+ return [[[[SKAccessibilityPDFAnnotationElement alloc]
initWithAnnotation:annotation pdfView:pdfView parent:self] autorelease]
accessibilityHitTest:point];
+ }
+ }
+ return [[[[SKAccessibilityPDFDisplayViewElement alloc]
initWithParent:self] autorelease] accessibilityHitTest:point];
+ } else {
+ return originalAccessibilityHitTest(self, _cmd, point);
+ }
+}
+
+- (id)replacementAccessibilityFocusedUIElement {
+ SKPDFView *pdfView = [self skpdfView];
+ if (pdfView) {
+ PDFAnnotation *annotation = [pdfView activeAnnotation];
+ if (annotation) {
+ return
NSAccessibilityUnignoredAncestor([[[SKAccessibilityPDFAnnotationElement alloc]
initWithAnnotation:annotation pdfView:pdfView parent:self] autorelease]);
+ } else {
+ return
NSAccessibilityUnignoredAncestor([[[SKAccessibilityPDFDisplayViewElement alloc]
initWithParent:self] autorelease]);
+ }
+ } else {
+ return originalAccessibilityFocusedUIElement(self, _cmd);
+ }
+}
+
+- (BOOL)accessibilityIsIgnored {
+ return NO;
+}
+
++ (void)load {
+ if ([self instancesRespondToSelector:@selector(passwordEntered:)])
+ originalPasswordEntered =
OBReplaceMethodImplementationWithSelector(self, @selector(passwordEntered:),
@selector(replacementPasswordEntered:));
+ if ([self
instancesRespondToSelector:@selector(accessibilityAttributeNames)])
+ originalAccessibilityAttributeNames =
OBReplaceMethodImplementationWithSelector(self,
@selector(accessibilityAttributeNames),
@selector(replacementAccessibilityAttributeNames));
+ if ([self
instancesRespondToSelector:@selector(accessibilityAttributeValue:)])
+ originalAccessibilityAttributeValue =
OBReplaceMethodImplementationWithSelector(self,
@selector(accessibilityAttributeValue:),
@selector(replacementAccessibilityAttributeValue:));
+ if ([self instancesRespondToSelector:@selector(accessibilityHitTest:)])
+ originalAccessibilityHitTest =
OBReplaceMethodImplementationWithSelector(self,
@selector(accessibilityHitTest:), @selector(replacementAccessibilityHitTest:));
+ if ([self
instancesRespondToSelector:@selector(accessibilityFocusedUIElement)])
+ originalAccessibilityFocusedUIElement =
OBReplaceMethodImplementationWithSelector(self,
@selector(accessibilityFocusedUIElement),
@selector(replacementAccessibilityFocusedUIElement));
+}
+
[EMAIL PROTECTED]
+
+#pragma mark -
+
[EMAIL PROTECTED] SKAccessibilityPDFDisplayViewElement
+
+- (id)initWithParent:(id)aParent {
+ if (self = [super init]) {
+ parent = aParent;
+ }
+ return self;
+}
+
+- (BOOL)isEqual:(id)object {
+ if ([object isKindOfClass:[SKAccessibilityPDFDisplayViewElement class]]) {
+ SKAccessibilityPDFDisplayViewElement *other =
(SKAccessibilityPDFDisplayViewElement *)object;
+ return parent == other->parent;
+ } else {
+ return NO;
+ }
+}
+
+- (unsigned int)hash {
+ return [parent hash];
+}
+
+- (NSArray *)accessibilityAttributeNames {
+ return originalAccessibilityAttributeNames(parent, _cmd);
+}
+
+- (id)accessibilityAttributeValue:(NSString *)attribute {
+ if ([attribute isEqualToString:NSAccessibilityParentAttribute]) {
+ return NSAccessibilityUnignoredAncestor(parent);
+ } else if ([attribute isEqualToString:NSAccessibilityWindowAttribute]) {
+ // We're in the same window as our parent.
+ return [NSAccessibilityUnignoredAncestor(parent)
accessibilityAttributeValue:NSAccessibilityWindowAttribute];
+ } else if ([attribute
isEqualToString:NSAccessibilityTopLevelUIElementAttribute]) {
+ // We're in the same top level element as our parent.
+ return [NSAccessibilityUnignoredAncestor(parent)
accessibilityAttributeValue:NSAccessibilityTopLevelUIElementAttribute];
+ } else {
+ return originalAccessibilityAttributeValue(parent, _cmd, attribute);
+ }
+}
+
+- (BOOL)accessibilityIsAttributeSettable:(NSString *)attribute {
+ return [parent respondsToSelector:_cmd] && [parent
accessibilityIsAttributeSettable:attribute];
+}
+
+- (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute {
+ if ([parent respondsToSelector:_cmd])
+ [parent accessibilitySetValue:value forAttribute:attribute];
+}
+
+- (NSArray *)accessibilityParameterizedAttributeNames {
+ return [parent respondsToSelector:_cmd] ? [parent
accessibilityParameterizedAttributeNames] : [NSArray array];
+}
+
+- (id)accessibilityAttributeValue:(NSString *)attribute
forParameter:(id)parameter {
+ return [parent respondsToSelector:_cmd] ? [parent
accessibilityAttributeValue:attribute forParameter:parameter] : nil;
+}
+
+- (BOOL)accessibilityIsIgnored {
+ return NO;
+}
+
+- (id)accessibilityHitTest:(NSPoint)point {
+ return NSAccessibilityUnignoredAncestor(self);
+}
+
+- (id)accessibilityFocusedUIElement {
+ return NSAccessibilityUnignoredAncestor(self);
+}
+
+- (NSArray *)accessibilityActionNames {
+ return [parent respondsToSelector:_cmd] ? [parent
accessibilityActionNames] : [NSArray array];
+}
+
+- (NSString *)accessibilityActionDescription:(NSString *)anAction {
+ return [parent respondsToSelector:_cmd] ? [parent
accessibilityActionDescription:anAction] :
NSAccessibilityActionDescription(anAction);
+}
+
+- (void)accessibilityPerformAction:(NSString *)anAction {
+ if ([parent respondsToSelector:_cmd])
+ [parent accessibilityPerformAction:anAction];
+}
+
[EMAIL PROTECTED]
+
+#pragma mark -
+
[EMAIL PROTECTED] SKAccessibilityPDFAnnotationElement
+
+- (id)initWithAnnotation:(PDFAnnotation *)anAnnotation pdfView:(SKPDFView
*)aPdfView parent:(id)aParent {
+ if (self = [super init]) {
+ annotation = anAnnotation;
+ pdfView = aPdfView;
+ parent = aParent;
+ }
+ return self;
+}
+
+- (BOOL)isEqual:(id)object {
+ if ([object isKindOfClass:[SKAccessibilityPDFAnnotationElement class]]) {
+ SKAccessibilityPDFAnnotationElement *other =
(SKAccessibilityPDFAnnotationElement *)object;
+ return annotation == other->annotation && pdfView == other->pdfView;
+ } else {
+ return NO;
+ }
+}
+
+- (unsigned int)hash {
+ return [annotation hash] + [pdfView hash];
+}
+
+- (NSArray *)accessibilityAttributeNames {
+ static NSArray *attributes = nil;
+ if (attributes == nil) {
+ attributes = [[NSArray alloc] initWithObjects:
+ NSAccessibilityRoleAttribute,
+ NSAccessibilityRoleDescriptionAttribute,
+ NSAccessibilityTitleAttribute,
+ NSAccessibilityValueAttribute,
+ NSAccessibilityParentAttribute,
+ NSAccessibilityWindowAttribute,
+ NSAccessibilityTopLevelUIElementAttribute,
+ NSAccessibilityFocusedAttribute,
+ NSAccessibilityEnabledAttribute,
+ NSAccessibilityPositionAttribute,
+ NSAccessibilitySizeAttribute,
+ nil];
+ }
+ return attributes;
+}
+
+- (id)accessibilityAttributeValue:(NSString *)attribute {
+ if ([attribute isEqualToString:NSAccessibilityRoleAttribute]) {
+ return [annotation accessibilityRoleAttribute];
+ } else if ([attribute
isEqualToString:NSAccessibilityRoleDescriptionAttribute]) {
+ return [annotation accessibilityRoleDescriptionAttribute];
+ } else if ([attribute isEqualToString:NSAccessibilityValueAttribute]) {
+ return [annotation accessibilityValueAttribute];
+ } else if ([attribute isEqualToString:NSAccessibilityTitleAttribute]) {
+ return [annotation accessibilityTitleAttribute];
+ } else if ([attribute
isEqualToString:NSAccessibilitySelectedTextAttribute]) {
+ return [annotation accessibilitySelectedTextAttribute];
+ } else if ([attribute
isEqualToString:NSAccessibilitySelectedTextRangeAttribute]) {
+ return [annotation accessibilitySelectedTextRangeAttribute];
+ } else if ([attribute
isEqualToString:NSAccessibilityNumberOfCharactersAttribute]) {
+ return [annotation accessibilityNumberOfCharactersAttribute];
+ } else if ([attribute
isEqualToString:NSAccessibilityVisibleCharacterRangeAttribute]) {
+ return [annotation accessibilityVisibleCharacterRangeAttribute];
+ } else if ([attribute isEqualToString:NSAccessibilityParentAttribute]) {
+ return NSAccessibilityUnignoredAncestor(parent);
+ } else if ([attribute isEqualToString:NSAccessibilityWindowAttribute]) {
+ // We're in the same window as our parent.
+ return [NSAccessibilityUnignoredAncestor(parent)
accessibilityAttributeValue:NSAccessibilityWindowAttribute];
+ } else if ([attribute
isEqualToString:NSAccessibilityTopLevelUIElementAttribute]) {
+ // We're in the same top level element as our parent.
+ return [NSAccessibilityUnignoredAncestor(parent)
accessibilityAttributeValue:NSAccessibilityTopLevelUIElementAttribute];
+ } else if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) {
+ return [NSNumber numberWithBool:[pdfView activeAnnotation] ==
annotation];
+ } else if ([attribute isEqualToString:NSAccessibilityEnabledAttribute]) {
+ return [NSNumber numberWithBool:NO];
+ } else if ([attribute isEqualToString:NSAccessibilityPositionAttribute]) {
+ NSRect rect = [pdfView convertRect:[annotation bounds]
fromPage:[annotation page]];
+ return [NSValue valueWithPoint:[[pdfView window]
convertBaseToScreen:[pdfView convertPoint:rect.origin toView:nil]]];
+ } else if ([attribute isEqualToString:NSAccessibilitySizeAttribute]) {
+ NSRect rect = [pdfView convertRect:[annotation bounds]
fromPage:[annotation page]];
+ return [NSValue valueWithSize:[pdfView convertSize:rect.size
toView:nil]];
+ } else {
+ return nil;
+ }
+}
+
+- (BOOL)accessibilityIsAttributeSettable:(NSString *)attribute {
+ return [attribute isEqualToString:NSAccessibilityFocusedAttribute];
+}
+
+- (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute {
+ if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) {
+ if ([value boolValue])
+ [pdfView setActiveAnnotation:annotation];
+ else if ([pdfView activeAnnotation] == annotation)
+ [pdfView setActiveAnnotation:nil];
+ }
+}
+
+- (BOOL)accessibilityIsIgnored {
+ return NO;
+}
+
+- (id)accessibilityHitTest:(NSPoint)point {
+ return NSAccessibilityUnignoredAncestor(self);
+}
+
+- (id)accessibilityFocusedUIElement {
+ return NSAccessibilityUnignoredAncestor(self);
+}
+
+- (NSArray *)accessibilityActionNames {
+ if ([[annotation type] isEqualToString:SKLinkString] || [annotation
isEditable])
+ return [NSArray arrayWithObject:NSAccessibilityPressAction];
+ else
+ return [NSArray array];
+}
+
+- (NSString *)accessibilityActionDescription:(NSString *)anAction {
+ return NSAccessibilityActionDescription(anAction);
+}
+
+- (void)accessibilityPerformAction:(NSString *)anAction {
+ if ([anAction isEqualToString:NSAccessibilityPressAction]) {
+ if ([pdfView activeAnnotation] != annotation)
+ [pdfView setActiveAnnotation:annotation];
+ [pdfView editActiveAnnotation:self];
+ }
+}
+
[EMAIL PROTECTED]
Modified: trunk/SKPDFView.h
===================================================================
--- trunk/SKPDFView.h 2008-04-20 23:54:10 UTC (rev 3780)
+++ trunk/SKPDFView.h 2008-04-21 23:41:33 UTC (rev 3781)
@@ -187,6 +187,9 @@
- (void)resetHoverRects;
- (void)removeHoverRects;
+- (NSRange)visiblePageIndexRange;
+- (NSRect)visibleContentRect;
+
- (NSUndoManager *)undoManager;
@end
Modified: trunk/SKPDFView.m
===================================================================
--- trunk/SKPDFView.m 2008-04-20 23:54:10 UTC (rev 3780)
+++ trunk/SKPDFView.m 2008-04-21 23:41:33 UTC (rev 3781)
@@ -116,9 +116,6 @@
@interface SKPDFView (Private)
-- (NSRange)visiblePageIndexRange;
-- (NSRect)visibleContentRect;
-
- (void)transformCGContext:(CGContextRef)context forPage:(PDFPage *)page;
- (void)autohideTimerFired:(NSTimer *)aTimer;
@@ -527,8 +524,10 @@
activeAnnotation = nil;
}
- if (changed)
+ if (changed) {
[[NSNotificationCenter defaultCenter]
postNotificationName:SKPDFViewActiveAnnotationDidChangeNotification object:self
userInfo:nil];
+ NSAccessibilityPostNotification(NSAccessibilityUnignoredAncestor([self
documentView]), NSAccessibilityFocusedUIElementChangedNotification);
+ }
}
- (BOOL)isEditing {
@@ -943,6 +942,9 @@
} else if (([self toolMode] == SKTextToolMode || [self toolMode] ==
SKNoteToolMode) &&
(eventChar == NSTabCharacter) && (modifiers ==
NSAlternateKeyMask)) {
[self selectNextActiveAnnotation:self];
+ } else if (([self toolMode] == SKTextToolMode || [self toolMode] ==
SKNoteToolMode) &&
+ (eventChar == 0x1B) && (modifiers == NSAlternateKeyMask)) {
+ [self setActiveAnnotation:nil];
// backtab is a bit inconsistent, it seems Shift+Tab gives a
Shift-BackTab key event, I would have expected either Shift-Tab (as for the raw
event) or BackTab (as for most shift-modified keys)
} else if (([self toolMode] == SKTextToolMode || [self toolMode] ==
SKNoteToolMode) &&
(((eventChar == NSBackTabCharacter) && ((modifiers &
~NSShiftKeyMask) == NSAlternateKeyMask)) ||
@@ -2241,12 +2243,6 @@
}
}
[EMAIL PROTECTED]
-
-#pragma mark -
-
[EMAIL PROTECTED] SKPDFView (Private)
-
- (void)transformCGContext:(CGContextRef)context forPage:(PDFPage *)page {
NSRect boxRect = [page boundsForBox:[self displayBox]];
@@ -3931,30 +3927,3 @@
SKCGContextDrawGrabHandle(context, CGPointMake(CGRectGetMaxX(rect),
CGRectGetMaxY(rect)), radius, mask == (BDSKMaxXEdgeMask | BDSKMaxYEdgeMask));
SKCGContextDrawGrabHandle(context, CGPointMake(CGRectGetMaxX(rect),
CGRectGetMinY(rect)), radius, mask == (BDSKMaxXEdgeMask | BDSKMinYEdgeMask));
}
-
-#pragma mark -
-
[EMAIL PROTECTED] PDFDisplayView : NSView
-- (void)passwordEntered:(id)sender;
[EMAIL PROTECTED]
-
[EMAIL PROTECTED] PDFDisplayView (SKExtensions)
[EMAIL PROTECTED]
-
[EMAIL PROTECTED] PDFDisplayView (SKExtensions)
-
-static IMP originalPasswordEntered = NULL;
-
-- (void)replacementPasswordEntered:(id)sender {
- SKPDFDocument *document = [[[self window] windowController] document];
- originalPasswordEntered(self, _cmd, sender);
- if ([document respondsToSelector:@selector(savePasswordInKeychain:)])
- [document savePasswordInKeychain:[sender stringValue]];
-}
-
-+ (void)load {
- if ([self instancesRespondToSelector:@selector(passwordEntered:)])
- originalPasswordEntered =
OBReplaceMethodImplementationWithSelector(self, @selector(passwordEntered:),
@selector(replacementPasswordEntered:));
-}
-
[EMAIL PROTECTED]
Modified: trunk/Skim.xcodeproj/project.pbxproj
===================================================================
--- trunk/Skim.xcodeproj/project.pbxproj 2008-04-20 23:54:10 UTC (rev
3780)
+++ trunk/Skim.xcodeproj/project.pbxproj 2008-04-21 23:41:33 UTC (rev
3781)
@@ -194,6 +194,7 @@
CECF61FF0DB258D600587D96 /* SKFontWell.m in Sources */ = {isa =
PBXBuildFile; fileRef = CECF61FE0DB258D600587D96 /* SKFontWell.m */; };
CEE106150BCBB72C00BF2D3E /* SKNotesDocument.m in Sources */ =
{isa = PBXBuildFile; fileRef = CEE106140BCBB72C00BF2D3E /* SKNotesDocument.m
*/; };
CEE1065E0BCBBE1300BF2D3E /* NotesDocument.nib in Resources */ =
{isa = PBXBuildFile; fileRef = CEE106580BCBBE1200BF2D3E /* NotesDocument.nib
*/; };
+ CEE176E40DBD5B0C00E6C317 /* PDFDisplayView_SKExtensions.m in
Sources */ = {isa = PBXBuildFile; fileRef = CEE176E30DBD5B0C00E6C317 /*
PDFDisplayView_SKExtensions.m */; };
CEE229390BFB7CE9002B746B /* ReleaseNotes.rtf in Resources */ =
{isa = PBXBuildFile; fileRef = CE54AA8E0BBC037400008750 /* ReleaseNotes.rtf */;
};
CEE22EA30BFB8672002B746B /* displayline in CopyFiles */ = {isa
= PBXBuildFile; fileRef = CE1E2F120BDB86A10011D9DD /* displayline */; };
CEE22EA40BFB8684002B746B /* skimnotes in CopyFiles */ = {isa =
PBXBuildFile; fileRef = CEF3BF750B99CA2900E12E3D /* skimnotes */; };
@@ -811,6 +812,8 @@
CEE106590BCBBE1200BF2D3E /* English */ = {isa =
PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path =
English.lproj/NotesDocument.nib; sourceTree = "<group>"; };
CEE107380BCBCA3200BF2D3E /* Dutch */ = {isa = PBXFileReference;
lastKnownFileType = wrapper.nib; name = Dutch; path =
Dutch.lproj/NotesDocument.nib; sourceTree = "<group>"; };
CEE11EF50BCC262800BF2D3E /* Italian */ = {isa =
PBXFileReference; lastKnownFileType = wrapper.nib; name = Italian; path =
Italian.lproj/NotesDocument.nib; sourceTree = "<group>"; };
+ CEE176E20DBD5B0C00E6C317 /* PDFDisplayView_SKExtensions.h */ =
{isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h;
path = PDFDisplayView_SKExtensions.h; sourceTree = "<group>"; };
+ CEE176E30DBD5B0C00E6C317 /* PDFDisplayView_SKExtensions.m */ =
{isa = PBXFileReference; fileEncoding = 4; lastKnownFileType =
sourcecode.c.objc; path = PDFDisplayView_SKExtensions.m; sourceTree =
"<group>"; };
CEE54D170DA2AA050037169F /* cs */ = {isa = PBXFileReference;
lastKnownFileType = wrapper.nib; name = cs; path = cs.lproj/InfoWindow.nib;
sourceTree = "<group>"; };
CEE54D190DA2AA100037169F /* cs */ = {isa = PBXFileReference;
lastKnownFileType = wrapper.nib; name = cs; path = cs.lproj/MainMenu.nib;
sourceTree = "<group>"; };
CEE54D1A0DA2AA1F0037169F /* cs */ = {isa = PBXFileReference;
lastKnownFileType = wrapper.nib; name = cs; path = cs.lproj/MainWindow.nib;
sourceTree = "<group>"; };
@@ -1130,6 +1133,8 @@
CEE54D870DA2E37B0037169F /*
PDFAnnotation_SKExtensions.m */,
CEE54DC60DA2EAE00037169F /*
PDFBorder_SKExtensions.h */,
CEE54DC70DA2EAE00037169F /*
PDFBorder_SKExtensions.m */,
+ CEE176E20DBD5B0C00E6C317 /*
PDFDisplayView_SKExtensions.h */,
+ CEE176E30DBD5B0C00E6C317 /*
PDFDisplayView_SKExtensions.m */,
CE6DC7B90D689138003A072F /*
PDFDocument_SKExtensions.h */,
CE6DC7BA0D689138003A072F /*
PDFDocument_SKExtensions.m */,
CE2DE50B0B85DC4000D0DA12 /*
PDFPage_SKExtensions.h */,
@@ -2013,6 +2018,7 @@
CE0859D20DAE912500760AFC /*
SKSnapshotPageCell.m in Sources */,
CECF61FF0DB258D600587D96 /* SKFontWell.m in
Sources */,
CE80666F0DB910610078D118 /*
SKSnapshotContentView.m in Sources */,
+ CEE176E40DBD5B0C00E6C317 /*
PDFDisplayView_SKExtensions.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
Skim-app-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/skim-app-commit