1 |
/* HiddenFilesPref.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 |
|
26 |
#include <Foundation/Foundation.h> |
27 |
#include <AppKit/AppKit.h> |
28 |
#ifdef GNUSTEP |
29 |
#include "GWLib.h" |
30 |
#include "GWFunctions.h" |
31 |
#include "GWNotifications.h" |
32 |
#else |
33 |
#include <GWorkspace/GWLib.h> |
34 |
#include <GWorkspace/GWFunctions.h> |
35 |
#include <GWorkspace/GWNotifications.h> |
36 |
#endif |
37 |
#include "HiddenFilesPref.h" |
38 |
#include "GWorkspace.h" |
39 |
#include "GNUstep.h" |
40 |
|
41 |
static NSString *nibName = @"HiddenFilesPref"; |
42 |
|
43 |
#define CHECKSIZE(sz) \ |
44 |
if (sz.width < 0) sz.width = 0; \ |
45 |
if (sz.height < 0) sz.height = 0 |
46 |
|
47 |
@implementation HiddenFilesPref |
48 |
|
49 |
- (void)dealloc |
50 |
{ |
51 |
[[NSNotificationCenter defaultCenter] removeObserver: self]; |
52 |
TEST_RELEASE (prefbox); |
53 |
RELEASE (currentPath); |
54 |
TEST_RELEASE (leftMatrix); |
55 |
TEST_RELEASE (rightMatrix); |
56 |
RELEASE (cellPrototipe); |
57 |
[super dealloc]; |
58 |
} |
59 |
|
60 |
- (id)init |
61 |
{ |
62 |
self = [super init]; |
63 |
|
64 |
if (self) { |
65 |
if ([NSBundle loadNibNamed: nibName owner: self] == NO) { |
66 |
NSLog(@"failed to load %@!", nibName); |
67 |
} else { |
68 |
NSArray *selection; |
69 |
NSString *path; |
70 |
NSString *defApp; |
71 |
NSString *type; |
72 |
BOOL isdir; |
73 |
|
74 |
RETAIN (prefbox); |
75 |
RELEASE (win); |
76 |
|
77 |
gw = [GWorkspace gworkspace]; |
78 |
fm = [NSFileManager defaultManager]; |
79 |
ws = [NSWorkspace sharedWorkspace]; |
80 |
|
81 |
selection = [gw selectedPaths]; |
82 |
path = [selection objectAtIndex: 0]; |
83 |
|
84 |
if ([selection count] > 1) { |
85 |
path = [path stringByDeletingLastPathComponent]; |
86 |
} else { |
87 |
[fm fileExistsAtPath: path isDirectory: &isdir]; |
88 |
if (isdir == NO) { |
89 |
path = [path stringByDeletingLastPathComponent]; |
90 |
} else if ([gw isPakageAtPath: path]) { |
91 |
path = [path stringByDeletingLastPathComponent]; |
92 |
} |
93 |
} |
94 |
|
95 |
ASSIGN (currentPath, path); |
96 |
|
97 |
[ws getInfoForFile: currentPath application: &defApp type: &type]; |
98 |
[iconView setImage: [gw iconForFile: currentPath ofType: type]]; |
99 |
|
100 |
cellPrototipe = [NSBrowserCell new]; |
101 |
|
102 |
[leftScroll setBorderType: NSBezelBorder]; |
103 |
[leftScroll setHasHorizontalScroller: NO]; |
104 |
[leftScroll setHasVerticalScroller: YES]; |
105 |
|
106 |
[rightScroll setBorderType: NSBezelBorder]; |
107 |
[rightScroll setHasHorizontalScroller: NO]; |
108 |
[rightScroll setHasVerticalScroller: YES]; |
109 |
|
110 |
leftMatrix = nil; |
111 |
rightMatrix = nil; |
112 |
|
113 |
[addButt setImage: [NSImage imageNamed: @"common_ArrowLeftH.tiff"]]; |
114 |
[removeButt setImage: [NSImage imageNamed: @"common_ArrowRightH.tiff"]]; |
115 |
|
116 |
[setButt setEnabled: NO]; |
117 |
|
118 |
[[NSNotificationCenter defaultCenter] addObserver: self |
119 |
selector: @selector(selectionChanged:) |
120 |
name: GWCurrentSelectionChangedNotification |
121 |
object: nil]; |
122 |
/* Internationalization */ |
123 |
[setButt setTitle: NSLocalizedString(@"Activate changes", @"")]; |
124 |
[loadButt setTitle: NSLocalizedString(@"Load", @"")]; |
125 |
[hiddenlabel setStringValue: NSLocalizedString(@"Hidden files", @"")]; |
126 |
[shownlabel setStringValue: NSLocalizedString(@"Shown files", @"")]; |
127 |
[labelinfo setStringValue: NSLocalizedString(@"Select and move the files to hide or to show", @"")]; |
128 |
} |
129 |
} |
130 |
|
131 |
return self; |
132 |
} |
133 |
|
134 |
- (NSView *)prefView |
135 |
{ |
136 |
return prefbox; |
137 |
} |
138 |
|
139 |
- (NSString *)prefName |
140 |
{ |
141 |
return NSLocalizedString(@"Hidden Files", @""); |
142 |
} |
143 |
|
144 |
- (void)selectionChanged:(NSNotification *)n |
145 |
{ |
146 |
NSArray *selection; |
147 |
NSString *path; |
148 |
NSString *defApp; |
149 |
NSString *type; |
150 |
BOOL isdir; |
151 |
|
152 |
selection = [gw selectedPaths]; |
153 |
path = [selection objectAtIndex: 0]; |
154 |
|
155 |
if ([selection count] > 1) { |
156 |
path = [path stringByDeletingLastPathComponent]; |
157 |
} else { |
158 |
[fm fileExistsAtPath: path isDirectory: &isdir]; |
159 |
if (isdir == NO) { |
160 |
path = [path stringByDeletingLastPathComponent]; |
161 |
} else if ([gw isPakageAtPath: path]) { |
162 |
path = [path stringByDeletingLastPathComponent]; |
163 |
} |
164 |
} |
165 |
|
166 |
ASSIGN (currentPath, path); |
167 |
|
168 |
[ws getInfoForFile: currentPath application: &defApp type: &type]; |
169 |
[iconView setImage: [gw iconForFile: currentPath ofType: type]]; |
170 |
|
171 |
[pathField setStringValue: [currentPath lastPathComponent]]; |
172 |
|
173 |
[self clearAll]; |
174 |
|
175 |
[prefbox setNeedsDisplay: YES]; |
176 |
} |
177 |
|
178 |
- (void)clearAll |
179 |
{ |
180 |
NSSize cs, ms; |
181 |
|
182 |
if (leftMatrix) { |
183 |
[leftMatrix removeFromSuperview]; |
184 |
[leftScroll setDocumentView: nil]; |
185 |
DESTROY (leftMatrix); |
186 |
} |
187 |
|
188 |
leftMatrix = [[NSMatrix alloc] initWithFrame: NSMakeRect(0, 0, 100, 100) |
189 |
mode: NSListModeMatrix prototype: cellPrototipe |
190 |
numberOfRows: 0 numberOfColumns: 0]; |
191 |
[leftMatrix setIntercellSpacing: NSZeroSize]; |
192 |
[leftMatrix setCellSize: NSMakeSize(130, 14)]; |
193 |
[leftMatrix setAutoscroll: YES]; |
194 |
[leftMatrix setAllowsEmptySelection: YES]; |
195 |
cs = [leftScroll contentSize]; |
196 |
ms = [leftMatrix cellSize]; |
197 |
ms.width = cs.width; |
198 |
CHECKSIZE (ms); |
199 |
[leftMatrix setCellSize: ms]; |
200 |
[leftScroll setDocumentView: leftMatrix]; |
201 |
|
202 |
if (rightMatrix) { |
203 |
[rightMatrix removeFromSuperview]; |
204 |
[rightScroll setDocumentView: nil]; |
205 |
DESTROY (rightMatrix); |
206 |
} |
207 |
|
208 |
rightMatrix = [[NSMatrix alloc] initWithFrame: NSMakeRect(0, 0, 100, 100) |
209 |
mode: NSListModeMatrix prototype: cellPrototipe |
210 |
numberOfRows: 0 numberOfColumns: 0]; |
211 |
[rightMatrix setIntercellSpacing: NSZeroSize]; |
212 |
[rightMatrix setCellSize: NSMakeSize(130, 14)]; |
213 |
[rightMatrix setAutoscroll: YES]; |
214 |
[rightMatrix setAllowsEmptySelection: YES]; |
215 |
cs = [rightScroll contentSize]; |
216 |
ms = [rightMatrix cellSize]; |
217 |
ms.width = cs.width; |
218 |
CHECKSIZE (ms); |
219 |
[rightMatrix setCellSize: ms]; |
220 |
[rightScroll setDocumentView: rightMatrix]; |
221 |
|
222 |
[setButt setEnabled: NO]; |
223 |
} |
224 |
|
225 |
- (IBAction)loadContents:(id)sender |
226 |
{ |
227 |
NSArray *files; |
228 |
NSMutableArray *hiddenFiles; |
229 |
BOOL hideSysFiles; |
230 |
NSString *h; |
231 |
int i, count; |
232 |
|
233 |
[self clearAll]; |
234 |
|
235 |
files = [fm directoryContentsAtPath: currentPath]; |
236 |
|
237 |
h = [currentPath stringByAppendingPathComponent: @".hidden"]; |
238 |
if ([fm fileExistsAtPath: h]) { |
239 |
h = [NSString stringWithContentsOfFile: h]; |
240 |
hiddenFiles = [[h componentsSeparatedByString: @"\n"] mutableCopy]; |
241 |
|
242 |
count = [hiddenFiles count]; |
243 |
for (i = 0; i < count; i++) { |
244 |
NSString *s = [hiddenFiles objectAtIndex: i]; |
245 |
|
246 |
if ([s length] == 0) { |
247 |
[hiddenFiles removeObject: s]; |
248 |
count--; |
249 |
i--; |
250 |
} |
251 |
} |
252 |
|
253 |
} else { |
254 |
hiddenFiles = nil; |
255 |
} |
256 |
hideSysFiles = [gw hideSysFiles]; |
257 |
|
258 |
if (hiddenFiles != nil || hideSysFiles) { |
259 |
NSMutableArray *mutableFiles = AUTORELEASE ([files mutableCopy]); |
260 |
|
261 |
if (hiddenFiles != nil) { |
262 |
[mutableFiles removeObjectsInArray: hiddenFiles]; |
263 |
} |
264 |
|
265 |
if (hideSysFiles) { |
266 |
int j = [mutableFiles count] - 1; |
267 |
|
268 |
while (j >= 0) { |
269 |
NSString *file = (NSString *)[mutableFiles objectAtIndex: j]; |
270 |
|
271 |
if ([file hasPrefix: @"."]) { |
272 |
[mutableFiles removeObjectAtIndex: j]; |
273 |
} |
274 |
j--; |
275 |
} |
276 |
} |
277 |
|
278 |
files = mutableFiles; |
279 |
} |
280 |
|
281 |
count = [files count]; |
282 |
if (count == 0) { |
283 |
TEST_RELEASE (hiddenFiles); |
284 |
return; |
285 |
} |
286 |
|
287 |
[rightMatrix addColumn]; |
288 |
for (i = 0; i < count; ++i) { |
289 |
id cell; |
290 |
|
291 |
if (i != 0) { |
292 |
[rightMatrix insertRow: i]; |
293 |
} |
294 |
cell = [rightMatrix cellAtRow: i column: 0]; |
295 |
[cell setStringValue: [files objectAtIndex: i]]; |
296 |
[cell setLeaf: YES]; |
297 |
} |
298 |
[rightMatrix sizeToCells]; |
299 |
|
300 |
if (hiddenFiles != nil) { |
301 |
count = [hiddenFiles count]; |
302 |
if (count == 0) { |
303 |
TEST_RELEASE (hiddenFiles); |
304 |
return; |
305 |
} |
306 |
|
307 |
[leftMatrix addColumn]; |
308 |
for (i = 0; i < count; ++i) { |
309 |
id cell; |
310 |
|
311 |
if (i != 0) { |
312 |
[leftMatrix insertRow: i]; |
313 |
} |
314 |
cell = [leftMatrix cellAtRow: i column: 0]; |
315 |
[cell setStringValue: [hiddenFiles objectAtIndex: i]]; |
316 |
[cell setLeaf: YES]; |
317 |
} |
318 |
[leftMatrix sizeToCells]; |
319 |
} |
320 |
|
321 |
TEST_RELEASE (hiddenFiles); |
322 |
} |
323 |
|
324 |
- (IBAction)moveToHidden:(id)sender |
325 |
{ |
326 |
NSArray *cells = [rightMatrix selectedCells]; |
327 |
|
328 |
if (cells) { |
329 |
NSMutableArray *names = [NSMutableArray arrayWithCapacity: 1]; |
330 |
int i; |
331 |
|
332 |
for (i = 0; i < [cells count]; i++) { |
333 |
NSString *name = [[cells objectAtIndex: i] stringValue]; |
334 |
[names addObject: name]; |
335 |
} |
336 |
|
337 |
[self removeCellsWithNames: names inMatrix: rightMatrix]; |
338 |
[self addCellsWithNames: names inMatrix: leftMatrix]; |
339 |
|
340 |
[setButt setEnabled: YES]; |
341 |
} |
342 |
} |
343 |
|
344 |
- (IBAction)moveToShown:(id)sender |
345 |
{ |
346 |
NSArray *cells = [leftMatrix selectedCells]; |
347 |
|
348 |
if (cells) { |
349 |
NSMutableArray *names = [NSMutableArray arrayWithCapacity: 1]; |
350 |
int i; |
351 |
|
352 |
for (i = 0; i < [cells count]; i++) { |
353 |
NSString *name = [[cells objectAtIndex: i] stringValue]; |
354 |
[names addObject: name]; |
355 |
} |
356 |
|
357 |
[self removeCellsWithNames: names inMatrix: leftMatrix]; |
358 |
[self addCellsWithNames: names inMatrix: rightMatrix]; |
359 |
|
360 |
[setButt setEnabled: YES]; |
361 |
} |
362 |
} |
363 |
|
364 |
- (IBAction)activateChanges:(id)sender |
365 |
{ |
366 |
if ([fm isWritableFileAtPath: currentPath] == NO) { |
367 |
NSString *message = @"You have not write access to "; |
368 |
message = [message stringByAppendingString: [currentPath lastPathComponent]]; |
369 |
|
370 |
NSRunAlertPanel(NSLocalizedString(@"error", @""), |
371 |
NSLocalizedString(message, @""), |
372 |
NSLocalizedString(@"Continue", @""), |
373 |
nil, nil); |
374 |
return; |
375 |
} else { |
376 |
NSArray *cells = [leftMatrix cells]; |
377 |
|
378 |
if (cells) { |
379 |
NSMutableArray *names; |
380 |
NSString *hconts; |
381 |
NSString *h; |
382 |
int i; |
383 |
|
384 |
names = [NSMutableArray arrayWithCapacity: 1]; |
385 |
for (i = 0; i < [cells count]; i++) { |
386 |
id cell = [cells objectAtIndex: i]; |
387 |
[names addObject: [cell stringValue]]; |
388 |
} |
389 |
|
390 |
hconts = [names componentsJoinedByString: @"\n"]; |
391 |
h = [currentPath stringByAppendingPathComponent: @".hidden"]; |
392 |
[hconts writeToFile: h atomically: YES]; |
393 |
|
394 |
[setButt setEnabled: NO]; |
395 |
} |
396 |
} |
397 |
} |
398 |
|
399 |
- (void)addCellsWithNames:(NSArray *)names inMatrix:(NSMatrix *)matrix |
400 |
{ |
401 |
id cell; |
402 |
NSSize cs, ms; |
403 |
int i; |
404 |
|
405 |
[matrix setIntercellSpacing: NSMakeSize(0, 0)]; |
406 |
|
407 |
for (i = 0; i < [names count]; i++) { |
408 |
[matrix addRow]; |
409 |
cell = [matrix cellAtRow: [[matrix cells] count] -1 column: 0]; |
410 |
[cell setStringValue: [names objectAtIndex: i]]; |
411 |
[cell setLeaf: YES]; |
412 |
} |
413 |
|
414 |
if (matrix == leftMatrix) { |
415 |
cs = [leftScroll contentSize]; |
416 |
} else { |
417 |
cs = [rightScroll contentSize]; |
418 |
} |
419 |
ms = [matrix cellSize]; |
420 |
ms.width = cs.width; |
421 |
CHECKSIZE (ms); |
422 |
[matrix setCellSize: ms]; |
423 |
[matrix sizeToCells]; |
424 |
|
425 |
[self selectCellsWithNames: names inMatrix: matrix]; |
426 |
|
427 |
[matrix setNeedsDisplay: YES]; |
428 |
} |
429 |
|
430 |
- (void)removeCellsWithNames:(NSArray *)names inMatrix:(NSMatrix *)matrix |
431 |
{ |
432 |
id cell; |
433 |
int i; |
434 |
|
435 |
for (i = 0; i < [names count]; i++) { |
436 |
cell = [self cellWithTitle: [names objectAtIndex: i] inMatrix: matrix]; |
437 |
|
438 |
if (cell != nil) { |
439 |
int row, col; |
440 |
|
441 |
[matrix getRow: &row column: &col ofCell: cell]; |
442 |
[matrix removeRow: row]; |
443 |
} |
444 |
} |
445 |
|
446 |
[matrix sizeToCells]; |
447 |
[matrix setNeedsDisplay: YES]; |
448 |
} |
449 |
|
450 |
- (void)selectCellsWithNames:(NSArray *)names inMatrix:(NSMatrix *)matrix |
451 |
{ |
452 |
int i, count, max; |
453 |
int *selectedIndexes = NULL; |
454 |
NSMutableArray *cells; |
455 |
|
456 |
cells = [NSMutableArray arrayWithCapacity: 1]; |
457 |
for (i = 0; i < [names count]; i++) { |
458 |
NSString *name = [names objectAtIndex: i]; |
459 |
id cell = [self cellWithTitle: name inMatrix: matrix]; |
460 |
|
461 |
if (cell) { |
462 |
[cells addObject: cell]; |
463 |
} |
464 |
} |
465 |
|
466 |
count = [cells count]; |
467 |
max = [matrix numberOfRows]; |
468 |
selectedIndexes = NSZoneMalloc(NSDefaultMallocZone(), sizeof(int) * count); |
469 |
|
470 |
for (i = 0; i < count; i++) { |
471 |
NSCell *cell; |
472 |
int sRow, sColumn; |
473 |
|
474 |
cell = [cells objectAtIndex: i]; |
475 |
[matrix getRow: &sRow column: &sColumn ofCell: cell]; |
476 |
selectedIndexes[i] = sRow; |
477 |
} |
478 |
|
479 |
for (i = 0; i < count; i++) { |
480 |
if (selectedIndexes[i] > max) { |
481 |
break; |
482 |
} |
483 |
[matrix selectCellAtRow: selectedIndexes[i] column: 0]; |
484 |
} |
485 |
|
486 |
NSZoneFree(NSDefaultMallocZone(), selectedIndexes); |
487 |
} |
488 |
|
489 |
- (id)cellWithTitle:(NSString *)title inMatrix:(NSMatrix *)matrix |
490 |
{ |
491 |
NSArray *cells; |
492 |
id cell; |
493 |
int i; |
494 |
|
495 |
cells = [matrix cells]; |
496 |
if (cells) { |
497 |
for (i = 0; i < [cells count]; i++) { |
498 |
cell = [cells objectAtIndex: i]; |
499 |
if ([[cell stringValue] isEqualToString: title]) { |
500 |
return cell; |
501 |
} |
502 |
} |
503 |
} |
504 |
|
505 |
return nil; |
506 |
} |
507 |
|
508 |
@end |