Attack My Code! Part 1
Attack My Code! Part 1
- Subject: Attack My Code! Part 1
- From: Charles Jenkins <email@hidden>
- Date: Thu, 12 Jun 2008 23:19:56 -0400
I'm new at programming in Cocoa, and if it is not rude to post a big
block of code to this list, I'd like to show you all a class I
developed and ask you to tell me about all the ways I've screwed it up!
BACKGROUND INFO
I'm trying to learn Chinese and I have a bunch of comic books to (try
to) read. Because writing is done with ideograms instead of an
alphabet, it's a bit of a pain to look words up in a dictionary, so
you wanna make notes to avoid having to look up the same character
again when you find it on the next page. Making notes on paper is not
ideal because it's hard to make them into a good reference; but making
notes on the Mac is hugely annoying because it's annoying to start
typing and find you haven't selected the right keyboard layout.
So what I want is an app that lets me enter word, pronunciation, and
definition in separate fields that REMEMBER the proper keyboard layout
and switch automatically when you enter and exit the fields.
I want to somehow connect my app to another app's text editor window
and tell it to transfer in a given format (hopefully HTML or RTF so
that the pronunciation and definition can be hidden until I need to
refer to them) so that I can do most of the typing in my little app
window and each time I've finished typing the word, pronunciation, and
definition, I can smack a button that will copy the finished product
to the pasteboard and send a signal to the other app to paste it.
The class I have to show to you today is the formatter that holds the
word, pronunciation, and definition as the user types them in, and is
ready at any time to provide them properly formatted in a variety of
ways. The best of these so far is HTML format, which hides the
pronunciation and definition in a tooltip!
Actually, the class seems to work pretty well, but the copyAsHtml and
copyAsRtf methods seem to put garbage on the clipboard. I have pored
over Apple's documentation regarding the pasteboard and converting an
attributed string to RTF, but there must be some crucial point I am
missing.
So I am looking for advice about how to get copyAsHtml and copyAsRtf
to work correctly, but also advice about anything else that I may be
doing wrong in the class.
Um, I guess I should ask: If this is not the proper place to be
sharing code like this, I would be happy to learn the better
alternative. I'm hoping to occasionally post classes as the app
develops and get feedback.
Here's my class:
// Formatter.h
#import <Cocoa/Cocoa.h>
@interface Formatter : NSObject {
NSString* word;
NSString* pronounciation;
NSString* definition;
NSPasteboard* thePasteboard;
}
-(id)init;
-(NSString*)pronounciationSurroundedBy:(NSString*)surroundChars;
-(NSString*)pronounciationSurroundedBy:(NSString*)surroundChars
withDefinitionSeparatedBy:(NSString*)sep;
-(NSString*)asText;
-(NSString*)asCsv;
-(NSString*)asHtml;
-(NSAttributedString*)asAttributedString;
-(void)copyAsText;
-(void)copyAsCsv;
-(void)copyAsHtml;
-(void)copyAsRtf;
@property(readwrite, copy) NSString* word;
@property(readwrite, copy) NSString* pronounciation;
@property(readwrite, copy) NSString* definition;
@end
// Formatter.m
#import "Formatter.h"
#define DOUBLE_QUOTE @"\""
@implementation Formatter
//-------------------------------------
+(NSString*)trimmedString:(NSString*)s
{
if ( s == NULL ) {
return @"";
} else {
return [ s stringByTrimmingCharactersInSet:[ NSCharacterSet
whitespaceAndNewlineCharacterSet ] ];
}
}
//-------------------------------------
+(NSString*)surroundNonEmptyString:(NSString*)text with:
(NSString*)surroundChars
{
if ( [ text length ] > 0 && surroundChars != NULL ) {
int numChars = [ surroundChars length ];
if ( numChars > 0 ) {
unichar l = [ surroundChars characterAtIndex:0 ];
unichar r = ( numChars == 1 )? l : [ surroundChars
characterAtIndex:1 ];
return [ NSString stringWithFormat:@"%C%@%C", l, text, r ];
}
}
return text;
}
//-------------------------------------
+(NSString*)concatString:(NSString*)a withString:(NSString*)b
separatedBy:(NSString*)sep
{
int aLen = ( a != NULL ) ? [ a length ] : 0;
int bLen = ( b != NULL ) ? [ b length ] : 0;
if ( aLen > 0 && bLen > 0 ) {
return [ NSString stringWithFormat:@"%@%@%@", a, sep, b ];
} else if ( aLen > 0 ) {
return a;
} else if ( bLen > 0 ) {
return b;
} else {
return @"";
}
}
//-------------------------------------
-(id)init
{
// Ensure all our data member variables have legal values
word = @"";
pronounciation = @"";
definition = @"";
// Prepare the pasteboard (clipboard) to recieve our clippings
thePasteboard = [ NSPasteboard generalPasteboard ];
NSArray* clippingTypes = [ NSArray arrayWithObjects:
NSStringPboardType, NSRTFPboardType, NSHTMLPboardType, nil ];
[ thePasteboard declareTypes:clippingTypes owner:self ];
return self;
}
//-------------------------------------
-(void)setWord:(NSString*)s
{
word = [ Formatter trimmedString:s ];
}
@synthesize word;
//-------------------------------------
-(void)setPronounciation:(NSString*)s
{
pronounciation = [ Formatter trimmedString:s ];
}
@synthesize pronounciation;
//-------------------------------------
-(void)setDefinition:(NSString*)s
{
definition = [ Formatter trimmedString:s ];
}
@synthesize definition;
//-------------------------------------
-(NSString*)pronounciationSurroundedBy:(NSString*)surroundChars
{
return [ Formatter surroundNonEmptyString:pronounciation
with:surroundChars ];
}
//-------------------------------------
-(NSString*)pronounciationSurroundedBy:(NSString*)surroundChars
withDefinitionSeparatedBy:(NSString*)sep
{
return [ Formatter concatString:[ self
pronounciationSurroundedBy:surroundChars ] withString:definition
separatedBy:sep ];
}
//-------------------------------------
-(NSString*)asText
{
if ( [ word length ] > 0 ) {
NSString* parens = @"()";
NSString* pd = [ self pronounciationSurroundedBy:parens
withDefinitionSeparatedBy:@" " ];
if ( [ pd length ] > 0 ) {
NSString* sep = ( [ pd characterAtIndex:0 ] == [ parens
characterAtIndex:0 ] ) ? @" " : @" - ";
return [ Formatter concatString:word withString:pd
separatedBy:sep ];
} else {
return word;
}
} else {
return @"";
}
}
//-------------------------------------
-(NSString*)asCsv
{
NSString* w = [ Formatter surroundNonEmptyString:word
with:DOUBLE_QUOTE ];
NSString* p = [ Formatter surroundNonEmptyString:pronounciation
with:DOUBLE_QUOTE ];
NSString* d = [ Formatter surroundNonEmptyString:definition
with:DOUBLE_QUOTE ];
return [ NSString stringWithFormat:@"%@, %@, %@", w, p, d ];
}
//-------------------------------------
-(NSString*)asHtml
{
NSString* pd = [ self pronounciationSurroundedBy:@"()"
withDefinitionSeparatedBy:@" " ];
if ( [ word length ] > 0 && [ pd length ] > 0 ) {
return [ NSString stringWithFormat:@"<a title=%@>%@</a>",
[ Formatter surroundNonEmptyString:pd with:DOUBLE_QUOTE ], word ];
} else {
return word;
}
}
//-------------------------------------
-(NSAttributedString*)asAttributedString
{
NSString* pd = [ self pronounciationSurroundedBy:@"()"
withDefinitionSeparatedBy:@" " ];
NSAttributedString* result;
if ( [ word length ] > 0 && [ pd length ] > 0 ) {
NSDictionary* attrsDictionary = [ NSDictionary
dictionaryWithObject:pd forKey:NSToolTipAttributeName ];
result = [ [ NSAttributedString alloc ] initWithString:word
attributes:attrsDictionary ];
} else {
result = [ [ NSAttributedString alloc ] initWithString:word ];
}
return result;
}
//-------------------------------------
-(void)copyAsText
{
NSData* data = [ [ self asText ]
dataUsingEncoding:NSUTF8StringEncoding ];
[ thePasteboard setData:data forType:NSStringPboardType ];
}
//-------------------------------------
-(void)copyAsCsv
{
NSData* data = [ [ self asCsv ]
dataUsingEncoding:NSUTF8StringEncoding ];
[ thePasteboard setData:data forType:NSStringPboardType ];
}
//-------------------------------------
-(void)copyAsHtml
{
NSData* data = [ [ self asHtml ]
dataUsingEncoding:NSUTF8StringEncoding ];
[ thePasteboard setData:data forType:NSStringPboardType ];
}
//-------------------------------------
-(void)copyAsRtf
{
NSAttributedString *attrString = [ self asAttributedString ];
NSRange wholeStringRange = NSMakeRange( 0, [ attrString length ] );
NSData* data = [ attrString RTFDFromRange:wholeStringRange
documentAttributes:nil ];
[ thePasteboard setData:data forType:NSRTFPboardType ];
}
@end
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden