/**
*
*/
package com.onpositive.gae.baseviewer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Key;
import com.onpositive.commons.ui.dialogs.TitledDialog;
import com.onpositive.commons.ui.tableeditor.ConfigurableTableViewer;
import com.onpositive.commons.ui.tableeditor.Field;
import com.onpositive.commons.ui.tableeditor.IDataFacade;
import com.onpositive.commons.ui.tableeditor.ISingleCallback;
import com.onpositive.gae.baseviewer.BaseDataFacade.GAEField;
import com.onpositive.gae.tools.license.LicenseChecker;
import com.onpositive.semantic.model.binding.Binding;
import com.onpositive.semantic.model.realm.OrderedRealm;
import com.onpositive.semantic.model.ui.property.IPropertyEditor;
import com.onpositive.semantic.model.ui.property.editors.CompositeEditor;
import com.onpositive.semantic.model.ui.property.editors.DisposeBindingListener;
import com.onpositive.semantic.model.ui.property.editors.structured.ListEnumeratedValueSelector;
public class BaseViewer extends ConfigurableTableViewer {
private class SelectColumnsDialog extends TitledDialog {
private final ListEnumeratedValueSelector<Field> vl;
IStructuredSelection selection;
private SelectColumnsDialog(IPropertyEditor<?> editor,
ListEnumeratedValueSelector<Field> vl) {
super(editor);
this.vl = vl;
}
protected void okPressed() {
Collection<Object> currentValue = vl.getCurrentValue();
selection = new StructuredSelection(
currentValue.toArray(new Object[currentValue.size()]));// .toArray());
super.okPressed();
}
}
public static class SortComparator extends ViewerComparator implements
Comparator<Object> {
private final String property;
private final boolean asc;
SortComparator(String property, boolean asc) {
this.property = property;
this.asc = asc;
}
public int compare(Viewer viewer, Object e1, Object e2) {
Entity en1 = (Entity) e1;
Entity en2 = (Entity) e2;
Object p1 = en1.getProperty(property);
Object p2 = en2.getProperty(property);
if (property.equals(Entity.KEY_RESERVED_PROPERTY)) {
p1 = en1.getKey();
p2 = en2.getKey();
}
int calc = calc(p1, p2);
if (asc) {
return calc;
} else {
return -calc;
}
}
@SuppressWarnings("unchecked")
private int calc(Object p1, Object p2) {
if (p1 == null && p2 != null) {
return -1;
} else if (p2 == null && p1 != null) {
return 1;
}
if (p1 == null && p2 == null) {
return 0;
}
if (p1 instanceof Comparable<?> && p2 instanceof Comparable<?>) {
Comparable<Object> c1 = (Comparable<Object>) p1;
try {
return c1.compareTo(p2);
} catch (Exception e) {
return 0;
}
}
if (p1 instanceof Collection && !(p2 instanceof Collection)) {
Collection m = (Collection) p1;
for (Object o : m) {
if (o instanceof Comparable<?>) {
Comparable<Object> c = (Comparable<Object>) o;
return c.compareTo(p2);
}
}
}
if (p2 instanceof Collection && !(p1 instanceof Collection)) {
Collection m = (Collection) p2;
for (Object o : m) {
if (o instanceof Comparable<?>) {
Comparable<Object> c = (Comparable<Object>) o;
return c.compareTo(p1);
}
}
}
if (p2 instanceof Collection && p1 instanceof Collection) {
Collection m1 = (Collection) p1;
Collection m2 = (Collection) p2;
if (m1.isEmpty()) {
if (m2.isEmpty()) {
return 0;
}
return 1;
}
if (m2.isEmpty()) {
if (m1.isEmpty()) {
return 0;
}
return -1;
}
for (Object o : m1) {
if (o instanceof Comparable<?>) {
Comparable<Object> c = (Comparable<Object>) o;
for (Object o1 : m2) {
if (o1 instanceof Comparable<?>) {
Comparable<Object> c1 = (Comparable<Object>) o1;
return c.compareTo(c1);
}
}
}
}
}
return 0;
}
public int compare(Object o1, Object o2) {
return compare(null, o1, o2);
}
}
private Action action;
protected IStructuredSelection currentSelection;
IProject project;
String kind;
private DataStoreTableUI ui;
BaseViewer(Action action, DataStoreTableUI ui, IProject project, String kind) {
this.action = action;
this.ui = ui;
this.project = project;
this.kind = kind;
}
public void fillPopupMenu(IMenuManager manager) {
final ISelection selection = getViewer().getSelection();
if (!selection.isEmpty()) {
manager.add(this.ui.createCreateAction());
manager.add(this.ui.createEditAction());
manager.add(this.ui.createDeleteAction());
manager.add(this.ui.createDuplicateEntityAction());
}
manager.add(new Separator());
MenuManager item = new MenuManager("Details Formatting");
Field[] fields = getFields();
for (Field f : fields) {
if (f.getType() == Key.class || f.getType() == Entity.class) {
final GAEField fr = (GAEField) f;
if (fr.keyKindDetails == null) {
item.add(new Action("Enable details formatting for "
+ f.name) {
public void run() {
fr.enableDetailFormatting();
}
});
} else {
item.add(new Action("Disable details formatting for "
+ f.name) {
public void run() {
fr.disableDetailFormatting();
}
});
}
}
}
manager.add(item);
manager.add(new Action("Configure visible columns") {
public void run() {
CompositeEditor editor = new CompositeEditor();
final Binding bnd = new Binding(String.class);
bnd.setName("Visible Properties");
bnd.setDescription("Please select properties which should be displayed in this view");
editor.setBinding(bnd);
final ListEnumeratedValueSelector<Field> vl = new ListEnumeratedValueSelector<Field>();
vl.getLayoutHints().setMinimumSize(new Point(300, 500));
vl.getLayoutHints().setHint(new Point(300, 500));
final OrderedRealm<Field> realm = new OrderedRealm<Field>();
final SelectColumnsDialog dlg = new SelectColumnsDialog(editor,
vl) {
protected void createButtonsForButtonBar(Composite parent) {
Button createButton = createButton(parent, 4,
"Select All", true);
createButton.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
vl.setSelection(new StructuredSelection(realm
.getContents().toArray()));
vl.addValues(realm.getContents());
}
});
Button createButton2 = createButton(parent, 5,
"Deselect All", true);
createButton2.addListener(SWT.Selection,
new Listener() {
public void handleEvent(Event event) {
vl.setSelection(new StructuredSelection());
vl.addValues(new ArrayList<Field>());
}
});
super.createButtonsForButtonBar(parent);
}
};
vl.setAsCheckBox(true);
vl.setValueAsSelection(true);
dlg.setResizable(true);
editor.add(vl);
for (Field f : getFields()) {
realm.add(f);
}
vl.setRealm(realm);
HashSet<Field> fl = new HashSet<Field>();
for (Field f : getFields()) {
if (!currentColumns.contains(f.name)
|| currentColumns.isEmpty()) { // currentColumns.contains(f.name)
// ||
// currentColumns.isEmpty()
fl.add(f);
}
}
vl.setValue(fl);
vl.setSelection(new StructuredSelection(fl.toArray()));
DisposeBindingListener.linkBindingLifeCycle(bnd, editor);
dlg.open();
if (dlg.selection != null) {
IStructuredSelection s = dlg.selection;
Object[] ar = s.toArray();
String[] result = new String[ar.length];
for (int a = 0; a < ar.length; a++) {
result[a] = ((Field) ar[a]).name;
}
currentColumns.clear();
// for (String sm : result) {
// currentColumns.add(sm);
// }
List<String> res = Arrays.asList(result);
for (Field ff : realm.getContents()) {
String nf = ff.name;
if (!res.contains(nf)) {
currentColumns.add(nf);
}
}
updateColumns();
// return result;
}
}
});
manager.add(ui.createRefreshAction());
}
public BaseViewer() {
}
public void refresh(IDataFacade facade) {
if (LicenseChecker.checkLicense(true)) {
super.refresh(facade);
}
}
public void dispose() {
getFacade().dispose();
super.dispose();
}
public void onOpen(Object selection) {
boolean needRefresh = false;
if (selection != null) {
needRefresh = ui.open(selection, true);
}
// fix?
if (needRefresh) {
ui.doRefresh();
ui.getFacade().updateFields();
}
}
public void storeColumnsWidth() throws CoreException {
if (project != null) {
if (kind.length() > 0) {
if (project.exists()) {
project.getProject().setPersistentProperty(
new QualifiedName(
"com.onpositive.baseviewer.columnswidth",
kind), getColumnsWidthString());
}
}
}
}
public void storeVisibleColumns() throws CoreException {
if (project != null) {
if (kind != null && kind.length() > 0) {
StringBuilder bld = new StringBuilder();
for (String s : currentColumns) {
bld.append(s);
bld.append(',');
}
if (bld.length() > 0) {
bld.deleteCharAt(bld.length() - 1);
}
String cString = bld.toString();
if (project.exists()) {
project.getProject().setPersistentProperty(
new QualifiedName(
"com.onpositive.baseviewer.columnsvisible",
kind), cString);
}
}
}
}
public void restoreVisibleColumns() throws CoreException {
if (project != null) {
if (kind.length() > 0) {
String persistentProperty = project
.getProject()
.getPersistentProperty(
new QualifiedName(
"com.onpositive.baseviewer.columnsvisible",
kind));
if (persistentProperty != null
&& persistentProperty.length() > 0) {
String[] split = persistentProperty.split(",");
currentColumns.clear();
for (String s : split) {
currentColumns.add(s.trim());
}
}
}
}
}
public String getColumnWidthString() throws CoreException {
if (project != null) {
if (kind.length() > 0) {
return project
.getProject()
.getPersistentProperty(
new QualifiedName(
"com.onpositive.baseviewer.columnswidth",
kind));
}
}
return null;
}
public void selectionChanged(IStructuredSelection selection) {
action.setEnabled(!selection.isEmpty());
currentSelection = selection;
ui.currentSelection = selection;
}
public void refreshO(Object object) {
refresh(object);
}
public ISingleCallback getSingleCallback() {
return new ISingleCallback() {
public void refresh(Object obj) {
refreshO(obj);
}
public void delete(Object obj) {
}
public void add(Object obj) {
}
};
}
public String getColumnsSort() throws CoreException {
if (project != null) {
if (kind != null && kind.length() > 0) {
String persistentProperty = project
.getProject()
.getPersistentProperty(
new QualifiedName(
"com.onpositive.baseviewer.columnssort",
kind));
return persistentProperty;// .equals("Parent") ?
// "":persistentProperty;
}
}
return "";
}
public int getColumnsSortAscending() throws CoreException {
if (project != null) {
if (kind.length() > 0) {
String persistentProperty = project
.getProject()
.getPersistentProperty(
new QualifiedName(
"com.onpositive.baseviewer.columnssortorder",
kind));
if (persistentProperty != null) {
return Integer.parseInt(persistentProperty);
}
}
}
return 0;
}
public void refreshSort(IDataFacade facade) {
BaseDataFacade f = (BaseDataFacade) facade;
final String property = getQuery().sort.property;
final boolean asc = getQuery().sort.ascending;
if (property != null && f.isCompleted()) {
getViewer().setComparator(new SortComparator(property, asc));
}
if (!f.isCompleted()) {
super.refreshSort(facade);
}
}
protected void storeColumnsSort(String name) throws CoreException {
if (project != null) {
if (kind.length() > 0) {
project.getProject().setPersistentProperty(
new QualifiedName(
"com.onpositive.baseviewer.columnssort", kind),
name);
}
}
}
protected void storeColumnsSortAscending(int order) throws CoreException {
// TODO Auto-generated method stub
if (project != null) {
if (kind.length() > 0) {
project.getProject().setPersistentProperty(
new QualifiedName(
"com.onpositive.baseviewer.columnssortorder",
kind), order + "");
}
}
}
protected boolean allowOrder(Field f, int order) {
if (f.isKey()) {
return order == SWT.UP || true;
}
return true;
}
protected boolean allowSort(Field f) {
Class<?> type = f.getType();
if (f.isKey()) {
return true;
}
if (type != null) {
if (Comparable.class.isAssignableFrom(type)) {
return true;
}
}
return false;
}
}