Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/* -*- tab-width: 4 -*-
*
* Electric(tm) VLSI Design System
*
* File: Undo.java
*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
*
* Electric(tm) 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 3 of the License, or
* (at your option) any later version.
*
* Electric(tm) 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 Electric(tm); see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, Mass 02111-1307, USA.
*/
package com.sun.electric.database.change;
import com.sun.electric.database.Snapshot;
import com.sun.electric.database.hierarchy.Cell;
import com.sun.electric.tool.Job;
import com.sun.electric.tool.JobException;
import com.sun.electric.tool.Tool;
import com.sun.electric.tool.user.User;
import java.util.ArrayList;
import java.util.List;
/**
* This interface defines changes that are made to the database.
*/
public class Undo {
/**
* Class to describe a batch of changes to the Electric database.
*/
private static class ChangeBatch {
private int oldSnapshotId, newSnapshotId;
private Tool tool;
private String activity;
private int startingHighlights = -1; // highlights before changes made
private int preUndoHighlights = -1; // highlights before undo of changes done
private ChangeBatch(Snapshot oldSnapshot, Tool tool, String activity, int startingHighlights, Snapshot newSnapshot) {
oldSnapshotId = oldSnapshot.snapshotId;
this.tool = tool;
this.activity = activity;
this.startingHighlights = startingHighlights;
newSnapshotId = newSnapshot.snapshotId;
}
public int getStartingHighlights() {
return startingHighlights;
}
public int getPreUndoHighlights() {
return preUndoHighlights;
}
/**
* Method to return the Tool associated with this ChangeBatch.
* @return the Tool associated with this ChangeBatch.
*/
public Tool getTool() {
return tool;
}
private void describe(String title) {
String activityFromTool = activity;
if (tool != null) {
activityFromTool += " from " + tool.getName() + " tool";
}
String message = "*** Batch '" + title + "', " + oldSnapshotId + "->" + newSnapshotId + " (" + activityFromTool + ")";
System.out.println(message);
}
}
private static int maximumBatches = User.getMaxUndoHistory();
private static final List doneList = new ArrayList();
private static final List undoneList = new ArrayList();
/**
* Method to terminate the current batch of changes.
*/
public static int endChanges(Snapshot oldSnapshot, Tool tool, String activity, Snapshot newSnapshot) {
int highlights = Job.getExtendedUserInterface().saveHighlights();
int oldId = oldSnapshot.snapshotId;
int newId = newSnapshot.snapshotId;
while (!doneList.isEmpty() && doneList.get(doneList.size() - 1).newSnapshotId != oldId) {
doneList.remove(doneList.size() - 1);
}
while (!undoneList.isEmpty() && undoneList.get(0).oldSnapshotId != oldId) {
undoneList.remove(0);
}
int doneIndex = indexOf(doneList, newId);
int undoneIndex = indexOf(undoneList, newId);
if (doneIndex >= 0) {
// undo
while (doneList.size() > doneIndex) {
ChangeBatch batch = doneList.remove(doneList.size() - 1);
System.out.println("Undoing: " + batch.activity);
batch.preUndoHighlights = highlights;
highlights = batch.startingHighlights;
undoneList.add(0, batch);
}
Job.getExtendedUserInterface().restoreHighlights(highlights);
} else if (undoneIndex >= 0) {
// redo
for (int i = 0; i < undoneIndex; i++) {
ChangeBatch batch = undoneList.remove(0);
System.out.println("Redoing: " + batch.activity);
batch.startingHighlights = highlights;
highlights = batch.preUndoHighlights;
doneList.add(batch);
}
Job.getExtendedUserInterface().restoreHighlights(highlights);
} else {
// change task
undoneList.clear();
doneList.add(new ChangeBatch(oldSnapshot, tool, activity, highlights, newSnapshot));
highlights = -1;
}
updateUndoRedo();
return highlights;
}
private static void invalidate(int snapshotId) {
int doneIndex = indexOf(doneList, snapshotId);
int undoneIndex = indexOf(undoneList, snapshotId);
if (doneIndex >= 0) {
// undo
if (doneIndex == 0) {
doneList.clear();
} else {
while (doneList.size() >= doneIndex) {
doneList.remove(doneList.size() - 1);
}
}
}
if (undoneIndex >= 0) {
// redo
if (undoneIndex == undoneList.size()) {
undoneList.clear();
} else {
for (int i = 0; i < undoneIndex; i++) {
if (!undoneList.isEmpty()) {
undoneList.remove(0);
}
}
}
}
updateUndoRedo();
}
private static int indexOf(List list, int snapshotId) {
for (int i = 0; i < list.size(); i++) {
ChangeBatch batch = list.get(i);
if (batch.oldSnapshotId == snapshotId) {
return i;
}
if (batch.newSnapshotId == snapshotId) {
return i + 1;
}
}
return -1;
}
private static void updateUndoRedo() {
// Ignore status if editing a text cell (the text window reports correct undo/redo status)
Cell cell = Job.getUserInterface().getCurrentCell();
if (cell != null && cell.getView().isTextView()) {
return;
}
Job.getExtendedUserInterface().showUndoRedoStatus(!doneList.isEmpty(), !undoneList.isEmpty());
}
public static String getUndoActivity() {
//return doneList.get(doneList.size() - 1).activity;}
if (!doneList.isEmpty()) {
return doneList.get(doneList.size() - 1).activity;
}
System.out.println("Nothing left to undo");
return "";
}
public static void removeLastChangeBatchTask()
{
if (!doneList.isEmpty())
{
ChangeBatch task = doneList.get(doneList.size() - 1);
invalidate(task.oldSnapshotId);
}
}
/**
* Method to undo a change.
*/
public static void undo() {
if (!doneList.isEmpty()) {
new UndoJob("Undo", doneList.get(doneList.size() - 1).oldSnapshotId);
} else {
System.out.println("Undo failed");
}
}
/**
* Method to redo a change.
*/
public static void redo() {
if (!undoneList.isEmpty()) {
new UndoJob("Redo", undoneList.get(0).newSnapshotId);
} else {
System.out.println("Redo failed");
}
}
/**
* Class to schedule an undo in a separate Job.
*/
public static class UndoJob extends Job {
int snapshotId;
public UndoJob(String jobName, int snapshotId) {
super(jobName, User.getUserTool(), Job.Type.UNDO, null, null, Job.Priority.USER);
this.snapshotId = snapshotId;
startJob();
}
public int getSnapshotId() {
return snapshotId;
}
public boolean doIt() throws JobException {
// must not be called.
throw new IllegalStateException();
}
public void terminateFail(Throwable e) {
invalidate(snapshotId);
super.terminateFail(e);
}
}
// /**
// * Method to undo the last batch of changes.
// * @return the batch number that was undone.
// * Returns null if nothing was undone.
// */
// public static int undoABatch(int savedHighlights) throws JobException
// {
// // get the most recent batch of changes
// int listSize = doneList.size();
// if (listSize == 0) return null;
// ChangeBatch batch = (ChangeBatch)doneList.get(listSize-1);
// doneList.remove(listSize-1);
// undoneList.add(batch);
// updateUndoRedo();
//
// // save pre undo highlights
// batch.preUndoHighlights = savedHighlights;
//
// // look through the changes in this batch
// Job.undo(batch.oldSnapshotId);
//
// // Put message in Message Window
// System.out.println("Undoing: " + batch.activity);
//// batch.describe("Undo");
// return batch;
// }
//
// /**
// * Method to redo the last batch of changes.
// * @return true if a batch was redone.
// */
// public static ChangeBatch redoABatch() throws JobException
// {
// // get the most recent batch of changes
// int listSize = undoneList.size();
// if (listSize == 0) return null;
// ChangeBatch batch = undoneList.get(listSize-1);
// undoneList.remove(listSize-1);
// doneList.add(batch);
// updateUndoRedo();
//
// Job.undo(batch.newSnapshotId);
//
// // Put message in Message Window
// System.out.println("Redoing: " + batch.activity);
//// batch.describe("Redo");
// return batch;
// }
//
// /**
// * Method to prevent undo by deleting all change batches.
// */
// public static void noUndoAllowed()
// {
// // kill them all
// doneList.clear();
// undoneList.clear();
// updateUndoRedo();
// }
/**
* Method to prevent redo by deleting all undone change batches.
*/
public static void noRedoAllowed() {
undoneList.clear();
updateUndoRedo();
}
/**
* Method to set the size of the history list and return the former size.
* @param newSize the new size of the history list (number of batches of changes).
* If not positive, the list size is not changed.
* @return the former size of the history list.
*/
public static int setHistoryListSize(int newSize) {
if (newSize <= 0) {
return maximumBatches;
}
int oldSize = maximumBatches;
maximumBatches = newSize;
if (doneList.size() > maximumBatches) {
doneList.remove(0);
}
updateUndoRedo();
return oldSize;
}
/**
* Method to display all changes.
*/
public static void showHistoryList() {
System.out.println("---------- Done batches (" + doneList.size() + ") ----------:");
for (int i = 0; i < doneList.size(); i++) {
ChangeBatch batch = doneList.get(i);
batch.describe("Done");
}
System.out.println("---------- Undone batches (" + undoneList.size() + ") ----------:");
for (int i = 0; i < undoneList.size(); i++) {
ChangeBatch batch = undoneList.get(i);
batch.describe("Undone");
}
}
}