1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.student.common.ui.client.widgets.rules;
17
18 import java.util.List;
19
20 import org.kuali.student.common.ui.client.mvc.Callback;
21 import org.kuali.student.common.ui.client.widgets.KSButton;
22 import org.kuali.student.common.ui.client.widgets.KSLabel;
23 import org.kuali.student.common.ui.client.widgets.KSPlaceholder;
24 import org.kuali.student.common.ui.client.widgets.KSProgressIndicator;
25 import org.kuali.student.common.ui.client.widgets.field.layout.element.SpanPanel;
26 import org.kuali.student.common.ui.client.widgets.table.Node;
27 import org.kuali.student.core.statement.dto.ReqComponentInfo;
28 import org.kuali.student.core.statement.dto.StatementOperatorTypeKey;
29 import org.kuali.student.core.statement.dto.StatementTreeViewInfo;
30
31 import com.google.gwt.event.dom.client.ClickEvent;
32 import com.google.gwt.event.dom.client.ClickHandler;
33 import com.google.gwt.event.shared.HandlerRegistration;
34 import com.google.gwt.user.client.Timer;
35 import com.google.gwt.user.client.ui.FlowPanel;
36 import com.google.gwt.user.client.ui.SimplePanel;
37 import com.google.gwt.user.client.ui.HTMLTable.Cell;
38
39 public class RuleTableManipulationWidget extends FlowPanel {
40
41
42 private KSButton btnMakeOR = new KSButton("OR");
43 private KSButton btnMakeAND = new KSButton("AND");
44 private KSButton btnAddToGroup = new KSButton("Group");
45 private KSButton btnMoveRuleDown = new KSButton("Move Down");
46 private KSButton btnMoveRuleUp = new KSButton("Move Up");
47 private KSButton btnUndo = new KSButton("Undo");
48 private KSButton btnRedo = new KSButton("Redo");
49 private KSButton btnDelete = new KSButton("Delete");
50 private SpanPanel separator1 = new SpanPanel(" | ");
51 private SpanPanel separator2 = new SpanPanel(" | ");
52 private FlowPanel topButtonsPanel = new FlowPanel();
53 private FlowPanel ruleTablePanel = new FlowPanel();
54
55 private KSProgressIndicator twiddler = new KSProgressIndicator();
56
57
58 private RuleTable ruleTable = new RuleTable(true);
59 private ClickHandler ruleTableSelectionHandler = null;
60 private ClickHandler ruleTableEditClauseHandler = null;
61 private HandlerRegistration textClickHandler = null;
62
63
64 private RuleInfo rule = new RuleInfo();
65 private Callback reqCompEditCallback;
66 private Callback ruleChangedCallback;
67 private boolean isEnabled = true;
68 private boolean isOperatorChecked = false;
69
70 public RuleTableManipulationWidget() {
71 createButtonsPanel();
72
73 twiddler.setVisible(false);
74 SimplePanel twiddlerPanel = new SimplePanel();
75 twiddlerPanel.setHeight("30px");
76 twiddlerPanel.setWidget(twiddler);
77
78 add(topButtonsPanel);
79
80 ruleTablePanel.setStyleName("KS-Program-Rule-ObjectView-RulePanel");
81 ruleTablePanel.add(ruleTable);
82 add(ruleTablePanel);
83
84 setupHandlers();
85 }
86
87 private void setupHandlers() {
88
89 ruleTableSelectionHandler = new ClickHandler() {
90
91 @Override
92 public void onClick(ClickEvent event) {
93
94 Cell cell = ruleTable.getCellForEvent(event);
95 if (cell == null) {
96 return;
97 }
98
99 RuleNodeWidget widget = (RuleNodeWidget) ruleTable.getWidget(cell.getRowIndex(), cell.getCellIndex());
100
101
102 if (widget.isEditMode() || !isEnabled) {
103 widget.setEditMode(false);
104 return;
105 }
106
107
108 Object userObject = widget.getNode().getUserObject();
109 if (userObject instanceof StatementVO) {
110 StatementVO statementVO = (StatementVO) userObject;
111 statementVO.setCheckBoxOn(!statementVO.isCheckBoxOn());
112 } else if (userObject instanceof ReqComponentVO) {
113 ReqComponentVO reqComponentVO = (ReqComponentVO) userObject;
114 reqComponentVO.setCheckBoxOn(!reqComponentVO.isCheckBoxOn());
115 }
116 updateTable();
117 }
118 };
119 textClickHandler = ruleTable.addTextClickHandler(ruleTableSelectionHandler);
120
121 ruleTableEditClauseHandler = new ClickHandler() {
122 @Override
123 public void onClick(ClickEvent event) {
124 Cell cell = ruleTable.getCellForEvent(event);
125 if (cell == null) {
126 return;
127 }
128
129 RuleNodeWidget widget = (RuleNodeWidget) ruleTable.getWidget(cell.getRowIndex(), cell.getCellIndex());
130 Object userObject = widget.getNode().getUserObject();
131 if (userObject instanceof ReqComponentVO) {
132 widget.setEditMode(true);
133 final ReqComponentVO rule = (ReqComponentVO) userObject;
134 reqCompEditCallback.exec(rule.getReqComponentInfo());
135 }
136 }
137 };
138
139 btnMoveRuleDown.addClickHandler(new ClickHandler() {
140 public void onClick(ClickEvent event) {
141 StatementVO statementVO = rule.getStatementVO();
142 if (statementVO != null) {
143
144 if (isAbletoMoveReqComp()) {
145 ReqComponentVO selectedReqCompVO = statementVO.getSelectedReqComponentVOs().get(0);
146 StatementVO enclosingStatementVO = statementVO.getEnclosingStatementVO(statementVO, selectedReqCompVO);
147 enclosingStatementVO.shiftReqComponent("RIGHT", selectedReqCompVO);
148 rule.getEditHistory().save(statementVO);
149 redraw(rule.getStatementVO().getStatementTreeViewInfo(), false, true);
150 }
151 }
152 }
153 });
154
155 btnMoveRuleUp.addClickHandler(new ClickHandler() {
156 public void onClick(ClickEvent event) {
157 StatementVO statementVO = rule.getStatementVO();
158 if (statementVO != null) {
159
160 if (isAbletoMoveReqComp()) {
161 ReqComponentVO selectedReqCompVO = statementVO.getSelectedReqComponentVOs().get(0);
162 StatementVO enclosingStatementVO = statementVO.getEnclosingStatementVO(statementVO, selectedReqCompVO);
163 enclosingStatementVO.shiftReqComponent("LEFT", selectedReqCompVO);
164 rule.getEditHistory().save(statementVO);
165 redraw(rule.getStatementVO().getStatementTreeViewInfo(), false, true);
166 }
167 }
168 }
169 });
170
171 btnMakeOR.addClickHandler(new ClickHandler() {
172 public void onClick(ClickEvent event) {
173
174
175 if (isMatchingOperandSelected(Token.Or)) {
176 StatementVO statementVO = rule.getSelectedStatementVOs().get(0);
177 if (statementVO != null) {
178 statementVO.getStatementInfo().setOperator(StatementOperatorTypeKey.OR);
179 statementVO.toggleAndOr();
180 }
181 } else {
182 rule.insertOR();
183 }
184
185
186 StatementVO unsimplified = RulesUtil.clone(rule.getStatementVO());
187 boolean structureChanged = rule.getStatementVO().simplify();
188 rule.getEditHistory().save(rule.getStatementVO());
189
190
191 if (structureChanged) {
192 showRuleBeforeSimplify(unsimplified);
193 } else {
194 redraw(rule.getStatementVO().getStatementTreeViewInfo(), false, true);
195 }
196 }
197 });
198
199 btnMakeAND.addClickHandler(new ClickHandler() {
200 public void onClick(ClickEvent event) {
201
202
203 if (isMatchingOperandSelected(Token.And)) {
204 StatementVO statementVO = rule.getSelectedStatementVOs().get(0);
205 if (statementVO != null) {
206 statementVO.getStatementInfo().setOperator(StatementOperatorTypeKey.AND);
207 statementVO.toggleAndOr();
208 }
209 } else {
210 rule.insertAND();
211 }
212
213
214 StatementVO unsimplified = RulesUtil.clone(rule.getStatementVO());
215 boolean structureChanged = rule.getStatementVO().simplify();
216 rule.getEditHistory().save(rule.getStatementVO());
217
218
219 if (structureChanged) {
220 showRuleBeforeSimplify(unsimplified);
221 } else {
222 redraw(rule.getStatementVO().getStatementTreeViewInfo(), false, true);
223 }
224 }
225 });
226
227 btnDelete.addClickHandler(new ClickHandler() {
228 public void onClick(ClickEvent event) {
229 rule.deleteItem();
230
231
232 StatementVO unsimplified = RulesUtil.clone(rule.getStatementVO());
233 boolean structureChanged = false;
234 if (rule.getStatementVO() != null) {
235 structureChanged = rule.getStatementVO().simplify();
236 }
237
238 rule.getEditHistory().save(rule.getStatementVO());
239
240
241 if (structureChanged) {
242 showRuleBeforeSimplify(unsimplified);
243 } else {
244 redraw((rule.getStatementVO() == null ? null : rule.getStatementVO().getStatementTreeViewInfo()), false, true);
245 }
246 }
247 });
248
249 btnAddToGroup.addClickHandler(new ClickHandler() {
250 public void onClick(ClickEvent event) {
251 rule.addToGroup();
252
253
254 StatementVO unsimplified = RulesUtil.clone(rule.getStatementVO());
255 boolean structureChanged = false;
256 if (rule.getStatementVO() != null) {
257 structureChanged = rule.getStatementVO().simplify();
258 }
259 rule.getEditHistory().save(rule.getStatementVO());
260
261
262 if (structureChanged) {
263 showRuleBeforeSimplify(unsimplified);
264 } else {
265 redraw(rule.getStatementVO().getStatementTreeViewInfo(), false, true);
266 }
267 }
268 });
269
270 btnUndo.addClickHandler(new ClickHandler() {
271 public void onClick(ClickEvent event) {
272 StatementVO previousState = rule.getEditHistory().undo();
273 if (previousState != null) {
274 rule.setStatementVO(previousState);
275 }
276 redraw(rule.getStatementVO().getStatementTreeViewInfo(), false, true);
277 }
278 });
279
280 btnRedo.addClickHandler(new ClickHandler() {
281 public void onClick(ClickEvent event) {
282 StatementVO nextState = rule.getEditHistory().redo();
283 if (nextState != null) {
284 rule.setStatementVO(nextState);
285 }
286 redraw(rule.getStatementVO().getStatementTreeViewInfo(), false, true);
287 }
288 });
289 }
290
291
292 public void redraw() {
293 updateTable();
294 }
295
296
297 public void redraw(StatementTreeViewInfo stmtTreeInfo, boolean newRule, Boolean ruleChanged) {
298 rule.getStatementVO().clearStatementAndReqComponents();
299 rule.getStatementVO().setStatementTreeViewInfo(stmtTreeInfo);
300 if (newRule) {
301 rule.setEditHistory(new EditHistory(rule.getStatementVO()));
302 }
303
304 rule.getStatementVO().clearSelections();
305 updateTable();
306
307 if (ruleChanged != null) {
308 ruleChangedCallback.exec(ruleChanged);
309 }
310 }
311
312 private void updateTable() {
313 setEnableButtons(true);
314 ruleTable.clear();
315 Node tree = rule.getStatementTree();
316 if ((tree != null) && (rule.getStatementVO().getChildCount() > 0)) {
317
318
319 if (ruleTablePanel.getWidgetIndex(ruleTable) == -1) {
320 ruleTablePanel.clear();
321 ruleTablePanel.add(ruleTable);
322 }
323
324 if (rule.isSimplifying()) {
325 twiddler.setText("Simplifying...");
326 twiddler.setVisible(true);
327 } else {
328 twiddler.setText("");
329 twiddler.setVisible(false);
330 }
331 ruleTable.buildTable(tree);
332 textClickHandler.removeHandler();
333 ruleTable.addTextClickHandler(ruleTableSelectionHandler);
334 ruleTable.addEditClauseHandler(ruleTableEditClauseHandler);
335 } else {
336 ruleTablePanel.clear();
337 ruleTablePanel.add(new KSLabel("No rules have been added"));
338 }
339 }
340
341 private void showRuleBeforeSimplify(StatementVO unsimplified) {
342 rule.setStatementVO(unsimplified);
343 rule.setSimplifying(true);
344 redraw(rule.getStatementVO().getStatementTreeViewInfo(), false, false);
345
346 Timer simplifyingTimer = new Timer() {
347 public void run() {
348 rule.setSimplifying(false);
349 rule.setStatementVO(rule.getEditHistory().getLastHistoricStmtVO());
350 redraw(rule.getStatementVO().getStatementTreeViewInfo(), false, true);
351 }
352 };
353 simplifyingTimer.schedule(1000);
354 }
355
356 public void setEnabledView(boolean enabled) {
357 setEnableButtons(enabled);
358 ruleTable.setEnabled(enabled);
359 isEnabled = enabled;
360 }
361
362 public void setEnableButtons(boolean enabled) {
363 if (enabled) {
364 btnMakeAND.setEnabled(isMatchingOperandSelected(Token.And) || rule.statementVOIsGroupAble());
365 btnMakeOR.setEnabled(isMatchingOperandSelected(Token.Or) || rule.statementVOIsGroupAble());
366 btnAddToGroup.setEnabled(rule.isAddToGroupOK());
367 btnUndo.setEnabled(rule.getEditHistory().isUndoable());
368 btnRedo.setEnabled(rule.getEditHistory().isRedoable());
369 btnDelete.setEnabled(isAbleToDelete());
370 btnMoveRuleUp.setEnabled(rule.getStatementVO().isNodeSelected() && !rule.getStatementVO().isFirstSelectedReqComp() && isAbletoMoveReqComp());
371 btnMoveRuleDown.setEnabled(rule.getStatementVO().isNodeSelected() && !rule.getStatementVO().isLastSelectedReqComp() && isAbletoMoveReqComp());
372 } else {
373 btnMakeAND.setEnabled(false);
374 btnMakeOR.setEnabled(false);
375 btnAddToGroup.setEnabled(false);
376 btnUndo.setEnabled(false);
377 btnRedo.setEnabled(false);
378 btnDelete.setEnabled(false);
379 btnMoveRuleUp.setEnabled(false);
380 btnMoveRuleDown.setEnabled(false);
381 }
382 }
383
384
385 private boolean isAbletoMoveReqComp() {
386 List<ReqComponentVO> selectedRCs = rule.getStatementVO().getSelectedReqComponentVOs();
387 List<StatementVO> selectedSs = rule.getStatementVO().getSelectedStatementVOs();
388 int numSelectedRCs = (selectedRCs == null)? 0 : selectedRCs.size();
389 int numSelectedSs = (selectedSs == null)? 0 : selectedSs.size();
390 return (numSelectedRCs == 1 && numSelectedSs == 0);
391 }
392
393
394 private boolean isMatchingOperandSelected(int type) {
395 List<StatementVO> selectedStmts = rule.getSelectedStatementVOs();
396 if (((rule.getSelectedReqComponentVOs() == null) || (rule.getSelectedReqComponentVOs().isEmpty())) && (selectedStmts.size() == 1)
397 && (((StatementVO)selectedStmts.get(0)).getType() != type)) {
398 return true;
399 }
400 return false;
401 }
402
403 private boolean isAbleToDelete() {
404
405 if ((rule.getSelectedStatementVOs() == null || rule.getSelectedStatementVOs().size() == 0) && (rule.getSelectedReqComponentVOs().size() > 1)) {
406 return true;
407 }
408
409 return rule.statementVOIsDegroupAble();
410 }
411
412 private void createButtonsPanel() {
413 final String ruleEditButton = "KS-Program-Rule-ObjectView-Button";
414
415 topButtonsPanel.setStyleName("KS-Program-Rule-ObjectView-ButtonPanel");
416 btnMakeAND.addStyleName(ruleEditButton);
417 btnMakeAND.addStyleName("KS-Program-Rule-ObjectView-AND-Button");
418 topButtonsPanel.add(btnMakeAND);
419 btnMakeOR.addStyleName("KS-Program-Rule-ObjectView-OR-Button");
420 btnMakeOR.addStyleName(ruleEditButton);
421 topButtonsPanel.add(btnMakeOR);
422
423
424 btnAddToGroup.addStyleName("KS-Program-Rule-ObjectView-Group-Button");
425 btnAddToGroup.addStyleName(ruleEditButton);
426 topButtonsPanel.add(btnAddToGroup);
427 btnMoveRuleUp.addStyleName("KS-Program-Rule-ObjectView-Up-Button");
428 btnMoveRuleUp.addStyleName(ruleEditButton);
429 topButtonsPanel.add(btnMoveRuleUp);
430 btnMoveRuleDown.addStyleName("KS-Program-Rule-ObjectView-Down-Button");
431 btnMoveRuleDown.addStyleName(ruleEditButton);
432 topButtonsPanel.add(btnMoveRuleDown);
433
434
435 btnUndo.addStyleName("KS-Program-Rule-ObjectView-Undo-Button");
436 btnUndo.addStyleName(ruleEditButton);
437 topButtonsPanel.add(btnUndo);
438 btnRedo.addStyleName("KS-Program-Rule-ObjectView-Redo-Button");
439 btnRedo.addStyleName(ruleEditButton);
440 topButtonsPanel.add(btnRedo);
441 btnDelete.addStyleName("KS-Program-Rule-ObjectView-Delete-Button");
442 btnDelete.addStyleName(ruleEditButton);
443 topButtonsPanel.add(btnDelete);
444 }
445
446 public RuleInfo getRule() {
447 return rule;
448 }
449
450 public void setRule(RuleInfo rule) {
451 this.rule = rule;
452 }
453
454 public void addReqCompEditButtonClickCallback(Callback<ReqComponentInfo> callback) {
455 reqCompEditCallback = callback;
456 }
457
458 public void addRuleChangedButtonClickCallback(Callback<Boolean> callback) {
459 ruleChangedCallback = callback;
460 }
461 }