The R Project SVN R-packages

Rev

Rev 6233 | Rev 6243 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 6233 Rev 6238
Line 32... Line 32...
32
 *
32
 *
33
 */
33
 */
34
 
34
 
35
#import "RScriptEditorTextStorage.h"
35
#import "RScriptEditorTextStorage.h"
36
#import "RScriptEditorTypesetter.h"
36
#import "RScriptEditorTypesetter.h"
-
 
37
#import "RScriptEditorTextView.h"
37
#import "FoldingSignTextAttachmentCell.h"
38
#import "FoldingSignTextAttachmentCell.h"
38
#import "PreferenceKeys.h"
39
#import "RGUI.h"
39
 
40
 
40
@implementation RScriptEditorTextStorage
41
@implementation RScriptEditorTextStorage
41
 
42
 
42
@synthesize lineFoldingEnabled = _lineFoldingEnabled;
-
 
43
 
-
 
44
static NSTextAttachment *sharedAttachment = nil;
43
static NSTextAttachment *sharedAttachment = nil;
45
static SEL _getSel;
44
static SEL _getSel;
46
static SEL _setSel;
45
static SEL _setSel;
47
static SEL _strSel;
46
static SEL _strSel;
48
static SEL _replSel;
47
static SEL _replSel;
49
static SEL _editSel;
48
static SEL _editSel;
50
static SEL _getlSel;
49
static SEL _getlSel;
51
 
50
 
52
 
-
 
53
+ (void)initialize
51
+ (void)initialize
54
{
52
{
55
 
53
 
56
	if ([self class] == [RScriptEditorTextStorage class]) {
54
	if ([self class] == [RScriptEditorTextStorage class]) {
57
		FoldingSignTextAttachmentCell *cell = [[FoldingSignTextAttachmentCell alloc] initImageCell:nil];
55
		FoldingSignTextAttachmentCell *cell = [[FoldingSignTextAttachmentCell alloc] initImageCell:nil];
Line 85... Line 83...
85
		_replImp = [_attributedString methodForSelector:_replSel];
83
		_replImp = [_attributedString methodForSelector:_replSel];
86
		_editImp = [self methodForSelector:_editSel];
84
		_editImp = [self methodForSelector:_editSel];
87
		_getlImp = [_attributedString methodForSelector:_getlSel];
85
		_getlImp = [_attributedString methodForSelector:_getlSel];
88
 
86
 
89
		foldedCounter = 0;
87
		foldedCounter = 0;
-
 
88
		currentMaxFoldedIndex = -1;
90
 
89
 
91
		for(NSInteger i = 0; i < R_MAX_FOLDED_ITEMS; i++) {
90
		for(NSInteger i = 0; i < R_MAX_FOLDED_ITEMS; i++) {
92
			foldedRanges[i][0] = -1;
91
			foldedRanges[i][0] = -1;
93
			foldedRanges[i][1] = 0;
92
			foldedRanges[i][1] = 0;
-
 
93
			foldedRanges[i][2] = 0;
94
		}
94
		}
95
	}
95
	}
96
 
96
 
97
	return self;
97
	return self;
98
}
98
}
Line 108... Line 108...
108
- (BOOL)hasFoldedItems
108
- (BOOL)hasFoldedItems
109
{
109
{
110
	return (foldedCounter == 0) ? NO : YES;
110
	return (foldedCounter == 0) ? NO : YES;
111
}
111
}
112
 
112
 
-
 
113
- (BOOL)inFoldedRangeForRange:(NSRange)range
-
 
114
{
-
 
115
	if(!foldedCounter) return NO;
-
 
116
 
-
 
117
	NSInteger i = 0;
-
 
118
	NSInteger maxRange = NSMaxRange(range);
-
 
119
	NSInteger rangeLoc = range.location;
-
 
120
	for(i = 0; i < currentMaxFoldedIndex+1; i++) {
-
 
121
		if(rangeLoc > foldedRanges[i][0] && maxRange <= foldedRanges[i][2]) {
-
 
122
			return YES;
-
 
123
		}
-
 
124
	}
-
 
125
	return NO;
-
 
126
	
-
 
127
}
-
 
128
 
