scide: DocManager - report warnings via the status bar
[supercollider.git] / editors / scapp / SMLAdvancedFind / SMLAdvancedFindController.m
blobce5cfaedea097b409a709995fbc8e811eb723bfa
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 //       [[NSApp mainWindow] firstResponder];
258 //      if (!searchStringLength > 0 || SMLCurrentDocument == nil || SMLCurrentProject == nil) {
259 //              NSBeep();
260 //              return;
261 //      }
262         
263         NSString *completeString;
264         NSInteger completeStringLength; 
265         NSInteger startLocation;
266         NSInteger resultsInThisDocument = 0;
267         NSInteger numberOfResults = 0;
268         NSRange foundRange;
269         NSRange searchRange;
270         
271         NSEnumerator *enumerator = [self scopeEnumerator];
272         id document;
273         
274         while (document = [enumerator nextObject]) {
275                 completeString = [[document textView] string];
276                 searchRange = [[document textView] selectedRange];
277                 completeStringLength = [completeString length];
278 //              if(searchRange.length == 0) searchRange =       NSMakeRange(0, completeStringLength);
279                 
280                 if (onlyInSelectionAdvancedFind == NO || searchRange.length == 0) {
281                         searchRange = NSMakeRange(0, completeStringLength);
282                 }
283                 
284                 startLocation = searchRange.location;
285                 resultsInThisDocument = 0;
286                 if (useRegularExpressions) {
287                         ICUPattern *pattern;
288                         @try { 
289                                 if (ignoreCaseAdvancedFind) {
290                                         pattern = [[[ICUPattern alloc] initWithString:searchString flags:(CaseInsensitiveMatching | Multiline)] autorelease];
291                                 } else {
292                                         pattern = [[[ICUPattern alloc] initWithString:searchString flags:Multiline] autorelease];
293                                 }
294                         }
295                         @catch (NSException *exception) {
296                                 [self alertThatThisIsNotAValidRegularExpression:searchString];
297                                 return;
298                         }
299                         @finally {
300                         }
301                         
302                         ICUMatcher *matcher;
303                         if (onlyInSelectionAdvancedFind == NO || searchRange.length == 0) {
304                                 matcher = [[[ICUMatcher alloc] initWithPattern:pattern overString:completeString] autorelease];
305                         } else {
306                                 matcher = [[[ICUMatcher alloc] initWithPattern:pattern overString:[completeString substringWithRange:searchRange]] autorelease];
307                         }
308                         
310                         while ([matcher findNext]) {
311                                 resultsInThisDocument++;
312                         }
313         
314                         
315                 } else {
316                         NSInteger searchLength;
318                         if (onlyInSelectionAdvancedFind == NO || searchRange.length == 0) {
319                                 searchLength = completeStringLength;
320                         } else {
321                                 searchLength = NSMaxRange(searchRange);
322                         }
323                         while (startLocation < searchLength) {
325                                 if (ignoreCaseAdvancedFind) {
326                                         foundRange = [completeString rangeOfString:searchString options:NSCaseInsensitiveSearch range:NSMakeRange(startLocation, NSMaxRange(searchRange) - startLocation)];
327                                 } else {
328                                         foundRange = [completeString rangeOfString:searchString options:NSLiteralSearch range:NSMakeRange(startLocation, NSMaxRange(searchRange) - startLocation)];
329                                 }
330                                 
331                                 if (foundRange.location == NSNotFound) {
332                                         break;
333                                 }
334                                 resultsInThisDocument++;
335                                 startLocation = NSMaxRange(foundRange);
336                         }
337         
338                 }
339                 numberOfResults += resultsInThisDocument;
340         }
341         
342         if (numberOfResults == 0) {
343                 [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]];
344                 NSBeep();
345                 return;
346         }
347         #if 0
349         if ([[SMLDefaults valueForKey:@"SuppressReplaceWarning"] boolValue] == YES) {
350                 [self performNumberOfReplaces:numberOfResults];
351         } else {
352         #endif
353                 NSString *title;
354                 NSString *defaultButton;
355                 if ([replaceString length] > 0) {
356                         if (numberOfResults != 1) {
357                                 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];
358                         } else {
359                                 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];
360                         }
361                         defaultButton = NSLocalizedString(@"Replace", @"Replace-button in ask-if-sure-you-want-to-replace-in-advanced-find-sheet");
362                 } else {
363                         if (numberOfResults != 1) {
364                                 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];
365                         } else {
366                                 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];
367                         }
368                         defaultButton = DELETEBUTTON;
369                 }
371                 NSBeginAlertSheet(title,
372                                                   defaultButton,
373                                                   nil,
374                                                   NSLocalizedString(@"Cancel", @"Cancel-button"),
375                                                   advancedFindWindow,
376                                                   self,
377                                                   @selector(replaceSheetDidEnd:returnCode:contextInfo:),
378                                                   nil,
379                                                   (void *)numberOfResults,
380                                                   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"));
381         #if 0
383         }
384         #endif
388 - (void)replaceSheetDidEnd:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo
390         [sheet close];
391     if (returnCode == NSAlertDefaultReturn) { // Replace
392                 [self performNumberOfReplaces:(NSInteger)contextInfo];
393         }
397 - (void)performNumberOfReplaces:(NSInteger)numberOfReplaces
399         NSString *searchString = [findSearchField stringValue];
400         NSString *replaceString = [replaceSearchField stringValue];
401         NSRange searchRange;
402         NSInteger completeStringLength; 
403         BOOL useRegularExpressions = (BOOL) [setUseRegularExpressionsButton state];
404         BOOL ignoreCaseAdvancedFind = (BOOL) [setIgnoreCaseButton state]; 
405         BOOL onlyInSelectionAdvancedFind = (BOOL) [setSearchInSelectionButton state]; 
406 //      NSLog(@"performNumberOfReplaces %i", numberOfReplaces);
407         
408         NSEnumerator *enumerator = [self scopeEnumerator];
409         id document;
410         while (document = [enumerator nextObject]) {
411                 NSTextView *textView = [document textView];
412                 NSString *originalString = [NSString stringWithString:[textView string]];
413                 NSMutableString *completeString = [NSMutableString stringWithString:[textView string]];
414                 
415 //              completeString = [[document textView] string];
416                 searchRange = [[document textView] selectedRange];
417                 completeStringLength = [completeString length];
418 //              if(searchRange.length == 0) searchRange =       NSMakeRange(0, completeStringLength);
419                 if (!onlyInSelectionAdvancedFind || searchRange.length == 0) {
420                         searchRange = NSMakeRange(0, completeStringLength);
421                 }
422                 
423                 if (useRegularExpressions == YES) {             
424                         ICUPattern *pattern;
425                         @try {
426                                 if (ignoreCaseAdvancedFind) {
427                                         pattern = [[ICUPattern alloc] initWithString:searchString flags:(CaseInsensitiveMatching | Multiline)];
428                                 } else {
429                                         pattern = [[ICUPattern alloc] initWithString:searchString flags:Multiline];
430                                 }
431                         }
432                         @catch (NSException *exception) {
433                                 [self alertThatThisIsNotAValidRegularExpression:searchString];
434                                 return;
435                         }
436                         @finally {
437                         }
438                         ICUMatcher *matcher;
439                         if (onlyInSelectionAdvancedFind== NO) {
440                                 matcher = [[[ICUMatcher alloc] initWithPattern:pattern overString:completeString] autorelease];
441                         } else {
442                                 matcher = [[[ICUMatcher alloc] initWithPattern:pattern overString:[completeString substringWithRange:searchRange]] autorelease];
443                         }
445                         NSMutableString *regularExpressionReplaceString = [NSMutableString stringWithString:replaceString];
446                         [regularExpressionReplaceString replaceOccurrencesOfString:@"\\n" withString:[NSString stringWithFormat:@"%C", 0x000A] options:NSLiteralSearch range:NSMakeRange(0, [regularExpressionReplaceString length])]; // It doesn't seem to work without this workaround
447                         [regularExpressionReplaceString replaceOccurrencesOfString:@"\\r" withString:[NSString stringWithFormat:@"%C", 0x000D] options:NSLiteralSearch range:NSMakeRange(0, [regularExpressionReplaceString length])];
448                         [regularExpressionReplaceString replaceOccurrencesOfString:@"\\t" withString:[NSString stringWithFormat:@"%C", 0x0009] options:NSLiteralSearch range:NSMakeRange(0, [regularExpressionReplaceString length])];
449                         
450                         if (onlyInSelectionAdvancedFind == NO) {
451                                 [completeString setString:[matcher replaceAllWithString:regularExpressionReplaceString]];
452                         } else {
453                                 [completeString replaceCharactersInRange:searchRange withString:[matcher replaceAllWithString:regularExpressionReplaceString]];
454                         }
455                         
456                 } else {
458                         if (ignoreCaseAdvancedFind == YES) {
459                                 [completeString replaceOccurrencesOfString:searchString withString:replaceString options:NSCaseInsensitiveSearch range:searchRange];
460                         } else {
461                                 [completeString replaceOccurrencesOfString:searchString withString:replaceString options:NSLiteralSearch range:searchRange];
463                         }
464                 }
465                 
466                 NSRange selectedRange = [textView selectedRange];
467                 if (![originalString isEqualToString:completeString] && [originalString length] != 0) {
468                         if ([textView shouldChangeTextInRange:NSMakeRange(0, [[textView string] length]) replacementString:completeString]) { // Do it this way to mark it as an Undo
469                                 [textView replaceCharactersInRange:NSMakeRange(0, [[textView string] length]) withString:completeString];
470                                 [textView didChangeText];
471                         }
472                 }               
473                 
474                 if (selectedRange.location <= [[textView string] length]) {
475                         [textView setSelectedRange:NSMakeRange(selectedRange.location, 0)];
476                 }
477         }
478         
479         if (numberOfReplaces != 1) {
480                 [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]];
481         } else {
482                 [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]];
483         }
484         [findResultsTreeController setContent:nil];
485         [findResultsTreeController setContent:[NSArray array]];
486         [mContents autorelease]; 
487         mContents = [[NSMutableArray alloc] init]; 
488         
489         [self removeCurrentlyDisplayedDocumentInAdvancedFind];
490         [advancedFindWindow makeKeyAndOrderFront:self];
494 - (void)showAdvancedFindWindow
496         if (advancedFindWindow == nil) {
497                 [NSBundle loadNibNamed:@"SCAdvancedFind.nib" owner:self];
498                         [advancedFindWindow makeKeyAndOrderFront:self];
499                         
500 //              mScrollView = [mTextView superview];
501 //              [mTextView removeFromSuperview];                        
502                 
503                 SMLStatusBarTextFieldCell *statusBarTextFieldCell = [[SMLStatusBarTextFieldCell alloc] initTextCell:@""];
504                 [findResultTextField setCell:statusBarTextFieldCell];
505                 [findResultsOutlineView setBackgroundColor:[[NSColor controlAlternatingRowBackgroundColors] objectAtIndex:1]];
507                 mSearchScope = SMLCurrentDocumentScope;
509                 [allDocumentsScope setState:NSOffState];
510                 [currentDocumentScope setState:NSOnState]; // If the user has clicked an already clicked button make sure it is on and not turned off
512                 #if 0           
513         
514                 SMLAdvancedFindScope searchScope = [[SMLDefaults valueForKey:@"AdvancedFindScope"] intValue];
516                 SMLAdvancedFindScope searchScope  = SMLCurrentDocumentScope;
517                 NSInteger distanceFromEdge = 26;
518                 
519                 [currentDocumentScope setTitle:NSLocalizedStringFromTable(@"Current document", @"Localizable3", @"Current document")];
520                 [currentDocumentScope sizeToFit];
521                 [currentDocumentScope setFrameOrigin:NSMakePoint(distanceFromEdge, [currentDocumentScope frame].origin.y)];
522                 [(SMLFilterBarButton *)currentDocumentScope frameDidChange:nil];                
523                 
524                 distanceFromEdge = distanceFromEdge + [currentDocumentScope bounds].size.width + 26;
525                 
526                 [currentProjectScope setTitle:NSLocalizedStringFromTable(@"Current project", @"Localizable3", @"Current project")];
527                 [currentProjectScope sizeToFit];
528                 [currentProjectScope setFrameOrigin:NSMakePoint(distanceFromEdge, [currentProjectScope frame].origin.y)];
529                 [(SMLFilterBarButton *)currentProjectScope frameDidChange:nil];
530                 
531                 distanceFromEdge = distanceFromEdge + [currentProjectScope bounds].size.width + 26;
532                 
533                 [allDocumentsScope setTitle:NSLocalizedStringFromTable(@"All documents", @"Localizable3", @"All documents")];
534                 [allDocumentsScope sizeToFit];
535                 [allDocumentsScope setFrameOrigin:NSMakePoint(distanceFromEdge, [allDocumentsScope frame].origin.y)];
536                 [(SMLFilterBarButton *)allDocumentsScope frameDidChange:nil];
537                 
538                 if (searchScope == SMLCurrentDocumentScope) {
539                         [currentDocumentScope setState:NSOnState];
540                 } else if (searchScope == SMLCurrentProjectScope) {
541                         [currentProjectScope setState:NSOnState];
542                 } else if (searchScope == SMLAllDocumentsScope) {
543                         [allDocumentsScope setState:NSOnState];
544                 }
545                 #endif  
546                 [findResultsTreeController setContent:nil];
547                 [findResultsTreeController setContent:[NSArray array]];
548         }
549         
550         [advancedFindWindow makeKeyAndOrderFront:self];
554 - (void)outlineViewSelectionDidChange:(NSNotification *)aNotification
556         if ([[findResultsTreeController arrangedObjects] count] == 0) {
557                 return;
558         }
559         id object = [[findResultsTreeController selectedObjects] objectAtIndex:0];      
560         if ([[object valueForKey:@"isLeaf"] boolValue] == NO) {
561                 return;
562         }
564         id document = [object valueForKey:@"document"];
565         if (document == nil) {
566                 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"]];
567                 NSBeginAlertSheet(title,
568                                                   NSLocalizedString(@"OK", @"OK-button"),
569                                                   nil,
570                                                   nil,
571                                                   advancedFindWindow,
572                                                   self,
573                                                   nil,
574                                                   NULL,
575                                                   nil,
576                                                   @"");
577                 return;
578         }
579         
580         currentlyDisplayedDocumentInAdvancedFind = document;
581         
582 #if 0
583         [resultDocumentContentView addSubview:[document valueForKey:@"fourthTextScrollView"]];
584         if ([[document valueForKey:@"showLineNumberGutter"] boolValue] == YES) {
585                 [resultDocumentContentView addSubview:[document valueForKey:@"fourthGutterScrollView"]];
586         }
588         [[document valueForKey:@"lineNumbers"] updateLineNumbersForClipView:[[document valueForKey:@"fourthTextScrollView"] contentView] checkWidth:YES recolour:YES]; // If the window has changed since the view was last visible
589 #endif  
591         [self removeCurrentlyDisplayedDocumentInAdvancedFind];
592                 
593         NSRange selectRange = NSRangeFromString([[[findResultsTreeController selectedObjects] objectAtIndex:0] valueForKey:@"range"]);
594         NSString *completeString = [[document textView] string];
595         if (NSMaxRange(selectRange) > [completeString length]) {
596 //              NSBeep();
597                 return;
598         }
599         [self insertDocumentIntoFourthContentView: document selectRange:selectRange ];
601         #if 0
602         if ([[SMLDefaults valueForKey:@"FocusOnTextInAdvancedFind"] boolValue] == YES) {
603                 [advancedFindWindow makeFirstResponder:[document valueForKey:@"fourthTextView"]];
604         }
605         #endif
608 - (void)insertDocumentIntoFourthContentView:(id)document selectRange: (NSRange) selectRange
611         if(!myWindowController) myWindowController = [[NSWindowController alloc] initWithWindow: [mScrollView window]];
612         if(mCurrentDocument != (NSDocument*) document || mTextView == NULL){
613                 mTextView = [[SCTextView alloc] initWithFrame: 
614                                                 [mScrollView bounds]];
615                 [mTextView setAutoresizingMask: 63];
616                 [[mTextView textContainer] setWidthTracksTextView: YES];
617                 [mTextView setAllowsUndo: YES];
618                 [mTextView setRichText: YES];
619                 [mTextView setSmartInsertDeleteEnabled: NO];
620                 [mTextView setImportsGraphics: YES];
621                 [mTextView setFont: [NSFont fontWithName: @"Monaco" size: 9]];
623                 [mTextView setLangClassToCall:@"Document" 
624                                 withKeyDownActionIndex:4 withKeyUpActionIndex:5];
625                 [mTextView setObjectKeyDownActionIndex:2 setObjectKeyUpActionIndex:1];
626         #if 1 //in order to have an SCTextView running a few methods would need to be moved from MyDocument to SCTextView
627                 [mTextView setDelegate: document];
628                 [mTextView setAcceptsFirstResponder:YES];
629 //              [mTextView setEditable:YES];
630         #endif
631                 [document addWindowController: myWindowController];
632                 [[mTextView layoutManager] replaceTextStorage: [[document textView] textStorage]];
634                 [mScrollView setDocumentView: mTextView];
635                 [mTextView release];
636                 mCurrentDocument = document;
637         }
638         [mTextView setSelectedRange: selectRange];
639     [mTextView scrollRangeToVisible: selectRange];
640 //      [[mTextView window] makeKeyAndOrderFront:nil];
644 // no sc - actions supported
645 - (void*) getSCObject 
647         return NULL;
650 - (NSEnumerator *)scopeEnumerator 
653         NSEnumerator *enumerator;
654         if (mSearchScope == SMLAllDocumentsScope) {
655                 NSDocumentController *docctl = [NSDocumentController sharedDocumentController];
656                 enumerator = [[docctl documents] objectEnumerator];     
657         } else {
658                 enumerator = [[NSArray arrayWithObject:[[NSDocumentController sharedDocumentController] currentDocument]] objectEnumerator];
659         }
660         // no project at the moment
661         return enumerator;
665 - (id)currentlyDisplayedDocumentInAdvancedFind
667     return currentlyDisplayedDocumentInAdvancedFind; 
671 - (void)removeCurrentlyDisplayedDocumentInAdvancedFind
673 //      [SMLInterface removeAllSubviewsFromView:resultDocumentContentView];
674 //      NSArray *array = [NSArray arrayWithArray:[resultDocumentContentView subviews]];
675 //      NSEnumerator *enumerator = [array objectEnumerator];
676 //      id item;
677 //      while (item = [enumerator nextObject]) {
678 //              [item removeFromSuperview];
679 //              item = nil;
680 //      }
681         // NSTextView superview
682 //      NSTextStorage *textStorage = NSTextStorage;
683 //              mScrollView = [mTextView superview];
684 //              [mTextView removeFromSuperview];
685 //              [[mTextView textStorage] removeLayoutManager:[mTextView layoutManager]];        
687 //              [[mTextView layoutManager] replaceTextStorage: nil];
688                 if(mTextView) {
689                         [[mTextView textStorage] removeLayoutManager:[mTextView layoutManager]];                        
690                         [mCurrentDocument removeWindowController: myWindowController];
691                         [mTextView removeFromSuperview]; 
692                         mTextView = NULL; 
693                         mCurrentDocument = NULL;
694                         myWindowController =NULL;
695                         
696                 }
699 - (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item
701         #if 0
702         if ([[SMLDefaults valueForKey:@"SizeOfDocumentsListTextPopUp"] intValue] == 0) {
703                 [cell setFont:[NSFont systemFontOfSize:11.0]];
704         } else {
705         #endif
706                 [cell setFont:[NSFont systemFontOfSize:11.0]];
707         #if 0
708         }
709         #endif
710 }       
713 - (NSMutableDictionary *)preparedResultDictionaryFromString:(NSString *)completeString searchStringLength:(NSInteger)searchStringLength range:(NSRange)foundRange lineNumber:(NSInteger)lineNumber document:(id)document
715         NSMutableString *displayString = [[[NSMutableString alloc] init] autorelease];
716         NSString *lineNumberString = [NSString stringWithFormat:@"%d\t", lineNumber];
717         [displayString appendString:lineNumberString];
718         NSRange linesRange = [completeString lineRangeForRange:foundRange];
719         #if 0
720         [displayString appendString:[SMLText replaceAllNewLineCharactersWithSymbolInString:[completeString substringWithRange:linesRange]]];
721         #endif
722         [displayString appendString:[completeString substringWithRange:linesRange]];
723         
724         NSMutableDictionary *node = [NSMutableDictionary dictionary];
725         [node setValue:[NSNumber numberWithBool:YES] forKey:@"isLeaf"];
726 //      [node setValue:1 forKey:@"isLeaf"];
728         [node setValue:NSStringFromRange(foundRange) forKey:@"range"]; //orginal
729 //      [node setValue:lineNumberString forKey:@"displayString"]; // jt
731 //      [node setValue:[[document objectID] URIRepresentation] forKey:@"document"];
732 //      [node setValue:[SMLBasic uriFromObject:document] forKey:@"document"];
733         [node setValue:document forKey:@"document"];
735         NSInteger fontSize;
736 //      if ([[SMLDefaults valueForKey:@"SizeOfDocumentsListTextPopUp"] intValue] == 0) {
737 //              fontSize = 11;
738 //      } else {
739                 fontSize = 11;
740 //      }
743         NSMutableAttributedString *attributedString = [[[NSMutableAttributedString alloc] initWithString:displayString attributes:[NSDictionary dictionaryWithObject:[NSFont systemFontOfSize:fontSize] forKey:NSFontAttributeName]] autorelease];
744         NSMutableParagraphStyle *style = [[[NSMutableParagraphStyle alloc] init] autorelease];
745                 
746         [style setLineBreakMode:NSLineBreakByTruncatingMiddle];
747         [attributedString addAttribute:NSParagraphStyleAttributeName value:style range:NSMakeRange(0, [displayString length])];
748         [attributedString applyFontTraits:NSBoldFontMask range:NSMakeRange(foundRange.location - linesRange.location + [lineNumberString length], foundRange.length)];
749         [node setValue:attributedString forKey:@"displayString"];
751         return node;
755 - (void)alertThatThisIsNotAValidRegularExpression:(NSString *)string
757         NSString *title = [NSString stringWithFormat:NSLocalizedStringFromTable(@"%@ is not a valid regular expression", @"Localizable3", @"%@ is not a valid regular expression"), string];
758         NSBeginAlertSheet(title,
759                                           OKBUTTON,
760                                           nil,
761                                           nil,
762                                           advancedFindWindow,
763                                           self,
764                                           @selector(notAValidRegularExpressionSheetDidEnd:returnCode:contextInfo:),
765                                           nil,
766                                           nil,
767                                           @"");
771 - (void)notAValidRegularExpressionSheetDidEnd:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo
773         [sheet close];
774         [findResultsTreeController setContent:nil];
775         [findResultsTreeController setContent:[NSArray array]];
776         [advancedFindWindow makeKeyAndOrderFront:nil];
780 - (IBAction)searchScopeChanged:(id)sender
782          mSearchScope = [sender tag];
784         if (mSearchScope == SMLCurrentDocumentScope) {
785 //              [currentProjectScope setState:NSOffState];
786                 [allDocumentsScope setState:NSOffState];
787                 [currentDocumentScope setState:NSOnState]; // If the user has clicked an already clicked button make sure it is on and not turned off
788         } else if (mSearchScope == SMLCurrentProjectScope) {
789 //              [currentDocumentScope setState:NSOffState];
790 //              [allDocumentsScope setState:NSOffState];
791 //              [currentProjectScope setState:NSOnState];
792         } else if (mSearchScope == SMLAllDocumentsScope) {
793                 [currentDocumentScope setState:NSOffState];
794 //              [currentProjectScope setState:NSOffState];
795                 [allDocumentsScope setState:NSOnState];
796         }
797                 
798         if (![[findSearchField stringValue] isEqualToString:@""]) {
799                 [self findAction:nil];
800         }       
803 - (void)showRegularExpressionsHelpPanel
805         if (regularExpressionsHelpPanel == nil) {
806                 [NSBundle loadNibNamed:@"SMLRegularExpressionHelp.nib" owner:self];
807         }
808         
809         [regularExpressionsHelpPanel makeKeyAndOrderFront:nil];
810         
813 - (NSWindow *)advancedFindWindow
815     return advancedFindWindow; 
819 - (NSOutlineView *)findResultsOutlineView
821     return findResultsOutlineView; 
825 - (IBAction)showRegularExpressionsHelpPanelAction:(id)sender
827         [self showRegularExpressionsHelpPanel];
831 @end