Subversion-Projekte lars-tiefland.prado

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/**
3
 * TWizard and the relevant class definitions.
4
 *
5
 * @author Qiang Xue <qiang.xue@gmail.com>
6
 * @link http://www.pradosoft.com/
7
 * @copyright Copyright &copy; 2005-2008 PradoSoft
8
 * @license http://www.pradosoft.com/license/
9
 * @version $Id: TWizard.php 2541 2008-10-21 15:05:13Z qiang.xue $
10
 * @package System.Web.UI.WebControls
11
 */
12
 
13
Prado::using('System.Web.UI.WebControls.TMultiView');
14
Prado::using('System.Web.UI.WebControls.TPanel');
15
Prado::using('System.Web.UI.WebControls.TButton');
16
Prado::using('System.Web.UI.WebControls.TLinkButton');
17
Prado::using('System.Web.UI.WebControls.TImageButton');
18
Prado::using('System.Web.UI.WebControls.TDataList');
19
Prado::using('System.Web.UI.WebControls.TWizardNavigationButtonStyle');
20
 
21
/**
22
 * Class TWizard.
23
 *
24
 * TWizard splits a large form and presents the user with a series of smaller
25
 * forms to complete. TWizard is analogous to the installation wizard commonly
26
 * used to install software in Windows.
27
 *
28
 * The smaller forms are called wizard steps ({@link TWizardStep}, which can be accessed via
29
 * {@link getWizardSteps WizardSteps}. In template, wizard steps can be added
30
 * into a wizard using the following syntax,
31
 * <code>
32
 *   <com:TWizard>
33
 *      <com:TWizardStep Title="step 1">
34
 *          content in step 1, may contain other controls
35
 *      </com:TWizardStep>
36
 *      <com:TWizardStep Title="step 2">
37
 *          content in step 2, may contain other controls
38
 *      </com:TWizardStep>
39
 *   </com:TWizard>
40
 * </code>
41
 *
42
 * Each wizard step can be one of the following types:
43
 * - Start : the first step in the wizard.
44
 * - Step : the internal steps in the wizard.
45
 * - Finish : the last step that allows user interaction.
46
 * - Complete : the step that shows a summary to user (no interaction is allowed).
47
 * - Auto : the step type is determined by wizard automatically.
48
 * At any time, only one step is visible to end-users, which can be obtained
49
 * by {@link getActiveStep ActiveStep}. Its index in the step collection is given by
50
 * {@link getActiveStepIndex ActiveStepIndex}.
51
 *
52
 * Wizard content can be customized in many ways.
53
 *
54
 * The layout of a wizard consists of four parts: header, step content, navigation
55
 * and side bar. Their content are affected by the following properties, respectively,
56
 * - header: {@link setHeaderText HeaderText} and {@link setHeaderTemplate HeaderTemplate}.
57
 *   If both are present, the latter takes precedence.
58
 * - step: {@link getWizardSteps WizardSteps}.
59
 * - navigation: {@link setStartNavigationTemplate StartNavigationTemplate},
60
 *   {@link setStepNavigationTemplate StepNavigationTemplate},
61
 *   {@link setFinishNavigationTemplate FinishNavigationTemplate}.
62
 *   Default templates will be used if above templates are not set.
63
 * - side bar: {@link setSideBarTemplate SideBarTemplate}.
64
 *   A default template will be used if this template is not set.
65
 *   Its visibility is toggled by {@link setShowSideBar ShowSideBar}.
66
 *
67
 * The style of these wizard layout components can be customized via the following style properties,
68
 * - header: {@link getHeaderStyle HeaderStyle}.
69
 * - step: {@link getStepStyle StepStyle}.
70
 * - navigation: {@link getNavigationStyle NavigationStyle},
71
 *   {@link getStartNextButtonStyle StartNextButtonStyle},
72
 *   {@link getStepNextButtonStyle StepNextButtonStyle},
73
 *   {@link getStepPreviousButtonStyle StepPreviousButtonStyle},
74
 *   {@link getFinishPreviousButtonStyle FinishPreviousButtonStyle},
75
 *   {@link getFinishCompleteButtonStyle FinishCompleteButtonStyle},
76
 *   {@link getCancelButtonStyle CancelButtonStyle}.
77
 * - side bar: {@link getSideBarStyle SideBarStyle} and {@link getSideBarButtonStyle SideBarButtonStyle}.
78
 *
79
 * @author Qiang Xue <qiang.xue@gmail.com>
80
 * @version $Id: TWizard.php 2541 2008-10-21 15:05:13Z qiang.xue $
81
 * @package System.Web.UI.WebControls
82
 * @since 3.0
83
 */
