/*
* 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.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 unscramble parameters.
*
* @author Stefan Laubenberger
* @version 0.7.0 (20110214)
* @since 0.0.1
*/
public class DialogUnscramble extends Dialog {
private static final long serialVersionUID = -7326211046446511318L;
static final Logger log = LoggerFactory.getLogger(DialogUnscramble.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_UNSCRAMBLE_ALGO = "key.unscramble.algo"; //$NON-NLS-1$
private static final String KEY_UNSCRAMBLE_INPUT = "key.unscramble.input"; //$NON-NLS-1$
private static final String KEY_UNSCRAMBLE_OUTPUT = "key.unscramble.output"; //$NON-NLS-1$
final Scrambler scrambler;
final Localizer localizer;
JTextField tfInput;
JTextField tfOutput;
JComboBox cbCodecs;
PasswordField password;
ActionAbstract actionGo;
{
// setAlwaysOnTop(true);
// setResizable(false);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setMinimumSize(SIZE_MINIMUM);
setSize(SIZE);
}
public DialogUnscramble(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_UNSCRAMBLE));
tfInput = new TextField(null == scrambler.getModuleData().getFile(KEY_UNSCRAMBLE_INPUT) ? null : scrambler
.getModuleData().getFile(KEY_UNSCRAMBLE_INPUT).getAbsolutePath(),
localizer.getTooltip(HelperResource.RES_LABEL_UNSCRAMBLE_INPUT));
tfInput.setEditable(false);
tfOutput = new TextField(null == scrambler.getModuleData().getFile(KEY_UNSCRAMBLE_OUTPUT) ? null : scrambler
.getModuleData().getFile(KEY_UNSCRAMBLE_OUTPUT).getAbsolutePath(),
localizer.getTooltip(HelperResource.RES_LABEL_UNSCRAMBLE_OUTPUT));
tfOutput.setEditable(false);
cbCodecs = new ComboBox(CryptoSymmetricAlgo.values(),
localizer.getTooltip(HelperResource.RES_LABEL_UNSCRAMBLE_CODEC));
password = new PasswordField(localizer.getTooltip(HelperResource.RES_LABEL_UNSCRAMBLE_PASSWORD));
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_UNSCRAMBLE_INPUT));
panelContent.add(label, gbc);
gbc.gridy++;
label = new Label(localizer.getValue(HelperResource.RES_LABEL_UNSCRAMBLE_OUTPUT));
panelContent.add(label, gbc);
gbc.gridy++;
label = new Label(localizer.getValue(HelperResource.RES_LABEL_UNSCRAMBLE_CODEC));
panelContent.add(label, gbc);
gbc.gridy++;
label = new Label(localizer.getValue(HelperResource.RES_LABEL_UNSCRAMBLE_PASSWORD));
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_UNSCRAMBLE_ALGO, CryptoSymmetricAlgo.class));
cbCodecs.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(final ItemEvent e) {
validateGo();
}
});
panelContent.add(cbCodecs, gbc);
gbc.gridy++;
password.addKeyListener(new KeyAdapter() {
@Override
public void keyTyped(final KeyEvent e) {
validateGo();
}
});
panelContent.add(password, 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 = 4;
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 != cbCodecs.getSelectedItem() && 0 < password.getPassword().length);
}
});
}
/*
* Overridden methods
*/
@Override
public void createAndShowGUI() {
if (log.isDebugEnabled()) log.debug(HelperLog.methodStart());
createLayout();
pack();
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 = 1175635761991684728L;
public ActionInput() {
super(localizer.getValue(HelperResource.RES_ACTION_UNSCRAMBLE_INPUT_SELECT), scrambler.getCallback()
.getScaledIcon(Icon.DOCUMENT_OPEN), localizer
.getTooltip(HelperResource.RES_ACTION_UNSCRAMBLE_INPUT_SELECT), localizer
.getMnemonic(HelperResource.RES_ACTION_UNSCRAMBLE_INPUT_SELECT));
}
@Override
public void actionPerformed(final ActionEvent e) {
scrambler.getCallback().setPopupEnabled(false);
final JFileChooser fc = new JFileChooser();
fc.setSelectedFile(scrambler.getModuleData().getFile(KEY_UNSCRAMBLE_INPUT));
if (JFileChooser.APPROVE_OPTION == fc.showOpenDialog(getOwner())) {
scrambler.getModuleData().addValue(KEY_UNSCRAMBLE_INPUT, fc.getSelectedFile());
tfInput.setText(scrambler.getModuleData().getFile(KEY_UNSCRAMBLE_INPUT).getAbsolutePath());
}
scrambler.getCallback().setPopupEnabled(true);
}
}
private class ActionOutput extends ActionAbstract {
private static final long serialVersionUID = 577417877059699268L;
public ActionOutput() {
super(localizer.getValue(HelperResource.RES_ACTION_UNSCRAMBLE_OUTPUT_SELECT), scrambler.getCallback()
.getScaledIcon(Icon.DOCUMENT_SAVE), localizer
.getTooltip(HelperResource.RES_ACTION_UNSCRAMBLE_OUTPUT_SELECT), localizer
.getMnemonic(HelperResource.RES_ACTION_UNSCRAMBLE_OUTPUT_SELECT));
}
@Override
public void actionPerformed(final ActionEvent e) {
scrambler.getCallback().setPopupEnabled(false);
final JFileChooser fc = new JFileChooser();
fc.setSelectedFile(scrambler.getModuleData().getFile(KEY_UNSCRAMBLE_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_UNSCRAMBLE_OUTPUT, output);
tfOutput.setText(output.getAbsolutePath());
isSelecting = false;
}
} else {
scrambler.getModuleData().addValue(KEY_UNSCRAMBLE_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 = -7303630756064808796L;
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(password.getPassword())
.getBytes(Constants.ENCODING_DEFAULT));
crypto.decrypt(scrambler.getModuleData().getFile(KEY_UNSCRAMBLE_INPUT), scrambler.getModuleData()
.getFile(KEY_UNSCRAMBLE_OUTPUT), key);
scrambler.getModuleData().addValue(KEY_UNSCRAMBLE_ALGO, algo);
// } catch (IOException ex) {
// log.error("Could not unscramble file", ex); //$NON-NLS-1$
// scrambler.displayMessage(scrambler.getModel().getName(), "Could not unscramble file",
// MessageType.ERROR);
} catch (Exception ex) {
log.error("Could not unscramble file", ex); //$NON-NLS-1$
scrambler.displayMessage(scrambler.getModel().getName(), localizer.getValue(HelperResource.RES_ERROR_UNSCRAMBLE),
MessageType.ERROR);
}
return null;
}
};
worker.addListener(scrambler);
scrambler.getCallback().addWorker(
worker,
localizer.getValue(HelperResource.RES_ACTION_UNSCRAMBLE),
scrambler.getModuleData().getFile(KEY_UNSCRAMBLE_INPUT).getName()
+ " -> " + scrambler.getModuleData().getFile(KEY_UNSCRAMBLE_OUTPUT).getName(), Icons.UNSCRAMBLE); //$NON-NLS-1$
final Thread thread = new Thread(worker);
thread.start();
// worker.execute();
clearAndHide();
}
}
private class ActionAbort extends ActionAbstract {
private static final long serialVersionUID = 6236641038453711083L;
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();
}
}
}