Merge branch 'alert_on_close' into 'master'

Always ask for confirmation before ending running session

See merge request sheepitrenderfarm/client!114
This commit is contained in:
harlekin
2022-09-29 14:07:39 +00:00
2 changed files with 69 additions and 24 deletions

View File

@@ -83,6 +83,7 @@ import okhttp3.HttpUrl;
private boolean disableErrorSending; private boolean disableErrorSending;
private boolean running; private boolean running;
private boolean awaitingStop;
private boolean suspended; private boolean suspended;
private boolean shuttingdown; private boolean shuttingdown;
@@ -104,6 +105,7 @@ import okhttp3.HttpUrl;
this.disableErrorSending = false; this.disableErrorSending = false;
this.running = false; this.running = false;
this.awaitingStop = false;
this.suspended = false; this.suspended = false;
this.shuttingdown = false; this.shuttingdown = false;
@@ -574,11 +576,13 @@ import okhttp3.HttpUrl;
public void askForStop() { public void askForStop() {
this.log.debug("Client::askForStop"); this.log.debug("Client::askForStop");
this.running = false; this.running = false;
this.awaitingStop = true;
} }
public void cancelStop() { public void cancelStop() {
this.log.debug("Client::cancelStop"); this.log.debug("Client::cancelStop");
this.running = true; this.running = true;
this.awaitingStop = false;
} }
public int senderLoop() { public int senderLoop() {

View File

@@ -26,17 +26,21 @@ import java.awt.GridBagLayout;
import java.awt.GridLayout; import java.awt.GridLayout;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.awt.Image; import java.awt.Image;
import java.io.File; import java.io.File;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.util.Date; import java.util.Date;
import java.util.Objects;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import javax.swing.BorderFactory; import javax.swing.BorderFactory;
import javax.swing.BoxLayout; import javax.swing.BoxLayout;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import javax.swing.JPanel; import javax.swing.JPanel;
@@ -56,6 +60,8 @@ import com.sheepit.client.standalone.GuiSwing.ActivityType;
import com.sheepit.client.standalone.swing.components.CollapsibleJPanel; import com.sheepit.client.standalone.swing.components.CollapsibleJPanel;
public class Working implements Activity { public class Working implements Activity {
public static final String ACTION_CLOSE_WINDOW = "Invoked close action by pressing x";
private GuiSwing parent; private GuiSwing parent;
private CollapsibleJPanel session_info_panel; private CollapsibleJPanel session_info_panel;
@@ -109,6 +115,19 @@ public class Working implements Activity {
currentTheme = UIManager.getLookAndFeel().getName(); // Capture the theme on component instantiation currentTheme = UIManager.getLookAndFeel().getName(); // Capture the theme on component instantiation
previousStatus = ""; previousStatus = "";
log = Log.getInstance(parent_.getConfiguration()); log = Log.getInstance(parent_.getConfiguration());
//Overwrite the window close button behaviour to showa dialogue
parent.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
parent.addWindowListener(new WindowAdapter() {
@Override public void windowClosing(WindowEvent e) {
super.windowClosing(e);
if (parent == null || parent.getClient().isRunning() == false) {
System.exit(0);
}
var exitAction = new ExitAfterAction();
exitAction.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, ACTION_CLOSE_WINDOW));
}
});
} }
@Override public void show() { @Override public void show() {
@@ -252,7 +271,11 @@ public class Working implements Activity {
blockJob.addActionListener(new blockJobAction()); blockJob.addActionListener(new blockJobAction());
exitAfterFrame = new JButton("Exit"); exitAfterFrame = new JButton("Exit");
exitAfterFrame.addActionListener(new ExitAfterAction()); ExitAfterAction exitAfterAction = new ExitAfterAction();
exitAfterFrame.addActionListener(exitAfterAction);
if (client != null && client.isAwaitingStop()) {
exitAfterAction.finishJobBeforeExit(client, getJobsQueueSize(client));
}
buttonsPanel.add(settingsButton); buttonsPanel.add(settingsButton);
buttonsPanel.add(pauseButton); buttonsPanel.add(pauseButton);
@@ -487,6 +510,10 @@ public class Working implements Activity {
return layout.getConstraints(c); return layout.getConstraints(c);
} }
private int getJobsQueueSize(Client client) {
return client.getUploadQueueSize() + (client.isRunning() ? 1 : 0);
}
class PauseAction implements ActionListener { class PauseAction implements ActionListener {
@Override public void actionPerformed(ActionEvent e) { @Override public void actionPerformed(ActionEvent e) {
@@ -518,34 +545,48 @@ public class Working implements Activity {
@Override public void actionPerformed(ActionEvent e) { @Override public void actionPerformed(ActionEvent e) {
Client client = parent.getClient(); Client client = parent.getClient();
if (client != null) { if (client != null) {
if (client.isRunning()) { if (client.isRunning() == false && Objects.equals(e.getActionCommand(), ACTION_CLOSE_WINDOW) == false) {
String[] exitJobOptions = { "Exit after current Jobs", "Exit Immediately", "Do Nothing" }; cancelExit(client);
int jobsQueueSize = client.getUploadQueueSize() + (client.isRunning() ? 1 : 0); return;
}
int userDecision = JOptionPane.showOptionDialog(null, String.format( int jobsQueueSize = getJobsQueueSize(client);
int userDecision = showCloseDialog(jobsQueueSize);
if (userDecision == 0) {
finishJobBeforeExit(client, jobsQueueSize);
}
else if (userDecision == 1) {
exitImmediately(client);
}
}
}
public int showCloseDialog(int jobsQueueSize) {
String[] exitJobOptions = { "Exit after current Jobs", "Exit Immediately", "Do Nothing" };
return JOptionPane.showOptionDialog(null, String.format(
"<html>You have <strong>%d frame%s</strong> being uploaded or rendered. Do you want to finish the jobs or exit now?.\n\n", "<html>You have <strong>%d frame%s</strong> being uploaded or rendered. Do you want to finish the jobs or exit now?.\n\n",
jobsQueueSize, // Add the current frame to the total count ONLY if the client is running jobsQueueSize, // Add the current frame to the total count ONLY if the client is running
(jobsQueueSize > 1 ? "s" : ""), (jobsQueueSize > 1 ? (jobsQueueSize + " ") : ""), (jobsQueueSize > 1 ? "s" : "")), (jobsQueueSize > 1 ? "s" : ""), (jobsQueueSize > 1 ? (jobsQueueSize + " ") : ""), (jobsQueueSize > 1 ? "s" : "")),
"Exit Now or Later", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, exitJobOptions, "Exit Now or Later", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, exitJobOptions,
exitJobOptions[2]); // Make the "Do nothing" button the default one to avoid mistakes exitJobOptions[2]); // Make the "Do nothing" button the default one to avoid mistakes
}
if (userDecision == 0) { public void finishJobBeforeExit(Client client, int jobsQueueSize) {
exitAfterFrame.setText(String.format("Cancel exit (%s frame%s to go)", jobsQueueSize, (jobsQueueSize > 1 ? "s" : ""))); exitAfterFrame.setText(String.format("Cancel exit (%s frame%s to go)", jobsQueueSize, (jobsQueueSize > 1 ? "s" : "")));
client.askForStop(); client.askForStop();
} }
else if (userDecision == 1) {
public void exitImmediately(Client client) {
client.stop(); client.stop();
System.exit(0); System.exit(0);
} }
}
else { public void cancelExit(Client client) {
exitAfterFrame.setText("Exit"); exitAfterFrame.setText("Exit");
client.cancelStop(); client.cancelStop();
} }
} }
}
}
class blockJobAction implements ActionListener { class blockJobAction implements ActionListener {
@Override public void actionPerformed(ActionEvent e) { @Override public void actionPerformed(ActionEvent e) {