|
From: Christopher W. <caw...@us...> - 2006-06-09 01:19:20
|
Update of /cvsroot/rubyeclipse/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/folding In directory sc8-pr-cvs9.sourceforge.net:/tmp/cvs-serv7890/src/org/rubypeople/rdt/internal/ui/text/folding Modified Files: DefaultRubyFoldingStructureProvider.java Log Message: Add a folding action menu to context ruler on left side of editor, and add command shortcuts for actions to manipulatae folding. Now users can collapse/expand all, comments, members, reset structure, etc. Index: DefaultRubyFoldingStructureProvider.java =================================================================== RCS file: /cvsroot/rubyeclipse/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/folding/DefaultRubyFoldingStructureProvider.java,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** DefaultRubyFoldingStructureProvider.java 10 Feb 2006 19:55:23 -0000 1.6 --- DefaultRubyFoldingStructureProvider.java 9 Jun 2006 01:19:17 -0000 1.7 *************** *** 5,16 **** --- 5,19 ---- import java.util.ArrayList; + import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; + import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; + import java.util.Set; import org.eclipse.jface.preference.IPreferenceStore; *************** *** 48,51 **** --- 51,55 ---- import org.rubypeople.rdt.ui.PreferenceConstants; import org.rubypeople.rdt.ui.text.folding.IRubyFoldingStructureProvider; + import org.rubypeople.rdt.ui.text.folding.IRubyFoldingStructureProviderExtension; /** *************** *** 53,57 **** */ public class DefaultRubyFoldingStructureProvider implements IProjectionListener, ! IRubyFoldingStructureProvider { private ITextEditor fEditor; --- 57,61 ---- */ public class DefaultRubyFoldingStructureProvider implements IProjectionListener, ! IRubyFoldingStructureProvider, IRubyFoldingStructureProviderExtension { private ITextEditor fEditor; *************** *** 679,681 **** --- 683,800 ---- } + + /* filters */ + /** + * Filter for annotations. + * @since 0.9.0 + */ + private static interface Filter { + boolean match(RubyProjectionAnnotation annotation); + } + + private static final class RubyElementSetFilter implements Filter { + private final Set fSet; + private final boolean fMatchCollapsed; + + private RubyElementSetFilter(Set set, boolean matchCollapsed) { + fSet= set; + fMatchCollapsed= matchCollapsed; + } + + public boolean match(RubyProjectionAnnotation annotation) { + boolean stateMatch= fMatchCollapsed == annotation.isCollapsed(); + if (stateMatch && !annotation.isComment() && !annotation.isMarkedDeleted()) { + IRubyElement element= annotation.getElement(); + if (fSet.contains(element)) { + return true; + } + } + return false; + } + } + /** + * Member filter, matches nested members (but not top-level types). + * @since 0.9.0 + */ + private final Filter fMemberFilter = new Filter() { + public boolean match(RubyProjectionAnnotation annotation) { + if (!annotation.isCollapsed() && !annotation.isComment() && !annotation.isMarkedDeleted()) { + IRubyElement element= annotation.getElement(); + if (element instanceof IMember) { + if (element.getElementType() != IRubyElement.TYPE || ((IMember) element).getDeclaringType() != null) { + return true; + } + } + } + return false; + } + }; + + /** + * Comment filter, matches comments. + * @since 0.9.0 + */ + private final Filter fCommentFilter = new Filter() { + public boolean match(RubyProjectionAnnotation annotation) { + if (!annotation.isCollapsed() && annotation.isComment() && !annotation.isMarkedDeleted()) { + return true; + } + return false; + } + }; + + public void collapseMembers() { + modifyFiltered(fMemberFilter, false); + } + + public void collapseComments() { + modifyFiltered(fCommentFilter, false); + } + + public void collapseElements(IRubyElement[] elements) { + Set set= new HashSet(Arrays.asList(elements)); + modifyFiltered(new RubyElementSetFilter(set, false), false); + } + + public void expandElements(IRubyElement[] elements) { + Set set= new HashSet(Arrays.asList(elements)); + modifyFiltered(new RubyElementSetFilter(set, true), true); + } + + /** + * Collapses all annotations matched by the passed filter. + * + * @param filter the filter to use to select which annotations to collapse + * @param expand <code>true</code> to expand the matched annotations, <code>false</code> to + * collapse them + * @since 0.9.0 + */ + private void modifyFiltered(Filter filter, boolean expand) { + if (!isInstalled()) + return; + + ProjectionAnnotationModel model= (ProjectionAnnotationModel) fEditor.getAdapter(ProjectionAnnotationModel.class); + if (model == null) + return; + + List modified= new ArrayList(); + Iterator iter= model.getAnnotationIterator(); + while (iter.hasNext()) { + Object annotation= iter.next(); + if (annotation instanceof RubyProjectionAnnotation) { + RubyProjectionAnnotation java= (RubyProjectionAnnotation) annotation; + + if (filter.match(java)) { + if (expand) + java.markExpanded(); + else + java.markCollapsed(); + modified.add(java); + } + + } + } + + model.modifyAnnotations(null, null, (Annotation[]) modified.toArray(new Annotation[modified.size()])); + } } |