mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-23 03:21:04 +00:00
Added code to share editing attributes and delegate between multiple
text views with the same layout manager git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@8371 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
9250be6b27
commit
9a852c5fe4
1 changed files with 162 additions and 17 deletions
|
@ -48,6 +48,20 @@
|
|||
|
||||
#define HUGE 1e7
|
||||
|
||||
#define SET_DELEGATE_NOTIFICATION(notif_name) \
|
||||
if ([_delegate respondsToSelector: @selector(textView##notif_name: )]) \
|
||||
[nc addObserver: _delegate \
|
||||
selector: @selector(textView##notif_name: ) \
|
||||
name: NSTextView##notif_name##Notification \
|
||||
object: _notifObject]
|
||||
|
||||
/* YES when in the process of synchronizing text view attributes.
|
||||
It is used to avoid recursive synchronizations. */
|
||||
static BOOL isSynchronizingFlags = NO;
|
||||
static BOOL isSynchronizingDelegate = NO;
|
||||
|
||||
/* The shared notification center */
|
||||
static NSNotificationCenter *nc;
|
||||
|
||||
@interface NSText(GNUstepPrivate)
|
||||
+ (NSDictionary*) defaultTypingAttributes;
|
||||
|
@ -67,6 +81,7 @@
|
|||
{
|
||||
[self setVersion: 1];
|
||||
[self registerForServices];
|
||||
nc = [NSNotificationCenter defaultCenter];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -256,10 +271,38 @@
|
|||
[self didChangeText];
|
||||
}
|
||||
|
||||
- (NSString *) string
|
||||
{
|
||||
return [_textStorage string];
|
||||
}
|
||||
|
||||
/*
|
||||
* NSTextView's specific methods
|
||||
*/
|
||||
|
||||
- (void) _updateMultipleTextViews
|
||||
{
|
||||
id oldNotifObject = _notifObject;
|
||||
|
||||
if ([[_layoutManager textContainers] count] > 1)
|
||||
{
|
||||
_tvf.multiple_textviews = YES;
|
||||
_notifObject = [_layoutManager firstTextView];
|
||||
}
|
||||
else
|
||||
{
|
||||
_tvf.multiple_textviews = NO;
|
||||
_notifObject = self;
|
||||
}
|
||||
|
||||
if ((_delegate != nil) && (oldNotifObject != _notifObject))
|
||||
{
|
||||
[nc removeObserver: _delegate name: nil object: oldNotifObject];
|
||||
SET_DELEGATE_NOTIFICATION (DidChangeSelection);
|
||||
SET_DELEGATE_NOTIFICATION (WillChangeNotifyingTextView);
|
||||
}
|
||||
}
|
||||
|
||||
/* This should only be called by [NSTextContainer -setTextView:] */
|
||||
- (void) setTextContainer: (NSTextContainer*)aTextContainer
|
||||
{
|
||||
|
@ -267,6 +310,8 @@
|
|||
_layoutManager = [aTextContainer layoutManager];
|
||||
_textStorage = [_layoutManager textStorage];
|
||||
|
||||
[self _updateMultipleTextViews];
|
||||
|
||||
// FIXME: Hack to get the layout change
|
||||
[_textContainer setContainerSize: _frame.size];
|
||||
}
|
||||
|
@ -277,6 +322,10 @@
|
|||
|
||||
/* Do not retain: text container is owning us. */
|
||||
_textContainer = aTextContainer;
|
||||
|
||||
[self _updateMultipleTextViews];
|
||||
|
||||
/* Update multiple_textviews flag */
|
||||
}
|
||||
|
||||
- (NSTextContainer *) textContainer
|
||||
|
@ -381,15 +430,88 @@
|
|||
return NSDragOperationNone;
|
||||
}
|
||||
|
||||
/*
|
||||
* Code to share settings between multiple textviews
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
_syncTextViewsCalling:withFlag: calls a set method on all text
|
||||
views sharing the same layout manager as this one. It sets the
|
||||
isSynchronizingFlags flag to YES to prevent recursive calls; calls the
|
||||
specified action on all the textviews (this one included) with the
|
||||
specified flag; sets back the isSynchronizingFlags flag to NO; then
|
||||
returns.
|
||||
|
||||
We need to explicitly call the methods - we can't copy the flags
|
||||
directly from one textview to another, to allow subclasses to
|
||||
override eg setEditable: to take some particular action when
|
||||
editing is turned on or off. */
|
||||
- (void) _syncTextViewsByCalling: (SEL)action withFlag: (BOOL)flag
|
||||
{
|
||||
NSArray *array;
|
||||
int i, count;
|
||||
void (*msg)(id, SEL, BOOL);
|
||||
|
||||
if (isSynchronizingFlags == YES)
|
||||
{
|
||||
[NSException raise: NSGenericException
|
||||
format: @"_syncTextViewsCalling:withFlag: "
|
||||
@"called recursively"];
|
||||
}
|
||||
|
||||
array = [_layoutManager textContainers];
|
||||
count = [array count];
|
||||
|
||||
msg = (void (*)(id, SEL, BOOL))[self methodForSelector: action];
|
||||
|
||||
if (!msg)
|
||||
{
|
||||
[NSException raise: NSGenericException
|
||||
format: @"invalid selector in "
|
||||
@"_syncTextViewsCalling:withFlag:"];
|
||||
}
|
||||
|
||||
isSynchronizingFlags = YES;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
NSTextView *tv;
|
||||
|
||||
tv = [(NSTextContainer *)[array objectAtIndex: i] textView];
|
||||
(*msg) (tv, action, flag);
|
||||
}
|
||||
|
||||
isSynchronizingFlags = NO;
|
||||
}
|
||||
|
||||
#define NSTEXTVIEW_SYNC(X) \
|
||||
if (_tvf.multiple_textviews && (isSynchronizingFlags == NO)) \
|
||||
[self _syncTextViewsByCalling: @selector(##X##) withFlag: flag]
|
||||
|
||||
- (void) setEditable: (BOOL)flag
|
||||
{
|
||||
NSTEXTVIEW_SYNC (setEditable:);
|
||||
[super setEditable: flag];
|
||||
/* FIXME/TODO: Update/show the insertion point */
|
||||
}
|
||||
|
||||
- (void) setFieldEditor: (BOOL)flag
|
||||
{
|
||||
NSTEXTVIEW_SYNC (setFieldEditor:);
|
||||
[super setFieldEditor: flag];
|
||||
}
|
||||
|
||||
- (void) setSelectable: (BOOL)flag
|
||||
{
|
||||
NSTEXTVIEW_SYNC (setSelectable:);
|
||||
[super setSelectable: flag];
|
||||
}
|
||||
|
||||
- (void) setRichText: (BOOL)flag
|
||||
{
|
||||
NSTEXTVIEW_SYNC (setRichText:);
|
||||
|
||||
[super setRichText: flag];
|
||||
[self updateDragTypeRegistration];
|
||||
/* FIXME/TODO: Also convert text to plain text or to rich text */
|
||||
|
@ -397,12 +519,15 @@
|
|||
|
||||
- (void) setImportsGraphics: (BOOL)flag
|
||||
{
|
||||
NSTEXTVIEW_SYNC (setImportsGraphics:);
|
||||
|
||||
[super setImportsGraphics: flag];
|
||||
[self updateDragTypeRegistration];
|
||||
}
|
||||
|
||||
- (void) setUsesRuler: (BOOL)flag
|
||||
{
|
||||
NSTEXTVIEW_SYNC (setUsesRuler:);
|
||||
_tf.uses_ruler = flag;
|
||||
}
|
||||
|
||||
|
@ -411,15 +536,19 @@
|
|||
return _tf.uses_ruler;
|
||||
}
|
||||
|
||||
- (void) setUsesFontPanel: (BOOL)flag
|
||||
{
|
||||
NSTEXTVIEW_SYNC (setUsesFontPanel:);
|
||||
[super setUsesFontPanel: flag];
|
||||
}
|
||||
|
||||
- (void) setRulerVisible: (BOOL)flag
|
||||
{
|
||||
NSTEXTVIEW_SYNC (setRulerVisible:);
|
||||
[super setRulerVisible: flag];
|
||||
}
|
||||
|
||||
- (BOOL) isRulerVisible
|
||||
{
|
||||
return _tf.is_ruler_visible;
|
||||
}
|
||||
#undef NSTEXTVIEW_SYNC
|
||||
|
||||
- (void) setSelectedRange: (NSRange)charRange
|
||||
{
|
||||
|
@ -947,8 +1076,8 @@ the affected range or replacement string before beginning changes, pass
|
|||
|
||||
- (void) didChangeText
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
postNotificationName: NSTextDidChangeNotification object: self];
|
||||
[nc postNotificationName: NSTextDidChangeNotification
|
||||
object: _notifObject];
|
||||
}
|
||||
|
||||
- (void) setSmartInsertDeleteEnabled: (BOOL)flag
|
||||
|
@ -1153,19 +1282,35 @@ container, returning the modified location. */
|
|||
|
||||
- (void) setDelegate: (id) anObject
|
||||
{
|
||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||
if (_tvf.multiple_textviews && (isSynchronizingDelegate == NO))
|
||||
{
|
||||
/* Invoke setDelegate: on all the textviews which share this
|
||||
delegate. */
|
||||
NSArray *array;
|
||||
int i, count;
|
||||
|
||||
isSynchronizingDelegate = YES;
|
||||
|
||||
array = [_layoutManager textContainers];
|
||||
count = [array count];
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
NSTextView *view;
|
||||
|
||||
view = [(NSTextContainer *)[array objectAtIndex: i] textView];
|
||||
[view setDelegate: anObject];
|
||||
}
|
||||
|
||||
isSynchronizingDelegate = NO;
|
||||
}
|
||||
|
||||
/* Now the real code to set the delegate */
|
||||
[super setDelegate: anObject];
|
||||
|
||||
#define SET_DELEGATE_NOTIFICATION(notif_name) \
|
||||
if ([_delegate respondsToSelector: @selector(textView##notif_name: )]) \
|
||||
[nc addObserver: _delegate \
|
||||
selector: @selector(textView##notif_name: ) \
|
||||
name: NSTextView##notif_name##Notification \
|
||||
object: self]
|
||||
|
||||
SET_DELEGATE_NOTIFICATION(DidChangeSelection);
|
||||
SET_DELEGATE_NOTIFICATION(WillChangeNotifyingTextView);
|
||||
|
||||
/* SET_DELEGATE_NOTIFICATION defined at the beginning of file */
|
||||
SET_DELEGATE_NOTIFICATION (DidChangeSelection);
|
||||
SET_DELEGATE_NOTIFICATION (WillChangeNotifyingTextView);
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
Loading…
Reference in a new issue