package pctelelog.ui;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import net.glxn.qrgen.QRCode;
import net.glxn.qrgen.image.ImageType;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Shell;
/**
* The pairing assistant for the android app
*
* @author Jeremy May
*
*/
public class PairingWindow implements WindowWidget, SelectionListener, DisposeListener {
/** Event Loop **/
private Display m_mainDisplay = null;
private Shell m_windowShell = null;
private ArrayList<String> m_ips = null;
private Label m_qrcode = null;
public PairingWindow(Display display) {
if(display == null) { throw new NullPointerException("Display cannot be null"); }
m_mainDisplay = display;
m_windowShell = new Shell(getMainDisplay(), SWT.CLOSE | SWT.APPLICATION_MODAL);
m_windowShell.setSize(270, 300);
init();
m_windowShell.pack();
}
public Shell getWindowShell() {
return m_windowShell;
}
public Display getMainDisplay() {
return m_mainDisplay;
}
/**
* Open/Show the pairing window
*
*/
public void open() {
getWindowShell().open();
}
/**
* Handler for Network LIst selections
*
*/
public void widgetSelected(SelectionEvent e) {
// Get selected item text
List source = (List) e.getSource();
int index = source.getSelectionIndex();
String ip = m_ips.get(index);
if(ip == "" || ip == null) { return; }
else {
displayQRImage(ip);
}
}
/**
* Handle cleanup of resources on window dispose
*
*/
public void widgetDisposed(DisposeEvent e) {
clearQRImage();
}
/**
* Get the Array List of IPs
*
* @return an array list of ips
*/
private ArrayList<String> getIPs() {
return m_ips;
}
/**
* Get the QR Code Label for the window
*
* @return the label
*/
private Label getQRCodeLabel() {
return m_qrcode;
}
/**
* Set up the Window
*
*/
private void init() {
m_ips = enumInterfaces();
createLayout();
createNetworkList();
createQRCodeLabel();
createCloseButton();
}
/**
* Get the IP of all non-loopback
* devices
*
* @return an array of IP Strings
*/
private ArrayList<String> enumInterfaces() {
Enumeration<NetworkInterface> interfaces = null;
try {
interfaces = NetworkInterface.getNetworkInterfaces();
} catch (SocketException e) {
e.printStackTrace();
}
ArrayList<NetworkInterface> list = Collections.list(interfaces);
ArrayList<String> strInterface = new ArrayList<String>();
for(NetworkInterface inter : list) {
try {
if(inter.isLoopback()) { continue; }
else {
for(InetAddress addr : Collections.list(inter.getInetAddresses())) {
strInterface.add(addr.getHostAddress());
}
}
} catch(SocketException e) { continue; }
}
return strInterface;
}
/**
* Create the layout
*
*/
private void createLayout() {
GridLayout layout = new GridLayout(1, true);
getWindowShell().setLayout(layout);
}
/**
* Create the Network List
*
*/
private void createNetworkList() {
Label listTxt = new Label(getWindowShell(), SWT.LEFT);
listTxt.setText("Select address to create QRCode:");
listTxt.setLayoutData(new GridData(SWT.FILL, SWT.NONE, false, false));
List list = new List(getWindowShell(), SWT.SINGLE);
list.addSelectionListener(this);
list.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
// Add IPs to list
for(String ip : getIPs()) {
list.add(ip);
}
}
/**
* Create and Assignthe QR Code label that will
* be used for the pairing window
*
*/
private void createQRCodeLabel() {
m_qrcode = new Label(getWindowShell(), SWT.CENTER | SWT.BORDER);
m_qrcode.setSize(250, 250);
m_qrcode.setBackground(getMainDisplay().getSystemColor(SWT.COLOR_WHITE));
m_qrcode.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
m_qrcode.setText("No Address Selected");
}
private void createCloseButton() {
Button close = new Button(getWindowShell(), SWT.PUSH);
close.setText("Close");
close.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true));
close.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
getWindowShell().dispose();
}
});
getWindowShell().setDefaultButton(close);
}
/**
* Show the QR Code for the IP
*
* @param ip an IP
*/
private void displayQRImage(String ip) {
// Dispose of the old image
clearQRImage();
// Generate QRCode
ByteArrayOutputStream stream = new ByteArrayOutputStream();
QRCode.from(ip).to(ImageType.PNG).withSize(250, 250).writeTo(stream);
ByteArrayInputStream input = new ByteArrayInputStream(stream.toByteArray());
// Generate Image and Show it
if(getQRCodeLabel().getImage() != null) { getQRCodeLabel().getImage().dispose(); }
Image img = new Image(getMainDisplay(), input);
getQRCodeLabel().setImage(img);
getQRCodeLabel().setToolTipText("QR for: " + ip);
getWindowShell().pack();
}
/**
* Dispose of the old QR image if it exists
*
*/
private void clearQRImage() {
Image image = getQRCodeLabel().getImage();
if(image != null) {
image.dispose();
}
}
public void widgetDefaultSelected(SelectionEvent e) {}
}