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

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