Revision: 2693 http://skim-app.svn.sourceforge.net/skim-app/?rev=2693&view=rev Author: hofman Date: 2007-08-21 10:04:05 -0700 (Tue, 21 Aug 2007)
Log Message: ----------- Rewrite type select, bit more modular. Allow to repeat a search by typing '/' (in the note table). Modified Paths: -------------- trunk/SKNoteOutlineView.m trunk/SKTypeSelectHelper.h trunk/SKTypeSelectHelper.m Modified: trunk/SKNoteOutlineView.m =================================================================== --- trunk/SKNoteOutlineView.m 2007-08-21 16:09:14 UTC (rev 2692) +++ trunk/SKNoteOutlineView.m 2007-08-21 17:04:05 UTC (rev 2693) @@ -89,6 +89,8 @@ [self delete:self]; else if (typeSelectHelper && modifiers == 0 && [[NSCharacterSet alphanumericCharacterSet] characterIsMember:eventChar]) [typeSelectHelper processKeyDownCharacter:eventChar]; + else if (typeSelectHelper && modifiers == 0 && eventChar == '/') + [typeSelectHelper repeatSearch]; else [super keyDown:theEvent]; } Modified: trunk/SKTypeSelectHelper.h =================================================================== --- trunk/SKTypeSelectHelper.h 2007-08-21 16:09:14 UTC (rev 2692) +++ trunk/SKTypeSelectHelper.h 2007-08-21 17:04:05 UTC (rev 2693) @@ -54,6 +54,7 @@ NSArray *searchCache; NSMutableString *searchString; NSTimer *timer; + BOOL processing; } - (id)dataSource; @@ -73,6 +74,7 @@ - (BOOL)isProcessing; - (void)processKeyDownCharacter:(unichar)character; +- (void)repeatSearch; @end Modified: trunk/SKTypeSelectHelper.m =================================================================== --- trunk/SKTypeSelectHelper.m 2007-08-21 16:09:14 UTC (rev 2692) +++ trunk/SKTypeSelectHelper.m 2007-08-21 17:04:05 UTC (rev 2693) @@ -38,9 +38,14 @@ #import "SKTypeSelectHelper.h" +#define TIMEOUT 0.7 @interface SKTypeSelectHelper (SKPrivate) -- (void)typeSelectSearchTimeout; +- (void)searchWithStickyMatch:(BOOL)allowUpdate; +- (void)stopTimer; +- (void)startTimerForSelector:(SEL)selector; +- (void)typeSelectSearchTimeout:(NSTimer *)aTimer; +- (void)typeSelectCleanTimeout:(NSTimer *)aTimer; - (unsigned int)indexOfMatchedItemAfterIndex:(unsigned int)selectedIndex; @end @@ -50,32 +55,32 @@ - (id)init { if (self = [super init]){ + searchString = [[NSMutableString alloc] init]; cycleResults = YES; - matchesImmediately = NO; + matchesImmediately = YES; matchOption = SKPrefixMatch; } return self; } - (void)dealloc { - [timer invalidate]; - [timer release]; + [self stopTimer]; [searchString release]; [searchCache release]; [super dealloc]; } -// API +#pragma mark Accessors + - (id)dataSource { return dataSource; } - (void)setDataSource:(id)newDataSource { - if (dataSource == newDataSource) - return; - - dataSource = newDataSource; - [self rebuildTypeSelectSearchCache]; + if (dataSource != newDataSource) { + dataSource = newDataSource; + [self rebuildTypeSelectSearchCache]; + } } - (BOOL)cyclesSimilarResults { @@ -102,6 +107,12 @@ matchOption = newValue; } +- (BOOL)isProcessing { + return processing; +} + +#pragma mark API + - (void)rebuildTypeSelectSearchCache { if (searchCache) [searchCache release]; @@ -110,13 +121,9 @@ } - (void)processKeyDownCharacter:(unichar)character { - NSString *selectedItem = nil; - unsigned int selectedIndex, foundIndex; + if (processing == NO) + [searchString setString:@""]; - // Create the search string the first time around - if (searchString == nil) - searchString = [[NSMutableString alloc] init]; - // Append the new character to the search string [searchString appendFormat:@"%C", character]; @@ -124,51 +131,59 @@ [dataSource typeSelectHelper:self updateSearchString:searchString]; // Reset the timer if it hasn't expired yet - NSDate *date = [NSDate dateWithTimeIntervalSinceNow:0.7]; + [self startTimerForSelector:@selector(typeSelectSearchTimeout:)]; + + if (matchesImmediately) + [self searchWithStickyMatch:processing]; + + processing = YES; +} + +- (void)repeatSearch { + [self searchWithStickyMatch:NO]; + + if ([searchString length] && [dataSource respondsToSelector:@selector(typeSelectHelper:updateSearchString:)]) + [dataSource typeSelectHelper:self updateSearchString:searchString]; + + [self startTimerForSelector:@selector(typeSelectCleanTimeout:)]; + + processing = NO; +} + [EMAIL PROTECTED] + +#pragma mark - + [EMAIL PROTECTED] SKTypeSelectHelper (SKPrivate) + +- (void)stopTimer { [timer invalidate]; [timer release]; timer = nil; - timer = [[NSTimer alloc] initWithFireDate:date interval:0 target:self selector:@selector(typeSelectSearchTimeout:) userInfo:NULL repeats:NO]; +} + +- (void)startTimerForSelector:(SEL)selector { + [self stopTimer]; + timer = [[NSTimer alloc] initWithFireDate:[NSDate dateWithTimeIntervalSinceNow:TIMEOUT] interval:0 target:self selector:selector userInfo:NULL repeats:NO]; [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode]; - - if (matchesImmediately) { - if (cycleResults) { - selectedIndex = [dataSource typeSelectHelperCurrentlySelectedIndex:self]; - if (selectedIndex < [searchCache count]) - selectedItem = [searchCache objectAtIndex:selectedIndex]; - else - selectedIndex = NSNotFound; - - // Avoid flashing a selection all over the place while you're still typing the thing you have selected - if (matchOption == SKFullStringMatch) { - if ([selectedItem caseInsensitiveCompare:searchString] == NSOrderedSame) - return; - } else { - unsigned int searchStringLength = [searchString length]; - unsigned int selectedItemLength = [selectedItem length]; - NSRange range = NSMakeRange(0, matchOption == SKPrefixMatch ? searchStringLength : selectedItemLength); - if (searchStringLength > 1 && selectedItemLength >= searchStringLength && [selectedItem rangeOfString:searchString options:NSCaseInsensitiveSearch range:range].location != NSNotFound) - return; - } - - } else { - selectedIndex = NSNotFound; - } - - foundIndex = [self indexOfMatchedItemAfterIndex:selectedIndex]; - - if (foundIndex != NSNotFound) - [dataSource typeSelectHelper:self selectItemAtIndex:foundIndex]; - } } -- (BOOL)isProcessing { - return timer != nil; +- (void)typeSelectSearchTimeout:(NSTimer *)aTimer { + if (matchesImmediately == NO) + [self searchWithStickyMatch:NO]; + [self typeSelectCleanTimeout:aTimer]; } -- (void)typeSelectSearchTimeout:(NSTimer *)aTimer { - if (matchesImmediately == NO && [searchString length]) { - unsigned int selectedIndex, foundIndex; +- (void)typeSelectCleanTimeout:(NSTimer *)aTimer { + if ([dataSource respondsToSelector:@selector(typeSelectHelper:updateSearchString:)]) + [dataSource typeSelectHelper:self updateSearchString:nil]; + [self stopTimer]; + processing = NO; +} + +- (void)searchWithStickyMatch:(BOOL)sticky { + if ([searchString length]) { + unsigned int selectedIndex, startIndex, foundIndex; if (cycleResults) { selectedIndex = [dataSource typeSelectHelperCurrentlySelectedIndex:self]; @@ -177,18 +192,17 @@ } else { selectedIndex = NSNotFound; } - foundIndex = [self indexOfMatchedItemAfterIndex:selectedIndex]; - if (foundIndex != NSNotFound) + + startIndex = selectedIndex; + if (sticky && selectedIndex != NSNotFound) + startIndex = startIndex > 0 ? startIndex - 1 : [searchCache count] - 1; + + foundIndex = [self indexOfMatchedItemAfterIndex:startIndex]; + + // Avoid flashing a selection all over the place while you're still typing the thing you have selected + if (foundIndex != NSNotFound && foundIndex != selectedIndex) [dataSource typeSelectHelper:self selectItemAtIndex:foundIndex]; } - - if ([dataSource respondsToSelector:@selector(typeSelectHelper:updateSearchString:)]) - [dataSource typeSelectHelper:self updateSearchString:nil]; - [timer invalidate]; - [timer release]; - timer = nil; - [searchString release]; - searchString = nil; } - (unsigned int)indexOfMatchedItemAfterIndex:(unsigned int)selectedIndex { 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: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ Skim-app-commit mailing list Skim-app-commit@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/skim-app-commit