84
class TWizard extends TWebControl implements INamingContainer
85
{
86
	/**
87
	 * Wizard step types.
88
	 * @deprecated deprecated since version 3.0.4 (use TWizardStepType constants instead)
89
	 */
90
	const ST_AUTO='Auto';
91
	const ST_START='Start';
92
	const ST_STEP='Step';
93
	const ST_FINISH='Finish';
94
	const ST_COMPLETE='Complete';
95
	/**
96
	 * Navigation commands.
97
	 */
98
	const CMD_PREVIOUS='PreviousStep';
99
	const CMD_NEXT='NextStep';
100
	const CMD_CANCEL='Cancel';
101
	const CMD_COMPLETE='Complete';
102
	const CMD_MOVETO='MoveTo';
103
	/**
104
	 * Side bar button ID
105
	 */
106
	const ID_SIDEBAR_BUTTON='SideBarButton';
107
	/**
108
	 * Side bar data list
109
	 */
110
	const ID_SIDEBAR_LIST='SideBarList';
111
 
112
	/**
113
	 * @var TMultiView multiview that contains the wizard steps
114
	 */
115
	private $_multiView=null;
116
	/**
117
	 * @var mixed navigation template for the start step.
118
	 */
119
	private $_startNavigationTemplate=null;
120
	/**
121
	 * @var mixed navigation template for internal steps.
122
	 */
123
	private $_stepNavigationTemplate=null;
124
	/**
125
	 * @var mixed navigation template for the finish step.
126
	 */
127
	private $_finishNavigationTemplate=null;
128
	/**
129
	 * @var mixed template for wizard header.
130
	 */
131
	private $_headerTemplate=null;
132
	/**
133
	 * @var mixed template for the side bar.
134
	 */
135
	private $_sideBarTemplate=null;
136
	/**
137
	 * @var TWizardStepCollection
138
	 */
139
	private $_wizardSteps=null;
140
	/**
141
	 * @var TPanel container of the wizard header
142
	 */
143
	private $_header;
144
	/**
145
	 * @var TPanel container of the wizard step content
146
	 */
147
	private $_stepContent;
148
	/**
149
	 * @var TPanel container of the wizard side bar
150
	 */
151
	private $_sideBar;
152
	/**
153
	 * @var TPanel navigation panel
154
	 */
155
	private $_navigation;
156
	/**
157
	 * @var TWizardNavigationContainer container of the start navigation
158
	 */
159
	private $_startNavigation;
160
	/**
161
	 * @var TWizardNavigationContainer container of the step navigation
162
	 */
163
	private $_stepNavigation;
164
	/**
165
	 * @var TWizardNavigationContainer container of the finish navigation
166
	 */
167
	private $_finishNavigation;
168
	/**
169
	 * @var boolean whether ActiveStepIndex was already set
170
	 */
171
	private $_activeStepIndexSet=false;
172
	/**
173
	 * @var TDataList side bar data list.
174
	 */
175
	private $_sideBarDataList;
176
	/**
177
	 * @var boolean whether navigation should be cancelled (a status set in OnSideBarButtonClick)
178
	 */
179
	private $_cancelNavigation=false;
180
 
181
	/**
182
	 * @return string tag name for the wizard
183
	 */
184
	protected function getTagName()
185
	{
186
		return 'div';
187
	}
188
 
189
	/**
190
	 * Adds {@link TWizardStep} objects into step collection.
191
	 * This method overrides the parent implementation and is
192
	 * invoked when template is being instantiated.
193
	 * @param mixed object instantiated in template
194
	 */
195
	public function addParsedObject($object)
196
	{
197
		if($object instanceof TWizardStep)
198
			$this->getWizardSteps()->add($object);
199
	}
200
 
201
	/**
202
	 * @return TWizardStep the currently active wizard step
203
	 */
204
	public function getActiveStep()
205
	{
206
		return $this->getMultiView()->getActiveView();
207
	}
208
 
209
	/**
210
	 * @param TWizardStep step to be activated
211
	 * @throws TInvalidOperationException if the step is not in the wizard step collection
212
	 */
213
	public function setActiveStep($step)
214
	{
215
		if(($index=$this->getWizardSteps()->indexOf($step))<0)
216
			throw new TInvalidOperationException('wizard_step_invalid');
217
		$this->setActiveStepIndex($index);
218
	}
219
 
220
	/**
221
	 * @return integer the zero-based index of the active wizard step
222
	 */
223
	public function getActiveStepIndex()
224
	{
225
		return $this->getMultiView()->getActiveViewIndex();
226
	}
227
 
228
	/**
229
	 * @param integer the zero-based index of the wizard step to be activated
230
	 */
231
	public function setActiveStepIndex($value)
232
	{
233
		$value=TPropertyValue::ensureInteger($value);
234
		$multiView=$this->getMultiView();
235
		if($multiView->getActiveViewIndex()!==$value)
236
		{
237
			$multiView->setActiveViewIndex($value);
238
			$this->_activeStepIndexSet=true;
239
			if($this->_sideBarDataList!==null && $this->getSideBarTemplate()!==null)
240
			{
241
				$this->_sideBarDataList->setSelectedItemIndex($this->getActiveStepIndex());
242
				$this->_sideBarDataList->dataBind();
243
			}
244
		}
245
	}
246
 
247
	/**
248
	 * @return TWizardStepCollection collection of wizard steps
249
	 */
250
	public function getWizardSteps()
251
	{
252
		if($this->_wizardSteps===null)
253
			$this->_wizardSteps=new TWizardStepCollection($this);
254
		return $this->_wizardSteps;
255
	}
256
 
257
	/**
258
	 * @return boolean whether to display a cancel button in each wizard step. Defaults to false.
259
	 */
260
	public function getShowCancelButton()
261
	{
262
		return $this->getViewState('ShowCancelButton',false);
263
	}
264
 
265
	/**
266
	 * @param boolean whether to display a cancel button in each wizard step.
267
	 */
268
	public function setShowCancelButton($value)
269
	{
270
		$this->setViewState('ShowCancelButton',TPropertyValue::ensureBoolean($value),false);
271
	}
272
 
273
	/**
274
	 * @return boolean whether to display a side bar that contains links to wizard steps. Defaults to true.
275
	 */
276
	public function getShowSideBar()
277
	{
278
		return $this->getViewState('ShowSideBar',true);
279
	}
280
 
281
	/**
282
	 * @param boolean whether to display a side bar that contains links to wizard steps.
283
	 */
284
	public function setShowSideBar($value)
285
	{
286
		$this->setViewState('ShowSideBar',TPropertyValue::ensureBoolean($value),true);
287
		$this->requiresControlsRecreation();
288
	}
289
 
290
	/**
291
	 * @return ITemplate navigation template for the start step. Defaults to null.
292
	 */
293
	public function getStartNavigationTemplate()
294
	{
295
		return $this->_startNavigationTemplate;
296
	}
297
 
298
	/**
299
	 * @param ITemplate navigation template for the start step.
300
	 */
301
	public function setStartNavigationTemplate($value)
302
	{
303
		$this->_startNavigationTemplate=$value;
304
		$this->requiresControlsRecreation();
305
	}
306
 
307
	/**
308
	 * @return ITemplate navigation template for internal steps. Defaults to null.
309
	 */
310
	public function getStepNavigationTemplate()
311
	{
312
		return $this->_stepNavigationTemplate;
313
	}
314
 
315
	/**
316
	 * @param ITemplate navigation template for internal steps.
317
	 */
318
	public function setStepNavigationTemplate($value)
319
	{
320
		$this->_stepNavigationTemplate=$value;
321
		$this->requiresControlsRecreation();
322
	}
323
 
324
	/**
325
	 * @return ITemplate navigation template for the finish step. Defaults to null.
326
	 */
327
	public function getFinishNavigationTemplate()
328
	{
329
		return $this->_finishNavigationTemplate;
330
	}
331
 
332
	/**
333
	 * @param ITemplate navigation template for the finish step.
334
	 */
335
	public function setFinishNavigationTemplate($value)
336
	{
337
		$this->_finishNavigationTemplate=$value;
338
		$this->requiresControlsRecreation();
339
	}
340
 
341
	/**
342
	 * @return ITemplate template for wizard header. Defaults to null.
343
	 */
344
	public function getHeaderTemplate()
345
	{
346
		return $this->_headerTemplate;
347
	}
348
 
349
	/**
350
	 * @param ITemplate template for wizard header.
351
	 */
352
	public function setHeaderTemplate($value)
353
	{
354
		$this->_headerTemplate=$value;
355
		$this->requiresControlsRecreation();
356
	}
357
 
358
	/**
359
	 * @return ITemplate template for the side bar. Defaults to null.
360
	 */
361
	public function getSideBarTemplate()
362
	{
363
		return $this->_sideBarTemplate;
364
	}
365
 
366
	/**
367
	 * @param ITemplate template for the side bar.
368
	 */
369
	public function setSideBarTemplate($value)
370
	{
371
		$this->_sideBarTemplate=$value;
372
		$this->requiresControlsRecreation();
373
	}
374
 
375
	/**
376
	 * @return string header text. Defaults to ''.
377
	 */
378
	public function getHeaderText()
379
	{
380
		return $this->getViewState('HeaderText','');
381
	}
382
 
383
	/**
384
	 * @param string header text.
385
	 */
386
	public function setHeaderText($value)
387
	{
388
		$this->setViewState('HeaderText',TPropertyValue::ensureString($value),'');
389
	}
390
 
391
	/**
392
	 * @return string the URL that the browser will be redirected to if the cancel button in the
393
	 * wizard is clicked. Defaults to ''.
394
	 */
395
	public function getCancelDestinationUrl()
396
	{
397
		return $this->getViewState('CancelDestinationUrl','');
398
	}
399
 
400
	/**
401
	 * @param string the URL that the browser will be redirected to if the cancel button in the
402
	 * wizard is clicked.
403
	 */
404
	public function setCancelDestinationUrl($value)
405
	{
406
		$this->setViewState('CancelDestinationUrl',TPropertyValue::ensureString($value),'');
407
	}
408
 
409
	/**
410
	 * @return string the URL that the browser will be redirected to if the wizard finishes.
411
	 * Defaults to ''.
412
	 */
413
	public function getFinishDestinationUrl()
414
	{
415
		return $this->getViewState('FinishDestinationUrl','');
416
	}
417
 
418
	/**
419
	 * @param string the URL that the browser will be redirected to if the wizard finishes.
420
	 */
421
	public function setFinishDestinationUrl($value)
422
	{
423
		$this->setViewState('FinishDestinationUrl',TPropertyValue::ensureString($value),'');
424
	}
425
 
426
	/**
427
	 * @return TStyle the style for the buttons displayed in the side bar.
428
	 */
429
	public function getSideBarButtonStyle()
430
	{
431
		if(($style=$this->getViewState('SideBarButtonStyle',null))===null)
432
		{
433
			$style=new TStyle;
434
			$this->setViewState('SideBarButtonStyle',$style,null);
435
		}
436
		return $style;
437
	}
438
 
439
	/**
440
	 * @return TStyle the style common for all navigation buttons.
441
	 */
442
	public function getNavigationButtonStyle()
443
	{
444
		if(($style=$this->getViewState('NavigationButtonStyle',null))===null)
445
		{
446
			$style=new TStyle;
447
			$this->setViewState('NavigationButtonStyle',$style,null);
448
		}
449
		return $style;
450
	}
451
 
452
	/**
453
	 * @return TWizardNavigationButtonStyle the style for the next button in the start wizard step.
454
	 */
455
	public function getStartNextButtonStyle()
456
	{
457
		if(($style=$this->getViewState('StartNextButtonStyle',null))===null)
458
		{
459
			$style=new TWizardNavigationButtonStyle;
460
			$style->setButtonText('Next');
461
			$this->setViewState('StartNextButtonStyle',$style,null);
462
		}
463
		return $style;
464
	}
465
 
466
	/**
467
	 * @return TWizardNavigationButtonStyle the style for the next button in each internal wizard step.
468
	 */
469
	public function getStepNextButtonStyle()
470
	{
471
		if(($style=$this->getViewState('StepNextButtonStyle',null))===null)
472
		{
473
			$style=new TWizardNavigationButtonStyle;
474
			$style->setButtonText('Next');
475
			$this->setViewState('StepNextButtonStyle',$style,null);
476
		}
477
		return $style;
478
	}
479
 
480
	/**
481
	 * @return TWizardNavigationButtonStyle the style for the previous button in the start wizard step.
482
	 */
483
	public function getStepPreviousButtonStyle()
484
	{
485
		if(($style=$this->getViewState('StepPreviousButtonStyle',null))===null)
486
		{
487
			$style=new TWizardNavigationButtonStyle;
488
			$style->setButtonText('Previous');
489
			$this->setViewState('StepPreviousButtonStyle',$style,null);
490
		}
491
		return $style;
492
	}
493
 
494
	/**
495
	 * @return TWizardNavigationButtonStyle the style for the complete button in the finish wizard step.
496
	 */
497
	public function getFinishCompleteButtonStyle()
498
	{
499
		if(($style=$this->getViewState('FinishCompleteButtonStyle',null))===null)
500
		{
501
			$style=new TWizardNavigationButtonStyle;
502
			$style->setButtonText('Complete');
503
			$this->setViewState('FinishCompleteButtonStyle',$style,null);
504
		}
505
		return $style;
506
	}
507
 
508
	/**
509
	 * @return TWizardNavigationButtonStyle the style for the previous button in the start wizard step.
510
	 */
511
	public function getFinishPreviousButtonStyle()
512
	{
513
		if(($style=$this->getViewState('FinishPreviousButtonStyle',null))===null)
514
		{
515
			$style=new TWizardNavigationButtonStyle;
516
			$style->setButtonText('Previous');
517
			$this->setViewState('FinishPreviousButtonStyle',$style,null);
518
		}
519
		return $style;
520
	}
521
 
522
	/**
523
	 * @return TWizardNavigationButtonStyle the style for the cancel button
524
	 */
525
	public function getCancelButtonStyle()
526
	{
527
		if(($style=$this->getViewState('CancelButtonStyle',null))===null)
528
		{
529
			$style=new TWizardNavigationButtonStyle;
530
			$style->setButtonText('Cancel');
531
			$this->setViewState('CancelButtonStyle',$style,null);
532
		}
533
		return $style;
534
	}
535
 
536
	/**
537
	 * @return TPanelStyle the style for the side bar.
538
	 */
539
	public function getSideBarStyle()
540
	{
541
		if(($style=$this->getViewState('SideBarStyle',null))===null)
542
		{
543
			$style=new TPanelStyle;
544
			$this->setViewState('SideBarStyle',$style,null);
545
		}
546
		return $style;
547
	}
548
 
549
	/**
550
	 * @return TPanelStyle the style for the header.
551
	 */
552
	public function getHeaderStyle()
553
	{
554
		if(($style=$this->getViewState('HeaderStyle',null))===null)
555
		{
556
			$style=new TPanelStyle;
557
			$this->setViewState('HeaderStyle',$style,null);
558
		}
559
		return $style;
560
	}
561
 
562
	/**
563
	 * @return TPanelStyle the style for each internal wizard step.
564
	 */
565
	public function getStepStyle()
566
	{
567
		if(($style=$this->getViewState('StepStyle',null))===null)
568
		{
569
			$style=new TPanelStyle;
570
			$this->setViewState('StepStyle',$style,null);
571
		}
572
		return $style;
573
	}
574
 
575
	/**
576
	 * @return TPanelStyle the style for the navigation panel.
577
	 */
578
	public function getNavigationStyle()
579
	{
580
		if(($style=$this->getViewState('NavigationStyle',null))===null)
581
		{
582
			$style=new TPanelStyle;
583
			$this->setViewState('NavigationStyle',$style,null);
584
		}
585
		return $style;
586
	}
587
 
588
	/**
589
	 * @return boolean whether to use default layout to arrange side bar and the rest wizard components. Defaults to true.
590
	 */
591
	public function getUseDefaultLayout()
592
	{
593
		return $this->getViewState('UseDefaultLayout',true);
594
	}
595
 
596
	/**
597
	 * @param boolean whether to use default layout to arrange side bar and the rest wizard components.
598
	 * If true, an HTML table will be used which places the side bar in the left cell
599
	 * while the rest components in the right cell.
600
	 */
601
	public function setUseDefaultLayout($value)
602
	{
603
		$this->setViewState('UseDefaultLayout',TPropertyValue::ensureBoolean($value),true);
604
	}
605
 
606
	/**
607
	 * @return TPanel container of the wizard header
608
	 */
609
	public function getHeader()
610
	{
611
		return $this->_header;
612
	}
613
 
614
	/**
615
	 * @return TPanel container of the wizard step content
616
	 */
617
	public function getStepContent()
618
	{
619
		return $this->_stepContent;
620
	}
621
 
622
	/**
623
	 * @return TPanel container of the wizard side bar
624
	 */
625
	public function getSideBar()
626
	{
627
		return $this->_sideBar;
628
	}
629
 
630
	/**
631
	 * @return TWizardNavigationContainer container of the start navigation
632
	 */
633
	public function getStartNavigation()
634
	{
635
		return $this->_startNavigation;
636
	}
637
 
638
	/**
639
	 * @return TWizardNavigationContainer container of the step navigation
640
	 */
641
	public function getStepNavigation()
642
	{
643
		return $this->_stepNavigation;
644
	}
645
 
646
	/**
647
	 * @return TWizardNavigationContainer container of the finish navigation
648
	 */
649
	public function getFinishNavigation()
650
	{
651
		return $this->_finishNavigation;
652
	}
653
 
654
	/**
655
	 * Raises <b>OnActiveStepChanged</b> event.
656
	 * This event is raised when the current visible step is changed in the
657
	 * wizard.
658
	 * @param TEventParameter event parameter
659
	 */
660
	public function onActiveStepChanged($param)
661
	{
662
		$this->raiseEvent('OnActiveStepChanged',$this,$param);
663
	}
664
 
665
	/**
666
	 * Raises <b>OnCancelButtonClick</b> event.
667
	 * This event is raised when a cancel navigation button is clicked in the
668
	 * current active step.
669
	 * @param TEventParameter event parameter
670
	 */
671
	public function onCancelButtonClick($param)
672
	{
673
		$this->raiseEvent('OnCancelButtonClick',$this,$param);
674
		if(($url=$this->getCancelDestinationUrl())!=='')
675
			$this->getResponse()->redirect($url);
676
	}
677
 
678
	/**
679
	 * Raises <b>OnCompleteButtonClick</b> event.
680
	 * This event is raised when a finish navigation button is clicked in the
681
	 * current active step.
682
	 * @param TWizardNavigationEventParameter event parameter
683
	 */
684
	public function onCompleteButtonClick($param)
685
	{
686
		$this->raiseEvent('OnCompleteButtonClick',$this,$param);
687
		if(($url=$this->getFinishDestinationUrl())!=='')
688
			$this->getResponse()->redirect($url);
689
	}
690
 
691
	/**
692
	 * Raises <b>OnNextButtonClick</b> event.
693
	 * This event is raised when a next navigation button is clicked in the
694
	 * current active step.
695
	 * @param TWizardNavigationEventParameter event parameter
696
	 */
697
	public function onNextButtonClick($param)
698
	{
699
		$this->raiseEvent('OnNextButtonClick',$this,$param);
700
	}
701
 
702
	/**
703
	 * Raises <b>OnPreviousButtonClick</b> event.
704
	 * This event is raised when a previous navigation button is clicked in the
705
	 * current active step.
706
	 * @param TWizardNavigationEventParameter event parameter
707
	 */
708
	public function onPreviousButtonClick($param)
709
	{
710
		$this->raiseEvent('OnPreviousButtonClick',$this,$param);
711
	}
712
 
713
	/**
714
	 * Raises <b>OnSideBarButtonClick</b> event.
715
	 * This event is raised when a link button in the side bar is clicked.
716
	 * @param TWizardNavigationEventParameter event parameter
717
	 */
718
	public function onSideBarButtonClick($param)
719
	{
720
		$this->raiseEvent('OnSideBarButtonClick',$this,$param);
721
	}
722
 
723
	/**
724
	 * Returns the multiview that holds the wizard steps.
725
	 * This method should only be used by control developers.
726
	 * @return TMultiView the multiview holding wizard steps
727
	 */
728
	public function getMultiView()
729
	{
730
		if($this->_multiView===null)
731
		{
732
			$this->_multiView=new TMultiView;
733
			$this->_multiView->setID('WizardMultiView');
734
			$this->_multiView->attachEventHandler('OnActiveViewChanged',array($this,'onActiveStepChanged'));
735
			$this->_multiView->ignoreBubbleEvents();
736
		}
737
		return $this->_multiView;
738
	}
739
 
740
	/**
741
	 * Adds a wizard step to the multiview.
742
	 * This method should only be used by control developers.
743
	 * It is invoked when a step is added into the step collection of the wizard.
744
	 * @param TWizardStep wizard step to be added into multiview.
745
	 */
746
	public function addedWizardStep($step)
747
	{
748
		if(($wizard=$step->getWizard())!==null)
749
			$wizard->getWizardSteps()->remove($step);
750
		$step->setWizard($this);
751
		$this->wizardStepsChanged();
752
	}
753
 
754
	/**
755
	 * Removes a wizard step from the multiview.
756
	 * This method should only be used by control developers.
757
	 * It is invoked when a step is removed from the step collection of the wizard.
758
	 * @param TWizardStep wizard step to be removed from multiview.
759
	 */
760
	public function removedWizardStep($step)
761
	{
762
		$step->setWizard(null);
763
		$this->wizardStepsChanged();
764
	}
765
 
766
	/**
767
	 * Creates the child controls of the wizard.
768
	 * This method overrides the parent implementation.
769
	 * @param TEventParameter event parameter
770
	 */
771
	public function onInit($param)
772
	{
773
		parent::onInit($param);
774
		$this->ensureChildControls();
775
		if($this->getActiveStepIndex()<0 && $this->getWizardSteps()->getCount()>0)
776
			$this->setActiveStepIndex(0);
777
	}
778
 
779
	/**
780
	 * Saves the current active step index into history.
781
	 * This method is invoked by the framework when the control state is being saved.
782
	 */
783
	public function saveState()
784
	{
785
		$index=$this->getActiveStepIndex();
786
		$history=$this->getHistory();
787
		if(!$history->getCount() || $history->peek()!==$index)
788
			$history->push($index);
789
	}
790
 
791
	/**
792
	 * Indicates the wizard needs to recreate all child controls.
793
	 */
794
	protected function requiresControlsRecreation()
795
	{
796
		if($this->getChildControlsCreated())
797
			$this->setChildControlsCreated(false);
798
	}
799
 
800
	/**
801
	 * Renders the wizard.
802
	 * @param THtmlWriter
803
	 */
804
	public function render($writer)
805
	{
806
		$this->ensureChildControls();
807
		if($this->getHasControls())
808
		{
809
			if($this->getUseDefaultLayout())
810
			{
811
				$this->applyControlProperties();
812
				$this->renderBeginTag($writer);
813
				$writer->write("\n<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" height=\"100%\" width=\"100%\">\n<tr><td width=\"1\" valign=\"top\">\n");
814
				$this->_sideBar->renderControl($writer);
815
				$writer->write("\n</td><td valign=\"top\">\n");
816
				$this->_header->renderControl($writer);
817
				$this->_stepContent->renderControl($writer);
818
				$this->_navigation->renderControl($writer);
819
				$writer->write("\n</td></tr></table>\n");
820
				$this->renderEndTag($writer);
821
			}
822
			else
823
			{
824
				$this->applyControlProperties();
825
				$this->renderBeginTag($writer);
826
				$this->_sideBar->renderControl($writer);
827
				$this->_header->renderControl($writer);
828
				$this->_stepContent->renderControl($writer);
829
				$this->_navigation->renderControl($writer);
830
				$this->renderEndTag($writer);
831
			}
832
		}
833
	}
834
 
835
	/**
836
	 * Applies various properties to the components of wizard
837
	 */
838
	protected function applyControlProperties()
839
	{
840
		$this->applyHeaderProperties();
841
		$this->applySideBarProperties();
842
		$this->applyStepContentProperties();
843
		$this->applyNavigationProperties();
844
	}
845
 
846
	/**
847
	 * Applies properties to the wizard header
848
	 */
849
	protected function applyHeaderProperties()
850
	{
851
		if(($style=$this->getViewState('HeaderStyle',null))!==null)
852
			$this->_header->getStyle()->mergeWith($style);
853
		if($this->getHeaderTemplate()===null)
854
		{
855
			$this->_header->getControls()->clear();
856
			$this->_header->getControls()->add($this->getHeaderText());
857
		}
858
	}
859
 
860
	/**
861
	 * Applies properties to the wizard sidebar
862
	 */
863
	protected function applySideBarProperties()
864
	{
865
		$this->_sideBar->setVisible($this->getShowSideBar());
866
		if($this->_sideBarDataList!==null && $this->getShowSideBar())
867
		{
868
			$this->_sideBarDataList->setDataSource($this->getWizardSteps());
869
			$this->_sideBarDataList->setSelectedItemIndex($this->getActiveStepIndex());
870
			$this->_sideBarDataList->dataBind();
871
			if(($style=$this->getViewState('SideBarButtonStyle',null))!==null)
872
			{
873
				foreach($this->_sideBarDataList->getItems() as $item)
874
				{
875
					if(($button=$item->findControl('SideBarButton'))!==null)
876
						$button->getStyle()->mergeWith($style);
877
				}
878
			}
879
		}
880
		if(($style=$this->getViewState('SideBarStyle',null))!==null)
881
			$this->_sideBar->getStyle()->mergeWith($style);
882
	}
883
 
884
	/**
885
	 * Applies properties to the wizard step content
886
	 */
887
	protected function applyStepContentProperties()
888
	{
889
		if(($style=$this->getViewState('StepStyle',null))!==null)
890
			$this->_stepContent->getStyle()->mergeWith($style);
891
	}
892
 
893
	/**
894
	 * Apply properties to various navigation panels.
895
	 */
896
	protected function applyNavigationProperties()
897
	{
898
		$wizardSteps=$this->getWizardSteps();
899
		$activeStep=$this->getActiveStep();
900
		$activeStepIndex=$this->getActiveStepIndex();
901
 
902
		if(!$this->_navigation)
903
			return;
904
		else if($activeStepIndex<0 || $activeStepIndex>=$wizardSteps->getCount())
905
		{
906
			$this->_navigation->setVisible(false);
907
			return;
908
		}
909
 
910
		// set visibility of different types of navigation panel
911
		$showStandard=true;
912
		foreach($wizardSteps as $step)
913
		{
914
			if(($step instanceof TTemplatedWizardStep) && ($container=$step->getNavigationContainer())!==null)
915
			{
916
				if($activeStep===$step)
917
				{
918
					$container->setVisible(true);
919
					$showStandard=false;
920
				}
921
				else
922
					$container->setVisible(false);
923
			}
924
		}
925
		$activeStepType=$this->getStepType($activeStep);
926
		if($activeStepType===TWizardStepType::Complete)
927
		{
928
			$this->_sideBar->setVisible(false);
929
			$this->_header->setVisible(false);
930
		}
931
		$this->_startNavigation->setVisible($showStandard && $activeStepType===self::ST_START);
932
		$this->_stepNavigation->setVisible($showStandard && $activeStepType===self::ST_STEP);
933
		$this->_finishNavigation->setVisible($showStandard && $activeStepType===self::ST_FINISH);
934
 
935
		if(($navigationStyle=$this->getViewState('NavigationStyle',null))!==null)
936
			$this->_navigation->getStyle()->mergeWith($navigationStyle);
937
 
938
		$displayCancelButton=$this->getShowCancelButton();
939
		$cancelButtonStyle=$this->getCancelButtonStyle();
940
		$buttonStyle=$this->getViewState('NavigationButtonStyle',null);
941
		if($buttonStyle!==null)
942
			$cancelButtonStyle->mergeWith($buttonStyle);
943
 
944
		// apply styles to start navigation buttons
945
		if(($cancelButton=$this->_startNavigation->getCancelButton())!==null)
946
		{
947
			$cancelButton->setVisible($displayCancelButton);
948
			$cancelButtonStyle->apply($cancelButton);
949
		}
950
		if(($button=$this->_startNavigation->getNextButton())!==null)
951
		{
952
			$button->setVisible(true);
953
			$style=$this->getStartNextButtonStyle();
954
			if($buttonStyle!==null)
955
				$style->mergeWith($buttonStyle);
956
			$style->apply($button);
957
		}
958
 
959
		// apply styles to finish navigation buttons
960
		if(($cancelButton=$this->_finishNavigation->getCancelButton())!==null)
961
		{
962
			$cancelButton->setVisible($displayCancelButton);
963
			$cancelButtonStyle->apply($cancelButton);
964
		}
965
		if(($button=$this->_finishNavigation->getPreviousButton())!==null)
966
		{
967
			$button->setVisible($this->allowNavigationToPreviousStep());
968
			$style=$this->getFinishPreviousButtonStyle();
969
			if($buttonStyle!==null)
970
				$style->mergeWith($buttonStyle);
971
			$style->apply($button);
972
		}
973
		if(($button=$this->_finishNavigation->getCompleteButton())!==null)
974
		{
975
			$button->setVisible(true);
976
			$style=$this->getFinishCompleteButtonStyle();
977
			if($buttonStyle!==null)
978
				$style->mergeWith($buttonStyle);
979
			$style->apply($button);
980
		}
981
 
982
		// apply styles to step navigation buttons
983
		if(($cancelButton=$this->_stepNavigation->getCancelButton())!==null)
984
		{
985
			$cancelButton->setVisible($displayCancelButton);
986
			$cancelButtonStyle->apply($cancelButton);
987
		}
988
		if(($button=$this->_stepNavigation->getPreviousButton())!==null)
989
		{
990
			$button->setVisible($this->allowNavigationToPreviousStep());
991
			$style=$this->getStepPreviousButtonStyle();
992
			if($buttonStyle!==null)
993
				$style->mergeWith($buttonStyle);
994
			$style->apply($button);
995
		}
996
		if(($button=$this->_stepNavigation->getNextButton())!==null)
997
		{
998
			$button->setVisible(true);
999
			$style=$this->getStepNextButtonStyle();
1000
			if($buttonStyle!==null)
1001
				$style->mergeWith($buttonStyle);
1002
			$style->apply($button);
1003
		}
1004
	}
1005
 
1006
	/**
1007
	 * @return TStack history containing step indexes that were navigated before
1008
	 */
1009
	protected function getHistory()
1010
	{
1011
		if(($history=$this->getControlState('History',null))===null)
1012
		{
1013
			$history=new TStack;
1014
			$this->setControlState('History',$history);
1015
		}
1016
		return $history;
1017
	}
1018
 
1019
	/**
1020
	 * Determines the type of the specified wizard step.
1021
	 * @param TWizardStep
1022
	 * @return TWizardStepType type of the step
1023
	 */
1024
	protected function getStepType($wizardStep)
1025
	{
1026
		if(($type=$wizardStep->getStepType())===TWizardStepType::Auto)
1027
		{
1028
			$steps=$this->getWizardSteps();
1029
			if(($index=$steps->indexOf($wizardStep))>=0)
1030
			{
1031
				$stepCount=$steps->getCount();
1032
				if($stepCount===1 || ($index<$stepCount-1 && $steps->itemAt($index+1)->getStepType()===TWizardStepType::Complete))
1033
					return TWizardStepType::Finish;
1034
				else if($index===0)
1035
					return TWizardStepType::Start;
1036
				else if($index===$stepCount-1)
1037
					return TWizardStepType::Finish;
1038
				else
1039
					return TWizardStepType::Step;
1040
			}
1041
			else
1042
				return $type;
1043
		}
1044
		else
1045
			return $type;
1046
	}
1047
 
1048
	/**
1049
	 * Clears up everything within the wizard.
1050
	 */
1051
	protected function reset()
1052
	{
1053
		$this->getControls()->clear();
1054
		$this->_header=null;
1055
		$this->_stepContent=null;
1056
		$this->_sideBar=null;
1057
		$this->_sideBarDataList=null;
1058
		$this->_navigation=null;
1059
		$this->_startNavigation=null;
1060
		$this->_stepNavigation=null;
1061
		$this->_finishNavigation=null;
1062
	}
1063
 
1064
	/**
1065
	 * Creates child controls within the wizard
1066
	 */
1067
	public function createChildControls()
1068
	{
1069
		$this->reset();
1070
		$this->createSideBar();
1071
		$this->createHeader();
1072
		$this->createStepContent();
1073
		$this->createNavigation();
1074
//		$this->clearChildState();
1075
	}
1076
 
1077
	/**
1078
	 * Creates the wizard header.
1079
	 */
1080
	protected function createHeader()
1081
	{
1082
		$this->_header=new TPanel;
1083
		if(($template=$this->getHeaderTemplate())!==null)
1084
			$template->instantiateIn($this->_header);
1085
		else
1086
			$this->_header->getControls()->add($this->getHeaderText());
1087
		$this->getControls()->add($this->_header);
1088
	}
1089
 
1090
	/**
1091
	 * Creates the wizard side bar
1092
	 */
1093
	protected function createSideBar()
1094
	{
1095
		if($this->getShowSideBar())
1096
		{
1097
			if(($template=$this->getSideBarTemplate())===null)
1098
				$template=new TWizardSideBarTemplate;
1099
			$this->_sideBar=new TPanel;
1100
			$template->instantiateIn($this->_sideBar);
1101
			$this->getControls()->add($this->_sideBar);
1102
 
1103
			if(($this->_sideBarDataList=$this->_sideBar->findControl(self::ID_SIDEBAR_LIST))!==null)
1104
			{
1105
				$this->_sideBarDataList->attachEventHandler('OnItemCommand',array($this,'dataListItemCommand'));
1106
				$this->_sideBarDataList->attachEventHandler('OnItemDataBound',array($this,'dataListItemDataBound'));
1107
				$this->_sideBarDataList->setDataSource($this->getWizardSteps());
1108
				$this->_sideBarDataList->setSelectedItemIndex($this->getActiveStepIndex());
1109
				$this->_sideBarDataList->dataBind();
1110
			}
1111
		}
1112
		else
1113
		{
1114
			$this->_sideBar=new TPanel;
1115
			$this->getControls()->add($this->_sideBar);
1116
		}
1117
	}
1118
 
1119
	/**
1120
	 * Event handler for sidebar datalist's OnItemCommand event.
1121
	 * This method is used internally by wizard. It mainly
1122
	 * sets the active step index according to the button clicked in the sidebar.
1123
	 * @param mixed sender of the event
1124
	 * @param TDataListCommandEventParameter
1125
	 */
1126
	public function dataListItemCommand($sender,$param)
1127
	{
1128
		$item=$param->getItem();
1129
		if($param->getCommandName()===self::CMD_MOVETO)
1130
		{
1131
			$stepIndex=$this->getActiveStepIndex();
1132
			$newStepIndex=TPropertyValue::ensureInteger($param->getCommandParameter());
1133
			$navParam=new TWizardNavigationEventParameter($stepIndex);
1134
			$navParam->setNextStepIndex($newStepIndex);
1135
 
1136
			// if the button clicked causes validation which fails,
1137
			// by default we will cancel navigation to the new step
1138
			$button=$param->getCommandSource();
1139
			if(($button instanceof IButtonControl) && $button->getCausesValidation() && ($page=$this->getPage())!==null && !$page->getIsValid())
1140
				$navParam->setCancelNavigation(true);
1141
 
1142
			$this->_activeStepIndexSet=false;
1143
			$this->onSideBarButtonClick($navParam);
1144
			$this->_cancelNavigation=$navParam->getCancelNavigation();
1145
			if(!$this->_cancelNavigation)
1146
			{
1147
				if(!$this->_activeStepIndexSet && $this->allowNavigationToStep($newStepIndex))
1148
					$this->setActiveStepIndex($newStepIndex);
1149
			}
1150
			else
1151
				$this->setActiveStepIndex($stepIndex);
1152
		}
1153
	}
1154
 
1155
	/**
1156
	 * Event handler for sidebar datalist's OnItemDataBound event.
1157
	 * This method is used internally by wizard. It mainly configures
1158
	 * the buttons in the sidebar datalist.
1159
	 * @param mixed sender of the event
1160
	 * @param TDataListItemEventParameter
1161
	 */
1162
	public function dataListItemDataBound($sender,$param)
1163
	{
1164
		$item=$param->getItem();
1165
		$itemType=$item->getItemType();
1166
		if($itemType==='Item' || $itemType==='AlternatingItem' || $itemType==='SelectedItem' || $itemType==='EditItem')
1167
		{
1168
			if(($button=$item->findControl(self::ID_SIDEBAR_BUTTON))!==null)
1169
			{
1170
				$step=$item->getData();
1171
				if(($this->getStepType($step)===TWizardStepType::Complete))
1172
					$button->setEnabled(false);
1173
				if(($title=$step->getTitle())!=='')
1174
					$button->setText($title);
1175
				else
1176
					$button->setText($step->getID(false));
1177
				$index=$this->getWizardSteps()->indexOf($step);
1178
				$button->setCommandName(self::CMD_MOVETO);
1179
				$button->setCommandParameter("$index");
1180
			}
1181
		}
1182
	}
1183
 
1184
	/**
1185
	 * Creates wizard step content.
1186
	 */
1187
	protected function createStepContent()
1188
	{
1189
		foreach($this->getWizardSteps() as $step)
1190
		{
1191
			if($step instanceof TTemplatedWizardStep)
1192
				$step->ensureChildControls();
1193
		}
1194
		$multiView=$this->getMultiView();
1195
		$this->_stepContent=new TPanel;
1196
		$this->_stepContent->getControls()->add($multiView);
1197
		$this->getControls()->add($this->_stepContent);
1198
		if($multiView->getViews()->getCount())
1199
			$multiView->setActiveViewIndex(0);
1200
	}
1201
 
1202
	/**
1203
	 * Creates navigation panel.
1204
	 */
1205
	protected function createNavigation()
1206
	{
1207
		$this->_navigation=new TPanel;
1208
		$this->getControls()->add($this->_navigation);
1209
		$controls=$this->_navigation->getControls();
1210
		foreach($this->getWizardSteps() as $step)
1211
		{
1212
			if($step instanceof TTemplatedWizardStep)
1213
			{
1214
				$step->instantiateNavigationTemplate();
1215
				if(($panel=$step->getNavigationContainer())!==null)
1216
					$controls->add($panel);
1217
			}
1218
		}
1219
		$this->_startNavigation=$this->createStartNavigation();
1220
		$controls->add($this->_startNavigation);
1221
		$this->_stepNavigation=$this->createStepNavigation();
1222
		$controls->add($this->_stepNavigation);
1223
		$this->_finishNavigation=$this->createFinishNavigation();
1224
		$controls->add($this->_finishNavigation);
1225
	}
1226
 
1227
	/**
1228
	 * Creates start navigation panel.
1229
	 */
1230
	protected function createStartNavigation()
1231
	{
1232
		if(($template=$this->getStartNavigationTemplate())===null)
1233
			$template=new TWizardStartNavigationTemplate($this);
1234
		$navigation=new TWizardNavigationContainer;
1235
		$template->instantiateIn($navigation);
1236
		return $navigation;
1237
	}
1238
 
1239
	/**
1240
	 * Creates step navigation panel.
1241
	 */
1242
	protected function createStepNavigation()
1243
	{
1244
		if(($template=$this->getStepNavigationTemplate())===null)
1245
			$template=new TWizardStepNavigationTemplate($this);
1246
		$navigation=new TWizardNavigationContainer;
1247
		$template->instantiateIn($navigation);
1248
		return $navigation;
1249
	}
1250
 
1251
	/**
1252
	 * Creates finish navigation panel.
1253
	 */
1254
	protected function createFinishNavigation()
1255
	{
1256
		if(($template=$this->getFinishNavigationTemplate())===null)
1257
			$template=new TWizardFinishNavigationTemplate($this);
1258
		$navigation=new TWizardNavigationContainer;
1259
		$template->instantiateIn($navigation);
1260
		return $navigation;
1261
	}
1262
 
1263
	/**
1264
	 * Updates the sidebar datalist if any.
1265
	 * This method is invoked when any wizard step is changed.
1266
	 */
1267
	public function wizardStepsChanged()
1268
	{
1269
		if($this->_sideBarDataList!==null)
1270
		{
1271
			$this->_sideBarDataList->setDataSource($this->getWizardSteps());
1272
			$this->_sideBarDataList->setSelectedItemIndex($this->getActiveStepIndex());
1273
			$this->_sideBarDataList->dataBind();
1274
		}
1275
	}
1276
 
1277
	/**
1278
	 * Determines the index of the previous step based on history.
1279
	 * @param boolean whether the first item in the history stack should be popped
1280
	 * up after calling this method.
1281
	 */
1282
	protected function getPreviousStepIndex($popStack)
1283
	{
1284
		$history=$this->getHistory();
1285
		if($history->getCount()>=0)
1286
		{
1287
			$activeStepIndex=$this->getActiveStepIndex();
1288
			$previousStepIndex=-1;
1289
			if($popStack)
1290
			{
1291
				$previousStepIndex=$history->pop();
1292
				if($activeStepIndex===$previousStepIndex && $history->getCount()>0)
1293
					$previousStepIndex=$history->pop();
1294
			}
1295
			else
1296
			{
1297
				$previousStepIndex=$history->peek();
1298
				if($activeStepIndex===$previousStepIndex && $history->getCount()>1)
1299
				{
1300
					$saveIndex=$history->pop();
1301
					$previousStepIndex=$history->peek();
1302
					$history->push($saveIndex);
1303
				}
1304
			}
1305
			return $activeStepIndex===$previousStepIndex ? -1 : $previousStepIndex;
1306
		}
1307
		else
1308
			return -1;
1309
	}
1310
 
1311
	/**
1312
	 * @return boolean whether navigation to the previous step is allowed
1313
	 */
1314
	protected function allowNavigationToPreviousStep()
1315
	{
1316
		if(($index=$this->getPreviousStepIndex(false))!==-1)
1317
			return $this->getWizardSteps()->itemAt($index)->getAllowReturn();
1318
		else
1319
			return false;
1320
	}
1321
 
1322
	/**
1323
	 * @param integer index of the step
1324
	 * @return boolean whether navigation to the specified step is allowed
1325
	 */
1326
	protected function allowNavigationToStep($index)
1327
	{
1328
		if($this->getHistory()->contains($index))
1329
			return $this->getWizardSteps()->itemAt($index)->getAllowReturn();
1330
		else
1331
			return true;
1332
	}
1333
 
1334
	/**
1335
	 * Handles bubbled events.
1336
	 * This method mainly translate certain command events into
1337
	 * wizard-specific events.
1338
	 * @param mixed sender of the original command event
1339
	 * @param TEventParameter event parameter
1340
	 * @throws TInvalidDataValueException if a navigation command is associated with an invalid parameter
1341
	 */
1342
	public function bubbleEvent($sender,$param)
1343
	{
1344
		if($param instanceof TCommandEventParameter)
1345
		{
1346
			$command=$param->getCommandName();
1347
			if(strcasecmp($command,self::CMD_CANCEL)===0)
1348
			{
1349
				$this->onCancelButtonClick($param);
1350
				return true;
1351
			}
1352
 
1353
			$type=$this->getStepType($this->getActiveStep());
1354
			$index=$this->getActiveStepIndex();
1355
			$navParam=new TWizardNavigationEventParameter($index);
1356
			if(($sender instanceof IButtonControl) && $sender->getCausesValidation() && ($page=$this->getPage())!==null && !$page->getIsValid())
1357
				$navParam->setCancelNavigation(true);
1358
 
1359
			$handled=false;
1360
			$movePrev=false;
1361
			$this->_activeStepIndexSet=false;
1362
 
1363
			if(strcasecmp($command,self::CMD_NEXT)===0)
1364
			{
1365
				if($type!==self::ST_START && $type!==self::ST_STEP)
1366
					throw new TInvalidDataValueException('wizard_command_invalid',self::CMD_NEXT);
1367
				if($index<$this->getWizardSteps()->getCount()-1)
1368
					$navParam->setNextStepIndex($index+1);
1369
				$this->onNextButtonClick($navParam);
1370
				$handled=true;
1371
			}
1372
			else if(strcasecmp($command,self::CMD_PREVIOUS)===0)
1373
			{
1374
				if($type!==self::ST_FINISH && $type!==self::ST_STEP)
1375
					throw new TInvalidDataValueException('wizard_command_invalid',self::CMD_PREVIOUS);
1376
				$movePrev=true;
1377
				if(($prevIndex=$this->getPreviousStepIndex(false))>=0)
1378
					$navParam->setNextStepIndex($prevIndex);
1379
				$this->onPreviousButtonClick($navParam);
1380
				$handled=true;
1381
			}
1382
			else if(strcasecmp($command,self::CMD_COMPLETE)===0)
1383
			{
1384
				if($type!==self::ST_FINISH)
1385
					throw new TInvalidDataValueException('wizard_command_invalid',self::CMD_COMPLETE);
1386
				if($index<$this->getWizardSteps()->getCount()-1)
1387
					$navParam->setNextStepIndex($index+1);
1388
				$this->onCompleteButtonClick($navParam);
1389
				$handled=true;
1390
			}
1391
			else if(strcasecmp($command,self::CMD_MOVETO)===0)
1392
			{
1393
				if($this->_cancelNavigation)  // may be set in onSideBarButtonClick
1394
					$navParam->setCancelNavigation(true);
1395
				$requestedStep=$param->getCommandParameter();
1396
				if (!is_numeric($requestedStep))
1397
				{
1398
					$requestedIndex=-1;
1399
					foreach ($this->getWizardSteps() as $index=>$step)
1400
						if ($step->getId()===$requestedStep)
1401
						{
1402
							$requestedIndex=$index;
1403
							break;
1404
						}
1405
					if ($requestedIndex<0)
1406
						throw new TConfigurationException('wizard_step_invalid');
1407
				}
1408
				else
1409
					$requestedIndex=TPropertyValue::ensureInteger($requestedStep);
1410
				$navParam->setNextStepIndex($requestedIndex);
1411
				$handled=true;
1412
			}
1413
 
1414
			if($handled)
1415
			{
1416
				if(!$navParam->getCancelNavigation())
1417
				{
1418
					$nextStepIndex=$navParam->getNextStepIndex();
1419
					if(!$this->_activeStepIndexSet && $this->allowNavigationToStep($nextStepIndex))
1420
					{
1421
						if($movePrev)
1422
							$this->getPreviousStepIndex(true);  // pop out the previous move from history
1423
						$this->setActiveStepIndex($nextStepIndex);
1424
					}
1425
				}
1426
				else
1427
					$this->setActiveStepIndex($index);
1428
				return true;
1429
			}
1430
		}
1431
		return false;
1432
	}
1433
}
1434
 
