+++ /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/
-*.log
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>org.argeo.swt.minidesktop</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
-package org.argeo.minidesktop;
-
-import java.util.Arrays;
-import java.util.List;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.browser.Browser;
-import org.eclipse.swt.browser.LocationAdapter;
-import org.eclipse.swt.browser.LocationEvent;
-import org.eclipse.swt.events.KeyAdapter;
-import org.eclipse.swt.events.KeyEvent;
-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.FillLayout;
-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;
-import org.eclipse.swt.widgets.Text;
-
-/** A very minimalistic web browser based on {@link Browser}. */
-public class MiniBrowser {
- private static Point defaultShellSize = new Point(800, 480);
-
- private Browser browser;
- private Text addressT;
-
- private final boolean fullscreen;
- private final boolean appMode;
-
- public MiniBrowser(Composite composite, String url, boolean fullscreen, boolean appMode) {
- this.fullscreen = fullscreen;
- this.appMode = appMode;
- createUi(composite);
- setUrl(url);
- }
-
- public Control createUi(Composite parent) {
- parent.setLayout(noSpaceGridLayout(new GridLayout()));
- if (!isAppMode()) {
- Control toolBar = createToolBar(parent);
- toolBar.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
- }
- Control body = createBody(parent);
- body.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- return body;
- }
-
- protected Control createToolBar(Composite parent) {
- Composite toolBar = new Composite(parent, SWT.NONE);
- toolBar.setLayout(new FillLayout());
- addressT = new Text(toolBar, SWT.SINGLE);
- addressT.addSelectionListener(new SelectionAdapter() {
-
- @Override
- public void widgetDefaultSelected(SelectionEvent e) {
- setUrl(addressT.getText().trim());
- }
- });
- return toolBar;
- }
-
- protected Control createBody(Composite parent) {
- browser = new Browser(parent, SWT.NONE);
- if (isFullScreen())
- browser.addKeyListener(new KeyAdapter() {
- @Override
- public void keyPressed(KeyEvent e) {
- if (e.keyCode == 0x77 && e.stateMask == 0x40000) {// Ctrl+W
- browser.getShell().dispose();
- }
- }
- });
- browser.addLocationListener(new LocationAdapter() {
- @Override
- public void changed(LocationEvent event) {
- System.out.println(event);
- if (addressT != null)
- addressT.setText(event.location);
- }
-
- });
- browser.addTitleListener(e -> titleChanged(e.title));
- browser.addOpenWindowListener((e) -> {
- e.browser = openNewBrowserWindow();
- });
- return browser;
- }
-
- protected Browser openNewBrowserWindow() {
-
- if (isFullScreen()) {
- // TODO manage multiple tabs?
- return browser;
- } else {
- Shell newShell = new Shell(browser.getDisplay(), SWT.SHELL_TRIM);
- MiniBrowser newMiniBrowser = new MiniBrowser(newShell, null, false, isAppMode());
- newShell.setSize(defaultShellSize);
- newShell.open();
- return newMiniBrowser.browser;
- }
- }
-
- protected boolean isFullScreen() {
- return fullscreen;
- }
-
- void setUrl(String url) {
- if (browser != null && url != null && !url.equals(browser.getUrl()))
- browser.setUrl(url.toString());
- }
-
- /** Called when URL changed; to be overridden, does nothing by default. */
- protected void urlChanged(String url) {
- }
-
- /** Called when title changed; to be overridden, does nothing by default. */
- protected void titleChanged(String title) {
- }
-
- protected Browser getBrowser() {
- return browser;
- }
-
- protected boolean isAppMode() {
- return appMode;
- }
-
- private static GridLayout noSpaceGridLayout(GridLayout layout) {
- layout.horizontalSpacing = 0;
- layout.verticalSpacing = 0;
- layout.marginWidth = 0;
- layout.marginHeight = 0;
- return layout;
- }
-
- public static void main(String[] args) {
- List<String> options = Arrays.asList(args);
- if (options.contains("--help")) {
- System.out.println("Usage: java " + MiniBrowser.class.getName().replace('.', '/') + " [OPTION] [URL]");
- System.out.println("A minimalistic web browser Eclipse SWT Browser integration.");
- System.out.println(" --fullscreen : take control of the whole screen (default is to run in a window)");
- System.out.println(" --app : open without an address bar and a toolbar");
- System.out.println(" --help : print this help and exit");
- System.exit(1);
- }
- boolean fullscreen = options.contains("--fullscreen");
- boolean appMode = options.contains("--app");
- String url = "https://start.duckduckgo.com/";
- if (options.size() > 0) {
- String last = options.get(options.size() - 1);
- if (!last.startsWith("--"))
- url = last.trim();
- }
-
- Display display = Display.getCurrent() == null ? new Display() : Display.getCurrent();
- Shell shell;
- if (fullscreen) {
- shell = new Shell(display, SWT.NO_TRIM);
- shell.setFullScreen(true);
- Rectangle bounds = display.getBounds();
- shell.setSize(bounds.width, bounds.height);
- } else {
- shell = new Shell(display, SWT.SHELL_TRIM);
- shell.setSize(defaultShellSize);
- }
-
- new MiniBrowser(shell, url, fullscreen, appMode) {
-
- @Override
- protected void titleChanged(String title) {
- shell.setText(title);
- }
- };
- shell.open();
-
- while (!shell.isDisposed()) {
- if (!display.readAndDispatch())
- display.sleep();
- }
- }
-
-}
+++ /dev/null
-package org.argeo.minidesktop;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import org.eclipse.swt.SWTException;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.Display;
-
-/** Icons. */
-public class MiniDesktopImages {
-
- public final Image homeIcon;
- public final Image exitIcon;
-
- public final Image terminalIcon;
- public final Image browserIcon;
- public final Image explorerIcon;
- public final Image textEditorIcon;
-
- public final Image folderIcon;
- public final Image fileIcon;
-
- public MiniDesktopImages(Display display) {
- homeIcon = loadImage(display, "nav_home@2x.png");
- exitIcon = loadImage(display, "delete@2x.png");
-
- terminalIcon = loadImage(display, "console_view@2x.png");
- browserIcon = loadImage(display, "external_browser@2x.png");
- explorerIcon = loadImage(display, "fldr_obj@2x.png");
- textEditorIcon = loadImage(display, "cheatsheet_obj@2x.png");
-
- folderIcon = loadImage(display, "fldr_obj@2x.png");
- fileIcon = loadImage(display, "file_obj@2x.png");
- }
-
- static Image loadImage(Display display, String path) {
- InputStream stream = MiniDesktopImages.class.getResourceAsStream(path);
- if (stream == null)
- throw new IllegalArgumentException("Image " + path + " not found");
- Image image = null;
- try {
- image = new Image(display, stream);
- } catch (SWTException ex) {
- } finally {
- try {
- stream.close();
- } catch (IOException ex) {
- }
- }
- return image;
- }
-}
+++ /dev/null
-package org.argeo.minidesktop;
-
-import java.lang.management.ManagementFactory;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.nio.file.Path;
-import java.util.Arrays;
-import java.util.List;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.CTabFolder;
-import org.eclipse.swt.custom.CTabItem;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.ImageData;
-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.program.Program;
-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.ToolBar;
-import org.eclipse.swt.widgets.ToolItem;
-
-/** A very minimalistic desktop manager based on Java and Eclipse SWT. */
-public class MiniDesktopManager {
- private Display display;
-
- private Shell rootShell;
- private Shell toolBarShell;
- private CTabFolder tabFolder;
- private int maxTabTitleLength = 16;
-
- private final boolean fullscreen;
- private final boolean stacking;
-
- private MiniDesktopImages images;
-
- public MiniDesktopManager(boolean fullscreen, boolean stacking) {
- this.fullscreen = fullscreen;
- this.stacking = stacking;
- }
-
- public void init() {
- Display.setAppName("Mini SWT Desktop");
- display = Display.getCurrent();
- if (display != null)
- throw new IllegalStateException("Already a display " + display);
- display = new Display();
-
- if (display.getTouchEnabled()) {
- System.out.println("Touch enabled.");
- }
-
- images = new MiniDesktopImages(display);
-
- int toolBarSize = 48;
-
- if (isFullscreen()) {
- rootShell = new Shell(display, SWT.NO_TRIM);
- rootShell.setFullScreen(true);
- Rectangle bounds = display.getBounds();
- rootShell.setLocation(0, 0);
- rootShell.setSize(bounds.width, bounds.height);
- } else {
- rootShell = new Shell(display, SWT.CLOSE | SWT.RESIZE);
- Rectangle shellArea = rootShell.computeTrim(200, 200, 800, 480);
- rootShell.setSize(shellArea.width, shellArea.height);
- rootShell.setText(Display.getAppName());
- rootShell.setImage(images.terminalIcon);
- }
-
- rootShell.setLayout(noSpaceGridLayout(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.CENTER, false, false));
- }
-
- if (isStacking()) {
- tabFolder = new CTabFolder(rootShell, SWT.MULTI | SWT.BORDER | SWT.BOTTOM);
- tabFolder.setLayout(noSpaceGridLayout(new GridLayout()));
- tabFolder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-
- Color selectionBackground = display.getSystemColor(SWT.COLOR_LIST_SELECTION);
- tabFolder.setSelectionBackground(selectionBackground);
-
- // background
- Control background = createBackground(tabFolder);
- CTabItem homeTabItem = new CTabItem(tabFolder, SWT.NONE);
- homeTabItem.setText("Home");
- homeTabItem.setImage(images.homeIcon);
- homeTabItem.setControl(background);
- tabFolder.setFocus();
- } else {
- createBackground(rootShell);
- }
-
- rootShell.open();
- // rootShell.layout(true, true);
-
- if (toolBarShell != null) {
- int toolBarShellY = (display.getBounds().height - toolBar.getSize().y) / 2;
- toolBarShell.setLocation(0, toolBarShellY);
- toolBarShell.open();
- }
-
- long jvmUptime = ManagementFactory.getRuntimeMXBean().getUptime();
- System.out.println("SWT Mini Desktop Manager available in " + jvmUptime + " ms.");
- }
-
- protected void createDock(ToolBar toolBar) {
- // Terminal
- addToolItem(toolBar, images.terminalIcon, "Terminal", () -> {
- String url = System.getProperty("user.home");
- AppContext appContext = createAppParent(images.terminalIcon);
- new MiniTerminal(appContext.getAppParent(), url) {
-
- @Override
- protected void exitCalled() {
- if (appContext.shell != null)
- appContext.shell.dispose();
- if (appContext.tabItem != null)
- appContext.tabItem.dispose();
- }
- };
- String title;
- try {
- title = System.getProperty("user.name") + "@" + InetAddress.getLocalHost().getHostName();
- } catch (UnknownHostException e) {
- title = System.getProperty("user.name") + "@localhost";
- }
- if (appContext.shell != null)
- appContext.shell.setText(title);
- if (appContext.tabItem != null) {
- appContext.tabItem.setText(tabTitle(title));
- appContext.tabItem.setToolTipText(title);
- }
- openApp(appContext);
- });
-
- // Web browser
- addToolItem(toolBar, images.browserIcon, "Browser", () -> {
- String url = "https://start.duckduckgo.com/";
- AppContext appContext = createAppParent(images.browserIcon);
- new MiniBrowser(appContext.getAppParent(), url, false, false) {
- @Override
- protected void titleChanged(String title) {
- if (appContext.shell != null)
- appContext.shell.setText(title);
- if (appContext.tabItem != null) {
- appContext.tabItem.setText(tabTitle(title));
- appContext.tabItem.setToolTipText(title);
- }
- }
- };
- openApp(appContext);
- });
-
- // File explorer
- addToolItem(toolBar, images.explorerIcon, "Explorer", () -> {
- String url = System.getProperty("user.home");
- AppContext appContext = createAppParent(images.explorerIcon);
- new MiniExplorer(appContext.getAppParent(), url) {
-
- @Override
- protected void pathChanged(Path path) {
- if (appContext.shell != null)
- appContext.shell.setText(path.toString());
- if (appContext.tabItem != null) {
- appContext.tabItem.setText(path.getFileName().toString());
- appContext.tabItem.setToolTipText(path.toString());
- }
- }
- };
- openApp(appContext);
- });
-
- // Separator
- new ToolItem(toolBar, SWT.SEPARATOR);
-
- // Exit
- addToolItem(toolBar, images.exitIcon, "Exit", () -> rootShell.dispose());
-
- toolBar.pack();
- }
-
- protected String tabTitle(String title) {
- return title.length() > maxTabTitleLength ? title.substring(0, maxTabTitleLength) : title;
- }
-
- protected void addToolItem(ToolBar toolBar, Image icon, String name, Runnable action) {
- ToolItem searchI = new ToolItem(toolBar, SWT.PUSH);
- searchI.setImage(icon);
- searchI.setToolTipText(name);
- searchI.addSelectionListener(new SelectionAdapter() {
-
- @Override
- public void widgetSelected(SelectionEvent e) {
- action.run();
- }
-
- });
- }
-
- protected AppContext createAppParent(Image icon) {
- if (isStacking()) {
- Composite appParent = new Composite(tabFolder, SWT.CLOSE);
- appParent.setLayout(noSpaceGridLayout(new GridLayout()));
- CTabItem item = new CTabItem(tabFolder, SWT.CLOSE);
- item.setImage(icon);
- item.setControl(appParent);
- return new AppContext(item);
- } else {
- Shell shell = isFullscreen() ? new Shell(rootShell, SWT.SHELL_TRIM)
- : new Shell(rootShell.getDisplay(), SWT.SHELL_TRIM);
- shell.setImage(icon);
- return new AppContext(shell);
- }
- }
-
- protected void openApp(AppContext appContext) {
- if (appContext.shell != null) {
- Shell shell = (Shell) appContext.shell;
- shell.open();
- shell.setSize(new Point(800, 480));
- }
- if (appContext.tabItem != null) {
- tabFolder.setFocus();
- tabFolder.setSelection(appContext.tabItem);
- }
- }
-
- protected Control createBackground(Composite parent) {
- Composite backgroundArea = new Composite(parent, SWT.NONE);
- backgroundArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- initBackground(backgroundArea);
- return backgroundArea;
- }
-
- protected void initBackground(Composite backgroundArea) {
- MiniHomePart homePart = new MiniHomePart() {
-
- @Override
- protected void fillAppsToolBar(ToolBar toolBar) {
- createDock(toolBar);
- }
- };
- homePart.createUiPart(backgroundArea, null);
- }
-
- public void run() {
- while (!rootShell.isDisposed()) {
- if (!display.readAndDispatch())
- display.sleep();
- }
- }
-
- public void dispose() {
- if (!rootShell.isDisposed())
- rootShell.dispose();
- }
-
- protected boolean isFullscreen() {
- return fullscreen;
- }
-
- protected boolean isStacking() {
- return stacking;
- }
-
- protected Image getIconForExt(String ext) {
- Program program = Program.findProgram(ext);
- if (program == null)
- return display.getSystemImage(SWT.ICON_INFORMATION);
-
- ImageData iconData = program.getImageData();
- if (iconData == null) {
- return display.getSystemImage(SWT.ICON_INFORMATION);
- } else {
- return new Image(display, iconData);
- }
-
- }
-
- private static GridLayout noSpaceGridLayout(GridLayout layout) {
- layout.horizontalSpacing = 0;
- layout.verticalSpacing = 0;
- layout.marginWidth = 0;
- layout.marginHeight = 0;
- return layout;
- }
-
- public static void main(String[] args) {
- List<String> options = Arrays.asList(args);
- if (options.contains("--help")) {
- System.out.println("Usage: java " + MiniDesktopManager.class.getName().replace('.', '/') + " [OPTION]");
- System.out.println("A minimalistic desktop manager based on Java and Eclipse SWT.");
- System.out.println(" --fullscreen : take control of the whole screen (default is to run in a window)");
- System.out.println(" --stacking : open apps as tabs (default is to create new windows)");
- System.out.println(" --help : print this help and exit");
- System.exit(1);
- }
- boolean fullscreen = options.contains("--fullscreen");
- boolean stacking = options.contains("--stacking");
-
- MiniDesktopManager desktopManager = new MiniDesktopManager(fullscreen, stacking);
- desktopManager.init();
- desktopManager.run();
- desktopManager.dispose();
- System.exit(0);
- }
-
- class AppContext {
- private Shell shell;
- private CTabItem tabItem;
-
- public AppContext(Shell shell) {
- this.shell = shell;
- }
-
- public AppContext(CTabItem tabItem) {
- this.tabItem = tabItem;
- }
-
- Composite getAppParent() {
- if (shell != null)
- return shell;
- if (tabItem != null)
- return (Composite) tabItem.getControl();
- throw new IllegalStateException();
- }
- }
-}
+++ /dev/null
-package org.argeo.minidesktop;
-
-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 path;
- private Text addressT;
- private Table browser;
-
- private boolean showHidden = false;
-
- public MiniExplorer(Composite parent, String url) {
- this(parent);
- setUrl(url);
- }
-
- public MiniExplorer(Composite parent) {
- parent.setLayout(noSpaceGridLayout(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);
- addressT.addSelectionListener(new SelectionAdapter() {
-
- @Override
- public void widgetDefaultSelected(SelectionEvent e) {
- setUrl(addressT.getText().trim());
- }
- });
- browser = createTable(parent, this.path);
-
- }
-
- public void setPath(Path url) {
- this.path = url;
- if (addressT != null)
- addressT.setText(url.toString());
- if (browser != null) {
- Composite parent = browser.getParent();
- browser.dispose();
- browser = createTable(parent, this.path);
- parent.layout(true, true);
- }
- pathChanged(url);
- }
-
- protected void pathChanged(Path path) {
-
- }
-
- 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)) {
- setPath(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(path, 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(path, 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) {
- setPath(Paths.get(url));
- }
-
- private static GridLayout noSpaceGridLayout(GridLayout layout) {
- layout.horizontalSpacing = 0;
- layout.verticalSpacing = 0;
- layout.marginWidth = 0;
- layout.marginHeight = 0;
- return layout;
- }
-
- public static void main(String[] args) {
- Display display = Display.getCurrent() == null ? new Display() : Display.getCurrent();
- Shell shell = new Shell(display, SWT.SHELL_TRIM);
-
- String url = args.length > 0 ? args[0] : System.getProperty("user.home");
- new MiniExplorer(shell, url) {
-
- @Override
- protected void pathChanged(Path path) {
- shell.setText(path.toString());
- }
-
- };
-
- shell.open();
- shell.setSize(new Point(800, 480));
- while (!shell.isDisposed()) {
- if (!display.readAndDispatch())
- display.sleep();
- }
- }
-
-}
+++ /dev/null
-package org.argeo.minidesktop;
-
-import java.net.InetAddress;
-import java.net.InterfaceAddress;
-import java.net.NetworkInterface;
-import java.net.SocketException;
-import java.net.UnknownHostException;
-import java.util.Enumeration;
-
-import org.eclipse.swt.SWT;
-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.Group;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.ProgressBar;
-import org.eclipse.swt.widgets.ToolBar;
-
-/** A start page displaying network information and resources. */
-public class MiniHomePart {
-
- public Control createUiPart(Composite parent, Object context) {
- parent.setLayout(new GridLayout(2, false));
- Display display = parent.getDisplay();
-
- // Apps
- Group appsGroup = new Group(parent, SWT.NONE);
- appsGroup.setText("Apps");
- appsGroup.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false, 2, 1));
- ToolBar appsToolBar = new ToolBar(appsGroup, SWT.HORIZONTAL | SWT.FLAT);
- fillAppsToolBar(appsToolBar);
-
- // Host
- Group hostGroup = new Group(parent, SWT.NONE);
- hostGroup.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false));
- hostGroup.setText("Host");
- hostGroup.setLayout(new GridLayout(2, false));
- label(hostGroup, "Hostname: ");
- try {
- InetAddress defaultAddr = InetAddress.getLocalHost();
- String hostname = defaultAddr.getHostName();
- label(hostGroup, hostname);
- label(hostGroup, "Address: ");
- label(hostGroup, defaultAddr.getHostAddress());
- } catch (UnknownHostException e) {
- label(hostGroup, e.getMessage());
- }
-
- Enumeration<NetworkInterface> netInterfaces = null;
- try {
- netInterfaces = NetworkInterface.getNetworkInterfaces();
- } catch (SocketException e) {
- label(hostGroup, "Interfaces: ");
- label(hostGroup, e.getMessage());
- }
- if (netInterfaces != null)
- while (netInterfaces.hasMoreElements()) {
- NetworkInterface netInterface = netInterfaces.nextElement();
- byte[] hardwareAddress = null;
- try {
- hardwareAddress = netInterface.getHardwareAddress();
- if (hardwareAddress != null) {
- label(hostGroup, convertHardwareAddress(hardwareAddress));
- label(hostGroup, netInterface.getName());
- for (InterfaceAddress addr : netInterface.getInterfaceAddresses()) {
- label(hostGroup, cleanHostAddress(addr.getAddress().getHostAddress()));
- label(hostGroup, Short.toString(addr.getNetworkPrefixLength()));
- }
- }
- } catch (SocketException e) {
- label(hostGroup, e.getMessage());
- }
- }
-
- // Resources
- Group resGroup = new Group(parent, SWT.NONE);
- resGroup.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
- resGroup.setText("Resources");
- resGroup.setLayout(new GridLayout(3, false));
-
- Runtime runtime = Runtime.getRuntime();
-
- String maxMemoryStr = Long.toString(runtime.maxMemory() / (1024 * 1024)) + " MB";
- label(resGroup, "Max Java memory: ");
- label(resGroup, maxMemoryStr);
- label(resGroup, "Java version: " + Runtime.version().toString());
-
- label(resGroup, "Usable Java memory: ");
- Label totalMemory = label(resGroup, maxMemoryStr);
- ProgressBar totalOnMax = new ProgressBar(resGroup, SWT.SMOOTH);
- totalOnMax.setMaximum(100);
- label(resGroup, "Used Java memory: ");
- Label usedMemory = label(resGroup, maxMemoryStr);
- ProgressBar usedOnTotal = new ProgressBar(resGroup, SWT.SMOOTH);
- totalOnMax.setMaximum(100);
- new Thread() {
- @Override
- public void run() {
- while (!totalOnMax.isDisposed()) {
- display.asyncExec(() -> {
- if (totalOnMax.isDisposed())
- return;
- totalOnMax.setSelection(javaTotalOnMaxPerct(runtime));
- usedOnTotal.setSelection(javaUsedOnTotalPerct(runtime));
- totalMemory.setText(Long.toString(runtime.totalMemory() / (1024 * 1024)) + " MB");
- usedMemory.setText(
- Long.toString((runtime.totalMemory() - runtime.freeMemory()) / (1024 * 1024)) + " MB");
- });
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- return;
- }
- }
- }
- }.start();
- return parent;
- }
-
- protected void fillAppsToolBar(ToolBar toolBar) {
-
- }
-
- protected int javaUsedOnTotalPerct(Runtime runtime) {
- return Math.toIntExact((runtime.totalMemory() - runtime.freeMemory()) * 100 / runtime.totalMemory());
- }
-
- protected int javaTotalOnMaxPerct(Runtime runtime) {
- return Math.toIntExact((runtime.totalMemory()) * 100 / runtime.maxMemory());
- }
-
- protected Label label(Composite parent, String text) {
- Label label = new Label(parent, SWT.WRAP);
- label.setText(text);
- return label;
- }
-
- protected String cleanHostAddress(String hostAddress) {
- // remove % from Ipv6 addresses
- int index = hostAddress.indexOf('%');
- if (index > 0)
- return hostAddress.substring(0, index);
- else
- return hostAddress;
- }
-
- protected String convertHardwareAddress(byte[] hardwareAddress) {
- if (hardwareAddress == null)
- return "";
- // from https://stackoverflow.com/a/2797498/7878010
- StringBuilder sb = new StringBuilder(18);
- for (byte b : hardwareAddress) {
- if (sb.length() > 0)
- sb.append(':');
- sb.append(String.format("%02x", b).toUpperCase());
- }
- return sb.toString();
- }
-}
+++ /dev/null
-package org.argeo.minidesktop;
-
-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.minidesktop;
-
-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;
-
- // Sub process
- private Process process;
- private boolean running = false;
- private OutputStream stdIn = null;
-
- private Thread readOut;
-
- public MiniTerminal(Composite parent, String url) {
- this(parent);
- setPath(url);
- }
-
- public MiniTerminal(Composite parent) {
- 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 (e.stateMask == 0x40000 && e.keyCode == 0x63) {// Ctrl+C
- if (process != null)
- process.destroy();
- } else if (e.stateMask == 0x40000 && e.keyCode == 0xdf) {// Ctrl+\
- if (process != null) {
- process.destroyForcibly();
- }
- } 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");
- exitCalled();
- return;
- }
-
- ProcessBuilder pb = new ProcessBuilder(args);
- pb.redirectErrorStream(true);
- pb.directory(currentDir.toFile());
-// Process process = Runtime.getRuntime().exec(input, null, currentPath.toFile());
- process = pb.start();
-
- stdIn = process.getOutputStream();
- readOut = new Thread("MiniTerminal 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 = null;
- process = null;
- }
- };
- 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);
- }
-
- protected void exitCalled() {
-
- }
-
- 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);
-
- String url = args.length > 0 ? args[0] : System.getProperty("user.home");
- new MiniTerminal(shell, url) {
-
- @Override
- protected void exitCalled() {
- shell.dispose();
- System.exit(0);
- }
- };
-
- shell.open();
- shell.setSize(new Point(800, 480));
- while (!shell.isDisposed()) {
- if (!display.readAndDispatch())
- display.sleep();
- }
- }
-
-}
+++ /dev/null
-package org.argeo.minidesktop;
-
-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();
- }
- }
-
-}
--- /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/
+*.log
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.argeo.swt.minidesktop</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
+package org.argeo.minidesktop;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.browser.Browser;
+import org.eclipse.swt.browser.LocationAdapter;
+import org.eclipse.swt.browser.LocationEvent;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+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.FillLayout;
+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;
+import org.eclipse.swt.widgets.Text;
+
+/** A very minimalistic web browser based on {@link Browser}. */
+public class MiniBrowser {
+ private static Point defaultShellSize = new Point(800, 480);
+
+ private Browser browser;
+ private Text addressT;
+
+ private final boolean fullscreen;
+ private final boolean appMode;
+
+ public MiniBrowser(Composite composite, String url, boolean fullscreen, boolean appMode) {
+ this.fullscreen = fullscreen;
+ this.appMode = appMode;
+ createUi(composite);
+ setUrl(url);
+ }
+
+ public Control createUi(Composite parent) {
+ parent.setLayout(noSpaceGridLayout(new GridLayout()));
+ if (!isAppMode()) {
+ Control toolBar = createToolBar(parent);
+ toolBar.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ }
+ Control body = createBody(parent);
+ body.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ return body;
+ }
+
+ protected Control createToolBar(Composite parent) {
+ Composite toolBar = new Composite(parent, SWT.NONE);
+ toolBar.setLayout(new FillLayout());
+ addressT = new Text(toolBar, SWT.SINGLE);
+ addressT.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ setUrl(addressT.getText().trim());
+ }
+ });
+ return toolBar;
+ }
+
+ protected Control createBody(Composite parent) {
+ browser = new Browser(parent, SWT.NONE);
+ if (isFullScreen())
+ browser.addKeyListener(new KeyAdapter() {
+ @Override
+ public void keyPressed(KeyEvent e) {
+ if (e.keyCode == 0x77 && e.stateMask == 0x40000) {// Ctrl+W
+ browser.getShell().dispose();
+ }
+ }
+ });
+ browser.addLocationListener(new LocationAdapter() {
+ @Override
+ public void changed(LocationEvent event) {
+ System.out.println(event);
+ if (addressT != null)
+ addressT.setText(event.location);
+ }
+
+ });
+
+ // FIXME make it portable
+// browser.addTitleListener(e -> titleChanged(e.title));
+// browser.addOpenWindowListener((e) -> {
+// e.browser = openNewBrowserWindow();
+// });
+ return browser;
+ }
+
+ protected Browser openNewBrowserWindow() {
+
+ if (isFullScreen()) {
+ // TODO manage multiple tabs?
+ return browser;
+ } else {
+ Shell newShell = new Shell(browser.getDisplay(), SWT.SHELL_TRIM);
+ MiniBrowser newMiniBrowser = new MiniBrowser(newShell, null, false, isAppMode());
+ newShell.setSize(defaultShellSize);
+ newShell.open();
+ return newMiniBrowser.browser;
+ }
+ }
+
+ protected boolean isFullScreen() {
+ return fullscreen;
+ }
+
+ void setUrl(String url) {
+ if (browser != null && url != null && !url.equals(browser.getUrl()))
+ browser.setUrl(url.toString());
+ }
+
+ /** Called when URL changed; to be overridden, does nothing by default. */
+ protected void urlChanged(String url) {
+ }
+
+ /** Called when title changed; to be overridden, does nothing by default. */
+ protected void titleChanged(String title) {
+ }
+
+ protected Browser getBrowser() {
+ return browser;
+ }
+
+ protected boolean isAppMode() {
+ return appMode;
+ }
+
+ private static GridLayout noSpaceGridLayout(GridLayout layout) {
+ layout.horizontalSpacing = 0;
+ layout.verticalSpacing = 0;
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ return layout;
+ }
+
+ public static void main(String[] args) {
+ List<String> options = Arrays.asList(args);
+ if (options.contains("--help")) {
+ System.out.println("Usage: java " + MiniBrowser.class.getName().replace('.', '/') + " [OPTION] [URL]");
+ System.out.println("A minimalistic web browser Eclipse SWT Browser integration.");
+ System.out.println(" --fullscreen : take control of the whole screen (default is to run in a window)");
+ System.out.println(" --app : open without an address bar and a toolbar");
+ System.out.println(" --help : print this help and exit");
+ System.exit(1);
+ }
+ boolean fullscreen = options.contains("--fullscreen");
+ boolean appMode = options.contains("--app");
+ String url = "https://start.duckduckgo.com/";
+ if (options.size() > 0) {
+ String last = options.get(options.size() - 1);
+ if (!last.startsWith("--"))
+ url = last.trim();
+ }
+
+ Display display = Display.getCurrent() == null ? new Display() : Display.getCurrent();
+ Shell shell;
+ if (fullscreen) {
+ shell = new Shell(display, SWT.NO_TRIM);
+ shell.setFullScreen(true);
+ Rectangle bounds = display.getBounds();
+ shell.setSize(bounds.width, bounds.height);
+ } else {
+ shell = new Shell(display, SWT.SHELL_TRIM);
+ shell.setSize(defaultShellSize);
+ }
+
+ new MiniBrowser(shell, url, fullscreen, appMode) {
+
+ @Override
+ protected void titleChanged(String title) {
+ shell.setText(title);
+ }
+ };
+ shell.open();
+
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ }
+
+}
--- /dev/null
+package org.argeo.minidesktop;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+/** Icons. */
+public class MiniDesktopImages {
+
+ public final Image homeIcon;
+ public final Image exitIcon;
+
+ public final Image terminalIcon;
+ public final Image browserIcon;
+ public final Image explorerIcon;
+ public final Image textEditorIcon;
+
+ public final Image folderIcon;
+ public final Image fileIcon;
+
+ public MiniDesktopImages(Display display) {
+ homeIcon = loadImage(display, "nav_home@2x.png");
+ exitIcon = loadImage(display, "delete@2x.png");
+
+ terminalIcon = loadImage(display, "console_view@2x.png");
+ browserIcon = loadImage(display, "external_browser@2x.png");
+ explorerIcon = loadImage(display, "fldr_obj@2x.png");
+ textEditorIcon = loadImage(display, "cheatsheet_obj@2x.png");
+
+ folderIcon = loadImage(display, "fldr_obj@2x.png");
+ fileIcon = loadImage(display, "file_obj@2x.png");
+ }
+
+ static Image loadImage(Display display, String path) {
+ InputStream stream = MiniDesktopImages.class.getResourceAsStream(path);
+ if (stream == null)
+ throw new IllegalArgumentException("Image " + path + " not found");
+ Image image = null;
+ try {
+ image = new Image(display, stream);
+ } catch (SWTException ex) {
+ } finally {
+ try {
+ stream.close();
+ } catch (IOException ex) {
+ }
+ }
+ return image;
+ }
+}
--- /dev/null
+package org.argeo.minidesktop;
+
+import java.lang.management.ManagementFactory;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CTabFolder;
+import org.eclipse.swt.custom.CTabItem;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Image;
+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;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.swt.widgets.ToolItem;
+
+/** A very minimalistic desktop manager based on Java and Eclipse SWT. */
+public class MiniDesktopManager {
+ private Display display;
+
+ private Shell rootShell;
+ private Shell toolBarShell;
+ private CTabFolder tabFolder;
+ private int maxTabTitleLength = 16;
+
+ private final boolean fullscreen;
+ private final boolean stacking;
+
+ private MiniDesktopImages images;
+
+ public MiniDesktopManager(boolean fullscreen, boolean stacking) {
+ this.fullscreen = fullscreen;
+ this.stacking = stacking;
+ }
+
+ public void init() {
+ Display.setAppName("Mini SWT Desktop");
+ display = Display.getCurrent();
+ if (display != null)
+ throw new IllegalStateException("Already a display " + display);
+ display = new Display();
+
+ if (display.getTouchEnabled()) {
+ System.out.println("Touch enabled.");
+ }
+
+ images = new MiniDesktopImages(display);
+
+ int toolBarSize = 48;
+
+ if (isFullscreen()) {
+ rootShell = new Shell(display, SWT.NO_TRIM);
+ rootShell.setFullScreen(true);
+ Rectangle bounds = display.getBounds();
+ rootShell.setLocation(0, 0);
+ rootShell.setSize(bounds.width, bounds.height);
+ } else {
+ rootShell = new Shell(display, SWT.CLOSE | SWT.RESIZE);
+ Rectangle shellArea = rootShell.computeTrim(200, 200, 800, 480);
+ rootShell.setSize(shellArea.width, shellArea.height);
+ rootShell.setText(Display.getAppName());
+ rootShell.setImage(images.terminalIcon);
+ }
+
+ rootShell.setLayout(noSpaceGridLayout(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.CENTER, false, false));
+ }
+
+ if (isStacking()) {
+ tabFolder = new CTabFolder(rootShell, SWT.MULTI | SWT.BORDER | SWT.BOTTOM);
+ tabFolder.setLayout(noSpaceGridLayout(new GridLayout()));
+ tabFolder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ Color selectionBackground = display.getSystemColor(SWT.COLOR_LIST_SELECTION);
+ tabFolder.setSelectionBackground(selectionBackground);
+
+ // background
+ Control background = createBackground(tabFolder);
+ CTabItem homeTabItem = new CTabItem(tabFolder, SWT.NONE);
+ homeTabItem.setText("Home");
+ homeTabItem.setImage(images.homeIcon);
+ homeTabItem.setControl(background);
+ tabFolder.setFocus();
+ } else {
+ createBackground(rootShell);
+ }
+
+ rootShell.open();
+ // rootShell.layout(true, true);
+
+ if (toolBarShell != null) {
+ int toolBarShellY = (display.getBounds().height - toolBar.getSize().y) / 2;
+ toolBarShell.setLocation(0, toolBarShellY);
+ toolBarShell.open();
+ }
+
+ long jvmUptime = ManagementFactory.getRuntimeMXBean().getUptime();
+ System.out.println("SWT Mini Desktop Manager available in " + jvmUptime + " ms.");
+ }
+
+ protected void createDock(ToolBar toolBar) {
+ // Terminal
+ addToolItem(toolBar, images.terminalIcon, "Terminal", () -> {
+ String url = System.getProperty("user.home");
+ AppContext appContext = createAppParent(images.terminalIcon);
+ new MiniTerminal(appContext.getAppParent(), url) {
+
+ @Override
+ protected void exitCalled() {
+ if (appContext.shell != null)
+ appContext.shell.dispose();
+ if (appContext.tabItem != null)
+ appContext.tabItem.dispose();
+ }
+ };
+ String title;
+ try {
+ title = System.getProperty("user.name") + "@" + InetAddress.getLocalHost().getHostName();
+ } catch (UnknownHostException e) {
+ title = System.getProperty("user.name") + "@localhost";
+ }
+ if (appContext.shell != null)
+ appContext.shell.setText(title);
+ if (appContext.tabItem != null) {
+ appContext.tabItem.setText(tabTitle(title));
+ appContext.tabItem.setToolTipText(title);
+ }
+ openApp(appContext);
+ });
+
+ // Web browser
+ addToolItem(toolBar, images.browserIcon, "Browser", () -> {
+ String url = "https://start.duckduckgo.com/";
+ AppContext appContext = createAppParent(images.browserIcon);
+ new MiniBrowser(appContext.getAppParent(), url, false, false) {
+ @Override
+ protected void titleChanged(String title) {
+ if (appContext.shell != null)
+ appContext.shell.setText(title);
+ if (appContext.tabItem != null) {
+ appContext.tabItem.setText(tabTitle(title));
+ appContext.tabItem.setToolTipText(title);
+ }
+ }
+ };
+ openApp(appContext);
+ });
+
+ // File explorer
+ addToolItem(toolBar, images.explorerIcon, "Explorer", () -> {
+ String url = System.getProperty("user.home");
+ AppContext appContext = createAppParent(images.explorerIcon);
+ new MiniExplorer(appContext.getAppParent(), url) {
+
+ @Override
+ protected void pathChanged(Path path) {
+ if (appContext.shell != null)
+ appContext.shell.setText(path.toString());
+ if (appContext.tabItem != null) {
+ appContext.tabItem.setText(path.getFileName().toString());
+ appContext.tabItem.setToolTipText(path.toString());
+ }
+ }
+ };
+ openApp(appContext);
+ });
+
+ // Separator
+ new ToolItem(toolBar, SWT.SEPARATOR);
+
+ // Exit
+ addToolItem(toolBar, images.exitIcon, "Exit", () -> rootShell.dispose());
+
+ toolBar.pack();
+ }
+
+ protected String tabTitle(String title) {
+ return title.length() > maxTabTitleLength ? title.substring(0, maxTabTitleLength) : title;
+ }
+
+ protected void addToolItem(ToolBar toolBar, Image icon, String name, Runnable action) {
+ ToolItem searchI = new ToolItem(toolBar, SWT.PUSH);
+ searchI.setImage(icon);
+ searchI.setToolTipText(name);
+ searchI.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ action.run();
+ }
+
+ });
+ }
+
+ protected AppContext createAppParent(Image icon) {
+ if (isStacking()) {
+ Composite appParent = new Composite(tabFolder, SWT.CLOSE);
+ appParent.setLayout(noSpaceGridLayout(new GridLayout()));
+ CTabItem item = new CTabItem(tabFolder, SWT.CLOSE);
+ item.setImage(icon);
+ item.setControl(appParent);
+ return new AppContext(item);
+ } else {
+ Shell shell = isFullscreen() ? new Shell(rootShell, SWT.SHELL_TRIM)
+ : new Shell(rootShell.getDisplay(), SWT.SHELL_TRIM);
+ shell.setImage(icon);
+ return new AppContext(shell);
+ }
+ }
+
+ protected void openApp(AppContext appContext) {
+ if (appContext.shell != null) {
+ Shell shell = (Shell) appContext.shell;
+ shell.open();
+ shell.setSize(new Point(800, 480));
+ }
+ if (appContext.tabItem != null) {
+ tabFolder.setFocus();
+ tabFolder.setSelection(appContext.tabItem);
+ }
+ }
+
+ protected Control createBackground(Composite parent) {
+ Composite backgroundArea = new Composite(parent, SWT.NONE);
+ backgroundArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ initBackground(backgroundArea);
+ return backgroundArea;
+ }
+
+ protected void initBackground(Composite backgroundArea) {
+ MiniHomePart homePart = new MiniHomePart() {
+
+ @Override
+ protected void fillAppsToolBar(ToolBar toolBar) {
+ createDock(toolBar);
+ }
+ };
+ homePart.createUiPart(backgroundArea, null);
+ }
+
+ public void run() {
+ while (!rootShell.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ }
+
+ public void dispose() {
+ if (!rootShell.isDisposed())
+ rootShell.dispose();
+ }
+
+ protected boolean isFullscreen() {
+ return fullscreen;
+ }
+
+ protected boolean isStacking() {
+ return stacking;
+ }
+
+ protected Image getIconForExt(String ext) {
+// Program program = Program.findProgram(ext);
+// if (program == null)
+ return display.getSystemImage(SWT.ICON_INFORMATION);
+
+// ImageData iconData = program.getImageData();
+// if (iconData == null) {
+// return display.getSystemImage(SWT.ICON_INFORMATION);
+// } else {
+// return new Image(display, iconData);
+// }
+
+ }
+
+ private static GridLayout noSpaceGridLayout(GridLayout layout) {
+ layout.horizontalSpacing = 0;
+ layout.verticalSpacing = 0;
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ return layout;
+ }
+
+ public static void main(String[] args) {
+ List<String> options = Arrays.asList(args);
+ if (options.contains("--help")) {
+ System.out.println("Usage: java " + MiniDesktopManager.class.getName().replace('.', '/') + " [OPTION]");
+ System.out.println("A minimalistic desktop manager based on Java and Eclipse SWT.");
+ System.out.println(" --fullscreen : take control of the whole screen (default is to run in a window)");
+ System.out.println(" --stacking : open apps as tabs (default is to create new windows)");
+ System.out.println(" --help : print this help and exit");
+ System.exit(1);
+ }
+ boolean fullscreen = options.contains("--fullscreen");
+ boolean stacking = options.contains("--stacking");
+
+ MiniDesktopManager desktopManager = new MiniDesktopManager(fullscreen, stacking);
+ desktopManager.init();
+ desktopManager.run();
+ desktopManager.dispose();
+ System.exit(0);
+ }
+
+ class AppContext {
+ private Shell shell;
+ private CTabItem tabItem;
+
+ public AppContext(Shell shell) {
+ this.shell = shell;
+ }
+
+ public AppContext(CTabItem tabItem) {
+ this.tabItem = tabItem;
+ }
+
+ Composite getAppParent() {
+ if (shell != null)
+ return shell;
+ if (tabItem != null)
+ return (Composite) tabItem.getControl();
+ throw new IllegalStateException();
+ }
+ }
+}
--- /dev/null
+package org.argeo.minidesktop;
+
+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.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 path;
+ private Text addressT;
+ private Table browser;
+
+ private boolean showHidden = false;
+
+ public MiniExplorer(Composite parent, String url) {
+ this(parent);
+ setUrl(url);
+ }
+
+ public MiniExplorer(Composite parent) {
+ parent.setLayout(noSpaceGridLayout(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);
+ addressT.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ setUrl(addressT.getText().trim());
+ }
+ });
+ browser = createTable(parent, this.path);
+
+ }
+
+ public void setPath(Path url) {
+ this.path = url;
+ if (addressT != null)
+ addressT.setText(url.toString());
+ if (browser != null) {
+ Composite parent = browser.getParent();
+ browser.dispose();
+ browser = createTable(parent, this.path);
+ parent.layout(true, true);
+ }
+ pathChanged(url);
+ }
+
+ protected void pathChanged(Path path) {
+
+ }
+
+ 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)) {
+ setPath(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(path, 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(path, 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) {
+ setPath(Paths.get(url));
+ }
+
+ private static GridLayout noSpaceGridLayout(GridLayout layout) {
+ layout.horizontalSpacing = 0;
+ layout.verticalSpacing = 0;
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ return layout;
+ }
+
+ public static void main(String[] args) {
+ Display display = Display.getCurrent() == null ? new Display() : Display.getCurrent();
+ Shell shell = new Shell(display, SWT.SHELL_TRIM);
+
+ String url = args.length > 0 ? args[0] : System.getProperty("user.home");
+ new MiniExplorer(shell, url) {
+
+ @Override
+ protected void pathChanged(Path path) {
+ shell.setText(path.toString());
+ }
+
+ };
+
+ shell.open();
+ shell.setSize(new Point(800, 480));
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ }
+
+}
--- /dev/null
+package org.argeo.minidesktop;
+
+import java.net.InetAddress;
+import java.net.InterfaceAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.util.Enumeration;
+
+import org.eclipse.swt.SWT;
+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.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.ProgressBar;
+import org.eclipse.swt.widgets.ToolBar;
+
+/** A start page displaying network information and resources. */
+public class MiniHomePart {
+
+ public Control createUiPart(Composite parent, Object context) {
+ parent.setLayout(new GridLayout(2, false));
+ Display display = parent.getDisplay();
+
+ // Apps
+ Group appsGroup = new Group(parent, SWT.NONE);
+ appsGroup.setText("Apps");
+ appsGroup.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false, 2, 1));
+ ToolBar appsToolBar = new ToolBar(appsGroup, SWT.HORIZONTAL | SWT.FLAT);
+ fillAppsToolBar(appsToolBar);
+
+ // Host
+ Group hostGroup = new Group(parent, SWT.NONE);
+ hostGroup.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false));
+ hostGroup.setText("Host");
+ hostGroup.setLayout(new GridLayout(2, false));
+ label(hostGroup, "Hostname: ");
+ try {
+ InetAddress defaultAddr = InetAddress.getLocalHost();
+ String hostname = defaultAddr.getHostName();
+ label(hostGroup, hostname);
+ label(hostGroup, "Address: ");
+ label(hostGroup, defaultAddr.getHostAddress());
+ } catch (UnknownHostException e) {
+ label(hostGroup, e.getMessage());
+ }
+
+ Enumeration<NetworkInterface> netInterfaces = null;
+ try {
+ netInterfaces = NetworkInterface.getNetworkInterfaces();
+ } catch (SocketException e) {
+ label(hostGroup, "Interfaces: ");
+ label(hostGroup, e.getMessage());
+ }
+ if (netInterfaces != null)
+ while (netInterfaces.hasMoreElements()) {
+ NetworkInterface netInterface = netInterfaces.nextElement();
+ byte[] hardwareAddress = null;
+ try {
+ hardwareAddress = netInterface.getHardwareAddress();
+ if (hardwareAddress != null) {
+ label(hostGroup, convertHardwareAddress(hardwareAddress));
+ label(hostGroup, netInterface.getName());
+ for (InterfaceAddress addr : netInterface.getInterfaceAddresses()) {
+ label(hostGroup, cleanHostAddress(addr.getAddress().getHostAddress()));
+ label(hostGroup, Short.toString(addr.getNetworkPrefixLength()));
+ }
+ }
+ } catch (SocketException e) {
+ label(hostGroup, e.getMessage());
+ }
+ }
+
+ // Resources
+ Group resGroup = new Group(parent, SWT.NONE);
+ resGroup.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ resGroup.setText("Resources");
+ resGroup.setLayout(new GridLayout(3, false));
+
+ Runtime runtime = Runtime.getRuntime();
+
+ String maxMemoryStr = Long.toString(runtime.maxMemory() / (1024 * 1024)) + " MB";
+ label(resGroup, "Max Java memory: ");
+ label(resGroup, maxMemoryStr);
+ label(resGroup, "Java version: " + Runtime.version().toString());
+
+ label(resGroup, "Usable Java memory: ");
+ Label totalMemory = label(resGroup, maxMemoryStr);
+ ProgressBar totalOnMax = new ProgressBar(resGroup, SWT.SMOOTH);
+ totalOnMax.setMaximum(100);
+ label(resGroup, "Used Java memory: ");
+ Label usedMemory = label(resGroup, maxMemoryStr);
+ ProgressBar usedOnTotal = new ProgressBar(resGroup, SWT.SMOOTH);
+ totalOnMax.setMaximum(100);
+ new Thread() {
+ @Override
+ public void run() {
+ while (!totalOnMax.isDisposed()) {
+ display.asyncExec(() -> {
+ if (totalOnMax.isDisposed())
+ return;
+ totalOnMax.setSelection(javaTotalOnMaxPerct(runtime));
+ usedOnTotal.setSelection(javaUsedOnTotalPerct(runtime));
+ totalMemory.setText(Long.toString(runtime.totalMemory() / (1024 * 1024)) + " MB");
+ usedMemory.setText(
+ Long.toString((runtime.totalMemory() - runtime.freeMemory()) / (1024 * 1024)) + " MB");
+ });
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ return;
+ }
+ }
+ }
+ }.start();
+ return parent;
+ }
+
+ protected void fillAppsToolBar(ToolBar toolBar) {
+
+ }
+
+ protected int javaUsedOnTotalPerct(Runtime runtime) {
+ return Math.toIntExact((runtime.totalMemory() - runtime.freeMemory()) * 100 / runtime.totalMemory());
+ }
+
+ protected int javaTotalOnMaxPerct(Runtime runtime) {
+ return Math.toIntExact((runtime.totalMemory()) * 100 / runtime.maxMemory());
+ }
+
+ protected Label label(Composite parent, String text) {
+ Label label = new Label(parent, SWT.WRAP);
+ label.setText(text);
+ return label;
+ }
+
+ protected String cleanHostAddress(String hostAddress) {
+ // remove % from Ipv6 addresses
+ int index = hostAddress.indexOf('%');
+ if (index > 0)
+ return hostAddress.substring(0, index);
+ else
+ return hostAddress;
+ }
+
+ protected String convertHardwareAddress(byte[] hardwareAddress) {
+ if (hardwareAddress == null)
+ return "";
+ // from https://stackoverflow.com/a/2797498/7878010
+ StringBuilder sb = new StringBuilder(18);
+ for (byte b : hardwareAddress) {
+ if (sb.length() > 0)
+ sb.append(':');
+ sb.append(String.format("%02x", b).toUpperCase());
+ }
+ return sb.toString();
+ }
+}
--- /dev/null
+package org.argeo.minidesktop;
+
+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.minidesktop;
+
+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.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;
+
+ // Sub process
+ private Process process;
+ private boolean running = false;
+ private OutputStream stdIn = null;
+
+ private Thread readOut;
+
+ public MiniTerminal(Composite parent, String url) {
+ this(parent);
+ setPath(url);
+ }
+
+ public MiniTerminal(Composite parent) {
+ 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 (e.stateMask == 0x40000 && e.keyCode == 0x63) {// Ctrl+C
+ if (process != null)
+ process.destroy();
+ } else if (e.stateMask == 0x40000 && e.keyCode == 0xdf) {// Ctrl+\
+ if (process != null) {
+ process.destroyForcibly();
+ }
+ } 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");
+ exitCalled();
+ return;
+ }
+
+ ProcessBuilder pb = new ProcessBuilder(args);
+ pb.redirectErrorStream(true);
+ pb.directory(currentDir.toFile());
+// Process process = Runtime.getRuntime().exec(input, null, currentPath.toFile());
+ process = pb.start();
+
+ stdIn = process.getOutputStream();
+ readOut = new Thread("MiniTerminal 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 = null;
+ process = null;
+ }
+ };
+ 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);
+ }
+
+ protected void exitCalled() {
+
+ }
+
+ 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);
+
+ String url = args.length > 0 ? args[0] : System.getProperty("user.home");
+ new MiniTerminal(shell, url) {
+
+ @Override
+ protected void exitCalled() {
+ shell.dispose();
+ System.exit(0);
+ }
+ };
+
+ shell.open();
+ shell.setSize(new Point(800, 480));
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ }
+
+}
--- /dev/null
+package org.argeo.minidesktop;
+
+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();
+ }
+ }
+
+}
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
+import org.argeo.minidesktop.MiniDesktopManager;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
-import org.eclipse.rap.rwt.application.AbstractEntryPoint;
import org.eclipse.rap.rwt.application.ApplicationConfiguration;
import org.eclipse.rap.rwt.application.ApplicationRunner;
+import org.eclipse.rap.rwt.application.EntryPoint;
+import org.eclipse.rap.rwt.application.Application.OperationMode;
import org.eclipse.rap.rwt.engine.RWTServlet;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
context.setContextPath("/");
server.setHandler(context);
- String entryPoint = "data";
+ String entryPoint = "app";
// rwt-resources requires a file system
try {
RwtRunner rwtRunner = new RwtRunner();
String entryPoint = "app";
- ApplicationConfiguration applicationConfiguration = (application) -> application.addEntryPoint("/" + entryPoint,
- () -> new AbstractEntryPoint() {
- private static final long serialVersionUID = 5678385921969090733L;
-
- @Override
- protected void createContents(Composite parent) {
- Label label = new Label(parent, 0);
- label.setText("Hello world!");
- }
- }, null);
+ ApplicationConfiguration applicationConfiguration = (application) -> {
+ application.setOperationMode(OperationMode.SWT_COMPATIBILITY);
+ application.addEntryPoint("/" + entryPoint, () -> new EntryPoint() {
+ @Override
+ public int createUI() {
+ MiniDesktopManager miniDesktopManager = new MiniDesktopManager(false, false);
+ miniDesktopManager.init();
+ miniDesktopManager.run();
+ return 0;
+ }
+ }, null);
+ };
rwtRunner.setApplicationConfiguration(applicationConfiguration);
rwtRunner.init();