mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-22 13:10:59 +00:00
Implement a standard find panel for NSTextView.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@31068 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
72a86ed519
commit
86ff2f4099
9 changed files with 686 additions and 5 deletions
16
ChangeLog
16
ChangeLog
|
@ -1,3 +1,19 @@
|
|||
2010-08-02 Wolfgang Lux <wolfgang.lux@gmail.com>
|
||||
|
||||
* Source/NSTextView.m (-validateUserInterfaceItem:,
|
||||
-performFindPanelAction:): Implement find panel support.
|
||||
|
||||
* Source/GNUmakefile:
|
||||
* Source/GSTextFinder.h:
|
||||
* Source/GSTextFinder.m:
|
||||
* Panels/GNUmakefile:
|
||||
* Panels/English.lproj/GSFindPanel.gorm:
|
||||
New text finder and associated find panel.
|
||||
|
||||
* Source/NSTextView.m(currentVersion, -initWithTextView:,
|
||||
-encodeWithCoder:, -initWithCoder:): Archive the uses find panel
|
||||
attribute. This required updating the NSTextView version to 3.
|
||||
|
||||
2010-08-02 Fred Kiefer <FredKiefer@gmx.de>
|
||||
|
||||
* Source/NSButton.m,
|
||||
|
|
31
Panels/English.lproj/GSFindPanel.gorm/data.classes
Normal file
31
Panels/English.lproj/GSFindPanel.gorm/data.classes
Normal file
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"## Comment" = "Do NOT change this file, Gorm maintains it";
|
||||
FirstResponder = {
|
||||
Actions = (
|
||||
"findNext:",
|
||||
"findPrevious:",
|
||||
"replace:",
|
||||
"replaceAll:",
|
||||
"replaceAndFind:"
|
||||
);
|
||||
Super = NSObject;
|
||||
};
|
||||
GSTextFinder = {
|
||||
Actions = (
|
||||
"replaceAll:",
|
||||
"findNext:",
|
||||
"findPrevious:",
|
||||
"replace:",
|
||||
"replaceAndFind:"
|
||||
);
|
||||
Outlets = (
|
||||
findText,
|
||||
ignoreCaseButton,
|
||||
messageText,
|
||||
panel,
|
||||
replaceScopeMatrix,
|
||||
replaceText
|
||||
);
|
||||
Super = NSObject;
|
||||
};
|
||||
}
|
BIN
Panels/English.lproj/GSFindPanel.gorm/data.info
Normal file
BIN
Panels/English.lproj/GSFindPanel.gorm/data.info
Normal file
Binary file not shown.
BIN
Panels/English.lproj/GSFindPanel.gorm/objects.gorm
Normal file
BIN
Panels/English.lproj/GSFindPanel.gorm/objects.gorm
Normal file
Binary file not shown.
|
@ -34,7 +34,8 @@ LOCALIZED_RESOURCE_COMPONENTS = \
|
|||
GSPageLayout.gorm \
|
||||
GSPrintPanel.gorm \
|
||||
GSToolbarCustomizationPalette.gorm \
|
||||
GSSpellPanel.gorm
|
||||
GSSpellPanel.gorm \
|
||||
GSFindPanel.gorm
|
||||
|
||||
-include GNUmakefile.preamble
|
||||
|
||||
|
|
|
@ -217,6 +217,7 @@ GSKeyBindingAction.m \
|
|||
GSKeyBindingTable.m \
|
||||
NSTextView.m \
|
||||
NSTextView_actions.m \
|
||||
GSTextFinder.m \
|
||||
GSLayoutManager.m \
|
||||
GSTypesetter.m \
|
||||
GSHorizontalTypesetter.m \
|
||||
|
|
82
Source/GSTextFinder.h
Normal file
82
Source/GSTextFinder.h
Normal file
|
@ -0,0 +1,82 @@
|
|||
/* -*-objc-*-
|
||||
GSTextFinder.h
|
||||
|
||||
The private text finder class for NSTextView
|
||||
|
||||
Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
|
||||
Author: Wolfgang Lux <wolfgang.lux@gmail.com>
|
||||
Date: 2010
|
||||
|
||||
This file is part of the GNUstep GUI Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; see the file COPYING.LIB.
|
||||
If not, see <http://www.gnu.org/licenses/> or write to the
|
||||
Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef _GS_TEXT_FINDER_H
|
||||
#define _GS_TEXT_FINDER_H
|
||||
|
||||
#import <Foundation/NSObject.h>
|
||||
|
||||
@class NSString;
|
||||
@class NSButton;
|
||||
@class NSMatrix;
|
||||
@class NSPanel;
|
||||
@class NSTextField;
|
||||
|
||||
@interface GSTextFinder : NSObject
|
||||
{
|
||||
// local attributes
|
||||
NSString *findString;
|
||||
NSString *replaceString;
|
||||
|
||||
// GUI
|
||||
NSPanel *panel;
|
||||
NSTextField *findText;
|
||||
NSTextField *replaceText;
|
||||
NSTextField *messageText;
|
||||
NSMatrix *replaceScopeMatrix;
|
||||
NSButton *ignoreCaseButton;
|
||||
}
|
||||
|
||||
// return shared panel instance
|
||||
+ (GSTextFinder *) sharedTextFinder;
|
||||
|
||||
// UI actions
|
||||
- (void) findNext: (id)sender;
|
||||
- (void) findPrevious: (id)sender;
|
||||
- (void) replaceAndFind: (id)sender;
|
||||
- (void) replace: (id)sender;
|
||||
- (void) replaceAll: (id)sender;
|
||||
- (void) performFindPanelAction: (id)sender;
|
||||
- (void) performFindPanelAction: (id)sender
|
||||
withTextView: (NSTextView *)aTextView;
|
||||
- (BOOL) validateFindPanelAction: (id)sender
|
||||
withTextView: (NSTextView *)aTextView;
|
||||
|
||||
// text finder methods
|
||||
- (void) showFindPanel;
|
||||
- (void) takeFindStringFromTextView: (NSText *)aTextView;
|
||||
- (BOOL) findStringInTextView: (NSText *)aTextView forward: (BOOL)forward;
|
||||
- (void) replaceStringInTextView: (NSTextView *)aTextView;
|
||||
- (void) replaceAllInTextView: (NSTextView *)aTextView
|
||||
onlyInSelection: (BOOL)flag;
|
||||
- (NSTextView *) targetView: (NSTextView *)aTextView;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* _GS_TEXT_FINDER_H */
|
527
Source/GSTextFinder.m
Normal file
527
Source/GSTextFinder.m
Normal file
|
@ -0,0 +1,527 @@
|
|||
/** <title>GSTextFinder</title>
|
||||
|
||||
Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
|
||||
Author: Wolfgang Lux <wolfgang.lux@gmail.com>
|
||||
Date: July 2010
|
||||
|
||||
This file is part of the GNUstep GUI Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; see the file COPYING.LIB.
|
||||
If not, see <http://www.gnu.org/licenses/> or write to the
|
||||
Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#import "config.h"
|
||||
#import <Foundation/NSString.h>
|
||||
#import <Foundation/NSNotification.h>
|
||||
#import "AppKit/NSApplication.h"
|
||||
#import "AppKit/NSButton.h"
|
||||
#import "AppKit/NSEvent.h"
|
||||
#import "AppKit/NSGraphics.h"
|
||||
#import "AppKit/NSMatrix.h"
|
||||
#import "AppKit/NSNib.h"
|
||||
#import "AppKit/NSNibLoading.h"
|
||||
#import "AppKit/NSPanel.h"
|
||||
#import "AppKit/NSPasteboard.h"
|
||||
#import "AppKit/NSTextField.h"
|
||||
#import "AppKit/NSTextView.h"
|
||||
#import "AppKit/NSWindow.h"
|
||||
#import "GSGuiPrivate.h"
|
||||
#import "GSTextFinder.h"
|
||||
|
||||
|
||||
@interface GSTextFinder(PrivateMethods)
|
||||
- (BOOL) _loadPanel;
|
||||
- (void) _applicationDidBecomeActive: (NSNotification *)notification;
|
||||
- (void) _updateFindStringFromPanel: (unsigned *)options
|
||||
putToPasteboard: (BOOL)flag;
|
||||
- (void) _updateReplaceStringFromPanel;
|
||||
- (void) _getFindStringFromPasteboard;
|
||||
- (void) _putFindStringToPasteboard;
|
||||
@end
|
||||
|
||||
@implementation GSTextFinder
|
||||
|
||||
static GSTextFinder *sharedTextFinder;
|
||||
|
||||
+ (GSTextFinder *) sharedTextFinder
|
||||
{
|
||||
if (sharedTextFinder == nil)
|
||||
{
|
||||
sharedTextFinder = [[self alloc] init];
|
||||
}
|
||||
return sharedTextFinder;
|
||||
}
|
||||
|
||||
- (id) init
|
||||
{
|
||||
if ((self = [super init]) != nil)
|
||||
{
|
||||
// make sure our search and replace strings are never nil
|
||||
findString = @"";
|
||||
replaceString = @"";
|
||||
|
||||
// update find string from pasteboard whenever the application is
|
||||
// activated
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
addObserver: self
|
||||
selector: @selector(_applicationDidBecomeActive:)
|
||||
name: NSApplicationDidBecomeActiveNotification
|
||||
object: NSApp];
|
||||
[self _applicationDidBecomeActive: nil];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
removeObserver: self
|
||||
name: NSApplicationDidBecomeActiveNotification
|
||||
object: NSApp];
|
||||
|
||||
DESTROY(findString);
|
||||
DESTROY(replaceString);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
// UI actions
|
||||
- (void) findNext: (id)sender
|
||||
{
|
||||
if ([self findStringInTextView: [self targetView: nil] forward: YES])
|
||||
{
|
||||
// Special case here: If the user edits the find string and then presses
|
||||
// the Return key while the find text field (rather the panel's field
|
||||
// editor) is first responder, close the panel when a match was found.
|
||||
// This behavior is compatible with OpenStep and Mac OS X. However, in
|
||||
// contrast to Mac OS X, this cannot be implemented by associating a
|
||||
// dedicated action with the find text field, since the event is already
|
||||
// processed by the panel's default button before the field editor has a
|
||||
// chance of looking at it.
|
||||
|
||||
// NB I assume here that the only keyboard event that can trigger the
|
||||
// Next button's action while the field editor is active is a key down
|
||||
// event from the Return key.
|
||||
if ([[panel currentEvent] type] == NSKeyDown &&
|
||||
[findText currentEditor] != nil)
|
||||
{
|
||||
[panel close];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void) findPrevious: (id)sender
|
||||
{
|
||||
[self findStringInTextView: [self targetView: nil] forward: NO];
|
||||
}
|
||||
|
||||
- (void) replaceAndFind: (id)sender
|
||||
{
|
||||
NSTextView *targetView = [self targetView: nil];
|
||||
[self replaceStringInTextView: targetView];
|
||||
[self findStringInTextView: targetView forward: YES];
|
||||
}
|
||||
|
||||
- (void) replace: (id)sender
|
||||
{
|
||||
[self replaceStringInTextView: [self targetView: nil]];
|
||||
}
|
||||
|
||||
- (void) replaceAll: (id)sender
|
||||
{
|
||||
// NB In contrast to -performFindPanelAction: this UI action takes the current
|
||||
// selection in the Replace All Scope matrix into account
|
||||
[self replaceAllInTextView: [self targetView: nil]
|
||||
onlyInSelection: [replaceScopeMatrix selectedTag] != 0];
|
||||
}
|
||||
|
||||
- (void) performFindPanelAction: (id)sender
|
||||
{
|
||||
[self performFindPanelAction: sender withTextView: nil];
|
||||
}
|
||||
|
||||
- (void) performFindPanelAction: (id)sender
|
||||
withTextView: (NSTextView *)aTextView
|
||||
{
|
||||
aTextView = [self targetView: aTextView];
|
||||
switch ([sender tag])
|
||||
{
|
||||
case NSFindPanelActionShowFindPanel:
|
||||
[self showFindPanel];
|
||||
break;
|
||||
|
||||
case NSFindPanelActionNext:
|
||||
[self findStringInTextView: aTextView forward: YES];
|
||||
break;
|
||||
case NSFindPanelActionPrevious:
|
||||
[self findStringInTextView: aTextView forward: NO];
|
||||
break;
|
||||
|
||||
case NSFindPanelActionReplaceAll:
|
||||
[self replaceAllInTextView: aTextView onlyInSelection: NO];
|
||||
break;
|
||||
|
||||
case NSFindPanelActionReplace:
|
||||
[self replaceStringInTextView: aTextView];
|
||||
break;
|
||||
|
||||
case NSFindPanelActionReplaceAndFind:
|
||||
[self replaceStringInTextView: aTextView];
|
||||
[self findStringInTextView: aTextView forward: YES];
|
||||
break;
|
||||
|
||||
case NSFindPanelActionSetFindString:
|
||||
[self takeFindStringFromTextView: aTextView];
|
||||
break;
|
||||
|
||||
case NSFindPanelActionReplaceAllInSelection:
|
||||
[self replaceAllInTextView: aTextView onlyInSelection: YES];
|
||||
break;
|
||||
|
||||
case NSFindPanelActionSelectAll:
|
||||
NSLog(@"NSFindPanelActionSelectAll not supported");
|
||||
break;
|
||||
|
||||
case NSFindPanelActionSelectAllInSelection:
|
||||
NSLog(@"NSFindPanelActionSelectAllInSelection not supported");
|
||||
break;
|
||||
|
||||
default:
|
||||
NSLog(@"Unknown find panel action (%u)", [sender tag]);
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL) validateFindPanelAction: (id)sender
|
||||
withTextView: (NSTextView *)aTextView
|
||||
{
|
||||
aTextView = [self targetView: aTextView];
|
||||
switch ([sender tag])
|
||||
{
|
||||
case NSFindPanelActionShowFindPanel:
|
||||
return YES;
|
||||
|
||||
case NSFindPanelActionReplace:
|
||||
return aTextView != nil;
|
||||
|
||||
case NSFindPanelActionSetFindString:
|
||||
return aTextView && [aTextView selectedRange].length > 0;
|
||||
|
||||
case NSFindPanelActionNext:
|
||||
case NSFindPanelActionPrevious:
|
||||
case NSFindPanelActionReplaceAll:
|
||||
case NSFindPanelActionReplaceAndFind:
|
||||
#if 0 // NSTextView does not support discontinuous selections at present
|
||||
case NSFindPanelActionSelectAll:
|
||||
#endif
|
||||
return aTextView && [findString length] > 0;
|
||||
|
||||
case NSFindPanelActionReplaceAllInSelection:
|
||||
#if 0 // NSTextView does not support discontinuous selections at present
|
||||
case NSFindPanelActionSelectAllInSelection:
|
||||
#endif
|
||||
return [findString length] > 0
|
||||
&& aTextView && [aTextView selectedRange].length > 0;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// disable everything else
|
||||
return NO;
|
||||
}
|
||||
|
||||
// text finder methods
|
||||
- (void) showFindPanel
|
||||
{
|
||||
if (panel == nil && [self _loadPanel] == NO)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
[messageText setStringValue: @""];
|
||||
[panel makeKeyAndOrderFront: self];
|
||||
[findText selectText: self];
|
||||
}
|
||||
|
||||
- (void) takeFindStringFromTextView: (NSText *)aTextView
|
||||
{
|
||||
[messageText setStringValue: @""];
|
||||
if (aTextView != nil)
|
||||
{
|
||||
NSRange range = [aTextView selectedRange];
|
||||
if (range.length)
|
||||
{
|
||||
NSString *string = [[aTextView string] substringFromRange: range];
|
||||
ASSIGNCOPY(findString, string);
|
||||
[findText setStringValue: string];
|
||||
[findText selectText: self];
|
||||
[self _putFindStringToPasteboard];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL) findStringInTextView: (NSText *)aTextView
|
||||
forward: (BOOL)forward
|
||||
{
|
||||
NSRange range;
|
||||
NSRange selectedRange;
|
||||
NSString *string;
|
||||
unsigned int options = NSLiteralSearch | NSCaseInsensitiveSearch;
|
||||
|
||||
[messageText setStringValue: @""];
|
||||
if (aTextView == nil)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
string = [aTextView string];
|
||||
selectedRange = [aTextView selectedRange];
|
||||
[self _updateFindStringFromPanel: &options putToPasteboard: YES];
|
||||
if (forward)
|
||||
{
|
||||
range = NSMakeRange(NSMaxRange(selectedRange),
|
||||
[string length] - NSMaxRange(selectedRange));
|
||||
range = [string rangeOfString: findString
|
||||
options: options
|
||||
range: range];
|
||||
if (range.location == NSNotFound)
|
||||
{
|
||||
range = NSMakeRange(0, selectedRange.location);
|
||||
range = [string rangeOfString: findString
|
||||
options: options
|
||||
range: range];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
options |= NSBackwardsSearch;
|
||||
range = NSMakeRange(0, selectedRange.location);
|
||||
range = [string rangeOfString: findString
|
||||
options: options
|
||||
range: range];
|
||||
if (range.location == NSNotFound)
|
||||
{
|
||||
range = NSMakeRange(NSMaxRange(selectedRange),
|
||||
[string length] - NSMaxRange(selectedRange));
|
||||
range = [string rangeOfString: findString
|
||||
options: options
|
||||
range: range];
|
||||
}
|
||||
}
|
||||
|
||||
if (range.location != NSNotFound)
|
||||
{
|
||||
[aTextView setSelectedRange: range];
|
||||
[aTextView scrollRangeToVisible: range];
|
||||
}
|
||||
else
|
||||
{
|
||||
[messageText setStringValue: _(@"Not found")];
|
||||
NSBeep();
|
||||
}
|
||||
return range.location != NSNotFound;
|
||||
}
|
||||
|
||||
- (void) replaceStringInTextView: (NSTextView *)aTextView
|
||||
{
|
||||
[messageText setStringValue: @""];
|
||||
if (aTextView != nil)
|
||||
{
|
||||
NSRange range = [aTextView selectedRange];
|
||||
|
||||
if ([aTextView shouldChangeTextInRange: range
|
||||
replacementString: replaceString])
|
||||
{
|
||||
[self _updateReplaceStringFromPanel];
|
||||
[aTextView replaceCharactersInRange: range
|
||||
withString: replaceString];
|
||||
[aTextView didChangeText];
|
||||
[aTextView scrollRangeToVisible: range];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void) replaceAllInTextView: (NSTextView *)aTextView
|
||||
onlyInSelection: (BOOL)flag
|
||||
{
|
||||
int n;
|
||||
NSRange range, replaceRange;
|
||||
NSString *format;
|
||||
NSString *string;
|
||||
unsigned int options = NSLiteralSearch | NSCaseInsensitiveSearch;
|
||||
[messageText setStringValue: @""];
|
||||
if (aTextView == nil)
|
||||
return;
|
||||
|
||||
[self _updateFindStringFromPanel: &options putToPasteboard: YES];
|
||||
[self _updateReplaceStringFromPanel];
|
||||
string = [aTextView string];
|
||||
replaceRange =
|
||||
flag ? [aTextView selectedRange] : NSMakeRange(0, [string length]);
|
||||
|
||||
// look for a first match in the range
|
||||
range = [string rangeOfString: findString
|
||||
options: options
|
||||
range: replaceRange];
|
||||
if (range.location == NSNotFound)
|
||||
{
|
||||
[messageText setStringValue: _(@"Not found")];
|
||||
NSBeep();
|
||||
return;
|
||||
}
|
||||
|
||||
n = 0;
|
||||
do
|
||||
{
|
||||
if ([aTextView shouldChangeTextInRange: range
|
||||
replacementString: replaceString])
|
||||
{
|
||||
[aTextView replaceCharactersInRange: range
|
||||
withString: replaceString];
|
||||
[aTextView didChangeText];
|
||||
n++;
|
||||
}
|
||||
|
||||
replaceRange =
|
||||
NSMakeRange(range.location + [replaceString length],
|
||||
NSMaxRange(replaceRange) -
|
||||
(range.location + [findString length]));
|
||||
range = [string rangeOfString: findString
|
||||
options: options
|
||||
range: replaceRange];
|
||||
}
|
||||
while (range.location != NSNotFound);
|
||||
|
||||
format = _(@"%d replaced");
|
||||
[messageText setStringValue: [NSString stringWithFormat: format, n]];
|
||||
|
||||
// set insertion point to the end of the last match
|
||||
range = NSMakeRange(replaceRange.location, 0);
|
||||
[aTextView setSelectedRange: range];
|
||||
[aTextView scrollRangeToVisible: range];
|
||||
}
|
||||
|
||||
- (NSTextView *) targetView: (NSTextView *)aTextView
|
||||
{
|
||||
// If aTextView is equal to the find panel's field editor use the default
|
||||
// target view
|
||||
if (aTextView == [panel fieldEditor: NO forObject: [panel firstResponder]])
|
||||
{
|
||||
aTextView = nil;
|
||||
}
|
||||
|
||||
if (aTextView == nil)
|
||||
{
|
||||
// The default target is the first responder of the main window
|
||||
// provided that it is a text view
|
||||
id aResponder = [[NSApp mainWindow] firstResponder];
|
||||
if ([aResponder isKindOfClass: [NSTextView class]])
|
||||
{
|
||||
aTextView = aResponder;
|
||||
}
|
||||
}
|
||||
return aTextView;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation GSTextFinder(PrivateMethods)
|
||||
|
||||
- (void) _applicationDidBecomeActive: (NSNotification *)notification
|
||||
{
|
||||
[self _getFindStringFromPasteboard];
|
||||
}
|
||||
|
||||
- (BOOL) _loadPanel
|
||||
{
|
||||
NSDictionary *table =
|
||||
[NSDictionary dictionaryWithObject: self forKey: NSNibOwner];
|
||||
if (![GSGuiBundle() loadNibFile: @"GSFindPanel"
|
||||
externalNameTable: table
|
||||
withZone: [self zone]])
|
||||
{
|
||||
NSLog(@"Model file load failed for GSFindPanel");
|
||||
return NO;
|
||||
}
|
||||
|
||||
[findText setStringValue: findString];
|
||||
[replaceText setStringValue: replaceString];
|
||||
[messageText setStringValue: @""];
|
||||
|
||||
// FIXME Setting this in gorm does not have an effect
|
||||
[panel setFrameAutosaveName: @"NSFindPanel"];
|
||||
|
||||
// Make sure the Find menu is enabled when the panel's field editor is
|
||||
// first responder
|
||||
[(NSTextView *)[panel fieldEditor: YES forObject: nil] setUsesFindPanel: YES];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void) _updateFindStringFromPanel: (unsigned int *)options
|
||||
putToPasteboard: (BOOL)flag
|
||||
{
|
||||
if (panel)
|
||||
{
|
||||
ASSIGN(findString, [findText stringValue]);
|
||||
if ([ignoreCaseButton state] != NSOffState)
|
||||
{
|
||||
*options |= NSCaseInsensitiveSearch;
|
||||
}
|
||||
else
|
||||
{
|
||||
*options &= ~NSCaseInsensitiveSearch;
|
||||
}
|
||||
}
|
||||
|
||||
if (flag)
|
||||
{
|
||||
[self _putFindStringToPasteboard];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) _updateReplaceStringFromPanel
|
||||
{
|
||||
if (panel)
|
||||
{
|
||||
ASSIGN(replaceString, [replaceText stringValue]);
|
||||
}
|
||||
}
|
||||
|
||||
- (void) _getFindStringFromPasteboard
|
||||
{
|
||||
NSPasteboard *pboard = [NSPasteboard pasteboardWithName:NSFindPboard];
|
||||
if ([[pboard types] containsObject:NSStringPboardType])
|
||||
{
|
||||
NSString *string = [pboard stringForType:NSStringPboardType];
|
||||
if ([string length] && ![string isEqualToString:findString])
|
||||
{
|
||||
ASSIGN(findString, string);
|
||||
[findText setStringValue: string];
|
||||
[findText selectText: self];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void) _putFindStringToPasteboard
|
||||
{
|
||||
NSPasteboard *pboard = [NSPasteboard pasteboardWithName:NSFindPboard];
|
||||
[pboard declareTypes: [NSArray arrayWithObject:NSStringPboardType]
|
||||
owner: nil];
|
||||
[pboard setString: findString forType: NSStringPboardType];
|
||||
}
|
||||
|
||||
@end
|
|
@ -86,6 +86,7 @@
|
|||
#import "AppKit/NSTextView.h"
|
||||
#import "AppKit/NSWindow.h"
|
||||
#import "GSGuiPrivate.h"
|
||||
#import "GSTextFinder.h"
|
||||
|
||||
|
||||
/*
|
||||
|
@ -187,7 +188,8 @@ Interface for a bunch of internal methods that need to be cleaned up.
|
|||
([tv usesRuler]?0x100:0) |
|
||||
([tv smartInsertDeleteEnabled]?0x200:0) |
|
||||
([tv allowsUndo]?0x400:0) |
|
||||
([tv drawsBackground]?0x800:0));
|
||||
([tv drawsBackground]?0x800:0) |
|
||||
([tv usesFindPanel]?0x2000:0));
|
||||
|
||||
ASSIGN(backgroundColor, [tv backgroundColor]);
|
||||
ASSIGN(paragraphStyle, [tv defaultParagraphStyle]);
|
||||
|
@ -297,7 +299,7 @@ Interface for a bunch of internal methods that need to be cleaned up.
|
|||
|
||||
/**** Misc. helpers and stuff ****/
|
||||
|
||||
static const int currentVersion = 2;
|
||||
static const int currentVersion = 3;
|
||||
|
||||
static BOOL noLayoutManagerException(void)
|
||||
{
|
||||
|
@ -831,6 +833,8 @@ that makes decoding and encoding compatible with the old code.
|
|||
[aCoder encodeValueOfObjCType: @encode(BOOL) at: &flag];
|
||||
flag = _tf.allows_undo;
|
||||
[aCoder encodeValueOfObjCType: @encode(BOOL) at: &flag];
|
||||
flag = _tf.uses_find_panel;
|
||||
[aCoder encodeValueOfObjCType: @encode(BOOL) at: &flag];
|
||||
[aCoder encodeObject: _insertionPointColor];
|
||||
[aCoder encodeValueOfObjCType: @encode(NSSize) at: &containerSize];
|
||||
flag = [_textContainer widthTracksTextView];
|
||||
|
@ -901,6 +905,7 @@ that makes decoding and encoding compatible with the old code.
|
|||
_tf.smart_insert_delete = ((0x200 & flags) > 0);
|
||||
_tf.allows_undo = ((0x400 & flags) > 0);
|
||||
_tf.draws_background = ((0x800 & flags) > 0);
|
||||
_tf.uses_find_panel = ((0x2000 & flags) > 0);
|
||||
}
|
||||
|
||||
if ([aDecoder containsValueForKey: @"NSTVFlags"])
|
||||
|
@ -968,6 +973,11 @@ that makes decoding and encoding compatible with the old code.
|
|||
_tf.smart_insert_delete = flag;
|
||||
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &flag];
|
||||
_tf.allows_undo = flag;
|
||||
if (version >= 3)
|
||||
{
|
||||
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &flag];
|
||||
_tf.uses_find_panel = flag;
|
||||
}
|
||||
|
||||
/* build up the rest of the text system, which doesn't get stored
|
||||
<doesn't even implement the Coding protocol>. */
|
||||
|
@ -976,7 +986,7 @@ that makes decoding and encoding compatible with the old code.
|
|||
/* See initWithFrame: for comments on this RELEASE */
|
||||
RELEASE(self);
|
||||
|
||||
if (version == currentVersion)
|
||||
if (version >= 2)
|
||||
{
|
||||
NSSize containerSize;
|
||||
|
||||
|
@ -2966,6 +2976,17 @@ Scroll so that the beginning of the range is visible.
|
|||
|| sel_eq(action, @selector(centerSelectionInVisibleArea:)))
|
||||
return [self isSelectable];
|
||||
|
||||
if (sel_eq(action, @selector(performFindPanelAction:)))
|
||||
{
|
||||
if ([self usesFindPanel] == NO)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
return [[GSTextFinder sharedTextFinder]
|
||||
validateFindPanelAction: item
|
||||
withTextView: self];
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
@ -5496,7 +5517,9 @@ configuation! */
|
|||
|
||||
- (void) performFindPanelAction: (id)sender
|
||||
{
|
||||
// FIXME
|
||||
[[GSTextFinder sharedTextFinder]
|
||||
performFindPanelAction: sender
|
||||
withTextView: self];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
Loading…
Reference in a new issue