Coverage Report - org.kuali.student.common.ui.client.configurable.mvc.multiplicity.MultiplicityGroup
 
Classes in this File Line Coverage Branch Coverage Complexity
MultiplicityGroup
0%
0/211
0%
0/78
1.825
MultiplicityGroup$1
0%
0/5
N/A
1.825
MultiplicityGroup$2
0%
0/3
N/A
1.825
MultiplicityGroup$3
0%
0/3
N/A
1.825
MultiplicityGroup$4
0%
0/3
N/A
1.825
MultiplicityGroup$ConditionChoices
0%
0/41
0%
0/4
1.825
MultiplicityGroup$SwappableFieldsHelper
0%
0/43
0%
0/20
1.825
 
 1  
 /**
 2  
  * Copyright 2010 The Kuali Foundation Licensed under the
 3  
  * Educational Community License, Version 2.0 (the "License"); you may
 4  
  * not use this file except in compliance with the License. You may
 5  
  * obtain a copy of the License at
 6  
  * <p/>
 7  
  * http://www.osedu.org/licenses/ECL-2.0
 8  
  * <p/>
 9  
  * Unless required by applicable law or agreed to in writing,
 10  
  * software distributed under the License is distributed on an "AS IS"
 11  
  * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 12  
  * or implied. See the License for the specific language governing
 13  
  * permissions and limitations under the License.
 14  
  * <p/>
 15  
  */
 16  
 package org.kuali.student.common.ui.client.configurable.mvc.multiplicity;
 17  
 
 18  
 import java.util.ArrayList;
 19  
 import java.util.HashMap;
 20  
 import java.util.List;
 21  
 import java.util.Map;
 22  
 import java.util.Set;
 23  
 import java.util.Map.Entry;
 24  
 
 25  
 import org.kuali.student.common.ui.client.configurable.mvc.FieldDescriptor;
 26  
 import org.kuali.student.common.ui.client.configurable.mvc.binding.ModelWidgetBinding;
 27  
 import org.kuali.student.common.ui.client.configurable.mvc.sections.BaseSection;
 28  
 import org.kuali.student.common.ui.client.configurable.mvc.sections.GroupSection;
 29  
 import org.kuali.student.common.ui.client.configurable.mvc.sections.MultiplicitySection;
 30  
 import org.kuali.student.common.ui.client.configurable.mvc.sections.Section;
 31  
 import org.kuali.student.common.ui.client.configurable.mvc.sections.SwapSection;
 32  
 import org.kuali.student.common.ui.client.configurable.mvc.sections.VerticalSection;
 33  
 import org.kuali.student.common.ui.client.mvc.Callback;
 34  
 import org.kuali.student.common.ui.client.mvc.DataModel;
 35  
 import org.kuali.student.common.ui.client.widgets.KSButton;
 36  
 import org.kuali.student.common.ui.client.widgets.KSButtonAbstract.ButtonStyle;
 37  
 import org.kuali.student.common.ui.client.widgets.ListOfStringWidget;
 38  
 import org.kuali.student.common.ui.client.widgets.list.KSRadioButtonList;
 39  
 import org.kuali.student.common.ui.client.widgets.list.KSSelectItemWidgetAbstract;
 40  
 import org.kuali.student.common.ui.client.widgets.list.ListItems;
 41  
 import org.kuali.student.common.ui.client.widgets.list.SelectionChangeEvent;
 42  
 import org.kuali.student.common.ui.client.widgets.list.SelectionChangeHandler;
 43  
 import org.kuali.student.common.ui.client.widgets.list.impl.KSRadioButtonListImpl;
 44  
 import org.kuali.student.common.ui.client.widgets.list.impl.SimpleListItems;
 45  
 import org.kuali.student.common.ui.client.widgets.search.KSPicker;
 46  
 import org.kuali.student.core.assembly.data.Data;
 47  
 import org.kuali.student.core.assembly.data.MetadataInterrogator;
 48  
 import org.kuali.student.core.assembly.data.QueryPath;
 49  
 
 50  
 import com.google.gwt.core.client.GWT;
 51  
 import com.google.gwt.event.dom.client.BlurHandler;
 52  
 import com.google.gwt.event.dom.client.ClickEvent;
 53  
 import com.google.gwt.event.dom.client.ClickHandler;
 54  
 import com.google.gwt.event.dom.client.FocusHandler;
 55  
 import com.google.gwt.event.shared.HandlerRegistration;
 56  
 import com.google.gwt.user.client.ui.Composite;
 57  
 import com.google.gwt.user.client.ui.FlowPanel;
 58  
 import com.google.gwt.user.client.ui.Widget;
 59  
 
 60  
 
 61  0
 public class MultiplicityGroup extends Composite {
 62  
 
 63  
     private MultiplicityConfiguration config;
 64  
 
 65  0
     private List<MultiplicityGroupItem> items = new ArrayList<MultiplicityGroupItem>();
 66  0
     private List<MultiplicityGroupItem> removed = new ArrayList<MultiplicityGroupItem>();
 67  
 
 68  0
     private FlowPanel mainPanel = new FlowPanel();
 69  0
     private FlowPanel itemsPanel = new FlowPanel();
 70  0
     private boolean loaded = false;
 71  0
     private int itemCount = 0;
 72  
     private String parentPath;
 73  0
     private boolean isDirty = false;
 74  
 
 75  
     private Map<SwapCompositeCondition, List<SwapCompositeConditionFieldConfig>> swappableFieldsDefinition;
 76  
     private List<String> deletionParentKeys;
 77  
 
 78  0
     public MultiplicityGroup() {
 79  0
     }
 80  
     
 81  
     public MultiplicityGroup(MultiplicityConfiguration config, 
 82  
             Map<SwapCompositeCondition, List<SwapCompositeConditionFieldConfig>> swappableFieldsDefinition,
 83  0
             List<String> deletionParentKeys) {
 84  0
         this.config = config;
 85  0
         initWidget(mainPanel);
 86  0
         this.swappableFieldsDefinition = swappableFieldsDefinition;
 87  0
         this.deletionParentKeys = deletionParentKeys;
 88  0
     }
 89  
 
 90  
 
 91  
     /**  
 92  
      * Creates an instance of a MultiplicityGroup based on the options in the MultiplicityConfiguration
 93  
      *
 94  
      * A MultiplicityGroup uses GroupSection to display data in a variable grid.  May be multiple rows and multiple fields per row based on
 95  
      * the defs in the MultiplicityConfiguration.
 96  
      *
 97  
      * May contain one or more MultiplicityItemSections based on user action, dictionary defs or data found in the model.
 98  
      *
 99  
      * @param config
 100  
      */
 101  0
     public MultiplicityGroup(MultiplicityConfiguration config){
 102  0
         this.config = config;
 103  0
         initWidget(mainPanel);
 104  0
     }
 105  
 
 106  0
     protected Callback<MultiplicityGroupItem> removeCallback = new Callback<MultiplicityGroupItem>(){
 107  
 
 108  
         public void exec(MultiplicityGroupItem itemToRemove) {
 109  0
             itemToRemove.setDeleted(true);
 110  0
             removed.add(itemToRemove);
 111  0
             itemsPanel.remove(itemToRemove);
 112  0
         }
 113  
     };
 114  
 
 115  
     public void onLoad() {
 116  0
         if (!loaded) {
 117  0
             mainPanel.add(itemsPanel);
 118  
 
 119  0
             if(config.isUpdateable()){
 120  0
                 Widget addWidget = generateAddWidget();
 121  0
                 mainPanel.add(addWidget);
 122  
             }
 123  
 
 124  0
             loaded = true;
 125  
         }
 126  
 
 127  0
         if (!loaded || itemCount == 0){
 128  0
                 Integer minOccurs = MetadataInterrogator.getLargestMinOccurs(config.getMetaData());
 129  0
                 if (minOccurs != null) {
 130  0
                     for (int i=0; i < minOccurs; i++){
 131  0
                             createItem();
 132  
                     }
 133  
                 }
 134  
 
 135  
         }
 136  0
     }
 137  
 
 138  
     private Widget generateAddWidget() {
 139  
             KSButton addWidget;
 140  0
             if(config.getStyleType() == MultiplicityConfiguration.StyleType.TOP_LEVEL_GROUP){
 141  0
                     addWidget = new KSButton(config.getAddItemLabel(), ButtonStyle.FORM_LARGE);
 142  
             }
 143  
             else{
 144  0
                     addWidget = new KSButton(config.getAddItemLabel(), ButtonStyle.FORM_SMALL);
 145  
             }
 146  0
         addWidget.addClickHandler(new ClickHandler(){
 147  
             public void onClick(ClickEvent event) {
 148  0
                 createItem();
 149  0
             }
 150  
         });
 151  0
         return addWidget;
 152  
     }
 153  
 
 154  
     /**
 155  
      * This adds an empty item to the multiplicity group 
 156  
      *
 157  
      * @return
 158  
      */
 159  
         public MultiplicityGroupItem createItem(){
 160  
     
 161  0
                 itemCount++;
 162  
 
 163  0
                 MultiplicityGroupItem item = new MultiplicityGroupItem(config.getItemLabel() + " " + itemCount, config.getStyleType(), config.isUpdateable());
 164  
                 
 165  0
         Widget itemWidget = createWidget();
 166  
         
 167  0
             if (item != null){
 168  0
                     item.setItemKey(new Integer(itemCount -1));
 169  0
                     item.setItemWidget(itemWidget);
 170  0
                     item.setRemoveCallback(removeCallback);
 171  0
             } else if (itemWidget instanceof MultiplicityGroupItem){
 172  0
                     item = (MultiplicityGroupItem)itemWidget;
 173  0
                     item.setItemKey(new Integer(itemCount -1));
 174  
             }
 175  0
             items.add(item);
 176  0
             item.redraw();
 177  0
             itemsPanel.add(item);
 178  
 
 179  0
         return item;
 180  
         }
 181  
         
 182  
         public FlowPanel getItemsPanel() {
 183  0
             return itemsPanel;
 184  
         }
 185  
 
 186  
     private Widget createWidget() {
 187  
 
 188  0
                 GroupSection section = new GroupSection();
 189  0
         final SwappableFieldsHelper helper = new SwappableFieldsHelper();
 190  
         // helperFieldKeys maps the paths with asterisks into absolute paths
 191  0
         final Map<String, String> helperFieldKeys = new HashMap<String, String>();
 192  0
         SwapSection swapSection = null;
 193  
 
 194  
                 //TODO might want fields and nested multiplicities at the same time. Remove if/else
 195  
 
 196  0
                 if (config.getNestedConfig() != null) {
 197  0
             MultiplicitySection ms = new MultiplicitySection(config.getNestedConfig().copy());
 198  0
                         String p = config.getNestedConfig().getParentFd().getFieldKey().replace('*', Character.forDigit(itemCount-1, 10));
 199  0
                     ms.setParentPath(p);
 200  0
             section.addSection(ms);
 201  0
                 }
 202  
                 else {
 203  0
                         for (Integer row  : config.getFields().keySet()) {
 204  0
                                 List<MultiplicityFieldConfiguration> fieldConfigs = config.getFields().get(row);
 205  0
                                 for (MultiplicityFieldConfiguration fieldConfig : fieldConfigs) {
 206  
                     //TODO  Should copy widgets/bindings too?
 207  0
                     FieldDescriptor newfd = null;
 208  0
                     Widget fieldWidget = null;
 209  0
                     if (fieldConfig.getFieldWidgetInitializer() != null) {
 210  0
                         fieldWidget = fieldConfig.getFieldWidgetInitializer().getNewWidget();
 211  0
                         ModelWidgetBinding mwb = fieldConfig.getFieldWidgetInitializer()
 212  
                             .getModelWidgetBindingInstance();
 213  0
                         newfd = new FieldDescriptor(
 214  
                                 translatePath(fieldConfig.getFieldPath()), 
 215  
                                 fieldConfig.getMessageKeyInfo(), 
 216  
                                 fieldConfig.getMetadata(),
 217  
                                 fieldWidget);
 218  0
                         newfd.setWidgetBinding(mwb);
 219  0
                     } else {
 220  0
                         newfd = new FieldDescriptor(
 221  
                                 translatePath(fieldConfig.getFieldPath()), 
 222  
                                 fieldConfig.getMessageKeyInfo(), 
 223  
                                 fieldConfig.getMetadata());
 224  0
                         fieldWidget = newfd.getFieldWidget();
 225  
                     }
 226  0
                     newfd.getFieldElement().setRequired(fieldConfig.isRequired());
 227  0
                     section.addField(newfd);
 228  0
                     helperFieldKeys.put(fieldConfig.getFieldPath(), newfd.getFieldKey());
 229  
 
 230  
                     // add handlers to all select field that can be selected and triggers
 231  
                     // selection change event to notify the swap section to switch section.
 232  0
                     if (fieldWidget instanceof KSSelectItemWidgetAbstract) {
 233  0
                         ((KSSelectItemWidgetAbstract)fieldWidget).addSelectionChangeHandler(new SelectionChangeHandler() {
 234  
                             @Override
 235  
                             public void onSelectionChange(SelectionChangeEvent event) {
 236  0
                                 helper.updateFieldDisplay();
 237  0
                             }
 238  
                         });
 239  0
                     } else if (fieldWidget instanceof KSPicker) {
 240  0
                         Widget inputWidget = ((KSPicker)fieldWidget).getInputWidget();
 241  0
                         if (inputWidget instanceof KSSelectItemWidgetAbstract) {
 242  0
                             ((KSSelectItemWidgetAbstract)inputWidget).addSelectionChangeHandler(new SelectionChangeHandler() {
 243  
                                 @Override
 244  
                                 public void onSelectionChange(SelectionChangeEvent event) {
 245  0
                                     helper.updateFieldDisplay();
 246  0
                                 }
 247  
                             });
 248  
                         }
 249  
                     }
 250  0
                                 }
 251  0
                                 section.nextLine();
 252  0
                         }
 253  0
             if (swappableFieldsDefinition != null) {
 254  0
                 ConditionChoices conditionChoices = new ConditionChoices(
 255  
                         new ArrayList<SwapCompositeCondition>(
 256  
                                 swappableFieldsDefinition.keySet()));
 257  0
                 List<String> newDeletionParentKeys = null;
 258  0
                 swapSection = new SwapSection(conditionChoices);
 259  0
                 if (deletionParentKeys != null) {
 260  0
                     for (String deletionParentKey : deletionParentKeys) {
 261  0
                         newDeletionParentKeys = (newDeletionParentKeys == null)?
 262  
                                 new ArrayList<String>() : newDeletionParentKeys;
 263  0
                         newDeletionParentKeys.add(translatePath(deletionParentKey));
 264  
                     }
 265  
                 }
 266  0
                 swapSection.setDeletionParentKey(newDeletionParentKeys);
 267  0
                 helper.setConditionChoices(conditionChoices);
 268  
                 // go through swappableFieldsDefinition and create and add the fields
 269  
                 // into conditionSection
 270  0
                 for (Entry<SwapCompositeCondition, List<SwapCompositeConditionFieldConfig>> entry : swappableFieldsDefinition.entrySet()) {
 271  0
                     SwapCompositeCondition condition = entry.getKey();
 272  0
                     List<SwapCompositeConditionFieldConfig> fieldConfigs = entry.getValue();
 273  0
                     Section conditionSection = new VerticalSection();
 274  0
                     if (fieldConfigs != null) {
 275  0
                         for (SwapCompositeConditionFieldConfig conditionFieldConfig : fieldConfigs) {
 276  0
                             if (conditionFieldConfig.useMultiplicity()) {
 277  0
                                 MultiplicityConfiguration newSubMultiplicityConfig = 
 278  
                                     configSwappableMultiplicitySection(
 279  
                                             conditionFieldConfig.getMultiplicityConfiguration());
 280  0
                                 MultiplicitySection subMultiplicitySection = 
 281  
                                     new MultiplicitySection(newSubMultiplicityConfig);
 282  0
                                 conditionSection.addSection(subMultiplicitySection);
 283  0
                             } else {
 284  0
                                 MultiplicityFieldConfiguration fieldConfig = 
 285  
                                     conditionFieldConfig.getMultiplicityFieldConfiguration();
 286  0
                                 FieldDescriptor concreteFieldDescriptor = new FieldDescriptor(
 287  
                                         translatePath(fieldConfig.getFieldPath()),
 288  
                                         fieldConfig.getMessageKeyInfo(),
 289  
                                         fieldConfig.getMetadata());
 290  0
                                 concreteFieldDescriptor.getFieldElement().setRequired(fieldConfig.isRequired());
 291  0
                                 if (fieldConfig.getFieldWidgetInitializer() != null) {
 292  0
                                     Widget fieldWidget = fieldConfig.getFieldWidgetInitializer().getNewWidget();
 293  0
                                     ModelWidgetBinding mwb = fieldConfig.getFieldWidgetInitializer()
 294  
                                         .getModelWidgetBindingInstance();
 295  0
                                     concreteFieldDescriptor.setFieldWidget(fieldWidget);
 296  0
                                     if(fieldWidget instanceof ListOfStringWidget){
 297  0
                                             ((ListOfStringWidget)fieldWidget).setFd(concreteFieldDescriptor);
 298  
                                     }
 299  
                                     
 300  0
                                     concreteFieldDescriptor.setWidgetBinding(mwb);
 301  
                                 }
 302  0
                                 conditionSection.addField(concreteFieldDescriptor);
 303  0
                                 helperFieldKeys.put(fieldConfig.getFieldPath(), translatePath(fieldConfig.getFieldPath()));
 304  0
                             }
 305  
                         }
 306  
                     }
 307  0
                     swapSection.addSection(conditionSection, condition.getConditionId());
 308  0
                 }
 309  0
                 section.addWidget(conditionChoices);
 310  0
                 section.addSection(swapSection);
 311  0
                 helper.setSwapSection(swapSection);
 312  
             }
 313  
             
 314  0
             helper.setParentSection(section);
 315  0
             helper.setSwappableFieldsDefinition(swappableFieldsDefinition);
 316  0
             helper.setHelperFieldKeys(helperFieldKeys);
 317  
         }
 318  0
                 return section;
 319  
         }
 320  
 
 321  
     public MultiplicityConfiguration configSwappableMultiplicitySection(MultiplicityConfiguration origConfig) {
 322  0
         MultiplicityConfiguration newSubMultiplicityConfig =
 323  
             origConfig.copy();
 324  
 
 325  0
         FieldDescriptor parentFd = origConfig.getParentFd();
 326  0
         FieldDescriptor subMultParentConfig = 
 327  
             new FieldDescriptor(
 328  
                     translatePath(parentFd.getFieldKey()),
 329  
                     parentFd.getMessageKey(),
 330  
                     parentFd.getMetadata());
 331  0
         subMultParentConfig.getFieldElement().setRequired(parentFd.getFieldElement().isRequired());
 332  0
         newSubMultiplicityConfig.setParent(subMultParentConfig);
 333  0
         Map<Integer, List<MultiplicityFieldConfiguration>> fieldConfigsMap = newSubMultiplicityConfig.getFields();
 334  0
         Map<Integer, List<MultiplicityFieldConfiguration>> newFieldsMap = new HashMap<Integer, List<MultiplicityFieldConfiguration>>();
 335  0
         int lineCounter = 0;
 336  0
         if (fieldConfigsMap != null) {
 337  0
             for (List<MultiplicityFieldConfiguration> fieldConfigsInLine : fieldConfigsMap.values()) {
 338  0
                 List<MultiplicityFieldConfiguration> newFieldConfigs = new ArrayList<MultiplicityFieldConfiguration>();
 339  0
                 for (MultiplicityFieldConfiguration fieldConfig : fieldConfigsInLine) {
 340  0
                     String configParentKey = (parentFd.getFieldKey() == null)? "" : parentFd.getFieldKey();
 341  0
                     String configFieldKey = (fieldConfig.getFieldPath() == null)? "" : fieldConfig.getFieldPath();
 342  0
                     String trimmedFieldKey = null;
 343  0
                     MultiplicityFieldConfiguration newFieldConfig = null;
 344  0
                     trimmedFieldKey = configFieldKey.substring(configParentKey.length());
 345  
                     
 346  0
                     QueryPath fieldPath = QueryPath.concat(subMultParentConfig.getFieldKey(), 
 347  
                             trimmedFieldKey);;
 348  0
                     newFieldConfig = new MultiplicityFieldConfiguration(
 349  
                             fieldPath.toString(), fieldConfig.getMessageKeyInfo(), fieldConfig.getMetadata(),
 350  
                             fieldConfig.getFieldWidgetInitializer());
 351  0
                     newFieldConfig.setRequired(fieldConfig.isRequired());
 352  0
                     newFieldConfigs.add(newFieldConfig);
 353  
                     
 354  0
                 }
 355  0
                 newFieldsMap.put(Integer.valueOf(lineCounter), newFieldConfigs);
 356  0
                 lineCounter++;
 357  0
             }
 358  
         }
 359  0
         newSubMultiplicityConfig.setFields(newFieldsMap);
 360  
         
 361  0
         return newSubMultiplicityConfig;
 362  
     }
 363  
 
 364  
     public String translatePath(String path) {
 365  
         String fieldPath;
 366  0
         if (parentPath != null) {
 367  0
             QueryPath parent = QueryPath.concat(parentPath);
 368  0
             int i = parent.size();
 369  
 
 370  0
             QueryPath subPath = QueryPath.concat(path);
 371  0
             String itemPath =  subPath.subPath(i, subPath.size()).toString();
 372  
 
 373  0
             QueryPath qp = QueryPath.concat(parentPath, itemPath);
 374  0
             fieldPath = qp.toString();
 375  0
         }
 376  
         else {
 377  0
             fieldPath = path;
 378  
         }
 379  
 
 380  0
         fieldPath = fieldPath.replace('*', Character.forDigit(itemCount-1, 10));
 381  0
         return fieldPath;
 382  
     }
 383  
 
 384  
 
 385  
     public void clear(){
 386  0
         itemsPanel.clear();
 387  0
         items.clear();
 388  0
         removed.clear();
 389  0
         itemCount = 0;
 390  0
     }
 391  
 
 392  
     public void redraw(){
 393  0
         for (MultiplicityGroupItem item:items){
 394  0
             item.redraw();
 395  
         }
 396  0
     }
 397  
 
 398  
     public void incrementItemKey(){
 399  0
                 itemCount++;
 400  0
         }
 401  
 
 402  
     /**
 403  
          * This returns the index key for the model for the item currently being added by addItem
 404  
          * This is useful, if you need to refer to the index in the createItem method
 405  
          * @return
 406  
          */
 407  
         public int getAddItemKey(){
 408  0
                 return itemCount-1;
 409  
         }
 410  
 
 411  
 
 412  
     public List<MultiplicityGroupItem> getItems() {
 413  0
         return items;
 414  
     }
 415  
 
 416  
     public List<MultiplicityGroupItem> getRemovedItems() {
 417  0
         return removed;
 418  
     }
 419  
 
 420  
         public int getItemCount() {
 421  0
                 return itemCount;
 422  
         }
 423  
         
 424  
         public void setItemCount(int itemCount) {
 425  0
                 this.itemCount = itemCount;
 426  0
         }
 427  
 
 428  
         public String getParentPath() {
 429  0
                 return parentPath;
 430  
         }
 431  
 
 432  
     /**
 433  
      * Allows the parentpath for this instance to be set, e.g. course/formats/0/activities
 434  
      * 
 435  
      * @param parentPath
 436  
      */
 437  
     public void setParentPath(String parentPath) {
 438  0
                 this.parentPath = parentPath;
 439  0
         }
 440  
 
 441  
         public MultiplicityConfiguration getConfig() {
 442  0
                 return config;
 443  
         }
 444  
 
 445  
         public void setConfig(MultiplicityConfiguration config) {
 446  0
                 this.config = config;
 447  0
         }   
 448  
         
 449  
     public void resetDirtyFlags() {
 450  0
             isDirty = false;
 451  0
                 for (MultiplicityGroupItem item:items){
 452  0
                         item.resetDirtyFlags();
 453  0
                         Widget itemWidget = item.getItemWidget();
 454  0
                         if (itemWidget instanceof BaseSection){
 455  0
                                 ((BaseSection)itemWidget).resetDirtyFlags();
 456  
                         }
 457  0
                 }
 458  0
     }
 459  
         
 460  
         public boolean isDirty(){
 461  0
                 for (MultiplicityGroupItem item:items){
 462  0
                         if (item.isDirty()){
 463  0
                                 isDirty = true;
 464  0
                                 break;
 465  
                         } else {
 466  0
                                 Widget itemWidget = item.getItemWidget();
 467  0
                                 if (itemWidget instanceof BaseSection && ((BaseSection)itemWidget).isDirty()){
 468  0
                                         isDirty = true;
 469  0
                                         break;
 470  
                                 }
 471  0
                         }
 472  
                 }
 473  0
                 return isDirty;
 474  
         }
 475  
         
 476  
         public void setIsDirty(boolean dirty){
 477  0
                 isDirty = dirty;
 478  0
         }
 479  
         
 480  
     public class ConditionChoices extends KSRadioButtonList{
 481  0
         private KSRadioButtonListImpl selectItemWidget = GWT.create(KSRadioButtonListImpl.class);
 482  0
         public ConditionChoices(List<SwapCompositeCondition> conditions){
 483  0
             SimpleListItems choices = new SimpleListItems();
 484  0
             if (conditions != null) {
 485  0
                 for (SwapCompositeCondition condition : conditions) {
 486  0
                     choices.addItem(condition.getConditionId(), condition.getConditionId());
 487  
                 }
 488  
             }
 489  0
             selectItemWidget.setListItems(choices);
 490  0
         }
 491  
 
 492  
         /**
 493  
          * @see org.kuali.student.common.ui.client.widgets.list.KSSelectItemWidgetAbstract#deSelectItem(java.lang.String)
 494  
          */
 495  
         public void deSelectItem(String id) {
 496  0
             selectItemWidget.deSelectItem(id);  
 497  0
         }
 498  
 
 499  
         /**
 500  
          * @see org.kuali.student.common.ui.client.widgets.list.KSSelectItemWidgetAbstract#getSelectedItems()
 501  
          */
 502  
         public List<String> getSelectedItems() {
 503  0
             return selectItemWidget.getSelectedItems();
 504  
         }
 505  
 
 506  
         /**
 507  
          * @see org.kuali.student.common.ui.client.widgets.list.KSSelectItemWidgetAbstract#selectItem(java.lang.String)
 508  
          */
 509  
         public void selectItem(String id) {
 510  0
             selectItemWidget.selectItem(id);
 511  0
         }
 512  
 
 513  
         public void setListItems(ListItems listItems) {
 514  0
             selectItemWidget.setListItems(listItems);      
 515  0
         }
 516  
 
 517  
         /**
 518  
          * Use to set number of columns to use when displaying list
 519  
          * 
 520  
          */
 521  
         public void setColumnSize(int cols){
 522  0
             selectItemWidget.setColumnSize(cols);
 523  0
         }
 524  
             
 525  0
         public void setMultipleSelect(boolean isMultipleSelect) {}
 526  
 
 527  
         /**
 528  
          * This overridden method is not used
 529  
          * 
 530  
          * @see org.kuali.student.common.ui.client.widgets.list.KSSelectItemWidgetAbstract#onLoad()
 531  
          */
 532  
         @Override
 533  0
         public void onLoad() {}
 534  
        
 535  
         public HandlerRegistration addSelectionChangeHandler(SelectionChangeHandler handler) {
 536  0
             return selectItemWidget.addSelectionChangeHandler(handler);
 537  
         }
 538  
 
 539  
         public ListItems getListItems() {
 540  0
             return selectItemWidget.getListItems();
 541  
         }
 542  
 
 543  
         public String getName() {
 544  0
             return selectItemWidget.getName();
 545  
         }
 546  
 
 547  
         public void setName(String name) {
 548  0
             selectItemWidget.setName(name);
 549  0
         }
 550  
 
 551  
         @Override
 552  
         public void setEnabled(boolean b) {
 553  0
             selectItemWidget.setEnabled(b);
 554  0
         }
 555  
 
 556  
         @Override
 557  
         public boolean isEnabled() {
 558  0
             return selectItemWidget.isEnabled();
 559  
         }
 560  
 
 561  
         @Override
 562  
         public boolean isMultipleSelect() {
 563  0
             return selectItemWidget.isMultipleSelect();
 564  
         }
 565  
 
 566  
         @Override
 567  
         public void redraw() {
 568  0
             selectItemWidget.redraw();
 569  0
         }
 570  
 
 571  
         @Override
 572  
         public void clear() {
 573  0
             selectItemWidget.clear();
 574  0
         }
 575  
 
 576  
         @Override
 577  
         public HandlerRegistration addBlurHandler(BlurHandler handler) {
 578  0
             return selectItemWidget.addBlurHandler(handler);
 579  
         }
 580  
 
 581  
         @Override
 582  
         public HandlerRegistration addFocusHandler(FocusHandler handler) {
 583  0
             return selectItemWidget.addFocusHandler(handler);
 584  
         }
 585  
 
 586  
         public void addWidgetReadyCallback(Callback<Widget> callback) {
 587  0
             selectItemWidget.addWidgetReadyCallback(callback);
 588  0
         }
 589  
 
 590  
         public boolean isInitialized() {
 591  0
             return selectItemWidget.isInitialized();
 592  
         }
 593  
 
 594  
         public void setInitialized(boolean initialized) {
 595  0
             selectItemWidget.setInitialized(initialized);
 596  0
         }
 597  
         
 598  
         /**
 599  
          * By default if the list items used by the checkbox has multiple attributes, the checkbox
 600  
          * generated will display all attributes as columns. Set this property to true if this
 601  
          * behavior is not desired.
 602  
          * 
 603  
          * @param ignoreMultiple
 604  
          */
 605  
         public void setIgnoreMultipleAttributes(boolean ignoreMultiple){
 606  0
             selectItemWidget.setIgnoreMultipleAttributes(ignoreMultiple);
 607  0
         }
 608  
     }
 609  
 
 610  0
     public class SwappableFieldsHelper {
 611  
         
 612  
         private GroupSection parentSection;
 613  0
         private Map<SwapCompositeCondition, List<SwapCompositeConditionFieldConfig>> swappableFieldsDefinition = 
 614  
             new HashMap<SwapCompositeCondition, List<SwapCompositeConditionFieldConfig>>();
 615  
         private Map<String, String> helperFieldKeys;
 616  
         private ConditionChoices conditionChoices;
 617  
         private SwapSection swapSection;
 618  
         public void updateFieldDisplay() {
 619  0
             Set<Entry<SwapCompositeCondition, List<SwapCompositeConditionFieldConfig>>> entries =
 620  
                 (swappableFieldsDefinition == null)? null : swappableFieldsDefinition.entrySet();
 621  0
             if (parentSection == null) {
 622  0
                 throw new RuntimeException("parentSection cannot be null");
 623  
             }
 624  0
             if (entries != null) {
 625  0
                 for (Entry<SwapCompositeCondition, List<SwapCompositeConditionFieldConfig>> entry : entries) {
 626  0
                     SwapCompositeCondition condition = entry.getKey();
 627  0
                     if (condition.evaluate(parentSection, helperFieldKeys)) {
 628  
                         // clear values in the widgets
 629  0
                         List<Section> deletedSections = swapSection.getDeletedSections();
 630  0
                         List<FieldDescriptor> fields = null;
 631  0
                         if (deletedSections != null) {
 632  0
                             for (Section deletedSection : deletedSections) {
 633  0
                                 fields = (fields == null)? new ArrayList() : fields;
 634  0
                                 fields.addAll(deletedSection.getFields());
 635  
                             }
 636  
                         }
 637  0
                         if (fields != null) {
 638  0
                             for (FieldDescriptor field : fields) {
 639  0
                                 Widget fieldWidget = field.getFieldWidget();
 640  0
                                 DataModel dataModel = new DataModel();
 641  0
                                 dataModel.setRoot(new Data());
 642  0
                                 ((ModelWidgetBinding)field.getModelWidgetBinding())
 643  
                                 .setWidgetValue(fieldWidget, 
 644  
                                         dataModel, field.getFieldKey());
 645  0
                             }
 646  
                         }
 647  
                         // trigger SectionChangeEvent to notify the selection widget
 648  
                         // that the selected condition has changed.
 649  0
                         SelectionChangeEvent selectionChangeEvent =
 650  
                             new SelectionChangeEvent(conditionChoices);
 651  0
                         selectionChangeEvent.setUserInitiated(true);
 652  0
                         conditionChoices.selectItem(condition.getConditionId());
 653  0
                         conditionChoices.fireEvent(selectionChangeEvent);
 654  
                     }
 655  0
                 }
 656  
             }
 657  0
         }
 658  
         public GroupSection getParentSection() {
 659  0
             return parentSection;
 660  
         }
 661  
         public void setParentSection(GroupSection parentSection) {
 662  0
             this.parentSection = parentSection;
 663  0
         }
 664  
         public Map<SwapCompositeCondition, List<SwapCompositeConditionFieldConfig>> getSwappableFieldsDefinition() {
 665  0
             return swappableFieldsDefinition;
 666  
         }
 667  
         public void setSwappableFieldsDefinition(Map<SwapCompositeCondition, List<SwapCompositeConditionFieldConfig>> swappableFieldsDefinition) {
 668  0
             this.swappableFieldsDefinition = swappableFieldsDefinition;
 669  0
         }
 670  
         public Map<String, String> getHelperFieldKeys() {
 671  0
             return helperFieldKeys;
 672  
         }
 673  
         public void setHelperFieldKeys(Map<String, String> helperFieldKeys) {
 674  0
             this.helperFieldKeys = helperFieldKeys;
 675  0
         }
 676  
         public ConditionChoices getConditionChoices() {
 677  0
             return conditionChoices;
 678  
         }
 679  
         public void setConditionChoices(ConditionChoices conditionChoices) {
 680  0
             this.conditionChoices = conditionChoices;
 681  0
         }
 682  
         public SwapSection getSwapSection() {
 683  0
             return swapSection;
 684  
         }
 685  
         public void setSwapSection(SwapSection swapSection) {
 686  0
             this.swapSection = swapSection;
 687  0
         }
 688  
     }
 689  
 
 690  
 }