/* * Fold.java * * Copyright (C) 2009-12 by RStudio, Inc. * * Unless you have received this program directly from RStudio pursuant * to the terms of a commercial license agreement with RStudio, then * this program is licensed to you under the terms of version 3 of the * GNU Affero General Public License. This program is distributed WITHOUT * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details. * */ package org.rstudio.studio.client.workbench.views.source.editors.text; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.JsArray; import com.google.gwt.core.client.JsArrayMixed; import org.rstudio.studio.client.workbench.views.source.editors.text.ace.AceFold; import org.rstudio.studio.client.workbench.views.source.editors.text.ace.Position; import org.rstudio.studio.client.workbench.views.source.editors.text.ace.Range; import java.util.ArrayList; public class Fold { public static int getCollectiveHashCode(ArrayList<Fold> folds) { int hashCode = 0; for (Fold fold : folds) { hashCode *= 31; hashCode += fold.hashCode(); } return hashCode; } public static Fold fromAceFold(AceFold fold, Position offset) { return new Fold( Position.create(fold.getStart().getRow() + offset.getRow(), fold.getStart().getColumn()), Position.create(fold.getEnd().getRow() + offset.getRow(), fold.getEnd().getColumn()), fold.getPlaceholder()); } public static String encode(ArrayList<Fold> folds) { StringBuilder result = new StringBuilder(); for (Fold f : folds) { result.append(f.getStartRow()).append('|') .append(f.getStartColumn()).append('|') .append(f.getEndRow()).append('|') .append(f.getEndColumn()).append('|') .append('\n'); } return result.toString(); } public static ArrayList<Fold> decode(String foldData) { ArrayList<Fold> results = new ArrayList<Fold>(); String[] chunks = foldData.split("\n"); for (String chunk : chunks) { if (chunk.isEmpty()) continue; String[] pieces = chunk.split("\\|"); results.add(new Fold(Integer.parseInt(pieces[0]), Integer.parseInt(pieces[1]), Integer.parseInt(pieces[2]), Integer.parseInt(pieces[3]), "..."));//pieces[4])); } return results; } public static JsArray<JsArrayMixed> toJs(ArrayList<Fold> folds) { JsArray<JsArrayMixed> results = JavaScriptObject.createArray().cast(); for (Fold f : folds) { JsArrayMixed foldData = JavaScriptObject.createArray().cast(); foldData.set(0, f.getStartRow()); foldData.set(1, f.getStartColumn()); foldData.set(2, f.getEndRow()); foldData.set(3, f.getEndColumn()); foldData.set(4, f.getPlaceholder()); results.push(foldData); } return results; } public static ArrayList<Fold> fromJs(JsArray<JsArrayMixed> folds) { ArrayList<Fold> results = new ArrayList<Fold>(); for (int i = 0; i < folds.length(); i++) { JsArrayMixed foldData = folds.get(i); results.add(new Fold((int)foldData.getNumber(0), (int)foldData.getNumber(1), (int)foldData.getNumber(2), (int)foldData.getNumber(3), foldData.getString(4))); } return results; } /** * Puts the input ace folds, and their subfolds (recursively), into a flat * list of Fold objects. */ public static ArrayList<Fold> flatten(JsArray<AceFold> folds) { ArrayList<Fold> results = new ArrayList<Fold>(); for (int i = 0; i < folds.length(); i++) collect(folds.get(i), results, Position.create(0, 0)); return results; } private static void collect(AceFold fold, ArrayList<Fold> results, Position parentOffset) { results.add(fromAceFold(fold, parentOffset)); JsArray<AceFold> subFolds = fold.getSubFolds(); for (int i = 0; i < subFolds.length(); i++) { AceFold subFold = subFolds.get(i); Position offset = Position.create( fold.getStart().getRow() + parentOffset.getRow(), fold.getStart().getColumn() + parentOffset.getColumn()); collect(subFold, results, offset); } } public Fold(Position start, Position end, String placeholder) { this(start.getRow(), start.getColumn(), end.getRow(), end.getColumn(), placeholder); } public Fold(int startRow, int startColumn, int endRow, int endColumn, String placeholder) { startRow_ = startRow; startColumn_ = startColumn; endRow_ = endRow; endColumn_ = endColumn; placeholder_ = placeholder; } public int getStartRow() { return startRow_; } public int getStartColumn() { return startColumn_; } public int getEndRow() { return endRow_; } public int getEndColumn() { return endColumn_; } public String getPlaceholder() { return placeholder_; } public Range getRange() { return Range.fromPoints( Position.create(getStartRow(), getStartColumn()), Position.create(getEndRow(), getEndColumn())); } public AceFold toAceFold() { return AceFold.createFold(getRange(), placeholder_); } @Override public int hashCode() { int hashCode = startRow_; hashCode *= 31; hashCode += startColumn_; hashCode *= 31; hashCode += endRow_; hashCode *= 31; hashCode += endColumn_; hashCode *= 31; hashCode += placeholder_.hashCode(); return hashCode; } private final int startRow_; private final int startColumn_; private final int endRow_; private final int endColumn_; private final String placeholder_; }