blob: 01469fdf6ed81bbcd159e95e6135d530df4b211e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2005 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ui.internal.ide.dialogs;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import javax.xml.parsers.ParserConfigurationException;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.preference.JFacePreferences;
import org.eclipse.jface.resource.JFaceColors;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.ide.IDEInternalWorkbenchImages;
import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
import org.eclipse.ui.internal.ide.IIDEHelpContextIds;
import org.eclipse.ui.part.EditorPart;
import org.xml.sax.SAXException;
/**
* A "fake" editor to show a welcome page
* The contents of this page are supplied in the product configuration
*
* PRIVATE
* This class is internal to the workbench and must not be called outside the workbench
*/
public class WelcomeEditor extends EditorPart {
private final static int HORZ_SCROLL_INCREMENT = 20;
private final static int VERT_SCROLL_INCREMENT = 20;
// width at which wrapping will stop and a horizontal scroll bar will be
// introduced
private final static int WRAP_MIN_WIDTH = 150;
private Composite editorComposite;
private Cursor handCursor;
private Cursor busyCursor;
private WelcomeParser parser;
private ArrayList hyperlinkRanges = new ArrayList();
private ArrayList texts = new ArrayList();
private ScrolledComposite scrolledComposite;
private IPropertyChangeListener colorListener;
private boolean mouseDown = false;
private boolean dragEvent = false;
private StyledText firstText, lastText;
private StyledText lastNavigatedText, currentText;
private boolean nextTabAbortTraversal, previousTabAbortTraversal = false;
private WelcomeEditorCopyAction copyAction;
/**
* Create a new instance of the welcome editor
*/
public WelcomeEditor() {
super();
setPartName(IDEWorkbenchMessages.WelcomeEditor_title);
copyAction = new WelcomeEditorCopyAction(this);
copyAction.setEnabled(false);
}
/**
* Update the welcome page to start at the
* beginning of the text.
*/
private void focusOn(StyledText newText, int caretOffset) {
if (newText == null)
return;
newText.setFocus();
newText.setCaretOffset(caretOffset);
scrolledComposite.setOrigin(0, newText.getLocation().y);
}
/**
* Finds the next text
*/
private StyledText nextText(StyledText text) {
int index = 0;
if (text == null)
return (StyledText) texts.get(0);
else
index = texts.indexOf(text);
//If we are not at the end....
if (index < texts.size() - 1)
return (StyledText) texts.get(index + 1);
else
return (StyledText) texts.get(0);
}
/**
* Finds the previous text
*/
private StyledText previousText(StyledText text) {
int index = 0;
if (text == null)
return (StyledText) texts.get(0);
else
index = texts.indexOf(text);
//If we are at the beginning....
if (index == 0)
return (StyledText) texts.get(texts.size() - 1);
else
return (StyledText) texts.get(index - 1);
}
/**
* Returns the current text.
*/
protected StyledText getCurrentText() {
return currentText;
}
/**
* Returns the copy action.
*/
protected WelcomeEditorCopyAction getCopyAction() {
return copyAction;
}
/**
* Finds the next link after the current selection.
*/
private StyleRange findNextLink(StyledText text) {
if (text == null)
return null;
WelcomeItem item = (WelcomeItem) text.getData();
StyleRange[] ranges = text.getStyleRanges();
int currentSelectionEnd = text.getSelection().y;
for (int i = 0; i < ranges.length; i++) {
if (ranges[i].start >= currentSelectionEnd)
if (item.isLinkAt(ranges[i].start))
return ranges[i];
}
return null;
}
/**
* Finds the previous link before the current selection.
*/
private StyleRange findPreviousLink(StyledText text) {
if (text == null)
return null;
WelcomeItem item = (WelcomeItem) text.getData();
StyleRange[] ranges = text.getStyleRanges();
int currentSelectionStart = text.getSelection().x;
for (int i = ranges.length - 1; i > -1; i--) {
if ((ranges[i].start + ranges[i].length) < currentSelectionStart)
if (item.isLinkAt(ranges[i].start + ranges[i].length - 1))
return ranges[i];
}
return null;
}
/**
* Finds the current link of the current selection.
*/
protected StyleRange getCurrentLink(StyledText text) {
StyleRange[] ranges = text.getStyleRanges();
int currentSelectionEnd = text.getSelection().y;
int currentSelectionStart = text.getSelection().x;
for (int i = 0; i < ranges.length; i++) {
if ((currentSelectionStart >= ranges[i].start)
&& (currentSelectionEnd <= (ranges[i].start + ranges[i].length))) {
return ranges[i];
}
}
return null;
}
/**
* Adds listeners to the given styled text
*/
private void addListeners(StyledText styledText) {
styledText.addMouseListener(new MouseAdapter() {
public void mouseDown(MouseEvent e) {
if (e.button != 1) {
return;
}
mouseDown = true;
}
public void mouseUp(MouseEvent e) {
mouseDown = false;
StyledText text = (StyledText) e.widget;
WelcomeItem item = (WelcomeItem) e.widget.getData();
int offset = text.getCaretOffset();
if (dragEvent) {
dragEvent = false;
if (item.isLinkAt(offset)) {
text.setCursor(handCursor);
}
} else if (item.isLinkAt(offset)) {
text.setCursor(busyCursor);
if (e.button == 1) {
item.triggerLinkAt(offset);
StyleRange selectionRange = getCurrentLink(text);
text.setSelectionRange(selectionRange.start,
selectionRange.length);
text.setCursor(null);
}
}
}
});
styledText.addMouseMoveListener(new MouseMoveListener() {
public void mouseMove(MouseEvent e) {
// Do not change cursor on drag events
if (mouseDown) {
if (!dragEvent) {
StyledText text = (StyledText) e.widget;
text.setCursor(null);
}
dragEvent = true;
return;
}
StyledText text = (StyledText) e.widget;
WelcomeItem item = (WelcomeItem) e.widget.getData();
int offset = -1;
try {
offset = text.getOffsetAtLocation(new Point(e.x, e.y));
} catch (IllegalArgumentException ex) {
// location is not over a character
}
if (offset == -1)
text.setCursor(null);
else if (item.isLinkAt(offset))
text.setCursor(handCursor);
else
text.setCursor(null);
}
});
styledText.addTraverseListener(new TraverseListener() {
public void keyTraversed(TraverseEvent e) {
StyledText text = (StyledText) e.widget;
switch (e.detail) {
case SWT.TRAVERSE_ESCAPE:
e.doit = true;
break;
case SWT.TRAVERSE_TAB_NEXT:
// Handle Ctrl-Tab
if ((e.stateMask & SWT.CTRL) != 0) {
if (e.widget == lastText)
return;
else {
e.doit = false;
nextTabAbortTraversal = true;
lastText.traverse(SWT.TRAVERSE_TAB_NEXT);
return;
}
}
if (nextTabAbortTraversal) {
nextTabAbortTraversal = false;
return;
}
// Find the next link in current widget, if applicable
// Stop at top of widget
StyleRange nextLink = findNextLink(text);
if (nextLink == null) {
// go to the next widget, focus at beginning
StyledText nextText = nextText(text);
nextText.setSelection(0);
focusOn(nextText, 0);
} else {
// focusOn: allow none tab traversals to align
focusOn(text, text.getSelection().x);
text.setSelectionRange(nextLink.start, nextLink.length);
}
e.detail = SWT.TRAVERSE_NONE;
e.doit = true;
break;
case SWT.TRAVERSE_TAB_PREVIOUS:
// Handle Ctrl-Shift-Tab
if ((e.stateMask & SWT.CTRL) != 0) {
if (e.widget == firstText)
return;
else {
e.doit = false;
previousTabAbortTraversal = true;
firstText.traverse(SWT.TRAVERSE_TAB_PREVIOUS);
return;
}
}
if (previousTabAbortTraversal) {
previousTabAbortTraversal = false;
return;
}
// Find the previous link in current widget, if applicable
// Stop at top of widget also
StyleRange previousLink = findPreviousLink(text);
if (previousLink == null) {
if (text.getSelection().x == 0) {
// go to the previous widget, focus at end
StyledText previousText = previousText(text);
previousText.setSelection(previousText
.getCharCount());
previousLink = findPreviousLink(previousText);
if (previousLink == null)
focusOn(previousText, 0);
else {
focusOn(previousText, previousText
.getSelection().x);
previousText
.setSelectionRange(previousLink.start,
previousLink.length);
}
} else {
// stay at top of this widget
focusOn(text, 0);
}
} else {
// focusOn: allow none tab traversals to align
focusOn(text, text.getSelection().x);
text.setSelectionRange(previousLink.start,
previousLink.length);
}
e.detail = SWT.TRAVERSE_NONE;
e.doit = true;
break;
default:
break;
}
}
});
styledText.addKeyListener(new KeyListener() {
public void keyReleased(KeyEvent e) {
//Ignore a key release
}
public void keyPressed(KeyEvent event) {
StyledText text = (StyledText) event.widget;
if (event.character == ' ' || event.character == SWT.CR) {
if (text != null) {
WelcomeItem item = (WelcomeItem) text.getData();
//Be sure we are in the selection
int offset = text.getSelection().x + 1;
if (item.isLinkAt(offset)) {
text.setCursor(busyCursor);
item.triggerLinkAt(offset);
StyleRange selectionRange = getCurrentLink(text);
text.setSelectionRange(selectionRange.start,
selectionRange.length);
text.setCursor(null);
}
}
return;
}
// When page down is pressed, move the cursor to the next item in the
// welcome page. Note that this operation wraps (pages to the top item
// when the last item is reached).
if (event.keyCode == SWT.PAGE_DOWN) {
focusOn(nextText(text), 0);
return;
}
// When page up is pressed, move the cursor to the previous item in the
// welcome page. Note that this operation wraps (pages to the bottom item
// when the first item is reached).
if (event.keyCode == SWT.PAGE_UP) {
focusOn(previousText(text), 0);
return;
}
}
});
styledText.addFocusListener(new FocusAdapter() {
public void focusLost(FocusEvent e) {
// Remember current text widget
lastNavigatedText = (StyledText) e.widget;
}
public void focusGained(FocusEvent e) {
currentText = (StyledText) e.widget;
// Remove highlighted selection if text widget has changed
if ((currentText != lastNavigatedText)
&& (lastNavigatedText != null))
lastNavigatedText.setSelection(lastNavigatedText
.getSelection().x);
// enable/disable copy action
copyAction.setEnabled(currentText.getSelectionCount() > 0);
}
});
styledText.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
// enable/disable copy action
StyledText text = (StyledText) e.widget;
copyAction.setEnabled(text.getSelectionCount() > 0);
}
});
}
/**
* Creates the wizard's title area.
*
* @param parent the SWT parent for the title area composite
* @return the created info area composite
*/
private Composite createInfoArea(Composite parent) {
// Create the title area which will contain
// a title, message, and image.
this.scrolledComposite = new ScrolledComposite(parent, SWT.V_SCROLL
| SWT.H_SCROLL);
this.scrolledComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
final Composite infoArea = new Composite(this.scrolledComposite,
SWT.NONE);
GridLayout layout = new GridLayout();
layout.marginHeight = 10;
layout.verticalSpacing = 5;
layout.numColumns = 2;
infoArea.setLayout(layout);
GridData data = new GridData(GridData.FILL_BOTH);
infoArea.setLayoutData(data);
boolean wrapped = parser.isFormatWrapped();
int HINDENT = 20;
// Get the background color for the title area
Display display = parent.getDisplay();
Color background = JFaceColors.getBannerBackground(display);
Color foreground = JFaceColors.getBannerForeground(display);
infoArea.setBackground(background);
int textStyle = SWT.MULTI | SWT.READ_ONLY;
if (wrapped) {
textStyle = textStyle | SWT.WRAP;
}
StyledText sampleStyledText = null;
// Create the intro item
WelcomeItem item = getIntroItem();
if (item != null) {
StyledText styledText = new StyledText(infoArea, textStyle);
this.texts.add(styledText);
sampleStyledText = styledText;
styledText.setCursor(null);
JFaceColors.setColors(styledText, foreground, background);
styledText.setText(getIntroItem().getText());
setBoldRanges(styledText, item.getBoldRanges());
setLinkRanges(styledText, item.getActionRanges());
setLinkRanges(styledText, item.getHelpRanges());
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = 2;
gd.horizontalIndent = HINDENT;
gd.verticalAlignment = GridData.VERTICAL_ALIGN_BEGINNING;
styledText.setLayoutData(gd);
styledText.setData(item);
addListeners(styledText);
Label spacer = new Label(infoArea, SWT.NONE);
spacer.setBackground(background);
gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
gd.horizontalSpan = 2;
spacer.setLayoutData(gd);
}
firstText = sampleStyledText;
// Create the welcome items
Label imageLabel = null;
WelcomeItem[] items = getItems();
for (int i = 0; i < items.length; i++) {
Label label = new Label(infoArea, SWT.NONE);
label.setBackground(background);
label
.setImage(PlatformUI
.getWorkbench()
.getSharedImages()
.getImage(
IDEInternalWorkbenchImages.IMG_OBJS_WELCOME_ITEM));
GridData gd = new GridData();
gd.horizontalIndent = HINDENT;
gd.verticalAlignment = GridData.VERTICAL_ALIGN_BEGINNING;
label.setLayoutData(gd);
if (imageLabel == null) {
imageLabel = label;
}
StyledText styledText = new StyledText(infoArea, textStyle);
this.texts.add(styledText);
sampleStyledText = styledText;
styledText.setCursor(null);
JFaceColors.setColors(styledText, foreground, background);
styledText.setText(items[i].getText());
setBoldRanges(styledText, items[i].getBoldRanges());
setLinkRanges(styledText, items[i].getActionRanges());
setLinkRanges(styledText, items[i].getHelpRanges());
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.verticalAlignment = GridData.VERTICAL_ALIGN_BEGINNING;
gd.verticalSpan = 2;
styledText.setLayoutData(gd);
styledText.setData(items[i]);
addListeners(styledText);
Label spacer = new Label(infoArea, SWT.NONE);
spacer.setBackground(background);
gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
gd.horizontalSpan = 2;
spacer.setLayoutData(gd);
// create context menu
MenuManager menuMgr = new MenuManager("#PopUp"); //$NON-NLS-1$
menuMgr.add(copyAction);
styledText.setMenu(menuMgr.createContextMenu(styledText));
}
lastText = sampleStyledText;
this.scrolledComposite.setContent(infoArea);
Point p = infoArea.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
this.scrolledComposite.setMinHeight(p.y);
if (wrapped) {
// introduce a horizontal scroll bar after a minimum width is reached
this.scrolledComposite.setMinWidth(WRAP_MIN_WIDTH);
} else {
this.scrolledComposite.setMinWidth(p.x);
}
this.scrolledComposite.setExpandHorizontal(true);
this.scrolledComposite.setExpandVertical(true);
// When the welcome editor is resized, we need to set the width hint for
// wrapped StyledText widgets so that the wrapped height will be recalculated.
if (wrapped && (imageLabel != null)) {
// figure out how wide the StyledText widgets should be, do this by first
// calculating the width of the area not used by styled text widgets
Rectangle bounds = imageLabel.getBounds();
final int adjust = HINDENT + bounds.width + layout.verticalSpacing
+ (layout.marginWidth * 2);
final int adjustFirst = HINDENT + (layout.marginWidth * 2);
infoArea.addListener(SWT.Resize, new Listener() {
public void handleEvent(Event event) {
int w = scrolledComposite.getClientArea().width;
// if the horizontal scroll bar exists, we want to wrap to the
// minimum wrap width
if (w < WRAP_MIN_WIDTH) {
w = WRAP_MIN_WIDTH;
}
for (int i = 0; i < texts.size(); i++) {
int extent;
if (i == 0)
extent = w - adjustFirst;
else
extent = w - adjust;
StyledText text = (StyledText) texts.get(i);
Point p = text.computeSize(extent, SWT.DEFAULT, false);
((GridData) text.getLayoutData()).widthHint = p.x;
}
// reset the scrolled composite height since the height of the
// styled text widgets have changed
Point p = infoArea.computeSize(SWT.DEFAULT, SWT.DEFAULT,
true);
scrolledComposite.setMinHeight(p.y);
}
});
}
// Adjust the scrollbar increments
if (sampleStyledText == null) {
this.scrolledComposite.getHorizontalBar().setIncrement(
HORZ_SCROLL_INCREMENT);
this.scrolledComposite.getVerticalBar().setIncrement(
VERT_SCROLL_INCREMENT);
} else {
GC gc = new GC(sampleStyledText);
int width = gc.getFontMetrics().getAverageCharWidth();
gc.dispose();
this.scrolledComposite.getHorizontalBar().setIncrement(width);
this.scrolledComposite.getVerticalBar().setIncrement(
sampleStyledText.getLineHeight());
}
return infoArea;
}
/**
* Creates the SWT controls for this workbench part.
* <p>
* Clients should not call this method (the workbench calls this method at
* appropriate times).
* </p>
* <p>
* For implementors this is a multi-step process:
* <ol>
* <li>Create one or more controls within the parent.</li>
* <li>Set the parent layout as needed.</li>
* <li>Register any global actions with the <code>IActionService</code>.</li>
* <li>Register any popup menus with the <code>IActionService</code>.</li>
* <li>Register a selection provider with the <code>ISelectionService</code>
* (optional). </li>
* </ol>
* </p>
*
* @param parent the parent control
*/
public void createPartControl(Composite parent) {
// read our contents
readFile();
if (parser == null)
return;
handCursor = new Cursor(parent.getDisplay(), SWT.CURSOR_HAND);
busyCursor = new Cursor(parent.getDisplay(), SWT.CURSOR_WAIT);
editorComposite = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout();
layout.marginHeight = 0;
layout.marginWidth = 0;
layout.verticalSpacing = 0;
layout.horizontalSpacing = 0;
editorComposite.setLayout(layout);
createTitleArea(editorComposite);
Label titleBarSeparator = new Label(editorComposite, SWT.HORIZONTAL
| SWT.SEPARATOR);
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
titleBarSeparator.setLayoutData(gd);
createInfoArea(editorComposite);
getSite().getWorkbenchWindow().getWorkbench().getHelpSystem().setHelp(
editorComposite, IIDEHelpContextIds.WELCOME_EDITOR);
this.colorListener = new IPropertyChangeListener() {
public void propertyChange(PropertyChangeEvent event) {
if (event.getProperty()
.equals(JFacePreferences.HYPERLINK_COLOR)) {
Color fg = JFaceColors.getHyperlinkText(editorComposite
.getDisplay());
Iterator links = hyperlinkRanges.iterator();
while (links.hasNext()) {
StyleRange range = (StyleRange) links.next();
range.foreground = fg;
}
}
}
};
JFacePreferences.getPreferenceStore().addPropertyChangeListener(
this.colorListener);
}
/**
* Creates the wizard's title area.
*
* @param parent the SWT parent for the title area composite
* @return the created title area composite
*/
private Composite createTitleArea(Composite parent) {
// Get the background color for the title area
Display display = parent.getDisplay();
Color background = JFaceColors.getBannerBackground(display);
Color foreground = JFaceColors.getBannerForeground(display);
// Create the title area which will contain
// a title, message, and image.
Composite titleArea = new Composite(parent, SWT.NONE | SWT.NO_FOCUS);
GridLayout layout = new GridLayout();
layout.marginHeight = 0;
layout.marginWidth = 0;
layout.verticalSpacing = 0;
layout.horizontalSpacing = 0;
layout.numColumns = 2;
titleArea.setLayout(layout);
titleArea.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
titleArea.setBackground(background);
// Message label
final CLabel messageLabel = new CLabel(titleArea, SWT.LEFT) {
protected String shortenText(GC gc, String text, int width) {
if (gc.textExtent(text, SWT.DRAW_MNEMONIC).x <= width)
return text;
final String ellipsis = "..."; //$NON-NLS-1$
int ellipseWidth = gc.textExtent(ellipsis, SWT.DRAW_MNEMONIC).x;
int length = text.length();
int end = length - 1;
while (end > 0) {
text = text.substring(0, end);
int l1 = gc.textExtent(text, SWT.DRAW_MNEMONIC).x;
if (l1 + ellipseWidth <= width) {
return text + ellipsis;
}
end--;
}
return text + ellipsis;
}
};
JFaceColors.setColors(messageLabel, foreground, background);
messageLabel.setText(getBannerTitle());
messageLabel.setFont(JFaceResources.getHeaderFont());
final IPropertyChangeListener fontListener = new IPropertyChangeListener() {
public void propertyChange(PropertyChangeEvent event) {
if (JFaceResources.HEADER_FONT.equals(event.getProperty())) {
messageLabel.setFont(JFaceResources.getHeaderFont());
}
}
};
messageLabel.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent event) {
JFaceResources.getFontRegistry().removeListener(fontListener);
}
});
JFaceResources.getFontRegistry().addListener(fontListener);
GridData gd = new GridData(GridData.FILL_BOTH);
messageLabel.setLayoutData(gd);
// Title image
Label titleImage = new Label(titleArea, SWT.LEFT);
titleImage.setBackground(background);
titleImage.setImage(PlatformUI.getWorkbench().getSharedImages()
.getImage(IDEInternalWorkbenchImages.IMG_OBJS_WELCOME_BANNER));
gd = new GridData();
gd.horizontalAlignment = GridData.END;
titleImage.setLayoutData(gd);
return titleArea;
}
/**
* The <code>WorkbenchPart</code> implementation of this
* <code>IWorkbenchPart</code> method disposes the title image
* loaded by <code>setInitializationData</code>. Subclasses may extend.
*/
public void dispose() {
super.dispose();
if (busyCursor != null)
busyCursor.dispose();
if (handCursor != null)
handCursor.dispose();
if (this.colorListener != null) {
JFacePreferences.getPreferenceStore().removePropertyChangeListener(
this.colorListener);
}
}
/* (non-Javadoc)
* Saves the contents of this editor.
* <p>
* Subclasses must override this method to implement the open-save-close lifecycle
* for an editor. For greater details, see <code>IEditorPart</code>
* </p>
*
* @see IEditorPart
*/
public void doSave(IProgressMonitor monitor) {
// do nothing
}
/* (non-Javadoc)
* Saves the contents of this editor to another object.
* <p>
* Subclasses must override this method to implement the open-save-close lifecycle
* for an editor. For greater details, see <code>IEditorPart</code>
* </p>
*
* @see IEditorPart
*/
public void doSaveAs() {
// do nothing
}
/**
* Returns the title obtained from the parser
*/
private String getBannerTitle() {
if (parser.getTitle() == null)
return ""; //$NON-NLS-1$
return parser.getTitle();
}
/**
* Returns the intro item or <code>null</code>
*/
private WelcomeItem getIntroItem() {
return parser.getIntroItem();
}
/**
* Returns the welcome items
*/
private WelcomeItem[] getItems() {
return parser.getItems();
}
/* (non-Javadoc)
* Sets the cursor and selection state for this editor to the passage defined
* by the given marker.
* <p>
* Subclasses may override. For greater details, see <code>IEditorPart</code>
* </p>
*
* @see IEditorPart
*/
public void gotoMarker(IMarker marker) {
// do nothing
}
/* (non-Javadoc)
* Initializes the editor part with a site and input.
* <p>
* Subclasses of <code>EditorPart</code> must implement this method. Within
* the implementation subclasses should verify that the input type is acceptable
* and then save the site and input. Here is sample code:
* </p>
* <pre>
* if (!(input instanceof IFileEditorInput))
* throw new PartInitException("Invalid Input: Must be IFileEditorInput");
* setSite(site);
* setInput(editorInput);
* </pre>
*/
public void init(IEditorSite site, IEditorInput input)
throws PartInitException {
if (!(input instanceof WelcomeEditorInput))
throw new PartInitException(
"Invalid Input: Must be WelcomeEditorInput"); //$NON-NLS-1$
setSite(site);
setInput(input);
}
/* (non-Javadoc)
* Returns whether the contents of this editor have changed since the last save
* operation.
* <p>
* Subclasses must override this method to implement the open-save-close lifecycle
* for an editor. For greater details, see <code>IEditorPart</code>
* </p>
*
* @see IEditorPart
*/
public boolean isDirty() {
return false;
}
/* (non-Javadoc)
* Returns whether the "save as" operation is supported by this editor.
* <p>
* Subclasses must override this method to implement the open-save-close lifecycle
* for an editor. For greater details, see <code>IEditorPart</code>
* </p>
*
* @see IEditorPart
*/
public boolean isSaveAsAllowed() {
return false;
}
/**
* Read the contents of the welcome page
*
* @param is the <code>InputStream</code> to parse
* @throws IOException if there is a problem parsing the stream.
*/
public void read(InputStream is) throws IOException {
try {
parser = new WelcomeParser();
} catch (ParserConfigurationException e) {
throw (IOException) (new IOException().initCause(e));
} catch (SAXException e) {
throw (IOException) (new IOException().initCause(e));
}
parser.parse(is);
}
/**
* Reads the welcome file
*/
public void readFile() {
URL url = ((WelcomeEditorInput) getEditorInput()).getAboutInfo()
.getWelcomePageURL();
if (url == null)
// should not happen
return;
InputStream is = null;
try {
is = url.openStream();
read(is);
} catch (IOException e) {
IStatus status = new Status(IStatus.ERROR,
IDEWorkbenchPlugin.IDE_WORKBENCH, 1, IDEWorkbenchMessages.WelcomeEditor_accessException, e);
IDEWorkbenchPlugin.log(IDEWorkbenchMessages.WelcomeEditor_readFileError, status);
} finally {
try {
if (is != null)
is.close();
} catch (IOException e) {
}
}
}
/**
* Sets the styled text's bold ranges
*/
private void setBoldRanges(StyledText styledText, int[][] boldRanges) {
for (int i = 0; i < boldRanges.length; i++) {
StyleRange r = new StyleRange(boldRanges[i][0], boldRanges[i][1],
null, null, SWT.BOLD);
styledText.setStyleRange(r);
}
}
/**
* Asks this part to take focus within the workbench.
* <p>
* Clients should not call this method (the workbench calls this method at
* appropriate times).
* </p>
*/
public void setFocus() {
if ((editorComposite != null) && (lastNavigatedText == null)
&& (currentText == null))
editorComposite.setFocus();
}
/**
* Sets the styled text's link (blue) ranges
*/
private void setLinkRanges(StyledText styledText, int[][] linkRanges) {
//Color fg = styledText.getDisplay().getSystemColor(SWT.COLOR_BLUE);
Color fg = JFaceColors.getHyperlinkText(styledText.getShell()
.getDisplay());
for (int i = 0; i < linkRanges.length; i++) {
StyleRange r = new StyleRange(linkRanges[i][0], linkRanges[i][1],
fg, null);
styledText.setStyleRange(r);
hyperlinkRanges.add(r);
}
}
}