/
CustomWorkspaceAccessPluginExtension.java
259 lines (236 loc) · 10.3 KB
/
CustomWorkspaceAccessPluginExtension.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
package com.oxygenxml.sdksamples.workspace;
import java.awt.event.ActionEvent;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JComponent;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.text.BadLocationException;
import ro.sync.ecss.extensions.api.AuthorAccess;
import ro.sync.ecss.extensions.api.AuthorDocumentController;
import ro.sync.ecss.extensions.api.node.AuthorDocumentFragment;
import ro.sync.exml.editor.EditorPageConstants;
import ro.sync.exml.plugin.workspace.WorkspaceAccessPluginExtension;
import ro.sync.exml.workspace.api.editor.WSEditor;
import ro.sync.exml.workspace.api.editor.page.author.WSAuthorEditorPage;
import ro.sync.exml.workspace.api.editor.page.text.WSTextEditorPage;
import ro.sync.exml.workspace.api.listeners.WSEditorChangeListener;
import ro.sync.exml.workspace.api.standalone.MenuBarCustomizer;
import ro.sync.exml.workspace.api.standalone.StandalonePluginWorkspace;
import ro.sync.exml.workspace.api.standalone.ToolbarComponentsCustomizer;
import ro.sync.exml.workspace.api.standalone.ToolbarInfo;
import ro.sync.exml.workspace.api.standalone.ViewComponentCustomizer;
import ro.sync.exml.workspace.api.standalone.ViewInfo;
import ro.sync.exml.workspace.api.standalone.actions.MenusAndToolbarsContributorCustomizer;
import ro.sync.exml.workspace.api.standalone.ui.ToolbarButton;
/**
* Plugin extension - workspace access extension.
*/
public class CustomWorkspaceAccessPluginExtension implements WorkspaceAccessPluginExtension {
/**
* The custom messages area. A sample component added to your custom view.
*/
private JTextArea customMessagesArea;
/**
* @see ro.sync.exml.plugin.workspace.WorkspaceAccessPluginExtension#applicationStarted(ro.sync.exml.workspace.api.standalone.StandalonePluginWorkspace)
*/
public void applicationStarted(final StandalonePluginWorkspace pluginWorkspaceAccess) {
//You can set or read global options.
//The "ro.sync.exml.options.APIAccessibleOptionTags" contains all accessible keys.
// pluginWorkspaceAccess.setGlobalObjectProperty("can.edit.read.only.files", Boolean.FALSE);
// Check In action
//You can access the content inside each opened WSEditor depending on the current editing page (Text/Grid or Author).
// A sample action which will be mounted on the main menu, toolbar and contextual menu.
final Action selectionSourceAction = createShowSelectionAction(pluginWorkspaceAccess);
//Mount the action on the contextual menus for the Text and Author modes.
pluginWorkspaceAccess.addMenusAndToolbarsContributorCustomizer(new MenusAndToolbarsContributorCustomizer() {
/**
* Customize the author popup menu.
*/
@Override
public void customizeAuthorPopUpMenu(JPopupMenu popup,
AuthorAccess authorAccess) {
// Add our custom action
popup.add(selectionSourceAction);
}
@Override
public void customizeTextPopUpMenu(JPopupMenu popup,
WSTextEditorPage textPage) {
// Add our custom action
popup.add(selectionSourceAction);
}
});
// Create your own main menu and add it to Oxygen or remove one of Oxygen's menus...
pluginWorkspaceAccess.addMenuBarCustomizer(new MenuBarCustomizer() {
/**
* @see ro.sync.exml.workspace.api.standalone.MenuBarCustomizer#customizeMainMenu(javax.swing.JMenuBar)
*/
public void customizeMainMenu(JMenuBar mainMenuBar) {
JMenu myMenu = new JMenu("My menu");
myMenu.add(selectionSourceAction);
// Add your menu before the Help menu
mainMenuBar.add(myMenu, mainMenuBar.getMenuCount() - 1);
}
});
pluginWorkspaceAccess.addEditorChangeListener(
new WSEditorChangeListener() {
@Override
public boolean editorAboutToBeOpenedVeto(URL editorLocation) {
//You can reject here the opening of an URL if you want
return true;
}
@Override
public void editorOpened(URL editorLocation) {
checkActionsStatus(editorLocation);
}
// Check actions status
private void checkActionsStatus(URL editorLocation) {
WSEditor editorAccess = pluginWorkspaceAccess.getCurrentEditorAccess(StandalonePluginWorkspace.MAIN_EDITING_AREA);
if (editorAccess != null) {
selectionSourceAction.setEnabled(
EditorPageConstants.PAGE_AUTHOR.equals(editorAccess.getCurrentPageID())
|| EditorPageConstants.PAGE_TEXT.equals(editorAccess.getCurrentPageID()));
}
}
@Override
public void editorClosed(URL editorLocation) {
//An edited XML document has been closed.
}
/**
* @see ro.sync.exml.workspace.api.listeners.WSEditorChangeListener#editorAboutToBeClosed(java.net.URL)
*/
@Override
public boolean editorAboutToBeClosed(URL editorLocation) {
//You can veto the closing of an XML document.
//Allow close
return true;
}
/**
* The editor was relocated (Save as was called).
*
* @see ro.sync.exml.workspace.api.listeners.WSEditorChangeListener#editorRelocated(java.net.URL, java.net.URL)
*/
@Override
public void editorRelocated(URL previousEditorLocation, URL newEditorLocation) {
//
}
@Override
public void editorPageChanged(URL editorLocation) {
checkActionsStatus(editorLocation);
}
@Override
public void editorSelected(URL editorLocation) {
checkActionsStatus(editorLocation);
}
@Override
public void editorActivated(URL editorLocation) {
checkActionsStatus(editorLocation);
}
},
StandalonePluginWorkspace.MAIN_EDITING_AREA);
//You can use this callback to populate your custom toolbar (defined in the plugin.xml) or to modify an existing Oxygen toolbar
// (add components to it or remove them)
pluginWorkspaceAccess.addToolbarComponentsCustomizer(new ToolbarComponentsCustomizer() {
/**
* @see ro.sync.exml.workspace.api.standalone.ToolbarComponentsCustomizer#customizeToolbar(ro.sync.exml.workspace.api.standalone.ToolbarInfo)
*/
public void customizeToolbar(ToolbarInfo toolbarInfo) {
//The toolbar ID is defined in the "plugin.xml"
if("SampleWorkspaceAccessToolbarID".equals(toolbarInfo.getToolbarID())) {
List<JComponent> comps = new ArrayList<JComponent>();
JComponent[] initialComponents = toolbarInfo.getComponents();
boolean hasInitialComponents = initialComponents != null && initialComponents.length > 0;
if (hasInitialComponents) {
// Add initial toolbar components
for (JComponent toolbarItem : initialComponents) {
comps.add(toolbarItem);
}
}
//Add your own toolbar button using our "ro.sync.exml.workspace.api.standalone.ui.ToolbarButton" API component
ToolbarButton customButton = new ToolbarButton(selectionSourceAction, true);
comps.add(customButton);
toolbarInfo.setComponents(comps.toArray(new JComponent[0]));
}
}
});
pluginWorkspaceAccess.addViewComponentCustomizer(new ViewComponentCustomizer() {
/**
* @see ro.sync.exml.workspace.api.standalone.ViewComponentCustomizer#customizeView(ro.sync.exml.workspace.api.standalone.ViewInfo)
*/
public void customizeView(ViewInfo viewInfo) {
if(
//The view ID defined in the "plugin.xml"
"SampleWorkspaceAccessID".equals(viewInfo.getViewID())) {
customMessagesArea = new JTextArea("Messages:");
viewInfo.setComponent(new JScrollPane(customMessagesArea));
viewInfo.setTitle("Custom Messages");
//You can have images located inside the JAR library and use them...
// viewInfo.setIcon(new ImageIcon(getClass().getClassLoader().getResource("images/customMessage.png").toString()));
}
}
});
}
/**
* Create the Swing action which shows the current selection.
*
* @param pluginWorkspaceAccess The plugin workspace access.
* @return The "Show Selection" action
*/
@SuppressWarnings("serial")
private AbstractAction createShowSelectionAction(
final StandalonePluginWorkspace pluginWorkspaceAccess) {
return new AbstractAction("Show Selection") {
public void actionPerformed(ActionEvent actionevent) {
//Get the current opened XML document
WSEditor editorAccess = pluginWorkspaceAccess.getCurrentEditorAccess(StandalonePluginWorkspace.MAIN_EDITING_AREA);
// The action is available only in Author mode.
if(editorAccess != null){
if (EditorPageConstants.PAGE_AUTHOR.equals(editorAccess.getCurrentPageID())) {
WSAuthorEditorPage authorPageAccess = (WSAuthorEditorPage) editorAccess.getCurrentPage();
AuthorDocumentController controller = authorPageAccess.getDocumentController();
if (authorPageAccess.hasSelection()) {
AuthorDocumentFragment selectionFragment;
try {
// Create fragment from selection
selectionFragment = controller.createDocumentFragment(
authorPageAccess.getSelectionStart(),
authorPageAccess.getSelectionEnd() - 1
);
// Serialize
String serializeFragmentToXML = controller.serializeFragmentToXML(selectionFragment);
// Show fragment
pluginWorkspaceAccess.showInformationMessage(serializeFragmentToXML);
} catch (BadLocationException e) {
pluginWorkspaceAccess.showErrorMessage("Show Selection Source operation failed: " + e.getMessage());
}
} else {
// No selection
pluginWorkspaceAccess.showInformationMessage("No selection available.");
}
} else if (EditorPageConstants.PAGE_TEXT.equals(editorAccess.getCurrentPageID())) {
WSTextEditorPage textPage = (WSTextEditorPage) editorAccess.getCurrentPage();
if (textPage.hasSelection()) {
pluginWorkspaceAccess.showInformationMessage(textPage.getSelectedText());
} else {
// No selection
pluginWorkspaceAccess.showInformationMessage("No selection available.");
}
}
}
}
};
}
/**
* @see ro.sync.exml.plugin.workspace.WorkspaceAccessPluginExtension#applicationClosing()
*/
public boolean applicationClosing() {
//You can reject the application closing here
return true;
}
}