class library: Spawner - don't access PriorityQueue-array
[supercollider.git] / editors / scapp / SMLAdvancedFind / SMLAdvancedFindController.m
blob358836becbc0004a33f1c33c6651f0542a4cf084
1 /*
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
8  
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
30
31         if (sharedInstance == nil) { 
32                 sharedInstance = [[self alloc] init];
33         }
34         
35         return sharedInstance;
36
39 - (id)init 
41     if (sharedInstance != nil) {
42         [self dealloc];
43     } else {
44         sharedInstance = [super init];
45                 mContents = [[NSMutableArray alloc] init]; 
46     }
47     return sharedInstance;
50 - (NSMutableArray*) contents
52         return mContents;
55 - (void) setContents: (NSArray *)newContents 
57 if (mContents != newContents) 
58     { 
59         [mContents autorelease]; 
60         mContents = [[NSMutableArray alloc] initWithArray:newContents]; 
61     } 
62
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]; 
70         
71         [findResultsOutlineView setDelegate:nil];
72         
73         [findResultsTreeController setContent:nil];
74         [findResultsTreeController setContent:[NSArray array]];
75         [mContents autorelease];
76         mContents = [[NSMutableArray alloc] init]; 
77         
78         
79         NSMutableArray *recentSearches = [[[NSMutableArray alloc] initWithArray:[findSearchField recentSearches]] autorelease];
80         if ([recentSearches indexOfObject:searchString] != NSNotFound) {
81                 [recentSearches removeObject:searchString];
82         }
83         [recentSearches insertObject:searchString atIndex:0];
84         if ([recentSearches count] > 15) {
85                 [recentSearches removeLastObject];
86         }
87         [findSearchField setRecentSearches:recentSearches];
88         
89         NSInteger searchStringLength = [searchString length];
90         if (!searchStringLength > 0 ) {
91 //              NSBeep();
92                 return;
93         }
95         NSString *completeString;
96         NSInteger completeStringLength; 
97         NSInteger startLocation;
98         NSInteger resultsInThisDocument = 0;
99         NSInteger lineNumber;
100         NSInteger index;
101         NSInteger numberOfResults = 0;
102         NSRange foundRange;
103         NSRange searchRange;
104         NSIndexPath *folderIndexPath;
105         NSMutableDictionary *node;
106         
107         NSEnumerator *enumerator = [self scopeEnumerator];
108         id document;
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"];
115 //              } else {
116                         [node setValue:[document displayName] forKey:@"displayString"];
117 //              }
119                 [node setValue:[NSNumber numberWithBool:NO] forKey:@"isLeaf"];
120                 
121                 folderIndexPath = [[[NSIndexPath alloc] initWithIndex:documentIndex] autorelease];
122                 [findResultsTreeController insertObject:node atArrangedObjectIndexPath:folderIndexPath];
123                 documentIndex++;
125                 completeString = [[document textView] string];
126                 searchRange = [[document textView] selectedRange];
127                 completeStringLength = [completeString length];
128                 
129                 if (onlyInSelectionAdvancedFind == NO || searchRange.length == 0) {
130                         searchRange = NSMakeRange(0, completeStringLength);
131                 }
132                 startLocation = searchRange.location;
133                 resultsInThisDocument = 0;
135                 if (useRegularExpressions) {
136                         ICUPattern *pattern;
137                         @try {
138                                 if (ignoreCaseAdvancedFind) {
139                                         pattern = [[ICUPattern alloc] initWithString:searchString flags:(CaseInsensitiveMatching | Multiline)];
140                                 } else {
141                                         pattern = [[ICUPattern alloc] initWithString:searchString flags:Multiline];
142                                 }
143                         }
144                         @catch (NSException *exception) {
145                                 [self alertThatThisIsNotAValidRegularExpression:searchString];
146                                 return;
147                         }
148                         @finally {
149                         }
150                         
151                         if ([completeString length] > 0) { // Otherwise ICU throws an exception
152                                 ICUMatcher *matcher;
153                                 if (onlyInSelectionAdvancedFind == NO || searchRange.length == 0) {
154                                         matcher = [[[ICUMatcher alloc] initWithPattern:pattern overString:completeString] autorelease];
155                                 } else {
156                                         matcher = [[[ICUMatcher alloc] initWithPattern:pattern overString:[completeString substringWithRange:searchRange]] autorelease];
157                                 }
158                                 
159                                 NSInteger indexTemp;
160                                 while ([matcher findNext]) {
161                                         NSInteger foundLocation = [matcher rangeOfMatch].location + startLocation;
162                                         for (index = 0, lineNumber = 0; index <= foundLocation; lineNumber++) {
163                                                 indexTemp = index;
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]*
167                                                 }
168                                         }
169                                         
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]];
173                                         [pool release];
174                                         
175                                         resultsInThisDocument++;
176                                 }
177                         }
178                         
179                 } else {                        
180                         while (startLocation < completeStringLength) {
181                                 if (ignoreCaseAdvancedFind) {
182                                         foundRange = [completeString rangeOfString:searchString options:NSCaseInsensitiveSearch range:NSMakeRange(startLocation, NSMaxRange(searchRange) - startLocation)];
183                                 } else {
184                                         foundRange = [completeString rangeOfString:searchString options:NSLiteralSearch range:NSMakeRange(startLocation, NSMaxRange(searchRange) - startLocation)];
185                                 }
187                                 if (foundRange.location == NSNotFound) {
188                                         break;
189                                 }
190                                 for (index = 0, lineNumber = 0; index <= foundRange.location; lineNumber++) {
191                                         index = NSMaxRange([completeString lineRangeForRange:NSMakeRange(index, 0)]);   
192                                 }
193                         
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]];
199                                 [pool release];
200                                 
201                                 resultsInThisDocument++;
202                                 startLocation = NSMaxRange(foundRange);
203                         }
204                 }
205                 if (resultsInThisDocument == 0) {
206                         [findResultsTreeController removeObjectAtArrangedObjectIndexPath:folderIndexPath];
207                         documentIndex--;
208                 } else {
209                         numberOfResults += resultsInThisDocument;
210                 }
211                         
212         }
213         
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];
219         } else {
220                 searchResultString = [NSString stringWithFormat:NSLocalizedString(@"Found %i matches for search-string %@", @"Found %i matches for search-string %@ in Advanced Find"), numberOfResults, searchString];
221         }
222 //      NSLog(searchResultString);
223         [findResultTextField setStringValue:searchResultString];
224         
225         [findResultsOutlineView setDelegate:self];
229 - (IBAction)replaceAction:(id)sender
230 {       
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]; 
236         
237         NSMutableArray *recentSearches = [[[NSMutableArray alloc] initWithArray:[findSearchField recentSearches]] autorelease];
238         if ([recentSearches indexOfObject:searchString] != NSNotFound) {
239                 [recentSearches removeObject:searchString];
240         }
241         [recentSearches insertObject:searchString atIndex:0];
242         if ([recentSearches count] > 15) {
243                 [recentSearches removeLastObject];
244         }
245         [findSearchField setRecentSearches:recentSearches];
246         
247         NSMutableArray *recentReplaces = [[[NSMutableArray alloc] initWithArray:[replaceSearchField recentSearches]] autorelease];
248         if ([recentReplaces indexOfObject:replaceString] != NSNotFound) {
249                 [recentReplaces removeObject:replaceString];
250         }
251         [recentReplaces insertObject:replaceString atIndex:0];
252         if ([recentReplaces count] > 15) {
253                 [recentReplaces removeLastObject];
254         }
255         [replaceSearchField setRecentSearches:recentReplaces];
256         
257         NSInteger searchStringLength = [searchString length];
258 //       [[NSApp mainWindow] firstResponder];
259 //      if (!searchStringLength > 0 || SMLCurrentDocument == nil || SMLCurrentProject == nil) {
260 //              NSBeep();
261 //              return;
262 //      }
263         
264         NSString *completeString;
265         NSInteger completeStringLength; 
266         NSInteger startLocation;
267         NSInteger resultsInThisDocument = 0;
268         NSInteger numberOfResults = 0;
269         NSRange foundRange;
270         NSRange searchRange;
271         
272         NSEnumerator *enumerator = [self scopeEnumerator];
273         id document;
274         
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);
280                 
281                 if (onlyInSelectionAdvancedFind == NO || searchRange.length == 0) {
282                         searchRange = NSMakeRange(0, completeStringLength);
283                 }
284                 
285                 startLocation = searchRange.location;
286                 resultsInThisDocument = 0;
287                 if (useRegularExpressions) {
288                         ICUPattern *pattern;
289                         @try { 
290                                 if (ignoreCaseAdvancedFind) {
291                                         pattern = [[[ICUPattern alloc] initWithString:searchString flags:(CaseInsensitiveMatching | Multiline)] autorelease];
292                                 } else {
293                                         pattern = [[[ICUPattern alloc] initWithString:searchString flags:Multiline] autorelease];
294                                 }
295                         }
296                         @catch (NSException *exception) {
297                                 [self alertThatThisIsNotAValidRegularExpression:searchString];
298                                 return;
299                         }
300                         @finally {
301                         }
302                         
303                         ICUMatcher *matcher;
304                         if (onlyInSelectionAdvancedFind == NO || searchRange.length == 0) {
305                                 matcher = [[[ICUMatcher alloc] initWithPattern:pattern overString:completeString] autorelease];
306                         } else {
307                                 matcher = [[[ICUMatcher alloc] initWithPattern:pattern overString:[completeString substringWithRange:searchRange]] autorelease];
308                         }
309                         
311                         while ([matcher findNext]) {
312                                 resultsInThisDocument++;
313                         }
314         
315                         
316                 } else {
317                         NSInteger searchLength;
319                         if (onlyInSelectionAdvancedFind == NO || searchRange.length == 0) {
320                                 searchLength = completeStringLength;
321                         } else {
322                                 searchLength = NSMaxRange(searchRange);
323                         }
324                         while (startLocation < searchLength) {
326                                 if (ignoreCaseAdvancedFind) {
327                                         foundRange = [completeString rangeOfString:searchString options:NSCaseInsensitiveSearch range:NSMakeRange(startLocation, NSMaxRange(searchRange) - startLocation)];
328                                 } else {
329                                         foundRange = [completeString rangeOfString:searchString options:NSLiteralSearch range:NSMakeRange(startLocation, NSMaxRange(searchRange) - startLocation)];
330                                 }
331                                 
332                                 if (foundRange.location == NSNotFound) {
333                                         break;
334                                 }
335                                 resultsInThisDocument++;
336                                 startLocation = NSMaxRange(foundRange);
337                         }
338         
339                 }
340                 numberOfResults += resultsInThisDocument;
341         }
342         
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]];
345                 NSBeep();
346                 return;
347         }
348         #if 0
350         if ([[SMLDefaults valueForKey:@"SuppressReplaceWarning"] boolValue] == YES) {
351                 [self performNumberOfReplaces:numberOfResults];
352         } else {
353         #endif
354                 NSString *title;
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];
359                         } else {
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];
361                         }
362                         defaultButton = NSLocalizedString(@"Replace", @"Replace-button in ask-if-sure-you-want-to-replace-in-advanced-find-sheet");
363                 } else {
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];
366                         } else {
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];
368                         }
369                         defaultButton = DELETEBUTTON;
370                 }
372                 NSBeginAlertSheet(title,
373                                                   defaultButton,
374                                                   nil,
375                                                   NSLocalizedString(@"Cancel", @"Cancel-button"),
376                                                   advancedFindWindow,
377                                                   self,
378                                                   @selector(replaceSheetDidEnd:returnCode:contextInfo:),
379                                                   nil,
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"));
382         #if 0
384         }
385         #endif
389 - (void)replaceSheetDidEnd:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo
391         [sheet close];
392     if (returnCode == NSAlertDefaultReturn) { // Replace
393                 [self performNumberOfReplaces:(NSInteger)contextInfo];
394         }
398 - (void)performNumberOfReplaces:(NSInteger)numberOfReplaces
400         NSString *searchString = [findSearchField stringValue];
401         NSString *replaceString = [replaceSearchField stringValue];
402         NSRange searchRange;
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);
408         
409         NSEnumerator *enumerator = [self scopeEnumerator];
410         id document;
411         while (document = [enumerator nextObject]) {
412                 NSTextView *textView = [document textView];
413                 NSString *originalString = [NSString stringWithString:[textView string]];
414                 NSMutableString *completeString = [NSMutableString stringWithString:[textView string]];
415                 
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);
422                 }
423                 
424                 if (useRegularExpressions == YES) {             
425                         ICUPattern *pattern;
426                         @try {
427                                 if (ignoreCaseAdvancedFind) {
428                                         pattern = [[ICUPattern alloc] initWithString:searchString flags:(CaseInsensitiveMatching | Multiline)];
429                                 } else {
430                                         pattern = [[ICUPattern alloc] initWithString:searchString flags:Multiline];
431                                 }
432                         }
433                         @catch (NSException *exception) {
434                                 [self alertThatThisIsNotAValidRegularExpression:searchString];
435                                 return;
436                         }
437                         @finally {
438                         }
439                         ICUMatcher *matcher;
440                         if (onlyInSelectionAdvancedFind== NO) {
441                                 matcher = [[[ICUMatcher alloc] initWithPattern:pattern overString:completeString] autorelease];
442                         } else {
443                                 matcher = [[[ICUMatcher alloc] initWithPattern:pattern overString:[completeString substringWithRange:searchRange]] autorelease];
444                         }
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])];
450                         
451                         if (onlyInSelectionAdvancedFind == NO) {
452                                 [completeString setString:[matcher replaceAllWithString:regularExpressionReplaceString]];
453                         } else {
454                                 [completeString replaceCharactersInRange:searchRange withString:[matcher replaceAllWithString:regularExpressionReplaceString]];
455                         }
456                         
457                 } else {
459                         if (ignoreCaseAdvancedFind == YES) {
460                                 [completeString replaceOccurrencesOfString:searchString withString:replaceString options:NSCaseInsensitiveSearch range:searchRange];
461                         } else {
462                                 [completeString replaceOccurrencesOfString:searchString withString:replaceString options:NSLiteralSearch range:searchRange];
464                         }
465                 }
466                 
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];
472                         }
473                 }               
474                 
475                 if (selectedRange.location <= [[textView string] length]) {
476                         [textView setSelectedRange:NSMakeRange(selectedRange.location, 0)];
477                 }
478         }
479         
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]];
482         } else {
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]];
484         }
485         [findResultsTreeController setContent:nil];
486         [findResultsTreeController setContent:[NSArray array]];
487         [mContents autorelease]; 
488         mContents = [[NSMutableArray alloc] init]; 
489         
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];
500                         
501 //              mScrollView = [mTextView superview];
502 //              [mTextView removeFromSuperview];                        
503                 
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
513                 #if 0           
514         
515                 SMLAdvancedFindScope searchScope = [[SMLDefaults valueForKey:@"AdvancedFindScope"] intValue];
517                 SMLAdvancedFindScope searchScope  = SMLCurrentDocumentScope;
518                 NSInteger distanceFromEdge = 26;
519                 
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];                
524                 
525                 distanceFromEdge = distanceFromEdge + [currentDocumentScope bounds].size.width + 26;
526                 
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];
531                 
532                 distanceFromEdge = distanceFromEdge + [currentProjectScope bounds].size.width + 26;
533                 
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];
538                 
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];
545                 }
546                 #endif  
547                 [findResultsTreeController setContent:nil];
548                 [findResultsTreeController setContent:[NSArray array]];
549         }
550         
551         [advancedFindWindow makeKeyAndOrderFront:self];
555 - (void)outlineViewSelectionDidChange:(NSNotification *)aNotification
557         if ([[findResultsTreeController arrangedObjects] count] == 0) {
558                 return;
559         }
560         id object = [[findResultsTreeController selectedObjects] objectAtIndex:0];      
561         if ([[object valueForKey:@"isLeaf"] boolValue] == NO) {
562                 return;
563         }
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"),
570                                                   nil,
571                                                   nil,
572                                                   advancedFindWindow,
573                                                   self,
574                                                   nil,
575                                                   NULL,
576                                                   nil,
577                                                   @"");
578                 return;
579         }
580         
581         currentlyDisplayedDocumentInAdvancedFind = document;
582         
583 #if 0
584         [resultDocumentContentView addSubview:[document valueForKey:@"fourthTextScrollView"]];
585         if ([[document valueForKey:@"showLineNumberGutter"] boolValue] == YES) {
586                 [resultDocumentContentView addSubview:[document valueForKey:@"fourthGutterScrollView"]];
587         }
589         [[document valueForKey:@"lineNumbers"] updateLineNumbersForClipView:[[document valueForKey:@"fourthTextScrollView"] contentView] checkWidth:YES recolour:YES]; // If the window has changed since the view was last visible
590 #endif  
592         [self removeCurrentlyDisplayedDocumentInAdvancedFind];
593                 
594         NSRange selectRange = NSRangeFromString([[[findResultsTreeController selectedObjects] objectAtIndex:0] valueForKey:@"range"]);
595         NSString *completeString = [[document textView] string];
596         if (NSMaxRange(selectRange) > [completeString length]) {
597 //              NSBeep();
598                 return;
599         }
600         [self insertDocumentIntoFourthContentView: document selectRange:selectRange ];
602         #if 0
603         if ([[SMLDefaults valueForKey:@"FocusOnTextInAdvancedFind"] boolValue] == YES) {
604                 [advancedFindWindow makeFirstResponder:[document valueForKey:@"fourthTextView"]];
605         }
606         #endif
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];
633         #endif
634                 [document addWindowController: myWindowController];
635                 [[mTextView layoutManager] replaceTextStorage: [[document textView] textStorage]];
637                 [mScrollView setDocumentView: mTextView];
638                 [mTextView release];
639                 mCurrentDocument = document;
640         }
641         [mTextView setSelectedRange: selectRange];
642     [mTextView scrollRangeToVisible: selectRange];
643 //      [[mTextView window] makeKeyAndOrderFront:nil];
647 // no sc - actions supported
648 - (void*) getSCObject 
650         return NULL;
653 - (NSEnumerator *)scopeEnumerator 
656         NSEnumerator *enumerator;
657         if (mSearchScope == SMLAllDocumentsScope) {
658                 NSDocumentController *docctl = [NSDocumentController sharedDocumentController];
659                 enumerator = [[docctl documents] objectEnumerator];     
660         } else {
661                 enumerator = [[NSArray arrayWithObject:[[NSDocumentController sharedDocumentController] currentDocument]] objectEnumerator];
662         }
663         // no project at the moment
664         return enumerator;
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];
679 //      id item;
680 //      while (item = [enumerator nextObject]) {
681 //              [item removeFromSuperview];
682 //              item = nil;
683 //      }
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];
691                 if(mTextView) {
692                         [[mTextView textStorage] removeLayoutManager:[mTextView layoutManager]];                        
693                         [mCurrentDocument removeWindowController: myWindowController];
694                         [mTextView removeFromSuperview]; 
695                         mTextView = NULL; 
696                         mCurrentDocument = NULL;
697                         myWindowController =NULL;
698                         
699                 }
702 - (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item
704         #if 0
705         if ([[SMLDefaults valueForKey:@"SizeOfDocumentsListTextPopUp"] intValue] == 0) {
706                 [cell setFont:[NSFont systemFontOfSize:11.0]];
707         } else {
708         #endif
709                 [cell setFont:[NSFont systemFontOfSize:11.0]];
710         #if 0
711         }
712         #endif
713 }       
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];
722         #if 0
723         [displayString appendString:[SMLText replaceAllNewLineCharactersWithSymbolInString:[completeString substringWithRange:linesRange]]];
724         #endif
725         [displayString appendString:[completeString substringWithRange:linesRange]];
726         
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"];
738         NSInteger fontSize;
739 //      if ([[SMLDefaults valueForKey:@"SizeOfDocumentsListTextPopUp"] intValue] == 0) {
740 //              fontSize = 11;
741 //      } else {
742                 fontSize = 11;
743 //      }
746         NSMutableAttributedString *attributedString = [[[NSMutableAttributedString alloc] initWithString:displayString attributes:[NSDictionary dictionaryWithObject:[NSFont systemFontOfSize:fontSize] forKey:NSFontAttributeName]] autorelease];
747         NSMutableParagraphStyle *style = [[[NSMutableParagraphStyle alloc] init] autorelease];
748                 
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"];
754         return node;
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,
762                                           OKBUTTON,
763                                           nil,
764                                           nil,
765                                           advancedFindWindow,
766                                           self,
767                                           @selector(notAValidRegularExpressionSheetDidEnd:returnCode:contextInfo:),
768                                           nil,
769                                           nil,
770                                           @"");
774 - (void)notAValidRegularExpressionSheetDidEnd:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo
776         [sheet close];
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];
799         }
800                 
801         if (![[findSearchField stringValue] isEqualToString:@""]) {
802                 [self findAction:nil];
803         }       
806 - (void)showRegularExpressionsHelpPanel
808         if (regularExpressionsHelpPanel == nil) {
809                 [NSBundle loadNibNamed:@"SMLRegularExpressionHelp.nib" owner:self];
810         }
811         
812         [regularExpressionsHelpPanel makeKeyAndOrderFront:nil];
813         
816 - (NSWindow *)advancedFindWindow
818     return advancedFindWindow; 
822 - (NSOutlineView *)findResultsOutlineView
824     return findResultsOutlineView; 
828 - (IBAction)showRegularExpressionsHelpPanelAction:(id)sender
830         [self showRegularExpressionsHelpPanel];
834 @end