ArduinoMenuBar.java

/*******************************************************************************
 * jArduino: Arduino C++ Code Generation From Java
 * Copyright 2020 Tony Washer
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/
package net.sourceforge.jarduino.gui;

import net.sourceforge.jarduino.ArduinoException;

import javax.swing.ButtonGroup;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JSeparator;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.io.File;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

/**
 * Arduino Menu Bar.
 */
public class ArduinoMenuBar {
    /**
     * The arduino base.
     */
    private static final String ARDUINO_LOC = System.getProperty("user.home") + "/Documents/Arduino";

    /**
     * The main panel.
     */
    private final ArduinoPanelMain theMain;

    /**
     * The MenuBar.
     */
    private final JMenuBar theMenuBar;

    /**
     * The help dialog.
     */
    private final ArduinoDialogHelp theHelp;

    /**
     * The about box.
     */
    private final ArduinoAbout theAbout;

    /**
     * The characterSet.
     */
    private Charset theCharset;

    /**
     * Constructor.
     * @param pFrame the frame
     * @param pMain the main panel
     * @throws ArduinoException on error
     */
    ArduinoMenuBar(final JFrame pFrame,
                   final ArduinoPanelMain pMain) throws ArduinoException {
        /* Store parameters */
        theMain = pMain;

        /* Create the help dialog */
        theHelp = new ArduinoDialogHelp(pFrame, pMain);

        /* Create the aboutBox */
        theAbout = new ArduinoAbout(pFrame);

        /* Create menu */
        theMenuBar = new JMenuBar();

        /* Create the file Menu */
        createFileMenu();

        /* Create the encoding Menu */
        createEncodingMenu();

        /* Create the help Menu */
        createHelpMenu();

        /* Handle the default location */
        final File myLocation = ArduinoPreferences.getDefaultLocation();
        if (myLocation != null) {
            handleNewSelection(myLocation);
        }
    }

    /**
     * Obtain the component.
     * @return the component
     */
    JMenuBar getComponent() {
        return theMenuBar;
    }

    /**
     * Create file menu.
     */
    private void createFileMenu() {
        /* Create the file Menu */
        final JMenu myFile = new JMenu("File");

        /* Create load item */
        final JMenuItem myLoad = new JMenuItem("Load DBC file");
        myLoad.addActionListener(e -> handleSelect());
        myFile.add(myLoad);

        /* Create export items */
        myFile.add(new JSeparator());
        final JMenuItem mySources = new JMenuItem("Export Sketch");
        mySources.addActionListener(e -> handleSketch());
        myFile.add(mySources);
        final JMenuItem myLibrary = new JMenuItem("Export Library");
        myLibrary.addActionListener(e -> handleLibrary());
        myFile.add(myLibrary);

        /* Create Exit item */
        myFile.add(new JSeparator());
        final JMenuItem myExit = new JMenuItem("Exit");
        myExit.addActionListener(e -> System.exit(0));
        myFile.add(myExit);

        /* Add to menuBar */
        theMenuBar.add(myFile);
    }

    /**
     * Create encoding menu.
     */
    private void createEncodingMenu() {
        /* Access the current charSet */
        theCharset = ArduinoPreferences.getCharSet();

        /* Create the encoding Menu and group */
        final JMenu myEncoding = new JMenu("Encoding");
        final ButtonGroup myEncGroup = new ButtonGroup();

        /* Create charSet menus */
        addCharSetToMenu(myEncoding, myEncGroup, StandardCharsets.ISO_8859_1);
        addCharSetToMenu(myEncoding, myEncGroup, StandardCharsets.UTF_8);

        /* Add to menuBar */
        theMenuBar.add(myEncoding);
    }

    /**
     * Create help menu.
     */
    private void createHelpMenu() {
        /* Create the help Menu */
        final JMenu myMenu = new JMenu("Help");

        /* Create help item */
        final JMenuItem myHelp = new JMenuItem("Help");
        myHelp.addActionListener(e -> theHelp.showDialog());
        myMenu.add(myHelp);

        /* Create About item */
        final JMenuItem myAbout = new JMenuItem("About");
        myAbout.addActionListener(e -> theAbout.showDialog());
        myMenu.add(myAbout);

        /* Add to menuBar */
        theMenuBar.add(myMenu);
    }
    /**
     * Add charSet to menu.
     * @param pEncoding the encoding menu
     * @param pGroup the button group
     * @param pCharset the character set
     */
    private void addCharSetToMenu(final JMenu pEncoding,
                                  final ButtonGroup pGroup,
                                  final Charset pCharset) {
        /* Create menu item */
        final JMenuItem myItem = new JRadioButtonMenuItem(pCharset.displayName());
        myItem.setSelected(pCharset.equals(theCharset));
        myItem.addActionListener(e -> setCharSet(pCharset));
        pEncoding.add(myItem);
        pGroup.add(myItem);
    }

