WizardKit 0.1
WKWizardPanel.m
1/*
2 * WKWizardPanel.m
3 *
4 * Implementation of the WKWizardPanel class for the WizardKit framework
5 *
6 * Copyright (c) 2006, by Saso Kiselkov
7 *
8 * For license details please see the file COPYING included with this
9 * source distribution package.
10 */
11
12#import "WKWizardPanel.h"
13
14#import <Foundation/NSString.h>
15#import <Foundation/NSBundle.h>
16#import <Foundation/NSArray.h>
17#import <Foundation/NSDictionary.h>
18#import <Foundation/NSException.h>
19#import <Foundation/NSNotification.h>
20#import <Foundation/NSCoder.h>
21
22#import <AppKit/NSApplication.h>
23
29NSString * const WKWizardPanelDidChangeCurrentStageNotification
30 = @"WKWizardPanelDidChangeCurrentStageNotification";
31
32@interface WKWizardPanel (Private)
33
34- (void) setupForStage: (NSString *) aStage;
35
36@end
37
63@implementation WKWizardPanel
64
65- (void) dealloc
66{
67 TEST_RELEASE(stages);
68 TEST_RELEASE(initialStage);
69
70 [super dealloc];
71}
72
82- (void) setStages: (NSArray *) someStages
83{
84 if (isActive == YES)
85 {
86 [NSException raise: NSInternalInconsistencyException
87 format: _(@"-[WKWizardPanel setStages:]: panel already "
88 @"active - stages must be set before activating the panel.")];
89 }
90
91 ASSIGNCOPY(stages, someStages);
92 DESTROY(initialStage);
93}
94
102- (NSArray *) stages
103{
104 return stages;
105}
106
115- (void) setRunsInModalSession: (BOOL) flag
116{
117 if (isActive == YES)
118 {
119 [NSException raise: NSInternalInconsistencyException
120 format: _(@"-[WKWizardPanel setRunsInModalSession:] "
121 @"panel already active - modality must be set before activating "
122 @"the panel.")];
123 }
124
125 runsInModalSession = flag;
126}
127
136{
137 return runsInModalSession;
138}
139
146- (void) setInitialStage: (NSString *) aStageName
147{
148 if (aStageName != nil && [stages containsObject: aStageName] == NO)
149 {
150 [NSException raise: NSInvalidArgumentException
151 format: _(@"-[WKWizardPanel setInitialStage:]: "
152 @"invalid stage name passed. Stage \"%@\" not in stages list: %@."),
153 aStageName, stages];
154 }
155
156 ASSIGN(initialStage, aStageName);
157}
158
166- (NSString *) initialStage
167{
168 return initialStage;
169}
170
177- (void) setCentersBeforeActivating: (BOOL) flag
178{
180}
181
193
205- (void) setCurrentStage: (NSString *) aStageName
206{
207 currentStage = [stages indexOfObject: aStageName];
208 if (currentStage == NSNotFound)
209 {
210 [NSException raise: NSInvalidArgumentException
211 format: _(@"-[WKWizardPanel setCurrentStage:]: "
212 @"invalid stage name passed. Stage \"%@\" not in stages list: %@."),
213 aStageName, stages];
214 }
215
216 [self setupForStage: aStageName];
217
218 [[NSNotificationCenter defaultCenter]
219 postNotificationName: WKWizardPanelDidChangeCurrentStageNotification
220 object: self
221 userInfo: [NSDictionary dictionaryWithObject: aStageName
222 forKey: @"Stage"]];
223}
224
232- (NSArray *) currentStage
233{
234 return [stages objectAtIndex: currentStage];
235}
236
243- (void) nextStage: (id) sender
244{
245 if (currentStage + 1 < [stages count])
246 {
247 [self setCurrentStage: [stages objectAtIndex: currentStage + 1]];
248 }
249}
250
257- (void) previousStage: (id) sender
258{
259 if (currentStage > 0)
260 {
261 [self setCurrentStage: [stages objectAtIndex: currentStage - 1]];
262 }
263}
264
281- (int) activate: (id) sender
282{
283 if (isActive)
284 {
285 [NSException raise: NSInternalInconsistencyException
286 format: _(@"-[WKWizardPanel activate:]: panel "
287 @"already active.")];
288 }
289
290 if ([stages count] == 0)
291 {
292 [NSException raise: NSInternalInconsistencyException
293 format: _(@"-[WKWizardPanel activate:]: no stages "
294 @"set. You must set the panel's stages before activating it.")];
295 }
296
297 isActive = YES;
298
299 if (initialStage != nil)
300 {
301 [self setCurrentStage: initialStage];
302 }
303 else
304 {
305 [self setCurrentStage: [stages objectAtIndex: 0]];
306 }
307
309 {
310 [self center];
311 }
312
314 {
315 int code;
316
317 code = [NSApp runModalForWindow: self];
318
319 [self close];
320
321 return code;
322 }
323 else
324 {
325 [self makeKeyAndOrderFront: nil];
326
327 return NSRunStoppedResponse;
328 }
329}
330
342- (void) deactivate: (id) sender
343{
344 if (isActive == NO)
345 {
346 [NSException raise: NSInternalInconsistencyException
347 format: _(@"-[WKWizardPanel deactivate:]: panel "
348 @"not active.")];
349 }
350
351 isActive = NO;
352
354 {
355 [NSApp stopModal];
356 }
357 else
358 {
359 [self close];
360 }
361}
362
372- (void) deactivateWithCode: (int) code
373{
374 if (isActive == NO)
375 {
376 [NSException raise: NSInternalInconsistencyException
377 format: _(@"-[WKWizardPanel deactivateWithCode:]: "
378 @"panel not active.")];
379 }
380
381 if (runsInModalSession == NO)
382 {
383 [NSException raise: NSInternalInconsistencyException
384 format: _(@"-[WKWizardPanel deactivateWithCode]: "
385 @"panel was not run in modal session. Use \"-deactivate:\" to "
386 @"deactivate a non-modal panel instead.")];
387 }
388
389 isActive = NO;
390
391 [NSApp stopModalWithCode: code];
392}
393
399- (BOOL) isActive
400{
401 return isActive;
402}
403
404// NSCoding protocol
405
406- (void) encodeWithCoder: (NSCoder*) aCoder
407{
408 [super encodeWithCoder: aCoder];
409
410 if ([aCoder allowsKeyedCoding])
411 {
412 [aCoder encodeBool: runsInModalSession
413 forKey: @"WKRunsInModalSessionFlag"];
414 [aCoder encodeBool: runsInModalSession
415 forKey: @"WKCentersBeforeActivatingFlag"];
416
417 [aCoder encodeObject: stages forKey: @"WKStages"];
418 [aCoder encodeObject: initialStage forKey: @"WKInitialStage"];
419 }
420 else
421 {
422 [aCoder encodeValueOfObjCType: @encode(BOOL)
423 at: &runsInModalSession];
424 [aCoder encodeValueOfObjCType: @encode(BOOL)
425 at: &centersBeforeActivating];
426
427 [aCoder encodeObject: stages];
428 [aCoder encodeObject: initialStage];
429 }
430}
431
432- (id) initWithCoder: (NSCoder*) aDecoder
433{
434 if ((self = [super initWithCoder: aDecoder]) != nil)
435 {
436 if ([aDecoder allowsKeyedCoding])
437 {
438 runsInModalSession = [aDecoder decodeBoolForKey:
439 @"WKRunsInModalSessionFlag"];
440 runsInModalSession = [aDecoder decodeBoolForKey:
441 @"WKCentersBeforeActivatingFlag"];
442
443 ASSIGN(stages, [aDecoder decodeObjectForKey: @"WKStages"]);
444 ASSIGN(initialStage, [aDecoder
445 decodeObjectForKey: @"WKInitialStage"]);
446 }
447 else
448 {
449 [aDecoder decodeValueOfObjCType: @encode(BOOL)
450 at: &runsInModalSession];
451 [aDecoder decodeValueOfObjCType: @encode(BOOL)
452 at: &centersBeforeActivating];
453
454 ASSIGN(stages, [aDecoder decodeObject]);
455 ASSIGN(initialStage, [aDecoder decodeObject]);
456 }
457 }
458
459 return self;
460}
461
462@end
463
469@implementation WKWizardPanel (Private)
470
476- (void) setupForStage: (NSString *) aStage
477{
478 [self setContentView: [[self delegate] wizardPanel: self
479 viewForStage: aStage]];
480 [self setInitialFirstResponder: [[self delegate] wizardPanel: self
481 initialFirstResponderForStage: aStage]];
482}
483
484@end
485
490@implementation NSObject (WKWizardPanelDelegate)
491
506- (NSView *) wizardPanel: (WKWizardPanel *) sender
507 viewForStage: (NSString *) aStageName
508{
509 [NSException raise: NSInternalInconsistencyException
510 format: _(@"Wizard delegate %@ didn't override %@."),
511 [self className], NSStringFromSelector(_cmd)];
512
513 return nil;
514}
515
525- (NSView *) wizardPanel: (WKWizardPanel *) sender
526 initialFirstResponderForStage: (NSString *) aStageName
527{
528 return nil;
529}
530
531@end
This informal protocol defines what methods the delegate of a wizard panel may or must implement to c...
A wizard panel class.
void setCurrentStage:(NSString *aStageName)
Makes the receiver display a specified stage.
NSString * initialStage
Returns the receiver's initial stage.
unsigned int currentStage
Returns the current stage which the receiver displays.
BOOL isActive
Returns whether the receiver is active or not.
NSArray * stages
Returns a list of stages of the receiver.
BOOL centersBeforeActivating
Returns whether the receiver centers itself before activating.
BOOL runsInModalSession
Returns whether the receiver activates itself in a modal session.