113
- (NSInteger)foldedAtIndex:(NSInteger)index
129
- (NSInteger)foldedAtIndex:(NSInteger)index
114
{
130
{
115
 
131
 
116
	if(!foldedCounter) return -1;
132
	if(!foldedCounter) return -1;
117
 
133
 
118
	NSInteger i = 0;
134
	NSInteger i = 0;
119
	for(i = 0; i < R_MAX_FOLDED_ITEMS; i++) {
135
	for(i = 0; i < currentMaxFoldedIndex+1; i++) {
120
		if(foldedRanges[i][0] <= index && foldedRanges[i][0]+foldedRanges[i][1] > index) {
136
		if(foldedRanges[i][2] > index && foldedRanges[i][0] <= index) {
121
			return i;
137
			return i;
122
		}
138
		}
123
	}
139
	}
124
	return -1;
140
	return -1;
125
}
141
}
Line 129... Line 145...
129
 
145
 
130
	if(!foldedCounter) return -1;
146
	if(!foldedCounter) return -1;
131
 
147
 
132
	if(index) {
148
	if(index) {
133
		// Folded ranges are stored from { to } but indicator will drawn inside of { and }
149
		// Folded ranges are stored from { to } but indicator will drawn inside of { and }
-
 
150
		NSInteger adjIndex = index + 1;
134
		for(NSInteger i = 0; i < R_MAX_FOLDED_ITEMS; i++) {
151
		for(NSInteger i = 0; i < currentMaxFoldedIndex+1; i++) {
135
			if(foldedRanges[i][0] > -1 && foldedRanges[i][0] <= (index-1) && foldedRanges[i][0]+foldedRanges[i][1] > index+1) {
152
			if(foldedRanges[i][2] > adjIndex && foldedRanges[i][0] < index) {
136
				return i;
153
				return i;
137
			}
154
			}
138
		}
155
		}
139
	}
156
	}
140
	return -1;
157
	return -1;
141
}
158
}
142
 
159
 
143
- (NSInteger)registerFoldedRange:(NSRange)range
160
- (NSInteger)registerFoldedRange:(NSRange)range
144
{
161
{
145
 
162
 
-
 
163
 
-
 
164
	[[[self delegate] undoManager] disableUndoRegistration];
-
 
165
 
146
	NSInteger index = -1;
166
	NSInteger index = -1;
147
	for(NSInteger i = 0; i < R_MAX_FOLDED_ITEMS; i++) {
167
	for(NSInteger i = 0; i < R_MAX_FOLDED_ITEMS; i++) {
148
		if(foldedRanges[i][0] == -1) {
168
		if(foldedRanges[i][0] == -1) {
149
			index = i;
169
			index = i;
150
			foldedRanges[i][0] = (NSInteger)range.location;
170
			foldedRanges[i][0] = (NSInteger)range.location;
151
			foldedRanges[i][1] = (NSInteger)range.length;
171
			foldedRanges[i][1] = (NSInteger)range.length;
-
 
172
			foldedRanges[i][2] = (NSInteger)NSMaxRange(range);
152
			foldedCounter++;
173
			foldedCounter++;
-
 
174
			if(i > currentMaxFoldedIndex) currentMaxFoldedIndex = i;
-
 
175
			SLog(@"RScriptEditorTextStorage:registerFoldedRange %@ at position %d : max index %d", NSStringFromRange(range), i, currentMaxFoldedIndex);
153
			break;
176
			break;
154
		}
177
		}
155
	}
178
	}
156
 
179
 
-
 
180
	[[[self delegate] undoManager] enableUndoRegistration];
-
 
181
 
157
	return(index);
182
	return(index);
158
 
183
 
159
}
184
}
160
 
185
 
