/* ********************************************************************** **
** Copyright notice **
** **
** (c) 2005-2009 RSSOwl Development Team **
** http://www.rssowl.org/ **
** **
** 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.rssowl.org/legal/epl-v10.html **
** **
** A copy is found in the file epl-v10.html and important notices to the **
** license from the team is found in the textfile LICENSE.txt distributed **
** in this package. **
** **
** This copyright notice MUST APPEAR in all copies of the file! **
** **
** Contributors: **
** RSSOwl Development Team - initial API and implementation **
** **
** ********************************************************************** */
package org.rssowl.ui.internal.dialogs.welcome;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Link;
import org.rssowl.ui.internal.Activator;
import org.rssowl.ui.internal.OwlUI;
import org.rssowl.ui.internal.util.BrowserUtils;
import org.rssowl.ui.internal.util.LayoutUtils;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
/**
* An instance of {@link WizardPage} that is used from the
* {@link TutorialWizard} and {@link WelcomeWizard} to guide the user.
*
* @author bpasero
*/
public class TutorialPage extends WizardPage {
private static final char BOLD = '#';
private static final char BLUE = '%';
private final Chapter fChapter;
/** Chapters of the Tutorial */
public enum Chapter {
INTRO,
LAYOUT,
NEWS,
SAVEDSEARCH,
NEWSBIN,
NEWSFILTER,
NOTIFIER,
SHARING,
IMPORT_EXPORT,
SYNCHRONIZATION,
PREFERENCES,
TIPS,
FINISH
}
TutorialPage(Chapter chapter) {
super(getTitle(chapter), getTitle(chapter), null);
fChapter = chapter;
setMessage(getMessage(chapter));
}
private static String getTitle(Chapter chapter) {
switch (chapter) {
case INTRO:
return Messages.TutorialPage_INTRO;
case LAYOUT:
return Messages.TutorialPage_OVERVIEW;
case NEWS:
return Messages.TutorialPage_NEWS;
case SAVEDSEARCH:
return Messages.TutorialPage_SAVED_SEARCHES;
case NEWSBIN:
return Messages.TutorialPage_NEWS_BINS;
case NEWSFILTER:
return Messages.TutorialPage_NEWS_FILTERS;
case NOTIFIER:
return Messages.TutorialPage_NOTIFICATIONS;
case SHARING:
return Messages.TutorialPage_SHARING;
case IMPORT_EXPORT:
return Messages.TutorialPage_IMPORT_EXPORT;
case SYNCHRONIZATION:
return Messages.TutorialPage_SYNCHRONIZATION;
case PREFERENCES:
return Messages.TutorialPage_PREFERENCES;
case TIPS:
return Messages.TutorialPage_TIPS_AND_TRICKS;
case FINISH:
return Messages.TutorialPage_FINISH;
}
return null;
}
private static String getMessage(Chapter chapter) {
switch (chapter) {
case INTRO:
return Messages.TutorialPage_WELCOME_TUTORIAL;
case LAYOUT:
return Messages.TutorialPage_OVERVIEW_TITLE;
case NEWS:
return Messages.TutorialPage_WORKING_WITH_NEWS;
case SAVEDSEARCH:
return Messages.TutorialPage_SAVING_SEARCH_RESULTS;
case NEWSBIN:
return Messages.TutorialPage_STORING_NEWS_BINS;
case NEWSFILTER:
return Messages.TutorialPage_NEWS_FILTER_POWER;
case NOTIFIER:
return Messages.TutorialPage_NOTIFIER_TITLE;
case SHARING:
return Messages.TutorialPage_SHARE_FEEDS_TITLE;
case IMPORT_EXPORT:
return Messages.TutorialPage_IMPORT_EXPORT_TITLE;
case SYNCHRONIZATION:
return Messages.TutorialPage_SYNCHRONIZATION_TITLE;
case PREFERENCES:
return Messages.TutorialPage_CONFIGURE_TITLE;
case TIPS:
return Messages.TutorialPage_TIPS_TITLE;
case FINISH:
return Messages.TutorialPage_FINISH_TITLE;
}
return null;
}
private ImageDescriptor getTitleImage() {
switch (fChapter) {
case LAYOUT:
return OwlUI.getImageDescriptor("icons/wizban/layout_wiz.png"); //$NON-NLS-1$
case NEWS:
return OwlUI.getImageDescriptor("icons/wizban/bkmrk_wiz.gif"); //$NON-NLS-1$
case SAVEDSEARCH:
return OwlUI.getImageDescriptor("icons/wizban/search.gif"); //$NON-NLS-1$
case NEWSBIN:
return OwlUI.getImageDescriptor("icons/wizban/newsbin_wiz.gif"); //$NON-NLS-1$
case NEWSFILTER:
return OwlUI.getImageDescriptor("icons/wizban/filter_wiz.png"); //$NON-NLS-1$
case NOTIFIER:
return OwlUI.getImageDescriptor("icons/wizban/notifier_wiz.gif"); //$NON-NLS-1$
case SHARING:
return OwlUI.getImageDescriptor("icons/wizban/sharing_wiz.gif"); //$NON-NLS-1$
case IMPORT_EXPORT:
return OwlUI.getImageDescriptor("icons/wizban/import_wiz.png"); //$NON-NLS-1$
case SYNCHRONIZATION:
return OwlUI.getImageDescriptor("icons/wizban/reader_wiz.png"); //$NON-NLS-1$
case PREFERENCES:
return OwlUI.getImageDescriptor("icons/wizban/preferences_wiz.gif"); //$NON-NLS-1$
case TIPS:
return OwlUI.getImageDescriptor("icons/wizban/tips_wiz.png"); //$NON-NLS-1$
default:
return OwlUI.getImageDescriptor("icons/wizban/welcome_wiz.gif"); //$NON-NLS-1$
}
}
/*
* @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
*/
public void createControl(Composite parent) {
/* Title Image */
setImageDescriptor(getTitleImage());
/* Container */
final Composite container = new Composite(parent, SWT.BORDER);
container.setLayout(new GridLayout(1, false));
container.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE));
/* Contents */
SafeRunnable.run(new ISafeRunnable() {
public void run() throws Exception {
createContents(container);
}
public void handleException(Throwable th) {
Activator.safeLogError(th.getMessage(), th);
}
});
Dialog.applyDialogFont(container);
setControl(container);
}
private void createContents(Composite container) {
switch (fChapter) {
case INTRO:
createIntroPage(container);
break;
case LAYOUT:
createOverviewPage(container);
break;
case NEWS:
createNewsPage(container);
break;
case SAVEDSEARCH:
createSavedSearchPage(container);
break;
case NEWSBIN:
createNewsBinPage(container);
break;
case NEWSFILTER:
createNewsFilterPage(container);
break;
case NOTIFIER:
createNotificationsPage(container);
break;
case SHARING:
createSharingPage(container);
break;
case IMPORT_EXPORT:
createImportExportPage(container);
break;
case SYNCHRONIZATION:
createSynchronizationPage(container);
break;
case PREFERENCES:
createPreferencesPage(container);
break;
case TIPS:
createTipsPage(container);
break;
case FINISH:
createFinishPage(container);
break;
}
}
private void createIntroPage(Composite container) {
StyledText text = createStyledText(container);
applyRichText(Messages.TutorialPage_WELCOME_TEXT, text);
}
private void createOverviewPage(Composite container) {
StyledText text = createStyledText(container);
applyRichText(Messages.TutorialPage_LAYOUT_TEXT, text);
}
private void createNewsPage(Composite container) {
StyledText text = createStyledText(container);
applyRichText(Messages.TutorialPage_NEWS_TEXT, text);
}
private void createSavedSearchPage(Composite container) {
StyledText text = createStyledText(container);
applyRichText(Messages.TutorialPage_SAVED_SEARCHES_TEXT, text);
}
private void createNewsBinPage(Composite container) {
StyledText text = createStyledText(container);
applyRichText(Messages.TutorialPage_NEWS_BIN_TEXT, text);
}
private void createNewsFilterPage(Composite container) {
StyledText text = createStyledText(container);
applyRichText(Messages.TutorialPage_NEWS_FILTER_TEXT, text);
}
private void createNotificationsPage(Composite container) {
StyledText text = createStyledText(container);
applyRichText(Messages.TutorialPage_NOTIFIER_TEXT, text);
}
private void createSharingPage(Composite container) {
StyledText text = createStyledText(container);
applyRichText(Messages.TutorialPage_SHARING_TEXT, text);
}
private void createImportExportPage(Composite container) {
StyledText text = createStyledText(container);
applyRichText(Messages.TutorialPage_IMPORT_EXPORT_TEXT, text);
}
private void createSynchronizationPage(Composite container) {
StyledText text = createStyledText(container);
applyRichText(Messages.TutorialPage_SYNCHRONIZATION_TEXT, text);
}
private void createPreferencesPage(Composite container) {
StyledText text = createStyledText(container);
applyRichText(Messages.TutorialPage_PREFERENCES_TEXT, text);
}
private void createTipsPage(Composite container) {
StyledText text = createStyledText(container);
applyRichText(Messages.TutorialPage_TIPS_TEXT, text);
}
private void createFinishPage(Composite container) {
StyledText text = createStyledText(container, false);
applyRichText(Messages.TutorialPage_FINISH_TEXT, text);
Composite linkContainer = new Composite(container, SWT.NONE);
linkContainer.setLayout(LayoutUtils.createGridLayout(1, 0, 0));
linkContainer.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
linkContainer.setBackground(container.getBackground());
/* Further Links */
createHyperLink(linkContainer, Messages.TutorialPage_FAQ, "http://www.rssowl.org/help"); //$NON-NLS-1$
createHyperLink(linkContainer, Messages.TutorialPage_FORUMS, "http://sourceforge.net/projects/rssowl/forums"); //$NON-NLS-1$
createHyperLink(linkContainer, Messages.TutorialPage_REPORT_BUGS, "http://dev.rssowl.org"); //$NON-NLS-1$
createHyperLink(linkContainer, Messages.TutorialPage_CONTACT, "http://www.rssowl.org/contact"); //$NON-NLS-1$
createHyperLink(linkContainer, Messages.TutorialPage_WEBSITE, "http://www.rssowl.org"); //$NON-NLS-1$
}
private StyledText createStyledText(Composite container) {
return createStyledText(container, true);
}
private StyledText createStyledText(Composite container, boolean grabVertical) {
StyledText text = new StyledText(container, SWT.WRAP | SWT.READ_ONLY);
text.setEnabled(false);
text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, grabVertical));
((GridData) text.getLayoutData()).widthHint = 500;
text.setLineSpacing(5);
return text;
}
private Link createHyperLink(Composite container, String text, final String href) {
Link link = new Link(container, SWT.NONE);
link.setText("<a>" + text + "</a>"); //$NON-NLS-1$ //$NON-NLS-2$
link.setBackground(container.getBackground());
link.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
BrowserUtils.openLinkExternal(href);
}
});
return link;
}
private void applyRichText(String text, StyledText widget) {
List<StyleRange> ranges = new ArrayList<StyleRange>();
StringBuilder buffer = new StringBuilder();
StringReader reader = new StringReader(text);
int character;
int index = 0;
boolean inBold = false;
boolean inBlue = false;
int boldStartIndex = 0;
int blueStartIndex = 0;
try {
while ((character = reader.read()) != -1) {
/* Bold Start */
if (character == BOLD && !inBold) {
inBold = true;
boldStartIndex = index;
}
/* Bold End */
else if (character == BOLD && inBold) {
inBold = false;
ranges.add(new StyleRange(boldStartIndex, index - boldStartIndex, null, null, SWT.BOLD));
}
/* Blue Start */
else if (character == BLUE && !inBlue) {
inBlue = true;
blueStartIndex = index;
}
/* Blue End */
else if (character == BLUE && inBlue) {
inBlue = false;
StyleRange range = new StyleRange();
range.foreground = widget.getDisplay().getSystemColor(SWT.COLOR_DARK_BLUE);
range.start = blueStartIndex;
range.length = index - blueStartIndex;
ranges.add(range);
}
/* Normal Character */
else {
buffer.append((char) character);
index++;
}
}
} catch (IOException e) {
/* Never Reached */
}
widget.setText(buffer.toString());
widget.setStyleRanges(ranges.toArray(new StyleRange[ranges.size()]));
}
}