+++ /dev/null
-package org.argeo.cms.e4.maintenance;
-
-import static org.eclipse.swt.SWT.RIGHT;
-
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.LinkedHashMap;
-
-import javax.jcr.ItemNotFoundException;
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.Property;
-import javax.jcr.PropertyIterator;
-import javax.jcr.PropertyType;
-import javax.jcr.RepositoryException;
-import javax.jcr.Value;
-
-import org.argeo.api.cms.Cms2DSize;
-import org.argeo.cms.CmsException;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.ui.CmsUiProvider;
-import org.argeo.cms.ui.util.CmsLink;
-import org.argeo.cms.ui.widgets.EditableImage;
-import org.argeo.cms.ui.widgets.Img;
-import org.argeo.jcr.JcrUtils;
-import org.eclipse.jface.viewers.ColumnLabelProvider;
-import org.eclipse.jface.viewers.ILazyContentProvider;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.TableViewerColumn;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.ScrolledComposite;
-import org.eclipse.swt.events.ControlAdapter;
-import org.eclipse.swt.events.ControlEvent;
-import org.eclipse.swt.events.KeyEvent;
-import org.eclipse.swt.events.KeyListener;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableColumn;
-import org.eclipse.swt.widgets.Text;
-
-public class Browse implements CmsUiProvider {
-
- // Some local constants to experiment. should be cleaned
- private final static String BROWSE_PREFIX = "browse#";
- private final static int THUMBNAIL_WIDTH = 400;
- private final static int COLUMN_WIDTH = 160;
- private DateFormat timeFormatter = new SimpleDateFormat("dd-MM-yyyy', 'HH:mm");
-
- // keep a cache of the opened nodes
- // Key is the path
- private LinkedHashMap<String, FilterEntitiesVirtualTable> browserCols = new LinkedHashMap<String, Browse.FilterEntitiesVirtualTable>();
- private Composite nodeDisplayParent;
- private Composite colViewer;
- private ScrolledComposite scrolledCmp;
- private Text parentPathTxt;
- private Text filterTxt;
- private Node currEdited;
-
- private String initialPath;
-
- @Override
- public Control createUi(Composite parent, Node context) throws RepositoryException {
- if (context == null)
- // return null;
- throw new CmsException("Context cannot be null");
- GridLayout layout = CmsSwtUtils.noSpaceGridLayout();
- layout.numColumns = 2;
- parent.setLayout(layout);
-
- // Left
- Composite leftCmp = new Composite(parent, SWT.NO_FOCUS);
- leftCmp.setLayoutData(CmsSwtUtils.fillAll());
- createBrowserPart(leftCmp, context);
-
- // Right
- nodeDisplayParent = new Composite(parent, SWT.NO_FOCUS | SWT.BORDER);
- GridData gd = new GridData(SWT.RIGHT, SWT.FILL, false, true);
- gd.widthHint = THUMBNAIL_WIDTH;
- nodeDisplayParent.setLayoutData(gd);
- createNodeView(nodeDisplayParent, context);
-
- // INIT
- setEdited(context);
- initialPath = context.getPath();
-
- // Workaround we don't yet manage the delete to display parent of the
- // initial context node
-
- return null;
- }
-
- private void createBrowserPart(Composite parent, Node context) throws RepositoryException {
- GridLayout layout = CmsSwtUtils.noSpaceGridLayout();
- parent.setLayout(layout);
- Composite filterCmp = new Composite(parent, SWT.NO_FOCUS);
- filterCmp.setLayoutData(CmsSwtUtils.fillWidth());
-
- // top filter
- addFilterPanel(filterCmp);
-
- // scrolled composite
- scrolledCmp = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.BORDER | SWT.NO_FOCUS);
- scrolledCmp.setLayoutData(CmsSwtUtils.fillAll());
- scrolledCmp.setExpandVertical(true);
- scrolledCmp.setExpandHorizontal(true);
- scrolledCmp.setShowFocusedControl(true);
-
- colViewer = new Composite(scrolledCmp, SWT.NO_FOCUS);
- scrolledCmp.setContent(colViewer);
- scrolledCmp.addControlListener(new ControlAdapter() {
- private static final long serialVersionUID = 6589392045145698201L;
-
- @Override
- public void controlResized(ControlEvent e) {
- Rectangle r = scrolledCmp.getClientArea();
- scrolledCmp.setMinSize(colViewer.computeSize(SWT.DEFAULT, r.height));
- }
- });
- initExplorer(colViewer, context);
- }
-
- private Control initExplorer(Composite parent, Node context) throws RepositoryException {
- parent.setLayout(CmsSwtUtils.noSpaceGridLayout());
- createBrowserColumn(parent, context);
- return null;
- }
-
- private Control createBrowserColumn(Composite parent, Node context) throws RepositoryException {
- // TODO style is not correctly managed.
- FilterEntitiesVirtualTable table = new FilterEntitiesVirtualTable(parent, SWT.BORDER | SWT.NO_FOCUS, context);
- // CmsUiUtils.style(table, ArgeoOrgStyle.browserColumn.style());
- table.filterList("*");
- table.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false, true));
- browserCols.put(context.getPath(), table);
- return null;
- }
-
- public void addFilterPanel(Composite parent) {
-
- parent.setLayout(CmsSwtUtils.noSpaceGridLayout(new GridLayout(2, false)));
-
- // Text Area for the filter
- parentPathTxt = new Text(parent, SWT.NO_FOCUS);
- parentPathTxt.setEditable(false);
- filterTxt = new Text(parent, SWT.SEARCH | SWT.ICON_CANCEL);
- filterTxt.setMessage("Filter current list");
- filterTxt.setLayoutData(CmsSwtUtils.fillWidth());
- filterTxt.addModifyListener(new ModifyListener() {
- private static final long serialVersionUID = 7709303319740056286L;
-
- public void modifyText(ModifyEvent event) {
- modifyFilter(false);
- }
- });
-
- filterTxt.addKeyListener(new KeyListener() {
- private static final long serialVersionUID = -4523394262771183968L;
-
- @Override
- public void keyReleased(KeyEvent e) {
- }
-
- @Override
- public void keyPressed(KeyEvent e) {
- boolean shiftPressed = (e.stateMask & SWT.SHIFT) != 0;
- // boolean altPressed = (e.stateMask & SWT.ALT) != 0;
- FilterEntitiesVirtualTable currTable = null;
- if (currEdited != null) {
- FilterEntitiesVirtualTable table = browserCols.get(getPath(currEdited));
- if (table != null && !table.isDisposed())
- currTable = table;
- }
-
- try {
- if (e.keyCode == SWT.ARROW_DOWN)
- currTable.setFocus();
- else if (e.keyCode == SWT.BS) {
- if (filterTxt.getText().equals("")
- && !(getPath(currEdited).equals("/") || getPath(currEdited).equals(initialPath))) {
- setEdited(currEdited.getParent());
- e.doit = false;
- filterTxt.setFocus();
- }
- } else if (e.keyCode == SWT.TAB && !shiftPressed) {
- if (currEdited.getNodes(filterTxt.getText() + "*").getSize() == 1) {
- setEdited(currEdited.getNodes(filterTxt.getText() + "*").nextNode());
- }
- filterTxt.setFocus();
- e.doit = false;
- }
- } catch (RepositoryException e1) {
- throw new CmsException("Unexpected error in key management for " + currEdited + "with filter "
- + filterTxt.getText(), e1);
- }
-
- }
- });
- }
-
- private void setEdited(Node node) {
- try {
- currEdited = node;
- CmsSwtUtils.clear(nodeDisplayParent);
- createNodeView(nodeDisplayParent, currEdited);
- nodeDisplayParent.layout();
- refreshFilters(node);
- refreshBrowser(node);
- } catch (RepositoryException re) {
- throw new CmsException("Unable to update browser for " + node, re);
- }
- }
-
- private void refreshFilters(Node node) throws RepositoryException {
- String currNodePath = node.getPath();
- parentPathTxt.setText(currNodePath);
- filterTxt.setText("");
- filterTxt.getParent().layout();
- }
-
- private void refreshBrowser(Node node) throws RepositoryException {
-
- // Retrieve
- String currNodePath = node.getPath();
- String currParPath = "";
- if (!"/".equals(currNodePath))
- currParPath = JcrUtils.parentPath(currNodePath);
- if ("".equals(currParPath))
- currParPath = "/";
-
- Object[][] colMatrix = new Object[browserCols.size()][2];
-
- int i = 0, j = -1, k = -1;
- for (String path : browserCols.keySet()) {
- colMatrix[i][0] = path;
- colMatrix[i][1] = browserCols.get(path);
- if (j >= 0 && k < 0 && !currNodePath.equals("/")) {
- boolean leaveOpened = path.startsWith(currNodePath);
-
- // workaround for same name siblings
- // fix me weird side effect when we go left or click on anb
- // already selected, unfocused node
- if (leaveOpened && (path.lastIndexOf("/") == 0 && currNodePath.lastIndexOf("/") == 0
- || JcrUtils.parentPath(path).equals(JcrUtils.parentPath(currNodePath))))
- leaveOpened = JcrUtils.lastPathElement(path).equals(JcrUtils.lastPathElement(currNodePath));
-
- if (!leaveOpened)
- k = i;
- }
- if (currParPath.equals(path))
- j = i;
- i++;
- }
-
- if (j >= 0 && k >= 0)
- // remove useless cols
- for (int l = i - 1; l >= k; l--) {
- browserCols.remove(colMatrix[l][0]);
- ((FilterEntitiesVirtualTable) colMatrix[l][1]).dispose();
- }
-
- // Remove disposed columns
- // TODO investigate and fix the mechanism that leave them there after
- // disposal
- if (browserCols.containsKey(currNodePath)) {
- FilterEntitiesVirtualTable currCol = browserCols.get(currNodePath);
- if (currCol.isDisposed())
- browserCols.remove(currNodePath);
- }
-
- if (!browserCols.containsKey(currNodePath))
- createBrowserColumn(colViewer, node);
-
- colViewer.setLayout(CmsSwtUtils.noSpaceGridLayout(new GridLayout(browserCols.size(), false)));
- // colViewer.pack();
- colViewer.layout();
- // also resize the scrolled composite
- scrolledCmp.layout();
- scrolledCmp.getShowFocusedControl();
- // colViewer.getParent().layout();
- // if (JcrUtils.parentPath(currNodePath).equals(currBrowserKey)) {
- // } else {
- // }
- }
-
- private void modifyFilter(boolean fromOutside) {
- if (!fromOutside)
- if (currEdited != null) {
- String filter = filterTxt.getText() + "*";
- FilterEntitiesVirtualTable table = browserCols.get(getPath(currEdited));
- if (table != null && !table.isDisposed())
- table.filterList(filter);
- }
-
- }
-
- private String getPath(Node node) {
- try {
- return node.getPath();
- } catch (RepositoryException e) {
- throw new CmsException("Unable to get path for node " + node, e);
- }
- }
-
- private Cms2DSize imageWidth = new Cms2DSize(250, 0);
-
- /**
- * Recreates the content of the box that displays information about the current
- * selected node.
- */
- private Control createNodeView(Composite parent, Node context) throws RepositoryException {
-
- parent.setLayout(new GridLayout(2, false));
-
- if (isImg(context)) {
- EditableImage image = new Img(parent, RIGHT, context, imageWidth);
- image.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false, 2, 1));
- }
-
- // Name and primary type
- Label contextL = new Label(parent, SWT.NONE);
- CmsSwtUtils.markup(contextL);
- contextL.setText("<b>" + context.getName() + "</b>");
- new Label(parent, SWT.NONE).setText(context.getPrimaryNodeType().getName());
-
- // Children
- for (NodeIterator nIt = context.getNodes(); nIt.hasNext();) {
- Node child = nIt.nextNode();
- new CmsLink(child.getName(), BROWSE_PREFIX + child.getPath()).createUi(parent, context);
- new Label(parent, SWT.NONE).setText(child.getPrimaryNodeType().getName());
- }
-
- // Properties
- for (PropertyIterator pIt = context.getProperties(); pIt.hasNext();) {
- Property property = pIt.nextProperty();
- Label label = new Label(parent, SWT.NONE);
- label.setText(property.getName());
- label.setToolTipText(JcrUtils.getPropertyDefinitionAsString(property));
- new Label(parent, SWT.NONE).setText(getPropAsString(property));
- }
-
- return null;
- }
-
- private boolean isImg(Node node) throws RepositoryException {
- // TODO support images
- return false;
-// return node.hasNode(JCR_CONTENT) && node.isNodeType(CmsTypes.CMS_IMAGE);
- }
-
- private String getPropAsString(Property property) throws RepositoryException {
- String result = "";
- if (property.isMultiple()) {
- result = getMultiAsString(property, ", ");
- } else {
- Value value = property.getValue();
- if (value.getType() == PropertyType.BINARY)
- result = "<binary>";
- else if (value.getType() == PropertyType.DATE)
- result = timeFormatter.format(value.getDate().getTime());
- else
- result = value.getString();
- }
- return result;
- }
-
- private String getMultiAsString(Property property, String separator) throws RepositoryException {
- if (separator == null)
- separator = "; ";
- Value[] values = property.getValues();
- StringBuilder builder = new StringBuilder();
- for (Value val : values) {
- String currStr = val.getString();
- if (!"".equals(currStr.trim()))
- builder.append(currStr).append(separator);
- }
- if (builder.lastIndexOf(separator) >= 0)
- return builder.substring(0, builder.length() - separator.length());
- else
- return builder.toString();
- }
-
- /** Almost canonical implementation of a table that display entities */
- private class FilterEntitiesVirtualTable extends Composite {
- private static final long serialVersionUID = 8798147431706283824L;
-
- // Context
- private Node context;
-
- // UI Objects
- private TableViewer entityViewer;
-
- // enable management of multiple columns
- Node getNode() {
- return context;
- }
-
- @Override
- public boolean setFocus() {
- if (entityViewer.getTable().isDisposed())
- return false;
- if (entityViewer.getSelection().isEmpty()) {
- Object first = entityViewer.getElementAt(0);
- if (first != null) {
- entityViewer.setSelection(new StructuredSelection(first), true);
- }
- }
- return entityViewer.getTable().setFocus();
- }
-
- void filterList(String filter) {
- try {
- NodeIterator nit = context.getNodes(filter);
- refreshFilteredList(nit);
- } catch (RepositoryException e) {
- throw new CmsException("Unable to filter " + getNode() + " children with filter " + filter, e);
- }
-
- }
-
- public FilterEntitiesVirtualTable(Composite parent, int style, Node context) {
- super(parent, SWT.NO_FOCUS);
- this.context = context;
- populate();
- }
-
- protected void populate() {
- Composite parent = this;
- GridLayout layout = CmsSwtUtils.noSpaceGridLayout();
-
- this.setLayout(layout);
- createTableViewer(parent);
- }
-
- private void createTableViewer(final Composite parent) {
- // the list
- // We must limit the size of the table otherwise the full list is
- // loaded
- // before the layout happens
- Composite listCmp = new Composite(parent, SWT.NO_FOCUS);
- GridData gd = new GridData(SWT.LEFT, SWT.FILL, false, true);
- gd.widthHint = COLUMN_WIDTH;
- listCmp.setLayoutData(gd);
- listCmp.setLayout(CmsSwtUtils.noSpaceGridLayout());
-
- entityViewer = new TableViewer(listCmp, SWT.VIRTUAL | SWT.SINGLE);
- Table table = entityViewer.getTable();
-
- table.setLayoutData(CmsSwtUtils.fillAll());
- table.setLinesVisible(true);
- table.setHeaderVisible(false);
- CmsSwtUtils.markup(table);
-
- CmsSwtUtils.style(table, MaintenanceStyles.BROWSER_COLUMN);
-
- // first column
- TableViewerColumn column = new TableViewerColumn(entityViewer, SWT.NONE);
- TableColumn tcol = column.getColumn();
- tcol.setWidth(COLUMN_WIDTH);
- tcol.setResizable(true);
- column.setLabelProvider(new SimpleNameLP());
-
- entityViewer.setContentProvider(new MyLazyCP(entityViewer));
- entityViewer.addSelectionChangedListener(new ISelectionChangedListener() {
-
- @Override
- public void selectionChanged(SelectionChangedEvent event) {
- IStructuredSelection selection = (IStructuredSelection) entityViewer.getSelection();
- if (selection.isEmpty())
- return;
- else
- setEdited((Node) selection.getFirstElement());
-
- }
- });
-
- table.addKeyListener(new KeyListener() {
- private static final long serialVersionUID = -330694313896036230L;
-
- @Override
- public void keyReleased(KeyEvent e) {
- }
-
- @Override
- public void keyPressed(KeyEvent e) {
-
- IStructuredSelection selection = (IStructuredSelection) entityViewer.getSelection();
- Node selected = null;
- if (!selection.isEmpty())
- selected = ((Node) selection.getFirstElement());
- try {
- if (e.keyCode == SWT.ARROW_RIGHT) {
- if (selected != null) {
- setEdited(selected);
- browserCols.get(selected.getPath()).setFocus();
- }
- } else if (e.keyCode == SWT.ARROW_LEFT) {
- try {
- selected = getNode().getParent();
- String newPath = selected.getPath(); // getNode().getParent()
- setEdited(selected);
- if (browserCols.containsKey(newPath))
- browserCols.get(newPath).setFocus();
- } catch (ItemNotFoundException ie) {
- // root silent
- }
- }
- } catch (RepositoryException ie) {
- throw new CmsException("Error while managing arrow " + "events in the browser for " + selected,
- ie);
- }
- }
- });
- }
-
- private class MyLazyCP implements ILazyContentProvider {
- private static final long serialVersionUID = 1L;
- private TableViewer viewer;
- private Object[] elements;
-
- public MyLazyCP(TableViewer viewer) {
- this.viewer = viewer;
- }
-
- public void dispose() {
- }
-
- public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
- // IMPORTANT: don't forget this: an exception will be thrown if
- // a selected object is not part of the results anymore.
- viewer.setSelection(null);
- this.elements = (Object[]) newInput;
- }
-
- public void updateElement(int index) {
- viewer.replace(elements[index], index);
- }
- }
-
- protected void refreshFilteredList(NodeIterator children) {
- Object[] rows = JcrUtils.nodeIteratorToList(children).toArray();
- entityViewer.setInput(rows);
- entityViewer.setItemCount(rows.length);
- entityViewer.refresh();
- }
-
- public class SimpleNameLP extends ColumnLabelProvider {
- private static final long serialVersionUID = 2465059387875338553L;
-
- @Override
- public String getText(Object element) {
- if (element instanceof Node) {
- Node curr = ((Node) element);
- try {
- return curr.getName();
- } catch (RepositoryException e) {
- throw new CmsException("Unable to get name for" + curr);
- }
- }
- return super.getText(element);
- }
- }
- }
-}
\ No newline at end of file