/*
* Copyright (c) 2011 by Stefan Laubenberger.
*
* Scrambler is free software: you can redistribute it and/or modify
* it under the terms of the General Public License v2.0.
*
* Scrambler is distributed together with Tyr 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:
* <http://www.gnu.org/licenses>
*
* This distribution is available at:
* <http://code.google.com/p/tyr/>
* <http://dev.laubenberger.net/tyr/>
*
* Contact information:
* Stefan Laubenberger
* Bullingerstrasse 53
* CH-8004 Zuerich
*
* <http://www.laubenberger.net>
*
* <laubenberger@gmail.com>
*/
package net.laubenberger.tyr.module.scrambler;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.TrayIcon.MessageType;
import java.awt.event.ActionEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.File;
import javax.crypto.SecretKey;
import javax.swing.BorderFactory;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import net.laubenberger.bogatyr.helper.HelperLog;
import net.laubenberger.bogatyr.misc.Constants;
import net.laubenberger.bogatyr.model.crypto.CryptoSymmetricAlgo;
import net.laubenberger.bogatyr.service.crypto.CryptoSymmetric;
import net.laubenberger.bogatyr.service.crypto.CryptoSymmetricImpl;
import net.laubenberger.bogatyr.service.localizer.Localizer;
import net.laubenberger.bogatyr.view.swing.ActionAbstract;
import net.laubenberger.bogatyr.view.swing.Button;
import net.laubenberger.bogatyr.view.swing.ComboBox;
import net.laubenberger.bogatyr.view.swing.Dialog;
import net.laubenberger.bogatyr.view.swing.Group;
import net.laubenberger.bogatyr.view.swing.Label;
import net.laubenberger.bogatyr.view.swing.Panel;
import net.laubenberger.bogatyr.view.swing.PasswordField;
import net.laubenberger.bogatyr.view.swing.TextField;
import net.laubenberger.bogatyr.view.swing.pane.PaneScroll;
import net.laubenberger.bogatyr.view.swing.worker.Worker;
import net.laubenberger.bogatyr.view.swing.worker.WorkerAbstract;
import net.laubenberger.tyr.model.Icon;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The dialog for the scramble parameters.
*
* @author Stefan Laubenberger
* @version 0.7.0 (20110214)
* @since 0.0.1
*/
public class DialogScramble extends Dialog {
private static final long serialVersionUID = -4693209233877273662L;
static final Logger log = LoggerFactory.getLogger(DialogScramble.class);
private static final Dimension SIZE = new Dimension(600, 375);
private static final Dimension SIZE_MINIMUM = new Dimension(320, 200);
private static final String KEY_SCRAMBLE_ALGO = "key.scramble.algo"; //$NON-NLS-1$
private static final String KEY_SCRAMBLE_INPUT = "key.scramble.input"; //$NON-NLS-1$
private static final String KEY_SCRAMBLE_OUTPUT = "key.scramble.output"; //$NON-NLS-1$
final Scrambler scrambler;
final Localizer localizer;
JTextField tfInput;
JTextField tfOutput;
JComboBox cbCodecs;
JPasswordField password1;
JPasswordField password2;
ActionAbstract actionGo;
{
// setAlwaysOnTop(true);
// setResizable(false);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setMinimumSize(SIZE_MINIMUM);
setSize(SIZE);
}
public DialogScramble(final Scrambler scrambler) {
super(scrambler.getOwner());
this.scrambler = scrambler;
localizer = scrambler.getModel().getLocalizer();
}
/*
* Private methods
*/
private void createLayout() {
getContentPane().removeAll();
// setLayout(new BorderLayout());
setTitle(localizer.getValue(HelperResource.RES_ACTION_SCRAMBLE));
tfInput = new TextField(null == scrambler.getModuleData().getFile(KEY_SCRAMBLE_INPUT) ? null : scrambler
.getModuleData().getFile(KEY_SCRAMBLE_INPUT).getAbsolutePath(),
localizer.getTooltip(HelperResource.RES_LABEL_SCRAMBLE_INPUT));
tfInput.setEditable(false);
tfOutput = new TextField(null == scrambler.getModuleData().getFile(KEY_SCRAMBLE_OUTPUT) ? null : scrambler
.getModuleData().getFile(KEY_SCRAMBLE_OUTPUT).getAbsolutePath(),
localizer.getTooltip(HelperResource.RES_LABEL_SCRAMBLE_OUTPUT));
tfOutput.setEditable(false);
cbCodecs = new ComboBox(CryptoSymmetricAlgo.values(),
localizer.getTooltip(HelperResource.RES_LABEL_SCRAMBLE_CODEC));
password1 = new PasswordField(localizer.getTooltip(HelperResource.RES_LABEL_SCRAMBLE_PASSWORD));
password2 = new PasswordField(localizer.getTooltip(HelperResource.RES_LABEL_SCRAMBLE_PASSWORD_VERIFY));
actionGo = new ActionGo();
final ActionAbstract actionAbort = new ActionAbort();
final Panel panel = new Panel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 5, 10));
// column 1
final GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.anchor = GridBagConstraints.NORTH;
gbc.gridy = 0;
gbc.gridx = 0;
gbc.insets = new Insets(5, 10, 5, 10);
final Panel panelContent = new Panel(new GridBagLayout());
Label label = new Label(localizer.getValue(HelperResource.RES_LABEL_SCRAMBLE_INPUT));
panelContent.add(label, gbc);
gbc.gridy++;
label = new Label(localizer.getValue(HelperResource.RES_LABEL_SCRAMBLE_OUTPUT));
panelContent.add(label, gbc);
gbc.gridy++;
label = new Label(localizer.getValue(HelperResource.RES_LABEL_SCRAMBLE_CODEC));
panelContent.add(label, gbc);
gbc.gridy++;
label = new Label(localizer.getValue(HelperResource.RES_LABEL_SCRAMBLE_PASSWORD));
panelContent.add(label, gbc);
gbc.gridy++;
label = new Label(localizer.getValue(HelperResource.RES_LABEL_SCRAMBLE_PASSWORD_VERIFY));
panelContent.add(label, gbc);
// column 2
gbc.gridx++;
gbc.gridy = 0;
gbc.weightx = 1.0D;
panelContent.add(tfInput, gbc);
gbc.gridy++;
panelContent.add(tfOutput, gbc);
gbc.gridy++;
cbCodecs.setSelectedItem(scrambler.getModuleData().getValue(KEY_SCRAMBLE_ALGO, CryptoSymmetricAlgo.class));
cbCodecs.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(final ItemEvent e) {
validateGo();
}
});
panelContent.add(cbCodecs, gbc);
gbc.gridy++;
password1.addKeyListener(new KeyAdapter() {
@Override
public void keyTyped(final KeyEvent e) {
validateGo();
}
});
panelContent.add(password1, gbc);
gbc.gridy++;
password2.addKeyListener(new KeyAdapter() {
@Override
public void keyTyped(final KeyEvent e) {
validateGo();
}
});
panelContent.add(password2, gbc);
// column 3
gbc.gridx++;
gbc.gridy = 0;
gbc.weightx = 0.0D;
panelContent.add(new Button(new ActionInput()), gbc);
gbc.gridy++;
panelContent.add(new Button(new ActionOutput()), gbc);
// spacer
gbc.gridy = 5;
gbc.fill = GridBagConstraints.BOTH;
gbc.weighty = 1.0D;
panelContent.add(new Panel(), gbc);
final JScrollPane scroll = new PaneScroll(panelContent);
final Group group = new Group(new Insets(0, 0, 0, 10), new Button(actionGo), new Button(actionAbort));
panel.add(scroll, BorderLayout.CENTER);
panel.add(group, BorderLayout.SOUTH);
getContentPane().add(panel);
validateGo();
// pack();
}
void validateGo() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
actionGo.setEnabled(null != tfInput.getText() && null != tfOutput.getText()
&& null != cbCodecs.getSelectedItem() && 0 < password1.getPassword().length
&& 0 < password2.getPassword().length
&& new String(password1.getPassword()).equals(new String(password2.getPassword())));
}
});
}
/*
* Overridden methods
*/
@Override
public void createAndShowGUI() {
if (log.isDebugEnabled()) log.debug(HelperLog.methodStart());
createLayout();
pack();
// setMinimumSize(getPreferred7Size());
scrambler.getDialogs().add(this);
super.createAndShowGUI();
if (log.isDebugEnabled()) log.debug(HelperLog.methodExit());
}
@Override
public void clearAndHide() {
if (log.isDebugEnabled()) log.debug(HelperLog.methodStart());
scrambler.getDialogs().remove(this);
super.clearAndHide();
if (log.isDebugEnabled()) log.debug(HelperLog.methodExit());
}
/*
* Inner classes
*/
private class ActionInput extends ActionAbstract {
private static final long serialVersionUID = 6465329237029707392L;
public ActionInput() {
super(localizer.getValue(HelperResource.RES_ACTION_SCRAMBLE_INPUT_SELECT), scrambler.getCallback()
.getScaledIcon(Icon.DOCUMENT_OPEN), localizer
.getTooltip(HelperResource.RES_ACTION_SCRAMBLE_INPUT_SELECT), localizer
.getMnemonic(HelperResource.RES_ACTION_SCRAMBLE_INPUT_SELECT));
}
@Override
public void actionPerformed(final ActionEvent e) {
scrambler.getCallback().setPopupEnabled(false);
final JFileChooser fc = new JFileChooser();
// fc.setCurrentDirectory(scrambler.getModuleData().getFile(KEY_SCRAMBLE_INPUT));
fc.setSelectedFile(scrambler.getModuleData().getFile(KEY_SCRAMBLE_INPUT));
if (JFileChooser.APPROVE_OPTION == fc.showOpenDialog(getOwner())) {
// final File input = fc.getSelectedFile();
scrambler.getModuleData().addValue(KEY_SCRAMBLE_INPUT, fc.getSelectedFile());
tfInput.setText(scrambler.getModuleData().getFile(KEY_SCRAMBLE_INPUT).getAbsolutePath());
}
scrambler.getCallback().setPopupEnabled(true);
}
}
private class ActionOutput extends ActionAbstract {
private static final long serialVersionUID = 8592899337370136971L;
public ActionOutput() {
super(localizer.getValue(HelperResource.RES_ACTION_SCRAMBLE_OUTPUT_SELECT), scrambler.getCallback()
.getScaledIcon(Icon.DOCUMENT_SAVE), localizer
.getTooltip(HelperResource.RES_ACTION_SCRAMBLE_OUTPUT_SELECT), localizer
.getMnemonic(HelperResource.RES_ACTION_SCRAMBLE_OUTPUT_SELECT));
}
@Override
public void actionPerformed(final ActionEvent e) {
scrambler.getCallback().setPopupEnabled(false);
final JFileChooser fc = new JFileChooser();
// fc.setCurrentDirectory(scrambler.getModuleData().getFile(KEY_SCRAMBLE_OUTPUT));
fc.setSelectedFile(scrambler.getModuleData().getFile(KEY_SCRAMBLE_OUTPUT));
boolean isSelecting = true;
while (isSelecting) {
if (JFileChooser.APPROVE_OPTION == fc.showSaveDialog(getOwner())) {
final File output = fc.getSelectedFile();
if (output.exists()) {
if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(getOwner(),
localizer.getValue(HelperResource.RES_TEXT_FILE_EXISTS_OVERWRITE), localizer.getValue(HelperResource.RES_TEXT_FILE_EXISTS), JOptionPane.WARNING_MESSAGE)) {
scrambler.getModuleData().addValue(KEY_SCRAMBLE_OUTPUT, output);
tfOutput.setText(output.getAbsolutePath());
isSelecting = false;
}
} else {
scrambler.getModuleData().addValue(KEY_SCRAMBLE_OUTPUT, output);
tfOutput.setText(output.getAbsolutePath());
isSelecting = false;
}
} else {
isSelecting = false;
}
}
scrambler.getCallback().setPopupEnabled(true);
}
}
private class ActionGo extends ActionAbstract {
private static final long serialVersionUID = -593062286254344043L;
public ActionGo() {
super(localizer.getValue(HelperResource.RES_ACTION_OK), scrambler.getCallback().getScaledIcon(Icon.OK),
localizer.getTooltip(HelperResource.RES_ACTION_OK), localizer.getMnemonic(HelperResource.RES_ACTION_OK));
}
@Override
public void actionPerformed(final ActionEvent e) {
final Worker worker = new WorkerAbstract<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
fireWorkerStart();
try {
final CryptoSymmetricAlgo algo = (CryptoSymmetricAlgo) cbCodecs.getSelectedItem();
final CryptoSymmetric crypto = new CryptoSymmetricImpl(algo);
final SecretKey key = crypto.generateKey(new String(password1.getPassword())
.getBytes(Constants.ENCODING_DEFAULT));
crypto.encrypt(scrambler.getModuleData().getFile(KEY_SCRAMBLE_INPUT), scrambler.getModuleData()
.getFile(KEY_SCRAMBLE_OUTPUT), key);
scrambler.getModuleData().addValue(KEY_SCRAMBLE_ALGO, algo);
// } catch (IOException ex) {
// log.error("Could not scramble file", ex); //$NON-NLS-1$
// scrambler
// .displayMessage(scrambler.getModel().getName(), "Could not scramble file", MessageType.ERROR);
} catch (Exception ex) {
log.error("Could not scramble file", ex); //$NON-NLS-1$
scrambler
.displayMessage(scrambler.getModel().getName(), localizer.getValue(HelperResource.RES_ERROR_SCRAMBLE), MessageType.ERROR);
}
return null;
}
};
worker.addListener(scrambler);
scrambler.getCallback().addWorker(
worker,
localizer.getValue(HelperResource.RES_ACTION_SCRAMBLE),
scrambler.getModuleData().getFile(KEY_SCRAMBLE_INPUT).getName()
+ " -> " + scrambler.getModuleData().getFile(KEY_SCRAMBLE_OUTPUT).getName(), Icons.SCRAMBLE); //$NON-NLS-1$
final Thread thread = new Thread(worker);
thread.start();
// worker.execute();
clearAndHide();
}
}
private class ActionAbort extends ActionAbstract {
private static final long serialVersionUID = -4661527106306345821L;
public ActionAbort() {
super(localizer.getValue(HelperResource.RES_ACTION_CANCEL),
scrambler.getCallback().getScaledIcon(Icon.CANCEL), localizer
.getTooltip(HelperResource.RES_ACTION_CANCEL), localizer
.getMnemonic(HelperResource.RES_ACTION_CANCEL));
}
@Override
public void actionPerformed(final ActionEvent e) {
clearAndHide();
}
}
}