| 1 |  |  package org.kuali.student.lum.common.client.widgets; | 
  | 2 |  |   | 
  | 3 |  |  import java.util.ArrayList; | 
  | 4 |  |  import java.util.HashMap; | 
  | 5 |  |  import java.util.List; | 
  | 6 |  |  import java.util.Map; | 
  | 7 |  |  import java.util.Set; | 
  | 8 |  |   | 
  | 9 |  |  import org.kuali.student.common.assembly.data.Data; | 
  | 10 |  |  import org.kuali.student.common.assembly.data.LookupMetadata; | 
  | 11 |  |  import org.kuali.student.common.assembly.data.LookupParamMetadata; | 
  | 12 |  |  import org.kuali.student.common.assembly.data.Metadata; | 
  | 13 |  |  import org.kuali.student.common.assembly.data.QueryPath; | 
  | 14 |  |  import org.kuali.student.common.assembly.data.Data.DataValue; | 
  | 15 |  |  import org.kuali.student.common.assembly.data.Data.Value; | 
  | 16 |  |  import org.kuali.student.common.search.dto.SearchParam; | 
  | 17 |  |  import org.kuali.student.common.search.dto.SearchRequest; | 
  | 18 |  |  import org.kuali.student.common.ui.client.configurable.mvc.FieldDescriptor; | 
  | 19 |  |  import org.kuali.student.common.ui.client.configurable.mvc.WidgetConfigInfo; | 
  | 20 |  |  import org.kuali.student.common.ui.client.configurable.mvc.binding.HasDataValueBinding; | 
  | 21 |  |  import org.kuali.student.common.ui.client.configurable.mvc.binding.ModelWidgetBindingSupport; | 
  | 22 |  |  import org.kuali.student.common.ui.client.configurable.mvc.sections.Section; | 
  | 23 |  |  import org.kuali.student.common.ui.client.configurable.mvc.sections.VerticalSection; | 
  | 24 |  |  import org.kuali.student.common.ui.client.configurable.mvc.views.VerticalSectionView; | 
  | 25 |  |  import org.kuali.student.common.ui.client.mvc.Callback; | 
  | 26 |  |  import org.kuali.student.common.ui.client.mvc.DataModel; | 
  | 27 |  |  import org.kuali.student.common.ui.client.mvc.DataModelDefinition; | 
  | 28 |  |  import org.kuali.student.common.ui.client.mvc.HasDataValue; | 
  | 29 |  |  import org.kuali.student.common.ui.client.widgets.KSDropDown; | 
  | 30 |  |  import org.kuali.student.common.ui.client.widgets.KSItemLabel; | 
  | 31 |  |  import org.kuali.student.common.ui.client.widgets.KSLabel; | 
  | 32 |  |  import org.kuali.student.common.ui.client.widgets.field.layout.element.MessageKeyInfo; | 
  | 33 |  |  import org.kuali.student.common.ui.client.widgets.layout.VerticalFlowPanel; | 
  | 34 |  |  import org.kuali.student.common.ui.client.widgets.list.KSSelectedList; | 
  | 35 |  |  import org.kuali.student.common.ui.client.widgets.list.SelectionChangeEvent; | 
  | 36 |  |  import org.kuali.student.common.ui.client.widgets.list.SelectionChangeHandler; | 
  | 37 |  |  import org.kuali.student.common.ui.client.widgets.list.impl.SimpleListItems; | 
  | 38 |  |  import org.kuali.student.common.ui.client.widgets.menus.KSListPanel; | 
  | 39 |  |  import org.kuali.student.common.ui.client.widgets.progress.BlockingTask; | 
  | 40 |  |  import org.kuali.student.common.ui.client.widgets.progress.KSBlockingProgressIndicator; | 
  | 41 |  |  import org.kuali.student.common.ui.client.widgets.search.KSPicker; | 
  | 42 |  |  import org.kuali.student.lum.lu.dto.MembershipQueryInfo; | 
  | 43 |  |   | 
  | 44 |  |  import com.google.gwt.dom.client.Style; | 
  | 45 |  |  import com.google.gwt.event.dom.client.ClickEvent; | 
  | 46 |  |  import com.google.gwt.event.dom.client.ClickHandler; | 
  | 47 |  |  import com.google.gwt.event.logical.shared.CloseEvent; | 
  | 48 |  |  import com.google.gwt.event.logical.shared.CloseHandler; | 
  | 49 |  |  import com.google.gwt.event.shared.HandlerRegistration; | 
  | 50 |  |  import com.google.gwt.user.client.Timer; | 
  | 51 |  |  import com.google.gwt.user.client.Window; | 
  | 52 |  |  import com.google.gwt.user.client.ui.HTML; | 
  | 53 |  |  import com.google.gwt.user.client.ui.Panel; | 
  | 54 |  |  import com.google.gwt.user.client.ui.Widget; | 
  | 55 |  |   | 
  | 56 | 0 |  public class CluSetEditorWidget extends VerticalSectionView { | 
  | 57 |  |   | 
  | 58 | 0 |      private List<KSSelectedListPanelPair> selectedListPanelPairs = new ArrayList<KSSelectedListPanelPair>(); | 
  | 59 |  |      private DataModelDefinition modelDefinition; | 
  | 60 |  |   | 
  | 61 | 0 |      private final Map<String, HandlerRegistration> showCluRangeDetailsHandlerRegs = new HashMap<String, HandlerRegistration>(); | 
  | 62 | 0 |      private List<KSItemLabelPanelPair> itemLabelPanelPairs = new ArrayList<KSItemLabelPanelPair>(); | 
  | 63 |  |      private String cluSetType; | 
  | 64 |  |      private String metadataId; | 
  | 65 | 0 |      private static Map<String, DataModelDefinition> modelDefinitionCache = new HashMap<String, DataModelDefinition>(); | 
  | 66 | 0 |      private BlockingTask initializeTask = new BlockingTask("Initializing"); | 
  | 67 |  |      private boolean singularCluOnly; | 
  | 68 |  |      private KSSelectedList approvedClusSelection; | 
  | 69 |  |       | 
  | 70 | 0 |      private enum CluSetManagementField { | 
  | 71 | 0 |          APPROVED, PROPOSED, CLUSETS, RANGE | 
  | 72 |  |      } | 
  | 73 |  |   | 
  | 74 |  |      public CluSetEditorWidget(CluSetRetriever cluSetRetriever, Enum<?> viewEnum, | 
  | 75 |  |              String name, String modelId, boolean showTitle, | 
  | 76 |  |              final Callback<Boolean> onReady, String cluSetType, boolean singularCluOnly) { | 
  | 77 | 0 |          super(viewEnum, name, modelId, showTitle); | 
  | 78 | 0 |          this.cluSetType = cluSetType; | 
  | 79 | 0 |          this.singularCluOnly = singularCluOnly; | 
  | 80 | 0 |          if (cluSetType != null && cluSetType.equals("kuali.cluSet.type.Program")) { | 
  | 81 | 0 |              this.metadataId = "programSet"; | 
  | 82 |  |          } else { | 
  | 83 | 0 |              this.metadataId = "courseSet"; | 
  | 84 |  |          } | 
  | 85 | 0 |          KSBlockingProgressIndicator.addTask(initializeTask); | 
  | 86 | 0 |          if (modelDefinitionCache.get(metadataId) == null) { | 
  | 87 | 0 |              cluSetRetriever.getMetadata(metadataId, new Callback<Metadata>(){ | 
  | 88 |  |                  @Override | 
  | 89 |  |                  public void exec(Metadata result) { | 
  | 90 | 0 |                      DataModelDefinition def = new DataModelDefinition(result); | 
  | 91 | 0 |                      modelDefinitionCache.put(metadataId, def); | 
  | 92 | 0 |                      setDef(def); | 
  | 93 | 0 |                      setupEditor(); | 
  | 94 | 0 |                      if (onReady != null) { | 
  | 95 | 0 |                          onReady.exec(new Boolean(true)); | 
  | 96 |  |                      } | 
  | 97 | 0 |                      KSBlockingProgressIndicator.removeTask(initializeTask);                 | 
  | 98 | 0 |                  } | 
  | 99 |  |              }); | 
  | 100 |  |          } else { | 
  | 101 | 0 |              DataModelDefinition def = modelDefinitionCache.get(metadataId); | 
  | 102 | 0 |              setDef(def); | 
  | 103 | 0 |              setupEditor(); | 
  | 104 | 0 |              if (onReady != null) { | 
  | 105 | 0 |                  onReady.exec(new Boolean(true)); | 
  | 106 |  |              } | 
  | 107 | 0 |              KSBlockingProgressIndicator.removeTask(initializeTask);                 | 
  | 108 |  |          } | 
  | 109 | 0 |      } | 
  | 110 |  |       | 
  | 111 |  |      private void setDef(DataModelDefinition def) { | 
  | 112 | 0 |          this.modelDefinition = def; | 
  | 113 | 0 |      } | 
  | 114 |  |       | 
  | 115 |  |      public void setupEditor() { | 
  | 116 | 0 |          String labelType = null; | 
  | 117 | 0 |          if (cluSetType == null || !cluSetType.equals("kuali.cluSet.type.Program")) { | 
  | 118 | 0 |              labelType = "Course"; | 
  | 119 |  |          } else { | 
  | 120 | 0 |              labelType = "Program"; | 
  | 121 |  |          } | 
  | 122 | 0 |          final CluSetEditOptionDropdown chooser = new CluSetEditOptionDropdown(); | 
  | 123 | 0 |          SwitchSection clusetDetails = new SwitchSection( | 
  | 124 |  |                  chooser, | 
  | 125 |  |                  null); | 
  | 126 | 0 |          clusetDetails.enableConfirmation(false); | 
  | 127 |  |           | 
  | 128 | 0 |          Section approvedClusSection = new VerticalSection(); | 
  | 129 | 0 |          FieldDescriptor approvedClusFd = addField(approvedClusSection,  | 
  | 130 |  |                  CommonWidgetConstants.CLU_SET_APPROVED_CLUS_FIELD,  | 
  | 131 |  |                  generateMessageInfo(CommonWidgetConstants.NEW_CLU_SET_CONTENT_APPROVED + labelType), | 
  | 132 |  |                  null, | 
  | 133 |  |                  null); | 
  | 134 | 0 |          approvedClusSelection = (KSSelectedList) approvedClusFd.getFieldWidget(); | 
  | 135 | 0 |          KSListPanel approvedClusListPanel = approvedClusSelection.separateValuesPanel(); | 
  | 136 | 0 |          clusetDetails.addSection(approvedClusSection, CommonWidgetConstants.CLU_SET_SWAP_APPROVED_CLUS); | 
  | 137 |  |           | 
  | 138 |  |   | 
  | 139 |  |           | 
  | 140 | 0 |          Section proposedClusSection = new VerticalSection(); | 
  | 141 | 0 |          FieldDescriptor proposedClusFd = addField(proposedClusSection,  | 
  | 142 |  |                  CommonWidgetConstants.CLU_SET_PROPOSED_CLUS_FIELD,  | 
  | 143 |  |                  generateMessageInfo(CommonWidgetConstants.NEW_CLU_SET_CONTENT_PROPOSED + labelType), | 
  | 144 |  |                  null, | 
  | 145 |  |                  null); | 
  | 146 | 0 |          final KSSelectedList proposedClusSelection = (KSSelectedList) proposedClusFd.getFieldWidget(); | 
  | 147 | 0 |          KSListPanel proposedClusListPanel = proposedClusSelection.separateValuesPanel(); | 
  | 148 | 0 |          clusetDetails.addSection(proposedClusSection, CommonWidgetConstants.CLU_SET_SWAP_PROPOSED_CLUS); | 
  | 149 |  |           | 
  | 150 |  |   | 
  | 151 |  |           | 
  | 152 | 0 |          KSItemLabel clusetRangeLabel = null; | 
  | 153 | 0 |          if (displayField(CluSetManagementField.RANGE)) { | 
  | 154 | 0 |              Section cluRangeSection = new VerticalSection(); | 
  | 155 | 0 |              final Picker cluSetRangePicker = configureSearch(CommonWidgetConstants.CLU_SET_CLU_SET_RANGE_EDIT_FIELD); | 
  | 156 | 0 |              addField(cluRangeSection,  | 
  | 157 |  |                      CommonWidgetConstants.CLU_SET_CLU_SET_RANGE_EDIT_FIELD,  | 
  | 158 |  |                      generateMessageInfo(CommonWidgetConstants.NEW_CLU_SET_CONTENT_RANGE + labelType), | 
  | 159 |  |                      cluSetRangePicker, | 
  | 160 |  |                      null); | 
  | 161 | 0 |              final CluSetRangeDataHelper clusetRangeModelHelper = new CluSetRangeDataHelper(); | 
  | 162 | 0 |              clusetRangeLabel = new KSItemLabel(true, true, clusetRangeModelHelper); | 
  | 163 | 0 |              final KSItemLabel theClusetRangeLabel = clusetRangeLabel; | 
  | 164 | 0 |              clusetRangeLabel.getElement().getStyle().setProperty("border", "solid 1px #cdcdcd"); | 
  | 165 | 0 |              clusetRangeLabel.getElement().getStyle().setProperty("width", "354px"); | 
  | 166 | 0 |              final FieldDescriptor cluRangeFieldDescriptor = addField( | 
  | 167 |  |                      cluRangeSection,  | 
  | 168 |  |                      CommonWidgetConstants.CLU_SET_CLU_SET_RANGE_FIELD,  | 
  | 169 |  |                      null,  | 
  | 170 |  |                      clusetRangeLabel, | 
  | 171 |  |                      null); | 
  | 172 | 0 |              cluRangeFieldDescriptor.setWidgetBinding(new CluSetRangeBinding(clusetRangeModelHelper)); | 
  | 173 | 0 |              cluSetRangePicker.getSearchWindow().addActionCompleteCallback(new Callback<Boolean>() { | 
  | 174 |  |                  @Override | 
  | 175 |  |                  public void exec(Boolean result) { | 
  | 176 | 0 |                      cluSetRangePicker.getSearchWindow().hide(); | 
  | 177 |  |   | 
  | 178 |  |   | 
  | 179 |  |   | 
  | 180 | 0 |                      final SearchRequest searchRequest = cluSetRangePicker.getSearchWindow().getSearchRequest(); | 
  | 181 | 0 |                      String selectedSearchKey = searchRequest.getSearchKey(); | 
  | 182 | 0 |                      Data searchRequestData = CluSetRangeModelUtil.INSTANCE.toData(searchRequest, null); | 
  | 183 | 0 |                      LookupMetadata lookupMetadata = null; | 
  | 184 |  |   | 
  | 185 |  |                       | 
  | 186 | 0 |                      List<LookupMetadata> lookupMDs = new ArrayList<LookupMetadata>(); | 
  | 187 | 0 |                      lookupMDs.add(cluSetRangePicker.getInitLookupMetadata()); | 
  | 188 | 0 |                      lookupMetadata = findLookupMetadataByLookupId(selectedSearchKey,  | 
  | 189 |  |                              lookupMDs, searchRequest.getParams()); | 
  | 190 | 0 |                      if (lookupMetadata == null ||  | 
  | 191 |  |                              !nullSafeEquals(lookupMetadata.getSearchTypeId(),  | 
  | 192 |  |                                      selectedSearchKey)) { | 
  | 193 | 0 |                          lookupMetadata = findLookupMetadataByLookupId(selectedSearchKey,  | 
  | 194 |  |                                  cluSetRangePicker.getAdditionalLookupMetadata(), | 
  | 195 |  |                                  searchRequest.getParams()); | 
  | 196 |  |                      } | 
  | 197 |  |   | 
  | 198 | 0 |                      addClusetItemViewHandler(clusetRangeModelHelper, | 
  | 199 |  |                              theClusetRangeLabel, | 
  | 200 |  |                              lookupMetadata, | 
  | 201 |  |                              searchRequestData, | 
  | 202 |  |                              searchRequest); | 
  | 203 | 0 |                      theClusetRangeLabel.setHighlighted(true); | 
  | 204 | 0 |                      new Timer() { | 
  | 205 |  |                          @Override | 
  | 206 |  |                          public void run() { | 
  | 207 | 0 |                              theClusetRangeLabel.setHighlighted(false); | 
  | 208 | 0 |                          } | 
  | 209 |  |                      }.schedule(5000); | 
  | 210 | 0 |                  } | 
  | 211 |  |              }); | 
  | 212 | 0 |              clusetDetails.addSection(cluRangeSection, CommonWidgetConstants.CLU_SET_SWAP_CLU_SET_RANGE); | 
  | 213 |  |          } | 
  | 214 |  |           | 
  | 215 |  |   | 
  | 216 |  |           | 
  | 217 | 0 |          KSListPanel cluSetsListPanel = null; | 
  | 218 | 0 |          KSSelectedList cluSetsSelection = null; | 
  | 219 | 0 |          if (displayField(CluSetManagementField.CLUSETS)) { | 
  | 220 | 0 |              Section cluSetSection = new VerticalSection(); | 
  | 221 | 0 |              FieldDescriptor cluSetsTempFd = getFieldDescriptor(  | 
  | 222 |  |                      CommonWidgetConstants.CLU_SET_CLU_SETS_FIELD,  | 
  | 223 |  |                      generateMessageInfo(CommonWidgetConstants.NEW_CLU_SET_CONTENT_CLUSET + labelType), | 
  | 224 |  |                      null, | 
  | 225 |  |                      null); | 
  | 226 | 0 |              KSSelectedList tempCluSetsSelection = (KSSelectedList) cluSetsTempFd.getFieldWidget(); | 
  | 227 | 0 |              WidgetConfigInfo config = tempCluSetsSelection.getConfig(); | 
  | 228 | 0 |              cluSetsSelection = new KSSelectedList(config, false); | 
  | 229 | 0 |              cluSetsListPanel = cluSetsSelection.separateValuesPanel(); | 
  | 230 | 0 |              final FieldDescriptor cluSetsFd = addField( | 
  | 231 |  |                      cluSetSection,  | 
  | 232 |  |                      CommonWidgetConstants.CLU_SET_CLU_SETS_FIELD,  | 
  | 233 |  |                      generateMessageInfo(CommonWidgetConstants.NEW_CLU_SET_CONTENT_CLUSET + labelType), | 
  | 234 |  |                      cluSetsSelection,  | 
  | 235 |  |                      null); | 
  | 236 | 0 |              cluSetsFd.setWidgetBinding(new CluSetBinding()); | 
  | 237 | 0 |              clusetDetails.addSection(cluSetSection, CommonWidgetConstants.CLU_SET_SWAP_CLU_SETS); | 
  | 238 |  |          } | 
  | 239 |  |           | 
  | 240 |  |   | 
  | 241 |  |           | 
  | 242 |  |           | 
  | 243 | 0 |          String contextName = (cluSetType != null && cluSetType.equals("kuali.cluSet.type.Program"))? | 
  | 244 |  |                  "PROGRAMS" : "COURSES"; | 
  | 245 | 0 |          VerticalFlowPanel selectedValuesPanel = new VerticalFlowPanel(); | 
  | 246 | 0 |          selectedValuesPanel.getElement().getStyle().setPaddingTop(20, Style.Unit.PX); | 
  | 247 | 0 |          VerticalFlowPanel approvedClusPanel = prepareValuesPanel(approvedClusListPanel, "APPROVED " + contextName); | 
  | 248 | 0 |          approvedClusPanel.getElement().getStyle().setPaddingTop(15, Style.Unit.PX); | 
  | 249 | 0 |          VerticalFlowPanel proposedClusPanel = prepareValuesPanel(proposedClusListPanel, "PROPOSED " + contextName); | 
  | 250 | 0 |          proposedClusPanel.getElement().getStyle().setPaddingTop(15, Style.Unit.PX); | 
  | 251 | 0 |          VerticalFlowPanel rangePanel = null; | 
  | 252 | 0 |          if (displayField(CluSetManagementField.RANGE)) { | 
  | 253 | 0 |              rangePanel = prepareValuesPanel(clusetRangeLabel, contextName + " RANGE"); | 
  | 254 | 0 |              rangePanel.getElement().getStyle().setPaddingTop(15, Style.Unit.PX); | 
  | 255 |  |          } | 
  | 256 | 0 |          VerticalFlowPanel cluSetsPanel = null; | 
  | 257 | 0 |          if (displayField(CluSetManagementField.CLUSETS)) { | 
  | 258 | 0 |              cluSetsPanel = prepareValuesPanel(cluSetsListPanel, contextName + " SETS"); | 
  | 259 | 0 |              cluSetsPanel.getElement().getStyle().setPaddingTop(15, Style.Unit.PX); | 
  | 260 |  |          } | 
  | 261 |  |           | 
  | 262 | 0 |          selectedValuesPanel.add(approvedClusPanel); | 
  | 263 | 0 |          selectedValuesPanel.add(proposedClusPanel); | 
  | 264 | 0 |          if (displayField(CluSetManagementField.RANGE)) { | 
  | 265 | 0 |              selectedValuesPanel.add(rangePanel); | 
  | 266 |  |          } | 
  | 267 | 0 |          if (displayField(CluSetManagementField.CLUSETS)) { | 
  | 268 | 0 |              selectedValuesPanel.add(cluSetsPanel); | 
  | 269 |  |          } | 
  | 270 |  |   | 
  | 271 | 0 |          addVisibilityHandlers(approvedClusSelection, approvedClusPanel); | 
  | 272 | 0 |          addVisibilityHandlers(proposedClusSelection, proposedClusPanel); | 
  | 273 | 0 |          if (displayField(CluSetManagementField.RANGE)) { | 
  | 274 | 0 |              addVisibilityHandlers(clusetRangeLabel, rangePanel); | 
  | 275 |  |          } | 
  | 276 | 0 |          if (displayField(CluSetManagementField.CLUSETS)) { | 
  | 277 | 0 |              addVisibilityHandlers(cluSetsSelection, cluSetsPanel); | 
  | 278 |  |          } | 
  | 279 |  |           | 
  | 280 | 0 |          selectedListPanelPairs.add(new KSSelectedListPanelPair(approvedClusSelection, approvedClusPanel)); | 
  | 281 | 0 |          selectedListPanelPairs.add(new KSSelectedListPanelPair(proposedClusSelection, proposedClusPanel)); | 
  | 282 | 0 |          if (displayField(CluSetManagementField.CLUSETS)) { | 
  | 283 | 0 |              selectedListPanelPairs.add(new KSSelectedListPanelPair(cluSetsSelection, cluSetsPanel)); | 
  | 284 |  |          } | 
  | 285 | 0 |          if (displayField(CluSetManagementField.RANGE)) { | 
  | 286 | 0 |              itemLabelPanelPairs.add(new KSItemLabelPanelPair(clusetRangeLabel, rangePanel)); | 
  | 287 |  |          } | 
  | 288 |  |           | 
  | 289 | 0 |          final VerticalSection choosingSection = new VerticalSection(); | 
  | 290 |  |          HTML prompt; | 
  | 291 | 0 |          if(cluSetType.equals("kuali.cluSet.type.Program")){ | 
  | 292 | 0 |              choosingSection.addWidget(new HTML("<b>Add a program or program set</b>")); | 
  | 293 | 0 |              prompt = new HTML("Add program or program sets. You may  <br/>" | 
  | 294 |  |                      + "add any combination of programs or program sets."); | 
  | 295 |  |          } | 
  | 296 |  |          else{ | 
  | 297 | 0 |              choosingSection.addWidget(new HTML("<b>Add a course, course set, or course range</b>")); | 
  | 298 | 0 |              prompt = new HTML("Add courses, course sets, or course ranges to your course set. You may <br/>" + | 
  | 299 |  |                  "add any combination of courses, dynamic course ranges, or Course sets."); | 
  | 300 |  |          } | 
  | 301 | 0 |          choosingSection.addWidget(chooser); | 
  | 302 | 0 |          choosingSection.addSection(clusetDetails); | 
  | 303 | 0 |          chooser.addSelectionChangeHandler(new SelectionChangeHandler() { | 
  | 304 |  |              @Override | 
  | 305 |  |              public void onSelectionChange(SelectionChangeEvent event) { | 
  | 306 | 0 |                  if (chooser.getSelectedItem() != null && | 
  | 307 |  |                          !chooser.getSelectedItem().trim().isEmpty()) { | 
  | 308 | 0 |                      choosingSection.setStyleName("KS-CluSetManagement-chooser"); | 
  | 309 |  |                  } else { | 
  | 310 | 0 |                      choosingSection.setStyleName("KS-CluSetManagement-chooser-unselected"); | 
  | 311 |  |                  } | 
  | 312 | 0 |              } | 
  | 313 |  |          }); | 
  | 314 |  |           | 
  | 315 | 0 |          this.addWidget(prompt); | 
  | 316 | 0 |          this.addSection(choosingSection); | 
  | 317 | 0 |          this.addWidget(selectedValuesPanel); | 
  | 318 | 0 |      } | 
  | 319 |  |       | 
  | 320 |  |      private boolean displayField(CluSetManagementField field) { | 
  | 321 | 0 |          boolean result = false; | 
  | 322 | 0 |          switch(field) { | 
  | 323 |  |              case APPROVED: | 
  | 324 |  |              case PROPOSED: | 
  | 325 | 0 |                  result = true; | 
  | 326 | 0 |                  break; | 
  | 327 |  |              case RANGE: | 
  | 328 | 0 |                  if (!singularCluOnly && (cluSetType == null || !cluSetType.equals("kuali.cluSet.type.Program"))) { | 
  | 329 | 0 |                      result = true; | 
  | 330 |  |                  } else { | 
  | 331 | 0 |                      result = false; | 
  | 332 |  |                  } | 
  | 333 | 0 |                  break; | 
  | 334 |  |              case CLUSETS: | 
  | 335 | 0 |                  if (!singularCluOnly) { | 
  | 336 | 0 |                      result = true; | 
  | 337 |  |                  } else { | 
  | 338 | 0 |                      result = false; | 
  | 339 |  |                  } | 
  | 340 |  |                  break; | 
  | 341 |  |          } | 
  | 342 | 0 |          return result; | 
  | 343 |  |      } | 
  | 344 |  |       | 
  | 345 |  |      private void addClusetItemViewHandler(CluSetRangeDataHelper clusetRangeModelHelper, | 
  | 346 |  |              KSItemLabel clusetRangeLabel, | 
  | 347 |  |              final LookupMetadata lookupMetadata, | 
  | 348 |  |              Data searchRequestData, | 
  | 349 |  |              final SearchRequest searchRequest) { | 
  | 350 | 0 |          clusetRangeModelHelper.setLookupMetadata(lookupMetadata); | 
  | 351 | 0 |          clusetRangeLabel.setValue(new DataValue(searchRequestData)); | 
  | 352 | 0 |          if (showCluRangeDetailsHandlerRegs != null &&  | 
  | 353 |  |                  showCluRangeDetailsHandlerRegs.get(Integer.toString(clusetRangeLabel.instanceId)) != null) { | 
  | 354 | 0 |              ((HandlerRegistration)showCluRangeDetailsHandlerRegs.get(Integer.toString(clusetRangeLabel.instanceId))).removeHandler(); | 
  | 355 |  |          } | 
  | 356 | 0 |          showCluRangeDetailsHandlerRegs.put(Integer.toString(clusetRangeLabel.instanceId),  | 
  | 357 | 0 |                  clusetRangeLabel.addShowDetailsHandler(new ClickHandler() { | 
  | 358 |  |              @Override | 
  | 359 |  |              public void onClick(ClickEvent event) { | 
  | 360 | 0 |                  SearchResultsLightBox srLightBox = new SearchResultsLightBox("View Course Range", | 
  | 361 |  |                          searchRequest, lookupMetadata); | 
  | 362 | 0 |                  srLightBox.show(); | 
  | 363 | 0 |              } | 
  | 364 |  |          })); | 
  | 365 | 0 |      } | 
  | 366 |  |       | 
  | 367 |  |      protected MessageKeyInfo generateMessageInfo(String labelKey) { | 
  | 368 | 0 |          return new MessageKeyInfo("clusetmanagement", "clusetmanagement", "draft", labelKey); | 
  | 369 |  |      } | 
  | 370 |  |       | 
  | 371 |  |      private FieldDescriptor getFieldDescriptor(  | 
  | 372 |  |              String fieldKey,  | 
  | 373 |  |              MessageKeyInfo messageKey,  | 
  | 374 |  |              Widget widget,  | 
  | 375 |  |              String parentPath) { | 
  | 376 | 0 |          QueryPath path = QueryPath.concat(parentPath, fieldKey); | 
  | 377 | 0 |          Metadata meta = modelDefinition.getMetadata(path); | 
  | 378 |  |          FieldDescriptor fd; | 
  | 379 | 0 |          if (widget != null) { | 
  | 380 | 0 |              fd = new FieldDescriptor(path.toString(), messageKey, meta, widget); | 
  | 381 |  |          } | 
  | 382 |  |          else{ | 
  | 383 | 0 |              fd = new FieldDescriptor(path.toString(), messageKey, meta); | 
  | 384 |  |          } | 
  | 385 | 0 |          return fd; | 
  | 386 |  |      } | 
  | 387 |  |   | 
  | 388 |  |      private FieldDescriptor addField(Section section,  | 
  | 389 |  |              String fieldKey,  | 
  | 390 |  |              MessageKeyInfo messageKey,  | 
  | 391 |  |              Widget widget,  | 
  | 392 |  |              String parentPath) { | 
  | 393 | 0 |          FieldDescriptor fd = getFieldDescriptor(fieldKey, messageKey, widget, parentPath); | 
  | 394 | 0 |          section.addField(fd); | 
  | 395 | 0 |          return fd; | 
  | 396 |  |      } | 
  | 397 |  |   | 
  | 398 |  |      private static boolean nullSafeEquals(Object obj1, Object obj2) { | 
  | 399 | 0 |          return (obj1 == null && obj2 == null || | 
  | 400 |  |                  obj1 != null && obj2 != null && obj1.equals(obj2)); | 
  | 401 |  |      } | 
  | 402 |  |       | 
  | 403 |  |      private VerticalFlowPanel prepareValuesPanel(Widget widget, String title) { | 
  | 404 | 0 |          final VerticalFlowPanel valuesPanel = new VerticalFlowPanel(); | 
  | 405 | 0 |          valuesPanel.add(new KSLabel(title)); | 
  | 406 | 0 |          valuesPanel.add(widget); | 
  | 407 | 0 |          valuesPanel.setVisible(false); | 
  | 408 | 0 |          return valuesPanel; | 
  | 409 |  |      } | 
  | 410 |  |       | 
  | 411 |  |      @Override | 
  | 412 |  |      public void updateWidgetData(DataModel model) { | 
  | 413 | 0 |          super.updateWidgetData(model); | 
  | 414 |  |           | 
  | 415 | 0 |          if (selectedListPanelPairs != null) { | 
  | 416 | 0 |              for (KSSelectedListPanelPair selectedListPanelPair : selectedListPanelPairs) { | 
  | 417 | 0 |                  handleSelectedListVisibility(selectedListPanelPair.getKsSelectedList(),  | 
  | 418 |  |                          selectedListPanelPair.getPanel()); | 
  | 419 |  |              } | 
  | 420 |  |          } | 
  | 421 | 0 |          if (itemLabelPanelPairs != null) { | 
  | 422 | 0 |              for (KSItemLabelPanelPair itemLabelPanelPair : itemLabelPanelPairs) { | 
  | 423 | 0 |                  handleListItemVisibility(itemLabelPanelPair.getKsItemLabel(),  | 
  | 424 |  |                          itemLabelPanelPair.getPanel()); | 
  | 425 |  |              } | 
  | 426 |  |          } | 
  | 427 | 0 |      } | 
  | 428 |  |   | 
  | 429 |  |      private void addVisibilityHandlers(final KSItemLabel listItem, | 
  | 430 |  |              final Panel selectionPanel) { | 
  | 431 | 0 |          listItem.addValueChangeCallback(new Callback<Value>() { | 
  | 432 |  |              @Override | 
  | 433 |  |              public void exec(Value result) { | 
  | 434 | 0 |                  handleListItemVisibility(listItem, selectionPanel); | 
  | 435 | 0 |              } | 
  | 436 |  |          }); | 
  | 437 | 0 |      } | 
  | 438 |  |       | 
  | 439 |  |      private void handleListItemVisibility(KSItemLabel listItem, Panel selectionPanel) { | 
  | 440 | 0 |          String displayText = listItem.getDisplayText(); | 
  | 441 | 0 |          if (displayText == null || displayText.equals("")) { | 
  | 442 | 0 |              selectionPanel.setVisible(false); | 
  | 443 |  |          } else { | 
  | 444 | 0 |              selectionPanel.setVisible(true); | 
  | 445 |  |          } | 
  | 446 | 0 |      } | 
  | 447 |  |       | 
  | 448 |  |      private void addVisibilityHandlers(final KSSelectedList selectionList, | 
  | 449 |  |              final Panel selectionPanel) { | 
  | 450 | 0 |          selectionList.addSelectionChangeHandler( | 
  | 451 | 0 |                  new SelectionChangeHandler() { | 
  | 452 |  |                      @Override | 
  | 453 |  |                      public void onSelectionChange(SelectionChangeEvent event) { | 
  | 454 | 0 |                          handleSelectedListVisibility(selectionList, selectionPanel); | 
  | 455 | 0 |                      } | 
  | 456 |  |                  } | 
  | 457 |  |          ); | 
  | 458 | 0 |      } | 
  | 459 |  |       | 
  | 460 |  |      private void handleSelectedListVisibility(final KSSelectedList selectionList, final Panel selectionPanel) { | 
  | 461 | 0 |          List<KSItemLabel> selectedItems = selectionList.getSelectedItems(); | 
  | 462 | 0 |          if (selectedItems != null && !selectedItems.isEmpty()) { | 
  | 463 |  |               | 
  | 464 | 0 |              selectionPanel.setVisible(true); | 
  | 465 | 0 |              for (KSItemLabel selectedItem : selectedItems) { | 
  | 466 | 0 |                  selectedItem.addCloseHandler(new CloseHandler<KSItemLabel>() { | 
  | 467 |  |                      @Override | 
  | 468 |  |                      public void onClose(CloseEvent<KSItemLabel> event) { | 
  | 469 | 0 |                          List<KSItemLabel> newSelectedItems =  | 
  | 470 |  |                              selectionList.getSelectedItems(); | 
  | 471 | 0 |                          int numNewSelectedItems = (newSelectedItems == null)? 0 : | 
  | 472 |  |                              newSelectedItems.size(); | 
  | 473 | 0 |                          if (numNewSelectedItems == 0) { | 
  | 474 |  |                               | 
  | 475 | 0 |                              selectionPanel.setVisible(false); | 
  | 476 |  |                          } | 
  | 477 | 0 |                      } | 
  | 478 |  |                  }); | 
  | 479 |  |              } | 
  | 480 |  |          } | 
  | 481 | 0 |      } | 
  | 482 |  |   | 
  | 483 |  |      private Picker configureSearch(String fieldKey) { | 
  | 484 | 0 |          QueryPath path = QueryPath.concat(null, fieldKey); | 
  | 485 | 0 |          Metadata metaData = modelDefinition.getMetadata(path); | 
  | 486 | 0 |          Picker picker = new Picker(metaData.getInitialLookup(), metaData.getAdditionalLookups()); | 
  | 487 | 0 |          return picker; | 
  | 488 |  |      } | 
  | 489 |  |   | 
  | 490 |  |      private static LookupMetadata findLookupMetadataByLookupId(String searchTypeId, | 
  | 491 |  |              List<LookupMetadata> lookupMetadatas, | 
  | 492 |  |              List<SearchParam> searchParams) { | 
  | 493 | 0 |          LookupMetadata result = null; | 
  | 494 | 0 |          if (lookupMetadatas != null) { | 
  | 495 | 0 |              for (LookupMetadata lookupMetadata : lookupMetadatas) { | 
  | 496 | 0 |                  if (nullSafeEquals(lookupMetadata.getSearchTypeId(), searchTypeId)) { | 
  | 497 |  |                       | 
  | 498 | 0 |                      List<LookupParamMetadata> paramMetas = lookupMetadata.getParams(); | 
  | 499 | 0 |                      List<LookupParamMetadata> resultParamMetas = null; | 
  | 500 | 0 |                      result = (result == null)? new LookupMetadata() : result; | 
  | 501 | 0 |                      result.setDesc(lookupMetadata.getDesc()); | 
  | 502 | 0 |                      result.setId(lookupMetadata.getId()); | 
  | 503 | 0 |                      result.setName(""); | 
  | 504 | 0 |                      resultParamMetas = result.getParams(); | 
  | 505 | 0 |                      if (resultParamMetas == null) { | 
  | 506 | 0 |                          resultParamMetas = new ArrayList<LookupParamMetadata>(); | 
  | 507 |  |                      } | 
  | 508 | 0 |                      if (paramMetas != null) { | 
  | 509 | 0 |                          for (LookupParamMetadata paramMeta : paramMetas) { | 
  | 510 | 0 |                              boolean resultParamMetaFound = false; | 
  | 511 | 0 |                              for (LookupParamMetadata resultParamMeta : resultParamMetas) { | 
  | 512 | 0 |                                  if (paramMeta.getKey().equals(resultParamMeta)) { | 
  | 513 | 0 |                                      resultParamMetaFound = true; | 
  | 514 | 0 |                                      break; | 
  | 515 |  |                                  } | 
  | 516 |  |                              } | 
  | 517 | 0 |                              if (!resultParamMetaFound) { | 
  | 518 | 0 |                                  resultParamMetas.add(paramMeta); | 
  | 519 |  |                              } | 
  | 520 | 0 |                          } | 
  | 521 |  |                      } | 
  | 522 | 0 |                      result.setParams(resultParamMetas); | 
  | 523 | 0 |                      result.setQosMetadata(lookupMetadata.getQosMetadata()); | 
  | 524 | 0 |                      result.setResultDisplayKey(lookupMetadata.getResultDisplayKey()); | 
  | 525 | 0 |                      result.setResultReturnKey(lookupMetadata.getResultReturnKey()); | 
  | 526 | 0 |                      result.setResults(lookupMetadata.getResults()); | 
  | 527 | 0 |                      result.setResultSortKey(lookupMetadata.getResultSortKey()); | 
  | 528 | 0 |                  } | 
  | 529 |  |              } | 
  | 530 |  |          } | 
  | 531 | 0 |          return result; | 
  | 532 |  |      } | 
  | 533 |  |       | 
  | 534 |  |      @Override | 
  | 535 |  |      public void updateModel() { | 
  | 536 |  |           | 
  | 537 | 0 |          super.updateModel(); | 
  | 538 | 0 |      } | 
  | 539 |  |   | 
  | 540 |  |   | 
  | 541 |  |   | 
  | 542 |  |      public class CluSetEditOptionDropdown extends KSDropDown { | 
  | 543 | 0 |          public CluSetEditOptionDropdown(){ | 
  | 544 | 0 |              SimpleListItems editOptions = new SimpleListItems(); | 
  | 545 |  |   | 
  | 546 | 0 |              if (cluSetType != null && cluSetType.equals("kuali.cluSet.type.Program")) { | 
  | 547 | 0 |                  editOptions.addItem(CommonWidgetConstants.CLU_SET_SWAP_APPROVED_CLUS, "Approved Programs"); | 
  | 548 | 0 |                  editOptions.addItem(CommonWidgetConstants.CLU_SET_SWAP_PROPOSED_CLUS, "Proposed Programs"); | 
  | 549 | 0 |                  if (!CluSetEditorWidget.this.singularCluOnly) { | 
  | 550 | 0 |                      editOptions.addItem(CommonWidgetConstants.CLU_SET_SWAP_CLU_SETS, "Program Sets"); | 
  | 551 |  |                  } | 
  | 552 |  |              } else { | 
  | 553 | 0 |                  editOptions.addItem(CommonWidgetConstants.CLU_SET_SWAP_APPROVED_CLUS, "Approved Courses"); | 
  | 554 | 0 |                  editOptions.addItem(CommonWidgetConstants.CLU_SET_SWAP_PROPOSED_CLUS, "Proposed Courses"); | 
  | 555 | 0 |                  if (!CluSetEditorWidget.this.singularCluOnly) { | 
  | 556 | 0 |                      editOptions.addItem(CommonWidgetConstants.CLU_SET_SWAP_CLU_SETS, "Course Sets"); | 
  | 557 | 0 |                      editOptions.addItem(CommonWidgetConstants.CLU_SET_SWAP_CLU_SET_RANGE, "Course Ranges (Course numbers, common learning objectives, etc)"); | 
  | 558 |  |                  } | 
  | 559 |  |              } | 
  | 560 | 0 |              super.setListItems(editOptions); | 
  | 561 | 0 |          } | 
  | 562 |  |      } | 
  | 563 |  |   | 
  | 564 |  |      class KSSelectedListPanelPair { | 
  | 565 |  |          private KSSelectedList ksSelectedList; | 
  | 566 |  |          private Panel panel; | 
  | 567 | 0 |          public KSSelectedListPanelPair(KSSelectedList ksSelectedList, Panel panel) { | 
  | 568 | 0 |              setKsSelectedList(ksSelectedList); | 
  | 569 | 0 |              setPanel(panel); | 
  | 570 | 0 |          } | 
  | 571 |  |          public KSSelectedList getKsSelectedList() { | 
  | 572 | 0 |              return ksSelectedList; | 
  | 573 |  |          } | 
  | 574 |  |          public void setKsSelectedList(KSSelectedList ksSelectedList) { | 
  | 575 | 0 |              this.ksSelectedList = ksSelectedList; | 
  | 576 | 0 |          } | 
  | 577 |  |          public Panel getPanel() { | 
  | 578 | 0 |              return panel; | 
  | 579 |  |          } | 
  | 580 |  |          public void setPanel(Panel panel) { | 
  | 581 | 0 |              this.panel = panel; | 
  | 582 | 0 |          } | 
  | 583 |  |      } | 
  | 584 |  |       | 
  | 585 |  |      class KSItemLabelPanelPair { | 
  | 586 |  |          private KSItemLabel ksItemLabel; | 
  | 587 |  |          private Panel panel; | 
  | 588 | 0 |          public KSItemLabelPanelPair(KSItemLabel ksItemLabel, Panel panel) { | 
  | 589 | 0 |              setKsItemLabel(ksItemLabel); | 
  | 590 | 0 |              setPanel(panel); | 
  | 591 | 0 |          } | 
  | 592 |  |          public KSItemLabel getKsItemLabel() { | 
  | 593 | 0 |              return ksItemLabel; | 
  | 594 |  |          } | 
  | 595 |  |          public void setKsItemLabel(KSItemLabel ksItemLabel) { | 
  | 596 | 0 |              this.ksItemLabel = ksItemLabel; | 
  | 597 | 0 |          } | 
  | 598 |  |          public Panel getPanel() { | 
  | 599 | 0 |              return panel; | 
  | 600 |  |          } | 
  | 601 |  |          public void setPanel(Panel panel) { | 
  | 602 | 0 |              this.panel = panel; | 
  | 603 | 0 |          } | 
  | 604 |  |      } | 
  | 605 |  |       | 
  | 606 |  |      public static class Picker extends KSPicker { | 
  | 607 |  |   | 
  | 608 |  |          private String name; | 
  | 609 |  |          private LookupMetadata initLookupMetadata; | 
  | 610 |  |          private List<LookupMetadata> additionalLookupMetadata; | 
  | 611 |  |   | 
  | 612 |  |          public Picker(LookupMetadata inLookupMetadata, List<LookupMetadata> additionalLookupMetadata) { | 
  | 613 | 0 |              super(inLookupMetadata, additionalLookupMetadata); | 
  | 614 | 0 |              this.initLookupMetadata = inLookupMetadata; | 
  | 615 | 0 |              this.additionalLookupMetadata = additionalLookupMetadata; | 
  | 616 | 0 |          } | 
  | 617 |  |   | 
  | 618 |  |          public String getName() { | 
  | 619 | 0 |              return name; | 
  | 620 |  |          } | 
  | 621 |  |   | 
  | 622 |  |          public void setName(String name) { | 
  | 623 | 0 |              this.name = name; | 
  | 624 | 0 |          } | 
  | 625 |  |   | 
  | 626 |  |          public LookupMetadata getInitLookupMetadata() { | 
  | 627 | 0 |              return initLookupMetadata; | 
  | 628 |  |          } | 
  | 629 |  |   | 
  | 630 |  |          public void setInitLookupMetadata(LookupMetadata initLookupMetadata) { | 
  | 631 | 0 |              this.initLookupMetadata = initLookupMetadata; | 
  | 632 | 0 |          } | 
  | 633 |  |   | 
  | 634 |  |          public List<LookupMetadata> getAdditionalLookupMetadata() { | 
  | 635 | 0 |              return additionalLookupMetadata; | 
  | 636 |  |          } | 
  | 637 |  |   | 
  | 638 |  |          public void setAdditionalLookupMetadata(List<LookupMetadata> additionalLookupMetadata) { | 
  | 639 | 0 |              this.additionalLookupMetadata = additionalLookupMetadata; | 
  | 640 | 0 |          } | 
  | 641 |  |           | 
  | 642 |  |      } | 
  | 643 |  |       | 
  | 644 | 0 |      public class CluSetBinding extends ModelWidgetBindingSupport<HasDataValue> { | 
  | 645 | 0 |          private HasDataValueBinding binding = HasDataValueBinding.INSTANCE; | 
  | 646 |  |   | 
  | 647 |  |          @Override | 
  | 648 |  |          public void setModelValue(HasDataValue widget, DataModel model, String path) { | 
  | 649 | 0 |              binding.setModelValue(widget, model, path); | 
  | 650 | 0 |          } | 
  | 651 |  |   | 
  | 652 |  |          @Override | 
  | 653 |  |          public void setWidgetValue(HasDataValue widget, DataModel model, String path) { | 
  | 654 | 0 |              binding.setWidgetValue(widget, model, path); | 
  | 655 | 0 |          } | 
  | 656 |  |      } | 
  | 657 |  |       | 
  | 658 | 0 |      public class CluSetRangeBinding extends ModelWidgetBindingSupport<HasDataValue> { | 
  | 659 | 0 |          private HasDataValueBinding binding = HasDataValueBinding.INSTANCE; | 
  | 660 | 0 |          private CluSetRangeDataHelper clusetRangeModelHelper = null; | 
  | 661 |  |           | 
  | 662 | 0 |          public CluSetRangeBinding(CluSetRangeDataHelper clusetRangeModelHelper) { | 
  | 663 | 0 |              this.clusetRangeModelHelper = clusetRangeModelHelper; | 
  | 664 | 0 |          } | 
  | 665 |  |           | 
  | 666 |  |          @Override | 
  | 667 |  |          public void setModelValue(HasDataValue widget, DataModel model, String path) { | 
  | 668 | 0 |              binding.setModelValue(widget, model, path); | 
  | 669 | 0 |          } | 
  | 670 |  |   | 
  | 671 |  |          @Override | 
  | 672 |  |          public void setWidgetValue(final HasDataValue widget, DataModel model, String path) { | 
  | 673 | 0 |              DataModel middleManModel = new DataModel(); | 
  | 674 | 0 |              if (model != null && model.getRoot() != null) { | 
  | 675 | 0 |                  middleManModel = new DataModel(model.getDefinition(), model.getRoot().copy()); | 
  | 676 |  |              } | 
  | 677 | 0 |              Metadata rangeEditMetaData = model.getMetadata( | 
  | 678 |  |                      QueryPath.parse(CommonWidgetConstants.CLU_SET_CLU_SET_RANGE_EDIT_FIELD)); | 
  | 679 | 0 |              Data membershipQueryData = (Data)model.get(path); | 
  | 680 | 0 |              MembershipQueryInfo membershipQueryInfo = (membershipQueryData == null)? | 
  | 681 |  |                      null : CluSetRangeModelUtil.INSTANCE.toMembershipQueryInfo(membershipQueryData); | 
  | 682 | 0 |              if (membershipQueryInfo != null) { | 
  | 683 | 0 |                  String selectedSearchTypeKey = membershipQueryInfo.getSearchTypeKey(); | 
  | 684 | 0 |                  List<LookupMetadata> lookupMDs = new ArrayList<LookupMetadata>(); | 
  | 685 | 0 |                  lookupMDs.add(rangeEditMetaData.getInitialLookup()); | 
  | 686 | 0 |                  LookupMetadata lookupMetadata = findLookupMetadataByLookupId(selectedSearchTypeKey,  | 
  | 687 |  |                          lookupMDs, membershipQueryInfo.getQueryParamValueList()); | 
  | 688 | 0 |                  if (lookupMetadata == null ||  | 
  | 689 |  |                          !nullSafeEquals(lookupMetadata.getName(),  | 
  | 690 |  |                                  selectedSearchTypeKey)) { | 
  | 691 | 0 |                      lookupMetadata = findLookupMetadataByLookupId(selectedSearchTypeKey,  | 
  | 692 |  |                              rangeEditMetaData.getAdditionalLookups(), | 
  | 693 |  |                              membershipQueryInfo.getQueryParamValueList()); | 
  | 694 |  |                  } | 
  | 695 |  |   | 
  | 696 | 0 |                  SearchRequest searchRequest = new SearchRequest(); | 
  | 697 | 0 |                  searchRequest.setSearchKey(selectedSearchTypeKey); | 
  | 698 |  |   | 
  | 699 | 0 |                  searchRequest.setParams(membershipQueryInfo.getQueryParamValueList()); | 
  | 700 | 0 |                  searchRequest.setSortColumn(lookupMetadata.getResultSortKey()); | 
  | 701 |  |                   | 
  | 702 |  |   | 
  | 703 |  |   | 
  | 704 |  |   | 
  | 705 |  |   | 
  | 706 |  |   | 
  | 707 |  |   | 
  | 708 | 0 |                  addClusetItemViewHandler(clusetRangeModelHelper, | 
  | 709 |  |                          (KSItemLabel)widget, | 
  | 710 |  |                          lookupMetadata, | 
  | 711 |  |                          membershipQueryData, | 
  | 712 |  |                          searchRequest); | 
  | 713 | 0 |                  ((KSItemLabel)widget).setHighlighted(true); | 
  | 714 | 0 |                  new Timer() { | 
  | 715 |  |                      @Override | 
  | 716 |  |                      public void run() { | 
  | 717 | 0 |                          ((KSItemLabel)widget).setHighlighted(false); | 
  | 718 | 0 |                      } | 
  | 719 |  |                  }.schedule(5000); | 
  | 720 |  |              } | 
  | 721 | 0 |              binding.setWidgetValue(widget, middleManModel, path); | 
  | 722 | 0 |          } | 
  | 723 |  |      } | 
  | 724 |  |  } |