diff --git a/src/main/java/forge/gui/DialogMigrateProfile.java b/src/main/java/forge/gui/DialogMigrateProfile.java index 03da67315ae..58630fd8d5d 100644 --- a/src/main/java/forge/gui/DialogMigrateProfile.java +++ b/src/main/java/forge/gui/DialogMigrateProfile.java @@ -160,7 +160,7 @@ public class DialogMigrateProfile { @Override public void run() { btnCancel.requestFocusInWindow(); } }); - _AnalyzerUpdater analyzer = new _AnalyzerUpdater(srcDir, !emptySrcDir); + _AnalyzerUpdater analyzer = new _AnalyzerUpdater(srcDir); analyzer.execute(); } @@ -195,7 +195,7 @@ public class DialogMigrateProfile { // used to ensure we only have one UI update pending at a time private volatile boolean _uiUpdateAck; - public _AnalyzerUpdater(String srcDir, boolean forced) { + public _AnalyzerUpdater(String srcDir) { _srcDir = srcDir; _selectionPanel.removeAll(); @@ -208,12 +208,12 @@ public class DialogMigrateProfile { JPanel knownDeckPanel = new JPanel(new MigLayout("insets 0, gap 5, wrap 2")); knownDeckPanel.setOpaque(false); knownDeckPanel.add(new FLabel.Builder().text("Decks").build(), "wrap"); - _addSelectionWidget(knownDeckPanel, forced, OpType.CONSTRUCTED_DECK, "Constructed decks"); - _addSelectionWidget(knownDeckPanel, forced, OpType.DRAFT_DECK, "Draft decks"); - _addSelectionWidget(knownDeckPanel, forced, OpType.PLANAR_DECK, "Planar decks"); - _addSelectionWidget(knownDeckPanel, forced, OpType.SCHEME_DECK, "Scheme decks"); - _addSelectionWidget(knownDeckPanel, forced, OpType.SEALED_DECK, "Sealed decks"); - _addSelectionWidget(knownDeckPanel, forced, OpType.UNKNOWN_DECK, "Unknown decks"); + _addSelectionWidget(knownDeckPanel, OpType.CONSTRUCTED_DECK, "Constructed decks"); + _addSelectionWidget(knownDeckPanel, OpType.DRAFT_DECK, "Draft decks"); + _addSelectionWidget(knownDeckPanel, OpType.PLANAR_DECK, "Planar decks"); + _addSelectionWidget(knownDeckPanel, OpType.SCHEME_DECK, "Scheme decks"); + _addSelectionWidget(knownDeckPanel, OpType.SEALED_DECK, "Sealed decks"); + _addSelectionWidget(knownDeckPanel, OpType.UNKNOWN_DECK, "Unknown decks"); JPanel unknownDeckPanel = new JPanel(new MigLayout("insets 0, gap 5")); unknownDeckPanel.setOpaque(false); _unknownDeckCombo = new JComboBox(); @@ -231,20 +231,20 @@ public class DialogMigrateProfile { JPanel dataPanel = new JPanel(new MigLayout("insets 0, gap 5, wrap")); dataPanel.setOpaque(false); dataPanel.add(new FLabel.Builder().text("Other data").build()); - _addSelectionWidget(dataPanel, forced, OpType.GAUNTLET_DATA, "Gauntlet data"); - _addSelectionWidget(dataPanel, forced, OpType.QUEST_DATA, "Quest saves"); - _addSelectionWidget(dataPanel, forced, OpType.PREFERENCE_FILE, "Preference files"); + _addSelectionWidget(dataPanel, OpType.GAUNTLET_DATA, "Gauntlet data"); + _addSelectionWidget(dataPanel, OpType.QUEST_DATA, "Quest saves"); + _addSelectionWidget(dataPanel, OpType.PREFERENCE_FILE, "Preference files"); cbPanel.add(dataPanel, "aligny top"); // add cacheDir data elements JPanel cachePanel = new JPanel(new MigLayout("insets 0, gap 5, wrap 2")); cachePanel.setOpaque(false); cachePanel.add(new FLabel.Builder().text("Cached data").build(), "wrap"); - _addSelectionWidget(cachePanel, forced, OpType.DEFAULT_CARD_PIC, "Default card pics"); - _addSelectionWidget(cachePanel, forced, OpType.SET_CARD_PIC, "Set-specific card pics"); - _addSelectionWidget(cachePanel, forced, OpType.TOKEN_PIC, "Card token pics"); - _addSelectionWidget(cachePanel, forced, OpType.QUEST_PIC, "Quest-related pics"); - _addSelectionWidget(cachePanel, forced, OpType.DB_FILE, "Database files"); + _addSelectionWidget(cachePanel, OpType.DEFAULT_CARD_PIC, "Default card pics"); + _addSelectionWidget(cachePanel, OpType.SET_CARD_PIC, "Set-specific card pics"); + _addSelectionWidget(cachePanel, OpType.TOKEN_PIC, "Card token pics"); + _addSelectionWidget(cachePanel, OpType.QUEST_PIC, "Quest-related pics"); + _addSelectionWidget(cachePanel, OpType.DB_FILE, "Database files"); cbPanel.add(cachePanel, "aligny top"); _selectionPanel.add(cbPanel, "center"); @@ -285,11 +285,10 @@ public class DialogMigrateProfile { _updateUI(); } - private void _addSelectionWidget(JPanel parent, boolean forced, OpType type, String name) { + private void _addSelectionWidget(JPanel parent, OpType type, String name) { FCheckBox cb = new FCheckBox(); cb.setName(name); cb.setSelected(true); - cb.setEnabled(!forced); cb.addChangeListener(_stateChangedListener); // use a skip list map instead of a regular hashmap so that the files are sorted alphabetically diff --git a/src/main/java/forge/gui/MigrationSourceAnalyzer.java b/src/main/java/forge/gui/MigrationSourceAnalyzer.java index 4bac6496cb9..2f4c2986889 100644 --- a/src/main/java/forge/gui/MigrationSourceAnalyzer.java +++ b/src/main/java/forge/gui/MigrationSourceAnalyzer.java @@ -82,9 +82,7 @@ public class MigrationSourceAnalyzer { public int getNumFilesAnalyzed() { return _numFilesAnalyzed; } public void doAnalysis() { - // TODO: analyze source path tree and populate operation sets - // ensure we ignore data that is already in the destination directory - + // TODO: determine if this is really the res dir _analyzeResDir(_source); } @@ -93,27 +91,91 @@ public class MigrationSourceAnalyzer { // private void _analyzeResDir(File root) { - for (File file : root.listFiles()) { - if (_cb.checkCancel()) { return; } - - if ("pics".equals(file.getName())) { - _analyzeCardPicsDir(file); + _analyzeDir(root, new _Analyzer() { + @Override boolean onDir(File dir) { + String dirname = dir.getName(); + if ("decks".equals(dirname)) { + _analyzeDecksDir(dir); + } else if ("gauntlet".equals(dirname)) { + _analyzeGauntletDataDir(dir); + } else if ("layouts".equals(dirname)) { + _analyzeLayoutsDir(dir); + } else if ("pics".equals(dirname)) { + _analyzeCardPicsDir(dir); + } else if ("pics_product".equals(dirname)) { + _analyzeProductPicsDir(dir); + } else if ("preferences".equals(dirname)) { + _analyzePreferencesDir(dir); + } else if ("quest".equals(dirname)) { + _analyzeQuestDir(dir); + } else { + return false; + } + return true; } - - // ignore other files - if (file.isFile()) { - ++_numFilesAnalyzed; - } else if (file.isDirectory()) { - _numFilesAnalyzed += _countFiles(file); - } - } + }); } + ////////////////////////////////////////////////////////////////////////// + // decks + // + + private void _analyzeDecksDir(File root) { + System.out.println("analyzing decks directory: " + root); + _analyzeDir(root, new _Analyzer() { + @Override void onFile(File file) { + } + @Override boolean onDir(File dir) { + return false; + } + }); + } + + ////////////////////////////////////////////////////////////////////////// + // gauntlet + // + + private void _analyzeGauntletDataDir(File root) { + System.out.println("analyzing gauntlet data directory: " + root); + _analyzeDir(root, new _Analyzer() { + @Override void onFile(File file) { + // find *.dat files, but exclude LOCKED_* + String filename = file.getName(); + if (filename.endsWith(".dat") && !filename.startsWith("LOCKED_")) { + File targetFile = new File(NewConstants.GAUNTLET_DIR.userPrefLoc, file.getName()); + if (!file.equals(targetFile)) { + _cb.addOp(OpType.GAUNTLET_DATA, file, targetFile); + } + } + } + }); + } + + ////////////////////////////////////////////////////////////////////////// + // gauntlet + // + + private void _analyzeLayoutsDir(File root) { + System.out.println("analyzing layouts directory: " + root); + _analyzeDir(root, new _Analyzer() { + @Override void onFile(File file) { + // find *_preferred.xml files + String filename = file.getName(); + if (filename.endsWith("_preferred.xml")) { + File targetFile = new File(NewConstants.USER_PREFS_DIR, file.getName().replace("_preferred", "")); + if (!file.equals(targetFile)) { + _cb.addOp(OpType.PREFERENCE_FILE, file, targetFile); + } + } + } + }); + } + ////////////////////////////////////////////////////////////////////////// // default card pics // - private static String _oldCleanString(final String in) { + private static String _oldCleanString(String in) { final StringBuffer out = new StringBuffer(); char c; for (int i = 0; i < in.length(); i++) { @@ -170,34 +232,27 @@ public class MigrationSourceAnalyzer { } System.out.println("analyzing default card pics directory: " + root); - for (File file : root.listFiles()) { - if (_cb.checkCancel()) { return; } - - if (file.isFile()) { - ++_numFilesAnalyzed; - String fileName = file.getName(); - if (_defaultPicOldNameToCurrentName.containsKey(fileName)) { - fileName = _defaultPicOldNameToCurrentName.get(fileName); - } else if (!_defaultPicNames.contains(fileName)) { - System.out.println("skipping umappable default pic file: " + file); - _unmappableFiles.add(file); - continue; - } - - File targetFile = new File(NewConstants.CACHE_CARD_PICS_DIR, fileName); - if (!file.equals(targetFile)) { - _cb.addOp(OpType.DEFAULT_CARD_PIC, file, targetFile); - } - } else if (file.isDirectory()) { - if ("icons".equals(file.getName())) { - _analyzeIconsPicsDir(file); - } else if ("tokens".equals(file.getName())) { - _analyzeTokenPicsDir(file); - } else { - _analyzeCardPicsSetDir(file); + _analyzeListedDir(root, NewConstants.CACHE_CARD_PICS_DIR, new _ListedAnalyzer() { + @Override public String map(String filename) { + if (_defaultPicOldNameToCurrentName.containsKey(filename)) { + return _defaultPicOldNameToCurrentName.get(filename); } + return _defaultPicNames.contains(filename) ? filename : null; } - } + + @Override public OpType getOpType(String filename) { return OpType.DEFAULT_CARD_PIC; } + + @Override boolean onDir(File dir) { + if ("icons".equals(dir.getName())) { + _analyzeIconsPicsDir(dir); + } else if ("tokens".equals(dir.getName())) { + _analyzeTokenPicsDir(dir); + } else { + _analyzeCardPicsSetDir(dir); + } + return true; + } + }); } ////////////////////////////////////////////////////////////////////////// @@ -237,28 +292,16 @@ public class MigrationSourceAnalyzer { _numFilesAnalyzed += _countFiles(root); return; } - editionCode = edition.getCode2(); - Set validFilenames = _cardFileNamesBySet.get(editionCode); - for (File file : root.listFiles()) { - if ( _cb.checkCancel()) { return; } - - if (file.isFile()) { - ++_numFilesAnalyzed; - if (validFilenames.contains(editionCode + "/" + file.getName())) { - File targetFile = new File(NewConstants.CACHE_CARD_PICS_DIR, editionCode + "/" + file.getName()); - if (!file.equals(targetFile)) { - _cb.addOp(OpType.SET_CARD_PIC, file, targetFile); - } - } else { - System.out.println("skipping umappable set pic file: " + file); - _unmappableFiles.add(file); - } - } else if (file.isDirectory()) { - System.out.println("skipping umappable subdirectory: " + file); - _numFilesAnalyzed += _countFiles(file); + final String editionCode2 = edition.getCode2(); + final Set validFilenames = _cardFileNamesBySet.get(editionCode2); + _analyzeListedDir(root, NewConstants.CACHE_CARD_PICS_DIR, new _ListedAnalyzer() { + @Override public String map(String filename) { + filename = editionCode2 + "/" + filename; + return validFilenames.contains(filename) ? filename : null; } - } + @Override public OpType getOpType(String filename) { return OpType.SET_CARD_PIC; } + }); } ////////////////////////////////////////////////////////////////////////// @@ -278,26 +321,10 @@ public class MigrationSourceAnalyzer { } System.out.println("analyzing icon pics directory: " + root); - for (File file : root.listFiles()) { - if (_cb.checkCancel()) { return; } - - if (file.isFile()) { - ++_numFilesAnalyzed; - if (!_iconFileNames.contains(file.getName())) { - System.out.println("skipping umappable icon pic file: " + file); - _unmappableFiles.add(file); - continue; - } - - File targetFile = new File(NewConstants.CACHE_ICON_PICS_DIR, file.getName()); - if (!file.equals(targetFile)) { - _cb.addOp(OpType.QUEST_DATA, file, targetFile); - } - } else if (file.isDirectory()) { - System.out.println("skipping umappable subdirectory: " + file); - _numFilesAnalyzed += _countFiles(file); - } - } + _analyzeListedDir(root, NewConstants.CACHE_ICON_PICS_DIR, new _ListedAnalyzer() { + @Override public String map(String filename) { return _iconFileNames.contains(filename) ? filename : null; } + @Override public OpType getOpType(String filename) { return OpType.QUEST_PIC; } + }); } Set _tokenFileNames; @@ -315,33 +342,136 @@ public class MigrationSourceAnalyzer { } System.out.println("analyzing token pics directory: " + root); - for (File file : root.listFiles()) { - if (_cb.checkCancel()) { return; } - - if (file.isFile()) { - ++_numFilesAnalyzed; - boolean isQuestToken = _questTokenFileNames.contains(file.getName()); - if (!isQuestToken && !_tokenFileNames.contains(file.getName())) { - System.out.println("skipping umappable token pic file: " + file); - _unmappableFiles.add(file); - continue; - } - - File targetFile = new File(NewConstants.CACHE_TOKEN_PICS_DIR, file.getName()); - if (!file.equals(targetFile)) { - _cb.addOp(isQuestToken ? OpType.QUEST_PIC : OpType.TOKEN_PIC, file, targetFile); - } - } else if (file.isDirectory()) { - System.out.println("skipping umappable subdirectory: " + file); - _numFilesAnalyzed += _countFiles(file); + _analyzeListedDir(root, NewConstants.CACHE_TOKEN_PICS_DIR, new _ListedAnalyzer() { + @Override public String map(String filename) { + return (_questTokenFileNames.contains(filename) || _tokenFileNames.contains(filename)) ? filename : null; } - } + @Override public OpType getOpType(String filename) { + return _questTokenFileNames.contains(filename) ? OpType.QUEST_PIC : OpType.TOKEN_PIC; + } + }); + } + + private void _analyzeProductPicsDir(File root) { + System.out.println("analyzing product pics directory: " + root); + // we don't care about files in the root dir -- the new files are .png, not the current .jpg ones + _analyzeDir(root, new _Analyzer() { + @Override boolean onDir(File dir) { + if ("booster".equals(dir.getName())) { + } else if ("fatpacks".equals(dir.getName())) { + } else if ("precons".equals(dir.getName())) { + } else if ("tournamentpacks".equals(dir.getName())) { + } else { + return false; + } + return true; + } + }); + } + + ////////////////////////////////////////////////////////////////////////// + // preferences + // + + private void _analyzePreferencesDir(File root) { + System.out.println("analyzing preferences directory: " + root); + _analyzeDir(root, new _Analyzer() { + @Override void onFile(File file) { + String filename = file.getName(); + if ("editor.preferences".equals(filename) || "forge.preferences".equals(filename)) { + File targetFile = new File(NewConstants.USER_PREFS_DIR, file.getName()); + if (!file.equals(targetFile)) { + _cb.addOp(OpType.PREFERENCE_FILE, file, targetFile); + } + } + } + }); + } + + ////////////////////////////////////////////////////////////////////////// + // quest data + // + + private void _analyzeQuestDir(File root) { + System.out.println("analyzing quest directory: " + root); + _analyzeDir(root, new _Analyzer() { + @Override boolean onDir(File dir) { + if ("data".equals(dir.getName())) { + _analyzeQuestDataDir(dir); + return true; + } + return false; + } + }); + } + + private void _analyzeQuestDataDir(File root) { + System.out.println("analyzing quest data directory: " + root); + _analyzeDir(root, new _Analyzer() { + @Override void onFile(File file) { + if (file.getName().endsWith(".dat")) { + File targetFile = new File(NewConstants.QUEST_SAVE_DIR, file.getName()); + if (!file.equals(targetFile)) { + _cb.addOp(OpType.QUEST_DATA, file, targetFile); + } + } + } + }); } ////////////////////////////////////////////////////////////////////////// // utility functions // + private class _Analyzer { + void onFile(File file) { } + + // returns whether the directory has been handled + boolean onDir(File dir) { return false; } + } + + private void _analyzeDir(File root, _Analyzer analyzer) { + for (File file : root.listFiles()) { + if (_cb.checkCancel()) { return; } + + if (file.isFile()) { + ++_numFilesAnalyzed; + analyzer.onFile(file); + } else if (file.isDirectory()) { + if (!analyzer.onDir(file)) { + _numFilesAnalyzed += _countFiles(file); + } + } + } + } + + private abstract class _ListedAnalyzer { + abstract String map(String filename); + abstract OpType getOpType(String filename); + + // returns whether the directory has been handled + boolean onDir(File dir) { return false; } + } + + private void _analyzeListedDir(File root, final String targetDir, final _ListedAnalyzer listedAnalyzer) { + _analyzeDir(root, new _Analyzer() { + @Override void onFile(File file) { + String filename = listedAnalyzer.map(file.getName()); + if (null == filename) { + System.out.println("skipping umappable pic file: " + file); + _unmappableFiles.add(file); + } else { + File targetFile = new File(targetDir, filename); + if (!file.equals(targetFile)) { + _cb.addOp(listedAnalyzer.getOpType(filename), file, targetFile); + } + } + } + + @Override boolean onDir(File dir) { return listedAnalyzer.onDir(dir); } + }); + } + private int _countFiles(File root) { int count = 0; for (File file : root.listFiles()) { diff --git a/src/main/java/forge/properties/NewConstants.java b/src/main/java/forge/properties/NewConstants.java index fc639b87987..0d1c6b2475b 100644 --- a/src/main/java/forge/properties/NewConstants.java +++ b/src/main/java/forge/properties/NewConstants.java @@ -58,8 +58,8 @@ public final class NewConstants { } // data that is only in the profile dirs - private static final String _USER_QUEST_DIR = USER_DIR + "quest/"; - private static final String _USER_PREFS_DIR = USER_DIR + "preferences/"; + public static final String USER_QUEST_DIR = USER_DIR + "quest/"; + public static final String USER_PREFS_DIR = USER_DIR + "preferences/"; public static final String LOG_FILE = USER_DIR + "forge.log"; public static final String DECK_BASE_DIR = USER_DIR + "decks/"; public static final String DECK_CONSTRUCTED_DIR = DECK_BASE_DIR + "constructed/"; @@ -67,17 +67,17 @@ public final class NewConstants { public static final String DECK_SEALED_DIR = DECK_BASE_DIR + "sealed/"; public static final String DECK_SCHEME_DIR = DECK_BASE_DIR + "scheme/"; public static final String DECK_PLANE_DIR = DECK_BASE_DIR + "planar/"; - public static final String QUEST_SAVE_DIR = _USER_QUEST_DIR + "saves/"; - public static final String MAIN_PREFS_FILE = _USER_PREFS_DIR + "forge.preferences"; - public static final String QUEST_PREFS_FILE = _USER_PREFS_DIR + "quest.preferences"; + public static final String QUEST_SAVE_DIR = USER_QUEST_DIR + "saves/"; + public static final String MAIN_PREFS_FILE = USER_PREFS_DIR + "forge.preferences"; + public static final String QUEST_PREFS_FILE = USER_PREFS_DIR + "quest.preferences"; // data that has defaults in the program dir but overrides/additions in the user dir private static final String _DEFAULTS_DIR = _RES_ROOT + "defaults/"; - public static final FileLocation EDITOR_PREFERENCES_FILE = new FileLocation(_DEFAULTS_DIR, _USER_PREFS_DIR, "editor.preferences"); - public static final FileLocation HOME_LAYOUT_FILE = new FileLocation(_DEFAULTS_DIR, _USER_PREFS_DIR, "home.xml"); - public static final FileLocation MATCH_LAYOUT_FILE = new FileLocation(_DEFAULTS_DIR, _USER_PREFS_DIR, "match.xml"); - public static final FileLocation EDITOR_LAYOUT_FILE = new FileLocation(_DEFAULTS_DIR, _USER_PREFS_DIR, "editor.xml"); + public static final FileLocation EDITOR_PREFERENCES_FILE = new FileLocation(_DEFAULTS_DIR, USER_PREFS_DIR, "editor.preferences"); + public static final FileLocation HOME_LAYOUT_FILE = new FileLocation(_DEFAULTS_DIR, USER_PREFS_DIR, "home.xml"); + public static final FileLocation MATCH_LAYOUT_FILE = new FileLocation(_DEFAULTS_DIR, USER_PREFS_DIR, "match.xml"); + public static final FileLocation EDITOR_LAYOUT_FILE = new FileLocation(_DEFAULTS_DIR, USER_PREFS_DIR, "editor.xml"); public static final FileLocation GAUNTLET_DIR = new FileLocation(_DEFAULTS_DIR, USER_DIR, "gauntlet/"); // data that is only in the cached dir @@ -96,7 +96,7 @@ public final class NewConstants { USER_DIR, CACHE_DIR, CACHE_CARD_PICS_DIR, - _USER_PREFS_DIR, + USER_PREFS_DIR, _DB_DIR, DECK_CONSTRUCTED_DIR, DECK_DRAFT_DIR, diff --git a/src/main/java/forge/view/FView.java b/src/main/java/forge/view/FView.java index effc0308e73..56e3e0ff505 100644 --- a/src/main/java/forge/view/FView.java +++ b/src/main/java/forge/view/FView.java @@ -135,7 +135,7 @@ public enum FView { // check quickly whether we have any data to migrate boolean hasData = false; - for (String resDir : Lists.newArrayList("decks", "gauntlet", "pics", "pics_product", "preferences", "quest/data")) { + for (String resDir : Lists.newArrayList("decks", "gauntlet", "layouts", "pics", "pics_product", "preferences", "quest/data")) { File f = new File("res", resDir); if (f.exists() && !profileDirs.contains(f)) { System.out.println("profile data found in obsolete location: " + f.getAbsolutePath());