1435
 
1436
/**
1437
 * TWizardStep class.
1438
 *
1439
 * TWizardStep represents a wizard step. The wizard owning the step
1440
 * can be obtained by {@link getWizard Wizard}.
1441
 * To specify the type of the step, set {@link setStepType StepType};
1442
 * For step title, set {@link setTitle Title}. If a step can be re-visited,
1443
 * set {@link setAllowReturn AllowReturn} to true.
1444
 *
1445
 * @author Qiang Xue <qiang.xue@gmail.com>
1446
 * @version $Id: TWizard.php 2541 2008-10-21 15:05:13Z qiang.xue $
1447
 * @package System.Web.UI.WebControls
1448
 * @since 3.0
1449
 */
1450
class TWizardStep extends TView
1451
{
1452
	private $_wizard;
1453
 
1454
	/**
1455
	 * @return TWizard the wizard owning this step
1456
	 */
1457
	public function getWizard()
1458
	{
1459
		return $this->_wizard;
1460
	}
1461
 
1462
	/**
1463
	 * Sets the wizard owning this step.
1464
	 * This method is used internally by {@link TWizard}.
1465
	 * @param TWizard the wizard owning this step
1466
	 */
1467
	public function setWizard($wizard)
1468
	{
1469
		$this->_wizard=$wizard;
1470
	}
1471
 
1472
	/**
1473
	 * @return string the title for this step.
1474
	 */
1475
	public function getTitle()
1476
	{
1477
		return $this->getViewState('Title','');
1478
	}
1479
 
1480
	/**
1481
	 * @param string the title for this step.
1482
	 */
1483
	public function setTitle($value)
1484
	{
1485
		$this->setViewState('Title',$value,'');
1486
		if($this->_wizard)
1487
			$this->_wizard->wizardStepsChanged();
1488
	}
1489
 
1490
	/**
1491
	 * @return boolean whether this step can be re-visited. Default to true.
1492
	 */
1493
	public function getAllowReturn()
1494
	{
1495
		return $this->getViewState('AllowReturn',true);
1496
	}
1497
 
1498
	/**
1499
	 * @param boolean whether this step can be re-visited.
1500
	 */
1501
	public function setAllowReturn($value)
1502
	{
1503
		$this->setViewState('AllowReturn',TPropertyValue::ensureBoolean($value),true);
1504
	}
1505
 
1506
	/**
1507
	 * @return TWizardStepType the wizard step type. Defaults to TWizardStepType::Auto.
1508
	 */
1509
	public function getStepType()
1510
	{
1511
		return $this->getViewState('StepType',TWizardStepType::Auto);
1512
	}
1513
 
1514
	/**
1515
	 * @param TWizardStepType the wizard step type.
1516
	 */
1517
	public function setStepType($type)
1518
	{
1519
		$type=TPropertyValue::ensureEnum($type,'TWizardStepType');
1520
		if($type!==$this->getStepType())
1521
		{
1522
			$this->setViewState('StepType',$type,TWizardStepType::Auto);
1523
			if($this->_wizard)
1524
				$this->_wizard->wizardStepsChanged();
1525
		}
1526
	}
1527
}
1528
 
