| 1 |
/* $Id$ */ |
|---|
| 2 |
|
|---|
| 3 |
/* |
|---|
| 4 |
* Copyright (c) 2005 Axel Andersson |
|---|
| 5 |
* All rights reserved. |
|---|
| 6 |
* |
|---|
| 7 |
* Redistribution and use in source and binary forms, with or without |
|---|
| 8 |
* modification, are permitted provided that the following conditions |
|---|
| 9 |
* are met: |
|---|
| 10 |
* 1. Redistributions of source code must retain the above copyright |
|---|
| 11 |
* notice, this list of conditions and the following disclaimer. |
|---|
| 12 |
* 2. Redistributions in binary form must reproduce the above copyright |
|---|
| 13 |
* notice, this list of conditions and the following disclaimer in the |
|---|
| 14 |
* documentation and/or other materials provided with the distribution. |
|---|
| 15 |
* |
|---|
| 16 |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
|---|
| 17 |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|---|
| 18 |
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
|---|
| 19 |
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, |
|---|
| 20 |
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
|---|
| 21 |
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
|---|
| 22 |
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
|---|
| 23 |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
|---|
| 24 |
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
|---|
| 25 |
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|---|
| 26 |
* POSSIBILITY OF SUCH DAMAGE. |
|---|
| 27 |
*/ |
|---|
| 28 |
|
|---|
| 29 |
#import "CPUController.h" |
|---|
| 30 |
#import "CPUDataSource.h" |
|---|
| 31 |
#import "CPUExpandedView.h" |
|---|
| 32 |
#import "CPUFloatingView.h" |
|---|
| 33 |
#import "CPUPanel.h" |
|---|
| 34 |
#import "CPUSettings.h" |
|---|
| 35 |
|
|---|
| 36 |
@implementation CPUController |
|---|
| 37 |
|
|---|
| 38 |
- (void)awakeFromNib { |
|---|
| 39 |
NSImageView *imageView; |
|---|
| 40 |
NSMutableArray *imageViews; |
|---|
| 41 |
NSTimer *timer; |
|---|
| 42 |
NSRect frame, rect; |
|---|
| 43 |
NSPoint point; |
|---|
| 44 |
unsigned int i, tag, numberOfCPUs; |
|---|
| 45 |
float alpha; |
|---|
| 46 |
|
|---|
| 47 |
[_floatingViewColorWell setColor:[CPUSettings objectForKey:CPUFloatingViewColor]]; |
|---|
| 48 |
|
|---|
| 49 |
alpha = [CPUSettings floatForKey:CPUFloatingViewAlpha]; |
|---|
| 50 |
|
|---|
| 51 |
if(alpha > 0.75) |
|---|
| 52 |
[_floatingViewAlphaMatrix selectCellWithTag:0]; |
|---|
| 53 |
else if(alpha <= 0.50) |
|---|
| 54 |
[_floatingViewAlphaMatrix selectCellWithTag:2]; |
|---|
| 55 |
else |
|---|
| 56 |
[_floatingViewAlphaMatrix selectCellWithTag:1]; |
|---|
| 57 |
|
|---|
| 58 |
[_floatingViewOrientationMatrix selectCellWithTag:[CPUSettings intForKey:CPUFloatingViewOrientation]]; |
|---|
| 59 |
|
|---|
| 60 |
[_expandedViewSystemColorWell setColor:[CPUSettings objectForKey:CPUExpandedViewSystemColor]]; |
|---|
| 61 |
[_expandedViewUserColorWell setColor:[CPUSettings objectForKey:CPUExpandedViewUserColor]]; |
|---|
| 62 |
[_expandedViewNiceColorWell setColor:[CPUSettings objectForKey:CPUExpandedViewNiceColor]]; |
|---|
| 63 |
[_expandedViewBackgroundColorWell setColor:[CPUSettings objectForKey:CPUExpandedViewBackgroundColor]]; |
|---|
| 64 |
|
|---|
| 65 |
tag = [CPUSettings intForKey:CPUApplicationIconDisplay]; |
|---|
| 66 |
[_applicationIconMatrix selectCellWithTag:tag]; |
|---|
| 67 |
|
|---|
| 68 |
switch(tag) { |
|---|
| 69 |
case CPUApplicationIconStandardView: |
|---|
| 70 |
_applicationIconStatus = CPUApplicationIconStandard; |
|---|
| 71 |
break; |
|---|
| 72 |
|
|---|
| 73 |
case CPUApplicationIconExpandedView: |
|---|
| 74 |
_applicationIconStatus = CPUApplicationIconExpanded; |
|---|
| 75 |
break; |
|---|
| 76 |
} |
|---|
| 77 |
|
|---|
| 78 |
[_standardPanel setFrameAutosaveName:@"StandardWindow"]; |
|---|
| 79 |
[_standardPanel setFloatingPanel:YES]; |
|---|
| 80 |
[_standardPanel setHidesOnDeactivate:NO]; |
|---|
| 81 |
|
|---|
| 82 |
numberOfCPUs = [CPUDataSource dataSource]->_numberOfCPUs; |
|---|
| 83 |
|
|---|
| 84 |
if(numberOfCPUs > 1) { |
|---|
| 85 |
frame = [_standardPanel frame]; |
|---|
| 86 |
frame.size.width = (numberOfCPUs * CPUStandardViewWidth) + 17.0; |
|---|
| 87 |
[_standardPanel setFrame:frame display:NO]; |
|---|
| 88 |
rect = [_standardPanel contentRectForFrameRect:frame]; |
|---|
| 89 |
point = [_standardPanel convertScreenToBase:rect.origin]; |
|---|
| 90 |
|
|---|
| 91 |
frame = [_standardBackgroundImageView frame]; |
|---|
| 92 |
frame.origin.x = 3.0; |
|---|
| 93 |
[_standardBackgroundImageView setFrame:frame]; |
|---|
| 94 |
[_standardImageView setFrame:frame]; |
|---|
| 95 |
|
|---|
| 96 |
imageViews = [[NSMutableArray alloc] initWithCapacity:numberOfCPUs]; |
|---|
| 97 |
[imageViews addObject:_standardImageView]; |
|---|
| 98 |
|
|---|
| 99 |
for(i = 1; i < numberOfCPUs; i++) { |
|---|
| 100 |
frame.origin.x += i * CPUStandardViewWidth; |
|---|
| 101 |
|
|---|
| 102 |
imageView = [[NSImageView alloc] initWithFrame:frame]; |
|---|
| 103 |
[imageView setImage:[NSImage imageNamed:@"StandardViewBackground.tiff"]]; |
|---|
| 104 |
[_standardBox addSubview:imageView]; |
|---|
| 105 |
[imageView release]; |
|---|
| 106 |
|
|---|
| 107 |
imageView = [[NSImageView alloc] initWithFrame:frame]; |
|---|
| 108 |
[imageView setImage:[NSImage imageNamed:@"StandardView07.tiff"]]; |
|---|
| 109 |
[_standardBox addSubview:imageView]; |
|---|
| 110 |
[imageViews addObject:imageView]; |
|---|
| 111 |
[imageView release]; |
|---|
| 112 |
} |
|---|
| 113 |
|
|---|
| 114 |
_imageViews = [[NSArray alloc] initWithArray:imageViews]; |
|---|
| 115 |
[imageViews release]; |
|---|
| 116 |
} else { |
|---|
| 117 |
_imageViews = [[NSArray alloc] initWithObjects:_standardImageView, NULL]; |
|---|
| 118 |
} |
|---|
| 119 |
|
|---|
| 120 |
[_expandedPanel setFrameAutosaveName:@"ExpandedWindow"]; |
|---|
| 121 |
[_expandedPanel setFloatingPanel:YES]; |
|---|
| 122 |
[_expandedPanel setHidesOnDeactivate:NO]; |
|---|
| 123 |
|
|---|
| 124 |
_applicationIcon = [[NSApp applicationIconImage] copy]; |
|---|
| 125 |
|
|---|
| 126 |
timer = [NSTimer scheduledTimerWithTimeInterval:[CPUSettings doubleForKey:CPUUpdateInterval] |
|---|
| 127 |
target:self |
|---|
| 128 |
selector:@selector(timer:) |
|---|
| 129 |
userInfo:NULL |
|---|
| 130 |
repeats:YES]; |
|---|
| 131 |
|
|---|
| 132 |
if([CPUSettings boolForKey:CPUStandardViewShown]) |
|---|
| 133 |
[_standardPanel makeKeyAndOrderFront:self]; |
|---|
| 134 |
|
|---|
| 135 |
if([CPUSettings boolForKey:CPUFloatingViewShown]) |
|---|
| 136 |
[self toggleFloatingWindow:self]; |
|---|
| 137 |
|
|---|
| 138 |
if([CPUSettings boolForKey:CPUExpandedViewShown]) |
|---|
| 139 |
[_expandedPanel makeKeyAndOrderFront:self]; |
|---|
| 140 |
} |
|---|
| 141 |
|
|---|
| 142 |
|
|---|
| 143 |
|
|---|
| 144 |
- (void)dealloc { |
|---|
| 145 |
[_floatingPanel release]; |
|---|
| 146 |
[_imageViews release]; |
|---|
| 147 |
[_applicationIcon release]; |
|---|
| 148 |
|
|---|
| 149 |
[super dealloc]; |
|---|
| 150 |
} |
|---|
| 151 |
|
|---|
| 152 |
|
|---|
| 153 |
|
|---|
| 154 |
#pragma mark - |
|---|
| 155 |
|
|---|
| 156 |
- (void)applicationWillTerminate:(NSNotification *)notification { |
|---|
| 157 |
[CPUSettings setBool:[_standardPanel isVisible] forKey:CPUStandardViewShown]; |
|---|
| 158 |
[CPUSettings setBool:[_floatingPanel isVisible] forKey:CPUFloatingViewShown]; |
|---|
| 159 |
[CPUSettings setBool:[_expandedPanel isVisible] forKey:CPUExpandedViewShown]; |
|---|
| 160 |
} |
|---|
| 161 |
|
|---|
| 162 |
|
|---|
| 163 |
|
|---|
| 164 |
#pragma mark - |
|---|
| 165 |
|
|---|
| 166 |
- (void)timer:(NSTimer *)timer { |
|---|
| 167 |
NSString *imageName; |
|---|
| 168 |
NSImage *image; |
|---|
| 169 |
NSBitmapImageRep *imageRep; |
|---|
| 170 |
CPUDataSource *dataSource; |
|---|
| 171 |
CPUData *data; |
|---|
| 172 |
NSRect frame; |
|---|
| 173 |
float width; |
|---|
| 174 |
unsigned int i, numberOfCPUs, usage; |
|---|
| 175 |
|
|---|
| 176 |
if([_floatingPanel isVisible]) |
|---|
| 177 |
[_floatingView setNeedsDisplay:YES]; |
|---|
| 178 |
|
|---|
| 179 |
if([_expandedPanel isVisible]) |
|---|
| 180 |
[_expandedView refresh]; |
|---|
| 181 |
|
|---|
| 182 |
if([_standardPanel isVisible] || _applicationIconStatus == CPUApplicationIconStandard) { |
|---|
| 183 |
dataSource = [CPUDataSource dataSource]; |
|---|
| 184 |
numberOfCPUs = dataSource->_numberOfCPUs; |
|---|
| 185 |
|
|---|
| 186 |
for(i = 0; i < numberOfCPUs; i++) { |
|---|
| 187 |
data = dataSource->_data[i]; |
|---|
| 188 |
usage = (data->_user + data->_system + data->_nice) * 19; |
|---|
| 189 |
|
|---|
| 190 |
switch(usage) { |
|---|
| 191 |
default: |
|---|
| 192 |
case 0: imageName = @"StandardView00.tiff"; break; |
|---|
| 193 |
case 1: imageName = @"StandardView01.tiff"; break; |
|---|
| 194 |
case 2: imageName = @"StandardView02.tiff"; break; |
|---|
| 195 |
case 3: imageName = @"StandardView03.tiff"; break; |
|---|
| 196 |
case 4: imageName = @"StandardView04.tiff"; break; |
|---|
| 197 |
case 5: imageName = @"StandardView05.tiff"; break; |
|---|
| 198 |
case 6: imageName = @"StandardView06.tiff"; break; |
|---|
| 199 |
case 7: imageName = @"StandardView07.tiff"; break; |
|---|
| 200 |
case 8: imageName = @"StandardView08.tiff"; break; |
|---|
| 201 |
case 9: imageName = @"StandardView09.tiff"; break; |
|---|
| 202 |
case 10: imageName = @"StandardView10.tiff"; break; |
|---|
| 203 |
case 11: imageName = @"StandardView11.tiff"; break; |
|---|
| 204 |
case 12: imageName = @"StandardView12.tiff"; break; |
|---|
| 205 |
case 13: imageName = @"StandardView13.tiff"; break; |
|---|
| 206 |
case 14: imageName = @"StandardView14.tiff"; break; |
|---|
| 207 |
case 15: imageName = @"StandardView15.tiff"; break; |
|---|
| 208 |
case 16: imageName = @"StandardView16.tiff"; break; |
|---|
| 209 |
case 17: imageName = @"StandardView17.tiff"; break; |
|---|
| 210 |
case 18: imageName = @"StandardView18.tiff"; break; |
|---|
| 211 |
} |
|---|
| 212 |
|
|---|
| 213 |
[[_imageViews objectAtIndex:i] setImage:[NSImage imageNamed:imageName]]; |
|---|
| 214 |
} |
|---|
| 215 |
} |
|---|
| 216 |
|
|---|
| 217 |
switch(_applicationIconStatus) { |
|---|
| 218 |
case CPUApplicationIconStandard: |
|---|
| 219 |
[_standardBox lockFocus]; |
|---|
| 220 |
frame = [_standardBox frame]; |
|---|
| 221 |
width = frame.size.width > 128.0 ? 128.0 : frame.size.width; |
|---|
| 222 |
imageRep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:frame]; |
|---|
| 223 |
[_standardBox unlockFocus]; |
|---|
| 224 |
|
|---|
| 225 |
image = [[NSImage alloc] initWithSize:NSMakeSize(128.0, 128.0)]; |
|---|
| 226 |
[image lockFocus]; |
|---|
| 227 |
[imageRep drawInRect:NSMakeRect(64.0 - (width / 2.0), 0.0, width, 128.0)]; |
|---|
| 228 |
[image unlockFocus]; |
|---|
| 229 |
[NSApp setApplicationIconImage:image]; |
|---|
| 230 |
[image release]; |
|---|
| 231 |
[imageRep release]; |
|---|
| 232 |
break; |
|---|
| 233 |
|
|---|
| 234 |
case CPUApplicationIconExpanded: |
|---|
| 235 |
image = [[NSImage alloc] initWithSize:NSMakeSize(128.0, 128.0)]; |
|---|
| 236 |
[image lockFocus]; |
|---|
| 237 |
[_expandedView drawIconInRect:NSMakeRect(0.0, 0.0, 128.0, 128.0)]; |
|---|
| 238 |
[image unlockFocus]; |
|---|
| 239 |
[NSApp setApplicationIconImage:image]; |
|---|
| 240 |
[image release]; |
|---|
| 241 |
break; |
|---|
| 242 |
|
|---|
| 243 |
case CPUApplicationIconResetDefault: |
|---|
| 244 |
[NSApp setApplicationIconImage:_applicationIcon]; |
|---|
| 245 |
_applicationIconStatus = CPUApplicationIconDefault; |
|---|
| 246 |
break; |
|---|
| 247 |
|
|---|
| 248 |
case CPUApplicationIconDefault: |
|---|
| 249 |
break; |
|---|
| 250 |
} |
|---|
| 251 |
} |
|---|
| 252 |
|
|---|
| 253 |
|
|---|
| 254 |
|
|---|
| 255 |
#pragma mark - |
|---|
| 256 |
|
|---|
| 257 |
- (IBAction)toggleFloatingWindow:(id)sender { |
|---|
| 258 |
NSRect frame, rect; |
|---|
| 259 |
BOOL horizontal; |
|---|
| 260 |
|
|---|
| 261 |
if(!_floatingPanel) { |
|---|
| 262 |
rect = [[NSScreen mainScreen] frame]; |
|---|
| 263 |
frame = NSMakeRect(rect.origin.x + 200.0, rect.origin.y + rect.size.height - 5.0, 10.0, 10.0); |
|---|
| 264 |
horizontal = ([CPUSettings intForKey:CPUFloatingViewOrientation] == CPUFloatingViewHorizontal); |
|---|
| 265 |
|
|---|
| 266 |
_floatingView = [[CPUFloatingView alloc] initWithFrame:frame isHorizontal:horizontal]; |
|---|
| 267 |
_floatingPanel = [[CPUPanel alloc] initWithContentRect:[_floatingView frame] |
|---|
| 268 |
styleMask:NSBorderlessWindowMask |
|---|
| 269 |
backing:NSBackingStoreBuffered |
|---|
| 270 |
defer:YES]; |
|---|
| 271 |
[_floatingPanel setFrameAutosaveName:@"FloatingWindow"]; |
|---|
| 272 |
[_floatingPanel setMovableByWindowBackground:YES]; |
|---|
| 273 |
[_floatingPanel setHidesOnDeactivate:NO]; |
|---|
| 274 |
[_floatingPanel setHasShadow:NO]; |
|---|
| 275 |
[_floatingPanel setOpaque:NO]; |
|---|
| 276 |
[_floatingPanel setAlphaValue:[CPUSettings doubleForKey:CPUFloatingViewAlpha]]; |
|---|
| 277 |
[_floatingPanel setFloatingPanel:YES]; |
|---|
| 278 |
[_floatingPanel setLevel:NSMainMenuWindowLevel + 1]; |
|---|
| 279 |
[_floatingPanel setBackgroundColor:[NSColor clearColor]]; |
|---|
| 280 |
[_floatingPanel setContentView:_floatingView]; |
|---|
| 281 |
[_floatingView release]; |
|---|
| 282 |
} |
|---|
| 283 |
|
|---|
| 284 |
if([_floatingPanel isVisible]) |
|---|
| 285 |
[_floatingPanel close]; |
|---|
| 286 |
else |
|---|
| 287 |
[_floatingPanel makeKeyAndOrderFront:self]; |
|---|
| 288 |
} |
|---|
| 289 |
|
|---|
| 290 |
|
|---|
| 291 |
|
|---|
| 292 |
- (IBAction)clearExpandedWindow:(id)sender { |
|---|
| 293 |
[[CPUDataSource dataSource] clearHistory]; |
|---|
| 294 |
[_expandedView invalidate]; |
|---|
| 295 |
[_expandedView setNeedsDisplay:YES]; |
|---|
| 296 |
} |
|---|
| 297 |
|
|---|
| 298 |
|
|---|
| 299 |
|
|---|
| 300 |
- (IBAction)openActivityMonitor:(id)sender { |
|---|
| 301 |
[[NSWorkspace sharedWorkspace] launchApplication:@"Activity Monitor"]; |
|---|
| 302 |
} |
|---|
| 303 |
|
|---|
| 304 |
|
|---|
| 305 |
|
|---|
| 306 |
- (IBAction)openTop:(id)sender { |
|---|
| 307 |
[[NSWorkspace sharedWorkspace] openFile:@"/usr/bin/top"]; |
|---|
| 308 |
} |
|---|
| 309 |
|
|---|
| 310 |
|
|---|
| 311 |
|
|---|
| 312 |
- (IBAction)changeFloatingView:(id)sender { |
|---|
| 313 |
float alpha; |
|---|
| 314 |
|
|---|
| 315 |
[CPUSettings setObject:[_floatingViewColorWell color] forKey:CPUFloatingViewColor]; |
|---|
| 316 |
|
|---|
| 317 |
switch([_floatingViewAlphaMatrix selectedTag]) { |
|---|
| 318 |
case 0: |
|---|
| 319 |
default: |
|---|
| 320 |
alpha = 1.0; |
|---|
| 321 |
break; |
|---|
| 322 |
|
|---|
| 323 |
case 1: |
|---|
| 324 |
alpha = 0.75; |
|---|
| 325 |
break; |
|---|
| 326 |
|
|---|
| 327 |
case 2: |
|---|
| 328 |
alpha = 0.50; |
|---|
| 329 |
break; |
|---|
| 330 |
} |
|---|
| 331 |
|
|---|
| 332 |
[CPUSettings setFloat:alpha forKey:CPUFloatingViewAlpha]; |
|---|
| 333 |
[CPUSettings setInt:[_floatingViewOrientationMatrix selectedTag] forKey:CPUFloatingViewOrientation]; |
|---|
| 334 |
|
|---|
| 335 |
[_floatingView setIsHorizontal:([CPUSettings intForKey:CPUFloatingViewOrientation] == CPUFloatingViewHorizontal)]; |
|---|
| 336 |
[_floatingPanel setContentSize:[_floatingView frame].size]; |
|---|
| 337 |
[_floatingPanel setAlphaValue:alpha]; |
|---|
| 338 |
} |
|---|
| 339 |
|
|---|
| 340 |
|
|---|
| 341 |
|
|---|
| 342 |
- (IBAction)changeExpandedView:(id)sender { |
|---|
| 343 |
[CPUSettings setObject:[_expandedViewSystemColorWell color] forKey:CPUExpandedViewSystemColor]; |
|---|
| 344 |
[CPUSettings setObject:[_expandedViewUserColorWell color] forKey:CPUExpandedViewUserColor]; |
|---|
| 345 |
[CPUSettings setObject:[_expandedViewNiceColorWell color] forKey:CPUExpandedViewNiceColor]; |
|---|
| 346 |
[CPUSettings setObject:[_expandedViewBackgroundColorWell color] forKey:CPUExpandedViewBackgroundColor]; |
|---|
| 347 |
|
|---|
| 348 |
[_expandedView invalidate]; |
|---|
| 349 |
[_expandedView setNeedsDisplay:YES]; |
|---|
| 350 |
} |
|---|
| 351 |
|
|---|
| 352 |
|
|---|
| 353 |
|
|---|
| 354 |
- (IBAction)changeApplicationIcon:(id)sender { |
|---|
| 355 |
unsigned int tag; |
|---|
| 356 |
|
|---|
| 357 |
tag = [_applicationIconMatrix selectedTag]; |
|---|
| 358 |
|
|---|
| 359 |
switch(tag) { |
|---|
| 360 |
case CPUApplicationIconStandardView: |
|---|
| 361 |
_applicationIconStatus = CPUApplicationIconStandard; |
|---|
| 362 |
break; |
|---|
| 363 |
|
|---|
| 364 |
case CPUApplicationIconExpandedView: |
|---|
| 365 |
_applicationIconStatus = CPUApplicationIconExpanded; |
|---|
| 366 |
break; |
|---|
| 367 |
|
|---|
| 368 |
case CPUApplicationIconNone: |
|---|
| 369 |
if(_applicationIconStatus != CPUApplicationIconDefault) |
|---|
| 370 |
_applicationIconStatus = CPUApplicationIconResetDefault; |
|---|
| 371 |
break; |
|---|
| 372 |
} |
|---|
| 373 |
|
|---|
| 374 |
[CPUSettings setInt:tag forKey:CPUApplicationIconDisplay]; |
|---|
| 375 |
} |
|---|
| 376 |
|
|---|
| 377 |
|
|---|
| 378 |
|
|---|
| 379 |
- (IBAction)releaseNotes:(id)sender { |
|---|
| 380 |
NSAttributedString *string; |
|---|
| 381 |
NSString *path; |
|---|
| 382 |
|
|---|
| 383 |
if([[_releaseNotesTextView string] length] == 0) { |
|---|
| 384 |
path = [[self bundle] pathForResource:@"ReleaseNotes" ofType:@"rtf"]; |
|---|
| 385 |
string = [[NSAttributedString alloc] initWithRTF:[NSData dataWithContentsOfFile:path] |
|---|
| 386 |
documentAttributes:NULL]; |
|---|
| 387 |
|
|---|
| 388 |
[_releaseNotesTextView setAttributedString:string]; |
|---|
| 389 |
[string release]; |
|---|
| 390 |
} |
|---|
| 391 |
|
|---|
| 392 |
[_releaseNotesWindow makeKeyAndOrderFront:self]; |
|---|
| 393 |
} |
|---|
| 394 |
|
|---|
| 395 |
@end |
|---|