diff --git a/gui/src/main/java/com/keepaste/gui/DialogKeep.java b/gui/src/main/java/com/keepaste/gui/DialogKeep.java index 0039491..a241651 100644 --- a/gui/src/main/java/com/keepaste/gui/DialogKeep.java +++ b/gui/src/main/java/com/keepaste/gui/DialogKeep.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ diff --git a/gui/src/main/java/com/keepaste/gui/Gui.java b/gui/src/main/java/com/keepaste/gui/Gui.java index bf698ac..c82486f 100644 --- a/gui/src/main/java/com/keepaste/gui/Gui.java +++ b/gui/src/main/java/com/keepaste/gui/Gui.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ diff --git a/gui/src/main/java/com/keepaste/gui/GuiMain.java b/gui/src/main/java/com/keepaste/gui/GuiMain.java index 6b66f88..6b861c0 100644 --- a/gui/src/main/java/com/keepaste/gui/GuiMain.java +++ b/gui/src/main/java/com/keepaste/gui/GuiMain.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ diff --git a/logic/src/main/java/com/keepaste/logic/Application.java b/logic/src/main/java/com/keepaste/logic/Application.java index edd359d..352a5ba 100644 --- a/logic/src/main/java/com/keepaste/logic/Application.java +++ b/logic/src/main/java/com/keepaste/logic/Application.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -55,7 +55,7 @@ import org.apache.maven.artifact.versioning.ComparableVersion; /** - * This class holds the main entry point for the application and holds a reference to the {@link Context}. + * This class holds the main entry point for the application and holds a reference to the {@code Context}. */ @Log4j2 public final class Application { @@ -76,98 +76,109 @@ private Application() { */ public static void main(String[] args) { try { - // Load settings from disk - ModelSettings modelSettings = SettingsManager.loadSettingsFromFile(); - // in case there is an issue loading the settings file, create a default one instead - if (modelSettings == null) { - SettingsManager.createDefaultSettingsFile(); - modelSettings = SettingsManager.loadSettingsFromFile(); - } - if (modelSettings == null) { - modelSettings = SettingsManager.getDefaultModelSettings(); - } + // checking if there is a new release available + checkForNewRelease(); - setInitialLookAndFeel(modelSettings); + // Load settings from disk or get default instance + ModelSettings modelSettings = SettingsManager.getModelSettings(); - final Gui gui = new Gui(); + // set look and feel based on settings + setInitialLookAndFeel(modelSettings); - if (OperatingSystemUtils.getOperatingSystemType() == OperatingSystemUtils.OperatingSystemType.WINDOWS) { - gui.setMinimumSize(new Dimension(APP_MIN_WIDTH, gui.getHeight())); - } - ModelActiveWindow modelActiveWindow = new ModelActiveWindow(); - context = new Context( - gui, - getWindowManager(), - modelSettings, - new KeepsManager(), - new KeepExecutionManager(), - modelActiveWindow); - boolean isFirstTimeRunning = !new File(context.getKeepsManager().getKeepsFilePathString()).exists(); - checkForNewRelease(); - Image logoImage = ImagesUtils.getImage("/logo-white.png"); - - // Create and display the form - ModelSettings finalModelSettings = modelSettings; - EventQueue.invokeLater(() -> { - try { - gui.setIconImage(logoImage); - gui.labelBackground.setVisible(false); - - // Intercepted window shown on status bar - ViewActiveWindow viewActiveWindow = new ViewActiveWindow(gui.labelTargetWindow, gui.labelTargetWindowTitle); - new ControllerActiveWindow(modelActiveWindow, viewActiveWindow); - - // Top menu bar - ViewTopMenu viewTopMenu = new ViewTopMenu(gui.menuItemMain, gui.menuItemAbout, gui.menuItemHeart); - viewTopMenu.initUpperMenuBar(); - new ControllerTopMenu(modelActiveWindow, viewActiveWindow, viewTopMenu.getLockingMenuItem()); - - // Tree - ViewTree viewTree = new ViewTree(); - ModelTree modelTree = new ModelTree(); - new ControllerTree(modelTree, viewTree); - - // look and feel (theme) controller - ViewLookAndFeel viewLookAndFeel = new ViewLookAndFeel(viewTree); - new ControllerLookAndFeel(finalModelSettings, viewLookAndFeel); - - final Toolkit toolkit = java.awt.Toolkit.getDefaultToolkit(); - final Dimension screenSize = toolkit.getScreenSize(); - - // do not change the order of these two next lines, setLocationRelativeTo sets the window in the center, - // but allows ctrl+f4 on Mac, while the second line set the window on a specific position. - // having those reversed will cause ctrl+f4 which is being used to switch between windows to stop working - // on always on top mode. - gui.setLocationRelativeTo(null); - gui.setLocation( - (int) screenSize.getWidth() - gui.getWidth() - LOCATION_MARGIN, - (int) screenSize.getHeight() - gui.getHeight() - LOCATION_MARGIN); - - gui.setAlwaysOnTop(finalModelSettings.isAlwaysOnTop()); - - gui.setVisible(true); - finalModelSettings.setLookAndFeel(finalModelSettings.getTheme()); - log.info("Gui initialized"); - - if (isFirstTimeRunning) { - // this is the first time keepaste runs on this machine, showing the welcome dialog - DialogWelcome dialogWelcome = new DialogWelcome(gui, true); - GuiUtils.initHyperlinkLabel(dialogWelcome.labelTutorial, "http://www.keepaste.com/tutorial.htm"); - GuiUtils.initHyperlinkLabel(dialogWelcome.labelKeepsLibrary, "https://github.com/tamirkrispis/keeps-library"); - GuiUtils.showDialogOnCenterScreen(dialogWelcome); - } - } catch (Exception ex) { - log.error("Failed to initialize gui", ex); - System.exit(1); - } + // generating app context to be used + context = generateContext(modelSettings); - context.startWindowInterceptorRunner(); - }); + // initializing and displaying the GUI + initGui(); + } catch (Exception ex) { log.error("Failed to start the application", ex); } } + private static void initGui() { + // Create and display the form + EventQueue.invokeLater(() -> { + try { + Gui gui = context.getGui(); + // setting minimum size for windows + if (OperatingSystemUtils.getOperatingSystemType() == OperatingSystemUtils.OperatingSystemType.WINDOWS) { + gui.setMinimumSize(new Dimension(APP_MIN_WIDTH, gui.getHeight())); + } + + gui.setIconImage(getLogoImage()); + gui.labelBackground.setVisible(false); + + // Intercepted window shown on status bar + ViewActiveWindow viewActiveWindow = new ViewActiveWindow(gui.labelTargetWindow, gui.labelTargetWindowTitle); + new ControllerActiveWindow(context.getModelActiveWindow(), viewActiveWindow); + + // Top menu bar + ViewTopMenu viewTopMenu = new ViewTopMenu(gui.menuItemMain, gui.menuItemAbout, gui.menuItemHeart); + viewTopMenu.initUpperMenuBar(); + new ControllerTopMenu(context.getModelActiveWindow(), viewActiveWindow, viewTopMenu.getLockingMenuItem()); + + // Tree + ViewTree viewTree = new ViewTree(); + ModelTree modelTree = new ModelTree(); + new ControllerTree(modelTree, viewTree); + + // look and feel (theme) controller + ViewLookAndFeel viewLookAndFeel = new ViewLookAndFeel(viewTree); + new ControllerLookAndFeel(context.getModelSettings(), viewLookAndFeel); + + final Toolkit toolkit = Toolkit.getDefaultToolkit(); + final Dimension screenSize = toolkit.getScreenSize(); + + // do not change the order of these two next lines, setLocationRelativeTo sets the window in the center, + // but allows ctrl+f4 on Mac, while the second line set the window on a specific position. + // having those reversed will cause ctrl+f4 which is being used to switch between windows to stop working + // on always on top mode. + gui.setLocationRelativeTo(null); + gui.setLocation( + (int) screenSize.getWidth() - gui.getWidth() - LOCATION_MARGIN, + (int) screenSize.getHeight() - gui.getHeight() - LOCATION_MARGIN); + + gui.setAlwaysOnTop(context.getModelSettings().isAlwaysOnTop()); + + gui.setVisible(true); + context.getModelSettings().setLookAndFeel(context.getModelSettings().getTheme()); + log.info("Gui initialized"); + + if (isFirstTimeRunning()) { + // this is the first time keepaste runs on this machine, showing the welcome dialog + DialogWelcome dialogWelcome = new DialogWelcome(gui, true); + GuiUtils.initHyperlinkLabel(dialogWelcome.labelTutorial, "https://www.keepaste.com/tutorial.htm"); + GuiUtils.initHyperlinkLabel(dialogWelcome.labelKeepsLibrary, "https://github.com/tamirkrispis/keeps-library"); + GuiUtils.showDialogOnCenterScreen(dialogWelcome); + } + } catch (Exception ex) { + log.error("Failed to initialize gui", ex); + System.exit(1); + } + + context.startWindowInterceptorRunner(); + }); + } + + private static Image getLogoImage() { + return ImagesUtils.getImage("/logo-white.png"); + } + + private static boolean isFirstTimeRunning() { + return !new File(context.getKeepsManager().getKeepsFilePathString()).exists(); + } + + private static Context generateContext(ModelSettings modelSettings) { + return new Context( + new Gui(), + getWindowManager(), + modelSettings, + new KeepsManager(), + new KeepExecutionManager(), + new ModelActiveWindow()); + } + private static void setInitialLookAndFeel(ModelSettings modelSettings) { try { FlatLightLaf.setup(); diff --git a/logic/src/main/java/com/keepaste/logic/Context.java b/logic/src/main/java/com/keepaste/logic/Context.java index 569dbb7..18ec66b 100644 --- a/logic/src/main/java/com/keepaste/logic/Context.java +++ b/logic/src/main/java/com/keepaste/logic/Context.java @@ -44,12 +44,12 @@ public class Context { /** * Constructor. * - * @param gui the {@link Gui} - * @param windowManager the relevant {@link WindowManager} based on the OS - * @param modelSettings the {@link ModelSettings} to be used - * @param keepsManager the {@link KeepsManager} to be used - * @param keepExecutionManager the {@link KeepExecutionManager} to be used - * @param modelActiveWindow the {@link ModelActiveWindow} to be used + * @param gui the {@code Gui} + * @param windowManager the relevant {@code WindowManager} based on the OS + * @param modelSettings the {@code ModelSettings} to be used + * @param keepsManager the {@code KeepsManager} to be used + * @param keepExecutionManager the {@code KeepExecutionManager} to be used + * @param modelActiveWindow the {@code ModelActiveWindow} to be used */ public Context(@NonNull final Gui gui, @NonNull final WindowManager windowManager, @@ -91,9 +91,8 @@ public String getVersion() { * Will start intercepting windows constantly. */ public void startWindowInterceptorRunner() { - log.info("Starting window interceptor"); - if (modelSettings.isFocusOnWindowAndPaste()) { + log.info("Starting window interceptor"); Runnable windowInterceptorRunner = new WindowInterceptorRunner(windowManager, modelActiveWindow, INTERCEPT_INTERVAL_IN_MS); windowInterceptorThread = new Thread(windowInterceptorRunner); windowInterceptorThread.setDaemon(true); diff --git a/logic/src/main/java/com/keepaste/logic/actionlisteners/dialogkeep/AddParamActionListener.java b/logic/src/main/java/com/keepaste/logic/actionlisteners/dialogkeep/AddParamActionListener.java index 94b21f6..92f589d 100644 --- a/logic/src/main/java/com/keepaste/logic/actionlisteners/dialogkeep/AddParamActionListener.java +++ b/logic/src/main/java/com/keepaste/logic/actionlisteners/dialogkeep/AddParamActionListener.java @@ -1,30 +1,30 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package com.keepaste.logic.actionlisteners.dialogkeep; +import com.keepaste.gui.DialogKeep; import com.keepaste.logic.views.KeepParametersTableModel; import lombok.extern.log4j.Log4j2; -import javax.swing.JTable; import java.awt.event.ActionEvent; /** - * This class is an ActionListener for adding a parameter to a Keep on the {@link com.keepaste.gui.DialogKeep}. + * This class is an ActionListener for adding a parameter to a Keep on the {@code com.keepaste.gui.DialogKeep}. */ @Log4j2 public class AddParamActionListener extends BaseDialogKeepActionListener { @@ -32,31 +32,31 @@ public class AddParamActionListener extends BaseDialogKeepActionListener { /** * Constructor. * - * @param table the {@link JTable} to show the parameters + * @param dialogKeep a {@code DialogKeep} */ - public AddParamActionListener(final JTable table) { - super(table); + public AddParamActionListener(final DialogKeep dialogKeep) { + super(dialogKeep); } @Override public void actionPerformed(ActionEvent e) { // Adding a new parameter to the parameters table on the dialog log.debug("DialogKeep - Adding new keep parameter on the Dialog Command"); - var table = getTable(); - KeepParametersTableModel model = (KeepParametersTableModel) table.getModel(); + var tableParams = dialogKeep.tableParams; + KeepParametersTableModel model = (KeepParametersTableModel) tableParams.getModel(); model.addRow(model.getRowCount(), "", ""); // Scroll to the added row int row = model.getRowCount() - 1; - table.scrollRectToVisible(table.getCellRect(row, 0, true)); + tableParams.scrollRectToVisible(tableParams.getCellRect(row, 0, true)); // Request focus on the added row's first cell - table.requestFocus(); - table.changeSelection(row, 0, false, false); - table.editCellAt(row, 0); - table.getEditorComponent().requestFocus(); + tableParams.requestFocus(); + tableParams.changeSelection(row, 0, false, false); + tableParams.editCellAt(row, 0); + tableParams.getEditorComponent().requestFocus(); // updating the table to show the new row - getTable().updateUI(); + tableParams.updateUI(); log.debug("DialogKeep - Added new keep parameter on the Dialog Command"); } } diff --git a/logic/src/main/java/com/keepaste/logic/actionlisteners/dialogkeep/BaseDialogKeepActionListener.java b/logic/src/main/java/com/keepaste/logic/actionlisteners/dialogkeep/BaseDialogKeepActionListener.java index e811ea5..97e5a8e 100644 --- a/logic/src/main/java/com/keepaste/logic/actionlisteners/dialogkeep/BaseDialogKeepActionListener.java +++ b/logic/src/main/java/com/keepaste/logic/actionlisteners/dialogkeep/BaseDialogKeepActionListener.java @@ -1,20 +1,14 @@ package com.keepaste.logic.actionlisteners.dialogkeep; -import lombok.Getter; +import com.keepaste.gui.DialogKeep; import lombok.NonNull; - -import javax.swing.JTable; import java.awt.event.ActionListener; public abstract class BaseDialogKeepActionListener implements ActionListener { - /** - * the {@link JTable} to show the parameters. - */ - @Getter - private final JTable table; + protected final DialogKeep dialogKeep; - BaseDialogKeepActionListener(@NonNull final JTable table) { - this.table = table; + BaseDialogKeepActionListener(@NonNull final DialogKeep dialogKeep) { + this.dialogKeep = dialogKeep; } } diff --git a/logic/src/main/java/com/keepaste/logic/actionlisteners/dialogkeep/ExistingParamActionListener.java b/logic/src/main/java/com/keepaste/logic/actionlisteners/dialogkeep/ExistingParamActionListener.java index 3f71d0b..2d346ef 100644 --- a/logic/src/main/java/com/keepaste/logic/actionlisteners/dialogkeep/ExistingParamActionListener.java +++ b/logic/src/main/java/com/keepaste/logic/actionlisteners/dialogkeep/ExistingParamActionListener.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -29,21 +29,18 @@ /** * This class is an ActionListener for showing a list of existing parameters so the user will be able to use any on the - * current Keep on the {@link com.keepaste.gui.DialogKeep}. + * current Keep on the {@code com.keepaste.gui.DialogKeep}. */ @Log4j2 public class ExistingParamActionListener extends BaseDialogKeepActionListener { - private final DialogKeep dialogKeep; - /** * Constructor. * - * @param dialogKeep the parent {@link DialogKeep}. + * @param dialogKeep a {@code DialogKeep}. */ public ExistingParamActionListener(final DialogKeep dialogKeep) { - super(dialogKeep.tableParams); - this.dialogKeep = dialogKeep; + super(dialogKeep); } @Override @@ -61,9 +58,9 @@ public void actionPerformed(ActionEvent e) { parameters.toArray(), null); if (selectedParam != null) { - KeepParametersTableModel model = (KeepParametersTableModel) getTable().getModel(); + KeepParametersTableModel model = (KeepParametersTableModel) dialogKeep.tableParams.getModel(); model.addRow(model.getRowCount(), selectedParam.getName(), selectedParam.getPhrase()); - getTable().updateUI(); + dialogKeep.tableParams.updateUI(); } log.debug("DialogKeep - Added [{}] keep parameter on Dialog Command from existing parameters list", selectedParam); } diff --git a/logic/src/main/java/com/keepaste/logic/actionlisteners/dialogkeep/OkButtonActionListener.java b/logic/src/main/java/com/keepaste/logic/actionlisteners/dialogkeep/OkButtonActionListener.java new file mode 100644 index 0000000..216bdb2 --- /dev/null +++ b/logic/src/main/java/com/keepaste/logic/actionlisteners/dialogkeep/OkButtonActionListener.java @@ -0,0 +1,139 @@ +package com.keepaste.logic.actionlisteners.dialogkeep; + +import com.keepaste.gui.DialogKeep; +import com.keepaste.logic.Application; +import com.keepaste.logic.models.Keep; +import com.keepaste.logic.models.KeepParameter; +import com.keepaste.logic.models.KeepsGroup; +import lombok.NonNull; +import org.apache.commons.lang3.StringUtils; + +import javax.swing.*; +import javax.swing.table.TableCellEditor; +import java.awt.event.ActionEvent; +import java.util.List; + +public class OkButtonActionListener extends BaseDialogKeepActionListener { + private final List editedParameters; + private final Keep keep; + + /** + * Constructor. + * + * @param dialogKeep a {@code DialogKeep} + * @param keep a {@code Keep} + * @param editedParameters a list of {@code KeepParameter} + */ + public OkButtonActionListener(@NonNull final DialogKeep dialogKeep, + @NonNull final Keep keep, + @NonNull final List editedParameters) { + super(dialogKeep); + this.keep = keep; + this.editedParameters = editedParameters; + } + + @Override + public void actionPerformed(ActionEvent e) { + + // if any cell is edited, stop/finish editing it + stopEditing(); + + // validating all mandatory fields provided + if (mandatoryFieldsNotProvided()) return; + + // validating that there are no duplications in parameter names + if (duplicationsInParamsNames()) return; + + // validating that all command parameters are met + if (notAllParamsOfCommandProvided()) return; + + // validating that all parameters used in parameters are met + if (notAllParamsOfParamsProvided()) return; + + keep.setTitle(dialogKeep.textName.getText().trim()); + keep.setPhrase(dialogKeep.textKeep.getText().trim()); + keep.setDescription(dialogKeep.textDescription.getText().trim()); + keep.setNeverPressEnter(dialogKeep.checkNeverPressEnter.isSelected()); + keep.setParameters(editedParameters); + + KeepsGroup rootNode = Application.getContext().getKeepsManager().getRootNode(); + Application.getContext().getKeepsManager().saveKeeps(rootNode); + + dialogKeep.setVisible(false); + } + + private boolean notAllParamsOfParamsProvided() { + for (KeepParameter parameter : editedParameters) { + String parameterPhrase = parameter.getPhrase(); + for (KeepParameter otherParameters : editedParameters) { + if (otherParameters == parameter) { + // validating that a keep parameter doesn't reference itself + if (paramReferencesItself(parameter, parameterPhrase)) return true; + } else { + parameterPhrase = parameterPhrase.replace(String.format("<%s>", otherParameters.getName()), ""); + } + } + int startIndex = parameterPhrase.indexOf("<"); + int endIndex = parameterPhrase.indexOf(">", startIndex); + if (startIndex > 0 && endIndex > 0) { + String missingParamName = parameterPhrase.substring(startIndex + 1, endIndex); + JOptionPane.showMessageDialog(Application.getContext().getGui(), + String.format("Given parameters does not cover all used parameters (on keep or its parameters)," + + " please add the following missing parameter - %s", missingParamName)); + return true; + } + } + return false; + } + + private static boolean paramReferencesItself(KeepParameter parameter, String parameterPhrase) { + if (parameterPhrase.contains(String.format("<%s>", parameter.getName()))) { + JOptionPane.showMessageDialog(Application.getContext().getGui(), + String.format("The parameter %s cannot use its own name as a command parameter.", parameter.getName())); + return true; + } + return false; + } + + private boolean notAllParamsOfCommandProvided() { + String commandStr = dialogKeep.textKeep.getText(); + for (KeepParameter parameter : editedParameters) { + commandStr = commandStr.replace(String.format("<%s>", parameter.getName()), ""); + } + if (commandStr.contains("<") && commandStr.contains(">")) { + JOptionPane.showMessageDialog(Application.getContext().getGui(), + "Given parameters does not cover all keep parameters, please add missing ones"); + return true; + } + return false; + } + + private boolean duplicationsInParamsNames() { + if (editedParameters.stream().map(KeepParameter::getName).distinct().count() < editedParameters.size()) { + JOptionPane.showMessageDialog(Application.getContext().getGui(), + "There are duplications in parameters names, please review"); + return true; + } + return false; + } + + private boolean mandatoryFieldsNotProvided() { + if (StringUtils.isEmpty(dialogKeep.textKeep.getText()) || StringUtils.isEmpty(dialogKeep.textName.getText())) { + JOptionPane.showMessageDialog(Application.getContext().getGui(), + "Both Name and Keep fields are mandatory", "Not enough...", JOptionPane.ERROR_MESSAGE); + return true; + } + return false; + } + + private void stopEditing() { + JTable tableParams = dialogKeep.tableParams; + if (tableParams.isEditing()) { + TableCellEditor cellEditor = tableParams.getCellEditor( + tableParams.getEditingRow(), tableParams.getEditingColumn()); + if (cellEditor != null) { + cellEditor.stopCellEditing(); + } + } + } +} diff --git a/logic/src/main/java/com/keepaste/logic/actionlisteners/dialogkeep/RemoveParamActionListener.java b/logic/src/main/java/com/keepaste/logic/actionlisteners/dialogkeep/RemoveParamActionListener.java index a11ac87..ff19f06 100644 --- a/logic/src/main/java/com/keepaste/logic/actionlisteners/dialogkeep/RemoveParamActionListener.java +++ b/logic/src/main/java/com/keepaste/logic/actionlisteners/dialogkeep/RemoveParamActionListener.java @@ -1,54 +1,54 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package com.keepaste.logic.actionlisteners.dialogkeep; +import com.keepaste.gui.DialogKeep; import com.keepaste.logic.views.KeepParametersTableModel; import lombok.extern.log4j.Log4j2; import javax.swing.*; import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; /** - * This class is an {@link ActionListener} for removing a parameter from a Keep on the {@link com.keepaste.gui.DialogKeep}. + * This class is an {@code ActionListener} for removing a parameter from a Keep on the {@code com.keepaste.gui.DialogKeep}. */ @Log4j2 public class RemoveParamActionListener extends BaseDialogKeepActionListener { - /** * Constructor. * - * @param table the {@link JTable} to show the parameters + * @param dialogKeep a {@code DialogKeep} */ - public RemoveParamActionListener(final JTable table) { - super(table); + public RemoveParamActionListener(final DialogKeep dialogKeep) { + super(dialogKeep); } @Override public void actionPerformed(ActionEvent e) { // removing the parameter from the Keep dialog log.debug("DialogKeep - Removing parameter from DialogKeep"); - if (getTable().getSelectedRow() >= 0) { - KeepParametersTableModel model = (KeepParametersTableModel) getTable().getModel(); - model.removeRow(getTable().getSelectedRow()); - getTable().updateUI(); + JTable tableParams = dialogKeep.tableParams; + if (tableParams.getSelectedRow() >= 0) { + KeepParametersTableModel model = (KeepParametersTableModel) tableParams.getModel(); + model.removeRow(tableParams.getSelectedRow()); + tableParams.updateUI(); } log.debug("DialogKeep - Removed parameter from DialogKeep"); } diff --git a/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/AlwaysOnTopActionListener.java b/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/AlwaysOnTopActionListener.java index 84b6576..7066dce 100644 --- a/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/AlwaysOnTopActionListener.java +++ b/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/AlwaysOnTopActionListener.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ diff --git a/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/AutoEnterActionListener.java b/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/AutoEnterActionListener.java index 5558659..2b861ab 100644 --- a/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/AutoEnterActionListener.java +++ b/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/AutoEnterActionListener.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -20,6 +20,7 @@ import com.keepaste.logic.Application; import com.keepaste.logic.common.Constants; +import com.keepaste.logic.utils.GuiUtils; import lombok.NonNull; import lombok.extern.log4j.Log4j2; @@ -60,9 +61,9 @@ public void actionPerformed(ActionEvent e) { Application.getContext().startWindowInterceptorRunner(); if (checkBoxMenuItem.isSelected()) { - Application.getContext().getGui().labelTargetWindow.setText(Constants.FULL_ON_MODE); + GuiUtils.showTargetWindowLabelMessage(Constants.FULL_ON_MODE, 1); } else { - Application.getContext().getGui().labelTargetWindow.setText(Constants.PASTE_BUT_DO_NOT_RUN_MODE); + GuiUtils.showTargetWindowLabelMessage(Constants.PASTE_BUT_DO_NOT_RUN_MODE, 1); } log.debug("TopMenu - full on mode"); } diff --git a/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/CopyToClipboardActionListener.java b/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/CopyToClipboardActionListener.java index c647311..998ae85 100644 --- a/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/CopyToClipboardActionListener.java +++ b/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/CopyToClipboardActionListener.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -39,8 +39,8 @@ public class CopyToClipboardActionListener implements ActionListener { /** * Constructor. * - * @param autoEnterCheckboxMenuItem the auto-enter {@link JCheckBoxMenuItem} - * @param focusOnTargetWindowCheckboxMenuItem the focus on target window {@link JCheckBoxMenuItem} + * @param autoEnterCheckboxMenuItem the auto-enter {@code JCheckBoxMenuItem} + * @param focusOnTargetWindowCheckboxMenuItem the focus on target window {@code JCheckBoxMenuItem} */ public CopyToClipboardActionListener(@NonNull final JCheckBoxMenuItem autoEnterCheckboxMenuItem, @NonNull final JCheckBoxMenuItem focusOnTargetWindowCheckboxMenuItem) { diff --git a/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/DialogAboutActionListener.java b/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/DialogAboutActionListener.java index 093d8da..a1f9605 100644 --- a/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/DialogAboutActionListener.java +++ b/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/DialogAboutActionListener.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -57,7 +57,7 @@ public void mouseExited(MouseEvent e) { } private void initDialog() { - GuiUtils.initHyperlinkLabel(dialogAbout.labelWebsite, "http://www.keepaste.com"); + GuiUtils.initHyperlinkLabel(dialogAbout.labelWebsite, "https://www.keepaste.com"); GuiUtils.initHyperlinkLabel(dialogAbout.labelGithub, "https://github.com/tamirkrispis/keepaste"); GuiUtils.initHyperlinkLabel(dialogAbout.labelIcons8, "https://icons8.com/"); GuiUtils.initHyperlinkLabel(dialogAbout.labelKeepsLibrary, "https://github.com/tamirkrispis/keeps-library"); diff --git a/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/DialogHeartActionListener.java b/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/DialogHeartActionListener.java index b4c1628..4466352 100644 --- a/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/DialogHeartActionListener.java +++ b/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/DialogHeartActionListener.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (https://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ diff --git a/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/ExitActionListener.java b/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/ExitActionListener.java index de740a0..e3c0012 100644 --- a/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/ExitActionListener.java +++ b/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/ExitActionListener.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ diff --git a/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/FocusOnTargetWindowActionListener.java b/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/FocusOnTargetWindowActionListener.java index 07e7167..b96d63c 100644 --- a/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/FocusOnTargetWindowActionListener.java +++ b/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/FocusOnTargetWindowActionListener.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -19,6 +19,7 @@ import com.keepaste.logic.Application; import com.keepaste.logic.common.Constants; +import com.keepaste.logic.utils.GuiUtils; import lombok.NonNull; import lombok.extern.log4j.Log4j2; @@ -37,8 +38,8 @@ public class FocusOnTargetWindowActionListener implements ActionListener { /** * Constructor. * - * @param copyToClipboardCheckboxMenuItem copy-to-clipboard {@link JCheckBoxMenuItem} - * @param autoEnterCheckboxMenuItem auto-enter {@link JCheckBoxMenuItem} + * @param copyToClipboardCheckboxMenuItem copy-to-clipboard {@code JCheckBoxMenuItem} + * @param autoEnterCheckboxMenuItem auto-enter {@code JCheckBoxMenuItem} */ public FocusOnTargetWindowActionListener(@NonNull final JCheckBoxMenuItem copyToClipboardCheckboxMenuItem, @NonNull final JCheckBoxMenuItem autoEnterCheckboxMenuItem) { @@ -55,7 +56,7 @@ public void actionPerformed(ActionEvent e) { copyToClipboardCheckboxMenuItem.setSelected(true); Application.getContext().getModelSettings().setPressEnterAfterPaste(false); autoEnterCheckboxMenuItem.setSelected(false); - Application.getContext().getGui().labelTargetWindow.setText(Constants.PASTE_BUT_DO_NOT_RUN_MODE); + GuiUtils.showTargetWindowLabelMessage(Constants.PASTE_BUT_DO_NOT_RUN_MODE, 1); Application.getContext().startWindowInterceptorRunner(); log.debug("TopMenu - Focus & paste but do not run mode"); } diff --git a/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/LockingActionListener.java b/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/LockingActionListener.java index 6c3640f..ab7c172 100644 --- a/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/LockingActionListener.java +++ b/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/LockingActionListener.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -40,8 +40,8 @@ public class LockingActionListener implements ActionListener { /** * Constructor. * - * @param modelActiveWindow {@link ModelActiveWindow} - * @param viewActiveWindow {@link ViewActiveWindow} + * @param modelActiveWindow {@code ModelActiveWindow} + * @param viewActiveWindow {@code ViewActiveWindow} */ public LockingActionListener(@NonNull final ModelActiveWindow modelActiveWindow, @NonNull final ViewActiveWindow viewActiveWindow) { diff --git a/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/PathMenuItemActionListener.java b/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/PathMenuItemActionListener.java index dbc5c35..1e366e3 100644 --- a/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/PathMenuItemActionListener.java +++ b/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/PathMenuItemActionListener.java @@ -1,3 +1,21 @@ +/** + * Keepaste - The keep and paste program (http://www.keepaste.com) + * Copyright (C) 2023 Tamir Krispis + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + *

+ * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + package com.keepaste.logic.actionlisteners.topmenu; import com.keepaste.logic.Application; diff --git a/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/ThemesMenuItemActionListener.java b/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/ThemesMenuItemActionListener.java index e48ba03..3c5cb60 100644 --- a/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/ThemesMenuItemActionListener.java +++ b/logic/src/main/java/com/keepaste/logic/actionlisteners/topmenu/ThemesMenuItemActionListener.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ diff --git a/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/AddGroupTreeNodeActionListener.java b/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/AddGroupTreeNodeActionListener.java index be551e1..bd5afeb 100644 --- a/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/AddGroupTreeNodeActionListener.java +++ b/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/AddGroupTreeNodeActionListener.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ diff --git a/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/AddKeepTreeNodeActionListener.java b/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/AddKeepTreeNodeActionListener.java index 485cb44..b23446b 100644 --- a/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/AddKeepTreeNodeActionListener.java +++ b/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/AddKeepTreeNodeActionListener.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ diff --git a/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/BaseTreeNodeActionListener.java b/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/BaseTreeNodeActionListener.java index c6194fa..a4b2cfa 100644 --- a/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/BaseTreeNodeActionListener.java +++ b/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/BaseTreeNodeActionListener.java @@ -1,3 +1,21 @@ +/** + * Keepaste - The keep and paste program (http://www.keepaste.com) + * Copyright (C) 2023 Tamir Krispis + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + *

+ * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + package com.keepaste.logic.actionlisteners.treenodes; import com.keepaste.logic.views.ViewTree; @@ -6,9 +24,9 @@ import java.awt.event.ActionListener; +@Getter public abstract class BaseTreeNodeActionListener implements ActionListener { - @Getter private final ViewTree viewTree; protected BaseTreeNodeActionListener(@NonNull final ViewTree viewTree) { diff --git a/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/DeleteTreeNodeActionListener.java b/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/DeleteTreeNodeActionListener.java index feafa08..dd10ff2 100644 --- a/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/DeleteTreeNodeActionListener.java +++ b/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/DeleteTreeNodeActionListener.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -35,7 +35,7 @@ public class DeleteTreeNodeActionListener extends BaseTreeNodeActionListener { /** * Constructor. * - * @param viewTree {@link ViewTree} + * @param viewTree {@code ViewTree} */ public DeleteTreeNodeActionListener(@NonNull final ViewTree viewTree) { super(viewTree); diff --git a/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/EditMenuItemActionListener.java b/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/EditMenuItemActionListener.java index 3639d5e..f1e4204 100644 --- a/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/EditMenuItemActionListener.java +++ b/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/EditMenuItemActionListener.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ diff --git a/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/ExportKeepsActionListener.java b/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/ExportKeepsActionListener.java index 2000c64..33a02de 100644 --- a/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/ExportKeepsActionListener.java +++ b/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/ExportKeepsActionListener.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -38,7 +38,7 @@ public class ExportKeepsActionListener extends BaseTreeNodeActionListener { /** * Constructor. * - * @param viewTree {@link ViewTree} + * @param viewTree {@code ViewTree} */ public ExportKeepsActionListener(@NonNull final ViewTree viewTree) { super(viewTree); diff --git a/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/ImportKeepsActionListener.java b/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/ImportKeepsActionListener.java index fba35c7..b66947b 100644 --- a/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/ImportKeepsActionListener.java +++ b/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/ImportKeepsActionListener.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -36,7 +36,7 @@ public class ImportKeepsActionListener extends BaseTreeNodeActionListener { /** * Constructor. * - * @param viewTree the Keep's {@link ViewTree} + * @param viewTree the Keep's {@code ViewTree} */ public ImportKeepsActionListener(@NonNull final ViewTree viewTree) { super(viewTree); @@ -47,9 +47,6 @@ public void actionPerformed(ActionEvent e) { try { // Create a file chooser dialog JFileChooser fileChooser = new JFileChooser(); - // Set the file filter to accept only JSON files -// FileNameExtensionFilter filter = new FileNameExtensionFilter("JSON Files", "json"); -// fileChooser.setFileFilter(filter); // Show the file chooser dialog int result = fileChooser.showOpenDialog(Application.getContext().getGui()); diff --git a/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/RenameGroupTreeNodeActionListener.java b/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/RenameGroupTreeNodeActionListener.java index fb2d31b..22250da 100644 --- a/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/RenameGroupTreeNodeActionListener.java +++ b/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/RenameGroupTreeNodeActionListener.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ diff --git a/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/RunKeepWithRefreshedParametersActionListener.java b/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/RunKeepWithRefreshedParametersActionListener.java index b7330d2..f5c0b8f 100644 --- a/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/RunKeepWithRefreshedParametersActionListener.java +++ b/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/RunKeepWithRefreshedParametersActionListener.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ diff --git a/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/TreeNodeMouseListener.java b/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/TreeNodeMouseListener.java new file mode 100644 index 0000000..6021bc3 --- /dev/null +++ b/logic/src/main/java/com/keepaste/logic/actionlisteners/treenodes/TreeNodeMouseListener.java @@ -0,0 +1,93 @@ +/** + * Keepaste - The keep and paste program (http://www.keepaste.com) + * Copyright (C) 2023 Tamir Krispis + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + *

+ * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.keepaste.logic.actionlisteners.treenodes; + +import com.keepaste.logic.Application; +import com.keepaste.logic.models.Keep; +import com.keepaste.logic.models.KeepNode; +import com.keepaste.logic.models.KeepsGroup; +import lombok.Getter; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.TreePath; +import java.awt.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +public class TreeNodeMouseListener extends MouseAdapter { + + @Getter + private DefaultMutableTreeNode selectedNode; + @Getter + private DefaultMutableTreeNode parentOfSelectedNode; + private final JPopupMenu treeKeepNodeContextMenu; + private final JPopupMenu treeGroupNodeContextMenu; + + public TreeNodeMouseListener(JPopupMenu treeGroupNodeContextMenu, + JPopupMenu treeKeepNodeContextMenu) { + this.treeKeepNodeContextMenu = treeKeepNodeContextMenu; + this.treeGroupNodeContextMenu = treeGroupNodeContextMenu; + } + + @Override + public void mousePressed(MouseEvent e) { + treeGroupNodeContextMenu.setVisible(false); + JTree tree = Application.getContext().getGui().tree; + TreePath path = tree.getPathForLocation(e.getX(), e.getY()); + tree.setSelectionPath(path); + DefaultMutableTreeNode node = (DefaultMutableTreeNode) + tree.getLastSelectedPathComponent(); + + if (node == null) { + //Nothing is selected. + return; + } + + if (SwingUtilities.isRightMouseButton(e) || e.getButton() == MouseEvent.BUTTON3 || e.isControlDown()) { + KeepNode keepNode = (KeepNode) node.getUserObject(); + if (node.isLeaf() && !(keepNode instanceof KeepsGroup)) { + // Keep node + selectedNode = node; + parentOfSelectedNode = (DefaultMutableTreeNode) node.getParent(); + EventQueue.invokeLater(() -> treeKeepNodeContextMenu.show(e.getComponent(), e.getX(), e.getY())); + } else { + // Keep group node + selectedNode = node; + parentOfSelectedNode = (DefaultMutableTreeNode) node.getParent(); + EventQueue.invokeLater(() -> treeGroupNodeContextMenu.show(e.getComponent(), e.getX(), e.getY())); + } + } else if (SwingUtilities.isLeftMouseButton(e)) { + tree.setSelectionPath(tree.getPathForLocation(e.getX(), e.getY())); + + DefaultMutableTreeNode clickedOnNode = (DefaultMutableTreeNode) + tree.getLastSelectedPathComponent(); + + if (clickedOnNode == null) { + //Nothing is selected. + return; + } + + KeepNode keepNode = (KeepNode) clickedOnNode.getUserObject(); + if (e.getClickCount() == 2 && clickedOnNode.isLeaf() && !(keepNode instanceof KeepsGroup)) { + Application.getContext().getKeepExecutionManager().executeKeepOnWindow((Keep) clickedOnNode.getUserObject()); + } + } + } +} diff --git a/logic/src/main/java/com/keepaste/logic/common/BaseSubject.java b/logic/src/main/java/com/keepaste/logic/common/BaseSubject.java index 47db10c..8946cc0 100644 --- a/logic/src/main/java/com/keepaste/logic/common/BaseSubject.java +++ b/logic/src/main/java/com/keepaste/logic/common/BaseSubject.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -34,7 +34,7 @@ public abstract class BaseSubject implements Subject { /** * Adds an observer to the subject. * - * @param observer the {@link Observer} + * @param observer the {@code Observer} */ @Override public void registerObserver(@NonNull final Observer observer) { @@ -44,7 +44,7 @@ public void registerObserver(@NonNull final Observer observer) { /** * Removes an observer from the subject. * - * @param observer the {@link Observer} + * @param observer the {@code Observer} */ @Override public void removeObserver(@NonNull final Observer observer) { diff --git a/logic/src/main/java/com/keepaste/logic/common/Constants.java b/logic/src/main/java/com/keepaste/logic/common/Constants.java index 71ea3d9..d35a6cb 100644 --- a/logic/src/main/java/com/keepaste/logic/common/Constants.java +++ b/logic/src/main/java/com/keepaste/logic/common/Constants.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -29,4 +29,6 @@ private Constants() { public static final String ONLY_COPY_MODE = "ONLY COPY MODE"; public static final String PASTE_BUT_DO_NOT_RUN_MODE = "PASTE BUT DO NOT RUN MODE"; public static final String FULL_ON_MODE = "FULL ON MODE"; + public static final String NO_ACTIVE_WINDOW = "No active window"; + } diff --git a/logic/src/main/java/com/keepaste/logic/common/Observer.java b/logic/src/main/java/com/keepaste/logic/common/Observer.java index 66f4dc5..07acf3c 100644 --- a/logic/src/main/java/com/keepaste/logic/common/Observer.java +++ b/logic/src/main/java/com/keepaste/logic/common/Observer.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -28,7 +28,7 @@ public interface Observer { /** * The method that the Subject will call once it needs to update the object with any change to the model in context. * - * @param model the {@link Model} in context + * @param model the {@code Model} in context */ void updateObserver(Model model); } diff --git a/logic/src/main/java/com/keepaste/logic/common/Subject.java b/logic/src/main/java/com/keepaste/logic/common/Subject.java index d47a951..d4c67cc 100644 --- a/logic/src/main/java/com/keepaste/logic/common/Subject.java +++ b/logic/src/main/java/com/keepaste/logic/common/Subject.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ diff --git a/logic/src/main/java/com/keepaste/logic/controllers/BaseController.java b/logic/src/main/java/com/keepaste/logic/controllers/BaseController.java index a8d33dd..6d8b610 100644 --- a/logic/src/main/java/com/keepaste/logic/controllers/BaseController.java +++ b/logic/src/main/java/com/keepaste/logic/controllers/BaseController.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -20,12 +20,10 @@ import com.keepaste.logic.common.BaseSubject; import com.keepaste.logic.common.Observer; -import com.keepaste.logic.views.View; -import org.apache.maven.model.Model; /** - * This class is a base controller (MVC), all controllers are both subjects and observers as they observe changes in {@link Model} - * and notifies the relevant {@link View}. + * This class is a base controller (MVC), all controllers are both subjects and observers as they observe changes in {@code Model} + * and notifies the relevant {@code View}. */ public abstract class BaseController extends BaseSubject implements Observer { // doesn't hold any specific implementation diff --git a/logic/src/main/java/com/keepaste/logic/controllers/ControllerActiveWindow.java b/logic/src/main/java/com/keepaste/logic/controllers/ControllerActiveWindow.java index 79990bd..5c8287f 100644 --- a/logic/src/main/java/com/keepaste/logic/controllers/ControllerActiveWindow.java +++ b/logic/src/main/java/com/keepaste/logic/controllers/ControllerActiveWindow.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -20,7 +20,6 @@ import com.keepaste.logic.common.BaseSubject; import com.keepaste.logic.common.Observer; -import com.keepaste.logic.common.Subject; import com.keepaste.logic.models.Model; import com.keepaste.logic.models.ModelActiveWindow; import com.keepaste.logic.models.WindowInformation; @@ -29,16 +28,16 @@ /** * This class will control the event whenever a new active window is intercepted. - * The controller class is an {@link Observer}, it listens on changes coming from the Model. - * And, it is also a {@link Subject}, after doing its logic, it will call updateObserver on the view which observe the controller. + * The controller class is an {@code Observer}, it listens on changes coming from the Model. + * And, it is also a {@code Subject}, after doing its logic, it will call updateObserver on the view which observe the controller. */ public class ControllerActiveWindow extends BaseSubject implements Observer { /** * Constructor. * - * @param modelActiveWindow {@link ModelActiveWindow} - * @param viewActiveWindow {@link ViewActiveWindow} + * @param modelActiveWindow {@code ModelActiveWindow} + * @param viewActiveWindow {@code ViewActiveWindow} */ public ControllerActiveWindow(@NonNull final ModelActiveWindow modelActiveWindow, @NonNull final ViewActiveWindow viewActiveWindow) { diff --git a/logic/src/main/java/com/keepaste/logic/controllers/ControllerLookAndFeel.java b/logic/src/main/java/com/keepaste/logic/controllers/ControllerLookAndFeel.java index 626baba..ccb46ed 100644 --- a/logic/src/main/java/com/keepaste/logic/controllers/ControllerLookAndFeel.java +++ b/logic/src/main/java/com/keepaste/logic/controllers/ControllerLookAndFeel.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -28,7 +28,7 @@ import lombok.NonNull; /** - * This class is the {@link BaseController} for look and feel changes from the {@link ModelSettings}. + * This class is the {@code BaseController} for look and feel changes from the {@code ModelSettings}. */ public class ControllerLookAndFeel extends BaseSubject implements Observer { @@ -36,8 +36,8 @@ public class ControllerLookAndFeel extends BaseSubject implements Observer { /** * Constructor. * - * @param modelSettings {@link ModelSettings} - * @param viewLookAndFeel {@link ViewLookAndFeel} + * @param modelSettings {@code ModelSettings} + * @param viewLookAndFeel {@code ViewLookAndFeel} */ public ControllerLookAndFeel(@NonNull final ModelSettings modelSettings, @NonNull final ViewLookAndFeel viewLookAndFeel) { diff --git a/logic/src/main/java/com/keepaste/logic/controllers/ControllerTopMenu.java b/logic/src/main/java/com/keepaste/logic/controllers/ControllerTopMenu.java index 262b417..35824a3 100644 --- a/logic/src/main/java/com/keepaste/logic/controllers/ControllerTopMenu.java +++ b/logic/src/main/java/com/keepaste/logic/controllers/ControllerTopMenu.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -28,16 +28,16 @@ import javax.swing.*; /** - * This class is a {@link BaseController} for the locking menu item. + * This class is a {@code BaseController} for the locking menu item. */ public class ControllerTopMenu extends BaseSubject implements Observer { /** * Constructor. * - * @param modelActiveWindow {@link ModelActiveWindow} - * @param viewActiveWindow {@link ViewActiveWindow} - * @param lockingMenuItem the locking {@link JMenuItem} + * @param modelActiveWindow {@code ModelActiveWindow} + * @param viewActiveWindow {@code ViewActiveWindow} + * @param lockingMenuItem the locking {@code JMenuItem} */ public ControllerTopMenu(@NonNull final ModelActiveWindow modelActiveWindow, @NonNull final ViewActiveWindow viewActiveWindow, diff --git a/logic/src/main/java/com/keepaste/logic/controllers/ControllerTree.java b/logic/src/main/java/com/keepaste/logic/controllers/ControllerTree.java index ac77c1b..41a8df3 100644 --- a/logic/src/main/java/com/keepaste/logic/controllers/ControllerTree.java +++ b/logic/src/main/java/com/keepaste/logic/controllers/ControllerTree.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -27,7 +27,7 @@ import java.io.IOException; /** - * This class is a {@link BaseController} observes for changes in the {@link ModelTree} and notifies the {@link ViewTree}. + * This class is a {@code BaseController} observes for changes in the {@code ModelTree} and notifies the {@code ViewTree}. */ public class ControllerTree extends BaseController { @@ -36,8 +36,8 @@ public class ControllerTree extends BaseController { /** * Constructor. * - * @param modelTree {@link ModelTree} - * @param viewTree {@link ViewTree} + * @param modelTree {@code ModelTree} + * @param viewTree {@code ViewTree} * @throws IOException on error */ public ControllerTree(@NonNull final ModelTree modelTree, diff --git a/logic/src/main/java/com/keepaste/logic/exceptions/KeepExecutionException.java b/logic/src/main/java/com/keepaste/logic/exceptions/KeepExecutionException.java index feb2b22..3e0d9e6 100644 --- a/logic/src/main/java/com/keepaste/logic/exceptions/KeepExecutionException.java +++ b/logic/src/main/java/com/keepaste/logic/exceptions/KeepExecutionException.java @@ -1,3 +1,21 @@ +/** + * Keepaste - The keep and paste program (http://www.keepaste.com) + * Copyright (C) 2023 Tamir Krispis + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + *

+ * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + package com.keepaste.logic.exceptions; import lombok.NonNull; diff --git a/logic/src/main/java/com/keepaste/logic/exceptions/KeepParameterExecutionException.java b/logic/src/main/java/com/keepaste/logic/exceptions/KeepParameterExecutionException.java index 8d19d3c..f362921 100644 --- a/logic/src/main/java/com/keepaste/logic/exceptions/KeepParameterExecutionException.java +++ b/logic/src/main/java/com/keepaste/logic/exceptions/KeepParameterExecutionException.java @@ -1,3 +1,21 @@ +/** + * Keepaste - The keep and paste program (http://www.keepaste.com) + * Copyright (C) 2023 Tamir Krispis + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + *

+ * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + package com.keepaste.logic.exceptions; import lombok.NonNull; diff --git a/logic/src/main/java/com/keepaste/logic/exceptions/KeepasteGenericException.java b/logic/src/main/java/com/keepaste/logic/exceptions/KeepasteGenericException.java index 31dd792..8b92ea5 100644 --- a/logic/src/main/java/com/keepaste/logic/exceptions/KeepasteGenericException.java +++ b/logic/src/main/java/com/keepaste/logic/exceptions/KeepasteGenericException.java @@ -1,3 +1,21 @@ +/** + * Keepaste - The keep and paste program (http://www.keepaste.com) + * Copyright (C) 2023 Tamir Krispis + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + *

+ * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + package com.keepaste.logic.exceptions; import lombok.NonNull; diff --git a/logic/src/main/java/com/keepaste/logic/interceptors/WindowInterceptorRunner.java b/logic/src/main/java/com/keepaste/logic/interceptors/WindowInterceptorRunner.java index d359276..45fdad3 100644 --- a/logic/src/main/java/com/keepaste/logic/interceptors/WindowInterceptorRunner.java +++ b/logic/src/main/java/com/keepaste/logic/interceptors/WindowInterceptorRunner.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -28,7 +28,7 @@ import java.util.concurrent.TimeUnit; /** - * This class is a {@link Runnable} that runs in parallel thread and samples the currently active window. + * This class is a {@code Runnable} that runs in parallel thread and samples the currently active window. * The active window is where Keeps will be pasted upon execution of a Keep. */ @Log4j2 diff --git a/logic/src/main/java/com/keepaste/logic/managers/KeepExecutionManager.java b/logic/src/main/java/com/keepaste/logic/managers/KeepExecutionManager.java index decfd27..6be84f2 100644 --- a/logic/src/main/java/com/keepaste/logic/managers/KeepExecutionManager.java +++ b/logic/src/main/java/com/keepaste/logic/managers/KeepExecutionManager.java @@ -1,54 +1,53 @@ +/** + * Keepaste - The keep and paste program (http://www.keepaste.com) + * Copyright (C) 2023 Tamir Krispis + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + *

+ * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + package com.keepaste.logic.managers; import com.keepaste.logic.Application; import com.keepaste.logic.exceptions.KeepExecutionException; -import com.keepaste.logic.exceptions.KeepParameterExecutionException; import com.keepaste.logic.models.Keep; -import com.keepaste.logic.models.KeepParameter; -import com.keepaste.logic.models.WindowInformation; -import com.keepaste.logic.utils.ClipboardUtils; import com.keepaste.logic.utils.FileSystemUtils; -import com.keepaste.logic.utils.KeyboardUtils; import com.keepaste.logic.utils.OperatingSystemUtils; -import lombok.Getter; -import lombok.NonNull; import lombok.extern.log4j.Log4j2; -import org.apache.commons.lang3.StringUtils; import javax.swing.*; -import java.awt.event.KeyListener; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; -import static com.keepaste.logic.common.Constants.ONLY_COPY_MODE; /** * This class hods methods related to Keep execution. */ @Log4j2 public final class KeepExecutionManager { - public static final String FAILED_TO_EXECUTE_KEEP = "Failed to execute keep"; - @Getter - private static final Map GLOBAL_PARAMETER_VALUES_MAP = new HashMap<>(); + public static final Map GLOBAL_PARAMETER_VALUES_MAP = new HashMap<>(); public static final int COMMAND_EXEC_TIMEOUT = 15; private String shell = "/bin/bash"; /** * Constructor. - * - * @throws IOException on error - * @throws InterruptedException on error */ public KeepExecutionManager() { if (OperatingSystemUtils.getOperatingSystemType() != OperatingSystemUtils.OperatingSystemType.WINDOWS) { @@ -69,18 +68,18 @@ public KeepExecutionManager() { /** - * Executed a selected {@link Keep} on the currently active window. + * Executed a selected {@code Keep} on the currently active window. * - * @param keep the {@link Keep} to execute + * @param keep the {@code Keep} to execute */ public void executeKeepOnWindow(Keep keep) { executeKeepOnWindow(keep, false); } /** - * Executed a selected {@link Keep} on the currently active window. + * Executed a selected {@code Keep} on the currently active window. * - * @param keep the {@link Keep} to execute + * @param keep the {@code Keep} to execute * @param refreshParameters true if we wish to clear the existing global parameters and have a fresh start */ public void executeKeepOnWindow(Keep keep, boolean refreshParameters) { @@ -88,119 +87,34 @@ public void executeKeepOnWindow(Keep keep, boolean refreshParameters) { "Executing Keep [{}] on window [{}] with refresh parameters [{}]", keep.toStringAll(), Application.getContext().getModelActiveWindow(), refreshParameters); - // clearing selection from tree not to accidentally executing the selected node when the user presses the 'enter' - // key (like on dialogs) - var currentSelectionPath = Application.getContext().getGui().tree.getSelectionPath(); - Application.getContext().getGui().tree.clearSelection(); - // stopping window interception while running the Keep to prevent pasting on wrong window Application.getContext().stopWindowInterceptorRunner(); - // keeping the active window that the user meant to paste on - WindowInformation currentlyActiveWindow = Application.getContext().getModelActiveWindow().getActiveWindow(); - // validating that only one keep is running at a time - if (Application.getContext().isKeepCurrentlyRunning()) { - JOptionPane.showMessageDialog(Application.getContext().getGui(), - "Can only run one Keep at a time, please wait for the other Keep to finish or abort it", - "One Keep at a time please", JOptionPane.WARNING_MESSAGE); - return; - } + if (isAKeepAlreadyRunning()) return; + // setting keep is running Application.getContext().setKeepCurrentlyRunning(true); - // preventing from enter being pressed on dialogs shown while manipulating parameters from triggering the tree's - // key listener (prevents from running another keep by mistake when pressing ENTER) - Optional viewTreeKeyListener = - Arrays.stream(Application.getContext().getGui().tree.getKeyListeners()) - .filter(keyListener -> keyListener.getClass().getName().contains("ViewTree")) - .findFirst(); - viewTreeKeyListener.ifPresent(keyListener -> Application.getContext().getGui().tree.removeKeyListener(keyListener)); - - Application.getContext().getGui().labelBackground.setText("Executing keep..."); - Application.getContext().getGui().labelBackground.setVisible(true); - SwingWorker worker = new SwingWorker<>() { - @Override - protected Void doInBackground() { - String keepToExecute = manipulateParameters(keep, refreshParameters); - log.info("Final Keep to execute [{}]", keepToExecute); - if (!StringUtils.isEmpty(keepToExecute)) { - - copyToClipboard(keepToExecute); + showExecutingKeepLabel(); - if (!Application.getContext().getModelSettings().isFocusOnWindowAndPaste()) { - handleOnlyCopy(); - } else { - if (isFocusOnActiveWindow(currentlyActiveWindow)) { - pasteKeep(); - pressEnter(keep); - } else { - handleWrongTargetWindow(); - } - } - } - return null; - } - - @Override - protected void done() { - Application.getContext().getGui().labelBackground.setVisible(false); - Application.getContext().setKeepCurrentlyRunning(false); - - viewTreeKeyListener.ifPresent(keyListener -> Application.getContext().getGui().tree.addKeyListener(keyListener)); - - Application.getContext().setKeepCurrentlyRunning(false); - Application.getContext().startWindowInterceptorRunner(); - - Application.getContext().getGui().tree.setSelectionPath(currentSelectionPath); - - log.debug("Keep execution finished"); - } - }; - worker.execute(); - } - - private static void copyToClipboard(String keepToExecute) { - // setting final keep command to the clipboard - log.debug("Setting [{}] to clipboard", keepToExecute); - ClipboardUtils.setValue(keepToExecute); + // executing the command on another thread not to block the main GUI thread + new KeepExecutionWorker(keep, refreshParameters).execute(); } - private static void handleWrongTargetWindow() { - JOptionPane.showMessageDialog(Application.getContext().getGui(), - "Seems like keepaste is not focused on the desired window, please try again...", - "Warning", - JOptionPane.WARNING_MESSAGE); - log.debug("Not focused on correct window so not pasting and pressing ENTER"); - } - - private static void pressEnter(Keep keep) { - if (Application.getContext().getModelSettings().isPressEnterAfterPaste()) { - if (keep.isNeverPressEnter()) { - log.debug("keep is set to never press 'enter' so it didn't"); - } else { - log.debug("Imitating \"ENTER\" key"); - KeyboardUtils.enter(); - } - } - } - - private static void pasteKeep() { - if (Application.getContext().getModelSettings().isFocusOnWindowAndPaste()) { - log.debug("pasting ".concat(ClipboardUtils.getValue().toString())); - Application.getContext().getWindowManager().paste(); - } + private static void showExecutingKeepLabel() { + Application.getContext().getGui().labelBackground.setText("Executing keep..."); + Application.getContext().getGui().labelBackground.setVisible(true); } - private static boolean isFocusOnActiveWindow(WindowInformation currentlyActiveWindow) { - if (currentlyActiveWindow == null) { + private static boolean isAKeepAlreadyRunning() { + if (Application.getContext().isKeepCurrentlyRunning()) { JOptionPane.showMessageDialog(Application.getContext().getGui(), - "Please select a window by clicking on it in order to run Keeps", - "No active window", JOptionPane.WARNING_MESSAGE); - throw new KeepExecutionException("No active window is set"); - } else { - return Application.getContext().getWindowManager().focusOnActiveWindow(currentlyActiveWindow); + "Can only run one Keep at a time, please wait for the other Keep to finish or abort it", + "One Keep at a time please", JOptionPane.WARNING_MESSAGE); + return true; } + return false; } /** @@ -297,266 +211,4 @@ public List executeCommand(List commandLines, boolean defaultPat inputStream.close(); return outputLines; } - - /** - * Will manage a Keep parameter. - * - * @param parameter the {@link KeepParameter} to handle - * @param keep the {@link Keep} in context - * @param isRefreshGlobalParameters if to refresh the global parameters - * @param currentParameterValuesMap the current global parameters cache - * @throws Exception in case of any error - */ - private void executeParameter( - @NonNull final KeepParameter parameter, - @NonNull final Keep keep, - final boolean isRefreshGlobalParameters, - @NonNull final Map currentParameterValuesMap) { - - // in case of this is a global parameter, checking if the value already exist for it - validateValueSetForGlobalParam(parameter, currentParameterValuesMap, isRefreshGlobalParameters); - - // in case the value doesn't exist yet - if (!ifParamValueSet(parameter, currentParameterValuesMap)) { - - // Array-type parameter - List paramValues = handleArrayTypeParamPhrase(parameter); - - // Command-type parameter - if (paramValues == null) { - paramValues = handleCommandTypeParamPhrase(parameter, keep, currentParameterValuesMap, isRefreshGlobalParameters); - } - - String selectedParamValue = null; - if (paramValues != null) { - selectedParamValue = displayParamValuesOptionsDialog(parameter, paramValues); - } else { - // free text parameter - log.debug("Parameter [{}] is of a free-text type", parameter); - - selectedParamValue = JOptionPane.showInputDialog( - Application.getContext().getGui().getContentPane(), - String.format("Input a value for %s", parameter.getName()), - "Set parameter value", - JOptionPane.QUESTION_MESSAGE); - log.debug("Value of [{}] was set to free-text parameter [{}]", selectedParamValue, parameter); - } - - if (StringUtils.isEmpty(selectedParamValue)) { - JOptionPane.showMessageDialog( - Application.getContext().getGui(), - String.format("Value for parameter \"%s\" is not set, cancelling processing the Keep", - parameter.getName()) - ); - log.debug( - "The user probably clicked on the cancel button on the dialog to set a free-text for " - + "the parameter [{}]", parameter); - throw new KeepParameterExecutionException("User cancelled"); - } else { - if (keep.getPhrase() != null && !StringUtils.isEmpty(selectedParamValue)) { - addParamValueToCurrentValues(parameter, currentParameterValuesMap, selectedParamValue); - addParamValueToGlobalValues(parameter, selectedParamValue); - } - } - } - } - - private static void addParamValueToCurrentValues( - KeepParameter parameter, - Map currentParameterValuesMap, - String selectedParamValue) { - log.debug("Adding value of [{} for parameter [{}] to the current parameters values map", selectedParamValue, parameter); - currentParameterValuesMap.put(parameter.getName(), selectedParamValue); - } - - private static void addParamValueToGlobalValues(KeepParameter parameter, String selectedParamValue) { - if (parameter.isGlobal()) { - log.debug( - "As it is set to be global, adding value of [{}] for parameter [{}] to the global " - + "parameters values map", selectedParamValue, parameter); - GLOBAL_PARAMETER_VALUES_MAP.put(parameter.getName(), selectedParamValue); - } - } - - private String displayParamValuesOptionsDialog(KeepParameter parameter, List keepResult) { - String selectedParamValue; - log.debug("Showing the user a dialog to choose a value for tha parameter [{}]", parameter); - selectedParamValue = (String) JOptionPane.showInputDialog( - Application.getContext().getGui().getContentPane(), - String.format("Choose a value for %s", parameter.getName()), - "Set parameter value", - JOptionPane.QUESTION_MESSAGE, - null, - parseToLineByLine(keepResult), - null); - log.debug("User selected the value [{}] for parameter [{}]", selectedParamValue, parameter); - if (StringUtils.isEmpty(selectedParamValue)) { - JOptionPane.showMessageDialog( - Application.getContext().getGui(), - String.format( - "Value for parameter \"%s\" is not set, cancelling processing the Keep", - parameter.getName()) - ); - log.debug( - "The user probably clicked on the cancel button on the dialog to choose a value " - + "for the parameter [{}]", parameter); - throw new KeepParameterExecutionException("User cancelled"); - } - return selectedParamValue; - } - - private List handleCommandTypeParamPhrase( - KeepParameter parameter, Keep keep, Map currentParameterValuesMap, boolean isRefreshGlobalParameters) { - List keepResult = null; - - if (!isFreeTextTypeParam(parameter)) { - try { - String paramKeepString = parameter.getPhrase(); - - log.debug("Parameter [{}] is of Command type, executing param command [{}]", parameter, paramKeepString); - paramKeepString = populateParamPhraseWithAlreadySetParams(parameter, currentParameterValuesMap, paramKeepString); - - // checking if the param Keep uses parameters as well, and if so, executing those first - for (KeepParameter innerParameter : keep.getParameters()) { - if (paramKeepString.contains(String.format("<%s>", innerParameter.getName()))) { - // this parameter uses another one, so executing it first - executeParameter(innerParameter, keep, isRefreshGlobalParameters, currentParameterValuesMap); - paramKeepString = paramKeepString.replace( - String.format("<%s>", innerParameter.getName()), - currentParameterValuesMap.get(innerParameter.getName())); - } - } - - keepResult = executeCommand(paramKeepString); - log.debug("Parameter [{}], Keep result=[{}]", parameter, keepResult); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } catch (Exception e) { - JOptionPane.showMessageDialog( - Application.getContext().getGui().getContentPane(), - String.format( - "Failed to run Keep \"%s\" for parameter \"%s\". %s.", - parameter.getPhrase(), parameter.getName(), e.getMessage()), - "Error when running a Keep", - JOptionPane.ERROR_MESSAGE - ); - } - } - return keepResult; - } - - - private static String populateParamPhraseWithAlreadySetParams( - KeepParameter parameter, Map currentParameterValuesMap, String paramKeepString) { - // filling existing parameters values if already chosen and used in the next parameter - for (Map.Entry currParam : currentParameterValuesMap.entrySet()) { - paramKeepString = paramKeepString.replace(String.format("<%s>", currParam.getKey()), currParam.getValue()); - log.debug("Parameter [{}] was taken from current run parameters, selected value=[{}]", parameter, currParam.getValue()); - } - return paramKeepString; - } - - private static boolean isFreeTextTypeParam(KeepParameter parameter) { - return parameter.getPhrase() == null || parameter.getPhrase().isEmpty(); - } - - private static boolean ifParamValueSet(KeepParameter parameter, Map currentParameterValuesMap) { - return currentParameterValuesMap.containsKey(parameter.getName()); - } - - private static void setParamValueFromGlobal(KeepParameter parameter, Map currentParameterValuesMap) { - String selectedParamValue; - selectedParamValue = GLOBAL_PARAMETER_VALUES_MAP.get(parameter.getName()); - currentParameterValuesMap.put(parameter.getName(), selectedParamValue); - log.debug("Parameter [{}] was taken from global parameters, selected value=[{}]", parameter, selectedParamValue); - } - - private static boolean isParamGlobalValueSet(KeepParameter parameter, boolean refreshParameters) { - return !refreshParameters && parameter.isGlobal() && GLOBAL_PARAMETER_VALUES_MAP.containsKey(parameter.getName()); - } - - - /* ***************** PRIVATE METHODS ***************** */ - - private String manipulateParameters(Keep keep, boolean refreshParameters) { - log.debug("Manipulating parameters"); - // manipulating parameters - - String keepToExecute = keep.getPhrase(); - Map currentParameterValuesMap = new HashMap<>(); - if (keep.getParameters() != null && !keep.getParameters().isEmpty()) { - for (KeepParameter parameter : keep.getParameters()) { - log.debug("Manipulating parameter [{}]", parameter); - - try { - executeParameter(parameter, keep, refreshParameters, currentParameterValuesMap); - } catch (KeepParameterExecutionException ex) { - log.error(FAILED_TO_EXECUTE_KEEP, ex); - return null; // cancelling - } - } - - for (Map.Entry entry : currentParameterValuesMap.entrySet()) { - keepToExecute = keepToExecute.replace(String.format("<%s>", entry.getKey()), entry.getValue()); - } - } - - return keepToExecute; - } - - private String[] parseToLineByLine(List stringToParse) { - if (stringToParse.size() == 1 && stringToParse.get(0).startsWith("[") && stringToParse.get(0).endsWith("]")) { - // this is a one-liner json array, splitting it, the next 'if' statement will process it - String jsonArr = stringToParse.get(0); - jsonArr = jsonArr.substring(1, jsonArr.length() - 1); - stringToParse = Arrays.asList(jsonArr.split(",")); - } - - if (!stringToParse.isEmpty() && stringToParse.get(0).equals("[")) { - // in case of a json array, an option to return visible and actual values for the dropdown lists (name of ec2 - // instance to display, the id to use on the command) - // parse from a json array - stringToParse.remove(0); // the opening '[' - stringToParse.remove(stringToParse.size() - 1); // the closing ']' - stringToParse.replaceAll(s -> s.replace("\",", "").replace("\"", "").trim()); // removing ", and " - } - - Collections.sort(stringToParse); - - return stringToParse.toArray(new String[stringToParse.size()]); - } - - private void handleOnlyCopy() { - new Thread(() -> { - Application.getContext().getGui().labelTargetWindow.setText("Keep copied, ready to paste..."); - try { - TimeUnit.SECONDS.sleep(2); - } catch (InterruptedException e) { - log.error("Sleep interrupted exception", e); - Thread.currentThread().interrupt(); - } - Application.getContext().getGui().labelTargetWindow.setText(ONLY_COPY_MODE); - }).start(); - } - - private void validateValueSetForGlobalParam(KeepParameter parameter, - Map currentParameterValuesMap, - boolean refreshParameters) { - // checking if we already have a value for this parameter on the global parameters (unless refresh parameters was chosen) - if (isParamGlobalValueSet(parameter, refreshParameters)) { - setParamValueFromGlobal(parameter, currentParameterValuesMap); - } - } - - private List handleArrayTypeParamPhrase(KeepParameter parameter) { - List keepResult = null; - if (!isFreeTextTypeParam(parameter) && parameter.getPhrase().startsWith("[")) { - // predefined array of values - keepResult = Arrays.stream(parameter.getPhrase().substring(1, parameter.getPhrase().length() - 1) - .split(",")).map(String::trim) - .collect(Collectors.toList()); - log.debug("Parameter [{}] is of array type, values=[{}]", parameter, keepResult); - } - return keepResult; - } } diff --git a/logic/src/main/java/com/keepaste/logic/managers/KeepExecutionWorker.java b/logic/src/main/java/com/keepaste/logic/managers/KeepExecutionWorker.java new file mode 100644 index 0000000..c376db8 --- /dev/null +++ b/logic/src/main/java/com/keepaste/logic/managers/KeepExecutionWorker.java @@ -0,0 +1,547 @@ +/** + * Keepaste - The keep and paste program (http://www.keepaste.com) + * Copyright (C) 2023 Tamir Krispis + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + *

+ * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.keepaste.logic.managers; + +import com.keepaste.logic.Application; +import com.keepaste.logic.exceptions.KeepExecutionException; +import com.keepaste.logic.exceptions.KeepParameterExecutionException; +import com.keepaste.logic.models.Keep; +import com.keepaste.logic.models.KeepParameter; +import com.keepaste.logic.models.WindowInformation; +import com.keepaste.logic.utils.ClipboardUtils; +import com.keepaste.logic.utils.GuiUtils; +import com.keepaste.logic.utils.KeyboardUtils; +import lombok.NonNull; +import lombok.extern.log4j.Log4j2; +import org.apache.commons.lang3.StringUtils; +import javax.swing.*; +import javax.swing.tree.TreePath; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * This is a {@code SwingWorker} that handles Keep execution. + */ +@Log4j2 +public class KeepExecutionWorker extends SwingWorker { + private static final String FAILED_TO_EXECUTE_KEEP = "Failed to execute keep"; + private final Keep keep; + private final boolean refreshParameters; + private final WindowInformation targetWindow; + private final TreePath treeSelectedPath; + + /** + * a {@code SwingWorker} to execute a keep on the currently active window. + * + * @param keep the {@code Keep} to execute + * @param refreshParameters if to refresh the global parameters + */ + public KeepExecutionWorker(Keep keep, boolean refreshParameters) { + this.keep = keep; + this.refreshParameters = refreshParameters; + + // clearing selection from tree not to accidentally executing the selected node when the user presses the 'enter' + // key (like on dialogs) + treeSelectedPath = getAndClearTreeSelection(); + + // keeping the active window that the user meant to paste on + targetWindow = Application.getContext().getModelActiveWindow().getActiveWindow(); + } + + @Override + protected Void doInBackground() { + // handling parameters and getting final command to execute + String commandToExecute = processParameters(keep, refreshParameters); + + log.info("Final Keep command to execute [{}]", commandToExecute); + + if (!StringUtils.isEmpty(commandToExecute)) { + // copying to clipboard always takes place + copyToClipboard(commandToExecute); + + // running execution flow based on flow settings + runExecutionFlow(); + } + return null; + } + + @Override + protected void done() { + log.debug("Completing keep execution"); + // hiding the temp background label + Application.getContext().getGui().labelBackground.setVisible(false); + // setting false flag saying there is no currently running keep + Application.getContext().setKeepCurrentlyRunning(false); + // starting back the window interceptor + Application.getContext().startWindowInterceptorRunner(); + // setting back the tree selection path (was removed to prevent from executing keep nodes when pressing 'enter' while keep is running, like when interacting with parameter dialogs) + Application.getContext().getGui().tree.setSelectionPath(treeSelectedPath); + log.debug("Keep execution completed"); + } + + /** + * Will run the keep execution flow. + */ + private void runExecutionFlow() { + // if next flow phase is not enabled, initiate only copy + if (!Application.getContext().getModelSettings().isFocusOnWindowAndPaste()) { + GuiUtils.showTargetWindowLabelMessage("Keep copied, ready to paste...", 1); + } else { + // if next flow phase is enabled, then focusing on active window + + if (isFocusOnActiveWindow(targetWindow)) { + pasteKeep(); + } else { + handleWrongTargetWindow(); + } + + // if next floe phase is enabled, then pressing enter + if (Application.getContext().getModelSettings().isPressEnterAfterPaste()) { + pressEnter(keep); + } + } + } + + /** + * Will process a keep's parameters and return the final keep command to be executed with parameters values. + * + * @param keep the executed {@code Keep} + * @param refreshParameters if to refresh and request the global parameters again + * @return the final keep command to be executed with parameters values + */ + private String processParameters(Keep keep, boolean refreshParameters) { + log.debug("Processing keep parameters for keep [{}]", keep); + String commandToExecute = keep.getPhrase(); + + // a map to hold parameters and their resolved values + Map currentParameterValuesMap = new HashMap<>(); + + if (isKeepHasParameters(keep)) { + for (KeepParameter parameter : keep.getParameters()) { + log.debug("Processing parameter [{}]", parameter); + try { + executeParameter(parameter, keep, refreshParameters, currentParameterValuesMap); + } catch (KeepParameterExecutionException ex) { + log.error(FAILED_TO_EXECUTE_KEEP, ex); + return null; // cancelling + } + } + + // setting parameter values to command + commandToExecute = setParametersValuesToCommand(currentParameterValuesMap, commandToExecute); + } + + return commandToExecute; + } + + /** + * Setting resolved parameter values to the command to be executed. + * + * @param currentParameterValuesMap the map with resolved parameter values + * @param commandToExecute the command to be executed + * @return the final command to execute + */ + private static String setParametersValuesToCommand(Map currentParameterValuesMap, String commandToExecute) { + for (Map.Entry entry : currentParameterValuesMap.entrySet()) { + commandToExecute = commandToExecute.replace(String.format("<%s>", entry.getKey()), entry.getValue()); + } + return commandToExecute; + } + + /** + * Checks if the keep has parameters. + * + * @param keep the {@code Keep} + * @return true if the keep has parameters, otherwise false + */ + private static boolean isKeepHasParameters(Keep keep) { + return keep.getParameters() != null && !keep.getParameters().isEmpty(); + } + + /** + * Copies the command to execute to clipboard. + * + * @param commandToExecute the command to be executed and copied to clipboard + */ + private static void copyToClipboard(String commandToExecute) { + // setting final keep command to the clipboard + log.debug("Setting [{}] to clipboard", commandToExecute); + ClipboardUtils.setValue(commandToExecute); + } + + /** + * Clears and return the current tree selection. + * This is used in order to prevent from executing keeps while another keep is running (by pressing 'enter' while interacting with dialogs during execution). + * + * @return the current tree selection that was cleared + */ + private static TreePath getAndClearTreeSelection() { + var currentSelectionPath = Application.getContext().getGui().tree.getSelectionPath(); + Application.getContext().getGui().tree.clearSelection(); + return currentSelectionPath; + } + + /** + * Validates that keepaste is focused on the active window where to execute the keep. + * + * @param currentlyActiveWindow the currently active window. + * @return true if focused, false otherwise + */ + private static boolean isFocusOnActiveWindow(WindowInformation currentlyActiveWindow) { + if (currentlyActiveWindow == null) { + JOptionPane.showMessageDialog(Application.getContext().getGui(), + "Please select a window by clicking on it in order to run Keeps", + "No active window", JOptionPane.WARNING_MESSAGE); + throw new KeepExecutionException("No active window is set"); + } else { + return Application.getContext().getWindowManager().focusOnActiveWindow(currentlyActiveWindow); + } + } + + /** + * Imitate pressing the 'enter' key. + * + * @param keep the executed {@code Keep} + */ + private static void pressEnter(Keep keep) { + if (keep.isNeverPressEnter()) { + log.debug("keep is set to never press 'enter' so it didn't"); + } else { + log.debug("Imitating \"ENTER\" key"); + KeyboardUtils.enter(); + } + } + + /** + * Pastes whatever was copied to the clipboard. + */ + private static void pasteKeep() { + log.debug("pasting ".concat(ClipboardUtils.getValue().toString())); + Application.getContext().getWindowManager().paste(); + } + + /** + * Handles a state where a different target window is the current active window than the one when keep execution started. + */ + private static void handleWrongTargetWindow() { + JOptionPane.showMessageDialog(Application.getContext().getGui(), + "Seems like keepaste is not focused on the desired window, please try again...", + "Warning", + JOptionPane.WARNING_MESSAGE); + log.debug("Not focused on correct window so not pasting and pressing ENTER"); + } + + /** + * Will manage a Keep parameter. + * + * @param parameter the {@code KeepParameter} to handle + * @param keep the {@code Keep} in context + * @param isRefreshGlobalParameters if to refresh the global parameters + * @param currentParameterValuesMap the current global parameters cache + */ + private void executeParameter( + @NonNull final KeepParameter parameter, + @NonNull final Keep keep, + final boolean isRefreshGlobalParameters, + @NonNull final Map currentParameterValuesMap) { + + // in case of this is a global parameter, checking if the value already exist for it then setting it on the current param values map + takeParamValueFromGlobalMapIfExists(parameter, currentParameterValuesMap, isRefreshGlobalParameters); + + // in case the value doesn't exist yet + if (!isParamValueAlreadyResolved(parameter, currentParameterValuesMap)) { + + // Array-type parameter, getting values to choose from + List paramValues = handleArrayTypeParamPhrase(parameter); + + // Command-type parameter, getting values to choose from + if (paramValues == null) { + paramValues = handleCommandTypeParamPhrase(parameter, keep, currentParameterValuesMap, isRefreshGlobalParameters); + } + + // a parameter to hold the resolved parameter value + String selectedParamValue; + + // if there are values to choose from + if (paramValues != null) { + // showing a dialog for the user to choose a resolved value from + selectedParamValue = displayParamValuesOptionsDialog(parameter, paramValues); + log.debug("Value of [{}] was chosen from an options dialog [{}]", selectedParamValue, parameter); + } else { + // free text parameter, ask the user for an input + log.debug("Parameter [{}] is of a free-text type", parameter); + + selectedParamValue = JOptionPane.showInputDialog( + Application.getContext().getGui().getContentPane(), + String.format("Input a value for %s", parameter.getName()), + "Set parameter value", + JOptionPane.QUESTION_MESSAGE); + log.debug("Value of [{}] was set to free-text parameter [{}]", selectedParamValue, parameter); + } + + // in case no value was given from this parameter + if (StringUtils.isEmpty(selectedParamValue)) { + JOptionPane.showMessageDialog( + Application.getContext().getGui(), + String.format("Value for parameter \"%s\" is not set, cancelling processing the Keep", + parameter.getName()) + ); + log.debug( + "The user probably clicked on the cancel button on the dialog to set a free-text for " + + "the parameter [{}]", parameter); + throw new KeepParameterExecutionException("User cancelled"); + } else { + // if this parameter was given a resolved value + if (keep.getPhrase() != null && !StringUtils.isEmpty(selectedParamValue)) { + // setting the value to the current resolved values map + addParamValueToCurrentValuesMap(parameter, currentParameterValuesMap, selectedParamValue); + // if it is a global parameter, adding it to the global parameters map as well + addParamValueToGlobalValues(parameter, selectedParamValue); + } + } + } + } + + + /** + * Will set the already resolved parameter value if exists on the global parameters map. + * + * @param parameter the {@code KeepParameter} + * @param currentParameterValuesMap the current parameter values map + * @param refreshParameters if to refresh the global parameters + */ + private void takeParamValueFromGlobalMapIfExists(KeepParameter parameter, + Map currentParameterValuesMap, + boolean refreshParameters) { + // checking if we already have a value for this parameter on the global parameters (unless refresh parameters was chosen) + if (isParamGlobalValueSet(parameter, refreshParameters)) { + takeCurrentParamValueFromGlobal(parameter, currentParameterValuesMap); + } + } + + /** + * Will handle a parameter of an array type ['a','b','c'] + * @param parameter the {@code KeepParameter} + * @return a list of possible values for the user to choose from + */ + private List handleArrayTypeParamPhrase(KeepParameter parameter) { + List keepResult = null; + if (isNotFreeTextTypeParam(parameter) && parameter.getPhrase().startsWith("[")) { + // predefined array of values + keepResult = Arrays.stream(parameter.getPhrase().substring(1, parameter.getPhrase().length() - 1) + .split(",")).map(String::trim) + .collect(Collectors.toList()); + log.debug("Parameter [{}] is of array type, values=[{}]", parameter, keepResult); + } + return keepResult; + } + + + /** + * Will return true if a param has a resolved value on the global resolved values map. + * + * @param parameter the {@code KeepParameter} + * @param refreshParameters if to refresh the global parameters + * @return true if a param has a resolved value on the global resolved values map. + */ + private static boolean isParamGlobalValueSet(KeepParameter parameter, boolean refreshParameters) { + return !refreshParameters && parameter.isGlobal() && KeepExecutionManager.GLOBAL_PARAMETER_VALUES_MAP.containsKey(parameter.getName()); + } + + /** + * Take a resolved value, if exists in global resolved values map. + * + * @param parameter the {@code KeepParameter} + * @param currentParameterValuesMap the current resolved parameters map + */ + private static void takeCurrentParamValueFromGlobal(KeepParameter parameter, Map currentParameterValuesMap) { + String selectedParamValue; + selectedParamValue = KeepExecutionManager.GLOBAL_PARAMETER_VALUES_MAP.get(parameter.getName()); + currentParameterValuesMap.put(parameter.getName(), selectedParamValue); + log.debug("Parameter [{}] was taken from global parameters, selected value=[{}]", parameter, selectedParamValue); + } + + /** + * Will return true if this is a command/array type of parameter (not free-text). + * + * @param parameter the {@code KeepParameter} + * @return true if this is a command/array type of parameter (not free-text). + */ + private static boolean isNotFreeTextTypeParam(KeepParameter parameter) { + return parameter.getPhrase() != null && !parameter.getPhrase().isEmpty(); + } + + /** + * Will return true if a param already has a resolved value on the current resolved values map. + * + * @param parameter the {@code KeepParameter} + * @param currentParameterValuesMap the current resolved values map + * @return true if a param already has a resolved value on the current resolved values map. + */ + private static boolean isParamValueAlreadyResolved(KeepParameter parameter, Map currentParameterValuesMap) { + return currentParameterValuesMap.containsKey(parameter.getName()); + } + + /** + * Adds a resolved value to the current resolved values map. + * + * @param parameter the {@code KeepParameter} + * @param currentParameterValuesMap the current resolved values map + * @param value the resolved value + */ + private static void addParamValueToCurrentValuesMap( + KeepParameter parameter, + Map currentParameterValuesMap, + String value) { + log.debug("Adding value of [{} for parameter [{}] to the current parameters values map", value, parameter); + currentParameterValuesMap.put(parameter.getName(), value); + } + + /** + * Adds a resolved value to the global resolved values map. + * + * @param parameter the {@code KeepParameter} + * @param value the resolved value + */ + private static void addParamValueToGlobalValues(KeepParameter parameter, String value) { + if (parameter.isGlobal()) { + log.debug( + "As it is set to be global, adding value of [{}] for parameter [{}] to the global " + + "parameters values map", value, parameter); + KeepExecutionManager.GLOBAL_PARAMETER_VALUES_MAP.put(parameter.getName(), value); + } + } + + /** + * Displays an options dialog for the user to choose a resolved value from. + * + * @param parameter the {@code KeepParameter} + * @param valuesToChooseFrom the list of values to choose from + * @return the selected value + */ + private String displayParamValuesOptionsDialog(KeepParameter parameter, List valuesToChooseFrom) { + String selectedParamValue; + log.debug("Showing the user a dialog to choose a value for tha parameter [{}]", parameter); + selectedParamValue = (String) JOptionPane.showInputDialog( + Application.getContext().getGui().getContentPane(), + String.format("Choose a value for %s", parameter.getName()), + "Set parameter value", + JOptionPane.QUESTION_MESSAGE, + null, + parseToLineByLine(valuesToChooseFrom), + null); + log.debug("User selected the value [{}] for parameter [{}]", selectedParamValue, parameter); + if (StringUtils.isEmpty(selectedParamValue)) { + JOptionPane.showMessageDialog( + Application.getContext().getGui(), + String.format( + "Value for parameter \"%s\" is not set, cancelling processing the Keep", + parameter.getName()) + ); + log.debug( + "The user probably clicked on the cancel button on the dialog to choose a value " + + "for the parameter [{}]", parameter); + throw new KeepParameterExecutionException("User cancelled"); + } + return selectedParamValue; + } + + /** + * Will execute the parameter command and return a list of values for the user to choose from. + * + * @param parameter the {@code KeepParameter} + * @param currentParameterValuesMap the currently resolved values map + * @return the selected value if to refresh the global resolved values map + */ + private List handleCommandTypeParamPhrase( + KeepParameter parameter, Keep keep, Map currentParameterValuesMap, boolean isRefreshGlobalParameters) { + List keepResult = null; + + if (isNotFreeTextTypeParam(parameter)) { + try { + String paramKeepString = parameter.getPhrase(); + + log.debug("Parameter [{}] is of Command type, executing param command [{}]", parameter, paramKeepString); + + // first setting all already resolved parameters values to the command of the param as it may use params as well + paramKeepString = setParametersValuesToCommand(currentParameterValuesMap, paramKeepString); + + // checking if the param Keep uses parameters as well, and if so, executing those first + for (KeepParameter innerParameter : keep.getParameters()) { + if (paramKeepString.contains(String.format("<%s>", innerParameter.getName()))) { + // this parameter uses another one, so executing it first + executeParameter(innerParameter, keep, isRefreshGlobalParameters, currentParameterValuesMap); + paramKeepString = paramKeepString.replace( + String.format("<%s>", innerParameter.getName()), + currentParameterValuesMap.get(innerParameter.getName())); + } + } + + keepResult = Application.getContext().getKeepExecutionManager().executeCommand(paramKeepString); + log.debug("Parameter [{}], Keep result=[{}]", parameter, keepResult); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } catch (Exception e) { + JOptionPane.showMessageDialog( + Application.getContext().getGui().getContentPane(), + String.format( + "Failed to run Keep \"%s\" for parameter \"%s\". %s.", + parameter.getPhrase(), parameter.getName(), e.getMessage()), + "Error when running a Keep", + JOptionPane.ERROR_MESSAGE + ); + } + } + return keepResult; + } + + + /** + * Will break a result into a clean list of values to choose from seperated by line breaks. + * + * @param stringToParse the list of strings returned as a result from a command + * @return a clean list of values to choose from seperated by line breaks + */ + private String[] parseToLineByLine(List stringToParse) { + if (stringToParse.size() == 1 && stringToParse.get(0).startsWith("[") && stringToParse.get(0).endsWith("]")) { + // this is a one-liner json array, splitting it, the next 'if' statement will process it + String jsonArr = stringToParse.get(0); + jsonArr = jsonArr.substring(1, jsonArr.length() - 1); + stringToParse = Arrays.asList(jsonArr.split(",")); + } + + if (!stringToParse.isEmpty() && stringToParse.get(0).equals("[")) { + // in case of a json array, an option to return visible and actual values for the dropdown lists (name of ec2 + // instance to display, the id to use on the command) + // parse from a json array + stringToParse.remove(0); // the opening bracket + stringToParse.remove(stringToParse.size() - 1); // the closing bracket + stringToParse.replaceAll(s -> s.replace("\",", "").replace("\"", "").trim()); // removing ", and " + } + + Collections.sort(stringToParse); + + return stringToParse.toArray(new String[0]); + } + +} diff --git a/logic/src/main/java/com/keepaste/logic/managers/KeepsManager.java b/logic/src/main/java/com/keepaste/logic/managers/KeepsManager.java index ef5c45c..448ee05 100644 --- a/logic/src/main/java/com/keepaste/logic/managers/KeepsManager.java +++ b/logic/src/main/java/com/keepaste/logic/managers/KeepsManager.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -36,7 +36,7 @@ import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; /** - * This utility class holds methods for managing {@link Keep}s. + * This utility class holds methods for managing {@code Keep}s. */ @Log4j2 public final class KeepsManager { @@ -91,7 +91,7 @@ public void saveKeeps(KeepsGroup rootNodeContext) { * Will save the current tree structure into a file. * * @param rootNodeContext the root node of the tree - * @param toFile the {@link File} where to persist the tree structure + * @param toFile the {@code File} where to persist the tree structure */ public void saveKeeps(KeepsGroup rootNodeContext, File toFile) { try { @@ -139,7 +139,7 @@ public void sort(KeepNode node) { * Will return all unique parameters from across the entire tree, this is used for adding an existing parameter on the * edit Keep dialog. * - * @return a List of {@link KeepParameter}s + * @return a List of {@code KeepParameter}s */ public List getAllUniqueParameters() { log.debug("Getting all unique parameters"); @@ -150,7 +150,7 @@ public List getAllUniqueParameters() { } /** - * Will return a json representation of a {@link Keep}. + * Will return a json representation of a {@code Keep}. * * @param keep the keep * @return a json representation of the keep @@ -162,10 +162,10 @@ public String getKeepJson(KeepNode keep) throws JsonProcessingException { } /** - * Will return a {@link KeepNode} out of a JSON {@link File}. + * Will return a {@code KeepNode} out of a JSON {@code File}. * * @param jsonFile the json file - * @return a {@link KeepNode} out of a JSON {@link File}. + * @return a {@code KeepNode} out of a JSON {@code File}. * @throws IOException upon failure */ public KeepNode getKeepFromJsonFile(File jsonFile) throws IOException { diff --git a/logic/src/main/java/com/keepaste/logic/managers/SettingsManager.java b/logic/src/main/java/com/keepaste/logic/managers/SettingsManager.java index f959d78..7c51ea6 100644 --- a/logic/src/main/java/com/keepaste/logic/managers/SettingsManager.java +++ b/logic/src/main/java/com/keepaste/logic/managers/SettingsManager.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -30,43 +30,46 @@ import java.io.IOException; /** - * This utility class is for managing the {@link ModelSettings}. + * This utility class is for managing the {@code ModelSettings}. */ @Log4j2 -public abstract class SettingsManager { - private static final SettingsToFile DEFAULT_MODEL_SETTINGS = SettingsToFile.builder() - .copyToClipboard(true) - .focusOnWindowAndPaste(true) - .pressEnterAfterPaste(true) - .themeClassName("FlatMacDarkLaf") - .alwaysOnTop(true) - .path(System.getenv("PATH")) - .build(); +public final class SettingsManager { + + /** + * private constructor as this is a utility class. + */ + private SettingsManager() { + // do nothing + } private static final ObjectMapper MAPPER = new ObjectMapper(); private static final File SETTINGS_FILE = new File(FileSystemUtils.getKeepasteDirectory().concat("/settings.json")); /** - * Will load settings from file. + * Will load settings from file or create and return default one if not exists or there is an issue loading it. * - * @return a {@link ModelSettings} + * @return a {@code ModelSettings} */ - public static ModelSettings loadSettingsFromFile() { - validateSettingsFileExists(); - try { - log.debug("Loading settings file [{}]", SETTINGS_FILE.getPath()); - SettingsToFile settingsToFile = MAPPER.readValue(SETTINGS_FILE, SettingsToFile.class); - return parseSettingsToFileToModelSettings(settingsToFile); - } catch (IOException e) { - log.error(String.format("Failed to load settings from file [%s]", SETTINGS_FILE), e); + public static ModelSettings getModelSettings() { + ModelSettings modelSettings = loadSettingsFromFile(); + + // in case there is an issue loading the settings file, create a default one instead + if (modelSettings == null) { + SettingsManager.createDefaultSettingsFile(); + modelSettings = SettingsManager.loadSettingsFromFile(); } - return null; + + if (modelSettings == null) { + modelSettings = SettingsManager.getDefaultModelSettings(); + } + return modelSettings; } + /** - * Will save the given {@link ModelSettings} to a file. + * Will save the given {@code ModelSettings} to a file. * - * @param settings the {@link ModelSettings} to persis + * @param settings the {@code ModelSettings} to persis */ public static void saveSettingsToFile(ModelSettings settings) { validateSettingsFileExists(); @@ -96,19 +99,35 @@ public static void createDefaultSettingsFile() { } /** - * Will get the default {@link ModelSettings} once one of the user is not present (persisted already). + * Will get the default {@code ModelSettings} once one of the user is not present (persisted already). * - * @return the default {@link ModelSettings} + * @return the default {@code ModelSettings} */ public static ModelSettings getDefaultModelSettings() { return parseSettingsToFileToModelSettings(getDefaultSettings()); } + /** + * Will load settings from a file. + * + * @return {@code ModelSettings} + */ + private static ModelSettings loadSettingsFromFile() { + validateSettingsFileExists(); + try { + log.debug("Loading settings file [{}]", SETTINGS_FILE.getPath()); + SettingsToFile settingsToFile = MAPPER.readValue(SETTINGS_FILE, SettingsToFile.class); + return parseSettingsToFileToModelSettings(settingsToFile); + } catch (IOException e) { + log.error(String.format("Failed to load settings from file [%s]", SETTINGS_FILE), e); + } + return null; + } /** - * Will parse a model representing the file - {@link SettingsToFile} to a genuine {@link ModelSettings}. + * Will parse a model representing the file - {@code SettingsToFile} to a genuine {@code ModelSettings}. * - * @return a {@link ModelSettings} + * @return a {@code ModelSettings} */ private static ModelSettings parseSettingsToFileToModelSettings(SettingsToFile settingsToFile) { LookAndFeel lookAndFeel = new FlatMacDarkLaf(); @@ -126,7 +145,7 @@ private static ModelSettings parseSettingsToFileToModelSettings(SettingsToFile s } /** - * Will save the given {@link SettingsToFile} to a file. + * Will save the given {@code SettingsToFile} to a file. * * @param settings the settings to persist */ @@ -149,6 +168,13 @@ private static void validateSettingsFileExists() { } private static SettingsToFile getDefaultSettings() { - return DEFAULT_MODEL_SETTINGS; + return SettingsToFile.builder() + .copyToClipboard(true) + .focusOnWindowAndPaste(true) + .pressEnterAfterPaste(true) + .themeClassName("FlatMacDarkLaf") + .alwaysOnTop(true) + .path(System.getenv("PATH")) + .build(); } } diff --git a/logic/src/main/java/com/keepaste/logic/managers/tree/BaseTreeTransferHandler.java b/logic/src/main/java/com/keepaste/logic/managers/tree/BaseTreeTransferHandler.java index 44b4eba..d86a80c 100644 --- a/logic/src/main/java/com/keepaste/logic/managers/tree/BaseTreeTransferHandler.java +++ b/logic/src/main/java/com/keepaste/logic/managers/tree/BaseTreeTransferHandler.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -41,9 +41,8 @@ public abstract class BaseTreeTransferHandler DropTargetListener { private final JTree tree; - private final DragSource dragSource; // dragsource - private final DropTarget dropTarget; //droptarget - private static DefaultMutableTreeNode draggedNode; + private final DragSource dragSource; + private DefaultMutableTreeNode draggedNode; private DefaultMutableTreeNode draggedNodeParent; private JLabel draggedLabel; private JLayeredPane dragPane; @@ -54,7 +53,8 @@ protected BaseTreeTransferHandler(@NonNull final JTree tree, final int action, f drawImage = drawIcon; dragSource = new DragSource(); dragSource.createDefaultDragGestureRecognizer(tree, action, this); - dropTarget = new DropTarget(tree, action, this); + // Keeping dropTarget commented out as I might need this in the future + // DropTarget dropTarget = new DropTarget(tree, action, this); } /* Methods for DragSourceListener */ @@ -71,141 +71,92 @@ public void dragDropEnd(DragSourceDropEvent dsde) { } public final void dragEnter(DragSourceDragEvent dsde) { - int action = dsde.getDropAction(); - if (action == DnDConstants.ACTION_COPY) { - dsde.getDragSourceContext().setCursor(DragSource.DefaultCopyDrop); - } else { - if (action == DnDConstants.ACTION_MOVE) { - dsde.getDragSourceContext().setCursor(DragSource.DefaultMoveDrop); - } else { - dsde.getDragSourceContext().setCursor(DragSource.DefaultMoveNoDrop); - } - } + handleSourceDragEnter(dsde); } public final void dragOver(DragSourceDragEvent dsde) { - int action = dsde.getDropAction(); - if (action == DnDConstants.ACTION_COPY) { - dsde.getDragSourceContext().setCursor(DragSource.DefaultCopyDrop); - } else { - if (action == DnDConstants.ACTION_MOVE) { - dsde.getDragSourceContext().setCursor(DragSource.DefaultMoveDrop); - } else { - dsde.getDragSourceContext().setCursor(DragSource.DefaultMoveNoDrop); - } - } + handleSourceDragEnter(dsde); } public final void dropActionChanged(DragSourceDragEvent dsde) { - int action = dsde.getDropAction(); - if (action == DnDConstants.ACTION_COPY) { - dsde.getDragSourceContext().setCursor(DragSource.DefaultCopyDrop); - } else { - if (action == DnDConstants.ACTION_MOVE) { - dsde.getDragSourceContext().setCursor(DragSource.DefaultMoveDrop); - } else { - dsde.getDragSourceContext().setCursor(DragSource.DefaultMoveNoDrop); - } - } + handleSourceDragEnter(dsde); } public final void dragExit(DragSourceEvent dse) { dse.getDragSourceContext().setCursor(DragSource.DefaultMoveNoDrop); } - /* Methods for DragGestureListener */ + /** + * Handling drag gesture. + * @param dge the {@code DragGestureEvent} describing + * the gesture that has just occurred + */ public final void dragGestureRecognized(DragGestureEvent dge) { TreePath path = tree.getSelectionPath(); if (path != null) { draggedNode = (DefaultMutableTreeNode) path.getLastPathComponent(); List expandedStates = new ArrayList<>(); - for (Enumeration enumeration = draggedNode.depthFirstEnumeration(); enumeration.hasMoreElements();) { + for (Enumeration enumeration = draggedNode.depthFirstEnumeration(); enumeration.hasMoreElements();) { DefaultMutableTreeNode element = (DefaultMutableTreeNode) enumeration.nextElement(); TreePath treePath = new TreePath(element.getPath()); expandedStates.add(tree.isExpanded(treePath)); } draggedNodeParent = (DefaultMutableTreeNode) draggedNode.getParent(); - BufferedImage image = null; - if (drawImage) { - Rectangle pathBounds = tree.getPathBounds(path); //getpathbounds of selectionpath - JComponent lbl = (JComponent)tree.getCellRenderer().getTreeCellRendererComponent( + final var image = getDragImage(path); + dragSource.startDrag(dge, DragSource.DefaultMoveNoDrop, image, new Point(0, 0), new TransferableNode(draggedNode, expandedStates), this); + } + } + + private BufferedImage getDragImage(TreePath path) { + BufferedImage image = null; + if (drawImage) { + Rectangle pathBounds = tree.getPathBounds(path); + if (pathBounds != null) { + JComponent lbl = (JComponent) tree.getCellRenderer().getTreeCellRendererComponent( tree, draggedNode, false, tree.isExpanded(path), - (tree.getModel()).isLeaf(path.getLastPathComponent()), 0, false); //returning the label - lbl.setBounds(pathBounds); //setting bounds to lbl + (tree.getModel()).isLeaf(path.getLastPathComponent()), 0, false); + lbl.setBounds(pathBounds); image = new BufferedImage( - lbl.getWidth(), lbl.getHeight(), java.awt.image.BufferedImage.TYPE_INT_ARGB_PRE); //buffered image reference passing the label's ht and width - Graphics2D graphics = image.createGraphics(); //creating the graphics for buffered image - graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f)); //Sets the Composite for the Graphics2D context + lbl.getWidth(), lbl.getHeight(), BufferedImage.TYPE_INT_ARGB_PRE); + Graphics2D graphics = image.createGraphics(); + graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f)); lbl.setOpaque(false); lbl.paint(graphics); graphics.dispose(); draggedLabel = new JLabel(new ImageIcon(image)); draggedLabel.setOpaque(false); draggedLabel.setBounds(pathBounds); - Container container = tree.getTopLevelAncestor(); - if (container == null) { - drawImage = false; + } Container container = tree.getTopLevelAncestor(); + if (container == null) { + drawImage = false; + } else { + if (container instanceof JWindow) { + dragPane = ((JWindow) tree.getTopLevelAncestor()).getLayeredPane(); + dragPane.add(draggedLabel, JLayeredPane.DRAG_LAYER); + } else if (container instanceof JFrame) { + dragPane = ((JFrame) tree.getTopLevelAncestor()).getLayeredPane(); + dragPane.add(draggedLabel, JLayeredPane.DRAG_LAYER); } else { - if (container instanceof JWindow) { - dragPane = ((JWindow) tree.getTopLevelAncestor()).getLayeredPane(); - dragPane.add(draggedLabel, JLayeredPane.DRAG_LAYER); - } else if (container instanceof JFrame) { - dragPane = ((JFrame) tree.getTopLevelAncestor()).getLayeredPane(); - dragPane.add(draggedLabel, JLayeredPane.DRAG_LAYER); - } else if (container instanceof JApplet) { - dragPane = ((JApplet) tree.getTopLevelAncestor()).getLayeredPane(); - dragPane.add(draggedLabel, JLayeredPane.DRAG_LAYER); - } else { - drawImage = false; - } + drawImage = false; } } - dragSource.startDrag(dge, DragSource.DefaultMoveNoDrop, image, new Point(0, 0), new TransferableNode(draggedNode, expandedStates), this); } + return image; } - /* Methods for DropTargetListener */ public final void dragEnter(DropTargetDragEvent dtde) { - Point pt = dtde.getLocation(); - int action = dtde.getDropAction(); - if (drawImage) { - paintImage(pt, ((DropTarget)dtde.getSource()).getComponent()); - } - if (canPerformAction(tree, draggedNode, action, pt)) { - dtde.acceptDrag(action); - } else { - dtde.rejectDrag(); - } + handleTargetDragEnter(dtde); } public final void dragExit(DropTargetEvent dte) { } public final void dragOver(DropTargetDragEvent dtde) { - Point pt = dtde.getLocation(); - int action = dtde.getDropAction(); - //tree.autoscroll(pt); - if (drawImage) { - paintImage(pt, ((DropTarget) dtde.getSource()).getComponent()); - } - if (canPerformAction(tree, draggedNode, action, pt)) { - dtde.acceptDrag(action); - } else { - dtde.rejectDrag(); - } + handleTargetDragEnter(dtde); } public final void dropActionChanged(DropTargetDragEvent dtde) { - Point pt = dtde.getLocation(); - int action = dtde.getDropAction(); - if (drawImage) { - paintImage(pt, ((DropTarget) dtde.getSource()).getComponent()); - } - if (canPerformAction(tree, draggedNode, action, pt)) { - dtde.acceptDrag(action); - } else { - dtde.rejectDrag(); - } + handleTargetDragEnter(dtde); } public final void drop(DropTargetDropEvent dtde) { @@ -215,13 +166,15 @@ public final void drop(DropTargetDropEvent dtde) { Point pt = dtde.getLocation(); if (transferable.isDataFlavorSupported(TransferableNode.NODE_FLAVOR) && canPerformAction(tree, draggedNode, action, pt)) { TreePath pathTarget = tree.getPathForLocation(pt.x, pt.y); - DefaultMutableTreeNode node = (DefaultMutableTreeNode) transferable.getTransferData(TransferableNode.NODE_FLAVOR); - DefaultMutableTreeNode newParentNode = (DefaultMutableTreeNode )pathTarget.getLastPathComponent(); - if (executeDrop(tree, node, newParentNode, action)) { - dtde.acceptDrop(action); - dtde.dropComplete(true); - tree.expandPath(new TreePath(newParentNode.getPath())); - return; + if (pathTarget != null) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) transferable.getTransferData(TransferableNode.NODE_FLAVOR); + DefaultMutableTreeNode newParentNode = (DefaultMutableTreeNode) pathTarget.getLastPathComponent(); + if (executeDrop(tree, node, newParentNode, action)) { + dtde.acceptDrop(action); + dtde.dropComplete(true); + tree.expandPath(new TreePath(newParentNode.getPath())); + return; + } } } dtde.rejectDrop(); @@ -233,6 +186,33 @@ public final void drop(DropTargetDropEvent dtde) { } } + private static void handleSourceDragEnter(DragSourceDragEvent dsde) { + int action = dsde.getDropAction(); + if (action == DnDConstants.ACTION_COPY) { + dsde.getDragSourceContext().setCursor(DragSource.DefaultCopyDrop); + } else { + if (action == DnDConstants.ACTION_MOVE) { + dsde.getDragSourceContext().setCursor(DragSource.DefaultMoveDrop); + } else { + dsde.getDragSourceContext().setCursor(DragSource.DefaultMoveNoDrop); + } + } + } + + + private void handleTargetDragEnter(DropTargetDragEvent dtde) { + Point pt = dtde.getLocation(); + int action = dtde.getDropAction(); + if (drawImage) { + paintImage(pt, ((DropTarget)dtde.getSource()).getComponent()); + } + if (canPerformAction(tree, draggedNode, action, pt)) { + dtde.acceptDrag(action); + } else { + dtde.rejectDrag(); + } + } + private synchronized void paintImage(Point pt, Component source) { pt = SwingUtilities.convertPoint(source, pt, dragPane); draggedLabel.setLocation(pt); diff --git a/logic/src/main/java/com/keepaste/logic/managers/tree/CustomTreeCellRenderer.java b/logic/src/main/java/com/keepaste/logic/managers/tree/CustomTreeCellRenderer.java index 956430b..ed9d339 100644 --- a/logic/src/main/java/com/keepaste/logic/managers/tree/CustomTreeCellRenderer.java +++ b/logic/src/main/java/com/keepaste/logic/managers/tree/CustomTreeCellRenderer.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -89,10 +89,10 @@ private Icon getIconForKeep(Keep keep) { } + @Getter enum IconType { MAVEN("mvn"); - @Getter private final String value; IconType(final String value) { diff --git a/logic/src/main/java/com/keepaste/logic/managers/tree/DefaultTreeTransferHandler.java b/logic/src/main/java/com/keepaste/logic/managers/tree/DefaultTreeTransferHandler.java index fee4f1d..30b3cd6 100644 --- a/logic/src/main/java/com/keepaste/logic/managers/tree/DefaultTreeTransferHandler.java +++ b/logic/src/main/java/com/keepaste/logic/managers/tree/DefaultTreeTransferHandler.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ diff --git a/logic/src/main/java/com/keepaste/logic/managers/tree/KeepsTreeModelListener.java b/logic/src/main/java/com/keepaste/logic/managers/tree/KeepsTreeModelListener.java index b6793b2..1938975 100644 --- a/logic/src/main/java/com/keepaste/logic/managers/tree/KeepsTreeModelListener.java +++ b/logic/src/main/java/com/keepaste/logic/managers/tree/KeepsTreeModelListener.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ diff --git a/logic/src/main/java/com/keepaste/logic/managers/tree/TransferableNode.java b/logic/src/main/java/com/keepaste/logic/managers/tree/TransferableNode.java index 84291b2..9df8262 100644 --- a/logic/src/main/java/com/keepaste/logic/managers/tree/TransferableNode.java +++ b/logic/src/main/java/com/keepaste/logic/managers/tree/TransferableNode.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ diff --git a/logic/src/main/java/com/keepaste/logic/managers/window/MacWindowsManager.java b/logic/src/main/java/com/keepaste/logic/managers/window/MacWindowsManager.java index 36d6e01..cb62eb2 100644 --- a/logic/src/main/java/com/keepaste/logic/managers/window/MacWindowsManager.java +++ b/logic/src/main/java/com/keepaste/logic/managers/window/MacWindowsManager.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -31,7 +31,7 @@ import java.util.concurrent.TimeUnit; /** - * This class is Mac's {@link WindowManager}, it holds relevant methods related to windows management in Mac's OS's. + * This class is Mac's {@code WindowManager}, it holds relevant methods related to windows management in Mac's OS's. */ @Log4j2 public final class MacWindowsManager implements WindowManager { diff --git a/logic/src/main/java/com/keepaste/logic/managers/window/WindowManager.java b/logic/src/main/java/com/keepaste/logic/managers/window/WindowManager.java index da2354e..3c3a5e1 100644 --- a/logic/src/main/java/com/keepaste/logic/managers/window/WindowManager.java +++ b/logic/src/main/java/com/keepaste/logic/managers/window/WindowManager.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -28,14 +28,14 @@ public interface WindowManager { /** * Will get the currently front-most and focused window from the operating system. * - * @return a {@link WindowInformation} containing relevant information about the window + * @return a {@code WindowInformation} containing relevant information about the window */ WindowInformation getActiveWindow(); /** * Will switch to the window before pasting the executed Keep. * - * @param windowContext the {@link WindowInformation} as the context of the window + * @param windowContext the {@code WindowInformation} as the context of the window * @return true if succeeded, false if failed */ boolean focusOnActiveWindow(@NonNull WindowInformation windowContext); diff --git a/logic/src/main/java/com/keepaste/logic/managers/window/WindowsWindowsManager.java b/logic/src/main/java/com/keepaste/logic/managers/window/WindowsWindowsManager.java index 224f5d2..a1c765d 100644 --- a/logic/src/main/java/com/keepaste/logic/managers/window/WindowsWindowsManager.java +++ b/logic/src/main/java/com/keepaste/logic/managers/window/WindowsWindowsManager.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -35,7 +35,7 @@ import java.awt.event.KeyEvent; /** - * This class is Windows's {@link WindowManager}, it holds relevant methods related to windows management in the Windows OS. + * This class is Windows's {@code WindowManager}, it holds relevant methods related to windows management in the Windows OS. */ @Log4j2 public final class WindowsWindowsManager implements WindowManager { @@ -94,7 +94,6 @@ public WindowInformation getActiveWindow() { .bottom(windowinfo.rcWindow.bottom) .build(); -// if (lastTopMostWindow == null || (topMostWindow.getProcessId() != lastTopMostWindow.getProcessId())) { if (!topMostWindow.equals(lastTopMostWindow)) { log.debug("top most window = [{}]", topMostWindow); } @@ -124,9 +123,7 @@ public boolean focusOnActiveWindow(@NonNull final WindowInformation windowContex try { WindowInformation activeWindow = Application.getContext().getModelActiveWindow().getActiveWindow(); if (activeWindow != null) { - /*WinDef.HWND result = */ User32DLL.SetFocus(activeWindow.getHwnd()); -// CommandAction.User32DLL.ShowWindow(ActiveWindow.activeWindow.getHwnd(), User32.SW_RESTORE); User32DLL.SetForegroundWindow(activeWindow.getHwnd()); return true; } else { @@ -140,11 +137,16 @@ public boolean focusOnActiveWindow(@NonNull final WindowInformation windowContex } static class User32DLL { + + private User32DLL() { + // do nothing + } + static { Native.register("user32"); } - // public static native int GetWindowThreadProcessId(HWND hWnd, PointerByReference pref); +// public static native int GetWindowThreadProcessId(HWND hWnd, PointerByReference pref); // public static native HWND GetForegroundWindow(); // public static native int GetWindowTextW(HWND hWnd, char[] lpString, int nMaxCount); public static native WinDef.HWND SetFocus(WinDef.HWND hWnd); diff --git a/logic/src/main/java/com/keepaste/logic/models/BaseModel.java b/logic/src/main/java/com/keepaste/logic/models/BaseModel.java index 75cf451..b2541ea 100644 --- a/logic/src/main/java/com/keepaste/logic/models/BaseModel.java +++ b/logic/src/main/java/com/keepaste/logic/models/BaseModel.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -21,7 +21,7 @@ import com.keepaste.logic.common.BaseSubject; /** - * This class is a base for all {@link Model}s in the application which are also {@link com.keepaste.logic.common.Subject}s. + * This class is a base for all {@code Model}s in the application which are also {@code com.keepaste.logic.common.Subject}s. */ public abstract class BaseModel extends BaseSubject implements Model { } diff --git a/logic/src/main/java/com/keepaste/logic/models/Keep.java b/logic/src/main/java/com/keepaste/logic/models/Keep.java index 30f3dbf..567fe9b 100644 --- a/logic/src/main/java/com/keepaste/logic/models/Keep.java +++ b/logic/src/main/java/com/keepaste/logic/models/Keep.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -99,23 +99,9 @@ public String toStringHTML() { if (parameters != null) { for (KeepParameter parameter : parameters) { - String color = "#b75300"; - String currentValue = ""; - if (parameter.isGlobal()) { - color = "#58a6ff"; - } - if (KeepExecutionManager.getGLOBAL_PARAMETER_VALUES_MAP().containsKey(parameter.getName())) { - currentValue = ", \"".concat( - KeepExecutionManager.getGLOBAL_PARAMETER_VALUES_MAP().get(parameter.getName())).concat("\""); - } - String type; - if (StringUtils.isEmpty(parameter.getPhrase())) { - type = "free-text"; - } else if (parameter.getPhrase().startsWith("[")) { - type = "values"; - } else { - type = "command"; - } + final var color = getColor(parameter); + final var currentValue = getCurrentValue(parameter); + final var type = getType(parameter); String command = !StringUtils.isEmpty(parameter.getPhrase()) ? "\"".concat(parameter.getPhrase()).concat("\"") : ""; sb.append(String.format("%s (%s%s)

%s
", color, parameter.getName(), type, currentValue, StringEscapeUtils.escapeHtml4(command))); @@ -125,4 +111,33 @@ public String toStringHTML() { sb.append(""); return sb.toString(); } + + private static String getType(KeepParameter parameter) { + String type; + if (StringUtils.isEmpty(parameter.getPhrase())) { + type = "free-text"; + } else if (parameter.getPhrase().startsWith("[")) { + type = "values"; + } else { + type = "command"; + } + return type; + } + + private static String getCurrentValue(KeepParameter parameter) { + String currentValue = ""; + if (KeepExecutionManager.GLOBAL_PARAMETER_VALUES_MAP.containsKey(parameter.getName())) { + currentValue = ", \"".concat( + KeepExecutionManager.GLOBAL_PARAMETER_VALUES_MAP.get(parameter.getName())).concat("\""); + } + return currentValue; + } + + private static String getColor(KeepParameter parameter) { + String color = "#b75300"; + if (parameter.isGlobal()) { + color = "#58a6ff"; + } + return color; + } } diff --git a/logic/src/main/java/com/keepaste/logic/models/KeepNode.java b/logic/src/main/java/com/keepaste/logic/models/KeepNode.java index e8139b5..f752084 100644 --- a/logic/src/main/java/com/keepaste/logic/models/KeepNode.java +++ b/logic/src/main/java/com/keepaste/logic/models/KeepNode.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -30,7 +30,7 @@ import javax.swing.*; /** - * This class represents a Keep node, it holds what is common for both {@link Keep} and {@link KeepsGroup}. + * This class represents a Keep node, it holds what is common for both {@code Keep} and {@code KeepsGroup}. */ @SuperBuilder @Getter @@ -38,7 +38,7 @@ @AllArgsConstructor @NoArgsConstructor @JsonIgnoreProperties(ignoreUnknown = true) -@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY) +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME) @JsonSubTypes({ @JsonSubTypes.Type(value = KeepsGroup.class, name = "KeepsGroup"), diff --git a/logic/src/main/java/com/keepaste/logic/models/KeepParameter.java b/logic/src/main/java/com/keepaste/logic/models/KeepParameter.java index 7f0dc37..b1aec7d 100644 --- a/logic/src/main/java/com/keepaste/logic/models/KeepParameter.java +++ b/logic/src/main/java/com/keepaste/logic/models/KeepParameter.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -63,4 +63,10 @@ public boolean equals(Object obj) { } return false; } + + @Override + public int hashCode() { + // as 'equals' is overridden, 'hashCode' should too + return super.hashCode(); + } } diff --git a/logic/src/main/java/com/keepaste/logic/models/KeepsGroup.java b/logic/src/main/java/com/keepaste/logic/models/KeepsGroup.java index 9b3466a..8c80df8 100644 --- a/logic/src/main/java/com/keepaste/logic/models/KeepsGroup.java +++ b/logic/src/main/java/com/keepaste/logic/models/KeepsGroup.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ diff --git a/logic/src/main/java/com/keepaste/logic/models/Model.java b/logic/src/main/java/com/keepaste/logic/models/Model.java index c13a831..b6504aa 100644 --- a/logic/src/main/java/com/keepaste/logic/models/Model.java +++ b/logic/src/main/java/com/keepaste/logic/models/Model.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ diff --git a/logic/src/main/java/com/keepaste/logic/models/ModelActiveWindow.java b/logic/src/main/java/com/keepaste/logic/models/ModelActiveWindow.java index a71a603..41d8f1c 100644 --- a/logic/src/main/java/com/keepaste/logic/models/ModelActiveWindow.java +++ b/logic/src/main/java/com/keepaste/logic/models/ModelActiveWindow.java @@ -1,23 +1,24 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package com.keepaste.logic.models; +import com.keepaste.logic.common.Constants; import lombok.Getter; import lombok.ToString; import lombok.extern.log4j.Log4j2; @@ -27,22 +28,20 @@ */ @ToString @Log4j2 +@Getter public class ModelActiveWindow extends BaseModel { // the current intercepted window by the window interceptor. - @Getter private WindowInformation interceptedWindow = null; // the set active window to work with when executing a Keep. - @Getter private WindowInformation activeWindow = null; - // the locked on window if this option is choosed. - @Getter + // the locked on window if this option is chosen. private WindowInformation lockedOnWindow = null; /** * Sets the intercepted window. * - * @param window the {@link WindowInformation} for the window + * @param window the {@code WindowInformation} for the window */ public void setInterceptedWindow(WindowInformation window) { if (window != interceptedWindow) { @@ -54,7 +53,7 @@ public void setInterceptedWindow(WindowInformation window) { /** * Sets the active window. * - * @param window the {@link WindowInformation} for the window + * @param window the {@code WindowInformation} for the window */ public void setActiveWindow(WindowInformation window) { log.debug("Active window set to [{}]", window); @@ -81,4 +80,13 @@ public void unLockFromWindow() { public boolean isLockedOnWindow() { return lockedOnWindow != null; } + + /** + * Will return the active window's app name or "No active window" if active window is null. + * + * @return the active window's app name or "No active window" if active window is null. + */ + public String getActiveWindowAppName() { + return activeWindow != null ? activeWindow.getApp() : Constants.NO_ACTIVE_WINDOW; + } } diff --git a/logic/src/main/java/com/keepaste/logic/models/ModelSettings.java b/logic/src/main/java/com/keepaste/logic/models/ModelSettings.java index 831a88e..eef4d07 100644 --- a/logic/src/main/java/com/keepaste/logic/models/ModelSettings.java +++ b/logic/src/main/java/com/keepaste/logic/models/ModelSettings.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -121,15 +121,17 @@ public String getPath() { @Override public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("copyToClipboard=".concat(String.valueOf(copyToClipboard))); - sb.append(System.getProperty(LINE_SEPARATOR)); - sb.append("focusOnTargetWindowAndPaste=".concat(String.valueOf(focusOnWindowAndPaste))); - sb.append(System.getProperty(LINE_SEPARATOR)); - sb.append("pressEnterAfterPaste=".concat(String.valueOf(pressEnterAfterPaste))); - sb.append(System.getProperty(LINE_SEPARATOR)); - sb.append("theme=".concat(getTheme().getClass().getName())); - sb.append(System.getProperty(LINE_SEPARATOR)); - return sb.toString(); + return "copyToClipboard=" + + copyToClipboard + + System.getProperty(LINE_SEPARATOR) + + "focusOnTargetWindowAndPaste=" + + focusOnWindowAndPaste + + System.getProperty(LINE_SEPARATOR) + + "pressEnterAfterPaste=" + + pressEnterAfterPaste + + System.getProperty(LINE_SEPARATOR) + + "theme=" + + getTheme().getClass().getName() + + System.getProperty(LINE_SEPARATOR); } } diff --git a/logic/src/main/java/com/keepaste/logic/models/ModelTree.java b/logic/src/main/java/com/keepaste/logic/models/ModelTree.java index 89ba547..2237a2f 100644 --- a/logic/src/main/java/com/keepaste/logic/models/ModelTree.java +++ b/logic/src/main/java/com/keepaste/logic/models/ModelTree.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ diff --git a/logic/src/main/java/com/keepaste/logic/models/SettingsToFile.java b/logic/src/main/java/com/keepaste/logic/models/SettingsToFile.java index 1ecb153..378fb93 100644 --- a/logic/src/main/java/com/keepaste/logic/models/SettingsToFile.java +++ b/logic/src/main/java/com/keepaste/logic/models/SettingsToFile.java @@ -1,9 +1,27 @@ +/** + * Keepaste - The keep and paste program (http://www.keepaste.com) + * Copyright (C) 2023 Tamir Krispis + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + *

+ * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + package com.keepaste.logic.models; import lombok.*; /** - * This is a simplified class is for saving the settings as defined in {@link ModelSettings} as Json on a file. + * This is a simplified class is for saving the settings as defined in {@code ModelSettings} as Json on a file. */ @NoArgsConstructor @AllArgsConstructor diff --git a/logic/src/main/java/com/keepaste/logic/models/WindowInformation.java b/logic/src/main/java/com/keepaste/logic/models/WindowInformation.java index 9911000..0969ba6 100644 --- a/logic/src/main/java/com/keepaste/logic/models/WindowInformation.java +++ b/logic/src/main/java/com/keepaste/logic/models/WindowInformation.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ diff --git a/logic/src/main/java/com/keepaste/logic/utils/ClipboardUtils.java b/logic/src/main/java/com/keepaste/logic/utils/ClipboardUtils.java index 6606ab2..0cf93de 100644 --- a/logic/src/main/java/com/keepaste/logic/utils/ClipboardUtils.java +++ b/logic/src/main/java/com/keepaste/logic/utils/ClipboardUtils.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ diff --git a/logic/src/main/java/com/keepaste/logic/utils/FileSystemUtils.java b/logic/src/main/java/com/keepaste/logic/utils/FileSystemUtils.java index f84f775..2d6cdf4 100644 --- a/logic/src/main/java/com/keepaste/logic/utils/FileSystemUtils.java +++ b/logic/src/main/java/com/keepaste/logic/utils/FileSystemUtils.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -23,6 +23,7 @@ import javax.swing.*; import java.io.File; +import java.nio.file.Files; /** * This class is a utility class for anything related to the file system. @@ -69,15 +70,14 @@ public static String getUserHomeDirectory() { return HOME_DIRECTORY; } - public static boolean isHomeDirectoryExists() { - return new File(HOME_DIRECTORY).exists(); - } - - public static boolean deleteFile(@NonNull final String filepath) { + public static void deleteFile(@NonNull final String filepath) { File file = new File(filepath); if (file.exists()) { - return file.delete(); + try { + Files.delete(file.toPath()); + } catch (Exception ex) { + log.error(String.format("Failed to delete file [%s]", filepath), ex); + } } - return true; } } diff --git a/logic/src/main/java/com/keepaste/logic/utils/GuiUtils.java b/logic/src/main/java/com/keepaste/logic/utils/GuiUtils.java index fc27f01..27ca36a 100644 --- a/logic/src/main/java/com/keepaste/logic/utils/GuiUtils.java +++ b/logic/src/main/java/com/keepaste/logic/utils/GuiUtils.java @@ -1,13 +1,16 @@ package com.keepaste.logic.utils; +import com.keepaste.logic.Application; import lombok.NonNull; +import lombok.extern.log4j.Log4j2; import javax.swing.*; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.net.URI; +import java.util.concurrent.TimeUnit; +@Log4j2 public final class GuiUtils { private GuiUtils() { @@ -17,7 +20,7 @@ private GuiUtils() { /** * Constructor. * - * @param dialog The {@link JDialog} to show + * @param dialog The {@code JDialog} to show */ public static void showDialogOnCenterScreen(@NonNull final JDialog dialog) { final Toolkit toolkit = java.awt.Toolkit.getDefaultToolkit(); @@ -34,14 +37,21 @@ public static void initHyperlinkLabel(JLabel label, String url) { @Override public void mouseClicked(MouseEvent e) { if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) { - try { - URI uri = new URI(url); - Desktop.getDesktop().browse(uri); - } catch (Exception ex) { - ex.printStackTrace(); - } + WebUtils.browseTo(url); } } }); } + + public static void showTargetWindowLabelMessage(String messageToShow, int showDurationInSeconds) { + new Thread(() -> { + Application.getContext().getGui().labelTargetWindow.setText(messageToShow); + try { + TimeUnit.SECONDS.sleep(showDurationInSeconds); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + Application.getContext().getGui().labelTargetWindow.setText(Application.getContext().getModelActiveWindow().getActiveWindowAppName()); + }).start(); + } } diff --git a/logic/src/main/java/com/keepaste/logic/utils/ImagesUtils.java b/logic/src/main/java/com/keepaste/logic/utils/ImagesUtils.java index 85ad83a..734821e 100644 --- a/logic/src/main/java/com/keepaste/logic/utils/ImagesUtils.java +++ b/logic/src/main/java/com/keepaste/logic/utils/ImagesUtils.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -41,7 +41,7 @@ public final class ImagesUtils { static final Random RANDOM = new Random(); private static final String KEEPASTE = "keepaste"; public static final int DEFAULT_COLOR_VAL = 128; - public static final int DEFAULT_ICON_WIDTH = 15; + public static final int DEFAULT_ICON_WIDTH_HEIGHT = 15; public static final int COLOR_PART_BOUND = 256; public static final int COLOR_PART_LIGHTER_VAL = 50; public static final int KEEP_ICON_FONT_SIZE = 12; @@ -79,10 +79,10 @@ public static ImageIcon getDefaultKeepNodeIcon() { } /** - * Will return an {@link ImageIcon} from a file path. + * Will return an {@code ImageIcon} from a file path. * * @param imagePath the image file path - * @return an {@link ImageIcon} from a filepath. + * @return an {@code ImageIcon} from a filepath. */ public static ImageIcon getImageIconFromFilePath(String imagePath) { Image image = getImage(imagePath); @@ -94,10 +94,10 @@ public static ImageIcon getImageIconFromFilePath(String imagePath) { } /** - * Will return an {@link Image} from a file path. + * Will return an {@code Image} from a file path. * * @param imagePath the image file path - * @return an {@link Image} from a file path. + * @return an {@code Image} from a file path. */ public static Image getImage(String imagePath) { try { @@ -129,8 +129,8 @@ private static ImageIcon getImageIcon(String keepExecutable, Color color) { * @param color the color of the icon */ public static void generateIcon(@NonNull final String commandExecutable, Color color) { - int width = DEFAULT_ICON_WIDTH; - int height = DEFAULT_ICON_WIDTH; + int width = DEFAULT_ICON_WIDTH_HEIGHT; + int height = DEFAULT_ICON_WIDTH_HEIGHT; BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = image.createGraphics(); @@ -153,12 +153,7 @@ public static void generateIcon(@NonNull final String commandExecutable, Color c } // Calculate a lighter color based on the random color - Color lighterColor = new Color(color.getRed() > COLOR_PART_LIGHTER_VAL ? color.getRed() - COLOR_PART_LIGHTER_VAL : color.getRed(), - color.getGreen() > COLOR_PART_LIGHTER_VAL ? color.getGreen() - COLOR_PART_LIGHTER_VAL : color.getGreen(), - color.getBlue() > COLOR_PART_LIGHTER_VAL ? color.getBlue() - COLOR_PART_LIGHTER_VAL : color.getBlue()); - - // Create gradient paint for the circle - GradientPaint gradientPaint = new GradientPaint(0, 0, lighterColor, width, height, color, true); + final var gradientPaint = getGradientPaint(color, width, height); // Apply gradient paint to the circle g2d.setPaint(gradientPaint); @@ -184,14 +179,24 @@ public static void generateIcon(@NonNull final String commandExecutable, Color c g2d.dispose(); // Save image as PNG + String imagePath = getCommandsIconsPath(commandExecutable); try { - ImageIO.write(image, "png", new File(getCommandsIconsPath(commandExecutable))); - log.info("Image for image path [{}] was created", commandExecutable); + ImageIO.write(image, "png", new File(imagePath)); + log.info("Image for image path [{}] was created", imagePath); } catch (IOException e) { - e.printStackTrace(); + log.error(String.format("Failed to write to image path [%s]", imagePath), e); } } + private static GradientPaint getGradientPaint(Color color, int width, int height) { + Color lighterColor = new Color(color.getRed() > COLOR_PART_LIGHTER_VAL ? color.getRed() - COLOR_PART_LIGHTER_VAL : color.getRed(), + color.getGreen() > COLOR_PART_LIGHTER_VAL ? color.getGreen() - COLOR_PART_LIGHTER_VAL : color.getGreen(), + color.getBlue() > COLOR_PART_LIGHTER_VAL ? color.getBlue() - COLOR_PART_LIGHTER_VAL : color.getBlue()); + + // Create gradient paint for the circle + return new GradientPaint(0, 0, lighterColor, width, height, color, true); + } + private static String getCommandsIconsPath(String commandExecutable) { FileSystemUtils.createDirectoryIfNotExists(FileSystemUtils.getKeepasteDirectory().concat("/commands_icons")); return FileSystemUtils.getKeepasteDirectory().concat("/commands_icons/".concat(commandExecutable).concat(".png")); diff --git a/logic/src/main/java/com/keepaste/logic/utils/KeyboardUtils.java b/logic/src/main/java/com/keepaste/logic/utils/KeyboardUtils.java index 6bf4dd5..1d19b86 100644 --- a/logic/src/main/java/com/keepaste/logic/utils/KeyboardUtils.java +++ b/logic/src/main/java/com/keepaste/logic/utils/KeyboardUtils.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ diff --git a/logic/src/main/java/com/keepaste/logic/utils/OperatingSystemUtils.java b/logic/src/main/java/com/keepaste/logic/utils/OperatingSystemUtils.java index b39b884..e50df4e 100644 --- a/logic/src/main/java/com/keepaste/logic/utils/OperatingSystemUtils.java +++ b/logic/src/main/java/com/keepaste/logic/utils/OperatingSystemUtils.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -37,9 +37,9 @@ private OperatingSystemUtils() { } /** - * Will return the current {@link OperatingSystemType}. + * Will return the current {@code OperatingSystemType}. * - * @return return the current {@link OperatingSystemType}. + * @return return the current {@code OperatingSystemType}. */ public static OperatingSystemType getOperatingSystemType() { OperatingSystemType operatingSystemType; diff --git a/logic/src/main/java/com/keepaste/logic/utils/WebUtils.java b/logic/src/main/java/com/keepaste/logic/utils/WebUtils.java index b8706bc..5715931 100644 --- a/logic/src/main/java/com/keepaste/logic/utils/WebUtils.java +++ b/logic/src/main/java/com/keepaste/logic/utils/WebUtils.java @@ -1,22 +1,24 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package com.keepaste.logic.utils; +import lombok.extern.log4j.Log4j2; + import java.awt.*; import java.io.IOException; import java.net.URI; @@ -26,6 +28,7 @@ /** * This class is a utility class for anything related to the web. */ +@Log4j2 public final class WebUtils { private WebUtils() { @@ -59,7 +62,7 @@ public static void browseTo(String url) { URI uri = new URI(url); Desktop.getDesktop().browse(uri); } catch (Exception e) { - e.printStackTrace(); + log.error(String.format("Failed to browse to [%s]", url), e); } } } diff --git a/logic/src/main/java/com/keepaste/logic/views/KeepParametersTableModel.java b/logic/src/main/java/com/keepaste/logic/views/KeepParametersTableModel.java index e663e44..678ab6f 100644 --- a/logic/src/main/java/com/keepaste/logic/views/KeepParametersTableModel.java +++ b/logic/src/main/java/com/keepaste/logic/views/KeepParametersTableModel.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -25,7 +25,7 @@ import java.util.List; /** - * This class is a model for a Keep's parameters as shown on the {@link com.keepaste.gui.DialogKeep}. + * This class is a model for a Keep's parameters as shown on the {@code com.keepaste.gui.DialogKeep}. */ public class KeepParametersTableModel extends AbstractTableModel { private final String[] columns = {"Parameter name", "Parameter value", "Global"}; @@ -84,24 +84,18 @@ public Object getValueAt(int rowIndex, int columnIndex) { * rather than a checkbox. */ @Override - public Class getColumnClass(int c) { + public Class getColumnClass(int c) { return getValueAt(0, c).getClass(); } - /* - * Don't need to implement this method unless your table's - * editable. - */ - @Override - public boolean isCellEditable(int row, int col) { - //Note that the data/cell address is constant, - //no matter where the cell appears onscreen. -// if (col < 2) { -// return false; -// } else { - return true; -// } - } + /* + * Don't need to implement this method unless your table's + * editable. + */ + @Override + public boolean isCellEditable(int row, int col) { + return true; + } /* * Don't need to implement this method unless your table's diff --git a/logic/src/main/java/com/keepaste/logic/views/View.java b/logic/src/main/java/com/keepaste/logic/views/View.java index 1ecac05..3df06d6 100644 --- a/logic/src/main/java/com/keepaste/logic/views/View.java +++ b/logic/src/main/java/com/keepaste/logic/views/View.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -21,7 +21,7 @@ import com.keepaste.logic.common.Observer; /** - * This interfaces are for Views in the MVC pattern, all views are {@link Observer}s. + * These interfaces are for Views in the MVC pattern, all views are {@code Observer}s. */ public interface View extends Observer { } diff --git a/logic/src/main/java/com/keepaste/logic/views/ViewActiveWindow.java b/logic/src/main/java/com/keepaste/logic/views/ViewActiveWindow.java index 153707d..dff57b8 100644 --- a/logic/src/main/java/com/keepaste/logic/views/ViewActiveWindow.java +++ b/logic/src/main/java/com/keepaste/logic/views/ViewActiveWindow.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ diff --git a/logic/src/main/java/com/keepaste/logic/views/ViewDialogKeep.java b/logic/src/main/java/com/keepaste/logic/views/ViewDialogKeep.java index c544720..bb15bf7 100644 --- a/logic/src/main/java/com/keepaste/logic/views/ViewDialogKeep.java +++ b/logic/src/main/java/com/keepaste/logic/views/ViewDialogKeep.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -22,19 +22,16 @@ import com.keepaste.logic.Application; import com.keepaste.logic.actionlisteners.dialogkeep.AddParamActionListener; import com.keepaste.logic.actionlisteners.dialogkeep.ExistingParamActionListener; +import com.keepaste.logic.actionlisteners.dialogkeep.OkButtonActionListener; import com.keepaste.logic.actionlisteners.dialogkeep.RemoveParamActionListener; import com.keepaste.logic.models.Keep; -import com.keepaste.logic.models.KeepsGroup; import com.keepaste.logic.models.KeepParameter; import com.keepaste.logic.utils.GuiUtils; -import org.apache.commons.lang3.StringUtils; -import javax.swing.*; -import javax.swing.table.TableCellEditor; import java.util.ArrayList; import java.util.List; /** - * This View class manages the {@link DialogKeep}. + * This View class manages the {@code DialogKeep}. */ public class ViewDialogKeep { private final DialogKeep dialogKeep = new DialogKeep(Application.getContext().getGui(), true); @@ -43,7 +40,7 @@ public class ViewDialogKeep { /** * Constructor. * - * @param keep the {@link Keep} in context + * @param keep the {@code Keep} in context */ public ViewDialogKeep(final Keep keep) { dialogKeep.setAlwaysOnTop(true); @@ -60,79 +57,12 @@ public ViewDialogKeep(final Keep keep) { this.editedParameters = keep.getParameters() == null ? new ArrayList<>() : new ArrayList<>(keep.getParameters()); dialogKeep.tableParams.setModel(getTableModel()); - dialogKeep.buttonAddParam.addActionListener(new AddParamActionListener(dialogKeep.tableParams)); - dialogKeep.buttonRemoveParam.addActionListener(new RemoveParamActionListener(dialogKeep.tableParams)); + dialogKeep.buttonAddParam.addActionListener(new AddParamActionListener(dialogKeep)); + dialogKeep.buttonRemoveParam.addActionListener(new RemoveParamActionListener(dialogKeep)); dialogKeep.buttonExistingParam.addActionListener(new ExistingParamActionListener(dialogKeep)); - dialogKeep.buttonCancel.addActionListener(e -> dialogKeep.setVisible(false)); + dialogKeep.buttonOK.addActionListener(new OkButtonActionListener(dialogKeep, keep, editedParameters)); - dialogKeep.buttonOK.addActionListener(e -> { - if (dialogKeep.tableParams.isEditing()) { - TableCellEditor cellEditor = dialogKeep.tableParams.getCellEditor( - dialogKeep.tableParams.getEditingRow(), dialogKeep.tableParams.getEditingColumn()); - if (cellEditor != null) { - cellEditor.stopCellEditing(); - } - } - if (StringUtils.isEmpty(dialogKeep.textKeep.getText()) || StringUtils.isEmpty(dialogKeep.textName.getText())) { - JOptionPane.showMessageDialog(Application.getContext().getGui(), - "Both Name and Keep fields are mandatory", "Not enough...", JOptionPane.ERROR_MESSAGE); - return; - } - // validating that there are no duplications in parameter names - if (editedParameters.stream().map(KeepParameter::getName).distinct().count() < editedParameters.size()) { - JOptionPane.showMessageDialog(Application.getContext().getGui(), - "There are duplications in parameters names, please review"); - return; - } - - // validating that all command parameters are met - String commandStr = dialogKeep.textKeep.getText(); - for (KeepParameter parameter : editedParameters) { - commandStr = commandStr.replace(String.format("<%s>", parameter.getName()), ""); - } - if (commandStr.contains("<") && commandStr.contains(">")) { - JOptionPane.showMessageDialog(Application.getContext().getGui(), - "Given parameters does not cover all keep parameters, please add missing ones"); - return; - } - - // also for parameters - for (KeepParameter parameter : editedParameters) { - String parameterPhrase = parameter.getPhrase(); - for (KeepParameter otherParameters : editedParameters) { - if (otherParameters == parameter) { - // validating that a keep parameter doesn't reference itself - if (parameterPhrase.contains(String.format("<%s>", parameter.getName()))) { - JOptionPane.showMessageDialog(Application.getContext().getGui(), - String.format("The parameter %s cannot use its own name as a command parameter.", parameter.getName())); - return; - } - } else { - parameterPhrase = parameterPhrase.replace(String.format("<%s>", otherParameters.getName()), ""); - } - } - int startIndex = parameterPhrase.indexOf("<"); - int endIndex = parameterPhrase.indexOf(">", startIndex); - if (startIndex > 0 && endIndex > 0) { - String missingParamName = parameterPhrase.substring(startIndex + 1, endIndex); - JOptionPane.showMessageDialog(Application.getContext().getGui(), - String.format("Given parameters does not cover all used parameters (on keep or its parameters)," - + " please add the following missing parameter - %s", missingParamName)); - return; - } - } - - keep.setTitle(dialogKeep.textName.getText().trim()); - keep.setPhrase(dialogKeep.textKeep.getText().trim()); - keep.setDescription(dialogKeep.textDescription.getText().trim()); - keep.setNeverPressEnter(dialogKeep.checkNeverPressEnter.isSelected()); - // getting parameters - keep.setParameters(editedParameters); - KeepsGroup rootNode = Application.getContext().getKeepsManager().getRootNode(); - Application.getContext().getKeepsManager().saveKeeps(rootNode); - dialogKeep.setVisible(false); - }); GuiUtils.showDialogOnCenterScreen(dialogKeep); } diff --git a/logic/src/main/java/com/keepaste/logic/views/ViewLookAndFeel.java b/logic/src/main/java/com/keepaste/logic/views/ViewLookAndFeel.java index 98f1cbb..798cbc6 100644 --- a/logic/src/main/java/com/keepaste/logic/views/ViewLookAndFeel.java +++ b/logic/src/main/java/com/keepaste/logic/views/ViewLookAndFeel.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -37,9 +37,9 @@ public class ViewLookAndFeel implements View { private final ViewTree viewTree; /** - * Constuctor. + * Constructor. * - * @param viewTree the {@link ViewTree} + * @param viewTree the {@code ViewTree} */ public ViewLookAndFeel(@NonNull final ViewTree viewTree) { this.viewTree = viewTree; diff --git a/logic/src/main/java/com/keepaste/logic/views/ViewTopMenu.java b/logic/src/main/java/com/keepaste/logic/views/ViewTopMenu.java index 7fba613..33dd5e9 100644 --- a/logic/src/main/java/com/keepaste/logic/views/ViewTopMenu.java +++ b/logic/src/main/java/com/keepaste/logic/views/ViewTopMenu.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -69,10 +69,31 @@ public void initUpperMenuBar() { JMenu settingsMenu = new JMenu("Settings"); - JMenu flowMenuItem = new JMenu("Flow"); - + final var flowMenuItem = getFlowMenuItem(); settingsMenu.add(flowMenuItem); + final var themesMenuItem = getThemesMenuItem(); + settingsMenu.add(themesMenuItem); + + if (OperatingSystemUtils.getOperatingSystemType() != OperatingSystemUtils.OperatingSystemType.WINDOWS) { + final var pathMenuItem = getPathMenuItem(); + settingsMenu.add(pathMenuItem); + } + + menuItemMain.add(settingsMenu); + menuItemMain.add(new JSeparator()); + + JMenuItem exitMenuItem = new JMenuItem("Exit"); + exitMenuItem.addActionListener(new ExitActionListener()); + menuItemMain.add(exitMenuItem); + + menuItemAbout.addMouseListener(new DialogAboutActionListener()); + menuItemHeart.addMouseListener(new DialogHeartActionListener()); + } + + private static JMenu getFlowMenuItem() { + JMenu flowMenuItem = new JMenu("Flow"); + JCheckBoxMenuItem copyToClipboardCheckBoxMenuItem = new JCheckBoxMenuItem("1. Copy keep to clipboard", Application.getContext().getModelSettings().isCopyToClipboard()); JCheckBoxMenuItem focusOnTargetWindowCheckBoxMenuItem = new JCheckBoxMenuItem("2. Focus on target window and paste", Application.getContext().getModelSettings().isFocusOnWindowAndPaste()); JCheckBoxMenuItem autoEnterCheckBoxMenuItem = new JCheckBoxMenuItem("3. Press 'Enter'", Application.getContext().getModelSettings().isPressEnterAfterPaste()); @@ -89,7 +110,17 @@ public void initUpperMenuBar() { AutoEnterActionListener autoEnterActionListener = new AutoEnterActionListener(copyToClipboardCheckBoxMenuItem, focusOnTargetWindowCheckBoxMenuItem); autoEnterCheckBoxMenuItem.addActionListener(autoEnterActionListener); flowMenuItem.add(autoEnterCheckBoxMenuItem); + return flowMenuItem; + } + private static JMenuItem getPathMenuItem() { + JMenuItem pathMenuItem = new JMenuItem("$PATH"); + PathMenuItemActionListener pathMenuItemActionListener = new PathMenuItemActionListener(); + pathMenuItem.addActionListener(pathMenuItemActionListener); + return pathMenuItem; + } + + private static JMenu getThemesMenuItem() { JMenu themesMenuItem = new JMenu("Themes"); ButtonGroup themesRadioButtonGroup = new ButtonGroup(); ThemesMenuItemActionListener themesMenuItemActionListener = new ThemesMenuItemActionListener(); @@ -108,24 +139,7 @@ public void initUpperMenuBar() { themesMenuItem.add(darkModeRadioMenuItem); themesMenuItem.add(lightModeRadioMenuItem); - settingsMenu.add(themesMenuItem); - - if (OperatingSystemUtils.getOperatingSystemType() != OperatingSystemUtils.OperatingSystemType.WINDOWS) { - JMenuItem pathMenuItem = new JMenuItem("$PATH"); - PathMenuItemActionListener pathMenuItemActionListener = new PathMenuItemActionListener(); - pathMenuItem.addActionListener(pathMenuItemActionListener); - settingsMenu.add(pathMenuItem); - } - - menuItemMain.add(settingsMenu); - menuItemMain.add(new JSeparator()); - - JMenuItem exitMenuItem = new JMenuItem("Exit"); - exitMenuItem.addActionListener(new ExitActionListener()); - menuItemMain.add(exitMenuItem); - - menuItemAbout.addMouseListener(new DialogAboutActionListener()); - menuItemHeart.addMouseListener(new DialogHeartActionListener()); + return themesMenuItem; } } diff --git a/logic/src/main/java/com/keepaste/logic/views/ViewTree.java b/logic/src/main/java/com/keepaste/logic/views/ViewTree.java index 3072327..cf8f115 100644 --- a/logic/src/main/java/com/keepaste/logic/views/ViewTree.java +++ b/logic/src/main/java/com/keepaste/logic/views/ViewTree.java @@ -1,17 +1,17 @@ /** * Keepaste - The keep and paste program (http://www.keepaste.com) * Copyright (C) 2023 Tamir Krispis - * + *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -43,13 +43,10 @@ public class ViewTree implements View { public static final int TOOLTIP_SHOW_DELAY_IN_MS = 500; public static final int TOOLTIP_DISMISS_DELAY_IN_MS = 30000; @Getter - private JTree tree; + private final JTree tree; @Getter private DefaultMutableTreeNode rootTreeNode; - @Getter - private DefaultMutableTreeNode parentOfSelectedNode; - @Getter - private DefaultMutableTreeNode selectedNode; + private TreeNodeMouseListener treeNodeMouseListener; private final DeleteTreeNodeActionListener deleteTreeNodeActionListener; private final ImportKeepsActionListener importKeepsActionListener; private final ExportKeepsActionListener exportKeepsActionListener; @@ -68,10 +65,18 @@ public void updateObserver(Model model) { JPopupMenu treeKeepNodeContextMenu = initKeepNodeContextMenu(); JPopupMenu treeGroupNodeContextMenu = initKeepGroupNodeContextMenu(); - addMouseListenerToKeepsTree(treeKeepNodeContextMenu, treeGroupNodeContextMenu); + addListenersToKeepsTree(treeKeepNodeContextMenu, treeGroupNodeContextMenu); }); } + public DefaultMutableTreeNode getSelectedNode() { + return treeNodeMouseListener != null ? treeNodeMouseListener.getSelectedNode() : null; + } + + public DefaultMutableTreeNode getParentOfSelectedNode() { + return treeNodeMouseListener != null ? treeNodeMouseListener.getParentOfSelectedNode() : null; + } + private JPopupMenu initKeepNodeContextMenu() { JPopupMenu treeKeepNodeContextMenu = new JPopupMenu("Keep configuration"); JMenuItem refreshParamsMenuItem = new JMenuItem("Execute with refreshed parameters"); @@ -119,7 +124,7 @@ private JPopupMenu initKeepGroupNodeContextMenu() { } public boolean isSelectedNodeGroupNode() { - return selectedNode != null && selectedNode.getUserObject() instanceof KeepsGroup; + return getSelectedNode() != null && getSelectedNode().getUserObject() instanceof KeepsGroup; } private void initKeepsTree() { @@ -176,7 +181,7 @@ public void resetSelectedNode() { } public void addKeepToTree(KeepNode keepNode) { - addKeepToTree(keepNode, true, selectedNode, true); + addKeepToTree(keepNode, true, getSelectedNode(), true); } public void addKeepToTree(KeepNode keepNode, DefaultMutableTreeNode parentTreeNode) { @@ -190,7 +195,7 @@ public void addKeepToTree(KeepNode keepNode, DefaultMutableTreeNode parentTreeNo private void addKeepToTree(KeepNode newKeep, boolean initialKeep, DefaultMutableTreeNode parentTreeNode, boolean save) { DefaultTreeModel treeModel = (DefaultTreeModel) getTree().getModel(); DefaultMutableTreeNode newKeepTreeNode = new DefaultMutableTreeNode(newKeep); - treeModel.insertNodeInto(newKeepTreeNode, parentTreeNode, getIndex(newKeep, parentTreeNode)); + treeModel.insertNodeInto(newKeepTreeNode, parentTreeNode, getInsertIndex(newKeep, parentTreeNode)); if (save && initialKeep) { // as the newKeep already holds all the child Keeps, we add it only once when the initialKeep is true ((KeepsGroup) parentTreeNode.getUserObject()).getKeepsNodes().add(newKeep); } @@ -209,7 +214,8 @@ private void addKeepToTree(KeepNode newKeep, boolean initialKeep, DefaultMutable } public void removeKeepFromTree(DefaultMutableTreeNode treeNodeToRemove) { - ((KeepsGroup)((DefaultMutableTreeNode)treeNodeToRemove.getParent()).getUserObject()).getKeepsNodes().remove((KeepNode)treeNodeToRemove.getUserObject()); + KeepNode keepNodeToRemove = (KeepNode)treeNodeToRemove.getUserObject(); + ((KeepsGroup)((DefaultMutableTreeNode)treeNodeToRemove.getParent()).getUserObject()).getKeepsNodes().remove(keepNodeToRemove); Application.getContext().getKeepsManager().saveKeeps((KeepsGroup)getRootTreeNode().getUserObject()); DefaultTreeModel treeModel = (DefaultTreeModel)getTree().getModel(); treeModel.removeNodeFromParent(treeNodeToRemove); @@ -230,16 +236,16 @@ private void resetAllNodes() { DefaultTreeModel model = (DefaultTreeModel)tree.getModel(); DefaultMutableTreeNode rootNode = (DefaultMutableTreeNode) (tree.getModel()).getRoot(); if (rootNode != null) { - Enumeration nodes = rootNode.depthFirstEnumeration(); + Enumeration nodes = rootNode.depthFirstEnumeration(); TreeNode current; while (nodes.hasMoreElements()) { - current = (TreeNode) nodes.nextElement(); + current = nodes.nextElement(); model.nodeChanged(current); } } } - private int getIndex(KeepNode childKeep, DefaultMutableTreeNode parentTreeNode) { + private int getInsertIndex(KeepNode childKeep, DefaultMutableTreeNode parentTreeNode) { int i; for (i = 0; i < parentTreeNode.getChildCount(); i++) { DefaultMutableTreeNode childTreeNode = (DefaultMutableTreeNode) parentTreeNode.getChildAt(i); @@ -248,70 +254,20 @@ private int getIndex(KeepNode childKeep, DefaultMutableTreeNode parentTreeNode) if (childKeep instanceof KeepsGroup && childKeepNode instanceof Keep) { return i; } - if ((childKeep instanceof KeepsGroup && childKeepNode instanceof KeepsGroup) - || (childKeep instanceof Keep && childKeepNode instanceof Keep)) { - if (StringUtils.compareIgnoreCase(childKeepNode.getTitle(), childKeep.getTitle()) > 0) { - return i; - } + if (((childKeep instanceof KeepsGroup && childKeepNode instanceof KeepsGroup) + || (childKeep instanceof Keep && childKeepNode instanceof Keep)) && + StringUtils.compareIgnoreCase(childKeepNode.getTitle(), childKeep.getTitle()) > 0) { + return i; } } return i; } - private void addMouseListenerToKeepsTree(JPopupMenu treeKeepNodeContextMenu, JPopupMenu treeGroupNodeContextMenu) { - MouseListener ml = new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - treeGroupNodeContextMenu.setVisible(false); - TreePath path = tree.getPathForLocation(e.getX(), e.getY()); - tree.setSelectionPath(path); - DefaultMutableTreeNode node = (DefaultMutableTreeNode) - tree.getLastSelectedPathComponent(); - - if (node == null) { - //Nothing is selected. - return; - } - - if (SwingUtilities.isRightMouseButton(e) || e.getButton() == MouseEvent.BUTTON3 || e.isControlDown()) { - KeepNode keepNode = (KeepNode) node.getUserObject(); - if (node.isLeaf() && !(keepNode instanceof KeepsGroup)) { - // Keep node - selectedNode = node; - parentOfSelectedNode = (DefaultMutableTreeNode) node.getParent(); - EventQueue.invokeLater(() -> treeKeepNodeContextMenu.show(e.getComponent(), e.getX(), e.getY())); - } else { - // Keep group node - selectedNode = node; - parentOfSelectedNode = (DefaultMutableTreeNode) node.getParent(); - EventQueue.invokeLater(() -> treeGroupNodeContextMenu.show(e.getComponent(), e.getX(), e.getY())); - } - } else if (SwingUtilities.isLeftMouseButton(e)) { - tree.setSelectionPath(tree.getPathForLocation(e.getX(), e.getY())); - - DefaultMutableTreeNode clickedOnNode = (DefaultMutableTreeNode) - tree.getLastSelectedPathComponent(); - - if (clickedOnNode == null) { - //Nothing is selected. - return; - } - - KeepNode keepNode = (KeepNode) clickedOnNode.getUserObject(); - if (e.getClickCount() == 2) { - if (clickedOnNode.isLeaf() && !(keepNode instanceof KeepsGroup)) { -// if (/*OperatingSystemUtils.getOperatingSystemType() == OperatingSystemUtils.OperatingSystemType.WINDOWS && */Application.getContext().getModelSettings().isFocusOnWindowAndPaste() && Application.getContext().getModelActiveWindow().getActiveWindow() == null) { -// JOptionPane.showMessageDialog(Application.getContext().getGui(), "Please select a window by clicking on it in order to run Keeps", "No active window", JOptionPane.WARNING_MESSAGE); -// return; -// } - - Application.getContext().getKeepExecutionManager().executeKeepOnWindow((Keep) clickedOnNode.getUserObject()); - } - } - } - } - }; - tree.addMouseListener(ml); + private void addListenersToKeepsTree(JPopupMenu treeKeepNodeContextMenu, JPopupMenu treeGroupNodeContextMenu) { + treeNodeMouseListener = new TreeNodeMouseListener( + treeGroupNodeContextMenu, + treeKeepNodeContextMenu); + tree.addMouseListener(treeNodeMouseListener); KeyListener listener = new KeyAdapter() { @Override