/*
*
* Panbox - encryption for cloud storage
* Copyright (C) 2014-2015 by Fraunhofer SIT and Sirrix AG
*
* 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 <http://www.gnu.org/licenses/>.
*
* Additonally, third party code may be provided with notices and open source
* licenses from communities and third parties that govern the use of those
* portions, and any licenses granted hereunder do not alter any rights and
* obligations you may have under such open source licenses, however, the
* disclaimer of warranty and limitation of liability provisions of the GPLv3
* will apply to all the product.
*
*/
package org.panbox.desktop.common.gui;
import org.apache.log4j.Logger;
import org.panbox.Settings;
import org.panbox.desktop.common.pairing.cam.*;
import javax.swing.*;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.ResourceBundle;
/**
* @author Clemens A. Schulz <c.schulz@sirrix.com>
*/
public class PairThisDeviceDialog extends javax.swing.JDialog implements
QRCodeListener {
private static final long serialVersionUID = -5273292017550278291L;
private static final ResourceBundle bundle = ResourceBundle.getBundle(
"org.panbox.desktop.common.gui.Messages", Settings.getInstance()
.getLocale());
protected static final Logger logger = Logger.getLogger("org.panbox");
private OpenCVWebCam webCam = null;
private String pairingPassword = null;
private ArrayList<CameraDevice> dev;
private File pairingFile;
/**
* Creates new form PairThisDeviceDialog
*
* @throws Exception
*/
public PairThisDeviceDialog(java.awt.Frame parent) throws Exception {
super(parent, true);
loadDeviceList();
initComponents(0);
setDeviceList();
QRCodeProcessor proc = new QRCodeProcessor();
proc.addSquareCodeListener(this);
try {
if (camLifeViewPanel instanceof OpenCVWebCam) {
webCam = (OpenCVWebCam) camLifeViewPanel;
webCam.setImageProcessor(proc);
webCam.start();
}
} catch (Exception e) {
logger.warn(
"PairThisDeviceDialog : Failed to load webcam. This might not be a problem. Thrown exception: ",
e);
}
setLocationRelativeTo(null);
}
private void loadDeviceList() {
dev = Utils.listVideoDevices();
logger.debug("PairThisDeviceDialog : loadDeviceList : Found these video devices: "
+ dev);
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
// <editor-fold defaultstate="collapsed"
// desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents(int deviceId) {
infoMessageLabel = new javax.swing.JLabel();
camLabel = new javax.swing.JLabel();
camComboBox = new javax.swing.JComboBox<CameraDevice>();
if (dev.size() > 0) {
camLifeViewPanel = new OpenCVWebCam(deviceId, 640, 480);
} else {
logger.debug("PairThisDeviceDialog : initComponents : No camera device could be found");
camLifeViewPanel = new DummyOpenCVWebCam();
}
buttonPanel = new javax.swing.JPanel();
importFileButton = new javax.swing.JButton();
enterPasswordButton = new javax.swing.JButton();
cancelButton = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
setTitle(bundle.getString("client.setupwizard.pairing.title")); // NOI18N
setMaximumSize(new java.awt.Dimension(660, 660));
setMinimumSize(new java.awt.Dimension(660, 660));
setResizable(false);
infoMessageLabel.setText(bundle
.getString("client.setupwizard.pairing.message")); // NOI18N
camLabel.setText(bundle
.getString("client.setupwizard.pairing.camLabel")); // NOI18N
camComboBox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
camComboBoxActionPerformed(evt);
}
});
javax.swing.GroupLayout camLifeViewPanelLayout = new javax.swing.GroupLayout(
camLifeViewPanel);
camLifeViewPanel.setLayout(camLifeViewPanelLayout);
camLifeViewPanelLayout.setHorizontalGroup(camLifeViewPanelLayout
.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 640, Short.MAX_VALUE));
camLifeViewPanelLayout.setVerticalGroup(camLifeViewPanelLayout
.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 480, Short.MAX_VALUE));
buttonPanel.setLayout(new java.awt.GridLayout(1, 3, 10, 0));
importFileButton.setText(bundle
.getString("client.setupwizard.pairing.importFileLabel")); // NOI18N
importFileButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
importFileButtonActionPerformed(evt);
}
});
buttonPanel.add(importFileButton);
enterPasswordButton.setText(bundle
.getString("client.setupwizard.pairing.enterPasswordLabel")); // NOI18N
enterPasswordButton
.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
enterPasswordButtonActionPerformed(evt);
}
});
buttonPanel.add(enterPasswordButton);
cancelButton.setText(bundle.getString("client.cancel")); // NOI18N
cancelButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cancelButtonActionPerformed(evt);
}
});
buttonPanel.add(cancelButton);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(
getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(layout
.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(
layout.createSequentialGroup()
.addContainerGap()
.addGroup(
layout.createParallelGroup(
javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(
layout.createSequentialGroup()
.addComponent(
camLabel,
javax.swing.GroupLayout.PREFERRED_SIZE,
70,
javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(
javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(
camComboBox,
0,
javax.swing.GroupLayout.DEFAULT_SIZE,
Short.MAX_VALUE))
.addComponent(
camLifeViewPanel,
javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE,
Short.MAX_VALUE)
.addGroup(
layout.createSequentialGroup()
.addComponent(
infoMessageLabel,
javax.swing.GroupLayout.PREFERRED_SIZE,
400,
javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0,
0,
Short.MAX_VALUE))
.addComponent(
buttonPanel,
javax.swing.GroupLayout.Alignment.TRAILING,
javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE,
Short.MAX_VALUE))
.addContainerGap()));
layout.setVerticalGroup(layout
.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(
layout.createSequentialGroup()
.addContainerGap()
.addComponent(infoMessageLabel,
javax.swing.GroupLayout.PREFERRED_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(
javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(
layout.createParallelGroup(
javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(camLabel)
.addComponent(
camComboBox,
javax.swing.GroupLayout.PREFERRED_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(
javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(camLifeViewPanel,
javax.swing.GroupLayout.PREFERRED_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(
javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(buttonPanel,
javax.swing.GroupLayout.PREFERRED_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(
javax.swing.GroupLayout.DEFAULT_SIZE,
Short.MAX_VALUE)));
pack();
}// </editor-fold>//GEN-END:initComponents
private void camComboBoxActionPerformed(java.awt.event.ActionEvent evt) {
CameraDevice dev = (CameraDevice) camComboBox.getModel()
.getSelectedItem();
logger.debug("PairThisDeviceDialog : camComboBoxActionPerformed : New device: "
+ dev);
// TODO: update camera view with new device!
// FIXME: I18N when this is changed
JOptionPane.showMessageDialog(this,
"Switching between devices is currently not supported!");
}
private void importFileButtonActionPerformed(java.awt.event.ActionEvent evt) {
JFileChooser chooser = new JFileChooser();
if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
pairingFile = chooser.getSelectedFile();
logger.debug("PairThisDeviceDialog : importFileButtonActionPerformed : File: "
+ pairingFile.getAbsolutePath());
this.dispose();
}
}
private void enterPasswordButtonActionPerformed(
java.awt.event.ActionEvent evt) {
// ask user to enter pairing password
final JTextField manualPassword = new JTextField();
manualPassword
.setText(bundle.getString("PairThisDeviceDialog.enterPW"));
manualPassword.addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent e) {
if (manualPassword.getText().equals(
bundle.getString("PairThisDeviceDialog.enterPW"))) {
manualPassword.setText("");
}
}
});
JOptionPane.showMessageDialog(this, manualPassword,
bundle.getString("PairThisDeviceDialog.enterPairingPW"),
JOptionPane.INFORMATION_MESSAGE);
// check if password is valid
String text = manualPassword.getText();
if (isPanboxQRCode(text)) {
logger.debug("PairThisDeviceDialog : enterPasswordButtonActionPerformed : Entered Password is a valid PanboxQRCodePassword. Will simulate QR scan...");
qrCodeDetected(text);
} else {
logger.debug("PairThisDeviceDialog : enterPasswordButtonActionPerformed : Entered Password is an invalid PanboxQRCodePassword. Will abort.");
JOptionPane
.showMessageDialog(
this,
"The entered password was not a valid Panbox pairing password. Please try again.");
}
}
private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {
dispose();
}
private void setDeviceList() {
dev = Utils.listVideoDevices();
logger.debug("PairThisDeviceDialog : setDeviceList : Found these video devices: "
+ dev);
camComboBox
.setModel(new javax.swing.DefaultComboBoxModel<CameraDevice>(
dev.toArray(new CameraDevice[] {})));
}
@Override
public void dispose() {
super.dispose();
if (webCam != null) {
webCam.stop();
}
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JPanel buttonPanel;
private javax.swing.JComboBox<CameraDevice> camComboBox;
private javax.swing.JLabel camLabel;
private javax.swing.JPanel camLifeViewPanel;
private javax.swing.JButton cancelButton;
private javax.swing.JButton enterPasswordButton;
private javax.swing.JButton importFileButton;
private javax.swing.JLabel infoMessageLabel;
// End of variables declaration//GEN-END:variables
private boolean isPanboxQRCode(String text) {
if (text.matches("^[0-9A-Za-z.]+:[A-Z0-9a-z+/]+={0,2}$")) {
return true;
} else {
return false;
}
}
@Override
public void qrCodeDetected(String text) {
text = text.trim();
if (isPanboxQRCode(text)) {
logger.debug("PairThisDeviceDialog : qrCodeDetected : Detected new Panbox QR Code: "
+ text);
pairingPassword = text;
this.dispose();
} else {
logger.debug("PairThisDeviceDialog : qrCodeDetected : Detected new non-Panbox QR Code: "
+ text);
}
}
public File getPairingFile() {
return pairingFile;
}
public String getPairingPassword() throws OperationAbortedException {
if (pairingPassword == null && pairingFile == null) {
throw new OperationAbortedException(
"Pairing password has not been specified.");
}
return pairingPassword;
}
}