package name.abuchen.portfolio.ui.dialogs;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.inject.Inject;
import javax.inject.Named;
import org.eclipse.e4.ui.services.IServiceConstants;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
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.swt.widgets.Shell;
import name.abuchen.portfolio.ui.Images;
import name.abuchen.portfolio.ui.Messages;
import name.abuchen.portfolio.ui.PortfolioPlugin;
import name.abuchen.portfolio.ui.util.DesktopAPI;
public class AboutDialog extends Dialog
{
private StyledText text;
@Inject
public AboutDialog(@Named(IServiceConstants.ACTIVE_SHELL) Shell parentShell)
{
super(parentShell);
}
@Override
protected Control createDialogArea(Composite parent)
{
String aboutText = MessageFormat.format(Messages.AboutText,
PortfolioPlugin.getDefault().getBundle().getVersion().toString());
Composite area = new Composite(parent, SWT.NONE);
area.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE));
getShell().setText(Messages.LabelAbout);
Label imageLabel = new Label(area, SWT.NONE);
imageLabel.setBackground(area.getBackground());
imageLabel.setImage(Images.LOGO_128.image());
List<StyleRange> styles = new ArrayList<StyleRange>();
aboutText = addContributorHyperlinks(aboutText, styles);
addBoldFirstLine(aboutText, styles);
addHyperlinks(aboutText, styles);
Collections.sort(styles, new Comparator<StyleRange>()
{
@Override
public int compare(StyleRange o1, StyleRange o2)
{
return Integer.compare(o1.start, o2.start);
}
});
text = new StyledText(area, SWT.MULTI | SWT.WRAP | SWT.READ_ONLY);
text.setText(aboutText);
text.setStyleRanges(styles.toArray(new StyleRange[0]));
text.addListener(SWT.MouseDown, new Listener()
{
public void handleEvent(Event event)
{
openBrowser(event);
}
});
// layout
GridLayoutFactory.fillDefaults().numColumns(2).margins(10, 10).spacing(10, 3).applyTo(area);
GridDataFactory.fillDefaults().grab(false, false).align(SWT.CENTER, SWT.TOP).applyTo(imageLabel);
GridDataFactory.fillDefaults().grab(true, true).applyTo(text);
return area;
}
@Override
protected void createButtonsForButtonBar(Composite parent)
{
Button b = createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
b.setFocus();
}
private String addContributorHyperlinks(String aboutText, List<StyleRange> styles)
{
Pattern pattern = Pattern.compile("\\[([\\w]*)\\]"); //$NON-NLS-1$
Matcher matcher = pattern.matcher(aboutText);
StringBuilder answer = new StringBuilder(aboutText.length());
int pointer = 0;
int found = 0;
while (matcher.find())
{
int start = matcher.start();
int end = matcher.end();
StyleRange styleRange = new StyleRange();
styleRange.underline = true;
styleRange.underlineStyle = SWT.UNDERLINE_LINK;
styleRange.underlineColor = Display.getDefault().getSystemColor(SWT.COLOR_DARK_BLUE);
styleRange.data = "https://github.com/" + matcher.group(1); //$NON-NLS-1$
styleRange.start = start - (2 * found);
styleRange.length = end - start - 2;
styles.add(styleRange);
answer.append(aboutText.substring(pointer, start));
answer.append(aboutText.substring(start + 1, end - 1));
pointer = end;
found++;
}
if (pointer < aboutText.length())
answer.append(aboutText.substring(pointer));
return answer.toString();
}
private void addBoldFirstLine(String aboutText, List<StyleRange> ranges)
{
StyleRange styleRange = new StyleRange();
styleRange.fontStyle = SWT.BOLD;
styleRange.start = 0;
styleRange.length = aboutText.indexOf('\n');
ranges.add(styleRange);
}
private void addHyperlinks(String aboutText, List<StyleRange> ranges)
{
Pattern pattern = Pattern.compile("https?://[^ \n]*"); //$NON-NLS-1$
Matcher matcher = pattern.matcher(aboutText);
while (matcher.find())
{
int start = matcher.start();
int end = matcher.end();
StyleRange styleRange = new StyleRange();
styleRange.underline = true;
styleRange.underlineStyle = SWT.UNDERLINE_LINK;
styleRange.underlineColor = Display.getDefault().getSystemColor(SWT.COLOR_DARK_BLUE);
styleRange.data = matcher.group();
styleRange.start = start;
styleRange.length = end - start;
ranges.add(styleRange);
}
}
private void openBrowser(Event event)
{
try
{
int offset = text.getOffsetAtLocation(new Point(event.x, event.y));
StyleRange style = text.getStyleRangeAtOffset(offset);
if (style != null && style.data != null)
DesktopAPI.browse(String.valueOf(style.data));
}
catch (IllegalArgumentException ignore)
{
// no character at position
}
}
}