+Import-Package: javax.naming.*,\
+javax.security.*
\ No newline at end of file
+++ /dev/null
-package org.argeo.api;
-
-import org.osgi.resource.Namespace;
-
-/** CMS Data Model capability namespace. */
-public class DataModelNamespace extends Namespace {
-
- public static final String CMS_DATA_MODEL_NAMESPACE = "cms.datamodel";
- public static final String NAME = "name";
- public static final String CND = "cnd";
- /** If 'true', indicates that no repository should be published */
- public static final String ABSTRACT = "abstract";
-
- private DataModelNamespace() {
- // empty
- }
-
-}
+++ /dev/null
-package org.argeo.api;
-
-import org.osgi.resource.Namespace;
-
-/** Namespace defining which resources can be published. Typically use to expose icon of scripts to the web. */
-public class PublishNamespace extends Namespace {
-
- public static final String CMS_PUBLISH_NAMESPACE = "cms.publish";
- public static final String PKG = "pkg";
- public static final String FILE = "file";
-
- private PublishNamespace() {
- // empty
- }
-
-}
--- /dev/null
+package org.argeo.api.cms;
+
+/** A 2D size. */
+public class Cms2DSize {
+ private Integer width;
+ private Integer height;
+
+ public Cms2DSize() {
+
+ }
+
+ public Cms2DSize(Integer width, Integer height) {
+ super();
+ this.width = width;
+ this.height = height;
+ }
+
+ public Integer getWidth() {
+ return width;
+ }
+
+ public void setWidth(Integer width) {
+ this.width = width;
+ }
+
+ public Integer getHeight() {
+ return height;
+ }
+
+ public void setHeight(Integer height) {
+ this.height = height;
+ }
+
+}
--- /dev/null
+package org.argeo.api.cms;
+
+import java.util.Set;
+
+/** An extensible user interface base on the CMS backend. */
+public interface CmsApp {
+ /**
+ * If {@link CmsUi#setData(String, Object)} is set with this property, it
+ * indicates a different UI (typically with another theming. The {@link CmsApp}
+ * can use this information, but it doesn't have to be set, in which case a
+ * default UI must be provided. The provided value must belong to the values
+ * returned by {@link CmsApp#getUiNames()}.
+ */
+ final static String UI_NAME_PROPERTY = CmsApp.class.getName() + ".ui.name";
+
+ Set<String> getUiNames();
+
+ CmsUi initUi(Object uiParent);
+
+ void refreshUi(CmsUi cmsUi, String state);
+
+ void setState(CmsUi cmsUi, String state);
+
+ CmsTheme getTheme(String uiName);
+
+ boolean allThemesAvailable();
+
+ void addCmsAppListener(CmsAppListener listener);
+
+ void removeCmsAppListener(CmsAppListener listener);
+}
--- /dev/null
+package org.argeo.api.cms;
+
+/** Notifies important events in a CMS App life cycle. */
+public interface CmsAppListener {
+ /** Theming has been updated and should be reloaded. */
+ void themingUpdated();
+}
--- /dev/null
+package org.argeo.api.cms;
+
+/** Abstraction of a simple edition life cycle. */
+public interface CmsEditable {
+
+ /** Whether the calling thread can edit, the value is immutable */
+ public Boolean canEdit();
+
+ public Boolean isEditing();
+
+ public void startEditing();
+
+ public void stopEditing();
+
+ public static CmsEditable NON_EDITABLE = new CmsEditable() {
+
+ @Override
+ public void stopEditing() {
+ }
+
+ @Override
+ public void startEditing() {
+ }
+
+ @Override
+ public Boolean isEditing() {
+ return false;
+ }
+
+ @Override
+ public Boolean canEdit() {
+ return false;
+ }
+ };
+
+ public static CmsEditable ALWAYS_EDITING = new CmsEditable() {
+
+ @Override
+ public void stopEditing() {
+ }
+
+ @Override
+ public void startEditing() {
+ }
+
+ @Override
+ public Boolean isEditing() {
+ return true;
+ }
+
+ @Override
+ public Boolean canEdit() {
+ return true;
+ }
+ };
+
+}
--- /dev/null
+package org.argeo.api.cms;
+
+/**
+ * Can be applied to {@link Enum}s in order to define events used by
+ * {@link CmsView#sendEvent(String, java.util.Map)}.
+ */
+public interface CmsEvent {
+ String name();
+
+ default String topic() {
+ return getTopicBase() + "/" + name();
+ }
+
+ default String getTopicBase() {
+ return "argeo/cms";
+ }
+
+
+}
--- /dev/null
+package org.argeo.api.cms;
+
+import java.io.InputStream;
+
+/** Read and write access to images. */
+public interface CmsImageManager<V, M> {
+ /** Load image in control */
+ public Boolean load(M node, V control, Cms2DSize size);
+
+ /** @return (0,0) if not available */
+ public Cms2DSize getImageSize(M node);
+
+ /**
+ * The related <img> tag, with src, width and height set.
+ *
+ * @return null if not available
+ */
+ public String getImageTag(M node);
+
+ /**
+ * The related <img> tag, with url, width and height set. Caller must
+ * close the tag (or add additional attributes).
+ *
+ * @return null if not available
+ */
+ public StringBuilder getImageTagBuilder(M node, Cms2DSize size);
+
+ /**
+ * Returns the remotely accessible URL of the image (registering it if
+ * needed) @return null if not available
+ */
+ public String getImageUrl(M node);
+
+// public Binary getImageBinary(Node node) throws RepositoryException;
+
+// public Image getSwtImage(Node node) throws RepositoryException;
+
+ /** @return URL */
+ public String uploadImage(M context, M uploadFolder, String fileName, InputStream in, String contentType);
+
+ @Deprecated
+ default String uploadImage(M uploadFolder, String fileName, InputStream in) {
+ System.err.println("Context must be provided to " + CmsImageManager.class.getName());
+ return uploadImage(null, uploadFolder, fileName, in, null);
+ }
+}
--- /dev/null
+package org.argeo.api.cms;
+
+import java.time.ZonedDateTime;
+import java.util.Locale;
+import java.util.UUID;
+
+import javax.naming.ldap.LdapName;
+import javax.security.auth.Subject;
+
+/** An authenticated user session. */
+public interface CmsSession {
+ final static String USER_DN = "DN";
+ final static String SESSION_UUID = "entryUUID";
+ final static String SESSION_LOCAL_ID = "uniqueIdentifier";
+
+ UUID getUuid();
+
+ String getUserRole();
+
+ LdapName getUserDn();
+
+ String getLocalId();
+
+ String getDisplayName();
+// Authorization getAuthorization();
+
+ Subject getSubject();
+
+ boolean isAnonymous();
+
+ ZonedDateTime getCreationTime();
+
+ ZonedDateTime getEnd();
+
+ Locale getLocale();
+
+ boolean isValid();
+
+ void registerView(String uid, Object view);
+}
--- /dev/null
+package org.argeo.api.cms;
+
+import java.util.UUID;
+
+import javax.security.auth.Subject;
+
+/**
+ * The ID of a {@link CmsSession}, which must be available in the private
+ * credentials of an authenticated {@link Subject}.
+ */
+public class CmsSessionId {
+ private final UUID uuid;
+
+ public CmsSessionId(UUID value) {
+ if (value == null)
+ throw new IllegalArgumentException("Value cannot be null");
+ this.uuid = value;
+ }
+
+ public UUID getUuid() {
+ return uuid;
+ }
+
+ @Override
+ public int hashCode() {
+ return uuid.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof CmsSessionId && ((CmsSessionId) obj).getUuid().equals(uuid);
+ }
+
+ @Override
+ public String toString() {
+ return "Node Session " + uuid;
+ }
+
+}
--- /dev/null
+package org.argeo.api.cms;
+
+/** Can be applied to {@link Enum}s in order to generate (CSS) class names. */
+public interface CmsStyle {
+ String name();
+
+ /** @deprecated use {@link #style()} instead. */
+ @Deprecated
+ default String toStyleClass() {
+ return style();
+ }
+
+ default String style() {
+ String classPrefix = getClassPrefix();
+ return "".equals(classPrefix) ? name() : classPrefix + "-" + name();
+ }
+
+ default String getClassPrefix() {
+ return "";
+ }
+
+}
--- /dev/null
+package org.argeo.api.cms;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Set;
+
+/** A CMS theme which can be applied to web apps as well as desktop apps. */
+public interface CmsTheme {
+ /** Unique ID of this theme. */
+ String getThemeId();
+
+ /**
+ * Load a resource as an input stream, base don its relative path, or
+ * <code>null</code> if not found
+ */
+ InputStream getResourceAsStream(String resourceName) throws IOException;
+
+ /** Relative paths to standard web CSS. */
+ Set<String> getWebCssPaths();
+
+ /** Relative paths to RAP specific CSS. */
+ Set<String> getRapCssPaths();
+
+ /** Relative paths to SWT specific CSS. */
+ Set<String> getSwtCssPaths();
+
+ /** Relative paths to images such as icons. */
+ Set<String> getImagesPaths();
+
+ /** Relative paths to fonts. */
+ Set<String> getFontsPaths();
+
+ /** Tags to be added to the header section of the HTML page. */
+ String getHtmlHeaders();
+
+ /** The HTML body to use. */
+ String getBodyHtml();
+
+ /** The default icon size (typically the smallest). */
+ Integer getDefaultIconSize();
+
+ /** Loads one of the relative path provided by the other methods. */
+ InputStream loadPath(String path) throws IOException;
+
+}
--- /dev/null
+package org.argeo.api.cms;
+
+public interface CmsUi {
+ Object getData(String key);
+ void setData(String key, Object value);
+
+}
--- /dev/null
+package org.argeo.api.cms;
+
+import java.security.PrivilegedAction;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.security.auth.login.LoginContext;
+
+/** Provides interaction with the CMS system. */
+public interface CmsView {
+ final static String CMS_VIEW_UID_PROPERTY = "argeo.cms.view.uid";
+ // String KEY = "org.argeo.cms.ui.view";
+
+ String getUid();
+
+ UxContext getUxContext();
+
+ // NAVIGATION
+ void navigateTo(String state);
+
+ // SECURITY
+ void authChange(LoginContext loginContext);
+
+ void logout();
+
+ // void registerCallbackHandler(CallbackHandler callbackHandler);
+
+ // SERVICES
+ void exception(Throwable e);
+
+ CmsImageManager<?, ?> getImageManager();
+
+ boolean isAnonymous();
+
+ /**
+ * Send an event to this topic. Does nothing by default., but if implemented it
+ * MUST set the {@link #CMS_VIEW_UID_PROPERTY} in the properties.
+ */
+ default void sendEvent(String topic, Map<String, Object> properties) {
+
+ }
+
+ /**
+ * Convenience methods for when {@link #sendEvent(String, Map)} only requires
+ * one single parameter.
+ */
+ default void sendEvent(String topic, String param, Object value) {
+ Map<String, Object> properties = new HashMap<>();
+ properties.put(param, value);
+ sendEvent(topic, properties);
+ }
+
+ default void applyStyles(Object widget) {
+
+ }
+
+ default <T> T doAs(PrivilegedAction<T> action) {
+ throw new UnsupportedOperationException();
+ }
+
+ default Void runAs(Runnable runnable) {
+ return doAs(new PrivilegedAction<Void>() {
+
+ @Override
+ public Void run() {
+ if (runnable != null)
+ runnable.run();
+ return null;
+ }
+ });
+ }
+
+ default void stateChanged(String state, String title) {
+ }
+
+ default CmsSession getCmsSession() {
+ throw new UnsupportedOperationException();
+ }
+
+ default Object getData(String key) {
+ throw new UnsupportedOperationException();
+ }
+
+ @SuppressWarnings("unchecked")
+ default <T> T getUiContext(Class<T> clss) {
+ return (T) getData(clss.getName());
+ }
+
+ default <T> void setUiContext(Class<T> clss, T instance) {
+ setData(clss.getName(), instance);
+ }
+
+ default void setData(String key, Object value) {
+ throw new UnsupportedOperationException();
+ }
+
+}
--- /dev/null
+package org.argeo.api.cms;
+
+import java.util.function.BiFunction;
+
+/**
+ * Stateless UI part creator. Takes a parent view (V) and a model context (M) in
+ * order to create a view part (W) which can then be further configured. Such
+ * object can be used as services and reference other part of the model which
+ * are relevant for all created UI part.
+ */
+@FunctionalInterface
+public interface MvcProvider<V, M, W> extends BiFunction<V, M, W> {
+ W createUiPart(V parent, M context);
+
+ /**
+ * Whether this parent view is supported.
+ *
+ * @return true by default.
+ */
+ default boolean isViewSupported(V parent) {
+ return true;
+ }
+
+ /**
+ * Whether this context is supported.
+ *
+ * @return true by default.
+ */
+ default boolean isModelSupported(M context) {
+ return true;
+ }
+
+ default W apply(V parent, M context) {
+ if (!isViewSupported(parent))
+ throw new IllegalArgumentException("Parent view " + parent + "is not supported.");
+ if (!isModelSupported(context))
+ throw new IllegalArgumentException("Model context " + context + "is not supported.");
+ return createUiPart(parent, context);
+ }
+
+ default W createUiPart(V parent) {
+ return createUiPart(parent, null);
+ }
+}
--- /dev/null
+package org.argeo.api.cms;
+
+public interface UxContext {
+ boolean isPortrait();
+
+ boolean isLandscape();
+
+ boolean isSquare();
+
+ boolean isSmall();
+
+ /**
+ * Is a production environment (must be false by default, and be explicitly
+ * set during the CMS deployment). When false, it can activate additional UI
+ * capabilities in order to facilitate QA.
+ */
+ boolean isMasterData();
+}
--- /dev/null
+package org.argeo.api.gcr;
+
+import java.util.function.Supplier;
+
+public interface ContentRepository extends Supplier<ContentSession> {
+}
--- /dev/null
+package org.argeo.api.gcr;
+
+public interface ContentSession {
+
+}
import java.util.HashMap;
import java.util.Map;
-import org.argeo.cms.ui.dialogs.CmsFeedback;
+import org.argeo.cms.swt.dialogs.CmsFeedback;
import org.eclipse.rap.e4.E4ApplicationConfig;
import org.eclipse.rap.rwt.application.Application;
import org.eclipse.rap.rwt.application.Application.OperationMode;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsImageManager;
+import org.argeo.api.cms.CmsView;
+import org.argeo.api.cms.UxContext;
import org.argeo.cms.auth.CurrentUser;
-import org.argeo.cms.ui.CmsImageManager;
-import org.argeo.cms.ui.CmsView;
-import org.argeo.cms.ui.UxContext;
-import org.argeo.cms.ui.dialogs.CmsFeedback;
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.cms.swt.SimpleSwtUxContext;
+import org.argeo.cms.swt.auth.CmsLoginShell;
+import org.argeo.cms.swt.dialogs.CmsFeedback;
import org.argeo.cms.ui.util.SimpleImageManager;
-import org.argeo.cms.ui.util.SimpleUxContext;
-import org.argeo.cms.ui.widgets.auth.CmsLoginShell;
import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.e4.ui.workbench.UIEvents;
import org.eclipse.e4.ui.workbench.lifecycle.PostContextCreate;
Display display = Display.getCurrent();
// UiContext.setData(CmsView.KEY, this);
CmsLoginShell loginShell = new CmsLoginShell(this);
- CmsView.registerCmsView(loginShell.getShell(), this);
+ CmsSwtUtils.registerCmsView(loginShell.getShell(), this);
loginShell.setSubject(subject);
try {
// try pre-auth
}
if (CurrentUser.getUsername(getSubject()) == null)
return false;
- uxContext = new SimpleUxContext();
+ uxContext = new SimpleSwtUxContext();
imageManager = new SimpleImageManager();
eventBroker.subscribe(UIEvents.UILifeCycle.APP_STARTUP_COMPLETE, new EventHandler() {
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="Default CallbackHandler">
- <implementation class="org.argeo.cms.ui.widgets.auth.DynamicCallbackHandler"/>
+ <implementation class="org.argeo.cms.swt.auth.DynamicCallbackHandler"/>
<service>
<provide interface="javax.security.auth.callback.CallbackHandler"/>
</service>
org.argeo.cms,\
org.eclipse.core.commands.common,\
org.eclipse.jface.window,\
-org.argeo.cms.ui.widgets.auth,\
+org.argeo.cms.swt.auth,\
*
<tags>shellMaximized</tags>
<tags>auth.cn=admin,ou=roles,ou=node</tags>
<children xsi:type="advanced:PerspectiveStack" xmi:id="_jXVqsCk4Eein5vuhpK-Dew" elementId="org.argeo.cms.e4.perspectivestack.0" selectedElement="_xOVlsDvOEeiF1foPJZSZkw">
- <children xsi:type="advanced:Perspective" xmi:id="_xOVlsDvOEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.perspective.users" label="Users" iconURI="platform:/plugin/org.argeo.cms.ui.theme/icons/group.png">
+ <children xsi:type="advanced:Perspective" xmi:id="_xOVlsDvOEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.perspective.users" label="Users" iconURI="platform:/plugin/org.argeo.cms.swt/icons/group.png">
<tags>auth.cn=admin,ou=roles,ou=node</tags>
<children xsi:type="basic:PartSashContainer" xmi:id="_1tQoEDvOEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.partsashcontainer.2" horizontal="true">
<children xsi:type="basic:PartStack" xmi:id="_vtbKkDvkEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.partstack.4" containerData="4000" selectedElement="_9gukYDvOEeiF1foPJZSZkw">
- <children xsi:type="basic:Part" xmi:id="_9gukYDvOEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.part.users" containerData="" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.users.UsersView" label="Users" iconURI="platform:/plugin/org.argeo.cms.ui.theme/icons/person.png">
+ <children xsi:type="basic:Part" xmi:id="_9gukYDvOEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.part.users" containerData="" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.users.UsersView" label="Users" iconURI="platform:/plugin/org.argeo.cms.swt/icons/person.png">
<handlers xmi:id="_0mN68DvjEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handler.4" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.users.handlers.NewUser" command="_uL5i4DvjEeiF1foPJZSZkw"/>
<handlers xmi:id="_ODLdgDvkEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handler.5" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.users.handlers.DeleteUsers" command="_xkcMADvjEeiF1foPJZSZkw"/>
<toolbar xmi:id="_jLWmkDvjEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.toolbar.1">
- <children xsi:type="menu:HandledToolItem" xmi:id="_jy_OUDvjEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handledtoolitem.new" label="New" iconURI="platform:/plugin/org.argeo.cms.ui.theme/icons/add.png" command="_uL5i4DvjEeiF1foPJZSZkw"/>
- <children xsi:type="menu:HandledToolItem" xmi:id="_9qszMDvjEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handledtoolitem.delete" label="Delete" iconURI="platform:/plugin/org.argeo.cms.ui.theme/icons/delete.png" command="_xkcMADvjEeiF1foPJZSZkw"/>
+ <children xsi:type="menu:HandledToolItem" xmi:id="_jy_OUDvjEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handledtoolitem.new" label="New" iconURI="platform:/plugin/org.argeo.cms.swt/icons/add.png" command="_uL5i4DvjEeiF1foPJZSZkw"/>
+ <children xsi:type="menu:HandledToolItem" xmi:id="_9qszMDvjEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handledtoolitem.delete" label="Delete" iconURI="platform:/plugin/org.argeo.cms.swt/icons/delete.png" command="_xkcMADvjEeiF1foPJZSZkw"/>
</toolbar>
</children>
</children>
<tags>usersEditorArea</tags>
</children>
<children xsi:type="basic:PartStack" xmi:id="_-mFn8DvkEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.partstack.5" containerData="2000">
- <children xsi:type="basic:Part" xmi:id="_6etk4DvOEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.part.groups" containerData="" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.users.GroupsView" label="Groups" iconURI="platform:/plugin/org.argeo.cms.ui.theme/icons/group.png">
+ <children xsi:type="basic:Part" xmi:id="_6etk4DvOEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.part.groups" containerData="" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.users.GroupsView" label="Groups" iconURI="platform:/plugin/org.argeo.cms.swt/icons/group.png">
<handlers xmi:id="_cmShoDvkEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handler.6" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.users.handlers.NewGroup" command="_uL5i4DvjEeiF1foPJZSZkw"/>
<handlers xmi:id="_fbYfcDvkEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handler.7" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.users.handlers.DeleteGroups" command="_xkcMADvjEeiF1foPJZSZkw"/>
<toolbar xmi:id="_Us0rADvkEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.toolbar.2">
- <children xsi:type="menu:HandledToolItem" xmi:id="_VQTLgDvkEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handledtoolitem.new" label="New" iconURI="platform:/plugin/org.argeo.cms.ui.theme/icons/add.png" command="_uL5i4DvjEeiF1foPJZSZkw"/>
- <children xsi:type="menu:HandledToolItem" xmi:id="_XfME8DvkEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handledtoolitem.delete" label="Delete" iconURI="platform:/plugin/org.argeo.cms.ui.theme/icons/delete.png" command="_xkcMADvjEeiF1foPJZSZkw"/>
+ <children xsi:type="menu:HandledToolItem" xmi:id="_VQTLgDvkEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handledtoolitem.new" label="New" iconURI="platform:/plugin/org.argeo.cms.swt/icons/add.png" command="_uL5i4DvjEeiF1foPJZSZkw"/>
+ <children xsi:type="menu:HandledToolItem" xmi:id="_XfME8DvkEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handledtoolitem.delete" label="Delete" iconURI="platform:/plugin/org.argeo.cms.swt/icons/delete.png" command="_xkcMADvjEeiF1foPJZSZkw"/>
</toolbar>
</children>
</children>
</children>
</children>
- <children xsi:type="advanced:Perspective" xmi:id="_jvjWYCk4Eein5vuhpK-Dew" elementId="org.argeo.cms.e4.perspective.data" label="Data" iconURI="platform:/plugin/org.argeo.cms.ui.theme/icons/nodes.gif">
+ <children xsi:type="advanced:Perspective" xmi:id="_jvjWYCk4Eein5vuhpK-Dew" elementId="org.argeo.cms.e4.perspective.data" label="Data" iconURI="platform:/plugin/org.argeo.cms.swt/icons/nodes.gif">
<children xsi:type="basic:PartSashContainer" xmi:id="_h3tvMCkxEein5vuhpK-Dew" elementId="org.argeo.cms.e4.partsashcontainer.0" selectedElement="_0B9SECkxEein5vuhpK-Dew" horizontal="true">
<children xsi:type="basic:PartStack" xmi:id="_0B9SECkxEein5vuhpK-Dew" elementId="org.argeo.cms.e4.partstack.0" containerData="4000" selectedElement="_WAjPkCkTEein5vuhpK-Dew">
- <children xsi:type="basic:Part" xmi:id="_WAjPkCkTEein5vuhpK-Dew" elementId="org.argeo.cms.e4.jcrbrowser" containerData="" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.jcr.JcrBrowserView" label="JCR" iconURI="platform:/plugin/org.argeo.cms.ui.theme/icons/browser.gif">
+ <children xsi:type="basic:Part" xmi:id="_WAjPkCkTEein5vuhpK-Dew" elementId="org.argeo.cms.e4.jcrbrowser" containerData="" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.jcr.JcrBrowserView" label="JCR" iconURI="platform:/plugin/org.argeo.cms.swt/icons/browser.gif">
<menus xsi:type="menu:PopupMenu" xmi:id="_eXiUECqREeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.popupmenu.nodeViewer">
- <children xsi:type="menu:HandledMenuItem" xmi:id="_GVeO8CqhEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handledmenuitem.refresh" label="Refresh" iconURI="platform:/plugin/org.argeo.cms.ui.theme/icons/refresh.png" command="_TOKHsCqYEeidr6NYQH6GbQ"/>
- <children xsi:type="menu:HandledMenuItem" xmi:id="_fU238CqREeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handledmenuitem.addfoldernode" label="Add folder" iconURI="platform:/plugin/org.argeo.cms.ui.theme/icons/addFolder.gif" command="_RgE5cCqREeidr6NYQH6GbQ"/>
- <children xsi:type="menu:HandledMenuItem" xmi:id="_U4o9cCqhEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handledmenuitem.rename" label="Rename" iconURI="platform:/plugin/org.argeo.cms.ui.theme/icons/rename.gif" command="_ZrcUMCqYEeidr6NYQH6GbQ"/>
- <children xsi:type="menu:HandledMenuItem" xmi:id="_Ncxo0CqhEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handledmenuitem.remove" label="Remove" iconURI="platform:/plugin/org.argeo.cms.ui.theme/icons/remove.gif" command="_ChJ-4CqYEeidr6NYQH6GbQ"/>
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_GVeO8CqhEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handledmenuitem.refresh" label="Refresh" iconURI="platform:/plugin/org.argeo.cms.swt/icons/refresh.png" command="_TOKHsCqYEeidr6NYQH6GbQ"/>
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_fU238CqREeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handledmenuitem.addfoldernode" label="Add folder" iconURI="platform:/plugin/org.argeo.cms.swt/icons/addFolder.gif" command="_RgE5cCqREeidr6NYQH6GbQ"/>
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_U4o9cCqhEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handledmenuitem.rename" label="Rename" iconURI="platform:/plugin/org.argeo.cms.swt/icons/rename.gif" command="_ZrcUMCqYEeidr6NYQH6GbQ"/>
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_Ncxo0CqhEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handledmenuitem.remove" label="Remove" iconURI="platform:/plugin/org.argeo.cms.swt/icons/remove.gif" command="_ChJ-4CqYEeidr6NYQH6GbQ"/>
</menus>
<menus xmi:id="_oRg_ACqTEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.menu.0">
<tags>ViewMenu</tags>
- <children xsi:type="menu:HandledMenuItem" xmi:id="_yJR8ECqYEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handledmenuitem.refresh" label="Refresh" iconURI="platform:/plugin/org.argeo.cms.ui.theme/icons/refresh.png" command="_TOKHsCqYEeidr6NYQH6GbQ"/>
- <children xsi:type="menu:HandledMenuItem" xmi:id="_o6HQECqTEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handledmenuitem.addfoldernode" label="Add folder" iconURI="platform:/plugin/org.argeo.cms.ui.theme/icons/addFolder.gif" command="_RgE5cCqREeidr6NYQH6GbQ"/>
- <children xsi:type="menu:HandledMenuItem" xmi:id="_5D7aACqYEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handledmenuitem.rename" label="Rename" iconURI="platform:/plugin/org.argeo.cms.ui.theme/icons/rename.gif" command="_ZrcUMCqYEeidr6NYQH6GbQ"/>
- <children xsi:type="menu:HandledMenuItem" xmi:id="_7rR2wCqYEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handledmenuitem.delete" label="Delete" iconURI="platform:/plugin/org.argeo.cms.ui.theme/icons/remove.gif" command="_ChJ-4CqYEeidr6NYQH6GbQ"/>
- <children xsi:type="menu:HandledMenuItem" xmi:id="_XsHLgFgQEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.handledmenuitem.0" iconURI="platform:/plugin/org.argeo.cms.ui.theme/icons/addRepo.gif" command="_ZWpasFgQEeiknZQLx-vtnA"/>
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_yJR8ECqYEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handledmenuitem.refresh" label="Refresh" iconURI="platform:/plugin/org.argeo.cms.swt/icons/refresh.png" command="_TOKHsCqYEeidr6NYQH6GbQ"/>
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_o6HQECqTEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handledmenuitem.addfoldernode" label="Add folder" iconURI="platform:/plugin/org.argeo.cms.swt/icons/addFolder.gif" command="_RgE5cCqREeidr6NYQH6GbQ"/>
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_5D7aACqYEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handledmenuitem.rename" label="Rename" iconURI="platform:/plugin/org.argeo.cms.swt/icons/rename.gif" command="_ZrcUMCqYEeidr6NYQH6GbQ"/>
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_7rR2wCqYEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handledmenuitem.delete" label="Delete" iconURI="platform:/plugin/org.argeo.cms.swt/icons/remove.gif" command="_ChJ-4CqYEeidr6NYQH6GbQ"/>
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_XsHLgFgQEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.handledmenuitem.0" iconURI="platform:/plugin/org.argeo.cms.swt/icons/addRepo.gif" command="_ZWpasFgQEeiknZQLx-vtnA"/>
</menus>
</children>
</children>
</children>
</children>
</children>
- <children xsi:type="advanced:Perspective" xmi:id="_u5ZakFhJEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.perspective.monitoring" label="Monitoring" iconURI="platform:/plugin/org.argeo.cms.ui.theme/icons/bundles.gif">
+ <children xsi:type="advanced:Perspective" xmi:id="_u5ZakFhJEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.perspective.monitoring" label="Monitoring" iconURI="platform:/plugin/org.argeo.cms.swt/icons/bundles.gif">
<children xsi:type="basic:PartStack" xmi:id="_7i7t8FhJEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.partstack.6">
- <children xsi:type="basic:Part" xmi:id="_Z-3cMFhbEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.part.osgiConfigurations" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.monitoring.OsgiConfigurationsView" label="OSGi Configurations" iconURI="platform:/plugin/org.argeo.cms.ui.theme/icons/node.gif"/>
- <children xsi:type="basic:Part" xmi:id="_8dM90FhJEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.part.cmsSessions" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.monitoring.CmsSessionsView" label="CMS Sessions" iconURI="platform:/plugin/org.argeo.cms.ui.theme/icons/person-logged-in.png"/>
- <children xsi:type="basic:Part" xmi:id="_KqRZIFhNEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.part.modules" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.monitoring.ModulesView" label="Modules" iconURI="platform:/plugin/org.argeo.cms.ui.theme/icons/bundles.gif"/>
- <children xsi:type="basic:Part" xmi:id="_dXtIoFhNEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.part.bundles" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.monitoring.BundlesView" label="Bundles" iconURI="platform:/plugin/org.argeo.cms.ui.theme/icons/bundles.gif"/>
+ <children xsi:type="basic:Part" xmi:id="_Z-3cMFhbEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.part.osgiConfigurations" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.monitoring.OsgiConfigurationsView" label="OSGi Configurations" iconURI="platform:/plugin/org.argeo.cms.swt/icons/node.gif"/>
+ <children xsi:type="basic:Part" xmi:id="_8dM90FhJEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.part.cmsSessions" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.monitoring.CmsSessionsView" label="CMS Sessions" iconURI="platform:/plugin/org.argeo.cms.swt/icons/person-logged-in.png"/>
+ <children xsi:type="basic:Part" xmi:id="_KqRZIFhNEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.part.modules" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.monitoring.ModulesView" label="Modules" iconURI="platform:/plugin/org.argeo.cms.swt/icons/bundles.gif"/>
+ <children xsi:type="basic:Part" xmi:id="_dXtIoFhNEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.part.bundles" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.monitoring.BundlesView" label="Bundles" iconURI="platform:/plugin/org.argeo.cms.swt/icons/bundles.gif"/>
</children>
</children>
- <children xsi:type="advanced:Perspective" xmi:id="_ABK2ADsNEeiUntFYWh-hFg" elementId="org.argeo.cms.e4.perspective.files" label="Files" iconURI="platform:/plugin/org.argeo.cms.ui.theme/icons/file.gif">
+ <children xsi:type="advanced:Perspective" xmi:id="_ABK2ADsNEeiUntFYWh-hFg" elementId="org.argeo.cms.e4.perspective.files" label="Files" iconURI="platform:/plugin/org.argeo.cms.swt/icons/file.gif">
<children xsi:type="basic:PartSashContainer" xmi:id="_FPimEDsSEeiUntFYWh-hFg" elementId="org.argeo.cms.e4.partsashcontainer.1" horizontal="true">
<children xsi:type="basic:PartStack" xmi:id="_H93NgDsSEeiUntFYWh-hFg" elementId="org.argeo.cms.e4.partstack.2" containerData="4000">
- <children xsi:type="basic:Part" xmi:id="_Izxh0DsSEeiUntFYWh-hFg" elementId="org.argeo.cms.e4.part.files" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.files.NodeFsBrowserView" label="Files" iconURI="platform:/plugin/org.argeo.cms.ui.theme/icons/file.gif"/>
+ <children xsi:type="basic:Part" xmi:id="_Izxh0DsSEeiUntFYWh-hFg" elementId="org.argeo.cms.e4.part.files" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.files.NodeFsBrowserView" label="Files" iconURI="platform:/plugin/org.argeo.cms.swt/icons/file.gif"/>
</children>
<children xsi:type="basic:Part" xmi:id="_TMqBMDsSEeiUntFYWh-hFg" elementId="org.argeo.cms.e4.part.0" containerData="6000"/>
</children>
<handlers xmi:id="_Vwax0DvrEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handler.8" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.handlers.OpenPerspective" command="_AF1UsDvrEeiF1foPJZSZkw"/>
<trimBars xmi:id="_euVxMCk2Eein5vuhpK-Dew" elementId="org.argeo.cms.e4.trimbar.0" side="Left">
<children xsi:type="menu:ToolBar" xmi:id="_fotHsCk2Eein5vuhpK-Dew" elementId="org.argeo.cms.e4.toolbar.0">
- <children xsi:type="menu:HandledToolItem" xmi:id="_jCSQgDvrEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handledtoolitem.users" label="Users" iconURI="platform:/plugin/org.argeo.cms.ui.theme/icons/group.png" command="_AF1UsDvrEeiF1foPJZSZkw">
+ <children xsi:type="menu:HandledToolItem" xmi:id="_jCSQgDvrEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handledtoolitem.users" label="Users" iconURI="platform:/plugin/org.argeo.cms.swt/icons/group.png" command="_AF1UsDvrEeiF1foPJZSZkw">
<tags>auth.cn=admin,ou=roles,ou=node</tags>
<parameters xmi:id="_lu_uYDvrEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.parameter.2" name="perspectiveId" value="org.argeo.cms.e4.perspective.users"/>
</children>
- <children xsi:type="menu:HandledToolItem" xmi:id="_jfUM4Ck2Eein5vuhpK-Dew" elementId="org.argeo.cms.e4.handledtoolitem.test" label="Data" iconURI="platform:/plugin/org.argeo.cms.ui.theme/icons/nodes.gif" command="_AF1UsDvrEeiF1foPJZSZkw">
+ <children xsi:type="menu:HandledToolItem" xmi:id="_jfUM4Ck2Eein5vuhpK-Dew" elementId="org.argeo.cms.e4.handledtoolitem.test" label="Data" iconURI="platform:/plugin/org.argeo.cms.swt/icons/nodes.gif" command="_AF1UsDvrEeiF1foPJZSZkw">
<parameters xmi:id="_KDlXQDvrEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.parameter.0" name="perspectiveId" value="org.argeo.cms.e4.perspective.data"/>
</children>
- <children xsi:type="menu:HandledToolItem" xmi:id="_dhv80FhKEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.handledtoolitem.monitoring" label="Monitoring" iconURI="platform:/plugin/org.argeo.cms.ui.theme/icons/bundles.gif" command="_AF1UsDvrEeiF1foPJZSZkw">
+ <children xsi:type="menu:HandledToolItem" xmi:id="_dhv80FhKEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.handledtoolitem.monitoring" label="Monitoring" iconURI="platform:/plugin/org.argeo.cms.swt/icons/bundles.gif" command="_AF1UsDvrEeiF1foPJZSZkw">
<parameters xmi:id="_kjN0cFhKEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.parameter.3" name="perspectiveId" value="org.argeo.cms.e4.perspective.monitoring"/>
</children>
- <children xsi:type="menu:HandledToolItem" xmi:id="_b0OHUDvrEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handledtoolitem.files" label="Files" iconURI="platform:/plugin/org.argeo.cms.ui.theme/icons/file.gif" command="_AF1UsDvrEeiF1foPJZSZkw">
+ <children xsi:type="menu:HandledToolItem" xmi:id="_b0OHUDvrEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.handledtoolitem.files" label="Files" iconURI="platform:/plugin/org.argeo.cms.swt/icons/file.gif" command="_AF1UsDvrEeiF1foPJZSZkw">
<parameters xmi:id="_fXvRYDvrEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.parameter.1" name="perspectiveId" value="org.argeo.cms.e4.perspective.files"/>
</children>
<children xsi:type="menu:ToolBarSeparator" xmi:id="_wuoL8FhLEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.toolbarseparator.0"/>
- <children xsi:type="menu:HandledToolItem" xmi:id="_2v8DkFhKEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.handledtoolitem.logout" label="Log out" iconURI="platform:/plugin/org.argeo.cms.ui.theme/icons/logout.png" command="_PsWd0FhLEeiknZQLx-vtnA"/>
+ <children xsi:type="menu:HandledToolItem" xmi:id="_2v8DkFhKEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.handledtoolitem.logout" label="Log out" iconURI="platform:/plugin/org.argeo.cms.swt/icons/logout.png" command="_PsWd0FhLEeiknZQLx-vtnA"/>
</children>
</trimBars>
</children>
<handlers xmi:id="_omPfkCqYEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.handler.3" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.jcr.handlers.RenameNode" command="_ZrcUMCqYEeidr6NYQH6GbQ"/>
<handlers xmi:id="_dUg-cFgQEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.handler.9" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.jcr.handlers.AddRemoteRepository" command="_ZWpasFgQEeiknZQLx-vtnA"/>
<handlers xmi:id="_RQyFAFhLEeiknZQLx-vtnA" elementId="org.argeo.cms.e4.handler.10" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.handlers.CloseWorkbench" command="_PsWd0FhLEeiknZQLx-vtnA"/>
- <descriptors xmi:id="_XzfoMCqlEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.partdescriptor.nodeEditor" label="Node Editor" iconURI="platform:/plugin/org.argeo.cms.ui.theme/icons/node.gif" allowMultiple="true" category="dataExplorer" closeable="true" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.jcr.JcrNodeEditor"/>
- <descriptors xmi:id="_sAdNwDvdEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.partdescriptor.userEditor" label="User Editor" iconURI="platform:/plugin/org.argeo.cms.ui.theme/icons/person.png" allowMultiple="true" category="usersEditorArea" closeable="true" dirtyable="true" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.users.UserEditor"/>
- <descriptors xmi:id="_5nK7EDvdEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.partdescriptor.groupEditor" label="Group Editor" iconURI="platform:/plugin/org.argeo.cms.ui.theme/icons/group.png" allowMultiple="true" category="usersEditorArea" closeable="true" dirtyable="true" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.users.GroupEditor"/>
+ <descriptors xmi:id="_XzfoMCqlEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.partdescriptor.nodeEditor" label="Node Editor" iconURI="platform:/plugin/org.argeo.cms.swt/icons/node.gif" allowMultiple="true" category="dataExplorer" closeable="true" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.jcr.JcrNodeEditor"/>
+ <descriptors xmi:id="_sAdNwDvdEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.partdescriptor.userEditor" label="User Editor" iconURI="platform:/plugin/org.argeo.cms.swt/icons/person.png" allowMultiple="true" category="usersEditorArea" closeable="true" dirtyable="true" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.users.UserEditor"/>
+ <descriptors xmi:id="_5nK7EDvdEeiF1foPJZSZkw" elementId="org.argeo.cms.e4.partdescriptor.groupEditor" label="Group Editor" iconURI="platform:/plugin/org.argeo.cms.swt/icons/group.png" allowMultiple="true" category="usersEditorArea" closeable="true" dirtyable="true" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.users.GroupEditor"/>
<commands xmi:id="_RgE5cCqREeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.command.addFolderNode" commandName="Add folder node" category="_MDkwUCqYEeidr6NYQH6GbQ"/>
<commands xmi:id="_ChJ-4CqYEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.command.deleteNodes" commandName="Delete nodes" category="_MDkwUCqYEeidr6NYQH6GbQ"/>
<commands xmi:id="_TOKHsCqYEeidr6NYQH6GbQ" elementId="org.argeo.cms.e4.command.refreshNodes" commandName="Refresh nodes" category="_MDkwUCqYEeidr6NYQH6GbQ"/>
import org.argeo.api.security.CryptoKeyring;
import org.argeo.cms.CmsException;
import org.argeo.cms.auth.CurrentUser;
-import org.argeo.cms.ui.dialogs.CmsMessageDialog;
+import org.argeo.cms.swt.dialogs.CmsMessageDialog;
import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
import org.argeo.osgi.transaction.WorkTransaction;
import org.eclipse.e4.core.di.annotations.Execute;
import org.argeo.api.security.CryptoKeyring;
import org.argeo.api.security.Keyring;
import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.ui.jcr.JcrBrowserUtils;
import org.argeo.cms.ui.jcr.NodeContentProvider;
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.ui.util.CmsUiUtils;
import org.argeo.eclipse.ui.EclipseUiException;
import org.argeo.eclipse.ui.TreeParent;
import org.argeo.eclipse.ui.jcr.AsyncUiEventListener;
// Create the tree on top of the view
Composite top = new Composite(sashForm, SWT.NONE);
// GridLayout gl = new GridLayout(1, false);
- top.setLayout(CmsUiUtils.noSpaceGridLayout());
+ top.setLayout(CmsSwtUtils.noSpaceGridLayout());
try {
this.userSession = this.nodeRepository.login(NodeConstants.HOME_WORKSPACE);
// Create the property viewer on the bottom
Composite bottom = new Composite(sashForm, SWT.NONE);
- bottom.setLayout(CmsUiUtils.noSpaceGridLayout());
+ bottom.setLayout(CmsSwtUtils.noSpaceGridLayout());
propertiesViewer = createPropertiesViewer(bottom);
sashForm.setWeights(getWeights());
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.argeo.cms.ui.util.CmsUiUtils;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
public AbstractOsgiComposite(Composite parent, int style) {
super(parent, style);
- parent.setLayout(CmsUiUtils.noSpaceGridLayout());
- setLayout(CmsUiUtils.noSpaceGridLayout());
+ parent.setLayout(CmsSwtUtils.noSpaceGridLayout());
+ setLayout(CmsSwtUtils.noSpaceGridLayout());
setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
initUi(style);
}
import javax.jcr.RepositoryException;
import javax.jcr.Value;
+import org.argeo.api.cms.Cms2DSize;
import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.ui.CmsUiProvider;
import org.argeo.cms.ui.util.CmsLink;
-import org.argeo.cms.ui.util.CmsUiUtils;
import org.argeo.cms.ui.widgets.EditableImage;
import org.argeo.cms.ui.widgets.Img;
import org.argeo.jcr.JcrUtils;
if (context == null)
// return null;
throw new CmsException("Context cannot be null");
- GridLayout layout = CmsUiUtils.noSpaceGridLayout();
+ GridLayout layout = CmsSwtUtils.noSpaceGridLayout();
layout.numColumns = 2;
parent.setLayout(layout);
// Left
Composite leftCmp = new Composite(parent, SWT.NO_FOCUS);
- leftCmp.setLayoutData(CmsUiUtils.fillAll());
+ leftCmp.setLayoutData(CmsSwtUtils.fillAll());
createBrowserPart(leftCmp, context);
// Right
}
private void createBrowserPart(Composite parent, Node context) throws RepositoryException {
- GridLayout layout = CmsUiUtils.noSpaceGridLayout();
+ GridLayout layout = CmsSwtUtils.noSpaceGridLayout();
parent.setLayout(layout);
Composite filterCmp = new Composite(parent, SWT.NO_FOCUS);
- filterCmp.setLayoutData(CmsUiUtils.fillWidth());
+ filterCmp.setLayoutData(CmsSwtUtils.fillWidth());
// top filter
addFilterPanel(filterCmp);
// scrolled composite
scrolledCmp = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.BORDER | SWT.NO_FOCUS);
- scrolledCmp.setLayoutData(CmsUiUtils.fillAll());
+ scrolledCmp.setLayoutData(CmsSwtUtils.fillAll());
scrolledCmp.setExpandVertical(true);
scrolledCmp.setExpandHorizontal(true);
scrolledCmp.setShowFocusedControl(true);
}
private Control initExplorer(Composite parent, Node context) throws RepositoryException {
- parent.setLayout(CmsUiUtils.noSpaceGridLayout());
+ parent.setLayout(CmsSwtUtils.noSpaceGridLayout());
createBrowserColumn(parent, context);
return null;
}
public void addFilterPanel(Composite parent) {
- parent.setLayout(CmsUiUtils.noSpaceGridLayout(new GridLayout(2, false)));
+ parent.setLayout(CmsSwtUtils.noSpaceGridLayout(new GridLayout(2, false)));
// Text Area for the filter
parentPathTxt = new Text(parent, SWT.NO_FOCUS);
parentPathTxt.setEditable(false);
filterTxt = new Text(parent, SWT.SEARCH | SWT.ICON_CANCEL);
filterTxt.setMessage("Filter current list");
- filterTxt.setLayoutData(CmsUiUtils.fillWidth());
+ filterTxt.setLayoutData(CmsSwtUtils.fillWidth());
filterTxt.addModifyListener(new ModifyListener() {
private static final long serialVersionUID = 7709303319740056286L;
private void setEdited(Node node) {
try {
currEdited = node;
- CmsUiUtils.clear(nodeDisplayParent);
+ CmsSwtUtils.clear(nodeDisplayParent);
createNodeView(nodeDisplayParent, currEdited);
nodeDisplayParent.layout();
refreshFilters(node);
if (!browserCols.containsKey(currNodePath))
createBrowserColumn(colViewer, node);
- colViewer.setLayout(CmsUiUtils.noSpaceGridLayout(new GridLayout(browserCols.size(), false)));
+ colViewer.setLayout(CmsSwtUtils.noSpaceGridLayout(new GridLayout(browserCols.size(), false)));
// colViewer.pack();
colViewer.layout();
// also resize the scrolled composite
}
}
- private Point imageWidth = new Point(250, 0);
+ private Cms2DSize imageWidth = new Cms2DSize(250, 0);
/**
* Recreates the content of the box that displays information about the current
// Name and primary type
Label contextL = new Label(parent, SWT.NONE);
- CmsUiUtils.markup(contextL);
+ CmsSwtUtils.markup(contextL);
contextL.setText("<b>" + context.getName() + "</b>");
new Label(parent, SWT.NONE).setText(context.getPrimaryNodeType().getName());
protected void populate() {
Composite parent = this;
- GridLayout layout = CmsUiUtils.noSpaceGridLayout();
+ GridLayout layout = CmsSwtUtils.noSpaceGridLayout();
this.setLayout(layout);
createTableViewer(parent);
GridData gd = new GridData(SWT.LEFT, SWT.FILL, false, true);
gd.widthHint = COLUMN_WIDTH;
listCmp.setLayoutData(gd);
- listCmp.setLayout(CmsUiUtils.noSpaceGridLayout());
+ listCmp.setLayout(CmsSwtUtils.noSpaceGridLayout());
entityViewer = new TableViewer(listCmp, SWT.VIRTUAL | SWT.SINGLE);
Table table = entityViewer.getTable();
- table.setLayoutData(CmsUiUtils.fillAll());
+ table.setLayoutData(CmsSwtUtils.fillAll());
table.setLinesVisible(true);
table.setHeaderVisible(false);
- CmsUiUtils.markup(table);
+ CmsSwtUtils.markup(table);
- CmsUiUtils.style(table, MaintenanceStyles.BROWSER_COLUMN);
+ CmsSwtUtils.style(table, MaintenanceStyles.BROWSER_COLUMN);
// first column
TableViewerColumn column = new TableViewerColumn(entityViewer, SWT.NONE);
package org.argeo.cms.e4.maintenance;
-import org.argeo.cms.ui.util.CmsUiUtils;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
Label label = new Label(this, SWT.NONE);
label.setData(new GridData(SWT.FILL, SWT.FILL, false, false));
- CmsUiUtils.markup(label);
+ CmsSwtUtils.markup(label);
label.setText(text.toString());
}
import org.apache.jackrabbit.core.RepositoryContext;
import org.apache.jackrabbit.core.config.RepositoryConfig;
import org.argeo.api.NodeConstants;
-import org.argeo.cms.ui.util.CmsUiUtils;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
}
Label label = new Label(parent, SWT.NONE);
label.setData(new GridData(SWT.FILL, SWT.FILL, false, false));
- CmsUiUtils.markup(label);
+ CmsSwtUtils.markup(label);
label.setText("<span style=''>" + text.toString() + "</span>");
}
import org.argeo.api.NodeConstants;
import org.argeo.api.NodeDeployment;
import org.argeo.api.NodeState;
-import org.argeo.cms.ui.util.CmsUiUtils;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
NodeState nodeState = bc.getService(nodeStateRef);
ServiceReference<NodeDeployment> nodeDeploymentRef = bc.getServiceReference(NodeDeployment.class);
Label label = new Label(composite, SWT.WRAP);
- CmsUiUtils.markup(label);
+ CmsSwtUtils.markup(label);
if (nodeDeploymentRef == null) {
label.setText("Not yet deployed on <br>" + nodeState.getHostname() + "</br>, please configure below.");
} else {
private static Group createHighLevelGroup(Composite parent, String text) {
Group group = new Group(parent, SWT.NONE);
group.setText(text);
- CmsUiUtils.markup(group);
+ CmsSwtUtils.markup(group);
return group;
}
import java.util.GregorianCalendar;
import java.util.TimeZone;
-import org.argeo.cms.ui.util.CmsUiUtils;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
this.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
logDisplay = new Text(this, SWT.WRAP | SWT.MULTI | SWT.READ_ONLY);
logDisplay.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- CmsUiUtils.markup(logDisplay);
+ CmsSwtUtils.markup(logDisplay);
Enumeration<LogEntry> logEntries = (Enumeration<LogEntry>) logReader.getLog();
while (logEntries.hasMoreElements())
logDisplay.append(printEntry(logEntries.nextElement()));
import javax.jcr.Node;
import javax.jcr.RepositoryException;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.ui.CmsUiProvider;
-import org.argeo.cms.ui.util.CmsUiUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
public Control createUi(Composite parent, Node context)
throws RepositoryException {
Composite body = new Composite(parent, SWT.NO_FOCUS);
- body.setLayoutData(CmsUiUtils.fillAll());
+ body.setLayoutData(CmsSwtUtils.fillAll());
body.setLayout(new GridLayout());
Label label = new Label(body, SWT.NONE);
label.setText("You should be an admin to perform maintenance operations. "
import java.net.URI;
-import org.argeo.cms.ui.util.CmsUiUtils;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
}
Label label = new Label(parent, SWT.NONE);
label.setData(new GridData(SWT.FILL, SWT.FILL, false, false));
- CmsUiUtils.markup(label);
+ CmsSwtUtils.markup(label);
label.setText(text.toString());
}
import javax.annotation.PostConstruct;
import javax.naming.ldap.LdapName;
-import org.argeo.cms.CmsException;
-import org.argeo.cms.auth.CmsSession;
+import org.argeo.api.cms.CmsSession;
import org.argeo.eclipse.ui.ColumnViewerComparator;
import org.argeo.eclipse.ui.specific.EclipseUiSpecificUtils;
import org.argeo.util.LangUtils;
private static final long serialVersionUID = -5234573509093747505L;
public String getText(Object element) {
- return ((CmsSession) element).getAuthorization().toString();
+ return ((CmsSession) element).getDisplayName();
}
public String getToolTipText(Object element) {
try {
srs = bc.getServiceReferences(CmsSession.class, null);
} catch (InvalidSyntaxException e) {
- throw new CmsException("Cannot retrieve CMS sessions", e);
+ throw new IllegalArgumentException("Cannot retrieve CMS sessions", e);
}
List<CmsSession> res = new ArrayList<>();
for (ServiceReference<CmsSession> sr : srs) {
package org.argeo.cms.e4.parts;
-import static org.argeo.cms.ui.util.CmsUiUtils.lbl;
-import static org.argeo.cms.ui.util.CmsUiUtils.txt;
-
import java.security.AccessController;
import java.time.ZonedDateTime;
import javax.annotation.PostConstruct;
import javax.security.auth.Subject;
-import org.argeo.cms.auth.CmsSession;
+import org.argeo.api.cms.CmsSession;
import org.argeo.cms.auth.CurrentUser;
+import org.argeo.cms.osgi.CmsOsgiUtils;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.osgi.framework.BundleContext;
p.setLayout(new GridLayout());
String username = CurrentUser.getUsername();
- lbl(p, "<strong>" + CurrentUser.getDisplayName() + "</strong>");
- txt(p, username);
- lbl(p, "Roles:");
+ CmsSwtUtils.lbl(p, "<strong>" + CurrentUser.getDisplayName() + "</strong>");
+ CmsSwtUtils.txt(p, username);
+ CmsSwtUtils.lbl(p, "Roles:");
roles: for (String role : CurrentUser.roles()) {
if (username.equals(role))
continue roles;
- txt(p, role);
+ CmsSwtUtils.txt(p, role);
}
Subject subject = Subject.getSubject(AccessController.getContext());
if (subject != null) {
- CmsSession cmsSession = CmsSession.getCmsSession(bc, subject);
+ CmsSession cmsSession = CmsOsgiUtils.getCmsSession(bc, subject);
ZonedDateTime loggedIndSince = cmsSession.getCreationTime();
- lbl(p, "Session:");
- txt(p, cmsSession.getUuid().toString());
- lbl(p, "Logged in since:");
- txt(p, loggedIndSince.toString());
+ CmsSwtUtils.lbl(p, "Session:");
+ CmsSwtUtils.txt(p, cmsSession.getUuid().toString());
+ CmsSwtUtils.lbl(p, "Logged in since:");
+ CmsSwtUtils.txt(p, loggedIndSince.toString());
}
}
}
import org.argeo.cms.e4.users.providers.RoleIconLP;
import org.argeo.cms.e4.users.providers.UserFilter;
import org.argeo.cms.jcr.CmsJcrUtils;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.ui.eclipse.forms.AbstractFormPart;
import org.argeo.cms.ui.eclipse.forms.IManagedForm;
-import org.argeo.cms.ui.util.CmsUiUtils;
import org.argeo.eclipse.ui.ColumnDefinition;
import org.argeo.eclipse.ui.EclipseUiUtils;
import org.argeo.eclipse.ui.parts.LdifUsersTable;
// GridLayout layout = new GridLayout(5, false);
GridLayout layout = new GridLayout(2, false);
body.setLayout(layout);
- body.setLayoutData(CmsUiUtils.fillWidth());
+ body.setLayoutData(CmsSwtUtils.fillWidth());
String cn = UserAdminUtils.getProperty(group, LdapAttrs.cn.name());
createReadOnlyLT(body, "Name", cn);
ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT);
ToolBar toolBar = toolBarManager.createControl(body);
- toolBar.setLayoutData(CmsUiUtils.fillWidth());
+ toolBar.setLayoutData(CmsSwtUtils.fillWidth());
toolBarManager.add(action);
toolBarManager.update(true);
import org.argeo.cms.e4.users.providers.DomainNameLP;
import org.argeo.cms.e4.users.providers.RoleIconLP;
import org.argeo.cms.e4.users.providers.UserFilter;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.ui.eclipse.forms.AbstractFormPart;
//import org.argeo.cms.ui.eclipse.forms.FormToolkit;
import org.argeo.cms.ui.eclipse.forms.IManagedForm;
-import org.argeo.cms.ui.util.CmsUiUtils;
import org.argeo.eclipse.ui.ColumnDefinition;
import org.argeo.eclipse.ui.EclipseUiUtils;
import org.argeo.eclipse.ui.parts.LdifUsersTable;
// Composite body= parent;
Composite body = new Composite(parent, SWT.BORDER);
body.setLayout(new GridLayout());
- body.setLayoutData(CmsUiUtils.fillAll());
+ body.setLayoutData(CmsSwtUtils.fillAll());
// boolean isAdmin = CurrentUser.isInRole(NodeConstants.ROLE_ADMIN);
Action action = new RemoveMembershipAction(userViewer, user, tooltip, SecurityAdminImages.ICON_REMOVE_DESC);
ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT);
ToolBar toolBar = toolBarManager.createControl(body);
- toolBar.setLayoutData(CmsUiUtils.fillWidth());
+ toolBar.setLayoutData(CmsSwtUtils.fillWidth());
toolBarManager.add(action);
toolBarManager.update(true);
return userViewerCmp;
package org.argeo.cms.jcr.internal;
-import static org.argeo.api.DataModelNamespace.CMS_DATA_MODEL_NAMESPACE;
+import static org.argeo.cms.osgi.DataModelNamespace.CMS_DATA_MODEL_NAMESPACE;
import java.util.ArrayList;
import java.util.Collections;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.argeo.api.DataModelNamespace;
import org.argeo.cms.CmsException;
+import org.argeo.cms.osgi.DataModelNamespace;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
package org.argeo.cms.jcr.internal;
-import static org.argeo.api.DataModelNamespace.CMS_DATA_MODEL_NAMESPACE;
+import static org.argeo.cms.osgi.DataModelNamespace.CMS_DATA_MODEL_NAMESPACE;
import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_INIT_PARAM_PREFIX;
import java.io.File;
import org.apache.jackrabbit.commons.cnd.CndImporter;
import org.apache.jackrabbit.core.RepositoryContext;
import org.apache.jackrabbit.core.RepositoryImpl;
-import org.argeo.api.DataModelNamespace;
import org.argeo.api.NodeConstants;
import org.argeo.api.NodeDeployment;
import org.argeo.api.security.CryptoKeyring;
import org.argeo.cms.jcr.internal.servlet.CmsRemotingServlet;
import org.argeo.cms.jcr.internal.servlet.CmsWebDavServlet;
import org.argeo.cms.jcr.internal.servlet.JcrHttpUtils;
+import org.argeo.cms.osgi.DataModelNamespace;
import org.argeo.jcr.Jcr;
import org.argeo.jcr.JcrException;
import org.argeo.jcr.JcrUtils;
import javax.security.auth.login.LoginException;
import org.apache.commons.logging.Log;
-import org.argeo.api.DataModelNamespace;
import org.argeo.api.NodeConstants;
import org.argeo.cms.jcr.internal.osgi.CmsJcrActivator;
+import org.argeo.cms.osgi.DataModelNamespace;
import org.osgi.framework.BundleContext;
import org.osgi.util.tracker.ServiceTracker;
import org.apache.commons.logging.LogFactory;
import org.apache.jackrabbit.server.SessionProvider;
import org.argeo.api.NodeConstants;
-import org.argeo.cms.auth.CmsSession;
+import org.argeo.api.cms.CmsSession;
import org.argeo.jcr.JcrUtils;
/**
import org.apache.jackrabbit.core.security.principal.AdminPrincipal;
import org.apache.jackrabbit.core.security.principal.PrincipalProvider;
import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsSession;
import org.argeo.api.security.AnonymousPrincipal;
import org.argeo.api.security.DataAdminPrincipal;
-import org.argeo.cms.auth.CmsSession;
+import org.argeo.cms.osgi.CmsOsgiUtils;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
boolean isRegularUser = !userPrincipal.isEmpty();
CmsSession cmsSession = null;
if (cmsBundleContext != null) {
- cmsSession = CmsSession.getCmsSession(cmsBundleContext, subject);
+ cmsSession = CmsOsgiUtils.getCmsSession(cmsBundleContext, subject);
if (log.isTraceEnabled())
log.trace("Opening JCR session for CMS session " + cmsSession);
}
org.eclipse.jface.window,\
org.eclipse.core.commands.common,\
*
+
+Bundle-ActivationPolicy: lazy
+
\ No newline at end of file
<version>2.3-SNAPSHOT</version>
</dependency>
+ <!-- Specific -->
+ <dependency>
+ <groupId>org.argeo.commons</groupId>
+ <artifactId>org.argeo.swt.specific.rap</artifactId>
+ <version>2.3-SNAPSHOT</version>
+ <scope>provided</scope>
+ </dependency>
<!-- UI -->
<dependency>
<groupId>org.argeo.tp.rap.e4</groupId>
--- /dev/null
+package org.argeo.cms.swt;
+
+import org.argeo.api.cms.CmsTheme;
+import org.eclipse.swt.graphics.Image;
+
+/** Can be applied to {@link Enum}s in order to generated {@link Image}s. */
+public interface CmsIcon {
+ String name();
+
+ default Image getSmallIcon(CmsTheme theme) {
+ return ((CmsSwtTheme) theme).getIcon(name(), getSmallIconSize());
+ }
+
+ default Image getBigIcon(CmsTheme theme) {
+ return ((CmsSwtTheme) theme).getIcon(name(), getBigIconSize());
+ }
+
+ default Integer getSmallIconSize() {
+ return 16;
+ }
+
+ default Integer getBigIconSize() {
+ return 32;
+ }
+}
--- /dev/null
+package org.argeo.cms.swt;
+
+/** Styles references in the CSS. */
+@Deprecated
+public interface CmsStyles {
+ // General
+ public final static String CMS_SHELL = "cms_shell";
+ public final static String CMS_MENU_LINK = "cms_menu_link";
+
+ // Header
+ public final static String CMS_HEADER = "cms_header";
+ public final static String CMS_HEADER_LEAD = "cms_header-lead";
+ public final static String CMS_HEADER_CENTER = "cms_header-center";
+ public final static String CMS_HEADER_END = "cms_header-end";
+
+ public final static String CMS_LEAD = "cms_lead";
+ public final static String CMS_END = "cms_end";
+ public final static String CMS_FOOTER = "cms_footer";
+
+ public final static String CMS_USER_MENU = "cms_user_menu";
+ public final static String CMS_USER_MENU_LINK = "cms_user_menu-link";
+ public final static String CMS_USER_MENU_ITEM = "cms_user_menu-item";
+ public final static String CMS_LOGIN_DIALOG = "cms_login_dialog";
+ public final static String CMS_LOGIN_DIALOG_USERNAME = "cms_login_dialog-username";
+ public final static String CMS_LOGIN_DIALOG_PASSWORD = "cms_login_dialog-password";
+
+ // Body
+ public final static String CMS_SCROLLED_AREA = "cms_scrolled_area";
+ public final static String CMS_BODY = "cms_body";
+ public final static String CMS_STATIC_TEXT = "cms_static-text";
+ public final static String CMS_LINK = "cms_link";
+}
--- /dev/null
+package org.argeo.cms.swt;
+
+import org.argeo.api.cms.CmsTheme;
+import org.eclipse.swt.graphics.Image;
+
+/** SWT specific {@link CmsTheme}. */
+public interface CmsSwtTheme extends CmsTheme {
+ /** The image registered at this path, or <code>null</code> if not found. */
+ Image getImage(String path);
+
+ /**
+ * And icon with this file name (without the extension), with a best effort to
+ * find the appropriate size, or <code>null</code> if not found.
+ *
+ * @param name An icon file name without path and extension.
+ * @param preferredSize the preferred size, if <code>null</code>,
+ * {@link #getDefaultIconSize()} will be tried.
+ */
+ Image getIcon(String name, Integer preferredSize);
+
+}
--- /dev/null
+package org.argeo.cms.swt;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.argeo.api.cms.CmsStyle;
+import org.argeo.api.cms.CmsTheme;
+import org.argeo.api.cms.CmsView;
+import org.argeo.eclipse.ui.specific.EclipseUiSpecificUtils;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.RowData;
+import org.eclipse.swt.layout.RowLayout;
+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;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.Widget;
+
+/** SWT utilities. */
+public class CmsSwtUtils {
+
+ /** Singleton. */
+ private CmsSwtUtils() {
+ }
+
+ public static CmsTheme getCmsTheme(Composite parent) {
+ CmsTheme theme = (CmsTheme) parent.getData(CmsTheme.class.getName());
+ if (theme == null) {
+ // find parent shell
+ Shell topShell = parent.getShell();
+ while (topShell.getParent() != null)
+ topShell = (Shell) topShell.getParent();
+ theme = (CmsTheme) topShell.getData(CmsTheme.class.getName());
+ parent.setData(CmsTheme.class.getName(), theme);
+ }
+ return theme;
+ }
+
+ public static void registerCmsTheme(Shell shell, CmsTheme theme) {
+ // find parent shell
+ Shell topShell = shell;
+ while (topShell.getParent() != null)
+ topShell = (Shell) topShell.getParent();
+ // check if already set
+ if (topShell.getData(CmsTheme.class.getName()) != null) {
+ CmsTheme registeredTheme = (CmsTheme) topShell.getData(CmsTheme.class.getName());
+ throw new IllegalArgumentException(
+ "Theme " + registeredTheme.getThemeId() + " already registered in this shell");
+ }
+ topShell.setData(CmsTheme.class.getName(), theme);
+ }
+
+ public static CmsView getCmsView(Control parent) {
+ // find parent shell
+ Shell topShell = parent.getShell();
+ while (topShell.getParent() != null)
+ topShell = (Shell) topShell.getParent();
+ return (CmsView) topShell.getData(CmsView.class.getName());
+ }
+
+ public static void registerCmsView(Shell shell, CmsView view) {
+ // find parent shell
+ Shell topShell = shell;
+ while (topShell.getParent() != null)
+ topShell = (Shell) topShell.getParent();
+ // check if already set
+ if (topShell.getData(CmsView.class.getName()) != null) {
+ CmsView registeredView = (CmsView) topShell.getData(CmsView.class.getName());
+ throw new IllegalArgumentException("Cms view " + registeredView + " already registered in this shell");
+ }
+ shell.setData(CmsView.class.getName(), view);
+ }
+
+ /** Sends an event via {@link CmsView#sendEvent(String, Map)}. */
+ public static void sendEventOnSelect(Control control, String topic, Map<String, Object> properties) {
+ SelectionListener listener = (Selected) (e) -> {
+ getCmsView(control.getParent()).sendEvent(topic, properties);
+ };
+ if (control instanceof Button) {
+ ((Button) control).addSelectionListener(listener);
+ } else
+ throw new UnsupportedOperationException("Control type " + control.getClass() + " is not supported.");
+ }
+
+ /**
+ * Convenience method to sends an event via
+ * {@link CmsView#sendEvent(String, Map)}.
+ */
+ public static void sendEventOnSelect(Control control, String topic, String key, Object value) {
+ Map<String, Object> properties = new HashMap<>();
+ properties.put(key, value);
+ sendEventOnSelect(control, topic, properties);
+ }
+
+ /*
+ * GRID LAYOUT
+ */
+ public static GridLayout noSpaceGridLayout() {
+ return noSpaceGridLayout(new GridLayout());
+ }
+
+ public static GridLayout noSpaceGridLayout(int columns) {
+ return noSpaceGridLayout(new GridLayout(columns, false));
+ }
+
+ /** @return the same layout, with spaces removed. */
+ public static GridLayout noSpaceGridLayout(GridLayout layout) {
+ layout.horizontalSpacing = 0;
+ layout.verticalSpacing = 0;
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ return layout;
+ }
+
+ public static GridData fillAll() {
+ return new GridData(SWT.FILL, SWT.FILL, true, true);
+ }
+
+ public static GridData fillWidth() {
+ return grabWidth(SWT.FILL, SWT.FILL);
+ }
+
+ public static GridData grabWidth(int horizontalAlignment, int verticalAlignment) {
+ return new GridData(horizontalAlignment, horizontalAlignment, true, false);
+ }
+
+ public static GridData fillHeight() {
+ return grabHeight(SWT.FILL, SWT.FILL);
+ }
+
+ public static GridData grabHeight(int horizontalAlignment, int verticalAlignment) {
+ return new GridData(horizontalAlignment, horizontalAlignment, false, true);
+ }
+
+ /*
+ * ROW LAYOUT
+ */
+ /** @return the same layout, with margins removed. */
+ public static RowLayout noMarginsRowLayout(RowLayout rowLayout) {
+ rowLayout.marginTop = 0;
+ rowLayout.marginBottom = 0;
+ rowLayout.marginLeft = 0;
+ rowLayout.marginRight = 0;
+ return rowLayout;
+ }
+
+ public static RowLayout noMarginsRowLayout(int type) {
+ return noMarginsRowLayout(new RowLayout(type));
+ }
+
+ public static RowData rowData16px() {
+ return new RowData(16, 16);
+ }
+
+ /*
+ * FORM LAYOUT
+ */
+ public static FormData coverAll() {
+ 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);
+ return fdLabel;
+ }
+
+ /*
+ * STYLING
+ */
+
+ /** Style widget */
+ public static <T extends Widget> T style(T widget, String style) {
+ if (style == null)
+ return widget;// does nothing
+ EclipseUiSpecificUtils.setStyleData(widget, style);
+ if (widget instanceof Control) {
+ CmsView cmsView = getCmsView((Control) widget);
+ if (cmsView != null)
+ cmsView.applyStyles(widget);
+ }
+ return widget;
+ }
+
+ /** Style widget */
+ public static <T extends Widget> T style(T widget, CmsStyle style) {
+ return style(widget, style.style());
+ }
+
+ /** Enable markups on widget */
+ public static <T extends Widget> T markup(T widget) {
+ EclipseUiSpecificUtils.setMarkupData(widget);
+ return widget;
+ }
+
+ /** Disable markup validation. */
+ public static <T extends Widget> T disableMarkupValidation(T widget) {
+ EclipseUiSpecificUtils.setMarkupValidationDisabledData(widget);
+ return widget;
+ }
+
+ /**
+ * Apply markup and set text on {@link Label}, {@link Button}, {@link Text}.
+ *
+ * @param widget the widget to style and to use in order to display text
+ * @param txt the object to display via its <code>toString()</code> method.
+ * This argument should not be null, but if it is null and
+ * assertions are disabled "<null>" is displayed instead; if
+ * assertions are enabled the call will fail.
+ *
+ * @see markup
+ */
+ public static <T extends Widget> T text(T widget, Object txt) {
+ assert txt != null;
+ String str = txt != null ? txt.toString() : "<null>";
+ markup(widget);
+ if (widget instanceof Label)
+ ((Label) widget).setText(str);
+ else if (widget instanceof Button)
+ ((Button) widget).setText(str);
+ else if (widget instanceof Text)
+ ((Text) widget).setText(str);
+ else
+ throw new IllegalArgumentException("Unsupported widget type " + widget.getClass());
+ return widget;
+ }
+
+ /** A {@link Label} with markup activated. */
+ public static Label lbl(Composite parent, Object txt) {
+ return text(new Label(parent, SWT.NONE), txt);
+ }
+
+ /** A read-only {@link Text} whose content can be copy/pasted. */
+ public static Text txt(Composite parent, Object txt) {
+ return text(new Text(parent, SWT.NONE), txt);
+ }
+
+ /** Dispose all children of a Composite */
+ public static void clear(Composite composite) {
+ if (composite.isDisposed())
+ return;
+ for (Control child : composite.getChildren())
+ child.dispose();
+ }
+}
--- /dev/null
+package org.argeo.cms.swt;
+
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+
+/**
+ * {@link MouseListener#mouseDoubleClick(MouseEvent)} as a functional interface
+ * in order to use as a short lambda expression in UI code.
+ * {@link MouseListener#mouseDownouseEvent)} and
+ * {@link MouseListener#mouseUp(MouseEvent)} do nothing by default.
+ */
+@FunctionalInterface
+public interface MouseDoubleClick extends MouseListener {
+ @Override
+ void mouseDoubleClick(MouseEvent e);
+
+ @Override
+ default void mouseDown(MouseEvent e) {
+ // does nothing
+ }
+
+ @Override
+ default void mouseUp(MouseEvent e) {
+ // does nothing
+ }
+}
--- /dev/null
+package org.argeo.cms.swt;
+
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+
+/**
+ * {@link MouseListener#mouseDown(MouseEvent)} as a functional interface in
+ * order to use as a short lambda expression in UI code.
+ * {@link MouseListener#mouseDoubleClick(MouseEvent)} and
+ * {@link MouseListener#mouseUp(MouseEvent)} do nothing by default.
+ */
+@FunctionalInterface
+public interface MouseDown extends MouseListener {
+ @Override
+ void mouseDown(MouseEvent e);
+
+ @Override
+ default void mouseDoubleClick(MouseEvent e) {
+ // does nothing
+ }
+
+ @Override
+ default void mouseUp(MouseEvent e) {
+ // does nothing
+ }
+}
--- /dev/null
+package org.argeo.cms.swt;
+
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+
+/**
+ * {@link SelectionListener} as a functional interface in order to use as a
+ * short lambda expression in UI code.
+ * {@link SelectionListener#widgetDefaultSelected(SelectionEvent)} does nothing
+ * by default.
+ */
+@FunctionalInterface
+public interface Selected extends SelectionListener {
+ @Override
+ public void widgetSelected(SelectionEvent e);
+
+ default public void widgetDefaultSelected(SelectionEvent e) {
+ // does nothing
+ }
+
+}
--- /dev/null
+package org.argeo.cms.swt;
+
+import org.argeo.api.cms.UxContext;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Display;
+
+public class SimpleSwtUxContext implements UxContext {
+ private Point size;
+ private Point small = new Point(400, 400);
+
+ public SimpleSwtUxContext() {
+ this(Display.getCurrent().getBounds());
+ }
+
+ public SimpleSwtUxContext(Rectangle rect) {
+ this.size = new Point(rect.width, rect.height);
+ }
+
+ public SimpleSwtUxContext(Point size) {
+ this.size = size;
+ }
+
+ @Override
+ public boolean isPortrait() {
+ return size.x >= size.y;
+ }
+
+ @Override
+ public boolean isLandscape() {
+ return size.x < size.y;
+ }
+
+ @Override
+ public boolean isSquare() {
+ return size.x == size.y;
+ }
+
+ @Override
+ public boolean isSmall() {
+ return size.x <= small.x || size.y <= small.y;
+ }
+
+ @Override
+ public boolean isMasterData() {
+ // TODO make it configurable
+ return true;
+ }
+
+}
--- /dev/null
+package org.argeo.cms.swt.auth;
+
+import static org.argeo.cms.CmsMsg.password;
+import static org.argeo.cms.CmsMsg.username;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Locale;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.LanguageCallback;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+import javax.servlet.http.HttpServletRequest;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.api.NodeConstants;
+import org.argeo.api.NodeState;
+import org.argeo.api.cms.CmsView;
+import org.argeo.cms.CmsMsg;
+import org.argeo.cms.LocaleUtils;
+import org.argeo.cms.auth.HttpRequestCallback;
+import org.argeo.cms.swt.CmsStyles;
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.eclipse.ui.specific.UiContext;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.events.TraverseEvent;
+import org.eclipse.swt.events.TraverseListener;
+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;
+import org.eclipse.swt.widgets.Text;
+
+public class CmsLogin implements CmsStyles, CallbackHandler {
+ private final static Log log = LogFactory.getLog(CmsLogin.class);
+
+ private Composite parent;
+ private Text usernameT, passwordT;
+ private Composite credentialsBlock;
+ private final SelectionListener loginSelectionListener;
+
+ private final Locale defaultLocale;
+ private LocaleChoice localeChoice = null;
+
+ private final CmsView cmsView;
+
+ // optional subject to be set explicitly
+ private Subject subject = null;
+
+ public CmsLogin(CmsView cmsView) {
+ this.cmsView = cmsView;
+ NodeState nodeState = null;// = Activator.getNodeState();
+ if (nodeState != null) {
+ defaultLocale = nodeState.getDefaultLocale();
+ List<Locale> locales = nodeState.getLocales();
+ if (locales != null)
+ localeChoice = new LocaleChoice(locales, defaultLocale);
+ } else {
+ defaultLocale = Locale.getDefault();
+ }
+ loginSelectionListener = new SelectionListener() {
+ private static final long serialVersionUID = -8832133363830973578L;
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ login();
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ }
+ };
+ }
+
+ protected boolean isAnonymous() {
+ return cmsView.isAnonymous();
+ }
+
+ public final void createUi(Composite parent) {
+ this.parent = parent;
+ createContents(parent);
+ }
+
+ protected void createContents(Composite parent) {
+ defaultCreateContents(parent);
+ }
+
+ public final void defaultCreateContents(Composite parent) {
+ parent.setLayout(CmsSwtUtils.noSpaceGridLayout());
+ Composite credentialsBlock = createCredentialsBlock(parent);
+ if (parent instanceof Shell) {
+ credentialsBlock.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true));
+ }
+ }
+
+ public final Composite createCredentialsBlock(Composite parent) {
+ if (isAnonymous()) {
+ return anonymousUi(parent);
+ } else {
+ return userUi(parent);
+ }
+ }
+
+ public Composite getCredentialsBlock() {
+ return credentialsBlock;
+ }
+
+ protected Composite userUi(Composite parent) {
+ Locale locale = localeChoice == null ? this.defaultLocale : localeChoice.getSelectedLocale();
+ credentialsBlock = new Composite(parent, SWT.NONE);
+ credentialsBlock.setLayout(new GridLayout());
+ // credentialsBlock.setLayoutData(CmsUiUtils.fillAll());
+
+ specificUserUi(credentialsBlock);
+
+ Label l = new Label(credentialsBlock, SWT.NONE);
+ CmsSwtUtils.style(l, CMS_USER_MENU_ITEM);
+ l.setText(CmsMsg.logout.lead(locale));
+ GridData lData = CmsSwtUtils.fillWidth();
+ lData.widthHint = 120;
+ l.setLayoutData(lData);
+
+ l.addMouseListener(new MouseAdapter() {
+ private static final long serialVersionUID = 6444395812777413116L;
+
+ public void mouseDown(MouseEvent e) {
+ logout();
+ }
+ });
+ return credentialsBlock;
+ }
+
+ /** To be overridden */
+ protected void specificUserUi(Composite parent) {
+
+ }
+
+ protected Composite anonymousUi(Composite parent) {
+ Locale locale = localeChoice == null ? this.defaultLocale : localeChoice.getSelectedLocale();
+ // We need a composite for the traversal
+ credentialsBlock = new Composite(parent, SWT.NONE);
+ credentialsBlock.setLayout(new GridLayout());
+ // credentialsBlock.setLayoutData(CmsUiUtils.fillAll());
+ CmsSwtUtils.style(credentialsBlock, CMS_LOGIN_DIALOG);
+
+ Integer textWidth = 120;
+ if (parent instanceof Shell)
+ CmsSwtUtils.style(parent, CMS_USER_MENU);
+ // new Label(this, SWT.NONE).setText(CmsMsg.username.lead());
+ usernameT = new Text(credentialsBlock, SWT.BORDER);
+ usernameT.setMessage(username.lead(locale));
+ CmsSwtUtils.style(usernameT, CMS_LOGIN_DIALOG_USERNAME);
+ GridData gd = CmsSwtUtils.fillWidth();
+ gd.widthHint = textWidth;
+ usernameT.setLayoutData(gd);
+
+ // new Label(this, SWT.NONE).setText(CmsMsg.password.lead());
+ passwordT = new Text(credentialsBlock, SWT.BORDER | SWT.PASSWORD);
+ passwordT.setMessage(password.lead(locale));
+ CmsSwtUtils.style(passwordT, CMS_LOGIN_DIALOG_PASSWORD);
+ gd = CmsSwtUtils.fillWidth();
+ gd.widthHint = textWidth;
+ passwordT.setLayoutData(gd);
+
+ TraverseListener tl = new TraverseListener() {
+ private static final long serialVersionUID = -1158892811534971856L;
+
+ public void keyTraversed(TraverseEvent e) {
+ if (e.detail == SWT.TRAVERSE_RETURN)
+ login();
+ }
+ };
+ credentialsBlock.addTraverseListener(tl);
+ usernameT.addTraverseListener(tl);
+ passwordT.addTraverseListener(tl);
+ parent.setTabList(new Control[] { credentialsBlock });
+ credentialsBlock.setTabList(new Control[] { usernameT, passwordT });
+
+ // Button
+ Button loginButton = new Button(credentialsBlock, SWT.PUSH);
+ loginButton.setText(CmsMsg.login.lead(locale));
+ loginButton.setLayoutData(CmsSwtUtils.fillWidth());
+ loginButton.addSelectionListener(loginSelectionListener);
+
+ extendsCredentialsBlock(credentialsBlock, locale, loginSelectionListener);
+ if (localeChoice != null)
+ createLocalesBlock(credentialsBlock);
+ return credentialsBlock;
+ }
+
+ /**
+ * To be overridden in order to provide custom login button and other links.
+ */
+ protected void extendsCredentialsBlock(Composite credentialsBlock, Locale selectedLocale,
+ SelectionListener loginSelectionListener) {
+
+ }
+
+ protected void updateLocale(Locale selectedLocale) {
+ // save already entered values
+ String usernameStr = usernameT.getText();
+ char[] pwd = passwordT.getTextChars();
+
+ for (Control child : parent.getChildren())
+ child.dispose();
+ createContents(parent);
+ if (parent.getParent() != null)
+ parent.getParent().layout(true, true);
+ else
+ parent.layout();
+ usernameT.setText(usernameStr);
+ passwordT.setTextChars(pwd);
+ }
+
+ protected Composite createLocalesBlock(final Composite parent) {
+ Composite c = new Composite(parent, SWT.NONE);
+ CmsSwtUtils.style(c, CMS_USER_MENU_ITEM);
+ c.setLayout(CmsSwtUtils.noSpaceGridLayout());
+ c.setLayoutData(CmsSwtUtils.fillAll());
+
+ SelectionListener selectionListener = new SelectionAdapter() {
+ private static final long serialVersionUID = 4891637813567806762L;
+
+ public void widgetSelected(SelectionEvent event) {
+ Button button = (Button) event.widget;
+ if (button.getSelection()) {
+ localeChoice.setSelectedIndex((Integer) event.widget.getData());
+ updateLocale(localeChoice.getSelectedLocale());
+ }
+ };
+ };
+
+ List<Locale> locales = localeChoice.getLocales();
+ for (Integer i = 0; i < locales.size(); i++) {
+ Locale locale = locales.get(i);
+ Button button = new Button(c, SWT.RADIO);
+ CmsSwtUtils.style(button, CMS_USER_MENU_ITEM);
+ button.setData(i);
+ button.setText(LocaleUtils.toLead(locale.getDisplayName(locale), locale) + " (" + locale + ")");
+ // button.addListener(SWT.Selection, listener);
+ button.addSelectionListener(selectionListener);
+ if (i == localeChoice.getSelectedIndex())
+ button.setSelection(true);
+ }
+ return c;
+ }
+
+ protected boolean login() {
+ // TODO use CmsVie in order to retrieve subject?
+ // Subject subject = cmsView.getLoginContext().getSubject();
+ // LoginContext loginContext = cmsView.getLoginContext();
+ try {
+ //
+ // LOGIN
+ //
+ // loginContext.logout();
+ LoginContext loginContext;
+ if (subject == null)
+ loginContext = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, this);
+ else
+ loginContext = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, subject, this);
+ loginContext.login();
+ cmsView.authChange(loginContext);
+ return true;
+ } catch (LoginException e) {
+ if (log.isTraceEnabled())
+ log.warn("Login failed: " + e.getMessage(), e);
+ else
+ log.warn("Login failed: " + e.getMessage());
+
+ try {
+ Thread.sleep(3000);
+ } catch (InterruptedException e2) {
+ // silent
+ }
+ // ErrorFeedback.show("Login failed", e);
+ return false;
+ }
+ // catch (LoginException e) {
+ // log.error("Cannot login", e);
+ // return false;
+ // }
+ }
+
+ protected void logout() {
+ cmsView.logout();
+ cmsView.navigateTo("~");
+ }
+
+ @Override
+ public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
+ for (Callback callback : callbacks) {
+ if (callback instanceof NameCallback && usernameT != null)
+ ((NameCallback) callback).setName(usernameT.getText());
+ else if (callback instanceof PasswordCallback && passwordT != null)
+ ((PasswordCallback) callback).setPassword(passwordT.getTextChars());
+ else if (callback instanceof HttpRequestCallback) {
+ ((HttpRequestCallback) callback).setRequest(UiContext.getHttpRequest());
+ ((HttpRequestCallback) callback).setResponse(UiContext.getHttpResponse());
+ } else if (callback instanceof LanguageCallback) {
+ Locale toUse = null;
+ if (localeChoice != null)
+ toUse = localeChoice.getSelectedLocale();
+ else if (defaultLocale != null)
+ toUse = defaultLocale;
+
+ if (toUse != null) {
+ ((LanguageCallback) callback).setLocale(toUse);
+ UiContext.setLocale(toUse);
+ }
+
+ }
+ }
+ }
+
+ public void setSubject(Subject subject) {
+ this.subject = subject;
+ }
+
+}
--- /dev/null
+package org.argeo.cms.swt.auth;
+
+import org.argeo.api.cms.CmsView;
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+/** The site-related user menu */
+public class CmsLoginShell extends CmsLogin {
+ private final Shell shell;
+
+ public CmsLoginShell(CmsView cmsView) {
+ super(cmsView);
+ shell = createShell();
+// createUi(shell);
+ }
+
+ /** To be overridden. */
+ protected Shell createShell() {
+ Shell shell = new Shell(Display.getCurrent(), SWT.NO_TRIM);
+ shell.setMaximized(true);
+ return shell;
+ }
+
+ /** To be overridden. */
+ public void open() {
+ CmsSwtUtils.style(shell, CMS_USER_MENU);
+ shell.open();
+ }
+
+ @Override
+ protected boolean login() {
+ boolean success = false;
+ try {
+ success = super.login();
+ return success;
+ } finally {
+ if (success)
+ closeShell();
+ else {
+ for (Control child : shell.getChildren())
+ child.dispose();
+ createUi(shell);
+ shell.layout();
+ // TODO error message
+ }
+ }
+ }
+
+ @Override
+ protected void logout() {
+ closeShell();
+ super.logout();
+ }
+
+ protected void closeShell() {
+ if (!shell.isDisposed()) {
+ shell.close();
+ shell.dispose();
+ }
+ }
+
+ public Shell getShell() {
+ return shell;
+ }
+
+ public void createUi(){
+ createUi(shell);
+ }
+}
--- /dev/null
+package org.argeo.cms.swt.auth;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.TextOutputCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * A composite that can populate itself based on {@link Callback}s. It can be
+ * used directly as a {@link CallbackHandler} or be used by one by calling the
+ * {@link #createCallbackHandlers(Callback[])}. Supported standard
+ * {@link Callback}s are:<br>
+ * <ul>
+ * <li>{@link PasswordCallback}</li>
+ * <li>{@link NameCallback}</li>
+ * <li>{@link TextOutputCallback}</li>
+ * </ul>
+ * Supported Argeo {@link Callback}s are:<br>
+ * <ul>
+ * <li>{@link LocaleChoice}</li>
+ * </ul>
+ */
+public class CompositeCallbackHandler extends Composite implements CallbackHandler {
+ private static final long serialVersionUID = -928223893722723777L;
+
+ private boolean wasUsedAlready = false;
+ private boolean isSubmitted = false;
+ private boolean isCanceled = false;
+
+ public CompositeCallbackHandler(Composite parent, int style) {
+ super(parent, style);
+ }
+
+ @Override
+ public synchronized void handle(final Callback[] callbacks) throws IOException, UnsupportedCallbackException {
+ // reset
+ if (wasUsedAlready && !isSubmitted() && !isCanceled()) {
+ cancel();
+ for (Control control : getChildren())
+ control.dispose();
+ isSubmitted = false;
+ isCanceled = false;
+ }
+
+ for (Callback callback : callbacks)
+ checkCallbackSupported(callback);
+ // create controls synchronously in the UI thread
+ getDisplay().syncExec(new Runnable() {
+
+ @Override
+ public void run() {
+ createCallbackHandlers(callbacks);
+ }
+ });
+
+ if (!wasUsedAlready)
+ wasUsedAlready = true;
+
+ // while (!isSubmitted() && !isCanceled()) {
+ // try {
+ // wait(1000l);
+ // } catch (InterruptedException e) {
+ // // silent
+ // }
+ // }
+
+ // cleanCallbacksAfterCancel(callbacks);
+ }
+
+ public void checkCallbackSupported(Callback callback) throws UnsupportedCallbackException {
+ if (callback instanceof TextOutputCallback || callback instanceof NameCallback
+ || callback instanceof PasswordCallback || callback instanceof LocaleChoice) {
+ return;
+ } else {
+ throw new UnsupportedCallbackException(callback);
+ }
+ }
+
+ /**
+ * Set writable callbacks to null if the handle is canceled (check is done
+ * by the method)
+ */
+ public void cleanCallbacksAfterCancel(Callback[] callbacks) {
+ if (isCanceled()) {
+ for (Callback callback : callbacks) {
+ if (callback instanceof NameCallback) {
+ ((NameCallback) callback).setName(null);
+ } else if (callback instanceof PasswordCallback) {
+ PasswordCallback pCallback = (PasswordCallback) callback;
+ char[] arr = pCallback.getPassword();
+ if (arr != null) {
+ Arrays.fill(arr, '*');
+ pCallback.setPassword(null);
+ }
+ }
+ }
+ }
+ }
+
+ public void createCallbackHandlers(Callback[] callbacks) {
+ Composite composite = this;
+ for (int i = 0; i < callbacks.length; i++) {
+ Callback callback = callbacks[i];
+ if (callback instanceof TextOutputCallback) {
+ createLabelTextoutputHandler(composite, (TextOutputCallback) callback);
+ } else if (callback instanceof NameCallback) {
+ createNameHandler(composite, (NameCallback) callback);
+ } else if (callback instanceof PasswordCallback) {
+ createPasswordHandler(composite, (PasswordCallback) callback);
+ } else if (callback instanceof LocaleChoice) {
+ createLocaleHandler(composite, (LocaleChoice) callback);
+ }
+ }
+ }
+
+ protected Text createNameHandler(Composite composite, final NameCallback callback) {
+ Label label = new Label(composite, SWT.NONE);
+ label.setText(callback.getPrompt());
+ final Text text = new Text(composite, SWT.SINGLE | SWT.LEAD | SWT.BORDER);
+ if (callback.getDefaultName() != null) {
+ // set default value, if provided
+ text.setText(callback.getDefaultName());
+ callback.setName(callback.getDefaultName());
+ }
+ text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ text.addModifyListener(new ModifyListener() {
+ private static final long serialVersionUID = 7300032545287292973L;
+
+ public void modifyText(ModifyEvent event) {
+ callback.setName(text.getText());
+ }
+ });
+ text.addSelectionListener(new SelectionListener() {
+ private static final long serialVersionUID = 1820530045857665111L;
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ submit();
+ }
+ });
+
+ text.addKeyListener(new KeyListener() {
+ private static final long serialVersionUID = -8698107785092095713L;
+
+ @Override
+ public void keyReleased(KeyEvent e) {
+ }
+
+ @Override
+ public void keyPressed(KeyEvent e) {
+ }
+ });
+ return text;
+ }
+
+ protected Text createPasswordHandler(Composite composite, final PasswordCallback callback) {
+ Label label = new Label(composite, SWT.NONE);
+ label.setText(callback.getPrompt());
+ final Text passwordText = new Text(composite, SWT.SINGLE | SWT.LEAD | SWT.PASSWORD | SWT.BORDER);
+ passwordText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ passwordText.addModifyListener(new ModifyListener() {
+ private static final long serialVersionUID = -7099363995047686732L;
+
+ public void modifyText(ModifyEvent event) {
+ callback.setPassword(passwordText.getTextChars());
+ }
+ });
+ passwordText.addSelectionListener(new SelectionListener() {
+ private static final long serialVersionUID = 1820530045857665111L;
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ submit();
+ }
+ });
+ return passwordText;
+ }
+
+ protected Combo createLocaleHandler(Composite composite, final LocaleChoice callback) {
+ String[] labels = callback.getSupportedLocalesLabels();
+ if (labels.length == 0)
+ return null;
+ Label label = new Label(composite, SWT.NONE);
+ label.setText("Language");
+
+ final Combo combo = new Combo(composite, SWT.READ_ONLY);
+ combo.setItems(labels);
+ combo.select(callback.getDefaultIndex());
+ combo.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ combo.addSelectionListener(new SelectionListener() {
+ private static final long serialVersionUID = 38678989091946277L;
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ callback.setSelectedIndex(combo.getSelectionIndex());
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ }
+ });
+ return combo;
+ }
+
+ protected Label createLabelTextoutputHandler(Composite composite, final TextOutputCallback callback) {
+ Label label = new Label(composite, SWT.NONE);
+ label.setText(callback.getMessage());
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
+ data.horizontalSpan = 2;
+ label.setLayoutData(data);
+ return label;
+ // TODO: find a way to pass this information
+ // int messageType = callback.getMessageType();
+ // int dialogMessageType = IMessageProvider.NONE;
+ // switch (messageType) {
+ // case TextOutputCallback.INFORMATION:
+ // dialogMessageType = IMessageProvider.INFORMATION;
+ // break;
+ // case TextOutputCallback.WARNING:
+ // dialogMessageType = IMessageProvider.WARNING;
+ // break;
+ // case TextOutputCallback.ERROR:
+ // dialogMessageType = IMessageProvider.ERROR;
+ // break;
+ // }
+ // setMessage(callback.getMessage(), dialogMessageType);
+ }
+
+ synchronized boolean isSubmitted() {
+ return isSubmitted;
+ }
+
+ synchronized boolean isCanceled() {
+ return isCanceled;
+ }
+
+ protected synchronized void submit() {
+ isSubmitted = true;
+ notifyAll();
+ }
+
+ protected synchronized void cancel() {
+ isCanceled = true;
+ notifyAll();
+ }
+}
--- /dev/null
+package org.argeo.cms.swt.auth;
+
+import java.io.IOException;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+import org.argeo.eclipse.ui.dialogs.LightweightDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+public class DynamicCallbackHandler implements CallbackHandler {
+
+ @Override
+ public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
+ Shell activeShell = Display.getCurrent().getActiveShell();
+ LightweightDialog dialog = new LightweightDialog(activeShell) {
+
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ CompositeCallbackHandler cch = new CompositeCallbackHandler(parent, SWT.NONE);
+ cch.createCallbackHandlers(callbacks);
+ return cch;
+ }
+ };
+ dialog.setBlockOnOpen(true);
+ dialog.open();
+ }
+
+}
--- /dev/null
+package org.argeo.cms.swt.auth;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+
+import javax.security.auth.callback.LanguageCallback;
+
+import org.argeo.cms.CmsException;
+import org.argeo.cms.LocaleUtils;
+
+/** Choose in a list of locales. TODO: replace with {@link LanguageCallback} */
+public class LocaleChoice {
+ private final List<Locale> locales;
+
+ private Integer selectedIndex = null;
+ private final Integer defaultIndex;
+
+ public LocaleChoice(List<Locale> locales, Locale defaultLocale) {
+ Integer defaultIndex = null;
+ this.locales = Collections.unmodifiableList(locales);
+ for (int i = 0; i < locales.size(); i++)
+ if (locales.get(i).equals(defaultLocale))
+ defaultIndex = i;
+
+ // based on language only
+ if (defaultIndex == null)
+ for (int i = 0; i < locales.size(); i++)
+ if (locales.get(i).getLanguage().equals(defaultLocale.getLanguage()))
+ defaultIndex = i;
+
+ if (defaultIndex == null)
+ throw new CmsException("Default locale " + defaultLocale + " is not in available locales " + locales);
+ this.defaultIndex = defaultIndex;
+
+ this.selectedIndex = defaultIndex;
+ }
+
+ /**
+ * Convenience constructor based on a comma separated list of iso codes (en,
+ * en_US, fr_CA, etc.). Default selection is default locale.
+ */
+ public LocaleChoice(String locales, Locale defaultLocale) {
+ this(LocaleUtils.asLocaleList(locales), defaultLocale);
+ }
+
+ public String[] getSupportedLocalesLabels() {
+ String[] labels = new String[locales.size()];
+ for (int i = 0; i < locales.size(); i++) {
+ Locale locale = locales.get(i);
+ if (locale.getCountry().equals(""))
+ labels[i] = locale.getDisplayLanguage(locale) + " [" + locale.getLanguage() + "]";
+ else
+ labels[i] = locale.getDisplayLanguage(locale) + " (" + locale.getDisplayCountry(locale) + ") ["
+ + locale.getLanguage() + "_" + locale.getCountry() + "]";
+
+ }
+ return labels;
+ }
+
+ public Locale getSelectedLocale() {
+ if (selectedIndex == null)
+ return null;
+ return locales.get(selectedIndex);
+ }
+
+ public void setSelectedIndex(Integer selectedIndex) {
+ this.selectedIndex = selectedIndex;
+ }
+
+ public Integer getSelectedIndex() {
+ return selectedIndex;
+ }
+
+ public Integer getDefaultIndex() {
+ return defaultIndex;
+ }
+
+ public List<Locale> getLocales() {
+ return locales;
+ }
+
+ public Locale getDefaultLocale() {
+ return locales.get(getDefaultIndex());
+ }
+}
--- /dev/null
+/** Argeo CMS authentication widgets, based on SWT. */
+package org.argeo.cms.swt.auth;
\ No newline at end of file
--- /dev/null
+package org.argeo.cms.swt.dialogs;
+
+import java.security.PrivilegedAction;
+import java.util.Arrays;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsView;
+import org.argeo.cms.CmsMsg;
+import org.argeo.cms.CmsUserManager;
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/** Dialog to change a password. */
+public class ChangePasswordDialog extends CmsMessageDialog {
+ private final static Log log = LogFactory.getLog(ChangePasswordDialog.class);
+
+ private CmsUserManager cmsUserManager;
+ private CmsView cmsView;
+
+ private PrivilegedAction<Integer> doIt;
+
+ public ChangePasswordDialog(Shell parentShell, String message, int kind, CmsUserManager cmsUserManager) {
+ super(parentShell, message, kind);
+ this.cmsUserManager = cmsUserManager;
+ cmsView = CmsSwtUtils.getCmsView(parentShell);
+ }
+
+ @Override
+ protected Control createInputArea(Composite userSection) {
+ addFormLabel(userSection, CmsMsg.currentPassword.lead());
+ Text previousPassword = new Text(userSection, SWT.BORDER | SWT.PASSWORD);
+ previousPassword.setLayoutData(CmsSwtUtils.fillWidth());
+ addFormLabel(userSection, CmsMsg.newPassword.lead());
+ Text newPassword = new Text(userSection, SWT.BORDER | SWT.PASSWORD);
+ newPassword.setLayoutData(CmsSwtUtils.fillWidth());
+ addFormLabel(userSection, CmsMsg.repeatNewPassword.lead());
+ Text confirmPassword = new Text(userSection, SWT.BORDER | SWT.PASSWORD);
+ confirmPassword.setLayoutData(CmsSwtUtils.fillWidth());
+
+ doIt = () -> {
+ if (Arrays.equals(newPassword.getTextChars(), confirmPassword.getTextChars())) {
+ try {
+ cmsUserManager.changeOwnPassword(previousPassword.getTextChars(), newPassword.getTextChars());
+ return OK;
+ } catch (Exception e1) {
+ log.error("Could not change password", e1);
+ cancel();
+ CmsMessageDialog.openError(CmsMsg.invalidPassword.lead());
+ return CANCEL;
+ }
+ } else {
+ cancel();
+ CmsMessageDialog.openError(CmsMsg.repeatNewPassword.lead());
+ return CANCEL;
+ }
+ };
+
+ pack();
+ return previousPassword;
+ }
+
+ @Override
+ protected void okPressed() {
+ Integer returnCode = cmsView.doAs(doIt);
+ if (returnCode.equals(OK)) {
+ super.okPressed();
+ CmsMessageDialog.openInformation(CmsMsg.passwordChanged.lead());
+ }
+ }
+
+ private static Label addFormLabel(Composite parent, String label) {
+ Label lbl = new Label(parent, SWT.WRAP);
+ lbl.setText(label);
+// CmsUiUtils.style(lbl, SuiteStyle.simpleLabel);
+ return lbl;
+ }
+
+}
--- /dev/null
+package org.argeo.cms.swt.dialogs;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.cms.CmsMsg;
+import org.argeo.cms.swt.Selected;
+import org.eclipse.swt.SWT;
+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;
+import org.eclipse.swt.widgets.Text;
+
+/** A dialog feedback based on a {@link LightweightDialog}. */
+public class CmsFeedback extends LightweightDialog {
+ private final static Log log = LogFactory.getLog(CmsFeedback.class);
+
+ private String message;
+ private Throwable exception;
+
+ public CmsFeedback(Shell parentShell, String message, Throwable e) {
+ super(parentShell);
+ this.message = message;
+ this.exception = e;
+ log.error(message, e);
+ }
+
+ public static CmsFeedback show(String message, Throwable e) {
+ // rethrow ThreaDeath in order to make sure that RAP will properly clean
+ // up the UI thread
+ if (e instanceof ThreadDeath)
+ throw (ThreadDeath) e;
+
+ try {
+ CmsFeedback cmsFeedback = new CmsFeedback(null, message, e);
+ cmsFeedback.setBlockOnOpen(false);
+ cmsFeedback.open();
+ return cmsFeedback;
+ } catch (Throwable e1) {
+ log.error("Cannot open error feedback (" + e.getMessage() + "), original error below", e);
+ return null;
+ }
+ }
+
+ public static CmsFeedback show(String message) {
+ CmsFeedback cmsFeedback = new CmsFeedback(null, message, null);
+ cmsFeedback.open();
+ return cmsFeedback;
+ }
+
+ /** Tries to find a display */
+ // private static Display getDisplay() {
+ // try {
+ // Display display = Display.getCurrent();
+ // if (display != null)
+ // return display;
+ // else
+ // return Display.getDefault();
+ // } catch (Exception e) {
+ // return Display.getCurrent();
+ // }
+ // }
+
+ protected Control createDialogArea(Composite parent) {
+ parent.setLayout(new GridLayout(2, false));
+
+ Label messageLbl = new Label(parent, SWT.WRAP);
+ if (message != null)
+ messageLbl.setText(message);
+ else if (exception != null)
+ messageLbl.setText(exception.getLocalizedMessage());
+
+ Button close = new Button(parent, SWT.FLAT);
+ close.setText(CmsMsg.close.lead());
+ close.setLayoutData(new GridData(SWT.END, SWT.TOP, false, false));
+ close.addSelectionListener((Selected) (e) -> closeShell(OK));
+
+ // Composite composite = new Composite(dialogarea, SWT.NONE);
+ // composite.setLayout(new GridLayout(2, false));
+ // composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ if (exception != null) {
+ Text stack = new Text(parent, SWT.MULTI | SWT.LEAD | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
+ stack.setEditable(false);
+ stack.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
+ StringWriter sw = new StringWriter();
+ exception.printStackTrace(new PrintWriter(sw));
+ stack.setText(sw.toString());
+ }
+
+ // parent.pack();
+ return messageLbl;
+ }
+
+}
--- /dev/null
+package org.argeo.cms.swt.dialogs;
+
+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.swt.SWT;
+import org.eclipse.swt.events.TraverseEvent;
+import org.eclipse.swt.events.TraverseListener;
+import org.eclipse.swt.graphics.Point;
+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.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+
+/** Base class for dialogs displaying messages or small forms. */
+public class CmsMessageDialog extends LightweightDialog {
+ public final static int NONE = 0;
+ public final static int ERROR = 1;
+ public final static int INFORMATION = 2;
+ public final static int QUESTION = 3;
+ public final static int WARNING = 4;
+ public final static int CONFIRM = 5;
+ public final static int QUESTION_WITH_CANCEL = 6;
+
+ private int kind;
+ private String message;
+
+ public CmsMessageDialog(Shell parentShell, String message, int kind) {
+ super(parentShell);
+ this.kind = kind;
+ this.message = message;
+ }
+
+ protected Control createDialogArea(Composite parent) {
+ parent.setLayout(new GridLayout());
+
+ TraverseListener traverseListener = new TraverseListener() {
+ private static final long serialVersionUID = -1158892811534971856L;
+
+ public void keyTraversed(TraverseEvent e) {
+ if (e.detail == SWT.TRAVERSE_RETURN)
+ okPressed();
+ else if (e.detail == SWT.TRAVERSE_ESCAPE)
+ cancelPressed();
+ }
+ };
+
+ // message
+ Composite body = new Composite(parent, SWT.NONE);
+ body.addTraverseListener(traverseListener);
+ GridLayout bodyGridLayout = new GridLayout();
+ bodyGridLayout.marginHeight = 20;
+ bodyGridLayout.marginWidth = 20;
+ body.setLayout(bodyGridLayout);
+ body.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ if (message != null) {
+ Label messageLbl = new Label(body, SWT.WRAP);
+ CmsSwtUtils.markup(messageLbl);
+ messageLbl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ messageLbl.setFont(EclipseUiUtils.getBoldFont(parent));
+ messageLbl.setText(message);
+ }
+
+ // buttons
+ Composite buttons = new Composite(parent, SWT.NONE);
+ buttons.addTraverseListener(traverseListener);
+ buttons.setLayoutData(new GridData(SWT.END, SWT.FILL, true, false));
+ if (kind == INFORMATION || kind == WARNING || kind == ERROR || kind == ERROR) {
+ GridLayout layout = new GridLayout(1, true);
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ buttons.setLayout(layout);
+
+ Button close = new Button(buttons, SWT.FLAT);
+ close.setText(CmsMsg.close.lead());
+ close.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
+ close.addSelectionListener((Selected) (e) -> closeShell(OK));
+ close.setFocus();
+ close.addTraverseListener(traverseListener);
+
+ buttons.setTabList(new Control[] { close });
+ } else if (kind == CONFIRM || kind == QUESTION || kind == QUESTION_WITH_CANCEL) {
+ Control input = createInputArea(body);
+ if (input != null) {
+ input.addTraverseListener(traverseListener);
+ body.setTabList(new Control[] { input });
+ }
+ GridLayout layout = new GridLayout(2, true);
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ buttons.setLayout(layout);
+
+ Button cancel = new Button(buttons, SWT.FLAT);
+ cancel.setText(CmsMsg.cancel.lead());
+ cancel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
+ cancel.addSelectionListener((Selected) (e) -> cancelPressed());
+ cancel.addTraverseListener(traverseListener);
+
+ Button ok = new Button(buttons, SWT.FLAT);
+ ok.setText(CmsMsg.ok.lead());
+ ok.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
+ ok.addSelectionListener((Selected) (e) -> okPressed());
+ ok.addTraverseListener(traverseListener);
+ if (input == null)
+ ok.setFocus();
+ else
+ input.setFocus();
+
+ buttons.setTabList(new Control[] { ok, cancel });
+ }
+ // pack();
+ parent.setTabList(new Control[] { body, buttons });
+ return body;
+ }
+
+ protected Control createInputArea(Composite parent) {
+ return null;
+ }
+
+ protected void okPressed() {
+ closeShell(OK);
+ }
+
+ protected void cancelPressed() {
+ closeShell(CANCEL);
+ }
+
+ protected void cancel() {
+ closeShell(CANCEL);
+ }
+
+ protected Point getInitialSize() {
+ return new Point(400, 200);
+ }
+
+ public static boolean open(int kind, Shell parent, String message) {
+ CmsMessageDialog dialog = new CmsMessageDialog(parent, message, kind);
+ return dialog.open() == 0;
+ }
+
+ public static boolean openConfirm(String message) {
+ return open(CONFIRM, Display.getCurrent().getActiveShell(), message);
+ }
+
+ public static void openInformation(String message) {
+ open(INFORMATION, Display.getCurrent().getActiveShell(), message);
+ }
+
+ public static boolean openQuestion(String message) {
+ return open(QUESTION, Display.getCurrent().getActiveShell(), message);
+ }
+
+ public static void openWarning(String message) {
+ open(WARNING, Display.getCurrent().getActiveShell(), message);
+ }
+
+ public static void openError(String message) {
+ open(ERROR, Display.getCurrent().getActiveShell(), message);
+ }
+
+}
--- /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 {
+ 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.dialogs;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.eclipse.ui.EclipseUiException;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.ShellAdapter;
+import org.eclipse.swt.events.ShellEvent;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+/** Generic lightweight dialog, not based on JFace. */
+public class LightweightDialog {
+ private final static Log log = LogFactory.getLog(LightweightDialog.class);
+
+ // must be the same value as org.eclipse.jface.window.Window#OK
+ public final static int OK = 0;
+ // must be the same value as org.eclipse.jface.window.Window#CANCEL
+ public final static int CANCEL = 1;
+
+ private Shell parentShell;
+ private Shell backgroundShell;
+ private Shell foregoundShell;
+
+ private Integer returnCode = null;
+ private boolean block = true;
+
+ private String title;
+
+ /** Tries to find a display */
+ private static Display getDisplay() {
+ try {
+ Display display = Display.getCurrent();
+ if (display != null)
+ return display;
+ else
+ return Display.getDefault();
+ } catch (Exception e) {
+ return Display.getCurrent();
+ }
+ }
+
+ public LightweightDialog(Shell parentShell) {
+ this.parentShell = parentShell;
+ }
+
+ public int open() {
+ if (foregoundShell != null)
+ throw new EclipseUiException("There is already a shell");
+ backgroundShell = new Shell(parentShell, SWT.ON_TOP);
+ backgroundShell.setFullScreen(true);
+ // if (parentShell != null) {
+ // backgroundShell.setBounds(parentShell.getBounds());
+ // } else
+ // backgroundShell.setMaximized(true);
+ backgroundShell.setAlpha(128);
+ backgroundShell.setBackground(getDisplay().getSystemColor(SWT.COLOR_BLACK));
+ foregoundShell = new Shell(backgroundShell, SWT.NO_TRIM | SWT.ON_TOP);
+ if (title != null)
+ setTitle(title);
+ foregoundShell.setLayout(new GridLayout());
+ foregoundShell.setSize(getInitialSize());
+ createDialogArea(foregoundShell);
+ // shell.pack();
+ // shell.layout();
+
+ Rectangle shellBounds = parentShell != null ? parentShell.getBounds() : Display.getCurrent().getBounds();// RAP
+ Point dialogSize = foregoundShell.getSize();
+ int x = shellBounds.x + (shellBounds.width - dialogSize.x) / 2;
+ int y = shellBounds.y + (shellBounds.height - dialogSize.y) / 2;
+ foregoundShell.setLocation(x, y);
+
+ foregoundShell.addShellListener(new ShellAdapter() {
+ private static final long serialVersionUID = -2701270481953688763L;
+
+ @Override
+ public void shellDeactivated(ShellEvent e) {
+ if (hasChildShells())
+ return;
+ if (returnCode == null)// not yet closed
+ closeShell(CANCEL);
+ }
+
+ @Override
+ public void shellClosed(ShellEvent e) {
+ notifyClose();
+ }
+
+ });
+
+ backgroundShell.open();
+ foregoundShell.open();
+ // after the foreground shell has been opened
+ backgroundShell.addFocusListener(new FocusListener() {
+ private static final long serialVersionUID = 3137408447474661070L;
+
+ @Override
+ public void focusLost(FocusEvent event) {
+ }
+
+ @Override
+ public void focusGained(FocusEvent event) {
+ if (hasChildShells())
+ return;
+ if (returnCode == null)// not yet closed
+ closeShell(CANCEL);
+ }
+ });
+
+ if (block) {
+ block();
+ }
+ if (returnCode == null)
+ returnCode = OK;
+ return returnCode;
+ }
+
+ public void block() {
+ try {
+ runEventLoop(foregoundShell);
+ } catch (ThreadDeath t) {
+ returnCode = CANCEL;
+ if (log.isTraceEnabled())
+ log.error("Thread death, canceling dialog", t);
+ } catch (Throwable t) {
+ returnCode = CANCEL;
+ log.error("Cannot open blocking lightweight dialog", t);
+ }
+ }
+
+ private boolean hasChildShells() {
+ if (foregoundShell == null)
+ return false;
+ return foregoundShell.getShells().length != 0;
+ }
+
+ // public synchronized int openAndWait() {
+ // open();
+ // while (returnCode == null)
+ // try {
+ // wait(100);
+ // } catch (InterruptedException e) {
+ // // silent
+ // }
+ // return returnCode;
+ // }
+
+ private synchronized void notifyClose() {
+ if (returnCode == null)
+ returnCode = CANCEL;
+ notifyAll();
+ }
+
+ protected void closeShell(int returnCode) {
+ this.returnCode = returnCode;
+ if (CANCEL == returnCode)
+ onCancel();
+ if (foregoundShell != null && !foregoundShell.isDisposed()) {
+ foregoundShell.close();
+ foregoundShell.dispose();
+ foregoundShell = null;
+ }
+
+ if (backgroundShell != null && !backgroundShell.isDisposed()) {
+ backgroundShell.close();
+ backgroundShell.dispose();
+ }
+ }
+
+ protected Point getInitialSize() {
+ // if (exception != null)
+ // return new Point(800, 600);
+ // else
+ return new Point(600, 400);
+ }
+
+ protected Control createDialogArea(Composite parent) {
+ Composite dialogarea = new Composite(parent, SWT.NONE);
+ dialogarea.setLayout(new GridLayout());
+ dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ return dialogarea;
+ }
+
+ protected Shell getBackgroundShell() {
+ return backgroundShell;
+ }
+
+ protected Shell getForegoundShell() {
+ return foregoundShell;
+ }
+
+ public void setBlockOnOpen(boolean shouldBlock) {
+ block = shouldBlock;
+ }
+
+ public void pack() {
+ foregoundShell.pack();
+ }
+
+ private void runEventLoop(Shell loopShell) {
+ Display display;
+ if (foregoundShell == null) {
+ display = Display.getCurrent();
+ } else {
+ display = loopShell.getDisplay();
+ }
+
+ while (loopShell != null && !loopShell.isDisposed()) {
+ try {
+ if (!display.readAndDispatch()) {
+ display.sleep();
+ }
+ } catch (UnsupportedOperationException e) {
+ throw e;
+ } catch (Throwable e) {
+ handleException(e);
+ }
+ }
+ if (!display.isDisposed())
+ display.update();
+ }
+
+ protected void handleException(Throwable t) {
+ if (t instanceof ThreadDeath) {
+ // Don't catch ThreadDeath as this is a normal occurrence when
+ // the thread dies
+ throw (ThreadDeath) t;
+ }
+ // Try to keep running.
+ t.printStackTrace();
+ }
+
+ /** @return false, if the dialog should not be closed. */
+ protected boolean onCancel() {
+ return true;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ if (title != null && getForegoundShell() != null)
+ getForegoundShell().setText(title);
+ }
+
+ public Integer getReturnCode() {
+ return returnCode;
+ }
+
+}
\ No newline at end of file
--- /dev/null
+package org.argeo.cms.swt.dialogs;
+
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/** A dialog asking a for a single value. */
+public class SingleValueDialog extends CmsMessageDialog {
+ private Text valueT;
+ private String value;
+ private String defaultValue;
+
+ public SingleValueDialog(Shell parentShell, String message) {
+ super(parentShell, message, QUESTION);
+ }
+
+ public SingleValueDialog(Shell parentShell, String message, String defaultValue) {
+ super(parentShell, message, QUESTION);
+ this.defaultValue = defaultValue;
+ }
+
+ @Override
+ protected Control createInputArea(Composite parent) {
+ valueT = new Text(parent, SWT.LEAD | SWT.BORDER | SWT.SINGLE);
+ valueT.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true));
+ if (defaultValue != null)
+ valueT.setText(defaultValue);
+ return valueT;
+ }
+
+ @Override
+ protected void okPressed() {
+ value = valueT.getText();
+ super.okPressed();
+ }
+
+ public String getString() {
+ return value;
+ }
+
+ public Long getLong() {
+ return Long.valueOf(getString());
+ }
+
+ public Double getDouble() {
+ return Double.valueOf(getString());
+ }
+
+ public static String ask(String message) {
+ return ask(message, null);
+ }
+
+ public static String ask(String message, String defaultValue) {
+ SingleValueDialog svd = new SingleValueDialog(Display.getCurrent().getActiveShell(), message, defaultValue);
+ if (svd.open() == Window.OK)
+ return svd.getString();
+ else
+ return null;
+ }
+
+ public static Long askLong(String message) {
+ SingleValueDialog svd = new SingleValueDialog(Display.getCurrent().getActiveShell(), message);
+ if (svd.open() == Window.OK)
+ return svd.getLong();
+ else
+ return null;
+ }
+
+ public static Double askDouble(String message) {
+ SingleValueDialog svd = new SingleValueDialog(Display.getCurrent().getActiveShell(), message);
+ if (svd.open() == Window.OK)
+ return svd.getDouble();
+ else
+ return null;
+ }
+
+}
--- /dev/null
+/** SWT/JFace dialogs. */
+package org.argeo.cms.swt.dialogs;
\ No newline at end of file
--- /dev/null
+package org.argeo.cms.swt.osgi;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.argeo.cms.osgi.BundleCmsTheme;
+import org.argeo.cms.swt.CmsSwtTheme;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.widgets.Display;
+
+/** Centralises some generic {@link CmsSwtTheme} patterns. */
+public class BundleCmsSwtTheme extends BundleCmsTheme implements CmsSwtTheme {
+ private Map<String, ImageData> imageCache = new HashMap<>();
+
+ private Map<String, Map<Integer, String>> iconPaths = new HashMap<>();
+
+ public Image getImage(String path) {
+ if (!imageCache.containsKey(path)) {
+ try (InputStream in = getResourceAsStream(path)) {
+ if (in == null)
+ return null;
+ ImageData imageData = new ImageData(in);
+ imageCache.put(path, imageData);
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+ ImageData imageData = imageCache.get(path);
+ Image image = new Image(Display.getCurrent(), imageData);
+ return image;
+ }
+
+ /**
+ * And icon with this file name (without the extension), with a best effort to
+ * find the appropriate size, or <code>null</code> if not found.
+ *
+ * @param name An icon file name without path and extension.
+ * @param preferredSize the preferred size, if <code>null</code>,
+ * {@link #getDefaultIconSize()} will be tried.
+ */
+ public Image getIcon(String name, Integer preferredSize) {
+ if (preferredSize == null)
+ preferredSize = getDefaultIconSize();
+ Map<Integer, String> subCache;
+ if (!iconPaths.containsKey(name))
+ subCache = new HashMap<>();
+ else
+ subCache = iconPaths.get(name);
+ Image image = null;
+ if (!subCache.containsKey(preferredSize)) {
+ Image bestMatchSoFar = null;
+ paths: for (String p : getImagesPaths()) {
+ int lastSlash = p.lastIndexOf('/');
+ String fileName = p;
+ if (lastSlash >= 0)
+ fileName = p.substring(lastSlash + 1);
+ int lastDot = fileName.lastIndexOf('.');
+ if (lastDot >= 0)
+ fileName = fileName.substring(0, lastDot);
+ if (fileName.equals(name)) {// matched
+ Image img = getImage(p);
+ int width = img.getBounds().width;
+ if (width == preferredSize) {// perfect match
+ subCache.put(preferredSize, p);
+ image = img;
+ break paths;
+ }
+ if (bestMatchSoFar == null) {
+ bestMatchSoFar = img;
+ } else {
+ if (Math.abs(width - preferredSize) < Math
+ .abs(bestMatchSoFar.getBounds().width - preferredSize))
+ bestMatchSoFar = img;
+ }
+ }
+ }
+
+ if (image == null)
+ image = bestMatchSoFar;
+ } else {
+ image = getImage(subCache.get(preferredSize));
+ }
+
+ if (image != null && !iconPaths.containsKey(name))
+ iconPaths.put(name, subCache);
+
+ return image;
+ }
+
+}
--- /dev/null
+package org.argeo.cms.swt.useradmin;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.argeo.api.NodeConstants;
+import org.argeo.eclipse.ui.ColumnDefinition;
+import org.argeo.eclipse.ui.EclipseUiException;
+import org.argeo.eclipse.ui.EclipseUiUtils;
+import org.argeo.eclipse.ui.parts.LdifUsersTable;
+import org.argeo.naming.LdapAttrs;
+import org.argeo.naming.LdapObjs;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.dialogs.TrayDialog;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.FillLayout;
+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.Shell;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.service.useradmin.Group;
+import org.osgi.service.useradmin.Role;
+import org.osgi.service.useradmin.User;
+import org.osgi.service.useradmin.UserAdmin;
+
+/** Dialog with a user (or group) list to pick up one */
+public class PickUpUserDialog extends TrayDialog {
+ private static final long serialVersionUID = -1420106871173920369L;
+
+ // Business objects
+ private final UserAdmin userAdmin;
+ private User selectedUser;
+
+ // this page widgets and UI objects
+ private String title;
+ private LdifUsersTable userTableViewerCmp;
+ private TableViewer userViewer;
+ private List<ColumnDefinition> columnDefs = new ArrayList<ColumnDefinition>();
+
+ /**
+ * A dialog to pick up a group or a user, showing a table with default
+ * columns
+ */
+ public PickUpUserDialog(Shell parentShell, String title, UserAdmin userAdmin) {
+ super(parentShell);
+ this.title = title;
+ this.userAdmin = userAdmin;
+
+ columnDefs.add(new ColumnDefinition(new UserLP(UserLP.COL_ICON), "",
+ 24, 24));
+ columnDefs.add(new ColumnDefinition(
+ new UserLP(UserLP.COL_DISPLAY_NAME), "Common Name", 150, 100));
+ columnDefs.add(new ColumnDefinition(new UserLP(UserLP.COL_DOMAIN),
+ "Domain", 100, 120));
+ columnDefs.add(new ColumnDefinition(new UserLP(UserLP.COL_DN),
+ "Distinguished Name", 300, 100));
+ }
+
+ /** A dialog to pick up a group or a user */
+ public PickUpUserDialog(Shell parentShell, String title,
+ UserAdmin userAdmin, List<ColumnDefinition> columnDefs) {
+ super(parentShell);
+ this.title = title;
+ this.userAdmin = userAdmin;
+ this.columnDefs = columnDefs;
+ }
+
+ @Override
+ protected void okPressed() {
+ if (getSelected() == null)
+ MessageDialog.openError(getShell(), "No user chosen",
+ "Please, choose a user or press Cancel.");
+ else
+ super.okPressed();
+ }
+
+ protected Control createDialogArea(Composite parent) {
+ Composite dialogArea = (Composite) super.createDialogArea(parent);
+ dialogArea.setLayout(new FillLayout());
+
+ Composite bodyCmp = new Composite(dialogArea, SWT.NO_FOCUS);
+ bodyCmp.setLayout(new GridLayout());
+
+ // Create and configure the table
+ userTableViewerCmp = new MyUserTableViewer(bodyCmp, SWT.MULTI
+ | SWT.H_SCROLL | SWT.V_SCROLL);
+
+ userTableViewerCmp.setColumnDefinitions(columnDefs);
+ userTableViewerCmp.populateWithStaticFilters(false, false);
+ GridData gd = EclipseUiUtils.fillAll();
+ gd.minimumHeight = 300;
+ userTableViewerCmp.setLayoutData(gd);
+ userTableViewerCmp.refresh();
+
+ // Controllers
+ userViewer = userTableViewerCmp.getTableViewer();
+ userViewer.addDoubleClickListener(new MyDoubleClickListener());
+ userViewer
+ .addSelectionChangedListener(new MySelectionChangedListener());
+
+ parent.pack();
+ return dialogArea;
+ }
+
+ public User getSelected() {
+ if (selectedUser == null)
+ return null;
+ else
+ return selectedUser;
+ }
+
+ protected void configureShell(Shell shell) {
+ super.configureShell(shell);
+ shell.setText(title);
+ }
+
+ class MyDoubleClickListener implements IDoubleClickListener {
+ public void doubleClick(DoubleClickEvent evt) {
+ if (evt.getSelection().isEmpty())
+ return;
+
+ Object obj = ((IStructuredSelection) evt.getSelection())
+ .getFirstElement();
+ if (obj instanceof User) {
+ selectedUser = (User) obj;
+ okPressed();
+ }
+ }
+ }
+
+ class MySelectionChangedListener implements ISelectionChangedListener {
+ @Override
+ public void selectionChanged(SelectionChangedEvent event) {
+ if (event.getSelection().isEmpty()) {
+ selectedUser = null;
+ return;
+ }
+ Object obj = ((IStructuredSelection) event.getSelection())
+ .getFirstElement();
+ if (obj instanceof Group) {
+ selectedUser = (Group) obj;
+ }
+ }
+ }
+
+ private class MyUserTableViewer extends LdifUsersTable {
+ private static final long serialVersionUID = 8467999509931900367L;
+
+ private final String[] knownProps = { LdapAttrs.uid.name(),
+ LdapAttrs.cn.name(), LdapAttrs.DN };
+
+ private Button showSystemRoleBtn;
+ private Button showUserBtn;
+
+ public MyUserTableViewer(Composite parent, int style) {
+ super(parent, style);
+ }
+
+ protected void populateStaticFilters(Composite staticFilterCmp) {
+ staticFilterCmp.setLayout(new GridLayout());
+ showSystemRoleBtn = new Button(staticFilterCmp, SWT.CHECK);
+ showSystemRoleBtn.setText("Show system roles ");
+
+ showUserBtn = new Button(staticFilterCmp, SWT.CHECK);
+ showUserBtn.setText("Show users ");
+
+ SelectionListener sl = new SelectionAdapter() {
+ private static final long serialVersionUID = -7033424592697691676L;
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ refresh();
+ }
+ };
+
+ showSystemRoleBtn.addSelectionListener(sl);
+ showUserBtn.addSelectionListener(sl);
+ }
+
+ @Override
+ protected List<User> listFilteredElements(String filter) {
+ Role[] roles;
+ try {
+ StringBuilder builder = new StringBuilder();
+
+ StringBuilder filterBuilder = new StringBuilder();
+ if (notNull(filter))
+ for (String prop : knownProps) {
+ filterBuilder.append("(");
+ filterBuilder.append(prop);
+ filterBuilder.append("=*");
+ filterBuilder.append(filter);
+ filterBuilder.append("*)");
+ }
+
+ String typeStr = "(" + LdapAttrs.objectClass.name() + "="
+ + LdapObjs.groupOfNames.name() + ")";
+ if ((showUserBtn.getSelection()))
+ typeStr = "(|(" + LdapAttrs.objectClass.name() + "="
+ + LdapObjs.inetOrgPerson.name() + ")" + typeStr
+ + ")";
+
+ if (!showSystemRoleBtn.getSelection())
+ typeStr = "(& " + typeStr + "(!(" + LdapAttrs.DN + "=*"
+ + NodeConstants.ROLES_BASEDN + ")))";
+
+ if (filterBuilder.length() > 1) {
+ builder.append("(&" + typeStr);
+ builder.append("(|");
+ builder.append(filterBuilder.toString());
+ builder.append("))");
+ } else {
+ builder.append(typeStr);
+ }
+ roles = userAdmin.getRoles(builder.toString());
+ } catch (InvalidSyntaxException e) {
+ throw new EclipseUiException(
+ "Unable to get roles with filter: " + filter, e);
+ }
+ List<User> users = new ArrayList<User>();
+ for (Role role : roles)
+ if (!users.contains(role))
+ users.add((User) role);
+ return users;
+ }
+ }
+
+ private boolean notNull(String string) {
+ if (string == null)
+ return false;
+ else
+ return !"".equals(string.trim());
+ }
+}
--- /dev/null
+package org.argeo.cms.swt.useradmin;
+
+import org.argeo.api.NodeConstants;
+import org.argeo.cms.auth.UserAdminUtils;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.osgi.service.useradmin.Role;
+import org.osgi.service.useradmin.User;
+
+/** Centralize label providers for the group table */
+class UserLP extends ColumnLabelProvider {
+ private static final long serialVersionUID = -4645930210988368571L;
+
+ final static String COL_ICON = "colID.icon";
+ final static String COL_DN = "colID.dn";
+ final static String COL_DISPLAY_NAME = "colID.displayName";
+ final static String COL_DOMAIN = "colID.domain";
+
+ final String currType;
+
+ // private Font italic;
+ private Font bold;
+
+ UserLP(String colId) {
+ this.currType = colId;
+ }
+
+ @Override
+ public Font getFont(Object element) {
+ // Current user as bold
+ if (UserAdminUtils.isCurrentUser(((User) element))) {
+ if (bold == null)
+ bold = JFaceResources.getFontRegistry().defaultFontDescriptor().setStyle(SWT.BOLD)
+ .createFont(Display.getCurrent());
+ return bold;
+ }
+ return null;
+ }
+
+ @Override
+ public Image getImage(Object element) {
+ if (COL_ICON.equals(currType)) {
+ User user = (User) element;
+ String dn = user.getName();
+ if (dn.endsWith(NodeConstants.ROLES_BASEDN))
+ return UsersImages.ICON_ROLE;
+ else if (user.getType() == Role.GROUP)
+ return UsersImages.ICON_GROUP;
+ else
+ return UsersImages.ICON_USER;
+ } else
+ return null;
+ }
+
+ @Override
+ public String getText(Object element) {
+ User user = (User) element;
+ return getText(user);
+
+ }
+
+ public String getText(User user) {
+ if (COL_DN.equals(currType))
+ return user.getName();
+ else if (COL_DISPLAY_NAME.equals(currType))
+ return UserAdminUtils.getCommonName(user);
+ else if (COL_DOMAIN.equals(currType))
+ return UserAdminUtils.getDomainName(user);
+ else
+ return "";
+ }
+}
--- /dev/null
+package org.argeo.cms.swt.useradmin;
+
+import org.argeo.cms.ui.theme.CmsImages;
+import org.eclipse.swt.graphics.Image;
+
+/** Specific users icons. */
+public class UsersImages {
+ private final static String PREFIX = "icons/";
+
+ public final static Image ICON_USER = CmsImages.createImg(PREFIX + "person.png");
+ public final static Image ICON_GROUP = CmsImages.createImg(PREFIX + "group.png");
+ public final static Image ICON_ROLE = CmsImages.createImg(PREFIX + "role.gif");
+ public final static Image ICON_CHANGE_PASSWORD = CmsImages.createImg(PREFIX + "security.gif");
+}
--- /dev/null
+/** SWT/JFace users management components. */
+package org.argeo.cms.swt.useradmin;
\ No newline at end of file
+++ /dev/null
-package org.argeo.eclipse.ui;
-
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseListener;
-
-/**
- * {@link MouseListener#mouseDoubleClick(MouseEvent)} as a functional interface
- * in order to use as a short lambda expression in UI code.
- * {@link MouseListener#mouseDownouseEvent)} and
- * {@link MouseListener#mouseUp(MouseEvent)} do nothing by default.
- */
-@FunctionalInterface
-public interface MouseDoubleClick extends MouseListener {
- @Override
- void mouseDoubleClick(MouseEvent e);
-
- @Override
- default void mouseDown(MouseEvent e) {
- // does nothing
- }
-
- @Override
- default void mouseUp(MouseEvent e) {
- // does nothing
- }
-}
+++ /dev/null
-package org.argeo.eclipse.ui;
-
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseListener;
-
-/**
- * {@link MouseListener#mouseDown(MouseEvent)} as a functional interface in
- * order to use as a short lambda expression in UI code.
- * {@link MouseListener#mouseDoubleClick(MouseEvent)} and
- * {@link MouseListener#mouseUp(MouseEvent)} do nothing by default.
- */
-@FunctionalInterface
-public interface MouseDown extends MouseListener {
- @Override
- void mouseDown(MouseEvent e);
-
- @Override
- default void mouseDoubleClick(MouseEvent e) {
- // does nothing
- }
-
- @Override
- default void mouseUp(MouseEvent e) {
- // does nothing
- }
-}
+++ /dev/null
-package org.argeo.eclipse.ui;
-
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-
-/**
- * {@link SelectionListener} as a functional interface in order to use as a
- * short lambda expression in UI code.
- * {@link SelectionListener#widgetDefaultSelected(SelectionEvent)} does nothing
- * by default.
- */
-@FunctionalInterface
-public interface Selected extends SelectionListener {
- @Override
- public void widgetSelected(SelectionEvent e);
-
- default public void widgetDefaultSelected(SelectionEvent e) {
- // does nothing
- }
-
-}
import javax.script.ScriptException;
import org.argeo.api.NodeConstants;
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.cms.swt.Selected;
import org.argeo.cms.ui.CmsUiProvider;
import org.argeo.cms.ui.util.CmsPane;
-import org.argeo.cms.ui.util.CmsUiUtils;
import org.argeo.cms.web.SimpleErgonomics;
-import org.argeo.eclipse.ui.Selected;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.rap.rwt.application.Application;
import org.eclipse.rap.rwt.application.EntryPoint;
if (false) {
// QA
- CmsUiUtils.style(cmsPane.getQaArea(), "qa");
+ CmsSwtUtils.style(cmsPane.getQaArea(), "qa");
Button reload = new Button(cmsPane.getQaArea(), SWT.FLAT);
- CmsUiUtils.style(reload, "qa");
+ CmsSwtUtils.style(reload, "qa");
reload.setText("Reload");
reload.addSelectionListener(new Selected() {
private static final long serialVersionUID = 1L;
});
// Support
- CmsUiUtils.style(cmsPane.getSupportArea(), "support");
+ CmsSwtUtils.style(cmsPane.getSupportArea(), "support");
Label msg = new Label(cmsPane.getSupportArea(), SWT.NONE);
- CmsUiUtils.style(msg, "support");
+ CmsSwtUtils.style(msg, "support");
msg.setText("UNSUPPORTED DEVELOPMENT VERSION");
}
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsTheme;
import org.argeo.cms.CmsException;
import org.argeo.cms.ui.CmsConstants;
-import org.argeo.cms.ui.CmsTheme;
import org.argeo.cms.ui.CmsUiProvider;
import org.argeo.cms.ui.util.CmsUiUtils;
import org.argeo.cms.web.BundleResourceLoader;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsView;
import org.argeo.cms.CmsException;
import org.argeo.cms.auth.CurrentUser;
import org.argeo.cms.auth.HttpRequestCallback;
import org.argeo.cms.auth.HttpRequestCallbackHandler;
-import org.argeo.cms.ui.CmsStyles;
-import org.argeo.cms.ui.CmsView;
+import org.argeo.cms.swt.CmsStyles;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.eclipse.ui.specific.UiContext;
import org.argeo.jcr.JcrUtils;
import org.argeo.naming.AuthPassword;
@Override
protected final void createContents(final Composite parent) {
// UiContext.setData(CmsView.KEY, this);
- CmsView.registerCmsView(parent.getShell(), this);
+ CmsSwtUtils.registerCmsView(parent.getShell(), this);
Subject.doAs(getSubject(), new PrivilegedAction<Void>() {
@Override
public Void run() {
import java.io.IOException;
import java.io.InputStream;
-import org.argeo.cms.ui.CmsTheme;
+import org.argeo.api.cms.CmsTheme;
import org.eclipse.rap.rwt.service.ResourceLoader;
/** A RAP {@link ResourceLoader} based on a {@link CmsTheme}. */
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.argeo.cms.ui.CmsApp;
-import org.argeo.cms.ui.CmsAppListener;
-import org.argeo.cms.ui.CmsTheme;
-import org.argeo.cms.ui.CmsView;
+import org.argeo.api.cms.CmsApp;
+import org.argeo.api.cms.CmsAppListener;
+import org.argeo.api.cms.CmsTheme;
+import org.argeo.api.cms.CmsView;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.util.LangUtils;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.rap.rwt.application.Application;
public void handleException(Throwable throwable) {
Display display = Display.getCurrent();
if (display != null && !display.isDisposed()) {
- CmsView cmsView = CmsView.getCmsView(display.getActiveShell());
+ CmsView cmsView = CmsSwtUtils.getCmsView(display.getActiveShell());
cmsView.exception(throwable);
} else {
log.error("Unexpected exception outside an UI thread", throwable);
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsApp;
+import org.argeo.api.cms.CmsImageManager;
+import org.argeo.api.cms.CmsSession;
+import org.argeo.api.cms.CmsUi;
+import org.argeo.api.cms.CmsView;
+import org.argeo.api.cms.UxContext;
import org.argeo.cms.LocaleUtils;
-import org.argeo.cms.auth.CmsSession;
import org.argeo.cms.auth.CurrentUser;
import org.argeo.cms.auth.HttpRequestCallbackHandler;
-import org.argeo.cms.ui.CmsApp;
-import org.argeo.cms.ui.CmsImageManager;
-import org.argeo.cms.ui.CmsView;
-import org.argeo.cms.ui.UxContext;
-import org.argeo.cms.ui.dialogs.CmsFeedback;
-import org.argeo.cms.ui.util.CmsUiUtils;
+import org.argeo.cms.osgi.CmsOsgiUtils;
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.cms.swt.SimpleSwtUxContext;
+import org.argeo.cms.swt.dialogs.CmsFeedback;
import org.argeo.cms.ui.util.DefaultImageManager;
-import org.argeo.cms.ui.util.SimpleUxContext;
import org.argeo.eclipse.ui.specific.UiContext;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.rap.rwt.application.EntryPoint;
private UxContext uxContext;
private CmsImageManager imageManager;
- private Composite ui;
+ private Display display;
+ private CmsUi ui;
private String uid;
@Override
public Void run() {
try {
- uxContext = new SimpleUxContext();
+ uxContext = new SimpleSwtUxContext();
imageManager = new DefaultImageManager();
CmsSession cmsSession = getCmsSession();
if (cmsSession != null) {
LocaleUtils.setThreadLocale(rwtLocale);
}
parent.setData(CmsApp.UI_NAME_PROPERTY, uiName);
+ display = parent.getDisplay();
ui = cmsWebApp.getCmsApp().initUi(parent);
- ui.setLayoutData(CmsUiUtils.fillAll());
+ if (ui instanceof Composite)
+ ((Composite) ui).setLayoutData(CmsSwtUtils.fillAll());
// we need ui to be set before refresh so that CmsView can store UI context data
// in it.
cmsWebApp.getCmsApp().refreshUi(ui, null);
if (swtError.code == SWT.ERROR_FUNCTION_DISPOSED)
return;
}
- ui.getDisplay().syncExec(() -> {
+ display.syncExec(() -> {
// CmsFeedback.show("Unexpected exception in CMS", e);
exception = e;
// log.error("Unexpected exception in CMS", e);
browserNavigation.pushState(state, title);
}
- @Override
public CmsImageManager getImageManager() {
return imageManager;
}
@Override
public CmsSession getCmsSession() {
- CmsSession cmsSession = CmsSession.getCmsSession(cmsWebApp.getBundleContext(), getSubject());
+ CmsSession cmsSession = CmsOsgiUtils.getCmsSession(cmsWebApp.getBundleContext(), getSubject());
return cmsSession;
}
public int createUI() {
Display display = new Display();
Shell shell = createShell(display);
- shell.setLayout(CmsUiUtils.noSpaceGridLayout());
- CmsView.registerCmsView(shell, this);
+ shell.setLayout(CmsSwtUtils.noSpaceGridLayout());
+ CmsSwtUtils.registerCmsView(shell, this);
createContents(shell);
shell.layout();
// if (shell.getMaximized()) {
package org.argeo.cms.web;
-import static org.argeo.cms.ui.util.BundleCmsTheme.CMS_THEME_BUNDLE_PROPERTY;
+import static org.argeo.cms.osgi.BundleCmsTheme.CMS_THEME_BUNDLE_PROPERTY;
import java.util.HashMap;
import java.util.Map;
-import org.argeo.cms.ui.util.BundleCmsTheme;
+import org.argeo.cms.osgi.BundleCmsTheme;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.rap.rwt.application.Application;
import org.eclipse.rap.rwt.application.ApplicationConfiguration;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsImageManager;
+import org.argeo.api.cms.UxContext;
import org.argeo.cms.CmsException;
-import org.argeo.cms.ui.CmsImageManager;
-import org.argeo.cms.ui.CmsStyles;
+import org.argeo.cms.swt.CmsStyles;
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.cms.swt.SimpleSwtUxContext;
import org.argeo.cms.ui.CmsUiProvider;
-import org.argeo.cms.ui.UxContext;
-import org.argeo.cms.ui.util.CmsUiUtils;
import org.argeo.cms.ui.util.DefaultImageManager;
-import org.argeo.cms.ui.util.SimpleUxContext;
import org.argeo.cms.ui.util.SystemNotifications;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.swt.SWT;
protected void initUi(Composite parent) {
uid = UUID.randomUUID().toString();
parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- parent.setLayout(CmsUiUtils.noSpaceGridLayout(new GridLayout(3, false)));
+ parent.setLayout(CmsSwtUtils.noSpaceGridLayout(new GridLayout(3, false)));
- uxContext = new SimpleUxContext();
+ uxContext = new SimpleSwtUxContext();
if (!getUxContext().isMasterData())
createAdminArea(parent);
headerArea = new Composite(parent, SWT.NONE);
// TODO: bi-directional
leftArea = new Composite(parent, SWT.NONE);
leftArea.setLayoutData(new GridData(SWT.LEAD, SWT.TOP, false, false));
- leftArea.setLayout(CmsUiUtils.noSpaceGridLayout());
+ leftArea.setLayout(CmsSwtUtils.noSpaceGridLayout());
bodyArea = new Composite(parent, SWT.NONE);
bodyArea.setData(RWT.CUSTOM_VARIANT, CmsStyles.CMS_BODY);
bodyArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- bodyArea.setLayout(CmsUiUtils.noSpaceGridLayout());
+ bodyArea.setLayout(CmsSwtUtils.noSpaceGridLayout());
// TODO: bi-directional
rightArea = new Composite(parent, SWT.NONE);
rightArea.setLayoutData(new GridData(SWT.END, SWT.TOP, false, false));
- rightArea.setLayout(CmsUiUtils.noSpaceGridLayout());
+ rightArea.setLayout(CmsSwtUtils.noSpaceGridLayout());
footerArea = new Composite(parent, SWT.NONE);
// footerArea.setLayout(new FillLayout());
for (Control child : area.getChildren())
child.dispose();
- CmsUiUtils.style(area, style);
+ CmsSwtUtils.style(area, style);
try {
uiProvider.createUi(area, getNode());
} catch (RepositoryException e) {
// clear
for (Control child : bodyArea.getChildren())
child.dispose();
- bodyArea.setLayout(CmsUiUtils.noSpaceGridLayout());
+ bodyArea.setLayout(CmsSwtUtils.noSpaceGridLayout());
try {
Node node = getNode();
return uid;
}
- @Override
public CmsImageManager getImageManager() {
return imageManager;
}
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.argeo.cms.ui.CmsTheme;
+import org.argeo.api.cms.CmsTheme;
import org.eclipse.rap.rwt.application.Application;
import org.eclipse.rap.rwt.service.ResourceLoader;
+++ /dev/null
-package org.argeo.cms.ui;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.jcr.Repository;
-
-import org.eclipse.rap.rwt.RWT;
-
-/** Base class for {@link CmsApp}s. */
-public abstract class AbstractCmsApp implements CmsApp {
- private Map<String, CmsTheme> themes = Collections.synchronizedMap(new HashMap<>());
-
- private List<CmsAppListener> cmsAppListeners = new ArrayList<>();
-
- private Repository repository;
-
- protected abstract String getThemeId(String uiName);
-
- @Override
- public CmsTheme getTheme(String uiName) {
- String themeId = getThemeId(uiName);
- if (themeId == null)
- return null;
- if (!themes.containsKey(themeId))
- throw new IllegalArgumentException("Theme " + themeId + " not found.");
- return themes.get(themeId);
- }
-
- @Override
- public boolean allThemesAvailable() {
- boolean themeMissing = false;
- uiNames: for (String uiName : getUiNames()) {
- String themeId = getThemeId(uiName);
- if (RWT.DEFAULT_THEME_ID.equals(themeId))
- continue uiNames;
- if (!themes.containsKey(themeId)) {
- themeMissing = true;
- break uiNames;
- }
- }
- return !themeMissing;
- }
-
- public void addTheme(CmsTheme theme, Map<String, String> properties) {
- themes.put(theme.getThemeId(), theme);
- if (allThemesAvailable())
- for (CmsAppListener listener : cmsAppListeners)
- listener.themingUpdated();
- }
-
- public void removeTheme(CmsTheme theme, Map<String, String> properties) {
- themes.remove(theme.getThemeId());
- }
-
- @Override
- public void addCmsAppListener(CmsAppListener listener) {
- cmsAppListeners.add(listener);
- if (allThemesAvailable())
- listener.themingUpdated();
- }
-
- @Override
- public void removeCmsAppListener(CmsAppListener listener) {
- cmsAppListeners.remove(listener);
- }
-
- protected Repository getRepository() {
- return repository;
- }
-
- public void setRepository(Repository repository) {
- this.repository = repository;
- }
-
-}
+++ /dev/null
-package org.argeo.cms.ui;
-
-import java.util.Set;
-
-import org.eclipse.swt.widgets.Composite;
-
-/** An extensible user interface base on the CMS backend. */
-public interface CmsApp {
- /**
- * If {@link Composite#setData(String, Object)} is set with this property, it
- * indicates a different UI (typically with another theming. The {@link CmsApp}
- * can use this information, but it doesn't have to be set, in which case a
- * default UI must be provided. The provided value must belong to the values
- * returned by {@link CmsApp#getUiNames()}.
- */
- final static String UI_NAME_PROPERTY = CmsApp.class.getName() + ".ui.name";
-
- Set<String> getUiNames();
-
- Composite initUi(Composite parent);
-
- void refreshUi(Composite parent, String state);
-
- void setState(Composite parent, String state);
-
- CmsTheme getTheme(String uiName);
-
- boolean allThemesAvailable();
-
- void addCmsAppListener(CmsAppListener listener);
-
- void removeCmsAppListener(CmsAppListener listener);
-}
+++ /dev/null
-package org.argeo.cms.ui;
-
-/** Notifies important events in a {@link CmsApp} life cycle. */
-public interface CmsAppListener {
- /** Theming has been updated and should be reloaded. */
- void themingUpdated();
-}
package org.argeo.cms.ui;
-import org.eclipse.swt.graphics.Point;
+import org.argeo.api.cms.Cms2DSize;
/** Commons constants */
+@Deprecated
public interface CmsConstants {
// DATAKEYS
// public final static String STYLE = EclipseUiConstants.CSS_CLASS;
public final static String LOADING_IMAGE = "icons/loading.gif";
public final static String NO_IMAGE = "icons/noPic-square-640px.png";
- public final static Point NO_IMAGE_SIZE = new Point(320, 320);
+ public final static Cms2DSize NO_IMAGE_SIZE = new Cms2DSize(320, 320);
public final static Float NO_IMAGE_RATIO = 1f;
// MISCEALLENEOUS
String DATE_TIME_FORMAT = "dd/MM/yyyy, HH:mm";
+++ /dev/null
-package org.argeo.cms.ui;
-
-/** Abstraction of a simple edition life cycle. */
-public interface CmsEditable {
-
- /** Whether the calling thread can edit, the value is immutable */
- public Boolean canEdit();
-
- public Boolean isEditing();
-
- public void startEditing();
-
- public void stopEditing();
-
- public static CmsEditable NON_EDITABLE = new CmsEditable() {
-
- @Override
- public void stopEditing() {
- }
-
- @Override
- public void startEditing() {
- }
-
- @Override
- public Boolean isEditing() {
- return false;
- }
-
- @Override
- public Boolean canEdit() {
- return false;
- }
- };
-
- public static CmsEditable ALWAYS_EDITING = new CmsEditable() {
-
- @Override
- public void stopEditing() {
- }
-
- @Override
- public void startEditing() {
- }
-
- @Override
- public Boolean isEditing() {
- return true;
- }
-
- @Override
- public Boolean canEdit() {
- return true;
- }
- };
-
-}
+++ /dev/null
-package org.argeo.cms.ui;
-
-import java.io.InputStream;
-
-import javax.jcr.Binary;
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.widgets.Control;
-
-/** Read and write access to images. */
-public interface CmsImageManager {
- /** Load image in control */
- public Boolean load(Node node, Control control, Point size) throws RepositoryException;
-
- /** @return (0,0) if not available */
- public Point getImageSize(Node node) throws RepositoryException;
-
- /**
- * The related <img> tag, with src, width and height set.
- *
- * @return null if not available
- */
- public String getImageTag(Node node) throws RepositoryException;
-
- /**
- * The related <img> tag, with url, width and height set. Caller must
- * close the tag (or add additional attributes).
- *
- * @return null if not available
- */
- public StringBuilder getImageTagBuilder(Node node, Point size) throws RepositoryException;
-
- /**
- * Returns the remotely accessible URL of the image (registering it if
- * needed) @return null if not available
- */
- public String getImageUrl(Node node) throws RepositoryException;
-
- public Binary getImageBinary(Node node) throws RepositoryException;
-
- public Image getSwtImage(Node node) throws RepositoryException;
-
- /** @return URL */
- public String uploadImage(Node context, Node uploadFolder, String fileName, InputStream in, String contentType)
- throws RepositoryException;
-
- @Deprecated
- default String uploadImage(Node uploadFolder, String fileName, InputStream in) throws RepositoryException {
- System.err.println("Context must be provided to " + CmsImageManager.class.getName());
- return uploadImage(null, uploadFolder, fileName, in, null);
- }
-}
+++ /dev/null
-package org.argeo.cms.ui;
-
-/** Styles references in the CSS. */
-@Deprecated
-public interface CmsStyles {
- // General
- public final static String CMS_SHELL = "cms_shell";
- public final static String CMS_MENU_LINK = "cms_menu_link";
-
- // Header
- public final static String CMS_HEADER = "cms_header";
- public final static String CMS_HEADER_LEAD = "cms_header-lead";
- public final static String CMS_HEADER_CENTER = "cms_header-center";
- public final static String CMS_HEADER_END = "cms_header-end";
-
- public final static String CMS_LEAD = "cms_lead";
- public final static String CMS_END = "cms_end";
- public final static String CMS_FOOTER = "cms_footer";
-
- public final static String CMS_USER_MENU = "cms_user_menu";
- public final static String CMS_USER_MENU_LINK = "cms_user_menu-link";
- public final static String CMS_USER_MENU_ITEM = "cms_user_menu-item";
- public final static String CMS_LOGIN_DIALOG = "cms_login_dialog";
- public final static String CMS_LOGIN_DIALOG_USERNAME = "cms_login_dialog-username";
- public final static String CMS_LOGIN_DIALOG_PASSWORD = "cms_login_dialog-password";
-
- // Body
- public final static String CMS_SCROLLED_AREA = "cms_scrolled_area";
- public final static String CMS_BODY = "cms_body";
- public final static String CMS_STATIC_TEXT = "cms_static-text";
- public final static String CMS_LINK = "cms_link";
-}
+++ /dev/null
-package org.argeo.cms.ui;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Set;
-
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Shell;
-
-/** A CMS theme which can be applied to web apps as well as desktop apps. */
-public interface CmsTheme {
- /** Unique ID of this theme. */
- String getThemeId();
-
- /**
- * Load a resource as an input stream, base don its relative path, or
- * <code>null</code> if not found
- */
- InputStream getResourceAsStream(String resourceName) throws IOException;
-
- /** Relative paths to standard web CSS. */
- Set<String> getWebCssPaths();
-
- /** Relative paths to RAP specific CSS. */
- Set<String> getRapCssPaths();
-
- /** Relative paths to SWT specific CSS. */
- Set<String> getSwtCssPaths();
-
- /** Relative paths to images such as icons. */
- Set<String> getImagesPaths();
-
- /** Relative paths to fonts. */
- Set<String> getFontsPaths();
-
- /** Tags to be added to the header section of the HTML page. */
- String getHtmlHeaders();
-
- /** The HTML body to use. */
- String getBodyHtml();
-
- /** The image registered at this path, or <code>null</code> if not found. */
- Image getImage(String path);
-
- /** The default icon size (typically the smallest). */
- Integer getDefaultIconSize();
-
- /** Loads one of the relative path provided by the other methods. */
- InputStream loadPath(String path) throws IOException;
-
- /**
- * And icon with this file name (without the extension), with a best effort to
- * find the appropriate size, or <code>null</code> if not found.
- *
- * @param name An icon file name without path and extension.
- * @param preferredSize the preferred size, if <code>null</code>,
- * {@link #getDefaultIconSize()} will be tried.
- */
- Image getIcon(String name, Integer preferredSize);
-
- static CmsTheme getCmsTheme(Composite parent) {
- CmsTheme theme = (CmsTheme) parent.getData(CmsTheme.class.getName());
- if (theme == null) {
- // find parent shell
- Shell topShell = parent.getShell();
- while (topShell.getParent() != null)
- topShell = (Shell) topShell.getParent();
- theme = (CmsTheme) topShell.getData(CmsTheme.class.getName());
- parent.setData(CmsTheme.class.getName(), theme);
- }
- return theme;
- }
-
- static void registerCmsTheme(Shell shell, CmsTheme theme) {
- // find parent shell
- Shell topShell = shell;
- while (topShell.getParent() != null)
- topShell = (Shell) topShell.getParent();
- // check if already set
- if (topShell.getData(CmsTheme.class.getName()) != null) {
- CmsTheme registeredTheme = (CmsTheme) topShell.getData(CmsTheme.class.getName());
- throw new IllegalArgumentException(
- "Theme " + registeredTheme.getThemeId() + " already registered in this shell");
- }
- topShell.setData(CmsTheme.class.getName(), theme);
- }
-
-}
import javax.jcr.Node;
import javax.jcr.RepositoryException;
+import org.argeo.api.cms.MvcProvider;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
+++ /dev/null
-package org.argeo.cms.ui;
-
-import java.security.PrivilegedAction;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.security.auth.login.LoginContext;
-
-import org.argeo.cms.auth.CmsSession;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Shell;
-
-/** Provides interaction with the CMS system. */
-public interface CmsView {
- final static String CMS_VIEW_UID_PROPERTY = "argeo.cms.view.uid";
- // String KEY = "org.argeo.cms.ui.view";
-
- String getUid();
-
- UxContext getUxContext();
-
- // NAVIGATION
- void navigateTo(String state);
-
- // SECURITY
- void authChange(LoginContext loginContext);
-
- void logout();
-
- // void registerCallbackHandler(CallbackHandler callbackHandler);
-
- // SERVICES
- void exception(Throwable e);
-
- CmsImageManager getImageManager();
-
- boolean isAnonymous();
-
- /**
- * Send an event to this topic. Does nothing by default., but if implemented it
- * MUST set the {@link #CMS_VIEW_UID_PROPERTY} in the properties.
- */
- default void sendEvent(String topic, Map<String, Object> properties) {
-
- }
-
- /**
- * Convenience methods for when {@link #sendEvent(String, Map)} only requires
- * one single parameter.
- */
- default void sendEvent(String topic, String param, Object value) {
- Map<String, Object> properties = new HashMap<>();
- properties.put(param, value);
- sendEvent(topic, properties);
- }
-
- default void applyStyles(Object widget) {
-
- }
-
- default <T> T doAs(PrivilegedAction<T> action) {
- throw new UnsupportedOperationException();
- }
-
- default Void runAs(Runnable runnable) {
- return doAs(new PrivilegedAction<Void>() {
-
- @Override
- public Void run() {
- if (runnable != null)
- runnable.run();
- return null;
- }
- });
- }
-
- default void stateChanged(String state, String title) {
- }
-
- default CmsSession getCmsSession() {
- throw new UnsupportedOperationException();
- }
-
- default Object getData(String key) {
- throw new UnsupportedOperationException();
- }
-
- @SuppressWarnings("unchecked")
- default <T> T getUiContext(Class<T> clss) {
- return (T) getData(clss.getName());
- }
-
- default <T> void setUiContext(Class<T> clss, T instance) {
- setData(clss.getName(), instance);
- }
-
- default void setData(String key, Object value) {
- throw new UnsupportedOperationException();
- }
-
- static CmsView getCmsView(Control parent) {
- // find parent shell
- Shell topShell = parent.getShell();
- while (topShell.getParent() != null)
- topShell = (Shell) topShell.getParent();
- return (CmsView) topShell.getData(CmsView.class.getName());
- }
-
- static void registerCmsView(Shell shell, CmsView view) {
- // find parent shell
- Shell topShell = shell;
- while (topShell.getParent() != null)
- topShell = (Shell) topShell.getParent();
- // check if already set
- if (topShell.getData(CmsView.class.getName()) != null) {
- CmsView registeredView = (CmsView) topShell.getData(CmsView.class.getName());
- throw new IllegalArgumentException("Cms view " + registeredView + " already registered in this shell");
- }
- shell.setData(CmsView.class.getName(), view);
- }
-
-}
+++ /dev/null
-package org.argeo.cms.ui;
-
-import java.util.function.BiFunction;
-
-/**
- * Stateless UI part creator. Takes a parent view (V) and a model context (M) in
- * order to create a view part (W) which can then be further configured. Such
- * object can be used as services and reference other part of the model which
- * are relevant for all created UI part.
- */
-@FunctionalInterface
-public interface MvcProvider<V, M, W> extends BiFunction<V, M, W> {
- W createUiPart(V parent, M context);
-
- /**
- * Whether this parent view is supported.
- *
- * @return true by default.
- */
- default boolean isViewSupported(V parent) {
- return true;
- }
-
- /**
- * Whether this context is supported.
- *
- * @return true by default.
- */
- default boolean isModelSupported(M context) {
- return true;
- }
-
- default W apply(V parent, M context) {
- if (!isViewSupported(parent))
- throw new IllegalArgumentException("Parent view " + parent + "is not supported.");
- if (!isModelSupported(context))
- throw new IllegalArgumentException("Model context " + context + "is not supported.");
- return createUiPart(parent, context);
- }
-
- default W createUiPart(V parent) {
- return createUiPart(parent, null);
- }
-}
+++ /dev/null
-package org.argeo.cms.ui;
-
-public interface UxContext {
- boolean isPortrait();
-
- boolean isLandscape();
-
- boolean isSquare();
-
- boolean isSmall();
-
- /**
- * Is a production environment (must be false by default, and be explicitly
- * set during the CMS deployment). When false, it can activate additional UI
- * capabilities in order to facilitate QA.
- */
- boolean isMasterData();
-}
+++ /dev/null
-package org.argeo.cms.ui.dialogs;
-
-import java.security.PrivilegedAction;
-import java.util.Arrays;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.cms.CmsMsg;
-import org.argeo.cms.CmsUserManager;
-import org.argeo.cms.ui.CmsView;
-import org.argeo.cms.ui.util.CmsUiUtils;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-
-/** Dialog to change a password. */
-public class ChangePasswordDialog extends CmsMessageDialog {
- private final static Log log = LogFactory.getLog(ChangePasswordDialog.class);
-
- private CmsUserManager cmsUserManager;
- private CmsView cmsView;
-
- private PrivilegedAction<Integer> doIt;
-
- public ChangePasswordDialog(Shell parentShell, String message, int kind, CmsUserManager cmsUserManager) {
- super(parentShell, message, kind);
- this.cmsUserManager = cmsUserManager;
- cmsView = CmsView.getCmsView(parentShell);
- }
-
- @Override
- protected Control createInputArea(Composite userSection) {
- addFormLabel(userSection, CmsMsg.currentPassword.lead());
- Text previousPassword = new Text(userSection, SWT.BORDER | SWT.PASSWORD);
- previousPassword.setLayoutData(CmsUiUtils.fillWidth());
- addFormLabel(userSection, CmsMsg.newPassword.lead());
- Text newPassword = new Text(userSection, SWT.BORDER | SWT.PASSWORD);
- newPassword.setLayoutData(CmsUiUtils.fillWidth());
- addFormLabel(userSection, CmsMsg.repeatNewPassword.lead());
- Text confirmPassword = new Text(userSection, SWT.BORDER | SWT.PASSWORD);
- confirmPassword.setLayoutData(CmsUiUtils.fillWidth());
-
- doIt = () -> {
- if (Arrays.equals(newPassword.getTextChars(), confirmPassword.getTextChars())) {
- try {
- cmsUserManager.changeOwnPassword(previousPassword.getTextChars(), newPassword.getTextChars());
- return OK;
- } catch (Exception e1) {
- log.error("Could not change password", e1);
- cancel();
- CmsMessageDialog.openError(CmsMsg.invalidPassword.lead());
- return CANCEL;
- }
- } else {
- cancel();
- CmsMessageDialog.openError(CmsMsg.repeatNewPassword.lead());
- return CANCEL;
- }
- };
-
- pack();
- return previousPassword;
- }
-
- @Override
- protected void okPressed() {
- Integer returnCode = cmsView.doAs(doIt);
- if (returnCode.equals(OK)) {
- super.okPressed();
- CmsMessageDialog.openInformation(CmsMsg.passwordChanged.lead());
- }
- }
-
- private static Label addFormLabel(Composite parent, String label) {
- Label lbl = new Label(parent, SWT.WRAP);
- lbl.setText(label);
-// CmsUiUtils.style(lbl, SuiteStyle.simpleLabel);
- return lbl;
- }
-
-}
+++ /dev/null
-package org.argeo.cms.ui.dialogs;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.cms.CmsMsg;
-import org.argeo.eclipse.ui.Selected;
-import org.eclipse.swt.SWT;
-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;
-import org.eclipse.swt.widgets.Text;
-
-/** A dialog feedback based on a {@link LightweightDialog}. */
-public class CmsFeedback extends LightweightDialog {
- private final static Log log = LogFactory.getLog(CmsFeedback.class);
-
- private String message;
- private Throwable exception;
-
- public CmsFeedback(Shell parentShell, String message, Throwable e) {
- super(parentShell);
- this.message = message;
- this.exception = e;
- log.error(message, e);
- }
-
- public static CmsFeedback show(String message, Throwable e) {
- // rethrow ThreaDeath in order to make sure that RAP will properly clean
- // up the UI thread
- if (e instanceof ThreadDeath)
- throw (ThreadDeath) e;
-
- try {
- CmsFeedback cmsFeedback = new CmsFeedback(null, message, e);
- cmsFeedback.setBlockOnOpen(false);
- cmsFeedback.open();
- return cmsFeedback;
- } catch (Throwable e1) {
- log.error("Cannot open error feedback (" + e.getMessage() + "), original error below", e);
- return null;
- }
- }
-
- public static CmsFeedback show(String message) {
- CmsFeedback cmsFeedback = new CmsFeedback(null, message, null);
- cmsFeedback.open();
- return cmsFeedback;
- }
-
- /** Tries to find a display */
- // private static Display getDisplay() {
- // try {
- // Display display = Display.getCurrent();
- // if (display != null)
- // return display;
- // else
- // return Display.getDefault();
- // } catch (Exception e) {
- // return Display.getCurrent();
- // }
- // }
-
- protected Control createDialogArea(Composite parent) {
- parent.setLayout(new GridLayout(2, false));
-
- Label messageLbl = new Label(parent, SWT.WRAP);
- if (message != null)
- messageLbl.setText(message);
- else if (exception != null)
- messageLbl.setText(exception.getLocalizedMessage());
-
- Button close = new Button(parent, SWT.FLAT);
- close.setText(CmsMsg.close.lead());
- close.setLayoutData(new GridData(SWT.END, SWT.TOP, false, false));
- close.addSelectionListener((Selected) (e) -> closeShell(OK));
-
- // Composite composite = new Composite(dialogarea, SWT.NONE);
- // composite.setLayout(new GridLayout(2, false));
- // composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-
- if (exception != null) {
- Text stack = new Text(parent, SWT.MULTI | SWT.LEAD | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
- stack.setEditable(false);
- stack.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
- StringWriter sw = new StringWriter();
- exception.printStackTrace(new PrintWriter(sw));
- stack.setText(sw.toString());
- }
-
- // parent.pack();
- return messageLbl;
- }
-
-}
+++ /dev/null
-package org.argeo.cms.ui.dialogs;
-
-import org.argeo.cms.CmsMsg;
-import org.argeo.cms.ui.util.CmsUiUtils;
-import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.argeo.eclipse.ui.Selected;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.TraverseEvent;
-import org.eclipse.swt.events.TraverseListener;
-import org.eclipse.swt.graphics.Point;
-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.Display;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-
-/** Base class for dialogs displaying messages or small forms. */
-public class CmsMessageDialog extends LightweightDialog {
- public final static int NONE = 0;
- public final static int ERROR = 1;
- public final static int INFORMATION = 2;
- public final static int QUESTION = 3;
- public final static int WARNING = 4;
- public final static int CONFIRM = 5;
- public final static int QUESTION_WITH_CANCEL = 6;
-
- private int kind;
- private String message;
-
- public CmsMessageDialog(Shell parentShell, String message, int kind) {
- super(parentShell);
- this.kind = kind;
- this.message = message;
- }
-
- protected Control createDialogArea(Composite parent) {
- parent.setLayout(new GridLayout());
-
- TraverseListener traverseListener = new TraverseListener() {
- private static final long serialVersionUID = -1158892811534971856L;
-
- public void keyTraversed(TraverseEvent e) {
- if (e.detail == SWT.TRAVERSE_RETURN)
- okPressed();
- else if (e.detail == SWT.TRAVERSE_ESCAPE)
- cancelPressed();
- }
- };
-
- // message
- Composite body = new Composite(parent, SWT.NONE);
- body.addTraverseListener(traverseListener);
- GridLayout bodyGridLayout = new GridLayout();
- bodyGridLayout.marginHeight = 20;
- bodyGridLayout.marginWidth = 20;
- body.setLayout(bodyGridLayout);
- body.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-
- if (message != null) {
- Label messageLbl = new Label(body, SWT.WRAP);
- CmsUiUtils.markup(messageLbl);
- messageLbl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
- messageLbl.setFont(EclipseUiUtils.getBoldFont(parent));
- messageLbl.setText(message);
- }
-
- // buttons
- Composite buttons = new Composite(parent, SWT.NONE);
- buttons.addTraverseListener(traverseListener);
- buttons.setLayoutData(new GridData(SWT.END, SWT.FILL, true, false));
- if (kind == INFORMATION || kind == WARNING || kind == ERROR || kind == ERROR) {
- GridLayout layout = new GridLayout(1, true);
- layout.marginWidth = 0;
- layout.marginHeight = 0;
- buttons.setLayout(layout);
-
- Button close = new Button(buttons, SWT.FLAT);
- close.setText(CmsMsg.close.lead());
- close.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
- close.addSelectionListener((Selected) (e) -> closeShell(OK));
- close.setFocus();
- close.addTraverseListener(traverseListener);
-
- buttons.setTabList(new Control[] { close });
- } else if (kind == CONFIRM || kind == QUESTION || kind == QUESTION_WITH_CANCEL) {
- Control input = createInputArea(body);
- if (input != null) {
- input.addTraverseListener(traverseListener);
- body.setTabList(new Control[] { input });
- }
- GridLayout layout = new GridLayout(2, true);
- layout.marginWidth = 0;
- layout.marginHeight = 0;
- buttons.setLayout(layout);
-
- Button cancel = new Button(buttons, SWT.FLAT);
- cancel.setText(CmsMsg.cancel.lead());
- cancel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
- cancel.addSelectionListener((Selected) (e) -> cancelPressed());
- cancel.addTraverseListener(traverseListener);
-
- Button ok = new Button(buttons, SWT.FLAT);
- ok.setText(CmsMsg.ok.lead());
- ok.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
- ok.addSelectionListener((Selected) (e) -> okPressed());
- ok.addTraverseListener(traverseListener);
- if (input == null)
- ok.setFocus();
- else
- input.setFocus();
-
- buttons.setTabList(new Control[] { ok, cancel });
- }
- // pack();
- parent.setTabList(new Control[] { body, buttons });
- return body;
- }
-
- protected Control createInputArea(Composite parent) {
- return null;
- }
-
- protected void okPressed() {
- closeShell(OK);
- }
-
- protected void cancelPressed() {
- closeShell(CANCEL);
- }
-
- protected void cancel() {
- closeShell(CANCEL);
- }
-
- protected Point getInitialSize() {
- return new Point(400, 200);
- }
-
- public static boolean open(int kind, Shell parent, String message) {
- CmsMessageDialog dialog = new CmsMessageDialog(parent, message, kind);
- return dialog.open() == 0;
- }
-
- public static boolean openConfirm(String message) {
- return open(CONFIRM, Display.getCurrent().getActiveShell(), message);
- }
-
- public static void openInformation(String message) {
- open(INFORMATION, Display.getCurrent().getActiveShell(), message);
- }
-
- public static boolean openQuestion(String message) {
- return open(QUESTION, Display.getCurrent().getActiveShell(), message);
- }
-
- public static void openWarning(String message) {
- open(WARNING, Display.getCurrent().getActiveShell(), message);
- }
-
- public static void openError(String message) {
- open(ERROR, Display.getCurrent().getActiveShell(), message);
- }
-
-}
+++ /dev/null
-package org.argeo.cms.ui.dialogs;
-
-import java.lang.reflect.InvocationTargetException;
-
-import org.argeo.cms.CmsMsg;
-import org.argeo.cms.ui.util.CmsUiUtils;
-import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.argeo.eclipse.ui.Selected;
-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(CmsUiUtils.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(CmsUiUtils.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 {
- 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.ui.dialogs;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.eclipse.ui.EclipseUiException;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.FocusEvent;
-import org.eclipse.swt.events.FocusListener;
-import org.eclipse.swt.events.ShellAdapter;
-import org.eclipse.swt.events.ShellEvent;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Shell;
-
-/** Generic lightweight dialog, not based on JFace. */
-public class LightweightDialog {
- private final static Log log = LogFactory.getLog(LightweightDialog.class);
-
- // must be the same value as org.eclipse.jface.window.Window#OK
- public final static int OK = 0;
- // must be the same value as org.eclipse.jface.window.Window#CANCEL
- public final static int CANCEL = 1;
-
- private Shell parentShell;
- private Shell backgroundShell;
- private Shell foregoundShell;
-
- private Integer returnCode = null;
- private boolean block = true;
-
- private String title;
-
- /** Tries to find a display */
- private static Display getDisplay() {
- try {
- Display display = Display.getCurrent();
- if (display != null)
- return display;
- else
- return Display.getDefault();
- } catch (Exception e) {
- return Display.getCurrent();
- }
- }
-
- public LightweightDialog(Shell parentShell) {
- this.parentShell = parentShell;
- }
-
- public int open() {
- if (foregoundShell != null)
- throw new EclipseUiException("There is already a shell");
- backgroundShell = new Shell(parentShell, SWT.ON_TOP);
- backgroundShell.setFullScreen(true);
- // if (parentShell != null) {
- // backgroundShell.setBounds(parentShell.getBounds());
- // } else
- // backgroundShell.setMaximized(true);
- backgroundShell.setAlpha(128);
- backgroundShell.setBackground(getDisplay().getSystemColor(SWT.COLOR_BLACK));
- foregoundShell = new Shell(backgroundShell, SWT.NO_TRIM | SWT.ON_TOP);
- if (title != null)
- setTitle(title);
- foregoundShell.setLayout(new GridLayout());
- foregoundShell.setSize(getInitialSize());
- createDialogArea(foregoundShell);
- // shell.pack();
- // shell.layout();
-
- Rectangle shellBounds = parentShell != null ? parentShell.getBounds() : Display.getCurrent().getBounds();// RAP
- Point dialogSize = foregoundShell.getSize();
- int x = shellBounds.x + (shellBounds.width - dialogSize.x) / 2;
- int y = shellBounds.y + (shellBounds.height - dialogSize.y) / 2;
- foregoundShell.setLocation(x, y);
-
- foregoundShell.addShellListener(new ShellAdapter() {
- private static final long serialVersionUID = -2701270481953688763L;
-
- @Override
- public void shellDeactivated(ShellEvent e) {
- if (hasChildShells())
- return;
- if (returnCode == null)// not yet closed
- closeShell(CANCEL);
- }
-
- @Override
- public void shellClosed(ShellEvent e) {
- notifyClose();
- }
-
- });
-
- backgroundShell.open();
- foregoundShell.open();
- // after the foreground shell has been opened
- backgroundShell.addFocusListener(new FocusListener() {
- private static final long serialVersionUID = 3137408447474661070L;
-
- @Override
- public void focusLost(FocusEvent event) {
- }
-
- @Override
- public void focusGained(FocusEvent event) {
- if (hasChildShells())
- return;
- if (returnCode == null)// not yet closed
- closeShell(CANCEL);
- }
- });
-
- if (block) {
- block();
- }
- if (returnCode == null)
- returnCode = OK;
- return returnCode;
- }
-
- public void block() {
- try {
- runEventLoop(foregoundShell);
- } catch (ThreadDeath t) {
- returnCode = CANCEL;
- if (log.isTraceEnabled())
- log.error("Thread death, canceling dialog", t);
- } catch (Throwable t) {
- returnCode = CANCEL;
- log.error("Cannot open blocking lightweight dialog", t);
- }
- }
-
- private boolean hasChildShells() {
- if (foregoundShell == null)
- return false;
- return foregoundShell.getShells().length != 0;
- }
-
- // public synchronized int openAndWait() {
- // open();
- // while (returnCode == null)
- // try {
- // wait(100);
- // } catch (InterruptedException e) {
- // // silent
- // }
- // return returnCode;
- // }
-
- private synchronized void notifyClose() {
- if (returnCode == null)
- returnCode = CANCEL;
- notifyAll();
- }
-
- protected void closeShell(int returnCode) {
- this.returnCode = returnCode;
- if (CANCEL == returnCode)
- onCancel();
- if (foregoundShell != null && !foregoundShell.isDisposed()) {
- foregoundShell.close();
- foregoundShell.dispose();
- foregoundShell = null;
- }
-
- if (backgroundShell != null && !backgroundShell.isDisposed()) {
- backgroundShell.close();
- backgroundShell.dispose();
- }
- }
-
- protected Point getInitialSize() {
- // if (exception != null)
- // return new Point(800, 600);
- // else
- return new Point(600, 400);
- }
-
- protected Control createDialogArea(Composite parent) {
- Composite dialogarea = new Composite(parent, SWT.NONE);
- dialogarea.setLayout(new GridLayout());
- dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- return dialogarea;
- }
-
- protected Shell getBackgroundShell() {
- return backgroundShell;
- }
-
- protected Shell getForegoundShell() {
- return foregoundShell;
- }
-
- public void setBlockOnOpen(boolean shouldBlock) {
- block = shouldBlock;
- }
-
- public void pack() {
- foregoundShell.pack();
- }
-
- private void runEventLoop(Shell loopShell) {
- Display display;
- if (foregoundShell == null) {
- display = Display.getCurrent();
- } else {
- display = loopShell.getDisplay();
- }
-
- while (loopShell != null && !loopShell.isDisposed()) {
- try {
- if (!display.readAndDispatch()) {
- display.sleep();
- }
- } catch (UnsupportedOperationException e) {
- throw e;
- } catch (Throwable e) {
- handleException(e);
- }
- }
- if (!display.isDisposed())
- display.update();
- }
-
- protected void handleException(Throwable t) {
- if (t instanceof ThreadDeath) {
- // Don't catch ThreadDeath as this is a normal occurrence when
- // the thread dies
- throw (ThreadDeath) t;
- }
- // Try to keep running.
- t.printStackTrace();
- }
-
- /** @return false, if the dialog should not be closed. */
- protected boolean onCancel() {
- return true;
- }
-
- public void setTitle(String title) {
- this.title = title;
- if (title != null && getForegoundShell() != null)
- getForegoundShell().setText(title);
- }
-
- public Integer getReturnCode() {
- return returnCode;
- }
-
-}
\ No newline at end of file
+++ /dev/null
-package org.argeo.cms.ui.dialogs;
-
-import org.eclipse.jface.window.Window;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-
-/** A dialog asking a for a single value. */
-public class SingleValueDialog extends CmsMessageDialog {
- private Text valueT;
- private String value;
- private String defaultValue;
-
- public SingleValueDialog(Shell parentShell, String message) {
- super(parentShell, message, QUESTION);
- }
-
- public SingleValueDialog(Shell parentShell, String message, String defaultValue) {
- super(parentShell, message, QUESTION);
- this.defaultValue = defaultValue;
- }
-
- @Override
- protected Control createInputArea(Composite parent) {
- valueT = new Text(parent, SWT.LEAD | SWT.BORDER | SWT.SINGLE);
- valueT.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true));
- if (defaultValue != null)
- valueT.setText(defaultValue);
- return valueT;
- }
-
- @Override
- protected void okPressed() {
- value = valueT.getText();
- super.okPressed();
- }
-
- public String getString() {
- return value;
- }
-
- public Long getLong() {
- return Long.valueOf(getString());
- }
-
- public Double getDouble() {
- return Double.valueOf(getString());
- }
-
- public static String ask(String message) {
- return ask(message, null);
- }
-
- public static String ask(String message, String defaultValue) {
- SingleValueDialog svd = new SingleValueDialog(Display.getCurrent().getActiveShell(), message, defaultValue);
- if (svd.open() == Window.OK)
- return svd.getString();
- else
- return null;
- }
-
- public static Long askLong(String message) {
- SingleValueDialog svd = new SingleValueDialog(Display.getCurrent().getActiveShell(), message);
- if (svd.open() == Window.OK)
- return svd.getLong();
- else
- return null;
- }
-
- public static Double askDouble(String message) {
- SingleValueDialog svd = new SingleValueDialog(Display.getCurrent().getActiveShell(), message);
- if (svd.open() == Window.OK)
- return svd.getDouble();
- else
- return null;
- }
-
-}
+++ /dev/null
-/** SWT/JFace dialogs. */
-package org.argeo.cms.ui.dialogs;
\ No newline at end of file
import javax.jcr.Node;
import javax.jcr.RepositoryException;
-import org.argeo.cms.ui.util.CmsUiUtils;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.ui.viewers.EditablePart;
import org.argeo.cms.ui.widgets.StyledControl;
import org.argeo.eclipse.ui.EclipseUiUtils;
/** To be overridden */
protected void setContainerLayoutData(Composite composite) {
- composite.setLayoutData(CmsUiUtils.fillWidth());
+ composite.setLayoutData(CmsSwtUtils.fillWidth());
}
@Override
protected Label createValueLabel(Composite parent, int style, String value) {
Label label = new Label(parent, style);
label.setText("#" + value);
- CmsUiUtils.markup(label);
- CmsUiUtils.style(label, FormStyle.propertyText.style());
+ CmsSwtUtils.markup(label);
+ CmsSwtUtils.style(label, FormStyle.propertyText.style());
return label;
}
Button deleteBtn = new Button(valCmp, SWT.FLAT);
deleteBtn.setData(FormConstants.LINKED_VALUE, value);
deleteBtn.addSelectionListener(removeValueSL);
- CmsUiUtils.style(deleteBtn, FormStyle.delete.style() + FormStyle.BUTTON_SUFFIX);
+ CmsSwtUtils.style(deleteBtn, FormStyle.delete.style() + FormStyle.BUTTON_SUFFIX);
GridData gd = new GridData();
gd.heightHint = btnHeight;
gd.widthHint = btnWidth;
// The "add new value" text is not meant to change, so we can set it on
// creation
text.setMessage(message);
- CmsUiUtils.style(text, style);
+ CmsSwtUtils.style(text, style);
text.setFocus();
text.addTraverseListener(new TraverseListener() {
if (canEdit) {
Label lbl = new Label(box, getStyle());
lbl.setText(message);
- CmsUiUtils.style(lbl, style);
- CmsUiUtils.markup(lbl);
+ CmsSwtUtils.style(lbl, style);
+ CmsSwtUtils.markup(lbl);
if (mouseListener != null)
lbl.addMouseListener(mouseListener);
return lbl;
}
public synchronized void startEditing() {
- CmsUiUtils.style(getControl(), FormStyle.propertyText.style());
+ CmsSwtUtils.style(getControl(), FormStyle.propertyText.style());
// getControl().setData(STYLE, FormStyle.propertyText.style());
super.startEditing();
}
public synchronized void stopEditing() {
- CmsUiUtils.style(getControl(), FormStyle.propertyMessage.style());
+ CmsSwtUtils.style(getControl(), FormStyle.propertyMessage.style());
// getControl().setData(STYLE, FormStyle.propertyMessage.style());
super.stopEditing();
}
import javax.jcr.Node;
import javax.jcr.RepositoryException;
-import org.argeo.cms.ui.util.CmsUiUtils;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.ui.viewers.EditablePart;
import org.argeo.cms.ui.widgets.StyledControl;
import org.argeo.eclipse.ui.EclipseUiUtils;
public synchronized void startEditing() {
// if (dateTxt != null && !dateTxt.isDisposed())
- CmsUiUtils.style(getControl(), FormStyle.propertyText);
+ CmsSwtUtils.style(getControl(), FormStyle.propertyText);
// getControl().setData(STYLE, FormStyle.propertyText.style());
super.startEditing();
}
public synchronized void stopEditing() {
if (EclipseUiUtils.isEmpty(dateTxt.getText()))
- CmsUiUtils.style(getControl(), FormStyle.propertyMessage);
+ CmsSwtUtils.style(getControl(), FormStyle.propertyMessage);
// getControl().setData(STYLE, FormStyle.propertyMessage.style());
else
- CmsUiUtils.style(getControl(), FormStyle.propertyText);
+ CmsSwtUtils.style(getControl(), FormStyle.propertyText);
// getControl().setData(STYLE, FormStyle.propertyText.style());
super.stopEditing();
}
protected Label createLabel(Composite box, String style) {
Label lbl = new Label(box, getStyle() | SWT.WRAP);
- lbl.setLayoutData(CmsUiUtils.fillWidth());
- CmsUiUtils.style(lbl, style);
- CmsUiUtils.markup(lbl);
+ lbl.setLayoutData(CmsSwtUtils.fillWidth());
+ CmsSwtUtils.style(lbl, style);
+ CmsSwtUtils.markup(lbl);
if (mouseListener != null)
lbl.addMouseListener(mouseListener);
return lbl;
}
private Control createCustomEditableControl(Composite box, String style) {
- box.setLayoutData(CmsUiUtils.fillWidth());
+ box.setLayoutData(CmsSwtUtils.fillWidth());
Composite dateComposite = new Composite(box, SWT.NONE);
GridLayout gl = EclipseUiUtils.noSpaceGridLayout(new GridLayout(2, false));
gl.horizontalSpacing = fieldBtnSpacing;
dateComposite.setLayout(gl);
dateTxt = new Text(dateComposite, SWT.BORDER);
- CmsUiUtils.style(dateTxt, style);
+ CmsSwtUtils.style(dateTxt, style);
dateTxt.setLayoutData(new GridData(120, SWT.DEFAULT));
dateTxt.setToolTipText(
"Enter a date with form \"" + FormUtils.DEFAULT_SHORT_DATE_FORMAT + "\" or use the calendar");
openCalBtn = new Button(dateComposite, SWT.FLAT);
- CmsUiUtils.style(openCalBtn, FormStyle.calendar.style() + FormStyle.BUTTON_SUFFIX);
+ CmsSwtUtils.style(openCalBtn, FormStyle.calendar.style() + FormStyle.BUTTON_SUFFIX);
GridData gd = new GridData(SWT.CENTER, SWT.CENTER, false, false);
gd.heightHint = 17;
openCalBtn.setLayoutData(gd);
super(source.getDisplay(), SWT.NO_TRIM | SWT.BORDER | SWT.ON_TOP);
populate();
// Add border and shadow style
- CmsUiUtils.markup(CalendarPopup.this);
- CmsUiUtils.style(CalendarPopup.this, FormStyle.popupCalendar.style());
+ CmsSwtUtils.markup(CalendarPopup.this);
+ CmsSwtUtils.style(CalendarPopup.this, FormStyle.popupCalendar.style());
pack();
layout();
setLocation(source.toDisplay((source.getLocation().x - 2), (source.getSize().y) + 3));
import javax.jcr.Node;
import javax.jcr.RepositoryException;
-import org.argeo.cms.ui.util.CmsUiUtils;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.ui.viewers.EditablePart;
import org.argeo.cms.ui.widgets.EditableText;
import org.argeo.eclipse.ui.EclipseUiUtils;
}
public synchronized void startEditing() {
- CmsUiUtils.style(getControl(), FormStyle.propertyText);
+ CmsSwtUtils.style(getControl(), FormStyle.propertyText);
super.startEditing();
}
public synchronized void stopEditing() {
if (EclipseUiUtils.isEmpty(((Text) getControl()).getText()))
- CmsUiUtils.style(getControl(), FormStyle.propertyMessage);
+ CmsSwtUtils.style(getControl(), FormStyle.propertyMessage);
else
- CmsUiUtils.style(getControl(), FormStyle.propertyText);
+ CmsSwtUtils.style(getControl(), FormStyle.propertyText);
super.stopEditing();
}
import javax.jcr.Node;
-import org.argeo.cms.ui.CmsEditable;
-import org.argeo.cms.ui.util.CmsUiUtils;
+import org.argeo.api.cms.CmsEditable;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
display = new Composite(parent, SWT.NONE);
display.setLayoutData(layoutData);
- CmsUiUtils.style(display, FormStyle.header.style());
+ CmsSwtUtils.style(display, FormStyle.header.style());
display.setBackgroundMode(SWT.INHERIT_FORCE);
- display.setLayout(CmsUiUtils.noSpaceGridLayout());
+ display.setLayout(CmsSwtUtils.noSpaceGridLayout());
publishBtn = createSimpleBtn(display, getPublishButtonLabel());
display.moveAbove(null);
private Button createSimpleBtn(Composite parent, String label) {
Button button = new Button(parent, SWT.FLAT | SWT.PUSH);
button.setText(label);
- CmsUiUtils.style(button, FormStyle.header.style());
+ CmsSwtUtils.style(button, FormStyle.header.style());
button.addSelectionListener(this);
return button;
}
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.argeo.cms.ui.CmsEditable;
-import org.argeo.cms.ui.CmsImageManager;
-import org.argeo.cms.ui.CmsView;
-import org.argeo.cms.ui.util.CmsUiUtils;
+import org.argeo.api.cms.Cms2DSize;
+import org.argeo.api.cms.CmsEditable;
+import org.argeo.api.cms.CmsImageManager;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.ui.viewers.AbstractPageViewer;
import org.argeo.cms.ui.viewers.EditablePart;
import org.argeo.cms.ui.viewers.Section;
// Context cached in the viewer
// The reference to translate from text to calendar and reverse
private DateFormat dateFormat = new SimpleDateFormat(FormUtils.DEFAULT_SHORT_DATE_FORMAT);
- private CmsImageManager imageManager;
+ private CmsImageManager<Control, Node> imageManager;
private FileUploadListener fileUploadListener;
public FormPageViewer(Section mainSection, int style, CmsEditable cmsEditable) throws RepositoryException {
return mainSection;
}
- protected CmsImageManager imageManager() {
+ protected CmsImageManager<Control, Node> imageManager() {
if (imageManager == null)
- imageManager = CmsView.getCmsView(mainSection).getImageManager();
+ imageManager = (CmsImageManager<Control, Node>) CmsSwtUtils.getCmsView(mainSection).getImageManager();
return imageManager;
}
Section section = null;
if (node != null) {
section = new Section(body, SWT.NO_FOCUS, node);
- section.setLayoutData(CmsUiUtils.fillWidth());
- section.setLayout(CmsUiUtils.noSpaceGridLayout());
+ section.setLayoutData(CmsSwtUtils.fillWidth());
+ section.setLayout(CmsSwtUtils.noSpaceGridLayout());
}
return section;
}
EditablePropertyString eps = new EditablePropertyString(bodyRow, SWT.WRAP | SWT.LEFT, node, propName, msg);
eps.setMouseListener(getMouseListener());
eps.setFocusListener(getFocusListener());
- eps.setLayoutData(CmsUiUtils.fillWidth());
+ eps.setLayoutData(CmsSwtUtils.fillWidth());
}
}
addListeners(emsp);
// emsp.setMouseListener(getMouseListener());
emsp.setStyle(FormStyle.propertyMessage.style());
- emsp.setLayoutData(CmsUiUtils.fillWidth());
+ emsp.setLayoutData(CmsSwtUtils.fillWidth());
}
}
// boolean isSmall = CmsView.getCmsView(parent).getUxContext().isSmall();
Label label = new Label(parent, SWT.LEAD | SWT.WRAP);
label.setText(value + " ");
- CmsUiUtils.style(label, FormStyle.propertyLabel.style());
+ CmsSwtUtils.style(label, FormStyle.propertyLabel.style());
GridData gd = new GridData(SWT.LEAD, vAlign, false, false);
if (labelColWidth != null)
gd.widthHint = labelColWidth;
protected Label newStyledLabel(Composite parent, String style, String value) {
Label label = new Label(parent, SWT.NONE);
label.setText(value);
- CmsUiUtils.style(label, style);
+ CmsSwtUtils.style(label, style);
return label;
}
protected Composite createRowLayoutComposite(Composite parent) throws RepositoryException {
Composite bodyRow = new Composite(parent, SWT.NO_FOCUS);
- bodyRow.setLayoutData(CmsUiUtils.fillWidth());
+ bodyRow.setLayoutData(CmsSwtUtils.fillWidth());
RowLayout rl = new RowLayout(SWT.WRAP);
rl.type = SWT.HORIZONTAL;
rl.spacing = rowLayoutHSpacing;
// for a while
cleanedName = System.currentTimeMillis() % 100000 + "_" + cleanedName;
- try {
- imageManager().uploadImage(context, context, cleanedName, stream, details.getContentType());
- // TODO clean refresh strategy
- section.getDisplay().asyncExec(new Runnable() {
- @Override
- public void run() {
- try {
- FormPageViewer.this.refresh(section);
- section.layout();
- section.getParent().layout();
- } catch (RepositoryException re) {
- throw new JcrException("Unable to refresh " + "image section for " + context, re);
- }
+ imageManager().uploadImage(context, context, cleanedName, stream, details.getContentType());
+ // TODO clean refresh strategy
+ section.getDisplay().asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ FormPageViewer.this.refresh(section);
+ section.layout();
+ section.getParent().layout();
+ } catch (RepositoryException re) {
+ throw new JcrException("Unable to refresh " + "image section for " + context, re);
}
- });
- } catch (RepositoryException re) {
- throw new JcrException("unable to upload image " + name + " at " + context, re);
- }
+ }
+ });
}
}
}
protected Img createImgComposite(Composite parent, Node node, Point preferredSize) throws RepositoryException {
- Img img = new Img(parent, SWT.NONE, node, preferredSize) {
+ Img img = new Img(parent, SWT.NONE, node, new Cms2DSize(preferredSize.x, preferredSize.y)) {
private static final long serialVersionUID = 1297900641952417540L;
@Override
protected void setContainerLayoutData(Composite composite) {
- composite.setLayoutData(CmsUiUtils.grabWidth(SWT.CENTER, SWT.DEFAULT));
+ composite.setLayoutData(CmsSwtUtils.grabWidth(SWT.CENTER, SWT.DEFAULT));
}
@Override
protected void setControlLayoutData(Control control) {
- control.setLayoutData(CmsUiUtils.grabWidth(SWT.CENTER, SWT.DEFAULT));
+ control.setLayoutData(CmsSwtUtils.grabWidth(SWT.CENTER, SWT.DEFAULT));
}
};
- img.setLayoutData(CmsUiUtils.grabWidth(SWT.CENTER, SWT.DEFAULT));
+ img.setLayoutData(CmsSwtUtils.grabWidth(SWT.CENTER, SWT.DEFAULT));
updateContent(img);
addListeners(img);
return img;
protected Composite addDeleteAbility(final Section section, final Node sessionNode, int topWeight,
int rightWeight) {
Composite comp = new Composite(section, SWT.NONE);
- comp.setLayoutData(CmsUiUtils.fillAll());
+ comp.setLayoutData(CmsSwtUtils.fillAll());
comp.setLayout(new FormLayout());
// The body to be populated
if (getCmsEditable().canEdit()) {
// the delete button
Button deleteBtn = new Button(comp, SWT.FLAT);
- CmsUiUtils.style(deleteBtn, FormStyle.deleteOverlay.style());
+ CmsSwtUtils.style(deleteBtn, FormStyle.deleteOverlay.style());
FormData formData = new FormData();
formData.right = new FormAttachment(rightWeight, 0);
formData.top = new FormAttachment(topWeight, 0);
package org.argeo.cms.ui.forms;
-import org.argeo.cms.ui.util.CmsStyle;
+import org.argeo.api.cms.CmsStyle;
/** Syles used */
public enum FormStyle implements CmsStyle {
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsView;
import org.argeo.cms.CmsException;
-import org.argeo.cms.ui.CmsView;
import org.argeo.cms.ui.util.CmsUiUtils;
import org.argeo.eclipse.ui.EclipseUiUtils;
import org.eclipse.jface.fieldassist.ControlDecoration;
import org.argeo.cms.CmsException;
import org.argeo.cms.auth.CurrentUser;
import org.argeo.cms.jcr.CmsJcrUtils;
-import org.argeo.cms.ui.util.CmsUiUtils;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.eclipse.ui.ColumnDefinition;
import org.argeo.eclipse.ui.EclipseUiUtils;
import org.argeo.eclipse.ui.fs.FileIconNameLabelProvider;
else
nameStr = path.getFileName().toString();
elemBtn.setText(nameStr + " >> ");
- CmsUiUtils.style(elemBtn, FsStyles.BREAD_CRUMB_BTN);
+ CmsSwtUtils.style(elemBtn, FsStyles.BREAD_CRUMB_BTN);
elemBtn.addSelectionListener(new SelectionAdapter() {
private static final long serialVersionUID = -4103695476023480651L;
}
private void populateBookmarks(Composite parent) {
- CmsUiUtils.clear(parent);
+ CmsSwtUtils.clear(parent);
parent.setLayout(new GridLayout());
ISelectionChangedListener selList = new BookmarksSelChangeListener();
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.argeo.cms.CmsException;
-import org.argeo.cms.ui.util.CmsUiUtils;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.eclipse.ui.EclipseUiUtils;
import org.argeo.eclipse.ui.dialogs.SingleValue;
import org.eclipse.jface.dialogs.MessageDialog;
Composite boxCmp = new Composite(this, SWT.NO_FOCUS | SWT.BORDER);
boxCmp.setLayout(EclipseUiUtils.noSpaceGridLayout());
- CmsUiUtils.style(boxCmp, FsStyles.CONTEXT_MENU_BOX);
+ CmsSwtUtils.style(boxCmp, FsStyles.CONTEXT_MENU_BOX);
createContextMenu(boxCmp);
addShellListener(new ActionsShellListener());
Button btn = new Button(boxCmp, SWT.FLAT | SWT.PUSH | SWT.LEAD);
btn.setText(getLabel(actionId));
btn.setLayoutData(EclipseUiUtils.fillWidth());
- CmsUiUtils.markup(btn);
- CmsUiUtils.style(btn, actionId + FsStyles.BUTTON_SUFFIX);
+ CmsSwtUtils.markup(btn);
+ CmsSwtUtils.style(btn, actionId + FsStyles.BUTTON_SUFFIX);
btn.setData(KEY_ACTION_ID, actionId);
btn.addSelectionListener(asl);
actionButtons.put(actionId, btn);
import javax.jcr.nodetype.NodeType;
import org.apache.commons.io.FilenameUtils;
-import org.argeo.cms.ui.CmsImageManager;
+import org.argeo.api.cms.CmsImageManager;
import org.argeo.cms.ui.widgets.Img;
import org.argeo.jcr.JcrException;
import org.argeo.jcr.JcrUtils;
import javax.jcr.RepositoryException;
+import org.argeo.api.cms.Cms2DSize;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.ui.util.CmsUiUtils;
import org.argeo.cms.ui.widgets.EditableImage;
-import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Text;
private static final long serialVersionUID = -5689145523114022890L;
private String src;
- private Point imageSize;
+ private Cms2DSize imageSize;
public SimpleEditableImage(Composite parent, int swtStyle) {
super(parent, swtStyle);
getParent().layout();
}
- public SimpleEditableImage(Composite parent, int swtStyle, String src,
- Point imageSize) {
+ public SimpleEditableImage(Composite parent, int swtStyle, String src, Cms2DSize imageSize) {
super(parent, swtStyle);
this.src = src;
this.imageSize = imageSize;
if (src != null)
imgTag = CmsUiUtils.img(src, imageSize);
else
- imgTag = CmsUiUtils.noImg(imageSize != null ? imageSize
- : NO_IMAGE_SIZE);
+ imgTag = CmsUiUtils.noImg(imageSize != null ? imageSize : NO_IMAGE_SIZE);
return imgTag;
}
protected Text createText(Composite box, String style) {
Text text = new Text(box, getStyle());
- CmsUiUtils.style(text, style);
+ CmsSwtUtils.style(text, style);
return text;
}
this.src = src;
}
- public Point getImageSize() {
+ public Cms2DSize getImageSize() {
return imageSize;
}
- public void setImageSize(Point imageSize) {
+ public void setImageSize(Cms2DSize imageSize) {
this.imageSize = imageSize;
}
+++ /dev/null
-package org.argeo.cms.ui.internal.rwt;
-
-import org.argeo.cms.ui.util.LoginEntryPoint;
-import org.eclipse.rap.rwt.application.Application;
-import org.eclipse.rap.rwt.application.Application.OperationMode;
-import org.eclipse.rap.rwt.application.ApplicationConfiguration;
-
-public class UserUi implements ApplicationConfiguration {
- @Override
- public void configure(Application application) {
- application.setOperationMode(OperationMode.SWT_COMPATIBILITY);
- application.addEntryPoint("/login", LoginEntryPoint.class, null);
- }
-}
+++ /dev/null
-package org.argeo.cms.ui.useradmin;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.argeo.api.NodeConstants;
-import org.argeo.eclipse.ui.ColumnDefinition;
-import org.argeo.eclipse.ui.EclipseUiException;
-import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.argeo.eclipse.ui.parts.LdifUsersTable;
-import org.argeo.naming.LdapAttrs;
-import org.argeo.naming.LdapObjs;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.dialogs.TrayDialog;
-import org.eclipse.jface.viewers.DoubleClickEvent;
-import org.eclipse.jface.viewers.IDoubleClickListener;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.layout.FillLayout;
-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.Shell;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.service.useradmin.Group;
-import org.osgi.service.useradmin.Role;
-import org.osgi.service.useradmin.User;
-import org.osgi.service.useradmin.UserAdmin;
-
-/** Dialog with a user (or group) list to pick up one */
-public class PickUpUserDialog extends TrayDialog {
- private static final long serialVersionUID = -1420106871173920369L;
-
- // Business objects
- private final UserAdmin userAdmin;
- private User selectedUser;
-
- // this page widgets and UI objects
- private String title;
- private LdifUsersTable userTableViewerCmp;
- private TableViewer userViewer;
- private List<ColumnDefinition> columnDefs = new ArrayList<ColumnDefinition>();
-
- /**
- * A dialog to pick up a group or a user, showing a table with default
- * columns
- */
- public PickUpUserDialog(Shell parentShell, String title, UserAdmin userAdmin) {
- super(parentShell);
- this.title = title;
- this.userAdmin = userAdmin;
-
- columnDefs.add(new ColumnDefinition(new UserLP(UserLP.COL_ICON), "",
- 24, 24));
- columnDefs.add(new ColumnDefinition(
- new UserLP(UserLP.COL_DISPLAY_NAME), "Common Name", 150, 100));
- columnDefs.add(new ColumnDefinition(new UserLP(UserLP.COL_DOMAIN),
- "Domain", 100, 120));
- columnDefs.add(new ColumnDefinition(new UserLP(UserLP.COL_DN),
- "Distinguished Name", 300, 100));
- }
-
- /** A dialog to pick up a group or a user */
- public PickUpUserDialog(Shell parentShell, String title,
- UserAdmin userAdmin, List<ColumnDefinition> columnDefs) {
- super(parentShell);
- this.title = title;
- this.userAdmin = userAdmin;
- this.columnDefs = columnDefs;
- }
-
- @Override
- protected void okPressed() {
- if (getSelected() == null)
- MessageDialog.openError(getShell(), "No user chosen",
- "Please, choose a user or press Cancel.");
- else
- super.okPressed();
- }
-
- protected Control createDialogArea(Composite parent) {
- Composite dialogArea = (Composite) super.createDialogArea(parent);
- dialogArea.setLayout(new FillLayout());
-
- Composite bodyCmp = new Composite(dialogArea, SWT.NO_FOCUS);
- bodyCmp.setLayout(new GridLayout());
-
- // Create and configure the table
- userTableViewerCmp = new MyUserTableViewer(bodyCmp, SWT.MULTI
- | SWT.H_SCROLL | SWT.V_SCROLL);
-
- userTableViewerCmp.setColumnDefinitions(columnDefs);
- userTableViewerCmp.populateWithStaticFilters(false, false);
- GridData gd = EclipseUiUtils.fillAll();
- gd.minimumHeight = 300;
- userTableViewerCmp.setLayoutData(gd);
- userTableViewerCmp.refresh();
-
- // Controllers
- userViewer = userTableViewerCmp.getTableViewer();
- userViewer.addDoubleClickListener(new MyDoubleClickListener());
- userViewer
- .addSelectionChangedListener(new MySelectionChangedListener());
-
- parent.pack();
- return dialogArea;
- }
-
- public User getSelected() {
- if (selectedUser == null)
- return null;
- else
- return selectedUser;
- }
-
- protected void configureShell(Shell shell) {
- super.configureShell(shell);
- shell.setText(title);
- }
-
- class MyDoubleClickListener implements IDoubleClickListener {
- public void doubleClick(DoubleClickEvent evt) {
- if (evt.getSelection().isEmpty())
- return;
-
- Object obj = ((IStructuredSelection) evt.getSelection())
- .getFirstElement();
- if (obj instanceof User) {
- selectedUser = (User) obj;
- okPressed();
- }
- }
- }
-
- class MySelectionChangedListener implements ISelectionChangedListener {
- @Override
- public void selectionChanged(SelectionChangedEvent event) {
- if (event.getSelection().isEmpty()) {
- selectedUser = null;
- return;
- }
- Object obj = ((IStructuredSelection) event.getSelection())
- .getFirstElement();
- if (obj instanceof Group) {
- selectedUser = (Group) obj;
- }
- }
- }
-
- private class MyUserTableViewer extends LdifUsersTable {
- private static final long serialVersionUID = 8467999509931900367L;
-
- private final String[] knownProps = { LdapAttrs.uid.name(),
- LdapAttrs.cn.name(), LdapAttrs.DN };
-
- private Button showSystemRoleBtn;
- private Button showUserBtn;
-
- public MyUserTableViewer(Composite parent, int style) {
- super(parent, style);
- }
-
- protected void populateStaticFilters(Composite staticFilterCmp) {
- staticFilterCmp.setLayout(new GridLayout());
- showSystemRoleBtn = new Button(staticFilterCmp, SWT.CHECK);
- showSystemRoleBtn.setText("Show system roles ");
-
- showUserBtn = new Button(staticFilterCmp, SWT.CHECK);
- showUserBtn.setText("Show users ");
-
- SelectionListener sl = new SelectionAdapter() {
- private static final long serialVersionUID = -7033424592697691676L;
-
- @Override
- public void widgetSelected(SelectionEvent e) {
- refresh();
- }
- };
-
- showSystemRoleBtn.addSelectionListener(sl);
- showUserBtn.addSelectionListener(sl);
- }
-
- @Override
- protected List<User> listFilteredElements(String filter) {
- Role[] roles;
- try {
- StringBuilder builder = new StringBuilder();
-
- StringBuilder filterBuilder = new StringBuilder();
- if (notNull(filter))
- for (String prop : knownProps) {
- filterBuilder.append("(");
- filterBuilder.append(prop);
- filterBuilder.append("=*");
- filterBuilder.append(filter);
- filterBuilder.append("*)");
- }
-
- String typeStr = "(" + LdapAttrs.objectClass.name() + "="
- + LdapObjs.groupOfNames.name() + ")";
- if ((showUserBtn.getSelection()))
- typeStr = "(|(" + LdapAttrs.objectClass.name() + "="
- + LdapObjs.inetOrgPerson.name() + ")" + typeStr
- + ")";
-
- if (!showSystemRoleBtn.getSelection())
- typeStr = "(& " + typeStr + "(!(" + LdapAttrs.DN + "=*"
- + NodeConstants.ROLES_BASEDN + ")))";
-
- if (filterBuilder.length() > 1) {
- builder.append("(&" + typeStr);
- builder.append("(|");
- builder.append(filterBuilder.toString());
- builder.append("))");
- } else {
- builder.append(typeStr);
- }
- roles = userAdmin.getRoles(builder.toString());
- } catch (InvalidSyntaxException e) {
- throw new EclipseUiException(
- "Unable to get roles with filter: " + filter, e);
- }
- List<User> users = new ArrayList<User>();
- for (Role role : roles)
- if (!users.contains(role))
- users.add((User) role);
- return users;
- }
- }
-
- private boolean notNull(String string) {
- if (string == null)
- return false;
- else
- return !"".equals(string.trim());
- }
-}
+++ /dev/null
-package org.argeo.cms.ui.useradmin;
-
-import org.argeo.api.NodeConstants;
-import org.argeo.cms.auth.UserAdminUtils;
-import org.eclipse.jface.resource.JFaceResources;
-import org.eclipse.jface.viewers.ColumnLabelProvider;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.Display;
-import org.osgi.service.useradmin.Role;
-import org.osgi.service.useradmin.User;
-
-/** Centralize label providers for the group table */
-class UserLP extends ColumnLabelProvider {
- private static final long serialVersionUID = -4645930210988368571L;
-
- final static String COL_ICON = "colID.icon";
- final static String COL_DN = "colID.dn";
- final static String COL_DISPLAY_NAME = "colID.displayName";
- final static String COL_DOMAIN = "colID.domain";
-
- final String currType;
-
- // private Font italic;
- private Font bold;
-
- UserLP(String colId) {
- this.currType = colId;
- }
-
- @Override
- public Font getFont(Object element) {
- // Current user as bold
- if (UserAdminUtils.isCurrentUser(((User) element))) {
- if (bold == null)
- bold = JFaceResources.getFontRegistry().defaultFontDescriptor().setStyle(SWT.BOLD)
- .createFont(Display.getCurrent());
- return bold;
- }
- return null;
- }
-
- @Override
- public Image getImage(Object element) {
- if (COL_ICON.equals(currType)) {
- User user = (User) element;
- String dn = user.getName();
- if (dn.endsWith(NodeConstants.ROLES_BASEDN))
- return UsersImages.ICON_ROLE;
- else if (user.getType() == Role.GROUP)
- return UsersImages.ICON_GROUP;
- else
- return UsersImages.ICON_USER;
- } else
- return null;
- }
-
- @Override
- public String getText(Object element) {
- User user = (User) element;
- return getText(user);
-
- }
-
- public String getText(User user) {
- if (COL_DN.equals(currType))
- return user.getName();
- else if (COL_DISPLAY_NAME.equals(currType))
- return UserAdminUtils.getCommonName(user);
- else if (COL_DOMAIN.equals(currType))
- return UserAdminUtils.getDomainName(user);
- else
- return "";
- }
-}
+++ /dev/null
-package org.argeo.cms.ui.useradmin;
-
-import org.argeo.cms.ui.theme.CmsImages;
-import org.eclipse.swt.graphics.Image;
-
-/** Specific users icons. */
-public class UsersImages {
- private final static String PREFIX = "icons/";
-
- public final static Image ICON_USER = CmsImages.createImg(PREFIX + "person.png");
- public final static Image ICON_GROUP = CmsImages.createImg(PREFIX + "group.png");
- public final static Image ICON_ROLE = CmsImages.createImg(PREFIX + "role.gif");
- public final static Image ICON_CHANGE_PASSWORD = CmsImages.createImg(PREFIX + "security.gif");
-}
+++ /dev/null
-/** SWT/JFace users management components. */
-package org.argeo.cms.ui.useradmin;
\ No newline at end of file
+++ /dev/null
-package org.argeo.cms.ui.util;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.argeo.cms.ui.CmsTheme;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.ImageData;
-import org.eclipse.swt.widgets.Display;
-
-/** Centralises some generic {@link CmsTheme} patterns. */
-public abstract class AbstractCmsTheme implements CmsTheme {
- private Map<String, ImageData> imageCache = new HashMap<>();
-
- private Map<String, Map<Integer, String>> iconPaths = new HashMap<>();
-
- private Integer defaultIconSize = 16;
-
- public Image getImage(String path) {
- if (!imageCache.containsKey(path)) {
- try (InputStream in = getResourceAsStream(path)) {
- if (in == null)
- return null;
- ImageData imageData = new ImageData(in);
- imageCache.put(path, imageData);
- } catch (IOException e) {
- throw new IllegalStateException(e);
- }
- }
- ImageData imageData = imageCache.get(path);
- Image image = new Image(Display.getCurrent(), imageData);
- return image;
- }
-
- @Override
- public Image getIcon(String name, Integer preferredSize) {
- if (preferredSize == null)
- preferredSize = defaultIconSize;
- Map<Integer, String> subCache;
- if (!iconPaths.containsKey(name))
- subCache = new HashMap<>();
- else
- subCache = iconPaths.get(name);
- Image image = null;
- if (!subCache.containsKey(preferredSize)) {
- Image bestMatchSoFar = null;
- paths: for (String p : getImagesPaths()) {
- int lastSlash = p.lastIndexOf('/');
- String fileName = p;
- if (lastSlash >= 0)
- fileName = p.substring(lastSlash + 1);
- int lastDot = fileName.lastIndexOf('.');
- if (lastDot >= 0)
- fileName = fileName.substring(0, lastDot);
- if (fileName.equals(name)) {// matched
- Image img = getImage(p);
- int width = img.getBounds().width;
- if (width == preferredSize) {// perfect match
- subCache.put(preferredSize, p);
- image = img;
- break paths;
- }
- if (bestMatchSoFar == null) {
- bestMatchSoFar = img;
- } else {
- if (Math.abs(width - preferredSize) < Math
- .abs(bestMatchSoFar.getBounds().width - preferredSize))
- bestMatchSoFar = img;
- }
- }
- }
-
- if (image == null)
- image = bestMatchSoFar;
- } else {
- image = getImage(subCache.get(preferredSize));
- }
-
- if (image != null && !iconPaths.containsKey(name))
- iconPaths.put(name, subCache);
-
- return image;
- }
-
- @Override
- public Integer getDefaultIconSize() {
- return defaultIconSize;
- }
-
-}
+++ /dev/null
-package org.argeo.cms.ui.util;
-
-import static java.nio.charset.StandardCharsets.UTF_8;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.URL;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.stream.Collectors;
-
-import org.apache.commons.io.IOUtils;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-
-/**
- * Simplifies the theming of an app (only RAP is supported at this stage).<br>
- *
- * Additional fonts listed in <code>/fonts.txt</code>.<br>
- * Additional (standard CSS) header in <code>/header.css</code>.<br>
- * RAP specific CSS files in <code>/rap/*.css</code>.<br>
- * All images added as additional resources based on extensions
- * <code>/ ** /*.{png,gif,jpeg,...}</code>.<br>
- */
-public class BundleCmsTheme extends AbstractCmsTheme {
- public final static String DEFAULT_CMS_THEME_BUNDLE = "org.argeo.theme.argeo2";
-
- public final static String CMS_THEME_PROPERTY = "argeo.cms.theme";
- public final static String CMS_THEME_BUNDLE_PROPERTY = "argeo.cms.theme.bundle";
-
- private final static String HEADER_CSS = "header.css";
- private final static String FONTS_TXT = "fonts.txt";
- private final static String BODY_HTML = "body.html";
-
-// private final static Log log = LogFactory.getLog(BundleCmsTheme.class);
-
- private String themeId;
- private Set<String> webCssPaths = new TreeSet<>();
- private Set<String> rapCssPaths = new TreeSet<>();
- private Set<String> swtCssPaths = new TreeSet<>();
- private Set<String> imagesPaths = new TreeSet<>();
- private Set<String> fontsPaths = new TreeSet<>();
-
- private String headerCss;
- private List<String> fonts = new ArrayList<>();
-
- private String bodyHtml="<body></body>";
-
- private String basePath;
- private String styleCssPath;
-// private String webCssPath;
-// private String rapCssPath;
-// private String swtCssPath;
- private Bundle themeBundle;
-
- public BundleCmsTheme() {
-
- }
-
- public void init(BundleContext bundleContext, Map<String, String> properties) {
- initResources(bundleContext, null);
- }
-
- public void destroy(BundleContext bundleContext, Map<String, String> properties) {
-
- }
-
- @Deprecated
- public BundleCmsTheme(BundleContext bundleContext) {
- this(bundleContext, null);
- }
-
- @Deprecated
- public BundleCmsTheme(BundleContext bundleContext, String symbolicName) {
- initResources(bundleContext, symbolicName);
- }
-
- private void initResources(BundleContext bundleContext, String symbolicName) {
- if (symbolicName == null) {
- themeBundle = bundleContext.getBundle();
-// basePath = "/theme/";
-// cssPath = basePath;
- } else {
- themeBundle = findThemeBundle(bundleContext, symbolicName);
- }
- basePath = "/";
- styleCssPath = "/style/";
-// webCssPath = "/css/";
-// rapCssPath = "/rap/";
-// swtCssPath = "/swt/";
-// this.themeId = RWT.DEFAULT_THEME_ID;
- this.themeId = themeBundle.getSymbolicName();
- webCssPaths = addCss(themeBundle, "/css/");
- rapCssPaths = addCss(themeBundle, "/rap/");
- swtCssPaths = addCss(themeBundle, "/swt/");
- addImages("*.png");
- addImages("*.gif");
- addImages("*.jpg");
- addImages("*.jpeg");
- addImages("*.svg");
- addImages("*.ico");
-
- addFonts("*.woff");
- addFonts("*.woff2");
-
- // fonts
- URL fontsUrl = themeBundle.getEntry(basePath + FONTS_TXT);
- if (fontsUrl != null) {
- loadFontsUrl(fontsUrl);
- }
-
- // common CSS header (plain CSS)
- URL headerCssUrl = themeBundle.getEntry(basePath + HEADER_CSS);
- if (headerCssUrl != null) {
- // added to plain Web CSS
- webCssPaths.add(basePath + HEADER_CSS);
- // and it will also be used by RAP:
- try (BufferedReader buffer = new BufferedReader(new InputStreamReader(headerCssUrl.openStream(), UTF_8))) {
- headerCss = buffer.lines().collect(Collectors.joining("\n"));
- } catch (IOException e) {
- throw new IllegalArgumentException("Cannot read " + headerCssUrl, e);
- }
- }
-
- // body
- URL bodyUrl = themeBundle.getEntry(basePath + BODY_HTML);
- if (bodyUrl != null) {
- loadBodyHtml(bodyUrl);
- }
-}
-
- public String getHtmlHeaders() {
- StringBuilder sb = new StringBuilder();
- if (headerCss != null) {
- sb.append("<style type='text/css'>\n");
- sb.append(headerCss);
- sb.append("\n</style>\n");
- }
- for (String link : fonts) {
- sb.append("<link rel='stylesheet' href='");
- sb.append(link);
- sb.append("'/>\n");
- }
- if (sb.length() == 0)
- return null;
- else
- return sb.toString();
- }
-
-
-
- @Override
- public String getBodyHtml() {
- return bodyHtml;
- }
-
- Set<String> addCss(Bundle themeBundle, String path) {
- Set<String> paths = new TreeSet<>();
-
- // common CSS
- Enumeration<URL> commonResources = themeBundle.findEntries(styleCssPath, "*.css", true);
- if (commonResources != null) {
- while (commonResources.hasMoreElements()) {
- String resource = commonResources.nextElement().getPath();
- // remove first '/' so that RWT registers it
- resource = resource.substring(1);
- if (!resource.endsWith("/")) {
- paths.add(resource);
- }
- }
- }
-
- // specific CSS
- Enumeration<URL> themeResources = themeBundle.findEntries(path, "*.css", true);
- if (themeResources != null) {
- while (themeResources.hasMoreElements()) {
- String resource = themeResources.nextElement().getPath();
- // remove first '/' so that RWT registers it
- resource = resource.substring(1);
- if (!resource.endsWith("/")) {
- paths.add(resource);
- }
- }
- }
- return paths;
- }
-
- void loadFontsUrl(URL url) {
- try (BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream(), UTF_8))) {
- String line = null;
- while ((line = in.readLine()) != null) {
- line = line.trim();
- if (!line.equals("") && !line.startsWith("#")) {
- fonts.add(line);
- }
- }
- } catch (IOException e) {
- throw new IllegalArgumentException("Cannot load URL " + url, e);
- }
- }
-
- void loadBodyHtml(URL url) {
- try (BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream(), UTF_8))) {
- bodyHtml= IOUtils.toString(url,StandardCharsets.UTF_8);
- } catch (IOException e) {
- throw new IllegalArgumentException("Cannot load URL " + url, e);
- }
- }
-
- void addImages(String pattern) {
- Enumeration<URL> themeResources = themeBundle.findEntries(basePath, pattern, true);
- if (themeResources == null)
- return;
- while (themeResources.hasMoreElements()) {
- String resource = themeResources.nextElement().getPath();
- // remove first '/' so that RWT registers it
- resource = resource.substring(1);
- if (!resource.endsWith("/")) {
-// if (resources.containsKey(resource))
-// log.warn("Overriding " + resource + " from " + themeBundle.getSymbolicName());
-// resources.put(resource, themeBRL);
- imagesPaths.add(resource);
- }
-
- }
-
- }
-
- void addFonts(String pattern) {
- Enumeration<URL> themeResources = themeBundle.findEntries(basePath, pattern, true);
- if (themeResources == null)
- return;
- while (themeResources.hasMoreElements()) {
- String resource = themeResources.nextElement().getPath();
- // remove first '/' so that RWT registers it
- resource = resource.substring(1);
- if (!resource.endsWith("/")) {
-// if (resources.containsKey(resource))
-// log.warn("Overriding " + resource + " from " + themeBundle.getSymbolicName());
-// resources.put(resource, themeBRL);
- fontsPaths.add(resource);
- }
-
- }
-
- }
-
- @Override
- public InputStream getResourceAsStream(String resourceName) throws IOException {
- URL res = themeBundle.getEntry(resourceName);
- if (res == null) {
- res = themeBundle.getResource(resourceName);
- if (res == null)
- return null;
-// throw new IllegalArgumentException(
-// "Resource " + resourceName + " not found in bundle " + themeBundle.getSymbolicName());
- }
- return res.openStream();
- }
-
- public String getThemeId() {
- return themeId;
- }
-
-// public void setThemeId(String themeId) {
-// this.themeId = themeId;
-// }
-//
-// public String getBasePath() {
-// return basePath;
-// }
-//
-// public void setBasePath(String basePath) {
-// this.basePath = basePath;
-// }
-//
-// public String getRapCssPath() {
-// return rapCssPath;
-// }
-//
-// public void setRapCssPath(String cssPath) {
-// this.rapCssPath = cssPath;
-// }
-
- @Override
- public Set<String> getWebCssPaths() {
- return webCssPaths;
- }
-
- @Override
- public Set<String> getRapCssPaths() {
- return rapCssPaths;
- }
-
- @Override
- public Set<String> getSwtCssPaths() {
- return swtCssPaths;
- }
-
- @Override
- public Set<String> getImagesPaths() {
- return imagesPaths;
- }
-
- @Override
- public Set<String> getFontsPaths() {
- return fontsPaths;
- }
-
- @Override
- public InputStream loadPath(String path) throws IOException {
- URL url = themeBundle.getResource(path);
- if (url == null)
- throw new IllegalArgumentException(
- "Path " + path + " not found in bundle " + themeBundle.getSymbolicName());
- return url.openStream();
- }
-
- private static Bundle findThemeBundle(BundleContext bundleContext, String themeId) {
- if (themeId == null)
- return null;
- // TODO optimize
- // TODO deal with multiple versions
- Bundle themeBundle = null;
- if (themeId != null) {
- for (Bundle bundle : bundleContext.getBundles())
- if (themeId.equals(bundle.getSymbolicName())) {
- themeBundle = bundle;
- break;
- }
- }
- return themeBundle;
- }
-
- @Override
- public int hashCode() {
- return themeId.hashCode();
- }
-
- @Override
- public String toString() {
- return "Bundle CMS Theme " + themeId;
- }
-
-}
+++ /dev/null
-package org.argeo.cms.ui.util;
-
-import org.argeo.cms.ui.CmsView;
-
-/**
- * Can be applied to {@link Enum}s in order to define events used by
- * {@link CmsView#sendEvent(String, java.util.Map)}.
- */
-public interface CmsEvent {
- String name();
-
- default String topic() {
- return getTopicBase() + "/" + name();
- }
-
- default String getTopicBase() {
- return "argeo/cms";
- }
-
-
-}
+++ /dev/null
-package org.argeo.cms.ui.util;
-
-import org.argeo.cms.ui.CmsTheme;
-import org.eclipse.swt.graphics.Image;
-
-/** Can be applied to {@link Enum}s in order to generated {@link Image}s. */
-public interface CmsIcon {
- String name();
-
- default Image getSmallIcon(CmsTheme theme) {
- return theme.getIcon(name(), getSmallIconSize());
- }
-
- default Image getBigIcon(CmsTheme theme) {
- return theme.getIcon(name(), getBigIconSize());
- }
-
- default Integer getSmallIconSize() {
- return 16;
- }
-
- default Integer getBigIconSize() {
- return 32;
- }
-}
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.CmsStyle;
import org.argeo.cms.auth.CurrentUser;
import org.argeo.cms.jcr.CmsJcrUtils;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.ui.CmsUiProvider;
import org.argeo.jcr.JcrException;
import org.eclipse.rap.rwt.RWT;
// }
Composite comp = new Composite(parent, SWT.NONE);
- comp.setLayout(CmsUiUtils.noSpaceGridLayout());
+ comp.setLayout(CmsSwtUtils.noSpaceGridLayout());
Label link = new Label(comp, SWT.NONE);
- CmsUiUtils.markup(link);
+ CmsSwtUtils.markup(link);
GridData layoutData = new GridData(horizontalAlignment, verticalAlignment, false, false);
if (image != null) {
if (imageHeight != null)
}
link.setLayoutData(layoutData);
- CmsUiUtils.style(comp, style != null ? style : getDefaultStyle());
- CmsUiUtils.style(link, style != null ? style : getDefaultStyle());
+ CmsSwtUtils.style(comp, style != null ? style : getDefaultStyle());
+ CmsSwtUtils.style(link, style != null ? style : getDefaultStyle());
// label
StringBuilder labelText = new StringBuilder();
package org.argeo.cms.ui.util;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
private Composite supportArea;
public CmsPane(Composite parent, int style) {
- parent.setLayout(CmsUiUtils.noSpaceGridLayout());
+ parent.setLayout(CmsSwtUtils.noSpaceGridLayout());
// qaArea = new Composite(parent, SWT.NONE);
// qaArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+++ /dev/null
-package org.argeo.cms.ui.util;
-
-/** Can be applied to {@link Enum}s in order to generate (CSS) class names. */
-public interface CmsStyle {
- String name();
-
- /** @deprecated use {@link #style()} instead. */
- @Deprecated
- default String toStyleClass() {
- return style();
- }
-
- default String style() {
- String classPrefix = getClassPrefix();
- return "".equals(classPrefix) ? name() : classPrefix + "-" + name();
- }
-
- default String getClassPrefix() {
- return "";
- }
-
-}
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
-import java.util.HashMap;
-import java.util.Map;
import java.util.StringTokenizer;
import javax.jcr.Node;
import javax.servlet.http.HttpServletRequest;
import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.Cms2DSize;
+import org.argeo.api.cms.CmsView;
import org.argeo.cms.jcr.CmsJcrUtils;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.ui.CmsConstants;
-import org.argeo.cms.ui.CmsView;
-import org.argeo.eclipse.ui.Selected;
-import org.argeo.eclipse.ui.specific.EclipseUiSpecificUtils;
-import org.argeo.jcr.JcrException;
import org.argeo.jcr.JcrUtils;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.rap.rwt.service.ResourceManager;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.layout.FormAttachment;
-import org.eclipse.swt.layout.FormData;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowData;
-import org.eclipse.swt.layout.RowLayout;
-import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.swt.widgets.Widget;
/** Static utilities for the CMS framework. */
-public class CmsUiUtils implements CmsConstants {
+public class CmsUiUtils {
// private final static Log log = LogFactory.getLog(CmsUiUtils.class);
/*
* CMS VIEW
*/
- /** Sends an event via {@link CmsView#sendEvent(String, Map)}. */
- public static void sendEventOnSelect(Control control, String topic, Map<String, Object> properties) {
- SelectionListener listener = (Selected) (e) -> {
- CmsView.getCmsView(control.getParent()).sendEvent(topic, properties);
- };
- if (control instanceof Button) {
- ((Button) control).addSelectionListener(listener);
- } else
- throw new UnsupportedOperationException("Control type " + control.getClass() + " is not supported.");
- }
-
- /**
- * Convenience method to sends an event via
- * {@link CmsView#sendEvent(String, Map)}.
- */
- public static void sendEventOnSelect(Control control, String topic, String key, Object value) {
- Map<String, Object> properties = new HashMap<>();
- properties.put(key, value);
- sendEventOnSelect(control, topic, properties);
- }
-
/**
* The CMS view related to this display, or null if none is available from this
* call.
*
- * @deprecated Use {@link CmsView#getCmsView(Composite)} instead.
+ * @deprecated Use {@link CmsSwtUtils#getCmsView(Composite)} instead.
*/
@Deprecated
public static CmsView getCmsView() {
// return UiContext.getData(CmsView.class.getName());
- return CmsView.getCmsView(Display.getCurrent().getActiveShell());
+ return CmsSwtUtils.getCmsView(Display.getCurrent().getActiveShell());
}
public static StringBuilder getServerBaseUrl(HttpServletRequest request) {
}
//
- public static String getDataUrl(Node node, HttpServletRequest request) throws RepositoryException {
+ public static String getDataUrl(Node node, HttpServletRequest request) {
try {
StringBuilder buf = getServerBaseUrl(request);
buf.append(getDataPath(node));
}
/** A path in the node repository */
- public static String getDataPath(Node node) throws RepositoryException {
+ public static String getDataPath(Node node) {
return getDataPath(NodeConstants.EGO_REPOSITORY, node);
}
- public static String getDataPath(String cn, Node node) throws RepositoryException {
+ public static String getDataPath(String cn, Node node) {
return CmsJcrUtils.getDataPath(cn, node);
}
/** Clean reserved URL characters for use in HTTP links. */
- public static String getDataPathForUrl(Node node) throws RepositoryException {
+ public static String getDataPathForUrl(Node node) {
return cleanPathForUrl(getDataPath(node));
}
/** Clean reserved URL characters for use in HTTP links. */
- public static String cleanPathForUrl(String path) throws RepositoryException {
+ public static String cleanPathForUrl(String path) {
StringTokenizer st = new StringTokenizer(path, "/");
StringBuilder sb = new StringBuilder();
while (st.hasMoreElements()) {
@Deprecated
public static RowData ROW_DATA_16px = new RowData(16, 16);
- /*
- * GRID LAYOUT
- */
- public static GridLayout noSpaceGridLayout() {
- return noSpaceGridLayout(new GridLayout());
- }
-
- public static GridLayout noSpaceGridLayout(int columns) {
- return noSpaceGridLayout(new GridLayout(columns, false));
- }
-
- /** @return the same layout, with spaces removed. */
- public static GridLayout noSpaceGridLayout(GridLayout layout) {
- layout.horizontalSpacing = 0;
- layout.verticalSpacing = 0;
- layout.marginWidth = 0;
- layout.marginHeight = 0;
- return layout;
- }
-
- public static GridData fillAll() {
- return new GridData(SWT.FILL, SWT.FILL, true, true);
- }
-
- public static GridData fillWidth() {
- return grabWidth(SWT.FILL, SWT.FILL);
- }
-
- public static GridData grabWidth(int horizontalAlignment, int verticalAlignment) {
- return new GridData(horizontalAlignment, horizontalAlignment, true, false);
- }
-
- public static GridData fillHeight() {
- return grabHeight(SWT.FILL, SWT.FILL);
- }
-
- public static GridData grabHeight(int horizontalAlignment, int verticalAlignment) {
- return new GridData(horizontalAlignment, horizontalAlignment, false, true);
- }
-
- /*
- * ROW LAYOUT
- */
- /** @return the same layout, with margins removed. */
- public static RowLayout noMarginsRowLayout(RowLayout rowLayout) {
- rowLayout.marginTop = 0;
- rowLayout.marginBottom = 0;
- rowLayout.marginLeft = 0;
- rowLayout.marginRight = 0;
- return rowLayout;
- }
-
- public static RowLayout noMarginsRowLayout(int type) {
- return noMarginsRowLayout(new RowLayout(type));
- }
-
- public static RowData rowData16px() {
- return new RowData(16, 16);
- }
+
/*
* FORM LAYOUT
*/
- public static FormData coverAll() {
- 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);
- return fdLabel;
- }
-
- /*
- * STYLING
- */
-
- /** Style widget */
- public static <T extends Widget> T style(T widget, String style) {
- if (style == null)
- return widget;// does nothing
- EclipseUiSpecificUtils.setStyleData(widget, style);
- if (widget instanceof Control) {
- CmsView cmsView = CmsView.getCmsView((Control) widget);
- if (cmsView != null)
- cmsView.applyStyles(widget);
- }
- return widget;
- }
-
- /** Style widget */
- public static <T extends Widget> T style(T widget, CmsStyle style) {
- return style(widget, style.toStyleClass());
- }
-
- /** Enable markups on widget */
- public static <T extends Widget> T markup(T widget) {
- EclipseUiSpecificUtils.setMarkupData(widget);
- return widget;
- }
-
- /** Disable markup validation. */
- public static <T extends Widget> T disableMarkupValidation(T widget) {
- EclipseUiSpecificUtils.setMarkupValidationDisabledData(widget);
- return widget;
- }
-
- /**
- * Apply markup and set text on {@link Label}, {@link Button}, {@link Text}.
- *
- * @param widget the widget to style and to use in order to display text
- * @param txt the object to display via its <code>toString()</code> method.
- * This argument should not be null, but if it is null and
- * assertions are disabled "<null>" is displayed instead; if
- * assertions are enabled the call will fail.
- *
- * @see #markup(Widget)
- */
- public static <T extends Widget> T text(T widget, Object txt) {
- assert txt != null;
- String str = txt != null ? txt.toString() : "<null>";
- markup(widget);
- if (widget instanceof Label)
- ((Label) widget).setText(str);
- else if (widget instanceof Button)
- ((Button) widget).setText(str);
- else if (widget instanceof Text)
- ((Text) widget).setText(str);
- else
- throw new IllegalArgumentException("Unsupported widget type " + widget.getClass());
- return widget;
- }
-
- /** A {@link Label} with markup activated. */
- public static Label lbl(Composite parent, Object txt) {
- return text(new Label(parent, SWT.NONE), txt);
- }
-
- /** A read-only {@link Text} whose content can be copy/pasted. */
- public static Text txt(Composite parent, Object txt) {
- return text(new Text(parent, SWT.NONE), txt);
- }
+
@Deprecated
public static void setItemHeight(Table table, int height) {
table.setData(CmsConstants.ITEM_HEIGHT, height);
}
- /** Dispose all children of a Composite */
- public static void clear(Composite composite) {
- if (composite.isDisposed())
- return;
- for (Control child : composite.getChildren())
- child.dispose();
- }
-
//
// JCR
//
}
// IMAGES
+
public static String img(Node fileNode, String width, String height) {
return img(null, fileNode, width, height);
}
public static String img(String serverBase, Node fileNode, String width, String height) {
// String src = (serverBase != null ? serverBase : "") + NodeUtils.getDataPath(fileNode);
String src;
- try {
- src = (serverBase != null ? serverBase : "") + getDataPathForUrl(fileNode);
- } catch (RepositoryException e) {
- throw new JcrException("Cannot get URL data path for " + fileNode, e);
- }
+ src = (serverBase != null ? serverBase : "") + getDataPathForUrl(fileNode);
return imgBuilder(src, width, height).append("/>").toString();
}
return imgBuilder(src, width, height).append("/>").toString();
}
- public static String img(String src, Point size) {
- return img(src, Integer.toString(size.x), Integer.toString(size.y));
+ public static String img(String src, Cms2DSize size) {
+ return img(src, Integer.toString(size.getWidth()), Integer.toString(size.getHeight()));
}
public static StringBuilder imgBuilder(String src, String width, String height) {
.append("' src='").append(src).append("'");
}
- public static String noImg(Point size) {
+ public static String noImg(Cms2DSize size) {
ResourceManager rm = RWT.getResourceManager();
- return CmsUiUtils.img(rm.getLocation(NO_IMAGE), size);
+ return CmsUiUtils.img(rm.getLocation(CmsConstants.NO_IMAGE), size);
}
public static String noImg() {
- return noImg(NO_IMAGE_SIZE);
+ return noImg(CmsConstants.NO_IMAGE_SIZE);
}
- public static Image noImage(Point size) {
+ public static Image noImage(Cms2DSize size) {
ResourceManager rm = RWT.getResourceManager();
InputStream in = null;
try {
- in = rm.getRegisteredContent(NO_IMAGE);
+ in = rm.getRegisteredContent(CmsConstants.NO_IMAGE);
ImageData id = new ImageData(in);
- ImageData scaled = id.scaledTo(size.x, size.y);
+ ImageData scaled = id.scaledTo(size.getWidth(), size.getHeight());
Image image = new Image(Display.getCurrent(), scaled);
return image;
} finally {
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.net.MalformedURLException;
-import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.argeo.cms.ui.CmsImageManager;
+import org.argeo.api.cms.Cms2DSize;
+import org.argeo.api.cms.CmsImageManager;
+import org.argeo.jcr.JcrException;
import org.argeo.jcr.JcrUtils;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.rap.rwt.service.ResourceManager;
import org.eclipse.swt.widgets.Label;
/** Manages only public images so far. */
-public class DefaultImageManager implements CmsImageManager {
+public class DefaultImageManager implements CmsImageManager<Control, Node> {
private final static Log log = LogFactory.getLog(DefaultImageManager.class);
// private MimetypesFileTypeMap fileTypeMap = new MimetypesFileTypeMap();
- public Boolean load(Node node, Control control, Point preferredSize) throws RepositoryException {
- Point imageSize = getImageSize(node);
- Point size;
+ public Boolean load(Node node, Control control, Cms2DSize preferredSize) {
+ Cms2DSize imageSize = getImageSize(node);
+ Cms2DSize size;
String imgTag = null;
- if (preferredSize == null || imageSize.x == 0 || imageSize.y == 0
- || (preferredSize.x == 0 && preferredSize.y == 0)) {
- if (imageSize.x != 0 && imageSize.y != 0) {
+ if (preferredSize == null || imageSize.getWidth() == 0 || imageSize.getHeight() == 0
+ || (preferredSize.getWidth() == 0 && preferredSize.getHeight() == 0)) {
+ if (imageSize.getWidth() != 0 && imageSize.getHeight() != 0) {
// actual image size if completely known
size = imageSize;
} else {
imgTag = CmsUiUtils.noImg(size);
}
- } else if (preferredSize.x != 0 && preferredSize.y != 0) {
+ } else if (preferredSize.getWidth() != 0 && preferredSize.getHeight() != 0) {
// given size if completely provided
size = preferredSize;
} else {
// at this stage :
// image is completely known
- assert imageSize.x != 0 && imageSize.y != 0;
+ assert imageSize.getWidth() != 0 && imageSize.getHeight() != 0;
// one and only one of the dimension as been specified
- assert preferredSize.x == 0 || preferredSize.y == 0;
+ assert preferredSize.getWidth() == 0 || preferredSize.getHeight() == 0;
size = resizeTo(imageSize, preferredSize);
}
} else if (control instanceof FileUpload) {
FileUpload lbl = (FileUpload) control;
lbl.setImage(CmsUiUtils.noImage(size));
- lbl.setSize(size);
+ lbl.setSize(new Point(size.getWidth(), size.getHeight()));
return loaded;
} else
loaded = false;
return loaded;
}
- private Point resizeTo(Point orig, Point constraints) {
- if (constraints.x != 0 && constraints.y != 0) {
+ private Cms2DSize resizeTo(Cms2DSize orig, Cms2DSize constraints) {
+ if (constraints.getWidth() != 0 && constraints.getHeight() != 0) {
return constraints;
- } else if (constraints.x == 0 && constraints.y == 0) {
+ } else if (constraints.getWidth() == 0 && constraints.getHeight() == 0) {
return orig;
- } else if (constraints.y == 0) {// force width
- return new Point(constraints.x, scale(orig.y, orig.x, constraints.x));
- } else if (constraints.x == 0) {// force height
- return new Point(scale(orig.x, orig.y, constraints.y), constraints.y);
+ } else if (constraints.getHeight() == 0) {// force width
+ return new Cms2DSize(constraints.getWidth(),
+ scale(orig.getHeight(), orig.getWidth(), constraints.getWidth()));
+ } else if (constraints.getWidth() == 0) {// force height
+ return new Cms2DSize(scale(orig.getWidth(), orig.getHeight(), constraints.getHeight()),
+ constraints.getHeight());
}
throw new IllegalArgumentException("Cannot resize " + orig + " to " + constraints);
}
return ((float) a) / ((float) b);
}
- public Point getImageSize(Node node) throws RepositoryException {
+ public Cms2DSize getImageSize(Node node) {
// TODO optimise
Image image = getSwtImage(node);
- return new Point(image.getBounds().width, image.getBounds().height);
+ return new Cms2DSize(image.getBounds().width, image.getBounds().height);
}
/** @return null if not available */
@Override
- public String getImageTag(Node node) throws RepositoryException {
+ public String getImageTag(Node node) {
return getImageTag(node, getImageSize(node));
}
- private String getImageTag(Node node, Point size) throws RepositoryException {
+ private String getImageTag(Node node, Cms2DSize size) {
StringBuilder buf = getImageTagBuilder(node, size);
if (buf == null)
return null;
/** @return null if not available */
@Override
- public StringBuilder getImageTagBuilder(Node node, Point size) throws RepositoryException {
- return getImageTagBuilder(node, Integer.toString(size.x), Integer.toString(size.y));
+ public StringBuilder getImageTagBuilder(Node node, Cms2DSize size) {
+ return getImageTagBuilder(node, Integer.toString(size.getWidth()), Integer.toString(size.getHeight()));
}
/** @return null if not available */
- private StringBuilder getImageTagBuilder(Node node, String width, String height) throws RepositoryException {
+ private StringBuilder getImageTagBuilder(Node node, String width, String height) {
String url = getImageUrl(node);
if (url == null)
return null;
/** @return null if not available */
@Override
- public String getImageUrl(Node node) throws RepositoryException {
+ public String getImageUrl(Node node) {
return CmsUiUtils.getDataPathForUrl(node);
}
- protected String getResourceName(Node node) throws RepositoryException {
- String workspace = node.getSession().getWorkspace().getName();
- if (node.hasNode(JCR_CONTENT))
- return workspace + '_' + node.getNode(JCR_CONTENT).getIdentifier();
- else
- return workspace + '_' + node.getIdentifier();
+ protected String getResourceName(Node node) {
+ try {
+ String workspace = node.getSession().getWorkspace().getName();
+ if (node.hasNode(JCR_CONTENT))
+ return workspace + '_' + node.getNode(JCR_CONTENT).getIdentifier();
+ else
+ return workspace + '_' + node.getIdentifier();
+ } catch (RepositoryException e) {
+ throw new JcrException(e);
+ }
}
- public Binary getImageBinary(Node node) throws RepositoryException {
- if (node.isNodeType(NT_FILE)) {
- return node.getNode(JCR_CONTENT).getProperty(JCR_DATA).getBinary();
- } else {
- return null;
+ public Binary getImageBinary(Node node) {
+ try {
+ if (node.isNodeType(NT_FILE)) {
+ return node.getNode(JCR_CONTENT).getProperty(JCR_DATA).getBinary();
+ } else {
+ return null;
+ }
+ } catch (RepositoryException e) {
+ throw new JcrException(e);
}
}
- public Image getSwtImage(Node node) throws RepositoryException {
+ public Image getSwtImage(Node node) {
InputStream inputStream = null;
Binary binary = getImageBinary(node);
if (binary == null)
try {
inputStream = binary.getStream();
return new Image(Display.getCurrent(), inputStream);
+ } catch (RepositoryException e) {
+ throw new JcrException(e);
} finally {
IOUtils.closeQuietly(inputStream);
JcrUtils.closeQuietly(binary);
}
@Override
- public String uploadImage(Node context, Node parentNode, String fileName, InputStream in, String contentType)
- throws RepositoryException {
+ public String uploadImage(Node context, Node parentNode, String fileName, InputStream in, String contentType) {
InputStream inputStream = null;
try {
String previousResourceName = null;
return CmsUiUtils.getDataPath(fileNode);
} catch (IOException e) {
throw new RuntimeException("Cannot upload image " + fileName + " in " + parentNode, e);
+ } catch (RepositoryException e) {
+ throw new JcrException(e);
} finally {
IOUtils.closeQuietly(inputStream);
}
+++ /dev/null
-package org.argeo.cms.ui.util;
-
-import java.util.Locale;
-import java.util.UUID;
-
-import javax.security.auth.Subject;
-import javax.security.auth.login.LoginContext;
-import javax.security.auth.login.LoginException;
-import javax.servlet.http.HttpServletRequest;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.api.NodeConstants;
-import org.argeo.cms.CmsException;
-import org.argeo.cms.auth.CurrentUser;
-import org.argeo.cms.ui.CmsImageManager;
-import org.argeo.cms.ui.CmsView;
-import org.argeo.cms.ui.UxContext;
-import org.argeo.cms.ui.widgets.auth.CmsLogin;
-import org.argeo.cms.ui.widgets.auth.CmsLoginShell;
-import org.argeo.eclipse.ui.specific.UiContext;
-import org.eclipse.rap.rwt.RWT;
-import org.eclipse.rap.rwt.application.EntryPoint;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-
-public class LoginEntryPoint implements EntryPoint, CmsView {
- protected final static String HEADER_WWW_AUTHENTICATE = "WWW-Authenticate";
- protected final static String HEADER_AUTHORIZATION = "Authorization";
- private final static Log log = LogFactory.getLog(LoginEntryPoint.class);
- private LoginContext loginContext;
- private UxContext uxContext = null;
- private String uid;
-
- @Override
- public int createUI() {
- uid = UUID.randomUUID().toString();
- final Display display = createDisplay();
-// UiContext.setData(CmsView.KEY, this);
-
- CmsLoginShell loginShell = createCmsLoginShell();
- CmsView.registerCmsView(loginShell.getShell(), this);
- try {
- // try pre-auth
- loginContext = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, loginShell);
- loginContext.login();
- } catch (LoginException e) {
- loginShell.createUi();
- loginShell.open();
-
- // HttpServletRequest request = RWT.getRequest();
- // String authorization = request.getHeader(HEADER_AUTHORIZATION);
- // if (authorization == null ||
- // !authorization.startsWith("Negotiate")) {
- // HttpServletResponse response = RWT.getResponse();
- // response.setStatus(401);
- // response.setHeader(HEADER_WWW_AUTHENTICATE, "Negotiate");
- // response.setDateHeader("Date", System.currentTimeMillis());
- // response.setDateHeader("Expires", System.currentTimeMillis() +
- // (24 * 60 * 60 * 1000));
- // response.setHeader("Accept-Ranges", "bytes");
- // response.setHeader("Connection", "Keep-Alive");
- // response.setHeader("Keep-Alive", "timeout=5, max=97");
- // // response.setContentType("text/html; charset=UTF-8");
- // }
-
- while (!loginShell.getShell().isDisposed()) {
- if (!display.readAndDispatch())
- display.sleep();
- }
- }
-
- if (CurrentUser.getUsername(getSubject()) == null)
- return -1;
- uxContext = new SimpleUxContext();
- return postLogin();
- }
-
- protected Display createDisplay() {
- return new Display();
- }
-
- protected int postLogin() {
- return 0;
- }
-
- protected HttpServletRequest getRequest() {
- return RWT.getRequest();
- }
-
- protected CmsLoginShell createCmsLoginShell() {
- return new CmsLoginShell(this) {
-
- @Override
- public void createContents(Composite parent) {
- LoginEntryPoint.this.createLoginPage(parent, this);
- }
-
- @Override
- protected void extendsCredentialsBlock(Composite credentialsBlock, Locale selectedLocale,
- SelectionListener loginSelectionListener) {
- LoginEntryPoint.this.extendsCredentialsBlock(credentialsBlock, selectedLocale, loginSelectionListener);
- }
-
- };
- }
-
- /**
- * To be overridden. CmsLogin#createCredentialsBlock() should be called at some
- * point in order to create the credentials composite. In order to use the
- * default layout, call CmsLogin#defaultCreateContents() but <b>not</b>
- * CmsLogin#createContent(), since it would lead to a stack overflow.
- */
- protected void createLoginPage(Composite parent, CmsLogin login) {
- login.defaultCreateContents(parent);
- }
-
- protected void extendsCredentialsBlock(Composite credentialsBlock, Locale selectedLocale,
- SelectionListener loginSelectionListener) {
-
- }
-
- @Override
- public String getUid() {
- return uid;
- }
-
- @Override
- public void navigateTo(String state) {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void authChange(LoginContext loginContext) {
- if (loginContext == null)
- throw new CmsException("Login context cannot be null");
- // logout previous login context
- if (this.loginContext != null)
- try {
- this.loginContext.logout();
- } catch (LoginException e1) {
- log.warn("Could not log out: " + e1);
- }
- this.loginContext = loginContext;
- }
-
- @Override
- public void logout() {
- if (loginContext == null)
- throw new CmsException("Login context should not bet null");
- try {
- CurrentUser.logoutCmsSession(loginContext.getSubject());
- loginContext.logout();
- } catch (LoginException e) {
- throw new CmsException("Cannot log out", e);
- }
- }
-
- @Override
- public void exception(Throwable e) {
- // TODO Auto-generated method stub
-
- }
-
- // @Override
- // public LoginContext getLoginContext() {
- // return loginContext;
- // }
-
- protected Subject getSubject() {
- return loginContext.getSubject();
- }
-
- @Override
- public boolean isAnonymous() {
- return CurrentUser.isAnonymous(getSubject());
- }
-
- @Override
- public CmsImageManager getImageManager() {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public UxContext getUxContext() {
- return uxContext;
- }
-}
\ No newline at end of file
package org.argeo.cms.ui.util;
-import org.argeo.cms.ui.CmsStyles;
+import org.argeo.cms.swt.CmsStyles;
/**
* Convenience class setting the custom style {@link CmsStyles#CMS_MENU_LINK} on
import javax.jcr.RepositoryException;
import org.argeo.cms.CmsException;
-import org.argeo.cms.ui.CmsStyles;
+import org.argeo.cms.swt.CmsStyles;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.ui.CmsUiProvider;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.swt.SWT;
Composite header = new Composite(parent, SWT.NONE);
header.setData(RWT.CUSTOM_VARIANT, CmsStyles.CMS_HEADER);
header.setBackgroundMode(SWT.INHERIT_DEFAULT);
- header.setLayout(CmsUiUtils.noSpaceGridLayout(new GridLayout(3, false)));
+ header.setLayout(CmsSwtUtils.noSpaceGridLayout(new GridLayout(3, false)));
configurePart(context, header, lead);
configurePart(context, header, center);
part.setData(RWT.CUSTOM_VARIANT, custom);
GridData gridData = new GridData(style, SWT.FILL, true, true);
part.setLayoutData(gridData);
- part.setLayout(CmsUiUtils.noSpaceGridLayout(new GridLayout(partProviders.size(), subPartsSameWidth)));
+ part.setLayout(CmsSwtUtils.noSpaceGridLayout(new GridLayout(partProviders.size(), subPartsSameWidth)));
for (CmsUiProvider uiProvider : partProviders) {
Control subPart = uiProvider.createUi(part, context);
subPart.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
import javax.jcr.Node;
import javax.jcr.RepositoryException;
-import org.argeo.cms.ui.CmsStyles;
+import org.argeo.cms.swt.CmsStyles;
import org.argeo.cms.ui.CmsUiProvider;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.swt.SWT;
package org.argeo.cms.ui.util;
+import org.argeo.api.cms.CmsStyle;
+
/** Simple styles used by the CMS UI utilities. */
public enum SimpleStyle implements CmsStyle {
link;
+++ /dev/null
-package org.argeo.cms.ui.util;
-
-import org.argeo.cms.ui.UxContext;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.widgets.Display;
-
-public class SimpleUxContext implements UxContext {
- private Point size;
- private Point small = new Point(400, 400);
-
- public SimpleUxContext() {
- this(Display.getCurrent().getBounds());
- }
-
- public SimpleUxContext(Rectangle rect) {
- this.size = new Point(rect.width, rect.height);
- }
-
- public SimpleUxContext(Point size) {
- this.size = size;
- }
-
- @Override
- public boolean isPortrait() {
- return size.x >= size.y;
- }
-
- @Override
- public boolean isLandscape() {
- return size.x < size.y;
- }
-
- @Override
- public boolean isSquare() {
- return size.x == size.y;
- }
-
- @Override
- public boolean isSmall() {
- return size.x <= small.x || size.y <= small.y;
- }
-
- @Override
- public boolean isMasterData() {
- // TODO make it configurable
- return true;
- }
-
-}
import org.apache.commons.io.IOUtils;
import org.argeo.cms.CmsException;
-import org.argeo.cms.ui.CmsStyles;
+import org.argeo.cms.swt.CmsStyles;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
.append(e.getMessage());
}
Label mailTo = new Label(pane, SWT.NONE);
- CmsUiUtils.markup(mailTo);
+ CmsSwtUtils.markup(mailTo);
mailTo.setText("<a href=\"" + mailToUrl + "\">Send details</a>");
mailTo.setLayoutData(new GridData(SWT.END, SWT.FILL, true, false));
import javax.jcr.Node;
import org.argeo.cms.CmsException;
-import org.argeo.cms.ui.widgets.auth.CmsLoginShell;
+import org.argeo.cms.swt.auth.CmsLoginShell;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.argeo.cms.CmsMsg;
import org.argeo.cms.auth.CurrentUser;
-import org.argeo.cms.ui.CmsStyles;
-import org.argeo.cms.ui.widgets.auth.CmsLoginShell;
+import org.argeo.cms.swt.CmsStyles;
+import org.argeo.cms.swt.auth.CmsLoginShell;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.MouseEvent;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.ui.CmsUiProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
Composite part = new Composite(parent, SWT.NONE);
part.setLayoutData(new GridData(SWT.LEAD, SWT.TOP, false, false));
// part.setData(RWT.CUSTOM_VARIANT, custom);
- part.setLayout(CmsUiUtils.noSpaceGridLayout());
+ part.setLayout(CmsSwtUtils.noSpaceGridLayout());
for (CmsUiProvider uiProvider : items) {
Control subPart = uiProvider.createUi(part, context);
subPart.setLayoutData(new GridData(SWT.LEAD, SWT.TOP, false, false));
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.argeo.cms.ui.CmsEditable;
+import org.argeo.api.cms.CmsEditable;
import org.argeo.cms.ui.widgets.ScrolledPage;
import org.argeo.jcr.JcrException;
import org.eclipse.jface.viewers.ContentViewer;
import javax.jcr.nodetype.NodeType;
import javax.jcr.version.VersionManager;
+import org.argeo.api.cms.CmsEditable;
import org.argeo.cms.CmsException;
-import org.argeo.cms.ui.CmsEditable;
import org.argeo.cms.ui.CmsEditionEvent;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.swt.SWT;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
-import org.argeo.cms.ui.util.CmsUiUtils;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.ui.widgets.JcrComposite;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
} else {
relativeDepth = 0;
}
- setLayout(CmsUiUtils.noSpaceGridLayout());
+ setLayout(CmsSwtUtils.noSpaceGridLayout());
} catch (RepositoryException e) {
throw new IllegalStateException("Cannot create section from " + node, e);
}
sectionHeader.dispose();
sectionHeader = new Composite(parent, SWT.NONE);
- sectionHeader.setLayoutData(CmsUiUtils.fillWidth());
- sectionHeader.setLayout(CmsUiUtils.noSpaceGridLayout());
+ sectionHeader.setLayoutData(CmsSwtUtils.fillWidth());
+ sectionHeader.setLayout(CmsSwtUtils.noSpaceGridLayout());
// sectionHeader.moveAbove(null);
// layout();
return sectionHeader;
package org.argeo.cms.ui.widgets;
-import org.argeo.cms.ui.util.CmsUiUtils;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
public ContextOverlay(Control control, int style) {
super(createShell(control, style), SWT.NONE);
Shell shell = getShell();
- setLayoutData(CmsUiUtils.fillAll());
+ setLayoutData(CmsSwtUtils.fillAll());
// TODO make autohide configurable?
//shell.addShellListener(new AutoHideShellListener());
this.control = control;
if (control.isDisposed())
throw new IllegalArgumentException("Control is disposed");
Shell shell = new Shell(control.getShell(), SWT.NO_TRIM);
- shell.setLayout(CmsUiUtils.noSpaceGridLayout());
+ shell.setLayout(CmsSwtUtils.noSpaceGridLayout());
Composite placeholder = new Composite(shell, SWT.BORDER);
- placeholder.setLayoutData(CmsUiUtils.fillAll());
- placeholder.setLayout(CmsUiUtils.noSpaceGridLayout());
+ placeholder.setLayoutData(CmsSwtUtils.fillAll());
+ placeholder.setLayout(CmsSwtUtils.noSpaceGridLayout());
return placeholder;
}
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.argeo.api.cms.Cms2DSize;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.ui.util.CmsUiUtils;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
private static final long serialVersionUID = -5689145523114022890L;
private final static Log log = LogFactory.getLog(EditableImage.class);
- private Point preferredImageSize;
+ private Cms2DSize preferredImageSize;
private Boolean loaded = false;
public EditableImage(Composite parent, int swtStyle) {
super(parent, swtStyle);
}
- public EditableImage(Composite parent, int swtStyle,
- Point preferredImageSize) {
+ public EditableImage(Composite parent, int swtStyle, Cms2DSize preferredImageSize) {
super(parent, swtStyle);
this.preferredImageSize = preferredImageSize;
}
- public EditableImage(Composite parent, int style, Node node,
- boolean cacheImmediately, Point preferredImageSize)
+ public EditableImage(Composite parent, int style, Node node, boolean cacheImmediately, Cms2DSize preferredImageSize)
throws RepositoryException {
super(parent, style, node, cacheImmediately);
this.preferredImageSize = preferredImageSize;
/** To be overriden. */
protected String createImgTag() throws RepositoryException {
- return CmsUiUtils.noImg(preferredImageSize != null ? preferredImageSize
- : getSize());
+ return CmsUiUtils
+ .noImg(preferredImageSize != null ? preferredImageSize : new Cms2DSize(getSize().x, getSize().y));
}
protected Label createLabel(Composite box, String style) {
Label lbl = new Label(box, getStyle());
// lbl.setLayoutData(CmsUiUtils.fillWidth());
- CmsUiUtils.markup(lbl);
- CmsUiUtils.style(lbl, style);
+ CmsSwtUtils.markup(lbl);
+ CmsSwtUtils.style(lbl, style);
if (mouseListener != null)
lbl.addMouseListener(mouseListener);
load(lbl);
loaded = true;
if (control != null) {
((Label) control).setText(imgTag);
- control.setSize(preferredImageSize != null ? preferredImageSize
+ control.setSize(preferredImageSize != null
+ ? new Point(preferredImageSize.getWidth(), preferredImageSize.getHeight())
: getSize());
} else {
loaded = false;
return loaded;
}
- public void setPreferredSize(Point size) {
+ public void setPreferredSize(Cms2DSize size) {
this.preferredImageSize = size;
if (!loaded) {
load((Label) getControl());
protected Text createText(Composite box, String style) {
Text text = new Text(box, getStyle());
- CmsUiUtils.style(text, style);
+ CmsSwtUtils.style(text, style);
return text;
}
- public Point getPreferredImageSize() {
+ public Cms2DSize getPreferredImageSize() {
return preferredImageSize;
}
import javax.jcr.Item;
import javax.jcr.RepositoryException;
-import org.argeo.cms.ui.util.CmsUiUtils;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.GridData;
protected Label createLabel(Composite box, String style) {
Label lbl = new Label(box, getStyle() | SWT.WRAP);
- lbl.setLayoutData(CmsUiUtils.fillWidth());
+ lbl.setLayoutData(CmsSwtUtils.fillWidth());
if (style != null)
- CmsUiUtils.style(lbl, style);
- CmsUiUtils.markup(lbl);
+ CmsSwtUtils.style(lbl, style);
+ CmsSwtUtils.markup(lbl);
if (mouseListener != null)
lbl.addMouseListener(mouseListener);
return lbl;
protected Text createTextLabel(Composite box, String style) {
Text lbl = new Text(box, getStyle() | SWT.MULTI);
lbl.setEditable(false);
- lbl.setLayoutData(CmsUiUtils.fillWidth());
+ lbl.setLayoutData(CmsSwtUtils.fillWidth());
if (style != null)
- CmsUiUtils.style(lbl, style);
- CmsUiUtils.markup(lbl);
+ CmsSwtUtils.style(lbl, style);
+ CmsSwtUtils.markup(lbl);
if (mouseListener != null)
lbl.addMouseListener(mouseListener);
return lbl;
final Text text = new Text(box, getStyle() | SWT.MULTI | SWT.WRAP);
text.setEditable(editable);
- GridData textLayoutData = CmsUiUtils.fillWidth();
+ GridData textLayoutData = CmsSwtUtils.fillWidth();
// textLayoutData.heightHint = preferredHeight;
text.setLayoutData(textLayoutData);
if (style != null)
- CmsUiUtils.style(text, style);
+ CmsSwtUtils.style(text, style);
text.setFocus();
return text;
}
import javax.jcr.Node;
import javax.jcr.RepositoryException;
-import org.argeo.cms.ui.CmsImageManager;
-import org.argeo.cms.ui.CmsView;
+import org.argeo.api.cms.Cms2DSize;
+import org.argeo.api.cms.CmsImageManager;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.ui.internal.JcrFileUploadReceiver;
-import org.argeo.cms.ui.util.CmsUiUtils;
import org.argeo.cms.ui.viewers.NodePart;
import org.argeo.cms.ui.viewers.Section;
import org.argeo.cms.ui.viewers.SectionPart;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
private final Section section;
- private final CmsImageManager imageManager;
+ private final CmsImageManager<Control, Node> imageManager;
private FileUploadHandler currentUploadHandler = null;
private FileUploadListener fileUploadListener;
- public Img(Composite parent, int swtStyle, Node imgNode, Point preferredImageSize) throws RepositoryException {
+ public Img(Composite parent, int swtStyle, Node imgNode, Cms2DSize preferredImageSize) throws RepositoryException {
this(Section.findSection(parent), parent, swtStyle, imgNode, preferredImageSize, null);
setStyle(TextStyles.TEXT_IMAGE);
}
setStyle(TextStyles.TEXT_IMAGE);
}
- public Img(Composite parent, int swtStyle, Node imgNode, CmsImageManager imageManager) throws RepositoryException {
+ public Img(Composite parent, int swtStyle, Node imgNode, CmsImageManager<Control, Node> imageManager)
+ throws RepositoryException {
this(Section.findSection(parent), parent, swtStyle, imgNode, null, imageManager);
setStyle(TextStyles.TEXT_IMAGE);
}
- Img(Section section, Composite parent, int swtStyle, Node imgNode, Point preferredImageSize,
- CmsImageManager imageManager) throws RepositoryException {
+ Img(Section section, Composite parent, int swtStyle, Node imgNode, Cms2DSize preferredImageSize,
+ CmsImageManager<Control, Node> imageManager) throws RepositoryException {
super(parent, swtStyle, imgNode, false, preferredImageSize);
this.section = section;
- this.imageManager = imageManager != null ? imageManager : CmsView.getCmsView(section).getImageManager();
- CmsUiUtils.style(this, TextStyles.TEXT_IMG);
+ this.imageManager = imageManager != null ? imageManager
+ : (CmsImageManager<Control, Node>) CmsSwtUtils.getCmsView(section).getImageManager();
+ CmsSwtUtils.style(this, TextStyles.TEXT_IMG);
}
@Override
@Override
protected synchronized Boolean load(Control lbl) {
- try {
- Node imgNode = getNode();
- boolean loaded = imageManager.load(imgNode, lbl, getPreferredImageSize());
- // getParent().layout();
- return loaded;
- } catch (RepositoryException e) {
- throw new JcrException("Cannot load " + getNodeId() + " from image manager", e);
- }
+ Node imgNode = getNode();
+ boolean loaded = imageManager.load(imgNode, lbl, getPreferredImageSize());
+ // getParent().layout();
+ return loaded;
}
protected Node getUploadFolder() {
return Jcr.getName(node) + '[' + Jcr.getIndex(node) + ']';
}
- protected CmsImageManager getImageManager() {
+ protected CmsImageManager<Control, Node> getImageManager() {
return imageManager;
}
currentUploadHandler = prepareUpload(receiver);
final ServerPushSession pushSession = new ServerPushSession();
final FileUpload fileUpload = new FileUpload(box, SWT.NONE);
- CmsUiUtils.style(fileUpload, style);
+ CmsSwtUtils.style(fileUpload, style);
fileUpload.addSelectionListener(new SelectionAdapter() {
private static final long serialVersionUID = -9158471843941668562L;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
-import org.argeo.cms.ui.util.CmsUiUtils;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.jcr.JcrException;
import org.eclipse.swt.widgets.Composite;
if (cacheImmediately)
this.cache = node;
// }
- setLayout(CmsUiUtils.noSpaceGridLayout());
+ setLayout(CmsSwtUtils.noSpaceGridLayout());
} catch (RepositoryException e) {
throw new IllegalStateException("Cannot create composite from " + item, e);
}
import javax.jcr.Item;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.ui.CmsConstants;
-import org.argeo.cms.ui.util.CmsUiUtils;
import org.argeo.eclipse.ui.specific.EclipseUiSpecificUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusListener;
public StyledControl(Composite parent, int swtStyle) {
super(parent, swtStyle);
- setLayout(CmsUiUtils.noSpaceGridLayout());
+ setLayout(CmsSwtUtils.noSpaceGridLayout());
}
public StyledControl(Composite parent, int style, Item item) {
protected Composite createBox() {
Composite box = new Composite(container, SWT.INHERIT_DEFAULT);
setContainerLayoutData(box);
- box.setLayout(CmsUiUtils.noSpaceGridLayout(3));
+ box.setLayout(CmsSwtUtils.noSpaceGridLayout(3));
return box;
}
protected Composite createContainer() {
Composite container = new Composite(this, SWT.INHERIT_DEFAULT);
setContainerLayoutData(container);
- container.setLayout(CmsUiUtils.noSpaceGridLayout());
+ container.setLayout(CmsSwtUtils.noSpaceGridLayout());
return container;
}
refreshControl(style);
if (style != null) {
- CmsUiUtils.style(box, style + "_box");
- CmsUiUtils.style(container, style + "_container");
+ CmsSwtUtils.style(box, style + "_box");
+ CmsSwtUtils.style(container, style + "_container");
}
}
/** To be overridden */
protected void setControlLayoutData(Control control) {
- control.setLayoutData(CmsUiUtils.fillWidth());
+ control.setLayoutData(CmsSwtUtils.fillWidth());
}
/** To be overridden */
protected void setContainerLayoutData(Composite composite) {
- composite.setLayoutData(CmsUiUtils.fillWidth());
+ composite.setLayoutData(CmsSwtUtils.fillWidth());
}
protected void clear(boolean deep) {
+++ /dev/null
-package org.argeo.cms.ui.widgets.auth;
-
-import java.io.IOException;
-import java.util.Arrays;
-
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.NameCallback;
-import javax.security.auth.callback.PasswordCallback;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.dialogs.TrayDialog;
-import org.eclipse.jface.operation.IRunnableWithProgress;
-import org.eclipse.jface.operation.ModalContext;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Shell;
-import org.osgi.framework.FrameworkUtil;
-
-/** Base for login dialogs */
-public abstract class AbstractLoginDialog extends TrayDialog implements CallbackHandler {
- private static final long serialVersionUID = -8046708963512717709L;
-
- private final static Log log = LogFactory.getLog(AbstractLoginDialog.class);
-
- private Thread modalContextThread = null;
- boolean processCallbacks = false;
- boolean isCancelled = false;
- Callback[] callbackArray;
-
- protected final Callback[] getCallbacks() {
- return this.callbackArray;
- }
-
- public abstract void internalHandle();
-
- public boolean isCancelled() {
- return isCancelled;
- }
-
- protected AbstractLoginDialog(Shell parentShell) {
- super(parentShell);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * javax.security.auth.callback.CallbackHandler#handle(javax.security.auth
- * .callback.Callback[])
- */
- public void handle(final Callback[] callbacks) throws IOException {
- // clean previous usage
- if (processCallbacks) {
- // this handler was already used
- processCallbacks = false;
- }
-
- if (modalContextThread != null) {
- try {
- modalContextThread.join(1000);
- } catch (InterruptedException e) {
- // silent
- }
- modalContextThread = null;
- }
-
- // initialize
- this.callbackArray = callbacks;
- final Display display = Display.getDefault();
- display.syncExec(new Runnable() {
-
- public void run() {
- isCancelled = false;
- setBlockOnOpen(false);
- open();
-
- final Button okButton = getButton(IDialogConstants.OK_ID);
- okButton.setText("Login");
- okButton.addSelectionListener(new SelectionListener() {
- private static final long serialVersionUID = -200281625679096775L;
-
- public void widgetSelected(final SelectionEvent event) {
- processCallbacks = true;
- }
-
- public void widgetDefaultSelected(final SelectionEvent event) {
- // nothing to do
- }
- });
- final Button cancel = getButton(IDialogConstants.CANCEL_ID);
- cancel.addSelectionListener(new SelectionListener() {
- private static final long serialVersionUID = -3826030278084915815L;
-
- public void widgetSelected(final SelectionEvent event) {
- isCancelled = true;
- processCallbacks = true;
- }
-
- public void widgetDefaultSelected(final SelectionEvent event) {
- // nothing to do
- }
- });
- }
- });
- try {
- ModalContext.setAllowReadAndDispatch(true); // Works for now.
- ModalContext.run(new IRunnableWithProgress() {
-
- public void run(final IProgressMonitor monitor) {
- modalContextThread = Thread.currentThread();
- // Wait here until OK or cancel is pressed, then let it rip.
- // The event
- // listener
- // is responsible for closing the dialog (in the
- // loginSucceeded
- // event).
- while (!processCallbacks && (modalContextThread != null)
- && (modalContextThread == Thread.currentThread())
- && FrameworkUtil.getBundle(AbstractLoginDialog.class).getBundleContext() != null) {
- // Note: SecurityUiPlugin.getDefault() != null is false
- // when the OSGi runtime is shut down
- try {
- Thread.sleep(100);
- // if (display.isDisposed()) {
- // log.warn("Display is disposed, killing login
- // dialog thread");
- // throw new ThreadDeath();
- // }
- } catch (final Exception e) {
- // do nothing
- }
- }
- processCallbacks = false;
- // Call the adapter to handle the callbacks
- if (!isCancelled())
- internalHandle();
- else
- // clear callbacks are when cancelling
- for (Callback callback : callbacks)
- if (callback instanceof PasswordCallback) {
- char[] arr = ((PasswordCallback) callback).getPassword();
- if (arr != null) {
- Arrays.fill(arr, '*');
- ((PasswordCallback) callback).setPassword(null);
- }
- } else if (callback instanceof NameCallback)
- ((NameCallback) callback).setName(null);
- }
- }, true, new NullProgressMonitor(), Display.getDefault());
- } catch (ThreadDeath e) {
- isCancelled = true;
- log.debug("Thread " + Thread.currentThread().getId() + " died");
- throw e;
- } catch (Exception e) {
- isCancelled = true;
- IOException ioe = new IOException("Unexpected issue in login dialog, see root cause for more details");
- ioe.initCause(e);
- throw ioe;
- } finally {
- // so that the modal thread dies
- processCallbacks = true;
- // try {
- // // wait for the modal context thread to gracefully exit
- // modalContextThread.join();
- // } catch (InterruptedException ie) {
- // // silent
- // }
- modalContextThread = null;
- }
- }
-
- protected void configureShell(Shell shell) {
- super.configureShell(shell);
- shell.setText("Authentication");
- }
-}
+++ /dev/null
-package org.argeo.cms.ui.widgets.auth;
-
-import static org.argeo.cms.CmsMsg.password;
-import static org.argeo.cms.CmsMsg.username;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.Locale;
-
-import javax.security.auth.Subject;
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.LanguageCallback;
-import javax.security.auth.callback.NameCallback;
-import javax.security.auth.callback.PasswordCallback;
-import javax.security.auth.callback.UnsupportedCallbackException;
-import javax.security.auth.login.LoginContext;
-import javax.security.auth.login.LoginException;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.api.NodeConstants;
-import org.argeo.api.NodeState;
-import org.argeo.cms.CmsMsg;
-import org.argeo.cms.LocaleUtils;
-import org.argeo.cms.auth.HttpRequestCallback;
-import org.argeo.cms.ui.CmsStyles;
-import org.argeo.cms.ui.CmsView;
-import org.argeo.cms.ui.internal.Activator;
-import org.argeo.cms.ui.util.CmsUiUtils;
-import org.argeo.eclipse.ui.specific.UiContext;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.MouseAdapter;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.events.TraverseEvent;
-import org.eclipse.swt.events.TraverseListener;
-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;
-import org.eclipse.swt.widgets.Text;
-
-public class CmsLogin implements CmsStyles, CallbackHandler {
- private final static Log log = LogFactory.getLog(CmsLogin.class);
-
- private Composite parent;
- private Text usernameT, passwordT;
- private Composite credentialsBlock;
- private final SelectionListener loginSelectionListener;
-
- private final Locale defaultLocale;
- private LocaleChoice localeChoice = null;
-
- private final CmsView cmsView;
-
- // optional subject to be set explicitly
- private Subject subject = null;
-
- public CmsLogin(CmsView cmsView) {
- this.cmsView = cmsView;
- NodeState nodeState = Activator.getNodeState();
- if (nodeState != null) {
- defaultLocale = nodeState.getDefaultLocale();
- List<Locale> locales = nodeState.getLocales();
- if (locales != null)
- localeChoice = new LocaleChoice(locales, defaultLocale);
- } else {
- defaultLocale = Locale.getDefault();
- }
- loginSelectionListener = new SelectionListener() {
- private static final long serialVersionUID = -8832133363830973578L;
-
- @Override
- public void widgetSelected(SelectionEvent e) {
- login();
- }
-
- @Override
- public void widgetDefaultSelected(SelectionEvent e) {
- }
- };
- }
-
- protected boolean isAnonymous() {
- return cmsView.isAnonymous();
- }
-
- public final void createUi(Composite parent) {
- this.parent = parent;
- createContents(parent);
- }
-
- protected void createContents(Composite parent) {
- defaultCreateContents(parent);
- }
-
- public final void defaultCreateContents(Composite parent) {
- parent.setLayout(CmsUiUtils.noSpaceGridLayout());
- Composite credentialsBlock = createCredentialsBlock(parent);
- if (parent instanceof Shell) {
- credentialsBlock.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true));
- }
- }
-
- public final Composite createCredentialsBlock(Composite parent) {
- if (isAnonymous()) {
- return anonymousUi(parent);
- } else {
- return userUi(parent);
- }
- }
-
- public Composite getCredentialsBlock() {
- return credentialsBlock;
- }
-
- protected Composite userUi(Composite parent) {
- Locale locale = localeChoice == null ? this.defaultLocale : localeChoice.getSelectedLocale();
- credentialsBlock = new Composite(parent, SWT.NONE);
- credentialsBlock.setLayout(new GridLayout());
- // credentialsBlock.setLayoutData(CmsUiUtils.fillAll());
-
- specificUserUi(credentialsBlock);
-
- Label l = new Label(credentialsBlock, SWT.NONE);
- CmsUiUtils.style(l, CMS_USER_MENU_ITEM);
- l.setText(CmsMsg.logout.lead(locale));
- GridData lData = CmsUiUtils.fillWidth();
- lData.widthHint = 120;
- l.setLayoutData(lData);
-
- l.addMouseListener(new MouseAdapter() {
- private static final long serialVersionUID = 6444395812777413116L;
-
- public void mouseDown(MouseEvent e) {
- logout();
- }
- });
- return credentialsBlock;
- }
-
- /** To be overridden */
- protected void specificUserUi(Composite parent) {
-
- }
-
- protected Composite anonymousUi(Composite parent) {
- Locale locale = localeChoice == null ? this.defaultLocale : localeChoice.getSelectedLocale();
- // We need a composite for the traversal
- credentialsBlock = new Composite(parent, SWT.NONE);
- credentialsBlock.setLayout(new GridLayout());
- // credentialsBlock.setLayoutData(CmsUiUtils.fillAll());
- CmsUiUtils.style(credentialsBlock, CMS_LOGIN_DIALOG);
-
- Integer textWidth = 120;
- if (parent instanceof Shell)
- CmsUiUtils.style(parent, CMS_USER_MENU);
- // new Label(this, SWT.NONE).setText(CmsMsg.username.lead());
- usernameT = new Text(credentialsBlock, SWT.BORDER);
- usernameT.setMessage(username.lead(locale));
- CmsUiUtils.style(usernameT, CMS_LOGIN_DIALOG_USERNAME);
- GridData gd = CmsUiUtils.fillWidth();
- gd.widthHint = textWidth;
- usernameT.setLayoutData(gd);
-
- // new Label(this, SWT.NONE).setText(CmsMsg.password.lead());
- passwordT = new Text(credentialsBlock, SWT.BORDER | SWT.PASSWORD);
- passwordT.setMessage(password.lead(locale));
- CmsUiUtils.style(passwordT, CMS_LOGIN_DIALOG_PASSWORD);
- gd = CmsUiUtils.fillWidth();
- gd.widthHint = textWidth;
- passwordT.setLayoutData(gd);
-
- TraverseListener tl = new TraverseListener() {
- private static final long serialVersionUID = -1158892811534971856L;
-
- public void keyTraversed(TraverseEvent e) {
- if (e.detail == SWT.TRAVERSE_RETURN)
- login();
- }
- };
- credentialsBlock.addTraverseListener(tl);
- usernameT.addTraverseListener(tl);
- passwordT.addTraverseListener(tl);
- parent.setTabList(new Control[] { credentialsBlock });
- credentialsBlock.setTabList(new Control[] { usernameT, passwordT });
-
- // Button
- Button loginButton = new Button(credentialsBlock, SWT.PUSH);
- loginButton.setText(CmsMsg.login.lead(locale));
- loginButton.setLayoutData(CmsUiUtils.fillWidth());
- loginButton.addSelectionListener(loginSelectionListener);
-
- extendsCredentialsBlock(credentialsBlock, locale, loginSelectionListener);
- if (localeChoice != null)
- createLocalesBlock(credentialsBlock);
- return credentialsBlock;
- }
-
- /**
- * To be overridden in order to provide custom login button and other links.
- */
- protected void extendsCredentialsBlock(Composite credentialsBlock, Locale selectedLocale,
- SelectionListener loginSelectionListener) {
-
- }
-
- protected void updateLocale(Locale selectedLocale) {
- // save already entered values
- String usernameStr = usernameT.getText();
- char[] pwd = passwordT.getTextChars();
-
- for (Control child : parent.getChildren())
- child.dispose();
- createContents(parent);
- if (parent.getParent() != null)
- parent.getParent().layout(true, true);
- else
- parent.layout();
- usernameT.setText(usernameStr);
- passwordT.setTextChars(pwd);
- }
-
- protected Composite createLocalesBlock(final Composite parent) {
- Composite c = new Composite(parent, SWT.NONE);
- CmsUiUtils.style(c, CMS_USER_MENU_ITEM);
- c.setLayout(CmsUiUtils.noSpaceGridLayout());
- c.setLayoutData(CmsUiUtils.fillAll());
-
- SelectionListener selectionListener = new SelectionAdapter() {
- private static final long serialVersionUID = 4891637813567806762L;
-
- public void widgetSelected(SelectionEvent event) {
- Button button = (Button) event.widget;
- if (button.getSelection()) {
- localeChoice.setSelectedIndex((Integer) event.widget.getData());
- updateLocale(localeChoice.getSelectedLocale());
- }
- };
- };
-
- List<Locale> locales = localeChoice.getLocales();
- for (Integer i = 0; i < locales.size(); i++) {
- Locale locale = locales.get(i);
- Button button = new Button(c, SWT.RADIO);
- CmsUiUtils.style(button, CMS_USER_MENU_ITEM);
- button.setData(i);
- button.setText(LocaleUtils.toLead(locale.getDisplayName(locale), locale) + " (" + locale + ")");
- // button.addListener(SWT.Selection, listener);
- button.addSelectionListener(selectionListener);
- if (i == localeChoice.getSelectedIndex())
- button.setSelection(true);
- }
- return c;
- }
-
- protected boolean login() {
- // TODO use CmsVie in order to retrieve subject?
- // Subject subject = cmsView.getLoginContext().getSubject();
- // LoginContext loginContext = cmsView.getLoginContext();
- try {
- //
- // LOGIN
- //
- // loginContext.logout();
- LoginContext loginContext;
- if (subject == null)
- loginContext = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, this);
- else
- loginContext = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, subject, this);
- loginContext.login();
- cmsView.authChange(loginContext);
- return true;
- } catch (LoginException e) {
- if (log.isTraceEnabled())
- log.warn("Login failed: " + e.getMessage(), e);
- else
- log.warn("Login failed: " + e.getMessage());
-
- try {
- Thread.sleep(3000);
- } catch (InterruptedException e2) {
- // silent
- }
- // ErrorFeedback.show("Login failed", e);
- return false;
- }
- // catch (LoginException e) {
- // log.error("Cannot login", e);
- // return false;
- // }
- }
-
- protected void logout() {
- cmsView.logout();
- cmsView.navigateTo("~");
- }
-
- @Override
- public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
- for (Callback callback : callbacks) {
- if (callback instanceof NameCallback && usernameT != null)
- ((NameCallback) callback).setName(usernameT.getText());
- else if (callback instanceof PasswordCallback && passwordT != null)
- ((PasswordCallback) callback).setPassword(passwordT.getTextChars());
- else if (callback instanceof HttpRequestCallback) {
- ((HttpRequestCallback) callback).setRequest(UiContext.getHttpRequest());
- ((HttpRequestCallback) callback).setResponse(UiContext.getHttpResponse());
- } else if (callback instanceof LanguageCallback) {
- Locale toUse = null;
- if (localeChoice != null)
- toUse = localeChoice.getSelectedLocale();
- else if (defaultLocale != null)
- toUse = defaultLocale;
-
- if (toUse != null) {
- ((LanguageCallback) callback).setLocale(toUse);
- UiContext.setLocale(toUse);
- }
-
- }
- }
- }
-
- public void setSubject(Subject subject) {
- this.subject = subject;
- }
-
-}
+++ /dev/null
-package org.argeo.cms.ui.widgets.auth;
-
-import org.argeo.cms.ui.CmsView;
-import org.argeo.cms.ui.util.CmsUiUtils;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Shell;
-
-/** The site-related user menu */
-public class CmsLoginShell extends CmsLogin {
- private final Shell shell;
-
- public CmsLoginShell(CmsView cmsView) {
- super(cmsView);
- shell = createShell();
-// createUi(shell);
- }
-
- /** To be overridden. */
- protected Shell createShell() {
- Shell shell = new Shell(Display.getCurrent(), SWT.NO_TRIM);
- shell.setMaximized(true);
- return shell;
- }
-
- /** To be overridden. */
- public void open() {
- CmsUiUtils.style(shell, CMS_USER_MENU);
- shell.open();
- }
-
- @Override
- protected boolean login() {
- boolean success = false;
- try {
- success = super.login();
- return success;
- } finally {
- if (success)
- closeShell();
- else {
- for (Control child : shell.getChildren())
- child.dispose();
- createUi(shell);
- shell.layout();
- // TODO error message
- }
- }
- }
-
- @Override
- protected void logout() {
- closeShell();
- super.logout();
- }
-
- protected void closeShell() {
- if (!shell.isDisposed()) {
- shell.close();
- shell.dispose();
- }
- }
-
- public Shell getShell() {
- return shell;
- }
-
- public void createUi(){
- createUi(shell);
- }
-}
+++ /dev/null
-package org.argeo.cms.ui.widgets.auth;
-
-import java.io.IOException;
-import java.util.Arrays;
-
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.NameCallback;
-import javax.security.auth.callback.PasswordCallback;
-import javax.security.auth.callback.TextOutputCallback;
-import javax.security.auth.callback.UnsupportedCallbackException;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.KeyEvent;
-import org.eclipse.swt.events.KeyListener;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
-
-/**
- * A composite that can populate itself based on {@link Callback}s. It can be
- * used directly as a {@link CallbackHandler} or be used by one by calling the
- * {@link #createCallbackHandlers(Callback[])}. Supported standard
- * {@link Callback}s are:<br>
- * <ul>
- * <li>{@link PasswordCallback}</li>
- * <li>{@link NameCallback}</li>
- * <li>{@link TextOutputCallback}</li>
- * </ul>
- * Supported Argeo {@link Callback}s are:<br>
- * <ul>
- * <li>{@link LocaleChoice}</li>
- * </ul>
- */
-public class CompositeCallbackHandler extends Composite implements CallbackHandler {
- private static final long serialVersionUID = -928223893722723777L;
-
- private boolean wasUsedAlready = false;
- private boolean isSubmitted = false;
- private boolean isCanceled = false;
-
- public CompositeCallbackHandler(Composite parent, int style) {
- super(parent, style);
- }
-
- @Override
- public synchronized void handle(final Callback[] callbacks) throws IOException, UnsupportedCallbackException {
- // reset
- if (wasUsedAlready && !isSubmitted() && !isCanceled()) {
- cancel();
- for (Control control : getChildren())
- control.dispose();
- isSubmitted = false;
- isCanceled = false;
- }
-
- for (Callback callback : callbacks)
- checkCallbackSupported(callback);
- // create controls synchronously in the UI thread
- getDisplay().syncExec(new Runnable() {
-
- @Override
- public void run() {
- createCallbackHandlers(callbacks);
- }
- });
-
- if (!wasUsedAlready)
- wasUsedAlready = true;
-
- // while (!isSubmitted() && !isCanceled()) {
- // try {
- // wait(1000l);
- // } catch (InterruptedException e) {
- // // silent
- // }
- // }
-
- // cleanCallbacksAfterCancel(callbacks);
- }
-
- public void checkCallbackSupported(Callback callback) throws UnsupportedCallbackException {
- if (callback instanceof TextOutputCallback || callback instanceof NameCallback
- || callback instanceof PasswordCallback || callback instanceof LocaleChoice) {
- return;
- } else {
- throw new UnsupportedCallbackException(callback);
- }
- }
-
- /**
- * Set writable callbacks to null if the handle is canceled (check is done
- * by the method)
- */
- public void cleanCallbacksAfterCancel(Callback[] callbacks) {
- if (isCanceled()) {
- for (Callback callback : callbacks) {
- if (callback instanceof NameCallback) {
- ((NameCallback) callback).setName(null);
- } else if (callback instanceof PasswordCallback) {
- PasswordCallback pCallback = (PasswordCallback) callback;
- char[] arr = pCallback.getPassword();
- if (arr != null) {
- Arrays.fill(arr, '*');
- pCallback.setPassword(null);
- }
- }
- }
- }
- }
-
- public void createCallbackHandlers(Callback[] callbacks) {
- Composite composite = this;
- for (int i = 0; i < callbacks.length; i++) {
- Callback callback = callbacks[i];
- if (callback instanceof TextOutputCallback) {
- createLabelTextoutputHandler(composite, (TextOutputCallback) callback);
- } else if (callback instanceof NameCallback) {
- createNameHandler(composite, (NameCallback) callback);
- } else if (callback instanceof PasswordCallback) {
- createPasswordHandler(composite, (PasswordCallback) callback);
- } else if (callback instanceof LocaleChoice) {
- createLocaleHandler(composite, (LocaleChoice) callback);
- }
- }
- }
-
- protected Text createNameHandler(Composite composite, final NameCallback callback) {
- Label label = new Label(composite, SWT.NONE);
- label.setText(callback.getPrompt());
- final Text text = new Text(composite, SWT.SINGLE | SWT.LEAD | SWT.BORDER);
- if (callback.getDefaultName() != null) {
- // set default value, if provided
- text.setText(callback.getDefaultName());
- callback.setName(callback.getDefaultName());
- }
- text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- text.addModifyListener(new ModifyListener() {
- private static final long serialVersionUID = 7300032545287292973L;
-
- public void modifyText(ModifyEvent event) {
- callback.setName(text.getText());
- }
- });
- text.addSelectionListener(new SelectionListener() {
- private static final long serialVersionUID = 1820530045857665111L;
-
- @Override
- public void widgetSelected(SelectionEvent e) {
- }
-
- @Override
- public void widgetDefaultSelected(SelectionEvent e) {
- submit();
- }
- });
-
- text.addKeyListener(new KeyListener() {
- private static final long serialVersionUID = -8698107785092095713L;
-
- @Override
- public void keyReleased(KeyEvent e) {
- }
-
- @Override
- public void keyPressed(KeyEvent e) {
- }
- });
- return text;
- }
-
- protected Text createPasswordHandler(Composite composite, final PasswordCallback callback) {
- Label label = new Label(composite, SWT.NONE);
- label.setText(callback.getPrompt());
- final Text passwordText = new Text(composite, SWT.SINGLE | SWT.LEAD | SWT.PASSWORD | SWT.BORDER);
- passwordText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- passwordText.addModifyListener(new ModifyListener() {
- private static final long serialVersionUID = -7099363995047686732L;
-
- public void modifyText(ModifyEvent event) {
- callback.setPassword(passwordText.getTextChars());
- }
- });
- passwordText.addSelectionListener(new SelectionListener() {
- private static final long serialVersionUID = 1820530045857665111L;
-
- @Override
- public void widgetSelected(SelectionEvent e) {
- }
-
- @Override
- public void widgetDefaultSelected(SelectionEvent e) {
- submit();
- }
- });
- return passwordText;
- }
-
- protected Combo createLocaleHandler(Composite composite, final LocaleChoice callback) {
- String[] labels = callback.getSupportedLocalesLabels();
- if (labels.length == 0)
- return null;
- Label label = new Label(composite, SWT.NONE);
- label.setText("Language");
-
- final Combo combo = new Combo(composite, SWT.READ_ONLY);
- combo.setItems(labels);
- combo.select(callback.getDefaultIndex());
- combo.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- combo.addSelectionListener(new SelectionListener() {
- private static final long serialVersionUID = 38678989091946277L;
-
- @Override
- public void widgetSelected(SelectionEvent e) {
- callback.setSelectedIndex(combo.getSelectionIndex());
- }
-
- @Override
- public void widgetDefaultSelected(SelectionEvent e) {
- }
- });
- return combo;
- }
-
- protected Label createLabelTextoutputHandler(Composite composite, final TextOutputCallback callback) {
- Label label = new Label(composite, SWT.NONE);
- label.setText(callback.getMessage());
- GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
- data.horizontalSpan = 2;
- label.setLayoutData(data);
- return label;
- // TODO: find a way to pass this information
- // int messageType = callback.getMessageType();
- // int dialogMessageType = IMessageProvider.NONE;
- // switch (messageType) {
- // case TextOutputCallback.INFORMATION:
- // dialogMessageType = IMessageProvider.INFORMATION;
- // break;
- // case TextOutputCallback.WARNING:
- // dialogMessageType = IMessageProvider.WARNING;
- // break;
- // case TextOutputCallback.ERROR:
- // dialogMessageType = IMessageProvider.ERROR;
- // break;
- // }
- // setMessage(callback.getMessage(), dialogMessageType);
- }
-
- synchronized boolean isSubmitted() {
- return isSubmitted;
- }
-
- synchronized boolean isCanceled() {
- return isCanceled;
- }
-
- protected synchronized void submit() {
- isSubmitted = true;
- notifyAll();
- }
-
- protected synchronized void cancel() {
- isCanceled = true;
- notifyAll();
- }
-}
+++ /dev/null
-package org.argeo.cms.ui.widgets.auth;
-
-import javax.security.auth.callback.CallbackHandler;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Shell;
-
-/** Default authentication dialog, to be used as {@link CallbackHandler}. */
-public class DefaultLoginDialog extends AbstractLoginDialog {
- private static final long serialVersionUID = -8551827590693035734L;
-
- public DefaultLoginDialog() {
- this(Display.getCurrent().getActiveShell());
- }
-
- public DefaultLoginDialog(Shell parentShell) {
- super(parentShell);
- }
-
- protected Point getInitialSize() {
- return new Point(350, 180);
- }
-
- @Override
- protected Control createContents(Composite parent) {
- Control control = super.createContents(parent);
- parent.pack();
-
- // Move the dialog to the center of the top level shell.
- Rectangle shellBounds;
- if (Display.getCurrent().getActiveShell() != null) // RCP
- shellBounds = Display.getCurrent().getActiveShell().getBounds();
- else
- shellBounds = Display.getCurrent().getBounds();// RAP
- Point dialogSize = parent.getSize();
- int x = shellBounds.x + (shellBounds.width - dialogSize.x) / 2;
- int y = shellBounds.y + (shellBounds.height - dialogSize.y) / 2;
- parent.setLocation(x, y);
- return control;
- }
-
- protected Control createDialogArea(Composite parent) {
- Composite dialogarea = (Composite) super.createDialogArea(parent);
- CompositeCallbackHandler composite = new CompositeCallbackHandler(
- dialogarea, SWT.NONE);
- composite.setLayout(new GridLayout(2, false));
- composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
- composite.createCallbackHandlers(getCallbacks());
- return composite;
- }
-
- public void internalHandle() {
- }
-}
+++ /dev/null
-package org.argeo.cms.ui.widgets.auth;
-
-import java.io.IOException;
-
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.UnsupportedCallbackException;
-
-import org.argeo.eclipse.ui.dialogs.LightweightDialog;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Shell;
-
-public class DynamicCallbackHandler implements CallbackHandler {
-
- @Override
- public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
- Shell activeShell = Display.getCurrent().getActiveShell();
- LightweightDialog dialog = new LightweightDialog(activeShell) {
-
- @Override
- protected Control createDialogArea(Composite parent) {
- CompositeCallbackHandler cch = new CompositeCallbackHandler(parent, SWT.NONE);
- cch.createCallbackHandlers(callbacks);
- return cch;
- }
- };
- dialog.setBlockOnOpen(true);
- dialog.open();
- }
-
-}
+++ /dev/null
-package org.argeo.cms.ui.widgets.auth;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Locale;
-
-import javax.security.auth.callback.LanguageCallback;
-
-import org.argeo.cms.CmsException;
-import org.argeo.cms.LocaleUtils;
-
-/** Choose in a list of locales. TODO: replace with {@link LanguageCallback} */
-public class LocaleChoice {
- private final List<Locale> locales;
-
- private Integer selectedIndex = null;
- private final Integer defaultIndex;
-
- public LocaleChoice(List<Locale> locales, Locale defaultLocale) {
- Integer defaultIndex = null;
- this.locales = Collections.unmodifiableList(locales);
- for (int i = 0; i < locales.size(); i++)
- if (locales.get(i).equals(defaultLocale))
- defaultIndex = i;
-
- // based on language only
- if (defaultIndex == null)
- for (int i = 0; i < locales.size(); i++)
- if (locales.get(i).getLanguage().equals(defaultLocale.getLanguage()))
- defaultIndex = i;
-
- if (defaultIndex == null)
- throw new CmsException("Default locale " + defaultLocale + " is not in available locales " + locales);
- this.defaultIndex = defaultIndex;
-
- this.selectedIndex = defaultIndex;
- }
-
- /**
- * Convenience constructor based on a comma separated list of iso codes (en,
- * en_US, fr_CA, etc.). Default selection is default locale.
- */
- public LocaleChoice(String locales, Locale defaultLocale) {
- this(LocaleUtils.asLocaleList(locales), defaultLocale);
- }
-
- public String[] getSupportedLocalesLabels() {
- String[] labels = new String[locales.size()];
- for (int i = 0; i < locales.size(); i++) {
- Locale locale = locales.get(i);
- if (locale.getCountry().equals(""))
- labels[i] = locale.getDisplayLanguage(locale) + " [" + locale.getLanguage() + "]";
- else
- labels[i] = locale.getDisplayLanguage(locale) + " (" + locale.getDisplayCountry(locale) + ") ["
- + locale.getLanguage() + "_" + locale.getCountry() + "]";
-
- }
- return labels;
- }
-
- public Locale getSelectedLocale() {
- if (selectedIndex == null)
- return null;
- return locales.get(selectedIndex);
- }
-
- public void setSelectedIndex(Integer selectedIndex) {
- this.selectedIndex = selectedIndex;
- }
-
- public Integer getSelectedIndex() {
- return selectedIndex;
- }
-
- public Integer getDefaultIndex() {
- return defaultIndex;
- }
-
- public List<Locale> getLocales() {
- return locales;
- }
-
- public Locale getDefaultLocale() {
- return locales.get(getDefaultIndex());
- }
-}
+++ /dev/null
-/** Argeo CMS authentication widgets, based on SWT. */
-package org.argeo.cms.ui.widgets.auth;
\ No newline at end of file
--- /dev/null
+package org.argeo.cms;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.argeo.api.cms.CmsApp;
+import org.argeo.api.cms.CmsAppListener;
+import org.argeo.api.cms.CmsTheme;
+
+/** Base class for {@link CmsApp}s. */
+public abstract class AbstractCmsApp implements CmsApp {
+ private Map<String, CmsTheme> themes = Collections.synchronizedMap(new HashMap<>());
+
+ private List<CmsAppListener> cmsAppListeners = new ArrayList<>();
+
+ protected abstract String getThemeId(String uiName);
+
+ @Override
+ public CmsTheme getTheme(String uiName) {
+ String themeId = getThemeId(uiName);
+ if (themeId == null)
+ return null;
+ if (!themes.containsKey(themeId))
+ throw new IllegalArgumentException("Theme " + themeId + " not found.");
+ return themes.get(themeId);
+ }
+
+ @Override
+ public boolean allThemesAvailable() {
+ boolean themeMissing = false;
+ uiNames: for (String uiName : getUiNames()) {
+ String themeId = getThemeId(uiName);
+ if ("org.eclipse.rap.rwt.theme.Default".equals(themeId))
+ continue uiNames;
+ if (!themes.containsKey(themeId)) {
+ themeMissing = true;
+ break uiNames;
+ }
+ }
+ return !themeMissing;
+ }
+
+ public void addTheme(CmsTheme theme, Map<String, String> properties) {
+ themes.put(theme.getThemeId(), theme);
+ if (allThemesAvailable())
+ for (CmsAppListener listener : cmsAppListeners)
+ listener.themingUpdated();
+ }
+
+ public void removeTheme(CmsTheme theme, Map<String, String> properties) {
+ themes.remove(theme.getThemeId());
+ }
+
+ @Override
+ public void addCmsAppListener(CmsAppListener listener) {
+ cmsAppListeners.add(listener);
+ if (allThemesAvailable())
+ listener.themingUpdated();
+ }
+
+ @Override
+ public void removeCmsAppListener(CmsAppListener listener) {
+ cmsAppListeners.remove(listener);
+ }
+
+}
import javax.servlet.http.HttpSession;
import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsSession;
+import org.argeo.api.cms.CmsSessionId;
import org.argeo.api.security.AnonymousPrincipal;
import org.argeo.api.security.DataAdminPrincipal;
import org.argeo.api.security.NodeSecurityUtils;
}
}
- public static CmsSession cmsSessionFromHttpSession(BundleContext bc, String httpSessionId) {
+ public static CmsSessionImpl cmsSessionFromHttpSession(BundleContext bc, String httpSessionId) {
Authorization authorization = null;
Collection<ServiceReference<CmsSession>> sr;
try {
} catch (InvalidSyntaxException e) {
throw new IllegalArgumentException("Cannot get CMS session for id " + httpSessionId, e);
}
- CmsSession cmsSession;
+ CmsSessionImpl cmsSession;
if (sr.size() == 1) {
- cmsSession = bc.getService(sr.iterator().next());
+ cmsSession = (CmsSessionImpl) bc.getService(sr.iterator().next());
// locale = cmsSession.getLocale();
authorization = cmsSession.getAuthorization();
if (authorization.getName() == null)
+++ /dev/null
-package org.argeo.cms.auth;
-
-import java.time.ZonedDateTime;
-import java.util.Collection;
-import java.util.Locale;
-import java.util.UUID;
-
-import javax.naming.ldap.LdapName;
-import javax.security.auth.Subject;
-
-import org.argeo.naming.LdapAttrs;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.useradmin.Authorization;
-
-/** An authenticated user session. */
-public interface CmsSession {
- final static String USER_DN = LdapAttrs.DN;
- final static String SESSION_UUID = LdapAttrs.entryUUID.name();
- final static String SESSION_LOCAL_ID = LdapAttrs.uniqueIdentifier.name();
-
- UUID getUuid();
-
- String getUserRole();
-
- LdapName getUserDn();
-
- String getLocalId();
-
- Authorization getAuthorization();
-
- Subject getSubject();
-
- boolean isAnonymous();
-
- ZonedDateTime getCreationTime();
-
- ZonedDateTime getEnd();
-
- Locale getLocale();
-
- boolean isValid();
-
- void registerView(String uid, Object view);
-
- /** @return The {@link CmsSession} for this {@link Subject} or null. */
- static CmsSession getCmsSession(BundleContext bc, Subject subject) {
- if (subject.getPrivateCredentials(CmsSessionId.class).isEmpty())
- return null;
- CmsSessionId cmsSessionId = subject.getPrivateCredentials(CmsSessionId.class).iterator().next();
- String uuid = cmsSessionId.getUuid().toString();
- Collection<ServiceReference<CmsSession>> sr;
- try {
- sr = bc.getServiceReferences(CmsSession.class, "(" + CmsSession.SESSION_UUID + "=" + uuid + ")");
- } catch (InvalidSyntaxException e) {
- throw new IllegalArgumentException("Cannot get CMS session for uuid " + uuid, e);
- }
- ServiceReference<CmsSession> cmsSessionRef;
- if (sr.size() == 1) {
- cmsSessionRef = sr.iterator().next();
- return bc.getService(cmsSessionRef);
- } else if (sr.size() == 0) {
- return null;
- } else
- throw new IllegalStateException(sr.size() + " CMS sessions registered for " + uuid);
- }
-}
+++ /dev/null
-package org.argeo.cms.auth;
-
-import java.util.UUID;
-
-import javax.security.auth.Subject;
-
-/**
- * The ID of a {@link CmsSession}, which must be available in the private
- * credentials of an authenticated {@link Subject}.
- */
-public class CmsSessionId {
- private final UUID uuid;
-
- public CmsSessionId(UUID value) {
- if (value == null)
- throw new IllegalArgumentException("Value cannot be null");
- this.uuid = value;
- }
-
- public UUID getUuid() {
- return uuid;
- }
-
- @Override
- public int hashCode() {
- return uuid.hashCode();
- }
-
- @Override
- public boolean equals(Object obj) {
- return obj instanceof CmsSessionId && ((CmsSessionId) obj).getUuid().equals(uuid);
- }
-
- @Override
- public String toString() {
- return "Node Session " + uuid;
- }
-
-}
import javax.security.auth.x500.X500Principal;
import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsSession;
+import org.argeo.api.cms.CmsSessionId;
import org.argeo.cms.internal.auth.CmsSessionImpl;
import org.argeo.cms.internal.auth.ImpliedByPrincipal;
import org.argeo.cms.internal.kernel.Activator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.argeo.cms.internal.auth.CmsSessionImpl;
import org.argeo.cms.internal.kernel.Activator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
String httpSessionId = httpSession.getId();
if (log.isTraceEnabled())
log.trace("HTTP login: " + request.getPathInfo() + " #" + httpSessionId);
- CmsSession cmsSession = CmsAuthUtils.cmsSessionFromHttpSession(bc, httpSessionId);
+ CmsSessionImpl cmsSession = CmsAuthUtils.cmsSessionFromHttpSession(bc, httpSessionId);
if (cmsSession != null) {
authorization = cmsSession.getAuthorization();
locale = cmsSession.getLocale();
String httpSessionId = httpSession.getId();
if (log.isTraceEnabled())
log.trace("HTTP login: " + request.getPathInfo() + " #" + httpSessionId);
- CmsSession cmsSession = CmsAuthUtils.cmsSessionFromHttpSession(bc, httpSessionId);
+ CmsSessionImpl cmsSession = CmsAuthUtils.cmsSessionFromHttpSession(bc, httpSessionId);
if (cmsSession != null) {
authorization = cmsSession.getAuthorization();
locale = cmsSession.getLocale();
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsSession;
import org.argeo.api.security.NodeSecurityUtils;
-import org.argeo.cms.auth.CmsSession;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.InvalidSyntaxException;
end = ZonedDateTime.now();
serviceRegistration.unregister();
-
try {
LoginContext lc;
if (isAnonymous()) {
return getEnd() != null;
}
- @Override
public Authorization getAuthorization() {
checkValid();
return authorization;
}
+ @Override
+ public String getDisplayName() {
+ return authorization.toString();
+ }
+
@Override
public UUID getUuid() {
return uuid;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
-import org.argeo.api.PublishNamespace;
+import org.argeo.cms.osgi.PublishNamespace;
import org.argeo.osgi.util.FilterRequirement;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import java.util.TreeSet;
import org.apache.commons.logging.Log;
-import org.argeo.api.DataModelNamespace;
+import org.argeo.cms.osgi.DataModelNamespace;
import org.osgi.framework.BundleContext;
import org.osgi.util.tracker.ServiceTracker;
--- /dev/null
+package org.argeo.cms.osgi;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.stream.Collectors;
+
+import org.apache.commons.io.IOUtils;
+import org.argeo.api.cms.CmsTheme;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+/**
+ * Simplifies the theming of an app (only RAP is supported at this stage).<br>
+ *
+ * Additional fonts listed in <code>/fonts.txt</code>.<br>
+ * Additional (standard CSS) header in <code>/header.css</code>.<br>
+ * RAP specific CSS files in <code>/rap/*.css</code>.<br>
+ * All images added as additional resources based on extensions
+ * <code>/ ** /*.{png,gif,jpeg,...}</code>.<br>
+ */
+public class BundleCmsTheme implements CmsTheme {
+ public final static String DEFAULT_CMS_THEME_BUNDLE = "org.argeo.theme.argeo2";
+
+ public final static String CMS_THEME_PROPERTY = "argeo.cms.theme";
+ public final static String CMS_THEME_BUNDLE_PROPERTY = "argeo.cms.theme.bundle";
+
+ private final static String HEADER_CSS = "header.css";
+ private final static String FONTS_TXT = "fonts.txt";
+ private final static String BODY_HTML = "body.html";
+
+// private final static Log log = LogFactory.getLog(BundleCmsTheme.class);
+
+ private String themeId;
+ private Set<String> webCssPaths = new TreeSet<>();
+ private Set<String> rapCssPaths = new TreeSet<>();
+ private Set<String> swtCssPaths = new TreeSet<>();
+ private Set<String> imagesPaths = new TreeSet<>();
+ private Set<String> fontsPaths = new TreeSet<>();
+
+ private String headerCss;
+ private List<String> fonts = new ArrayList<>();
+
+ private String bodyHtml="<body></body>";
+
+ private String basePath;
+ private String styleCssPath;
+// private String webCssPath;
+// private String rapCssPath;
+// private String swtCssPath;
+ private Bundle themeBundle;
+
+ private Integer defaultIconSize = 16;
+
+ public BundleCmsTheme() {
+
+ }
+
+ public void init(BundleContext bundleContext, Map<String, String> properties) {
+ initResources(bundleContext, null);
+ }
+
+ public void destroy(BundleContext bundleContext, Map<String, String> properties) {
+
+ }
+
+ @Deprecated
+ public BundleCmsTheme(BundleContext bundleContext) {
+ this(bundleContext, null);
+ }
+
+ @Deprecated
+ public BundleCmsTheme(BundleContext bundleContext, String symbolicName) {
+ initResources(bundleContext, symbolicName);
+ }
+
+ private void initResources(BundleContext bundleContext, String symbolicName) {
+ if (symbolicName == null) {
+ themeBundle = bundleContext.getBundle();
+// basePath = "/theme/";
+// cssPath = basePath;
+ } else {
+ themeBundle = findThemeBundle(bundleContext, symbolicName);
+ }
+ basePath = "/";
+ styleCssPath = "/style/";
+// webCssPath = "/css/";
+// rapCssPath = "/rap/";
+// swtCssPath = "/swt/";
+// this.themeId = RWT.DEFAULT_THEME_ID;
+ this.themeId = themeBundle.getSymbolicName();
+ webCssPaths = addCss(themeBundle, "/css/");
+ rapCssPaths = addCss(themeBundle, "/rap/");
+ swtCssPaths = addCss(themeBundle, "/swt/");
+ addImages("*.png");
+ addImages("*.gif");
+ addImages("*.jpg");
+ addImages("*.jpeg");
+ addImages("*.svg");
+ addImages("*.ico");
+
+ addFonts("*.woff");
+ addFonts("*.woff2");
+
+ // fonts
+ URL fontsUrl = themeBundle.getEntry(basePath + FONTS_TXT);
+ if (fontsUrl != null) {
+ loadFontsUrl(fontsUrl);
+ }
+
+ // common CSS header (plain CSS)
+ URL headerCssUrl = themeBundle.getEntry(basePath + HEADER_CSS);
+ if (headerCssUrl != null) {
+ // added to plain Web CSS
+ webCssPaths.add(basePath + HEADER_CSS);
+ // and it will also be used by RAP:
+ try (BufferedReader buffer = new BufferedReader(new InputStreamReader(headerCssUrl.openStream(), UTF_8))) {
+ headerCss = buffer.lines().collect(Collectors.joining("\n"));
+ } catch (IOException e) {
+ throw new IllegalArgumentException("Cannot read " + headerCssUrl, e);
+ }
+ }
+
+ // body
+ URL bodyUrl = themeBundle.getEntry(basePath + BODY_HTML);
+ if (bodyUrl != null) {
+ loadBodyHtml(bodyUrl);
+ }
+}
+
+ public String getHtmlHeaders() {
+ StringBuilder sb = new StringBuilder();
+ if (headerCss != null) {
+ sb.append("<style type='text/css'>\n");
+ sb.append(headerCss);
+ sb.append("\n</style>\n");
+ }
+ for (String link : fonts) {
+ sb.append("<link rel='stylesheet' href='");
+ sb.append(link);
+ sb.append("'/>\n");
+ }
+ if (sb.length() == 0)
+ return null;
+ else
+ return sb.toString();
+ }
+
+
+
+ @Override
+ public String getBodyHtml() {
+ return bodyHtml;
+ }
+
+ Set<String> addCss(Bundle themeBundle, String path) {
+ Set<String> paths = new TreeSet<>();
+
+ // common CSS
+ Enumeration<URL> commonResources = themeBundle.findEntries(styleCssPath, "*.css", true);
+ if (commonResources != null) {
+ while (commonResources.hasMoreElements()) {
+ String resource = commonResources.nextElement().getPath();
+ // remove first '/' so that RWT registers it
+ resource = resource.substring(1);
+ if (!resource.endsWith("/")) {
+ paths.add(resource);
+ }
+ }
+ }
+
+ // specific CSS
+ Enumeration<URL> themeResources = themeBundle.findEntries(path, "*.css", true);
+ if (themeResources != null) {
+ while (themeResources.hasMoreElements()) {
+ String resource = themeResources.nextElement().getPath();
+ // remove first '/' so that RWT registers it
+ resource = resource.substring(1);
+ if (!resource.endsWith("/")) {
+ paths.add(resource);
+ }
+ }
+ }
+ return paths;
+ }
+
+ void loadFontsUrl(URL url) {
+ try (BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream(), UTF_8))) {
+ String line = null;
+ while ((line = in.readLine()) != null) {
+ line = line.trim();
+ if (!line.equals("") && !line.startsWith("#")) {
+ fonts.add(line);
+ }
+ }
+ } catch (IOException e) {
+ throw new IllegalArgumentException("Cannot load URL " + url, e);
+ }
+ }
+
+ void loadBodyHtml(URL url) {
+ try (BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream(), UTF_8))) {
+ bodyHtml= IOUtils.toString(url,StandardCharsets.UTF_8);
+ } catch (IOException e) {
+ throw new IllegalArgumentException("Cannot load URL " + url, e);
+ }
+ }
+
+ void addImages(String pattern) {
+ Enumeration<URL> themeResources = themeBundle.findEntries(basePath, pattern, true);
+ if (themeResources == null)
+ return;
+ while (themeResources.hasMoreElements()) {
+ String resource = themeResources.nextElement().getPath();
+ // remove first '/' so that RWT registers it
+ resource = resource.substring(1);
+ if (!resource.endsWith("/")) {
+// if (resources.containsKey(resource))
+// log.warn("Overriding " + resource + " from " + themeBundle.getSymbolicName());
+// resources.put(resource, themeBRL);
+ imagesPaths.add(resource);
+ }
+
+ }
+
+ }
+
+ void addFonts(String pattern) {
+ Enumeration<URL> themeResources = themeBundle.findEntries(basePath, pattern, true);
+ if (themeResources == null)
+ return;
+ while (themeResources.hasMoreElements()) {
+ String resource = themeResources.nextElement().getPath();
+ // remove first '/' so that RWT registers it
+ resource = resource.substring(1);
+ if (!resource.endsWith("/")) {
+// if (resources.containsKey(resource))
+// log.warn("Overriding " + resource + " from " + themeBundle.getSymbolicName());
+// resources.put(resource, themeBRL);
+ fontsPaths.add(resource);
+ }
+
+ }
+
+ }
+
+ @Override
+ public InputStream getResourceAsStream(String resourceName) throws IOException {
+ URL res = themeBundle.getEntry(resourceName);
+ if (res == null) {
+ res = themeBundle.getResource(resourceName);
+ if (res == null)
+ return null;
+// throw new IllegalArgumentException(
+// "Resource " + resourceName + " not found in bundle " + themeBundle.getSymbolicName());
+ }
+ return res.openStream();
+ }
+
+ public String getThemeId() {
+ return themeId;
+ }
+
+// public void setThemeId(String themeId) {
+// this.themeId = themeId;
+// }
+//
+// public String getBasePath() {
+// return basePath;
+// }
+//
+// public void setBasePath(String basePath) {
+// this.basePath = basePath;
+// }
+//
+// public String getRapCssPath() {
+// return rapCssPath;
+// }
+//
+// public void setRapCssPath(String cssPath) {
+// this.rapCssPath = cssPath;
+// }
+
+ @Override
+ public Set<String> getWebCssPaths() {
+ return webCssPaths;
+ }
+
+ @Override
+ public Set<String> getRapCssPaths() {
+ return rapCssPaths;
+ }
+
+ @Override
+ public Set<String> getSwtCssPaths() {
+ return swtCssPaths;
+ }
+
+ @Override
+ public Set<String> getImagesPaths() {
+ return imagesPaths;
+ }
+
+ @Override
+ public Set<String> getFontsPaths() {
+ return fontsPaths;
+ }
+
+ @Override
+ public Integer getDefaultIconSize() {
+ return defaultIconSize;
+ }
+
+ @Override
+ public InputStream loadPath(String path) throws IOException {
+ URL url = themeBundle.getResource(path);
+ if (url == null)
+ throw new IllegalArgumentException(
+ "Path " + path + " not found in bundle " + themeBundle.getSymbolicName());
+ return url.openStream();
+ }
+
+ private static Bundle findThemeBundle(BundleContext bundleContext, String themeId) {
+ if (themeId == null)
+ return null;
+ // TODO optimize
+ // TODO deal with multiple versions
+ Bundle themeBundle = null;
+ if (themeId != null) {
+ for (Bundle bundle : bundleContext.getBundles())
+ if (themeId.equals(bundle.getSymbolicName())) {
+ themeBundle = bundle;
+ break;
+ }
+ }
+ return themeBundle;
+ }
+
+ @Override
+ public int hashCode() {
+ return themeId.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return "Bundle CMS Theme " + themeId;
+ }
+
+}
--- /dev/null
+package org.argeo.cms.osgi;
+
+import java.util.Collection;
+
+import javax.security.auth.Subject;
+
+import org.argeo.api.cms.CmsSession;
+import org.argeo.api.cms.CmsSessionId;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+
+public class CmsOsgiUtils {
+
+ /** @return The {@link CmsSession} for this {@link Subject} or null. */
+ public static CmsSession getCmsSession(BundleContext bc, Subject subject) {
+ if (subject.getPrivateCredentials(CmsSessionId.class).isEmpty())
+ return null;
+ CmsSessionId cmsSessionId = subject.getPrivateCredentials(CmsSessionId.class).iterator().next();
+ String uuid = cmsSessionId.getUuid().toString();
+ Collection<ServiceReference<CmsSession>> sr;
+ try {
+ sr = bc.getServiceReferences(CmsSession.class, "(" + CmsSession.SESSION_UUID + "=" + uuid + ")");
+ } catch (InvalidSyntaxException e) {
+ throw new IllegalArgumentException("Cannot get CMS session for uuid " + uuid, e);
+ }
+ ServiceReference<CmsSession> cmsSessionRef;
+ if (sr.size() == 1) {
+ cmsSessionRef = sr.iterator().next();
+ return bc.getService(cmsSessionRef);
+ } else if (sr.size() == 0) {
+ return null;
+ } else
+ throw new IllegalStateException(sr.size() + " CMS sessions registered for " + uuid);
+ }
+
+ /** Singleton.*/
+ private CmsOsgiUtils() {
+ }
+}
--- /dev/null
+package org.argeo.cms.osgi;
+
+import org.osgi.resource.Namespace;
+
+/** CMS Data Model capability namespace. */
+public class DataModelNamespace extends Namespace {
+
+ public static final String CMS_DATA_MODEL_NAMESPACE = "cms.datamodel";
+ public static final String NAME = "name";
+ public static final String CND = "cnd";
+ /** If 'true', indicates that no repository should be published */
+ public static final String ABSTRACT = "abstract";
+
+ private DataModelNamespace() {
+ // empty
+ }
+
+}
--- /dev/null
+package org.argeo.cms.osgi;
+
+import org.osgi.resource.Namespace;
+
+/** Namespace defining which resources can be published. Typically use to expose icon of scripts to the web. */
+public class PublishNamespace extends Namespace {
+
+ public static final String CMS_PUBLISH_NAMESPACE = "cms.publish";
+ public static final String PKG = "pkg";
+ public static final String FILE = "file";
+
+ private PublishNamespace() {
+ // empty
+ }
+
+}
import javax.security.auth.Subject;
import javax.servlet.http.HttpServletRequest;
-import org.argeo.cms.auth.CmsSession;
+import org.argeo.api.cms.CmsSession;
import org.argeo.cms.auth.CurrentUser;
+import org.argeo.cms.osgi.CmsOsgiUtils;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.service.http.HttpContext;
public static CmsSession getCmsSession(HttpServletRequest req) {
Subject subject = Subject
.getSubject((AccessControlContext) req.getAttribute(AccessControlContext.class.getName()));
- CmsSession cmsSession = CmsSession.getCmsSession(bundleContext, subject);
+ CmsSession cmsSession = CmsOsgiUtils.getCmsSession(bundleContext, subject);
return cmsSession;
}
}