First commit
This commit is contained in:
parent
40bff34006
commit
57d60609e2
179 changed files with 59241 additions and 0 deletions
47
src/SelekTOR.java
Normal file
47
src/SelekTOR.java
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (C) 2014 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Explanation of why this is in the default package
|
||||
*
|
||||
* @author Alistair Neil <info@dazzleships.net>
|
||||
*
|
||||
* The app launcher is here in the default package which should not normally be
|
||||
* used. The method java uses to launche its apps is not fully compatible with
|
||||
* various Linux launchers panels such as Dockbarx or Unity launchers and thus
|
||||
* confuses those apps. By putting this simple launch handle here in the default
|
||||
* package the Linux dockpanel launchers should function correctly when it
|
||||
* commes to application pinning.
|
||||
*
|
||||
*/
|
||||
public class SelekTOR {
|
||||
|
||||
/**
|
||||
* @param args the command line arguments
|
||||
*/
|
||||
public static void main(final String args[]) {
|
||||
|
||||
java.awt.EventQueue.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
new client.SelekTOR(args);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
246
src/client/ExitNodeTableModel.java
Normal file
246
src/client/ExitNodeTableModel.java
Normal file
|
@ -0,0 +1,246 @@
|
|||
/*
|
||||
* 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 java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alistair Neil <info@dazzleships.net>
|
||||
*/
|
||||
public class ExitNodeTableModel extends DefaultTableModel {
|
||||
|
||||
private final List<String> salFinger = Collections.synchronizedList(new ArrayList<String>());
|
||||
private final String[] columnNames = new String[5];
|
||||
private NodeItem ni;
|
||||
|
||||
public ExitNodeTableModel() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the table model of all data
|
||||
*/
|
||||
public void clear() {
|
||||
getDataVector().clear();
|
||||
salFinger.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of columns
|
||||
*
|
||||
* @return columns as integer
|
||||
*/
|
||||
@Override
|
||||
public int getColumnCount() {
|
||||
return columnNames.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the cell is editable
|
||||
*
|
||||
* @param row Cell row
|
||||
* @param col Cell column
|
||||
* @return True if editable
|
||||
*/
|
||||
@Override
|
||||
public boolean isCellEditable(int row, int col) {
|
||||
return col == 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set value with given fingerprint at given column
|
||||
*
|
||||
* @param value Value
|
||||
* @param finger Fingerprint
|
||||
* @param col Column
|
||||
*/
|
||||
public void setValueAt(Object value, String finger, int col) {
|
||||
setValueAt(value, salFinger.indexOf(finger), col);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to set the testing field cell values for a specific
|
||||
* fingerprint, the hops field is hidden and does npt show up in table
|
||||
*
|
||||
* @param finger Fingerprint
|
||||
* @param latency Latency value
|
||||
* @param status Status value
|
||||
* @param hops Hops value
|
||||
*/
|
||||
public synchronized void setTestFieldValues(String finger, long latency, String status, String hops) {
|
||||
int row = salFinger.indexOf(finger);
|
||||
if (row > -1) {
|
||||
ni = (NodeItem) super.getValueAt(row, 0);
|
||||
ni.setTestLatency(latency);
|
||||
ni.setTestingMessage(status);
|
||||
ni.setCircuitHops(hops);
|
||||
fireTableRowsUpdated(row, row);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get row nodeitem
|
||||
*
|
||||
* @param row
|
||||
* @return a nodeitem
|
||||
*/
|
||||
public NodeItem getNodeItemAt(int row) {
|
||||
return (NodeItem) super.getValueAt(row, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cell value at row,col
|
||||
*
|
||||
* @param value
|
||||
* @param row
|
||||
* @param col
|
||||
*/
|
||||
@Override
|
||||
public void setValueAt(Object value, int row, int col) {
|
||||
try {
|
||||
ni = (NodeItem) super.getValueAt(row, 0);
|
||||
switch (col) {
|
||||
case 1:
|
||||
ni.setBandwidth((Float) value);
|
||||
break;
|
||||
case 2:
|
||||
ni.setTestLatency((Long) value);
|
||||
break;
|
||||
case 3:
|
||||
ni.setTestingMessage((String) value);
|
||||
break;
|
||||
case 4:
|
||||
ni.setFavouriteEnabled((Boolean) value);
|
||||
break;
|
||||
case 5:
|
||||
salFinger.set(row, (String) value);
|
||||
ni.setFingerprint((String) value);
|
||||
return;
|
||||
case 6:
|
||||
ni.setCircuitHops((String) value);
|
||||
return;
|
||||
}
|
||||
fireTableCellUpdated(row, col);
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cell value as object at row,col
|
||||
*
|
||||
* @param row
|
||||
* @param col
|
||||
* @return value as object
|
||||
*/
|
||||
@Override
|
||||
public Object getValueAt(int row, int col) {
|
||||
ni = (NodeItem) super.getValueAt(row, 0);
|
||||
Object obj = null;
|
||||
switch (col) {
|
||||
case 0:
|
||||
obj = ni.getNickName();
|
||||
break;
|
||||
case 1:
|
||||
obj = ni.getBandwidth();
|
||||
break;
|
||||
case 2:
|
||||
obj = ni.getTestLatency();
|
||||
break;
|
||||
case 3:
|
||||
obj = ni.getTestingMessage();
|
||||
break;
|
||||
case 4:
|
||||
obj = ni.isFavourite();
|
||||
break;
|
||||
case 5:
|
||||
obj = ni.getFingerprint();
|
||||
break;
|
||||
case 6:
|
||||
obj = ni.getCircuitHops();
|
||||
break;
|
||||
case 7:
|
||||
obj = ni.getTestStatus();
|
||||
break;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add rowdata with given data object array
|
||||
*
|
||||
* @param rowData
|
||||
*/
|
||||
@Override
|
||||
public void addRow(Object[] rowData) {
|
||||
super.addRow(rowData);
|
||||
salFinger.add(((NodeItem) rowData[0]).getFingerprint());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column class at given index
|
||||
*
|
||||
* @param index
|
||||
* @return Class
|
||||
*/
|
||||
@Override
|
||||
public Class getColumnClass(int index) {
|
||||
Class cl;
|
||||
switch (index) {
|
||||
case 1:
|
||||
cl = Float.class;
|
||||
break;
|
||||
case 2:
|
||||
cl = Long.class;
|
||||
break;
|
||||
case 4:
|
||||
cl = Boolean.class;
|
||||
break;
|
||||
default:
|
||||
cl = String.class;
|
||||
break;
|
||||
}
|
||||
return cl;
|
||||
}
|
||||
|
||||
}
|
177
src/client/GuardNodeDialog.form
Normal file
177
src/client/GuardNodeDialog.form
Normal file
|
@ -0,0 +1,177 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.6" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
|
||||
<NonVisualComponents>
|
||||
<Container class="javax.swing.JPopupMenu" name="popupTable">
|
||||
<Events>
|
||||
<EventHandler event="popupMenuWillBecomeVisible" listener="javax.swing.event.PopupMenuListener" parameters="javax.swing.event.PopupMenuEvent" handler="popupTablePopupMenuWillBecomeVisible"/>
|
||||
</Events>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout">
|
||||
<Property name="useNullLayout" type="boolean" value="true"/>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<MenuItem class="javax.swing.JMenuItem" name="jMenuNodeDetails">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="table_popup_details" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jMenuNodeDetailsActionPerformed"/>
|
||||
</Events>
|
||||
</MenuItem>
|
||||
<MenuItem class="javax.swing.JMenuItem" name="jMenuWhois">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="table_popup_whois" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jMenuWhoisActionPerformed"/>
|
||||
</Events>
|
||||
</MenuItem>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</NonVisualComponents>
|
||||
<Properties>
|
||||
<Property name="defaultCloseOperation" type="int" value="2"/>
|
||||
<Property name="title" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="wintitle_guardnodes" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
<Property name="resizable" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<SyntheticProperties>
|
||||
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
|
||||
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
|
||||
</SyntheticProperties>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="jButtonClear" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="jButtonClose" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jButtonApply" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="jTextArea1" max="32767" attributes="0"/>
|
||||
<Component id="jScrollPane1" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jTextArea1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jScrollPane1" pref="367" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jButtonClear" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jButtonApply" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jButtonClose" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTable" name="jTableGuards">
|
||||
<Properties>
|
||||
<Property name="autoCreateRowSorter" type="boolean" value="true"/>
|
||||
<Property name="selectionModel" type="javax.swing.ListSelectionModel" editor="org.netbeans.modules.form.editors2.JTableSelectionModelEditor">
|
||||
<JTableSelectionModel selectionMode="0"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="jTableGuardsMouseClicked"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JButton" name="jButtonClear">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="button_clearguards" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="ttip_clearguards" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButtonClearActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="jButtonApply">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="button_apply" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButtonApplyActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="jButtonClose">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="button_close" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButtonCloseActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextArea" name="jTextArea1">
|
||||
<Properties>
|
||||
<Property name="editable" type="boolean" value="false"/>
|
||||
<Property name="columns" type="int" value="40"/>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new javax.swing.JLabel().getFont()" type="code"/>
|
||||
</Property>
|
||||
<Property name="lineWrap" type="boolean" value="true"/>
|
||||
<Property name="rows" type="int" value="2"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="label_guard_minimum" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
<Property name="wrapStyleWord" type="boolean" value="true"/>
|
||||
<Property name="disabledTextColor" type="java.awt.Color" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection component="jTextArea1" name="foreground" type="property"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[0, 0]"/>
|
||||
</Property>
|
||||
<Property name="opaque" type="boolean" value="false"/>
|
||||
<Property name="requestFocusEnabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
299
src/client/GuardNodeDialog.java
Normal file
299
src/client/GuardNodeDialog.java
Normal file
|
@ -0,0 +1,299 @@
|
|||
/*
|
||||
* 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 java.awt.event.MouseEvent;
|
||||
import javax.swing.event.TableModelEvent;
|
||||
import lib.GTKFixes;
|
||||
import lib.Localisation;
|
||||
import lib.Utilities;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alistair Neil <info@dazzleships.net>
|
||||
*/
|
||||
public class GuardNodeDialog extends javax.swing.JDialog {
|
||||
|
||||
public static final int CANCEL = 0;
|
||||
public static final int APPLY = 1;
|
||||
public static final int RESET = 2;
|
||||
private static final String ATLAS = "https://atlas.torproject.org/";
|
||||
private static final Localisation LOCAL = new Localisation("resources/MessagesBundle");
|
||||
private int intRowSelected = -1;
|
||||
private int returnStatus = CANCEL;
|
||||
private final GuardNodeTableModel gntm;
|
||||
private NodeList nl;
|
||||
|
||||
/**
|
||||
* Creates new form GuardNodeDialog
|
||||
*
|
||||
* @param parent
|
||||
* @param modal
|
||||
*/
|
||||
public GuardNodeDialog(java.awt.Frame parent, boolean modal) {
|
||||
super(parent, modal);
|
||||
initComponents();
|
||||
GTKFixes.fixTextAreaColor(jTextArea1);
|
||||
jTableGuards.setComponentPopupMenu(popupTable);
|
||||
gntm = new GuardNodeTableModel();
|
||||
gntm.setColumnName(LOCAL.getString("guardtable_col1"), 0);
|
||||
gntm.setColumnName(LOCAL.getString("guardtable_col2"), 1);
|
||||
gntm.setColumnName(LOCAL.getString("guardtable_col3"), 2);
|
||||
gntm.setColumnName(LOCAL.getString("guardtable_col4"), 3);
|
||||
gntm.addTableModelListener(new javax.swing.event.TableModelListener() {
|
||||
|
||||
@Override
|
||||
public void tableChanged(TableModelEvent e) {
|
||||
if (gntm.getEnabledCount() >= 3 || gntm.getEnabledCount() == 0) {
|
||||
jButtonApply.setEnabled(true);
|
||||
} else {
|
||||
jButtonApply.setEnabled(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
jTableGuards.setModel(gntm);
|
||||
adjustGuardTableColumns();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the nodelist
|
||||
*
|
||||
* @param nl
|
||||
*/
|
||||
public void setNodeList(NodeList nl) {
|
||||
this.nl = nl;
|
||||
this.nl.setGuardNodeTableModel(gntm);
|
||||
this.nl.refreshGuardTableModel();
|
||||
adjustGuardTableColumns();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust guard table column widths
|
||||
*/
|
||||
private void adjustGuardTableColumns() {
|
||||
// Adjust table column widths
|
||||
Utilities.adjustTableColumnWidth(jTableGuards,
|
||||
"XXXXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
"XXXXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
"XXXXXXXXXXXXXXX",
|
||||
"XXXXXXXXXXXXXXX");
|
||||
}
|
||||
|
||||
private void clearSelections() {
|
||||
|
||||
for (int row = 0; row < jTableGuards.getRowCount(); row++) {
|
||||
jTableGuards.setValueAt(false, row, 3);
|
||||
}
|
||||
}
|
||||
|
||||
private void doClose(int retStatus) {
|
||||
returnStatus = retStatus;
|
||||
setVisible(false);
|
||||
dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
popupTable = new javax.swing.JPopupMenu();
|
||||
jMenuNodeDetails = new javax.swing.JMenuItem();
|
||||
jMenuWhois = new javax.swing.JMenuItem();
|
||||
jScrollPane1 = new javax.swing.JScrollPane();
|
||||
jTableGuards = new javax.swing.JTable();
|
||||
jButtonClear = new javax.swing.JButton();
|
||||
jButtonApply = new javax.swing.JButton();
|
||||
jButtonClose = new javax.swing.JButton();
|
||||
jTextArea1 = new javax.swing.JTextArea();
|
||||
|
||||
popupTable.addPopupMenuListener(new javax.swing.event.PopupMenuListener() {
|
||||
public void popupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent evt) {
|
||||
popupTablePopupMenuWillBecomeVisible(evt);
|
||||
}
|
||||
public void popupMenuWillBecomeInvisible(javax.swing.event.PopupMenuEvent evt) {
|
||||
}
|
||||
public void popupMenuCanceled(javax.swing.event.PopupMenuEvent evt) {
|
||||
}
|
||||
});
|
||||
|
||||
jMenuNodeDetails.setText(LOCAL.getString("table_popup_details")); // NOI18N
|
||||
jMenuNodeDetails.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
jMenuNodeDetailsActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
popupTable.add(jMenuNodeDetails);
|
||||
|
||||
jMenuWhois.setText(LOCAL.getString("table_popup_whois")); // NOI18N
|
||||
jMenuWhois.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
jMenuWhoisActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
popupTable.add(jMenuWhois);
|
||||
|
||||
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
|
||||
setTitle(LOCAL.getString("wintitle_guardnodes")); // NOI18N
|
||||
setResizable(false);
|
||||
|
||||
jTableGuards.setAutoCreateRowSorter(true);
|
||||
jTableGuards.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
|
||||
jTableGuards.addMouseListener(new java.awt.event.MouseAdapter() {
|
||||
public void mouseClicked(java.awt.event.MouseEvent evt) {
|
||||
jTableGuardsMouseClicked(evt);
|
||||
}
|
||||
});
|
||||
jScrollPane1.setViewportView(jTableGuards);
|
||||
|
||||
jButtonClear.setText(LOCAL.getString("button_clearguards")); // NOI18N
|
||||
jButtonClear.setToolTipText(LOCAL.getString("ttip_clearguards")); // NOI18N
|
||||
jButtonClear.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
jButtonClearActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jButtonApply.setText(LOCAL.getString("button_apply")); // NOI18N
|
||||
jButtonApply.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
jButtonApplyActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jButtonClose.setText(LOCAL.getString("button_close")); // NOI18N
|
||||
jButtonClose.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
jButtonCloseActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jTextArea1.setEditable(false);
|
||||
jTextArea1.setColumns(40);
|
||||
jTextArea1.setFont(new javax.swing.JLabel().getFont());
|
||||
jTextArea1.setLineWrap(true);
|
||||
jTextArea1.setRows(2);
|
||||
jTextArea1.setText(LOCAL.getString("label_guard_minimum")); // NOI18N
|
||||
jTextArea1.setWrapStyleWord(true);
|
||||
jTextArea1.setDisabledTextColor(jTextArea1.getForeground());
|
||||
jTextArea1.setEnabled(false);
|
||||
jTextArea1.setMinimumSize(new java.awt.Dimension(0, 0));
|
||||
jTextArea1.setOpaque(false);
|
||||
jTextArea1.setRequestFocusEnabled(false);
|
||||
|
||||
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(jButtonClear)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(jButtonClose)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jButtonApply))
|
||||
.addComponent(jTextArea1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(jScrollPane1))
|
||||
.addContainerGap())
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(jTextArea1, 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, 367, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jButtonClear)
|
||||
.addComponent(jButtonApply)
|
||||
.addComponent(jButtonClose))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
pack();
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void jButtonCloseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonCloseActionPerformed
|
||||
doClose(CANCEL);
|
||||
}//GEN-LAST:event_jButtonCloseActionPerformed
|
||||
|
||||
private void jButtonApplyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonApplyActionPerformed
|
||||
nl.saveGuardWhitelist();
|
||||
doClose(APPLY);
|
||||
}//GEN-LAST:event_jButtonApplyActionPerformed
|
||||
|
||||
private void jButtonClearActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonClearActionPerformed
|
||||
clearSelections();
|
||||
}//GEN-LAST:event_jButtonClearActionPerformed
|
||||
|
||||
private void jMenuNodeDetailsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuNodeDetailsActionPerformed
|
||||
String finger = (String) gntm.getValueAt(intRowSelected, 4);
|
||||
finger = finger.replace("$", "");
|
||||
Utilities.openFileExternally(ATLAS + "#details/" + finger);
|
||||
}//GEN-LAST:event_jMenuNodeDetailsActionPerformed
|
||||
|
||||
private void jMenuWhoisActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuWhoisActionPerformed
|
||||
String finger = (String) gntm.getValueAt(intRowSelected, 4);
|
||||
NodeItem ni = nl.getNode(finger);
|
||||
if (ni != null) {
|
||||
Utilities.openFileExternally("https://www.networksolutions.com/whois/results.jsp?ip=" + ni.getIPAddress());
|
||||
}
|
||||
}//GEN-LAST:event_jMenuWhoisActionPerformed
|
||||
|
||||
private void popupTablePopupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent evt) {//GEN-FIRST:event_popupTablePopupMenuWillBecomeVisible
|
||||
jMenuWhois.setEnabled(intRowSelected > -1);
|
||||
jMenuNodeDetails.setEnabled(intRowSelected > -1);
|
||||
}//GEN-LAST:event_popupTablePopupMenuWillBecomeVisible
|
||||
|
||||
private void jTableGuardsMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jTableGuardsMouseClicked
|
||||
if (evt.getButton() != MouseEvent.BUTTON1) {
|
||||
return;
|
||||
}
|
||||
intRowSelected = jTableGuards.getSelectedRow();
|
||||
if (intRowSelected > 0) {
|
||||
intRowSelected = jTableGuards.convertRowIndexToModel(intRowSelected);
|
||||
}
|
||||
}//GEN-LAST:event_jTableGuardsMouseClicked
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton jButtonApply;
|
||||
private javax.swing.JButton jButtonClear;
|
||||
private javax.swing.JButton jButtonClose;
|
||||
private javax.swing.JMenuItem jMenuNodeDetails;
|
||||
private javax.swing.JMenuItem jMenuWhois;
|
||||
private javax.swing.JScrollPane jScrollPane1;
|
||||
private javax.swing.JTable jTableGuards;
|
||||
private javax.swing.JTextArea jTextArea1;
|
||||
private javax.swing.JPopupMenu popupTable;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
203
src/client/GuardNodeTableModel.java
Normal file
203
src/client/GuardNodeTableModel.java
Normal file
|
@ -0,0 +1,203 @@
|
|||
/*
|
||||
* 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 java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alistair Neil <info@dazzleships.net>
|
||||
*/
|
||||
public class GuardNodeTableModel extends DefaultTableModel {
|
||||
|
||||
private final List<String> salFinger = Collections.synchronizedList(new ArrayList<String>());
|
||||
private final String[] columnNames = {"GuardNode", "Country", "BW (MB\\s)", "Trusted"};
|
||||
private NodeItem ni;
|
||||
private int enabledcount;
|
||||
|
||||
public GuardNodeTableModel() {
|
||||
}
|
||||
|
||||
public int getEnabledCount() {
|
||||
return enabledcount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the table model of all data
|
||||
*/
|
||||
public void clear() {
|
||||
getDataVector().clear();
|
||||
salFinger.clear();
|
||||
enabledcount = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of columns
|
||||
*
|
||||
* @return columns as integer
|
||||
*/
|
||||
@Override
|
||||
public int getColumnCount() {
|
||||
return columnNames.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the cell is editable
|
||||
*
|
||||
* @param row Cell row
|
||||
* @param col Cell column
|
||||
* @return True if editable
|
||||
*/
|
||||
@Override
|
||||
public boolean isCellEditable(int row, int col) {
|
||||
return col == 3;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set value with given fingerprint at given column
|
||||
*
|
||||
* @param value Value
|
||||
* @param finger Fingerprint
|
||||
* @param col Column
|
||||
*/
|
||||
public void setValueAt(Object value, String finger, int col) {
|
||||
setValueAt(value, salFinger.indexOf(finger), col);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cell value at row,col
|
||||
*
|
||||
* @param value
|
||||
* @param row
|
||||
* @param col
|
||||
*/
|
||||
@Override
|
||||
public void setValueAt(Object value, int row, int col) {
|
||||
try {
|
||||
ni = (NodeItem) super.getValueAt(row, 0);
|
||||
if (col == 3) {
|
||||
ni.setGuardEnabled((Boolean) value);
|
||||
if (ni.isGuardEnabled()) {
|
||||
enabledcount++;
|
||||
} else {
|
||||
if (enabledcount > 0) {
|
||||
enabledcount--;
|
||||
}
|
||||
}
|
||||
fireTableCellUpdated(row, col);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cell value as object at row,col
|
||||
*
|
||||
* @param row
|
||||
* @param col
|
||||
* @return value as object
|
||||
*/
|
||||
@Override
|
||||
public Object getValueAt(int row, int col) {
|
||||
ni = (NodeItem) super.getValueAt(row, 0);
|
||||
Object obj = null;
|
||||
switch (col) {
|
||||
case 0:
|
||||
obj = ni.getNickName();
|
||||
break;
|
||||
case 1:
|
||||
obj = ni.getCountryName();
|
||||
break;
|
||||
case 2:
|
||||
obj = ni.getBandwidth();
|
||||
break;
|
||||
case 3:
|
||||
obj = ni.isGuardEnabled();
|
||||
break;
|
||||
case 4:
|
||||
obj = ni.getFingerprint();
|
||||
break;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add rowdata with given data object array
|
||||
*
|
||||
* @param rowData
|
||||
*/
|
||||
@Override
|
||||
public void addRow(Object[] rowData) {
|
||||
super.addRow(rowData);
|
||||
ni = (NodeItem) rowData[0];
|
||||
if (ni.isGuardEnabled()) {
|
||||
enabledcount++;
|
||||
}
|
||||
salFinger.add(ni.getFingerprint());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column class at given index
|
||||
*
|
||||
* @param index
|
||||
* @return Class
|
||||
*/
|
||||
@Override
|
||||
public Class getColumnClass(int index) {
|
||||
Class cl;
|
||||
switch (index) {
|
||||
case 2:
|
||||
cl = Float.class;
|
||||
break;
|
||||
case 3:
|
||||
cl = Boolean.class;
|
||||
break;
|
||||
default:
|
||||
cl = String.class;
|
||||
break;
|
||||
}
|
||||
return cl;
|
||||
}
|
||||
|
||||
}
|
405
src/client/NodeItem.java
Normal file
405
src/client/NodeItem.java
Normal file
|
@ -0,0 +1,405 @@
|
|||
/*
|
||||
* 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 java.text.DecimalFormat;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alistair Neil <info@dazzleships.net>
|
||||
*/
|
||||
public class NodeItem extends Object implements Cloneable {
|
||||
|
||||
public static final int TYPE_EXIT = 1;
|
||||
public static final int TYPE_GUARD = 2;
|
||||
public static final int TESTSTATUS_UNKNOWN = 0;
|
||||
public static final int TESTSTATUS_PASSED = 1;
|
||||
public static final int TESTSTATUS_FAILED = 2;
|
||||
private int type;
|
||||
private boolean exitFavourite;
|
||||
private boolean guardEnabled;
|
||||
private boolean httpSupported;
|
||||
private String stable;
|
||||
private String countrycode;
|
||||
private String countryname;
|
||||
private String nickname;
|
||||
private String finger;
|
||||
private String ipaddress;
|
||||
private String testingmess;
|
||||
private String circuithops;
|
||||
private int teststatus;
|
||||
private float bandwidth;
|
||||
private int streams;
|
||||
private long latency;
|
||||
private long testlatency;
|
||||
|
||||
public NodeItem() {
|
||||
this.type = 0;
|
||||
this.exitFavourite = false;
|
||||
this.guardEnabled = false;
|
||||
this.httpSupported = false;
|
||||
this.countrycode = null;
|
||||
this.latency = 9999;
|
||||
this.testlatency = this.latency;
|
||||
this.bandwidth = 0;
|
||||
this.streams = 0;
|
||||
this.countrycode = "";
|
||||
this.countryname = "";
|
||||
this.stable = "";
|
||||
this.testingmess = "";
|
||||
this.ipaddress = "";
|
||||
this.finger = "";
|
||||
this.nickname = "";
|
||||
this.teststatus = TESTSTATUS_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Node type
|
||||
*
|
||||
* @param mask
|
||||
*/
|
||||
public final void setType(int mask) {
|
||||
this.type |= mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear node type
|
||||
*/
|
||||
public final void clearType() {
|
||||
this.type = 0;
|
||||
}
|
||||
|
||||
public boolean isNonUnique() {
|
||||
return (nickname.contains("Default")
|
||||
|| nickname.contains("default")
|
||||
|| nickname.contains("Unnamed"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Is exit node
|
||||
*
|
||||
* @return true if an exit node
|
||||
*/
|
||||
public final boolean isExit() {
|
||||
return (type & TYPE_EXIT) != 0;
|
||||
}
|
||||
|
||||
public boolean isHttpSupported() {
|
||||
return httpSupported;
|
||||
}
|
||||
|
||||
public void setHttpSupported(boolean supported) {
|
||||
httpSupported = supported;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Guard node
|
||||
*
|
||||
* @return true if guard node
|
||||
*/
|
||||
public final boolean isGuard() {
|
||||
return (type & TYPE_GUARD) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set circuit hops
|
||||
*
|
||||
* @param hops
|
||||
*/
|
||||
public final void setCircuitHops(String hops) {
|
||||
circuithops = hops;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get circuit hops
|
||||
*
|
||||
* @return Circuit hops as String
|
||||
*/
|
||||
public final String getCircuitHops() {
|
||||
return circuithops;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Nodeitem testing status message
|
||||
*
|
||||
* @param text
|
||||
*/
|
||||
public final void setTestingMessage(String text) {
|
||||
this.testingmess = text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set testing status flag
|
||||
*
|
||||
* @param status
|
||||
*/
|
||||
public final void setTestStatus(int status) {
|
||||
teststatus = status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get testing status flag
|
||||
*
|
||||
* @return test status
|
||||
*/
|
||||
public final int getTestStatus() {
|
||||
return teststatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Node item status
|
||||
*
|
||||
* @return Nodeitem testing status message as string
|
||||
*/
|
||||
public final String getTestingMessage() {
|
||||
return testingmess;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Nodeitem latency value in ms
|
||||
*
|
||||
* @param latency
|
||||
*/
|
||||
public final void setLatency(long latency) {
|
||||
this.latency = latency;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Nodeitem latency in ms
|
||||
*
|
||||
* @return Latency value in ms
|
||||
*/
|
||||
public final long getLatency() {
|
||||
return latency;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Nodeitem test latency value in ms
|
||||
*
|
||||
* @param latency
|
||||
*/
|
||||
public final void setTestLatency(long latency) {
|
||||
this.testlatency = latency;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Nodeitem test latency in ms
|
||||
*
|
||||
* @return Latency value in ms
|
||||
*/
|
||||
public final long getTestLatency() {
|
||||
return testlatency;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set exit enabled status of Nodeitem
|
||||
*
|
||||
* @param enabled
|
||||
*/
|
||||
public final void setFavouriteEnabled(boolean enabled) {
|
||||
this.exitFavourite = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get exit enabled status of Nodeitem
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
public final boolean isFavourite() {
|
||||
return exitFavourite;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set guard enabled status of Nodeitem
|
||||
*
|
||||
* @param enabled
|
||||
*/
|
||||
public final void setGuardEnabled(boolean enabled) {
|
||||
this.guardEnabled = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get guard enabled status of Nodeitem
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
public final boolean isGuardEnabled() {
|
||||
return guardEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Nodeitem stability yes/no/unknown
|
||||
*
|
||||
* @param stability
|
||||
*/
|
||||
public final void setStable(String stability) {
|
||||
this.stable = stability;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Nodeitem stability
|
||||
*
|
||||
* @return Stability
|
||||
*/
|
||||
public final String getStability() {
|
||||
return stable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Nodeitem with its two letter country code abbreviation
|
||||
*
|
||||
* @param abrv
|
||||
*/
|
||||
public final void setCountryCode(String abrv) {
|
||||
countrycode = abrv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get nodeitem two letter country code abbreviation
|
||||
*
|
||||
* @return Country code as string
|
||||
*/
|
||||
public final String getCountryCode() {
|
||||
return countrycode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Nodeitem with its full country name
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
public final void setCountryName(String name) {
|
||||
countryname = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get nodeitem full country name
|
||||
*
|
||||
* @return Country name as string
|
||||
*/
|
||||
public final String getCountryName() {
|
||||
return countryname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set nodeitem name
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
public final void setNickName(String name) {
|
||||
nickname = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get nodeitem unique name
|
||||
*
|
||||
* @return Node name as string
|
||||
*/
|
||||
public final String getNickName() {
|
||||
return nickname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set node item bandwidth
|
||||
*
|
||||
* @param bw
|
||||
*/
|
||||
public final void setBandwidth(float bw) {
|
||||
bandwidth = bw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get nodeitem bandwith
|
||||
*
|
||||
* @return Bandwidth as long, in kb/s
|
||||
*/
|
||||
public final float getBandwidth() {
|
||||
Float result;
|
||||
try {
|
||||
DecimalFormat df = new DecimalFormat("#0.##");
|
||||
result = Float.parseFloat(df.format(bandwidth).replace(",", "."));
|
||||
} catch (Exception ex) {
|
||||
result = (float) 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set nodeitem number of streams
|
||||
*
|
||||
* @param streams
|
||||
*/
|
||||
public final void setStreams(int streams) {
|
||||
this.streams = streams;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get nodeitems active streams
|
||||
*
|
||||
* @return Number of active streams as int
|
||||
*/
|
||||
public final int getStreams() {
|
||||
return streams;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set nodeitem fingerprint
|
||||
*
|
||||
* @param fp
|
||||
*/
|
||||
public final void setFingerprint(String fp) {
|
||||
finger = fp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get nodeitems fingerprint
|
||||
*
|
||||
* @return Tor node fingerprint as string
|
||||
*/
|
||||
public final String getFingerprint() {
|
||||
return finger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set nodeitem ip address
|
||||
*
|
||||
* @param ip
|
||||
*/
|
||||
public final void setIPAddress(String ip) {
|
||||
ipaddress = ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get nodeitem ip address
|
||||
*
|
||||
* @return IP address as a string
|
||||
*/
|
||||
public final String getIPAddress() {
|
||||
return ipaddress;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeItem clone() {
|
||||
try {
|
||||
return (NodeItem) super.clone();
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
757
src/client/NodeList.java
Normal file
757
src/client/NodeList.java
Normal file
|
@ -0,0 +1,757 @@
|
|||
/*
|
||||
* 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 java.text.Collator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.regex.Pattern;
|
||||
import lib.Localisation;
|
||||
import lib.SimpleFile;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alistair Neil <info@dazzleships.net>
|
||||
*/
|
||||
public class NodeList {
|
||||
|
||||
public static final int NODELIST_IDLE = 0;
|
||||
public static final int NODELIST_BUILDING = 1;
|
||||
public static final int NODELIST_BUILT = 2;
|
||||
public static final int NODELIST_FAILED = 3;
|
||||
public static final int NODELIST_TERMINATED = 4;
|
||||
private static final String EMPTYSTRING = "";
|
||||
private static final Localisation LOCAL = new Localisation("resources/MessagesBundle");
|
||||
private ExitNodeTableModel entm;
|
||||
private GuardNodeTableModel gntm;
|
||||
private int intStatus = NODELIST_IDLE;
|
||||
private HashMap<String, NodeItem> hmNode;
|
||||
private final HashMap<String, NodeItem> hmBridges;
|
||||
private final ArrayList<String> alCountries;
|
||||
private TorController tc;
|
||||
private final String exitFavouritesFile;
|
||||
private final String guardFavouritesFile;
|
||||
private final String filepath;
|
||||
private volatile boolean boolAbortActions;
|
||||
private final Pattern pattspace = Pattern.compile(" ");
|
||||
private int nooffavs;
|
||||
|
||||
public NodeList(String filepath, String exitfavourites, String guardfavouritesfile) {
|
||||
this.hmNode = new HashMap<>();
|
||||
this.hmBridges = new HashMap<>();
|
||||
this.filepath = filepath;
|
||||
this.alCountries = new ArrayList<>();
|
||||
this.exitFavouritesFile = exitfavourites;
|
||||
this.guardFavouritesFile = guardfavouritesfile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get node item from its fingerprint
|
||||
*
|
||||
* @param key or fingerprint
|
||||
* @return NodeItem
|
||||
*/
|
||||
public final NodeItem getNode(String key) {
|
||||
String temp;
|
||||
NodeItem ni = hmNode.get(key);
|
||||
if (ni == null) {
|
||||
// No bridge found so must be a new node not currently in nodelist
|
||||
ArrayList<String> alRouterInfo = getRouterDesc(key);
|
||||
if (alRouterInfo != null) {
|
||||
alRouterInfo.addAll(getRouterStatus(key));
|
||||
ni = new NodeItem();
|
||||
temp = filterRouterInfo(alRouterInfo, "router ");
|
||||
if (temp == null) {
|
||||
return null;
|
||||
}
|
||||
String[] data = pattspace.split(temp);
|
||||
ni.setFingerprint(key);
|
||||
ni.setNickName(data[0]);
|
||||
ni.setIPAddress(data[1]);
|
||||
String isocode = tc.getCountryFromIP(ni.getIPAddress());
|
||||
if (isocode == null || isocode.contentEquals("??")) {
|
||||
isocode = "U1";
|
||||
}
|
||||
ni.setCountryCode(isocode);
|
||||
ni.setCountryName(LOCAL.getDisplayCountry(isocode));
|
||||
temp = filterRouterInfo(alRouterInfo, "bandwidth ");
|
||||
data = pattspace.split(temp);
|
||||
ni.setBandwidth(getLowestBandwidth(data));
|
||||
temp = filterRouterInfo(alRouterInfo, "s ");
|
||||
if (temp == null) {
|
||||
// We probably have a bridge
|
||||
ni.setType(NodeItem.TYPE_GUARD);
|
||||
ni.setStable(LOCAL.getString("text_yes"));
|
||||
return ni;
|
||||
}
|
||||
if (temp.contains("Guard")) {
|
||||
ni.setType(NodeItem.TYPE_GUARD);
|
||||
}
|
||||
if (temp.contains("Stable")) {
|
||||
ni.setStable(LOCAL.getString("text_yes"));
|
||||
} else {
|
||||
ni.setStable(LOCAL.getString("text_no"));
|
||||
}
|
||||
if (temp.contains("Exit") && !temp.contains("BadExit")) {
|
||||
ni.setType(NodeItem.TYPE_EXIT);
|
||||
temp = filterRouterInfo(alRouterInfo, "p ");
|
||||
if (temp.startsWith("accept")) {
|
||||
temp = temp.replace("accept ", "");
|
||||
if (!containsPort(temp, 80) && !containsPort(temp, 443)) {
|
||||
return ni;
|
||||
}
|
||||
} else {
|
||||
temp = temp.replace("reject ", "");
|
||||
if (containsPort(temp, 80) || containsPort(temp, 443)) {
|
||||
return ni;
|
||||
}
|
||||
}
|
||||
ni.setHttpSupported(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ni;
|
||||
}
|
||||
|
||||
public ArrayList<String> getRouterDesc(String finger) {
|
||||
ArrayList<String> alResult = tc.getInfo("desc/id/" + finger);
|
||||
if (alResult == null) {
|
||||
return null;
|
||||
}
|
||||
alResult.remove("250 OK");
|
||||
if (alResult.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return alResult;
|
||||
}
|
||||
|
||||
public ArrayList<String> getRouterStatus(String finger) {
|
||||
ArrayList<String> alResult = tc.getInfo("ns/id/" + finger);
|
||||
if (alResult == null) {
|
||||
return null;
|
||||
}
|
||||
alResult.remove("250 OK");
|
||||
if (alResult.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return alResult;
|
||||
}
|
||||
|
||||
public String filterRouterInfo(ArrayList<String> alInfo, String field) {
|
||||
for (String s : alInfo) {
|
||||
if (s.startsWith(field)) {
|
||||
return s.replace(field, "");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the process status
|
||||
*
|
||||
* @return status
|
||||
*/
|
||||
public final int getCurrentStatus() {
|
||||
return intStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the nodelist
|
||||
*
|
||||
* @param tc
|
||||
*/
|
||||
public final void refreshNodelist(TorController tc) {
|
||||
boolAbortActions = false;
|
||||
intStatus = NODELIST_BUILDING;
|
||||
this.tc = tc;
|
||||
boolean boolSuccess = populateNodeMap();
|
||||
if (boolSuccess) {
|
||||
boolSuccess = fetchFingerData();
|
||||
}
|
||||
if (boolSuccess) {
|
||||
intStatus = NODELIST_BUILT;
|
||||
} else if (boolAbortActions) {
|
||||
intStatus = NODELIST_TERMINATED;
|
||||
} else {
|
||||
intStatus = NODELIST_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update internal node mappings
|
||||
*
|
||||
*/
|
||||
private boolean populateNodeMap() {
|
||||
String strFlags;
|
||||
String data[];
|
||||
String temp;
|
||||
String strNick;
|
||||
String strIP;
|
||||
String strCountryName;
|
||||
String strCountryCode;
|
||||
String strPerms;
|
||||
String strDirPort;
|
||||
String strOrPort;
|
||||
|
||||
NodeItem ni;
|
||||
|
||||
SimpleFile sfConsensus = new SimpleFile(tc.getDataFolder() + SimpleFile.getSeparator() + "cached-consensus");
|
||||
|
||||
hmNode.clear();
|
||||
alCountries.clear();
|
||||
sfConsensus.openBufferedRead();
|
||||
while (!boolAbortActions) {
|
||||
temp = sfConsensus.readLine();
|
||||
// Test for end of node info file
|
||||
if (temp.startsWith("directory-footer")) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Test for node info line
|
||||
if (temp.startsWith("r ")) {
|
||||
data = pattspace.split(temp);
|
||||
strNick = data[1];
|
||||
strIP = data[6];
|
||||
strOrPort = data[7];
|
||||
strDirPort = data[8];
|
||||
|
||||
// Read flags line
|
||||
while (true) {
|
||||
strFlags = sfConsensus.readLine();
|
||||
if (strFlags.startsWith("s ")) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Ignore certain types of node
|
||||
if (!strFlags.contains("Running")
|
||||
|| !strFlags.contains("Valid")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Read port permissions line
|
||||
while (true) {
|
||||
strPerms = sfConsensus.readLine();
|
||||
if (strPerms.startsWith("p ")) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if Tor is fully active
|
||||
if (tc.getStatus() < TorController.STATUS_IDLE) {
|
||||
boolAbortActions = false;
|
||||
alCountries.clear();
|
||||
break;
|
||||
}
|
||||
|
||||
// Get country code from ip address
|
||||
strCountryCode = tc.getCountryFromIP(strIP);
|
||||
if (strCountryCode == null || strCountryCode.contains("??")) {
|
||||
strCountryCode = "U1";
|
||||
}
|
||||
|
||||
// If we get GEOIP errors then abort
|
||||
if (strCountryCode.startsWith("551 GEOIP")) {
|
||||
alCountries.clear();
|
||||
break;
|
||||
}
|
||||
|
||||
// Get country name
|
||||
strCountryName = LOCAL.getDisplayCountry(strCountryCode);
|
||||
|
||||
ni = new NodeItem();
|
||||
// Update our node item fields now that we have validated our node
|
||||
ni.setCountryCode(strCountryCode);
|
||||
ni.setCountryName(strCountryName);
|
||||
ni.setNickName(strNick);
|
||||
ni.setIPAddress(strIP);
|
||||
// Get stableflag
|
||||
if (strFlags.contains("Stable")) {
|
||||
ni.setStable(LOCAL.getString("text_yes"));
|
||||
} else {
|
||||
ni.setStable(LOCAL.getString("text_no"));
|
||||
}
|
||||
|
||||
hmNode.put(strOrPort + strDirPort + ":" + strIP, ni);
|
||||
|
||||
// Check if a guard node
|
||||
if (strFlags.contains("Guard")) {
|
||||
ni.setType(NodeItem.TYPE_GUARD);
|
||||
}
|
||||
|
||||
// Check if an exit node also exclude nodes flagged as bad exits
|
||||
if (strFlags.contains("Exit") && !strFlags.contains("BadExit")) {
|
||||
ni.setType(NodeItem.TYPE_EXIT);
|
||||
// Simple test on port permissions, we will only allow node
|
||||
// if it accepts connections on port 80 and 443 for web browsing
|
||||
if (strPerms.startsWith("p accept")) {
|
||||
strPerms = strPerms.replace("p accept ", "");
|
||||
if (!containsPort(strPerms, 80)) {
|
||||
continue;
|
||||
}
|
||||
if (!containsPort(strPerms, 443)) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
strPerms = strPerms.replace("p reject ", "");
|
||||
if (containsPort(strPerms, 80)) {
|
||||
continue;
|
||||
}
|
||||
if (containsPort(strPerms, 443)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ni.setHttpSupported(true);
|
||||
|
||||
// Ensure we only add exit country info in once to validated countries list
|
||||
if (!alCountries.contains(strCountryCode + "," + strCountryName)) {
|
||||
alCountries.add(strCountryCode + "," + strCountryName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sfConsensus.closeFile();
|
||||
|
||||
// Sort our country validation list
|
||||
if (alCountries.isEmpty()) {
|
||||
return false;
|
||||
} else {
|
||||
Collections.sort(alCountries, Collator.getInstance());
|
||||
}
|
||||
return !boolAbortActions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update internal finger mappings
|
||||
*
|
||||
*/
|
||||
private boolean fetchFingerData() {
|
||||
int idx;
|
||||
String line;
|
||||
String data[];
|
||||
String ipaddress;
|
||||
String finger;
|
||||
String strOrPort;
|
||||
String strDirPort;
|
||||
String key;
|
||||
boolean result;
|
||||
|
||||
String guardwhitelist = getGuardFavouritesAsCSV();
|
||||
NodeItem ni;
|
||||
HashMap<String, NodeItem> hmNodeReplacement = new HashMap<>();
|
||||
|
||||
SimpleFile sfDescriptors = new SimpleFile(tc.getDataFolder() + SimpleFile.getSeparator() + "cached-descriptors");
|
||||
SimpleFile sfDescriptorsNew = new SimpleFile(tc.getDataFolder() + SimpleFile.getSeparator() + "cached-descriptors.new");
|
||||
if (!sfDescriptorsNew.exists() || sfDescriptorsNew.getFile().length() == 0) {
|
||||
sfDescriptorsNew = null;
|
||||
}
|
||||
|
||||
sfDescriptors.openBufferedRead();
|
||||
try {
|
||||
while (!boolAbortActions) {
|
||||
line = sfDescriptors.readLine();
|
||||
// If line is null we have then processed the main descriptors file
|
||||
if (line == null) {
|
||||
// Check if their is a descriptors new file
|
||||
if (sfDescriptorsNew == null) {
|
||||
break;
|
||||
} else {
|
||||
sfDescriptors.closeFile();
|
||||
sfDescriptors = sfDescriptorsNew;
|
||||
sfDescriptors.openBufferedRead();
|
||||
sfDescriptorsNew = null;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (line.startsWith("router ")) {
|
||||
data = pattspace.split(line);
|
||||
ipaddress = data[2];
|
||||
strOrPort = data[3];
|
||||
strDirPort = data[5];
|
||||
key = strOrPort + strDirPort + ":";
|
||||
if (!hmNode.containsKey(key + ipaddress)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get fingerprint
|
||||
while (true) {
|
||||
line = sfDescriptors.readLine();
|
||||
idx = line.indexOf("fingerprint");
|
||||
if (idx > -1) {
|
||||
line = line.substring(idx + 12);
|
||||
break;
|
||||
}
|
||||
}
|
||||
finger = "$" + line.replace(" ", EMPTYSTRING);
|
||||
|
||||
// Get bandwidth
|
||||
while (true) {
|
||||
line = sfDescriptors.readLine();
|
||||
idx = line.indexOf("bandwidth");
|
||||
if (idx > -1) {
|
||||
line = line.substring(idx + 10);
|
||||
break;
|
||||
}
|
||||
}
|
||||
data = pattspace.split(line);
|
||||
ni = hmNode.get(key + ipaddress);
|
||||
ni.setFingerprint(finger);
|
||||
ni.setGuardEnabled(guardwhitelist.contains(finger));
|
||||
ni.setBandwidth(getLowestBandwidth(data));
|
||||
hmNodeReplacement.put(finger, ni);
|
||||
}
|
||||
}
|
||||
result = !boolAbortActions;
|
||||
} catch (Exception ex) {
|
||||
result = false;
|
||||
}
|
||||
sfDescriptors.closeFile();
|
||||
// Replace our original ipaddress keyed nodemap with our fingerprint keyed nodemap
|
||||
hmNode = hmNodeReplacement;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the lowest bandwidth
|
||||
*
|
||||
* @param data
|
||||
* @return bandwidth as float
|
||||
*/
|
||||
private float getLowestBandwidth(String[] data) {
|
||||
float bw = 1000000;
|
||||
float tmp;
|
||||
for (String s : data) {
|
||||
tmp = Float.parseFloat(s) / 1000000;
|
||||
if (tmp < bw) {
|
||||
bw = tmp;
|
||||
}
|
||||
}
|
||||
return bw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add newly learned bridge to nodelist
|
||||
*
|
||||
* @param bridgedata
|
||||
*/
|
||||
public void addBridge(String bridgedata) {
|
||||
Pattern pat = Pattern.compile(" ");
|
||||
bridgedata = bridgedata.substring(bridgedata.indexOf('$'));
|
||||
String[] data = pat.split(bridgedata);
|
||||
int index = data[0].indexOf('~');
|
||||
if (index < 0) {
|
||||
index = data[0].indexOf('=');
|
||||
}
|
||||
NodeItem ni = new NodeItem();
|
||||
ni.setFingerprint(data[0].substring(0, index));
|
||||
ni.setIPAddress(data[2]);
|
||||
ni.setNickName(data[0].substring(index + 1));
|
||||
hmBridges.put(ni.getFingerprint(), ni);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear any learned bridges
|
||||
*/
|
||||
public void clearBridges() {
|
||||
hmBridges.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to check supplied data contains the specified port
|
||||
*
|
||||
* @param data
|
||||
* @param port
|
||||
* @return True if data contains specified port
|
||||
*/
|
||||
private boolean containsPort(String data, int port) {
|
||||
String strRanges[];
|
||||
String[] strPorts;
|
||||
int rangemin;
|
||||
int rangemax;
|
||||
Pattern pattcomma = Pattern.compile(",");
|
||||
Pattern pattminus = Pattern.compile("-");
|
||||
strRanges = pattcomma.split(data);
|
||||
for (String s : strRanges) {
|
||||
// Test to see if its a range of ports
|
||||
if (s.contains("-")) {
|
||||
strPorts = pattminus.split(s);
|
||||
rangemin = Integer.parseInt(strPorts[0]);
|
||||
rangemax = Integer.parseInt(strPorts[1]);
|
||||
if (port >= rangemin && port <= rangemax) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
// We have a single port
|
||||
rangemin = Integer.parseInt(s);
|
||||
if (port == rangemin) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets validated countries, a valid country is any country with active exit
|
||||
* nodes
|
||||
*
|
||||
* @return String array of countries
|
||||
*/
|
||||
public final String[] getValidatedCountries() {
|
||||
return alCountries.toArray(new String[alCountries.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets validated country codes, a valid country is any country with active
|
||||
* exit nodes
|
||||
*
|
||||
* @return String array of country abbreviations
|
||||
*/
|
||||
public final String[] getValidatedCountryCodes() {
|
||||
String[] result = new String[alCountries.size()];
|
||||
int idx = 0;
|
||||
for (String s : alCountries) {
|
||||
result[idx++] = s.substring(0, 2);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the guard node view table model
|
||||
*
|
||||
* @param gntm
|
||||
*/
|
||||
public final void setGuardNodeTableModel(GuardNodeTableModel gntm) {
|
||||
this.gntm = gntm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the exit node view table model
|
||||
*
|
||||
* @param entm
|
||||
*/
|
||||
public final void setExitNodeTableModel(ExitNodeTableModel entm) {
|
||||
this.entm = entm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of exitnodes, if all is false then it returns only favourited
|
||||
* nodes, if omitfailednodes is true then don't include nodes that failed
|
||||
* testing
|
||||
*
|
||||
* @param all
|
||||
* @param omitfailednodes
|
||||
* @return ArrayList of exit nodes
|
||||
*/
|
||||
public final ArrayList<String> getExitNodes(boolean all, boolean omitfailednodes) {
|
||||
ArrayList<String> al = new ArrayList<>();
|
||||
for (int i = 0; i < entm.getRowCount(); i++) {
|
||||
int teststatus = (Integer) entm.getValueAt(i, 7);
|
||||
if (omitfailednodes && teststatus == NodeItem.TESTSTATUS_FAILED) {
|
||||
continue;
|
||||
}
|
||||
boolean fave = (Boolean) entm.getValueAt(i, 4) | all;
|
||||
if (fave) {
|
||||
al.add((String) entm.getValueAt(i, 5));
|
||||
}
|
||||
}
|
||||
return al;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a string of comma separated exitnodes, if all is false then it
|
||||
* returns only favourited nodes, if omitfailednodes is true then don't
|
||||
* include nodes that failed testing
|
||||
*
|
||||
* @param all
|
||||
* @param omitfailednodes
|
||||
* @return String of exitnodes in csv format
|
||||
*/
|
||||
public final String getExitNodesAsString(boolean all, boolean omitfailednodes) {
|
||||
String result = getExitNodes(all, omitfailednodes).toString();
|
||||
result = result.replace("[", "").replace(" ", "").replace("]", "");
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of all guard nodes guard nodes
|
||||
*
|
||||
* @return ArrayList of guard nodes
|
||||
*/
|
||||
public final ArrayList<String> getGuardNodes() {
|
||||
ArrayList<String> al = new ArrayList<>();
|
||||
if (gntm == null) {
|
||||
return al;
|
||||
}
|
||||
for (int i = 0; i < gntm.getRowCount(); i++) {
|
||||
al.add((String) gntm.getValueAt(i, 3));
|
||||
}
|
||||
return al;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get guard favourites
|
||||
*
|
||||
* @return CSV string of guard entry fingerprints
|
||||
*/
|
||||
public final String getGuardFavouritesAsCSV() {
|
||||
StringBuilder sbResult = new StringBuilder();
|
||||
String line;
|
||||
String sep = "";
|
||||
if (guardFavouritesFile == null) {
|
||||
return sbResult.toString();
|
||||
}
|
||||
SimpleFile sf = new SimpleFile(filepath + guardFavouritesFile);
|
||||
if (!sf.exists()) {
|
||||
return sbResult.toString();
|
||||
}
|
||||
sf.openBufferedRead();
|
||||
while ((line = sf.readLine()) != null) {
|
||||
sbResult.append(sep);
|
||||
sbResult.append(line);
|
||||
if (sep.isEmpty()) {
|
||||
sep = ",";
|
||||
}
|
||||
}
|
||||
sf.closeFile();
|
||||
return sbResult.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the guard node table model
|
||||
*/
|
||||
public final void refreshGuardTableModel() {
|
||||
if (gntm == null) {
|
||||
return;
|
||||
}
|
||||
NodeItem ni;
|
||||
gntm.clear();
|
||||
// Populate model
|
||||
for (String s : hmNode.keySet()) {
|
||||
ni = hmNode.get(s);
|
||||
if (ni.isGuard()) {
|
||||
Object[] rowData = new Object[]{ni};
|
||||
gntm.addRow(rowData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the table model based on supplied country
|
||||
*
|
||||
*
|
||||
* @param isocountry in the format "GB,Great Britain"
|
||||
*/
|
||||
public final void refreshExitTableModel(String isocountry) {
|
||||
if (entm == null) {
|
||||
return;
|
||||
}
|
||||
NodeItem ni;
|
||||
entm.clear();
|
||||
String abbrv = isocountry;
|
||||
String favourites = "";
|
||||
if (exitFavouritesFile != null) {
|
||||
SimpleFile sf = new SimpleFile(filepath + exitFavouritesFile);
|
||||
if (sf.exists()) {
|
||||
sf.openBufferedRead();
|
||||
favourites = sf.readEntireFile().trim();
|
||||
sf.closeFile();
|
||||
}
|
||||
}
|
||||
|
||||
// Populate model
|
||||
nooffavs = 0;
|
||||
for (String s : hmNode.keySet()) {
|
||||
ni = hmNode.get(s);
|
||||
if (ni.isExit() && ni.isHttpSupported() && ni.getCountryCode().contentEquals(abbrv)) {
|
||||
ni.setLatency(9999);
|
||||
ni.setTestingMessage(LOCAL.getString("textfield_unknown"));
|
||||
// Whitelisting here
|
||||
ni.setFavouriteEnabled(favourites.contains(ni.getIPAddress()));
|
||||
if (ni.isFavourite()) {
|
||||
nooffavs++;
|
||||
}
|
||||
Object[] rowData = new Object[]{ni};
|
||||
entm.addRow(rowData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of active favourites
|
||||
*
|
||||
* @return number of favs as int
|
||||
*/
|
||||
public int getNumberOfFavs() {
|
||||
return nooffavs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures any threaded actions will terminate themselves
|
||||
*/
|
||||
public final void terminate() {
|
||||
boolAbortActions = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save exit node whitelist
|
||||
*/
|
||||
public void saveExitFavourites() {
|
||||
if (exitFavouritesFile == null) {
|
||||
return;
|
||||
}
|
||||
SimpleFile sf = new SimpleFile(filepath + exitFavouritesFile);
|
||||
sf.openBufferedWrite();
|
||||
NodeItem ni;
|
||||
nooffavs = 0;
|
||||
for (String s : hmNode.keySet()) {
|
||||
ni = hmNode.get(s);
|
||||
if (ni.isExit() && ni.isFavourite()) {
|
||||
nooffavs++;
|
||||
sf.writeFile(ni.getIPAddress(), 1);
|
||||
}
|
||||
}
|
||||
sf.closeFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save exit node blacklist
|
||||
*
|
||||
* @return number of active guards
|
||||
*/
|
||||
public int saveGuardWhitelist() {
|
||||
int activeguards = 0;
|
||||
if (guardFavouritesFile == null) {
|
||||
return activeguards;
|
||||
}
|
||||
SimpleFile sf = new SimpleFile(filepath + guardFavouritesFile);
|
||||
sf.openBufferedWrite();
|
||||
NodeItem ni;
|
||||
for (String s : hmNode.keySet()) {
|
||||
ni = hmNode.get(s);
|
||||
if (ni.isGuard() && ni.isGuardEnabled()) {
|
||||
sf.writeFile(ni.getFingerprint(), 1);
|
||||
activeguards++;
|
||||
}
|
||||
}
|
||||
sf.closeFile();
|
||||
return activeguards;
|
||||
}
|
||||
|
||||
}
|
721
src/client/PacFactory.java
Normal file
721
src/client/PacFactory.java
Normal file
|
@ -0,0 +1,721 @@
|
|||
/*
|
||||
* 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 java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Random;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
import lib.OSFunction;
|
||||
import lib.SimpleFile;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alistair Neil <info@dazzleships.net>
|
||||
*/
|
||||
public class PacFactory {
|
||||
|
||||
public static final String FILEUSER = "user";
|
||||
private static final String FILEEXT = ".txt";
|
||||
public static final int PROXY_DISABLED = 0;
|
||||
public static final int PROXY_PATTERN = 1;
|
||||
public static final int PROXY_ALL = 2;
|
||||
private static final String PACFILE_EXT = ".pac";
|
||||
private static final String PATTERNFIRSTLINE = "### Pattern File, Do not remove or modify this line ###";
|
||||
private String strKDEProxyPrefsBackup;
|
||||
private String strGnome3ProxyPrefsBackup;
|
||||
private String strPACPath;
|
||||
private String strBackupFolder;
|
||||
private String strPatternsFolder;
|
||||
private String strTempFolder;
|
||||
private String strDefaultProxy = "";
|
||||
private String strDoNotProxy = "";
|
||||
private String strActiveCountry;
|
||||
private String strActivePacName = "";
|
||||
private final Random randgen;
|
||||
|
||||
public PacFactory() {
|
||||
randgen = new Random(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the active country code
|
||||
*
|
||||
* @return Active country
|
||||
*/
|
||||
public String getActiveCountry() {
|
||||
return strActiveCountry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and/or activate a pacfile for a specific country
|
||||
*
|
||||
* @param isocountry
|
||||
* @param port
|
||||
*/
|
||||
public void createPacFile(String isocountry, int port) {
|
||||
|
||||
// Generate a pseudo random pac name
|
||||
String pacname = createRandomName() + PACFILE_EXT;
|
||||
savePACFile(pacname, getPacRules(isocountry, String.valueOf(port)));
|
||||
setProxyAutoConfigURL("file://" + strPACPath.replace("\\", "/") + pacname);
|
||||
strActiveCountry = isocountry;
|
||||
if (!strActivePacName.isEmpty()) {
|
||||
this.deletePAC(strActivePacName);
|
||||
}
|
||||
strActivePacName = pacname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get pac rules for a specific country Can also be used for getting direct
|
||||
* rule and proxy all rules, by setting countrycode to "direct" or
|
||||
* "proxyall"
|
||||
*
|
||||
* @param countrycode
|
||||
* @param port
|
||||
* @return An arraylist of rules
|
||||
*/
|
||||
private ArrayList<String> getPacRules(String country, String port) {
|
||||
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
// If country code is null then generate proxy all traffic rules
|
||||
if (country.contentEquals("proxyall")) {
|
||||
addSocksRule(result, "127.0.0.1", port);
|
||||
return result;
|
||||
}
|
||||
if (country.contentEquals("direct")) {
|
||||
addDirectMatchingRule(result, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
Pattern pat = Pattern.compile(",");
|
||||
String[] split;
|
||||
// Create our pattern rules storage list
|
||||
ArrayList<String> patternrules = new ArrayList<>();
|
||||
|
||||
// Add in do not proxy rules
|
||||
if (!strDoNotProxy.isEmpty()) {
|
||||
split = pat.split(strDoNotProxy);
|
||||
for (String s : split) {
|
||||
if (!s.isEmpty()) {
|
||||
addDirectMatchingRule(result, "*" + s + "*");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get default patterns
|
||||
loadPatternsList(country, patternrules);
|
||||
for (String s : patternrules) {
|
||||
split = pat.split(s);
|
||||
if (split.length < 3) {
|
||||
break;
|
||||
}
|
||||
if (split[2].contentEquals("true")) {
|
||||
if (split[1].contentEquals("*")) {
|
||||
addSocksRule(result, "127.0.0.1", port);
|
||||
return result;
|
||||
} else {
|
||||
addSocksMatchingRule(result, split[1], "127.0.0.1", port);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (strDefaultProxy.isEmpty()) {
|
||||
addDirectMatchingRule(result, null);
|
||||
} else {
|
||||
addProxyRule(result, strDefaultProxy);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param rules
|
||||
* @param proxy
|
||||
*/
|
||||
public void addProxyRule(ArrayList<String> rules, String proxy) {
|
||||
rules.add("\treturn \"PROXY " + proxy + "\";");
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a socks rule to a supplied list
|
||||
*
|
||||
* @param rules
|
||||
* @param host
|
||||
* @param port
|
||||
*/
|
||||
public void addSocksRule(ArrayList<String> rules, String host, String port) {
|
||||
String rule = "\treturn \"SOCKS5 " + host + ":" + port + "\";";
|
||||
rules.add(rule);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param rules
|
||||
* @param pattern
|
||||
*/
|
||||
public void addDirectMatchingRule(ArrayList<String> rules, String pattern) {
|
||||
String rule;
|
||||
if (pattern == null) {
|
||||
rule = "\treturn \"DIRECT\";";
|
||||
} else {
|
||||
rule = "\tif (shExpMatch(url, \"" + pattern + "\"))\n"
|
||||
+ "\t{\n"
|
||||
+ "\t\treturn \"DIRECT\";\n"
|
||||
+ "\t}";
|
||||
|
||||
}
|
||||
rules.add(rule);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add socks pattern mayching rule to a supllied list
|
||||
*
|
||||
* @param rules
|
||||
* @param pattern
|
||||
* @param host
|
||||
* @param port
|
||||
*/
|
||||
public void addSocksMatchingRule(ArrayList<String> rules, String pattern, String host, String port) {
|
||||
String rule = "\tif (shExpMatch(url, \"" + pattern + "\"))\n"
|
||||
+ "\t{\n"
|
||||
+ "\t\treturn \"SOCKS5 " + host + ":" + port + "\";\n"
|
||||
+ "\t}";
|
||||
|
||||
rules.add(rule);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a patterns list from a file
|
||||
*
|
||||
* @param country
|
||||
* @param list
|
||||
*/
|
||||
public void loadPatternsList(String country, ArrayList<String> list) {
|
||||
String line;
|
||||
int idxs, idxe;
|
||||
SimpleFile sfPatternFile = new SimpleFile(strPatternsFolder + country.substring(0, 2) + "_" + FILEUSER + FILEEXT);
|
||||
if (sfPatternFile.exists()) {
|
||||
sfPatternFile.openBufferedRead();
|
||||
while ((line = sfPatternFile.readLine()) != null) {
|
||||
idxs = line.indexOf('<');
|
||||
idxe = line.indexOf('>');
|
||||
if (idxs == 0 && idxe == (line.length() - 1)) {
|
||||
list.add(line.substring(idxs + 1, idxe) + "," + FILEUSER);
|
||||
}
|
||||
}
|
||||
sfPatternFile.closeFile();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete patterns file for a given country and type, where type is either
|
||||
* "def" or "user"
|
||||
*
|
||||
* @param country
|
||||
* @param type
|
||||
*/
|
||||
public void deletePatternsFile(String country, String type) {
|
||||
SimpleFile sfPatternFile = new SimpleFile(strPatternsFolder + country.substring(0, 2) + "_" + type + FILEEXT);
|
||||
sfPatternFile.delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a patterns list by filename
|
||||
*
|
||||
* @param country
|
||||
* @param list
|
||||
* @param type
|
||||
*/
|
||||
public void savePatternsList(String country, String type, ArrayList<String> list) {
|
||||
|
||||
SimpleFile sfPatternFile = new SimpleFile(strPatternsFolder + country.substring(0, 2) + "_" + type + FILEEXT);
|
||||
sfPatternFile.openBufferedWrite();
|
||||
sfPatternFile.writeFile(PATTERNFIRSTLINE, 1);
|
||||
for (String s : list) {
|
||||
sfPatternFile.writeFile("<" + s + ">", 1);
|
||||
}
|
||||
sfPatternFile.closeFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create folder in which pattern files will be stored
|
||||
*
|
||||
* @param folder
|
||||
*/
|
||||
public final void setPatternsFolder(String folder) {
|
||||
strPatternsFolder = folder + SimpleFile.getSeparator();
|
||||
SimpleFile.createFolder(strPatternsFolder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set folder where pac files will be generated
|
||||
*
|
||||
* @param folder
|
||||
*/
|
||||
public final void setPACFolder(String folder) {
|
||||
strPACPath = folder;
|
||||
SimpleFile.createFolder(folder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set folder where system proxy settings will be backed up
|
||||
*
|
||||
* @param folder
|
||||
*/
|
||||
public final void setBackupFolder(String folder) {
|
||||
strBackupFolder = folder + SimpleFile.getSeparator();
|
||||
SimpleFile.createFolder(strBackupFolder);
|
||||
if (OSFunction.getGsettingsPath() != null) {
|
||||
strGnome3ProxyPrefsBackup = strBackupFolder + "gnome3_proxy.txt";
|
||||
} else {
|
||||
strGnome3ProxyPrefsBackup = null;
|
||||
}
|
||||
if (OSFunction.getKDEProxyPath() != null) {
|
||||
strKDEProxyPrefsBackup = strBackupFolder + "kde_proxy.txt";
|
||||
} else {
|
||||
strKDEProxyPrefsBackup = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the temp folder for file extractions
|
||||
*
|
||||
* @param path
|
||||
*/
|
||||
public final void setTempFolder(String path) {
|
||||
strTempFolder = path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic backup of proxy settings
|
||||
*
|
||||
*/
|
||||
public void backupProxyPrefs() {
|
||||
backupGnomeProxyPrefs();
|
||||
backupKDEProxyPrefs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gnome backup of proxy settings
|
||||
*
|
||||
*/
|
||||
private void backupGnomeProxyPrefs() {
|
||||
if (strBackupFolder == null) {
|
||||
return;
|
||||
}
|
||||
SimpleFile sfProxyPrefs;
|
||||
try {
|
||||
if (strGnome3ProxyPrefsBackup != null) {
|
||||
sfProxyPrefs = new SimpleFile(strGnome3ProxyPrefsBackup);
|
||||
if (!sfProxyPrefs.exists()) {
|
||||
sfProxyPrefs.openBufferedWrite();
|
||||
sfProxyPrefs.writeFile(OSFunction.getGnome3Pref("org.gnome.system.proxy", "mode"), 1);
|
||||
sfProxyPrefs.writeFile(OSFunction.getGnome3Pref("org.gnome.system.proxy", "autoconfig-url"), 1);
|
||||
sfProxyPrefs.closeFile();
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Logger.getGlobal().logp(Level.SEVERE, this.getClass().getName(), "backupGnomeProxyPrefs()", "", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* KDE backup of proxy settings
|
||||
*
|
||||
*/
|
||||
private void backupKDEProxyPrefs() {
|
||||
if (strBackupFolder == null) {
|
||||
return;
|
||||
}
|
||||
SimpleFile sfProxyPrefs;
|
||||
try {
|
||||
if (strKDEProxyPrefsBackup != null) {
|
||||
sfProxyPrefs = new SimpleFile(strKDEProxyPrefsBackup);
|
||||
if (!sfProxyPrefs.exists()) {
|
||||
sfProxyPrefs.openBufferedWrite();
|
||||
sfProxyPrefs.writeFile(OSFunction.getKDEPref("Proxy Settings", "Proxy Config Script", ""), 1);
|
||||
sfProxyPrefs.writeFile(OSFunction.getKDEPref("Proxy Settings", "ProxyType", "0"), 1);
|
||||
sfProxyPrefs.closeFile();
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Logger.getGlobal().logp(Level.SEVERE, this.getClass().getName(), "backupKDEProxyPrefs()", "", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic restore of proxy settings, for ease of use
|
||||
*
|
||||
*/
|
||||
public void restoreProxyPrefs(boolean resetonfail) {
|
||||
restoreGnomeProxyPrefs(resetonfail);
|
||||
restoreKDEProxyPrefs(resetonfail);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gnome specific restore of proxy settings
|
||||
*
|
||||
*/
|
||||
private void restoreGnomeProxyPrefs(boolean resetonfail) {
|
||||
|
||||
SimpleFile sfProxyPrefs;
|
||||
|
||||
try {
|
||||
// Restore gnome3 proxy prefs
|
||||
if (strGnome3ProxyPrefsBackup != null) {
|
||||
sfProxyPrefs = new SimpleFile(strGnome3ProxyPrefsBackup);
|
||||
if (sfProxyPrefs.exists()) {
|
||||
sfProxyPrefs.openBufferedRead();
|
||||
String mode = sfProxyPrefs.readLine();
|
||||
String url = sfProxyPrefs.readLine();
|
||||
sfProxyPrefs.closeFile();
|
||||
if (url != null && mode != null && !mode.isEmpty()) {
|
||||
// Restore original settings from file
|
||||
OSFunction.setGnome3Pref("org.gnome.system.proxy", "mode", mode);
|
||||
OSFunction.setGnome3Pref("org.gnome.system.proxy", "autoconfig-url", url);
|
||||
}
|
||||
} else {
|
||||
if (resetonfail) {
|
||||
setGnomeProxyAutoConfigURL(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Logger.getGlobal().logp(Level.SEVERE, this.getClass().getName(), "restoreGnomeProxyPrefs()", "", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* KDE specific restore of proxy settings
|
||||
*
|
||||
*/
|
||||
private void restoreKDEProxyPrefs(boolean resetonfail) {
|
||||
|
||||
SimpleFile sfProxyPrefs;
|
||||
|
||||
try {
|
||||
// Restore kde proxy prefs
|
||||
if (strKDEProxyPrefsBackup != null) {
|
||||
sfProxyPrefs = new SimpleFile(strKDEProxyPrefsBackup);
|
||||
if (sfProxyPrefs.exists()) {
|
||||
sfProxyPrefs.openBufferedRead();
|
||||
String url = sfProxyPrefs.readLine();
|
||||
String type = sfProxyPrefs.readLine();
|
||||
sfProxyPrefs.closeFile();
|
||||
if (url != null && type != null) {
|
||||
if (!SimpleFile.exists(url)) {
|
||||
url = "";
|
||||
}
|
||||
OSFunction.setKDEPref("Proxy Settings", "Proxy Config Script", url);
|
||||
OSFunction.setKDEPref("Proxy Settings", "ProxyType", type);
|
||||
}
|
||||
} else {
|
||||
if (resetonfail) {
|
||||
setKDEProxyAutoConfigURL(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Logger.getGlobal().logp(Level.SEVERE, this.getClass().getName(), "restoreKDEProxyPrefs()", "", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic proxy prefs delete, for ease of use
|
||||
*/
|
||||
public void deleteProxyPrefs() {
|
||||
deleteGnomeProxyPrefs();
|
||||
deleteKDEProxyPrefs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic delete of backed up gnome proxy settings
|
||||
*
|
||||
* @return boolean True if successful
|
||||
*/
|
||||
private boolean deleteGnomeProxyPrefs() {
|
||||
|
||||
if (strBackupFolder == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean result = true;
|
||||
|
||||
// Delete Gnome3 prefs
|
||||
if (strGnome3ProxyPrefsBackup != null) {
|
||||
result = SimpleFile.delete(strGnome3ProxyPrefsBackup);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic delete of backed up KDE proxy settings
|
||||
*
|
||||
* @return boolean True if successful
|
||||
*/
|
||||
private boolean deleteKDEProxyPrefs() {
|
||||
|
||||
if (strBackupFolder == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean result = true;
|
||||
|
||||
// Delete Kde prefs
|
||||
if (strKDEProxyPrefsBackup != null) {
|
||||
result = SimpleFile.delete(strKDEProxyPrefsBackup);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic set proxy config
|
||||
*
|
||||
* @param url
|
||||
*/
|
||||
public void setProxyAutoConfigURL(String url) {
|
||||
setGnomeProxyAutoConfigURL(url);
|
||||
setKDEProxyAutoConfigURL(url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Gnome proxy config
|
||||
*
|
||||
* @param url
|
||||
*/
|
||||
private void setGnomeProxyAutoConfigURL(String url) {
|
||||
if (strGnome3ProxyPrefsBackup != null) {
|
||||
if (url == null) {
|
||||
OSFunction.resetGnome3Pref("org.gnome.system.proxy", "mode");
|
||||
OSFunction.resetGnome3Pref("org.gnome.system.proxy", "autoconfig-url");
|
||||
} else {
|
||||
OSFunction.setGnome3Pref("org.gnome.system.proxy", "mode", "auto");
|
||||
OSFunction.setGnome3Pref("org.gnome.system.proxy", "autoconfig-url", url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set KDE proxy config
|
||||
*
|
||||
* @param url
|
||||
*/
|
||||
private void setKDEProxyAutoConfigURL(String url) {
|
||||
|
||||
if (strKDEProxyPrefsBackup != null) {
|
||||
if (url == null) {
|
||||
OSFunction.setKDEPref("Proxy Settings", "Proxy Config Script", "");
|
||||
OSFunction.setKDEPref("Proxy Settings", "ProxyType", 0);
|
||||
} else {
|
||||
OSFunction.setKDEPref("Proxy Settings", "Proxy Config Script", url);
|
||||
OSFunction.setKDEPref("Proxy Settings", "ProxyType", 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save pac file using given filename
|
||||
*
|
||||
* @param filename
|
||||
* @param ruleslist
|
||||
*/
|
||||
private void savePACFile(String filename, ArrayList<String> ruleslist) {
|
||||
SimpleFile sfPacFile = new SimpleFile(strPACPath + filename);
|
||||
sfPacFile.openBufferedWrite();
|
||||
sfPacFile.writeFile("//" + filename, 1);
|
||||
String temp = "function FindProxyForURL(url, host) {";
|
||||
sfPacFile.writeFile(temp, 1);
|
||||
for (String s : ruleslist) {
|
||||
sfPacFile.writeFile(s, 1);
|
||||
}
|
||||
sfPacFile.writeFile("}", 1);
|
||||
sfPacFile.closeFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete specified pac file
|
||||
*
|
||||
* @param filename
|
||||
* @return boolean true if action successful
|
||||
*/
|
||||
public boolean deletePAC(String filename) {
|
||||
return SimpleFile.delete(strPACPath + filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all pac files
|
||||
*/
|
||||
public void deleteAllPAC() {
|
||||
SimpleFile sf = new SimpleFile(strPACPath);
|
||||
sf.setFileFilter(PACFILE_EXT);
|
||||
sf.deleteFileList(sf.getFileList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a pseudo random numerical name
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
private String createRandomName() {
|
||||
// Create new filename with a random number to modify filename from
|
||||
// previous one to force auto reload of pac settings in browser
|
||||
int pacNumber = randgen.nextInt();
|
||||
if (pacNumber < 0) {
|
||||
pacNumber = 0 - pacNumber;
|
||||
}
|
||||
return String.valueOf(pacNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set default proxy url
|
||||
*
|
||||
* @param proxyurl
|
||||
*/
|
||||
public void setDefaultProxy(String proxyurl) {
|
||||
strDefaultProxy = proxyurl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set do not proxy
|
||||
*
|
||||
* @param hostcsv
|
||||
*/
|
||||
public void setDoNotProxy(String hostcsv) {
|
||||
strDoNotProxy = hostcsv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get value of comma separated host or ip list
|
||||
*
|
||||
* @return String value
|
||||
*/
|
||||
public String getDoNotProxy() {
|
||||
return strDoNotProxy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds pattern to an existing pattern file
|
||||
*
|
||||
* @param country
|
||||
* @param description
|
||||
* @param pattern
|
||||
*/
|
||||
public void addToPatternFile(String country, String description, String pattern) {
|
||||
if (strPatternsFolder == null || pattern.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
SimpleFile sfPatternFile = new SimpleFile(strPatternsFolder + SimpleFile.getSeparator() + country.substring(0, 2) + "_" + FILEUSER + FILEEXT);
|
||||
sfPatternFile.openBufferedAppend();
|
||||
sfPatternFile.writeFile("<" + description + "," + pattern + ",true>", 1);
|
||||
sfPatternFile.closeFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of user pattern files
|
||||
*
|
||||
* @return array of files
|
||||
*/
|
||||
public File[] getPatternsFiles() {
|
||||
SimpleFile sf = new SimpleFile(strPatternsFolder);
|
||||
sf.setFileFilter(FILEUSER + FILEEXT);
|
||||
return sf.getFileList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Export user patterns
|
||||
*
|
||||
* @param filename
|
||||
* @param files
|
||||
*/
|
||||
public void exportUserPatterns(String filename, File[] files) {
|
||||
|
||||
// Append .zip extension if we need to
|
||||
if (!filename.endsWith(".zip")) {
|
||||
filename += ".zip";
|
||||
}
|
||||
// Add user pattern files to zip
|
||||
SimpleFile sf = new SimpleFile(filename);
|
||||
sf.openZipStream(9);
|
||||
sf.addFilesToZip(files);
|
||||
sf.closeZipStream();
|
||||
}
|
||||
|
||||
/**
|
||||
* Import patterns
|
||||
*
|
||||
* @param filename
|
||||
* @return true if succesful
|
||||
*/
|
||||
public boolean importPatterns(String filename) {
|
||||
|
||||
// Import patterns
|
||||
boolean success = false;
|
||||
SimpleFile sf = new SimpleFile(filename);
|
||||
String destpath;
|
||||
// Check existence
|
||||
if (sf.exists()) {
|
||||
// Get temporary path to extraction folder
|
||||
if (strTempFolder == null) {
|
||||
destpath = OSFunction.getTempFolder(null)
|
||||
+ getClass().getName();
|
||||
} else {
|
||||
destpath = strTempFolder + getClass().getName();
|
||||
}
|
||||
// Create temp extraction folder
|
||||
SimpleFile.createFolder(destpath);
|
||||
// Extract files to temp folder
|
||||
success = sf.extractZipTo(destpath);
|
||||
if (success) {
|
||||
// Get list of files
|
||||
sf.setFileName(destpath);
|
||||
sf.setFileFilter(".txt");
|
||||
File[] files = sf.getFileList();
|
||||
// Verify each file before copying them over
|
||||
String firstLine;
|
||||
try {
|
||||
if (files.length == 0) {
|
||||
throw new Exception();
|
||||
}
|
||||
for (File f : files) {
|
||||
// Verify valid pattern file by checking first line of file
|
||||
sf.setFile(f);
|
||||
sf.openBufferedRead();
|
||||
firstLine = sf.readLine();
|
||||
sf.closeFile();
|
||||
if (firstLine != null) {
|
||||
if (firstLine.toLowerCase().contains("pattern file")) {
|
||||
SimpleFile.copyFromTo(f.getAbsolutePath(), strPatternsFolder + f.getName());
|
||||
} else {
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
// Delete temporary files
|
||||
SimpleFile.deleteFolder(destpath);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
}
|
202
src/client/PatternsEditor.form
Normal file
202
src/client/PatternsEditor.form
Normal file
|
@ -0,0 +1,202 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.6" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
|
||||
<Properties>
|
||||
<Property name="defaultCloseOperation" type="int" value="2"/>
|
||||
<Property name="title" type="java.lang.String" value="Proxy Pattern Editor"/>
|
||||
<Property name="iconImage" type="java.awt.Image" editor="org.netbeans.modules.form.ComponentChooserEditor">
|
||||
<ComponentRef name="null"/>
|
||||
</Property>
|
||||
<Property name="resizable" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<SyntheticProperties>
|
||||
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
|
||||
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
|
||||
</SyntheticProperties>
|
||||
<Events>
|
||||
<EventHandler event="windowClosing" listener="java.awt.event.WindowListener" parameters="java.awt.event.WindowEvent" handler="closeDialog"/>
|
||||
</Events>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jScrollPane1" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jComboCountry" min="-2" pref="264" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jButtonDeletePattern" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jButtonAddPattern" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="jButtonCancel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jButtonSave" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jLabel17" min="-2" max="-2" attributes="1"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jTextDoNotProxy" max="32767" attributes="1"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jComboCountry" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jScrollPane1" pref="341" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jTextDoNotProxy" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel17" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jButtonDeletePattern" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jButtonCancel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jButtonSave" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jButtonAddPattern" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JButton" name="jButtonSave">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="button_save" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButtonSaveActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="jButtonCancel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="button_close" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButtonCancelActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JComboBox" name="jComboCountry">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })" type="code"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="jComboCountryItemStateChanged"/>
|
||||
</Events>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new javax.swing.JComboBox<>()"/>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<String>"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="jButtonDeletePattern">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="button_delete" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButtonDeletePatternActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="jButtonAddPattern">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="button_addnew" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButtonAddPatternActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel1">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="label_editcountry" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTable" name="jTablePatterns">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor">
|
||||
<Table columnCount="0" rowCount="0"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="ttip_patterntable" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
<Property name="autoResizeMode" type="int" value="3"/>
|
||||
<Property name="selectionModel" type="javax.swing.ListSelectionModel" editor="org.netbeans.modules.form.editors2.JTableSelectionModelEditor">
|
||||
<JTableSelectionModel selectionMode="2"/>
|
||||
</Property>
|
||||
<Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor">
|
||||
<TableHeader reorderingAllowed="false" resizingAllowed="false"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="mouseReleased" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="jTablePatternsMouseReleased"/>
|
||||
<EventHandler event="keyReleased" listener="java.awt.event.KeyListener" parameters="java.awt.event.KeyEvent" handler="jTablePatternsKeyReleased"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JLabel" name="jLabel17">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="label_donotproxy" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="jTextDoNotProxy">
|
||||
<Properties>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="ttip_donotproxy" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="focusLost" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="jTextDoNotProxyFocusLost"/>
|
||||
<EventHandler event="keyReleased" listener="java.awt.event.KeyListener" parameters="java.awt.event.KeyEvent" handler="jTextDoNotProxyKeyReleased"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
602
src/client/PatternsEditor.java
Normal file
602
src/client/PatternsEditor.java
Normal file
|
@ -0,0 +1,602 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
635
src/client/PrefsDialog.form
Normal file
635
src/client/PrefsDialog.form
Normal file
|
@ -0,0 +1,635 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.8" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
|
||||
<Properties>
|
||||
<Property name="defaultCloseOperation" type="int" value="2"/>
|
||||
<Property name="iconImage" type="java.awt.Image" editor="org.netbeans.modules.form.ComponentChooserEditor">
|
||||
<ComponentRef name="null"/>
|
||||
</Property>
|
||||
<Property name="resizable" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<SyntheticProperties>
|
||||
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
|
||||
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
|
||||
</SyntheticProperties>
|
||||
<Events>
|
||||
<EventHandler event="windowClosing" listener="java.awt.event.WindowListener" parameters="java.awt.event.WindowEvent" handler="closeDialog"/>
|
||||
</Events>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jButtonDefaults" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="jButtonCancel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jButtonApply" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="jTabPrefs" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jTabPrefs" max="32767" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jButtonApply" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jButtonCancel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jButtonDefaults" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JTabbedPane" name="jTabPrefs">
|
||||
<Events>
|
||||
<EventHandler event="stateChanged" listener="javax.swing.event.ChangeListener" parameters="javax.swing.event.ChangeEvent" handler="jTabPrefsStateChanged"/>
|
||||
</Events>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="jPanelBasicPrefs">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
|
||||
<FontInfo relative="true">
|
||||
<Font bold="true" component="jPanelBasicPrefs" property="font" relativeSize="true" size="0"/>
|
||||
</FontInfo>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription">
|
||||
<JTabbedPaneConstraints tabName="Basic">
|
||||
<Property name="tabTitle" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="tab_basic" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</JTabbedPaneConstraints>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jPanelGeneralPrefs" max="32767" attributes="1"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jPanelGeneralPrefs" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="jPanelGeneralPrefs">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||
<TitledBorder title="General Settings">
|
||||
<ResourceString PropertyName="titleX" bundle="resources/MessagesBundle.properties" key="panel_general" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
<Connection PropertyName="font" component="jPanelBasicPrefs" name="font" type="property"/>
|
||||
<Connection PropertyName="color" component="jPanelBasicPrefs" name="foreground" type="property"/>
|
||||
</TitledBorder>
|
||||
</Border>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jCheckAutostart" alignment="0" min="-2" max="-2" attributes="3"/>
|
||||
<Component id="jCheckHideTray" min="-2" max="-2" attributes="3"/>
|
||||
<Component id="jCheckCacheDelete" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jCheckHideMin" alignment="0" min="-2" max="-2" attributes="3"/>
|
||||
<Component id="jCheckDisableNotify" alignment="0" min="-2" max="-2" attributes="3"/>
|
||||
</Group>
|
||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jCheckAppUpdate" min="-2" max="-2" attributes="2"/>
|
||||
<Component id="jCheckGeoUpdate" alignment="0" min="-2" max="-2" attributes="2"/>
|
||||
<Component id="jCheckDisableTray" alignment="0" min="-2" max="-2" attributes="3"/>
|
||||
<Component id="jCheckMinOnClose" min="-2" max="-2" attributes="3"/>
|
||||
</Group>
|
||||
<EmptySpace pref="39" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jCheckAutostart" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jCheckGeoUpdate" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jCheckHideTray" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jCheckDisableTray" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jCheckHideMin" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jCheckMinOnClose" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jCheckCacheDelete" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jCheckAppUpdate" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jCheckDisableNotify" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace pref="132" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JCheckBox" name="jCheckHideTray">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="chkbox_hidetotray" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="ttip_hidetotray" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="jCheckAppUpdate">
|
||||
<Properties>
|
||||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="chkbox_checkforupdates" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="ttip_checkforupdates" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="jCheckAutostart">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="chkbox_autostart" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="ttip_autostart" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="jCheckDisableTray">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="chkbox_disabletray" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="ttip_disabletray" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="jCheckDisableTrayItemStateChanged"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="jCheckMinOnClose">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="chkbox_minonclose" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="ttip_minonclose" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="jCheckCacheDelete">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="chkbox_securedelete" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="ttip_securedelete" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="jCheckDisableNotify">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="chkbox_disablenotify" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="ttip_disablenotify" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="jCheckHideMin">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="chkbox_hidemin" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="ttip_hidemin" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="jCheckGeoUpdate">
|
||||
<Properties>
|
||||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="chkbox_geocheck" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="ttip_geocheck" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="jPanelAdvancedPrefs">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription">
|
||||
<JTabbedPaneConstraints tabName="Advanced">
|
||||
<Property name="tabTitle" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="tab_advanced" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</JTabbedPaneConstraints>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="1" attributes="0">
|
||||
<Component id="jPanel1" max="32767" attributes="0"/>
|
||||
<Component id="jPanelTorPrefs" max="32767" attributes="1"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jPanelTorPrefs" max="32767" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jPanel1" max="32767" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="jPanelTorPrefs">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||
<TitledBorder title="Tor Client Settings">
|
||||
<ResourceString PropertyName="titleX" bundle="resources/MessagesBundle.properties" key="panel_torclientset" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
<Connection PropertyName="font" component="jPanelBasicPrefs" name="font" type="property"/>
|
||||
<Connection PropertyName="color" component="jPanelBasicPrefs" name="foreground" type="property"/>
|
||||
</TitledBorder>
|
||||
</Border>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jLabel14" alignment="0" min="-2" max="-2" attributes="1"/>
|
||||
<Component id="jLabel15" alignment="0" min="-2" max="-2" attributes="1"/>
|
||||
<Component id="jLabel12" alignment="0" min="-2" max="-2" attributes="1"/>
|
||||
<Component id="jLabel13" alignment="0" min="-2" max="-2" attributes="1"/>
|
||||
<Component id="jLabel11" alignment="0" min="-2" max="-2" attributes="1"/>
|
||||
<Component id="jLabel6" alignment="0" min="-2" max="-2" attributes="1"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jCheckSafeSocks" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||
<Component id="jCheckTestSocks" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="jCheckAvoidDisk" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jComboLogLev" min="-2" pref="145" max="-2" attributes="0"/>
|
||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||
<Component id="jCheckSafeLog" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jTextTorBridge" min="-2" pref="259" max="-2" attributes="1"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jButtonGetBridges" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jSpinnerMainPort" min="-2" max="-2" attributes="2"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jLabelPortRanges" min="-2" max="-2" attributes="2"/>
|
||||
</Group>
|
||||
<Component id="jTextTorArgs" alignment="0" max="32767" attributes="1"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="2" attributes="0">
|
||||
<Component id="jLabelPortRanges" alignment="2" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jSpinnerMainPort" alignment="2" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel6" alignment="2" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel11" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jTextTorBridge" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jButtonGetBridges" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel14" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jCheckSafeSocks" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jCheckTestSocks" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel12" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jComboLogLev" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jCheckSafeLog" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel15" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jCheckAvoidDisk" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel13" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jTextTorArgs" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="jLabel6">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="label_listenport" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JSpinner" name="jSpinnerMainPort">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.SpinnerModel" editor="org.netbeans.modules.form.editors2.SpinnerModelEditor">
|
||||
<SpinnerModel initial="9054" maximum="9999" minimum="9054" numberType="java.lang.Integer" stepSize="1" type="number"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="ttip_listenport" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabelPortRanges">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Currently active port ranges, 9052 to 9063"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel11">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="label_bridgeaddress" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="jTextTorBridge">
|
||||
<Properties>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="ttip_bridgeaddress" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="jButtonGetBridges">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="button_getbridges" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButtonGetBridgesActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="jCheckSafeSocks">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="chkbox_safesocks" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="ttip_safesocks" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel12">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="label_torlogging" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="jCheckTestSocks">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="chkbox_testsocks" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="ttip_testsocks" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel13">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="label_torargs" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="jTextTorArgs">
|
||||
<Properties>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="ttip_extraargs" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel14">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="label_torsocks" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="jCheckAvoidDisk">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="chkbox_diskavoid" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="ttip_avoiddisk" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel15">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="label_diskoptions" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JComboBox" name="jComboLogLev">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new DefaultComboBoxModel<>(new String[] {LOCAL.getString("combo_loglev1"),LOCAL.getString("combo_loglev2"),LOCAL.getString("combo_loglev3")})" type="code"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="ttip_combo_loglevel" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new javax.swing.JComboBox<>()"/>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<String>"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="jCheckSafeLog">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="chkbox_safelog" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="ttip_safelogging" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="jPanel1">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||
<TitledBorder title="Network Settings">
|
||||
<ResourceString PropertyName="titleX" bundle="resources/MessagesBundle.properties" key="panel_network" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
<Connection PropertyName="font" component="jPanelBasicPrefs" name="font" type="property"/>
|
||||
<Connection PropertyName="color" component="jPanelBasicPrefs" name="foreground" type="property"/>
|
||||
</TitledBorder>
|
||||
</Border>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jLabel16" min="-2" max="-2" attributes="1"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jTextHTTPProxy" max="32767" attributes="1"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel16" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jTextHTTPProxy" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="jLabel16">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="label_defaultproxy" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="jTextHTTPProxy">
|
||||
<Properties>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="ttip_defaultproxy" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JButton" name="jButtonCancel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="button_close" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButtonCancelActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="jButtonApply">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="button_apply" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButtonApplyActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="jButtonDefaults">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="button_prefdefaults" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButtonDefaultsActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
608
src/client/PrefsDialog.java
Normal file
608
src/client/PrefsDialog.java
Normal file
|
@ -0,0 +1,608 @@
|
|||
/*
|
||||
* 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 javax.swing.DefaultComboBoxModel;
|
||||
import lib.Localisation;
|
||||
import lib.SimpleProps;
|
||||
import lib.Utilities;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alistair Neil, <info@dazzleships.net>
|
||||
*/
|
||||
public final class PrefsDialog extends javax.swing.JDialog {
|
||||
|
||||
public static final int CANCEL = 0;
|
||||
public static final int APPLY = 1;
|
||||
public static final int RESET = 2;
|
||||
|
||||
private static final Localisation LOCAL = new Localisation("resources/MessagesBundle");
|
||||
private final SimpleProps sp;
|
||||
private final String disabledprefs;
|
||||
|
||||
/**
|
||||
* Creates a preferences editor dialog
|
||||
*
|
||||
* @param parent Parent Frame
|
||||
* @param sp
|
||||
* @param disabledprefs
|
||||
*/
|
||||
public PrefsDialog(java.awt.Frame parent, SimpleProps sp, String disabledprefs) {
|
||||
super(parent, true);
|
||||
this.sp = sp;
|
||||
this.disabledprefs = disabledprefs;
|
||||
initComponents();
|
||||
loadBasicPrefs(false);
|
||||
loadAdvancedPrefs(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the return status of this dialog - one of RET_OK or RET_CANCEL
|
||||
*/
|
||||
public int getReturnStatus() {
|
||||
return returnStatus;
|
||||
}
|
||||
|
||||
public void loadBasicPrefs(boolean usedefault) {
|
||||
|
||||
sp.setDefaultModeEnabled(usedefault);
|
||||
jCheckAutostart.setSelected(sp.getBool("PREF_AUTOSTART"));
|
||||
jCheckDisableTray.setSelected(sp.getBool("PREF_NOSYSTRAY"));
|
||||
jCheckHideMin.setEnabled(!jCheckDisableTray.isSelected());
|
||||
jCheckHideTray.setSelected(sp.getBool("PREF_HIDETOTRAY"));
|
||||
jCheckAppUpdate.setSelected(sp.getBool("PREF_UPDATECHECK"));
|
||||
jCheckMinOnClose.setSelected(sp.getBool("PREF_MINONCLOSE"));
|
||||
jCheckCacheDelete.setSelected(sp.getBool("PREF_CACHEDELETE"));
|
||||
jCheckDisableNotify.setSelected(sp.getBool("PREF_DISABLE_NOTIFY"));
|
||||
jCheckHideMin.setSelected(sp.getBool("PREF_HIDE_MIN"));
|
||||
jCheckGeoUpdate.setSelected(sp.getBool("PREF_GEOCHECK"));
|
||||
if (disabledprefs.contains("jCheckDisableTray")) {
|
||||
jCheckDisableTray.setEnabled(false);
|
||||
jCheckHideMin.setEnabled(false);
|
||||
}
|
||||
jCheckAppUpdate.setVisible(!disabledprefs.contains("jCheckAppUpdate"));
|
||||
sp.setDefaultModeEnabled(false);
|
||||
updatePortRanges(sp.getInt("PREF_TOR_TESTHREADS"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the preferences
|
||||
*
|
||||
* @param usedefault
|
||||
*/
|
||||
public void loadAdvancedPrefs(boolean usedefault) {
|
||||
sp.setDefaultModeEnabled(usedefault);
|
||||
jTextHTTPProxy.setText(sp.getString("PREF_HTTP_PROXY"));
|
||||
jSpinnerMainPort.setValue(sp.getInt("PREF_LISTENPORT"));
|
||||
jTextTorBridge.setText(sp.getString("PREF_TORBRIDGE"));
|
||||
jTextTorArgs.setText(sp.getString("PREF_TORARGS"));
|
||||
jComboLogLev.setSelectedIndex(sp.getInt("PREF_TORLOGLEV"));
|
||||
jCheckSafeSocks.setSelected(sp.getBool("PREF_SAFESOCKS"));
|
||||
jCheckTestSocks.setSelected(sp.getBool("PREF_TESTSOCKS"));
|
||||
jCheckAvoidDisk.setSelected(sp.getBool("PREF_AVOIDDISK"));
|
||||
jCheckSafeLog.setSelected(sp.getBool("PREF_SAFELOG"));
|
||||
sp.setDefaultModeEnabled(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save preferences
|
||||
*/
|
||||
public void savePreferences() {
|
||||
|
||||
sp.setInt("PREF_LISTENPORT", (Integer) jSpinnerMainPort.getValue());
|
||||
sp.setInt("PREF_TORLOGLEV", jComboLogLev.getSelectedIndex());
|
||||
sp.setBool("PREF_AUTOSTART", jCheckAutostart.isSelected());
|
||||
sp.setBool("PREF_NOSYSTRAY", jCheckDisableTray.isSelected());
|
||||
sp.setBool("PREF_HIDETOTRAY", jCheckHideTray.isSelected());
|
||||
sp.setBool("PREF_UPDATECHECK", jCheckAppUpdate.isSelected());
|
||||
sp.setBool("PREF_MINONCLOSE", jCheckMinOnClose.isSelected());
|
||||
sp.setBool("PREF_SAFESOCKS", jCheckSafeSocks.isSelected());
|
||||
sp.setBool("PREF_TESTSOCKS", jCheckTestSocks.isSelected());
|
||||
sp.setBool("PREF_AVOIDDISK", jCheckAvoidDisk.isSelected());
|
||||
sp.setBool("PREF_SAFELOG", jCheckSafeLog.isSelected());
|
||||
sp.setBool("PREF_CACHEDELETE", jCheckCacheDelete.isSelected());
|
||||
sp.setBool("PREF_DISABLE_NOTIFY", jCheckDisableNotify.isSelected());
|
||||
sp.setBool("PREF_HIDE_MIN", jCheckHideMin.isSelected());
|
||||
sp.setBool("PREF_GEOCHECK", jCheckGeoUpdate.isSelected());
|
||||
sp.setString("PREF_HTTP_PROXY", jTextHTTPProxy.getText());
|
||||
sp.setString("PREF_TORBRIDGE", jTextTorBridge.getText());
|
||||
sp.setString("PREF_TORARGS", jTextTorArgs.getText());
|
||||
}
|
||||
|
||||
/**
|
||||
* Update displayed port ranges to reflect any port changes
|
||||
*/
|
||||
private void updatePortRanges(int threads) {
|
||||
int intBasePort = sp.getInt("PREF_LISTENPORT");
|
||||
String strRanges = LOCAL.getString("label_portranges");
|
||||
strRanges = strRanges.replace("$portmin", String.valueOf(intBasePort));
|
||||
strRanges = strRanges.replace("$portmax", String.valueOf(intBasePort + (threads * 2) + 1));
|
||||
jLabelPortRanges.setText(strRanges);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
|
||||
jTabPrefs = new javax.swing.JTabbedPane();
|
||||
jPanelBasicPrefs = new javax.swing.JPanel();
|
||||
jPanelGeneralPrefs = new javax.swing.JPanel();
|
||||
jCheckHideTray = new javax.swing.JCheckBox();
|
||||
jCheckAppUpdate = new javax.swing.JCheckBox();
|
||||
jCheckAutostart = new javax.swing.JCheckBox();
|
||||
jCheckDisableTray = new javax.swing.JCheckBox();
|
||||
jCheckMinOnClose = new javax.swing.JCheckBox();
|
||||
jCheckCacheDelete = new javax.swing.JCheckBox();
|
||||
jCheckDisableNotify = new javax.swing.JCheckBox();
|
||||
jCheckHideMin = new javax.swing.JCheckBox();
|
||||
jCheckGeoUpdate = new javax.swing.JCheckBox();
|
||||
jPanelAdvancedPrefs = new javax.swing.JPanel();
|
||||
jPanelTorPrefs = new javax.swing.JPanel();
|
||||
jLabel6 = new javax.swing.JLabel();
|
||||
jSpinnerMainPort = new javax.swing.JSpinner();
|
||||
jLabelPortRanges = new javax.swing.JLabel();
|
||||
jLabel11 = new javax.swing.JLabel();
|
||||
jTextTorBridge = new javax.swing.JTextField();
|
||||
jButtonGetBridges = new javax.swing.JButton();
|
||||
jCheckSafeSocks = new javax.swing.JCheckBox();
|
||||
jLabel12 = new javax.swing.JLabel();
|
||||
jCheckTestSocks = new javax.swing.JCheckBox();
|
||||
jLabel13 = new javax.swing.JLabel();
|
||||
jTextTorArgs = new javax.swing.JTextField();
|
||||
jLabel14 = new javax.swing.JLabel();
|
||||
jCheckAvoidDisk = new javax.swing.JCheckBox();
|
||||
jLabel15 = new javax.swing.JLabel();
|
||||
jComboLogLev = new javax.swing.JComboBox<>();
|
||||
jCheckSafeLog = new javax.swing.JCheckBox();
|
||||
jPanel1 = new javax.swing.JPanel();
|
||||
jLabel16 = new javax.swing.JLabel();
|
||||
jTextHTTPProxy = new javax.swing.JTextField();
|
||||
jButtonCancel = new javax.swing.JButton();
|
||||
jButtonApply = new javax.swing.JButton();
|
||||
jButtonDefaults = new javax.swing.JButton();
|
||||
|
||||
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
|
||||
setIconImage(null);
|
||||
setResizable(false);
|
||||
addWindowListener(new java.awt.event.WindowAdapter() {
|
||||
public void windowClosing(java.awt.event.WindowEvent evt) {
|
||||
closeDialog(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jTabPrefs.addChangeListener(new javax.swing.event.ChangeListener() {
|
||||
public void stateChanged(javax.swing.event.ChangeEvent evt) {
|
||||
jTabPrefsStateChanged(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jPanelBasicPrefs.setFont(jPanelBasicPrefs.getFont().deriveFont(jPanelBasicPrefs.getFont().getStyle() | java.awt.Font.BOLD));
|
||||
|
||||
jPanelGeneralPrefs.setBorder(javax.swing.BorderFactory.createTitledBorder(null, LOCAL.getString("panel_general"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, jPanelBasicPrefs.getFont(), jPanelBasicPrefs.getForeground())); // NOI18N
|
||||
|
||||
jCheckHideTray.setText(LOCAL.getString("chkbox_hidetotray")); // NOI18N
|
||||
jCheckHideTray.setToolTipText(LOCAL.getString("ttip_hidetotray")); // NOI18N
|
||||
|
||||
jCheckAppUpdate.setSelected(true);
|
||||
jCheckAppUpdate.setText(LOCAL.getString("chkbox_checkforupdates")); // NOI18N
|
||||
jCheckAppUpdate.setToolTipText(LOCAL.getString("ttip_checkforupdates")); // NOI18N
|
||||
|
||||
jCheckAutostart.setText(LOCAL.getString("chkbox_autostart")); // NOI18N
|
||||
jCheckAutostart.setToolTipText(LOCAL.getString("ttip_autostart")); // NOI18N
|
||||
|
||||
jCheckDisableTray.setText(LOCAL.getString("chkbox_disabletray")); // NOI18N
|
||||
jCheckDisableTray.setToolTipText(LOCAL.getString("ttip_disabletray")); // NOI18N
|
||||
jCheckDisableTray.addItemListener(new java.awt.event.ItemListener() {
|
||||
public void itemStateChanged(java.awt.event.ItemEvent evt) {
|
||||
jCheckDisableTrayItemStateChanged(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jCheckMinOnClose.setText(LOCAL.getString("chkbox_minonclose")); // NOI18N
|
||||
jCheckMinOnClose.setToolTipText(LOCAL.getString("ttip_minonclose")); // NOI18N
|
||||
|
||||
jCheckCacheDelete.setText(LOCAL.getString("chkbox_securedelete")); // NOI18N
|
||||
jCheckCacheDelete.setToolTipText(LOCAL.getString("ttip_securedelete")); // NOI18N
|
||||
|
||||
jCheckDisableNotify.setText(LOCAL.getString("chkbox_disablenotify")); // NOI18N
|
||||
jCheckDisableNotify.setToolTipText(LOCAL.getString("ttip_disablenotify")); // NOI18N
|
||||
|
||||
jCheckHideMin.setText(LOCAL.getString("chkbox_hidemin")); // NOI18N
|
||||
jCheckHideMin.setToolTipText(LOCAL.getString("ttip_hidemin")); // NOI18N
|
||||
|
||||
jCheckGeoUpdate.setSelected(true);
|
||||
jCheckGeoUpdate.setText(LOCAL.getString("chkbox_geocheck")); // NOI18N
|
||||
jCheckGeoUpdate.setToolTipText(LOCAL.getString("ttip_geocheck")); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout jPanelGeneralPrefsLayout = new javax.swing.GroupLayout(jPanelGeneralPrefs);
|
||||
jPanelGeneralPrefs.setLayout(jPanelGeneralPrefsLayout);
|
||||
jPanelGeneralPrefsLayout.setHorizontalGroup(
|
||||
jPanelGeneralPrefsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanelGeneralPrefsLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(jPanelGeneralPrefsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jCheckAutostart)
|
||||
.addComponent(jCheckHideTray)
|
||||
.addComponent(jCheckCacheDelete)
|
||||
.addComponent(jCheckHideMin)
|
||||
.addComponent(jCheckDisableNotify))
|
||||
.addGap(18, 18, 18)
|
||||
.addGroup(jPanelGeneralPrefsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jCheckAppUpdate)
|
||||
.addComponent(jCheckGeoUpdate)
|
||||
.addComponent(jCheckDisableTray)
|
||||
.addComponent(jCheckMinOnClose))
|
||||
.addContainerGap(39, Short.MAX_VALUE))
|
||||
);
|
||||
jPanelGeneralPrefsLayout.setVerticalGroup(
|
||||
jPanelGeneralPrefsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanelGeneralPrefsLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(jPanelGeneralPrefsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jCheckAutostart)
|
||||
.addComponent(jCheckGeoUpdate))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(jPanelGeneralPrefsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jCheckHideTray)
|
||||
.addComponent(jCheckDisableTray))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(jPanelGeneralPrefsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jCheckHideMin)
|
||||
.addComponent(jCheckMinOnClose))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(jPanelGeneralPrefsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jCheckCacheDelete)
|
||||
.addComponent(jCheckAppUpdate))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jCheckDisableNotify)
|
||||
.addContainerGap(132, Short.MAX_VALUE))
|
||||
);
|
||||
|
||||
javax.swing.GroupLayout jPanelBasicPrefsLayout = new javax.swing.GroupLayout(jPanelBasicPrefs);
|
||||
jPanelBasicPrefs.setLayout(jPanelBasicPrefsLayout);
|
||||
jPanelBasicPrefsLayout.setHorizontalGroup(
|
||||
jPanelBasicPrefsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanelBasicPrefsLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(jPanelGeneralPrefs, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addContainerGap())
|
||||
);
|
||||
jPanelBasicPrefsLayout.setVerticalGroup(
|
||||
jPanelBasicPrefsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanelBasicPrefsLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(jPanelGeneralPrefs, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
jTabPrefs.addTab(LOCAL.getString("tab_basic"), jPanelBasicPrefs); // NOI18N
|
||||
|
||||
jPanelTorPrefs.setBorder(javax.swing.BorderFactory.createTitledBorder(null, LOCAL.getString("panel_torclientset"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, jPanelBasicPrefs.getFont(), jPanelBasicPrefs.getForeground())); // NOI18N
|
||||
|
||||
jLabel6.setText(LOCAL.getString("label_listenport")); // NOI18N
|
||||
|
||||
jSpinnerMainPort.setModel(new javax.swing.SpinnerNumberModel(9050, 9050, 9999, 1));
|
||||
jSpinnerMainPort.setToolTipText(LOCAL.getString("ttip_listenport")); // NOI18N
|
||||
|
||||
jLabelPortRanges.setText("Currently active port ranges, 9052 to 9063");
|
||||
|
||||
jLabel11.setText(LOCAL.getString("label_bridgeaddress")); // NOI18N
|
||||
|
||||
jTextTorBridge.setToolTipText(LOCAL.getString("ttip_bridgeaddress")); // NOI18N
|
||||
|
||||
jButtonGetBridges.setText(LOCAL.getString("button_getbridges")); // NOI18N
|
||||
jButtonGetBridges.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
jButtonGetBridgesActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jCheckSafeSocks.setText(LOCAL.getString("chkbox_safesocks")); // NOI18N
|
||||
jCheckSafeSocks.setToolTipText(LOCAL.getString("ttip_safesocks")); // NOI18N
|
||||
|
||||
jLabel12.setText(LOCAL.getString("label_torlogging")); // NOI18N
|
||||
|
||||
jCheckTestSocks.setText(LOCAL.getString("chkbox_testsocks")); // NOI18N
|
||||
jCheckTestSocks.setToolTipText(LOCAL.getString("ttip_testsocks")); // NOI18N
|
||||
|
||||
jLabel13.setText(LOCAL.getString("label_torargs")); // NOI18N
|
||||
|
||||
jTextTorArgs.setToolTipText(LOCAL.getString("ttip_extraargs")); // NOI18N
|
||||
|
||||
jLabel14.setText(LOCAL.getString("label_torsocks")); // NOI18N
|
||||
|
||||
jCheckAvoidDisk.setText(LOCAL.getString("chkbox_diskavoid")); // NOI18N
|
||||
jCheckAvoidDisk.setToolTipText(LOCAL.getString("ttip_avoiddisk")); // NOI18N
|
||||
|
||||
jLabel15.setText(LOCAL.getString("label_diskoptions")); // NOI18N
|
||||
|
||||
jComboLogLev.setModel(new DefaultComboBoxModel<>(new String[] {LOCAL.getString("combo_loglev1"),LOCAL.getString("combo_loglev2"),LOCAL.getString("combo_loglev3")}));
|
||||
jComboLogLev.setToolTipText(LOCAL.getString("ttip_combo_loglevel")); // NOI18N
|
||||
|
||||
jCheckSafeLog.setText(LOCAL.getString("chkbox_safelog")); // NOI18N
|
||||
jCheckSafeLog.setToolTipText(LOCAL.getString("ttip_safelogging")); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout jPanelTorPrefsLayout = new javax.swing.GroupLayout(jPanelTorPrefs);
|
||||
jPanelTorPrefs.setLayout(jPanelTorPrefsLayout);
|
||||
jPanelTorPrefsLayout.setHorizontalGroup(
|
||||
jPanelTorPrefsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanelTorPrefsLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(jPanelTorPrefsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jLabel14)
|
||||
.addComponent(jLabel15)
|
||||
.addComponent(jLabel12)
|
||||
.addComponent(jLabel13)
|
||||
.addComponent(jLabel11)
|
||||
.addComponent(jLabel6))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(jPanelTorPrefsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||
.addGroup(jPanelTorPrefsLayout.createSequentialGroup()
|
||||
.addComponent(jCheckSafeSocks)
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(jCheckTestSocks))
|
||||
.addComponent(jCheckAvoidDisk)
|
||||
.addGroup(jPanelTorPrefsLayout.createSequentialGroup()
|
||||
.addComponent(jComboLogLev, javax.swing.GroupLayout.PREFERRED_SIZE, 145, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(jCheckSafeLog))
|
||||
.addGroup(jPanelTorPrefsLayout.createSequentialGroup()
|
||||
.addComponent(jTextTorBridge, javax.swing.GroupLayout.PREFERRED_SIZE, 259, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jButtonGetBridges))
|
||||
.addGroup(jPanelTorPrefsLayout.createSequentialGroup()
|
||||
.addComponent(jSpinnerMainPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jLabelPortRanges))
|
||||
.addComponent(jTextTorArgs))
|
||||
.addContainerGap())
|
||||
);
|
||||
jPanelTorPrefsLayout.setVerticalGroup(
|
||||
jPanelTorPrefsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanelTorPrefsLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(jPanelTorPrefsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
|
||||
.addComponent(jLabelPortRanges)
|
||||
.addComponent(jSpinnerMainPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(jLabel6))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(jPanelTorPrefsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel11)
|
||||
.addComponent(jTextTorBridge, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(jButtonGetBridges))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(jPanelTorPrefsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel14)
|
||||
.addComponent(jCheckSafeSocks)
|
||||
.addComponent(jCheckTestSocks))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(jPanelTorPrefsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel12)
|
||||
.addComponent(jComboLogLev, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(jCheckSafeLog))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addGroup(jPanelTorPrefsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel15)
|
||||
.addComponent(jCheckAvoidDisk))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addGroup(jPanelTorPrefsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel13)
|
||||
.addComponent(jTextTorArgs, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder(null, LOCAL.getString("panel_network"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, jPanelBasicPrefs.getFont(), jPanelBasicPrefs.getForeground())); // NOI18N
|
||||
|
||||
jLabel16.setText(LOCAL.getString("label_defaultproxy")); // NOI18N
|
||||
|
||||
jTextHTTPProxy.setToolTipText(LOCAL.getString("ttip_defaultproxy")); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
|
||||
jPanel1.setLayout(jPanel1Layout);
|
||||
jPanel1Layout.setHorizontalGroup(
|
||||
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(jLabel16)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jTextHTTPProxy)
|
||||
.addContainerGap())
|
||||
);
|
||||
jPanel1Layout.setVerticalGroup(
|
||||
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel16)
|
||||
.addComponent(jTextHTTPProxy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
javax.swing.GroupLayout jPanelAdvancedPrefsLayout = new javax.swing.GroupLayout(jPanelAdvancedPrefs);
|
||||
jPanelAdvancedPrefs.setLayout(jPanelAdvancedPrefsLayout);
|
||||
jPanelAdvancedPrefsLayout.setHorizontalGroup(
|
||||
jPanelAdvancedPrefsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanelAdvancedPrefsLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(jPanelAdvancedPrefsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(jPanelTorPrefs, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addContainerGap())
|
||||
);
|
||||
jPanelAdvancedPrefsLayout.setVerticalGroup(
|
||||
jPanelAdvancedPrefsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanelAdvancedPrefsLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(jPanelTorPrefs, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
jTabPrefs.addTab(LOCAL.getString("tab_advanced"), jPanelAdvancedPrefs); // NOI18N
|
||||
|
||||
jButtonCancel.setText(LOCAL.getString("button_close")); // NOI18N
|
||||
jButtonCancel.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
jButtonCancelActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jButtonApply.setText(LOCAL.getString("button_apply")); // NOI18N
|
||||
jButtonApply.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
jButtonApplyActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jButtonDefaults.setText(LOCAL.getString("button_prefdefaults")); // NOI18N
|
||||
jButtonDefaults.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
jButtonDefaultsActionPerformed(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()
|
||||
.addComponent(jButtonDefaults)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(jButtonCancel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jButtonApply)
|
||||
.addContainerGap())
|
||||
.addComponent(jTabPrefs)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(jTabPrefs)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jButtonApply)
|
||||
.addComponent(jButtonCancel)
|
||||
.addComponent(jButtonDefaults))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
pack();
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void jButtonApplyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonApplyActionPerformed
|
||||
savePreferences();
|
||||
updatePortRanges(sp.getInt("PREF_TOR_TESTHREADS"));
|
||||
doClose(APPLY);
|
||||
}//GEN-LAST:event_jButtonApplyActionPerformed
|
||||
|
||||
private void jButtonCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonCancelActionPerformed
|
||||
doClose(CANCEL);
|
||||
}//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 jButtonGetBridgesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonGetBridgesActionPerformed
|
||||
Utilities.openFileExternally("https://bridges.torproject.org/bridges?lang="
|
||||
+ LOCAL.toWebLanguageTag());
|
||||
}//GEN-LAST:event_jButtonGetBridgesActionPerformed
|
||||
|
||||
private void jButtonDefaultsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonDefaultsActionPerformed
|
||||
switch (jTabPrefs.getSelectedIndex()) {
|
||||
// Basic tab
|
||||
case 0:
|
||||
loadBasicPrefs(true);
|
||||
break;
|
||||
// Advanced tab
|
||||
case 1:
|
||||
loadAdvancedPrefs(true);
|
||||
break;
|
||||
}
|
||||
}//GEN-LAST:event_jButtonDefaultsActionPerformed
|
||||
|
||||
private void jTabPrefsStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_jTabPrefsStateChanged
|
||||
switch (jTabPrefs.getSelectedIndex()) {
|
||||
case 0:
|
||||
jButtonDefaults.setToolTipText(LOCAL.getString("ttip_resetbasicprefs"));
|
||||
break;
|
||||
case 1:
|
||||
jButtonDefaults.setToolTipText(LOCAL.getString("ttip_resetadvprefs"));
|
||||
break;
|
||||
}
|
||||
}//GEN-LAST:event_jTabPrefsStateChanged
|
||||
|
||||
private void jCheckDisableTrayItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_jCheckDisableTrayItemStateChanged
|
||||
jCheckHideMin.setEnabled(!jCheckDisableTray.isSelected());
|
||||
}//GEN-LAST:event_jCheckDisableTrayItemStateChanged
|
||||
|
||||
private void doClose(int retStatus) {
|
||||
returnStatus = retStatus;
|
||||
setVisible(false);
|
||||
dispose();
|
||||
}
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton jButtonApply;
|
||||
private javax.swing.JButton jButtonCancel;
|
||||
private javax.swing.JButton jButtonDefaults;
|
||||
private javax.swing.JButton jButtonGetBridges;
|
||||
private javax.swing.JCheckBox jCheckAppUpdate;
|
||||
private javax.swing.JCheckBox jCheckAutostart;
|
||||
private javax.swing.JCheckBox jCheckAvoidDisk;
|
||||
private javax.swing.JCheckBox jCheckCacheDelete;
|
||||
private javax.swing.JCheckBox jCheckDisableNotify;
|
||||
private javax.swing.JCheckBox jCheckDisableTray;
|
||||
private javax.swing.JCheckBox jCheckGeoUpdate;
|
||||
private javax.swing.JCheckBox jCheckHideMin;
|
||||
private javax.swing.JCheckBox jCheckHideTray;
|
||||
private javax.swing.JCheckBox jCheckMinOnClose;
|
||||
private javax.swing.JCheckBox jCheckSafeLog;
|
||||
private javax.swing.JCheckBox jCheckSafeSocks;
|
||||
private javax.swing.JCheckBox jCheckTestSocks;
|
||||
private javax.swing.JComboBox<String> jComboLogLev;
|
||||
private javax.swing.JLabel jLabel11;
|
||||
private javax.swing.JLabel jLabel12;
|
||||
private javax.swing.JLabel jLabel13;
|
||||
private javax.swing.JLabel jLabel14;
|
||||
private javax.swing.JLabel jLabel15;
|
||||
private javax.swing.JLabel jLabel16;
|
||||
private javax.swing.JLabel jLabel6;
|
||||
private javax.swing.JLabel jLabelPortRanges;
|
||||
private javax.swing.JPanel jPanel1;
|
||||
private javax.swing.JPanel jPanelAdvancedPrefs;
|
||||
private javax.swing.JPanel jPanelBasicPrefs;
|
||||
private javax.swing.JPanel jPanelGeneralPrefs;
|
||||
private javax.swing.JPanel jPanelTorPrefs;
|
||||
private javax.swing.JSpinner jSpinnerMainPort;
|
||||
private javax.swing.JTabbedPane jTabPrefs;
|
||||
private javax.swing.JTextField jTextHTTPProxy;
|
||||
private javax.swing.JTextField jTextTorArgs;
|
||||
private javax.swing.JTextField jTextTorBridge;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
private int returnStatus = CANCEL;
|
||||
}
|
138
src/client/QuickAddDialog.form
Normal file
138
src/client/QuickAddDialog.form
Normal file
|
@ -0,0 +1,138 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.6" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
|
||||
<Properties>
|
||||
<Property name="defaultCloseOperation" type="int" value="2"/>
|
||||
<Property name="title" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="dlg_quickadd_title" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
<Property name="iconImage" type="java.awt.Image" editor="org.netbeans.modules.form.ComponentChooserEditor">
|
||||
<ComponentRef name="null"/>
|
||||
</Property>
|
||||
<Property name="resizable" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<SyntheticProperties>
|
||||
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
|
||||
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
|
||||
</SyntheticProperties>
|
||||
<Events>
|
||||
<EventHandler event="windowClosing" listener="java.awt.event.WindowListener" parameters="java.awt.event.WindowEvent" handler="closeDialog"/>
|
||||
</Events>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jPanelPreferences" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jPanelPreferences" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="jPanelPreferences">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
|
||||
<FontInfo relative="true">
|
||||
<Font bold="true" component="jPanelPreferences" property="font" relativeSize="true" size="0"/>
|
||||
</FontInfo>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jLabel1" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jTextDescription" alignment="1" pref="343" max="32767" attributes="1"/>
|
||||
<Component id="jLabel2" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jTextPattern" alignment="0" pref="343" max="32767" attributes="1"/>
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<Component id="jButtonCancel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jButtonApply" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||
<Component id="jTextDescription" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jLabel2" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||
<Component id="jTextPattern" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jButtonApply" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jButtonCancel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="jLabel1">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="label_quickadd_desc" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="jTextDescription">
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel2">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="label_quickadd_pattern" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="jTextPattern">
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="jButtonCancel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="button_cancel" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButtonCancelActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="jButtonApply">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="button_addnew" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButtonApplyActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
214
src/client/QuickAddDialog.java
Normal file
214
src/client/QuickAddDialog.java
Normal file
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
* 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.Localisation;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alistair Neil, <info@dazzleships.net>
|
||||
*/
|
||||
public final class QuickAddDialog extends javax.swing.JDialog {
|
||||
|
||||
private static final Localisation LOCAL = new Localisation("resources/MessagesBundle");
|
||||
public static final int CANCEL = 0;
|
||||
public static final int APPLY = 1;
|
||||
public static final int RESET = 2;
|
||||
|
||||
/**
|
||||
* Creates a quick add patterns dialog
|
||||
*
|
||||
* @param parent parent frame
|
||||
* @param modal modality
|
||||
*/
|
||||
public QuickAddDialog(java.awt.Frame parent, boolean modal) {
|
||||
super(parent, modal);
|
||||
initComponents();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set text that appears on the Apply button
|
||||
*
|
||||
* @param text
|
||||
*/
|
||||
public void setApplyText(String text) {
|
||||
jButtonApply.setText(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the test that appears in both fields
|
||||
*
|
||||
* @param desc
|
||||
* @param pattern
|
||||
*/
|
||||
public void setFields(String desc, String pattern) {
|
||||
jTextDescription.setText(desc);
|
||||
jTextPattern.setText(pattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get contents of description field
|
||||
*
|
||||
* @return String text
|
||||
*/
|
||||
public String getDescription() {
|
||||
return jTextDescription.getText();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get contents of the pattern field
|
||||
*
|
||||
* @return String text
|
||||
*/
|
||||
public String getPattern() {
|
||||
return jTextPattern.getText();
|
||||
}
|
||||
|
||||
/**
|
||||
* @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() {
|
||||
|
||||
jPanelPreferences = new javax.swing.JPanel();
|
||||
jLabel1 = new javax.swing.JLabel();
|
||||
jTextDescription = new javax.swing.JTextField();
|
||||
jLabel2 = new javax.swing.JLabel();
|
||||
jTextPattern = new javax.swing.JTextField();
|
||||
jButtonCancel = new javax.swing.JButton();
|
||||
jButtonApply = new javax.swing.JButton();
|
||||
|
||||
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
|
||||
setTitle(LOCAL.getString("dlg_quickadd_title")); // NOI18N
|
||||
setIconImage(null);
|
||||
setResizable(false);
|
||||
addWindowListener(new java.awt.event.WindowAdapter() {
|
||||
public void windowClosing(java.awt.event.WindowEvent evt) {
|
||||
closeDialog(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jPanelPreferences.setFont(jPanelPreferences.getFont().deriveFont(jPanelPreferences.getFont().getStyle() | java.awt.Font.BOLD));
|
||||
|
||||
jLabel1.setText(LOCAL.getString("label_quickadd_desc")); // NOI18N
|
||||
|
||||
jLabel2.setText(LOCAL.getString("label_quickadd_pattern")); // NOI18N
|
||||
|
||||
jButtonCancel.setText(LOCAL.getString("button_cancel")); // NOI18N
|
||||
jButtonCancel.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
jButtonCancelActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jButtonApply.setText(LOCAL.getString("button_addnew")); // NOI18N
|
||||
jButtonApply.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
jButtonApplyActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout jPanelPreferencesLayout = new javax.swing.GroupLayout(jPanelPreferences);
|
||||
jPanelPreferences.setLayout(jPanelPreferencesLayout);
|
||||
jPanelPreferencesLayout.setHorizontalGroup(
|
||||
jPanelPreferencesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanelPreferencesLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(jPanelPreferencesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jLabel1)
|
||||
.addComponent(jTextDescription, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 343, Short.MAX_VALUE)
|
||||
.addComponent(jLabel2)
|
||||
.addComponent(jTextPattern, javax.swing.GroupLayout.DEFAULT_SIZE, 343, Short.MAX_VALUE)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanelPreferencesLayout.createSequentialGroup()
|
||||
.addComponent(jButtonCancel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jButtonApply)))
|
||||
.addContainerGap())
|
||||
);
|
||||
jPanelPreferencesLayout.setVerticalGroup(
|
||||
jPanelPreferencesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanelPreferencesLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(jLabel1)
|
||||
.addGap(0, 0, 0)
|
||||
.addComponent(jTextDescription, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jLabel2)
|
||||
.addGap(0, 0, 0)
|
||||
.addComponent(jTextPattern, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(jPanelPreferencesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jButtonApply)
|
||||
.addComponent(jButtonCancel))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
|
||||
getContentPane().setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jPanelPreferences, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jPanelPreferences, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
);
|
||||
|
||||
pack();
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void jButtonApplyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonApplyActionPerformed
|
||||
doClose(APPLY);
|
||||
}//GEN-LAST:event_jButtonApplyActionPerformed
|
||||
|
||||
private void jButtonCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonCancelActionPerformed
|
||||
doClose(CANCEL);
|
||||
}//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 doClose(int retStatus) {
|
||||
returnStatus = retStatus;
|
||||
setVisible(false);
|
||||
dispose();
|
||||
}
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton jButtonApply;
|
||||
private javax.swing.JButton jButtonCancel;
|
||||
private javax.swing.JLabel jLabel1;
|
||||
private javax.swing.JLabel jLabel2;
|
||||
private javax.swing.JPanel jPanelPreferences;
|
||||
private javax.swing.JTextField jTextDescription;
|
||||
private javax.swing.JTextField jTextPattern;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
private int returnStatus = CANCEL;
|
||||
}
|
1018
src/client/SelekTOR.form
Normal file
1018
src/client/SelekTOR.form
Normal file
File diff suppressed because it is too large
Load diff
3595
src/client/SelekTOR.java
Normal file
3595
src/client/SelekTOR.java
Normal file
File diff suppressed because it is too large
Load diff
236
src/client/TorCircuit.java
Normal file
236
src/client/TorCircuit.java
Normal file
|
@ -0,0 +1,236 @@
|
|||
/*
|
||||
* 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 java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alistair Neil <info@dazzleships.net>
|
||||
*/
|
||||
public final class TorCircuit {
|
||||
|
||||
public static final int FINGER = 0;
|
||||
public static final int NICKNAME = 1;
|
||||
private String[] dataCirc;
|
||||
private String[] dataHops;
|
||||
private String circuitinfo;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public TorCircuit() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor, Create circuit object with given circuit
|
||||
*
|
||||
* @param circuit
|
||||
*/
|
||||
public TorCircuit(String circuit) {
|
||||
setCircuit(circuit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set circuit to supplied circuit
|
||||
*
|
||||
* @param circuit
|
||||
*/
|
||||
public void setCircuit(String circuit) {
|
||||
circuitinfo = circuit;
|
||||
Pattern pattern = Pattern.compile(" ");
|
||||
dataCirc = pattern.split(circuit);
|
||||
setHops(dataCirc[2]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get circuit
|
||||
*
|
||||
* @return circuit as string
|
||||
*/
|
||||
public String getCircuit() {
|
||||
return circuitinfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set hops
|
||||
*
|
||||
* @param hops
|
||||
*/
|
||||
public void setHops(String hops) {
|
||||
Pattern pattern = Pattern.compile(",");
|
||||
dataHops = pattern.split(hops);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current circuit ID
|
||||
*
|
||||
* @return ID as string
|
||||
*/
|
||||
public String getID() {
|
||||
return dataCirc[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current circuit status
|
||||
*
|
||||
* @return status as string
|
||||
*/
|
||||
public String getStatus() {
|
||||
return dataCirc[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current circuits build flags
|
||||
*
|
||||
* @return build flags as string
|
||||
*/
|
||||
public String getBuildFlags() {
|
||||
return dataCirc[3].substring(12);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current circuits purpose
|
||||
*
|
||||
* @return purpose as string
|
||||
*/
|
||||
public String getPurpose() {
|
||||
return dataCirc[4].substring(8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current circuits timestamp
|
||||
*
|
||||
* @return timestamp as string
|
||||
*/
|
||||
public String getTimestamp() {
|
||||
return dataCirc[5].substring(13);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get circuit hops
|
||||
*
|
||||
* @return circuit hops as string
|
||||
*/
|
||||
public String getHops() {
|
||||
return dataCirc[2];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current circuits guard or entry node
|
||||
*
|
||||
* @return guard node as string
|
||||
*/
|
||||
public String getGuardHop() {
|
||||
String result = null;
|
||||
try {
|
||||
result = dataHops[0];
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current circuits middle node if any, returns exit node for a two hop
|
||||
* circuit
|
||||
*
|
||||
* @return middleman node as string
|
||||
*/
|
||||
public String getMiddleHop() {
|
||||
String result = null;
|
||||
try {
|
||||
if (dataHops.length < 3) {
|
||||
result = "";
|
||||
} else {
|
||||
result = dataHops[1];
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current circuits exit node
|
||||
*
|
||||
* @return exit node as string
|
||||
*/
|
||||
public String getExitHop() {
|
||||
String result = null;
|
||||
try {
|
||||
result = dataHops[dataHops.length - 1];
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Guardnode finger or nick
|
||||
*
|
||||
* @param type 0 = finger, 1 = nick
|
||||
* @return fingerprint as string
|
||||
*/
|
||||
public String getGuard(int type) {
|
||||
return getFromNodeHop(getGuardHop(), type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Middleman
|
||||
*
|
||||
* @param type 0 = finger, 1 = nick
|
||||
* @return fingerprint as string
|
||||
*/
|
||||
public String getMiddleMan(int type) {
|
||||
return getFromNodeHop(getMiddleHop(), type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Exitnode
|
||||
*
|
||||
* @param type 0 = finger, 1 = nick
|
||||
* @return fingerprint as string
|
||||
*/
|
||||
public String getExit(int type) {
|
||||
return getFromNodeHop(getExitHop(), type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get fingerprint of given node Nodeinfo is in the format of
|
||||
* fingerprint~name or fingerprint=name
|
||||
*
|
||||
* @param nodeinfo
|
||||
* @param type 0 = finger, 1 = nickname
|
||||
* @return fingerprint as string
|
||||
*/
|
||||
public static String getFromNodeHop(String nodeinfo, int type) {
|
||||
Pattern pattern;
|
||||
try {
|
||||
if (nodeinfo.contains("~")) {
|
||||
pattern = Pattern.compile("~");
|
||||
} else {
|
||||
pattern = Pattern.compile("=");
|
||||
}
|
||||
String[] result = pattern.split(nodeinfo);
|
||||
if (result.length > 0) {
|
||||
return result[type];
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
1165
src/client/TorController.java
Normal file
1165
src/client/TorController.java
Normal file
File diff suppressed because it is too large
Load diff
195
src/client/TorMonFrame.form
Normal file
195
src/client/TorMonFrame.form
Normal file
|
@ -0,0 +1,195 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JFrameFormInfo">
|
||||
<Properties>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[554, 492]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<SyntheticProperties>
|
||||
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
|
||||
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
|
||||
</SyntheticProperties>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jPanelMain" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jPanelMain" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="jPanelMain">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
|
||||
<FontInfo relative="true">
|
||||
<Font bold="true" component="jPanelMain" property="font" relativeSize="true" size="0"/>
|
||||
</FontInfo>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jPanel1" alignment="0" max="32767" attributes="0"/>
|
||||
<Component id="jPanel2" alignment="0" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
<Component id="jButtonClose" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jPanel1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jPanel2" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jButtonClose" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="jPanel1">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||
<TitledBorder title="Startup Arguments">
|
||||
<ResourceString PropertyName="titleX" bundle="resources/MessagesBundle.properties" key="panel_startupargs" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
<Connection PropertyName="font" component="jPanelMain" name="font" type="property"/>
|
||||
</TitledBorder>
|
||||
</Border>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jScrollPane1" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jScrollPane1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTextArea" name="jTextAreaLaunch">
|
||||
<Properties>
|
||||
<Property name="editable" type="boolean" value="false"/>
|
||||
<Property name="columns" type="int" value="38"/>
|
||||
<Property name="lineWrap" type="boolean" value="true"/>
|
||||
<Property name="rows" type="int" value="7"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="jPanel2">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||
<TitledBorder title="StdOut Monitor">
|
||||
<ResourceString PropertyName="titleX" bundle="resources/MessagesBundle.properties" key="panel_stdout" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
<Connection PropertyName="font" component="jPanelMain" name="font" type="property"/>
|
||||
</TitledBorder>
|
||||
</Border>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jScrollPaneStdOut" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jScrollPaneStdOut" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="jScrollPaneStdOut">
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTextArea" name="jTextAreaStdOut">
|
||||
<Properties>
|
||||
<Property name="editable" type="boolean" value="false"/>
|
||||
<Property name="columns" type="int" value="38"/>
|
||||
<Property name="rows" type="int" value="8"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JButton" name="jButtonClose">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="resources/MessagesBundle.properties" key="button_close" replaceFormat="LOCAL.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButtonCloseActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
191
src/client/TorMonFrame.java
Normal file
191
src/client/TorMonFrame.java
Normal file
|
@ -0,0 +1,191 @@
|
|||
/*
|
||||
* 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 javax.swing.JTextArea;
|
||||
import lib.GTKFixes;
|
||||
import lib.Localisation;
|
||||
import lib.OSFunction;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alistair Neil <info@dazzleships.net>
|
||||
*/
|
||||
public class TorMonFrame extends javax.swing.JFrame {
|
||||
|
||||
private static final Localisation LOCAL = new Localisation("resources/MessagesBundle");
|
||||
|
||||
/**
|
||||
* Creates new form TorMonFrame
|
||||
*/
|
||||
public TorMonFrame() {
|
||||
initComponents();
|
||||
jTextAreaLaunch.setOpaque(OSFunction.isWindows());
|
||||
jTextAreaStdOut.setOpaque(OSFunction.isWindows());
|
||||
GTKFixes.fixTextAreaColor(jTextAreaLaunch);
|
||||
GTKFixes.fixTextAreaColor(jTextAreaStdOut);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set launch command text
|
||||
*
|
||||
* @param command
|
||||
*/
|
||||
public void setLaunchString(String command) {
|
||||
jTextAreaLaunch.setText(command);
|
||||
jTextAreaLaunch.setCaretPosition(0);
|
||||
}
|
||||
|
||||
public JTextArea getStdoutTextArea() {
|
||||
return jTextAreaStdOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
jPanelMain = new javax.swing.JPanel();
|
||||
jPanel1 = new javax.swing.JPanel();
|
||||
jScrollPane1 = new javax.swing.JScrollPane();
|
||||
jTextAreaLaunch = new javax.swing.JTextArea();
|
||||
jPanel2 = new javax.swing.JPanel();
|
||||
jScrollPaneStdOut = new javax.swing.JScrollPane();
|
||||
jTextAreaStdOut = new javax.swing.JTextArea();
|
||||
jButtonClose = new javax.swing.JButton();
|
||||
|
||||
setMinimumSize(new java.awt.Dimension(554, 492));
|
||||
|
||||
jPanelMain.setFont(jPanelMain.getFont().deriveFont(jPanelMain.getFont().getStyle() | java.awt.Font.BOLD));
|
||||
|
||||
jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder(null, LOCAL.getString("panel_startupargs"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, jPanelMain.getFont())); // NOI18N
|
||||
|
||||
jTextAreaLaunch.setEditable(false);
|
||||
jTextAreaLaunch.setColumns(38);
|
||||
jTextAreaLaunch.setLineWrap(true);
|
||||
jTextAreaLaunch.setRows(7);
|
||||
jScrollPane1.setViewportView(jTextAreaLaunch);
|
||||
|
||||
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
|
||||
jPanel1.setLayout(jPanel1Layout);
|
||||
jPanel1Layout.setHorizontalGroup(
|
||||
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(jScrollPane1)
|
||||
.addContainerGap())
|
||||
);
|
||||
jPanel1Layout.setVerticalGroup(
|
||||
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder(null, LOCAL.getString("panel_stdout"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, jPanelMain.getFont())); // NOI18N
|
||||
|
||||
jTextAreaStdOut.setEditable(false);
|
||||
jTextAreaStdOut.setColumns(38);
|
||||
jTextAreaStdOut.setRows(8);
|
||||
jScrollPaneStdOut.setViewportView(jTextAreaStdOut);
|
||||
|
||||
javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
|
||||
jPanel2.setLayout(jPanel2Layout);
|
||||
jPanel2Layout.setHorizontalGroup(
|
||||
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel2Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(jScrollPaneStdOut)
|
||||
.addContainerGap())
|
||||
);
|
||||
jPanel2Layout.setVerticalGroup(
|
||||
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(jScrollPaneStdOut)
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
jButtonClose.setText(LOCAL.getString("button_close")); // NOI18N
|
||||
jButtonClose.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
jButtonCloseActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout jPanelMainLayout = new javax.swing.GroupLayout(jPanelMain);
|
||||
jPanelMain.setLayout(jPanelMainLayout);
|
||||
jPanelMainLayout.setHorizontalGroup(
|
||||
jPanelMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanelMainLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(jPanelMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanelMainLayout.createSequentialGroup()
|
||||
.addGap(0, 0, Short.MAX_VALUE)
|
||||
.addComponent(jButtonClose)))
|
||||
.addContainerGap())
|
||||
);
|
||||
jPanelMainLayout.setVerticalGroup(
|
||||
jPanelMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanelMainLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jButtonClose)
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
|
||||
getContentPane().setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jPanelMain, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jPanelMain, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
);
|
||||
|
||||
pack();
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void jButtonCloseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonCloseActionPerformed
|
||||
this.setVisible(false);
|
||||
}//GEN-LAST:event_jButtonCloseActionPerformed
|
||||
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton jButtonClose;
|
||||
private javax.swing.JPanel jPanel1;
|
||||
private javax.swing.JPanel jPanel2;
|
||||
private javax.swing.JPanel jPanelMain;
|
||||
private javax.swing.JScrollPane jScrollPane1;
|
||||
private javax.swing.JScrollPane jScrollPaneStdOut;
|
||||
private javax.swing.JTextArea jTextAreaLaunch;
|
||||
private javax.swing.JTextArea jTextAreaStdOut;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
845
src/client/TorProcess.java
Normal file
845
src/client/TorProcess.java
Normal file
|
@ -0,0 +1,845 @@
|
|||
/*
|
||||
* 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 java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URI;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.text.BadLocationException;
|
||||
import lib.ClientProcess;
|
||||
import lib.SimpleFile;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alistair Neil <info@dazzleships.net>
|
||||
*/
|
||||
public class TorProcess extends ClientProcess {
|
||||
|
||||
public static final int LOG_DEBUG = 0;
|
||||
public static final int LOG_INFO = 1;
|
||||
public static final int LOG_NOTICE = 2;
|
||||
private static final String TORCONFIGFILE = "torrc";
|
||||
public static final String EMPTYSTRING = "";
|
||||
|
||||
// Event constants
|
||||
public static final int TOR_MESSAGE = 0;
|
||||
public static final int TOR_BOOT_TIMEOUT = 1;
|
||||
public static final int TOR_BOOT_FATAL = 2;
|
||||
public static final int TOR_BOOT_ERROR = 3;
|
||||
public static final int TOR_CLOCK_ERROR = 4;
|
||||
public static final int TOR_NOROUTE = 5;
|
||||
public static final int TOR_BOOTED = 6;
|
||||
public static final int TOR_RESTARTED = 7;
|
||||
public static final int TOR_NOEXITS = 8;
|
||||
public static final int TOR_STOPPED = 9;
|
||||
public static final int TOR_BRIDGE = 10;
|
||||
public static final int TOR_NEWCIRC = 11;
|
||||
public static final int TOR_DIRINFO_STALE = 12;
|
||||
public static final int TOR_NOHOP0 = 13;
|
||||
public static final int TOR_NONET_ACTIVITY = 14;
|
||||
private static final String[] EVENTMESSAGES = new String[]{
|
||||
"TOR_MESSAGE", "TOR_BOOT_TIMEOUT", "TOR_BOOT_FATAL", "TOR_BOOT_ERROR",
|
||||
"TOR_CLOCK_ERROR", "TOR_NOROUTE", "TOR_BOOTED", "TOR_RESTARTED",
|
||||
"TOR_NOEXITS", "TOR_STOPPED", "TOR_BRIDGE", "TOR_NEWCIRC",
|
||||
"TOR_DIRINFO_STALE", "TOR_NOHOP0", "TOR_NONET_ACTIVITY"
|
||||
};
|
||||
|
||||
private final LinkedHashMap<String, String> lhmCLIOptions;
|
||||
private final LinkedHashMap<String, String> lhmTorrcOptions;
|
||||
private final String strClientLocation;
|
||||
private final String strConfigFolder;
|
||||
private String strSecret;
|
||||
private String strCachedDataFolder;
|
||||
private String invCommas = "\"";
|
||||
private String strExternalArgs = "";
|
||||
private String strBridges = "";
|
||||
private int intListenPort;
|
||||
private int intInitialBootEvent;
|
||||
private int loglev = LOG_NOTICE;
|
||||
private float version = 9999;
|
||||
private int maxlines = 50;
|
||||
private int nolines;
|
||||
private JTextArea jtxtstdout;
|
||||
private boolean boolSilentBoot;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param clientpath Path to Tor client
|
||||
* @param configfolder Filepath to torrc
|
||||
*/
|
||||
public TorProcess(String clientpath, String configfolder) {
|
||||
setSilentBootEnabled(false);
|
||||
strClientLocation = clientpath;
|
||||
this.intInitialBootEvent = TOR_BOOTED;
|
||||
this.strConfigFolder = configfolder;
|
||||
this.lhmCLIOptions = new LinkedHashMap<>();
|
||||
this.lhmTorrcOptions = new LinkedHashMap<>();
|
||||
// All our initialisation
|
||||
if (SimpleFile.getSeparator().compareTo("/") == 0) {
|
||||
this.invCommas = "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts Tor process, and issues booted event on completion
|
||||
*
|
||||
*/
|
||||
public final void startProcess() {
|
||||
setStartupTimeout(60);
|
||||
// Cache age check
|
||||
float age = getCacheAge();
|
||||
Logger.getGlobal().logp(Level.INFO, TorProcess.class.getName(),
|
||||
"start() on Port=" + getListenPort(), "Cache age = " + (int) age + " minutes.");
|
||||
if (age > 180) {
|
||||
deleteCacheData();
|
||||
Logger.getGlobal().logp(Level.INFO, TorProcess.class.getName(),
|
||||
"start() on Port=" + getListenPort(), "Cache stale, deleting old cache data.");
|
||||
}
|
||||
// Some essential initialisation
|
||||
String strConfig = strClientLocation
|
||||
+ " -f " + invCommas
|
||||
+ getConfigFilePath()
|
||||
+ invCommas
|
||||
+ " " + getCLIOptionsAsString()
|
||||
+ " " + strExternalArgs;
|
||||
Logger.getGlobal().logp(Level.INFO, TorProcess.class.getName(),
|
||||
"start() on Port=" + getListenPort(),
|
||||
"INFO: starting with " + strConfig );
|
||||
super.start(strConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Tor stdout log level
|
||||
*
|
||||
* @param lev
|
||||
*/
|
||||
public final void setLogLevel(int lev) {
|
||||
loglev = lev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set external user provided startup arguments
|
||||
*
|
||||
* @param torargs
|
||||
*/
|
||||
public final void setExternalArgs(String torargs) {
|
||||
strExternalArgs = torargs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the listening port
|
||||
*
|
||||
* @param port
|
||||
*/
|
||||
public final void setListenPort(int port) {
|
||||
// Setup listening port and control port
|
||||
if (intListenPort == port) {
|
||||
return;
|
||||
}
|
||||
intListenPort = port;
|
||||
setCLIOption("SocksPort", "127.0.0.1:" + String.valueOf(port));
|
||||
setCLIOption("ControlSocket", "/run/tor/control");
|
||||
setCLIOption("ControlPort", "127.0.0.1:" + String.valueOf(port + 1));
|
||||
// Finish of by creating the default config file and data folders
|
||||
createDataFolder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the event that is issued on process boot completion
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
public final void setInitialBootEvent(int event) {
|
||||
intInitialBootEvent = event;
|
||||
}
|
||||
|
||||
/**
|
||||
* Client event handler, can be overriden by parent class
|
||||
*
|
||||
* @param data line data from standard output of Tor client
|
||||
*/
|
||||
@Override
|
||||
public final void clientProcessEventFired(String data) {
|
||||
|
||||
Logger.getGlobal().logp(Level.FINER, TorProcess.class.getName(),
|
||||
"clientProcessEventFired() on Port=" + getListenPort(), data);
|
||||
|
||||
if (!data.isEmpty()) {
|
||||
appendStdout(data);
|
||||
}
|
||||
|
||||
// Check for process stopped
|
||||
if (getClientStatus() == CLIENT_STOPPED) {
|
||||
torProcessEventFired(TOR_STOPPED, null);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for timeout
|
||||
if (getClientStatus() == CLIENT_TIMEDOUT) {
|
||||
torProcessEventFired(TOR_BOOT_TIMEOUT, null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (getClientStatus() == CLIENT_RUNNING) {
|
||||
// Check to see if we need to copy cache
|
||||
if (strCachedDataFolder != null) {
|
||||
SimpleFile.copyFolderContents(strCachedDataFolder, getDataFolder() + SimpleFile.getSeparator(), "torrc");
|
||||
strCachedDataFolder = null;
|
||||
}
|
||||
// Check for fatal tor process startup errors
|
||||
if (data.contains("[warn] Our clock")) {
|
||||
torProcessEventFired(TOR_CLOCK_ERROR, data);
|
||||
return;
|
||||
}
|
||||
// Check for errors
|
||||
if (data.contains("exception") || data.contains("[err]")) {
|
||||
torProcessEventFired(TOR_BOOT_FATAL, data);
|
||||
return;
|
||||
}
|
||||
// Check for network unreachable
|
||||
if (data.contains("NOROUTE")) {
|
||||
torProcessEventFired(TOR_NOROUTE, data);
|
||||
return;
|
||||
}
|
||||
// Check new tor bridge
|
||||
if (data.contains("[notice] new bridge")) {
|
||||
torProcessEventFired(TOR_BRIDGE, data);
|
||||
return;
|
||||
}
|
||||
// Check for conditions that may prevent circuit building
|
||||
if (data.contains("directory information is no longer up-to-date")) {
|
||||
torProcessEventFired(TOR_DIRINFO_STALE, data);
|
||||
return;
|
||||
}
|
||||
// Check for conditions that will prevent circuit building
|
||||
if (data.contains("All routers are down")) {
|
||||
torProcessEventFired(TOR_NOEXITS, data);
|
||||
return;
|
||||
}
|
||||
// Check for Tor retrying on new circuit
|
||||
if (data.contains("Retrying on a new circuit")) {
|
||||
torProcessEventFired(TOR_NEWCIRC, data);
|
||||
return;
|
||||
}
|
||||
// Check for Tor failed to find hop zero
|
||||
if (data.contains("Failed to find node for hop 0")) {
|
||||
torProcessEventFired(TOR_NOHOP0, data);
|
||||
return;
|
||||
}
|
||||
// Check for no net activity
|
||||
if (data.contains("Tor has not observed any network activity")) {
|
||||
torProcessEventFired(TOR_NONET_ACTIVITY, data);
|
||||
return;
|
||||
}
|
||||
// Check for a bootstrap message
|
||||
if (data.contains("Bootstrapped")) {
|
||||
// If silent then dont fire bootstrapping messages
|
||||
if (!boolSilentBoot) {
|
||||
torProcessEventFired(TOR_MESSAGE, data.substring(data.indexOf(']') + 2));
|
||||
}
|
||||
int percent = getPercentage(data);
|
||||
// Set startup timeout based on percentage of Tor progression
|
||||
if (percent >= 15) {
|
||||
setStartupTimeout(60);
|
||||
}
|
||||
if (percent >= 40) {
|
||||
setStartupTimeout(120);
|
||||
}
|
||||
if (percent >= 80) {
|
||||
setStartupTimeout(30);
|
||||
}
|
||||
// Check for initial bootup completion
|
||||
if (percent >= 100) {
|
||||
setStartupTimeout(-1);
|
||||
torProcessEventFired(intInitialBootEvent, null);
|
||||
intInitialBootEvent = TOR_BOOTED;
|
||||
setSilentBootEnabled(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get percentage value from bootstrap message
|
||||
*
|
||||
* @param data
|
||||
* @return percentage as and int
|
||||
*/
|
||||
private int getPercentage(String data) {
|
||||
int result = -1;
|
||||
int idx1 = data.indexOf("Bootstrapped ");
|
||||
if (idx1 > -1) {
|
||||
idx1 += 13;
|
||||
int idx2 = data.indexOf('%', idx1);
|
||||
if (idx2 > -1) {
|
||||
String temp = data.substring(idx1, idx2);
|
||||
result = Integer.parseInt(temp);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/Disable bootstrap message events on startup
|
||||
*
|
||||
* @param enabled
|
||||
*/
|
||||
public final void setSilentBootEnabled(boolean enabled) {
|
||||
boolSilentBoot = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get textual representation on an event
|
||||
*
|
||||
* @param event
|
||||
* @return Event as text
|
||||
*/
|
||||
public String getEventMessage(int event) {
|
||||
return EVENTMESSAGES[event];
|
||||
}
|
||||
|
||||
/**
|
||||
* Called if an event was fired, will be overidden by sub class
|
||||
*
|
||||
* @param event
|
||||
* @param data
|
||||
*/
|
||||
public void torProcessEventFired(int event, String data) {
|
||||
}
|
||||
|
||||
public final void setControlPassword(String secret, String hashpass) {
|
||||
strSecret = secret;
|
||||
setCLIOption("hashedcontrolpassword", hashpass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the currently set authentification secret
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public final String getSecret() {
|
||||
return strSecret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Tor bridges, supports multiple addresses
|
||||
*
|
||||
* @param bridges
|
||||
*/
|
||||
public final void setBridges(String bridges) {
|
||||
|
||||
clearCLIOption("UseBridges");
|
||||
clearCLIOption("Bridge");
|
||||
clearCLIOption("UpdateBridgesFromAuthority");
|
||||
strBridges = "";
|
||||
if (bridges == null || bridges.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
StringBuilder sbBridgesOption = new StringBuilder();
|
||||
String sep = "";
|
||||
String[] arrBridges = Pattern.compile(",").split(bridges);
|
||||
for (String s : arrBridges) {
|
||||
sbBridgesOption.append(sep);
|
||||
sbBridgesOption.append(s);
|
||||
if (sep.isEmpty()) {
|
||||
sep = " --Bridge ";
|
||||
}
|
||||
}
|
||||
strBridges = bridges;
|
||||
setCLIOption("UseBridges", "1");
|
||||
setCLIOption("UpdateBridgesFromAuthority", "1");
|
||||
setCLIOption("Bridge", sbBridgesOption.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate bridge addresses
|
||||
*
|
||||
* @param bridges
|
||||
* @return true if valid
|
||||
*/
|
||||
public boolean validateBridges(String bridges) {
|
||||
if (bridges.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
String[] arrBridges = Pattern.compile(",").split(bridges);
|
||||
for (String s : arrBridges) {
|
||||
if (!validateHostPort(s)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a host:port ipv4 address
|
||||
*
|
||||
* @param hostport
|
||||
* @return true if valid
|
||||
*/
|
||||
public final boolean validateHostPort(String hostport) {
|
||||
|
||||
try {
|
||||
URI uri = new URI("my://" + hostport); // may throw URISyntaxException
|
||||
if (uri.getHost() == null || uri.getPort() == -1) {
|
||||
return false;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get bridges
|
||||
*
|
||||
* @return bridges as csv string
|
||||
*/
|
||||
public final String getBridges() {
|
||||
return strBridges;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Ownership process id, useful for proper process termination in event
|
||||
* of a crash
|
||||
*
|
||||
* @param processid
|
||||
*/
|
||||
public void setOwnershipID(String processid) {
|
||||
this.setCLIOption("__OwningControllerProcess", processid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the currently set process ownership ID
|
||||
*
|
||||
* @return String process id
|
||||
*/
|
||||
public String getOwnershipID() {
|
||||
return getCLIOptions("__OwningControllerProcess");
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the path to the geoip file
|
||||
*
|
||||
* @param filepath File location
|
||||
*/
|
||||
public final void setGeoIP4(String filepath) {
|
||||
if (filepath != null) {
|
||||
if (SimpleFile.exists(filepath)) {
|
||||
setTorrcOption("GeoIPFile", invCommas + filepath + invCommas);
|
||||
} else {
|
||||
clearTorrcOption("GeoIPFile");
|
||||
}
|
||||
} else {
|
||||
clearTorrcOption("GeoIPFile");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the path to the geoip file
|
||||
*
|
||||
* @param filepath File location
|
||||
*/
|
||||
public final void setGeoIP6(String filepath) {
|
||||
if (filepath != null) {
|
||||
if (SimpleFile.exists(filepath)) {
|
||||
setTorrcOption("GeoIPv6File", invCommas + filepath + invCommas);
|
||||
} else {
|
||||
clearTorrcOption("GeoIPv6File");
|
||||
}
|
||||
} else {
|
||||
clearTorrcOption("GeoIPv6File");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Tor client location as a filepath
|
||||
*
|
||||
* @return filepath as string
|
||||
*/
|
||||
public final String getClientLocation() {
|
||||
return strClientLocation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the path to the configuration file
|
||||
*
|
||||
* @return String Path to configuration file
|
||||
*/
|
||||
public final String getConfigFilePath() {
|
||||
return getDataFolder() + File.separator + TORCONFIGFILE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a previously added tor option string
|
||||
*
|
||||
* @param option Tor option key
|
||||
* @return String Tor option value
|
||||
*/
|
||||
public final String getCLIOptions(String option) {
|
||||
return lhmCLIOptions.get(option);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a tor option string which is passed to the tor client on startup. See
|
||||
* Tor documentation for valid options.
|
||||
*
|
||||
* @param option
|
||||
* @param value
|
||||
*/
|
||||
public final void setCLIOption(String option, String value) {
|
||||
lhmCLIOptions.put(option, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a tor option boolean value
|
||||
*
|
||||
* @param option
|
||||
* @param value
|
||||
*/
|
||||
public final void setBoolTorOption(String option, boolean value) {
|
||||
lhmCLIOptions.remove(option);
|
||||
if (value) {
|
||||
lhmCLIOptions.put(option, "1");
|
||||
} else {
|
||||
lhmCLIOptions.put(option, "0");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a previously added tor option string
|
||||
*
|
||||
* @param option Tor option key
|
||||
* @return String Tor option value
|
||||
*/
|
||||
public final String getTorrcOption(String option) {
|
||||
return lhmTorrcOptions.get(option);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a torrc option string See Tor documentation for valid options.
|
||||
*
|
||||
* @param option
|
||||
* @param value
|
||||
*/
|
||||
public final void setTorrcOption(String option, String value) {
|
||||
if (value.startsWith("\"")) {
|
||||
value = value.replace('\\', '/');
|
||||
}
|
||||
lhmTorrcOptions.put(option, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the currently set torrc options as single String
|
||||
*
|
||||
* @return String Tor client formatted cli arguments
|
||||
*/
|
||||
public final String getTorrcOptionsAsString() {
|
||||
Iterator<String> iterator = lhmTorrcOptions.keySet().iterator();
|
||||
String key;
|
||||
StringBuilder sbResult = new StringBuilder();
|
||||
while (iterator.hasNext()) {
|
||||
key = iterator.next();
|
||||
sbResult.append(key);
|
||||
sbResult.append(" ");
|
||||
sbResult.append(lhmTorrcOptions.get(key));
|
||||
sbResult.append("\r\n");
|
||||
}
|
||||
return sbResult.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove previously add torrc option
|
||||
*
|
||||
* @param option
|
||||
*/
|
||||
public final void clearTorrcOption(String option) {
|
||||
lhmTorrcOptions.remove(option);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a previously added tor option boolean value
|
||||
*
|
||||
* @param option Tor option key
|
||||
* @return Boolean value
|
||||
*/
|
||||
public final boolean getCLIOptionBool(String option) {
|
||||
return lhmCLIOptions.get(option).contentEquals("1");
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove previously add tor option
|
||||
*
|
||||
* @param option
|
||||
*/
|
||||
public final void clearCLIOption(String option) {
|
||||
lhmCLIOptions.remove(option);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the currently set tor options as single String for use as
|
||||
* arguments passed to tor client
|
||||
*
|
||||
* @return String Tor cleint formatted cli arguments
|
||||
*/
|
||||
public final String getCLIOptionsAsString() {
|
||||
Iterator<String> iterator = lhmCLIOptions.keySet().iterator();
|
||||
String key;
|
||||
String value;
|
||||
StringBuilder sbResult = new StringBuilder();
|
||||
while (iterator.hasNext()) {
|
||||
key = iterator.next();
|
||||
sbResult.append("--");
|
||||
sbResult.append(key);
|
||||
sbResult.append(" ");
|
||||
value = lhmCLIOptions.get(key);
|
||||
if (!value.isEmpty()) {
|
||||
sbResult.append(value);
|
||||
sbResult.append(" ");
|
||||
}
|
||||
}
|
||||
return sbResult.toString().trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the listening port
|
||||
*
|
||||
* @return port
|
||||
*/
|
||||
public final int getListenPort() {
|
||||
return intListenPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the control port
|
||||
*
|
||||
* @return port
|
||||
*/
|
||||
public final int getControlPort() {
|
||||
return intListenPort + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the default Tor config file
|
||||
*/
|
||||
public final void createDefaultConfig() {
|
||||
SimpleFile sfTorrc = new SimpleFile(getConfigFilePath());
|
||||
sfTorrc.openBufferedWrite();
|
||||
sfTorrc.writeFile(getTorrcOptionsAsString(), 0);
|
||||
switch (loglev) {
|
||||
case LOG_DEBUG:
|
||||
sfTorrc.writeFile("log debug stdout", 1);
|
||||
break;
|
||||
case LOG_INFO:
|
||||
sfTorrc.writeFile("log info stdout", 1);
|
||||
break;
|
||||
case LOG_NOTICE:
|
||||
sfTorrc.writeFile("log notice stdout", 1);
|
||||
break;
|
||||
}
|
||||
|
||||
sfTorrc.writeFile(EMPTYSTRING, 1);
|
||||
sfTorrc.closeFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the configuration file
|
||||
*/
|
||||
public final void deleteConfigFile() {
|
||||
SimpleFile.delete(getConfigFilePath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a data folder for the Tor client to put its cache data
|
||||
*/
|
||||
public final void createDataFolder() {
|
||||
String folder = getDataFolder();
|
||||
if (folder != null) {
|
||||
setTorrcOption("DataDirectory", invCommas + getDataFolder() + invCommas);
|
||||
SimpleFile.createFolder(getDataFolder());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the datafolder being used by tor client
|
||||
*
|
||||
* @return Path to datafolder
|
||||
*/
|
||||
public final String getDataFolder() {
|
||||
if (strConfigFolder == null) {
|
||||
return null;
|
||||
}
|
||||
return strConfigFolder + String.valueOf(intListenPort);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the age of the file cache in minutes
|
||||
*
|
||||
* @return age of cache in minutes
|
||||
*/
|
||||
public float getCacheAge() {
|
||||
|
||||
String path = getDataFolder() + SimpleFile.getSeparator()
|
||||
+ "cached-consensus";
|
||||
if (SimpleFile.exists(path)) {
|
||||
return SimpleFile.getAgeOfFile(path, SimpleFile.PERIOD_MINUTES);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete Tor cache data
|
||||
*/
|
||||
public final void deleteCacheData() {
|
||||
SimpleFile.secureWipe(getDataFolder() + SimpleFile.getSeparator() + "cached-consensus");
|
||||
SimpleFile.secureWipe(getDataFolder() + SimpleFile.getSeparator() + "cached-certs");
|
||||
SimpleFile.secureWipe(getDataFolder() + SimpleFile.getSeparator() + "cached-descriptors");
|
||||
SimpleFile.secureWipe(getDataFolder() + SimpleFile.getSeparator() + "cached-descriptors.new");
|
||||
SimpleFile.secureWipe(getDataFolder() + SimpleFile.getSeparator() + "lock");
|
||||
SimpleFile.secureWipe(getDataFolder() + SimpleFile.getSeparator() + "state");
|
||||
}
|
||||
|
||||
/**
|
||||
* This populates the the current folder whose name is derived from the
|
||||
* listening port with data from the given source folder derived by the
|
||||
* given port number. This effectively allows each Tor client spawned to
|
||||
* have its Tor cache data copied from the first Tor client launched instead
|
||||
* of having to go to the net and fetch it and thus start up is a lot
|
||||
* faster. I was actually mildly suprised that this actually works.
|
||||
*
|
||||
* @param port
|
||||
*/
|
||||
public final void setCachedDataFolder(int port) {
|
||||
if (port < 0) {
|
||||
strCachedDataFolder = null;
|
||||
return;
|
||||
}
|
||||
strCachedDataFolder = strConfigFolder + String.valueOf(port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the currently set cached data folder
|
||||
*
|
||||
* @return path to cached data folder as String
|
||||
*/
|
||||
public final String getCachedDataFolder() {
|
||||
return strCachedDataFolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the text area that will receive Stdout output
|
||||
*
|
||||
* @param jta
|
||||
*/
|
||||
public void setStdoutTextArea(JTextArea jta) {
|
||||
jtxtstdout = jta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the maximum no of lines to display in the Stdout output
|
||||
*
|
||||
* @param lines
|
||||
*/
|
||||
public void setMaxHistory(int lines) {
|
||||
maxlines = lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the Stdout text area
|
||||
*/
|
||||
public void clearStdout() {
|
||||
if (jtxtstdout != null) {
|
||||
jtxtstdout.setText("");
|
||||
}
|
||||
nolines = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append text to the StdOut text area
|
||||
*
|
||||
* @param text
|
||||
*/
|
||||
private void appendStdout(String text) {
|
||||
if (jtxtstdout == null) {
|
||||
return;
|
||||
}
|
||||
jtxtstdout.append(text + "\n");
|
||||
if (++nolines > maxlines) {
|
||||
try {
|
||||
int end = jtxtstdout.getLineEndOffset(0);
|
||||
jtxtstdout.replaceRange("", 0, end);
|
||||
} catch (BadLocationException ex) {
|
||||
}
|
||||
}
|
||||
jtxtstdout.setCaretPosition(jtxtstdout.getText().length());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Tor version as float
|
||||
*
|
||||
* @return Tor version as String
|
||||
*/
|
||||
public final float getVersion() {
|
||||
if (version == 9999) {
|
||||
BufferedReader br;
|
||||
String strVer = "";
|
||||
Process proc;
|
||||
try {
|
||||
proc = Runtime.getRuntime().exec(strClientLocation + " --version");
|
||||
br = new BufferedReader(new InputStreamReader(proc.getInputStream()), 256);
|
||||
String line;
|
||||
while (true) {
|
||||
line = br.readLine();
|
||||
if (line == null) {
|
||||
break;
|
||||
}
|
||||
strVer = line;
|
||||
}
|
||||
br.close();
|
||||
proc.destroy();
|
||||
proc.waitFor();
|
||||
} catch (IOException | InterruptedException ex) {
|
||||
Logger.getLogger(TorProcess.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
int idx = strVer.indexOf("ion");
|
||||
if (idx > -1) {
|
||||
strVer = strVer.substring(idx + 4).replace(".", "");
|
||||
idx = strVer.indexOf(' ');
|
||||
if (idx > -1) {
|
||||
strVer = strVer.substring(0, idx);
|
||||
}
|
||||
try {
|
||||
version = Float.parseFloat("0." + strVer) * 10;
|
||||
} catch (Exception ex) {
|
||||
Logger.getGlobal().logp(Level.SEVERE, this.getClass().getName(), "getVersion() Port=" + intListenPort, "", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
}
|
135
src/lib/AboutDialog.form
Normal file
135
src/lib/AboutDialog.form
Normal file
|
@ -0,0 +1,135 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.5" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
|
||||
<Properties>
|
||||
<Property name="defaultCloseOperation" type="int" value="2"/>
|
||||
<Property name="title" type="java.lang.String" value="Title"/>
|
||||
<Property name="resizable" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<SyntheticProperties>
|
||||
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
|
||||
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
|
||||
</SyntheticProperties>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jPanel1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jPanel1" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="jPanel1">
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="jButtonVisit" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jButtonContact" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="jButtonClose" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="jLabelAppLogo" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jTextAreaVersion" min="-2" pref="183" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||
<Component id="jLabelAppLogo" max="32767" attributes="3"/>
|
||||
<Component id="jTextAreaVersion" max="32767" attributes="3"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="2" attributes="0">
|
||||
<Component id="jButtonVisit" alignment="2" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jButtonContact" alignment="2" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jButtonClose" alignment="2" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JButton" name="jButtonVisit">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Visit Us"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButtonVisitActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="jButtonContact">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Contact Us"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButtonContactActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="jButtonClose">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Close"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButtonCloseActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabelAppLogo">
|
||||
<Properties>
|
||||
<Property name="verticalAlignment" type="int" value="1"/>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[128, 128]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextArea" name="jTextAreaVersion">
|
||||
<Properties>
|
||||
<Property name="editable" type="boolean" value="false"/>
|
||||
<Property name="columns" type="int" value="15"/>
|
||||
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection component="jPanel1" name="foreground" type="property"/>
|
||||
</Property>
|
||||
<Property name="lineWrap" type="boolean" value="true"/>
|
||||
<Property name="rows" type="int" value="5"/>
|
||||
<Property name="wrapStyleWord" type="boolean" value="true"/>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="null"/>
|
||||
</Property>
|
||||
<Property name="focusable" type="boolean" value="false"/>
|
||||
<Property name="opaque" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
233
src/lib/AboutDialog.java
Normal file
233
src/lib/AboutDialog.java
Normal file
|
@ -0,0 +1,233 @@
|
|||
/*
|
||||
* 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 lib;
|
||||
|
||||
import java.awt.Image;
|
||||
import javax.swing.ImageIcon;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alistair Neil, <info@dazzleships.net>
|
||||
*/
|
||||
public class AboutDialog extends javax.swing.JDialog {
|
||||
|
||||
private String strHome = null;
|
||||
private String strContact = null;
|
||||
|
||||
/**
|
||||
* Creates new About Dialog
|
||||
*
|
||||
* @param parent
|
||||
* @param modal
|
||||
*/
|
||||
public AboutDialog(java.awt.Frame parent, boolean modal) {
|
||||
super(parent, modal);
|
||||
initComponents();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set appliction description
|
||||
*
|
||||
* @param text
|
||||
*/
|
||||
public void setAppDescription(String text) {
|
||||
jTextAreaVersion.setText(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set application logo
|
||||
*
|
||||
* @param ii
|
||||
*/
|
||||
public void setAppLogo(ImageIcon ii) {
|
||||
Image im = ii.getImage().getScaledInstance(jLabelAppLogo.getWidth(), jLabelAppLogo.getHeight(), Image.SCALE_SMOOTH);
|
||||
ii.setImage(im);
|
||||
jLabelAppLogo.setIcon(ii);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set home url
|
||||
*
|
||||
* @param home
|
||||
*/
|
||||
public void setHomeURL(String home) {
|
||||
strHome = home;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set contact url
|
||||
*
|
||||
* @param contact
|
||||
*/
|
||||
public void setContactURL(String contact) {
|
||||
strContact = contact;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set text on Contact button
|
||||
*
|
||||
* @param text
|
||||
*/
|
||||
public void setButtonContactText(String text) {
|
||||
jButtonContact.setText(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set text on Visit button
|
||||
*
|
||||
* @param text
|
||||
*/
|
||||
public void setButtonVisitText(String text) {
|
||||
jButtonVisit.setText(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set text on Close button
|
||||
*
|
||||
* @param text
|
||||
*/
|
||||
public void setButtonCloseText(String text) {
|
||||
jButtonClose.setText(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
|
||||
jPanel1 = new javax.swing.JPanel();
|
||||
jButtonVisit = new javax.swing.JButton();
|
||||
jButtonContact = new javax.swing.JButton();
|
||||
jButtonClose = new javax.swing.JButton();
|
||||
jLabelAppLogo = new javax.swing.JLabel();
|
||||
jTextAreaVersion = new javax.swing.JTextArea();
|
||||
|
||||
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
|
||||
setTitle("Title");
|
||||
setResizable(false);
|
||||
|
||||
jButtonVisit.setText("Visit Us");
|
||||
jButtonVisit.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
jButtonVisitActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jButtonContact.setText("Contact Us");
|
||||
jButtonContact.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
jButtonContactActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jButtonClose.setText("Close");
|
||||
jButtonClose.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
jButtonCloseActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jLabelAppLogo.setVerticalAlignment(javax.swing.SwingConstants.TOP);
|
||||
jLabelAppLogo.setPreferredSize(new java.awt.Dimension(128, 128));
|
||||
|
||||
jTextAreaVersion.setEditable(false);
|
||||
jTextAreaVersion.setColumns(15);
|
||||
jTextAreaVersion.setForeground(jPanel1.getForeground());
|
||||
jTextAreaVersion.setLineWrap(true);
|
||||
jTextAreaVersion.setRows(5);
|
||||
jTextAreaVersion.setWrapStyleWord(true);
|
||||
jTextAreaVersion.setBorder(null);
|
||||
jTextAreaVersion.setFocusable(false);
|
||||
jTextAreaVersion.setOpaque(false);
|
||||
|
||||
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
|
||||
jPanel1.setLayout(jPanel1Layout);
|
||||
jPanel1Layout.setHorizontalGroup(
|
||||
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||
.addComponent(jButtonVisit)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jButtonContact)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(jButtonClose))
|
||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||
.addComponent(jLabelAppLogo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jTextAreaVersion, javax.swing.GroupLayout.PREFERRED_SIZE, 183, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
);
|
||||
jPanel1Layout.setVerticalGroup(
|
||||
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||
.addComponent(jLabelAppLogo, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(jTextAreaVersion))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
|
||||
.addComponent(jButtonVisit)
|
||||
.addComponent(jButtonContact)
|
||||
.addComponent(jButtonClose)))
|
||||
);
|
||||
|
||||
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()
|
||||
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
pack();
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void jButtonVisitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonVisitActionPerformed
|
||||
if (strHome != null) {
|
||||
Utilities.openFileExternally(strHome);
|
||||
}
|
||||
}//GEN-LAST:event_jButtonVisitActionPerformed
|
||||
|
||||
private void jButtonContactActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonContactActionPerformed
|
||||
if (strContact != null) {
|
||||
Utilities.openFileExternally(strContact);
|
||||
}
|
||||
}//GEN-LAST:event_jButtonContactActionPerformed
|
||||
|
||||
private void jButtonCloseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonCloseActionPerformed
|
||||
dispose();
|
||||
}//GEN-LAST:event_jButtonCloseActionPerformed
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton jButtonClose;
|
||||
private javax.swing.JButton jButtonContact;
|
||||
private javax.swing.JButton jButtonVisit;
|
||||
private javax.swing.JLabel jLabelAppLogo;
|
||||
private javax.swing.JPanel jPanel1;
|
||||
private javax.swing.JTextArea jTextAreaVersion;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
233
src/lib/ClientProcess.java
Normal file
233
src/lib/ClientProcess.java
Normal file
|
@ -0,0 +1,233 @@
|
|||
/*
|
||||
* 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 lib;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.SwingWorker;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alistair Neil <info@dazzleships.net>
|
||||
*/
|
||||
public class ClientProcess {
|
||||
|
||||
public static final int CLIENT_STOPPED = 0;
|
||||
public static final int CLIENT_RUNNING = 1;
|
||||
public static final int CLIENT_TIMEDOUT = 2;
|
||||
private long initialdelay = 0;
|
||||
private volatile long startupTimeout;
|
||||
private SwingWorker<ArrayList<String>, String> swWorker;
|
||||
private volatile Process procApplication;
|
||||
private PrintWriter pwWriter;
|
||||
private volatile Thread threadSleep;
|
||||
private int intStatus = CLIENT_STOPPED;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public ClientProcess() {
|
||||
setStartupTimeout(15);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the initial delay that is executed prior to starting the process
|
||||
*
|
||||
* @param ms
|
||||
*/
|
||||
public final void setStartupDelay(long ms) {
|
||||
initialdelay = ms;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set startup timeout
|
||||
*
|
||||
* @param seconds
|
||||
*/
|
||||
public final void setStartupTimeout(long seconds) {
|
||||
startupTimeout = seconds * 1000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the client process
|
||||
*
|
||||
* @param processpath
|
||||
*/
|
||||
public final void start(final String processpath) {
|
||||
swWorker = new SwingWorker<ArrayList<String>, String>() {
|
||||
|
||||
String line;
|
||||
int endstatus;
|
||||
|
||||
@Override
|
||||
protected ArrayList<String> doInBackground() {
|
||||
BufferedReader brProcInput = null;
|
||||
BufferedReader brProcError = null;
|
||||
try {
|
||||
endstatus = CLIENT_STOPPED;
|
||||
if (isCancelled()) {
|
||||
return null;
|
||||
}
|
||||
threadSleep = Thread.currentThread();
|
||||
if (initialdelay > 0) {
|
||||
try {
|
||||
Thread.sleep(initialdelay);
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
}
|
||||
threadSleep = null;
|
||||
initialdelay = 0;
|
||||
if (isCancelled()) {
|
||||
return null;
|
||||
}
|
||||
procApplication = Runtime.getRuntime().exec(processpath);
|
||||
if (procApplication == null) {
|
||||
return null;
|
||||
}
|
||||
brProcInput = new BufferedReader(new InputStreamReader(procApplication.getInputStream()), 512);
|
||||
brProcError = new BufferedReader(new InputStreamReader(procApplication.getErrorStream()), 512);
|
||||
pwWriter = new PrintWriter(procApplication.getOutputStream());
|
||||
long timeout = System.currentTimeMillis() + startupTimeout;
|
||||
while (!isCancelled()) {
|
||||
if (brProcInput.ready()) {
|
||||
timeout = System.currentTimeMillis() + startupTimeout;
|
||||
// Read process notifications
|
||||
line = brProcInput.readLine();
|
||||
publish(line);
|
||||
}
|
||||
if (brProcError.ready()) {
|
||||
timeout = System.currentTimeMillis() + startupTimeout;
|
||||
// Read process notifications
|
||||
line = brProcError.readLine();
|
||||
publish(line);
|
||||
}
|
||||
if (System.currentTimeMillis() > timeout && startupTimeout > 0) {
|
||||
endstatus = CLIENT_TIMEDOUT;
|
||||
break;
|
||||
}
|
||||
threadSleep = Thread.currentThread();
|
||||
try {
|
||||
Thread.sleep(20);
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
threadSleep = null;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Logger.getGlobal().logp(Level.INFO, ClientProcess.class.getName(),
|
||||
"SwingWorker Loop Exception", ex.getMessage());
|
||||
} finally {
|
||||
// Cleanup resources
|
||||
try {
|
||||
if (brProcInput != null) {
|
||||
brProcInput.close();
|
||||
}
|
||||
if (brProcError != null) {
|
||||
brProcError.close();
|
||||
}
|
||||
pwWriter.close();
|
||||
// Destroy process
|
||||
if (procApplication != null) {
|
||||
procApplication.getOutputStream().close();
|
||||
procApplication.getInputStream().close();
|
||||
procApplication.getErrorStream().close();
|
||||
procApplication.destroy();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Logger.getGlobal().logp(Level.INFO, ClientProcess.class.getName(),
|
||||
"SwingWorker Cleanup", ex.getMessage());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void process(List<String> chunks) {
|
||||
for (String s : chunks) {
|
||||
if (s != null) {
|
||||
clientProcessEventFired(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void done() {
|
||||
intStatus = endstatus;
|
||||
clientProcessEventFired("");
|
||||
}
|
||||
|
||||
};
|
||||
intStatus = CLIENT_RUNNING;
|
||||
clientProcessEventFired("");
|
||||
// Start client process
|
||||
swWorker.execute();
|
||||
}
|
||||
|
||||
public final int getClientStatus() {
|
||||
return intStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the client system process
|
||||
*
|
||||
* @return a process
|
||||
*/
|
||||
public final Process getProcess() {
|
||||
return procApplication;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the client process
|
||||
*
|
||||
*/
|
||||
public final void stopProcess() {
|
||||
if (threadSleep != null) {
|
||||
threadSleep.interrupt();
|
||||
}
|
||||
if (swWorker != null) {
|
||||
swWorker.cancel(true);
|
||||
}
|
||||
try {
|
||||
procApplication.waitFor();
|
||||
} catch (Exception ex) {
|
||||
Logger.getGlobal().logp(Level.INFO, ClientProcess.class.getName(),
|
||||
"stopProcess", ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message to the process
|
||||
*
|
||||
* @param message
|
||||
*/
|
||||
public final void sendMessage(String message) {
|
||||
pwWriter.write(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Event from the process, should be overriden by sub class
|
||||
*
|
||||
* @param data
|
||||
*/
|
||||
public void clientProcessEventFired(String data) {
|
||||
}
|
||||
}
|
120
src/lib/DesktopNotify.java
Normal file
120
src/lib/DesktopNotify.java
Normal file
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* 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 lib;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* This class handles desktop notifications
|
||||
*
|
||||
* @author Alistair Neil <info@dazzleships.net>
|
||||
*/
|
||||
public class DesktopNotify {
|
||||
|
||||
private final String iconpath;
|
||||
private String notifytitle;
|
||||
private String notifybody;
|
||||
private String notifysendpath;
|
||||
private final SwingTrayIcon sti;
|
||||
private boolean enabled;
|
||||
private boolean supported = true;
|
||||
|
||||
public DesktopNotify(SwingTrayIcon sti, String iconpath) {
|
||||
this.sti = sti;
|
||||
this.iconpath = iconpath;
|
||||
if (OSFunction.isLinux()) {
|
||||
this.notifysendpath = OSFunction.findFile("notify-send", "/usr/bin/");
|
||||
if (this.notifysendpath == null) {
|
||||
Logger.getGlobal().log(Level.WARNING, "notify-send not found.");
|
||||
this.supported = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is notifications supported
|
||||
*
|
||||
* @return true if supported
|
||||
*/
|
||||
public boolean isSupported() {
|
||||
return supported;
|
||||
}
|
||||
|
||||
/**
|
||||
* Are notifications enabled
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable/Enable notifications
|
||||
*
|
||||
* @param enabled
|
||||
*/
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set desktop notification title
|
||||
*
|
||||
* @param text
|
||||
*/
|
||||
public void setNotificationTitle(String text) {
|
||||
notifytitle = text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set desktop notification body
|
||||
*
|
||||
* @param text
|
||||
*/
|
||||
public void setNotificationBody(String text) {
|
||||
notifybody = text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Raise a notification
|
||||
*
|
||||
*/
|
||||
public void raiseNotification() {
|
||||
if (notifybody == null || notifytitle == null || !enabled) {
|
||||
return;
|
||||
}
|
||||
if (OSFunction.isWindows()) {
|
||||
if (sti != null) {
|
||||
sti.displayMessage(notifytitle, notifybody);
|
||||
}
|
||||
} else {
|
||||
if (notifysendpath != null) {
|
||||
OSFunction.launchProcess("notify-send", "-u", "normal",
|
||||
"-i", iconpath, notifytitle, notifybody);
|
||||
}
|
||||
}
|
||||
notifybody = null;
|
||||
}
|
||||
|
||||
public String getNotifySendPath() {
|
||||
return notifysendpath;
|
||||
}
|
||||
|
||||
}
|
90
src/lib/ExtensionFileFilter.java
Normal file
90
src/lib/ExtensionFileFilter.java
Normal file
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* 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 lib;
|
||||
|
||||
import java.io.File;
|
||||
import javax.swing.filechooser.FileFilter;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alistair Neil, <info@dazzleships.net>
|
||||
* Taken from Oracle documentation.
|
||||
*/
|
||||
public class ExtensionFileFilter extends FileFilter {
|
||||
|
||||
String description;
|
||||
String extensions[];
|
||||
|
||||
/**
|
||||
* Convenience constructor for a single extension
|
||||
*
|
||||
* @param description
|
||||
* @param extension
|
||||
*/
|
||||
public ExtensionFileFilter(String description, String extension) {
|
||||
this(description, new String[]{extension});
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience constructor for a multiple extensions
|
||||
*
|
||||
* @param description
|
||||
* @param extensions
|
||||
*/
|
||||
public ExtensionFileFilter(String description, String extensions[]) {
|
||||
if (description == null) {
|
||||
this.description = extensions[0];
|
||||
} else {
|
||||
this.description = description;
|
||||
}
|
||||
this.extensions = extensions.clone();
|
||||
toLower(this.extensions);
|
||||
}
|
||||
|
||||
private void toLower(String array[]) {
|
||||
for (int i = 0, n = array.length; i < n; i++) {
|
||||
array[i] = array[i].toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get description
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(File file) {
|
||||
if (file.isDirectory()) {
|
||||
return true;
|
||||
} else {
|
||||
String path = file.getAbsolutePath().toLowerCase();
|
||||
for (int i = 0, n = extensions.length; i < n; i++) {
|
||||
String extension = extensions[i];
|
||||
if ((path.endsWith(extension) && (path.charAt(path.length() - extension.length() - 1)) == '.')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
128
src/lib/GTKFixes.java
Normal file
128
src/lib/GTKFixes.java
Normal file
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* 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 lib;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuBar;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.event.MenuEvent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alistair Neil <info@dazzleships.net>
|
||||
*/
|
||||
public class GTKFixes {
|
||||
|
||||
public static void fixMenubarHeight(JMenuBar jmb, JMenuItem jmi) {
|
||||
jmb.setPreferredSize(new Dimension(jmb.getPreferredSize().width, jmi.getPreferredSize().height));
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixes incorrect JMenu selectionForeground and selectionBackground
|
||||
* highlighting
|
||||
*
|
||||
* @param jms Array of JMenus or single JMenu
|
||||
*/
|
||||
public static void fixMenuSelectionColor(JMenu... jms) {
|
||||
// If gtk laf not installed then do nothing
|
||||
if (!UIManager.getLookAndFeel().getID().contentEquals("GTK")) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (final JMenu jm : jms) {
|
||||
final Color bgfixed = new Color(((Color) UIManager.get("Menu.selectionBackground")).getRGB());
|
||||
final Color fgfixed = new Color(((Color) UIManager.get("Menu.selectionForeground")).getRGB());
|
||||
final Color fgnormal = jm.getForeground();
|
||||
final Color bgnormal = new Color(((Color) UIManager.get("Menu.background")).getRGB());
|
||||
jm.setText(" " + jm.getText() + " ");
|
||||
jm.addMenuListener(new javax.swing.event.MenuListener() {
|
||||
|
||||
@Override
|
||||
public void menuSelected(MenuEvent e) {
|
||||
jm.setOpaque(true);
|
||||
jm.setForeground(fgfixed);
|
||||
jm.setBackground(bgfixed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void menuDeselected(MenuEvent e) {
|
||||
jm.setOpaque(false);
|
||||
jm.setForeground(fgnormal);
|
||||
jm.setBackground(bgnormal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void menuCanceled(MenuEvent e) {
|
||||
jm.setOpaque(false);
|
||||
jm.setForeground(fgnormal);
|
||||
jm.setBackground(bgnormal);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixes incorrect JMenu border outline
|
||||
*
|
||||
* @param jms Array of JMenus or single JMenu
|
||||
*/
|
||||
public static void fixJMenuPopupBorder(JMenu... jms) {
|
||||
// If gtk laf not installed then do nothing
|
||||
if (!UIManager.getLookAndFeel().getID().contentEquals("GTK")) {
|
||||
return;
|
||||
}
|
||||
for (final JMenu jm : jms) {
|
||||
jm.getPopupMenu().setBorder(BorderFactory.createLineBorder(
|
||||
new Color(UIManager.getColor("PopupMenu.background").getRGB()).darker(), 1));
|
||||
}
|
||||
}
|
||||
|
||||
public static void fixTrayMenuPopupBorder(TrayPopupMenu tpm) {
|
||||
tpm.setBorder(BorderFactory.createLineBorder(
|
||||
new Color(UIManager.getColor("PopupMenu.background").getRGB()).darker(), 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixes incorrect JMenu selectionForeground highlighting
|
||||
*
|
||||
* @param jmi Array of JMenuItems or single JMenuItem
|
||||
*/
|
||||
public static void fixMenuItemFgColor(JMenuItem... jmi) {
|
||||
// If gtk laf not installed then do nothing
|
||||
if (!UIManager.getLookAndFeel().getID().contentEquals("GTK")) {
|
||||
return;
|
||||
}
|
||||
for (final JMenuItem jm : jmi) {
|
||||
final Color fgfixed = new Color(UIManager.getColor("MenuItem.foreground").getRGB());
|
||||
jm.setForeground(fgfixed);
|
||||
}
|
||||
}
|
||||
|
||||
public static void fixTextAreaColor(JTextArea jta) {
|
||||
if (OSFunction.isLinux()) {
|
||||
jta.setForeground(UIManager.getColor("JLabel.foreground"));
|
||||
jta.setBackground(UIManager.getColor("JLabel.background"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
139
src/lib/InfoDialog.form
Normal file
139
src/lib/InfoDialog.form
Normal file
|
@ -0,0 +1,139 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.5" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
|
||||
<Properties>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[410, 165]"/>
|
||||
</Property>
|
||||
<Property name="resizable" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<SyntheticProperties>
|
||||
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
|
||||
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
|
||||
</SyntheticProperties>
|
||||
<Events>
|
||||
<EventHandler event="windowClosing" listener="java.awt.event.WindowListener" parameters="java.awt.event.WindowEvent" handler="closeDialog"/>
|
||||
</Events>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jPanelMain" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jPanelMain" max="32767" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="jPanelMain">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
|
||||
<FontInfo relative="true">
|
||||
<Font bold="true" component="jPanelMain" property="font" relativeSize="true" size="2"/>
|
||||
</FontInfo>
|
||||
</Property>
|
||||
<Property name="opaque" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jCheckBoxOption" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace pref="63" max="32767" attributes="0"/>
|
||||
<Component id="jButtonCancel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jButtonContinue" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="jScrollPane2" alignment="0" max="32767" attributes="0"/>
|
||||
<Component id="jProgressBar" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jScrollPane2" pref="304" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jProgressBar" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jCheckBoxOption" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jButtonContinue" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jButtonCancel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JButton" name="jButtonCancel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Cancel"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButtonCancelActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="jCheckBoxOption">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Disable this notification."/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="jButtonContinue">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Continue"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButtonContinueActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Container class="javax.swing.JScrollPane" name="jScrollPane2">
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTextArea" name="jTextInfo">
|
||||
<Properties>
|
||||
<Property name="editable" type="boolean" value="false"/>
|
||||
<Property name="columns" type="int" value="20"/>
|
||||
<Property name="lineWrap" type="boolean" value="true"/>
|
||||
<Property name="rows" type="int" value="5"/>
|
||||
<Property name="wrapStyleWord" type="boolean" value="true"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JProgressBar" name="jProgressBar">
|
||||
<Properties>
|
||||
<Property name="string" type="java.lang.String" value=""/>
|
||||
<Property name="stringPainted" type="boolean" value="true"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
549
src/lib/InfoDialog.java
Normal file
549
src/lib/InfoDialog.java
Normal file
|
@ -0,0 +1,549 @@
|
|||
/*
|
||||
* 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 lib;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Frame;
|
||||
import java.awt.event.ActionEvent;
|
||||
import javax.swing.JProgressBar;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.Timer;
|
||||
import javax.swing.WindowConstants;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alistair Neil, <info@dazzleships.net>
|
||||
*/
|
||||
public class InfoDialog extends javax.swing.JDialog {
|
||||
|
||||
public static final int CANCEL_BUTTON = 0;
|
||||
public static final int CANCEL_WINDOW = 1;
|
||||
public static final int OK = 2;
|
||||
private Color fg = null;
|
||||
private final Frame parent;
|
||||
private String strButtClose;
|
||||
private String strTitle = "";
|
||||
private final Font fontDefault;
|
||||
private Timer tmrAutoClose;
|
||||
private Timer tmrButtonLock;
|
||||
|
||||
/**
|
||||
* Creates new InfoDialog, for parent frame with modality modal
|
||||
*
|
||||
* @param parent
|
||||
*/
|
||||
public InfoDialog(Frame parent) {
|
||||
super(parent, true);
|
||||
this.parent = parent;
|
||||
initComponents();
|
||||
jCheckBoxOption.setVisible(false);
|
||||
jProgressBar.setVisible(false);
|
||||
fg = jTextInfo.getForeground();
|
||||
fontDefault = jTextInfo.getFont();
|
||||
setContinueButtonText("Continue");
|
||||
setCancelButtonText("Cancel");
|
||||
setCloseButtonText("Close");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Font getFont() {
|
||||
return jPanelMain.getFont();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience methods
|
||||
*
|
||||
* @param title
|
||||
*/
|
||||
public final void createInfo(String title) {
|
||||
createInfo(title, null);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param title
|
||||
* @param info
|
||||
*/
|
||||
public final void createInfo(String title, String info) {
|
||||
super.setTitle(strTitle + " " + title);
|
||||
setModal(true);
|
||||
setCancelVisible(false);
|
||||
setContinueButtonText(strButtClose);
|
||||
jProgressBar.setVisible(false);
|
||||
FontMetrics fm = getFontMetrics(getFont());
|
||||
int width = fm.stringWidth(getTitle());
|
||||
if (width > getWidth()) {
|
||||
setSize(width, getHeight());
|
||||
}
|
||||
jTextInfo.setFont(fontDefault);
|
||||
jTextInfo.setForeground(fg);
|
||||
jTextInfo.setText("");
|
||||
if (info != null) {
|
||||
jTextInfo.setText(info);
|
||||
}
|
||||
jTextInfo.setCaretPosition(0);
|
||||
setLocationRelativeTo(parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set dialog title
|
||||
*
|
||||
* @param title
|
||||
*/
|
||||
@Override
|
||||
public final void setTitle(String title) {
|
||||
strTitle = title;
|
||||
super.setTitle(strTitle);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param title
|
||||
*/
|
||||
public final void createWarn(String title) {
|
||||
createWarn(title, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create warning dialog
|
||||
*
|
||||
* @param title
|
||||
* @param info
|
||||
*/
|
||||
public final void createWarn(String title, String info) {
|
||||
super.setTitle(strTitle + " " + title);
|
||||
setModal(true);
|
||||
setCancelVisible(true);
|
||||
jProgressBar.setVisible(false);
|
||||
FontMetrics fm = getFontMetrics(getFont());
|
||||
int width = fm.stringWidth(getTitle());
|
||||
if (width > getWidth()) {
|
||||
setSize(width, getHeight());
|
||||
}
|
||||
jTextInfo.setFont(fontDefault);
|
||||
jTextInfo.setForeground(fg);
|
||||
jTextInfo.setText("");
|
||||
if (info != null) {
|
||||
jTextInfo.setText(info);
|
||||
}
|
||||
setLocationRelativeTo(parent);
|
||||
jTextInfo.setCaretPosition(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create progress bar dialog
|
||||
*
|
||||
* @param title
|
||||
* @param info
|
||||
*/
|
||||
public final void createProgress(String title, String info) {
|
||||
super.setTitle(strTitle + " " + title);
|
||||
setModal(true);
|
||||
setCancelVisible(true);
|
||||
jProgressBar.setVisible(true);
|
||||
FontMetrics fm = getFontMetrics(getFont());
|
||||
int width = fm.stringWidth(getTitle());
|
||||
if (width > getWidth()) {
|
||||
setSize(width, getHeight());
|
||||
}
|
||||
jTextInfo.setFont(fontDefault);
|
||||
jTextInfo.setForeground(fg);
|
||||
jTextInfo.setText("");
|
||||
if (info != null) {
|
||||
jTextInfo.setText(info);
|
||||
}
|
||||
setLocationRelativeTo(parent);
|
||||
jTextInfo.setCaretPosition(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overridable handle for a progress based task
|
||||
*
|
||||
* @param status
|
||||
* @param jpb
|
||||
*/
|
||||
public void progressTask(int status, JProgressBar jpb) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create error dialog
|
||||
*
|
||||
* @param title
|
||||
*/
|
||||
public final void createError(String title) {
|
||||
createError(title, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create error dialog
|
||||
*
|
||||
* @param title
|
||||
* @param info
|
||||
*/
|
||||
public final void createError(String title, String info) {
|
||||
super.setTitle(strTitle + " " + title);
|
||||
setModal(true);
|
||||
setCancelVisible(false);
|
||||
setContinueButtonText(strButtClose);
|
||||
jProgressBar.setVisible(false);
|
||||
FontMetrics fm = getFontMetrics(getFont());
|
||||
int width = fm.stringWidth(getTitle());
|
||||
if (width > getWidth()) {
|
||||
setSize(width, getHeight());
|
||||
}
|
||||
jTextInfo.setFont(fontDefault);
|
||||
jTextInfo.setForeground(fg);
|
||||
jTextInfo.setText("");
|
||||
if (info != null) {
|
||||
jTextInfo.setText(info);
|
||||
}
|
||||
setLocationRelativeTo(parent);
|
||||
jTextInfo.setCaretPosition(0);
|
||||
}
|
||||
|
||||
public final void setTimeLock(final int secs) {
|
||||
jButtonCancel.setEnabled(false);
|
||||
jButtonContinue.setEnabled(false);
|
||||
this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
|
||||
final String buttontext = jButtonCancel.getText();
|
||||
tmrButtonLock = new Timer(1000, new java.awt.event.ActionListener() {
|
||||
int localsecs = secs;
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
localsecs--;
|
||||
if (localsecs == 0) {
|
||||
tmrButtonLock.stop();
|
||||
jButtonCancel.setText(buttontext);
|
||||
jButtonCancel.setEnabled(true);
|
||||
jButtonContinue.setEnabled(true);
|
||||
} else {
|
||||
jButtonCancel.setText(buttontext + " (" + localsecs + ")");
|
||||
}
|
||||
}
|
||||
});
|
||||
jButtonCancel.setText(buttontext + " (" + secs + ")");
|
||||
tmrButtonLock.start();
|
||||
}
|
||||
|
||||
public final void setCloseButtonText(String text) {
|
||||
strButtClose = text;
|
||||
}
|
||||
|
||||
public final void setCancelButtonText(String text) {
|
||||
jButtonCancel.setText(text);
|
||||
}
|
||||
|
||||
public final void setContinueButtonText(String text) {
|
||||
jButtonContinue.setText(text);
|
||||
}
|
||||
|
||||
public final void setCheckBoxText(String text) {
|
||||
jCheckBoxOption.setText(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/Disable Autoscrolling
|
||||
*
|
||||
* @param enabled
|
||||
*/
|
||||
public final void setAutoScrollEnabled(boolean enabled) {
|
||||
jTextInfo.setAutoscrolls(enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append text to the information area, Scrolling should be enabled
|
||||
*
|
||||
* @param text
|
||||
*/
|
||||
public final void appendInfoText(String text) {
|
||||
jTextInfo.append(text);
|
||||
jTextInfo.setCaretPosition(jTextInfo.getText().length());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether the forms checkbox is enabled
|
||||
*
|
||||
* @param enabled
|
||||
*/
|
||||
public final void setCheckBoxVisible(boolean enabled) {
|
||||
jCheckBoxOption.setVisible(enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set check box selection status
|
||||
*
|
||||
* @param checked
|
||||
*/
|
||||
public final void setCheckBoxEnabled(boolean checked) {
|
||||
jCheckBoxOption.setSelected(checked);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if checkbox is selected
|
||||
*
|
||||
* @return boolean True if selected
|
||||
*/
|
||||
public final boolean isCheckBoxSelected() {
|
||||
return jCheckBoxOption.isSelected();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set info font
|
||||
*
|
||||
* @param font
|
||||
* @param sizeoffset
|
||||
*/
|
||||
public final void setFont(String font, int sizeoffset) {
|
||||
jTextInfo.setFont(new Font(font, jTextInfo.getFont().getStyle(),
|
||||
jTextInfo.getFont().getSize() + sizeoffset));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the form auto close period in milliseconds
|
||||
*
|
||||
* @param millis
|
||||
*/
|
||||
public final void setAutoClose(int millis) {
|
||||
tmrAutoClose = new Timer(millis, new java.awt.event.ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
tmrAutoClose.stop();
|
||||
doClose(CANCEL_WINDOW);
|
||||
}
|
||||
});
|
||||
tmrAutoClose.start();
|
||||
}
|
||||
|
||||
public final JTextArea getTextArea() {
|
||||
return jTextInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the return status of this dialog - one of RET_OK or RET_CANCEL
|
||||
*/
|
||||
public final int getReturnStatus() {
|
||||
return returnStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set dialog message body
|
||||
*
|
||||
* @param text
|
||||
*/
|
||||
public final void setInfoText(String text) {
|
||||
jTextInfo.setText(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set dialog message body, and font colour
|
||||
*
|
||||
* @param text
|
||||
* @param fgcolor
|
||||
*/
|
||||
public final void setInfoText(String text, Color fgcolor) {
|
||||
jTextInfo.setForeground(fgcolor);
|
||||
jTextInfo.setText(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether Cancel button is enabled
|
||||
*
|
||||
* @param enabled
|
||||
*/
|
||||
public final void setCancelEnabled(boolean enabled) {
|
||||
jButtonCancel.setEnabled(enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether Cancel button is visible
|
||||
*
|
||||
* @param visible
|
||||
*/
|
||||
public final void setCancelVisible(boolean visible) {
|
||||
jButtonCancel.setVisible(visible);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether Ok button is enabled
|
||||
*
|
||||
* @param enabled
|
||||
*/
|
||||
public final void setAckEnabled(boolean enabled) {
|
||||
jButtonContinue.setEnabled(enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether OK button is visible
|
||||
*
|
||||
* @param visible
|
||||
*/
|
||||
public final void setAckVisible(boolean visible) {
|
||||
jButtonContinue.setVisible(visible);
|
||||
}
|
||||
|
||||
public void setVisibleWithFocus(boolean visible) {
|
||||
super.setVisible(visible);
|
||||
this.requestFocus();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
|
||||
jPanelMain = new javax.swing.JPanel();
|
||||
jButtonCancel = new javax.swing.JButton();
|
||||
jCheckBoxOption = new javax.swing.JCheckBox();
|
||||
jButtonContinue = new javax.swing.JButton();
|
||||
jScrollPane2 = new javax.swing.JScrollPane();
|
||||
jTextInfo = new javax.swing.JTextArea();
|
||||
jProgressBar = new javax.swing.JProgressBar();
|
||||
|
||||
setMinimumSize(new java.awt.Dimension(410, 165));
|
||||
setResizable(false);
|
||||
addWindowListener(new java.awt.event.WindowAdapter() {
|
||||
public void windowClosing(java.awt.event.WindowEvent evt) {
|
||||
closeDialog(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jPanelMain.setFont(jPanelMain.getFont().deriveFont(jPanelMain.getFont().getStyle() | java.awt.Font.BOLD, jPanelMain.getFont().getSize()+2));
|
||||
jPanelMain.setOpaque(false);
|
||||
|
||||
jButtonCancel.setText("Cancel");
|
||||
jButtonCancel.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
jButtonCancelActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jCheckBoxOption.setText("Disable this notification.");
|
||||
|
||||
jButtonContinue.setText("Continue");
|
||||
jButtonContinue.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
jButtonContinueActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jTextInfo.setEditable(false);
|
||||
jTextInfo.setColumns(20);
|
||||
jTextInfo.setLineWrap(true);
|
||||
jTextInfo.setRows(5);
|
||||
jTextInfo.setWrapStyleWord(true);
|
||||
jScrollPane2.setViewportView(jTextInfo);
|
||||
|
||||
jProgressBar.setString("");
|
||||
jProgressBar.setStringPainted(true);
|
||||
|
||||
javax.swing.GroupLayout jPanelMainLayout = new javax.swing.GroupLayout(jPanelMain);
|
||||
jPanelMain.setLayout(jPanelMainLayout);
|
||||
jPanelMainLayout.setHorizontalGroup(
|
||||
jPanelMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanelMainLayout.createSequentialGroup()
|
||||
.addComponent(jCheckBoxOption)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 63, Short.MAX_VALUE)
|
||||
.addComponent(jButtonCancel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jButtonContinue))
|
||||
.addComponent(jScrollPane2)
|
||||
.addComponent(jProgressBar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
);
|
||||
jPanelMainLayout.setVerticalGroup(
|
||||
jPanelMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanelMainLayout.createSequentialGroup()
|
||||
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 304, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jProgressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(jPanelMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jCheckBoxOption)
|
||||
.addComponent(jButtonContinue)
|
||||
.addComponent(jButtonCancel)))
|
||||
);
|
||||
|
||||
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()
|
||||
.addComponent(jPanelMain, 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(jPanelMain, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
pack();
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
private void jButtonCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonCancelActionPerformed
|
||||
doClose(CANCEL_BUTTON);
|
||||
}//GEN-LAST:event_jButtonCancelActionPerformed
|
||||
|
||||
/**
|
||||
* Closes the dialog
|
||||
*/
|
||||
private void closeDialog(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_closeDialog
|
||||
if (tmrButtonLock == null || !tmrButtonLock.isRunning()) {
|
||||
doClose(CANCEL_WINDOW);
|
||||
}
|
||||
}//GEN-LAST:event_closeDialog
|
||||
|
||||
private void jButtonContinueActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonContinueActionPerformed
|
||||
doClose(OK);
|
||||
}//GEN-LAST:event_jButtonContinueActionPerformed
|
||||
|
||||
private void doClose(int retStatus) {
|
||||
if (jProgressBar.isVisible()) {
|
||||
progressTask(retStatus, jProgressBar);
|
||||
return;
|
||||
}
|
||||
if (tmrAutoClose != null) {
|
||||
tmrAutoClose.stop();
|
||||
tmrAutoClose = null;
|
||||
}
|
||||
if (tmrButtonLock != null) {
|
||||
tmrButtonLock.stop();
|
||||
tmrButtonLock = null;
|
||||
}
|
||||
returnStatus = retStatus;
|
||||
setVisible(false);
|
||||
dispose();
|
||||
}
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton jButtonCancel;
|
||||
private javax.swing.JButton jButtonContinue;
|
||||
private javax.swing.JCheckBox jCheckBoxOption;
|
||||
private javax.swing.JPanel jPanelMain;
|
||||
private javax.swing.JProgressBar jProgressBar;
|
||||
private javax.swing.JScrollPane jScrollPane2;
|
||||
private javax.swing.JTextArea jTextInfo;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
private int returnStatus = CANCEL_BUTTON;
|
||||
}
|
109
src/lib/Localisation.java
Normal file
109
src/lib/Localisation.java
Normal file
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* 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 Version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* 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 lib;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alistair Neil, <info@dazzleships.net>
|
||||
*/
|
||||
public final class Localisation {
|
||||
|
||||
// Private Stuff
|
||||
private final ResourceBundle resourceBundle;
|
||||
private String encoding = null;
|
||||
|
||||
public Localisation(String resource) {
|
||||
String strSupportedLangs = "fr,en,pt";
|
||||
encoding = this.getString("encoding");
|
||||
if (!strSupportedLangs.contains(getLocale().getLanguage())) {
|
||||
Locale.setDefault(new Locale("en", "GB"));
|
||||
resourceBundle = ResourceBundle.getBundle(resource, Locale.getDefault());
|
||||
} else {
|
||||
resourceBundle = ResourceBundle.getBundle(resource);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the locale
|
||||
*
|
||||
* @return The locale
|
||||
*/
|
||||
public Locale getLocale() {
|
||||
return Locale.getDefault();
|
||||
}
|
||||
|
||||
public String toWebLanguageTag() {
|
||||
return getLocale().toLanguageTag().replace('-', '_');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the country name for supplied iso2 code
|
||||
*
|
||||
* @param iso2
|
||||
* @return Localised country name
|
||||
*/
|
||||
public String getDisplayCountry(String iso2) {
|
||||
switch (iso2) {
|
||||
case "A1":
|
||||
case "A2":
|
||||
case "O1":
|
||||
case "U1":
|
||||
return getString("iso" + iso2);
|
||||
default:
|
||||
Locale obj = new Locale("", iso2);
|
||||
return obj.getDisplayCountry();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get localised string using given key
|
||||
*
|
||||
* @param key
|
||||
* @return localised string
|
||||
*/
|
||||
public String getString(String key) {
|
||||
try {
|
||||
if (!encoding.contentEquals("encoding")) {
|
||||
byte[] text = resourceBundle.getString(key).getBytes("ISO8859-1");
|
||||
return new String(text, encoding);
|
||||
} else {
|
||||
return resourceBundle.getString(key);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of localised strings using a key array or multiple keys
|
||||
*
|
||||
* @param keys
|
||||
* @return localised string array
|
||||
*/
|
||||
public String[] getStrings(String... keys) {
|
||||
|
||||
String[] result = new String[keys.length];
|
||||
int i = 0;
|
||||
for (String key : keys) {
|
||||
result[i++] = getString(key);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
430
src/lib/NetFunctions.java
Normal file
430
src/lib/NetFunctions.java
Normal file
|
@ -0,0 +1,430 @@
|
|||
/*
|
||||
* 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 lib;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.Proxy;
|
||||
import java.net.Socket;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.JProgressBar;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alistair Neil, <info@dazzleships.net>
|
||||
*/
|
||||
public class NetFunctions {
|
||||
|
||||
public static final int CONNECTION_FAILED = 0;
|
||||
public static final int FILE_LOCAL_ISNEWER = 1;
|
||||
public static final int FILE_RETRIEVED = 2;
|
||||
public static final int FILE_FAILED = 3;
|
||||
public static final int EVENT_URLOK = 1;
|
||||
public static final int EVENT_URLFAILED = 2;
|
||||
public static final int EVENT_NETLATENCY = 3;
|
||||
public static final long LATENCY_FAIL = 9999;
|
||||
public static final long LATENCY_UNKNOWN = 0;
|
||||
private int intSocketTimeout = 8000;
|
||||
private JProgressBar jpb;
|
||||
|
||||
public NetFunctions() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set default socket timeout
|
||||
*
|
||||
* @param timeout
|
||||
*/
|
||||
public void setSocketTimeout(int timeout) {
|
||||
intSocketTimeout = timeout;
|
||||
}
|
||||
|
||||
public void setProgressBar(JProgressBar jpb) {
|
||||
this.jpb = jpb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the contents of a URL to a file
|
||||
*
|
||||
* @param destfile File destination path
|
||||
* @param sourceurl URL
|
||||
* @param socket
|
||||
* @param force Forces update regardless of age
|
||||
* @return int File retieval status code
|
||||
*/
|
||||
public int saveURLContentToFile(String destfile, String sourceurl, Socket socket, boolean force) {
|
||||
// Get a handle to our local file
|
||||
File f = new File(destfile);
|
||||
InputStream is = openStreamToURL(sourceurl, socket);
|
||||
HttpPage hp = new HttpPage(is);
|
||||
int result = FILE_FAILED;
|
||||
try {
|
||||
socket.setSoTimeout(intSocketTimeout);
|
||||
hp.retrieveHeader();
|
||||
if (hp.isHeaderOK()) {
|
||||
result = FILE_LOCAL_ISNEWER;
|
||||
if (hp.getLastModified() > f.lastModified() || force) {
|
||||
if (hp.saveBodyToFile(destfile, jpb)) {
|
||||
result = FILE_RETRIEVED;
|
||||
Logger.getGlobal().logp(Level.INFO, this.getClass().getName(), "saveURLContentToFile", "Http body content retrieved");
|
||||
} else {
|
||||
Logger.getGlobal().logp(Level.WARNING, this.getClass().getName(), "saveURLContentToFile", "Failed to retrieve Http body content");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Logger.getGlobal().logp(Level.WARNING, this.getClass().getName(), "saveURLContentToFile", "Failed to retrieve Http header");
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
Logger.getGlobal().logp(Level.WARNING, this.getClass().getName(), "saveURLContentToFile", ex.getMessage());
|
||||
} finally {
|
||||
try {
|
||||
is.close();
|
||||
socket.close();
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure ipaddress is valid number
|
||||
*
|
||||
* @param ipaddress
|
||||
* @return true if a valid ip address
|
||||
*/
|
||||
public boolean isIPAddress(String ipaddress) {
|
||||
ipaddress = ipaddress.replace(".", "");
|
||||
try {
|
||||
Long.parseLong(ipaddress);
|
||||
return true;
|
||||
} catch (NumberFormatException ex) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get latency non threaded version
|
||||
*
|
||||
* @param surl Testing url
|
||||
* @param proxy Specify a proxy, null == no proxy
|
||||
* @param timeout Specify a timeout before declaring failure
|
||||
* @return long latency in milliseconds
|
||||
*/
|
||||
public long getLatency(String surl, Proxy proxy, int timeout) {
|
||||
|
||||
long lngStart;
|
||||
long lngResult;
|
||||
HttpURLConnection conn = null;
|
||||
|
||||
try {
|
||||
URL url = new URL(surl);
|
||||
if (proxy == null) {
|
||||
conn = (HttpURLConnection) url.openConnection();
|
||||
} else {
|
||||
conn = (HttpURLConnection) url.openConnection(proxy);
|
||||
}
|
||||
conn.setDoInput(true);
|
||||
conn.setDefaultUseCaches(false);
|
||||
conn.setConnectTimeout(timeout);
|
||||
lngStart = System.currentTimeMillis();
|
||||
conn.connect();
|
||||
lngResult = System.currentTimeMillis() - lngStart;
|
||||
} catch (IOException ex) {
|
||||
lngResult = LATENCY_FAIL;
|
||||
Logger.getGlobal().log(Level.WARNING, "getLatency {0}", ex.getMessage());
|
||||
}
|
||||
if (conn != null) {
|
||||
conn.disconnect();
|
||||
}
|
||||
return lngResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check web for updates and return version string if an update is available
|
||||
*
|
||||
* @param sourceurl URL to check
|
||||
* @param s Socket
|
||||
* @return String new version number
|
||||
*/
|
||||
public String getURLContentAsString(String sourceurl, Socket s) {
|
||||
|
||||
String result = null;
|
||||
try {
|
||||
s.setSoTimeout(intSocketTimeout);
|
||||
try (InputStream is = openStreamToURL(sourceurl, s)) {
|
||||
HttpPage hp = new HttpPage(is);
|
||||
hp.retrieveHeader();
|
||||
if (hp.isHeaderOK()) {
|
||||
result = hp.getBodyAsString();
|
||||
}
|
||||
is.close();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Logger.getGlobal().log(Level.WARNING, "getURLAsString", ex.getMessage());
|
||||
result = null;
|
||||
} finally {
|
||||
try {
|
||||
s.close();
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open an inputstream to the given url on the given socket
|
||||
*
|
||||
* @param surl
|
||||
* @param s
|
||||
* @return inputstream
|
||||
*/
|
||||
public InputStream openStreamToURL(String surl, Socket s) {
|
||||
URI uri;
|
||||
try {
|
||||
uri = new URI(surl);
|
||||
String host = uri.getHost();
|
||||
String path = uri.getRawPath();
|
||||
if (path == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
PrintWriter request = new PrintWriter(s.getOutputStream());
|
||||
request.print("GET " + path + " HTTP/1.1\r\n"
|
||||
+ "Host: " + host + "\r\n"
|
||||
+ "Connection: close\r\n\r\n"
|
||||
);
|
||||
|
||||
request.flush();
|
||||
InputStream inStream = s.getInputStream();
|
||||
return inStream;
|
||||
} catch (URISyntaxException | IOException ex) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store an http formatted web page
|
||||
*/
|
||||
public static final class HttpPage {
|
||||
|
||||
public static final String PATTERN_RFC1123 = "EEE, dd MMM yyyy HH:mm:ss zzz";
|
||||
public static final String PATTERN_RFC1036 = "EEEE, dd-MMM-yy HH:mm:ss zzz";
|
||||
public static final String PATTERN_ASCTIME = "EEE MMM d HH:mm:ss yyyy";
|
||||
private final TimeZone GMT = TimeZone.getTimeZone("GMT");
|
||||
private final SimpleDateFormat format = new SimpleDateFormat("", Locale.US);
|
||||
private final HashMap<String, String> hm = new HashMap<>();
|
||||
private final InputStream israw;
|
||||
|
||||
/**
|
||||
* Store webpage from the given input stream
|
||||
*
|
||||
* @param is
|
||||
*/
|
||||
public HttpPage(InputStream is) {
|
||||
format.setTimeZone(GMT);
|
||||
israw = is;
|
||||
}
|
||||
|
||||
private String readLine(InputStream is) {
|
||||
byte data;
|
||||
String line = "";
|
||||
String term = "";
|
||||
try {
|
||||
while (!"\r\n".equals(term)) {
|
||||
data = (byte) is.read();
|
||||
if (data == -1) {
|
||||
return null;
|
||||
}
|
||||
line += String.valueOf((char) data);
|
||||
if (((char) data) == '\r' || ((char) data) == '\n') {
|
||||
term += String.valueOf((char) data);
|
||||
} else {
|
||||
term = "";
|
||||
}
|
||||
}
|
||||
line = line.trim();
|
||||
} catch (Exception ex) {
|
||||
line = null;
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve http header info
|
||||
*/
|
||||
public final void retrieveHeader() {
|
||||
int colonpos;
|
||||
String key;
|
||||
String value;
|
||||
String line;
|
||||
try {
|
||||
line = readLine(israw);
|
||||
hm.put("Header-Response", line);
|
||||
while (true) {
|
||||
line = readLine(israw);
|
||||
if (line.isEmpty()) {
|
||||
if (hm.get("Content-Length") == null) {
|
||||
line = readLine(israw);
|
||||
if (!line.isEmpty()) {
|
||||
try {
|
||||
long contentsize = Long.parseLong(line, 16);
|
||||
hm.put("Content-Length", String.valueOf(contentsize));
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
colonpos = line.indexOf(':');
|
||||
key = line.substring(0, colonpos);
|
||||
value = line.substring(colonpos + 1);
|
||||
hm.put(key, value.trim());
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Logger.getGlobal().log(Level.WARNING, "retrieveHeader()", ex.getMessage());
|
||||
hm.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve http body as string should only be used with text content
|
||||
*
|
||||
* @return null if failed, otherwise returns the contents
|
||||
*/
|
||||
public final String getBodyAsString() {
|
||||
String result = "";
|
||||
try {
|
||||
String temp = hm.get("Content-Length");
|
||||
if (temp == null) {
|
||||
return null;
|
||||
}
|
||||
long contentsize = Long.parseLong(temp);
|
||||
while (contentsize-- != 0) {
|
||||
result += (char) israw.read();
|
||||
}
|
||||
} catch (NumberFormatException | IOException ex) {
|
||||
result = null;
|
||||
Logger.getGlobal().log(Level.WARNING, "getBodyAsString()", ex.getMessage());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save http body to a file, applies to all types of content
|
||||
*
|
||||
* @param dest File destination
|
||||
* @param jpb Progress bar
|
||||
* @return true if successful
|
||||
*/
|
||||
public final boolean saveBodyToFile(String dest, JProgressBar jpb) {
|
||||
try {
|
||||
String temp = hm.get("Content-Length");
|
||||
if (temp == null) {
|
||||
return false;
|
||||
}
|
||||
long contentsize = Long.parseLong(temp);
|
||||
long bytereset = contentsize / 102;
|
||||
long bytecount = bytereset;
|
||||
int progress = 0;
|
||||
File f = new File(dest);
|
||||
try (FileOutputStream fos = new FileOutputStream(f)) {
|
||||
if (jpb != null) {
|
||||
jpb.setString(null);
|
||||
}
|
||||
while (contentsize-- != 0) {
|
||||
fos.write(israw.read());
|
||||
if (bytecount-- == 0) {
|
||||
bytecount = bytereset;
|
||||
if (jpb != null) {
|
||||
jpb.setValue(progress++);
|
||||
}
|
||||
}
|
||||
}
|
||||
fos.close();
|
||||
return true;
|
||||
}
|
||||
} catch (NumberFormatException | IOException ex) {
|
||||
Logger.getGlobal().log(Level.WARNING, "saveBody()", ex.getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get various properties of the web page
|
||||
*
|
||||
* @param key
|
||||
* @return property string
|
||||
*/
|
||||
public final String getProperty(String key) {
|
||||
return hm.get(key);
|
||||
}
|
||||
|
||||
private long getHttpDate(String adate) {
|
||||
try {
|
||||
format.applyPattern(PATTERN_RFC1123);
|
||||
return format.parse(adate).getTime();
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
try {
|
||||
format.applyPattern(PATTERN_RFC1036);
|
||||
return format.parse(adate).getTime();
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
try {
|
||||
format.applyPattern(PATTERN_ASCTIME);
|
||||
return format.parse(adate).getTime();
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public final long getLastModified() {
|
||||
return getHttpDate(hm.get("Last-Modified"));
|
||||
}
|
||||
|
||||
public final long getServerDate() {
|
||||
return getHttpDate(hm.get("Date"));
|
||||
}
|
||||
|
||||
public final long getExpires() {
|
||||
return getHttpDate(hm.get("Expires"));
|
||||
}
|
||||
|
||||
public final boolean isHeaderOK() {
|
||||
String temp = hm.get("Content-Length");
|
||||
if (temp == null) {
|
||||
return false;
|
||||
}
|
||||
temp = hm.get("Header-Response");
|
||||
if (temp == null) {
|
||||
return false;
|
||||
}
|
||||
return temp.contains("200 OK");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
870
src/lib/OSFunction.java
Normal file
870
src/lib/OSFunction.java
Normal file
|
@ -0,0 +1,870 @@
|
|||
/*
|
||||
* 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 lib;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.RuntimeMXBean;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Locale;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alistair Neil <info@dazzleships.net>
|
||||
*/
|
||||
public class OSFunction {
|
||||
|
||||
private static ArrayList<String> alProcesses;
|
||||
|
||||
/**
|
||||
* Get process id
|
||||
*
|
||||
* @return Process id or -1 if not found
|
||||
*/
|
||||
public static String getOurProcessID() {
|
||||
RuntimeMXBean rtb = ManagementFactory.getRuntimeMXBean();
|
||||
String processName = rtb.getName();
|
||||
Integer pid = tryPattern(processName);
|
||||
return String.valueOf(pid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get process id from a process
|
||||
*
|
||||
* @param process
|
||||
* @return process id as String
|
||||
*/
|
||||
public static String getProcessID(String process) {
|
||||
Pattern pattern = Pattern.compile(" +");
|
||||
String[] result = pattern.split(process.trim());
|
||||
if (isWindows()) {
|
||||
return result[1];
|
||||
} else {
|
||||
return result[0];
|
||||
}
|
||||
}
|
||||
|
||||
private static Integer tryPattern(String processName) {
|
||||
Integer result = null;
|
||||
Pattern pattern = Pattern.compile("^([0-9]+)@.+$", Pattern.CASE_INSENSITIVE);
|
||||
Matcher matcher = pattern.matcher(processName);
|
||||
if (matcher.matches()) {
|
||||
result = Integer.parseInt(matcher.group(1));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get OS version
|
||||
*
|
||||
* @return String OS version
|
||||
*/
|
||||
public static String getOSVersion() {
|
||||
return System.getProperty("os.version");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user name
|
||||
*
|
||||
* @return String User name
|
||||
*/
|
||||
public static String getUserName() {
|
||||
return System.getProperty("user.name");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get users home folder
|
||||
*
|
||||
* @return String path to home folder
|
||||
*/
|
||||
public static String getUsersHomeFolder() {
|
||||
return System.getProperty("user.home");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file separator
|
||||
*
|
||||
* @return String separator
|
||||
*/
|
||||
public static String getFileSeparator() {
|
||||
return System.getProperty("file.separator");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get users documents folder (Windows only)
|
||||
*
|
||||
* @return String path to documents folder
|
||||
*/
|
||||
public static String getUsersDocFolder() {
|
||||
|
||||
String strReturn = getUsersHomeFolder() + "\\Documents";
|
||||
if (isWinXP()) {
|
||||
strReturn = getUsersHomeFolder() + "\\My Documents";
|
||||
}
|
||||
return strReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user settings path
|
||||
*
|
||||
* @return String path to user settings folder
|
||||
*/
|
||||
public static String getUserSettingsPath() {
|
||||
|
||||
String userSettingsPath;
|
||||
if (isWindows()) {
|
||||
userSettingsPath = getUsersHomeFolder() + "\\Application Data\\";
|
||||
} else {
|
||||
userSettingsPath = getUsersHomeFolder() + "/";
|
||||
}
|
||||
return userSettingsPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specified application's settings folder, if null return this
|
||||
* applications setting folder
|
||||
*
|
||||
* @param appname Application settings folder name
|
||||
* @param appseries Application series (optional)
|
||||
* @return String Path to the applications setting folder
|
||||
*/
|
||||
public static String getAppSettingsPath(String appname, String appseries) {
|
||||
|
||||
String appSettingsPath = getUserSettingsPath();
|
||||
if (appname == null) {
|
||||
return appSettingsPath;
|
||||
}
|
||||
if (isLinux()) {
|
||||
appname = "." + appname;
|
||||
}
|
||||
appSettingsPath += appname + getFileSeparator();
|
||||
if (appseries != null) {
|
||||
appSettingsPath += appseries + getFileSeparator();
|
||||
}
|
||||
return appSettingsPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get users current folder
|
||||
*
|
||||
* @return String Path to current folder
|
||||
*/
|
||||
public static String getUsersCurrentFolder() {
|
||||
return System.getProperty("user.dir");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get users temp folder
|
||||
*
|
||||
* @param path
|
||||
* @return String Path to users temp folder
|
||||
*/
|
||||
public static String getTempFolder(String path) {
|
||||
String result = System.getProperty("java.io.tmpdir");
|
||||
String sep = "";
|
||||
if (isLinux()) {
|
||||
sep = getFileSeparator();
|
||||
}
|
||||
result += sep;
|
||||
if (path != null && !path.isEmpty()) {
|
||||
if (isWindows()) {
|
||||
sep = getFileSeparator();
|
||||
}
|
||||
result = result + path + sep;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get OS name, convenience method
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public static String getOSName() {
|
||||
return System.getProperty("os.name").toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get OS architecture, convenience method
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public static String getOSArch() {
|
||||
return System.getProperty("os.arch");
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic test for Windows platform
|
||||
*
|
||||
* @return boolean True if Windows
|
||||
*/
|
||||
public static boolean isWindows() {
|
||||
return getOSName().contains("windows");
|
||||
}
|
||||
|
||||
/**
|
||||
* Specific test for Win 7
|
||||
*
|
||||
* @return boolean True if Win 7
|
||||
*/
|
||||
public static boolean isWin7() {
|
||||
return getOSName().startsWith("windows 7");
|
||||
}
|
||||
|
||||
/**
|
||||
* Specific test for Win 8
|
||||
*
|
||||
* @return boolean True if Win 8
|
||||
*/
|
||||
public static boolean isWin8() {
|
||||
return getOSName().startsWith("windows 8");
|
||||
}
|
||||
|
||||
/**
|
||||
* Specific test for Win 10
|
||||
*
|
||||
* @return boolean True if Win 10
|
||||
*/
|
||||
public static boolean isWin10() {
|
||||
return getOSName().startsWith("windows 10");
|
||||
}
|
||||
|
||||
/**
|
||||
* Specific test for Win XP
|
||||
*
|
||||
* @return boolean True if Win XP
|
||||
*/
|
||||
public static boolean isWinXP() {
|
||||
return getOSName().contentEquals("windows");
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic test for Linux platform
|
||||
*
|
||||
* @return boolean True if Linux
|
||||
*/
|
||||
public static boolean isLinux() {
|
||||
return getOSName().contains("linux");
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a specific file, requires a series of paths where it might be found
|
||||
* to be provided
|
||||
*
|
||||
* @param fname
|
||||
* @param paths
|
||||
* @return String path to file or null
|
||||
*/
|
||||
public static String findFile(String fname, String... paths) {
|
||||
for (String s : paths) {
|
||||
if (new File(s + fname).exists()) {
|
||||
return s + fname;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if their are multiple instances of the this app running
|
||||
*
|
||||
* @param appname
|
||||
* @return True if multiple instance
|
||||
*/
|
||||
public static boolean isMultipleInstance(String appname) {
|
||||
if (alProcesses == null) {
|
||||
alProcesses = getLiveProcesses();
|
||||
}
|
||||
ArrayList<String> processes = OSFunction.filterProcesses(appname);
|
||||
return OSFunction.filterProcesses(processes, "java").size() > 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cached list of processes
|
||||
*
|
||||
* @return list
|
||||
*/
|
||||
public static ArrayList<String> getCachedProcesses() {
|
||||
return alProcesses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find processes matching the contents of filter
|
||||
*
|
||||
* @param processes
|
||||
* @param filter
|
||||
* @return ArrayList of matching processes
|
||||
*/
|
||||
public static ArrayList<String> filterProcesses(ArrayList<String> processes, String filter) {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
if (processes != null && !processes.isEmpty()) {
|
||||
if (filter != null) {
|
||||
for (String s : processes) {
|
||||
if (s.contains(filter)) {
|
||||
result.add(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find processes matching the contents of filter
|
||||
*
|
||||
* @param filter
|
||||
* @return ArrayList of matching processes
|
||||
*/
|
||||
public static ArrayList<String> filterProcesses(String filter) {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
if (!alProcesses.isEmpty()) {
|
||||
if (filter != null) {
|
||||
for (String s : alProcesses) {
|
||||
if (s.contains(filter)) {
|
||||
result.add(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic kill process with matching pid
|
||||
*
|
||||
* @param pid
|
||||
* @return String kill result or null if failed
|
||||
*/
|
||||
public static String killProcess(String pid) {
|
||||
if (isWindows()) {
|
||||
return killProcessWindows(pid);
|
||||
}
|
||||
if (isLinux()) {
|
||||
return killProcessLinux(pid);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Windows specific kill process with matching pid
|
||||
*
|
||||
* @param pid
|
||||
* @return String kill result or null if failed
|
||||
*/
|
||||
private static String killProcessWindows(String pid) {
|
||||
Process processKill;
|
||||
try {
|
||||
processKill = Runtime.getRuntime().exec("taskkill /F /pid " + pid);
|
||||
return getProcessResult(processKill);
|
||||
} catch (IOException ex) {
|
||||
Logger.getGlobal().logp(Level.WARNING, OSFunction.class.getName(), "killProcessWindows", "", ex);
|
||||
}
|
||||
try {
|
||||
processKill = Runtime.getRuntime().exec("tskill " + pid);
|
||||
return getProcessResult(processKill);
|
||||
} catch (IOException ex) {
|
||||
Logger.getGlobal().logp(Level.WARNING, OSFunction.class.getName(), "killProcessWindows", "", ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Linux specific specific kill process with matching pid
|
||||
*
|
||||
* @param pid
|
||||
* @return String kill result or null if failed
|
||||
*/
|
||||
private static String killProcessLinux(String pid) {
|
||||
Process processKill = null;
|
||||
try {
|
||||
processKill = Runtime.getRuntime().exec("kill -9 " + pid);
|
||||
} catch (IOException ex) {
|
||||
Logger.getGlobal().logp(Level.WARNING, OSFunction.class.getName(), "killProcessLinux", "", ex);
|
||||
}
|
||||
return getProcessResult(processKill);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a files hidden status (Windows only)
|
||||
*
|
||||
* @param filepath Path to file includes filename
|
||||
* @param hidden True/False
|
||||
*/
|
||||
public static void setFileHidden(String filepath, boolean hidden) {
|
||||
|
||||
if (isWindows()) {
|
||||
try {
|
||||
if (hidden) {
|
||||
Runtime.getRuntime().exec("Attrib.exe +H " + filepath).waitFor();
|
||||
} else {
|
||||
Runtime.getRuntime().exec("Attrib.exe -H " + filepath).waitFor();
|
||||
}
|
||||
} catch (IOException | InterruptedException ex) {
|
||||
Logger.getGlobal().logp(Level.WARNING, OSFunction.class.getName(), "setFileHidden", "", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get gnome 3 preference using schema name and key name
|
||||
*
|
||||
* @param schema
|
||||
* @param key
|
||||
* @return String preference value
|
||||
*/
|
||||
public static String getGnome3Pref(String schema, String key) {
|
||||
Process p = launchProcess("gsettings", "get", schema, key);
|
||||
String result = getProcessResult(p);
|
||||
if (result != null) {
|
||||
result = result.replace("'", "").replace("[", "").replace("]", "");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a gnome 3 boolean value using schema name and key name
|
||||
*
|
||||
* @param schema
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public static void setGnome3Pref(String schema, String key, boolean value) {
|
||||
setGnome3Pref(schema, key, String.valueOf(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a gnome 3 string value using schema name and key name
|
||||
*
|
||||
* @param schema
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public static void setGnome3Pref(String schema, String key, String value) {
|
||||
if (value == null || value.isEmpty()) {
|
||||
resetGnome3Pref(schema, key);
|
||||
} else {
|
||||
launchProcess("gsettings", "set", schema, key, "'" + value + "'");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset a gnome3 value to its default. If key is null, it will reset the
|
||||
* whole schema tree to its defaults
|
||||
*
|
||||
* @param schema
|
||||
* @param key
|
||||
*/
|
||||
public static void resetGnome3Pref(String schema, String key) {
|
||||
if (key == null) {
|
||||
launchProcess("gsettings", "reset", schema);
|
||||
} else {
|
||||
launchProcess("gsettings", "reset", schema, key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a kde preference string value using group name, key name and return
|
||||
* contents of def on failure
|
||||
*
|
||||
* @param group
|
||||
* @param key
|
||||
* @param def
|
||||
* @return String Preference value
|
||||
*/
|
||||
public static String getKDEPref(String group, String key, String def) {
|
||||
|
||||
// If exists read the file contents and find the matching key
|
||||
String strKdePath = getKDEProxyPath();
|
||||
if (strKdePath == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String strTemp = null;
|
||||
SimpleFile sf = new SimpleFile(strKdePath);
|
||||
sf.openBufferedRead();
|
||||
while ((strTemp = sf.readLine()) != null) {
|
||||
if (strTemp.contains("[" + group + "]")) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (strTemp == null) {
|
||||
return def;
|
||||
}
|
||||
while ((strTemp = sf.readLine()) != null) {
|
||||
if (strTemp.contains(key)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
sf.closeFile();
|
||||
if (strTemp == null) {
|
||||
return def;
|
||||
}
|
||||
strTemp = strTemp.substring(strTemp.indexOf('=') + 1);
|
||||
return strTemp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a kde string preference value using group name, key name
|
||||
*
|
||||
* @param group
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public static void setKDEPref(String group, String key, String value) {
|
||||
|
||||
// If exists read the file contents and find the matching key
|
||||
String strKdePath = getKDEProxyPath();
|
||||
if (strKdePath == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
SimpleFile sf = new SimpleFile(strKdePath);
|
||||
// Get file contents into a array list for further processing
|
||||
String strTemp;
|
||||
ArrayList<String> listContents = new ArrayList<>();
|
||||
sf.openBufferedRead();
|
||||
while ((strTemp = sf.readLine()) != null) {
|
||||
listContents.add(strTemp);
|
||||
}
|
||||
sf.closeFile();
|
||||
|
||||
// Process contents of file and write it back out
|
||||
sf.openBufferedWrite();
|
||||
// Find Group entry
|
||||
boolean entryfound = false;
|
||||
while (!listContents.isEmpty()) {
|
||||
strTemp = listContents.get(0);
|
||||
sf.writeFile(strTemp, 1);
|
||||
listContents.remove(0);
|
||||
if (strTemp.contentEquals("[" + group + "]")) {
|
||||
entryfound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If no group entry found then write one
|
||||
if (!entryfound) {
|
||||
sf.writeFile("", 1);
|
||||
sf.writeFile("[" + group + "]", 1);
|
||||
}
|
||||
|
||||
// Find key entry
|
||||
while (!listContents.isEmpty()) {
|
||||
strTemp = listContents.get(0);
|
||||
listContents.remove(0);
|
||||
if (strTemp.contains(key)) {
|
||||
break;
|
||||
}
|
||||
sf.writeFile(strTemp, 1);
|
||||
}
|
||||
|
||||
sf.writeFile(key + "=" + value, 1);
|
||||
|
||||
// Write out rest of file
|
||||
while (!listContents.isEmpty()) {
|
||||
strTemp = listContents.get(0);
|
||||
listContents.remove(0);
|
||||
sf.writeFile(strTemp, 1);
|
||||
}
|
||||
sf.closeFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a kde boolean preference value using group name, key name
|
||||
*
|
||||
* @param group
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public static void setKDEPref(String group, String key, boolean value) {
|
||||
setKDEPref(group, key, String.valueOf(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a kde integer preference value using group name, key name
|
||||
*
|
||||
* @param group
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public static void setKDEPref(String group, String key, int value) {
|
||||
setKDEPref(group, key, String.valueOf(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for KDE installed (Linux only)
|
||||
*
|
||||
* @return String path to kde proxy file or null
|
||||
*/
|
||||
public static String getKDEProxyPath() {
|
||||
if (isLinux()) {
|
||||
File f = new File(getUsersHomeFolder() + "/.config/kioslaverc");
|
||||
if (f.exists()) {
|
||||
return f.getAbsolutePath();
|
||||
}
|
||||
f = new File(getUsersHomeFolder() + "/.kde/share/config/kioslaverc");
|
||||
if (f.exists()) {
|
||||
return f.getAbsolutePath();
|
||||
}
|
||||
f = new File(getUsersHomeFolder() + "/.kde4/share/config/kioslaverc");
|
||||
if (f.exists()) {
|
||||
return f.getAbsolutePath();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if gsettings installed (Linux only)
|
||||
*
|
||||
* @return String path to gsetttings
|
||||
*/
|
||||
public static String getGsettingsPath() {
|
||||
// Verify if gsettings is installed
|
||||
return findFile("gsettings", "/usr/bin/");
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to get the first resultant output of an executed
|
||||
* process as a String
|
||||
*
|
||||
* @param aprocess
|
||||
* @return String Process result
|
||||
*/
|
||||
public static String getProcessResult(Process aprocess) {
|
||||
if (aprocess == null) {
|
||||
return null;
|
||||
}
|
||||
return getProcessOutput(aprocess.getInputStream()).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain all output of an executed process.
|
||||
*
|
||||
* @param is
|
||||
* @return ArrayList of Strings containing all generated output
|
||||
*/
|
||||
public static ArrayList<String> getProcessOutput(InputStream is) {
|
||||
|
||||
String line;
|
||||
ArrayList<String> arrList = new ArrayList<>();
|
||||
try {
|
||||
try (BufferedReader input = new BufferedReader(new InputStreamReader(is))) {
|
||||
while ((line = input.readLine()) != null) {
|
||||
if (line.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
arrList.add(line);
|
||||
}
|
||||
}
|
||||
return arrList;
|
||||
} catch (IOException ex) {
|
||||
Logger.getGlobal().logp(Level.SEVERE, OSFunction.class.getName(), "getProcessResults", "", ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch an external process with arguments
|
||||
*
|
||||
* @param command
|
||||
* @return Process
|
||||
*/
|
||||
public static Process launchProcess(String... command) {
|
||||
try {
|
||||
Process p = Runtime.getRuntime().exec(command);
|
||||
if (p == null) {
|
||||
Logger.getGlobal().logp(Level.WARNING, OSFunction.class.getName(), "launchProcess", "Failed Process", "");
|
||||
}
|
||||
return p;
|
||||
} catch (IOException ex) {
|
||||
Logger.getGlobal().logp(Level.WARNING, OSFunction.class.getName(), "launchProcess", "", ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets list of active system processes
|
||||
*
|
||||
* @return Arraylist of system process
|
||||
*/
|
||||
public static ArrayList<String> getLiveProcesses() {
|
||||
if (isWindows()) {
|
||||
return getActiveProcessesWindows();
|
||||
} else {
|
||||
return getActiveProcessesLinux();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Windows specific refresh or internal list of active system processes
|
||||
*/
|
||||
private static ArrayList<String> getActiveProcessesWindows() {
|
||||
ArrayList<String> alResult = new ArrayList<>();
|
||||
try {
|
||||
Logger.getGlobal().info("refreshActiveProcessesWindows()");
|
||||
Process p = Runtime.getRuntime().exec(System.getenv("windir") + "\\system32\\" + "tasklist.exe /v");
|
||||
alResult = getProcessOutput(p.getInputStream());
|
||||
if (alResult.size() > 1) {
|
||||
// Remove second entry
|
||||
alResult.remove(1);
|
||||
}
|
||||
return alResult;
|
||||
} catch (IOException ex) {
|
||||
Logger.getGlobal().logp(Level.WARNING, OSFunction.class.getName(), "refreshActiveProcessesWindows", "", ex);
|
||||
}
|
||||
return alResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Linux specific refresh or internal list of active system processes
|
||||
*/
|
||||
private static ArrayList<String> getActiveProcessesLinux() {
|
||||
|
||||
ArrayList<String> alResult = new ArrayList<>();
|
||||
try {
|
||||
Process process = Runtime.getRuntime().exec("ps ax");
|
||||
alResult = getProcessOutput(process.getInputStream());
|
||||
return alResult;
|
||||
} catch (IOException ex) {
|
||||
Logger.getGlobal().logp(Level.WARNING, OSFunction.class.getName(), "refreshActiveProcessesLinux", "", ex);
|
||||
}
|
||||
return alResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the compositor
|
||||
*
|
||||
* @return name as String
|
||||
*/
|
||||
public static String getCompositor() {
|
||||
String result = "unknown";
|
||||
if (isWin7() || isWin8() || isWin10()) {
|
||||
return "DWM";
|
||||
}
|
||||
if (isWindows()) {
|
||||
return getOSName();
|
||||
}
|
||||
if (alProcesses == null) {
|
||||
alProcesses = getLiveProcesses();
|
||||
}
|
||||
for (String s : alProcesses) {
|
||||
if (s.contains("kwin")) {
|
||||
result = "kwin";
|
||||
break;
|
||||
}
|
||||
if (s.contains("compton")) {
|
||||
result = "compton";
|
||||
break;
|
||||
}
|
||||
if (s.contains("cinnamon")) {
|
||||
result = "clutter";
|
||||
break;
|
||||
}
|
||||
if (s.contains("marco")) {
|
||||
result = "marco";
|
||||
break;
|
||||
}
|
||||
if (s.contains("compiz")) {
|
||||
result = "compiz";
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the active desktop
|
||||
*
|
||||
* @return name as String
|
||||
*/
|
||||
public static String getActiveDesktop() {
|
||||
if (isWindows()) {
|
||||
return getOSName();
|
||||
}
|
||||
String result = "unknown";
|
||||
if (alProcesses == null) {
|
||||
alProcesses = getLiveProcesses();
|
||||
}
|
||||
for (String s : alProcesses) {
|
||||
if (s.contains("cinnamon-session")) {
|
||||
result = "cinnamon";
|
||||
break;
|
||||
}
|
||||
if (s.contains("xfce4-session")) {
|
||||
result = "xfce";
|
||||
break;
|
||||
}
|
||||
if (s.contains("mate-session")) {
|
||||
result = "mate";
|
||||
break;
|
||||
}
|
||||
if (s.contains("gnome-shell")) {
|
||||
result = "gnome3";
|
||||
break;
|
||||
}
|
||||
if (s.contains("unity-settings-daemon")) {
|
||||
result = "unity";
|
||||
break;
|
||||
}
|
||||
if (s.contains("lxsession")) {
|
||||
result = "lxde";
|
||||
break;
|
||||
}
|
||||
if (s.contains("plasma-desktop")) {
|
||||
result = "kde4";
|
||||
break;
|
||||
}
|
||||
if (s.contains("plasmashell")) {
|
||||
result = "kde5";
|
||||
break;
|
||||
}
|
||||
if (s.contains("enlightenment")) {
|
||||
result = "enlightenment";
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear active processes, mainly to reduce memory consumption when were
|
||||
* done with them
|
||||
*/
|
||||
public static void clearActiveProcesses() {
|
||||
alProcesses.clear();
|
||||
alProcesses = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default language iso code
|
||||
*
|
||||
* @return language iso code
|
||||
*/
|
||||
public static String getLangCode() {
|
||||
return Locale.getDefault().getLanguage();
|
||||
}
|
||||
|
||||
}
|
895
src/lib/SimpleFile.java
Normal file
895
src/lib/SimpleFile.java
Normal file
|
@ -0,0 +1,895 @@
|
|||
/*
|
||||
* 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 lib;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.file.FileVisitResult;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.SimpleFileVisitor;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alistair Neil info@dazzleships.net
|
||||
*/
|
||||
public class SimpleFile {
|
||||
|
||||
public static final int PERIOD_MINUTES = 0;
|
||||
public static final int PERIOD_HOURS = 1;
|
||||
public static final int PERIOD_DAYS = 2;
|
||||
public static final int NOTFOUND = 0;
|
||||
public static final int FILEDELETEOK = 1;
|
||||
public static final int FILEDELETEFAIL = 2;
|
||||
private final int blockreadsize = 1024;
|
||||
private BufferedReader br;
|
||||
private BufferedWriter bw;
|
||||
private ZipOutputStream zos;
|
||||
private File f;
|
||||
private String filter = "";
|
||||
|
||||
public SimpleFile() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param pathname
|
||||
*/
|
||||
public SimpleFile(String pathname) {
|
||||
f = new File(pathname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set filename
|
||||
*
|
||||
* @param pathname
|
||||
*/
|
||||
public final void setFileName(String pathname) {
|
||||
f = new File(pathname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set file
|
||||
*
|
||||
* @param file
|
||||
*/
|
||||
public final void setFile(File file) {
|
||||
f = file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file
|
||||
*
|
||||
* @return file
|
||||
*/
|
||||
public final File getFile() {
|
||||
return f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close file and any resources such as buffered readers/writers that are
|
||||
* attached to it.
|
||||
*/
|
||||
public final void closeFile() {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(SimpleFile.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
br = null;
|
||||
}
|
||||
if (bw != null) {
|
||||
try {
|
||||
bw.close();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(SimpleFile.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
bw = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the file filter
|
||||
*
|
||||
* @param filter
|
||||
*/
|
||||
public final void setFileFilter(String filter) {
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current file filter
|
||||
*
|
||||
* @return Returns the file filter
|
||||
*/
|
||||
public final String getFileFilter() {
|
||||
return filter;
|
||||
}
|
||||
|
||||
public final static String getSeparator() {
|
||||
return File.separator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new folder
|
||||
*
|
||||
* @return True if successful
|
||||
*/
|
||||
public final boolean createFolder() {
|
||||
if (f.exists()) {
|
||||
return true;
|
||||
}
|
||||
return f.mkdirs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new folder
|
||||
*
|
||||
* @param path The location of the new folder
|
||||
* @return True if successful
|
||||
*/
|
||||
public final static boolean createFolder(String path) {
|
||||
File fl = new File(path);
|
||||
if (fl.exists()) {
|
||||
return true;
|
||||
}
|
||||
return fl.mkdirs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new file
|
||||
*
|
||||
* @return True if file exist or is created
|
||||
*/
|
||||
public final boolean createFile() {
|
||||
boolean createNewFile = true;
|
||||
if (!f.exists()) {
|
||||
try {
|
||||
createFolder(f.getParent());
|
||||
createNewFile = f.createNewFile();
|
||||
} catch (IOException ex) {
|
||||
createNewFile = false;
|
||||
}
|
||||
}
|
||||
return createNewFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the file list at the specified directory location based on filter
|
||||
* contents
|
||||
*
|
||||
* @return An array of Files
|
||||
*/
|
||||
public final File[] getFileList() {
|
||||
|
||||
File[] arrFilesCache;
|
||||
if (filter.isEmpty()) {
|
||||
arrFilesCache = f.listFiles();
|
||||
} else {
|
||||
arrFilesCache = f.listFiles(new FileFilter() {
|
||||
@Override
|
||||
public boolean accept(File pathname) {
|
||||
return pathname.getPath().contains(filter);
|
||||
}
|
||||
});
|
||||
}
|
||||
return arrFilesCache;
|
||||
}
|
||||
|
||||
public final File getOldestFile() {
|
||||
long lngLastAge = new Date().getTime();
|
||||
File oldest = null;
|
||||
File[] arrFiles = getFileList();
|
||||
for (File fi : arrFiles) {
|
||||
if (fi.lastModified() < lngLastAge) {
|
||||
lngLastAge = fi.lastModified();
|
||||
oldest = fi;
|
||||
}
|
||||
}
|
||||
return oldest;
|
||||
}
|
||||
|
||||
public final static void walkFileTree(String path, ArrayList<File> files) {
|
||||
walkFileTree(path, files, "");
|
||||
}
|
||||
|
||||
public final static void walkFileTree(String path, ArrayList<File> files, final String filter) {
|
||||
|
||||
File[] arrFilesCache;
|
||||
File root = new File(path);
|
||||
if (filter.isEmpty()) {
|
||||
arrFilesCache = root.listFiles();
|
||||
} else {
|
||||
arrFilesCache = root.listFiles(new FileFilter() {
|
||||
@Override
|
||||
public boolean accept(File pathname) {
|
||||
return pathname.getPath().contains(filter);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (arrFilesCache == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (File f : arrFilesCache) {
|
||||
if (f.isDirectory()) {
|
||||
walkFileTree(f.getAbsolutePath(), files, filter);
|
||||
} else {
|
||||
files.add(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the supplied list of files, be very carefull with this
|
||||
*
|
||||
* @param files
|
||||
*/
|
||||
public final void deleteFileList(File[] files) {
|
||||
for (File fx : files) {
|
||||
if (fx.isFile()) {
|
||||
boolean delete = fx.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete folder and its contents using specified folder path
|
||||
*
|
||||
* @param folder
|
||||
* @return boolean True if successful
|
||||
*/
|
||||
public final static boolean deleteFolder(String folder) {
|
||||
if (OSFunction.isLinux() && folder.contentEquals("/")) {
|
||||
return false;
|
||||
}
|
||||
return deleteFolder(new File(folder));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a folder and all of its contents works recursively
|
||||
*
|
||||
*/
|
||||
private static boolean deleteFolder(File folder) {
|
||||
if (!folder.exists()) {
|
||||
return false;
|
||||
}
|
||||
for (File fx : folder.listFiles()) {
|
||||
if (fx.isDirectory()) {
|
||||
deleteFolder(fx);
|
||||
} else {
|
||||
boolean delete = fx.delete();
|
||||
}
|
||||
}
|
||||
return folder.delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Wipe folder and its contents using specified folder path
|
||||
*
|
||||
* @param folder
|
||||
*/
|
||||
public final static void secureWipeFolder(String folder) {
|
||||
if (OSFunction.isLinux() && folder.contentEquals("/")) {
|
||||
return;
|
||||
}
|
||||
secureWipeFolder(new File(folder));
|
||||
}
|
||||
|
||||
/**
|
||||
* Wipe folder and its contents using specified File
|
||||
*
|
||||
* @param folder
|
||||
*/
|
||||
public final static void secureWipeFolder(File folder) {
|
||||
if (!folder.exists()) {
|
||||
return;
|
||||
}
|
||||
for (File fx : folder.listFiles()) {
|
||||
if (fx.isDirectory()) {
|
||||
secureWipeFolder(fx);
|
||||
} else {
|
||||
secureWipe(fx);
|
||||
}
|
||||
}
|
||||
folder = renameTo(folder, "0000000");
|
||||
folder.delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Wipe file using specified filename
|
||||
*
|
||||
* @param filename
|
||||
*/
|
||||
public final static void secureWipe(String filename) {
|
||||
secureWipe(new File(filename));
|
||||
}
|
||||
|
||||
/**
|
||||
* Wipe file using specified File
|
||||
*
|
||||
* @param f
|
||||
*/
|
||||
public final static void secureWipe(File f) {
|
||||
|
||||
if (!f.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
FileOutputStream fos = null;
|
||||
byte b[] = new byte[4096];
|
||||
long i = f.length() / 4096;
|
||||
int remainder = (int) (f.length() % 4096);
|
||||
byte r[] = new byte[remainder];
|
||||
try {
|
||||
// Overwrite with zeros
|
||||
fos = new FileOutputStream(f, false);
|
||||
while (i-- > 0) {
|
||||
fos.write(b);
|
||||
fos.flush();
|
||||
}
|
||||
fos.write(r);
|
||||
fos.close();
|
||||
// Zero file length
|
||||
b = new byte[0];
|
||||
fos = new FileOutputStream(f, false);
|
||||
fos.write(b);
|
||||
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(SimpleFile.class
|
||||
.getName()).log(Level.SEVERE, null, ex);
|
||||
} finally {
|
||||
try {
|
||||
if (fos != null) {
|
||||
fos.close();
|
||||
}
|
||||
// Rename file
|
||||
f = renameTo(f, "0000000000");
|
||||
// Delete file
|
||||
f.delete();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final static File renameTo(File f, String newname) {
|
||||
String path = f.getParent();
|
||||
if (path != null) {
|
||||
path += File.separator + newname;
|
||||
File nf = new File(path);
|
||||
if (f.renameTo(nf)) {
|
||||
return nf;
|
||||
}
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy multiple files from one folder to another
|
||||
*
|
||||
* @param from The from path
|
||||
* @param to The to path
|
||||
* @param ignore
|
||||
*/
|
||||
public final static void copyFolderContents(String from, String to, String ignore) {
|
||||
try {
|
||||
File ourFile = new File(from);
|
||||
for (File fx : ourFile.listFiles()) {
|
||||
if (!ignore.contains(fx.getName())) {
|
||||
copyFromTo(fx.getAbsolutePath(), to + fx.getName());
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Logger.getGlobal().logp(Level.WARNING, "SimpleFile", "copyFolderContents()", "", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of filenames, array if populated from the offset value
|
||||
* onwards
|
||||
*
|
||||
* @param offset
|
||||
* @return An array of filenames
|
||||
*/
|
||||
public final String[] getFilenames(int offset) {
|
||||
|
||||
String filename;
|
||||
File[] fileList = getFileList();
|
||||
String[] result = new String[fileList.length + offset];
|
||||
try {
|
||||
for (int i = 0; i < fileList.length; i++) {
|
||||
filename = fileList[i].getName();
|
||||
result[i + offset] = filename.substring(0, filename.indexOf('.'));
|
||||
}
|
||||
return result;
|
||||
} catch (Exception ex) {
|
||||
Logger.getGlobal().logp(Level.WARNING, this.getClass().getName(), "getFilenames(int offset)", "", ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if path exists
|
||||
*
|
||||
* @return Returns true if file exists
|
||||
*/
|
||||
public final boolean exists() {
|
||||
return f.exists();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if path exists
|
||||
*
|
||||
* @param pathname The pathname to check for
|
||||
* @return Returns true if file exists
|
||||
*/
|
||||
public final static boolean exists(String pathname) {
|
||||
return new File(pathname).exists();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes file
|
||||
*
|
||||
* @return Returns true if successful
|
||||
*/
|
||||
public final boolean delete() {
|
||||
return f.delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the specified file
|
||||
*
|
||||
* @param filename
|
||||
* @return Returns true if successful
|
||||
*/
|
||||
public final static boolean delete(String filename) {
|
||||
return new File(filename).delete();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param toname
|
||||
* @return Returns true if successful
|
||||
*/
|
||||
public final boolean renameFile(String toname) {
|
||||
return f.renameTo(new File(toname));
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a buffered file for read
|
||||
*
|
||||
* @return Returns null if failed
|
||||
*/
|
||||
public final BufferedReader openBufferedRead() {
|
||||
|
||||
try {
|
||||
br = new BufferedReader(new FileReader(f));
|
||||
return br;
|
||||
} catch (FileNotFoundException ex) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this if you need access to a file within a jar
|
||||
*
|
||||
*/
|
||||
public final void openBufferedResource() {
|
||||
|
||||
try {
|
||||
String path = f.getPath();
|
||||
path = path.replace('\\', '/');
|
||||
InputStream is = getClass().getResourceAsStream(path);
|
||||
br = new BufferedReader(new InputStreamReader(is));
|
||||
} catch (Exception ex) {
|
||||
Logger.getGlobal().logp(Level.WARNING, this.getClass().getName(), "openBufferedRead(int filehandle)", "", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a buffered file for append
|
||||
*
|
||||
*/
|
||||
public final void openBufferedAppend() {
|
||||
|
||||
try {
|
||||
bw = new BufferedWriter(new FileWriter(f, true));
|
||||
} catch (IOException ex) {
|
||||
Logger.getGlobal().logp(Level.WARNING, this.getClass().getName(), "openBufferedAppend()", "", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a single line from a text file
|
||||
*
|
||||
* @return Contents as String
|
||||
*/
|
||||
public final String readLine() {
|
||||
try {
|
||||
return br.readLine();
|
||||
} catch (IOException ex) {
|
||||
Logger.getGlobal().logp(Level.WARNING, this.getClass().getName(), "readLine(int filehandle)", "", ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read bytes from previously opened BufferedReader
|
||||
*
|
||||
* @return Returns the entire contents from a file
|
||||
*/
|
||||
public final String readEntireFile() {
|
||||
|
||||
char[] cb = new char[blockreadsize];
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int bytes;
|
||||
try {
|
||||
while (br.ready()) {
|
||||
bytes = br.read(cb);
|
||||
sb.append(cb, 0, bytes);
|
||||
}
|
||||
return sb.toString();
|
||||
} catch (IOException ex) {
|
||||
Logger.getGlobal().logp(Level.WARNING, this.getClass().getName(), "readEntireFile()", "", ex);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public final FileInputStream openFileInputStream(String filename) {
|
||||
try {
|
||||
return new FileInputStream(new File(filename));
|
||||
} catch (FileNotFoundException ex) {
|
||||
Logger.getGlobal().logp(Level.WARNING, this.getClass().getName(), "openFileInputStream()", "", ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a file output stream
|
||||
*
|
||||
* @return Returns Opened file output stream
|
||||
*/
|
||||
public final FileOutputStream openFileOutputStream() {
|
||||
try {
|
||||
return new FileOutputStream(f);
|
||||
} catch (FileNotFoundException ex) {
|
||||
Logger.getGlobal().logp(Level.WARNING, this.getClass().getName(), "openFileOutputStream()", "", ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a buffered file for write
|
||||
*
|
||||
*/
|
||||
public final void openBufferedWrite() {
|
||||
|
||||
try {
|
||||
bw = new BufferedWriter(new FileWriter(f));
|
||||
} catch (IOException ex) {
|
||||
Logger.getGlobal().logp(Level.WARNING, this.getClass().getName(), "openBufferedWrite()", "", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public final void flushWriter() {
|
||||
try {
|
||||
bw.flush();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write to a previously opened output file
|
||||
*
|
||||
* @param data The data to be written
|
||||
* @param newlines The number of newlines to generate
|
||||
*/
|
||||
public final void writeFile(String data, int newlines) {
|
||||
|
||||
try {
|
||||
bw.write(data);
|
||||
while (newlines > 0) {
|
||||
bw.newLine();
|
||||
newlines--;
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
Logger.getGlobal().logp(Level.WARNING, this.getClass().getName(),
|
||||
"writeToFile(" + data + "," + String.valueOf(newlines) + ")", "", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write to a previously opened output file
|
||||
*
|
||||
* @param data The character data to be written
|
||||
* @param nochars
|
||||
*/
|
||||
public final void writeFile(char[] data, int nochars) {
|
||||
|
||||
try {
|
||||
bw.write(data, 0, nochars);
|
||||
} catch (IOException ex) {
|
||||
Logger.getGlobal().logp(Level.WARNING, this.getClass().getName(), "writeToFile()", "", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy file to
|
||||
*
|
||||
* @param frompath
|
||||
* @param topath
|
||||
*/
|
||||
public final static void copyFromTo(String frompath, String topath) {
|
||||
try {
|
||||
Path source = new File(frompath).toPath();
|
||||
Path dest = new File(topath).toPath();
|
||||
Files.copy(source, dest, StandardCopyOption.REPLACE_EXISTING);
|
||||
} catch (IOException ex) {
|
||||
Logger.getGlobal().logp(Level.WARNING, "SimpleFile", "copyFromTo()", "", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public final static void mergeFiles(String srcpath1, String srcpath2, String destpath) {
|
||||
try (OutputStream os = new FileOutputStream(new File(destpath))) {
|
||||
Path source = new File(srcpath1).toPath();
|
||||
Files.copy(source, os);
|
||||
source = new File(srcpath2).toPath();
|
||||
Files.copy(source, os);
|
||||
os.close();
|
||||
} catch (IOException ex) {
|
||||
Logger.getGlobal().logp(Level.WARNING, "SimpleFile", "mergeFiles", "", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the age of a specified file
|
||||
*
|
||||
* @param filepath
|
||||
* @param period
|
||||
* @return Age of file as float
|
||||
*/
|
||||
public final static float getAgeOfFile(String filepath, int period) {
|
||||
File fx = new File(filepath);
|
||||
if (!fx.exists()) {
|
||||
return -1;
|
||||
}
|
||||
float fltAge = System.currentTimeMillis() - fx.lastModified();
|
||||
switch (period) {
|
||||
case PERIOD_MINUTES:
|
||||
return fltAge / 60000;
|
||||
case PERIOD_HOURS:
|
||||
return fltAge / (60000 * 60);
|
||||
case PERIOD_DAYS:
|
||||
return fltAge / (60000 * 60 * 24);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see our file is older in minutes, returns true if it is
|
||||
*
|
||||
* @param filename
|
||||
* @param minutes
|
||||
* @return boolean
|
||||
*/
|
||||
public final static boolean isMinutesOlder(String filename, long minutes) {
|
||||
long lngAge = System.currentTimeMillis() - new File(filename).lastModified();
|
||||
return lngAge > (60000 * minutes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see our file is older in hours, returns true if it is
|
||||
*
|
||||
* @param filename
|
||||
* @param hours
|
||||
* @return boolean
|
||||
*/
|
||||
public final static boolean isHoursOlder(String filename, long hours) {
|
||||
long lngAge = System.currentTimeMillis() - new File(filename).lastModified();
|
||||
return lngAge > (60000 * 60 * hours);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see our file is older in days, returns true if it is
|
||||
*
|
||||
* @param filename
|
||||
* @param days
|
||||
* @return boolean
|
||||
*/
|
||||
public final static boolean isDaysOlder(String filename, long days) {
|
||||
long lngAge = System.currentTimeMillis() - new File(filename).lastModified();
|
||||
return lngAge > (60000 * 60 * 24 * days);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a zipstream. returns false if it fails
|
||||
*
|
||||
* @param level
|
||||
* @return an open zipstream
|
||||
*/
|
||||
public final boolean openZipStream(int level) {
|
||||
try {
|
||||
zos = new ZipOutputStream(new FileOutputStream(f.getAbsolutePath()));
|
||||
if (level < 0 || level > 9) {
|
||||
level = 6;
|
||||
}
|
||||
zos.setLevel(level);
|
||||
return true;
|
||||
} catch (FileNotFoundException ex) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close a zip stream
|
||||
*/
|
||||
public final void closeZipStream() {
|
||||
if (zos != null) {
|
||||
try {
|
||||
zos.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final static void compress(String source, String dest) {
|
||||
final Path pathSource = Paths.get(source);
|
||||
try {
|
||||
final ZipOutputStream outputStream = new ZipOutputStream(new FileOutputStream(dest));
|
||||
Files.walkFileTree(pathSource, new SimpleFileVisitor<Path>() {
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attributes) {
|
||||
try {
|
||||
Path targetFile = pathSource.relativize(file);
|
||||
outputStream.putNextEntry(new ZipEntry(targetFile.toString()));
|
||||
byte[] bytes = Files.readAllBytes(file);
|
||||
outputStream.write(bytes, 0, bytes.length);
|
||||
outputStream.closeEntry();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
});
|
||||
outputStream.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add files to a zip file
|
||||
*
|
||||
* @param srcfiles An array of Files
|
||||
* @return boolean True if successful
|
||||
*/
|
||||
public final boolean addFilesToZip(File... srcfiles) {
|
||||
FileInputStream in = null;
|
||||
if (srcfiles == null || srcfiles.length == 0) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
for (File fx : srcfiles) {
|
||||
in = new FileInputStream(fx);
|
||||
// name the file inside the zip file
|
||||
zos.putNextEntry(new ZipEntry(fx.getName()));
|
||||
byte[] b = Files.readAllBytes(Paths.get(fx.getAbsolutePath()));
|
||||
zos.write(b, 0, b.length);
|
||||
in.close();
|
||||
}
|
||||
return true;
|
||||
} catch (IOException ex) {
|
||||
} finally {
|
||||
try {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts a zip file to a supplied location
|
||||
*
|
||||
* @param destpath Destination for contents of zip file
|
||||
* @return True if successful
|
||||
*/
|
||||
public final boolean extractZipTo(String destpath) {
|
||||
FileOutputStream fos;
|
||||
final int BUFFER = 2048;
|
||||
try {
|
||||
FileInputStream fis = new FileInputStream(f);
|
||||
try (ZipInputStream zin = new ZipInputStream(new BufferedInputStream(fis))) {
|
||||
ZipEntry entry;
|
||||
while ((entry = zin.getNextEntry()) != null) {
|
||||
int count;
|
||||
byte data[] = new byte[BUFFER];
|
||||
try {
|
||||
fos = new FileOutputStream(destpath + File.separator + entry.getName());
|
||||
} catch (FileNotFoundException ex) {
|
||||
continue;
|
||||
}
|
||||
try (BufferedOutputStream dest = new BufferedOutputStream(fos, 2048)) {
|
||||
while ((count = zin.read(data, 0, BUFFER)) != -1) {
|
||||
dest.write(data, 0, count);
|
||||
}
|
||||
dest.flush();
|
||||
dest.close();
|
||||
}
|
||||
fos.close();
|
||||
}
|
||||
zin.close();
|
||||
fis.close();
|
||||
}
|
||||
return true;
|
||||
} catch (IOException ex) {
|
||||
Logger.getGlobal().logp(Level.WARNING, this.getClass().getName(), "extractZipTo()", "", ex);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public final static boolean objectWrite(String filepath, Object o) {
|
||||
ObjectOutputStream oos = null;
|
||||
try {
|
||||
oos = new ObjectOutputStream(new FileOutputStream(new File(filepath)));
|
||||
} catch (FileNotFoundException ex) {
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
if (oos == null) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
oos.writeObject(o);
|
||||
oos.close();
|
||||
return true;
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public final static Object objectRead(String filepath, Object defObject) {
|
||||
ObjectInputStream oos = null;
|
||||
try {
|
||||
oos = new ObjectInputStream(new FileInputStream(new File(filepath)));
|
||||
} catch (FileNotFoundException ex) {
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
if (oos == null) {
|
||||
return defObject;
|
||||
}
|
||||
Object result = defObject;
|
||||
try {
|
||||
result = oos.readObject();
|
||||
} catch (IOException | ClassNotFoundException ex) {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
289
src/lib/SimpleProps.java
Normal file
289
src/lib/SimpleProps.java
Normal file
|
@ -0,0 +1,289 @@
|
|||
/*
|
||||
* 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 lib;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Properties;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alistair Neil <info@dazzleships.net>
|
||||
*/
|
||||
public final class SimpleProps {
|
||||
|
||||
private final File fileStore;
|
||||
private final String comment;
|
||||
private final ArrayList<String> alChanged;
|
||||
private boolean boolDefaultEnabled;
|
||||
private final Properties defProps = new Properties();
|
||||
private Properties appProps;
|
||||
|
||||
/**
|
||||
* Constructor, requires
|
||||
*
|
||||
* @param filepath
|
||||
* @param comment
|
||||
*/
|
||||
public SimpleProps(String filepath, String comment) {
|
||||
alChanged = new ArrayList<>();
|
||||
fileStore = new File(filepath);
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/disable default mode
|
||||
*
|
||||
* @param enabled
|
||||
*/
|
||||
public void setDefaultModeEnabled(boolean enabled) {
|
||||
boolDefaultEnabled = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a long number property
|
||||
*
|
||||
* @param property
|
||||
* @param num
|
||||
*/
|
||||
public void setLong(String property, long num) {
|
||||
String value = String.valueOf(num);
|
||||
setString(property, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a long number property
|
||||
*
|
||||
* @param property
|
||||
* @return A long number
|
||||
*/
|
||||
public long getLong(String property) {
|
||||
try {
|
||||
if (boolDefaultEnabled) {
|
||||
return Long.parseLong(defProps.getProperty(property));
|
||||
} else {
|
||||
return Long.parseLong(appProps.getProperty(property));
|
||||
}
|
||||
} catch (NumberFormatException ex) {
|
||||
Logger.getGlobal().logp(Level.WARNING, this.getClass().getName(), "getLong", "", ex);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a integer number property
|
||||
*
|
||||
* @param property
|
||||
* @param num
|
||||
*/
|
||||
public void setInt(String property, int num) {
|
||||
String value = String.valueOf(num);
|
||||
setString(property, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an integer number property
|
||||
*
|
||||
* @param property
|
||||
* @return an integer
|
||||
*/
|
||||
public int getInt(String property) {
|
||||
try {
|
||||
if (boolDefaultEnabled) {
|
||||
return Integer.parseInt(defProps.getProperty(property));
|
||||
} else {
|
||||
return Integer.parseInt(appProps.getProperty(property));
|
||||
}
|
||||
} catch (NumberFormatException ex) {
|
||||
Logger.getGlobal().logp(Level.WARNING, this.getClass().getName(), "getInt", "", ex);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a boolean property
|
||||
*
|
||||
* @param property
|
||||
* @param enabled
|
||||
*/
|
||||
public void setBool(String property, boolean enabled) {
|
||||
if (enabled) {
|
||||
setString(property, "true");
|
||||
} else {
|
||||
setString(property, "false");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a boolean property
|
||||
*
|
||||
* @param property
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean getBool(String property) {
|
||||
try {
|
||||
String result;
|
||||
if (boolDefaultEnabled) {
|
||||
result = defProps.getProperty(property).toLowerCase();
|
||||
} else {
|
||||
result = appProps.getProperty(property).toLowerCase();
|
||||
}
|
||||
return result.contentEquals("true");
|
||||
} catch (Exception ex) {
|
||||
Logger.getGlobal().logp(Level.WARNING, this.getClass().getName(), "getBool", "", ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a String property
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
* @return String
|
||||
*/
|
||||
public Object setString(String key, String value) {
|
||||
value = value.trim();
|
||||
if (boolDefaultEnabled) {
|
||||
return defProps.setProperty(key, value);
|
||||
}
|
||||
String prop = appProps.getProperty(key);
|
||||
if (prop == null) {
|
||||
prop = "null";
|
||||
}
|
||||
if (prop.contentEquals(value)) {
|
||||
if (alChanged.contains(key)) {
|
||||
alChanged.remove(key);
|
||||
}
|
||||
} else {
|
||||
if (!alChanged.contains(key)) {
|
||||
alChanged.add(key);
|
||||
}
|
||||
}
|
||||
return appProps.setProperty(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a String property
|
||||
*
|
||||
* @param key
|
||||
* @return String or null
|
||||
*/
|
||||
public String getString(String key) {
|
||||
try {
|
||||
String prop;
|
||||
if (boolDefaultEnabled) {
|
||||
prop = defProps.getProperty(key);
|
||||
} else {
|
||||
prop = appProps.getProperty(key);
|
||||
}
|
||||
if (prop == null) {
|
||||
prop = "";
|
||||
}
|
||||
return prop;
|
||||
} catch (Exception ex) {
|
||||
Logger.getGlobal().logp(Level.WARNING, this.getClass().getName(), "getString", "", ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save to xml file
|
||||
*/
|
||||
public void save() {
|
||||
alChanged.clear();
|
||||
OutputStream os = null;
|
||||
try {
|
||||
os = new FileOutputStream(fileStore);
|
||||
appProps.storeToXML(os, comment);
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(SimpleProps.class.getName()).log(Level.SEVERE, null, ex);
|
||||
} finally {
|
||||
try {
|
||||
if (os != null) {
|
||||
os.close();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load from xml file
|
||||
*/
|
||||
public void load() {
|
||||
InputStream is = null;
|
||||
try {
|
||||
if (!fileStore.exists()) {
|
||||
fileStore.getParentFile().mkdirs();
|
||||
fileStore.createNewFile();
|
||||
save();
|
||||
}
|
||||
is = new FileInputStream(fileStore);
|
||||
appProps.loadFromXML(is);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(SimpleProps.class.getName()).log(Level.SEVERE, null, ex);
|
||||
} finally {
|
||||
try {
|
||||
if (is != null) {
|
||||
is.close();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
}
|
||||
alChanged.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the properties file store
|
||||
*
|
||||
* @return true if successful
|
||||
*/
|
||||
public boolean delete() {
|
||||
if (fileStore.exists()) {
|
||||
return fileStore.delete();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a comma separated list of properties that were changed
|
||||
*
|
||||
* @return A String of property keys that were changed
|
||||
*/
|
||||
public String getChangedProperties() {
|
||||
return alChanged.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset to defaults
|
||||
*/
|
||||
public void resetToDefaults() {
|
||||
appProps = new Properties(defProps);
|
||||
alChanged.clear();
|
||||
}
|
||||
|
||||
}
|
502
src/lib/SwingTrayIcon.java
Normal file
502
src/lib/SwingTrayIcon.java
Normal file
|
@ -0,0 +1,502 @@
|
|||
/*
|
||||
* 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 lib;
|
||||
|
||||
import java.awt.AWTEvent;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.Insets;
|
||||
import java.awt.MouseInfo;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.SystemTray;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.TrayIcon;
|
||||
import java.awt.Window.Type;
|
||||
import java.awt.event.AWTEventListener;
|
||||
import java.awt.event.ComponentEvent;
|
||||
import java.awt.event.ComponentListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.JToolTip;
|
||||
import javax.swing.JWindow;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.event.PopupMenuEvent;
|
||||
import javax.swing.event.PopupMenuListener;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alistair Neil <info@dazzleships.net>
|
||||
*/
|
||||
public final class SwingTrayIcon {
|
||||
|
||||
private InfoTip infoToolTip;
|
||||
private JDialog jdiagPopup;
|
||||
private TrayPopupMenu trayPopupMenu;
|
||||
private AWTEventListener awtEventListen;
|
||||
private volatile boolean mouseExited = false;
|
||||
private SystemTray st = null;
|
||||
private GraphicsConfiguration gc = null;
|
||||
private Point mouseloc;
|
||||
private TrayIcon ti;
|
||||
private boolean loaded;
|
||||
|
||||
public SwingTrayIcon(GraphicsConfiguration gc, String resourcepath) {
|
||||
loaded = false;
|
||||
if (!SystemTray.isSupported()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
st = SystemTray.getSystemTray();
|
||||
ClassLoader cl = this.getClass().getClassLoader();
|
||||
ti = new TrayIcon(new javax.swing.ImageIcon(cl.getResource(resourcepath)).getImage());
|
||||
} catch (Exception ex) {
|
||||
return;
|
||||
}
|
||||
ti.setImageAutoSize(true);
|
||||
this.gc = gc;
|
||||
initDiagPopup();
|
||||
if (OSFunction.isLinux()) {
|
||||
infoToolTip = new InfoTip();
|
||||
infoToolTip.setFocusable(false);
|
||||
}
|
||||
initMouseHandler();
|
||||
}
|
||||
|
||||
private void initMouseHandler() {
|
||||
// We need a global mouse listener due to the way TrayIcon intercepts
|
||||
// mousemovements but doesnt feed all the events back to us
|
||||
awtEventListen = new java.awt.event.AWTEventListener() {
|
||||
@Override
|
||||
public void eventDispatched(AWTEvent event) {
|
||||
// Catch mouse event so we can easily get coords
|
||||
final MouseEvent e = (MouseEvent) event;
|
||||
if (!(e.getSource() instanceof TrayIcon)) {
|
||||
return;
|
||||
}
|
||||
mouseloc = MouseInfo.getPointerInfo().getLocation();
|
||||
switch (e.getID()) {
|
||||
case MouseEvent.MOUSE_ENTERED:
|
||||
if (infoToolTip == null || trayPopupMenu.isVisible()) {
|
||||
return;
|
||||
}
|
||||
mouseExited = false;
|
||||
// Raise tooltip
|
||||
Thread t = new Thread(new java.lang.Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
if (!trayPopupMenu.isVisible() && !mouseExited) {
|
||||
infoToolTip.setLocation(getPlacementPosition(mouseloc, infoToolTip.getWidth(), infoToolTip.getHeight(), true));
|
||||
infoToolTip.setVisible(true);
|
||||
} else {
|
||||
infoToolTip.setVisible(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
t.start();
|
||||
break;
|
||||
|
||||
case MouseEvent.MOUSE_EXITED:
|
||||
mouseExited = true;
|
||||
if (infoToolTip != null) {
|
||||
infoToolTip.setVisible(false);
|
||||
}
|
||||
break;
|
||||
|
||||
case MouseEvent.MOUSE_RELEASED:
|
||||
if (e.getButton() == MouseEvent.BUTTON3) {
|
||||
if (infoToolTip != null) {
|
||||
infoToolTip.setVisible(false);
|
||||
}
|
||||
mouseExited = true;
|
||||
raisePopupMenu(mouseloc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
Toolkit.getDefaultToolkit().addAWTEventListener(awtEventListen, AWTEvent.MOUSE_EVENT_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise our hidden dialog which we use to grab focus so that the
|
||||
* popumenu can be closed whenever we click on the desktop
|
||||
*/
|
||||
private void initDiagPopup() {
|
||||
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
jdiagPopup = new JDialog();
|
||||
jdiagPopup.setUndecorated(true);
|
||||
jdiagPopup.setMinimumSize(new Dimension(0, 0));
|
||||
jdiagPopup.setBounds(new Rectangle(0, 0));
|
||||
jdiagPopup.setType(Type.POPUP);
|
||||
jdiagPopup.setFocusable(false);
|
||||
jdiagPopup.setAutoRequestFocus(false);
|
||||
try {
|
||||
jdiagPopup.setLocation(new Point(screenSize.width, screenSize.height));
|
||||
jdiagPopup.setOpacity(0);
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
jdiagPopup.addComponentListener(new java.awt.event.ComponentListener() {
|
||||
|
||||
@Override
|
||||
public void componentResized(ComponentEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentMoved(ComponentEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentShown(ComponentEvent e) {
|
||||
trayPopupMenu.setVisible(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentHidden(ComponentEvent e) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
// Remove from system tray
|
||||
unload();
|
||||
// Cleanup assets that may prevent shutdown
|
||||
if (ti != null) {
|
||||
for (MouseListener ml : ti.getMouseListeners()) {
|
||||
ti.removeMouseListener(ml);
|
||||
}
|
||||
}
|
||||
if (awtEventListen != null) {
|
||||
Toolkit.getDefaultToolkit().removeAWTEventListener(awtEventListen);
|
||||
awtEventListen = null;
|
||||
}
|
||||
if (trayPopupMenu != null) {
|
||||
for (PopupMenuListener pml : trayPopupMenu.getPopupMenuListeners()) {
|
||||
trayPopupMenu.removePopupMenuListener(pml);
|
||||
}
|
||||
trayPopupMenu = null;
|
||||
}
|
||||
if (jdiagPopup != null) {
|
||||
for (ComponentListener cl : jdiagPopup.getComponentListeners()) {
|
||||
jdiagPopup.removeComponentListener(cl);
|
||||
}
|
||||
jdiagPopup.dispose();
|
||||
jdiagPopup = null;
|
||||
}
|
||||
if (infoToolTip != null) {
|
||||
infoToolTip.dispose();
|
||||
infoToolTip = null;
|
||||
}
|
||||
st = null;
|
||||
}
|
||||
|
||||
public void disable() {
|
||||
unload();
|
||||
st = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set tray right click popup
|
||||
*
|
||||
* @param tpm
|
||||
*/
|
||||
public void setTrayPopupMenu(TrayPopupMenu tpm) {
|
||||
trayPopupMenu = tpm;
|
||||
if (tpm == null || ti == null) {
|
||||
return;
|
||||
}
|
||||
trayPopupMenu.setFocusable(false);
|
||||
// Add popup menu listener to detect when it is hidden
|
||||
trayPopupMenu.addPopupMenuListener(new javax.swing.event.PopupMenuListener() {
|
||||
|
||||
@Override
|
||||
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
|
||||
jdiagPopup.setVisible(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void popupMenuCanceled(PopupMenuEvent e) {
|
||||
jdiagPopup.setVisible(false);
|
||||
}
|
||||
});
|
||||
trayPopupMenu.setEnabled(true);
|
||||
trayPopupMenu.setInvoker(jdiagPopup);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open tray popup
|
||||
*
|
||||
*/
|
||||
private void raisePopupMenu(Point mouseloc) {
|
||||
if (trayPopupMenu != null) {
|
||||
// Set onscreen location of trayPopup
|
||||
Point p = getPlacementPosition(mouseloc, trayPopupMenu.getVisibleRect().width, trayPopupMenu.getHeight(), false);
|
||||
trayPopupMenu.setLocation(p);
|
||||
jdiagPopup.setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate onscreen placement position based on mouse pointer position
|
||||
*
|
||||
* @param boxwidth
|
||||
* @param boxheight
|
||||
* @param centre
|
||||
* @return Point
|
||||
*/
|
||||
private Point getPlacementPosition(Point coords, int boxwidth, int boxheight, boolean istooltip) {
|
||||
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
Insets screenInsets;
|
||||
Point result = new Point();
|
||||
double x, y, limit;
|
||||
int yoff = 0;
|
||||
|
||||
if (OSFunction.isLinux()) {
|
||||
screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(gc);
|
||||
int i = screenInsets.bottom + screenInsets.left + screenInsets.right
|
||||
+ screenInsets.top;
|
||||
// If all insets are zero then offset them all by 32, bit of a hack
|
||||
// for desktops that allow intelligent hiding of tray panel
|
||||
if (i == 0) {
|
||||
screenInsets = new Insets(32, 32, 32, 32);
|
||||
}
|
||||
} else {
|
||||
screenInsets = new Insets(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
// Calculate X axis positioning
|
||||
x = coords.x;
|
||||
if (x > (screenSize.getWidth() / 2)) {
|
||||
limit = screenSize.width - screenInsets.right;
|
||||
if (x + boxwidth > limit) {
|
||||
if (screenInsets.right == 0) {
|
||||
x -= boxwidth;
|
||||
} else {
|
||||
x = limit - boxwidth;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
limit = screenInsets.left;
|
||||
if (x < limit) {
|
||||
x = limit;
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate Y axis positioning
|
||||
y = coords.y;
|
||||
if (y > (screenSize.getHeight() / 2)) {
|
||||
// Bottom
|
||||
if (istooltip && screenInsets.bottom == 0) {
|
||||
yoff = (int) ((ti.getSize().getHeight() + 1) / 2);
|
||||
}
|
||||
} else // Bottom
|
||||
{
|
||||
if (istooltip && screenInsets.top == 0) {
|
||||
yoff = (int) ((ti.getSize().getHeight() + 1) / 2);
|
||||
}
|
||||
}
|
||||
|
||||
if (screenInsets.top != 0 && y < screenInsets.top) {
|
||||
y += (screenInsets.top - y);
|
||||
}
|
||||
limit = screenSize.height - screenInsets.bottom;
|
||||
if (y + yoff + boxheight > limit) {
|
||||
if (yoff > 0) {
|
||||
y -= (boxheight + yoff);
|
||||
} else if (screenInsets.bottom == 0) {
|
||||
y -= (boxheight + yoff);
|
||||
} else {
|
||||
y = limit - boxheight;
|
||||
}
|
||||
} else {
|
||||
y += yoff;
|
||||
}
|
||||
result.setLocation(x, y);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set info tip text
|
||||
*
|
||||
* @param text
|
||||
*/
|
||||
public void setInfoTip(String text) {
|
||||
if (ti == null) {
|
||||
return;
|
||||
}
|
||||
if (OSFunction.isLinux()) {
|
||||
// Check to see if tay icon need reloaded
|
||||
if (SystemTray.isSupported() && isLoaded() && st.getTrayIcons().length == 0) {
|
||||
try {
|
||||
st.add(ti);
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
}
|
||||
// Update tooltip (Linux only)
|
||||
if (infoToolTip != null) {
|
||||
infoToolTip.setText(text);
|
||||
if (infoToolTip.isVisible()) {
|
||||
infoToolTip.setLocation(getPlacementPosition(mouseloc, infoToolTip.getWidth(), infoToolTip.getHeight(), true));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Update tooltip (Windows Only)
|
||||
ti.setToolTip(text);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display desktop message (Windows only)
|
||||
*
|
||||
* @param title
|
||||
* @param body
|
||||
*/
|
||||
public void displayMessage(String title, String body) {
|
||||
if (ti != null) {
|
||||
ti.displayMessage(title, body, TrayIcon.MessageType.INFO);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load tray icon
|
||||
*/
|
||||
public void load() {
|
||||
// I know this looks odd but it is required for onscreen positioning
|
||||
// of the tray popup to work
|
||||
if (trayPopupMenu != null) {
|
||||
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
trayPopupMenu.setLocation(screenSize.height, screenSize.width);
|
||||
trayPopupMenu.setVisible(true);
|
||||
trayPopupMenu.setVisible(false);
|
||||
}
|
||||
// Add this tray icon to system tray
|
||||
try {
|
||||
if (st != null) {
|
||||
st.add(ti);
|
||||
loaded = true;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
loaded = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unload Tray icon
|
||||
*/
|
||||
public void unload() {
|
||||
// Remove the tray icon from system tray
|
||||
if (st != null) {
|
||||
st.remove(ti);
|
||||
}
|
||||
loaded = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a mouse listener
|
||||
*
|
||||
* @param ml
|
||||
*/
|
||||
public void addMouseListener(MouseListener ml) {
|
||||
if (ti != null) {
|
||||
ti.addMouseListener(ml);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is tray icon loaded
|
||||
*
|
||||
* @return ture if it is
|
||||
*/
|
||||
public boolean isLoaded() {
|
||||
return loaded;
|
||||
}
|
||||
|
||||
public boolean isSupported() {
|
||||
return st != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Info tip object
|
||||
*/
|
||||
private static final class InfoTip extends JWindow {
|
||||
|
||||
JTextArea jta;
|
||||
Pattern p = Pattern.compile("\n");
|
||||
|
||||
public InfoTip() {
|
||||
initInfoTip();
|
||||
}
|
||||
|
||||
private void initInfoTip() {
|
||||
setType(Type.POPUP);
|
||||
jta = new JTextArea();
|
||||
add(jta);
|
||||
JToolTip jtt = jta.createToolTip();
|
||||
jta.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY));
|
||||
jta.setBackground(new Color(jtt.getBackground().getRGB()));
|
||||
jta.setForeground(new Color(jtt.getForeground().getRGB()));
|
||||
setBackground(jta.getBackground());
|
||||
jta.setOpaque(true);
|
||||
jta.setEditable(false);
|
||||
jta.setLineWrap(true);
|
||||
jta.setWrapStyleWord(true);
|
||||
jta.setVisible(true);
|
||||
setEnabled(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set info tip text
|
||||
*
|
||||
* @param text
|
||||
*/
|
||||
public void setText(String text) {
|
||||
String[] strs = p.split(text);
|
||||
String largest = "";
|
||||
int longest = 0;
|
||||
int width;
|
||||
for (String s : strs) {
|
||||
width = jta.getFontMetrics(jta.getFont()).stringWidth(s);
|
||||
if (width > longest) {
|
||||
largest = s;
|
||||
longest = width;
|
||||
}
|
||||
}
|
||||
jta.setText(" " + text.replace("\n", "\n "));
|
||||
width = jta.getFontMetrics(jta.getFont()).stringWidth(largest + "XXX");
|
||||
int lineheight = jta.getFontMetrics(jta.getFont()).getHeight() + 1;
|
||||
int boxheight = jta.getLineCount() * (lineheight);
|
||||
setSize(width, boxheight);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
93
src/lib/TextResourceDialog.form
Normal file
93
src/lib/TextResourceDialog.form
Normal file
|
@ -0,0 +1,93 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.5" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
|
||||
<Properties>
|
||||
<Property name="defaultCloseOperation" type="int" value="2"/>
|
||||
<Property name="resizable" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<SyntheticProperties>
|
||||
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
|
||||
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
|
||||
</SyntheticProperties>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jScrollPane1" max="32767" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="jButtonLaunchURL" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="jButtonClose" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jScrollPane1" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jButtonClose" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jButtonLaunchURL" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTextArea" name="jTextArea">
|
||||
<Properties>
|
||||
<Property name="editable" type="boolean" value="false"/>
|
||||
<Property name="columns" type="int" value="40"/>
|
||||
<Property name="lineWrap" type="boolean" value="true"/>
|
||||
<Property name="rows" type="int" value="20"/>
|
||||
<Property name="text" type="java.lang.String" value="
"/>
|
||||
<Property name="wrapStyleWord" type="boolean" value="true"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JButton" name="jButtonClose">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Close"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButtonCloseActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="jButtonLaunchURL">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="URL Desc"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButtonLaunchURLActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
169
src/lib/TextResourceDialog.java
Normal file
169
src/lib/TextResourceDialog.java
Normal file
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
* 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 lib;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alistair Neil <info@dazzleships.net>
|
||||
*/
|
||||
public class TextResourceDialog extends javax.swing.JDialog {
|
||||
|
||||
private String strUrl;
|
||||
|
||||
/**
|
||||
* Creates new License Dialog
|
||||
*
|
||||
* @param parent
|
||||
* @param modal
|
||||
*/
|
||||
public TextResourceDialog(java.awt.Frame parent, boolean modal) {
|
||||
super(parent, modal);
|
||||
initComponents();
|
||||
jTextArea.setCaretPosition(0);
|
||||
jButtonLaunchURL.setVisible(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the browser url for unnoficial translation
|
||||
*
|
||||
* @param url
|
||||
*/
|
||||
public void setButtonURL(String url) {
|
||||
strUrl = url;
|
||||
jButtonLaunchURL.setVisible(url != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the license text
|
||||
*
|
||||
* @return Text
|
||||
*/
|
||||
public String getText() {
|
||||
return jTextArea.getText();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the license text
|
||||
*
|
||||
* @param text
|
||||
*/
|
||||
public void setText(String text) {
|
||||
jTextArea.setText(text);
|
||||
jTextArea.setCaretPosition(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the text on the Close button
|
||||
*
|
||||
* @param text
|
||||
*/
|
||||
public void setCloseButtonText(String text) {
|
||||
jButtonClose.setText(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the text on the Close button
|
||||
*
|
||||
* @param text
|
||||
*/
|
||||
public void setURLButtonText(String text) {
|
||||
jButtonLaunchURL.setText(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
|
||||
jScrollPane1 = new javax.swing.JScrollPane();
|
||||
jTextArea = new javax.swing.JTextArea();
|
||||
jButtonClose = new javax.swing.JButton();
|
||||
jButtonLaunchURL = new javax.swing.JButton();
|
||||
|
||||
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
|
||||
setResizable(false);
|
||||
|
||||
jTextArea.setEditable(false);
|
||||
jTextArea.setColumns(40);
|
||||
jTextArea.setLineWrap(true);
|
||||
jTextArea.setRows(20);
|
||||
jTextArea.setText("\n");
|
||||
jTextArea.setWrapStyleWord(true);
|
||||
jScrollPane1.setViewportView(jTextArea);
|
||||
|
||||
jButtonClose.setText("Close");
|
||||
jButtonClose.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
jButtonCloseActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jButtonLaunchURL.setText("URL Desc");
|
||||
jButtonLaunchURL.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
jButtonLaunchURLActionPerformed(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(jButtonLaunchURL)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(jButtonClose)))
|
||||
.addContainerGap())
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(jScrollPane1)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jButtonClose)
|
||||
.addComponent(jButtonLaunchURL))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
pack();
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void jButtonCloseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonCloseActionPerformed
|
||||
dispose();
|
||||
}//GEN-LAST:event_jButtonCloseActionPerformed
|
||||
|
||||
private void jButtonLaunchURLActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonLaunchURLActionPerformed
|
||||
Utilities.openFileExternally(strUrl);
|
||||
}//GEN-LAST:event_jButtonLaunchURLActionPerformed
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton jButtonClose;
|
||||
private javax.swing.JButton jButtonLaunchURL;
|
||||
private javax.swing.JScrollPane jScrollPane1;
|
||||
private javax.swing.JTextArea jTextArea;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
63
src/lib/TrayPopupMenu.java
Normal file
63
src/lib/TrayPopupMenu.java
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* 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 lib;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.UIManager;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alistair Neil <info@dazzleships.net>
|
||||
*/
|
||||
public class TrayPopupMenu extends JPopupMenu {
|
||||
|
||||
private Color bg;
|
||||
|
||||
public TrayPopupMenu() {
|
||||
super();
|
||||
bg = super.getBackground();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JMenuItem add(JMenuItem mi) {
|
||||
mi.setForeground(new Color(UIManager.getColor("MenuItem.foreground").getRGB()));
|
||||
super.add(mi);
|
||||
return mi;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setForeground(Color fg) {
|
||||
super.setForeground(fg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackground(Color bg) {
|
||||
super.setBackground(bg);
|
||||
this.bg = bg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintComponent(final Graphics g) {
|
||||
g.setColor(new Color(bg.getRGB()));
|
||||
g.fillRect(0, 0, getWidth(), getHeight());
|
||||
}
|
||||
|
||||
}
|
497
src/lib/Utilities.java
Normal file
497
src/lib/Utilities.java
Normal file
|
@ -0,0 +1,497 @@
|
|||
/*
|
||||
* 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 lib;
|
||||
|
||||
import java.awt.Desktop;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Frame;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Formatter;
|
||||
import java.util.Random;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.UnsupportedLookAndFeelException;
|
||||
import javax.swing.filechooser.FileFilter;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alistair Neil <info@dazzleships.net>
|
||||
*/
|
||||
public final class Utilities {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public Utilities() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Covert list to csv
|
||||
*
|
||||
* @param al
|
||||
* @return String of comma separated values
|
||||
*/
|
||||
public static String getListAsCSV(ArrayList<String> al) {
|
||||
return al.toString().replace("[", "").replace("]", "").replace(" ", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Preloads filechooser in background so it will open instantly when
|
||||
* requested
|
||||
*/
|
||||
public static void preloadFileChooser() {
|
||||
Thread t = new Thread(new java.lang.Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
JFileChooser fileChooser = new JFileChooser();
|
||||
}
|
||||
});
|
||||
t.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens java file chooser dialog, convenience method. Returns filepath if
|
||||
* successful and null if not
|
||||
*
|
||||
* @param parent
|
||||
* @param folder
|
||||
* @param filter Extension filter
|
||||
* @param mode Fileselection mode
|
||||
* @return String Filepath
|
||||
*/
|
||||
public static String openFileChooser(Frame parent, String folder, FileFilter filter, int mode) {
|
||||
JFileChooser fileChooser = new JFileChooser();
|
||||
fileChooser.setFileSelectionMode(mode);
|
||||
fileChooser.setCurrentDirectory(new File(folder));
|
||||
if (filter != null) {
|
||||
fileChooser.addChoosableFileFilter(filter);
|
||||
}
|
||||
int intReturn = fileChooser.showOpenDialog(parent);
|
||||
if (intReturn == JFileChooser.APPROVE_OPTION) {
|
||||
return fileChooser.getSelectedFile().getAbsolutePath();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for newer appversion
|
||||
*
|
||||
* @param localversion
|
||||
* @param remoteversion
|
||||
* @return True if newer
|
||||
*/
|
||||
public static boolean isNewerVersion(String localversion, String remoteversion) {
|
||||
return convertBuildnumToFloat(remoteversion) > convertBuildnumToFloat(localversion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an debian build number into a floating point number
|
||||
*
|
||||
* @param version
|
||||
* @return Float version
|
||||
*/
|
||||
private static float convertBuildnumToFloat(String version) {
|
||||
|
||||
float result;
|
||||
Pattern p;
|
||||
String[] parts;
|
||||
try {
|
||||
if (version.contains("-")) {
|
||||
// Handling for old non-debian compatible version
|
||||
p = Pattern.compile("-");
|
||||
parts = p.split(version);
|
||||
} else {
|
||||
// Handling for new debian compatible version
|
||||
p = Pattern.compile("\\.");
|
||||
parts = p.split(version);
|
||||
parts[0] = parts[0] + "." + parts[1];
|
||||
parts[1] = parts[2];
|
||||
parts[2] = "";
|
||||
}
|
||||
result = Float.parseFloat(parts[0]);
|
||||
result += (Float.parseFloat(parts[1]) / 100000);
|
||||
} catch (Exception ex) {
|
||||
version = version.replaceAll("[^0-9.]", "");
|
||||
result = convertVersionToFloat(version);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a windows version number into a floating point number
|
||||
*
|
||||
* @param version
|
||||
* @return Float version
|
||||
*/
|
||||
private static float convertVersionToFloat(String version) {
|
||||
|
||||
int c;
|
||||
float f;
|
||||
version = version.toLowerCase();
|
||||
if (version.startsWith("v")) {
|
||||
version = version.substring(1);
|
||||
}
|
||||
try {
|
||||
c = version.charAt(version.length() - 1);
|
||||
if (c > 96) {
|
||||
version = version.substring(0, version.length() - 1);
|
||||
Float fraction = (float) (c - 96) / 10000;
|
||||
f = Float.parseFloat(version) + fraction;
|
||||
} else {
|
||||
f = Float.parseFloat(version);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
f = 0;
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the desktop default file editor
|
||||
*
|
||||
* @param path Path to file
|
||||
*/
|
||||
public static void editFile(String path) {
|
||||
if (OSFunction.isLinux()) {
|
||||
OSFunction.launchProcess("xdg-open", path);
|
||||
return;
|
||||
}
|
||||
if (OSFunction.isWindows()) {
|
||||
OSFunction.launchProcess("notepad", path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch the desktops default file handling program
|
||||
*
|
||||
* @param strUrl
|
||||
* @return Returns true if successful
|
||||
*/
|
||||
public static boolean openFileExternally(final String strUrl) {
|
||||
String url = strUrl.replace("\\", "/");
|
||||
try {
|
||||
if (OSFunction.isLinux()) {
|
||||
OSFunction.launchProcess("xdg-open", url);
|
||||
} else {
|
||||
if (Desktop.isDesktopSupported()) {
|
||||
Desktop deskSupport = Desktop.getDesktop();
|
||||
if (url.startsWith("http") || url.startsWith("ftp")) {
|
||||
deskSupport.browse(new URI(url));
|
||||
} else {
|
||||
deskSupport.open(new File(url));
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} catch (URISyntaxException | IOException ex) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialises the UI Look and Feel
|
||||
*
|
||||
* @param theme
|
||||
*/
|
||||
public static void loadUIStyle(String theme) {
|
||||
|
||||
try {
|
||||
if (theme == null) {
|
||||
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
|
||||
return;
|
||||
}
|
||||
|
||||
if (theme.contentEquals("Metal")) {
|
||||
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
|
||||
return;
|
||||
}
|
||||
|
||||
if (theme.contentEquals("Nimbus")) {
|
||||
// Switch to Nimbus theme
|
||||
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
|
||||
return;
|
||||
}
|
||||
|
||||
if (theme.contentEquals("System")) {
|
||||
try {
|
||||
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
|
||||
return;
|
||||
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
|
||||
}
|
||||
try {
|
||||
UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
|
||||
return;
|
||||
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
|
||||
}
|
||||
}
|
||||
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
|
||||
}
|
||||
|
||||
// If everything else fails use default cross platform metal
|
||||
try {
|
||||
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
|
||||
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust specified column width based on the width of a test string
|
||||
*
|
||||
* @param table
|
||||
* @param test
|
||||
*/
|
||||
public static void adjustTableColumnWidth(JTable table, String... test) {
|
||||
FontMetrics ourFontMetrics = table.getFontMetrics(table.getFont());
|
||||
int col = 0;
|
||||
for (String s : test) {
|
||||
table.getColumn(table.getColumnName(col++)).setPreferredWidth(ourFontMetrics.stringWidth(s));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate secret key.
|
||||
*
|
||||
* @param length
|
||||
* @return String key
|
||||
*/
|
||||
public static String generateSecretKey(int length) {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
Random random = new Random();
|
||||
String chars = "abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
int x;
|
||||
try {
|
||||
for (int i = 0; i < length; i++) {
|
||||
x = random.nextInt(chars.length() - 1);
|
||||
buffer.append(chars.substring(x, x + 1));
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public static String getTorHashPassword(String secret) {
|
||||
byte[] key = S2KRFC2440(secret);
|
||||
return "16:" + byteToHex(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Secret to key, Algorithm info taken from
|
||||
* http://sunsite.icm.edu.pl/gnupg/rfc2440-3.html
|
||||
*
|
||||
* @param secret
|
||||
* @return hashed key for the given secret
|
||||
*/
|
||||
public static byte[] S2KRFC2440(String secret) {
|
||||
|
||||
// Create our message digest for SHA-1
|
||||
MessageDigest md;
|
||||
try {
|
||||
md = MessageDigest.getInstance("SHA-1");
|
||||
} catch (Exception ex) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Create our random S2K salt, the 9th byte is loaded with the code count which
|
||||
// determines the amount of octet hashing used.
|
||||
// This salt is eventually combined with the secret to prevent dictionary attacks
|
||||
int codecount = 32;
|
||||
byte[] s2ksalt = new byte[9];
|
||||
SecureRandom sr = new SecureRandom();
|
||||
sr.nextBytes(s2ksalt);
|
||||
s2ksalt[8] = (byte) codecount;
|
||||
// The octet hashing count is defined by the following formula where EXPBIAS is 6
|
||||
int octethashcount = (16 + (codecount & 15)) << ((codecount >> 4) + 6);
|
||||
|
||||
// Merge our S2K salt and partialsecret arrays together into one array to
|
||||
// create the full secret key.
|
||||
byte[] partialsecret;
|
||||
try {
|
||||
partialsecret = secret.getBytes("UTF-8");
|
||||
} catch (UnsupportedEncodingException ex) {
|
||||
return null;
|
||||
}
|
||||
byte[] fullsecret = new byte[8 + partialsecret.length];
|
||||
System.arraycopy(s2ksalt, 0, fullsecret, 0, 8);
|
||||
System.arraycopy(partialsecret, 0, fullsecret, 8, partialsecret.length);
|
||||
// Do the hashing based on the hashcount
|
||||
while (true) {
|
||||
if (octethashcount < fullsecret.length) {
|
||||
md.update(fullsecret, 0, octethashcount);
|
||||
break;
|
||||
} else {
|
||||
md.update(fullsecret);
|
||||
}
|
||||
octethashcount -= fullsecret.length;
|
||||
}
|
||||
// Create our final key by merging s2kspecifier and digest result
|
||||
byte[] ourkey = new byte[20 + 9];
|
||||
System.arraycopy(md.digest(), 0, ourkey, 9, 20);
|
||||
System.arraycopy(s2ksalt, 0, ourkey, 0, 9);
|
||||
return ourkey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SHAHash using given password string
|
||||
*
|
||||
* @param password
|
||||
* @return SHAhash string
|
||||
*/
|
||||
public static String getSHAHash(String password) {
|
||||
String sha1 = "";
|
||||
try {
|
||||
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
|
||||
crypt.reset();
|
||||
crypt.update(password.getBytes("UTF-8"));
|
||||
sha1 = byteToHex(crypt.digest());
|
||||
} catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
|
||||
}
|
||||
return sha1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert byte to a hex string
|
||||
*
|
||||
* @param hash
|
||||
* @return byte as a hex string
|
||||
*/
|
||||
private static String byteToHex(final byte[] hash) {
|
||||
String result;
|
||||
try (Formatter formatter = new Formatter()) {
|
||||
for (byte b : hash) {
|
||||
formatter.format("%02x", b);
|
||||
}
|
||||
result = formatter.toString();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve text from a resource text file
|
||||
*
|
||||
* @param resourcepath
|
||||
* @return String text
|
||||
*/
|
||||
public static String getTextFromResource(String resourcepath) {
|
||||
SimpleFile sf = new SimpleFile(resourcepath);
|
||||
sf.openBufferedResource();
|
||||
String text = sf.readEntireFile();
|
||||
sf.closeFile();
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve text from a text file
|
||||
*
|
||||
* @param filepath
|
||||
* @return String text
|
||||
*/
|
||||
public static String getTextFromFile(String filepath) {
|
||||
SimpleFile sf = new SimpleFile(filepath);
|
||||
String text = "";
|
||||
if (sf.exists()) {
|
||||
sf.openBufferedRead();
|
||||
text = sf.readEntireFile();
|
||||
sf.closeFile();
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the sha1 checksum of a given file
|
||||
*
|
||||
* @param filepath
|
||||
* @return Checksum as a hex string
|
||||
*/
|
||||
public static String getSha1Sum(String filepath) {
|
||||
StringBuilder sb = new StringBuilder("");
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("SHA1");
|
||||
FileInputStream fis = new FileInputStream(filepath);
|
||||
byte[] dataBytes = new byte[1024];
|
||||
int nread;
|
||||
while ((nread = fis.read(dataBytes)) != -1) {
|
||||
md.update(dataBytes, 0, nread);
|
||||
}
|
||||
byte[] mdbytes = md.digest();
|
||||
//convert the byte to hex format
|
||||
for (int i = 0; i < mdbytes.length; i++) {
|
||||
sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1));
|
||||
}
|
||||
} catch (NoSuchAlgorithmException | IOException ex) {
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a hidden dummy window for registration to various docks/launchers
|
||||
* Fixes the neverending launching indicator
|
||||
*/
|
||||
public static void registerWindow() {
|
||||
final JFrame jf = new JFrame();
|
||||
|
||||
jf.addWindowListener(new java.awt.event.WindowListener() {
|
||||
@Override
|
||||
public void windowOpened(WindowEvent e) {
|
||||
jf.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowClosed(WindowEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowIconified(WindowEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowDeiconified(WindowEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowActivated(WindowEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowDeactivated(WindowEvent e) {
|
||||
}
|
||||
});
|
||||
jf.setUndecorated(true);
|
||||
jf.setBounds(0, 0, 0, 0);
|
||||
jf.setVisible(true);
|
||||
}
|
||||
|
||||
}
|
263
src/resources/MessagesBundle.properties
Normal file
263
src/resources/MessagesBundle.properties
Normal file
|
@ -0,0 +1,263 @@
|
|||
# English GB, Default language file
|
||||
gpltransurl=https://www.gnu.org/licenses/translations.en.html
|
||||
appdesc=$appname $appver, Tor Exit Nodes Made Simple.
|
||||
text_yes=Yes
|
||||
text_no=No
|
||||
text_mode=Mode
|
||||
wintitle_prefs = $appname Preferences
|
||||
wintitle_about = About $appname
|
||||
wintitle_patternedit = $appname Pattern Editor
|
||||
wintitle_guardnodes=Guard node selection
|
||||
wintitle_tormonitor=Tor Client Monitor
|
||||
textfield_unknown=Unknown
|
||||
progstatus_initial=Initialising...
|
||||
progstatus_generate=Generating fresh node list, please wait.
|
||||
progstatus_cachedated=Cached descriptors out of date, will renew them.
|
||||
progstatus_nonet=Internet access un-available.
|
||||
progstatus_checkrecommended=Checking for the latest recommended nodes.
|
||||
progstatus_gotrecommended=Retrieved recommended node list.
|
||||
progstatus_torfailretry=Tor failed to start, retrying.
|
||||
progstatus_nodefail=Requested node activation failed.
|
||||
progstatus_nodefailretry=Requested node activation failed, will try again please wait.
|
||||
progstatus_nodefailtorchoose=Requested node not reachable, will let Tor choose please wait.
|
||||
progstatus_nodeactive3hop=3 Hop Circuit to exit node $nodename is active.
|
||||
progstatus_nodeactive2hop=2 Hop Circuit to exit node $nodename is active.
|
||||
progstatus_autoswitch=Auto-Switching to node
|
||||
progstatus_manswitch=Switching to manually selected node
|
||||
progstatus_waitfortor=Waiting for Tor to activate a node.
|
||||
progstatus_switchtonode=Switching to node $nodename.
|
||||
progstatus_applychanges=Applying new preferences.
|
||||
circuit_status_creating_2hop=Creating 2 hop circuit.
|
||||
circuit_status_creating_3hop=Creating 3 hop circuit.
|
||||
circuit_status_testing=Testing circuit.
|
||||
circuit_status_aborted=Testing aborted.
|
||||
circuit_status_built=$1 circuits built.
|
||||
circuit_status_passed=Circuit passed.
|
||||
circuit_status_failed=Circuit Failed.
|
||||
circuit_status_none=No circuits available.
|
||||
circuit_status_noroute=All routers down.
|
||||
combo_proxymode1=Disabled
|
||||
combo_proxymode2=Proxy by Pattern
|
||||
combo_proxymode3=Proxy all Traffic
|
||||
combo_loglev1=Debug
|
||||
combo_loglev2=Info
|
||||
combo_loglev3=Notice
|
||||
traymenu_proxymode1=Mode : Proxy Disabled
|
||||
traymenu_proxymode2=Mode : Proxy by Pattern
|
||||
traymenu_proxymode3=Mode : Proxy all Traffic
|
||||
traymenu_showgui=Hide/Show GUI
|
||||
traytool_guardnode=GuardNode
|
||||
traytool_exitnode=ExitNode
|
||||
exittable_col1=ExitNode
|
||||
exittable_col2=BW (MB\\s)
|
||||
exittable_col3=Latency (ms)
|
||||
exittable_col4=Status
|
||||
exittable_col5=Favourite
|
||||
guardtable_col1=GuardNode
|
||||
guardtable_col2=Country
|
||||
guardtable_col3=BW (MB\\s)
|
||||
guardtable_col4=Trusted
|
||||
patterntable_col1=Description
|
||||
patterntable_col2=Pattern
|
||||
patterntable_col3=Enabled
|
||||
menu_menu=Menu
|
||||
menu_prefs=Preferences
|
||||
menu_quickadd=Quick Add Pattern
|
||||
menu_patternedit=Proxy Pattern Editor
|
||||
menu_export=Export Patterns
|
||||
menu_import=Import Patterns
|
||||
menu_quit=Quit
|
||||
menu_defaultpatterns=Default Patterns
|
||||
menu_userpatterns=User Patterns
|
||||
menu_help=Help
|
||||
menu_debuglog=View Debug Log
|
||||
menu_helpcontents=Help Contents
|
||||
menu_torcheck=Tor Routing Check
|
||||
menu_about=About
|
||||
menu_license=License
|
||||
menu_tormanual=Official Tor Manual
|
||||
menu_tormonitor=Tor Client Monitor
|
||||
menu_close=Close Menu
|
||||
menu_proxy=Proxy Mode
|
||||
menu_leaktest=DNS Leak Test
|
||||
menu_credits=Credits
|
||||
label_latency_url=Tor Latency Checking URL :
|
||||
label_guardnode=Guard :
|
||||
label_bridgenode=Bridge :
|
||||
label_activecountry=Exit Country :
|
||||
label_proxymode=Proxy Mode :
|
||||
label_exitnode=Exit Node:
|
||||
label_torlatency=Latency
|
||||
label_fingerprint=Fingerprint:
|
||||
label_bandwidth=Bandwidth
|
||||
label_streams=Streams
|
||||
label_stable=Stable
|
||||
label_status=Client Status:
|
||||
label_listenport=Tor Listening Port :
|
||||
label_defaultproxy=Default HTTP Proxy :
|
||||
label_bridgeaddress=Tor Bridge Address :
|
||||
label_portranges=Currently active port ranges, $portmin to $portmax
|
||||
label_editcountry=Select Country To View its Patterns
|
||||
label_quickadd_desc=Description :
|
||||
label_quickadd_pattern=Pattern :
|
||||
label_threshold=Threshold
|
||||
label_exitip=Exit IP:
|
||||
label_guardip=Guard IP:
|
||||
label_guardcountry=Guard Country:
|
||||
label_torlogging=Logging Level :
|
||||
label_torargs=Startup Arguments :
|
||||
label_torsocks=Socks Settings :
|
||||
label_diskoptions=Disk Options :
|
||||
label_guard_minimum=You can have either zero guard nodes selected in which case the tor client will choose or you can have 3 or more guard nodes selected.
|
||||
label_nickname=Nickname
|
||||
label_ip=IP
|
||||
label_country=Country
|
||||
label_exit=Exit :
|
||||
label_middle=Middle :
|
||||
label_donotproxy=Do not proxy :
|
||||
button_details=Atlas Details
|
||||
button_whois=WhoIs
|
||||
button_close=Close
|
||||
button_apply=Apply
|
||||
button_delete=Delete
|
||||
button_addnew=Add New
|
||||
button_save=Save
|
||||
button_cancel=Cancel
|
||||
button_continue=Continue
|
||||
button_getbridges=Get Bridges
|
||||
button_mozillarestart=$browser Restart
|
||||
button_visitus=Visit Us
|
||||
button_contactus=Contact Us
|
||||
button_translations=Unofficial Translations
|
||||
button_prefdefaults=Reset to Defaults
|
||||
button_setguards=Set Guard Nodes
|
||||
button_clearfavs=Clear Favourites
|
||||
button_clearguards=Clear Selected Guards
|
||||
button_support=Support SelekTOR
|
||||
button_patreon=Support SelekTOR with Patreon
|
||||
panel_info=Active Circuit
|
||||
panel_general=General Settings
|
||||
panel_network=Network Settings
|
||||
panel_management=Node Management Settings
|
||||
panel_torclientset=Tor Client Settings
|
||||
panel_startupargs=Startup Arguments
|
||||
panel_stdout=StdOut Monitor
|
||||
chkbox_autoselect=Auto Node Select
|
||||
chkbox_autostart=Autostart SelekTOR
|
||||
chkbox_checkforupdates=Check for updates on startup
|
||||
chkbox_disabletray=Disable tray icon.
|
||||
chkbox_autopatterns=Auto install latest patterns.
|
||||
chkbox_mozillawarn=Disable Mozilla warning
|
||||
chkbox_recnodesonly=Use recommended nodes in Pattern Mode
|
||||
chkbox_hidetotray=Minimise at startup
|
||||
chkbox_minonclose=Minimise instead of Exit on close
|
||||
chkbox_twohop=Use 2 hop circuits to Exit Node in Pattern mode
|
||||
chkbox_safesocks=Safe Socks
|
||||
chkbox_warnunsafesocks=Warn Unsafe
|
||||
chkbox_diskavoid=Avoid disk writes
|
||||
chkbox_testsocks=Test Socks
|
||||
chkbox_safelog=Safe Logging
|
||||
chkbox_guardwarn1=Issue popup warning if unspecified guard node is used
|
||||
chkbox_securedelete=Secure delete Tor caches on exit
|
||||
chkbox_guardwarn2=Issue popup warning if less than 3 guard nodes selected
|
||||
ttip_autostart=Will start SelekTOR automatically on boot/login.
|
||||
ttip_hidetotray=SelekTOR will startup in system tray
|
||||
ttip_checkforupdates=SelekTOR will check for a newer version on startup
|
||||
ttip_autoinstall=Will fetch the latest patterns from Dazzleships.Net.
|
||||
ttip_disabletray=Disable the system tray icon
|
||||
ttip_mozillawarn=Disable the Mozilla browser warning
|
||||
ttip_listenport=The Tor client listening port.
|
||||
ttip_defaultproxy=Any traffic not routed through Tor will be redirected through this HTTP proxy.
|
||||
ttip_donotproxy=Any URL that contains one of these comma separated entries will not be proxied and will be connected to directly.
|
||||
ttip_bridgeaddress=To bypass ISP blocking add a valid bridge address here.
|
||||
ttip_forcedns=Force DNS Lookup via Tor, requires browser restart.
|
||||
ttip_forcenode=When checked node will be activated regardless of any current activity
|
||||
ttip_enhanon=Will use 3 node hops instead of 2 hops.
|
||||
ttip_recnodesonly=Will use the recommended nodes in pattern mode
|
||||
ttip_minonclose=Application will minimise instead of exit when main window is closed
|
||||
ttip_threshold=Threshold Latency
|
||||
ttip_safesocks=When enabled, Tor will reject application connections that use unsafe variants of the socks protocol.
|
||||
ttip_warnunsafe=When enabled, Tor will warn whenever a request is received that only contains an IP address instead of a hostname.
|
||||
ttip_testsocks=When enabled, Tor will make a notice-level log entry for each connection indicating whether it used a safe socks protocol or an unsafe one.
|
||||
ttip_safelogging=When enabled, Tor will scrub potentially sensitive strings from log messages.
|
||||
ttip_avoiddisk=When enabled, Tor will try to write to disk less frequently than we would otherwise.
|
||||
ttip_extraargs=Additional user specified arguments, see Tor Manual.
|
||||
ttip_combo_loglevel=Tor logging level.
|
||||
ttip_twohop=Use 2 hop circuits instead of Tor default of 3, reduces latency but lowers anonymity.
|
||||
ttip_resetbasicprefs=Reset Basic preferences to their defaults.
|
||||
ttip_resetadvprefs=Reset Advanced preferences to their defaults.
|
||||
ttip_securedelete=When enabled, Tor caches will be overwritten by zero's then deleted
|
||||
ttip_autonode=When enabled, SelekTOR will attempt to choose the best performing node
|
||||
ttip_guardwarn=When enabled, a popup warning will be issued indicating an un-specified guard node is active.
|
||||
ttip_clearguards=Clear selected guard nodes.
|
||||
ttip_clearfavs=Clear Favourites
|
||||
ttip_guardwarn2=When enabled, a popup warning will be issued indicating not enough guardnodes are selected.
|
||||
dlg_update_title=Update Available.
|
||||
dlg_update_body=$version is now available for download.
|
||||
dlg_restoreproxy_title=Original Proxy Settings
|
||||
dlg_restoreproxy_body=Select Continue to restore the proxy settings to their original settings prior to the installation of SelekTOR.
|
||||
dlg_resetproxy_title=Default Proxy Settings
|
||||
dlg_resetproxy_body=Select Continue to reset proxy settings to their system defaults.
|
||||
dlg_gsetting_title=Gsettings not found
|
||||
dlg_gsetting_body=$appname cannot function fully without the gsettings binary installed, on some distro's it can be found in the package libglib2.0-bin.
|
||||
dlg_torclient_title=TOR Client not found
|
||||
dlg_torclient_body=$appname cannot function without the Tor client installed please install the tor and the tor-geoipdb packages for your distro.
|
||||
dlg_mozillarestart_title=Warning: $browser browser is active.
|
||||
dlg_mozillarestart_body=$appname detected that the $browser browser is already running.\nA browser restart is required to enable $appname functionality.\n\nIf you elect to restart $browser all currently open tabs will be restored when $browser restarts, requires \"Show my Windows and tabs from last time\" option to be selected in $browser preferences/options.\n\nYou can disable this browser warning in $appname Preferences.
|
||||
dlg_license_title=$appname License
|
||||
dlg_credits_title=$appname Credits
|
||||
dlg_credits_body=To have your name listed here and also earn my gratitude please consider supporting the further development of SelekTOR on the Linux platform via Patreon.
|
||||
dlg_exportuser_title=Export User Patterns
|
||||
dlg_exportuser_body=No user created patterns found.\n\nUse the pattern editor to add your own patterns
|
||||
dlg_exportdefault_title=Export Default Patterns
|
||||
dlg_exportdefault_body=No default patterns found.
|
||||
dlg_saveuser_title=Save User patterns
|
||||
dlg_savedefault_title=Save Default patterns
|
||||
dlg_import_title=Import pattern file
|
||||
dlg_import_success_title=Patterns Imported
|
||||
dlg_import_success_body=Patterns were succesfully imported and are now active.
|
||||
dlg_import_fail_title=Import Failed
|
||||
dlg_import_fail_body=Failed to correctly import patterns.
|
||||
dlg_whois_title=Whois $ipaddress
|
||||
dlg_whois_body=Please wait while I try fetching Whois data...
|
||||
dlg_whois_fail=Sorry unable to fetch Whois information.
|
||||
dlg_toold_body=The currently installed Tor client is to old, Tor 0.2.7.6 or better is required.\n\nLinux users should visit the following page\nhttps://www.torproject.org/download/download-unix.html.en\nto obtain the latest Tor client.
|
||||
dlg_error_title=Startup Error
|
||||
dlg_error_body=This error is fatal and $appname will shut itself down.
|
||||
dlg_quickadd_title=Add Pattern
|
||||
dlg_nodelistfail_body=Nodelist generation failed due to GEOIP errors.
|
||||
dlg_patterneditsave_title=Save Current Patterns
|
||||
dlg_patterneditsave_body=Current patterns have been modified.\n\nIf you wish to save them, click Continue else click Cancel.
|
||||
dlg_instancefail_title=Multiple instance failure
|
||||
dlg_instancefail_body=An instance of $appname is already running, only one instance can be run at any time.\n\nEither shutdown the existing instance of $appname or in the event of a $appname crash restart X by logging out and in again.
|
||||
dlg_guardwarn_title=Guard Node Warning
|
||||
dlg_guardwarn_body=A guard node that is not in your specified guard nodes list has been used.\nThis is probably due to your selected guard nodes being no longer reachable and thus the tor client has assigned its own guard node.\n\nYou may want to check your currently set guard nodes to see if they are still available or select new ones.
|
||||
dlg_notenoughguards_body=Their are not enough guard nodes set for Tor to operate efficiently or securely.\n\nEither clear all selected guards which will allow the Tor client to choose its own guards or select three or more guards manually.
|
||||
dlg_bridgerr_title=Bridge address validation failure
|
||||
dlg_bridgerr_body=The supplied bridge information contains validation errors and does not conform to a valid host:port ipv4 address format.\n\nBridge specification format examples are as follows:\n\nSingle bridge:\n127.0.0.1:8080\n\nMultiple bridges:\n127.0.0.1:8080,128.5.6.8:224\n\nBridges have been reset to their defaults.
|
||||
table_popup_details=Details
|
||||
table_popup_begintest=Begin Test Cycle
|
||||
table_popup_whois=WhoIs
|
||||
tab_basic=Basic
|
||||
tab_advanced=Advanced
|
||||
isoA1=Anonymous Proxy
|
||||
isoA2=Satellite Provider
|
||||
isoO1=Other Country
|
||||
isoU1=Unknown
|
||||
chkbox_disablenotify=Disable desktop notifications
|
||||
ttip_disablenotify=Disable desktop notifications
|
||||
dlg_libnotify_title=notify-send not found
|
||||
dlg_libnotify_body=Desktop notifications will not function without the libnotify-bin package installed.\n\nTo prevent this popup appearing again either install the required package or disable desktop notifications in preferences.
|
||||
ttip_hidemin=Application will hide instead of minimise
|
||||
chkbox_hidemin=Hide instead of Minimise
|
||||
label_autoselect=Auto Selection Mode :
|
||||
menu_geoip=Update GEOIP
|
||||
chkbox_geocheck=Do quarterly GEOIP update check
|
||||
ttip_geocheck=SelekTOR will popup the "GEOIP Update dialog" if your GEOIP database is out of date.
|
||||
dlg_geo_title=GEO Location Data Update
|
||||
dlg_geo_body=The default geo-location data that comes with the Tor client is sometimes out of date, You can have SelekTOR download and use the latest geolocation data. These are maintained on a quarterly basis.\n\nPlease note, if you choose not to update, some nodes may be assigned to the wrong country.\n\nThe data in these files, like the data supplied by the Tor client, is provided by Maxmind.com.
|
||||
dload_status_contact=Fetching latest GEOIP data
|
||||
dload_status_failed=Download failed
|
||||
chkbox_viator=Download via Tor
|
||||
ttip_patterntable=Supports in-line editing, double left click a table cell to begin editing.
|
||||
fileext_pattern=Zipped Pattern File
|
10
src/resources/MessagesBundle_en_US.properties
Normal file
10
src/resources/MessagesBundle_en_US.properties
Normal file
|
@ -0,0 +1,10 @@
|
|||
progstatus_initial=Initializing...
|
||||
chkbox_hidetotray=Minimize at startup
|
||||
chkbox_minonclose=Minimize instead of Exit on close
|
||||
ttip_minonclose=Application will minimize instead of exit when window is closed.
|
||||
ttip_hidemin=Application will hide instead of minimize
|
||||
chkbox_hidemin=Hide instead of Minimize
|
||||
button_clearfavs=Clear Favorites
|
||||
ttip_clearfavs=Clear Favorites
|
||||
exittable_col5=Favorite
|
||||
|
256
src/resources/MessagesBundle_fr_CA.properties
Normal file
256
src/resources/MessagesBundle_fr_CA.properties
Normal file
|
@ -0,0 +1,256 @@
|
|||
# French CA, Default language file, provided by yahoe001
|
||||
gpltransurl=https://fsffrance.org/gpl/gpl-fr.fr.html
|
||||
appdesc=$appname $appver, Les n\u0153uds de sortie de Tor simplifi\u00e9s.
|
||||
text_yes=Oui
|
||||
text_no=Non
|
||||
wintitle_prefs = Pr\u00e9f\u00e9rences de $appname
|
||||
wintitle_about = \u00c0 propos de $appname
|
||||
wintitle_patternedit = \u00c9diteur de mod\u00e8les $appname
|
||||
wintitle_guardnodes=S\u00e9lection des n\u0153uds de garde
|
||||
wintitle_tormonitor=Moniteur du client Tor
|
||||
textfield_unknown=Inconnu
|
||||
progstatus_initial=Initialisation...
|
||||
progstatus_bridges=Mise en place du changement de ponts.
|
||||
progstatus_generate=G\u00e9n\u00e9ration d'une nouvelle liste de n\u0153uds, veuillez patienter.
|
||||
progstatus_cachedated=Les descripteurs en cache sont p\u00e9rim\u00e9s, ils seront renouvel\u00e9s.
|
||||
progstatus_nonet=L'acc\u00e8s \u00e0 Internet n'est pas disponible.
|
||||
progstatus_checkrecommended=Recherche des derniers n\u0153uds recommand\u00e9s.
|
||||
progstatus_torfailretry=\u00c9chec lors du d\u00e9marrage de Tor, nouvel essai.
|
||||
progstatus_nodefail=\u00c9chec lors de l'activation du n\u0153ud demand\u00e9.
|
||||
progstatus_nodefailretry=\u00c9chec lors de l'activation du n\u0153ud demand\u00e9. Nouvel essai, veuillez patienter.
|
||||
progstatus_nodefailtorchoose=Le n\u0153ud demand\u00e9 n'est pas joignable, Tor en choisira un, veuillez patienter.
|
||||
progstatus_nodeactive3hop=Le circuit \u00e0 3 sauts vers le n\u0153ud de sortie $nodename est actif.
|
||||
progstatus_nodeactive2hop=Le circuit \u00e0 2 sauts vers le n\u0153ud de sortie $nodename est actif.
|
||||
progstatus_autoswitch=Auto-commutation vers le n\u0153ud
|
||||
progstatus_manswitch=Commutation vers le n\u0153ud choisi manuellement
|
||||
progstatus_waitfortor=Attente d'activation d'un n\u0153ud par Tor.
|
||||
progstatus_switchtonode=Commutation vers le n\u0153ud $nodename.
|
||||
progstatus_applychanges=Mise en place des nouvelles pr\u00e9f\u00e9rences.
|
||||
circuit_status_creating_2hop=Cr\u00e9ation d'un circuit \u00e0 2 sauts.
|
||||
circuit_status_creating_3hop=Cr\u00e9ation d'un circuit \u00e0 3 sauts.
|
||||
circuit_status_testing=Test du circuit.
|
||||
circuit_status_aborted=Test interrompu.
|
||||
circuit_status_built=$1 circuit(s) construit(s).
|
||||
circuit_status_passed=Circuit v\u00e9rifi\u00e9.
|
||||
circuit_status_failed=\u00c9chec de circuit.
|
||||
circuit_status_none=Aucun circuit n'est disponible.
|
||||
circuit_status_noroute=Routeurs (tous) hors service.
|
||||
combo_proxymode1=D\u00e9sactiv\u00e9
|
||||
combo_proxymode2=Relais par mod\u00e8le
|
||||
combo_proxymode3=Relayer tout le trafic
|
||||
combo_loglev1=D\u00e9bogage
|
||||
combo_loglev2=Infos
|
||||
combo_loglev3=Avis
|
||||
traymenu_proxymode1=Mode : pas de relais
|
||||
traymenu_proxymode2=Mode : relais par mod\u00e8le
|
||||
traymenu_proxymode3=Mode : relayer tout le trafic
|
||||
traymenu_showgui=Cacher/Montrer l'IUG
|
||||
traytool_guardnode=Noeud de garde
|
||||
traytool_exitnode=Noeud de sortie
|
||||
exittable_col1=N\u0153ud de sortie
|
||||
exittable_col2=BP (MB\\s)
|
||||
exittable_col3=D\u00e9lai (ms)
|
||||
exittable_col4=\u00c9tat
|
||||
exittable_col5=Favori
|
||||
patterntable_col1=Description
|
||||
patterntable_col2=Mod\u00e8le
|
||||
patterntable_col3=Activ\u00e9
|
||||
guardtable_col1=N\u0153ud de garde
|
||||
guardtable_col2=Pays
|
||||
guardtable_col3=BP (MB\\s)
|
||||
guardtable_col4=De confiance
|
||||
menu_menu=Menu
|
||||
menu_prefs=Pr\u00e9f\u00e9rences
|
||||
menu_quickadd=Ajout rapide d'un mod\u00e8le
|
||||
menu_patternedit=\u00c9diteur de mod\u00e8les de relais
|
||||
menu_export=Exporter les mod\u00e8les
|
||||
menu_import=Import les mod\u00e8les
|
||||
menu_quit=Quitter
|
||||
menu_defaultpatterns=Mod\u00e8le par d\u00e9faut
|
||||
menu_userpatterns=Mod\u00e8les de l'utilisateur
|
||||
menu_help=Aide
|
||||
menu_debuglog=Voir le journal de d\u00e9bogage
|
||||
menu_helpcontents=Contenu de l'aide
|
||||
menu_torcheck=V\u00e9rification de routine de Tor
|
||||
menu_about=\u00c0 propos de
|
||||
menu_license=Licence
|
||||
menu_proxy=Mode de relais
|
||||
menu_close=Fermer le menu
|
||||
menu_tormanual=Manuel officiel de Tor
|
||||
menu_tormonitor=Moniteur du client Tor
|
||||
menu_leaktest=Test de fuite DNS
|
||||
menu_credits=Cr\u00e9dits
|
||||
label_activecountry=Pays actif :
|
||||
label_proxymode=Mode de relais :
|
||||
label_exitnode=N\u0153ud de sortie :
|
||||
label_ip=IP :
|
||||
label_torlatency=D\u00e9lai
|
||||
label_fingerprint=Empreinte :
|
||||
label_bandwidth=Bande passante
|
||||
label_streams=Flux
|
||||
label_stable=Stable
|
||||
label_status=\u00c9tat :
|
||||
label_listenport=Port d'\u00e9coute de Tor :
|
||||
label_defaultproxy=Mandataire HTTP par d\u00e9faut :
|
||||
label_bridgeaddress=Adresse de pont de Tor :
|
||||
label_portranges=Plages de port pr\u00e9sentement actives, de $portmin \u00e0 $portmax
|
||||
label_editcountry=Choisir un pays pour voir ses mod\u00e8les
|
||||
label_quickadd_desc=Description :
|
||||
label_quickadd_pattern=Mod\u00e8le :
|
||||
label_threshold=D\u00e9lai seuil
|
||||
label_middle=Milieu :
|
||||
label_exit=Sortie :
|
||||
label_nickname=Pseudonyme
|
||||
label_ip=IP
|
||||
label_country=Pays
|
||||
label_guard_minimum=Vous pouvez soit ne choisir aucun n\u0153ud de garde au cas o\u00f9 le client Tor les choisit, soit choisir trois n\u0153uds de garde ou plus.
|
||||
label_torlogging=Niveau de journalisation :
|
||||
label_torargs=Arguments de d\u00e9marrage :
|
||||
label_torsocks=Param\u00e8tres Socks :
|
||||
label_diskoptions=Options du disque :
|
||||
label_guardnode=Garde :
|
||||
label_bridgenode=Pont :
|
||||
label_donotproxy=Ne pas relayer :
|
||||
button_details=D\u00e9tails
|
||||
button_whois=Qui est
|
||||
button_close=Fermer
|
||||
button_apply=Appliquer
|
||||
button_delete=Supprimer
|
||||
button_addnew=Ajouter un nouveau
|
||||
button_save=Enregistrer
|
||||
button_cancel=Annuler
|
||||
button_continue=Continuer
|
||||
button_getbridges=Obtenir des ponts
|
||||
button_mozillarestart=Red\u00e9marrer $browser
|
||||
button_visitus=Rendez-nous visite
|
||||
button_contactus=Contactez-nous
|
||||
button_translations=Traductions non officielles
|
||||
button_prefdefaults=R\u00e9initialiser aux leurs valeurs par d\u00e9faut.
|
||||
button_setguards=D\u00e9finir les n\u0153uds de garde
|
||||
button_details=D\u00e9tails de l'atlas
|
||||
button_clearguards=Effacer les n\u0153uds de garde choisis
|
||||
button_clearfavs=Effacer les favoris
|
||||
button_support=Soutenir SelekTOR
|
||||
button_patreon=Soutenir SelekTOR avec Patreon
|
||||
panel_general=Param\u00e8tres g\u00e9n\u00e9raux
|
||||
panel_network= Param\u00e8tres r\u00e9seau
|
||||
panel_management=Param\u00e8tres de gestion des n\u0153uds
|
||||
panel_info=Circuit actif
|
||||
panel_torclientset=Param\u00e8tres du client Tor
|
||||
panel_startupargs=Arguments de d\u00e9marrage
|
||||
panel_stdout=Moniteur de sortie standard
|
||||
chkbox_autoselect=Choix automatique du n\u0153ud
|
||||
chkbox_autostart=D\u00e9marrage automatique de SelekTOR
|
||||
chkbox_checkforupdates=V\u00e9rifier les mises \u00e0 jour au d\u00e9marrage
|
||||
chkbox_disabletray=D\u00e9sactiver l'ic\u00f4ne de notification
|
||||
chkbox_autopatterns=Installer automatiquement les derniers mod\u00e8les.
|
||||
chkbox_mozillawarn=D\u00e9sactiver l'avertissement de Mozilla
|
||||
chkbox_recnodesonly=Utiliser les n\u0153uds recommand\u00e9s en mode par mod\u00e8les
|
||||
chkbox_hidetotray=Minimiser au d\u00e9marrage
|
||||
chkbox_minonclose=Minimiser plut\u00f4t que de quitter lors de la fermeture
|
||||
chkbox_safesocks=Socks s\u00e9curitaire
|
||||
chkbox_twohop=Utiliser des circuits \u00e0 2 sauts vers le n\u0153ud de sortie en mode par mod\u00e8les
|
||||
chkbox_warnunsafesocks=Avertir si \u00e0 risque
|
||||
chkbox_diskavoid=\u00c9viter les \u00e9critures sur le disque
|
||||
chkbox_testsocks=Tester Socks
|
||||
chkbox_safelog=Journalisation s\u00e9curitaire
|
||||
chkbox_guardwarn1=Afficher une fen\u00eatre d'avertissement si un n\u0153ud de garde non sp\u00e9cifi\u00e9 est utilis\u00e9
|
||||
chkbox_guardwarn2=Afficher une fen\u00eatre d'avertissement si moins de trois n\u0153uds de garde sont choisis
|
||||
chkbox_securedelete=Effacement s\u00e9curis\u00e9 des caches de Tor lors de la fermeture
|
||||
ttip_autostart=D\u00e9marrage automatique de SelekTOR lors du d\u00e9marrage/de la connexion
|
||||
ttip_hidetotray=Minimiser au d\u00e9marrage
|
||||
ttip_checkforupdates=SelekTOR v\u00e9rifiera les mises \u00e0 jour au d\u00e9marage
|
||||
ttip_autoinstall=Les derniers mod\u00e8les seront r\u00e9cup\u00e9r\u00e9s de Dazzleships.Net
|
||||
ttip_disabletray=D\u00e9sactiver l'ic\u00f4ne de notification
|
||||
ttip_mozillawarn=D\u00e9sactiver l'avertissement du navigateur Mozilla
|
||||
ttip_listenport=Le port d'\u00e9coute du client Tor
|
||||
ttip_defaultproxy=Tout trafic qui ne sera pas redirig\u00e9 par Tor sera redirig\u00e9 par ce mandataire HTTP
|
||||
ttip_donotproxy=Toute URL contenant une de ces entr\u00e9es s\u00e9par\u00e9es par des virgules ne sera pas relay\u00e9e. L'on s'y connectera directement.
|
||||
ttip_bridgeaddress=Pour contourner le blocage du FSI, ajouter une adresse de pont valide ici
|
||||
ttip_forcedns=Forcer la recherche DNS par Tor, exige le red\u00e9marrage du navigateur
|
||||
ttip_forcenode=Si coch\u00e9, le n\u0153ud sera activ\u00e9 quelque soit l'activit\u00e9 du n\u0153ud
|
||||
ttip_recnodesonly=Les n\u0153uds recommand\u00e9s seront utilis\u00e9s en mode par mod\u00e8les
|
||||
ttip_minonclose=L'application sera minimis\u00e9e au lieu de quitter \u00e0 la fermeture de la fermeture principale
|
||||
ttip_threshold=D\u00e9lai seuil
|
||||
ttip_safesocks=Activ\u00e9e, Tor rejettera les connexions logicielles qui utilisent des variantes dangereuses du protocole Socks.
|
||||
ttip_warnunsafe=Activ\u00e9e, Tor avertira \u00e0 chaque fois qu'une requ\u00eate est re\u00e7ue contenant seulement une adresse IP au lieu d'un nom d'h\u00f4te.
|
||||
ttip_testsocks=Activ\u00e9e Tor journalisera une entr\u00e9e de journal de niveau avis pour chaque connexion en indiquant si elle utilise un protocole Socks s\u00e9curitaire ou dangereux.
|
||||
ttip_safelogging=Activ\u00e9e, Tor nettoiera les cha\u00eenes potentiellement sensibles des messages de journalisation.
|
||||
ttip_avoiddisk=Activ\u00e9e, Tor essaiera d'\u00e9crire moins fr\u00e9quemment sur le disque que nous ne le ferions autrement.
|
||||
ttip_extraargs= Arguments suppl\u00e9mentaires sp\u00e9cifi\u00e9s par l'utilisateur, voir le Manuel Tor.
|
||||
ttip_combo_loglevel=Niveau de journalisation de Tor.
|
||||
ttip_twohop=Utiliser des circuits \u00e0 2 sauts au lieu des 3 par d\u00e9faut de Tor. R\u00e9duit le d\u00e9lai de transit mais affaiblit l'anonymat.
|
||||
ttip_resetbasicprefs=R\u00e9initialiser les pr\u00e9f\u00e9rences de base \u00e0 leurs valeurs par d\u00e9faut.
|
||||
ttip_resetadvprefs=R\u00e9initialiser les pr\u00e9f\u00e9rences avanc\u00e9es \u00e0 leurs valeurs par d\u00e9faut.
|
||||
ttip_guardwarn1=Activ\u00e9, une fen\u00eatre d'avertissement sera affich\u00e9e indiquant qu'un n\u0153ud de garde non sp\u00e9cifi\u00e9 est actif.
|
||||
ttip_guardwarn2=Activ\u00e9, une fen\u00eatre d'avertissement sera affich\u00e9e indiquant que trop peu de n\u0153uds de garde sont choisis
|
||||
ttip_clearguards=Effacer les n\u0153uds de garde choisis.
|
||||
ttip_securedelete=Activ\u00e9, les caches de Tor seront \u00e9cras\u00e9es par des z\u00e9ros, puis supprim\u00e9es
|
||||
dlg_update_title=Mise \u00e0 jour disponible.
|
||||
dlg_update_body=$version est maintenant disponible au t\u00e9l\u00e9chargement.
|
||||
dlg_restoreproxy_title=Param\u00e8tres originaux du mandataire
|
||||
dlg_restoreproxy_body=Choisir Continuer pour restaurer les param\u00e8tres du mandataire aux valeurs par d\u00e9faut avant l'installation de SelekTOR.
|
||||
dlg_resetproxy_title=Param\u00e8tres par d\u00e9faut du mandataire
|
||||
dlg_resetproxy_body=Choisir Continuer pour r\u00e9initialiser les param\u00e8tres du serveur mandataire \u00e0 leurs valeurs syst\u00e8me par d\u00e9faut.
|
||||
dlg_gsetting_title=Gsettings introuvable
|
||||
dlg_gsetting_body=$appname ne peux pas fonctionner correctement sans que l'ex\u00e9cutable binary soit install\u00e9. Dans certaines distributions il peut \u00eatre trouv\u00e9 dans le paquet libglib2.0-bin.
|
||||
dlg_torclient_title=Client TOR introuvable
|
||||
dlg_torclient_body=$appname ne peux pas fonctionner sans que le client Tor ne soit Install\u00e9. Veuillez installer les paquets tor et tor-geoipdb pour votre distribution.
|
||||
dlg_mozillarestart_title=Avertissement\u00a0: Le navigateur $browser est actif.
|
||||
dlg_mozillarestart_body=$appname a d\u00e9tect\u00e9 que le navigateur $browser tourne d\u00e9j\u00e0.\nUn red\u00e9marrage du navigateur est exig\u00e9 pour permettre le fonctionnement de $appname.\n\nSi vous choisissez de red\u00e9marrer $browser, tous les onglets actuellement ouverts seront restaur\u00e9s au red\u00e9marrage de $browser, l'option \u00ab Afficher les dernier onglets et fen\u00eatres utilis\u00e9s \u00bb, doit \u00eatre choisie dans les options de $browser.\n\nVous pouvez d\u00e9sactiver cet avertissement du navigateur dans les Pr\u00e9f\u00e9rences de $appname.
|
||||
dlg_license_title=Licence de $appname
|
||||
dlg_exportuser_title=Exporter les mod\u00e8les d'utilisateur
|
||||
dlg_exportuser_body=Aucun mod\u00e8le cr\u00e9\u00e9 par l'utilisateur n'a \u00e9t\u00e9 trouv\u00e9.\n\nUtilisez l'\u00e9diteur de mode pour ajouter vos propres mod\u00e8les
|
||||
dlg_exportdefault_title=Exporter les mod\u00e8les par d\u00e9faut
|
||||
dlg_exportdefault_body=Aucun mod\u00e8le par d\u00e9faut n'a \u00e9t\u00e9 trouv\u00e9.
|
||||
dlg_saveuser_title=Enregistrer les modes de l'utilisateur
|
||||
dlg_savedefault_title=Enregistrer les mod\u00e8les par d\u00e9faut
|
||||
dlg_import_title=Importer le fichier des mod\u00e8les
|
||||
dlg_import_success_title=Mod\u00e8les import\u00e9s
|
||||
dlg_import_success_body=Les mod\u00e8les ont \u00e9t\u00e9 import\u00e9s avec succ\u00e8s et sont maintenant actifs.
|
||||
dlg_import_fail_title=\u00c9chec lors l'importation
|
||||
dlg_import_fail_body=Les mod\u00e8les n'ont pas \u00e9t\u00e9 import\u00e9s correctement.
|
||||
dlg_whois_title=Qui est $ipaddress
|
||||
dlg_whois_body=Veuillez patienter pendant que j'essaie de r\u00e9cup\u00e9rer les donn\u00e9s de WhoIs...
|
||||
dlg_whois_fail=D\u00e9sol\u00e9, impossible de r\u00e9cup\u00e9rer les informations de Whois.
|
||||
dlg_toold_body=Le client Tor actuellement install\u00e9 est trop ancien, Tor 0.2.7.6 ou ult\u00e9rieure est exig\u00e9e.\n\nLes utilisateurs de Linux devraient visiter la page suivante \nhttps://www.torproject.org/download/download-unix.html.en\npour obtenir le dernier client Tor.
|
||||
dlg_error_title=Erreur de d\u00e9marrage
|
||||
dlg_error_body=Cette erreur est fatale et $appname se fermera.
|
||||
dlg_quickadd_title=Ajouter un mod\u00e8le
|
||||
dlg_nodelistfail_body=La g\u00e9n\u00e9ration de la liste des n\u0153uds a \u00e9chou\u00e9 \u00e0 cause d'erreurs de GEOIP.
|
||||
dlg_patterneditsave_title=Enregistrer les mod\u00e8les actuels
|
||||
dlg_patterneditsave_body=Les mod\u00e8les actuels ont \u00e9t\u00e9 modifi\u00e9s.\n\nSi vous d\u00e9sirez les enregistrer, cliquez sur Continuer, autrement cliquez sur Annuler.
|
||||
dlg_instancefail_title=\u00c9chec d\u00fb \u00e0 plusieurs instances
|
||||
dlg_instancefail_body=Une instance de $appname est d\u00e9j\u00e0 en cours et une seule peut \u00eatre ex\u00e9cut\u00e9e \u00e0 la fois.\n\nQuittez l'instance existante de $appname ou dans le cas d'un plantage de $appname, red\u00e9marrez X en vous d\u00e9connectant et en vous connectant de nouveau.
|
||||
dlg_guardwarn_title=Avertissement de n\u0153ud de garde
|
||||
dlg_guardwarn_body=Un n\u0153ud de garde ne se trouvant pas dans votre liste de n\u0153uds de garde sp\u00e9cifi\u00e9e a \u00e9t\u00e9 utilis\u00e9.\nCeci provient probablement du fait que vos n\u0153uds de garde s\u00e9lectionn\u00e9s ne sont plus joignables et par cons\u00e9quent le client Tor a assign\u00e9 son propre n\u0153ud de garde.\n\nVous devriez v\u00e9rifier vos n\u0153uds de garde actuellement d\u00e9finis pour voir s'ils sont toujours disponibles, ou en choisir de nouveaux.
|
||||
dlg_notenoughguards_body=Il n'y a pas assez de n\u0153uds de garde d\u00e9finis afin que Tor fonctionne efficacement et en toute s\u00e9curit\u00e9.\n\nSupprimez tous les n\u0153uds de garde s\u00e9lectionn\u00e9s, ce qui permettra au client Tor de choisir ses propres n\u0153uds de garde, ou choisissez manuellement trois n\u0153uds de garde ou plus.dlg_notenoughguards_body=Il n'y a pas assez de n\u0153uds de garde d\u00e9finis afin que Tor fonctionne efficacement et en toute s\u00e9curit\u00e9.\n\nSupprimez tous les n\u0153uds de garde s\u00e9lectionn\u00e9s, ce qui permettra au client Tor de choisir ses propres n\u0153uds de garde, ou choisissez manuellement trois n\u0153uds de garde ou plus.
|
||||
dlg_bridgerr_title=\u00c9chec de validation de l'adresse de pont
|
||||
dlg_bridgerr_body=Les informations de pont fournies contiennent des erreurs de validation et ne se conforment pas \u00e0 un format d'adresse IPv4 valide h\u00f4te:port\n\nVoici des exemples de format de sp\u00e9cification de ponts :\n\nPont simple : \n127.0.0.1:8080\n\nPonts multiples : \n127.0.0.1:8080,128.5.6.8:224\n\nLes ponts ont \u00e9t\u00e9 r\u00e9initialis\u00e9s \u00e0 leurs valeurs par d\u00e9faut.
|
||||
dlg_credits_title=Cr\u00e9dits de $appname
|
||||
dlg_credits_body=Afin que votre nom apparaissent ici et pour aussi m\u00e9riter ma gratitude, veuillez envisager de soutenir le d\u00e9veloppement futur de SelekTOR sous Linux avec Patreon.
|
||||
table_popup_details=D\u00e9tails
|
||||
table_popup_whois=Qui est
|
||||
table_popup_begintest=Commencer le cycle de test
|
||||
tab_basic=De base
|
||||
tab_advanced=Avanc\u00e9
|
||||
isoA1=Mandataire annonyme
|
||||
isoO1=autre Pays
|
||||
isoU1=Inconnu
|
||||
chkbox_disablenotify=D\u00e9sactiver les notifications du bureau
|
||||
ttip_disablenotify=D\u00e9sactiver les notifications du bureau
|
||||
dlg_libnotify_title=notify-send est introuvable
|
||||
dlg_libnotify_body=Les notifications de bureau ne fonctionneront pas sans que le paquet libnotify-bin ne soit install\u00e9.\n\nPour emp\u00eacher que cette fen\u00eatre apparaissent de nouveau installez le paquet exig\u00e9 ou d\u00e9sactivez les notifications de bureau dans les pr\u00e9f\u00e9rences.
|
||||
ttip_hidemin=L'appli sera cach\u00e9e au lieu d'\u00eatre minimis\u00e9e.
|
||||
chkbox_hidemin=Cacher au lieu de minimiser
|
||||
label_autoselect= Mode de s\u00e9lection automatique :
|
||||
menu_geoip=Mettre GEOIP \u00e0 jour
|
||||
chkbox_geocheck=V\u00e9rification trimestrielle des mises \u00e0 jour GEOIP
|
||||
ttip_geocheck=SelekTOR affichera la \u00abfen\u00eatre de mise \u00e0 jour GEOIP \u00bbsi votre base de donn\u00e9es GEOIP est p\u00e9rim\u00e9e.
|
||||
dlg_geo_title=Mise \u00e0 jour des donn\u00e9es de g\u00e9olocalisation
|
||||
dlg_geo_body=Les donn\u00e9es de g\u00e9olocalisation fournies par Tor sont parfois p\u00e9rim\u00e9es. Vous pouvez demander \u00e0 SelekTOR de t\u00e9l\u00e9charger ses propres fichiers de donn\u00e9es de g\u00e9olocalisation de Dazzleships.net et de les utiliser. Ils sont mis \u00e0 jour trimestriellement.\n\nVeuillez noter que si vous choisissez de ne pas mettre \u00e0 jour, certains n\u0153uds pourraient \u00eatre assign\u00e9s au mauvais pays.\n\nLes donn\u00e9es des ces fichiers, comme les donn\u00e9es fournies par le client Tor, sont fournies par Maxmind.com.
|
||||
dload_status_contact=R\u00e9cup\u00e9ration des derni\u00e8res donn\u00e9es GEOIP
|
||||
dload_status_failed=\u00c9chec de t\u00e9l\u00e9chargement
|
||||
chkbox_viator=T\u00e9l\u00e9charger par Tor
|
||||
ttip_patterntable=\u00c9dition en ligne prise en charge, un double-clic gauche lance l'\u00e9dition d'une cellule d'un tableau.
|
||||
fileext_pattern=Fichiers de mod\u00e8les zipp\u00e9
|
256
src/resources/MessagesBundle_fr_CH.properties
Normal file
256
src/resources/MessagesBundle_fr_CH.properties
Normal file
|
@ -0,0 +1,256 @@
|
|||
# French CA, Default language file, provided by yahoe001
|
||||
gpltransurl=https://fsffrance.org/gpl/gpl-fr.fr.html
|
||||
appdesc=$appname $appver, Les n\u0153uds de sortie de Tor simplifi\u00e9s.
|
||||
text_yes=Oui
|
||||
text_no=Non
|
||||
wintitle_prefs = Pr\u00e9f\u00e9rences de $appname
|
||||
wintitle_about = \u00c0 propos de $appname
|
||||
wintitle_patternedit = \u00c9diteur de mod\u00e8les $appname
|
||||
wintitle_guardnodes=S\u00e9lection des n\u0153uds de garde
|
||||
wintitle_tormonitor=Moniteur du client Tor
|
||||
textfield_unknown=Inconnu
|
||||
progstatus_initial=Initialisation...
|
||||
progstatus_bridges=Mise en place du changement de ponts.
|
||||
progstatus_generate=G\u00e9n\u00e9ration d'une nouvelle liste de n\u0153uds, veuillez patienter.
|
||||
progstatus_cachedated=Les descripteurs en cache sont p\u00e9rim\u00e9s, ils seront renouvel\u00e9s.
|
||||
progstatus_nonet=L'acc\u00e8s \u00e0 Internet n'est pas disponible.
|
||||
progstatus_checkrecommended=Recherche des derniers n\u0153uds recommand\u00e9s.
|
||||
progstatus_torfailretry=\u00c9chec lors du d\u00e9marrage de Tor, nouvel essai.
|
||||
progstatus_nodefail=\u00c9chec lors de l'activation du n\u0153ud demand\u00e9.
|
||||
progstatus_nodefailretry=\u00c9chec lors de l'activation du n\u0153ud demand\u00e9. Nouvel essai, veuillez patienter.
|
||||
progstatus_nodefailtorchoose=Le n\u0153ud demand\u00e9 n'est pas joignable, Tor en choisira un, veuillez patienter.
|
||||
progstatus_nodeactive3hop=Le circuit \u00e0 3 sauts vers le n\u0153ud de sortie $nodename est actif.
|
||||
progstatus_nodeactive2hop=Le circuit \u00e0 2 sauts vers le n\u0153ud de sortie $nodename est actif.
|
||||
progstatus_autoswitch=Auto-commutation vers le n\u0153ud
|
||||
progstatus_manswitch=Commutation vers le n\u0153ud choisi manuellement
|
||||
progstatus_waitfortor=Attente d'activation d'un n\u0153ud par Tor.
|
||||
progstatus_switchtonode=Commutation vers le n\u0153ud $nodename.
|
||||
progstatus_applychanges=Mise en place des nouvelles pr\u00e9f\u00e9rences.
|
||||
circuit_status_creating_2hop=Cr\u00e9ation d'un circuit \u00e0 2 sauts.
|
||||
circuit_status_creating_3hop=Cr\u00e9ation d'un circuit \u00e0 3 sauts.
|
||||
circuit_status_testing=Test du circuit.
|
||||
circuit_status_aborted=Test interrompu.
|
||||
circuit_status_built=$1 circuit(s) construit(s).
|
||||
circuit_status_passed=Circuit v\u00e9rifi\u00e9.
|
||||
circuit_status_failed=\u00c9chec de circuit.
|
||||
circuit_status_none=Aucun circuit n'est disponible.
|
||||
circuit_status_noroute=Routeurs (tous) hors service.
|
||||
combo_proxymode1=D\u00e9sactiv\u00e9
|
||||
combo_proxymode2=Relais par mod\u00e8le
|
||||
combo_proxymode3=Relayer tout le trafic
|
||||
combo_loglev1=D\u00e9bogage
|
||||
combo_loglev2=Infos
|
||||
combo_loglev3=Avis
|
||||
traymenu_proxymode1=Mode : pas de relais
|
||||
traymenu_proxymode2=Mode : relais par mod\u00e8le
|
||||
traymenu_proxymode3=Mode : relayer tout le trafic
|
||||
traymenu_showgui=Cacher/Montrer l'IUG
|
||||
traytool_guardnode=Noeud de garde
|
||||
traytool_exitnode=Noeud de sortie
|
||||
exittable_col1=N\u0153ud de sortie
|
||||
exittable_col2=BP (MB\\s)
|
||||
exittable_col3=D\u00e9lai (ms)
|
||||
exittable_col4=\u00c9tat
|
||||
exittable_col5=Favori
|
||||
patterntable_col1=Description
|
||||
patterntable_col2=Mod\u00e8le
|
||||
patterntable_col3=Activ\u00e9
|
||||
guardtable_col1=N\u0153ud de garde
|
||||
guardtable_col2=Pays
|
||||
guardtable_col3=BP (MB\\s)
|
||||
guardtable_col4=De confiance
|
||||
menu_menu=Menu
|
||||
menu_prefs=Pr\u00e9f\u00e9rences
|
||||
menu_quickadd=Ajout rapide d'un mod\u00e8le
|
||||
menu_patternedit=\u00c9diteur de mod\u00e8les de relais
|
||||
menu_export=Exporter les mod\u00e8les
|
||||
menu_import=Import les mod\u00e8les
|
||||
menu_quit=Quitter
|
||||
menu_defaultpatterns=Mod\u00e8le par d\u00e9faut
|
||||
menu_userpatterns=Mod\u00e8les de l'utilisateur
|
||||
menu_help=Aide
|
||||
menu_debuglog=Voir le journal de d\u00e9bogage
|
||||
menu_helpcontents=Contenu de l'aide
|
||||
menu_torcheck=V\u00e9rification de routine de Tor
|
||||
menu_about=\u00c0 propos de
|
||||
menu_license=Licence
|
||||
menu_proxy=Mode de relais
|
||||
menu_close=Fermer le menu
|
||||
menu_tormanual=Manuel officiel de Tor
|
||||
menu_tormonitor=Moniteur du client Tor
|
||||
menu_leaktest=Test de fuite DNS
|
||||
menu_credits=Cr\u00e9dits
|
||||
label_activecountry=Pays actif :
|
||||
label_proxymode=Mode de relais :
|
||||
label_exitnode=N\u0153ud de sortie :
|
||||
label_ip=IP :
|
||||
label_torlatency=D\u00e9lai
|
||||
label_fingerprint=Empreinte :
|
||||
label_bandwidth=Bande passante
|
||||
label_streams=Flux
|
||||
label_stable=Stable
|
||||
label_status=\u00c9tat :
|
||||
label_listenport=Port d'\u00e9coute de Tor :
|
||||
label_defaultproxy=Mandataire HTTP par d\u00e9faut :
|
||||
label_bridgeaddress=Adresse de pont de Tor :
|
||||
label_portranges=Plages de port pr\u00e9sentement actives, de $portmin \u00e0 $portmax
|
||||
label_editcountry=Choisir un pays pour voir ses mod\u00e8les
|
||||
label_quickadd_desc=Description :
|
||||
label_quickadd_pattern=Mod\u00e8le :
|
||||
label_threshold=D\u00e9lai seuil
|
||||
label_middle=Milieu :
|
||||
label_exit=Sortie :
|
||||
label_nickname=Pseudonyme
|
||||
label_ip=IP
|
||||
label_country=Pays
|
||||
label_guard_minimum=Vous pouvez soit ne choisir aucun n\u0153ud de garde au cas o\u00f9 le client Tor les choisit, soit choisir trois n\u0153uds de garde ou plus.
|
||||
label_torlogging=Niveau de journalisation :
|
||||
label_torargs=Arguments de d\u00e9marrage :
|
||||
label_torsocks=Param\u00e8tres Socks :
|
||||
label_diskoptions=Options du disque :
|
||||
label_guardnode=Garde :
|
||||
label_bridgenode=Pont :
|
||||
label_donotproxy=Ne pas relayer :
|
||||
button_details=D\u00e9tails
|
||||
button_whois=Qui est
|
||||
button_close=Fermer
|
||||
button_apply=Appliquer
|
||||
button_delete=Supprimer
|
||||
button_addnew=Ajouter un nouveau
|
||||
button_save=Enregistrer
|
||||
button_cancel=Annuler
|
||||
button_continue=Continuer
|
||||
button_getbridges=Obtenir des ponts
|
||||
button_mozillarestart=Red\u00e9marrer $browser
|
||||
button_visitus=Rendez-nous visite
|
||||
button_contactus=Contactez-nous
|
||||
button_translations=Traductions non officielles
|
||||
button_prefdefaults=R\u00e9initialiser aux leurs valeurs par d\u00e9faut.
|
||||
button_setguards=D\u00e9finir les n\u0153uds de garde
|
||||
button_details=D\u00e9tails de l'atlas
|
||||
button_clearguards=Effacer les n\u0153uds de garde choisis
|
||||
button_clearfavs=Effacer les favoris
|
||||
button_support=Soutenir SelekTOR
|
||||
button_patreon=Soutenir SelekTOR avec Patreon
|
||||
panel_general=Param\u00e8tres g\u00e9n\u00e9raux
|
||||
panel_network= Param\u00e8tres r\u00e9seau
|
||||
panel_management=Param\u00e8tres de gestion des n\u0153uds
|
||||
panel_info=Circuit actif
|
||||
panel_torclientset=Param\u00e8tres du client Tor
|
||||
panel_startupargs=Arguments de d\u00e9marrage
|
||||
panel_stdout=Moniteur de sortie standard
|
||||
chkbox_autoselect=Choix automatique du n\u0153ud
|
||||
chkbox_autostart=D\u00e9marrage automatique de SelekTOR
|
||||
chkbox_checkforupdates=V\u00e9rifier les mises \u00e0 jour au d\u00e9marrage
|
||||
chkbox_disabletray=D\u00e9sactiver l'ic\u00f4ne de notification
|
||||
chkbox_autopatterns=Installer automatiquement les derniers mod\u00e8les.
|
||||
chkbox_mozillawarn=D\u00e9sactiver l'avertissement de Mozilla
|
||||
chkbox_recnodesonly=Utiliser les n\u0153uds recommand\u00e9s en mode par mod\u00e8les
|
||||
chkbox_hidetotray=Minimiser au d\u00e9marrage
|
||||
chkbox_minonclose=Minimiser plut\u00f4t que de quitter lors de la fermeture
|
||||
chkbox_safesocks=Socks s\u00e9curitaire
|
||||
chkbox_twohop=Utiliser des circuits \u00e0 2 sauts vers le n\u0153ud de sortie en mode par mod\u00e8les
|
||||
chkbox_warnunsafesocks=Avertir si \u00e0 risque
|
||||
chkbox_diskavoid=\u00c9viter les \u00e9critures sur le disque
|
||||
chkbox_testsocks=Tester Socks
|
||||
chkbox_safelog=Journalisation s\u00e9curitaire
|
||||
chkbox_guardwarn1=Afficher une fen\u00eatre d'avertissement si un n\u0153ud de garde non sp\u00e9cifi\u00e9 est utilis\u00e9
|
||||
chkbox_guardwarn2=Afficher une fen\u00eatre d'avertissement si moins de trois n\u0153uds de garde sont choisis
|
||||
chkbox_securedelete=Effacement s\u00e9curis\u00e9 des caches de Tor lors de la fermeture
|
||||
ttip_autostart=D\u00e9marrage automatique de SelekTOR lors du d\u00e9marrage/de la connexion
|
||||
ttip_hidetotray=Minimiser au d\u00e9marrage
|
||||
ttip_checkforupdates=SelekTOR v\u00e9rifiera les mises \u00e0 jour au d\u00e9marage
|
||||
ttip_autoinstall=Les derniers mod\u00e8les seront r\u00e9cup\u00e9r\u00e9s de Dazzleships.Net
|
||||
ttip_disabletray=D\u00e9sactiver l'ic\u00f4ne de notification
|
||||
ttip_mozillawarn=D\u00e9sactiver l'avertissement du navigateur Mozilla
|
||||
ttip_listenport=Le port d'\u00e9coute du client Tor
|
||||
ttip_defaultproxy=Tout trafic qui ne sera pas redirig\u00e9 par Tor sera redirig\u00e9 par ce mandataire HTTP
|
||||
ttip_donotproxy=Toute URL contenant une de ces entr\u00e9es s\u00e9par\u00e9es par des virgules ne sera pas relay\u00e9e. L'on s'y connectera directement.
|
||||
ttip_bridgeaddress=Pour contourner le blocage du FSI, ajouter une adresse de pont valide ici
|
||||
ttip_forcedns=Forcer la recherche DNS par Tor, exige le red\u00e9marrage du navigateur
|
||||
ttip_forcenode=Si coch\u00e9, le n\u0153ud sera activ\u00e9 quelque soit l'activit\u00e9 du n\u0153ud
|
||||
ttip_recnodesonly=Les n\u0153uds recommand\u00e9s seront utilis\u00e9s en mode par mod\u00e8les
|
||||
ttip_minonclose=L'application sera minimis\u00e9e au lieu de quitter \u00e0 la fermeture de la fermeture principale
|
||||
ttip_threshold=D\u00e9lai seuil
|
||||
ttip_safesocks=Activ\u00e9e, Tor rejettera les connexions logicielles qui utilisent des variantes dangereuses du protocole Socks.
|
||||
ttip_warnunsafe=Activ\u00e9e, Tor avertira \u00e0 chaque fois qu'une requ\u00eate est re\u00e7ue contenant seulement une adresse IP au lieu d'un nom d'h\u00f4te.
|
||||
ttip_testsocks=Activ\u00e9e Tor journalisera une entr\u00e9e de journal de niveau avis pour chaque connexion en indiquant si elle utilise un protocole Socks s\u00e9curitaire ou dangereux.
|
||||
ttip_safelogging=Activ\u00e9e, Tor nettoiera les cha\u00eenes potentiellement sensibles des messages de journalisation.
|
||||
ttip_avoiddisk=Activ\u00e9e, Tor essaiera d'\u00e9crire moins fr\u00e9quemment sur le disque que nous ne le ferions autrement.
|
||||
ttip_extraargs= Arguments suppl\u00e9mentaires sp\u00e9cifi\u00e9s par l'utilisateur, voir le Manuel Tor.
|
||||
ttip_combo_loglevel=Niveau de journalisation de Tor.
|
||||
ttip_twohop=Utiliser des circuits \u00e0 2 sauts au lieu des 3 par d\u00e9faut de Tor. R\u00e9duit le d\u00e9lai de transit mais affaiblit l'anonymat.
|
||||
ttip_resetbasicprefs=R\u00e9initialiser les pr\u00e9f\u00e9rences de base \u00e0 leurs valeurs par d\u00e9faut.
|
||||
ttip_resetadvprefs=R\u00e9initialiser les pr\u00e9f\u00e9rences avanc\u00e9es \u00e0 leurs valeurs par d\u00e9faut.
|
||||
ttip_guardwarn1=Activ\u00e9, une fen\u00eatre d'avertissement sera affich\u00e9e indiquant qu'un n\u0153ud de garde non sp\u00e9cifi\u00e9 est actif.
|
||||
ttip_guardwarn2=Activ\u00e9, une fen\u00eatre d'avertissement sera affich\u00e9e indiquant que trop peu de n\u0153uds de garde sont choisis
|
||||
ttip_clearguards=Effacer les n\u0153uds de garde choisis.
|
||||
ttip_securedelete=Activ\u00e9, les caches de Tor seront \u00e9cras\u00e9es par des z\u00e9ros, puis supprim\u00e9es
|
||||
dlg_update_title=Mise \u00e0 jour disponible.
|
||||
dlg_update_body=$version est maintenant disponible au t\u00e9l\u00e9chargement.
|
||||
dlg_restoreproxy_title=Param\u00e8tres originaux du mandataire
|
||||
dlg_restoreproxy_body=Choisir Continuer pour restaurer les param\u00e8tres du mandataire aux valeurs par d\u00e9faut avant l'installation de SelekTOR.
|
||||
dlg_resetproxy_title=Param\u00e8tres par d\u00e9faut du mandataire
|
||||
dlg_resetproxy_body=Choisir Continuer pour r\u00e9initialiser les param\u00e8tres du serveur mandataire \u00e0 leurs valeurs syst\u00e8me par d\u00e9faut.
|
||||
dlg_gsetting_title=Gsettings introuvable
|
||||
dlg_gsetting_body=$appname ne peux pas fonctionner correctement sans que l'ex\u00e9cutable binary soit install\u00e9. Dans certaines distributions il peut \u00eatre trouv\u00e9 dans le paquet libglib2.0-bin.
|
||||
dlg_torclient_title=Client TOR introuvable
|
||||
dlg_torclient_body=$appname ne peux pas fonctionner sans que le client Tor ne soit Install\u00e9. Veuillez installer les paquets tor et tor-geoipdb pour votre distribution.
|
||||
dlg_mozillarestart_title=Avertissement\u00a0: Le navigateur $browser est actif.
|
||||
dlg_mozillarestart_body=$appname a d\u00e9tect\u00e9 que le navigateur $browser tourne d\u00e9j\u00e0.\nUn red\u00e9marrage du navigateur est exig\u00e9 pour permettre le fonctionnement de $appname.\n\nSi vous choisissez de red\u00e9marrer $browser, tous les onglets actuellement ouverts seront restaur\u00e9s au red\u00e9marrage de $browser, l'option \u00ab Afficher les dernier onglets et fen\u00eatres utilis\u00e9s \u00bb, doit \u00eatre choisie dans les options de $browser.\n\nVous pouvez d\u00e9sactiver cet avertissement du navigateur dans les Pr\u00e9f\u00e9rences de $appname.
|
||||
dlg_license_title=Licence de $appname
|
||||
dlg_exportuser_title=Exporter les mod\u00e8les d'utilisateur
|
||||
dlg_exportuser_body=Aucun mod\u00e8le cr\u00e9\u00e9 par l'utilisateur n'a \u00e9t\u00e9 trouv\u00e9.\n\nUtilisez l'\u00e9diteur de mode pour ajouter vos propres mod\u00e8les
|
||||
dlg_exportdefault_title=Exporter les mod\u00e8les par d\u00e9faut
|
||||
dlg_exportdefault_body=Aucun mod\u00e8le par d\u00e9faut n'a \u00e9t\u00e9 trouv\u00e9.
|
||||
dlg_saveuser_title=Enregistrer les modes de l'utilisateur
|
||||
dlg_savedefault_title=Enregistrer les mod\u00e8les par d\u00e9faut
|
||||
dlg_import_title=Importer le fichier des mod\u00e8les
|
||||
dlg_import_success_title=Mod\u00e8les import\u00e9s
|
||||
dlg_import_success_body=Les mod\u00e8les ont \u00e9t\u00e9 import\u00e9s avec succ\u00e8s et sont maintenant actifs.
|
||||
dlg_import_fail_title=\u00c9chec lors l'importation
|
||||
dlg_import_fail_body=Les mod\u00e8les n'ont pas \u00e9t\u00e9 import\u00e9s correctement.
|
||||
dlg_whois_title=Qui est $ipaddress
|
||||
dlg_whois_body=Veuillez patienter pendant que j'essaie de r\u00e9cup\u00e9rer les donn\u00e9s de WhoIs...
|
||||
dlg_whois_fail=D\u00e9sol\u00e9, impossible de r\u00e9cup\u00e9rer les informations de Whois.
|
||||
dlg_toold_body=Le client Tor actuellement install\u00e9 est trop ancien, Tor 0.2.7.6 ou ult\u00e9rieure est exig\u00e9e.\n\nLes utilisateurs de Linux devraient visiter la page suivante \nhttps://www.torproject.org/download/download-unix.html.en\npour obtenir le dernier client Tor.
|
||||
dlg_error_title=Erreur de d\u00e9marrage
|
||||
dlg_error_body=Cette erreur est fatale et $appname se fermera.
|
||||
dlg_quickadd_title=Ajouter un mod\u00e8le
|
||||
dlg_nodelistfail_body=La g\u00e9n\u00e9ration de la liste des n\u0153uds a \u00e9chou\u00e9 \u00e0 cause d'erreurs de GEOIP.
|
||||
dlg_patterneditsave_title=Enregistrer les mod\u00e8les actuels
|
||||
dlg_patterneditsave_body=Les mod\u00e8les actuels ont \u00e9t\u00e9 modifi\u00e9s.\n\nSi vous d\u00e9sirez les enregistrer, cliquez sur Continuer, autrement cliquez sur Annuler.
|
||||
dlg_instancefail_title=\u00c9chec d\u00fb \u00e0 plusieurs instances
|
||||
dlg_instancefail_body=Une instance de $appname est d\u00e9j\u00e0 en cours et une seule peut \u00eatre ex\u00e9cut\u00e9e \u00e0 la fois.\n\nQuittez l'instance existante de $appname ou dans le cas d'un plantage de $appname, red\u00e9marrez X en vous d\u00e9connectant et en vous connectant de nouveau.
|
||||
dlg_guardwarn_title=Avertissement de n\u0153ud de garde
|
||||
dlg_guardwarn_body=Un n\u0153ud de garde ne se trouvant pas dans votre liste de n\u0153uds de garde sp\u00e9cifi\u00e9e a \u00e9t\u00e9 utilis\u00e9.\nCeci provient probablement du fait que vos n\u0153uds de garde s\u00e9lectionn\u00e9s ne sont plus joignables et par cons\u00e9quent le client Tor a assign\u00e9 son propre n\u0153ud de garde.\n\nVous devriez v\u00e9rifier vos n\u0153uds de garde actuellement d\u00e9finis pour voir s'ils sont toujours disponibles, ou en choisir de nouveaux.
|
||||
dlg_notenoughguards_body=Il n'y a pas assez de n\u0153uds de garde d\u00e9finis afin que Tor fonctionne efficacement et en toute s\u00e9curit\u00e9.\n\nSupprimez tous les n\u0153uds de garde s\u00e9lectionn\u00e9s, ce qui permettra au client Tor de choisir ses propres n\u0153uds de garde, ou choisissez manuellement trois n\u0153uds de garde ou plus.dlg_notenoughguards_body=Il n'y a pas assez de n\u0153uds de garde d\u00e9finis afin que Tor fonctionne efficacement et en toute s\u00e9curit\u00e9.\n\nSupprimez tous les n\u0153uds de garde s\u00e9lectionn\u00e9s, ce qui permettra au client Tor de choisir ses propres n\u0153uds de garde, ou choisissez manuellement trois n\u0153uds de garde ou plus.
|
||||
dlg_bridgerr_title=\u00c9chec de validation de l'adresse de pont
|
||||
dlg_bridgerr_body=Les informations de pont fournies contiennent des erreurs de validation et ne se conforment pas \u00e0 un format d'adresse IPv4 valide h\u00f4te:port\n\nVoici des exemples de format de sp\u00e9cification de ponts :\n\nPont simple : \n127.0.0.1:8080\n\nPonts multiples : \n127.0.0.1:8080,128.5.6.8:224\n\nLes ponts ont \u00e9t\u00e9 r\u00e9initialis\u00e9s \u00e0 leurs valeurs par d\u00e9faut.
|
||||
dlg_credits_title=Cr\u00e9dits de $appname
|
||||
dlg_credits_body=Afin que votre nom apparaissent ici et pour aussi m\u00e9riter ma gratitude, veuillez envisager de soutenir le d\u00e9veloppement futur de SelekTOR sous Linux avec Patreon.
|
||||
table_popup_details=D\u00e9tails
|
||||
table_popup_whois=Qui est
|
||||
table_popup_begintest=Commencer le cycle de test
|
||||
tab_basic=De base
|
||||
tab_advanced=Avanc\u00e9
|
||||
isoA1=Mandataire annonyme
|
||||
isoO1=autre Pays
|
||||
isoU1=Inconnu
|
||||
chkbox_disablenotify=D\u00e9sactiver les notifications du bureau
|
||||
ttip_disablenotify=D\u00e9sactiver les notifications du bureau
|
||||
dlg_libnotify_title=notify-send est introuvable
|
||||
dlg_libnotify_body=Les notifications de bureau ne fonctionneront pas sans que le paquet libnotify-bin ne soit install\u00e9.\n\nPour emp\u00eacher que cette fen\u00eatre apparaissent de nouveau installez le paquet exig\u00e9 ou d\u00e9sactivez les notifications de bureau dans les pr\u00e9f\u00e9rences.
|
||||
ttip_hidemin=L'appli sera cach\u00e9e au lieu d'\u00eatre minimis\u00e9e.
|
||||
chkbox_hidemin=Cacher au lieu de minimiser
|
||||
label_autoselect= Mode de s\u00e9lection automatique :
|
||||
menu_geoip=Mettre GEOIP \u00e0 jour
|
||||
chkbox_geocheck=V\u00e9rification trimestrielle des mises \u00e0 jour GEOIP
|
||||
ttip_geocheck=SelekTOR affichera la \u00abfen\u00eatre de mise \u00e0 jour GEOIP \u00bbsi votre base de donn\u00e9es GEOIP est p\u00e9rim\u00e9e.
|
||||
dlg_geo_title=Mise \u00e0 jour des donn\u00e9es de g\u00e9olocalisation
|
||||
dlg_geo_body=Les donn\u00e9es de g\u00e9olocalisation fournies par Tor sont parfois p\u00e9rim\u00e9es. Vous pouvez demander \u00e0 SelekTOR de t\u00e9l\u00e9charger ses propres fichiers de donn\u00e9es de g\u00e9olocalisation de Dazzleships.net et de les utiliser. Ils sont mis \u00e0 jour trimestriellement.\n\nVeuillez noter que si vous choisissez de ne pas mettre \u00e0 jour, certains n\u0153uds pourraient \u00eatre assign\u00e9s au mauvais pays.\n\nLes donn\u00e9es des ces fichiers, comme les donn\u00e9es fournies par le client Tor, sont fournies par Maxmind.com.
|
||||
dload_status_contact=R\u00e9cup\u00e9ration des derni\u00e8res donn\u00e9es GEOIP
|
||||
dload_status_failed=\u00c9chec de t\u00e9l\u00e9chargement
|
||||
chkbox_viator=T\u00e9l\u00e9charger par Tor
|
||||
ttip_patterntable=\u00c9dition en ligne prise en charge, un double-clic gauche lance l'\u00e9dition d'une cellule d'un tableau.
|
||||
fileext_pattern=Fichiers de mod\u00e8les zipp\u00e9
|
256
src/resources/MessagesBundle_fr_FR.properties
Normal file
256
src/resources/MessagesBundle_fr_FR.properties
Normal file
|
@ -0,0 +1,256 @@
|
|||
# French CA, Default language file, provided by yahoe001
|
||||
gpltransurl=https://fsffrance.org/gpl/gpl-fr.fr.html
|
||||
appdesc=$appname $appver, Les n\u0153uds de sortie de Tor simplifi\u00e9s.
|
||||
text_yes=Oui
|
||||
text_no=Non
|
||||
wintitle_prefs = Pr\u00e9f\u00e9rences de $appname
|
||||
wintitle_about = \u00c0 propos de $appname
|
||||
wintitle_patternedit = \u00c9diteur de mod\u00e8les $appname
|
||||
wintitle_guardnodes=S\u00e9lection des n\u0153uds de garde
|
||||
wintitle_tormonitor=Moniteur du client Tor
|
||||
textfield_unknown=Inconnu
|
||||
progstatus_initial=Initialisation...
|
||||
progstatus_bridges=Mise en place du changement de ponts.
|
||||
progstatus_generate=G\u00e9n\u00e9ration d'une nouvelle liste de n\u0153uds, veuillez patienter.
|
||||
progstatus_cachedated=Les descripteurs en cache sont p\u00e9rim\u00e9s, ils seront renouvel\u00e9s.
|
||||
progstatus_nonet=L'acc\u00e8s \u00e0 Internet n'est pas disponible.
|
||||
progstatus_checkrecommended=Recherche des derniers n\u0153uds recommand\u00e9s.
|
||||
progstatus_torfailretry=\u00c9chec lors du d\u00e9marrage de Tor, nouvel essai.
|
||||
progstatus_nodefail=\u00c9chec lors de l'activation du n\u0153ud demand\u00e9.
|
||||
progstatus_nodefailretry=\u00c9chec lors de l'activation du n\u0153ud demand\u00e9. Nouvel essai, veuillez patienter.
|
||||
progstatus_nodefailtorchoose=Le n\u0153ud demand\u00e9 n'est pas joignable, Tor en choisira un, veuillez patienter.
|
||||
progstatus_nodeactive3hop=Le circuit \u00e0 3 sauts vers le n\u0153ud de sortie $nodename est actif.
|
||||
progstatus_nodeactive2hop=Le circuit \u00e0 2 sauts vers le n\u0153ud de sortie $nodename est actif.
|
||||
progstatus_autoswitch=Auto-commutation vers le n\u0153ud
|
||||
progstatus_manswitch=Commutation vers le n\u0153ud choisi manuellement
|
||||
progstatus_waitfortor=Attente d'activation d'un n\u0153ud par Tor.
|
||||
progstatus_switchtonode=Commutation vers le n\u0153ud $nodename.
|
||||
progstatus_applychanges=Mise en place des nouvelles pr\u00e9f\u00e9rences.
|
||||
circuit_status_creating_2hop=Cr\u00e9ation d'un circuit \u00e0 2 sauts.
|
||||
circuit_status_creating_3hop=Cr\u00e9ation d'un circuit \u00e0 3 sauts.
|
||||
circuit_status_testing=Test du circuit.
|
||||
circuit_status_aborted=Test interrompu.
|
||||
circuit_status_built=$1 circuit(s) construit(s).
|
||||
circuit_status_passed=Circuit v\u00e9rifi\u00e9.
|
||||
circuit_status_failed=\u00c9chec de circuit.
|
||||
circuit_status_none=Aucun circuit n'est disponible.
|
||||
circuit_status_noroute=Routeurs (tous) hors service.
|
||||
combo_proxymode1=D\u00e9sactiv\u00e9
|
||||
combo_proxymode2=Relais par mod\u00e8le
|
||||
combo_proxymode3=Relayer tout le trafic
|
||||
combo_loglev1=D\u00e9bogage
|
||||
combo_loglev2=Infos
|
||||
combo_loglev3=Avis
|
||||
traymenu_proxymode1=Mode : pas de relais
|
||||
traymenu_proxymode2=Mode : relais par mod\u00e8le
|
||||
traymenu_proxymode3=Mode : relayer tout le trafic
|
||||
traymenu_showgui=Cacher/Montrer l'IUG
|
||||
traytool_guardnode=Noeud de garde
|
||||
traytool_exitnode=Noeud de sortie
|
||||
exittable_col1=N\u0153ud de sortie
|
||||
exittable_col2=BP (MB\\s)
|
||||
exittable_col3=D\u00e9lai (ms)
|
||||
exittable_col4=\u00c9tat
|
||||
exittable_col5=Favori
|
||||
patterntable_col1=Description
|
||||
patterntable_col2=Mod\u00e8le
|
||||
patterntable_col3=Activ\u00e9
|
||||
guardtable_col1=N\u0153ud de garde
|
||||
guardtable_col2=Pays
|
||||
guardtable_col3=BP (MB\\s)
|
||||
guardtable_col4=De confiance
|
||||
menu_menu=Menu
|
||||
menu_prefs=Pr\u00e9f\u00e9rences
|
||||
menu_quickadd=Ajout rapide d'un mod\u00e8le
|
||||
menu_patternedit=\u00c9diteur de mod\u00e8les de relais
|
||||
menu_export=Exporter les mod\u00e8les
|
||||
menu_import=Import les mod\u00e8les
|
||||
menu_quit=Quitter
|
||||
menu_defaultpatterns=Mod\u00e8le par d\u00e9faut
|
||||
menu_userpatterns=Mod\u00e8les de l'utilisateur
|
||||
menu_help=Aide
|
||||
menu_debuglog=Voir le journal de d\u00e9bogage
|
||||
menu_helpcontents=Contenu de l'aide
|
||||
menu_torcheck=V\u00e9rification de routine de Tor
|
||||
menu_about=\u00c0 propos de
|
||||
menu_license=Licence
|
||||
menu_proxy=Mode de relais
|
||||
menu_close=Fermer le menu
|
||||
menu_tormanual=Manuel officiel de Tor
|
||||
menu_tormonitor=Moniteur du client Tor
|
||||
menu_leaktest=Test de fuite DNS
|
||||
menu_credits=Cr\u00e9dits
|
||||
label_activecountry=Pays actif :
|
||||
label_proxymode=Mode de relais :
|
||||
label_exitnode=N\u0153ud de sortie :
|
||||
label_ip=IP :
|
||||
label_torlatency=D\u00e9lai
|
||||
label_fingerprint=Empreinte :
|
||||
label_bandwidth=Bande passante
|
||||
label_streams=Flux
|
||||
label_stable=Stable
|
||||
label_status=\u00c9tat :
|
||||
label_listenport=Port d'\u00e9coute de Tor :
|
||||
label_defaultproxy=Mandataire HTTP par d\u00e9faut :
|
||||
label_bridgeaddress=Adresse de pont de Tor :
|
||||
label_portranges=Plages de port pr\u00e9sentement actives, de $portmin \u00e0 $portmax
|
||||
label_editcountry=Choisir un pays pour voir ses mod\u00e8les
|
||||
label_quickadd_desc=Description :
|
||||
label_quickadd_pattern=Mod\u00e8le :
|
||||
label_threshold=D\u00e9lai seuil
|
||||
label_middle=Milieu :
|
||||
label_exit=Sortie :
|
||||
label_nickname=Pseudonyme
|
||||
label_ip=IP
|
||||
label_country=Pays
|
||||
label_guard_minimum=Vous pouvez soit ne choisir aucun n\u0153ud de garde au cas o\u00f9 le client Tor les choisit, soit choisir trois n\u0153uds de garde ou plus.
|
||||
label_torlogging=Niveau de journalisation :
|
||||
label_torargs=Arguments de d\u00e9marrage :
|
||||
label_torsocks=Param\u00e8tres Socks :
|
||||
label_diskoptions=Options du disque :
|
||||
label_guardnode=Garde :
|
||||
label_bridgenode=Pont :
|
||||
label_donotproxy=Ne pas relayer :
|
||||
button_details=D\u00e9tails
|
||||
button_whois=Qui est
|
||||
button_close=Fermer
|
||||
button_apply=Appliquer
|
||||
button_delete=Supprimer
|
||||
button_addnew=Ajouter un nouveau
|
||||
button_save=Enregistrer
|
||||
button_cancel=Annuler
|
||||
button_continue=Continuer
|
||||
button_getbridges=Obtenir des ponts
|
||||
button_mozillarestart=Red\u00e9marrer $browser
|
||||
button_visitus=Rendez-nous visite
|
||||
button_contactus=Contactez-nous
|
||||
button_translations=Traductions non officielles
|
||||
button_prefdefaults=R\u00e9initialiser aux leurs valeurs par d\u00e9faut.
|
||||
button_setguards=D\u00e9finir les n\u0153uds de garde
|
||||
button_details=D\u00e9tails de l'atlas
|
||||
button_clearguards=Effacer les n\u0153uds de garde choisis
|
||||
button_clearfavs=Effacer les favoris
|
||||
button_support=Soutenir SelekTOR
|
||||
button_patreon=Soutenir SelekTOR avec Patreon
|
||||
panel_general=Param\u00e8tres g\u00e9n\u00e9raux
|
||||
panel_network= Param\u00e8tres r\u00e9seau
|
||||
panel_management=Param\u00e8tres de gestion des n\u0153uds
|
||||
panel_info=Circuit actif
|
||||
panel_torclientset=Param\u00e8tres du client Tor
|
||||
panel_startupargs=Arguments de d\u00e9marrage
|
||||
panel_stdout=Moniteur de sortie standard
|
||||
chkbox_autoselect=Choix automatique du n\u0153ud
|
||||
chkbox_autostart=D\u00e9marrage automatique de SelekTOR
|
||||
chkbox_checkforupdates=V\u00e9rifier les mises \u00e0 jour au d\u00e9marrage
|
||||
chkbox_disabletray=D\u00e9sactiver l'ic\u00f4ne de notification
|
||||
chkbox_autopatterns=Installer automatiquement les derniers mod\u00e8les.
|
||||
chkbox_mozillawarn=D\u00e9sactiver l'avertissement de Mozilla
|
||||
chkbox_recnodesonly=Utiliser les n\u0153uds recommand\u00e9s en mode par mod\u00e8les
|
||||
chkbox_hidetotray=Minimiser au d\u00e9marrage
|
||||
chkbox_minonclose=Minimiser plut\u00f4t que de quitter lors de la fermeture
|
||||
chkbox_safesocks=Socks s\u00e9curitaire
|
||||
chkbox_twohop=Utiliser des circuits \u00e0 2 sauts vers le n\u0153ud de sortie en mode par mod\u00e8les
|
||||
chkbox_warnunsafesocks=Avertir si \u00e0 risque
|
||||
chkbox_diskavoid=\u00c9viter les \u00e9critures sur le disque
|
||||
chkbox_testsocks=Tester Socks
|
||||
chkbox_safelog=Journalisation s\u00e9curitaire
|
||||
chkbox_guardwarn1=Afficher une fen\u00eatre d'avertissement si un n\u0153ud de garde non sp\u00e9cifi\u00e9 est utilis\u00e9
|
||||
chkbox_guardwarn2=Afficher une fen\u00eatre d'avertissement si moins de trois n\u0153uds de garde sont choisis
|
||||
chkbox_securedelete=Effacement s\u00e9curis\u00e9 des caches de Tor lors de la fermeture
|
||||
ttip_autostart=D\u00e9marrage automatique de SelekTOR lors du d\u00e9marrage/de la connexion
|
||||
ttip_hidetotray=Minimiser au d\u00e9marrage
|
||||
ttip_checkforupdates=SelekTOR v\u00e9rifiera les mises \u00e0 jour au d\u00e9marage
|
||||
ttip_autoinstall=Les derniers mod\u00e8les seront r\u00e9cup\u00e9r\u00e9s de Dazzleships.Net
|
||||
ttip_disabletray=D\u00e9sactiver l'ic\u00f4ne de notification
|
||||
ttip_mozillawarn=D\u00e9sactiver l'avertissement du navigateur Mozilla
|
||||
ttip_listenport=Le port d'\u00e9coute du client Tor
|
||||
ttip_defaultproxy=Tout trafic qui ne sera pas redirig\u00e9 par Tor sera redirig\u00e9 par ce mandataire HTTP
|
||||
ttip_donotproxy=Toute URL contenant une de ces entr\u00e9es s\u00e9par\u00e9es par des virgules ne sera pas relay\u00e9e. L'on s'y connectera directement.
|
||||
ttip_bridgeaddress=Pour contourner le blocage du FSI, ajouter une adresse de pont valide ici
|
||||
ttip_forcedns=Forcer la recherche DNS par Tor, exige le red\u00e9marrage du navigateur
|
||||
ttip_forcenode=Si coch\u00e9, le n\u0153ud sera activ\u00e9 quelque soit l'activit\u00e9 du n\u0153ud
|
||||
ttip_recnodesonly=Les n\u0153uds recommand\u00e9s seront utilis\u00e9s en mode par mod\u00e8les
|
||||
ttip_minonclose=L'application sera minimis\u00e9e au lieu de quitter \u00e0 la fermeture de la fermeture principale
|
||||
ttip_threshold=D\u00e9lai seuil
|
||||
ttip_safesocks=Activ\u00e9e, Tor rejettera les connexions logicielles qui utilisent des variantes dangereuses du protocole Socks.
|
||||
ttip_warnunsafe=Activ\u00e9e, Tor avertira \u00e0 chaque fois qu'une requ\u00eate est re\u00e7ue contenant seulement une adresse IP au lieu d'un nom d'h\u00f4te.
|
||||
ttip_testsocks=Activ\u00e9e Tor journalisera une entr\u00e9e de journal de niveau avis pour chaque connexion en indiquant si elle utilise un protocole Socks s\u00e9curitaire ou dangereux.
|
||||
ttip_safelogging=Activ\u00e9e, Tor nettoiera les cha\u00eenes potentiellement sensibles des messages de journalisation.
|
||||
ttip_avoiddisk=Activ\u00e9e, Tor essaiera d'\u00e9crire moins fr\u00e9quemment sur le disque que nous ne le ferions autrement.
|
||||
ttip_extraargs= Arguments suppl\u00e9mentaires sp\u00e9cifi\u00e9s par l'utilisateur, voir le Manuel Tor.
|
||||
ttip_combo_loglevel=Niveau de journalisation de Tor.
|
||||
ttip_twohop=Utiliser des circuits \u00e0 2 sauts au lieu des 3 par d\u00e9faut de Tor. R\u00e9duit le d\u00e9lai de transit mais affaiblit l'anonymat.
|
||||
ttip_resetbasicprefs=R\u00e9initialiser les pr\u00e9f\u00e9rences de base \u00e0 leurs valeurs par d\u00e9faut.
|
||||
ttip_resetadvprefs=R\u00e9initialiser les pr\u00e9f\u00e9rences avanc\u00e9es \u00e0 leurs valeurs par d\u00e9faut.
|
||||
ttip_guardwarn1=Activ\u00e9, une fen\u00eatre d'avertissement sera affich\u00e9e indiquant qu'un n\u0153ud de garde non sp\u00e9cifi\u00e9 est actif.
|
||||
ttip_guardwarn2=Activ\u00e9, une fen\u00eatre d'avertissement sera affich\u00e9e indiquant que trop peu de n\u0153uds de garde sont choisis
|
||||
ttip_clearguards=Effacer les n\u0153uds de garde choisis.
|
||||
ttip_securedelete=Activ\u00e9, les caches de Tor seront \u00e9cras\u00e9es par des z\u00e9ros, puis supprim\u00e9es
|
||||
dlg_update_title=Mise \u00e0 jour disponible.
|
||||
dlg_update_body=$version est maintenant disponible au t\u00e9l\u00e9chargement.
|
||||
dlg_restoreproxy_title=Param\u00e8tres originaux du mandataire
|
||||
dlg_restoreproxy_body=Choisir Continuer pour restaurer les param\u00e8tres du mandataire aux valeurs par d\u00e9faut avant l'installation de SelekTOR.
|
||||
dlg_resetproxy_title=Param\u00e8tres par d\u00e9faut du mandataire
|
||||
dlg_resetproxy_body=Choisir Continuer pour r\u00e9initialiser les param\u00e8tres du serveur mandataire \u00e0 leurs valeurs syst\u00e8me par d\u00e9faut.
|
||||
dlg_gsetting_title=Gsettings introuvable
|
||||
dlg_gsetting_body=$appname ne peux pas fonctionner correctement sans que l'ex\u00e9cutable binary soit install\u00e9. Dans certaines distributions il peut \u00eatre trouv\u00e9 dans le paquet libglib2.0-bin.
|
||||
dlg_torclient_title=Client TOR introuvable
|
||||
dlg_torclient_body=$appname ne peux pas fonctionner sans que le client Tor ne soit Install\u00e9. Veuillez installer les paquets tor et tor-geoipdb pour votre distribution.
|
||||
dlg_mozillarestart_title=Avertissement\u00a0: Le navigateur $browser est actif.
|
||||
dlg_mozillarestart_body=$appname a d\u00e9tect\u00e9 que le navigateur $browser tourne d\u00e9j\u00e0.\nUn red\u00e9marrage du navigateur est exig\u00e9 pour permettre le fonctionnement de $appname.\n\nSi vous choisissez de red\u00e9marrer $browser, tous les onglets actuellement ouverts seront restaur\u00e9s au red\u00e9marrage de $browser, l'option \u00ab Afficher les dernier onglets et fen\u00eatres utilis\u00e9s \u00bb, doit \u00eatre choisie dans les options de $browser.\n\nVous pouvez d\u00e9sactiver cet avertissement du navigateur dans les Pr\u00e9f\u00e9rences de $appname.
|
||||
dlg_license_title=Licence de $appname
|
||||
dlg_exportuser_title=Exporter les mod\u00e8les d'utilisateur
|
||||
dlg_exportuser_body=Aucun mod\u00e8le cr\u00e9\u00e9 par l'utilisateur n'a \u00e9t\u00e9 trouv\u00e9.\n\nUtilisez l'\u00e9diteur de mode pour ajouter vos propres mod\u00e8les
|
||||
dlg_exportdefault_title=Exporter les mod\u00e8les par d\u00e9faut
|
||||
dlg_exportdefault_body=Aucun mod\u00e8le par d\u00e9faut n'a \u00e9t\u00e9 trouv\u00e9.
|
||||
dlg_saveuser_title=Enregistrer les modes de l'utilisateur
|
||||
dlg_savedefault_title=Enregistrer les mod\u00e8les par d\u00e9faut
|
||||
dlg_import_title=Importer le fichier des mod\u00e8les
|
||||
dlg_import_success_title=Mod\u00e8les import\u00e9s
|
||||
dlg_import_success_body=Les mod\u00e8les ont \u00e9t\u00e9 import\u00e9s avec succ\u00e8s et sont maintenant actifs.
|
||||
dlg_import_fail_title=\u00c9chec lors l'importation
|
||||
dlg_import_fail_body=Les mod\u00e8les n'ont pas \u00e9t\u00e9 import\u00e9s correctement.
|
||||
dlg_whois_title=Qui est $ipaddress
|
||||
dlg_whois_body=Veuillez patienter pendant que j'essaie de r\u00e9cup\u00e9rer les donn\u00e9s de WhoIs...
|
||||
dlg_whois_fail=D\u00e9sol\u00e9, impossible de r\u00e9cup\u00e9rer les informations de Whois.
|
||||
dlg_toold_body=Le client Tor actuellement install\u00e9 est trop ancien, Tor 0.2.7.6 ou ult\u00e9rieure est exig\u00e9e.\n\nLes utilisateurs de Linux devraient visiter la page suivante \nhttps://www.torproject.org/download/download-unix.html.en\npour obtenir le dernier client Tor.
|
||||
dlg_error_title=Erreur de d\u00e9marrage
|
||||
dlg_error_body=Cette erreur est fatale et $appname se fermera.
|
||||
dlg_quickadd_title=Ajouter un mod\u00e8le
|
||||
dlg_nodelistfail_body=La g\u00e9n\u00e9ration de la liste des n\u0153uds a \u00e9chou\u00e9 \u00e0 cause d'erreurs de GEOIP.
|
||||
dlg_patterneditsave_title=Enregistrer les mod\u00e8les actuels
|
||||
dlg_patterneditsave_body=Les mod\u00e8les actuels ont \u00e9t\u00e9 modifi\u00e9s.\n\nSi vous d\u00e9sirez les enregistrer, cliquez sur Continuer, autrement cliquez sur Annuler.
|
||||
dlg_instancefail_title=\u00c9chec d\u00fb \u00e0 plusieurs instances
|
||||
dlg_instancefail_body=Une instance de $appname est d\u00e9j\u00e0 en cours et une seule peut \u00eatre ex\u00e9cut\u00e9e \u00e0 la fois.\n\nQuittez l'instance existante de $appname ou dans le cas d'un plantage de $appname, red\u00e9marrez X en vous d\u00e9connectant et en vous connectant de nouveau.
|
||||
dlg_guardwarn_title=Avertissement de n\u0153ud de garde
|
||||
dlg_guardwarn_body=Un n\u0153ud de garde ne se trouvant pas dans votre liste de n\u0153uds de garde sp\u00e9cifi\u00e9e a \u00e9t\u00e9 utilis\u00e9.\nCeci provient probablement du fait que vos n\u0153uds de garde s\u00e9lectionn\u00e9s ne sont plus joignables et par cons\u00e9quent le client Tor a assign\u00e9 son propre n\u0153ud de garde.\n\nVous devriez v\u00e9rifier vos n\u0153uds de garde actuellement d\u00e9finis pour voir s'ils sont toujours disponibles, ou en choisir de nouveaux.
|
||||
dlg_notenoughguards_body=Il n'y a pas assez de n\u0153uds de garde d\u00e9finis afin que Tor fonctionne efficacement et en toute s\u00e9curit\u00e9.\n\nSupprimez tous les n\u0153uds de garde s\u00e9lectionn\u00e9s, ce qui permettra au client Tor de choisir ses propres n\u0153uds de garde, ou choisissez manuellement trois n\u0153uds de garde ou plus.dlg_notenoughguards_body=Il n'y a pas assez de n\u0153uds de garde d\u00e9finis afin que Tor fonctionne efficacement et en toute s\u00e9curit\u00e9.\n\nSupprimez tous les n\u0153uds de garde s\u00e9lectionn\u00e9s, ce qui permettra au client Tor de choisir ses propres n\u0153uds de garde, ou choisissez manuellement trois n\u0153uds de garde ou plus.
|
||||
dlg_bridgerr_title=\u00c9chec de validation de l'adresse de pont
|
||||
dlg_bridgerr_body=Les informations de pont fournies contiennent des erreurs de validation et ne se conforment pas \u00e0 un format d'adresse IPv4 valide h\u00f4te:port\n\nVoici des exemples de format de sp\u00e9cification de ponts :\n\nPont simple : \n127.0.0.1:8080\n\nPonts multiples : \n127.0.0.1:8080,128.5.6.8:224\n\nLes ponts ont \u00e9t\u00e9 r\u00e9initialis\u00e9s \u00e0 leurs valeurs par d\u00e9faut.
|
||||
dlg_credits_title=Cr\u00e9dits de $appname
|
||||
dlg_credits_body=Afin que votre nom apparaissent ici et pour aussi m\u00e9riter ma gratitude, veuillez envisager de soutenir le d\u00e9veloppement futur de SelekTOR sous Linux avec Patreon.
|
||||
table_popup_details=D\u00e9tails
|
||||
table_popup_whois=Qui est
|
||||
table_popup_begintest=Commencer le cycle de test
|
||||
tab_basic=De base
|
||||
tab_advanced=Avanc\u00e9
|
||||
isoA1=Mandataire annonyme
|
||||
isoO1=autre Pays
|
||||
isoU1=Inconnu
|
||||
chkbox_disablenotify=D\u00e9sactiver les notifications du bureau
|
||||
ttip_disablenotify=D\u00e9sactiver les notifications du bureau
|
||||
dlg_libnotify_title=notify-send est introuvable
|
||||
dlg_libnotify_body=Les notifications de bureau ne fonctionneront pas sans que le paquet libnotify-bin ne soit install\u00e9.\n\nPour emp\u00eacher que cette fen\u00eatre apparaissent de nouveau installez le paquet exig\u00e9 ou d\u00e9sactivez les notifications de bureau dans les pr\u00e9f\u00e9rences.
|
||||
ttip_hidemin=L'appli sera cach\u00e9e au lieu d'\u00eatre minimis\u00e9e.
|
||||
chkbox_hidemin=Cacher au lieu de minimiser
|
||||
label_autoselect= Mode de s\u00e9lection automatique :
|
||||
menu_geoip=Mettre GEOIP \u00e0 jour
|
||||
chkbox_geocheck=V\u00e9rification trimestrielle des mises \u00e0 jour GEOIP
|
||||
ttip_geocheck=SelekTOR affichera la \u00abfen\u00eatre de mise \u00e0 jour GEOIP \u00bbsi votre base de donn\u00e9es GEOIP est p\u00e9rim\u00e9e.
|
||||
dlg_geo_title=Mise \u00e0 jour des donn\u00e9es de g\u00e9olocalisation
|
||||
dlg_geo_body=Les donn\u00e9es de g\u00e9olocalisation fournies par Tor sont parfois p\u00e9rim\u00e9es. Vous pouvez demander \u00e0 SelekTOR de t\u00e9l\u00e9charger ses propres fichiers de donn\u00e9es de g\u00e9olocalisation de Dazzleships.net et de les utiliser. Ils sont mis \u00e0 jour trimestriellement.\n\nVeuillez noter que si vous choisissez de ne pas mettre \u00e0 jour, certains n\u0153uds pourraient \u00eatre assign\u00e9s au mauvais pays.\n\nLes donn\u00e9es des ces fichiers, comme les donn\u00e9es fournies par le client Tor, sont fournies par Maxmind.com.
|
||||
dload_status_contact=R\u00e9cup\u00e9ration des derni\u00e8res donn\u00e9es GEOIP
|
||||
dload_status_failed=\u00c9chec de t\u00e9l\u00e9chargement
|
||||
chkbox_viator=T\u00e9l\u00e9charger par Tor
|
||||
ttip_patterntable=\u00c9dition en ligne prise en charge, un double-clic gauche lance l'\u00e9dition d'une cellule d'un tableau.
|
||||
fileext_pattern=Fichiers de mod\u00e8les zipp\u00e9
|
256
src/resources/MessagesBundle_fr_LU.properties
Normal file
256
src/resources/MessagesBundle_fr_LU.properties
Normal file
|
@ -0,0 +1,256 @@
|
|||
# French CA, Default language file, provided by yahoe001
|
||||
gpltransurl=https://fsffrance.org/gpl/gpl-fr.fr.html
|
||||
appdesc=$appname $appver, Les n\u0153uds de sortie de Tor simplifi\u00e9s.
|
||||
text_yes=Oui
|
||||
text_no=Non
|
||||
wintitle_prefs = Pr\u00e9f\u00e9rences de $appname
|
||||
wintitle_about = \u00c0 propos de $appname
|
||||
wintitle_patternedit = \u00c9diteur de mod\u00e8les $appname
|
||||
wintitle_guardnodes=S\u00e9lection des n\u0153uds de garde
|
||||
wintitle_tormonitor=Moniteur du client Tor
|
||||
textfield_unknown=Inconnu
|
||||
progstatus_initial=Initialisation...
|
||||
progstatus_bridges=Mise en place du changement de ponts.
|
||||
progstatus_generate=G\u00e9n\u00e9ration d'une nouvelle liste de n\u0153uds, veuillez patienter.
|
||||
progstatus_cachedated=Les descripteurs en cache sont p\u00e9rim\u00e9s, ils seront renouvel\u00e9s.
|
||||
progstatus_nonet=L'acc\u00e8s \u00e0 Internet n'est pas disponible.
|
||||
progstatus_checkrecommended=Recherche des derniers n\u0153uds recommand\u00e9s.
|
||||
progstatus_torfailretry=\u00c9chec lors du d\u00e9marrage de Tor, nouvel essai.
|
||||
progstatus_nodefail=\u00c9chec lors de l'activation du n\u0153ud demand\u00e9.
|
||||
progstatus_nodefailretry=\u00c9chec lors de l'activation du n\u0153ud demand\u00e9. Nouvel essai, veuillez patienter.
|
||||
progstatus_nodefailtorchoose=Le n\u0153ud demand\u00e9 n'est pas joignable, Tor en choisira un, veuillez patienter.
|
||||
progstatus_nodeactive3hop=Le circuit \u00e0 3 sauts vers le n\u0153ud de sortie $nodename est actif.
|
||||
progstatus_nodeactive2hop=Le circuit \u00e0 2 sauts vers le n\u0153ud de sortie $nodename est actif.
|
||||
progstatus_autoswitch=Auto-commutation vers le n\u0153ud
|
||||
progstatus_manswitch=Commutation vers le n\u0153ud choisi manuellement
|
||||
progstatus_waitfortor=Attente d'activation d'un n\u0153ud par Tor.
|
||||
progstatus_switchtonode=Commutation vers le n\u0153ud $nodename.
|
||||
progstatus_applychanges=Mise en place des nouvelles pr\u00e9f\u00e9rences.
|
||||
circuit_status_creating_2hop=Cr\u00e9ation d'un circuit \u00e0 2 sauts.
|
||||
circuit_status_creating_3hop=Cr\u00e9ation d'un circuit \u00e0 3 sauts.
|
||||
circuit_status_testing=Test du circuit.
|
||||
circuit_status_aborted=Test interrompu.
|
||||
circuit_status_built=$1 circuit(s) construit(s).
|
||||
circuit_status_passed=Circuit v\u00e9rifi\u00e9.
|
||||
circuit_status_failed=\u00c9chec de circuit.
|
||||
circuit_status_none=Aucun circuit n'est disponible.
|
||||
circuit_status_noroute=Routeurs (tous) hors service.
|
||||
combo_proxymode1=D\u00e9sactiv\u00e9
|
||||
combo_proxymode2=Relais par mod\u00e8le
|
||||
combo_proxymode3=Relayer tout le trafic
|
||||
combo_loglev1=D\u00e9bogage
|
||||
combo_loglev2=Infos
|
||||
combo_loglev3=Avis
|
||||
traymenu_proxymode1=Mode : pas de relais
|
||||
traymenu_proxymode2=Mode : relais par mod\u00e8le
|
||||
traymenu_proxymode3=Mode : relayer tout le trafic
|
||||
traymenu_showgui=Cacher/Montrer l'IUG
|
||||
traytool_guardnode=Noeud de garde
|
||||
traytool_exitnode=Noeud de sortie
|
||||
exittable_col1=N\u0153ud de sortie
|
||||
exittable_col2=BP (MB\\s)
|
||||
exittable_col3=D\u00e9lai (ms)
|
||||
exittable_col4=\u00c9tat
|
||||
exittable_col5=Favori
|
||||
patterntable_col1=Description
|
||||
patterntable_col2=Mod\u00e8le
|
||||
patterntable_col3=Activ\u00e9
|
||||
guardtable_col1=N\u0153ud de garde
|
||||
guardtable_col2=Pays
|
||||
guardtable_col3=BP (MB\\s)
|
||||
guardtable_col4=De confiance
|
||||
menu_menu=Menu
|
||||
menu_prefs=Pr\u00e9f\u00e9rences
|
||||
menu_quickadd=Ajout rapide d'un mod\u00e8le
|
||||
menu_patternedit=\u00c9diteur de mod\u00e8les de relais
|
||||
menu_export=Exporter les mod\u00e8les
|
||||
menu_import=Import les mod\u00e8les
|
||||
menu_quit=Quitter
|
||||
menu_defaultpatterns=Mod\u00e8le par d\u00e9faut
|
||||
menu_userpatterns=Mod\u00e8les de l'utilisateur
|
||||
menu_help=Aide
|
||||
menu_debuglog=Voir le journal de d\u00e9bogage
|
||||
menu_helpcontents=Contenu de l'aide
|
||||
menu_torcheck=V\u00e9rification de routine de Tor
|
||||
menu_about=\u00c0 propos de
|
||||
menu_license=Licence
|
||||
menu_proxy=Mode de relais
|
||||
menu_close=Fermer le menu
|
||||
menu_tormanual=Manuel officiel de Tor
|
||||
menu_tormonitor=Moniteur du client Tor
|
||||
menu_leaktest=Test de fuite DNS
|
||||
menu_credits=Cr\u00e9dits
|
||||
label_activecountry=Pays actif :
|
||||
label_proxymode=Mode de relais :
|
||||
label_exitnode=N\u0153ud de sortie :
|
||||
label_ip=IP :
|
||||
label_torlatency=D\u00e9lai
|
||||
label_fingerprint=Empreinte :
|
||||
label_bandwidth=Bande passante
|
||||
label_streams=Flux
|
||||
label_stable=Stable
|
||||
label_status=\u00c9tat :
|
||||
label_listenport=Port d'\u00e9coute de Tor :
|
||||
label_defaultproxy=Mandataire HTTP par d\u00e9faut :
|
||||
label_bridgeaddress=Adresse de pont de Tor :
|
||||
label_portranges=Plages de port pr\u00e9sentement actives, de $portmin \u00e0 $portmax
|
||||
label_editcountry=Choisir un pays pour voir ses mod\u00e8les
|
||||
label_quickadd_desc=Description :
|
||||
label_quickadd_pattern=Mod\u00e8le :
|
||||
label_threshold=D\u00e9lai seuil
|
||||
label_middle=Milieu :
|
||||
label_exit=Sortie :
|
||||
label_nickname=Pseudonyme
|
||||
label_ip=IP
|
||||
label_country=Pays
|
||||
label_guard_minimum=Vous pouvez soit ne choisir aucun n\u0153ud de garde au cas o\u00f9 le client Tor les choisit, soit choisir trois n\u0153uds de garde ou plus.
|
||||
label_torlogging=Niveau de journalisation :
|
||||
label_torargs=Arguments de d\u00e9marrage :
|
||||
label_torsocks=Param\u00e8tres Socks :
|
||||
label_diskoptions=Options du disque :
|
||||
label_guardnode=Garde :
|
||||
label_bridgenode=Pont :
|
||||
label_donotproxy=Ne pas relayer :
|
||||
button_details=D\u00e9tails
|
||||
button_whois=Qui est
|
||||
button_close=Fermer
|
||||
button_apply=Appliquer
|
||||
button_delete=Supprimer
|
||||
button_addnew=Ajouter un nouveau
|
||||
button_save=Enregistrer
|
||||
button_cancel=Annuler
|
||||
button_continue=Continuer
|
||||
button_getbridges=Obtenir des ponts
|
||||
button_mozillarestart=Red\u00e9marrer $browser
|
||||
button_visitus=Rendez-nous visite
|
||||
button_contactus=Contactez-nous
|
||||
button_translations=Traductions non officielles
|
||||
button_prefdefaults=R\u00e9initialiser aux leurs valeurs par d\u00e9faut.
|
||||
button_setguards=D\u00e9finir les n\u0153uds de garde
|
||||
button_details=D\u00e9tails de l'atlas
|
||||
button_clearguards=Effacer les n\u0153uds de garde choisis
|
||||
button_clearfavs=Effacer les favoris
|
||||
button_support=Soutenir SelekTOR
|
||||
button_patreon=Soutenir SelekTOR avec Patreon
|
||||
panel_general=Param\u00e8tres g\u00e9n\u00e9raux
|
||||
panel_network= Param\u00e8tres r\u00e9seau
|
||||
panel_management=Param\u00e8tres de gestion des n\u0153uds
|
||||
panel_info=Circuit actif
|
||||
panel_torclientset=Param\u00e8tres du client Tor
|
||||
panel_startupargs=Arguments de d\u00e9marrage
|
||||
panel_stdout=Moniteur de sortie standard
|
||||
chkbox_autoselect=Choix automatique du n\u0153ud
|
||||
chkbox_autostart=D\u00e9marrage automatique de SelekTOR
|
||||
chkbox_checkforupdates=V\u00e9rifier les mises \u00e0 jour au d\u00e9marrage
|
||||
chkbox_disabletray=D\u00e9sactiver l'ic\u00f4ne de notification
|
||||
chkbox_autopatterns=Installer automatiquement les derniers mod\u00e8les.
|
||||
chkbox_mozillawarn=D\u00e9sactiver l'avertissement de Mozilla
|
||||
chkbox_recnodesonly=Utiliser les n\u0153uds recommand\u00e9s en mode par mod\u00e8les
|
||||
chkbox_hidetotray=Minimiser au d\u00e9marrage
|
||||
chkbox_minonclose=Minimiser plut\u00f4t que de quitter lors de la fermeture
|
||||
chkbox_safesocks=Socks s\u00e9curitaire
|
||||
chkbox_twohop=Utiliser des circuits \u00e0 2 sauts vers le n\u0153ud de sortie en mode par mod\u00e8les
|
||||
chkbox_warnunsafesocks=Avertir si \u00e0 risque
|
||||
chkbox_diskavoid=\u00c9viter les \u00e9critures sur le disque
|
||||
chkbox_testsocks=Tester Socks
|
||||
chkbox_safelog=Journalisation s\u00e9curitaire
|
||||
chkbox_guardwarn1=Afficher une fen\u00eatre d'avertissement si un n\u0153ud de garde non sp\u00e9cifi\u00e9 est utilis\u00e9
|
||||
chkbox_guardwarn2=Afficher une fen\u00eatre d'avertissement si moins de trois n\u0153uds de garde sont choisis
|
||||
chkbox_securedelete=Effacement s\u00e9curis\u00e9 des caches de Tor lors de la fermeture
|
||||
ttip_autostart=D\u00e9marrage automatique de SelekTOR lors du d\u00e9marrage/de la connexion
|
||||
ttip_hidetotray=Minimiser au d\u00e9marrage
|
||||
ttip_checkforupdates=SelekTOR v\u00e9rifiera les mises \u00e0 jour au d\u00e9marage
|
||||
ttip_autoinstall=Les derniers mod\u00e8les seront r\u00e9cup\u00e9r\u00e9s de Dazzleships.Net
|
||||
ttip_disabletray=D\u00e9sactiver l'ic\u00f4ne de notification
|
||||
ttip_mozillawarn=D\u00e9sactiver l'avertissement du navigateur Mozilla
|
||||
ttip_listenport=Le port d'\u00e9coute du client Tor
|
||||
ttip_defaultproxy=Tout trafic qui ne sera pas redirig\u00e9 par Tor sera redirig\u00e9 par ce mandataire HTTP
|
||||
ttip_donotproxy=Toute URL contenant une de ces entr\u00e9es s\u00e9par\u00e9es par des virgules ne sera pas relay\u00e9e. L'on s'y connectera directement.
|
||||
ttip_bridgeaddress=Pour contourner le blocage du FSI, ajouter une adresse de pont valide ici
|
||||
ttip_forcedns=Forcer la recherche DNS par Tor, exige le red\u00e9marrage du navigateur
|
||||
ttip_forcenode=Si coch\u00e9, le n\u0153ud sera activ\u00e9 quelque soit l'activit\u00e9 du n\u0153ud
|
||||
ttip_recnodesonly=Les n\u0153uds recommand\u00e9s seront utilis\u00e9s en mode par mod\u00e8les
|
||||
ttip_minonclose=L'application sera minimis\u00e9e au lieu de quitter \u00e0 la fermeture de la fermeture principale
|
||||
ttip_threshold=D\u00e9lai seuil
|
||||
ttip_safesocks=Activ\u00e9e, Tor rejettera les connexions logicielles qui utilisent des variantes dangereuses du protocole Socks.
|
||||
ttip_warnunsafe=Activ\u00e9e, Tor avertira \u00e0 chaque fois qu'une requ\u00eate est re\u00e7ue contenant seulement une adresse IP au lieu d'un nom d'h\u00f4te.
|
||||
ttip_testsocks=Activ\u00e9e Tor journalisera une entr\u00e9e de journal de niveau avis pour chaque connexion en indiquant si elle utilise un protocole Socks s\u00e9curitaire ou dangereux.
|
||||
ttip_safelogging=Activ\u00e9e, Tor nettoiera les cha\u00eenes potentiellement sensibles des messages de journalisation.
|
||||
ttip_avoiddisk=Activ\u00e9e, Tor essaiera d'\u00e9crire moins fr\u00e9quemment sur le disque que nous ne le ferions autrement.
|
||||
ttip_extraargs= Arguments suppl\u00e9mentaires sp\u00e9cifi\u00e9s par l'utilisateur, voir le Manuel Tor.
|
||||
ttip_combo_loglevel=Niveau de journalisation de Tor.
|
||||
ttip_twohop=Utiliser des circuits \u00e0 2 sauts au lieu des 3 par d\u00e9faut de Tor. R\u00e9duit le d\u00e9lai de transit mais affaiblit l'anonymat.
|
||||
ttip_resetbasicprefs=R\u00e9initialiser les pr\u00e9f\u00e9rences de base \u00e0 leurs valeurs par d\u00e9faut.
|
||||
ttip_resetadvprefs=R\u00e9initialiser les pr\u00e9f\u00e9rences avanc\u00e9es \u00e0 leurs valeurs par d\u00e9faut.
|
||||
ttip_guardwarn1=Activ\u00e9, une fen\u00eatre d'avertissement sera affich\u00e9e indiquant qu'un n\u0153ud de garde non sp\u00e9cifi\u00e9 est actif.
|
||||
ttip_guardwarn2=Activ\u00e9, une fen\u00eatre d'avertissement sera affich\u00e9e indiquant que trop peu de n\u0153uds de garde sont choisis
|
||||
ttip_clearguards=Effacer les n\u0153uds de garde choisis.
|
||||
ttip_securedelete=Activ\u00e9, les caches de Tor seront \u00e9cras\u00e9es par des z\u00e9ros, puis supprim\u00e9es
|
||||
dlg_update_title=Mise \u00e0 jour disponible.
|
||||
dlg_update_body=$version est maintenant disponible au t\u00e9l\u00e9chargement.
|
||||
dlg_restoreproxy_title=Param\u00e8tres originaux du mandataire
|
||||
dlg_restoreproxy_body=Choisir Continuer pour restaurer les param\u00e8tres du mandataire aux valeurs par d\u00e9faut avant l'installation de SelekTOR.
|
||||
dlg_resetproxy_title=Param\u00e8tres par d\u00e9faut du mandataire
|
||||
dlg_resetproxy_body=Choisir Continuer pour r\u00e9initialiser les param\u00e8tres du serveur mandataire \u00e0 leurs valeurs syst\u00e8me par d\u00e9faut.
|
||||
dlg_gsetting_title=Gsettings introuvable
|
||||
dlg_gsetting_body=$appname ne peux pas fonctionner correctement sans que l'ex\u00e9cutable binary soit install\u00e9. Dans certaines distributions il peut \u00eatre trouv\u00e9 dans le paquet libglib2.0-bin.
|
||||
dlg_torclient_title=Client TOR introuvable
|
||||
dlg_torclient_body=$appname ne peux pas fonctionner sans que le client Tor ne soit Install\u00e9. Veuillez installer les paquets tor et tor-geoipdb pour votre distribution.
|
||||
dlg_mozillarestart_title=Avertissement\u00a0: Le navigateur $browser est actif.
|
||||
dlg_mozillarestart_body=$appname a d\u00e9tect\u00e9 que le navigateur $browser tourne d\u00e9j\u00e0.\nUn red\u00e9marrage du navigateur est exig\u00e9 pour permettre le fonctionnement de $appname.\n\nSi vous choisissez de red\u00e9marrer $browser, tous les onglets actuellement ouverts seront restaur\u00e9s au red\u00e9marrage de $browser, l'option \u00ab Afficher les dernier onglets et fen\u00eatres utilis\u00e9s \u00bb, doit \u00eatre choisie dans les options de $browser.\n\nVous pouvez d\u00e9sactiver cet avertissement du navigateur dans les Pr\u00e9f\u00e9rences de $appname.
|
||||
dlg_license_title=Licence de $appname
|
||||
dlg_exportuser_title=Exporter les mod\u00e8les d'utilisateur
|
||||
dlg_exportuser_body=Aucun mod\u00e8le cr\u00e9\u00e9 par l'utilisateur n'a \u00e9t\u00e9 trouv\u00e9.\n\nUtilisez l'\u00e9diteur de mode pour ajouter vos propres mod\u00e8les
|
||||
dlg_exportdefault_title=Exporter les mod\u00e8les par d\u00e9faut
|
||||
dlg_exportdefault_body=Aucun mod\u00e8le par d\u00e9faut n'a \u00e9t\u00e9 trouv\u00e9.
|
||||
dlg_saveuser_title=Enregistrer les modes de l'utilisateur
|
||||
dlg_savedefault_title=Enregistrer les mod\u00e8les par d\u00e9faut
|
||||
dlg_import_title=Importer le fichier des mod\u00e8les
|
||||
dlg_import_success_title=Mod\u00e8les import\u00e9s
|
||||
dlg_import_success_body=Les mod\u00e8les ont \u00e9t\u00e9 import\u00e9s avec succ\u00e8s et sont maintenant actifs.
|
||||
dlg_import_fail_title=\u00c9chec lors l'importation
|
||||
dlg_import_fail_body=Les mod\u00e8les n'ont pas \u00e9t\u00e9 import\u00e9s correctement.
|
||||
dlg_whois_title=Qui est $ipaddress
|
||||
dlg_whois_body=Veuillez patienter pendant que j'essaie de r\u00e9cup\u00e9rer les donn\u00e9s de WhoIs...
|
||||
dlg_whois_fail=D\u00e9sol\u00e9, impossible de r\u00e9cup\u00e9rer les informations de Whois.
|
||||
dlg_toold_body=Le client Tor actuellement install\u00e9 est trop ancien, Tor 0.2.7.6 ou ult\u00e9rieure est exig\u00e9e.\n\nLes utilisateurs de Linux devraient visiter la page suivante \nhttps://www.torproject.org/download/download-unix.html.en\npour obtenir le dernier client Tor.
|
||||
dlg_error_title=Erreur de d\u00e9marrage
|
||||
dlg_error_body=Cette erreur est fatale et $appname se fermera.
|
||||
dlg_quickadd_title=Ajouter un mod\u00e8le
|
||||
dlg_nodelistfail_body=La g\u00e9n\u00e9ration de la liste des n\u0153uds a \u00e9chou\u00e9 \u00e0 cause d'erreurs de GEOIP.
|
||||
dlg_patterneditsave_title=Enregistrer les mod\u00e8les actuels
|
||||
dlg_patterneditsave_body=Les mod\u00e8les actuels ont \u00e9t\u00e9 modifi\u00e9s.\n\nSi vous d\u00e9sirez les enregistrer, cliquez sur Continuer, autrement cliquez sur Annuler.
|
||||
dlg_instancefail_title=\u00c9chec d\u00fb \u00e0 plusieurs instances
|
||||
dlg_instancefail_body=Une instance de $appname est d\u00e9j\u00e0 en cours et une seule peut \u00eatre ex\u00e9cut\u00e9e \u00e0 la fois.\n\nQuittez l'instance existante de $appname ou dans le cas d'un plantage de $appname, red\u00e9marrez X en vous d\u00e9connectant et en vous connectant de nouveau.
|
||||
dlg_guardwarn_title=Avertissement de n\u0153ud de garde
|
||||
dlg_guardwarn_body=Un n\u0153ud de garde ne se trouvant pas dans votre liste de n\u0153uds de garde sp\u00e9cifi\u00e9e a \u00e9t\u00e9 utilis\u00e9.\nCeci provient probablement du fait que vos n\u0153uds de garde s\u00e9lectionn\u00e9s ne sont plus joignables et par cons\u00e9quent le client Tor a assign\u00e9 son propre n\u0153ud de garde.\n\nVous devriez v\u00e9rifier vos n\u0153uds de garde actuellement d\u00e9finis pour voir s'ils sont toujours disponibles, ou en choisir de nouveaux.
|
||||
dlg_notenoughguards_body=Il n'y a pas assez de n\u0153uds de garde d\u00e9finis afin que Tor fonctionne efficacement et en toute s\u00e9curit\u00e9.\n\nSupprimez tous les n\u0153uds de garde s\u00e9lectionn\u00e9s, ce qui permettra au client Tor de choisir ses propres n\u0153uds de garde, ou choisissez manuellement trois n\u0153uds de garde ou plus.dlg_notenoughguards_body=Il n'y a pas assez de n\u0153uds de garde d\u00e9finis afin que Tor fonctionne efficacement et en toute s\u00e9curit\u00e9.\n\nSupprimez tous les n\u0153uds de garde s\u00e9lectionn\u00e9s, ce qui permettra au client Tor de choisir ses propres n\u0153uds de garde, ou choisissez manuellement trois n\u0153uds de garde ou plus.
|
||||
dlg_bridgerr_title=\u00c9chec de validation de l'adresse de pont
|
||||
dlg_bridgerr_body=Les informations de pont fournies contiennent des erreurs de validation et ne se conforment pas \u00e0 un format d'adresse IPv4 valide h\u00f4te:port\n\nVoici des exemples de format de sp\u00e9cification de ponts :\n\nPont simple : \n127.0.0.1:8080\n\nPonts multiples : \n127.0.0.1:8080,128.5.6.8:224\n\nLes ponts ont \u00e9t\u00e9 r\u00e9initialis\u00e9s \u00e0 leurs valeurs par d\u00e9faut.
|
||||
dlg_credits_title=Cr\u00e9dits de $appname
|
||||
dlg_credits_body=Afin que votre nom apparaissent ici et pour aussi m\u00e9riter ma gratitude, veuillez envisager de soutenir le d\u00e9veloppement futur de SelekTOR sous Linux avec Patreon.
|
||||
table_popup_details=D\u00e9tails
|
||||
table_popup_whois=Qui est
|
||||
table_popup_begintest=Commencer le cycle de test
|
||||
tab_basic=De base
|
||||
tab_advanced=Avanc\u00e9
|
||||
isoA1=Mandataire annonyme
|
||||
isoO1=autre Pays
|
||||
isoU1=Inconnu
|
||||
chkbox_disablenotify=D\u00e9sactiver les notifications du bureau
|
||||
ttip_disablenotify=D\u00e9sactiver les notifications du bureau
|
||||
dlg_libnotify_title=notify-send est introuvable
|
||||
dlg_libnotify_body=Les notifications de bureau ne fonctionneront pas sans que le paquet libnotify-bin ne soit install\u00e9.\n\nPour emp\u00eacher que cette fen\u00eatre apparaissent de nouveau installez le paquet exig\u00e9 ou d\u00e9sactivez les notifications de bureau dans les pr\u00e9f\u00e9rences.
|
||||
ttip_hidemin=L'appli sera cach\u00e9e au lieu d'\u00eatre minimis\u00e9e.
|
||||
chkbox_hidemin=Cacher au lieu de minimiser
|
||||
label_autoselect= Mode de s\u00e9lection automatique :
|
||||
menu_geoip=Mettre GEOIP \u00e0 jour
|
||||
chkbox_geocheck=V\u00e9rification trimestrielle des mises \u00e0 jour GEOIP
|
||||
ttip_geocheck=SelekTOR affichera la \u00abfen\u00eatre de mise \u00e0 jour GEOIP \u00bbsi votre base de donn\u00e9es GEOIP est p\u00e9rim\u00e9e.
|
||||
dlg_geo_title=Mise \u00e0 jour des donn\u00e9es de g\u00e9olocalisation
|
||||
dlg_geo_body=Les donn\u00e9es de g\u00e9olocalisation fournies par Tor sont parfois p\u00e9rim\u00e9es. Vous pouvez demander \u00e0 SelekTOR de t\u00e9l\u00e9charger ses propres fichiers de donn\u00e9es de g\u00e9olocalisation de Dazzleships.net et de les utiliser. Ils sont mis \u00e0 jour trimestriellement.\n\nVeuillez noter que si vous choisissez de ne pas mettre \u00e0 jour, certains n\u0153uds pourraient \u00eatre assign\u00e9s au mauvais pays.\n\nLes donn\u00e9es des ces fichiers, comme les donn\u00e9es fournies par le client Tor, sont fournies par Maxmind.com.
|
||||
dload_status_contact=R\u00e9cup\u00e9ration des derni\u00e8res donn\u00e9es GEOIP
|
||||
dload_status_failed=\u00c9chec de t\u00e9l\u00e9chargement
|
||||
chkbox_viator=T\u00e9l\u00e9charger par Tor
|
||||
ttip_patterntable=\u00c9dition en ligne prise en charge, un double-clic gauche lance l'\u00e9dition d'une cellule d'un tableau.
|
||||
fileext_pattern=Fichiers de mod\u00e8les zipp\u00e9
|
261
src/resources/MessagesBundle_pt_BR.properties
Normal file
261
src/resources/MessagesBundle_pt_BR.properties
Normal file
|
@ -0,0 +1,261 @@
|
|||
# Portuguese BR, Default language file, provide by Paulo Roberto Alves de Oliveira (aka kretcheu) <kretcheu@gmail.com> Licensed by GPL-2+
|
||||
appdesc=$appname $appver, N\u00f3s de sa\u00edda Tor com simplicidade.
|
||||
text_yes=Sim
|
||||
text_no=N\u00e3o
|
||||
text_mode=N\u00f3
|
||||
wintitle_prefs = Prefer\u00eancias $appname
|
||||
wintitle_about = Sobre $appname
|
||||
wintitle_patternedit = Editor de modelos $appname
|
||||
wintitle_guardnodes=Sele\u00e7\u00e3o de n\u00f3s guarda
|
||||
wintitle_tormonitor=Monitor do cliente Tor
|
||||
textfield_unknown=Desconhecido
|
||||
progstatus_initial=Iniciando...
|
||||
progstatus_generate=Gerando lista de n\u00f3s, por favor aguarde.
|
||||
progstatus_cachedated=Descri\u00e7\u00f5es armazenadas desatualizadas, iremos atualiz\u00e1-las.
|
||||
progstatus_nonet=Acesso a Internet n\u00e3o dispon\u00edvel.
|
||||
progstatus_checkrecommended=Verificando os \u00faltimos n\u00f3s recomendados.
|
||||
progstatus_gotrecommended=Lista de n\u00f3s recomendados recuperados.
|
||||
progstatus_torfailretry=O Tor falhou ao iniciar, tentando novamente.
|
||||
progstatus_nodefail=Ativa\u00e7\u00e3o requisitada do n\u00f3 falhou.
|
||||
progstatus_nodefailretry=Ativa\u00e7\u00e3o requisitada do n\u00f3 falhou, tentaremos novamente, por favor aguarde.
|
||||
progstatus_nodefailtorchoose=N\u00f3 requisitado fora de alcance, deixaremos o Tor escolher.
|
||||
progstatus_nodeactive3hop=Circuito de 3 saltos do n\u00f3 de sa\u00edda $nodename est\u00e1 ativo.
|
||||
progstatus_nodeactive2hop=Cirtuito de 2 saltos do n\u00f3 de sa\u00edda $nodename est\u00e1 ativo.
|
||||
progstatus_autoswitch=Troca autom\u00e1tica de n\u00f3
|
||||
progstatus_manswitch=Trocando para n\u00f3 manualmente selecionado.
|
||||
progstatus_waitfortor=Aguardando ativa\u00e7\u00e3o do n\u00f3 pelo Tor.
|
||||
progstatus_switchtonode=Trocando para o n\u00f3 $nodename.
|
||||
progstatus_applychanges=Aplicando novas prefer\u00eancias.
|
||||
circuit_status_creating_2hop=Criando circuito de 2 saltos.
|
||||
circuit_status_creating_3hop=Criando circuito de 3 saltos.
|
||||
circuit_status_testing=Testanto circuito.
|
||||
circuit_status_aborted=Teste cancelado.
|
||||
circuit_status_built=Circuito $1 constru\u00eddo.
|
||||
circuit_status_passed=Circuito passou.
|
||||
circuit_status_failed=Circuito falhou.
|
||||
circuit_status_none=Nenhum circuito dispon\u00edvel.
|
||||
circuit_status_noroute=Todos roteadores fora.
|
||||
combo_proxymode1=Desabilitado
|
||||
combo_proxymode2=Proxy por modelo
|
||||
combo_proxymode3=Proxy para todo tr\u00e1fego
|
||||
combo_loglev1=Depura\u00e7\u00e3o
|
||||
combo_loglev2=Informa\u00e7\u00e3o
|
||||
combo_loglev3=Aviso
|
||||
traymenu_proxymode1=Modo: Proxy Desabilitado
|
||||
traymenu_proxymode2=Modo: Proxy por modelo
|
||||
traymenu_proxymode3=Modo: Proxy para todo tr\u00e1fego
|
||||
traymenu_showgui=Esconde/Mostra GUI
|
||||
traytool_guardnode=N\u00f3 guarda
|
||||
traytool_exitnode=N\u00f3 de sa\u00edda
|
||||
exittable_col1=N\u00f3 de sa\u00edda
|
||||
exittable_col2=Largura de Banda (MB\/s)
|
||||
exittable_col3=Lat\u00eancia (ms)
|
||||
exittable_col4=Estado
|
||||
exittable_col5=Favorito
|
||||
guardtable_col1=N\u00f3 guarda
|
||||
guardtable_col2=Pa\u00eds
|
||||
guardtable_col3=Largura de Banda (MB\/s)
|
||||
guardtable_col4=Confi\u00e1vel
|
||||
patterntable_col1=Descri\u00e7\u00e3o
|
||||
patterntable_col2=Modelo
|
||||
patterntable_col3=Habilitado
|
||||
menu_menu=Menu
|
||||
menu_prefs=Prefer\u00eancias
|
||||
menu_quickadd=Adicione modelo rapidamente
|
||||
menu_patternedit=Editor de modelo de proxy
|
||||
menu_export=Exporta\u00e7\u00e3o de modelos
|
||||
menu_import=Importa\u00e7\u00e3o de modelos
|
||||
menu_quit=Sair
|
||||
menu_defaultpatterns=Modelos padr\u00e3o
|
||||
menu_userpatterns=Modelos de usu\u00e1rio
|
||||
menu_help=Ajuda
|
||||
menu_debuglog=Ver log de depura\u00e7\u00e3o
|
||||
menu_helpcontents=Conte\u00fado de ajuda
|
||||
menu_torcheck=Verificar roteamento Tor
|
||||
menu_about=Sobre
|
||||
menu_license=Licen\u00e7a
|
||||
menu_tormanual=Manual oficial do Tor
|
||||
menu_tormonitor=Monitor de cliente Tor
|
||||
menu_close=Menu fechar
|
||||
menu_proxy=Modo Proxy
|
||||
menu_leaktest=Testar vazamento de DNS
|
||||
menu_credits=Cr\u00e9ditos
|
||||
label_latency_url=URL de verifica\u00e7\u00e3o de lat\u00eancia do Tor:
|
||||
label_guardnode=Guarda:
|
||||
label_bridgenode=Ponte:
|
||||
label_activecountry=Pa\u00eds de sa\u00edda:
|
||||
label_proxymode=Modo do proxy:
|
||||
label_exitnode=N\u00f3 de sa\u00edda:
|
||||
label_torlatency=Lat\u00eancia
|
||||
label_fingerprint=Impress\u00e3o digital:
|
||||
label_bandwidth=Largura de banda
|
||||
label_streams=Fluxos
|
||||
label_stable=Est\u00e1vel
|
||||
label_status=Estado do cliente:
|
||||
label_listenport=Porta de escuta do Tor:
|
||||
label_defaultproxy=Proxy HTTP padr\u00e3o:
|
||||
label_bridgeaddress=Endere\u00e7o de ponte Tor:
|
||||
label_portranges=Intervalo atual de portas, $portmin at\u00e9 $portmax
|
||||
label_editcountry=Selecione o pa\u00eds para ver seu modelo
|
||||
label_quickadd_desc=Descri\u00e7\u00e3o:
|
||||
label_quickadd_pattern=Modelo:
|
||||
label_threshold=Limite
|
||||
label_exitip=IP de sa\u00edda:
|
||||
label_guardip=IP do n\u00f3 guarda:
|
||||
label_guardcountry=Pa\u00eds do n\u00f3 guarda:
|
||||
label_torlogging=N\u00edvel de log:
|
||||
label_torargs=Par\u00e2metros iniciais:
|
||||
label_torsocks=Configura\u00e7\u00e3o do Socks:
|
||||
label_diskoptions=Op\u00e7\u00f5es de disco:
|
||||
label_guard_minimum=Voc\u00ea pode tanto n\u00e3o ter n\u00f3s guarda selecionados, nesse caso o cliente Tor ir\u00e1 escolher ou ter 3 ou mais n\u00f3s guarda selecionados.
|
||||
label_nickname=Apelido
|
||||
label_ip=IP
|
||||
label_country=Pa\u00eds
|
||||
label_exit=Sa\u00edda:
|
||||
label_middle=Meio:
|
||||
label_donotproxy=Sem proxy:
|
||||
button_details=Detalhes do atlas
|
||||
button_whois=WhoIs
|
||||
button_close=Fechar
|
||||
button_apply=Aplicar
|
||||
button_delete=Apagar
|
||||
button_addnew=Adicionar novo
|
||||
button_save=Salvar
|
||||
button_cancel=Cancelar
|
||||
button_continue=Continuar
|
||||
button_getbridges=Obter pontes
|
||||
button_mozillarestart=Reiniciar $browser
|
||||
button_visitus=Visite-nos
|
||||
button_contactus=Contacte-nos
|
||||
button_translations=Tradu\u00e7\u00f5es n\u00e3o oficiais
|
||||
button_prefdefaults=Restaurar padr\u00f5es
|
||||
button_setguards=Definir n\u00f3s guarda
|
||||
button_clearguards=Limpar n\u00f3s guarda selecionados
|
||||
button_clearfavs=Limpar Favoritos
|
||||
button_support=Apoie o SelekTOR
|
||||
button_patreon=Apoie o SelekTOR com Patreon
|
||||
panel_info=Circuito ativo
|
||||
panel_general=Configura\u00e7\u00f5es gerais
|
||||
panel_network=Configura\u00e7\u00f5es de rede
|
||||
panel_management=Configura\u00e7\u00f5es de gest\u00e3o de n\u00f3s
|
||||
panel_torclientset=Configura\u00e7\u00f5es do cliente Tor
|
||||
panel_startupargs=Par\u00e2metros iniciais
|
||||
panel_stdout=Monitor de sa\u00edda
|
||||
chkbox_autoselect=Sele\u00e7\u00e3o autom\u00e1tica de n\u00f3s
|
||||
chkbox_autostart=Iniciar automaticamente o SelekTOR
|
||||
chkbox_checkforupdates=Verificar por atualiza\u00e7\u00f5es ao iniciar
|
||||
chkbox_disabletray=Desabilitar \u00edcone da bandeja.
|
||||
chkbox_autopatterns=Instalar automaticamente os \u00faltimos modelos.
|
||||
chkbox_mozillawarn=Desabilitar alerta Mozilla
|
||||
chkbox_recnodesonly=Usar n\u00f3s recomendados no modelo
|
||||
chkbox_hidetotray=Minimizar ao iniciar
|
||||
chkbox_minonclose=Minimizar ao inv\u00e9s de sair ao fechar
|
||||
chkbox_twohop=Usar circuitos de 2 saltos para n\u00f3 de sa\u00edda no modelo
|
||||
chkbox_safesocks=Socks seguro
|
||||
chkbox_warnunsafesocks=Avisar se inseguro
|
||||
chkbox_diskavoid=Evitar escrita no disco
|
||||
chkbox_testsocks=Testar Socks
|
||||
chkbox_safelog=Logging seguro
|
||||
chkbox_guardwarn1=Alertar se um n\u00f3 guarda n\u00e3o especificado for usado
|
||||
chkbox_securedelete=Apagar dados armazenados do Tor ao sair
|
||||
chkbox_guardwarn2=Alertar se menos de 3 n\u00f3s guardas forem selecionados
|
||||
ttip_autostart=Ir\u00e1 iniciar o SelekTOR automaticamente no boot/login.
|
||||
ttip_hidetotray=SelekTOR iniciar\u00e1 na bandeja do sistema
|
||||
ttip_checkforupdates=SelekTOR verificar\u00e1 por nova vers\u00e3o ao iniciar
|
||||
ttip_autoinstall=Buscar\u00e1 \u00faltimos modelos de Dazzleships.Net.
|
||||
ttip_disabletray=Desabilitar \u00edcone na bandeja do sistema
|
||||
ttip_mozillawarn=Desabilitar alerta do navegador Mozilla
|
||||
ttip_listenport=Cliente Tor escutando na porta.
|
||||
ttip_defaultproxy=Todo tr\u00e1fego n\u00e3o roteado pelo Tor ir\u00e1 ser redirecionado por esse proxy HTTP.
|
||||
ttip_donotproxy=Qualquer URL que contenha uma ou mais dessas entradas, separadas por v\u00edrgula, ser\u00e1 conectada diretamente.
|
||||
ttip_bridgeaddress=Para evitar bloqueio do provedor adicione um endere\u00e7o v\u00e1lido de ponte aqui.
|
||||
ttip_forcedns=Force pesquisa de DNS via Tor, precisa reiniciar o navegador.
|
||||
ttip_forcenode=Quando marcado o n\u00f3 \u00e9 ativado independente de atividade atual
|
||||
ttip_enhanon=Usar\u00e1 3 saltos de n\u00f3s ao inv\u00e9s de 2 saltos.
|
||||
ttip_recnodesonly=Usuar\u00e1 n\u00f3s recomendados do modelo
|
||||
ttip_minonclose=A aplica\u00e7\u00e3o ir\u00e1 minimizar ao inv\u00e9s de sair ao fechar a janela principal
|
||||
ttip_threshold=Limite de lat\u00eancia
|
||||
ttip_safesocks=Quando habilitado, o Tor ir\u00e1 rejeitar conex\u00f5es que usam varia\u00e7\u00f5es inseguras do protocolo socks.
|
||||
ttip_warnunsafe=Quando habilitado, o Tor ir\u00e1 avisar sempre que uma requisi\u00e7\u00e3o recebida contiver apenas IP ao inv\u00e9s de um nome de m\u00e1quina.
|
||||
ttip_testsocks=Quando habilitado, o Tor ir\u00e1 gerar um log de n\u00edvel aviso para cada conex\u00e3o, indicando se foi usado o protocolo socks seguro ou inseguro.
|
||||
ttip_safelogging=Quando habilitado, o Tor ir\u00e1 limpar o texto potencialmente cr\u00edtico das mensagens de log.
|
||||
ttip_avoiddisk=Quando habilitado, o Tor tentar\u00e1 escrever no disco com menos frequ\u00eancia.
|
||||
ttip_extraargs=Especifique par\u00e2metros adicionais, veja o manual do Tor.
|
||||
ttip_combo_loglevel=N\u00edvel de log do Tor.
|
||||
ttip_twohop=Usar circuitos de 2 saltos ao inv\u00e9s de 3 saltos, padr\u00e3o do Tor, reduz a lat\u00eancia mas diminui o anonimato.
|
||||
ttip_resetbasicprefs=Restaurar as prefer\u00eancias b\u00e1sicas para seus padr\u00f5es.
|
||||
ttip_resetadvprefs=Restaurar as prefer\u00eancias avan\u00e7adas para seus padr\u00f5es.
|
||||
ttip_securedelete=Quando habilitado, o armazenamento do Tor ser\u00e1 sobrescrito por zeros quanto apagado.
|
||||
ttip_autonode=Quando habilitado, o SelekTOR tentar\u00e1 escolher o n\u00f3 de melhor performance.
|
||||
ttip_guardwarn=Quando habilitado, um alerta ser\u00e1 usado para indicar que um n\u00f3 guarda n\u00e3o especificado est\u00e1 ativo.
|
||||
ttip_clearguards=Limpar n\u00f3s guarda selecionados.
|
||||
ttip_guardwarn2=Quando habilitado, um alerta ser\u00e1 usado para indicar insufici\u00eancia de n\u00f3s guarda selecionados.
|
||||
dlg_update_title=Atualiza\u00e7\u00e3o dispon\u00edvel.
|
||||
dlg_update_body=Vers\u00e3o $version est\u00e1 dispon\u00edvel para download.
|
||||
dlg_restoreproxy_title=Configura\u00e7\u00e3o original do proxy
|
||||
dlg_restoreproxy_body=Selecione continue para restaurar as configura\u00e7\u00f5es originais do proxy antes da instala\u00e7\u00e3o do SelekTOR.
|
||||
dlg_resetproxy_title=Configura\u00e7\u00e3o padr\u00e3o do proxy
|
||||
dlg_resetproxy_body=Selecione continuar para limpar as configura\u00e7\u00f5es de proxy para o padr\u00e3o do sistema.
|
||||
dlg_gsetting_title=Gsettings n\u00e3o encontrado
|
||||
dlg_gsetting_body=$appname n\u00e3o funciona sem o bin\u00e1rio gsettings instalado, em algumas distribui\u00e7\u00f5es pode ser encontrado no pacote libglib2.0-bin.
|
||||
dlg_torclient_title=Cliente TOR n\u00e3o encontrado
|
||||
dlg_torclient_body=$appname n\u00e3o funciona sem um cliente Tor instalado, por favor instale os pacotes tor e tor-geoipdb da sua distribui\u00e7\u00e3o.
|
||||
dlg_mozillarestart_title=Alerta: O navegador $browser est\u00e1 ativo.
|
||||
dlg_mozillarestart_body=O $appname detectou que o navegador $browser j\u00e1 est\u00e1 em execu\u00e7\u00e3o.\nReiniciar o navegador \u00e9 necess\u00e1rio para habilitar $appname.\n\nSe escolher reiniciar o $browser todas as abas abertas ser\u00e3o restauradas quando o $browser reiniciar, requer que a op\u00e7\u00e3o \"Restaurar janelas e abas anteriores\" seja selecionada no menu prefer\u00eancias no $browser.\n\nVoc\u00ea pode desabilitar o aviso do navegador em prefer\u00eancias de $appname.
|
||||
dlg_license_title=Licen\u00e7a $appname
|
||||
dlg_exportuser_title=Exportar modelo de usu\u00e1rio
|
||||
dlg_exportuser_body=Nenhum modelo de usu\u00e1rio encontrado.\n\nUse o editor de modelos para adicionar seus pr\u00f3rios modelos
|
||||
dlg_exportdefault_title=Exporte os modelos padr\u00e3o
|
||||
dlg_exportdefault_body=Nenhum modelo padr\u00e3o encontrado.
|
||||
dlg_saveuser_title=Salvar o modelo de usu\u00e1rio
|
||||
dlg_savedefault_title=Salvar os modelos padr\u00e3o
|
||||
dlg_import_title=Importar um arquivo de modelo
|
||||
dlg_import_success_title=Modelo importado
|
||||
dlg_import_success_body=Modelos importados com susesso e agora ativos.
|
||||
dlg_import_fail_title=Importa\u00e7\u00e3o falhou
|
||||
dlg_import_fail_body=Falhou ao importar modelos.
|
||||
dlg_whois_title=Whois $ipaddress
|
||||
dlg_whois_body=Por favor aguarde enquanto buscando dados Whois...
|
||||
dlg_whois_fail=Desculpe, n\u00e3o foi poss\u00edvel encontrar informa\u00e7\u00f5es de Whois.
|
||||
dlg_toold_body=O cliente Tor atualmente instalado \u00e9 antigo, o Tor 0.2.7.6 ou mais novo \u00e9 requerido.\n\nUsu\u00e1rios de GNU/Linux podem acessar a p\u00e1gina \nhttps://www.torproject.org/download/download-unix.html.en\n para obter o cliente Tor mais recente, ou diretamente dos reposit\u00f3rios.
|
||||
dlg_error_title=Erro de inicia\u00e7\u00e3o
|
||||
dlg_error_body=Esse erro \u00e9 fatal e $appname ir\u00e1 fechar.
|
||||
dlg_quickadd_title=Adicionar modelo
|
||||
dlg_nodelistfail_body=A gera\u00e7\u00e3o da lista de n\u00f3s falhou devido a erros do GEOIP.
|
||||
dlg_patterneditsave_title=Salvar os modelos atuais
|
||||
dlg_patterneditsave_body=Modelos atuais foram modificados.\n\nSe voc\u00ea deseja salv\u00e1-los clique em continuar sen\u00e3o clique em cancelar.
|
||||
dlg_instancefail_title=Falha de inst\u00e2ncia multipla
|
||||
dlg_instancefail_body=Uma inst\u00e2ncia de $appname j\u00e1 est\u00e1 em execu\u00e7\u00e3o, somente uma inst\u00e2ncia pode ser executada por vez.\n\nFechar a inst\u00e2ncia existente de $appname ou no caso de $appname congelar reinicie o X deslogando e logando novamente.
|
||||
dlg_guardwarn_title=Alerta de n\u00f3 guarda
|
||||
dlg_guardwarn_body=Um n\u00f3 guarda que n\u00e3o est\u00e1 na lista de n\u00f3s guarda especificados foi usado.\nProvavelmente porque seus n\u00f3s guarda selecionados n\u00e3o s\u00e3o mais alcan\u00e7\u00e1veis e o cliente Tor escolheu seus pr\u00f3prios n\u00f3s guarda. Talvez queira verificar sua lista de n\u00f3s guarda para ver se ainda est\u00e3o dispon\u00edveis ou selecionar novos.
|
||||
dlg_notenoughguards_body=N\u00e3o h\u00e1 n\u00f3s guarda suficientes para o Tor operar com seguran\u00e7a e efici\u00eancia.\n\nLimpe todos os n\u00f3s guarda selecionados e deixe o cliente Tor escolher seus pr\u00f3prios n\u00f3s guarda ou escolha 3 n\u00f3s guarda manualmente.
|
||||
dlg_bridgerr_title=Falha na valida\u00e7\u00e3o do endere\u00e7o da ponte.
|
||||
dlg_bridgerr_body=A informa\u00e7\u00e3o da ponte fornecida cont\u00e9m erros de valida\u00e7\u00e3o e n\u00e3o est\u00e1 em conformidade com um formato v\u00e1lido host:port endere\u00e7o ipv4.\n\nExemplos do formato de especifica\u00e7\u00e3o de pontes s\u00e3o:\n\nPonte \u00fanica:\n127.0.0.1:8080\n\nPontes m\u00faltiplas:\n127.0.0.1:8080,128.5.6.8:224\n\nAs pontes foram restauradas para os padr\u00f5es.
|
||||
dlg_credits_title=Cr\u00e9ditos $appname
|
||||
dlg_credits_body=Para ter seu nome listado aqui e tamb\u00e9m merecer minha gratid\u00e3o por favor apoie o desenvolvimento do SelekTOR na plataforma GNU/Linux atrav\u00e9s do Patreon
|
||||
table_popup_details=Detalhes
|
||||
table_popup_begintest=Inicia ciclo de teste
|
||||
table_popup_whois=WhoIs
|
||||
tab_basic=B\u00e1sico
|
||||
tab_advanced=Avan\u00e7ado
|
||||
isoA1=Proxy an\u00f4nimo
|
||||
isoA2=Provedor de sat\u00e9lite
|
||||
isoO1=Outro pa\u00eds
|
||||
isoU1=Desconhecido
|
||||
chkbox_disablenotify=Desabilitar notifica\u00e7\u00f5es
|
||||
ttip_disablenotify=Desabilita notifica\u00e7\u00f5es
|
||||
dlg_libnotify_title=notify-send n\u00e3o encontrado
|
||||
dlg_libnotify_body=Notifica\u00e7\u00f5es n\u00e3o funcionam sem o pacote libnotify-bin instalado.\n\nPara previnir que esse alerta apare\u00e7a novamente, instale o pacote requerido ou desabilite as notifica\u00e7\u00f5es em prefer\u00eancias.
|
||||
ttip_hidemin=Aplica\u00e7\u00e3o ser\u00e1 oculta ao inv\u00e9s de minimizar
|
||||
chkbox_hidemin=Ocultar ao inv\u00e9s de minimizar
|
||||
label_autoselect=Modo de auto sele\u00e7\u00e3o:
|
||||
menu_geoip=Atualizar GEOIP
|
||||
chkbox_geocheck=Fazer verifica\u00e7\u00e3o trimestral de atualiza\u00e7\u00e3o do GEOIP
|
||||
ttip_geocheck=SelekTOR ir\u00e1 mostrar o "Di\u00e1logo de atualiza\u00e7\u00e3o GEOIP" se sua base de dados GEOIP estiver desatualizada.
|
||||
dlg_geo_title=Atualiza\u00e7\u00e3o de dados de geolocaliza\u00e7\u00e3o
|
||||
dlg_geo_body=Os dados de geolocaliza\u00e7\u00e3o padr\u00e3o vindos do cliente Tor algumas vezes est\u00e3o desatualizados, voc\u00ea pode baixar os dados de geolocaliza\u00e7\u00e3o de Dazzleships.net. Eles s\u00e3o atualizados trimestralmente.\n\nVeja, se escolher n\u00e3o atualizar, alguns n\u00f3s podem estar atribu\u00eddos a pa\u00edses errados.\n\nOs dados nesses arquivos, assim como os do cliente Tor s\u00e3o fornecidos por Maxmind.com.
|
||||
dload_status_contact=Obtendo dados GEOIP mais recentes
|
||||
dload_status_failed=Download falhou
|
||||
chkbox_viator=Download via Tor
|
||||
ttip_patterntable=Para editar, d\u00ea um duplo click na c\u00e9lula da tabela que deseja modificar.
|
||||
fileext_pattern=Arquivo zip do modelo
|
1
src/resources/credits.txt
Normal file
1
src/resources/credits.txt
Normal file
|
@ -0,0 +1 @@
|
|||
Alistair Neil (Developer)
|
339
src/resources/license.txt
Normal file
339
src/resources/license.txt
Normal file
|
@ -0,0 +1,339 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
BIN
src/resources/trayicon.png
Normal file
BIN
src/resources/trayicon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9 KiB |
Loading…
Add table
Add a link
Reference in a new issue