/* * Name: OgreTextFinder.m * Project: OgreKit * * Creation Date: Sep 20 2003 * Author: Isao Sonobe * Copyright: Copyright (c) 2003 Isao Sonobe, All rights reserved. * License: OgreKit License * * Encoding: UTF8 * Tabsize: 4 */ #import /* Foundation */ #import #import #import #import /* Threads */ #import // concrete implementors #import #import #import #import #import #import /* Adapters */ #import #import #import // concrete implementors // TextView #import #if 0 // FIXME: not used yet // TableView #import // OutlineView #import #endif /* Views */ #import /* Find Results */ #import #import #import /* Controllers */ #import #import #import // singleton static OgreTextFinder *_sharedTextFinder = nil; // 例外名 NSString *OgreTextFinderException = @"OgreTextFinderException"; // encode/decodeに使用するKey static NSString *OgreTextFinderHistoryKey = @"Find Controller History"; static NSString *OgreTextFinderSyntaxKey = @"Syntax"; static NSString *OgreTextFinderEscapeCharacterKey = @"Escape Character"; @implementation OgreTextFinder + (id)sharedTextFinder { if (_sharedTextFinder == nil) { _sharedTextFinder = [[[self class] alloc] init]; } return _sharedTextFinder; } - (id)init { #ifdef DEBUG_OGRE_FIND_PANEL NSLog(@"-init of %@", [self className]); #endif if (_sharedTextFinder != nil) { [super release]; return _sharedTextFinder; } self = [super init]; if (self != nil) { _busyTargetArray = [[NSMutableArray alloc] initWithCapacity:0]; // 使用中ターゲット NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSDictionary *fullHistory = [defaults dictionaryForKey:@"OgreTextFinder"]; // 履歴等 if (fullHistory != nil) { _history = [[fullHistory objectForKey: OgreTextFinderHistoryKey] retain]; id anObject = [fullHistory objectForKey: OgreTextFinderSyntaxKey]; if(anObject == nil) { [self setSyntax:[OGRegularExpression defaultSyntax]]; } else { _syntax = [OGRegularExpression syntaxForIntValue:[anObject intValue]]; } _escapeCharacter = [[fullHistory objectForKey: OgreTextFinderEscapeCharacterKey] retain]; if(_escapeCharacter == nil) { [self setEscapeCharacter:[OGRegularExpression defaultEscapeCharacter]]; } } else { _history = nil; [self setSyntax:[OGRegularExpression defaultSyntax]]; [self setEscapeCharacter:[OGRegularExpression defaultEscapeCharacter]]; } _saved = NO; // Applicationのterminationを拾う (履歴保存のタイミング) [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(appWillTerminate:) name: NSApplicationWillTerminateNotification object: NSApp]; // Applicationのlaunchを拾う (Findメニューの設定のタイミング) [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(appDidFinishLaunching:) name: NSApplicationDidFinishLaunchingNotification object: NSApp]; if ([self findPanelNibName]) { [NSBundle loadNibNamed:[self findPanelNibName] owner:self]; } else { /* Load default find panel */ findPanelController = [[OgreFindPanelController alloc] init]; [findPanelController setFindPanel: [OgreFindPanel sharedFindPanel]]; [findPanelController setTextFinder: self]; [[OgreFindPanel sharedFindPanel] setFindPanelController: findPanelController]; [self setFindPanelController: findPanelController]; } _sharedTextFinder = self; _useStylesInFindPanel = YES; /* registering adapters for targets */ _adapterClassArray = [[NSMutableArray alloc] initWithCapacity:1]; _targetClassArray = [[NSMutableArray alloc] initWithCapacity:1]; // NSTextView [self registeringAdapterClass:[OgreTextViewAdapter class] forTargetClass:[NSTextView class]]; } return self; } - (void)setUseStylesInFindPanel:(BOOL)use { _useStylesInFindPanel = use; } - (BOOL)useStylesInFindPanel { return _useStylesInFindPanel; } - (void)appDidFinishLaunching:(NSNotification*)aNotification { #ifdef DEBUG_OGRE_FIND_PANEL NSLog(@"-appDidFinishLaunching: of %@", [self className]); #endif [[NSNotificationCenter defaultCenter] removeObserver:self name: NSApplicationDidFinishLaunchingNotification object: NSApp]; /* send 'ogreKitShouldUseStylesInFindPanel:' message to the responder chain */ [NSApp sendAction:@selector(ogreKitShouldUseStylesInFindPanel:) to:nil from:self]; /* if you don't want to use "Replace With Styles" in the Find Panel, add the following method to the subclass or delegate of NSApplication. - (void)ogreKitShouldUseStylesInFindPanel:(OgreTextFinder*)textFinder { [textFinder setShouldUseStylesInFindPanel:NO]; } */ } - (void)appWillTerminate:(NSNotification*)aNotification { #ifdef DEBUG_OGRE_FIND_PANEL NSLog(@"-appWillTerminate: of %@", [self className]); #endif [[NSNotificationCenter defaultCenter] removeObserver:self name: NSApplicationWillTerminateNotification object: NSApp]; // 検索履歴等の保存 NSDictionary *fullHistory = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects: [findPanelController history], [NSNumber numberWithInt:[OGRegularExpression intValueForSyntax:_syntax]], _escapeCharacter, nil] forKeys:[NSArray arrayWithObjects: OgreTextFinderHistoryKey, OgreTextFinderSyntaxKey, OgreTextFinderEscapeCharacterKey, nil]]; NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults setObject:fullHistory forKey:@"OgreTextFinder"]; [defaults synchronize]; _saved = YES; } - (NSDictionary*)history // 非公開メソッド { #ifdef DEBUG_OGRE_FIND_PANEL NSLog(@"-history of %@", [self className]); #endif NSDictionary *history = _history; _history = nil; return [history autorelease]; } - (void)dealloc { #ifdef DEBUG_OGRE_FIND_PANEL NSLog(@"CAUTION! -dealloc of %@", [self className]); #endif [[NSNotificationCenter defaultCenter] removeObserver:self]; if (_saved == NO) [self appWillTerminate:nil]; // 履歴の保存がまだならば保存する。 [_targetClassArray release]; [_adapterClassArray release]; [findPanelController release]; [_history release]; [_escapeCharacter release]; [_busyTargetArray release]; _sharedTextFinder = nil; [super dealloc]; } - (IBAction)showFindPanel:(id)sender { [findPanelController showFindPanel:self]; } - (NSString *)findPanelNibName { return nil; } /* accessors */ - (void)setFindPanelController:(OgreFindPanelController*)aFindPanelController { [findPanelController autorelease]; findPanelController = [aFindPanelController retain]; } - (OgreFindPanelController*)findPanelController { return findPanelController; } - (void)setEscapeCharacter:(NSString*)character { [character retain]; [_escapeCharacter release]; _escapeCharacter = character; } - (NSString*)escapeCharacter { return _escapeCharacter; } - (void)setSyntax:(OgreSyntax)syntax { //NSLog(@"%d", [OGRegularExpression intValueForSyntax:syntax]); _syntax = syntax; } - (OgreSyntax)syntax { return _syntax; } /* 検索対象 */ - (void)setTargetToFindIn:(id)target { #ifdef DEBUG_OGRE_FIND_PANEL NSLog(@"-setTargetToFindIn:\"%@\" of %@", [target className], [self className]); #endif _targetToFindIn = target; } - (id)targetToFindIn { #ifdef DEBUG_OGRE_FIND_PANEL NSLog(@"-targetToFindIn of %@", [self className]); #endif id target = nil; [self setTargetToFindIn:nil]; [self setAdapterClassForTargetToFindIn:Nil]; /* responder chainにtellMeTargetToFindIn:を投げる */ if ([NSApp sendAction:@selector(tellMeTargetToFindIn:) to:nil from:self]) { // tellMeTargetToFindIn:に応答があった場合、 //NSLog(@"succeed to perform tellMeTargetToFindIn:"); if ([self hasAdapterClassForObject:_targetToFindIn]) target = _targetToFindIn; } else { // 応答がない場合、main windowのfirst responderがNSTextViewならばそれを採用する。 //NSLog(@"failed to perform tellMeTargetToFindIn:"); id anObject = [[NSApp mainWindow] firstResponder]; if (anObject != nil && [self hasAdapterClassForObject:anObject]) target = anObject; } return target; } - (BOOL)isBusyTarget:(id)target { return [_busyTargetArray containsObject:target]; } - (void)makeTargetBusy:(id)target { if (target != nil) [_busyTargetArray addObject:target]; } - (void)makeTargetFree:(id)target { if (target != nil) [_busyTargetArray removeObject:target]; } /* Find/Replace/Highlight... */ - (OgreTextFindResult*)find:(NSString*)expressionString options:(unsigned)options fromTop:(BOOL)isFromTop forward:(BOOL)forward wrap:(BOOL)isWrap { id target = [self targetToFindIn]; if ((target == nil) || [self isBusyTarget:target]) { if (target == nil) { NSLog(@"No target"); } else { NSLog(@"Busy target"); } // NSLog(@"No target or busy target"); return [OgreTextFindResult textFindResultWithTarget:target thread:nil]; } [self makeTargetBusy:target]; OgreFindThread *thread = nil; OgreTextFindProgressSheet *sheet = nil; OgreTextFindResult *textFindResult = nil; NS_DURING OGRegularExpression *regex = [OGRegularExpression regularExpressionWithString:expressionString options:options syntax:[self syntax] escapeCharacter:[self escapeCharacter]]; /* スレッドの生成 */ id adapter = [self adapterForTarget:target]; thread = [[[OgreFindThread alloc] initWithComponent:adapter] autorelease]; [thread setRegularExpression:regex]; [thread setOptions:options]; [thread setWrap:isWrap]; [thread setBackward:!forward]; [thread setFromTop:isFromTop]; [thread setInSelection:NO]; [thread setAsynchronous:NO]; [thread detach]; [self makeTargetFree:target]; textFindResult = [thread result]; NS_HANDLER textFindResult = [OgreTextFindResult textFindResultWithTarget:target thread:thread]; [textFindResult setType:OgreTextFindResultError]; [textFindResult setAlertSheet:sheet exception:localException]; NS_ENDHANDLER return textFindResult; } - (OgreTextFindResult*)findAll:(NSString*)expressionString color:(NSColor*)highlightColor options:(unsigned)options inSelection:(BOOL)inSelection { #ifdef DEBUG_OGRE_FIND_PANEL NSLog(@"-findAll:... of %@", [self className]); #endif id target = [self targetToFindIn]; if ((target == nil) || [self isBusyTarget:target]) return [OgreTextFindResult textFindResultWithTarget:target thread:nil]; [self makeTargetBusy:target]; OgreTextFindThread *thread = nil; OgreTextFindProgressSheet *sheet = nil; OgreTextFindResult *textFindResult = nil; NS_DURING OGRegularExpression *regex = [OGRegularExpression regularExpressionWithString:expressionString options:options syntax:[self syntax] escapeCharacter:[self escapeCharacter]]; /* 処理状況表示用シートの生成 */ sheet = [[OgreTextFindProgressSheet alloc] initWithWindow:[(NSView *)target window] title:OgreTextFinderLocalizedString(@"Find All") didEndSelector:@selector(makeTargetFree:) toTarget:self withObject:target]; /* スレッドの生成 */ id adapter = [self adapterForTarget:target]; thread = [[[OgreFindAllThread alloc] initWithComponent:adapter] autorelease]; [thread setRegularExpression:regex]; [thread setHighlightColor:highlightColor]; [thread setOptions:options]; [thread setInSelection:inSelection]; [thread setDidEndSelector:@selector(didEndThread:) toTarget:self]; [thread setProgressDelegate:sheet]; [thread setAsynchronous:YES]; [thread detach]; textFindResult = [OgreTextFindResult textFindResultWithTarget:target thread:thread]; [textFindResult setType:OgreTextFindResultSuccess]; NS_HANDLER textFindResult = [OgreTextFindResult textFindResultWithTarget:target thread:thread]; [textFindResult setType:OgreTextFindResultError]; [textFindResult setAlertSheet:sheet exception:localException]; NS_ENDHANDLER return textFindResult; } - (OgreTextFindResult*)replace:(NSString*)expressionString withString:(NSString*)replaceString options:(unsigned)options { return [self replaceAndFind:[OGPlainString stringWithString:expressionString] withOGString:[OGPlainString stringWithString:replaceString] options:options replacingOnly:YES wrap:NO]; } - (OgreTextFindResult*)replace:(NSString*)expressionString withAttributedString:(NSAttributedString*)replaceString options:(unsigned)options { return [self replaceAndFind:[OGPlainString stringWithString:expressionString] withOGString:[OGAttributedString stringWithAttributedString:replaceString] options:options replacingOnly:YES wrap:NO]; } - (OgreTextFindResult*)replace:(NSObject*)expressionString withOGString:(NSObject*)replaceString options:(unsigned)options { return [self replaceAndFind:expressionString withOGString:replaceString options:options replacingOnly:YES wrap:NO]; } - (OgreTextFindResult*)replaceAndFind:(NSString*)expressionString withString:(NSString*)replaceString options:(unsigned)options replacingOnly:(BOOL)replacingOnly wrap:(BOOL)isWrap { return [self replaceAndFind:[OGPlainString stringWithString:expressionString] withOGString:[OGPlainString stringWithString:replaceString] options:options replacingOnly:replacingOnly wrap:isWrap]; } - (OgreTextFindResult*)replaceAndFind:(NSString*)expressionString withAttributedString:(NSAttributedString*)replaceString options:(unsigned)options replacingOnly:(BOOL)replacingOnly wrap:(BOOL)isWrap { return [self replaceAndFind:[OGPlainString stringWithString:expressionString] withOGString:[OGAttributedString stringWithAttributedString:replaceString] options:options replacingOnly:replacingOnly wrap:isWrap]; } - (OgreTextFindResult*)replaceAndFind:(NSObject*)expressionString withOGString:(NSObject*)replaceString options:(unsigned)options replacingOnly:(BOOL)replacingOnly wrap:(BOOL)isWrap { #ifdef DEBUG_OGRE_FIND_PANEL NSLog(@"-replaceAndFind:... of %@", [self className]); #endif id target = [self targetToFindIn]; if ((target == nil) || [self isBusyTarget:target] /*|| ![target isEditable]*/) return [OgreTextFindResult textFindResultWithTarget:target thread:nil]; [self makeTargetBusy:target]; OgreReplaceAndFindThread *thread = nil; OgreTextFindProgressSheet *sheet = nil; OgreTextFindResult *textFindResult = nil; NS_DURING OGRegularExpression *regex = [OGRegularExpression regularExpressionWithString:[expressionString string] options:options syntax:[self syntax] escapeCharacter:[self escapeCharacter]]; OGReplaceExpression *repex = [OGReplaceExpression replaceExpressionWithOGString:replaceString options:options syntax:[self syntax] escapeCharacter:[self escapeCharacter]]; // スレッドの生成 id adapter = [self adapterForTarget:target]; thread = [[[OgreReplaceAndFindThread alloc] initWithComponent:adapter] autorelease]; [thread setRegularExpression:regex]; [thread setReplaceExpression:repex]; [thread setOptions:options]; [thread setInSelection:NO]; [thread setAsynchronous:NO]; [thread setReplacingOnly:replacingOnly]; [thread setWrap:isWrap]; [thread detach]; [self makeTargetFree:target]; textFindResult = [thread result]; NS_HANDLER textFindResult = [OgreTextFindResult textFindResultWithTarget:target thread:thread]; [textFindResult setType:OgreTextFindResultError]; [textFindResult setAlertSheet:sheet exception:localException]; NS_ENDHANDLER return textFindResult; } - (OgreTextFindResult*)replaceAll:(NSString*)expressionString withString:(NSString*)replaceString options:(unsigned)options inSelection:(BOOL)inSelection { return [self replaceAll:[OGPlainString stringWithString:expressionString] withOGString:[OGPlainString stringWithString:replaceString] options:options inSelection:inSelection]; } - (OgreTextFindResult*)replaceAll:(NSString*)expressionString withAttributedString:(NSAttributedString*)replaceString options:(unsigned)options inSelection:(BOOL)inSelection { return [self replaceAll:[OGPlainString stringWithString:expressionString] withOGString:[OGAttributedString stringWithAttributedString:replaceString] options:options inSelection:inSelection]; } - (OgreTextFindResult*)replaceAll:(NSObject*)expressionString withOGString:(NSObject*)replaceString options:(unsigned)options inSelection:(BOOL)inSelection { #ifdef DEBUG_OGRE_FIND_PANEL NSLog(@"-replaceAll:... of %@", [self className]); #endif id target = [self targetToFindIn]; if ((target == nil) || [self isBusyTarget:target] /*|| ![target isEditable]*/) return [OgreTextFindResult textFindResultWithTarget:target thread:nil]; [self makeTargetBusy:target]; OgreTextFindThread *thread = nil; OgreTextFindProgressSheet *sheet = nil; OgreTextFindResult *textFindResult = nil; NS_DURING OGRegularExpression *regex = [OGRegularExpression regularExpressionWithString:[expressionString string] options:options syntax:[self syntax] escapeCharacter:[self escapeCharacter]]; OGReplaceExpression *repex = [OGReplaceExpression replaceExpressionWithOGString:replaceString options:options syntax:[self syntax] escapeCharacter:[self escapeCharacter]]; /* 処理状況表示用シートの生成 */ sheet = [[OgreTextFindProgressSheet alloc] initWithWindow:[(NSView *)target window] title:OgreTextFinderLocalizedString(@"Replace All") didEndSelector:@selector(makeTargetFree:) toTarget:self withObject:target]; /* スレッドの生成 */ id adapter = [self adapterForTarget:target]; thread = [[[OgreReplaceAllThread alloc] initWithComponent:adapter] autorelease]; [thread setRegularExpression:regex]; [thread setReplaceExpression:repex]; [thread setOptions:options]; [thread setInSelection:inSelection]; [thread setDidEndSelector:@selector(didEndThread:) toTarget:self]; [thread setProgressDelegate:sheet]; [thread setAsynchronous:YES]; [thread detach]; textFindResult = [OgreTextFindResult textFindResultWithTarget:target thread:thread]; [textFindResult setType:OgreTextFindResultSuccess]; NS_HANDLER textFindResult = [OgreTextFindResult textFindResultWithTarget:target thread:thread]; [textFindResult setType:OgreTextFindResultError]; [textFindResult setAlertSheet:sheet exception:localException]; NS_ENDHANDLER return textFindResult; } - (OgreTextFindResult*)unhightlight { #ifdef DEBUG_OGRE_FIND_PANEL NSLog(@"-unhightlight:... of %@", [self className]); #endif id target = [self targetToFindIn]; if ((target == nil) || [self isBusyTarget:target]) return [OgreTextFindResult textFindResultWithTarget:target thread:nil]; [self makeTargetBusy:target]; OgreTextFindThread *thread = nil; OgreTextFindResult *textFindResult = nil; NS_DURING /* スレッドの生成 */ id adapter = [self adapterForTarget:target]; thread = [[[OgreUnhighlightThread alloc] initWithComponent:adapter] autorelease]; [thread setAsynchronous:NO]; [thread detach]; [self makeTargetFree:target]; textFindResult = [thread result]; NS_HANDLER textFindResult = [OgreTextFindResult textFindResultWithTarget:target thread:thread]; [textFindResult setType:OgreTextFindResultError]; [textFindResult setAlertSheet:nil exception:localException]; NS_ENDHANDLER return textFindResult; } - (OgreTextFindResult*)hightlight:(NSString*)expressionString color:(NSColor*)highlightColor options:(unsigned)options inSelection:(BOOL)inSelection { #ifdef DEBUG_OGRE_FIND_PANEL NSLog(@"-hightlight:... of %@", [self className]); #endif id target = [self targetToFindIn]; if ((target == nil) || [self isBusyTarget:target]) return [OgreTextFindResult textFindResultWithTarget:target thread:nil]; [self makeTargetBusy:target]; OgreTextFindThread *thread = nil; OgreTextFindProgressSheet *sheet = nil; OgreTextFindResult *textFindResult = nil; NS_DURING OGRegularExpression *regex = [OGRegularExpression regularExpressionWithString:expressionString options:options syntax:[self syntax] escapeCharacter:[self escapeCharacter]]; /* 処理状況表示用シートの生成 */ sheet = [[OgreTextFindProgressSheet alloc] initWithWindow:[(NSView *)target window] title:OgreTextFinderLocalizedString(@"Highlight") didEndSelector:@selector(makeTargetFree:) toTarget:self withObject:target]; /* スレッドの生成 */ id adapter = [self adapterForTarget:target]; thread = [[[OgreHighlightThread alloc] initWithComponent:adapter] autorelease]; [thread setRegularExpression:regex]; [thread setHighlightColor:highlightColor]; [thread setOptions:options]; [thread setInSelection:inSelection]; [thread setDidEndSelector:@selector(didEndThread:) toTarget:self]; [thread setProgressDelegate:sheet]; [thread setAsynchronous:YES]; [thread detach]; textFindResult = [OgreTextFindResult textFindResultWithTarget:target thread:thread]; [textFindResult setType:OgreTextFindResultSuccess]; NS_HANDLER textFindResult = [OgreTextFindResult textFindResultWithTarget:target thread:thread]; [textFindResult setType:OgreTextFindResultError]; [textFindResult setAlertSheet:sheet exception:localException]; NS_ENDHANDLER return textFindResult; } /* selection */ - (NSString*)selectedString { return [[self selectedOGString] string]; } - (NSAttributedString*)selectedAttributedString { return [[self selectedOGString] attributedString]; } - (NSObject*)selectedOGString { id target = [self targetToFindIn]; if ((target == nil) || [self isBusyTarget:target]) return nil; [self makeTargetBusy:target]; OgreTextFindLeaf *selectedLeaf = nil; NSObject *string = nil; OgreTextFindResult *textFindResult = nil; NS_DURING id adapter = [self adapterForTarget:target]; selectedLeaf = [adapter selectedLeaf]; [selectedLeaf willProcessFinding:nil]; string = [[selectedLeaf ogString] substringWithRange:[selectedLeaf selectedRange]]; [selectedLeaf finalizeFinding]; [self makeTargetFree:target]; NS_HANDLER textFindResult = [OgreTextFindResult textFindResultWithTarget:target thread:nil]; [textFindResult setType:OgreTextFindResultError]; [textFindResult setAlertSheet:nil exception:localException]; [textFindResult alertIfErrorOccurred]; NS_ENDHANDLER return string; } - (BOOL)isSelectionEmpty { id target = [self targetToFindIn]; if ((target == nil) || [self isBusyTarget:target]) return NO; [self makeTargetBusy:target]; OgreTextFindLeaf *selectedLeaf = nil; NSRange selectedRange = NSMakeRange(0, 0); OgreTextFindResult *textFindResult = nil; NS_DURING id adapter = [self adapterForTarget:target]; selectedLeaf = [adapter selectedLeaf]; [selectedLeaf willProcessFinding:nil]; selectedRange = [selectedLeaf selectedRange]; [selectedLeaf finalizeFinding]; [self makeTargetFree:target]; NS_HANDLER textFindResult = [OgreTextFindResult textFindResultWithTarget:target thread:nil]; [textFindResult setType:OgreTextFindResultError]; [textFindResult setAlertSheet:nil exception:localException]; [textFindResult alertIfErrorOccurred]; NS_ENDHANDLER if (selectedRange.length > 0) return NO; return YES; } - (BOOL)jumpToSelection { id target = [self targetToFindIn]; if ((target == nil) || [self isBusyTarget:target]) return NO; [self makeTargetBusy:target]; OgreTextFindLeaf *selectedLeaf = nil; OgreTextFindResult *textFindResult = nil; NS_DURING id adapter = [self adapterForTarget:target]; selectedLeaf = [adapter selectedLeaf]; [selectedLeaf willProcessFinding:nil]; [[(id )adapter window] makeKeyAndOrderFront:self]; [selectedLeaf jumpToSelection]; [selectedLeaf finalizeFinding]; [self makeTargetFree:target]; NS_HANDLER textFindResult = [OgreTextFindResult textFindResultWithTarget:target thread:nil]; [textFindResult setType:OgreTextFindResultError]; [textFindResult setAlertSheet:nil exception:localException]; [textFindResult alertIfErrorOccurred]; NS_ENDHANDLER return YES; } /* notify from Thread */ - (void)didEndThread:(OgreTextFindThread*)aTextFindThread { #ifdef DEBUG_OGRE_FIND_PANEL NSLog(@"-didEndThread of %@", [self className]); #endif BOOL shouldCloseProgressSheet = NO; SEL didEndSelector = [aTextFindThread didEndSelectorForFindPanelController]; id result = [aTextFindThread result]; shouldCloseProgressSheet = (BOOL)(!![findPanelController performSelector:didEndSelector withObject:result]); id sheet = [aTextFindThread progressDelegate]; if (shouldCloseProgressSheet) { // 自動的に閉じる。OKボタンではreleaseしないようにする。 [(id )sheet setReleaseWhenOKButtonClicked:NO]; [sheet performSelector:@selector(close:) withObject:self]; } [sheet release]; } /* alert sheet */ - (OgreTextFindProgressSheet*)alertSheetOnTarget:(id)aTerget { OgreTextFindProgressSheet *sheet = nil; if ((aTerget != nil) && ![self isBusyTarget:aTerget]) { [self makeTargetBusy:aTerget]; sheet = [[OgreTextFindProgressSheet alloc] initWithWindow:[(NSView *)aTerget window] title:@"" didEndSelector:@selector(makeTargetFree:) toTarget:self withObject:aTerget]; } return sheet; } /* Getting and registering adapters for targets */ - (id)adapterForTarget:(id)aTargetToFindIn { if ([aTargetToFindIn respondsToSelector:@selector(ogreAdapter)]) return [(id )aTargetToFindIn ogreAdapter]; Class anAdapterClass = [self adapterClassForTargetToFindIn]; if (anAdapterClass == Nil) { /* Searching in the adapter-target array */ int index, count = [_adapterClassArray count]; for (index = count - 1; index >= 0; index--) { if ([aTargetToFindIn isKindOfClass:[_targetClassArray objectAtIndex:index]]) { anAdapterClass = [_adapterClassArray objectAtIndex:index]; break; } } } return [[[anAdapterClass alloc] initWithTarget:aTargetToFindIn] autorelease]; } - (void)registeringAdapterClass:(Class)anAdapterClass forTargetClass:(Class)aTargetClass { [_adapterClassArray addObject:anAdapterClass]; [_targetClassArray addObject:aTargetClass]; } - (void)setAdapterClassForTargetToFindIn:(Class)adapterClass { _adapterClassForTarget = adapterClass; } - (Class)adapterClassForTargetToFindIn; { return _adapterClassForTarget; } - (BOOL)hasAdapterClassForObject:(id)anObject { if (anObject == nil) return NO; if ([anObject respondsToSelector:@selector(ogreAdapter)]) return YES; int index, count = [_targetClassArray count]; for (index = count - 1; index >= 0; index--) { if ([anObject isKindOfClass:[_targetClassArray objectAtIndex:index]]) { return YES; break; } } return NO; } @end