Projekt

Obecné

Profil

Stáhnout (4.96 KB) Statistiky
| Větev: | Tag: | Revize:
1
import io.FileWorker;
2
import javafx.concurrent.Worker;
3
import javafx.scene.effect.BlendMode;
4
import javafx.scene.input.Clipboard;
5
import javafx.scene.input.ClipboardContent;
6
import javafx.scene.input.DataFormat;
7
import javafx.scene.input.KeyCode;
8
import javafx.scene.web.WebEngine;
9
import javafx.scene.web.WebView;
10
import netscape.javascript.JSObject;
11

    
12
/**
13
 * An instance of this class represents the editor element in the GUI.
14
 */
15
public class Editor {
16

    
17
	/**
18
	 * Default editor mode. The best are Zeek and Javascript (when using this
19
	 * deserializer).
20
	 */
21
	public static final String DEFAULT_MODE = "javascript";
22

    
23
	/**
24
	 * Default editor theme. The best is eclipse (when using this deserializer).
25
	 */
26
	public static final String DEFAULT_THEME = "eclipse";
27

    
28
	/**
29
	 * A read-only text area that displays the resulting JSON.
30
	 */
31
	private WebView view;
32

    
33
	/**
34
	 * WebView engine.
35
	 */
36
	private WebEngine engine;
37

    
38
	/**
39
	 * ACE editor instance in the web page.
40
	 */
41
	private JSObject editor;
42

    
43
	/**
44
	 * Session of the ACE editor. It is used for other settings that cannot be
45
	 * specified in the editor.
46
	 */
47
	private JSObject session;
48

    
49
	/**
50
	 * Resulting JSON.
51
	 */
52
	private String json;
53

    
54
	/**
55
	 * WebView and WebEngine initialization.
56
	 */
57
	public Editor() {
58
		view = new WebView();
59
		view.setPrefHeight(400);
60
		view.setBlendMode(BlendMode.DARKEN); // for "transparent" background.
61
		view.setContextMenuEnabled(false);
62
		view.setOnKeyReleased(event -> { // copy does not work by default => text to clipboard.
63
			if (event.isControlDown() && event.getCode() == KeyCode.C) {
64
				String copy = (String) editor.call("getSelectedText");
65
				if (copy != null) {
66
					ClipboardContent content = new ClipboardContent();
67
					content.put(DataFormat.PLAIN_TEXT, copy);
68
					Clipboard.getSystemClipboard().setContent(content);
69
				}
70
			}
71
		});
72

    
73
		engine = view.getEngine();
74
		engine.loadContent(getBasicHTML()); // load page.
75
		engine.getLoadWorker().stateProperty().addListener((observable, oldValue, newValue) -> {
76
			if (newValue == Worker.State.SUCCEEDED) {
77
				JSObject ace = (JSObject) engine.executeScript("ace");
78
				editor = (JSObject) ace.call("edit", "editor");
79
				session = (JSObject) editor.call("getSession");
80

    
81
				editor.call("setScrollSpeed", ".1"); // slower scrolling.
82
				session.call("setUseWorker", false); // disable content checking.
83
				editor.call("setReadOnly", true);
84

    
85
				setMode(DEFAULT_MODE);
86
				setTheme(DEFAULT_THEME);
87
			}
88
		});
89
	}
90

    
91
	/**
92
	 * Sets a new mode in the editor.
93
	 * 
94
	 * @param mode new editor mode.
95
	 */
96
	public void setMode(String mode) {
97
		session.call("setMode", "ace/mode/" + mode);
98
	}
99

    
100
	/**
101
	 * Sets a new theme in the editor.
102
	 * 
103
	 * @param theme new editor theme.
104
	 */
105
	public void setTheme(String theme) {
106
		editor.call("setTheme", "ace/theme/" + theme);
107
	}
108

    
109
	/**
110
	 * @return the using instance of the WebView.
111
	 */
112
	public WebView getView() {
113
		return view;
114
	}
115

    
116
	/**
117
	 * @return the text displayed in the editor.
118
	 */
119
	public String getJson() {
120
		return json;
121
	}
122

    
123
	/**
124
	 * Replaces the editor content.
125
	 * 
126
	 * @param json new content.
127
	 */
128
	public void setContent(String json) {
129
		this.json = json;
130
		editor.call("setValue", "");
131
		editor.call("insert", json);
132
	}
133

    
134
	/**
135
	 * @return basic HTML page with ACE for WebView engine.
136
	 */
137
	private String getBasicHTML() {
138
		return "<!DOCTYPE html>"
139
				+ "<html>"
140
				+ "  <head>"
141
				+ "    <style type=\"text/css\">"
142
				+ "      #editor {"
143
				+ "        margin: 0;"
144
				+ "        position: absolute;"
145
				+ "        top: 0;"
146
				+ "        bottom: 0;"
147
				+ "        left: 0;"
148
				+ "        right: 0;"
149
				+ "      }"
150
				+ "    </style>"
151
				+ "  </head>"
152
				+ "  <body>"
153
				+ "    <div id=\"editor\"></div>"
154
				+ "    <script src=\"" + FileWorker.getResource("/ace/ace.js") + "\"></script>"
155
				+ "  </body>"
156
				+ "</html>";
157
	}
158

    
159
	/**
160
	 * Converts classic text with HTML tags to the correct HTML (critical characters
161
	 * replaced by HTML entities). For insertion to JS. IT IS NO LONGER USED - only
162
	 * for "NICE TO HAVE".
163
	 * 
164
	 * @param str text that is half plain text ('\n', '\t', etc.) and half html.
165
	 * 
166
	 * @return correct HTML with HTML entities.
167
	 */
168
	@SuppressWarnings(value = { "unused" })
169
	private String escape(String str) {
170
		StringBuilder builder = new StringBuilder();
171
		char strArray[] = str.toCharArray();
172
		for (int i = 0; i < strArray.length; i++) {
173
			char c = strArray[i];
174
			switch (c) {
175
			case '\'':
176
				builder.append("&#39;");
177
				break;
178
			case '<':
179
				builder.append("&lt;");
180
				break;
181
			case '>':
182
				builder.append("&gt;");
183
				break;
184
			case '&':
185
				builder.append("&amp;");
186
				break;
187
			case '"':
188
				builder.append("&quot;");
189
				break;
190
			case '\n':
191
				builder.append("<br/>");
192
				break;
193
			case '\t':
194
				builder.append("&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;");
195
				break;
196
			case ' ':
197
				builder.append("&nbsp;");
198
				break;
199
			case (char) 13:
200
				break;
201
			default:
202
				if (c < 128) {
203
					builder.append(c);
204
				} else {
205
					builder.append("&#").append((int) c).append(";");
206
				}
207
			}
208
		}
209
		return builder.toString();
210
	}
211

    
212
}
(3-3/6)