in projectional/src/main/java/jetbrains/jetpad/projectional/cell/BaseProjectionalSynchronizer.java [346:562]
public void attach(SynchronizerContext ctx) {
myTargetCellList.initList();
initChildViews();
myRoleSynchronizer.attach(ctx);
myTarget.addTrait(new CellTrait() {
@Override
public void onCopy(Cell cell, CopyCutEvent event) {
if (canCopy()) {
event.consume(copy());
return;
}
super.onCopy(cell, event);
}
@Override
public void onCut(Cell cell, CopyCutEvent event) {
if (canCut()) {
event.consume(cut());
return;
}
super.onCut(cell, event);
}
@Override
public void onPaste(Cell cell, PasteEvent event) {
if (canPaste(event.getContent())) {
paste(event.getContent());
event.consume();
return;
}
super.onPaste(cell, event);
}
private boolean canCopy() {
return hasItemsToCopy() && (myItemKind != null || itemsToStringSupported());
}
private ClipboardContent copy() {
if (myItemKind != null) {
return createClipboardContent(itemsToCopy());
} else if (itemsToStringSupported()) {
return TextContentHelper.createClipboardContent(itemsToString(itemsToCopy()));
} else {
throw new IllegalStateException("canCopy() and copy() are inconsistent");
}
}
private ClipboardContent createClipboardContent(List<SourceItemT> items) {
final List<SourceItemT> copiedItems = new ArrayList<>();
for (SourceItemT item : items) {
copiedItems.add(myCloner.apply(item));
}
return new ClipboardContent() {
@Override
public boolean isSupported(ContentKind<?> kind) {
if (Objects.equal(kind, myItemKind)) {
return copiedItems.size() <= 1;
}
return Objects.equal(kind, listOf(myItemKind));
}
@Override
public <T> T get(ContentKind<T> kind) {
if (Objects.equal(kind, myItemKind)) {
return (T) myCloner.apply(copiedItems.get(0));
}
final List<SourceItemT> result = new ArrayList<>();
for (SourceItemT item : new ArrayList<>(copiedItems)) {
result.add(myCloner.apply(item));
}
return (T) result;
}
@Override
public String toString() {
if (itemsToStringSupported()) {
return itemsToString(copiedItems);
}
return super.toString();
}
};
}
private boolean itemsToStringSupported() {
return myContentListToString != null || myContentToString != null;
}
private String itemsToString(List<SourceItemT> items) {
if (myContentListToString != null) {
return myContentListToString.apply(items);
}
if (myContentToString != null) {
return myContentToString.apply(items.get(0));
}
throw new IllegalStateException("itemsToStringSupported() and itemsToString() are inconsistent");
}
private boolean hasItemsToCopy() {
return (!getSelectedItems().isEmpty()) || (currentItem() != null);
}
private List<SourceItemT> itemsToCopy() {
final List<SourceItemT> items = new ArrayList<>();
if (!getSelectedItems().isEmpty()) {
for (SourceItemT item : getSelectedItems()) {
items.add(item);
}
} else {
items.add(currentItem());
}
return items;
}
private boolean canCut() {
return hasItemsToCopy() && myItemKind != null;
}
private ClipboardContent cut() {
List<SourceItemT> toCopy = itemsToCopy();
ClipboardContent result = createClipboardContent(toCopy);
clear(toCopy);
return result;
}
private boolean canPaste(ClipboardContent content) {
for (ContentKind kind : myContentKinds.keySet()) {
if (content.isSupported(kind) || (isMultiItemPasteSupported() && content.isSupported(listOf(kind)))) {
return true;
}
}
if (isMultiItemPasteSupported()) {
for (ContentKind kind : myListContentKinds.keySet()) {
if (content.isSupported(kind)) {
return true;
}
}
}
return false;
}
private void paste(ClipboardContent content) {
for (ListMap<ContentKind, Function<?, SourceItemT>>.Entry entry : myContentKinds.entrySet()) {
ContentKind kind = entry.key();
Function<Object, SourceItemT> fromContent = (Function<Object, SourceItemT>) entry.value();
if (content.isSupported(entry.key())) {
SourceItemT item = fromContent.apply(content.get(kind));
if (item != null) {
insertItem(item);
}
return;
} else if (isMultiItemPasteSupported() && content.isSupported(listOf(kind))) {
List<SourceItemT> itemsList = (List<SourceItemT>) fromContent.apply(content.get(listOf(kind)));
if (itemsList != null) {
insertItems(itemsList);
}
return;
}
}
if (isMultiItemPasteSupported()) {
for (ListMap<ContentKind, Function<?, List<SourceItemT>>>.Entry entry : myListContentKinds.entrySet()) {
ContentKind kind = entry.key();
if (content.isSupported(kind)) {
Function<Object, List<SourceItemT>> fromContent = (Function<Object, List<SourceItemT>>) entry.value();
List<SourceItemT> items = fromContent.apply(content.get(kind));
if (items != null) {
insertItems(items);
}
return;
}
}
}
throw new IllegalStateException("canPaste() and paste() are inconsistent. Content: " + content);
}
@Override
public void onFocusGained(Cell cell, FocusEvent event) {
super.onFocusGained(cell, event);
myForDeletion.set(null);
}
@Override
public void onFocusLost(Cell cell, FocusEvent event) {
super.onFocusLost(cell, event);
myForDeletion.set(null);
}
@Override
public void onKeyPressed(Cell cell, KeyEvent event) {
super.onKeyPressed(cell, event);
myForDeletion.set(null);
}
@Override
public void onKeyTyped(Cell cell, KeyEvent event) {
super.onKeyTyped(cell, event);
myForDeletion.set(null);
}
@Override
public void onMouseClicked(Cell cell, MouseEvent event) {
super.onMouseClicked(cell, event);
myForDeletion.set(null);
}
@Override
public void onMousePressed(Cell cell, MouseEvent event) {
super.onMousePressed(cell, event);
myForDeletion.set(null);
}
});
}