Package com.cburch.logisim.gui.main

Source Code of com.cburch.logisim.gui.main.SelectionActions$Copy

/* Copyright (c) 2010, Carl Burch. License information is located in the
* com.cburch.logisim.Main source code and at www.cburch.com/logisim/. */

package com.cburch.logisim.gui.main;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;

import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

import com.cburch.logisim.circuit.Circuit;
import com.cburch.logisim.circuit.CircuitMutation;
import com.cburch.logisim.circuit.CircuitTransaction;
import com.cburch.logisim.circuit.CircuitTransactionResult;
import com.cburch.logisim.circuit.ReplacementMap;
import com.cburch.logisim.circuit.SubcircuitFactory;
import com.cburch.logisim.circuit.Wire;
import com.cburch.logisim.comp.Component;
import com.cburch.logisim.comp.ComponentFactory;
import com.cburch.logisim.data.AttributeSet;
import com.cburch.logisim.data.Location;
import com.cburch.logisim.file.LogisimFile;
import com.cburch.logisim.proj.Action;
import com.cburch.logisim.proj.JoinedAction;
import com.cburch.logisim.proj.Project;
import com.cburch.logisim.tools.AddTool;
import com.cburch.logisim.tools.Library;
import com.cburch.logisim.tools.Tool;

public class SelectionActions {
  private SelectionActions() { }
 
  public static Action drop(Selection sel, Collection<Component> comps) {
    HashSet<Component> floating = new HashSet<Component>(sel.getFloatingComponents());
    HashSet<Component> anchored = new HashSet<Component>(sel.getAnchoredComponents());
    ArrayList<Component> toDrop = new ArrayList<Component>();
    ArrayList<Component> toIgnore = new ArrayList<Component>();
    for (Component comp : comps) {
      if (floating.contains(comp)) {
        toDrop.add(comp);
      } else if (anchored.contains(comp)) {
        toDrop.add(comp);
        toIgnore.add(comp);
      }
    }
    int numDrop = toDrop.size() - toIgnore.size();
    if (numDrop == 0) {
      for (Component comp : toIgnore) {
        sel.remove(null, comp);
      }
      return null;
    } else {
      return new Drop(sel, toDrop, numDrop);
    }
  }
 
  public static Action dropAll(Selection sel) {
    return drop(sel, sel.getComponents());
  }

  public static Action clear(Selection sel) {
    return new Delete(sel);
  }
 
  public static Action duplicate(Selection sel) {
    return new Duplicate(sel);
  }

  public static Action cut(Selection sel) {
    return new Cut(sel);
  }

  public static Action copy(Selection sel) {
    return new Copy(sel);
  }

  public static Action pasteMaybe(Project proj, Selection sel) {
    HashMap<Component, Component> replacements = getReplacementMap(proj);
    return new Paste(sel, replacements);
  }
 
  public static Action translate(Selection sel, int dx, int dy, ReplacementMap repl) {
    return new Translate(sel, dx, dy, repl);
  }
 
  private static class Drop extends Action {
    private Selection sel;
    private Component[] drops;
    private int numDrops;
    private SelectionSave before;
    private CircuitTransaction xnReverse;
   
    Drop(Selection sel, Collection<Component> toDrop, int numDrops) {
      this.sel = sel;
      this.drops = new Component[toDrop.size()];
      toDrop.toArray(this.drops);
      this.numDrops = numDrops;
      this.before = SelectionSave.create(sel);
    }

    @Override
    public String getName() {
      return numDrops == 1 ? Strings.get("dropComponentAction")
          : Strings.get("dropComponentsAction");
    }

    @Override
    public void doIt(Project proj) {
      Circuit circuit = proj.getCurrentCircuit();
      CircuitMutation xn = new CircuitMutation(circuit);
      for (Component comp : drops) {
        sel.remove(xn, comp);
      }
      CircuitTransactionResult result = xn.execute();
      xnReverse = result.getReverseTransaction();
    }

    @Override
    public void undo(Project proj) {
      xnReverse.execute();
    }

    @Override
    public boolean shouldAppendTo(Action other) {
      Action last;
      if (other instanceof JoinedAction) last = ((JoinedAction) other).getLastAction();
      else last = other;
     
      SelectionSave otherAfter = null;
      if (last instanceof Paste) {
        otherAfter = ((Paste) last).after;
      } else if (last instanceof Duplicate) {
        otherAfter = ((Duplicate) last).after;
      }
      return otherAfter != null && otherAfter.equals(this.before);
    }
  }

  private static class Delete extends Action {
    private Selection sel;
    private CircuitTransaction xnReverse;

    Delete(Selection sel) {
      this.sel = sel;
    }

    @Override
    public String getName() {
      return Strings.get("deleteSelectionAction");
    }

    @Override
    public void doIt(Project proj) {
      Circuit circuit = proj.getCurrentCircuit();
      CircuitMutation xn = new CircuitMutation(circuit);
      sel.deleteAllHelper(xn);
      CircuitTransactionResult result = xn.execute();
      xnReverse = result.getReverseTransaction();
    }

    @Override
    public void undo(Project proj) {
      xnReverse.execute();
    }
  }

  private static class Duplicate extends Action {
    private Selection sel;
    private CircuitTransaction xnReverse;
    private SelectionSave after;

    Duplicate(Selection sel) {
      this.sel = sel;
    }

    @Override
    public String getName() {
      return Strings.get("duplicateSelectionAction");
    }

    @Override
    public void doIt(Project proj) {
      Circuit circuit = proj.getCurrentCircuit();
      CircuitMutation xn = new CircuitMutation(circuit);
      sel.duplicateHelper(xn);

      CircuitTransactionResult result = xn.execute();
      xnReverse = result.getReverseTransaction();
      after = SelectionSave.create(sel);
    }

    @Override
    public void undo(Project proj) {
      xnReverse.execute();
    }
  }

  private static class Cut extends Action {
    private Action first;
    private Action second;

    Cut(Selection sel) {
      first = new Copy(sel);
      second = new Delete(sel);
    }

    @Override
    public String getName() {
      return Strings.get("cutSelectionAction");
    }

    @Override
    public void doIt(Project proj) {
      first.doIt(proj);
      second.doIt(proj);
    }

    @Override
    public void undo(Project proj) {
      second.undo(proj);
      first.undo(proj);
    }
  }

  private static class Copy extends Action {
    private Selection sel;
    private Clipboard oldClip;

    Copy(Selection sel) {
      this.sel = sel;
    }

    @Override
    public boolean isModification() { return false; }

    @Override
    public String getName() {
      return Strings.get("copySelectionAction");
    }

    @Override
    public void doIt(Project proj) {
      oldClip = Clipboard.get();
      Clipboard.set(sel, sel.getAttributeSet());
    }

    @Override
    public void undo(Project proj) {
      Clipboard.set(oldClip);
    }
  }
 
  private static HashMap<Component, Component> getReplacementMap(Project proj) {
    HashMap<Component, Component> replMap;
    replMap = new HashMap<Component, Component>();
   
    LogisimFile file = proj.getLogisimFile();
    ArrayList<Library> libs = new ArrayList<Library>();
    libs.add(file);
    libs.addAll(file.getLibraries());
   
    ArrayList<String> dropped = null;
    Clipboard clip = Clipboard.get();
    Collection<Component> comps = clip.getComponents();
    HashMap<ComponentFactory, ComponentFactory> factoryReplacements;
    factoryReplacements = new HashMap<ComponentFactory, ComponentFactory>();
    for (Component comp : comps) {
      if (comp instanceof Wire) continue;
     
      ComponentFactory compFactory = comp.getFactory();
      ComponentFactory copyFactory = findComponentFactory(compFactory, libs, false);
      if (factoryReplacements.containsKey(compFactory)) {
        copyFactory = factoryReplacements.get(compFactory);
      } else if (copyFactory == null) {
        ComponentFactory candidate = findComponentFactory(compFactory, libs, true);
        if (candidate == null) {
          if (dropped == null) {
            dropped = new ArrayList<String>();
          }
          dropped.add(compFactory.getDisplayName());
        } else {
          String msg = Strings.get("pasteCloneQuery",
              compFactory.getName());
          Object[] opts = { Strings.get("pasteCloneReplace"),
              Strings.get("pasteCloneIgnore"),
              Strings.get("pasteCloneCancel") };
          int select = JOptionPane.showOptionDialog(proj.getFrame(),
              msg, Strings.get("pasteCloneTitle"), 0,
              JOptionPane.QUESTION_MESSAGE, null, opts, opts[0]);
          if (select == 0) {
            copyFactory = candidate;
          } else if (select == 1) {
            copyFactory = null;
          } else {
            return null;
          }
          factoryReplacements.put(compFactory, copyFactory);
        }
      }
     
      if (copyFactory == null) {
        replMap.put(comp, null);
      } else if (copyFactory != compFactory) {
        Location copyLoc = comp.getLocation();
        AttributeSet copyAttrs = (AttributeSet) comp.getAttributeSet().clone();
        Component copy = copyFactory.createComponent(copyLoc, copyAttrs);
        replMap.put(comp, copy);
      }
    }
   
    if (dropped != null) {
      Collections.sort(dropped);
      StringBuilder droppedStr = new StringBuilder();
      droppedStr.append(Strings.get("pasteDropMessage"));
      String curName = dropped.get(0);
      int curCount = 1;
      int lines = 1;
      for (int i = 1; i <= dropped.size(); i++) {
        String nextName = i == dropped.size() ? "" : dropped.get(i);
        if (nextName.equals(curName)) {
          curCount++;
        } else {
          lines++;
          droppedStr.append("\n  ");
          droppedStr.append(curName);
          if (curCount > 1) {
            droppedStr.append(" \u00d7 " + curCount);
          }
         
          curName = nextName;
          curCount = 1;
        }
      }

      lines = Math.max(3, Math.min(7, lines));
      JTextArea area = new JTextArea(lines, 60);
      area.setEditable(false);
      area.setText(droppedStr.toString());
      area.setCaretPosition(0);
      JScrollPane areaPane = new JScrollPane(area);
      JOptionPane.showMessageDialog(proj.getFrame(), areaPane,
          Strings.get("pasteDropTitle"),
          JOptionPane.WARNING_MESSAGE);
    }
   
    return replMap;
  }
 
