You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

603 lines
22 KiB
Java

/*
* Copyright (C) 2009-2017 Alistair Neil <info@dazzleships.net>
*
* 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 2
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package client;
import lib.InfoDialog;
import java.awt.Component;
import java.awt.FontMetrics;
import java.awt.Frame;
import java.awt.event.ItemEvent;
import java.util.ArrayList;
import java.util.regex.Pattern;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import lib.Localisation;
/**
*
* @author Alistair Neil, <info@dazzleships.net>
*/
public final class PatternsEditor extends javax.swing.JDialog {
public static final int CANCEL = 0;
public static final int APPLY = 1;
private final PACTableModel pactm = new PACTableModel();
private PacFactory pacFactory = null;
private String strChange = null;
private Frame parent = null;
private String strSelectedCountry = null;
private static final Localisation LOCAL = new Localisation("resources/MessagesBundle");
/**
* Creates a PatternsEditor dialog
*
* @param parent Parent frame
* @param modal Modality
* @param pacfactory PacFactory being edited
*/
public PatternsEditor(java.awt.Frame parent, boolean modal, PacFactory pacfactory) {
super(parent, modal);
this.parent = parent;
pacFactory = pacfactory;
initComponents();
pactm.setColumnName(LOCAL.getString("patterntable_col1"), 0);
pactm.setColumnName(LOCAL.getString("patterntable_col2"), 1);
pactm.setColumnName(LOCAL.getString("patterntable_col3"), 2);
jTablePatterns.setModel(pactm);
jTablePatterns.setDefaultRenderer(String.class, new CustomTableCellRenderer());
// Adjust our column widths
adjustTableColumnWidth(0, "AAAAAAAAAA");
adjustTableColumnWidth(1, "AAAAAAAAAAAAAAAAAAAAAAAA");
adjustTableColumnWidth(2, "AAA");
jTablePatterns.setRowHeight(jLabel1.getHeight() + 1);
jTablePatterns.setShowGrid(true);
jTextDoNotProxy.setText(pacFactory.getDoNotProxy());
}
/**
* Populate the country combobox with a list of countries
*
* @param countries String[] of countries
*/
public void populateCountryComboBox(String[] countries) {
jComboCountry.setModel(new DefaultComboBoxModel<>(countries));
jComboCountry.setSelectedIndex(-1);
}
/**
* Set the selected country
*
* @param country
*/
public void setSelectedCountry(String country) {
jComboCountry.setSelectedItem(country);
}
/**
* Populate the patterns table
*
* @param patterns an ArrayList<String> of pattern rules
*/
private void populatePatternsTable(ArrayList<String> patterns) {
// Clear all entries from table
while (pactm.getRowCount() > 0) {
pactm.removeRow(0);
}
// If patterns null just return;
if (patterns == null) {
strChange = pactm.toString() + jTextDoNotProxy.getText();
return;
}
// Populate table
Pattern pat = Pattern.compile(",");
String[] split;
Object[] obj = new Object[3];
for (String s : patterns) {
split = pat.split(s);
if (split.length < 4) {
continue;
}
obj[0] = split[0];
obj[1] = split[1];
try {
obj[2] = Boolean.valueOf(split[2]);
} catch (Exception ex) {
obj[2] = true;
}
pactm.addRow(obj, (split[3]).contains("user"));
}
strChange = pactm.toString() + jTextDoNotProxy.getText();
}
/**
* Test to see if patterns table has changed
*
* @return boolean True if changed
*/
private boolean isPatternsTableChanged() {
if (strChange == null) {
return false;
}
String temp = pactm.toString() + jTextDoNotProxy.getText();
return (!temp.contentEquals(strChange));
}
/**
* Save patterns and rebuild active country pac if required
*/
private void savePatterns() {
String s;
Boolean b;
ArrayList<String> listUser = new ArrayList<>();
int rowCount = pactm.getRowCount();
if (rowCount > 0) {
for (int i = 0; i < rowCount; i++) {
s = pactm.getValueAt(i, 0) + "," + pactm.getValueAt(i, 1);
b = (Boolean) pactm.getValueAt(i, 2);
if (b) {
s += ",true";
} else {
s += ",false";
}
listUser.add(s);
}
}
if (listUser.isEmpty()) {
pacFactory.deletePatternsFile(strSelectedCountry, PacFactory.FILEUSER);
} else {
pacFactory.savePatternsList(strSelectedCountry, PacFactory.FILEUSER, listUser);
}
pacFactory.setDoNotProxy(jTextDoNotProxy.getText());
strChange = pactm.toString() + jTextDoNotProxy.getText();
}
/**
* This is a check to see if any pattern save are required before exiting
* the pattern editor
*/
private int saveOnExitCheck() {
int result = CANCEL;
if (jButtonSave.isEnabled()) {
jComboCountry.hidePopup();
InfoDialog id = new InfoDialog(parent);
id.createWarn(LOCAL.getString("dlg_patterneditsave_title"),
LOCAL.getString("dlg_patterneditsave_body"));
id.setVisible(true);
strChange = null;
if (id.getReturnStatus() == InfoDialog.OK) {
savePatterns();
result = APPLY;
}
jButtonSave.setEnabled(isPatternsTableChanged());
}
return result;
}
/**
* Will adjust table column widths based on fontmetrics
*
* @param col Column to be adjusted
* @param text Text string to adjust for
*/
private void adjustTableColumnWidth(int col, String text) {
FontMetrics ourFontMetrics = getFontMetrics(jTablePatterns.getTableHeader().getFont());
jTablePatterns.getColumn(jTablePatterns.getColumnName(col)).setPreferredWidth(ourFontMetrics.stringWidth(text));
}
/**
* @return the return status of this dialog - one of RET_OK or RET_CANCEL
*/
public int getReturnStatus() {
return returnStatus;
}
/**
* 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() {
jButtonSave = new javax.swing.JButton();
jButtonCancel = new javax.swing.JButton();
jComboCountry = new javax.swing.JComboBox<>();
jButtonDeletePattern = new javax.swing.JButton();
jButtonAddPattern = new javax.swing.JButton();
jLabel1 = new javax.swing.JLabel();
jScrollPane1 = new javax.swing.JScrollPane();
jTablePatterns = new javax.swing.JTable();
jLabel17 = new javax.swing.JLabel();
jTextDoNotProxy = new javax.swing.JTextField();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
setTitle("Proxy Pattern Editor");
setIconImage(null);
setResizable(false);
addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent evt) {
closeDialog(evt);
}
});
jButtonSave.setText(LOCAL.getString("button_save")); // NOI18N
jButtonSave.setEnabled(false);
jButtonSave.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButtonSaveActionPerformed(evt);
}
});
jButtonCancel.setText(LOCAL.getString("button_close")); // NOI18N
jButtonCancel.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButtonCancelActionPerformed(evt);
}
});
jComboCountry.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
jComboCountry.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
jComboCountryItemStateChanged(evt);
}
});
jButtonDeletePattern.setText(LOCAL.getString("button_delete")); // NOI18N
jButtonDeletePattern.setEnabled(false);
jButtonDeletePattern.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButtonDeletePatternActionPerformed(evt);
}
});
jButtonAddPattern.setText(LOCAL.getString("button_addnew")); // NOI18N
jButtonAddPattern.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButtonAddPatternActionPerformed(evt);
}
});
jLabel1.setText(LOCAL.getString("label_editcountry")); // NOI18N
jTablePatterns.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
},
new String [] {
}
));
jTablePatterns.setToolTipText(LOCAL.getString("ttip_patterntable")); // NOI18N
jTablePatterns.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_LAST_COLUMN);
jTablePatterns.setSelectionMode(javax.swing.ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
jTablePatterns.getTableHeader().setResizingAllowed(false);
jTablePatterns.getTableHeader().setReorderingAllowed(false);
jTablePatterns.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseReleased(java.awt.event.MouseEvent evt) {
jTablePatternsMouseReleased(evt);
}
});
jTablePatterns.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyReleased(java.awt.event.KeyEvent evt) {
jTablePatternsKeyReleased(evt);
}
});
jScrollPane1.setViewportView(jTablePatterns);
jLabel17.setText(LOCAL.getString("label_donotproxy")); // NOI18N
jTextDoNotProxy.setToolTipText(LOCAL.getString("ttip_donotproxy")); // NOI18N
jTextDoNotProxy.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusLost(java.awt.event.FocusEvent evt) {
jTextDoNotProxyFocusLost(evt);
}
});
jTextDoNotProxy.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyReleased(java.awt.event.KeyEvent evt) {
jTextDoNotProxyKeyReleased(evt);
}
});
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)
.addComponent(jScrollPane1)
.addGroup(layout.createSequentialGroup()
.addComponent(jComboCountry, javax.swing.GroupLayout.PREFERRED_SIZE, 264, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel1))
.addGroup(layout.createSequentialGroup()
.addComponent(jButtonDeletePattern)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jButtonAddPattern)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jButtonCancel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jButtonSave))
.addGroup(layout.createSequentialGroup()
.addComponent(jLabel17)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jTextDoNotProxy)))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel1)
.addComponent(jComboCountry, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 341, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jTextDoNotProxy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel17))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jButtonDeletePattern)
.addComponent(jButtonCancel)
.addComponent(jButtonSave)
.addComponent(jButtonAddPattern))
.addContainerGap())
);
pack();
}// </editor-fold>//GEN-END:initComponents
private void jButtonSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonSaveActionPerformed
savePatterns();
jButtonSave.setEnabled(isPatternsTableChanged());
doClose(APPLY);
}//GEN-LAST:event_jButtonSaveActionPerformed
private void jButtonCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonCancelActionPerformed
doClose(saveOnExitCheck());
}//GEN-LAST:event_jButtonCancelActionPerformed
/**
* Closes the dialog
*/
private void closeDialog(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_closeDialog
doClose(CANCEL);
}//GEN-LAST:event_closeDialog
private void jComboCountryItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_jComboCountryItemStateChanged
if (evt.getStateChange() != ItemEvent.SELECTED) {
return;
}
saveOnExitCheck();
// Check for no entries
if (jComboCountry.getItemCount() == 0) {
jTablePatterns.setEnabled(false);
jButtonDeletePattern.setEnabled(false);
jButtonAddPattern.setEnabled(false);
jButtonSave.setEnabled(false);
populatePatternsTable(null);
return;
}
// We reach here if we have selected a valid country
jTablePatterns.setEnabled(true);
jButtonAddPattern.setEnabled(true);
strSelectedCountry = (String) jComboCountry.getSelectedItem();
ArrayList<String> patterns = new ArrayList<>();
pacFactory.loadPatternsList(strSelectedCountry, patterns);
populatePatternsTable(patterns);
}//GEN-LAST:event_jComboCountryItemStateChanged
private void jTablePatternsMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jTablePatternsMouseReleased
jButtonDeletePattern.setEnabled(jTablePatterns.isCellEditable(jTablePatterns.getSelectedRow(), 0));
jButtonSave.setEnabled(isPatternsTableChanged());
}//GEN-LAST:event_jTablePatternsMouseReleased
private void jButtonDeletePatternActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonDeletePatternActionPerformed
int[] i;
while (true) {
i = jTablePatterns.getSelectedRows();
if (i.length == 0) {
break;
}
pactm.removeRow(i[0]);
}
jButtonDeletePattern.setEnabled(false);
jButtonSave.setEnabled(isPatternsTableChanged());
}//GEN-LAST:event_jButtonDeletePatternActionPerformed
private void jTablePatternsKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jTablePatternsKeyReleased
jButtonSave.setEnabled(isPatternsTableChanged());
}//GEN-LAST:event_jTablePatternsKeyReleased
private void jButtonAddPatternActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonAddPatternActionPerformed
QuickAddDialog qad = new QuickAddDialog(parent, true);
qad.setTitle("Add new pattern");
qad.setLocationRelativeTo(this);
qad.setVisible(true);
if (qad.getReturnStatus() == QuickAddDialog.CANCEL) {
return;
}
if (!qad.getPattern().isEmpty()) {
pactm.addRow(new Object[]{qad.getDescription(), qad.getPattern(), Boolean.TRUE}, true);
}
jButtonSave.setEnabled(isPatternsTableChanged());
}//GEN-LAST:event_jButtonAddPatternActionPerformed
private void jTextDoNotProxyKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jTextDoNotProxyKeyReleased
jButtonSave.setEnabled(isPatternsTableChanged());
}//GEN-LAST:event_jTextDoNotProxyKeyReleased
private void jTextDoNotProxyFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jTextDoNotProxyFocusLost
jButtonSave.setEnabled(isPatternsTableChanged());
}//GEN-LAST:event_jTextDoNotProxyFocusLost
private void doClose(int retStatus) {
returnStatus = retStatus;
setVisible(false);
dispose();
}
/**
* CustomTableCellRenderer
*/
public class CustomTableCellRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
Component c = super.getTableCellRendererComponent(table, value,
isSelected, hasFocus, row, column);
// Only for specific cell
if (table.isRowSelected(row)) {
return c;
}
if (column < 2) {
if (table.getModel().isCellEditable(row, column)) {
c.setBackground(javax.swing.UIManager.getDefaults().getColor("Table.background"));
} else {
c.setBackground(javax.swing.UIManager.getDefaults().getColor("control"));
}
}
return c;
}
}
/**
* PACTableModel class
*/
public class PACTableModel extends DefaultTableModel {
@SuppressWarnings("rawtypes")
private final String[] columnNames = {"Description", "Pattern", "Enabled"};
private final Class[] types = new Class[]{
java.lang.String.class, java.lang.String.class, java.lang.Boolean.class
};
private final ArrayList<Boolean> rowedit = new ArrayList<>();
public void addRow(Object[] obj, boolean editable) {
addRow(obj);
rowedit.add(editable);
}
/**
* Constructor
*/
public PACTableModel() {
}
/**
* Get column count as integer
*
* @return columns as integer
*/
@Override
public int getColumnCount() {
return types.length;
}
/**
* Get column class
*
* @param columnIndex
* @return object Class
*/
@Override
@SuppressWarnings("rawtypes")
public Class getColumnClass(int columnIndex) {
return types[columnIndex];
}
/**
* Test if cell at given row, col is editable
*
* @param row
* @param column
* @return True if editable
*/
@Override
public boolean isCellEditable(int row, int column) {
if (column == 2) {
return true;
} else {
return rowedit.get(row);
}
}
/**
* Get column name at given index
*
* @param index
* @return name as string
*/
@Override
public String getColumnName(int index) {
return columnNames[index];
}
/**
* Set the column name at the specified index
*
* @param name
* @param index
*/
public void setColumnName(String name, int index) {
if (index < columnNames.length) {
columnNames[index] = name;
}
}
/**
* Returns all data as a single string
*
* @return string
*/
@Override
public String toString() {
return getDataVector().toString();
}
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton jButtonAddPattern;
private javax.swing.JButton jButtonCancel;
private javax.swing.JButton jButtonDeletePattern;
private javax.swing.JButton jButtonSave;
private javax.swing.JComboBox<String> jComboCountry;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel17;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JTable jTablePatterns;
private javax.swing.JTextField jTextDoNotProxy;
// End of variables declaration//GEN-END:variables
private int returnStatus = CANCEL;
}