📄 buffer.java
字号:
/* * Buffer.java - jEdit buffer * Copyright (C) 1998, 1999, 2000, 2001 Slava Pestov * Portions copyright (C) 1999, 2000 mike dillon * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */package org.gjt.sp.jedit;import gnu.regexp.*;import javax.swing.*;import javax.swing.event.*;import javax.swing.text.*;import javax.swing.undo.*;import java.awt.*;import java.io.File;import java.util.*;import org.gjt.sp.jedit.browser.VFSBrowser;import org.gjt.sp.jedit.io.*;import org.gjt.sp.jedit.msg.*;import org.gjt.sp.jedit.search.RESearchMatcher;import org.gjt.sp.jedit.syntax.*;import org.gjt.sp.jedit.textarea.*;import org.gjt.sp.util.Log;/** * An in-memory copy of an open file.<p> * * Buffers extend Swing document properties to obtain the default values * from jEdit's global properties. * * @author Slava Pestov * @version $Id: Buffer.java,v 1.1.1.1 2001/09/02 05:37:06 spestov Exp $ */public class Buffer extends PlainDocument implements EBComponent{ /** * Line separator property. */ public static final String LINESEP = "lineSeparator"; /** * Backed up property. * @since jEdit 3.2pre2 */ public static final String BACKED_UP = "Buffer__backedUp"; /** * Caret info properties. * @since jEdit 3.2pre1 */ public static final String CARET = "Buffer__caret"; public static final String SELECTION = "Buffer__selection"; public static final String SCROLL_VERT = "Buffer__scrollVert"; public static final String SCROLL_HORIZ = "Buffer__scrollHoriz"; /** * Character encoding used when loading and saving. * @since jEdit 3.2pre4 */ public static final String ENCODING = "encoding"; /** * Reloads settings from the properties. This should be called * after the <code>syntax</code> buffer-local property is * changed. */ public void propertiesChanged() { if(getBooleanProperty("syntax")) setTokenMarker(mode.getTokenMarker()); else setTokenMarker(jEdit.getMode("text").getTokenMarker()); if(undo != null) { try { undo.setLimit(Integer.parseInt(jEdit.getProperty( "buffer.undoCount"))); } catch(NumberFormatException nf) { undo.setLimit(100); } } // cache these for improved performance putProperty("tabSize",getProperty("tabSize")); putProperty("maxLineLen",getProperty("maxLineLen")); } /** * Displays the 'insert file' dialog box and inserts the selected file * into the buffer. * @param view The view * @since jEdit 2.7pre2 */ public void showInsertFileDialog(View view) { String[] files = GUIUtilities.showVFSFileDialog(view,null, VFSBrowser.OPEN_DIALOG,false); if(files != null) insert(view,files[0]); } /** * Prints the buffer. * @param view The view * @since jEdit 2.7pre2 */ public void print(View view) { PrintJob job = view.getToolkit().getPrintJob(view,name,null); if(job == null) return; view.showWaitCursor(); int topMargin; int leftMargin; int bottomMargin; int rightMargin; int ppi = job.getPageResolution(); try { topMargin = (int)(Float.valueOf(jEdit.getProperty( "print.margin.top")).floatValue() * ppi); } catch(NumberFormatException nf) { topMargin = ppi / 2; } try { leftMargin = (int)(Float.valueOf(jEdit.getProperty( "print.margin.left")).floatValue() * ppi); } catch(NumberFormatException nf) { leftMargin = ppi / 2; } try { bottomMargin = (int)(Float.valueOf(jEdit.getProperty( "print.margin.bottom")).floatValue() * ppi); } catch(NumberFormatException nf) { bottomMargin = topMargin; } try { rightMargin = (int)(Float.valueOf(jEdit.getProperty( "print.margin.right")).floatValue() * ppi); } catch(NumberFormatException nf) { rightMargin = leftMargin; } boolean printHeader = jEdit.getBooleanProperty("print.header"); boolean printFooter = jEdit.getBooleanProperty("print.footer"); boolean printLineNumbers = jEdit.getBooleanProperty("print.lineNumbers"); boolean syntax = jEdit.getBooleanProperty("print.syntax"); String header = path; String footer = new Date().toString(); int lineCount = getDefaultRootElement().getElementCount(); TabExpander expander = null; Graphics gfx = null; String fontFamily = jEdit.getProperty("print.font"); int fontSize; try { fontSize = Integer.parseInt(jEdit.getProperty( "print.fontsize")); } catch(NumberFormatException nf) { fontSize = 10; } int fontStyle; try { fontStyle = Integer.parseInt(jEdit.getProperty( "print.fontstyle")); } catch(NumberFormatException nf) { fontStyle = Font.PLAIN; } SyntaxStyle[] styles = GUIUtilities.loadStyles(fontFamily,fontSize); boolean style = jEdit.getBooleanProperty("print.style"); boolean color = jEdit.getBooleanProperty("print.color"); Font font = new Font(fontFamily,fontStyle,fontSize); FontMetrics fm = null; Dimension pageDimension = job.getPageDimension(); int pageWidth = pageDimension.width; int pageHeight = pageDimension.height; int y = 0; int tabSize = 0; int lineHeight = 0; int page = 0; int lineNumberDigits = (int)Math.ceil(Math.log( lineCount) / Math.log(10)); int lineNumberWidth = 0; TextRenderer renderer = TextRenderer.createPrintTextRenderer(); renderer.configure(false,false); for(int i = 0; i < lineCount; i++) { if(gfx == null) { page++; gfx = job.getGraphics(); renderer.setupGraphics(gfx); gfx.setFont(font); fm = gfx.getFontMetrics(); if(printLineNumbers) { lineNumberWidth = fm.charWidth('0') * lineNumberDigits; } else lineNumberWidth = 0; lineHeight = fm.getHeight(); tabSize = getTabSize() * fm.charWidth(' '); expander = new PrintTabExpander(leftMargin + lineNumberWidth,tabSize); y = topMargin + lineHeight - fm.getDescent() - fm.getLeading(); if(printHeader) { gfx.setColor(Color.lightGray); gfx.fillRect(leftMargin,topMargin,pageWidth - leftMargin - rightMargin,lineHeight); gfx.setColor(Color.black); gfx.drawString(header,leftMargin,y); y += lineHeight; } } y += lineHeight; gfx.setColor(Color.black); gfx.setFont(font); int x = leftMargin; if(printLineNumbers) { String lineNumber = String.valueOf(i + 1); gfx.drawString(lineNumber,(leftMargin + lineNumberWidth) - fm.stringWidth(lineNumber),y); x += lineNumberWidth + fm.charWidth('0'); } paintSyntaxLine(i,gfx,x,y,expander,style,color, font,Color.black,Color.white,styles, renderer); int bottomOfPage = pageHeight - bottomMargin - lineHeight; if(printFooter) bottomOfPage -= lineHeight * 2; if(y >= bottomOfPage || i == lineCount - 1) { if(printFooter) { y = pageHeight - bottomMargin; gfx.setColor(Color.lightGray); gfx.setFont(font); gfx.fillRect(leftMargin,y - lineHeight,pageWidth - leftMargin - rightMargin,lineHeight); gfx.setColor(Color.black); y -= (lineHeight - fm.getAscent()); gfx.drawString(footer,leftMargin,y); Integer[] args = { new Integer(page) }; String pageStr = jEdit.getProperty("print.page",args); int width = fm.stringWidth(pageStr); gfx.drawString(pageStr,pageWidth - rightMargin - width,y); } gfx.dispose(); gfx = null; } } job.end(); view.hideWaitCursor(); } /** * Reloads the buffer from disk, asking for confirmation if the buffer * is dirty. * @param view The view * @since jEdit 2.7pre2 */ public void reload(View view) { if(getFlag(DIRTY)) { String[] args = { name }; int result = GUIUtilities.confirm(view,"changedreload", args,JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); if(result != JOptionPane.YES_OPTION) return; } view.getEditPane().saveCaretInfo(); load(view,true); } /** * Loads the buffer from disk, even if it is loaded already. * @param view The view * @param reload If true, user will not be asked to recover autosave * file, if any * * @since 2.5pre1 */ public boolean load(final View view, final boolean reload) { if(isPerformingIO()) { GUIUtilities.error(view,"buffer-multiple-io",null); return false; } setFlag(LOADING,true); // view text areas temporarily blank out while a buffer is // being loaded, to indicate to the user that there is no // data available yet. EditBus.send(new BufferUpdate(this,view,BufferUpdate.LOAD_STARTED)); undo = null; final boolean loadAutosave; if(reload || !getFlag(NEW_FILE)) { if(file != null) modTime = file.lastModified(); // Only on initial load if(!reload && autosaveFile != null && autosaveFile.exists()) loadAutosave = recoverAutosave(view); else { if(autosaveFile != null) autosaveFile.delete(); loadAutosave = false; } if(!loadAutosave) { // this returns false if initial sanity // checks (if the file is a directory, etc) // fail if(!vfs.load(view,this,path)) { setFlag(LOADING,false); return false; } } } else loadAutosave = false; // Do some stuff once loading is finished Runnable runnable = new Runnable() { public void run() { StringBuffer sbuf = (StringBuffer)getProperty( BufferIORequest.LOAD_DATA); if(sbuf != null) { try { // For `reload' command remove(0,getLength()); insertString(0,sbuf.toString(),null); } catch(BadLocationException bl) { bl.printStackTrace(); } } // reload maxLineLen and tabSize // from the global/mode properties getDocumentProperties().remove("tabSize"); getDocumentProperties().remove("indentSize"); getDocumentProperties().remove("maxLineLen"); getDocumentProperties().remove( BufferIORequest.LOAD_DATA); undo = new MyUndoManager(); try { undo.setLimit(Integer.parseInt( jEdit.getProperty( "buffer.undoCount"))); } catch(NumberFormatException nf) { undo.setLimit(100); } setMode(); setFlag(LOADING,false); // if reloading a file, clear dirty flag if(reload) setDirty(false); // if loadAutosave is false, we loaded an // autosave file, so we set 'dirty' to true // note that we don't use setDirty(), // because a) that would send an unnecessary // message, b) it would also set the // AUTOSAVE_DIRTY flag, which will make // the autosave thread write out a // redundant autosave file if(loadAutosave) setFlag(DIRTY,true); if(jEdit.getBooleanProperty("parseFully")) { for(int i = 0; i < lineCount; i++) markTokens(i); } try { int collapseFolds = ((Integer) getProperty("collapseFolds")) .intValue(); if(collapseFolds != 0) expandFolds(collapseFolds); } catch(Exception e) { } // send some EditBus messages if(!getFlag(TEMPORARY)) { EditBus.send(new BufferUpdate(Buffer.this, view,BufferUpdate.LOADED)); EditBus.send(new BufferUpdate(Buffer.this, view,BufferUpdate.MARKERS_CHANGED)); } } }; if(getFlag(TEMPORARY)) runnable.run(); else VFSManager.runInAWTThread(runnable); return true; } /** * Loads a file from disk, and inserts it into this buffer. * @param view The view * * @since 2.7pre1 */ public boolean insert(final View view, String path) { if(isPerformingIO()) { GUIUtilities.error(view,"buffer-multiple-io",null); return false; } if(!MiscUtilities.isURL(path)) path = MiscUtilities.constructPath(this.path,path); Buffer buffer = jEdit.getBuffer(path); if(buffer != null) { try { view.getTextArea().setSelectedText( buffer.getText(0,buffer.getLength())); } catch(BadLocationException bl) { bl.printStackTrace(); } return true; } VFS vfs = VFSManager.getVFSForPath(path); setFlag(IO,true); // this returns false if initial sanity // checks (if the file is a directory, etc) // fail if(!vfs.insert(view,this,path)) { setFlag(IO,false); return false; } // Do some stuff once loading is finished VFSManager.runInAWTThread(new Runnable() { public void run() { setFlag(IO,false); StringBuffer sbuf = (StringBuffer)getProperty( BufferIORequest.LOAD_DATA); if(sbuf != null) { getDocumentProperties().remove( BufferIORequest.LOAD_DATA); view.getTextArea().setSelectedText(sbuf.toString()); } } }); return true; } /** * Autosaves this buffer. */ public void autosave() { if(autosaveFile == null || !getFlag(AUTOSAVE_DIRTY) || !getFlag(DIRTY) || getFlag(LOADING) || getFlag(IO)) return; setFlag(AUTOSAVE_DIRTY,false); VFSManager.runInWorkThread(new BufferIORequest( BufferIORequest.AUTOSAVE,null,this,null, VFSManager.getFileVFS(),autosaveFile.getPath())); } /** * Prompts the user for a file to save this buffer to. * @param view The view * @param rename True if the buffer's path should be changed, false
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -