/* * BufferSetManager.java - Manages the buffersets. * :tabSize=4:indentSize=4:noTabs=false: * :folding=explicit:collapseFolds=1: * * Copyright (C) 2008, 2010 Matthieu Casanova * * 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.bufferset; //{{{ Imports import org.gjt.sp.jedit.*; import org.gjt.sp.jedit.io.VFS; import org.gjt.sp.jedit.io.VFSManager; import org.gjt.sp.jedit.msg.EditPaneUpdate; import org.gjt.sp.jedit.msg.PropertiesChanged; import org.gjt.sp.jedit.visitors.JEditVisitorAdapter; import org.gjt.sp.util.Log; import org.gjt.sp.jedit.EditBus.EBHandler; import java.util.*; //}}} /** * The buffersets manager. A singleton instance of this * can be obtained from jEdit.getBufferSetManager() * * @author Matthieu Casanova * @since jEdit 4.3pre15 */ public class BufferSetManager { //{{{ BufferSetManager constructor public BufferSetManager() { EditBus.addToBus(this); try { scope = BufferSet.Scope.valueOf(jEdit.getProperty("bufferset.scope", "global")); } catch (IllegalArgumentException e) { Log.log(Log.ERROR, this, e); scope = BufferSet.Scope.global; } } //}}} //{{{ handleEditPaneUpdate() method @EBHandler public void handleEditPaneUpdate(EditPaneUpdate message) { if (message.getWhat() == EditPaneUpdate.DESTROYED) { EditPane editPane = message.getEditPane(); BufferSet bufferSet = editPane.getBufferSet(); Buffer[] allBuffers = bufferSet.getAllBuffers(); for (Buffer buffer : allBuffers) { _removeBuffer(bufferSet, buffer); } } } //}}} //{{{ handlePropertiesChanged() method @EBHandler public void handlePropertiesChanged(PropertiesChanged msg) { // pass on PropertiesChanged message to BufferSets so // they can resort themselves as needed. jEdit.visit(new JEditVisitorAdapter() { @Override public void visit(EditPane editPane) { editPane.getBufferSet().propertiesChanged(); } }); } //}}} //{{{ countBufferSets() method /** * Count the bufferSets in which the buffer is. * @param buffer the buffer * @return the number of buffersets in which buffer is * @see org.gjt.sp.jedit.jEdit#closeBuffer(org.gjt.sp.jedit.EditPane, org.gjt.sp.jedit.Buffer) */ public int countBufferSets(Buffer buffer) { return getOwners(buffer).size(); } //}}} //{{{ setScope() method public void setScope(BufferSet.Scope scope) { if (scope == this.scope) return; jEdit.setProperty("bufferset.scope", scope.name()); if (scope.compareTo(this.scope) > 0) { // The new scope is wider if (scope == BufferSet.Scope.global) { final Buffer[] buffers = jEdit.getBuffers(); jEdit.visit(new JEditVisitorAdapter() { @Override public void visit(EditPane editPane) { BufferSet bufferSet = editPane.getBufferSet(); for (Buffer buffer : buffers) { bufferSet.addBuffer(buffer); } } }); } else { final Map<View,Set<Buffer>> buffersMap = new HashMap<View, Set<Buffer>>(); jEdit.visit(new JEditVisitorAdapter() { @Override public void visit(EditPane editPane) { BufferSet bufferSet = editPane.getBufferSet(); Buffer[] buffers = bufferSet.getAllBuffers(); Set<Buffer> set = buffersMap.get(editPane.getView()); if (set == null) { set = new HashSet<Buffer>(); buffersMap.put(editPane.getView(), set); } set.addAll(Arrays.asList(buffers)); } }); jEdit.visit(new JEditVisitorAdapter() { @Override public void visit(EditPane editPane) { BufferSet bufferSet = editPane.getBufferSet(); Set<Buffer> set = buffersMap.get(editPane.getView()); for (Buffer buffer : set) { bufferSet.addBuffer(buffer); } } }); } } this.scope = scope; EditBus.send(new PropertiesChanged(this)); } //}}} //{{{ getScope() method public BufferSet.Scope getScope() { return scope; } //}}} //{{{ addBuffer() methods /** * Add a buffer into the current editPane of the given view. * If the view is null, it will be added to the current * editPane of the active view. * @param view a view (or null) * @param buffer the buffer to add */ public void addBuffer(View view, Buffer buffer) { EditPane editPane = view == null ? null : view.getEditPane(); addBuffer(editPane, buffer); } /** * Add a buffer into the given editPane. * If the editPane is null, it will be added to the current * editPane of the active view. * @param editPane an EditPane (or null) * @param buffer the buffer to add */ public void addBuffer(EditPane editPane, final Buffer buffer) { if (editPane == null) { editPane = jEdit.getActiveView().getEditPane(); } BufferSet bufferSet = editPane.getBufferSet(); switch (scope) { case editpane: bufferSet.addBuffer(buffer); break; case view: EditPane[] editPanes = editPane.getView().getEditPanes(); for (EditPane pane:editPanes) { if (pane == null) continue; BufferSet bfs = pane.getBufferSet(); bfs.addBuffer(buffer); } break; case global: jEdit.visit(new JEditVisitorAdapter() { @Override public void visit(EditPane editPane) { BufferSet bfs = editPane.getBufferSet(); bfs.addBuffer(buffer); } }); } } //}}} //{{{ moveBuffer() method /** * Moves a buffer from a old position to a new position in the * BufferSet used in an EditPane. */ public void moveBuffer(EditPane editPane, int oldPosition, int newPosition) { editPane.getBufferSet().moveBuffer(oldPosition, newPosition); } //}}} //{{{ removeBuffer() methods /** * Remove a buffer from the EditPane's bufferSet. * * @param editPane the editPane It cannot be null * @param buffer the buffer */ public void removeBuffer(EditPane editPane, Buffer buffer) { switch (scope) { case editpane: BufferSet bufferSet = editPane.getBufferSet(); removeBuffer(bufferSet, buffer); break; case view: EditPane[] editPanes = editPane.getView().getEditPanes(); for (EditPane pane : editPanes) { removeBuffer(pane.getBufferSet(), buffer); } break; case global: jEdit._closeBuffer(null, buffer); break; } } /** * Remove a buffer from a bufferSet. * And make sure that the bufferSet is not empty after that * * @param bufferSet the bufferSet * @param buffer the buffer that will be removed */ void removeBuffer(BufferSet bufferSet, Buffer buffer) { Log.log(Log.DEBUG, this, "removeBuffer("+bufferSet+','+buffer+')'); _removeBuffer(bufferSet, buffer); bufferRemoved(bufferSet); } /** * remove a buffer from all bufferSets. * * @param buffer the buffer that must be removed */ public void removeBuffer(Buffer buffer) { for (BufferSet bufferSet : getOwners(buffer)) { bufferSet.removeBuffer(buffer); bufferRemoved(bufferSet); } } //}}} //{{{ bufferRemoved() method /** * This method is called when a buffer has been removed from a bufferSet. * If it is empty, an untitled buffer is created and added to the bufferSet * @param bufferSet the bufferSet from which the buffer was removed */ private void bufferRemoved(BufferSet bufferSet) { if (bufferSet.size() == 0) { Buffer newEmptyBuffer = createUntitledBuffer(); EditPane editPaneOwner = getOwner(bufferSet); addBuffer(editPaneOwner, newEmptyBuffer); } } //}}} //{{{ _removeBuffer() method /** * Remove a buffer from a bufferSet. * Used when closing an EditPane * * @param bufferSet the bufferSet * @param buffer the buffer that will be removed */ private void _removeBuffer(BufferSet bufferSet, Buffer buffer) { Set<BufferSet> owners = getOwners(buffer); owners.remove(bufferSet); bufferSet.removeBuffer(buffer); if (owners.isEmpty()) { Log.log(Log.DEBUG, this, "Buffer:"+buffer+" is in no bufferSet anymore, closing it"); jEdit._closeBuffer(null, buffer); } } //}}} //{{{ createUntitledBuffer() method /** * Create an untitled buffer * @return the new untitled buffer */ public static Buffer createUntitledBuffer() { int untitledCount = jEdit.getNextUntitledBufferId(); View view = jEdit.getActiveView(); String parent = null; if (view != null) { Buffer buffer = view.getBuffer(); parent = buffer.getDirectory(); } if (parent == null) { parent = System.getProperty("user.home"); } VFS vfs = VFSManager.getVFSForPath(parent); if ((vfs.getCapabilities() & VFS.WRITE_CAP) == 0) { // cannot write on that VFS, creating untitled buffer in home directory parent = System.getProperty("user.home"); } Buffer newEmptyBuffer = jEdit.openTemporary(view, parent, "Untitled-" + untitledCount,true, null); jEdit.commitTemporary(newEmptyBuffer); return newEmptyBuffer; } //}}} //{{{ Private members //{{{ getOwners() method /** * @return set of BufferSets that contain buffer * @since 4.4pre1 */ public Set<BufferSet> getOwners(Buffer buffer) { final Set<BufferSet> candidates = new HashSet<BufferSet>(); // Collect all BufferSets. jEdit.visit(new JEditVisitorAdapter() { @Override public void visit(EditPane editPane) { candidates.add(editPane.getBufferSet()); } }); // Remove all that doesn't contain the buffer. Iterator<BufferSet> i = candidates.iterator(); while (i.hasNext()) { if (i.next().indexOf(buffer) == -1) { i.remove(); } } // Remaining are the result. return candidates; } //}}} //{{{ getOwner() method /** * Return the editpane that owns the BufferSet * @param bufferSet the bufferSet * @return the owner of the given bufferSet */ private static EditPane getOwner(BufferSet bufferSet) { View[] views = jEdit.getViews(); for (View view : views) { EditPane[] editPanes = view.getEditPanes(); for (EditPane editPane : editPanes) { if (editPane.getBufferSet() == bufferSet) { return editPane; } } } return null; } //}}} /** The scope of the bufferSets. */ private BufferSet.Scope scope; //}}} }