/*
* Copyright (c) 2012, 2013 Hemanta Sapkota.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Hemanta Sapkota (laex.pearl@gmail.com)
*/
package com.laex.cg2d.screeneditor.handlers;
import java.io.IOException;
import org.apache.commons.lang.StringUtils;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.gef.commands.CommandStack;
import org.eclipse.gef.commands.CompoundCommand;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.viewers.ListViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Spinner;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.widgets.FormToolkit;
import com.badlogic.gdx.math.Rectangle;
import com.laex.cg2d.model.ILayerManager;
import com.laex.cg2d.model.ScreenModel.CGScreenModel;
import com.laex.cg2d.model.model.GameModel;
import com.laex.cg2d.model.model.IDCreationStrategy;
import com.laex.cg2d.model.model.IDCreationStrategyFactory;
import com.laex.cg2d.model.model.Layer;
import com.laex.cg2d.model.model.ModelCopier;
import com.laex.cg2d.model.model.Shape;
import com.laex.cg2d.screeneditor.Activator;
import com.laex.cg2d.screeneditor.ScreenEditorUtil;
import com.laex.cg2d.screeneditor.commands.LayerAddCommand;
import com.laex.cg2d.screeneditor.commands.ShapeCreateCommand;
import com.laex.cg2d.screeneditor.model.ScreenModelAdapter;
import com.laex.cg2d.screeneditor.model.ShapeCopier;
/**
* The Class ListExistingScreensDialog.
*/
public class ImportScreenContentsDialog extends TitleAreaDialog {
/** The list. */
private List list;
/** The list viewer. */
private ListViewer listViewer;
/** The res list. */
private java.util.List<IResource> resList;
/** The command stack. */
private CommandStack commandStack;
/** The form toolkit. */
private final FormToolkit formToolkit = new FormToolkit(Display.getDefault());
/** The btn import in new. */
private Button btnImportInNew;
/** The txt new layer name. */
private Text txtNewLayerName;
/** The new layer name composite. */
private Composite newLayerNameComposite;
/** The lbl shape prefix. */
private Label lblShapePrefix;
/** The txt suffix. */
private Text txtSuffix;
/** The lbl columns. */
private Label lblColumns;
/** The txt columns repeat. */
private Spinner txtColumnsRepeat;
/** The label. */
private Label label;
/**
* Create the dialog.
*
* @param parentShell
* the parent shell
* @param cmdStack
* the cmd stack
*/
public ImportScreenContentsDialog(Shell parentShell, CommandStack cmdStack) {
super(parentShell);
this.commandStack = cmdStack;
}
/**
* Create contents of the dialog.
*
* @param parent
* the parent
* @return the control
*/
@Override
protected Control createDialogArea(Composite parent) {
setTitle("Import Screen Contents Dialog");
setMessage("Import contents from other screens");
Composite container = (Composite) super.createDialogArea(parent);
container.setLayout(new GridLayout(2, false));
new Label(container, SWT.NONE);
listViewer = new ListViewer(container, SWT.BORDER | SWT.V_SCROLL);
list = listViewer.getList();
GridData gd_list = new GridData(SWT.FILL, SWT.FILL, false, false, 2, 1);
gd_list.widthHint = 176;
gd_list.heightHint = 144;
list.setLayoutData(gd_list);
lblShapePrefix = formToolkit.createLabel(container, "Suffix (Required)", SWT.NONE);
lblShapePrefix.setBackground(null);
new Label(container, SWT.NONE);
txtSuffix = formToolkit.createText(container, "New Text", SWT.NONE);
txtSuffix.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
txtSuffix.setText("");
txtSuffix.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
validateAll();
}
});
new Label(container, SWT.NONE);
lblColumns = new Label(container, SWT.NONE);
lblColumns.setToolTipText("Repeat Columns");
formToolkit.adapt(lblColumns, true, true);
lblColumns.setText("Columns");
lblColumns.setBackground(null);
new Label(container, SWT.NONE);
txtColumnsRepeat = new Spinner(container, SWT.BORDER);
txtColumnsRepeat.setSelection(1);
txtColumnsRepeat.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
formToolkit.adapt(txtColumnsRepeat);
formToolkit.paintBordersFor(txtColumnsRepeat);
new Label(container, SWT.NONE);
btnImportInNew = new Button(container, SWT.CHECK);
btnImportInNew.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));
btnImportInNew.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
validateAll();
}
});
formToolkit.adapt(btnImportInNew, true, true);
btnImportInNew.setText("Import in New Layer");
btnImportInNew.setBackground(null);
txtNewLayerName = formToolkit.createText(container, "New Text", SWT.NONE);
txtNewLayerName.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
txtNewLayerName.setText("");
txtNewLayerName.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
if (!StringUtils.isEmpty(txtNewLayerName.getText())) {
btnImportInNew.setSelection(true);
} else {
btnImportInNew.setSelection(false);
}
validateAll();
}
});
new Label(container, SWT.NONE);
newLayerNameComposite = formToolkit.createComposite(container, SWT.NONE);
newLayerNameComposite.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));
newLayerNameComposite.setEnabled(false);
newLayerNameComposite.setBackground(null);
formToolkit.paintBordersFor(newLayerNameComposite);
newLayerNameComposite.setLayout(new GridLayout(1, false));
try {
loadScreens();
} catch (CoreException e) {
Activator.log(e);
}
return container;
}
/**
* Load screens.
*
* @throws CoreException
* the core exception
*/
private void loadScreens() throws CoreException {
resList = ScreenEditorUtil.getListOfScreensInCurrentProject(ScreenEditorUtil.getActiveEditorInput());
for (IResource res : resList) {
if (res.getName().equals(((IFileEditorInput) ScreenEditorUtil.getActiveEditorInput()).getFile().getName())) {
continue;
}
list.add(res.getName());
}
list.select(0);
}
/**
* Validate all.
*/
private void validateAll() {
validateNewLayerNameSelection();
validateSuffix();
validateScreens();
if (StringUtils.isEmpty(txtNewLayerName.getText()) && btnImportInNew.getSelection()) {
getButton(OK).setEnabled(false);
}
}
/**
* Validate new layer name selection.
*/
private void validateNewLayerNameSelection() {
if (btnImportInNew.getSelection()) {
newLayerNameComposite.setEnabled(true);
txtNewLayerName.setFocus();
if (!isNewLayerNameValid()) {
getButton(OK).setEnabled(false);
return;
} else {
getButton(OK).setEnabled(true);
}
} else {
getButton(OK).setEnabled(true);
newLayerNameComposite.setEnabled(false);
}
}
/**
* Checks if is new layer name valid.
*
* @return true, if is new layer name valid
*/
private boolean isNewLayerNameValid() {
if (StringUtils.isEmpty(txtNewLayerName.getText())) {
return false;
}
return true;
}
/**
* Validate suffix.
*/
private void validateSuffix() {
boolean isAlphaNumeric = StringUtils.isAlphanumeric(txtSuffix.getText());
boolean isEmpty = StringUtils.isEmpty(txtSuffix.getText());
if (isEmpty) {
getButton(OK).setEnabled(false);
setErrorMessage("Please provide a suffix");
return;
}
// validate suffix
// for the suffix to be valid
if (!isAlphaNumeric || isEmpty) {
getButton(OK).setEnabled(false);
setErrorMessage("Suffix should be alphanumeric");
return;
}
getButton(OK).setEnabled(true);
setErrorMessage(null);
}
/**
* Validate screens.
*/
private void validateScreens() {
// The resource list has at least one screen file i.e. itself, which is not
// displayed on the list
if (resList.size() <= 1) {
setErrorMessage("You must have at least one other screen for import.");
}
}
/**
* Create contents of the button bar.
*
* @param parent
* the parent
*/
@Override
protected void createButtonsForButtonBar(Composite parent) {
createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
validateAll();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.dialogs.Dialog#okPressed()
*/
@Override
protected void okPressed() {
// Before we proceed, we ask the user to save the file
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor()
.doSave(new NullProgressMonitor());
String resFile = list.getSelection()[0];
for (IResource res : resList) {
if (res.getName().equals(resFile)) {
IFile file = (IFile) res;
try {
CGScreenModel model = CGScreenModel.parseFrom(file.getContents());
GameModel gameModel = ScreenModelAdapter.asGameModel(model);
GameModel thisScreenModel = ScreenEditorUtil.getScreenModel();
CompoundCommand cc = new CompoundCommand();
boolean createNewLayer = btnImportInNew.getSelection();
ILayerManager layerMgr = ScreenEditorUtil.getScreenLayerManager();
Layer layer = null;
if (createNewLayer) {
int newLayerId = layerMgr.getNewLayerId();
layer = new Layer(newLayerId, txtNewLayerName.getText() + newLayerId, true, false);
LayerAddCommand layerAddCmd = new LayerAddCommand(layer, thisScreenModel.getDiagram());
cc.add(layerAddCmd);
} else {
// Use existing layer
layer = layerMgr.getCurrentLayer();
if (layer == null) {
// If we have layers, use the first one
if (layerMgr.layerCount() > 0) {
layer = layerMgr.getLayerAt(0);
} else {
MessageBox mb = new MessageBox(getShell(), SWT.ERROR);
mb.setMessage("There are no layers in the screen. Please select the \"import\" feature before continuting");
mb.setText("No Layers in the screen");
mb.open();
return;
}
}
}
/*
* We need an id creator for model we're currently working on. not of
* the file were trying to import from.
*/
IDCreationStrategy idCreator = IDCreationStrategyFactory.getIDCreator(ScreenEditorUtil.getScreenModel());
int index = 0;
for (int i = 0; i < txtColumnsRepeat.getSelection(); i++) {
for (Shape shape : gameModel.getDiagram().getChildren()) {
// add suffix to id
// TODO: Create a shape cloning mechanism
ModelCopier shapeCopier = new ShapeCopier();
Shape newShape = (Shape) shapeCopier.copy(shape);
newShape.setParentLayer(layer);
// make sure our items are really unique
StringBuffer sb = new StringBuffer(shape.getId()).append(txtSuffix.getText()).append(index++);
boolean isIdUsed = idCreator.isIdUsed(newShape.getEditorShapeType(), sb.toString());
if (isIdUsed) {
newShape.setId(idCreator.newId(newShape.getEditorShapeType()));
} else {
newShape.setId(sb.toString());
}
Rectangle r = new Rectangle(shape.getBounds()); // make sure to
// make a copy of
// the bounds and
// then modify its
// coords
if (shape.getEditorShapeType().isBackground()) {
r.x = i * shape.getBounds().getWidth() - 1;
} else {
r.x += i * thisScreenModel.getScreenPrefs().getCardPrefs().getCardWidth();
}
newShape.setBounds(r);
ShapeCreateCommand scc = new ShapeCreateCommand(newShape, thisScreenModel.getDiagram());
cc.add(scc);
}
}
commandStack.execute(cc);
} catch (IOException e) {
Activator.log(e);
} catch (CoreException e) {
Activator.log(e);
}
}
}
super.okPressed();
}
/**
* Return the initial size of the dialog.
*
* @return the initial size
*/
@Override
protected Point getInitialSize() {
return new Point(303, 450);
}
}