1 21 22 package org.armedbear.j; 23 24 import java.awt.BorderLayout ; 25 import java.awt.event.FocusEvent ; 26 import java.awt.event.FocusListener ; 27 import java.awt.event.InputEvent ; 28 import java.awt.event.KeyEvent ; 29 import java.awt.event.KeyListener ; 30 import java.util.Vector ; 31 import javax.swing.BoxLayout ; 32 import javax.swing.JDialog ; 33 import javax.swing.JLabel ; 34 import javax.swing.JPanel ; 35 import javax.swing.border.EmptyBorder ; 36 37 public class SaveFileDialog extends JDialog implements FocusListener , KeyListener 38 { 39 private File destination; 40 41 protected final Editor editor; 42 protected final String title; 43 protected String defaultName; 44 protected HistoryTextField textField; 45 protected History history; 46 47 private final String prompt; 48 private Vector completions; 49 private int index; 50 private boolean completionsIgnoreCase; 51 private boolean allowDirectory; 52 private boolean confirmOverwrite = true; 53 54 public SaveFileDialog(Editor editor, String title) 55 { 56 super(editor.getFrame(), title, true); 57 this.editor = editor; 58 this.title = title; 59 prompt = "File:"; 60 init(); 61 } 62 63 public SaveFileDialog(Editor editor, String title, String prompt) 64 { 65 super(editor.getFrame(), title, true); 66 this.editor = editor; 67 this.title = title; 68 this.prompt = prompt; 69 init(); 70 } 71 72 public SaveFileDialog(Editor editor, String title, String prompt, String defaultName) 73 { 74 super(editor.getFrame(), title, true); 75 this.editor = editor; 76 this.title = title; 77 this.prompt = prompt; 78 this.defaultName = defaultName; 79 init(); 80 } 81 82 public final File getDestination() 83 { 84 return destination; 85 } 86 87 public final void setAllowDirectory(boolean b) 88 { 89 allowDirectory = b; 90 } 91 92 public final void setConfirmOverwrite(boolean b) 93 { 94 confirmOverwrite = b; 95 } 96 97 public final void setInitialText(String s) 98 { 99 textField.setText(s); 100 } 101 102 private void init() 103 { 104 if (Platform.isPlatformWindows()) 105 completionsIgnoreCase = true; 106 else 107 completionsIgnoreCase = Editor.preferences().getBooleanProperty(Property.FILENAME_COMPLETIONS_IGNORE_CASE); 108 JPanel panel = new JPanel (); 109 panel.setLayout(new BoxLayout (panel, BoxLayout.Y_AXIS)); 110 panel.setBorder(new EmptyBorder (5, 5, 5, 5)); 111 panel.add(new Label(prompt)); 112 textField = new HistoryTextField(20); 113 history = new History("saveFile.file"); 114 textField.setHistory(history); 115 if (defaultName != null && defaultName.length() > 0) { 116 File directory = editor.getCurrentDirectory(); 117 if (directory == null || directory.isRemote()) 118 directory = Directories.getUserHomeDirectory(); 119 File file = File.getInstance(directory, defaultName); 120 if (file != null) 121 textField.setText(file.canonicalPath()); 122 } 123 panel.add(textField); 124 getContentPane().add(panel, BorderLayout.CENTER); 125 pack(); 126 textField.setFocusTraversalKeysEnabled(false); 127 addFocusListener(this); 128 addKeyListener(this); 129 textField.addKeyListener(this); 130 textField.requestFocus(); 131 textField.selectAll(); 132 } 133 134 public void focusGained(FocusEvent e) 135 { 136 textField.requestFocus(); 137 } 138 139 public void focusLost(FocusEvent e) 140 { 141 } 142 143 public void keyPressed(KeyEvent e) 144 { 145 int keyCode = e.getKeyCode(); 146 int modifiers = e.getModifiers(); 147 switch (keyCode) { 148 case KeyEvent.VK_TAB: { 149 String s = null; 150 String entry = textField.getText(); 151 if (modifiers == InputEvent.SHIFT_MASK) 152 s = previousGuess(); 153 else { 154 File dir = editor.getCurrentDirectory(); 155 if (dir != null && !dir.isRemote()) { 156 File file = File.getInstance(dir, entry); 157 if (file != null) 158 s = guess(file.canonicalPath()); 159 } 160 } 161 e.consume(); 162 if (s != null) { 163 textField.setText(s); 164 textField.setCaretPosition(s.length()); 165 } 166 return; 167 } 168 case KeyEvent.VK_ENTER: 169 e.consume(); 170 enter(); 171 return; 172 case KeyEvent.VK_ESCAPE: 173 e.consume(); 174 destination = null; 175 dispose(); 176 return; 177 case KeyEvent.VK_SHIFT: 179 case KeyEvent.VK_CONTROL: 180 case KeyEvent.VK_ALT: 181 case KeyEvent.VK_META: 182 return; 183 default: 185 completions = null; 186 return; 187 } 188 } 189 190 public void keyReleased(KeyEvent e) 191 { 192 } 193 194 public void keyTyped(KeyEvent e) 195 { 196 } 197 198 protected void enter() 199 { 200 final String entry = textField.getText().trim(); 201 if (entry.length() == 0) { 202 destination = null; 203 dispose(); 204 return; 205 } 206 File file; 207 if (Utilities.isFilenameAbsolute(entry)) { 208 file = File.getInstance(entry); 209 } else { 210 File directory = editor.getCurrentDirectory(); 211 if (directory == null || directory.isRemote()) 212 directory = Directories.getUserHomeDirectory(); 213 file = File.getInstance(directory, entry); 214 } 215 if (file == null) { 216 dispose(); 217 return; 218 } 219 if (file.isRemote()) { 220 destination = file; 221 } else { 222 if (file.isDirectory()) { 223 if (defaultName != null) 224 file = File.getInstance(file, defaultName); 225 if (file.isDirectory() && !allowDirectory) { 226 String message = file.canonicalPath() + " is a directory"; 227 MessageDialog.showMessageDialog(editor, message, title); 228 requestFocus(); 229 return; 230 } 231 } 232 if (file.isFile()) { 233 if (file.canWrite()) { 234 String message = "Overwrite existing file " + file.canonicalPath() + "?"; 235 if (!confirmOverwrite || editor.confirm(title, message)) { 236 destination = file; 237 history.append(file.canonicalPath()); 238 history.save(); 239 dispose(); 240 } 241 return; 242 } else { 243 String message = file.canonicalPath() + " is read only"; 245 MessageDialog.showMessageDialog(editor, message, title); 246 return; 247 } 248 } 249 File parentDir = file.isDirectory() ? file : file.getParentFile(); 252 if (parentDir == null || !parentDir.isDirectory()) { 253 String message = "Invalid path"; 254 MessageDialog.showMessageDialog(editor, message, title); 255 requestFocus(); 256 return; 257 } 258 if (!Utilities.isDirectoryWritable(parentDir)) { 260 String message = "Directory " + parentDir.canonicalPath() + " is not writable"; 261 MessageDialog.showMessageDialog(editor, message, title); 262 requestFocus(); 263 return; 264 } 265 destination = file; 266 } 267 history.append(destination.netPath()); 268 history.save(); 269 dispose(); 270 } 271 272 private String guess(String prefix) 273 { 274 if (completions != null) { 275 if (index < completions.size()) 276 return (String ) completions.get(index++); 277 index = 0; 278 if (index < completions.size()) 279 return (String ) completions.get(index++); 280 return null; 281 } 282 completions = getCompletions(prefix); 283 index = 0; 284 if (completions.size() > 0) 285 return (String ) completions.get(index++); 286 return null; 287 } 288 289 private String previousGuess() 290 { 291 if (completions != null) { 292 if (completions.size() > 1){ 293 index -= 2; 294 if (index < 0) 295 index += completions.size(); 296 return (String ) completions.get(index++); 297 } 298 } 299 return null; 300 } 301 302 private Vector getCompletions(String prefix) 303 { 304 Vector v = new Vector (); 305 File currentDir = editor.getCurrentDirectory(); 306 File dir = null; 307 boolean isShortName = false; 308 if (Utilities.isFilenameAbsolute(prefix) || 309 prefix.indexOf(LocalFile.getSeparatorChar()) >= 0) { 310 File f = File.getInstance(currentDir, prefix); 311 dir = f.getParentFile(); 312 prefix = f.getName(); 313 } else { 314 dir = currentDir; 315 isShortName = true; 316 } 317 String [] names = dir.list(); 318 if (names != null) { 319 for (int i = 0; i < names.length; i++) { 320 boolean matches = false; 321 if (completionsIgnoreCase) 322 matches = names[i].regionMatches(true, 0, prefix, 0, prefix.length()); 323 else 324 matches = names[i].startsWith(prefix); 325 if (matches) { 326 File file = File.getInstance(dir, names[i]); 327 String name = dir == currentDir ? file.getName() : file.getAbsolutePath(); 328 if (file.isDirectory()) { 329 v.add(name + LocalFile.getSeparator()); 330 continue; 331 } 332 v.add(name); 333 } 334 } 335 } 336 return v; 337 } 338 339 public void dispose() 340 { 341 super.dispose(); 342 editor.restoreFocus(); 343 } 344 345 public static File getSaveFile(Editor editor, String dialogTitle) 346 { 347 final File file = editor.getBuffer().getFile(); 348 final String defaultName = file != null ? file.getName() : null; 349 SaveFileDialog d = 350 new SaveFileDialog(editor, dialogTitle, "File:", defaultName); 351 editor.centerDialog(d); 352 d.show(); 353 return d.getDestination(); 354 } 355 356 public static void writeGlobalKeyMap() 357 { 358 final Editor editor = Editor.currentEditor(); 359 SaveFileDialog d = new SaveFileDialog(editor, "Write Global Key Map"); 360 editor.centerDialog(d); 361 d.show(); 362 File file = d.getDestination(); 363 if (file != null) 364 KeyMap.getGlobalKeyMap().writeKeyMap(file); 365 } 366 367 public static void writeLocalKeyMap() 368 { 369 final Editor editor = Editor.currentEditor(); 370 SaveFileDialog d = new SaveFileDialog(editor, "Write Local Key Map"); 371 editor.centerDialog(d); 372 d.show(); 373 File file = d.getDestination(); 374 if (file != null) 375 editor.getBuffer().getKeyMapForMode().writeKeyMap(file); 376 } 377 } 378 | Popular Tags |