Keeping Text Views in Sync

I have two text views in separate windows of my application, but I need their contents to always be the same. While bindings seem to be an obvious answer, to use them, I have to enable “Continuously sets value” or something to that effect, which causes my application to lock up and never recover when I hide one of the text views. (The text views are in a split view, along with a web view). Since the applications is sometimes fullscreen, that can be quite a problem. :wink: In short, bindings seem to be out. I also tried setting the contents of one text view to a variable, and then loading that variable in the other one. While that transferred the text, that was it - no fonts, formatting, or images, all of which also need to be kept in sync. Is there any way to do this, or am I just out of luck?

Hi gonfunko,

I think this should work:

// file: textViewAddition.h

#import <Cocoa/Cocoa.h>

@interface NSText (textViewAddition)
-(void)syncTV:(NSText *)syncSource;
@end

// file: textViewAddition.m

#import "textViewAddition.h"

@implementation NSText (textViewAddition)  
-(void)syncTV:(NSText *)syncSource{
	NSRange sourceRange = NSMakeRange(0,[[syncSource string] length]);
	NSRange targetRange = NSMakeRange(0,[[self string] length]);
	[self replaceCharactersInRange:targetRange withRTFD:[syncSource RTFDFromRange:sourceRange]];
}
@end

after adding this category files to your project you can have the RTFD content of your text views synchronized - for example in ‘on end editing’:

global tvone, tvtwo

on awake from nib theObject
	set tvone to text view "tv1" of scroll view "sv1" of split view "splitview" of window "main"
	set tvtwo to text view "tv2" of scroll view "sv2" of split view "splitview" of window "main"
end awake from nib

on end editing theObject
	if theObject = tvone then
		set syncobj to tvtwo
	else
		set syncobj to tvone
	end if
	call method "syncTV:" of syncobj with parameter theObject
end end editing

D.

Thanks a ton - it works great! :smiley: I had to tweak the Applescripts a bit to make it fit what I’m trying to achieve, but the Objective-C does a great job. Thanks again!

If you don’t mind it being live as-you-type, you could try this method, which also uses Objective-C:

First, open your interface in Interface Builder, and create a NSObject subclass.
Add two outlets to the class for the text views, instantiate the class, and connect the outlets from the class in the Instances pane to the text views. Next, create the objective-c files for the class, and return to Xcode.

If you don’t understand the above then feel free to reply, and I’ll go through it step-by-step. It sounds like you already have some experience with Cocoa, though, since you say you’ve implemented full screen, something applescript studio can’t handle.

Anyway, in your class’s .m file, add the following:

- (void)awakeFromNib { [[textView2 layoutManager] replaceTextStorage:[textView1 textStorage]]; }
Easy. What this does is give both text views the same shared storage, so whatever appears or is changed in one gets reflected in the other, and vice versa.
According to the documentation:

As I said before, feel free to reply if you have any queries or problems.

That works even better! I think I’ll go with the straight Cocoa method, as it seems like it’s a bit faster, and probably more reliable. Thanks to both of you again. :slight_smile: