package name.abuchen.portfolio.ui.parts;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import org.eclipse.core.commands.Command;
import org.eclipse.core.commands.IParameter;
import org.eclipse.core.commands.Parameterization;
import org.eclipse.core.commands.ParameterizedCommand;
import org.eclipse.core.commands.common.NotDefinedException;
import org.eclipse.core.runtime.Path;
import org.eclipse.e4.core.commands.ECommandService;
import org.eclipse.e4.core.commands.EHandlerService;
import org.eclipse.e4.core.di.annotations.Optional;
import org.eclipse.e4.ui.di.UIEventTopic;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.workbench.modeling.EPartService;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import name.abuchen.portfolio.ui.Images;
import name.abuchen.portfolio.ui.Messages;
import name.abuchen.portfolio.ui.PortfolioPlugin;
import name.abuchen.portfolio.ui.UIConstants;
import name.abuchen.portfolio.ui.util.DesktopAPI;
import name.abuchen.portfolio.ui.util.RecentFilesCache;
@SuppressWarnings("restriction")
public class WelcomePart
{
private static final String OPEN = "open:"; //$NON-NLS-1$
@Inject
private ECommandService commandService;
@Inject
private EHandlerService handlerService;
@Inject
private EPartService partService;
@Inject
private RecentFilesCache recentFiles;
private Composite recentFilesComposite;
private Font boldFont;
@PostConstruct
public void createComposite(Composite parent)
{
Composite container = new Composite(parent, SWT.NONE);
container.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE));
RowLayout layout = new RowLayout();
layout.spacing = 20;
layout.marginHeight = layout.marginWidth = 10;
container.setLayout(layout);
// create fonts
FontData[] fD = container.getFont().getFontData();
fD[0].setStyle(SWT.BOLD);
boldFont = new Font(container.getDisplay(), fD[0]);
fD[0].setStyle(SWT.NORMAL);
fD[0].setHeight(fD[0].getHeight() * 2);
final Font bigFont = new Font(container.getDisplay(), fD[0]);
container.addDisposeListener(e -> {
boldFont.dispose();
bigFont.dispose();
});
// first column: logo
Label image = new Label(container, SWT.NONE);
image.setBackground(container.getBackground());
image.setImage(Images.LOGO_128.image());
// second column: actions
Composite actions = new Composite(container, SWT.NONE);
actions.setBackground(container.getBackground());
GridLayoutFactory.fillDefaults().numColumns(2).spacing(20, 20).applyTo(actions);
Label title = new Label(actions, SWT.NONE);
title.setText(Messages.LabelPortfolioPerformance);
title.setFont(bigFont);
GridDataFactory.fillDefaults().span(2, 1).applyTo(title);
Label version = new Label(actions, SWT.NONE);
version.setText(PortfolioPlugin.getDefault().getBundle().getVersion().toString());
GridDataFactory.fillDefaults().span(2, 1).applyTo(version);
Composite links = new Composite(actions, SWT.NONE);
GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.BEGINNING).applyTo(links);
GridLayoutFactory.fillDefaults().applyTo(links);
addSectionLabel(boldFont, links, Messages.IntroLabelActions);
addLink(links, "action:open", Messages.IntroOpenFile, Messages.IntroOpenFileText); //$NON-NLS-1$
addLink(links, "action:new", Messages.IntroNewFile, Messages.IntroNewFileText); //$NON-NLS-1$
addSectionLabel(boldFont, links, Messages.IntroLabelSamples);
addLink(links, "action:sample", Messages.IntroOpenSample, Messages.IntroOpenSampleText); //$NON-NLS-1$
addLink(links, "action:daxsample", Messages.IntroOpenDaxSample, Messages.IntroOpenDaxSampleText); //$NON-NLS-1$
addSectionLabel(boldFont, links, Messages.IntroLabelHelp);
addLink(links, "https://forum.portfolio-performance.info", //$NON-NLS-1$
Messages.IntroOpenForum, Messages.IntroOpenForumText);
addLink(links, "https://forum.portfolio-performance.info/c/how-to", //$NON-NLS-1$
Messages.IntroOpenHowtos, Messages.IntroOpenHowtosText);
addLink(links, "https://forum.portfolio-performance.info/c/faq", //$NON-NLS-1$
Messages.IntroOpenFAQ, Messages.IntroOpenFAQText);
createRecentFilesComposite(actions);
}
private void createRecentFilesComposite(Composite actions)
{
recentFilesComposite = new Composite(actions, SWT.NONE);
GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.BEGINNING).applyTo(recentFilesComposite);
GridLayoutFactory.fillDefaults().applyTo(recentFilesComposite);
addSectionLabel(boldFont, recentFilesComposite, Messages.IntroLabelRecentlyUsedFiles);
for (String file : recentFiles.getRecentFiles())
{
String name = Path.fromOSString(file).lastSegment();
addLink(recentFilesComposite, OPEN + file, name, null);
}
}
private void addSectionLabel(Font boldFont, Composite actions, String label)
{
Label l = new Label(actions, SWT.NONE);
l.setText(label);
l.setFont(boldFont);
GridDataFactory.fillDefaults().indent(0, 20).applyTo(l);
}
private void addLink(Composite container, final String target, String label, String subtext)
{
Link link = new Link(container, SWT.UNDERLINE_LINK);
link.setText("<a>" + label + "</a>"); //$NON-NLS-1$ //$NON-NLS-2$
link.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
linkActivated(target);
}
});
if (subtext != null)
{
Label l = new Label(container, SWT.WRAP);
l.setText(subtext);
GridDataFactory.fillDefaults().indent(0, -3).applyTo(l);
}
}
public void linkActivated(String target)
{
if (target.startsWith(OPEN))
{
String file = target.substring(OPEN.length());
// check if file is already opened somewhere
java.util.Optional<MPart> part = partService.getParts().stream()
.filter(p -> UIConstants.Part.PORTFOLIO.equals(p.getElementId())) //
.filter(p -> file.equals(p.getPersistedState().get(UIConstants.File.PERSISTED_STATE_KEY)))
.findAny();
if (part.isPresent())
partService.activate(part.get());
else
executeCommand(UIConstants.Command.OPEN_RECENT_FILE, UIConstants.Parameter.FILE, file);
}
else if ("action:open".equals(target)) //$NON-NLS-1$
{
executeCommand("name.abuchen.portfolio.ui.command.open"); //$NON-NLS-1$
}
else if ("action:new".equals(target)) //$NON-NLS-1$
{
executeCommand("name.abuchen.portfolio.ui.command.newclient"); //$NON-NLS-1$
}
else if ("action:sample".equals(target)) //$NON-NLS-1$
{
executeCommand("name.abuchen.portfolio.ui.command.openSample", //$NON-NLS-1$
UIConstants.Parameter.SAMPLE_FILE, //
"/" + getClass().getPackage().getName().replace('.', '/') + "/kommer.xml"); //$NON-NLS-1$ //$NON-NLS-2$
}
else if ("action:daxsample".equals(target)) //$NON-NLS-1$
{
executeCommand("name.abuchen.portfolio.ui.command.openSample", //$NON-NLS-1$
UIConstants.Parameter.SAMPLE_FILE, //
"/" + getClass().getPackage().getName().replace('.', '/') + "/dax.xml"); //$NON-NLS-1$ //$NON-NLS-2$
}
else if (target.startsWith("http")) //$NON-NLS-1$
{
DesktopAPI.browse(target);
}
}
private void executeCommand(String command, String... parameters)
{
try
{
Command cmd = commandService.getCommand(command);
List<Parameterization> parameterizations = new ArrayList<>();
if (parameters != null)
{
for (int ii = 0; ii < parameters.length; ii = ii + 2)
{
IParameter p = cmd.getParameter(parameters[ii]);
parameterizations.add(new Parameterization(p, parameters[ii + 1]));
}
}
ParameterizedCommand pCmd = new ParameterizedCommand(cmd,
parameterizations.toArray(new Parameterization[0]));
if (handlerService.canExecute(pCmd))
handlerService.executeHandler(pCmd);
}
catch (NotDefinedException e)
{
PortfolioPlugin.log(e);
MessageDialog.openError(Display.getDefault().getActiveShell(), Messages.LabelError, e.getMessage());
}
}
@Inject
@Optional
public void subscribeFileTopic(@UIEventTopic(UIConstants.Event.File.ALL_SUB_TOPICS) String file)
{
if (recentFilesComposite == null)
return;
Composite parent = recentFilesComposite.getParent();
recentFilesComposite.dispose();
createRecentFilesComposite(parent);
recentFilesComposite.getParent().getParent().layout(true);
}
}