X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=plugins%2Forg.argeo.slc.client.ui.dist%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fslc%2Fclient%2Fui%2Fdist%2Feditors%2FDistributionOverviewPage.java;h=4468cc9194f8e2cbbedee13f9818a44e8ce38a7c;hb=941542e5c89c1058d0b9607188bcb9c9ed10072c;hp=e6f5558e283c14534d452877ad9fa2f88236cd62;hpb=30337022a8b1ffe10eb645791d767d41c3db4e40;p=gpl%2Fargeo-slc.git diff --git a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/DistributionOverviewPage.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/DistributionOverviewPage.java index e6f5558e2..4468cc919 100644 --- a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/DistributionOverviewPage.java +++ b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/DistributionOverviewPage.java @@ -1,3 +1,18 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.argeo.slc.client.ui.dist.editors; import java.util.ArrayList; @@ -10,13 +25,19 @@ import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.query.QueryManager; import javax.jcr.query.QueryResult; +import javax.jcr.query.qom.Constraint; +import javax.jcr.query.qom.DynamicOperand; import javax.jcr.query.qom.Ordering; import javax.jcr.query.qom.QueryObjectModel; import javax.jcr.query.qom.QueryObjectModelFactory; import javax.jcr.query.qom.Selector; +import javax.jcr.query.qom.StaticOperand; +import org.argeo.ArgeoException; import org.argeo.eclipse.ui.ErrorFeedback; import org.argeo.jcr.JcrUtils; +import org.argeo.slc.client.ui.dist.DistConstants; +import org.argeo.slc.client.ui.dist.DistImages; import org.argeo.slc.client.ui.dist.DistPlugin; import org.argeo.slc.client.ui.dist.commands.DeleteArtifacts; import org.argeo.slc.client.ui.dist.utils.CommandHelpers; @@ -27,32 +48,54 @@ import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.IStructuredSelection; 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.events.ControlEvent; +import org.eclipse.swt.events.ControlListener; +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.events.SelectionListener; 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.Label; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.Text; import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PartInitException; import org.eclipse.ui.forms.IManagedForm; import org.eclipse.ui.forms.editor.FormEditor; import org.eclipse.ui.forms.editor.FormPage; +import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.forms.widgets.ScrolledForm; -import org.osgi.framework.Constants; -/** Table giving an overview of an OSGi distribution */ +/** Table giving an overview of an OSGi distribution with corresponding filters */ public class DistributionOverviewPage extends FormPage implements SlcNames { final static String PAGE_ID = "distributionOverviewPage"; + // final private static Log log = LogFactory + // .getLog(DistributionOverviewPage.class); - private TableViewer viewer; + // Business Objects private Session session; + // This page widgets private NodeViewerComparator comparator; + private TableViewer viewer; + private Text artifactTxt; + private FormToolkit tk; + private Composite header; + + // private Section headerSection; public DistributionOverviewPage(FormEditor formEditor, String title, Session session) { @@ -63,84 +106,218 @@ public class DistributionOverviewPage extends FormPage implements SlcNames { @Override protected void createFormContent(IManagedForm managedForm) { ScrolledForm form = managedForm.getForm(); + tk = managedForm.getToolkit(); + + // Main Layout GridLayout layout = new GridLayout(1, false); - form.getBody().setLayout(layout); + Composite body = form.getBody(); + body.setLayout(layout); + + // Add the filter section + createFilterPart(body); + // Add the table + createTableViewer(body); + + viewer.setInput(session); + resetFilter(); + + // Add a listener to enable custom resize process + form.addControlListener(new ControlListener() { + public void controlResized(ControlEvent e) { + refreshLayout(); + } + + public void controlMoved(ControlEvent e) { + } + }); + + // This below doesn not work; the listener must be added as a control + // listener to be correctly notified when resize events happen + + // form.addListener(SWT.RESIZE, new Listener() { + // public void handleEvent(Event event) { + // log.debug("Form resized ...."); + // } + // }); + + } + + /** Build repository request */ + private NodeIterator listBundleArtifacts(Session session) + throws RepositoryException { + QueryManager queryManager = session.getWorkspace().getQueryManager(); + QueryObjectModelFactory factory = queryManager.getQOMFactory(); + + final String bundleArtifactsSelector = "bundleArtifacts"; + Selector source = factory.selector(SlcTypes.SLC_BUNDLE_ARTIFACT, + bundleArtifactsSelector); + + // Create a dynamic operand for each property on which we want to filter + DynamicOperand symbNameDO = factory.propertyValue( + source.getSelectorName(), SlcNames.SLC_SYMBOLIC_NAME); + DynamicOperand versionDO = factory.propertyValue( + source.getSelectorName(), SlcNames.SLC_BUNDLE_VERSION); + DynamicOperand nameDO = factory.propertyValue(source.getSelectorName(), + DistConstants.SLC_BUNDLE_NAME); + + // Default Constraint: no source artifacts + Constraint defaultC = factory.not(factory.comparison( + symbNameDO, + QueryObjectModelFactory.JCR_OPERATOR_LIKE, + factory.literal(session.getValueFactory().createValue( + "%.source")))); + + // Build constraints based the textArea content + String artifactTxtVal = artifactTxt.getText(); + if (!"".equals(artifactTxtVal.trim())) { + // Parse the String + String[] strs = artifactTxtVal.trim().split(" "); + for (String token : strs) { + token = token.replace('*', '%'); + StaticOperand so = factory.literal(session.getValueFactory() + .createValue("%" + token + "%")); + + Constraint currC = factory.comparison(symbNameDO, + QueryObjectModelFactory.JCR_OPERATOR_LIKE, so); + currC = factory.or(currC, factory.comparison(versionDO, + QueryObjectModelFactory.JCR_OPERATOR_LIKE, so)); + currC = factory.or(currC, factory.comparison(nameDO, + QueryObjectModelFactory.JCR_OPERATOR_LIKE, so)); + + defaultC = factory.and(defaultC, currC); + } + } + + Ordering order = factory.descending(factory.propertyValue( + bundleArtifactsSelector, SlcNames.SLC_BUNDLE_VERSION)); + Ordering order2 = factory.ascending(factory.propertyValue( + bundleArtifactsSelector, SlcNames.SLC_SYMBOLIC_NAME)); + Ordering[] orderings = { order, order2 }; + QueryObjectModel query = factory.createQuery(source, defaultC, + orderings, null); + + QueryResult result = query.execute(); + return result.getNodes(); + + } + + private void createFilterPart(Composite parent) { + header = tk.createComposite(parent); + GridLayout layout = new GridLayout(2, false); + header.setLayout(layout); + GridData gd = new GridData(SWT.FILL, SWT.FILL, false, false); + header.setLayoutData(gd); + + // TODO display real repository information + // Title: some meta information + Label lbl = tk.createLabel(header, "Current repository: ", SWT.NONE); + + gd = new GridData(SWT.FILL, SWT.FILL, false, false); + gd.horizontalSpan = 2; + lbl.setLayoutData(gd); + + // Text Area to filter + artifactTxt = tk.createText(header, "", SWT.BORDER | SWT.SINGLE); + gd = new GridData(SWT.FILL, SWT.FILL, false, false); + gd.grabExcessHorizontalSpace = true; + artifactTxt.setLayoutData(gd); + artifactTxt.addModifyListener(new ModifyListener() { + + public void modifyText(ModifyEvent event) { + refreshFilteredList(); + } + }); + + Button resetBtn = tk.createButton(header, null, SWT.PUSH); + resetBtn.setImage(DistImages.IMG_REPO_READONLY); + resetBtn.addSelectionListener(new SelectionListener() { + + public void widgetSelected(SelectionEvent e) { + resetFilter(); + } + + public void widgetDefaultSelected(SelectionEvent e) { + } + }); + + } + + private void resetFilter() { + artifactTxt.setText(""); + artifactTxt.setMessage("Enter filter criterion separated by a space"); + viewer.refresh(); + } + + private void refreshFilteredList() { + viewer.refresh(); + } + + private void createTableViewer(Composite parent) { // helpers to enable sorting by column List propertiesList = new ArrayList(); List propertyTypesList = new ArrayList(); // Define the TableViewer - viewer = new TableViewer(form.getBody(), SWT.MULTI | SWT.H_SCROLL + viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER); - TableViewerColumn col = new TableViewerColumn(viewer, SWT.V_SCROLL); + // Name + TableViewerColumn col = new TableViewerColumn(viewer, SWT.NONE); col.getColumn().setWidth(300); - col.getColumn().setText("Symbolic name"); + col.getColumn().setText("Name"); col.setLabelProvider(new ColumnLabelProvider() { @Override public String getText(Object element) { - return JcrUtils.get((Node) element, SLC_SYMBOLIC_NAME); + return JcrUtils.get((Node) element, + DistConstants.SLC_BUNDLE_NAME); } }); col.getColumn().addSelectionListener(getSelectionAdapter(0)); - propertiesList.add(SLC_SYMBOLIC_NAME); + propertiesList.add(DistConstants.SLC_BUNDLE_NAME); propertyTypesList.add(PropertyType.STRING); - col = new TableViewerColumn(viewer, SWT.NONE); - col.getColumn().setWidth(100); - col.getColumn().setText("Version"); + // Symbolic name + col = new TableViewerColumn(viewer, SWT.V_SCROLL); + col.getColumn().setWidth(300); + col.getColumn().setText("Symbolic name"); col.setLabelProvider(new ColumnLabelProvider() { @Override public String getText(Object element) { - return JcrUtils.get((Node) element, SLC_BUNDLE_VERSION); + return JcrUtils.get((Node) element, SLC_SYMBOLIC_NAME); } }); col.getColumn().addSelectionListener(getSelectionAdapter(1)); - propertiesList.add(SLC_BUNDLE_VERSION); + propertiesList.add(SLC_SYMBOLIC_NAME); propertyTypesList.add(PropertyType.STRING); + // Version col = new TableViewerColumn(viewer, SWT.NONE); - col.getColumn().setWidth(150); - col.getColumn().setText("Group ID"); + col.getColumn().setWidth(100); + col.getColumn().setText("Version"); col.setLabelProvider(new ColumnLabelProvider() { @Override public String getText(Object element) { - return JcrUtils.get((Node) element, SLC_GROUP_ID); + return JcrUtils.get((Node) element, SLC_BUNDLE_VERSION); } }); col.getColumn().addSelectionListener(getSelectionAdapter(2)); - propertiesList.add(SLC_GROUP_ID); - propertyTypesList.add(PropertyType.STRING); - - col = new TableViewerColumn(viewer, SWT.NONE); - col.getColumn().setWidth(300); - col.getColumn().setText("Name"); - col.setLabelProvider(new ColumnLabelProvider() { - @Override - public String getText(Object element) { - return JcrUtils.get((Node) element, SLC_ - + Constants.BUNDLE_NAME); - } - }); - col.getColumn().addSelectionListener(getSelectionAdapter(3)); - propertiesList.add(SLC_ + Constants.BUNDLE_NAME); + propertiesList.add(SLC_BUNDLE_VERSION); propertyTypesList.add(PropertyType.STRING); final Table table = viewer.getTable(); table.setHeaderVisible(true); table.setLinesVisible(true); - table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); viewer.setContentProvider(new DistributionsContentProvider()); getSite().setSelectionProvider(viewer); - viewer.setInput(session); - comparator = new NodeViewerComparator(1, - NodeViewerComparator.DESCENDING, propertiesList, + comparator = new NodeViewerComparator(2, + NodeViewerComparator.ASCENDING, propertiesList, propertyTypesList); viewer.setComparator(comparator); + // Context Menu MenuManager menuManager = new MenuManager(); Menu menu = menuManager.createContextMenu(viewer.getTable()); menuManager.addMenuListener(new IMenuListener() { @@ -151,6 +328,8 @@ public class DistributionOverviewPage extends FormPage implements SlcNames { viewer.getTable().setMenu(menu); getSite().registerContextMenu(menuManager, viewer); + // Double click + viewer.addDoubleClickListener(new DoubleClickListener()); } @Override @@ -163,12 +342,12 @@ public class DistributionOverviewPage extends FormPage implements SlcNames { viewer.refresh(); } - /** Programatically configure the context menu */ + /** Programmatically configure the context menu */ protected void contextMenuAboutToShow(IMenuManager menuManager) { IWorkbenchWindow window = DistPlugin.getDefault().getWorkbench() .getActiveWorkbenchWindow(); - // Build conditions depending on element type (repo or workspace) + // Build conditions // Delete selected artifacts CommandHelpers.refreshCommand(menuManager, window, DeleteArtifacts.ID, @@ -177,26 +356,6 @@ public class DistributionOverviewPage extends FormPage implements SlcNames { } - static NodeIterator listBundleArtifacts(Session session) - throws RepositoryException { - QueryManager queryManager = session.getWorkspace().getQueryManager(); - QueryObjectModelFactory factory = queryManager.getQOMFactory(); - - final String bundleArtifactsSelector = "bundleArtifacts"; - Selector source = factory.selector(SlcTypes.SLC_BUNDLE_ARTIFACT, - bundleArtifactsSelector); - - Ordering order = factory.ascending(factory.propertyValue( - bundleArtifactsSelector, SlcNames.SLC_SYMBOLIC_NAME)); - Ordering[] orderings = { order }; - - QueryObjectModel query = factory.createQuery(source, null, orderings, - null); - - QueryResult result = query.execute(); - return result.getNodes(); - } - private SelectionAdapter getSelectionAdapter(final int index) { SelectionAdapter selectionAdapter = new SelectionAdapter() { @Override @@ -217,15 +376,16 @@ public class DistributionOverviewPage extends FormPage implements SlcNames { return selectionAdapter; } - private static class DistributionsContentProvider implements + /* LOCAL CLASSES */ + private class DistributionsContentProvider implements IStructuredContentProvider { - private Session session; + // private Session session; public void dispose() { } public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - session = (Session) newInput; + // session = (Session) newInput; } public Object[] getElements(Object arg0) { @@ -239,72 +399,61 @@ public class DistributionOverviewPage extends FormPage implements SlcNames { } } } - // - // private class BoundedLayout extends Layout { - // protected Layout delegateLayout; - // - // protected Method computeSizeMethod; - // protected Method layoutMethod; - // - // protected boolean widthBound; - // - // public BoundedLayout(Layout delegateLayout, boolean widthBound) { - // setDelegateLayout(delegateLayout); - // this.widthBound = widthBound; - // } - // - // public Layout getDelegateLayout() { - // return delegateLayout; - // } - // - // public void setDelegateLayout(Layout delegateLayout) { - // this.delegateLayout = delegateLayout; - // - // try { - // computeSizeMethod = delegateLayout.getClass() - // .getDeclaredMethod("computeSize", Composite.class, - // int.class, int.class, boolean.class); - // computeSizeMethod.setAccessible(true); - // - // layoutMethod = delegateLayout.getClass().getDeclaredMethod( - // "layout", Composite.class, boolean.class); - // layoutMethod.setAccessible(true); - // } catch (Exception e) { - // throw new RuntimeException(e); - // } - // } - // - // @Override - // protected Point computeSize(Composite composite, int wHint, int hHint, - // boolean flushCache) { - // // get comp size to make sure we don't let any children exceed it - // Point compSize = composite.getSize(); - // - // try { - // Point layoutComputedSize = (Point) computeSizeMethod.invoke( - // delegateLayout, composite, wHint, hHint, flushCache); - // - // if (widthBound) { - // layoutComputedSize.x = Math.min(compSize.x, - // layoutComputedSize.x); - // } else { - // layoutComputedSize.y = Math.min(compSize.y, - // layoutComputedSize.y); - // } - // - // return layoutComputedSize; - // } catch (Exception e) { - // throw new RuntimeException(e); - // } - // } - // - // @Override - // protected void layout(Composite composite, boolean flushCache) { - // try { - // layoutMethod.invoke(delegateLayout, composite, flushCache); - // } catch (Exception e) { - // throw new RuntimeException(e); - // } - // } - // } + + private class DoubleClickListener implements IDoubleClickListener { + + public void doubleClick(DoubleClickEvent event) { + Object obj = ((IStructuredSelection) event.getSelection()) + .getFirstElement(); + try { + if (obj instanceof Node) { + Node node = (Node) obj; + if (node.isNodeType(SlcTypes.SLC_BUNDLE_ARTIFACT)) { + GenericBundleEditorInput gaei = new GenericBundleEditorInput( + node); + DistPlugin.getDefault().getWorkbench() + .getActiveWorkbenchWindow().getActivePage() + .openEditor(gaei, GenericBundleEditor.ID); + } + } + } catch (RepositoryException re) { + throw new ArgeoException( + "Repository error while getting node info", re); + } catch (PartInitException pie) { + throw new ArgeoException( + "Unexepected exception while opening artifact editor", + pie); + } + } + } + + /** + * UI Trick to put scroll bar on the table rather than on the scrollform + */ + private void refreshLayout() { + // Compute desired table size + int maxH = getManagedForm().getForm().getSize().y; + int maxW = getManagedForm().getForm().getParent().getSize().x; + maxH = maxH - header.getSize().y; + final Table table = viewer.getTable(); + GridData gd = new GridData(SWT.LEFT, SWT.TOP, true, true); + + // when table height is less than 200 px, we let the scroll bar on the + // scrollForm + // FIXME substract some spare space. Here is room for optimization + gd.heightHint = Math.max(maxH - 35, 200); + gd.widthHint = Math.max(maxW - 35, 200); + + table.setLayoutData(gd); + getManagedForm().reflow(true); + } + + @Override + public void setActive(boolean active) { + super.setActive(active); + if (active) { + refreshLayout(); + } + } + } \ No newline at end of file