    /**
     * Handle selection.
     */
    private void handleSelect() {
        /* Create and configure the file chooser */
        final JFileChooser myChooser = new JFileChooser();
        myChooser.setDialogTitle("Select DBC File");
        myChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
        myChooser.setFileFilter(new FileNameExtensionFilter("DBC Files", "dbc"));

        /* Access the current selection */
        final File myCurrent = ArduinoPreferences.getDefaultLocation();
        if (myCurrent != null) {
            myChooser.setCurrentDirectory(new File(myCurrent.getParent()));
        }

        /* Select the file */
        final int myResult = myChooser.showOpenDialog(theMain.getFrame());

        /* If we selected a file */
        if (myResult == JFileChooser.APPROVE_OPTION) {
            /* Access file and process it */
            final File mySelected = myChooser.getSelectedFile();
            handleNewSelection(mySelected);
        }
    }

    /**
     * Handle new location.
     * @param pSelected the selected file
     */
    private void handleNewSelection(final File pSelected) {
        /* Access file and process it */
        ArduinoException myError = theMain.setSelected(pSelected, theCharset);
        if (myError == null) {
            myError = ArduinoPreferences.storeDefaultLocation(pSelected);
        }

        /* If we have an error */
        if (myError != null) {
            /* Record it */
            theMain.setError(myError);
        }
    }

    /**
     * Handle sketch.
     */
    private void handleSketch() {
        /* Create and configure the file chooser */
        final JFileChooser myChooser = new JFileChooser();
        myChooser.setDialogTitle("Select Sketch directory");
        myChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);

        /* Access the current selection */
        File myCurrent = ArduinoPreferences.getSketchLocation();
        if (myCurrent == null) {
            /* Try the arduino base */
            myCurrent = new File(ARDUINO_LOC);
        }

        /* set current directory */
        myChooser.setCurrentDirectory(myCurrent);

        /* Select the directory */
        final int myResult = myChooser.showSaveDialog(theMain.getFrame());

        /* If we selected a file */
        if (myResult == JFileChooser.APPROVE_OPTION) {
            /* Access directory and process it */
            final File myOutDir = myChooser.getSelectedFile();
            handleWritingSketch(myOutDir);
        }
    }

    /**
     * Handle writing sketch files.
     * @param pOutDir the selected output directory
     */
    private void handleWritingSketch(final File pOutDir) {
        /* Output the files */
        ArduinoException myError = theMain.writeSketch(pOutDir, theCharset);
        if (myError == null) {
            myError = ArduinoPreferences.storeSketchLocation(pOutDir);
        }

        /* record error */
        if (myError != null) {
            theMain.setError(myError);
        }
    }

    /**
     * Handle library.
     */
    private void handleLibrary() {
        /* Create and configure the file chooser */
        final JFileChooser myChooser = new JFileChooser();
        myChooser.setDialogTitle("Select Library directory");
        myChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);

        /* Access the current selection */
        File myCurrent = ArduinoPreferences.getLibraryLocation();
        if (myCurrent == null) {
            /* Try the arduino library base */
            myCurrent = new File(ARDUINO_LOC + "/libraries");
        }

        /* set current directory */
        myChooser.setCurrentDirectory(myCurrent);

        /* Select the directory */
        final int myResult = myChooser.showSaveDialog(theMain.getFrame());

        /* If we selected a file */
        if (myResult == JFileChooser.APPROVE_OPTION) {
            /* Access directory and process it */
            final File myOutDir = myChooser.getSelectedFile();
            handleWritingLibrary(myOutDir);
        }
    }

    /**
     * Handle writing library files.
     * @param pOutDir the selected output directory
     */
    private void handleWritingLibrary(final File pOutDir) {
        /* Output the files */
        ArduinoException myError = theMain.writeLibrary(pOutDir, theCharset);
        if (myError == null) {
            myError = ArduinoPreferences.storeLibraryLocation(pOutDir);
        }

        /* record error */
        if (myError != null) {
            theMain.setError(myError);
        }
    }

    /**
     * Set characterSet.
     * @param pCharset the character set
     */
    private void setCharSet(final Charset pCharset) {
        /* Store the characterSet */
        theCharset = pCharset;
        final ArduinoException myError = ArduinoPreferences.storeCharSet(theCharset);

        /* record error */
        if (myError != null) {
            theMain.setError(myError);
        }
    }
}