diff options
author | Jonathan Bauer | 2016-03-15 14:08:22 +0100 |
---|---|---|
committer | Jonathan Bauer | 2016-03-15 14:08:22 +0100 |
commit | 400fc72fc9d606e56a1d20efba37514b556aed30 (patch) | |
tree | 6fc23ba996283b952c5170d5647396506c37a777 /dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LectureDetailsWindow.java | |
parent | [client] fix '.part' not beeing removed from TransferPanel when the transfer ... (diff) | |
download | tutor-module-400fc72fc9d606e56a1d20efba37514b556aed30.tar.gz tutor-module-400fc72fc9d606e56a1d20efba37514b556aed30.tar.xz tutor-module-400fc72fc9d606e56a1d20efba37514b556aed30.zip |
[client] reworked lecture details window
now uses tabs for subsets of options - clearing up the gui a bit
Diffstat (limited to 'dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LectureDetailsWindow.java')
-rw-r--r-- | dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LectureDetailsWindow.java | 351 |
1 files changed, 213 insertions, 138 deletions
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LectureDetailsWindow.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LectureDetailsWindow.java index df91e811..c4b3700e 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LectureDetailsWindow.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LectureDetailsWindow.java @@ -6,6 +6,8 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.ArrayList; @@ -22,6 +24,7 @@ import java.util.Map.Entry; import javax.swing.DefaultComboBoxModel; import javax.swing.JFrame; import javax.swing.JOptionPane; +import javax.swing.JRadioButton; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; @@ -37,6 +40,12 @@ import org.openslx.bwlp.thrift.iface.UserInfo; import org.openslx.dozmod.gui.Gui; import org.openslx.dozmod.gui.MainWindow; import org.openslx.dozmod.gui.control.AdvancedConfigurator.AdvancedConfiguration; +import org.openslx.dozmod.gui.control.AdvancedConfigurator.AdvancedConfigurationChangeEvent; +import org.openslx.dozmod.gui.control.AdvancedConfigurator.AdvancedConfigurationChangeEventListener; +import org.openslx.dozmod.gui.control.JCheckBoxTree.CheckChangeEvent; +import org.openslx.dozmod.gui.control.JCheckBoxTree.CheckChangeEventListener; +import org.openslx.dozmod.gui.control.LectureCustomPermissionManager.UserChangeEvent; +import org.openslx.dozmod.gui.control.LectureCustomPermissionManager.UserChangeEventListener; import org.openslx.dozmod.gui.helper.DateTimeHelper; import org.openslx.dozmod.gui.helper.MessageType; import org.openslx.dozmod.gui.helper.TextChangeListener; @@ -50,7 +59,6 @@ import org.openslx.dozmod.thrift.ThriftActions; import org.openslx.dozmod.thrift.ThriftActions.DownloadCallback; import org.openslx.dozmod.thrift.ThriftActions.LectureMetaCallback; import org.openslx.dozmod.thrift.ThriftError; -import org.openslx.dozmod.thrift.cache.MetaDataCache; import org.openslx.dozmod.thrift.cache.UserCache; import org.openslx.dozmod.util.FormatHelper; import org.openslx.dozmod.util.MapHelper; @@ -105,20 +113,36 @@ public class LectureDetailsWindow extends LectureDetailsWindowLayout implements */ private ImageDetailsRead image = null; + /** + * Flag indicating a change in this lecture's linked image + */ private boolean imageLinkChanged = false; + /** + * Flag indicating a change in this lecture's metadata + */ private boolean metadataChanged = false; + /** + * Flag indicating a change in this lecture's permissions + */ private boolean permissionsChanged = false; + /** + * Holder of the location information of this lecture + */ private LocationInfo locationInfo = null; + /** + * Holder of the netrules/runscript of this lecture + */ private AdvancedConfiguration currentAdvConf = null; /** * Constructor * * @param modalParent parent of this popup window + * @param callback function to be called when a lecture update occured */ public LectureDetailsWindow(Frame modalParent, LectureUpdatedCallback callback) { super(modalParent); @@ -127,6 +151,7 @@ public class LectureDetailsWindow extends LectureDetailsWindowLayout implements this.callback = callback; setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); + addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { @@ -176,16 +201,6 @@ public class LectureDetailsWindow extends LectureDetailsWindowLayout implements cboVersions.setEnabled(!chkAutoUpdate.isSelected()); } }); - btnAdvancedOptions.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - AdvancedConfiguration conf = LectureAdvancedSettingsWindow.open(JOptionPane.getFrameForComponent(me), currentAdvConf); - if (conf == null) - return; - currentAdvConf = conf; - reactToChange(); - } - }); btnChangeOwner.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -201,48 +216,61 @@ public class LectureDetailsWindow extends LectureDetailsWindowLayout implements }, "Besitzer festlegen", lecture.ownerId); } }); - btnPermissions.addActionListener(new ActionListener() { + + final ActionListener changeReacter = new ActionListener() { @Override - public void actionPerformed(ActionEvent arg0) { - // NOTE once the following window is closed, customPermissions and lecture.defaultPermissions - // objects will contain the changes the user did. We will later only compare these with - // the original values as saved in originalCustomPermissions and originalDefaultPermissions - LecturePermissionWindow.open(me, customPermissions, lecture.defaultPermissions, - lecture.ownerId); + public void actionPerformed(ActionEvent e) { reactToChange(); } - }); - btnLocations.addActionListener(new ActionListener() { + }; + + ctlLocationSelector.getTree().addCheckChangeEventListener(new CheckChangeEventListener() { @Override - public void actionPerformed(ActionEvent e) { - LocationInfo ret = LocationSelectionWindow.open(me, locationInfo.locationList, locationInfo.limitToLocations); - if (ret == null) { - // nothing changed - return; - } - // TODO check size of returns - locationInfo = ret; + public void checkStateChanged(CheckChangeEvent event) { reactToChange(); } }); - if (MetaDataCache.getLocations() == null || MetaDataCache.getLocations().isEmpty()) { - btnLocations.setVisible(false); + for (JRadioButton btn : ctlLocationSelector.getButtons()) { + btn.addActionListener(changeReacter); } - - btnSaveChanges.addActionListener(new ActionListener() { + final ActionListener updateDefaultPermissionListener = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - saveChanges(); + ctlPermissionManager.updateDefaultPermissions(chkCustomPermAdmin.isSelected(), + chkCustomPermEdit.isSelected()); + reactToChange(); + } + }; + chkCustomPermAdmin.addActionListener(updateDefaultPermissionListener); + chkCustomPermEdit.addActionListener(updateDefaultPermissionListener); + ctlPermissionManager.getTable().addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + reactToChange(); + } + }); + ctlPermissionManager.addUserChangeEventListener(new UserChangeEventListener() { + @Override + public void stateChanged(UserChangeEvent event) { + reactToChange(); } }); + chkCustomPermAdmin.addActionListener(changeReacter); + chkCustomPermEdit.addActionListener(changeReacter); - // final step, add listeners to react to change + ctlAdvancedConfigurator.addAdvancedConfigurationChangeEventListener(new AdvancedConfigurationChangeEventListener() { + @Override + public void stateChanged(AdvancedConfigurationChangeEvent event) { + btnSaveChanges.setEnabled(ctlAdvancedConfigurator.hasChanged()); + } + }); final TextChangeListener docListener = new TextChangeListener() { @Override public void changed() { reactToChange(); } }; + txtTitle.getDocument().addDocumentListener(docListener); txtDescription.getDocument().addDocumentListener(docListener); @@ -282,10 +310,17 @@ public class LectureDetailsWindow extends LectureDetailsWindowLayout implements // save default color of date/time stuff to reset the background later dateTimeTextColor = dtpStartDate.getForeground(); + // last step, the save button + btnSaveChanges.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + saveChanges(); + } + }); // disable save button btnSaveChanges.setEnabled(false); // wait for the image to be loaded before (potentially) enabling fields - makeEditable(false); + toggleEditable(false); } /** @@ -308,28 +343,30 @@ public class LectureDetailsWindow extends LectureDetailsWindowLayout implements if (lecture != null) { customPermissions = ThriftActions.getLecturePermissions( JOptionPane.getFrameForComponent(me), lecture.lectureId); - locationInfo = new LocationInfo(lecture.locationIds, lecture.limitToLocations); } + fillDetails(); } - fillDetails(); } }); } /** - * callback function when we received the lecture's details from the server + * Internal callback function when we received the lecture's details from the server */ private void fillDetails() { if (lecture == null) { txtTitle.setText("-"); - makeEditable(false); + lblTitleInfo.setText("-"); + toggleEditable(false); return; } - + LOGGER.debug("LECT: " + lecture); if (image == null) { txtImageName.setText("-"); + lblImageNameInfo.setText("-"); } else { txtImageName.setText(image.getImageName()); + lblImageNameInfo.setText(image.getImageName()); } // remember original advanced config currentAdvConf = new AdvancedConfiguration(lecture.networkExceptions, lecture.runscript); @@ -350,10 +387,24 @@ public class LectureDetailsWindow extends LectureDetailsWindowLayout implements originalCustomPermissions.put(entry.getKey(), new LecturePermissions(entry.getValue())); } } - + // init permission info + ctlPermissionManager.initPanel(customPermissions, lecture.defaultPermissions, lecture.ownerId); + chkCustomPermAdmin.setSelected(lecture.defaultPermissions.admin); + chkCustomPermEdit.setSelected(lecture.defaultPermissions.edit); + // init location info + locationInfo = new LocationInfo(lecture.locationIds, lecture.limitToLocations); + ctlLocationSelector.setOnlyInSelection(locationInfo.limitToLocations); + ctlLocationSelector.setSelectedLocationsAsIds(locationInfo.locationList); + // advanced config stuff, save current information + currentAdvConf = new AdvancedConfiguration(lecture.networkExceptions, lecture.runscript); + // init advanced info + ctlAdvancedConfigurator.setState(new AdvancedConfiguration(lecture.networkExceptions, lecture.runscript)); + txtTitle.setText(lecture.getLectureName()); + lblTitleInfo.setText(lecture.getLectureName()); txtDescription.setText(lecture.getDescription()); lblOwner.setUser(UserCache.find(lecture.getOwnerId())); + lblOwnerInfo.setUser(UserCache.find(lecture.getOwnerId())); lblUpdater.setUser(UserCache.find(lecture.getUpdaterId())); lblCreateTime.setText(FormatHelper.longDate(lecture.getCreateTime())); lblUpdateTime.setText(FormatHelper.longDate(lecture.getUpdateTime())); @@ -369,7 +420,6 @@ public class LectureDetailsWindow extends LectureDetailsWindowLayout implements cboVersions.setEnabled(!lecture.autoUpdate); lblUseCount.setText(Integer.toString(lecture.useCount)); - fillVersionsCombo(); Calendar startCal = Calendar.getInstance(); @@ -384,7 +434,10 @@ public class LectureDetailsWindow extends LectureDetailsWindowLayout implements endCal.get(Calendar.DATE)); spnEndTime.getModel().setValue(endCal.getTime()); - makeEditable(true); + // now enable the tabs the user can see given its permissions + toggleEditable(true); + // and always switch to the "About" tab + pnlTabs.setSelectedIndex(pnlTabs.indexOfTab("Übersicht")); setVisible(true); } @@ -433,7 +486,7 @@ public class LectureDetailsWindow extends LectureDetailsWindowLayout implements // success Gui.showMessageBox(me, "Besitzrechte übertragen an " + FormatHelper.userName(user), MessageType.INFO, null, null); - makeEditable(false); + toggleEditable(false); String lectureId = lecture.getLectureId(); synchronized (me) { image = null; @@ -484,7 +537,87 @@ public class LectureDetailsWindow extends LectureDetailsWindowLayout implements } /** - * Push the changes of the image details to the satellite + * Checks whether the user changed any fields of the image details and + * enables the save button if so. + */ + private void reactToChange() { + // before checks we need to update the local objects holding the information of the "widgets" + // update the location information + locationInfo = new LocationInfo(ctlLocationSelector.getSelectedLocationsAsIds(), + ctlLocationSelector.getOnlyInSelection()); + // update the custom permissions + customPermissions = ctlPermissionManager.updatePermissionReferences(); + // NOTE: AdvancedConfiguration stuff will only get checked when clicking "Save" since + // checking for rules syntax while the user is still typing does not make much sense... + // now we can check for changes + metadataChanged = reactToChangeInternal(); + permissionsChanged = MapHelper.hasChanged(originalCustomPermissions, customPermissions); + btnSaveChanges.setEnabled(metadataChanged || permissionsChanged); + } + + /** + * Checks whether the user changed any fields of the image details and + * enables the save button if so. + */ + private boolean reactToChangeInternal() { + if (lecture == null) + return false; + + boolean changed = false; + // mandatory fields checks + if (txtTitle.getText().isEmpty()) { + pnlTabs.setSelectedIndex(pnlTabs.indexOfTab("Allgemein")); + lblError.setText("Kein Veranstaltungsname gesetzt!"); + return false; + } + if (txtDescription.getText().isEmpty()) { + pnlTabs.setSelectedIndex(pnlTabs.indexOfTab("Allgemein")); + lblError.setText("Keine Beschreibung angegeben!"); + return false; + } + // version checkbox changed? + ImageVersionDetails currentVersion = cboVersions.getItemAt(cboVersions.getSelectedIndex()); + if (currentVersion == null) { + pnlTabs.setSelectedIndex(pnlTabs.indexOfTab("Allgemein")); + lblError.setText("Keine Version ausgewählt!"); + return false; + } + // Date stuff + Date start = DateTimeHelper.getDateFrom(dtpStartDate, spnStartTime); + Date end = DateTimeHelper.getDateFrom(dtpEndDate, spnEndTime); + if (!isPeriodValid(start, end, false) && dateHasChanged()) { + pnlTabs.setSelectedIndex(pnlTabs.indexOfTab("Allgemein")); + lblError.setText("Ungültiger Zeitraum!"); + return false; + } + + // done with mandatory checks, remove error message + lblError.setText(null); + + // check for changes in all fields + changed = !txtTitle.getText().equals(lecture.getLectureName()) + || !txtDescription.getText().equals(lecture.getDescription()) + || !currentVersion.getVersionId().equals(lecture.getImageVersionId()) + || (DateTimeHelper.getDateFrom(dtpStartDate, spnStartTime).getTime() / 1000L) != lecture.getStartTime() + || (DateTimeHelper.getDateFrom(dtpEndDate, spnEndTime).getTime() / 1000L) != lecture.getEndTime() + || chkAutoUpdate.isSelected() != lecture.autoUpdate + || chkIsExam.isSelected() != lecture.isExam + || chkHasInternetAccess.isSelected() != lecture.hasInternetAccess + || chkHasUsbAccess.isSelected() != lecture.hasUsbAccess + || chkIsActive.isSelected() != lecture.isEnabled + || !lecture.defaultPermissions.equals(originalDefaultPermissions) + || (locationInfo != null && lecture.locationIds != null && !lecture.locationIds.equals(locationInfo.locationList)) + || (locationInfo != null && lecture.limitToLocations != locationInfo.limitToLocations) + || (currentAdvConf != null && lecture.networkExceptions != null && !lecture.networkExceptions.equals(currentAdvConf.netRulesList)) + || (currentAdvConf != null && lecture.runscript != null && !lecture.runscript.equals(currentAdvConf.runScriptText)) + || imageLinkChanged; + + return changed; + } + + /** + * Triggers the saving of the changes of this lecture + * And inform the callback function about the outcome */ private void saveChanges() { boolean saved = saveChangesInternal(); @@ -495,14 +628,30 @@ public class LectureDetailsWindow extends LectureDetailsWindowLayout implements btnSaveChanges.setEnabled(true); } + /** + * Internal helper actually saving the changes to the satellite + * + * @return true if saving succeeded, false otherwise. + */ private boolean saveChangesInternal() { // check, whether autoupdate is selected and choose version accordingly if (image != null) { lecture.imageVersionId = chkAutoUpdate.isSelected() ? image.latestVersionId : cboVersions.getItemAt(cboVersions.getSelectedIndex()).versionId; } + // goto to advanced tab and check (by getting) the state of the textAreas + pnlTabs.setSelectedIndex(pnlTabs.indexOfTab("Erweitert")); + currentAdvConf = ctlAdvancedConfigurator.getState(); + if (currentAdvConf == null) { + // getState() will return null only if it couldn't parse the rules + // which means that the user got informed about what was invalid + // So we just return here until the parsing works. + lblError.setText("Ungültiger Zeitraum!"); + return false; + } // now check if we need to push a new LectureWrite if (metadataChanged) { + LOGGER.info("Trying to save..."); // first build the LectureWrite from the GUI fields final LectureWrite metadata = new LectureWrite(txtTitle.getText(), txtDescription.getText(), lecture.getImageVersionId(), chkAutoUpdate.isSelected(), chkIsActive.isSelected(), @@ -588,100 +737,22 @@ public class LectureDetailsWindow extends LectureDetailsWindowLayout implements } /** - * Checks whether the user changed any fields of the image details and - * enables the save button if so. - */ - private void reactToChange() { - // check details fields - metadataChanged = reactToChangeInternal(); - permissionsChanged = MapHelper.hasChanged(originalCustomPermissions, customPermissions); - btnSaveChanges.setEnabled(metadataChanged || permissionsChanged); - } - - /** - * Checks whether the user changed any fields of the image details and - * enables the save button if so. - */ - private boolean reactToChangeInternal() { - if (lecture == null) - return false; - - boolean changed = false; - // mandatory fields checks - if (txtTitle.getText().isEmpty()) { - lblError.setText("Kein Veranstaltungsname gesetzt!"); - return false; - } - if (txtDescription.getText().isEmpty()) { - lblError.setText("Keine Beschreibung angegeben!"); - return false; - } - // version checkbox changed? - ImageVersionDetails currentVersion = cboVersions.getItemAt(cboVersions.getSelectedIndex()); - if (currentVersion == null) { - lblError.setText("Keine Version ausgewählt!"); - return false; - } - // Date stuff - Date start = DateTimeHelper.getDateFrom(dtpStartDate, spnStartTime); - Date end = DateTimeHelper.getDateFrom(dtpEndDate, spnEndTime); - if (!isPeriodValid(start, end, false) && dateHasChanged()) { - lblError.setText("Ungültiger Zeitraum!"); - return false; - } - - // done with mandatory checks, remove error message - lblError.setText(null); - - // check for changes in all fields - changed = !txtTitle.getText().equals(lecture.getLectureName()) - || !txtDescription.getText().equals(lecture.getDescription()) - || !currentVersion.getVersionId().equals(lecture.getImageVersionId()) - || (DateTimeHelper.getDateFrom(dtpStartDate, spnStartTime).getTime() / 1000L) != lecture.getStartTime() - || (DateTimeHelper.getDateFrom(dtpEndDate, spnEndTime).getTime() / 1000L) != lecture.getEndTime() - || chkAutoUpdate.isSelected() != lecture.autoUpdate - || chkIsExam.isSelected() != lecture.isExam - || chkHasInternetAccess.isSelected() != lecture.hasInternetAccess - || chkHasUsbAccess.isSelected() != lecture.hasUsbAccess - || chkIsActive.isSelected() != lecture.isEnabled - || !lecture.defaultPermissions.equals(originalDefaultPermissions) - || (locationInfo != null && lecture.locationIds != null && !lecture.locationIds.equals(locationInfo.locationList)) - || (locationInfo != null && lecture.limitToLocations != locationInfo.limitToLocations) - || (currentAdvConf != null && lecture.networkExceptions != null && !lecture.networkExceptions.equals(currentAdvConf.netRulesList)) - || (currentAdvConf != null && lecture.runscript != null && !lecture.runscript.equals(currentAdvConf.runScriptText)) - || imageLinkChanged; - - return changed; - } - - /** - * Enables/disables the editable fields based on 'editable' - * - * @param editable true to make fields editable, false otherwise. + * Enables/Disables the tabs based on the given flag 'editable'. + * + * @param editable when true, will enable the tabs if the user is allowed to see them. + * If false, this will disable all tabs but the first tab "About". */ - private void makeEditable(boolean editable) { - editable = editable && (LecturePerms.canEdit(lecture) || LecturePerms.canAdmin(lecture)); - txtTitle.setEditable(editable); - txtDescription.setEditable(editable); - btnLinkImage.setEnabled(editable); - if (MetaDataCache.getLocations() == null) - btnLocations.setEnabled(editable); - - //TODO Temporarily disabled until implemented - chkIsExam.setEnabled(false); - chkHasInternetAccess.setEnabled(false); -// chkIsExam.setEnabled(editable); -// chkHasInternetAccess.setEnabled(editable); - - chkIsActive.setEnabled(editable); - chkAutoUpdate.setEnabled(editable); - cboVersions.setEnabled(editable && !lecture.autoUpdate && image != null); - btnChangeOwner.setEnabled(editable && LecturePerms.canAdmin(lecture)); - btnPermissions.setEnabled(editable && LecturePerms.canAdmin(lecture)); - dtpStartDate.setEnabled(editable); - spnStartTime.setEnabled(editable); - dtpEndDate.setEnabled(editable); - spnEndTime.setEnabled(editable); + protected void toggleEditable(boolean editable) { + // if we don't have a lecture and an image set, just disable + editable &= (LecturePerms.canEdit(lecture)); + // "Übersicht" is always enabled + pnlTabs.setEnabledAt(pnlTabs.indexOfTab("Allgemein"), editable); + pnlTabs.setEnabledAt(pnlTabs.indexOfTab("Beschränkungen"), editable); + pnlTabs.setEnabledAt(pnlTabs.indexOfTab("Berechtigungen"), editable && LecturePerms.canAdmin(lecture)); + pnlTabs.setEnabledAt(pnlTabs.indexOfTab("Raumauswahl"), editable); + pnlTabs.setEnabledAt(pnlTabs.indexOfTab("Erweitert"), editable); + // special shit for those shitty special buttons.... + btnChangeOwner.setEnabled(LecturePerms.canAdmin(lecture)); btnDownloadImage.setEnabled(ImagePerms.canDownload(image)); } @@ -733,6 +804,10 @@ public class LectureDetailsWindow extends LectureDetailsWindowLayout implements && !Gui.showMessageBox(me, "Änderungen werden verworfen, wollen Sie wirklich schließen?", MessageType.QUESTION_YESNO, null, null)) return; + synchronized(me) { + lecture = null; + image = null; + } dispose(); } } |