Oolite 1.91.0.7604-240417-a536cbe
Loading...
Searching...
No Matches
OODockTilePlugIn.m
Go to the documentation of this file.
1/*
2
3OODockTilePlugIn.m
4
5
6Oolite
7Copyright (C) 2004-2010 Giles C Williams and contributors
8
9This program is free software; you can redistribute it and/or
10modify it under the terms of the GNU General Public License
11as published by the Free Software Foundation; either version 2
12of the License, or (at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22MA 02110-1301, USA.
23
24*/
25
26#import "OODockTilePlugIn.h"
29
30
31#define OOLITE_LEOPARD 1
32
33
34@interface OODockTilePlugIn ()
35
36- (NSURL *) snapshotsURLCreatingIfNeeded:(BOOL)create;
37- (NSString *) latestLogPath;
38- (NSString *) logFolderPath;
39
40@end
41
42
43static NSString *OOLogHandlerGetLogBasePath(void);
44static NSArray *ResourceManagerRootPaths(void);
45
46
47@implementation OODockTilePlugIn
48
49@synthesize dockTile = _dockTile;
50@synthesize dockMenu = _dockMenu;
51
52
53- (id) init
54{
55 if ((self = [super init]))
56 {
57 [NSBundle loadNibNamed:@"OODockTilePlugIn" owner:self];
58 }
59
60 return self;
61}
62
63
64- (void) dealloc
65{
66 self.dockTile = nil;
67 self.dockMenu = nil;
68
69 [super dealloc];
70}
71
72
73- (IBAction) showScreenShots:(id)sender
74{
75 [[NSWorkspace sharedWorkspace] openURL:[self snapshotsURLCreatingIfNeeded:NO]];
76}
77
78
79- (IBAction) showExpansionPacks:sender
80{
81 NSArray *paths = ResourceManagerRootPaths();
82
83 // Look for an AddOns directory that actually contains some AddOns.
84 for (NSString *path in paths) {
85 if ([self addOnsExistAtPath:path]) {
86 [self openPath:path];
87 return;
88 }
89 }
90
91 // If that failed, look for an AddOns directory that actually exists.
92 for (NSString *path in paths) {
93 if ([self isDirectoryAtPath:path]) {
94 [self openPath:path];
95 return;
96 }
97 }
98
99 // None found, create the default path.
100 [NSFileManager.defaultManager createDirectoryAtPath:paths[0]
101 withIntermediateDirectories:YES
102 attributes:nil
103 error:NULL];
104 [self openPath:paths[0]];
105}
106
107
108- (BOOL) isDirectoryAtPath:(NSString *)path
109{
110 BOOL isDirectory;
111 return [NSFileManager.defaultManager fileExistsAtPath:path isDirectory:&isDirectory] && isDirectory;
112}
113
114
115- (BOOL) addOnsExistAtPath:(NSString *)path
116{
117 if (![self isDirectoryAtPath:path]) return NO;
118
119 NSWorkspace *workspace = NSWorkspace.sharedWorkspace;
120 for (NSString *subPath in [NSFileManager.defaultManager enumeratorAtPath:path]) {
121 subPath = [path stringByAppendingPathComponent:subPath];
122 NSString *type = [workspace typeOfFile:subPath error:NULL];
123 if ([workspace type:type conformsToType:@"org.aegidian.oolite.expansion"]) return YES;
124 }
125
126 return NO;
127}
128
129
130- (void) openPath:(NSString *)path
131{
132 [NSWorkspace.sharedWorkspace openURL:[NSURL fileURLWithPath:path]];
133}
134
135
136- (IBAction) showLatestLog:(id)sender
137{
138 [[NSWorkspace sharedWorkspace] openURL:[NSURL fileURLWithPath:[self latestLogPath]]];
139}
140
141
142- (IBAction) showLogFolder:(id)sender
143{
144 [[NSWorkspace sharedWorkspace] openURL:[NSURL fileURLWithPath:[self logFolderPath]]];
145}
146
147
148- (BOOL) validateMenuItem:(NSMenuItem *)menuItem
149{
150 SEL action = [menuItem action];
151
152 if (action == @selector(showScreenShots:))
153 {
154 return [[NSFileManager defaultManager] fileExistsAtPath:[[self snapshotsURLCreatingIfNeeded:NO] path]];
155 }
156 else if (action == @selector(showLatestLog:))
157 {
158 return [[NSFileManager defaultManager] fileExistsAtPath:[self latestLogPath]];
159 }
160
161 return YES;
162}
163
164
165static id GetPreference(NSString *key, Class expectedClass)
166{
167 // Use CFPreferences instead of NSDefaults so we can specify the app ID.
168 CFPropertyListRef value = CFPreferencesCopyAppValue((CFStringRef)key, CFSTR("org.aegidian.oolite"));
169 id result = [NSMakeCollectable(value) autorelease];
170 if (expectedClass != Nil && ![result isKindOfClass:expectedClass]) result = nil;
171
172 return result;
173}
174
175
176static void SetPreference(NSString *key, id value)
177{
178 CFPreferencesSetAppValue((CFStringRef)key, value, CFSTR("org.aegidian.oolite"));
179}
180
181
182static void RemovePreference(NSString *key)
183{
184 SetPreference(key, nil);
185}
186
187
188static NSString *DESC(NSString *key)
189{
190 static NSDictionary *descs = nil;
191 if (descs == nil)
192 {
193 // Get default description.plist from Oolite.
194 NSURL *url = [[NSBundle bundleForClass:[OODockTilePlugIn class]] bundleURL];
195 url = [NSURL URLWithString:@"../../Resources/Config/descriptions.plist" relativeToURL:url];
196
197 descs = [NSDictionary dictionaryWithContentsOfURL:url];
198 if (descs == nil) descs = [NSDictionary dictionary];
199 [descs retain];
200 }
201
202 NSString *result = [descs objectForKey:key];
203 if (![result isKindOfClass:[NSString class]]) result = key; // We don't need to deal with arrays.
204 return result;
205}
206
207
208#define kSnapshotsDirRefKey @"snapshots-directory-reference"
209#define kSnapshotsDirNameKey @"snapshots-directory-name"
210
211- (NSURL *) snapshotsURLCreatingIfNeeded:(BOOL)create
212{
213 BOOL stale = NO;
214 NSDictionary *snapshotDirDict = GetPreference(kSnapshotsDirRefKey, [NSDictionary class]);
215 NSURL *url = nil;
216 NSString *name = DESC(@"snapshots-directory-name-mac");
217
218 if (snapshotDirDict != nil)
219 {
221 if (url != nil)
222 {
223 NSString *existingName = [[url path] lastPathComponent];
224 if ([existingName compare:name options:NSCaseInsensitiveSearch] != 0)
225 {
226 // Check name from previous access, because we might have changed localizations.
227 NSString *originalOldName = GetPreference(kSnapshotsDirNameKey, [NSString class]);
228 if (originalOldName == nil || [existingName compare:originalOldName options:NSCaseInsensitiveSearch] != 0)
229 {
230 url = nil;
231 }
232 }
233
234 // did we put the old directory in the trash?
235 Boolean inTrash = false;
236 const UInt8* utfPath = (UInt8*)[[url path] UTF8String];
237
238 OSStatus err = DetermineIfPathIsEnclosedByFolder(kOnAppropriateDisk, kTrashFolderType, utfPath, false, &inTrash);
239 // if so, create a new directory.
240 if (err == noErr && inTrash == true) url = nil;
241 }
242 }
243
244 if (url == nil)
245 {
246 NSString *path = nil;
247 NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDesktopDirectory, NSUserDomainMask, YES);
248 if ([searchPaths count] > 0)
249 {
250 path = [[searchPaths objectAtIndex:0] stringByAppendingPathComponent:name];
251 }
252 url = [NSURL fileURLWithPath:path];
253
254 if (url != nil)
255 {
256 stale = YES;
257 if (create)
258 {
259 NSFileManager *fmgr = [NSFileManager defaultManager];
260 if (![fmgr fileExistsAtPath:path])
261 {
262#if OOLITE_LEOPARD
263 [fmgr createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:NULL];
264#else
265 [fmgr createDirectoryAtPath:path attributes:nil];
266#endif
267 }
268 }
269 }
270 }
271
272 if (stale)
273 {
274 snapshotDirDict = JAPersistentFileReferenceFromURL(url);
275 if (snapshotDirDict != nil)
276 {
277 SetPreference(kSnapshotsDirRefKey, snapshotDirDict);
278 SetPreference(kSnapshotsDirNameKey, [[url path] lastPathComponent]);
279 }
280 else
281 {
283 }
284 }
285
286 return url;
287}
288
289
290- (NSString *) latestLogPath
291{
292 return [[self logFolderPath] stringByAppendingPathComponent:@"Latest.log"];
293}
294
295
296- (NSString *) logFolderPath
297{
299}
300
301@end
302
303
304// Adapted from OOLogOutputHandler.m.
305static NSString *OOLogHandlerGetLogBasePath(void)
306{
307 static NSString *basePath = nil;
308
309 if (basePath == nil)
310 {
311 // ~/Library
312 basePath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0];
313 basePath = [basePath stringByAppendingPathComponent:@"Logs"];
314 basePath = [basePath stringByAppendingPathComponent:@"Oolite"];
315
316 BOOL exists, directory;
317 NSFileManager *fmgr = [NSFileManager defaultManager];
318
319 exists = [fmgr fileExistsAtPath:basePath isDirectory:&directory];
320 if (exists)
321 {
322 if (!directory)
323 {
324 basePath = nil;
325 }
326 }
327 else
328 {
329 if (![fmgr createDirectoryAtPath:basePath withIntermediateDirectories:YES attributes:nil error:NULL])
330 {
331 basePath = nil;
332 }
333 }
334
335 [basePath retain];
336 }
337
338 return basePath;
339}
340
341
342static NSArray *ResourceManagerRootPaths(void)
343{
344 // Adapted from -[ResourceManager rootPaths].
345 return [NSArray arrayWithObjects:
346 [[[[NSHomeDirectory() stringByAppendingPathComponent:@"Library"]
347 stringByAppendingPathComponent:@"Application Support"]
348 stringByAppendingPathComponent:@"Oolite"]
349 stringByAppendingPathComponent:@"AddOns"],
350 [[[[NSBundle mainBundle] bundlePath]
351 stringByDeletingLastPathComponent]
352 stringByAppendingPathComponent:@"AddOns"],
353 [[NSHomeDirectory()
354 stringByAppendingPathComponent:@".Oolite"]
355 stringByAppendingPathComponent:@"AddOns"],
356 nil];
357}
#define kSnapshotsDirNameKey
#define kSnapshotsDirRefKey
@ kJAPersistentFileReferenceWithoutUI
@ kJAPersistentFileReferenceWithoutMounting
NSURL * JAURLFromPersistentFileReference(NSDictionary *fileRef, JAPersistentFileReferenceResolveFlags flags, BOOL *isStale)
NSDictionary * JAPersistentFileReferenceFromURL(NSURL *url)
static NSString * OOLogHandlerGetLogBasePath(void)
static NSArray * ResourceManagerRootPaths(void)
NSString * OOLogHandlerGetLogBasePath(void)
unsigned count
return nil
#define DESC(key)
Definition Universe.h:839
static void SetPreference(NSString *key, id value)
static NSString * DESC(NSString *key)
IBOutlet NSMenu * dockMenu
NSDockTile * dockTile
static id GetPreference(NSString *key, Class expectedClass)
NSDockTile * _dockTile
static void RemovePreference(NSString *key)
NSString * latestLogPath()
NSString * logFolderPath()