1529
 
1530
/**
1531
 * TCompleteWizardStep class.
1532
 *
1533
 * TCompleteWizardStep represents a wizard step of type TWizardStepType::Complete.
1534
 *
1535
 * @author Qiang Xue <qiang.xue@gmail.com>
1536
 * @version $Id: TWizard.php 2541 2008-10-21 15:05:13Z qiang.xue $
1537
 * @package System.Web.UI.WebControls
1538
 * @since 3.0
1539
 */
1540
class TCompleteWizardStep extends TWizardStep
1541
{
1542
	/**
1543
	 * @return TWizardStepType the wizard step type. Always TWizardStepType::Complete.
1544
	 */
1545
	public function getStepType()
1546
	{
1547
		return TWizardStepType::Complete;
1548
	}
1549
 
1550
	/**
1551
	 * @param string the wizard step type.
1552
	 * @throws TInvalidOperationException whenever this method is invoked.
1553
	 */
1554
	public function setStepType($value)
1555
	{
1556
		throw new TInvalidOperationException('completewizardstep_steptype_readonly');
1557
	}
1558
}
1559
 
1560
 
1561
/**
1562
 * TTemplatedWizardStep class.
1563
 *
1564
 * TTemplatedWizardStep represents a wizard step whose content and navigation
1565
 * can be customized using templates. To customize the step content, specify
1566
 * {@link setContentTemplate ContentTemplate}. To customize navigation specific
1567
 * to the step, specify {@link setNavigationTemplate NavigationTemplate}. Note,
1568
 * if the navigation template is not specified, default navigation will be used.
1569
 *
1570
 * @author Qiang Xue <qiang.xue@gmail.com>
1571
 * @version $Id: TWizard.php 2541 2008-10-21 15:05:13Z qiang.xue $
1572
 * @package System.Web.UI.WebControls
1573
 * @since 3.0
1574
 */
