From 6cf7d758efb24a4d526630afdcc12105536a61ab Mon Sep 17 00:00:00 2001 From: Craig Wisniewski Date: Thu, 17 Oct 2024 19:18:05 +1030 Subject: [PATCH] Revert "Provide functionality for add-on development" --- build.gradle | 3 - .../maptool/client/AppPreferences.java | 9 - .../ui/addon/AddOnLibrariesDialogView.form | 206 ++------- .../ui/addon/AddOnLibrariesDialogView.java | 300 ++---------- .../ui/addon/AddOnLibrariesTableModel.java | 38 +- .../client/ui/addon/CreateNewAddonDialog.form | 328 ------------- .../client/ui/addon/CreateNewAddonDialog.java | 259 ----------- .../addon/ExternalAddOnImportCellEditor.java | 89 ---- .../ExternalAddOnLibrariesTableModel.java | 99 ---- .../client/ui/addon/creator/MTLibCreator.java | 102 ---- .../client/ui/addon/creator/NewAddOn.java | 53 --- .../ui/addon/creator/NewAddOnBuilder.java | 248 ---------- .../ui/addon/creator/NewAddOnCreator.java | 335 -------------- .../CampaignPropertiesDialog.java | 5 +- .../library/ExternalAddonsUpdateEvent.java | 18 - .../maptool/model/library/LibraryManager.java | 91 +--- .../model/library/addon/AddOnLibrary.java | 92 +--- .../library/addon/AddOnLibraryImporter.java | 193 +------- .../library/addon/AddOnLibraryManager.java | 120 +---- .../addon/ExternalAddOnLibraryManager.java | 435 ------------------ .../library/addon/ExternalLibraryInfo.java | 36 -- .../net/rptools/maptool/util/FileUtil.java | 39 -- .../rptools/maptool/language/i18n.properties | 40 +- .../maptool/language/i18n_cs.properties | 4 +- .../maptool/language/i18n_da.properties | 4 +- .../maptool/language/i18n_en.properties | 4 +- .../maptool/language/i18n_en_AU.properties | 4 +- .../maptool/language/i18n_en_GB.properties | 6 +- .../maptool/language/i18n_es.properties | 4 +- .../maptool/language/i18n_fr.properties | 4 +- .../maptool/language/i18n_it.properties | 4 +- .../maptool/language/i18n_nl.properties | 4 +- .../maptool/language/i18n_pl.properties | 4 +- .../maptool/language/i18n_pt.properties | 4 +- .../maptool/language/i18n_ru.properties | 4 +- .../maptool/language/i18n_si.properties | 4 +- .../maptool/language/i18n_sv.properties | 4 +- .../maptool/language/i18n_uk.properties | 4 +- .../maptool/language/i18n_zh.properties | 4 +- 39 files changed, 159 insertions(+), 3045 deletions(-) delete mode 100644 src/main/java/net/rptools/maptool/client/ui/addon/CreateNewAddonDialog.form delete mode 100644 src/main/java/net/rptools/maptool/client/ui/addon/CreateNewAddonDialog.java delete mode 100644 src/main/java/net/rptools/maptool/client/ui/addon/ExternalAddOnImportCellEditor.java delete mode 100644 src/main/java/net/rptools/maptool/client/ui/addon/ExternalAddOnLibrariesTableModel.java delete mode 100644 src/main/java/net/rptools/maptool/client/ui/addon/creator/MTLibCreator.java delete mode 100644 src/main/java/net/rptools/maptool/client/ui/addon/creator/NewAddOn.java delete mode 100644 src/main/java/net/rptools/maptool/client/ui/addon/creator/NewAddOnBuilder.java delete mode 100644 src/main/java/net/rptools/maptool/client/ui/addon/creator/NewAddOnCreator.java delete mode 100644 src/main/java/net/rptools/maptool/model/library/ExternalAddonsUpdateEvent.java delete mode 100644 src/main/java/net/rptools/maptool/model/library/addon/ExternalAddOnLibraryManager.java delete mode 100644 src/main/java/net/rptools/maptool/model/library/addon/ExternalLibraryInfo.java diff --git a/build.gradle b/build.gradle index 9707e79bc3..d3bfe5e7d6 100644 --- a/build.gradle +++ b/build.gradle @@ -485,9 +485,6 @@ dependencies { // Built In Add-on Libraries implementation 'com.github.RPTools:maptool-builtin-addons:1.3' - // File watcher library to work around some inconsistencies with java.nio.file.WatchService - implementation 'io.methvin:directory-watcher:0.18.0' - // For advanced dice roller implementation 'com.github.RPTools:advanced-dice-roller:1.0.3' } diff --git a/src/main/java/net/rptools/maptool/client/AppPreferences.java b/src/main/java/net/rptools/maptool/client/AppPreferences.java index e46ae34e66..ff458fbe5b 100644 --- a/src/main/java/net/rptools/maptool/client/AppPreferences.java +++ b/src/main/java/net/rptools/maptool/client/AppPreferences.java @@ -393,15 +393,6 @@ public class AppPreferences { public static final Preference iconTheme = StringType.create("iconTheme", "Rod Takehara"); - public static final Preference externalAddOnLibrariesPath = - StringType.create("externalAddOnLibrariesPath", null); - - public static final Preference externalAddOnLibrariesEnabled = - BooleanType.create("externalAddOnLibrariesEnabled", false); - - public static final Preference createAddOnParentDir = - StringType.create("createAddOnParentDir", System.getProperty("user.home")); - static { // Used to be stored as separate components but now is one color. Add if not already there. if (prefs.get("trustedPrefixFG", null) == null) { diff --git a/src/main/java/net/rptools/maptool/client/ui/addon/AddOnLibrariesDialogView.form b/src/main/java/net/rptools/maptool/client/ui/addon/AddOnLibrariesDialogView.form index 42ba1f8bfb..e27669d642 100644 --- a/src/main/java/net/rptools/maptool/client/ui/addon/AddOnLibrariesDialogView.form +++ b/src/main/java/net/rptools/maptool/client/ui/addon/AddOnLibrariesDialogView.form @@ -1,26 +1,31 @@
- + + - - + - + + + + + + - - - + + + @@ -36,8 +41,8 @@ - - + + @@ -50,19 +55,15 @@ - + - + - - - - - + @@ -187,7 +188,6 @@ - @@ -275,7 +275,7 @@ - + @@ -283,146 +283,40 @@ - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + @@ -431,7 +325,9 @@ - + + + diff --git a/src/main/java/net/rptools/maptool/client/ui/addon/AddOnLibrariesDialogView.java b/src/main/java/net/rptools/maptool/client/ui/addon/AddOnLibrariesDialogView.java index 5ce4cc77c2..75137f8120 100644 --- a/src/main/java/net/rptools/maptool/client/ui/addon/AddOnLibrariesDialogView.java +++ b/src/main/java/net/rptools/maptool/client/ui/addon/AddOnLibrariesDialogView.java @@ -16,6 +16,8 @@ import java.awt.Toolkit; import java.awt.datatransfer.StringSelection; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; @@ -25,7 +27,6 @@ import java.util.Optional; import java.util.concurrent.ExecutionException; import javax.swing.JButton; -import javax.swing.JCheckBox; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JFileChooser; @@ -33,155 +34,52 @@ import javax.swing.JPanel; import javax.swing.JTabbedPane; import javax.swing.JTable; -import javax.swing.JTextField; import javax.swing.JTextPane; import javax.swing.KeyStroke; -import javax.swing.filechooser.FileNameExtensionFilter; import net.rptools.maptool.client.AppActions.MapPreviewFileChooser; import net.rptools.maptool.client.AppConstants; -import net.rptools.maptool.client.AppPreferences; import net.rptools.maptool.client.MapTool; -import net.rptools.maptool.client.swing.SwingUtil; import net.rptools.maptool.client.ui.JLabelHyperLinkListener; import net.rptools.maptool.client.ui.ViewAssetDialog; -import net.rptools.maptool.client.ui.addon.creator.MTLibCreator; -import net.rptools.maptool.events.MapToolEventBus; import net.rptools.maptool.language.I18N; import net.rptools.maptool.model.library.Library; import net.rptools.maptool.model.library.LibraryInfo; import net.rptools.maptool.model.library.LibraryManager; import net.rptools.maptool.model.library.addon.AddOnLibraryImporter; -import net.rptools.maptool.model.library.addon.ExternalLibraryInfo; /** Dialog for managing add-on libraries. */ public class AddOnLibrariesDialogView extends JDialog { - /** Removes an add-on library. */ + private JPanel contentPane; private JButton buttonRemove; - - /** Closes the dialog. */ private JButton buttonClose; - - /** The tabbed pane for the dialog. */ private JTabbedPane tabbedPane; - - /** Table containing the imported add-ons */ private JTable addOnLibraryTable; - - /** The text pane for the add-on description. */ private JTextPane addOnDescriptionTextPane; - - /** Adds an add-on library. */ private JButton buttonAdd; - - /** The name of the selected add-on. */ private JLabel addOnNameLabel; - - /** The version of the selected add-on. */ private JLabel addOnVersionLabel; - - /** The authors of the selected add-on. */ private JLabel addOnAuthorsLabel; - - /** The namespace of the selected add-on. */ private JLabel addOnNamespaceLabel; - - /** The short description of the selected add-on. */ private JLabel addOnShortDescLabel; - - /** The website of the selected add-on. */ private JLabel addOnWebsiteLabel; - - /** The git URL of the selected add-on. */ private JLabel addOnGitUrlLabel; - - /** The license of the selected add-on. */ private JLabel addOnLicenseLabel; - - /** The button for viewing the README file of the selected add-on. */ private JButton viewReadMeFileButton; - - /** The button for viewing the license file of the selected add-on. */ private JButton viewLicenseFileButton; - - /** The button for copying the theme CSS. */ private JButton copyThemeCSS; - - /** The button for copying the stat sheet theme. */ private JButton copyStatSheetThemeButton; - /** The checkbox for enabling external add-ons. */ - private JCheckBox enableExternalAddOnCheckBox; - - /** The table for external add-ons. */ - private JTable externalAddonTable; - - /** The button for creating an add-on skeleton. */ - private JButton createAddonSkeletonButton; - - /** The text field for the add-on development directory. */ - private JTextField directoryTextField; - - /** The button for browsing to select the add-on development directory. */ - private JButton browseButton; - - /** The content pane for the dialog. */ - private JPanel contentPane; - - /** Creates a .mtlib (zip) file for the selected add-on. */ - private JButton createMTLibButton; - - /** The information for the selected add-on. */ private LibraryInfo selectedAddOn; - /** The model for the external add-on libraries table. */ - private final ExternalAddOnLibrariesTableModel externalAddOnLibrariesTableModel; - - /** The model for the add-on libraries table. */ - private final AddOnLibrariesTableModel addOnLibrariesTableModel; - - /** The currently selected external add-on. */ - private ExternalLibraryInfo selectedExternalAddon; - /** Creates a new instance of the dialog. */ public AddOnLibrariesDialogView() { setContentPane(contentPane); setModal(true); getRootPane().setDefaultButton(buttonClose); - - var eventBus = new MapToolEventBus().getMainEventBus(); - - addOnLibrariesTableModel = new AddOnLibrariesTableModel(); - eventBus.register(addOnLibrariesTableModel); - - addOnLibraryTable.setModel(addOnLibrariesTableModel); + addOnLibraryTable.setModel(new AddOnLibrariesTableModel()); addOnLibraryTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); - externalAddOnLibrariesTableModel = new ExternalAddOnLibrariesTableModel(); - externalAddonTable.setModel(externalAddOnLibrariesTableModel); - eventBus.register(externalAddOnLibrariesTableModel); - - externalAddonTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); - externalAddonTable.setDefaultRenderer( - ExternalLibraryInfo.class, new ExternalAddOnImportCellEditor()); - externalAddonTable.setDefaultEditor( - ExternalLibraryInfo.class, new ExternalAddOnImportCellEditor()); - externalAddonTable - .getSelectionModel() - .addListSelectionListener( - e -> { - int selectedRow = externalAddonTable.getSelectedRow(); - if (selectedRow == -1) { - createMTLibButton.setEnabled(false); - selectedExternalAddon = null; - } else { - createMTLibButton.setEnabled(true); - selectedExternalAddon = - (ExternalLibraryInfo) - externalAddOnLibrariesTableModel.getValueAt(selectedRow, 6); - } - }); - buttonRemove.setEnabled(false); addOnLibraryTable .getSelectionModel() @@ -232,7 +130,11 @@ public void windowClosing(WindowEvent e) { // call onClose() on ESCAPE contentPane.registerKeyboardAction( - e -> onClose(), + new ActionListener() { + public void actionPerformed(ActionEvent e) { + onClose(); + } + }, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); @@ -267,128 +169,42 @@ public void windowClosing(WindowEvent e) { }); copyThemeCSS.addActionListener( - e -> - new LibraryManager() - .getLibrary(AppConstants.MT_BUILTIN_ADD_ON_NAMESPACE) - .ifPresent( - library -> { - URI uri = URI.create(AppConstants.MT_THEME_CSS); - String themeCss = null; - try { - themeCss = library.readAsString(uri.toURL()).get(); - } catch (InterruptedException | ExecutionException | IOException ex) { - throw new RuntimeException(ex); - } - Toolkit.getDefaultToolkit() - .getSystemClipboard() - .setContents(new StringSelection(themeCss), null); - })); - - copyStatSheetThemeButton.addActionListener( - e -> - new LibraryManager() - .getLibrary(AppConstants.MT_BUILTIN_ADD_ON_NAMESPACE) - .ifPresent( - library -> { - URI uri = URI.create(AppConstants.MT_THEME_STAT_SHEET_CSS); - String themeCss = null; - try { - themeCss = library.readAsString(uri.toURL()).get(); - } catch (InterruptedException | ExecutionException | IOException ex) { - throw new RuntimeException(ex); - } - Toolkit.getDefaultToolkit() - .getSystemClipboard() - .setContents(new StringSelection(themeCss), null); - })); - - createAddonSkeletonButton.addActionListener(e -> createAddonSkeleton()); - - enableExternalAddOnCheckBox.addActionListener( e -> { - setExternalAddOnControlsEnabled(enableExternalAddOnCheckBox.isSelected()); - directoryTextField.setEnabled(enableExternalAddOnCheckBox.isSelected()); - try { - new LibraryManager() - .setExternalLibrariesEnabled(enableExternalAddOnCheckBox.isSelected()); - } catch (IOException ex) { - // do nothing - } - AppPreferences.externalAddOnLibrariesEnabled.set( - enableExternalAddOnCheckBox.isSelected()); - }); - - browseButton.addActionListener( - e -> { - JFileChooser chooser = new JFileChooser(); - chooser.setDialogTitle(I18N.getText("library.dialog.import.title")); - chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); - chooser.showOpenDialog(MapTool.getFrame()); - if (chooser.getSelectedFile() != null) { - directoryTextField.setText(chooser.getSelectedFile().getAbsolutePath()); - AppPreferences.externalAddOnLibrariesPath.set( - chooser.getSelectedFile().getAbsolutePath()); - } + new LibraryManager() + .getLibrary(AppConstants.MT_BUILTIN_ADD_ON_NAMESPACE) + .ifPresent( + library -> { + URI uri = URI.create(AppConstants.MT_THEME_CSS); + String themeCss = null; + try { + themeCss = library.readAsString(uri.toURL()).get(); + } catch (InterruptedException | ExecutionException | IOException ex) { + throw new RuntimeException(ex); + } + Toolkit.getDefaultToolkit() + .getSystemClipboard() + .setContents(new StringSelection(themeCss), null); + }); }); - createMTLibButton.addActionListener( + copyStatSheetThemeButton.addActionListener( e -> { - if (selectedExternalAddon == null) { - return; - } - - var fileChooser = new JFileChooser(); - fileChooser.setFileFilter( - new FileNameExtensionFilter( - I18N.getText("library.dialog.addon.fileFilter"), "mtlib")); - if (fileChooser.showSaveDialog(MapTool.getFrame()) == JFileChooser.APPROVE_OPTION) { - var outputPath = fileChooser.getSelectedFile().toPath(); - if (!outputPath.toString().endsWith(".mtlib")) { - outputPath = outputPath.resolveSibling(outputPath.getFileName() + ".mtlib"); - } - var creator = - new MTLibCreator( - selectedExternalAddon.backingDirectory(), - outputPath.getParent(), - outputPath.getFileName().toString()); - creator.create(); - } + new LibraryManager() + .getLibrary(AppConstants.MT_BUILTIN_ADD_ON_NAMESPACE) + .ifPresent( + library -> { + URI uri = URI.create(AppConstants.MT_THEME_STAT_SHEET_CSS); + String themeCss = null; + try { + themeCss = library.readAsString(uri.toURL()).get(); + } catch (InterruptedException | ExecutionException | IOException ex) { + throw new RuntimeException(ex); + } + Toolkit.getDefaultToolkit() + .getSystemClipboard() + .setContents(new StringSelection(themeCss), null); + }); }); - - createMTLibButton.setEnabled(false); - - LibraryManager libraryManager = new LibraryManager(); - enableExternalAddOnCheckBox.setSelected(libraryManager.externalLibrariesEnabled()); - directoryTextField.setText(AppPreferences.externalAddOnLibrariesPath.get()); - setExternalAddOnControlsEnabled(enableExternalAddOnCheckBox.isSelected()); - if (enableExternalAddOnCheckBox.isSelected()) { - refreshLibraries(); - } - pack(); - } - - /** Refreshes the external add-on libraries table information. */ - private void refreshLibraries() { - var model = (ExternalAddOnLibrariesTableModel) externalAddonTable.getModel(); - model.refresh(); - } - - /** - * Sets the enabled state of the external add-on controls. - * - * @param selected the state to set. - */ - private void setExternalAddOnControlsEnabled(boolean selected) { - externalAddonTable.setEnabled(selected); - browseButton.setEnabled(selected); - } - - /** Creates a new add-on skeleton. */ - private void createAddonSkeleton() { - var dialog = new CreateNewAddonDialog(); - dialog.pack(); - SwingUtil.centerOver(dialog, MapTool.getFrame()); - dialog.setVisible(true); } /** @@ -430,9 +246,6 @@ private void selectedAddOnChanged(LibraryInfo addOn) { /** Closes the dialog. */ private void onClose() { dispose(); - var eventBus = new MapToolEventBus().getMainEventBus(); - eventBus.unregister(externalAddOnLibrariesTableModel); - eventBus.unregister(addOnLibrariesTableModel); } /** Add an add-on library to the library manager. */ @@ -462,11 +275,6 @@ private void addAddOnLibrary() { } } - /** - * Views the license file for the given library. - * - * @param libInfo the library to view the license file for. - */ private void viewLicenseFile(LibraryInfo libInfo) { Optional lib = new LibraryManager().getLibrary(libInfo.namespace()); lib.ifPresent( @@ -476,20 +284,9 @@ private void viewLicenseFile(LibraryInfo libInfo) { .thenAccept( a -> a.ifPresent( - asset -> - new ViewAssetDialog( - asset, - I18N.getText("library.dialog.addon.license"), - 640, - 480) - .showModal()))); + asset -> new ViewAssetDialog(asset, "License", 640, 480).showModal()))); } - /** - * Views the README file for the given library. - * - * @param libInfo the library to view the README file for. - */ private void viewReadMeFile(LibraryInfo libInfo) { Optional lib = new LibraryManager().getLibrary(libInfo.namespace()); lib.ifPresent( @@ -499,12 +296,13 @@ private void viewReadMeFile(LibraryInfo libInfo) { .thenAccept( a -> a.ifPresent( - asset -> - new ViewAssetDialog( - asset, - I18N.getText("library.dialog.addon.readme"), - 640, - 480) - .showModal()))); + asset -> new ViewAssetDialog(asset, "License", 640, 480).showModal()))); + } + + public static void main(String[] args) { + AddOnLibrariesDialogView dialog = new AddOnLibrariesDialogView(); + dialog.pack(); + dialog.setVisible(true); + System.exit(0); } } diff --git a/src/main/java/net/rptools/maptool/client/ui/addon/AddOnLibrariesTableModel.java b/src/main/java/net/rptools/maptool/client/ui/addon/AddOnLibrariesTableModel.java index 579ae81f9c..cdc5e83822 100644 --- a/src/main/java/net/rptools/maptool/client/ui/addon/AddOnLibrariesTableModel.java +++ b/src/main/java/net/rptools/maptool/client/ui/addon/AddOnLibrariesTableModel.java @@ -14,46 +14,30 @@ */ package net.rptools.maptool.client.ui.addon; -import com.google.common.eventbus.Subscribe; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutionException; import javax.swing.table.AbstractTableModel; import net.rptools.maptool.language.I18N; -import net.rptools.maptool.model.library.AddOnsAddedEvent; import net.rptools.maptool.model.library.LibraryInfo; import net.rptools.maptool.model.library.LibraryManager; import net.rptools.maptool.model.library.LibraryType; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -/** - * The AddOnLibrariesTableModel class is a table model for displaying add-on libraries in the a - * JTable. - */ public class AddOnLibrariesTableModel extends AbstractTableModel { - - /** The logger. */ private static final Logger log = LogManager.getLogger(AddOnLibrariesDialogController.class); - /** The list of add-on libraries. */ private final List addons = new ArrayList<>(); - /** The AddOnLibrariesTableModel constructor. */ public AddOnLibrariesTableModel() { try { addons.addAll(new LibraryManager().getLibraries(LibraryType.ADD_ON)); } catch (ExecutionException | InterruptedException e) { - log.error(I18N.getText("library.dialog.error.displayingAddons"), e); + log.error("Error displaying add-on libraries", e); } } - /** - * Get the add-on library at the specified row of the table. - * - * @param row the row. - * @return the add-on library. - */ public LibraryInfo getAddOn(int row) { return addons.get(row); } @@ -101,24 +85,4 @@ public void fireTableDataChanged() { } super.fireTableDataChanged(); } - - /** - * Handle the AddOnsUpdatedEvent event by firing a table data changed event. - * - * @param event the AddOnsUpdatedEvent event. - */ - @Subscribe - public void handleAddOnsUpdatedEvent(AddOnsAddedEvent event) { - fireTableDataChanged(); - } - - /** - * Handle the AddOnsRemovedEvent event by firing a table data changed event. - * - * @param event the AddOnsRemovedEvent event. - */ - @Subscribe - public void handleAddOnsRemovedEvent(AddOnsAddedEvent event) { - fireTableDataChanged(); - } } diff --git a/src/main/java/net/rptools/maptool/client/ui/addon/CreateNewAddonDialog.form b/src/main/java/net/rptools/maptool/client/ui/addon/CreateNewAddonDialog.form deleted file mode 100644 index 949190019e..0000000000 --- a/src/main/java/net/rptools/maptool/client/ui/addon/CreateNewAddonDialog.form +++ /dev/null @@ -1,328 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/java/net/rptools/maptool/client/ui/addon/CreateNewAddonDialog.java b/src/main/java/net/rptools/maptool/client/ui/addon/CreateNewAddonDialog.java deleted file mode 100644 index 79e34f4db1..0000000000 --- a/src/main/java/net/rptools/maptool/client/ui/addon/CreateNewAddonDialog.java +++ /dev/null @@ -1,259 +0,0 @@ -/* - * This software Copyright by the RPTools.net development team, and - * licensed under the Affero GPL Version 3 or, at your option, any later - * version. - * - * MapTool Source Code 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. - * - * You should have received a copy of the GNU Affero General Public - * License * along with this source Code. If not, please visit - * and specifically the Affero license - * text at . - */ -package net.rptools.maptool.client.ui.addon; - -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.KeyEvent; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.io.File; -import java.io.IOException; -import java.util.List; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JComponent; -import javax.swing.JDialog; -import javax.swing.JFileChooser; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JTextField; -import javax.swing.JTextPane; -import javax.swing.KeyStroke; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; -import net.rptools.maptool.client.AppPreferences; -import net.rptools.maptool.client.MapTool; -import net.rptools.maptool.client.ui.addon.creator.NewAddOnBuilder; -import net.rptools.maptool.client.ui.addon.creator.NewAddOnCreator; -import net.rptools.maptool.language.I18N; - -/** Dialog for creating a new Add-On library skeleton. */ -public class CreateNewAddonDialog extends JDialog { - - /** The content pane. */ - private JPanel contentPane; - - /** OK button which will create the new Add-On. */ - private JButton buttonOK; - - /** Cancel button which will close the dialog. */ - private JButton buttonCancel; - - /** Text field for the Add-On name. */ - private JTextField nameTextField; - - /** Text field for the Add-On version. */ - private JTextField versionTextField; - - /** Check box for creating events. */ - private JCheckBox eventsCheckBox; - - /** Text pane for the Add-On description. */ - private JTextPane descriptionTextPane; - - /** Button for browsing for the directory to create the new add-on in. */ - private JButton directoryBrowseButton; - - /** Text field for the Add-On namespace. */ - private JTextField namespaceTextField; - - /** Text field for the Git URL. */ - private JTextField gitURLTextField; - - /** Text field for the website URL. */ - private JTextField websiteTextField; - - /** Text field for the license. */ - private JTextField licenseTextField; - - /** Text field for the authors. */ - private JTextField authorsTextField; - - /** Text field for the parent directory. */ - private JTextField parentDirectoryTextField; - - /** Check box for creating slash commands. */ - private JCheckBox slashCommandCheckBox; - - /** Check box for creating MTS properties. */ - private JCheckBox mtsPropCheckBox; - - /** Check box for creating UDFs. */ - private JCheckBox udfCheckBox; - - /** Text field for the short description. */ - private JTextField shortDescTextBox; - - /** Text field for the directory name. */ - private JTextField directoryTextField; - - /** Creates a new CreateNewAddonDialog. */ - public CreateNewAddonDialog() { - setContentPane(contentPane); - setModal(true); - getRootPane().setDefaultButton(buttonOK); - - buttonOK.addActionListener( - new ActionListener() { - public void actionPerformed(ActionEvent e) { - onOK(); - } - }); - - buttonCancel.addActionListener( - new ActionListener() { - public void actionPerformed(ActionEvent e) { - onCancel(); - } - }); - - // call onCancel() when cross is clicked - setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); - addWindowListener( - new WindowAdapter() { - public void windowClosing(WindowEvent e) { - onCancel(); - } - }); - - // call onCancel() on ESCAPE - contentPane.registerKeyboardAction( - new ActionListener() { - public void actionPerformed(ActionEvent e) { - onCancel(); - } - }, - KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), - JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); - - // browse button - directoryBrowseButton.addActionListener( - e -> { - JFileChooser chooser = new JFileChooser(); - chooser.setDialogTitle(I18N.getText("library.dialog.create.parentDir.title")); - chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); - chooser.showOpenDialog(MapTool.getFrame()); - if (chooser.getSelectedFile() != null) { - var path = chooser.getSelectedFile().getAbsolutePath(); - parentDirectoryTextField.setText(path); - AppPreferences.createAddOnParentDir.set(path); - } - }); - - var docChangeListener = - new DocumentListener() { - @Override - public void insertUpdate(DocumentEvent e) { - validateInputs(); - } - - @Override - public void removeUpdate(DocumentEvent e) { - validateInputs(); - } - - @Override - public void changedUpdate(DocumentEvent e) { - validateInputs(); - } - }; - - namespaceTextField.getDocument().addDocumentListener(docChangeListener); - nameTextField.getDocument().addDocumentListener(docChangeListener); - versionTextField.getDocument().addDocumentListener(docChangeListener); - parentDirectoryTextField.getDocument().addDocumentListener(docChangeListener); - directoryTextField.getDocument().addDocumentListener(docChangeListener); - authorsTextField.getDocument().addDocumentListener(docChangeListener); - licenseTextField.getDocument().addDocumentListener(docChangeListener); - shortDescTextBox.getDocument().addDocumentListener(docChangeListener); - descriptionTextPane.getDocument().addDocumentListener(docChangeListener); - - setDefaults(); - - validateInputs(); - } - - /** Sets the default values for the new add-on fields. */ - private void setDefaults() { - namespaceTextField.setText("net.some-example.addon"); - nameTextField.setText("Example Add-On"); - versionTextField.setText("0.0.1"); - shortDescTextBox.setText(I18N.getText("library.dialog.addon.create.shortDesc")); - descriptionTextPane.setText(I18N.getText("library.dialog.addon.create.longDesc")); - parentDirectoryTextField.setText(AppPreferences.createAddOnParentDir.get()); - } - - /** Validates the input fields. */ - private void validateInputs() { - buttonOK.setEnabled( - !namespaceTextField.getText().isEmpty() - && !nameTextField.getText().isEmpty() - && !versionTextField.getText().isEmpty() - && !parentDirectoryTextField.getText().isEmpty() - && !directoryTextField.getText().isEmpty() - && !authorsTextField.getText().isEmpty()); - } - - /** - * Handles the OK button click. This will attempt to create the new add-on skeleton based on the - * users inputs and then close the dialog. - */ - private void onOK() { - var parentDir = new File(parentDirectoryTextField.getText()); - if (!parentDir.exists()) { - JOptionPane.showMessageDialog( - this, I18N.getText("library.dialog.addon.create.noSuchDir", parentDir.toString())); - return; - } - var dir = parentDir.toPath().resolve(directoryTextField.getText()).toFile(); - if (dir.exists()) { - JOptionPane.showMessageDialog( - this, I18N.getText("library.dialog.addon.create.dirExists", dir.toString())); - return; - } - - var newAddon = - new NewAddOnBuilder() - .setName(nameTextField.getText()) - .setVersion(versionTextField.getText()) - .setNamespace(namespaceTextField.getText()) - .setGitURL(gitURLTextField.getText()) - .setWebsite(websiteTextField.getText()) - .setLicense(licenseTextField.getText()) - .setShortDescription(shortDescTextBox.getText()) - .setDescription(descriptionTextPane.getText()) - .setAuthors(List.of(authorsTextField.getText().split(","))) - .setCreateEvents(eventsCheckBox.isSelected()) - .setCreateSlashCommands(slashCommandCheckBox.isSelected()) - .setCreateUDFs(udfCheckBox.isSelected()) - .setCreateMTSProperties(mtsPropCheckBox.isSelected()) - .build(); - dispose(); - try { - new NewAddOnCreator(newAddon, dir.toPath()).create(); - } catch (IOException e) { - JOptionPane.showMessageDialog(this, e.getMessage()); - } - } - - /** - * Handles the cancel button click. This closes the dialog without attempting to create the new - * add-on skeleton. - */ - private void onCancel() { - dispose(); - } -} diff --git a/src/main/java/net/rptools/maptool/client/ui/addon/ExternalAddOnImportCellEditor.java b/src/main/java/net/rptools/maptool/client/ui/addon/ExternalAddOnImportCellEditor.java deleted file mode 100644 index e0c9722140..0000000000 --- a/src/main/java/net/rptools/maptool/client/ui/addon/ExternalAddOnImportCellEditor.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * This software Copyright by the RPTools.net development team, and - * licensed under the Affero GPL Version 3 or, at your option, any later - * version. - * - * MapTool Source Code 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. - * - * You should have received a copy of the GNU Affero General Public - * License * along with this source Code. If not, please visit - * and specifically the Affero license - * text at . - */ -package net.rptools.maptool.client.ui.addon; - -import java.awt.*; -import java.io.IOException; -import javax.swing.*; -import javax.swing.border.EmptyBorder; -import javax.swing.table.TableCellEditor; -import javax.swing.table.TableCellRenderer; -import net.rptools.maptool.client.MapTool; -import net.rptools.maptool.language.I18N; -import net.rptools.maptool.model.library.LibraryManager; -import net.rptools.maptool.model.library.addon.ExternalLibraryInfo; - -/** Cell editor for the import button in the external add-on dialog. */ -public class ExternalAddOnImportCellEditor extends AbstractCellEditor - implements TableCellEditor, TableCellRenderer { - - /** The button that is displayed in the cell. */ - private final JButton button = new JButton(); - - /** The external library info for the currently displayed row. */ - private ExternalLibraryInfo info; - - /** Creates a new cell editor. */ - public ExternalAddOnImportCellEditor() { - button.addActionListener( - e -> { - try { - new LibraryManager().importFromExternal(info.libraryInfo().namespace()); - } catch (IOException ex) { - MapTool.showError( - I18N.getText("library.dialog.import.failed", info.libraryInfo().namespace())); - } - stopCellEditing(); - }); - } - - @Override - public Component getTableCellEditorComponent( - JTable table, Object value, boolean isSelected, int row, int column) { - return getButton(table, value, isSelected, false, row, column); - } - - @Override - public Object getCellEditorValue() { - return info; - } - - @Override - public Component getTableCellRendererComponent( - JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { - return getButton(table, value, isSelected, hasFocus, row, column); - } - - /** Returns the button component for the given cell. */ - private Component getButton( - JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { - button.setEnabled(true); - info = (ExternalLibraryInfo) value; - String buttonTextKey; - if (info.isInstalled()) { - buttonTextKey = "library.dialog.reimport"; - } else { - buttonTextKey = "library.dialog.import"; - } - button.setText(I18N.getText(buttonTextKey)); - - var panel = new JPanel(); - panel.setLayout(new BorderLayout()); - panel.add(button, BorderLayout.CENTER); - panel.setBackground(isSelected ? table.getSelectionBackground() : table.getBackground()); - panel.setBorder(new EmptyBorder(1, 5, 2, 5)); - return panel; - } -} diff --git a/src/main/java/net/rptools/maptool/client/ui/addon/ExternalAddOnLibrariesTableModel.java b/src/main/java/net/rptools/maptool/client/ui/addon/ExternalAddOnLibrariesTableModel.java deleted file mode 100644 index a822cd33e6..0000000000 --- a/src/main/java/net/rptools/maptool/client/ui/addon/ExternalAddOnLibrariesTableModel.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * This software Copyright by the RPTools.net development team, and - * licensed under the Affero GPL Version 3 or, at your option, any later - * version. - * - * MapTool Source Code 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. - * - * You should have received a copy of the GNU Affero General Public - * License * along with this source Code. If not, please visit - * and specifically the Affero license - * text at . - */ -package net.rptools.maptool.client.ui.addon; - -import com.google.common.eventbus.Subscribe; -import java.util.List; -import javax.swing.table.AbstractTableModel; -import net.rptools.maptool.language.I18N; -import net.rptools.maptool.model.library.ExternalAddonsUpdateEvent; -import net.rptools.maptool.model.library.LibraryManager; -import net.rptools.maptool.model.library.addon.ExternalLibraryInfo; - -/** - * The ExternalAddOnLibrariesTableModel class is a table model for the external add-on libraries. - */ -public class ExternalAddOnLibrariesTableModel extends AbstractTableModel { - - @Override - public int getRowCount() { - return new LibraryManager().getExternalAddOnLibraries().size(); - } - - @Override - public int getColumnCount() { - return 7; - } - - @Override - public Class getColumnClass(int columnIndex) { - return switch (columnIndex) { - case 4, 5 -> Boolean.class; - case 6 -> ExternalLibraryInfo.class; - default -> String.class; - }; - } - - @Override - public boolean isCellEditable(int rowIndex, int columnIndex) { - return getColumnClass(columnIndex) == ExternalLibraryInfo.class; - } - - @Override - public Object getValueAt(int rowIndex, int columnIndex) { - List addons = new LibraryManager().getExternalAddOnLibraries(); - - var info = addons.get(rowIndex); - return switch (columnIndex) { - case 0 -> info.libraryInfo().name(); - case 1 -> info.libraryInfo().version(); - case 2 -> info.libraryInfo().namespace(); - case 3 -> info.subDirectoryName(); - case 4 -> info.isInstalled(); - case 5 -> info.updatedOnDisk(); - case 6 -> info; - default -> null; - }; - } - - @Override - public String getColumnName(int column) { - return switch (column) { - case 0 -> I18N.getText("library.dialog.addon.name"); - case 1 -> I18N.getText("library.dialog.addon.version"); - case 2 -> I18N.getText("library.dialog.addon.namespace"); - case 3 -> I18N.getText("library.dialog.addon.subdir"); - case 4 -> I18N.getText("library.dialog.addon.imported"); - case 5 -> I18N.getText("library.dialog.addon.updated"); - case 6 -> I18N.getText("library.dialog.addon.refresh"); - default -> null; - }; - } - - /** - * Handle the event when external addons are added. - * - * @param event the AddOnsAddedEvent event. - */ - @Subscribe - public void handleExternalAddOnsAdded(ExternalAddonsUpdateEvent event) { - refresh(); - } - - /** Refresh the table data. */ - public void refresh() { - fireTableDataChanged(); - } -} diff --git a/src/main/java/net/rptools/maptool/client/ui/addon/creator/MTLibCreator.java b/src/main/java/net/rptools/maptool/client/ui/addon/creator/MTLibCreator.java deleted file mode 100644 index 267446d9e8..0000000000 --- a/src/main/java/net/rptools/maptool/client/ui/addon/creator/MTLibCreator.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * This software Copyright by the RPTools.net development team, and - * licensed under the Affero GPL Version 3 or, at your option, any later - * version. - * - * MapTool Source Code 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. - * - * You should have received a copy of the GNU Affero General Public - * License * along with this source Code. If not, please visit - * and specifically the Affero license - * text at . - */ -package net.rptools.maptool.client.ui.addon.creator; - -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.HashSet; -import java.util.zip.Deflater; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; -import net.rptools.maptool.client.MapTool; - -/** - * This class is responsible for creating a .mtlib file from the contents of a directory. - * - *

The .mtlib file is a zip file that contains all the files in the directory. - * - *

The .mtlib file is used to install the add-on into MapTool. - */ -public class MTLibCreator { - - /** The path to the directory to create the .mtlib file from. */ - private final Path addOnPath; - - /** The output path for the .mtlib file. */ - private final Path outputPath; - - /** The name of the .mtlib file to create. */ - private final String fileName; - - /** - * Create a new instance of the MTLibCreator. - * - * @param addOnPath The path to the directory to create the .mtlib file from. - * @param outputPath The output path for the .mtlib file. - * @param fileName The name of the .mtlib file to create. - */ - public MTLibCreator(Path addOnPath, Path outputPath, String fileName) { - this.addOnPath = addOnPath; - this.outputPath = outputPath; - this.fileName = fileName; - } - - /** Create the .mtlib file. */ - public void create() { - try (var zipOut = new ZipOutputStream(Files.newOutputStream(outputPath.resolve(fileName)))) { - zipOut.setLevel(Deflater.BEST_COMPRESSION); - var fileList = new HashSet(); - try (var pathStream = Files.find(addOnPath, Integer.MAX_VALUE, this::includeFile)) { - pathStream.forEach(fileList::add); - } - for (Path path : fileList) { - zipOut.putNextEntry(new ZipEntry(addOnPath.relativize(path).toString())); - Files.copy(path, zipOut); - } - } catch (Exception e) { - MapTool.showError("library.dialog.addon.errorCreatingMTLib", e); - } - } - - /** - * Determine if a file should be included in the .mtlib file. - * - * @param path The path to the file. - * @param att The attributes of the file. - * @return True if the file should be included, false otherwise. - */ - private boolean includeFile(Path path, BasicFileAttributes att) { - var subPath = addOnPath.relativize(path); - - if (att.isDirectory()) { - return false; - } - - if (subPath.getNameCount() == 0) { - return false; - } - - if (subPath.getName(0).toString().startsWith(".")) { - return false; - } - - if (path.getFileName().toString().toLowerCase().endsWith(".mtlib")) { - return false; - } - - return true; - } -} diff --git a/src/main/java/net/rptools/maptool/client/ui/addon/creator/NewAddOn.java b/src/main/java/net/rptools/maptool/client/ui/addon/creator/NewAddOn.java deleted file mode 100644 index 367195e97c..0000000000 --- a/src/main/java/net/rptools/maptool/client/ui/addon/creator/NewAddOn.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This software Copyright by the RPTools.net development team, and - * licensed under the Affero GPL Version 3 or, at your option, any later - * version. - * - * MapTool Source Code 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. - * - * You should have received a copy of the GNU Affero General Public - * License * along with this source Code. If not, please visit - * and specifically the Affero license - * text at . - */ -package net.rptools.maptool.client.ui.addon.creator; - -import java.util.List; - -/** - * Represents a new AddOn to be created. - * - * @param name The name of the AddOn. - * @param version The version of the AddOn. - * @param namespace The namespace of the AddOn. - * @param gitURL The git URL of the AddOn. - * @param website The website of the AddOn. - * @param license The license of the AddOn. - * @param shortDescription The short description of the AddOn. - * @param description The description of the AddOn. - * @param authors The authors of the AddOn. - * @param createEvents Whether to create example events. - * @param createSlashCommands Whether to create example slash commands. - * @param createMTSProperties Whether to create example MTS properties. - * @param createUDFs Whether to create example UDFs. (not yet implemented). - * @param readme The readme of the AddOn. - * @param licenseText The license text of the AddOn. - */ -public record NewAddOn( - String name, - String version, - String namespace, - String gitURL, - String website, - String license, - String shortDescription, - String description, - List authors, - boolean createEvents, - boolean createSlashCommands, - boolean createMTSProperties, - boolean createUDFs, - String readme, - String licenseText) {} diff --git a/src/main/java/net/rptools/maptool/client/ui/addon/creator/NewAddOnBuilder.java b/src/main/java/net/rptools/maptool/client/ui/addon/creator/NewAddOnBuilder.java deleted file mode 100644 index 4b8257970c..0000000000 --- a/src/main/java/net/rptools/maptool/client/ui/addon/creator/NewAddOnBuilder.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * This software Copyright by the RPTools.net development team, and - * licensed under the Affero GPL Version 3 or, at your option, any later - * version. - * - * MapTool Source Code 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. - * - * You should have received a copy of the GNU Affero General Public - * License * along with this source Code. If not, please visit - * and specifically the Affero license - * text at . - */ -package net.rptools.maptool.client.ui.addon.creator; - -import java.util.ArrayList; -import java.util.List; -import net.rptools.maptool.language.I18N; - -/** Builder for creating a {@link NewAddOn}. */ -public class NewAddOnBuilder { - - /** The name of the add-on. */ - private String name; - - /** The version of the add-on. */ - private String version; - - /** The namespace of the add-on. */ - private String namespace; - - /** The git URL of the add-on. */ - private String gitURL; - - /** The website of the add-on. */ - private String website; - - /** The license of the add-on. */ - private String license; - - /** The short description of the add-on. */ - private String shortDescription; - - /** The description of the add-on. */ - private String description; - - /** The authors of the add-on. */ - private final List authors = new ArrayList<>(); - - /** Whether to create events. */ - private boolean createEvents; - - /** Whether to create slash commands. */ - private boolean createSlashCommands; - - /** Whether to create MTS properties. */ - private boolean createMTSProperties; - - /** Whether to create UDFs. (not yet implemented) */ - private boolean createUDFs; - - /** - * Sets the name of the add-on. - * - * @param name the name of the add-on - * @return this builder. - */ - public NewAddOnBuilder setName(String name) { - this.name = name; - return this; - } - - /** - * Sets the version of the add-on. - * - * @param version the version of the add-on - * @return this builder. - */ - public NewAddOnBuilder setVersion(String version) { - this.version = version; - return this; - } - - /** - * Sets the namespace of the add-on. - * - * @param namespace the namespace of the add-on - * @return this builder. - */ - public NewAddOnBuilder setNamespace(String namespace) { - this.namespace = namespace; - return this; - } - - /** - * Sets the git URL of the add-on. - * - * @param gitURL the git URL of the add-on - * @return this builder. - */ - public NewAddOnBuilder setGitURL(String gitURL) { - this.gitURL = gitURL; - return this; - } - - /** - * Sets the website of the add-on. - * - * @param website the website of the add-on - * @return this builder. - */ - public NewAddOnBuilder setWebsite(String website) { - this.website = website; - return this; - } - - /** - * Sets the license of the add-on. - * - * @param license the license of the add-on - * @return this builder. - */ - public NewAddOnBuilder setLicense(String license) { - this.license = license; - return this; - } - - /** - * Sets the short description of the add-on. - * - * @param shortDescription the short description of the add-on - * @return this builder. - */ - public NewAddOnBuilder setShortDescription(String shortDescription) { - this.shortDescription = shortDescription; - return this; - } - - /** - * Sets the description of the add-on. - * - * @param description the description of the add-on - * @return this builder. - */ - public NewAddOnBuilder setDescription(String description) { - this.description = description; - return this; - } - - /** - * Sets the authors of the add-on. - * - * @param authors the authors of the add-on - * @return this builder. - */ - public NewAddOnBuilder setAuthors(List authors) { - this.authors.clear(); - this.authors.addAll(authors); - return this; - } - - /** - * Sets whether to create events. - * - * @param events whether to create events. - * @return this builder. - */ - public NewAddOnBuilder setCreateEvents(boolean events) { - this.createEvents = events; - return this; - } - - /** - * Sets whether to create slash commands. - * - * @param slashCommands whether to create slash commands. - * @return this builder. - */ - public NewAddOnBuilder setCreateSlashCommands(boolean slashCommands) { - this.createSlashCommands = slashCommands; - return this; - } - - /** - * Sets whether to create MTS properties. - * - * @param mtsProperties whether to create MTS properties. - * @return this builder. - */ - public NewAddOnBuilder setCreateMTSProperties(boolean mtsProperties) { - this.createMTSProperties = mtsProperties; - return this; - } - - /** - * Sets whether to create UDFs. - * - * @param udfs whether to create UDFs. - * @return this builder. - */ - public NewAddOnBuilder setCreateUDFs(boolean udfs) { - this.createUDFs = udfs; - return this; - } - - /** - * Builds a new {@link NewAddOn} from the current state of the builder. - * - * @return a new {@link NewAddOn}. - */ - public NewAddOn build() { - return new NewAddOn( - name, - version, - namespace, - gitURL, - website, - license, - shortDescription, - description, - authors, - createEvents, - createSlashCommands, - createMTSProperties, - createUDFs, - getReadMe(), - getLicenseText()); - } - - /** - * Gets the default README text. - * - * @return the default README text. - */ - private String getReadMe() { - return I18N.getText("library.dialog.addon.create.readeMe"); - } - - /** - * Gets the default license text. - * - * @return the default license text. - */ - private String getLicenseText() { - return I18N.getText("library.dialog.addon.create.licenseText"); - } -} diff --git a/src/main/java/net/rptools/maptool/client/ui/addon/creator/NewAddOnCreator.java b/src/main/java/net/rptools/maptool/client/ui/addon/creator/NewAddOnCreator.java deleted file mode 100644 index 25054c2955..0000000000 --- a/src/main/java/net/rptools/maptool/client/ui/addon/creator/NewAddOnCreator.java +++ /dev/null @@ -1,335 +0,0 @@ -/* - * This software Copyright by the RPTools.net development team, and - * licensed under the Affero GPL Version 3 or, at your option, any later - * version. - * - * MapTool Source Code 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. - * - * You should have received a copy of the GNU Affero General Public - * License * along with this source Code. If not, please visit - * and specifically the Affero license - * text at . - */ -package net.rptools.maptool.client.ui.addon.creator; - -import com.google.protobuf.util.JsonFormat; -import java.io.FileNotFoundException; -import java.io.FileWriter; -import java.io.IOException; -import java.io.PrintWriter; -import java.nio.file.Path; -import net.rptools.maptool.language.I18N; -import net.rptools.maptool.model.library.addon.AddOnLibrary; -import net.rptools.maptool.model.library.addon.AddOnLibraryImporter; -import net.rptools.maptool.model.library.proto.AddOnLibraryDto; -import net.rptools.maptool.model.library.proto.AddOnLibraryEventsDto; -import net.rptools.maptool.model.library.proto.AddonSlashCommandsDto; -import net.rptools.maptool.model.library.proto.AddonSlashCommandsDto.AddOnSlashCommand; -import net.rptools.maptool.model.library.proto.MTScriptPropertiesDto; - -/** Creates a new add-on directory structure and files. */ -public class NewAddOnCreator { - - /** The name of the README file. */ - private static final String README_FILE = "README.md"; - - /** The name of the LICENSE file. */ - private static final String LICENSE_FILE = "license.txt"; - - /** The add-on to create. */ - private final NewAddOn addOn; - - /** The path to the add-on directory. */ - private final Path addOnPath; - - /** The path to the library directory. */ - private final Path libraryPath; - - /** The path to the mtscript directory. */ - private final Path mtscriptPath; - - /** The path to the public directory. */ - private final Path publicPath; - - /** The path to the mtscript public directory. */ - private final Path mtscriptPublicPath; - - private static final String AUTO_EXEC_EXAMPLE_MACRO = "public/auto_exec.mts"; - private static final String NON_AUTO_EXEC_EXAMPLE_MACRO = "public/non_auto_exec.mts"; - private static final String SLASH_COMMAND_EXAMPLE_MACRO = "testSlash.mts"; - private static final String ON_FIRST_INIT_EXAMPLE_MACRO = "onFirstInit.mts"; - private static final String ON_INIT_EXAMPLE_MACRO = "onInit.mts"; - private static final String ON_INITIATIVE_CHANGE_REQUEST_EXAMPLE_MACRO = - "onInitiativeChangeRequest.mts"; - private static final String ON_INITIATIVE_CHANGE_EXAMPLE_MACRO = "onInitiativeChange.mts"; - private static final String ON_TOKEN_MOVE_EXAMPLE_MACRO = "onTokenMove.mts"; - private static final String ON_MULTIPLE_TOKENS_MOVE_EXAMPLE_MACRO = "onMultipleTokensMove.mts"; - - /** - * Creates a new add-on creator. - * - * @param newAddOn the add-on to create. - * @param path the path to the add-on directory which will be created. - */ - public NewAddOnCreator(NewAddOn newAddOn, Path path) { - addOn = newAddOn; - addOnPath = path; - libraryPath = path.resolve(AddOnLibraryImporter.CONTENT_DIRECTORY); - mtscriptPath = libraryPath.resolve(AddOnLibrary.MTSCRIPT_DIR); - publicPath = libraryPath.resolve(AddOnLibrary.URL_PUBLIC_DIR); - mtscriptPublicPath = mtscriptPath.resolve(AddOnLibrary.MTSCRIPT_PUBLIC_DIR); - } - - /** - * Creates the add-on directory structure and files. - * - * @throws IOException if an error occurs creating the directory or files. - */ - public void create() throws IOException { - createAddOnDirectories(); - createLibraryFile(); - - if (addOn.createEvents()) { - createEvents(); - } - - if (addOn.createSlashCommands()) { - createSlashCommands(); - } - if (addOn.createMTSProperties()) { - createMTSProperties(); - } - createReadmeFile(); - createLicenseFile(); - } - - /** - * Creates the README file. - * - * @throws IOException if an error occurs creating the file. - */ - private void createLicenseFile() throws IOException { - try { - var licensePath = addOnPath.resolve(LICENSE_FILE); - var writer = new FileWriter(licensePath.toFile()); - writer.write(addOn.licenseText()); - writer.close(); - } catch (IOException e) { - throw new IOException(I18N.getText("library.dialog.failedToCreateFile", LICENSE_FILE), e); - } - } - - /** - * Creates the README file. - * - * @throws IOException if an error occurs creating the file. - */ - private void createReadmeFile() throws IOException { - try { - var readmePath = addOnPath.resolve(README_FILE); - var writer = new FileWriter(readmePath.toFile()); - writer.write(addOn.readme()); - writer.close(); - } catch (IOException e) { - throw new IOException(I18N.getText("library.dialog.failedToCreateFile", README_FILE), e); - } - } - - /** - * Creates the MTS properties file. - * - * @throws IOException if an error occurs creating the file. - */ - private void createMTSProperties() throws IOException { - var builder = MTScriptPropertiesDto.newBuilder(); - var propertiesBuilderAutoExec = MTScriptPropertiesDto.Property.newBuilder(); - propertiesBuilderAutoExec.setFilename(AUTO_EXEC_EXAMPLE_MACRO); - propertiesBuilderAutoExec.setAutoExecute(true); - propertiesBuilderAutoExec.setDescription(I18N.getText("library.dialog.create.autoExecDesc")); - - var propertiesBuilderNoAutoExec = MTScriptPropertiesDto.Property.newBuilder(); - propertiesBuilderNoAutoExec.setFilename(NON_AUTO_EXEC_EXAMPLE_MACRO); - propertiesBuilderNoAutoExec.setAutoExecute(false); - propertiesBuilderNoAutoExec.setDescription( - I18N.getText("library.dialog.create.noAutoExecDesc")); - - builder.addProperties(propertiesBuilderAutoExec); - builder.addProperties(propertiesBuilderNoAutoExec); - - try { - var mtsPropertiesPath = addOnPath.resolve(AddOnLibraryImporter.MACROSCRIPT_PROPERTY_FILE); - var writer = new FileWriter(mtsPropertiesPath.toFile()); - writer.write(JsonFormat.printer().print(builder)); - writer.close(); - } catch (IOException e) { - throw new IOException( - I18N.getText( - "library.dialog.failedToCreateFile", AddOnLibraryImporter.MACROSCRIPT_PROPERTY_FILE), - e); - } - writeMacro(mtscriptPath.resolve(AUTO_EXEC_EXAMPLE_MACRO)); - writeMacro(mtscriptPath.resolve(NON_AUTO_EXEC_EXAMPLE_MACRO)); - } - - /** - * Creates the slash commands file. - * - * @throws IOException if an error occurs creating the file. - */ - private void createSlashCommands() throws IOException { - var builder = AddonSlashCommandsDto.newBuilder(); - var slashCommandBuilder = AddOnSlashCommand.newBuilder(); - slashCommandBuilder.setName("exampleSlash"); - slashCommandBuilder.setDescription(I18N.getText("library.dialog.create.exampleSlashCmdDesc")); - slashCommandBuilder.setCommand(SLASH_COMMAND_EXAMPLE_MACRO); - builder.addSlashCommands(slashCommandBuilder); - - try { - var slashCommandPath = addOnPath.resolve(AddOnLibraryImporter.SLASH_COMMAND_FILE); - var writer = new FileWriter(slashCommandPath.toFile()); - writer.write(JsonFormat.printer().print(builder)); - writer.close(); - } catch (IOException e) { - throw new IOException( - I18N.getText( - "library.dialog.failedToCreateFile", AddOnLibraryImporter.SLASH_COMMAND_FILE), - e); - } - - writeMacro(mtscriptPath.resolve(SLASH_COMMAND_EXAMPLE_MACRO)); - } - - /** - * Creates the events file. - * - * @throws IOException if an error occurs creating the file. - */ - private void createEvents() throws IOException { - // Add init events - var builder = AddOnLibraryEventsDto.newBuilder(); - var onFirstInitMTSBuilder = AddOnLibraryEventsDto.Events.newBuilder(); - onFirstInitMTSBuilder.setName("onFirstInit"); - onFirstInitMTSBuilder.setMts(ON_FIRST_INIT_EXAMPLE_MACRO); - builder.addEvents(onFirstInitMTSBuilder); - var onInitMTSBuilder = AddOnLibraryEventsDto.Events.newBuilder(); - onInitMTSBuilder.setName("onInit"); - onInitMTSBuilder.setMts(ON_INIT_EXAMPLE_MACRO); - builder.addEvents(onInitMTSBuilder); - - // Add legacy events - var legacyEventsBuilder = AddOnLibraryEventsDto.newBuilder(); - var onInitiativeChangeRequestBuilder = AddOnLibraryEventsDto.Events.newBuilder(); - onInitiativeChangeRequestBuilder.setName("onInitiativeChangeRequest"); - onInitiativeChangeRequestBuilder.setMts(ON_INITIATIVE_CHANGE_REQUEST_EXAMPLE_MACRO); - var onInitiativeChangeBuilder = AddOnLibraryEventsDto.Events.newBuilder(); - onInitiativeChangeBuilder.setName("onInitiativeChange"); - onInitiativeChangeBuilder.setMts(ON_INITIATIVE_CHANGE_EXAMPLE_MACRO); - legacyEventsBuilder.addLegacyEvents(onInitiativeChangeBuilder); - var onTokenMoveBuilder = AddOnLibraryEventsDto.Events.newBuilder(); - onTokenMoveBuilder.setName("onTokenMove"); - onTokenMoveBuilder.setMts(ON_TOKEN_MOVE_EXAMPLE_MACRO); - legacyEventsBuilder.addLegacyEvents(onTokenMoveBuilder); - var onMultipleTokensMoveBuilder = AddOnLibraryEventsDto.Events.newBuilder(); - onMultipleTokensMoveBuilder.setName("onMultipleTokensMove"); - onMultipleTokensMoveBuilder.setMts(ON_MULTIPLE_TOKENS_MOVE_EXAMPLE_MACRO); - legacyEventsBuilder.addLegacyEvents(onMultipleTokensMoveBuilder); - - // Add events to builder - builder.addAllEvents(legacyEventsBuilder.getLegacyEventsList()); - try { - var eventsPath = addOnPath.resolve(AddOnLibraryImporter.EVENT_PROPERTY_FILE); - var writer = new FileWriter(eventsPath.toFile()); - writer.write(JsonFormat.printer().print(builder)); - writer.close(); - } catch (IOException e) { - throw new IOException( - I18N.getText( - "library.dialog.failedToCreateFile", AddOnLibraryImporter.EVENT_PROPERTY_FILE), - e); - } - - writeMacro(mtscriptPath.resolve(ON_FIRST_INIT_EXAMPLE_MACRO)); - writeMacro(mtscriptPath.resolve(ON_INIT_EXAMPLE_MACRO)); - writeMacro(mtscriptPath.resolve(ON_INITIATIVE_CHANGE_REQUEST_EXAMPLE_MACRO)); - writeMacro(mtscriptPath.resolve(ON_INITIATIVE_CHANGE_EXAMPLE_MACRO)); - writeMacro(mtscriptPath.resolve(ON_TOKEN_MOVE_EXAMPLE_MACRO)); - writeMacro(mtscriptPath.resolve(ON_MULTIPLE_TOKENS_MOVE_EXAMPLE_MACRO)); - } - - /** - * Creates the library file. - * - * @throws IOException if an error occurs creating the file. - */ - private void createLibraryFile() throws IOException { - var builder = AddOnLibraryDto.newBuilder(); - builder.setName(addOn.name()); - builder.setVersion(addOn.version()); - builder.setNamespace(addOn.namespace()); - builder.addAllAuthors(addOn.authors()); - if (addOn.gitURL() != null && !addOn.gitURL().isEmpty()) { - builder.setGitUrl(addOn.gitURL()); - } - if (addOn.website() != null && !addOn.website().isEmpty()) { - builder.setWebsite(addOn.website()); - } - if (addOn.license() != null && !addOn.license().isEmpty()) { - builder.setLicense(addOn.license()); - } - builder.setShortDescription(addOn.shortDescription()); - builder.setDescription(addOn.description()); - builder.setLicenseFile(LICENSE_FILE); - builder.setReadMeFile(README_FILE); - try { - var libraryInfoPath = addOnPath.resolve(AddOnLibraryImporter.LIBRARY_INFO_FILE); - var writer = new FileWriter(libraryInfoPath.toFile()); - writer.write(JsonFormat.printer().includingDefaultValueFields().print(builder)); - writer.close(); - } catch (IOException e) { - throw new IOException( - I18N.getText("library.dialog.failedToCreateFile", AddOnLibraryImporter.LIBRARY_INFO_FILE), - e); - } - } - - /** - * Creates the add-on directories. - * - * @throws IOException if an error occurs creating the directories. - */ - private void createAddOnDirectories() throws IOException { - createAddOnDirectory(addOnPath); - createAddOnDirectory(libraryPath); - createAddOnDirectory(mtscriptPath); - createAddOnDirectory(mtscriptPublicPath); - createAddOnDirectory(publicPath); - } - - /** - * Creates a new directory. - * - * @param path the path to the directory to create. - * @throws IOException if an error occurs creating the directory.. - */ - private void createAddOnDirectory(Path path) throws IOException { - if (!path.toFile().mkdirs()) { - throw new IOException(I18N.getText("library.dialog.failedToCreateDir", path.toString())); - } - } - - /** - * Write an example macro to the given path. - * - * @param path the path to write the macro to (including filename) - */ - private void writeMacro(Path path) throws FileNotFoundException { - var filename = path.getFileName().toString(); - var comment = I18N.getText("library.dialog.addon.create.mtsComment", filename); - try (var writer = new PrintWriter(path.toFile())) { - writer.println(""); - writer.println("[h: broadcast('" + filename + "')] "); - } - } -} diff --git a/src/main/java/net/rptools/maptool/client/ui/campaignproperties/CampaignPropertiesDialog.java b/src/main/java/net/rptools/maptool/client/ui/campaignproperties/CampaignPropertiesDialog.java index a7e815c597..4f6aa5dd51 100644 --- a/src/main/java/net/rptools/maptool/client/ui/campaignproperties/CampaignPropertiesDialog.java +++ b/src/main/java/net/rptools/maptool/client/ui/campaignproperties/CampaignPropertiesDialog.java @@ -454,9 +454,8 @@ private void initExportButton() { JOptionPane.INFORMATION_MESSAGE); CampaignPropertiesDto campaignPropertiesDto = MapTool.getCampaign().getCampaignProperties().toDto(); - try (FileOutputStream fos = new FileOutputStream(chooser.getSelectedFile())) { - fos.write(JsonFormat.printer().print(campaignPropertiesDto).getBytes()); - } + FileOutputStream fos = new FileOutputStream(chooser.getSelectedFile()); + fos.write(JsonFormat.printer().print(campaignPropertiesDto).getBytes()); } } catch (IOException ioe) { diff --git a/src/main/java/net/rptools/maptool/model/library/ExternalAddonsUpdateEvent.java b/src/main/java/net/rptools/maptool/model/library/ExternalAddonsUpdateEvent.java deleted file mode 100644 index f0cdfcbbfb..0000000000 --- a/src/main/java/net/rptools/maptool/model/library/ExternalAddonsUpdateEvent.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * This software Copyright by the RPTools.net development team, and - * licensed under the Affero GPL Version 3 or, at your option, any later - * version. - * - * MapTool Source Code 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. - * - * You should have received a copy of the GNU Affero General Public - * License * along with this source Code. If not, please visit - * and specifically the Affero license - * text at . - */ -package net.rptools.maptool.model.library; - -/** Event that is fired when the list of external addons is updated. */ -public record ExternalAddonsUpdateEvent() {} diff --git a/src/main/java/net/rptools/maptool/model/library/LibraryManager.java b/src/main/java/net/rptools/maptool/model/library/LibraryManager.java index f9624e356d..f5507f78d3 100644 --- a/src/main/java/net/rptools/maptool/model/library/LibraryManager.java +++ b/src/main/java/net/rptools/maptool/model/library/LibraryManager.java @@ -14,9 +14,7 @@ */ package net.rptools.maptool.model.library; -import java.io.IOException; import java.net.URL; -import java.nio.file.Path; import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -28,7 +26,11 @@ import net.rptools.maptool.client.MapTool; import net.rptools.maptool.client.MapToolMacroContext; import net.rptools.maptool.events.MapToolEventBus; -import net.rptools.maptool.model.library.addon.*; +import net.rptools.maptool.model.library.addon.AddOnLibrary; +import net.rptools.maptool.model.library.addon.AddOnLibraryData; +import net.rptools.maptool.model.library.addon.AddOnLibraryManager; +import net.rptools.maptool.model.library.addon.AddOnSlashCommandManager; +import net.rptools.maptool.model.library.addon.TransferableAddOnLibrary; import net.rptools.maptool.model.library.builtin.BuiltInLibraryManager; import net.rptools.maptool.model.library.proto.AddOnLibraryListDto; import net.rptools.maptool.model.library.token.LibraryTokenManager; @@ -72,63 +74,12 @@ public class LibraryManager { private static final AddOnSlashCommandManager addOnSlashCommandManager = new AddOnSlashCommandManager(); - /** - * Initializes the library manager. This method should be called after instantiation of the - * library manager. - */ public static void init() { libraryTokenManager.init(); builtInLibraryManager.loadBuiltIns(); - addOnLibraryManager.init(); new MapToolEventBus().getMainEventBus().register(addOnSlashCommandManager); } - /** - * Returns the list of external add-on libraries. - * - * @return the list of external add-on libraries. - */ - public List getExternalAddOnLibraries() { - return addOnLibraryManager.getExternalAddOnLibraries(); - } - - /** - * Returns if external add-on libraries are enabled. - * - * @return if external add-on libraries are enabled. - */ - public boolean externalLibrariesEnabled() { - return addOnLibraryManager.externalLibrariesEnabled(); - } - - /** - * Sets if external add-on libraries are enabled. - * - * @param enabled if external add-on libraries are enabled. - */ - public void setExternalLibrariesEnabled(boolean enabled) throws IOException { - addOnLibraryManager.setExternalLibrariesEnabled(enabled); - } - - /** - * Returns the path to the external add-on libraries. - * - * @return the path to the external add-on libraries. - */ - public Path getEternalLibraryPath() { - return addOnLibraryManager.getExternalLibraryPath(); - } - - /** - * Sets the path to the external add-on libraries. - * - * @param path the path to the external add-on libraries. - * @throws IOException if an error occurs while setting the path. - */ - public void setExternalLibraryPath(Path path) throws IOException { - addOnLibraryManager.setExternalLibraryPath(path); - } - /** * Checks to see if this library name used a reserved prefix. * @@ -210,7 +161,7 @@ public boolean addOnLibraryExists(String namespace) { /** * Register and add-on library. * - * @param addOn the Add-On to register. + * @param addOn the Add On to register. */ public boolean registerAddOnLibrary(AddOnLibrary addOn) { try { @@ -226,8 +177,7 @@ public boolean registerAddOnLibrary(AddOnLibrary addOn) { } /** - * Deregister the add-on in library associated with the specified namespace. This will deregister - * the add-on if it is external. + * Deregister the add-on in library associated with the specified namespace. * * @param namespace the namespace to deregister. */ @@ -239,7 +189,7 @@ public void deregisterAddOnLibrary(String namespace) { } /** - * Register an add-on in library, replacing any existing library. + * Register a add-on in library, replacing any existing library. * * @param addOnLibrary the add-on in library to register. */ @@ -258,30 +208,6 @@ public boolean reregisterAddOnLibrary(AddOnLibrary addOnLibrary) { return true; } - /** - * Register an add-on as an external add-on. This will not make the add-on available to - * MapTool. To make the add-on available to MapTool, use {@link #importFromExternal(String)} - * - * @param path The path of the add-on to register. - * @throws IOException if an error occurs while registering the add-on. - */ - public void registerExternalAddOnLibrary(Path path) throws IOException { - addOnLibraryManager.registerExternalLibrary(path); - } - - /** - * Import an add-on from an external source. This will make the add-on available to MapTool. - * Importing an updated version of an add-on will replace the existing add-on. - * - * @param namespace The namespace of the add-on to import. - */ - public void importFromExternal(String namespace) throws IOException { - if (addOnLibraryManager.namespaceRegistered(namespace)) { - addOnLibraryManager.deregisterLibrary(namespace); - } - addOnLibraryManager.importFromExternal(namespace); - } - /** * Returns a list of information about the registered libraries. * @@ -415,7 +341,6 @@ public void removeAddOnLibrary(String namespace) { * initialization next time they are added. */ public void removeAddOnLibraries() { - for (var lib : addOnLibraryManager.getLibraries()) { lib.getLibraryData() .thenAccept( diff --git a/src/main/java/net/rptools/maptool/model/library/addon/AddOnLibrary.java b/src/main/java/net/rptools/maptool/model/library/addon/AddOnLibrary.java index 9d2264c417..a24ad46892 100644 --- a/src/main/java/net/rptools/maptool/model/library/addon/AddOnLibrary.java +++ b/src/main/java/net/rptools/maptool/model/library/addon/AddOnLibrary.java @@ -19,7 +19,6 @@ import java.io.InputStream; import java.net.URI; import java.net.URL; -import java.nio.file.Path; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -68,10 +67,10 @@ public class AddOnLibrary implements Library { /** The name of the event for first time initialization. */ - public static final String FIRST_INIT_EVENT = "onFirstInit"; + private static final String FIRST_INIT_EVENT = "onFirstInit"; /** The name of the event for initialization. */ - public static final String INIT_EVENT = "onInit"; + private static final String INIT_EVENT = "onInit"; /** The prefix for the name of the JavaScript context for this addon. */ private static final String JS_CONTEXT_PREFIX = "addon:"; @@ -80,13 +79,13 @@ public class AddOnLibrary implements Library { private record MTScript(String path, boolean autoExecute, String description, MD5Key md5Key) {} /** The directory where the files exposed URI are stored. */ - public static final String URL_PUBLIC_DIR = "public/"; + private static final String URL_PUBLIC_DIR = "public/"; /** The directory where MT MacroScripts are stored. */ - public static final String MTSCRIPT_DIR = "mtscript/"; + private static final String MTSCRIPT_DIR = "mtscript/"; /** The directory where public MT MacroScripts are stored. */ - public static final String MTSCRIPT_PUBLIC_DIR = "public/"; + private static final String MTSCRIPT_PUBLIC_DIR = "public/"; /** Logger instance for this class. */ private static final Logger logger = LogManager.getLogger(AddOnLibrary.class); @@ -160,12 +159,6 @@ private record MTScript(String path, boolean autoExecute, String description, MD /** The information about the add-on library. */ private final LibraryInfo libraryInfo; - /** - * The directory that the library is in for development mode, or null if the add-on is not in - * development mode. - */ - private final Path backingDirectory; - /** * Class used to represent Drop In Libraries. * @@ -174,8 +167,6 @@ private record MTScript(String path, boolean autoExecute, String description, MD * @param eventsDto The MTScript Events Data Transfer Object. * @param slashCommandsDto The Slash Commands Data Transfer Object. * @param pathAssetMap mapping of paths in the library to {@link MD5Key}s and {@link Type}s. - * @param backingDirectory The directory that the library is in for development mode, or null if - * the add-on is not in development mode. */ private AddOnLibrary( MD5Key libraryAssetKey, @@ -184,8 +175,7 @@ private AddOnLibrary( AddOnLibraryEventsDto eventsDto, AddOnStatSheetsDto statSheetsDto, AddonSlashCommandsDto slashCommandsDto, - Map> pathAssetMap, - Path backingDirectory) { + Map> pathAssetMap) { Objects.requireNonNull(dto, I18N.getText("library.error.invalidDefinition")); name = Objects.requireNonNull(dto.getName(), I18N.getText("library.error.emptyName")); version = @@ -268,8 +258,6 @@ private AddOnLibrary( jsContextName = JS_CONTEXT_PREFIX + namespace; - this.backingDirectory = backingDirectory; - libraryInfo = new LibraryInfo( name, @@ -319,47 +307,7 @@ public static AddOnLibrary fromDto( Map> pathAssetMap) { return new AddOnLibrary( - libraryAssetKey, - dto, - mtsDto, - eventsDto, - statSheetsDto, - slashCommandsDto, - pathAssetMap, - null); - } - - /** - * Creates a new Drop In Library from the given {@link AddOnLibraryDto}, {@link - * MTScriptPropertiesDto}, and file path assets map. - * - * @param dto The Drop In Libraries Data Transfer Object. - * @param mtsDto The MTScript Properties Data Transfer Object. - * @param eventsDto The Events Data Transfer Object. - * @param slashCommandsDto The Slash Commands Data Transfer Object. - * @param pathAssetMap mapping of paths in the library to {@link MD5Key}s and {@link Asset.Type}s. - * @param backingDirectory The directory that the library is in for development mode, or null if - * the add-on is not in development mode. - * @return the new Add on library. - */ - public static AddOnLibrary fromDto( - MD5Key libraryAssetKey, - AddOnLibraryDto dto, - MTScriptPropertiesDto mtsDto, - AddOnLibraryEventsDto eventsDto, - AddOnStatSheetsDto statSheetsDto, - AddonSlashCommandsDto slashCommandsDto, - Map> pathAssetMap, - Path backingDirectory) { - return new AddOnLibrary( - libraryAssetKey, - dto, - mtsDto, - eventsDto, - statSheetsDto, - slashCommandsDto, - pathAssetMap, - backingDirectory); + libraryAssetKey, dto, mtsDto, eventsDto, statSheetsDto, slashCommandsDto, pathAssetMap); } @Override @@ -729,12 +677,6 @@ private void runJS(String file) { .join(); } - /** - * Returns the DataValue for the specified path in the add-on library. - * - * @param path the path to the file to read. - * @return the DataValue for the specified path in the add-on library. - */ CompletableFuture readFile(String path) { return CompletableFuture.supplyAsync( () -> { @@ -747,24 +689,4 @@ CompletableFuture readFile(String path) { return DataValueFactory.fromAsset(filePath, asset); }); } - - /** - * Returns if the add-on library is in development mode or not. - * - * @return true if the add-on library is in development mode, false - * otherwise. - */ - public boolean isInDevelopmentMode() { - return backingDirectory != null; - } - - /** - * Returns the directory that the library is in for development mode, or null if the add-on is not - * in development mode. - * - * @return the directory for the add-on. - */ - public Path getBackingDirectory() { - return backingDirectory; - } } diff --git a/src/main/java/net/rptools/maptool/model/library/addon/AddOnLibraryImporter.java b/src/main/java/net/rptools/maptool/model/library/addon/AddOnLibraryImporter.java index 1eb0d30626..e0b66d3cb4 100644 --- a/src/main/java/net/rptools/maptool/model/library/addon/AddOnLibraryImporter.java +++ b/src/main/java/net/rptools/maptool/model/library/addon/AddOnLibraryImporter.java @@ -21,27 +21,21 @@ import java.io.InputStreamReader; import java.io.OutputStream; import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardOpenOption; import java.util.HashMap; import java.util.Map; -import java.util.stream.Collectors; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; -import java.util.zip.ZipOutputStream; import javax.swing.filechooser.FileFilter; import net.rptools.lib.MD5Key; import net.rptools.maptool.language.I18N; import net.rptools.maptool.model.Asset; import net.rptools.maptool.model.Asset.Type; import net.rptools.maptool.model.AssetManager; -import net.rptools.maptool.model.library.LibraryInfo; import net.rptools.maptool.model.library.proto.AddOnLibraryDto; import net.rptools.maptool.model.library.proto.AddOnLibraryEventsDto; import net.rptools.maptool.model.library.proto.AddOnStatSheetsDto; import net.rptools.maptool.model.library.proto.AddonSlashCommandsDto; import net.rptools.maptool.model.library.proto.MTScriptPropertiesDto; -import net.rptools.maptool.util.FileUtil; import org.apache.tika.mime.MediaType; import org.javatuples.Pair; @@ -141,128 +135,6 @@ public AddOnLibrary importFromAsset(Asset asset) throws IOException { return importFromFile(tempFile); } - /** - * Imports the {@link LibraryInfo} from the specified directory. If the {@code LIBRARY_INFO_FILE} - * does not exist in this directory then null will be returned. - * - * @param dir The directory to import the library info from. - * @return the {@link LibraryInfo} that was imported, {@code null} if the library info file does - * not exist. - * @throws IOException if an error occurs while reading the library. - */ - public LibraryInfo getLibraryInfoFromDirectory(Path dir) throws IOException { - var infoPath = dir.resolve(LIBRARY_INFO_FILE).toAbsolutePath(); - if (!Files.exists(infoPath)) { - return null; - } - - var builder = AddOnLibraryDto.newBuilder(); - JsonFormat.parser().ignoringUnknownFields().merge(Files.newBufferedReader(infoPath), builder); - - return new LibraryInfo( - builder.getName(), - builder.getNamespace(), - builder.getVersion(), - builder.getWebsite(), - builder.getGitUrl(), - builder.getAuthorsList().toArray(new String[0]), - builder.getLicense(), - builder.getDescription(), - builder.getShortDescription(), - builder.getAllowsUriAccess(), - builder.getReadMeFile(), - builder.getLicenseFile()); - } - - /** - * Imports the add-on library from the specified directory - * - * @param dir the directory to import the library from. - * @return the {@link AddOnLibrary} that was imported. - * @throws IOException if an error occurs while reading the library. - */ - public AddOnLibrary importFromDirectory(Path dir) throws IOException { - - var infoPath = dir.resolve(LIBRARY_INFO_FILE); - if (!Files.exists(infoPath)) { - throw new IOException(I18N.getText("library.error.addOn.noConfigFile", dir)); - } - - var builder = AddOnLibraryDto.newBuilder(); - JsonFormat.parser().ignoringUnknownFields().merge(Files.newBufferedReader(infoPath), builder); - - var pathAssetMap = processAssetsFromDirectory(builder.getNamespace(), dir); - - var mtsPropBuilder = MTScriptPropertiesDto.newBuilder(); - var mtsPropPath = dir.resolve(MACROSCRIPT_PROPERTY_FILE); - if (Files.exists(mtsPropPath)) - JsonFormat.parser() - .ignoringUnknownFields() - .merge(Files.newBufferedReader(mtsPropPath), mtsPropBuilder); - - var eventPropBuilder = AddOnLibraryEventsDto.newBuilder(); - var eventPropPath = dir.resolve(EVENT_PROPERTY_FILE); - if (Files.exists(eventPropPath)) - JsonFormat.parser() - .ignoringUnknownFields() - .merge(Files.newBufferedReader(eventPropPath), eventPropBuilder); - - var statSheetsBuilder = AddOnStatSheetsDto.newBuilder(); - var statSheetsPath = dir.resolve(STATS_SHEET_FILE); - if (Files.exists(statSheetsPath)) - JsonFormat.parser() - .ignoringUnknownFields() - .merge(Files.newBufferedReader(statSheetsPath), statSheetsBuilder); - - var slashCommandsBuilder = AddonSlashCommandsDto.newBuilder(); - var slashCommandsPath = dir.resolve(SLASH_COMMAND_FILE); - if (Files.exists(slashCommandsPath)) - JsonFormat.parser() - .ignoringUnknownFields() - .merge(Files.newBufferedReader(slashCommandsPath), slashCommandsBuilder); - - addMetaDataFromDirectory(builder.getNamespace(), dir, pathAssetMap); - - // Directory assets must be zipped up. When external add-on libraries are sent to remotes, - // they should act as normal add-on libraries. - var addOnLib = builder.build(); - - var zipPath = Files.createTempFile(builder.getNamespace(), null); - try (var zipOut = - new ZipOutputStream(Files.newOutputStream(zipPath, StandardOpenOption.WRITE))) { - var paths = - pathAssetMap.keySet().stream() - .map( - path -> { - if (path.startsWith(METADATA_DIR)) return path.substring(METADATA_DIR.length()); - return CONTENT_DIRECTORY + path; - }) - .collect(Collectors.toSet()); - - for (var pathString : paths) { - zipOut.putNextEntry(new ZipEntry(pathString)); - var p = dir.resolve(pathString); - if (Files.isRegularFile(p)) zipOut.write(Files.readAllBytes(p)); - zipOut.closeEntry(); - } - } - - var data = Files.readAllBytes(zipPath); - Files.delete(zipPath); - - var asset = Type.MTLIB.getFactory().apply(addOnLib.getNamespace(), data); - addAsset(asset); - - return AddOnLibrary.fromDto( - asset.getMD5Key(), - addOnLib, - mtsPropBuilder.build(), - eventPropBuilder.build(), - statSheetsBuilder.build(), - slashCommandsBuilder.build(), - pathAssetMap); - } - /** * Imports the add-on library from the specified file. * @@ -271,6 +143,7 @@ public AddOnLibrary importFromDirectory(Path dir) throws IOException { * @throws IOException if an error occurs while reading the asset. */ public AddOnLibrary importFromFile(File file) throws IOException { + var diiBuilder = AddOnLibraryDto.newBuilder(); try (var zip = new ZipFile(file)) { ZipEntry entry = zip.getEntry(LIBRARY_INFO_FILE); @@ -283,7 +156,7 @@ public AddOnLibrary importFromFile(File file) throws IOException { .merge(new InputStreamReader(zip.getInputStream(entry)), builder); // MT MacroScript properties - var pathAssetMap = processAssetsFromZip(builder.getNamespace(), zip); + var pathAssetMap = processAssets(builder.getNamespace(), zip); var mtsPropBuilder = MTScriptPropertiesDto.newBuilder(); ZipEntry mtsPropsZipEntry = zip.getEntry(MACROSCRIPT_PROPERTY_FILE); if (mtsPropsZipEntry != null) { @@ -322,7 +195,7 @@ public AddOnLibrary importFromFile(File file) throws IOException { } // Copy Metadata - addMetaDataFromZip(builder.getNamespace(), zip, pathAssetMap); + addMetaData(builder.getNamespace(), zip, pathAssetMap); var addOnLib = builder.build(); byte[] data = Files.readAllBytes(file.toPath()); @@ -367,7 +240,7 @@ public AddOnLibrary importFromClassPath(String path) throws IOException { * @param pathAssetMap the map of asset paths and asset details. * @throws IOException */ - private void addMetaDataFromZip( + private void addMetaData( String namespace, ZipFile zip, Map> pathAssetMap) throws IOException { var entries = zip.stream().filter(e -> !e.getName().contains("/")).toList(); @@ -384,29 +257,6 @@ private void addMetaDataFromZip( } } - /** - * Adds the metadata from the add-on directory to the metadata directory. - * - * @param namespace The namespace of the add-on. - * @param dir The directory of the add-on. - * @param pathAssetMap The asset details output. - * @throws IOException If there is an error reading assets from the directory. - */ - private void addMetaDataFromDirectory( - String namespace, Path dir, Map> pathAssetMap) throws IOException { - var entries = Files.list(dir).filter(p -> !Files.isDirectory(p)).collect(Collectors.toSet()); - for (var entry : entries) { - var path = METADATA_DIR + entry.getFileName().toString(); - var bytes = Files.readAllBytes(entry); - - var mediaType = Asset.getMediaType(entry.getFileName().toString(), bytes); - - var asset = Type.fromMediaType(mediaType).getFactory().apply(namespace + "/" + path, bytes); - addAsset(asset); - pathAssetMap.put(path, Pair.with(asset.getMD5Key(), asset.getType())); - } - } - /** * Reads the assets from the add-on library and adds them to the asset manager. * @@ -415,7 +265,7 @@ private void addMetaDataFromDirectory( * @return a map of asset paths and asset details. * @throws IOException if there is an error reading the assets from the add-on library. */ - private Map> processAssetsFromZip(String namespace, ZipFile zip) + private Map> processAssets(String namespace, ZipFile zip) throws IOException { var pathAssetMap = new HashMap>(); var entries = @@ -437,39 +287,6 @@ private Map> processAssetsFromZip(String namespace, Z return pathAssetMap; } - /** - * Reads the assets from a flat directory. This is primarily used for external libraries, such as - * development-mode libraries. - * - * @param namespace The namespace to classify assets under. - * @param dir The directory to process as an add-on. - * @return A map containing asset paths and details. - * @throws IOException If there is an error reading assets from the directory. - */ - private Map> processAssetsFromDirectory(String namespace, Path dir) - throws IOException { - var pathAssetMap = new HashMap>(); - var contentDir = dir.resolve(CONTENT_DIRECTORY); - - // Empty libraries are still permitted. - if (!Files.exists(contentDir)) return pathAssetMap; - - for (Path entry : FileUtil.listRecursively(contentDir).collect(Collectors.toSet())) { - if (Files.isDirectory(entry)) continue; - entry = dir.relativize(entry); - var pathString = entry.toString().substring(CONTENT_DIRECTORY.length()).replace('\\', '/'); - var bytes = Files.readAllBytes(dir.resolve(entry)); - - var mediaType = Asset.getMediaType(entry.toString(), bytes); - - var asset = - Type.fromMediaType(mediaType).getFactory().apply(namespace + "/" + pathString, bytes); - addAsset(asset); - pathAssetMap.put(pathString, Pair.with(asset.getMD5Key(), asset.getType())); - } - return pathAssetMap; - } - /** * Adds the {@link Asset} to the {@link AssetManager} if it does not already exist. * diff --git a/src/main/java/net/rptools/maptool/model/library/addon/AddOnLibraryManager.java b/src/main/java/net/rptools/maptool/model/library/addon/AddOnLibraryManager.java index f233743dc2..5d04309356 100644 --- a/src/main/java/net/rptools/maptool/model/library/addon/AddOnLibraryManager.java +++ b/src/main/java/net/rptools/maptool/model/library/addon/AddOnLibraryManager.java @@ -14,9 +14,7 @@ */ package net.rptools.maptool.model.library.addon; -import java.io.IOException; import java.net.URL; -import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -25,8 +23,6 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; -import net.rptools.maptool.client.AppPreferences; -import net.rptools.maptool.client.MapTool; import net.rptools.maptool.events.MapToolEventBus; import net.rptools.maptool.model.library.AddOnsAddedEvent; import net.rptools.maptool.model.library.AddOnsRemovedEvent; @@ -44,9 +40,6 @@ public class AddOnLibraryManager { /** The add-on libraries that are registered. */ private final Map namespaceLibraryMap = new ConcurrentHashMap<>(); - /** The external add-on library manager. */ - private ExternalAddOnLibraryManager externalAddOnLibraryManager; - /** * Is there a add-on library that would handle this path. This just checks the protocol and * namespace, it won't check that the full path actually exists. @@ -92,16 +85,6 @@ public void registerLibrary(AddOnLibrary library) { .post(new AddOnsAddedEvent(Set.of(library.getLibraryInfo().join()))); } - /** - * Checks to see if the specified namespace is registered. - * - * @param namespace the namespace to check. - * @return {@code true} if the namespace is registered. - */ - public boolean isNamespaceRegistered(String namespace) { - return namespaceLibraryMap.containsKey(namespace.toLowerCase()); - } - /** * Deregister the add-on library with the specified namespace. * @@ -188,7 +171,7 @@ public void removeAllLibraries() { .map(CompletableFuture::join) .collect(Collectors.toSet()); - if (!libs.isEmpty()) { + if (libs.size() > 0) { new MapToolEventBus().getMainEventBus().post(new AddOnsRemovedEvent(libs)); for (var library : namespaceLibraryMap.values()) { library.cleanup(); @@ -210,105 +193,4 @@ public CompletableFuture> getLegacyEventTargets(String eventName) { .filter(l -> l.getLegacyEvents().contains(eventName)) .collect(Collectors.toSet())); } - - /** Initializes the add-on library manager. */ - public void init() { - externalAddOnLibraryManager = new ExternalAddOnLibraryManager(this); - String path = AppPreferences.externalAddOnLibrariesPath.get(); - - try { - externalAddOnLibraryManager.setExternalLibraryPath(Path.of(path)); - externalAddOnLibraryManager.setEnabled(AppPreferences.externalAddOnLibrariesEnabled.get()); - externalAddOnLibraryManager.init(); - } catch (IOException e) { - MapTool.showError("Error setting external library path", e); - try { - externalAddOnLibraryManager.setEnabled(false); - } catch (IOException ex) { - // Do nothing as it shouldn't happen, but if it does there is no action we can take - } - } - } - - /** - * Replaces the add-on library with a newer version. - * - * @param library the library to replace the existing library with. - */ - public void replaceLibrary(AddOnLibrary library) { - library - .getNamespace() - .thenAccept( - namespace -> { - deregisterLibrary(namespace); - registerLibrary(library); - }); - } - - /** - * Returns the information of external add-on libraries that are registered. - * - * @return the information of external add-on libraries that are registered. - */ - public List getExternalAddOnLibraries() { - return externalAddOnLibraryManager.getLibraries(); - } - - /** - * Returns if external add-on libraries are enabled. - * - * @return if external add-on libraries are enabled. - */ - public boolean externalLibrariesEnabled() { - return externalAddOnLibraryManager.isEnabled(); - } - - /** - * Sets if external add-on libraries are enabled. - * - * @param enabled if external add-on libraries are enabled. - * @throws IOException if an I/O error occurs. - */ - public void setExternalLibrariesEnabled(boolean enabled) throws IOException { - externalAddOnLibraryManager.setEnabled(enabled); - } - - /** - * Returns the path to the external add-on libraries. - * - * @return the path to the external add-on libraries. - */ - public Path getExternalLibraryPath() { - return externalAddOnLibraryManager.getExternalLibraryPath(); - } - - /** - * Sets the path to the external add-on libraries. - * - * @param path the path to the external add-on libraries. - * @throws IOException if an I/O error occurs. - */ - public void setExternalLibraryPath(Path path) throws IOException { - externalAddOnLibraryManager.setExternalLibraryPath(path); - } - - /** - * Registers the add-on library as an external library. - * - * @param path The path to the library. - * @throws IOException if an I/O error occurs. - */ - public void registerExternalLibrary(Path path) throws IOException { - externalAddOnLibraryManager.registerExternalAddOnLibrary(path); - } - - /** - * Makes the external library with the given namespace available to MapTool. Importing an existing - * library will replace the existing library. - * - * @param namespace The namespace of the library. - */ - public void importFromExternal(String namespace) throws IOException { - externalAddOnLibraryManager.importLibrary(namespace); - } } diff --git a/src/main/java/net/rptools/maptool/model/library/addon/ExternalAddOnLibraryManager.java b/src/main/java/net/rptools/maptool/model/library/addon/ExternalAddOnLibraryManager.java deleted file mode 100644 index 93804d6bb6..0000000000 --- a/src/main/java/net/rptools/maptool/model/library/addon/ExternalAddOnLibraryManager.java +++ /dev/null @@ -1,435 +0,0 @@ -/* - * This software Copyright by the RPTools.net development team, and - * licensed under the Affero GPL Version 3 or, at your option, any later - * version. - * - * MapTool Source Code 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. - * - * You should have received a copy of the GNU Affero General Public - * License * along with this source Code. If not, please visit - * and specifically the Affero license - * text at . - */ -package net.rptools.maptool.model.library.addon; - -import com.google.common.eventbus.Subscribe; -import io.methvin.watcher.DirectoryWatcher; -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.locks.ReentrantLock; -import net.rptools.maptool.client.MapTool; -import net.rptools.maptool.events.MapToolEventBus; -import net.rptools.maptool.language.I18N; -import net.rptools.maptool.model.library.AddOnsAddedEvent; -import net.rptools.maptool.model.library.AddOnsRemovedEvent; -import net.rptools.maptool.model.library.ExternalAddonsUpdateEvent; -import net.rptools.maptool.model.library.LibraryInfo; - -/** - * Manages the external add-on libraries that are baked by the file system. This manager will watch - * the external add-on library directory for changes and will update the add-on libraries available - * but will not automatically update the add-on libraries that MapTool has loaded. - */ -public class ExternalAddOnLibraryManager { - - /** The add-on library manager that is used to register the external add-on libraries. */ - private final AddOnLibraryManager addOnLibraryManager; - - /** The add-on libraries that are registered. */ - private final Map namespaceInfoMap = new ConcurrentHashMap<>(); - - /** Is the external add-on library manager enabled. */ - private boolean enabled = false; - - /** The path to the external add-on libraries. */ - private Path externalLibraryPath = null; - - /** Is the external add-on library manager initialised. */ - private boolean initialised = false; - - /** Directory watcher for watching the external add-on library directory. */ - private DirectoryWatcher directoryWatcher; - - /** Lock for managing enabled and path states. */ - private final ReentrantLock lock = new ReentrantLock(); - - /** - * Creates a new instance of the external add-on library manager. {@code init()} must be called - * after construction. - * - * @param addOnLibraryManager the add-on library manager used to register the add-on libraries. - */ - public ExternalAddOnLibraryManager(AddOnLibraryManager addOnLibraryManager) { - this.addOnLibraryManager = addOnLibraryManager; - } - - /** - * Initializes the external add-on library manager. It is safe to call {@see - * setExternalLibraryPath(Path)} and {@see setEnabled(boolean)} before calling this method, but no - * directory watching will occur until this method is called. - * - * @throws IOException if an error occurs. - * @throws IllegalStateException if the external add-on library manager has already been - * initialised. - */ - public void init() throws IOException { - try { - lock.lock(); - if (initialised) { - throw new IllegalStateException("External add-on library manager already initialised"); - } - initialised = true; - startWatching(); - } finally { - lock.unlock(); - } - var eventBus = new MapToolEventBus().getMainEventBus(); - eventBus.register(this); - } - - /** - * Handles the event when an add-on library is added to MapTool. - * - * @param event the add-on library that was added to MapTool. - */ - @Subscribe - public void onLibraryAdded(AddOnsAddedEvent event) { - boolean updated = false; - for (LibraryInfo libraryInfo : event.addOns()) { - var namespace = libraryInfo.namespace().toLowerCase(); - if (namespaceInfoMap.containsKey(namespace)) { - var oldInfo = namespaceInfoMap.get(namespace); - var newInfo = - new ExternalLibraryInfo( - namespace, - oldInfo.libraryInfo(), - false, - true, - oldInfo.backingDirectory(), - externalLibraryPath.relativize(oldInfo.backingDirectory()).toString()); - namespaceInfoMap.put(namespace, newInfo); - updated = true; - } - } - if (updated) { - new MapToolEventBus().getMainEventBus().post(new ExternalAddonsUpdateEvent()); - } - } - - /** - * Handles the event when an add-on library is removed from MapTool. - * - * @param event the add-on library that was removed from MapTool. - */ - @Subscribe - public void onLibraryRemoved(AddOnsRemovedEvent event) { - boolean updated = false; - for (LibraryInfo libraryInfo : event.addOns()) { - var namespace = libraryInfo.namespace().toLowerCase(); - if (namespaceInfoMap.containsKey(namespace)) { - var oldInfo = namespaceInfoMap.get(namespace); - var newInfo = - new ExternalLibraryInfo( - namespace, - oldInfo.libraryInfo(), - true, - false, - oldInfo.backingDirectory(), - externalLibraryPath.relativize(oldInfo.backingDirectory()).toString()); - namespaceInfoMap.put(namespace, newInfo); - updated = true; - } - } - if (updated) { - new MapToolEventBus().getMainEventBus().post(new ExternalAddonsUpdateEvent()); - } - } - - /** - * Registers an external add-on library. - * - * @param info Information about the add-on library to register. - */ - private void registerExternalAddOnLibrary(ExternalLibraryInfo info) { - boolean isInstalled = addOnLibraryManager.isNamespaceRegistered(info.namespace()); - var externalInfo = - new ExternalLibraryInfo( - info.namespace(), - info.libraryInfo(), - true, - isInstalled, - info.backingDirectory(), - externalLibraryPath.relativize(info.backingDirectory()).toString()); - namespaceInfoMap.put(info.namespace().toLowerCase(), externalInfo); - } - - /** - * Deregisters an external add-on library. - * - * @param path the backing path of the add-on library to deregister. - */ - public void deregisterExternalAddOnLibrary(Path path) { - namespaceInfoMap.values().stream() - .filter(info -> info.backingDirectory().equals(path)) - .findFirst() - .ifPresent(info -> namespaceInfoMap.remove(info.namespace().toLowerCase())); - var eventBus = new MapToolEventBus().getMainEventBus(); - eventBus.post(new ExternalAddonsUpdateEvent()); - } - - /** - * Refreshes an external add-on library. - * - * @param path the path to the add-on library. - * @throws IOException if an error occurs. - */ - public void refreshExternalAddOnLibrary(Path path) throws IOException { - registerExternalAddOnLibrary(path); // Allows us to change behaviour later without breaking API - } - - /** - * Registers an external add-on library. - * - * @param path the path to the add-on library. - * @throws IOException if an error occurs. - */ - public void registerExternalAddOnLibrary(Path path) throws IOException { - var lib = new AddOnLibraryImporter().getLibraryInfoFromDirectory(path); - if (lib == null) { - return; - } - boolean isInstalled = addOnLibraryManager.isNamespaceRegistered(lib.namespace()); - var info = - new ExternalLibraryInfo( - lib.namespace(), - lib, - false, - isInstalled, - path, - externalLibraryPath.relativize(path).toString()); - registerExternalAddOnLibrary(info); - var eventBus = new MapToolEventBus().getMainEventBus(); - eventBus.post(new ExternalAddonsUpdateEvent()); - } - - /** - * Gets the external libraries that have been registered. - * - * @return the external libraries. - */ - public List getLibraries() { - return new ArrayList<>(namespaceInfoMap.values()); - } - - /** - * Is the external add-on library manager enabled. - * - * @return {@code true} if the external add-on library manager is enabled. - */ - public boolean isEnabled() { - try { - lock.lock(); - return enabled; - } finally { - lock.unlock(); - } - } - - /** - * Sets the enabled state of the external add-on library manager. - * - * @param enabled the enabled state. - * @throws IOException if an error occurs. - */ - public void setEnabled(boolean enabled) throws IOException { - try { - lock.lock(); - if (this.enabled != enabled) { - this.enabled = enabled; - if (enabled) { - startWatching(); - } else { - stopWatching(); - } - } - } finally { - lock.unlock(); - } - } - - /** - * Gets the path to the external add-on libraries. - * - * @return the path to the external add-on libraries. - */ - public Path getExternalLibraryPath() { - try { - lock.lock(); - return externalLibraryPath; - } finally { - lock.unlock(); - } - } - - /** - * Sets the path to the external add-on libraries. - * - * @param path the path to the external add-on libraries. - * @throws IOException if an error occurs. - */ - public void setExternalLibraryPath(Path path) throws IOException { - if (path != null && path.equals(externalLibraryPath)) { - return; - } - try { - lock.lock(); - externalLibraryPath = path; - stopWatching(); - if (path != null && enabled) { - startWatching(); - } - } finally { - lock.unlock(); - } - } - - /** Stops watching the external add-on library directory. */ - private void stopWatching() throws IOException { - try { - lock.lock(); - if (directoryWatcher != null) { - directoryWatcher.close(); - directoryWatcher = null; - } - } finally { - lock.unlock(); - } - } - - /** - * Starts watching the external add-on library directory. - * - * @throws IOException if an error occurs. - */ - private void startWatching() throws IOException { - try { - lock.lock(); - refreshAll(); - if (enabled && externalLibraryPath != null && Files.exists(externalLibraryPath)) { - if (directoryWatcher != null) { - directoryWatcher.watchAsync(); - } else { - directoryWatcher = createDirectoryWatcher(); - directoryWatcher.watchAsync(); - } - } - } finally { - lock.unlock(); - } - } - - /** - * Refreshes all the external add-on libraries. - * - * @throws IOException if an error occurs. - */ - private void refreshAll() throws IOException { - if (!initialised || !enabled || externalLibraryPath == null) { - return; - } - File[] directories = externalLibraryPath.toFile().listFiles(File::isDirectory); - if (directories != null) { - for (File directory : directories) { - try { - registerExternalAddOnLibrary(directory.toPath()); - } catch (IOException e) { - MapTool.showError(I18N.getText("library.dialog.read.failed", directory)); - } - } - } - var eventBus = new MapToolEventBus().getMainEventBus(); - eventBus.post(new ExternalAddonsUpdateEvent()); - } - - /** - * Makes the add-on library with the specified namespace available to MapTool. - * - * @param namespace the namespace of the add-on library to make available. - */ - public void importLibrary(String namespace) throws IOException { - if (enabled) { - var libInfo = namespaceInfoMap.get(namespace.toLowerCase()); - if (libInfo != null) { - var lib = new AddOnLibraryImporter().importFromDirectory(libInfo.backingDirectory()); - addOnLibraryManager.registerLibrary(lib); - } - } - } - - /** - * Checks to see if the specified path is an ignored sub-path when watching the external add-on - * - * @param path the path to check. - * @return {@code true} if the path is an ignored sub-path. - */ - private boolean isIgnoredSubPath(Path path) { - if (path.startsWith(".git")) { - return true; - } - - if (path.getFileName().toString().toLowerCase().endsWith(".mtlib")) { - return true; - } - - return false; - } - - /** - * Stops the add-on library with the specified namespace from being available to MapTool. - * - * @return the namespace of the add-on library to stop being available. - * @throws IOException if an error occurs. - */ - private DirectoryWatcher createDirectoryWatcher() throws IOException { - return DirectoryWatcher.builder() - .path(externalLibraryPath) - .listener( - event -> { - try { - int basePathNameCount = externalLibraryPath.getNameCount(); - var path = event.path(); - if (path.getNameCount() <= basePathNameCount) { - return; - } - if (!path.startsWith(externalLibraryPath)) { - return; - } - var subPath = externalLibraryPath.relativize(path); - if (isIgnoredSubPath(subPath)) { - return; - } - path = externalLibraryPath.resolve(path.getName(basePathNameCount)); - switch (event.eventType()) { - case CREATE -> registerExternalAddOnLibrary(path); - case DELETE -> { - if (path.toFile().exists()) { - refreshExternalAddOnLibrary(path); - } else { - deregisterExternalAddOnLibrary(path); - } - } - case MODIFY -> refreshExternalAddOnLibrary(path); - } - } catch (IOException e) { - MapTool.showError(I18N.getText("library.dialog.read.failed", event.path())); - } - }) - .build(); - } -} diff --git a/src/main/java/net/rptools/maptool/model/library/addon/ExternalLibraryInfo.java b/src/main/java/net/rptools/maptool/model/library/addon/ExternalLibraryInfo.java deleted file mode 100644 index eed3446292..0000000000 --- a/src/main/java/net/rptools/maptool/model/library/addon/ExternalLibraryInfo.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This software Copyright by the RPTools.net development team, and - * licensed under the Affero GPL Version 3 or, at your option, any later - * version. - * - * MapTool Source Code 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. - * - * You should have received a copy of the GNU Affero General Public - * License * along with this source Code. If not, please visit - * and specifically the Affero license - * text at . - */ -package net.rptools.maptool.model.library.addon; - -import java.nio.file.Path; -import net.rptools.maptool.model.library.LibraryInfo; - -/** - * Represents the information about external add-on library. - * - * @param namespace The namespace of the add-on. - * @param libraryInfo The library info of the add-on. - * @param updatedOnDisk Whether the add-on has been updated on disk. - * @param isInstalled Whether the add-on is installed. - * @param backingDirectory The backing directory of the add-on. - * @param subDirectoryName The subdirectory name of the add-on in the add-on development dir. - */ -public record ExternalLibraryInfo( - String namespace, - LibraryInfo libraryInfo, - boolean updatedOnDisk, - boolean isInstalled, - Path backingDirectory, - String subDirectoryName) {} diff --git a/src/main/java/net/rptools/maptool/util/FileUtil.java b/src/main/java/net/rptools/maptool/util/FileUtil.java index a08240193b..577db94ab4 100644 --- a/src/main/java/net/rptools/maptool/util/FileUtil.java +++ b/src/main/java/net/rptools/maptool/util/FileUtil.java @@ -21,11 +21,6 @@ import java.math.BigDecimal; import java.math.BigInteger; import java.math.RoundingMode; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Objects; -import java.util.stream.Collectors; -import java.util.stream.Stream; import net.rptools.maptool.client.AppUtil; /** @@ -203,38 +198,4 @@ public static File cleanFileName(String path, String fileName, String extension) public static File cleanFileName(String fileName, String extension) { return cleanFileName(null, fileName, extension); } - - /** - * Uses {@link Files#list(Path)} to recursively list all paths from a directory. The result - * includes directories. - * - * @param dir The directory to list recursively. - * @return A stream with all files. - * @throws IOException if an I/O error occurs while opening the directory, or any of its recursive - * children. - */ - public static Stream listRecursively(Path dir) throws IOException { - try (var pathStream = Files.list(dir)) { - var list = pathStream.collect(Collectors.toSet()); - try { - return Stream.concat( - list.stream(), - list.stream() - .flatMap( - p -> { - if (Files.isDirectory(p)) - try { - return listRecursively(p).map(p::resolve); - } catch (IOException e) { - throw new RuntimeException(e); - } - return null; - }) - .filter(Objects::nonNull)); - } catch (RuntimeException e) { - // This is to bypass an uncaught exception in the above lambda that calls in place. - throw (IOException) e.getCause(); - } - } - } } diff --git a/src/main/resources/net/rptools/maptool/language/i18n.properties b/src/main/resources/net/rptools/maptool/language/i18n.properties index 09fb8740fb..92cf3b9bab 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n.properties @@ -2931,8 +2931,6 @@ library.error.invalidDefinition = Invalid library definition. library.error.emptyName = Name can not be empty for add-on library. library.error.emptyVersion = Version can''t be empty for add-on library {0}. library.dialog.import.title = Import Add-On Library. -library.dialog.reimport = Reimport -library.dialog.import = Import library.import.ioError = IO Error importing Drop In Library. library.import.error = Error importing Drop In Library {0}. library.import.error.notGM = Only GM can import a Drop in Library. @@ -2974,7 +2972,6 @@ library.dialog.addon.description = Description library.dialog.addon.readMeFile = View Read Me File library.dialog.addon.authors = Authors library.dialog.addon.license = License -library.dialog.addon.readme = Read Me library.dialog.addon.licenseFile = View License File library.dialog.addon.giturl = Git URL library.dialog.addon.website = Website @@ -2985,41 +2982,8 @@ library.dialog.deleteData.confirm = Are you sure you want to remove add-on libra library.dialog.copy.title = The copied CSS is for testing \ purposes only.
Within your add-on use
lib://net.rptools.maptool/css/mt-stat-sheet.css \ or
lib://net.rptools.maptool/css/mt-theme.css -library.dialog.copyMTThemeCSS = Copy CSS Theme to clipboard -library.dialog.copyMTStatSheetTheme = Copy Stat Sheet Theme to clipboard -library.dialog.externalAddon = Enable external add-on libraries (development purposes only) -library.dialog.addon.subdir = Sub Directory -library.dialog.addon.imported = Imported -library.dialog.addon.updated = Updated -library.dialog.addon.refresh = Refresh -library.dialog.addon.createNew = Create New Add-On -library.dialog.addon.createMTLib = Create .mtlib file -library.dialog.directory.label = Add On Directory -library.dialog.parentdir.label = Parent Directory -library.dialog.read.failed = Error trying to read details of add-on in {0}, check library.json file format -library.dialog.import.failed = Error trying to read details of add-on in {0}, check library.json file format and library contents. -library.dialog.addon.createExample=Create Example Files -library.dialog.addon.createEvents=Events -library.dialog.addons.authorsComma=Authors (comma seperated) -library.dialog.addon.createSlash=Slash Commands -library.dialog.addon.createMTSProps=Macro Script Properties -library.dialog.addon.udf=User Defined Functions -library.dialog.addon.create.readeMe = ### Read Me\nPlace your Read Me information here, this file supports markup. -library.dialog.addon.create.licenseText = Place your license details in this file. -library.dialog.addon.create.shortDesc = Add-on Short Description -library.dialog.addon.create.longDesc = Add-on Long Description -library.dialog.addon.create.noSuchDir = Parent directory {0} for add-on does not exist. -library.dialog.addon.create.dirExists = Directory {0} for add-on already exists, chose a different directory. -library.dialog.create.parentDir.title = Choose Parent Directory for the Add-On -library.dialog.failedToCreateDir = Failed to create directory {0} for add-on. -library.dialog.failedToCreateFile = Failed to create file {0} for add-on. -library.dialog.create.exampleSlashCmdDesc = Example Slash Command -library.dialog.create.autoExecDesc = Auto Exec in macro link example -library.dialog.create.noAutoExecDesc = Non Auto Exec in macro link example -library.dialog.error.displayingAddons = Error displaying add-on libraries -library.dialog.addon.fileFilter = Add-On Libraries (*.mtlib) -library.dialog.addon.errorCreatingMTLib = Error Creating .mtlib file -library.dialog.addon.create.mtsComment = Replace this file ({0}) with your content +library.dialog.copyMTThemeCSS = Copy CSS Theme to clipbaord +library.dialog.copyMTStatSheetTheme = Copy Stat Sheet Theme to clipbaord # Game Data data.error.cantConvertTo = Can''t convert {0} to {1}. diff --git a/src/main/resources/net/rptools/maptool/language/i18n_cs.properties b/src/main/resources/net/rptools/maptool/language/i18n_cs.properties index 351b4b7352..649beb40ca 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n_cs.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n_cs.properties @@ -2735,8 +2735,8 @@ library.dialog.table.removeData = Remove Library and Data library.dialog.delete.confirm = Are you sure you want to remove add-on library {0}? library.dialog.deleteData.confirm = Are you sure you want to remove add-on library {0} and all its data? library.dialog.copy.title = The copied CSS is for testing purposes only.
Within your add-on use
lib\://net.rptools.maptool/css/mt-stat-sheet.css or
lib\://net.rptools.maptool/css/mt-theme.css -library.dialog.copyMTThemeCSS = Copy CSS Theme to clipboard -library.dialog.copyMTStatSheetTheme = Copy Stat Sheet Theme to clipboard +library.dialog.copyMTThemeCSS = Copy CSS Theme to clipbaord +library.dialog.copyMTStatSheetTheme = Copy Stat Sheet Theme to clipbaord # Game Data data.error.cantConvertTo = Can't convert {0} to {1}. diff --git a/src/main/resources/net/rptools/maptool/language/i18n_da.properties b/src/main/resources/net/rptools/maptool/language/i18n_da.properties index 044d1e358d..ae876d3184 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n_da.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n_da.properties @@ -2735,8 +2735,8 @@ library.dialog.table.removeData = Remove Library and Data library.dialog.delete.confirm = Are you sure you want to remove add-on library {0}? library.dialog.deleteData.confirm = Are you sure you want to remove add-on library {0} and all its data? library.dialog.copy.title = The copied CSS is for testing purposes only.
Within your add-on use
lib\://net.rptools.maptool/css/mt-stat-sheet.css or
lib\://net.rptools.maptool/css/mt-theme.css -library.dialog.copyMTThemeCSS = Copy CSS Theme to clipboard -library.dialog.copyMTStatSheetTheme = Copy Stat Sheet Theme to clipboard +library.dialog.copyMTThemeCSS = Copy CSS Theme to clipbaord +library.dialog.copyMTStatSheetTheme = Copy Stat Sheet Theme to clipbaord # Game Data data.error.cantConvertTo = Kan ikke konvertere {0} til {1}. diff --git a/src/main/resources/net/rptools/maptool/language/i18n_en.properties b/src/main/resources/net/rptools/maptool/language/i18n_en.properties index 99b6fbdfba..00142e12aa 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n_en.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n_en.properties @@ -2738,8 +2738,8 @@ library.dialog.table.removeData = Remove Library and Data library.dialog.delete.confirm = Are you sure you want to remove add-on library {0}? library.dialog.deleteData.confirm = Are you sure you want to remove add-on library {0} and all its data? library.dialog.copy.title = The copied CSS is for testing purposes only.
Within your add-on use
lib\://net.rptools.maptool/css/mt-stat-sheet.css or
lib\://net.rptools.maptool/css/mt-theme.css -library.dialog.copyMTThemeCSS = Copy CSS Theme to clipboard -library.dialog.copyMTStatSheetTheme = Copy Stat Sheet Theme to clipboard +library.dialog.copyMTThemeCSS = Copy CSS Theme to clipbaord +library.dialog.copyMTStatSheetTheme = Copy Stat Sheet Theme to clipbaord # Game Data data.error.cantConvertTo = Can't convert {0} to {1}. diff --git a/src/main/resources/net/rptools/maptool/language/i18n_en_AU.properties b/src/main/resources/net/rptools/maptool/language/i18n_en_AU.properties index 5a8aad2044..3c51b44586 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n_en_AU.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n_en_AU.properties @@ -2786,8 +2786,8 @@ library.dialog.table.removeData = Remove Library and Data library.dialog.delete.confirm = Are you sure you want to remove add-on library {0}? library.dialog.deleteData.confirm = Are you sure you want to remove add-on library {0} and all its data? library.dialog.copy.title = The copied CSS is for testing purposes only.
Within your add-on use
lib\://net.rptools.maptool/css/mt-stat-sheet.css or
lib\://net.rptools.maptool/css/mt-theme.css -library.dialog.copyMTThemeCSS = Copy CSS Theme to clipboard -library.dialog.copyMTStatSheetTheme = Copy Stat Sheet Theme to clipboard +library.dialog.copyMTThemeCSS = Copy CSS Theme to clipbaord +library.dialog.copyMTStatSheetTheme = Copy Stat Sheet Theme to clipbaord # Game Data data.error.cantConvertTo = Can't convert {0} to {1}. diff --git a/src/main/resources/net/rptools/maptool/language/i18n_en_GB.properties b/src/main/resources/net/rptools/maptool/language/i18n_en_GB.properties index 09d93d7d9f..ccfdf50ff3 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n_en_GB.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n_en_GB.properties @@ -1198,7 +1198,7 @@ action.error.noMapBoard = There is no map image. Use "Edit # hard-coded in the application, but that's OSX for you. ;-) action.exit = E&xit action.exit.description = Exit out of MapTool. -action.exportCampaignAs = +action.exportCampaignAs = action.exportCampaignAs.description = Export current campaign to a version compatible with older MapTool releases. action.exportScreenShot = Screenshot action.exportScreenShot.title = Export Screenshot @@ -2786,8 +2786,8 @@ library.dialog.table.removeData = Remove Library and Data library.dialog.delete.confirm = Are you sure you want to remove add-on library {0}? library.dialog.deleteData.confirm = Are you sure you want to remove add-on library {0} and all its data? library.dialog.copy.title = The copied CSS is for testing purposes only.
Within your add-on use
lib\://net.rptools.maptool/css/mt-stat-sheet.css or
lib\://net.rptools.maptool/css/mt-theme.css -library.dialog.copyMTThemeCSS = Copy CSS Theme to clipboard -library.dialog.copyMTStatSheetTheme = Copy Stat Sheet Theme to clipboard +library.dialog.copyMTThemeCSS = Copy CSS Theme to clipbaord +library.dialog.copyMTStatSheetTheme = Copy Stat Sheet Theme to clipbaord # Game Data data.error.cantConvertTo = Can't convert {0} to {1}. diff --git a/src/main/resources/net/rptools/maptool/language/i18n_es.properties b/src/main/resources/net/rptools/maptool/language/i18n_es.properties index 14755c19bf..73978e60ee 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n_es.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n_es.properties @@ -2735,8 +2735,8 @@ library.dialog.table.removeData = Remove Library and Data library.dialog.delete.confirm = Are you sure you want to remove add-on library {0}? library.dialog.deleteData.confirm = Are you sure you want to remove add-on library {0} and all its data? library.dialog.copy.title = The copied CSS is for testing purposes only.
Within your add-on use
lib\://net.rptools.maptool/css/mt-stat-sheet.css or
lib\://net.rptools.maptool/css/mt-theme.css -library.dialog.copyMTThemeCSS = Copy CSS Theme to clipboard -library.dialog.copyMTStatSheetTheme = Copy Stat Sheet Theme to clipboard +library.dialog.copyMTThemeCSS = Copy CSS Theme to clipbaord +library.dialog.copyMTStatSheetTheme = Copy Stat Sheet Theme to clipbaord # Game Data data.error.cantConvertTo = Can't convert {0} to {1}. diff --git a/src/main/resources/net/rptools/maptool/language/i18n_fr.properties b/src/main/resources/net/rptools/maptool/language/i18n_fr.properties index 3365b032b7..4c3f041e2b 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n_fr.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n_fr.properties @@ -2735,8 +2735,8 @@ library.dialog.table.removeData = Remove Library and Data library.dialog.delete.confirm = Are you sure you want to remove add-on library {0}? library.dialog.deleteData.confirm = Are you sure you want to remove add-on library {0} and all its data? library.dialog.copy.title = The copied CSS is for testing purposes only.
Within your add-on use
lib\://net.rptools.maptool/css/mt-stat-sheet.css or
lib\://net.rptools.maptool/css/mt-theme.css -library.dialog.copyMTThemeCSS = Copy CSS Theme to clipboard -library.dialog.copyMTStatSheetTheme = Copy Stat Sheet Theme to clipboard +library.dialog.copyMTThemeCSS = Copy CSS Theme to clipbaord +library.dialog.copyMTStatSheetTheme = Copy Stat Sheet Theme to clipbaord # Game Data data.error.cantConvertTo = Can't convert {0} to {1}. diff --git a/src/main/resources/net/rptools/maptool/language/i18n_it.properties b/src/main/resources/net/rptools/maptool/language/i18n_it.properties index a3e536cab5..4414534677 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n_it.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n_it.properties @@ -2735,8 +2735,8 @@ library.dialog.table.removeData = Rimuovi Libreria e Dati library.dialog.delete.confirm = Sei sicuro di voler rimuovere la libreria aggiuntiva {0}? library.dialog.deleteData.confirm = Sei sicuro di voler rimuovere la libreria aggiuntiva {0} e tutti i suoi dati? library.dialog.copy.title = The copied CSS is for testing purposes only.
Within your add-on use
lib\://net.rptools.maptool/css/mt-stat-sheet.css or
lib\://net.rptools.maptool/css/mt-theme.css -library.dialog.copyMTThemeCSS = Copy CSS Theme to clipboard -library.dialog.copyMTStatSheetTheme = Copy Stat Sheet Theme to clipboard +library.dialog.copyMTThemeCSS = Copy CSS Theme to clipbaord +library.dialog.copyMTStatSheetTheme = Copy Stat Sheet Theme to clipbaord # Game Data data.error.cantConvertTo = Impossibile convertire {0} in {1}. diff --git a/src/main/resources/net/rptools/maptool/language/i18n_nl.properties b/src/main/resources/net/rptools/maptool/language/i18n_nl.properties index 538c037b33..887c95b3f3 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n_nl.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n_nl.properties @@ -2735,8 +2735,8 @@ library.dialog.table.removeData = Remove Library and Data library.dialog.delete.confirm = Are you sure you want to remove add-on library {0}? library.dialog.deleteData.confirm = Are you sure you want to remove add-on library {0} and all its data? library.dialog.copy.title = The copied CSS is for testing purposes only.
Within your add-on use
lib\://net.rptools.maptool/css/mt-stat-sheet.css or
lib\://net.rptools.maptool/css/mt-theme.css -library.dialog.copyMTThemeCSS = Copy CSS Theme to clipboard -library.dialog.copyMTStatSheetTheme = Copy Stat Sheet Theme to clipbaaord +library.dialog.copyMTThemeCSS = Copy CSS Theme to clipbaord +library.dialog.copyMTStatSheetTheme = Copy Stat Sheet Theme to clipbaord # Game Data data.error.cantConvertTo = Can't convert {0} to {1}. diff --git a/src/main/resources/net/rptools/maptool/language/i18n_pl.properties b/src/main/resources/net/rptools/maptool/language/i18n_pl.properties index bfac031e76..3526e92446 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n_pl.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n_pl.properties @@ -2735,8 +2735,8 @@ library.dialog.table.removeData = Usuń bibliotekę i dane library.dialog.delete.confirm = Czy na pewno chcesz usunąć bibliotekę dodatków {0}? library.dialog.deleteData.confirm = Czy na pewno chcesz usunąć bibliotekę dodatków {0} i wszystkie jej dane? library.dialog.copy.title = Skopiowany CSS służy wyłącznie do testowania.
W ramach dodatku użyj
lib\://net.rptools.maptool/css/mt-stat-sheet.css lub
lib\://net.rptools.maptool/css/mt-theme.css -library.dialog.copyMTThemeCSS = Skopiuj motyw CSS do clipboard -library.dialog.copyMTStatSheetTheme = Skopiuj motyw arkusza statystyk do clipboard +library.dialog.copyMTThemeCSS = Skopiuj motyw CSS do clipbaord +library.dialog.copyMTStatSheetTheme = Skopiuj motyw arkusza statystyk do clipbaord # Game Data data.error.cantConvertTo = Nie można przekonwertować {0} na {1}. diff --git a/src/main/resources/net/rptools/maptool/language/i18n_pt.properties b/src/main/resources/net/rptools/maptool/language/i18n_pt.properties index b444562a07..fd4b60ce42 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n_pt.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n_pt.properties @@ -2735,8 +2735,8 @@ library.dialog.table.removeData = Remove Library and Data library.dialog.delete.confirm = Are you sure you want to remove add-on library {0}? library.dialog.deleteData.confirm = Are you sure you want to remove add-on library {0} and all its data? library.dialog.copy.title = The copied CSS is for testing purposes only.
Within your add-on use
lib\://net.rptools.maptool/css/mt-stat-sheet.css or
lib\://net.rptools.maptool/css/mt-theme.css -library.dialog.copyMTThemeCSS = Copy CSS Theme to clipboard -library.dialog.copyMTStatSheetTheme = Copy Stat Sheet Theme to clipboard +library.dialog.copyMTThemeCSS = Copy CSS Theme to clipbaord +library.dialog.copyMTStatSheetTheme = Copy Stat Sheet Theme to clipbaord # Game Data data.error.cantConvertTo = Can't convert {0} to {1}. diff --git a/src/main/resources/net/rptools/maptool/language/i18n_ru.properties b/src/main/resources/net/rptools/maptool/language/i18n_ru.properties index 4dc779d484..55a4c68fdc 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n_ru.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n_ru.properties @@ -2735,8 +2735,8 @@ library.dialog.table.removeData = Remove Library and Data library.dialog.delete.confirm = Are you sure you want to remove add-on library {0}? library.dialog.deleteData.confirm = Are you sure you want to remove add-on library {0} and all its data? library.dialog.copy.title = The copied CSS is for testing purposes only.
Within your add-on use
lib\://net.rptools.maptool/css/mt-stat-sheet.css or
lib\://net.rptools.maptool/css/mt-theme.css -library.dialog.copyMTThemeCSS = Copy CSS Theme to clipboard -library.dialog.copyMTStatSheetTheme = Copy Stat Sheet Theme to clipboard +library.dialog.copyMTThemeCSS = Copy CSS Theme to clipbaord +library.dialog.copyMTStatSheetTheme = Copy Stat Sheet Theme to clipbaord # Game Data data.error.cantConvertTo = Can't convert {0} to {1}. diff --git a/src/main/resources/net/rptools/maptool/language/i18n_si.properties b/src/main/resources/net/rptools/maptool/language/i18n_si.properties index 28e8c3afe4..756327bba4 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n_si.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n_si.properties @@ -2738,8 +2738,8 @@ library.dialog.table.removeData = Remove Library and Data library.dialog.delete.confirm = Are you sure you want to remove add-on library {0}? library.dialog.deleteData.confirm = Are you sure you want to remove add-on library {0} and all its data? library.dialog.copy.title = The copied CSS is for testing purposes only.
Within your add-on use
lib\://net.rptools.maptool/css/mt-stat-sheet.css or
lib\://net.rptools.maptool/css/mt-theme.css -library.dialog.copyMTThemeCSS = Copy CSS Theme to clipboard -library.dialog.copyMTStatSheetTheme = Copy Stat Sheet Theme to clipboard +library.dialog.copyMTThemeCSS = Copy CSS Theme to clipbaord +library.dialog.copyMTStatSheetTheme = Copy Stat Sheet Theme to clipbaord # Game Data data.error.cantConvertTo = Can't convert {0} to {1}. diff --git a/src/main/resources/net/rptools/maptool/language/i18n_sv.properties b/src/main/resources/net/rptools/maptool/language/i18n_sv.properties index 2f6fdfc08c..cfb14cf531 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n_sv.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n_sv.properties @@ -2735,8 +2735,8 @@ library.dialog.table.removeData = Remove Library and Data library.dialog.delete.confirm = Are you sure you want to remove add-on library {0}? library.dialog.deleteData.confirm = Are you sure you want to remove add-on library {0} and all its data? library.dialog.copy.title = The copied CSS is for testing purposes only.
Within your add-on use
lib\://net.rptools.maptool/css/mt-stat-sheet.css or
lib\://net.rptools.maptool/css/mt-theme.css -library.dialog.copyMTThemeCSS = Copy CSS Theme to clipboard -library.dialog.copyMTStatSheetTheme = Copy Stat Sheet Theme to clipboard +library.dialog.copyMTThemeCSS = Copy CSS Theme to clipbaord +library.dialog.copyMTStatSheetTheme = Copy Stat Sheet Theme to clipbaord # Game Data data.error.cantConvertTo = Can't convert {0} to {1}. diff --git a/src/main/resources/net/rptools/maptool/language/i18n_uk.properties b/src/main/resources/net/rptools/maptool/language/i18n_uk.properties index f22daa4c87..9ce4d742f2 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n_uk.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n_uk.properties @@ -2735,8 +2735,8 @@ library.dialog.table.removeData = Remove Library and Data library.dialog.delete.confirm = Are you sure you want to remove add-on library {0}? library.dialog.deleteData.confirm = Are you sure you want to remove add-on library {0} and all its data? library.dialog.copy.title = The copied CSS is for testing purposes only.
Within your add-on use
lib\://net.rptools.maptool/css/mt-stat-sheet.css or
lib\://net.rptools.maptool/css/mt-theme.css -library.dialog.copyMTThemeCSS = Copy CSS Theme to clipboard -library.dialog.copyMTStatSheetTheme = Copy Stat Sheet Theme to clipboard +library.dialog.copyMTThemeCSS = Copy CSS Theme to clipbaord +library.dialog.copyMTStatSheetTheme = Copy Stat Sheet Theme to clipbaord # Game Data data.error.cantConvertTo = Can't convert {0} to {1}. diff --git a/src/main/resources/net/rptools/maptool/language/i18n_zh.properties b/src/main/resources/net/rptools/maptool/language/i18n_zh.properties index 475012c672..7ad427eff6 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n_zh.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n_zh.properties @@ -2735,8 +2735,8 @@ library.dialog.table.removeData = Remove Library and Data library.dialog.delete.confirm = Are you sure you want to remove add-on library {0}? library.dialog.deleteData.confirm = Are you sure you want to remove add-on library {0} and all its data? library.dialog.copy.title = The copied CSS is for testing purposes only.
Within your add-on use
lib\://net.rptools.maptool/css/mt-stat-sheet.css or
lib\://net.rptools.maptool/css/mt-theme.css -library.dialog.copyMTThemeCSS = Copy CSS Theme to clipboard -library.dialog.copyMTStatSheetTheme = Copy Stat Sheet Theme to clipboard +library.dialog.copyMTThemeCSS = Copy CSS Theme to clipbaord +library.dialog.copyMTStatSheetTheme = Copy Stat Sheet Theme to clipbaord # Game Data data.error.cantConvertTo = Can't convert {0} to {1}.