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;
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;
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;
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;
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;
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;
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;
--- /dev/null
+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);
+ }
+
+}
+++ /dev/null
-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();
-}
--- /dev/null
+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();
+}
--- /dev/null
+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());
+ }
+}
--- /dev/null
+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();
+}
--- /dev/null
+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;
+ }
+
+}
+++ /dev/null
-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);
- }
-
-}
+++ /dev/null
-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());
- }
-}
+++ /dev/null
-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();
-}
+++ /dev/null
-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;
- }
-
-}
package org.argeo.eclipse.ui;
+import org.argeo.cms.ux.widgets.TreeParent;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;
+++ /dev/null
-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());
- }
-
-}
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;
/** 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;
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;
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;
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;
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
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;
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;
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;
}
@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;
}
@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
if (getCmsEditable().isEditing() && !(getEdited() instanceof Img)) {
if (source == mainSection)
return;
- EditablePart part = findDataParent(source);
+ SwtEditablePart part = findDataParent(source);
upload(part);
} else {
getCmsEditable().startEditing();
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));
}
}
- protected synchronized void upload(EditablePart part) {
+ protected synchronized void upload(SwtEditablePart part) {
if (part instanceof SectionPart) {
if (part instanceof Img) {
if (getEdited() == part)
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();
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 {
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;
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 {
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 {
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;
/**
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;
/**
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
// 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;
/**
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;
private MouseListener mouseListener;
private FocusListener focusListener;
- private EditablePart edited;
+ private SwtEditablePart edited;
private ISelection selection = StructuredSelection.EMPTY;
private AccessControlContext accessControlContext;
}
/** 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 */
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) {
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);
}
/**
- * 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());
return readOnly;
}
- protected EditablePart getEdited() {
+ protected SwtEditablePart getEdited() {
return edited;
}
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;
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;
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();
--- /dev/null
+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();
+
+}
+++ /dev/null
-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();
-
-}
--- /dev/null
+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());
+ }
+
+}