1575
class TTemplatedWizardStep extends TWizardStep implements INamingContainer
1576
{
1577
	/**
1578
	 * @var ITemplate the template for displaying the navigation UI of a wizard step.
1579
	 */
1580
	private $_navigationTemplate=null;
1581
	/**
1582
	 * @var ITemplate the template for displaying the content within the wizard step.
1583
	 */
1584
	private $_contentTemplate=null;
1585
	/**
1586
	 * @var TWizardNavigationContainer
1587
	 */
1588
	private $_navigationContainer=null;
1589
 
1590
	/**
1591
	 * Creates child controls.
1592
	 * This method mainly instantiates the content template, if any.
1593
	 */
1594
	public function createChildControls()
1595
	{
1596
		$this->getControls()->clear();
1597
		if($this->_contentTemplate)
1598
			$this->_contentTemplate->instantiateIn($this);
1599
	}
1600
 
1601
	/**
1602
	 * Ensures child controls are created.
1603
	 * @param mixed event parameter
1604
	 */
1605
	public function onInit($param)
1606
	{
1607
		parent::onInit($param);
1608
		$this->ensureChildControls();
1609
	}
1610
 
1611
	/**
1612
	 * @return ITemplate the template for the content of the wizard step.
1613
	 */
1614
	public function getContentTemplate()
1615
	{
1616
		return $this->_contentTemplate;
1617
	}
1618
 
1619
	/**
1620
	 * @param ITemplate the template for the content of the wizard step.
1621
	 */
1622
	public function setContentTemplate($value)
1623
	{
1624
		$this->_contentTemplate=$value;
1625
	}
1626
 
1627
	/**
1628
	 * @return ITemplate the template for displaying the navigation UI of a wizard step. Defaults to null.
1629
	 */
1630
	public function getNavigationTemplate()
1631
	{
1632
		return $this->_navigationTemplate;
1633
	}
1634
 
1635
	/**
1636
	 * @param ITemplate the template for displaying the navigation UI of a wizard step.
1637
	 */
1638
	public function setNavigationTemplate($value)
1639
	{
1640
		$this->_navigationTemplate=$value;
1641
	}
1642
 
1643
	/**
1644
	 * @return TWizardNavigationContainer the control containing the navigation.
1645
	 * It could be null if no navigation template is specified.
1646
	 */
1647
	public function getNavigationContainer()
1648
	{
1649
		return $this->_navigationContainer;
1650
	}
1651
 
1652
	/**
1653
	 * Instantiates the navigation template if any
1654
	 */
1655
	public function instantiateNavigationTemplate()
1656
	{
1657
		if(!$this->_navigationContainer && $this->_navigationTemplate)
1658
		{
1659
			$this->_navigationContainer=new TWizardNavigationContainer;
1660
			$this->_navigationTemplate->instantiateIn($this->_navigationContainer);
1661
		}
1662
	}
1663
}
1664
 
