diff --git a/megameklab/resources/megameklab/resources/Dialogs.properties b/megameklab/resources/megameklab/resources/Dialogs.properties
index b516eee11..6937df920 100644
--- a/megameklab/resources/megameklab/resources/Dialogs.properties
+++ b/megameklab/resources/megameklab/resources/Dialogs.properties
@@ -66,6 +66,8 @@ 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.
ConfigurationDialog.mekChassis.text=Mek Chassis Arrangement:
ConfigurationDialog.mekChassis.tooltip=Meks with a Clan and an IS chassis name will print their chassis in the selected arrangement. Meks with no clan chassis name will always just print their chassis.
+ConfigurationDialog.cbMulDndBehaviour.text=MUL file drag and drop behaviour:
+ConfigurationDialog.cbMulDndBehaviour.tooltip=What should be done when a MUL file is dragged onto the MML window?
RecordSheetTask.printing=Printing
RecordSheetTask.exporting=Exporting
diff --git a/megameklab/resources/megameklab/resources/Menu.properties b/megameklab/resources/megameklab/resources/Menu.properties
index b69fc38d7..5b8a40a5e 100644
--- a/megameklab/resources/megameklab/resources/Menu.properties
+++ b/megameklab/resources/megameklab/resources/Menu.properties
@@ -117,6 +117,9 @@ MMLStartUp.NEW_JUMPSHIP=New Advanced Aerospace
MMLStartUp.NEW_SUPPORTVEE=New Support Vehicle
MMLStartUp.NEW_PROTOMEK=New ProtoMek
+MulDndBehaviour.PRINT=Print
+MulDndBehaviour.EXPORT=Export to PDF
+
# The following values are used programatically by ClanISMekNameOrdering
ClanISMekNameOrdering.CLAN_IS=Clan Name (IS Name)
ClanISMekNameOrdering.IS_CLAN=IS Name (Clan Name)
diff --git a/megameklab/src/megameklab/ui/MegaMekLabMainUI.java b/megameklab/src/megameklab/ui/MegaMekLabMainUI.java
index f4466140e..1b1e61877 100644
--- a/megameklab/src/megameklab/ui/MegaMekLabMainUI.java
+++ b/megameklab/src/megameklab/ui/MegaMekLabMainUI.java
@@ -24,6 +24,7 @@
import megameklab.ui.util.ExitOnWindowClosingListener;
import megameklab.ui.util.RefreshListener;
import megameklab.util.CConfig;
+import megameklab.util.MMLFileDropTarget;
import javax.swing.*;
import java.awt.*;
@@ -34,7 +35,7 @@ public abstract class MegaMekLabMainUI extends JFrame implements RefreshListener
protected MenuBar mmlMenuBar;
protected boolean refreshRequired = false;
private String originalName = "";
-
+
public MegaMekLabMainUI() {
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
addWindowListener(new ExitOnWindowClosingListener(this));
@@ -46,8 +47,9 @@ protected void finishSetup() {
setJMenuBar(mmlMenuBar);
reloadTabs();
refreshAll();
+ this.setDropTarget(new MMLFileDropTarget(this));
}
-
+
protected void setSizeAndLocation() {
pack();
restrictToScrenSize();
@@ -196,4 +198,9 @@ public void refreshMenuBar() {
public boolean hasEntityNameChanged() {
return !MenuBar.createUnitFilename(entity).equals(originalName);
}
-}
\ No newline at end of file
+
+ @Override
+ public MenuBar getMMLMenuBar() {
+ return mmlMenuBar;
+ }
+}
diff --git a/megameklab/src/megameklab/ui/MenuBar.java b/megameklab/src/megameklab/ui/MenuBar.java
index b82ab09eb..12462e116 100644
--- a/megameklab/src/megameklab/ui/MenuBar.java
+++ b/megameklab/src/megameklab/ui/MenuBar.java
@@ -1202,6 +1202,10 @@ private void loadUnitFromFile(int fileNumber) {
}
}
+ loadFile(unitFile);
+ }
+
+ public void loadFile(File unitFile) {
try {
Entity loadedUnit = new MekFileParser(unitFile).getEntity();
diff --git a/megameklab/src/megameklab/ui/MenuBarOwner.java b/megameklab/src/megameklab/ui/MenuBarOwner.java
index 04a1feae9..7f6699984 100644
--- a/megameklab/src/megameklab/ui/MenuBarOwner.java
+++ b/megameklab/src/megameklab/ui/MenuBarOwner.java
@@ -133,4 +133,6 @@ default void changeTheme(String lookAndFeelInfo) {
}
});
}
+
+ MenuBar getMMLMenuBar();
}
diff --git a/megameklab/src/megameklab/ui/MulDndBehaviour.java b/megameklab/src/megameklab/ui/MulDndBehaviour.java
new file mode 100644
index 000000000..80da7cd2e
--- /dev/null
+++ b/megameklab/src/megameklab/ui/MulDndBehaviour.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2024 - 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 .
+ */
+package megameklab.ui;
+
+import java.util.ResourceBundle;
+
+public enum MulDndBehaviour {
+ PRINT,
+ EXPORT;
+
+ 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("MulDndBehaviour." + name());
+ }
+}
diff --git a/megameklab/src/megameklab/ui/StartupGUI.java b/megameklab/src/megameklab/ui/StartupGUI.java
index de277199c..d1b80ed78 100644
--- a/megameklab/src/megameklab/ui/StartupGUI.java
+++ b/megameklab/src/megameklab/ui/StartupGUI.java
@@ -29,6 +29,7 @@
import megameklab.ui.dialog.UiLoader;
import megameklab.ui.util.ExitOnWindowClosingListener;
import megameklab.util.CConfig;
+import megameklab.util.MMLFileDropTarget;
import megameklab.util.UnitUtil;
import javax.swing.*;
@@ -236,6 +237,7 @@ private void initComponents() {
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
+ this.setDropTarget(new MMLFileDropTarget(this));
}
/**
@@ -314,4 +316,9 @@ public boolean hasEntityNameChanged() {
public void refreshMenuBar() {
mmlMenuBar.refreshMenuBar();
}
+
+ @Override
+ public MenuBar getMMLMenuBar() {
+ return mmlMenuBar;
+ }
}
diff --git a/megameklab/src/megameklab/ui/dialog/settings/MiscSettingsPanel.java b/megameklab/src/megameklab/ui/dialog/settings/MiscSettingsPanel.java
index 5c1df2036..93ee203f1 100644
--- a/megameklab/src/megameklab/ui/dialog/settings/MiscSettingsPanel.java
+++ b/megameklab/src/megameklab/ui/dialog/settings/MiscSettingsPanel.java
@@ -39,16 +39,10 @@
import megamek.common.preference.PreferenceManager;
import megamek.logging.MMLogger;
import megameklab.ui.MMLStartUp;
+import megameklab.ui.MulDndBehaviour;
import megameklab.ui.util.SpringUtilities;
import megameklab.util.CConfig;
-import org.apache.logging.log4j.LogManager;
-import javax.swing.*;
-import javax.swing.border.EmptyBorder;
-import java.awt.*;
-import java.io.File;
-import java.net.MalformedURLException;
-import java.net.URL;
import java.util.*;
/**
@@ -64,9 +58,10 @@ public class MiscSettingsPanel extends JPanel {
private final JCheckBox chkSkipSavePrompts = new JCheckBox();
private final JTextField txtUserDir = new JTextField(20);
private final JSlider guiScale = new JSlider();
+ private final MMComboBox cbMulDndBehaviour = new MMComboBox<>("MUL Drag and Drop behaviour", MulDndBehaviour.values());
MiscSettingsPanel(JFrame parent) {
- startUpMMComboBox.setRenderer(startUpRenderer);
+ startUpMMComboBox.setRenderer(miscComboBoxRenderer);
startUpMMComboBox.setSelectedItem(CConfig.getStartUpType());
startUpMMComboBox.setToolTipText(resources.getString("ConfigurationDialog.startup.tooltip"));
JLabel startUpLabel = new JLabel(resources.getString("ConfigurationDialog.startup.text"));
@@ -78,6 +73,17 @@ public class MiscSettingsPanel extends JPanel {
startUpLine.add(Box.createHorizontalStrut(5));
startUpLine.add(startUpMMComboBox);
+ cbMulDndBehaviour.setRenderer(miscComboBoxRenderer);
+ cbMulDndBehaviour.setToolTipText(resources.getString("ConfigurationDialog.cbMulDndBehaviour.tooltip"));
+ cbMulDndBehaviour.setSelectedItem(CConfig.getBooleanParam(CConfig.MISC_MUL_DND_BEHAVIOUR) ? MulDndBehaviour.EXPORT : MulDndBehaviour.PRINT);
+ JLabel mulDndLabel = new JLabel(resources.getString("ConfigurationDialog.cbMulDndBehaviour.text"));
+ mulDndLabel.setToolTipText(resources.getString("ConfigurationDialog.cbMulDndBehaviour.tooltip"));
+
+ JPanel mulDndLine = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
+ mulDndLine.add(mulDndLabel);
+ mulDndLine.add(Box.createHorizontalStrut(5));
+ mulDndLine.add(cbMulDndBehaviour);
+
chkSummaryFormatTRO.setText(resources.getString("ConfigurationDialog.chkSummaryFormatTRO.text"));
chkSummaryFormatTRO.setToolTipText(resources.getString("ConfigurationDialog.chkSummaryFormatTRO.tooltip"));
@@ -136,11 +142,12 @@ public class MiscSettingsPanel extends JPanel {
JPanel gridPanel = new JPanel(new SpringLayout());
gridPanel.add(startUpLine);
gridPanel.add(userDirLine);
+ gridPanel.add(mulDndLine);
gridPanel.add(chkSummaryFormatTRO);
gridPanel.add(chkSkipSavePrompts);
gridPanel.add(scaleLine);
- SpringUtilities.makeCompactGrid(gridPanel, 5, 1, 0, 0, 15, 10);
+ SpringUtilities.makeCompactGrid(gridPanel, 6, 1, 0, 0, 15, 10);
gridPanel.setBorder(new EmptyBorder(20, 30, 20, 30));
setLayout(new FlowLayout(FlowLayout.LEFT));
add(gridPanel);
@@ -154,6 +161,7 @@ Map getMiscSettings() {
? MMLStartUp.SPLASH_SCREEN
: startUpMMComboBox.getSelectedItem();
miscSettings.put(CConfig.MISC_STARTUP, startUp.name());
+ miscSettings.put(CConfig.MISC_MUL_DND_BEHAVIOUR, String.valueOf(cbMulDndBehaviour.getSelectedItem() == MulDndBehaviour.EXPORT));
// User directory and gui scale are stored in MM's client settings, not in CConfig, therefore not added here
return miscSettings;
}
@@ -166,7 +174,7 @@ float guiScale() {
return 0.1f * guiScale.getValue();
}
- DefaultListCellRenderer startUpRenderer = new DefaultListCellRenderer() {
+ DefaultListCellRenderer miscComboBoxRenderer = new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList> list, Object value, int index, boolean isSelected,
boolean cellHasFocus) {
@@ -175,6 +183,11 @@ public Component getListCellRendererComponent(JList> list, Object value, int i
};
private String displayName(Object value) {
- return (value instanceof MMLStartUp) ? ((MMLStartUp) value).getDisplayName() : "";
+ if (value instanceof MMLStartUp su) {
+ return su.getDisplayName();
+ } else if (value instanceof MulDndBehaviour mdb) {
+ return mdb.getDisplayName();
+ }
+ return "";
}
}
diff --git a/megameklab/src/megameklab/util/CConfig.java b/megameklab/src/megameklab/util/CConfig.java
index 290857a42..90137fc2b 100644
--- a/megameklab/src/megameklab/util/CConfig.java
+++ b/megameklab/src/megameklab/util/CConfig.java
@@ -62,6 +62,7 @@ public final class CConfig {
public static final String MISC_STARTUP = "StartupGui";
public static final String MISC_SUMMARY_FORMAT_TRO = "useTROFormat";
public static final String MISC_SKIP_SAFETY_PROMPTS = "skipSafetyPrompts";
+ public static final String MISC_MUL_DND_BEHAVIOUR = "mulDndBehaviour";
public static final String GUI_PLAF = "lookAndFeel";
public static final String GUI_COLOR_WEAPONS = "Weapons";
diff --git a/megameklab/src/megameklab/util/MMLFileDropTarget.java b/megameklab/src/megameklab/util/MMLFileDropTarget.java
new file mode 100644
index 000000000..f4a3e0a02
--- /dev/null
+++ b/megameklab/src/megameklab/util/MMLFileDropTarget.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2024 - 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 .
+ */
+
+package megameklab.util;
+
+import megamek.logging.MMLogger;
+import megameklab.ui.MenuBarOwner;
+
+import java.awt.datatransfer.DataFlavor;
+import java.awt.dnd.DnDConstants;
+import java.awt.dnd.DropTarget;
+import java.awt.dnd.DropTargetDropEvent;
+import java.io.File;
+import java.util.List;
+
+public class MMLFileDropTarget extends DropTarget {
+ private static final MMLogger logger = MMLogger.create(MMLFileDropTarget.class);
+
+ private final MenuBarOwner owner;
+
+ public MMLFileDropTarget(MenuBarOwner owner) {
+ this.owner = owner;
+ }
+
+ @Override
+ public synchronized void drop(DropTargetDropEvent event) {
+ try {
+ event.acceptDrop(DnDConstants.ACTION_COPY);
+ var files = (List) event.getTransferable().getTransferData(DataFlavor.javaFileListFlavor);
+ if (files.size() != 1) {
+ event.dropComplete(false);
+ return;
+ }
+
+ var file = files.get(0);
+ var name = file.getName();
+
+ if (name.endsWith(".mtf") || name.endsWith(".blk")) {
+ owner.getMMLMenuBar().loadFile(file);
+ event.dropComplete(true);
+ } else if (name.endsWith(".mul")) {
+ UnitPrintManager.printMUL(owner.getFrame(), CConfig.getBooleanParam(CConfig.MISC_MUL_DND_BEHAVIOUR), file);
+ event.dropComplete(true);
+ } else {
+ event.dropComplete(false);
+ }
+
+
+ } catch (Exception e) {
+ event.dropComplete(false);
+ logger.warn(e);
+ }
+ }
+}
diff --git a/megameklab/src/megameklab/util/UnitPrintManager.java b/megameklab/src/megameklab/util/UnitPrintManager.java
index 945750468..0cfc729dd 100644
--- a/megameklab/src/megameklab/util/UnitPrintManager.java
+++ b/megameklab/src/megameklab/util/UnitPrintManager.java
@@ -77,20 +77,24 @@ public static void printMUL(JFrame parent, boolean printToPdf) {
// I want a file, y'know!
return;
}
+ printMUL(parent, printToPdf, f.getSelectedFile());
+ }
+
+ public static void printMUL(JFrame parent, boolean printToPdf, File file) {
Vector loadedUnits;
try {
var options = new GameOptions();
options.initialize();
options.getOption(RPG_MANEI_DOMINI).setValue(true);
options.getOption(RPG_PILOT_ADVANTAGES).setValue(true);
- loadedUnits = new MULParser(f.getSelectedFile(), options).getEntities();
+ loadedUnits = new MULParser(file, options).getEntities();
loadedUnits.trimToSize();
} catch (Exception ex) {
logger.error("", ex);
return;
}
- new PrintQueueDialog(parent, printToPdf, loadedUnits, true, f.getSelectedFile().getName()).setVisible(true);
+ new PrintQueueDialog(parent, printToPdf, loadedUnits, true, file.getName()).setVisible(true);
}
public static File getExportFile(Frame parent) {