1 23 24 package org.gjt.sp.jedit; 25 26 import javax.swing.*; 28 import javax.swing.text.*; 29 import java.io.File ; 30 import java.io.IOException ; 31 import java.net.Socket ; 32 import java.util.*; 33 import org.gjt.sp.jedit.browser.VFSBrowser; 34 import org.gjt.sp.jedit.buffer.*; 35 import org.gjt.sp.jedit.io.*; 36 import org.gjt.sp.jedit.msg.*; 37 import org.gjt.sp.jedit.syntax.*; 38 import org.gjt.sp.jedit.textarea.*; 39 import org.gjt.sp.jedit.bufferio.BufferIORequest; 40 import org.gjt.sp.jedit.bufferio.BufferAutosaveRequest; 41 import org.gjt.sp.jedit.bufferio.MarkersSaveRequest; 42 import org.gjt.sp.util.*; 43 45 71 public class Buffer extends JEditBuffer 72 { 73 78 public static final String BACKED_UP = "Buffer__backedUp"; 79 80 84 public static final String CARET = "Buffer__caret"; 85 public static final String CARET_POSITIONED = "Buffer__caretPositioned"; 86 87 90 public static final String SELECTION = "Buffer__selection"; 91 92 97 public static final String SCROLL_VERT = "Buffer__scrollVert"; 98 public static final String SCROLL_HORIZ = "Buffer__scrollHoriz"; 99 100 104 public static final String ENCODING_AUTODETECT = "encodingAutodetect"; 105 106 110 public static final String TRAILING_EOL = "trailingEOL"; 111 112 116 public static final String GZIPPED = "gzipped"; 117 119 121 128 public void reload(View view) 129 { 130 if (getFlag(NEW_FILE)) 131 return; 132 if(isDirty()) 133 { 134 String [] args = { path }; 135 int result = GUIUtilities.confirm(view,"changedreload", 136 args,JOptionPane.YES_NO_OPTION, 137 JOptionPane.WARNING_MESSAGE); 138 if(result != JOptionPane.YES_OPTION) 139 return; 140 } 141 EditPane[] editPanes = view.getEditPanes(); 142 for (int i = 0; i < editPanes.length; i++) 143 editPanes[i].saveCaretInfo(); 144 load(view,true); 145 } 147 156 public boolean load(final View view, final boolean reload) 157 { 158 if(isPerformingIO()) 159 { 160 GUIUtilities.error(view,"buffer-multiple-io",null); 161 return false; 162 } 163 164 setBooleanProperty(BufferIORequest.ERROR_OCCURRED,false); 165 166 setLoading(true); 167 168 if(!getFlag(TEMPORARY)) 172 EditBus.send(new BufferUpdate(this,view,BufferUpdate.LOAD_STARTED)); 173 174 final boolean loadAutosave; 175 176 if(reload || !getFlag(NEW_FILE)) 177 { 178 if(file != null) 179 modTime = file.lastModified(); 180 181 if(!reload && autosaveFile != null && autosaveFile.exists()) 183 loadAutosave = recoverAutosave(view); 184 else 185 { 186 if(autosaveFile != null) 187 autosaveFile.delete(); 188 loadAutosave = false; 189 } 190 191 if(!loadAutosave) 192 { 193 VFS vfs = VFSManager.getVFSForPath(path); 194 195 if(!checkFileForLoad(view,vfs,path)) 196 { 197 setLoading(false); 198 return false; 199 } 200 201 if(reload || !getFlag(NEW_FILE)) 204 { 205 if(!vfs.load(view,this,path)) 206 { 207 setLoading(false); 208 return false; 209 } 210 } 211 } 212 } 213 else 214 loadAutosave = false; 215 216 Runnable runnable = new Runnable () 218 { 219 public void run() 220 { 221 String newPath = getStringProperty( 222 BufferIORequest.NEW_PATH); 223 Segment seg = (Segment)getProperty( 224 BufferIORequest.LOAD_DATA); 225 IntegerArray endOffsets = (IntegerArray) 226 getProperty(BufferIORequest.END_OFFSETS); 227 228 loadText(seg,endOffsets); 229 230 unsetProperty(BufferIORequest.LOAD_DATA); 231 unsetProperty(BufferIORequest.END_OFFSETS); 232 unsetProperty(BufferIORequest.NEW_PATH); 233 234 undoMgr.clear(); 235 undoMgr.setLimit(jEdit.getIntegerProperty( 236 "buffer.undoCount",100)); 237 238 if(!getFlag(TEMPORARY)) 239 finishLoading(); 240 241 setLoading(false); 242 243 if(reload) 245 setDirty(false); 246 247 if(!loadAutosave && newPath != null) 248 setPath(newPath); 249 250 253 if(loadAutosave) 260 Buffer.super.setDirty(true); 261 262 if(!getFlag(TEMPORARY)) 264 { 265 fireBufferLoaded(); 266 EditBus.send(new BufferUpdate(Buffer.this, 267 view,BufferUpdate.LOADED)); 268 } 271 } 272 }; 274 if(getFlag(TEMPORARY)) 275 runnable.run(); 276 else 277 VFSManager.runInAWTThread(runnable); 278 279 return true; 280 } 282 289 public boolean insertFile(View view, String path) 290 { 291 if(isPerformingIO()) 292 { 293 GUIUtilities.error(view,"buffer-multiple-io",null); 294 return false; 295 } 296 297 setBooleanProperty(BufferIORequest.ERROR_OCCURRED,false); 298 299 path = MiscUtilities.constructPath(this.path,path); 300 301 Buffer buffer = jEdit.getBuffer(path); 302 if(buffer != null) 303 { 304 view.getTextArea().setSelectedText( 305 buffer.getText(0,buffer.getLength())); 306 return true; 307 } 308 309 VFS vfs = VFSManager.getVFSForPath(path); 310 311 return vfs.insert(view,this,path); 315 } 317 321 public void autosave() 322 { 323 if(autosaveFile == null || !getFlag(AUTOSAVE_DIRTY) 324 || !isDirty() || isPerformingIO()) 325 return; 326 327 setFlag(AUTOSAVE_DIRTY,false); 328 329 VFSManager.runInWorkThread(new BufferAutosaveRequest( 330 null,this,null,VFSManager.getFileVFS(), 331 autosaveFile.getPath())); 332 } 334 342 public boolean saveAs(View view, boolean rename) 343 { 344 String [] files = GUIUtilities.showVFSFileDialog(view,path, 345 VFSBrowser.SAVE_DIALOG,false); 346 347 if(files == null) 350 return false; 351 352 return save(view,files[0],rename); 353 } 355 363 public boolean save(View view, String path) 364 { 365 return save(view,path,true); 366 } 368 379 public boolean save(final View view, String path, final boolean rename) 380 { 381 if(isPerformingIO()) 382 { 383 GUIUtilities.error(view,"buffer-multiple-io",null); 384 return false; 385 } 386 387 setBooleanProperty(BufferIORequest.ERROR_OCCURRED,false); 388 389 if(path == null && getFlag(NEW_FILE)) 390 return saveAs(view,rename); 391 392 if(path == null && file != null) 393 { 394 long newModTime = file.lastModified(); 395 396 if(newModTime != modTime 397 && jEdit.getBooleanProperty("view.checkModStatus")) 398 { 399 Object [] args = { this.path }; 400 int result = GUIUtilities.confirm(view, 401 "filechanged-save",args, 402 JOptionPane.YES_NO_OPTION, 403 JOptionPane.WARNING_MESSAGE); 404 if(result != JOptionPane.YES_OPTION) 405 return false; 406 } 407 } 408 409 EditBus.send(new BufferUpdate(this,view,BufferUpdate.SAVING)); 410 411 setPerformingIO(true); 412 413 final String oldPath = this.path; 414 final String oldSymlinkPath = symlinkPath; 415 final String newPath = path == null ? this.path : path; 416 417 VFS vfs = VFSManager.getVFSForPath(newPath); 418 419 if(!checkFileForSave(view,vfs,newPath)) 420 { 421 setPerformingIO(false); 422 return false; 423 } 424 425 Object session = vfs.createVFSSession(newPath,view); 426 if (session == null) 427 { 428 setPerformingIO(false); 429 return false; 430 } 431 432 unsetProperty("overwriteReadonly"); 433 unsetProperty("forbidTwoStageSave"); 434 try 435 { 436 VFSFile file = vfs._getFile(session,newPath,view); 437 if (file != null) 438 { 439 boolean vfsRenameCap = (vfs.getCapabilities() & VFS.RENAME_CAP) != 0; 440 if (!file.isWriteable()) 441 { 442 Log.log(Log.WARNING, this, "Buffer saving : File " + file + " is readOnly"); 443 if (vfsRenameCap) 444 { 445 Log.log(Log.DEBUG, this, "Buffer saving : VFS can rename files"); 446 String savePath = vfs._canonPath(session,newPath,view); 447 if(!MiscUtilities.isURL(savePath)) 448 savePath = MiscUtilities.resolveSymlinks(savePath); 449 savePath = vfs.getTwoStageSaveName(savePath); 450 if (savePath == null) 451 { 452 Log.log(Log.DEBUG, this, "Buffer saving : two stage save impossible because path is null"); 453 VFSManager.error(view, 454 newPath, 455 "ioerror.save-readonly-twostagefail", 456 null); 457 setPerformingIO(false); 458 return false; 459 } 460 else 461 { 462 int result = GUIUtilities.confirm( 463 view, "vfs.overwrite-readonly", 464 new Object []{newPath}, 465 JOptionPane.YES_NO_OPTION, 466 JOptionPane.WARNING_MESSAGE); 467 if (result == JOptionPane.YES_OPTION) 468 { 469 Log.log(Log.WARNING, this, "Buffer saving : two stage save will be used to save buffer"); 470 setBooleanProperty("overwriteReadonly",true); 471 } 472 else 473 { 474 Log.log(Log.DEBUG,this, "Buffer not saved"); 475 setPerformingIO(false); 476 return false; 477 } 478 } 479 } 480 else 481 { 482 Log.log(Log.WARNING, this, "Buffer saving : file is readonly and vfs cannot do two stage save"); 483 VFSManager.error(view, 484 newPath, 485 "ioerror.write-error-readonly", 486 null); 487 setPerformingIO(false); 488 return false; 489 } 490 } 491 else 492 { 493 String savePath = vfs._canonPath(session,newPath,view); 494 if(!MiscUtilities.isURL(savePath)) 495 savePath = MiscUtilities.resolveSymlinks(savePath); 496 savePath = vfs.getTwoStageSaveName(savePath); 497 if (jEdit.getBooleanProperty("twoStageSave") && (!vfsRenameCap || savePath == null)) 498 { 499 502 503 int result = GUIUtilities.confirm( 504 view, "vfs.twostageimpossible", 505 new Object []{newPath}, 506 JOptionPane.YES_NO_OPTION, 507 JOptionPane.WARNING_MESSAGE); 508 if (result == JOptionPane.YES_OPTION) 509 { 510 Log.log(Log.WARNING, this, "Buffer saving : two stage save cannot be used"); 511 setBooleanProperty("forbidTwoStageSave",true); 512 } 513 else 514 { 515 Log.log(Log.DEBUG,this, "Buffer not saved"); 516 setPerformingIO(false); 517 return false; 518 } 519 520 } 521 } 522 } 523 } 524 catch(IOException io) 525 { 526 VFSManager.error(view,newPath,"ioerror", 527 new String [] { io.toString() }); 528 setPerformingIO(false); 529 return false; 530 } 531 finally 532 { 533 try 534 { 535 vfs._endVFSSession(session,view); 536 } 537 catch(IOException io) 538 { 539 VFSManager.error(view,newPath,"ioerror", 540 new String [] { io.toString() }); 541 setPerformingIO(false); 542 return false; 543 } 544 } 545 546 if(!vfs.save(view,this,newPath)) 547 { 548 setPerformingIO(false); 549 return false; 550 } 551 552 VFSManager.runInAWTThread(new Runnable () 554 { 555 public void run() 556 { 557 setPerformingIO(false); 558 setProperty("overwriteReadonly",null); 559 finishSaving(view,oldPath,oldSymlinkPath, 560 newPath,rename,getBooleanProperty( 561 BufferIORequest.ERROR_OCCURRED)); 562 updateMarkersFile(view); 563 } 564 }); 565 566 return true; 567 } 569 public static final int FILE_NOT_CHANGED = 0; 571 public static final int FILE_CHANGED = 1; 572 public static final int FILE_DELETED = 2; 573 580 public int checkFileStatus(View view) 581 { 582 if(!isPerformingIO() && file != null && !getFlag(NEW_FILE)) 587 { 588 boolean newReadOnly = (file.exists() && !file.canWrite()); 589 if(newReadOnly != isFileReadOnly()) 590 { 591 setFileReadOnly(newReadOnly); 592 EditBus.send(new BufferUpdate(this,null, 593 BufferUpdate.DIRTY_CHANGED)); 594 } 595 596 long oldModTime = modTime; 597 long newModTime = file.lastModified(); 598 599 if(newModTime != oldModTime) 600 { 601 modTime = newModTime; 602 603 if(!file.exists()) 604 { 605 setFlag(NEW_FILE,true); 606 setDirty(true); 607 return FILE_DELETED; 608 } 609 else 610 { 611 return FILE_CHANGED; 612 } 613 } 614 } 615 616 return FILE_NOT_CHANGED; 617 } 619 621 623 628 public long getLastModified() 629 { 630 return modTime; 631 } 633 638 public void setLastModified(long modTime) 639 { 640 this.modTime = modTime; 641 } 643 648 public boolean getAutoReload() 649 { 650 return getFlag(AUTORELOAD); 651 } 653 658 public void setAutoReload(boolean value) 659 { 660 setFlag(AUTORELOAD, value); 661 } 663 669 public boolean getAutoReloadDialog() 670 { 671 return getFlag(AUTORELOAD_DIALOG); 672 } 674 681 public void setAutoReloadDialog(boolean value) 682 { 683 setFlag(AUTORELOAD_DIALOG, value); 684 } 686 691 public VFS getVFS() 692 { 693 return VFSManager.getVFSForPath(path); 694 } 696 701 public File getAutosaveFile() 702 { 703 return autosaveFile; 704 } 706 710 public String getName() 711 { 712 return name; 713 } 715 719 public String getPath() 720 { 721 return path; 722 } 724 730 public String getSymlinkPath() 731 { 732 return symlinkPath; 733 } 735 740 public String getDirectory() 741 { 742 return directory; 743 } 745 751 public boolean isClosed() 752 { 753 return getFlag(CLOSED); 754 } 756 760 public boolean isLoaded() 761 { 762 return !isLoading(); 763 } 765 770 public boolean isNewFile() 771 { 772 return getFlag(NEW_FILE); 773 } 775 780 public void setNewFile(boolean newFile) 781 { 782 setFlag(NEW_FILE,newFile); 783 if(!newFile) 784 setFlag(UNTITLED,false); 785 } 787 791 public boolean isUntitled() 792 { 793 return getFlag(UNTITLED); 794 } 796 800 public void setDirty(boolean d) 801 { 802 boolean old_d = isDirty(); 803 super.setDirty(d); 804 boolean editable = isEditable(); 805 806 if(d) 807 { 808 if(editable) 809 setFlag(AUTOSAVE_DIRTY,true); 810 } 811 else 812 { 813 setFlag(AUTOSAVE_DIRTY,false); 814 815 if(autosaveFile != null) 816 autosaveFile.delete(); 817 } 818 819 if(d != old_d && editable) 820 { 821 EditBus.send(new BufferUpdate(this,null, 822 BufferUpdate.DIRTY_CHANGED)); 823 } 824 } 826 833 public boolean isTemporary() 834 { 835 return getFlag(TEMPORARY); 836 } 838 843 public Icon getIcon() 844 { 845 if(isDirty()) 846 return GUIUtilities.loadIcon("dirty.gif"); 847 else if(isReadOnly()) 848 return GUIUtilities.loadIcon("readonly.gif"); 849 else if(getFlag(NEW_FILE)) 850 return GUIUtilities.loadIcon("new.gif"); 851 else 852 return GUIUtilities.loadIcon("normal.gif"); 853 } 855 857 859 863 public void addBufferChangeListener(BufferChangeListener listener, 864 int priority) 865 { 866 addBufferListener(new BufferChangeListener.Adapter(listener),priority); 867 } 869 873 public void addBufferChangeListener(BufferChangeListener listener) 874 { 875 addBufferChangeListener(listener,NORMAL_PRIORITY); 876 } 878 882 public void removeBufferChangeListener(BufferChangeListener listener) 883 { 884 BufferListener[] listeners = getBufferListeners(); 885 886 for(int i = 0; i < listeners.length; i++) 887 { 888 BufferListener l = listeners[i]; 889 if(l instanceof BufferChangeListener.Adapter) 890 { 891 if(((BufferChangeListener.Adapter)l).getDelegate() == listener) 892 { 893 removeBufferListener(l); 894 return; 895 } 896 } 897 } 898 } 900 902 904 910 public void propertiesChanged() 911 { 912 String folding = getStringProperty("folding"); 913 FoldHandler handler = FoldHandler.getFoldHandler(folding); 914 915 if(handler != null) 916 { 917 setFoldHandler(handler); 918 } 919 else 920 { 921 if (folding != null) 922 Log.log(Log.WARNING, this, path + ": invalid 'folding' property: " + folding); 923 setFoldHandler(new DummyFoldHandler()); 924 } 925 926 EditBus.send(new BufferUpdate(this,null,BufferUpdate.PROPERTIES_CHANGED)); 927 } 929 public Object getDefaultProperty(String name) 931 { 932 Object retVal; 933 934 if(mode != null) 935 { 936 retVal = mode.getProperty(name); 937 if(retVal == null) 938 return null; 939 940 setDefaultProperty(name,retVal); 941 return retVal; 942 } 943 String value = jEdit.getProperty("buffer." + name); 945 if(value == null) 946 return null; 947 948 try 950 { 951 retVal = new Integer (value); 952 } 953 catch(NumberFormatException nf) 954 { 955 retVal = value; 956 } 957 958 return retVal; 959 } 961 968 public void toggleWordWrap(View view) 969 { 970 String wrap = getStringProperty("wrap"); 971 if(wrap.equals("none")) 972 wrap = "soft"; 973 else if(wrap.equals("soft")) 974 wrap = "hard"; 975 else if(wrap.equals("hard")) 976 wrap = "none"; 977 view.getStatus().setMessageAndClear(jEdit.getProperty( 978 "view.status.wrap-changed",new String [] { 979 wrap })); 980 setProperty("wrap",wrap); 981 propertiesChanged(); 982 } 984 991 public void toggleLineSeparator(View view) 992 { 993 String status = null; 994 String lineSep = getStringProperty("lineSeparator"); 995 if("\n".equals(lineSep)) 996 { 997 status = "windows"; 998 lineSep = "\r\n"; 999 } 1000 else if("\r\n".equals(lineSep)) 1001 { 1002 status = "mac"; 1003 lineSep = "\r"; 1004 } 1005 else if("\r".equals(lineSep)) 1006 { 1007 status = "unix"; 1008 lineSep = "\n"; 1009 } 1010 view.getStatus().setMessageAndClear(jEdit.getProperty( 1011 "view.status.linesep-changed",new String [] { 1012 jEdit.getProperty("lineSep." + status) })); 1013 setProperty("lineSeparator",lineSep); 1014 setDirty(true); 1015 propertiesChanged(); 1016 } 1018 1027 public String getContextSensitiveProperty(int offset, String name) 1028 { 1029 Object value = super.getContextSensitiveProperty(offset,name); 1030 1031 if(value == null) 1032 { 1033 ParserRuleSet rules = getRuleSetAtOffset(offset); 1034 1035 value = jEdit.getMode(rules.getModeName()) 1036 .getProperty(name); 1037 1038 if(value == null) 1039 value = mode.getProperty(name); 1040 } 1041 1042 if(value == null) 1043 return null; 1044 else 1045 return String.valueOf(value); 1046 } 1048 1050 1052 1056 public Mode getMode() 1057 { 1058 return mode; 1059 } 1061 1069 public void setMode(String mode) 1070 { 1071 setMode(jEdit.getMode(mode)); 1072 } 1074 1081 public void setMode(Mode mode) 1082 { 1083 1085 if(mode == null) 1086 throw new NullPointerException ("Mode must be non-null"); 1087 1088 this.mode = mode; 1089 1090 textMode = "text".equals(mode.getName()); 1091 1092 setTokenMarker(mode.getTokenMarker()); 1093 1094 resetCachedProperties(); 1095 propertiesChanged(); 1096 } 1098 1103 public void setMode() 1104 { 1105 String userMode = getStringProperty("mode"); 1106 if(userMode != null) 1107 { 1108 Mode m = jEdit.getMode(userMode); 1109 if(m != null) 1110 { 1111 setMode(m); 1112 return; 1113 } 1114 } 1115 1116 String nogzName = name.substring(0,name.length() - 1117 (name.endsWith(".gz") ? 3 : 0)); 1118 Mode[] modes = jEdit.getModes(); 1119 1120 String firstLine = getLineText(0); 1121 1122 for(int i = modes.length - 1; i >= 0; i--) 1125 { 1126 if(modes[i].accept(nogzName,firstLine)) 1127 { 1128 setMode(modes[i]); 1129 return; 1130 } 1131 } 1132 1133 Mode defaultMode = jEdit.getMode(jEdit.getProperty("buffer.defaultMode")); 1134 if(defaultMode == null) 1135 defaultMode = jEdit.getMode("text"); 1136 setMode(defaultMode); 1137 } 1139 1141 1143 1147 public void putProperty(Object name, Object value) 1148 { 1149 if(!(name instanceof String )) 1151 return; 1152 1153 setProperty((String )name,value); 1154 } 1156 1160 public void putBooleanProperty(String name, boolean value) 1161 { 1162 setBooleanProperty(name,value); 1163 } 1165 1169 public static class TokenList extends DefaultTokenHandler 1170 { 1171 public Token getFirstToken() 1172 { 1173 return getTokens(); 1174 } 1175 } 1176 1177 1180 public TokenList markTokens(int lineIndex) 1181 { 1182 TokenList list = new TokenList(); 1183 markTokens(lineIndex,list); 1184 return list; 1185 } 1187 1191 public void insertString(int offset, String str, AttributeSet attr) 1192 { 1193 insert(offset,str); 1194 } 1196 1201 public File getFile() 1202 { 1203 return file; 1204 } 1206 1208 1210 1215 public Vector<Marker> getMarkers() 1216 { 1217 return markers; 1218 } 1220 1226 public String getMarkerStatusPrompt(String action) 1227 { 1228 return jEdit.getProperty("view.status." + action, 1229 new String [] { getMarkerNameString() }); 1230 } 1232 1238 public String getMarkerNameString() 1239 { 1240 StringBuilder buf = new StringBuilder (); 1241 for(int i = 0; i < markers.size(); i++) 1242 { 1243 Marker marker = markers.get(i); 1244 if(marker.getShortcut() != '\0') 1245 { 1246 if(buf.length() != 0) 1247 buf.append(' '); 1248 buf.append(marker.getShortcut()); 1249 } 1250 } 1251 1252 if(buf.length() == 0) 1253 return jEdit.getProperty("view.status.no-markers"); 1254 else 1255 return buf.toString(); 1256 } 1258 1266 public void addOrRemoveMarker(char shortcut, int pos) 1267 { 1268 int line = getLineOfOffset(pos); 1269 if(getMarkerAtLine(line) != null) 1270 removeMarker(line); 1271 else 1272 addMarker(shortcut,pos); 1273 } 1275 1282 public void addMarker(char shortcut, int pos) 1283 { 1284 Marker markerN = new Marker(this,shortcut,pos); 1285 boolean added = false; 1286 1287 if(isLoaded()) 1289 { 1290 setFlag(MARKERS_CHANGED,true); 1291 1292 markerN.createPosition(); 1293 1294 for(int i = 0; i < markers.size(); i++) 1295 { 1296 Marker marker = markers.get(i); 1297 if(shortcut != '\0' && marker.getShortcut() == shortcut) 1298 marker.setShortcut('\0'); 1299 1300 if(marker.getPosition() == pos) 1301 { 1302 markers.removeElementAt(i); 1303 i--; 1304 } 1305 } 1306 1307 for(int i = 0; i < markers.size(); i++) 1308 { 1309 Marker marker = markers.get(i); 1310 if(marker.getPosition() > pos) 1311 { 1312 markers.insertElementAt(markerN,i); 1313 added = true; 1314 break; 1315 } 1316 } 1317 } 1318 1319 if(!added) 1320 markers.addElement(markerN); 1321 1322 if(isLoaded() && !getFlag(TEMPORARY)) 1323 { 1324 EditBus.send(new BufferUpdate(this,null, 1325 BufferUpdate.MARKERS_CHANGED)); 1326 } 1327 } 1329 1336 public Marker getMarkerInRange(int start, int end) 1337 { 1338 for(int i = 0; i < markers.size(); i++) 1339 { 1340 Marker marker = markers.get(i); 1341 int pos = marker.getPosition(); 1342 if(pos >= start && pos < end) 1343 return marker; 1344 } 1345 1346 return null; 1347 } 1349 1356 public Marker getMarkerAtLine(int line) 1357 { 1358 for(int i = 0; i < markers.size(); i++) 1359 { 1360 Marker marker = markers.get(i); 1361 if(getLineOfOffset(marker.getPosition()) == line) 1362 return marker; 1363 } 1364 1365 return null; 1366 } 1368 1374 public void removeMarker(int line) 1375 { 1376 for(int i = 0; i < markers.size(); i++) 1377 { 1378 Marker marker = markers.get(i); 1379 if(getLineOfOffset(marker.getPosition()) == line) 1380 { 1381 setFlag(MARKERS_CHANGED,true); 1382 marker.removePosition(); 1383 markers.removeElementAt(i); 1384 i--; 1385 } 1386 } 1387 1388 EditBus.send(new BufferUpdate(this,null, 1389 BufferUpdate.MARKERS_CHANGED)); 1390 } 1392 1397 public void removeAllMarkers() 1398 { 1399 setFlag(MARKERS_CHANGED,true); 1400 1401 for(int i = 0; i < markers.size(); i++) 1402 markers.get(i).removePosition(); 1403 1404 markers.removeAllElements(); 1405 1406 if(isLoaded()) 1407 { 1408 EditBus.send(new BufferUpdate(this,null, 1409 BufferUpdate.MARKERS_CHANGED)); 1410 } 1411 } 1413 1419 public Marker getMarker(char shortcut) 1420 { 1421 Enumeration<Marker> e = markers.elements(); 1422 while(e.hasMoreElements()) 1423 { 1424 Marker marker = e.nextElement(); 1425 if(marker.getShortcut() == shortcut) 1426 return marker; 1427 } 1428 return null; 1429 } 1431 1437 public String getMarkersPath(VFS vfs) 1438 { 1439 return vfs.getParentOfPath(path) 1440 + '.' + vfs.getFileName(path) 1441 + ".marks"; 1442 } 1444 1452 public boolean updateMarkersFile(View view) 1453 { 1454 if(!markersChanged()) 1455 return true; 1456 VFS vfs = VFSManager.getVFSForPath(getPath()); 1458 if ((vfs.getCapabilities() & VFS.WRITE_CAP) == 0) { 1459 VFSManager.error(view, path, "vfs.not-supported.save", 1460 new String [] { "markers file" }); 1461 return false; 1462 } 1463 Object session = vfs.createVFSSession(path, view); 1464 if(session == null) 1465 return false; 1466 VFSManager.runInWorkThread( 1467 new MarkersSaveRequest( 1468 view, this, session, vfs, path)); 1469 return true; 1470 } 1472 1478 public boolean markersChanged() 1479 { 1480 return getFlag(MARKERS_CHANGED); 1481 } 1483 1488 public void setMarkersChanged(boolean changed) 1489 { 1490 setFlag(MARKERS_CHANGED, changed); 1491 } 1493 1495 1497 1501 public void setWaitSocket(Socket waitSocket) 1502 { 1503 this.waitSocket = waitSocket; 1504 } 1506 1510 public Buffer getNext() 1511 { 1512 return next; 1513 } 1515 1519 public Buffer getPrev() 1520 { 1521 return prev; 1522 } 1524 1528 public int getIndex() 1529 { 1530 int count = 0; 1531 Buffer buffer = prev; 1532 while (true) 1533 { 1534 if(buffer == null) 1535 break; 1536 count++; 1537 buffer = buffer.prev; 1538 } 1539 return count; 1540 } 1542 1547 public String toString() 1548 { 1549 return name + " (" + directory + ')'; 1550 } 1552 1554 1556 Buffer prev; 1557 1558 Buffer next; 1559 1560 Buffer(String path, boolean newFile, boolean temp, Hashtable props) 1562 { 1563 super(props); 1564 1565 markers = new Vector<Marker>(); 1566 1567 setFlag(TEMPORARY,temp); 1568 1569 setPath(path); 1571 1572 1587 setFlag(UNTITLED,newFile); 1588 setFlag(NEW_FILE,newFile); 1589 setFlag(AUTORELOAD,jEdit.getBooleanProperty("autoReload")); 1590 setFlag(AUTORELOAD_DIALOG,jEdit.getBooleanProperty("autoReloadDialog")); 1591 } 1593 void commitTemporary() 1595 { 1596 setFlag(TEMPORARY,false); 1597 1598 finishLoading(); 1599 } 1601 void close() 1603 { 1604 setFlag(CLOSED,true); 1605 1606 if(autosaveFile != null) 1607 autosaveFile.delete(); 1608 1609 if(waitSocket != null) 1611 { 1612 try 1613 { 1614 waitSocket.getOutputStream().write('\0'); 1615 waitSocket.getOutputStream().flush(); 1616 waitSocket.getInputStream().close(); 1617 waitSocket.getOutputStream().close(); 1618 waitSocket.close(); 1619 } 1620 catch(IOException io) 1621 { 1622 } 1624 } 1625 } 1627 1629 1631 1633 private void setFlag(int flag, boolean value) 1635 { 1636 if(value) 1637 flags |= (1 << flag); 1638 else 1639 flags &= ~(1 << flag); 1640 } 1642 private boolean getFlag(int flag) 1644 { 1645 int mask = (1 << flag); 1646 return (flags & mask) == mask; 1647 } 1649 private static final int CLOSED = 0; 1651 private static final int NEW_FILE = 3; 1652 private static final int UNTITLED = 4; 1653 private static final int AUTOSAVE_DIRTY = 5; 1654 private static final int AUTORELOAD = 6; 1655 private static final int AUTORELOAD_DIALOG = 7; 1656 private static final int TEMPORARY = 10; 1657 private static final int MARKERS_CHANGED = 12; 1658 1660 private int flags; 1661 1662 1664 private String path; 1666 private String symlinkPath; 1667 private String name; 1668 private String directory; 1669 private File file; 1670 private File autosaveFile; 1671 private long modTime; 1672 private Mode mode; 1673 1674 private final Vector<Marker> markers; 1675 1676 private Socket waitSocket; 1677 1679 private void setPath(String path) 1681 { 1682 View[] views = jEdit.getViews(); 1683 for (int i = 0; i < views.length; i++) 1684 { 1685 View view = views[i]; 1686 EditPane[] editPanes = view.getEditPanes(); 1687 for (int j = 0; j < editPanes.length; j++) 1688 editPanes[j].bufferRenamed(this.path, path); 1689 } 1690 1691 this.path = path; 1692 VFS vfs = VFSManager.getVFSForPath(path); 1693 if((vfs.getCapabilities() & VFS.WRITE_CAP) == 0) 1694 setFileReadOnly(true); 1695 name = vfs.getFileName(path); 1696 directory = vfs.getParentOfPath(path); 1697 1698 if(vfs instanceof FileVFS) 1699 { 1700 file = new File (path); 1701 symlinkPath = MiscUtilities.resolveSymlinks(path); 1702 1703 if(autosaveFile != null) 1706 autosaveFile.delete(); 1707 autosaveFile = new File (file.getParent(),'#' + name + '#'); 1708 } 1709 else 1710 { 1711 file = null; 1714 autosaveFile = null; 1715 symlinkPath = path; 1716 } 1717 } 1719 private boolean recoverAutosave(final View view) 1721 { 1722 if(!autosaveFile.canRead()) 1723 return false; 1724 1725 GUIUtilities.hideSplashScreen(); 1727 1728 final Object [] args = { autosaveFile.getPath() }; 1729 int result = GUIUtilities.confirm(view,"autosave-found",args, 1730 JOptionPane.YES_NO_OPTION,JOptionPane.WARNING_MESSAGE); 1731 1732 if(result == JOptionPane.YES_OPTION) 1733 { 1734 VFSManager.getFileVFS().load(view,this,autosaveFile.getPath()); 1735 1736 VFSManager.runInAWTThread(new Runnable () 1739 { 1740 public void run() 1741 { 1742 GUIUtilities.message(view,"autosave-loaded",args); 1743 } 1744 }); 1745 1746 return true; 1747 } 1748 else 1749 return false; 1750 } 1752 private boolean checkFileForLoad(View view, VFS vfs, String path) 1754 { 1755 if((vfs.getCapabilities() & VFS.LOW_LATENCY_CAP) != 0) 1756 { 1757 Object session = vfs.createVFSSession(path,view); 1758 if(session == null) 1759 return false; 1760 1761 try 1762 { 1763 VFSFile file = vfs._getFile(session,path,view); 1764 if(file == null) 1765 { 1766 setNewFile(true); 1767 return true; 1768 } 1769 1770 if(!file.isReadable()) 1771 { 1772 VFSManager.error(view,path,"ioerror.no-read",null); 1773 setNewFile(false); 1774 return false; 1775 } 1776 1777 setFileReadOnly(!file.isWriteable()); 1778 1779 if(file.getType() != VFSFile.FILE) 1780 { 1781 VFSManager.error(view,path, 1782 "ioerror.open-directory",null); 1783 setNewFile(false); 1784 return false; 1785 } 1786 } 1787 catch(IOException io) 1788 { 1789 VFSManager.error(view,path,"ioerror", 1790 new String [] { io.toString() }); 1791 return false; 1792 } 1793 finally 1794 { 1795 try 1796 { 1797 vfs._endVFSSession(session,view); 1798 } 1799 catch(IOException io) 1800 { 1801 VFSManager.error(view,path,"ioerror", 1802 new String [] { io.toString() }); 1803 return false; 1804 } 1805 } 1806 } 1807 1808 return true; 1809 } 1811 private static boolean checkFileForSave(View view, VFS vfs, String path) 1813 { 1814 if((vfs.getCapabilities() & VFS.LOW_LATENCY_CAP) != 0) 1815 { 1816 Object session = vfs.createVFSSession(path,view); 1817 if(session == null) 1818 return false; 1819 1820 try 1821 { 1822 VFSFile file = vfs._getFile(session,path,view); 1823 if(file == null) 1824 return true; 1825 1826 if(file.getType() != VFSFile.FILE) 1827 { 1828 VFSManager.error(view,path, 1829 "ioerror.save-directory",null); 1830 return false; 1831 } 1832 } 1833 catch(IOException io) 1834 { 1835 VFSManager.error(view,path,"ioerror", 1836 new String [] { io.toString() }); 1837 return false; 1838 } 1839 finally 1840 { 1841 try 1842 { 1843 vfs._endVFSSession(session,view); 1844 } 1845 catch(IOException io) 1846 { 1847 VFSManager.error(view,path,"ioerror", 1848 new String [] { io.toString() }); 1849 return false; 1850 } 1851 } 1852 } 1853 1854 return true; 1855 } 1857 private void finishLoading() 1859 { 1860 parseBufferLocalProperties(); 1861 FoldHandler oldFoldHandler = getFoldHandler(); 1864 setMode(); 1865 1866 if(getFoldHandler() == oldFoldHandler) 1867 { 1868 invalidateFoldLevels(); 1872 1873 fireFoldHandlerChanged(); 1874 } 1875 1876 for(int i = 0; i < markers.size(); i++) 1878 { 1879 Marker marker = markers.get(i); 1880 marker.removePosition(); 1881 int pos = marker.getPosition(); 1882 if(pos > getLength()) 1883 marker.setPosition(getLength()); 1884 else if(pos < 0) 1885 marker.setPosition(0); 1886 marker.createPosition(); 1887 } 1888 } 1890 private void finishSaving(View view, String oldPath, 1892 String oldSymlinkPath, String path, 1893 boolean rename, boolean error) 1894 { 1895 if(!error && !path.equals(oldPath)) 1899 { 1900 Buffer buffer = jEdit.getBuffer(path); 1901 1902 if(rename) 1903 { 1904 1909 if(buffer != null && 1910 !buffer.getPath().equals(oldPath)) 1911 { 1912 buffer.setDirty(false); 1913 jEdit.closeBuffer(view,buffer); 1914 } 1915 1916 setPath(path); 1917 } 1918 else 1919 { 1920 1923 if(buffer != null && 1924 !buffer.getPath().equals(oldPath)) 1925 { 1926 buffer.load(view,true); 1927 } 1928 } 1929 } 1931 if(rename) 1933 { 1934 if(file != null) 1935 modTime = file.lastModified(); 1936 1937 if(!error) 1938 { 1939 try 1945 { 1946 writeLock(); 1947 1948 if(autosaveFile != null) 1949 autosaveFile.delete(); 1950 1951 setFlag(AUTOSAVE_DIRTY,false); 1952 setFileReadOnly(false); 1953 setFlag(NEW_FILE,false); 1954 setFlag(UNTITLED,false); 1955 super.setDirty(false); 1956 1957 undoMgr.bufferSaved(); 1961 } 1962 finally 1963 { 1964 writeUnlock(); 1965 } 1966 1967 parseBufferLocalProperties(); 1968 1969 if(!getPath().equals(oldPath)) 1970 { 1971 jEdit.updatePosition(oldSymlinkPath,this); 1972 setMode(); 1973 } 1974 else 1975 { 1976 String newMode = getStringProperty("mode"); 1978 if(newMode != null && 1979 !newMode.equals(getMode() 1980 .getName())) 1981 setMode(); 1982 else 1983 propertiesChanged(); 1984 } 1985 1986 EditBus.send(new BufferUpdate(this, 1987 view,BufferUpdate.DIRTY_CHANGED)); 1988 1989 EditBus.send(new BufferUpdate(this, 1991 view,BufferUpdate.SAVED)); 1992 } 1993 } } 1996 } 1998 | Popular Tags |