1665
 
1666
/**
1667
 * TWizardStepCollection class.
1668
 *
1669
 * TWizardStepCollection represents the collection of wizard steps owned
1670
 * by a {@link TWizard}.
1671
 *
1672
 * @author Qiang Xue <qiang.xue@gmail.com>
1673
 * @version $Id: TWizard.php 2541 2008-10-21 15:05:13Z qiang.xue $
1674
 * @package System.Web.UI.WebControls
1675
 * @since 3.0
1676
 */
1677
class TWizardStepCollection extends TList
1678
{
1679
	/**
1680
	 * @var TWizard
1681
	 */
1682
	private $_wizard;
1683
 
1684
	/**
1685
	 * Constructor.
1686
	 * @param TWizard wizard that owns this collection
1687
	 */
1688
	public function __construct(TWizard $wizard)
1689
	{
1690
		$this->_wizard=$wizard;
1691
	}
1692
 
1693
	/**
1694
	 * Inserts an item at the specified position.
1695
	 * This method overrides the parent implementation by checking if
1696
	 * the item being added is a {@link TWizardStep}.
1697
	 * @param integer the speicified position.
1698
	 * @param mixed new item
1699
	 * @throws TInvalidDataTypeException if the item being added is not TWizardStep.
1700
	 */
1701
	public function insertAt($index,$item)
1702
	{
1703
		if($item instanceof TWizardStep)
1704
		{
1705
			parent::insertAt($index,$item);
1706
			$this->_wizard->getMultiView()->getViews()->insertAt($index,$item);
1707
			$this->_wizard->addedWizardStep($item);
1708
		}
1709
		else
1710
			throw new TInvalidDataTypeException('wizardstepcollection_wizardstep_required');
1711
	}
1712
 
1713
	/**
1714
	 * Removes an item at the specified position.
1715
	 * @param integer the index of the item to be removed.
1716
	 * @return mixed the removed item.
1717
	 */
1718
	public function removeAt($index)
1719
	{
1720
		$step=parent::removeAt($index);
1721
		$this->_wizard->getMultiView()->getViews()->remove($step);
1722
		$this->_wizard->removedWizardStep($step);
1723
		return $step;
1724
	}
1725
}
1726
 
