diff options
author | Jonathan Bauer | 2015-07-17 16:14:30 +0200 |
---|---|---|
committer | Jonathan Bauer | 2015-07-17 16:14:30 +0200 |
commit | 091253db78dffb234c02ef1ed2e8f0fb3b9703a8 (patch) | |
tree | 0ec5f7a5ecd93500216b8bf49944a6cfdb72ba81 | |
parent | [client] improved ImageMetaDataPage setPageComplete logic (diff) | |
download | tutor-module-091253db78dffb234c02ef1ed2e8f0fb3b9703a8.tar.gz tutor-module-091253db78dffb234c02ef1ed2e8f0fb3b9703a8.tar.xz tutor-module-091253db78dffb234c02ef1ed2e8f0fb3b9703a8.zip |
[client] upload progress bar and cancel button
currently naive implementation, rework needed when the API is completed
4 files changed, 143 insertions, 32 deletions
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 55dd1193..e072b6b4 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 @@ -8,6 +8,7 @@ import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; +import org.openslx.dozmod.gui.control.BlockProgressBar; public abstract class ImageUploadPageLayout extends WizardPage { @@ -16,6 +17,8 @@ public abstract class ImageUploadPageLayout extends WizardPage { protected Button imageFileBrowseButton; protected Text imageFileTextField; protected Button startUploadButton; + protected BlockProgressBar blockProgressBar; + protected Button cancelUpload; /** * Page for uploading an imagefile @@ -59,6 +62,14 @@ public abstract class ImageUploadPageLayout extends WizardPage { startUploadButton = new Button(container, SWT.PUSH); startUploadButton.setText("Upload"); + blockProgressBar = new BlockProgressBar(container, null); + GridData gdBlockProgressBar = new GridData(SWT.FILL, SWT.END, false, false, 3, 1); + gdBlockProgressBar.heightHint = 25; + blockProgressBar.setLayoutData(gdBlockProgressBar); + + cancelUpload = new Button(container, SWT.PUSH); + cancelUpload.setText("Cancel"); + setControl(container); } } 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 d4e47078..02bbb2a4 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 @@ -61,7 +61,7 @@ public class ImageMetaDataPage extends ImageMetaDataPageLayout { osCombo.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { - setPageCompleteOrMessage(); + reactToUserInput(); } }); @@ -72,7 +72,7 @@ public class ImageMetaDataPage extends ImageMetaDataPageLayout { @Override public void keyReleased(KeyEvent e) { - setPageCompleteOrMessage(); + reactToUserInput(); } }); // -- checkboxes for permissions -- @@ -148,7 +148,7 @@ public class ImageMetaDataPage extends ImageMetaDataPageLayout { * Called by event listeners. This will set guidance message or error message * and call setPageComplete(bool) accordingly. */ - private void setPageCompleteOrMessage() { + private void reactToUserInput() { final int selectionIndex = osCombo.getSelectionIndex(); final String descriptionInput = descriptionText.getText(); @@ -165,13 +165,12 @@ public class ImageMetaDataPage extends ImageMetaDataPageLayout { } else { // OS selected, save it to state uploadWizardState.selectedOs = (OperatingSystem) osCombo.getData(osCombo.getItem(selectionIndex)); - LOGGER.debug(uploadWizardState.selectedOs.toString()); if (descriptionInput.isEmpty()) { // OS set, no description setMessage("Fügen Sie eine Beschreibung hinzu."); } else { // all set - setMessage("Alles fertig, clicken Sie 'Finish'."); + setMessage("Fertig! 'Next'/'Finish' Text bla."); } } // always save the description input, even if empty. 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 4920f90c..835af5cb 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 @@ -14,6 +14,7 @@ import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.FileDialog; +import org.openslx.bwlp.thrift.iface.TransferState; import org.openslx.dozmod.Config; import org.openslx.dozmod.filetransfer.UploadTask; import org.openslx.dozmod.gui.Gui; @@ -88,7 +89,7 @@ public class ImageUploadPage extends ImageUploadPageLayout { public void mouseDoubleClick(MouseEvent e) { } }); - + // Start upload startUploadButton.addSelectionListener(new SelectionListener() { @@ -102,6 +103,21 @@ public class ImageUploadPage extends ImageUploadPageLayout { } }); startUploadButton.setEnabled(false); + + // Cancel upload + cancelUpload.addSelectionListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + cancelUpload(); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + }); + cancelUpload.setVisible(false); + blockProgressBar.setVisible(false); imageFileBrowseButton.setFocus(); } @@ -159,7 +175,7 @@ public class ImageUploadPage extends ImageUploadPageLayout { setPageComplete(false); return; } - + // vmx ok, set it as our description file uploadWizardState.descriptionFile = file; @@ -193,6 +209,17 @@ public class ImageUploadPage extends ImageUploadPageLayout { super.setVisible(visible); } + /** + * This function starts the image creation process. It is triggered by the "Upload" button. + * + * Depending on the state, it will first try to get a UUID for the new image by calling + * createImage() of the thrift API. If a UUID is received, it will request an upload with + * requestImageVersionUpload(). If granted, it will finally start a thread for the UploadTask. + * + * Then a callback to the Gui is executed where we can process the upload state and give the + * user feedback about it. + * + */ private void createAndUploadImage() { // first get the image name from the field // (either auto filled by VmwareMetaData or by user) @@ -228,16 +255,12 @@ public class ImageUploadPage extends ImageUploadPageLayout { && uploadWizardState.uuid != null) { // do actually start the upload now LOGGER.debug("Starting upload for : " + uploadWizardState.diskFile.toPath()); - final Thread t = new Thread(new UploadTask( + uploadWizardState.uploadTaskThread = new Thread(new UploadTask( Session.getSatelliteAddress(), uploadWizardState.transferInformation.getPlainPort(), uploadWizardState.transferInformation.getToken(), uploadWizardState.diskFile)); - t.start(); - if (!t.isAlive()) { - // thread existed already, something is going wrong - LOGGER.error("Thread already died, upload seems to have failed?"); - } + uploadWizardState.uploadTaskThread.start(); } Gui.display.asyncExec(new Runnable() { @Override @@ -260,6 +283,8 @@ public class ImageUploadPage extends ImageUploadPageLayout { * know which step failed and handle the error accordingly. */ public void createAndUploadImageCallback() { + // if we get here, reset cancelled to false + uploadWizardState.cancelled = false; // always disable "Browse" and "Image Name" field imageNameTextField.setEnabled(false); imageFileBrowseButton.setEnabled(false); @@ -278,32 +303,104 @@ public class ImageUploadPage extends ImageUploadPageLayout { // request "granted" LOGGER.debug("Transfer request granted."); uploadWizardState.transferInformation = uploadWizardState.transferInformation; + blockProgressBar.setEnabled(true); + blockProgressBar.setVisible(true); + cancelUpload.setEnabled(true); + cancelUpload.setVisible(true); setMessage("Upload läuft! Sie können fortfahren."); } else { LOGGER.debug("No transfer information in upload state!"); setErrorMessage("Fehler bei der Upload-Anfrage!"); } - // TODO // -- periodically check upload status -- -// QuickTimer.scheduleAtFixedRate(new Task() { -// @Override -// public void fire() { -// try { -// uploadWizardState.transferStatus = -// ThriftManager.getSatClient() -// .queryUploadStatus(uploadWizardState.transferInformation.getToken()); -// } catch (Exception e) { -// LOGGER.error("Error while requesting upload status for: " + uploadWizardState.uuid, e); -// } -// Gui.display.asyncExec(new Runnable() { -// @Override -// public void run() { -// LOGGER.debug("Status: " + uploadWizardState.transferStatus.toString()); -// } -// }); -// } -// }, 0, 1000); + QuickTimer.scheduleAtFixedRate(new Task() { + final Task me = this; + @Override + public void fire() { + if (!uploadWizardState.uploadTaskThread.isAlive()) { + LOGGER.debug("Cancelling since upload thread is dead."); + cancel(); + return; + } + if (uploadWizardState.transferInformation == null) { + LOGGER.debug("Transfer information was reseted, aborting."); + cancel(); + return; + } + try { + uploadWizardState.transferStatus = ThriftManager.getSatClient() + .queryUploadStatus(uploadWizardState.transferInformation.getToken()); + } catch (Exception e) { + LOGGER.error("Error while requesting upload status for: " + uploadWizardState.uuid, e); + } + Gui.display.asyncExec(new Runnable() { + @Override + public void run() { + // should we stop? + if (uploadWizardState.cancelled + || uploadWizardState.transferStatus.state == TransferState.FINISHED +// || uploadWizardState.transferStatus.state == TransferState.CANCELLED + || uploadWizardState.transferStatus.state == TransferState.ERROR) { + me.cancel(); + } + // always callback to gui + processTransferStatus(); + } + }); + } + }, 0, 1000); setPageComplete(uploadWizardState.uuid != null && uploadWizardState.transferInformation != null); } + + /** + * Evaluates the transfer's state and show feedback to the user based on the state. + */ + private void processTransferStatus() { + if (getControl().isDisposed()) + return; + // always update progress bar + blockProgressBar.setStatus(uploadWizardState.transferStatus.getBlockStatus()); + switch (uploadWizardState.transferStatus.state) { + case FINISHED: + cancelUpload.setEnabled(false); + MainWindow.showMessageBox("Upload abgeschlossen.", MessageType.INFO, LOGGER, null); + break; + case ERROR: + if (MainWindow.showMessageBox("Fehler beim Upload. Nochmal versuchen?", MessageType.ERROR_RETRY, LOGGER, null)) { + // user wants to try again, just reset transferInformation ... + uploadWizardState.transferInformation = null; + // ... since this function will then do the upload process again. + createAndUploadImage(); + } + break; +// case CANCELLED: + case WORKING: + case IDLE: + // WORKING|IDLE = noops? + break; + default: + LOGGER.debug("Invalid transfer state: " + uploadWizardState.transferStatus.state); + break; + } + } + + private void cancelUpload() { + LOGGER.debug("Cancelling upload ..."); + // first tell the server about this + try { + ThriftManager.getSatClient().cancelUpload(uploadWizardState.transferInformation.getToken()); + } catch (Exception e) { + LOGGER.error("Error while canceling upload for: " + uploadWizardState.uuid, e); + MainWindow.showMessageBox("Konnte Upload nicht abbrechen!", MessageType.ERROR_RETRY, LOGGER, null); + } + // HACK stop our periodic timer + // TODO remove this once we have a CANCELLED state. + uploadWizardState.cancelled = true; + uploadWizardState.transferInformation = null; + // now try to stop our upload thread + uploadWizardState.uploadTaskThread.stop(); + cancelUpload.setEnabled(false); + blockProgressBar.setEnabled(false); + } } diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/state/UploadWizardState.java b/dozentenmodul/src/main/java/org/openslx/dozmod/state/UploadWizardState.java index e768414a..d37465f6 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/state/UploadWizardState.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/state/UploadWizardState.java @@ -40,4 +40,8 @@ public class UploadWizardState { public TransferInformation transferInformation = null; // transfer status for the current upload public TransferStatus transferStatus = null; + // thread for executing the upload task + public Thread uploadTaskThread = null; + // user cancelled flag + public boolean cancelled = false; } |