merge the formfield patch from ooo-build
[ooovba.git] / vcl / aqua / source / a11y / aqua11ytextattributeswrapper.mm
blobe521e7362323793cfb377801fd196ca2d5c03fd1
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  * 
5  * Copyright 2008 by Sun Microsystems, Inc.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * $RCSfile: aqua11ytextattributeswrapper.mm,v $
10  *
11  * $Revision: 1.3 $
12  *
13  * This file is part of OpenOffice.org.
14  *
15  * OpenOffice.org is free software: you can redistribute it and/or modify
16  * it under the terms of the GNU Lesser General Public License version 3
17  * only, as published by the Free Software Foundation.
18  *
19  * OpenOffice.org is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU Lesser General Public License version 3 for more details
23  * (a copy is included in the LICENSE file that accompanied this code).
24  *
25  * You should have received a copy of the GNU Lesser General Public License
26  * version 3 along with OpenOffice.org.  If not, see
27  * <http://www.openoffice.org/license.html>
28  * for a copy of the LGPLv3 License.
29  *
30  ************************************************************************/
32 // MARKER(update_precomp.py): autogen include statement, do not remove
33 #include "precompiled_vcl.hxx"
35 #include "aqua11ytextattributeswrapper.h"
36 #include "salinst.h"
37 #include <com/sun/star/accessibility/AccessibleTextType.hpp>
38 #include <com/sun/star/awt/FontUnderline.hpp>
39 #include <com/sun/star/awt/FontWeight.hpp>
40 #include <com/sun/star/awt/FontStrikeout.hpp>
42 using namespace ::com::sun::star::accessibility;
43 using namespace ::com::sun::star::awt;
44 using namespace ::com::sun::star::beans;
45 using namespace ::com::sun::star::lang;
46 using namespace ::com::sun::star::uno;
47 using namespace ::rtl;
49 @implementation AquaA11yTextAttributesWrapper : NSObject
51 +(int)convertUnderlineStyle:(PropertyValue)property {
52     int underlineStyle = NSNoUnderlineStyle;
53     sal_Int16 value = 0;
54     property.Value >>= value;
55     if ( value != FontUnderline::NONE 
56       && value != FontUnderline::DONTKNOW) {
57         underlineStyle = NSSingleUnderlineStyle;
58     }
59     return underlineStyle;
62 +(int)convertBoldStyle:(PropertyValue)property {
63     int boldStyle = 0;
64     float value = 0;
65     property.Value >>= value;
66     if ( value == FontWeight::SEMIBOLD
67       || value == FontWeight::BOLD
68       || value == FontWeight::ULTRABOLD
69       || value == FontWeight::BLACK ) {
70         boldStyle = NSBoldFontMask;
71     }
72     return boldStyle;
75 +(int)convertItalicStyle:(PropertyValue)property {
76     int italicStyle = 0;
77     sal_Int16 value = property.Value.get<FontSlant>();
78     if ( value == FontSlant_ITALIC ) {
79         italicStyle = NSItalicFontMask;
80     }
81     return italicStyle;
84 +(MacOSBOOL)isStrikethrough:(PropertyValue)property {
85     MacOSBOOL strikethrough = NO;
86     sal_Int16 value = 0;
87     property.Value >>= value;
88     if ( value != FontStrikeout::NONE
89       && value != FontStrikeout::DONTKNOW ) {
90         strikethrough = YES;
91     }
92     return strikethrough;
95 +(MacOSBOOL)convertBoolean:(PropertyValue)property {
96     MacOSBOOL myBoolean = NO;
97     bool value = sal_False;
98     property.Value >>= value;
99     if ( value ) {
100         myBoolean = YES;
101     }
102     return myBoolean;
105 +(NSNumber *)convertShort:(PropertyValue)property {
106     sal_Int16 value = 0;
107     property.Value >>= value;
108     return [ NSNumber numberWithShort: value ];
111 +(void)addColor:(sal_Int32)salColor forAttribute:(NSString *)attribute andRange:(NSRange)range toString:(NSMutableAttributedString *)string {
112     if ( salColor != -1 ) {
113         float elements[] = { salColor & 0x00ff0000, salColor & 0x0000ff00, salColor & 0x000000ff };
114         CGColorRef color = CGColorCreate ( CGColorSpaceCreateWithName ( kCGColorSpaceGenericRGB ), elements );
115         [ string addAttribute: attribute value: (id) color range: range ];
116         CGColorRelease ( color );
117     }
120 +(void)addFont:(NSFont *)font toString:(NSMutableAttributedString *)string forRange:(NSRange)range {
121     if ( font != nil ) {
122         NSDictionary * fontDictionary = [ NSDictionary dictionaryWithObjectsAndKeys:
123             [ font fontName ], NSAccessibilityFontNameKey,
124             [ font familyName ], NSAccessibilityFontFamilyKey,
125             [ font displayName ], NSAccessibilityVisibleNameKey,
126             [ NSNumber numberWithFloat: [ font pointSize ] ], NSAccessibilityFontSizeKey, 
127             nil
128         ];
129         [ string addAttribute: NSAccessibilityFontTextAttribute 
130                 value: fontDictionary 
131                 range: range
132         ];
133     }
136 +(void)applyAttributesFrom:(Sequence < PropertyValue >)attributes toString:(NSMutableAttributedString *)string forRange:(NSRange)range storeDefaultsTo:(AquaA11yWrapper *)wrapperStore getDefaultsFrom:(AquaA11yWrapper *)wrapper {
137     NSAutoreleasePool * pool = [ [ NSAutoreleasePool alloc ] init ];
138     // constants
139     static const OUString attrUnderline = OUString::createFromAscii("CharUnderline");
140     static const OUString attrBold = OUString::createFromAscii("CharWeight");
141     static const OUString attrFontname = OUString::createFromAscii("CharFontName");
142     static const OUString attrItalic = OUString::createFromAscii("CharPosture");
143     static const OUString attrHeight = OUString::createFromAscii("CharHeight");
144     static const OUString attrStrikethrough = OUString::createFromAscii("CharStrikeout");
145     static const OUString attrShadow = OUString::createFromAscii("CharShadowed");
146     static const OUString attrUnderlineColor = OUString::createFromAscii("CharUnderlineColor");
147     static const OUString attrUnderlineHasColor = OUString::createFromAscii("CharUnderlineHasColor");
148     static const OUString attrForegroundColor = OUString::createFromAscii("CharColor");
149     static const OUString attrBackgroundColor = OUString::createFromAscii("CharBackColor");
150     static const OUString attrSuperscript = OUString::createFromAscii("CharEscapement");
151     // vars
152     OUString fontname;
153     int fonttraits = 0;
154     float fontsize = 0.0;
155     sal_Int32 underlineColor = 0;
156     MacOSBOOL underlineHasColor = NO;
157     // add attributes to string
158     for ( int attrIndex = 0; attrIndex < attributes.getLength(); attrIndex++ ) {
159         PropertyValue property = attributes [ attrIndex ];
160         // TODO: NSAccessibilityMisspelledTextAttribute, NSAccessibilityAttachmentTextAttribute, NSAccessibilityLinkTextAttribute
161         // NSAccessibilityStrikethroughColorTextAttribute is unsupported by UNP-API
162         if ( property.Value.hasValue() ) {
163             if ( property.Name.equals ( attrUnderline ) ) {
164                 int style = [ AquaA11yTextAttributesWrapper convertUnderlineStyle: property ];
165                 if ( style != NSNoUnderlineStyle ) {
166                     [ string addAttribute: NSAccessibilityUnderlineTextAttribute value: [ NSNumber numberWithInt: style ] range: range ];
167                 }
168             } else if ( property.Name.equals ( attrFontname ) ) {
169                 property.Value >>= fontname;
170             } else if ( property.Name.equals ( attrBold ) ) {
171                 fonttraits |= [ AquaA11yTextAttributesWrapper convertBoldStyle: property ];
172             } else if ( property.Name.equals ( attrItalic ) ) {
173                 fonttraits |= [ AquaA11yTextAttributesWrapper convertItalicStyle: property ];
174             } else if ( property.Name.equals ( attrHeight ) ) {
175                 property.Value >>= fontsize;
176             } else if ( property.Name.equals ( attrStrikethrough ) ) {
177                 if ( [ AquaA11yTextAttributesWrapper isStrikethrough: property ] ) {
178                     [ string addAttribute: NSAccessibilityStrikethroughTextAttribute value: [ NSNumber numberWithBool: YES ] range: range ];
179                 }
180             } else if ( property.Name.equals ( attrShadow ) ) {
181                 if ( [ AquaA11yTextAttributesWrapper convertBoolean: property ] ) {
182                     [ string addAttribute: NSAccessibilityShadowTextAttribute value: [ NSNumber numberWithBool: YES ] range: range ];
183                 }
184             } else if ( property.Name.equals ( attrUnderlineColor ) ) {
185                 property.Value >>= underlineColor;
186             } else if ( property.Name.equals ( attrUnderlineHasColor ) ) {
187                 underlineHasColor = [ AquaA11yTextAttributesWrapper convertBoolean: property ];
188             } else if ( property.Name.equals ( attrForegroundColor ) ) {
189                 [ AquaA11yTextAttributesWrapper addColor: property.Value.get<sal_Int32>() forAttribute: NSAccessibilityForegroundColorTextAttribute andRange: range toString: string ];
190             } else if ( property.Name.equals ( attrBackgroundColor ) ) {
191                 [ AquaA11yTextAttributesWrapper addColor: property.Value.get<sal_Int32>() forAttribute: NSAccessibilityBackgroundColorTextAttribute andRange: range toString: string ];
192             } else if ( property.Name.equals ( attrSuperscript ) ) {
193                 // values < zero mean subscript
194                 // values > zero mean superscript
195                 // this is true for both NSAccessibility-API and UNO-API
196                 NSNumber * number = [ AquaA11yTextAttributesWrapper convertShort: property ];
197                 if ( [ number shortValue ] != 0 ) {
198                     [ string addAttribute: NSAccessibilitySuperscriptTextAttribute value: number range: range ];
199                 }
200             }
201         }
202     }
203     // add underline information
204     if ( underlineHasColor ) {
205         [ AquaA11yTextAttributesWrapper addColor: underlineColor forAttribute: NSAccessibilityUnderlineColorTextAttribute andRange: range toString: string ];
206     }
207     // add font information
208     if ( wrapperStore != nil ) { // default
209         [ wrapperStore setDefaultFontname: CreateNSString ( fontname ) ];
210         [ wrapperStore setDefaultFontsize: fontsize ];
211         NSFont * font = [ [ NSFontManager sharedFontManager ] fontWithFamily: CreateNSString ( fontname ) traits: fonttraits weight: 0 size: fontsize ];
212         [ AquaA11yTextAttributesWrapper addFont: font toString: string forRange: range ];
213     } else if ( wrapper != nil && fonttraits != 0 ) { // attribute run and bold and/or italic was found
214         NSFont * font = [ [ NSFontManager sharedFontManager ] fontWithFamily: [ wrapper defaultFontname ] traits: fonttraits weight: 0 size: [ wrapper defaultFontsize ] ];
215         [ AquaA11yTextAttributesWrapper addFont: font toString: string forRange: range ];
216     }
217     [ pool release ];
220 +(NSMutableAttributedString *)createAttributedStringForElement:(AquaA11yWrapper *)wrapper inOrigRange:(id)origRange {
221     static const Sequence < OUString > emptySequence;
222     // vars
223     NSMutableAttributedString * string = nil;
224     int loc = [ origRange rangeValue ].location;
225     int len = [ origRange rangeValue ].length;
226     int endIndex = loc + len;
227     int currentIndex = loc;
228     try {
229         NSString * myString = CreateNSString ( [ wrapper accessibleText ] -> getText() ); // TODO: dirty fix for i87817
230         string = [ [ NSMutableAttributedString alloc ] initWithString: CreateNSString ( [ wrapper accessibleText ] -> getTextRange ( loc, loc + len ) ) ];
231         if ( [ wrapper accessibleTextAttributes ] != nil && [myString characterAtIndex:0] != 57361) { // TODO: dirty fix for i87817
232             [ string beginEditing ];
233             // add default attributes for whole string
234             Sequence < PropertyValue > defaultAttributes = [ wrapper accessibleTextAttributes ] -> getDefaultAttributes ( emptySequence );
235             [ AquaA11yTextAttributesWrapper applyAttributesFrom: defaultAttributes toString: string forRange: [ origRange rangeValue ] storeDefaultsTo: wrapper getDefaultsFrom: nil ];
236             // add attributes for attribute run(s)
237             while ( currentIndex < endIndex ) {
238                 TextSegment textSegment = [ wrapper accessibleText ] -> getTextAtIndex ( currentIndex, AccessibleTextType::ATTRIBUTE_RUN );
239                 int endOfRange = endIndex > textSegment.SegmentEnd ? textSegment.SegmentEnd : endIndex;
240                 NSRange rangeForAttributeRun = NSMakeRange ( currentIndex, endOfRange - currentIndex );
241                 // add run attributes
242                 Sequence < PropertyValue > attributes = [ wrapper accessibleTextAttributes ] -> getRunAttributes ( currentIndex, emptySequence );
243                 [ AquaA11yTextAttributesWrapper applyAttributesFrom: attributes toString: string forRange: rangeForAttributeRun storeDefaultsTo: nil getDefaultsFrom: wrapper ];
244                 currentIndex = textSegment.SegmentEnd;
245             }
246             [ string endEditing ];
247         }
248     } catch ( IllegalArgumentException & e ) {
249         // empty
250     } catch ( IndexOutOfBoundsException & e ) {
251         // empty
252     } catch ( RuntimeException& ) {
253         // at least don't crash
254     }
255     return string;
258 @end