Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: cederberg/rapidcontext
base: 9d47fead94
...
head fork: cederberg/rapidcontext
compare: 6ff05e8e55
Checking mergeability… Don't worry, you can still create the pull request.
  • 7 commits
  • 10 files changed
  • 0 commit comments
  • 1 contributor
View
3  src/java/org/rapidcontext/app/ApplicationContext.java
@@ -31,6 +31,7 @@
import org.rapidcontext.app.proc.PluginListProcedure;
import org.rapidcontext.app.proc.PluginLoadProcedure;
import org.rapidcontext.app.proc.PluginUnloadProcedure;
+import org.rapidcontext.app.proc.ProcedureDeleteProcedure;
import org.rapidcontext.app.proc.ProcedureListProcedure;
import org.rapidcontext.app.proc.ProcedureReadProcedure;
import org.rapidcontext.app.proc.ProcedureTypesProcedure;
@@ -213,6 +214,7 @@ private ApplicationContext(File baseDir, File localDir) {
* and the environment configuration.
*/
private void initAll() {
+ Library.builtInPlugin = PluginManager.SYSTEM_PLUGIN;
initLibrary();
initPlugins();
// TODO: Remove singleton environment reference
@@ -256,6 +258,7 @@ private void initLibrary() {
library.addBuiltIn(new ProcedureReadProcedure());
library.addBuiltIn(new ProcedureTypesProcedure());
library.addBuiltIn(new ProcedureWriteProcedure());
+ library.addBuiltIn(new ProcedureDeleteProcedure());
library.addBuiltIn(new ResetProcedure());
library.addBuiltIn(new SessionCurrentProcedure());
library.addBuiltIn(new SessionTerminateProcedure());
View
3  src/java/org/rapidcontext/app/plugin/PluginManager.java
@@ -27,6 +27,7 @@
import org.apache.commons.lang.StringUtils;
import org.rapidcontext.core.data.Binary;
import org.rapidcontext.core.data.Dict;
+import org.rapidcontext.core.proc.Library;
import org.rapidcontext.core.storage.FileStorage;
import org.rapidcontext.core.storage.MemoryStorage;
import org.rapidcontext.core.storage.Metadata;
@@ -467,6 +468,7 @@ public void load(String pluginId) throws PluginException {
loadJarFiles(pluginId);
// Create plug-in instance
+ Library.builtInPlugin = pluginId;
className = dict.getString(Plugin.KEY_CLASSNAME, null);
if (className == null || className.trim().length() <= 0) {
plugin = new Plugin(dict);
@@ -514,6 +516,7 @@ public void load(String pluginId) throws PluginException {
LOG.log(Level.WARNING, msg, e);
throw new PluginException(msg + ": " + e.getMessage());
}
+ Library.builtInPlugin = SYSTEM_PLUGIN;
}
/**
View
120 src/java/org/rapidcontext/app/proc/ProcedureDeleteProcedure.java
@@ -0,0 +1,120 @@
+/*
+ * RapidContext <http://www.rapidcontext.com/>
+ * Copyright (c) 2007-2012 Per Cederberg. All rights reserved.
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the BSD license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * See the RapidContext LICENSE.txt file for more details.
+ */
+
+package org.rapidcontext.app.proc;
+
+import org.rapidcontext.core.proc.Bindings;
+import org.rapidcontext.core.proc.CallContext;
+import org.rapidcontext.core.proc.Procedure;
+import org.rapidcontext.core.proc.ProcedureException;
+import org.rapidcontext.core.security.Restricted;
+import org.rapidcontext.core.security.SecurityContext;
+
+/**
+ * The built-in procedure delete procedure.
+ *
+ * @author Per Cederberg
+ * @version 1.0
+ */
+public class ProcedureDeleteProcedure implements Procedure, Restricted {
+
+ /**
+ * The procedure name constant.
+ */
+ public static final String NAME = "System.Procedure.Delete";
+
+ /**
+ * The default bindings.
+ */
+ private Bindings defaults = new Bindings();
+
+ /**
+ * Creates a new procedure delete procedure.
+ *
+ * @throws ProcedureException if the initialization failed
+ */
+ public ProcedureDeleteProcedure() throws ProcedureException {
+ defaults.set("name", Bindings.ARGUMENT, "", "The procedure name");
+ defaults.seal();
+ }
+
+ /**
+ * Checks if the currently authenticated user has access to this
+ * object.
+ *
+ * @return true if the current user has access, or
+ * false otherwise
+ */
+ public boolean hasAccess() {
+ return SecurityContext.hasAdmin();
+ }
+
+ /**
+ * Returns the procedure name.
+ *
+ * @return the procedure name
+ */
+ public String getName() {
+ return NAME;
+ }
+
+ /**
+ * Returns the procedure description.
+ *
+ * @return the procedure description
+ */
+ public String getDescription() {
+ return "Deletes a procedure from the local plug-in. If the " +
+ "procedure exists in another plug-in, that version will be " +
+ "kept intact.";
+ }
+
+ /**
+ * Returns the bindings for this procedure. If this procedure
+ * requires any special data, adapter connection or input
+ * argument binding, those bindings should be set (but possibly
+ * to null or blank values).
+ *
+ * @return the bindings for this procedure
+ */
+ public Bindings getBindings() {
+ return defaults;
+ }
+
+ /**
+ * Executes a call of this procedure in the specified context
+ * and with the specified call bindings. The semantics of what
+ * the procedure actually does, is up to each implementation.
+ * Note that the call bindings are normally inherited from the
+ * procedure bindings with arguments bound to their call values.
+ *
+ * @param cx the procedure call context
+ * @param bindings the call bindings to use
+ *
+ * @return the result of the call, or
+ * null if the call produced no result
+ *
+ * @throws ProcedureException if the call execution caused an
+ * error
+ */
+ public Object call(CallContext cx, Bindings bindings)
+ throws ProcedureException {
+ String name = ((String) bindings.getValue("name")).trim();
+ if (name.length() == 0) {
+ throw new ProcedureException("invalid procedure name");
+ }
+ cx.getLibrary().deleteProcedure(name);
+ return null;
+ }
+}
View
14 src/java/org/rapidcontext/app/proc/ProcedureReadProcedure.java
@@ -1,7 +1,6 @@
/*
* RapidContext <http://www.rapidcontext.com/>
- * Copyright (c) 2007-2010 Per Cederberg & Dynabyte AB.
- * All rights reserved.
+ * Copyright (c) 2007-2012 Per Cederberg. All rights reserved.
*
* This program is free software: you can redistribute it and/or
* modify it under the terms of the BSD license.
@@ -20,6 +19,7 @@
import org.rapidcontext.core.proc.AddOnProcedure;
import org.rapidcontext.core.proc.Bindings;
import org.rapidcontext.core.proc.CallContext;
+import org.rapidcontext.core.proc.Library;
import org.rapidcontext.core.proc.Procedure;
import org.rapidcontext.core.proc.ProcedureException;
import org.rapidcontext.core.security.Restricted;
@@ -121,7 +121,7 @@ public Object call(CallContext cx, Bindings bindings)
if (!SecurityContext.hasAccess(proc, "")) {
throw new ProcedureException("no procedure '" + name + "' found");
}
- return getProcedureData(proc);
+ return getProcedureData(cx.getLibrary(), proc);
}
/**
@@ -134,16 +134,16 @@ public Object call(CallContext cx, Bindings bindings)
* @throws ProcedureException if the bindings data access
* failed
*/
- static Dict getProcedureData(Procedure proc) throws ProcedureException {
- Dict res;
-
- res = new Dict();
+ static Dict getProcedureData(Library library, Procedure proc)
+ throws ProcedureException {
+ Dict res = new Dict();
res.set("name", proc.getName());
if (proc instanceof AddOnProcedure) {
res.set("type", ((AddOnProcedure) proc).getType());
} else {
res.set("type", "built-in");
}
+ res.set("plugin", library.getProcedurePluginId(proc.getName()));
res.set("description", proc.getDescription());
res.set("bindings", getBindingsData(proc.getBindings()));
return res;
View
5 src/java/org/rapidcontext/app/proc/ProcedureWriteProcedure.java
@@ -1,7 +1,6 @@
/*
* RapidContext <http://www.rapidcontext.com/>
- * Copyright (c) 2007-2010 Per Cederberg & Dynabyte AB.
- * All rights reserved.
+ * Copyright (c) 2007-2012 Per Cederberg. All rights reserved.
*
* This program is free software: you can redistribute it and/or
* modify it under the terms of the BSD license.
@@ -129,6 +128,6 @@ public Object call(CallContext cx, Bindings bindings)
data.set("description", bindings.getValue("description", ""));
data.set("binding", bindings.getValue("bindings"));
proc = cx.getLibrary().storeProcedure(data);
- return ProcedureReadProcedure.getProcedureData(proc);
+ return ProcedureReadProcedure.getProcedureData(cx.getLibrary(), proc);
}
}
View
63 src/java/org/rapidcontext/core/proc/Library.java
@@ -1,7 +1,6 @@
/*
* RapidContext <http://www.rapidcontext.com/>
- * Copyright (c) 2007-2010 Per Cederberg & Dynabyte AB.
- * All rights reserved.
+ * Copyright (c) 2007-2012 Per Cederberg. All rights reserved.
*
* This program is free software: you can redistribute it and/or
* modify it under the terms of the BSD license.
@@ -54,6 +53,11 @@
private static HashMap types = new HashMap();
/**
+ * The identifier of the currently loading plug-in.
+ */
+ public static String builtInPlugin = null;
+
+ /**
* The data storage to use for loading and listing procedures.
*/
private Storage storage = null;
@@ -69,6 +73,13 @@
private HashMap builtIns = new HashMap();
/**
+ * The map of built-in procedure plugin identifiers. The map is
+ * indexed by the procedure name and contains the plug-in
+ * identifier for the procedure.
+ */
+ private HashMap builtInPlugins = new HashMap();
+
+ /**
* The map of cached procedures. The map is indexed by the
* procedure name and is populated automatically from the data
* store upon procedure requests.
@@ -228,6 +239,24 @@ public Procedure getProcedure(String name) throws ProcedureException {
}
/**
+ * Returns the plug-in identifier of the specified procedure.
+ *
+ * @param name the procedure name
+ *
+ * @return the plug-in identifier, or
+ * null if not found
+ */
+ public String getProcedurePluginId(String name) {
+ Metadata meta = storage.lookup(PATH_PROC.child(name, false));
+ if (builtInPlugins.containsKey(name)) {
+ return (String) builtInPlugins.get(name);
+ } else if (meta != null) {
+ return ((Path) meta.storagePaths().get(0)).name();
+ }
+ return null;
+ }
+
+ /**
* Adds a new built-in procedure to the library.
*
* @param proc the procedure definition
@@ -242,6 +271,7 @@ public void addBuiltIn(Procedure proc) throws ProcedureException {
"' already exists");
}
builtIns.put(proc.getName(), proc);
+ builtInPlugins.put(proc.getName(), builtInPlugin);
}
/**
@@ -251,6 +281,7 @@ public void addBuiltIn(Procedure proc) throws ProcedureException {
*/
public void removeBuiltIn(String name) {
builtIns.remove(name);
+ builtInPlugins.remove(name);
}
/**
@@ -301,20 +332,38 @@ public Procedure loadProcedure(String name)
* created or written to the data store
*/
public Procedure storeProcedure(Dict data) throws ProcedureException {
- AddOnProcedure proc;
- String msg;
-
- proc = createProcedure(data);
+ AddOnProcedure proc = createProcedure(data);
try {
+ cache.remove(proc.getName());
storage.store(PATH_PROC.child(proc.getName(), false), proc.getData());
} catch (StorageException e) {
- msg = "failed to write procedure data: " + e.getMessage();
+ String msg = "failed to write procedure data: " + e.getMessage();
throw new ProcedureException(msg);
}
return proc;
}
/**
+ * Removes a procedure from the storage (if possible). Normally,
+ * only procedures in the local plug-in can be removed this way.
+ * Built-in procedures will remain unaffected by this.
+ *
+ * @param name the name of the procedure
+ *
+ * @throws ProcedureException if an error occurred while removing
+ * the procedure from storage
+ */
+ public void deleteProcedure(String name) throws ProcedureException {
+ try {
+ cache.remove(name);
+ storage.remove(PATH_PROC.child(name, false));
+ } catch (StorageException e) {
+ String msg = "failed to remove procedure: " + e.getMessage();
+ throw new ProcedureException(msg);
+ }
+ }
+
+ /**
* Creates a new add-on procedure from the specified data object.
*
* @param data the procedure data object
View
3  src/java/org/rapidcontext/core/storage/FileStorage.java
@@ -1,6 +1,6 @@
/*
* RapidContext <http://www.rapidcontext.com/>
- * Copyright (c) 2007-2011 Per Cederberg. All rights reserved.
+ * Copyright (c) 2007-2012 Per Cederberg. All rights reserved.
*
* This program is free software: you can redistribute it and/or
* modify it under the terms of the BSD license.
@@ -240,6 +240,7 @@ public void remove(Path path) throws StorageException {
FileUtil.deleteFiles(file);
} else {
FileUtil.delete(file);
+ FileUtil.deleteEmptyDirs(baseDir);
}
} catch (IOException e) {
msg = "failed to remove " + file + ": " + e.getMessage();
View
29 src/java/org/rapidcontext/util/FileUtil.java
@@ -1,6 +1,6 @@
/*
* RapidContext <http://www.rapidcontext.com/>
- * Copyright (c) 2007-2010 Per Cederberg. All rights reserved.
+ * Copyright (c) 2007-2012 Per Cederberg. All rights reserved.
*
* This program is free software: you can redistribute it and/or
* modify it under the terms of the BSD license.
@@ -157,6 +157,33 @@ public static void deleteFiles(File dir) throws IOException {
}
/**
+ * Deletes all empty directories in a directory, but leaves the
+ * directory itself unmodified. This method will remove any empty
+ * directories recursively, making it possible to remove a tree
+ * of empty directories.
+ *
+ * @param dir the directory to clean
+ *
+ * @throws IOException if some files couldn't be deleted
+ *
+ * @see #deleteFiles(File)
+ */
+ public static void deleteEmptyDirs(File dir) throws IOException {
+ File[] files = dir.listFiles();
+ if (files != null) {
+ for (int i = 0; i < files.length; i++) {
+ if (files[i].isDirectory()) {
+ deleteEmptyDirs(files[i]);
+ File[] subfiles = files[i].listFiles();
+ if (subfiles == null || subfiles.length == 0) {
+ delete(files[i]);
+ }
+ }
+ }
+ }
+ }
+
+ /**
* Creates a new temporary directory. If a temporary directory
* has been set, it will be used. Otherwise the default temporary
* directory will be used.
View
35 src/plugin/system/files/app/admin/app.js
@@ -18,6 +18,7 @@ AdminApp.prototype.start = function () {
appList: "System.App.List",
plugInList: "System.PlugIn.List",
procList: "System.Procedure.List",
+ procDelete: "System.Procedure.Delete",
userList: "System.User.List",
userChange: "System.User.Change"
});
@@ -33,7 +34,7 @@ AdminApp.prototype.start = function () {
MochiKit.Signal.connect(this.ui.appLaunchWindow, "onclick", this, "_launchAppWindow");
var func = function (td, data) {
if (data) {
- var styles = { marginLeft: "6px" };
+ var styles = { marginLeft: "3px" };
var attrs = { ref: "EXPAND", tooltip: "Open in new window", style: styles };
var img = RapidContext.Widget.Icon(attrs);
var link = MochiKit.DOM.A({ href: data, target: "_blank" }, data, img);
@@ -67,8 +68,13 @@ AdminApp.prototype.start = function () {
MochiKit.Signal.connectOnce(this.ui.procTab, "onenter", this.proc.procList, "call");
RapidContext.UI.connectProc(this.proc.procList, this.ui.procTreeLoading, this.ui.procTreeReload);
MochiKit.Signal.connect(this.proc.procList, "onsuccess", this, "_callbackProcedures");
+ RapidContext.UI.connectProc(this.proc.procDelete);
+ MochiKit.Signal.connect(this.proc.procDelete, "oncall", this.ui.overlay, "show");
+ MochiKit.Signal.connect(this.proc.procDelete, "onresponse", this.ui.overlay, "hide");
+ MochiKit.Signal.connect(this.proc.procDelete, "onsuccess", this.proc.procList, "recall");
MochiKit.Signal.connect(this.ui.procTree, "onselect", this, "_showProcedure");
MochiKit.Signal.connect(this.ui.procAdd, "onclick", this, "_addProcedure");
+ MochiKit.Signal.connect(this.ui.procRemove, "onclick", this, "_removeProcedure");
MochiKit.Signal.connect(this.ui.procEdit, "onclick", this, "_editProcedure");
MochiKit.Signal.connect(this.ui.procEditType, "onchange", this, "_updateProcEdit");
MochiKit.Signal.connect(this.ui.procEditAdd, "onclick", this, "_addProcBinding");
@@ -155,7 +161,10 @@ AdminApp.prototype._showApp = function () {
}
MochiKit.DOM.replaceChildNodes(this.ui.appIcon, img);
MochiKit.DOM.removeElementClass(this.ui.appLink, "hidden");
- this.ui.appLink.href = "/rapidcontext/storage/app/" + data.id;
+ var path = "/storage/plugin/" + data.plugin + "/app/" + data.id;
+ var url = "/rapidcontext/storage" + path;
+ MochiKit.DOM.setNodeAttribute(this.ui.appLink, "href", url);
+ this.ui.appLink.href = "/rapidcontext/storage" + path;
this.ui.appResourceTable.show();
this.ui.appResourceTable.setData(data.resources);
this.ui.appLaunch.show();
@@ -192,6 +201,10 @@ AdminApp.prototype._showPlugin = function () {
var data = this.ui.pluginTable.getSelectedData();
this.ui.pluginForm.reset();
this.ui.pluginForm.update(data);
+ MochiKit.DOM.removeElementClass(this.ui.pluginLink, "hidden");
+ var path = "/storage/plugin/" + data.id + "/";
+ var url = "/rapidcontext/storage" + path;
+ MochiKit.DOM.setNodeAttribute(this.ui.pluginLink, "href", url);
if (data.loaded) {
this.ui.pluginLoad.hide();
this.ui.pluginUnload.show();
@@ -339,6 +352,7 @@ AdminApp.prototype._callbackProcedures = function (res) {
node.data = res[i];
}
this.ui.procTree.removeAllMarked();
+ this._showProcedure();
}
/**
@@ -364,6 +378,7 @@ AdminApp.prototype.showProcedure = function (name) {
AdminApp.prototype._showProcedure = function () {
var node = this.ui.procTree.selectedChild();
this.ui.procForm.reset();
+ this.ui.procRemove.hide();
this.ui.procEdit.hide();
this.ui.procReload.hide();
this.ui.procLoading.hide();
@@ -392,6 +407,9 @@ AdminApp.prototype._callbackShowProcedure = function (res) {
RapidContext.UI.showError(res);
} else {
this._currentProc = res;
+ if (res.plugin == "local") {
+ this.ui.procRemove.show();
+ }
if (res.type != "built-in") {
this.ui.procEdit.show();
}
@@ -419,6 +437,7 @@ AdminApp.prototype._callbackShowProcedure = function (res) {
this.ui.procExec.disabled = false;
this.ui.procBatch.disabled = false;
this.ui.procExecResult.removeAll();
+ RapidContext.Util.resizeElements(this.ui.procExecResult);
}
}
@@ -502,6 +521,18 @@ AdminApp.prototype._addProcedure = function () {
}
/**
+ * Removes the currently shown procedure (if in the local plug-in).
+ */
+AdminApp.prototype._removeProcedure = function () {
+ var p = this._currentProc;
+ var msg = "Do you really want to delete the\nprocedure '" + p.name + "'?";
+ if (confirm(msg)) {
+ this.ui.overlay.setAttrs({ message: "Deleting..." });
+ this.proc.procDelete(p.name);
+ }
+}
+
+/**
* Opens the procedure editing dialog for an existing procedure.
*/
AdminApp.prototype._editProcedure = function () {
View
42 src/plugin/system/files/app/admin/ui.xml
@@ -35,7 +35,7 @@
<td>
<a id="appLink" href="#" target="_blank" class="hidden">
<Field name="*" format="/storage/plugin/{plugin}/app/{id}" />
- <Icon ref="EXPAND" tooltip="Open storage view" style="margin-left: 6px;" />
+ <Icon ref="EXPAND" tooltip="Open storage view" style="margin-left: 3px;" />
</a>
</td>
</tr>
@@ -63,7 +63,7 @@
</tr>
<tr>
<td colspan="2" style="padding-top: 10px;">
- <Button id="appLaunch" class="widgetHidden" style="margin-right: 6px"><Icon ref="OK" /> Launch</Button>
+ <Button id="appLaunch" class="widgetHidden" style="margin-right: 10px"><Icon ref="OK" /> Launch</Button>
<Button id="appLaunchWindow" class="widgetHidden"><Icon ref="EXPAND" /> Launch in new window</Button>
</td>
</tr>
@@ -85,7 +85,7 @@
<strong><Field name="name" /></strong>,
<Field name="approxSize" />,
<Field name="mimeType" />
- <Icon id="pluginFileDelete" ref="DELETE" style="margin-left: 6px;" />
+ <Icon id="pluginFileDelete" ref="DELETE" style="margin-left: 3px;" />
</Pane>
</td>
</tr>
@@ -126,6 +126,15 @@
</td>
</tr>
<tr>
+ <th class="label" style="padding-right: 4px;">Storage:</th>
+ <td>
+ <a id="pluginLink" href="#" target="_blank" class="hidden">
+ <Field name="*" format="/storage/plugin/{id}/" />
+ <Icon ref="EXPAND" tooltip="Open storage view" style="margin-left: 3px;" />
+ </a>
+ </td>
+ </tr>
+ <tr>
<th class="label" style="padding-right: 4px;">Name:</th>
<td>
<Field name="name" />
@@ -134,13 +143,13 @@
<tr>
<th class="label" style="padding-right: 4px;">Description:</th>
<td>
- <Field name="description" style="white-space: pre;" />
+ <Field name="description" style="white-space: pre-wrap;" />
</td>
</tr>
<tr>
<th class="label" style="padding-right: 4px;">Copyright:</th>
<td>
- <Field name="copyright" style="white-space: pre;" />
+ <Field name="copyright" style="white-space: pre-wrap;" />
</td>
</tr>
<tr>
@@ -151,8 +160,8 @@
</tr>
<tr>
<td colspan="2" style="padding-top: 4px;">
- <Button id="pluginLoad" style="margin-right: 6px"><Icon ref="OK" tooltip="Load" /> Load</Button>
- <Button id="pluginUnload" style="margin-right: 6px"><Icon ref="ERROR" tooltip="Unload" /> Unload</Button>
+ <Button id="pluginLoad" style="margin-right: 10px"><Icon ref="OK" tooltip="Load" /> Load</Button>
+ <Button id="pluginUnload" style="margin-right: 10px"><Icon ref="ERROR" tooltip="Unload" /> Unload</Button>
</td>
</tr>
</tbody>
@@ -168,6 +177,7 @@
<Form id="procForm" style="width: 100%; height: 100%;">
<h3>Procedure Details:
<Icon id="procAdd" ref="ADD" style="margin-right: 3px;" />
+ <Icon id="procRemove" ref="REMOVE" style="margin-right: 3px;" />
<Icon id="procEdit" ref="EDIT" style="margin-right: 3px;" />
<Icon id="procReload" ref="RELOAD" />
<Icon id="procLoading" ref="LOADING" />
@@ -187,6 +197,12 @@
</td>
</tr>
<tr>
+ <th class="label" style="padding-right: 4px;">Plug-In:</th>
+ <td>
+ <Field name="plugin" />
+ </td>
+ </tr>
+ <tr>
<th class="label" style="padding-right: 4px;">Description:</th>
<td>
<Field name="description" />
@@ -203,7 +219,7 @@
</tbody>
</table>
<div style="margin-top: 6px;">
- <Button id="procExec" disabled="true" style="margin-right: 6px;"><Icon ref="OK" /> Execute</Button>
+ <Button id="procExec" disabled="true" style="margin-right: 10px;"><Icon ref="OK" /> Execute</Button>
<Button id="procBatch" disabled="true"><Icon ref="DELAY" /> Execute Batch</Button>
</div>
<Tree id="procExecResult" w="100%" h="10%" style="margin-top: 6px;">
@@ -225,8 +241,8 @@
</div>
<TextArea name="value" w="100%-5" h="100%-65" />
<div style="position: absolute; bottom: 10px; right: 10px;">
- <Button id="procArgCancel" style="margin-left: 6px;"><Icon ref="CANCEL" /> Cancel</Button>
- <Button id="procArgSave" style="margin-left: 6px;"><Icon ref="OK" /> Save</Button>
+ <Button id="procArgCancel" style="margin-left: 10px;"><Icon ref="CANCEL" /> Cancel</Button>
+ <Button id="procArgSave" style="margin-left: 10px;"><Icon ref="OK" /> Save</Button>
</div>
</Form>
</Dialog>
@@ -287,8 +303,8 @@
</table>
</Form>
<div style="position: absolute; bottom: 10px; right: 10px;">
- <Button id="procEditCancel" style="margin-left: 6px;"><Icon ref="CANCEL" /> Cancel</Button>
- <Button id="procEditSave" style="margin-left: 6px;"><Icon ref="OK" /> Save</Button>
+ <Button id="procEditCancel" style="margin-left: 10px;"><Icon ref="CANCEL" /> Cancel</Button>
+ <Button id="procEditSave" style="margin-left: 10px;"><Icon ref="OK" /> Save</Button>
</div>
</Dialog>
</Pane>
@@ -382,7 +398,7 @@
</tr>
<tr>
<td colspan="2" style="padding-top: 4px;">
- <Button id="userSave" style="margin-right: 6px"><Icon ref="OK" /> Save</Button>
+ <Button id="userSave" style="margin-right: 10px"><Icon ref="OK" /> Save</Button>
</td>
</tr>
</tbody>

No commit comments for this range

Something went wrong with that request. Please try again.