1 /**
2 * Copyright 2005-2012 The Kuali Foundation
3 *
4 * Licensed under the Educational Community License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.opensource.org/licenses/ecl2.php
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.kuali.rice.krad.uif.container;
17
18 import java.util.ArrayList;
19 import java.util.List;
20
21 import org.apache.commons.lang.StringUtils;
22 import org.kuali.rice.core.api.exception.RiceRuntimeException;
23 import org.kuali.rice.krad.uif.UifConstants;
24 import org.kuali.rice.krad.uif.UifParameters;
25 import org.kuali.rice.krad.uif.component.BindingInfo;
26 import org.kuali.rice.krad.uif.component.Component;
27 import org.kuali.rice.krad.uif.component.ComponentSecurity;
28 import org.kuali.rice.krad.uif.component.DataBinding;
29 import org.kuali.rice.krad.uif.field.ActionField;
30 import org.kuali.rice.krad.uif.field.DataField;
31 import org.kuali.rice.krad.uif.field.DataFieldSecurity;
32 import org.kuali.rice.krad.uif.field.Field;
33 import org.kuali.rice.krad.uif.field.LabelField;
34 import org.kuali.rice.krad.uif.util.ComponentUtils;
35 import org.kuali.rice.krad.uif.view.View;
36 import org.kuali.rice.krad.uif.widget.QuickFinder;
37
38 /**
39 * Group that holds a collection of objects and configuration for presenting the
40 * collection in the UI. Supports functionality such as add line, line actions,
41 * and nested collections.
42 *
43 * <p>
44 * Note the standard header/footer can be used to give a header to the
45 * collection as a whole, or to provide actions that apply to the entire
46 * collection
47 * </p>
48 *
49 * <p>
50 * For binding purposes the binding path of each row field is indexed. The name
51 * property inherited from <code>ComponentBase</code> is used as the collection
52 * name. The collectionObjectClass property is used to lookup attributes from
53 * the data dictionary.
54 * </p>
55 *
56 * @author Kuali Rice Team (rice.collab@kuali.org)
57 */
58 public class CollectionGroup extends Group implements DataBinding {
59 private static final long serialVersionUID = -6496712566071542452L;
60
61 private Class<?> collectionObjectClass;
62
63 private String propertyName;
64 private BindingInfo bindingInfo;
65
66 private boolean renderAddLine;
67 private String addLinePropertyName;
68 private BindingInfo addLineBindingInfo;
69 private LabelField addLineLabelField;
70 private List<? extends Component> addLineFields;
71 private List<ActionField> addLineActionFields;
72
73 private boolean renderLineActions;
74 private List<ActionField> actionFields;
75
76 private boolean renderSelectField;
77 private String selectPropertyName;
78
79 private QuickFinder collectionLookup;
80
81 private boolean showHideInactiveButton;
82 private boolean showInactive;
83 private CollectionFilter activeCollectionFilter;
84 private List<CollectionFilter> filters;
85
86 private List<CollectionGroup> subCollections;
87 private String subCollectionSuffix;
88
89 private CollectionGroupBuilder collectionGroupBuilder;
90
91 public CollectionGroup() {
92 renderAddLine = true;
93 renderLineActions = true;
94 showInactive = false;
95 showHideInactiveButton = true;
96 renderSelectField = false;
97
98 filters = new ArrayList<CollectionFilter>();
99 actionFields = new ArrayList<ActionField>();
100 addLineFields = new ArrayList<Field>();
101 addLineActionFields = new ArrayList<ActionField>();
102 subCollections = new ArrayList<CollectionGroup>();
103 }
104
105 /**
106 * The following actions are performed:
107 *
108 * <ul>
109 * <li>Set fieldBindModelPath to the collection model path (since the fields
110 * have to belong to the same model as the collection)</li>
111 * <li>Set defaults for binding</li>
112 * <li>Default add line field list to groups items list</li>
113 * <li>Sets default active collection filter if not set</li>
114 * <li>Sets the dictionary entry (if blank) on each of the items to the
115 * collection class</li>
116 * </ul>
117 *
118 * @see org.kuali.rice.krad.uif.component.ComponentBase#performInitialization(org.kuali.rice.krad.uif.view.View,
119 * java.lang.Object)
120 */
121 @Override
122 public void performInitialization(View view, Object model) {
123 setFieldBindingObjectPath(getBindingInfo().getBindingObjectPath());
124
125 super.performInitialization(view, model);
126
127 if (bindingInfo != null) {
128 bindingInfo.setDefaults(view, getPropertyName());
129 }
130
131 if (addLineBindingInfo != null) {
132 // add line binds to model property
133 if (StringUtils.isNotBlank(addLinePropertyName)) {
134 addLineBindingInfo.setDefaults(view, getPropertyName());
135 addLineBindingInfo.setBindingName(addLinePropertyName);
136 if (StringUtils.isNotBlank(getFieldBindByNamePrefix())) {
137 addLineBindingInfo.setBindByNamePrefix(getFieldBindByNamePrefix());
138 }
139 }
140 }
141
142 for (Component item : getItems()) {
143 if (item instanceof DataField) {
144 DataField field = (DataField) item;
145
146 if (StringUtils.isBlank(field.getDictionaryObjectEntry())) {
147 field.setDictionaryObjectEntry(collectionObjectClass.getName());
148 }
149 }
150 }
151
152 for (Component addLineField : addLineFields) {
153 if (addLineField instanceof DataField) {
154 DataField field = (DataField) addLineField;
155
156 if (StringUtils.isBlank(field.getDictionaryObjectEntry())) {
157 field.setDictionaryObjectEntry(collectionObjectClass.getName());
158 }
159 }
160 }
161
162 if ((addLineFields == null) || addLineFields.isEmpty()) {
163 addLineFields = getItems();
164 }
165
166 // if active collection filter not set use default
167 if (this.activeCollectionFilter == null) {
168 activeCollectionFilter = new ActiveCollectionFilter();
169 }
170
171 // set static collection path on items
172 String collectionPath = "";
173 if (StringUtils.isNotBlank(getBindingInfo().getCollectionPath())) {
174 collectionPath += getBindingInfo().getCollectionPath() + ".";
175 }
176 if (StringUtils.isNotBlank(getBindingInfo().getBindByNamePrefix())) {
177 collectionPath += getBindingInfo().getBindByNamePrefix() + ".";
178 }
179 collectionPath += getBindingInfo().getBindingName();
180
181 List<DataField> collectionFields = ComponentUtils.getComponentsOfTypeDeep(getItems(), DataField.class);
182 for (DataField collectionField : collectionFields) {
183 collectionField.getBindingInfo().setCollectionPath(collectionPath);
184 }
185
186 List<DataField> addLineCollectionFields = ComponentUtils.getComponentsOfTypeDeep(addLineFields, DataField.class);
187 for (DataField collectionField : addLineCollectionFields) {
188 collectionField.getBindingInfo().setCollectionPath(collectionPath);
189 }
190
191 // add collection entry to abstract classes
192 if (!view.getAbstractTypeClasses().containsKey(collectionPath)) {
193 view.getAbstractTypeClasses().put(collectionPath, getCollectionObjectClass());
194 }
195
196 // initialize container items and sub-collections (since they are not in
197 // child list)
198 for (Component item : getItems()) {
199 view.getViewHelperService().performComponentInitialization(view, model, item);
200 }
201
202 // initialize addLineFields
203 for (Component item : addLineFields) {
204 view.getViewHelperService().performComponentInitialization(view, model, item);
205 }
206
207 for (CollectionGroup collectionGroup : getSubCollections()) {
208 collectionGroup.getBindingInfo().setCollectionPath(collectionPath);
209 view.getViewHelperService().performComponentInitialization(view, model, collectionGroup);
210 }
211 }
212
213 /**
214 * Calls the configured <code>CollectionGroupBuilder</code> to build the
215 * necessary components based on the collection data
216 *
217 * @see org.kuali.rice.krad.uif.container.ContainerBase#performApplyModel(org.kuali.rice.krad.uif.view.View,
218 * java.lang.Object, org.kuali.rice.krad.uif.component.Component)
219 */
220 @Override
221 public void performApplyModel(View view, Object model, Component parent) {
222 super.performApplyModel(view, model, parent);
223
224 pushCollectionGroupToReference();
225
226 // if rendering the collection group, build out the lines
227 if (isRender()) {
228 getCollectionGroupBuilder().build(view, model, this);
229 }
230
231 // TODO: is this necessary to call again?
232 pushCollectionGroupToReference();
233 }
234
235 /**
236 * Sets a reference in the context map for all nested components to the collection group
237 * instance, and sets name as parameter for an action fields in the group
238 */
239 protected void pushCollectionGroupToReference() {
240 List<Component> components = this.getComponentsForLifecycle();
241
242 ComponentUtils.pushObjectToContext(components, UifConstants.ContextVariableNames.COLLECTION_GROUP, this);
243
244 List<ActionField> actionFields = ComponentUtils.getComponentsOfTypeDeep(components, ActionField.class);
245 for (ActionField actionField : actionFields) {
246 actionField.addActionParameter(UifParameters.SELLECTED_COLLECTION_PATH,
247 this.getBindingInfo().getBindingPath());
248 }
249 }
250
251 /**
252 * New collection lines are handled in the framework by maintaining a map on
253 * the form. The map contains as a key the collection name, and as value an
254 * instance of the collection type. An entry is created here for the
255 * collection represented by the <code>CollectionGroup</code> if an instance
256 * is not available (clearExistingLine will force a new instance). The given
257 * model must be a subclass of <code>UifFormBase</code> in order to find the
258 * Map.
259 *
260 * @param model - Model instance that contains the new collection lines Map
261 * @param clearExistingLine - boolean that indicates whether the line should be set to a
262 * new instance if it already exists
263 */
264 public void initializeNewCollectionLine(View view, Object model, CollectionGroup collectionGroup,
265 boolean clearExistingLine) {
266 getCollectionGroupBuilder().initializeNewCollectionLine(view, model, collectionGroup, clearExistingLine);
267 }
268
269 /**
270 * @see org.kuali.rice.krad.uif.container.ContainerBase#getComponentsForLifecycle()
271 */
272 @Override
273 public List<Component> getComponentsForLifecycle() {
274 List<Component> components = super.getComponentsForLifecycle();
275
276 components.add(addLineLabelField);
277 components.add(collectionLookup);
278
279 // remove the containers items because we don't want them as children
280 // (they will become children of the layout manager as the rows are
281 // created)
282 for (Component item : getItems()) {
283 if (components.contains(item)) {
284 components.remove(item);
285 }
286 }
287
288 return components;
289 }
290
291 /**
292 * @see org.kuali.rice.krad.uif.component.Component#getComponentPrototypes()
293 */
294 @Override
295 public List<Component> getComponentPrototypes() {
296 List<Component> components = super.getComponentPrototypes();
297
298 components.addAll(actionFields);
299 components.addAll(addLineActionFields);
300 components.addAll(getItems());
301 components.addAll(getSubCollections());
302 components.addAll(addLineFields);
303
304 return components;
305 }
306
307 /**
308 * Object class the collection maintains. Used to get dictionary information
309 * in addition to creating new instances for the collection when necessary
310 *
311 * @return Class<?> collection object class
312 */
313 public Class<?> getCollectionObjectClass() {
314 return this.collectionObjectClass;
315 }
316
317 /**
318 * Setter for the collection object class
319 *
320 * @param collectionObjectClass
321 */
322 public void setCollectionObjectClass(Class<?> collectionObjectClass) {
323 this.collectionObjectClass = collectionObjectClass;
324 }
325
326 /**
327 * @see org.kuali.rice.krad.uif.component.DataBinding#getPropertyName()
328 */
329 public String getPropertyName() {
330 return this.propertyName;
331 }
332
333 /**
334 * Setter for the collections property name
335 *
336 * @param propertyName
337 */
338 public void setPropertyName(String propertyName) {
339 this.propertyName = propertyName;
340 }
341
342 /**
343 * Determines the binding path for the collection. Used to get the
344 * collection value from the model in addition to setting the binding path
345 * for the collection attributes
346 *
347 * @see org.kuali.rice.krad.uif.component.DataBinding#getBindingInfo()
348 */
349 public BindingInfo getBindingInfo() {
350 return this.bindingInfo;
351 }
352
353 /**
354 * Setter for the binding info instance
355 *
356 * @param bindingInfo
357 */
358 public void setBindingInfo(BindingInfo bindingInfo) {
359 this.bindingInfo = bindingInfo;
360 }
361
362 /**
363 * Action fields that should be rendered for each collection line. Example
364 * line action is the delete action
365 *
366 * @return List<ActionField> line action fields
367 */
368 public List<ActionField> getActionFields() {
369 return this.actionFields;
370 }
371
372 /**
373 * Setter for the line action fields list
374 *
375 * @param actionFields
376 */
377 public void setActionFields(List<ActionField> actionFields) {
378 this.actionFields = actionFields;
379 }
380
381 /**
382 * Indicates whether the action column for the collection should be rendered
383 *
384 * @return boolean true if the actions should be rendered, false if not
385 * @see #getActionFields()
386 */
387 public boolean isRenderLineActions() {
388 return this.renderLineActions;
389 }
390
391 /**
392 * Setter for the render line actions indicator
393 *
394 * @param renderLineActions
395 */
396 public void setRenderLineActions(boolean renderLineActions) {
397 this.renderLineActions = renderLineActions;
398 }
399
400 /**
401 * Indicates whether an add line should be rendered for the collection
402 *
403 * @return boolean true if add line should be rendered, false if it should
404 * not be
405 */
406 public boolean isRenderAddLine() {
407 return this.renderAddLine;
408 }
409
410 /**
411 * Setter for the render add line indicator
412 *
413 * @param renderAddLine
414 */
415 public void setRenderAddLine(boolean renderAddLine) {
416 this.renderAddLine = renderAddLine;
417 }
418
419 /**
420 * Convenience getter for the add line label field text. The text is used to
421 * label the add line when rendered and its placement depends on the
422 * <code>LayoutManager</code>.
423 * <p>
424 * For the <code>TableLayoutManager</code> the label appears in the sequence
425 * column to the left of the add line fields. For the
426 * <code>StackedLayoutManager</code> the label is placed into the group
427 * header for the line.
428 * </p>
429 *
430 * @return String add line label
431 */
432 public String getAddLineLabel() {
433 if (getAddLineLabelField() != null) {
434 return getAddLineLabelField().getLabelText();
435 }
436
437 return null;
438 }
439
440 /**
441 * Setter for the add line label text
442 *
443 * @param addLineLabel
444 */
445 public void setAddLineLabel(String addLineLabel) {
446 if (getAddLineLabelField() != null) {
447 getAddLineLabelField().setLabelText(addLineLabel);
448 }
449 }
450
451 /**
452 * <code>LabelField</code> instance for the add line label
453 *
454 * @return LabelField add line label field
455 * @see #getAddLineLabel()
456 */
457 public LabelField getAddLineLabelField() {
458 return this.addLineLabelField;
459 }
460
461 /**
462 * Setter for the <code>LabelField</code> instance for the add line label
463 *
464 * @param addLineLabelField
465 * @see #getAddLineLabel()
466 */
467 public void setAddLineLabelField(LabelField addLineLabelField) {
468 this.addLineLabelField = addLineLabelField;
469 }
470
471 /**
472 * Name of the property that contains an instance for the add line. If set
473 * this is used with the binding info to create the path to the add line.
474 * Can be left blank in which case the framework will manage the add line
475 * instance in a generic map.
476 *
477 * @return String add line property name
478 */
479 public String getAddLinePropertyName() {
480 return this.addLinePropertyName;
481 }
482
483 /**
484 * Setter for the add line property name
485 *
486 * @param addLinePropertyName
487 */
488 public void setAddLinePropertyName(String addLinePropertyName) {
489 this.addLinePropertyName = addLinePropertyName;
490 }
491
492 /**
493 * <code>BindingInfo</code> instance for the add line property used to
494 * determine the full binding path. If add line name given
495 * {@link #getAddLineLabel()} then it is set as the binding name on the
496 * binding info. Add line label and binding info are not required, in which
497 * case the framework will manage the new add line instances through a
498 * generic map (model must extend UifFormBase)
499 *
500 * @return BindingInfo add line binding info
501 */
502 public BindingInfo getAddLineBindingInfo() {
503 return this.addLineBindingInfo;
504 }
505
506 /**
507 * Setter for the add line binding info
508 *
509 * @param addLineBindingInfo
510 */
511 public void setAddLineBindingInfo(BindingInfo addLineBindingInfo) {
512 this.addLineBindingInfo = addLineBindingInfo;
513 }
514
515 /**
516 * List of <code>Component</code> instances that should be rendered for the
517 * collection add line (if enabled). If not set, the default group's items
518 * list will be used
519 *
520 * @return List<? extends Component> add line field list
521 */
522 public List<? extends Component> getAddLineFields() {
523 return this.addLineFields;
524 }
525
526 /**
527 * Setter for the add line field list
528 *
529 * @param addLineFields
530 */
531 public void setAddLineFields(List<? extends Component> addLineFields) {
532 this.addLineFields = addLineFields;
533 }
534
535 /**
536 * Action fields that should be rendered for the add line. This is generally
537 * the add action (button) but can be configured to contain additional
538 * actions
539 *
540 * @return List<ActionField> add line action fields
541 */
542 public List<ActionField> getAddLineActionFields() {
543 return this.addLineActionFields;
544 }
545
546 /**
547 * Setter for the add line action fields
548 *
549 * @param addLineActionFields
550 */
551 public void setAddLineActionFields(List<ActionField> addLineActionFields) {
552 this.addLineActionFields = addLineActionFields;
553 }
554
555 /**
556 * Indicates whether lines of the collection group should be selected by rendering a
557 * field for each line that will allow selection
558 *
559 * <p>
560 * For example, having the select field enabled could allow selecting multiple lines from a search
561 * to return (multi-value lookup)
562 * </p>
563 *
564 * @return boolean true if select field should be rendered, false if not
565 */
566 public boolean isRenderSelectField() {
567 return renderSelectField;
568 }
569
570 /**
571 * Setter for the render selected field indicator
572 *
573 * @param renderSelectField
574 */
575 public void setRenderSelectField(boolean renderSelectField) {
576 this.renderSelectField = renderSelectField;
577 }
578
579 /**
580 * When {@link #isRenderSelectField()} is true, gives the name of the property the select field
581 * should bind to
582 *
583 * <p>
584 * Note if no prefix is given in the property name, such as 'form.', it is assumed the property is
585 * contained on the collection line. In this case the binding path to the collection line will be
586 * appended. In other cases, it is assumed the property is a list or set of String that will hold the
587 * selected identifier strings
588 * </p>
589 *
590 * <p>
591 * This property is not required. If not the set the framework will use a property contained on
592 * <code>UifFormBase</code>
593 * </p>
594 *
595 * @return String property name for select field
596 */
597 public String getSelectPropertyName() {
598 return selectPropertyName;
599 }
600
601 /**
602 * Setter for the property name that will bind to the select field
603 *
604 * @param selectPropertyName
605 */
606 public void setSelectPropertyName(String selectPropertyName) {
607 this.selectPropertyName = selectPropertyName;
608 }
609
610 /**
611 * Instance of the <code>QuickFinder</code> widget that configures a multi-value lookup for the collection
612 *
613 * <p>
614 * If the collection lookup is enabled (by the render property of the quick finder), {@link
615 * #getCollectionObjectClass()} will be used as the data object class for the lookup (if not set). Field
616 * conversions need to be set as usual and will be applied for each line returned
617 * </p>
618 *
619 * @return QuickFinder instance configured for the collection lookup
620 */
621 public QuickFinder getCollectionLookup() {
622 return collectionLookup;
623 }
624
625 /**
626 * Setter for the collection lookup quickfinder instance
627 *
628 * @param collectionLookup
629 */
630 public void setCollectionLookup(QuickFinder collectionLookup) {
631 this.collectionLookup = collectionLookup;
632 }
633
634 /**
635 * Indicates whether inactive collections lines should be displayed
636 *
637 * <p>
638 * Setting only applies when the collection line type implements the
639 * <code>Inactivatable</code> interface. If true and showInactive is
640 * set to false, the collection will be filtered to remove any items
641 * whose active status returns false
642 * </p>
643 *
644 * @return boolean true to show inactive records, false to not render inactive records
645 */
646 public boolean isShowInactive() {
647 return showInactive;
648 }
649
650 /**
651 * Setter for the show inactive indicator
652 *
653 * @param showInactive boolean show inactive
654 */
655 public void setShowInactive(boolean showInactive) {
656 this.showInactive = showInactive;
657 }
658
659 /**
660 * Collection filter instance for filtering the collection data when the
661 * showInactive flag is set to false
662 *
663 * @return CollectionFilter
664 */
665 public CollectionFilter getActiveCollectionFilter() {
666 return activeCollectionFilter;
667 }
668
669 /**
670 * Setter for the collection filter to use for filter inactive records from the
671 * collection
672 *
673 * @param activeCollectionFilter - CollectionFilter instance
674 */
675 public void setActiveCollectionFilter(CollectionFilter activeCollectionFilter) {
676 this.activeCollectionFilter = activeCollectionFilter;
677 }
678
679 /**
680 * List of {@link CollectionFilter} instances that should be invoked to filter the collection before
681 * displaying
682 *
683 * @return List<CollectionFilter>
684 */
685 public List<CollectionFilter> getFilters() {
686 return filters;
687 }
688
689 /**
690 * Setter for the List of collection filters for which the collection will be filtered against
691 *
692 * @param filters
693 */
694 public void setFilters(List<CollectionFilter> filters) {
695 this.filters = filters;
696 }
697
698 /**
699 * List of <code>CollectionGroup</code> instances that are sub-collections
700 * of the collection represented by this collection group
701 *
702 * @return List<CollectionGroup> sub collections
703 */
704 public List<CollectionGroup> getSubCollections() {
705 return this.subCollections;
706 }
707
708 /**
709 * Setter for the sub collection list
710 *
711 * @param subCollections
712 */
713 public void setSubCollections(List<CollectionGroup> subCollections) {
714 this.subCollections = subCollections;
715 }
716
717 /**
718 * Suffix for IDs that identifies the collection line the sub-collection belongs to
719 *
720 * <p>
721 * Built by the framework as the collection lines are being generated
722 * </p>
723 *
724 * @return String id suffix for sub-collection
725 */
726 public String getSubCollectionSuffix() {
727 return subCollectionSuffix;
728 }
729
730 /**
731 * Setter for the sub-collection suffix (used by framework, should not be
732 * set in configuration)
733 *
734 * @param subCollectionSuffix
735 */
736 public void setSubCollectionSuffix(String subCollectionSuffix) {
737 this.subCollectionSuffix = subCollectionSuffix;
738 }
739
740 /**
741 * Collection Security object that indicates what authorization (permissions) exist for the collection
742 *
743 * @return CollectionGroupSecurity instance
744 */
745 @Override
746 public CollectionGroupSecurity getComponentSecurity() {
747 return (CollectionGroupSecurity) super.getComponentSecurity();
748 }
749
750 /**
751 * Override to assert a {@link CollectionGroupSecurity} instance is set
752 *
753 * @param componentSecurity - instance of CollectionGroupSecurity
754 */
755 @Override
756 public void setComponentSecurity(ComponentSecurity componentSecurity) {
757 if (!(componentSecurity instanceof CollectionGroupSecurity)) {
758 throw new RiceRuntimeException(
759 "Component security for CollectionGroup should be instance of CollectionGroupSecurity");
760 }
761
762 super.setComponentSecurity(componentSecurity);
763 }
764
765 @Override
766 protected Class<? extends ComponentSecurity> getComponentSecurityClass() {
767 return CollectionGroupSecurity.class;
768 }
769
770 /**
771 * <code>CollectionGroupBuilder</code> instance that will build the
772 * components dynamically for the collection instance
773 *
774 * @return CollectionGroupBuilder instance
775 */
776 public CollectionGroupBuilder getCollectionGroupBuilder() {
777 if (this.collectionGroupBuilder == null) {
778 this.collectionGroupBuilder = new CollectionGroupBuilder();
779 }
780 return this.collectionGroupBuilder;
781 }
782
783 /**
784 * Setter for the collection group building instance
785 *
786 * @param collectionGroupBuilder
787 */
788 public void setCollectionGroupBuilder(CollectionGroupBuilder collectionGroupBuilder) {
789 this.collectionGroupBuilder = collectionGroupBuilder;
790 }
791
792 /**
793 * @param showHideInactiveButton the showHideInactiveButton to set
794 */
795 public void setShowHideInactiveButton(boolean showHideInactiveButton) {
796 this.showHideInactiveButton = showHideInactiveButton;
797 }
798
799 /**
800 * @return the showHideInactiveButton
801 */
802 public boolean isShowHideInactiveButton() {
803 return showHideInactiveButton;
804 }
805
806 }