161
- (BOOL)removeFoldedRangeWithId:(NSNumber*)index
186
- (BOOL)removeFoldedRangeWithIndex:(NSInteger)index
162
{
187
{
163
 
188
 
-
 
189
	BOOL exists = NO;
-
 
190
	NSRange range;
-
 
191
	
-
 
192
	SLog(@"RScriptEditorTextStorage:removeFoldedRangeWithIndex %d", i);
-
 
193
	
164
	NSInteger i = [index integerValue];
194
	if(index > -1 && index < R_MAX_FOLDED_ITEMS) {
-
 
195
		if(foldedRanges[index][0] > -1 && foldedRanges[index][1] > 0) {
-
 
196
			range = NSMakeRange(foldedRanges[index][0], foldedRanges[index][1]);
-
 
197
			exists = YES;
-
 
198
		}
-
 
199
	}
165
 
200
 
166
	if(i < 0 || i >= R_MAX_FOLDED_ITEMS) {
201
	if(!exists) {
167
		[self removeAllFoldedRanges];
202
		[self removeAllFoldedRanges];
-
 
203
		NSLog(@"Removing folded text chunk failed. For safety reasons all folded chunks were be unfolded.");
168
		return NO;
204
		return NO;
169
	}
205
	}
170
 
206
 
171
	[[[self delegate] undoManager] disableUndoRegistration];
207
	[[[self delegate] undoManager] disableUndoRegistration];
172
 
208
 
173
	NSRange range = NSMakeRange(foldedRanges[i][0], foldedRanges[i][1]);
-
 
174
	range = NSIntersectionRange(NSMakeRange(0, [_attributedString length]), range);
209
	range = NSIntersectionRange(NSMakeRange(0, [[_attributedString string] length]), range);
175
	if(range.length) {
210
	if(range.length) {
176
		[self beginEditing];
-
 
177
		// [self removeAttribute:foldingAttributeName range:range];
-
 
178
		[self removeAttribute:foldingAttributeId range:range];
-
 
179
		[self removeAttribute:NSCursorAttributeName range:range];
211
		[self removeAttribute:NSCursorAttributeName range:range];
180
		[self removeAttribute:NSToolTipAttributeName range:range];
212
		[self removeAttribute:NSToolTipAttributeName range:range];
181
		[self endEditing];
-
 
182
	}
213
	}
183
 
214
 
184
	foldedRanges[i][0] = -1;
215
	foldedRanges[index][0] = -1;
185
	foldedRanges[i][1] = 0;
216
	foldedRanges[index][1] = 0;
-
 
217
	foldedRanges[index][2] = 0;
186
	foldedCounter--;
218
	foldedCounter--;
187
	if(foldedCounter < 0) foldedCounter = 0;
219
	if(foldedCounter < 0) foldedCounter = 0;
188
 
220
 
-
 
221
	// check folded chunks inside range
-
 
222
	NSInteger rloc = range.location;
-
 
223
	NSInteger maxrlen = NSMaxRange(range);
-
 
224
	NSRange r;
-
 
225
	for(NSInteger j = currentMaxFoldedIndex; j >= 0; j--) {
-
 
226
		if(foldedRanges[j][0] > rloc && foldedRanges[j][2] < maxrlen) {
-
 
227
			r = NSMakeRange(foldedRanges[j][0], foldedRanges[j][1]);
-
 
228
			foldedRanges[j][0] = -1;
-
 
229
			foldedRanges[j][1] = 0;
-
 
230
			foldedRanges[j][2] = 0;
-
 
231
			[[self delegate] refoldLinesInRange:r];
-
 
232
		}
-
 
233
	}
-
 
234
 
189
	[[[self delegate] undoManager] enableUndoRegistration];
235
	[[[self delegate] undoManager] enableUndoRegistration];
-
 
236
	
-
 
237
	// update currentMaxFoldedIndex
-
 
238
	NSInteger maxCount = -1;
-
 
239
	for(NSInteger i = 0; i < R_MAX_FOLDED_ITEMS; i++) {
-
 
240
		if(foldedRanges[i][0] > -1) {
-
 
241
			if(i > maxCount) maxCount = i;
-
 
242
		}
-
 
243
	}
-
 
244
	currentMaxFoldedIndex = maxCount;
-
 
245
	SLog(@"RScriptEditorTextStorage:removeFoldedRangeWithIndex: done. Max index: %d", currentMaxFoldedIndex);
190
 
246
 
191
	return YES;
247
	return YES;
192
}
248
}
193
 
249
 
