Move UX components between packages
authorMathieu Baudier <mbaudier@argeo.org>
Thu, 23 Jun 2022 10:59:13 +0000 (12:59 +0200)
committerMathieu Baudier <mbaudier@argeo.org>
Thu, 23 Jun 2022 10:59:13 +0000 (12:59 +0200)
38 files changed:
eclipse/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/JcrBrowserView.java
eclipse/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/handlers/AddFolderNode.java
eclipse/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/handlers/DeleteNodes.java
eclipse/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/handlers/Refresh.java
eclipse/org.argeo.cms.e4/src/org/argeo/cms/e4/monitoring/BundleNode.java
eclipse/org.argeo.cms.e4/src/org/argeo/cms/e4/monitoring/ModulesView.java
eclipse/org.argeo.cms.e4/src/org/argeo/cms/e4/monitoring/ServiceReferenceNode.java
eclipse/org.argeo.cms.swt/src/org/argeo/cms/jface/dialog/CmsWizardDialog.java [new file with mode: 0644]
eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/EditablePart.java [deleted file]
eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/SwtEditablePart.java [new file with mode: 0644]
eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/acr/SwtSection.java [new file with mode: 0644]
eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/acr/SwtSectionPart.java [new file with mode: 0644]
eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/acr/SwtTabbedArea.java [new file with mode: 0644]
eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/dialogs/CmsWizardDialog.java [deleted file]
eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/widgets/SwtSection.java [deleted file]
eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/widgets/SwtSectionPart.java [deleted file]
eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/widgets/SwtTabbedArea.java [deleted file]
eclipse/org.argeo.cms.swt/src/org/argeo/eclipse/ui/AbstractTreeContentProvider.java
eclipse/org.argeo.cms.swt/src/org/argeo/eclipse/ui/TreeParent.java [deleted file]
jcr/org.argeo.cms.ui/src/org/argeo/cms/ui/forms/EditableLink.java
jcr/org.argeo.cms.ui/src/org/argeo/cms/ui/forms/EditableMultiStringProperty.java
jcr/org.argeo.cms.ui/src/org/argeo/cms/ui/forms/EditablePropertyDate.java
jcr/org.argeo.cms.ui/src/org/argeo/cms/ui/forms/EditablePropertyString.java
jcr/org.argeo.cms.ui/src/org/argeo/cms/ui/forms/FormPageViewer.java
jcr/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/JcrBrowserUtils.java
jcr/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/NodeContentProvider.java
jcr/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/model/MaintainedRepositoryElem.java
jcr/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/model/RemoteRepositoryElem.java
jcr/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/model/RepositoriesElem.java
jcr/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/model/RepositoryElem.java
jcr/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/model/SingleJcrNodeElem.java
jcr/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/model/WorkspaceElem.java
jcr/org.argeo.cms.ui/src/org/argeo/cms/ui/viewers/AbstractPageViewer.java
jcr/org.argeo.cms.ui/src/org/argeo/cms/ui/viewers/Section.java
jcr/org.argeo.cms.ui/src/org/argeo/cms/ui/viewers/SectionPart.java
org.argeo.cms.ux/src/org/argeo/cms/ux/acr/ContentPart.java [new file with mode: 0644]
org.argeo.cms.ux/src/org/argeo/cms/ux/widgets/ContentPart.java [deleted file]
org.argeo.cms.ux/src/org/argeo/cms/ux/widgets/TreeParent.java [new file with mode: 0644]

index 98e80936da362693bf1844582fd470a52521177b..46e1b6507c53ff784b7fe9a26b290e5c9f2053f8 100644 (file)
@@ -27,8 +27,8 @@ import org.argeo.cms.ui.jcr.NodeLabelProvider;
 import org.argeo.cms.ui.jcr.OsgiRepositoryRegister;
 import org.argeo.cms.ui.jcr.PropertiesContentProvider;
 import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem;
+import org.argeo.cms.ux.widgets.TreeParent;
 import org.argeo.eclipse.ui.EclipseUiException;
-import org.argeo.eclipse.ui.TreeParent;
 import org.argeo.eclipse.ui.jcr.AsyncUiEventListener;
 import org.argeo.eclipse.ui.jcr.util.NodeViewerComparer;
 import org.argeo.jcr.JcrUtils;
index 8f5bc36e176477d0c2c1a9a83e1853b51df83d3a..09fa760cd29a0aedf63af482d84acebe4550e49b 100644 (file)
@@ -10,7 +10,7 @@ import javax.jcr.nodetype.NodeType;
 import org.argeo.cms.e4.jcr.JcrBrowserView;
 import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem;
 import org.argeo.cms.ui.jcr.model.WorkspaceElem;
-import org.argeo.eclipse.ui.TreeParent;
+import org.argeo.cms.ux.widgets.TreeParent;
 import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
 import org.argeo.eclipse.ui.dialogs.SingleValue;
 import org.eclipse.e4.core.di.annotations.Execute;
index 1974e4d444f030a1cd99d2fb0fdbc01cc3c5353a..b8de06b463dbf4b6b3229395ed76909efca6d9ff 100644 (file)
@@ -9,8 +9,8 @@ import javax.jcr.RepositoryException;
 import org.argeo.cms.e4.jcr.JcrBrowserView;
 import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem;
 import org.argeo.cms.ui.jcr.model.WorkspaceElem;
+import org.argeo.cms.ux.widgets.TreeParent;
 import org.argeo.eclipse.ui.EclipseUiException;
-import org.argeo.eclipse.ui.TreeParent;
 import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
 import org.eclipse.e4.core.di.annotations.Execute;
 import org.eclipse.e4.ui.model.application.ui.basic.MPart;
index 4ae072cb577bf01660f010618db6f73414516462..036e70ac1df752b7a6691e1ec06abdc4f7df26f6 100644 (file)
@@ -6,7 +6,7 @@ import javax.inject.Named;
 
 import org.argeo.cms.e4.jcr.JcrBrowserView;
 import org.argeo.cms.ui.jcr.JcrBrowserUtils;
-import org.argeo.eclipse.ui.TreeParent;
+import org.argeo.cms.ux.widgets.TreeParent;
 import org.eclipse.e4.core.di.annotations.Execute;
 import org.eclipse.e4.ui.model.application.ui.basic.MPart;
 import org.eclipse.e4.ui.services.IServiceConstants;
index 962ad386e649d19fe3fe5d4404ea019c1c03534f..e9536830f72bf6cce0e47f1788ff70f4f94856c0 100644 (file)
@@ -1,6 +1,6 @@
 package org.argeo.cms.e4.monitoring;
 
-import org.argeo.eclipse.ui.TreeParent;
+import org.argeo.cms.ux.widgets.TreeParent;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.ServiceReference;
 
index f0d8c29521776777dd4369263182f8e4074092a2..6317882c44fe5b09017aedbcf00ee6feeae842f9 100644 (file)
@@ -5,7 +5,7 @@ import java.util.List;
 
 import javax.annotation.PostConstruct;
 
-import org.argeo.eclipse.ui.TreeParent;
+import org.argeo.cms.ux.widgets.TreeParent;
 import org.eclipse.e4.ui.di.Focus;
 import org.eclipse.jface.viewers.ITreeContentProvider;
 import org.eclipse.jface.viewers.TreeViewer;
index d9c45fe1103cef34c96575821ad83bbd62bed079..1c60811d2339410d973de41441ec87e1fd60c3a6 100644 (file)
@@ -1,6 +1,6 @@
 package org.argeo.cms.e4.monitoring;
 
-import org.argeo.eclipse.ui.TreeParent;
+import org.argeo.cms.ux.widgets.TreeParent;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.ServiceReference;
 