  private static ComponentFactory findComponentFactory(ComponentFactory factory,
      ArrayList<Library> libs, boolean acceptNameMatch) {
    String name = factory.getName();
    for (Library lib : libs) {
      for (Tool tool : lib.getTools()) {
        if (tool instanceof AddTool) {
          AddTool addTool = (AddTool) tool;
          if (name.equals(addTool.getName())) {
            ComponentFactory fact = addTool.getFactory(true);
            if (acceptNameMatch) {
              return fact;
            } else if (fact == factory) {
              return fact;
            } else if (fact.getClass() == factory.getClass()
                && !(fact instanceof SubcircuitFactory)) {
              return fact;
            }
          }
        }
      }
    }
    return null;
  }

  private static class Paste extends Action {
    private Selection sel;
    private CircuitTransaction xnReverse;
    private SelectionSave after;
    private HashMap<Component,Component> componentReplacements;

    Paste(Selection sel, HashMap<Component, Component> replacements) {
      this.sel = sel;
      this.componentReplacements = replacements;
    }

    @Override
    public String getName() {
      return Strings.get("pasteClipboardAction");
    }

    @Override
    public void doIt(Project proj) {
      Clipboard clip = Clipboard.get();
      Circuit circuit = proj.getCurrentCircuit();
      CircuitMutation xn = new CircuitMutation(circuit);
      Collection<Component> comps = clip.getComponents();
      Collection<Component> toAdd = computeAdditions(comps);
      if (toAdd.size() > 0) {
        sel.pasteHelper(xn, toAdd);
        CircuitTransactionResult result = xn.execute();
        xnReverse = result.getReverseTransaction();
        after = SelectionSave.create(sel);
      } else {
        xnReverse = null;
      }
    }
   
    private Collection<Component> computeAdditions(Collection<Component> comps) {
      HashMap<Component, Component> replMap = componentReplacements;
      ArrayList<Component> toAdd = new ArrayList<Component>(comps.size());
      for (Iterator<Component> it = comps.iterator(); it.hasNext(); ) {
        Component comp = it.next();
        if (replMap.containsKey(comp)) {
          Component repl = replMap.get(comp);
          if (repl != null) {
            toAdd.add(repl);
          }
        } else {
          toAdd.add(comp);
        }
      }
      return toAdd;
    }
   
    @Override
    public void undo(Project proj) {
      if (xnReverse != null) {
        xnReverse.execute();
      }
    }
  }

  private static class Translate extends Action {
    private Selection sel;
    private int dx;
    private int dy;
    private ReplacementMap replacements;
    private SelectionSave before;
    private CircuitTransaction xnReverse;
   
    Translate(Selection sel, int dx, int dy, ReplacementMap replacements) {
      this.sel = sel;
      this.dx = dx;
      this.dy = dy;
      this.replacements = replacements;
      this.before = SelectionSave.create(sel);
    }

    @Override
    public String getName() {
      return Strings.get("moveSelectionAction");
    }

    @Override
    public void doIt(Project proj) {
      Circuit circuit = proj.getCurrentCircuit();
      CircuitMutation xn = new CircuitMutation(circuit);

      sel.translateHelper(xn, dx, dy);
      if (replacements != null) {
        xn.replace(replacements);
      }

      CircuitTransactionResult result = xn.execute();
      xnReverse = result.getReverseTransaction();
    }

    @Override
    public void undo(Project proj) {
      xnReverse.execute();
    }

    @Override
    public boolean shouldAppendTo(Action other) {
      Action last;
      if (other instanceof JoinedAction) last = ((JoinedAction) other).getLastAction();
      else last = other;
     
      SelectionSave otherAfter = null;
      if (last instanceof Paste) {
        otherAfter = ((Paste) last).after;
      } else if (last instanceof Duplicate) {
        otherAfter = ((Duplicate) last).after;
      }
      return otherAfter != null && otherAfter.equals(this.before);
    }
  }
}
TOP

Related Classes of com.cburch.logisim.gui.main.SelectionActions$Copy

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.