194
- (void)removeAllFoldedRanges
250
- (void)removeAllFoldedRanges
195
{
251
{
-
 
252
 
-
 
253
	[[[self delegate] undoManager] disableUndoRegistration];
-
 
254
 
196
	for(NSInteger i = 0; i < R_MAX_FOLDED_ITEMS; i++) {
255
	for(NSInteger i = 0; i < R_MAX_FOLDED_ITEMS; i++) {
197
		foldedRanges[i][0] = -1;
256
		foldedRanges[i][0] = -1;
198
		foldedRanges[i][1] = 0;
257
		foldedRanges[i][1] = 0;
-
 
258
		foldedRanges[i][2] = 0;
199
	}
259
	}
200
	[[[self delegate] undoManager] disableUndoRegistration];
-
 
201
	NSRange range = NSMakeRange(0, [_attributedString length]);
260
	NSRange range = NSMakeRange(0, [_attributedString length]);
202
	[self beginEditing];
-
 
203
	// [self removeAttribute:foldingAttributeName range:range];
-
 
204
	[self removeAttribute:foldingAttributeId range:range];
-
 
205
	[self removeAttribute:NSCursorAttributeName range:range];
261
	[self removeAttribute:NSCursorAttributeName range:range];
206
	[self removeAttribute:NSToolTipAttributeName range:range];
262
	[self removeAttribute:NSToolTipAttributeName range:range];
207
	[self endEditing];
-
 
208
	[[[self delegate] undoManager] enableUndoRegistration];
-
 
-
 
263
 
209
	foldedCounter = 0;
264
	foldedCounter = 0;
-
 
265
	currentMaxFoldedIndex = -1;
-
 
266
 
-
 
267
	[[[self delegate] undoManager] enableUndoRegistration];
-
 
268
 
210
}
269
}
211
 
270
 
