2 Smultron version 3.1, 2007-05-19
3 Written by Peter Borg, pgw3@mac.com
4 Find the latest version at http://smultron.sourceforge.net
6 Copyright 2004-2007 Peter Borg
7 Adapted for SuperCollider by Jan Trutzschler
9 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
11 http://www.apache.org/licenses/LICENSE-2.0
13 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
15 #define U_HIDE_DRAFT_API 1
16 #import "SMLAdvancedFindController.h"
17 #define __LP64__ false
18 //#define SMLCurrentDocument [[NSApp mainWindow] firstResponder]
19 #import "ICUPattern.h"
20 #import "ICUMatcher.h"
21 #import "SCTextView.h"
22 #import "SMLStatusBarTextFieldCell.h"
25 @implementation SMLAdvancedFindController
27 static id sharedInstance = nil;
29 + (SMLAdvancedFindController *)sharedInstance
31 if (sharedInstance == nil) {
32 sharedInstance = [[self alloc] init];
35 return sharedInstance;
41 if (sharedInstance != nil) {
44 sharedInstance = [super init];
45 mContents = [[NSMutableArray alloc] init];
47 return sharedInstance;
50 - (NSMutableArray*) contents
55 - (void) setContents: (NSArray *)newContents
57 if (mContents != newContents)
59 [mContents autorelease];
60 mContents = [[NSMutableArray alloc] initWithArray:newContents];
64 - (IBAction)findAction:(id)sender
66 NSString *searchString = [findSearchField stringValue];
67 BOOL useRegularExpressions = (BOOL) [setUseRegularExpressionsButton state];
68 BOOL ignoreCaseAdvancedFind = (BOOL) [setIgnoreCaseButton state];
69 BOOL onlyInSelectionAdvancedFind = (BOOL) [setSearchInSelectionButton state];
71 [findResultsOutlineView setDelegate:nil];
73 [findResultsTreeController setContent:nil];
74 [findResultsTreeController setContent:[NSArray array]];
75 [mContents autorelease];
76 mContents = [[NSMutableArray alloc] init];
79 NSMutableArray *recentSearches = [[[NSMutableArray alloc] initWithArray:[findSearchField recentSearches]] autorelease];
80 if ([recentSearches indexOfObject:searchString] != NSNotFound) {
81 [recentSearches removeObject:searchString];
83 [recentSearches insertObject:searchString atIndex:0];
84 if ([recentSearches count] > 15) {
85 [recentSearches removeLastObject];
87 [findSearchField setRecentSearches:recentSearches];
89 NSInteger searchStringLength = [searchString length];
90 if (!searchStringLength > 0 ) {
95 NSString *completeString;
96 NSInteger completeStringLength;
97 NSInteger startLocation;
98 NSInteger resultsInThisDocument = 0;
101 NSInteger numberOfResults = 0;
104 NSIndexPath *folderIndexPath;
105 NSMutableDictionary *node;
107 NSEnumerator *enumerator = [self scopeEnumerator];
109 NSInteger documentIndex = 0;
111 while (document = [enumerator nextObject]) {
112 node = [NSMutableDictionary dictionary];
113 // if ([[SMLDefaults valueForKey:@"ShowFullPathInWindowTitle"] boolValue] == YES) {
114 // [node setValue:[document valueForKey:@"nameWithPath"] forKey:@"displayString"];
116 [node setValue:[document displayName] forKey:@"displayString"];
119 [node setValue:[NSNumber numberWithBool:NO] forKey:@"isLeaf"];
121 folderIndexPath = [[[NSIndexPath alloc] initWithIndex:documentIndex] autorelease];
122 [findResultsTreeController insertObject:node atArrangedObjectIndexPath:folderIndexPath];
125 completeString = [[document textView] string];
126 searchRange = [[document textView] selectedRange];
127 completeStringLength = [completeString length];
129 if (onlyInSelectionAdvancedFind == NO || searchRange.length == 0) {
130 searchRange = NSMakeRange(0, completeStringLength);
132 startLocation = searchRange.location;
133 resultsInThisDocument = 0;
135 if (useRegularExpressions) {
138 if (ignoreCaseAdvancedFind) {
139 pattern = [[ICUPattern alloc] initWithString:searchString flags:(CaseInsensitiveMatching | Multiline)];
141 pattern = [[ICUPattern alloc] initWithString:searchString flags:Multiline];
144 @catch (NSException *exception) {
145 [self alertThatThisIsNotAValidRegularExpression:searchString];
151 if ([completeString length] > 0) { // Otherwise ICU throws an exception
153 if (onlyInSelectionAdvancedFind == NO || searchRange.length == 0) {
154 matcher = [[[ICUMatcher alloc] initWithPattern:pattern overString:completeString] autorelease];
156 matcher = [[[ICUMatcher alloc] initWithPattern:pattern overString:[completeString substringWithRange:searchRange]] autorelease];
160 while ([matcher findNext]) {
161 NSInteger foundLocation = [matcher rangeOfMatch].location + startLocation;
162 for (index = 0, lineNumber = 0; index <= foundLocation; lineNumber++) {
164 index = NSMaxRange([completeString lineRangeForRange:NSMakeRange(index, 0)]);
165 if (indexTemp == index) {
166 index++; // Make sure it moves forward if it is stuck when searching e.g. for [ \t\n]*
170 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
171 NSRange rangeMatch = NSMakeRange([matcher rangeOfMatch].location + searchRange.location, [matcher rangeOfMatch].length);
172 [findResultsTreeController insertObject:[self preparedResultDictionaryFromString:completeString searchStringLength:searchStringLength range:rangeMatch lineNumber:lineNumber document:document] atArrangedObjectIndexPath:[folderIndexPath indexPathByAddingIndex:resultsInThisDocument]];
175 resultsInThisDocument++;
180 while (startLocation < completeStringLength) {
181 if (ignoreCaseAdvancedFind) {
182 foundRange = [completeString rangeOfString:searchString options:NSCaseInsensitiveSearch range:NSMakeRange(startLocation, NSMaxRange(searchRange) - startLocation)];
184 foundRange = [completeString rangeOfString:searchString options:NSLiteralSearch range:NSMakeRange(startLocation, NSMaxRange(searchRange) - startLocation)];
187 if (foundRange.location == NSNotFound) {
190 for (index = 0, lineNumber = 0; index <= foundRange.location; lineNumber++) {
191 index = NSMaxRange([completeString lineRangeForRange:NSMakeRange(index, 0)]);
194 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
195 // NSLog(@"found range: %i, lineNumber: %i", foundRange.length, lineNumber);
196 [findResultsTreeController insertObject:[self preparedResultDictionaryFromString:completeString searchStringLength:searchStringLength range:foundRange lineNumber:lineNumber document:document] atArrangedObjectIndexPath:[folderIndexPath indexPathByAddingIndex:resultsInThisDocument]];
201 resultsInThisDocument++;
202 startLocation = NSMaxRange(foundRange);
205 if (resultsInThisDocument == 0) {
206 [findResultsTreeController removeObjectAtArrangedObjectIndexPath:folderIndexPath];
209 numberOfResults += resultsInThisDocument;
214 NSString *searchResultString;
215 if (numberOfResults == 0) {
216 searchResultString = [NSString stringWithFormat:NSLocalizedString(@"Could not find a match for search-string %@", @"Could not find a match for search-string %@ in Advanced Find"), searchString];
217 } else if (numberOfResults == 1) {
218 searchResultString = [NSString stringWithFormat:NSLocalizedString(@"Found one match for search-string %@", @"Found one match for search-string %@ in Advanced Find"), searchString];
220 searchResultString = [NSString stringWithFormat:NSLocalizedString(@"Found %i matches for search-string %@", @"Found %i matches for search-string %@ in Advanced Find"), numberOfResults, searchString];
222 // NSLog(searchResultString);
223 [findResultTextField setStringValue:searchResultString];
225 [findResultsOutlineView setDelegate:self];
229 - (IBAction)replaceAction:(id)sender
231 NSString *searchString = [findSearchField stringValue];
232 NSString *replaceString = [replaceSearchField stringValue];
233 BOOL useRegularExpressions = (BOOL) [setUseRegularExpressionsButton state];
234 BOOL ignoreCaseAdvancedFind = (BOOL) [setIgnoreCaseButton state];
235 BOOL onlyInSelectionAdvancedFind = (BOOL) [setSearchInSelectionButton state];
237 NSMutableArray *recentSearches = [[[NSMutableArray alloc] initWithArray:[findSearchField recentSearches]] autorelease];
238 if ([recentSearches indexOfObject:searchString] != NSNotFound) {
239 [recentSearches removeObject:searchString];
241 [recentSearches insertObject:searchString atIndex:0];
242 if ([recentSearches count] > 15) {
243 [recentSearches removeLastObject];
245 [findSearchField setRecentSearches:recentSearches];
247 NSMutableArray *recentReplaces = [[[NSMutableArray alloc] initWithArray:[replaceSearchField recentSearches]] autorelease];
248 if ([recentReplaces indexOfObject:replaceString] != NSNotFound) {
249 [recentReplaces removeObject:replaceString];
251 [recentReplaces insertObject:replaceString atIndex:0];
252 if ([recentReplaces count] > 15) {
253 [recentReplaces removeLastObject];
255 [replaceSearchField setRecentSearches:recentReplaces];
257 NSInteger searchStringLength = [searchString length];
258 // [[NSApp mainWindow] firstResponder];
259 // if (!searchStringLength > 0 || SMLCurrentDocument == nil || SMLCurrentProject == nil) {
264 NSString *completeString;
265 NSInteger completeStringLength;
266 NSInteger startLocation;
267 NSInteger resultsInThisDocument = 0;
268 NSInteger numberOfResults = 0;
272 NSEnumerator *enumerator = [self scopeEnumerator];
275 while (document = [enumerator nextObject]) {
276 completeString = [[document textView] string];
277 searchRange = [[document textView] selectedRange];
278 completeStringLength = [completeString length];
279 // if(searchRange.length == 0) searchRange = NSMakeRange(0, completeStringLength);
281 if (onlyInSelectionAdvancedFind == NO || searchRange.length == 0) {
282 searchRange = NSMakeRange(0, completeStringLength);
285 startLocation = searchRange.location;
286 resultsInThisDocument = 0;
287 if (useRegularExpressions) {
290 if (ignoreCaseAdvancedFind) {
291 pattern = [[[ICUPattern alloc] initWithString:searchString flags:(CaseInsensitiveMatching | Multiline)] autorelease];
293 pattern = [[[ICUPattern alloc] initWithString:searchString flags:Multiline] autorelease];
296 @catch (NSException *exception) {
297 [self alertThatThisIsNotAValidRegularExpression:searchString];
304 if (onlyInSelectionAdvancedFind == NO || searchRange.length == 0) {
305 matcher = [[[ICUMatcher alloc] initWithPattern:pattern overString:completeString] autorelease];
307 matcher = [[[ICUMatcher alloc] initWithPattern:pattern overString:[completeString substringWithRange:searchRange]] autorelease];
311 while ([matcher findNext]) {
312 resultsInThisDocument++;
317 NSInteger searchLength;
319 if (onlyInSelectionAdvancedFind == NO || searchRange.length == 0) {
320 searchLength = completeStringLength;
322 searchLength = NSMaxRange(searchRange);
324 while (startLocation < searchLength) {
326 if (ignoreCaseAdvancedFind) {
327 foundRange = [completeString rangeOfString:searchString options:NSCaseInsensitiveSearch range:NSMakeRange(startLocation, NSMaxRange(searchRange) - startLocation)];
329 foundRange = [completeString rangeOfString:searchString options:NSLiteralSearch range:NSMakeRange(startLocation, NSMaxRange(searchRange) - startLocation)];
332 if (foundRange.location == NSNotFound) {
335 resultsInThisDocument++;
336 startLocation = NSMaxRange(foundRange);
340 numberOfResults += resultsInThisDocument;
343 if (numberOfResults == 0) {
344 [findResultTextField setObjectValue:[NSString stringWithFormat:NSLocalizedString(@"Could not find a match for search-string %@", @"Could not find a match for search-string %@ in Advanced Find"), searchString]];
350 if ([[SMLDefaults valueForKey:@"SuppressReplaceWarning"] boolValue] == YES) {
351 [self performNumberOfReplaces:numberOfResults];
355 NSString *defaultButton;
356 if ([replaceString length] > 0) {
357 if (numberOfResults != 1) {
358 title = [NSString stringWithFormat:NSLocalizedString(@"Are you sure that you want to replace %i occurrences of %@ with %@?", @"Ask if you are sure that you want to replace %i occurrences of %@ with %@ in ask-if-sure-you-want-to-replace-in-advanced-find-sheet"), numberOfResults, searchString, replaceString];
360 title = [NSString stringWithFormat:NSLocalizedString(@"Are you sure that you want to replace one occurrence of %@ with %@?", @"Ask if you are sure that you want to replace one occurrence of %@ with %@ in ask-if-sure-you-want-to-replace-in-advanced-find-sheet"), searchString, replaceString];
362 defaultButton = NSLocalizedString(@"Replace", @"Replace-button in ask-if-sure-you-want-to-replace-in-advanced-find-sheet");
364 if (numberOfResults != 1) {
365 title = [NSString stringWithFormat:NSLocalizedString(@"Are you sure that you want to delete %i occurrences of %@?", @"Ask if you are sure that you want to delete %i occurrences of %@ in ask-if-sure-you-want-to-replace-in-advanced-find-sheet"), numberOfResults, searchString, replaceString];
367 title = [NSString stringWithFormat:NSLocalizedString(@"Are you sure that you want to delete the one occurrence of %@?", @"Ask if you are sure that you want to delete the one occurrence of %@ in ask-if-sure-you-want-to-replace-in-advanced-find-sheet"), searchString, replaceString];
369 defaultButton = DELETEBUTTON;
372 NSBeginAlertSheet(title,
375 NSLocalizedString(@"Cancel", @"Cancel-button"),
378 @selector(replaceSheetDidEnd:returnCode:contextInfo:),
380 (void *)numberOfResults,
381 NSLocalizedString(@"Remember that you can always Undo any changes", @"Remember that you can always Undo any changes in ask-if-sure-you-want-to-replace-in-advanced-find-sheet"));
389 - (void)replaceSheetDidEnd:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo
392 if (returnCode == NSAlertDefaultReturn) { // Replace
393 [self performNumberOfReplaces:(NSInteger)contextInfo];
398 - (void)performNumberOfReplaces:(NSInteger)numberOfReplaces
400 NSString *searchString = [findSearchField stringValue];
401 NSString *replaceString = [replaceSearchField stringValue];
403 NSInteger completeStringLength;
404 BOOL useRegularExpressions = (BOOL) [setUseRegularExpressionsButton state];
405 BOOL ignoreCaseAdvancedFind = (BOOL) [setIgnoreCaseButton state];
406 BOOL onlyInSelectionAdvancedFind = (BOOL) [setSearchInSelectionButton state];
407 // NSLog(@"performNumberOfReplaces %i", numberOfReplaces);
409 NSEnumerator *enumerator = [self scopeEnumerator];
411 while (document = [enumerator nextObject]) {
412 NSTextView *textView = [document textView];
413 NSString *originalString = [NSString stringWithString:[textView string]];
414 NSMutableString *completeString = [NSMutableString stringWithString:[textView string]];
416 // completeString = [[document textView] string];
417 searchRange = [[document textView] selectedRange];
418 completeStringLength = [completeString length];
419 // if(searchRange.length == 0) searchRange = NSMakeRange(0, completeStringLength);
420 if (!onlyInSelectionAdvancedFind || searchRange.length == 0) {
421 searchRange = NSMakeRange(0, completeStringLength);
424 if (useRegularExpressions == YES) {
427 if (ignoreCaseAdvancedFind) {
428 pattern = [[ICUPattern alloc] initWithString:searchString flags:(CaseInsensitiveMatching | Multiline)];
430 pattern = [[ICUPattern alloc] initWithString:searchString flags:Multiline];
433 @catch (NSException *exception) {
434 [self alertThatThisIsNotAValidRegularExpression:searchString];
440 if (onlyInSelectionAdvancedFind== NO) {
441 matcher = [[[ICUMatcher alloc] initWithPattern:pattern overString:completeString] autorelease];
443 matcher = [[[ICUMatcher alloc] initWithPattern:pattern overString:[completeString substringWithRange:searchRange]] autorelease];
446 NSMutableString *regularExpressionReplaceString = [NSMutableString stringWithString:replaceString];
447 [regularExpressionReplaceString replaceOccurrencesOfString:@"\\n" withString:[NSString stringWithFormat:@"%C", 0x000A] options:NSLiteralSearch range:NSMakeRange(0, [regularExpressionReplaceString length])]; // It doesn't seem to work without this workaround
448 [regularExpressionReplaceString replaceOccurrencesOfString:@"\\r" withString:[NSString stringWithFormat:@"%C", 0x000D] options:NSLiteralSearch range:NSMakeRange(0, [regularExpressionReplaceString length])];
449 [regularExpressionReplaceString replaceOccurrencesOfString:@"\\t" withString:[NSString stringWithFormat:@"%C", 0x0009] options:NSLiteralSearch range:NSMakeRange(0, [regularExpressionReplaceString length])];
451 if (onlyInSelectionAdvancedFind == NO) {
452 [completeString setString:[matcher replaceAllWithString:regularExpressionReplaceString]];
454 [completeString replaceCharactersInRange:searchRange withString:[matcher replaceAllWithString:regularExpressionReplaceString]];
459 if (ignoreCaseAdvancedFind == YES) {
460 [completeString replaceOccurrencesOfString:searchString withString:replaceString options:NSCaseInsensitiveSearch range:searchRange];
462 [completeString replaceOccurrencesOfString:searchString withString:replaceString options:NSLiteralSearch range:searchRange];
467 NSRange selectedRange = [textView selectedRange];
468 if (![originalString isEqualToString:completeString] && [originalString length] != 0) {
469 if ([textView shouldChangeTextInRange:NSMakeRange(0, [[textView string] length]) replacementString:completeString]) { // Do it this way to mark it as an Undo
470 [textView replaceCharactersInRange:NSMakeRange(0, [[textView string] length]) withString:completeString];
471 [textView didChangeText];
475 if (selectedRange.location <= [[textView string] length]) {
476 [textView setSelectedRange:NSMakeRange(selectedRange.location, 0)];
480 if (numberOfReplaces != 1) {
481 [findResultTextField setObjectValue:[NSString stringWithFormat:NSLocalizedString(@"Replaced %i occurrences of %@ with %@", @"Indicate that we replaced %i occurrences of %@ with %@ in update-search-textField-after-replace"), numberOfReplaces, searchString, replaceString]];
483 [findResultTextField setObjectValue:[NSString stringWithFormat:NSLocalizedString(@"Replaced one occurrence of %@ with %@", @"Indicate that we replaced one occurrence of %@ with %@ in update-search-textField-after-replace"), searchString, replaceString]];
485 [findResultsTreeController setContent:nil];
486 [findResultsTreeController setContent:[NSArray array]];
487 [mContents autorelease];
488 mContents = [[NSMutableArray alloc] init];
490 [self removeCurrentlyDisplayedDocumentInAdvancedFind];
491 [advancedFindWindow makeKeyAndOrderFront:self];
495 - (void)showAdvancedFindWindow
497 if (advancedFindWindow == nil) {
498 [NSBundle loadNibNamed:@"SCAdvancedFind.nib" owner:self];
499 [advancedFindWindow makeKeyAndOrderFront:self];
501 // mScrollView = [mTextView superview];
502 // [mTextView removeFromSuperview];
504 SMLStatusBarTextFieldCell *statusBarTextFieldCell = [[SMLStatusBarTextFieldCell alloc] initTextCell:@""];
505 [findResultTextField setCell:statusBarTextFieldCell];
506 [findResultsOutlineView setBackgroundColor:[[NSColor controlAlternatingRowBackgroundColors] objectAtIndex:1]];
508 mSearchScope = SMLCurrentDocumentScope;
510 [allDocumentsScope setState:NSOffState];
511 [currentDocumentScope setState:NSOnState]; // If the user has clicked an already clicked button make sure it is on and not turned off
515 SMLAdvancedFindScope searchScope = [[SMLDefaults valueForKey:@"AdvancedFindScope"] intValue];
517 SMLAdvancedFindScope searchScope = SMLCurrentDocumentScope;
518 NSInteger distanceFromEdge = 26;
520 [currentDocumentScope setTitle:NSLocalizedStringFromTable(@"Current document", @"Localizable3", @"Current document")];
521 [currentDocumentScope sizeToFit];
522 [currentDocumentScope setFrameOrigin:NSMakePoint(distanceFromEdge, [currentDocumentScope frame].origin.y)];
523 [(SMLFilterBarButton *)currentDocumentScope frameDidChange:nil];
525 distanceFromEdge = distanceFromEdge + [currentDocumentScope bounds].size.width + 26;
527 [currentProjectScope setTitle:NSLocalizedStringFromTable(@"Current project", @"Localizable3", @"Current project")];
528 [currentProjectScope sizeToFit];
529 [currentProjectScope setFrameOrigin:NSMakePoint(distanceFromEdge, [currentProjectScope frame].origin.y)];
530 [(SMLFilterBarButton *)currentProjectScope frameDidChange:nil];
532 distanceFromEdge = distanceFromEdge + [currentProjectScope bounds].size.width + 26;
534 [allDocumentsScope setTitle:NSLocalizedStringFromTable(@"All documents", @"Localizable3", @"All documents")];
535 [allDocumentsScope sizeToFit];
536 [allDocumentsScope setFrameOrigin:NSMakePoint(distanceFromEdge, [allDocumentsScope frame].origin.y)];
537 [(SMLFilterBarButton *)allDocumentsScope frameDidChange:nil];
539 if (searchScope == SMLCurrentDocumentScope) {
540 [currentDocumentScope setState:NSOnState];
541 } else if (searchScope == SMLCurrentProjectScope) {
542 [currentProjectScope setState:NSOnState];
543 } else if (searchScope == SMLAllDocumentsScope) {
544 [allDocumentsScope setState:NSOnState];
547 [findResultsTreeController setContent:nil];
548 [findResultsTreeController setContent:[NSArray array]];
551 [advancedFindWindow makeKeyAndOrderFront:self];
555 - (void)outlineViewSelectionDidChange:(NSNotification *)aNotification
557 if ([[findResultsTreeController arrangedObjects] count] == 0) {
560 id object = [[findResultsTreeController selectedObjects] objectAtIndex:0];
561 if ([[object valueForKey:@"isLeaf"] boolValue] == NO) {
565 id document = [object valueForKey:@"document"];
566 if (document == nil) {
567 NSString *title = [NSString stringWithFormat:NSLocalizedString(@"The document %@ is no longer open", @"Indicate that the document %@ is no longer open in Document-is-no-longer-opened-after-selection-in-advanced-find-sheet"), [document valueForKey:@"name"]];
568 NSBeginAlertSheet(title,
569 NSLocalizedString(@"OK", @"OK-button"),
581 currentlyDisplayedDocumentInAdvancedFind = document;
584 [resultDocumentContentView addSubview:[document valueForKey:@"fourthTextScrollView"]];
585 if ([[document valueForKey:@"showLineNumberGutter"] boolValue] == YES) {
586 [resultDocumentContentView addSubview:[document valueForKey:@"fourthGutterScrollView"]];
589 [[document valueForKey:@"lineNumbers"] updateLineNumbersForClipView:[[document valueForKey:@"fourthTextScrollView"] contentView] checkWidth:YES recolour:YES]; // If the window has changed since the view was last visible
592 [self removeCurrentlyDisplayedDocumentInAdvancedFind];
594 NSRange selectRange = NSRangeFromString([[[findResultsTreeController selectedObjects] objectAtIndex:0] valueForKey:@"range"]);
595 NSString *completeString = [[document textView] string];
596 if (NSMaxRange(selectRange) > [completeString length]) {
600 [self insertDocumentIntoFourthContentView: document selectRange:selectRange ];
603 if ([[SMLDefaults valueForKey:@"FocusOnTextInAdvancedFind"] boolValue] == YES) {
604 [advancedFindWindow makeFirstResponder:[document valueForKey:@"fourthTextView"]];
609 - (void)insertDocumentIntoFourthContentView:(id)document selectRange: (NSRange) selectRange
612 int gutterWidth = 0; // no lineNumbers for now
613 if(!myWindowController) myWindowController = [[NSWindowController alloc] initWithWindow: [mScrollView window]];
614 NSTextStorage *textStorage = [[document textView] textStorage];
615 if(mCurrentDocument != (NSDocument*) document || mTextView == NULL){
616 mTextView = [[SCTextView alloc] initWithFrame:
617 [mScrollView bounds]];
618 [mTextView setAutoresizingMask: 63];
619 [[mTextView textContainer] setWidthTracksTextView: YES];
620 [mTextView setAllowsUndo: YES];
621 [mTextView setRichText: YES];
622 [mTextView setSmartInsertDeleteEnabled: NO];
623 [mTextView setImportsGraphics: YES];
624 [mTextView setFont: [NSFont fontWithName: @"Monaco" size: 9]];
626 [mTextView setLangClassToCall:@"Document"
627 withKeyDownActionIndex:4 withKeyUpActionIndex:5];
628 [mTextView setObjectKeyDownActionIndex:2 setObjectKeyUpActionIndex:1];
629 #if 1 //in order to have an SCTextView running a few methods would need to be moved from MyDocument to SCTextView
630 [mTextView setDelegate: document];
631 [mTextView setAcceptsFirstResponder:YES];
632 // [mTextView setEditable:YES];
634 [document addWindowController: myWindowController];
635 [[mTextView layoutManager] replaceTextStorage: [[document textView] textStorage]];
637 [mScrollView setDocumentView: mTextView];
639 mCurrentDocument = document;
641 [mTextView setSelectedRange: selectRange];
642 [mTextView scrollRangeToVisible: selectRange];
643 // [[mTextView window] makeKeyAndOrderFront:nil];
647 // no sc - actions supported
648 - (void*) getSCObject
653 - (NSEnumerator *)scopeEnumerator
656 NSEnumerator *enumerator;
657 if (mSearchScope == SMLAllDocumentsScope) {
658 NSDocumentController *docctl = [NSDocumentController sharedDocumentController];
659 enumerator = [[docctl documents] objectEnumerator];
661 enumerator = [[NSArray arrayWithObject:[[NSDocumentController sharedDocumentController] currentDocument]] objectEnumerator];
663 // no project at the moment
668 - (id)currentlyDisplayedDocumentInAdvancedFind
670 return currentlyDisplayedDocumentInAdvancedFind;
674 - (void)removeCurrentlyDisplayedDocumentInAdvancedFind
676 // [SMLInterface removeAllSubviewsFromView:resultDocumentContentView];
677 // NSArray *array = [NSArray arrayWithArray:[resultDocumentContentView subviews]];
678 // NSEnumerator *enumerator = [array objectEnumerator];
680 // while (item = [enumerator nextObject]) {
681 // [item removeFromSuperview];
684 // NSTextView superview
685 // NSTextStorage *textStorage = NSTextStorage;
686 // mScrollView = [mTextView superview];
687 // [mTextView removeFromSuperview];
688 // [[mTextView textStorage] removeLayoutManager:[mTextView layoutManager]];
690 // [[mTextView layoutManager] replaceTextStorage: nil];
692 [[mTextView textStorage] removeLayoutManager:[mTextView layoutManager]];
693 [mCurrentDocument removeWindowController: myWindowController];
694 [mTextView removeFromSuperview];
696 mCurrentDocument = NULL;
697 myWindowController =NULL;
702 - (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item
705 if ([[SMLDefaults valueForKey:@"SizeOfDocumentsListTextPopUp"] intValue] == 0) {
706 [cell setFont:[NSFont systemFontOfSize:11.0]];
709 [cell setFont:[NSFont systemFontOfSize:11.0]];
716 - (NSMutableDictionary *)preparedResultDictionaryFromString:(NSString *)completeString searchStringLength:(NSInteger)searchStringLength range:(NSRange)foundRange lineNumber:(NSInteger)lineNumber document:(id)document
718 NSMutableString *displayString = [[[NSMutableString alloc] init] autorelease];
719 NSString *lineNumberString = [NSString stringWithFormat:@"%d\t", lineNumber];
720 [displayString appendString:lineNumberString];
721 NSRange linesRange = [completeString lineRangeForRange:foundRange];
723 [displayString appendString:[SMLText replaceAllNewLineCharactersWithSymbolInString:[completeString substringWithRange:linesRange]]];
725 [displayString appendString:[completeString substringWithRange:linesRange]];
727 NSMutableDictionary *node = [NSMutableDictionary dictionary];
728 [node setValue:[NSNumber numberWithBool:YES] forKey:@"isLeaf"];
729 // [node setValue:1 forKey:@"isLeaf"];
731 [node setValue:NSStringFromRange(foundRange) forKey:@"range"]; //orginal
732 // [node setValue:lineNumberString forKey:@"displayString"]; // jt
734 // [node setValue:[[document objectID] URIRepresentation] forKey:@"document"];
735 // [node setValue:[SMLBasic uriFromObject:document] forKey:@"document"];
736 [node setValue:document forKey:@"document"];
739 // if ([[SMLDefaults valueForKey:@"SizeOfDocumentsListTextPopUp"] intValue] == 0) {
746 NSMutableAttributedString *attributedString = [[[NSMutableAttributedString alloc] initWithString:displayString attributes:[NSDictionary dictionaryWithObject:[NSFont systemFontOfSize:fontSize] forKey:NSFontAttributeName]] autorelease];
747 NSMutableParagraphStyle *style = [[[NSMutableParagraphStyle alloc] init] autorelease];
749 [style setLineBreakMode:NSLineBreakByTruncatingMiddle];
750 [attributedString addAttribute:NSParagraphStyleAttributeName value:style range:NSMakeRange(0, [displayString length])];
751 [attributedString applyFontTraits:NSBoldFontMask range:NSMakeRange(foundRange.location - linesRange.location + [lineNumberString length], foundRange.length)];
752 [node setValue:attributedString forKey:@"displayString"];
758 - (void)alertThatThisIsNotAValidRegularExpression:(NSString *)string
760 NSString *title = [NSString stringWithFormat:NSLocalizedStringFromTable(@"%@ is not a valid regular expression", @"Localizable3", @"%@ is not a valid regular expression"), string];
761 NSBeginAlertSheet(title,
767 @selector(notAValidRegularExpressionSheetDidEnd:returnCode:contextInfo:),
774 - (void)notAValidRegularExpressionSheetDidEnd:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo
777 [findResultsTreeController setContent:nil];
778 [findResultsTreeController setContent:[NSArray array]];
779 [advancedFindWindow makeKeyAndOrderFront:nil];
783 - (IBAction)searchScopeChanged:(id)sender
785 mSearchScope = [sender tag];
787 if (mSearchScope == SMLCurrentDocumentScope) {
788 // [currentProjectScope setState:NSOffState];
789 [allDocumentsScope setState:NSOffState];
790 [currentDocumentScope setState:NSOnState]; // If the user has clicked an already clicked button make sure it is on and not turned off
791 } else if (mSearchScope == SMLCurrentProjectScope) {
792 // [currentDocumentScope setState:NSOffState];
793 // [allDocumentsScope setState:NSOffState];
794 // [currentProjectScope setState:NSOnState];
795 } else if (mSearchScope == SMLAllDocumentsScope) {
796 [currentDocumentScope setState:NSOffState];
797 // [currentProjectScope setState:NSOffState];
798 [allDocumentsScope setState:NSOnState];
801 if (![[findSearchField stringValue] isEqualToString:@""]) {
802 [self findAction:nil];
806 - (void)showRegularExpressionsHelpPanel
808 if (regularExpressionsHelpPanel == nil) {
809 [NSBundle loadNibNamed:@"SMLRegularExpressionHelp.nib" owner:self];
812 [regularExpressionsHelpPanel makeKeyAndOrderFront:nil];
816 - (NSWindow *)advancedFindWindow
818 return advancedFindWindow;
822 - (NSOutlineView *)findResultsOutlineView
824 return findResultsOutlineView;
828 - (IBAction)showRegularExpressionsHelpPanelAction:(id)sender
830 [self showRegularExpressionsHelpPanel];