summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2019-02-26 18:13:28 +0100
committerSimon Rettberg2019-02-26 18:13:28 +0100
commit9aead2a6230d26837a319f77f14046c3902c7fcb (patch)
treebfa97375609930c43c97e4c769637665cd1456bb
parent[server] Implement fetching preset runscripts (diff)
downloadtutor-module-9aead2a6230d26837a319f77f14046c3902c7fcb.tar.gz
tutor-module-9aead2a6230d26837a319f77f14046c3902c7fcb.tar.xz
tutor-module-9aead2a6230d26837a319f77f14046c3902c7fcb.zip
[client] Add preset runscript selector to lecture details
-rwxr-xr-xdozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/StartupConfigurator.java203
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LectureDetailsWindow.java9
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/thrift/cache/MetaDataCache.java8
3 files changed, 195 insertions, 25 deletions
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/StartupConfigurator.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/StartupConfigurator.java
index f37a45ed..7013e437 100755
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/StartupConfigurator.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/StartupConfigurator.java
@@ -1,24 +1,50 @@
package org.openslx.dozmod.gui.configurator;
import java.awt.Color;
+import java.awt.Dialog.ModalityType;
+import java.awt.GridBagConstraints;
import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.atomic.AtomicReference;
import javax.swing.Box;
+import javax.swing.ButtonModel;
import javax.swing.DefaultComboBoxModel;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
-
+import javax.swing.SwingUtilities;
+import javax.swing.event.ChangeListener;
+
+import org.apache.log4j.Logger;
+import org.openslx.bwlp.thrift.iface.ImageDetailsRead;
+import org.openslx.bwlp.thrift.iface.LectureRead;
+import org.openslx.bwlp.thrift.iface.PresetRunScript;
+import org.openslx.dozmod.gui.Gui;
import org.openslx.dozmod.gui.changemonitor.DialogChangeMonitor;
import org.openslx.dozmod.gui.control.ComboBox;
import org.openslx.dozmod.gui.control.ComboBox.ComboBoxRenderer;
import org.openslx.dozmod.gui.control.QLabel;
import org.openslx.dozmod.gui.control.WordWrapLabel;
import org.openslx.dozmod.gui.helper.GridManager;
+import org.openslx.dozmod.gui.helper.MessageType;
+import org.openslx.dozmod.thrift.Session;
+import org.openslx.dozmod.thrift.cache.MetaDataCache;
+import org.openslx.thrifthelper.ThriftManager;
+import org.openslx.util.QuickTimer;
+import org.openslx.util.QuickTimer.Task;
import org.openslx.util.Util;
/**
@@ -26,13 +52,109 @@ import org.openslx.util.Util;
* Runscript and sound (un)muting
*/
public class StartupConfigurator extends StartupConfiguratorLayout {
-
+
private static final long serialVersionUID = -3497629601818983994L;
private StartupSettings startupSettings = new StartupSettings(null);
+ private ImageDetailsRead image;
+
+ private List<PresetRunScript> scripts;
+
+ private LectureRead lecture;
+
+ private ChangeListener mightyListener;
+
public StartupConfigurator() {
super();
+ QuickTimer.scheduleOnce(new Task() {
+ @Override
+ public void fire() {
+ scripts = MetaDataCache.getPredefinedRunScripts();
+ if (scripts.isEmpty()) {
+ Gui.asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ btnPredefinedScripts.setVisible(false);
+ }
+ });
+ }
+ }
+ });
+ btnPredefinedScripts.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ showRunscriptSelector();
+ }
+ });
+ }
+
+ private void showRunscriptSelector() {
+ if (scripts == null) {
+ Gui.showMessageBox("Wah wah wah! Null scripts", MessageType.ERROR, null, null);
+ return;
+ }
+ final JDialog dialog = new JDialog(SwingUtilities.getWindowAncestor(this),
+ "Startscripte auswählen", ModalityType.APPLICATION_MODAL);
+ JPanel pane = new JPanel();
+ dialog.setContentPane(pane);
+ dialog.setMinimumSize(Gui.getScaledDimension(200, 300));
+ GridManager grid = new GridManager(pane, 2, true, new Insets(2, 2, 2, 2));
+ final Map<ButtonModel, Integer> mapper = new HashMap<>();
+ boolean haveDisabled = false;
+ for (PresetRunScript ruleSet : scripts) {
+ JCheckBox button = new JCheckBox(ruleSet.displayname);
+ grid.add(button, 2);
+ grid.nextRow();
+ mapper.put(button.getModel(), ruleSet.scriptId);
+ if (image != null && ruleSet.osIds != null
+ && !ruleSet.osIds.contains(image.osId)) {
+ button.setEnabled(false);
+ haveDisabled = true;
+ }
+ if (lecture != null && lecture.presetScriptIds != null && lecture.presetScriptIds.contains(ruleSet.scriptId)) {
+ button.setSelected(true);
+ }
+ }
+ if (haveDisabled) {
+ grid.add(new WordWrapLabel("Ausgegraute Elemente sind mit dem zur"
+ + " Veranstaltung gehörendem Betriebssystem nicht kompatibel"), 2);
+ grid.nextRow();
+ }
+ JButton btnCancel = new JButton("Abbrechen");
+ JButton btnOk = new JButton("SPASCHAN");
+ grid.add(btnCancel).anchor(GridBagConstraints.LINE_START);
+ grid.add(btnOk).anchor(GridBagConstraints.LINE_END);
+ grid.finish(true);
+ btnCancel.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ dialog.dispose();
+ }
+ });
+ final AtomicReference<List<Integer>> selectedScripts = new AtomicReference<>();
+ btnOk.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ List<Integer> selected = new ArrayList<>();
+ for (Entry<ButtonModel, Integer> button : mapper.entrySet()) {
+ if (button.getKey().isSelected()) {
+ selected.add(button.getValue());
+ }
+ }
+ selectedScripts.set(selected);
+ dialog.dispose();
+ }
+ });
+ dialog.pack();
+ Gui.centerShellOverShell(SwingUtilities.getWindowAncestor(this), dialog);
+ dialog.setVisible(true);
+ // Call blocks as it's a modal window
+ if (selectedScripts.get() != null) {
+ // User clicked OK
+ startupSettings.selectedScripts = selectedScripts.get();
+ mightyListener.stateChanged(null);
+ }
}
private void setError(final String msg) {
@@ -45,7 +167,7 @@ public class StartupConfigurator extends StartupConfiguratorLayout {
* @return runscript as String. If no text was entered, returns a empty
* string.
*/
- public String getState() {
+ public StartupSettings getState() {
setError(""); // fill remove any prior errors, we'll reset them if needed
// handle user input, this is tricky since
// * either an item has been selected -> editorContent will be of our enum type
@@ -56,7 +178,7 @@ public class StartupConfigurator extends StartupConfiguratorLayout {
} else if (cboContent instanceof String) {
startupSettings.put(Field.EXTENSION, (String) cboContent);
}
- String taInputText = taRunScript.getText();
+ startupSettings.runScript = taRunScript.getText();
RunscriptVisibility visibility = (RunscriptVisibility) cboRunscriptVisibility.getSelectedItem();
startupSettings.put(Field.VISIBILITY, Integer.toString(visibility.value));
@@ -64,7 +186,7 @@ public class StartupConfigurator extends StartupConfiguratorLayout {
startupSettings.put(Field.MUTED, Integer.toString(sound.value));
setError("");
- return startupSettings.serialize() + "\n" + taInputText;
+ return startupSettings;
}
/**
@@ -72,17 +194,33 @@ public class StartupConfigurator extends StartupConfiguratorLayout {
* this sets the content of the text areas to the corresponding network
* rules/runscript as given by the AdvancedConfiguration object
*
- * @param config
+ * @param lecture
* AdvancedConfiguration to set the state to
*/
- public void setState(final String config) {
- if (config == null || config.isEmpty()) {
+ public void setState(final LectureRead lecture) {
+ if (lecture == null)
+ return;
+ this.lecture = lecture;
+ setCustomScript(lecture.runscript);
+ QuickTimer.scheduleOnce(new Task() {
+ @Override
+ public void fire() {
+ try {
+ image = ThriftManager.getSatClient().getImageDetails(Session.getSatelliteToken(), lecture.imageBaseId);
+ } catch (Exception e) {
+ }
+ }
+ });
+ }
+
+ private void setCustomScript(final String lecture) {
+ if (lecture == null || lecture.isEmpty()) {
cboRunscriptType.setSelectedItem(null);
taRunScript.setText("");
return;
}
String header = null;
- try (BufferedReader reader = new BufferedReader(new StringReader(config))) {
+ try (BufferedReader reader = new BufferedReader(new StringReader(lecture))) {
header = reader.readLine();
} catch (IOException e) {
// swallow ...
@@ -90,7 +228,7 @@ public class StartupConfigurator extends StartupConfiguratorLayout {
if (header != null) {
// we should have following format: ext=<interpreter/extension>;visibility=<flag>;...
// e.g. ext=sh;visibility=0
- startupSettings.deserialize(header);
+ startupSettings.deserializeItems(header);
String extension = startupSettings.get(Field.EXTENSION);
for (RunscriptType type : RunscriptType.values()) {
if (type.extension.equals(extension)) {
@@ -123,7 +261,7 @@ public class StartupConfigurator extends StartupConfiguratorLayout {
}
// finished with the interpreter, remove that line from the given config
// before setting that text
- taRunScript.setText(config.replaceFirst(".*?\n", ""));
+ taRunScript.setText(lecture.replaceFirst(".*?\n", ""));
}
public void addToChangeMonitor(DialogChangeMonitor changeMonitor) {
@@ -131,6 +269,7 @@ public class StartupConfigurator extends StartupConfiguratorLayout {
changeMonitor.addEditableCombo(cboRunscriptType, null);
changeMonitor.addFixedCombo(cboRunscriptVisibility, null);
changeMonitor.addFixedCombo(cboSoundState, null);
+ // TODO: Preset runscript
}
private static enum Field {
@@ -145,32 +284,35 @@ public class StartupConfigurator extends StartupConfiguratorLayout {
}
/**
- * Map holding the inline settings from line 1 of the script
+ * Object holding all the startup settings
*/
- private static class StartupSettings extends HashMap<String, String> {
- private static final long serialVersionUID = -5893345450266600626L;
+ public static class StartupSettings {
+
+ public Map<String, String> items = new HashMap<>();
+ public String runScript;
+ public List<Integer> selectedScripts;
public StartupSettings(String data) {
super();
- deserialize(data);
+ deserializeItems(data);
}
public String put(Field key, String value) {
value = value.replace(';', '_').replace('\r', '_').replace('\n', '_');
- return super.put(key.id, value);
+ return items.put(key.id, value);
}
public String get(Field key)
{
- String ret = super.get(key.id);
+ String ret = items.get(key.id);
if (ret == null)
return "";
return ret;
}
- public String serialize() {
+ public String serializeItems() {
StringBuilder sb = new StringBuilder();
- for (Entry<String, String> e : this.entrySet()) {
+ for (Entry<String, String> e : items.entrySet()) {
if (sb.length() != 0) {
sb.append(';');
}
@@ -181,18 +323,30 @@ public class StartupConfigurator extends StartupConfiguratorLayout {
return sb.toString();
}
- public void deserialize(String data) {
+ public void deserializeItems(String data) {
if (data == null)
return;
- clear();
+ items.clear();
String[] parts = data.split(";");
for (String s : parts) {
String[] entry = s.split("=");
if (entry.length == 2) {
- put(entry[0], entry[1]);
+ items.put(entry[0], entry[1]);
}
}
}
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof StartupSettings))
+ return false;
+ StartupSettings other = (StartupSettings) obj;
+ if (this.selectedScripts == other.selectedScripts)
+ return true;
+ if (this.selectedScripts == null)
+ return false;
+ return this.selectedScripts.equals(other.selectedScripts);
+ }
}
}
@@ -212,6 +366,7 @@ class StartupConfiguratorLayout extends JPanel {
protected final ComboBox<RunscriptType> cboRunscriptType;
protected final ComboBox<RunscriptVisibility> cboRunscriptVisibility;
protected final ComboBox<SoundState> cboSoundState;
+ protected final JButton btnPredefinedScripts;
public StartupConfiguratorLayout() {
GridManager grid = new GridManager(this, 2, true, new Insets(5, 5, 5, 5));
@@ -275,6 +430,10 @@ class StartupConfiguratorLayout extends JPanel {
grid.add(scpRunScript, 2).fill(true, true).expand(true, true);
grid.nextRow();
+ btnPredefinedScripts = new JButton("Vordefinierte Scripte...");
+ grid.add(btnPredefinedScripts, 2).anchor(GridBagConstraints.LINE_END);
+ grid.nextRow();
+
lblError = new QLabel("");
lblError.setForeground(Color.RED);
JPanel pnlError = new JPanel();
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 12e6fe55..8924ed97 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
@@ -39,6 +39,7 @@ import org.openslx.dozmod.gui.changemonitor.DialogChangeMonitor;
import org.openslx.dozmod.gui.changemonitor.DialogChangeMonitor.NotNullConstraint;
import org.openslx.dozmod.gui.changemonitor.DialogChangeMonitor.TextNotEmptyConstraint;
import org.openslx.dozmod.gui.changemonitor.DialogChangeMonitor.ValidationConstraint;
+import org.openslx.dozmod.gui.configurator.StartupConfigurator.StartupSettings;
import org.openslx.dozmod.gui.helper.DateTimeHelper;
import org.openslx.dozmod.gui.helper.MessageType;
import org.openslx.dozmod.gui.helper.UiFeedback;
@@ -343,7 +344,7 @@ public class LectureDetailsWindow extends LectureDetailsWindowLayout implements
ctlLocationSelector.setSelectedLocationsAsIds(lecture.locationIds);
// init advanced info
- ctlRunscriptConfigurator.setState(lecture.runscript);
+ ctlRunscriptConfigurator.setState(lecture);
ctlNetshareConfigurator.setState(lecture.networkShares, lecture.presetNetworkShares);
ctlLdapFilterConfigurator.setState(lecture.ldapFilters, lecture.presetLdapFilters);
ctlNetrulesConfigurator.setState(lecture.networkExceptions);
@@ -381,7 +382,7 @@ public class LectureDetailsWindow extends LectureDetailsWindowLayout implements
dtpEndDate.getModel().setDate(endCal.get(Calendar.YEAR), endCal.get(Calendar.MONTH),
endCal.get(Calendar.DATE));
spnEndTime.getModel().setValue(endCal.getTime());
-
+
// now enable the tabs the user can see given its permissions
toggleEditable(true);
// and always switch to the "About" tab
@@ -525,10 +526,11 @@ public class LectureDetailsWindow extends LectureDetailsWindowLayout implements
changeListenerPermissions.reset();
}
// first build the LectureWrite from the GUI fields
+ StartupSettings startupSettings = ctlRunscriptConfigurator.getState();
final LectureWrite metadata = new LectureWrite(txtTitle.getText(), txtDescription.getText(),
lecture.getImageVersionId(), chkAutoUpdate.isSelected(), chkIsActive.isSelected(),
startTime, endTime,
- ctlRunscriptConfigurator.getState(), null,
+ startupSettings.runScript, null,
chkIsExam.isSelected(),
chkHasInternetAccess.isSelected(),
lecture.getDefaultPermissions(), ctlLocationSelector.getSelectedLocationsAsIds(),
@@ -538,6 +540,7 @@ public class LectureDetailsWindow extends LectureDetailsWindowLayout implements
metadata.setNetworkExceptions(ctlNetrulesConfigurator.getState());
metadata.setNetworkShares(ctlNetshareConfigurator.getState());
metadata.setLdapFilters(ctlLdapFilterConfigurator.getState());
+ metadata.setPresetScriptIds(startupSettings.selectedScripts);
// now trigger the actual action
try {
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/thrift/cache/MetaDataCache.java b/dozentenmodul/src/main/java/org/openslx/dozmod/thrift/cache/MetaDataCache.java
index 6d75f792..8b6e4890 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/thrift/cache/MetaDataCache.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/thrift/cache/MetaDataCache.java
@@ -11,6 +11,7 @@ import org.openslx.bwlp.thrift.iface.Location;
import org.openslx.bwlp.thrift.iface.NetShare;
import org.openslx.bwlp.thrift.iface.OperatingSystem;
import org.openslx.bwlp.thrift.iface.PredefinedData;
+import org.openslx.bwlp.thrift.iface.PresetRunScript;
import org.openslx.bwlp.thrift.iface.Virtualizer;
import org.openslx.dozmod.thrift.Session;
import org.openslx.thrifthelper.ThriftManager;
@@ -217,6 +218,13 @@ public class MetaDataCache {
return new ArrayList<NetShare>(0);
return pd.netShares;
}
+
+ public static List<PresetRunScript> getPredefinedRunScripts() {
+ PredefinedData pd = predefinedData.get();
+ if (pd == null || pd.ldapFilter == null)
+ return new ArrayList<PresetRunScript>(0);
+ return pd.runScripts;
+ }