212
- (BOOL)existsFoldedRange:(NSRange)range
271
- (BOOL)existsFoldedRange:(NSRange)range
213
{
272
{
214
 
273
 
215
	if(!foldedCounter) return NO;
274
	if(!foldedCounter) return NO;
216
 
275
 
217
	BOOL success = NO;
276
	BOOL success = NO;
218
	for(NSInteger i = 0; i < R_MAX_FOLDED_ITEMS; i++) {
277
	for(NSInteger i = 0; i < currentMaxFoldedIndex+1; i++) {
219
		if(foldedRanges[i][0] == range.location && foldedRanges[i][1] == range.length) {
278
		if(foldedRanges[i][0] == range.location && foldedRanges[i][1] == range.length) {
220
			success = YES;
279
			success = YES;
221
			break;
280
			break;
222
		}
281
		}
223
	}
282
	}
Line 230... Line 289...
230
{
289
{
231
 
290
 
232
	if(!foldedCounter || index < 0 || index > R_MAX_FOLDED_ITEMS) return NSMakeRange(NSNotFound, 0);
291
	if(!foldedCounter || index < 0 || index > R_MAX_FOLDED_ITEMS) return NSMakeRange(NSNotFound, 0);
233
 
292
 
234
	NSInteger loc = foldedRanges[index][0];
293
	NSInteger loc = foldedRanges[index][0];
-
 
294
 
235
	if(loc == -1) return NSMakeRange(NSNotFound, 0);
295
	if(loc == -1) return NSMakeRange(NSNotFound, 0);
-
 
296
 
236
	return NSMakeRange(loc, foldedRanges[index][1]-foldedRanges[index][0]);
297
	return NSMakeRange(loc, foldedRanges[index][1]-foldedRanges[index][0]);
-
 
298
 
237
}
299
}
-
 
300
#pragma mark -
-
 
301
#pragma mark Primitives
238
 
302
 
239
// NSAttributedString primitives
-
 
240
- (NSString *)string
303
- (NSString *)string
241
{ 
304
{ 
242
	return (*_strImp)(_attributedString, _strSel);
305
	return (*_strImp)(_attributedString, _strSel);
243
}
306
}
244
 
307
 
Line 253... Line 316...
253
 
316
 
254
	// Check if location is inside folded range for drawing indicator
317
	// Check if location is inside folded range for drawing indicator
255
	NSInteger index = -1;
318
	NSInteger index = -1;
256
	if(location) {
319
	if(location) {
257
		// Notes folded ranges are stored from { to } but indicator will drawn inside of { and }
320
		// Notes folded ranges are stored from { to } but indicator will drawn inside of { and }
-
 
321
		NSInteger adjLocation = location + 2;
258
		for(NSInteger i = 0; i < R_MAX_FOLDED_ITEMS; i++) {
322
		for(NSInteger i = 0; i < currentMaxFoldedIndex+1; i++) {
259
			if(foldedRanges[i][0] <= (location-1) && foldedRanges[i][0]+foldedRanges[i][1] > location+2) {
323
			if(foldedRanges[i][2] > adjLocation && foldedRanges[i][0] < location) {
260
				index = i;
324
				index = i;
261
				break;
325
				break;
262
			}
326
			}
263
		}
327
		}
264
	}
328
	}
265
 
329
 
266
	if (index > -1) {
330
	if (index > -1) {
267
		effectiveRange = NSMakeRange(foldedRanges[index][0]+1, foldedRanges[index][1]-2);
331
		effectiveRange = NSMakeRange(foldedRanges[index][0]+1, foldedRanges[index][1]-2);
268
		// We adds NSAttachmentAttributeName if in lineFoldingAttributeName
332
		// We adds NSAttachmentAttributeName if location is at beginning of folded range
269
		if (location == effectiveRange.location) { // beginning of a folded range
333
		if (location == effectiveRange.location) { // beginning of a folded range
270
 
334
 
271
			NSMutableDictionary *dict = [attributes mutableCopyWithZone:NULL];
335
			NSMutableDictionary *dict = [attributes mutableCopyWithZone:NULL];
272
			[dict setObject:sharedAttachment forKey:NSAttachmentAttributeName];
336
			[dict setObject:sharedAttachment forKey:NSAttachmentAttributeName];
273
			attributes = [dict autorelease];
337
			attributes = [dict autorelease];
Line 285... Line 349...
285
 
349
 
286
- (void)edited:(NSUInteger)mask range:(NSRange)oldRange changeInLength:(NSInteger)lengthChange
350
- (void)edited:(NSUInteger)mask range:(NSRange)oldRange changeInLength:(NSInteger)lengthChange
287
{
351
{
288
 
352
 
289
	if(foldedCounter && mask == NSTextStorageEditedCharacters) {
353
	if(foldedCounter && mask == NSTextStorageEditedCharacters) {
290
		// update foldedRanges array
354
		// update foldedRanges array due to changes
291
		NSInteger index = oldRange.location;
355
		NSInteger index = oldRange.location-1;
-
 
356
		NSInteger maxOldRange = NSMaxRange(oldRange) + 1;
292
		for(NSInteger i = 0; i < R_MAX_FOLDED_ITEMS; i++) {
357
		for(NSInteger i = 0; i < currentMaxFoldedIndex+1; i++) {
293
			if(index < foldedRanges[i][0]) {
358
			if(index < foldedRanges[i][0]) {
-
 
359
				// if change covers the entire folded range -> delete it
294
				if(foldedRanges[i][0] >= oldRange.location && foldedRanges[i][0]+foldedRanges[i][1] <= NSMaxRange(oldRange)) {
360
				if(foldedRanges[i][2] < maxOldRange && foldedRanges[i][0] > index) {
295
					[self removeFoldedRangeWithId:[NSNumber numberWithInt:i]];
361
					[self removeFoldedRangeWithIndex:i];
296
					continue;
362
					continue;
297
				}
363
				}
-
 
364
				// otherwise correct folded start range and maxrange
298
				foldedRanges[i][0] += lengthChange;
365
				foldedRanges[i][0] += lengthChange;
-
 
366
				foldedRanges[i][2] += lengthChange;
-
 
367
				// for safety delete it if new location is negative
299
				if(foldedRanges[i][0] < -1) {
368
				if(foldedRanges[i][0] < 0) {
300
					[self removeFoldedRangeWithId:[NSNumber numberWithInt:i]];
369
					[self removeFoldedRangeWithIndex:i];
301
				}
370
				}
302
			}
371
			}
303
		}
372
		}
304
	}
373
	}
305
 
374