Skip to content

Commit

Permalink
Merge pull request #1352 from SJuliez/use-file-extensions-for-load-fr…
Browse files Browse the repository at this point in the history
…om-file

MML interface changes
  • Loading branch information
SJuliez authored Dec 31, 2023
2 parents c46eda7 + ab178ac commit a95494c
Show file tree
Hide file tree
Showing 43 changed files with 1,192 additions and 894 deletions.
4 changes: 3 additions & 1 deletion megameklab/resources/megameklab/resources/Dialogs.properties
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ ConfigurationDialog.techProgression.title=Tech Progression
ConfigurationDialog.printing.title=Record Sheets and Export
ConfigurationDialog.misc.title=General
ConfigurationDialog.chkTechProgression.text=Use Variable Tech Level
ConfigurationDialog.chkTechProgression.tooltip=Tech Level changes from Experimental to Advanced to Standard based on the year
ConfigurationDialog.chkTechProgression.tooltip=When this is checked, the tech level of equipment and therefore of the unit changes from Experimental to Advanced to Standard based on the year. If it is unchecked, all equipment and the unit keeps its tech level regardless of the year.
ConfigurationDialog.chkTechYear.text=Use game year
ConfigurationDialog.chkTechYear.tooltip=Use this year to determine the Tech Level if later than the introduction year.
ConfigurationDialog.chkTechShowFaction.text=Allow setting a unit's Faction
Expand Down Expand Up @@ -53,6 +53,8 @@ ConfigurationDialog.chkSummaryFormatTRO.text=Use TRO format for text export
ConfigurationDialog.chkSummaryFormatTRO.tooltip=When checked, text exports are formatted in technical readout style, otherwise as a traditional MegaMek unit summary.
ConfigurationDialog.chkSkipSavePrompts.text=Disable save prompts. Use at your own risk!
ConfigurationDialog.chkSkipSavePrompts.tooltip=When checked, no safety dialogs warning about losing changes when switching unit or unit type will be shown.
ConfigurationDialog.startup.text=MML Startup:
ConfigurationDialog.startup.tooltip=Depending on the startup type selected, MML will start in the main menu or, alternatively, directly load the most recent unit or start with a new unit instead of the main menu.

RecordSheetTask.printing=Printing
RecordSheetTask.exporting=Exporting
Expand Down
18 changes: 16 additions & 2 deletions megameklab/resources/megameklab/resources/Menu.properties
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ refreshMenu.text=Refresh
miRefreshUnitCache.text=Refresh Unit Cache
## Options Menu
optionsMenu.text=Options
miImport.text=Import MML Settings...
miConfiguration.text=Configuration...
## Themes Menu
themesMenu.text=Themes
Expand All @@ -72,6 +73,7 @@ unitCostBreakdownMenu.text=Unit Cost Breakdown
unitWeightBreakdownMenu.text=Unit Weight Breakdown
### Help Menu
helpMenu.text=Help
miResetWindow.text=Reset Window Positions
miAbout.text=About...
miRecordSheetImages.text=Record Sheet Images...

Expand All @@ -93,10 +95,22 @@ dialog.imagePath.title=Image Path
dialog.saveAs.title=Save As
dialog.saveAs.message.format=%s %s saved to %s
dialog.filter.unitFiles=Unit Files (*.mtf; *.blk; *.hmp)
dialog.importSettings=Import Settings From...

message.invalidUnit.format=Warning: Invalid unit, it might load incorrectly!\n%1$s
message.invalidUnit.text=Warning: Invalid unit, it might load incorrectly!
message.savingInvalidUnit.text=Warning: Saving an invalid unit, it might load incorrectly!
message.exportingInvalidUnit.text=Warning: Exporting an invalid unit!
message.abortUnitLoad.text=Warning: Could not create new UI, aborting unit load!\
Probable cause: Unsupported unit type.

