summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2015-07-31 18:09:31 +0200
committerSimon Rettberg2015-07-31 18:09:31 +0200
commitd54ec5d58f657d5529c47bc5fafa38ca7f2283e3 (patch)
treec60c3dce4efc091e749d08eca8b916320f2807dd
parent[client] Continued implementation of Wizard (diff)
downloadtutor-module-d54ec5d58f657d5529c47bc5fafa38ca7f2283e3.tar.gz
tutor-module-d54ec5d58f657d5529c47bc5fafa38ca7f2283e3.tar.xz
tutor-module-d54ec5d58f657d5529c47bc5fafa38ca7f2283e3.zip
[client] Mostly finished Wizard implementation
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/filetransfer/TransferTask.java15
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/Gui.java4
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/MainWindow.java13
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/table/ImagePermissionTable.java3
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/ImageWizard.java46
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/Wizard.java174
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/WizardPage.java34
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageCustomPermissionPageLayout.java6
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageMetaDataPageLayout.java12
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageUploadPageLayout.java15
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageCustomPermissionPage.java1
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageMetaDataPage.java3
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageUploadPage.java260
13 files changed, 377 insertions, 209 deletions
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/filetransfer/TransferTask.java b/dozentenmodul/src/main/java/org/openslx/dozmod/filetransfer/TransferTask.java
index 355d7393..c9471174 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/filetransfer/TransferTask.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/filetransfer/TransferTask.java
@@ -5,12 +5,15 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+import org.apache.log4j.Logger;
import org.openslx.bwlp.thrift.iface.TransferState;
import org.openslx.filetransfer.Transfer;
import org.openslx.util.Util;
public abstract class TransferTask implements Runnable {
+ private static final Logger LOGGER = Logger.getLogger(TransferTask.class);
+
protected static final double BYTES_PER_MIB = 1024 * 1024;
protected static final long CHUNK_SIZE = 16 * 1024 * 1024;
@@ -79,7 +82,7 @@ public abstract class TransferTask implements Runnable {
public boolean isRunning() {
return isRunning;
}
-
+
public boolean isCanceled() {
return isCancelled;
}
@@ -152,8 +155,10 @@ public abstract class TransferTask implements Runnable {
TransferThread thread = createNewThread();
if (thread != null) {
thread.setDaemon(true);
- thread.start();
connectingTransfers.add(thread);
+ thread.start();
+ LOGGER.debug("Made new transfer. Connecting: " + connectingTransfers.size()
+ + ", Active: " + transfers.size());
}
}
}
@@ -213,6 +218,12 @@ public abstract class TransferTask implements Runnable {
}
}
+ public int getTransferCount() {
+ synchronized (transfers) {
+ return transfers.size();
+ }
+ }
+
protected abstract static class TransferThread extends Thread {
@Override
public abstract void run();
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/Gui.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/Gui.java
index 6e9870d0..879d73db 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/Gui.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/Gui.java
@@ -212,10 +212,6 @@ public class Gui {
* @param task Task to run
*/
public static void asyncExec(final Runnable task) {
- if (SwingUtilities.isEventDispatchThread()) {
- task.run();
- return;
- }
SwingUtilities.invokeLater(task);
}
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/MainWindow.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/MainWindow.java
index f1a6755d..8987f673 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/MainWindow.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/MainWindow.java
@@ -2,7 +2,6 @@ package org.openslx.dozmod.gui;
import java.awt.BorderLayout;
import java.awt.Dimension;
-import java.awt.Frame;
import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;
import java.awt.Window;
@@ -46,6 +45,8 @@ public abstract class MainWindow {
private static CompositePage currentPage;
+ private static boolean isQuitQuestionOpen = false;
+
private static final Map<Class<? extends CompositePage>, CompositePage> pages = new ConcurrentHashMap<>();
private static final String THRIFT_CONNECTION_ERROR = "Lost connection to the masterserver. Do you want to retry?";
@@ -147,7 +148,10 @@ public abstract class MainWindow {
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyChar() == 17) { // Ctrl-Q = Quit
- askApplicationQuit();
+ if (!isQuitQuestionOpen) {
+ isQuitQuestionOpen = true;
+ askApplicationQuit();
+ }
event.consume();
}
return event.isConsumed();
@@ -169,9 +173,6 @@ public abstract class MainWindow {
mainWindow.getContentPane().add(mainContainer, BorderLayout.CENTER);
mainWindow.setVisible(true);
- Gui.centerShell(mainWindow);
- Gui.limitShellSize(mainWindow);
-
// here we can check for Session information
if (Session.getSatelliteToken() != null) {
// Wait for proxy server init
@@ -199,6 +200,7 @@ public abstract class MainWindow {
null, null)) {
Gui.exit(0);
}
+ isQuitQuestionOpen = false;
}
/**
@@ -256,6 +258,7 @@ public abstract class MainWindow {
}
});
}
+
// hack TODO what to giev to a popup when we aren't in this class?
public static JFrame getMainWin() {
return mainWindow;
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/table/ImagePermissionTable.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/table/ImagePermissionTable.java
index bc928436..a5fb2e3b 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/table/ImagePermissionTable.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/table/ImagePermissionTable.java
@@ -2,6 +2,7 @@ package org.openslx.dozmod.gui.control.table;
import org.openslx.dozmod.gui.helper.UserImagePermissions;
import org.openslx.dozmod.thrift.UserCache;
+import org.openslx.dozmod.util.FormatHelper;
@SuppressWarnings("serial")
public class ImagePermissionTable extends ListTable<UserImagePermissions> {
@@ -16,7 +17,7 @@ public class ImagePermissionTable extends ListTable<UserImagePermissions> {
protected Object getValueAtInternal(int rowIndex, int columnIndex) {
UserImagePermissions row = get(rowIndex);
if (columnIndex == 0)
- return UserCache.find(row.userId);
+ return FormatHelper.userName(UserCache.find(row.userId));
if (columnIndex == 1)
return row.permissions.link;
if (columnIndex == 2)
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/ImageWizard.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/ImageWizard.java
index 33cdea74..97efd804 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/ImageWizard.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/ImageWizard.java
@@ -46,26 +46,26 @@ public class ImageWizard extends Wizard {
}
@Override
- public boolean performFinish() {
- // TODO evaluate table state and create the map of permissions
- //
- // since we only started the download and created a "blank" image entry
+ public boolean wantFinish() {
+ // since we only started the upload and created a "blank" image entry
// we can here do all the sanity checks on the fields of UploadWizardState
// and react accordingly.
// check state
- if (!isStateValid()) {
- LOGGER.error("Invalid state!");
- return false;
- } else {
- // TODO run the actually request over external threaded class
- try {
- // push to sat
- ThriftManager.getSatClient().updateImageBase(Session.getSatelliteToken(),
- uploadWizardState.uuid.toString(), imageBaseWriteFromState());
- } catch (TException e) {
- LOGGER.error("Fail to push image metadata to satellite: ", e);
- return false;
- }
+ return isStateValid();
+ }
+
+ @Override
+ public void performFinish() {
+ // TODO evaluate table state and create the map of permissions
+ // TODO run the actually request over external threaded class
+ try {
+ // push to sat
+ ThriftManager.getSatClient().updateImageBase(Session.getSatelliteToken(),
+ uploadWizardState.uuid.toString(), imageBaseWriteFromState());
+ } catch (TException e) {
+ Gui.showMessageBox(this, "Fail to push image metadata to satellite: ", MessageType.ERROR, LOGGER,
+ e);
+ return;
}
// push permissions to satellite server
@@ -75,9 +75,9 @@ public class ImageWizard extends Wizard {
ThriftManager.getSatClient().writeImagePermissions(Session.getSatelliteToken(),
uploadWizardState.uuid, uploadWizardState.permissionList);
} catch (TException e) {
- // TODO Auto-generated catch block
- LOGGER.error("Could not write permissions list to satellite: ", e);
- return false;
+ Gui.showMessageBox(this, "Could not write permissions list to satellite: ",
+ MessageType.ERROR, LOGGER, e);
+ return;
}
}
try {
@@ -86,12 +86,12 @@ public class ImageWizard extends Wizard {
uploadWizardState.transferInformation.getToken(),
new ImageVersionWrite(uploadWizardState.isEnabled, uploadWizardState.isRestricted));
} catch (TException e) {
- LOGGER.error("Could not set active/restricted flags to satellite: ", e);
- return false;
+ Gui.showMessageBox(this, "Could not set active/restricted flags to satellite: ",
+ MessageType.ERROR, LOGGER, e);
+ return;
}
Gui.showMessageBox(this, "Creation of image worked :)", MessageType.INFO, LOGGER, null);
- return true;
}
private boolean isStateValid() {
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/Wizard.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/Wizard.java
index ac77dfb6..50be8c56 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/Wizard.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/Wizard.java
@@ -4,19 +4,28 @@ import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
+import java.awt.GridBagLayout;
import java.awt.Window;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.BorderFactory;
+import javax.swing.Box;
import javax.swing.BoxLayout;
+import javax.swing.JButton;
import javax.swing.JDialog;
+import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
+import javax.swing.JSeparator;
+import javax.swing.SwingConstants;
import org.openslx.dozmod.gui.MainWindow;
+import org.openslx.dozmod.gui.helper.GridPos;
@SuppressWarnings("serial")
public class Wizard extends JDialog {
@@ -25,9 +34,16 @@ public class Wizard extends JDialog {
private final JLabel messageLabel;
private final List<WizardPage> pages = new ArrayList<>();
private final JPanel contentPanel;
+ private int currentPage = -1;
+
+ private final JButton btnPrev;
+ private final JButton btnNext;
+ private final JButton btnCancel;
+ private final JButton btnFinish;
public Wizard(Window parent) {
super(parent, ModalityType.APPLICATION_MODAL);
+ setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
setLayout(new BorderLayout());
JPanel header = new JPanel();
header.setMinimumSize(new Dimension(0, 100));
@@ -41,10 +57,29 @@ public class Wizard extends JDialog {
titleLabel.setFont(titleLabel.getFont().deriveFont(Font.BOLD));
titleLabel.setForeground(Color.BLACK);
messageLabel.setForeground(Color.BLACK);
+ messageLabel.setHorizontalTextPosition(SwingConstants.RIGHT);
header.add(titleLabel);
header.add(messageLabel);
// Add header
- getContentPane().add(header, BorderLayout.PAGE_START);
+ JPanel headerWrapper = new JPanel();
+ headerWrapper.setLayout(new GridBagLayout());
+ headerWrapper.add(header, GridPos.get(0, 0, true, false));
+ headerWrapper.add(new JSeparator(), GridPos.get(0, 1, true, false));
+ getContentPane().add(headerWrapper, BorderLayout.PAGE_START);
+ // Buttons in footer
+ JPanel footer = new JPanel();
+ footer.add(Box.createHorizontalGlue());
+ btnPrev = new JButton("< Zurück");
+ btnNext = new JButton("Weiter >");
+ btnCancel = new JButton("Abbrechen");
+ btnFinish = new JButton("Fertigstellen");
+ footer.add(btnPrev);
+ footer.add(btnNext);
+ footer.add(Box.createRigidArea(new Dimension(10, 10)));
+ footer.add(btnCancel);
+ footer.add(Box.createRigidArea(new Dimension(5, 5)));
+ footer.add(btnFinish);
+ add(footer, BorderLayout.PAGE_END);
// Add content panel
contentPanel = new JPanel();
contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.PAGE_AXIS));
@@ -54,18 +89,97 @@ public class Wizard extends JDialog {
setPreferredSize(new Dimension(550, 420));
setResizable(false);
MainWindow.centerShell(this);
+ // Window events
addWindowListener(new WindowAdapter() {
@Override
public void windowOpened(WindowEvent e) {
+ e.getWindow().pack();
if (!pages.isEmpty()) {
- WizardPage page = pages.get(0);
- page.setVisible(true);
+ showPage(0);
+ }
+ }
+
+ @Override
+ public void windowClosing(WindowEvent we) {
+ if (onCancelRequest())
+ dispose();
+ }
+ });
+ // Äkschns
+ btnNext.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (currentPage + 1 < pages.size()) {
+ if (!pages.get(currentPage).wantNextOrFinish())
+ return; // Page canceled the operation
+ showPage(currentPage + 1);
+ }
+ }
+ });
+ btnPrev.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (currentPage > 0) {
+ showPage(currentPage - 1);
+ }
+ }
+ });
+ btnCancel.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (onCancelRequest())
+ dispose();
+ }
+ });
+ btnFinish.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (currentPage != -1) {
+ if (!pages.get(currentPage).wantNextOrFinish())
+ return;
+ }
+ if (wantFinish()) {
+ if (currentPage != -1) {
+ pages.get(currentPage).onPageLeave();
+ }
+ performFinish();
+ dispose();
}
- e.getWindow().pack();
}
});
}
+ private void showPage(int index) {
+ if (currentPage != -1) {
+ WizardPage old = pages.get(currentPage);
+ old.onPageLeave();
+ old.setVisible(false);
+ }
+ WizardPage page = pages.get(index);
+ page.onPageEnter();
+ page.setVisible(true);
+ currentPage = index;
+ updateHeader(page);
+ updateButtons(page);
+ validate();
+ }
+
+ void updateHeader(WizardPage page) {
+ if (currentPage == -1 || pages.get(currentPage) != page)
+ return;
+ String pageTitle = page.getTitle();
+ String pageDesc = page.getMessage();
+ if (pageTitle == null)
+ pageTitle = "Step " + currentPage;
+ if (pageDesc == null)
+ pageDesc = "";
+ titleLabel.setText(pageTitle);
+ messageLabel.setText(pageDesc);
+ messageLabel.setIcon(page.getMessageIcon());
+ messageLabel.validate();
+ setTitle(getWindowTitle() + " - " + pageTitle);
+ }
+
public String getWindowTitle() {
// TODO Auto-generated method stub
return null;
@@ -79,25 +193,55 @@ public class Wizard extends JDialog {
pages.add(page);
}
+ void updateButtons(WizardPage page) {
+ // State of finish button
+ boolean canFinish = true;
+ for (WizardPage p : pages) {
+ if (!p.isComplete()) {
+ canFinish = false;
+ break;
+ }
+ }
+ btnFinish.setEnabled(canFinish);
+ // State of next button
+ if (currentPage != -1 && pages.get(currentPage) == page) {
+ btnNext.setEnabled(currentPage + 1 < pages.size() && page.isComplete());
+ btnPrev.setEnabled(currentPage > 0 && pages.get(currentPage - 1).canComeBack);
+ }
+ }
+
+ /*
+ * Callback to wizard implementation
+ */
+
/**
- * Called when user clicks finish. Override to do final checks and take
- * appropriate actions.
+ * User clicked cancel or (X) - when returning false,
+ * wizard will stay open
*
- * @return <code>true</code> if finish is allowed/succeeded,
- * <code>false</code> otherwise
+ * @return
*/
- public boolean performFinish() {
+ protected boolean onCancelRequest() {
return true;
}
- void updateHeader() {
- // TODO Auto-generated method stub
-
+ /**
+ * Called when user clicks finish. Override to do final checks and take
+ * appropriate actions.
+ *
+ * @return <code>true</code> if finish is allowed, <code>false</code>
+ * otherwise
+ */
+ protected boolean wantFinish() {
+ return true;
}
- void updateButtons() {
- // TODO Auto-generated method stub
-
+ /**
+ * Called so the wizard can perform finishing steps. This is called after
+ * wantFinish() returned true and onPageLeave was called on the currently
+ * visible wizard step.
+ */
+ protected void performFinish() {
+ // void
}
}
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/WizardPage.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/WizardPage.java
index 52b6f85b..3468ee83 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/WizardPage.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/WizardPage.java
@@ -1,7 +1,12 @@
package org.openslx.dozmod.gui.wizard;
+import java.awt.Dialog;
+
+import javax.swing.Icon;
import javax.swing.JPanel;
+import javax.swing.UIManager;
+@SuppressWarnings("serial")
public abstract class WizardPage extends JPanel {
private final String title;
@@ -33,9 +38,23 @@ public abstract class WizardPage extends JPanel {
return this.title;
}
+ public String getMessage() {
+ if (this.message != null)
+ return this.message;
+ return this.description;
+ }
+
private void updateHeader() {
if (this.wizard != null)
- this.wizard.updateHeader();
+ this.wizard.updateHeader(this);
+ }
+
+ protected Dialog getDialog() {
+ return wizard;
+ }
+
+ public boolean isComplete() {
+ return this.isComplete;
}
/*
@@ -50,7 +69,7 @@ public abstract class WizardPage extends JPanel {
*
* @return true allows to flip the page, false cancels
*/
- protected boolean goNext() {
+ protected boolean wantNextOrFinish() {
return isComplete;
}
@@ -81,10 +100,11 @@ public abstract class WizardPage extends JPanel {
protected void setPageComplete(boolean b) {
isComplete = b;
if (wizard != null)
- wizard.updateButtons();
+ wizard.updateButtons(this);
}
protected void setDescription(String description) {
+ this.message = null;
this.description = description;
this.updateHeader();
}
@@ -101,4 +121,12 @@ public abstract class WizardPage extends JPanel {
this.updateHeader();
}
+ protected Icon getMessageIcon() {
+ if (message == null)
+ return null;
+ if (isError)
+ return (Icon) UIManager.get("OptionPane.errorIcon");
+ return (Icon) UIManager.get("OptionPane.warningIcon");
+ }
+
}
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageCustomPermissionPageLayout.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageCustomPermissionPageLayout.java
index ab69fa6e..d257b6f9 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageCustomPermissionPageLayout.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageCustomPermissionPageLayout.java
@@ -35,11 +35,11 @@ public class ImageCustomPermissionPageLayout extends WizardPage {
add(new JScrollPane(permissionTable), GridPos.get(0, 0, true, true));
// Buttons below Table
- addUser = new JButton();
+ addUser = new JButton(addUserLabel);
add(addUser, GridPos.get(0, 1));
- removeUser = new JButton();
- add(removeUser, GridPos.get(1, 1));
+ removeUser = new JButton(removeUserLabel);
+ add(removeUser, GridPos.get(0, 2));
}
}
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageMetaDataPageLayout.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageMetaDataPageLayout.java
index be113f2a..375dc401 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageMetaDataPageLayout.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageMetaDataPageLayout.java
@@ -1,14 +1,17 @@
package org.openslx.dozmod.gui.wizard.layout;
import java.awt.Component;
+import java.awt.Dimension;
import java.awt.GridBagLayout;
+import javax.swing.Box;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
+import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.border.TitledBorder;
@@ -61,8 +64,14 @@ public abstract class ImageMetaDataPageLayout extends WizardPage {
JLabel descriptionCation = new JLabel("Beschreibung");
descriptionText = new JTextArea(3, 50);
+ descriptionText.setMinimumSize(new Dimension(0, 60));
+ descriptionText.setLineWrap(true);
+ descriptionText.setWrapStyleWord(true);
+ JScrollPane descPane = new JScrollPane(descriptionText, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ descPane.setMinimumSize(descriptionText.getMinimumSize());
add(descriptionCation, GridPos.get(0, 1));
- add(descriptionText, GridPos.get(1, 1, true, false));
+ add(descPane, GridPos.get(1, 1, true, false));
setActiveCheck = new JCheckBox("Image aktivieren");
add(setActiveCheck, GridPos.get(0, 2));
@@ -85,6 +94,7 @@ public abstract class ImageMetaDataPageLayout extends WizardPage {
permissionsGroup.add(writePermissionsCheck);
permissionsGroup.add(adminPermissionsCheck);
add(permissionsGroup, GridPos.get(0, 4, 2, 1, true, false));
+ add(Box.createVerticalGlue(), GridPos.get(0, 5, true, true));
// -- end permissions group --
}
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageUploadPageLayout.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageUploadPageLayout.java
index aa30a8bc..6ae5ae5b 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageUploadPageLayout.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageUploadPageLayout.java
@@ -4,6 +4,7 @@ import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.event.KeyEvent;
+import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JTextField;
@@ -19,12 +20,12 @@ public abstract class ImageUploadPageLayout extends WizardPage {
protected JTextField imageNameTextField;
protected JButton imageFileBrowseButton;
protected JTextField imageFileTextField;
- protected JButton startUploadButton;
protected BlockProgressBar blockProgressBar;
/**
* Page for uploading an imagefile
- * @param wizard
+ *
+ * @param wizard
*
* @param editExistingImage wether to edit existing image file or create new
* one
@@ -47,14 +48,14 @@ public abstract class ImageUploadPageLayout extends WizardPage {
// -- Name --
JLabel imageNameCaption = new JLabel("Name des Images");
imageNameTextField = new JTextField();
- startUploadButton = new JButton("Upload starten");
- startUploadButton.setMnemonic(KeyEvent.VK_U);
add(imageNameCaption, GridPos.get(0, 1));
- add(imageNameTextField, GridPos.get(1, 1, true, false));
- add(startUploadButton, GridPos.get(2, 1));
+ add(imageNameTextField, GridPos.get(1, 1, 2, 1, true, false));
blockProgressBar = new BlockProgressBar(null);
blockProgressBar.setPreferredSize(new Dimension(200, 50));
- add(blockProgressBar, GridPos.get(0, 1, 3, 1));
+ blockProgressBar.setMinimumSize(blockProgressBar.getPreferredSize());
+ add(blockProgressBar, GridPos.get(0, 2, 3, 1, true, false));
+
+ add(Box.createVerticalGlue(), GridPos.get(0, 3, 3, 1, true, true));
}
}
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageCustomPermissionPage.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageCustomPermissionPage.java
index 98c8b5c5..ea8ae831 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageCustomPermissionPage.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageCustomPermissionPage.java
@@ -28,6 +28,7 @@ public class ImageCustomPermissionPage extends ImageCustomPermissionPageLayout {
*/
public ImageCustomPermissionPage(Wizard wizard, UploadWizardState uploadWizardState) {
super(wizard);
+ setPageComplete(true);
this.uploadWizardState = uploadWizardState;
permissionList = new ArrayList<UserImagePermissions>();
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageMetaDataPage.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageMetaDataPage.java
index a33fdb37..c61b2764 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageMetaDataPage.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageMetaDataPage.java
@@ -92,11 +92,12 @@ public class ImageMetaDataPage extends ImageMetaDataPageLayout {
}
@Override
- protected boolean goNext() {
+ protected boolean wantNextOrFinish() {
state.permissions = new ImagePermissions(linkPermissionsCheck.isSelected(),
readPermissionsCheck.isSelected(), writePermissionsCheck.isSelected(),
adminPermissionsCheck.isSelected());
state.selectedOs = (OperatingSystem)osCombo.getSelectedItem();
+ LOGGER.info("Selected OS is " + state.selectedOs);
return state.selectedOs != null && state.description != null;
}
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageUploadPage.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageUploadPage.java
index 33f15f40..cbe2f8fa 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageUploadPage.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageUploadPage.java
@@ -1,5 +1,6 @@
package org.openslx.dozmod.gui.wizard.page;
+import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
@@ -10,10 +11,10 @@ import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;
+import javax.swing.JComponent;
import javax.swing.JFileChooser;
-import javax.swing.SwingUtilities;
-import javax.swing.event.DocumentEvent;
-import javax.swing.event.DocumentListener;
+import javax.swing.LookAndFeel;
+import javax.swing.UIManager;
import javax.swing.filechooser.FileNameExtensionFilter;
import org.apache.log4j.Logger;
@@ -23,7 +24,6 @@ import org.openslx.dozmod.filetransfer.TransferEventListener;
import org.openslx.dozmod.filetransfer.UploadTask;
import org.openslx.dozmod.gui.Gui;
import org.openslx.dozmod.gui.helper.MessageType;
-import org.openslx.dozmod.gui.wizard.ImageWizard;
import org.openslx.dozmod.gui.wizard.Wizard;
import org.openslx.dozmod.gui.wizard.layout.ImageUploadPageLayout;
import org.openslx.dozmod.state.UploadWizardState;
@@ -32,9 +32,11 @@ import org.openslx.dozmod.thrift.Session;
import org.openslx.thrifthelper.ThriftManager;
import org.openslx.util.QuickTimer;
import org.openslx.util.QuickTimer.Task;
+import org.openslx.util.Util;
import org.openslx.util.vm.VmMetaData.HardDisk;
import org.openslx.util.vm.VmwareMetaData;
+@SuppressWarnings("serial")
public class ImageUploadPage extends ImageUploadPageLayout {
private final static Logger LOGGER = Logger.getLogger(ImageUploadPage.class);
@@ -48,28 +50,6 @@ public class ImageUploadPage extends ImageUploadPageLayout {
this.canComeBack = false;
this.state = uploadWizardState;
- imageNameTextField.getDocument().addDocumentListener(new DocumentListener() {
- @Override
- public void removeUpdate(DocumentEvent e) {
- changedUpdate(e);
- }
-
- @Override
- public void insertUpdate(DocumentEvent e) {
- changedUpdate(e);
- }
-
- @Override
- public void changedUpdate(DocumentEvent e) {
- if (!imageNameTextField.getText().isEmpty()) {
- setPageComplete(state.descriptionFile != null && state.uuid != null
- && state.transferInformation != null);
- } else {
- setPageComplete(false);
- }
- }
- });
-
// Browse for *.vmx
imageFileBrowseButton.addActionListener(new ActionListener() {
@Override
@@ -86,34 +66,55 @@ public class ImageUploadPage extends ImageUploadPageLayout {
}
});
- // Start upload
- startUploadButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- createAndUploadImage();
- }
- });
- startUploadButton.setEnabled(false);
-
blockProgressBar.setVisible(false);
imageFileBrowseButton.requestFocus();
}
private void browseForVm() {
- JFileChooser dialog = new JFileChooser(Config.getUploadPath());
- FileNameExtensionFilter filter = new FileNameExtensionFilter("Virtuelle Maschine", "vmx");
- dialog.setFileFilter(filter);
- dialog.setFileSelectionMode(JFileChooser.FILES_ONLY);
+ // Ugly hack to get a prettier file chooser with GTK - should be moved to helper/util class
+ LookAndFeel old = UIManager.getLookAndFeel();
+ if (!old.getName().toLowerCase().contains("gtk")) {
+ old = null;
+ } else {
+ try {
+ UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ JFileChooser fc = new JFileChooser(Config.getUploadPath());
+ if (old != null) {
+ fc.updateUI();
+ try {
+ UIManager.setLookAndFeel(old);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ refreshUI(fc, false);
+ }
+ FileNameExtensionFilter filter = new FileNameExtensionFilter("VMware Virtual Machine", "vmx");
+ fc.setFileFilter(filter);
+ fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
- int ret = dialog.showOpenDialog(SwingUtilities.windowForComponent(this));
- if (ret != JFileChooser.APPROVE_OPTION)
- return;
- File file = dialog.getSelectedFile();
- if (file == null)
+ int action = fc.showOpenDialog(getDialog());
+ File file = fc.getSelectedFile();
+ if (action != JFileChooser.APPROVE_OPTION || file == null)
return;
vmxSelected(file.getAbsoluteFile());
}
+ private static void refreshUI(JComponent c, boolean includeParent) {
+ if (includeParent)
+ c.updateUI();
+
+ for (int i = 0; i < c.getComponentCount(); i++) {
+ Component child = c.getComponent(i);
+ if (child instanceof JComponent) {
+ refreshUI((JComponent) child, true);
+ }
+ }
+ }
+
private void vmxSelected(File file) {
Config.setUploadPath(file.getParent());
try {
@@ -173,13 +174,12 @@ public class ImageUploadPage extends ImageUploadPageLayout {
// let the user know the upload is ready
setErrorMessage(null);
setDescription("Sie können jetzt den Upload starten!");
- startUploadButton.setEnabled(true);
- startUploadButton.requestFocus();
+ setPageComplete(true);
}
/**
* This function starts the image creation process. It is triggered by the
- * "Upload" button.
+ * "Next" button.
*
* Depending on the state, it will first try to get a UUID for the new image
* by calling
@@ -193,106 +193,81 @@ public class ImageUploadPage extends ImageUploadPageLayout {
* user feedback about it.
*
*/
- private void createAndUploadImage() {
+ @Override
+ protected boolean wantNextOrFinish() {
// first get the image name from the field
// (either auto filled by VmwareMetaData or by user)
state.name = imageNameTextField.getText();
+ // and to request the upload once we received that UUID.
- // schedule task to create the image if we have no UUID
- // and to request the upload once we received that UUID.
- QuickTimer.scheduleOnce(new Task() {
- @Override
- public void fire() {
- // -- create image --
- if (state.uuid == null) {
- LOGGER.debug("Creating image...");
- try {
- state.uuid = ThriftManager.getSatClient().createImage(Session.getSatelliteToken(),
- state.name);
- } catch (Exception e) {
- LOGGER.error("Error while creating image: ", e);
- }
- }
- if (state.transferInformation == null && state.uuid != null) {
- // -- request upload --
- LOGGER.debug("Requesting upload...");
- try {
- state.transferInformation = ThriftManager.getSatClient().requestImageVersionUpload(
- Session.getSatelliteToken(), state.uuid, state.diskFile.length(), null,
- state.meta.getFilteredDefinition());
- } catch (Exception e) {
- LOGGER.error("Error while requesting download for: " + state.uuid, e);
- }
- }
- if (state.uploadTask == null && state.transferInformation != null && state.uuid != null) {
- // do actually start the upload now
- LOGGER.debug("Starting upload for : " + state.diskFile.toPath());
- try {
- state.uploadTask = new UploadTask(Session.getSatelliteAddress(),
- state.transferInformation.getPlainPort(),
- state.transferInformation.getToken(), state.diskFile);
- } catch (FileNotFoundException e) {
- Gui.showMessageBox(getTopLevelAncestor(), "Cannot upload file: Not found",
- MessageType.ERROR, LOGGER, e);
- return;
- }
- // -- add listener for upload status/progress --
- state.uploadTask.addListener(new TransferEventListener() {
+ // -- create image --
+ if (state.uuid == null) {
+ LOGGER.debug("Creating image...");
+ try {
+ state.uuid = ThriftManager.getSatClient()
+ .createImage(Session.getSatelliteToken(), state.name);
+ } catch (Exception e) {
+ setErrorMessage("Konnte das Image nicht auf dem Satelliten erstellen");
+ LOGGER.error("Error while creating image: ", e);
+ return false;
+ }
+ imageNameTextField.setEnabled(false);
+ imageFileBrowseButton.setEnabled(false);
+ imageFileTextField.setEnabled(false);
+ }
+ // -- request upload --
+ if (state.transferInformation == null) {
+ LOGGER.debug("Requesting upload...");
+ try {
+ state.transferInformation = ThriftManager.getSatClient().requestImageVersionUpload(
+ Session.getSatelliteToken(), state.uuid, state.diskFile.length(), null,
+ state.meta.getFilteredDefinition());
+ } catch (Exception e) {
+ setErrorMessage("Fehler beim Aushandeln des Uploads");
+ LOGGER.error("Error while requesting download for: " + state.uuid, e);
+ return false;
+ }
+ }
+ if (state.uploadTask == null) {
+ // do actually start the upload now
+ LOGGER.debug("Starting upload for: " + state.diskFile.toPath());
+ try {
+ state.uploadTask = new UploadTask(Session.getSatelliteAddress(),
+ state.transferInformation.getPlainPort(), state.transferInformation.getToken(),
+ state.diskFile);
+ } catch (FileNotFoundException e) {
+ Gui.showMessageBox(getTopLevelAncestor(), "Cannot upload file: Not found\n\n"
+ + state.diskFile.getAbsolutePath(), MessageType.ERROR, LOGGER, e);
+ return false;
+ }
+ // -- add listener for upload status/progress --
+ state.uploadTask.addListener(new TransferEventListener() {
+ @Override
+ public void update(final TransferEvent event) {
+ final TransferEventListener listener = this;
+ Gui.asyncExec(new Runnable() {
@Override
- public void update(final TransferEvent event) {
- final TransferEventListener listener = this;
- Gui.asyncExec(new Runnable() {
- @Override
- public void run() {
- // always callback to gui
- processTransferStatus(listener, event);
- }
- });
+ public void run() {
+ // always callback to gui
+ processTransferStatus(listener, event);
}
});
- new Thread(state.uploadTask).start();
}
- Gui.asyncExec(new Runnable() {
- @Override
- public void run() {
- createAndUploadImageCallback();
- }
- });
- }
- });
- }
+ });
+ new Thread(state.uploadTask).start();
+ do {
+ Util.sleep(5);
+ } while (state.uploadTask.getConnectFailCount() == 0 && state.uploadTask.getTransferCount() == 0);
+ }
- /**
- * Callback for the QuickTimer executing the thrift calls (see
- * createAndUploadImage())
- *
- * createAndUploadImage() starts the image upload process by creating the
- * image,
- * requesting upload transfer, starting the upload task and finally query
- * the upload
- * status to check if the upload is actually running.
- *
- * Each step will update the UploadWizardState which we will evaluate here
- * to
- * know which step failed and handle the error accordingly.
- */
- public void createAndUploadImageCallback() {
- // always disable "Browse" and "Image Name" field
- imageNameTextField.setEnabled(false);
- imageFileBrowseButton.setEnabled(false);
- imageFileTextField.setEnabled(false);
- // -- check image creation --
- if (state.uuid == null) {
- LOGGER.debug("No UUID in upload state!");
- setErrorMessage("Konnte das Image nicht auf dem Satelliten erstellen!");
- } else if (state.transferInformation == null) {
- LOGGER.debug("No transfer information in upload state!");
- setErrorMessage("Fehler bei der Upload-Anfrage!");
- } else if (state.uploadTask != null) {
- blockProgressBar.setVisible(true);
- setDescription("Der Upload wurde gestartet");
+ if (state.uploadTask.getTransferCount() == 0) {
+ Gui.showMessageBox(this, "Error connecting to Satellite for upload!", MessageType.ERROR, LOGGER,
+ null);
+ return false;
}
- setPageComplete(state.uploadTask != null);
+ // -- check image creation --
+ blockProgressBar.setVisible(true);
+ return true;
}
/**
@@ -325,13 +300,10 @@ public class ImageUploadPage extends ImageUploadPageLayout {
case ERROR:
if (state.uploadTask != null && state.uploadTask.isCanceled())
return;
- if (Gui.showMessageBox(this, "Fehler beim Upload: " + event.errorMessage
- + "\nNochmal versuchen?", MessageType.ERROR_RETRY, LOGGER, null)) {
- // user wants to try again, just reset transferInformation ...
- state.uploadTask = null;
- // ... since this function will then do the upload process again.
- createAndUploadImage();
- }
+ Gui.showMessageBox(this, "Fehler beim Upload: " + event.errorMessage, MessageType.ERROR, LOGGER,
+ null);
+ // user wants to try again, just reset transferInformation ...
+ state.uploadTask = null;
break;
case WORKING:
case IDLE: