/*******************************************************************************
* Copyright (c) 2012 Arapiki Solutions Inc.
* 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:
* psmith - initial API and
* implementation and/or initial documentation
*******************************************************************************/
package com.buildml.eclipse.outline;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.swt.widgets.Item;
import com.buildml.eclipse.MainEditor;
import com.buildml.eclipse.bobj.UIInteger;
import com.buildml.eclipse.utils.AlertDialog;
import com.buildml.eclipse.utils.UndoOpAdapter;
import com.buildml.model.IBuildStore;
import com.buildml.model.IPackageMgr;
import com.buildml.model.undo.PackageUndoOp;
import com.buildml.utils.errors.ErrorCode;
/**
* This class manages the cell-editing capability of the content outline view. That is,
* when the user wants to rename a package or folder, this class is used to query and
* update the underlying BuildStore model.
*
* @author Peter Smith <psmith@arapiki.com>
*/
public class OutlineContentCellModifier implements ICellModifier {
/*=====================================================================================*
* FIELDS/TYPES
*=====================================================================================*/
/** The main BuildML editor that we're outlining */
private MainEditor mainEditor;
/** The BuildStore we can retrieve the outline from */
private IBuildStore buildStore;
/** The BuildStore's package manager */
private IPackageMgr pkgMgr;
/*=====================================================================================*
* CONSTRUCTORS
*=====================================================================================*/
/**
* Create a new OutlineContentCellModifier which will be called into action whenever
* the user wishes to rename a package or folder.
*
* @param mainEditor The main BuildML editor that we're outlining.
*/
public OutlineContentCellModifier(MainEditor mainEditor) {
this.mainEditor = mainEditor;
this.buildStore = mainEditor.getBuildStore();
this.pkgMgr = buildStore.getPackageMgr();
}
/*=====================================================================================*
* PUBLIC METHODS
*=====================================================================================*/
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ICellModifier#canModify(java.lang.Object, java.lang.String)
*/
@Override
public boolean canModify(Object element, String property) {
/*
* The user should only be provided with the "rename" menu option if they're allowed
* to rename the selected element. Therefore, we can just say "true" all the time,
* since we know that we'll never be called in the case where the modification is
* not possible (such as the root folder, or the <import> package).
*/
return true;
}
/*-------------------------------------------------------------------------------------*/
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ICellModifier#getValue(java.lang.Object, java.lang.String)
*/
@Override
public Object getValue(Object element, String property) {
/*
* For the "NAME" column (actually, there is only one column) retrieve the entry's
* name from the BuildStore. This will be the initial text that appears when editing
* the cell's content.
*/
if ("NAME".equals(property)) {
int id = ((UIInteger)element).getId();
String name = pkgMgr.getName(id);
if (name == null) {
return "<invalid>";
}
return name;
}
return null;
}
/*-------------------------------------------------------------------------------------*/
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ICellModifier#modify(java.lang.Object, java.lang.String, java.lang.Object)
*/
@Override
public void modify(Object element, String property, Object value) {
if (element instanceof Item) {
element = ((Item)element).getData();
}
/*
* If the user has finished editing the "NAME" column, we must now place the updated value
* back into the database (possibly with errors being reported).
*/
if ("NAME".equals(property) || !(value instanceof String)) {
int id = ((UIInteger)element).getId();
/* has the name actually changed? If not, there's no work to do */
String newName = (String)value;
String oldName = pkgMgr.getName(id);
if ((oldName == null) || !(oldName.equals(newName))) {
/* Change the name in the database, handling any potential errors */
int rc = pkgMgr.setName(id, newName);
if (rc == ErrorCode.ALREADY_USED) {
AlertDialog.displayErrorDialog("Can't Rename",
"The name \"" + value + "\" is already in use. " +
"Choose a different name");
} else if (rc == ErrorCode.INVALID_NAME) {
AlertDialog.displayErrorDialog("Can't Rename",
"The name \"" + value + "\" is not a valid package identifier. " +
"Choose a different name");
}
/*
* Success - refresh the view and add the name change into
* the undo/redo history.
*/
else {
PackageUndoOp op = new PackageUndoOp(buildStore, id);
op.recordRename(oldName, newName);
new UndoOpAdapter("Rename", op).invoke();
}
}
}
}
/*-------------------------------------------------------------------------------------*/
}