allow update of the current Mode

This commit is contained in:
Ben Fry
2022-03-12 20:35:32 -05:00
parent 07e48e68f3
commit 92550dbc94
4 changed files with 140 additions and 36 deletions
+11 -4
View File
@@ -1733,11 +1733,12 @@ public class Base {
/**
* Close a sketch as specified by its editor window.
* @param editor Editor object of the sketch to be closed.
* @param modeSwitch Whether this close is being done in the context of a
* mode switch.
* @param preventQuit For platforms that must have a window open,
* prevent a quit because a new window will be opened
* (i.e. when upgrading or changing the Mode)
* @return true if succeeded in closing, false if canceled.
*/
public boolean handleClose(Editor editor, boolean modeSwitch) {
public boolean handleClose(Editor editor, boolean preventQuit) {
if (!editor.checkModified()) {
return false;
}
@@ -1775,14 +1776,20 @@ public class Base {
}
}
/*
// wow, this is wrong (should only be called after the last window)
// but also outdated, because it's instance_server.* not server.*
// and Preferences.save() is also about restoring sketches.
Preferences.unset("server.port"); //$NON-NLS-1$
Preferences.unset("server.key"); //$NON-NLS-1$
// Save out the current prefs state
Preferences.save();
*/
if (defaultFileMenu == null) {
if (modeSwitch) {
if (preventQuit) {
// need to close this editor, ever so temporarily
editor.setVisible(false);
editor.dispose();
@@ -298,41 +298,70 @@ public abstract class LocalContribution extends Contribution {
/**
* Non-blocking call to remove a contribution in a new thread.
*/
void removeContribution(final Base base,
final ContribProgress pm,
final StatusPanel status) {
protected void removeContribution(Base base,
ContribProgress pm,
StatusPanel status,
boolean updating) {
// TODO: replace with SwingWorker [jv]
new Thread(() -> remove(base, pm, status, ContributionListing.getInstance()), "Contribution Uninstaller").start();
new Thread(() -> remove(base, pm, status, updating), "Contribution Uninstaller").start();
}
void remove(final Base base,
final ContribProgress pm,
final StatusPanel status,
final ContributionListing contribListing) {
private void remove(Base base, ContribProgress pm, StatusPanel status, boolean updating) {
pm.startTask("Removing");
boolean doBackup = Preferences.getBoolean("contribution.backup.on_remove");
if (getType() == ContributionType.MODE) {
boolean isModeActive = false;
//Set<Sketch> sketches = new HashSet<>();
List<Editor> editors = new ArrayList<>(); // might be nice to be in order
ModeContribution m = (ModeContribution) this;
for (Editor e : base.getEditors()) {
if (e.getMode().equals(m.getMode())) {
isModeActive = true;
break;
for (Editor editor : base.getEditors()) {
if (editor.getMode().equals(m.getMode())) {
Sketch sketch = editor.getSketch();
if (sketch.isModified()) {
pm.cancel();
editor.toFront();
Messages.showMessage("Save Sketch",
"Please first save “" + sketch.getName() + "”.");
return;
} else {
// Keep track of open Editor windows using this Mode
//sketchMainList.add(sketch.getMainPath());
//sketches.add(sketch);
editors.add(editor);
}
}
}
if (!isModeActive) {
m.clearClassLoader(base);
} else {
// Close any open Editor windows that were using this Mode,
// and if updating, build up a list of paths for the sketches
// so that we can dispose of the Editor objects.
//StringList sketchPathList = new StringList();
for (Editor editor : editors) {
//sketchPathList.append(editor.getSketch().getMainPath());
StatusPanelDetail.storeSketchPath(editor.getSketch().getMainPath());
base.handleClose(editor, true);
}
editors.clear();
m.clearClassLoader(base);
//StatusPanelDetail.storeSketches(sketchPathList);
/*
pm.cancel();
Messages.showMessage("Mode Manager",
"Please save your Sketch and change the Mode of all Editor\n" +
"windows that have " + name + " as the active Mode.");
return;
*/
if (!updating) {
// Notify the Base in case this is the current Mode
base.modeRemoved(m.getMode());
// If that was the last Editor window, and we deleted its Mode,
// open a fresh window using the default Mode.
if (base.getEditors().size() == 0) {
base.handleNew();
}
}
// Notify the Base in case this is the current Mode
base.modeRemoved(m.getMode());
}
if (getType() == ContributionType.TOOL) {
@@ -357,16 +386,18 @@ public abstract class LocalContribution extends Contribution {
try {
// TODO: run this in SwingWorker done() [jv]
EventQueue.invokeAndWait(() -> {
ContributionListing cl = ContributionListing.getInstance();
Contribution advertisedVersion =
contribListing.getAvailableContribution(LocalContribution.this);
cl.getAvailableContribution(LocalContribution.this);
if (advertisedVersion == null) {
contribListing.removeContribution(LocalContribution.this);
cl.removeContribution(LocalContribution.this);
} else {
contribListing.replaceContribution(LocalContribution.this, advertisedVersion);
cl.replaceContribution(LocalContribution.this, advertisedVersion);
}
base.refreshContribs(LocalContribution.this.getType());
base.setUpdatesAvailable(contribListing.countUpdates(base));
base.setUpdatesAvailable(cl.countUpdates(base));
});
} catch (InterruptedException e) {
e.printStackTrace();
@@ -386,10 +417,11 @@ public abstract class LocalContribution extends Contribution {
try {
// TODO: run this in SwingWorker done() [jv]
EventQueue.invokeAndWait(() -> {
contribListing.replaceContribution(LocalContribution.this,
ContributionListing cl = ContributionListing.getInstance();
cl.replaceContribution(LocalContribution.this,
LocalContribution.this);
base.refreshContribs(LocalContribution.this.getType());
base.setUpdatesAvailable(contribListing.countUpdates(base));
base.setUpdatesAvailable(cl.countUpdates(base));
});
} catch (InterruptedException e) {
e.printStackTrace();
@@ -436,7 +468,6 @@ public abstract class LocalContribution extends Contribution {
* @return String[] packageNames (without wildcards) or null if none are specified
*/
public StringList getImports() {
//return imports != null ? imports.toArray(new String[0]) : null;
return imports;
}
@@ -25,6 +25,8 @@ import java.awt.Component;
import java.awt.Dimension;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.AbstractQueue;
import java.util.concurrent.ConcurrentLinkedQueue;
import javax.swing.JProgressBar;
@@ -38,7 +40,6 @@ import processing.app.ui.Toolkit;
*/
class StatusPanelDetail {
private final ListPanel listPanel;
private final ContributionListing contribListing = ContributionListing.getInstance();
static private final int BUTTON_WIDTH = Toolkit.zoom(100);
@@ -148,6 +149,9 @@ class StatusPanelDetail {
ContribProgress installProgress = new ContribProgress(progressBar) {
public void finishedAction() {
finishInstall(isException());
// if it was a Mode, restore any sketches
restoreSketches();
}
public void cancelAction() {
@@ -171,7 +175,7 @@ class StatusPanelDetail {
installInProgress = true;
if (contrib instanceof AvailableContribution) {
installContribution((AvailableContribution) contrib);
contribListing.replaceContribution(contrib, contrib);
ContributionListing.getInstance().replaceContribution(contrib, contrib);
}
}
@@ -182,6 +186,10 @@ class StatusPanelDetail {
public void update() {
clearStatusMessage();
updateInProgress = true;
ContributionListing contribListing = ContributionListing.getInstance();
// TODO not really a 'restart' anymore, just requires care [fry 220312]
if (contrib.getType().requiresRestart()) {
// For the special "Updates" tab in the manager, there are no progress
// bars, so if that's what we're doing, this will create a dummy bar.
@@ -198,7 +206,12 @@ class StatusPanelDetail {
resetProgressBar();
AvailableContribution ad =
contribListing.getAvailableContribution(contrib);
// install the new version of the Mode (or Tool)
installContribution(ad, ad.link);
// if it was a Mode, restore any sketches
//if (contrib.getType() == ContributionType.MODE) {
//restoreSketches();
//}
}
@Override
@@ -213,7 +226,7 @@ class StatusPanelDetail {
}
}
};
getLocalContrib().removeContribution(getBase(), progress, getStatusPanel());
getLocalContrib().removeContribution(getBase(), progress, getStatusPanel(), true);
} else {
AvailableContribution ad =
@@ -243,7 +256,7 @@ class StatusPanelDetail {
removeInProgress = false;
}
};
getLocalContrib().removeContribution(getBase(), progress, getStatusPanel());
getLocalContrib().removeContribution(getBase(), progress, getStatusPanel(), false);
}
}
@@ -251,6 +264,53 @@ class StatusPanelDetail {
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
static AbstractQueue<String> restoreQueue = new ConcurrentLinkedQueue<>();
static protected void storeSketchPath(String path) {
restoreQueue.add(path);
}
protected void restoreSketches() {
while (!restoreQueue.isEmpty()) {
String path = restoreQueue.remove();
getBase().handleOpen(path);
}
}
/*
static final String SAVED_COUNT = "mode.update.sketch.count";
static protected void storeSketches(StringList sketchPathList) {
Preferences.setInteger(SAVED_COUNT, sketchPathList.size());
int index = 0;
for (String path : sketchPathList) {
Preferences.set("mode.update.sketch." + index, path);
index++;
}
}
protected void restoreSketches() {
if (Preferences.get(SAVED_COUNT) != null) {
int count = Preferences.getInteger(SAVED_COUNT);
for (int i = 0; i < count; i++) {
String key = "mode.update.sketch." + i;
String path = Preferences.get(key);
getBase().handleOpen(path); // re-open this sketch
Preferences.unset(key);
}
}
}
*/
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
// Can't be called from the constructor because the path isn't set all the
// way down. However, Base does not change over time. More importantly,
// though, is that the functions being called in Base are somewhat suspect
+9 -3
View File
@@ -49,10 +49,14 @@ X this was hiding the issue that was causing contribs to be added several time
X because the add() was inside the category loop of that code
X remove unused 'restart' flagging code, setRestartFlag() never used
X all that was left was maintenance of when that's been set, so...
X allow update of the current Mode
X if doing an update (not just delete), close sketches and re-open
X if doing a delete, require sketches to be closed
_ after failed update of Mode, the button is no longer available
_ have to click something else, then click back on the Mode line again
_ allow update of the current Mode
_ if doing an update (not just delete), close sketches and re-open
_ if doing a delete, require sketches to be closed
_ lots of rewriting to use SwingWorker
_ https://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html
_ when starting in p5jsMode, going to the contrib manager shows no green checks for libs
@@ -60,6 +64,8 @@ _ tricky because those aren't gonna show up in 'Add Library'
_ which is another case for a separate 'contrib manager' thing
_ maybe that's the update button? when no updates, it's still a button?
_ remove updateInProgress from StatusPanelDetail
_ CJKV fonts are hosed b/c they're not actually monospace
_ https://github.com/processing/processing4/issues/447