# The following values are used programatically by MMLStartUp
MMLStartUp.SPLASH_SCREEN=MML Main UI
MMLStartUp.RECENT_UNIT=Last Unit
MMLStartUp.NEW_MEK=New Mek
MMLStartUp.NEW_TANK=New Combat Vehicle
MMLStartUp.NEW_BATTLEARMOR=New BattleArmor
MMLStartUp.NEW_CONVINFANTRY=New Conventional Infantry
MMLStartUp.NEW_FIGHTER=New Fighter
MMLStartUp.NEW_DROPSHIP=New SmallCraft/DropShip
MMLStartUp.NEW_JUMPSHIP=New Advanced Aerospace
MMLStartUp.NEW_SUPPORTVEE=New Support Vehicle
MMLStartUp.NEW_PROTOMEK=New ProtoMek
14 changes: 14 additions & 0 deletions megameklab/resources/megameklab/resources/PopupMessages.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
mostRecentNotFound=The most recent unit file could not be opened. Starting in MML's main UI instead.
noMostRecentUnit=There is no most recent unit. Starting in MML's main UI instead.
fileReadError=A problem occurred while trying to read the file %s. This can happen for various reasons. The file may not exist, MML may lack the rights to read the file or the file may be malformed or not conform to its file extension. The error message is:\n\n%s
invalidUnit=The unit is invalid for the reasons listed below and may load incorrectly!\n\n%s
validUnit=Validation Passed.
fileWriteError=A problem occurred while trying to write the file. The error message is:\n\n%s
unitSaved=%s %s saved to %s
lookAndFeelError=A problem occurred while trying to change the Java Look-and-Feel. The error message is:\n\n%s
uncaughtException=Uncaught %s detected. Please open up an issue containing all logs and the current unit file at https://github.com/MegaMek/megameklab/issues
loadUiError=A problem occurred while trying to create the unit UI, reverting to a new Mek!
locationFull=Could not add %s because the chosen location is full!
invalidLocation=%s can't be placed in %s!
importSettingsHelp=To import settings, find the main megameklab directory of a previous setup of MML and select this directory (e.g. D:/BT_Stuff/megameklab04915). This directory should contain among others a directory called mmconf (D:/BT_Stuff/megameklab04915/mmconf) which in turn contains the file megameklab.properties.
settingsImported=The settings have been imported.\n\nPlease note that due to the way MegaMekLab uses some of MegaMek's settings not all settings can currently be imported. The settings that are not imported are, e.g., the user directory and display settings for the unit preview.\n\nIt is strongly advised to close and restart MML. Some settings will only take effect after restarting MML.
5 changes: 1 addition & 4 deletions megameklab/resources/megameklab/resources/Splash.properties
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,4 @@ btnNewAero.text=New Aero Fighter
btnNewDropper.text=New Dropship/Small Craft
btnNewLargeCraft.text=New Capital-Scale Craft
btnQuit.text=Quit
version.text=MegaMekLab Version
message.invalidUnit.format=Warning: Invalid unit, it might load incorrectly!\n%1$s
message.abortUnitLoad.text=Warning: Could not create new UI, aborting unit load!\
Probable cause: Unsupported unit type.
version.text=MegaMekLab Version
97 changes: 83 additions & 14 deletions megameklab/src/megameklab/MegaMekLab.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,16 @@

import megamek.MegaMek;
import megamek.client.ui.preferences.SuitePreferences;
import megamek.common.EquipmentType;
import megamek.common.MechSummaryCache;
import megamek.common.*;
import megameklab.ui.PopupMessages;
import megameklab.ui.StartupGUI;
import megameklab.ui.dialog.UiLoader;
import megameklab.util.CConfig;
import megameklab.util.UnitUtil;
import org.apache.logging.log4j.LogManager;

import javax.swing.*;
import java.io.File;
import java.util.Locale;

