diff options
| author | Simon Rettberg | 2015-07-31 18:09:31 +0200 |
|---|---|---|
| committer | Simon Rettberg | 2015-07-31 18:09:31 +0200 |
| commit | d54ec5d58f657d5529c47bc5fafa38ca7f2283e3 (patch) | |
| tree | c60c3dce4efc091e749d08eca8b916320f2807dd /dozentenmodul/src/main/java/org | |
| parent | [client] Continued implementation of Wizard (diff) | |
| download | tutor-module-d54ec5d58f657d5529c47bc5fafa38ca7f2283e3.tar.gz tutor-module-d54ec5d58f657d5529c47bc5fafa38ca7f2283e3.tar.xz tutor-module-d54ec5d58f657d5529c47bc5fafa38ca7f2283e3.zip | |
[client] Mostly finished Wizard implementation
Diffstat (limited to 'dozentenmodul/src/main/java/org')
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: |
