1 /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. 2 * Copyright (C) 2011-2016 Brian P. Hinz 3 * 4 * This is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This software is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this software; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 17 * USA. 18 */ 19 20 package com.tigervnc.vncviewer; 21 22 import java.awt.*; 23 import java.awt.event.*; 24 import java.io.File; 25 import java.nio.CharBuffer; 26 import javax.swing.*; 27 import javax.swing.border.*; 28 import javax.swing.filechooser.*; 29 import javax.swing.WindowConstants.*; 30 import java.util.*; 31 32 import com.tigervnc.rfb.*; 33 34 import static java.awt.GridBagConstraints.HORIZONTAL; 35 import static java.awt.GridBagConstraints.LINE_START; 36 import static java.awt.GridBagConstraints.LINE_END; 37 import static java.awt.GridBagConstraints.NONE; 38 import static java.awt.GridBagConstraints.REMAINDER; 39 40 import static com.tigervnc.vncviewer.Parameters.*; 41 42 class ServerDialog extends Dialog implements Runnable { 43 44 @SuppressWarnings({"unchecked","rawtypes"}) ServerDialog(String defaultServerName, CharBuffer vncServerName)45 public ServerDialog(String defaultServerName, 46 CharBuffer vncServerName) { 47 super(true); 48 this.vncServerName = vncServerName; 49 setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); 50 setTitle("VNC Viewer: Connection Details"); 51 setResizable(false); 52 addWindowListener(new WindowAdapter() { 53 public void windowClosing(WindowEvent e) { 54 endDialog(); 55 System.exit(1); 56 } 57 }); 58 59 JLabel serverLabel = new JLabel("VNC server:", JLabel.RIGHT); 60 String valueStr = new String(defaultServerName); 61 ArrayList<String> servernames = new ArrayList<String>(); 62 if (!valueStr.isEmpty()) 63 servernames.add(valueStr); 64 String history = UserPreferences.get("ServerDialog", "history"); 65 if (history != null) { 66 for (String s : history.split(",")) { 67 if (servernames.indexOf(s) < 0) 68 servernames.add(s); 69 } 70 } 71 serverName = new MyJComboBox(servernames.toArray()); 72 serverName.addActionListener(new ActionListener() { 73 public void actionPerformed(ActionEvent e) { 74 JComboBox s = (JComboBox)e.getSource(); 75 if (e.getActionCommand().equals("comboBoxEdited")) { 76 s.insertItemAt(editor.getItem(), 0); 77 s.setSelectedIndex(0); 78 } 79 } 80 }); 81 if (servernames.size() == 0) 82 serverName.setPrototypeDisplayValue("255.255.255.255:5900"); 83 84 serverName.setEditable(true); 85 editor = serverName.getEditor(); 86 editor.getEditorComponent().addKeyListener(new KeyListener() { 87 public void keyTyped(KeyEvent e) {} 88 public void keyReleased(KeyEvent e) {} 89 public void keyPressed(KeyEvent e) { 90 if (KeyMap.get_keycode_fallback_extended(e) == KeyEvent.VK_ENTER) { 91 serverName.insertItemAt(editor.getItem(), 0); 92 serverName.setSelectedIndex(0); 93 handleConnect(); 94 } 95 } 96 }); 97 98 Container contentPane = this.getContentPane(); 99 contentPane.setLayout(new GridBagLayout()); 100 101 JLabel icon = new JLabel(VncViewer.logoIcon); 102 optionsButton = new JButton("Options..."); 103 optionsButton.addActionListener(new ActionListener() { 104 public void actionPerformed(ActionEvent e) { 105 handleOptions(); 106 } 107 }); 108 JButton loadButton = new JButton("Load..."); 109 loadButton.addActionListener(new ActionListener() { 110 public void actionPerformed(ActionEvent e) { 111 handleLoad(); 112 } 113 }); 114 JButton saveAsButton = new JButton("Save As..."); 115 saveAsButton.addActionListener(new ActionListener() { 116 public void actionPerformed(ActionEvent e) { 117 handleSaveAs(); 118 } 119 }); 120 aboutButton = new JButton("About..."); 121 aboutButton.addActionListener(new ActionListener() { 122 public void actionPerformed(ActionEvent e) { 123 handleAbout(); 124 } 125 }); 126 cancelButton = new JButton("Cancel"); 127 cancelButton.addActionListener(new ActionListener() { 128 public void actionPerformed(ActionEvent e) { 129 handleCancel(); 130 } 131 }); 132 connectButton = new JButton("Connect \u21B5"); 133 connectButton.addActionListener(new ActionListener() { 134 public void actionPerformed(ActionEvent e) { 135 handleConnect(); 136 } 137 }); 138 139 contentPane.add(icon, 140 new GridBagConstraints(0, 0, 141 1, 1, 142 LIGHT, LIGHT, 143 LINE_START, NONE, 144 new Insets(5, 5, 5, 5), 145 NONE, NONE)); 146 contentPane.add(serverLabel, 147 new GridBagConstraints(1, 0, 148 1, 1, 149 LIGHT, LIGHT, 150 LINE_START, NONE, 151 new Insets(5, 10, 5, 5), 152 NONE, NONE)); 153 contentPane.add(serverName, 154 new GridBagConstraints(2, 0, 155 REMAINDER, 1, 156 HEAVY, LIGHT, 157 LINE_START, HORIZONTAL, 158 new Insets(5, 0, 5, 5), 159 NONE, NONE)); 160 JPanel buttonPane1 = new JPanel(); 161 Box box = Box.createHorizontalBox(); 162 JSeparator separator1 = new JSeparator(); 163 JSeparator separator2 = new JSeparator(); 164 GroupLayout layout = new GroupLayout(buttonPane1); 165 buttonPane1.setLayout(layout); 166 layout.setAutoCreateGaps(false); 167 layout.setAutoCreateContainerGaps(false); 168 layout.setHorizontalGroup( 169 layout.createSequentialGroup() 170 .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) 171 .addGroup(layout.createSequentialGroup() 172 .addGap(10) 173 .addComponent(optionsButton)) 174 .addComponent(separator1) 175 .addGroup(layout.createSequentialGroup() 176 .addGap(10) 177 .addComponent(aboutButton))) 178 .addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING) 179 .addGroup(layout.createSequentialGroup() 180 .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) 181 .addComponent(loadButton) 182 .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) 183 .addComponent(saveAsButton) 184 .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) 185 .addComponent(box) 186 .addGap(10)) 187 .addComponent(separator2) 188 .addGroup(layout.createSequentialGroup() 189 .addComponent(cancelButton) 190 .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) 191 .addComponent(connectButton) 192 .addGap(10))) 193 ); 194 layout.setVerticalGroup( 195 layout.createSequentialGroup() 196 .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) 197 .addComponent(optionsButton) 198 .addComponent(loadButton) 199 .addComponent(saveAsButton) 200 .addComponent(box)) 201 .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) 202 .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) 203 .addComponent(separator1) 204 .addComponent(separator2)) 205 .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) 206 .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) 207 .addComponent(aboutButton) 208 .addComponent(cancelButton) 209 .addComponent(connectButton)) 210 .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) 211 ); 212 layout.linkSize(SwingConstants.HORIZONTAL, 213 optionsButton, loadButton, saveAsButton, 214 aboutButton, cancelButton, box); 215 contentPane.add(buttonPane1, 216 new GridBagConstraints(0, 1, 217 REMAINDER, 1, 218 LIGHT, LIGHT, 219 LINE_START, HORIZONTAL, 220 new Insets(5, 0, 10, 0), 221 NONE, NONE)); 222 pack(); 223 } 224 run()225 public void run() { 226 this.showDialog(); 227 } 228 handleOptions()229 private void handleOptions() { 230 // quirk for mac os x 231 if (VncViewer.os.startsWith("mac os x")) 232 this.setAlwaysOnTop(false); 233 OptionsDialog.showDialog(this); 234 } 235 handleLoad()236 private void handleLoad() { 237 String title = "Select a TigerVNC configuration file"; 238 File dflt = new File(FileUtils.getVncHomeDir().concat("default.tigervnc")); 239 FileNameExtensionFilter filter = 240 new FileNameExtensionFilter("TigerVNC configuration (*.tigervnc)", "tigervnc"); 241 File f = showChooser(title, dflt, filter); 242 if (f != null && f.exists() && f.canRead()) 243 loadViewerParameters(f.getAbsolutePath()); 244 } 245 handleSaveAs()246 private void handleSaveAs() { 247 String title = "Save the TigerVNC configuration to file"; 248 File dflt = new File(FileUtils.getVncHomeDir().concat("default.tigervnc")); 249 if (!dflt.exists() || !dflt.isFile()) 250 dflt = new File(FileUtils.getVncHomeDir()); 251 FileNameExtensionFilter filter = 252 new FileNameExtensionFilter("TigerVNC configuration (*.tigervnc)", "tigervnc"); 253 File f = showChooser(title, dflt, filter); 254 while (f != null && f.exists() && f.isFile()) { 255 String msg = f.getAbsolutePath(); 256 msg = msg.concat(" already exists. Do you want to overwrite?"); 257 Object[] options = {"Overwrite", "No \u21B5"}; 258 JOptionPane op = 259 new JOptionPane(msg, JOptionPane.QUESTION_MESSAGE, 260 JOptionPane.OK_CANCEL_OPTION, null, options, options[1]); 261 JDialog dlg = op.createDialog(this, "TigerVNC Viewer"); 262 dlg.setIconImage(VncViewer.frameIcon); 263 dlg.setAlwaysOnTop(true); 264 dlg.setVisible(true); 265 if (op.getValue() == options[0]) 266 break; 267 else 268 f = showChooser(title, f, filter); 269 } 270 if (f != null && (!f.exists() || f.canWrite())) 271 saveViewerParameters(f.getAbsolutePath(), (String)serverName.getSelectedItem()); 272 } 273 handleAbout()274 private void handleAbout() { 275 VncViewer.about_vncviewer(this); 276 } 277 handleCancel()278 private void handleCancel() { 279 endDialog(); 280 } 281 handleConnect()282 private void handleConnect() { 283 String servername = (String)serverName.getSelectedItem(); 284 servername.trim(); 285 vncServerName.put(servername).flip(); 286 saveViewerParameters(null, servername); 287 endDialog(); 288 } 289 290 @SuppressWarnings("rawtypes") 291 MyJComboBox serverName; 292 ComboBoxEditor editor; 293 JButton aboutButton, optionsButton, connectButton, cancelButton; 294 OptionsDialog options; 295 CharBuffer vncServerName; 296 static LogWriter vlog = new LogWriter("ServerDialog"); 297 298 } 299