1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 package org.openoffice.test.assistant.views;
25 
26 import java.io.File;
27 import java.lang.reflect.InvocationTargetException;
28 import java.util.ArrayList;
29 
30 import org.eclipse.core.runtime.IProgressMonitor;
31 import org.eclipse.core.runtime.IStatus;
32 import org.eclipse.jdt.core.JavaConventions;
33 import org.eclipse.jface.action.Action;
34 import org.eclipse.jface.action.IMenuListener;
35 import org.eclipse.jface.action.IMenuManager;
36 import org.eclipse.jface.action.IToolBarManager;
37 import org.eclipse.jface.action.MenuManager;
38 import org.eclipse.jface.action.Separator;
39 import org.eclipse.jface.dialogs.MessageDialog;
40 import org.eclipse.jface.operation.IRunnableWithProgress;
41 import org.eclipse.jface.preference.IPreferenceStore;
42 import org.eclipse.jface.text.IDocument;
43 import org.eclipse.jface.text.ITextSelection;
44 import org.eclipse.jface.viewers.CellEditor;
45 import org.eclipse.jface.viewers.ColumnViewerEditor;
46 import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent;
47 import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy;
48 import org.eclipse.jface.viewers.DoubleClickEvent;
49 import org.eclipse.jface.viewers.ICellModifier;
50 import org.eclipse.jface.viewers.IDoubleClickListener;
51 import org.eclipse.jface.viewers.ISelection;
52 import org.eclipse.jface.viewers.IStructuredSelection;
53 import org.eclipse.jface.viewers.TableViewer;
54 import org.eclipse.jface.viewers.TableViewerEditor;
55 import org.eclipse.jface.viewers.TextCellEditor;
56 import org.eclipse.swt.SWT;
57 import org.eclipse.swt.events.ModifyEvent;
58 import org.eclipse.swt.events.ModifyListener;
59 import org.eclipse.swt.graphics.Color;
60 import org.eclipse.swt.layout.GridData;
61 import org.eclipse.swt.layout.GridLayout;
62 import org.eclipse.swt.widgets.Composite;
63 import org.eclipse.swt.widgets.Display;
64 import org.eclipse.swt.widgets.Label;
65 import org.eclipse.swt.widgets.Menu;
66 import org.eclipse.swt.widgets.Table;
67 import org.eclipse.swt.widgets.TableColumn;
68 import org.eclipse.swt.widgets.TableItem;
69 import org.eclipse.swt.widgets.Text;
70 import org.eclipse.ui.IActionBars;
71 import org.eclipse.ui.IEditorPart;
72 import org.eclipse.ui.IWorkbench;
73 import org.eclipse.ui.IWorkbenchActionConstants;
74 import org.eclipse.ui.IWorkbenchPage;
75 import org.eclipse.ui.IWorkbenchWindow;
76 import org.eclipse.ui.PlatformUI;
77 import org.eclipse.ui.part.ViewPart;
78 import org.eclipse.ui.texteditor.AbstractTextEditor;
79 import org.eclipse.ui.texteditor.IDocumentProvider;
80 import org.openoffice.test.assistant.Activator;
81 import org.openoffice.test.assistant.preferences.PreferenceConstants;
82 import org.openoffice.test.vcl.client.CommandCaller.WinInfoReceiver;
83 import org.openoffice.test.vcl.client.Constant;
84 import org.openoffice.test.vcl.client.SmartId;
85 import org.openoffice.test.vcl.client.VclHook;
86 import org.openoffice.test.vcl.widgets.VclApp;
87 
88 public class VclExplorer extends ViewPart implements WinInfoReceiver {
89 	public static final String ID = "org.vclauto.assistant.views.VclExplorer";
90 	private TableViewer viewer;
91 	private Label messageLabel;
92 	private Action inspectAction;
93 	private Action launchAction;
94 	private Action insertCodeAction;
95 	private UIMapOp uiMapOp = new UIMapOp();
96 	private ArrayList<ControlInfo> controlInfos = new ArrayList<ControlInfo>();
97 	private Display display;
98 	private Color duplicatedNameColor;
99 	/**
100 	 * The constructor.
101 	 */
VclExplorer()102 	public VclExplorer() {
103 		VclHook.getCommandCaller().setWinInfoReceiver(this);
104 	}
105 
createPartControl(Composite parent)106 	public void createPartControl(Composite parent) {
107 		GridLayout layout = new GridLayout();
108 		layout.numColumns = 1;
109 		layout.marginLeft = 0;
110 		layout.marginRight = 0;
111 		layout.marginTop = 0;
112 		layout.marginBottom = 0;
113 		layout.marginHeight = 0;
114 		layout.marginWidth = 0;
115 		parent.setLayout(layout);
116 
117 		messageLabel = new Label(parent, SWT.NONE);
118 		GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
119 		gridData.minimumHeight = 14;
120 		gridData.heightHint = 14;
121 		messageLabel.setLayoutData(gridData);
122 
123 		viewer = new TableViewer(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
124 		gridData = new GridData(GridData.FILL_BOTH);
125 		viewer.getTable().setLayoutData(gridData);
126 
127 		viewer.setContentProvider(new VclExplorerContentProvider());
128 		viewer.setLabelProvider(new VclExplorerLabelProvider());
129 		viewer.setInput(controlInfos);
130 
131 		display = parent.getDisplay();
132 		duplicatedNameColor = new Color(display, 255, 160, 160);
133 		final Table table = viewer.getTable();
134 		table.setHeaderVisible(true);
135 		table.setLinesVisible(true);
136 		TableColumn column = new TableColumn(table, SWT.NONE);
137 		column.setText("ID");
138 		column.setResizable(true);
139 		column.setMoveable(false);
140 		column.setWidth(100);
141 		column = new TableColumn(table, SWT.NONE);
142 		column.setText("Name");
143 		column.setResizable(true);
144 		column.setMoveable(false);
145 		column.setWidth(150);
146 
147 		column = new TableColumn(table, SWT.NONE);
148 		column.setText("Type");
149 		column.setResizable(true);
150 		column.setMoveable(false);
151 		column.setWidth(100);
152 		column = new TableColumn(table, SWT.NONE);
153 		column.setText("Tips");
154 		column.setResizable(true);
155 		column.setMoveable(false);
156 		column.setWidth(200);
157 
158 		viewer.setColumnProperties(new String[] { "ID", "Name", "Type", "Tips" });
159 		TextCellEditor nameCellEditor = new TextCellEditor(viewer.getTable());
160 		final Text nameText = ((Text) nameCellEditor.getControl());
161 		nameText.addModifyListener(new ModifyListener() {
162 					public void modifyText(ModifyEvent me) {
163 						String message = validateName(nameText.getText());
164 						if (message != null) {
165 							messageLabel.setText(message);
166 							nameText.setBackground(duplicatedNameColor);
167 						} else {
168 							messageLabel.setText("");
169 							nameText.setBackground(null);
170 						}
171 					}
172 				});
173 
174 		viewer.setCellEditors(new CellEditor[] { null, nameCellEditor, null, null});
175 		viewer.setCellModifier(new ICellModifier() {
176 
177 			public boolean canModify(Object element, String property) {
178 				if (!"Name".equals(property))
179 					return false;
180 
181 				ControlInfo controlInfo = (ControlInfo) element;
182 				if (controlInfo.name != null)
183 					return false;
184 
185 				return uiMapOp.scan();
186 			}
187 
188 			public Object getValue(Object element, String property) {
189 //				if (!"Name".equals(property))
190 //					return false;
191 				ControlInfo controlInfo = (ControlInfo) element;
192 				return controlInfo.name == null ? "" : controlInfo.name;
193 			}
194 
195 			public void modify(Object element, String property, Object value) {
196 //				if (!"Name".equals(property))
197 //					return;
198 				TableItem item = (TableItem) element;
199 				ControlInfo controlInfo = (ControlInfo) item.getData();
200 				String newName = (String) value;
201 				String msg = validateName(newName);
202 				if (msg == null) {
203 					controlInfo.name = newName;
204 					if (doDefineName(controlInfo)) {
205 						item.setText(1, newName);
206 						messageLabel.setText("");
207 					} else {
208 						controlInfo.name = null;
209 						messageLabel.setText("Can't define the control in UIMap. UIMap maybe is broken!");
210 					}
211 				} else {
212 					messageLabel.setText(msg);
213 				}
214 			}
215 
216 		});
217 
218 		ColumnViewerEditorActivationStrategy actSupport = new ColumnViewerEditorActivationStrategy(
219 				viewer) {
220 			protected boolean isEditorActivationEvent(
221 					ColumnViewerEditorActivationEvent event) {
222 				return event.eventType == ColumnViewerEditorActivationEvent.TRAVERSAL
223 						|| event.eventType == ColumnViewerEditorActivationEvent.MOUSE_DOUBLE_CLICK_SELECTION
224 						|| event.eventType == ColumnViewerEditorActivationEvent.PROGRAMMATIC;
225 			}
226 		};
227 
228 		TableViewerEditor.create(viewer, actSupport,
229 				ColumnViewerEditor.TABBING_HORIZONTAL
230 						| ColumnViewerEditor.TABBING_MOVE_TO_ROW_NEIGHBOR
231 						| ColumnViewerEditor.TABBING_VERTICAL
232 						| ColumnViewerEditor.KEYBOARD_ACTIVATION);
233 
234 		// Create the help context id for the viewer's control
235 		PlatformUI.getWorkbench().getHelpSystem().setHelp(viewer.getControl(), "org.vclauto.assistant.viewer");
236 		makeActions();
237 		hookContextMenu();
238 		hookDoubleClickAction();
239 		contributeToActionBars();
240 	}
241 
hookContextMenu()242 	private void hookContextMenu() {
243 		MenuManager menuMgr = new MenuManager("#PopupMenu");
244 		menuMgr.setRemoveAllWhenShown(true);
245 		menuMgr.addMenuListener(new IMenuListener() {
246 			public void menuAboutToShow(IMenuManager manager) {
247 				VclExplorer.this.fillContextMenu(manager);
248 			}
249 		});
250 		Menu menu = menuMgr.createContextMenu(viewer.getControl());
251 		viewer.getControl().setMenu(menu);
252 		getSite().registerContextMenu(menuMgr, viewer);
253 	}
254 
contributeToActionBars()255 	private void contributeToActionBars() {
256 		IActionBars bars = getViewSite().getActionBars();
257 		fillLocalPullDown(bars.getMenuManager());
258 		fillLocalToolBar(bars.getToolBarManager());
259 	}
260 
fillLocalPullDown(IMenuManager manager)261 	private void fillLocalPullDown(IMenuManager manager) {
262 		manager.add(inspectAction);
263 		manager.add(new Separator());
264 		manager.add(launchAction);
265 	}
266 
fillContextMenu(IMenuManager manager)267 	private void fillContextMenu(IMenuManager manager) {
268 		manager.add(inspectAction);
269 		manager.add(launchAction);
270 		// Other plug-ins can contribute there actions here
271 		manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
272 	}
273 
fillLocalToolBar(IToolBarManager manager)274 	private void fillLocalToolBar(IToolBarManager manager) {
275 		manager.add(inspectAction);
276 		manager.add(launchAction);
277 	}
278 
makeActions()279 	private void makeActions() {
280 		inspectAction = new Action() {
281 			public void run() {
282 				if (!VclHook.available()) {
283 					showMessage("OpenOffice is not launched or initializing. Click \"Launch\" to start OpenOffice or wait it to finish initializing.");
284 					return;
285 				}
286 				try {
287 					VclHook.invokeCommand(Constant.RC_DisplayHid, new Object[]{Boolean.TRUE});
288 				} catch (Exception e) {
289 					showMessage("OpenOffice disappeared! It maybe crashed or freezed. Please re-launch it.");
290 				}
291 
292 
293 			}
294 		};
295 		inspectAction.setText("Inspect");
296 		inspectAction.setToolTipText("Inspect VCL controls.");
297 //		action1.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().
298 //			getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK));
299 
300 		launchAction = new Action() {
301 			public void run() {
302 				IPreferenceStore store = Activator.getDefault().getPreferenceStore();
303 				final String ooHome = store.getString(PreferenceConstants.P_OPENOFFICE_HOME);
304 				if (ooHome == null || ooHome.length() == 0) {
305 					showMessage("Please set OpenOffice home in the Vclauto assistant preference page.");
306 					return;
307 				}
308 				File ooHomeFile = new File(ooHome, "soffice.bin");
309 				if (!ooHomeFile.exists()) {
310 					showMessage("OpenOffice home is not set correctly in the Vclauto assistant preference page.");
311 					return;
312 				}
313 
314 				IRunnableWithProgress op = new IRunnableWithProgress() {
315 					@Override
316 					public void run(IProgressMonitor arg0) throws InvocationTargetException, InterruptedException {
317 						VclApp app = new VclApp(ooHome);
318 						if (!app.exists()) {
319 							app.kill();
320 							app.start();
321 						}
322 					}
323 				};
324 
325 				IWorkbench wb = PlatformUI.getWorkbench();
326 
327 				try {
328 					wb.getProgressService().run(true, false, op);
329 				} catch (InvocationTargetException e) {
330 					e.printStackTrace();
331 				} catch (InterruptedException e) {
332 
333 					e.printStackTrace();
334 				}
335 			}
336 		};
337 		launchAction.setText("Launch");
338 		launchAction.setToolTipText("Launch OpenOffice");
339 //		action2.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().
340 //				getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK));
341 		insertCodeAction = new Action() {
342 			public void run() {
343 				ISelection selection = viewer.getSelection();
344 				if (selection == null)
345 					return;
346 
347 				final ControlInfo controlInfo = (ControlInfo)((IStructuredSelection) selection).getFirstElement();
348 				if (controlInfo.name != null) {
349 					doInsertCode(controlInfo.name);
350 				}
351 			}
352 		};
353 	}
354 
validateName(String name)355 	private String validateName(String name) {
356 		 if (uiMapOp.names.contains(name))
357 			 return "Duplicated name.";
358 		 IStatus status = JavaConventions.validateFieldName(name, "1.5", "1.5");
359 		 return status.isOK() ? null : "It's an invalidate java field name.";
360 	}
doDefineName(ControlInfo controlInfo)361 	private boolean doDefineName(ControlInfo controlInfo) {
362 		try {
363 			uiMapOp.define(controlInfo);
364 		} catch (Exception e) {
365 			controlInfo.name = null;
366 			e.printStackTrace();
367 		}
368 
369 		return true;
370 	}
371 
doInsertCode(String code)372 	private void doInsertCode(String code) {
373 		IWorkbench wb = PlatformUI.getWorkbench();
374 		IWorkbenchWindow window = wb.getActiveWorkbenchWindow();
375 		IWorkbenchPage page = window.getActivePage();
376 
377 		IEditorPart editorPart = page.getActiveEditor();
378 		if (!(editorPart instanceof AbstractTextEditor))
379 			return;
380 
381 		AbstractTextEditor editor = (AbstractTextEditor) editorPart;
382 		IDocumentProvider dp = editor.getDocumentProvider();
383 		IDocument doc = dp.getDocument(editor.getEditorInput());
384 		try {
385 			ITextSelection textSelection = (ITextSelection) editorPart.getSite().getSelectionProvider().getSelection();
386 			int offset = textSelection.getOffset();
387 
388 			doc.replace(offset, textSelection.getLength(), code);
389 		} catch (Exception e) {
390 			// TODO: handle exception
391 			e.printStackTrace();
392 		}
393 	}
394 
hookDoubleClickAction()395 	private void hookDoubleClickAction() {
396 		viewer.addDoubleClickListener(new IDoubleClickListener() {
397 			public void doubleClick(DoubleClickEvent event) {
398 
399 				insertCodeAction.run();
400 			}
401 		});
402 	}
showMessage(String message)403 	private void showMessage(String message) {
404 		MessageDialog.openInformation(
405 			viewer.getControl().getShell(),
406 			"Vcl Explorer",
407 			message);
408 	}
409 
410 	/**
411 	 * Passing the focus request to the viewer's control.
412 	 */
setFocus()413 	public void setFocus() {
414 		viewer.getControl().setFocus();
415 	}
416 
417 
418 	@Override
addWinInfo(final SmartId id, final long type, final String t)419 	public void addWinInfo(final SmartId id, final long type, final String t) {
420 		final String tooltip = t.replaceAll("%.*%.*:", "");
421 		ControlInfo info = new ControlInfo(id, type, tooltip);
422 		//info.shot();
423 		controlInfos.add(info);
424 	}
425 
426 	@Override
onFinishReceiving()427 	public void onFinishReceiving() {
428 //		for (ControlInfo info : controlInfos) {
429 //			info.shot();
430 //		}
431 //
432 		display.asyncExec(new Runnable() {
433 			public void run() {
434 				if (uiMapOp.scan()) {
435 					uiMapOp.populateName(controlInfos);
436 				} else {
437 					messageLabel.setText("Can not find UIMap and code generating will not work.");
438 				}
439 				viewer.setInput(controlInfos);
440 			}
441 		});
442 	}
443 
444 	@Override
onStartReceiving()445 	public void onStartReceiving() {
446 		controlInfos = new ArrayList<ControlInfo>();
447 	}
448 }