459 lines
15 KiB
JavaScript
459 lines
15 KiB
JavaScript
/*
|
|
* Copyright 2016-2024 ANSYS, Inc.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
|
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
|
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
|
|
* permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of
|
|
* the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
|
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
|
|
* OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
*
|
|
* v2024-03-27 - fixed glitch in default y value in drop to diagram function
|
|
* v2022-12-01 - added functions to drop elements to diagrams
|
|
* v2022-11-18 - added functions to show in internal/external browser
|
|
* v2020-11-22 - extended selectElement by check / uncheck all tool for multi selection
|
|
* v2020-05-20 - extended selectElement by description and pre-selection
|
|
* v2019-03-20 - fixed glitch in openDirectory, improved alertWithAbortOption
|
|
* v2018-08-28 - alertWithToggle and alertWithAbortOption added
|
|
* v2018-07-17 - copyToClipboard and copyFromClipboard added
|
|
* v2018-04-12 - openDirectory added
|
|
* v2016-11-14 - initial version
|
|
*/
|
|
if (!bind) {
|
|
throw "This script requires extended API";
|
|
}
|
|
|
|
// bind UI utility (NOT OFFICIAL API YET)
|
|
var UI = bind("de.ikv.medini.util.eclipse", "de.ikv.medini.util.eclipse.MediniUIUtil", false);
|
|
var AnalyzeUI = bind("de.ikv.analyze.ui.common", "de.ikv.analyze.ui.common.util.AnalyzeUIUtil", false);
|
|
var Dialogs = bind("de.ikv.medini.util.eclipse", "de.ikv.medini.util.eclipse.dialogs.MediniDialogUtil", false);
|
|
var SelectElementTreeDialog = bind("de.ikv.medini.cockpit.ui", "de.ikv.medini.cockpit.ui.dialogs.SelectModelElementTreeDialog", false);
|
|
var SWT = bind("org.eclipse.swt", "org.eclipse.swt.SWT", false);
|
|
var SWTPoint = bind("org.eclipse.swt", "org.eclipse.swt.graphics.Point", false);
|
|
var SWTButton = bind("org.eclipse.swt", "org.eclipse.swt.widgets.Button", false);
|
|
var DirectoryDialog = bind("org.eclipse.swt", "org.eclipse.swt.widgets.DirectoryDialog", false);
|
|
var InputDialog = bind("org.eclipse.jface", "org.eclipse.jface.dialogs.InputDialog", false);
|
|
var StructuredSelection = bind("org.eclipse.jface", "org.eclipse.jface.viewers.StructuredSelection", false);
|
|
var ArrayTreeContentProvider = bind("de.ikv.medini.util.eclipse", "de.ikv.medini.util.eclipse.jface.viewers.ArrayTreeContentProvider", false);
|
|
var VanillaAction = bind("de.ikv.medini.util.eclipse", "de.ikv.medini.util.eclipse.jface.action.VanillaAction", false);
|
|
var WidgetUtil = bind("de.ikv.medini.util.swt", "de.ikv.medini.util.swt.widgets.WidgetUtil", false);
|
|
var ScopedPreferenceStore = bind("org.eclipse.ui.workbench", "org.eclipse.ui.preferences.ScopedPreferenceStore", false);
|
|
var InstanceScope = bind("org.eclipse.equinox.preferences", "org.eclipse.core.runtime.preferences.InstanceScope", false);
|
|
var BasicEList = bind("org.eclipse.emf.common", "org.eclipse.emf.common.util.BasicEList", false);
|
|
|
|
function openFile(extensions) {
|
|
var fileName = undefined;
|
|
UI.execute(function select(monitor) {
|
|
var shell = UI.getWorkbenchWindowShell();
|
|
fileName = Dialogs.openFileDialog(shell, SWT.OPEN, extensions);
|
|
});
|
|
|
|
if (fileName) {
|
|
return new java.io.File(fileName);
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
/**
|
|
* Open the directory dialog.
|
|
*
|
|
* @param message
|
|
* {String} the dialog's message, which is a description of the
|
|
* purpose for which it was opened
|
|
* @param initialPath
|
|
* {String} the path that the dialog will select initially
|
|
* @returns {java.io.File} the selected path or undefined
|
|
*/
|
|
function openDirectory(message, initialPath) {
|
|
var dirName = undefined;
|
|
UI.execute(function select(monitor) {
|
|
var shell = UI.getWorkbenchWindowShell();
|
|
var dialog = new DirectoryDialog(shell);
|
|
if (message) {
|
|
dialog.setMessage(message);
|
|
}
|
|
if (initialPath) {
|
|
dialog.setFilterPath(initialPath);
|
|
}
|
|
dirName = Dialogs.openDirectoryDialog(dialog);
|
|
});
|
|
|
|
if (dirName) {
|
|
return new java.io.File(dirName.trim());
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
/**
|
|
* Opens the editor for the given semantic element.
|
|
*
|
|
* @param {EObject}
|
|
* semanticElement
|
|
* @param {Number}
|
|
* delay the delay in milliseconds before the editor opens (optional)
|
|
*/
|
|
function openEditor(semanticElement, delay) {
|
|
var openFunc = function open(monitor) {
|
|
AnalyzeUI.INSTANCE.openEditorForSemanticElement(semanticElement, true,
|
|
false, false, true);
|
|
};
|
|
|
|
if (delay != undefined) {
|
|
UI.executeDelayed(delay, openFunc);
|
|
} else {
|
|
UI.executeNonBlocking(openFunc);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* It is rather difficult to decide whether a given object
|
|
* is an array with Rhino.
|
|
*/
|
|
function isArray(object) {
|
|
if (object == undefined) {
|
|
return false;
|
|
}
|
|
if (typeof object != "object") {
|
|
return false;
|
|
}
|
|
if (object.length == undefined) {
|
|
return false;
|
|
}
|
|
if (typeof object.length != "number") {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Opens an element selection dialog, either single selection or multi-selection.
|
|
* An optional root element can be passed.
|
|
*
|
|
* @param {String} title
|
|
* @param {EClass} type
|
|
* @param {Boolean} multiple
|
|
* @param {Object} root
|
|
* @param {String} description (optional)
|
|
* @param {Array} preSelection (optional)
|
|
* @returns a single object or an array of objects or undefined
|
|
*/
|
|
function selectElement(title, type, multiple, root, description, preSelection) {
|
|
var selected = undefined;
|
|
UI.execute(function select(monitor) {
|
|
var shell = UI.getWorkbenchWindowShell();
|
|
var dialog = new SelectElementTreeDialog(shell, title, type, multiple);
|
|
AnalyzeUI.INSTANCE.preparate(dialog);
|
|
dialog.setStyle(SelectElementTreeDialog.CHECKBOX);
|
|
if (multiple) {
|
|
dialog.setStyle(SelectElementTreeDialog.TOOLBAR_CHECK_ALL);
|
|
dialog.setStyle(SelectElementTreeDialog.TOOLBAR_UNCHECK_ALL);
|
|
dialog.setStyle(SelectElementTreeDialog.PROPAGATE_CHECKED_STATE);
|
|
}
|
|
// new since 05-2020
|
|
if (description) {
|
|
dialog.setDescription(description);
|
|
}
|
|
// new since 05-2020
|
|
if (preSelection) {
|
|
// the dialog only access EObject arrays or collections
|
|
var list = new BasicEList();
|
|
preSelection.forEach(function (p) { list.add(p); });
|
|
dialog.setInitiallySelectedObjects(list);
|
|
}
|
|
// use global variable "project" as input if none was defined
|
|
if (root == undefined) {
|
|
root = finder.getProject();
|
|
} else if (isArray(root)) {
|
|
dialog.setTreeContentProvider(new ArrayTreeContentProvider());
|
|
dialog.clearStyle(1 << 12); // <- filter does not work in this case
|
|
}
|
|
dialog.setTreeInput(root);
|
|
var result = Dialogs.openDialog(dialog);
|
|
|
|
if (result == 0) { // Window.OK = 0
|
|
selected = dialog.getSelectedModelElements();
|
|
if (!multiple) {
|
|
selected = selected[0];
|
|
// FIXME This should be normally done by the dialog already, why isn't?
|
|
if (selected.prototype == Metamodel.projectmodel.PJProxyModel) {
|
|
selected = selected.originalModel;
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
return selected;
|
|
}
|
|
|
|
/*
|
|
* Input filter which accepts all.
|
|
*/
|
|
function acceptAll(input) {
|
|
return null;
|
|
}
|
|
|
|
function inputText(title, message, initialValue, validator) {
|
|
var selected = undefined;
|
|
if (validator == undefined) {
|
|
validator = acceptAll;
|
|
}
|
|
UI.execute(function select(monitor) {
|
|
var shell = UI.getWorkbenchWindowShell();
|
|
var dialog = new InputDialog(shell, title, message, initialValue,
|
|
validator);
|
|
var result = dialog.open();
|
|
if (result == 0) { // Window.OK = 0
|
|
selected = dialog.getValue();
|
|
}
|
|
});
|
|
|
|
return selected;
|
|
}
|
|
|
|
/**
|
|
* Opens an option dialog with a message and buttons for each option.
|
|
*
|
|
* @param {String} title
|
|
* @param {String} message
|
|
* @param [{String}] options an array of strings aka options
|
|
* @returns the index of the selected option or -1 (cancel)
|
|
*/
|
|
function selectOption(title, message, buttons) {
|
|
// API says: "can be called from any thread" but not true
|
|
// TODO assert that buttons is an array
|
|
var selected = -1;
|
|
UI.execute(function select(monitor) {
|
|
selected = UI.displayQuestion(title, message, buttons);
|
|
});
|
|
|
|
return selected;
|
|
}
|
|
|
|
function runHandler(handler, object, label) {
|
|
// use a vanilla action to satisfy the handler
|
|
var action = new VanillaAction(label);
|
|
// we have to run in UI thread
|
|
UI.execute(function run(monitor) {
|
|
// simulate a selection
|
|
handler.selectionChanged(action, new StructuredSelection(object));
|
|
handler.run(action);
|
|
});
|
|
}
|
|
|
|
function setHandlerSelection(handler, object, label) {
|
|
// use a vanilla action to satisfy the handler
|
|
var action = new VanillaAction(label ? label : "set selection");
|
|
handler.selectionChanged(action, new StructuredSelection(object));
|
|
}
|
|
|
|
/**
|
|
* Helper to fill the text into the system Clipboard.
|
|
*
|
|
* @param {String}
|
|
* text to copy to the Clipboard
|
|
*
|
|
*/
|
|
function copyToClipboard(text) {
|
|
var toolkit = java.awt.Toolkit.getDefaultToolkit();
|
|
var clipboard = toolkit.getSystemClipboard();
|
|
var transfer = new java.awt.datatransfer.StringSelection(text);
|
|
clipboard.setContents(transfer, null);
|
|
}
|
|
|
|
/**
|
|
* Helper to extract text from the system Clipboard.
|
|
*
|
|
* @return {String} text if the Clipboard contains text, otherwise the result is
|
|
* undefined
|
|
*/
|
|
function copyFromClipboard() {
|
|
var toolkit = java.awt.Toolkit.getDefaultToolkit();
|
|
var clipboard = toolkit.getSystemClipboard();
|
|
return clipboard.getData(java.awt.datatransfer.DataFlavor.stringFlavor);
|
|
}
|
|
|
|
/**
|
|
* Opens a message dialog similar to "alert" but with a typical "Do not show
|
|
* again" toggle.
|
|
*
|
|
* @param {String}
|
|
* message
|
|
* @param {Object}
|
|
* an optional object (map) that holds information on kind, title
|
|
* @returns 0 (OK) or 1 (CANCEL)
|
|
*/
|
|
function alertWithToggle(message, options) {
|
|
if (options == undefined) {
|
|
options = {};
|
|
}
|
|
var kind = options["kind"];
|
|
var title = options["title"];
|
|
var toggleMessage = options["toggleMessage"];
|
|
var bundleName = options["bundleName"];
|
|
var key = options["key"];
|
|
var style = options["style"];
|
|
|
|
if (kind == undefined) {
|
|
kind = 2; // INFO
|
|
}
|
|
if (title == undefined) {
|
|
title = "Alert";
|
|
}
|
|
if (toggleMessage == undefined) {
|
|
toggleMessage = "Do not show this message again";
|
|
}
|
|
if (bundleName == undefined) {
|
|
bundleName = "de.ikv.medini.util.eclipse";
|
|
}
|
|
if (key == undefined) {
|
|
key = message;
|
|
}
|
|
if (style == undefined) {
|
|
style = SWT.NONE;
|
|
}
|
|
|
|
var store = new ScopedPreferenceStore(InstanceScope.INSTANCE, bundleName);
|
|
var selected = undefined;
|
|
UI.execute(function select(monitor) {
|
|
var shell = UI.getWorkbenchWindowShell();
|
|
selected = Dialogs.openDialogWithDontShowAgainToggle(kind, shell, title, message, toggleMessage, store, key, style);
|
|
store.save();
|
|
});
|
|
|
|
return selected;
|
|
}
|
|
|
|
/**
|
|
* Opens a message dialog similar to "alert" but allows the user to choose
|
|
* whether or not to abort the program completely. Returns <code>true</code>
|
|
* if "Abort" and <code>false</code> if "Continue" has been selected.
|
|
* <strong>Note: It is up to the caller to evaluate this and abort the program,
|
|
* if the user has opted so.</strong>
|
|
*
|
|
* @param {String}
|
|
* title the dialog title
|
|
* @param {String}
|
|
* message the message
|
|
* @returns <code>false</code> if the user has selected to continue,
|
|
* <code>true</code> if the user has selected to abort
|
|
*/
|
|
function alertWithAbortOption(title, message) {
|
|
var selected = selectOption(title, message , [ "Continue", "Abort" ]);
|
|
if (selected == 1) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Opens a given object in the external browser. The following types are
|
|
* supported: java.io.File and string.
|
|
*
|
|
* @param object URL string or File object
|
|
*/
|
|
function openInExternalBrowser(object) {
|
|
if (object instanceof java.io.File) {
|
|
object = object.toURL();
|
|
}
|
|
var url = '' + object; // make a string out of it
|
|
AnalyzeUI.INSTANCE.openInExternalBrowser(url);
|
|
}
|
|
|
|
/**
|
|
* Opens a given object in the internal browser. The following types are
|
|
* supported: java.io.File and string.
|
|
*
|
|
* @param object URL string or File object
|
|
* @param id optional unique id of this browser window, default is 'OpenInInternalBrowser'
|
|
* @param name optional window name
|
|
* @param name optional window tooltip
|
|
*/
|
|
function openInInternalBrowser(object, id, name, tooltip) {
|
|
if (object instanceof java.io.File) {
|
|
object = object.toURL();
|
|
}
|
|
var url = '' + object; // make a string out of it
|
|
var AS_VIEW = 64; // 1 << 6
|
|
var STATUS = 8; // 1 << 3
|
|
var NAVIGATION_BAR = 4; // 1 << 2
|
|
var style = AS_VIEW; // + STATUS + NAVIGATION_BAR;
|
|
|
|
// MUST be executed in UI thread
|
|
UI.execute(function select(monitor) {
|
|
var /* IWorkbenchBrowserSupport */ support = UI.getWorkbench().getBrowserSupport();
|
|
console.log("Internal available: {0}", support.internalWebBrowserAvailable);
|
|
var /* IWebBrowser */ browser =
|
|
support.createBrowser(style, id != null ? id : "OpenInInternalBrowser",
|
|
name != null ? name : "Internal Browser", tooltip);
|
|
browser.openURL(new java.net.URL(url));
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Drops objects on a given diagram using an offset edit part
|
|
*
|
|
* @param objectsBeingDropped
|
|
* an arrays of dropped objects
|
|
* @param extendedData
|
|
* an optional map providing extended request data (may be <code>null</code>)
|
|
* @param diagram
|
|
* the diagram onto which the objects have been dropped
|
|
* @param x
|
|
* the location where the objects has been dropped
|
|
* @param y
|
|
* the location where the objects has been dropped
|
|
* @param operation
|
|
* the drop operation (2 = {@link DND#DROP_MOVE}, {1 = @link DND#DROP_COPY}, or {4 = @link DND#DROP_LINK}}
|
|
*/
|
|
function dropObjectsToDiagram(objectsBeingDropped, extendedData, /* PJDiagram */ diagram, x, y, /* int */ operation) {
|
|
|
|
var OffscreenEditPartFactory = bind("org.eclipse.gmf.runtime.diagram.ui", "org.eclipse.gmf.runtime.diagram.ui.OffscreenEditPartFactory", false);
|
|
var DropObjectsRequest = bind("org.eclipse.gmf.runtime.diagram.ui", "org.eclipse.gmf.runtime.diagram.ui.requests.DropObjectsRequest", false);
|
|
var Point = bind("org.eclipse.draw2d", "org.eclipse.draw2d.geometry.Point", false);
|
|
|
|
UI.execute(function select(monitor) {
|
|
var shell = UI.getWorkbenchWindowShell();
|
|
var /* EditPartViewer */ viewer =
|
|
OffscreenEditPartFactory.getInstance().createDiagramEditPart(diagram.diagram, shell).getViewer();
|
|
|
|
if (operation == undefined) {
|
|
operation = 2;
|
|
}
|
|
if (x == undefined) {
|
|
x = 50;
|
|
}
|
|
if (y == undefined) {
|
|
y = 50;
|
|
}
|
|
var request = new DropObjectsRequest();
|
|
|
|
request.setObjects(objectsBeingDropped);
|
|
request.setRequiredDetail(operation);
|
|
request.setAllowedDetail(operation);
|
|
if (extendedData != null) {
|
|
request.getExtendedData().putAll(extendedData);
|
|
}
|
|
/* Point */ var location = new Point(x, y);
|
|
request.setLocation(location);
|
|
|
|
/* EditPart */ targetEP = viewer.contents.getTargetEditPart(request);
|
|
if (targetEP != null) {
|
|
var command = targetEP.getCommand(request);
|
|
if ((command != null) && command.canExecute()) {
|
|
var stack = viewer.getDiagramEditDomain().getDiagramCommandStack();
|
|
stack.execute(command);
|
|
// flush pending UI events and asynchronous requests
|
|
UI.flushEventQueue();
|
|
}
|
|
}
|
|
});
|
|
}
|