diff --git a/eclipse/org.argeo.cms.swt/src/org/argeo/cms/jface/dialog/CmsWizardDialog.java b/eclipse/org.argeo.cms.swt/src/org/argeo/cms/jface/dialog/CmsWizardDialog.java
new file mode 100644 (file)
index 0000000..33841a1
--- /dev/null
@@ -0,0 +1,222 @@
+package org.argeo.cms.jface.dialog;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.argeo.cms.CmsMsg;
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.cms.swt.Selected;
+import org.argeo.cms.swt.dialogs.LightweightDialog;
+import org.argeo.eclipse.ui.EclipseUiUtils;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.wizard.IWizard;
+import org.eclipse.jface.wizard.IWizardContainer2;
+import org.eclipse.jface.wizard.IWizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+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.Label;
+import org.eclipse.swt.widgets.Shell;
+
+/** A wizard dialog based on {@link LightweightDialog}. */
+public class CmsWizardDialog extends LightweightDialog implements IWizardContainer2 {
+       private static final long serialVersionUID = -2123153353654812154L;
+
+       private IWizard wizard;
+       private IWizardPage currentPage;
+       private int currentPageIndex;
+
+       private Label titleBar;
+       private Label message;
+       private Composite[] pageBodies;
+       private Composite buttons;
+       private Button back;
+       private Button next;
+       private Button finish;
+
+       public CmsWizardDialog(Shell parentShell, IWizard wizard) {
+               super(parentShell);
+               this.wizard = wizard;
+               wizard.setContainer(this);
+               // create the pages
+               wizard.addPages();
+               currentPage = wizard.getStartingPage();
+               if (currentPage == null)
+                       throw new IllegalArgumentException("At least one wizard page is required");
+       }
+
+       @Override
+       protected Control createDialogArea(Composite parent) {
+               updateWindowTitle();
+
+               Composite messageArea = new Composite(parent, SWT.NONE);
+               messageArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+               {
+                       messageArea.setLayout(CmsSwtUtils.noSpaceGridLayout(new GridLayout(2, false)));
+                       titleBar = new Label(messageArea, SWT.WRAP);
+                       titleBar.setFont(EclipseUiUtils.getBoldFont(parent));
+                       titleBar.setLayoutData(new GridData(SWT.BEGINNING, SWT.FILL, true, false));
+                       updateTitleBar();
+                       Button cancelButton = new Button(messageArea, SWT.FLAT);
+                       cancelButton.setText(CmsMsg.cancel.lead());
+                       cancelButton.setLayoutData(new GridData(SWT.END, SWT.TOP, false, false, 1, 3));
+                       cancelButton.addSelectionListener((Selected) (e) -> closeShell(CANCEL));
+                       message = new Label(messageArea, SWT.WRAP);
+                       message.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 2));
+                       updateMessage();
+               }
+
+               Composite body = new Composite(parent, SWT.BORDER);
+               body.setLayout(new FormLayout());
+               body.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+               pageBodies = new Composite[wizard.getPageCount()];
+               IWizardPage[] pages = wizard.getPages();
+               for (int i = 0; i < pages.length; i++) {
+                       pageBodies[i] = new Composite(body, SWT.NONE);
+                       pageBodies[i].setLayout(CmsSwtUtils.noSpaceGridLayout());
+                       setSwitchingFormData(pageBodies[i]);
+                       pages[i].createControl(pageBodies[i]);
+               }
+               showPage(currentPage);
+
+               buttons = new Composite(parent, SWT.NONE);
+               buttons.setLayoutData(new GridData(SWT.END, SWT.FILL, true, false));
+               {
+                       boolean singlePage = wizard.getPageCount() == 1;
+                       // singlePage = false;// dev
+                       GridLayout layout = new GridLayout(singlePage ? 1 : 3, true);
+                       layout.marginWidth = 0;
+                       layout.marginHeight = 0;
+                       buttons.setLayout(layout);
+                       // TODO revert order for right-to-left languages
+
+                       if (!singlePage) {
+                               back = new Button(buttons, SWT.PUSH);
+                               back.setText(CmsMsg.wizardBack.lead());
+                               back.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
+                               back.addSelectionListener((Selected) (e) -> backPressed());
+
+                               next = new Button(buttons, SWT.PUSH);
+                               next.setText(CmsMsg.wizardNext.lead());
+                               next.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
+                               next.addSelectionListener((Selected) (e) -> nextPressed());
+                       }
+                       finish = new Button(buttons, SWT.PUSH);
+                       finish.setText(CmsMsg.wizardFinish.lead());
+                       finish.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
+                       finish.addSelectionListener((Selected) (e) -> finishPressed());
+
+                       updateButtons();
+               }
+               return body;
+       }
+
+       @Override
+       public IWizardPage getCurrentPage() {
+               return currentPage;
+       }
+
+       @Override
+       public Shell getShell() {
+               return getForegoundShell();
+       }
+
+       @Override
+       public void showPage(IWizardPage page) {
+               IWizardPage[] pages = wizard.getPages();
+               int index = -1;
+               for (int i = 0; i < pages.length; i++) {
+                       if (page == pages[i]) {
+                               index = i;
+                               break;
+                       }
+               }
+               if (index < 0)
+                       throw new IllegalArgumentException("Cannot find index of wizard page " + page);
+               pageBodies[index].moveAbove(pageBodies[currentPageIndex]);
+
+               // // clear
+               // for (Control c : body.getChildren())
+               // c.dispose();
+               // page.createControl(body);
+               // body.layout(true, true);
+               currentPageIndex = index;
+               currentPage = page;
+       }
+
+       @Override
+       public void updateButtons() {
+               if (back != null)
+                       back.setEnabled(wizard.getPreviousPage(currentPage) != null);
+               if (next != null)
+                       next.setEnabled(wizard.getNextPage(currentPage) != null && currentPage.canFlipToNextPage());
+               if (finish != null) {
+                       finish.setEnabled(wizard.canFinish());
+               }
+       }
+
+       @Override
+       public void updateMessage() {
+               if (currentPage.getMessage() != null)
+                       message.setText(currentPage.getMessage());
+       }
+
+       @Override
+       public void updateTitleBar() {
+               if (currentPage.getTitle() != null)
+                       titleBar.setText(currentPage.getTitle());
+       }
+
+       @Override
+       public void updateWindowTitle() {
+               setTitle(wizard.getWindowTitle());
+       }
+
+       @Override
+       public void run(boolean fork, boolean cancelable, IRunnableWithProgress runnable)
+                       throws InvocationTargetException, InterruptedException {
+               // FIXME it creates a dependency to Eclipse Core Runtime
+               // runnable.run(null);
+       }
+
+       @Override
+       public void updateSize() {
+               // TODO pack?
+       }
+
+       protected boolean onCancel() {
+               return wizard.performCancel();
+       }
+
+       protected void nextPressed() {
+               IWizardPage page = wizard.getNextPage(currentPage);
+               showPage(page);
+               updateButtons();
+       }
+
+       protected void backPressed() {
+               IWizardPage page = wizard.getPreviousPage(currentPage);
+               showPage(page);
+               updateButtons();
+       }
+
+       protected void finishPressed() {
+               if (wizard.performFinish())
+                       closeShell(OK);
+       }
+
+       private static void setSwitchingFormData(Composite composite) {
+               FormData fdLabel = new FormData();
+               fdLabel.top = new FormAttachment(0, 0);
+               fdLabel.left = new FormAttachment(0, 0);
+               fdLabel.right = new FormAttachment(100, 0);
+               fdLabel.bottom = new FormAttachment(100, 0);
+               composite.setLayoutData(fdLabel);
+       }
+
+}
diff --git a/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/EditablePart.java b/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/EditablePart.java
deleted file mode 100644 (file)
index 90c1677..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.argeo.cms.swt;
-
-import org.eclipse.swt.widgets.Control;
-
-/** Manages whether an editable or non editable control is shown. */
-public interface EditablePart {
-       public void startEditing();
-
-       public void stopEditing();
-
-       public Control getControl();
-}
diff --git a/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/SwtEditablePart.java b/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/SwtEditablePart.java
new file mode 100644 (file)
index 0000000..f2cceef
--- /dev/null
@@ -0,0 +1,9 @@
+package org.argeo.cms.swt;
+
+import org.argeo.cms.ux.widgets.EditablePart;
+import org.eclipse.swt.widgets.Control;
+
+/** Manages whether an editable or non editable control is shown. */
+public interface SwtEditablePart extends EditablePart {
+       public Control getControl();
+}
diff --git a/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/acr/SwtSection.java b/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/acr/SwtSection.java
new file mode 100644 (file)
index 0000000..89d0038
--- /dev/null
@@ -0,0 +1,158 @@
+package org.argeo.cms.swt.acr;
+
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.argeo.api.acr.Content;
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.cms.ux.widgets.EditablePart;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+/** A structured UI related to a JCR context. */
+public class SwtSection extends ContentComposite {
+       private static final long serialVersionUID = -5933796173755739207L;
+
+       private final SwtSection parentSection;
+       private Composite sectionHeader;
+       private final Integer relativeDepth;
+
+       public SwtSection(Composite parent, int style, Content node) {
+               this(parent, findSection(parent), style, node);
+       }
+
+       public SwtSection(SwtSection section, int style, Content node) {
+               this(section, section, style, node);
+       }
+
+       protected SwtSection(Composite parent, SwtSection parentSection, int style, Content node) {
+               super(parent, style, node);
+               this.parentSection = parentSection;
+               if (parentSection != null) {
+                       relativeDepth = getProvidedContent().getDepth() - parentSection.getProvidedContent().getDepth();
+               } else {
+                       relativeDepth = 0;
+               }
+               setLayout(CmsSwtUtils.noSpaceGridLayout());
+       }
+
+       public Map<String, SwtSection> getSubSections() {
+               LinkedHashMap<String, SwtSection> result = new LinkedHashMap<String, SwtSection>();
+               for (Control child : getChildren()) {
+                       if (child instanceof Composite) {
+                               collectDirectSubSections((Composite) child, result);
+                       }
+               }
+               return Collections.unmodifiableMap(result);
+       }
+
+       private void collectDirectSubSections(Composite composite, LinkedHashMap<String, SwtSection> subSections) {
+               if (composite == sectionHeader || composite instanceof EditablePart)
+                       return;
+               if (composite instanceof SwtSection) {
+                       SwtSection section = (SwtSection) composite;
+                       subSections.put(section.getProvidedContent().getSessionLocalId(), section);
+                       return;
+               }
+
+               for (Control child : composite.getChildren())
+                       if (child instanceof Composite)
+                               collectDirectSubSections((Composite) child, subSections);
+       }
+
+       public Composite createHeader() {
+               return createHeader(this);
+       }
+
+       public Composite createHeader(Composite parent) {
+               if (sectionHeader != null)
+                       sectionHeader.dispose();
+
+               sectionHeader = new Composite(parent, SWT.NONE);
+               sectionHeader.setLayoutData(CmsSwtUtils.fillWidth());
+               sectionHeader.setLayout(CmsSwtUtils.noSpaceGridLayout());
+               // sectionHeader.moveAbove(null);
+               // layout();
+               return sectionHeader;
+       }
+
+       public Composite getHeader() {
+               if (sectionHeader != null && sectionHeader.isDisposed())
+                       sectionHeader = null;
+               return sectionHeader;
+       }
+
+       // SECTION PARTS
+       public SwtSectionPart getSectionPart(String partId) {
+               for (Control child : getChildren()) {
+                       if (child instanceof SwtSectionPart) {
+                               SwtSectionPart sectionPart = (SwtSectionPart) child;
+                               if (sectionPart.getPartId().equals(partId))
+                                       return sectionPart;
+                       }
+               }
+               return null;
+       }
+
+       public SwtSectionPart nextSectionPart(SwtSectionPart sectionPart) {
+               Control[] children = getChildren();
+               for (int i = 0; i < children.length; i++) {
+                       if (sectionPart == children[i]) {
+                               for (int j = i + 1; j < children.length; j++) {
+                                       if (children[i + 1] instanceof SwtSectionPart) {
+                                               return (SwtSectionPart) children[i + 1];
+                                       }
+                               }
+
+//                             if (i + 1 < children.length) {
+//                                     Composite next = (Composite) children[i + 1];
+//                                     return (SectionPart) next;
+//                             } else {
+//                                     // next section
+//                             }
+                       }
+               }
+               return null;
+       }
+
+       public SwtSectionPart previousSectionPart(SwtSectionPart sectionPart) {
+               Control[] children = getChildren();
+               for (int i = 0; i < children.length; i++) {
+                       if (sectionPart == children[i])
+                               if (i != 0) {
+                                       Composite previous = (Composite) children[i - 1];
+                                       return (SwtSectionPart) previous;
+                               } else {
+                                       // previous section
+                               }
+               }
+               return null;
+       }
+
+       @Override
+       public String toString() {
+               if (parentSection == null)
+                       return "Main section " + getContent();
+               return "Section " + getContent();
+       }
+
+       public SwtSection getParentSection() {
+               return parentSection;
+       }
+
+       public Integer getRelativeDepth() {
+               return relativeDepth;
+       }
+
+       /** Recursively finds the related section in the parents (can be itself) */
+       public static SwtSection findSection(Control control) {
+               if (control == null)
+                       return null;
+               if (control instanceof SwtSection)
+                       return (SwtSection) control;
+               else
+                       return findSection(control.getParent());
+       }
+}
diff --git a/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/acr/SwtSectionPart.java b/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/acr/SwtSectionPart.java
new file mode 100644 (file)
index 0000000..7fbf4bb
--- /dev/null
@@ -0,0 +1,11 @@
+package org.argeo.cms.swt.acr;
+
+import org.argeo.cms.ux.acr.ContentPart;
+import org.argeo.cms.ux.widgets.EditablePart;
+
+/** An editable part dynamically related to a Section */
+public interface SwtSectionPart extends EditablePart, ContentPart {
+       public String getPartId();
+
+       public SwtSection getSection();
+}
diff --git a/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/acr/SwtTabbedArea.java b/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/acr/SwtTabbedArea.java
new file mode 100644 (file)
index 0000000..cd4e37d
--- /dev/null
@@ -0,0 +1,258 @@
+package org.argeo.cms.swt.acr;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.argeo.api.acr.Content;
+import org.argeo.api.acr.spi.ProvidedContent;
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.cms.swt.Selected;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StackLayout;
+import org.eclipse.swt.graphics.Image;
+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.Label;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.swt.widgets.ToolItem;
+
+/** Manages {@link SwtSection} in a tab-like structure. */
+public class SwtTabbedArea extends Composite {
+       private static final long serialVersionUID = 8659669229482033444L;
+
+       private Composite headers;
+       private Composite body;
+
+       private List<SwtSection> sections = new ArrayList<>();
+
+       private ProvidedContent previousNode;
+       private SwtUiProvider previousUiProvider;
+       private SwtUiProvider currentUiProvider;
+
+       private String tabStyle;
+       private String tabSelectedStyle;
+       private String bodyStyle;
+       private Image closeIcon;
+
+       private StackLayout stackLayout;
+
+       private boolean singleTab = false;
+
+       public SwtTabbedArea(Composite parent, int style) {
+               super(parent, SWT.NONE);
+               CmsSwtUtils.style(parent, bodyStyle);
+
+               setLayout(CmsSwtUtils.noSpaceGridLayout());
+
+               // TODO manage tabs at bottom or sides
+               headers = new Composite(this, SWT.NONE);
+               headers.setLayoutData(CmsSwtUtils.fillWidth());
+               body = new Composite(this, SWT.NONE);
+               body.setLayoutData(CmsSwtUtils.fillAll());
+               // body.setLayout(new FormLayout());
+               stackLayout = new StackLayout();
+               body.setLayout(stackLayout);
+               emptyState();
+       }
+
+       protected void refreshTabHeaders() {
+               int tabCount = sections.size() > 0 ? sections.size() : 1;
+               for (Control tab : headers.getChildren())
+                       tab.dispose();
+
+               headers.setLayout(CmsSwtUtils.noSpaceGridLayout(new GridLayout(tabCount, true)));
+
+               if (sections.size() == 0) {
+                       Composite emptyHeader = new Composite(headers, SWT.NONE);
+                       emptyHeader.setLayoutData(CmsSwtUtils.fillAll());
+                       emptyHeader.setLayout(new GridLayout());
+                       Label lbl = new Label(emptyHeader, SWT.NONE);
+                       lbl.setText("");
+                       lbl.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false));
+
+               }
+
+               SwtSection currentSection = getCurrentSection();
+               for (SwtSection section : sections) {
+                       boolean selected = section == currentSection;
+                       Composite sectionHeader = section.createHeader(headers);
+                       CmsSwtUtils.style(sectionHeader, selected ? tabSelectedStyle : tabStyle);
+                       int headerColumns = singleTab ? 1 : 2;
+                       sectionHeader.setLayout(new GridLayout(headerColumns, false));
+                       sectionHeader.setLayout(CmsSwtUtils.noSpaceGridLayout(headerColumns));
+                       Button title = new Button(sectionHeader, SWT.FLAT);
+                       CmsSwtUtils.style(title, selected ? tabSelectedStyle : tabStyle);
+                       title.setLayoutData(CmsSwtUtils.fillWidth());
+                       title.addSelectionListener((Selected) (e) -> showTab(tabIndex(section.getNode())));
+                       Content node = section.getContent();
+
+                       // FIXME find a standard way to display titles
+                       String titleStr = node.getName().getLocalPart();
+                       
+                       // TODO internationalize
+                       title.setText(titleStr);
+                       if (!singleTab) {
+                               ToolBar toolBar = new ToolBar(sectionHeader, SWT.NONE);
+                               ToolItem closeItem = new ToolItem(toolBar, SWT.FLAT);
+                               if (closeIcon != null)
+                                       closeItem.setImage(closeIcon);
+                               else
+                                       closeItem.setText("X");
+                               CmsSwtUtils.style(closeItem, selected ? tabSelectedStyle : tabStyle);
+                               closeItem.addSelectionListener((Selected) (e) -> closeTab(section));
+                       }
+               }
+
+       }
+
+       public void view(SwtUiProvider uiProvider, Content context) {
+               if (body.isDisposed())
+                       return;
+               int index = tabIndex(context);
+               if (index >= 0) {
+                       showTab(index);
+                       previousNode = (ProvidedContent) context;
+                       previousUiProvider = uiProvider;
+                       return;
+               }
+               SwtSection section = (SwtSection) body.getChildren()[0];
+               previousNode = (ProvidedContent) section.getNode();
+               if (previousNode == null) {// empty state
+                       previousNode = (ProvidedContent) context;
+                       previousUiProvider = uiProvider;
+               } else {
+                       previousUiProvider = currentUiProvider;
+               }
+               currentUiProvider = uiProvider;
+               section.setContent(context);
+               // section.setLayoutData(CmsUiUtils.coverAll());
+               build(section, uiProvider, context);
+               if (sections.size() == 0)
+                       sections.add(section);
+               refreshTabHeaders();
+               index = tabIndex(context);
+               showTab(index);
+               layout(true, true);
+       }
+
+       public void open(SwtUiProvider uiProvider, Content context) {
+               if (singleTab)
+                       throw new UnsupportedOperationException("Open is not supported in single tab mode.");
+
+               if (previousNode != null
+                               && previousNode.getSessionLocalId().equals(((ProvidedContent) context).getSessionLocalId())) {
+                       // does nothing
+                       return;
+               }
+               if (sections.size() == 0)
+                       CmsSwtUtils.clear(body);
+               SwtSection currentSection = getCurrentSection();
+               int currentIndex = sections.indexOf(currentSection);
+               SwtSection previousSection = new SwtSection(body, SWT.NONE, context);
+               build(previousSection, previousUiProvider, previousNode);
+               // previousSection.setLayoutData(CmsUiUtils.coverAll());
+               int newIndex = currentIndex + 1;
+               sections.add(currentIndex, previousSection);
+//             sections.add(newIndex, previousSection);
+               showTab(newIndex);
+               refreshTabHeaders();
+               layout(true, true);
+       }
+
+       public void showTab(int index) {
+               SwtSection sectionToShow = sections.get(index);
+               // sectionToShow.moveAbove(null);
+               stackLayout.topControl = sectionToShow;
+               refreshTabHeaders();
+               layout(true, true);
+       }
+
+       protected void build(SwtSection section, SwtUiProvider uiProvider, Content context) {
+               for (Control child : section.getChildren())
+                       child.dispose();
+               CmsSwtUtils.style(section, bodyStyle);
+               section.setContent(context);
+               uiProvider.createUiPart(section, context);
+
+       }
+
+       private int tabIndex(Content context) {
+               for (int i = 0; i < sections.size(); i++) {
+                       SwtSection section = sections.get(i);
+                       if (section.getSessionLocalId().equals(((ProvidedContent) context).getSessionLocalId()))
+                               return i;
+               }
+               return -1;
+       }
+
+       public void closeTab(SwtSection section) {
+               int currentIndex = sections.indexOf(section);
+               int nextIndex = currentIndex == 0 ? 0 : currentIndex - 1;
+               sections.remove(section);
+               section.dispose();
+               if (sections.size() == 0) {
+                       emptyState();
+                       refreshTabHeaders();
+                       layout(true, true);
+                       return;
+               }
+               refreshTabHeaders();
+               showTab(nextIndex);
+       }
+
+       public void closeAllTabs() {
+               for (SwtSection section : sections) {
+                       section.dispose();
+               }
+               sections.clear();
+               emptyState();
+               refreshTabHeaders();
+               layout(true, true);
+       }
+
+       protected void emptyState() {
+               new SwtSection(body, SWT.NONE, null);
+               refreshTabHeaders();
+       }
+
+       public Composite getCurrent() {
+               return getCurrentSection();
+       }
+
+       protected SwtSection getCurrentSection() {
+               return (SwtSection) stackLayout.topControl;
+       }
+
+       public Content getCurrentContext() {
+               SwtSection section = getCurrentSection();
+               if (section != null) {
+                       return section.getNode();
+               } else {
+                       return null;
+               }
+       }
+
+       public void setTabStyle(String tabStyle) {
+               this.tabStyle = tabStyle;
+       }
+
+       public void setTabSelectedStyle(String tabSelectedStyle) {
+               this.tabSelectedStyle = tabSelectedStyle;
+       }
+
+       public void setBodyStyle(String bodyStyle) {
+               this.bodyStyle = bodyStyle;
+       }
+
+       public void setCloseIcon(Image closeIcon) {
+               this.closeIcon = closeIcon;
+       }
+
+       public void setSingleTab(boolean singleTab) {
+               this.singleTab = singleTab;
+       }
+
+}
diff --git a/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/dialogs/CmsWizardDialog.java b/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/dialogs/CmsWizardDialog.java
deleted file mode 100644 (file)
index d9957d6..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-package org.argeo.cms.swt.dialogs;
-
-import java.lang.reflect.InvocationTargetException;
-
-import org.argeo.cms.CmsMsg;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.swt.Selected;
-import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.eclipse.jface.operation.IRunnableWithProgress;
-import org.eclipse.jface.wizard.IWizard;
-import org.eclipse.jface.wizard.IWizardContainer2;
-import org.eclipse.jface.wizard.IWizardPage;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.FormAttachment;
-import org.eclipse.swt.layout.FormData;
-import org.eclipse.swt.layout.FormLayout;
-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.Label;
-import org.eclipse.swt.widgets.Shell;
-
-/** A wizard dialog based on {@link LightweightDialog}. */
-public class CmsWizardDialog extends LightweightDialog implements IWizardContainer2 {
-       private static final long serialVersionUID = -2123153353654812154L;
-
-       private IWizard wizard;
-       private IWizardPage currentPage;
-       private int currentPageIndex;
-
-       private Label titleBar;
-       private Label message;
-       private Composite[] pageBodies;
-       private Composite buttons;
-       private Button back;
-       private Button next;
-       private Button finish;
-
-       public CmsWizardDialog(Shell parentShell, IWizard wizard) {
-               super(parentShell);
-               this.wizard = wizard;
-               wizard.setContainer(this);
-               // create the pages
-               wizard.addPages();
-               currentPage = wizard.getStartingPage();
-               if (currentPage == null)
-                       throw new IllegalArgumentException("At least one wizard page is required");
-       }
-
-       @Override
-       protected Control createDialogArea(Composite parent) {
-               updateWindowTitle();
-
-               Composite messageArea = new Composite(parent, SWT.NONE);
-               messageArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-               {
-                       messageArea.setLayout(CmsSwtUtils.noSpaceGridLayout(new GridLayout(2, false)));
-                       titleBar = new Label(messageArea, SWT.WRAP);
-                       titleBar.setFont(EclipseUiUtils.getBoldFont(parent));
-                       titleBar.setLayoutData(new GridData(SWT.BEGINNING, SWT.FILL, true, false));
-                       updateTitleBar();
-                       Button cancelButton = new Button(messageArea, SWT.FLAT);
-                       cancelButton.setText(CmsMsg.cancel.lead());
-                       cancelButton.setLayoutData(new GridData(SWT.END, SWT.TOP, false, false, 1, 3));
-                       cancelButton.addSelectionListener((Selected) (e) -> closeShell(CANCEL));
-                       message = new Label(messageArea, SWT.WRAP);
-                       message.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 2));
-                       updateMessage();
-               }
-
-               Composite body = new Composite(parent, SWT.BORDER);
-               body.setLayout(new FormLayout());
-               body.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-               pageBodies = new Composite[wizard.getPageCount()];
-               IWizardPage[] pages = wizard.getPages();
-               for (int i = 0; i < pages.length; i++) {
-                       pageBodies[i] = new Composite(body, SWT.NONE);
-                       pageBodies[i].setLayout(CmsSwtUtils.noSpaceGridLayout());
-                       setSwitchingFormData(pageBodies[i]);
-                       pages[i].createControl(pageBodies[i]);
-               }
-               showPage(currentPage);
-
-               buttons = new Composite(parent, SWT.NONE);
-               buttons.setLayoutData(new GridData(SWT.END, SWT.FILL, true, false));
-               {
-                       boolean singlePage = wizard.getPageCount() == 1;
-                       // singlePage = false;// dev
-                       GridLayout layout = new GridLayout(singlePage ? 1 : 3, true);
-                       layout.marginWidth = 0;
-                       layout.marginHeight = 0;
-                       buttons.setLayout(layout);
-                       // TODO revert order for right-to-left languages
-
-                       if (!singlePage) {
-                               back = new Button(buttons, SWT.PUSH);
-                               back.setText(CmsMsg.wizardBack.lead());
-                               back.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
-                               back.addSelectionListener((Selected) (e) -> backPressed());
-
-                               next = new Button(buttons, SWT.PUSH);
-                               next.setText(CmsMsg.wizardNext.lead());
-                               next.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
-                               next.addSelectionListener((Selected) (e) -> nextPressed());
-                       }
-                       finish = new Button(buttons, SWT.PUSH);
-                       finish.setText(CmsMsg.wizardFinish.lead());
-                       finish.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
-                       finish.addSelectionListener((Selected) (e) -> finishPressed());
-
-                       updateButtons();
-               }
-               return body;
-       }
-
-       @Override
-       public IWizardPage getCurrentPage() {
-               return currentPage;
-       }
-
-       @Override
-       public Shell getShell() {
-               return getForegoundShell();
-       }
-
-       @Override
-       public void showPage(IWizardPage page) {
-               IWizardPage[] pages = wizard.getPages();
-               int index = -1;
-               for (int i = 0; i < pages.length; i++) {
-                       if (page == pages[i]) {
-                               index = i;
-                               break;
-                       }
-               }
-               if (index < 0)
-                       throw new IllegalArgumentException("Cannot find index of wizard page " + page);
-               pageBodies[index].moveAbove(pageBodies[currentPageIndex]);
-
-               // // clear
-               // for (Control c : body.getChildren())
-               // c.dispose();
-               // page.createControl(body);
-               // body.layout(true, true);
-               currentPageIndex = index;
-               currentPage = page;
-       }
-
-       @Override
-       public void updateButtons() {
-               if (back != null)
-                       back.setEnabled(wizard.getPreviousPage(currentPage) != null);
-               if (next != null)
-                       next.setEnabled(wizard.getNextPage(currentPage) != null && currentPage.canFlipToNextPage());
-               if (finish != null) {
-                       finish.setEnabled(wizard.canFinish());
-               }
-       }
-
-       @Override
-       public void updateMessage() {
-               if (currentPage.getMessage() != null)
-                       message.setText(currentPage.getMessage());
-       }
-
-       @Override
-       public void updateTitleBar() {
-               if (currentPage.getTitle() != null)
-                       titleBar.setText(currentPage.getTitle());
-       }
-
-       @Override
-       public void updateWindowTitle() {
-               setTitle(wizard.getWindowTitle());
-       }
-
-       @Override
-       public void run(boolean fork, boolean cancelable, IRunnableWithProgress runnable)
-                       throws InvocationTargetException, InterruptedException {
-               // FIXME it creates a dependency to Eclipse Core Runtime
-               // runnable.run(null);
-       }
-
-       @Override
-       public void updateSize() {
-               // TODO pack?
-       }
-
-       protected boolean onCancel() {
-               return wizard.performCancel();
-       }
-
-       protected void nextPressed() {
-               IWizardPage page = wizard.getNextPage(currentPage);
-               showPage(page);
-               updateButtons();
-       }
-
-       protected void backPressed() {
-               IWizardPage page = wizard.getPreviousPage(currentPage);
-               showPage(page);
-               updateButtons();
-       }
-
-       protected void finishPressed() {
-               if (wizard.performFinish())
-                       closeShell(OK);
-       }
-
-       private static void setSwitchingFormData(Composite composite) {
-               FormData fdLabel = new FormData();
-               fdLabel.top = new FormAttachment(0, 0);
-               fdLabel.left = new FormAttachment(0, 0);
-               fdLabel.right = new FormAttachment(100, 0);
-               fdLabel.bottom = new FormAttachment(100, 0);
-               composite.setLayoutData(fdLabel);
-       }
-
-}
diff --git a/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/widgets/SwtSection.java b/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/widgets/SwtSection.java
deleted file mode 100644 (file)
index 5562bcf..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-package org.argeo.cms.swt.widgets;
-
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-import org.argeo.api.acr.Content;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.swt.acr.ContentComposite;
-import org.argeo.cms.ux.widgets.EditablePart;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-
-/** A structured UI related to a JCR context. */
-public class SwtSection extends ContentComposite {
-       private static final long serialVersionUID = -5933796173755739207L;
-
-       private final SwtSection parentSection;
-       private Composite sectionHeader;
-       private final Integer relativeDepth;
-
-       public SwtSection(Composite parent, int style, Content node) {
-               this(parent, findSection(parent), style, node);
-       }
-
-       public SwtSection(SwtSection section, int style, Content node) {
-               this(section, section, style, node);
-       }
-
-       protected SwtSection(Composite parent, SwtSection parentSection, int style, Content node) {
-               super(parent, style, node);
-               this.parentSection = parentSection;
-               if (parentSection != null) {
-                       relativeDepth = getProvidedContent().getDepth() - parentSection.getProvidedContent().getDepth();
-               } else {
-                       relativeDepth = 0;
-               }
-               setLayout(CmsSwtUtils.noSpaceGridLayout());
-       }
-
-       public Map<String, SwtSection> getSubSections() {
-               LinkedHashMap<String, SwtSection> result = new LinkedHashMap<String, SwtSection>();
-               for (Control child : getChildren()) {
-                       if (child instanceof Composite) {
-                               collectDirectSubSections((Composite) child, result);
-                       }
-               }
-               return Collections.unmodifiableMap(result);
-       }
-
-       private void collectDirectSubSections(Composite composite, LinkedHashMap<String, SwtSection> subSections) {
-               if (composite == sectionHeader || composite instanceof EditablePart)
-                       return;
-               if (composite instanceof SwtSection) {
-                       SwtSection section = (SwtSection) composite;
-                       subSections.put(section.getProvidedContent().getSessionLocalId(), section);
-                       return;
-               }
-
-               for (Control child : composite.getChildren())
-                       if (child instanceof Composite)
-                               collectDirectSubSections((Composite) child, subSections);
-       }
-
-       public Composite createHeader() {
-               return createHeader(this);
-       }
-
-       public Composite createHeader(Composite parent) {
-               if (sectionHeader != null)
-                       sectionHeader.dispose();
-
-               sectionHeader = new Composite(parent, SWT.NONE);
-               sectionHeader.setLayoutData(CmsSwtUtils.fillWidth());
-               sectionHeader.setLayout(CmsSwtUtils.noSpaceGridLayout());
-               // sectionHeader.moveAbove(null);
-               // layout();
-               return sectionHeader;
-       }
-
-       public Composite getHeader() {
-               if (sectionHeader != null && sectionHeader.isDisposed())
-                       sectionHeader = null;
-               return sectionHeader;
-       }
-
-       // SECTION PARTS
-       public SwtSectionPart getSectionPart(String partId) {
-               for (Control child : getChildren()) {
-                       if (child instanceof SwtSectionPart) {
-                               SwtSectionPart sectionPart = (SwtSectionPart) child;
-                               if (sectionPart.getPartId().equals(partId))
-                                       return sectionPart;
-                       }
-               }
-               return null;
-       }
-
-       public SwtSectionPart nextSectionPart(SwtSectionPart sectionPart) {
-               Control[] children = getChildren();
-               for (int i = 0; i < children.length; i++) {
-                       if (sectionPart == children[i]) {
-                               for (int j = i + 1; j < children.length; j++) {
-                                       if (children[i + 1] instanceof SwtSectionPart) {
-                                               return (SwtSectionPart) children[i + 1];
-                                       }
-                               }
-
-//                             if (i + 1 < children.length) {
-//                                     Composite next = (Composite) children[i + 1];
-//                                     return (SectionPart) next;
-//                             } else {
-//                                     // next section
-//                             }
-                       }
-               }
-               return null;
-       }
-
-       public SwtSectionPart previousSectionPart(SwtSectionPart sectionPart) {
-               Control[] children = getChildren();
-               for (int i = 0; i < children.length; i++) {
-                       if (sectionPart == children[i])
-                               if (i != 0) {
-                                       Composite previous = (Composite) children[i - 1];
-                                       return (SwtSectionPart) previous;
-                               } else {
-                                       // previous section
-                               }
-               }
-               return null;
-       }
-
-       @Override
-       public String toString() {
-               if (parentSection == null)
-                       return "Main section " + getContent();
-               return "Section " + getContent();
-       }
-
-       public SwtSection getParentSection() {
-               return parentSection;
-       }
-
-       public Integer getRelativeDepth() {
-               return relativeDepth;
-       }
-
-       /** Recursively finds the related section in the parents (can be itself) */
-       public static SwtSection findSection(Control control) {
-               if (control == null)
-                       return null;
-               if (control instanceof SwtSection)
-                       return (SwtSection) control;
-               else
-                       return findSection(control.getParent());
-       }
-}
diff --git a/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/widgets/SwtSectionPart.java b/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/widgets/SwtSectionPart.java
deleted file mode 100644 (file)
index e057860..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-package org.argeo.cms.swt.widgets;
-
-import org.argeo.cms.ux.widgets.ContentPart;
-import org.argeo.cms.ux.widgets.EditablePart;
-
-/** An editable part dynamically related to a Section */
-public interface SwtSectionPart extends EditablePart, ContentPart {
-       public String getPartId();
-
-       public SwtSection getSection();
-}
diff --git a/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/widgets/SwtTabbedArea.java b/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/widgets/SwtTabbedArea.java
deleted file mode 100644 (file)
index a2f7671..0000000
+++ /dev/null
@@ -1,259 +0,0 @@
-package org.argeo.cms.swt.widgets;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.argeo.api.acr.Content;
-import org.argeo.api.acr.spi.ProvidedContent;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.swt.Selected;
-import org.argeo.cms.swt.acr.SwtUiProvider;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.StackLayout;
-import org.eclipse.swt.graphics.Image;
-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.Label;
-import org.eclipse.swt.widgets.ToolBar;
-import org.eclipse.swt.widgets.ToolItem;
-
-/** Manages {@link SwtSection} in a tab-like structure. */
-public class SwtTabbedArea extends Composite {
-       private static final long serialVersionUID = 8659669229482033444L;
-
-       private Composite headers;
-       private Composite body;
-
-       private List<SwtSection> sections = new ArrayList<>();
-
-       private ProvidedContent previousNode;
-       private SwtUiProvider previousUiProvider;
-       private SwtUiProvider currentUiProvider;
-
-       private String tabStyle;
-       private String tabSelectedStyle;
-       private String bodyStyle;
-       private Image closeIcon;
-
-       private StackLayout stackLayout;
-
-       private boolean singleTab = false;
-
-       public SwtTabbedArea(Composite parent, int style) {
-               super(parent, SWT.NONE);
-               CmsSwtUtils.style(parent, bodyStyle);
-
-               setLayout(CmsSwtUtils.noSpaceGridLayout());
-
-               // TODO manage tabs at bottom or sides
-               headers = new Composite(this, SWT.NONE);
-               headers.setLayoutData(CmsSwtUtils.fillWidth());
-               body = new Composite(this, SWT.NONE);
-               body.setLayoutData(CmsSwtUtils.fillAll());
-               // body.setLayout(new FormLayout());
-               stackLayout = new StackLayout();
-               body.setLayout(stackLayout);
-               emptyState();
-       }
-
-       protected void refreshTabHeaders() {
-               int tabCount = sections.size() > 0 ? sections.size() : 1;
-               for (Control tab : headers.getChildren())
-                       tab.dispose();
-
-               headers.setLayout(CmsSwtUtils.noSpaceGridLayout(new GridLayout(tabCount, true)));
-
-               if (sections.size() == 0) {
-                       Composite emptyHeader = new Composite(headers, SWT.NONE);
-                       emptyHeader.setLayoutData(CmsSwtUtils.fillAll());
-                       emptyHeader.setLayout(new GridLayout());
-                       Label lbl = new Label(emptyHeader, SWT.NONE);
-                       lbl.setText("");
-                       lbl.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false));
-
-               }
-
-               SwtSection currentSection = getCurrentSection();
-               for (SwtSection section : sections) {
-                       boolean selected = section == currentSection;
-                       Composite sectionHeader = section.createHeader(headers);
-                       CmsSwtUtils.style(sectionHeader, selected ? tabSelectedStyle : tabStyle);
-                       int headerColumns = singleTab ? 1 : 2;
-                       sectionHeader.setLayout(new GridLayout(headerColumns, false));
-                       sectionHeader.setLayout(CmsSwtUtils.noSpaceGridLayout(headerColumns));
-                       Button title = new Button(sectionHeader, SWT.FLAT);
-                       CmsSwtUtils.style(title, selected ? tabSelectedStyle : tabStyle);
-                       title.setLayoutData(CmsSwtUtils.fillWidth());
-                       title.addSelectionListener((Selected) (e) -> showTab(tabIndex(section.getNode())));
-                       Content node = section.getContent();
-
-                       // FIXME find a standard way to display titles
-                       String titleStr = node.getName().getLocalPart();
-                       
-                       // TODO internationalize
-                       title.setText(titleStr);
-                       if (!singleTab) {
-                               ToolBar toolBar = new ToolBar(sectionHeader, SWT.NONE);
-                               ToolItem closeItem = new ToolItem(toolBar, SWT.FLAT);
-                               if (closeIcon != null)
-                                       closeItem.setImage(closeIcon);
-                               else
-                                       closeItem.setText("X");
-                               CmsSwtUtils.style(closeItem, selected ? tabSelectedStyle : tabStyle);
-                               closeItem.addSelectionListener((Selected) (e) -> closeTab(section));
-                       }
-               }
-
-       }
-
-       public void view(SwtUiProvider uiProvider, Content context) {
-               if (body.isDisposed())
-                       return;
-               int index = tabIndex(context);
-               if (index >= 0) {
-                       showTab(index);
-                       previousNode = (ProvidedContent) context;
-                       previousUiProvider = uiProvider;
-                       return;
-               }
-               SwtSection section = (SwtSection) body.getChildren()[0];
-               previousNode = (ProvidedContent) section.getNode();
-               if (previousNode == null) {// empty state
-                       previousNode = (ProvidedContent) context;
-                       previousUiProvider = uiProvider;
-               } else {
-                       previousUiProvider = currentUiProvider;
-               }
-               currentUiProvider = uiProvider;
-               section.setContent(context);
-               // section.setLayoutData(CmsUiUtils.coverAll());
-               build(section, uiProvider, context);
-               if (sections.size() == 0)
-                       sections.add(section);
-               refreshTabHeaders();
-               index = tabIndex(context);
-               showTab(index);
-               layout(true, true);
-       }
-
-       public void open(SwtUiProvider uiProvider, Content context) {
-               if (singleTab)
-                       throw new UnsupportedOperationException("Open is not supported in single tab mode.");
-
-               if (previousNode != null
-                               && previousNode.getSessionLocalId().equals(((ProvidedContent) context).getSessionLocalId())) {
-                       // does nothing
-                       return;
-               }
-               if (sections.size() == 0)
-                       CmsSwtUtils.clear(body);
-               SwtSection currentSection = getCurrentSection();
-               int currentIndex = sections.indexOf(currentSection);
-               SwtSection previousSection = new SwtSection(body, SWT.NONE, context);
-               build(previousSection, previousUiProvider, previousNode);
-               // previousSection.setLayoutData(CmsUiUtils.coverAll());
-               int newIndex = currentIndex + 1;
-               sections.add(currentIndex, previousSection);
-//             sections.add(newIndex, previousSection);
-               showTab(newIndex);
-               refreshTabHeaders();
-               layout(true, true);
-       }
-
-       public void showTab(int index) {
-               SwtSection sectionToShow = sections.get(index);
-               // sectionToShow.moveAbove(null);
-               stackLayout.topControl = sectionToShow;
-               refreshTabHeaders();
-               layout(true, true);
-       }
-
-       protected void build(SwtSection section, SwtUiProvider uiProvider, Content context) {
-               for (Control child : section.getChildren())
-                       child.dispose();
-               CmsSwtUtils.style(section, bodyStyle);
-               section.setContent(context);
-               uiProvider.createUiPart(section, context);
-
-       }
-
-       private int tabIndex(Content context) {
-               for (int i = 0; i < sections.size(); i++) {
-                       SwtSection section = sections.get(i);
-                       if (section.getSessionLocalId().equals(((ProvidedContent) context).getSessionLocalId()))
-                               return i;
-               }
-               return -1;
-       }
-
-       public void closeTab(SwtSection section) {
-               int currentIndex = sections.indexOf(section);
-               int nextIndex = currentIndex == 0 ? 0 : currentIndex - 1;
-               sections.remove(section);
-               section.dispose();
-               if (sections.size() == 0) {
-                       emptyState();
-                       refreshTabHeaders();
-                       layout(true, true);
-                       return;
-               }
-               refreshTabHeaders();
-               showTab(nextIndex);
-       }
-
-       public void closeAllTabs() {
-               for (SwtSection section : sections) {
-                       section.dispose();
-               }
-               sections.clear();
-               emptyState();
-               refreshTabHeaders();
-               layout(true, true);
-       }
-
-       protected void emptyState() {
-               new SwtSection(body, SWT.NONE, null);
-               refreshTabHeaders();
-       }
-
-       public Composite getCurrent() {
-               return getCurrentSection();
-       }
-
-       protected SwtSection getCurrentSection() {
-               return (SwtSection) stackLayout.topControl;
-       }
-
-       public Content getCurrentContext() {
-               SwtSection section = getCurrentSection();
-               if (section != null) {
-                       return section.getNode();
-               } else {
-                       return null;
-               }
-       }
-
-       public void setTabStyle(String tabStyle) {
-               this.tabStyle = tabStyle;
-       }
-
-       public void setTabSelectedStyle(String tabSelectedStyle) {
-               this.tabSelectedStyle = tabSelectedStyle;
-       }
-
-       public void setBodyStyle(String bodyStyle) {
-               this.bodyStyle = bodyStyle;
-       }
-
-       public void setCloseIcon(Image closeIcon) {
-               this.closeIcon = closeIcon;
-       }
-
-       public void setSingleTab(boolean singleTab) {
-               this.singleTab = singleTab;
-       }
-
-}
index c882eb766f7756e32f0d9a6cba7fae3bf18dbd8e..64ea2dbc9a193121ad47d0b60b94d1f2aefb8ecd 100644 (file)
@@ -1,5 +1,6 @@
 package org.argeo.eclipse.ui;
 
