Source Code Cross Referenced for Buffer.java in  » Swing-Library » jEdit » org » gjt » sp » jedit » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Swing Library » jEdit » org.gjt.sp.jedit 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Buffer.java - jEdit buffer
0003:         * :tabSize=8:indentSize=8:noTabs=false:
0004:         * :folding=explicit:collapseFolds=1:
0005:         *
0006:         * Copyright (C) 1998, 2005 Slava Pestov
0007:         * Portions copyright (C) 1999, 2000 mike dillon
0008:         *
0009:         * This program is free software; you can redistribute it and/or
0010:         * modify it under the terms of the GNU General Public License
0011:         * as published by the Free Software Foundation; either version 2
0012:         * of the License, or any later version.
0013:         *
0014:         * This program is distributed in the hope that it will be useful,
0015:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0016:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0017:         * GNU General Public License for more details.
0018:         *
0019:         * You should have received a copy of the GNU General Public License
0020:         * along with this program; if not, write to the Free Software
0021:         * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
0022:         */
0023:
0024:        package org.gjt.sp.jedit;
0025:
0026:        //{{{ Imports
0027:
0028:        import org.gjt.sp.jedit.browser.VFSBrowser;
0029:        import org.gjt.sp.jedit.buffer.*;
0030:        import org.gjt.sp.jedit.bufferio.BufferAutosaveRequest;
0031:        import org.gjt.sp.jedit.bufferio.BufferIORequest;
0032:        import org.gjt.sp.jedit.bufferio.MarkersSaveRequest;
0033:        import org.gjt.sp.jedit.gui.StyleEditor;
0034:        import org.gjt.sp.jedit.io.FileVFS;
0035:        import org.gjt.sp.jedit.io.VFS;
0036:        import org.gjt.sp.jedit.io.VFSFile;
0037:        import org.gjt.sp.jedit.io.VFSManager;
0038:        import org.gjt.sp.jedit.msg.BufferUpdate;
0039:        import org.gjt.sp.jedit.syntax.*;
0040:        import org.gjt.sp.jedit.textarea.JEditTextArea;
0041:        import org.gjt.sp.jedit.textarea.Selection;
0042:        import org.gjt.sp.util.IntegerArray;
0043:        import org.gjt.sp.util.Log;
0044:
0045:        import javax.swing.*;
0046:        import javax.swing.text.AttributeSet;
0047:        import javax.swing.text.Segment;
0048:        import java.io.File;
0049:        import java.io.IOException;
0050:        import java.net.Socket;
0051:        import java.util.Enumeration;
0052:        import java.util.Hashtable;
0053:        import java.util.Vector;
0054:
0055:        //}}}
0056:
0057:        /**
0058:         * A <code>Buffer</code> represents the contents of an open text
0059:         * file as it is maintained in the computer's memory (as opposed to
0060:         * how it may be stored on a disk).<p>
0061:         *
0062:         * In a BeanShell script, you can obtain the current buffer instance from the
0063:         * <code>buffer</code> variable.<p>
0064:         *
0065:         * This class does not have a public constructor.
0066:         * Buffers can be opened and closed using methods in the <code>jEdit</code>
0067:         * class.<p>
0068:         *
0069:         * This class is partially thread-safe, however you must pay attention to two
0070:         * very important guidelines:
0071:         * <ul>
0072:         * <li>Changes to a buffer can only be made from the AWT thread.
0073:         * <li>When accessing the buffer from another thread, you must
0074:         * grab a read lock if you plan on performing more than one call, to ensure that
0075:         * the buffer contents are not changed by the AWT thread for the duration of the
0076:         * lock. Only methods whose descriptions specify thread safety can be invoked
0077:         * from other threads.
0078:         * </ul>
0079:         *
0080:         * @author Slava Pestov
0081:         * @version $Id: Buffer.java 11199 2007-12-06 18:39:23Z k_satoda $
0082:         */
0083:        public class Buffer extends JEditBuffer {
0084:            //{{{ Some constants
0085:            /**
0086:             * Backed up property.
0087:             * @since jEdit 3.2pre2
0088:             */
0089:            public static final String BACKED_UP = "Buffer__backedUp";
0090:
0091:            /**
0092:             * Caret info properties.
0093:             * @since jEdit 3.2pre1
0094:             */
0095:            public static final String CARET = "Buffer__caret";
0096:            public static final String CARET_POSITIONED = "Buffer__caretPositioned";
0097:
0098:            /**
0099:             * Stores a List of {@link Selection} instances.
0100:             */
0101:            public static final String SELECTION = "Buffer__selection";
0102:
0103:            /**
0104:             * This should be a physical line number, so that the scroll
0105:             * position is preserved correctly across reloads (which will
0106:             * affect virtual line numbers, due to fold being reset)
0107:             */
0108:            public static final String SCROLL_VERT = "Buffer__scrollVert";
0109:            public static final String SCROLL_HORIZ = "Buffer__scrollHoriz";
0110:
0111:            /**
0112:             * Should jEdit try to set the encoding based on a UTF8, UTF16 or
0113:             * XML signature at the beginning of the file?
0114:             */
0115:            public static final String ENCODING_AUTODETECT = "encodingAutodetect";
0116:
0117:            /**
0118:             * This property is set to 'true' if the file has a trailing newline.
0119:             * @since jEdit 4.0pre1
0120:             */
0121:            public static final String TRAILING_EOL = "trailingEOL";
0122:
0123:            /**
0124:             * This property is set to 'true' if the file should be GZipped.
0125:             * @since jEdit 4.0pre4
0126:             */
0127:            public static final String GZIPPED = "gzipped";
0128:
0129:            //}}}
0130:
0131:            //{{{ Input/output methods
0132:
0133:            //{{{ reload() method
0134:            /**
0135:             * Reloads the buffer from disk, asking for confirmation if the buffer
0136:             * has unsaved changes.
0137:             * @param view The view
0138:             * @since jEdit 2.7pre2
0139:             */
0140:            public void reload(View view) {
0141:                if (getFlag(UNTITLED))
0142:                    return;
0143:                if (isDirty()) {
0144:                    String[] args = { path };
0145:                    int result = GUIUtilities.confirm(view, "changedreload",
0146:                            args, JOptionPane.YES_NO_OPTION,
0147:                            JOptionPane.WARNING_MESSAGE);
0148:                    if (result != JOptionPane.YES_OPTION)
0149:                        return;
0150:                }
0151:                EditPane[] editPanes = view.getEditPanes();
0152:                for (int i = 0; i < editPanes.length; i++)
0153:                    editPanes[i].saveCaretInfo();
0154:                load(view, true);
0155:            } //}}}
0156:
0157:            //{{{ load() method
0158:            /**
0159:             * Loads the buffer from disk.
0160:             * @param view The view
0161:             * @param reload If true, user will not be asked to recover autosave
0162:             * file, if any
0163:             *
0164:             * @since 2.5pre1
0165:             */
0166:            public boolean load(final View view, final boolean reload) {
0167:                if (isPerformingIO()) {
0168:                    GUIUtilities.error(view, "buffer-multiple-io", null);
0169:                    return false;
0170:                }
0171:
0172:                setBooleanProperty(BufferIORequest.ERROR_OCCURRED, false);
0173:
0174:                setLoading(true);
0175:
0176:                // view text areas temporarily blank out while a buffer is
0177:                // being loaded, to indicate to the user that there is no
0178:                // data available yet.
0179:                if (!getFlag(TEMPORARY))
0180:                    EditBus.send(new BufferUpdate(this , view,
0181:                            BufferUpdate.LOAD_STARTED));
0182:
0183:                final boolean loadAutosave;
0184:
0185:                if (reload || !getFlag(NEW_FILE)) {
0186:                    if (file != null)
0187:                        modTime = file.lastModified();
0188:
0189:                    // Only on initial load
0190:                    if (!reload && autosaveFile != null
0191:                            && autosaveFile.exists())
0192:                        loadAutosave = recoverAutosave(view);
0193:                    else {
0194:                        if (autosaveFile != null)
0195:                            autosaveFile.delete();
0196:                        loadAutosave = false;
0197:                    }
0198:
0199:                    if (!loadAutosave) {
0200:                        VFS vfs = VFSManager.getVFSForPath(path);
0201:
0202:                        if (!checkFileForLoad(view, vfs, path)) {
0203:                            setLoading(false);
0204:                            return false;
0205:                        }
0206:
0207:                        // have to check again since above might set
0208:                        // NEW_FILE flag
0209:                        if (reload || !getFlag(NEW_FILE)) {
0210:                            if (!vfs.load(view, this , path)) {
0211:                                setLoading(false);
0212:                                return false;
0213:                            }
0214:                        }
0215:                    }
0216:                } else
0217:                    loadAutosave = false;
0218:
0219:                //{{{ Do some stuff once loading is finished
0220:                Runnable runnable = new Runnable() {
0221:                    public void run() {
0222:                        String newPath = getStringProperty(BufferIORequest.NEW_PATH);
0223:                        Segment seg = (Segment) getProperty(BufferIORequest.LOAD_DATA);
0224:                        IntegerArray endOffsets = (IntegerArray) getProperty(BufferIORequest.END_OFFSETS);
0225:
0226:                        loadText(seg, endOffsets);
0227:
0228:                        unsetProperty(BufferIORequest.LOAD_DATA);
0229:                        unsetProperty(BufferIORequest.END_OFFSETS);
0230:                        unsetProperty(BufferIORequest.NEW_PATH);
0231:
0232:                        undoMgr.clear();
0233:                        undoMgr.setLimit(jEdit.getIntegerProperty(
0234:                                "buffer.undoCount", 100));
0235:
0236:                        if (!getFlag(TEMPORARY))
0237:                            finishLoading();
0238:
0239:                        setLoading(false);
0240:
0241:                        // if reloading a file, clear dirty flag
0242:                        if (reload)
0243:                            setDirty(false);
0244:
0245:                        if (!loadAutosave && newPath != null)
0246:                            setPath(newPath);
0247:
0248:                        // if loadAutosave is false, we loaded an
0249:                        // autosave file, so we set 'dirty' to true
0250:
0251:                        // note that we don't use setDirty(),
0252:                        // because a) that would send an unnecessary
0253:                        // message, b) it would also set the
0254:                        // AUTOSAVE_DIRTY flag, which will make
0255:                        // the autosave thread write out a
0256:                        // redundant autosave file
0257:                        if (loadAutosave)
0258:                            Buffer.super .setDirty(true);
0259:
0260:                        // send some EditBus messages
0261:                        if (!getFlag(TEMPORARY)) {
0262:                            fireBufferLoaded();
0263:                            EditBus.send(new BufferUpdate(Buffer.this , view,
0264:                                    BufferUpdate.LOADED));
0265:                            //EditBus.send(new BufferUpdate(Buffer.this,
0266:                            //	view,BufferUpdate.MARKERS_CHANGED));
0267:                        }
0268:                    }
0269:                }; //}}}
0270:
0271:                if (getFlag(TEMPORARY))
0272:                    runnable.run();
0273:                else
0274:                    VFSManager.runInAWTThread(runnable);
0275:
0276:                return true;
0277:            } //}}}
0278:
0279:            //{{{ insertFile() method
0280:            /**
0281:             * Loads a file from disk, and inserts it into this buffer.
0282:             * @param view The view
0283:             * @param path the path of the file to insert
0284:             *
0285:             * @since 4.0pre1
0286:             */
0287:            public boolean insertFile(View view, String path) {
0288:                if (isPerformingIO()) {
0289:                    GUIUtilities.error(view, "buffer-multiple-io", null);
0290:                    return false;
0291:                }
0292:
0293:                setBooleanProperty(BufferIORequest.ERROR_OCCURRED, false);
0294:
0295:                path = MiscUtilities.constructPath(this .path, path);
0296:
0297:                Buffer buffer = jEdit.getBuffer(path);
0298:                if (buffer != null) {
0299:                    view.getTextArea().setSelectedText(
0300:                            buffer.getText(0, buffer.getLength()));
0301:                    return true;
0302:                }
0303:
0304:                VFS vfs = VFSManager.getVFSForPath(path);
0305:
0306:                // this returns false if initial sanity
0307:                // checks (if the file is a directory, etc)
0308:                // fail
0309:                return vfs.insert(view, this , path);
0310:            } //}}}
0311:
0312:            //{{{ autosave() method
0313:            /**
0314:             * Autosaves this buffer.
0315:             */
0316:            public void autosave() {
0317:                if (autosaveFile == null || !getFlag(AUTOSAVE_DIRTY)
0318:                        || !isDirty() || isPerformingIO())
0319:                    return;
0320:
0321:                setFlag(AUTOSAVE_DIRTY, false);
0322:
0323:                VFSManager.runInWorkThread(new BufferAutosaveRequest(null,
0324:                        this , null, VFSManager.getFileVFS(), autosaveFile
0325:                                .getPath()));
0326:            } //}}}
0327:
0328:            //{{{ saveAs() method
0329:            /**
0330:             * Prompts the user for a file to save this buffer to.
0331:             * @param view The view
0332:             * @param rename True if the buffer's path should be changed, false
0333:             * if only a copy should be saved to the specified filename
0334:             * @since jEdit 2.6pre5
0335:             */
0336:            public boolean saveAs(View view, boolean rename) {
0337:                String[] files = GUIUtilities.showVFSFileDialog(view, path,
0338:                        VFSBrowser.SAVE_DIALOG, false);
0339:
0340:                // files[] should have length 1, since the dialog type is
0341:                // SAVE_DIALOG
0342:                if (files == null)
0343:                    return false;
0344:
0345:                return save(view, files[0], rename);
0346:            } //}}}
0347:
0348:            //{{{ save() method
0349:            /**
0350:             * Saves this buffer to the specified path name, or the current path
0351:             * name if it's null.
0352:             * @param view The view
0353:             * @param path The path name to save the buffer to, or null to use
0354:             * the existing path
0355:             */
0356:            public boolean save(View view, String path) {
0357:                return save(view, path, true, false);
0358:            } //}}}
0359:
0360:            //{{{ save() method
0361:            /**
0362:             * Saves this buffer to the specified path name, or the current path
0363:             * name if it's null.
0364:             * @param view The view
0365:             * @param path The path name to save the buffer to, or null to use
0366:             * the existing path
0367:             * @param rename True if the buffer's path should be changed, false
0368:             * if only a copy should be saved to the specified filename
0369:             * @since jEdit 2.6pre5
0370:             */
0371:            public boolean save(final View view, String path,
0372:                    final boolean rename) {
0373:                return save(view, path, rename, false);
0374:            } //}}}
0375:
0376:            //{{{ save() method
0377:            /**
0378:             * Saves this buffer to the specified path name, or the current path
0379:             * name if it's null.
0380:             * @param view The view
0381:             * @param path The path name to save the buffer to, or null to use
0382:             * the existing path
0383:             * @param rename True if the buffer's path should be changed, false
0384:             * if only a copy should be saved to the specified filename
0385:             * @param disableFileStatusCheck  Disables file status checking
0386:             * regardless of the state of the checkFileStatus property
0387:             */
0388:            public boolean save(final View view, String path,
0389:                    final boolean rename, boolean disableFileStatusCheck) {
0390:                if (isPerformingIO()) {
0391:                    GUIUtilities.error(view, "buffer-multiple-io", null);
0392:                    return false;
0393:                }
0394:
0395:                setBooleanProperty(BufferIORequest.ERROR_OCCURRED, false);
0396:
0397:                if (path == null && getFlag(NEW_FILE))
0398:                    return saveAs(view, rename);
0399:
0400:                if (path == null && file != null) {
0401:                    long newModTime = file.lastModified();
0402:
0403:                    if (newModTime != modTime
0404:                            && jEdit.getBooleanProperty("view.checkModStatus")) {
0405:                        Object[] args = { this .path };
0406:                        int result = GUIUtilities.confirm(view,
0407:                                "filechanged-save", args,
0408:                                JOptionPane.YES_NO_OPTION,
0409:                                JOptionPane.WARNING_MESSAGE);
0410:                        if (result != JOptionPane.YES_OPTION)
0411:                            return false;
0412:                    }
0413:                }
0414:
0415:                EditBus.send(new BufferUpdate(this , view, BufferUpdate.SAVING));
0416:
0417:                setPerformingIO(true);
0418:
0419:                final String oldPath = this .path;
0420:                final String oldSymlinkPath = symlinkPath;
0421:                final String newPath = path == null ? this .path : path;
0422:
0423:                VFS vfs = VFSManager.getVFSForPath(newPath);
0424:
0425:                if (!checkFileForSave(view, vfs, newPath)) {
0426:                    setPerformingIO(false);
0427:                    return false;
0428:                }
0429:
0430:                Object session = vfs.createVFSSession(newPath, view);
0431:                if (session == null) {
0432:                    setPerformingIO(false);
0433:                    return false;
0434:                }
0435:
0436:                unsetProperty("overwriteReadonly");
0437:                unsetProperty("forbidTwoStageSave");
0438:                try {
0439:                    VFSFile file = vfs._getFile(session, newPath, view);
0440:                    if (file != null) {
0441:                        boolean vfsRenameCap = (vfs.getCapabilities() & VFS.RENAME_CAP) != 0;
0442:                        if (!file.isWriteable()) {
0443:                            Log.log(Log.WARNING, this , "Buffer saving : File "
0444:                                    + file + " is readOnly");
0445:                            if (vfsRenameCap) {
0446:                                Log.log(Log.DEBUG, this ,
0447:                                        "Buffer saving : VFS can rename files");
0448:                                String savePath = vfs._canonPath(session,
0449:                                        newPath, view);
0450:                                if (!MiscUtilities.isURL(savePath))
0451:                                    savePath = MiscUtilities
0452:                                            .resolveSymlinks(savePath);
0453:                                savePath = vfs.getTwoStageSaveName(savePath);
0454:                                if (savePath == null) {
0455:                                    Log
0456:                                            .log(Log.DEBUG, this ,
0457:                                                    "Buffer saving : two stage save impossible because path is null");
0458:                                    VFSManager
0459:                                            .error(
0460:                                                    view,
0461:                                                    newPath,
0462:                                                    "ioerror.save-readonly-twostagefail",
0463:                                                    null);
0464:                                    setPerformingIO(false);
0465:                                    return false;
0466:                                } else {
0467:                                    int result = GUIUtilities.confirm(view,
0468:                                            "vfs.overwrite-readonly",
0469:                                            new Object[] { newPath },
0470:                                            JOptionPane.YES_NO_OPTION,
0471:                                            JOptionPane.WARNING_MESSAGE);
0472:                                    if (result == JOptionPane.YES_OPTION) {
0473:                                        Log
0474:                                                .log(Log.WARNING, this ,
0475:                                                        "Buffer saving : two stage save will be used to save buffer");
0476:                                        setBooleanProperty("overwriteReadonly",
0477:                                                true);
0478:                                    } else {
0479:                                        Log.log(Log.DEBUG, this ,
0480:                                                "Buffer not saved");
0481:                                        setPerformingIO(false);
0482:                                        return false;
0483:                                    }
0484:                                }
0485:                            } else {
0486:                                Log
0487:                                        .log(Log.WARNING, this ,
0488:                                                "Buffer saving : file is readonly and vfs cannot do two stage save");
0489:                                VFSManager.error(view, newPath,
0490:                                        "ioerror.write-error-readonly", null);
0491:                                setPerformingIO(false);
0492:                                return false;
0493:                            }
0494:                        } else {
0495:                            String savePath = vfs._canonPath(session, newPath,
0496:                                    view);
0497:                            if (!MiscUtilities.isURL(savePath))
0498:                                savePath = MiscUtilities
0499:                                        .resolveSymlinks(savePath);
0500:                            savePath = vfs.getTwoStageSaveName(savePath);
0501:                            if (jEdit.getBooleanProperty("twoStageSave")
0502:                                    && (!vfsRenameCap || savePath == null)) {
0503:                                // the file is writeable but the vfs cannot do two stage. We must overwrite
0504:                                // readonly flag
0505:
0506:                                int result = GUIUtilities.confirm(view,
0507:                                        "vfs.twostageimpossible",
0508:                                        new Object[] { newPath },
0509:                                        JOptionPane.YES_NO_OPTION,
0510:                                        JOptionPane.WARNING_MESSAGE);
0511:                                if (result == JOptionPane.YES_OPTION) {
0512:                                    Log
0513:                                            .log(Log.WARNING, this ,
0514:                                                    "Buffer saving : two stage save cannot be used");
0515:                                    setBooleanProperty("forbidTwoStageSave",
0516:                                            true);
0517:                                } else {
0518:                                    Log
0519:                                            .log(Log.DEBUG, this ,
0520:                                                    "Buffer not saved");
0521:                                    setPerformingIO(false);
0522:                                    return false;
0523:                                }
0524:
0525:                            }
0526:                        }
0527:                    }
0528:                } catch (IOException io) {
0529:                    VFSManager.error(view, newPath, "ioerror",
0530:                            new String[] { io.toString() });
0531:                    setPerformingIO(false);
0532:                    return false;
0533:                } finally {
0534:                    try {
0535:                        vfs._endVFSSession(session, view);
0536:                    } catch (IOException io) {
0537:                        VFSManager.error(view, newPath, "ioerror",
0538:                                new String[] { io.toString() });
0539:                        setPerformingIO(false);
0540:                        return false;
0541:                    }
0542:                }
0543:
0544:                if (!vfs.save(view, this , newPath)) {
0545:                    setPerformingIO(false);
0546:                    return false;
0547:                }
0548:
0549:                // Once save is complete, do a few other things
0550:                VFSManager.runInAWTThread(new Runnable() {
0551:                    public void run() {
0552:                        setPerformingIO(false);
0553:                        setProperty("overwriteReadonly", null);
0554:                        finishSaving(
0555:                                view,
0556:                                oldPath,
0557:                                oldSymlinkPath,
0558:                                newPath,
0559:                                rename,
0560:                                getBooleanProperty(BufferIORequest.ERROR_OCCURRED));
0561:                        updateMarkersFile(view);
0562:                    }
0563:                });
0564:
0565:                int check = jEdit.getIntegerProperty("checkFileStatus");
0566:                if ((!disableFileStatusCheck) && (check == 1 || check == 2))
0567:                    jEdit.checkBufferStatus(view, false);
0568:
0569:                return true;
0570:            } //}}}
0571:
0572:            //{{{ checkFileStatus() method
0573:            public static final int FILE_NOT_CHANGED = 0;
0574:            public static final int FILE_CHANGED = 1;
0575:            public static final int FILE_DELETED = 2;
0576:
0577:            /**
0578:             * Check if the buffer has changed on disk.
0579:             * @return One of <code>NOT_CHANGED</code>, <code>CHANGED</code>, or
0580:             * <code>DELETED</code>.
0581:             *
0582:             * @since jEdit 4.2pre1
0583:             */
0584:            public int checkFileStatus(View view) {
0585:                // - don't do these checks while a save is in progress,
0586:                // because for a moment newModTime will be greater than
0587:                // oldModTime, due to the multithreading
0588:                // - only supported on local file system
0589:                if (!isPerformingIO() && file != null && !getFlag(NEW_FILE)) {
0590:                    boolean newReadOnly = (file.exists() && !file.canWrite());
0591:                    if (newReadOnly != isFileReadOnly()) {
0592:                        setFileReadOnly(newReadOnly);
0593:                        EditBus.send(new BufferUpdate(this , null,
0594:                                BufferUpdate.DIRTY_CHANGED));
0595:                    }
0596:
0597:                    long oldModTime = modTime;
0598:                    long newModTime = file.lastModified();
0599:
0600:                    if (newModTime != oldModTime) {
0601:                        modTime = newModTime;
0602:
0603:                        if (!file.exists()) {
0604:                            setFlag(NEW_FILE, true);
0605:                            setDirty(true);
0606:                            return FILE_DELETED;
0607:                        } else {
0608:                            return FILE_CHANGED;
0609:                        }
0610:                    }
0611:                }
0612:
0613:                return FILE_NOT_CHANGED;
0614:            } //}}}
0615:
0616:            //}}}
0617:
0618:            //{{{ Getters/setter methods for various buffer meta-data
0619:
0620:            //{{{ getLastModified() method
0621:            /**
0622:             * Returns the last time jEdit modified the file on disk.
0623:             * This method is thread-safe.
0624:             */
0625:            public long getLastModified() {
0626:                return modTime;
0627:            } //}}}
0628:
0629:            //{{{ setLastModified() method
0630:            /**
0631:             * Sets the last time jEdit modified the file on disk.
0632:             * @param modTime The new modification time
0633:             */
0634:            public void setLastModified(long modTime) {
0635:                this .modTime = modTime;
0636:            } //}}}
0637:
0638:            //{{{ getAutoReload() method
0639:            /**
0640:             * Returns the status of the AUTORELOAD flag
0641:             * If true, reload changed files automatically
0642:             */
0643:            public boolean getAutoReload() {
0644:                return getFlag(AUTORELOAD);
0645:            } //}}}
0646:
0647:            //{{{ setAutoReload() method
0648:            /**
0649:             * Sets the status of the AUTORELOAD flag
0650:             * @param value # If true, reload changed files automatically
0651:             */
0652:            public void setAutoReload(boolean value) {
0653:                setFlag(AUTORELOAD, value);
0654:            } //}}}
0655:
0656:            //{{{ getAutoReloadDialog() method
0657:            /**
0658:             * Returns the status of the AUTORELOAD_DIALOG flag
0659:             * If true, prompt for reloading or notify user
0660:             * when the file has changed on disk
0661:             */
0662:            public boolean getAutoReloadDialog() {
0663:                return getFlag(AUTORELOAD_DIALOG);
0664:            } //}}}
0665:
0666:            //{{{ setAutoReloadDialog() method
0667:            /**
0668:             * Sets the status of the AUTORELOAD_DIALOG flag
0669:             * @param value # If true, prompt for reloading or notify user
0670:             * when the file has changed on disk
0671:
0672:             */
0673:            public void setAutoReloadDialog(boolean value) {
0674:                setFlag(AUTORELOAD_DIALOG, value);
0675:            } //}}}
0676:
0677:            //{{{ getVFS() method
0678:            /**
0679:             * Returns the virtual filesystem responsible for loading and
0680:             * saving this buffer. This method is thread-safe.
0681:             */
0682:            public VFS getVFS() {
0683:                return VFSManager.getVFSForPath(path);
0684:            } //}}}
0685:
0686:            //{{{ getAutosaveFile() method
0687:            /**
0688:             * Returns the autosave file for this buffer. This may be null if
0689:             * the file is non-local.
0690:             */
0691:            public File getAutosaveFile() {
0692:                return autosaveFile;
0693:            } //}}}
0694:
0695:            //{{{ removeAutosaveFile() method
0696:            /**
0697:             * Remove the autosave file.
0698:             * @since jEdit 4.3pre12
0699:             */
0700:            public void removeAutosaveFile() {
0701:                if (autosaveFile != null) {
0702:                    autosaveFile.delete();
0703:                    setFlag(AUTOSAVE_DIRTY, true);
0704:                }
0705:            } //}}}
0706:
0707:            //{{{ getName() method
0708:            /**
0709:             * Returns the name of this buffer. This method is thread-safe.
0710:             */
0711:            public String getName() {
0712:                return name;
0713:            } //}}}
0714:
0715:            //{{{ getPath() method
0716:            /**
0717:             * Returns the path name of this buffer. This method is thread-safe.
0718:             */
0719:            public String getPath() {
0720:                return path;
0721:            } //}}}
0722:
0723:            //{{{ getSymlinkPath() method
0724:            /**
0725:             * If this file is a symbolic link, returns the link destination.
0726:             * Otherwise returns the file's path. This method is thread-safe.
0727:             * @since jEdit 4.2pre1
0728:             */
0729:            public String getSymlinkPath() {
0730:                return symlinkPath;
0731:            } //}}}
0732:
0733:            //{{{ getDirectory() method
0734:            /**
0735:             * Returns the directory containing this buffer.
0736:             * @since jEdit 4.1pre11
0737:             */
0738:            public String getDirectory() {
0739:                return directory;
0740:            } //}}}
0741:
0742:            //{{{ isClosed() method
0743:            /**
0744:             * Returns true if this buffer has been closed with
0745:             * {@link org.gjt.sp.jedit.jEdit#closeBuffer(View,Buffer)}.
0746:             * This method is thread-safe.
0747:             */
0748:            public boolean isClosed() {
0749:                return getFlag(CLOSED);
0750:            } //}}}
0751:
0752:            //{{{ isLoaded() method
0753:            /**
0754:             * Returns true if the buffer is loaded. This method is thread-safe.
0755:             */
0756:            public boolean isLoaded() {
0757:                return !isLoading();
0758:            } //}}}
0759:
0760:            //{{{ isNewFile() method
0761:            /**
0762:             * Returns whether this buffer lacks a corresponding version on disk.
0763:             * This method is thread-safe.
0764:             */
0765:            public boolean isNewFile() {
0766:                return getFlag(NEW_FILE);
0767:            } //}}}
0768:
0769:            //{{{ setNewFile() method
0770:            /**
0771:             * Sets the new file flag.
0772:             * @param newFile The new file flag
0773:             */
0774:            public void setNewFile(boolean newFile) {
0775:                setFlag(NEW_FILE, newFile);
0776:                if (!newFile)
0777:                    setFlag(UNTITLED, false);
0778:            } //}}}
0779:
0780:            //{{{ isUntitled() method
0781:            /**
0782:             * Returns true if this file is 'untitled'. This method is thread-safe.
0783:             */
0784:            public boolean isUntitled() {
0785:                return getFlag(UNTITLED);
0786:            } //}}}
0787:
0788:            //{{{ setDirty() method
0789:            /**
0790:             * Sets the 'dirty' (changed since last save) flag of this buffer.
0791:             */
0792:            public void setDirty(boolean d) {
0793:                boolean old_d = isDirty();
0794:                super .setDirty(d);
0795:                boolean editable = isEditable();
0796:
0797:                if (d) {
0798:                    if (editable)
0799:                        setFlag(AUTOSAVE_DIRTY, true);
0800:                } else {
0801:                    setFlag(AUTOSAVE_DIRTY, false);
0802:
0803:                    if (autosaveFile != null)
0804:                        autosaveFile.delete();
0805:                }
0806:
0807:                if (d != old_d && editable) {
0808:                    EditBus.send(new BufferUpdate(this , null,
0809:                            BufferUpdate.DIRTY_CHANGED));
0810:                }
0811:            } //}}}
0812:
0813:            //{{{ isTemporary() method
0814:            /**
0815:             * Returns if this is a temporary buffer. This method is thread-safe.
0816:             * @see jEdit#openTemporary(View,String,String,boolean)
0817:             * @see jEdit#commitTemporary(Buffer)
0818:             * @since jEdit 2.2pre7
0819:             */
0820:            public boolean isTemporary() {
0821:                return getFlag(TEMPORARY);
0822:            } //}}}
0823:
0824:            //{{{ getIcon() method
0825:            /**
0826:             * Returns this buffer's icon.
0827:             * @since jEdit 2.6pre6
0828:             */
0829:            public Icon getIcon() {
0830:                if (isDirty())
0831:                    return GUIUtilities.loadIcon("dirty.gif");
0832:                else if (isReadOnly())
0833:                    return GUIUtilities.loadIcon("readonly.gif");
0834:                else if (getFlag(NEW_FILE))
0835:                    return GUIUtilities.loadIcon("new.gif");
0836:                else
0837:                    return GUIUtilities.loadIcon("normal.gif");
0838:            } //}}}
0839:
0840:            //}}}
0841:
0842:            //{{{ Buffer events
0843:
0844:            //{{{ addBufferChangeListener() method
0845:            /**
0846:             * @deprecated Call {@link JEditBuffer#addBufferListener(BufferListener,int)}.
0847:             */
0848:            public void addBufferChangeListener(BufferChangeListener listener,
0849:                    int priority) {
0850:                addBufferListener(new BufferChangeListener.Adapter(listener),
0851:                        priority);
0852:            } //}}}
0853:
0854:            //{{{ addBufferChangeListener() method
0855:            /**
0856:             * @deprecated Call {@link JEditBuffer#addBufferListener(BufferListener)}.
0857:             */
0858:            public void addBufferChangeListener(BufferChangeListener listener) {
0859:                addBufferChangeListener(listener, NORMAL_PRIORITY);
0860:            } //}}}
0861:
0862:            //{{{ removeBufferChangeListener() method
0863:            /**
0864:             * @deprecated Call {@link JEditBuffer#removeBufferListener(BufferListener)}.
0865:             */
0866:            public void removeBufferChangeListener(BufferChangeListener listener) {
0867:                BufferListener[] listeners = getBufferListeners();
0868:
0869:                for (int i = 0; i < listeners.length; i++) {
0870:                    BufferListener l = listeners[i];
0871:                    if (l instanceof  BufferChangeListener.Adapter) {
0872:                        if (((BufferChangeListener.Adapter) l).getDelegate() == listener) {
0873:                            removeBufferListener(l);
0874:                            return;
0875:                        }
0876:                    }
0877:                }
0878:            } //}}}
0879:
0880:            //}}}
0881:
0882:            //{{{ Property methods
0883:
0884:            //{{{ propertiesChanged() method
0885:            /**
0886:             * Reloads settings from the properties. This should be called
0887:             * after the <code>syntax</code> or <code>folding</code>
0888:             * buffer-local properties are changed.
0889:             */
0890:            public void propertiesChanged() {
0891:                super .propertiesChanged();
0892:                EditBus.send(new BufferUpdate(this , null,
0893:                        BufferUpdate.PROPERTIES_CHANGED));
0894:            } //}}}
0895:
0896:            //{{{ getDefaultProperty() method
0897:            public Object getDefaultProperty(String name) {
0898:                Object retVal;
0899:
0900:                if (mode != null) {
0901:                    retVal = mode.getProperty(name);
0902:                    if (retVal == null)
0903:                        return null;
0904:
0905:                    setDefaultProperty(name, retVal);
0906:                    return retVal;
0907:                }
0908:                // Now try buffer.<property>
0909:                String value = jEdit.getProperty("buffer." + name);
0910:                if (value == null)
0911:                    return null;
0912:
0913:                // Try returning it as an integer first
0914:                try {
0915:                    retVal = new Integer(value);
0916:                } catch (NumberFormatException nf) {
0917:                    retVal = value;
0918:                }
0919:
0920:                return retVal;
0921:            } //}}}
0922:
0923:            //{{{ toggleWordWrap() method
0924:            /**
0925:             * Toggles word wrap between the three available modes. This is used
0926:             * by the status bar.
0927:             * @param view We show a message in the view's status bar
0928:             * @since jEdit 4.1pre3
0929:             */
0930:            public void toggleWordWrap(View view) {
0931:                String wrap = getStringProperty("wrap");
0932:                if (wrap.equals("none"))
0933:                    wrap = "soft";
0934:                else if (wrap.equals("soft"))
0935:                    wrap = "hard";
0936:                else if (wrap.equals("hard"))
0937:                    wrap = "none";
0938:                view.getStatus().setMessageAndClear(
0939:                        jEdit.getProperty("view.status.wrap-changed",
0940:                                new String[] { wrap }));
0941:                setProperty("wrap", wrap);
0942:                propertiesChanged();
0943:            } //}}}
0944:
0945:            //{{{ toggleLineSeparator() method
0946:            /**
0947:             * Toggles the line separator between the three available settings.
0948:             * This is used by the status bar.
0949:             * @param view We show a message in the view's status bar
0950:             * @since jEdit 4.1pre3
0951:             */
0952:            public void toggleLineSeparator(View view) {
0953:                String status = null;
0954:                String lineSep = getStringProperty("lineSeparator");
0955:                if ("\n".equals(lineSep)) {
0956:                    status = "windows";
0957:                    lineSep = "\r\n";
0958:                } else if ("\r\n".equals(lineSep)) {
0959:                    status = "mac";
0960:                    lineSep = "\r";
0961:                } else if ("\r".equals(lineSep)) {
0962:                    status = "unix";
0963:                    lineSep = "\n";
0964:                }
0965:                view.getStatus().setMessageAndClear(
0966:                        jEdit.getProperty("view.status.linesep-changed",
0967:                                new String[] { jEdit.getProperty("lineSep."
0968:                                        + status) }));
0969:                setProperty("lineSeparator", lineSep);
0970:                setDirty(true);
0971:                propertiesChanged();
0972:            } //}}}
0973:
0974:            //{{{ getContextSensitiveProperty() method
0975:            /**
0976:             * Some settings, like comment start and end strings, can
0977:             * vary between different parts of a buffer (HTML text and inline
0978:             * JavaScript, for example).
0979:             * @param offset The offset
0980:             * @param name The property name
0981:             * @since jEdit 4.0pre3
0982:             */
0983:            public String getContextSensitiveProperty(int offset, String name) {
0984:                Object value = super .getContextSensitiveProperty(offset, name);
0985:
0986:                if (value == null) {
0987:                    ParserRuleSet rules = getRuleSetAtOffset(offset);
0988:
0989:                    value = jEdit.getMode(rules.getModeName())
0990:                            .getProperty(name);
0991:
0992:                    if (value == null)
0993:                        value = mode.getProperty(name);
0994:                }
0995:
0996:                if (value == null)
0997:                    return null;
0998:                else
0999:                    return String.valueOf(value);
1000:            } //}}}
1001:
1002:            //}}}
1003:
1004:            //{{{ Edit modes, syntax highlighting
1005:
1006:            //{{{ setMode() method
1007:            /**
1008:             * Sets this buffer's edit mode by calling the accept() method
1009:             * of each registered edit mode.
1010:             */
1011:            public void setMode() {
1012:                String userMode = getStringProperty("mode");
1013:                if (userMode != null) {
1014:                    unsetProperty("mode");
1015:                    Mode m = ModeProvider.instance.getMode(userMode);
1016:                    if (m != null) {
1017:                        setMode(m);
1018:                        return;
1019:                    }
1020:                }
1021:
1022:                String firstLine = getLineText(0);
1023:
1024:                Mode mode = ModeProvider.instance.getModeForFile(name,
1025:                        firstLine);
1026:                if (mode != null) {
1027:                    setMode(mode);
1028:                    return;
1029:                }
1030:
1031:                Mode defaultMode = jEdit.getMode(jEdit
1032:                        .getProperty("buffer.defaultMode"));
1033:                if (defaultMode == null)
1034:                    defaultMode = jEdit.getMode("text");
1035:                setMode(defaultMode);
1036:            } //}}}
1037:
1038:            //}}}
1039:
1040:            //{{{ Deprecated methods
1041:
1042:            //{{{ putProperty() method
1043:            /**
1044:             * @deprecated Call <code>setProperty()</code> instead.
1045:             */
1046:            public void putProperty(Object name, Object value) {
1047:                // for backwards compatibility
1048:                if (!(name instanceof  String))
1049:                    return;
1050:
1051:                setProperty((String) name, value);
1052:            } //}}}
1053:
1054:            //{{{ putBooleanProperty() method
1055:            /**
1056:             * @deprecated Call <code>setBooleanProperty()</code> instead
1057:             */
1058:            public void putBooleanProperty(String name, boolean value) {
1059:                setBooleanProperty(name, value);
1060:            } //}}}
1061:
1062:            //{{{ markTokens() method
1063:            /**
1064:             * @deprecated Use org.gjt.sp.jedit.syntax.DefaultTokenHandler instead
1065:             */
1066:            public static class TokenList extends DefaultTokenHandler {
1067:                public Token getFirstToken() {
1068:                    return getTokens();
1069:                }
1070:            }
1071:
1072:            /**
1073:             * @deprecated Use the other form of <code>markTokens()</code> instead
1074:             */
1075:            public TokenList markTokens(int lineIndex) {
1076:                TokenList list = new TokenList();
1077:                markTokens(lineIndex, list);
1078:                return list;
1079:            } //}}}
1080:
1081:            //{{{ insertString() method
1082:            /**
1083:             * @deprecated Call <code>insert()</code> instead.
1084:             */
1085:            public void insertString(int offset, String str, AttributeSet attr) {
1086:                insert(offset, str);
1087:            } //}}}
1088:
1089:            //{{{ getFile() method
1090:            /**
1091:             * @deprecated Do not call this method, use {@link #getPath()}
1092:             * instead.
1093:             */
1094:            public File getFile() {
1095:                return file;
1096:            } //}}}
1097:
1098:            //}}}
1099:
1100:            //{{{ Marker methods
1101:
1102:            //{{{ getMarkers() method
1103:            /**
1104:             * Returns a vector of markers.
1105:             * @since jEdit 3.2pre1
1106:             */
1107:            public Vector<Marker> getMarkers() {
1108:                return markers;
1109:            } //}}}
1110:
1111:            //{{{ getMarkerStatusPrompt() method
1112:            /**
1113:             * Returns the status prompt for the given marker action. Only
1114:             * intended to be called from <code>actions.xml</code>.
1115:             * @since jEdit 4.2pre2
1116:             */
1117:            public String getMarkerStatusPrompt(String action) {
1118:                return jEdit.getProperty("view.status." + action,
1119:                        new String[] { getMarkerNameString() });
1120:            } //}}}
1121:
1122:            //{{{ getMarkerNameString() method
1123:            /**
1124:             * Returns a string of all set markers, used by the status bar
1125:             * (eg, "a b $ % ^").
1126:             * @since jEdit 4.2pre2
1127:             */
1128:            public String getMarkerNameString() {
1129:                StringBuilder buf = new StringBuilder();
1130:                for (int i = 0; i < markers.size(); i++) {
1131:                    Marker marker = markers.get(i);
1132:                    if (marker.getShortcut() != '\0') {
1133:                        if (buf.length() != 0)
1134:                            buf.append(' ');
1135:                        buf.append(marker.getShortcut());
1136:                    }
1137:                }
1138:
1139:                if (buf.length() == 0)
1140:                    return jEdit.getProperty("view.status.no-markers");
1141:                else
1142:                    return buf.toString();
1143:            } //}}}
1144:
1145:            //{{{ addOrRemoveMarker() method
1146:            /**
1147:             * If a marker is set on the line of the position, it is removed. Otherwise
1148:             * a new marker with the specified shortcut is added.
1149:             * @param pos The position of the marker
1150:             * @param shortcut The shortcut ('\0' if none)
1151:             * @since jEdit 3.2pre5
1152:             */
1153:            public void addOrRemoveMarker(char shortcut, int pos) {
1154:                int line = getLineOfOffset(pos);
1155:                if (getMarkerAtLine(line) != null)
1156:                    removeMarker(line);
1157:                else
1158:                    addMarker(shortcut, pos);
1159:            } //}}}
1160:
1161:            //{{{ addMarker() method
1162:            /**
1163:             * Adds a marker to this buffer.
1164:             * @param pos The position of the marker
1165:             * @param shortcut The shortcut ('\0' if none)
1166:             * @since jEdit 3.2pre1
1167:             */
1168:            public void addMarker(char shortcut, int pos) {
1169:                Marker markerN = new Marker(this , shortcut, pos);
1170:                boolean added = false;
1171:
1172:                // don't sort markers while buffer is being loaded
1173:                if (isLoaded()) {
1174:                    setFlag(MARKERS_CHANGED, true);
1175:
1176:                    markerN.createPosition();
1177:
1178:                    for (int i = 0; i < markers.size(); i++) {
1179:                        Marker marker = markers.get(i);
1180:                        if (shortcut != '\0'
1181:                                && marker.getShortcut() == shortcut)
1182:                            marker.setShortcut('\0');
1183:
1184:                        if (marker.getPosition() == pos) {
1185:                            markers.removeElementAt(i);
1186:                            i--;
1187:                        }
1188:                    }
1189:
1190:                    for (int i = 0; i < markers.size(); i++) {
1191:                        Marker marker = markers.get(i);
1192:                        if (marker.getPosition() > pos) {
1193:                            markers.insertElementAt(markerN, i);
1194:                            added = true;
1195:                            break;
1196:                        }
1197:                    }
1198:                }
1199:
1200:                if (!added)
1201:                    markers.addElement(markerN);
1202:
1203:                if (isLoaded() && !getFlag(TEMPORARY)) {
1204:                    EditBus.send(new BufferUpdate(this , null,
1205:                            BufferUpdate.MARKERS_CHANGED));
1206:                }
1207:            } //}}}
1208:
1209:            //{{{ getMarkerInRange() method
1210:            /**
1211:             * Returns the first marker within the specified range.
1212:             * @param start The start offset
1213:             * @param end The end offset
1214:             * @since jEdit 4.0pre4
1215:             */
1216:            public Marker getMarkerInRange(int start, int end) {
1217:                for (int i = 0; i < markers.size(); i++) {
1218:                    Marker marker = markers.get(i);
1219:                    int pos = marker.getPosition();
1220:                    if (pos >= start && pos < end)
1221:                        return marker;
1222:                }
1223:
1224:                return null;
1225:            } //}}}
1226:
1227:            //{{{ getMarkerAtLine() method
1228:            /**
1229:             * Returns the first marker at the specified line, or <code>null</code>
1230:             * if there is none.
1231:             * @param line The line number
1232:             * @since jEdit 3.2pre2
1233:             */
1234:            public Marker getMarkerAtLine(int line) {
1235:                for (int i = 0; i < markers.size(); i++) {
1236:                    Marker marker = markers.get(i);
1237:                    if (getLineOfOffset(marker.getPosition()) == line)
1238:                        return marker;
1239:                }
1240:
1241:                return null;
1242:            } //}}}
1243:
1244:            //{{{ removeMarker() method
1245:            /**
1246:             * Removes all markers at the specified line.
1247:             * @param line The line number
1248:             * @since jEdit 3.2pre2
1249:             */
1250:            public void removeMarker(int line) {
1251:                for (int i = 0; i < markers.size(); i++) {
1252:                    Marker marker = markers.get(i);
1253:                    if (getLineOfOffset(marker.getPosition()) == line) {
1254:                        setFlag(MARKERS_CHANGED, true);
1255:                        marker.removePosition();
1256:                        markers.removeElementAt(i);
1257:                        i--;
1258:                    }
1259:                }
1260:
1261:                EditBus.send(new BufferUpdate(this , null,
1262:                        BufferUpdate.MARKERS_CHANGED));
1263:            } //}}}
1264:
1265:            //{{{ removeAllMarkers() method
1266:            /**
1267:             * Removes all defined markers.
1268:             * @since jEdit 2.6pre1
1269:             */
1270:            public void removeAllMarkers() {
1271:                setFlag(MARKERS_CHANGED, true);
1272:
1273:                for (int i = 0; i < markers.size(); i++)
1274:                    markers.get(i).removePosition();
1275:
1276:                markers.removeAllElements();
1277:
1278:                if (isLoaded()) {
1279:                    EditBus.send(new BufferUpdate(this , null,
1280:                            BufferUpdate.MARKERS_CHANGED));
1281:                }
1282:            } //}}}
1283:
1284:            //{{{ getMarker() method
1285:            /**
1286:             * Returns the marker with the specified shortcut.
1287:             * @param shortcut The shortcut
1288:             * @since jEdit 3.2pre2
1289:             */
1290:            public Marker getMarker(char shortcut) {
1291:                Enumeration<Marker> e = markers.elements();
1292:                while (e.hasMoreElements()) {
1293:                    Marker marker = e.nextElement();
1294:                    if (marker.getShortcut() == shortcut)
1295:                        return marker;
1296:                }
1297:                return null;
1298:            } //}}}
1299:
1300:            //{{{ getMarkersPath() method
1301:            /**
1302:             * Returns the path for this buffer's markers file
1303:             * @param vfs The appropriate VFS
1304:             * @since jEdit 4.3pre7
1305:             * @deprecated it will fail if you save to another VFS. use {@link #getMarkersPath(VFS, String)}
1306:             */
1307:            @Deprecated
1308:            public String getMarkersPath(VFS vfs) {
1309:                return getMarkersPath(vfs, path);
1310:            } //}}}
1311:
1312:            //{{{ getMarkersPath() method
1313:            /**
1314:             * Returns the path for this buffer's markers file
1315:             * @param vfs The appropriate VFS
1316:             * @param path the path of the buffer, it can be different from the field
1317:             * when using save-as
1318:             * @since jEdit 4.3pre10
1319:             */
1320:            public static String getMarkersPath(VFS vfs, String path) {
1321:                return vfs.getParentOfPath(path) + '.' + vfs.getFileName(path)
1322:                        + ".marks";
1323:            } //}}}
1324:
1325:            //{{{ updateMarkersFile() method
1326:            /**
1327:             * Save the markers file, or delete it when there are mo markers left
1328:             * Handling markers is now independent from saving the buffer.
1329:             * Changing markers will not set the buffer dirty any longer.
1330:             * @param view The current view
1331:             * @since jEdit 4.3pre7
1332:             */
1333:            public boolean updateMarkersFile(View view) {
1334:                if (!markersChanged())
1335:                    return true;
1336:                // adapted from VFS.save
1337:                VFS vfs = VFSManager.getVFSForPath(getPath());
1338:                if (((vfs.getCapabilities() & VFS.WRITE_CAP) == 0)
1339:                        || (!vfs.isMarkersFileSupported())) {
1340:                    VFSManager.error(view, path, "vfs.not-supported.save",
1341:                            new String[] { "markers file" });
1342:                    return false;
1343:                }
1344:                Object session = vfs.createVFSSession(path, view);
1345:                if (session == null)
1346:                    return false;
1347:                VFSManager.runInWorkThread(new MarkersSaveRequest(view, this ,
1348:                        session, vfs, path));
1349:                return true;
1350:            } //}}}
1351:
1352:            //{{{ markersChanged() method
1353:            /**
1354:             * Return true when markers have changed and the markers file needs
1355:             * to be updated
1356:             * @since jEdit 4.3pre7
1357:             */
1358:            public boolean markersChanged() {
1359:                return getFlag(MARKERS_CHANGED);
1360:            } //}}}
1361:
1362:            //{{{ setMarkersChanged() method
1363:            /**
1364:             * Sets/unsets the MARKERS_CHANGED flag
1365:             * @since jEdit 4.3pre7
1366:             */
1367:            public void setMarkersChanged(boolean changed) {
1368:                setFlag(MARKERS_CHANGED, changed);
1369:            } //}}}
1370:
1371:            //}}}
1372:
1373:            //{{{ Miscellaneous methods
1374:
1375:            //{{{ setWaitSocket() method
1376:            /**
1377:             * This socket is closed when the buffer is closed.
1378:             */
1379:            public void setWaitSocket(Socket waitSocket) {
1380:                this .waitSocket = waitSocket;
1381:            } //}}}
1382:
1383:            //{{{ getNext() method
1384:            /**
1385:             * Returns the next buffer in the list.
1386:             */
1387:            public Buffer getNext() {
1388:                return next;
1389:            } //}}}
1390:
1391:            //{{{ getPrev() method
1392:            /**
1393:             * Returns the previous buffer in the list.
1394:             */
1395:            public Buffer getPrev() {
1396:                return prev;
1397:            } //}}}
1398:
1399:            //{{{ getIndex() method
1400:            /**
1401:             * Returns the position of this buffer in the buffer list.
1402:             */
1403:            public int getIndex() {
1404:                int count = 0;
1405:                Buffer buffer = prev;
1406:                while (true) {
1407:                    if (buffer == null)
1408:                        break;
1409:                    count++;
1410:                    buffer = buffer.prev;
1411:                }
1412:                return count;
1413:            } //}}}
1414:
1415:            //{{{ toString() method
1416:            /**
1417:             * Returns a string representation of this buffer.
1418:             * This simply returns the path name.
1419:             */
1420:            public String toString() {
1421:                return name + " (" + directory + ')';
1422:            } //}}}
1423:
1424:            //}}}
1425:
1426:            //{{{ Package-private members
1427:            /** The previous buffer in the list. */
1428:            Buffer prev;
1429:            /** The next buffer in the list. */
1430:            Buffer next;
1431:
1432:            //{{{ Buffer constructor
1433:            Buffer(String path, boolean newFile, boolean temp, Hashtable props) {
1434:                super (props);
1435:
1436:                markers = new Vector<Marker>();
1437:
1438:                setFlag(TEMPORARY, temp);
1439:
1440:                // this must be called before any EditBus messages are sent
1441:                setPath(path);
1442:
1443:                /* Magic: UNTITLED is only set if newFile param to
1444:                 * constructor is set, NEW_FILE is also set if file
1445:                 * doesn't exist on disk.
1446:                 *
1447:                 * This is so that we can tell apart files created
1448:                 * with jEdit.newFile(), and those that just don't
1449:                 * exist on disk.
1450:                 *
1451:                 * Why do we need to tell the difference between the
1452:                 * two? jEdit.addBufferToList() checks if the only
1453:                 * opened buffer is an untitled buffer, and if so,
1454:                 * replaces it with the buffer to add. We don't want
1455:                 * this behavior to occur with files that don't
1456:                 * exist on disk; only untitled ones.
1457:                 */
1458:                setFlag(UNTITLED, newFile);
1459:                setFlag(NEW_FILE, newFile);
1460:                setFlag(AUTORELOAD, jEdit.getBooleanProperty("autoReload"));
1461:                setFlag(AUTORELOAD_DIALOG, jEdit
1462:                        .getBooleanProperty("autoReloadDialog"));
1463:            } //}}}
1464:
1465:            //{{{ commitTemporary() method
1466:            void commitTemporary() {
1467:                setFlag(TEMPORARY, false);
1468:
1469:                finishLoading();
1470:            } //}}}
1471:
1472:            //{{{ close() method
1473:            void close() {
1474:                setFlag(CLOSED, true);
1475:
1476:                if (autosaveFile != null)
1477:                    autosaveFile.delete();
1478:
1479:                // notify clients with -wait
1480:                if (waitSocket != null) {
1481:                    try {
1482:                        waitSocket.getOutputStream().write('\0');
1483:                        waitSocket.getOutputStream().flush();
1484:                        waitSocket.getInputStream().close();
1485:                        waitSocket.getOutputStream().close();
1486:                        waitSocket.close();
1487:                    } catch (IOException io) {
1488:                        //Log.log(Log.ERROR,this,io);
1489:                    }
1490:                }
1491:            } //}}}
1492:
1493:            //}}}
1494:
1495:            //{{{ Private members
1496:
1497:            //{{{ Flags
1498:
1499:            //{{{ setFlag() method
1500:            private void setFlag(int flag, boolean value) {
1501:                if (value)
1502:                    flags |= (1 << flag);
1503:                else
1504:                    flags &= ~(1 << flag);
1505:            } //}}}
1506:
1507:            //{{{ getFlag() method
1508:            private boolean getFlag(int flag) {
1509:                int mask = (1 << flag);
1510:                return (flags & mask) == mask;
1511:            } //}}}
1512:
1513:            //{{{ Flag values
1514:            private static final int CLOSED = 0;
1515:            private static final int NEW_FILE = 3;
1516:            private static final int UNTITLED = 4;
1517:            private static final int AUTOSAVE_DIRTY = 5;
1518:            private static final int AUTORELOAD = 6;
1519:            private static final int AUTORELOAD_DIALOG = 7;
1520:            private static final int TEMPORARY = 10;
1521:            private static final int MARKERS_CHANGED = 12;
1522:            //}}}
1523:
1524:            private int flags;
1525:
1526:            //}}}
1527:
1528:            //{{{ Instance variables
1529:            private String path;
1530:            private String symlinkPath;
1531:            private String name;
1532:            private String directory;
1533:            private File file;
1534:            private File autosaveFile;
1535:            private long modTime;
1536:
1537:            private final Vector<Marker> markers;
1538:
1539:            private Socket waitSocket;
1540:
1541:            //}}}
1542:
1543:            //{{{ setPath() method
1544:            private void setPath(String path) {
1545:                View[] views = jEdit.getViews();
1546:                for (int i = 0; i < views.length; i++) {
1547:                    View view = views[i];
1548:                    EditPane[] editPanes = view.getEditPanes();
1549:                    for (int j = 0; j < editPanes.length; j++)
1550:                        editPanes[j].bufferRenamed(this .path, path);
1551:                }
1552:
1553:                this .path = path;
1554:                VFS vfs = VFSManager.getVFSForPath(path);
1555:                if ((vfs.getCapabilities() & VFS.WRITE_CAP) == 0)
1556:                    setFileReadOnly(true);
1557:                name = vfs.getFileName(path);
1558:                directory = vfs.getParentOfPath(path);
1559:
1560:                if (vfs instanceof  FileVFS) {
1561:                    file = new File(path);
1562:                    symlinkPath = MiscUtilities.resolveSymlinks(path);
1563:
1564:                    // if we don't do this, the autosave file won't be
1565:                    // deleted after a save as
1566:                    if (autosaveFile != null)
1567:                        autosaveFile.delete();
1568:                    autosaveFile = new File(file.getParent(), '#' + name + '#');
1569:                } else {
1570:                    // I wonder if the lack of this broke anything in the
1571:                    // past?
1572:                    file = null;
1573:                    autosaveFile = null;
1574:                    symlinkPath = path;
1575:                }
1576:            } //}}}
1577:
1578:            //{{{ recoverAutosave() method
1579:            private boolean recoverAutosave(final View view) {
1580:                if (!autosaveFile.canRead())
1581:                    return false;
1582:
1583:                // this method might get called at startup
1584:                GUIUtilities.hideSplashScreen();
1585:
1586:                final Object[] args = { autosaveFile.getPath() };
1587:                int result = GUIUtilities.confirm(view, "autosave-found", args,
1588:                        JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
1589:
1590:                if (result == JOptionPane.YES_OPTION) {
1591:                    VFSManager.getFileVFS().load(view, this ,
1592:                            autosaveFile.getPath());
1593:
1594:                    // show this message when all I/O requests are
1595:                    // complete
1596:                    VFSManager.runInAWTThread(new Runnable() {
1597:                        public void run() {
1598:                            GUIUtilities.message(view, "autosave-loaded", args);
1599:                        }
1600:                    });
1601:
1602:                    return true;
1603:                } else
1604:                    return false;
1605:            } //}}}
1606:
1607:            //{{{ checkFileForLoad() method
1608:            private boolean checkFileForLoad(View view, VFS vfs, String path) {
1609:                if ((vfs.getCapabilities() & VFS.LOW_LATENCY_CAP) != 0) {
1610:                    Object session = vfs.createVFSSession(path, view);
1611:                    if (session == null)
1612:                        return false;
1613:
1614:                    try {
1615:                        VFSFile file = vfs._getFile(session, path, view);
1616:                        if (file == null) {
1617:                            setNewFile(true);
1618:                            return true;
1619:                        }
1620:
1621:                        if (!file.isReadable()) {
1622:                            VFSManager.error(view, path, "ioerror.no-read",
1623:                                    null);
1624:                            setNewFile(false);
1625:                            return false;
1626:                        }
1627:
1628:                        setFileReadOnly(!file.isWriteable());
1629:
1630:                        if (file.getType() != VFSFile.FILE) {
1631:                            VFSManager.error(view, path,
1632:                                    "ioerror.open-directory", null);
1633:                            setNewFile(false);
1634:                            return false;
1635:                        }
1636:                    } catch (IOException io) {
1637:                        VFSManager.error(view, path, "ioerror",
1638:                                new String[] { io.toString() });
1639:                        return false;
1640:                    } finally {
1641:                        try {
1642:                            vfs._endVFSSession(session, view);
1643:                        } catch (IOException io) {
1644:                            VFSManager.error(view, path, "ioerror",
1645:                                    new String[] { io.toString() });
1646:                            return false;
1647:                        }
1648:                    }
1649:                }
1650:
1651:                return true;
1652:            } //}}}
1653:
1654:            //{{{ checkFileForSave() method
1655:            private static boolean checkFileForSave(View view, VFS vfs,
1656:                    String path) {
1657:                if ((vfs.getCapabilities() & VFS.LOW_LATENCY_CAP) != 0) {
1658:                    Object session = vfs.createVFSSession(path, view);
1659:                    if (session == null)
1660:                        return false;
1661:
1662:                    try {
1663:                        VFSFile file = vfs._getFile(session, path, view);
1664:                        if (file == null)
1665:                            return true;
1666:
1667:                        if (file.getType() != VFSFile.FILE) {
1668:                            VFSManager.error(view, path,
1669:                                    "ioerror.save-directory", null);
1670:                            return false;
1671:                        }
1672:                    } catch (IOException io) {
1673:                        VFSManager.error(view, path, "ioerror",
1674:                                new String[] { io.toString() });
1675:                        return false;
1676:                    } finally {
1677:                        try {
1678:                            vfs._endVFSSession(session, view);
1679:                        } catch (IOException io) {
1680:                            VFSManager.error(view, path, "ioerror",
1681:                                    new String[] { io.toString() });
1682:                            return false;
1683:                        }
1684:                    }
1685:                }
1686:
1687:                return true;
1688:            } //}}}
1689:
1690:            //{{{ finishLoading() method
1691:            private void finishLoading() {
1692:                parseBufferLocalProperties();
1693:                // AHA!
1694:                // this is probably the only way to fix this
1695:                FoldHandler oldFoldHandler = getFoldHandler();
1696:                setMode();
1697:
1698:                if (getFoldHandler() == oldFoldHandler) {
1699:                    // on a reload, the fold handler doesn't change, but
1700:                    // we still need to re-collapse folds.
1701:                    // don't do this on initial fold handler creation
1702:                    invalidateFoldLevels();
1703:
1704:                    fireFoldHandlerChanged();
1705:                }
1706:
1707:                // Create marker positions
1708:                for (int i = 0; i < markers.size(); i++) {
1709:                    Marker marker = markers.get(i);
1710:                    marker.removePosition();
1711:                    int pos = marker.getPosition();
1712:                    if (pos > getLength())
1713:                        marker.setPosition(getLength());
1714:                    else if (pos < 0)
1715:                        marker.setPosition(0);
1716:                    marker.createPosition();
1717:                }
1718:            } //}}}
1719:
1720:            //{{{ finishSaving() method
1721:            private void finishSaving(View view, String oldPath,
1722:                    String oldSymlinkPath, String path, boolean rename,
1723:                    boolean error) {
1724:                //{{{ Set the buffer's path
1725:                // Caveat: won't work if save() called with a relative path.
1726:                // But I don't think anyone calls it like that anyway.
1727:                if (!error && !path.equals(oldPath)) {
1728:                    Buffer buffer = jEdit.getBuffer(path);
1729:
1730:                    if (rename) {
1731:                        /* if we save a file with the same name as one
1732:                         * that's already open, we presume that we can
1733:                         * close the existing file, since the user
1734:                         * would have confirmed the overwrite in the
1735:                         * 'save as' dialog box anyway */
1736:                        if (buffer != null && /* can't happen? */
1737:                        !buffer.getPath().equals(oldPath)) {
1738:                            buffer.setDirty(false);
1739:                            jEdit.closeBuffer(view, buffer);
1740:                        }
1741:
1742:                        setPath(path);
1743:                    } else {
1744:                        /* if we saved over an already open file using
1745:                         * 'save a copy as', then reload the existing
1746:                         * buffer */
1747:                        if (buffer != null && /* can't happen? */
1748:                        !buffer.getPath().equals(oldPath)) {
1749:                            buffer.load(view, true);
1750:                        }
1751:                    }
1752:                } //}}}
1753:
1754:                //{{{ Update this buffer for the new path
1755:                if (rename) {
1756:                    if (file != null)
1757:                        modTime = file.lastModified();
1758:
1759:                    if (!error) {
1760:                        // we do a write lock so that the
1761:                        // autosave, which grabs a read lock,
1762:                        // is not executed between the
1763:                        // deletion of the autosave file
1764:                        // and clearing of the dirty flag
1765:                        try {
1766:                            writeLock();
1767:
1768:                            if (autosaveFile != null)
1769:                                autosaveFile.delete();
1770:
1771:                            setFlag(AUTOSAVE_DIRTY, false);
1772:                            setFileReadOnly(false);
1773:                            setFlag(NEW_FILE, false);
1774:                            setFlag(UNTITLED, false);
1775:                            super .setDirty(false);
1776:
1777:                            // this ensures that undo can clear
1778:                            // the dirty flag properly when all
1779:                            // edits up to a save are undone
1780:                            undoMgr.bufferSaved();
1781:                        } finally {
1782:                            writeUnlock();
1783:                        }
1784:
1785:                        parseBufferLocalProperties();
1786:
1787:                        if (!getPath().equals(oldPath)) {
1788:                            if (!isTemporary())
1789:                                jEdit.updatePosition(oldSymlinkPath, this );
1790:                            setMode();
1791:                        } else {
1792:                            // if user adds mode buffer-local property
1793:                            String newMode = getStringProperty("mode");
1794:                            if (newMode != null
1795:                                    && !newMode.equals(getMode().getName()))
1796:                                setMode();
1797:                            else
1798:                                propertiesChanged();
1799:                        }
1800:
1801:                        if (!isTemporary()) {
1802:                            EditBus.send(new BufferUpdate(this , view,
1803:                                    BufferUpdate.DIRTY_CHANGED));
1804:
1805:                            // new message type introduced in 4.0pre4
1806:                            EditBus.send(new BufferUpdate(this , view,
1807:                                    BufferUpdate.SAVED));
1808:                        }
1809:                    }
1810:                } //}}}
1811:            } //}}}
1812:
1813:            //{{{ editSyntaxStyle() method
1814:            /**
1815:             * Edit the syntax style of the token under the caret.
1816:             * 
1817:             * @param textArea the textarea where your caret is
1818:             * @since jEdit 4.3pre11
1819:             */
1820:            void editSyntaxStyle(JEditTextArea textArea) {
1821:                int lineNum = textArea.getCaretLine();
1822:                int start = getLineStartOffset(lineNum);
1823:                int position = textArea.getCaretPosition();
1824:
1825:                DefaultTokenHandler tokenHandler = new DefaultTokenHandler();
1826:                markTokens(lineNum, tokenHandler);
1827:                Token token = tokenHandler.getTokens();
1828:
1829:                while (token.id != Token.END) {
1830:                    int next = start + token.length;
1831:                    if (start <= position && next > position)
1832:                        break;
1833:                    start = next;
1834:                    token = token.next;
1835:                }
1836:                if (token.id == Token.END || token.id == Token.NULL) {
1837:                    JOptionPane.showMessageDialog(jEdit.getActiveView(), jEdit
1838:                            .getProperty("syntax-style-no-token.message"),
1839:                            jEdit.getProperty("syntax-style-no-token.title"),
1840:                            JOptionPane.PLAIN_MESSAGE);
1841:                    return;
1842:                }
1843:                String typeName = Token.tokenToString(token.id);
1844:                String property = "view.style." + typeName.toLowerCase();
1845:                SyntaxStyle currentStyle = GUIUtilities.parseStyle(jEdit
1846:                        .getProperty(property), "Dialog", 12);
1847:                SyntaxStyle style = new StyleEditor(jEdit.getActiveView(),
1848:                        currentStyle, typeName).getStyle();
1849:                if (style != null)
1850:                    jEdit.setProperty(property, GUIUtilities
1851:                            .getStyleString(style));
1852:                jEdit.propertiesChanged();
1853:            } //}}}
1854:            //}}}
1855:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.