Update of /cvsroot/unitime/UniTime/JavaSource/org/unitime/timetable/gwt/client/sectioning In directory sfp-cvsdas-2.v30.ch3.sourceforge.com:/tmp/cvs-serv14262/JavaSource/org/unitime/timetable/gwt/client/sectioning Modified Files: SuggestionsBox.java TimeGrid.java CourseRequestsTable.java CourseSelectionBox.java StudentSectioningWidget.java Log Message: Student Scheduling Assistant - Adopted to use the new priority weighting model - adding penalization for sections without time assignment, over expected sections, and sections that have a different time or instructor than selected - Only show Enroll button when it is available - Show LoadingWidget while waiting - Display free time requests as red background in the timetable grid Index: CourseRequestsTable.java =================================================================== RCS file: /cvsroot/unitime/UniTime/JavaSource/org/unitime/timetable/gwt/client/sectioning/CourseRequestsTable.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** CourseRequestsTable.java 1 Dec 2010 11:10:50 -0000 1.2 --- CourseRequestsTable.java 13 Jan 2011 23:08:47 -0000 1.3 *************** *** 24,29 **** import org.unitime.timetable.gwt.client.ToolBox; ! import org.unitime.timetable.gwt.client.widgets.ValidationErrors; ! import org.unitime.timetable.gwt.client.widgets.Validator; import org.unitime.timetable.gwt.resources.StudentSectioningConstants; import org.unitime.timetable.gwt.resources.StudentSectioningMessages; --- 24,28 ---- import org.unitime.timetable.gwt.client.ToolBox; ! import org.unitime.timetable.gwt.client.widgets.LoadingWidget; import org.unitime.timetable.gwt.resources.StudentSectioningConstants; import org.unitime.timetable.gwt.resources.StudentSectioningMessages; *************** *** 67,71 **** private FlexTable iGrid; private AcademicSessionProvider iSessionProvider; - private ValidationErrors iValidator; private ArrayList<CourseSelectionBox[]> iCourses; private ArrayList<CourseSelectionBox[]> iAlternatives; --- 66,69 ---- *************** *** 305,310 **** private void init() { - iValidator = new ValidationErrors(false, MESSAGES.courseRequestsScheduling(), MESSAGES.validationFailed(), false); - CourseSelectionBox.Validator checkForDuplicities = new CourseSelectionBox.Validator() { public String validate(CourseSelectionBox source) { --- 303,306 ---- *************** *** 390,396 **** c[1].addValidator(checkForDuplicities); c[2].addValidator(checkForDuplicities); - iValidator.addValidator(c[0]); - iValidator.addValidator(c[1]); - iValidator.addValidator(c[2]); } --- 386,389 ---- *************** *** 466,492 **** c[1].addValidator(checkForDuplicities); c[2].addValidator(checkForDuplicities); - iValidator.addValidator(c[0]); - iValidator.addValidator(c[1]); - iValidator.addValidator(c[2]); } ! ! iValidator.addValidator(new Validator() { ! public void validate(final AsyncCallback<String> callback) { ! CourseRequestInterface cr = new CourseRequestInterface(); ! cr.setAcademicSessionId(iSessionProvider.getAcademicSessionId()); ! fillInCourses(cr); fillInAlternatives(cr); ! iSectioningService.checkCourses(cr, ! new AsyncCallback<Collection<String>>() { ! public void onSuccess(Collection<String> result) { ! for (String course: result) ! setError(course, MESSAGES.validationCourseNotExists(course)); ! callback.onSuccess(result.isEmpty() ? null : MESSAGES.validationUnknownCourseNotExists()); ! } ! public void onFailure(Throwable caught) { ! callback.onFailure(caught); ! } ! }); } ! }); } --- 459,491 ---- c[1].addValidator(checkForDuplicities); c[2].addValidator(checkForDuplicities); } ! } ! ! public void validate(final AsyncCallback<Boolean> callback) { ! String failed = null; ! LoadingWidget.getInstance().show(MESSAGES.courseRequestsValidating()); ! for (final CourseSelectionBox[] c: iCourses) { ! for (CourseSelectionBox x: c) { ! String message = x.validate(); ! if (message != null) failed = message; } ! } ! CourseRequestInterface cr = new CourseRequestInterface(); ! cr.setAcademicSessionId(iSessionProvider.getAcademicSessionId()); ! fillInCourses(cr); fillInAlternatives(cr); ! final boolean success = (failed == null); ! iSectioningService.checkCourses(cr, ! new AsyncCallback<Collection<String>>() { ! public void onSuccess(Collection<String> result) { ! for (String course: result) ! setError(course, MESSAGES.validationCourseNotExists(course)); ! LoadingWidget.getInstance().hide(); ! callback.onSuccess(success && result.isEmpty()); ! } ! public void onFailure(Throwable caught) { ! LoadingWidget.getInstance().hide(); ! callback.onFailure(caught); ! } ! }); } *************** *** 509,516 **** } - public ValidationErrors getValidator() { - return iValidator; - } - public void fillInCourses(CourseRequestInterface cr) { for (CourseSelectionBox[] course: iCourses) { --- 508,511 ---- Index: CourseSelectionBox.java =================================================================== RCS file: /cvsroot/unitime/UniTime/JavaSource/org/unitime/timetable/gwt/client/sectioning/CourseSelectionBox.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** CourseSelectionBox.java 11 Jan 2011 16:51:45 -0000 1.4 --- CourseSelectionBox.java 13 Jan 2011 23:08:47 -0000 1.5 *************** *** 28,32 **** import org.unitime.timetable.gwt.client.widgets.UniTimeDialogBox; import org.unitime.timetable.gwt.client.widgets.UniTimeTabPanel; - import org.unitime.timetable.gwt.client.widgets.Validator; import org.unitime.timetable.gwt.client.widgets.WebTable; import org.unitime.timetable.gwt.client.widgets.WebTable.RowDoubleClickEvent; --- 28,31 ---- *************** *** 91,95 **** * @author Tomas Muller */ ! public class CourseSelectionBox extends Composite implements Validator { public static final StudentSectioningResources RESOURCES = GWT.create(StudentSectioningResources.class); public static final StudentSectioningMessages MESSAGES = GWT.create(StudentSectioningMessages.class); --- 90,94 ---- * @author Tomas Muller */ ! public class CourseSelectionBox extends Composite { public static final StudentSectioningResources RESOURCES = GWT.create(StudentSectioningResources.class); public static final StudentSectioningMessages MESSAGES = GWT.create(StudentSectioningMessages.class); *************** *** 1000,1008 **** } ! public void validate(final AsyncCallback<String> callback) { if (iTextField.getText().isEmpty() || iTextField.getText().equals(iHint)) { iError.setVisible(false); ! callback.onSuccess(null); ! return; } if (iAllowFreeTime) { --- 999,1006 ---- } ! public String validate() { if (iTextField.getText().isEmpty() || iTextField.getText().equals(iHint)) { iError.setVisible(false); ! return null; } if (iAllowFreeTime) { *************** *** 1010,1015 **** parseFreeTime(iTextField.getText()); iError.setVisible(false); ! callback.onSuccess(null); ! return; } catch (IllegalArgumentException e) { if (iTextField.getText().toLowerCase().startsWith(CONSTANTS.freePrefix().toLowerCase())) { --- 1008,1012 ---- parseFreeTime(iTextField.getText()); iError.setVisible(false); ! return null; } catch (IllegalArgumentException e) { if (iTextField.getText().toLowerCase().startsWith(CONSTANTS.freePrefix().toLowerCase())) { *************** *** 1017,1022 **** iError.setTitle(e.getMessage()); iError.setVisible(true); ! callback.onSuccess(e.getMessage()); ! return; } } --- 1014,1018 ---- iError.setTitle(e.getMessage()); iError.setVisible(true); ! return e.getMessage(); } } *************** *** 1028,1037 **** iError.setTitle(null); iError.setVisible(true); ! callback.onSuccess(message); ! return ; } } iError.setVisible(false); ! callback.onSuccess(null); } --- 1024,1032 ---- iError.setTitle(null); iError.setVisible(true); ! return message; } } iError.setVisible(false); ! return null; } Index: StudentSectioningWidget.java =================================================================== RCS file: /cvsroot/unitime/UniTime/JavaSource/org/unitime/timetable/gwt/client/sectioning/StudentSectioningWidget.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** StudentSectioningWidget.java 10 Dec 2010 22:25:03 -0000 1.3 --- StudentSectioningWidget.java 13 Jan 2011 23:08:47 -0000 1.4 *************** *** 26,29 **** --- 26,30 ---- import org.unitime.timetable.gwt.client.sectioning.TimeGrid.Meeting; import org.unitime.timetable.gwt.client.widgets.ImageLink; + import org.unitime.timetable.gwt.client.widgets.LoadingWidget; import org.unitime.timetable.gwt.client.widgets.UniTimeTabPanel; import org.unitime.timetable.gwt.client.widgets.WebTable; *************** *** 253,257 **** iCourseRequests.changeTip(); iErrorMessage.setHTML(""); ! iCourseRequests.getValidator().validate(new AsyncCallback<Boolean>() { public void onSuccess(Boolean result) { updateHistory(); --- 254,258 ---- iCourseRequests.changeTip(); iErrorMessage.setHTML(""); ! iCourseRequests.validate(new AsyncCallback<Boolean>() { public void onSuccess(Boolean result) { updateHistory(); *************** *** 269,277 **** } }); iSectioningService.section(iCourseRequests.getRequest(), iLastResult, new AsyncCallback<ClassAssignmentInterface>() { public void onFailure(Throwable caught) { iErrorMessage.setHTML(caught.getMessage()); iErrorMessage.setVisible(true); ! iCourseRequests.getValidator().hide(); updateHistory(); } --- 270,279 ---- } }); + LoadingWidget.getInstance().show(MESSAGES.courseRequestsScheduling()); iSectioningService.section(iCourseRequests.getRequest(), iLastResult, new AsyncCallback<ClassAssignmentInterface>() { public void onFailure(Throwable caught) { iErrorMessage.setHTML(caught.getMessage()); iErrorMessage.setVisible(true); ! LoadingWidget.getInstance().hide(); updateHistory(); } *************** *** 284,288 **** iErrorMessage.setHTML(MESSAGES.validationFailed()); iErrorMessage.setVisible(true); ! iCourseRequests.getValidator().hide(); updateHistory(); } --- 286,290 ---- iErrorMessage.setHTML(MESSAGES.validationFailed()); iErrorMessage.setVisible(true); ! LoadingWidget.getInstance().hide(); updateHistory(); } *************** *** 291,295 **** iErrorMessage.setHTML(MESSAGES.validationFailed()); iErrorMessage.setVisible(true); ! iCourseRequests.getValidator().hide(); updateHistory(); } --- 293,297 ---- iErrorMessage.setHTML(MESSAGES.validationFailed()); iErrorMessage.setVisible(true); ! LoadingWidget.getInstance().hide(); updateHistory(); } *************** *** 424,431 **** iCourseRequests.changeTip(); iErrorMessage.setHTML(""); ! iCourseRequests.getValidator().validate(new AsyncCallback<Boolean>() { public void onSuccess(Boolean result) { updateHistory(); if (result) { iSectioningService.saveRequest(iCourseRequests.getRequest(), new AsyncCallback<Boolean>() { public void onSuccess(Boolean result) { --- 426,434 ---- iCourseRequests.changeTip(); iErrorMessage.setHTML(""); ! iCourseRequests.validate(new AsyncCallback<Boolean>() { public void onSuccess(Boolean result) { updateHistory(); if (result) { + LoadingWidget.getInstance().show(MESSAGES.courseRequestsSaving()); iSectioningService.saveRequest(iCourseRequests.getRequest(), new AsyncCallback<Boolean>() { public void onSuccess(Boolean result) { *************** *** 434,443 **** iErrorMessage.setVisible(true); } ! iCourseRequests.getValidator().hide(); } public void onFailure(Throwable caught) { iErrorMessage.setHTML(MESSAGES.saveRequestsFail(caught.getMessage())); iErrorMessage.setVisible(true); ! iCourseRequests.getValidator().hide(); } }); --- 437,446 ---- iErrorMessage.setVisible(true); } ! LoadingWidget.getInstance().hide(); } public void onFailure(Throwable caught) { iErrorMessage.setHTML(MESSAGES.saveRequestsFail(caught.getMessage())); iErrorMessage.setVisible(true); ! LoadingWidget.getInstance().hide(); } }); *************** *** 445,449 **** iErrorMessage.setHTML(MESSAGES.validationFailed()); iErrorMessage.setVisible(true); ! iCourseRequests.getValidator().hide(); updateHistory(); } --- 448,452 ---- iErrorMessage.setHTML(MESSAGES.validationFailed()); iErrorMessage.setVisible(true); ! LoadingWidget.getInstance().hide(); updateHistory(); } *************** *** 452,456 **** iErrorMessage.setHTML(MESSAGES.validationFailed()); iErrorMessage.setVisible(true); ! iCourseRequests.getValidator().hide(); updateHistory(); } --- 455,459 ---- iErrorMessage.setHTML(MESSAGES.validationFailed()); iErrorMessage.setVisible(true); ! LoadingWidget.getInstance().hide(); updateHistory(); } *************** *** 485,490 **** iAssignments.setSelectedRow(rowIndex); iErrorMessage.setVisible(false); ! iSuggestionsBox.setRow(iCourseRequests.getRequest(), iLastResult, rowIndex); ! iSuggestionsBox.center(); } --- 488,492 ---- iAssignments.setSelectedRow(rowIndex); iErrorMessage.setVisible(false); ! iSuggestionsBox.open(iCourseRequests.getRequest(), iLastResult, rowIndex); } *************** *** 497,500 **** --- 499,517 ---- ArrayList<WebTable.Row> rows = new ArrayList<WebTable.Row>(); iAssignmentGrid.clear(); + CourseRequestInterface req = iCourseRequests.getRequest(); + for (CourseRequestInterface.Request r: req.getCourses()) { + if (r.hasRequestedFreeTime()) { + for (CourseRequestInterface.FreeTime ft: r.getRequestedFreeTime()) { + iAssignmentGrid.addFreeTime(ft); + } + } + } + for (CourseRequestInterface.Request r: req.getAlternatives()) { + if (r.hasRequestedFreeTime()) { + for (CourseRequestInterface.FreeTime ft: r.getRequestedFreeTime()) { + iAssignmentGrid.addFreeTime(ft); + } + } + } for (ClassAssignmentInterface.CourseAssignment course: result.getCourseAssignments()) { if (course.isAssigned()) { *************** *** 522,526 **** (clazz.isSaved() ? new WebTable.IconCell(RESOURCES.saved(), null, null) : new WebTable.Cell("")), (clazz.isOfHighDemand() ? new WebTable.IconCell(RESOURCES.highDemand(), MESSAGES.highDemand(clazz.getExpected(), clazz.getAvailableLimit()), null) : new WebTable.Cell(""))); ! final ArrayList<TimeGrid.Meeting> meetings = iAssignmentGrid.addClass(clazz, rows.size()); // row.setId(course.isFreeTime() ? "Free " + clazz.getDaysString() + " " +clazz.getStartString() + " - " + clazz.getEndString() : course.getCourseId() + ":" + clazz.getClassId()); final int index = rows.size(); --- 539,543 ---- (clazz.isSaved() ? new WebTable.IconCell(RESOURCES.saved(), null, null) : new WebTable.Cell("")), (clazz.isOfHighDemand() ? new WebTable.IconCell(RESOURCES.highDemand(), MESSAGES.highDemand(clazz.getExpected(), clazz.getAvailableLimit()), null) : new WebTable.Cell(""))); ! final ArrayList<TimeGrid.Meeting> meetings = (clazz.isFreeTime() ? null : iAssignmentGrid.addClass(clazz, rows.size())); // row.setId(course.isFreeTime() ? "Free " + clazz.getDaysString() + " " +clazz.getStartString() + " - " + clazz.getEndString() : course.getCourseId() + ":" + clazz.getClassId()); final int index = rows.size(); *************** *** 600,608 **** iAssignmentPanel.setWidth(iAssignmentGrid.getWidth()); iAssignments.setData(rowArray); ! iCourseRequests.getValidator().hide(); iPanel.remove(iCourseRequests); iPanel.insert(iAssignmentPanelWithFocus, 0); iPrev.setVisible(true); ! iEnroll.setVisible(true); iPrint.setVisible(true); iExport.setVisible(true); --- 617,626 ---- iAssignmentPanel.setWidth(iAssignmentGrid.getWidth()); iAssignments.setData(rowArray); ! if (LoadingWidget.getInstance().isShowing()) ! LoadingWidget.getInstance().hide(); iPanel.remove(iCourseRequests); iPanel.insert(iAssignmentPanelWithFocus, 0); iPrev.setVisible(true); ! iEnroll.setVisible(result.isCanEnroll()); iPrint.setVisible(true); iExport.setVisible(true); *************** *** 622,626 **** } else { iErrorMessage.setHTML(MESSAGES.noSchedule()); ! iCourseRequests.getValidator().hide(); } } --- 640,645 ---- } else { iErrorMessage.setHTML(MESSAGES.noSchedule()); ! if (LoadingWidget.getInstance().isShowing()) ! LoadingWidget.getInstance().fail(MESSAGES.noSchedule()); } } Index: TimeGrid.java =================================================================== RCS file: /cvsroot/unitime/UniTime/JavaSource/org/unitime/timetable/gwt/client/sectioning/TimeGrid.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** TimeGrid.java 1 Dec 2010 11:10:50 -0000 1.2 --- TimeGrid.java 13 Jan 2011 23:08:47 -0000 1.3 *************** *** 29,32 **** --- 29,33 ---- import org.unitime.timetable.gwt.resources.StudentSectioningResources; import org.unitime.timetable.gwt.shared.ClassAssignmentInterface; + import org.unitime.timetable.gwt.shared.CourseRequestInterface; import com.google.gwt.core.client.GWT; *************** *** 83,86 **** --- 84,88 ---- private ArrayList<PinClickHandler> iPinClickHandlers = new ArrayList<PinClickHandler>(); private ArrayList<ClassAssignmentInterface.ClassAssignment> iClasses = new ArrayList<ClassAssignmentInterface.ClassAssignment>(); + private ArrayList<BusyPanel> iBusy = new ArrayList<BusyPanel>(); public TimeGrid() { *************** *** 183,186 **** --- 185,197 ---- } + public void addFreeTime(CourseRequestInterface.FreeTime ft) { + for (int day: ft.getDays()) + addBusy(day, ft.getStart(), ft.getLength()); + } + + private void addBusy(int day, int start, int length) { + iBusy.add(new BusyPanel(day, start, length)); + } + public void setCalendarUrl(String url) { iCalendar.setUrl(url); *************** *** 198,201 **** --- 209,214 ---- m.addStyleName("meeting-selected-noshadow"); } + for (BusyPanel busy: iBusy) + tg.addBusy(busy.getDay(), busy.getStart(), busy.getLength()); return tg; } *************** *** 238,241 **** --- 251,256 ---- for (Meeting meeting: meetings) meeting.move(); + for (BusyPanel busy: iBusy) + busy.move(); } *************** *** 266,269 **** --- 281,288 ---- if (iMeetingTable[6][slot] !=null && !iMeetingTable[6][slot].isEmpty()) hasSun = true; } + for (BusyPanel busy: iBusy) { + if (busy.getDay() == 5) hasSat = true; + if (busy.getDay() == 6) hasSun = true; + } if (!hasSat && !hasSun) setNrDays(5); else if (!hasSun) setNrDays(6); *************** *** 296,299 **** --- 315,321 ---- iColor.clear(); iClasses.clear(); + for (BusyPanel busy: iBusy) + busy.remove(); + iBusy.clear(); } *************** *** 659,661 **** --- 681,711 ---- } } + + private class BusyPanel extends SimplePanel { + private int iDayOfWeek, iStartSlot, iLength; + + public BusyPanel(int dayOfWeek, int startSlot, int length) { + super(); + iDayOfWeek = dayOfWeek; + iStartSlot = startSlot; + iLength = length; + setStyleName("busy"); + setSize(String.valueOf(iCellWidth + (iPrint ? 3 : iDayOfWeek + 1 < iNrDays ? 3 : 0)), String.valueOf(125 * iLength / 30)); + iGrid.insert(this, iCellWidth * iDayOfWeek, 125 * iStartSlot / 30 - 50 * iStart, 1); + } + + public void move() { + setWidth(String.valueOf(iCellWidth + (iPrint ? 3 : iDayOfWeek + 1 < iNrDays ? 3 : 0))); + DOM.setStyleAttribute(getElement(), "left", String.valueOf(iCellWidth * iDayOfWeek)); + } + + public int getDay() { return iDayOfWeek; } + public int getStart() { return iStartSlot; } + public int getLength() { return iLength; } + + public void remove() { + iGrid.remove(this); + } + + } } Index: SuggestionsBox.java =================================================================== RCS file: /cvsroot/unitime/UniTime/JavaSource/org/unitime/timetable/gwt/client/sectioning/SuggestionsBox.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** SuggestionsBox.java 1 Dec 2010 11:10:50 -0000 1.2 --- SuggestionsBox.java 13 Jan 2011 23:08:47 -0000 1.3 *************** *** 23,26 **** --- 23,27 ---- import java.util.Collection; + import org.unitime.timetable.gwt.client.widgets.LoadingWidget; import org.unitime.timetable.gwt.client.widgets.WebTable; import org.unitime.timetable.gwt.client.widgets.WebTable.RowClickEvent; *************** *** 96,100 **** iSuggestions.setEmptyMessage(MESSAGES.suggestionsLoading()); iSuggestionsScroll = new ScrollPanel(iSuggestions); ! iSuggestionsScroll.setSize("950", "400"); iSuggestionsScroll.setStyleName("unitime-ScrollPanel"); suggestionPanel.add(iSuggestionsScroll); --- 97,101 ---- iSuggestions.setEmptyMessage(MESSAGES.suggestionsLoading()); iSuggestionsScroll = new ScrollPanel(iSuggestions); ! iSuggestionsScroll.setHeight("400"); iSuggestionsScroll.setStyleName("unitime-ScrollPanel"); suggestionPanel.add(iSuggestionsScroll); *************** *** 108,111 **** --- 109,114 ---- iSuggestions.setEmptyMessage("<font color='red'>" + caught.getMessage() + "</font>"); iMessages.setHTML(""); + LoadingWidget.getInstance().hide(); + center(); } *************** *** 116,119 **** --- 119,124 ---- iSuggestions.clearData(true); iSuggestions.setEmptyMessage(MESSAGES.suggestionsNoAlternative(iSource)); + LoadingWidget.getInstance().hide(); + center(); } else { ArrayList<WebTable.Row> rows = new ArrayList<WebTable.Row>(); *************** *** 301,306 **** for (WebTable.Row row: rows) rowArray[idx++] = row; iSuggestions.setData(rowArray); ! if (rows.isEmpty()) iSuggestions.setEmptyMessage(MESSAGES.suggestionsNoAlternative(iSource)); } } --- 306,314 ---- for (WebTable.Row row: rows) rowArray[idx++] = row; iSuggestions.setData(rowArray); ! if (rows.isEmpty()) { iSuggestions.setEmptyMessage(MESSAGES.suggestionsNoAlternative(iSource)); + } + LoadingWidget.getInstance().hide(); + center(); } } *************** *** 331,335 **** } ! public void setRow(CourseRequestInterface request, ArrayList<ClassAssignmentInterface.ClassAssignment> rows, int index) { ClassAssignmentInterface.ClassAssignment row = rows.get(index); iAssignment = row; --- 339,344 ---- } ! public void open(CourseRequestInterface request, ArrayList<ClassAssignmentInterface.ClassAssignment> rows, int index) { ! LoadingWidget.getInstance().show(MESSAGES.suggestionsLoading()); ClassAssignmentInterface.ClassAssignment row = rows.get(index); iAssignment = row; |