reset analyzer when a new directory is chosen

This commit is contained in:
myk
2013-03-12 19:23:53 +00:00
parent 21ba3a1558
commit d58d3ecfd6
4 changed files with 118 additions and 43 deletions

View File

@@ -30,6 +30,7 @@ import java.util.Map;
import java.util.concurrent.ConcurrentSkipListMap;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
@@ -40,6 +41,8 @@ import javax.swing.SwingWorker;
import javax.swing.Timer;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.DefaultCaret;
import net.miginfocom.swing.MigLayout;
@@ -47,6 +50,7 @@ import net.miginfocom.swing.MigLayout;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import forge.Command;
import forge.error.BugReporter;
import forge.gui.MigrationSourceAnalyzer.OpType;
import forge.gui.toolbox.FButton;
@@ -61,19 +65,23 @@ import forge.properties.NewConstants;
public class DialogMigrateProfile {
private final Runnable _onImportSuccessful;
private final FButton _btnStart;
private final FLabel _btnChooseDir;
private final JPanel _selectionPanel;
private volatile boolean _cancel;
public DialogMigrateProfile(String srcDir, boolean showMigrationBlurb, final Runnable onDialogClose) {
@SuppressWarnings("serial")
public DialogMigrateProfile(String forcedSrcDir, final Runnable onDialogClose) {
FPanel p = new FPanel(new MigLayout("insets dialog, gap 0, center, wrap"));
p.setOpaque(false);
p.setBackgroundTexture(FSkin.getIcon(FSkin.Backgrounds.BG_TEXTURE));
// header
p.add(new FLabel.Builder().text("Migrate profile data").fontSize(15).build(), "center");
boolean isMigration = !StringUtils.isEmpty(forcedSrcDir);
if (showMigrationBlurb) {
// header
p.add(new FLabel.Builder().text((isMigration ? "Migrate" : "Import") + " profile data").fontSize(15).build(), "center");
if (isMigration) {
FPanel blurbPanel = new FPanel(new MigLayout("insets dialog, gap 10, center, wrap"));
blurbPanel.setOpaque(false);
blurbPanel.add(new FLabel.Builder().text("<html><b>What's this?</b></html>").build(), "growx");
@@ -106,16 +114,77 @@ public class DialogMigrateProfile {
JPanel importSourcePanel = new JPanel(new MigLayout("insets 0, gap 10"));
importSourcePanel.setOpaque(false);
importSourcePanel.add(new FLabel.Builder().text("Import from:").build());
boolean emptySrcDir = StringUtils.isEmpty(srcDir);
FTextField txfSrc = new FTextField.Builder().readonly(!emptySrcDir).build();
final FTextField txfSrc = new FTextField.Builder().readonly().build();
importSourcePanel.add(txfSrc, "pushx, growx");
if (!emptySrcDir) {
File srcDirFile = new File(srcDir);
txfSrc.setText(srcDirFile.getAbsolutePath());
}
// TODO: listen for new directory choice and reset analysis
importSourcePanel.add(new FLabel.ButtonBuilder().text("Choose directory...").enabled(emptySrcDir).build(), "h pref+8!, w pref+12!");
p.add(importSourcePanel, "gaptop 20, growx");
_btnChooseDir = new FLabel.ButtonBuilder().text("Choose directory...").enabled(!isMigration).build();
final JFileChooser _fileChooser = new JFileChooser();
_fileChooser.setMultiSelectionEnabled(false);
_fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
_btnChooseDir.setCommand(new Command() {
@Override public void execute() {
if (JFileChooser.APPROVE_OPTION == _fileChooser.showOpenDialog(null)) {
txfSrc.setText(_fileChooser.getSelectedFile().getAbsolutePath());
}
}
});
importSourcePanel.add(_btnChooseDir, "h pref+8!, w pref+12!");
txfSrc.getDocument().addDocumentListener(new DocumentListener() {
boolean _analyzerActive; // access synchronized on _onAnalyzerDone
String prevText;
private final Runnable _onAnalyzerDone = new Runnable() {
public synchronized void run() {
_analyzerActive = false;
notify();
}
};
@Override public void removeUpdate(DocumentEvent e) { }
@Override public void changedUpdate(DocumentEvent e) { }
@Override public void insertUpdate(DocumentEvent e) {
final String text = txfSrc.getText();
if (text.equals(prevText)) {
return;
}
prevText = text;
// cancel any active analyzer
_cancel = true;
if (!text.isEmpty()) {
_btnChooseDir.setEnabled(false);
_btnStart.setEnabled(false);
SwingWorker<Void, Void> analyzerStarter = new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
// wait for active analyzer (if any) to quit
synchronized (_onAnalyzerDone) {
while (_analyzerActive) {
_onAnalyzerDone.wait();
}
}
return null;
}
// executes in gui event loop thread
@Override
protected void done() {
_cancel = false;
synchronized (_onAnalyzerDone) {
_AnalyzerUpdater analyzer = new _AnalyzerUpdater(text, _onAnalyzerDone);
analyzer.execute();
_analyzerActive = true;
}
_btnChooseDir.setEnabled(true);
}
};
analyzerStarter.execute();
}
}
});
p.add(importSourcePanel, "gaptop 20, pushx, growx");
// prepare import selection panel
_selectionPanel = new JPanel();
@@ -148,8 +217,8 @@ public class DialogMigrateProfile {
JPanel southPanel = new JPanel(new MigLayout("ax center"));
southPanel.setOpaque(false);
southPanel.add(_btnStart, "center, w 40%, h pref+12!");
southPanel.add(btnCancel, "center, w 40%, h pref+12!");
southPanel.add(_btnStart, "center, w pref+72!, h pref+12!");
southPanel.add(btnCancel, "center, w pref+72!, h pref+12!");
p.add(southPanel, "growx");
@@ -163,9 +232,9 @@ public class DialogMigrateProfile {
@Override public void run() { btnCancel.requestFocusInWindow(); }
});
if (!emptySrcDir) {
_AnalyzerUpdater analyzer = new _AnalyzerUpdater(srcDir);
analyzer.execute();
if (isMigration) {
File srcDirFile = new File(forcedSrcDir);
txfSrc.setText(srcDirFile.getAbsolutePath());
}
}
@@ -191,14 +260,16 @@ public class DialogMigrateProfile {
};
private final String _srcDir;
private final Runnable _onAnalyzerDone;
private final JComboBox _unknownDeckCombo;
private final FCheckBox _moveCheckbox;
private final FCheckBox _overwriteCheckbox;
private final JTextArea _operationLog;
private final JProgressBar _progressBar;
public _AnalyzerUpdater(String srcDir) {
_srcDir = srcDir;
public _AnalyzerUpdater(String srcDir, Runnable onAnalyzerDone) {
_srcDir = srcDir;
_onAnalyzerDone = onAnalyzerDone;
_selectionPanel.removeAll();
_selectionPanel.setLayout(new MigLayout("insets 0, gap 5, wrap"));
@@ -357,7 +428,7 @@ public class DialogMigrateProfile {
MigrationSourceAnalyzer.AnalysisCallback cb = new MigrationSourceAnalyzer.AnalysisCallback() {
@Override
public boolean checkCancel() { return _cancel; }
public boolean checkCancel() { try{Thread.sleep(1);}catch(InterruptedException e) {} return _cancel; }
@Override
public void addOp(OpType type, File src, File dest) {
@@ -418,26 +489,29 @@ public class DialogMigrateProfile {
// executes in gui event loop thread
@Override
protected void done() {
if (_cancel) { return; }
_progressBar.setValue(_progressBar.getMaximum());
_stateChangedListener.stateChanged(null);
_progressBar.setString("Analysis complete");
_btnStart.addActionListener(new ActionListener() {
@Override public void actionPerformed(ActionEvent arg0) {
_btnStart.removeActionListener(this);
_btnStart.setEnabled(false);
_disableAll();
_Importer importer = new _Importer(
_selections, _unknownDeckCombo, _operationLog, _progressBar,
_moveCheckbox.isSelected(), _overwriteCheckbox.isSelected());
importer.execute();
}
});
_btnStart.setEnabled(true);
if (!_cancel) {
_progressBar.setValue(_progressBar.getMaximum());
_stateChangedListener.stateChanged(null);
_progressBar.setString("Analysis complete");
_btnStart.addActionListener(new ActionListener() {
@Override public void actionPerformed(ActionEvent arg0) {
_btnStart.removeActionListener(this);
_btnStart.setEnabled(false);
_btnChooseDir.setEnabled(false);
_disableAll();
_Importer importer = new _Importer(
_selections, _unknownDeckCombo, _operationLog, _progressBar,
_moveCheckbox.isSelected(), _overwriteCheckbox.isSelected());
importer.execute();
}
});
_btnStart.setEnabled(true);
}
_onAnalyzerDone.run();
}
}

View File

@@ -34,7 +34,7 @@ public enum CSubmenuDownloaders implements ICDoc {
private final Command cmdHowToPlay = new Command() { @Override
public void execute() { VSubmenuDownloaders.SINGLETON_INSTANCE.showHowToPlay(); } };
private final Command cmdImportPictures = new Command() { @Override
public void execute() { new DialogMigrateProfile(null, false, null); } };
public void execute() { new DialogMigrateProfile(null, null); } };
private final Command cmdReportBug = new Command() { @Override
public void execute() { BugReporter.reportBug(null); }
};

View File

@@ -31,6 +31,7 @@ public class FTextField extends JTextField {
public Builder maxLength(int i0) { maxLength = i0; return this; }
public Builder readonly(boolean b0) { readonly = b0; return this; }
public Builder readonly() { return readonly(true); }
public Builder text(String s0) { text = s0; return this; }
public Builder tooltip(String s0) { toolTip = s0; return this; }

View File

@@ -163,7 +163,7 @@ public enum FView {
}
if (hasOldData) {
new DialogMigrateProfile("res", true, new Runnable() {
new DialogMigrateProfile("res", new Runnable() {
@Override public void run() {
// remove known cruft files, yes this is ugly, but it's also temporary
for (String cruftFile : Lists.newArrayList("decks/SkieraCube-cards_not_supported_yet.txt", "decks/cube/ArabianExtended.dck", "decks/cube/GtcGuildBoros.dck", "decks/cube/GtcGuildDimir.dck", "decks/cube/GtcGuildGruul.dck", "decks/cube/GtcGuildOrzhov.dck", "decks/cube/GtcGuildSimic.dck", "decks/cube/GtcPromoBoros.dck", "decks/cube/GtcPromoDimir.dck", "decks/cube/GtcPromoGruul.dck", "decks/cube/GtcPromoOrzhov.dck", "decks/cube/GtcPromoSimic.dck", "decks/cube/JuzamjediCube.dck", "decks/cube/RtRGuildAzorius.dck", "decks/cube/RtRGuildGolgari.dck", "decks/cube/RtRGuildIzzet.dck", "decks/cube/RtRGuildRakdos.dck", "decks/cube/RtRGuildSelesnya.dck", "decks/cube/RtRPromoAzorius.dck", "decks/cube/RtRPromoGolgari.dck", "decks/cube/RtRPromoIzzet.dck", "decks/cube/RtRPromoRakdos.dck", "decks/cube/RtRPromoSelesnya.dck", "decks/cube/SkieraCube.dck", "gauntlet/LOCKED_DotP Preconstructed.dat", "gauntlet/LOCKED_Swimming With Sharks.dat", "layouts/editor_default.xml", "layouts/home_default.xml", "layouts/match_default.xml", "pics/snow_covered_forest1.jpg", "pics/snow_covered_forest2.jpg", "pics/snow_covered_forest3.jpg", "pics/snow_covered_island1.jpg", "pics/snow_covered_island2.jpg", "pics/snow_covered_island3.jpg", "pics/snow_covered_mountain1.jpg", "pics/snow_covered_mountain2.jpg", "pics/snow_covered_mountain3.jpg", "pics/snow_covered_plains1.jpg", "pics/snow_covered_plains2.jpg", "pics/snow_covered_plains3.jpg", "pics/snow_covered_swamp1.jpg", "pics/snow_covered_swamp2.jpg", "pics/snow_covered_swamp3.jpg", "pics/VAN/Birds of Paradise Avatar.full.jpg", "pics/VAN/Erhnam Djinn Avatar.full.jpg", "pics/VAN/Goblin Warchief Avatar.full.jpg", "pics/VAN/Grinning Demon Avatar.full.jpg", "pics/VAN/Platinum Angel Avatar.full.jpg", "pics/VAN/Prodigal Sorcerer Avatar.full.jpg", "pics/VAN/Rith, the Awakener Avatar.full.jpg", "pics/VAN/Royal Assassin Avatar.full.jpg", "pics/VAN/Serra Angel Avatar.full.jpg", "pics/VAN/Tradewind Rider Avatar.full.jpg", "pics_product/10E.jpg", "pics_product/2ED.jpg", "pics_product/3ED.jpg", "pics_product/4ED.jpg", "pics_product/5DN.jpg", "pics_product/5ED.jpg", "pics_product/6ED.jpg", "pics_product/7ED.jpg", "pics_product/8ED.jpg", "pics_product/9ED.jpg", "pics_product/ALA.jpg", "pics_product/ALL.jpg", "pics_product/APC.jpg", "pics_product/ARB.jpg", "pics_product/ARN.jpg", "pics_product/ATQ.jpg", "pics_product/BOK.jpg", "pics_product/CFX.jpg", "pics_product/CHK.jpg", "pics_product/CHR.jpg", "pics_product/CSP.jpg", "pics_product/DIS.jpg", "pics_product/DKA.jpg", "pics_product/DRK.jpg", "pics_product/DST.jpg", "pics_product/EVE.jpg", "pics_product/EXO.jpg", "pics_product/FEM.jpg", "pics_product/FUT.jpg", "pics_product/GPT.jpg", "pics_product/HML.jpg", "pics_product/ICE.jpg", "pics_product/INV.jpg", "pics_product/ISD.jpg", "pics_product/JUD.jpg", "pics_product/LEA.jpg", "pics_product/LEB.jpg", "pics_product/LEG.jpg", "pics_product/LGN.jpg", "pics_product/LRW.jpg", "pics_product/M10.jpg", "pics_product/M11.jpg", "pics_product/M12.jpg", "pics_product/MBS.jpg", "pics_product/MIR.jpg", "pics_product/MMQ.jpg", "pics_product/MOR.jpg", "pics_product/MRD.jpg", "pics_product/NMS.jpg", "pics_product/NPH.jpg", "pics_product/ODY.jpg", "pics_product/ONS.jpg", "pics_product/PCY.jpg", "pics_product/PLC.jpg", "pics_product/PLS.jpg", "pics_product/PO2.jpg", "pics_product/POR.jpg", "pics_product/PTK.jpg", "pics_product/RAV.jpg", "pics_product/ROE.jpg", "pics_product/S99.jpg", "pics_product/SCG.jpg", "pics_product/SHM.jpg", "pics_product/SOK.jpg", "pics_product/SOM.jpg", "pics_product/STH.jpg", "pics_product/TMP.jpg", "pics_product/TOR.jpg", "pics_product/TSP.jpg", "pics_product/UDS.jpg", "pics_product/ULG.jpg", "pics_product/USG.jpg", "pics_product/VIS.jpg", "pics_product/WTH.jpg", "pics_product/WWK.jpg", "pics_product/ZEN.jpg", "pics_product/fatpacks/PLS.JPG", "preferences/.project", "preferences/editor.default.preferences", "preferences/main.properties", "quest/quest.preferences", "quest/quest.properties")) {