public class MegaMekLab {
Expand All @@ -36,20 +38,14 @@ public static void main(String... args) {
// First, create a global default exception handler
Thread.setDefaultUncaughtExceptionHandler((thread, t) -> {
LogManager.getLogger().error("Uncaught Exception Detected", t);
final String name = t.getClass().getName();
JOptionPane.showMessageDialog(null,
String.format("Uncaught %s detected. Please open up an issue containing all logs and the current unit file at https://github.com/MegaMek/megameklab/issues", name),
"Uncaught " + name, JOptionPane.ERROR_MESSAGE);
PopupMessages.showUncaughtException(null, t);
});

// Second, let's handle logging
MegaMek.initializeLogging(MMLConstants.PROJECT_NAME);
MegaMekLab.initializeLogging(MMLConstants.PROJECT_NAME);

// Third, let's handle suite graphical setup initialization
MegaMek.initializeSuiteGraphicalSetups(MMLConstants.PROJECT_NAME);

// Finally, let's handle startup
ToolTipManager.sharedInstance().setDismissDelay(1000000);
ToolTipManager.sharedInstance().setReshowDelay(50);
startup();
}

Expand Down Expand Up @@ -80,13 +76,49 @@ private static void startup() {
setLookAndFeel();

// Create a startup frame and display it
StartupGUI sud = new StartupGUI();
sud.setVisible(true);
switch (CConfig.getStartUpType()) {
case NEW_MEK:
UiLoader.loadUi(Entity.ETYPE_MECH, false, false);
break;
case NEW_TANK:
UiLoader.loadUi(Entity.ETYPE_TANK, false, false);
break;
case NEW_FIGHTER:
UiLoader.loadUi(Entity.ETYPE_AERO, false, false);
break;
case NEW_DROPSHIP:
UiLoader.loadUi(Entity.ETYPE_DROPSHIP, false, false);
break;
case NEW_PROTOMEK:
UiLoader.loadUi(Entity.ETYPE_PROTOMECH, false, false);
break;
case NEW_JUMPSHIP:
UiLoader.loadUi(Entity.ETYPE_JUMPSHIP, false, false);
break;
case NEW_SUPPORTVEE:
UiLoader.loadUi(Entity.ETYPE_SUPPORT_TANK, false, false);
break;
case NEW_BATTLEARMOR:
UiLoader.loadUi(Entity.ETYPE_BATTLEARMOR, false, false);
break;
case NEW_CONVINFANTRY:
UiLoader.loadUi(Entity.ETYPE_INFANTRY, false, false);
break;
case RECENT_UNIT:
if (loadMostRecentUnit()) {
return;
}
// intentional fall through when loading the most recent unit doesn't work
default:
case SPLASH_SCREEN:
new StartupGUI().setVisible(true);
break;
}
}

private static void setLookAndFeel() {
try {
String plaf = CConfig.getParam(CConfig.CONFIG_PLAF, UIManager.getSystemLookAndFeelClassName());
String plaf = CConfig.getParam(CConfig.GUI_PLAF, UIManager.getSystemLookAndFeelClassName());
UIManager.setLookAndFeel(plaf);
} catch (Exception ex) {
LogManager.getLogger().error("", ex);
Expand All @@ -100,4 +132,41 @@ public static SuitePreferences getMMLPreferences() {
public static MMLOptions getMMLOptions() {
return mmlOptions;
}

/**
* Tries loading the most recent unit. Returns true when successful, false when no such
* unit could be found or the unit doesn't load.
*
* @return True when the most recent unit is successfully loaded
*/
private static boolean loadMostRecentUnit() {
String mostRecentName = CConfig.getRecentFile(1);
if (mostRecentName.isBlank()) {
PopupMessages.showNoMostRecentUnitError(null);
return false;
}

File unitFile = new File(mostRecentName);
if (!unitFile.isFile()) {
PopupMessages.showMostRecentUnitMissingError(null);
return false;
}

try {
Entity recentUnit = new MechFileParser(unitFile).getEntity();
if (recentUnit == null) {
return false;
} else if (!UnitUtil.validateUnit(recentUnit).isBlank()) {
PopupMessages.showUnitInvalidWarning(null, UnitUtil.validateUnit(recentUnit));
}

UiLoader.loadUi(recentUnit, unitFile.toString());
return true;
} catch (Exception ex) {
PopupMessages.showFileReadError(null, unitFile.toString(), ex.getMessage());
return false;
}
}

private MegaMekLab() { }
}
3 changes: 2 additions & 1 deletion megameklab/src/megameklab/printing/PrintEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import megamek.common.options.PilotOptions;
import megamek.common.options.Quirks;
import megameklab.util.CConfig;
import megameklab.util.RSScale;
import org.apache.batik.anim.dom.SVGGraphicsElement;
import org.apache.batik.anim.dom.SVGLocatableSupport;
import org.apache.batik.util.SVGConstants;
Expand Down Expand Up @@ -424,7 +425,7 @@ protected void drawStructure() {
*/
protected void writeEquipment(SVGRectElement svgRect) {
new InventoryWriter(this, svgRect).writeEquipment();
if (!CConfig.scaleUnits().equals(CConfig.RSScale.HEXES)) {
if (!CConfig.scaleUnits().equals(RSScale.HEXES)) {
setTextField(UNIT_SCALE, "(" + CConfig.scaleUnits().fullName + ")");
}
}
Expand Down
3 changes: 2 additions & 1 deletion megameklab/src/megameklab/printing/PrintMech.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import megameklab.printing.reference.*;
import megameklab.util.CConfig;
import megameklab.util.ImageHelper;
import megameklab.util.RSScale;
import megameklab.util.UnitUtil;
import org.apache.batik.anim.dom.SVGDOMImplementation;
import org.apache.batik.dom.util.SAXDocumentFactory;
Expand Down Expand Up @@ -644,7 +645,7 @@ private String formatHeatSinkType() {
private String formatHeatMovementPenalty(int penalty) {
// 2212 is the Unicode Minus Sign; has much better length than '-'; supported by most fonts
String penaltyString = "\u2212" + CConfig.formatScale(penalty, true) + " Movement";
if (CConfig.scaleUnits() == CConfig.RSScale.HEXES) {
if (CConfig.scaleUnits() == RSScale.HEXES) {
penaltyString += " Points";
}
return penaltyString;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import megameklab.printing.PrintEntity;
import megameklab.printing.PrintRecordSheet;
import megameklab.util.CConfig;
import megameklab.util.RSScale;
import org.apache.batik.util.SVGConstants;

/**
Expand Down Expand Up @@ -91,7 +92,7 @@ private void addVeeAttackerMods() {
private void addTerrainMods() {
addRow(bundle.getString("terrain"), "", "");
String hexName;
if (CConfig.scaleUnits().equals(CConfig.RSScale.HEXES)) {
if (CConfig.scaleUnits().equals(RSScale.HEXES)) {
hexName = "hex";
} else {
hexName = CConfig.getIntParam(CConfig.RS_SCALE_FACTOR)
Expand All @@ -104,7 +105,7 @@ private void addTerrainMods() {

private void addTargetMods() {
addRow(bundle.getString("target"), "", "");
if (CConfig.scaleUnits().equals(CConfig.RSScale.HEXES)) {
if (CConfig.scaleUnits().equals(RSScale.HEXES)) {
addRow("", bundle.getString("proneAdjacent"), "-2");
} else {
addRow("", bundle.getString("proneBasesToBase"), "-2");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import megamek.common.actions.ClubAttackAction;
import megameklab.printing.PrintMech;
import megameklab.util.CConfig;
import megameklab.util.RSScale;
import megameklab.util.StringUtils;
import org.apache.batik.util.SVGConstants;

Expand Down Expand Up @@ -59,7 +60,7 @@ public PhysicalAttacks(PrintMech sheet) {
addRow(bundle.getString("charge"), "+0*", String.format(hasTorsoSpikes ?
"%.0f/%s\u2020" : "%.0f/%s",
Math.floor(sheet.getEntity().getWeight() / 10.0),
CConfig.scaleUnits().equals(CConfig.RSScale.HEXES) ?
CConfig.scaleUnits().equals(RSScale.HEXES) ?
bundle.getString("hex") :
CConfig.getIntParam(CConfig.RS_SCALE_FACTOR) + CConfig.scaleUnits().abbreviation));
if (sheet.getEntity().getOriginalJumpMP() > 0) {
Expand Down
65 changes: 65 additions & 0 deletions megameklab/src/megameklab/ui/MMLStartUp.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright (c) 2023 - The MegaMek Team. All Rights Reserved.
*
* This file is part of MegaMekLab.
*
* MegaMek is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MegaMek is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MegaMek. If not, see <http://www.gnu.org/licenses/>.
*/
package megameklab.ui;

import java.util.ResourceBundle;

/**
* This class represents the different types of entry into MML that can be configured in the settings. Options
* are e.g. starting with the splash screen main UI (as it has been), trying to load the most recent unit or
* starting with a new unit directly.
*
* @author Simon (Juliez)
*/
public enum MMLStartUp {

SPLASH_SCREEN,
RECENT_UNIT,
NEW_MEK,
NEW_TANK,
NEW_BATTLEARMOR,
NEW_CONVINFANTRY,
NEW_FIGHTER,
NEW_DROPSHIP,
NEW_JUMPSHIP,
NEW_SUPPORTVEE,
NEW_PROTOMEK;

private final ResourceBundle resources = ResourceBundle.getBundle("megameklab.resources.Menu");

/** @return A display name for this MMLStartUp taken from the resources (possibly localised). */
public String getDisplayName() {
return resources.getString("MMLStartUp." + name());
}

/**
* Parses the given String, returning the MMLStartUp fitting the String like the valueOf() method does,
* but returns SPLASH_SCREEN when it can't be parsed (instead of null).
*
* @param startUpName A string giving one of the MMLStartUp values
* @return the MMLStartUp parsed from the string or SPLASH_SCREEN. Never returns null.
*/
public static MMLStartUp parse(String startUpName) {
try {
return valueOf(startUpName);
} catch (IllegalArgumentException e) {
return SPLASH_SCREEN;
}
}
}
Loading

0 comments on commit a95494c

Please sign in to comment.