1
/*******************************************************************************
2
* Copyright (C) 2003-2004, 2013, Guillaume Brocker
4
* All rights reserved. This program and the accompanying materials
5
* are made available under the terms of the Eclipse Public License v1.0
6
* which accompanies this distribution, and is available at
7
* http://www.eclipse.org/legal/epl-v10.html
10
* Guillaume Brocker - Initial API and implementation
12
******************************************************************************/
14
package eclox.ui.editor.advanced;
16
import java.util.regex.Matcher;
17
import java.util.regex.Pattern;
19
import org.eclipse.jface.dialogs.MessageDialog;
20
import org.eclipse.jface.resource.FontRegistry;
21
import org.eclipse.jface.viewers.ISelection;
22
import org.eclipse.swt.layout.FillLayout;
23
import org.eclipse.swt.layout.GridData;
24
import org.eclipse.swt.layout.GridLayout;
25
import org.eclipse.swt.widgets.Composite;
26
import org.eclipse.ui.forms.IDetailsPage;
27
import org.eclipse.ui.forms.IFormPart;
28
import org.eclipse.ui.forms.IManagedForm;
29
import org.eclipse.ui.forms.events.HyperlinkEvent;
30
import org.eclipse.ui.forms.events.IHyperlinkListener;
31
import org.eclipse.ui.forms.widgets.FormText;
32
import org.eclipse.ui.forms.widgets.FormToolkit;
33
import org.eclipse.ui.forms.widgets.Section;
35
import eclox.core.doxyfiles.Doxyfile;
36
import eclox.core.doxyfiles.Setting;
37
import eclox.ui.Plugin;
38
import eclox.ui.editor.editors.SettingEditor;
42
* Implements the generic details node page.
46
public class DetailsPage implements IDetailsPage {
48
/** symbolic name for emphasis font */
49
private static final String EMPHASIS = "em";
51
/** the static setting editor class register */
52
private static EditorClassRegister editorClassRegister = new EditorClassRegister();
54
/** the setting editor instance */
55
private SettingEditor editor;
57
/** the section that contains all our controls */
58
private Section section;
60
/** he editor content container widget */
61
private Composite editorContainer;
63
/** the control containing all controls of the section */
64
private Composite sectionContent;
66
/** the managed form the page is attached to */
67
protected IManagedForm managedForm;
69
/** the current selection */
70
private NavigableSelection selection = new NavigableSelection();
72
/** the control displaying the setting's note text */
73
private FormText noteLabel;
75
/** the font registry used for note text formatting */
76
private FontRegistry fontRegistry;
79
* Defines the listeners that will managed activation of hyper-links in the
82
private class MyHyperlinkListener implements IHyperlinkListener {
84
private DetailsPage owner;
89
* @param owner the owner of the instance
91
MyHyperlinkListener( DetailsPage owner ) {
96
* @see org.eclipse.ui.forms.events.IHyperlinkListener#linkActivated(org.eclipse.ui.forms.events.HyperlinkEvent)
98
public void linkActivated(HyperlinkEvent e) {
100
assert editor != null;
102
Doxyfile doxyfile = editor.getInput().getOwner();
103
Setting setting = doxyfile.getSetting( e.getHref().toString() );
105
if( setting != null ) {
106
managedForm.fireSelectionChanged( owner, selection.select(setting) );
111
* @see org.eclipse.ui.forms.events.IHyperlinkListener#linkEntered(org.eclipse.ui.forms.events.HyperlinkEvent)
113
public void linkEntered(HyperlinkEvent e) {}
116
* @see org.eclipse.ui.forms.events.IHyperlinkListener#linkExited(org.eclipse.ui.forms.events.HyperlinkEvent)
118
public void linkExited(HyperlinkEvent e) {}
123
* @see org.eclipse.ui.forms.IDetailsPage#createContents(org.eclipse.swt.widgets.Composite)
125
public void createContents(Composite parent) {
126
FormToolkit toolkit = this.managedForm.getToolkit();
128
fontRegistry = new FontRegistry(parent.getDisplay());
130
// Initializes the parent control.
131
parent.setLayout(new FillLayout());
133
// Creates the section
134
this.section = toolkit.createSection(parent, Section.TITLE_BAR);
135
this.section.marginHeight = 5;
136
this.section.marginWidth = 10;
138
// Createst the section content and its layout
139
this.sectionContent = toolkit.createComposite(section);
140
this.section.setClient(this.sectionContent);
141
GridLayout layout = new GridLayout(1, true);
142
layout.marginWidth = 0;
143
layout.marginHeight = 0;
144
this.sectionContent.setLayout(layout);
146
// Creates the editor content.
147
this.editorContainer = managedForm.getToolkit().createComposite(sectionContent);
148
this.editorContainer.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
150
// Creates controls displaying the setting note.
151
this.noteLabel = this.managedForm.getToolkit().createFormText( sectionContent, false );
152
this.noteLabel.setLayoutData( new GridData(GridData.FILL_HORIZONTAL) );
153
this.noteLabel.setFont( EMPHASIS, fontRegistry.getItalic("") );
154
this.noteLabel.addHyperlinkListener( new MyHyperlinkListener(this) );
159
* @see org.eclipse.ui.forms.IFormPart#commit(boolean)
161
public void commit(boolean onSave) {
162
if( editor != null ) {
168
* @see org.eclipse.ui.forms.IFormPart#dispose()
170
public void dispose() {}
173
* @see org.eclipse.ui.forms.IFormPart#initialize(org.eclipse.ui.forms.IManagedForm)
175
public void initialize(IManagedForm form) {
176
this.managedForm = form;
180
* @see org.eclipse.ui.forms.IFormPart#isDirty()
182
public boolean isDirty() {
183
return editor != null ? editor.isDirty() : false;
187
* @see org.eclipse.ui.forms.IFormPart#isStale()
189
public boolean isStale() {
190
return editor != null ? editor.isStale() : false;
194
* @see org.eclipse.ui.forms.IFormPart#refresh()
196
public void refresh() {
197
if( editor != null ) {
203
* @see org.eclipse.ui.forms.IFormPart#setFocus()
205
public void setFocus() {
207
assert this.editor != null;
209
this.editor.setFocus();
213
* @see org.eclipse.ui.forms.IFormPart#setFormInput(java.lang.Object)
215
public boolean setFormInput(Object input) {
220
* @see org.eclipse.ui.forms.IPartSelectionListener#selectionChanged(org.eclipse.ui.forms.IFormPart, org.eclipse.jface.viewers.ISelection)
222
public void selectionChanged(IFormPart part, ISelection newSelection) {
224
assert (newSelection instanceof NavigableSelection);
226
// Retreieves the node that is provided by the selection.
227
/*if( part != this )*/ {
228
selection = (NavigableSelection) newSelection;
229
Object object = selection.getFirstElement();
230
Setting setting = (object instanceof Setting) ? (Setting) object : null;
231
String text = setting.getProperty(Setting.TEXT);
233
// Checks that the setting has a text property.
235
Plugin.log(setting.getIdentifier() + ": missing TEXT property.");
236
text = new String(setting.getIdentifier());
239
// Updates the form controls.
240
this.selectNote(setting);
241
this.selectEditor(setting);
242
this.section.setText( text );
243
this.section.layout(true, true);
248
* Disposes the current editor.
250
private void disposeEditor() {
258
* Selects the editor for the specified setting.
260
* @param input the setting that is the new input
262
private void selectEditor(Setting input) {
264
// Retrieves the editor class for the input.
265
Class editorClass = editorClassRegister.find(input);
267
// Perhaps should we remove the current editor.
268
if(editor != null && editor.getClass() != editorClass) {
272
// Perhaps, we should create a new editor instance.
274
editor = (SettingEditor) editorClass.newInstance();
275
editor.createContent(editorContainer, managedForm.getToolkit());
276
editorContainer.setLayoutData( new GridData(editor.grabVerticalSpace() ? GridData.FILL_BOTH : GridData.FILL_HORIZONTAL) );
279
// Assigns the input to the editor.
280
editor.setInput(input);
283
catch(Throwable throwable) {
284
MessageDialog.openError(this.managedForm.getForm().getShell(), "Unexpected Error", throwable.toString());
289
* Updates the UI controls for the specified node.
291
* @param setting a setting instance to use to refresh the UI controls.
293
private void selectNote(Setting setting) {
294
// Retrieves the setting's note text.
295
String text = setting.getProperty( Setting.NOTE );
297
// If there is none, build a default one.
299
text = "Not available.";
301
// Else do some parsing and replacements for layout and style.
303
Doxyfile doxyfile = setting.getOwner();
305
text = text.startsWith("<p>") ? text : "<p>"+text+"</p>";
306
Matcher matcher = Pattern.compile("([A-Z_]{2,}|Warning:|Note:|@[a-z]+)").matcher(text);
307
StringBuffer buffer = new StringBuffer();
308
while( matcher.find() ) {
309
String match = matcher.group(1);
311
if( match.equals("YES") || match.equals("NO") ) {
312
matcher.appendReplacement( buffer, "<span font=\""+EMPHASIS+"\">"+match+"</span>");
314
else if( match.equals("Note:") || match.equals("Warning:") ) {
315
matcher.appendReplacement( buffer, "<b>"+match+"</b>");
317
else if( match.startsWith("@") ) {
318
matcher.appendReplacement( buffer, "<span font=\""+EMPHASIS+"\">"+match+"</span>");
321
Setting matchSetting = doxyfile.getSetting(match);
323
if( matchSetting != null ) {
324
String settingText = matchSetting.getProperty(Setting.TEXT);
326
if( matchSetting == setting ) {
327
matcher.appendReplacement( buffer, "<span font=\""+EMPHASIS+"\">"+settingText+"</span>");
330
matcher.appendReplacement( buffer, "<a href=\""+matchSetting.getIdentifier()+"\">"+settingText+"</a>");
335
matcher.appendTail( buffer );
336
text = buffer.toString();
339
// Finally, assignes the text to the user interface control.
340
this.noteLabel.setText("<form>"+text+"</form>", true, false);