/**
* Broadcast.java
*
* Created on Oct 14, 2010, 4:47:24 PM
*
* @author pquiring
*
* This class implements Broadcasting a pre-recorded message to a list of phone numbers and/or taking surveys.
*
* NOTE : Please only broadcast to your own customers. Laws in some countries/states may prohibit contacting random individuals.
*
*/
import java.io.*;
import java.net.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
import javaforce.*;
import javaforce.voip.*;
public class Broadcast extends javax.swing.JFrame implements SIPClientInterface, RTPInterface, ActionListener {
public final String version = "0.36";
public String startList = null;
public String cfgSuffix = "";
public boolean allowdups = false;
public JFLockFile lockFile;
public String databaseName = "jfBroadcastSchema2";
public String dbPath;
/** Creates new form Broadcast */
public Broadcast() {
processArgs();
lockFile = new JFLockFile();
if (!lockFile.lock(JF.getUserPath() + "/jfbroadcast" + cfgSuffix + ".lck")) {
JF.showError("Error", "Another instance of jfBroadcast is already running!");
System.exit(0);
}
dbPath = null;
if (dbPath == null) {
dbPath = System.getProperty("user.home");
}
//setup derby.system.home
System.setProperty("derby.system.home", dbPath);
SQL.initClass(SQL.derbySQL);
initComponents();
setPosition();
loadHelp();
if (cfgSuffix.length() > 0)
setTitle("jfBroadcast/" + version + ":" + cfgSuffix);
else
setTitle("jfBroadcast/" + version);
JFLog.init(JF.getUserPath() + "/jfbroadcast" + cfgSuffix + ".log", true);
loadSetup();
setOptsState();
updateAvailableLists();
new Thread() {
@Override
public void run() {
createDatabase();
if (check_update.isSelected()) checkVersion();
}
}.start();
idx = 0;
buttonGroup1.add(single);
buttonGroup1.add(multi);
buttonGroup1.add(terminate);
buttonGroup1.add(gotouser);
buttonGroup1.add(cont);
buttonGroup1.add(gotoidx);
buttonGroup1.add(xfer);
loadQuestion();
if (startList != null) {
//do -start command line option
int cnt = selected_list.getItemCount();
boolean ok = false;
for(int b=0;b<cnt;b++) {
String item = (String)selected_list.getItemAt(b);
if (item.equals(startList)) {
selected_list.setSelectedIndex(b);
start.doClick();
ok = true;
break;
}
}
if (!ok) {
JFLog.log("Error:specifed list for -start option not found");
}
}
//set icons
JFImage appicon = new JFImage();
appicon.loadPNG(this.getClass().getClassLoader().getResourceAsStream("jfbroadcast.png"));
setIconImage(appicon.getImage());
appicon.loadPNG(this.getClass().getClassLoader().getResourceAsStream("jfbroadcast_tray.png"));
tray = SystemTray.getSystemTray();
Dimension size = tray.getTrayIconSize();
JFImage scaled = new JFImage(size.width, size.height);
scaled.fill(0, 0, size.width, size.height, 0x00000000, true); //fill with alpha transparent
if (true) {
//scaled image (looks bad sometimes)
scaled.getGraphics().drawImage(appicon.getImage()
, 0, 0, size.width, size.height
, 0, 0, appicon.getWidth(), appicon.getHeight()
, null);
} else {
//center image
scaled.getGraphics().drawImage(appicon.getImage()
, (size.width - appicon.getWidth()) / 2
, (size.height - appicon.getHeight()) / 2
, null);
}
//create tray icon
PopupMenu popup = new PopupMenu();
show = new MenuItem("Show");
show.addActionListener(this);
popup.add(show);
popup.addSeparator();
exit = new MenuItem("Exit");
exit.addActionListener(this);
popup.add(exit);
icon = new TrayIcon(scaled.getImage(), "jfBroadcast", popup);
icon.addActionListener(this);
tray = SystemTray.getSystemTray();
try { tray.add(icon); } catch (Exception e) { JFLog.log(e); }
}
/** 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() {
buttonGroup1 = new javax.swing.ButtonGroup();
jLabel1 = new javax.swing.JLabel();
start = new javax.swing.JButton();
status = new javax.swing.JLabel();
jTabbedPane1 = new javax.swing.JTabbedPane();
jPanel2 = new javax.swing.JPanel();
jLabel9 = new javax.swing.JLabel();
jLabel10 = new javax.swing.JLabel();
jLabel11 = new javax.swing.JLabel();
jLabel12 = new javax.swing.JLabel();
sip_user = new javax.swing.JTextField();
sip_auth = new javax.swing.JTextField();
sip_host = new javax.swing.JTextField();
jLabel34 = new javax.swing.JLabel();
sip_start = new javax.swing.JTextField();
jLabel36 = new javax.swing.JLabel();
sip_end = new javax.swing.JTextField();
jLabel35 = new javax.swing.JLabel();
sip_name = new javax.swing.JTextField();
sip_pass = new javax.swing.JPasswordField();
jPanel3 = new javax.swing.JPanel();
create_list = new javax.swing.JButton();
list_name = new javax.swing.JTextField();
jLabel5 = new javax.swing.JLabel();
selected_list = new javax.swing.JComboBox();
reset_list = new javax.swing.JButton();
delete_list = new javax.swing.JButton();
export_list = new javax.swing.JButton();
import_list = new javax.swing.JButton();
fix_list = new javax.swing.JButton();
jLabel33 = new javax.swing.JLabel();
jButton2 = new javax.swing.JButton();
jPanel11 = new javax.swing.JPanel();
jScrollPane1 = new javax.swing.JScrollPane();
listView = new javax.swing.JTable();
jPanel4 = new javax.swing.JPanel();
jPanel1 = new javax.swing.JPanel();
jLabel2 = new javax.swing.JLabel();
jLabel3 = new javax.swing.JLabel();
jLabel4 = new javax.swing.JLabel();
greeting_threshold = new javax.swing.JTextField();
silence_threshold = new javax.swing.JTextField();
silence_duration = new javax.swing.JTextField();
human_vm_detect = new javax.swing.JCheckBox();
voicemail_hangup = new javax.swing.JCheckBox();
jPanel7 = new javax.swing.JPanel();
jLabel13 = new javax.swing.JLabel();
enable_g729a = new javax.swing.JCheckBox();
enable_reinvites = new javax.swing.JCheckBox();
jLabel6 = new javax.swing.JLabel();
maxRingTime = new javax.swing.JSpinner();
enable_g711u = new javax.swing.JCheckBox();
enable_g711a = new javax.swing.JCheckBox();
number_lines = new javax.swing.JSpinner();
jLabel24 = new javax.swing.JLabel();
jLabel23 = new javax.swing.JLabel();
delay = new javax.swing.JSpinner();
check_update = new javax.swing.JCheckBox();
maxAttempts = new javax.swing.JSpinner();
exit_on_close_window = new javax.swing.JCheckBox();
jPanel8 = new javax.swing.JPanel();
xfer_number = new javax.swing.JTextField();
jLabel7 = new javax.swing.JLabel();
xfer_digit = new javax.swing.JTextField();
enable_xfer = new javax.swing.JCheckBox();
jPanel9 = new javax.swing.JPanel();
jPanel10 = new javax.swing.JPanel();
jLabel26 = new javax.swing.JLabel();
day1 = new javax.swing.JCheckBox();
start1 = new javax.swing.JTextField();
jLabel25 = new javax.swing.JLabel();
end1 = new javax.swing.JTextField();
day2 = new javax.swing.JCheckBox();
start2 = new javax.swing.JTextField();
jLabel27 = new javax.swing.JLabel();
end2 = new javax.swing.JTextField();
day3 = new javax.swing.JCheckBox();
start3 = new javax.swing.JTextField();
jLabel28 = new javax.swing.JLabel();
end3 = new javax.swing.JTextField();
day4 = new javax.swing.JCheckBox();
start4 = new javax.swing.JTextField();
jLabel29 = new javax.swing.JLabel();
end4 = new javax.swing.JTextField();
end5 = new javax.swing.JTextField();
jLabel30 = new javax.swing.JLabel();
start5 = new javax.swing.JTextField();
day5 = new javax.swing.JCheckBox();
day6 = new javax.swing.JCheckBox();
start6 = new javax.swing.JTextField();
jLabel31 = new javax.swing.JLabel();
end6 = new javax.swing.JTextField();
day7 = new javax.swing.JCheckBox();
start7 = new javax.swing.JTextField();
jLabel32 = new javax.swing.JLabel();
end7 = new javax.swing.JTextField();
jPanel5 = new javax.swing.JPanel();
enable = new javax.swing.JCheckBox();
wav_filename = new javax.swing.JTextField();
select_file = new javax.swing.JButton();
next_msg = new javax.swing.JButton();
prev_msg = new javax.swing.JButton();
title = new javax.swing.JLabel();
single = new javax.swing.JRadioButton();
count = new javax.swing.JComboBox();
multi = new javax.swing.JRadioButton();
terminate = new javax.swing.JRadioButton();
gotouser = new javax.swing.JRadioButton();
goto_1 = new javax.swing.JTextField();
goto_2 = new javax.swing.JTextField();
goto_3 = new javax.swing.JTextField();
goto_4 = new javax.swing.JTextField();
goto_5 = new javax.swing.JTextField();
goto_6 = new javax.swing.JTextField();
goto_7 = new javax.swing.JTextField();
goto_8 = new javax.swing.JTextField();
goto_9 = new javax.swing.JTextField();
jLabel8 = new javax.swing.JLabel();
jLabel14 = new javax.swing.JLabel();
jLabel15 = new javax.swing.JLabel();
jLabel16 = new javax.swing.JLabel();
jLabel17 = new javax.swing.JLabel();
jLabel18 = new javax.swing.JLabel();
jLabel19 = new javax.swing.JLabel();
jLabel20 = new javax.swing.JLabel();
jLabel21 = new javax.swing.JLabel();
cont = new javax.swing.JRadioButton();
gotoidx = new javax.swing.JRadioButton();
gotoidxnum = new javax.swing.JTextField();
jLabel22 = new javax.swing.JLabel();
msg_idx = new javax.swing.JSlider();
xfer = new javax.swing.JRadioButton();
jPanel6 = new javax.swing.JPanel();
jScrollPane2 = new javax.swing.JScrollPane();
help = new javax.swing.JTextArea();
save_setup = new javax.swing.JButton();
jButton1 = new javax.swing.JButton();
setTitle("jfBroadcast");
addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent evt) {
formWindowClosing(evt);
}
});
jLabel1.setText("Broadcast a message to a list of phone numbers or take a survey.");
start.setText("Start!");
start.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
startActionPerformed(evt);
}
});
status.setText("Status:OK");
jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("SIP Details"));
jLabel9.setText("Username");
jLabel10.setText("Authorization Username");
jLabel10.setToolTipText("optional");
jLabel11.setText("Domain");
jLabel12.setText("Password");
jLabel34.setText("SIP Port Range:");
jLabel34.setToolTipText("Valid range : 1024 thru 65535");
sip_start.setText("6000");
sip_start.setToolTipText("1024 - 60000");
jLabel36.setText("to");
sip_end.setText("9000");
sip_end.setToolTipText("1024 - 65535");
jLabel35.setText("Display Name");
jLabel35.setToolTipText("optional");
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()
.addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel2Layout.createSequentialGroup()
.addComponent(jLabel34)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(sip_start, javax.swing.GroupLayout.PREFERRED_SIZE, 55, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel36)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(sip_end, javax.swing.GroupLayout.PREFERRED_SIZE, 55, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 465, Short.MAX_VALUE))
.addGroup(jPanel2Layout.createSequentialGroup()
.addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel10)
.addComponent(jLabel9)
.addComponent(jLabel35)
.addComponent(jLabel11)
.addComponent(jLabel12))
.addGap(25, 25, 25)
.addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(sip_auth)
.addComponent(sip_name)
.addComponent(sip_user)
.addComponent(sip_host)
.addComponent(sip_pass, javax.swing.GroupLayout.Alignment.LEADING))))
.addContainerGap())
);
jPanel2Layout.setVerticalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel2Layout.createSequentialGroup()
.addContainerGap()
.addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel35)
.addComponent(sip_name, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel9)
.addComponent(sip_user, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel10)
.addComponent(sip_auth, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel11)
.addComponent(sip_host, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel12)
.addComponent(sip_pass, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(18, 18, 18)
.addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(sip_start, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel36)
.addComponent(sip_end, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel34))
.addContainerGap(204, Short.MAX_VALUE))
);
jTabbedPane1.addTab("SIP", jPanel2);
jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder("Lists"));
create_list.setText("Create List...");
create_list.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
create_listActionPerformed(evt);
}
});
list_name.setText("default");
jLabel5.setText("Select List:");
selected_list.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
selected_listItemStateChanged(evt);
}
});
reset_list.setText("Reset List...");
reset_list.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
reset_listActionPerformed(evt);
}
});
delete_list.setText("Delete List...");
delete_list.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
delete_listActionPerformed(evt);
}
});
export_list.setText("Export List...");
export_list.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
export_listActionPerformed(evt);
}
});
import_list.setText("Import List...");
import_list.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
import_listActionPerformed(evt);
}
});
fix_list.setText("Fix 'calling' in List...");
fix_list.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
fix_listActionPerformed(evt);
}
});
jLabel33.setText("Name:");
jButton2.setText("Fix 'errors' in List...");
jButton2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton2ActionPerformed(evt);
}
});
javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
jPanel3.setLayout(jPanel3Layout);
jPanel3Layout.setHorizontalGroup(
jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel3Layout.createSequentialGroup()
.addContainerGap()
.addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel3Layout.createSequentialGroup()
.addComponent(jLabel5)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(selected_list, javax.swing.GroupLayout.PREFERRED_SIZE, 158, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(jPanel3Layout.createSequentialGroup()
.addComponent(import_list)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(export_list))
.addGroup(jPanel3Layout.createSequentialGroup()
.addComponent(reset_list)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(delete_list))
.addGroup(jPanel3Layout.createSequentialGroup()
.addComponent(fix_list)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jButton2))
.addGroup(jPanel3Layout.createSequentialGroup()
.addComponent(jLabel33)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(list_name, javax.swing.GroupLayout.PREFERRED_SIZE, 175, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(create_list)))
.addContainerGap(371, Short.MAX_VALUE))
);
jPanel3Layout.setVerticalGroup(
jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel3Layout.createSequentialGroup()
.addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(list_name, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(create_list)
.addComponent(jLabel33))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel5)
.addComponent(selected_list, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(import_list)
.addComponent(export_list))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(reset_list)
.addComponent(delete_list))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(fix_list)
.addComponent(jButton2))
.addContainerGap(241, Short.MAX_VALUE))
);
jTabbedPane1.addTab("Lists", jPanel3);
listView.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
},
new String [] {
"Number", "Status", "Attempts", "Survey", "Timestamp"
}
) {
Class[] types = new Class [] {
java.lang.String.class, java.lang.String.class, java.lang.Integer.class, java.lang.String.class, java.lang.String.class
};
boolean[] canEdit = new boolean [] {
false, false, false, false, false
};
public Class getColumnClass(int columnIndex) {
return types [columnIndex];
}
public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit [columnIndex];
}
});
listView.setEnabled(false);
jScrollPane1.setViewportView(listView);
javax.swing.GroupLayout jPanel11Layout = new javax.swing.GroupLayout(jPanel11);
jPanel11.setLayout(jPanel11Layout);
jPanel11Layout.setHorizontalGroup(
jPanel11Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel11Layout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 686, Short.MAX_VALUE)
.addContainerGap())
);
jPanel11Layout.setVerticalGroup(
jPanel11Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel11Layout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 378, Short.MAX_VALUE)
.addContainerGap())
);
jTabbedPane1.addTab("Active List", jPanel11);
jPanel4.setBorder(javax.swing.BorderFactory.createTitledBorder("Options"));
jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Human/Voicemail Detection Options"));
jLabel2.setText("Greeting Detection Threshold:");
jLabel2.setToolTipText("100-32000 (default = 1000)");
jLabel3.setText("Silence Detection Threshold:");
jLabel3.setToolTipText("100-32000 (default = 1000)");
jLabel4.setText("Silence Duration (ms):");
jLabel4.setToolTipText("100-5000 (default = 2000)");
greeting_threshold.setText("1000");
greeting_threshold.setToolTipText("100-32000 (default = 1000)");
silence_threshold.setText("1000");
silence_threshold.setToolTipText("100-32000 (default = 1000)");
silence_duration.setText("2000");
silence_duration.setToolTipText("100-5000 (default = 1000)");
human_vm_detect.setSelected(true);
human_vm_detect.setText("Enable human/voicemail detection");
human_vm_detect.setToolTipText("Start messages after human/voicemail greeting.");
human_vm_detect.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
human_vm_detectActionPerformed(evt);
}
});
voicemail_hangup.setText("Voicemail hangup");
voicemail_hangup.setToolTipText("Hangup call if voicemail is detected.");
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(human_vm_detect)
.addGap(0, 0, Short.MAX_VALUE))
.addGroup(jPanel1Layout.createSequentialGroup()
.addContainerGap()
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(voicemail_hangup, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(jPanel1Layout.createSequentialGroup()
.addComponent(jLabel2)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(greeting_threshold, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(jPanel1Layout.createSequentialGroup()
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel3)
.addComponent(jLabel4))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(silence_threshold)
.addComponent(silence_duration, javax.swing.GroupLayout.PREFERRED_SIZE, 122, javax.swing.GroupLayout.PREFERRED_SIZE))))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addContainerGap()
.addComponent(human_vm_detect)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel2)
.addComponent(greeting_threshold, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel3)
.addComponent(silence_threshold, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(7, 7, 7)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel4)
.addComponent(silence_duration, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(voicemail_hangup)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
jPanel7.setBorder(javax.swing.BorderFactory.createTitledBorder("General Options"));
jLabel13.setText("Delay (ms) :");
jLabel13.setToolTipText("100-10000");
enable_g729a.setSelected(true);
enable_g729a.setText("Enable g729a codec");
enable_reinvites.setSelected(true);
enable_reinvites.setText("Enable reinvites");
jLabel6.setText("Number of Lines:");
jLabel6.setToolTipText("Number of concurrent calls.");
maxRingTime.addChangeListener(new javax.swing.event.ChangeListener() {
public void stateChanged(javax.swing.event.ChangeEvent evt) {
maxRingTimeStateChanged(evt);
}
});
enable_g711u.setSelected(true);
enable_g711u.setText("Enable g711u codec");
enable_g711a.setText("Enable g711a codec");
number_lines.setValue(4);
number_lines.addChangeListener(new javax.swing.event.ChangeListener() {
public void stateChanged(javax.swing.event.ChangeEvent evt) {
number_linesStateChanged(evt);
}
});
jLabel24.setText("Max Attempts:");
jLabel24.setToolTipText("Max attempts to call each number.");
jLabel23.setText("Max Ring Time:");
jLabel23.setToolTipText("Max ring time in seconds.");
delay.setToolTipText("100-10000");
delay.addChangeListener(new javax.swing.event.ChangeListener() {
public void stateChanged(javax.swing.event.ChangeEvent evt) {
delayStateChanged(evt);
}
});
check_update.setSelected(true);
check_update.setText("Check for update on startup");
maxAttempts.addChangeListener(new javax.swing.event.ChangeListener() {
public void stateChanged(javax.swing.event.ChangeEvent evt) {
maxAttemptsStateChanged(evt);
}
});
exit_on_close_window.setText("Close app when closing window");
javax.swing.GroupLayout jPanel7Layout = new javax.swing.GroupLayout(jPanel7);
jPanel7.setLayout(jPanel7Layout);
jPanel7Layout.setHorizontalGroup(
jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel7Layout.createSequentialGroup()
.addContainerGap()
.addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(exit_on_close_window)
.addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel7Layout.createSequentialGroup()
.addComponent(jLabel24)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(maxAttempts))
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel7Layout.createSequentialGroup()
.addComponent(jLabel23)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(maxRingTime))
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel7Layout.createSequentialGroup()
.addComponent(jLabel13)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(delay))
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel7Layout.createSequentialGroup()
.addComponent(jLabel6)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(number_lines, javax.swing.GroupLayout.PREFERRED_SIZE, 115, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addComponent(enable_g711a)
.addComponent(enable_g711u)
.addComponent(enable_g729a)
.addComponent(check_update)
.addComponent(enable_reinvites))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
jPanel7Layout.setVerticalGroup(
jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel7Layout.createSequentialGroup()
.addContainerGap()
.addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel6)
.addComponent(number_lines, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel13)
.addComponent(delay, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(7, 7, 7)
.addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel23)
.addComponent(maxRingTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel24)
.addComponent(maxAttempts, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(enable_g729a)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(enable_g711u)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(enable_g711a)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(enable_reinvites)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(check_update)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(exit_on_close_window)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
jPanel8.setBorder(javax.swing.BorderFactory.createTitledBorder("Transfer Option"));
jLabel7.setText("Transfer destination =");
xfer_digit.setText("0");
enable_xfer.setText("Enable transfer : Digit =");
javax.swing.GroupLayout jPanel8Layout = new javax.swing.GroupLayout(jPanel8);
jPanel8.setLayout(jPanel8Layout);
jPanel8Layout.setHorizontalGroup(
jPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel8Layout.createSequentialGroup()
.addContainerGap()
.addComponent(enable_xfer)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(xfer_digit, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel7)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(xfer_number)
.addContainerGap())
);
jPanel8Layout.setVerticalGroup(
jPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel8Layout.createSequentialGroup()
.addContainerGap()
.addGroup(jPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(enable_xfer)
.addComponent(xfer_digit, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(xfer_number, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel7))
.addContainerGap())
);
javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4);
jPanel4.setLayout(jPanel4Layout);
jPanel4Layout.setHorizontalGroup(
jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel4Layout.createSequentialGroup()
.addContainerGap()
.addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jPanel8, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(jPanel4Layout.createSequentialGroup()
.addComponent(jPanel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 136, Short.MAX_VALUE)))
.addContainerGap())
);
jPanel4Layout.setVerticalGroup(
jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel4Layout.createSequentialGroup()
.addGap(10, 10, 10)
.addComponent(jPanel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jPanel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
jTabbedPane1.addTab("Options", jPanel4);
jPanel10.setBorder(javax.swing.BorderFactory.createTitledBorder("Calling Times"));
jLabel26.setText("List all times in 24HR format.");
day1.setText("Sunday");
start1.setText("10:00");
jLabel25.setText("to");
end1.setText("17:00");
day2.setSelected(true);
day2.setText("Monday");
start2.setText("10:00");
jLabel27.setText("to");
end2.setText("17:00");
day3.setSelected(true);
day3.setText("Tuesday");
start3.setText("10:00");
jLabel28.setText("to");
end3.setText("17:00");
day4.setSelected(true);
day4.setText("Wednesday");
start4.setText("10:00");
jLabel29.setText("to");
end4.setText("17:00");
end5.setText("17:00");
jLabel30.setText("to");
start5.setText("10:00");
day5.setSelected(true);
day5.setText("Thursday");
day6.setSelected(true);
day6.setText("Friday");
start6.setText("10:00");
jLabel31.setText("to");
end6.setText("17:00");
day7.setText("Saturday");
start7.setText("10:00");
jLabel32.setText("to");
end7.setText("17:00");
javax.swing.GroupLayout jPanel10Layout = new javax.swing.GroupLayout(jPanel10);
jPanel10.setLayout(jPanel10Layout);
jPanel10Layout.setHorizontalGroup(
jPanel10Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel10Layout.createSequentialGroup()
.addContainerGap()
.addGroup(jPanel10Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel10Layout.createSequentialGroup()
.addComponent(day1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(start1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel25)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(end1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(jPanel10Layout.createSequentialGroup()
.addComponent(jLabel26)
.addGap(0, 0, Short.MAX_VALUE))
.addGroup(jPanel10Layout.createSequentialGroup()
.addComponent(day2)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(start2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel27)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(end2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(jPanel10Layout.createSequentialGroup()
.addComponent(day3)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(start3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel28)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(end3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(jPanel10Layout.createSequentialGroup()
.addComponent(day4)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(start4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel29)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(end4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(jPanel10Layout.createSequentialGroup()
.addComponent(day5)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(start5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel30)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(end5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(jPanel10Layout.createSequentialGroup()
.addComponent(day6)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(start6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel31)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(end6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(jPanel10Layout.createSequentialGroup()
.addComponent(day7)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(start7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel32)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(end7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addContainerGap())
);
jPanel10Layout.setVerticalGroup(
jPanel10Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel10Layout.createSequentialGroup()
.addContainerGap()
.addComponent(jLabel26)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(jPanel10Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(day1)
.addComponent(start1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel25)
.addComponent(end1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel10Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(day2)
.addComponent(start2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel27)
.addComponent(end2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel10Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(day3)
.addComponent(start3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel28)
.addComponent(end3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel10Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(day4)
.addComponent(start4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel29)
.addComponent(end4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel10Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(day5)
.addComponent(start5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel30)
.addComponent(end5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel10Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(day6)
.addComponent(start6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel31)
.addComponent(end6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel10Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(day7)
.addComponent(start7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel32)
.addComponent(end7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
javax.swing.GroupLayout jPanel9Layout = new javax.swing.GroupLayout(jPanel9);
jPanel9.setLayout(jPanel9Layout);
jPanel9Layout.setHorizontalGroup(
jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel9Layout.createSequentialGroup()
.addContainerGap()
.addComponent(jPanel10, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(493, Short.MAX_VALUE))
);
jPanel9Layout.setVerticalGroup(
jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel9Layout.createSequentialGroup()
.addContainerGap()
.addComponent(jPanel10, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(143, Short.MAX_VALUE))
);
jTabbedPane1.addTab("Times", jPanel9);
jPanel5.setBorder(javax.swing.BorderFactory.createTitledBorder("Messages / Questions"));
enable.setText("Enable : WAV=");
wav_filename.setText("filename.wav");
select_file.setText("...");
select_file.setToolTipText("Select File...");
select_file.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
select_fileActionPerformed(evt);
}
});
next_msg.setText(">");
next_msg.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
next_msgActionPerformed(evt);
}
});
prev_msg.setText("<");
prev_msg.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
prev_msgActionPerformed(evt);
}
});
title.setText("#1/99");
single.setText("Single digit response : allowed responses =");
count.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "1", "1-2", "1-3", "1-4", "1-5", "1-6", "1-7", "1-8", "1-9" }));
multi.setText("Long response (user ends input with # or after 5 sec pause) (continues to next message)");
terminate.setText("Terminate call after this message");
gotouser.setText("Goto message from user input (1-99)");
gotouser.setToolTipText("Goto question based on digit pressed.");
goto_1.setText("0");
goto_1.setToolTipText("1");
goto_2.setText("0");
goto_2.setToolTipText("2");
goto_3.setText("0");
goto_3.setToolTipText("3");
goto_4.setText("0");
goto_4.setToolTipText("4");
goto_5.setText("0");
goto_5.setToolTipText("5");
goto_6.setText("0");
goto_6.setToolTipText("6");
goto_7.setText("0");
goto_7.setToolTipText("7");
goto_8.setText("0");
goto_8.setToolTipText("8");
goto_9.setText("0");
goto_9.setToolTipText("9");
jLabel8.setText("1:");
jLabel14.setText("3:");
jLabel15.setText("2:");
jLabel16.setText("4:");
jLabel17.setText("5:");
jLabel18.setText("7:");
jLabel19.setText("6:");
jLabel20.setText("9:");
jLabel21.setText("8:");
cont.setSelected(true);
cont.setText("Continue to next message");
gotoidx.setText("Goto message after this message (1-99)");
gotoidxnum.setText("0");
jLabel22.setText("(continues to next message)");
msg_idx.setMaximum(98);
msg_idx.setValue(0);
msg_idx.addChangeListener(new javax.swing.event.ChangeListener() {
public void stateChanged(javax.swing.event.ChangeEvent evt) {
msg_idxStateChanged(evt);
}
});
xfer.setText("Transfer call after message");
javax.swing.GroupLayout jPanel5Layout = new javax.swing.GroupLayout(jPanel5);
jPanel5.setLayout(jPanel5Layout);
jPanel5Layout.setHorizontalGroup(
jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel5Layout.createSequentialGroup()
.addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel5Layout.createSequentialGroup()
.addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel5Layout.createSequentialGroup()
.addComponent(enable)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(wav_filename, javax.swing.GroupLayout.DEFAULT_SIZE, 391, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED))
.addGroup(jPanel5Layout.createSequentialGroup()
.addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(cont)
.addComponent(terminate))
.addGap(249, 249, 249)))
.addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(msg_idx, 0, 0, Short.MAX_VALUE)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel5Layout.createSequentialGroup()
.addComponent(select_file)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(title, javax.swing.GroupLayout.PREFERRED_SIZE, 45, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(prev_msg)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(next_msg))))
.addGroup(jPanel5Layout.createSequentialGroup()
.addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(multi)
.addGroup(jPanel5Layout.createSequentialGroup()
.addComponent(single)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(count, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jLabel22))
.addGroup(jPanel5Layout.createSequentialGroup()
.addComponent(gotoidx)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(gotoidxnum, javax.swing.GroupLayout.PREFERRED_SIZE, 47, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(jPanel5Layout.createSequentialGroup()
.addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(gotouser, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(xfer, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel8)
.addGap(2, 2, 2)
.addComponent(goto_1, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel15)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(goto_2, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel14)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(goto_3, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel16)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(goto_4, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel17)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(goto_5, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel19)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(goto_6, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel18)
.addGap(6, 6, 6)
.addComponent(goto_7, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel21)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(goto_8, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel20)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(goto_9, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addGap(0, 0, Short.MAX_VALUE)))
.addContainerGap())
);
jPanel5Layout.setVerticalGroup(
jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel5Layout.createSequentialGroup()
.addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(enable)
.addComponent(wav_filename, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(next_msg)
.addComponent(prev_msg)
.addComponent(title)
.addComponent(select_file))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel5Layout.createSequentialGroup()
.addComponent(cont)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(terminate)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(single)
.addComponent(count, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel22)))
.addComponent(msg_idx, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(multi)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(gotoidx)
.addComponent(gotoidxnum, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(gotouser)
.addComponent(goto_1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel8)
.addComponent(jLabel15)
.addComponent(goto_2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(goto_3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(goto_4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel14)
.addComponent(jLabel16)
.addComponent(jLabel17)
.addComponent(goto_5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(goto_6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(goto_7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(goto_8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel18)
.addComponent(jLabel19)
.addComponent(jLabel21)
.addComponent(jLabel20)
.addComponent(goto_9, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(xfer)
.addContainerGap(177, Short.MAX_VALUE))
);
jTabbedPane1.addTab("Messages / Questions", jPanel5);
help.setEditable(false);
help.setColumns(20);
help.setRows(5);
jScrollPane2.setViewportView(help);
javax.swing.GroupLayout jPanel6Layout = new javax.swing.GroupLayout(jPanel6);
jPanel6.setLayout(jPanel6Layout);
jPanel6Layout.setHorizontalGroup(
jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 706, Short.MAX_VALUE)
);
jPanel6Layout.setVerticalGroup(
jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
);
jTabbedPane1.addTab("Help", jPanel6);
save_setup.setText("Save Setup");
save_setup.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
save_setupActionPerformed(evt);
}
});
jButton1.setText("Donate");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(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(jTabbedPane1)
.addGroup(layout.createSequentialGroup()
.addComponent(jLabel1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jButton1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(save_setup))
.addGroup(layout.createSequentialGroup()
.addComponent(start)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(status, 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()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel1)
.addComponent(save_setup)
.addComponent(jButton1))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jTabbedPane1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(start)
.addComponent(status))
.addContainerGap())
);
pack();
}// </editor-fold>//GEN-END:initComponents
private void startActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_startActionPerformed
if (state == states.CALLING) {
stopCalling();
return;
}
if (state == states.STOPPING) {
if (JF.showConfirm("Warning", "Are you sure you want to force stop?")) {
forceStopCalling();
}
return;
}
callingThread = new Thread() {
@Override
public void run() {
startCalling();
}
};
callingThread.start();
}//GEN-LAST:event_startActionPerformed
private void save_setupActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_save_setupActionPerformed
saveSetup();
}//GEN-LAST:event_save_setupActionPerformed
private void msg_idxStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_msg_idxStateChanged
gotoQuestion(msg_idx.getValue());
}//GEN-LAST:event_msg_idxStateChanged
private void prev_msgActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_prev_msgActionPerformed
prevQuestion();
}//GEN-LAST:event_prev_msgActionPerformed
private void next_msgActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_next_msgActionPerformed
nextQuestion();
}//GEN-LAST:event_next_msgActionPerformed
private void select_fileActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_select_fileActionPerformed
selectFile();
}//GEN-LAST:event_select_fileActionPerformed
private void maxAttemptsStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_maxAttemptsStateChanged
validateOptions();
}//GEN-LAST:event_maxAttemptsStateChanged
private void maxRingTimeStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_maxRingTimeStateChanged
validateOptions();
}//GEN-LAST:event_maxRingTimeStateChanged
private void number_linesStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_number_linesStateChanged
validateOptions();
}//GEN-LAST:event_number_linesStateChanged
private void delayStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_delayStateChanged
validateOptions();
}//GEN-LAST:event_delayStateChanged
private void fix_listActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fix_listActionPerformed
fixList(false, false);
}//GEN-LAST:event_fix_listActionPerformed
private void import_listActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_import_listActionPerformed
importList();
}//GEN-LAST:event_import_listActionPerformed
private void export_listActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_export_listActionPerformed
exportList();
}//GEN-LAST:event_export_listActionPerformed
private void delete_listActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_delete_listActionPerformed
deleteList();
}//GEN-LAST:event_delete_listActionPerformed
private void reset_listActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_reset_listActionPerformed
resetList();
}//GEN-LAST:event_reset_listActionPerformed
private void selected_listItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_selected_listItemStateChanged
updateList();
}//GEN-LAST:event_selected_listItemStateChanged
private void create_listActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_create_listActionPerformed
createList();
}//GEN-LAST:event_create_listActionPerformed
private void human_vm_detectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_human_vm_detectActionPerformed
setOptsState();
}//GEN-LAST:event_human_vm_detectActionPerformed
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
JF.donate();
}//GEN-LAST:event_jButton1ActionPerformed
private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
if (settings.exit_on_close_window) {
if (lockFile != null) {
lockFile.unlock();
}
System.exit(0);
} else {
icon.displayMessage(null, "jfBroadcast is still active", TrayIcon.MessageType.NONE);
}
}//GEN-LAST:event_formWindowClosing
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
fixList(false, true);
}//GEN-LAST:event_jButton2ActionPerformed
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
Broadcast.args = args;
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new Broadcast().setVisible(true);
}
});
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.ButtonGroup buttonGroup1;
private javax.swing.JCheckBox check_update;
private javax.swing.JRadioButton cont;
private javax.swing.JComboBox count;
private javax.swing.JButton create_list;
private javax.swing.JCheckBox day1;
private javax.swing.JCheckBox day2;
private javax.swing.JCheckBox day3;
private javax.swing.JCheckBox day4;
private javax.swing.JCheckBox day5;
private javax.swing.JCheckBox day6;
private javax.swing.JCheckBox day7;
private javax.swing.JSpinner delay;
private javax.swing.JButton delete_list;
private javax.swing.JCheckBox enable;
private javax.swing.JCheckBox enable_g711a;
private javax.swing.JCheckBox enable_g711u;
private javax.swing.JCheckBox enable_g729a;
private javax.swing.JCheckBox enable_reinvites;
private javax.swing.JCheckBox enable_xfer;
private javax.swing.JTextField end1;
private javax.swing.JTextField end2;
private javax.swing.JTextField end3;
private javax.swing.JTextField end4;
private javax.swing.JTextField end5;
private javax.swing.JTextField end6;
private javax.swing.JTextField end7;
private javax.swing.JCheckBox exit_on_close_window;
private javax.swing.JButton export_list;
private javax.swing.JButton fix_list;
private javax.swing.JTextField goto_1;
private javax.swing.JTextField goto_2;
private javax.swing.JTextField goto_3;
private javax.swing.JTextField goto_4;
private javax.swing.JTextField goto_5;
private javax.swing.JTextField goto_6;
private javax.swing.JTextField goto_7;
private javax.swing.JTextField goto_8;
private javax.swing.JTextField goto_9;
private javax.swing.JRadioButton gotoidx;
private javax.swing.JTextField gotoidxnum;
private javax.swing.JRadioButton gotouser;
private javax.swing.JTextField greeting_threshold;
private javax.swing.JTextArea help;
private javax.swing.JCheckBox human_vm_detect;
private javax.swing.JButton import_list;
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton2;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel10;
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 jLabel17;
private javax.swing.JLabel jLabel18;
private javax.swing.JLabel jLabel19;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel20;
private javax.swing.JLabel jLabel21;
private javax.swing.JLabel jLabel22;
private javax.swing.JLabel jLabel23;
private javax.swing.JLabel jLabel24;
private javax.swing.JLabel jLabel25;
private javax.swing.JLabel jLabel26;
private javax.swing.JLabel jLabel27;
private javax.swing.JLabel jLabel28;
private javax.swing.JLabel jLabel29;
private javax.swing.JLabel jLabel3;
private javax.swing.JLabel jLabel30;
private javax.swing.JLabel jLabel31;
private javax.swing.JLabel jLabel32;
private javax.swing.JLabel jLabel33;
private javax.swing.JLabel jLabel34;
private javax.swing.JLabel jLabel35;
private javax.swing.JLabel jLabel36;
private javax.swing.JLabel jLabel4;
private javax.swing.JLabel jLabel5;
private javax.swing.JLabel jLabel6;
private javax.swing.JLabel jLabel7;
private javax.swing.JLabel jLabel8;
private javax.swing.JLabel jLabel9;
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel10;
private javax.swing.JPanel jPanel11;
private javax.swing.JPanel jPanel2;
private javax.swing.JPanel jPanel3;
private javax.swing.JPanel jPanel4;
private javax.swing.JPanel jPanel5;
private javax.swing.JPanel jPanel6;
private javax.swing.JPanel jPanel7;
private javax.swing.JPanel jPanel8;
private javax.swing.JPanel jPanel9;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JTabbedPane jTabbedPane1;
private javax.swing.JTable listView;
private javax.swing.JTextField list_name;
private javax.swing.JSpinner maxAttempts;
private javax.swing.JSpinner maxRingTime;
private javax.swing.JSlider msg_idx;
private javax.swing.JRadioButton multi;
private javax.swing.JButton next_msg;
private javax.swing.JSpinner number_lines;
private javax.swing.JButton prev_msg;
private javax.swing.JButton reset_list;
private javax.swing.JButton save_setup;
private javax.swing.JButton select_file;
private javax.swing.JComboBox selected_list;
private javax.swing.JTextField silence_duration;
private javax.swing.JTextField silence_threshold;
private javax.swing.JRadioButton single;
private javax.swing.JTextField sip_auth;
private javax.swing.JTextField sip_end;
private javax.swing.JTextField sip_host;
private javax.swing.JTextField sip_name;
private javax.swing.JPasswordField sip_pass;
private javax.swing.JTextField sip_start;
private javax.swing.JTextField sip_user;
private javax.swing.JButton start;
private javax.swing.JTextField start1;
private javax.swing.JTextField start2;
private javax.swing.JTextField start3;
private javax.swing.JTextField start4;
private javax.swing.JTextField start5;
private javax.swing.JTextField start6;
private javax.swing.JTextField start7;
private javax.swing.JLabel status;
private javax.swing.JRadioButton terminate;
private javax.swing.JLabel title;
private javax.swing.JCheckBox voicemail_hangup;
private javax.swing.JTextField wav_filename;
private javax.swing.JRadioButton xfer;
private javax.swing.JTextField xfer_digit;
private javax.swing.JTextField xfer_number;
// End of variables declaration//GEN-END:variables
//global data
enum states { STOPPED, CALLING, STOPPING};
states state = states.STOPPED;
Thread callingThread;
int lineCount;
SIPClient sip;
Lines lines[];
boolean registered;
short silence[] = new short[160];
short tmp[] = new short[160];
Wav wav[];
SQL psql; //persistant sql connection
String dbname = "broadcast";
String listid;
volatile boolean processing = false;
int skipCount;
int maxquietcount;
static String args[];
static class update {
public String number, status, survey;
public update(String number, String status, String survey) {
this.number = number;
this.status = status;
this.survey = survey;
}
}
Vector<update> updateList = new Vector<update>();
final static int NUMQUESTIONS = 99;
//actions
final static int A_CONT = 0;
final static int A_TERMINATE = 4;
final static int A_SINGLE = 1;
final static int A_MULTI = 2;
final static int A_GOTOUSER = 3;
final static int A_GOTOIDX = 5;
final static int A_XFER = 6;
public void createDatabase() {
if (new File(dbPath + "/" + databaseName + "/service.properties").exists()) return; //already exists
JFTask task = new JFTask() {
public boolean work() {
this.setTitle("Creating database...");
this.setLabel("Creating database...");
this.setProgress(25);
SQL sql = new SQL();
if (!sql.connect("jdbc:derby:" + databaseName + ";" + "create=true")) {
this.setLabel("Database create failed : SQL connection failed");
return false;
}
this.setProgress(50);
if (!sql.execute("create table lists (id int GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1) primary key, name varchar(37) not null unique)")) {
this.setLabel("Database create failed : Create Table failed (already created?)");
return false;
}
this.setProgress(75);
if (!sql.execute("create table listdata (id int not null, number varchar(32) not null, status varchar(32) default 'new' not null, attempts int default 0 not null, survey varchar(64), called timestamp, unique(number, id))")) {
this.setLabel("Database create failed : Create Table failed (already created?)");
return false;
}
this.setProgress(100);
this.setLabel("Database created succesfully");
return true;
}
};
ProgressDialog pd = new ProgressDialog(this, true, task);
pd.setVisible(true);
}
public void setStatus(String str) {
status.setText("Status:" + str);
}
public String safe(String str) {
char strin[] = str.toCharArray();
char strout[] = new char[str.length()];
for(int a=0;a<strin.length;a++) {
if ((Character.toLowerCase(strin[a]) >= 'a') && (Character.toLowerCase(strin[a]) <= 'z')) {
strout[a] = strin[a];
continue;
}
if ((strin[a] >= '0') && (strin[a] <= '9')) {
strout[a] = strin[a];
continue;
}
strout[a] = '_';
}
return new String(strout);
}
public String sip_pass_getText() {
return new String(sip_pass.getPassword());
}
public void createList() {
String safe = safe(list_name.getText());
if (safe.length() == 0) return;
SQL sql = new SQL();
if (!sql.connect("jdbc:derby:" + databaseName)) {
setStatus("SQL connection failed");
return;
}
if (!sql.execute("insert into lists values (default, '" + safe + "')")) {
setStatus("Insert failed (already created?)");
return;
}
setStatus("OK:CreateTable:" + safe);
updateAvailableLists();
}
public void deleteList() {
String sel = (String)selected_list.getSelectedItem();
if (sel == null || sel.length() == 0) return;
if (JOptionPane.showConfirmDialog(null, "Delete List:" + sel + "?", "Sure?", JOptionPane.OK_CANCEL_OPTION) != JOptionPane.OK_OPTION) return;
SQL sql = new SQL();
if (!sql.connect("jdbc:derby:" + databaseName)) {
setStatus("SQL connection failed");
return;
}
if (!sql.execute("delete from listdata where id=(select id from lists where name='"+sel+"')")) {
setStatus("delete from lists failed(1)");
return;
}
if (!sql.execute("delete from lists where name='"+sel+"'")) {
setStatus("delete from lists failed(2)");
return;
}
setStatus("OK:DeleteList:"+sel);
updateAvailableLists();
updateList();
}
public void resetList() {
String sel = (String)selected_list.getSelectedItem();
if (sel == null || sel.length() == 0) return;
if (JOptionPane.showConfirmDialog(null, "Reset List:" + sel + "?", "Sure?", JOptionPane.OK_CANCEL_OPTION) != JOptionPane.OK_OPTION) return;
SQL sql = new SQL();
if (!sql.connect("jdbc:derby:" + databaseName)) {
setStatus("SQL connection failed");
return;
}
if (!sql.execute("update listdata set status='new', attempts = 0, survey = '', called = null where id=(select id from lists where name='" + sel + "')")) {
setStatus("update failed");
return;
}
setStatus("OK:ResetList:"+sel);
updateList();
}
public void fixList(boolean quite, boolean errors) {
String sel = (String)selected_list.getSelectedItem();
if (sel == null || sel.length() == 0) return;
if (!quite) {
String msg;
if (errors) {
msg = "Fix 'errors' in List:" + sel + "?";
} else {
msg = "Fix 'calling' in List:" + sel + "?";
}
if (JOptionPane.showConfirmDialog(null, msg, "Sure?", JOptionPane.OK_CANCEL_OPTION) != JOptionPane.OK_OPTION) return;
}
SQL sql = new SQL();
if (!sql.connect("jdbc:derby:" + databaseName)) {
setStatus("SQL connection failed");
return;
}
String query;
if (errors) {
query = "update listdata set status='new', attempts = 0, survey = '', called = null where status like 'err_%' and id=(select id from lists where name='" + sel + "')";
} else {
query = "update listdata set status='new', attempts = 0, survey = '', called = null where status='calling' and id=(select id from lists where name='" + sel + "')";
}
if (!sql.execute(query)) {
setStatus("update failed");
return;
}
if (!quite) {
setStatus("OK:FixList:"+sel);
}
updateList();
}
public final void updateAvailableLists() {
File file = new File(dbPath + "/" + databaseName);
if (!file.exists()) return; //not ready
String data[][];
SQL sql = new SQL();
if (!sql.connect("jdbc:derby:" + databaseName)) {
// setStatus("SQL connection failed");
return;
}
data = sql.select("select name from lists");
if (data == null) {
// setStatus("select failed");
return;
}
int yc = data.length;
if (yc == 0) {
//???
}
ArrayList<String> al = new ArrayList<String>();
String e;
for(int y=0;y<yc;y++) {
e = data[y][0];
al.add(e);
}
selected_list.setModel(new DefaultComboBoxModel(al.toArray()));
// selectedList.setSelectedIndex(0);
updateList();
}
private String getid(SQL sql, String sel) {
String data[][];
data = sql.select("select id from lists where name='" + sel +"'");
if (data == null) {
// setStatus("select failed");
return null;
}
int yc = data.length;
if (yc != 1) return null;
return data[0][0];
}
public void importList() {
String sel = (String)selected_list.getSelectedItem();
if (sel == null || sel.length() == 0) return;
JFileChooser chooser = new JFileChooser();
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
chooser.setMultiSelectionEnabled(false);
chooser.setCurrentDirectory(new File(JF.getCurrentPath()));
if (chooser.showOpenDialog(this) != JFileChooser.APPROVE_OPTION) return;
String num;
SQL sql = new SQL();
if (!sql.connect("jdbc:derby:" + databaseName)) {
setStatus("SQL connection failed");
return;
}
int line = 1;
int errcnt = 0;
int okcnt = 0;
ArrayList<String> numbers = null;
int duptag = 1;
if (allowdups) {
numbers = new ArrayList<String>();
int cnt = listView.getRowCount();
for(int a=0;a<cnt;a++) {
numbers.add((String)listView.getValueAt(a, 0));
}
}
try {
String id = getid(sql, sel);
if (id == null) throw new Exception("unable to find list");
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(chooser.getSelectedFile().toString())));
do {
num = reader.readLine();
if (num == null) break;
int idx2 = num.indexOf(",");
if (idx2 != -1) {
num = num.substring(0, idx2);
}
num = num.trim();
if (allowdups) {
//check if this number already exists and add a tag to it
if (numbers.contains(num)) {
num += "," + duptag++;
}
numbers.add(num);
}
if (!sql.execute("insert into listdata (id, number) values (" + id + ",'" + num + "')")) {
errcnt++;
} else {
okcnt++;
}
line++;
} while (true);
reader.close();
} catch (Exception e) {
setStatus(e.toString());
updateList();
return;
}
setStatus("OK : File loaded : Inserted = " + okcnt + " : Errors = " + errcnt);
updateList();
}
public void exportList() {
String data[][];
String sel = (String)selected_list.getSelectedItem();
if (sel == null || sel.length() == 0) return;
JFileChooser chooser = new JFileChooser();
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
chooser.setMultiSelectionEnabled(false);
chooser.setCurrentDirectory(new File(JF.getCurrentPath()));
if (chooser.showSaveDialog(this) != JFileChooser.APPROVE_OPTION) return;
String num;
SQL sql = new SQL();
if (!sql.connect("jdbc:derby:" + databaseName)) {
setStatus("SQL connection failed");
return;
}
data = sql.select("select number,status,attempts,survey,called from listdata where id=(select id from lists where name='" + sel + "')");
if (data == null) {
setStatus("select failed (1)");
return;
}
try {
FileOutputStream fos = new FileOutputStream(chooser.getSelectedFile().toString());
for(int a=0;a<data.length;a++) {
String timestamp = data[a][4];
String date = "null", time = "null";
if (timestamp != null && timestamp.length() > 10) {
date = timestamp.substring(0, 10);
time = timestamp.substring(11);
}
fos.write((data[a][0] + "," + data[a][1] + "," + data[a][2] + "," + data[a][3] + "," + date + "," + time + "\r\n").getBytes());
}
fos.close();
} catch (Exception e) {
setStatus(e.toString());
return;
}
setStatus("OK : List exported");
}
private String cols[] = new String[] {"Number","Status","Attempts","Survey","Timestamp"};
public void updateList() {
String data[][];
String sel = (String)selected_list.getSelectedItem();
if (sel == null || sel.length() == 0) {
listView.setModel(new DefaultTableModel(new String[][] {}, cols));
return;
}
SQL sql = new SQL();
if (!sql.connect("jdbc:derby:" + databaseName)) {
// setStatus("SQL connection failed");
return;
}
data = sql.select("select number, status, attempts, survey, called from listdata where id=(select id from lists where name='" + sel + "')");
if (data == null) {
data = new String[][] {};
}
listView.setModel(new DefaultTableModel(data, cols));
}
public boolean isConfigValid() {
if (xfer_digit.getText().length() != 1) {setStatus("Error:Transfer digit is invalid"); return false;}
for(int a=0;a<NUMQUESTIONS;a++) {
if (questions.action[a] == A_GOTOUSER) {
for(int b=0;b<9;b++) {
if (questions.gotouser[a][b] != 0) break;
if (b==8) {
setStatus("Error:Question #" + (a+1) + " has an undefined goto action.");
return false;
}
}
}
if (questions.action[a] == A_GOTOIDX) {
if (questions.gotoidx[a] == 0) {
setStatus("Error:Question #" + (a+1) + " has an undefined goto action.");
return false;
}
}
}
if (sip_host.getText().length() == 0) {
setStatus("Error:SIP host undefined.");
return false;
}
if (sip_user.getText().length() == 0) {
setStatus("Error:SIP user undefined.");
return false;
}
int cnt = 0;
try {
int start = Integer.valueOf(sip_start.getText());
if (start < 1024 || start > 60000) {
setStatus("Error:SIP Port start is not in range");
return false;
}
int end = Integer.valueOf(sip_end.getText());
if (end < 1024 || end > 60000) {
setStatus("Error:SIP Port end is not in range");
return false;
}
if (end < start || (end-start < 1000)) {
setStatus("Error:SIP Port range is invalid");
return false;
}
for(int a=0;a<NUMQUESTIONS;a++) {
if (!questions.enabled[a]) continue;
File test = new File(questions.wav[a]);
if (!test.exists()) {
setStatus("Error : Message #" + (a+1) + " WAV file doesn't exist.");
return false;
}
cnt++;
}
} catch (Exception e) {
setStatus("Error:" + e);
return false;
}
if (cnt == 0) {
setStatus("Error:No messages defined.");
return false;
}
cnt = 0;
if (enable_g729a.isSelected()) cnt++;
if (enable_g711u.isSelected()) cnt++;
if (enable_g711a.isSelected()) cnt++;
if (cnt == 0) {
setStatus("Error:Must enable at least one codec");
return false;
}
return true;
}
public static class Settings implements Serializable {
static final long serialVersionUID = 1000L;
String sql_host, sql_user, sql_pass; //obsolete (do not delete or old cfg will not load)
String sip_name, sip_user, sip_auth, sip_host, sip_pass;
String wav_filename; //obsolete
int numberLines = 8;
String xfer;
boolean disable_g729a; //obsolete
int delay = 100;
boolean enable_xfer = false;
char xfer_digit = '0';
int maxRingTime = 60; //in seconds
int maxAttempts = 3;
boolean disable_detect = false;
boolean enable_g729a = true, enable_g711u = true, enable_g711a = false;
boolean enable_reinvites = true;
boolean check_update = true;
int greetingThreshold = 1000, silenceThreshold = 1000, silenceDuration = 1000;
//calling times
boolean day[] = new boolean[] {false, true, true, true, true, true, false};
String start[] = new String[] {"10:00", "10:00", "10:00", "10:00", "10:00", "10:00", "10:00"};
String end[] = new String[] {"17:00", "17:00", "17:00", "17:00", "17:00", "17:00", "17:00"};
//sip port range
int sip_start, sip_end;
boolean voicemail_hangup;
boolean exit_on_close_window;
}
private Settings settings;
public final void loadSetup() {
try {
FileInputStream fis = new FileInputStream(JF.getUserPath() + "/broadcast" + cfgSuffix + ".cfg");
ObjectInputStream ois = new ObjectInputStream(fis);
settings = (Settings)ois.readObject();
fis.close();
sip_name.setText(settings.sip_name);
sip_user.setText(settings.sip_user);
sip_auth.setText(settings.sip_auth);
sip_host.setText(settings.sip_host);
sip_pass.setText(settings.sip_pass);
if (settings.sip_start == 0) {
settings.sip_start = 6000;
settings.sip_end = 9000;
}
sip_start.setText("" + settings.sip_start);
sip_end.setText("" + settings.sip_end);
number_lines.setValue(new Integer(settings.numberLines));
xfer_number.setText(settings.xfer);
if (settings.delay == 0) settings.delay = 100;
delay.setValue(new Integer(settings.delay));
enable_xfer.setSelected(settings.enable_xfer);
xfer_digit.setText("" + settings.xfer_digit);
if (settings.maxRingTime == 0) settings.maxRingTime = 60;
maxRingTime.setValue(new Integer(settings.maxRingTime));
if (settings.maxAttempts == 0) settings.maxAttempts = 3;
maxAttempts.setValue(new Integer(settings.maxAttempts));
enable_g729a.setSelected(settings.enable_g729a);
enable_g711u.setSelected(settings.enable_g711u);
enable_g711a.setSelected(settings.enable_g711a);
enable_reinvites.setSelected(settings.enable_reinvites);
check_update.setSelected(settings.check_update);
exit_on_close_window.setSelected(settings.exit_on_close_window);
human_vm_detect.setSelected(!settings.disable_detect);
greeting_threshold.setText(Integer.toString(settings.greetingThreshold));
silence_threshold.setText(Integer.toString(settings.silenceThreshold));
silence_duration.setText(Integer.toString(settings.silenceDuration));
voicemail_hangup.setSelected(settings.voicemail_hangup);
if (settings.day == null) {
settings.day = new boolean[] {false, true, true, true, true, true, false};
}
day1.setSelected(settings.day[0]);
day2.setSelected(settings.day[1]);
day3.setSelected(settings.day[2]);
day4.setSelected(settings.day[3]);
day5.setSelected(settings.day[4]);
day6.setSelected(settings.day[5]);
day7.setSelected(settings.day[6]);
if (settings.start == null) {
settings.start = new String[] {"10:00", "10:00", "10:00", "10:00", "10:00", "10:00", "10:00"};
}
start1.setText(settings.start[0]);
start2.setText(settings.start[1]);
start3.setText(settings.start[2]);
start4.setText(settings.start[3]);
start5.setText(settings.start[4]);
start6.setText(settings.start[5]);
start7.setText(settings.start[6]);
if (settings.end == null) {
settings.end = new String[] {"17:00", "17:00", "17:00", "17:00", "17:00", "17:00", "17:00"};
}
end1.setText(settings.end[0]);
end2.setText(settings.end[1]);
end3.setText(settings.end[2]);
end4.setText(settings.end[3]);
end5.setText(settings.end[4]);
end6.setText(settings.end[5]);
end7.setText(settings.end[6]);
fis = new FileInputStream(JF.getUserPath() + "/broadcast-msgs" + cfgSuffix + ".cfg");
ois = new ObjectInputStream(fis);
questions = (Questions)ois.readObject();
fis.close();
} catch (FileNotFoundException e) {
loadDefaults();
setStatus("Loading default settings");
JFLog.log("No config found");
} catch (Exception e) {
loadDefaults();
setStatus("Load Settings Failed:" + e);
JFLog.log(e);
}
validateOptions();
}
private void loadDefaults() {
settings = new Settings();
sip_start.setText("6000");
sip_end.setText("9000");
number_lines.setValue(new Integer(8));
delay.setValue(new Integer(100));
maxRingTime.setValue(new Integer(60));
maxAttempts.setValue(new Integer(3));
human_vm_detect.setSelected(true);
greeting_threshold.setText("1000");
silence_threshold.setText("1000");
silence_duration.setText("2000");
voicemail_hangup.setSelected(false);
enable_reinvites.setSelected(true);
enable_g729a.setSelected(true);
enable_g711u.setSelected(true);
enable_g711a.setSelected(false);
check_update.setSelected(true);
exit_on_close_window.setSelected(false);
day1.setSelected(false);
day2.setSelected(true);
day3.setSelected(true);
day4.setSelected(true);
day5.setSelected(true);
day6.setSelected(true);
day7.setSelected(false);
start1.setText("10:00");
start2.setText("10:00");
start3.setText("10:00");
start4.setText("10:00");
start5.setText("10:00");
start6.setText("10:00");
start7.setText("10:00");
end1.setText("17:00");
end2.setText("17:00");
end3.setText("17:00");
end4.setText("17:00");
end5.setText("17:00");
end6.setText("17:00");
end7.setText("17:00");
}
private void validateTime(JTextField field, String def) {
String txt = field.getText();
String f[] = txt.split("[:]");
if (f.length != 2) {
field.setText(def);
return;
}
int hr = JF.atoi(f[0]);
int min = JF.atoi(f[1]);
if (hr < 0 || hr > 24 || min < 0 || min > 59) {
field.setText(def);
}
}
private void validateOptions() {
if ((Integer)number_lines.getValue() < 1) {
number_lines.setValue(new Integer(1));
}
if ((Integer)delay.getValue() < 100) {
delay.setValue(new Integer(100));
}
if ((Integer)delay.getValue() > 10000) {
delay.setValue(new Integer(10000));
}
if ((Integer)maxRingTime.getValue() < 10) {
maxRingTime.setValue(new Integer(10));
}
if ((Integer)maxRingTime.getValue() > 100) {
maxRingTime.setValue(new Integer(100));
}
if ((Integer)maxAttempts.getValue() < 1) {
maxAttempts.setValue(new Integer(1));
}
if ((Integer)maxAttempts.getValue() > 100) {
maxAttempts.setValue(new Integer(100));
}
validateTime(start1, "10:00");
validateTime(start2, "10:00");
validateTime(start3, "10:00");
validateTime(start4, "10:00");
validateTime(start5, "10:00");
validateTime(start6, "10:00");
validateTime(start7, "10:00");
validateTime(end1, "17:00");
validateTime(end2, "17:00");
validateTime(end3, "17:00");
validateTime(end4, "17:00");
validateTime(end5, "17:00");
validateTime(end6, "17:00");
validateTime(end7, "17:00");
int value = JF.atoi(greeting_threshold.getText());
if (value < 100 || value > 32000) greeting_threshold.setText("1000");
value = JF.atoi(silence_threshold.getText());
if (value < 100 || value > 32000) silence_threshold.setText("1000");
value = JF.atoi(silence_duration.getText());
if (value < 100 || value > 5000) silence_duration.setText("2000");
}
public void saveSetup() {
validateOptions();
saveQuestion();
try {
FileOutputStream fos = new FileOutputStream(JF.getUserPath() + "/broadcast" + cfgSuffix + ".cfg");
ObjectOutputStream oos = new ObjectOutputStream(fos);
settings = new Settings();
settings.sip_name = sip_name.getText();
settings.sip_user = sip_user.getText();
settings.sip_auth = sip_auth.getText();
settings.sip_host = sip_host.getText();
settings.sip_pass = sip_pass_getText();
settings.sip_start = Integer.valueOf(sip_start.getText());
settings.sip_end = Integer.valueOf(sip_end.getText());
settings.wav_filename = ""; //obsolete
settings.numberLines = (Integer)(number_lines.getValue());
settings.xfer = xfer_number.getText();
settings.disable_detect = !human_vm_detect.isSelected();
settings.greetingThreshold = JF.atoi(greeting_threshold.getText());
settings.silenceThreshold = JF.atoi(silence_threshold.getText());
settings.silenceDuration = JF.atoi(silence_duration.getText());
settings.voicemail_hangup = voicemail_hangup.isSelected();
settings.delay = (Integer)(delay.getValue());
settings.enable_xfer = enable_xfer.isSelected();
settings.xfer_digit = xfer_digit.getText().charAt(0);
settings.maxRingTime = (Integer)(maxRingTime.getValue());
settings.maxAttempts = (Integer)(maxAttempts.getValue());
settings.enable_g729a = enable_g729a.isSelected();
settings.enable_g711u = enable_g711u.isSelected();
settings.enable_g711a = enable_g711a.isSelected();
settings.enable_reinvites = enable_reinvites.isSelected();
settings.check_update = check_update.isSelected();
settings.day[0] = day1.isSelected();
settings.day[1] = day2.isSelected();
settings.day[2] = day3.isSelected();
settings.day[3] = day4.isSelected();
settings.day[4] = day5.isSelected();
settings.day[5] = day6.isSelected();
settings.day[6] = day7.isSelected();
settings.start[0] = start1.getText();
settings.start[1] = start2.getText();
settings.start[2] = start3.getText();
settings.start[3] = start4.getText();
settings.start[4] = start5.getText();
settings.start[5] = start6.getText();
settings.start[6] = start7.getText();
settings.end[0] = end1.getText();
settings.end[1] = end2.getText();
settings.end[2] = end3.getText();
settings.end[3] = end4.getText();
settings.end[4] = end5.getText();
settings.end[5] = end6.getText();
settings.end[6] = end7.getText();
oos.writeObject(settings);
fos.close();
fos = new FileOutputStream(JF.getUserPath() + "/broadcast-msgs" + cfgSuffix + ".cfg");
oos = new ObjectOutputStream(fos);
oos.writeObject(questions);
fos.close();
} catch (Exception e) {
setStatus("Save Settings Failed:" + e);
JFLog.log(e);
return;
}
setStatus("OK : saved");
}
public int firstlocalsipport = 6000;
public int nextlocalsipport = 6000;
public int lastlocalsipport = 9000;
public int getlocalsipport() {
int ret = nextlocalsipport;
nextlocalsipport++;
if (nextlocalsipport == lastlocalsipport) nextlocalsipport = firstlocalsipport;
return ret;
}
public String getHost(String host) {
int idx = host.indexOf(":");
if (idx == -1) return host;
return host.substring(0, idx);
}
public int getPort(String host, int def) {
int idx = host.indexOf(":");
if (idx == -1) return def;
return Integer.valueOf(host.substring(idx+1));
}
public static class Lines {
boolean inuse = false; //this line in use?
boolean ringing = false; //is line ringing
boolean talking = false; //are we talking to someone on a line
boolean xfered = false; //was call transfered
boolean hello = false; //did we hear something on the line
boolean repeat = false; //repeating message
String number; //number we called
String callid; //not caller id, but a unique ID for this call leg
String survey; //user responses (long responses are in brackets)
String multi; //for long inputs
RTP rtp;
int msgidx = 0;
int wavpos = 0;
int ringwait = 0;
int postwait = 0;
int quietcount = 0; //wait till we hear quiet after hello (answering machine detection)
int noresponse = 0;
boolean voicemail = false;
}
public void startCalling() {
if (!isConfigValid()) return;
String sel = (String)selected_list.getSelectedItem();
if (sel == null || sel.length() == 0) {
setStatus("Pick a valid list(1)");
return;
}
saveSetup();
firstlocalsipport = settings.sip_start;
nextlocalsipport = firstlocalsipport;
lastlocalsipport = settings.sip_end;
skipCount = 0;
maxquietcount = settings.silenceDuration / 20;
//lock resources
setState(false);
if (sip_pass_getText().length() == 0)
setStatus("waiting for register");
else
setStatus("calling");
JFLog.log("thresholds : " + settings.greetingThreshold + "," + settings.silenceThreshold + "," + settings.silenceDuration);
fixList(true, false);
//load WAV file(s)
wav = new Wav[NUMQUESTIONS];
int cnt = 0;
for(int a=0;a<NUMQUESTIONS;a++) {
wav[a] = new Wav();
if (!questions.enabled[a]) continue;
if (!wav[a].load(questions.wav[a])) {
setStatus(wav[a].errmsg);
setState(true);
return;
}
cnt++;
}
if (cnt == 0) {
setStatus("no messages");
setState(true);
return;
}
//create persistant sql connection
psql = new SQL();
if (!psql.connect("jdbc:derby:" + databaseName)) {
setStatus("SQL connection failed");
setState(true);
return;
}
listid = getid(psql, sel);
if (listid == null) {
setStatus("Error : Pick a valid list");
psql.close();
setState(true);
return;
}
state = states.CALLING;
start.setText("Stop");
//create SIP resources
lineCount = (Integer)number_lines.getValue();
sip = new SIPClient();
int fail = 0;
while (!sip.init(getHost(sip_host.getText()), getPort(sip_host.getText(), 5060), getlocalsipport(), this, SIP.Transport.UDP)) {
fail++;
if (fail == 10) {
setStatus("Error:SIP init failed");
setState(true);
state = states.STOPPED;
start.setText("Start!");
return;
}
}
if (sip_pass_getText().length() > 0) {
sip.register(sip_name.getText(), sip_user.getText(), sip_auth.getText(), sip_pass_getText());
registered = false;
} else {
registered = true;
}
lines = new Lines[lineCount];
for(int a=0;a<lineCount;a++) {
lines[a] = new Lines();
}
//create 20ms timer
java.util.Timer timer = new java.util.Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
process();
}
}, 0, 20);
int delayms = (Integer)delay.getValue();
while (state == states.CALLING) {
//look for a free SIP resource and fill it with a call
JF.sleep(delayms);
processUpdateList();
if (!inCallingTime()) {
JF.sleep(250);
continue;
}
String number = nextAvailableNumber(); //NOTE:this keeps sql connection established (keep alive)
if (!registered) continue;
if (number == null) {
//no more numbers to dial
if (anyStillCalling()) continue;
setStatus("Finished list");
break;
}
for(int a=0;a<lineCount;a++) {
if (lines[a].inuse) continue;
lines[a].rtp = null;
lines[a].msgidx = 0;
lines[a].wavpos = 0;
lines[a].ringwait = 0;
lines[a].postwait = 0;
lines[a].xfered = false;
lines[a].hello = false;
lines[a].repeat = false;
lines[a].number = number;
lines[a].quietcount = 0;
lines[a].voicemail = false;
lines[a].survey = "";
lines[a].multi = "";
lines[a].inuse = true;
lines[a].callid = dialNumber(number, lines[a]);
markCalling(number);
break;
}
}
while (anyStillCalling()) {
processUpdateList();
JF.sleep(1000); //wait for all calls to finish
}
processUpdateList();
psql.close();
timer.cancel();
//unlock resources
setState(true);
if (state == states.STOPPING) {
setStatus("stopped");
}
sip.unregister();
sip.uninit();
state = states.STOPPED;
start.setText("Start!");
}
public void stopCalling() {
state = states.STOPPING;
setStatus("stopping");
}
public void forceStopCalling() {
setStatus("killing connections");
for(int a=0;a<lines.length;a++) {
if (lines[a].inuse) {
sip.bye(lines[a].callid);
endCall(lines[a], "err_force_stop");
}
}
}
public boolean inCallingTime() {
Calendar c = Calendar.getInstance();
int cday = c.get(Calendar.DAY_OF_WEEK); //1-7
cday--; //0-6
int chr = c.get(Calendar.HOUR_OF_DAY); //0-23
int cmin = c.get(Calendar.MINUTE); //0-59
if (!settings.day[cday]) return false;
String start = settings.start[cday];
String startf[] = start.split("[:]");
int starthr = JF.atoi(startf[0]);
int startmin = JF.atoi(startf[1]);
if (chr < starthr) return false;
if (chr == starthr && cmin < startmin) return false;
String end = settings.end[cday];
String endf[] = end.split("[:]");
int endhr = JF.atoi(endf[0]);
int endmin = JF.atoi(endf[1]);
if (chr > endhr) return false;
if (chr == endhr && cmin > endmin) return false;
return true;
}
public void setState(boolean state) {
sip_host.setEnabled(state);
sip_auth.setEnabled(state);
sip_name.setEnabled(state);
sip_user.setEnabled(state);
sip_pass.setEnabled(state);
sip_start.setEnabled(state);
sip_end.setEnabled(state);
save_setup.setEnabled(state);
create_list.setEnabled(state);
delete_list.setEnabled(state);
selected_list.setEnabled(state);
import_list.setEnabled(state);
number_lines.setEnabled(state);
xfer_number.setEnabled(state);
reset_list.setEnabled(state);
list_name.setEnabled(state);
enable_g729a.setEnabled(state);
enable_g711u.setEnabled(state);
enable_g711a.setEnabled(state);
enable_reinvites.setEnabled(state);
check_update.setEnabled(state);
exit_on_close_window.setEnabled(state);
human_vm_detect.setEnabled(state);
greeting_threshold.setEnabled(state);
silence_threshold.setEnabled(state);
silence_duration.setEnabled(state);
voicemail_hangup.setEnabled(state);
export_list.setEnabled(state);
delay.setEnabled(state);
enable_xfer.setEnabled(state);
xfer_digit.setEnabled(state);
fix_list.setEnabled(state);
enable.setEnabled(state);
wav_filename.setEnabled(state);
select_file.setEnabled(state);
single.setEnabled(state);
multi.setEnabled(state);
count.setEnabled(state);
cont.setEnabled(state);
terminate.setEnabled(state);
gotouser.setEnabled(state);
gotoidx.setEnabled(state);
gotoidxnum.setEnabled(state);
goto_1.setEnabled(state);
goto_2.setEnabled(state);
goto_3.setEnabled(state);
goto_4.setEnabled(state);
goto_5.setEnabled(state);
goto_6.setEnabled(state);
goto_7.setEnabled(state);
goto_8.setEnabled(state);
goto_9.setEnabled(state);
maxRingTime.setEnabled(state);
maxAttempts.setEnabled(state);
xfer.setEnabled(state);
day1.setEnabled(state);
day2.setEnabled(state);
day3.setEnabled(state);
day4.setEnabled(state);
day5.setEnabled(state);
day6.setEnabled(state);
day7.setEnabled(state);
start1.setEnabled(state);
start2.setEnabled(state);
start3.setEnabled(state);
start4.setEnabled(state);
start5.setEnabled(state);
start6.setEnabled(state);
start7.setEnabled(state);
end1.setEnabled(state);
end2.setEnabled(state);
end3.setEnabled(state);
end4.setEnabled(state);
end5.setEnabled(state);
end6.setEnabled(state);
end7.setEnabled(state);
}
public String nextAvailableNumber() {
String data[][];
String sel = (String)selected_list.getSelectedItem();
if (sel == null || sel.length() == 0) return null;
//select next available number where status='new' or 'busy'. order by status desc to get 'new' before 'busy'
data = psql.select("select number from listdata where (status = 'new' or status = 'busy') and attempts < " + settings.maxAttempts + " and id=" + listid + " order by status desc, attempts asc fetch first row only");
if (data == null) {
setStatus("nextAvailableNumber : select failed (1)");
return null;
}
if (data.length == 0) return null;
return data[0][0];
}
public Codec[] getCodecs() {
Codec codecs[] = new Codec[0];
if (enable_g729a.isSelected()) codecs = SIP.addCodec(codecs, RTP.CODEC_G729a);
if (enable_g711u.isSelected()) codecs = SIP.addCodec(codecs, RTP.CODEC_G711u);
if (enable_g711a.isSelected()) codecs = SIP.addCodec(codecs, RTP.CODEC_G711a);
return codecs;
}
public String dialNumber(String number, Lines line) {
//generate a callid and initiate a sip call
line.rtp = new RTP();
line.rtp.init(this);
SDP sdp = new SDP();
SDP.Stream astream = sdp.addStream(SDP.Type.audio);
astream.port = line.rtp.getlocalrtpport();
astream.codecs = getCodecs();
// if (allowdups) {
int idx = number.indexOf(",");
if (idx != -1) {
number = number.substring(0, idx);
}
// }
return sip.invite(number, sdp);
}
public void markCalling(String number) {
String data[][];
//set status='calling' and increment attempts
String sel = (String)selected_list.getSelectedItem();
if (sel == null || sel.length() == 0) return;
int attempts = 0;
data = psql.select("select attempts from listdata where number = '" + number + "' and id=" + listid);
if (data == null) {
setStatus("select failed");
return;
}
if (data.length == 0) return;
attempts = Integer.valueOf(data[0][0]) + 1;
if (!psql.execute("update listdata set attempts = " + attempts + ", status = 'calling' where number = '" + number + "' and id=" + listid)) {
setStatus("update failed");
return;
}
//update local copy
int rc = listView.getRowCount();
for(int row=0;row<rc;row++) {
if (((String)listView.getValueAt(row, 0)).equals(number)) {
listView.setValueAt("calling", row, 1);
listView.setValueAt(new Integer(attempts), row, 2);
listView.repaint();
return;
}
}
}
public void unmarkCalling() {
String sel = (String)selected_list.getSelectedItem();
if (sel == null || sel.length() == 0) return;
if (!psql.execute("update lists set status = 'aborted', called = current_timestamp where status = 'calling' and id=" + listid)) {
setStatus("update failed");
return;
}
updateList();
}
public boolean anyStillCalling() {
String data[][];
String sel = (String)selected_list.getSelectedItem();
if (sel == null || sel.length() == 0) return false;
data = psql.select("select count(number) from listdata where status = 'calling' and id=" + listid);
if (data == null) {
setStatus("select failed");
return false;
}
if (data.length == 0) return false;
return !(data[0][0].equals("0"));
}
public void endCall(Lines line, String status) {
System.out.println("endCall:" + line.number + ":status=" + status);
line.talking = false;
line.rtp.stop();
line.rtp.uninit();
line.rtp = null;
line.callid = null;
line.noresponse = 0;
line.inuse = false;
updateList.add(new update(line.number, status, line.survey));
}
public void processUpdateList() {
String sel = (String)selected_list.getSelectedItem();
if (sel == null || sel.length() == 0) return;
update u;
while (updateList.size() > 0) {
u = updateList.remove(0);
if (!psql.execute("update listdata set status = '" + u.status + "', survey = '" + u.survey + "', called = current_timestamp where number = '" + u.number + "' and id=" + listid)) {
setStatus("endCall : update failed : " + u.number);
return;
}
String called = psql.select1value("select called from listdata where number = '" + u.number + "' and id=" + listid);
//update local copy
int rc = listView.getRowCount();
for(int row=0;row<rc;row++) {
if (((String)listView.getValueAt(row, 0)).equals(u.number)) {
listView.setValueAt(u.status, row, 1);
listView.setValueAt(u.survey, row, 3);
listView.setValueAt(called, row, 4);
listView.repaint();
break;
}
}
}
}
public void process() {
//20ms audio timer
byte encoded[];
if (processing) {
skipCount++;
setStatus("audio timer skipped : system too slow : reduce # of lines : skipCount=" + skipCount);
return;
}
processing = true;
try {
for(int a=0;a<lineCount;a++) {
if (!lines[a].inuse) continue;
if (!lines[a].talking) {
lines[a].ringwait++;
if (lines[a].ringwait == 50 * settings.maxRingTime) { //there are 50 process() per second
//waiting/ringing for too long (1min)
sip.cancel(lines[a].callid);
endCall(lines[a], "no_anwser");
}
continue;
}
if (lines[a].quietcount < maxquietcount) {
if (!lines[a].hello) {
//detect hello/answering machine
if (lines[a].rtp.getDefaultChannel().getSamples(tmp)) {
for(int p=0;p<160;p++) {
if (Math.abs(tmp[p]) > settings.greetingThreshold) {
lines[a].hello = true;
break;
}
}
}
} else {
//detect end of hello/answering machine beep
if (lines[a].rtp.getDefaultChannel().getSamples(tmp)) {
int avg = 0;
int peek = 0;
int val;
for(int p=0;p<160;p++) {
val = Math.abs(tmp[p]);
avg += val;
if (val > peek) peek = val;
}
avg /= 160;
if (avg > settings.silenceThreshold) {
lines[a].quietcount = 0;
if (lines[a].voicemail) continue;
if (isVoiceMailBeep(tmp, peek)) {
if (settings.voicemail_hangup) {
JFLog.log("voicemail detected (hangup) : " + lines[a].number);
sip.bye(lines[a].callid);
endCall(lines[a], "voicemail");
continue;
} else {
lines[a].voicemail = true;
}
}
} else {
if (lines[a].voicemail) {
//silence after voicemail beep detected
JFLog.log("voicemail detected : " + lines[a].number);
lines[a].quietcount = maxquietcount;
} else {
lines[a].quietcount++;
}
}
} else {
lines[a].quietcount++; //g729a silence suppression (evil)
}
}
encoded = lines[a].rtp.getDefaultChannel().coder.encode(silence);
lines[a].rtp.getDefaultChannel().writeRTP(encoded, 0, encoded.length);
} else {
if (lines[a].wavpos >= wav[lines[a].msgidx].samples.length) {
if (questions.action[lines[a].msgidx] == A_CONT) {
nextMessage(lines[a]);
continue;
}
if (questions.action[lines[a].msgidx] == A_GOTOIDX) {
lines[a].msgidx = questions.gotoidx[lines[a].msgidx] - 1 - 1;
nextMessage(lines[a]);
continue;
}
if (questions.action[lines[a].msgidx] == A_XFER) {
if (lines[a].xfered) continue; //already tried to xfer call
if (xfer_number.getText().length() == 0) continue; //no # to transfer to
sip.refer(lines[a].callid, xfer_number.getText());
lines[a].xfered = true;
continue;
}
lines[a].postwait += 160;
if (lines[a].postwait == 40000) { //5 seconds
if ((questions.action[lines[a].msgidx] == A_TERMINATE) || (questions.action[lines[a].msgidx] == A_XFER) || (lines[a].noresponse == 5)) {
sip.bye(lines[a].callid);
endCall(lines[a], "ok");
continue;
} else {
if (questions.action[lines[a].msgidx] == A_MULTI) {
if (lines[a].multi.length() > 0) {
lines[a].survey += "(" + lines[a].multi + ")";
nextMessage(lines[a]);
} else {
//repeat message
lines[a].repeat = true; //allow immediate response
lines[a].wavpos = 0;
lines[a].postwait = 0;
lines[a].multi = "";
lines[a].noresponse++;
}
} else if (questions.action[lines[a].msgidx] == A_GOTOUSER) {
//repeat message
lines[a].repeat = true; //allow immediate response
lines[a].wavpos = 0;
lines[a].postwait = 0;
lines[a].noresponse++;
}
}
}
encoded = lines[a].rtp.getDefaultChannel().coder.encode(silence);
lines[a].rtp.getDefaultChannel().writeRTP(encoded, 0, encoded.length);
} else {
encoded = lines[a].rtp.getDefaultChannel().coder.encode(Arrays.copyOfRange(wav[lines[a].msgidx].samples, lines[a].wavpos, lines[a].wavpos + 160));
lines[a].rtp.getDefaultChannel().writeRTP(encoded, 0, encoded.length);
lines[a].wavpos += 160;
}
}
}
} catch (Exception e) {
JFLog.log("process() exception:");
JFLog.log(e);
}
processing = false;
}
public void checkVersion() {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
new URL("http://jfbroadcast.sourceforge.net/version.php").openStream()));
String line = reader.readLine();
if (line.equals(version)) {JFLog.log("version is up-to-date"); return;}
JFLog.log("newer version is available : " + line);
JOptionPane.showMessageDialog(this,
"A newer version of jfbroadcast is available! (v" + line + ")\r\nPlease goto http://jfbroadcast.sourceforge.net to download it",
"Info",
JOptionPane.INFORMATION_MESSAGE);
} catch (Exception e) {
JFLog.log("error while checking for version update");
JFLog.log(e);
}
}
//SIPClientInterface
public void onRegister(SIPClient sip, boolean status) {
if (status) {
if (state != states.CALLING) return;
registered = true;
setStatus("calling");
} else {
if (state != states.CALLING) return;
setStatus("Error : register failed");
}
}
public void onTrying(SIPClient sip, String callid) {
if (state == states.STOPPED) return;
for(int a=0;a<lineCount;a++) {
if (!lines[a].inuse) continue;
if (!lines[a].callid.equals(callid)) continue;
JFLog.log("trying : " + lines[a].number);
}
}
public void onRinging(SIPClient sip, String callid) {
if (state == states.STOPPED) return;
for(int a=0;a<lineCount;a++) {
if (!lines[a].inuse) continue;
if (!lines[a].callid.equals(callid)) continue;
lines[a].ringing = true;
JFLog.log("ringing : " + lines[a].number);
}
}
public void onSuccess(SIPClient sip, String callid, SDP sdp, boolean complete) {
if (!complete) return; //not interested in 183 (ringback)
if (state == states.STOPPED) return;
SDP.Stream astream = sdp.getFirstAudioStream();
if (astream == null) return;
for(int a=0;a<lineCount;a++) {
if (!lines[a].inuse) continue;
if (!lines[a].callid.equals(callid)) continue;
if (!lines[a].talking) {
int cnt = 0;
if (astream.hasCodec(RTP.CODEC_G729a)) cnt++;
if (astream.hasCodec(RTP.CODEC_G711u)) cnt++;
if (astream.hasCodec(RTP.CODEC_G711a)) cnt++;
if ((cnt > 1) && (enable_reinvites.isSelected())) {
Codec codecs[] = new Codec[0];
//try to reinvite with one codec
if (astream.hasCodec(RTP.CODEC_G729a)) {
codecs = new Codec[] {RTP.CODEC_G729a};
}
else if (SIP.hasCodec(codecs, RTP.CODEC_G711u)) {
codecs = new Codec[] {RTP.CODEC_G711u};
}
else if (SIP.hasCodec(codecs, RTP.CODEC_G711a)) {
codecs = new Codec[] {RTP.CODEC_G711a};
}
SDP localsdp = new SDP();
SDP.Stream localStream = localsdp.addStream(SDP.Type.audio);
localStream.codecs = codecs;
localStream.port = lines[a].rtp.getlocalrtpport();
JFLog.log("reinvite:" + lines[a].number);
sip.reinvite(callid, localsdp);
return;
}
JFLog.log("connected : number=" + lines[a].number);
lines[a].rtp.start();
RTPChannel channel = lines[a].rtp.createChannel(astream);
if (channel == null) {
JFLog.log("Failed to create RTPChannel:" + lines[a].number);
return;
};
channel.start();
lines[a].ringing = false;
if (settings.disable_detect) {
lines[a].hello = true;
lines[a].quietcount = maxquietcount;
}
lines[a].talking = true;
return;
}
}
}
public void onBye(SIPClient sip, String callid) {
if (state == states.STOPPED) return;
for(int a=0;a<lineCount;a++ ){
if (!lines[a].inuse) continue;
if (lines[a].callid.equals(callid)) {
endCall(lines[a], "ok");
}
}
}
public int onInvite(SIPClient sip, String callid, String fromid, String fromnumber, SDP sdp) {
return 486; //busy
}
public void onCancel(SIPClient sip, String callid, int code) {
if (state == states.STOPPED) return;
for(int a=0;a<lineCount;a++ ){
if (!lines[a].inuse) continue;
if (lines[a].callid.equals(callid)) {
switch (code) {
case 486: endCall(lines[a], "busy"); break;
default: endCall(lines[a], "err_" + code); break;
}
}
}
}
public void onRefer(SIPClient sip, String callid) {
if (state == states.STOPPED) return;
for(int a=0;a<lineCount;a++ ){
if (!lines[a].inuse) continue;
if (lines[a].callid.equals(callid)) {
endCall(lines[a], "ok_xfered");
}
}
}
public void onNotify(SIPClient sip, String callid, String event, String content) {
}
public void onAck(SIPClient sip, String callid, SDP sdp) {
}
//RTPInterface
public void rtpSamples(RTPChannel rtp) {}
public void rtpDigit(RTPChannel channel, char c) {
if (state == states.STOPPED) return;
if (c == '*') return;
for(int a=0;a<lineCount;a++ ){
if (!lines[a].inuse) continue;
if (lines[a].rtp == channel.rtp) {
lines[a].noresponse = 0;
if ((enable_xfer.isSelected()) && (c == xfer_digit.getText().charAt(0))) {
if (lines[a].xfered) return; //already tried to xfer call
if (xfer_number.getText().length() == 0) return;
sip.refer(lines[a].callid, xfer_number.getText());
lines[a].xfered = true;
return;
}
if ((lines[a].wavpos < 8000 * 5) && (!lines[a].repeat)) {
return; //too soon (msg must play at least 5 sec before response is allowed)
}
switch (questions.action[lines[a].msgidx]) {
case A_TERMINATE:
break;
case A_SINGLE:
lines[a].survey += c;
nextMessage(lines[a]);
break;
case A_MULTI:
if (c == '#') {
lines[a].survey += "(" + lines[a].multi + ")";
nextMessage(lines[a]);
} else {
lines[a].multi += c;
}
lines[a].postwait = 0;
break;
case A_GOTOUSER:
if (c == '#') return; //bad input
if (c == '0') return; //bad input
int newidx = questions.gotouser[lines[a].msgidx][c - '0' - 1];
if ((newidx < 1) || (newidx > 99)) return; //bad input
lines[a].survey += c; //see bug # 2 @ jfbroadcast.sf.net
lines[a].msgidx = newidx - 1 - 1; //-1 for zero based, -1 for nextMessage()
nextMessage(lines[a]);
break;
}
}
}
}
public void rtpH263(RTPChannel rtp, byte[] bytes, int off, int len) {}
public void rtpH263_1998(RTPChannel rtp, byte[] bytes, int off, int len) {}
public void rtpH263_2000(RTPChannel rtp, byte[] bytes, int off, int len) {}
public void rtpH264(RTPChannel rtp, byte[] bytes, int off, int len) {}
public void rtpJPEG(RTPChannel rtp, byte[] bytes, int off, int len) {}
public void rtpVP8(RTPChannel rtp, byte[] bytes, int off, int len) {}
public void rtpInactive(RTPChannel rtp) {}
private void nextMessage(Lines line) {
line.wavpos = 0;
line.postwait = 0;
line.multi = "";
line.repeat = false;
while (true) {
if (line.msgidx == NUMQUESTIONS-1) {
sip.bye(line.callid);
endCall(line, "ok");
return;
}
line.msgidx++;
if (line.msgidx < 0) continue;
// System.out.println("nextMsg=" + line.msgidx);
if (questions.enabled[line.msgidx]) return;
}
}
public void rtpPacket(RTPChannel rtp, byte[] data,int pos,int len) {}
public void rtcpPacket(RTPChannel rtp, byte[] data,int pos,int len) {}
public static class Questions implements Serializable {
static final long serialVersionUID = 1000L;
boolean enabled[] = new boolean[NUMQUESTIONS];
String wav[] = new String[NUMQUESTIONS];
int action[] = new int[NUMQUESTIONS];
int count[] = new int[NUMQUESTIONS]; //# digits allowed for single entry
int gotouser[][] = new int[NUMQUESTIONS][9];
int gotoidx[] = new int[NUMQUESTIONS];
Questions() {
for(int a=0;a<NUMQUESTIONS;a++) {
enabled[a] = false;
wav[a] = new String();
action[a] = A_CONT;
count[a] = 0;
}
}
}
public static Questions questions = new Questions();
private int idx = 0;
public void selectFile() {
JFileChooser chooser = new JFileChooser();
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
chooser.setMultiSelectionEnabled(false);
chooser.setCurrentDirectory(new File(JF.getCurrentPath()));
if (chooser.showOpenDialog(this) != JFileChooser.APPROVE_OPTION) return;
wav_filename.setText(chooser.getSelectedFile().toString().replaceAll("\\\\", "/"));
}
private void prevQuestion() {
if (idx == 0) return;
saveQuestion();
idx--;
loadQuestion();
try { msg_idx.setValue(idx); } catch (Exception e) {System.out.println("" + e);}
}
private void nextQuestion() {
if (idx == NUMQUESTIONS-1) return;
saveQuestion();
idx++;
loadQuestion();
try { msg_idx.setValue(idx); } catch (Exception e) {System.out.println("" + e);}
}
private void gotoQuestion(int newidx) {
saveQuestion();
idx = newidx;
loadQuestion();
}
private void loadQuestion() {
title.setText("#" + (idx+1) + "/" + NUMQUESTIONS);
enable.setSelected(questions.enabled[idx]);
wav_filename.setText(questions.wav[idx]);
cont.setSelected(questions.action[idx] == A_CONT);
single.setSelected(questions.action[idx] == A_SINGLE);
multi.setSelected(questions.action[idx] == A_MULTI);
terminate.setSelected(questions.action[idx] == A_TERMINATE);
gotouser.setSelected(questions.action[idx] == A_GOTOUSER);
gotoidx.setSelected(questions.action[idx] == A_GOTOIDX);
xfer.setSelected(questions.action[idx] == A_XFER);
count.setSelectedIndex(questions.count[idx]);
goto_1.setText("" + questions.gotouser[idx][0]);
goto_2.setText("" + questions.gotouser[idx][1]);
goto_3.setText("" + questions.gotouser[idx][2]);
goto_4.setText("" + questions.gotouser[idx][3]);
goto_5.setText("" + questions.gotouser[idx][4]);
goto_6.setText("" + questions.gotouser[idx][5]);
goto_7.setText("" + questions.gotouser[idx][6]);
goto_8.setText("" + questions.gotouser[idx][7]);
goto_9.setText("" + questions.gotouser[idx][8]);
gotoidxnum.setText("" + questions.gotoidx[idx]);
}
private void saveQuestion() {
questions.enabled[idx] = enable.isSelected();
questions.wav[idx] = wav_filename.getText();
if (cont.isSelected()) questions.action[idx] = A_CONT;
if (single.isSelected()) questions.action[idx] = A_SINGLE;
if (multi.isSelected()) questions.action[idx] = A_MULTI;
if (terminate.isSelected()) questions.action[idx] = A_TERMINATE;
if (gotouser.isSelected()) questions.action[idx] = A_GOTOUSER;
if (gotoidx.isSelected()) questions.action[idx] = A_GOTOIDX;
if (xfer.isSelected()) questions.action[idx] = A_XFER;
questions.count[idx] = count.getSelectedIndex();
questions.gotouser[idx][0] = Math.min(Math.abs(JF.atoi(goto_1.getText())), 99);
questions.gotouser[idx][1] = Math.min(Math.abs(JF.atoi(goto_2.getText())), 99);
questions.gotouser[idx][2] = Math.min(Math.abs(JF.atoi(goto_3.getText())), 99);
questions.gotouser[idx][3] = Math.min(Math.abs(JF.atoi(goto_4.getText())), 99);
questions.gotouser[idx][4] = Math.min(Math.abs(JF.atoi(goto_5.getText())), 99);
questions.gotouser[idx][5] = Math.min(Math.abs(JF.atoi(goto_6.getText())), 99);
questions.gotouser[idx][6] = Math.min(Math.abs(JF.atoi(goto_7.getText())), 99);
questions.gotouser[idx][7] = Math.min(Math.abs(JF.atoi(goto_8.getText())), 99);
questions.gotouser[idx][8] = Math.min(Math.abs(JF.atoi(goto_9.getText())), 99);
questions.gotoidx[idx] = Math.min(Math.abs(JF.atoi(gotoidxnum.getText())), 99);
}
private void loadHelp(){
try {
InputStream is = getClass().getResourceAsStream("readme.txt");
int len = is.available();
byte txt[] = new byte[len];
is.read(txt);
help.setText(new String(txt,0,len));
help.setCaretPosition(0);
} catch (Exception e) { }
}
private void processArgs() {
if (args == null || args.length == 0) return;
for(int a=0;a<args.length;a++) {
if (args[a].equals("-start")) {
a++;
if (a == args.length) {
JFLog.log("Error:Must include list with -start option");
return;
}
startList = args[a];
}
else if (args[a].equals("-dbpath")) {
a++;
if (a == args.length) {
JFLog.log("Error:Must include path with -dbpath option");
return;
}
dbPath = args[a];
}
else if (args[a].equals("-cfgsuffix")) {
a++;
if (a == args.length) {
JFLog.log("Error:Must include string with -cfgsuffix option");
return;
}
cfgSuffix = args[a];
}
else if (args[a].equals("-allowdups")) {
allowdups = true;
}
}
}
private void setPosition() {
Dimension d = getSize();
Rectangle s = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds();
if ((d.width > s.width) || (d.height > s.height)) {
if (d.width > s.width) d.width = s.width;
if (d.height > s.height) d.height = s.height;
setSize(d);
}
setLocation(s.width/2 - d.width/2, s.height/2 - d.height/2);
}
public void actionPerformed(ActionEvent e) {
Object o = e.getSource();
if (o == exit) {
if (lockFile != null) {
lockFile.unlock();
}
System.exit(0);
}
if (o == show) {
if (isVisible()) {
if ((getExtendedState() & Frame.ICONIFIED) == Frame.ICONIFIED) {
setExtendedState(getExtendedState() ^ Frame.ICONIFIED);
}
requestFocus();
} else {
setVisible(true);
}
}
}
private void setOptsState() {
boolean state = human_vm_detect.isSelected();
greeting_threshold.setEnabled(state);
silence_threshold.setEnabled(state);
silence_duration.setEnabled(state);
voicemail_hangup.setEnabled(state);
}
//voicemail beep is 0.2 sec @ 987.8 Hz (B5 note)
//volume is around 7000 (16bit)
private boolean isVoiceMailBeep(short samples[], int peek) {
//basically check if wave moves up/down smoothly and maintains a
//relative constant volume
int dir = 0; //unknown
short last = samples[1];
if (peek < 2000) return false; //too quiet
if (peek > 30000) return false; //too loud
int pmax = peek + 1000;
int pmin = peek - 1000;
int nmax = -peek + 1000;
int nmin = -peek - 1000;
if (last > samples[0]) {
dir = 1;
} else {
dir = -1;
}
int wc = -1; //samples / wave count
for(int a=2;a<160;a++) {
short now = samples[a];
if (dir == 1) {
if (now < last) {
//hit a peek
if (wc != -1) {
if (last < pmin || last > pmax) {
// System.out.println("+last <> peek:" + last + "<" + pmin + ">" + pmax);
return false;
}
if (wc < 7 || wc > 9) {
// System.out.println("wc=" + wc);
return false;
} //Hz out of range
}
wc = 0; //start wave count
dir = -1;
}
} else {
if (now > last) {
//hit valley
if (wc != -1) {
if (last < nmin || last > nmax) {
// System.out.println("-last <> peek:" + last + "<" + nmin + ">" + nmax + ":wc=" + wc);
return false;
}
}
dir = 1;
}
}
if (wc != -1) wc++;
last = now;
}
return true;
}
public SystemTray tray;
public TrayIcon icon;
public MenuItem exit, show;
}