/* * * 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; } }