1727
 
1728
/**
1729
 * TWizardNavigationContainer class.
1730
 *
1731
 * TWizardNavigationContainer represents a control containing
1732
 * a wizard navigation. The navigation may contain a few buttons, including
1733
 * {@link getPreviousButton PreviousButton}, {@link getNextButton NextButton},
1734
 * {@link getCancelButton CancelButton}, {@link getCompleteButton CompleteButton}.
1735
 *
1736
 * @author Qiang Xue <qiang.xue@gmail.com>
1737
 * @version $Id: TWizard.php 2541 2008-10-21 15:05:13Z qiang.xue $
1738
 * @package System.Web.UI.WebControls
1739
 * @since 3.0
1740
 */
1741
class TWizardNavigationContainer extends TControl implements INamingContainer
1742
{
1743
	private $_previousButton=null;
1744
	private $_nextButton=null;
1745
	private $_cancelButton=null;
1746
	private $_completeButton=null;
1747
 
1748
	/**
1749
	 * @return mixed the previous button
1750
	 */
1751
	public function getPreviousButton()
1752
	{
1753
		return $this->_previousButton;
1754
	}
1755
 
1756
	/**
1757
	 * @param mixed the previous button
1758
	 */
1759
	public function setPreviousButton($value)
1760
	{
1761
		$this->_previousButton=$value;
1762
	}
1763
 
1764
	/**
1765
	 * @return mixed the next button
1766
	 */
1767
	public function getNextButton()
1768
	{
1769
		return $this->_nextButton;
1770
	}
1771
 
1772
	/**
1773
	 * @param mixed the next button
1774
	 */
1775
	public function setNextButton($value)
1776
	{
1777
		$this->_nextButton=$value;
1778
	}
1779
 
1780
	/**
1781
	 * @return mixed the cancel button
1782
	 */
1783
	public function getCancelButton()
1784
	{
1785
		return $this->_cancelButton;
1786
	}
1787
 
1788
	/**
1789
	 * @param mixed the cancel button
1790
	 */
1791
	public function setCancelButton($value)
1792
	{
1793
		$this->_cancelButton=$value;
1794
	}
1795
 
1796
	/**
1797
	 * @return mixed the complete button
1798
	 */
1799
	public function getCompleteButton()
1800
	{
1801
		return $this->_completeButton;
1802
	}
1803
 
1804
	/**
1805
	 * @param mixed the complete button
1806
	 */
1807
	public function setCompleteButton($value)
1808
	{
1809
		$this->_completeButton=$value;
1810
	}
1811
}
1812
 
1813
 
1814
/**
1815
 * TWizardNavigationEventParameter class.
1816
 *
1817
 * TWizardNavigationEventParameter represents the parameter for
1818
 * {@link TWizard}'s navigation events.
1819
 *
1820
 * The index of the currently active step can be obtained from
1821
 * {@link getCurrentStepIndex CurrentStepIndex}, while the index
1822
 * of the candidate new step is in {@link getNextStepIndex NextStepIndex}.
1823
 * By modifying {@link setNextStepIndex NextStepIndex}, the new step
1824
 * can be changed to another one. If there is anything wrong with
1825
 * the navigation and it is not wanted, set {@link setCancelNavigation CancelNavigation}
1826
 * to true.
1827
 *
1828
 * @author Qiang Xue <qiang.xue@gmail.com>
1829
 * @version $Id: TWizard.php 2541 2008-10-21 15:05:13Z qiang.xue $
1830
 * @package System.Web.UI.WebControls
1831
 * @since 3.0
1832
 */
1833
class TWizardNavigationEventParameter extends TEventParameter
1834
{
1835
	private $_cancel=false;
1836
	private $_currentStep;
1837
	private $_nextStep;
1838
 
1839
	/**
1840
	 * Constructor.
1841
	 * @param integer current step index
1842
	 */
1843
	public function __construct($currentStep)
1844
	{
1845
		$this->_currentStep=$currentStep;
1846
		$this->_nextStep=$currentStep;
1847
	}
1848
 
1849
	/**
1850
	 * @return integer the zero-based index of the currently active step.
1851
	 */
1852
	public function getCurrentStepIndex()
1853
	{
1854
		return $this->_currentStep;
1855
	}
1856
 
1857
	/**
1858
	 * @return integer the zero-based index of the next step. Default to {@link getCurrentStepIndex CurrentStepIndex}.
1859
	 */
1860
	public function getNextStepIndex()
1861
	{
1862
		return $this->_nextStep;
1863
	}
1864
 
1865
	/**
1866
	 * @param integer the zero-based index of the next step.
1867
	 */
1868
	public function setNextStepIndex($index)
1869
	{
1870
		$this->_nextStep=TPropertyValue::ensureInteger($index);
1871
	}
1872
 
1873
	/**
1874
	 * @return boolean whether navigation to the next step should be canceled. Default to false.
1875
	 */
1876
	public function getCancelNavigation()
1877
	{
1878
		return $this->_cancel;
1879
	}
1880
 
1881
	/**
1882
	 * @param boolean whether navigation to the next step should be canceled.
1883
	 */
1884
	public function setCancelNavigation($value)
1885
	{
1886
		$this->_cancel=TPropertyValue::ensureBoolean($value);
1887
	}
1888
}
1889
 
1890
/**
1891
 * TWizardSideBarTemplate class.
1892
 * TWizardSideBarTemplate is the default template for wizard sidebar.
1893
 * @author Qiang Xue <qiang.xue@gmail.com>
1894
 * @version $Id: TWizard.php 2541 2008-10-21 15:05:13Z qiang.xue $
1895
 * @package System.Web.UI.WebControls
1896
 * @since 3.0
1897
 */
1898
class TWizardSideBarTemplate extends TComponent implements ITemplate
1899
{
1900
	/**
1901
	 * Instantiates the template.
1902
	 * It creates a {@link TDataList} control.
1903
	 * @param TControl parent to hold the content within the template
1904
	 */
1905
	public function instantiateIn($parent)
1906
	{
1907
		$dataList=new TDataList;
1908
		$dataList->setID(TWizard::ID_SIDEBAR_LIST);
1909
		$dataList->getSelectedItemStyle()->getFont()->setBold(true);
1910
		$dataList->setItemTemplate(new TWizardSideBarListItemTemplate);
1911
		$parent->getControls()->add($dataList);
1912
	}
1913
}
1914
 
1915
/**
1916
 * TWizardSideBarListItemTemplate class.
1917
 * TWizardSideBarListItemTemplate is the default template for each item in the sidebar datalist.
1918
 * @author Qiang Xue <qiang.xue@gmail.com>
1919
 * @version $Id: TWizard.php 2541 2008-10-21 15:05:13Z qiang.xue $
1920
 * @package System.Web.UI.WebControls
1921
 * @since 3.0
1922
 */