+import org.argeo.cms.ux.widgets.TreeParent;
 import org.eclipse.jface.viewers.ITreeContentProvider;
 import org.eclipse.jface.viewers.Viewer;
 
diff --git a/eclipse/org.argeo.cms.swt/src/org/argeo/eclipse/ui/TreeParent.java b/eclipse/org.argeo.cms.swt/src/org/argeo/eclipse/ui/TreeParent.java
deleted file mode 100644 (file)
index cf3c157..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-package org.argeo.eclipse.ui;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** Parent / children semantic to be used for simple UI Tree structure */
-public class TreeParent {
-       private String name;
-       private TreeParent parent;
-
-       private List<Object> children;
-
-       /**
-        * Unique id within the context of a tree display. If set, equals() and
-        * hashCode() methods will be based on it
-        */
-       private String path = null;
-
-       /** False until at least one child has been added, then true until cleared */
-       private boolean loaded = false;
-
-       public TreeParent(String name) {
-               this.name = name;
-               children = new ArrayList<Object>();
-       }
-
-       public synchronized void addChild(Object child) {
-               loaded = true;
-               children.add(child);
-               if (child instanceof TreeParent)
-                       ((TreeParent) child).setParent(this);
-       }
-
-       /**
-        * Remove this child. The child is disposed.
-        */
-       public synchronized void removeChild(Object child) {
-               children.remove(child);
-               if (child instanceof TreeParent) {
-                       ((TreeParent) child).dispose();
-               }
-       }
-
-       public synchronized void clearChildren() {
-               for (Object obj : children) {
-                       if (obj instanceof TreeParent)
-                               ((TreeParent) obj).dispose();
-               }
-               loaded = false;
-               children.clear();
-       }
-
-       /**
-        * If overridden, <code>super.dispose()</code> must be called, typically
-        * after custom cleaning.
-        */
-       public synchronized void dispose() {
-               clearChildren();
-               parent = null;
-               children = null;
-       }
-
-       public synchronized Object[] getChildren() {
-               return children.toArray(new Object[children.size()]);
-       }
-
-       @SuppressWarnings("unchecked")
-       public synchronized <T> List<T> getChildrenOfType(Class<T> clss) {
-               List<T> lst = new ArrayList<T>();
-               for (Object obj : children) {
-                       if (clss.isAssignableFrom(obj.getClass()))
-                               lst.add((T) obj);
-               }
-               return lst;
-       }
-
-       public synchronized boolean hasChildren() {
-               return children.size() > 0;
-       }
-
-       public Object getChildByName(String name) {
-               for (Object child : children) {
-                       if (child.toString().equals(name))
-                               return child;
-               }
-               return null;
-       }
-
-       public synchronized Boolean isLoaded() {
-               return loaded;
-       }
-
-       public String getName() {
-               return name;
-       }
-
-       public void setParent(TreeParent parent) {
-               this.parent = parent;
-               if (parent != null && parent.path != null)
-                       this.path = parent.path + '/' + name;
-               else
-                       this.path = '/' + name;
-       }
-
-       public TreeParent getParent() {
-               return parent;
-       }
-
-       public String toString() {
-               return getName();
-       }
-
-       public int compareTo(TreeParent o) {
-               return name.compareTo(o.name);
-       }
-
-       @Override
-       public int hashCode() {
-               if (path != null)
-                       return path.hashCode();
-               else
-                       return name.hashCode();
-       }
-
-       @Override
-       public boolean equals(Object obj) {
-               if (path != null && obj instanceof TreeParent)
-                       return path.equals(((TreeParent) obj).path);
-               else
-                       return name.equals(obj.toString());
-       }
-
-}
index 689fca3167708cca632d7d1637ffbf811f792f23..3c1e8cda530d09caf60997a5ce0e9b5d5790bfbe 100644 (file)
@@ -3,7 +3,7 @@ package org.argeo.cms.ui.forms;
 import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 
