<artifactId>org.argeo.dep.cms.e4.rcp</artifactId>
<name>Node Eclipse RCP</name>
<dependencies>
+ <!-- Argeo -->
+ <dependency>
+ <groupId>org.argeo.commons</groupId>
+ <artifactId>org.argeo.eclipse.ui</artifactId>
+ <version>2.1.77-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.commons.rcp</groupId>
+ <artifactId>org.argeo.eclipse.ui.rcp</artifactId>
+ <version>2.1.77-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.commons</groupId>
+ <artifactId>org.argeo.cms.ui</artifactId>
+ <version>2.1.77-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.commons</groupId>
+ <artifactId>org.argeo.cms.ui.theme</artifactId>
+ <version>2.1.77-SNAPSHOT</version>
+ </dependency>
+
+ <!-- Desktop -->
+ <dependency>
+ <groupId>org.argeo.commons.rcp</groupId>
+ <artifactId>org.argeo.cms.desktop</artifactId>
+ <version>2.1.77-SNAPSHOT</version>
+ </dependency>
+
+ <!-- E4 specific -->
+ <dependency>
+ <groupId>org.argeo.commons</groupId>
+ <artifactId>org.argeo.cms.e4</artifactId>
+ <version>2.1.77-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.commons.rcp</groupId>
+ <artifactId>org.argeo.cms.e4.rcp</artifactId>
+ <version>2.1.77-SNAPSHOT</version>
+ </dependency>
+
+ <!-- RCP specific -->
+ <!-- <dependency> -->
+ <!-- <groupId>org.argeo.commons.rcp</groupId> -->
+ <!-- <artifactId>org.argeo.cms.ui.workbench.rcp</artifactId> -->
+ <!-- <version>2.1.18-SNAPSHOT</version> -->
+ <!-- </dependency> -->
+ <!-- <dependency> -->
+ <!-- <groupId>org.argeo.commons</groupId> -->
+ <!-- <artifactId>org.argeo.cms.ui.workbench</artifactId> -->
+ <!-- <version>${version.argeo-commons}</version> -->
+ <!-- </dependency> -->
+
+ <dependency>
+ <groupId>org.argeo.commons</groupId>
+ <artifactId>org.argeo.dep.cms.node</artifactId>
+ <version>2.1.77-SNAPSHOT</version>
+ <type>pom</type>
+ </dependency>
+
+ <!-- SDK -->
+ <dependency>
+ <groupId>org.argeo.tp.equinox</groupId>
+ <artifactId>org.eclipse.osgi</artifactId>
+ <scope>test</scope>
+ </dependency>
+
<!-- SWT for ARM -->
<dependency>
<groupId>org.argeo.tp.rcp.e4</groupId>
</dependency>
- <!-- Eclipse -->
- <dependency>
- <groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.eclipse.ui</artifactId>
- <version>2.1.77-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.argeo.commons.rcp</groupId>
- <artifactId>org.argeo.eclipse.ui.rcp</artifactId>
- <version>2.1.77-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.cms.ui</artifactId>
- <version>2.1.77-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.cms.ui.theme</artifactId>
- <version>2.1.77-SNAPSHOT</version>
- </dependency>
-
- <!-- E4 specific -->
- <dependency>
- <groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.cms.e4</artifactId>
- <version>2.1.77-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.argeo.commons.rcp</groupId>
- <artifactId>org.argeo.cms.e4.rcp</artifactId>
- <version>2.1.77-SNAPSHOT</version>
- </dependency>
-
- <!-- RCP specific -->
- <!-- <dependency> -->
- <!-- <groupId>org.argeo.commons.rcp</groupId> -->
- <!-- <artifactId>org.argeo.cms.ui.workbench.rcp</artifactId> -->
- <!-- <version>2.1.18-SNAPSHOT</version> -->
- <!-- </dependency> -->
- <!-- <dependency> -->
- <!-- <groupId>org.argeo.commons</groupId> -->
- <!-- <artifactId>org.argeo.cms.ui.workbench</artifactId> -->
- <!-- <version>${version.argeo-commons}</version> -->
- <!-- </dependency> -->
-
- <dependency>
- <groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.dep.cms.node</artifactId>
- <version>2.1.77-SNAPSHOT</version>
- <type>pom</type>
- </dependency>
-
- <!-- SDK -->
- <dependency>
- <groupId>org.argeo.tp.equinox</groupId>
- <artifactId>org.eclipse.osgi</artifactId>
- <scope>test</scope>
- </dependency>
-
</dependencies>
<dependencyManagement>
<dependencies>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
--- /dev/null
+/bin/
+/target/
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.argeo.cms.desktop</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
--- /dev/null
+/MANIFEST.MF
--- /dev/null
+Import-Package: org.eclipse.swt,\
+*
--- /dev/null
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.argeo.commons.rcp</groupId>
+ <artifactId>argeo-rcp</artifactId>
+ <version>2.1.77-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+ <artifactId>org.argeo.cms.desktop</artifactId>
+ <name>CMS Desktop</name>
+ <packaging>jar</packaging>
+ <dependencies>
+ <!-- Base Argeo UI -->
+ <dependency>
+ <groupId>org.argeo.commons</groupId>
+ <artifactId>org.argeo.cms.ui</artifactId>
+ <version>2.1.77-SNAPSHOT</version>
+ </dependency>
+ <!-- RCP specific -->
+ <dependency>
+ <groupId>org.argeo.commons.rcp</groupId>
+ <artifactId>org.argeo.eclipse.ui.rcp</artifactId>
+ <version>2.1.77-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+</project>
\ No newline at end of file
--- /dev/null
+package org.argeo.cms.desktop;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+public class Activator implements BundleActivator {
+
+ private static BundleContext context;
+
+ static BundleContext getContext() {
+ return context;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext bundleContext) throws Exception {
+ Activator.context = bundleContext;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext bundleContext) throws Exception {
+ Activator.context = null;
+ }
+
+}
--- /dev/null
+package org.argeo.cms.desktop;
+
+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.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.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.swt.widgets.ToolItem;
+
+public class CmsDesktopManager {
+ private Display display;
+
+ private Shell rootShell;
+ private Shell toolBarShell;
+
+ public void init() {
+ display = Display.getCurrent();
+ if (display != null)
+ throw new IllegalStateException("Already a display " + display);
+ display = new Display();
+
+ int toolBarSize = 48;
+
+ if (isFullScreen()) {
+ rootShell = new Shell(display, SWT.NO_TRIM);
+ // rootShell.setMaximized(true);
+ rootShell.setFullScreen(true);
+ Rectangle bounds = display.getBounds();
+
+ rootShell.setSize(bounds.width, bounds.height);
+// Point realSize = rootShell.getSize();
+// rootShell.setBounds(bounds);
+// Rectangle realBounds = rootShell.getBounds();
+ } else {
+ rootShell = new Shell(display, SWT.SHELL_TRIM);
+ Rectangle shellArea = rootShell.computeTrim(200, 200, 800, 480);
+ rootShell.setSize(shellArea.width, shellArea.height);
+ }
+
+ rootShell.setLayout(new GridLayout(2, false));
+ Composite toolBarArea = new Composite(rootShell, SWT.NONE);
+ toolBarArea.setLayoutData(new GridData(toolBarSize, rootShell.getSize().y));
+
+ ToolBar toolBar;
+ if (isFullScreen()) {
+ toolBarShell = new Shell(rootShell, SWT.NO_TRIM | SWT.ON_TOP);
+ toolBar = new ToolBar(toolBarShell, SWT.VERTICAL | SWT.FLAT | SWT.BORDER);
+ createDock(toolBar);
+ toolBarShell.pack();
+ toolBarArea.setLayoutData(new GridData(toolBar.getSize().x, toolBar.getSize().y));
+ } else {
+ toolBar = new ToolBar(toolBarArea, SWT.VERTICAL | SWT.FLAT | SWT.BORDER);
+ createDock(toolBar);
+ toolBarArea.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false));
+ }
+
+ Composite backgroundArea = new Composite(rootShell, SWT.NONE);
+ backgroundArea.setLayout(new GridLayout(6, true));
+ DesktopLayer desktopLayer = new DesktopLayer();
+ desktopLayer.init(backgroundArea);
+ rootShell.open();
+ // rootShell.layout(true, true);
+
+ if (toolBarShell != null) {
+ toolBarShell.setLocation(new Point(0, 0));
+ toolBarShell.open();
+ }
+ }
+
+ protected void createDock(ToolBar toolBar) {
+
+ // toolBar.setLocation(clientArea.x, clientArea.y);
+
+ ToolItem closeI = new ToolItem(toolBar, SWT.PUSH);
+ closeI.setImage(display.getSystemImage(SWT.ICON_ERROR));
+ closeI.setToolTipText("Close");
+ closeI.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ rootShell.dispose();
+ }
+
+ });
+
+ ToolItem searchI = new ToolItem(toolBar, SWT.PUSH);
+ searchI.setImage(display.getSystemImage(SWT.ICON_QUESTION));
+ searchI.setToolTipText("Search");
+ searchI.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ // rootShell.dispose();
+ }
+
+ });
+ // toolBar.setSize(48, toolBar.getSize().y);
+ toolBar.pack();
+ }
+
+ public void run() {
+ while (!rootShell.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ }
+
+ public void dispose() {
+ if (!rootShell.isDisposed())
+ rootShell.dispose();
+ }
+
+ protected boolean isFullScreen() {
+ return true;
+ }
+
+ public static void main(String[] args) {
+ CmsDesktopManager desktopManager = new CmsDesktopManager();
+ desktopManager.init();
+ // Runtime.getRuntime().addShutdownHook(new Thread(() ->
+ // desktopManager.dispose(), "Dispose desktop manager"));
+ desktopManager.run();
+ desktopManager.dispose();
+ }
+
+}
--- /dev/null
+package org.argeo.cms.desktop;
+
+import java.io.IOException;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import org.apache.commons.io.FilenameUtils;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.program.Program;
+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;
+
+public class DesktopLayer {
+ // TODO make it configurable
+ private Path desktopDir = Paths.get(System.getProperty("user.home"), "tmp");
+
+ public void init(Composite parentShell) {
+// Decorations shell = new Decorations(parentShell, SWT.CLOSE);
+// shell.setLayoutData(new GridData(GridData.FILL_BOTH));
+ createUi(parentShell, desktopDir);
+ // shell.open();
+ }
+
+ public Control createUi(Composite parent, Path context) {
+ // parent.setLayout(new FillLayout());
+ try {
+ DirectoryStream<Path> ds = Files.newDirectoryStream(context);
+ ds.forEach((path) -> createIcon(parent, path));
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return parent;
+
+ }
+
+ protected void createIcon(Composite parent, Path path) {
+ String ext = FilenameUtils.getExtension(path.getFileName().toString());
+ Program program = Program.findProgram(ext);
+ if (program == null) {
+ createDefaultIcon(parent, path);
+ return;
+ }
+
+ Display display = parent.getDisplay();
+ ImageData iconData = program.getImageData();
+
+ Image iconImage;
+ if (iconData == null) {
+ iconImage = display.getSystemImage(SWT.ICON_INFORMATION);
+ iconData = iconImage.getImageData();
+ } else {
+ iconImage = new Image(display, iconData);
+ }
+
+ Composite icon = new Composite(parent, SWT.NONE);
+ icon.setLayoutData(new GridData(48, 72));
+ icon.setLayout(new GridLayout());
+ // Button
+ Button iconB = new Button(icon, SWT.FLAT);
+ iconB.setImage(iconImage);
+ // iconB.setLayoutData(new GridData(iconData.width, iconData.height));
+ iconB.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false));
+ iconB.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ program.execute(path.toString());
+ }
+
+ });
+ // Label
+ Label iconL = new Label(icon, SWT.WRAP);
+ iconL.setText(path.getFileName().toString());
+ iconL.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false));
+ }
+
+ protected void createDefaultIcon(Composite parent, Path path) {
+ Composite icon = new Composite(parent, SWT.NONE);
+ icon.setLayout(new GridLayout());
+ Label iconL = new Label(icon, SWT.NONE);
+ iconL.setText(path.getFileName().toString());
+ iconL.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true));
+ }
+}
--- /dev/null
+package org.argeo.cms.desktop.mini;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.browser.Browser;
+import org.eclipse.swt.browser.LocationEvent;
+import org.eclipse.swt.browser.LocationListener;
+import org.eclipse.swt.browser.TitleListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+public class MiniBrowser {
+ private URL url;
+ private Text addressT;
+ private Browser browser;
+
+ public MiniBrowser(Composite parent, int style) {
+ parent.setLayout(new GridLayout());
+
+ Composite toolBar = new Composite(parent, SWT.NONE);
+ toolBar.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ toolBar.setLayout(new FillLayout());
+ addressT = new Text(toolBar, SWT.SINGLE | SWT.BORDER);
+ // addressT.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ addressT.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ setUrl(addressT.getText().trim());
+ }
+ });
+
+ browser = new Browser(parent, SWT.WEBKIT);
+ browser.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ browser.addLocationListener(new LocationListener() {
+
+ @Override
+ public void changing(LocationEvent event) {
+ }
+
+ @Override
+ public void changed(LocationEvent event) {
+ try {
+ MiniBrowser.this.url = new URL(browser.getUrl());
+ addressT.setText(url.toString());
+ } catch (MalformedURLException e) {
+ addressT.setText(e.getMessage());
+ throw new IllegalArgumentException("Cannot interpet new URL", e);
+
+ }
+ }
+ });
+ }
+
+ public void setUrl(URL url) {
+ this.url = url;
+ if (addressT != null)
+ addressT.setText(url.toString());
+ if (browser != null)
+ browser.setUrl(url.toString());
+ }
+
+ public void setUrl(String url) {
+ try {
+ setUrl(new URL(url));
+ } catch (MalformedURLException e) {
+ // try with http
+ try {
+ setUrl(new URL("http://"+url));
+ return;
+ } catch (MalformedURLException e1) {
+ // nevermind...
+ }
+ throw new IllegalArgumentException("Cannot interpret URL " + url, e);
+ }
+ }
+
+ public void addTitleListener(TitleListener titleListener) {
+ browser.addTitleListener(titleListener);
+ }
+
+ public static void main(String[] args) {
+ Display display = Display.getCurrent() == null ? new Display() : Display.getCurrent();
+ Shell shell = new Shell(display, SWT.SHELL_TRIM);
+
+ MiniBrowser miniBrowser = new MiniBrowser(shell, SWT.NONE);
+ miniBrowser.addTitleListener(e -> shell.setText(e.title));
+ String url = args.length > 0 ? args[0] : "http://www.argeo.org";
+ miniBrowser.setUrl(url);
+
+ shell.open();
+ shell.setSize(new Point(800, 480));
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ }
+
+}
--- /dev/null
+package org.argeo.cms.desktop.mini;
+
+import java.io.IOException;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+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.graphics.Point;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.program.Program;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.swt.widgets.Text;
+
+public class MiniExplorer {
+ private Path url;
+ private Text addressT;
+ private Table browser;
+
+ private boolean showHidden = false;
+
+ public MiniExplorer(Composite parent, int style) {
+ parent.setLayout(new GridLayout());
+
+ Composite toolBar = new Composite(parent, SWT.NONE);
+ toolBar.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ toolBar.setLayout(new FillLayout());
+ addressT = new Text(toolBar, SWT.SINGLE | SWT.BORDER);
+ // addressT.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ addressT.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ setUrl(addressT.getText().trim());
+ }
+ });
+ browser = createTable(parent, this.url);
+
+ }
+
+ public void setUrl(Path url) {
+ this.url = url;
+ if (addressT != null)
+ addressT.setText(url.toString());
+ if (browser != null) {
+ Composite parent = browser.getParent();
+ browser.dispose();
+ browser = createTable(parent, this.url);
+ parent.layout(true, true);
+ }
+ }
+
+ protected Table createTable(Composite parent, Path path) {
+ Table table = new Table(parent, SWT.BORDER);
+ table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ table.addMouseListener(new MouseAdapter() {
+
+ @Override
+ public void mouseDoubleClick(MouseEvent e) {
+ Point pt = new Point(e.x, e.y);
+ TableItem item = table.getItem(pt);
+ Path path = (Path) item.getData();
+ if (Files.isDirectory(path)) {
+ setUrl(path);
+ } else {
+ Program.launch(path.toString());
+ }
+ }
+ });
+
+ if (path != null) {
+ if (path.getParent() != null) {
+ TableItem parentTI = new TableItem(table, SWT.NONE);
+ parentTI.setText("..");
+ parentTI.setData(path.getParent());
+ }
+
+ try {
+ // directories
+ DirectoryStream<Path> ds = Files.newDirectoryStream(url, p -> Files.isDirectory(p) && isShown(p));
+ ds.forEach(p -> {
+ TableItem ti = new TableItem(table, SWT.NONE);
+ ti.setText(p.getFileName().toString() + "/");
+ ti.setData(p);
+ });
+ // files
+ ds = Files.newDirectoryStream(url, p -> !Files.isDirectory(p) && isShown(p));
+ ds.forEach(p -> {
+ TableItem ti = new TableItem(table, SWT.NONE);
+ ti.setText(p.getFileName().toString());
+ ti.setData(p);
+ });
+ } catch (IOException e1) {
+ // TODO Auto-generated catch block
+ e1.printStackTrace();
+ }
+ }
+ return table;
+ }
+
+ protected boolean isShown(Path path) {
+ if (showHidden)
+ return true;
+ try {
+ return !Files.isHidden(path);
+ } catch (IOException e) {
+ throw new IllegalArgumentException("Cannot check " + path, e);
+ }
+ }
+
+ public void setUrl(String url) {
+ setUrl(Paths.get(url));
+ }
+
+ public static void main(String[] args) {
+ Display display = Display.getCurrent() == null ? new Display() : Display.getCurrent();
+ Shell shell = new Shell(display, SWT.SHELL_TRIM);
+
+ MiniExplorer miniBrowser = new MiniExplorer(shell, SWT.NONE);
+ String url = args.length > 0 ? args[0] : System.getProperty("user.home");
+ miniBrowser.setUrl(url);
+
+ shell.open();
+ shell.setSize(new Point(800, 480));
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ }
+
+}
--- /dev/null
+package org.argeo.cms.desktop.mini;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.ImageLoader;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.RowLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Shell;
+
+public class MiniImageViewer implements PaintListener {
+ private URL url;
+ private Canvas area;
+
+ private Image image;
+
+ public MiniImageViewer(Composite parent, int style) {
+ parent.setLayout(new GridLayout());
+
+ Composite toolBar = new Composite(parent, SWT.NONE);
+ toolBar.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ toolBar.setLayout(new RowLayout());
+ Button load = new Button(toolBar, SWT.FLAT);
+ load.setText("\u2191");// up arrow
+ load.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ FileDialog fileDialog = new FileDialog(area.getShell());
+ String path = fileDialog.open();
+ if (path != null) {
+ setUrl(path);
+ }
+ }
+
+ });
+
+ area = new Canvas(parent, SWT.NONE);
+ area.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ area.addPaintListener(this);
+ }
+
+ protected void load(URL url) {
+ try {
+ ImageLoader imageLoader = new ImageLoader();
+ ImageData[] data = imageLoader.load(url.openStream());
+ image = new Image(area.getDisplay(), data[0]);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void paintControl(PaintEvent e) {
+ e.gc.drawImage(image, 0, 0);
+
+ }
+
+ protected Path url2path(URL url) {
+ try {
+ Path path = Paths.get(url.toURI());
+ return path;
+ } catch (URISyntaxException e) {
+ throw new IllegalStateException("Cannot convert " + url + " to uri", e);
+ }
+ }
+
+ public void setUrl(URL url) {
+ this.url = url;
+ if (area != null)
+ load(this.url);
+ }
+
+ public void setUrl(String url) {
+ try {
+ setUrl(new URL(url));
+ } catch (MalformedURLException e) {
+ // try with http
+ try {
+ setUrl(new URL("file://" + url));
+ return;
+ } catch (MalformedURLException e1) {
+ // nevermind...
+ }
+ throw new IllegalArgumentException("Cannot interpret URL " + url, e);
+ }
+ }
+
+ public static void main(String[] args) {
+ Display display = Display.getCurrent() == null ? new Display() : Display.getCurrent();
+ Shell shell = new Shell(display, SWT.SHELL_TRIM);
+
+ MiniImageViewer miniBrowser = new MiniImageViewer(shell, SWT.NONE);
+ String url = args.length > 0 ? args[0] : "";
+ if (!url.trim().equals("")) {
+ miniBrowser.setUrl(url);
+ shell.setText(url);
+ } else {
+ shell.setText("*");
+ }
+
+ shell.open();
+ shell.setSize(new Point(800, 480));
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ }
+
+}
--- /dev/null
+package org.argeo.cms.desktop.mini;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Caret;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+public class MiniTerminal implements KeyListener, PaintListener {
+
+ private Canvas area;
+ private Caret caret;
+
+ private StringBuffer buf = new StringBuffer("");
+ private StringBuffer userInput = new StringBuffer("");
+ private List<String> history = new ArrayList<>();
+
+ private Point charExtent = null;
+ private int charsPerLine = 0;
+ private String[] lines = new String[0];
+ private List<String> logicalLines = new ArrayList<>();
+
+ private Font mono;
+ private Charset charset;
+
+ private Path currentDir;
+ private Path homeDir;
+ private String host = "localhost";
+ private String username;
+
+ private boolean running = false;
+ private OutputStream stdIn = null;
+
+ public MiniTerminal(Composite parent, int style) {
+ charset = StandardCharsets.UTF_8;
+
+ Display display = parent.getDisplay();
+ // Linux-specific
+ mono = new Font(display, "Monospace", 10, SWT.NONE);
+
+ parent.setLayout(new GridLayout());
+ area = new Canvas(parent, SWT.NONE);
+ area.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ caret = new Caret(area, SWT.NONE);
+ area.setCaret(caret);
+
+ area.addKeyListener(this);
+ area.addPaintListener(this);
+
+ username = System.getProperty("user.name");
+ try {
+ host = InetAddress.getLocalHost().getHostName();
+ if (host.indexOf('.') > 0)
+ host = host.substring(0, host.indexOf('.'));
+ } catch (UnknownHostException e) {
+ host = "localhost";
+ }
+ homeDir = Paths.get(System.getProperty("user.home"));
+ currentDir = homeDir;
+
+ buf = new StringBuffer(prompt());
+ }
+
+ @Override
+ public void keyPressed(KeyEvent e) {
+ }
+
+ @Override
+ public void keyReleased(KeyEvent e) {
+ if (e.keyLocation != 0)
+ return;// weird characters
+ // System.out.println(e.character);
+ if (e.keyCode == 0xd) {// return
+ markLogicalLine();
+ if (!running)
+ processUserInput();
+ // buf.append(prompt());
+ } else if (e.keyCode == 0x8) {// delete
+ if (userInput.length() == 0)
+ return;
+ userInput.setLength(userInput.length() - 1);
+ if (!running && buf.length() > 0)
+ buf.setLength(buf.length() - 1);
+ } else {
+ // if (!running)
+ buf.append(e.character);
+ userInput.append(e.character);
+ }
+
+ if (area.isDisposed())
+ return;
+ area.redraw();
+ // System.out.println("Append " + e);
+
+ if (running) {
+ if (stdIn != null) {
+ try {
+ stdIn.write(Character.toString(e.character).getBytes(charset));
+ } catch (IOException e1) {
+ // TODO Auto-generated catch block
+ e1.printStackTrace();
+ }
+ }
+ }
+ }
+
+ protected String prompt() {
+ String fileName = currentDir.equals(homeDir) ? "~" : currentDir.getFileName().toString();
+ String end = username.equals("root") ? "]# " : "]$ ";
+ return "[" + username + "@" + host + " " + fileName + end;
+ }
+
+ private void displayPrompt() {
+ buf.append(prompt() + userInput);
+ }
+
+ protected void markLogicalLine() {
+ String str = buf.toString().trim();
+ logicalLines.add(str);
+ buf = new StringBuffer("");
+ }
+
+ private void processUserInput() {
+ String cmd = userInput.toString();
+ userInput = new StringBuffer("");
+ processUserInput(cmd);
+ history.add(cmd);
+ }
+
+ protected void processUserInput(String input) {
+ try {
+ StringTokenizer st = new StringTokenizer(input);
+ List<String> args = new ArrayList<>();
+ while (st.hasMoreTokens())
+ args.add(st.nextToken());
+ if (args.size() == 0) {
+ displayPrompt();
+ return;
+ }
+
+ // change directory
+ if (args.get(0).equals("cd")) {
+ if (args.size() == 1) {
+ setPath(homeDir);
+ } else {
+ Path newPath = currentDir.resolve(args.get(1));
+ if (!Files.exists(newPath) || !Files.isDirectory(newPath)) {
+ println(newPath + ": No such file or directory");
+ return;
+ }
+ setPath(newPath);
+ }
+ displayPrompt();
+ return;
+ }
+ // show current directory
+ else if (args.get(0).equals("pwd")) {
+ println(currentDir);
+ displayPrompt();
+ return;
+ }
+ // exit
+ else if (args.get(0).equals("exit")) {
+ println("logout");
+ area.getShell().dispose();
+ return;
+ }
+
+ ProcessBuilder pb = new ProcessBuilder(args);
+ pb.redirectErrorStream(true);
+ pb.directory(currentDir.toFile());
+// Process process = Runtime.getRuntime().exec(input, null, currentPath.toFile());
+ Process process = pb.start();
+
+ stdIn = process.getOutputStream();
+ Thread readOut = new Thread("Read out") {
+ @Override
+ public void run() {
+ running = true;
+ try (BufferedReader in = new BufferedReader(
+ new InputStreamReader(process.getInputStream(), charset))) {
+ String line = null;
+ while ((line = in.readLine()) != null) {
+ println(line);
+ }
+ } catch (IOException e) {
+ println(e.getMessage());
+ }
+ stdIn = null;
+ displayPrompt();
+ running = false;
+ }
+ };
+ readOut.start();
+ } catch (IOException e) {
+ println(e.getMessage());
+ displayPrompt();
+ }
+ }
+
+ protected int linesForLogicalLine(char[] line) {
+ return line.length / charsPerLine + 1;
+ }
+
+ protected void println(Object line) {
+ buf.append(line);
+ markLogicalLine();
+ }
+
+ protected void refreshLines(int charPerLine, int nbrOfLines) {
+ if (lines.length != nbrOfLines) {
+ lines = new String[nbrOfLines];
+ Arrays.fill(lines, null);
+ }
+ if (this.charsPerLine != charPerLine)
+ this.charsPerLine = charPerLine;
+
+ int currentLine = nbrOfLines - 1;
+ // current line
+ if (buf.length() > 0) {
+ lines[currentLine] = buf.toString();
+ } else {
+ lines[currentLine] = "";
+ }
+ currentLine--;
+
+ logicalLines: for (int i = logicalLines.size() - 1; i >= 0; i--) {
+ char[] logicalLine = logicalLines.get(i).toCharArray();
+ int linesNeeded = linesForLogicalLine(logicalLine);
+ for (int j = linesNeeded - 1; j >= 0; j--) {
+ int from = j * charPerLine;
+ int to = j == linesNeeded - 1 ? from + charPerLine : Math.min(from + charPerLine, logicalLine.length);
+ lines[currentLine] = new String(Arrays.copyOfRange(logicalLine, from, to));
+// System.out.println("Set line " + currentLine + " to : " + lines[currentLine]);
+ currentLine--;
+ if (currentLine < 0)
+ break logicalLines;
+ }
+ }
+ }
+
+ @Override
+ public void paintControl(PaintEvent e) {
+ GC gc = e.gc;
+ gc.setFont(mono);
+ if (charExtent == null)
+ charExtent = gc.textExtent("a");
+
+ Point areaSize = area.getSize();
+ int charPerLine = areaSize.x / charExtent.x;
+ int nbrOfLines = areaSize.y / charExtent.y;
+ refreshLines(charPerLine, nbrOfLines);
+
+ for (int i = 0; i < lines.length; i++) {
+ String line = lines[i];
+ if (line != null)
+ gc.drawString(line, 0, i * charExtent.y);
+ }
+// String toDraw = buf.toString();
+// gc.drawString(toDraw, 0, 0);
+// area.setCaret(caret);
+ }
+
+ public void setPath(String path) {
+ this.currentDir = Paths.get(path);
+ }
+
+ public void setPath(Path path) {
+ this.currentDir = path;
+ }
+
+ public static void main(String[] args) {
+ Display display = Display.getCurrent() == null ? new Display() : Display.getCurrent();
+ Shell shell = new Shell(display, SWT.SHELL_TRIM);
+
+ MiniTerminal miniBrowser = new MiniTerminal(shell, SWT.NONE);
+ String url = args.length > 0 ? args[0] : System.getProperty("user.home");
+ miniBrowser.setPath(url);
+
+ shell.open();
+ shell.setSize(new Point(800, 480));
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ }
+
+}
--- /dev/null
+package org.argeo.cms.desktop.mini;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+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.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.RowLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+public class MiniTextEditor {
+ private URL url;
+ private Text text;
+
+ public MiniTextEditor(Composite parent, int style) {
+ parent.setLayout(new GridLayout());
+
+ Composite toolBar = new Composite(parent, SWT.NONE);
+ toolBar.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ toolBar.setLayout(new RowLayout());
+ Button load = new Button(toolBar, SWT.FLAT);
+ load.setText("\u2191");// up arrow
+ load.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ FileDialog fileDialog = new FileDialog(text.getShell());
+ String path = fileDialog.open();
+ if (path != null) {
+ setUrl(path);
+ }
+ }
+
+ });
+
+ Button save = new Button(toolBar, SWT.FLAT);
+ save.setText("\u2193");// down arrow
+ // save.setText("\u1F609");// emoji
+ save.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ save(url);
+ }
+
+ });
+
+ text = new Text(parent, SWT.WRAP | SWT.MULTI | SWT.BORDER | SWT.V_SCROLL);
+ text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ }
+
+ protected void load(URL url) {
+ text.setText("");
+ // TODO deal with encoding and binary data
+ try (BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream(), StandardCharsets.UTF_8))) {
+ String line = null;
+ while ((line = in.readLine()) != null) {
+ text.append(line + "\n");
+ }
+ text.setEditable(true);
+ } catch (IOException e) {
+ if (e instanceof FileNotFoundException) {
+ Path path = url2path(url);
+ try {
+ Files.createFile(path);
+ load(url);
+ return;
+ } catch (IOException e1) {
+ e = e1;
+ }
+ }
+ text.setText(e.getMessage());
+ text.setEditable(false);
+ e.printStackTrace();
+ // throw new IllegalStateException("Cannot load " + url, e);
+ }
+ }
+
+ protected Path url2path(URL url) {
+ try {
+ Path path = Paths.get(url.toURI());
+ return path;
+ } catch (URISyntaxException e) {
+ throw new IllegalStateException("Cannot convert " + url + " to uri", e);
+ }
+ }
+
+ protected void save(URL url) {
+ if (!url.getProtocol().equals("file"))
+ throw new IllegalArgumentException(url.getProtocol() + " protocol is not supported for write");
+ Path path = url2path(url);
+ try (BufferedWriter out = new BufferedWriter(new OutputStreamWriter(Files.newOutputStream(path)))) {
+ out.write(text.getText());
+ } catch (IOException e) {
+ throw new IllegalStateException("Cannot save " + url + " to " + path, e);
+ }
+ }
+
+ public void setUrl(URL url) {
+ this.url = url;
+ if (text != null)
+ load(url);
+ }
+
+ public void setUrl(String url) {
+ try {
+ setUrl(new URL(url));
+ } catch (MalformedURLException e) {
+ // try with http
+ try {
+ setUrl(new URL("file://" + url));
+ return;
+ } catch (MalformedURLException e1) {
+ // nevermind...
+ }
+ throw new IllegalArgumentException("Cannot interpret URL " + url, e);
+ }
+ }
+
+ public static void main(String[] args) {
+ Display display = Display.getCurrent() == null ? new Display() : Display.getCurrent();
+ Shell shell = new Shell(display, SWT.SHELL_TRIM);
+
+ MiniTextEditor miniBrowser = new MiniTextEditor(shell, SWT.NONE);
+ String url = args.length > 0 ? args[0] : "";
+ if (!url.trim().equals("")) {
+ miniBrowser.setUrl(url);
+ shell.setText(url);
+ } else {
+ shell.setText("*");
+ }
+
+ shell.open();
+ shell.setSize(new Point(800, 480));
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ }
+
+}
<packaging>pom</packaging>
<modules>
<module>org.argeo.eclipse.ui.rcp</module>
+ <module>org.argeo.cms.desktop</module>
<module>org.argeo.cms.e4.rcp</module>
<module>dep</module>
<!-- <module>demo</module> -->