1923
class TWizardSideBarListItemTemplate extends TComponent implements ITemplate
1924
{
1925
	/**
1926
	 * Instantiates the template.
1927
	 * It creates a {@link TLinkButton}.
1928
	 * @param TControl parent to hold the content within the template
1929
	 */
1930
	public function instantiateIn($parent)
1931
	{
1932
		$button=new TLinkButton;
1933
		$button->setID(TWizard::ID_SIDEBAR_BUTTON);
1934
		$parent->getControls()->add($button);
1935
	}
1936
}
1937
 
1938
/**
1939
 * TWizardNavigationTemplate class.
1940
 * TWizardNavigationTemplate is the base class for various navigation templates.
1941
 * @author Qiang Xue <qiang.xue@gmail.com>
1942
 * @version $Id: TWizard.php 2541 2008-10-21 15:05:13Z qiang.xue $
1943
 * @package System.Web.UI.WebControls
1944
 * @since 3.0
1945
 */
1946
class TWizardNavigationTemplate extends TComponent implements ITemplate
1947
{
1948
	private $_wizard;
1949
 
1950
	/**
1951
	 * Constructor.
1952
	 * @param TWizard the wizard owning this template
1953
	 */
1954
	public function __construct($wizard)
1955
	{
1956
		$this->_wizard=$wizard;
1957
	}
1958
 
1959
	/**
1960
	 * @return TWizard the wizard owning this template
1961
	 */
1962
	public function getWizard()
1963
	{
1964
		return $this->_wizard;
1965
	}
1966
 
1967
	/**
1968
	 * Instantiates the template.
1969
	 * Derived classes should override this method.
1970
	 * @param TControl parent to hold the content within the template
1971
	 */
1972
	public function instantiateIn($parent)
1973
	{
1974
	}
1975
 
1976
	/**
1977
	 * Creates a navigation button.
1978
	 * It creates a {@link TButton}, {@link TLinkButton}, or {@link TImageButton},
1979
	 * depending on the given parameters.
1980
	 * @param TWizardNavigationButtonStyle button style
1981
	 * @param boolean whether the button should cause validation
1982
	 * @param string command name for the button's OnCommand event
1983
	 * @throws TInvalidDataValueException if the button type is not recognized
1984
	 */
1985
	protected function createNavigationButton($buttonStyle,$causesValidation,$commandName)
1986
	{
1987
		switch($buttonStyle->getButtonType())
1988
		{
1989
			case TWizardNavigationButtonType::Button:
1990
				$button=new TButton;
1991
				break;
1992
			case TWizardNavigationButtonType::Link:
1993
				$button=new TLinkButton;
1994
				break;
1995
			case TWizardNavigationButtonType::Image:
1996
				$button=new TImageButton;
1997
				$button->setImageUrl($buttonStyle->getImageUrl());
1998
				break;
1999
			default:
2000
				throw new TInvalidDataValueException('wizard_buttontype_unknown',$buttonStyle->getButtonType());
2001
		}
2002
		$button->setText($buttonStyle->getButtonText());
2003
		$button->setCausesValidation($causesValidation);
2004
		$button->setCommandName($commandName);
2005
		return $button;
2006
	}
2007
}
2008
 
2009
/**
2010
 * TWizardStartNavigationTemplate class.
2011
 * TWizardStartNavigationTemplate is the template used as default wizard start navigation panel.
2012
 * It consists of two buttons, Next and Cancel.
2013
 * @author Qiang Xue <qiang.xue@gmail.com>
2014
 * @version $Id: TWizard.php 2541 2008-10-21 15:05:13Z qiang.xue $
2015
 * @package System.Web.UI.WebControls
2016
 * @since 3.0
2017
 */
2018
class TWizardStartNavigationTemplate extends TWizardNavigationTemplate
2019
{
2020
	/**
2021
	 * Instantiates the template.
2022
	 * @param TControl parent to hold the content within the template
2023
	 */
2024
	public function instantiateIn($parent)
2025
	{
2026
		$nextButton=$this->createNavigationButton($this->getWizard()->getStartNextButtonStyle(),true,TWizard::CMD_NEXT);
2027
		$cancelButton=$this->createNavigationButton($this->getWizard()->getCancelButtonStyle(),false,TWizard::CMD_CANCEL);
2028
 
2029
		$controls=$parent->getControls();
2030
		$controls->add($nextButton);
2031
		$controls->add("\n");
2032
		$controls->add($cancelButton);
2033
 
2034
		$parent->setNextButton($nextButton);
2035
		$parent->setCancelButton($cancelButton);
2036
	}
2037
}
2038
 
2039
/**
2040
 * TWizardFinishNavigationTemplate class.
2041
 * TWizardFinishNavigationTemplate is the template used as default wizard finish navigation panel.
2042
 * It consists of three buttons, Previous, Complete and Cancel.
2043
 * @author Qiang Xue <qiang.xue@gmail.com>
2044
 * @version $Id: TWizard.php 2541 2008-10-21 15:05:13Z qiang.xue $
2045
 * @package System.Web.UI.WebControls
2046
 * @since 3.0
2047
 */
2048
class TWizardFinishNavigationTemplate extends TWizardNavigationTemplate
2049
{
2050
	/**
2051
	 * Instantiates the template.
2052
	 * @param TControl parent to hold the content within the template
2053
	 */
2054
	public function instantiateIn($parent)
2055
	{
2056
		$previousButton=$this->createNavigationButton($this->getWizard()->getFinishPreviousButtonStyle(),false,TWizard::CMD_PREVIOUS);
2057
		$completeButton=$this->createNavigationButton($this->getWizard()->getFinishCompleteButtonStyle(),true,TWizard::CMD_COMPLETE);
2058
		$cancelButton=$this->createNavigationButton($this->getWizard()->getCancelButtonStyle(),false,TWizard::CMD_CANCEL);
2059
 
2060
		$controls=$parent->getControls();
2061
		$controls->add($previousButton);
2062
		$controls->add("\n");
2063
		$controls->add($completeButton);
2064
		$controls->add("\n");
2065
		$controls->add($cancelButton);
2066
 
2067
		$parent->setPreviousButton($previousButton);
2068
		$parent->setCompleteButton($completeButton);
2069
		$parent->setCancelButton($cancelButton);
2070
	}
2071
}
2072
 
2073
/**
2074
 * TWizardStepNavigationTemplate class.
2075
 * TWizardStepNavigationTemplate is the template used as default wizard step navigation panel.
2076
 * It consists of three buttons, Previous, Next and Cancel.
2077
 * @author Qiang Xue <qiang.xue@gmail.com>
2078
 * @version $Id: TWizard.php 2541 2008-10-21 15:05:13Z qiang.xue $
2079
 * @package System.Web.UI.WebControls
2080
 * @since 3.0
2081
 */
2082
class TWizardStepNavigationTemplate extends TWizardNavigationTemplate
2083
{
2084
	/**
2085
	 * Instantiates the template.
2086
	 * @param TControl parent to hold the content within the template
2087
	 */
2088
	public function instantiateIn($parent)
2089
	{
2090
		$previousButton=$this->createNavigationButton($this->getWizard()->getStepPreviousButtonStyle(),false,TWizard::CMD_PREVIOUS);
2091
		$nextButton=$this->createNavigationButton($this->getWizard()->getStepNextButtonStyle(),true,TWizard::CMD_NEXT);
2092
		$cancelButton=$this->createNavigationButton($this->getWizard()->getCancelButtonStyle(),false,TWizard::CMD_CANCEL);
2093
 
2094
		$controls=$parent->getControls();
2095
		$controls->add($previousButton);
2096
		$controls->add("\n");
2097
		$controls->add($nextButton);
2098
		$controls->add("\n");
2099
		$controls->add($cancelButton);
2100
 
2101
		$parent->setPreviousButton($previousButton);
2102
		$parent->setNextButton($nextButton);
2103
		$parent->setCancelButton($cancelButton);
2104
	}
2105
}
2106
 
2107
 
2108
/**
2109
 * TWizardNavigationButtonType class.
2110
 * TWizardNavigationButtonType defines the enumerable type for the possible types of buttons
2111
 * that can be used in the navigation part of a {@link TWizard}.
2112
 *
2113
 * The following enumerable values are defined:
2114
 * - Button: a regular click button
2115
 * - Image: an image button
2116
 * - Link: a hyperlink button
2117
 *
2118
 * @author Qiang Xue <qiang.xue@gmail.com>
2119
 * @version $Id: TWizard.php 2541 2008-10-21 15:05:13Z qiang.xue $
2120
 * @package System.Web.UI.WebControls
2121
 * @since 3.0.4
2122
 */
2123
class TWizardNavigationButtonType extends TEnumerable
2124
{
2125
	const Button='Button';
2126
	const Image='Image';
2127
	const Link='Link';
2128
}
2129
 
2130
 
2131
/**
2132
 * TWizardStepType class.
2133
 * TWizardStepType defines the enumerable type for the possible types of {@link TWizard wizard} steps.
2134
 *
2135
 * The following enumerable values are defined:
2136
 * - Auto: the type is automatically determined based on the location of the wizard step in the whole step collection.
2137
 * - Complete: the step is the last summary step.
2138
 * - Start: the step is the first step
2139
 * - Step: the step is between the begin and the end steps.
2140
 * - Finish: the last step before the Complete step.
2141
 *
2142
 * @author Qiang Xue <qiang.xue@gmail.com>
2143
 * @version $Id: TWizard.php 2541 2008-10-21 15:05:13Z qiang.xue $
2144
 * @package System.Web.UI.WebControls
2145
 * @since 3.0.4
2146
 */
2147
class TWizardStepType extends TEnumerable
2148
{
2149
	const Auto='Auto';
2150
	const Complete='Complete';
2151
	const Start='Start';
2152
	const Step='Step';
2153
	const Finish='Finish';
2154
}
2155