-import org.argeo.cms.swt.EditablePart;
+import org.argeo.cms.swt.SwtEditablePart;
 import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.Composite;
@@ -13,7 +13,7 @@ import org.eclipse.swt.widgets.Text;
 
 /** Editable String that displays a browsable link when read-only */
 public class EditableLink extends EditablePropertyString implements
-               EditablePart {
+               SwtEditablePart {
        private static final long serialVersionUID = 5055000749992803591L;
 
        private String type;
index a04537ef475de74cb4ea26cb2c84e868d710af25..ff827004674e13b249501526164aa6603d1083d7 100644 (file)
@@ -6,7 +6,7 @@ import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 
 import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.swt.EditablePart;
+import org.argeo.cms.swt.SwtEditablePart;
 import org.argeo.cms.ui.widgets.StyledControl;
 import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.eclipse.jface.dialogs.MessageDialog;
@@ -24,7 +24,7 @@ import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Text;
 
 /** Display, add or remove values from a list in a CMS context */
-public class EditableMultiStringProperty extends StyledControl implements EditablePart {
+public class EditableMultiStringProperty extends StyledControl implements SwtEditablePart {
        private static final long serialVersionUID = -7044614381252178595L;
 
        private String propertyName;
index 0f80ca78cfb480e41814a54affc56cd43faf2287..641f916f2bd7620839b67c073c1ca46d80e5d290 100644 (file)
@@ -8,7 +8,7 @@ import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 
 import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.swt.EditablePart;
+import org.argeo.cms.swt.SwtEditablePart;
 import org.argeo.cms.ui.widgets.StyledControl;
 import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.eclipse.swt.SWT;
@@ -29,7 +29,7 @@ import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.Text;
 
 /** CMS form part to display and edit a date */
-public class EditablePropertyDate extends StyledControl implements EditablePart {
+public class EditablePropertyDate extends StyledControl implements SwtEditablePart {
        private static final long serialVersionUID = 2500215515778162468L;
 
        // Context
index ffe7e36f76e5fcd6391d588a8cb1649bd69a3dca..f2575e1f96591d0d39e6314324dcefc412429535 100644 (file)
@@ -7,7 +7,7 @@ import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 
 import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.swt.EditablePart;
+import org.argeo.cms.swt.SwtEditablePart;
 import org.argeo.cms.ui.widgets.EditableText;
 import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.eclipse.swt.widgets.Composite;
@@ -16,7 +16,7 @@ import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Text;
 
 /** Editable String in a CMS context */
-public class EditablePropertyString extends EditableText implements EditablePart {
+public class EditablePropertyString extends EditableText implements SwtEditablePart {
        private static final long serialVersionUID = 5055000749992803591L;
 
        private String propertyName;
index e10dd4556f5d1c0355d862ed3a72b2f80f36f02b..1888055fccef9c0cbcb9a462200ca2aec8a64e3e 100644 (file)
@@ -19,7 +19,7 @@ import org.argeo.api.cms.ux.Cms2DSize;
 import org.argeo.api.cms.ux.CmsEditable;
 import org.argeo.api.cms.ux.CmsImageManager;
 import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.swt.EditablePart;
+import org.argeo.cms.swt.SwtEditablePart;
 import org.argeo.cms.ui.viewers.AbstractPageViewer;
 import org.argeo.cms.ui.viewers.Section;
 import org.argeo.cms.ui.viewers.SectionPart;
@@ -86,14 +86,14 @@ public class FormPageViewer extends AbstractPageViewer {
        }
 
        @Override
-       protected void prepare(EditablePart part, Object caretPosition) {
+       protected void prepare(SwtEditablePart part, Object caretPosition) {
                if (part instanceof Img) {
                        ((Img) part).setFileUploadListener(fileUploadListener);
                }
        }
 
        /** To be overridden.Save the edited part. */
-       protected void save(EditablePart part) throws RepositoryException {
+       protected void save(SwtEditablePart part) throws RepositoryException {
                Node node = null;
                if (part instanceof EditableMultiStringProperty) {
                        EditableMultiStringProperty ept = (EditableMultiStringProperty) part;
@@ -148,7 +148,7 @@ public class FormPageViewer extends AbstractPageViewer {
        }
 
        @Override
-       protected void updateContent(EditablePart part) throws RepositoryException {
+       protected void updateContent(SwtEditablePart part) throws RepositoryException {
                if (part instanceof EditableMultiStringProperty) {
                        EditableMultiStringProperty ept = (EditableMultiStringProperty) part;
                        // SWT : View
@@ -259,7 +259,7 @@ public class FormPageViewer extends AbstractPageViewer {
                                        if (getCmsEditable().isEditing() && !(getEdited() instanceof Img)) {
                                                if (source == mainSection)
                                                        return;
-                                               EditablePart part = findDataParent(source);
+                                               SwtEditablePart part = findDataParent(source);
                                                upload(part);
                                        } else {
                                                getCmsEditable().startEditing();
@@ -273,7 +273,7 @@ public class FormPageViewer extends AbstractPageViewer {
                        if (getCmsEditable().isEditing()) {
                                if (e.button == 1) {
                                        Control source = (Control) e.getSource();
-                                       EditablePart composite = findDataParent(source);
+                                       SwtEditablePart composite = findDataParent(source);
                                        Point point = new Point(e.x, e.y);
                                        if (!(composite instanceof Img))
                                                edit(composite, source.toDisplay(point));
@@ -286,7 +286,7 @@ public class FormPageViewer extends AbstractPageViewer {
                        }
                }
 
-               protected synchronized void upload(EditablePart part) {
+               protected synchronized void upload(SwtEditablePart part) {
                        if (part instanceof SectionPart) {
                                if (part instanceof Img) {
                                        if (getEdited() == part)
@@ -561,7 +561,7 @@ public class FormPageViewer extends AbstractPageViewer {
                                if (source instanceof Button) {
                                        Button btn = (Button) source;
                                        Object obj = btn.getData(FormConstants.LINKED_VALUE);
-                                       EditablePart ep = findDataParent(btn);
+                                       SwtEditablePart ep = findDataParent(btn);
                                        if (ep != null && ep instanceof EditableMultiStringProperty) {
                                                EditableMultiStringProperty emsp = (EditableMultiStringProperty) ep;
                                                List<String> values = emsp.getValues();
index e4c5873a0531ce27a644e1c9a4893892cf093ba6..b36acc36831782428c1f856e0b550c42f2ac7d57 100644 (file)
@@ -9,8 +9,8 @@ import org.argeo.cms.ui.jcr.model.RepositoriesElem;
 import org.argeo.cms.ui.jcr.model.RepositoryElem;
 import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem;
 import org.argeo.cms.ui.jcr.model.WorkspaceElem;
+import org.argeo.cms.ux.widgets.TreeParent;
 import org.argeo.eclipse.ui.EclipseUiException;
-import org.argeo.eclipse.ui.TreeParent;
 
 /** Useful methods to manage the JCR Browser */
 public class JcrBrowserUtils {
index 00449df26c22643833d2d727ca390e133fa0e71f..0625cc8721f5ef689906f14fe28c6824b357458f 100644 (file)
@@ -16,7 +16,7 @@ import org.argeo.cms.jcr.CmsJcrUtils;
 import org.argeo.cms.security.Keyring;
 import org.argeo.cms.ui.jcr.model.RepositoriesElem;
 import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem;
-import org.argeo.eclipse.ui.TreeParent;
+import org.argeo.cms.ux.widgets.TreeParent;
 import org.eclipse.jface.viewers.ITreeContentProvider;
 import org.eclipse.jface.viewers.Viewer;
 
index 61654b61a5c620004f4ad52aca674641d5a3ed00..d33b33f636a16fc8859eee3d416abc0d7f2b7b53 100644 (file)
@@ -2,7 +2,7 @@ package org.argeo.cms.ui.jcr.model;
 
 import javax.jcr.Repository;
 
-import org.argeo.eclipse.ui.TreeParent;
+import org.argeo.cms.ux.widgets.TreeParent;
 
 /** Wrap a MaintainedRepository */
 public class MaintainedRepositoryElem extends RepositoryElem {
index 428e7f1cd2fe73a591dc770ebe702d8ebdbd99ce..908d1b135a60bce8b26a4c15434924574490bf05 100644 (file)
@@ -12,8 +12,8 @@ import javax.jcr.SimpleCredentials;
 import org.argeo.cms.ArgeoNames;
 import org.argeo.cms.jcr.CmsJcrUtils;
 import org.argeo.cms.security.Keyring;
+import org.argeo.cms.ux.widgets.TreeParent;
 import org.argeo.eclipse.ui.EclipseUiException;
-import org.argeo.eclipse.ui.TreeParent;
 
 /** Root of a remote repository */
 public class RemoteRepositoryElem extends RepositoryElem {
index 858633202d72d22d83c4a28c1bc85bb03c2334db..742800b0b54e364dde808a7fa093a08aa3ebad32 100644 (file)
@@ -13,8 +13,8 @@ import org.argeo.cms.ArgeoNames;
 import org.argeo.cms.jcr.CmsJcrUtils;
 import org.argeo.cms.security.Keyring;
 import org.argeo.cms.ui.jcr.RepositoryRegister;
+import org.argeo.cms.ux.widgets.TreeParent;
 import org.argeo.eclipse.ui.EclipseUiException;
-import org.argeo.eclipse.ui.TreeParent;
 import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
 
 /**
index afff3ef9e6290bde6b4d0f8f5ab55798294d833c..296c369220aae99cf705033b27d0f8ec541d2a1d 100644 (file)
@@ -5,8 +5,8 @@ import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 
 import org.argeo.api.cms.CmsConstants;
+import org.argeo.cms.ux.widgets.TreeParent;
 import org.argeo.eclipse.ui.EclipseUiException;
-import org.argeo.eclipse.ui.TreeParent;
 import org.argeo.jcr.JcrUtils;
 
 /**
index 859deee974d77dcf8812f4e60726dcc6c99b56ca..a2584a5e8a467d964d1cbfa42c5cad1f2f67e7af 100644 (file)
@@ -5,8 +5,8 @@ import javax.jcr.NodeIterator;
 import javax.jcr.RepositoryException;
 import javax.jcr.Workspace;
 
+import org.argeo.cms.ux.widgets.TreeParent;
 import org.argeo.eclipse.ui.EclipseUiException;
-import org.argeo.eclipse.ui.TreeParent;
 
 /**
  * UI Tree component. Wraps a node of a JCR {@link Workspace}. It also keeps a
index 24fc5758d50a3b988f1941a41d4d55dfc384f6d2..2d786669f8655e77f8412b79778017251baec43e 100644 (file)
@@ -8,8 +8,8 @@ import javax.jcr.Session;
 // import javax.jcr.Workspace;
 import javax.jcr.Workspace;
 
+import org.argeo.cms.ux.widgets.TreeParent;
 import org.argeo.eclipse.ui.EclipseUiException;
-import org.argeo.eclipse.ui.TreeParent;
 import org.argeo.jcr.JcrUtils;
 
 /**
index a247313e1ad17ab1609775c3b9786681d509bf7c..e23846e928d0c47136de8a9f9fd66e6b3c6bffc3 100644 (file)
@@ -13,7 +13,7 @@ import javax.security.auth.Subject;
 
 import org.argeo.api.cms.CmsLog;
 import org.argeo.api.cms.ux.CmsEditable;
-import org.argeo.cms.swt.EditablePart;
+import org.argeo.cms.swt.SwtEditablePart;
 import org.argeo.cms.swt.widgets.ScrolledPage;
 import org.argeo.jcr.JcrException;
 import org.eclipse.jface.viewers.ContentViewer;
@@ -43,7 +43,7 @@ public abstract class AbstractPageViewer extends ContentViewer implements Observ
        private MouseListener mouseListener;
        private FocusListener focusListener;
 
-       private EditablePart edited;
+       private SwtEditablePart edited;
        private ISelection selection = StructuredSelection.EMPTY;
 
        private AccessControlContext accessControlContext;
@@ -141,11 +141,11 @@ public abstract class AbstractPageViewer extends ContentViewer implements Observ
        }
 
        /** To be overridden.Save the edited part. */
-       protected void save(EditablePart part) throws RepositoryException {
+       protected void save(SwtEditablePart part) throws RepositoryException {
        }
 
        /** Prepare the edited part */
-       protected void prepare(EditablePart part, Object caretPosition) {
+       protected void prepare(SwtEditablePart part, Object caretPosition) {
        }
 
        /** Notified when the editing state changed. Does nothing, to be overridden */
@@ -178,17 +178,17 @@ public abstract class AbstractPageViewer extends ContentViewer implements Observ
                this.selection = selection;
        }
 
-       protected void updateContent(EditablePart part) throws RepositoryException {
+       protected void updateContent(SwtEditablePart part) throws RepositoryException {
        }
 
        // LOW LEVEL EDITION
-       protected void edit(EditablePart part, Object caretPosition) {
+       protected void edit(SwtEditablePart part, Object caretPosition) {
                try {
                        if (edited == part)
                                return;
 
                        if (edited != null && edited != part) {
-                               EditablePart previouslyEdited = edited;
+                               SwtEditablePart previouslyEdited = edited;
                                try {
                                        stopEditing(true);
                                } catch (Exception e) {
@@ -240,8 +240,8 @@ public abstract class AbstractPageViewer extends ContentViewer implements Observ
                                save(edited);
 
                        edited.stopEditing();
-                       EditablePart editablePart = edited;
-                       Control control = ((EditablePart) edited).getControl();
+                       SwtEditablePart editablePart = edited;
+                       Control control = ((SwtEditablePart) edited).getControl();
                        edited = null;
                        // TODO make edited state management more robust
                        updateContent(editablePart);
@@ -270,11 +270,11 @@ public abstract class AbstractPageViewer extends ContentViewer implements Observ
        }
 
        /**
-        * Find the first {@link EditablePart} in the parents hierarchy of this control
+        * Find the first {@link SwtEditablePart} in the parents hierarchy of this control
         */
-       protected EditablePart findDataParent(Control parent) {
-               if (parent instanceof EditablePart) {
-                       return (EditablePart) parent;
+       protected SwtEditablePart findDataParent(Control parent) {
+               if (parent instanceof SwtEditablePart) {
+                       return (SwtEditablePart) parent;
                }
                if (parent.getParent() != null)
                        return findDataParent(parent.getParent());
@@ -328,7 +328,7 @@ public abstract class AbstractPageViewer extends ContentViewer implements Observ
                return readOnly;
        }
 
-       protected EditablePart getEdited() {
+       protected SwtEditablePart getEdited() {
                return edited;
        }
 
index 0e489e05f6f7b63039a0ebe4ca8825f40ce6a605..b27fa38457b2d3b60a28314245930fd363c10ce9 100644 (file)
@@ -8,7 +8,7 @@ import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 
 import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.swt.EditablePart;
+import org.argeo.cms.swt.SwtEditablePart;
 import org.argeo.cms.ui.widgets.JcrComposite;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.Composite;
@@ -57,7 +57,7 @@ public class Section extends JcrComposite {
 
        private void collectDirectSubSections(Composite composite, LinkedHashMap<String, Section> subSections)
                        throws RepositoryException {
-               if (composite == sectionHeader || composite instanceof EditablePart)
+               if (composite == sectionHeader || composite instanceof SwtEditablePart)
                        return;
                if (composite instanceof Section) {
                        Section section = (Section) composite;
index df3c734c21c6412a07ab041cdb5bad513c746f60..4278c83cc0d3b9aa4f171e2a0d0f09ce30da6600 100644 (file)
@@ -1,9 +1,9 @@
 package org.argeo.cms.ui.viewers;
 
-import org.argeo.cms.swt.EditablePart;
+import org.argeo.cms.swt.SwtEditablePart;
 
 /** An editable part dynamically related to a Section */
-public interface SectionPart extends EditablePart, NodePart {
+public interface SectionPart extends SwtEditablePart, NodePart {
        public String getPartId();
 
        public Section getSection();
diff --git a/org.argeo.cms.ux/src/org/argeo/cms/ux/acr/ContentPart.java b/org.argeo.cms.ux/src/org/argeo/cms/ux/acr/ContentPart.java
new file mode 100644 (file)
index 0000000..8d674f8
--- /dev/null
@@ -0,0 +1,12 @@
+package org.argeo.cms.ux.acr;
+
+import org.argeo.api.acr.Content;
+
+/** A part displaying or editing a content. */
+public interface ContentPart {
+       Content getContent();
+
+       @Deprecated
+       Content getNode();
+
+}
diff --git a/org.argeo.cms.ux/src/org/argeo/cms/ux/widgets/ContentPart.java b/org.argeo.cms.ux/src/org/argeo/cms/ux/widgets/ContentPart.java
deleted file mode 100644 (file)
index 5e91f5c..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.argeo.cms.ux.widgets;
-
-import org.argeo.api.acr.Content;
-
-/** A part displaying or editing a content. */
-public interface ContentPart {
-       Content getContent();
-
-       @Deprecated
-       Content getNode();
-
-}
diff --git a/org.argeo.cms.ux/src/org/argeo/cms/ux/widgets/TreeParent.java b/org.argeo.cms.ux/src/org/argeo/cms/ux/widgets/TreeParent.java
new file mode 100644 (file)
index 0000000..97dedcc
--- /dev/null
@@ -0,0 +1,133 @@
+package org.argeo.cms.ux.widgets;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/** Parent / children semantic to be used for simple UI Tree structure */
+public class TreeParent {
+       private String name;
+       private TreeParent parent;
+
+       private List<Object> children;
+
+       /**
+        * Unique id within the context of a tree display. If set, equals() and
+        * hashCode() methods will be based on it
+        */
+       private String path = null;
+
+       /** False until at least one child has been added, then true until cleared */
+       private boolean loaded = false;
+
+       public TreeParent(String name) {
+               this.name = name;
+               children = new ArrayList<Object>();
+       }
+
+       public synchronized void addChild(Object child) {
+               loaded = true;
+               children.add(child);
+               if (child instanceof TreeParent)
+                       ((TreeParent) child).setParent(this);
+       }
+
+       /**
+        * Remove this child. The child is disposed.
+        */
+       public synchronized void removeChild(Object child) {
+               children.remove(child);
+               if (child instanceof TreeParent) {
+                       ((TreeParent) child).dispose();
+               }
+       }
+
+       public synchronized void clearChildren() {
+               for (Object obj : children) {
+                       if (obj instanceof TreeParent)
+                               ((TreeParent) obj).dispose();
+               }
+               loaded = false;
+               children.clear();
+       }
+
+       /**
+        * If overridden, <code>super.dispose()</code> must be called, typically
+        * after custom cleaning.
+        */
+       public synchronized void dispose() {
+               clearChildren();
+               parent = null;
+               children = null;
+       }
+
+       public synchronized Object[] getChildren() {
+               return children.toArray(new Object[children.size()]);
+       }
+
+       @SuppressWarnings("unchecked")
+       public synchronized <T> List<T> getChildrenOfType(Class<T> clss) {
+               List<T> lst = new ArrayList<T>();
+               for (Object obj : children) {
+                       if (clss.isAssignableFrom(obj.getClass()))
+                               lst.add((T) obj);
+               }
+               return lst;
+       }
+
+       public synchronized boolean hasChildren() {
+               return children.size() > 0;
+       }
+
+       public Object getChildByName(String name) {
+               for (Object child : children) {
+                       if (child.toString().equals(name))
+                               return child;
+               }
+               return null;
+       }
+
+       public synchronized Boolean isLoaded() {
+               return loaded;
+       }
+
+       public String getName() {
+               return name;
+       }
+
+       public void setParent(TreeParent parent) {
+               this.parent = parent;
+               if (parent != null && parent.path != null)
+                       this.path = parent.path + '/' + name;
+               else
+                       this.path = '/' + name;
+       }
+
+       public TreeParent getParent() {
+               return parent;
+       }
+
+       public String toString() {
+               return getName();
+       }
+
+       public int compareTo(TreeParent o) {
+               return name.compareTo(o.name);
+       }
+
+       @Override
+       public int hashCode() {
+               if (path != null)
+                       return path.hashCode();
+               else
+                       return name.hashCode();
+       }
+
+       @Override
+       public boolean equals(Object obj) {
+               if (path != null && obj instanceof TreeParent)
+                       return path.equals(((TreeParent) obj).path);
+               else
+                       return name.equals(obj.toString());
+       }
+
+}