WizardKit
0.1
|
00001 /* 00002 * WKWizardPanel.m 00003 * 00004 * Implementation of the WKWizardPanel class for the WizardKit framework 00005 * 00006 * Copyright (c) 2006, by Saso Kiselkov 00007 * 00008 * For license details please see the file COPYING included with this 00009 * source distribution package. 00010 */ 00011 00012 #import "WKWizardPanel.h" 00013 00014 #import <Foundation/NSString.h> 00015 #import <Foundation/NSBundle.h> 00016 #import <Foundation/NSArray.h> 00017 #import <Foundation/NSDictionary.h> 00018 #import <Foundation/NSException.h> 00019 #import <Foundation/NSNotification.h> 00020 #import <Foundation/NSCoder.h> 00021 00022 #import <AppKit/NSApplication.h> 00023 00029 NSString * const WKWizardPanelDidChangeCurrentStageNotification 00030 = @"WKWizardPanelDidChangeCurrentStageNotification"; 00031 00032 @interface WKWizardPanel (Private) 00033 00034 - (void) setupForStage: (NSString *) aStage; 00035 00036 @end 00037 00063 @implementation WKWizardPanel 00064 00065 - (void) dealloc 00066 { 00067 TEST_RELEASE(stages); 00068 TEST_RELEASE(initialStage); 00069 00070 [super dealloc]; 00071 } 00072 00082 - (void) setStages: (NSArray *) someStages 00083 { 00084 if (isActive == YES) 00085 { 00086 [NSException raise: NSInternalInconsistencyException 00087 format: _(@"-[WKWizardPanel setStages:]: panel already " 00088 @"active - stages must be set before activating the panel.")]; 00089 } 00090 00091 ASSIGNCOPY(stages, someStages); 00092 DESTROY(initialStage); 00093 } 00094 00102 - (NSArray *) stages 00103 { 00104 return stages; 00105 } 00106 00115 - (void) setRunsInModalSession: (BOOL) flag 00116 { 00117 if (isActive == YES) 00118 { 00119 [NSException raise: NSInternalInconsistencyException 00120 format: _(@"-[WKWizardPanel setRunsInModalSession:] " 00121 @"panel already active - modality must be set before activating " 00122 @"the panel.")]; 00123 } 00124 00125 runsInModalSession = flag; 00126 } 00127 00135 - (BOOL) runsInModalSession 00136 { 00137 return runsInModalSession; 00138 } 00139 00146 - (void) setInitialStage: (NSString *) aStageName 00147 { 00148 if (aStageName != nil && [stages containsObject: aStageName] == NO) 00149 { 00150 [NSException raise: NSInvalidArgumentException 00151 format: _(@"-[WKWizardPanel setInitialStage:]: " 00152 @"invalid stage name passed. Stage \"%@\" not in stages list: %@."), 00153 aStageName, stages]; 00154 } 00155 00156 ASSIGN(initialStage, aStageName); 00157 } 00158 00166 - (NSString *) initialStage 00167 { 00168 return initialStage; 00169 } 00170 00177 - (void) setCentersBeforeActivating: (BOOL) flag 00178 { 00179 centersBeforeActivating = flag; 00180 } 00181 00189 - (BOOL) centersBeforeActivating 00190 { 00191 return centersBeforeActivating; 00192 } 00193 00205 - (void) setCurrentStage: (NSString *) aStageName 00206 { 00207 currentStage = [stages indexOfObject: aStageName]; 00208 if (currentStage == NSNotFound) 00209 { 00210 [NSException raise: NSInvalidArgumentException 00211 format: _(@"-[WKWizardPanel setCurrentStage:]: " 00212 @"invalid stage name passed. Stage \"%@\" not in stages list: %@."), 00213 aStageName, stages]; 00214 } 00215 00216 [self setupForStage: aStageName]; 00217 00218 [[NSNotificationCenter defaultCenter] 00219 postNotificationName: WKWizardPanelDidChangeCurrentStageNotification 00220 object: self 00221 userInfo: [NSDictionary dictionaryWithObject: aStageName 00222 forKey: @"Stage"]]; 00223 } 00224 00232 - (NSArray *) currentStage 00233 { 00234 return [stages objectAtIndex: currentStage]; 00235 } 00236 00243 - (void) nextStage: (id) sender 00244 { 00245 if (currentStage + 1 < [stages count]) 00246 { 00247 [self setCurrentStage: [stages objectAtIndex: currentStage + 1]]; 00248 } 00249 } 00250 00257 - (void) previousStage: (id) sender 00258 { 00259 if (currentStage > 0) 00260 { 00261 [self setCurrentStage: [stages objectAtIndex: currentStage - 1]]; 00262 } 00263 } 00264 00281 - (int) activate: (id) sender 00282 { 00283 if (isActive) 00284 { 00285 [NSException raise: NSInternalInconsistencyException 00286 format: _(@"-[WKWizardPanel activate:]: panel " 00287 @"already active.")]; 00288 } 00289 00290 if ([stages count] == 0) 00291 { 00292 [NSException raise: NSInternalInconsistencyException 00293 format: _(@"-[WKWizardPanel activate:]: no stages " 00294 @"set. You must set the panel's stages before activating it.")]; 00295 } 00296 00297 isActive = YES; 00298 00299 if (initialStage != nil) 00300 { 00301 [self setCurrentStage: initialStage]; 00302 } 00303 else 00304 { 00305 [self setCurrentStage: [stages objectAtIndex: 0]]; 00306 } 00307 00308 if (centersBeforeActivating) 00309 { 00310 [self center]; 00311 } 00312 00313 if (runsInModalSession) 00314 { 00315 int code; 00316 00317 code = [NSApp runModalForWindow: self]; 00318 00319 [self close]; 00320 00321 return code; 00322 } 00323 else 00324 { 00325 [self makeKeyAndOrderFront: nil]; 00326 00327 return NSRunStoppedResponse; 00328 } 00329 } 00330 00342 - (void) deactivate: (id) sender 00343 { 00344 if (isActive == NO) 00345 { 00346 [NSException raise: NSInternalInconsistencyException 00347 format: _(@"-[WKWizardPanel deactivate:]: panel " 00348 @"not active.")]; 00349 } 00350 00351 isActive = NO; 00352 00353 if (runsInModalSession) 00354 { 00355 [NSApp stopModal]; 00356 } 00357 else 00358 { 00359 [self close]; 00360 } 00361 } 00362 00372 - (void) deactivateWithCode: (int) code 00373 { 00374 if (isActive == NO) 00375 { 00376 [NSException raise: NSInternalInconsistencyException 00377 format: _(@"-[WKWizardPanel deactivateWithCode:]: " 00378 @"panel not active.")]; 00379 } 00380 00381 if (runsInModalSession == NO) 00382 { 00383 [NSException raise: NSInternalInconsistencyException 00384 format: _(@"-[WKWizardPanel deactivateWithCode]: " 00385 @"panel was not run in modal session. Use \"-deactivate:\" to " 00386 @"deactivate a non-modal panel instead.")]; 00387 } 00388 00389 isActive = NO; 00390 00391 [NSApp stopModalWithCode: code]; 00392 } 00393 00399 - (BOOL) isActive 00400 { 00401 return isActive; 00402 } 00403 00404 // NSCoding protocol 00405 00406 - (void) encodeWithCoder: (NSCoder*) aCoder 00407 { 00408 [super encodeWithCoder: aCoder]; 00409 00410 if ([aCoder allowsKeyedCoding]) 00411 { 00412 [aCoder encodeBool: runsInModalSession 00413 forKey: @"WKRunsInModalSessionFlag"]; 00414 [aCoder encodeBool: runsInModalSession 00415 forKey: @"WKCentersBeforeActivatingFlag"]; 00416 00417 [aCoder encodeObject: stages forKey: @"WKStages"]; 00418 [aCoder encodeObject: initialStage forKey: @"WKInitialStage"]; 00419 } 00420 else 00421 { 00422 [aCoder encodeValueOfObjCType: @encode(BOOL) 00423 at: &runsInModalSession]; 00424 [aCoder encodeValueOfObjCType: @encode(BOOL) 00425 at: ¢ersBeforeActivating]; 00426 00427 [aCoder encodeObject: stages]; 00428 [aCoder encodeObject: initialStage]; 00429 } 00430 } 00431 00432 - (id) initWithCoder: (NSCoder*) aDecoder 00433 { 00434 if ((self = [super initWithCoder: aDecoder]) != nil) 00435 { 00436 if ([aDecoder allowsKeyedCoding]) 00437 { 00438 runsInModalSession = [aDecoder decodeBoolForKey: 00439 @"WKRunsInModalSessionFlag"]; 00440 runsInModalSession = [aDecoder decodeBoolForKey: 00441 @"WKCentersBeforeActivatingFlag"]; 00442 00443 ASSIGN(stages, [aDecoder decodeObjectForKey: @"WKStages"]); 00444 ASSIGN(initialStage, [aDecoder 00445 decodeObjectForKey: @"WKInitialStage"]); 00446 } 00447 else 00448 { 00449 [aDecoder decodeValueOfObjCType: @encode(BOOL) 00450 at: &runsInModalSession]; 00451 [aDecoder decodeValueOfObjCType: @encode(BOOL) 00452 at: ¢ersBeforeActivating]; 00453 00454 ASSIGN(stages, [aDecoder decodeObject]); 00455 ASSIGN(initialStage, [aDecoder decodeObject]); 00456 } 00457 } 00458 00459 return self; 00460 } 00461 00462 @end 00463 00469 @implementation WKWizardPanel (Private) 00470 00476 - (void) setupForStage: (NSString *) aStage 00477 { 00478 [self setContentView: [[self delegate] wizardPanel: self 00479 viewForStage: aStage]]; 00480 [self setInitialFirstResponder: [[self delegate] wizardPanel: self 00481 initialFirstResponderForStage: aStage]]; 00482 } 00483 00484 @end 00485 00490 @implementation NSObject (WKWizardPanelDelegate) 00491 00506 - (NSView *) wizardPanel: (WKWizardPanel *) sender 00507 viewForStage: (NSString *) aStageName 00508 { 00509 [NSException raise: NSInternalInconsistencyException 00510 format: _(@"Wizard delegate %@ didn't override %@."), 00511 [self className], NSStringFromSelector(_cmd)]; 00512 00513 return nil; 00514 } 00515 00525 - (NSView *) wizardPanel: (WKWizardPanel *) sender 00526 initialFirstResponderForStage: (NSString *) aStageName 00527 { 00528 return nil; 00529 } 00530 00531 @end