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

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