001/**
002 * Copyright 2005-2016 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.krad.uif.container;
017
018import java.util.ArrayList;
019import java.util.List;
020
021import org.apache.commons.lang.StringUtils;
022import org.kuali.rice.core.api.exception.RiceRuntimeException;
023import org.kuali.rice.krad.uif.UifConstants;
024import org.kuali.rice.krad.uif.UifParameters;
025import org.kuali.rice.krad.uif.component.BindingInfo;
026import org.kuali.rice.krad.uif.component.Component;
027import org.kuali.rice.krad.uif.component.ComponentSecurity;
028import org.kuali.rice.krad.uif.component.DataBinding;
029import org.kuali.rice.krad.uif.field.ActionField;
030import org.kuali.rice.krad.uif.field.DataField;
031import org.kuali.rice.krad.uif.field.DataFieldSecurity;
032import org.kuali.rice.krad.uif.field.Field;
033import org.kuali.rice.krad.uif.field.LabelField;
034import org.kuali.rice.krad.uif.util.ComponentUtils;
035import org.kuali.rice.krad.uif.view.View;
036import org.kuali.rice.krad.uif.widget.QuickFinder;
037
038/**
039 * Group that holds a collection of objects and configuration for presenting the
040 * collection in the UI. Supports functionality such as add line, line actions,
041 * and nested collections.
042 *
043 * <p>
044 * Note the standard header/footer can be used to give a header to the
045 * collection as a whole, or to provide actions that apply to the entire
046 * collection
047 * </p>
048 *
049 * <p>
050 * For binding purposes the binding path of each row field is indexed. The name
051 * property inherited from <code>ComponentBase</code> is used as the collection
052 * name. The collectionObjectClass property is used to lookup attributes from
053 * the data dictionary.
054 * </p>
055 *
056 * @author Kuali Rice Team (rice.collab@kuali.org)
057 */
058public class CollectionGroup extends Group implements DataBinding {
059    private static final long serialVersionUID = -6496712566071542452L;
060
061    private Class<?> collectionObjectClass;
062
063    private String propertyName;
064    private BindingInfo bindingInfo;
065
066    private boolean renderAddLine;
067    private String addLinePropertyName;
068    private BindingInfo addLineBindingInfo;
069    private LabelField addLineLabelField;
070    private List<? extends Component> addLineFields;
071    private List<ActionField> addLineActionFields;
072
073    private boolean renderLineActions;
074    private List<ActionField> actionFields;
075
076    private boolean renderSelectField;
077    private String selectPropertyName;
078
079    private QuickFinder collectionLookup;
080
081    private boolean showHideInactiveButton;
082    private boolean showInactive;
083    private CollectionFilter activeCollectionFilter;
084    private List<CollectionFilter> filters;
085
086    private List<CollectionGroup> subCollections;
087    private String subCollectionSuffix;
088
089    private CollectionGroupBuilder collectionGroupBuilder;
090
091    public CollectionGroup() {
092        renderAddLine = true;
093        renderLineActions = true;
094        showInactive = false;
095        showHideInactiveButton = true;
096        renderSelectField = false;
097
098        filters = new ArrayList<CollectionFilter>();
099        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    public CollectionGroupSecurity getCollectionGroupSecurity() {
746        return (CollectionGroupSecurity) super.getComponentSecurity();
747    }
748
749    /**
750     * Override to assert a {@link CollectionGroupSecurity} instance is set
751     *
752     * @param componentSecurity - instance of CollectionGroupSecurity
753     */
754    @Override
755    public void setComponentSecurity(ComponentSecurity componentSecurity) {
756        if (!(componentSecurity instanceof CollectionGroupSecurity)) {
757            throw new RiceRuntimeException(
758                    "Component security for CollectionGroup should be instance of CollectionGroupSecurity");
759        }
760
761        super.setComponentSecurity(componentSecurity);
762    }
763
764    @Override
765    protected Class<? extends ComponentSecurity> getComponentSecurityClass() {
766        return CollectionGroupSecurity.class;
767    }
768
769    /**
770     * <code>CollectionGroupBuilder</code> instance that will build the
771     * components dynamically for the collection instance
772     *
773     * @return CollectionGroupBuilder instance
774     */
775    public CollectionGroupBuilder getCollectionGroupBuilder() {
776        if (this.collectionGroupBuilder == null) {
777            this.collectionGroupBuilder = new CollectionGroupBuilder();
778        }
779        return this.collectionGroupBuilder;
780    }
781
782    /**
783     * Setter for the collection group building instance
784     *
785     * @param collectionGroupBuilder
786     */
787    public void setCollectionGroupBuilder(CollectionGroupBuilder collectionGroupBuilder) {
788        this.collectionGroupBuilder = collectionGroupBuilder;
789    }
790
791    /**
792     * @param showHideInactiveButton the showHideInactiveButton to set
793     */
794    public void setShowHideInactiveButton(boolean showHideInactiveButton) {
795        this.showHideInactiveButton = showHideInactiveButton;
796    }
797
798    /**
799     * @return the showHideInactiveButton
800     */
801    public boolean isShowHideInactiveButton() {
802        return showHideInactiveButton;
803    }
804
805}