/[gnustep]/gnustep/usr-apps/gworkspace/GWLib/Browser2.m
ViewVC logotype

Contents of /gnustep/usr-apps/gworkspace/GWLib/Browser2.m

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.3 - (show annotations) (download)
Fri Sep 26 10:25:37 2003 UTC (20 years, 7 months ago) by esersale
Branch: MAIN
Changes since 1.2: +2 -2 lines
*** empty log message ***

1 /* Browser2.m
2 *
3 * Copyright (C) 2003 Free Software Foundation, Inc.
4 *
5 * Author: Enrico Sersale <enrico@imago.ro>
6 * Date: August 2001
7 *
8 * This file is part of the GNUstep GWorkspace application
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 */
24
25 #include <Foundation/Foundation.h>
26 #include <AppKit/AppKit.h>
27 #include "GWProtocol.h"
28 #include "GWFunctions.h"
29 #include "GWNotifications.h"
30 #include <math.h>
31 #include "Browser2.h"
32 #include "BColumn.h"
33 #include "BCell.h"
34 #include "BIcon.h"
35 #include "BNameEditor.h"
36 #include "GNUstep.h"
37
38 #define NSBR_VOFFSET 4
39 #define BEZEL_BORDER_SIZE NSMakeSize(2, 2)
40 #define ICON_FRAME_HEIGHT 52
41 #define ICON_SIZE_WIDTH 48
42 #define ICON_VOFFSET 14
43 #define LINE_SCROLL 10
44 #define LABEL_HEIGHT 14
45 #define LABEL_MARGIN 8
46 #define EDIT_MARGIN 4
47
48 #define CHECKRECT(rct) \
49 if (rct.size.width < 0) rct.size.width = 0; \
50 if (rct.size.height < 0) rct.size.height = 0
51
52 #define CHECKSIZE(sz) \
53 if (sz.width < 0) sz.width = 0; \
54 if (sz.height < 0) sz.height = 0
55
56 #ifndef max
57 #define max(a,b) ((a) >= (b) ? (a):(b))
58 #endif
59
60 #ifndef min
61 #define min(a,b) ((a) <= (b) ? (a):(b))
62 #endif
63
64 double myrintf(double a)
65 {
66 return (floor(a + 0.5));
67 }
68
69 @implementation Browser2
70
71 - (void)dealloc
72 {
73 RELEASE (columns);
74 if (colRects != NULL) {
75 NSZoneFree (NSDefaultMallocZone(), colRects);
76 }
77 RELEASE (cellPrototype);
78 RELEASE (scroller);
79 RELEASE (pathSeparator);
80 RELEASE (basePath);
81 RELEASE (nameEditor);
82 RELEASE (editorFont);
83 TEST_RELEASE (doubleClickSelection);
84 TEST_RELEASE (charBuffer);
85 TEST_RELEASE (waitCursor);
86 [super dealloc];
87 }
88
89 - (id)initWithBasePath:(NSString *)bpath
90 visibleColumns:(int)vcols
91 styleMask:(int)mask
92 delegate:(id)anobject
93 remoteHost:(NSString *)rhost
94 {
95 self = [super init];
96
97 if (self) {
98 #ifdef GNUSTEP
99 Class gwclass = [[NSBundle mainBundle] principalClass];
100 #else
101 Class gwclass = [[NSBundle mainBundle] classNamed: @"GWorkspace"];
102 #endif
103 NSRect rect = NSMakeRect(0, 0, 600, 200);
104 NSSize bs = BEZEL_BORDER_SIZE;
105 int i;
106
107 createEmptySel = @selector(createEmptyColumn);
108 createEmpty = [self methodForSelector: createEmptySel];
109
110 addAndLoadSel = @selector(addAndLoadColumnForPaths:);
111 addAndLoad = [self methodForSelector: addAndLoadSel];
112
113 unloadFromSel = @selector(unloadFromColumn:);
114 unloadFrom = [self methodForSelector: unloadFromSel];
115
116 lastColumnSel = @selector(setLastColumn:);
117 lastColumn = [self methodForSelector: lastColumnSel];
118
119 setPathsSel = @selector(setCurrentPaths:);
120 setPaths = [[BColumn class] instanceMethodForSelector: setPathsSel];
121
122 gworkspace = (id<GWProtocol>)[gwclass gworkspace];
123
124 if (rhost) {
125 isRemote = YES;
126 ASSIGN (remoteHostName, rhost);
127 waitCursor = [[NSCursor alloc] initWithImage: [NSImage imageNamed: @"watch.tiff"]];
128 [waitCursor setHotSpot: NSMakePoint(8, 8)];
129 [NSCursor setHiddenUntilMouseMoves: NO];
130 } else {
131 isRemote = NO;
132 remoteHostName = nil;
133 }
134
135 [self setFrame: rect];
136 visibleColumns = vcols;
137 ASSIGN (basePath, bpath);
138 delegate = anobject;
139 styleMask = mask;
140 canUpdateViews = YES;
141
142 colRects = NULL;
143 columnWidth = (rect.size.width / (float)visibleColumns);
144 scrollerWidth = [NSScroller scrollerWidth];
145 iconsPathWidth = 96 - scrollerWidth;
146 if (styleMask & GWColumnIconMask) {
147 columnOriginY = 0;
148 } else {
149 columnOriginY = scrollerWidth + (4 * bs.height);
150 }
151
152 ASSIGN (pathSeparator, fixPath(@"/", 0));
153
154 if (styleMask & GWIconCellsMask) {
155 cellPrototype = [[BCell alloc] initIconCell];
156 } else {
157 cellPrototype = [[BCell alloc] init];
158 }
159
160 columns = [[NSMutableArray alloc] init];
161 getSel = @selector(objectAtIndex:);
162 getImp = [columns methodForSelector: getSel];
163 indexSel = @selector(indexOfObject:);
164 indexImp = (intIMP)[columns methodForSelector: indexSel];
165
166 scrollerRect.origin.x = bs.width;
167 if (styleMask & GWColumnIconMask) {
168 scrollerRect.origin.y = [self frame].size.height - iconsPathWidth - scrollerWidth;
169 } else {
170 scrollerRect.origin.y = bs.height;
171 }
172 scrollerRect.size.width = [self frame].size.width - (2 * bs.width);
173 scrollerRect.size.height = scrollerWidth;
174 scroller = [[NSScroller alloc] initWithFrame: scrollerRect];
175 [scroller setTarget: self];
176 [scroller setAction: @selector(scrollViaScroller:)];
177 [self addSubview: scroller];
178
179 rect = [self frame];
180
181 for (i = 0; i < visibleColumns; i++) {
182 (*createEmpty)(self, createEmptySel);
183 }
184
185 nameEditor = [[BNameEditor alloc] init];
186 [nameEditor setDelegate: self];
187 [nameEditor setTarget: self];
188 [nameEditor setAction: @selector(editorAction:)];
189 ASSIGN (editorFont, [NSFont systemFontOfSize: 12]);
190 [nameEditor setFont: editorFont];
191 [nameEditor setBezeled: NO];
192 [nameEditor setAlignment: NSCenterTextAlignment];
193 [nameEditor setBackgroundColor: [NSColor whiteColor]];
194 edCol = nil;
195 isEditingIconName = NO;
196
197 firstVisibleColumn = 0;
198 lastVisibleColumn = visibleColumns - 1;
199 currentshift = 0;
200 lastColumnLoaded = -1;
201 alphaNumericalLastColumn = -1;
202
203 skipUpdateScroller = NO;
204 lastKeyPressed = 0.;
205 charBuffer = nil;
206 doubleClickSelection = nil;
207 simulatingDoubleClick = NO;
208 isLoaded = NO;
209 }
210
211 return self;
212 }
213
214 - (void)setPathAndSelection:(NSArray *)selection
215 {
216 NSString *path;
217 NSArray *subStrings;
218 NSString *aStr;
219 NSString *progrPath;
220 unsigned numberOfSubStrings;
221 unsigned i;
222 int column;
223 BColumn *selCol;
224
225 canUpdateViews = NO;
226
227 [self loadColumnZero];
228
229 if (selection == nil || [[selection objectAtIndex: 0] isEqual: basePath]) {
230 canUpdateViews = YES;
231 [self tile];
232 [self setNeedsDisplay: YES];
233 if (isRemote) {
234 [[NSCursor arrowCursor] set];
235 }
236 return;
237 }
238
239 if ([selection count] > 1) {
240 path = [[selection objectAtIndex: 0] stringByDeletingLastPathComponent];
241 } else {
242 path = [selection objectAtIndex: 0];
243 }
244
245 if ([basePath isEqualToString: pathSeparator] == NO) {
246 NSRange range = [path rangeOfString: basePath];
247
248 if (range.length == 0) {
249 ASSIGN (basePath, pathSeparator);
250 [self loadColumnZero];
251 subStrings = [path componentsSeparatedByString: pathSeparator];
252
253 } else {
254 NSString *rpath = [path substringFromIndex: [basePath cStringLength]];
255 subStrings = [rpath componentsSeparatedByString: pathSeparator];
256 }
257
258 } else {
259 subStrings = [path componentsSeparatedByString: pathSeparator];
260 }
261
262 numberOfSubStrings = [subStrings count];
263
264 // Ignore a trailing void component.
265 if (numberOfSubStrings > 0
266 && [[subStrings objectAtIndex: 0] isEqualToString: @""]) {
267 numberOfSubStrings--;
268
269 if (numberOfSubStrings) {
270 NSRange theRange;
271
272 theRange.location = 1;
273 theRange.length = numberOfSubStrings;
274 subStrings = [subStrings subarrayWithRange: theRange];
275 }
276
277 [self loadColumnZero];
278 }
279
280 column = lastColumnLoaded;
281 if (column < 0) {
282 column = 0;
283 }
284
285 progrPath = [NSString stringWithString: basePath];
286
287 for (i = 0; i < numberOfSubStrings; i++) {
288 BColumn *bc = (*getImp)(columns, getSel, column + i);
289
290 aStr = [subStrings objectAtIndex: i];
291
292 if ([aStr isEqualToString: @""] == NO) {
293 BOOL found = NO;
294
295 progrPath = [progrPath stringByAppendingPathComponent: aStr];
296
297 found = [bc selectMatrixCellsWithNames: [NSArray arrayWithObject: aStr]
298 sendAction: NO];
299
300 if (found == NO) {
301 NSLog(@"Browser: unable to find cell '%@' in column %d\n", aStr, column + i);
302 break;
303 }
304
305 (*addAndLoad)(self, addAndLoadSel, [NSArray arrayWithObject: progrPath]);
306 }
307 }
308
309 if ([selection count] > 1) {
310 BColumn *bc = (*getImp)(columns, getSel, lastColumnLoaded);
311
312 NSMutableArray *names = [NSMutableArray arrayWithCapacity: 1];
313 int i = 0;
314
315 for (i = 0; i < [selection count]; i++) {
316 [names addObject: [[selection objectAtIndex: i] lastPathComponent]];
317 }
318
319 [bc selectMatrixCellsWithNames: names sendAction: NO];
320
321 (*addAndLoad)(self, addAndLoadSel, selection);
322 }
323
324 canUpdateViews = YES;
325 [self tile];
326 [self setNeedsDisplay: YES];
327
328 selCol = [self selectedColumn];
329 if (selCol) {
330 NSMatrix *matrix = [selCol cmatrix];
331
332 if (matrix) {
333 [[self window] makeFirstResponder: matrix];
334 }
335 }
336
337 if (isRemote) {
338 [[NSCursor arrowCursor] set];
339 }
340 }
341
342 - (void)loadColumnZero
343 {
344 (*lastColumn)(self, lastColumnSel, -1);
345 (*addAndLoad)(self, addAndLoadSel, [NSArray arrayWithObject: basePath]);
346 isLoaded = YES;
347 [self tile];
348 }
349
350 - (BColumn *)createEmptyColumn
351 {
352 unsigned int style = (styleMask & GWColumnIconMask)
353 | (styleMask & GWIconCellsMask)
354 | (styleMask & GWViewsPaksgesMask);
355
356 BColumn *bc = [[BColumn alloc] initInBrowser: self
357 atIndex: [columns count]
358 cellPrototype: cellPrototype
359 styleMask: style
360 remoteHost: remoteHostName];
361 [columns addObject: bc];
362 [self addSubview: bc];
363 if (styleMask & GWColumnIconMask) {
364 [self addSubview: [bc iconView]];
365 }
366 RELEASE(bc);
367
368 return bc;
369 }
370
371 - (void)addAndLoadColumnForPaths:(NSArray *)cpaths
372 {
373 BColumn *bc;
374 int i;
375
376 if (lastColumnLoaded + 1 >= [columns count]) {
377 i = (*indexImp)(columns, indexSel, (*createEmpty)(self, createEmptySel));
378 } else {
379 i = lastColumnLoaded + 1;
380 }
381
382 bc = (*getImp)(columns, getSel, i);
383 (*setPaths)(bc, setPathsSel, cpaths);
384 (*lastColumn)(self, lastColumnSel, i);
385
386 isLoaded = YES;
387
388 [self tile];
389
390 if ((i > 0) && ((i - 1) == lastVisibleColumn)) {
391 [self scrollColumnsRightBy: 1];
392 }
393 }
394
395 - (void)unloadFromColumn:(int)column
396 {
397 BColumn *bc = nil;
398 int i, count;
399
400 count = [columns count];
401
402 for (i = column; i < count; ++i) {
403 bc = (*getImp)(columns, getSel, i);
404
405 if ([bc isLoaded]) {
406 [bc setCurrentPaths: nil];
407 }
408
409 if (i >= visibleColumns) {
410 [bc removeFromSuperview];
411 if (styleMask & GWColumnIconMask) {
412 [[bc iconView] removeFromSuperview];
413 }
414
415 [columns removeObject: bc];
416
417 count--;
418 i--;
419 }
420 }
421
422 if (column == 0) {
423 isLoaded = NO;
424 }
425
426 // Scrolls if needed.
427 if (column <= lastVisibleColumn) {
428 [self scrollColumnsLeftBy: lastVisibleColumn - column + 1];
429 }
430
431 [self updateScroller];
432 }
433
434 - (void)reloadColumnWithPath:(NSString *)cpath
435 {
436 BColumn *col = [self columnWithPath: cpath];
437
438 if (col) {
439 [col setCurrentPaths: [NSArray arrayWithObject: cpath]];
440 }
441 }
442
443 - (void)reloadFromColumnWithPath:(NSString *)cpath
444 {
445 BColumn *col = [self columnWithPath: cpath];
446
447 if (col) {
448 int index = [col index];
449 int i = 0;
450
451 for (i = index; i < [columns count]; i++) {
452 BColumn *nextcol = (*getImp)(columns, getSel, i);
453 NSArray *selection = [self selectionInColumnBeforeColumn: nextcol];
454
455 if (selection) {
456 [nextcol setCurrentPaths: selection];
457
458 } else {
459 int last = (i > 0) ? i - 1 : 0;
460 int shift = 0;
461 int leftscr = 0;
462
463 if (last >= visibleColumns) {
464 if (last < firstVisibleColumn) {
465 shift = visibleColumns - 1;
466 } else if (last > lastVisibleColumn) {
467 leftscr = last - lastVisibleColumn;
468 } else {
469 shift = lastVisibleColumn - last;
470 }
471 }
472
473 (*lastColumn)(self, lastColumnSel, last);
474
475 if (shift) {
476 currentshift = 0;
477 [self setShift: shift];
478 } else if (leftscr) {
479 [self scrollColumnsLeftBy: leftscr];
480 }
481
482 break;
483 }
484 }
485
486 [self tile];
487
488 col = [self lastNotEmptyColumn];
489
490 if (col) {
491 NSArray *selection = [col selection];
492 int index = [col index];
493
494 if (index < firstVisibleColumn) {
495 [self scrollColumnToVisible: index];
496 }
497
498 if (selection) {
499 BColumn *nextcol = (*getImp)(columns, getSel, ([col index] + 1));
500
501 if (styleMask & GWColumnIconMask) {
502 [nextcol updateIcon];
503 [nextcol selectIcon];
504 }
505
506 [delegate currentSelectedPaths: selection];
507
508 } else {
509 NSString *currpath = [col currentPath];
510
511 if (currpath) {
512 [delegate currentSelectedPaths: [NSArray arrayWithObject: currpath]];
513
514 if (styleMask & GWColumnIconMask) {
515 [col selectIcon];
516 }
517 }
518 }
519 }
520 }
521 }
522
523 - (void)setLastColumn:(int)column
524 {
525 lastColumnLoaded = column;
526 (*unloadFrom)(self, unloadFromSel, column + 1);
527 }
528
529 - (void)tile
530 {
531 NSSize bs = BEZEL_BORDER_SIZE;
532 float frameWidth;
533 NSRect r;
534 int i;
535
536 if (canUpdateViews == NO) {
537 return;
538 }
539
540 r = [self frame];
541
542 columnSize.height = r.size.height;
543 if (styleMask & GWColumnIconMask) {
544 columnOriginY = 0;
545 } else {
546 columnOriginY = scrollerWidth + (4 * bs.height);
547 }
548
549 // Horizontal scroller
550 scrollerRect.origin.x = bs.width;
551 if (styleMask & GWColumnIconMask) {
552 scrollerRect.origin.y = r.size.height - iconsPathWidth - scrollerWidth - 1;
553 } else {
554 scrollerRect.origin.y = bs.height;
555 }
556 scrollerRect.size.width = r.size.width - (2 * bs.width);
557 scrollerRect.size.height = scrollerWidth;
558
559 if (styleMask & GWColumnIconMask) {
560 columnSize.height -= iconsPathWidth + scrollerWidth + (3 * bs.height) + NSBR_VOFFSET;
561 } else {
562 columnSize.height -= scrollerWidth + (3 * bs.height) + NSBR_VOFFSET;
563 }
564
565 if (!NSEqualRects(scrollerRect, [scroller frame])) {
566 CHECKRECT (scrollerRect);
567 [scroller setFrame: scrollerRect];
568 }
569
570 // Columns
571 frameWidth = r.size.width - (4.0 + (float)visibleColumns);
572 columnSize.width = (int)(frameWidth / (float)visibleColumns);
573 CHECKSIZE (columnSize);
574
575 [self makeColumnsRects];
576
577 for (i = 0; i < [columns count]; i++) {
578 BColumn *bc = (*getImp)(columns, getSel, i);
579
580 if (styleMask & GWColumnIconMask) {
581 [[bc iconView] setFrame: NSMakeRect(colRects[i].origin.x,
582 r.size.height - iconsPathWidth + (2 * bs.width),
583 colRects[i].size.width, iconsPathWidth - (2 * bs.width))];
584 }
585
586 [bc setFrame: colRects[i]];
587 }
588
589 if (styleMask & GWColumnIconMask) {
590 [self updateNameEditor];
591 }
592 }
593
594 - (void)makeColumnsRects
595 {
596 int count = [columns count];
597 int i = 0;
598
599 if (colRects != NULL) {
600 NSZoneFree (NSDefaultMallocZone(), colRects);
601 }
602 colRects = NSZoneMalloc (NSDefaultMallocZone(), sizeof(NSRect) * count);
603
604 for (i = 0; i < count; i++) {
605 int n = i - firstVisibleColumn;
606
607 colRects[i] = NSZeroRect;
608
609 colRects[i].size = columnSize;
610
611 if (i < firstVisibleColumn) {
612 colRects[i].origin.x = (n * columnSize.width);
613 } else {
614 if (i == firstVisibleColumn) {
615 colRects[i].origin.x = (n * columnSize.width) + 2;
616 } else if (i <= lastVisibleColumn) {
617 colRects[i].origin.x = (n * columnSize.width) + (n + 2);
618 } else {
619 colRects[i].origin.x = (n * columnSize.width) + (n + 8);
620 }
621 }
622
623 if (i == lastVisibleColumn) {
624 colRects[i].size.width = [self bounds].size.width - (colRects[i].origin.x + 2);
625 }
626
627 colRects[i].origin.y = columnOriginY;
628
629 CHECKRECT (colRects[i]);
630 }
631 }
632
633 - (void)scrollViaScroller:(NSScroller *)sender
634 {
635 NSScrollerPart hit;
636
637 if ([sender class] != [NSScroller class]) {
638 return;
639 }
640
641 hit = [sender hitPart];
642
643 switch (hit) {
644 // Scroll to the left
645 case NSScrollerDecrementLine:
646 case NSScrollerDecrementPage:
647 [self scrollColumnsLeftBy: 1];
648 if (currentshift > 0) {
649 (*lastColumn)(self, lastColumnSel, (lastColumnLoaded - currentshift));
650 [self setShift: currentshift - 1];
651 }
652 break;
653
654 // Scroll to the right
655 case NSScrollerIncrementLine:
656 case NSScrollerIncrementPage:
657 [self scrollColumnsRightBy: 1];
658 break;
659
660 // The knob or knob slot
661 case NSScrollerKnob:
662 case NSScrollerKnobSlot:
663 {
664 float f = [sender floatValue];
665 float n = lastColumnLoaded + 1 - visibleColumns;
666
667 skipUpdateScroller = YES;
668 [self scrollColumnToVisible: myrintf(f * n) + visibleColumns - 1];
669 skipUpdateScroller = NO;
670
671 (*lastColumn)(self, lastColumnSel, (lastColumnLoaded - currentshift));
672 currentshift = 0;
673 }
674 break;
675
676 // NSScrollerNoPart ???
677 default:
678 break;
679 }
680 }
681
682 - (void)updateScroller
683 {
684 if ((lastColumnLoaded == 0) || (lastColumnLoaded <= (visibleColumns - 1))) {
685 [scroller setEnabled: NO];
686
687 } else {
688 if (!skipUpdateScroller) {
689 float prop = (float)visibleColumns / (float)(lastColumnLoaded + 1);
690 float i = lastColumnLoaded - visibleColumns + 1;
691 float f = 1 + ((lastVisibleColumn - lastColumnLoaded) / i);
692 [scroller setFloatValue: f knobProportion: prop];
693 }
694
695 [scroller setEnabled: YES];
696 }
697
698 [scroller setNeedsDisplay: YES];
699 }
700
701 - (void)scrollColumnsLeftBy:(int)shiftAmount
702 {
703 // Cannot shift past the zero column
704 if ((firstVisibleColumn - shiftAmount) < 0) {
705 shiftAmount = firstVisibleColumn;
706 }
707
708 // No amount to shift then nothing to do
709 if (shiftAmount <= 0) {
710 return;
711 }
712
713 // Shift
714 firstVisibleColumn = firstVisibleColumn - shiftAmount;
715 lastVisibleColumn = lastVisibleColumn - shiftAmount;
716
717 // Update the scroller
718 [self updateScroller];
719
720 // Update the scrollviews
721 [self tile];
722 }
723
724 - (void)scrollColumnsRightBy:(int)shiftAmount
725 {
726 // Cannot shift past the last loaded column
727 if ((shiftAmount + lastVisibleColumn) > lastColumnLoaded) {
728 shiftAmount = lastColumnLoaded - lastVisibleColumn;
729 }
730
731 // No amount to shift then nothing to do
732 if (shiftAmount <= 0) {
733 return;
734 }
735
736 // Shift
737 firstVisibleColumn = firstVisibleColumn + shiftAmount;
738 lastVisibleColumn = lastVisibleColumn + shiftAmount;
739
740 // Update the scroller
741 [self updateScroller];
742
743 // Update the scrollviews
744 [self tile];
745 }
746
747 - (void)scrollColumnToVisible:(int)column
748 {
749 int i;
750
751 // If its the last visible column then we are there already
752 if (lastVisibleColumn == column) {
753 return;
754 }
755
756 // If there are not enough columns to scroll with
757 // then the column must be visible
758 if (lastColumnLoaded + 1 <= visibleColumns) {
759 return;
760 }
761
762 i = lastVisibleColumn - column;
763 if (i > 0) {
764 [self scrollColumnsLeftBy: i];
765 } else {
766 [self scrollColumnsRightBy: (-i)];
767 }
768 }
769
770 - (void)moveLeft:(id)sender
771 {
772 BColumn *selCol;
773 int index;
774
775 if (!(selCol = [self selectedColumn])) {
776 return;
777 }
778
779 index = [selCol index];
780
781 if (index > 0) {
782 (*lastColumn)(self, lastColumnSel, index);
783
784 [selCol setLeaf: YES];
785 if (styleMask & GWColumnIconMask) {
786 [selCol selectIcon];
787 }
788
789 selCol = (*getImp)(columns, getSel, index - 1);
790 [delegate currentSelectedPaths: [selCol selection]];
791 [[self window] makeFirstResponder: [selCol cmatrix]];
792 }
793 }
794
795 - (void)moveRight:(id)sender
796 {
797 BColumn *selCol = [self selectedColumn];
798
799 if (selCol == nil) {
800 selCol = (*getImp)(columns, getSel, 0);
801
802 if ([selCol selectFirstCell]) {
803 [[self window] makeFirstResponder: [selCol cmatrix]];
804 }
805 } else {
806 NSMatrix *matrix = [selCol cmatrix];
807
808 if (matrix) {
809 int index = [selCol index];
810
811 [matrix sendAction];
812
813 if (index < ([columns count] - 1)) {
814 selCol = (*getImp)(columns, getSel, index + 1);
815 matrix = [selCol cmatrix];
816 if (matrix) {
817 if ([selCol selectFirstCell]) {
818 [matrix sendAction];
819 [[self window] makeFirstResponder: matrix];
820 }
821 }
822 }
823 }
824 }
825 }
826
827 - (void)setShift:(int)s
828 {
829 int i;
830
831 for (i = 0; i <= s; i++) {
832 (*createEmpty)(self, createEmptySel);
833 }
834
835 currentshift = s;
836 (*lastColumn)(self, lastColumnSel, (lastColumnLoaded + s));
837 [self scrollColumnsRightBy: s];
838 [self tile];
839 }
840
841 - (NSString *)pathToLastColumn
842 {
843 int i;
844
845 for (i = 0; i < [columns count]; i++) {
846 BColumn *col = (*getImp)(columns, getSel, i);
847
848 if ([col isLeaf]) {
849 NSString *cpath = [col currentPath];
850 BOOL is_dir = NO;
851
852 is_dir = [gworkspace server: remoteHostName
853 existsAndIsDirectoryFileAtPath: cpath];
854 if (is_dir) {
855 if (([gworkspace server: remoteHostName isPakageAtPath: cpath] == NO)
856 || (styleMask & GWViewsPaksgesMask)) {
857 return cpath;
858 } else if (i > 0) {
859 return [(*getImp)(columns, getSel, i - 1) currentPath];
860 }
861 } else if (i > 0) {
862 return [(*getImp)(columns, getSel, i - 1) currentPath];
863 }
864 }
865 }
866
867 return nil;
868 }
869
870 - (BOOL)isShowingPath:(NSString *)path
871 {
872 return ([self columnWithPath: path] ? YES : NO);
873 }
874
875 - (BColumn *)selectedColumn
876 {
877 int i;
878
879 for (i = lastColumnLoaded; i >= 0; i--) {
880 BColumn *col = (*getImp)(columns, getSel, i);
881
882 if ([col isSelected]) {
883 return col;
884 }
885 }
886
887 return nil;
888 }
889
890 - (NSArray *)selectionInColumn:(int)column
891 {
892 return [(*getImp)(columns, getSel, column) selection];
893 }
894
895 - (NSArray *)selectionInColumnBeforeColumn:(BColumn *)col
896 {
897 int index = [col index];
898
899 if (index == 0) {
900 return [NSArray arrayWithObject: basePath];
901 }
902
903 return [(*getImp)(columns, getSel, (index - 1)) selection];
904 }
905
906 - (void)selectCellsWithNames:(NSArray *)names
907 inColumnWithPath:(NSString *)cpath
908 sendAction:(BOOL)act
909 {
910 BColumn *col = [self columnWithPath: cpath];
911
912 if (col) {
913 [col selectMatrixCellsWithNames: names sendAction: act];
914 }
915 }
916
917 - (void)extendSelectionWithDimmedFiles:(NSArray *)dimmFiles
918 fromColumnWithPath:(NSString *)cpath
919 {
920 BColumn *col = [self columnWithPath: cpath];
921
922 if (col) {
923 NSArray *selection = [col selection];
924 int i = 0;
925
926 if (selection) {
927 BOOL contained = NO;
928
929 for (i = 0; i < [selection count]; i++) {
930 NSString *selFile = [[selection objectAtIndex: i] lastPathComponent];
931
932 if ([dimmFiles containsObject: selFile]) {
933 contained = YES;
934 break;
935 }
936 }
937
938 if (contained) {
939 for (i = [col index] + 1; i < [columns count]; i++) {
940 [(*getImp)(columns, getSel, i) lock];
941 }
942 }
943 }
944 }
945 }
946
947 - (void)selectAllInLastColumn
948 {
949 BColumn *col = [self lastNotEmptyColumn];
950
951 if (col) {
952 [col selectAll];
953 }
954 }
955
956 - (void)selectForEditingInLastColumn
957 {
958 // [nameEditor selectText: nil];
959 }
960
961 - (void)unselectNameEditor
962 {
963 [nameEditor setBackgroundColor: [NSColor windowBackgroundColor]];
964 [self setNeedsDisplayInRect: [nameEditor frame]];
965 }
966
967 - (void)restoreSelectionAfterDndOfIcon:(BIcon *)dndicon
968 {
969 BColumn *col = [self lastLoadedColumn];
970
971 if (col && (styleMask & GWColumnIconMask)) {
972 [[col myIcon] select];
973 }
974
975 [nameEditor setBackgroundColor: [NSColor whiteColor]];
976 [self updateNameEditor];
977 }
978
979 - (void)renewLastIcon
980 {
981 BColumn *col = [self lastLoadedColumn];
982
983 if (col && (styleMask & GWColumnIconMask)) {
984 BIcon *icon = [col myIcon];
985
986 if (icon) {
987 [icon renewIcon];
988 }
989 }
990 }
991
992 - (void)addCellsWithNames:(NSArray *)names
993 inColumnWithPath:(NSString *)cpath
994 {
995 BColumn *col = [self columnWithPath: cpath];
996
997 if (col) {
998 [col addMatrixCellsWithNames: names];
999 }
1000 }
1001
1002 - (void)addDimmedCellsWithNames:(NSArray *)names
1003 inColumnWithPath:(NSString *)cpath
1004 {
1005 BColumn *col = [self columnWithPath: cpath];
1006
1007 if (col) {
1008 [col addDimmedMatrixCellsWithNames: names];
1009 }
1010 }
1011
1012 - (void)removeCellsWithNames:(NSArray *)names
1013 inColumnWithPath:(NSString *)cpath
1014 {
1015 BColumn *col = [self columnWithPath: cpath];
1016
1017 if (col) {
1018 [col removeMatrixCellsWithNames: names];
1019 }
1020 }
1021
1022
1023 - (void)lockCellsWithNames:(NSArray *)names
1024 inColumnWithPath:(NSString *)cpath
1025 {
1026 BColumn *col = [self columnWithPath: cpath];
1027
1028 if (col) {
1029 [col lockCellsWithNames: names];
1030 }
1031 }
1032
1033 - (void)unLockCellsWithNames:(NSArray *)names
1034 inColumnWithPath:(NSString *)cpath
1035 mustExtend:(BOOL)extend
1036 {
1037 BColumn *col = [self columnWithPath: cpath];
1038 int i = 0;
1039
1040 if (col) {
1041 [col unLockCellsWithNames: names];
1042
1043 if (extend) {
1044 for (i = [col index] + 1; i < [columns count]; i++) {
1045 [(*getImp)(columns, getSel, i) unLock];
1046 }
1047 }
1048 }
1049 }
1050
1051 - (int)firstVisibleColumn
1052 {
1053 return firstVisibleColumn;
1054 }
1055
1056 - (BColumn *)lastLoadedColumn
1057 {
1058 int i;
1059
1060 for (i = [columns count] - 1; i >= 0; i--) {
1061 BColumn *col = (*getImp)(columns, getSel, i);
1062
1063 if ([col isLoaded] && [col isLeaf]) {
1064 return col;
1065 }
1066 }
1067
1068 return nil;
1069 }
1070
1071 - (BColumn *)lastNotEmptyColumn
1072 {
1073 int i;
1074
1075 for (i = 0; i < [columns count]; i++) {
1076 BColumn *col = (*getImp)(columns, getSel, i);
1077
1078 if ([col isLeaf]) {
1079 id matrix = [col cmatrix];
1080
1081 if (matrix && [[matrix cells] count]) {
1082 return col;
1083 } else if (i > 0) {
1084 return (*getImp)(columns, getSel, i - 1);
1085 }
1086 }
1087 }
1088
1089 return nil;
1090 }
1091
1092 - (BColumn *)columnWithPath:(NSString *)cpath
1093 {
1094 int i;
1095
1096 for (i = 0; i < [columns count]; i++) {
1097 BColumn *col = (*getImp)(columns, getSel, i);
1098
1099 if ([[col currentPath] isEqual: cpath]) {
1100 return col;
1101 }
1102 }
1103
1104 return nil;
1105 }
1106
1107 - (BColumn *)columnBeforeColumn:(BColumn *)col
1108 {
1109 int index = [col index];
1110
1111 if (index > 0) {
1112 return (*getImp)(columns, getSel, index - 1);
1113 }
1114
1115 return nil;
1116 }
1117
1118 - (BColumn *)columnAfterColumn:(BColumn *)col
1119 {
1120 int index = [col index];
1121
1122 if (index < ([columns count] - 1)) {
1123 return (*getImp)(columns, getSel, index + 1);
1124 }
1125
1126 return nil;
1127 }
1128
1129 - (NSArray *)columnsDifferentFromColumn:(BColumn *)col
1130 {
1131 NSMutableArray *arr = [NSMutableArray arrayWithCapacity: 1];
1132 int i;
1133
1134 for (i = 0; i < [columns count]; i++) {
1135 BColumn *bc = (*getImp)(columns, getSel, i);
1136
1137 if (bc != col) {
1138 [arr addObject: bc];
1139 }
1140 }
1141
1142 return arr;
1143 }
1144
1145 - (NSPoint)positionOfLastIcon
1146 {
1147 BColumn *col = [self lastLoadedColumn];
1148
1149 if (col && (styleMask & GWColumnIconMask)) {
1150 NSRect r = [[col iconView] frame];
1151 NSSize s = [[col myIcon] iconShift];
1152
1153 return NSMakePoint(r.origin.x + s.width,
1154 r.origin.y + s.height + ICON_VOFFSET);
1155 }
1156
1157 return NSZeroPoint;
1158 }
1159
1160 - (NSPoint)positionForSlidedImage
1161 {
1162 if ((lastVisibleColumn < [columns count]) && (styleMask & GWColumnIconMask)) {
1163 BColumn *col = (*getImp)(columns, getSel, lastVisibleColumn);
1164 NSRect r = [[col iconView] frame];
1165 NSPoint p = [self positionOfLastIcon];
1166
1167 return NSMakePoint(r.origin.x + ((r.size.width - ICON_SIZE_WIDTH) / 2), p.y);
1168 }
1169
1170 return NSZeroPoint;
1171 }
1172
1173 - (BOOL)viewsapps
1174 {
1175 return (styleMask & GWViewsPaksgesMask);
1176 }
1177
1178 - (void)mouseDown:(NSEvent*)theEvent
1179 {
1180 if (simulatingDoubleClick) {
1181 NSPoint p = [[self window] mouseLocationOutsideOfEventStream];
1182
1183 if ((max(p.x, mousePointX) - min(p.x, mousePointX)) <= 3
1184 && (max(p.y, mousePointY) - min(p.y, mousePointY)) <= 3) {
1185 [delegate openSelectedPaths: doubleClickSelection newViewer: NO];
1186 }
1187 }
1188
1189 [super mouseDown: theEvent];
1190 }
1191
1192 - (void)doubleClikTimeOut:(id)sender
1193 {
1194 simulatingDoubleClick = NO;
1195 }
1196
1197 - (void)clickInMatrixOfColumn:(BColumn *)col
1198 {
1199 int index = [col index];
1200 int pos = index - firstVisibleColumn + 1;
1201 BOOL mustshift = (firstVisibleColumn > 0) ? YES : NO;
1202 NSArray *selection = [col selection];
1203
1204 if ((selection == nil) || ([selection count] == 0)) {
1205 [self clickOnIcon: [col myIcon] ofColumn: col];
1206 return;
1207 }
1208
1209 if (isRemote) {
1210 [waitCursor set];
1211 }
1212
1213 if ((pos == visibleColumns) && (index == ([columns count] -1))) {
1214 NSTimer *timer;
1215 NSPoint p;
1216
1217 p = [[self window] mouseLocationOutsideOfEventStream];
1218 mousePointX = p.x;
1219 mousePointY = p.y;
1220 ASSIGN (doubleClickSelection, selection);
1221 simulatingDoubleClick = YES;
1222
1223 timer = [NSTimer scheduledTimerWithTimeInterval: 0.3
1224 target: self selector: @selector(doubleClikTimeOut:)
1225 userInfo: nil repeats: NO];
1226 }
1227
1228 [delegate currentSelectedPaths: selection];
1229
1230 currentshift = 0;
1231 canUpdateViews = NO;
1232
1233 (*lastColumn)(self, lastColumnSel, index);
1234 (*addAndLoad)(self, addAndLoadSel, selection);
1235
1236 if ((mustshift == YES) && (pos < (visibleColumns - 1))) {
1237 [self setShift: visibleColumns - pos - 1];
1238 }
1239
1240 canUpdateViews = YES;
1241 [self tile];
1242
1243 if (isRemote) {
1244 [[NSCursor arrowCursor] set];
1245 }
1246
1247 #ifndef GNUSTEP
1248 [[self window] makeFirstResponder: self];
1249 #endif
1250 }
1251
1252 - (void)doubleClickInMatrixOfColumn:(BColumn *)col
1253 {
1254 NSArray *selection = [col selection];
1255
1256 if (selection) {
1257 [delegate openSelectedPaths: selection newViewer: NO];
1258 }
1259 }
1260
1261 - (void)clickOnIcon:(BIcon *)icon ofColumn:(BColumn *)col
1262 {
1263 BColumn *column;
1264
1265 if ([icon isSinglePath] == NO) {
1266 return;
1267 }
1268
1269 if (isRemote) {
1270 [waitCursor set];
1271 }
1272
1273 column = [self columnBeforeColumn: col];
1274
1275 if (column) {
1276 NSString *name = [icon name];
1277
1278 if ([column selectMatrixCellsWithNames: [NSArray arrayWithObject: name]
1279 sendAction: YES] == NO) {
1280 (*lastColumn)(self, lastColumnSel, [column index]);
1281 [delegate currentSelectedPaths: [NSArray arrayWithObject: [column currentPath]]];
1282 }
1283
1284 } else {
1285 (*lastColumn)(self, lastColumnSel, 0);
1286 [delegate currentSelectedPaths: [NSArray arrayWithObject: basePath]];
1287 [self tile];
1288 }
1289
1290 [nameEditor setBackgroundColor: [NSColor whiteColor]];
1291
1292 if (isRemote) {
1293 [[NSCursor arrowCursor] set];
1294 }
1295
1296 [[self window] makeFirstResponder: self];
1297 }
1298
1299 - (void)doubleClickOnIcon:(BIcon *)icon
1300 ofColumn:(BColumn *)col
1301 newViewer:(BOOL)isnew
1302 {
1303 [delegate openSelectedPaths: [icon paths] newViewer: isnew];
1304 }
1305
1306 - (void)updateNameEditor
1307 {
1308 BColumn *col = [self lastLoadedColumn];
1309
1310 if ([[self subviews] containsObject: nameEditor]) {
1311 NSRect edr = [nameEditor frame];
1312
1313 [nameEditor abortEditing];
1314 [nameEditor setName: nil paths: nil index: -1];
1315 [nameEditor removeFromSuperview];
1316 [self setNeedsDisplayInRect: edr];
1317 edCol = nil;
1318 }
1319
1320 isEditingIconName = NO;
1321
1322 if (col && ([col index] <= lastVisibleColumn)) {
1323 BIcon *icon = [col myIcon];
1324 NSArray *paths = [icon paths];
1325 NSString *name = [icon isRootIcon] ? [icon hostname] : [icon name];
1326 BOOL locked = [icon isLocked];
1327 BOOL canedit = ((!locked) && (paths && [paths count] == 1) && (![icon isRootIcon]));
1328 NSRect r = [[col iconView] frame];
1329 float bw = [self bounds].size.width - EDIT_MARGIN;
1330 float centerx = r.origin.x + (r.size.width / 2);
1331 float labwidth = [editorFont widthOfString: name] + LABEL_MARGIN;
1332
1333 if ((centerx + (labwidth / 2)) >= bw) {
1334 centerx -= (centerx + (labwidth / 2) - bw);
1335 } else if ((centerx - (labwidth / 2)) < LABEL_MARGIN) {
1336 centerx += fabs(centerx - (labwidth / 2)) + LABEL_MARGIN;
1337 }
1338
1339 [[icon label] setFrame: NSMakeRect(centerx, r.origin.y, 1, 1)];
1340
1341 r = NSMakeRect(centerx - (labwidth / 2), r.origin.y, labwidth, LABEL_HEIGHT);
1342 [nameEditor setFrame: r];
1343 [nameEditor setName: name paths: paths index: [col index]];
1344 [nameEditor setBackgroundColor: [NSColor whiteColor]];
1345 [nameEditor setTextColor: (locked ? [NSColor disabledControlTextColor]
1346 : [NSColor controlTextColor])];
1347 [nameEditor setEditable: canedit];
1348 [nameEditor setSelectable: canedit];
1349 [self addSubview: nameEditor];
1350 }
1351 }
1352
1353 - (BOOL)isEditingIconName
1354 {
1355 return isEditingIconName;
1356 }
1357
1358 - (void)controlTextDidChange:(NSNotification *)aNotification
1359 {
1360 static NSRect edr = {{0, 0}, {0, 0}};
1361 static float crx = 0;
1362 static float ory = 0;
1363 static float bw = 0;
1364 NSString *s;
1365 float labwidth;
1366 float labcenter;
1367
1368 if (edCol == nil) {
1369 edCol = [self lastLoadedColumn];
1370 edr = [[edCol iconView] frame];
1371 crx = edr.origin.x + (edr.size.width / 2);
1372 ory = edr.origin.y;
1373 bw = [self bounds].size.width - EDIT_MARGIN;
1374 }
1375
1376 s = [nameEditor stringValue];
1377 labwidth = [editorFont widthOfString: s] + LABEL_MARGIN;
1378
1379 labcenter = crx;
1380
1381 while ((labcenter + (labwidth / 2)) > bw) {
1382 labcenter -= EDIT_MARGIN;
1383 if (labcenter < EDIT_MARGIN) {
1384 break;
1385 }
1386 }
1387
1388 while ((labcenter - (labwidth / 2)) < EDIT_MARGIN) {
1389 labcenter += EDIT_MARGIN;
1390 if (labcenter >= bw) {
1391 break;
1392 }
1393 }
1394
1395 [self setNeedsDisplayInRect: [nameEditor frame]];
1396 [nameEditor setFrame: NSMakeRect((labcenter - (labwidth / 2)), ory, labwidth, LABEL_HEIGHT)];
1397 }
1398
1399 - (void)controlTextDidBeginEditing:(NSNotification *)aNotification
1400 {
1401 isEditingIconName = YES;
1402 }
1403
1404 - (void)controlTextDidEndEditing:(NSNotification *)aNotification
1405 {
1406 NSString *oldpath = [[nameEditor paths] objectAtIndex: 0];
1407 NSString *basepath = [oldpath stringByDeletingLastPathComponent];
1408 NSString *oldname = [nameEditor name];
1409 NSString *newname = [nameEditor stringValue];
1410 NSString *newpath = [basepath stringByAppendingPathComponent: newname];
1411 NSFileManager *fm = [NSFileManager defaultManager];
1412
1413 #define CLEAREDITING \
1414 [self updateNameEditor]; \
1415 return
1416
1417 if (isRemote) {
1418 [self updateNameEditor];
1419
1420 [gworkspace server: remoteHostName
1421 renamePath: oldpath
1422 toNewName: newpath];
1423 return;
1424 }
1425
1426 isEditingIconName = NO;
1427 [nameEditor setAlignment: NSCenterTextAlignment];
1428
1429 if ([fm isWritableFileAtPath: oldpath] == NO) {
1430 NSRunAlertPanel(NSLocalizedString(@"Error", @""),
1431 [NSString stringWithFormat: @"%@\"%@\"!\n",
1432 NSLocalizedString(@"You have not write permission\nfor ", @""),
1433 oldpath], NSLocalizedString(@"Continue", @""), nil, nil);
1434 CLEAREDITING;
1435
1436 } else if ([fm isWritableFileAtPath: basepath] == NO) {
1437 NSRunAlertPanel(NSLocalizedString(@"Error", @""),
1438 [NSString stringWithFormat: @"%@\"%@\"!\n",
1439 NSLocalizedString(@"You have not write permission\nfor ", @""),
1440 basepath], NSLocalizedString(@"Continue", @""), nil, nil);
1441 CLEAREDITING;
1442
1443 } else {
1444 NSCharacterSet *notAllowSet = [NSCharacterSet characterSetWithCharactersInString: @"/\\*$|~\'\"`^!?"];
1445 NSRange range = [newname rangeOfCharacterFromSet: notAllowSet];
1446 NSArray *dirContents = [fm directoryContentsAtPath: basepath];
1447 NSMutableDictionary *notifObj = [NSMutableDictionary dictionaryWithCapacity: 1];
1448
1449 if (range.length > 0) {
1450 NSRunAlertPanel(NSLocalizedString(@"Error", @""),
1451 NSLocalizedString(@"Invalid char in name", @""),
1452 NSLocalizedString(@"Continue", @""), nil, nil);
1453 CLEAREDITING;
1454 }
1455
1456 if ([dirContents containsObject: newname]) {
1457 if ([newname isEqualToString: oldname]) {
1458 CLEAREDITING;
1459 } else {
1460 NSRunAlertPanel(NSLocalizedString(@"Error", @""),
1461 [NSString stringWithFormat: @"%@\"%@\" %@\n",
1462 NSLocalizedString(@"The name ", @""),
1463 newname, NSLocalizedString(@" is already in use!", @"")],
1464 NSLocalizedString(@"Continue", @""), nil, nil);
1465 CLEAREDITING;
1466 }
1467 }
1468
1469 [notifObj setObject: GWorkspaceRenameOperation forKey: @"operation"];
1470 [notifObj setObject: oldpath forKey: @"source"];
1471 [notifObj setObject: newpath forKey: @"destination"];
1472 [notifObj setObject: [NSArray arrayWithObject: @""] forKey: @"files"];
1473
1474 [[NSNotificationCenter defaultCenter]
1475 postNotificationName: GWFileSystemWillChangeNotification
1476 object: notifObj];
1477
1478 [fm movePath: oldpath toPath: newpath handler: self];
1479
1480 [[NSNotificationCenter defaultCenter]
1481 postNotificationName: GWFileSystemDidChangeNotification
1482 object: notifObj];
1483
1484 [self updateNameEditor];
1485 }
1486 }
1487
1488 - (void)editorAction:(id)sender
1489 {
1490 }
1491
1492 - (BOOL)fileManager:(NSFileManager *)manager
1493 shouldProceedAfterError:(NSDictionary *)errorDict
1494 {
1495 NSString *title = NSLocalizedString(@"Error", @"");
1496 NSString *msg1 = NSLocalizedString(@"Cannot rename ", @"");
1497 NSString *name = [nameEditor name];
1498 NSString *msg2 = NSLocalizedString(@"Continue", @"");
1499
1500 NSRunAlertPanel(title, [NSString stringWithFormat: @"%@'%@'!", msg1, name], msg2, nil, nil);
1501
1502 return NO;
1503 }
1504
1505 - (void)fileManager:(NSFileManager *)manager willProcessPath:(NSString *)path
1506 {
1507 }
1508
1509 - (BOOL)acceptsFirstResponder
1510 {
1511 return YES;
1512 }
1513
1514 - (BOOL)becomeFirstResponder
1515 {
1516 BColumn *selCol;
1517 NSMatrix *matrix;
1518
1519 selCol = [self selectedColumn];
1520
1521 if (selCol == nil) {
1522 matrix = [(*getImp)(columns, getSel, 0) cmatrix];
1523 } else {
1524 matrix = [selCol cmatrix];
1525 }
1526
1527 if (matrix) {
1528 [[self window] makeFirstResponder: matrix];
1529 }
1530
1531 return YES;
1532 }
1533
1534 - (void)keyDown:(NSEvent *)theEvent
1535 {
1536 NSString *characters;
1537 unichar character;
1538 BColumn *column;
1539 NSMatrix *matrix;
1540
1541 if (!(column = [self selectedColumn])) {
1542 return;
1543 }
1544 if (!(matrix = [column cmatrix])) {
1545 return;
1546 }
1547
1548 characters = [theEvent characters];
1549 character = 0;
1550
1551 if ([characters length] > 0) {
1552 character = [characters characterAtIndex: 0];
1553 }
1554
1555 switch (character) {
1556 case NSUpArrowFunctionKey:
1557 case NSDownArrowFunctionKey:
1558 return;
1559
1560 case NSLeftArrowFunctionKey:
1561 {
1562 if ([theEvent modifierFlags] & NSControlKeyMask) {
1563 [super keyDown: theEvent];
1564 } else {
1565 [self moveLeft: self];
1566 }
1567 }
1568 return;
1569
1570 case NSRightArrowFunctionKey:
1571 {
1572 if ([theEvent modifierFlags] & NSControlKeyMask) {
1573 [super keyDown: theEvent];
1574 } else {
1575 [self moveRight: self];
1576 }
1577 }
1578 return;
1579
1580 case 13:
1581 [matrix sendDoubleAction];
1582 return;
1583
1584 case NSTabCharacter:
1585 {
1586 if ([theEvent modifierFlags] & NSShiftKeyMask)
1587 [[self window] selectKeyViewPrecedingView: self];
1588 else
1589 [[self window] selectKeyViewFollowingView: self];
1590 }
1591 return;
1592 break;
1593 }
1594
1595 if ((character < 0xF700) && ([characters length] > 0)) {
1596 // column = [self lastNotEmptyColumn];
1597 column = [self selectedColumn];
1598
1599 if (column) {
1600 int index = [column index];
1601
1602 matrix = [column cmatrix];
1603
1604 if (matrix == nil) {
1605 return;
1606 }
1607
1608 if (charBuffer == nil) {
1609 charBuffer = [characters substringToIndex: 1];
1610 RETAIN (charBuffer);
1611 } else {
1612 if (([theEvent timestamp] - lastKeyPressed < 2000.0)
1613 && (alphaNumericalLastColumn == index)) {
1614 ASSIGN (charBuffer, ([charBuffer stringByAppendingString:
1615 [characters substringToIndex: 1]]));
1616 } else {
1617 ASSIGN (charBuffer, ([characters substringToIndex: 1]));
1618 }
1619 }
1620
1621 alphaNumericalLastColumn = index;
1622 lastKeyPressed = [theEvent timestamp];
1623
1624 if ([column selectCellWithPrefix: charBuffer]) {
1625 // [[self window] makeFirstResponder: matrix];
1626 return;
1627 }
1628 }
1629
1630 lastKeyPressed = 0.;
1631 }
1632
1633 [super keyDown: theEvent];
1634 }
1635
1636 - (void)resizeSubviewsWithOldSize:(NSSize)oldSize
1637 {
1638 [self tile];
1639 }
1640
1641 - (void)drawRect:(NSRect)rect
1642 {
1643 NSRect r;
1644 NSSize bs;
1645 NSPoint p1, p2;
1646 NSRect browserRect;
1647 NSRect scrollerBorderRect;
1648 int i;
1649
1650 r = [self bounds];
1651 bs = BEZEL_BORDER_SIZE;
1652
1653 NSRectClip(rect);
1654 [[[self window] backgroundColor] set];
1655 NSRectFill(rect);
1656
1657 if (!isLoaded) {
1658 [self loadColumnZero];
1659 }
1660
1661 if (styleMask & GWColumnIconMask) {
1662 scrollerBorderRect = NSMakeRect(scrollerRect.origin.x,
1663 scrollerRect.origin.y, scrollerRect.size.width,
1664 scrollerRect.size.height + iconsPathWidth - 2);
1665
1666 scrollerBorderRect.origin.x = 0;
1667 scrollerBorderRect.origin.y = scrollerRect.origin.y - 1;
1668 scrollerBorderRect.size.width += 2 * bs.width;
1669 scrollerBorderRect.size.height += (2 * bs.height);
1670
1671 } else {
1672 scrollerBorderRect = scrollerRect;
1673 scrollerBorderRect.origin.x = 0;
1674 scrollerBorderRect.origin.y = 1;
1675 scrollerBorderRect.size.width += 2 * bs.width;
1676 scrollerBorderRect.size.height += (2 * bs.height) - 1;
1677 }
1678
1679 if (NSIntersectsRect(scrollerBorderRect, r)) {
1680 p1 = NSMakePoint(scrollerBorderRect.origin.x + 2,
1681 scrollerBorderRect.origin.y + scrollerRect.size.height + 2);
1682 p2 = NSMakePoint(scrollerBorderRect.origin.x + scrollerBorderRect.size.width - 2,
1683 scrollerBorderRect.origin.y + scrollerRect.size.height + 2);
1684
1685 NSDrawGrayBezel(scrollerBorderRect, r);
1686
1687 if (styleMask & GWColumnIconMask) {
1688 [[NSColor blackColor] set];
1689 [NSBezierPath strokeLineFromPoint: p1 toPoint: p2];
1690 }
1691 }
1692
1693 if (styleMask & GWColumnIconMask) {
1694 browserRect = NSMakeRect(0, -2, r.size.width, columnSize.height + 4);
1695 } else {
1696 browserRect = NSMakeRect(0, columnOriginY - 2, r.size.width,
1697 r.size.height - columnOriginY + 2);
1698 }
1699 NSDrawGrayBezel(browserRect, r);
1700
1701 [[NSColor blackColor] set];
1702
1703 for (i = 1; i < visibleColumns; i++) {
1704 p1 = NSMakePoint((columnSize.width * i) + 2 + (i-1),
1705 columnSize.height + columnOriginY);
1706 p2 = NSMakePoint((columnSize.width * i) + 2 + (i-1), columnOriginY);
1707 [NSBezierPath strokeLineFromPoint: p1 toPoint: p2];
1708 }
1709 }
1710
1711 @end
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26